st77xx.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #include "lcd.h"
  2. #include "spi.h"
  3. #include "FreeRTOS.h"
  4. #define DIV_NUM 10
  5. #define INVERSE 1
  6. #define ST_OFFSET 80
  7. #define BIT(x) (1<<x)
  8. #define ST77XX_CASET 0x2A
  9. #define ST77XX_RASET 0x2B
  10. #define ST77XX_RAMWR 0x2C
  11. #define ST77XX_RAMRD 0x2E
  12. #define ST77XX_MADCTL 0x36
  13. #define ST77XX_PIXEL_FORMAT 0x3A
  14. #define ST77XX_MADCTL_MH BIT(2)
  15. #define ST77XX_MADCTL_ML BIT(4)
  16. #define ST77XX_MADCTL_MV BIT(5)
  17. #define ST77XX_MADCTL_MX BIT(6)
  18. #define ST77XX_MADCTL_MY BIT(7)
  19. #define ST77XX_MADCTL_RGB 0x00
  20. #define ST77XX_MADCTL_BGR BIT(3)
  21. //#define delay_ms(x) rt_thread_mdelay(x)
  22. #define TFT_PORT GPIOD
  23. #define TFT_RST_PIN GPIO_PIN_9
  24. #define TFT_DC_PIN GPIO_PIN_8
  25. #define TFT_BG_PIN GPIO_PIN_10
  26. #define TFT_SCL_PIN GPIO_PIN_13
  27. #define TFT_MOSI_PIN GPIO_PIN_15
  28. #define TFT_CS_PIN GPIO_PIN_12
  29. #define LCD_SCLK_Clr() gpio_bit_reset(GPIOB,TFT_SCL_PIN)//SCL=SCLK
  30. #define LCD_SCLK_Set() gpio_bit_set(GPIOB,TFT_SCL_PIN)
  31. #define LCD_MOSI_Clr() gpio_bit_reset(GPIOB,TFT_MOSI_PIN)//SDA=MOSI
  32. #define LCD_MOSI_Set() gpio_bit_set(GPIOB,TFT_MOSI_PIN)
  33. #define LCD_RES_Clr() gpio_bit_reset(TFT_PORT,TFT_RST_PIN)//RES
  34. #define LCD_RES_Set() gpio_bit_set(TFT_PORT,TFT_RST_PIN)
  35. #define LCD_DC_Clr() gpio_bit_reset(TFT_PORT,TFT_DC_PIN)//DC
  36. #define LCD_DC_Set() gpio_bit_set(TFT_PORT,TFT_DC_PIN)
  37. #define LCD_CS_Clr() gpio_bit_reset(GPIOB,TFT_CS_PIN)//CS
  38. #define LCD_CS_Set() gpio_bit_set(GPIOB,TFT_CS_PIN)
  39. #define LCD_BLK_Clr() gpio_bit_reset(TFT_PORT,TFT_BG_PIN)//BLK
  40. #define LCD_BLK_Set() gpio_bit_set(TFT_PORT,TFT_BG_PIN)
  41. #define SPI_SOFT 0
  42. #define SPI_HARD 1
  43. #define SPI_HARD_DMA 2
  44. #define USE_SPI_TYPE SPI_HARD_DMA
  45. void st77xx_fill(lcd_handle_t *h, uint32_t color);
  46. static void spi1_byte_write(uint8_t data)
  47. {
  48. int i;
  49. LCD_CS_Clr();
  50. for(i=0;i<8;i++)
  51. {
  52. LCD_SCLK_Clr();
  53. if(data&0x80)
  54. {
  55. LCD_MOSI_Set();
  56. }
  57. else
  58. {
  59. LCD_MOSI_Clr();
  60. }
  61. LCD_SCLK_Set();
  62. data<<=1;
  63. }
  64. LCD_CS_Set();
  65. //LCD_SCLK_Set();
  66. }
  67. static void spi1_byte_hard_write(uint8_t data,uint16_t timeout)
  68. {
  69. uint16_t _time = timeout;
  70. LCD_CS_Clr();
  71. while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_TBE))
  72. {
  73. if(timeout)
  74. {
  75. timeout --;
  76. }
  77. else
  78. break;
  79. }
  80. spi_i2s_data_transmit(SPI1,data);
  81. while(RESET == spi_i2s_flag_get(SPI1,SPI_FLAG_RBNE))
  82. {
  83. if(_time)
  84. {
  85. _time --;
  86. }
  87. else
  88. break;
  89. }
  90. spi_i2s_data_receive(SPI1);
  91. LCD_CS_Set();
  92. }
  93. static spi1_dma_data_write(uint16_t *data,uint32_t lenth)
  94. {
  95. //LCD_DC_Set();
  96. LCD_CS_Clr();
  97. dma_channel_disable(DMA0,DMA_CH4);
  98. dma_memory_address_config(DMA0,DMA_CH4,(uint32_t)(data));
  99. dma_transfer_number_config(DMA0,DMA_CH4,lenth);
  100. dma_channel_enable(DMA0,DMA_CH4);
  101. spi_dma_enable(SPI1, SPI_DMA_TRANSMIT);
  102. while(!dma_flag_get(DMA0, DMA_CH4, DMA_FLAG_FTF));
  103. dma_flag_clear(DMA0, DMA_CH4, DMA_FLAG_FTF);
  104. LCD_CS_Set();
  105. }
  106. static void write_cmd(lcd_handle_t *h, uint8_t reg)
  107. {
  108. LCD_DC_Clr();
  109. #if (USE_SPI_TYPE == SPI_SOFT)
  110. spi1_byte_write(reg);
  111. #elif (USE_SPI_TYPE == SPI_HARD)
  112. spi1_byte_hard_write(reg,200);
  113. #else
  114. spi1_dma_data_write(&reg,1);
  115. #endif
  116. LCD_DC_Set();
  117. }
  118. static void write_data(lcd_handle_t *h, uint8_t data)
  119. {
  120. #if (USE_SPI_TYPE == SPI_SOFT)
  121. spi1_byte_write(data);
  122. #elif (USE_SPI_TYPE == SPI_HARD)
  123. spi1_byte_hard_write(data,200);
  124. #else
  125. spi1_dma_data_write(&data,1);
  126. #endif
  127. }
  128. static void write_cmd_data(lcd_handle_t *h, uint8_t reg, uint16_t data)
  129. {
  130. write_cmd (h,reg);
  131. write_data(h,data);
  132. }
  133. static void read_data(lcd_handle_t *h, uint8_t *data, int length)
  134. {
  135. }
  136. static void write_16bit(lcd_handle_t *h, uint16_t data)
  137. {
  138. #if (USE_SPI_TYPE == SPI_SOFT)
  139. spi1_byte_write(data >> 8);
  140. spi1_byte_write(data);
  141. #elif (USE_SPI_TYPE == SPI_HARD)
  142. spi1_byte_hard_write(data>>8,200);
  143. spi1_byte_hard_write(data,200);
  144. #else
  145. spi1_dma_data_write(&data,2);
  146. #endif
  147. }
  148. void st77xx_rotate(lcd_handle_t *h, int rotate)
  149. {
  150. uint8_t madctl=0,mode=INVERSE?ST77XX_MADCTL_BGR:ST77XX_MADCTL_RGB;
  151. switch (rotate)
  152. {
  153. case 0:
  154. madctl = mode;
  155. break;
  156. case 90:
  157. madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MX | mode);
  158. break;
  159. case 180:
  160. madctl = (ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | mode);
  161. break;
  162. case 270:
  163. madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MY | mode);
  164. break;
  165. default:
  166. break;
  167. }
  168. write_cmd_data(h, ST77XX_MADCTL, madctl);
  169. }
  170. void st77xx_set_win(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
  171. {
  172. int x1=x,y1=y;
  173. int x2=x+w-1,y2=y+h-1;
  174. if(hd->rotate == 0)
  175. {
  176. }else if(hd->rotate == 90)
  177. {
  178. }else if(hd->rotate == 180)
  179. {
  180. y1+=80;
  181. y2+=80;
  182. }else
  183. {
  184. x1+=80;
  185. x2+=80;
  186. }
  187. write_cmd (hd,ST77XX_CASET);
  188. write_data(hd,x1>>8);
  189. write_data(hd,x1);
  190. write_data(hd,x2>>8);
  191. write_data(hd,x2);
  192. write_cmd (hd,ST77XX_RASET);
  193. write_data(hd,y1>>8);
  194. write_data(hd,y1);
  195. write_data(hd,y2>>8);
  196. write_data(hd,y2);
  197. write_cmd (hd,ST77XX_RAMWR);
  198. }
  199. void st77xx_refresh(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void *data, uint32_t len)
  200. {
  201. if(x>=hd->width || y>=hd->height) {
  202. return;
  203. }
  204. st77xx_set_win(hd, x, y, w, h);
  205. #if (USE_SPI_TYPE == SPI_SOFT)
  206. for(int i = 0;i < len;i++)
  207. {
  208. spi1_byte_write(*(uint8_t*)(&data[i]));
  209. }
  210. #elif (USE_SPI_TYPE == SPI_HARD)
  211. for(int i = 0;i < len;i++)
  212. spi1_byte_hard_write(*(uint8_t*)(&data[i]),200);
  213. #else
  214. spi1_dma_data_write(data,len);
  215. #endif
  216. }
  217. void st77xx_draw_pixel(lcd_handle_t *hd, uint16_t x, uint16_t y, uint32_t color)
  218. {
  219. st77xx_set_win(hd, x, y, 1, 1);
  220. write_16bit(hd, color);
  221. }
  222. static void st77xx_reg_init(lcd_handle_t *h)
  223. {
  224. write_cmd (h,0x11);
  225. //delay_ms(150);
  226. vTaskDelay(120);
  227. write_cmd (h,0xB2); //Porch Setting
  228. write_data(h,0x0C);
  229. write_data(h,0x0C);
  230. write_data(h,0x00);
  231. write_data(h,0x33);
  232. write_data(h,0x33);
  233. write_cmd (h,0x35);
  234. write_data(h,0x00);
  235. write_cmd (h,ST77XX_MADCTL);
  236. write_data(h,0x00);
  237. write_cmd (h,ST77XX_PIXEL_FORMAT);
  238. write_data(h,0x05); //03=RGB444,05=RGB565,06=RGB666
  239. write_cmd (h,0xb7); //Gate Control
  240. write_data(h,0x35);
  241. write_cmd (h,0xbb); //VCOM Setting
  242. write_data(h,0x2d);
  243. write_cmd (h,0xC0); //LCM Control
  244. write_data(h,0x2C);
  245. write_cmd (h,0xC2); //VDV and VRH Command Enable
  246. write_data(h,0x01);
  247. write_cmd (h,0xC3); //VRH set
  248. write_data(h,0x15);
  249. write_cmd (h,0xC4); //VDV set
  250. write_data(h,0x20);
  251. write_cmd (h,0xC6); //Frame Rate Control
  252. write_data(h,0x0F);
  253. write_cmd (h,0xD0); //Power Control 1
  254. write_data(h,0xA4);
  255. write_data(h,0xA1);
  256. write_cmd (h,0xD6);
  257. write_data(h,0xA1);
  258. write_cmd (h,0xE0); /* set Positive Voltage Gamma */
  259. write_data(h,0x70);
  260. write_data(h,0x05);
  261. write_data(h,0x0a);
  262. write_data(h,0x0b);
  263. write_data(h,0x0a);
  264. write_data(h,0x27);
  265. write_data(h,0x2f);
  266. write_data(h,0x44);
  267. write_data(h,0x47);
  268. write_data(h,0x37);
  269. write_data(h,0x14);
  270. write_data(h,0x14);
  271. write_data(h,0x29);
  272. write_data(h,0x2f);
  273. write_cmd (h,0xE1); /* set Negative Voltage Gamma */
  274. write_data(h,0x70);
  275. write_data(h,0x07);
  276. write_data(h,0x0c);
  277. write_data(h,0x08);
  278. write_data(h,0x08);
  279. write_data(h,0x04);
  280. write_data(h,0x2f);
  281. write_data(h,0x33);
  282. write_data(h,0x46);
  283. write_data(h,0x18);
  284. write_data(h,0x15);
  285. write_data(h,0x15);
  286. write_data(h,0x2b);
  287. write_data(h,0x2d);
  288. write_cmd (h,0x21); // Dispaly Inversion On
  289. write_cmd (h,0x29); // Display On
  290. write_cmd (h,ST77XX_RAMWR); // Memory Write
  291. //vTaskDelay(50);
  292. }
  293. static void st77xx_reset(lcd_handle_t *h)
  294. {
  295. LCD_RES_Clr();
  296. vTaskDelay(100);
  297. LCD_RES_Set();
  298. vTaskDelay(120);
  299. LCD_BLK_Set();
  300. vTaskDelay(100);
  301. }
  302. void LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color)
  303. {
  304. unsigned short i,j;
  305. //LCD_Address_Set(xsta,ysta,xend-1,yend-1);//ÉèÖÃÏÔʾ·¶Î§
  306. st77xx_set_win(NULL,xsta,ysta, xend-1, yend-1);
  307. for(i=ysta;i<yend;i++)
  308. {
  309. for(j=xsta;j<xend;j++)
  310. {
  311. write_16bit(NULL,color);
  312. }
  313. }
  314. }
  315. static void write_color(lcd_handle_t *h, uint16_t color, int cnt)
  316. {
  317. int i;
  318. for(i=0; i<cnt; i++) {
  319. write_16bit(h, color);
  320. }
  321. }
  322. static void fill_color(lcd_handle_t *h, uint16_t color, int cnt)
  323. {
  324. int i,cnt2=(cnt<=h->buflen/2)?cnt:h->buflen/2;
  325. for(i=0; i<cnt2; i++) {
  326. *(uint16_t*)(&h->buf[i]) = color;
  327. }
  328. // write_color(h,color,cnt2);
  329. }
  330. void st77xx_fill_rect(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color)
  331. {
  332. int height=hd->height/DIV_NUM;
  333. int i,y1=0,h1=0,times=h/height,left=h%height;
  334. times += left?1:0;
  335. fill_color(hd, color, hd->buflen/2);
  336. for(i=0; i<times; i++) {
  337. y1 = y+i*height;
  338. h1 = ((h1+height)>h)?(h-h1):height;
  339. st77xx_refresh(hd, x, y1, w, h1, hd->buf, w*h1*2);
  340. }
  341. }
  342. void st77xx_fill(lcd_handle_t *h, uint32_t color)
  343. {
  344. st77xx_fill_rect(h, 0, 0, h->width, h->height, color);
  345. }
  346. uint8_t lcd_cache[11520] = {0};
  347. int st77xx_init(lcd_handle_t *h)
  348. {
  349. rcu_periph_clock_enable(RCU_GPIOD);
  350. rcu_periph_clock_enable(RCU_GPIOB);
  351. #if (USE_SPI_TYPE == SPI_SOFT)
  352. gpio_init(TFT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_RST_PIN | TFT_DC_PIN | TFT_BG_PIN);
  353. gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_SCL_PIN | TFT_MOSI_PIN | TFT_CS_PIN);
  354. gpio_bit_set(TFT_PORT,TFT_RST_PIN | TFT_DC_PIN | TFT_BG_PIN);
  355. gpio_bit_set(GPIOB,TFT_SCL_PIN | TFT_MOSI_PIN | TFT_CS_PIN);
  356. #else
  357. gpio_init(TFT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_RST_PIN | TFT_DC_PIN | TFT_BG_PIN);
  358. gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TFT_SCL_PIN | TFT_MOSI_PIN | TFT_CS_PIN);
  359. gpio_bit_set(TFT_PORT,TFT_RST_PIN | TFT_DC_PIN | TFT_BG_PIN);
  360. gpio_bit_set(GPIOB,TFT_SCL_PIN | TFT_MOSI_PIN | TFT_CS_PIN);
  361. spix_init();
  362. #endif
  363. h->buflen = 11520;
  364. h->buf = &lcd_cache[0];
  365. st77xx_reset(h);
  366. st77xx_reg_init(h);
  367. st77xx_fill(h, COLOR_BLACK);
  368. st77xx_rotate(h, h->rotate);
  369. //LCD_Fill(0,0,240,240,0XFFFF);
  370. return 0;
  371. }
  372. int st77xx_deinit(lcd_handle_t *h)
  373. {
  374. return 0;
  375. }