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 #include "hdf_log.h"
16 #include "los_task.h"
17 #include "gd32f4xx.h"
18 #include "lcd_hardware_init.h"
19 #include "tli_ipa_config.h"
20
21 #define HORIZONTAL_SYNCHRONOUS_PULSE 10
22 #define HORIZONTAL_BACK_PORCH 20
23 #define ACTIVE_WIDTH 320
24 #define HORIZONTAL_FRONT_PORCH 40
25
26 #define VERTICAL_SYNCHRONOUS_PULSE 2
27 #define VERTICAL_BACK_PORCH 2
28 #define ACTIVE_HEIGHT 480
29 #define VERTICAL_FRONT_PORCH 4
30 #define PLLSAI_N 108
31 #define PLLSAI_P 2
32 #define PLLSAI_R 3
33 #define WIDTH_DOUBLE 2
34 #define WIDTH_OFFSET 3
35 /*!
36 \brief LCD configuration
37 \param[in] none
38 \param[out] none
39 \retval none
40 */
InitLcdGpio(void)41 void InitLcdGpio(void)
42 {
43 /* configure the LCD control line */
44 lcdCtrlGpioConfig();
45 lcdDisable();
46 lcdEnable();
47
48 /* configure the GPIO of TLI */
49 InitTliGpio();
50
51 /* configure the LCD_SPI */
52 InitLcdSpiGpio();
53 }
54
SetLcdBackgroundLayer(void)55 void SetLcdBackgroundLayer(void)
56 {
57 tli_parameter_struct tli_init_struct;
58
59 /* initialize the parameters of structure */
60 tli_struct_para_init(&tli_init_struct);
61
62 /* TLI initialization */
63 tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
64 tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
65 tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW;
66 tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_INVERTEDTLI;
67
68 tli_init_struct.synpsz_hpsz = HORIZONTAL_SYNCHRONOUS_PULSE - 1;
69 tli_init_struct.synpsz_vpsz = VERTICAL_SYNCHRONOUS_PULSE - 1;
70 tli_init_struct.backpsz_hbpsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1;
71 tli_init_struct.backpsz_vbpsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1;
72 tli_init_struct.activesz_hasz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH - 1;
73 tli_init_struct.activesz_vasz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT - 1;
74 tli_init_struct.totalsz_htsz =
75 HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH + HORIZONTAL_FRONT_PORCH - 1;
76 tli_init_struct.totalsz_vtsz =
77 VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT + VERTICAL_FRONT_PORCH - 1;
78
79 /* LCD background color configure */
80 tli_init_struct.backcolor_red = 0xFF;
81 tli_init_struct.backcolor_green = 0xFF;
82 tli_init_struct.backcolor_blue = 0xFF;
83 tli_init(&tli_init_struct);
84 }
85
SetLcdFrontLayer(uint32_t layerId,uint32_t left,uint32_t top,uint32_t pictureWidth,uint32_t pictureHeight,uint32_t pictureBuffer)86 int32_t SetLcdFrontLayer(uint32_t layerId, uint32_t left, uint32_t top, uint32_t pictureWidth, uint32_t pictureHeight,
87 uint32_t pictureBuffer)
88 {
89 uint32_t layerX;
90 tli_layer_parameter_struct tli_layer_init_struct;
91 /* initialize the parameters of structure */
92 tli_layer_struct_para_init(&tli_layer_init_struct);
93
94 if (layerId > 1) {
95 HDF_LOGE("layerId(%d) is more than 1\n", layerId);
96 return -1;
97 }
98
99 if ((left + pictureWidth) > ACTIVE_WIDTH) {
100 HDF_LOGE("total width is out of range [0, %d]\n", ACTIVE_WIDTH);
101 return -1;
102 }
103
104 if ((top + pictureHeight) > ACTIVE_HEIGHT) {
105 HDF_LOGE("total height is out of range [0, %d]\n", ACTIVE_HEIGHT);
106 return -1;
107 }
108
109 if (layerId == 0) {
110 layerX = LAYER0;
111 } else {
112 layerX = LAYER1;
113 }
114
115 tli_layer_init_struct.layer_window_leftpos = (0 + left + HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH);
116 tli_layer_init_struct.layer_window_rightpos =
117 (pictureWidth + left + HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1);
118 tli_layer_init_struct.layer_window_toppos = (0 + top + VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH);
119 tli_layer_init_struct.layer_window_bottompos =
120 (pictureHeight + top + VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1);
121
122 tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
123 tli_layer_init_struct.layer_sa = 0xFF;
124 tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;
125 tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;
126 tli_layer_init_struct.layer_default_alpha = 0;
127 tli_layer_init_struct.layer_default_blue = 0;
128 tli_layer_init_struct.layer_default_green = 0;
129 tli_layer_init_struct.layer_default_red = 0;
130 tli_layer_init_struct.layer_frame_bufaddr = pictureBuffer;
131 tli_layer_init_struct.layer_frame_line_length = ((pictureWidth * WIDTH_DOUBLE) + WIDTH_OFFSET);
132 tli_layer_init_struct.layer_frame_buf_stride_offset = (pictureWidth * WIDTH_DOUBLE);
133 tli_layer_init_struct.layer_frame_total_line_number = pictureHeight;
134 tli_layer_init(layerX, &tli_layer_init_struct);
135
136 return 0;
137 }
138
139 /*!
140 \brief configure TLI peripheral
141 \param[in] none
142 \param[out] none
143 \retval none
144 */
ConfigTli(void)145 void ConfigTli(void)
146 {
147 tli_parameter_struct tli_init_struct;
148 tli_layer_parameter_struct tli_layer_init_struct;
149
150 /* initialize the parameters of structure */
151 tli_struct_para_init(&tli_init_struct);
152 tli_layer_struct_para_init(&tli_layer_init_struct);
153
154 rcu_periph_clock_enable(RCU_TLI);
155
156 /* configure the PLLSAI clock to generate lcd clock */
157 if (ERROR == rcu_pllsai_config(PLLSAI_N, PLLSAI_P, PLLSAI_R)) {
158 while (1) { }
159 }
160 rcu_tli_clock_div_config(RCU_PLLSAIR_DIV4);
161 rcu_osci_on(RCU_PLLSAI_CK);
162 if (ERROR == rcu_osci_stab_wait(RCU_PLLSAI_CK)) {
163 while (1) { }
164 }
165 }
166
167 /*!
168 \brief IPA initialize and configuration
169 \param[in] none
170 \param[out] none
171 \retval none
172 */
ipaConfig(uint32_t width,uint32_t height,uint32_t srcAddr,uint32_t desAddr)173 int32_t ipaConfig(uint32_t width, uint32_t height, uint32_t srcAddr, uint32_t desAddr)
174 {
175 ipa_destination_parameter_struct ipa_destination_init_struct;
176 ipa_foreground_parameter_struct ipa_fg_init_struct;
177
178 /* 如果目标层像素格式是ARGB8888,这些位必须是32位对齐,如果目标层像素格式是
179 RGB565, ARGB1555或ARGB4444,这些位必须是16位对齐,如果违背以上对齐规
180 则,当传输使能的时候,将检测到一个配置错误。 */
181 ipa_foreground_struct_para_init(&ipa_fg_init_struct);
182 ipa_destination_struct_para_init(&ipa_destination_init_struct);
183
184 rcu_periph_clock_enable(RCU_IPA);
185
186 ipa_deinit();
187 /* IPA pixel format convert mode configure */
188 ipa_pixel_format_convert_mode_set(IPA_FGTODE);
189 /* destination pixel format configure */
190 ipa_destination_init_struct.destination_pf = IPA_DPF_RGB565;
191 /* destination memory base address configure */
192 ipa_destination_init_struct.destination_memaddr = desAddr;
193 /* destination pre-defined alpha value RGB configure */
194 ipa_destination_init_struct.destination_pregreen = 0;
195 ipa_destination_init_struct.destination_preblue = 0;
196 ipa_destination_init_struct.destination_prered = 0;
197 ipa_destination_init_struct.destination_prealpha = 0;
198 /* destination line offset configure */
199 ipa_destination_init_struct.destination_lineoff = 0;
200 /* height of the image to be processed configure */
201 ipa_destination_init_struct.image_height = height;
202 /* width of the image to be processed configure */
203 ipa_destination_init_struct.image_width = width;
204 /* IPA destination initialization */
205 ipa_destination_init(&ipa_destination_init_struct);
206
207 /* IPA foreground configure */
208 ipa_fg_init_struct.foreground_memaddr = srcAddr;
209 ipa_fg_init_struct.foreground_pf = FOREGROUND_PPF_RGB565;
210 ipa_fg_init_struct.foreground_alpha_algorithm = IPA_FG_ALPHA_MODE_0;
211 ipa_fg_init_struct.foreground_prealpha = 0;
212 ipa_fg_init_struct.foreground_lineoff = 0;
213 ipa_fg_init_struct.foreground_preblue = 0;
214 ipa_fg_init_struct.foreground_pregreen = 0;
215 ipa_fg_init_struct.foreground_prered = 0;
216 /* foreground initialization */
217 ipa_foreground_init(&ipa_fg_init_struct);
218 }
219
220 /*!
221 \brief configure TLI peripheral and display blend image
222 \param[in] none
223 \param[out] none
224 \retval none
225 */
tliBlendConfig(uint32_t left,uint32_t top,uint32_t pictureWidth,uint32_t pictureHeight,uint32_t pictureBuffer)226 int32_t tliBlendConfig(uint32_t left, uint32_t top, uint32_t pictureWidth, uint32_t pictureHeight,
227 uint32_t pictureBuffer)
228 {
229 SetLcdFrontLayer(1, left, top, pictureWidth, pictureHeight, pictureBuffer);
230
231 return 0;
232 }
233 /*!
234 \brief configure TLI GPIO
235 \param[in] none
236 \param[out] none
237 \retval none
238 */
InitTliGpio(void)239 void InitTliGpio(void)
240 {
241 /* enable the periphral clock */
242 rcu_periph_clock_enable(RCU_GPIOA);
243 rcu_periph_clock_enable(RCU_GPIOB);
244 rcu_periph_clock_enable(RCU_GPIOC);
245 rcu_periph_clock_enable(RCU_GPIOD);
246 rcu_periph_clock_enable(RCU_GPIOF);
247 rcu_periph_clock_enable(RCU_GPIOG);
248
249 /* configure HSYNC(PC6), VSYNC(PA4), PCLK(PG7), DE(PF10) */
250 /* configure LCD_R7(PG6), LCD_R6(PA8), LCD_R5(PA12), LCD_R4(PA11), LCD_R3(PB0),
251 LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PB11), LCD_G4(PB10), LCD_G3(PG10), LCD_G2(PA6),
252 LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PA3), LCD_B4(PG12), LCD_B3(PG11) */
253 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_3);
254 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_4);
255 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_6);
256 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_8);
257 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_11);
258 gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_12);
259
260 gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_0);
261 gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_8);
262 gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_9);
263 gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_10);
264 gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_11);
265
266 gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_6);
267 gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_7);
268
269 gpio_af_set(GPIOD, GPIO_AF_14, GPIO_PIN_3);
270
271 gpio_af_set(GPIOF, GPIO_AF_14, GPIO_PIN_10);
272
273 gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_6);
274 gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_7);
275 gpio_af_set(GPIOG, GPIO_AF_9, GPIO_PIN_10);
276 gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_11);
277 gpio_af_set(GPIOG, GPIO_AF_9, GPIO_PIN_12);
278
279 gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
280 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_11 | GPIO_PIN_12);
281 gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
282 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_11 | GPIO_PIN_12);
283
284 gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE,
285 GPIO_PIN_0 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11);
286 gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
287 GPIO_PIN_0 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11);
288
289 gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7);
290 gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
291
292 gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
293 gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
294
295 gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
296 gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
297
298 gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE,
299 GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
300 gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
301 GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
302 }
303