commit
1f43c6d654
145
console.c
Normal file
145
console.c
Normal 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
66
console.h
Normal 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 */
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
272
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;
|
||||
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
66
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
|
||||
|
23
glcdconf.h
23
glcdconf.h
@ -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
4
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++) {
|
||||
|
3
gui.h
3
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);
|
||||
|
||||
|
1
lcd.mk
1
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) \
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user