overhauled CwLnx driver (Dave Pratt)

This commit is contained in:
marschap
2007-04-30 13:47:35 +00:00
parent 8331b37fa3
commit 34e8d1e1ae
4 changed files with 145 additions and 38 deletions
+3
View File
@@ -224,6 +224,9 @@ Karsten Festag
Gatewood Green Gatewood Green
- picolcd driver - picolcd driver
Dave Pratt
- overhauled CwLnx driver
Further developers in the sourceforge lcdproc team: Further developers in the sourceforge lcdproc team:
Mindaugas Idzelis aim4min Mindaugas Idzelis aim4min
+1
View File
@@ -14,6 +14,7 @@ v.0.5dev (ongoing development)
- server core: cleanup - remove unnecessary cruft - server core: cleanup - remove unnecessary cruft
* server core: refactor renderin code * server core: refactor renderin code
+ LCDd: config options TitleSpeed= and Heartbeat= + LCDd: config options TitleSpeed= and Heartbeat=
* overhauled CwLnx driver (Dave Pratt)
v.0.5.2 v.0.5.2
* fix switching on/off the Load screen in lcdproc client using the menu * fix switching on/off the Load screen in lcdproc client using the menu
+140 -37
View File
@@ -122,6 +122,7 @@ MODULE_EXPORT char *symbol_prefix = "CwLnx_";
static void CwLnx_linewrap(int fd, int on); static void CwLnx_linewrap(int fd, int on);
static void CwLnx_autoscroll(int fd, int on); static void CwLnx_autoscroll(int fd, int on);
static void CwLnx_hidecursor(int fd); static void CwLnx_hidecursor(int fd);
static void CwLnx_set_char_unrestricted(Driver *drvthis, int n, unsigned char *dat);
#define LCD_CMD 254 #define LCD_CMD 254
@@ -140,31 +141,37 @@ static void CwLnx_hidecursor(int fd);
#define LCD_SETCHAR 78 #define LCD_SETCHAR 78
#define LCD_ENABLE_SCROLL 81 #define LCD_ENABLE_SCROLL 81
#define LCD_DISABLE_SCROLL 82 #define LCD_DISABLE_SCROLL 82
#define LCD_SOFT_RESET 86
#define LCD_OFF_CURSOR 72 #define LCD_OFF_CURSOR 72
#define LCD_PUT_PIXEL 112 #define LCD_PUT_PIXEL 112
#define LCD_CLEAR_PIXEL 113 #define LCD_CLEAR_PIXEL 113
#define DELAY 2000 /* 2 milli sec */ #define DELAY 2000 /* 2 milli sec */
#define UPDATE_DELAY 0 /* 1 imicro sec */ #define UPDATE_DELAY 20000 /* 20 milliseconds */
#define SETUP_DELAY 1 /* 2 micro sec */ #define SETUP_DELAY 20000 /* 20 milliseconds */
#define MOVE_COST 5 /* # bytes for most move-to ops */
static int Write_LCD(int fd, char *c, int size) static int Write_LCD(int fd, char *c, int size)
{ {
int rc; int rc, wrote = 0;
int retries = 30; int retries = 30;
do { do {
rc = write(fd, c, size); rc = write(fd, c, size);
if (rc == size) if (rc > 0) {
c += rc;
size -= rc;
wrote += rc;
} else if (rc == 0 || (rc < 0 && errno == EAGAIN)) { /* would have blocked */
usleep(DELAY);
} else {
break; break;
usleep(DELAY); }
} while (size > 0 && --retries > 0);
} while (--retries > 0); return wrote;
return rc;
} }
@@ -392,7 +399,20 @@ CwLnx_autoscroll(int fd, int on)
static void static void
CwLnx_hidecursor(int fd) CwLnx_hidecursor(int fd)
{ {
Disable_Cursor(fd); Disable_Cursor(fd);
}
/********************************************************************
* Reset the display bios
*/
static void CwLnx_reboot(int fd)
{
char cmd[] = { LCD_CMD, LCD_SOFT_RESET, LCD_CMD_END };
Write_LCD(fd, cmd, 3);
usleep(SETUP_DELAY);
return;
} }
@@ -410,8 +430,6 @@ CwLnx_hidecursor(int fd)
MODULE_EXPORT int MODULE_EXPORT int
CwLnx_init(Driver *drvthis) CwLnx_init(Driver *drvthis)
{ {
struct termios portset_save;
char device[200] = DEFAULT_DEVICE; char device[200] = DEFAULT_DEVICE;
int speed = DEFAULT_SPEED; int speed = DEFAULT_SPEED;
char size[200] = DEFAULT_SIZE; char size[200] = DEFAULT_SIZE;
@@ -576,23 +594,26 @@ CwLnx_init(Driver *drvthis)
} }
report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); report(RPT_INFO, "%s: opened display on %s", drvthis->name, device);
/*
Since we don't know what speed the display is using when
we first connect to it, configure the port for the speed
we don't want to use, send a command to switch the display
to the speed we want to use, and flush the command.
*/
Init_Port(p->fd); Init_Port(p->fd);
tcgetattr(p->fd, &portset_save); if (speed == B9600) {
speed = B19200; Setup_Port(p->fd, B19200);
Setup_Port(p->fd, speed);
Set_9600(p->fd); Set_9600(p->fd);
close(p->fd); } else {
Setup_Port(p->fd, B9600);
p->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); Set_19200(p->fd);
if (p->fd == -1) {
report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno));
return -1;
} }
report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); tcdrain(p->fd);
usleep(SETUP_DELAY);
Init_Port(p->fd); Init_Port(p->fd);
speed = B9600;
Setup_Port(p->fd, speed); Setup_Port(p->fd, speed);
CwLnx_hidecursor(p->fd); CwLnx_hidecursor(p->fd);
CwLnx_linewrap(p->fd, 1); CwLnx_linewrap(p->fd, 1);
CwLnx_autoscroll(p->fd, 0); CwLnx_autoscroll(p->fd, 0);
@@ -712,7 +733,8 @@ CwLnx_flush(Driver *drvthis)
PrivateData *p = drvthis->private_data; PrivateData *p = drvthis->private_data;
int i, j; int i, j;
int move = 1; int iUpdate = 0, jUpdate = 0;
unsigned char *firstUpdate = NULL, *lastUpdate = NULL;
unsigned char *q = p->framebuf; unsigned char *q = p->framebuf;
unsigned char *r = p->backingstore; unsigned char *r = p->backingstore;
@@ -720,25 +742,43 @@ CwLnx_flush(Driver *drvthis)
for (i = 0; i < p->height; i++) { for (i = 0; i < p->height; i++) {
for (j = 0; j < p->width; j++) { for (j = 0; j < p->width; j++) {
if ((*q == *r) && !((0 < *q) && (*q < 16))) { if ((*q == *r) && !((0 < *q) && (*q < 16))) {
move = 1; if (firstUpdate && q - lastUpdate > MOVE_COST) {
} Set_Insert(p->fd, iUpdate, jUpdate);
else { Write_LCD(p->fd, (char *) firstUpdate,
/* Draw characters that have changed, as well lastUpdate - firstUpdate + 1);
* as custom characters. We know not if a custom firstUpdate = lastUpdate = NULL;
* character has changed. */ }
if (move == 1) { } else {
Set_Insert(p->fd, i, j); lastUpdate = q;
move = 0; if (!firstUpdate) {
firstUpdate = q;
iUpdate = i;
jUpdate = j;
} }
Write_LCD(p->fd, (char *) q, 1);
} }
q++; q++;
r++; r++;
} }
} }
memcpy(p->backingstore, p->framebuf, p->width * p->height); if (firstUpdate) {
} Set_Insert(p->fd, iUpdate, jUpdate);
Write_LCD(p->fd, (char *) firstUpdate,
lastUpdate - firstUpdate + 1);
}
memcpy(p->backingstore, p->framebuf, p->width * p->height);
if (p->backlight != p->saved_backlight ||
p->brightness != p->saved_brightness) {
if (!p->backlight) {
Backlight_Brightness(p->fd, 1);
} else {
Backlight_Brightness(p->fd, 1 + p->brightness * 6 / 900); /* 90% and up is full brightness */
}
p->saved_backlight = p->backlight;
p->saved_brightness = p->brightness;
}
}
/** /**
* Print a character on the screen at position (x,y). * Print a character on the screen at position (x,y).
@@ -904,7 +944,11 @@ CwLnx_hbar(Driver *drvthis, int x, int y, int len, int promille, int options)
for (i = 1; i <= p->cellwidth; i++) { for (i = 1; i <= p->cellwidth; i++) {
// fill pixel columns from left to right. // fill pixel columns from left to right.
memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar)); memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar));
#if defined(SEAMLESS_HBARS)
CwLnx_set_char_unrestricted(drvthis, i+1, hBar);
#else
CwLnx_set_char(drvthis, i+1, hBar); CwLnx_set_char(drvthis, i+1, hBar);
#endif
} }
} }
@@ -1020,6 +1064,65 @@ CwLnx_set_char(Driver *drvthis, int n, unsigned char *dat)
} }
/*
* Identical to CwLnx_set_char, but it doesn't restrict the 12232 to
* using only 5 of its 6 columns. Full 6-column mode is required
* for seamless H-bars.
*/
#if defined(SEAMLESS_HBARS)
static void
CwLnx_set_char_unrestricted(Driver *drvthis, int n, unsigned char *dat)
{
PrivateData *p = drvthis->private_data;
char c;
int rc;
if ((n <= 0) || (n > CwLnx_get_free_chars(drvthis)))
return;
if (!dat)
return;
c = LCD_CMD;
rc = Write_LCD(p->fd, &c, 1);
c = LCD_SETCHAR;
rc = Write_LCD(p->fd, &c, 1);
c = (char) n;
rc = Write_LCD(p->fd, &c, 1);
if (p->model == 1602) { // the character model
unsigned char mask = (1 << p->cellwidth) - 1;
int row;
for (row = 0; row < p->cellheight; row++) {
c = dat[row] & mask;
Write_LCD(p->fd, &c, 1);
}
} else if (p->model == 12232) { // the graphical model
int col;
for (col = p->cellwidth - 1; col >= 0; col--) {
int letter = 0;
int row;
for (row = p->cellheight - 1; row >= 0; row--) {
letter <<= 1;
letter |= ((dat[row] >> col) & 1);
}
c = letter;
Write_LCD(p->fd, &c, 1);
}
}
c = LCD_CMD_END;
rc = Write_LCD(p->fd, &c, 1);
}
#endif
/** /**
* Place an icon on the screen. * Place an icon on the screen.
* \param drvthis Pointer to driver structure. * \param drvthis Pointer to driver structure.
+1 -1
View File
@@ -31,7 +31,7 @@
#define DEFAULT_DEVICE "/dev/lcd" #define DEFAULT_DEVICE "/dev/lcd"
#define DEFAULT_BACKLIGHT 1 #define DEFAULT_BACKLIGHT 1
#define DEFAULT_BRIGHTNESS 200 #define DEFAULT_BRIGHTNESS 700
#define DEFAULT_CELL_WIDTH_1602 5 #define DEFAULT_CELL_WIDTH_1602 5
#define DEFAULT_CELL_WIDTH_12232 6 #define DEFAULT_CELL_WIDTH_12232 6