aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--console.c145
-rw-r--r--console.h66
-rw-r--r--drivers/lcd/s6d1121_lld.c44
-rw-r--r--drivers/lcd/s6d1121_lld.h2
-rw-r--r--drivers/lcd/ssd1289_lld.c117
-rw-r--r--drivers/lcd/ssd1289_lld.h2
-rw-r--r--drivers/touchpad/ads7843_lld.h2
-rw-r--r--drivers/touchpad/xpt2046_lld.h2
-rw-r--r--glcd.c278
-rw-r--r--glcd.h66
-rw-r--r--glcdconf.h23
-rw-r--r--gui.c4
-rw-r--r--gui.h3
-rw-r--r--lcd.mk1
-rw-r--r--touchpad.c4
15 files changed, 487 insertions, 272 deletions
diff --git a/console.c b/console.c
new file mode 100644
index 00000000..c206ef5f
--- /dev/null
+++ b/console.c
@@ -0,0 +1,145 @@
+/*
+ * console.c
+ *
+ * Created on: 20 Jun 2012
+ * Author: Thomas Saunders AKA "Badger"
+ */
+
+#include "ch.h"
+
+#include "fonts.h"
+#include "glcd.h"
+#include "console.h"
+
+/*
+ * Interface implementation. The interface is write only
+ */
+
+static size_t writes(void *ip, const uint8_t *bp, size_t n) {
+ return lcdConsoleWrite((GLCDConsole *)ip, 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) {
+ return lcdConsolePut((GLCDConsole *)ip, (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)timeout;
+ /* TODO: handle timeout */
+ return lcdConsolePut((GLCDConsole *)ip, (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)time;
+ return lcdConsoleWrite((GLCDConsole *)ip, 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
+};
+
+
+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;
+
+ console->vmt = &vmt;
+ /* read font, get height */
+ console->fy = font[FONT_TABLE_HEIGHT_IDX];
+
+ /* 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->bkcolor = bkcolor;
+ console->color = color;
+
+ console->font = font;
+}
+
+msg_t lcdConsolePut(GLCDConsole *console, char c) {
+ uint8_t width;
+
+ 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, console->font);
+ if((console->cx + width) >= console->sx) {
+ console->cx = 0;
+ console->cy += console->fy;
+ }
+
+ if((console->cy > console->sy)) {
+
+ lcdVerticalScroll(console->x0, console->y0, console->x0 + console->sx,
+ console->y0 + console->sy + console->fy, console->fy);
+ /* reset the cursor */
+ console->cx = 0;
+ console->cy = console->sy;
+ }
+
+ lcdDrawChar(console->x0 + console->cx, console->y0 + console->cy, c,
+ console->font, console->color, console->bkcolor, solid);
+
+ /* update cursor */
+ console->cx += width;
+ }
+
+}
+
+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
new file mode 100644
index 00000000..fcdef293
--- /dev/null
+++ b/console.h
@@ -0,0 +1,66 @@
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+#include "glcd.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 */
+ /* font */
+ font_t font;
+ /* lcd area to use */
+ uint16_t x0,y0;
+ /* current cursor position, in pixels */
+ uint16_t cx,cy;
+ /* console size in pixels */
+ uint16_t sx,sy;
+ /* foreground and background colour */
+ uint16_t bkcolor, color;
+ /* font size in pixels */
+ uint8_t fy;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONSOLE_H */
diff --git a/drivers/lcd/s6d1121_lld.c b/drivers/lcd/s6d1121_lld.c
index f7268126..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)
@@ -238,6 +240,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,5 +364,35 @@ 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);
+
+ 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();
+
+ lld_lcdSetWindow(x0, row1, x1, row1);
+ lld_lcdWriteStreamStart();
+ lld_lcdWriteStream(buf, x1-x0);
+ lld_lcdWriteStreamStop();
+ }
+}
+
+
#endif
diff --git a/drivers/lcd/s6d1121_lld.h b/drivers/lcd/s6d1121_lld.h
index edc6da33..8c4e7057 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
@@ -43,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 6b199df6..5a14d238 100644
--- a/drivers/lcd/ssd1289_lld.c
+++ b/drivers/lcd/ssd1289_lld.c
@@ -6,6 +6,8 @@ uint8_t orientation;
uint16_t DeviceCode;
extern uint16_t lcd_width, lcd_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) {
@@ -63,7 +65,7 @@ static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
}
__inline void lld_lcdWriteStreamStart(void) {
- Clr_CS
+ Clr_CS;
lld_lcdWriteIndex(0x0022);
}
@@ -84,6 +86,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_SPI
@@ -114,6 +135,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);
}
@@ -130,6 +152,24 @@ __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;
+ /* throw away first value read */
+ volatile uint16_t dummy = LCD_RAM;
+
+ for(i = 0; i < size; i++) {
+ buffer[i] = LCD_RAM;
+ }
+}
#endif
static __inline void lld_lcdDelay(uint16_t us) {
@@ -158,13 +198,19 @@ void lld_lcdSetPowerMode(uint8_t powerMode) {
}
void lld_lcdSetCursor(uint16_t x, uint16_t y) {
+ /* Reg 0x004E is an 8 bit value
+ * Reg 0x004F is 9 bit
+ * Use a bit mask to make sure they are not set too high
+ */
+
if(PORTRAIT) {
- lld_lcdWriteReg(0x004e, x);
- lld_lcdWriteReg(0x004f, y);
+ lld_lcdWriteReg(0x004e, x & 0x00FF);
+ lld_lcdWriteReg(0x004f, y & 0x01FF);
} else if(LANDSCAPE) {
- lld_lcdWriteReg(0x004e, y);
- lld_lcdWriteReg(0x004f, x);
+ lld_lcdWriteReg(0x004e, y & 0x00FF);
+ lld_lcdWriteReg(0x004f, x & 0x01FF);
}
+
}
void lld_lcdSetOrientation(uint8_t newOrientation) {
@@ -201,26 +247,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(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) | 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;
}
}
@@ -348,5 +403,33 @@ uint16_t lld_lcdGetWidth(void) {
return lcd_width;
}
+/* 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);
+
+ 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();
+
+ lld_lcdSetWindow(x0, row1, x1, row1);
+ lld_lcdWriteStreamStart();
+ lld_lcdWriteStream(buf, x1-x0);
+ lld_lcdWriteStreamStop();
+ }
+}
+
#endif
diff --git a/drivers/lcd/ssd1289_lld.h b/drivers/lcd/ssd1289_lld.h
index 5462acd6..16a9ef0d 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
@@ -25,6 +24,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/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/glcd.c b/glcd.c
index 01e166a8..2c6b3bba 100644
--- a/glcd.c
+++ b/glcd.c
@@ -3,89 +3,15 @@
#include <stdlib.h>
#include <math.h>
-/*===========================================================================*/
-/* 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;
-static uint8_t tpText = 0;
-const uint8_t* font;
void lcdInit(GLCDDriver *glcdp) {
- glcdp->vmt = &vmt;
lld_lcdInit();
lcd_width = lcdGetWidth();
lcd_height = lcdGetHeight();
lcdSetOrientation(portrait);
- lcdSetFontTransparency(transparent);
- lcdSetFont(font_MediumBold);
}
uint16_t lcdGetHeight(void) {
@@ -120,6 +46,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);
}
@@ -193,135 +127,118 @@ 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;
-
- // No support for nongraphic characters, so just ignore them
+ 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 */
if(c < 0x20 || c > 0x7F) {
- if(c == '\n')
- lcdLineBreak();
return RDY_OK;
}
- chi = *(uint16_t*)(&font[FONT_TABLE_CHAR_LOOKUP_IDX + (c-0x20)*2]);
-
- ptr = font + chi;
-
- 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)
- lcdDrawPixel(cx+x, cy+y, fgcolor);
- else if(!tpText)
- lcdDrawPixel(cx+x, cy+y, bgcolor);
-
- chi >>= 1;
+ /* 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]);
+
+ /* 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++);
+
+ /* 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) {
+ /* 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 {
+ /* Just draw the needed pixels onto the LCD */
+ if (charData & 0x01)
+ lcdDrawPixel(cx+x, cy+y, color);
+ }
+
+ /* Shift the data down by one bit */
+ charData >>= 1;
}
+
+ /* Increment pointer by 2 bytes to the next column */
ptr += 2;
}
- cx += fontWidth;
- if(sps != 0) {
- if(!tpText)
- lcdFillArea(cx, cy, cx+sps, cy+fontHeight, bgcolor);
- cx += sps;
- }
-
- /* 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 */
+ return charWidth + padAfterChar;
}
-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;
-}
-
-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 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;
- 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]);
-
- ptr = font + chi;
-
- uint8_t fontWidth = *(ptr++);
+ /* 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]);
- 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;
@@ -360,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) {
@@ -401,3 +318,6 @@ 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 8108b21f..d0597a88 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"
@@ -30,87 +35,60 @@ enum filled {frame, filled};
enum transparency {solid, transparent};
enum powermode {powerOff, powerOn, sleepOn, sleepOff};
-// 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.
*/
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
extern "C" {
#endif
-
+/* Core functions */
void lcdInit(GLCDDriver *);
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 lcdSetPowerMode(uint8_t powerMode);
+/* 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
}
#endif
diff --git a/glcdconf.h b/glcdconf.h
deleted file mode 100644
index b6445e93..00000000
--- a/glcdconf.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef GLCDCONF_H
-#define GLCDCONF_H
-
-#define SCREEN_WIDTH 240
-#define SCREEN_HEIGHT 320
-
-/***** 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
diff --git a/gui.c b/gui.c
index 945606e7..070d9949 100644
--- a/gui.c
+++ b/gui.c
@@ -135,7 +135,7 @@ uint8_t guiDeleteElement(char *label) {
return deleteElement(label);
}
-uint8_t guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, char *str, uint16_t fontColor, uint16_t buttonColor, uint16_t shadow, char *label, uint8_t *active, uint8_t *state) {
+uint8_t guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, char *str, font_t font, uint16_t fontColor, uint16_t buttonColor, uint16_t shadow, char *label, uint8_t *active, uint8_t *state) {
struct guiNode_t *newNode;
uint16_t i;
@@ -156,7 +156,7 @@ uint8_t guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, char *
if(addElement(newNode) != 1)
return 0;
- lcdDrawRectString(x0, y0, x1, y1, str, fontColor, buttonColor);
+ lcdDrawRectString(x0, y0, x1, y1, str, font, fontColor, buttonColor);
if(shadow != 0) {
for(i = 0; i < shadow; i++) {
diff --git a/gui.h b/gui.h
index 513043aa..5b2919f7 100644
--- a/gui.h
+++ b/gui.h
@@ -46,6 +46,7 @@ Thread *guiInit(uint16_t interval, tprio_t priority);
*
* return: none
*/
+
void guiPrintElements(BaseSequentialStream *chp);
/*
@@ -69,7 +70,7 @@ uint8_t guiDeleteElement(char *label);
*
* return: 1 if button successfully created
*/
-uint8_t guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, char *str, uint16_t fontColor, uint16_t buttonColor, uint16_t shadow, char *label, uint8_t *active, uint8_t *state);
+uint8_t guiDrawButton(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, char *str, font_t font, uint16_t fontColor, uint16_t buttonColor, uint16_t shadow, char *label, uint8_t *active, uint8_t *state);
uint8_t guiDrawSlider(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t orientation, uint16_t frameColor, uint16_t bkColor, uint16_t valueColor, char *label, uint8_t *active, uint8_t *value);
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) \
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]);