Merge pull request #50 from mobyfab/master

DMA support for SSD1963
remotes/origin_old/ugfx_release_2.6
Tectu 2012-09-19 02:42:20 -07:00
commit d3b604cfde
4 changed files with 152 additions and 83 deletions

View File

@ -189,9 +189,18 @@ bool_t GDISP_LLD(init)(void) {
/* FSMC setup for F1/F3 */ /* FSMC setup for F1/F3 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0); rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
#if defined(LCD_USE_DMA) && defined(LCD_DMA_STREAM)
#error "DMA not implemented for F1/F3 Devices"
#endif
#elif defined(STM32F4XX) || defined(STM32F2XX) #elif defined(STM32F4XX) || defined(STM32F2XX)
/* STM32F2-F4 FSMC init */ /* STM32F2-F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
#if defined(LCD_USE_DMA) && defined(LCD_DMA_STREAM)
if (dmaStreamAllocate(LCD_DMA_STREAM, 0, NULL, NULL)) chSysHalt();
dmaStreamSetMemory0(LCD_DMA_STREAM, &LCD_RAM);
dmaStreamSetMode(LCD_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
#endif
#else #else
#error "FSMC not implemented for this device" #error "FSMC not implemented for this device"
#endif #endif
@ -248,7 +257,7 @@ bool_t GDISP_LLD(init)(void) {
/* Screen size */ /* Screen size */
GDISP_LLD(writeindex)(SSD1963_SET_LCD_MODE); GDISP_LLD(writeindex)(SSD1963_SET_LCD_MODE);
// GDISP_LLD(writedata)(0x0000); // GDISP_LLD(writedata)(0x0000);
GDISP_LLD(writedata)(0b00011000); GDISP_LLD(writedata)(0b00011000); //Enabled dithering
GDISP_LLD(writedata)(0x0000); GDISP_LLD(writedata)(0x0000);
GDISP_LLD(writedata)(mHIGH((SCREEN_WIDTH+1))); GDISP_LLD(writedata)(mHIGH((SCREEN_WIDTH+1)));
GDISP_LLD(writedata)((SCREEN_WIDTH+1)); GDISP_LLD(writedata)((SCREEN_WIDTH+1));
@ -366,6 +375,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @notapi * @notapi
*/ */
void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
@ -374,14 +384,29 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif #endif
uint32_t index = 0, area; uint32_t area;
area = cx*cy; area = cx*cy;
GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1);
GDISP_LLD(writestreamstart)(); GDISP_LLD(writestreamstart)();
#if defined(LCD_USE_FSMC) && defined(LCD_USE_DMA) && defined(LCD_DMA_STREAM)
uint8_t i;
dmaStreamSetPeripheral(LCD_DMA_STREAM, &color);
dmaStreamSetMode(LCD_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
for (i = area/65535; i; i--) {
dmaStreamSetTransactionSize(LCD_DMA_STREAM, 65535);
dmaStreamEnable(LCD_DMA_STREAM);
dmaWaitCompletion(LCD_DMA_STREAM);
}
dmaStreamSetTransactionSize(LCD_DMA_STREAM, area%65535);
dmaStreamEnable(LCD_DMA_STREAM);
dmaWaitCompletion(LCD_DMA_STREAM);
#else
uint32_t index;
for(index = 0; index < area; index++) for(index = 0; index < area; index++)
GDISP_LLD(writedata)(color); GDISP_LLD(writedata)(color);
#endif //#ifdef LCD_USE_DMA
} }
#endif #endif
@ -399,8 +424,6 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @notapi * @notapi
*/ */
void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
@ -414,13 +437,31 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1);
GDISP_LLD(writestreamstart)(); GDISP_LLD(writestreamstart)();
buffer += srcx + srcy * srccx;
#if defined(LCD_USE_FSMC) && defined(LCD_USE_DMA) && defined(LCD_DMA_STREAM)
uint32_t area = cx*cy;
uint8_t i;
dmaStreamSetPeripheral(LCD_DMA_STREAM, buffer);
dmaStreamSetMode(LCD_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
for (i = area/65535; i; i--) {
dmaStreamSetTransactionSize(LCD_DMA_STREAM, 65535);
dmaStreamEnable(LCD_DMA_STREAM);
dmaWaitCompletion(LCD_DMA_STREAM);
}
dmaStreamSetTransactionSize(LCD_DMA_STREAM, area%65535);
dmaStreamEnable(LCD_DMA_STREAM);
dmaWaitCompletion(LCD_DMA_STREAM);
#else
coord_t endx, endy;
unsigned lg;
endx = srcx + cx; endx = srcx + cx;
endy = y + cy; endy = y + cy;
lg = srccx - cx; lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg) for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++) for(x=srcx; x < endx; x++)
GDISP_LLD(writedata)(*buffer++); GDISP_LLD(writedata)(*buffer++);
#endif //#ifdef LCD_USE_DMA
} }
#endif #endif

View File

@ -2,11 +2,37 @@ To use this driver:
1. Add in your halconf.h: 1. Add in your halconf.h:
a) #define HAL_USE_GDISP TRUE a) #define HAL_USE_GDISP TRUE
b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD b) Any optional high level driver defines (see gdisp.h) eg: #define GDISP_NEED_MULTITHREAD TRUE
c) One (only) of: c) One (only) of:
#define LCD_USE_GPIO (Work in progress) #define LCD_USE_GPIO
#define LCD_USE_FSMC #define LCD_USE_FSMC
d) Edit gdisp_lld_panel.h with your panel properties d) If you want to use DMA (only works with FSMC):
#define LCD_USE_DMA
#define LCD_DMA_STREAM STM32_DMA2_STREAM6 //You can change the DMA channel according to your needs
2. To your makefile add the following lines: 2. Edit gdisp_lld_panel.h with your panel properties
3. To your makefile add the following lines:
include $(LCDLIB)/drivers/gdisp/SSD1963/gdisp_lld.mk include $(LCDLIB)/drivers/gdisp/SSD1963/gdisp_lld.mk
Example FSMC config with DMA:
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
#define LCD_USE_FSMC
#define LCD_USE_DMA
#define LCD_DMA_STREAM STM32_DMA2_STREAM6
#if defined(LCD_USE_GPIO)
#define LCD_CMD_PORT GPIOC
#define LCD_DATA_PORT GPIOD
#define LCD_CS 0
#define LCD_RS 1
#define LCD_WR 2
#define LCD_RD 3
#endif

View File

@ -52,7 +52,7 @@
/*===========================================================================*/ /*===========================================================================*/
/* Driver local variables. */ /* Driver local variables. */
/*===========================================================================*/ /*===========================================================================*/
volatile static struct cal cal = { static volatile struct cal cal = {
1, 1, 0, 0 1, 1, 0, 0
}; };
@ -168,6 +168,7 @@ uint16_t tpReadX(void) {
case landscapeInv: case landscapeInv:
return y; return y;
} }
return 0;
} }
/** /**
@ -193,6 +194,7 @@ uint16_t tpReadY(void) {
case landscapeInv: case landscapeInv:
return SCREEN_WIDTH - x; return SCREEN_WIDTH - x;
} }
return 0;
} }
void tpCalibrate(void) { void tpCalibrate(void) {