Merge pull request #11 from trsaunders/master

Console support
This commit is contained in:
Tectu 2012-06-27 10:03:05 -07:00
commit 1f43c6d654
15 changed files with 484 additions and 269 deletions

145
console.c Normal file
View File

@ -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;
}

66
console.h Normal file
View File

@ -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 */

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

272
glcd.c
View File

@ -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;
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;
// No support for nongraphic characters, so just ignore them
/* 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]);
/* 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++);
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;
/* 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;
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);
}
}
/* TODO: proper return codes */
return RDY_OK;
/* 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 lcdWriteString(const char *str, size_t n) {
size_t l = 0;
for(l = 0; l < n; l++) {
if(lcdDrawChar(*str++) != RDY_OK)
break;
/* 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;
}
size_t lcdPutString(const char *str) {
size_t l = 0;
while(*str) {
if(lcdDrawChar(*str++) != RDY_OK)
break;
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;
l++;
}
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 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;
@ -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);
}

66
glcd.h
View File

@ -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

View File

@ -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

4
gui.c
View File

@ -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++) {

3
gui.h
View File

@ -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);

1
lcd.mk
View File

@ -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) \

View File

@ -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]);