convert hd44780 driver to use bignum library, add a few security checks

This commit is contained in:
marschap
2006-04-26 09:46:01 +00:00
parent 7c92890b64
commit e43b741795
4 changed files with 243 additions and 499 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ CFontzPacket_LDADD = libLCD.a libbignum.a
curses_LDADD = @LIBCURSES@
CwLnx_LDADD = libLCD.a
glcdlib_LDADD = libLCD.a @LIBGLCD@
hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @libusb_libs@
hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @libusb_libs@ libbignum.a
hd44780_DEPENDENCIES = @HD44780_DRIVERS@
icp_a106_LDADD = libLCD.a
imon_LDADD = libLCD.a
@@ -61,7 +61,7 @@ curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h
CwLnx_SOURCES = lcd.h lcd_lib.h CwLnx.c CwLnx.h report.h
glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h
glk_SOURCES = lcd.h glk.c glk.h glkproto.c glkproto.h report.h
hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h
hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h
EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-winamp.c hd44780-winamp.h hd44780-picanlcd.c hd44780-picanlcd.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcdserializer.c hd44780-lcdserializer.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h
icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
+15 -10
View File
@@ -29,11 +29,19 @@
/* Constants for userdefchar_mode */
#define NUM_CCs 8 /* number of custom characters */
#define CCMODE_STANDARD 0 /* only char 0 is used for heartbeat */
#define CCMODE_VBAR 1
#define CCMODE_HBAR 2
#define CCMODE_BIGNUM 3
#define CCMODE_BIGCHAR 4
typedef enum {
standard, /* only char 0 is used for heartbeat */
vbar, /* vertical bars */
hbar, /* horizontaln bars */
bignum, /* big numbers */
bigchar /* big characters */
} CGmode;
typedef struct cgram_cache {
unsigned char cache[LCD_DEFAULT_CELLHEIGHT];
int clean;
} CGram;
typedef struct ConnectionMapping {
char *name;
@@ -57,8 +65,8 @@ typedef struct driver_private_data {
char *lcd_contents;
// The defineable characters
char *cc_buf;
char *cc_dirty;
CGram cc[NUM_CCs];
CGmode ccmode;
// Connection type data
int connectiontype_index;
@@ -106,9 +114,6 @@ typedef struct driver_private_data {
int backlight_bit;
int output_state; // what was most recently output to the output port
int ccmode;
} PrivateData;
// Structures holding pointers to HD44780 specific functions
+225 -486
View File
@@ -73,6 +73,7 @@
#include "lcd_lib.h"
#include "hd44780.h"
#include "report.h"
#include "adv_bignum.h"
#include "timing.h"
#include "hd44780-low.h"
@@ -131,17 +132,16 @@ HD44780_init (Driver * drvthis)
PrivateData *p;
// Alocate and store private data
p = (PrivateData *) malloc(sizeof(PrivateData));
p = (PrivateData *) calloc(1, sizeof(PrivateData));
if (p == NULL)
return -1;
if (drvthis->store_private_ptr( drvthis, p))
if (drvthis->store_private_ptr(drvthis, p))
return -1;
// Clear data struct
memset( p, 0, sizeof(*p) );
// initialize private data
p->cellheight = 8; /* Do not change this !!! This is a controller property, not a display property !!! */
p->cellwidth = 5;
p->ccmode = CCMODE_STANDARD;
p->ccmode = standard;
//// READ THE CONFIG FILE
@@ -189,18 +189,18 @@ HD44780_init (Driver * drvthis)
// default case for when spans aren't indicated
// - add a sanity check against p->height ??
if (p->numLines == 0) {
if ((p->spanList = (int *) malloc(sizeof(int) * p->height))) {
if ((p->spanList = (int *) calloc(sizeof(int), p->height)) != NULL) {
int i;
for (i = 0; i < p->height; ++i) {
p->spanList[i] = 1;
p->numLines = p->height;
}
} else
report(RPT_ERR, "%s: error mallocing", drvthis->name);
report(RPT_ERR, "%s: error allocing", drvthis->name);
}
if (p->numDisplays == 0) {
if ((p->dispVOffset = (int *) malloc(sizeof(int))) &&
(p->dispSizes = (int *) malloc(sizeof(int)))) {
if (((p->dispVOffset = (int *) calloc(1, sizeof(int))) != NULL) &&
((p->dispSizes = (int *) calloc(1, sizeof(int))) != NULL)) {
p->dispVOffset[0] = 0;
p->dispSizes[0] = p->height;
p->numDisplays = 1;
@@ -228,7 +228,7 @@ HD44780_init (Driver * drvthis)
#endif
// Allocate framebuffer
p->framebuf = (char *) malloc(p->width * p->height);
p->framebuf = (char *) calloc(p->width * p->height, sizeof(char));
if (p->framebuf == NULL) {
report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
//HD44780_close();
@@ -236,29 +236,18 @@ HD44780_init (Driver * drvthis)
}
// Allocate and clear the buffer for incremental updates
p->lcd_contents = (char *) malloc (p->width * p->height);
p->lcd_contents = (char *) calloc (p->width * p->height, sizeof(char));
if (p->lcd_contents == NULL) {
report(RPT_ERR, "%s: unable to allocate framebuffer backing store", drvthis->name);
return -1;
}
memset(p->lcd_contents, 0, p->width * p->height);
// Allocate and clear the buffer for defineable characters
p->cc_buf = (char *) malloc(NUM_CCs * p->cellheight);
p->cc_dirty = (char *) malloc(NUM_CCs);
if (!p->cc_buf || !p->cc_dirty) {
report(RPT_ERR, "%s: error mallocing", drvthis->name);
return -1;
}
memset(p->cc_buf, 0, NUM_CCs * p->cellheight);
memset(p->cc_dirty, 1, NUM_CCs); /* all custom chars dirty */
// Keypad ?
if (p->have_keypad) {
int x, y;
// Read keymap
for ( x=0; x<KEYPAD_MAXX; x++ ) {
for (x = 0; x < KEYPAD_MAXX; x++) {
char buf[40];
// First fill with default value
@@ -275,8 +264,8 @@ HD44780_init (Driver * drvthis)
}
}
for ( x=0; x<KEYPAD_MAXX; x++ ) {
for ( y=0; y<KEYPAD_MAXY; y++ ) {
for (x = 0; x < KEYPAD_MAXX; x++) {
for (y = 0; y<KEYPAD_MAXY; y++) {
char buf[40];
// First fill with default value
@@ -298,7 +287,7 @@ HD44780_init (Driver * drvthis)
// Output latch state - init to a non-valid value
p->output_state = 999999;
if ((p->hd44780_functions = (HD44780_functions *) malloc(sizeof(HD44780_functions))) == NULL) {
if ((p->hd44780_functions = (HD44780_functions *) calloc(1, sizeof(HD44780_functions))) == NULL) {
report(RPT_ERR, "%s: error mallocing", drvthis->name);
return -1;
}
@@ -307,7 +296,7 @@ HD44780_init (Driver * drvthis)
p->hd44780_functions->output = NULL;
// Do connection type specific display init
if (connectionMapping[p->connectiontype_index].init_fn (drvthis) != 0)
if (connectionMapping[p->connectiontype_index].init_fn(drvthis) != 0)
return -1;
// Display startup parameters on the LCD
@@ -477,9 +466,9 @@ HD44780_flush (Driver *drvthis)
// Update LCD incrementally by comparing with last contents
count = 0;
for (y=0; y<p->height; y++) {
for (y = 0; y < p->height; y++) {
drawing = 0;
for (x=0 ; x<wid; x++) {
for (x = 0 ; x < wid; x++) {
ch = p->framebuf[(y * wid) + x];
if ( ch != p->lcd_contents[(y*wid)+x] ) {
if ( !drawing || x % 8 == 0 ) { // x%8 is for 16x1 displays !
@@ -489,7 +478,7 @@ HD44780_flush (Driver *drvthis)
p->hd44780_functions->senddata (p, p->spanList[y], RS_DATA, HD44780_charmap[(unsigned char)ch]);
p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands
p->lcd_contents[(y*wid)+x] = ch;
count ++;
count++;
}
else {
drawing = 0;
@@ -500,8 +489,8 @@ HD44780_flush (Driver *drvthis)
/* Check which defineable chars we need to update */
count = 0;
for ( i = 0; i < NUM_CCs; i ++ ) {
if ( p->cc_dirty[i] ) {
for (i = 0; i < NUM_CCs; i++) {
if (!p->cc[i].clean) {
/* Tell the HD44780 we will redefine char number i */
p->hd44780_functions->senddata (p, 0, RS_INSTR, SETCHAR | i * 8);
@@ -509,15 +498,14 @@ HD44780_flush (Driver *drvthis)
/* Send the subsequent rows */
for (row = 0; row < p->cellheight; row++) {
p->hd44780_functions->senddata (p, 0, RS_DATA, p->cc_buf[i*p->cellheight+row]);
p->hd44780_functions->senddata (p, 0, RS_DATA, p->cc[i].cache[row]);
p->hd44780_functions->uPause (p, 40); /* Minimum exec time for all commands */
}
/* Mark as not dirty anymore */
p->cc_dirty[i] = 0;
count ++;
p->cc[i].clean = 1; /* mark as clean */
count++;
}
}
debug(RPT_DEBUG, "HD44780: flushed %d custom chars's", count );
debug(RPT_DEBUG, "%s: flushed %d custom chars", drvthis->name, count);
}
/////////////////////////////////////////////////////////////////
@@ -528,7 +516,7 @@ HD44780_clear (Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
memset(p->framebuf, ' ', p->width * p->height);
p->ccmode = CCMODE_STANDARD;
p->ccmode = standard;
}
/////////////////////////////////////////////////////////////////
@@ -541,26 +529,28 @@ HD44780_chr (Driver *drvthis, int x, int y, char ch)
y--;
x--;
p->framebuf[ (y * p->width) + x] = ch;
if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height))
p->framebuf[ (y * p->width) + x] = ch;
}
/////////////////////////////////////////////////////////////////
// Place a string in the framebuffer
//
MODULE_EXPORT void
HD44780_string (Driver *drvthis, int x, int y, char *s)
HD44780_string (Driver *drvthis, int x, int y, char *string)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
int i;
x --; // Convert 1-based coords to 0-based
y --;
x--; // Convert 1-based coords to 0-based
y--;
for (i = 0; s[i]; i++) {
// Check for buffer overflows...
if ((y * p->width) + x + i > (p->width * p->height))
break;
p->framebuf[(y*p->width) + x + i] = s[i];
if ((y < 0) || (y >= p->height))
return;
for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) {
if (x >= 0) // no write left of left border
p->framebuf[(y * p->width) + x] = string[i];
}
}
@@ -574,185 +564,6 @@ HD44780_backlight (Driver *drvthis, int on)
p->hd44780_functions->backlight (p, on);
}
/////////////////////////////////////////////////////////////////
// Sets up for vertical bars. Call before HD44780->vbar()
//
static void
HD44780_init_vbar (Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
char a[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
};
char b[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
char c[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
char d[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
char e[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
char f[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
char g[] = {
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
};
if ( p->ccmode == CCMODE_VBAR ) {
/* Work already done */
return;
}
if ( p->ccmode != CCMODE_STANDARD ) {
/* Not supported (yet) */
report(RPT_WARNING, "HD44780_init_vbar: Cannot combine two modes using user defined characters" );
return;
}
p->ccmode = CCMODE_VBAR;
HD44780_set_char (drvthis, 1, a);
HD44780_set_char (drvthis, 2, b);
HD44780_set_char (drvthis, 3, c);
HD44780_set_char (drvthis, 4, d);
HD44780_set_char (drvthis, 5, e);
HD44780_set_char (drvthis, 6, f);
HD44780_set_char (drvthis, 7, g);
}
/////////////////////////////////////////////////////////////////
// Inits horizontal bars...
//
static void
HD44780_init_hbar (Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
char a[] = {
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
1, 0, 0, 0, 0,
};
char b[] = {
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
};
char c[] = {
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
1, 1, 1, 0, 0,
};
char d[] = {
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
};
char e[] = {
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
};
if ( p->ccmode == CCMODE_HBAR ) {
/* Work already done */
return;
}
if ( p->ccmode != CCMODE_STANDARD ) {
/* Not supported (yet) */
report(RPT_WARNING, "HD44780_init_hbar: Cannot combine two modes using user defined characters" );
return;
}
p->ccmode = CCMODE_HBAR;
HD44780_set_char (drvthis, 1, a);
HD44780_set_char (drvthis, 2, b);
HD44780_set_char (drvthis, 3, c);
HD44780_set_char (drvthis, 4, d);
HD44780_set_char (drvthis, 5, e);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar...
//
@@ -768,7 +579,26 @@ HD44780_vbar (Driver *drvthis, int x, int y, int len, int promille, int options)
* promille is the number of promilles (0..1000) that the bar should be filled.
*/
HD44780_init_vbar(drvthis);
if (p->ccmode != vbar) {
unsigned char vBar[p->cellheight];
int i;
if (p->ccmode != standard) {
/* Not supported(yet) */
report(RPT_WARNING, "%s: vbar: cannot combine two modes using user defined characters",
drvthis->name);
return;
}
p->ccmode = vbar;
memset(vBar, 0x00, sizeof(vBar));
for (i = 1; i < p->cellheight; i++) {
// add pixel line per pixel line ...
vBar[p->cellheight - i] = 0xFF;
HD44780_set_char(drvthis, i, vBar);
}
}
lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0);
}
@@ -788,107 +618,29 @@ HD44780_hbar (Driver *drvthis, int x, int y, int len, int promille, int options)
* promille is the number of promilles (0..1000) that the bar should be filled.
*/
HD44780_init_hbar(drvthis);
if (p->ccmode != hbar) {
unsigned char hBar[p->cellheight];
int i;
if (p->ccmode != standard) {
/* Not supported(yet) */
report(RPT_WARNING, "%s: hbar: cannot combine two modes using user defined characters",
drvthis->name);
return;
}
p->ccmode = hbar;
for (i = 1; i <= p->cellwidth; i++) {
// fill pixel columns from left to right.
memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar));
HD44780_set_char(drvthis, i, hBar);
}
}
lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0);
}
/////////////////////////////////////////////////////////////////
// Sets up for big numbers.
//
static void
HD44780_init_num (Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
char bignum_ccs[8][5*8] = {{
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
}, {
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0
}, {
1, 1, 0, 1, 1,
1, 1, 0, 1, 1,
1, 1, 0, 1, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
}, {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0
}, {
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 0, 0
}, {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 0, 1, 1,
1, 1, 0, 1, 1,
1, 1, 0, 1, 1,
0, 0, 0, 0, 0
}, {
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 0, 0, 0
}, {
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 1, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
}};
if (p->ccmode != CCMODE_BIGNUM) {
int i;
if ( p->ccmode != CCMODE_STANDARD ) {
/* Not supported (yet) */
report(RPT_WARNING, "HD44780_init_num: Cannot combine two modes using user defined characters" );
return;
}
p->ccmode = CCMODE_BIGNUM;
for (i = 0; i < 8; i++)
HD44780_set_char (drvthis, i, bignum_ccs[i]);
}
}
/////////////////////////////////////////////////////////////////
// Writes a big number.
@@ -897,85 +649,26 @@ MODULE_EXPORT void
HD44780_num (Driver *drvthis, int x, int num)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
int do_init = 0;
char bignum_map[11][4][3] = {
{ /* 0: */
{ 1, 2, 3 },
{ 6, 32, 6 },
{ 6, 32, 6 },
{ 7, 2, 32 } },
{ /* 1: */
{ 7, 6, 32 },
{ 32, 6, 32 },
{ 32, 6, 32 },
{ 7, 2, 32 } },
{ /* 2: */
{ 1, 2, 3 },
{ 32, 5, 0 },
{ 1, 32, 32 },
{ 2, 2, 0 } },
{ /* 3: */
{ 1, 2, 3 },
{ 32, 5, 0 },
{ 3, 32, 6 },
{ 7, 2, 32 } },
{ /* 4: */
{ 32, 3, 6 },
{ 1, 32, 6 },
{ 2, 2, 6 },
{ 32, 32, 0 } },
{ /* 5: */
{ 1, 2, 0 },
{ 2, 2, 3 },
{ 3, 32, 6 },
{ 7, 2, 32 } },
{ /* 6: */
{ 1, 2, 32 },
{ 6, 5, 32 },
{ 6, 32, 6 },
{ 7, 2, 32 } },
{ /* 7: */
{ 2, 2, 6 },
{ 32, 1, 32 },
{ 32, 6, 32 },
{ 32, 0, 32 } },
{ /* 8: */
{ 1, 2, 3 },
{ 4, 5, 0 },
{ 6, 32, 6 },
{ 7, 2, 32 } },
{ /* 9: */
{ 1, 2, 3 },
{ 4, 3, 6 },
{ 32, 1, 32 },
{ 7, 32, 32 } },
{ /* colon: (only 1st column used) */
{ 32, 32, 32 },
{ 7, 32, 32 },
{ 7, 32, 32 },
{ 32, 32, 32 } }
};
if ((num < 0) || (num > 10))
if ((num < 0) || (num > 10))
return;
if (p->height >= 4) {
int y = (p->height - 2) / 2;
int x2, y2;
HD44780_init_num(drvthis);
for (x2 = 0; x2 < 3; x2++) {
for (y2 = 0; y2 < 4; y2++) {
HD44780_chr( drvthis, x+x2, y+y2, bignum_map[num][y2][x2] );
}
if (num == 10)
x2 = 2; /* =break, for colon only */
if (p->ccmode != bignum) {
if (p->ccmode != standard) {
/* Not supported (yet) */
report(RPT_WARNING, "%s: num: cannot combine two modes using user defined characters",
drvthis->name);
return;
}
p->ccmode = bignum;
do_init = 1;
}
else
HD44780_chr(drvthis, x, 1 + (p->height - 1) / 2,
(num == 10) ? ':' : (num + '0'));
// Lib_adv_bignum does everything needed to show the bignumbers.
lib_adv_bignum(drvthis, x, num, do_init, NUM_CCs);
}
/////////////////////////////////////////////////////////////////
@@ -986,29 +679,26 @@ HD44780_num (Driver *drvthis, int x, int num)
// The input is just an array of characters...
//
MODULE_EXPORT void
HD44780_set_char (Driver *drvthis, int n, char *dat)
HD44780_set_char (Driver *drvthis, int n, unsigned char *dat)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
int row, col;
int letter;
unsigned char mask = (1 << p->cellwidth) - 1;
int row;
if (n < 0 || n > 7)
if ((n < 0) || (n >= NUM_CCs))
return;
if (!dat)
return;
for (row = 0; row < p->cellheight; row++) {
letter = 0;
if (p->lastline || (row < p->cellheight - 1)) {
for (col = 0; col < p->cellwidth; col++) {
letter <<= 1;
letter |= (dat[(row * p->cellwidth) + col] > 0) ? 1 : 0;
}
}
if ( p->cc_buf[n*p->cellheight+row] != letter ) {
p->cc_dirty[n] = 1; /* only mark as dirty if really different */
}
p->cc_buf[n*p->cellheight+row] = letter;
int letter = 0;
if (p->lastline || (row < p->cellheight - 1))
letter = dat[row] & mask;
if (p->cc[n].cache[row] != letter)
p->cc[n].clean = 0; /* only mark dirty if really different */
p->cc[n].cache[row] = letter;
}
}
@@ -1018,78 +708,127 @@ HD44780_set_char (Driver *drvthis, int n, char *dat)
MODULE_EXPORT int
HD44780_icon (Driver *drvthis, int x, int y, int icon)
{
char heart_open[] = {
1, 1, 1, 1, 1,
1, 0, 1, 0, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 0, 0, 0, 1,
1, 1, 0, 1, 1,
1, 1, 1, 1, 1 };
char heart_filled[] = {
1, 1, 1, 1, 1,
1, 0, 1, 0, 1,
0, 1, 0, 1, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
1, 0, 1, 0, 1,
1, 1, 0, 1, 1,
1, 1, 1, 1, 1 };
char arrow_up[] = {
0, 0, 1, 0, 0,
0, 1, 1, 1, 0,
1, 0, 1, 0, 1,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 0, 0 };
char arrow_down[] = {
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
1, 0, 1, 0, 1,
0, 1, 1, 1, 0,
0, 0, 1, 0, 0,
0, 0, 0, 0, 0 };
char checkbox_off[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0 };
char checkbox_on[] = {
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
1, 1, 1, 0, 1,
1, 0, 1, 1, 0,
1, 0, 1, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0 };
char checkbox_gray[] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 0, 1, 0, 1,
1, 1, 0, 1, 1,
1, 0, 1, 0, 1,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0 };
char block_filled[] = {
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1 };
static unsigned char heart_open[] =
{ b__XXXXX,
b__X_X_X,
b_______,
b_______,
b_______,
b__X___X,
b__XX_XX,
b__XXXXX };
static unsigned char heart_filled[] =
{ b__XXXXX,
b__X_X_X,
b___X_X_,
b___XXX_,
b___XXX_,
b__X_X_X,
b__XX_XX,
b__XXXXX };
static unsigned char arrow_up[] =
{ b____X__,
b___XXX_,
b__X_X_X,
b____X__,
b____X__,
b____X__,
b____X__,
b_______ };
static unsigned char arrow_down[] =
{ b____X__,
b____X__,
b____X__,
b____X__,
b__X_X_X,
b___XXX_,
b____X__,
b_______ };
/*
static unsigned char arrow_left[] =
{ b_______,
b____X__,
b___X___,
b__XXXXX,
b___X___,
b____X__,
b_______,
b_______ };
static unsigned char arrow_right[] =
{ b_______,
b____X__,
b_____X_,
b__XXXXX,
b_____X_,
b____X__,
b_______,
b_______ };
*/
static unsigned char checkbox_off[] =
{ b_______,
b_______,
b__XXXXX,
b__X___X,
b__X___X,
b__X___X,
b__XXXXX,
b_______ };
static unsigned char checkbox_on[] =
{ b____X__,
b____X__,
b__XXX_X,
b__X_XX_,
b__X_X_X,
b__X___X,
b__XXXXX,
b_______ };
static unsigned char checkbox_gray[] =
{ b_______,
b_______,
b__XXXXX,
b__X_X_X,
b__XX_XX,
b__X_X_X,
b__XXXXX,
b_______ };
/*
static unsigned char selector_left[] =
{ b___X___,
b___XX__,
b___XXX_,
b___XXXX,
b___XXX_,
b___XX__,
b___X___,
b_______ };
static unsigned char selector_right[] =
{ b_____X_,
b____XX_,
b___XXX_,
b__XXXX_,
b___XXX_,
b____XX_,
b_____X_,
b_______ };
static unsigned char ellipsis[] =
{ b_______,
b_______,
b_______,
b_______,
b_______,
b_______,
b__X_X_X,
b_______ };
*/
static unsigned char block_filled[] =
{ b__XXXXX,
b__XXXXX,
b__XXXXX,
b__XXXXX,
b__XXXXX,
b__XXXXX,
b__XXXXX,
b__XXXXX };
/* Yes I know, this is a VERY BAD implementation */
switch ( icon ) {
@@ -1171,7 +910,7 @@ HD44780_get_key(Driver *drvthis)
return NULL;
}
// Otherwise a keypress will be returned
p->pressed_key_repetitions ++;
p->pressed_key_repetitions++;
}
else {
// It's a new keypress
+1 -1
View File
@@ -34,7 +34,7 @@ MODULE_EXPORT void HD44780_hbar (Driver *drvthis, int x, int y, int len, int pro
MODULE_EXPORT void HD44780_num (Driver *drvthis, int x, int num);
MODULE_EXPORT int HD44780_icon (Driver *drvthis, int x, int y, int icon);
MODULE_EXPORT void HD44780_set_char (Driver *drvthis, int n, char *dat);
MODULE_EXPORT void HD44780_set_char (Driver *drvthis, int n, unsigned char *dat);
MODULE_EXPORT void HD44780_backlight (Driver *drvthis, int on);
MODULE_EXPORT void HD44780_output (Driver *drvthis, int state);