1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-08-11     RT-Thread    the first version
9  */
10 #include "rtthread.h"
11 #include "stm32f4xx_hal.h"
12 #include "ili9341.h"
13 
14 /**
15   * @brief  LCD Control pin
16   */
17 #define LCD_NCS_PIN                             GPIO_PIN_2
18 #define LCD_NCS_GPIO_PORT                       GPIOC
19 #define LCD_NCS_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOC_CLK_ENABLE()
20 #define LCD_NCS_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOC_CLK_DISABLE()
21 
22 /**
23   * @brief  LCD Command/data pin
24   */
25 #define LCD_WRX_PIN                             GPIO_PIN_13
26 #define LCD_WRX_GPIO_PORT                       GPIOD
27 #define LCD_WRX_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOD_CLK_ENABLE()
28 #define LCD_WRX_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOD_CLK_DISABLE()
29 
30 #define LCD_RDX_PIN                             GPIO_PIN_12
31 #define LCD_RDX_GPIO_PORT                       GPIOD
32 #define LCD_RDX_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOD_CLK_ENABLE()
33 #define LCD_RDX_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOD_CLK_DISABLE()
34 
35 /* Maximum Timeout values for flags waiting loops */
36 #define SPIx_TIMEOUT_MAX              ((uint32_t)0x1000)
37 
38 /* Chip Select macro definition */
39 #define LCD_CS_LOW()       HAL_GPIO_WritePin(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, GPIO_PIN_RESET)
40 #define LCD_CS_HIGH()      HAL_GPIO_WritePin(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, GPIO_PIN_SET)
41 
42 /* Set WRX High to send data */
43 #define LCD_WRX_LOW()      HAL_GPIO_WritePin(LCD_WRX_GPIO_PORT, LCD_WRX_PIN, GPIO_PIN_RESET)
44 #define LCD_WRX_HIGH()     HAL_GPIO_WritePin(LCD_WRX_GPIO_PORT, LCD_WRX_PIN, GPIO_PIN_SET)
45 
46 /* Set WRX High to send data */
47 #define LCD_RDX_LOW()      HAL_GPIO_WritePin(LCD_RDX_GPIO_PORT, LCD_RDX_PIN, GPIO_PIN_RESET)
48 #define LCD_RDX_HIGH()     HAL_GPIO_WritePin(LCD_RDX_GPIO_PORT, LCD_RDX_PIN, GPIO_PIN_SET)
49 
50 static uint8_t Is_LCD_IO_Initialized = 0;
51 static SPI_HandleTypeDef SpiHandle;
52 
53 /**
54   * @brief  SPIx Bus initialization
55   */
SPIx_Init(void)56 static void SPIx_Init(void)
57 {
58   if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET)
59   {
60     /* SPI configuration -----------------------------------------------------*/
61     SpiHandle.Instance = SPI5;
62     /* SPI baudrate is set to 5.6 MHz (PCLK2/SPI_BaudRatePrescaler = 90/16 = 5.625 MHz)
63     */
64     SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
65 
66     /* On STM32F429I-Discovery, LCD ID cannot be read then keep a common configuration */
67     /* for LCD and GYRO (SPI_DIRECTION_2LINES) */
68     /* Note: To read a register a LCD, SPI_DIRECTION_1LINE should be set */
69     SpiHandle.Init.Direction      = SPI_DIRECTION_2LINES;
70     SpiHandle.Init.CLKPhase       = SPI_PHASE_1EDGE;
71     SpiHandle.Init.CLKPolarity    = SPI_POLARITY_LOW;
72     SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
73     SpiHandle.Init.CRCPolynomial  = 7;
74     SpiHandle.Init.DataSize       = SPI_DATASIZE_8BIT;
75     SpiHandle.Init.FirstBit       = SPI_FIRSTBIT_MSB;
76     SpiHandle.Init.NSS            = SPI_NSS_SOFT;
77     SpiHandle.Init.TIMode         = SPI_TIMODE_DISABLED;
78     SpiHandle.Init.Mode           = SPI_MODE_MASTER;
79 
80     HAL_SPI_Init(&SpiHandle);
81   }
82 }
83 
84 /**
85   * @brief  Configures the LCD_SPI interface.
86   */
LCD_GPIO_Init(void)87 static void LCD_GPIO_Init(void)
88 {
89   GPIO_InitTypeDef GPIO_InitStructure;
90 
91   if(Is_LCD_IO_Initialized == 0)
92   {
93     Is_LCD_IO_Initialized = 1;
94 
95     /* Configure NCS in Output Push-Pull mode */
96     LCD_WRX_GPIO_CLK_ENABLE();
97     GPIO_InitStructure.Pin     = LCD_WRX_PIN;
98     GPIO_InitStructure.Mode    = GPIO_MODE_OUTPUT_PP;
99     GPIO_InitStructure.Pull    = GPIO_NOPULL;
100     GPIO_InitStructure.Speed   = GPIO_SPEED_FAST;
101     HAL_GPIO_Init(LCD_WRX_GPIO_PORT, &GPIO_InitStructure);
102 
103     LCD_RDX_GPIO_CLK_ENABLE();
104     GPIO_InitStructure.Pin     = LCD_RDX_PIN;
105     GPIO_InitStructure.Mode    = GPIO_MODE_OUTPUT_PP;
106     GPIO_InitStructure.Pull    = GPIO_NOPULL;
107     GPIO_InitStructure.Speed   = GPIO_SPEED_FAST;
108     HAL_GPIO_Init(LCD_RDX_GPIO_PORT, &GPIO_InitStructure);
109 
110     /* Configure the LCD Control pins ----------------------------------------*/
111     LCD_NCS_GPIO_CLK_ENABLE();
112 
113     /* Configure NCS in Output Push-Pull mode */
114     GPIO_InitStructure.Pin     = LCD_NCS_PIN;
115     GPIO_InitStructure.Mode    = GPIO_MODE_OUTPUT_PP;
116     GPIO_InitStructure.Pull    = GPIO_NOPULL;
117     GPIO_InitStructure.Speed   = GPIO_SPEED_FAST;
118     HAL_GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure);
119 
120     /* Set or Reset the control line */
121     LCD_CS_LOW();
122     LCD_CS_HIGH();
123 
124     SPIx_Init();
125   }
126 }
127 
128 /**
129   * @brief  Writes data to the selected LCD register.
130   * @param  data: data to lcd.
131   * @retval None
132   */
ili9341_write_data(uint16_t data)133 static void ili9341_write_data(uint16_t data)
134 {
135   /* Set WRX to send data */
136   LCD_WRX_HIGH();
137 
138   /* Reset LCD control line(/CS) and Send data */
139   LCD_CS_LOW();
140 
141     HAL_SPI_Transmit(&SpiHandle, (uint8_t*) &data, 1, SPIx_TIMEOUT_MAX);
142 
143   /* Deselect: Chip Select high */
144   LCD_CS_HIGH();
145 }
146 
147 /**
148   * @brief  Writes  to the selected LCD register.
149   * @param  reg: address of the selected register.
150   * @retval None
151   */
ili9341_write_register(uint8_t reg)152 static void ili9341_write_register(uint8_t reg)
153 {
154   /* Reset WRX to send command */
155   LCD_WRX_LOW();
156 
157   /* Reset LCD control line(/CS) and Send command */
158   LCD_CS_LOW();
159 
160   HAL_SPI_Transmit(&SpiHandle, (uint8_t*) &reg, 1, SPIx_TIMEOUT_MAX);
161 
162   /* Deselect: Chip Select high */
163   LCD_CS_HIGH();
164 }
165 
166 /**
167   * @brief  Power on the LCD.
168   * @param  None
169   * @retval int
170   */
ili9341_hw_init(void)171 int ili9341_hw_init(void)
172 {
173   /* Initialize ILI9341 low level bus layer ----------------------------------*/
174   LCD_GPIO_Init();
175 
176   /* Configure LCD */
177   ili9341_write_register(0xCA);
178   ili9341_write_data(0xC3);
179   ili9341_write_data(0x08);
180   ili9341_write_data(0x50);
181   ili9341_write_register(LCD_POWERB);
182   ili9341_write_data(0x00);
183   ili9341_write_data(0xC1);
184   ili9341_write_data(0x30);
185   ili9341_write_register(LCD_POWER_SEQ);
186   ili9341_write_data(0x64);
187   ili9341_write_data(0x03);
188   ili9341_write_data(0x12);
189   ili9341_write_data(0x81);
190   ili9341_write_register(LCD_DTCA);
191   ili9341_write_data(0x85);
192   ili9341_write_data(0x00);
193   ili9341_write_data(0x78);
194   ili9341_write_register(LCD_POWERA);
195   ili9341_write_data(0x39);
196   ili9341_write_data(0x2C);
197   ili9341_write_data(0x00);
198   ili9341_write_data(0x34);
199   ili9341_write_data(0x02);
200   ili9341_write_register(LCD_PRC);
201   ili9341_write_data(0x20);
202   ili9341_write_register(LCD_DTCB);
203   ili9341_write_data(0x00);
204   ili9341_write_data(0x00);
205   ili9341_write_register(LCD_FRMCTR1);
206   ili9341_write_data(0x00);
207   ili9341_write_data(0x1B);
208   ili9341_write_register(LCD_DFC);
209   ili9341_write_data(0x0A);
210   ili9341_write_data(0xA2);
211   ili9341_write_register(LCD_POWER1);
212   ili9341_write_data(0x10);
213   ili9341_write_register(LCD_POWER2);
214   ili9341_write_data(0x10);
215   ili9341_write_register(LCD_VCOM1);
216   ili9341_write_data(0x45);
217   ili9341_write_data(0x15);
218   ili9341_write_register(LCD_VCOM2);
219   ili9341_write_data(0x90);
220   ili9341_write_register(LCD_MAC);
221   ili9341_write_data(0xC8);
222   ili9341_write_register(LCD_3GAMMA_EN);
223   ili9341_write_data(0x00);
224   ili9341_write_register(LCD_RGB_INTERFACE);
225   ili9341_write_data(0xC2);
226   ili9341_write_register(LCD_DFC);
227   ili9341_write_data(0x0A);
228   ili9341_write_data(0xA7);
229   ili9341_write_data(0x27);
230   ili9341_write_data(0x04);
231 
232   /* Colomn address set */
233   ili9341_write_register(LCD_COLUMN_ADDR);
234   ili9341_write_data(0x00);
235   ili9341_write_data(0x00);
236   ili9341_write_data(0x00);
237   ili9341_write_data(0xEF);
238   /* Page address set */
239   ili9341_write_register(LCD_PAGE_ADDR);
240   ili9341_write_data(0x00);
241   ili9341_write_data(0x00);
242   ili9341_write_data(0x01);
243   ili9341_write_data(0x3F);
244   ili9341_write_register(LCD_INTERFACE);
245   ili9341_write_data(0x01);
246   ili9341_write_data(0x00);
247   ili9341_write_data(0x06);
248 
249   ili9341_write_register(LCD_GRAM);
250   rt_thread_mdelay(20);
251 
252   ili9341_write_register(LCD_GAMMA);
253   ili9341_write_data(0x01);
254 
255   ili9341_write_register(LCD_PGAMMA);
256   ili9341_write_data(0x0F);
257   ili9341_write_data(0x29);
258   ili9341_write_data(0x24);
259   ili9341_write_data(0x0C);
260   ili9341_write_data(0x0E);
261   ili9341_write_data(0x09);
262   ili9341_write_data(0x4E);
263   ili9341_write_data(0x78);
264   ili9341_write_data(0x3C);
265   ili9341_write_data(0x09);
266   ili9341_write_data(0x13);
267   ili9341_write_data(0x05);
268   ili9341_write_data(0x17);
269   ili9341_write_data(0x11);
270   ili9341_write_data(0x00);
271   ili9341_write_register(LCD_NGAMMA);
272   ili9341_write_data(0x00);
273   ili9341_write_data(0x16);
274   ili9341_write_data(0x1B);
275   ili9341_write_data(0x04);
276   ili9341_write_data(0x11);
277   ili9341_write_data(0x07);
278   ili9341_write_data(0x31);
279   ili9341_write_data(0x33);
280   ili9341_write_data(0x42);
281   ili9341_write_data(0x05);
282   ili9341_write_data(0x0C);
283   ili9341_write_data(0x0A);
284   ili9341_write_data(0x28);
285   ili9341_write_data(0x2F);
286   ili9341_write_data(0x0F);
287 
288   ili9341_write_register(LCD_SLEEP_OUT);
289   rt_thread_mdelay(20);
290   ili9341_write_register(LCD_DISPLAY_ON);
291   /* GRAM start writing */
292   ili9341_write_register(LCD_GRAM);
293 
294     return 0;
295 }
296 INIT_DEVICE_EXPORT(ili9341_hw_init);
297 
298 
299 
300