Change STM32F429i-Discovery board to use the general STM32LTDC driver.

The special ILI9341 init code is now in the board file (it is board specific).
The specific STM32F429i-Discovery driver is now gone
ugfx_release_2.6
inmarket 2015-11-25 12:24:22 +10:00
parent 6900dfc0ab
commit 205160aec0
12 changed files with 102 additions and 831 deletions

View File

@ -3,5 +3,5 @@ GFXSRC += $(GFXLIB)/boards/base/STM32F429i-Discovery/stm32f429i_discovery_sdram
$(GFXLIB)/boards/base/STM32F429i-Discovery/stm32f4xx_fmc.c
GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
include $(GFXLIB)/drivers/gdisp/STM32F429iDiscovery/driver.mk
include $(GFXLIB)/drivers/gdisp/STM32LTDC/driver.mk
include $(GFXLIB)/drivers/ginput/touch/STMPE811/driver.mk

View File

@ -48,7 +48,104 @@ static const ltdcConfig driverCfg = {
LTDC_UNUSED_LAYER_CONFIG
};
static GFXINLINE void init_board(GDisplay *g) {
#include "ili9341.h"
static void acquire_bus(GDisplay *g) {
(void) g;
spiSelect(SPI_PORT);
}
static void release_bus(GDisplay *g) {
(void) g;
spiUnselect(SPI_PORT);
}
static void write_index(GDisplay *g, uint8_t index) {
static uint8_t sindex;
(void) g;
palClearPad(DC_PORT, DC_PIN);
sindex = index;
spiSend(SPI_PORT, 1, &sindex);
}
static void write_data(GDisplay *g, uint8_t data) {
static uint8_t sdata;
(void) g;
palSetPad(DC_PORT, DC_PIN);
sdata = data;
spiSend(SPI_PORT, 1, &sdata);
}
static void Init9341(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 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;
@ -84,6 +181,8 @@ static GFXINLINE void init_board(GDisplay *g) {
memset((void *)SDRAM_BANK_ADDR, 0, 0x400000);
spiStart(SPI_PORT, &spi_cfg);
Init9341(g);
break;
}
}
@ -97,34 +196,4 @@ static GFXINLINE void set_backlight(GDisplay *g, uint8_t percent) {
(void) percent;
}
static GFXINLINE void acquire_bus(GDisplay *g) {
(void) g;
spiSelect(SPI_PORT);
}
static GFXINLINE void release_bus(GDisplay *g) {
(void) g;
spiUnselect(SPI_PORT);
}
static GFXINLINE void write_index(GDisplay *g, uint8_t index) {
static uint8_t sindex;
(void) g;
palClearPad(DC_PORT, DC_PIN);
sindex = index;
spiSend(SPI_PORT, 1, &sindex);
}
static GFXINLINE void write_data(GDisplay *g, uint8_t data) {
static uint8_t sdata;
(void) g;
palSetPad(DC_PORT, DC_PIN);
sdata = data;
spiSend(SPI_PORT, 1, &sdata);
}
#endif /* _GDISP_LLD_BOARD_H */

View File

@ -15,7 +15,7 @@ ifeq ($(OPT_OS),raw32)
$(GFXLIB)/boards/base/STM32F746-Discovery/stm32f746g_raw32_ugfx.c \
$(GFXLIB)/boards/base/STM32F746-Discovery/stm32f746g_raw32_system.c \
$(GFXLIB)/boards/base/STM32F746-Discovery/stm32f746g_raw32_interrupts.c
GFXDEFS += GFX_OS_EXTRA_INIT_FUNCTION=Raw32OSInit GFX_OS_INIT_NO_WARNING=TRUE
GFXDEFS += GFX_OS_PRE_INIT_FUNCTION=Raw32OSInit GFX_OS_INIT_NO_WARNING=TRUE
GFXINC += $(CMSIS)/Device/ST/STM32F7xx/Include \
$(CMSIS)/Include \
$(STMHAL)/Inc

View File

@ -16,7 +16,6 @@
#endif
static void SystemClock_Config(void);
static void CPU_CACHE_Enable(void);
void Raw32OSInit(void) {
/* Enable the CPU Cache's */

View File

@ -1,66 +0,0 @@
/*
* 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 = {
240, 320,
10, 2,
20, 2,
10, 4,
0,
0x000000,
{
(LLDCOLOR_TYPE *)SDRAM_BANK_ADDR, // frame
240, 320, // width, height
240 * LTDC_PIXELBYTES, // pitch
LTDC_PIXELFORMAT, // fmt
0, 0, // x, y
240, 320, // cx, cy
LTDC_COLOR_FUCHSIA, // defcolor
0x980088, // keycolor
LTDC_BLEND_FIX1_FIX2, // blending
0, // palette
0, // palettelen
0xFF, // alpha
LTDC_LEF_ENABLE // flags
},
LTDC_UNUSED_LAYER_CONFIG
};
static GFXINLINE 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 GFXINLINE void post_init_board(GDisplay *g) {
}
static GFXINLINE void set_backlight(GDisplay *g, uint8_t percent) {
}
static GFXINLINE void acquire_bus(GDisplay *g) {
}
static GFXINLINE void release_bus(GDisplay *g) {
}
static GFXINLINE void write_index(GDisplay *g, uint8_t index) {
}
static GFXINLINE void write_data(GDisplay *g, uint8_t data) {
}
#endif /* _GDISP_LLD_BOARD_H */

View File

@ -1,2 +0,0 @@
GFXINC += $(GFXLIB)/drivers/gdisp/STM32F429iDiscovery
GFXSRC += $(GFXLIB)/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_STM32F429iDiscovery.c

View File

@ -1,520 +0,0 @@
/*
* 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
#ifndef LTDC_USE_DMA2D
#define LTDC_USE_DMA2D FALSE
#endif
#define GDISP_DRIVER_VMT GDISPVMT_STM32F429iDiscovery
#include "gdisp_lld_config.h"
#include "../../../src/gdisp/gdisp_driver.h"
#include "stm32_ltdc.h"
#if LTDC_USE_DMA2D
#include "stm32_dma2d.h"
#endif
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
#if LTDC_USE_DMA2D
dma2d_init();
#endif
// 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
#if LTDC_USE_DMA2D
static void dma2d_init(void)
{
// Enable DMA2D clock (DMA2DEN = 1)
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN;
// Output color format
#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565
DMA2D->OPFCCR = OPFCCR_RGB565;
#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888
DMA2D->OPFCCR = OPFCCR_OPFCCR_RGB888;
#endif
// Foreground color format
#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565
DMA2D->FGPFCCR = FGPFCCR_CM_RGB565;
#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888
DMA2D->FGPFCCR = FGPFCCR_CM_RGB888;
#endif
}
// Uses p.x,p.y p.cx,p.cy p.color
LLDSPEC void gdisp_lld_fill_area(GDisplay* g)
{
LLDCOLOR_TYPE c;
// Wait until DMA2D is ready
while (1) {
if (!(DMA2D->CR & DMA2D_CR_START)) {
break;
}
}
c = gdispColor2Native(g->p.color);
// Output color register
DMA2D->OCOLR = (uint32_t)c;
// Output memory address register
DMA2D->OMAR = g->p.y * g->g.Width * LTDC_PIXELBYTES + g->p.x * LTDC_PIXELBYTES + (uint32_t)driverCfg.bglayer.frame;
// Output offset register (in pixels)
DMA2D->OOR = g->g.Width - g->p.cx;
// PL (pixel per lines to be transferred); NL (number of lines)
DMA2D->NLR = (g->p.cx << 16) | (g->p.cy);
// Set MODE to R2M and Start the process
DMA2D->CR = DMA2D_CR_MODE_R2M | DMA2D_CR_START;
}
// Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
LLDSPEC void gdisp_lld_blit_area(GDisplay* g)
{
// Wait until DMA2D is ready
while (1) {
if (!(DMA2D->CR & DMA2D_CR_START)) {
break;
}
}
// Foreground memory address register
DMA2D->FGMAR = g->p.y1 * g->p.x2 * LTDC_PIXELBYTES + g->p.x1 * LTDC_PIXELBYTES + (uint32_t)g->p.ptr;
// Foreground offset register (expressed in pixels)
DMA2D->FGOR = g->p.x2 - g->p.cx;
// Output memory address register
DMA2D->OMAR = g->p.y * g->g.Width * LTDC_PIXELBYTES + g->p.x * LTDC_PIXELBYTES + (uint32_t)driverCfg.bglayer.frame;
// Output offset register (expressed in pixels)
DMA2D->OOR = g->g.Width - g->p.cx;
// PL (pixel per lines to be transferred); NL (number of lines)
DMA2D->NLR = (g->p.cx << 16) | (g->p.cy);
// Set MODE to M2M and Start the process
DMA2D->CR = DMA2D_CR_MODE_M2M | DMA2D_CR_START;
}
#endif /* LTDC_USE_DMA2D */
#endif /* GFX_USE_GDISP */

View File

@ -1,38 +0,0 @@
/*
* 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 LTDC_USE_DMA2D TRUE
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
/*===========================================================================*/
/* Don't change stuff below this line. Please. */
/*===========================================================================*/
#if LTDC_USE_DMA2D
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#else
#define GDISP_HARDWARE_FILLS FALSE
#define GDISP_HARDWARE_BITFILLS FALSE
#endif /* GDISP_USE_DMA2D */
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */

View File

@ -1,11 +0,0 @@
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/STM32F429iDiscovery/driver.mk
3. Add a board_STM32F429iDiscovery.h to you project directory (or board directory)
base on one of the templates.

View File

@ -1,18 +0,0 @@
#ifndef _STM32_DMA2D_H
#define _STM32_DMA2D_H
#define OPFCCR_ARGB8888 0x00
#define OPFCCR_RGB888 0x01
#define OPFCCR_RGB565 0x02
#define OPFCCR_ARGB1555 0x03
#define OPFCCR_ARGB4444 0x04
#define FGPFCCR_CM_RGB888 0x01
#define FGPFCCR_CM_RGB565 0x02
#define DMA2D_CR_MODE_R2M ((uint32_t)0x00030000) /* Register-to-memory mode */
#define DMA2D_CR_MODE_M2M ((uint32_t)0x00000000) /* Register-to-memory mode */
static void dma2d_init(void);
#endif /* _STM32_DMA2D_H */

View File

@ -1,142 +0,0 @@
/*
* 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
#ifndef STM32F429_439xx
#error "Currently only STM32F429xx and STM32F439xx are supported"
#endif
#endif /* STM32_LTDC_H */