diff options
| author | reinelt <> | 2005-12-12 09:08:08 +0000 | 
|---|---|---|
| committer | reinelt <> | 2005-12-12 09:08:08 +0000 | 
| commit | d9ef234db55e6a8b21ab70b0c5c94e0d41d70c50 (patch) | |
| tree | 67c56c5ba08b04b1119c2975c92aa767f17d508b | |
| parent | ed398c799540d0bbe9f2eb0a92013e94f89bbf14 (diff) | |
| download | lcd4linux-d9ef234db55e6a8b21ab70b0c5c94e0d41d70c50.tar.gz | |
[lcd4linux @ 2005-12-12 09:08:08 by reinelt]
finally removed old udelay code path; read timing values from config
| -rw-r--r-- | drv_HD44780.c | 62 | ||||
| -rw-r--r-- | lcd4linux.conf.sample | 19 | ||||
| -rw-r--r-- | udelay.c | 99 | ||||
| -rw-r--r-- | udelay.h | 17 | 
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' @@ -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 @@ -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) | 
