diff --git a/ChangeLog b/ChangeLog index a572fb3..7cb3fe7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ v.0.5dev (ongoing development) * lcdproc: Make the iface screen more readable on 2x16 displays * All drivers: sync functions with prototypes * Port remaining drivers to 0.5 API (glk, lcdm001, stv5730) + * Pyramid: Only send LED state changes, doxygen-ize v0.5.4 * Update driver includes and LDFLAGS (fixed glk and bayrad binding error) diff --git a/server/drivers/pylcd.c b/server/drivers/pylcd.c index 6243c0e..5d2ce3e 100644 --- a/server/drivers/pylcd.c +++ b/server/drivers/pylcd.c @@ -49,6 +49,9 @@ * - correct escaping for characters 128-255 (also fixes the 'ß' issue) * - correct icons (custom chars 8-15 cannot be set, checkboxes were wrong) * - Add a delay after set_char. This seems to fix occasional hangs + * - Cache status of LEDs and only send on update, reduces communication + * - Add prototypes for all and Doxygen comments to internal functions + * - remove unused read_ACK() */ #include @@ -90,14 +93,21 @@ MODULE_EXPORT char *symbol_prefix = "pyramid_"; /* Prototypes: */ -int send_ACK(PrivateData *); +static int data_ready(PrivateData *p); +static int read_tele(PrivateData *p, char *buffer); +static int real_send_tele(PrivateData *p, char *buffer, int len); +static int send_tele(PrivateData *p, char *buffer); +static int send_ACK(PrivateData *p); +static unsigned long long timestamp(PrivateData *p); +static int initTTY(Driver *drvthis, int FD); /* local functions for pylcd.c */ -/* Performs an select on the device used. Returns if no data is available at the - moment. Used to keep reading-operations from blocking the driver. +/** + * Performs an select on the device used. Returns if no data is available at + * the moment. Used to keep reading-operations from blocking the driver. */ -int +static int data_ready(PrivateData *p) { FD_ZERO(&p->rdfs); @@ -105,12 +115,17 @@ data_ready(PrivateData *p) return select(p->FD+1, &p->rdfs, NULL, NULL, &p->timeout)>0; } -/* Reads one telegramm, stores the telegramm without ETX/STX in buffer - returns True on successful detection of a telegram, False if nothing was read - or the telegramm didn't match its CC or if MAXCOUNT was exeeded without - reading a complete telegramm. + +/** + * Reads one telegramm, stores the telegramm without ETX/STX in buffer. + * \param p Pointer to driver's private data + * \param buffer Pointer to memory to store the telegram in. Must be at least + * MAXOUNT size! + * \return True (1) on successful detection of a telegram, False (0) if + * nothing was read or the telegramm didn't match its CC or if + * MAXCOUNT was exeeded without reading a complete telegramm. */ -int +static int read_tele(PrivateData *p, char *buffer) { char zeichen=0; @@ -166,27 +181,21 @@ read_tele(PrivateData *p, char *buffer) } } -/* Wrapper for reading an acknowledge telegramm. - */ -int -read_ACK(PrivateData *p) -{ - char buffer[MAXCOUNT]; - int retval=read_tele(p, buffer); - - return (retval && buffer[0]=='Q'); -} - -/* Send the input as telegramm. +/** + * Send the input as telegramm. * - * The telegram buffer just contains the raw telegram data - * - It shall not contain and marks - * - It may contain bytes below 0x20, they are automatically escaped by - * real_sent_tele + * 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. * - * NOTE: This function does not wait for any ACKs. + * \param p Pointer to driver's private data + * \param buffer Buffer containing the data to send + * \param len Number of bytes to send from buffer + * \return Always 0 + * + * \note This function does not wait for any ACKs. */ -int +static int real_send_tele(PrivateData *p, char *buffer, int len) { char cc=0x00; @@ -194,11 +203,11 @@ real_send_tele(PrivateData *p, char *buffer, int len) char buffer2[255]; i=0; j=0; - buffer2[j++]=2; // emit + buffer2[j++]=2; /* emit */ - /* copy the whole telegram package and escape - * characters below 0x20. - * ie. 0x8 --> 0x28 + /* + * copy the whole telegram package and escape characters below 0x20. + * ie. 0x8 --> 0x28. */ while (len-- && j < 253) { @@ -209,8 +218,8 @@ real_send_tele(PrivateData *p, char *buffer, int len) buffer2[j++]=buffer[i++]; } } - buffer2[j++]=3; // emit - len=j; // new package length + buffer2[j++]=3; /* emit */ + len=j; /* new package length */ /* calculate over all bytes */ for (i=0; iled[i] ? '1' : '0'; - send_tele(p, tele); - } - - return 0; -} /* Driver functions according to current API-Version */ @@ -394,23 +393,20 @@ pyramid_init (Driver *drvthis) send_tele(p, "C0101"); send_tele(p, "M3"); + /* invalidate LED status to make output(0) work */ + for (i = 0; i < 7; i++) + p->led[i] = -1; /* hardware selftest + clear all LEDs */ + pyramid_output(drvthis, 0); /* needed, otherwise L11 won't work */ for (i = 0; i < 7; i++) { - p->led[i?i-1:0] = 0; - p->led[i] = 1; - set_leds(p); + pyramid_output(drvthis, 1 << i); usleep(10000); } for (i = 6; i >= 0; i--) { - p->led[i+1] = 0; - p->led[i] = 1; - set_leds(p); + pyramid_output(drvthis, 1 << i); usleep(10000); } - for (i = 0; i < 7; i++) { - p->led[i] = 0; - } - set_leds(p); + pyramid_output(drvthis, 0); report(RPT_DEBUG, "%s: init() done", drvthis->name); @@ -496,22 +492,24 @@ pyramid_flush (Driver *drvthis) { memcpy(mesg, p->framebuffer, 33); - // we got the japanese HD44780U, so convert the german umlauts and - // other stuff + /* + * we got the japanese HD44780U, so convert the german umlauts and + * other stuff, assuming input is iso_8859-1. + */ for (i=1; i<33; i++) { switch ((unsigned char)mesg[i]) { - // assume input is iso_8859-1 - case 0xe4: mesg[i]=0xe1; break; // ä - case 0xf6: mesg[i]=0xef; break; // ö - case 0xfc: mesg[i]=0xf5; break; // ü - case 0xdf: mesg[i]=0xe2; break; // ß - case 0xb7: mesg[i]=0xa5; break; // · - case 0xb0: mesg[i]=0xdf; break; // ° + case 0xe4: mesg[i]=0xe1; break; /* ä */ + case 0xf6: mesg[i]=0xef; break; /* ö */ + case 0xfc: mesg[i]=0xf5; break; /* ü */ + case 0xdf: mesg[i]=0xe2; break; /* ß */ + case 0xb7: mesg[i]=0xa5; break; /* · */ + case 0xb0: mesg[i]=0xdf; break; /* ° */ } } + /* We do not wait for the ACK here, these are read by get_key() */ send_tele(p, "C0101"); - real_send_tele(p, mesg, 33); /* We do not wait for the ACK here*/ + real_send_tele(p, mesg, 33); p->FB_modified=False; p->last_buf_time=current_time; @@ -594,7 +592,7 @@ MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat) return; } - // which character? + /* which character? */ tele[1]=n+0x40; for (row = 0; row < p->cellheight; row++) { @@ -603,9 +601,8 @@ MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat) pixels <<= 1; pixels |= (dat[(row * p->cellwidth) + column] != 0); } - pixels |= 0x40; // pixel information is transferred with - // an offset of 40h - + /* pixel information is transferred with an offset of 40h */ + pixels |= 0x40; tele[row+2]=pixels; } real_send_tele(p, tele, 10); @@ -1077,11 +1074,9 @@ pyramid_icon (Driver *drvthis, int x, int y, int icon) } -/* +/* TODO: Implement this after converting to 8 byte CC. MODULE_EXPORT void pyramid_num (Driver *drvthis, int x, int num){}; -MODULE_EXPORT void -pyramid_heartbeat (Driver *drvthis, int state){}; */ /** @@ -1118,21 +1113,6 @@ pyramid_cursor (Driver *drvthis, int x, int y, int state) /* Hardware functions */ -#if 0 -// all of these are not supported by the display (data sheet) -MODULE_EXPORT int -pyramid_get_contrast (Driver *drvthis){return 0;}; -MODULE_EXPORT void -pyramid_set_contrast (Driver *drvthis, int promille){}; -MODULE_EXPORT int -pyramid_get_brightness (Driver *drvthis, int state){return 0;}; -MODULE_EXPORT void -pyramid_set_brightness (Driver *drvthis, int state, int promille){}; -MODULE_EXPORT void -pyramid_backlight (Driver *drvthis, int on) -#endif - - /** * Set output port. * Setting an output port bit lights the associated LED; @@ -1145,11 +1125,16 @@ pyramid_output (Driver *drvthis, int state) { PrivateData *p = (PrivateData *) drvthis->private_data; int i; + char tele[]= {"L00"}; - for (i = 0; i < 7; i++) - p->led[i] = state & (1 << i); - - set_leds(p); + for (i = 0; i < 7; i++) { + if (p->led[i] != (state & (1 << i))) { + p->led[i] = state & (1 << i); + tele[1] = i + '1'; + tele[2] = p->led[i] ? '1' : '0'; + send_tele(p, tele); + } + } if(state & (1 << 8)) { pyramid_init_custom1(drvthis); @@ -1259,7 +1244,7 @@ pyramid_get_key (Driver *drvthis) return "Escape+Enter"; #endif - return NULL; // Ignore combined key events + return NULL; /* Ignore combined key events */ } diff --git a/server/drivers/pylcd.h b/server/drivers/pylcd.h index e4e4e51..4325681 100644 --- a/server/drivers/pylcd.h +++ b/server/drivers/pylcd.h @@ -32,12 +32,10 @@ # include "config.h" #endif -#define MAXCOUNT 10 +#define MAXCOUNT 10 /* Including terminating NUL */ #define WIDTH 16 #define HEIGHT 2 -//Pyramid DS says 16, HD44780U DS says 8 -//#define CUSTOMCHARS 16 #define CUSTOMCHARS 8 #define CELLHEIGHT 8 @@ -79,5 +77,25 @@ typedef struct pyramid_private_data { } PrivateData; +MODULE_EXPORT int pyramid_init (Driver *drvthis); +MODULE_EXPORT void pyramid_close (Driver *drvthis); +MODULE_EXPORT int pyramid_width (Driver *drvthis); +MODULE_EXPORT int pyramid_height (Driver *drvthis); +MODULE_EXPORT int pyramid_cellwidth (Driver *drvthis); +MODULE_EXPORT int pyramid_cellheight (Driver *drvthis); +MODULE_EXPORT void pyramid_clear (Driver *drvthis); +MODULE_EXPORT void pyramid_flush (Driver *drvthis); +MODULE_EXPORT void pyramid_string (Driver *drvthis, int x, int y, const char string[]); +MODULE_EXPORT void pyramid_chr (Driver *drvthis, int x, int y, char c); +MODULE_EXPORT void pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT int pyramid_icon (Driver *drvthis, int x, int y, int icon); +MODULE_EXPORT void pyramid_cursor (Driver *drvthis, int x, int y, int state); +MODULE_EXPORT int pyramid_get_free_chars (Driver *drvthis); +MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat); +MODULE_EXPORT void pyramid_output (Driver *drvthis, int state); +MODULE_EXPORT const char * pyramid_get_key (Driver *drvthis); +MODULE_EXPORT const char * pyramid_get_info (Driver *drvthis); + #endif