The MCUXpresso SDK provides a Peripheral driver for the LCD controller (LCD) of MCUXpresso SDK devices.
The LCD driver supports TFT and STN panel. It also supports hardware cursor, which makes software easy.
Typical use case
Update framebuffer dynamically
The function LCDC_SetPanelAddr is used to set the new framebuffer address. After this function, the new framebuffer address is not loaded to current register until the vertical synchroization. When the address is loaded, the interrupt kLCDC_BaseAddrUpdateInterrupt occurs then upper layer could set the new framebuffer. In this example, there are two buffers. When the active buffer is displayed, upper layer could modify the inactive buffer.
#if (defined(__CC_ARM) || defined(__GNUC__))
__attribute__((aligned(8)))
#elif defined(__ICCARM__)
#pragma data_alignment = 8
#else
#error Toolchain not support.
#endif
static uint16_t s_frameBufs[2][IMG_HEIGHT][IMG_WIDTH];
static volatile uint8_t s_inactiveBufsIdx;
static volatile bool s_frameAddrUpdated = false;
void LCD_IRQHandler(void)
{
{
s_frameAddrUpdated = true;
}
}
static void APP_FillBuffer(void *buffer);
int main(void)
{
BOARD_InitHardware();
s_frameAddrUpdated = false;
s_inactiveBufsIdx = 1;
APP_FillBuffer((void *)(s_frameBufs[0]));
LCDC_Init(LCD, &lcdConfig, LCD_INPUT_CLK_FREQ);
NVIC_EnableIRQ(LCD_IRQn);
while (1)
{
APP_FillBuffer((void *)s_frameBufs[s_inactiveBufsIdx]);
while (!s_frameAddrUpdated)
{
}
s_frameAddrUpdated = false;
s_inactiveBufsIdx ^= 1U;
}
}
Hardware cursor
This example shows how to show a 32x32 pixel cursor and change its position.
int32_t cursorPosX = 0;
int32_t cursorPosY = 0;
cursorConfig.
image[0] = (uint32_t *)cursor32Img0;
while (1)
{
}
|
enum | _lcdc_polarity_flags {
kLCDC_InvertVsyncPolarity = LCD_POL_IVS_MASK,
kLCDC_InvertHsyncPolarity = LCD_POL_IHS_MASK,
kLCDC_InvertClkPolarity = LCD_POL_IPC_MASK,
kLCDC_InvertDePolarity = LCD_POL_IOE_MASK
} |
| LCD sigal polarity flags. More...
|
|
enum | lcdc_bpp_t {
kLCDC_1BPP = 0U,
kLCDC_2BPP = 1U,
kLCDC_4BPP = 2U,
kLCDC_8BPP = 3U,
kLCDC_16BPP = 4U,
kLCDC_24BPP = 5U,
kLCDC_16BPP565 = 6U,
kLCDC_12BPP = 7U
} |
| LCD bits per pixel. More...
|
|
enum | lcdc_display_t {
kLCDC_DisplayTFT = LCD_CTRL_LCDTFT_MASK,
kLCDC_DisplaySingleMonoSTN4Bit = LCD_CTRL_LCDBW_MASK,
kLCDC_DisplaySingleMonoSTN8Bit,
kLCDC_DisplayDualMonoSTN4Bit,
kLCDC_DisplayDualMonoSTN8Bit,
kLCDC_DisplaySingleColorSTN8Bit = 0U,
kLCDC_DisplayDualColorSTN8Bit = LCD_CTRL_LCDDUAL_MASK
} |
| The types of display panel. More...
|
|
enum | lcdc_data_format_t {
kLCDC_LittleEndian = 0U,
kLCDC_BigEndian = LCD_CTRL_BEPO_MASK | LCD_CTRL_BEBO_MASK,
kLCDC_WinCeMode = LCD_CTRL_BEPO_MASK
} |
| LCD panel buffer data format. More...
|
|
enum | lcdc_vertical_compare_interrupt_mode_t {
kLCDC_StartOfVsync,
kLCDC_StartOfBackPorch,
kLCDC_StartOfActiveVideo,
kLCDC_StartOfFrontPorch
} |
| LCD vertical compare interrupt mode. More...
|
|
enum | _lcdc_interrupts {
kLCDC_CursorInterrupt = LCD_CRSR_INTMSK_CRSRIM_MASK,
kLCDC_FifoUnderflowInterrupt = LCD_INTMSK_FUFIM_MASK,
kLCDC_BaseAddrUpdateInterrupt = LCD_INTMSK_LNBUIM_MASK,
kLCDC_VerticalCompareInterrupt = LCD_INTMSK_VCOMPIM_MASK,
kLCDC_AhbErrorInterrupt = LCD_INTMSK_BERIM_MASK
} |
| LCD interrupts. More...
|
|
enum | lcdc_panel_t {
kLCDC_UpperPanel,
kLCDC_LowerPanel
} |
| LCD panel frame. More...
|
|
enum | lcdc_cursor_size_t {
kLCDC_CursorSize32,
kLCDC_CursorSize64
} |
| LCD hardware cursor size. More...
|
|
enum | lcdc_cursor_sync_mode_t {
kLCDC_CursorAsync,
kLCDC_CursorSync
} |
| LCD hardware cursor frame synchronization mode. More...
|
|
struct lcdc_cursor_palette_t |
struct lcdc_cursor_config_t |
#define LCDC_CURSOR_COUNT 4 |
#define LCDC_CURSOR_IMG_BPP 2 |
#define LCDC_PALETTE_SIZE_WORDS (ARRAY_SIZE(((LCD_Type *)0)->PAL)) |
Enumerator |
---|
kLCDC_InvertVsyncPolarity |
Invert the VSYNC polarity, set to active low.
|
kLCDC_InvertHsyncPolarity |
Invert the HSYNC polarity, set to active low.
|
kLCDC_InvertClkPolarity |
Invert the panel clock polarity, set to drive data on falling edge.
|
kLCDC_InvertDePolarity |
Invert the data enable (DE) polarity, set to active low.
|
Enumerator |
---|
kLCDC_1BPP |
1 bpp.
|
kLCDC_2BPP |
2 bpp.
|
kLCDC_4BPP |
4 bpp.
|
kLCDC_8BPP |
8 bpp.
|
kLCDC_16BPP |
16 bpp.
|
kLCDC_24BPP |
24 bpp, TFT panel only.
|
kLCDC_16BPP565 |
16 bpp, 5:6:5 mode.
|
kLCDC_12BPP |
12 bpp, 4:4:4 mode.
|
Enumerator |
---|
kLCDC_DisplayTFT |
Active matrix TFT panels with up to 24-bit bus interface.
|
kLCDC_DisplaySingleMonoSTN4Bit |
Single-panel monochrome STN (4-bit bus interface).
|
kLCDC_DisplaySingleMonoSTN8Bit |
Single-panel monochrome STN (8-bit bus interface).
|
kLCDC_DisplayDualMonoSTN4Bit |
Dual-panel monochrome STN (4-bit bus interface).
|
kLCDC_DisplayDualMonoSTN8Bit |
Dual-panel monochrome STN (8-bit bus interface).
|
kLCDC_DisplaySingleColorSTN8Bit |
Single-panel color STN (8-bit bus interface).
|
kLCDC_DisplayDualColorSTN8Bit |
Dual-panel coor STN (8-bit bus interface).
|
Enumerator |
---|
kLCDC_LittleEndian |
Little endian byte, little endian pixel.
|
kLCDC_BigEndian |
Big endian byte, big endian pixel.
|
kLCDC_WinCeMode |
little-endian byte, big-endian pixel for Windows CE mode.
|
Enumerator |
---|
kLCDC_StartOfVsync |
Generate vertical compare interrupt at start of VSYNC.
|
kLCDC_StartOfBackPorch |
Generate vertical compare interrupt at start of back porch.
|
kLCDC_StartOfActiveVideo |
Generate vertical compare interrupt at start of active video.
|
kLCDC_StartOfFrontPorch |
Generate vertical compare interrupt at start of front porch.
|
Enumerator |
---|
kLCDC_CursorInterrupt |
Cursor image read finished interrupt.
|
kLCDC_FifoUnderflowInterrupt |
FIFO underflow interrupt.
|
kLCDC_BaseAddrUpdateInterrupt |
Panel frame base address update interrupt.
|
kLCDC_VerticalCompareInterrupt |
Vertical compare interrupt.
|
kLCDC_AhbErrorInterrupt |
AHB master error interrupt.
|
Enumerator |
---|
kLCDC_UpperPanel |
Upper panel frame.
|
kLCDC_LowerPanel |
Lower panel frame.
|
Enumerator |
---|
kLCDC_CursorSize32 |
32x32 pixel cursor.
|
kLCDC_CursorSize64 |
64x64 pixel cursor.
|
Enumerator |
---|
kLCDC_CursorAsync |
Cursor change will be displayed immediately.
|
kLCDC_CursorSync |
Cursor change will be displayed in next frame.
|
- Parameters
-
base | LCD peripheral base address. |
config | Pointer to configuration structure, see to lcdc_config_t. |
srcClock_Hz | The LCD input clock (LCDCLK) frequency in Hz. |
- Return values
-
kStatus_Success | LCD is initialized successfully. |
kStatus_InvalidArgument | Initlialize failed because of invalid argument. |
void LCDC_Deinit |
( |
LCD_Type * |
base | ) |
|
- Parameters
-
base | LCD peripheral base address. |
This function initializes the configuration structure. The default values are:
config->panelClock_Hz = 0U;
config->ppl = 0U;
config->hsw = 0U;
config->hfp = 0U;
config->hbp = 0U;
config->lpp = 0U;
config->vsw = 0U;
config->vfp = 0U;
config->vbp = 0U;
config->acBiasFreq = 1U;
config->polarityFlags = 0U;
config->enableLineEnd = false;
config->lineEndDelay = 0U;
config->upperPanelAddr = 0U;
config->lowerPanelAddr = 0U;
config->swapRedBlue = false;
- Parameters
-
config | Pointer to configuration structure. |
static void LCDC_Start |
( |
LCD_Type * |
base | ) |
|
|
inlinestatic |
The LCD power up sequence should be:
- Apply power to LCD, here all output signals are held low.
- When LCD power stablized, call LCDC_Start to output the timing signals.
- Apply contrast voltage to LCD panel. Delay if the display requires.
- Call LCDC_PowerUp.
- Parameters
-
base | LCD peripheral base address. |
static void LCDC_Stop |
( |
LCD_Type * |
base | ) |
|
|
inlinestatic |
The LCD power down sequence should be:
- Call LCDC_PowerDown.
- Delay if the display requires. Disable contrast voltage to LCD panel.
- Call LCDC_Stop to disable the timing signals.
- Disable power to LCD.
- Parameters
-
base | LCD peripheral base address. |
static void LCDC_PowerUp |
( |
LCD_Type * |
base | ) |
|
|
inlinestatic |
- Parameters
-
base | LCD peripheral base address. |
static void LCDC_PowerDown |
( |
LCD_Type * |
base | ) |
|
|
inlinestatic |
- Parameters
-
base | LCD peripheral base address. |
void LCDC_SetPanelAddr |
( |
LCD_Type * |
base, |
|
|
lcdc_panel_t |
panel, |
|
|
uint32_t |
addr |
|
) |
| |
- Parameters
-
base | LCD peripheral base address. |
panel | Which panel to set. |
addr | Frame base address, must be doubleword(64-bit) aligned. |
void LCDC_SetPalette |
( |
LCD_Type * |
base, |
|
|
const uint32_t * |
palette, |
|
|
uint8_t |
count_words |
|
) |
| |
- Parameters
-
base | LCD peripheral base address. |
palette | Pointer to the palette array. |
count_words | Length of the palette array to set (how many words), it should not be larger than LCDC_PALETTE_SIZE_WORDS. |
- Parameters
-
base | LCD peripheral base address. |
mode | The vertical compare interrupt mode. |
void LCDC_EnableInterrupts |
( |
LCD_Type * |
base, |
|
|
uint32_t |
mask |
|
) |
| |
Example to enable LCD base address update interrupt and vertical compare interrupt:
- Parameters
-
base | LCD peripheral base address. |
mask | Interrupts to enable, it is OR'ed value of _lcdc_interrupts. |
void LCDC_DisableInterrupts |
( |
LCD_Type * |
base, |
|
|
uint32_t |
mask |
|
) |
| |
Example to disable LCD base address update interrupt and vertical compare interrupt:
- Parameters
-
base | LCD peripheral base address. |
mask | Interrupts to disable, it is OR'ed value of _lcdc_interrupts. |
uint32_t LCDC_GetInterruptsPendingStatus |
( |
LCD_Type * |
base | ) |
|
Example:
- Parameters
-
base | LCD peripheral base address. |
- Returns
- Interrupts pending status, it is OR'ed value of _lcdc_interrupts.
uint32_t LCDC_GetEnabledInterruptsPendingStatus |
( |
LCD_Type * |
base | ) |
|
void LCDC_ClearInterruptsStatus |
( |
LCD_Type * |
base, |
|
|
uint32_t |
mask |
|
) |
| |
Example to clear LCD base address update interrupt and vertical compare interrupt pending status:
- Parameters
-
base | LCD peripheral base address. |
mask | Interrupts to disable, it is OR'ed value of _lcdc_interrupts. |
This function should be called before enabling the hardware cursor. It supports initializing multiple cursor images at a time when using 32x32 pixels cursor.
For example:
cursorConfig.
image[0] = cursor0Img;
cursorConfig.
image[2] = cursor2Img;
In this example, cursor 0 and cursor 2 image data are initialized, but cursor 1 and cursor 3 image data are not initialized because image[1] and image[2] are all NULL. With this, application could initializes all cursor images it will use at the beginning and call LCDC_SetCursorImage directly to display the one which it needs.
- Parameters
-
base | LCD peripheral base address. |
config | Pointer to the hardware cursor configuration structure. |
The default configuration values are:
config->palette0.red = 0U;
config->palette0.green = 0U;
config->palette0.blue = 0U;
config->palette1.red = 255U;
config->palette1.green = 255U;
config->palette1.blue = 255U;
config->image[0] = (uint32_t *)0;
config->image[1] = (uint32_t *)0;
config->image[2] = (uint32_t *)0;
config->image[3] = (uint32_t *)0;
- Parameters
-
config | Pointer to the hardware cursor configuration structure. |
static void LCDC_EnableCursor |
( |
LCD_Type * |
base, |
|
|
bool |
enable |
|
) |
| |
|
inlinestatic |
- Parameters
-
base | LCD peripheral base address. |
enable | True to enable, false to disable. |
static void LCDC_ChooseCursor |
( |
LCD_Type * |
base, |
|
|
uint8_t |
index |
|
) |
| |
|
inlinestatic |
When using 32x32 cursor, the number of cursors supports is LCDC_CURSOR_COUNT. When using 64x64 cursor, the LCD only supports one cursor. This function selects which cursor to display when using 32x32 cursor. When synchronization mode is kLCDC_CursorSync, the change effects in the next frame. When synchronization mode is * kLCDC_CursorAsync, change effects immediately.
- Parameters
-
base | LCD peripheral base address. |
index | Index of the cursor to display. |
- Note
- The function LCDC_SetCursorPosition must be called after this function to show the new cursor.
void LCDC_SetCursorPosition |
( |
LCD_Type * |
base, |
|
|
int32_t |
positionX, |
|
|
int32_t |
positionY |
|
) |
| |
When synchronization mode is kLCDC_CursorSync, position change effects in the next frame. When synchronization mode is kLCDC_CursorAsync, position change effects immediately.
- Parameters
-
base | LCD peripheral base address. |
positionX | X ordinate of the cursor top-left measured in pixels |
positionY | Y ordinate of the cursor top-left measured in pixels |
void LCDC_SetCursorImage |
( |
LCD_Type * |
base, |
|
|
lcdc_cursor_size_t |
size, |
|
|
uint8_t |
index, |
|
|
const uint32_t * |
image |
|
) |
| |
The interrupt kLCDC_CursorInterrupt indicates that last cursor pixel is displayed. When the hardware cursor is enabled,
- Parameters
-
base | LCD peripheral base address. |
size | The cursor size. |
index | Index of the cursor to set when using 32x32 cursor. |
image | Pointer to the cursor image. When using 32x32 cursor, the image size should be LCDC_CURSOR_IMG_32X32_WORDS. When using 64x64 cursor, the image size should be LCDC_CURSOR_IMG_64X64_WORDS. |
uint32_t lcdc_config_t::panelClock_Hz |
uint16_t lcdc_config_t::ppl |
uint8_t lcdc_config_t::hsw |
uint8_t lcdc_config_t::hfp |
uint8_t lcdc_config_t::hbp |
uint16_t lcdc_config_t::lpp |
uint8_t lcdc_config_t::vsw |
uint8_t lcdc_config_t::vfp |
uint8_t lcdc_config_t::vbp |
uint8_t lcdc_config_t::acBiasFreq |
Only used for STN display.
uint16_t lcdc_config_t::polarityFlags |
bool lcdc_config_t::enableLineEnd |
uint8_t lcdc_config_t::lineEndDelay |
uint32_t lcdc_config_t::upperPanelAddr |
uint32_t lcdc_config_t::lowerPanelAddr |
bool lcdc_config_t::swapRedBlue |
uint8_t lcdc_cursor_palette_t::red |
uint8_t lcdc_cursor_palette_t::green |
uint8_t lcdc_cursor_palette_t::blue |