drv_lcd.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #include <drv_lcd.h>
  2. #include <stdlib.h>
  3. #define SPI_PORT spi1
  4. uint slice_num;
  5. LCD_ATTRIBUTES LCD;
  6. /******************************************************************************
  7. function : Hardware reset
  8. parameter:
  9. ******************************************************************************/
  10. static void LCD_Reset(void)
  11. {
  12. DEV_Digital_Write(LCD_RST_PIN, 1);
  13. rt_thread_mdelay(100);
  14. DEV_Digital_Write(LCD_RST_PIN, 0);
  15. rt_thread_mdelay(100);
  16. DEV_Digital_Write(LCD_RST_PIN, 1);
  17. rt_thread_mdelay(100);
  18. }
  19. /******************************************************************************
  20. function : send command
  21. parameter:
  22. Reg : Command register
  23. ******************************************************************************/
  24. static void LCD_SendCommand(UBYTE Reg)
  25. {
  26. DEV_Digital_Write(LCD_DC_PIN, 0);
  27. DEV_Digital_Write(LCD_CS_PIN, 0);
  28. DEV_SPI_WriteByte(Reg);
  29. DEV_Digital_Write(LCD_CS_PIN, 1);
  30. }
  31. /******************************************************************************
  32. function : send data
  33. parameter:
  34. Data : Write data
  35. ******************************************************************************/
  36. static void LCD_SendData_8Bit(UBYTE Data)
  37. {
  38. DEV_Digital_Write(LCD_DC_PIN, 1);
  39. DEV_Digital_Write(LCD_CS_PIN, 0);
  40. DEV_SPI_WriteByte(Data);
  41. DEV_Digital_Write(LCD_CS_PIN, 1);
  42. }
  43. /******************************************************************************
  44. function : send data
  45. parameter:
  46. Data : Write data
  47. ******************************************************************************/
  48. static void LCD_SendData_16Bit(UWORD Data)
  49. {
  50. DEV_Digital_Write(LCD_DC_PIN, 1);
  51. DEV_Digital_Write(LCD_CS_PIN, 0);
  52. DEV_SPI_WriteByte((Data >> 8) & 0xFF);
  53. DEV_SPI_WriteByte(Data & 0xFF);
  54. DEV_Digital_Write(LCD_CS_PIN, 1);
  55. }
  56. /******************************************************************************
  57. function : Initialize the lcd register
  58. parameter:
  59. ******************************************************************************/
  60. static void LCD_InitReg(void)
  61. {
  62. LCD_SendCommand(0x3A);
  63. LCD_SendData_8Bit(0x05);
  64. LCD_SendCommand(0xB2);
  65. LCD_SendData_8Bit(0x0C);
  66. LCD_SendData_8Bit(0x0C);
  67. LCD_SendData_8Bit(0x00);
  68. LCD_SendData_8Bit(0x33);
  69. LCD_SendData_8Bit(0x33);
  70. LCD_SendCommand(0xB7); // Gate Control
  71. LCD_SendData_8Bit(0x35);
  72. LCD_SendCommand(0xBB); // VCOM Setting
  73. LCD_SendData_8Bit(0x19);
  74. LCD_SendCommand(0xC0); // LCM Control
  75. LCD_SendData_8Bit(0x2C);
  76. LCD_SendCommand(0xC2); // VDV and VRH Command Enable
  77. LCD_SendData_8Bit(0x01);
  78. LCD_SendCommand(0xC3); // VRH Set
  79. LCD_SendData_8Bit(0x12);
  80. LCD_SendCommand(0xC4); // VDV Set
  81. LCD_SendData_8Bit(0x20);
  82. LCD_SendCommand(0xC6); // Frame Rate Control in Normal Mode
  83. LCD_SendData_8Bit(0x01); // 110hz
  84. LCD_SendCommand(0xD0); // Power Control 1
  85. LCD_SendData_8Bit(0xA4);
  86. LCD_SendData_8Bit(0xA1);
  87. LCD_SendCommand(0xE0); // Positive Voltage Gamma Control
  88. LCD_SendData_8Bit(0xD0);
  89. LCD_SendData_8Bit(0x04);
  90. LCD_SendData_8Bit(0x0D);
  91. LCD_SendData_8Bit(0x11);
  92. LCD_SendData_8Bit(0x13);
  93. LCD_SendData_8Bit(0x2B);
  94. LCD_SendData_8Bit(0x3F);
  95. LCD_SendData_8Bit(0x54);
  96. LCD_SendData_8Bit(0x4C);
  97. LCD_SendData_8Bit(0x18);
  98. LCD_SendData_8Bit(0x0D);
  99. LCD_SendData_8Bit(0x0B);
  100. LCD_SendData_8Bit(0x1F);
  101. LCD_SendData_8Bit(0x23);
  102. LCD_SendCommand(0xE1); // Negative Voltage Gamma Control
  103. LCD_SendData_8Bit(0xD0);
  104. LCD_SendData_8Bit(0x04);
  105. LCD_SendData_8Bit(0x0C);
  106. LCD_SendData_8Bit(0x11);
  107. LCD_SendData_8Bit(0x13);
  108. LCD_SendData_8Bit(0x2C);
  109. LCD_SendData_8Bit(0x3F);
  110. LCD_SendData_8Bit(0x44);
  111. LCD_SendData_8Bit(0x51);
  112. LCD_SendData_8Bit(0x2F);
  113. LCD_SendData_8Bit(0x1F);
  114. LCD_SendData_8Bit(0x1F);
  115. LCD_SendData_8Bit(0x20);
  116. LCD_SendData_8Bit(0x23);
  117. LCD_SendCommand(0x21); // Display Inversion On
  118. LCD_SendCommand(0x11); // Sleep Out
  119. LCD_SendCommand(0x29); // Display On
  120. }
  121. /********************************************************************************
  122. function: Set the resolution and scanning method of the screen
  123. parameter:
  124. Scan_dir: Scan direction
  125. ********************************************************************************/
  126. static void LCD_SetAttributes(UBYTE Scan_dir)
  127. {
  128. // Get the screen scan direction
  129. LCD.SCAN_DIR = Scan_dir;
  130. UBYTE MemoryAccessReg = 0x00;
  131. // Get GRAM and LCD width and height
  132. if (Scan_dir == HORIZONTAL)
  133. {
  134. LCD.HEIGHT = LCD_WIDTH;
  135. LCD.WIDTH = LCD_HEIGHT;
  136. MemoryAccessReg = 0X70;
  137. }
  138. else
  139. {
  140. LCD.HEIGHT = LCD_HEIGHT;
  141. LCD.WIDTH = LCD_WIDTH;
  142. MemoryAccessReg = 0X00;
  143. }
  144. // Set the read / write scan direction of the frame memory
  145. LCD_SendCommand(0x36); // MX, MY, RGB mode
  146. LCD_SendData_8Bit(MemoryAccessReg); // 0x08 set RGB
  147. }
  148. /********************************************************************************
  149. function : Initialize the lcd
  150. parameter:
  151. ********************************************************************************/
  152. void LCD_Init(UBYTE Scan_dir)
  153. {
  154. DEV_SET_PWM(50);
  155. // Hardware reset
  156. LCD_Reset();
  157. // Set the resolution and scanning method of the screen
  158. LCD_SetAttributes(Scan_dir);
  159. // Set the initialization register
  160. LCD_InitReg();
  161. }
  162. void LCD_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
  163. {
  164. // set the X coordinates
  165. LCD_SendCommand(0x2A);
  166. LCD_SendData_8Bit((Xstart >> 8) & 0xFF);
  167. LCD_SendData_8Bit(Xstart & 0xFF);
  168. LCD_SendData_8Bit(((Xend - 1) >> 8) & 0xFF);
  169. LCD_SendData_8Bit((Xend - 1) & 0xFF);
  170. // set the Y coordinates
  171. LCD_SendCommand(0x2B);
  172. LCD_SendData_8Bit((Ystart >> 8) & 0xFF);
  173. LCD_SendData_8Bit(Ystart & 0xFF);
  174. LCD_SendData_8Bit(((Yend - 1) >> 8) & 0xFF);
  175. LCD_SendData_8Bit((Yend - 1) & 0xFF);
  176. LCD_SendCommand(0X2C);
  177. }
  178. /******************************************************************************
  179. function : Clear screen
  180. parameter:
  181. ******************************************************************************/
  182. void LCD_Clear(UWORD Color)
  183. {
  184. UWORD j, i;
  185. UWORD Image[LCD.WIDTH * LCD.HEIGHT];
  186. Color = ((Color << 8) & 0xff00) | (Color >> 8);
  187. for (j = 0; j < LCD.HEIGHT * LCD.WIDTH; j++)
  188. {
  189. Image[j] = Color;
  190. }
  191. LCD_SetWindows(0, 0, LCD.WIDTH, LCD.HEIGHT);
  192. DEV_Digital_Write(LCD_DC_PIN, 1);
  193. DEV_Digital_Write(LCD_CS_PIN, 0);
  194. for (j = 0; j < LCD.HEIGHT; j++)
  195. {
  196. DEV_SPI_Write_nByte((uint8_t *) &Image[j * LCD.WIDTH], LCD.WIDTH * 2);
  197. }
  198. DEV_Digital_Write(LCD_CS_PIN, 1);
  199. }
  200. /******************************************************************************
  201. function : Sends the image buffer in RAM to displays
  202. parameter:
  203. ******************************************************************************/
  204. void LCD_Display(UWORD *Image)
  205. {
  206. UWORD j;
  207. LCD_SetWindows(0, 0, LCD.WIDTH, LCD.HEIGHT);
  208. DEV_Digital_Write(LCD_DC_PIN, 1);
  209. DEV_Digital_Write(LCD_CS_PIN, 0);
  210. for (j = 0; j < LCD.HEIGHT; j++)
  211. {
  212. DEV_SPI_Write_nByte((uint8_t *) &Image[j * LCD.WIDTH], LCD.WIDTH * 2);
  213. }
  214. DEV_Digital_Write(LCD_CS_PIN, 1);
  215. LCD_SendCommand(0x29);
  216. }
  217. /******************************************************************************
  218. function : Sends the image buffer in RAM to displays
  219. parameter:
  220. Xstart : X direction Start coordinates
  221. Ystart : Y direction Start coordinates
  222. Xend : X direction end coordinates
  223. Yend : Y direction end coordinates
  224. Image : Written content
  225. ******************************************************************************/
  226. void LCD_DisplayWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD *Image)
  227. {
  228. // display
  229. UDOUBLE Addr = 0;
  230. UWORD j;
  231. LCD_SetWindows(Xstart, Ystart, Xend, Yend);
  232. DEV_Digital_Write(LCD_DC_PIN, 1);
  233. DEV_Digital_Write(LCD_CS_PIN, 0);
  234. for (j = Ystart; j < Yend - 1; j++)
  235. {
  236. Addr = Xstart + j * LCD.WIDTH;
  237. DEV_SPI_Write_nByte((uint8_t *) &Image[Addr], (Xend - Xstart) * 2);
  238. }
  239. DEV_Digital_Write(LCD_CS_PIN, 1);
  240. }
  241. /******************************************************************************
  242. function : Change the color of a point
  243. parameter:
  244. X : X coordinates
  245. Y : Y coordinates
  246. Color : Color
  247. ******************************************************************************/
  248. void LCD_DisplayPoint(UWORD X, UWORD Y, UWORD Color)
  249. {
  250. LCD_SetWindows(X, Y, X, Y);
  251. LCD_SendData_16Bit(Color);
  252. }
  253. void Handler_LCD(int signo)
  254. {
  255. // System Exit
  256. rt_kprintf("\r\nHandler:Program stop\r\n");
  257. DEV_Module_Exit();
  258. exit(0);
  259. }
  260. /**
  261. * GPIO read and write
  262. **/
  263. void DEV_Digital_Write(UWORD Pin, UBYTE Value)
  264. {
  265. gpio_put(Pin, Value);
  266. }
  267. UBYTE DEV_Digital_Read(UWORD Pin)
  268. {
  269. return gpio_get(Pin);
  270. }
  271. /**
  272. * GPIO Mode
  273. **/
  274. void DEV_GPIO_Mode(UWORD Pin, UWORD Mode)
  275. {
  276. gpio_init(Pin);
  277. if (Mode == 0 || Mode == GPIO_IN)
  278. {
  279. gpio_set_dir(Pin, GPIO_IN);
  280. }
  281. else
  282. {
  283. gpio_set_dir(Pin, GPIO_OUT);
  284. }
  285. }
  286. /**
  287. * SPI
  288. **/
  289. void DEV_SPI_WriteByte(UBYTE Value)
  290. {
  291. spi_write_blocking(SPI_PORT, &Value, 1);
  292. }
  293. void DEV_SPI_Write_nByte(UBYTE pData[], UDOUBLE Len)
  294. {
  295. spi_write_blocking(SPI_PORT, pData, Len);
  296. }
  297. void DEV_GPIO_Init(void)
  298. {
  299. DEV_GPIO_Mode(LCD_RST_PIN, 1);
  300. DEV_GPIO_Mode(LCD_DC_PIN, 1);
  301. DEV_GPIO_Mode(LCD_CS_PIN, 1);
  302. DEV_GPIO_Mode(LCD_BL_PIN, 1);
  303. DEV_Digital_Write(LCD_CS_PIN, 1);
  304. DEV_Digital_Write(LCD_DC_PIN, 0);
  305. DEV_Digital_Write(LCD_BL_PIN, 1);
  306. }
  307. /******************************************************************************
  308. function: Module Initialize, the library and initialize the pins, SPI protocol
  309. parameter:
  310. Info:
  311. ******************************************************************************/
  312. UBYTE DEV_Module_Init(void)
  313. {
  314. // SPI Config
  315. spi_init(SPI_PORT, 80000 * 1000);
  316. gpio_set_function(LCD_CLK_PIN, GPIO_FUNC_SPI);
  317. gpio_set_function(LCD_MOSI_PIN, GPIO_FUNC_SPI);
  318. // GPIO Config
  319. DEV_GPIO_Init();
  320. // PWM Config
  321. gpio_set_function(LCD_BL_PIN, GPIO_FUNC_PWM);
  322. slice_num = pwm_gpio_to_slice_num(LCD_BL_PIN);
  323. pwm_set_wrap(slice_num, 100);
  324. pwm_set_chan_level(slice_num, PWM_CHAN_B, 1);
  325. pwm_set_clkdiv(slice_num, 50);
  326. pwm_set_enabled(slice_num, true);
  327. rt_kprintf("DEV_Module_Init OK \r\n");
  328. return 0;
  329. }
  330. void DEV_SET_PWM(UBYTE Value)
  331. {
  332. if (Value < 0 || Value > 100)
  333. {
  334. rt_kprintf("DEV_SET_PWM Error \r\n");
  335. }
  336. else
  337. {
  338. pwm_set_chan_level(slice_num, PWM_CHAN_B, Value);
  339. }
  340. }
  341. UBYTE SPI_Init(void)
  342. {
  343. DEV_Module_Init();
  344. return 0;
  345. }
  346. bool _swapBytes;
  347. UDOUBLE dma_tx_channel;
  348. dma_channel_config dma_tx_config;
  349. /***************************************************************************************
  350. ** Function name: dmaWait
  351. ** Description: Wait until DMA is over (blocking!)
  352. ***************************************************************************************/
  353. void dmaWait(void)
  354. {
  355. while (dma_channel_is_busy(dma_tx_channel))
  356. ;
  357. // For SPI must also wait for FIFO to flush and reset format
  358. while (spi_get_hw(SPI_PORT)->sr & SPI_SSPSR_BSY_BITS)
  359. {
  360. };
  361. spi_set_format(SPI_PORT, 16, (spi_cpol_t) 0, (spi_cpha_t) 0, SPI_MSB_FIRST);
  362. }
  363. /***************************************************************************************
  364. ** Function name: pushPixelsDMA
  365. ** Description: Push pixels to TFT
  366. ***************************************************************************************/
  367. void pushPixelsDMA(UWORD* image, UDOUBLE len)
  368. {
  369. if ((len == 0))
  370. return;
  371. dmaWait();
  372. channel_config_set_bswap(&dma_tx_config, !_swapBytes);
  373. dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_PORT)->dr, (UWORD*) image, len, true);
  374. }
  375. bool initDMA(bool ctrl_cs)
  376. {
  377. dma_tx_channel = dma_claim_unused_channel(true);
  378. dma_tx_config = dma_channel_get_default_config(dma_tx_channel);
  379. channel_config_set_transfer_data_size(&dma_tx_config, DMA_SIZE_16);
  380. channel_config_set_dreq(&dma_tx_config, spi_get_index(SPI_PORT) ? DREQ_SPI1_TX : DREQ_SPI0_TX);
  381. return true;
  382. }