aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drv_HD44780.c62
-rw-r--r--lcd4linux.conf.sample19
-rw-r--r--udelay.c99
-rw-r--r--udelay.h17
4 files changed, 90 insertions, 107 deletions
diff --git a/drv_HD44780.c b/drv_HD44780.c
index 52b03dd..6d66903 100644
--- a/drv_HD44780.c
+++ b/drv_HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: drv_HD44780.c,v 1.56 2005/12/12 05:52:03 reinelt Exp $
+/* $Id: drv_HD44780.c,v 1.57 2005/12/12 09:08:08 reinelt Exp $
*
* new style driver for HD44780-based displays
*
@@ -32,6 +32,9 @@
*
*
* $Log: drv_HD44780.c,v $
+ * Revision 1.57 2005/12/12 09:08:08 reinelt
+ * finally removed old udelay code path; read timing values from config
+ *
* Revision 1.56 2005/12/12 05:52:03 reinelt
* type of delays is 'unsigned long'
*
@@ -298,28 +301,9 @@ static int Model;
static int Capabilities;
-/* low level communication timings [nanoseconds]
- * as these values differ from spec to spec,
- * we use the worst-case values.
- */
-
-#define T_CYCLE 1000 /* Enable cycle time */
-#define T_PW 450 /* Enable pulse width */
-#define T_AS 140 /* Address setup time */
-#define T_H 40 /* Data hold time */
-#define T_AH 20 /* Address hold time */
-
-
-/* HD44780 execution timings [microseconds]
- * as these values differ from spec to spec,
- * we use the worst-case values.
- */
-
-#define T_INIT1 4100 /* first init sequence: 4.1 msec */
-#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 2250 /* Clear Display */
+/* Timings */
+static int T_CY, T_PW, T_AS, T_AH;
+static int T_INIT1, T_INIT2, T_EXEC, T_WRCG, T_CLEAR, T_HOME, T_ONOFF;
static int Bits = 0;
@@ -561,8 +545,8 @@ static void drv_HD_PP_byte(const unsigned char controller, const unsigned char d
/* send high nibble of the data */
drv_HD_PP_nibble(controller, ((data >> 4) & 0x0f) | RS);
- /* Make sure we honour T_CYCLE */
- ndelay(T_CYCLE - T_AS - T_PW);
+ /* Make sure we honour T_CY */
+ ndelay(T_CY - T_AS - T_PW);
/* send low nibble of the data */
drv_HD_PP_nibble(controller, (data & 0x0f) | RS);
@@ -769,6 +753,30 @@ static int drv_HD_PP_load(const char *section)
Capabilities &= ~CAP_GPO;
}
+ /* Timings */
+
+ /* low level communication timings [nanoseconds]
+ * as these values differ from spec to spec,
+ * we use the worst-case default values, but allow
+ * modification from the config file.
+ */
+ T_CY = timing(Name, section, "CY", 1000, "ns"); /* Enable cycle time */
+ T_PW = timing(Name, section, "PW", 450, "ns"); /* Enable pulse width */
+ T_AS = timing(Name, section, "AS", 140, "ns"); /* Address setup time */
+ T_AH = timing(Name, section, "AH", 20, "ns"); /* Address hold time */
+
+ /* HD44780 execution timings [microseconds]
+ * as these values differ from spec to spec,
+ * we use the worst-case default values, but allow
+ * modification from the config file.
+ */
+ T_INIT1 = timing(Name, section, "INIT1", 4100, "us"); /* first init sequence: 4.1 msec */
+ T_INIT2 = timing(Name, section, "INIT2", 100, "us"); /* second init sequence: 100 usec */
+ T_EXEC = timing(Name, section, "EXEC", 80, "us"); /* normal execution time */
+ T_WRCG = timing(Name, section, "WRCG", 120, "us"); /* CG RAM Write */
+ T_CLEAR = timing(Name, section, "CLEAR", 2250, "us"); /* Clear Display */
+ T_HOME = timing(Name, section, "HOME", 2250, "us"); /* Return Cursor Home */
+ T_ONOFF = timing(Name, section, "ONOFF", 2250, "us"); /* Display On/Off Control */
/* clear all signals */
if (Bits == 8) {
@@ -1313,7 +1321,7 @@ static int drv_HD_start(const char *section, const int quiet)
}
drv_HD_command(allControllers, 0x08, T_EXEC); /* Controller 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, 0x0c, T_ONOFF); /* Display on, cursor off, blink off, wait 1.64 ms */
drv_HD_command(allControllers, 0x06, T_EXEC); /* curser moves to right, no shift */
if ((Capabilities & CAP_HD66712) && DROWS > 2) {
@@ -1323,7 +1331,7 @@ static int drv_HD_start(const char *section, const int quiet)
}
drv_HD_clear(); /* clear *all* displays */
- drv_HD_command(allControllers, 0x03, T_CLEAR); /* return home */
+ drv_HD_command(allControllers, 0x03, T_HOME); /* return home */
/* maybe set backlight */
if (Capabilities & CAP_BACKLIGHT) {
diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample
index da346fb..d75acbf 100644
--- a/lcd4linux.conf.sample
+++ b/lcd4linux.conf.sample
@@ -119,6 +119,21 @@ Display HD44780-winamp {
ENABLE2 'GND'
GPO 'GND'
}
+ Timing {
+ # low-level communication [ns]
+ CY 1000 # Enable cycle time
+ PW 450 # Enable pulse width
+ AS 140 # Address setup time
+ AH 20 # Address hold time
+ # HD44780 execution timings [us]
+ INIT1 4100 # first init sequence: 4.1 msec
+ INIT2 100 # second init sequence: 100 usec
+ EXEC 80 # normal execution time
+ WRCG 120 # CG RAM Write
+ CLEAR 2250 # Clear Display
+ HOME 2250 # Return Cursor Home
+ ONOFF 2250 # Display On/Off Control
+ }
}
# Dual-HD44780 display from Pollin
@@ -828,7 +843,7 @@ Layout testMySQL {
#Display 'MI240'
#Display 'CW12232'
#Display 'HD44780-generic'
-#Display 'HD44780-WinAmp'
+Display 'HD44780-WinAmp'
#Display 'WDC2704M'
#Display 'SC1602D'
#Display 'LCM-162'
@@ -839,7 +854,7 @@ Layout testMySQL {
#Display 'M50530-24x8'
#Display 'LCDTerm'
#Display 'SimpleLCD'
-Display 'BA63'
+#Display 'BA63'
#Display 'CT20x4'
#Display 'T6963-240x64'
#Display 'XWindow'
diff --git a/udelay.c b/udelay.c
index e26bc08..82011db 100644
--- a/udelay.c
+++ b/udelay.c
@@ -1,4 +1,4 @@
-/* $Id: udelay.c,v 1.20 2005/05/08 04:32:45 reinelt Exp $
+/* $Id: udelay.c,v 1.21 2005/12/12 09:08:08 reinelt Exp $
*
* short delays
*
@@ -23,6 +23,9 @@
*
*
* $Log: udelay.c,v $
+ * Revision 1.21 2005/12/12 09:08:08 reinelt
+ * finally removed old udelay code path; read timing values from config
+ *
* Revision 1.20 2005/05/08 04:32:45 reinelt
* CodingStyle added and applied
*
@@ -112,21 +115,19 @@
*
* exported fuctions:
*
- * void udelay (unsigned long usec)
- * delays program execution for usec microseconds
- * uses global variable 'loops_per_usec', which has to be set before.
- * This function does busy-waiting! so use only for delays smaller
- * than 10 msec
- *
- * void udelay_calibrate (void) (if USE_OLD_UDELAY is defined)
- * does a binary approximation for 'loops_per_usec'
- * should be called several times on an otherwise idle machine
- * the maximum value should be used
- *
* void udelay_init (void)
* selects delay method (gettimeofday() ord rdtsc() according
* to processor features
*
+ * unsigned long timing (const char *driver, const char *section, const char *name, const int defval, const char *unit);
+ * returns a timing value from config or the default value
+ *
+ * void udelay (unsigned long usec)
+ * delays program execution for usec microseconds
+ * uses global variable 'loops_per_usec', which has to be set before.
+ * This function does busy-waiting! so use only for delays smaller
+ * than 10 msec
+ *
*/
#include "config.h"
@@ -134,12 +135,6 @@
#include <stdio.h>
-#ifdef USE_OLD_UDELAY
-
-#include <time.h>
-
-#else
-
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
@@ -151,58 +146,16 @@
#include <asm/msr.h>
#endif
-#endif
-
#include "debug.h"
+#include "cfg.h"
+#include "qprintf.h"
#include "udelay.h"
-#ifdef USE_OLD_UDELAY
-
-unsigned long loops_per_usec;
-
-void ndelay(const unsigned long nsec)
-{
- unsigned long loop = (nsec * loops_per_usec + 999) / 1000;
-
- __asm__(".align 16\n" "1:\tdecl %0\n" "\tjne 1b": /* no result */
- :"a"(loop));
-}
-
-/* adopted from /usr/src/linux/init/main.c */
-
-void udelay_calibrate(void)
-{
- clock_t tick;
- unsigned long bit;
-
- loops_per_usec = 1;
- while (loops_per_usec <<= 1) {
- tick = clock();
- while (clock() == tick);
- tick = clock();
- ndelay(1000000000 / CLOCKS_PER_SEC);
- if (clock() > tick)
- break;
- }
-
- loops_per_usec >>= 1;
- bit = loops_per_usec;
- while (bit >>= 1) {
- loops_per_usec |= bit;
- tick = clock();
- while (clock() == tick);
- tick = clock();
- ndelay(1000000000 / CLOCKS_PER_SEC);
- if (clock() > tick)
- loops_per_usec &= ~bit;
- }
-}
-
-#else
static unsigned int ticks_per_usec = 0;
+
static void getCPUinfo(int *hasTSC, double *MHz)
{
int fd;
@@ -269,7 +222,6 @@ void udelay_init(void)
error("udelay: Even if your CPU supports TSC, it will not be used!");
error("udelay: You *really* should install msr.h and recompile LCD4linux!");
#endif
-
{
ticks_per_usec = 0;
info("udelay: using gettimeofday() delay loop");
@@ -277,6 +229,23 @@ void udelay_init(void)
}
+unsigned long timing(const char *driver, const char *section, const char *name, const int defval, const char *unit)
+{
+ char sec[256];
+ int ret, val;
+
+ qprintf(sec, sizeof(sec), "%s.Timing", section);
+
+ ret = cfg_number(sec, name, defval, 0, -1, &val);
+ if (val != defval) {
+ info("%s: timing: %6s = %5d %s (default %d %s)", driver, name, val, unit, defval, unit);
+ } else {
+ info("%s: timing: %6s = %5d %s (default)", driver, name, defval, unit);
+ }
+ return val;
+}
+
+
void ndelay(const unsigned long nsec)
{
@@ -314,5 +283,3 @@ void ndelay(const unsigned long nsec)
} while (now.tv_sec == end.tv_sec ? now.tv_usec < end.tv_usec : now.tv_sec < end.tv_sec);
}
}
-
-#endif
diff --git a/udelay.h b/udelay.h
index 3271c7f..aa26950 100644
--- a/udelay.h
+++ b/udelay.h
@@ -1,4 +1,4 @@
-/* $Id: udelay.h,v 1.10 2005/05/08 04:32:45 reinelt Exp $
+/* $Id: udelay.h,v 1.11 2005/12/12 09:08:08 reinelt Exp $
*
* short delays
*
@@ -23,6 +23,9 @@
*
*
* $Log: udelay.h,v $
+ * Revision 1.11 2005/12/12 09:08:08 reinelt
+ * finally removed old udelay code path; read timing values from config
+ *
* Revision 1.10 2005/05/08 04:32:45 reinelt
* CodingStyle added and applied
*
@@ -79,18 +82,8 @@ static inline void rep_nop(void)
__asm__ __volatile__("rep; nop");
}
-
-#ifdef USE_OLD_UDELAY
-
-extern unsigned long loops_per_usec;
-void udelay_calibrate(void);
-
-#else
-
void udelay_init(void);
-
-#endif
-
+unsigned long timing(const char *driver, const char *section, const char *name, const int defval, const char *unit);
void ndelay(const unsigned long nsec);
#define udelay(usec) ndelay(usec*1000)