Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic 4-line HD44780 LCD display support. Work needed ...
details: https://anonhg.NetBSD.org/src/rev/7dc83322b9f2
branches: trunk
changeset: 583590:7dc83322b9f2
user: joff <joff%NetBSD.org@localhost>
date: Sun Aug 14 02:56:06 2005 +0000
description:
4-line HD44780 LCD display support. Work needed for the NetBSD toaster port.
The HD44780 actually doesn't support 4 lines, but the 4 line displays
use two chips, one for the top two lines and one for the bottom
two lines. The chips share the databus, register-select, and write
signals but have separate enable signals.
diffstat:
sys/dev/ic/hd44780_subr.c | 210 ++++++++++++++++++++++++++++-----------------
sys/dev/ic/hd44780var.h | 42 +++++---
2 files changed, 156 insertions(+), 96 deletions(-)
diffs (truncated from 620 to 300 lines):
diff -r d123cc9b6b4e -r 7dc83322b9f2 sys/dev/ic/hd44780_subr.c
--- a/sys/dev/ic/hd44780_subr.c Sat Aug 13 21:50:45 2005 +0000
+++ b/sys/dev/ic/hd44780_subr.c Sun Aug 14 02:56:06 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hd44780_subr.c,v 1.6 2005/02/27 00:27:01 perry Exp $ */
+/* $NetBSD: hd44780_subr.c,v 1.7 2005/08/14 02:56:06 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.6 2005/02/27 00:27:01 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.7 2005/08/14 02:56:06 joff Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -57,15 +57,14 @@
#define COORD_TO_IDX(x, y) ((y) * sc->sc_cols + (x))
#define COORD_TO_DADDR(x, y) ((y) * HD_ROW2_ADDR + (x))
-#define IDX_TO_ROW(idx) (((idx) >= sc->sc_cols) ? 1 : 0)
-#define IDX_TO_COL(idx) (((idx) >= sc->sc_cols) ? \
- ((idx) - sc->sc_cols) : (idx))
-#define IDX_TO_DDADDR(idx) ((IDX_TO_ROW((idx)) == 1) ? \
- (HD_ROW2_ADDR + IDX_TO_COL((idx))) : \
- (IDX_TO_COL((idx))))
-#define DADDR_TO_ROW(daddr) (((daddr) >= HD_ROW2_ADDR) ? 1 : 0)
-#define DADDR_TO_COL(daddr) ((DADDR_TO_ROW((daddr)) == 1) ? \
- ((daddr) - HD_ROW2_ADDR) : (daddr))
+#define IDX_TO_ROW(idx) ((idx) / sc->sc_cols)
+#define IDX_TO_COL(idx) ((idx) % sc->sc_cols)
+#define IDX_TO_DADDR(idx) (IDX_TO_ROW((idx)) * HD_ROW2_ADDR + \
+ IDX_TO_COL((idx)))
+#define DADDR_TO_ROW(daddr) ((daddr) / HD_ROW2_ADDR)
+#define DADDR_TO_COL(daddr) ((daddr) % HD_ROW2_ADDR)
+#define DADDR_TO_CHIPDADDR(daddr) ((daddr) % (HD_ROW2_ADDR * 2))
+#define DADDR_TO_CHIPNO(daddr) ((daddr) / (HD_ROW2_ADDR * 2))
static void hlcd_cursor(void *, int, int, int);
static int hlcd_mapchar(void *, int, unsigned int *);
@@ -142,7 +141,7 @@
struct hlcd_screen *hdscr = id;
c &= 0xff;
- if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE))
+ if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP)))
hdscr->image[hdscr->hlcd_sc->sc_cols * row + col] = c;
else
hdscr->image[col] = c;
@@ -161,7 +160,7 @@
if ((dstcol + ncols - 1) > hdscr->hlcd_sc->sc_cols)
ncols = hdscr->hlcd_sc->sc_cols - srccol;
- if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE))
+ if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP)))
bcopy(&hdscr->image[hdscr->hlcd_sc->sc_cols * row + srccol],
&hdscr->image[hdscr->hlcd_sc->sc_cols * row + dstcol], ncols);
else
@@ -183,7 +182,7 @@
if ((startcol + ncols) > hdscr->hlcd_sc->sc_cols)
ncols = hdscr->hlcd_sc->sc_cols - startcol;
- if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE))
+ if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP)))
memset(&hdscr->image[hdscr->hlcd_sc->sc_cols * row + startcol],
' ', ncols);
else
@@ -199,7 +198,7 @@
struct hlcd_screen *hdscr = id;
int ncols = hdscr->hlcd_sc->sc_cols;
- if (!(hdscr->hlcd_sc->sc_flags & HD_MULTILINE))
+ if (!(hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP)))
return;
bcopy(&hdscr->image[srcrow * ncols], &hdscr->image[dstrow * ncols],
nrows * ncols);
@@ -307,14 +306,16 @@
struct hd44780_chip *sc;
int daddr, c;
{
- int curdaddr;
+ int curdaddr, en, chipdaddr;
curdaddr = COORD_TO_DADDR(sc->sc_screen.hlcd_curx,
sc->sc_screen.hlcd_cury);
+ en = DADDR_TO_CHIPNO(daddr);
+ chipdaddr = DADDR_TO_CHIPDADDR(daddr);
if (daddr != curdaddr)
- hd44780_ir_write(sc, cmd_ddramset(daddr));
+ hd44780_ir_write(sc, en, cmd_ddramset(chipdaddr));
- hd44780_dr_write(sc, c);
+ hd44780_dr_write(sc, en, c);
daddr++;
sc->sc_screen.hlcd_curx = DADDR_TO_COL(daddr);
@@ -327,6 +328,7 @@
{
struct hd44780_chip *sc = arg;
int len, crsridx, startidx, x, y;
+ int old_en, new_en;
u_char *img, *curimg;
if (sc->sc_curscr == NULL)
@@ -337,13 +339,20 @@
else
len = sc->sc_cols;
+ if (sc->sc_flags & HD_MULTICHIP)
+ len = len * 2;
+
+ x = sc->sc_screen.hlcd_curx;
+ y = sc->sc_screen.hlcd_cury;
+ old_en = DADDR_TO_CHIPNO(COORD_TO_DADDR(x, y));
+
img = sc->sc_screen.image;
curimg = sc->sc_curscr->image;
startidx = crsridx =
COORD_TO_IDX(sc->sc_screen.hlcd_curx, sc->sc_screen.hlcd_cury);
do {
if (img[crsridx] != curimg[crsridx]) {
- hlcd_updatechar(sc, IDX_TO_DDADDR(crsridx),
+ hlcd_updatechar(sc, IDX_TO_DADDR(crsridx),
curimg[crsridx]);
img[crsridx] = curimg[crsridx];
}
@@ -352,19 +361,33 @@
crsridx = 0;
} while (crsridx != startidx);
+ x = sc->sc_curscr->hlcd_curx;
+ y = sc->sc_curscr->hlcd_cury;
+ new_en = DADDR_TO_CHIPNO(COORD_TO_DADDR(x, y));
+
if (sc->sc_screen.hlcd_curx != sc->sc_curscr->hlcd_curx ||
sc->sc_screen.hlcd_cury != sc->sc_curscr->hlcd_cury) {
+
x = sc->sc_screen.hlcd_curx = sc->sc_curscr->hlcd_curx;
y = sc->sc_screen.hlcd_cury = sc->sc_curscr->hlcd_cury;
- hd44780_ir_write(sc, cmd_ddramset(COORD_TO_DADDR(x, y)));
+
+ hd44780_ir_write(sc, new_en, cmd_ddramset(
+ DADDR_TO_CHIPDADDR(COORD_TO_DADDR(x, y))));
+
+ }
+
+ /* visible cursor switched to other chip */
+ if (old_en != new_en && sc->sc_screen.hlcd_curon) {
+ hd44780_ir_write(sc, old_en, cmd_dispctl(1, 0, 0));
+ hd44780_ir_write(sc, new_en, cmd_dispctl(1, 1, 1));
}
if (sc->sc_screen.hlcd_curon != sc->sc_curscr->hlcd_curon) {
sc->sc_screen.hlcd_curon = sc->sc_curscr->hlcd_curon;
if (sc->sc_screen.hlcd_curon)
- hd44780_ir_write(sc, cmd_dispctl(1, 1, 1));
+ hd44780_ir_write(sc, new_en, cmd_dispctl(1, 1, 1));
else
- hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
+ hd44780_ir_write(sc, new_en, cmd_dispctl(1, 0, 0));
}
callout_schedule(&sc->redraw, 1);
@@ -403,26 +426,39 @@
sc->sc_screen.image = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
memset(sc->sc_screen.image, ' ', PAGE_SIZE);
sc->sc_curscr = NULL;
+ sc->sc_curchip = 0;
callout_init(&sc->redraw);
callout_setfunc(&sc->redraw, hlcd_redraw, sc);
}
+int hd44780_init(sc)
+ struct hd44780_chip *sc;
+{
+ int ret;
+
+ ret = hd44780_chipinit(sc, 0);
+ if (ret != 0 || !(sc->sc_flags & HD_MULTICHIP)) return ret;
+ else return hd44780_chipinit(sc, 1);
+}
+
/*
* Initialize 4-bit or 8-bit connected device.
*/
int
-hd44780_init(sc)
+hd44780_chipinit(sc, en)
struct hd44780_chip *sc;
+ u_int32_t en;
{
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);
+ hd44780_ir_write(sc, en, cmd);
delay(HD_TIMEOUT_LONG);
- hd44780_ir_write(sc, cmd);
- hd44780_ir_write(sc, cmd);
+ hd44780_ir_write(sc, en, cmd);
+ hd44780_ir_write(sc, en, cmd);
cmd = cmd_funcset(
sc->sc_flags & HD_8BIT,
@@ -430,14 +466,14 @@
sc->sc_flags & HD_BIGFONT);
if ((sc->sc_flags & HD_8BIT) == 0)
- hd44780_ir_write(sc, cmd);
+ hd44780_ir_write(sc, en, cmd);
sc->sc_flags |= HD_UP;
- hd44780_ir_write(sc, cmd);
- hd44780_ir_write(sc, cmd_dispctl(0, 0, 0));
- hd44780_ir_write(sc, cmd_clear());
- hd44780_ir_write(sc, cmd_modset(1, 0));
+ hd44780_ir_write(sc, en, cmd);
+ hd44780_ir_write(sc, en, cmd_dispctl(0, 0, 0));
+ hd44780_ir_write(sc, en, cmd_clear());
+ hd44780_ir_write(sc, en, cmd_modset(1, 0));
if (sc->sc_flags & HD_TIMEDOUT) {
sc->sc_flags &= ~HD_UP;
@@ -445,19 +481,19 @@
}
/* Turn display on and clear it. */
- hd44780_ir_write(sc, cmd_clear());
- hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
+ hd44780_ir_write(sc, en, cmd_clear());
+ hd44780_ir_write(sc, en, 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) {
+ hd44780_ir_write(sc, en, cmd_ddramset(0x5));
+ hd44780_ir_write(sc, en, cmd_shift(0, 1));
+ hd44780_busy_wait(sc, en);
+ if ((dat = hd44780_ir_read(sc, en) & 0x7f) != 0x6) {
sc->sc_dev_ok = 0;
sc->sc_flags &= ~HD_UP;
return EIO;
}
- hd44780_ir_write(sc, cmd_ddramset(0));
+ hd44780_ir_write(sc, en, cmd_ddramset(0));
return 0;
}
@@ -473,6 +509,7 @@
{
u_int8_t tmp;
int error = 0;
+ u_int32_t en = sc->sc_curchip;
#define hd44780_io() ((struct hd44780_io *)data)
#define hd44780_info() ((struct hd44780_info*)data)
@@ -481,22 +518,22 @@
switch (cmd) {
/* Clear the LCD. */
case HLCD_CLEAR:
- hd44780_ir_write(sc, cmd_clear());
+ hd44780_ir_write(sc, en, cmd_clear());
break;
/* Move the cursor one position to the left. */
case HLCD_CURSOR_LEFT:
- hd44780_ir_write(sc, cmd_shift(0, 0));
+ hd44780_ir_write(sc, en, cmd_shift(0, 0));
break;
/* Move the cursor one position to the right. */
case HLCD_CURSOR_RIGHT:
- hd44780_ir_write(sc, cmd_shift(0, 1));
+ hd44780_ir_write(sc, en, cmd_shift(0, 1));
break;
/* Control the LCD. */
case HLCD_DISPCTL:
- hd44780_ir_write(sc, cmd_dispctl(
+ hd44780_ir_write(sc, en, cmd_dispctl(
hd44780_ctrl()->display_on,
hd44780_ctrl()->cursor_on,
hd44780_ctrl()->blink_on));
@@ -506,6 +543,8 @@
case HLCD_GET_INFO:
hd44780_info()->lines
= (sc->sc_flags & HD_MULTILINE) ? 2 : 1;
+ if (sc->sc_flags & HD_MULTICHIP)
+ hd44780_info()->lines *= 2;
hd44780_info()->phys_rows = sc->sc_cols;
hd44780_info()->virt_rows = sc->sc_vcols;
hd44780_info()->is_wide = sc->sc_flags & HD_8BIT;
Home |
Main Index |
Thread Index |
Old Index