diff options
author | Mateusz Tomaszkiewicz <silentdemon@gmail.com> | 2013-06-12 23:23:05 +0200 |
---|---|---|
committer | Mateusz Tomaszkiewicz <silentdemon@gmail.com> | 2013-06-18 23:32:22 +0200 |
commit | 767188ed8d9d44d1f60ec9ed3f8fad295d6434fe (patch) | |
tree | 5ed29c12d296069bbe2b5787a23097d5320d176c /drivers/gdisp/SSD2119/gdisp_lld.c | |
parent | b28eb3eefd798c70681bb9b39393c36b942314d1 (diff) | |
download | uGFX-767188ed8d9d44d1f60ec9ed3f8fad295d6434fe.tar.gz uGFX-767188ed8d9d44d1f60ec9ed3f8fad295d6434fe.tar.bz2 uGFX-767188ed8d9d44d1f60ec9ed3f8fad295d6434fe.zip |
SSD2119: make use of DMA
This is mostly a copy from Eddie's work posted here:
http://forum.chibios.org/phpbb/viewtopic.php?f=11&t=851#p11054
No work was done towards making it work as fast as possible.
Tested with:
https://github.com/etmatrix/ChibiOS-GFX-Example/blob/master/bench/main.c
Results show performance of ~5.34 Mpx/s with use of DMA compared to
~4.78 Mpx/s without.
Diffstat (limited to 'drivers/gdisp/SSD2119/gdisp_lld.c')
-rw-r--r-- | drivers/gdisp/SSD2119/gdisp_lld.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/drivers/gdisp/SSD2119/gdisp_lld.c b/drivers/gdisp/SSD2119/gdisp_lld.c index fe28ca45..d7e08504 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_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_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_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_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_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_DMA) && defined(GDISP_DMA_STREAM) + stream_stop(); release_bus(); } @@ -418,8 +471,16 @@ 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 + + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank + 1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_BUSTURN_0; + + color = read_data(); // dummy read color = read_data(); + + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank + 1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0; + stream_stop(); release_bus(); @@ -450,8 +511,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 +535,17 @@ 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 + + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank + 1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_BUSTURN_0; + + j = read_data(); // dummy read for (j = 0; (coord_t)j < cx; j++) buf[j] = read_data(); + + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank + 1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0; + stream_stop(); set_viewport(x, row1, cx, 1); |