From 3e6c7accdc2f89908389df126f3fb7294eb9be45 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sun, 12 Jul 2015 02:54:17 +0200 Subject: [PATCH] Adding DMA2D to STM32F429i-Discovery --- .../gdisp_lld_STM32F429iDiscovery.c | 95 +++++++++++++++++++ .../STM32F429iDiscovery/gdisp_lld_config.h | 14 +++ .../gdisp/STM32F429iDiscovery/stm32_dma2d.h | 18 ++++ 3 files changed, 127 insertions(+) create mode 100644 drivers/gdisp/STM32F429iDiscovery/stm32_dma2d.h diff --git a/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_STM32F429iDiscovery.c b/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_STM32F429iDiscovery.c index a42fe990..204097d3 100644 --- a/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_STM32F429iDiscovery.c +++ b/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_STM32F429iDiscovery.c @@ -18,12 +18,20 @@ #undef GDISP_SCREEN_WIDTH #endif +#ifndef LTDC_USE_DMA2D + #define LTDC_USE_DMA2D FALSE +#endif + #define GDISP_DRIVER_VMT GDISPVMT_STM32F429iDiscovery #include "drivers/gdisp/STM32F429iDiscovery/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 @@ -287,6 +295,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { // Initialise the LTDC controller LTDC_Init(); + // Initialise DMA2D + #if LTDC_USE_DMA2D + dma2d_init(); + #endif + // Initialise DMA2D //dma2dStart(&DMA2DD1, &dma2d_cfg); //dma2d_test(); @@ -422,4 +435,86 @@ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { } #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 */ diff --git a/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_config.h b/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_config.h index 29e016ce..c661f67c 100644 --- a/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_config.h +++ b/drivers/gdisp/STM32F429iDiscovery/gdisp_lld_config.h @@ -14,11 +14,25 @@ /* 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 */ diff --git a/drivers/gdisp/STM32F429iDiscovery/stm32_dma2d.h b/drivers/gdisp/STM32F429iDiscovery/stm32_dma2d.h new file mode 100644 index 00000000..d3374d05 --- /dev/null +++ b/drivers/gdisp/STM32F429iDiscovery/stm32_dma2d.h @@ -0,0 +1,18 @@ +#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 */