diff options
Diffstat (limited to 'drivers/gdisp/SSD2119')
-rw-r--r-- | drivers/gdisp/SSD2119/gdisp_lld.c | 99 | ||||
-rw-r--r-- | drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h | 82 | ||||
-rw-r--r-- | drivers/gdisp/SSD2119/readme.txt | 13 |
3 files changed, 141 insertions, 53 deletions
diff --git a/drivers/gdisp/SSD2119/gdisp_lld.c b/drivers/gdisp/SSD2119/gdisp_lld.c index fe28ca45..b3fa4fd3 100644 --- a/drivers/gdisp/SSD2119/gdisp_lld.c +++ b/drivers/gdisp/SSD2119/gdisp_lld.c @@ -240,13 +240,13 @@ bool_t gdisp_lld_init(void) { write_reg(SSD2119_REG_Y_RAM_ADDR, 0x00); delay(5); - // Release the bus + // Release the bus release_bus(); /* Turn on the backlight */ set_backlight(GDISP_INITIAL_BACKLIGHT); - /* Initialise the GDISP structure */ + /* Initialise the GDISP structure */ GDISP.Width = GDISP_SCREEN_WIDTH; GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Orientation = GDISP_ROTATE_0; @@ -309,14 +309,33 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_clear(color_t color) { - unsigned i; + unsigned area; + + area = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; acquire_bus(); reset_viewport(); set_cursor(0, 0); stream_start(); - for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++) - write_data(color); + + #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + uint8_t i; + dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); + dmaStreamSetMode(GDISP_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(GDISP_DMA_STREAM, 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + } + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + #else + uint32_t index; + for(index = 0; index < area; index++) + write_data(color); + #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + stream_stop(); release_bus(); } @@ -334,7 +353,7 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { - unsigned i, area; + unsigned area; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } @@ -349,8 +368,25 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { acquire_bus(); set_viewport(x, y, cx, cy); stream_start(); - for(i = 0; i < area; i++) - write_data(color); + + #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + uint8_t i; + dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); + dmaStreamSetMode(GDISP_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(GDISP_DMA_STREAM, 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + } + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + #else + uint32_t index; + for(index = 0; index < area; index++) + write_data(color); + #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + stream_stop(); release_bus(); } @@ -370,8 +406,6 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { * @notapi */ void gdisp_lld_blit_area_ex(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 (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } @@ -382,17 +416,36 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif + buffer += srcx + srcy * srccx; + acquire_bus(); set_viewport(x, y, cx, cy); stream_start(); - endx = srcx + cx; - endy = y + cy; - lg = srccx - cx; - buffer += srcx + srcy * srccx; - for(; y < endy; y++, buffer += lg) - for(x=srcx; x < endx; x++) - write_data(*buffer++); + #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + uint32_t area = cx * cy; + uint8_t i; + dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer); + dmaStreamSetMode(GDISP_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(GDISP_DMA_STREAM, 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + } + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + #else + coord_t endx, endy; + uint32_t lg; + endx = srcx + cx; + endy = y + cy; + lg = srccx - cx; + for(; y < endy; y++, buffer += lg) + for(x=srcx; x < endx; x++) + write_data(*buffer++); + #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + stream_stop(); release_bus(); } @@ -418,8 +471,10 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { acquire_bus(); set_cursor(x, y); stream_start(); - color = read_data(); // dummy read + + color = read_data(); // dummy read color = read_data(); + stream_stop(); release_bus(); @@ -450,8 +505,8 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; - if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; - if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; + if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif abslines = lines < 0 ? -lines : lines; @@ -474,9 +529,11 @@ void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) { /* read row0 into the buffer and then write at row1*/ set_viewport(x, row0, cx, 1); stream_start(); - j = read_data(); // dummy read + + j = read_data(); // dummy read for (j = 0; (coord_t)j < cx; j++) buf[j] = read_data(); + stream_stop(); set_viewport(x, row1, cx, 1); diff --git a/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h b/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h index ccbba2a3..068af149 100644 --- a/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h +++ b/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h @@ -16,38 +16,67 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H +/* This board file uses only FSMC, so don't undefine this. */ +#define GDISP_USE_FSMC +/* But it is OK to disable DMA use. */ +#define GDISP_USE_DMA +#define GDISP_DMA_STREAM STM32_DMA2_STREAM6 + /* Using FSMC A19 (PE3) as DC */ -#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */ -#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */ +#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */ +#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */ -#define SET_RST palSetPad(GPIOD, 3); -#define CLR_RST palClearPad(GPIOD, 3); +#define SET_RST palSetPad(GPIOD, 3); +#define CLR_RST palClearPad(GPIOD, 3); -/* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */ +/* + * PWM configuration structure. We use timer 4 channel 2 (orange LED on board). + * The reason for so high clock is that with any lower, onboard coil is squeaking. + * The major disadvantage of this clock is a lack of linearity between PWM duty + * cycle width and brightness. In fact only with low preset one sees any change + * (eg. duty cycle between 1-20). Feel free to adjust this, maybe only my board + * behaves like this. According to the G5126 datesheet (backlight LED driver) + * the PWM frequency should be somewhere between 200 Hz to 200 kHz. + */ static const PWMConfig pwmcfg = { - 1000000, /* 1 MHz PWM clock frequency. */ - 100, /* PWM period is 100 cycles. */ - NULL, - { - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL} - }, - 0 + 1000000, /* 1 MHz PWM clock frequency. */ + 100, /* PWM period is 100 cycles. */ + NULL, + { + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL} + }, + 0 }; /** * @brief Initialise the board for the display. - * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins + * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins * * @notapi */ static inline void init_board(void) { unsigned char FSMC_Bank; - /* STM32F4 FSMC init */ - rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + #ifndef GDISP_USE_FSMC + #error "This board uses only FSMC, please define GDISP_USE_FSMC" + #endif + + #if defined(STM32F4XX) || defined(STM32F2XX) + /* STM32F4 FSMC init */ + rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + + #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) + gfxExit(); + dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM); + dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); + #endif + #else + #error "FSMC not implemented for this device" + #endif /* Group pins */ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) | @@ -61,15 +90,14 @@ static inline void init_board(void) { palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); FSMC_Bank = 0; - - /* FSMC timing */ - FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \ - | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \ - | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ; - - /* Bank1 NOR/SRAM control register configuration - * This is actually not needed as already set by default after reset */ - FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; + /* FSMC timing register configuration */ + FSMC_Bank1->BTCR[FSMC_Bank + 1] = (FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1) \ + | (FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1) \ + | FSMC_BTR1_BUSTURN_0; + + /* Bank1 NOR/PSRAM control register configuration + * Write enable, memory databus width set to 16 bit, memory bank enable */ + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_WREN | FSMC_BCR1_MWID_0 | FSMC_BCR1_MBKEN; /* Display backlight control */ /* TIM4 is an alternate function 2 (AF2) */ diff --git a/drivers/gdisp/SSD2119/readme.txt b/drivers/gdisp/SSD2119/readme.txt index 371df813..23d82eb7 100644 --- a/drivers/gdisp/SSD2119/readme.txt +++ b/drivers/gdisp/SSD2119/readme.txt @@ -4,17 +4,20 @@ Driver for LCD with 16-bit 8080 interface (65k colors). To use this driver: -1. Add in your halconf.h: +1. Add in your gfxconf.h: a) #define GFX_USE_GDISP TRUE b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD c) If you are not using a known board then create a gdisp_lld_board.h file - and ensure it is on your include path. - Use the gdisp_lld_board_embest_dmstf4bb_fsmc.h file as a basis. + and ensure it is on your include path. Use the gdisp_lld_board_embest_dmstf4bb.h + file as a basis. Currently known boards are: - BOARD_EMBEST_DMSTF4BB_FSMC - FSMC interface - Board configuration assume that you have STM32_PWM_USE_TIM4 set to TRUE in your mcuconf.h. + BOARD_EMBEST_DMSTF4BB - FSMC interface + This board configuration assumes that you have PWM driver enabled + and STM32_PWM_USE_TIM4 set to TRUE in your mcuconf.h. + If you use FSMC, define in your board file GDISP_USE_FSMC. If you use DMA, + define GDISP_USE_DMA. d) The following are optional - define them if you are not using the defaults below: #define GDISP_SCREEN_WIDTH 320 |