diff --git a/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h b/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h new file mode 100644 index 00000000..2f7be489 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h @@ -0,0 +1,73 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +static const ltdcConfig driverCfg = { + 480, 270, // Width, Height (pixels) + 10, 2, // Horizontal, Vertical sync (pixels) + 20, 2, // Horizontal, Vertical back porch (pixels) + 10, 4, // Horizontal, Vertical front porch (pixels) + 0, // Sync flags + 0x000000, // Clear color (RGB888) + + { // Background layer config + (LLDCOLOR_TYPE *)SDRAM_BANK_ADDR, // Frame buffer address + 480, 270, // Width, Height (pixels) + 480 * LTDC_PIXELBYTES, // Line pitch (bytes) + LTDC_PIXELFORMAT, // Pixel format + 0, 0, // Start pixel position (x, y) + 480, 270, // Size of virtual layer (cx, cy) + LTDC_COLOR_FUCHSIA, // Default color (ARGB8888) + 0x980088, // Color key (RGB888) + LTDC_BLEND_FIX1_FIX2, // Blending factors + 0, // Palette (RGB888, can be NULL) + 0, // Palette length + 0xFF, // Constant alpha factor + LTDC_LEF_ENABLE // Layer configuration flags + }, + LTDC_UNUSED_LAYER_CONFIG // Foreground layer config +}; + +static inline void init_board(GDisplay *g) { + + // As we are not using multiple displays we set g->board to NULL as we don't use it. + g->board = 0; + + switch(g->controllerdisplay) { + case 0: // Set up for Display 0 + // Your init here + break; + } +} + +static inline void post_init_board(GDisplay* g) +{ +} + +static inline void set_backlight(GDisplay* g, uint8_t percent) +{ +} + +static inline void acquire_bus(GDisplay* g) +{ +} + +static inline void release_bus(GDisplay* g) +{ +} + +static inline void write_index(GDisplay* g, uint8_t index) +{ +} + +static inline void write_data(GDisplay* g, uint8_t data) +{ +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/gdisp/STM32F746Discovery/driver.mk b/drivers/gdisp/STM32F746Discovery/driver.mk new file mode 100644 index 00000000..720d5d1c --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/STM32F746Discovery +GFXSRC += $(GFXLIB)/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c diff --git a/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c b/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c new file mode 100644 index 00000000..7077f024 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c @@ -0,0 +1,425 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "gfx.h" + +#if GFX_USE_GDISP + +#if defined(GDISP_SCREEN_HEIGHT) + #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." + #undef GISP_SCREEN_HEIGHT +#endif +#if defined(GDISP_SCREEN_WIDTH) + #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." + #undef GDISP_SCREEN_WIDTH +#endif + +#define GDISP_DRIVER_VMT GDISPVMT_STM32F746Discovery +#include "drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" + +#include "stm32_ltdc.h" + +typedef struct ltdcLayerConfig { + // frame + LLDCOLOR_TYPE *frame; // Frame buffer address + coord_t width, height; // Frame size in pixels + coord_t pitch; // Line pitch, in bytes + uint16_t fmt; // Pixel format in LTDC format + + // window + coord_t x, y; // Start pixel position of the virtual layer + coord_t cx, cy; // Size of the virtual layer + + uint32_t defcolor; // Default color, ARGB8888 + uint32_t keycolor; // Color key, RGB888 + uint32_t blending; // Blending factors + const uint32_t *palette; // The palette, RGB888 (can be NULL) + uint16_t palettelen; // Palette length + uint8_t alpha; // Constant alpha factor + uint8_t layerflags; // Layer configuration +} ltdcLayerConfig; + +#define LTDC_UNUSED_LAYER_CONFIG { 0, 1, 1, 1, LTDC_FMT_L8, 0, 0, 1, 1, 0x000000, 0x000000, LTDC_BLEND_FIX1_FIX2, 0, 0, 0, 0 } + +typedef struct ltdcConfig { + coord_t width, height; // Screen size + coord_t hsync, vsync; // Horizontal and Vertical sync pixels + coord_t hbackporch, vbackporch; // Horizontal and Vertical back porch pixels + coord_t hfrontporch, vfrontporch; // Horizontal and Vertical front porch pixels + uint8_t syncflags; // Sync flags + uint32_t bgcolor; // Clear screen color RGB888 + + ltdcLayerConfig bglayer; // Background layer config + ltdcLayerConfig fglayer; // Foreground layer config +} ltdcConfig; + +#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565 + #define LTDC_PIXELFORMAT LTDC_FMT_RGB565 + #define LTDC_PIXELBYTES 2 + #define LTDC_PIXELBITS 16 +#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888 + #define LTDC_PIXELFORMAT LTDC_FMT_RGB888 + #define LTDC_PIXELBYTES 3 + #define LTDC_PIXELBITS 24 +#else + #error "GDISP: STM32F4iDiscovery - unsupported pixel format" +#endif + +#include "board_STM32F429iDiscovery.h" + +#include "ili9341.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 50 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +/*===========================================================================*/ +/* Driver local routines . */ +/*===========================================================================*/ + +#define PIXIL_POS(g, x, y) ((y) * driverCfg.bglayer.pitch + (x) * LTDC_PIXELBYTES) +#define PIXEL_ADDR(g, pos) ((LLDCOLOR_TYPE *)((uint8_t *)driverCfg.bglayer.frame+pos)) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +static void InitController(GDisplay *g) { + #define REG_TYPEMASK 0xFF00 + #define REG_DATAMASK 0x00FF + + #define REG_DATA 0x0000 + #define REG_COMMAND 0x0100 + #define REG_DELAY 0x0200 + + static const uint16_t initdata[] = { + REG_COMMAND | ILI9341_CMD_RESET, + REG_DELAY | 5, + REG_COMMAND | ILI9341_CMD_DISPLAY_OFF, + REG_COMMAND | ILI9341_SET_FRAME_CTL_NORMAL, 0x00, 0x1B, + REG_COMMAND | ILI9341_SET_FUNCTION_CTL, 0x0A, 0xA2, + REG_COMMAND | ILI9341_SET_POWER_CTL_1, 0x10, + REG_COMMAND | ILI9341_SET_POWER_CTL_2, 0x10, + #if 1 + REG_COMMAND | ILI9341_SET_VCOM_CTL_1, 0x45, 0x15, + REG_COMMAND | ILI9341_SET_VCOM_CTL_2, 0x90, + #else + REG_COMMAND | ILI9341_SET_VCOM_CTL_1, 0x35, 0x3E, + REG_COMMAND | ILI9341_SET_VCOM_CTL_2, 0xBE, + #endif + REG_COMMAND | ILI9341_SET_MEM_ACS_CTL, 0xC8, + REG_COMMAND | ILI9341_SET_RGB_IF_SIG_CTL, 0xC2, + REG_COMMAND | ILI9341_SET_FUNCTION_CTL, 0x0A, 0xA7, 0x27, 0x04, + REG_COMMAND | ILI9341_SET_COL_ADDR, 0x00, 0x00, 0x00, 0xEF, + REG_COMMAND | ILI9341_SET_PAGE_ADDR, 0x00, 0x00, 0x01, 0x3F, + REG_COMMAND | ILI9341_SET_IF_CTL, 0x01, 0x00, 0x06, + REG_COMMAND | ILI9341_SET_GAMMA, 0x01, + REG_COMMAND | ILI9341_SET_PGAMMA, + #if 1 + 0x0F, 0x29, 0x24, 0x0C, 0x0E, 0x09, 0x4E, 0x78, + 0x3C, 0x09, 0x13, 0x05, 0x17, 0x11, 0x00, + #else + 0x1F, 0x1a, 0x18, 0x0a, 0x0f, 0x06, 0x45, 0x87, + 0x32, 0x0a, 0x07, 0x02, 0x07, 0x05, 0x00, + #endif + REG_COMMAND | ILI9341_SET_NGAMMA, + #if 1 + 0x00, 0x16, 0x1B, 0x04, 0x11, 0x07, 0x31, 0x33, + 0x42, 0x05, 0x0C, 0x0A, 0x28, 0x2F, 0x0F, + #else + 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3a, 0x78, + 0x4d, 0x05, 0x18, 0x0d, 0x38, 0x3a, 0x1f, + #endif + REG_COMMAND | ILI9341_CMD_SLEEP_OFF, + REG_DELAY | 10, + REG_COMMAND | ILI9341_CMD_DISPLAY_ON, + REG_COMMAND | ILI9341_SET_MEM + }; + + const uint16_t *p; + + acquire_bus(g); + for(p = initdata; p < &initdata[sizeof(initdata)/sizeof(initdata[0])]; p++) { + switch(*p & REG_TYPEMASK) { + case REG_DATA: write_data(g, *p); break; + case REG_COMMAND: write_index(g, *p); break; + case REG_DELAY: gfxSleepMilliseconds(*p & 0xFF); break; + } + } + release_bus(g); +} + +static void LTDC_Reload(void) { + LTDC->SRCR |= LTDC_SRCR_IMR; + while (LTDC->SRCR & (LTDC_SRCR_IMR | LTDC_SRCR_VBR)) + gfxYield(); +} + +static void LTDC_LayerInit(LTDC_Layer_TypeDef *pLayReg, const ltdcLayerConfig * pCfg) { + static const uint8_t fmt2Bpp[] = { + 4, /* LTDC_FMT_ARGB8888 */ + 3, /* LTDC_FMT_RGB888 */ + 2, /* LTDC_FMT_RGB565 */ + 2, /* LTDC_FMT_ARGB1555 */ + 2, /* LTDC_FMT_ARGB4444 */ + 1, /* LTDC_FMT_L8 */ + 1, /* LTDC_FMT_AL44 */ + 2 /* LTDC_FMT_AL88 */ + }; + uint32_t start, stop; + + // Set the framebuffer dimensions and format + pLayReg->PFCR = (pLayReg->PFCR & ~LTDC_LxPFCR_PF) | ((uint32_t)pCfg->fmt & LTDC_LxPFCR_PF); + pLayReg->CFBAR = (uint32_t)pCfg->frame & LTDC_LxCFBAR_CFBADD; + pLayReg->CFBLR = ((((uint32_t)pCfg->pitch << 16) & LTDC_LxCFBLR_CFBP) | (((uint32_t)fmt2Bpp[pCfg->fmt] * pCfg->width + 3) & LTDC_LxCFBLR_CFBLL)); + pLayReg->CFBLNR = (uint32_t)pCfg->height & LTDC_LxCFBLNR_CFBLNBR; + + // Set the display window boundaries + start = (uint32_t)pCfg->x + driverCfg.hsync + driverCfg.hbackporch; + stop = start + pCfg->cx - 1; + pLayReg->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + start = (uint32_t)pCfg->y + driverCfg.vsync + driverCfg.vbackporch; + stop = start + pCfg->cy - 1; + pLayReg->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); + + // Set colors + pLayReg->DCCR = pCfg->defcolor; + pLayReg->CKCR = (pLayReg->CKCR & ~0x00FFFFFF) | (pCfg->keycolor & 0x00FFFFFF); + pLayReg->CACR = (pLayReg->CACR & ~LTDC_LxCACR_CONSTA) | ((uint32_t)pCfg->alpha & LTDC_LxCACR_CONSTA); + pLayReg->BFCR = (pLayReg->BFCR & ~(LTDC_LxBFCR_BF1 | LTDC_LxBFCR_BF2)) | ((uint32_t)pCfg->blending & (LTDC_LxBFCR_BF1 | LTDC_LxBFCR_BF2)); + for (start = 0; start < pCfg->palettelen; start++) + pLayReg->CLUTWR = ((uint32_t)start << 24) | (pCfg->palette[start] & 0x00FFFFFF); + + // Final flags + pLayReg->CR = (pLayReg->CR & ~LTDC_LEF_MASK) | ((uint32_t)pCfg->layerflags & LTDC_LEF_MASK); +} + +static void LTDC_Init(void) { + // Set up the display scanning + uint32_t hacc, vacc; + + /* Reset the LTDC hardware module.*/ + RCC->APB2RSTR |= RCC_APB2RSTR_LTDCRST; + RCC->APB2RSTR = 0; + + /* Enable the LTDC clock.*/ + RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | (1 << 16); /* /4 */ + + // Enable the module + RCC->APB2ENR |= RCC_APB2ENR_LTDCEN; + + // Turn off the controller and its interrupts. + LTDC->GCR = 0; + LTDC->IER = 0; + LTDC_Reload(); + + // Set synchronization params + hacc = driverCfg.hsync - 1; + vacc = driverCfg.vsync - 1; + LTDC->SSCR = ((hacc << 16) & LTDC_SSCR_HSW) | ((vacc << 0) & LTDC_SSCR_VSH); + + // Set accumulated back porch params + hacc += driverCfg.hbackporch; + vacc += driverCfg.vbackporch; + LTDC->BPCR = ((hacc << 16) & LTDC_BPCR_AHBP) | ((vacc << 0) & LTDC_BPCR_AVBP); + + // Set accumulated active params + hacc += driverCfg.width; + vacc += driverCfg.height; + LTDC->AWCR = ((hacc << 16) & LTDC_AWCR_AAW) | ((vacc << 0) & LTDC_AWCR_AAH); + + // Set accumulated total params + hacc += driverCfg.hfrontporch; + vacc += driverCfg.vfrontporch; + LTDC->TWCR = ((hacc << 16) & LTDC_TWCR_TOTALW) | ((vacc << 0) & LTDC_TWCR_TOTALH); + + // Set signal polarities and other flags + LTDC->GCR = driverCfg.syncflags & (LTDC_EF_MASK & ~LTDC_EF_ENABLE); + + // Set background color + LTDC->BCCR = (LTDC->BCCR & ~0x00FFFFFF) | (driverCfg.bgcolor & 0x00FFFFFF); + + // Load the background layer + LTDC_LayerInit(LTDC_Layer1, &driverCfg.bglayer); + + // Load the foreground layer + LTDC_LayerInit(LTDC_Layer2, &driverCfg.fglayer); + + // Interrupt handling + //nvicEnableVector(STM32_LTDC_EV_NUMBER, CORTEX_PRIORITY_MASK(STM32_LTDC_EV_IRQ_PRIORITY)); + //nvicEnableVector(STM32_LTDC_ER_NUMBER, CORTEX_PRIORITY_MASK(STM32_LTDC_ER_IRQ_PRIORITY)); + // Possible flags - LTDC_IER_RRIE, LTDC_IER_LIE, LTDC_IER_FUIE, LTDC_IER_TERRIE etc + LTDC->IER = 0; + + // Set everything going + LTDC_Reload(); + LTDC->GCR |= LTDC_GCR_LTDCEN; + LTDC_Reload(); +} + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + + // Initialize the private structure + g->priv = 0; + g->board = 0; + //if (!(g->priv = gfxAlloc(sizeof(fbPriv)))) + // gfxHalt("GDISP Framebuffer: Failed to allocate private memory"); + + // Init the board + init_board(g); + //((fbPriv *)g->priv)->fbi.cfg = init_board(g); + + // Initialise the ILI9341 controller + InitController(g); + + // Initialise the LTDC controller + LTDC_Init(); + + // Initialise DMA2D + //dma2dStart(&DMA2DD1, &dma2d_cfg); + //dma2d_test(); + + // Finish Init the board + post_init_board(g); + + /* Turn on the back-light */ + set_backlight(g, GDISP_INITIAL_BACKLIGHT); + + /* Initialise the GDISP structure */ + g->g.Width = driverCfg.bglayer.width; + g->g.Height = driverCfg.bglayer.height; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + return TRUE; +} + +LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + unsigned pos; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + PIXEL_ADDR(g, pos)[0] = gdispColor2Native(g->p.color); +} + +LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + unsigned pos; + LLDCOLOR_TYPE color; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + color = PIXEL_ADDR(g, pos)[0]; + return gdispNative2Color(color); +} + +#if GDISP_NEED_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay *g) { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: case powerOn: case powerSleep: case powerDeepSleep: + // TODO + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; + + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_BACKLIGHT: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + set_backlight(g, (unsigned)g->p.ptr); + g->g.Backlight = (unsigned)g->p.ptr; + return; + + case GDISP_CONTROL_CONTRAST: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + // TODO + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h b/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h new file mode 100644 index 00000000..29e016ce --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h @@ -0,0 +1,24 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/gdisp/STM32F746Discovery/readme.txt b/drivers/gdisp/STM32F746Discovery/readme.txt new file mode 100644 index 00000000..ab87e1d8 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/readme.txt @@ -0,0 +1,11 @@ +To use this driver: + +1. Add in your gfxconf.h: + a) #define GFX_USE_GDISP TRUE + +2. To your makefile add the following lines: + include $(GFXLIB)/gfx.mk + include $(GFXLIB)/drivers/gdisp/STM32F746Discovery/driver.mk + +3. Add a board_STM32F746Discovery.h to you project directory (or board directory) + base on one of the templates. diff --git a/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h b/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h new file mode 100644 index 00000000..429d8627 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h @@ -0,0 +1,138 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef STM32_LTDC_H +#define STM32_LTDC_H + +// LTDC enable flags +#define LTDC_EF_ENABLE (1 << 0) /**< LTDC enabled.*/ +#define LTDC_EF_DITHER (1 << 16) /**< Dithering enabled.*/ +#define LTDC_EF_PIXCLK_INVERT (1 << 28) /**< Inverted pixel clock.*/ +#define LTDC_EF_DATAEN_HIGH (1 << 29) /**< Active-high data enable.*/ +#define LTDC_EF_VSYNC_HIGH (1 << 30) /**< Active-high vsync.*/ +#define LTDC_EF_HSYNC_HIGH (1 << 31) /**< Active-high hsync.*/ + +#define LTDC_EF_MASK (LTDC_EF_ENABLE | LTDC_EF_DITHER | LTDC_EF_PIXCLK_INVERT | LTDC_EF_DATAEN_HIGH | LTDC_EF_VSYNC_HIGH | LTDC_EF_HSYNC_HIGH) + +// LTDC layer enable flags +#define LTDC_LEF_ENABLE (1 << 0) /**< Layer enabled*/ +#define LTDC_LEF_KEYING (1 << 1) /**< Color keying enabled.*/ +#define LTDC_LEF_PALETTE (1 << 4) /**< Palette enabled.*/ + +#define LTDC_LEF_MASK (LTDC_LEF_ENABLE | LTDC_LEF_KEYING | LTDC_LEF_PALETTE) + +// LTDC pixel formats +#define LTDC_FMT_ARGB8888 0 /**< ARGB-8888 format.*/ +#define LTDC_FMT_RGB888 1 /**< RGB-888 format.*/ +#define LTDC_FMT_RGB565 2 /**< RGB-565 format.*/ +#define LTDC_FMT_ARGB1555 3 /**< ARGB-1555 format.*/ +#define LTDC_FMT_ARGB4444 4 /**< ARGB-4444 format.*/ +#define LTDC_FMT_L8 5 /**< L-8 format.*/ +#define LTDC_FMT_AL44 6 /**< AL-44 format.*/ +#define LTDC_FMT_AL88 7 /**< AL-88 format.*/ + +// LTDC pixel format aliased raw masks +#define LTDC_XMASK_ARGB8888 0xFFFFFFFF /**< ARGB-8888 aliased mask.*/ +#define LTDC_XMASK_RGB888 0x00FFFFFF /**< RGB-888 aliased mask.*/ +#define LTDC_XMASK_RGB565 0x00F8FCF8 /**< RGB-565 aliased mask.*/ +#define LTDC_XMASK_ARGB1555 0x80F8F8F8 /**< ARGB-1555 aliased mask.*/ +#define LTDC_XMASK_ARGB4444 0xF0F0F0F0 /**< ARGB-4444 aliased mask.*/ +#define LTDC_XMASK_L8 0x000000FF /**< L-8 aliased mask.*/ +#define LTDC_XMASK_AL44 0xF00000F0 /**< AL-44 aliased mask.*/ +#define LTDC_XMASK_AL88 0xFF0000FF /**< AL-88 aliased mask.*/ + +// LTDC blending factors +#define LTDC_BLEND_FIX1_FIX2 0x0405 /**< cnst1; 1 - cnst2 */ +#define LTDC_BLEND_FIX1_MOD2 0x0407 /**< cnst1; 1 - a2 * cnst2 */ +#define LTDC_BLEND_MOD1_FIX2 0x0605 /**< a1 * cnst1; 1 - cnst2 */ +#define LTDC_BLEND_MOD1_MOD2 0x0607 /**< a1 * cnst1; 1 - a2 * cnst2 */ + +// LTDC parameter bounds +#define LTDC_MIN_SCREEN_WIDTH 1 +#define LTDC_MIN_SCREEN_HEIGHT 1 +#define LTDC_MAX_SCREEN_WIDTH 800 +#define LTDC_MAX_SCREEN_HEIGHT 600 + +#define LTDC_MIN_HSYNC_WIDTH 1 +#define LTDC_MIN_VSYNC_HEIGHT 1 +#define LTDC_MAX_HSYNC_WIDTH (1 << 12) +#define LTDC_MAX_VSYNC_HEIGHT (1 << 11) + +#define LTDC_MIN_HBP_WIDTH 0 +#define LTDC_MIN_VBP_HEIGHT 0 +#define LTDC_MAX_HBP_WIDTH (1 << 12) +#define LTDC_MAX_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_HBP_WIDTH 1 +#define LTDC_MIN_ACC_VBP_HEIGHT 1 +#define LTDC_MAX_ACC_HBP_WIDTH (1 << 12) +#define LTDC_MAX_ACC_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_HFP_WIDTH 0 +#define LTDC_MIN_VFP_HEIGHT 0 +#define LTDC_MAX_HFP_WIDTH (1 << 12) +#define LTDC_MAX_VFP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACTIVE_WIDTH 0 +#define LTDC_MIN_ACTIVE_HEIGHT 0 +#define LTDC_MAX_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_ACTIVE_WIDTH 1 +#define LTDC_MIN_ACC_ACTIVE_HEIGHT 1 +#define LTDC_MAX_ACC_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACC_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_TOTAL_WIDTH 1 +#define LTDC_MIN_ACC_TOTAL_HEIGHT 1 +#define LTDC_MAX_ACC_TOTAL_WIDTH (1 << 12) +#define LTDC_MAX_ACC_TOTAL_HEIGHT (1 << 11) + +#define LTDC_MIN_LINE_INTERRUPT_POS 0 +#define LTDC_MAX_LINE_INTERRUPT_POS ((1 << 11) - 1) + +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) + +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) + +#define LTDC_MIN_FRAME_WIDTH_BYTES 0 +#define LTDC_MIN_FRAME_HEIGHT_LINES 0 +#define LTDC_MIN_FRAME_PITCH_BYTES 0 +#define LTDC_MAX_FRAME_WIDTH_BYTES ((1 << 13) - 1 - 3) +#define LTDC_MAX_FRAME_HEIGHT_LINES ((1 << 11) - 1) +#define LTDC_MAX_FRAME_PITCH_BYTES ((1 << 13) - 1) + +#define LTDC_MIN_PIXFMT_ID 0 +#define LTDC_MAX_PIXFMT_ID 7 + +#define LTDC_MAX_PALETTE_LENGTH 256 + +// LTDC basic ARGB-8888 colors. +#define LTDC_COLOR_BLACK 0xFF000000 +#define LTDC_COLOR_MAROON 0xFF800000 +#define LTDC_COLOR_GREEN 0xFF008000 +#define LTDC_COLOR_OLIVE 0xFF808000 +#define LTDC_COLOR_NAVY 0xFF000080 +#define LTDC_COLOR_PURPLE 0xFF800080 +#define LTDC_COLOR_TEAL 0xFF008080 +#define LTDC_COLOR_SILVER 0xFFC0C0C0 +#define LTDC_COLOR_GRAY 0xFF808080 +#define LTDC_COLOR_RED 0xFFFF0000 +#define LTDC_COLOR_LIME 0xFF00FF00 +#define LTDC_COLOR_YELLOW 0xFFFFFF00 +#define LTDC_COLOR_BLUE 0xFF0000FF +#define LTDC_COLOR_FUCHSIA 0xFFFF00FF +#define LTDC_COLOR_AQUA 0xFF00FFFF +#define LTDC_COLOR_WHITE 0xFFFFFFFF + +#endif /* STM32_LTDC_H */