extend pyramid driver fixing a few bugs on the way
This commit is contained in:
@@ -41,6 +41,7 @@ lirc_LDADD = @LIBLIRC_CLIENT@
|
|||||||
lcterm_LDADD = libLCD.a
|
lcterm_LDADD = libLCD.a
|
||||||
mtc_s16209x_LDADD = libLCD.a
|
mtc_s16209x_LDADD = libLCD.a
|
||||||
NoritakeVFD_LDADD = libLCD.a
|
NoritakeVFD_LDADD = libLCD.a
|
||||||
|
pyramid_LDADD = libLCD.a
|
||||||
serialVFD_LDADD = libLCD.a libbignum.a
|
serialVFD_LDADD = libLCD.a libbignum.a
|
||||||
svga_LDADD = @LIBSVGA@
|
svga_LDADD = @LIBSVGA@
|
||||||
t6963_LDADD = libLCD.a
|
t6963_LDADD = libLCD.a
|
||||||
|
|||||||
+425
-59
@@ -33,6 +33,10 @@
|
|||||||
* Changes:
|
* Changes:
|
||||||
* 2006-02-20 Stefan Reinauer <stepan@coresystems.de>
|
* 2006-02-20 Stefan Reinauer <stepan@coresystems.de>
|
||||||
* - add support for onboard LEDs via "output" command
|
* - add support for onboard LEDs via "output" command
|
||||||
|
* 2006-04-12 Stefan Reinauer <stepan@coresystems.de>
|
||||||
|
* - add support for user defined characters (set_char/get_free_chars)
|
||||||
|
* - add support for vbars/hbars, get_info, reorganize pyramid_init()
|
||||||
|
* - fixed a timing bug and implemented escaping in (real_)send_tele()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -54,6 +58,7 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "lcd_lib.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
|
|
||||||
#define min(a, b) ((a)<(b) ? (a) : (b))
|
#define min(a, b) ((a)<(b) ? (a) : (b))
|
||||||
@@ -71,7 +76,6 @@ MODULE_EXPORT int stay_in_foreground = 0;
|
|||||||
MODULE_EXPORT int supports_multiple = 0;
|
MODULE_EXPORT int supports_multiple = 0;
|
||||||
MODULE_EXPORT char *symbol_prefix = "pyramid_";
|
MODULE_EXPORT char *symbol_prefix = "pyramid_";
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes: */
|
/* Prototypes: */
|
||||||
|
|
||||||
int send_ACK(PrivateData *);
|
int send_ACK(PrivateData *);
|
||||||
@@ -153,31 +157,70 @@ read_ACK(PrivateData *p)
|
|||||||
return (retval && buffer[0]=='Q');
|
return (retval && buffer[0]=='Q');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the input as telegramm. Depending on value for wfack
|
/* Send the input as telegramm.
|
||||||
this routine waits for an ACK and retransmitts till an ACK is received or
|
*
|
||||||
doesn't expect an ACK.
|
* The telegram buffer just contains the raw telegram data
|
||||||
|
* - It shall not contain <STX> and <ETX> marks
|
||||||
|
* - It may contain bytes below 0x20, they are automatically escaped by
|
||||||
|
* real_sent_tele
|
||||||
|
*
|
||||||
|
* NOTE: This function does not wait for any ACKs.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
send_tele(PrivateData *p, char *buffer)
|
real_send_tele(PrivateData *p, char *buffer, int len)
|
||||||
{
|
{
|
||||||
char cc=0x00;
|
char cc=0x00;
|
||||||
int i, len;
|
int i, j;
|
||||||
char buffer2[255];
|
char buffer2[255];
|
||||||
|
|
||||||
sprintf(buffer2,"\2%s\3", buffer);
|
i=0; j=0;
|
||||||
len=strlen(buffer2);
|
buffer2[j++]=2; // emit <STX>
|
||||||
|
|
||||||
|
/* copy the whole telegram package and escape
|
||||||
|
* characters below 0x20.
|
||||||
|
* ie. 0x8 --> <ESC> 0x28
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
if (buffer[i]<0x20) {
|
||||||
|
buffer2[j++]=0x1b;
|
||||||
|
buffer2[j++]=buffer[i++]+0x20;
|
||||||
|
} else {
|
||||||
|
buffer2[j++]=buffer[i++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer2[j++]=3; // emit <ETX>
|
||||||
|
len=j; // new package length
|
||||||
|
|
||||||
|
/* calculate <BCC> over all bytes */
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<len; i++)
|
||||||
cc ^= buffer2[i];
|
cc ^= buffer2[i];
|
||||||
|
|
||||||
buffer2[len]=cc;
|
buffer2[len++]=cc;
|
||||||
|
|
||||||
write(p->FD, buffer2, len+1);
|
write(p->FD, buffer2, len);
|
||||||
/* tcflush (p->FD, TCIFLUSH); */
|
/* tcflush (p->FD, TCIFLUSH); */
|
||||||
|
|
||||||
|
/* Take a little nap. This works as a pacemaker */
|
||||||
|
usleep(50);
|
||||||
|
|
||||||
debug(RPT_DEBUG, "%s: sent %s", __FUNCTION__, buffer);
|
debug(RPT_DEBUG, "%s: sent %s", __FUNCTION__, buffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we know what our telegrams look like, we may use
|
||||||
|
* send_tele instead of real_send_tele.
|
||||||
|
* NOTE: This only works when there are no NULL bytes
|
||||||
|
* in the telegram
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
send_tele(PrivateData *p, char *buffer)
|
||||||
|
{
|
||||||
|
return real_send_tele(p, buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrapper for sending ACKs via real_send_tele
|
/* Wrapper for sending ACKs via real_send_tele
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@@ -253,6 +296,8 @@ pyramid_init (Driver *drvthis, char *args)
|
|||||||
int i;
|
int i;
|
||||||
PrivateData *p;
|
PrivateData *p;
|
||||||
|
|
||||||
|
/* get memory for private data */
|
||||||
|
|
||||||
p = (PrivateData *) malloc(sizeof(PrivateData));
|
p = (PrivateData *) malloc(sizeof(PrivateData));
|
||||||
if ((p == NULL) || (drvthis->store_private_ptr(drvthis, p) < 0))
|
if ((p == NULL) || (drvthis->store_private_ptr(drvthis, p) < 0))
|
||||||
{
|
{
|
||||||
@@ -260,13 +305,35 @@ pyramid_init (Driver *drvthis, char *args)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read config file: */
|
/* fill static elements of private data */
|
||||||
|
p->width = WIDTH;
|
||||||
|
p->height = HEIGHT;
|
||||||
|
p->customchars=CUSTOMCHARS;
|
||||||
|
p->cellwidth=CELLWIDTH;
|
||||||
|
p->cellheight=CELLHEIGHT;
|
||||||
|
p->custom = normal;
|
||||||
|
|
||||||
|
strcpy(p->last_key_pressed, NOKEY);
|
||||||
|
p->last_key_time = timestamp(p);
|
||||||
|
p->last_buf_time = timestamp(p);
|
||||||
|
|
||||||
|
p->timeout.tv_sec = 0;
|
||||||
|
p->timeout.tv_usec = MICROTIMEOUT;
|
||||||
|
|
||||||
|
strcpy(p->framebuffer, "D ");
|
||||||
|
p->FB_modified = 1;
|
||||||
|
|
||||||
|
/* read config file, fill configuration
|
||||||
|
* dependent elements of private data
|
||||||
|
*/
|
||||||
|
|
||||||
/* Which serial device should be used? */
|
/* Which serial device should be used? */
|
||||||
strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, "/dev/lcd"), sizeof(p->device));
|
strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, "/dev/lcd"), sizeof(p->device));
|
||||||
p->device[sizeof(p->device)-1] = '\0';
|
p->device[sizeof(p->device)-1] = '\0';
|
||||||
report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device);
|
report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device);
|
||||||
|
|
||||||
|
/* Initialize connection to the LCD */
|
||||||
|
|
||||||
/* open and initialize serial device */
|
/* open and initialize serial device */
|
||||||
p->FD = open(p->device, O_RDWR);
|
p->FD = open(p->device, O_RDWR);
|
||||||
|
|
||||||
@@ -274,23 +341,16 @@ pyramid_init (Driver *drvthis, char *args)
|
|||||||
report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, p->device, strerror(errno));
|
report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, p->device, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initTTY(drvthis, p->FD) != 0)
|
if (initTTY(drvthis, p->FD) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
p->timeout.tv_sec = 0;
|
|
||||||
p->timeout.tv_usec = MICROTIMEOUT;
|
|
||||||
p->width = WIDTH;
|
|
||||||
p->height = HEIGHT;
|
|
||||||
p->LEDtoggle = 0;
|
|
||||||
strcpy(p->last_key_pressed, NOKEY);
|
|
||||||
p->last_key_time = timestamp(p);
|
|
||||||
p->last_buf_time = timestamp(p);
|
|
||||||
|
|
||||||
/* Acknowledge all telegramms, the device may yet be sending.
|
/* Acknowledge all telegramms, the device may yet be sending.
|
||||||
(Reset doesn't clear telegramms, darn protocol ... )
|
* (Reset doesn't clear telegramms, darn protocol ... )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tcflush(p->FD, TCIFLUSH); /* clear everything */
|
tcflush(p->FD, TCIFLUSH); /* clear everything */
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
i = read_tele(p, buffer);
|
i = read_tele(p, buffer);
|
||||||
if (i == True)
|
if (i == True)
|
||||||
@@ -300,19 +360,27 @@ pyramid_init (Driver *drvthis, char *args)
|
|||||||
usleep(600000);
|
usleep(600000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now Reset and clear */
|
/* Initialize the display hardware: reset, clear and set cursor shape */
|
||||||
|
|
||||||
send_tele(p, "R");
|
send_tele(p, "R");
|
||||||
send_tele(p, "C0101");
|
send_tele(p, "C0101");
|
||||||
send_tele(p, "D ");
|
send_tele(p, "D ");
|
||||||
send_tele(p, "C0101");
|
send_tele(p, "C0101");
|
||||||
send_tele(p, "M3");
|
send_tele(p, "M3");
|
||||||
strcpy(p->framebuffer, "D ");
|
|
||||||
p->FB_modified = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
/* hardware selftest + clear all LEDs */
|
||||||
p->led[i] = 0;
|
for (i = 0; i < 7; i++) {
|
||||||
set_leds(p);
|
p->led[i?i-1:0] = 0;
|
||||||
|
p->led[i] = 1;
|
||||||
|
set_leds(p);
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
for (i = 6; i >= 0; i--) {
|
||||||
|
p->led[i+1] = 0;
|
||||||
|
p->led[i] = 1;
|
||||||
|
set_leds(p);
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
|
||||||
report(RPT_DEBUG, "%s: init() done", drvthis->name);
|
report(RPT_DEBUG, "%s: init() done", drvthis->name);
|
||||||
|
|
||||||
@@ -352,9 +420,9 @@ pyramid_clear (Driver *drvthis)
|
|||||||
strcpy(p->framebuffer, "D ");
|
strcpy(p->framebuffer, "D ");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* flushed the content of the framebuffer to the display.
|
/* flush the content of the framebuffer to the display.
|
||||||
p->FB_modified tells if the content was modified. If not,
|
* p->FB_modified tells if the content was modified. If not,
|
||||||
that means, nothing has to be done
|
* that means, nothing has to be done
|
||||||
*/
|
*/
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
pyramid_flush (Driver *drvthis)
|
pyramid_flush (Driver *drvthis)
|
||||||
@@ -366,7 +434,7 @@ pyramid_flush (Driver *drvthis)
|
|||||||
if ((p->FB_modified==True) && (current_time>(p->last_buf_time+40000)))
|
if ((p->FB_modified==True) && (current_time>(p->last_buf_time+40000)))
|
||||||
{
|
{
|
||||||
send_tele(p, "C0101");
|
send_tele(p, "C0101");
|
||||||
send_tele(p, p->framebuffer); /* We do not wait for the ACK here*/
|
real_send_tele(p, p->framebuffer, 33); /* We do not wait for the ACK here*/
|
||||||
p->FB_modified=False;
|
p->FB_modified=False;
|
||||||
p->last_buf_time=current_time;
|
p->last_buf_time=current_time;
|
||||||
sprintf(mesg, "C%02d%02d", p->C_x, p->C_y);
|
sprintf(mesg, "C%02d%02d", p->C_x, p->C_y);
|
||||||
@@ -403,19 +471,323 @@ pyramid_chr (Driver *drvthis, int x, int y, char c)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Extended functions */
|
/* User defined characters */
|
||||||
|
|
||||||
|
MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat)
|
||||||
|
{
|
||||||
|
char tele[10] = "G@ABCDEFGH";
|
||||||
|
int row, column, pixels;
|
||||||
|
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
|
|
||||||
|
if (n<0 && n>15) {
|
||||||
|
debug(RPT_DEBUG, "only characters 0-15 can be changed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dat) {
|
||||||
|
debug(RPT_DEBUG, "no character data\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// which character?
|
||||||
|
tele[1]=n+0x40;
|
||||||
|
|
||||||
|
for (row = 0; row < p->cellheight; row++) {
|
||||||
|
pixels=0;
|
||||||
|
for (column = 0; column < p->cellwidth; column++) {
|
||||||
|
pixels <<= 1;
|
||||||
|
pixels |= (dat[(row * p->cellwidth) + column] != 0);
|
||||||
|
}
|
||||||
|
pixels |= 0x40; // pixel information is transferred with
|
||||||
|
// an offset of 40h
|
||||||
|
|
||||||
|
tele[row+2]=pixels;
|
||||||
|
}
|
||||||
|
real_send_tele(p, tele, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_EXPORT int pyramid_get_free_chars (Driver *drvthis)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
return (p->customchars);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_EXPORT int pyramid_cellwidth (Driver *drvthis)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
return (p->cellwidth);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_EXPORT int pyramid_cellheight (Driver *drvthis)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
return (p->cellheight);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Sets up for vertical bars. Call before pyramid->vbar()
|
||||||
|
|
||||||
|
static void
|
||||||
|
pyramid_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->custom != vbar) {
|
||||||
|
pyramid_set_char (drvthis, 1, a);
|
||||||
|
pyramid_set_char (drvthis, 2, b);
|
||||||
|
pyramid_set_char (drvthis, 3, c);
|
||||||
|
pyramid_set_char (drvthis, 4, d);
|
||||||
|
pyramid_set_char (drvthis, 5, e);
|
||||||
|
pyramid_set_char (drvthis, 6, f);
|
||||||
|
pyramid_set_char (drvthis, 7, g);
|
||||||
|
p->custom = vbar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inits horizontal bars...
|
||||||
|
static void
|
||||||
|
pyramid_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, 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,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (p->custom != hbar) {
|
||||||
|
pyramid_set_char (drvthis, 1, a);
|
||||||
|
pyramid_set_char (drvthis, 2, b);
|
||||||
|
pyramid_set_char (drvthis, 3, c);
|
||||||
|
pyramid_set_char (drvthis, 4, d);
|
||||||
|
pyramid_set_char (drvthis, 5, e);
|
||||||
|
p->custom = hbar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws a vertical bar...
|
||||||
|
|
||||||
|
MODULE_EXPORT void
|
||||||
|
pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int options)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
|
pyramid_init_vbar(drvthis);
|
||||||
|
|
||||||
|
lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws a horizontal bar to the right.
|
||||||
|
|
||||||
|
MODULE_EXPORT void
|
||||||
|
pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int options)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
|
pyramid_init_hbar(drvthis);
|
||||||
|
|
||||||
|
lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_EXPORT int
|
||||||
|
pyramid_icon (Driver *drvthis, int x, int y, int icon)
|
||||||
|
{
|
||||||
|
char icons[3][5 * 8] = {
|
||||||
|
{
|
||||||
|
1, 1, 1, 1, 1, // Empty Heart
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
1, 1, 1, 1, 1, // Filled Heart
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, // Ellipsis
|
||||||
|
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, 0, 1, 0, 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
|
// notify the others that we messed up their character set.
|
||||||
|
// Unused for heartbeats as we should always leave that icon alone.
|
||||||
|
//
|
||||||
|
// Leaving this in the code as notification for other similar cases
|
||||||
|
if (p->custom == bign) {
|
||||||
|
printf("Switching to beat\n");
|
||||||
|
p->custom = beat;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch( icon ) {
|
||||||
|
case ICON_BLOCK_FILLED:
|
||||||
|
pyramid_chr( drvthis, x, y, 255 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICON_HEART_FILLED:
|
||||||
|
pyramid_set_char( drvthis, 0, icons[0] );
|
||||||
|
pyramid_chr( drvthis, x, y, 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICON_HEART_OPEN:
|
||||||
|
pyramid_set_char( drvthis, 0, icons[1] );
|
||||||
|
pyramid_chr( drvthis, x, y, 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("x=%d, y=%d, icon=%x\n", x,y,icon);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int pattern){};
|
|
||||||
MODULE_EXPORT void
|
|
||||||
pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int pattern){};
|
|
||||||
MODULE_EXPORT void
|
|
||||||
pyramid_num (Driver *drvthis, int x, int num){};
|
pyramid_num (Driver *drvthis, int x, int num){};
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
pyramid_heartbeat (Driver *drvthis, int state){};
|
pyramid_heartbeat (Driver *drvthis, int state){};
|
||||||
MODULE_EXPORT void
|
|
||||||
pyramid_icon (Driver *drvthis, int x, int y, int icon){};
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
@@ -428,22 +800,10 @@ pyramid_cursor (Driver *drvthis, int x, int y, int state)
|
|||||||
p->C_state = state;
|
p->C_state = state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Userdef characters, are those still supported ? */
|
|
||||||
|
|
||||||
/*
|
|
||||||
MODULE_EXPORT void
|
|
||||||
pyramid_set_char (Driver *drvthis, int n, char *dat){};
|
|
||||||
MODULE_EXPORT int
|
|
||||||
pyramid_get_free_chars (Driver *drvthis){return 0;};
|
|
||||||
MODULE_EXPORT int
|
|
||||||
pyramid_cellwidth (Driver *drvthis){return 0;};
|
|
||||||
MODULE_EXPORT int
|
|
||||||
pyramid_cellheight (Driver *drvthis){return 0;};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Hardware functions */
|
/* Hardware functions */
|
||||||
|
|
||||||
/*
|
#if 0
|
||||||
|
// all of these are not supported by the display (data sheet)
|
||||||
MODULE_EXPORT int
|
MODULE_EXPORT int
|
||||||
pyramid_get_contrast (Driver *drvthis){return 0;};
|
pyramid_get_contrast (Driver *drvthis){return 0;};
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
@@ -454,7 +814,7 @@ MODULE_EXPORT void
|
|||||||
pyramid_set_brightness (Driver *drvthis, int state, int promille){};
|
pyramid_set_brightness (Driver *drvthis, int state, int promille){};
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
pyramid_backlight (Driver *drvthis, int on)
|
pyramid_backlight (Driver *drvthis, int on)
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
MODULE_EXPORT void
|
MODULE_EXPORT void
|
||||||
pyramid_output (Driver *drvthis, int state)
|
pyramid_output (Driver *drvthis, int state)
|
||||||
@@ -480,7 +840,11 @@ pyramid_get_key (Driver *drvthis)
|
|||||||
int retval;
|
int retval;
|
||||||
PrivateData *p = (PrivateData *) drvthis->private_data;
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
|
||||||
/* Now we read everything from the display and as long as we got ACKs, we ignore them. */
|
/* Now we read everything from the display,
|
||||||
|
* and as long as we got ACKs, we ignore them.
|
||||||
|
* (eat up all pending ACKs)
|
||||||
|
*/
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
retval = read_tele(p, buffer);
|
retval = read_tele(p, buffer);
|
||||||
if ((retval == False) || (buffer[0] != 'Q')) break;
|
if ((retval == False) || (buffer[0] != 'Q')) break;
|
||||||
@@ -533,10 +897,12 @@ pyramid_get_key (Driver *drvthis)
|
|||||||
|
|
||||||
|
|
||||||
/* Returns a string. Server cannot modify this string. */
|
/* Returns a string. Server cannot modify this string. */
|
||||||
|
|
||||||
/*
|
|
||||||
MODULE_EXPORT const char *
|
MODULE_EXPORT const char *
|
||||||
pyramid_get_info (){return NULL;};
|
pylcd_get_info (Driver *drvthis)
|
||||||
*/
|
{
|
||||||
|
static char *pylcd_info_string="Pyramid LCD driver";
|
||||||
|
|
||||||
|
return pylcd_info_string;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+31
-3
@@ -5,6 +5,7 @@
|
|||||||
the "pyramid" LCD device from Pyramid.
|
the "pyramid" LCD device from Pyramid.
|
||||||
|
|
||||||
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
|
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
|
||||||
|
Copyright (C) 2006 coresystems GmbH <info@coresystems.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -35,25 +36,52 @@
|
|||||||
#define WIDTH 16
|
#define WIDTH 16
|
||||||
#define HEIGHT 2
|
#define HEIGHT 2
|
||||||
|
|
||||||
|
#define CUSTOMCHARS 16
|
||||||
|
#define CELLHEIGHT 8
|
||||||
|
#define CELLWIDTH 5
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
normal = 0,
|
||||||
|
hbar = 1,
|
||||||
|
vbar = 2,
|
||||||
|
bign = 4,
|
||||||
|
beat = 8
|
||||||
|
} custom_type;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
/* device io */
|
||||||
int FD;
|
int FD;
|
||||||
char device[255];
|
char device[255];
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
fd_set rdfs;
|
fd_set rdfs;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
|
/* device description */
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int customchars;
|
||||||
|
int cellwidth;
|
||||||
|
int cellheight;
|
||||||
|
|
||||||
|
/* output handling */
|
||||||
char framebuffer[WIDTH*HEIGHT+2];
|
char framebuffer[WIDTH*HEIGHT+2];
|
||||||
int FB_modified;
|
int FB_modified;
|
||||||
int LEDtoggle;
|
custom_type custom;
|
||||||
|
|
||||||
|
/* button handling */
|
||||||
char last_key_pressed[6];
|
char last_key_pressed[6];
|
||||||
unsigned long long last_key_time;
|
unsigned long long last_key_time;
|
||||||
unsigned long long last_buf_time;
|
unsigned long long last_buf_time;
|
||||||
|
|
||||||
|
/* cursor handling */
|
||||||
int C_x;
|
int C_x;
|
||||||
int C_y;
|
int C_y;
|
||||||
int C_state;
|
int C_state;
|
||||||
|
|
||||||
|
/* led handling */
|
||||||
char led[7];
|
char led[7];
|
||||||
|
|
||||||
} PrivateData;
|
} PrivateData;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user