• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http:// www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "lcd_hardware_init.h"
17 
18 #define LCD_SPI_CS(a)                                                                                                  \
19     do {                                                                                                               \
20         if (a) {                                                                                                       \
21             gpio_bit_set(LCD_CS_GPIO_PORT, LCD_CS_PIN);                                                                \
22         } else {                                                                                                       \
23             gpio_bit_reset(LCD_CS_GPIO_PORT, LCD_CS_PIN);                                                              \
24         }                                                                                                              \
25     } while (0)
26 #define SPI_DCLK(a)                                                                                                    \
27     do {                                                                                                               \
28         if (a) {                                                                                                       \
29             gpio_bit_set(LCD_SPI_SCK_GPIO_PORT, LCD_SPI_SCK_PIN);                                                      \
30         } else {                                                                                                       \
31             gpio_bit_reset(LCD_SPI_SCK_GPIO_PORT, LCD_SPI_SCK_PIN);                                                    \
32         }                                                                                                              \
33     } while (0)
34 #define SPI_SDA(a)                                                                                                     \
35     do {                                                                                                               \
36         if (a) {                                                                                                       \
37             gpio_bit_set(LCD_SPI_MOSI_GPIO_PORT, LCD_SPI_MOSI_PIN);                                                    \
38         } else {                                                                                                       \
39             gpio_bit_reset(LCD_SPI_MOSI_GPIO_PORT, LCD_SPI_MOSI_PIN);                                                  \
40         }                                                                                                              \
41     } while (0)
42 
43 #define DELAY_120_MS 120
44 #define DELAY_20_MS 20
45 #define WRITE_OFFSET 8
46 static void delay(uint32_t count);
47 
48 /*!
49     \brief      enable the LCD
50     \param[in]  none
51     \param[out] none
52     \retval     none
53 */
lcdEnable(void)54 void lcdEnable(void)
55 {
56     gpio_bit_set(LCD_CS_GPIO_PORT, LCD_CS_PIN);
57 }
58 
59 /*!
60     \brief      disable the LCD
61     \param[in]  none
62     \param[out] none
63     \retval     none
64 */
lcdDisable(void)65 void lcdDisable(void)
66 {
67     gpio_bit_reset(LCD_CS_GPIO_PORT, LCD_CS_PIN);
68 }
69 
70 /*!
71     \brief      configure the LCD control line
72     \param[in]  none
73     \param[out] none
74     \retval     none
75 */
lcdCtrlGpioConfig(void)76 void lcdCtrlGpioConfig(void)
77 {
78     /* enable GPIOs clock */
79     rcu_periph_clock_enable(LCD_CS_GPIO_CLK);
80     rcu_periph_clock_enable(LCD_RS_GPIO_CLK);
81 
82     /* configure LCD_CS_GPIO_PORT(PD11) and LCD_RS_GPIO_PORT(PE3) */
83     gpio_mode_set(LCD_CS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_CS_PIN);
84     gpio_output_options_set(LCD_CS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LCD_CS_PIN);
85 
86     gpio_mode_set(LCD_RS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_RS_PIN);
87     gpio_output_options_set(LCD_RS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LCD_RS_PIN);
88 
89     /* set the chip select pin */
90     lcdCtrlLineSet(LCD_CS_GPIO_PORT, LCD_CS_PIN);
91 }
92 
93 /*!
94     \brief      set the LCD control line
95     \param[in]  gpiox: control line GPIO
96       \arg        LCD_CS_GPIO_PORT: LCD chip select GPIO
97       \arg        LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO
98     \param[in]  gpiopin: control line pin
99       \arg        LCD_CS_PIN: LCD chip select pin
100       \arg        LCD_RS_PIN: LCD register/RAM selection pin
101     \param[out] none
102     \retval     none
103 */
lcdCtrlLineSet(uint32_t gpiox,uint16_t gpiopin)104 void lcdCtrlLineSet(uint32_t gpiox, uint16_t gpiopin)
105 {
106     gpio_bit_set(gpiox, gpiopin);
107 }
108 
109 /*!
110     \brief      reset the LCD control line
111     \param[in]  gpiox: control line GPIO
112       \arg        LCD_CS_GPIO_PORT: LCD chip select GPIO
113       \arg        LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO
114     \param[in]  gpiopin: control line pin
115       \arg        LCD_CS_PIN: LCD chip select pin
116       \arg        LCD_RS_PIN: LCD register/RAM selection pin
117     \param[out] none
118     \retval     none
119 */
lcdCtrlLineReset(uint32_t gpiox,uint16_t gpiopin)120 void lcdCtrlLineReset(uint32_t gpiox, uint16_t gpiopin)
121 {
122     gpio_bit_reset(gpiox, gpiopin);
123 }
124 
125 /*!
126     \brief      configure the LCD SPI and it's GPIOs
127     \param[in]  none
128     \param[out] none
129     \retval     none
130 */
InitLcdSpiGpio(void)131 void InitLcdSpiGpio(void)
132 {
133     /* GPIO clock enable */
134     rcu_periph_clock_enable(LCD_SPI_SCK_GPIO_CLK);
135     rcu_periph_clock_enable(LCD_SPI_MOSI_GPIO_CLK);
136 
137     /* configure the LCD SPI pins */
138     gpio_mode_set(LCD_SPI_SCK_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_SPI_SCK_PIN);
139     gpio_output_options_set(LCD_SPI_SCK_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LCD_SPI_SCK_PIN);
140     gpio_mode_set(LCD_SPI_MOSI_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_SPI_MOSI_PIN);
141     gpio_output_options_set(LCD_SPI_MOSI_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LCD_SPI_MOSI_PIN);
142 }
143 
144 /*!
145     \brief      write command to select LCD register
146     \param[in]  lcd_register: the address of the selected register
147     \param[out] none
148     \retval     none
149 */
lcdCommandWrite(uint8_t lcd_register)150 void lcdCommandWrite(uint8_t lcd_register)
151 {
152     /* reset LCD_RS to send command */
153     lcdCtrlLineReset(LCD_RS_GPIO_PORT, LCD_RS_PIN);
154 
155     /* reset LCD control line and send command */
156     lcdDisable();
157     while (RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) { }
158     spi_i2s_data_transmit(LCD_SPI, lcd_register);
159 
160     /* wait until a data is sent */
161     while (RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS)) { }
162 
163     lcdEnable();
164 }
165 
166 /*!
167     \brief      write data to select LCD register
168     \param[in]  value: the value that will be written to the selected register
169     \param[out] none
170     \retval     none
171 */
lcdDateWrite(uint8_t value)172 void lcdDateWrite(uint8_t value)
173 {
174     /* set LCD_RS to send data */
175     lcdCtrlLineSet(LCD_RS_GPIO_PORT, LCD_RS_PIN);
176 
177     /* reset LCD control line and send data */
178     lcdDisable();
179     while (RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) { }
180 
181     spi_i2s_data_transmit(LCD_SPI, value);
182 
183     /* wait until a data is sent */
184     while (RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS)) { }
185 
186     lcdEnable();
187 }
188 
189 /*!
190     \brief      GPIO emulated SPI byte write
191     \param[in]  byte: data to be sent
192     \param[out] none
193     \retval     none
194 */
spiIOByteWrite(unsigned char byteIn)195 void spiIOByteWrite(unsigned char byteIn)
196 {
197     unsigned char n;
198     unsigned char byte = byteIn;
199     for (n = 0; n < WRITE_OFFSET; n++) {
200         if (byte & 0x80) {
201             SPI_SDA(1);
202         } else {
203             SPI_SDA(0);
204         }
205         byte <<= 1;
206 
207         SPI_DCLK(0);
208         SPI_DCLK(1);
209     }
210 }
211 
212 /*!
213     \brief      GPIO emulated SPI write command
214     \param[in]  cmd: command to be sent
215     \param[out] none
216     \retval     none
217 */
spiIOCommandWrite(uint8_t cmd)218 void spiIOCommandWrite(uint8_t cmd)
219 {
220     LCD_SPI_CS(0);
221     SPI_SDA(0);
222     SPI_DCLK(0);
223     SPI_DCLK(1);
224     spiIOByteWrite(cmd);
225 
226     LCD_SPI_CS(1);
227 }
228 
229 /*!
230     \brief      GPIO emulated SPI write data
231     \param[in]  tem_data: data to be sent
232     \param[out] none
233     \retval     none
234 */
spiIODateWrite(uint8_t tem_data)235 void spiIODateWrite(uint8_t tem_data)
236 {
237     LCD_SPI_CS(0);
238     SPI_SDA(1);
239     SPI_DCLK(0);
240     SPI_DCLK(1);
241     spiIOByteWrite(tem_data);
242     LCD_SPI_CS(1);
243 }
244 
InitLcdRegisterBefore(void)245 void InitLcdRegisterBefore(void)
246 {
247     delay(DELAY_120_MS);
248 
249     LCD_SPI_CS(1);
250     delay(DELAY_20_MS);
251     LCD_SPI_CS(0);
252 
253     spiIOCommandWrite(0xE0); // P-Gamma
254     spiIODateWrite(0x00);
255     spiIODateWrite(0x10);
256     spiIODateWrite(0x14);
257     spiIODateWrite(0x03);
258     spiIODateWrite(0x0E);
259     spiIODateWrite(0x04);
260     spiIODateWrite(0x36);
261     spiIODateWrite(0x56);
262     spiIODateWrite(0x4B);
263     spiIODateWrite(0x04);
264     spiIODateWrite(0x0C);
265     spiIODateWrite(0x0A);
266     spiIODateWrite(0x30);
267     spiIODateWrite(0x34);
268     spiIODateWrite(0x0F);
269 
270     spiIOCommandWrite(0XE1); // N-Gamma
271     spiIODateWrite(0x00);
272     spiIODateWrite(0x0E);
273     spiIODateWrite(0x13);
274     spiIODateWrite(0x03);
275     spiIODateWrite(0x10);
276     spiIODateWrite(0x06);
277     spiIODateWrite(0x3E);
278     spiIODateWrite(0x34);
279     spiIODateWrite(0x55);
280     spiIODateWrite(0x05);
281     spiIODateWrite(0x0F);
282     spiIODateWrite(0x0E);
283     spiIODateWrite(0x3A);
284     spiIODateWrite(0x3E);
285     spiIODateWrite(0x0F);
286 }
InitLcdRegister(void)287 void InitLcdRegister(void)
288 {
289     InitLcdRegisterBefore();
290     spiIOCommandWrite(0XC0); // Power Control 1
291     spiIODateWrite(0x0F);    // Vreg1out
292     spiIODateWrite(0x0C);    // Verg2out
293 
294     spiIOCommandWrite(0xC1); // Power Control 2
295     spiIODateWrite(0x41);    // VGH,VGL
296 
297     spiIOCommandWrite(0xC5); // Power Control 3
298     spiIODateWrite(0x00);
299     spiIODateWrite(0x21); // Vcom
300     spiIODateWrite(0x80);
301 
302     spiIOCommandWrite(0x2a);
303     spiIODateWrite(0 >> WRITE_OFFSET);
304     spiIODateWrite(0);
305     spiIODateWrite(LCD_PIXEL_WIDTH >> WRITE_OFFSET);
306     spiIODateWrite((uint8_t)LCD_PIXEL_WIDTH);
307 
308     spiIOCommandWrite(0x2b);
309     spiIODateWrite(0 >> WRITE_OFFSET);
310     spiIODateWrite(0);
311     spiIODateWrite(LCD_PIXEL_HEIGHT >> WRITE_OFFSET);
312     spiIODateWrite((uint8_t)LCD_PIXEL_HEIGHT);
313 
314     spiIOCommandWrite(0x36); // Memory Access
315     spiIODateWrite(0x48);
316 
317     spiIOCommandWrite(0x3A); //  Interface Pixel Format
318     spiIODateWrite(0x66);    // 18bit
319     // spiIODateWrite(0x55);    // 16bit
320 
321     spiIOCommandWrite(0XB0); //  Interface Mode Control
322     spiIODateWrite(0x00);
323 
324     spiIOCommandWrite(0xB1); // Frame rate
325     spiIODateWrite(0xA0);    // 60Hz
326 
327     spiIOCommandWrite(0xB4); // Display Inversion Control
328     spiIODateWrite(0x02);    // 2-dot
329 
330     spiIOCommandWrite(0XB6); // RGB/MCU Interface Control
331     spiIODateWrite(0x22);    // MCU
332     spiIODateWrite(0x02);    // Source,Gate scan dieection
333 
334     spiIOCommandWrite(0XE9); //  Set Image Function
335     spiIODateWrite(0x00);    // disable 24 bit data input
336 
337     spiIOCommandWrite(0xF7); // Adjust Control
338     spiIODateWrite(0xA9);
339     spiIODateWrite(0x51);
340     spiIODateWrite(0x2C);
341     spiIODateWrite(0x82); // D7 stream, loose
342 
343     spiIOCommandWrite(0x21); // Normal Black
344 
345     spiIOCommandWrite(0x11); // Sleep out
346     delay(DELAY_120_MS);
347     spiIOCommandWrite(0x29); // Display on
348 
349     delay(DELAY_120_MS);
350 }
351 
352 /*!
353     \brief      insert a delay time
354     \param[in]  count: delay time
355     \param[out] none
356     \retval     none
357 */
delay(__IO uint32_t count)358 static void delay(__IO uint32_t count)
359 {
360     __IO uint32_t index = 0;
361     for (index = count; index != 0; index--) { }
362 }
363