]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2004-01-30 07:12:35 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 30 Jan 2004 07:12:35 +0000 (07:12 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 30 Jan 2004 07:12:35 +0000 (07:12 +0000)
HD44780 busy-flag support from Martin Hejl
loadavg() uClibc replacement from Martin Heyl
round() uClibc replacement from Martin Hejl
warning in i2c_sensors fixed
[

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@347 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

drv_HD44780.c
plugin_i2c_sensors.c
plugin_loadavg.c
processor.c

index 7ca7d5bb9bddc00eb61a69e8861e0c6977b99d2e..7bcaadeb8ce70510c366ab1271f197fdaaa95b18 100644 (file)
@@ -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
  *
  *
  *
  * $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 <unistd.h>
 #include <termios.h>
 #include <fcntl.h>
+#include <sys/time.h>
 
 #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);
 }
 
 
index 2c673f1576b902008ab00edc5a2760b8f8d9b341..a8b6747de020c0b045f228fc2f362842b4526d71 100644 (file)
@@ -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
  *
  *
  *
  * $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)))   {
index e88baaa62c66346cc1eda4e95421318a7d96f6af..31601220e7cac85728501cbbbb4a16f7a9d7bc02 100644 (file)
@@ -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
  *
  *
  *
  * $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
  *
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #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)
 {
index bf4884f4d8937814e341c01fbba1592559ef39dd..afb0757e190c73b7383aa8ab4ffe7226025cf0ac 100644 (file)
@@ -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
  *
  *
  *
  * $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)
 {