From 0f377dc9efe9cf2a3d14413188d6f61f0f22b8d0 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 20 Jun 2012 23:32:27 +0100 Subject: [PATCH 01/17] starting work on virtual console --- console.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ console.h | 63 +++++++++++++++++++++++++++++++++ lcd.mk | 1 + 3 files changed, 167 insertions(+) create mode 100644 console.c create mode 100644 console.h diff --git a/console.c b/console.c new file mode 100644 index 00000000..c944b899 --- /dev/null +++ b/console.c @@ -0,0 +1,103 @@ +/* + * console.c + * + * Created on: 20 Jun 2012 + * Author: Thomas Saunders AKA "Badger" + */ + +#include "ch.h" + +#include "fonts.h" +#include "glcd.h" +#include "console.h" + + +msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, + uint16_t y1, const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { + const uint8_t* ptr; + uint16_t chi; + uint16_t x,y; + /* read font, get size */ + /* TODO: this is messy. improve font handling. + * this assumes that all characters are as wide as A */ + console->fy = font[FONT_TABLE_HEIGHT_IDX]; + chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + ('A'-0x20)*2]); + ptr = font + chi; + console->fx = *(ptr++); + + /* calculate the size of the console in characters */ + console->sx = (x1-x0)/console->fx; + console->sy = (y1-y0)/console->fy; + + console->cx = 0; + console->cy = 0; + + console->buf = buffer; + console->bidx = 0; +} + + +/* + * Interface implementation. The interface is write only + */ + +static size_t writes(void *ip, const uint8_t *bp, size_t n) { + (void)ip; + return lcdWriteString(bp, n); +} + +static size_t reads(void *ip, uint8_t *bp, size_t n) { + (void)ip; + (void)bp; + (void)n; + return 0; +} + +static msg_t put(void *ip, uint8_t b) { + (void)ip; + return lcdDrawChar((char)b); +} + +static msg_t get(void *ip) { + (void)ip; + return RDY_OK; +} + +static msg_t putt(void *ip, uint8_t b, systime_t timeout) { + (void)ip; + (void)timeout; + /* TODO: handle timeout */ + return lcdDrawChar((char)b); +} + +static msg_t gett(void *ip, systime_t timeout) { + (void)ip; + (void)timeout; + return RDY_OK; +} + +static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) { + (void)ip; + (void)time; + return lcdWriteString(bp, n); +} + +static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) { + (void)ip; + (void)bp; + (void)n; + (void)time; + return 0; +} + +static chnflags_t getflags(void *ip) { + _chn_get_and_clear_flags_impl(ip); +} + +static const struct GLCDConsoleVMT vmt = { + writes, reads, put, get, + putt, gett, writet, readt, + getflags +}; + + diff --git a/console.h b/console.h new file mode 100644 index 00000000..6f017d88 --- /dev/null +++ b/console.h @@ -0,0 +1,63 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +/** + * @brief Structure representing a GLCD driver. + */ +typedef struct GLCDConsole GLCDConsole; + +/** + * @brief @p GLCDConsole specific methods. + */ +#define _glcd_driver_methods \ + _base_asynchronous_channel_methods + +/** + * @extends BaseAsynchronousChannelVMT + * + * @brief @p GLCDConsole virtual methods table. + */ +struct GLCDConsoleVMT { + _glcd_driver_methods +}; + +/** + * @extends BaseAsynchronousChannel + * + * @brief GLCD Console class. + * @details This class extends @p BaseAsynchronousChannel by adding physical + * I/O queues. + */ +struct GLCDConsole { + /** @brief Virtual Methods Table.*/ + const struct GLCDConsoleVMT *vmt; + _base_asynchronous_channel_data + /* WARNING: Do not add any data to this struct above this comment, only below */ + /* text buffer */ + uint8_t *buf; + /* lcd area to use */ + uint16_t x0,y0,x1,y1; + /* current cursor position, in character coordinates (not pixels) */ + uint16_t cx,cy; + /* console size in characters */ + uint16_t sx,sy; + /* foreground and background colour */ + uint16_t bkcolor, color; + /* font size in pixels */ + uint8_t fx,fy; + /* buffer index */ + uint16_t bidx; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, + const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color); + +#ifdef __cplusplus +} +#endif + +#endif /* CONSOLE_H */ diff --git a/lcd.mk b/lcd.mk index 1c54d5e9..5ba7df1b 100644 --- a/lcd.mk +++ b/lcd.mk @@ -7,6 +7,7 @@ LCDSRC = $(LCDLIB)/glcd.c \ $(LCDLIB)/touchpad.c \ $(LCDLIB)/graph.c \ $(LCDLIB)/gui.c \ + $(LCDLIB)/console.c \ $(LCD_DRIVERS_SRC) LCDINC = $(LCDLIB) \ From 427346aaf231e91b2c025f62152380d36e7ea6a5 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Thu, 21 Jun 2012 23:14:18 +0100 Subject: [PATCH 02/17] more console stuff --- console.c | 140 +++++++++++++++++++++++++++++++++++++++++------------- console.h | 8 +++- 2 files changed, 113 insertions(+), 35 deletions(-) diff --git a/console.c b/console.c index c944b899..8961646d 100644 --- a/console.c +++ b/console.c @@ -11,39 +11,12 @@ #include "glcd.h" #include "console.h" - -msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, - uint16_t y1, const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { - const uint8_t* ptr; - uint16_t chi; - uint16_t x,y; - /* read font, get size */ - /* TODO: this is messy. improve font handling. - * this assumes that all characters are as wide as A */ - console->fy = font[FONT_TABLE_HEIGHT_IDX]; - chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + ('A'-0x20)*2]); - ptr = font + chi; - console->fx = *(ptr++); - - /* calculate the size of the console in characters */ - console->sx = (x1-x0)/console->fx; - console->sy = (y1-y0)/console->fy; - - console->cx = 0; - console->cy = 0; - - console->buf = buffer; - console->bidx = 0; -} - - /* * Interface implementation. The interface is write only */ static size_t writes(void *ip, const uint8_t *bp, size_t n) { - (void)ip; - return lcdWriteString(bp, n); + return lcdConsoleWrite((GLCDConsole *)ip, bp, n); } static size_t reads(void *ip, uint8_t *bp, size_t n) { @@ -54,8 +27,7 @@ static size_t reads(void *ip, uint8_t *bp, size_t n) { } static msg_t put(void *ip, uint8_t b) { - (void)ip; - return lcdDrawChar((char)b); + return lcdConsolePut((GLCDConsole *)ip, (char)b); } static msg_t get(void *ip) { @@ -64,10 +36,9 @@ static msg_t get(void *ip) { } static msg_t putt(void *ip, uint8_t b, systime_t timeout) { - (void)ip; (void)timeout; /* TODO: handle timeout */ - return lcdDrawChar((char)b); + return lcdConsolePut((GLCDConsole *)ip, (char)b); } static msg_t gett(void *ip, systime_t timeout) { @@ -77,9 +48,8 @@ static msg_t gett(void *ip, systime_t timeout) { } static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) { - (void)ip; (void)time; - return lcdWriteString(bp, n); + return lcdConsoleWrite((GLCDConsole *)ip, bp, n); } static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) { @@ -101,3 +71,105 @@ static const struct GLCDConsoleVMT vmt = { }; +msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, + uint16_t y1, const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { + const uint8_t* ptr; + uint16_t chi; + uint16_t x,y; + + console->vmt = &vmt; + /* read font, get size */ + /* TODO: this is messy. improve font handling. + * this assumes that all characters are as wide as A */ + console->fy = font[FONT_TABLE_HEIGHT_IDX]; + chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + ('A'-0x20)*2]); + ptr = font + chi; + console->fx = *(ptr++); + + /* calculate the size of the console in characters */ + console->sx = (x1-x0)/console->fx; + console->sy = (y1-y0)/console->fy; + + console->cx = 0; + console->cy = 0; + console->x0 = x0; + console->y0 = y0; + + console->buf = buffer; + console->bidx = 0; + console->blen = console->sx*console->sy; + console->bstrt = 0; + + console->bkcolor = bkcolor; + console->color = color; + + console->font = font; + console->full = FALSE; +} + +msg_t lcdConsoleUpdate(GLCDConsole *console) { + +} + +msg_t lcdConsolePut(GLCDConsole *console, char c) { + + if(console->full) { + return RDY_RESET; + } + + bool_t redraw = FALSE; + /* write character to current position in buffer */ + console->buf[console->bidx++] = c; + + if(console->bidx == console->blen) { + /* wrap around to the beginning */ + console->bidx = 0; + } + + if(c == '\n') { + console->cx = 0; + console->cy++; + redraw = TRUE; + } else if(c == '\r') { + console->cx = 0; + } else { + console->cx++; + } + + if(console->cx > console->sx) { + /* character has extended beyond end of line */ + redraw = TRUE; + } + + if(redraw && console->cy == console->sy) { + + /* we've gone past the end of the console */ + console->full = TRUE; + return RDY_RESET; + /* start at beginning of buffer and remove the first line */ + uint16_t i; + + /* increment i from bstrt until it has been incremented more than console->sx or finds a new line */ + for(i = console->bstrt; ((i - console->bstrt) < console->sx) && (console->buf[i % console->sx] != '\n'); i++); + + /* update bstrt to the new start point of the console */ + console->bstrt = i; + } else { + /* just draw the character at the current position */ + lcdMoveCursor(console->x0 + console->cx*console->fx, console->y0 + console->cy*console->fy, + console->color, console->bkcolor); + + lcdSetFont(console->font); + lcdDrawChar(c); + } +} + +msg_t lcdConsoleWrite(GLCDConsole *console, uint8_t *bp, size_t n) { + size_t i; + for(i = 0; i < n; i++) + lcdConsolePut(console, bp[i]); + + return RDY_OK; +} + + diff --git a/console.h b/console.h index 6f017d88..06320853 100644 --- a/console.h +++ b/console.h @@ -35,6 +35,8 @@ struct GLCDConsole { /* WARNING: Do not add any data to this struct above this comment, only below */ /* text buffer */ uint8_t *buf; + /* font */ + const uint8_t *font; /* lcd area to use */ uint16_t x0,y0,x1,y1; /* current cursor position, in character coordinates (not pixels) */ @@ -46,7 +48,8 @@ struct GLCDConsole { /* font size in pixels */ uint8_t fx,fy; /* buffer index */ - uint16_t bidx; + uint16_t bidx, blen, bstrt; + bool_t full; }; #ifdef __cplusplus @@ -56,6 +59,9 @@ extern "C" { msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color); +msg_t lcdConsolePut(GLCDConsole *console, char c); +msg_t lcdConsoleWrite(GLCDConsole *console, uint8_t *bp, size_t n); + #ifdef __cplusplus } #endif From d0e3a0636e052594bc0f2794527a9e0f0b9aa43a Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Fri, 22 Jun 2012 10:26:41 +0100 Subject: [PATCH 03/17] removed glcdconf.h it makes more sense for this config to be in the board file / application header / chconf.h --- drivers/lcd/s6d1121_lld.h | 1 - drivers/lcd/ssd1289_lld.h | 1 - drivers/touchpad/ads7843_lld.h | 2 +- drivers/touchpad/xpt2046_lld.h | 2 +- glcdconf.h | 21 --------------------- 5 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 glcdconf.h diff --git a/drivers/lcd/s6d1121_lld.h b/drivers/lcd/s6d1121_lld.h index edc6da33..24e207e8 100644 --- a/drivers/lcd/s6d1121_lld.h +++ b/drivers/lcd/s6d1121_lld.h @@ -2,7 +2,6 @@ #define S6D1121_H #include "glcd.h" -#include "glcdconf.h" #ifdef LCD_USE_S6D1121 diff --git a/drivers/lcd/ssd1289_lld.h b/drivers/lcd/ssd1289_lld.h index 3cedcc90..f1f07937 100644 --- a/drivers/lcd/ssd1289_lld.h +++ b/drivers/lcd/ssd1289_lld.h @@ -2,7 +2,6 @@ #define SSD1289_H #include "glcd.h" -#include "glcdconf.h" #ifdef LCD_USE_SSD1289 diff --git a/drivers/touchpad/ads7843_lld.h b/drivers/touchpad/ads7843_lld.h index 388aacc8..121e6288 100644 --- a/drivers/touchpad/ads7843_lld.h +++ b/drivers/touchpad/ads7843_lld.h @@ -1,7 +1,7 @@ #ifndef ADS7843_LLD_H #define ADS7843_LLD_H -#include "glcdconf.h" +#include "glcd.h" #include "touchpad.h" #ifdef TOUCHPAD_USE_ADS7843 diff --git a/drivers/touchpad/xpt2046_lld.h b/drivers/touchpad/xpt2046_lld.h index ed7a0d09..c3a12077 100644 --- a/drivers/touchpad/xpt2046_lld.h +++ b/drivers/touchpad/xpt2046_lld.h @@ -1,7 +1,7 @@ #ifndef XPT2046_LLD_H #define XPT2046_LLD_H -#include "glcdconf.h" +#include "glcd.h" #include "touchpad.h" #ifdef TOUCHPAD_USE_XPT2046 diff --git a/glcdconf.h b/glcdconf.h deleted file mode 100644 index 657ee32d..00000000 --- a/glcdconf.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef GLCDCONF_H -#define GLCDCONF_H - - -/***** LCD CONTROLLER *****/ -#define LCD_USE_SSD1289 -// #define LCD_USE_S6D1121 - - -/***** LCD INTERFACE *****/ -#define LCD_USE_GPIO -// #define LCD_USE_SPI -// #define LCD_USE_FSMC - - -/***** TOUCHPAD CONTROLLER *****/ -// #define TOUCHPAD_USE_ADS7843 -#define TOUCHPAD_USE_XPT2046 - - -#endif From 5c7d3819be53ede62bffccaadc70ee5fc0734d5c Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Fri, 22 Jun 2012 21:41:24 +0100 Subject: [PATCH 04/17] text scrolling sort of starting to work but it is slow and the font has artefacts, probably because a fixed width is being used --- console.c | 102 ++++++++++++++++++++++++++++++++++-------------------- console.h | 2 +- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/console.c b/console.c index 8961646d..4e21a795 100644 --- a/console.c +++ b/console.c @@ -87,8 +87,8 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 console->fx = *(ptr++); /* calculate the size of the console in characters */ - console->sx = (x1-x0)/console->fx; - console->sy = (y1-y0)/console->fy; + console->sx = (x1-x0); + console->sy = (y1-y0); console->cx = 0; console->cy = 0; @@ -96,7 +96,7 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 console->y0 = y0; console->buf = buffer; - console->bidx = 0; + console->wptr = 0; console->blen = console->sx*console->sy; console->bstrt = 0; @@ -112,56 +112,82 @@ msg_t lcdConsoleUpdate(GLCDConsole *console) { } msg_t lcdConsolePut(GLCDConsole *console, char c) { + uint8_t width = console->fx; + uint16_t i; + uint16_t s = console->wptr; + bool_t redraw = FALSE; if(console->full) { return RDY_RESET; } - bool_t redraw = FALSE; - /* write character to current position in buffer */ - console->buf[console->bidx++] = c; + /* write character to current position in buffer and update wptr */ + console->buf[console->wptr] = c; - if(console->bidx == console->blen) { + if(++console->wptr == console->blen) { /* wrap around to the beginning */ - console->bidx = 0; + console->wptr = 0; } - if(c == '\n') { - console->cx = 0; - console->cy++; - redraw = TRUE; - } else if(c == '\r') { - console->cx = 0; - } else { - console->cx++; - } + lcdSetFont(console->font); + lcdSetFontTransparency(solid); + /* keep looping until we've finished writing + * we may write more than one character if the console needs to be re-drawn + * at the end of the loop leave the cursor set to the position for the next character + * checks to see if this is out of range will be performed at the start of that character + */ + do { + if(console->buf[s] == '\n') { + console->cx = 0; + console->cy += console->fy; + } else if(console->buf[s] == '\r') { + /* TODO: work backwards through the buffer to the start of the current line */ + //console->cx = 0; + } else { + if(console->cx >= console->sx) { + console->cx = 0; + console->cy += console->fy; + } - if(console->cx > console->sx) { - /* character has extended beyond end of line */ - redraw = TRUE; - } + if((console->cy + console->fy) >= console->sy) { + /* we've gone beyond the end of the console */ + //console->full = TRUE; + //return RDY_RESET; + /* start at beginning of buffer and remove the first line */ - if(redraw && console->cy == console->sy) { + /* increment s from bstrt until it has been incremented more than + * console->sx or finds a new line */ + s = console->bstrt; + console->cx = 0; - /* we've gone past the end of the console */ - console->full = TRUE; - return RDY_RESET; - /* start at beginning of buffer and remove the first line */ - uint16_t i; + while((console->cx <= console->sx) && (console->buf[s % console->blen] != '\n')) { + s++; + /* TODO: increment based on the width of the character at s */ + /* TODO: this doesn't handle carriage return */ + console->cx += width; + } - /* increment i from bstrt until it has been incremented more than console->sx or finds a new line */ - for(i = console->bstrt; ((i - console->bstrt) < console->sx) && (console->buf[i % console->sx] != '\n'); i++); + /* update bstrt to the new start point of the console */ + console->bstrt = s; - /* update bstrt to the new start point of the console */ - console->bstrt = i; - } else { - /* just draw the character at the current position */ - lcdMoveCursor(console->x0 + console->cx*console->fx, console->y0 + console->cy*console->fy, - console->color, console->bkcolor); + /* reset the cursor */ + console->cx = 0; + console->cy = 0; + } + lcdMoveCursor(console->x0 + console->cx, console->y0 + console->cy, + console->color, console->bkcolor); + lcdDrawChar(console->buf[s]); + + /* update cursor */ + console->cx += width; + } + + /* finally increment index */ + if(++s == console->blen) + s = 0; + + } while(s != console->wptr); - lcdSetFont(console->font); - lcdDrawChar(c); - } } msg_t lcdConsoleWrite(GLCDConsole *console, uint8_t *bp, size_t n) { diff --git a/console.h b/console.h index 06320853..10e061ff 100644 --- a/console.h +++ b/console.h @@ -48,7 +48,7 @@ struct GLCDConsole { /* font size in pixels */ uint8_t fx,fy; /* buffer index */ - uint16_t bidx, blen, bstrt; + uint16_t wptr, blen, bstrt; bool_t full; }; From 23a3bf0efa969cf8f3443c6b148fa7f2b6cd74af Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Sat, 23 Jun 2012 23:04:35 +0100 Subject: [PATCH 05/17] clear the end of lines when shifting down --- console.c | 26 ++++++++++---------------- console.h | 9 ++++----- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/console.c b/console.c index 4e21a795..96793bad 100644 --- a/console.c +++ b/console.c @@ -78,13 +78,9 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 uint16_t x,y; console->vmt = &vmt; - /* read font, get size */ - /* TODO: this is messy. improve font handling. - * this assumes that all characters are as wide as A */ + /* read font, get height */ console->fy = font[FONT_TABLE_HEIGHT_IDX]; - chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + ('A'-0x20)*2]); - ptr = font + chi; - console->fx = *(ptr++); + /* calculate the size of the console in characters */ console->sx = (x1-x0); @@ -104,7 +100,6 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 console->color = color; console->font = font; - console->full = FALSE; } msg_t lcdConsoleUpdate(GLCDConsole *console) { @@ -112,15 +107,11 @@ msg_t lcdConsoleUpdate(GLCDConsole *console) { } msg_t lcdConsolePut(GLCDConsole *console, char c) { - uint8_t width = console->fx; uint16_t i; uint16_t s = console->wptr; + uint8_t width; bool_t redraw = FALSE; - if(console->full) { - return RDY_RESET; - } - /* write character to current position in buffer and update wptr */ console->buf[console->wptr] = c; @@ -137,22 +128,25 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { * checks to see if this is out of range will be performed at the start of that character */ do { + width = lcdMeasureChar(console->buf[s]); if(console->buf[s] == '\n') { + /* clear the text at the end of the line */ + if(console->cx < console->sx) + lcdDrawRect(console->cx, console->cy, console->sx, console->cy + console->fy, + 1, console->bkcolor); console->cx = 0; console->cy += console->fy; } else if(console->buf[s] == '\r') { /* TODO: work backwards through the buffer to the start of the current line */ //console->cx = 0; } else { - if(console->cx >= console->sx) { + if((console->cx + width) >= console->sx) { console->cx = 0; console->cy += console->fy; } if((console->cy + console->fy) >= console->sy) { /* we've gone beyond the end of the console */ - //console->full = TRUE; - //return RDY_RESET; /* start at beginning of buffer and remove the first line */ /* increment s from bstrt until it has been incremented more than @@ -164,7 +158,7 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { s++; /* TODO: increment based on the width of the character at s */ /* TODO: this doesn't handle carriage return */ - console->cx += width; + console->cx += lcdMeasureChar(console->buf[s % console->blen]); } /* update bstrt to the new start point of the console */ diff --git a/console.h b/console.h index 10e061ff..13b77605 100644 --- a/console.h +++ b/console.h @@ -38,18 +38,17 @@ struct GLCDConsole { /* font */ const uint8_t *font; /* lcd area to use */ - uint16_t x0,y0,x1,y1; - /* current cursor position, in character coordinates (not pixels) */ + uint16_t x0,y0; + /* current cursor position, in pixels */ uint16_t cx,cy; - /* console size in characters */ + /* console size in pixels */ uint16_t sx,sy; /* foreground and background colour */ uint16_t bkcolor, color; /* font size in pixels */ - uint8_t fx,fy; + uint8_t fy; /* buffer index */ uint16_t wptr, blen, bstrt; - bool_t full; }; #ifdef __cplusplus From 08a70cc3ce9fde4e9dd89db1ab7f60330cf7af4e Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Sun, 24 Jun 2012 17:25:44 +0100 Subject: [PATCH 06/17] remove BaseSyncronousStream interface from GLCDDriver --- glcd.c | 99 ++++++++++------------------------------------------------ glcd.h | 27 +--------------- 2 files changed, 17 insertions(+), 109 deletions(-) diff --git a/glcd.c b/glcd.c index 4ff40d1d..26306582 100644 --- a/glcd.c +++ b/glcd.c @@ -3,73 +3,6 @@ #include #include -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/* - * Interface implementation. The interface is write only - */ - -static size_t writes(void *ip, const uint8_t *bp, size_t n) { - (void)ip; - return lcdWriteString(bp, n); -} - -static size_t reads(void *ip, uint8_t *bp, size_t n) { - (void)ip; - (void)bp; - (void)n; - return 0; -} - -static msg_t put(void *ip, uint8_t b) { - (void)ip; - return lcdDrawChar((char)b); -} - -static msg_t get(void *ip) { - (void)ip; - return RDY_OK; -} - -static msg_t putt(void *ip, uint8_t b, systime_t timeout) { - (void)ip; - (void)timeout; - /* TODO: handle timeout */ - return lcdDrawChar((char)b); -} - -static msg_t gett(void *ip, systime_t timeout) { - (void)ip; - (void)timeout; - return RDY_OK; -} - -static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) { - (void)ip; - (void)time; - return lcdWriteString(bp, n); -} - -static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) { - (void)ip; - (void)bp; - (void)n; - (void)time; - return 0; -} - -static chnflags_t getflags(void *ip) { - _chn_get_and_clear_flags_impl(ip); -} - -static const struct GLCDDriverVMT vmt = { - writes, reads, put, get, - putt, gett, writet, readt, - getflags -}; - uint16_t lcd_width, lcd_height; uint16_t bgcolor = White, fgcolor = Black; uint16_t cx = 0, cy = 0; @@ -77,7 +10,6 @@ static uint8_t tpText = 0; const uint8_t* font; void lcdInit(GLCDDriver *glcdp) { - glcdp->vmt = &vmt; lld_lcdInit(); lcd_width = SCREEN_WIDTH; @@ -116,6 +48,14 @@ void lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co lld_lcdFillArea(x0, y0, x1, y1, color); } +void lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n) { + lld_lcdSetWindow(x0, y0, x1, y1); + + lld_lcdWriteStreamStart(); + lld_lcdWriteStream(buffer, n); + lld_lcdWriteStreamStop(); +} + void lcdClear(uint16_t color) { lld_lcdClear(color); } @@ -203,11 +143,11 @@ msg_t lcdDrawChar(char c) { uint8_t sps = font[FONT_TABLE_PAD_AFTER_CHAR_IDX]; uint16_t chi; uint16_t x,y; + uint16_t buf[20*16]; + // No support for nongraphic characters, so just ignore them if(c < 0x20 || c > 0x7F) { - if(c == '\n') - lcdLineBreak(); return RDY_OK; } @@ -217,28 +157,21 @@ msg_t lcdDrawChar(char c) { uint8_t fontWidth = *(ptr++); - if(cx + fontWidth > lcdGetWidth()) - lcdLineBreak(); - for(x = 0; x < fontWidth; x++) { chi = *(uint16_t*)ptr; for(y = 0; y < fontHeight; y++) { - if(chi & 0x01) + if(!tpText) { + buf[y*fontWidth+x] = (chi & 0x01) ? fgcolor : bgcolor; + } else { lcdDrawPixel(cx+x, cy+y, fgcolor); - else if(!tpText) - lcdDrawPixel(cx+x, cy+y, bgcolor); - + } chi >>= 1; } ptr += 2; } - cx += fontWidth; - if(sps != 0) { - if(!tpText) - lcdFillArea(cx, cy, cx+sps, cy+fontHeight, bgcolor); - cx += sps; - } + if(!tpText) + lcdWriteArea(cx, cy, cx+fontWidth, cy+fontHeight, buf, fontWidth*fontHeight); /* TODO: proper return codes */ return RDY_OK; diff --git a/glcd.h b/glcd.h index bda5013d..4cb859ed 100644 --- a/glcd.h +++ b/glcd.h @@ -46,33 +46,7 @@ extern const uint8_t* font; */ typedef struct GLCDDriver GLCDDriver; -/** - * @brief @p GLCDDriver specific methods. - */ -#define _glcd_driver_methods \ - _base_asynchronous_channel_methods - -/** - * @extends BaseAsynchronousChannelVMT - * - * @brief @p GLCDDriver virtual methods table. - */ -struct GLCDDriverVMT { - _glcd_driver_methods -}; - -/** - * @extends BaseAsynchronousChannel - * - * @brief GLCD driver class. - * @details This class extends @p BaseAsynchronousChannel by adding physical - * I/O queues. - */ struct GLCDDriver { - /** @brief Virtual Methods Table.*/ - const struct GLCDDriverVMT *vmt; - _base_asynchronous_channel_data - /* WARNING: Do not add any data to this struct above this comment, only below */ }; #ifdef __cplusplus @@ -86,6 +60,7 @@ void lcdClear(uint16_t color); void lcdSetOrientation(uint8_t newOrientation); void lcdSetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); void lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color); +void lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n); void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t point); void lcdDrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color); From 79f7278f3df0c377390653fdab3496371fb1cc66 Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Mon, 25 Jun 2012 13:57:42 +0100 Subject: [PATCH 07/17] add vertical scroll functions --- console.c | 93 ++++++++++++--------------------------- drivers/lcd/s6d1121_lld.c | 10 +++++ drivers/lcd/s6d1121_lld.h | 1 + drivers/lcd/ssd1289_lld.c | 15 +++++++ drivers/lcd/ssd1289_lld.h | 1 + glcd.c | 6 +++ glcd.h | 7 +++ 7 files changed, 69 insertions(+), 64 deletions(-) diff --git a/console.c b/console.c index 96793bad..782c7fbb 100644 --- a/console.c +++ b/console.c @@ -84,7 +84,7 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 /* calculate the size of the console in characters */ console->sx = (x1-x0); - console->sy = (y1-y0); + console->sy = ((int16_t)((y1-y0)/console->fy))*console->fy; console->cx = 0; console->cy = 0; @@ -107,80 +107,45 @@ msg_t lcdConsoleUpdate(GLCDConsole *console) { } msg_t lcdConsolePut(GLCDConsole *console, char c) { - uint16_t i; - uint16_t s = console->wptr; uint8_t width; bool_t redraw = FALSE; - /* write character to current position in buffer and update wptr */ - console->buf[console->wptr] = c; - - if(++console->wptr == console->blen) { - /* wrap around to the beginning */ - console->wptr = 0; - } lcdSetFont(console->font); lcdSetFontTransparency(solid); - /* keep looping until we've finished writing - * we may write more than one character if the console needs to be re-drawn - * at the end of the loop leave the cursor set to the position for the next character - * checks to see if this is out of range will be performed at the start of that character - */ - do { - width = lcdMeasureChar(console->buf[s]); - if(console->buf[s] == '\n') { - /* clear the text at the end of the line */ - if(console->cx < console->sx) - lcdDrawRect(console->cx, console->cy, console->sx, console->cy + console->fy, - 1, console->bkcolor); + + if(c == '\n') { + /* clear the text at the end of the line */ + if(console->cx < console->sx) + lcdDrawRect(console->cx, console->cy, console->sx, console->cy + console->fy, + 1, console->bkcolor); + console->cx = 0; + console->cy += console->fy; + } else if(c == '\r') { + /* TODO: work backwards through the buffer to the start of the current line */ + //console->cx = 0; + } else { + width = lcdMeasureChar(c); + if((console->cx + width) >= console->sx) { console->cx = 0; console->cy += console->fy; - } else if(console->buf[s] == '\r') { - /* TODO: work backwards through the buffer to the start of the current line */ - //console->cx = 0; - } else { - if((console->cx + width) >= console->sx) { - console->cx = 0; - console->cy += console->fy; - } - - if((console->cy + console->fy) >= console->sy) { - /* we've gone beyond the end of the console */ - /* start at beginning of buffer and remove the first line */ - - /* increment s from bstrt until it has been incremented more than - * console->sx or finds a new line */ - s = console->bstrt; - console->cx = 0; - - while((console->cx <= console->sx) && (console->buf[s % console->blen] != '\n')) { - s++; - /* TODO: increment based on the width of the character at s */ - /* TODO: this doesn't handle carriage return */ - console->cx += lcdMeasureChar(console->buf[s % console->blen]); - } - - /* update bstrt to the new start point of the console */ - console->bstrt = s; - - /* reset the cursor */ - console->cx = 0; - console->cy = 0; - } - lcdMoveCursor(console->x0 + console->cx, console->y0 + console->cy, - console->color, console->bkcolor); - lcdDrawChar(console->buf[s]); - - /* update cursor */ - console->cx += width; } - /* finally increment index */ - if(++s == console->blen) - s = 0; + if((console->cy + console->fy) >= console->sy) { + lcdVerticalScroll(console->x0, console->y0, console->x0 + console->sx, + console->y0 + console->sy, console->fy); + /* reset the cursor */ + console->cx = 0; + while((console->cy) >= console->sy) + console->cy -= console->fy; + } + lcdMoveCursor(console->x0 + console->cx, console->y0 + console->cy, + console->color, console->bkcolor); + lcdDrawChar(c); - } while(s != console->wptr); + /* update cursor */ + console->cx += width; + } } diff --git a/drivers/lcd/s6d1121_lld.c b/drivers/lcd/s6d1121_lld.c index f7268126..7f842e33 100644 --- a/drivers/lcd/s6d1121_lld.c +++ b/drivers/lcd/s6d1121_lld.c @@ -350,5 +350,15 @@ uint16_t lld_lcdGetWidth(void) { return lcd_width; } +void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { + lld_lcdSetWindow(x0, y0, x1, y1); + + /* if negative shift, then subtract from the height of the area */ + lines = (lines < 0) ? ((y1-y0) + lines) : lines; + + /* TODO: implement */ +} + + #endif diff --git a/drivers/lcd/s6d1121_lld.h b/drivers/lcd/s6d1121_lld.h index 24e207e8..8c4e7057 100644 --- a/drivers/lcd/s6d1121_lld.h +++ b/drivers/lcd/s6d1121_lld.h @@ -42,6 +42,7 @@ uint16_t lld_lcdGetPixelColor(uint16_t x, uint16_t y); uint16_t lld_lcdGetOrientation(void); uint16_t lld_lcdGetHeight(void); uint16_t lld_lcdGetWidth(void); +void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines); #ifdef __cplusplus } diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index ac4d050f..85250baf 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -334,5 +334,20 @@ uint16_t lld_lcdGetWidth(void) { return lcd_width; } +#include "chprintf.h" + +void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { + lld_lcdSetWindow(x0, y0, x1, y1); + + /* if negative shift, then subtract from the height of the area */ + lines = (lines < 0) ? ((y1-y0) + lines) : lines; + + /* driver accepts only 9 bit line value */ + lld_lcdWriteReg(0x0041, (uint16_t)lines & 0x01FF); + + /* enable the scroll */ + lld_lcdWriteReg(0x0007, (0x0001 << 9) | 0x0133); +} + #endif diff --git a/drivers/lcd/ssd1289_lld.h b/drivers/lcd/ssd1289_lld.h index f1f07937..787b7d38 100644 --- a/drivers/lcd/ssd1289_lld.h +++ b/drivers/lcd/ssd1289_lld.h @@ -146,6 +146,7 @@ uint16_t lld_lcdGetPixelColor(uint16_t x, uint16_t y); uint16_t lld_lcdGetOrientation(void); uint16_t lld_lcdGetHeight(void); uint16_t lld_lcdGetWidth(void); +void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines); #ifdef __cplusplus } diff --git a/glcd.c b/glcd.c index 26306582..2a6535af 100644 --- a/glcd.c +++ b/glcd.c @@ -330,3 +330,9 @@ void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint } while(a <= b); } +void lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { + lld_lcdVerticalScroll(x0,y0,x1,y1,lines); +} + + + diff --git a/glcd.h b/glcd.h index 4cb859ed..cf4c44a7 100644 --- a/glcd.h +++ b/glcd.h @@ -4,6 +4,11 @@ #include "ch.h" #include "hal.h" #include "fonts.h" + +#if !defined(LCD_USE_FSMC) | !defined(LCD_USE_GPIO) | !defined(LCD_USE_SPI) +#include "glcdconf.h" +#endif + #include "ssd1289_lld.h" #include "s6d1121_lld.h" @@ -87,6 +92,8 @@ uint16_t lcdGetOrientation(void); uint16_t lcdBGR2RGB(uint16_t color); uint16_t lcdGetPixelColor(uint16_t x, uint16_t y); +void lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines); + #ifdef __cplusplus } #endif From a51bb1bf5f298168d9b0964bf3a68a1090f8d00c Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Mon, 25 Jun 2012 18:51:35 +0100 Subject: [PATCH 08/17] merge Abhishek's changes, small fixes for API changes --- console.c | 14 ++--- console.h | 6 +- glcd.c | 182 +++++++++++++++++++++++++---------------------------- glcd.h | 34 +++++----- gui.c | 4 +- gui.h | 4 +- touchpad.c | 4 +- 7 files changed, 116 insertions(+), 132 deletions(-) diff --git a/console.c b/console.c index 782c7fbb..08ee17d2 100644 --- a/console.c +++ b/console.c @@ -72,7 +72,7 @@ static const struct GLCDConsoleVMT vmt = { msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, - uint16_t y1, const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { + uint16_t y1, font_t font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { const uint8_t* ptr; uint16_t chi; uint16_t x,y; @@ -110,10 +110,6 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { uint8_t width; bool_t redraw = FALSE; - - lcdSetFont(console->font); - lcdSetFontTransparency(solid); - if(c == '\n') { /* clear the text at the end of the line */ if(console->cx < console->sx) @@ -125,7 +121,7 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { /* TODO: work backwards through the buffer to the start of the current line */ //console->cx = 0; } else { - width = lcdMeasureChar(c); + width = lcdMeasureChar(c, console->font); if((console->cx + width) >= console->sx) { console->cx = 0; console->cy += console->fy; @@ -139,9 +135,9 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { while((console->cy) >= console->sy) console->cy -= console->fy; } - lcdMoveCursor(console->x0 + console->cx, console->y0 + console->cy, - console->color, console->bkcolor); - lcdDrawChar(c); + + lcdDrawChar(console->x0 + console->cx, console->y0 + console->cy, c, + console->font, console->color, console->bkcolor, solid); /* update cursor */ console->cx += width; diff --git a/console.h b/console.h index 13b77605..0ed2f51c 100644 --- a/console.h +++ b/console.h @@ -1,6 +1,8 @@ #ifndef CONSOLE_H #define CONSOLE_H +#include "glcd.h" + /** * @brief Structure representing a GLCD driver. */ @@ -36,7 +38,7 @@ struct GLCDConsole { /* text buffer */ uint8_t *buf; /* font */ - const uint8_t *font; + font_t font; /* lcd area to use */ uint16_t x0,y0; /* current cursor position, in pixels */ @@ -56,7 +58,7 @@ extern "C" { #endif msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, - const uint8_t *font, uint8_t *buffer, uint16_t bkcolor, uint16_t color); + font_t font, uint8_t *buffer, uint16_t bkcolor, uint16_t color); msg_t lcdConsolePut(GLCDConsole *console, char c); msg_t lcdConsoleWrite(GLCDConsole *console, uint8_t *bp, size_t n); diff --git a/glcd.c b/glcd.c index 2a6535af..1a77af1b 100644 --- a/glcd.c +++ b/glcd.c @@ -4,10 +4,6 @@ #include uint16_t lcd_width, lcd_height; -uint16_t bgcolor = White, fgcolor = Black; -uint16_t cx = 0, cy = 0; -static uint8_t tpText = 0; -const uint8_t* font; void lcdInit(GLCDDriver *glcdp) { @@ -16,8 +12,6 @@ void lcdInit(GLCDDriver *glcdp) { lcd_height = SCREEN_HEIGHT; lcdSetOrientation(portrait); - lcdSetFontTransparency(transparent); - lcdSetFont(font_MediumBold); } uint16_t lcdGetHeight(void) { @@ -129,128 +123,122 @@ void lcdDrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t co } } -void lcdSetFont(const uint8_t *newFont) { - font = newFont; -} - -void lcdSetFontTransparency(uint8_t transparency) { - tpText = transparency; -} - -msg_t lcdDrawChar(char c) { +int lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText) { + /* Working pointer */ const uint8_t* ptr; - uint8_t fontHeight = lcdGetCurFontHeight(); - uint8_t sps = font[FONT_TABLE_PAD_AFTER_CHAR_IDX]; - uint16_t chi; - uint16_t x,y; - uint16_t buf[20*16]; + uint8_t x, y; + + /* Variables to store character details */ + uint8_t charWidth; + uint8_t charHeight = lcdGetFontHeight(font); + uint8_t padAfterChar = font[FONT_TABLE_PAD_AFTER_CHAR_IDX]; + + /* Local var to hold offset in font table */ + uint16_t charStartOffset; + /* Working buffer for fast non-transparent text rendering [patch by Badger] */ + static uint16_t buf[20*16]; - // No support for nongraphic characters, so just ignore them + /* No support for nongraphic characters, so just ignore them */ if(c < 0x20 || c > 0x7F) { return RDY_OK; } - chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c-0x20)*2]); + /* Read the offset of the character data in the font table from the lookup table */ + charStartOffset = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c - 0x20) * 2]); - ptr = font + chi; + /* After we're done, position the pointer at the offset. + * The first byte that is immediately read will be the font width + * After that, actual 16-bit font data follows, first column down */ + ptr = font + charStartOffset; + charWidth = *(ptr++); - uint8_t fontWidth = *(ptr++); - - for(x = 0; x < fontWidth; x++) { - chi = *(uint16_t*)ptr; - for(y = 0; y < fontHeight; y++) { + /* Loop through the data and display. The font data is LSB first, down the column */ + for(x = 0; x < charWidth; x++) { + /* Get the font bitmap data for the column */ + uint16_t charData = *(uint16_t*)ptr; + + for(y = 0; y < charHeight; y++) { + /* Draw the LSB on the screen accordingly. */ if(!tpText) { - buf[y*fontWidth+x] = (chi & 0x01) ? fgcolor : bgcolor; + /* Store data into working buffer (patch by Badger), + * Then write it all onto the LCD in one stroke */ + buf[y*charWidth + x] = (charData & 0x01) ? color : bkcolor; } else { - lcdDrawPixel(cx+x, cy+y, fgcolor); + /* Just draw the needed pixels onto the LCD */ + if (charData & 0x01) + lcdDrawPixel(cx+x, cy+y, color); } - chi >>= 1; + + /* Shift the data down by one bit */ + charData >>= 1; } + + /* Increment pointer by 2 bytes to the next column */ ptr += 2; } - if(!tpText) - lcdWriteArea(cx, cy, cx+fontWidth, cy+fontHeight, buf, fontWidth*fontHeight); - - /* TODO: proper return codes */ - return RDY_OK; -} - -size_t lcdWriteString(const char *str, size_t n) { - size_t l = 0; - for(l = 0; l < n; l++) { - if(lcdDrawChar(*str++) != RDY_OK) - break; + if(!tpText) { + /* [Patch by Badger] Write all in one stroke */ + lcdWriteArea(cx, cy, cx+charWidth, cy+charHeight, buf, charWidth*charHeight); + + /* Do padding after character, if needed for solid text rendering + * TODO: To be optimised */ + if (padAfterChar != 0) { + lcdFillArea(cx+charWidth, cy+charHeight, cx+charWidth+padAfterChar, cy+charHeight, bkcolor); + } } - return l; + /* Return the width of the character, we need it so that lcdDrawString may work + * We don't have a static address counter */ + + /* Abhishek: what should padAfter be? + * return charWidth+padAfter; + */ + return charWidth; } -size_t lcdPutString(const char *str) { - size_t l = 0; - while(*str) { - if(lcdDrawChar(*str++) != RDY_OK) - break; - - l++; +/* WARNING: No boundary checks! Unpredictable behaviour if text exceeds boundary */ +void lcdDrawString(uint16_t x, uint16_t y, const char *str, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText) { + uint16_t cx=x, cy=y; + + while (*str) { + cx += lcdDrawChar(cx, cy, *str++, font, color, bkcolor, tpText); } - - return l; } -void lcdMoveCursor(uint16_t x, uint16_t y, uint16_t color, uint16_t bkcolor) { - cx = x; - cy = y; - bgcolor = bkcolor; - fgcolor = color; -} +uint16_t lcdMeasureChar(char c, font_t font) { + /* Variables to store character details */ + uint8_t charWidth; + uint8_t padAfterChar = font[FONT_TABLE_PAD_AFTER_CHAR_IDX]; + + /* Local var to hold offset in font table */ + uint16_t charStartOffset; -void lcdDrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bkcolor) { - uint16_t _bg = bgcolor, _fg = fgcolor; - cx = x; - cy = y; - bgcolor = bkcolor; - fgcolor = color; - lcdPutString(str); - bgcolor = _bg; - fgcolor = _fg; -} - -uint16_t lcdMeasureChar(char c) { - const uint8_t *ptr; - - // First get spaces after each character, usually 0 but can change - uint8_t sps = font[FONT_TABLE_PAD_AFTER_CHAR_IDX]; - - uint16_t chi; - - if(c < 0x20 || c > 0x7F) + /* No support for nongraphic characters, so just ignore them */ + if(c < 0x20 || c > 0x7F) { return 0; + } - chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c-0x20)*2]); + /* Read the offset of the character data in the font table from the lookup table */ + charStartOffset = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c - 0x20) * 2]); - ptr = font + chi; - - uint8_t fontWidth = *(ptr++); - - return fontWidth + sps; + /* Retrurn the byte at the offset, that's our charWidth */ + charWidth = *(font + charStartOffset); + + return charWidth+padAfterChar; } -uint16_t lcdMeasureString(const char *str) { +uint16_t lcdMeasureString(const char *str, font_t font) { uint16_t result = 0; - while (*str)result += lcdMeasureChar(*str++); + /* Measure each char width, add it, return the result */ + while (*str) + result += lcdMeasureChar(*str++, font); return result; } -void lcdLineBreak() { - // x=0 seems too much on the edge. So I keep it at 3 - cx = 3; - cy += lcdGetCurFontHeight(); -} - uint16_t lcdBGR2RGB(uint16_t color) { uint16_t r, g, b, rgb; @@ -289,15 +277,15 @@ void lcdDrawRect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t fil } } -void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char *str, uint16_t fontColor, uint16_t bkColor) { +void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char* str, font_t font, uint16_t fontColor, uint16_t bkColor) { uint16_t off_left, off_up; - off_left = ((x1-x0)-lcdMeasureString(str))/2; + off_left = ((x1-x0)-lcdMeasureString(str, font))/2; off_up = ((y1-y0) - lcdGetCurFontHeight()) / 2; lcdDrawRect(x0, y0, x1, y1, 1, bkColor); - - lcdDrawString(x0+off_left, y0+off_up, str, fontColor, bkColor); + /* Abhishek: default to solid text for this? */ + lcdDrawString(x0+off_left, y0+off_up, str, font, fontColor, bkColor, solid); } void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint16_t color) { diff --git a/glcd.h b/glcd.h index cf4c44a7..0b4bbdca 100644 --- a/glcd.h +++ b/glcd.h @@ -5,7 +5,7 @@ #include "hal.h" #include "fonts.h" -#if !defined(LCD_USE_FSMC) | !defined(LCD_USE_GPIO) | !defined(LCD_USE_SPI) +#if !defined(LCD_USE_FSMC) && !defined(LCD_USE_GPIO) && !defined(LCD_USE_SPI) #include "glcdconf.h" #endif @@ -37,14 +37,10 @@ enum orientation {portrait, landscape, portraitInv, landscapeInv}; enum filled {frame, filled}; enum transparency {solid, transparent}; -// For text rendering only -extern uint16_t bgcolor, fgcolor; -extern uint16_t cx, cy; -extern const uint8_t* font; +typedef const uint8_t* font_t; // A few macros -#define lcdGotoXY(x,y) { cx=x; cy=y; } -#define lcdGetCurFontHeight() (font[FONT_TABLE_HEIGHT_IDX]) +#define lcdGetFontHeight(font) (font[FONT_TABLE_HEIGHT_IDX]) /** * @brief Structure representing a GLCD driver. @@ -58,7 +54,7 @@ struct GLCDDriver { extern "C" { #endif - +/* Core functions */ void lcdInit(GLCDDriver *); void lcdClear(uint16_t color); @@ -67,31 +63,31 @@ void lcdSetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); void lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color); void lcdWriteArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *buffer, size_t n); +/* Drawing functions */ void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t point); void lcdDrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color); void lcdDrawRect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t filled, uint16_t color); -void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char* str, uint16_t fontColor, uint16_t bkColor); +void lcdDrawRectString(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const char* str, font_t font, uint16_t fontColor, uint16_t bkColor); void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint16_t color); -void lcdSetFontTransparency(uint8_t transparency); -void lcdSetFont(const uint8_t *newFont); -void lcdMoveCursor(uint16_t x, uint16_t y, uint16_t color, uint16_t bkcolor); -msg_t lcdDrawChar(char c); -size_t lcdWriteString(const char *str, size_t n); -size_t lcdPutString(const char *str); -void lcdDrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bkcolor); -void lcdLineBreak(void); +/* Text Rendering Functions */ +int lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText); +void lcdDrawString(uint16_t x, uint16_t y, const char *str, font_t font, uint16_t color, uint16_t bkcolor, bool_t tpText); -uint16_t lcdMeasureChar(char c); -uint16_t lcdMeasureString(const char* str); +/* Character measuring functions */ +uint16_t lcdMeasureChar(char c, font_t font); +uint16_t lcdMeasureString(const char* str, font_t font); +/* Size and orientation related */ uint16_t lcdGetHeight(void); uint16_t lcdGetWidth(void); uint16_t lcdGetOrientation(void); +/* BGR->RGB and pixel readback */ uint16_t lcdBGR2RGB(uint16_t color); uint16_t lcdGetPixelColor(uint16_t x, uint16_t y); +/* Scrolling function */ void lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines); #ifdef __cplusplus diff --git a/gui.c b/gui.c index 1d162d54..16a29098 100644 --- a/gui.c +++ b/gui.c @@ -68,7 +68,7 @@ void guiInit(uint16_t updateInterval) { tp = chThdCreateFromHeap(NULL, THD_WA_SIZE(64), HIGHPRIO-1, TouchPadThread, updateInterval); } -Thread *guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, unsigned char *str, uint16_t fontColor, uint16_t buttonColor, uint16_t interval, uint8_t *state) { +Thread *guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, unsigned char *str, font_t font, uint16_t fontColor, uint16_t buttonColor, uint16_t interval, uint8_t *state) { struct button_t *button; Thread *tp = NULL; @@ -80,7 +80,7 @@ Thread *guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, unsign button->state = state; button->interval = interval; - lcdDrawRectString(x0, y0, x1, y1, str, fontColor, buttonColor); + lcdDrawRectString(x0, y0, x1, y1, str, font, fontColor, buttonColor); tp = chThdCreateFromHeap(NULL, THD_WA_SIZE(64), NORMALPRIO, buttonThread, button); return tp; diff --git a/gui.h b/gui.h index d0ec128a..b4a0ee56 100644 --- a/gui.h +++ b/gui.h @@ -1,6 +1,8 @@ #ifndef GUI_H #define GUI_H +#include "glcd.h" + struct button_t { uint16_t x0; uint16_t y0; @@ -53,7 +55,7 @@ void guiInit(uint16_t updateIntervl); * * return: pointer to created thread */ -Thread *guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, unsigned char *str, uint16_t fontColor, uint16_t buttonColor, uint16_t inverval, uint8_t *state); +Thread *guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, unsigned char *str, font_t font, uint16_t fontColor, uint16_t buttonColor, uint16_t inverval, uint8_t *state); /* * Description: draws a bar graph and updates it's value diff --git a/touchpad.c b/touchpad.c index 3f355ead..4829ed4a 100644 --- a/touchpad.c +++ b/touchpad.c @@ -126,8 +126,8 @@ void tpCalibrate(void) { lcdSetOrientation(portrait); lcdClear(Red); - cx=40; cy=10; - lcdDrawString(40, 10, "Touchpad Calibration", White, Red); + /* Abhishek: need to specify a font to use here, should probably make sure it exists somehow */ + lcdDrawString(40, 10, "Touchpad Calibration", font_Larger, White, Red, solid); for(i=0; i<2; i++) { tpDrawCross(cross[i][0], cross[i][1]); From d96a491d321c7f668994d05e5a2ac7c119fb9f5b Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Mon, 25 Jun 2012 21:29:51 +0100 Subject: [PATCH 09/17] work in progress for partial area scroll --- console.c | 24 +++++++++++-------- drivers/lcd/ssd1289_lld.c | 50 ++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/console.c b/console.c index 08ee17d2..4d245a70 100644 --- a/console.c +++ b/console.c @@ -84,7 +84,7 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 /* calculate the size of the console in characters */ console->sx = (x1-x0); - console->sy = ((int16_t)((y1-y0)/console->fy))*console->fy; + console->sy = (((int16_t)((y1-y0)/console->fy))-1)*console->fy; console->cx = 0; console->cy = 0; @@ -102,13 +102,10 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 console->font = font; } -msg_t lcdConsoleUpdate(GLCDConsole *console) { - -} - msg_t lcdConsolePut(GLCDConsole *console, char c) { uint8_t width; - bool_t redraw = FALSE; + bool_t newline = FALSE; + if(c == '\n') { /* clear the text at the end of the line */ @@ -123,19 +120,26 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { } else { width = lcdMeasureChar(c, console->font); if((console->cx + width) >= console->sx) { + chprintf(&SD1, "[1] "); console->cx = 0; console->cy += console->fy; } - if((console->cy + console->fy) >= console->sy) { + if( + (console->cy > console->sy)) { + chprintf(&SD1, "[2] "); + if(newline) + chprintf(&SD1, "* "); lcdVerticalScroll(console->x0, console->y0, console->x0 + console->sx, console->y0 + console->sy, console->fy); /* reset the cursor */ console->cx = 0; - while((console->cy) >= console->sy) - console->cy -= console->fy; + console->cy = console->sy; + } else if(newline) { + chprintf(&SD1, "[3] "); + console->cy += console->fy; } - + //chprintf(&SD1, "'%c' at [%d, %d]\r\n", c, console->x0 + console->cx, console->y0 + console->cy); lcdDrawChar(console->x0 + console->cx, console->y0 + console->cy, c, console->font, console->color, console->bkcolor, solid); diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index 85250baf..3ea4806c 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -6,6 +6,9 @@ uint8_t orientation; uint16_t DeviceCode; extern uint16_t lcd_width, lcd_height; +/* TODO: use max(height, width) */ +static uint16_t buf[SCREEN_HEIGHT]; + #ifdef LCD_USE_GPIO static __inline void lld_lcdWriteIndex(uint16_t index) { Clr_RS; @@ -131,6 +134,21 @@ __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { for(i = 0; i < size; i++) LCD_RAM = buffer[i]; } + +__inline void lld_lcdReadStreamStart(void) { + LCD_REG = 0x0022; +} + +__inline void lld_lcdReadStreamStop(void) { + +} + +__inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + uint16_t i; + for(i = 0; i < size; i++) { + buffer[i] = LCD_RAM; + } +} #endif #ifdef LCD_USE_SPI @@ -146,10 +164,10 @@ static __inline void lcdDelay(uint16_t us) { void lld_lcdSetCursor(uint16_t x, uint16_t y) { if(PORTRAIT) { lld_lcdWriteReg(0x004e, x); - lld_lcdWriteReg(0x004f, y); + lld_lcdWriteReg(0x004f, y); } else if(LANDSCAPE) { lld_lcdWriteReg(0x004e, y); - lld_lcdWriteReg(0x004f, x); + lld_lcdWriteReg(0x004f, x); } } @@ -336,17 +354,31 @@ uint16_t lld_lcdGetWidth(void) { #include "chprintf.h" +/* a positive lines value shifts the screen up, negative down */ void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { + uint16_t row0, row1; + uint16_t i; lld_lcdSetWindow(x0, y0, x1, y1); - /* if negative shift, then subtract from the height of the area */ - lines = (lines < 0) ? ((y1-y0) + lines) : lines; + for(i = 0; i < ((y1-y0) - abs(lines)); i++) { + if(lines > 0) { + row0 = y0 + i + lines; + row1 = y0 + i; + } else { + row0 = (y1 - i - 1) + lines; + row1 = (y1 - i - 1); + } + /* read row0 into the buffer and then write at row1*/ + lld_lcdSetWindow(x0, row0, x1, row0); + lld_lcdReadStreamStart(); + lld_lcdReadStream(buf, x1-x0); + lld_lcdReadStreamStop(); - /* driver accepts only 9 bit line value */ - lld_lcdWriteReg(0x0041, (uint16_t)lines & 0x01FF); - - /* enable the scroll */ - lld_lcdWriteReg(0x0007, (0x0001 << 9) | 0x0133); + lld_lcdSetWindow(x0, row1, x1, row1); + lld_lcdWriteStreamStart(); + lld_lcdWriteStream(buf, x1-x0); + lld_lcdWriteStreamStop(); + } } #endif From 7f306bab7638b0472fd47f47ed133fe77b41a499 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Mon, 25 Jun 2012 23:46:50 +0100 Subject: [PATCH 10/17] tidy up --- drivers/lcd/ssd1289_lld.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index 3ea4806c..3f98b8de 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -352,8 +352,6 @@ uint16_t lld_lcdGetWidth(void) { return lcd_width; } -#include "chprintf.h" - /* a positive lines value shifts the screen up, negative down */ void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { uint16_t row0, row1; From c10f54e5aff2c465adcb486c1cb7b66ea3c21567 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Tue, 26 Jun 2012 23:58:29 +0100 Subject: [PATCH 11/17] more console work --- console.c | 33 +++++------------- console.h | 8 ++--- drivers/lcd/ssd1289_lld.c | 73 +++++++++++++++++++++++++++++++-------- glcd.c | 6 +--- 4 files changed, 71 insertions(+), 49 deletions(-) diff --git a/console.c b/console.c index 4d245a70..c206ef5f 100644 --- a/console.c +++ b/console.c @@ -71,8 +71,8 @@ static const struct GLCDConsoleVMT vmt = { }; -msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, - uint16_t y1, font_t font, uint8_t *buffer, uint16_t bkcolor, uint16_t color) { +msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t width, uint16_t height, + font_t font, uint16_t bkcolor, uint16_t color) { const uint8_t* ptr; uint16_t chi; uint16_t x,y; @@ -81,21 +81,15 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 /* read font, get height */ console->fy = font[FONT_TABLE_HEIGHT_IDX]; - - /* calculate the size of the console in characters */ - console->sx = (x1-x0); - console->sy = (((int16_t)((y1-y0)/console->fy))-1)*console->fy; + /* calculate the size of the console as an integer multiple of characters */ + console->sx = width; + console->sy = (((int16_t)(height/console->fy))-1)*console->fy; console->cx = 0; console->cy = 0; console->x0 = x0; console->y0 = y0; - console->buf = buffer; - console->wptr = 0; - console->blen = console->sx*console->sy; - console->bstrt = 0; - console->bkcolor = bkcolor; console->color = color; @@ -104,8 +98,6 @@ msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1 msg_t lcdConsolePut(GLCDConsole *console, char c) { uint8_t width; - bool_t newline = FALSE; - if(c == '\n') { /* clear the text at the end of the line */ @@ -120,26 +112,19 @@ msg_t lcdConsolePut(GLCDConsole *console, char c) { } else { width = lcdMeasureChar(c, console->font); if((console->cx + width) >= console->sx) { - chprintf(&SD1, "[1] "); console->cx = 0; console->cy += console->fy; } - if( - (console->cy > console->sy)) { - chprintf(&SD1, "[2] "); - if(newline) - chprintf(&SD1, "* "); + if((console->cy > console->sy)) { + lcdVerticalScroll(console->x0, console->y0, console->x0 + console->sx, - console->y0 + console->sy, console->fy); + console->y0 + console->sy + console->fy, console->fy); /* reset the cursor */ console->cx = 0; console->cy = console->sy; - } else if(newline) { - chprintf(&SD1, "[3] "); - console->cy += console->fy; } - //chprintf(&SD1, "'%c' at [%d, %d]\r\n", c, console->x0 + console->cx, console->y0 + console->cy); + lcdDrawChar(console->x0 + console->cx, console->y0 + console->cy, c, console->font, console->color, console->bkcolor, solid); diff --git a/console.h b/console.h index 0ed2f51c..fcdef293 100644 --- a/console.h +++ b/console.h @@ -35,8 +35,6 @@ struct GLCDConsole { const struct GLCDConsoleVMT *vmt; _base_asynchronous_channel_data /* WARNING: Do not add any data to this struct above this comment, only below */ - /* text buffer */ - uint8_t *buf; /* font */ font_t font; /* lcd area to use */ @@ -49,16 +47,14 @@ struct GLCDConsole { uint16_t bkcolor, color; /* font size in pixels */ uint8_t fy; - /* buffer index */ - uint16_t wptr, blen, bstrt; }; #ifdef __cplusplus extern "C" { #endif -msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, - font_t font, uint8_t *buffer, uint16_t bkcolor, uint16_t color); +msg_t lcdConsoleInit(GLCDConsole *console, uint16_t x0, uint16_t y0, uint16_t width, uint16_t height, + font_t font, uint16_t bkcolor, uint16_t color); msg_t lcdConsolePut(GLCDConsole *console, char c); msg_t lcdConsoleWrite(GLCDConsole *console, uint8_t *bp, size_t n); diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index 3f98b8de..4c9c4009 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -92,6 +92,25 @@ __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { } } +__inline void lld_lcdReadStreamStart(void) { + Clr_CS + lld_lcdWriteIndex(0x0022); +} + +__inline void lld_lcdReadStreamStop(void) { + Set_CS; +} + +__inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + uint16_t i; + /* throw away first value read */ + volatile uint16_t dummy = LCD_RAM; + + for(i = 0; i < size; i++) { + buffer[i] = LCD_RAM; + } +} + #endif #ifdef LCD_USE_FSMC @@ -118,6 +137,7 @@ static __inline uint16_t lld_lcdReadData(void) { static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { LCD_REG = lcdReg; + volatile uint16_t dummy = LCD_RAM; return (LCD_RAM); } @@ -145,6 +165,9 @@ __inline void lld_lcdReadStreamStop(void) { __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { uint16_t i; + /* throw away first value read */ + volatile uint16_t dummy = LCD_RAM; + for(i = 0; i < size; i++) { buffer[i] = LCD_RAM; } @@ -162,13 +185,25 @@ static __inline void lcdDelay(uint16_t us) { void lld_lcdSetCursor(uint16_t x, uint16_t y) { + /* Reg 0x004E is an 8 bit value + * Reg 0x004F is 8 bit + */ + /* + * if(PORTRAIT) { + lld_lcdWriteReg(0x004e, x & 0x00FF); + lld_lcdWriteReg(0x004f, y & 0x01FF); + } else if(LANDSCAPE) { + lld_lcdWriteReg(0x004e, y & 0x00FF); + lld_lcdWriteReg(0x004f, x & 0x01FF); + } + */ if(PORTRAIT) { - lld_lcdWriteReg(0x004e, x); + lld_lcdWriteReg(0x004e, x); lld_lcdWriteReg(0x004f, y); } else if(LANDSCAPE) { - lld_lcdWriteReg(0x004e, y); + lld_lcdWriteReg(0x004e, y); lld_lcdWriteReg(0x004f, x); - } + } } void lld_lcdSetOrientation(uint8_t newOrientation) { @@ -205,26 +240,35 @@ void lld_lcdSetOrientation(uint8_t newOrientation) { void lld_lcdSetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { lld_lcdSetCursor(x0, y0); + /* Reg 0x44 - Horizontal RAM address position + * Upper Byte - HEA + * Lower Byte - HSA + * 0 <= HSA <= HEA <= 0xEF + * Reg 0x45,0x46 - Vertical RAM address position + * Lower 9 bits gives 0-511 range in each value + * 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F + */ + switch(lcdGetOrientation()) { case portrait: - lld_lcdWriteReg(0x44, ((x1-1) << 8) | x0); + lld_lcdWriteReg(0x44, (((x1-1) << 8) ) | (x0 )); lld_lcdWriteReg(0x45, y0); - lld_lcdWriteReg(0x46, y1-1); + lld_lcdWriteReg(0x46, (y1-1)); break; case landscape: - lld_lcdWriteReg(0x44, ((y1-1) << 8) | y1); - lld_lcdWriteReg(0x45, x0); - lld_lcdWriteReg(0x46, x1-1); + lld_lcdWriteReg(0x44, (((y1-1) << 8) & 0xFF00) | (y1 & 0x00FF)); + lld_lcdWriteReg(0x45, x0 & 0x01FF); + lld_lcdWriteReg(0x46, (x1-1) & 0x01FF); break; case portraitInv: - lld_lcdWriteReg(0x44, ((x1-1) << 8) | x0); - lld_lcdWriteReg(0x45, y0); - lld_lcdWriteReg(0x46, y1-1); + lld_lcdWriteReg(0x44, (((x1-1) << 8) & 0xFF00) | (x0 & 0x00FF)); + lld_lcdWriteReg(0x45, y0 & 0x01FF); + lld_lcdWriteReg(0x46, (y1-1) & 0x01FF); break; case landscapeInv: - lld_lcdWriteReg(0x44, ((y1-1) << 8) | y1); - lld_lcdWriteReg(0x45, x0); - lld_lcdWriteReg(0x46, x1-1); + lld_lcdWriteReg(0x44, (((y1-1) << 8) & 0xFF00) | (y1 & 0x00FF)); + lld_lcdWriteReg(0x45, x0 & 0x01FF); + lld_lcdWriteReg(0x46, (x1-1) & 0x01FF); break; } } @@ -366,6 +410,7 @@ void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, i row0 = (y1 - i - 1) + lines; row1 = (y1 - i - 1); } + /* read row0 into the buffer and then write at row1*/ lld_lcdSetWindow(x0, row0, x1, row0); lld_lcdReadStreamStart(); diff --git a/glcd.c b/glcd.c index 1a77af1b..e6a5cbb5 100644 --- a/glcd.c +++ b/glcd.c @@ -191,11 +191,7 @@ int lcdDrawChar(uint16_t cx, uint16_t cy, char c, font_t font, uint16_t color, u /* Return the width of the character, we need it so that lcdDrawString may work * We don't have a static address counter */ - - /* Abhishek: what should padAfter be? - * return charWidth+padAfter; - */ - return charWidth; + return charWidth + padAfterChar; } /* WARNING: No boundary checks! Unpredictable behaviour if text exceeds boundary */ From 351c50cc48eb5468254a4fa4401e2de9536378a5 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 16:40:23 +0100 Subject: [PATCH 12/17] tidy up --- drivers/lcd/s6d1121_lld.c | 38 +++++++++++++++++++++++++++++++++++--- glcd.c | 3 --- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/lcd/s6d1121_lld.c b/drivers/lcd/s6d1121_lld.c index 7f842e33..da8878e2 100644 --- a/drivers/lcd/s6d1121_lld.c +++ b/drivers/lcd/s6d1121_lld.c @@ -238,6 +238,18 @@ __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { } } +__inline void lld_lcdReadStreamStart(void) { + /* TODO */ +} + +__inline void lld_lcdReadStreamStop(void) { + /* TODO */ +} + +__inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { + /* TODO */ +} + void lld_lcdFillArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) { uint32_t index = 0, area; @@ -350,13 +362,33 @@ uint16_t lld_lcdGetWidth(void) { return lcd_width; } +/* a positive lines value shifts the screen up, negative down */ +/* TODO: test this */ void lld_lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { + uint16_t row0, row1; + uint16_t i; lld_lcdSetWindow(x0, y0, x1, y1); - /* if negative shift, then subtract from the height of the area */ - lines = (lines < 0) ? ((y1-y0) + lines) : lines; + for(i = 0; i < ((y1-y0) - abs(lines)); i++) { + if(lines > 0) { + row0 = y0 + i + lines; + row1 = y0 + i; + } else { + row0 = (y1 - i - 1) + lines; + row1 = (y1 - i - 1); + } - /* TODO: implement */ + /* read row0 into the buffer and then write at row1*/ + lld_lcdSetWindow(x0, row0, x1, row0); + lld_lcdReadStreamStart(); + lld_lcdReadStream(buf, x1-x0); + lld_lcdReadStreamStop(); + + lld_lcdSetWindow(x0, row1, x1, row1); + lld_lcdWriteStreamStart(); + lld_lcdWriteStream(buf, x1-x0); + lld_lcdWriteStreamStop(); + } } diff --git a/glcd.c b/glcd.c index e6a5cbb5..980dfa04 100644 --- a/glcd.c +++ b/glcd.c @@ -317,6 +317,3 @@ void lcdDrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint8_t filled, uint void lcdVerticalScroll(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int16_t lines) { lld_lcdVerticalScroll(x0,y0,x1,y1,lines); } - - - From 1d09786fa445371c4b4898a8c35be1257e56d89d Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 16:42:09 +0100 Subject: [PATCH 13/17] more safety checks --- drivers/lcd/ssd1289_lld.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index 4c9c4009..ffcbb167 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -188,22 +188,15 @@ void lld_lcdSetCursor(uint16_t x, uint16_t y) { /* Reg 0x004E is an 8 bit value * Reg 0x004F is 8 bit */ - /* - * if(PORTRAIT) { + + if(PORTRAIT) { lld_lcdWriteReg(0x004e, x & 0x00FF); lld_lcdWriteReg(0x004f, y & 0x01FF); } else if(LANDSCAPE) { lld_lcdWriteReg(0x004e, y & 0x00FF); lld_lcdWriteReg(0x004f, x & 0x01FF); } - */ - if(PORTRAIT) { - lld_lcdWriteReg(0x004e, x); - lld_lcdWriteReg(0x004f, y); - } else if(LANDSCAPE) { - lld_lcdWriteReg(0x004e, y); - lld_lcdWriteReg(0x004f, x); - } + } void lld_lcdSetOrientation(uint8_t newOrientation) { @@ -251,9 +244,9 @@ void lld_lcdSetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { switch(lcdGetOrientation()) { case portrait: - lld_lcdWriteReg(0x44, (((x1-1) << 8) ) | (x0 )); - lld_lcdWriteReg(0x45, y0); - lld_lcdWriteReg(0x46, (y1-1)); + lld_lcdWriteReg(0x44, (((x1-1) << 8) & 0xFF00 ) | (x0 & 0x00FF)); + lld_lcdWriteReg(0x45, y0 & 0x01FF); + lld_lcdWriteReg(0x46, (y1-1) & 0x01FF); break; case landscape: lld_lcdWriteReg(0x44, (((y1-1) << 8) & 0xFF00) | (y1 & 0x00FF)); From e4ec0e943270f3c249182e02210f1f78dfa7522b Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 16:45:23 +0100 Subject: [PATCH 14/17] use max(height,width) to calculate buffer size --- drivers/lcd/s6d1121_lld.c | 2 ++ drivers/lcd/ssd1289_lld.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/lcd/s6d1121_lld.c b/drivers/lcd/s6d1121_lld.c index da8878e2..2a591ee2 100644 --- a/drivers/lcd/s6d1121_lld.c +++ b/drivers/lcd/s6d1121_lld.c @@ -2,6 +2,8 @@ #ifdef LCD_USE_S6D1121 +static uint16_t buf[((SCREEN_HEIGHT > SCREEN_WIDTH ) ? SCREEN_HEIGHT : SCREEN_WIDTH)]; + #define LCD_RST_LOW palClearPad(LCD_RST_GPIO, LCD_RST_PIN) #define LCD_RST_HIGH palSetPad(LCD_RST_GPIO, LCD_RST_PIN) diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index ffcbb167..c2dfc1f3 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -6,8 +6,7 @@ uint8_t orientation; uint16_t DeviceCode; extern uint16_t lcd_width, lcd_height; -/* TODO: use max(height, width) */ -static uint16_t buf[SCREEN_HEIGHT]; +static uint16_t buf[((SCREEN_HEIGHT > SCREEN_WIDTH ) ? SCREEN_HEIGHT : SCREEN_WIDTH)]; #ifdef LCD_USE_GPIO static __inline void lld_lcdWriteIndex(uint16_t index) { From 44eb3583bc0333c20b6eac7a9be208cf7edbde55 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 16:46:20 +0100 Subject: [PATCH 15/17] add missing semi colon --- drivers/lcd/ssd1289_lld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index c2dfc1f3..e1f697ca 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -71,7 +71,7 @@ static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { } __inline void lld_lcdWriteStreamStart(void) { - Clr_CS + Clr_CS; lld_lcdWriteIndex(0x0022); } From 8a6337b4e746c3d9f42061b26aa2e17370b7db37 Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 16:51:54 +0100 Subject: [PATCH 16/17] tidy up comments --- drivers/lcd/ssd1289_lld.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/lcd/ssd1289_lld.c b/drivers/lcd/ssd1289_lld.c index e1f697ca..831f0eda 100644 --- a/drivers/lcd/ssd1289_lld.c +++ b/drivers/lcd/ssd1289_lld.c @@ -185,7 +185,8 @@ static __inline void lcdDelay(uint16_t us) { void lld_lcdSetCursor(uint16_t x, uint16_t y) { /* Reg 0x004E is an 8 bit value - * Reg 0x004F is 8 bit + * Reg 0x004F is 9 bit + * Use a bit mask to make sure they are not set too high */ if(PORTRAIT) { From bb69ed37aad36fac6bdf1e2c9669caee5689630f Mon Sep 17 00:00:00 2001 From: trsaunders Date: Wed, 27 Jun 2012 17:53:04 +0100 Subject: [PATCH 17/17] fix merge --- gui.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gui.h b/gui.h index 2a857f17..5b2919f7 100644 --- a/gui.h +++ b/gui.h @@ -6,15 +6,6 @@ #include "glcd.h" #include "touchpad.h" -struct button_t { - uint16_t x0; - uint16_t y0; - uint16_t x1; - uint16_t y1; - uint32_t *state; - uint16_t interval; -}; - static struct guiNode_t { uint8_t type; uint16_t x0;