aboutsummaryrefslogtreecommitdiffstats
path: root/drv_HD44780.c
diff options
context:
space:
mode:
Diffstat (limited to 'drv_HD44780.c')
-rw-r--r--drv_HD44780.c203
1 files changed, 150 insertions, 53 deletions
diff --git a/drv_HD44780.c b/drv_HD44780.c
index 7bcaade..c3d776e 100644
--- a/drv_HD44780.c
+++ b/drv_HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: drv_HD44780.c,v 1.7 2004/01/30 07:12:35 reinelt Exp $
+/* $Id: drv_HD44780.c,v 1.8 2004/02/01 08:05:12 reinelt Exp $
*
* new style driver for HD44780-based displays
*
@@ -29,6 +29,11 @@
*
*
* $Log: drv_HD44780.c,v $
+ * Revision 1.8 2004/02/01 08:05:12 reinelt
+ * Crystalfontz 633 extensions (CRC checking and stuff)
+ * Models table for HD44780
+ * Noritake VFD BVrightness patch from Bill Paxton
+ *
* Revision 1.7 2004/01/30 07:12:35 reinelt
* HD44780 busy-flag support from Martin Hejl
* loadavg() uClibc replacement from Martin Heyl
@@ -93,6 +98,8 @@
static char Name[]="HD44780";
+static int Model;
+static int Capabilities;
/* low level communication timings [nanoseconds]
* as these values differ from spec to spec,
@@ -131,7 +138,7 @@ 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;
+static int UseBusy = 0;
// Fixme
@@ -139,6 +146,23 @@ static int GPOS;
// static int GPO=0;
+typedef struct {
+ int type;
+ char *name;
+ int capabilities;
+} MODEL;
+
+#define CAP_BRIGHTNESS (1<<0)
+#define CAP_BUSY4BIT (1<<1)
+
+static MODEL Models[] = {
+ { 0x01, "generic", 0 },
+ { 0x02, "Noritake", CAP_BRIGHTNESS },
+ { 0x03, "Soekris", CAP_BUSY4BIT },
+ { 0xff, "Unknown", 0 }
+};
+
+
// ****************************************
// *** hardware dependant functions ***
// ****************************************
@@ -321,7 +345,7 @@ static void drv_HD_command (unsigned char controller, unsigned char cmd, int del
}
// wait for command completion
- if (!use_busy_flag) udelay(delay);
+ if (!UseBusy) udelay(delay);
}
@@ -333,7 +357,7 @@ 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 (UseBusy) wait_for_busy_flag(controller);
if (Bits==8) {
@@ -345,7 +369,7 @@ 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;
- if (!use_busy_flag) {
+ if (!UseBusy) {
// clear RW, set RS
drv_generic_parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS);
// Address set-up time
@@ -354,7 +378,7 @@ static void drv_HD_data (unsigned char controller, char *string, int len, int de
while (len--) {
- if (use_busy_flag) {
+ if (UseBusy) {
wait_for_busy_flag(controller);
// clear RW, set RS
drv_generic_parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS);
@@ -369,19 +393,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
- if (!use_busy_flag) udelay(delay);
+ if (!UseBusy) udelay(delay);
}
} else { // 4 bit mode
while (len--) {
- if (use_busy_flag) wait_for_busy_flag(controller);
+ if (UseBusy) wait_for_busy_flag(controller);
// send data with RS enabled
drv_HD_byte (controller, *(string++), SIGNAL_RS);
// wait for command completion
- if (!use_busy_flag) udelay(delay);
+ if (!UseBusy) udelay(delay);
}
}
}
@@ -416,11 +440,81 @@ static void drv_HD_goto (int row, int col)
}
+static void drv_HD_write (char *string, int len)
+{
+ 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 (allControllers, 0x40|8*ascii, T_EXEC);
+ drv_HD_data (allControllers, buffer, 8, T_WRCG);
+}
+
+
+static int drv_HD_brightness (int brightness)
+{
+ char cmd;
+
+ if (!(Capabilities & CAP_BRIGHTNESS)) return -1;
+
+ if (brightness<0) brightness=0;
+ if (brightness>3) brightness=3;
+
+ cmd='0'+brightness;
+
+ drv_HD_command (allControllers, 0x38, T_EXEC); // enable function
+ drv_HD_data (allControllers, &cmd, 1, T_WRCG); // set brightness
+
+ return brightness;
+}
+
+
+// Fixme
+#if 0
+static void drv_HD_setGPO (int bits)
+{
+ if (Lcd.gpos>0) {
+
+ // put data on DB1..DB8
+ drv_generic_parport_data (bits);
+
+ // 74HCT573 set-up time
+ ndelay(20);
+
+ // send data
+ // 74HCT573 enable pulse width = 24ns
+ drv_generic_parport_toggle (SIGNAL_GPO, 1, 230);
+ }
+}
+#endif
+
+
static int drv_HD_start (char *section)
{
+ char *model, *s;
int rows=-1, cols=-1, gpos=-1;
- char *s;
+ model=cfg_get(section, "Model", NULL);
+ if (model!=NULL && *model!='\0') {
+ int i;
+ for (i=0; Models[i].type!=0xff; i++) {
+ if (strcasecmp(Models[i].name, model)==0) break;
+ }
+ if (Models[i].type==0xff) {
+ error ("%s: %s.Model '%s' is unknown from %s", Name, section, model, cfg_source());
+ return -1;
+ }
+ Model=i;
+ Capabilities=Models[Model].capabilities;
+ info ("%s: using model '%s'", Name, Models[Model].name);
+ } else {
+ error ("%s: no '%s.Model' entry from %s", Name, section, cfg_source());
+ return -1;
+ }
+
s=cfg_get(section, "Size", NULL);
if (s==NULL || *s=='\0') {
error ("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
@@ -499,59 +593,42 @@ static int drv_HD_start (char *section)
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
+
+ // maybe use busy-flag from now on
+ // (we can't use the busy flag during the init sequence)
+ cfg_number(section, "UseBusy", 0, 0, 1, &UseBusy);
+
+ // make sure we don't use the busy flag with RW wired to GND
+ if (UseBusy && SIGNAL_RW) {
+ error("%s: Busyflag is to be used, but RW is wired to GND", Name);
+ UseBusy=0;
+ }
- // 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;
+ // make shure the display supports busy-flag checking in 4-Bit-Mode
+ // at the moment this is inly possible with martin Hejl's gpio driver,
+ // which allows to use 4 bits as input and 4 bits as output
+ if (UseBusy && Bits==4 && !(Capabilities&CAP_BUSY4BIT)) {
+ error("%s: Model '%s' does not support busy-flag checking in 4-bit-mode", Name, Models[Model].name);
+ UseBusy=0;
}
- info("HD44780: %susing Busyflag", use_busy_flag?"":"not ");
+ info("%s: %susing busy-flag checking", Name, UseBusy?"":"not ");
drv_HD_command (allControllers, 0x01, T_CLEAR); // clear *both* displays
drv_HD_command (allControllers, 0x03, T_CLEAR); // return home
+
+ // maybe set brightness
+ if (Capabilities & CAP_BRIGHTNESS) {
+ int brightness;
+ if (cfg_number(section, "Brightness", 0, 0, 3, &brightness)==0) {
+ drv_HD_brightness(brightness);
+ }
+ }
-
return 0;
}
-static void drv_HD_write (char *string, int len)
-{
- 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 (allControllers, 0x40|8*ascii, T_EXEC);
- drv_HD_data (allControllers, buffer, 8, T_WRCG);
-}
-
-
-// Fixme
-#if 0
-static void drv_HD_setGPO (int bits)
-{
- if (Lcd.gpos>0) {
-
- // put data on DB1..DB8
- drv_generic_parport_data (bits);
-
- // 74HCT573 set-up time
- ndelay(20);
-
- // send data
- // 74HCT573 enable pulse width = 24ns
- drv_generic_parport_toggle (SIGNAL_GPO, 1, 230);
- }
-}
-#endif
-
// ****************************************
// *** plugins ***
// ****************************************
@@ -575,7 +652,11 @@ static void drv_HD_setGPO (int bits)
// list models
int drv_HD_list (void)
{
- printf ("any");
+ int i;
+
+ for (i=0; Models[i].type!=0xff; i++) {
+ printf ("%s ", Models[i].name);
+ }
return 0;
}
@@ -665,3 +746,19 @@ DRIVER drv_HD44780 = {
quit: drv_HD_quit,
};
+
+#if 0
++
++// Change Noritake CU series VFD brightness level
++ char tmpbuffer[2];
++ int cu_vfd_brightness;
++ if (cfg_number("CU_VFD_Brightness", 0, 0, 3, &cu_vfd_brightness)<0) return -1;
++ if (cu_vfd_brightness) {
+ + snprintf (tmpbuffer, 2, "\%o", cu_vfd_brightness);
+ + HD_command (0x03, 0x38, T_EXEC); // enable function
+ + HD_write (0x03, tmpbuffer, 1, T_WRCG); // set brightness
+ + info ("HD44780: Noritake CU VFD detected. Brightness = %d (0-3)", cu_vfd_brightness);
+ + info (" Settings: 0=100\%, 1=75\%, 2=50\%, 3=25\%");
+ + }
+
+#endif