st7789.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "lcd.h"
  2. #include "log.h"
  3. #define DIV_NUM 10
  4. #define COL_ADDR_SET 0x2A
  5. #define ROW_ADDR_SET 0x2B
  6. #define MEMORY_WRITE 0x2C
  7. /**
  8. * MADCTL(36H):
  9. * +---------------------------------------+
  10. * | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
  11. * | MY | MX | MV | ML | RGB| MH | - | - |
  12. * +---------------------------------------+
  13. * [3] 0=RGB,1=BGR
  14. */
  15. #define DATA_ACCESS 0x36
  16. /**
  17. * COLMOD(3AH):
  18. * +---------------------------------------+
  19. * | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
  20. * | 0 | D6 | D5 | D4 | 0 | D2 | D1 | D0 |
  21. * +---------------------------------------+
  22. * [6:4] RGB interface Color format:
  23. * 101=65K RGB
  24. * 110=262K RGB
  25. * [2:0] Control interface color format:
  26. * 011=12bit/pixel
  27. * 101=16bit/pixel
  28. * 110=18bit/pixel
  29. * 111=16M truncated
  30. */
  31. #define PIXEL_FORMAT 0x3A
  32. #define delay_ms(x) rt_thread_mdelay(x)
  33. static void st7789_fill(lcd_handle_t *h, uint16_t color);
  34. static void write_reg(lcd_handle_t *h, uint8_t reg)
  35. {
  36. gpio_set(DC_PIN, 0);
  37. rt_spi_send(h->dev, &reg, 1);
  38. }
  39. static void write_data(lcd_handle_t *h, uint8_t data)
  40. {
  41. gpio_set(DC_PIN, 1);
  42. rt_spi_send(h->dev, &data, 1);
  43. }
  44. static void write_reg_data(lcd_handle_t *h, uint8_t reg, uint16_t data)
  45. {
  46. write_reg(h,reg);
  47. write_data(h,data);
  48. }
  49. static void read_data(lcd_handle_t *h, uint8_t *data, int length)
  50. {
  51. gpio_set(DC_PIN, 1);
  52. rt_spi_transfer(h->dev, RT_NULL, data, length);
  53. }
  54. static void write_16bit(lcd_handle_t *h, uint16_t data)
  55. {
  56. uint8_t buf[2];
  57. buf[0] = data >> 8;
  58. buf[1] = data & 0xff;
  59. gpio_set(DC_PIN, 1);
  60. rt_spi_send(h->dev, buf, 2);
  61. }
  62. void st7789_rotate(lcd_handle_t *h, int rotate)
  63. {
  64. switch (rotate)
  65. {
  66. case 0:
  67. //h->width = LCD_W;
  68. //h->height = LCD_H;
  69. write_reg_data(h, DATA_ACCESS, (0 << 3) | (0 << 5) | (0 << 6) | (0 << 7)); /* BGR==0,MV==0,MX==0,MY==0 */
  70. break;
  71. case 90:
  72. //h->width = LCD_H;
  73. //h->height = LCD_W;
  74. write_reg_data(h, DATA_ACCESS, (0 << 3) | (1 << 5) | (1 << 6) | (0 << 7)); /* BGR==0,MV==1,MX==0,MY==1 */
  75. break;
  76. case 180:
  77. //h->width = LCD_W;
  78. //h->height = LCD_H;
  79. write_reg_data(h, DATA_ACCESS, (0 << 3) | (0 << 5) | (1 << 6) | (1 << 7)); /* BGR==0,MV==0,MX==1,MY==1 */
  80. break;
  81. case 270:
  82. //h->width = LCD_H;
  83. //h->height = LCD_W;
  84. write_reg_data(h, DATA_ACCESS, (0 << 3) | (1 << 5) | (0 << 6) | (1 << 7)); /* BGR==0,MV==1,MX==0,MY==1 */
  85. break;
  86. default:
  87. break;
  88. }
  89. }
  90. static void st7789_set_win(lcd_handle_t *hd, int x, int y, int w, int h)
  91. {
  92. write_reg(hd,COL_ADDR_SET);
  93. write_data(hd,x>>8);
  94. write_data(hd,x&0xff);
  95. write_data(hd,(x+w-1)>>8);
  96. write_data(hd,(x+w-1)&0xff);
  97. write_reg(hd,ROW_ADDR_SET);
  98. write_data(hd,y>>8);
  99. write_data(hd,y&0xff);
  100. write_data(hd,(y+h-1)>>8);
  101. write_data(hd,(y+h-1)&0xff);
  102. write_reg(hd,MEMORY_WRITE);
  103. }
  104. void st7789_refresh(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void *data, uint32_t len)
  105. {
  106. int r;
  107. st7789_set_win(hd, x, y, x + w - 1, y + h - 1);
  108. gpio_set(DC_PIN, 1);
  109. r = rt_spi_send(hd->dev, data, len);
  110. }
  111. static void st7789_reg_init(lcd_handle_t *h)
  112. {
  113. write_reg(h, DATA_ACCESS);
  114. write_data(h, 0x00);
  115. write_reg(h, PIXEL_FORMAT);
  116. write_data(h, 0X05); //03=RGB444,05=RGB565,06=RGB666
  117. write_reg(h, 0xB2); //Porch Setting
  118. write_data(h, 0x0C);
  119. write_data(h, 0x0C);
  120. write_data(h, 0X00);
  121. write_data(h, 0X33);
  122. write_data(h, 0X33);
  123. write_reg(h, 0xB7); //Gate Control
  124. write_data(h, 0x46);
  125. write_reg(h, 0xBB); //VCOM Setting
  126. write_data(h, 0x1B);
  127. write_reg(h, 0xC0); //LCM Control
  128. write_data(h, 0x2C);
  129. write_reg(h, 0xC2); //VDV and VRH Command Enable
  130. write_data(h, 0x01);
  131. write_reg(h, 0xC3); //VRH set
  132. write_data(h, 0x0F);
  133. write_reg(h, 0xC4); //VDV set
  134. write_data(h, 0x20);
  135. write_reg(h, 0xC6); //Frame Rate Control
  136. write_data(h, 0x0F);
  137. write_reg(h, 0xD0); //Power Control 1
  138. write_data(h, 0xA4);
  139. write_data(h, 0xA1);
  140. write_reg(h, 0xD6);
  141. write_data(h, 0xA1);
  142. write_reg(h, 0xE0); /* set Positive Voltage Gamma */
  143. write_data(h, 0xF0);
  144. write_data(h, 0x00);
  145. write_data(h, 0x06);
  146. write_data(h, 0x04);
  147. write_data(h, 0x05);
  148. write_data(h, 0x05);
  149. write_data(h, 0x31);
  150. write_data(h, 0x44);
  151. write_data(h, 0x48);
  152. write_data(h, 0x36);
  153. write_data(h, 0x12);
  154. write_data(h, 0x12);
  155. write_data(h, 0x2B);
  156. write_data(h, 0x34);
  157. write_reg(h, 0xE1); /* set Negative Voltage Gamma */
  158. write_data(h, 0XF0);
  159. write_data(h, 0X0B);
  160. write_data(h, 0X0F);
  161. write_data(h, 0X0F);
  162. write_data(h, 0X0D);
  163. write_data(h, 0X26);
  164. write_data(h, 0X31);
  165. write_data(h, 0X43);
  166. write_data(h, 0X47);
  167. write_data(h, 0X38);
  168. write_data(h, 0X14);
  169. write_data(h, 0X14);
  170. write_data(h, 0X2C);
  171. write_data(h, 0X32);
  172. write_reg(h, 0x21); // Dispaly Inversion On
  173. write_reg(h, 0x29); // Display On
  174. write_reg(h,MEMORY_WRITE); // Memory Write
  175. }
  176. static void st7789_reset(lcd_handle_t *h)
  177. {
  178. gpio_set(RST_PIN, 0); /* LCD Hardware Reset */
  179. delay_ms(100);
  180. gpio_set(RST_PIN, 1);
  181. delay_ms(120); /* Delay 120ms */
  182. write_reg(h,0x11); /* Sleep out */
  183. delay_ms(120); /* Delay 120ms */
  184. }
  185. static void set_color(lcd_handle_t *h, uint16_t color)
  186. {
  187. int i,cnt=h->buflen/2;
  188. for(i=0; i<cnt; i++) {
  189. h->buf[i] = color;
  190. }
  191. }
  192. static void st7789_fill(lcd_handle_t *h, uint16_t color)
  193. {
  194. int i;
  195. int height=h->height/DIV_NUM;
  196. set_color(h, color);
  197. for(i=0; i<DIV_NUM; i++) {
  198. st7789_refresh(h, 0, i*height, h->width, height, h->buf, h->buflen);
  199. }
  200. }
  201. #define SPI_BUS "spi2"
  202. #define SPI_DEV_NAME "spi2.0"
  203. int st7789_init(lcd_handle_t *h)
  204. {
  205. int r;
  206. struct rt_spi_configuration sc;
  207. gpio_init(BK_PIN, GPIO_OUT, 0);
  208. gpio_init(DC_PIN, GPIO_OUT, 0);
  209. gpio_init(RST_PIN, GPIO_OUT, 0);
  210. r = rt_hw_spi_device_attach(SPI_BUS, SPI_DEV_NAME, CS_PIN);
  211. if(r!=RT_EOK) {
  212. return -1;
  213. }
  214. h->dev = (struct rt_spi_device*)rt_device_find(SPI_DEV_NAME);
  215. if(h->dev==NULL) {
  216. return -1;
  217. }
  218. sc.data_width = 8;
  219. sc.max_hz = 5 * 1000 * 1000;
  220. sc.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
  221. r = rt_spi_configure(h->dev, &sc);
  222. h->buflen = (h->width*h->height*2)/DIV_NUM;
  223. h->buf = (uint16_t*)malloc(h->buflen);
  224. if (!h->buf) {
  225. LOGE("malloc buffer falied\n");
  226. return -1;
  227. }
  228. st7789_reset(h);
  229. st7789_reg_init(h);
  230. gpio_set(BK_PIN, 1);
  231. st7789_fill(h, COLOR_GREEN);
  232. return 0;
  233. }
  234. int st7789_deinit(lcd_handle_t *h)
  235. {
  236. gpio_deinit(BK_PIN);
  237. gpio_deinit(DC_PIN);
  238. gpio_deinit(RST_PIN);
  239. free(h->buf);
  240. return 0;
  241. }