diff options
Diffstat (limited to '')
-rw-r--r-- | HD44780.c | 68 | ||||
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | Makefile.in | 8 | ||||
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | lcd4linux.c | 29 | ||||
-rw-r--r-- | udelay.c | 99 | ||||
-rw-r--r-- | udelay.h | 41 |
7 files changed, 197 insertions, 58 deletions
@@ -1,4 +1,4 @@ -/* $Id: HD44780.c,v 1.3 2000/04/15 11:13:54 reinelt Exp $ +/* $Id: HD44780.c,v 1.4 2000/04/15 16:56:52 reinelt Exp $ * * driver for display modules based on the HD44780 chip * @@ -20,6 +20,14 @@ * * * $Log: HD44780.c,v $ + * Revision 1.4 2000/04/15 16:56:52 reinelt + * + * moved delay loops to udelay.c + * renamed -d (debugging) switch to -v (verbose) + * new switch -d to calibrate delay loop + * 'Delay' entry for HD44780 back again + * delay loops will not calibrate automatically, because this will fail with hich CPU load + * * Revision 1.3 2000/04/15 11:13:54 reinelt * * added '-d' (debugging) switch @@ -60,6 +68,7 @@ #include "debug.h" #include "cfg.h" #include "display.h" +#include "udelay.h" #define XRES 5 #define YRES 8 @@ -83,7 +92,6 @@ typedef struct { static LCD Lcd; static unsigned short Port=0; -static unsigned long loops_per_usec; static char Txt[4][40]; static BAR Bar[4][40]; @@ -92,49 +100,13 @@ static int nSegment=2; static SEGMENT Segment[128] = {{ len1:0, len2:0, type:255, used:0, ascii:32 }, { len1:255, len2:255, type:255, used:0, ascii:255 }}; -static void HD_delay (unsigned long usec) -{ - unsigned long i=usec*loops_per_usec; - while (i--); -} - -static void HD_calibrate_delay (void) -{ - clock_t tick; - unsigned long bit; - - loops_per_usec=1; - while (loops_per_usec<<=1) { - tick=clock(); - while (clock()==tick); - tick=clock(); - HD_delay(1000000/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(); - HD_delay(1000000/CLOCKS_PER_SEC); - if (clock()>tick) - loops_per_usec&=~bit; - } - - debug ("calibrating delay: %ld loops/usec\n", loops_per_usec); -} - static void HD_command (unsigned char cmd, int delay) { outb (cmd, Port); // put data on DB1..DB8 outb (0x02, Port+2); // set Enable = bit 0 invertet - HD_delay(1); + udelay (1); outb (0x03, Port+2); // clear Enable - HD_delay(delay); + udelay (delay); } static void HD_write (char *string, int len, int delay) @@ -142,9 +114,9 @@ static void HD_write (char *string, int len, int delay) while (len--) { outb (*string++, Port); // put data on DB1..DB8 outb (0x00, Port+2); // set Enable = bit 0 invertet - HD_delay(1); + udelay (1); outb (0x01, Port+2); // clear Enable - HD_delay(delay); + udelay (delay); } } @@ -368,6 +340,16 @@ int HD_init (LCD *Self) return -1; } + s=cfg_get ("Delay"); + if (s==NULL || *s=='\0') { + fprintf (stderr, "HD44780: no 'Delay' entry in %s\n", cfg_file()); + return -1; + } + if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') { + fprintf (stderr, "HD44780: bad delay '%s' in %s\n", s, cfg_file()); + return -1; + } + s=cfg_get("Size"); if (s==NULL || *s=='\0') { fprintf (stderr, "HD44780: no 'Size' entry in %s\n", cfg_file()); @@ -382,8 +364,6 @@ int HD_init (LCD *Self) Self->cols=cols; Lcd=*Self; - HD_calibrate_delay(); - if (HD_open()!=0) return -1; diff --git a/Makefile.am b/Makefile.am index e9d30ea..e042eaf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,7 @@ processor.c processor.h \ system.c system.h \ isdn.c isdn.h \ filter.c filter.h \ +udelay.c udelay.h \ display.c display.h \ pixmap.c pixmap.h \ fontmap.c fontmap.h \ diff --git a/Makefile.in b/Makefile.in index bc87e06..d6266d9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -73,7 +73,7 @@ AM_CFLAGS = $(X_CFLAGS) -Wall lcd4linux_LDFLAGS = $(X_LIBS) @WITH_X_TRUE@lcd4linux_LDADD = -lX11 -lcd4linux_SOURCES = lcd4linux.c debug.h cfg.c cfg.h lock.c lock.h parser.c parser.h processor.c processor.h system.c system.h isdn.c isdn.h filter.c filter.h display.c display.h pixmap.c pixmap.h fontmap.c fontmap.h Skeleton.c MatrixOrbital.c HD44780.c Raster.c XWindow.c +lcd4linux_SOURCES = lcd4linux.c debug.h cfg.c cfg.h lock.c lock.h parser.c parser.h processor.c processor.h system.c system.h isdn.c isdn.h filter.c filter.h udelay.c udelay.h display.c display.h pixmap.c pixmap.h fontmap.c fontmap.h Skeleton.c MatrixOrbital.c HD44780.c Raster.c XWindow.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -90,8 +90,8 @@ X_LIBS = @X_LIBS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ lcd4linux_OBJECTS = lcd4linux.o cfg.o lock.o parser.o processor.o \ -system.o isdn.o filter.o display.o pixmap.o fontmap.o Skeleton.o \ -MatrixOrbital.o HD44780.o Raster.o XWindow.o +system.o isdn.o filter.o udelay.o display.o pixmap.o fontmap.o \ +Skeleton.o MatrixOrbital.o HD44780.o Raster.o XWindow.o @WITH_X_TRUE@lcd4linux_DEPENDENCIES = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -109,7 +109,7 @@ DEP_FILES = .deps/HD44780.P .deps/MatrixOrbital.P .deps/Raster.P \ .deps/Skeleton.P .deps/XWindow.P .deps/cfg.P .deps/display.P \ .deps/filter.P .deps/fontmap.P .deps/isdn.P .deps/lcd4linux.P \ .deps/lock.P .deps/parser.P .deps/pixmap.P .deps/processor.P \ -.deps/system.P +.deps/system.P .deps/udelay.P SOURCES = $(lcd4linux_SOURCES) OBJECTS = $(lcd4linux_OBJECTS) @@ -1,5 +1,5 @@ # -# $Id: README,v 1.5 2000/04/15 11:13:54 reinelt Exp $ +# $Id: README,v 1.6 2000/04/15 16:56:52 reinelt Exp $ # This is the README file for lcd4linux @@ -22,9 +22,12 @@ print version number and a small help text, then exit lcd4linux -l list available drivers -lcd4linux [-c key=val] [-d] [-f config-file] [-o output] [-q] +lcd4linux -d +calibrate delay loop (necessary for some drivers) + +lcd4linux [-c key=val] [-f config-file] [-o output] [-q] [-v] run lcd4linux -generate debugging messages with '-d' +generate debugging messages with '-v' use configuration from 'config-file' instead of /etc/lcd4linux.conf write picture to 'output' (raster driver only) overwrite entries from the config-file with '-c' diff --git a/lcd4linux.c b/lcd4linux.c index 602b70e..75b195a 100644 --- a/lcd4linux.c +++ b/lcd4linux.c @@ -1,4 +1,4 @@ -/* $Id: lcd4linux.c,v 1.21 2000/04/15 11:56:35 reinelt Exp $ +/* $Id: lcd4linux.c,v 1.22 2000/04/15 16:56:52 reinelt Exp $ * * LCD4Linux * @@ -20,6 +20,14 @@ * * * $Log: lcd4linux.c,v $ + * Revision 1.22 2000/04/15 16:56:52 reinelt + * + * moved delay loops to udelay.c + * renamed -d (debugging) switch to -v (verbose) + * new switch -d to calibrate delay loop + * 'Delay' entry for HD44780 back again + * delay loops will not calibrate automatically, because this will fail with hich CPU load + * * Revision 1.21 2000/04/15 11:56:35 reinelt * * more debug messages @@ -125,12 +133,13 @@ #include <stdio.h> #include <unistd.h> -#include "debug.h" #include "cfg.h" +#include "debug.h" +#include "udelay.h" #include "display.h" #include "processor.h" -char *release="LCD4Linux V" VERSION " (c) 2000 Michael Reinelt <reinelt@eunet.at>"; +char *release="LCD4Linux " VERSION " (c) 2000 Michael Reinelt <reinelt@eunet.at>"; char *output=NULL; int debugging=0; int tick, tack; @@ -140,7 +149,8 @@ static void usage(void) printf ("%s\n", release); printf ("usage: lcd4linux [-h]\n"); printf (" lcd4linux [-l]\n"); - printf (" lcd4linux [-c key=value] [-d] [-f config-file] [-o output-file] [-q]\n"); + printf (" lcd4linux [-d]\n"); + printf (" lcd4linux [-c key=value] [-f config-file] [-o output-file] [-q] [-v]\n"); } int lcd_hello (void) @@ -186,7 +196,7 @@ int main (int argc, char *argv[]) int c, smooth; int quiet=0; - while ((c=getopt (argc, argv, "c:df:hlo:q"))!=EOF) { + while ((c=getopt (argc, argv, "c:df:hlo:qv"))!=EOF) { switch (c) { case 'c': if (cfg_cmd (optarg)<0) { @@ -195,8 +205,10 @@ int main (int argc, char *argv[]) } break; case 'd': - debugging++; - break; + printf ("%s\n", release); + udelay_calibrate(); + printf ("calibrating delay loop: Delay=%ld\n", loops_per_usec); + exit(0); case 'h': usage(); exit(0); @@ -213,6 +225,9 @@ int main (int argc, char *argv[]) case 'q': quiet++; break; + case 'v': + debugging++; + break; default: exit(2); } diff --git a/udelay.c b/udelay.c new file mode 100644 index 0000000..8bb25ab --- /dev/null +++ b/udelay.c @@ -0,0 +1,99 @@ +/* $Id: udelay.c,v 1.1 2000/04/15 16:56:52 reinelt Exp $ + * + * short delays + * + * Copyright 1999, 2000 by Michael Reinelt (reinelt@eunet.at) + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: udelay.c,v $ + * Revision 1.1 2000/04/15 16:56:52 reinelt + * + * moved delay loops to udelay.c + * renamed -d (debugging) switch to -v (verbose) + * new switch -d to calibrate delay loop + * 'Delay' entry for HD44780 back again + * delay loops will not calibrate automatically, because this will fail with hich CPU load + * + */ + +/* + * + * 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) + * does a binary approximation for 'loops_per_usec' + * should be called several times on an otherwise idle machine + * the maximum value should be used + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include "debug.h" +#include "udelay.h" + +unsigned long loops_per_usec; + +void udelay (unsigned long usec) +{ + unsigned long loop=usec*loops_per_usec; + + __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(); + udelay(1000000/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(); + udelay(1000000/CLOCKS_PER_SEC); + if (clock()>tick) + loops_per_usec&=~bit; + } +} diff --git a/udelay.h b/udelay.h new file mode 100644 index 0000000..42f2ca8 --- /dev/null +++ b/udelay.h @@ -0,0 +1,41 @@ +/* $Id: udelay.h,v 1.1 2000/04/15 16:56:52 reinelt Exp $ + * + * short delays + * + * Copyright 1999, 2000 by Michael Reinelt (reinelt@eunet.at) + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: udelay.h,v $ + * Revision 1.1 2000/04/15 16:56:52 reinelt + * + * moved delay loops to udelay.c + * renamed -d (debugging) switch to -v (verbose) + * new switch -d to calibrate delay loop + * 'Delay' entry for HD44780 back again + * delay loops will not calibrate automatically, because this will fail with hich CPU load + * + */ + +#ifndef _UDELAY_H_ +#define _UDELAY_H_ + +extern unsigned long loops_per_usec; + +void udelay (unsigned long usec); +void udelay_calibrate (void); + +#endif |