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