st77xx.c 7.1 KB

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