]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2003-08-19 05:23:55 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Tue, 19 Aug 2003 05:23:55 +0000 (05:23 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Tue, 19 Aug 2003 05:23:55 +0000 (05:23 +0000)
HD44780 dual-controller patch from Jesse Brook Kovach

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

HD44780.c
parport.c

index babc11a0bde6ade0ccc9ada605022082d457bcce..5417877497d97ae1a5b087b17ae2478f8ca64d81 100644 (file)
--- a/HD44780.c
+++ b/HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: HD44780.c,v 1.33 2003/08/19 04:28:41 reinelt Exp $
+/* $Id: HD44780.c,v 1.34 2003/08/19 05:23:55 reinelt Exp $
  *
  * driver for display modules based on the HD44780 chip
  *
@@ -7,6 +7,9 @@
  * Modification for 4-Bit mode
  * 2003 Martin Hejl (martin@hejl.de)
  *
+ * Modification for 2nd controller support
+ * 2003 Jesse Brook Kovach <jkovach@wam.umd.edu>
+ *
  *
  * 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
@@ -24,6 +27,9 @@
  *
  *
  * $Log: HD44780.c,v $
+ * Revision 1.34  2003/08/19 05:23:55  reinelt
+ * HD44780 dual-controller patch from Jesse Brook Kovach
+ *
  * Revision 1.33  2003/08/19 04:28:41  reinelt
  * more Icon stuff, minor glitches fixed
  *
 static LCD Lcd;
 static int Bits=0;
 static int GPO=0;
+static int Controllers = 0;
+static int Controller  = 0;
 
 static char *FrameBuffer1=NULL;
 static char *FrameBuffer2=NULL;
@@ -210,12 +218,21 @@ static char *FrameBuffer2=NULL;
 static unsigned char SIGNAL_RW;
 static unsigned char SIGNAL_RS;
 static unsigned char SIGNAL_ENABLE;
+static unsigned char SIGNAL_ENABLE2;
 static unsigned char SIGNAL_GPO;
 
-
-static void HD_nibble(unsigned char nibble)
+static void HD_nibble(unsigned char controller, unsigned char nibble)
 {
-
+  unsigned char enable;
+
+  // enable signal: 'controller' is a bitmask
+  // bit 0 .. send to controller #0
+  // bit 1 .. send to controller #1
+  // so we can send a byte to both controllers at the same time!
+  enable=0;
+  if (controller&0x01) enable|=SIGNAL_ENABLE;
+  if (controller&0x02) enable|=SIGNAL_ENABLE2;
+  
   // clear ENABLE
   // put data on DB1..DB4
   // nibble already contains RS bit!
@@ -225,7 +242,7 @@ static void HD_nibble(unsigned char nibble)
   ndelay(T_AS);
   
   // rise ENABLE
-  parport_data(nibble | SIGNAL_ENABLE);
+  parport_data(nibble | enable);
   
   // Enable pulse width
   ndelay(T_PW);
@@ -235,24 +252,33 @@ static void HD_nibble(unsigned char nibble)
 }
 
 
-static void HD_byte (unsigned char data, unsigned char RS)
+static void HD_byte (unsigned char controller, unsigned char data, unsigned char RS)
 {
   // send high nibble of the data
-  HD_nibble (((data>>4)&0x0f)|RS);
+  HD_nibble (controller, ((data>>4)&0x0f)|RS);
 
   // Make sure we honour T_CYCLE
   ndelay(T_CYCLE-T_AS-T_PW);
 
   // send low nibble of the data
-  HD_nibble((data&0x0f)|RS);
+  HD_nibble(controller, (data&0x0f)|RS);
 }
 
 
-static void HD_command (unsigned char cmd, int delay)
+static void HD_command (unsigned char controller, unsigned char cmd, int delay)
 {
-    
+  unsigned char enable;
+   
   if (Bits==8) {
     
+    // enable signal: 'controller' is a bitmask
+    // bit 0 .. send to controller #0
+    // bit 1 .. send to controller #1
+    // so we can send a byte to both controllers at the same time!
+    enable=0;
+    if (controller&0x01) enable|=SIGNAL_ENABLE;
+    if (controller&0x02) enable|=SIGNAL_ENABLE2;
+    
     // put data on DB1..DB8
     parport_data (cmd);
   
@@ -263,11 +289,11 @@ static void HD_command (unsigned char cmd, int delay)
     ndelay(T_AS);
 
     // send command
-    parport_toggle (SIGNAL_ENABLE, 1, T_PW);
-
+    parport_toggle (enable, 1, T_PW);
+    
   } else {
 
-    HD_byte (cmd, 0);
+    HD_byte (controller, cmd, 0);
 
   }
   
@@ -277,11 +303,20 @@ static void HD_command (unsigned char cmd, int delay)
 }
 
 
-static void HD_write (char *string, int len, int delay)
+static void HD_write (unsigned char controller, char *string, int len, int delay)
 {
+  unsigned char enable;
 
   if (Bits==8) {
 
+    // enable signal: 'controller' is a bitmask
+    // bit 0 .. send to controller #0
+    // bit 1 .. send to controller #1
+    // so we can send a byte to both controllers at the same time!
+    enable=0;
+    if (controller&0x01) enable|=SIGNAL_ENABLE;
+    if (controller&0x02) enable|=SIGNAL_ENABLE2;
+    
     // clear RW, set RS
     parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS);
 
@@ -294,27 +329,26 @@ static void HD_write (char *string, int len, int delay)
       parport_data (*(string++));
       
       // send command
-      parport_toggle (SIGNAL_ENABLE, 1, T_PW);
+      parport_toggle (enable, 1, T_PW);
       
       // wait for command completion
       udelay(delay);
     }
-
+    
   } else { // 4 bit mode
-
+    
     while (len--) {
 
       // send data with RS enabled
-      HD_byte (*(string++), SIGNAL_RS);
-
+      HD_byte (controller, *(string++), SIGNAL_RS);
+      
       // wait for command completion
       udelay(delay);
     }
-
   }
-
 }
 
+
 static void HD_setGPO (int bits)
 {
   if (Lcd.gpos>0) {
@@ -334,8 +368,9 @@ static void HD_setGPO (int bits)
 
 static void HD_define_char (int ascii, char *buffer)
 {
-  HD_command (0x40|8*ascii, 40);
-  HD_write (buffer, 8, 120); // 120 usec delay for CG RAM write
+  // define chars on *both* controllers!
+  HD_command (0x03, 0x40|8*ascii, 40);
+  HD_write (0x03, buffer, 8, 120); // 120 usec delay for CG RAM write
 }
 
 
@@ -348,10 +383,10 @@ int HD_clear (int full)
   
   if (full) {
     memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
-    HD_command (0x01, 1640); // clear display
-    HD_setGPO (GPO);         // All GPO's off
+    HD_command (0x03, 0x01, 1640); // clear *both* displays
+    HD_setGPO (GPO);               // all GPO's off
   }
-
+  
   return 0;
 }
 
@@ -383,6 +418,17 @@ int HD_init (LCD *Self)
     }    
   }
   
+  s=cfg_get("Controllers", "1");
+  Controllers=strtol(s, &e, 0);
+  if (*e!='\0' || Controllers<1 || Controllers>2) {
+    error ("HD44780: bad Controllers '%s' in %s, should be '1' or '2'", s, cfg_file());
+    return -1;
+  }    
+  info ("wiring: using display with %d controllers", Controllers);
+  
+  // current controller
+  Controller=1;
+
   Self->rows=rows;
   Self->cols=cols;
   Self->gpos=gpos;
@@ -405,15 +451,17 @@ int HD_init (LCD *Self)
   info ("wiring: using %d bit mode", Bits);
 
   if (Bits==8) {
-    if ((SIGNAL_RS     = parport_wire_ctrl ("RS",     "AUTOFD"))==0xff) return -1;
-    if ((SIGNAL_RW     = parport_wire_ctrl ("RW",     "GND")   )==0xff) return -1;
-    if ((SIGNAL_ENABLE = parport_wire_ctrl ("ENABLE", "STROBE"))==0xff) return -1;
-    if ((SIGNAL_GPO    = parport_wire_ctrl ("GPO",    "INIT")  )==0xff) return -1;
+    if ((SIGNAL_RS      = parport_wire_ctrl ("RS",      "AUTOFD"))==0xff) return -1;
+    if ((SIGNAL_RW      = parport_wire_ctrl ("RW",      "GND")   )==0xff) return -1;
+    if ((SIGNAL_ENABLE  = parport_wire_ctrl ("ENABLE",  "STROBE"))==0xff) return -1;
+    if ((SIGNAL_ENABLE2 = parport_wire_ctrl ("ENABLE2", "SELECT"))==0xff) return -1;
+    if ((SIGNAL_GPO     = parport_wire_ctrl ("GPO",     "INIT")  )==0xff) return -1;
   } else {
-    if ((SIGNAL_RS     = parport_wire_data ("RS",     "DB4"))==0xff) return -1;
-    if ((SIGNAL_RW     = parport_wire_data ("RW",     "DB5"))==0xff) return -1;
-    if ((SIGNAL_ENABLE = parport_wire_data ("ENABLE", "DB6"))==0xff) return -1;
-    if ((SIGNAL_GPO    = parport_wire_data ("GPO",    "DB7"))==0xff) return -1;
+    if ((SIGNAL_RS      = parport_wire_data ("RS",      "DB4"))==0xff) return -1;
+    if ((SIGNAL_RW      = parport_wire_data ("RW",      "DB5"))==0xff) return -1;
+    if ((SIGNAL_ENABLE  = parport_wire_data ("ENABLE",  "DB6"))==0xff) return -1;
+    if ((SIGNAL_ENABLE2 = parport_wire_data ("ENABLE2", "DB7"))==0xff) return -1;
+    if ((SIGNAL_GPO     = parport_wire_data ("GPO",     "GND"))==0xff) return -1;
   }
   
   if (parport_open() != 0) {
@@ -431,24 +479,23 @@ int HD_init (LCD *Self)
   // set direction: write
   parport_direction (0);
 
-  // initialize display
+  // initialize *both* displays
   if (Bits==8) {
-    HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
-    HD_command (0x30, 100);  // 8 Bit mode, wait 100 us
-    HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms
-    HD_command (0x38, 40);   // 8 Bit mode, 1/16 duty cycle, 5x8 font
+    HD_command (0x03, 0x30, 4100); // 8 Bit mode, wait 4.1 ms
+    HD_command (0x03, 0x30, 100);  // 8 Bit mode, wait 100 us
+    HD_command (0x03, 0x30, 4100); // 8 Bit mode, wait 4.1 ms
+    HD_command (0x03, 0x38, 40);   // 8 Bit mode, 1/16 duty cycle, 5x8 font
   } else {
-    HD_nibble(0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms
-    HD_nibble(0x03); udelay(100);  // 4 Bit mode, wait 100 us
-    HD_nibble(0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms
-    HD_nibble(0x02); udelay(100);  // 4 Bit mode, wait 100 us
-    HD_command (0x28, 40);        // 4 Bit mode, 1/16 duty cycle, 5x8 font
+    HD_nibble(0x03, 0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms
+    HD_nibble(0x03, 0x03); udelay(100);  // 4 Bit mode, wait 100 us
+    HD_nibble(0x03, 0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms
+    HD_nibble(0x03, 0x02); udelay(100);  // 4 Bit mode, wait 100 us
+    HD_command (0x03, 0x28, 40);        // 4 Bit mode, 1/16 duty cycle, 5x8 font
   }
   
-  HD_command (0x08, 40);   // Display off, cursor off, blink off
-  HD_command (0x0c, 1640); // Display on, cursor off, blink off, wait 1.64 ms
-  HD_command (0x06, 40);   // curser moves to right, no shift
-
+  HD_command (0x03, 0x08, 40);   // Display off, cursor off, blink off
+  HD_command (0x03, 0x0c, 1640); // Display on, cursor off, blink off, wait 1.64 ms
+  HD_command (0x03, 0x06, 40);   // curser moves to right, no shift
 
   bar_init(rows, cols, XRES, YRES, CHARS);
   bar_add_segment(  0,  0,255, 32); // ASCII  32 = blank
@@ -464,8 +511,15 @@ void HD_goto (int row, int col)
 {
   int pos;
 
+  if (Controllers>1 && row>=2) {
+    row -= 2;
+    Controller = 2;
+  } else {
+    Controller = 1;
+  }
+   
   pos=(row%2)*64+(row/2)*20+col;
-  HD_command (0x80|pos, 40);
+  HD_command (Controller, (0x80|pos), 40);
 }
 
 
@@ -528,7 +582,7 @@ int HD_flush (void)
          equal=0;
        }
       }
-      HD_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1, 40); // 40 usec delay for write
+      HD_write (Controller, FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1, 50); // 50 usec delay for write
     }
   }
 
index a5ba3c2e7ed3131a8f55463c9a9fca1d4ade4a36..db633b7fe0ad89aaac7b54dc8a2d282bf7880846 100644 (file)
--- a/parport.c
+++ b/parport.c
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.4 2003/08/16 07:31:35 reinelt Exp $
+/* $Id: parport.c,v 1.5 2003/08/19 05:23:55 reinelt Exp $
  *
  * generic parallel port handling
  *
@@ -20,6 +20,9 @@
  *
  *
  * $Log: parport.c,v $
+ * Revision 1.5  2003/08/19 05:23:55  reinelt
+ * HD44780 dual-controller patch from Jesse Brook Kovach
+ *
  * Revision 1.4  2003/08/16 07:31:35  reinelt
  * double buffering in all drivers
  *
@@ -340,7 +343,6 @@ void parport_control (unsigned char mask, unsigned char value)
 
   // Strobe, Select and AutoFeed are inverted!
   value = mask & (value ^ (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD));
-  // value ^= PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD;
 
 #ifdef WITH_PPDEV
   if (PPdev) {
@@ -358,45 +360,50 @@ void parport_control (unsigned char mask, unsigned char value)
 }
 
 
-void parport_toggle (unsigned char bit, int level, int delay)
+void parport_toggle (unsigned char bits, int level, int delay)
 {
+  unsigned char value1, value2;
 
   // any signal affected?
   // Note: this may happen in case a signal is hardwired to GND
-  if (bit==0) return;
+  if (bits==0) return;
 
+  // prepare value
+  value1=level?bits:0;
+  value2=level?0:bits;
+  
   // Strobe, Select and AutoFeed are inverted!
-  if (bit & (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD)) {
-    level=!level;
-  }
+  value1 = bits & (value1 ^ (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD));
+  value2 = bits & (value1 ^ (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD));
+  
  
 #ifdef WITH_PPDEV
   if (PPdev) {
     struct ppdev_frob_struct frob;
-    frob.mask=bit;
+    frob.mask=bits;
     
     // rise
-    frob.val=level?bit:0;
+    frob.val=value1;
     ioctl (PPfd, PPFCONTROL, &frob);
     
     // pulse width
     ndelay(delay);      
     
     // lower
-    frob.val=level?0:bit;
+    frob.val=value2;
     ioctl (PPfd, PPFCONTROL, &frob);
   } else
 #endif
     {
       // rise
-      ctr = (ctr & ~bit) ^ (level?bit:0);
+      ctr = (ctr & ~bits) ^ value1;
       outb (ctr, Port+2);
 
       // pulse width
       ndelay(delay);      
       
       // lower
-      ctr = (ctr & ~bit) ^ (level?0:bit);
+      ctr = (ctr & ~bits) ^ value2;
       outb (ctr, Port+2);
     }
 }