lcd_ili9341.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-23 Rbb666 First version
  9. */
  10. #include <rtdevice.h>
  11. #ifdef BSP_USING_SPI_LCD
  12. #include "lcd_ili9341.h"
  13. #include "drivers/spi.h"
  14. /* 2.8 inch LCD module */
  15. /* res pin -> P4_14 */
  16. /* d/c pin -> P4_13 */
  17. /* cs pin -> P4_05 */
  18. /* sda pin -> p4_11 */
  19. /* scl pin -> p4_12 */
  20. _lcd_dev lcddev;
  21. static struct rt_spi_device *lcd_dev;
  22. static void rt_hw_spi_device_attach(const char *bus_name, const char *device_name, void *cs_Pin)
  23. {
  24. struct rt_spi_device *spi_device;
  25. RT_ASSERT(device_name != NULL && bus_name != NULL);
  26. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  27. RT_ASSERT(spi_device != RT_NULL);
  28. rt_err_t err = rt_spi_bus_attach_device(spi_device, device_name, bus_name, cs_Pin);
  29. if (RT_EOK != err)
  30. {
  31. rt_kprintf("%s attach failed.", bus_name);
  32. }
  33. }
  34. rt_err_t spi_lcd_init(void)
  35. {
  36. rt_err_t res = RT_EOK;
  37. rt_hw_spi_device_attach("spi0", "spi30", (void *)LCD_CS_PIN);
  38. lcd_dev = (struct rt_spi_device *)rt_device_find("spi30");
  39. if (lcd_dev != RT_NULL)
  40. {
  41. struct rt_spi_configuration spi_config;
  42. spi_config.data_width = 8;
  43. spi_config.max_hz = 20 * 1000 * 1000;
  44. spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
  45. rt_spi_configure(lcd_dev, &spi_config);
  46. }
  47. else
  48. {
  49. res = RT_ERROR;
  50. }
  51. LCD_Init();
  52. return res;
  53. }
  54. MSH_CMD_EXPORT(spi_lcd_init, lcd_spi_init);
  55. void LCD_RESET(void)
  56. {
  57. LCD_RES_CLR;
  58. DELAY(100);
  59. LCD_RES_SET;
  60. DELAY(100);
  61. }
  62. void LCD_WR_REG(uint8_t reg)
  63. {
  64. LCD_DC_CLR;
  65. rt_spi_send(lcd_dev, &reg, 1);
  66. LCD_DC_SET;
  67. }
  68. void LCD_WR_DATA(uint8_t data)
  69. {
  70. LCD_DC_SET;
  71. rt_spi_send(lcd_dev, &data, 1);
  72. }
  73. void LCD_ReadData(uint8_t *data, uint16_t length)
  74. {
  75. LCD_DC_SET;
  76. rt_spi_transfer(lcd_dev, RT_NULL, &data, length);
  77. }
  78. void LCD_WriteReg(uint8_t reg, uint16_t regdata)
  79. {
  80. LCD_WR_REG(reg);
  81. LCD_WR_DATA(regdata);
  82. }
  83. void LCD_WriteRAM_Prepare(void)
  84. {
  85. LCD_WR_REG(lcddev.wramcmd);
  86. }
  87. void LCD_WriteData_16Bit(uint16_t Data)
  88. {
  89. uint8_t buf[2];
  90. LCD_DC_SET;
  91. buf[0] = Data >> 8;
  92. buf[1] = Data & 0xff;
  93. rt_spi_send(lcd_dev, buf, 2);
  94. }
  95. void LCD_direction(uint8_t direction)
  96. {
  97. lcddev.setxcmd = 0x2A;
  98. lcddev.setycmd = 0x2B;
  99. lcddev.wramcmd = 0x2C;
  100. switch (direction)
  101. {
  102. case 0:
  103. lcddev.width = LCD_W;
  104. lcddev.height = LCD_H;
  105. LCD_WriteReg(0x36, (1 << 3) | (0 << 6) | (0 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
  106. break;
  107. case 1:
  108. lcddev.width = LCD_H;
  109. lcddev.height = LCD_W;
  110. LCD_WriteReg(0x36, (1 << 3) | (0 << 7) | (1 << 6) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
  111. break;
  112. case 2:
  113. lcddev.width = LCD_W;
  114. lcddev.height = LCD_H;
  115. LCD_WriteReg(0x36, (1 << 3) | (1 << 6) | (1 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
  116. break;
  117. case 3:
  118. lcddev.width = LCD_H;
  119. lcddev.height = LCD_W;
  120. LCD_WriteReg(0x36, (1 << 3) | (1 << 7) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
  121. break;
  122. default:
  123. break;
  124. }
  125. }
  126. void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
  127. {
  128. LCD_WR_REG(lcddev.setxcmd);
  129. LCD_WR_DATA(xStar >> 8);
  130. LCD_WR_DATA(0x00FF & xStar);
  131. LCD_WR_DATA(xEnd >> 8);
  132. LCD_WR_DATA(0x00FF & xEnd);
  133. LCD_WR_REG(lcddev.setycmd);
  134. LCD_WR_DATA(yStar >> 8);
  135. LCD_WR_DATA(0x00FF & yStar);
  136. LCD_WR_DATA(yEnd >> 8);
  137. LCD_WR_DATA(0x00FF & yEnd);
  138. LCD_WriteRAM_Prepare();
  139. }
  140. void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
  141. {
  142. LCD_SetWindows(Xpos, Ypos, Xpos, Ypos);
  143. }
  144. void LCD_Clear(uint16_t Color)
  145. {
  146. unsigned int i, m;
  147. uint8_t buf[80];
  148. for (i = 0; i < 40; i++)
  149. {
  150. buf[2 * i] = Color >> 8;
  151. buf[2 * i + 1] = Color & 0xff;
  152. }
  153. LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);
  154. LCD_DC_SET;
  155. for (i = 0; i < lcddev.height; i++)
  156. {
  157. for (m = 0; m < lcddev.width;)
  158. {
  159. m += 40;
  160. rt_spi_send(lcd_dev, buf, 80);
  161. }
  162. }
  163. }
  164. void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color)
  165. {
  166. uint16_t i, j;
  167. LCD_SetWindows(xsta, ysta, xend - 1, yend - 1);
  168. for (i = ysta; i < yend; i++)
  169. {
  170. for (j = xsta; j < xend; j++)
  171. {
  172. LCD_WriteData_16Bit(color);
  173. }
  174. }
  175. }
  176. void lcd_fill_array_spi(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, void *Image)
  177. {
  178. rt_uint32_t size = 0;
  179. size = (Xend - Xstart + 1) * (Yend - Ystart + 1) * 2;/*16bit*/
  180. LCD_SetWindows(Xstart, Ystart, Xend, Yend);
  181. LCD_DC_SET;
  182. rt_spi_send(lcd_dev, Image, size);
  183. }
  184. static void _ili9341_init(void)
  185. {
  186. LCD_WR_REG(0xCF);
  187. LCD_WR_DATA(0x00);
  188. LCD_WR_DATA(0X83);
  189. LCD_WR_DATA(0X30);
  190. LCD_WR_REG(0xED);
  191. LCD_WR_DATA(0x64);
  192. LCD_WR_DATA(0x03);
  193. LCD_WR_DATA(0X12);
  194. LCD_WR_DATA(0X81);
  195. LCD_WR_REG(0xE8);
  196. LCD_WR_DATA(0x85);
  197. LCD_WR_DATA(0x00);
  198. LCD_WR_DATA(0x79);
  199. LCD_WR_REG(0xCB);
  200. LCD_WR_DATA(0x39);
  201. LCD_WR_DATA(0x2C);
  202. LCD_WR_DATA(0x00);
  203. LCD_WR_DATA(0x34);
  204. LCD_WR_DATA(0x02);
  205. LCD_WR_REG(0xF7);
  206. LCD_WR_DATA(0x20);
  207. LCD_WR_REG(0xEA);
  208. LCD_WR_DATA(0x00);
  209. LCD_WR_DATA(0x00);
  210. LCD_WR_REG(0xC0); /* Power control */
  211. LCD_WR_DATA(0x26); /* VRH[5:0] */
  212. LCD_WR_REG(0xC1); /* Power control */
  213. LCD_WR_DATA(0x11); /* SAP[2:0];BT[3:0] */
  214. LCD_WR_REG(0xC5); /* VCM control */
  215. LCD_WR_DATA(0x35);
  216. LCD_WR_DATA(0x3E);
  217. LCD_WR_REG(0xC7); /* VCM control2 */
  218. LCD_WR_DATA(0XBE);
  219. LCD_WR_REG(0x36); /* Memory Access Control */
  220. LCD_WR_DATA(0x28);
  221. LCD_WR_REG(0x3A);
  222. LCD_WR_DATA(0x55);
  223. LCD_WR_REG(0xB1);
  224. LCD_WR_DATA(0x00);
  225. LCD_WR_DATA(0x1B);
  226. LCD_WR_REG(0xB6); /* Display Function Control */
  227. LCD_WR_DATA(0x0A);
  228. LCD_WR_DATA(0xA2);
  229. LCD_WR_REG(0xF2); /* 3Gamma Function Disable */
  230. LCD_WR_DATA(0x08);
  231. LCD_WR_REG(0x26); /* Gamma curve selected */
  232. LCD_WR_DATA(0x01);
  233. LCD_WR_REG(0xE0); /* set Gamma */
  234. LCD_WR_DATA(0X1F);
  235. LCD_WR_DATA(0X1A);
  236. LCD_WR_DATA(0X18);
  237. LCD_WR_DATA(0X0A);
  238. LCD_WR_DATA(0X0F);
  239. LCD_WR_DATA(0X06);
  240. LCD_WR_DATA(0X45);
  241. LCD_WR_DATA(0X87);
  242. LCD_WR_DATA(0X32);
  243. LCD_WR_DATA(0X0A);
  244. LCD_WR_DATA(0X07);
  245. LCD_WR_DATA(0X02);
  246. LCD_WR_DATA(0X07);
  247. LCD_WR_DATA(0X05);
  248. LCD_WR_DATA(0X00);
  249. LCD_WR_REG(0xE1); /* set Gamma */
  250. LCD_WR_DATA(0X00);
  251. LCD_WR_DATA(0X25);
  252. LCD_WR_DATA(0X27);
  253. LCD_WR_DATA(0X05);
  254. LCD_WR_DATA(0X10);
  255. LCD_WR_DATA(0X09);
  256. LCD_WR_DATA(0X3A);
  257. LCD_WR_DATA(0X78);
  258. LCD_WR_DATA(0X4D);
  259. LCD_WR_DATA(0X05);
  260. LCD_WR_DATA(0X18);
  261. LCD_WR_DATA(0X0D);
  262. LCD_WR_DATA(0X38);
  263. LCD_WR_DATA(0X3A);
  264. LCD_WR_DATA(0X2F);
  265. LCD_WR_REG(0x29);
  266. }
  267. void LCD_Init(void)
  268. {
  269. LCD_RESET(); /* LCD Hardware Reset */
  270. LCD_WR_REG(0x11); /* Sleep out */
  271. DELAY(120); /* Delay 120ms */
  272. _ili9341_init();
  273. LCD_direction(USE_HORIZONTAL);
  274. }
  275. static uint16_t color_array[] =
  276. {
  277. WHITE, BLACK, BLUE, BRED,
  278. GRED, GBLUE, RED, YELLOW
  279. };
  280. static rt_err_t lcd_spi_test()
  281. {
  282. uint8_t index = 0;
  283. for (index = 0; index < sizeof(color_array) / sizeof(color_array[0]); index++)
  284. {
  285. LCD_Clear(color_array[index]);
  286. DELAY(200);
  287. }
  288. return RT_EOK;
  289. }
  290. MSH_CMD_EXPORT(lcd_spi_test, lcd_spi_test);
  291. #endif