1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-20 14:55:13 +03:00

LCD_DUAL_BUFFER optional (speed vs RAM)

This commit is contained in:
Damjan Adamic 2014-12-06 18:19:32 +01:00
parent e4de0da0bb
commit f2ed441916
6 changed files with 52 additions and 19 deletions

View file

@ -314,6 +314,15 @@ TRACE_SD_CARD = NO
TRACE_FATFS = NO TRACE_FATFS = NO
TRACE_AUDIO = 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 --------------------------- #------- END BUILD OPTIONS ---------------------------
# Define programs and commands. # Define programs and commands.
@ -678,11 +687,17 @@ ifeq ($(PCB), TARANIS)
CPPDEFS = -DREV4a CPPDEFS = -DREV4a
SWR = YES SWR = YES
else ifeq ($(PCBREV), REVPLUS) else ifeq ($(PCBREV), REVPLUS)
CPPDEFS = -DREVPLUS -DLCD_DUAL_BUFFER CPPDEFS = -DREVPLUS
ifeq ($(LCD_DUAL_BUFFER), YES)
CPPDEFS += -DLCD_DUAL_BUFFER
endif
HAPTIC = YES HAPTIC = YES
SWR = NO SWR = NO
else ifeq ($(PCBREV), REV9E) 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 HAPTIC = YES
SWR = YES SWR = YES
else else

View file

@ -161,12 +161,18 @@
#define DISPLAY_BUF_SIZE (LCD_W*((LCD_H+7)/8)) #define DISPLAY_BUF_SIZE (LCD_W*((LCD_H+7)/8))
#endif #endif
#if defined(LCD_DUAL_BUFFER) #if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER)
extern display_t displayBuf1[DISPLAY_BUF_SIZE]; extern display_t displayBuf1[DISPLAY_BUF_SIZE];
extern display_t displayBuf2[DISPLAY_BUF_SIZE]; extern display_t displayBuf2[DISPLAY_BUF_SIZE];
extern display_t * displayBuf; extern display_t * displayBuf;
#else #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 #endif
extern coord_t lcdLastPos; extern coord_t lcdLastPos;

View file

@ -37,7 +37,7 @@
#include "opentx.h" #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 displayBuf1[DISPLAY_BUF_SIZE];
display_t displayBuf2[DISPLAY_BUF_SIZE]; display_t displayBuf2[DISPLAY_BUF_SIZE];
display_t * displayBuf = displayBuf1; display_t * displayBuf = displayBuf1;
@ -47,6 +47,7 @@ display_t displayBuf[DISPLAY_BUF_SIZE];
void lcd_clear() void lcd_clear()
{ {
lcdWaitDmaEnd();
memset(displayBuf, 0, DISPLAY_BUFER_SIZE); memset(displayBuf, 0, DISPLAY_BUFER_SIZE);
} }

View file

@ -41,6 +41,7 @@
#if !defined(CPUARM) #if !defined(CPUARM)
void lcd_putcAtt(coord_t x, uint8_t y, const unsigned char c, LcdFlags flags) 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 ]; uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
const pm_uchar *q = &font_5x7[(c-0x20)*5]; 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) void lcd_plot(coord_t x, coord_t y, LcdFlags att)
{ {
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
if (p<DISPLAY_END) if (p<DISPLAY_END)
lcd_mask(p, BITMASK(y%8), att); lcd_mask(p, BITMASK(y%8), att);
@ -214,6 +216,7 @@ void lcd_hlineStip(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att)
if (y >= LCD_H) return; if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; } if (x+w > LCD_W) { w = LCD_W - x; }
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t msk = BITMASK(y%8); uint8_t msk = BITMASK(y%8);
while (w--) { 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)) if (pat==DOTTED && !(y%2))
pat = ~pat; pat = ~pat;
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07); y = (y & 0x07);
if (y) { 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)) if (pat==DOTTED && !(y%2))
pat = ~pat; pat = ~pat;
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07); y = (y & 0x07);
if (y) { 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) void lcd_invert_line(int8_t y)
{ {
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[y * LCD_W]; uint8_t *p = &displayBuf[y * LCD_W];
for (coord_t x=0; x<LCD_W; x++) { for (coord_t x=0; x<LCD_W; x++) {
ASSERT_IN_DISPLAY(p); ASSERT_IN_DISPLAY(p);
@ -323,6 +329,7 @@ void lcd_img(coord_t x, coord_t y, const pm_uchar * img, uint8_t idx, LcdFlags a
uint8_t hb = (pgm_read_byte(q++)+7)/8; uint8_t hb = (pgm_read_byte(q++)+7)/8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false); bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb; q += idx*w*hb;
lcdWaitDmaEnd();
for (uint8_t yb = 0; yb < hb; yb++) { for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ]; uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ];
for (coord_t i=0; i<w; i++){ for (coord_t i=0; i<w; i++){

View file

@ -64,8 +64,8 @@ void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
void lcd_plot(coord_t x, coord_t y, LcdFlags att) void lcd_plot(coord_t x, coord_t y, LcdFlags att)
{ {
if (x<0 || x>=LCD_W || y<0 || y>=LCD_H) if (x<0 || x>=LCD_W || y<0 || y>=LCD_H) return;
return; lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ];
uint8_t mask = PIXEL_GREY_MASK(y, att); uint8_t mask = PIXEL_GREY_MASK(y, att);
if (p<DISPLAY_END) { if (p<DISPLAY_END) {
@ -77,12 +77,11 @@ void lcd_hlineStip(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att)
{ {
if (y >= LCD_H) return; if (y >= LCD_H) return;
if (x+w > LCD_W) { if (x+w > LCD_W) {
if (x >= LCD_W ) { if (x >= LCD_W ) return;
return;
}
w = LCD_W - x; w = LCD_W - x;
} }
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ]; uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ];
uint8_t mask = PIXEL_GREY_MASK(y, att); uint8_t mask = PIXEL_GREY_MASK(y, att);
while (w--) { 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) void lcd_invert_line(int8_t line)
{ {
lcdWaitDmaEnd();
uint8_t *p = &displayBuf[line * 4 * LCD_W]; uint8_t *p = &displayBuf[line * 4 * LCD_W];
for (coord_t x=0; x<LCD_W*4; x++) { for (coord_t x=0; x<LCD_W*4; x++) {
ASSERT_IN_DISPLAY(p); ASSERT_IN_DISPLAY(p);
@ -159,20 +159,17 @@ void lcd_bmp(coord_t x, coord_t y, const uint8_t * img, coord_t offset, coord_t
width = w; width = w;
} }
if (x+width > LCD_W) { if (x+width > LCD_W) {
if (x >= LCD_W ) { if (x >= LCD_W ) return;
return;
}
width = LCD_W-x; width = LCD_W-x;
} }
uint8_t rows = (*q++ + 1) / 2; uint8_t rows = (*q++ + 1) / 2;
lcdWaitDmaEnd();
for (uint8_t row=0; row<rows; row++) { for (uint8_t row=0; row<rows; row++) {
q = img + 2 + row*w + offset; q = img + 2 + row*w + offset;
uint8_t *p = &displayBuf[(row + (y/2)) * LCD_W + x]; uint8_t *p = &displayBuf[(row + (y/2)) * LCD_W + x];
for (coord_t i=0; i<width; i++) { for (coord_t i=0; i<width; i++) {
if ((p) >= DISPLAY_END) { if ((p) >= DISPLAY_END) return;
return;
}
uint8_t b = *q++; uint8_t b = *q++;
if (y & 1) { if (y & 1) {
*p = (*p & 0x0f) + ((b & 0x0f) << 4); *p = (*p & 0x0f) + ((b & 0x0f) << 4);

View file

@ -180,6 +180,13 @@ void Set_Address(u8 x, u8 y)
volatile bool lcd_busy; volatile bool lcd_busy;
#if !defined(LCD_DUAL_BUFFER)
void lcdWaitDmaEnd()
{
WAIT_FOR_DMA_END();
}
#endif
void lcdRefresh(bool wait) void lcdRefresh(bool wait)
{ {
//wait if previous DMA transfer still active //wait if previous DMA transfer still active