aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HD44780.c68
-rw-r--r--Makefile.am1
-rw-r--r--Makefile.in8
-rw-r--r--README9
-rw-r--r--lcd4linux.c29
-rw-r--r--udelay.c99
-rw-r--r--udelay.h41
7 files changed, 197 insertions, 58 deletions
diff --git a/HD44780.c b/HD44780.c
index 5ce60d6..4d7e4d7 100644
--- a/HD44780.c
+++ b/HD44780.c
@@ -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)
diff --git a/README b/README
index 2c50759..c715eb5 100644
--- a/README
+++ b/README
@@ -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