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