st77xx.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. if(hd->rotate == 0)
  77. {
  78. }else if(hd->rotate == 90)
  79. {
  80. }else if(hd->rotate == 180)
  81. {
  82. y1+=80;
  83. y2+=80;
  84. }else
  85. {
  86. x1+=80;
  87. x2+=80;
  88. }
  89. write_cmd (hd,ST77XX_CASET);
  90. write_data(hd,x1>>8);
  91. write_data(hd,x1);
  92. write_data(hd,x2>>8);
  93. write_data(hd,x2);
  94. write_cmd (hd,ST77XX_RASET);
  95. write_data(hd,y1>>8);
  96. write_data(hd,y1);
  97. write_data(hd,y2>>8);
  98. write_data(hd,y2);
  99. write_cmd (hd,ST77XX_RAMWR);
  100. }
  101. void st77xx_refresh(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void *data, uint32_t len)
  102. {
  103. if(x>=hd->width || y>=hd->height) {
  104. return;
  105. }
  106. st77xx_set_win(hd, x, y, w, h);
  107. gpio_set(DC_PIN, 1);
  108. rt_spi_send(hd->dev, data, len);
  109. }
  110. void st77xx_draw_pixel(lcd_handle_t *hd, uint16_t x, uint16_t y, uint32_t color)
  111. {
  112. st77xx_set_win(hd, x, y, 1, 1);
  113. write_16bit(hd, color);
  114. }
  115. static void st77xx_reg_init(lcd_handle_t *h)
  116. {
  117. write_cmd (h,0x11);
  118. delay_ms(150);
  119. write_cmd (h,0xB2); //Porch Setting
  120. write_data(h,0x0C);
  121. write_data(h,0x0C);
  122. write_data(h,0x00);
  123. write_data(h,0x33);
  124. write_data(h,0x33);
  125. write_cmd (h,0x35);
  126. write_data(h,0x00);
  127. write_cmd (h,ST77XX_MADCTL);
  128. write_data(h,0x00);
  129. write_cmd (h,ST77XX_PIXEL_FORMAT);
  130. write_data(h,0x05); //03=RGB444,05=RGB565,06=RGB666
  131. write_cmd (h,0xb7); //Gate Control
  132. write_data(h,0x35);
  133. write_cmd (h,0xbb); //VCOM Setting
  134. write_data(h,0x2d);
  135. write_cmd (h,0xC0); //LCM Control
  136. write_data(h,0x2C);
  137. write_cmd (h,0xC2); //VDV and VRH Command Enable
  138. write_data(h,0x01);
  139. write_cmd (h,0xC3); //VRH set
  140. write_data(h,0x15);
  141. write_cmd (h,0xC4); //VDV set
  142. write_data(h,0x20);
  143. write_cmd (h,0xC6); //Frame Rate Control
  144. write_data(h,0x0F);
  145. write_cmd (h,0xD0); //Power Control 1
  146. write_data(h,0xA4);
  147. write_data(h,0xA1);
  148. write_cmd (h,0xD6);
  149. write_data(h,0xA1);
  150. write_cmd (h,0xE0); /* set Positive Voltage Gamma */
  151. write_data(h,0x70);
  152. write_data(h,0x05);
  153. write_data(h,0x0a);
  154. write_data(h,0x0b);
  155. write_data(h,0x0a);
  156. write_data(h,0x27);
  157. write_data(h,0x2f);
  158. write_data(h,0x44);
  159. write_data(h,0x47);
  160. write_data(h,0x37);
  161. write_data(h,0x14);
  162. write_data(h,0x14);
  163. write_data(h,0x29);
  164. write_data(h,0x2f);
  165. write_cmd (h,0xE1); /* set Negative Voltage Gamma */
  166. write_data(h,0x70);
  167. write_data(h,0x07);
  168. write_data(h,0x0c);
  169. write_data(h,0x08);
  170. write_data(h,0x08);
  171. write_data(h,0x04);
  172. write_data(h,0x2f);
  173. write_data(h,0x33);
  174. write_data(h,0x46);
  175. write_data(h,0x18);
  176. write_data(h,0x15);
  177. write_data(h,0x15);
  178. write_data(h,0x2b);
  179. write_data(h,0x2d);
  180. write_cmd (h,0x21); // Dispaly Inversion On
  181. write_cmd (h,0x29); // Display On
  182. write_cmd (h,ST77XX_RAMWR); // Memory Write
  183. }
  184. static void st77xx_reset(lcd_handle_t *h)
  185. {
  186. gpio_set(RST_PIN, 0); /* LCD Hardware Reset */
  187. delay_ms(100);
  188. gpio_set(RST_PIN, 1);
  189. delay_ms(120); /* Delay 120ms */
  190. }
  191. static void fill_color(lcd_handle_t *h, uint16_t color, int cnt)
  192. {
  193. int i,cnt2=(cnt<=h->buflen/2)?cnt:h->buflen/2;
  194. for(i=0; i<cnt2; i++) {
  195. h->buf[i] = color;
  196. }
  197. }
  198. static void write_color(lcd_handle_t *h, uint16_t color, int cnt)
  199. {
  200. int i;
  201. for(i=0; i<cnt; i++) {
  202. write_16bit(h, color);
  203. }
  204. }
  205. void st77xx_fill_rect(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color)
  206. {
  207. int height=hd->height/DIV_NUM;
  208. int i,y1=0,h1=0,times=h/height,left=h%height;
  209. times += left?1:0;
  210. fill_color(hd, color, hd->buflen/2);
  211. for(i=0; i<times; i++) {
  212. y1 = y+i*height;
  213. h1 = ((h1+height)>h)?(h-h1):height;
  214. st77xx_refresh(hd, x, y1, w, h1, hd->buf, w*h1*2);
  215. }
  216. }
  217. void st77xx_fill(lcd_handle_t *h, uint32_t color)
  218. {
  219. st77xx_fill_rect(h, 0, 0, h->width, h->height, color);
  220. }
  221. #define SPI_BUS "spi2"
  222. #define SPI_DEV_NAME "spi2.0"
  223. int st77xx_init(lcd_handle_t *h)
  224. {
  225. int r;
  226. struct rt_spi_configuration sc;
  227. gpio_init(BK_PIN, GPIO_OUT, 0);
  228. gpio_init(DC_PIN, GPIO_OUT, 0);
  229. gpio_init(RST_PIN, GPIO_OUT, 0);
  230. r = rt_hw_spi_device_attach(SPI_BUS, SPI_DEV_NAME, CS_PIN);
  231. if(r!=RT_EOK) {
  232. return -1;
  233. }
  234. h->dev = (struct rt_spi_device*)rt_device_find(SPI_DEV_NAME);
  235. if(h->dev==NULL) {
  236. return -1;
  237. }
  238. sc.data_width = 8;
  239. sc.max_hz = 32 * 1000 * 1000;
  240. sc.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
  241. r = rt_spi_configure(h->dev, &sc);
  242. h->buflen = (h->width*h->height*2)/DIV_NUM;
  243. h->buf = (uint16_t*)malloc(h->buflen);
  244. if (!h->buf) {
  245. LOGE("malloc buffer falied\n");
  246. return -1;
  247. }
  248. st77xx_reset(h);
  249. st77xx_reg_init(h);
  250. st77xx_rotate(h, h->rotate);
  251. gpio_set(BK_PIN, 1);
  252. st77xx_fill(h, COLOR_BLACK);
  253. return 0;
  254. }
  255. int st77xx_deinit(lcd_handle_t *h)
  256. {
  257. gpio_deinit(BK_PIN);
  258. gpio_deinit(DC_PIN);
  259. gpio_deinit(RST_PIN);
  260. free(h->buf);
  261. return 0;
  262. }