st77xx.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #include "lcd.h"
  2. #include "log.h"
  3. #define DIV_NUM 10
  4. #define INVERSE 1
  5. #define ST_OFFSET 80
  6. #define BIT(x) (1<<x)
  7. #define ST77XX_CASET 0x2A
  8. #define ST77XX_RASET 0x2B
  9. #define ST77XX_RAMWR 0x2C
  10. #define ST77XX_RAMRD 0x2E
  11. #define ST77XX_MADCTL 0x36
  12. #define ST77XX_PIXEL_FORMAT 0x3A
  13. #define ST77XX_MADCTL_MH BIT(2)
  14. #define ST77XX_MADCTL_ML BIT(4)
  15. #define ST77XX_MADCTL_MV BIT(5)
  16. #define ST77XX_MADCTL_MX BIT(6)
  17. #define ST77XX_MADCTL_MY BIT(7)
  18. #define ST77XX_MADCTL_RGB 0x00
  19. #define ST77XX_MADCTL_BGR BIT(3)
  20. #define delay_ms(x) rt_thread_mdelay(x)
  21. void st77xx_fill(lcd_handle_t *h, uint32_t color);
  22. static void write_cmd(lcd_handle_t *h, uint8_t reg)
  23. {
  24. gpio_set(DC_PIN, 0);
  25. rt_spi_send(h->dev, &reg, 1);
  26. }
  27. static void write_data(lcd_handle_t *h, uint8_t data)
  28. {
  29. gpio_set(DC_PIN, 1);
  30. rt_spi_send(h->dev, &data, 1);
  31. }
  32. static void write_cmd_data(lcd_handle_t *h, uint8_t reg, uint16_t data)
  33. {
  34. write_cmd (h,reg);
  35. write_data(h,data);
  36. }
  37. static void read_data(lcd_handle_t *h, uint8_t *data, int length)
  38. {
  39. gpio_set(DC_PIN, 1);
  40. rt_spi_transfer(h->dev, RT_NULL, data, length);
  41. }
  42. static void write_16bit(lcd_handle_t *h, uint16_t data)
  43. {
  44. uint8_t buf[2];
  45. buf[0] = data >> 8;
  46. buf[1] = data & 0xff;
  47. gpio_set(DC_PIN, 1);
  48. rt_spi_send(h->dev, buf, 2);
  49. }
  50. void st77xx_rotate(lcd_handle_t *h, int rotate)
  51. {
  52. uint8_t madctl=0,mode=INVERSE?ST77XX_MADCTL_BGR:ST77XX_MADCTL_RGB;
  53. switch (rotate)
  54. {
  55. case 0:
  56. madctl = mode;
  57. break;
  58. case 90:
  59. madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MX | mode);
  60. break;
  61. case 180:
  62. madctl = (ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | mode);
  63. break;
  64. case 270:
  65. madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MY | mode);
  66. break;
  67. default:
  68. break;
  69. }
  70. write_cmd_data(h, ST77XX_MADCTL, madctl);
  71. }
  72. void st77xx_set_win(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
  73. {
  74. int x1=x,y1=y;
  75. int x2=x+w-1,y2=y+h-1;
  76. write_cmd (hd,ST77XX_CASET);
  77. write_data(hd,x1>>8);
  78. write_data(hd,x1);
  79. write_data(hd,x2>>8);
  80. write_data(hd,x2);
  81. write_cmd (hd,ST77XX_RASET);
  82. write_data(hd,y1>>8);
  83. write_data(hd,y1);
  84. write_data(hd,y2>>8);
  85. write_data(hd,y2);
  86. write_cmd (hd,ST77XX_RAMWR);
  87. }
  88. void st77xx_refresh(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void *data, uint32_t len)
  89. {
  90. if(x>=hd->width || y>=hd->height) {
  91. return;
  92. }
  93. st77xx_set_win(hd, x, y, w, h);
  94. gpio_set(DC_PIN, 1);
  95. rt_spi_send(hd->dev, data, len);
  96. }
  97. void st77xx_draw_pixel(lcd_handle_t *hd, uint16_t x, uint16_t y, uint32_t color)
  98. {
  99. st77xx_set_win(hd, x, y, 1, 1);
  100. write_16bit(hd, color);
  101. }
  102. static void st77xx_reg_init(lcd_handle_t *h)
  103. {
  104. write_cmd (h,0x11);
  105. delay_ms(150);
  106. write_cmd (h,0xB2); //Porch Setting
  107. write_data(h,0x0C);
  108. write_data(h,0x0C);
  109. write_data(h,0x00);
  110. write_data(h,0x33);
  111. write_data(h,0x33);
  112. write_cmd (h,0x35);
  113. write_data(h,0x00);
  114. write_cmd (h,ST77XX_MADCTL);
  115. write_data(h,0x00);
  116. write_cmd (h,ST77XX_PIXEL_FORMAT);
  117. write_data(h,0x05); //03=RGB444,05=RGB565,06=RGB666
  118. write_cmd (h,0xb7); //Gate Control
  119. write_data(h,0x35);
  120. write_cmd (h,0xbb); //VCOM Setting
  121. write_data(h,0x2d);
  122. write_cmd (h,0xC0); //LCM Control
  123. write_data(h,0x2C);
  124. write_cmd (h,0xC2); //VDV and VRH Command Enable
  125. write_data(h,0x01);
  126. write_cmd (h,0xC3); //VRH set
  127. write_data(h,0x15);
  128. write_cmd (h,0xC4); //VDV set
  129. write_data(h,0x20);
  130. write_cmd (h,0xC6); //Frame Rate Control
  131. write_data(h,0x0F);
  132. write_cmd (h,0xD0); //Power Control 1
  133. write_data(h,0xA4);
  134. write_data(h,0xA1);
  135. write_cmd (h,0xD6);
  136. write_data(h,0xA1);
  137. write_cmd (h,0xE0); /* set Positive Voltage Gamma */
  138. write_data(h,0x70);
  139. write_data(h,0x05);
  140. write_data(h,0x0a);
  141. write_data(h,0x0b);
  142. write_data(h,0x0a);
  143. write_data(h,0x27);
  144. write_data(h,0x2f);
  145. write_data(h,0x44);
  146. write_data(h,0x47);
  147. write_data(h,0x37);
  148. write_data(h,0x14);
  149. write_data(h,0x14);
  150. write_data(h,0x29);
  151. write_data(h,0x2f);
  152. write_cmd (h,0xE1); /* set Negative Voltage Gamma */
  153. write_data(h,0x70);
  154. write_data(h,0x07);
  155. write_data(h,0x0c);
  156. write_data(h,0x08);
  157. write_data(h,0x08);
  158. write_data(h,0x04);
  159. write_data(h,0x2f);
  160. write_data(h,0x33);
  161. write_data(h,0x46);
  162. write_data(h,0x18);
  163. write_data(h,0x15);
  164. write_data(h,0x15);
  165. write_data(h,0x2b);
  166. write_data(h,0x2d);
  167. write_cmd (h,0x21); // Dispaly Inversion On
  168. write_cmd (h,0x29); // Display On
  169. write_cmd (h,ST77XX_RAMWR); // Memory Write
  170. }
  171. static void st77xx_reset(lcd_handle_t *h)
  172. {
  173. gpio_set(RST_PIN, 0); /* LCD Hardware Reset */
  174. delay_ms(100);
  175. gpio_set(RST_PIN, 1);
  176. delay_ms(120); /* Delay 120ms */
  177. }
  178. static void fill_color(lcd_handle_t *h, uint16_t color, int cnt)
  179. {
  180. int i,cnt2=(cnt<=h->buflen/2)?cnt:h->buflen/2;
  181. for(i=0; i<cnt2; i++) {
  182. h->buf[i] = color;
  183. }
  184. }
  185. static void write_color(lcd_handle_t *h, uint16_t color, int cnt)
  186. {
  187. int i;
  188. for(i=0; i<cnt; i++) {
  189. write_16bit(h, color);
  190. }
  191. }
  192. void st77xx_fill_rect(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color)
  193. {
  194. int height=hd->height/DIV_NUM;
  195. int i,y1=0,h1=0,times=h/height,left=h%height;
  196. times += left?1:0;
  197. fill_color(hd, color, hd->buflen/2);
  198. for(i=0; i<times; i++) {
  199. y1 = y+i*height;
  200. h1 = ((h1+height)>h)?(h-h1):height;
  201. st77xx_refresh(hd, x, y1, w, h1, hd->buf, w*h1*2);
  202. }
  203. }
  204. void st77xx_fill(lcd_handle_t *h, uint32_t color)
  205. {
  206. st77xx_fill_rect(h, 0, 0, h->width, h->height, color);
  207. }
  208. #define SPI_BUS "spi2"
  209. #define SPI_DEV_NAME "spi2.0"
  210. int st77xx_init(lcd_handle_t *h)
  211. {
  212. int r;
  213. struct rt_spi_configuration sc;
  214. gpio_init(BK_PIN, GPIO_OUT, 0);
  215. gpio_init(DC_PIN, GPIO_OUT, 0);
  216. gpio_init(RST_PIN, GPIO_OUT, 0);
  217. r = rt_hw_spi_device_attach(SPI_BUS, SPI_DEV_NAME, CS_PIN);
  218. if(r!=RT_EOK) {
  219. return -1;
  220. }
  221. h->dev = (struct rt_spi_device*)rt_device_find(SPI_DEV_NAME);
  222. if(h->dev==NULL) {
  223. return -1;
  224. }
  225. sc.data_width = 8;
  226. sc.max_hz = 32 * 1000 * 1000;
  227. sc.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
  228. r = rt_spi_configure(h->dev, &sc);
  229. h->buflen = (h->width*h->height*2)/DIV_NUM;
  230. h->buf = (uint16_t*)malloc(h->buflen);
  231. if (!h->buf) {
  232. LOGE("malloc buffer falied\n");
  233. return -1;
  234. }
  235. st77xx_reset(h);
  236. st77xx_reg_init(h);
  237. st77xx_rotate(h, h->rotate);
  238. gpio_set(BK_PIN, 1);
  239. st77xx_fill(h, COLOR_BLACK);
  240. return 0;
  241. }
  242. int st77xx_deinit(lcd_handle_t *h)
  243. {
  244. gpio_deinit(BK_PIN);
  245. gpio_deinit(DC_PIN);
  246. gpio_deinit(RST_PIN);
  247. free(h->buf);
  248. return 0;
  249. }