Only flush modified defined characters.
This commit is contained in:
@@ -29,6 +29,14 @@ enum ifWidth { IF_4bit, IF_8bit };
|
|||||||
#define KEYPAD_MAXX 5
|
#define KEYPAD_MAXX 5
|
||||||
#define KEYPAD_MAXY 11
|
#define KEYPAD_MAXY 11
|
||||||
|
|
||||||
|
/* Constants for userdefchar_mode */
|
||||||
|
#define NUM_UDCs 8 /* number of characters */
|
||||||
|
#define UDCMODE_STANDARD 0 /* only char 0 is used for heartbeat */
|
||||||
|
#define UDCMODE_VBAR 1
|
||||||
|
#define UDCMODE_HBAR 2
|
||||||
|
#define UDCMODE_BIGNUM 3
|
||||||
|
#define UDCMODE_BIGCHAR 4
|
||||||
|
|
||||||
typedef struct ConnectionMapping {
|
typedef struct ConnectionMapping {
|
||||||
char *name;
|
char *name;
|
||||||
int (*init_fn) (Driver *drvthis);
|
int (*init_fn) (Driver *drvthis);
|
||||||
@@ -48,6 +56,10 @@ typedef struct driver_private_data {
|
|||||||
// For incremental updates store last lcd contents
|
// For incremental updates store last lcd contents
|
||||||
char *lcd_contents;
|
char *lcd_contents;
|
||||||
|
|
||||||
|
// The defineable characters
|
||||||
|
char *udc_buf;
|
||||||
|
char *udc_dirty;
|
||||||
|
|
||||||
// Connection type data
|
// Connection type data
|
||||||
int connectiontype_index;
|
int connectiontype_index;
|
||||||
struct hwDependentFns *hd44780_functions;
|
struct hwDependentFns *hd44780_functions;
|
||||||
@@ -89,6 +101,8 @@ typedef struct driver_private_data {
|
|||||||
|
|
||||||
int backlight_bit;
|
int backlight_bit;
|
||||||
|
|
||||||
|
int udcmode;
|
||||||
|
|
||||||
} PrivateData;
|
} PrivateData;
|
||||||
|
|
||||||
// Structures holding pointers to HD44780 specific functions
|
// Structures holding pointers to HD44780 specific functions
|
||||||
|
|||||||
+72
-13
@@ -72,6 +72,7 @@
|
|||||||
#include "shared/str.h"
|
#include "shared/str.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "hd44780.h"
|
#include "hd44780.h"
|
||||||
|
#include "report.h"
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
@@ -140,8 +141,9 @@ HD44780_init (Driver * drvthis, char *args)
|
|||||||
|
|
||||||
// Clear data struct
|
// Clear data struct
|
||||||
memset( p, 0, sizeof(*p) );
|
memset( p, 0, sizeof(*p) );
|
||||||
p->cellheight = 8;
|
p->cellheight = 8; /* Do not change this !!! This is a controller property, not a display property !!! */
|
||||||
p->cellwidth = 5;
|
p->cellwidth = 5;
|
||||||
|
p->udcmode = UDCMODE_STANDARD;
|
||||||
|
|
||||||
|
|
||||||
//// READ THE CONFIG FILE
|
//// READ THE CONFIG FILE
|
||||||
@@ -229,7 +231,16 @@ HD44780_init (Driver * drvthis, char *args)
|
|||||||
if (!p->lcd_contents) {
|
if (!p->lcd_contents) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(p->lcd_contents, ' ', p->width * p->height);
|
memset(p->lcd_contents, 0, p->width * p->height);
|
||||||
|
|
||||||
|
// Allocate and clear the buffer for defineable characters
|
||||||
|
p->udc_buf = (unsigned char *) malloc (NUM_UDCs * p->cellheight);
|
||||||
|
p->udc_dirty = (unsigned char *) malloc (NUM_UDCs);
|
||||||
|
if (!p->udc_buf || !p->udc_dirty) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(p->udc_buf, 0, NUM_UDCs * p->cellheight);
|
||||||
|
memset(p->udc_dirty, 1, NUM_UDCs); /* all udcs dirty */
|
||||||
|
|
||||||
// Backlight ?
|
// Backlight ?
|
||||||
if ( p->have_backlight ) {
|
if ( p->have_backlight ) {
|
||||||
@@ -432,8 +443,12 @@ HD44780_flush (Driver *drvthis)
|
|||||||
int wid = p->width;
|
int wid = p->width;
|
||||||
char ch;
|
char ch;
|
||||||
char drawing;
|
char drawing;
|
||||||
|
int row;
|
||||||
|
int i;
|
||||||
|
int count;
|
||||||
|
|
||||||
// Update LCD incrementally by comparing with last contents
|
// 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;
|
drawing = 0;
|
||||||
for (x=0 ; x<wid; x++) {
|
for (x=0 ; x<wid; x++) {
|
||||||
@@ -446,12 +461,35 @@ HD44780_flush (Driver *drvthis)
|
|||||||
p->hd44780_functions->senddata (p, p->spanList[y], RS_DATA, HD44780_charmap[(unsigned char)ch]);
|
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->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands
|
||||||
p->lcd_contents[(y*wid)+x] = ch;
|
p->lcd_contents[(y*wid)+x] = ch;
|
||||||
|
count ++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
drawing = 0;
|
drawing = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug( RPT_DEBUG, "HD44780: flushed %d chars", count );
|
||||||
|
|
||||||
|
/* Check which defineable chars we need to update */
|
||||||
|
count = 0;
|
||||||
|
for( i = 0; i < NUM_UDCs; i ++ ) {
|
||||||
|
if( p->udc_dirty[i] ) {
|
||||||
|
|
||||||
|
/* Tell the HD44780 we will redefine char number i */
|
||||||
|
p->hd44780_functions->senddata (p, 0, RS_INSTR, SETCHAR | i * 8);
|
||||||
|
p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands
|
||||||
|
|
||||||
|
/* Send the subsequent rows */
|
||||||
|
for (row = 0; row < p->cellheight; row++) {
|
||||||
|
p->hd44780_functions->senddata (p, 0, RS_DATA, p->udc_buf[i*p->cellheight+row]);
|
||||||
|
p->hd44780_functions->uPause (p, 40); /* Minimum exec time for all commands */
|
||||||
|
}
|
||||||
|
/* Mark as not dirty anymore */
|
||||||
|
p->udc_dirty[i] = 0;
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug( RPT_DEBUG, "HD44780: flushed %d udc's", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
@@ -462,6 +500,7 @@ HD44780_clear (Driver *drvthis)
|
|||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
memset(p->framebuf, ' ', p->width * p->height);
|
memset(p->framebuf, ' ', p->width * p->height);
|
||||||
|
p->udcmode = UDCMODE_STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
@@ -513,7 +552,7 @@ HD44780_backlight (Driver *drvthis, int on)
|
|||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
HD44780_init_vbar (Driver *drvthis)
|
HD44780_init_vbar (Driver *drvthis)
|
||||||
{
|
{
|
||||||
//PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
char a[] = {
|
char a[] = {
|
||||||
0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0,
|
||||||
@@ -586,6 +625,18 @@ HD44780_init_vbar (Driver *drvthis)
|
|||||||
1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if( p->udcmode == UDCMODE_VBAR ) {
|
||||||
|
/* Work already done */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p->udcmode != UDCMODE_STANDARD ) {
|
||||||
|
/* Not supported (yet) */
|
||||||
|
report( RPT_WARNING, "HD44780_init_vbar: Cannot combine two modes using user defined characters" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->udcmode = UDCMODE_VBAR;
|
||||||
|
|
||||||
HD44780_set_char (drvthis, 1, a);
|
HD44780_set_char (drvthis, 1, a);
|
||||||
HD44780_set_char (drvthis, 2, b);
|
HD44780_set_char (drvthis, 2, b);
|
||||||
HD44780_set_char (drvthis, 3, c);
|
HD44780_set_char (drvthis, 3, c);
|
||||||
@@ -601,7 +652,7 @@ HD44780_init_vbar (Driver *drvthis)
|
|||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
HD44780_init_hbar (Driver *drvthis)
|
HD44780_init_hbar (Driver *drvthis)
|
||||||
{
|
{
|
||||||
//PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
char a[] = {
|
char a[] = {
|
||||||
1, 0, 0, 0, 0,
|
1, 0, 0, 0, 0,
|
||||||
@@ -644,6 +695,18 @@ HD44780_init_hbar (Driver *drvthis)
|
|||||||
1, 1, 1, 1, 0,
|
1, 1, 1, 1, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if( p->udcmode == UDCMODE_HBAR ) {
|
||||||
|
/* Work already done */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p->udcmode != UDCMODE_STANDARD ) {
|
||||||
|
/* Not supported (yet) */
|
||||||
|
report( RPT_WARNING, "HD44780_init_hbar: Cannot combine two modes using user defined characters" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->udcmode = UDCMODE_HBAR;
|
||||||
|
|
||||||
HD44780_set_char (drvthis, 1, a);
|
HD44780_set_char (drvthis, 1, a);
|
||||||
HD44780_set_char (drvthis, 2, b);
|
HD44780_set_char (drvthis, 2, b);
|
||||||
HD44780_set_char (drvthis, 3, c);
|
HD44780_set_char (drvthis, 3, c);
|
||||||
@@ -698,7 +761,6 @@ HD44780_hbar (Driver *drvthis, int x, int y, int len)
|
|||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
HD44780_init_num (Driver *drvthis)
|
HD44780_init_num (Driver *drvthis)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
@@ -707,9 +769,6 @@ HD44780_init_num (Driver *drvthis)
|
|||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
HD44780_num (Driver *drvthis, int x, int num)
|
HD44780_num (Driver *drvthis, int x, int num)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
|
||||||
int offset = p->width * ( p->height / 2 );
|
|
||||||
p->framebuf[x+offset] = num + '0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
@@ -719,6 +778,7 @@ MODULE_EXPORT void
|
|||||||
HD44780_heartbeat (Driver *drvthis, int type)
|
HD44780_heartbeat (Driver *drvthis, int type)
|
||||||
{
|
{
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
static int timer = 0;
|
static int timer = 0;
|
||||||
int whichIcon;
|
int whichIcon;
|
||||||
static int saved_type = HEARTBEAT_ON;
|
static int saved_type = HEARTBEAT_ON;
|
||||||
@@ -764,17 +824,16 @@ HD44780_set_char (Driver *drvthis, int n, char *dat)
|
|||||||
if (!dat)
|
if (!dat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->hd44780_functions->senddata (p, 0, RS_INSTR, SETCHAR | n * 8);
|
|
||||||
p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands
|
|
||||||
|
|
||||||
for (row = 0; row < p->cellheight; row++) {
|
for (row = 0; row < p->cellheight; row++) {
|
||||||
letter = 0;
|
letter = 0;
|
||||||
for (col = 0; col < p->cellwidth; col++) {
|
for (col = 0; col < p->cellwidth; col++) {
|
||||||
letter <<= 1;
|
letter <<= 1;
|
||||||
letter |= (dat[(row * p->cellwidth) + col] > 0);
|
letter |= (dat[(row * p->cellwidth) + col] > 0);
|
||||||
}
|
}
|
||||||
p->hd44780_functions->senddata (p, 0, RS_DATA, letter);
|
if( p->udc_buf[n*p->cellheight+row] != letter ) {
|
||||||
p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands
|
p->udc_dirty[n] = 1; /* only mark as dirty if really different */
|
||||||
|
}
|
||||||
|
p->udc_buf[n*p->cellheight+row] = letter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user