Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Handle (i.e. don't lock up the kernel in hd44780_...
details: https://anonhg.NetBSD.org/src/rev/8a0afde0fe9c
branches: trunk
changeset: 572633:8a0afde0fe9c
user: joff <joff%NetBSD.org@localhost>
date: Sun Jan 09 15:43:56 2005 +0000
description:
Handle (i.e. don't lock up the kernel in hd44780_busy_wait) the case of the
LCD not being there.
diffstat:
sys/dev/ic/hd44780_subr.c | 84 ++++++++++++++++++++++++++++++++++++----------
sys/dev/ic/hd44780_subr.h | 8 ++--
2 files changed, 70 insertions(+), 22 deletions(-)
diffs (222 lines):
diff -r e917739bc0c7 -r 8a0afde0fe9c sys/dev/ic/hd44780_subr.c
--- a/sys/dev/ic/hd44780_subr.c Sun Jan 09 15:39:59 2005 +0000
+++ b/sys/dev/ic/hd44780_subr.c Sun Jan 09 15:43:56 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hd44780_subr.c,v 1.2 2005/01/08 20:17:22 joff Exp $ */
+/* $NetBSD: hd44780_subr.c,v 1.3 2005/01/09 15:43:56 joff Exp $ */
/*
* Copyright (c) 2002 Dennis I. Chernoivanov
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.2 2005/01/08 20:17:22 joff Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.3 2005/01/09 15:43:56 joff Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -48,8 +48,6 @@
#include <dev/ic/hd44780reg.h>
#include <dev/ic/hd44780_subr.h>
-static void hd44780_init(struct hd44780_chip *);
-
/*
* Finish device attach. sc_writereg, sc_readreg and sc_flags must be properly
* initialized prior to this call.
@@ -58,6 +56,7 @@
hd44780_attach_subr(sc)
struct hd44780_chip *sc;
{
+ int err = 0;
/* Putc/getc are supposed to be set by platform-dependent code. */
if ((sc->sc_writereg == NULL) || (sc->sc_readreg == NULL))
sc->sc_dev_ok = 0;
@@ -69,24 +68,25 @@
sc->sc_dev_ok = 0;
if (sc->sc_dev_ok) {
- if ((sc->sc_flags & HD_UP) == 0)
- hd44780_init(sc);
+ if ((sc->sc_flags & HD_UP) == 0)
+ err = hd44780_init(sc);
+ if (err != 0)
+ printf("%s: not responding or unconnected\n", sc->sc_dev->dv_xname);
- /* Turn display on and clear it. */
- hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
- hd44780_ir_write(sc, cmd_clear());
}
}
/*
* Initialize 4-bit or 8-bit connected device.
*/
-static void
+int
hd44780_init(sc)
struct hd44780_chip *sc;
{
- u_int8_t cmd;
+ u_int8_t cmd, dat;
+ sc->sc_flags &= ~(HD_TIMEDOUT|HD_UP);
+ sc->sc_dev_ok = 1;
cmd = cmd_init(sc->sc_flags & HD_8BIT);
hd44780_ir_write(sc, cmd);
delay(HD_TIMEOUT_LONG);
@@ -107,6 +107,28 @@
hd44780_ir_write(sc, cmd_dispctl(0, 0, 0));
hd44780_ir_write(sc, cmd_clear());
hd44780_ir_write(sc, cmd_modset(1, 0));
+
+ if (sc->sc_flags & HD_TIMEDOUT) {
+ sc->sc_flags &= ~HD_UP;
+ return EIO;
+ }
+
+ /* Turn display on and clear it. */
+ hd44780_ir_write(sc, cmd_clear());
+ hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
+
+ /* Attempt a simple probe for presence */
+ hd44780_ir_write(sc, cmd_ddramset(0x5));
+ hd44780_ir_write(sc, cmd_shift(0, 1));
+ hd44780_busy_wait(sc);
+ if ((dat = hd44780_ir_read(sc) & 0x7f) != 0x6) {
+ sc->sc_dev_ok = 0;
+ sc->sc_flags &= ~HD_UP;
+ return EIO;
+ }
+ hd44780_ir_write(sc, cmd_ddramset(0));
+
+ return 0;
}
/*
@@ -163,13 +185,7 @@
/* Reset the LCD. */
case HLCD_RESET:
- hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
- hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
- hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
- hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
- hd44780_ir_write(sc, cmd_modset(1, 0));
- hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
- hd44780_ir_write(sc, cmd_clear());
+ error = hd44780_init(sc);
break;
/* Get the current cursor position. */
@@ -238,6 +254,9 @@
error = EINVAL;
}
+ if (sc->sc_flags & HD_TIMEDOUT)
+ error = EIO;
+
return error;
}
@@ -308,6 +327,23 @@
hd44780_dr_write(sc, io->buf[i]);
}
+void
+hd44780_busy_wait(sc)
+ struct hd44780_chip *sc;
+{
+ int nloops = 100;
+
+ if (sc->sc_flags & HD_TIMEDOUT)
+ return;
+
+ while(nloops-- && (hd44780_ir_read(sc) & BUSY_FLAG) == BUSY_FLAG);
+
+ if (nloops == 0) {
+ sc->sc_flags |= HD_TIMEDOUT;
+ sc->sc_dev_ok = 0;
+ }
+}
+
#if defined(HD44780_STD_WIDE)
/*
* Standard 8-bit version of 'sc_writereg' (8-bit port, 8-bit access)
@@ -321,6 +357,9 @@
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh;
+ if (sc->sc_dev_ok == 0)
+ return;
+
if (reg == 0)
ioh = sc->sc_ioir;
else
@@ -341,6 +380,9 @@
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh;
+ if (sc->sc_dev_ok == 0)
+ return;
+
if (reg == 0)
ioh = sc->sc_ioir;
else
@@ -362,6 +404,9 @@
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh;
+ if (sc->sc_dev_ok == 0)
+ return;
+
if (reg == 0)
ioh = sc->sc_ioir;
else
@@ -385,6 +430,9 @@
bus_space_handle_t ioh;
u_int8_t rd, dat;
+ if (sc->sc_dev_ok == 0)
+ return;
+
if (reg == 0)
ioh = sc->sc_ioir;
else
diff -r e917739bc0c7 -r 8a0afde0fe9c sys/dev/ic/hd44780_subr.h
--- a/sys/dev/ic/hd44780_subr.h Sun Jan 09 15:39:59 2005 +0000
+++ b/sys/dev/ic/hd44780_subr.h Sun Jan 09 15:43:56 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hd44780_subr.h,v 1.2 2005/01/08 20:17:22 joff Exp $ */
+/* $NetBSD: hd44780_subr.h,v 1.3 2005/01/09 15:43:56 joff Exp $ */
/*
* Copyright (c) 2002 Dennis I. Chernoivanov
@@ -81,6 +81,7 @@
#define HD_BIGFONT 0x04 /* 5x10 if set, 5x8 otherwise */
#define HD_KEYPAD 0x08 /* if set, keypad is connected */
#define HD_UP 0x10 /* if set, lcd has been initialized */
+#define HD_TIMEDOUT 0x20 /* lcd has recently stopped talking */
u_char sc_flags;
u_char sc_rows; /* visible rows */
@@ -99,9 +100,6 @@
u_int8_t (* sc_readreg)(struct hd44780_chip *, u_int32_t);
};
-#define hd44780_busy_wait(sc) \
- while((hd44780_ir_read(sc) & BUSY_FLAG) == BUSY_FLAG)
-
#define hd44780_ir_write(sc, dat) \
do { \
hd44780_busy_wait(sc); \
@@ -118,6 +116,8 @@
(sc)->sc_readreg((sc), 1)
void hd44780_attach_subr(struct hd44780_chip *);
+void hd44780_busy_wait(struct hd44780_chip *);
+int hd44780_init(struct hd44780_chip *);
int hd44780_ioctl_subr(struct hd44780_chip *, u_long, caddr_t);
void hd44780_ddram_redraw(struct hd44780_chip *, struct hd44780_io *);
Home |
Main Index |
Thread Index |
Old Index