1 /*
2 * Copyright 2017-2022 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #ifndef _FSL_ELCDIF_H_
10 #define _FSL_ELCDIF_H_
11
12 #include "fsl_common.h"
13
14 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (0 != FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET))
15 #include "fsl_memory.h"
16 #endif
17
18 /*!
19 * @addtogroup elcdif
20 * @{
21 */
22
23 /*******************************************************************************
24 * Definitions
25 ******************************************************************************/
26
27 /*! @name Driver version */
28 /*@{*/
29 /*! @brief eLCDIF driver version */
30 #define FSL_ELCDIF_DRIVER_VERSION (MAKE_VERSION(2, 0, 5))
31 /*@}*/
32
33 /* All IRQ flags in CTRL1 register. */
34 #define ELCDIF_CTRL1_IRQ_MASK \
35 (LCDIF_CTRL1_BM_ERROR_IRQ_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_MASK | \
36 LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK)
37
38 /* All IRQ enable control bits in CTRL1 register. */
39 #define ELCDIF_CTRL1_IRQ_EN_MASK \
40 (LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK | \
41 LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK)
42
43 /* All IRQ flags in AS_CTRL register. */
44 #if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
45 #define ELCDIF_AS_CTRL_IRQ_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
46 #else
47 #define ELCDIF_AS_CTRL_IRQ_MASK 0U
48 #endif
49
50 /* All IRQ enable control bits in AS_CTRL register. */
51 #if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
52 #define ELCDIF_AS_CTRL_IRQ_EN_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
53 #else
54 #define ELCDIF_AS_CTRL_IRQ_EN_MASK 0U
55 #endif
56
57 #if ((0 != (ELCDIF_CTRL1_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_MASK)) || \
58 (0 != (ELCDIF_AS_CTRL_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_EN_MASK)))
59 #error Interrupt bits overlap, need to update the interrupt functions.
60 #endif
61
62 #if defined(LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK)
63 #define FSL_FEATURE_LCDIF_HAS_PXP_HANDSHAKE 1
64 #else
65 #define FSL_FEATURE_LCDIF_HAS_PXP_HANDSHAKE 0
66 #endif
67
68 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (0 != FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET))
69 #define ELCDIF_ADDR_CPU_2_IP(addr) (MEMORY_ConvertMemoryMapAddress((uint32_t)(addr), kMEMORY_Local2DMA))
70 #else
71 #define ELCDIF_ADDR_CPU_2_IP(addr) (addr)
72 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
73
74 /* LUT memory entery number. */
75 #define ELCDIF_LUT_ENTRY_NUM 256U
76
77 /*!
78 * @brief eLCDIF signal polarity flags
79 */
80 enum _elcdif_polarity_flags
81 {
82 kELCDIF_VsyncActiveLow = 0U, /*!< VSYNC active low. */
83 kELCDIF_HsyncActiveLow = 0U, /*!< HSYNC active low. */
84 kELCDIF_DataEnableActiveLow = 0U, /*!< Data enable line active low. */
85 kELCDIF_DriveDataOnFallingClkEdge = 0U, /*!< Drive data on falling clock edge, capture data
86 on rising clock edge. */
87
88 kELCDIF_VsyncActiveHigh = LCDIF_VDCTRL0_VSYNC_POL_MASK, /*!< VSYNC active high. */
89 kELCDIF_HsyncActiveHigh = LCDIF_VDCTRL0_HSYNC_POL_MASK, /*!< HSYNC active high. */
90 kELCDIF_DataEnableActiveHigh = LCDIF_VDCTRL0_ENABLE_POL_MASK, /*!< Data enable line active high. */
91 kELCDIF_DriveDataOnRisingClkEdge = LCDIF_VDCTRL0_DOTCLK_POL_MASK, /*!< Drive data on falling
92 clock edge, capture data
93 on rising clock edge. */
94 };
95
96 /*!
97 * @brief The eLCDIF interrupts to enable.
98 */
99 enum _elcdif_interrupt_enable
100 {
101 kELCDIF_BusMasterErrorInterruptEnable = LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK, /*!< Bus master error interrupt. */
102 kELCDIF_TxFifoOverflowInterruptEnable = LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK, /*!< TXFIFO overflow interrupt. */
103 kELCDIF_TxFifoUnderflowInterruptEnable = LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK, /*!< TXFIFO underflow interrupt. */
104 kELCDIF_CurFrameDoneInterruptEnable =
105 LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
106 kELCDIF_VsyncEdgeInterruptEnable =
107 LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
108 #if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
109 kELCDIF_SciSyncOnInterruptEnable =
110 LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
111 #endif
112 };
113
114 /*!
115 * @brief The eLCDIF interrupt status flags.
116 */
117 enum _elcdif_interrupt_flags
118 {
119 kELCDIF_BusMasterError = LCDIF_CTRL1_BM_ERROR_IRQ_MASK, /*!< Bus master error interrupt. */
120 kELCDIF_TxFifoOverflow = LCDIF_CTRL1_OVERFLOW_IRQ_MASK, /*!< TXFIFO overflow interrupt. */
121 kELCDIF_TxFifoUnderflow = LCDIF_CTRL1_UNDERFLOW_IRQ_MASK, /*!< TXFIFO underflow interrupt. */
122 kELCDIF_CurFrameDone =
123 LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
124 kELCDIF_VsyncEdge = LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
125 #if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
126 kELCDIF_SciSyncOn = LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
127 #endif
128 };
129
130 /*!
131 * @brief eLCDIF status flags
132 */
133 enum _elcdif_status_flags
134 {
135 kELCDIF_LFifoFull = LCDIF_STAT_LFIFO_FULL_MASK, /*!< LFIFO full. */
136 kELCDIF_LFifoEmpty = LCDIF_STAT_LFIFO_EMPTY_MASK, /*!< LFIFO empty. */
137 kELCDIF_TxFifoFull = LCDIF_STAT_TXFIFO_FULL_MASK, /*!< TXFIFO full. */
138 kELCDIF_TxFifoEmpty = LCDIF_STAT_TXFIFO_EMPTY_MASK, /*!< TXFIFO empty. */
139 #if defined(LCDIF_STAT_BUSY_MASK)
140 kELCDIF_LcdControllerBusy = LCDIF_STAT_BUSY_MASK, /*!< The external LCD controller busy signal. */
141 #endif
142 #if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
143 kELCDIF_CurDviField2 = LCDIF_STAT_DVI_CURRENT_FIELD_MASK, /*!< Current DVI filed, if set, then current filed is 2,
144 otherwise current filed is 1. */
145 #endif
146 };
147
148 /*!
149 * @brief The pixel format.
150 *
151 * This enumerator should be defined together with the array s_pixelFormatReg.
152 * To support new pixel format, enhance this enumerator and s_pixelFormatReg.
153 */
154 typedef enum _elcdif_pixel_format
155 {
156 kELCDIF_PixelFormatRAW8 = 0, /*!< RAW 8 bit, four data use 32 bits. */
157 kELCDIF_PixelFormatRGB565 = 1, /*!< RGB565, two pixel use 32 bits. */
158 kELCDIF_PixelFormatRGB666 = 2, /*!< RGB666 unpacked, one pixel uses 32 bits, high byte unused,
159 upper 2 bits of other bytes unused. */
160 kELCDIF_PixelFormatXRGB8888 = 3, /*!< XRGB8888 unpacked, one pixel uses 32 bits, high byte unused. */
161 kELCDIF_PixelFormatRGB888 = 4, /*!< RGB888 packed, one pixel uses 24 bits. */
162 } elcdif_pixel_format_t;
163
164 /*! @brief The LCD data bus type. */
165 typedef enum _elcdif_lcd_data_bus
166 {
167 kELCDIF_DataBus8Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(1), /*!< 8-bit data bus. */
168 kELCDIF_DataBus16Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(0), /*!< 16-bit data bus, support RGB565. */
169 kELCDIF_DataBus18Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(2), /*!< 18-bit data bus, support RGB666. */
170 kELCDIF_DataBus24Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(3), /*!< 24-bit data bus, support RGB888. */
171 } elcdif_lcd_data_bus_t;
172
173 /*!
174 * @brief The register value when using different pixel format.
175 *
176 * These register bits control the pixel format:
177 * - CTRL[DATA_FORMAT_24_BIT]
178 * - CTRL[DATA_FORMAT_18_BIT]
179 * - CTRL[DATA_FORMAT_16_BIT]
180 * - CTRL[WORD_LENGTH]
181 * - CTRL1[BYTE_PACKING_FORMAT]
182 */
183 typedef struct _elcdif_pixel_format_reg
184 {
185 uint32_t regCtrl; /*!< Value of register CTRL. */
186 uint32_t regCtrl1; /*!< Value of register CTRL1. */
187 } elcdif_pixel_format_reg_t;
188
189 /*!
190 * @brief eLCDIF configure structure for RGB mode (DOTCLK mode).
191 */
192 typedef struct _elcdif_rgb_mode_config
193 {
194 uint16_t panelWidth; /*!< Display panel width, pixels per line. */
195 uint16_t panelHeight; /*!< Display panel height, how many lines per panel. */
196 uint8_t hsw; /*!< HSYNC pulse width. */
197 uint8_t hfp; /*!< Horizontal front porch. */
198 uint8_t hbp; /*!< Horizontal back porch. */
199 uint8_t vsw; /*!< VSYNC pulse width. */
200 uint8_t vfp; /*!< Vrtical front porch. */
201 uint8_t vbp; /*!< Vertical back porch. */
202 uint32_t polarityFlags; /*!< OR'ed value of @ref _elcdif_polarity_flags, used to contol the signal polarity. */
203 uint32_t bufferAddr; /*!< Frame buffer address. */
204 elcdif_pixel_format_t pixelFormat; /*!< Pixel format. */
205 elcdif_lcd_data_bus_t dataBus; /*!< LCD data bus. */
206 } elcdif_rgb_mode_config_t;
207
208 /*!
209 * @brief eLCDIF alpha surface pixel format.
210 */
211 typedef enum _elcdif_as_pixel_format
212 {
213 kELCDIF_AsPixelFormatARGB8888 = 0x0, /*!< 32-bit pixels with alpha. */
214 kELCDIF_AsPixelFormatRGB888 = 0x4, /*!< 32-bit pixels without alpha (unpacked 24-bit format) */
215 kELCDIF_AsPixelFormatARGB1555 = 0x8, /*!< 16-bit pixels with alpha. */
216 kELCDIF_AsPixelFormatARGB4444 = 0x9, /*!< 16-bit pixels with alpha. */
217 kELCDIF_AsPixelFormatRGB555 = 0xC, /*!< 16-bit pixels without alpha. */
218 kELCDIF_AsPixelFormatRGB444 = 0xD, /*!< 16-bit pixels without alpha. */
219 kELCDIF_AsPixelFormatRGB565 = 0xE, /*!< 16-bit pixels without alpha. */
220 } elcdif_as_pixel_format_t;
221
222 /*!
223 * @brief eLCDIF alpha surface buffer configuration.
224 */
225 typedef struct _elcdif_as_buffer_config
226 {
227 uint32_t bufferAddr; /*!< Buffer address. */
228 elcdif_as_pixel_format_t pixelFormat; /*!< Pixel format. */
229 } elcdif_as_buffer_config_t;
230
231 /*!
232 * @brief eLCDIF alpha mode during blending.
233 */
234 typedef enum _elcdif_alpha_mode
235 {
236 kELCDIF_AlphaEmbedded, /*!< The alpha surface pixel alpha value will be used for blend. */
237 kELCDIF_AlphaOverride, /*!< The user defined alpha value will be used for blend directly. */
238 kELCDIF_AlphaMultiply, /*!< The alpha surface pixel alpha value scaled the user defined
239 alpha value will be used for blend, for example, pixel alpha set
240 set to 200, user defined alpha set to 100, then the reault alpha
241 is 200 * 100 / 255. */
242 kELCDIF_AlphaRop /*!< Raster operation. */
243 } elcdif_alpha_mode_t;
244
245 /*!
246 * @brief eLCDIF ROP mode during blending.
247 *
248 * Explanation:
249 * - AS: Alpha surface
250 * - PS: Process surface
251 * - nAS: Alpha surface NOT value
252 * - nPS: Process surface NOT value
253 */
254 typedef enum _elcdif_rop_mode
255 {
256 kELCDIF_RopMaskAs = 0x0, /*!< AS AND PS. */
257 kELCDIF_RopMaskNotAs = 0x1, /*!< nAS AND PS. */
258 kELCDIF_RopMaskAsNot = 0x2, /*!< AS AND nPS. */
259 kELCDIF_RopMergeAs = 0x3, /*!< AS OR PS. */
260 kELCDIF_RopMergeNotAs = 0x4, /*!< nAS OR PS. */
261 kELCDIF_RopMergeAsNot = 0x5, /*!< AS OR nPS. */
262 kELCDIF_RopNotCopyAs = 0x6, /*!< nAS. */
263 kELCDIF_RopNot = 0x7, /*!< nPS. */
264 kELCDIF_RopNotMaskAs = 0x8, /*!< AS NAND PS. */
265 kELCDIF_RopNotMergeAs = 0x9, /*!< AS NOR PS. */
266 kELCDIF_RopXorAs = 0xA, /*!< AS XOR PS. */
267 kELCDIF_RopNotXorAs = 0xB /*!< AS XNOR PS. */
268 } elcdif_rop_mode_t;
269
270 /*!
271 * @brief eLCDIF alpha surface blending configuration.
272 */
273 typedef struct _elcdif_as_blend_config
274 {
275 uint8_t alpha; /*!< User defined alpha value, only used when @ref alphaMode is @ref kELCDIF_AlphaOverride or @ref
276 kELCDIF_AlphaRop. */
277 bool invertAlpha; /*!< Set true to invert the alpha. */
278 elcdif_alpha_mode_t alphaMode; /*!< Alpha mode. */
279 elcdif_rop_mode_t ropMode; /*!< ROP mode, only valid when @ref alphaMode is @ref kELCDIF_AlphaRop. */
280 } elcdif_as_blend_config_t;
281
282 /*!
283 * @brief eLCDIF LUT
284 *
285 * The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
286 * before output to external displayer.
287 *
288 * There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
289 * determins which memory to use.
290 */
291 typedef enum _elcdif_lut
292 {
293 kELCDIF_Lut0 = 0, /*!< LUT 0. */
294 kELCDIF_Lut1, /*!< LUT 1. */
295 } elcdif_lut_t;
296
297 /*******************************************************************************
298 * APIs
299 ******************************************************************************/
300
301 #if defined(__cplusplus)
302 extern "C" {
303 #endif /* __cplusplus */
304
305 /*!
306 * @name eLCDIF initialization and de-initialization
307 * @{
308 */
309
310 /*!
311 * @brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode).
312 *
313 * This function ungates the eLCDIF clock and configures the eLCDIF peripheral according
314 * to the configuration structure.
315 *
316 * @param base eLCDIF peripheral base address.
317 * @param config Pointer to the configuration structure.
318 */
319 void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config);
320
321 /*!
322 * @brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode.
323 *
324 * This function sets the configuration structure to default values.
325 * The default configuration is set to the following values.
326 * @code
327 config->panelWidth = 480U;
328 config->panelHeight = 272U;
329 config->hsw = 41;
330 config->hfp = 4;
331 config->hbp = 8;
332 config->vsw = 10;
333 config->vfp = 4;
334 config->vbp = 2;
335 config->polarityFlags = kELCDIF_VsyncActiveLow |
336 kELCDIF_HsyncActiveLow |
337 kELCDIF_DataEnableActiveLow |
338 kELCDIF_DriveDataOnFallingClkEdge;
339 config->bufferAddr = 0U;
340 config->pixelFormat = kELCDIF_PixelFormatRGB888;
341 config->dataBus = kELCDIF_DataBus24Bit;
342 @endcode
343 *
344 * @param config Pointer to the eLCDIF configuration structure.
345 */
346 void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config);
347
348 /*!
349 * @brief Deinitializes the eLCDIF peripheral.
350 *
351 * @param base eLCDIF peripheral base address.
352 */
353 void ELCDIF_Deinit(LCDIF_Type *base);
354
355 /* @} */
356
357 /*!
358 * @name Module operation
359 * @{
360 */
361
362 /*!
363 * @brief Set the pixel format in RGB (DOTCLK) mode.
364 *
365 * @param base eLCDIF peripheral base address.
366 * @param pixelFormat The pixel format.
367 */
368 void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat);
369
370 /*!
371 * @brief Start to display in RGB (DOTCLK) mode.
372 *
373 * @param base eLCDIF peripheral base address.
374 */
ELCDIF_RgbModeStart(LCDIF_Type * base)375 static inline void ELCDIF_RgbModeStart(LCDIF_Type *base)
376 {
377 base->CTRL_SET = LCDIF_CTRL_RUN_MASK | LCDIF_CTRL_DOTCLK_MODE_MASK;
378 }
379
380 /*!
381 * @brief Stop display in RGB (DOTCLK) mode and wait until finished.
382 *
383 * @param base eLCDIF peripheral base address.
384 */
385 void ELCDIF_RgbModeStop(LCDIF_Type *base);
386
387 /*!
388 * @brief Set the next frame buffer address to display.
389 *
390 * @param base eLCDIF peripheral base address.
391 * @param bufferAddr The frame buffer address to set.
392 */
ELCDIF_SetNextBufferAddr(LCDIF_Type * base,uint32_t bufferAddr)393 static inline void ELCDIF_SetNextBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
394 {
395 base->NEXT_BUF = ELCDIF_ADDR_CPU_2_IP(bufferAddr);
396 }
397
398 /*!
399 * @brief Reset the eLCDIF peripheral.
400 *
401 * @param base eLCDIF peripheral base address.
402 */
403 void ELCDIF_Reset(LCDIF_Type *base);
404
405 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN) && (0 != FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN))
406 /*!
407 * @brief Pull up or down the reset pin for the externel LCD controller.
408 *
409 * @param base eLCDIF peripheral base address.
410 * @param pullUp True to pull up reset pin, false to pull down.
411 */
ELCDIF_PullUpResetPin(LCDIF_Type * base,bool pullUp)412 static inline void ELCDIF_PullUpResetPin(LCDIF_Type *base, bool pullUp)
413 {
414 if (pullUp)
415 {
416 base->CTRL1_SET = LCDIF_CTRL1_RESET_MASK;
417 }
418 else
419 {
420 base->CTRL1_CLR = LCDIF_CTRL1_RESET_MASK;
421 }
422 }
423 #endif
424
425 #if (defined(FSL_FEATURE_LCDIF_HAS_PXP_HANDSHAKE) && (0 != FSL_FEATURE_LCDIF_HAS_PXP_HANDSHAKE))
426 /*!
427 * @brief Enable or disable the hand shake with PXP.
428 *
429 * @param base eLCDIF peripheral base address.
430 * @param enable True to enable, false to disable.
431 */
ELCDIF_EnablePxpHandShake(LCDIF_Type * base,bool enable)432 static inline void ELCDIF_EnablePxpHandShake(LCDIF_Type *base, bool enable)
433 {
434 if (enable)
435 {
436 base->CTRL_SET = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
437 }
438 else
439 {
440 base->CTRL_CLR = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
441 }
442 }
443 #endif
444
445 /* @} */
446
447 /*!
448 * @name Status
449 * @{
450 */
451
452 /*!
453 * @brief Get the CRC value of the frame sent out.
454 *
455 * When a frame is sent complete (the interrupt @ref kELCDIF_CurFrameDone assert), this function
456 * can be used to get the CRC value of the frame sent.
457 *
458 * @param base eLCDIF peripheral base address.
459 * @return The CRC value.
460 *
461 * @note The CRC value is dependent on the LCD_DATABUS_WIDTH.
462 */
ELCDIF_GetCrcValue(const LCDIF_Type * base)463 static inline uint32_t ELCDIF_GetCrcValue(const LCDIF_Type *base)
464 {
465 return base->CRC_STAT;
466 }
467
468 /*!
469 * @brief Get the bus master error virtual address.
470 *
471 * When bus master error occurs (the interrupt kELCDIF_BusMasterError assert), this function
472 * can get the virtual address at which the AXI master received an error
473 * response from the slave.
474 *
475 * @param base eLCDIF peripheral base address.
476 * @return The error virtual address.
477 */
ELCDIF_GetBusMasterErrorAddr(const LCDIF_Type * base)478 static inline uint32_t ELCDIF_GetBusMasterErrorAddr(const LCDIF_Type *base)
479 {
480 return base->BM_ERROR_STAT;
481 }
482
483 /*!
484 * @brief Get the eLCDIF status.
485 *
486 * The status flags are returned as a mask value, application could check the
487 * corresponding bit. Example:
488 *
489 * @code
490 uint32_t statusFlags;
491 statusFlags = ELCDIF_GetStatus(LCDIF);
492
493 if (kELCDIF_LFifoFull & statusFlags)
494 {
495 }
496
497 if (kELCDIF_TxFifoEmpty & statusFlags)
498 {
499 }
500 @endcode
501 *
502 * @param base eLCDIF peripheral base address.
503 * @return The mask value of status flags, it is OR'ed value of @ref _elcdif_status_flags.
504 */
ELCDIF_GetStatus(const LCDIF_Type * base)505 static inline uint32_t ELCDIF_GetStatus(const LCDIF_Type *base)
506 {
507 return base->STAT & (LCDIF_STAT_LFIFO_FULL_MASK | LCDIF_STAT_LFIFO_EMPTY_MASK | LCDIF_STAT_TXFIFO_FULL_MASK |
508 LCDIF_STAT_TXFIFO_EMPTY_MASK
509 #if defined(LCDIF_STAT_BUSY_MASK)
510 | LCDIF_STAT_BUSY_MASK
511 #endif
512 #if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
513 | LCDIF_STAT_DVI_CURRENT_FIELD_MASK
514 #endif
515 );
516 }
517
518 /*!
519 * @brief Get current count in Latency buffer (LFIFO).
520 *
521 * @param base eLCDIF peripheral base address.
522 * @return The LFIFO current count
523 */
ELCDIF_GetLFifoCount(const LCDIF_Type * base)524 static inline uint32_t ELCDIF_GetLFifoCount(const LCDIF_Type *base)
525 {
526 return (base->STAT & LCDIF_STAT_LFIFO_COUNT_MASK) >> LCDIF_STAT_LFIFO_COUNT_SHIFT;
527 }
528
529 /* @} */
530
531 /*!
532 * @name Interrupts
533 * @{
534 */
535
536 /*!
537 * @brief Enables eLCDIF interrupt requests.
538 *
539 * @param base eLCDIF peripheral base address.
540 * @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
541 */
ELCDIF_EnableInterrupts(LCDIF_Type * base,uint32_t mask)542 static inline void ELCDIF_EnableInterrupts(LCDIF_Type *base, uint32_t mask)
543 {
544 base->CTRL1_SET = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
545 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && (0 != FSL_FEATURE_LCDIF_HAS_NO_AS))
546 base->AS_CTRL |= (mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
547 #endif
548 }
549
550 /*!
551 * @brief Disables eLCDIF interrupt requests.
552 *
553 * @param base eLCDIF peripheral base address.
554 * @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
555 */
ELCDIF_DisableInterrupts(LCDIF_Type * base,uint32_t mask)556 static inline void ELCDIF_DisableInterrupts(LCDIF_Type *base, uint32_t mask)
557 {
558 base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
559 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && (0 != FSL_FEATURE_LCDIF_HAS_NO_AS))
560 base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
561 #endif
562 }
563
564 /*!
565 * @brief Get eLCDIF interrupt peding status.
566 *
567 * @param base eLCDIF peripheral base address.
568 * @return Interrupt pending status, OR'ed value of _elcdif_interrupt_flags.
569 */
ELCDIF_GetInterruptStatus(const LCDIF_Type * base)570 static inline uint32_t ELCDIF_GetInterruptStatus(const LCDIF_Type *base)
571 {
572 uint32_t flags;
573
574 flags = (base->CTRL1 & ELCDIF_CTRL1_IRQ_MASK);
575 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && (0 != FSL_FEATURE_LCDIF_HAS_NO_AS))
576 flags |= (base->AS_CTRL & ELCDIF_AS_CTRL_IRQ_MASK);
577 #endif
578
579 return flags;
580 }
581
582 /*!
583 * @brief Clear eLCDIF interrupt peding status.
584 *
585 * @param base eLCDIF peripheral base address.
586 * @param mask of the flags to clear, OR'ed value of _elcdif_interrupt_flags.
587 */
ELCDIF_ClearInterruptStatus(LCDIF_Type * base,uint32_t mask)588 static inline void ELCDIF_ClearInterruptStatus(LCDIF_Type *base, uint32_t mask)
589 {
590 base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_MASK);
591 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && (0 != FSL_FEATURE_LCDIF_HAS_NO_AS))
592 base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_MASK);
593 #endif
594 }
595
596 /* @} */
597
598 #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && (0 != FSL_FEATURE_LCDIF_HAS_NO_AS))
599 /*!
600 * @name Alpha surface
601 * @{
602 */
603
604 /*!
605 * @brief Set the configuration for alpha surface buffer.
606 *
607 * @param base eLCDIF peripheral base address.
608 * @param config Pointer to the configuration structure.
609 */
610 void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config);
611
612 /*!
613 * @brief Set the alpha surface blending configuration.
614 *
615 * @param base eLCDIF peripheral base address.
616 * @param config Pointer to the configuration structure.
617 */
618 void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config);
619
620 /*!
621 * @brief Set the next alpha surface buffer address.
622 *
623 * @param base eLCDIF peripheral base address.
624 * @param bufferAddr Alpha surface buffer address.
625 */
ELCDIF_SetNextAlphaSurfaceBufferAddr(LCDIF_Type * base,uint32_t bufferAddr)626 static inline void ELCDIF_SetNextAlphaSurfaceBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
627 {
628 base->AS_NEXT_BUF = ELCDIF_ADDR_CPU_2_IP(bufferAddr);
629 }
630
631 /*!
632 * @brief Set the overlay color key.
633 *
634 * If a pixel in the current overlay image with a color that falls in the range
635 * from the @p colorKeyLow to @p colorKeyHigh range, it will use the process surface
636 * pixel value for that location.
637 *
638 * @param base eLCDIF peripheral base address.
639 * @param colorKeyLow Color key low range.
640 * @param colorKeyHigh Color key high range.
641 *
642 * @note Colorkey operations are higher priority than alpha or ROP operations
643 */
ELCDIF_SetOverlayColorKey(LCDIF_Type * base,uint32_t colorKeyLow,uint32_t colorKeyHigh)644 static inline void ELCDIF_SetOverlayColorKey(LCDIF_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh)
645 {
646 base->AS_CLRKEYLOW = colorKeyLow;
647 base->AS_CLRKEYHIGH = colorKeyHigh;
648 }
649
650 /*!
651 * @brief Enable or disable the color key.
652 *
653 * @param base eLCDIF peripheral base address.
654 * @param enable True to enable, false to disable.
655 */
ELCDIF_EnableOverlayColorKey(LCDIF_Type * base,bool enable)656 static inline void ELCDIF_EnableOverlayColorKey(LCDIF_Type *base, bool enable)
657 {
658 if (enable)
659 {
660 base->AS_CTRL |= LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
661 }
662 else
663 {
664 base->AS_CTRL &= ~LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
665 }
666 }
667
668 /*!
669 * @brief Enable or disable the alpha surface.
670 *
671 * @param base eLCDIF peripheral base address.
672 * @param enable True to enable, false to disable.
673 */
ELCDIF_EnableAlphaSurface(LCDIF_Type * base,bool enable)674 static inline void ELCDIF_EnableAlphaSurface(LCDIF_Type *base, bool enable)
675 {
676 if (enable)
677 {
678 base->AS_CTRL |= LCDIF_AS_CTRL_AS_ENABLE_MASK;
679 }
680 else
681 {
682 base->AS_CTRL &= ~LCDIF_AS_CTRL_AS_ENABLE_MASK;
683 }
684 }
685
686 /*!
687 * @brief Enable or disable the process surface.
688 *
689 * Process surface is the normal frame buffer. The process surface content
690 * is controlled by ::ELCDIF_SetNextBufferAddr.
691 *
692 * @param base eLCDIF peripheral base address.
693 * @param enable True to enable, false to disable.
694 */
ELCDIF_EnableProcessSurface(LCDIF_Type * base,bool enable)695 static inline void ELCDIF_EnableProcessSurface(LCDIF_Type *base, bool enable)
696 {
697 if (enable)
698 {
699 base->AS_CTRL &= ~LCDIF_AS_CTRL_PS_DISABLE_MASK;
700 }
701 else
702 {
703 base->AS_CTRL |= LCDIF_AS_CTRL_PS_DISABLE_MASK;
704 }
705 }
706
707 /* @} */
708 #endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
709
710 #if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && (0 != FSL_FEATURE_LCDIF_HAS_LUT))
711 /*!
712 * @name LUT
713 *
714 * The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
715 * before output to external displayer.
716 *
717 * There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
718 * determins which memory to use.
719 *
720 * @{
721 */
722
723 /*!
724 * @brief Enable or disable the LUT.
725 *
726 * @param base eLCDIF peripheral base address.
727 * @param enable True to enable, false to disable.
728 */
ELCDIF_EnableLut(LCDIF_Type * base,bool enable)729 static inline void ELCDIF_EnableLut(LCDIF_Type *base, bool enable)
730 {
731 if (enable)
732 {
733 base->LUT_CTRL &= ~LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
734 }
735 else
736 {
737 base->LUT_CTRL |= LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
738 }
739 }
740
741 /*!
742 * @brief Load the LUT value.
743 *
744 * This function loads the LUT value to the specific LUT memory, user can
745 * specify the start entry index.
746 *
747 * @param base eLCDIF peripheral base address.
748 * @param lut Which LUT to load.
749 * @param startIndex The start index of the LUT entry to update.
750 * @param lutData The LUT data to load.
751 * @param count Count of @p lutData.
752 * @retval kStatus_Success Initialization success.
753 * @retval kStatus_InvalidArgument Wrong argument.
754 */
755 status_t ELCDIF_UpdateLut(
756 LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count);
757
758 /* @} */
759 #endif /* FSL_FEATURE_LCDIF_HAS_LUT */
760
761 #if defined(__cplusplus)
762 }
763 #endif /* __cplusplus */
764
765 /* @} */
766
767 #endif /*_FSL_ELCDIF_H_*/
768