diff --git a/radio/src/Makefile b/radio/src/Makefile index 79b768a07..07facfafd 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -314,6 +314,15 @@ TRACE_SD_CARD = NO TRACE_FATFS = NO TRACE_AUDIO = NO +# Enable double buffering for LCD. Only for TARANIS PLUS and 9XE targets. +# Activating requires about 6kB of RAM, but it enables menus task to +# immediately start to compose a new LCD image while the current one is +# being written to LCD by DMA. +# If this option is NO, then first function that affects LCD buffer is +# delayed until DMA transfer is finished. +# Values = NO, YES +LCD_DUAL_BUFFER = NO + #------- END BUILD OPTIONS --------------------------- # Define programs and commands. @@ -678,11 +687,17 @@ ifeq ($(PCB), TARANIS) CPPDEFS = -DREV4a SWR = YES else ifeq ($(PCBREV), REVPLUS) - CPPDEFS = -DREVPLUS -DLCD_DUAL_BUFFER + CPPDEFS = -DREVPLUS + ifeq ($(LCD_DUAL_BUFFER), YES) + CPPDEFS += -DLCD_DUAL_BUFFER + endif HAPTIC = YES SWR = NO else ifeq ($(PCBREV), REV9E) - CPPDEFS = -DREVPLUS -DREV9E -DLCD_DUAL_BUFFER + CPPDEFS = -DREVPLUS -DREV9E + ifeq ($(LCD_DUAL_BUFFER), YES) + CPPDEFS += -DLCD_DUAL_BUFFER + endif HAPTIC = YES SWR = YES else diff --git a/radio/src/lcd.h b/radio/src/lcd.h index 8f5a16801..8f5474c1d 100644 --- a/radio/src/lcd.h +++ b/radio/src/lcd.h @@ -161,12 +161,18 @@ #define DISPLAY_BUF_SIZE (LCD_W*((LCD_H+7)/8)) #endif -#if defined(LCD_DUAL_BUFFER) -extern display_t displayBuf1[DISPLAY_BUF_SIZE]; -extern display_t displayBuf2[DISPLAY_BUF_SIZE]; -extern display_t * displayBuf; +#if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER) + extern display_t displayBuf1[DISPLAY_BUF_SIZE]; + extern display_t displayBuf2[DISPLAY_BUF_SIZE]; + extern display_t * displayBuf; #else -extern display_t displayBuf[DISPLAY_BUF_SIZE]; + extern display_t displayBuf[DISPLAY_BUF_SIZE]; +#endif + +#if defined(PCBTARANIS) && defined(REVPLUS) && !defined(LCD_DUAL_BUFFER) + void lcdWaitDmaEnd(); +#else + #define lcdWaitDmaEnd() #endif extern coord_t lcdLastPos; diff --git a/radio/src/lcd_common.cpp b/radio/src/lcd_common.cpp index c46f8fa4f..c03f0ccd3 100644 --- a/radio/src/lcd_common.cpp +++ b/radio/src/lcd_common.cpp @@ -37,7 +37,7 @@ #include "opentx.h" -#if defined(LCD_DUAL_BUFFER) +#if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER) display_t displayBuf1[DISPLAY_BUF_SIZE]; display_t displayBuf2[DISPLAY_BUF_SIZE]; display_t * displayBuf = displayBuf1; @@ -47,6 +47,7 @@ display_t displayBuf[DISPLAY_BUF_SIZE]; void lcd_clear() { + lcdWaitDmaEnd(); memset(displayBuf, 0, DISPLAY_BUFER_SIZE); } diff --git a/radio/src/lcd_default.cpp b/radio/src/lcd_default.cpp index f4777abb4..5e09f5430 100644 --- a/radio/src/lcd_default.cpp +++ b/radio/src/lcd_default.cpp @@ -41,6 +41,7 @@ #if !defined(CPUARM) void lcd_putcAtt(coord_t x, uint8_t y, const unsigned char c, LcdFlags flags) { + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; const pm_uchar *q = &font_5x7[(c-0x20)*5]; @@ -204,6 +205,7 @@ void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att) void lcd_plot(coord_t x, coord_t y, LcdFlags att) { + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; if (p= LCD_H) return; if (x+w > LCD_W) { w = LCD_W - x; } + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; uint8_t msk = BITMASK(y%8); while (w--) { @@ -239,6 +242,7 @@ void lcd_vlineStip(coord_t x, int8_t y, int8_t h, uint8_t pat) if (pat==DOTTED && !(y%2)) pat = ~pat; + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; y = (y & 0x07); if (y) { @@ -277,6 +281,7 @@ void lcd_vlineStip(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlags att) if (pat==DOTTED && !(y%2)) pat = ~pat; + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; y = (y & 0x07); if (y) { @@ -303,6 +308,7 @@ void lcd_vlineStip(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlags att) void lcd_invert_line(int8_t y) { + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[y * LCD_W]; for (coord_t x=0; x=LCD_W || y<0 || y>=LCD_H) - return; + if (x<0 || x>=LCD_W || y<0 || y>=LCD_H) return; + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ]; uint8_t mask = PIXEL_GREY_MASK(y, att); if (p= LCD_H) return; if (x+w > LCD_W) { - if (x >= LCD_W ) { - return; - } + if (x >= LCD_W ) return; w = LCD_W - x; } + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ]; uint8_t mask = PIXEL_GREY_MASK(y, att); while (w--) { @@ -123,6 +122,7 @@ void lcd_vlineStip(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlags att) void lcd_invert_line(int8_t line) { + lcdWaitDmaEnd(); uint8_t *p = &displayBuf[line * 4 * LCD_W]; for (coord_t x=0; x LCD_W) { - if (x >= LCD_W ) { - return; - } + if (x >= LCD_W ) return; width = LCD_W-x; } uint8_t rows = (*q++ + 1) / 2; + lcdWaitDmaEnd(); for (uint8_t row=0; row= DISPLAY_END) { - return; - } + if ((p) >= DISPLAY_END) return; uint8_t b = *q++; if (y & 1) { *p = (*p & 0x0f) + ((b & 0x0f) << 4); diff --git a/radio/src/targets/taranis/lcd_driver.cpp b/radio/src/targets/taranis/lcd_driver.cpp index c16584189..17686e2b3 100644 --- a/radio/src/targets/taranis/lcd_driver.cpp +++ b/radio/src/targets/taranis/lcd_driver.cpp @@ -180,6 +180,13 @@ void Set_Address(u8 x, u8 y) volatile bool lcd_busy; +#if !defined(LCD_DUAL_BUFFER) +void lcdWaitDmaEnd() +{ + WAIT_FOR_DMA_END(); +} +#endif + void lcdRefresh(bool wait) { //wait if previous DMA transfer still active