aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@seriouslyembedded.com>2015-07-08 02:41:20 +0200
committerJoel Bodenmann <joel@seriouslyembedded.com>2015-07-08 02:41:20 +0200
commit49f32f5ce7e88877abc66b091e5d00e32681a150 (patch)
treed4bd52bfaeebc95cd546cc2cc89bb09f0e8764e1
parent2f6aaa9586297d287c5c721660795db1191f47f3 (diff)
downloaduGFX-49f32f5ce7e88877abc66b091e5d00e32681a150.tar.gz
uGFX-49f32f5ce7e88877abc66b091e5d00e32681a150.tar.bz2
uGFX-49f32f5ce7e88877abc66b091e5d00e32681a150.zip
Starting STM32F7 Discovery driver development
-rw-r--r--drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h73
-rw-r--r--drivers/gdisp/STM32F746Discovery/driver.mk2
-rw-r--r--drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c425
-rw-r--r--drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h24
-rw-r--r--drivers/gdisp/STM32F746Discovery/readme.txt11
-rw-r--r--drivers/gdisp/STM32F746Discovery/stm32_ltdc.h138
6 files changed, 673 insertions, 0 deletions
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 */