From dd2fb5d7e68baf56fb78d242542735b3dbf6c919 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sun, 2 Aug 2020 17:38:03 +0000 Subject: [PATCH] Added buffered rendering --- example.c | 1 + main.c | 9 +++++++ spilcd.h | 2 ++ st7735.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 83 insertions(+), 8 deletions(-) diff --git a/example.c b/example.c index da02b6b..19dbb24 100644 --- a/example.c +++ b/example.c @@ -215,6 +215,7 @@ int main(int argc, char** argv) { /* Refresh screen */ //ssd1306Refresh(); //SSD1306MSDELAY(1000); + lcd_redrawBuffer(lcd); sleep(1); } diff --git a/main.c b/main.c index 1f34582..9db3a0f 100644 --- a/main.c +++ b/main.c @@ -26,10 +26,12 @@ int main(int argc, char *argv[]) printf("Fill display..."); printf("blue..."); lcd_fillScreen(lcd, 0, 70, 160); + lcd_redrawBuffer(lcd); printf("...waiting 1 second..."); sleep(1); printf("black..."); lcd_fillScreen(lcd, 0, 0, 0); + lcd_redrawBuffer(lcd); printf("DONE\n"); printf("...waiting 1 second...\n"); @@ -43,6 +45,7 @@ int main(int argc, char *argv[]) random_color_g(i), random_color_b(i)); } + lcd_redrawBuffer(lcd); printf("DONE\n"); printf("...waiting 1 second...\n"); @@ -61,9 +64,12 @@ int main(int argc, char *argv[]) for (int p = 0; p < w*h; p++) { lcd_pushPixel(lcd, r * p / (w*h), g * (w*h-p) / (w*h), b); } + lcd_redrawBuffer(lcd); } printf("DONE\n"); + return 0; + printf("...waiting 1 second...\n"); sleep(1); @@ -71,6 +77,7 @@ int main(int argc, char *argv[]) lcd_fillScreen(lcd, 0, 0, 0); lcd_fillRect(lcd, 30, 10, 10, 10, 0, 255, 255); lcd_fillRect(lcd, 30, 30, 10, 10, 255, 255, 0); + lcd_redrawBuffer(lcd); printf("DONE\n"); printf("...waiting 1 second...\n"); @@ -81,6 +88,7 @@ int main(int argc, char *argv[]) lcd_drawChar(lcd, 10, 90, 'A', 255, 0, 0); lcd_drawText(lcd, 10, 50, "Hello, world!", 0, 255, 0); lcd_drawChar(lcd, 10, 100, 'Z', 0, 0, 255); + lcd_redrawBuffer(lcd); printf("DONE\n"); printf("...waiting 2 seconds...\n"); @@ -92,6 +100,7 @@ int main(int argc, char *argv[]) random_color_r(i), random_color_g(i), random_color_b(i)); + lcd_redrawBuffer(lcd); } printf("DONE\n"); diff --git a/spilcd.h b/spilcd.h index 6207d0c..d82d0fd 100644 --- a/spilcd.h +++ b/spilcd.h @@ -76,5 +76,7 @@ void lcd_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b); */ void lcd_pushPixels(lcd_t* lcd, uint8* pixels, size_t count); +void lcd_redrawBuffer(lcd_t* lcd); + #endif // __SPILCD_H__ diff --git a/st7735.c b/st7735.c index c476554..232dbe1 100644 --- a/st7735.c +++ b/st7735.c @@ -28,6 +28,14 @@ struct }; /****************************** END EASY PORT END *****************************/ +static uint8 screen_buffer[128 * 160 * 3]; // TODO: make dynamic +static uint8 screen_window_x1; +static uint8 screen_window_x2; +static uint8 screen_window_y1; +static uint8 screen_window_y2; +static uint8 screen_cursor_x; +static uint8 screen_cursor_y; + static lcd_t *activeDisplay; /* @@ -54,6 +62,10 @@ static inline void *safeMalloc(size_t size) } /* safeMalloc */ +uint8 lcdhw_setWindow(lcd_t* lcd, uint8 x1, uint8 y1, uint8 x2, uint8 y2); +void lcdhw_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b); +void lcdhw_pushPixels(lcd_t* lcd, uint8* pixels, size_t count); + void lcd_setOrientation(lcd_t* lcd, uint8 orientation); void lcd_setGamma(lcd_t* lcd, uint8 state); void lcd_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b); @@ -158,28 +170,28 @@ void lcd_setOrientation(lcd_t* lcd, uint8 orientation) writeData(0x60); /* MX + MV */ activeDisplay->width = 160; activeDisplay->height = 128; - lcd_setWindow(lcd, 0, 0, 159, 127); + lcdhw_setWindow(lcd, 0, 0, 159, 127); break; case 2: writeData(0xC0); /* MY + MX */ activeDisplay->width = 128; activeDisplay->height = 160; - lcd_setWindow(lcd, 0, 0, 127, 159); + lcdhw_setWindow(lcd, 0, 0, 127, 159); break; case 3: writeData(0xA0); /* MY + MV */ activeDisplay->width = 160; activeDisplay->height = 128; - lcd_setWindow(lcd, 0, 0, 159, 127); + lcdhw_setWindow(lcd, 0, 0, 159, 127); break; default: writeData(0x00); /* None */ activeDisplay->width = 128; activeDisplay->height = 160; - lcd_setWindow(lcd, 0, 0, 127, 159); + lcdhw_setWindow(lcd, 0, 0, 127, 159); break; } } /* lcdst_setOrientation */ @@ -206,7 +218,7 @@ void lcd_setInversion(lcd_t* lcd, uint8 state) writeCommand(state ? 0x21 : 0x20); } /* lcdst_setInversion */ -uint8 lcd_setWindow(lcd_t* lcd, uint8 x1, uint8 y1, uint8 x2, uint8 y2) +uint8 lcdhw_setWindow(lcd_t* lcd, uint8 x1, uint8 y1, uint8 x2, uint8 y2) { /* Accept: 0 <= x1 <= x2 < activeDisplay->width */ if(x2 < x1) return 1; @@ -241,18 +253,69 @@ void lcd_activateRamWrite(void) uint8 pixel[3]; -inline void lcd_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b) +inline void lcdhw_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b) { gpio.digitalWrite(activeDisplay->a0, HIGH); pixel[0] = r; pixel[1] = g; pixel[2] = b; gpio.spiDataRW(activeDisplay->channel, pixel, 3); -} /* lcdst_pushPx */ +} -void lcd_pushPixels(lcd_t* lcd, uint8* pixels, size_t count) +void lcdhw_pushPixels(lcd_t* lcd, uint8* pixels, size_t count) { gpio.digitalWrite(activeDisplay->a0, HIGH); gpio.spiDataRW(activeDisplay->channel, pixels, count * 3); } +uint8 line_buffer[160*3]; // lcd->width or lcd->height + +void lcd_redrawBuffer(lcd_t* lcd) +{ + for (int i = 0; i < lcd->height; i++) { + memcpy(line_buffer, &screen_buffer[i*lcd->width*3], lcd->width*3); + lcdhw_setWindow(lcd, 0, i, lcd->width - 1, i); + lcdhw_pushPixels(lcd, line_buffer, lcd->width); + } +} + +uint8 lcd_setWindow(lcd_t* lcd, uint8 x1, uint8 y1, uint8 x2, uint8 y2) +{ + screen_window_x1 = x1; + screen_window_x2 = x2; + screen_window_y1 = y1; + screen_window_y2 = y2; + screen_cursor_x = x1; + screen_cursor_y = y1; + return 0; +} + +void lcd_pushPixel(lcd_t* lcd, uint8 r, uint8 g, uint8 b) +{ + int i = screen_cursor_x + + screen_cursor_y * lcd->width; + screen_buffer[i * 3 + 0] = r; + screen_buffer[i * 3 + 1] = g; + screen_buffer[i * 3 + 2] = b; + + screen_cursor_x++; + if (screen_cursor_x > screen_window_x2) { + screen_cursor_x = screen_window_x1; + screen_cursor_y++; + if (screen_cursor_y > screen_window_y2) { + screen_cursor_y = screen_window_y1; + } + } +} + +void lcd_pushPixels(lcd_t* lcd, uint8* pixels, size_t count) +{ + for (int i = 0; i < count; i++) { + lcd_pushPixel(lcd, + pixels[i * 3 + 0], + pixels[i * 3 + 1], + pixels[i * 3 + 2]); + } +} + +