1 /*
2 * Copyright (c) 2019-2021,2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_lcdif.h"
8
9 /*******************************************************************************
10 * Definitions
11 ******************************************************************************/
12
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.lcdif"
16 #endif
17
18 #if defined(LCDIF_RSTS)
19 #define LCDIF_RESETS_ARRAY LCDIF_RSTS
20 #elif defined(DCNANO_RSTS)
21 #define LCDIF_RESETS_ARRAY DCNANO_RSTS
22 #endif
23
24 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
25 typedef union
26 {
27 lcdif_layer_alpha_blend_config_t _alphaConfig;
28 uint32_t _u32;
29 } lcdif_reg32_convert_t;
30 #endif
31
32 /*******************************************************************************
33 * Prototypes
34 ******************************************************************************/
35
36 /*!
37 * brief Get the instance from the base address
38 *
39 * param base LCDIF peripheral base address
40 *
41 * return The LCDIF module instance
42 */
43 static uint32_t LCDIF_GetInstance(LCDIF_Type *base);
44
45 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
46 /*!
47 * brief Gets the layer config register value
48 *
49 * param config Pointer to the configuration structure.
50 *
51 * return The value for layer configuration register.
52 */
53 static uint32_t LCDIF_GetLayerConfig(const lcdif_fb_config_t *config);
54 #endif
55 /*******************************************************************************
56 * Variables
57 ******************************************************************************/
58 /*! brief Pointers to LCDIF bases for each instance. */
59 static LCDIF_Type *const s_lcdifBases[] = LCDIF_BASE_PTRS;
60
61 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
62 /*! brief Pointers to LCDIF clocks for each LCDIF submodule. */
63 static const clock_ip_name_t s_lcdifClocks[] = LCDIF_CLOCKS;
64 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
65
66 #if defined(LCDIF_RESETS_ARRAY)
67 /* Reset array */
68 static const reset_ip_name_t s_lcdifResets[] = LCDIF_RESETS_ARRAY;
69 #endif
70
71 /*******************************************************************************
72 * Code
73 ******************************************************************************/
LCDIF_GetInstance(LCDIF_Type * base)74 static uint32_t LCDIF_GetInstance(LCDIF_Type *base)
75 {
76 uint32_t instance;
77
78 /* Find the instance index from base address mappings. */
79 for (instance = 0; instance < ARRAY_SIZE(s_lcdifBases); instance++)
80 {
81 if (MSDK_REG_SECURE_ADDR(s_lcdifBases[instance]) == MSDK_REG_SECURE_ADDR(base))
82 {
83 break;
84 }
85 }
86
87 assert(instance < ARRAY_SIZE(s_lcdifBases));
88
89 return instance;
90 }
91
92 /*!
93 * brief Initialize the LCDIF.
94 *
95 * This function initializes the LCDIF to work.
96 *
97 * param base LCDIF peripheral base address.
98 *
99 * retval kStatus_Success Initialize successfully.
100 */
LCDIF_Init(LCDIF_Type * base)101 status_t LCDIF_Init(LCDIF_Type *base)
102 {
103 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
104 uint32_t instance = LCDIF_GetInstance(base);
105 CLOCK_EnableClock(s_lcdifClocks[instance]);
106 #endif
107
108 #if defined(LCDIF_RESETS_ARRAY)
109 RESET_ReleasePeripheralReset(s_lcdifResets[LCDIF_GetInstance(base)]);
110 #endif
111
112 base->FRAMEBUFFERCONFIG0 = 0;
113 /* Clear interrupt status and disable interrupt. */
114 base->DISPLAYINTRENABLE = 0;
115 (void)(base->DISPLAYINTR);
116
117 return kStatus_Success;
118 }
119
120 /*!
121 * brief De-initialize the LCDIF.
122 *
123 * This function disables the LCDIF peripheral clock.
124 *
125 * param base LCDIF peripheral base address.
126 */
LCDIF_Deinit(LCDIF_Type * base)127 void LCDIF_Deinit(LCDIF_Type *base)
128 {
129 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
130 uint32_t instance = LCDIF_GetInstance(base);
131 CLOCK_DisableClock(s_lcdifClocks[instance]);
132 #endif
133 }
134
135 /*!
136 * brief Get the default configuration for to initialize the LCDIF DPI mode.
137 *
138 * The default configuration value is:
139 *
140 * code
141 * config->panelWidth = 0;
142 * config->panelHeight = 0;
143 * config->hsw = 0;
144 * config->hfp = 0;
145 * config->hbp = 0;
146 * config->vsw = 0;
147 * config->vfp = 0;
148 * config->vbp = 0;
149 * config->polarityFlags = kLCDIF_VsyncActiveLow | kLCDIF_HsyncActiveLow | kLCDIF_DataEnableActiveHigh |
150 * kLCDIF_DriveDataOnFallingClkEdge; config->format = kLCDIF_Output24Bit;
151 * endcode
152 *
153 * param config Pointer to the LCDIF DPI configuration.
154 */
LCDIF_DpiModeGetDefaultConfig(lcdif_dpi_config_t * config)155 void LCDIF_DpiModeGetDefaultConfig(lcdif_dpi_config_t *config)
156 {
157 assert(NULL != config);
158
159 (void)memset(config, 0, sizeof(*config));
160
161 config->panelWidth = 0;
162 config->panelHeight = 0;
163 config->hsw = 0;
164 config->hfp = 0;
165 config->hbp = 0;
166 config->vsw = 0;
167 config->vfp = 0;
168 config->vbp = 0;
169 config->polarityFlags = (uint32_t)kLCDIF_VsyncActiveLow | (uint32_t)kLCDIF_HsyncActiveLow |
170 (uint32_t)kLCDIF_DataEnableActiveHigh | (uint32_t)kLCDIF_DriveDataOnFallingClkEdge;
171 config->format = kLCDIF_Output24Bit;
172 }
173
174 /*!
175 * @brief Initialize the LCDIF to work in DPI mode.
176 *
177 * This function configures the LCDIF DPI display.
178 *
179 * param base LCDIF peripheral base address.
180 * param displayIndex Display index.
181 * param config Pointer to the configuration structure.
182 *
183 * retval kStatus_Success Initialize successfully.
184 * retval kStatus_InvalidArgument Initialize failed because of invalid argument.
185 */
LCDIF_DpiModeSetConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_dpi_config_t * config)186 status_t LCDIF_DpiModeSetConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dpi_config_t *config)
187 {
188 assert(NULL != config);
189
190 uint32_t regHsync;
191 uint32_t regVsync;
192 uint32_t regPanelConfig;
193
194 /* Reset the frame buffer. */
195 base->FRAMEBUFFERCONFIG0 = 0;
196
197 /* Change to DPI mode. */
198 base->DBICONFIG0 &= ~LCDIF_DBICONFIG0_BUS_OUTPUT_SEL_MASK;
199
200 base->DPICONFIG0 = (uint32_t)config->format;
201
202 base->HDISPLAY0 =
203 ((uint32_t)config->panelWidth << LCDIF_HDISPLAY0_DISPLAY_END_SHIFT) |
204 (((uint32_t)config->panelWidth + config->hsw + config->hfp + config->hbp) << LCDIF_HDISPLAY0_TOTAL_SHIFT);
205
206 base->VDISPLAY0 =
207 ((uint32_t)config->panelHeight << LCDIF_VDISPLAY0_DISPLAY_END_SHIFT) |
208 (((uint32_t)config->panelHeight + config->vsw + config->vfp + config->vbp) << LCDIF_VDISPLAY0_TOTAL_SHIFT);
209
210 /* HSYNC */
211 regHsync = (((uint32_t)config->panelWidth + config->hfp) << LCDIF_HSYNC0_START_SHIFT) |
212 (((uint32_t)config->panelWidth + config->hfp + config->hsw) << LCDIF_HSYNC0_END_SHIFT) |
213 LCDIF_HSYNC0_PULSE_MASK;
214
215 if ((uint32_t)kLCDIF_HsyncActiveHigh != (config->polarityFlags & (uint32_t)kLCDIF_HsyncActiveHigh))
216 {
217 regHsync |= LCDIF_HSYNC0_POLARITY_MASK;
218 }
219
220 base->HSYNC0 = regHsync;
221
222 /* VSYNC */
223 regVsync = (((uint32_t)config->panelHeight + config->vfp) << LCDIF_VSYNC0_START_SHIFT) |
224 (((uint32_t)config->panelHeight + config->vfp + config->vsw) << LCDIF_VSYNC0_END_SHIFT) |
225 LCDIF_VSYNC0_PULSE_MASK;
226
227 if ((uint32_t)kLCDIF_VsyncActiveHigh != (config->polarityFlags & (uint32_t)kLCDIF_VsyncActiveHigh))
228 {
229 regVsync |= LCDIF_VSYNC0_POLARITY_MASK;
230 }
231
232 base->VSYNC0 = regVsync;
233
234 /* DE, Data, clock. */
235 regPanelConfig = LCDIF_PANELCONFIG0_DE_MASK | LCDIF_PANELCONFIG0_CLOCK_MASK;
236
237 if ((uint32_t)kLCDIF_DataEnableActiveHigh != ((uint32_t)kLCDIF_DataEnableActiveHigh & config->polarityFlags))
238 {
239 regPanelConfig |= LCDIF_PANELCONFIG0_DE_POLARITY_MASK;
240 }
241
242 if ((uint32_t)kLCDIF_DriveDataOnRisingClkEdge ==
243 ((uint32_t)kLCDIF_DriveDataOnRisingClkEdge & config->polarityFlags))
244 {
245 regPanelConfig |= LCDIF_PANELCONFIG0_CLOCK_POLARITY_MASK;
246 }
247
248 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
249 base->PANELCONFIG0 = regPanelConfig;
250 #else
251 base->PANELCONFIG0 = regPanelConfig | LCDIF_PANELCONFIG0_SEQUENCING_MASK;
252 #endif
253 return kStatus_Success;
254 }
255
256 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
257 /*!
258 * @brief Gets default frame buffer configuration.
259 *
260 * Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version. Apart
261 * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
262 * to get the default configuration for all the 3 layers.
263 *
264 * @param config Pointer to the configuration structure.
265 */
LCDIF_FrameBufferGetDefaultConfig(lcdif_fb_config_t * config)266 void LCDIF_FrameBufferGetDefaultConfig(lcdif_fb_config_t *config)
267 {
268 assert(config != NULL);
269
270 (void)memset(config, 0, sizeof(*config));
271
272 config->enable = true;
273 config->rotateFlipMode = kLCDIF_Rotate0;
274 config->inOrder = kLCDIF_PixelInputOrderARGB;
275 config->format = kLCDIF_PixelFormatRGB565;
276 config->standard = kLCDIF_ConvertBT601;
277
278 /* kLCDIF_PorterDuffSrc */
279 config->alpha.srcAlphaMode = kLCDIF_AlphaStraight;
280 config->alpha.srcGlobalAlphaMode = kLCDIF_AlphaLocal;
281 config->alpha.srcFactorMode = kLCDIF_AlphaFactorOne;
282 config->alpha.useSrcAlpha = (uint32_t) true;
283 config->alpha.dstAlphaMode = kLCDIF_AlphaStraight;
284 config->alpha.dstGlobalAlphaMode = kLCDIF_AlphaLocal;
285 config->alpha.dstFactorMode = kLCDIF_AlphaFactorZero;
286 config->alpha.useDstAlpha = (uint32_t) true;
287 }
288
LCDIF_GetLayerConfig(const lcdif_fb_config_t * config)289 static uint32_t LCDIF_GetLayerConfig(const lcdif_fb_config_t *config)
290 {
291 return LCDIF_FRAMEBUFFERCONFIG0_ROT_ANGLE(config->rotateFlipMode) |
292 LCDIF_FRAMEBUFFERCONFIG0_UV_SWIZZLE(config->enableUVSwizzle) |
293 LCDIF_FRAMEBUFFERCONFIG0_SWIZZLE(config->inOrder) |
294 LCDIF_FRAMEBUFFERCONFIG0_COLOR_KEY_EN(config->colorkey.enable) |
295 LCDIF_FRAMEBUFFERCONFIG0_ENABLE((uint32_t)config->enable) | ((uint32_t)config->format & 0x7UL);
296 }
297
298 /*!
299 * brief Configure the video layer for LCDIF frame buffer.
300 *
301 * Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version. Apart
302 * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
303 * to configure the legacy video layer, and use @ref LCDIF_SetOverlayLayerConfig to configure the overlay layers.
304 *
305 * param base LCDIF peripheral base address.
306 * param displayIndex Display index.
307 * param config Pointer to the configuration structure.
308 */
LCDIF_SetFrameBufferConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_fb_config_t * config)309 void LCDIF_SetFrameBufferConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_fb_config_t *config)
310 {
311 assert(NULL != config);
312
313 lcdif_reg32_convert_t pid;
314 pid._alphaConfig = config->alpha;
315
316 base->LAYERCLOCKGATE = (base->LAYERCLOCKGATE & (~LCDIF_LAYERCLOCKGATE_DISABLE_VIDEO_CLK_MASK)) |
317 LCDIF_LAYERCLOCKGATE_DISABLE_VIDEO_CLK(!config->enable);
318 base->FRAMEBUFFERCONFIG0 = LCDIF_GetLayerConfig(config);
319 base->FRAMEBUFFERCLEARVALUE = config->clearValue;
320 base->VIDEOTL = LCDIF_VIDEOTL_X(config->topLeftX) | LCDIF_VIDEOTL_Y(config->topLeftY);
321 base->FRAMEBUFFERSIZE = LCDIF_FRAMEBUFFERSIZE_WIDTH(config->width) | LCDIF_FRAMEBUFFERSIZE_HEIGHT(config->height);
322 base->FRAMEBUFFERCOLORKEY = config->colorkey.lowValue;
323 base->FRAMEBUFFERCOLORKEYHIGH = config->colorkey.highValue;
324 base->VIDEOGLOBALALPHA = (uint32_t)(pid._u32 >> 16U);
325 base->VIDEOALPHABLENDCONFIG = (pid._u32 & 0xFFFFUL);
326 base->DCTILEINCFG0 = ((uint32_t)config->format >> 3U) | LCDIF_DCTILEINCFG0_YUV_STANDARD((uint32_t)config->standard);
327 }
328
329 /*!
330 * brief Configure the video layer position.
331 *
332 * Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version. Apart
333 * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
334 * to configure the legacy video layer, and use @ref LCDIF_SetOverlayLayerPosition to configure the overlay layers.
335 *
336 * param base LCDIF peripheral base address.
337 * param displayIndex Display index.
338 * param topLeftX The x value of thr top-left coordinate.
339 * param topLeftY The y value of thr top-left coordinate.
340 * param width The width of the layer.
341 * param height The height of the layer.
342 */
LCDIF_SetFrameBufferPosition(LCDIF_Type * base,uint8_t displayIndex,uint16_t topLeftX,uint16_t topLeftY,uint16_t width,uint16_t height)343 void LCDIF_SetFrameBufferPosition(
344 LCDIF_Type *base, uint8_t displayIndex, uint16_t topLeftX, uint16_t topLeftY, uint16_t width, uint16_t height)
345 {
346 base->VIDEOTL = LCDIF_VIDEOTL_X(topLeftX) | LCDIF_VIDEOTL_Y(topLeftY);
347 base->FRAMEBUFFERSIZE = LCDIF_FRAMEBUFFERSIZE_WIDTH(width) | LCDIF_FRAMEBUFFERSIZE_HEIGHT(height);
348 }
349
350 /*!
351 * brief Configure the overlay layers for LCDIF frame buffer.
352 *
353 * Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version. Apart
354 * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
355 * to configure the overlay layers, and use @ref LCDIF_SetFrameBufferConfig to configure the legacy video layer.
356 *
357 * param base LCDIF peripheral base address.
358 * param displayIndex Display index.
359 * param config Pointer to the configuration structure.
360 * param layerIndex Pointer to the configuration structure.
361 */
LCDIF_SetOverlayLayerConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_fb_config_t * config,uint8_t layerIndex)362 void LCDIF_SetOverlayLayerConfig(LCDIF_Type *base,
363 uint8_t displayIndex,
364 const lcdif_fb_config_t *config,
365 uint8_t layerIndex)
366 {
367 assert(NULL != config);
368
369 lcdif_reg32_convert_t pid;
370 pid._alphaConfig = config->alpha;
371
372 switch (layerIndex)
373 {
374 case 0U:
375 base->OVERLAYCONFIG = LCDIF_GetLayerConfig(config);
376 base->OVERLAYCLEARVALUE = config->clearValue;
377 base->LAYERCLOCKGATE = (base->LAYERCLOCKGATE & (~LCDIF_LAYERCLOCKGATE_DISABLE_OVERLAY0_CLK_MASK)) |
378 LCDIF_LAYERCLOCKGATE_DISABLE_OVERLAY0_CLK(!config->enable);
379 base->OVERLAYTL = LCDIF_OVERLAYTL_X(config->topLeftX) | LCDIF_OVERLAYTL_Y(config->topLeftY);
380 base->OVERLAYSIZE = LCDIF_OVERLAYSIZE_WIDTH(config->width) | LCDIF_OVERLAYSIZE_HEIGHT(config->height);
381 base->OVERLAYCOLORKEY = config->colorkey.lowValue;
382 base->OVERLAYCOLORKEYHIGH = config->colorkey.highValue;
383 base->OVERLAYGLOBALALPHA = (uint32_t)(pid._u32 >> 16U);
384 base->OVERLAYALPHABLENDCONFIG = (pid._u32 & 0xFFFFUL);
385 base->DCOVERLAYTILEINCFG =
386 ((uint32_t)config->format >> 3U) | LCDIF_DCTILEINCFG0_YUV_STANDARD((uint32_t)config->standard);
387 break;
388
389 case 1U:
390 base->OVERLAYCONFIG1 = LCDIF_GetLayerConfig(config);
391 base->OVERLAYCLEARVALUE = config->clearValue;
392 base->LAYERCLOCKGATE = (base->LAYERCLOCKGATE & (~LCDIF_LAYERCLOCKGATE_DISABLE_OVERLAY1_CLK_MASK)) |
393 LCDIF_LAYERCLOCKGATE_DISABLE_OVERLAY1_CLK(!config->enable);
394 base->OVERLAYTL1 = LCDIF_OVERLAYTL_X(config->topLeftX) | LCDIF_OVERLAYTL_Y(config->topLeftY);
395 base->OVERLAYSIZE1 = LCDIF_OVERLAYSIZE_WIDTH(config->width) | LCDIF_OVERLAYSIZE_HEIGHT(config->height);
396 base->OVERLAYCOLORKEY1 = config->colorkey.lowValue;
397 base->OVERLAYCOLORKEYHIGH1 = config->colorkey.highValue;
398 base->OVERLAYGLOBALALPHA1 = (uint32_t)(pid._u32 >> 16U);
399 base->OVERLAYALPHABLENDCONFIG1 = (pid._u32 & 0xFFFFUL);
400 break;
401
402 default:
403 /* Only 2 overlay layers. */
404 assert(false);
405 break;
406 }
407 }
408
409 /*!
410 * brief Configure the overlay layer position.
411 *
412 * Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version. Apart
413 * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
414 * to configure the overlay layers, and use @ref LCDIF_SetFrameBufferPosition to configure the legacy video layer.
415 *
416 * param base LCDIF peripheral base address.
417 * param displayIndex Display index.
418 * param topLeftX The x value of thr top-left coordinate.
419 * param topLeftY The y value of thr top-left coordinate.
420 * param width The width of the layer.
421 * param height The height of the layer.
422 * param layerIndex Pointer to the configuration structure.
423 */
LCDIF_SetOverlayLayerPosition(LCDIF_Type * base,uint8_t displayIndex,uint16_t topLeftX,uint16_t topLeftY,uint16_t width,uint16_t height,uint8_t layerIndex)424 void LCDIF_SetOverlayLayerPosition(LCDIF_Type *base,
425 uint8_t displayIndex,
426 uint16_t topLeftX,
427 uint16_t topLeftY,
428 uint16_t width,
429 uint16_t height,
430 uint8_t layerIndex)
431 {
432 switch (layerIndex)
433 {
434 case 0U:
435 base->OVERLAYTL = LCDIF_OVERLAYTL_X(topLeftX) | LCDIF_OVERLAYTL_Y(topLeftY);
436 base->OVERLAYSIZE = LCDIF_OVERLAYSIZE_WIDTH(width) | LCDIF_OVERLAYSIZE_HEIGHT(height);
437 break;
438
439 case 1U:
440 base->OVERLAYTL1 = LCDIF_OVERLAYTL_X(topLeftX) | LCDIF_OVERLAYTL_Y(topLeftY);
441 base->OVERLAYSIZE1 = LCDIF_OVERLAYSIZE_WIDTH(width) | LCDIF_OVERLAYSIZE_HEIGHT(height);
442 break;
443
444 default:
445 /* Only 2 overlay layers. */
446 assert(false);
447 break;
448 }
449 }
450
451 /*!
452 * brief Get the alpha blend configuration by porter duff blend mode.
453 *
454 * param mode The blend mode.
455 * param config Pointer to the configuration.
456 * retval kStatus_Success Successfully get the configuration.
457 * retval kStatus_InvalidArgument The blend mode not supported.
458 */
LCDIF_GetPorterDuffConfig(lcdif_porter_duff_blend_mode_t mode,lcdif_layer_alpha_blend_config_t * config)459 status_t LCDIF_GetPorterDuffConfig(lcdif_porter_duff_blend_mode_t mode, lcdif_layer_alpha_blend_config_t *config)
460 {
461 status_t status;
462
463 lcdif_reg32_convert_t pid;
464
465 static const uint32_t pdCtrl[] = {
466 /* kLCDIF_PorterDuffSrc */
467 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
468 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorOne) |
469 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorZero),
470
471 /* kLCDIF_PorterDuffAtop */
472 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
473 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorStraight) |
474 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorInversed),
475
476 /* kLCDIF_PorterDuffOver */
477 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
478 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorOne) |
479 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorInversed),
480
481 /* kLCDIF_PorterDuffIn */
482 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
483 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorStraight) |
484 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorZero),
485
486 /* kLCDIF_PorterDuffOut */
487 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
488 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorInversed) |
489 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorZero),
490
491 /* kLCDIF_PorterDuffDst */
492 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
493 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorZero) |
494 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorOne),
495
496 /* kLCDIF_PorterDuffDstAtop */
497 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
498 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorInversed) |
499 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorStraight),
500
501 /* kLCDIF_PorterDuffDstOver */
502 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
503 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorInversed) |
504 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorOne),
505
506 /* kLCDIF_PorterDuffDstIn */
507 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
508 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorZero) |
509 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorStraight),
510
511 /* kLCDIF_PorterDuffDstOut */
512 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
513 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorZero) |
514 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorInversed),
515
516 /* kLCDIF_PorterDuffPlus */
517 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
518 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorOne) |
519 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorOne),
520
521 /* kLCDIF_PorterDuffXor */
522 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
523 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorInversed) |
524 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorInversed),
525
526 /* kLCDIF_PorterDuffClear */
527 LCDIF_VIDEOALPHABLENDCONFIG_ALPHA_BLEND_MASK |
528 LCDIF_VIDEOALPHABLENDCONFIG_SRC_BLENDING_MODE(kLCDIF_AlphaFactorZero) |
529 LCDIF_VIDEOALPHABLENDCONFIG_DST_BLENDING_MODE(kLCDIF_AlphaFactorZero),
530 };
531
532 if (mode >= kLCDIF_PorterDuffMax)
533 {
534 status = kStatus_InvalidArgument;
535 }
536 else
537 {
538 pid._u32 = pdCtrl[(uint32_t)mode] |
539 LCDIF_VIDEOALPHABLENDCONFIG_SRC_GLOBAL_ALPHA_MODE((uint32_t)kLCDIF_AlphaLocal) |
540 LCDIF_VIDEOALPHABLENDCONFIG_DST_GLOBAL_ALPHA_MODE((uint32_t)kLCDIF_AlphaLocal) |
541 LCDIF_VIDEOALPHABLENDCONFIG_SRC_ALPHA_FACTOR((uint32_t) false) |
542 LCDIF_VIDEOALPHABLENDCONFIG_DST_ALPHA_FACTOR((uint32_t) false) |
543 LCDIF_VIDEOALPHABLENDCONFIG_SRC_ALPHA_MODE((uint32_t)kLCDIF_AlphaStraight) |
544 LCDIF_VIDEOALPHABLENDCONFIG_DST_ALPHA_MODE((uint32_t)kLCDIF_AlphaStraight);
545
546 *config = pid._alphaConfig;
547
548 status = kStatus_Success;
549 }
550
551 return status;
552 }
553
554 /*!
555 * brief Sets the frame buffer address for overlay layer.
556 *
557 * note The address must be 128 bytes aligned.
558 *
559 * param base LCDIF peripheral base address.
560 * param displayIndex Display index.
561 * param address Frame buffer address.
562 * param layerIndex Pointer to the configuration structure.
563 */
LCDIF_SetOverlayLayerAddr(LCDIF_Type * base,uint8_t displayIndex,uint32_t address,uint8_t layerIndex)564 void LCDIF_SetOverlayLayerAddr(LCDIF_Type *base, uint8_t displayIndex, uint32_t address, uint8_t layerIndex)
565 {
566 /* The frame buffer address and stride must be 128 bytes aligned. */
567 assert(0U == (address & (LCDIF_FB_ALIGN - 1U)));
568 assert(layerIndex < 2U);
569
570 switch (layerIndex)
571 {
572 case 0U:
573 base->OVERLAYADDRESS = LCDIF_ADDR_CPU_2_IP(address);
574 break;
575
576 case 1U:
577 base->OVERLAYADDRESS1 = LCDIF_ADDR_CPU_2_IP(address);
578 break;
579
580 default:
581 /* Only 2 overlay layers. */
582 assert(false);
583 break;
584 }
585 }
586
587 /*!
588 * brief Sets the frame buffer stride for overlay layer.
589 *
590 * param base LCDIF peripheral base address.
591 * param displayIndex Display index.
592 * param strideBytes The stride in byte.
593 * param layerIndex Pointer to the configuration structure.
594 */
LCDIF_SetOverlayLayerStride(LCDIF_Type * base,uint8_t displayIndex,uint32_t strideBytes,uint8_t layerIndex)595 void LCDIF_SetOverlayLayerStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes, uint8_t layerIndex)
596 {
597 assert(layerIndex < 2U);
598
599 switch (layerIndex)
600 {
601 case 0U:
602 base->OVERLAYSTRIDE = strideBytes;
603 break;
604
605 case 1U:
606 base->OVERLAYSTRIDE1 = strideBytes;
607 break;
608
609 default:
610 /* Only 2 overlay layers. */
611 assert(false);
612 break;
613 }
614 }
615
616 /*!
617 * brief Gets default panel configuration.
618 *
619 * The default configuration is
620 * config->enable = true;
621 * config->enableGamma = false;
622 * config->order = kLCDIF_VideoOverlay0Overlay1;
623 * config->endian = kLCDIF_NoSwap;
624 *
625 * param config Pointer to the configuration structure.
626 */
LCDIF_PanelGetDefaultConfig(lcdif_panel_config_t * config)627 void LCDIF_PanelGetDefaultConfig(lcdif_panel_config_t *config)
628 {
629 assert(config != NULL);
630
631 (void)memset(config, 0, sizeof(*config));
632
633 config->enable = true;
634 config->enableGamma = false;
635 config->order = kLCDIF_VideoOverlay0Overlay1;
636 config->endian = kLCDIF_NoSwap;
637 }
638
639 /*!
640 * brief Configure the LCDIF panel.
641 *
642 * param base LCDIF peripheral base address.
643 * param displayIndex Display index.
644 * param config Pointer to the configuration structure.
645 */
LCDIF_SetPanelConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_panel_config_t * config)646 void LCDIF_SetPanelConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_panel_config_t *config)
647 {
648 assert(NULL != config);
649
650 base->BLENDSTACKORDER = (uint32_t)config->order;
651 base->SRCCONFIGENDIAN = (uint32_t)config->endian;
652 base->PANELFUNCTION = (base->PANELFUNCTION & ~(LCDIF_PANELFUNCTION_OUTPUT_MASK | LCDIF_PANELFUNCTION_GAMMA_MASK)) |
653 LCDIF_PANELFUNCTION_OUTPUT((uint32_t)config->enable) |
654 LCDIF_PANELFUNCTION_GAMMA((uint32_t)config->enableGamma);
655 }
656
657 #else
658
659 /*!
660 * @brief Get default frame buffer configuration.
661 *
662 * The default configuration is
663 * config->enable = true;
664 * config->enableGamma = false;
665 * config->format = kLCDIF_PixelFormatRGB565;
666 *
667 * @param config Pointer to the configuration structure.
668 */
LCDIF_FrameBufferGetDefaultConfig(lcdif_fb_config_t * config)669 void LCDIF_FrameBufferGetDefaultConfig(lcdif_fb_config_t *config)
670 {
671 assert(config != NULL);
672
673 (void)memset(config, 0, sizeof(*config));
674
675 config->enable = true;
676 config->enableGamma = false;
677 config->format = kLCDIF_PixelFormatRGB565;
678 }
679
680 /*!
681 * brief Configure the LCDIF frame buffer.
682 *
683 * param base LCDIF peripheral base address.
684 * param displayIndex Display index.
685 * param config Pointer to the configuration structure.
686 */
LCDIF_SetFrameBufferConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_fb_config_t * config)687 void LCDIF_SetFrameBufferConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_fb_config_t *config)
688 {
689 assert(NULL != config);
690 uint32_t reg;
691
692 if (config->enable)
693 {
694 reg = LCDIF_FRAMEBUFFERCONFIG0_RESET_MASK | LCDIF_FRAMEBUFFERCONFIG0_OUTPUT_MASK | (uint32_t)config->format;
695 if (config->enableGamma)
696 {
697 reg |= LCDIF_FRAMEBUFFERCONFIG0_GAMMA_MASK;
698 }
699 base->FRAMEBUFFERCONFIG0 = reg;
700 }
701 else
702 {
703 base->FRAMEBUFFERCONFIG0 = 0U;
704 }
705 }
706
707 #endif
708
709 /*
710 * @brief Set the frame buffer stride.
711 *
712 * @param base LCDIF peripheral base address.
713 * @param displayIndex Display index.
714 * @param strideBytes The stride in byte.
715 */
LCDIF_SetFrameBufferStride(LCDIF_Type * base,uint8_t displayIndex,uint32_t strideBytes)716 void LCDIF_SetFrameBufferStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes)
717 {
718 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
719 base->FRAMEBUFFERSTRIDE0 = strideBytes;
720 #else
721 base->FRAMEBUFFERSTRIDE0 = LCDIF_ALIGN_ADDR(strideBytes, LCDIF_FB_ALIGN);
722 #endif
723 }
724
725 /*!
726 * brief Set the dither configuration.
727 *
728 * param base LCDIF peripheral base address.
729 * param displayIndex Index to configure.
730 * param config Pointer to the configuration structure.
731 */
LCDIF_SetDitherConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_dither_config_t * config)732 void LCDIF_SetDitherConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dither_config_t *config)
733 {
734 assert(NULL != config);
735
736 if (config->enable)
737 {
738 base->DISPLAYDITHERTABLELOW0 = config->low;
739 base->DISPLAYDITHERTABLEHIGH0 = config->high;
740 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
741 base->PANELFUNCTION |= LCDIF_PANELFUNCTION_DITHER_MASK;
742 #else
743 base->DISPLAYDITHERCONFIG0 = ((uint32_t)config->redSize << LCDIF_DISPLAYDITHERCONFIG0_RED_SIZE_SHIFT) |
744 ((uint32_t)config->greenSize << LCDIF_DISPLAYDITHERCONFIG0_GREEN_SIZE_SHIFT) |
745 ((uint32_t)config->blueSize << LCDIF_DISPLAYDITHERCONFIG0_BLUE_SIZE_SHIFT) |
746 LCDIF_DISPLAYDITHERCONFIG0_ENABLE_MASK;
747 #endif
748 }
749 else
750 {
751 base->DISPLAYDITHERTABLELOW0 = 0U;
752 base->DISPLAYDITHERTABLEHIGH0 = 0U;
753 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
754 base->PANELFUNCTION &= ~LCDIF_PANELFUNCTION_DITHER_MASK;
755 #else
756 base->DISPLAYDITHERCONFIG0 = 0U;
757 #endif
758 }
759 }
760
761 /*!
762 * brief Set the gamma translation values to the LCDIF gamma table.
763 *
764 * param base LCDIF peripheral base address.
765 * param displayIndex Display index.
766 * param startIndex Start index in the gamma table that the value will be set to.
767 * param gamma The gamma values to set to the gamma table in LCDIF, could be defined using LCDIF_MAKE_GAMMA_VALUE.
768 * param gammaLen The length of the p gamma.
769 */
LCDIF_SetGammaData(LCDIF_Type * base,uint8_t displayIndex,uint16_t startIndex,const uint32_t * gamma,uint16_t gammaLen)770 void LCDIF_SetGammaData(
771 LCDIF_Type *base, uint8_t displayIndex, uint16_t startIndex, const uint32_t *gamma, uint16_t gammaLen)
772 {
773 assert(startIndex + gammaLen <= LCDIF_GAMMA_INDEX_MAX);
774
775 base->GAMMAINDEX0 = startIndex;
776
777 while (0U != (gammaLen--))
778 {
779 base->GAMMADATA0 = *(gamma++);
780 }
781 }
782
783 /*!
784 * brief Initialize the LCDIF to work in DBI mode.
785 *
786 * This function configures the LCDIF DBI display.
787 *
788 * param base LCDIF peripheral base address.
789 * param displayIndex Display index.
790 * param config Pointer to the configuration structure.
791 * retval kStatus_Success Initialize successfully.
792 * retval kStatus_InvalidArgument Initialize failed because of invalid argument.
793 */
LCDIF_DbiModeSetConfig(LCDIF_Type * base,uint8_t displayIndex,const lcdif_dbi_config_t * config)794 status_t LCDIF_DbiModeSetConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dbi_config_t *config)
795 {
796 base->FRAMEBUFFERCONFIG0 = 0;
797
798 base->PANELCONFIG0 = 0U;
799
800 /* Set to DBI mode. */
801 base->DBICONFIG0 = LCDIF_DBICONFIG0_DBI_AC_TIME_UNIT(config->acTimeUnit) |
802 #if (defined(FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY) && FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY)
803 LCDIF_DBICONFIG0_DBIX_POLARITY(config->reversePolarity ? 0UL : 1UL) |
804 #endif
805 LCDIF_DBICONFIG0_BUS_OUTPUT_SEL(1) | (uint32_t)config->format |
806 LCDIF_DBICONFIG0_DBI_TYPE(config->type);
807
808 /*Put DBI bus into idle*/
809 base->DBIIFRESET0 = LCDIF_DBIIFRESET0_DBI_IF_LEVEL_RESET_MASK;
810
811 /*Config AC characteristics*/
812 base->DBIWRCHAR10 = LCDIF_DBIWRCHAR10_DBI_WR_CS_ASSERT(config->writeCSAssert) |
813 LCDIF_DBIWRCHAR10_DBI_WR_EOR_WR_ASSERT(config->writeWRAssert) |
814 LCDIF_DBIWRCHAR10_DBI_WR_PERIOD(config->writeWRPeriod);
815
816 base->DBIWRCHAR20 = LCDIF_DBIWRCHAR20_DBI_WR_CS_DE_ASRT(config->writeCSDeassert) |
817 LCDIF_DBIWRCHAR20_DBI_WR_EOR_WR_DE_ASRT(config->writeWRDeassert);
818
819 return kStatus_Success;
820 }
821
822 /*!
823 * brief Get the default configuration to initialize the LCDIF DBI mode.
824 *
825 * The default configuration value is:
826 *
827 * code
828 * config->swizzle = kLCDIF_DbiOutSwizzleRGB;
829 * config->format = kLCDIF_DbiOutD8RGB332;
830 * config->acTimeUnit = 0;
831 * config->type = kLCDIF_DbiTypeA_ClockedE;
832 * config->reversePolarity = false;
833 * config->writeWRPeriod = 3U;
834 * config->writeWRAssert = 0U;
835 * config->writeCSAssert = 0U;
836 * config->writeWRDeassert = 0U;
837 * config->writeCSDeassert = 0U;
838 * config->typeCTas = 1U;
839 * config->typeCSCLTwrl = 1U;
840 * config->typeCSCLTwrh = 1U;
841 * endcode
842 *
843 * param config Pointer to the LCDIF DBI configuration.
844 */
LCDIF_DbiModeGetDefaultConfig(lcdif_dbi_config_t * config)845 void LCDIF_DbiModeGetDefaultConfig(lcdif_dbi_config_t *config)
846 {
847 config->swizzle = kLCDIF_DbiOutSwizzleRGB;
848 config->format = kLCDIF_DbiOutD8RGB332;
849 config->acTimeUnit = 0;
850
851 #if (defined(FSL_FEATURE_LCDIF_HAS_DBI_TYPE) && FSL_FEATURE_LCDIF_HAS_DBI_TYPE)
852 config->type = kLCDIF_DbiTypeA_ClockedE;
853 #endif
854
855 #if (defined(FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY) && FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY)
856 config->reversePolarity = false;
857 #endif
858
859 config->writeWRPeriod = 3U;
860 config->writeWRAssert = 0U;
861 config->writeCSAssert = 0U;
862 config->writeWRDeassert = 0U;
863 config->writeCSDeassert = 0U;
864
865 #if (defined(FSL_FEATURE_LCDIF_HAS_TYPEC) && FSL_FEATURE_LCDIF_HAS_TYPEC)
866 config->typeCTas = 1U;
867 config->typeCSCLTwrl = 1U;
868 config->typeCSCLTwrh = 1U;
869 #endif
870 }
871
872 /*!
873 * brief Select the update area in DBI mode.
874 *
875 * param base LCDIF peripheral base address.
876 * param displayIndex Display index.
877 * param startX X coordinate for start pixel.
878 * param startY Y coordinate for start pixel.
879 * param endX X coordinate for end pixel.
880 * param endY Y coordinate for end pixel.
881 * param isTiled true if the pixel data is tiled.
882 */
LCDIF_DbiSelectArea(LCDIF_Type * base,uint8_t displayIndex,uint16_t startX,uint16_t startY,uint16_t endX,uint16_t endY,bool isTiled)883 void LCDIF_DbiSelectArea(LCDIF_Type *base,
884 uint8_t displayIndex,
885 uint16_t startX,
886 uint16_t startY,
887 uint16_t endX,
888 uint16_t endY,
889 bool isTiled)
890 {
891 uint16_t width = endX - startX + 1U;
892 uint16_t height = endY - startY + 1U;
893
894 uint16_t vDisplayExtra = isTiled ? 2U : 1U; /* Used for waiting for the data FIFO to be filled */
895
896 base->HDISPLAY0 = LCDIF_HDISPLAY0_DISPLAY_END((uint32_t)width) | LCDIF_HDISPLAY0_TOTAL((uint32_t)width);
897 base->HSYNC0 = LCDIF_HSYNC0_START((uint32_t)startX) | LCDIF_HSYNC0_END((uint32_t)endX + 1UL);
898
899 base->VDISPLAY0 = LCDIF_VDISPLAY0_DISPLAY_END((uint32_t)height) |
900 LCDIF_VDISPLAY0_TOTAL((uint32_t)height + (uint32_t)vDisplayExtra);
901
902 if (isTiled)
903 {
904 base->VSYNC0 = LCDIF_VSYNC0_START((uint32_t)startY) | LCDIF_VSYNC0_END((uint32_t)endY + 1UL);
905 }
906 }
907
908 /*!
909 * brief Send data to DBI port.
910 *
911 * Can be used to send light weight data to panel. To send pixel data in frame buffer, use @ref LCDIF_DbiWriteMem.
912 *
913 * param base LCDIF peripheral base address.
914 * param displayIndex Display index.
915 * param data pointer to data buffer.
916 * param dataLen_Byte data buffer length in byte.
917 */
LCDIF_DbiSendData(LCDIF_Type * base,uint8_t displayIndex,const uint8_t * data,uint32_t dataLen_Byte)918 void LCDIF_DbiSendData(LCDIF_Type *base, uint8_t displayIndex, const uint8_t *data, uint32_t dataLen_Byte)
919 {
920 while (dataLen_Byte > 0U)
921 {
922 /* Send data. DBICMD bit set to 1, means currently send data, used in type C mode. */
923 base->DBICMD0 = LCDIF_DBICMD0_DBI_COMMANDFLAG(kLCDIF_DbiCmdData) | (uint32_t)(*data) | (1UL << 8U);
924 data++;
925 dataLen_Byte--;
926 }
927 }
928
929 /*!
930 * brief Send command followed by data to DBI port.
931 *
932 * param base LCDIF peripheral base address.
933 * param displayIndex Display index.
934 * param cmd the DBI command to send.
935 * param data pointer to data buffer.
936 * param dataLen_Byte data buffer length in byte.
937 */
LCDIF_DbiSendCommandAndData(LCDIF_Type * base,uint8_t displayIndex,uint8_t cmd,const uint8_t * data,uint32_t dataLen_Byte)938 void LCDIF_DbiSendCommandAndData(
939 LCDIF_Type *base, uint8_t displayIndex, uint8_t cmd, const uint8_t *data, uint32_t dataLen_Byte)
940 {
941 LCDIF_DbiSendCommand(base, displayIndex, cmd);
942 LCDIF_DbiSendData(base, displayIndex, data, dataLen_Byte);
943 }
944
945 /*!
946 * brief Get the hardware cursor default configuration
947 *
948 * The default configuration values are:
949 *
950 * code
951 * config->enable = true;
952 * config->format = kLCDIF_CursorMasked;
953 * config->hotspotOffsetX = 0;
954 * config->hotspotOffsetY = 0;
955 * endcode
956 *
957 * param config Pointer to the hardware cursor configuration structure.
958 */
LCDIF_CursorGetDefaultConfig(lcdif_cursor_config_t * config)959 void LCDIF_CursorGetDefaultConfig(lcdif_cursor_config_t *config)
960 {
961 assert(NULL != config);
962
963 (void)memset(config, 0, sizeof(*config));
964
965 config->enable = true;
966 config->format = kLCDIF_CursorMasked;
967 config->hotspotOffsetX = 0;
968 config->hotspotOffsetY = 0;
969 }
970
971 /*!
972 * brief Configure the cursor.
973 *
974 * param base LCDIF peripheral base address.
975 * param config Cursor configuration.
976 */
LCDIF_SetCursorConfig(LCDIF_Type * base,const lcdif_cursor_config_t * config)977 void LCDIF_SetCursorConfig(LCDIF_Type *base, const lcdif_cursor_config_t *config)
978 {
979 assert(NULL != config);
980
981 uint32_t regConfig = 0U;
982
983 if (config->enable)
984 {
985 regConfig |= (uint32_t)(config->format) << LCDIF_CURSORCONFIG_FORMAT_SHIFT;
986 regConfig |= (((uint32_t)config->hotspotOffsetX << LCDIF_CURSORCONFIG_HOT_SPOT_X_SHIFT) |
987 ((uint32_t)config->hotspotOffsetY << LCDIF_CURSORCONFIG_HOT_SPOT_Y_SHIFT));
988 }
989
990 base->CURSORCONFIG = regConfig;
991 }
992
993 /*!
994 * brief Set the cursor color
995 *
996 * param base LCDIF peripheral base address.
997 * param background Background color, could be defined use ref LCDIF_MAKE_CURSOR_COLOR
998 * param foreground Foreground color, could be defined use ref LCDIF_MAKE_CURSOR_COLOR
999 */
LCDIF_SetCursorColor(LCDIF_Type * base,uint32_t background,uint32_t foreground)1000 void LCDIF_SetCursorColor(LCDIF_Type *base, uint32_t background, uint32_t foreground)
1001 {
1002 base->CURSORBACKGROUND = background;
1003 base->CURSORFOREGROUND = foreground;
1004 }
1005