From 1ffb8be56b4017149d8c108aee2eeaf881a88d3e Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Fri, 30 Jan 2004 07:12:35 +0000 Subject: [lcd4linux @ 2004-01-30 07:12:35 by reinelt] HD44780 busy-flag support from Martin Hejl loadavg() uClibc replacement from Martin Heyl round() uClibc replacement from Martin Hejl warning in i2c_sensors fixed [ --- drv_HD44780.c | 216 ++++++++++++++++++++++++++++++++++++++++++--------- plugin_i2c_sensors.c | 11 ++- plugin_loadavg.c | 50 +++++++++++- processor.c | 20 ++++- 4 files changed, 257 insertions(+), 40 deletions(-) diff --git a/drv_HD44780.c b/drv_HD44780.c index 7ca7d5b..7bcaade 100644 --- a/drv_HD44780.c +++ b/drv_HD44780.c @@ -1,4 +1,4 @@ -/* $Id: drv_HD44780.c,v 1.6 2004/01/29 04:40:02 reinelt Exp $ +/* $Id: drv_HD44780.c,v 1.7 2004/01/30 07:12:35 reinelt Exp $ * * new style driver for HD44780-based displays * @@ -29,6 +29,13 @@ * * * $Log: drv_HD44780.c,v $ + * Revision 1.7 2004/01/30 07:12:35 reinelt + * HD44780 busy-flag support from Martin Hejl + * loadavg() uClibc replacement from Martin Heyl + * round() uClibc replacement from Martin Hejl + * warning in i2c_sensors fixed + * [ + * * Revision 1.6 2004/01/29 04:40:02 reinelt * every .c file includes "config.h" now * @@ -70,6 +77,7 @@ #include #include #include +#include #include "debug.h" #include "cfg.h" @@ -95,6 +103,7 @@ static char Name[]="HD44780"; #define T_PW 450 // Enable pulse width #define T_AS 60 // Address setup time #define T_H 40 // Data hold time +#define T_AH 20 // Address hold time /* HD44780 execution timings [microseconds] @@ -106,12 +115,13 @@ static char Name[]="HD44780"; #define T_INIT2 100 // second init sequence: 100 usec #define T_EXEC 80 // normal execution time #define T_WRCG 120 // CG RAM Write -#define T_CLEAR 1640 // Clear Display +#define T_CLEAR 1680 // Clear Display static int Bits=0; -static int Controllers = 0; -static int Controller = 0; +static int numControllers = 0; +static int allControllers = 0; +static int currController = 0; static unsigned char SIGNAL_RW; static unsigned char SIGNAL_RS; @@ -119,6 +129,11 @@ static unsigned char SIGNAL_ENABLE; static unsigned char SIGNAL_ENABLE2; static unsigned char SIGNAL_GPO; +/* maximum time to wait for the busy-flag (in usec) */ +#define MAX_BUSYFLAG_WAIT 100000 +static int use_busy_flag = 0; + + // Fixme static int GPOS; // static int GPO=0; @@ -128,6 +143,107 @@ static int GPOS; // *** hardware dependant functions *** // **************************************** +static void wait_for_busy_flag(int controller) +{ + unsigned char enable; + unsigned int counter; + unsigned char data=0xFF; + unsigned char busymask=0; + + if (Bits==8) { + busymask = 0x80; + } else { + /* Since in 4-Bit mode DB0 on the parport is mapped to DB4 on the LCD + (and consequently, DB3 on the partport is mapped to DB7 on the LCD) + we need to listen for DB3 on the parport to go low + */ + busymask = 0x8; + } + + enable=SIGNAL_ENABLE; + + while (controller > 0) { + if (controller&0x01 && enable!=0) { + /* set data-lines to input*/ + drv_generic_parport_direction(1); + + if (Bits==8) { + // Set RW, clear RS + drv_generic_parport_control(SIGNAL_RW|SIGNAL_RS,SIGNAL_RW); + } else { + drv_generic_parport_data(SIGNAL_RW); + } + + // Address set-up time + ndelay(T_AS); + + // rise ENABLE + if (Bits==8) { + drv_generic_parport_control(enable,enable); + } else { + drv_generic_parport_data(SIGNAL_RW|enable); + } + + counter=0; + while (1) { + /* read the busy flag */ + data = drv_generic_parport_read(); + if ((data&busymask)==0) break; + + /* make sure we don't wait forever + - but only check after 5 iterations + that way, we won't slow down normal mode + (where we don't need the timeout anyway) */ + counter++; + + if (counter >= 5) { + struct timeval now, end; + + if (counter == 5) { + // determine the time when the timeout has expired + gettimeofday (&end, NULL); + end.tv_usec+=MAX_BUSYFLAG_WAIT; + while (end.tv_usec>1000000) { + end.tv_usec-=1000000; + end.tv_sec++; + } + } + + // get the current time + gettimeofday(&now, NULL); + if (now.tv_sec==end.tv_sec?now.tv_usec>=end.tv_usec:now.tv_sec>=end.tv_sec) { + error ("HD44780: timeout waiting for busy flag on controller %x (%x)", controller, data); + break; + + } + } + } + + // RS=low, RW=low, EN=low + if (Bits==8) { + // Lower EN + drv_generic_parport_control(enable,0); + + // Address hold time + ndelay(T_AH); + + drv_generic_parport_control(SIGNAL_RW|SIGNAL_RS,0); + } else { + // Lower EN + drv_generic_parport_data(SIGNAL_RW); + ndelay(T_AH); + drv_generic_parport_data(0); + } + + /* set data-lines to output*/ + drv_generic_parport_direction(0); + } + enable=SIGNAL_ENABLE2; + controller=controller >> 1; + } +} + + static void drv_HD_nibble(unsigned char controller, unsigned char nibble) { unsigned char enable; @@ -205,8 +321,8 @@ static void drv_HD_command (unsigned char controller, unsigned char cmd, int del } // wait for command completion - udelay(delay); - + if (!use_busy_flag) udelay(delay); + } @@ -217,6 +333,8 @@ static void drv_HD_data (unsigned char controller, char *string, int len, int de // sanity check if (len<=0) return; + if (use_busy_flag) wait_for_busy_flag(controller); + if (Bits==8) { // enable signal: 'controller' is a bitmask @@ -227,13 +345,22 @@ static void drv_HD_data (unsigned char controller, char *string, int len, int de if (controller&0x01) enable|=SIGNAL_ENABLE; if (controller&0x02) enable|=SIGNAL_ENABLE2; - // clear RW, set RS - drv_generic_parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); - - // Address set-up time - ndelay(T_AS); + if (!use_busy_flag) { + // clear RW, set RS + drv_generic_parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); + // Address set-up time + ndelay(T_AS); + } while (len--) { + + if (use_busy_flag) { + wait_for_busy_flag(controller); + // clear RW, set RS + drv_generic_parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); + // Address set-up time + ndelay(T_AS); + } // put data on DB1..DB8 drv_generic_parport_data (*(string++)); @@ -242,18 +369,19 @@ static void drv_HD_data (unsigned char controller, char *string, int len, int de drv_generic_parport_toggle (enable, 1, T_PW); // wait for command completion - udelay(delay); + if (!use_busy_flag) udelay(delay); } } else { // 4 bit mode while (len--) { + if (use_busy_flag) wait_for_busy_flag(controller); // send data with RS enabled drv_HD_byte (controller, *(string++), SIGNAL_RS); // wait for command completion - udelay(delay); + if (!use_busy_flag) udelay(delay); } } } @@ -264,11 +392,11 @@ static void drv_HD_goto (int row, int col) int pos; // handle multiple displays/controllers - if (Controllers>1 && row>=DROWS/2) { + if (numControllers>1 && row>=DROWS/2) { row -= DROWS/2; - Controller = 2; + currController = 2; } else { - Controller = 1; + currController = 1; } // 16x1 Displays are organized as 8x2 :-( @@ -284,7 +412,7 @@ static void drv_HD_goto (int row, int col) pos=(row%2)*64+(row/2)*20+col; } - drv_HD_command (Controller, (0x80|pos), T_EXEC); + drv_HD_command (currController, (0x80|pos), T_EXEC); } @@ -306,11 +434,14 @@ static int drv_HD_start (char *section) if (cfg_number(section, "GPOs", 0, 0, 8, &gpos)<0) return -1; info ("%s: controlling %d GPO's", Name, gpos); - if (cfg_number(section, "Controllers", 1, 1, 2, &Controllers)<0) return -1; - info ("%s: using display with %d controllers", Name, Controllers); + if (cfg_number(section, "Controllers", 1, 1, 2, &numControllers)<0) return -1; + info ("%s: using display with %d controllers", Name, numControllers); // current controller - Controller=1; + currController=1; + + // Bitmask for *all* Controllers + allControllers = numControllers==2 ? 3 : 1; DROWS = rows; DCOLS = cols; @@ -354,22 +485,35 @@ static int drv_HD_start (char *section) // initialize *both* displays if (Bits==8) { - drv_HD_command (0x03, 0x30, T_INIT1); // 8 Bit mode, wait 4.1 ms - drv_HD_command (0x03, 0x30, T_INIT2); // 8 Bit mode, wait 100 us - drv_HD_command (0x03, 0x38, T_EXEC); // 8 Bit mode, 1/16 duty cycle, 5x8 font + drv_HD_command (allControllers, 0x30, T_INIT1); // 8 Bit mode, wait 4.1 ms + drv_HD_command (allControllers, 0x30, T_INIT2); // 8 Bit mode, wait 100 us + drv_HD_command (allControllers, 0x38, T_EXEC); // 8 Bit mode, 1/16 duty cycle, 5x8 font } else { - drv_HD_nibble(0x03, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms - drv_HD_nibble(0x03, 0x03); udelay(T_INIT2); // 4 Bit mode, wait 100 us - drv_HD_nibble(0x03, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms - drv_HD_nibble(0x03, 0x02); udelay(T_INIT2); // 4 Bit mode, wait 100 us - drv_HD_command (0x03, 0x28, T_EXEC); // 4 Bit mode, 1/16 duty cycle, 5x8 font + drv_HD_nibble (allControllers, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms + drv_HD_nibble (allControllers, 0x03); udelay(T_INIT2); // 4 Bit mode, wait 100 us + drv_HD_nibble (allControllers, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms + drv_HD_nibble (allControllers, 0x02); udelay(T_INIT2); // 4 Bit mode, wait 100 us + drv_HD_command (allControllers, 0x28, T_EXEC); // 4 Bit mode, 1/16 duty cycle, 5x8 font + } + + drv_HD_command (allControllers, 0x08, T_EXEC); // Display off, cursor off, blink off + drv_HD_command (allControllers, 0x0c, T_CLEAR); // Display on, cursor off, blink off, wait 1.64 ms + drv_HD_command (allControllers, 0x06, T_EXEC); // curser moves to right, no shift + + // Save it in a local variable, until init is complete (for init, we can't use the busy flag) + if (cfg_number(section, "UseBusy", 0, 0, 1, &use_busy_flag)<0) return -1; + + // Make sure we don't use the busy flag, if it's set to GND + if (SIGNAL_RW == 0 && use_busy_flag != 0 ) { + debug("HD44780: Busyflag is to be used, but wiring set RW to GND. Disabling busy-flag"); + use_busy_flag=0; } - drv_HD_command (0x03, 0x08, T_EXEC); // Display off, cursor off, blink off - drv_HD_command (0x03, 0x0c, T_CLEAR); // Display on, cursor off, blink off, wait 1.64 ms - drv_HD_command (0x03, 0x06, T_EXEC); // curser moves to right, no shift - drv_HD_command (0x03, 0x01, T_CLEAR); // clear *both* displays - drv_HD_command (0x03, 0x03, T_CLEAR); // return home + info("HD44780: %susing Busyflag", use_busy_flag?"":"not "); + + drv_HD_command (allControllers, 0x01, T_CLEAR); // clear *both* displays + drv_HD_command (allControllers, 0x03, T_CLEAR); // return home + return 0; } @@ -377,15 +521,15 @@ static int drv_HD_start (char *section) static void drv_HD_write (char *string, int len) { - drv_HD_data (Controller, string, len, T_EXEC); + drv_HD_data (currController, string, len, T_EXEC); } static void drv_HD_defchar (int ascii, char *buffer) { // define chars on *both* controllers! - drv_HD_command (0x03, 0x40|8*ascii, T_EXEC); - drv_HD_data (0x03, buffer, 8, T_WRCG); + drv_HD_command (allControllers, 0x40|8*ascii, T_EXEC); + drv_HD_data (allControllers, buffer, 8, T_WRCG); } diff --git a/plugin_i2c_sensors.c b/plugin_i2c_sensors.c index 2c673f1..a8b6747 100644 --- a/plugin_i2c_sensors.c +++ b/plugin_i2c_sensors.c @@ -1,4 +1,4 @@ -/* $Id: plugin_i2c_sensors.c,v 1.5 2004/01/29 05:55:30 reinelt Exp $ +/* $Id: plugin_i2c_sensors.c,v 1.6 2004/01/30 07:12:35 reinelt Exp $ * * I2C sensors plugin * @@ -22,6 +22,13 @@ * * * $Log: plugin_i2c_sensors.c,v $ + * Revision 1.6 2004/01/30 07:12:35 reinelt + * HD44780 busy-flag support from Martin Hejl + * loadavg() uClibc replacement from Martin Heyl + * round() uClibc replacement from Martin Hejl + * warning in i2c_sensors fixed + * [ + * * Revision 1.5 2004/01/29 05:55:30 reinelt * check for /sys mounted * @@ -164,7 +171,7 @@ void my_i2c_sensors_path(void) fd1 = opendir(base); if (!fd1) { error("[i2c_sensors] Impossible to open %s! Is /sys mounted?", base); - return -1; + return; } while((dir = readdir(fd1))) { diff --git a/plugin_loadavg.c b/plugin_loadavg.c index e88baaa..3160122 100644 --- a/plugin_loadavg.c +++ b/plugin_loadavg.c @@ -1,4 +1,4 @@ -/* $Id: plugin_loadavg.c,v 1.2 2004/01/29 04:40:02 reinelt Exp $ +/* $Id: plugin_loadavg.c,v 1.3 2004/01/30 07:12:35 reinelt Exp $ * * plugin for load average * @@ -23,6 +23,13 @@ * * * $Log: plugin_loadavg.c,v $ + * Revision 1.3 2004/01/30 07:12:35 reinelt + * HD44780 busy-flag support from Martin Hejl + * loadavg() uClibc replacement from Martin Heyl + * round() uClibc replacement from Martin Hejl + * warning in i2c_sensors fixed + * [ + * * Revision 1.2 2004/01/29 04:40:02 reinelt * every .c file includes "config.h" now * @@ -49,10 +56,51 @@ #include #include #include +#include +#include +#include +#include #include "debug.h" #include "plugin.h" +#ifndef HAVE_GETLOADAVG + +int getloadavg (double loadavg[], int nelem) +{ + static int fd=-2; + char buf[65], *p; + ssize_t nread; + int i; + + if (fd==-2) fd = open ("/proc/loadavg", O_RDONLY); + if (fd < 0) return -1; + + lseek(fd,0,SEEK_SET); + nread = read (fd, buf, sizeof buf - 1); + //close (fd); + + if (nread < 0) return -1; + buf[nread - 1] = '\0'; + + if (nelem > 3) nelem = 3; + p = buf; + for (i = 0; i < nelem; ++i) { + char *endp; + loadavg[i] = strtod (p, &endp); + if (endp == NULL || endp == p) + /* This should not happen. The format of /proc/loadavg + must have changed. Don't return with what we have, + signal an error. */ + return -1; + p = endp; + } + + return i; +} + +#endif + static void my_loadavg (RESULT *result, RESULT *arg1) { diff --git a/processor.c b/processor.c index bf4884f..afb0757 100644 --- a/processor.c +++ b/processor.c @@ -1,4 +1,4 @@ -/* $Id: processor.c,v 1.54 2004/01/29 04:40:02 reinelt Exp $ +/* $Id: processor.c,v 1.55 2004/01/30 07:12:35 reinelt Exp $ * * main data processing * @@ -22,6 +22,13 @@ * * * $Log: processor.c,v $ + * Revision 1.55 2004/01/30 07:12:35 reinelt + * HD44780 busy-flag support from Martin Hejl + * loadavg() uClibc replacement from Martin Heyl + * round() uClibc replacement from Martin Hejl + * warning in i2c_sensors fixed + * [ + * * Revision 1.54 2004/01/29 04:40:02 reinelt * every .c file includes "config.h" now * @@ -292,6 +299,17 @@ static struct telmon telmon; extern int tick, tack; static int tick_text, tick_bar, tick_icon, tick_gpo; +#ifdef DONT_HAVE_ROUND +double round(double x) { + static int y=0; + if (x<0) { + y = (x-0.5); + } else { + y = (x-0.5); + } + return((double)y); +} +#endif static double query (int token) { -- cgit v1.2.3