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*) ®, 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