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.
This commit is contained in:
parent
e446808533
commit
02e79f9fb1
|
@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.6 2005/02/27 00:27:01 perry Exp $
|
|||
|
||||
#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 @@ hlcd_putchar(id, row, col, c, attr)
|
|||
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 @@ hlcd_copycols(id, row, srccol, dstcol, ncols)
|
|||
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 @@ hlcd_erasecols(id, row, startcol, ncols, fillattr)
|
|||
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 @@ hlcd_copyrows(id, srcrow, dstrow, nrows)
|
|||
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 @@ hlcd_updatechar(sc, daddr, c)
|
|||
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 @@ hlcd_redraw(arg)
|
|||
{
|
||||
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 @@ hlcd_redraw(arg)
|
|||
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 @@ hlcd_redraw(arg)
|
|||
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 @@ hd44780_attach_subr(sc)
|
|||
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 @@ hd44780_init(sc)
|
|||
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 @@ hd44780_init(sc)
|
|||
}
|
||||
|
||||
/* 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 @@ hd44780_ioctl_subr(sc, cmd, data)
|
|||
{
|
||||
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 @@ hd44780_ioctl_subr(sc, cmd, data)
|
|||
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 @@ hd44780_ioctl_subr(sc, cmd, data)
|
|||
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;
|
||||
|
@ -521,64 +560,74 @@ hd44780_ioctl_subr(sc, cmd, data)
|
|||
|
||||
/* Get the current cursor position. */
|
||||
case HLCD_GET_CURSOR_POS:
|
||||
hd44780_io()->dat = (hd44780_ir_read(sc) & 0x7f);
|
||||
hd44780_io()->dat = (hd44780_ir_read(sc, en) & 0x7f);
|
||||
break;
|
||||
|
||||
/* Set the cursor position. */
|
||||
case HLCD_SET_CURSOR_POS:
|
||||
hd44780_ir_write(sc, cmd_ddramset(hd44780_io()->dat));
|
||||
hd44780_ir_write(sc, en, cmd_ddramset(hd44780_io()->dat));
|
||||
break;
|
||||
|
||||
/* Get the value at the current cursor position. */
|
||||
case HLCD_GETC:
|
||||
tmp = (hd44780_ir_read(sc) & 0x7f);
|
||||
hd44780_ir_write(sc, cmd_ddramset(tmp));
|
||||
hd44780_io()->dat = hd44780_dr_read(sc);
|
||||
tmp = (hd44780_ir_read(sc, en) & 0x7f);
|
||||
hd44780_ir_write(sc, en, cmd_ddramset(tmp));
|
||||
hd44780_io()->dat = hd44780_dr_read(sc, en);
|
||||
break;
|
||||
|
||||
/* Set the character at the cursor position + advance cursor. */
|
||||
case HLCD_PUTC:
|
||||
hd44780_dr_write(sc, hd44780_io()->dat);
|
||||
hd44780_dr_write(sc, en, hd44780_io()->dat);
|
||||
break;
|
||||
|
||||
/* Shift display left. */
|
||||
case HLCD_SHIFT_LEFT:
|
||||
hd44780_ir_write(sc, cmd_shift(1, 0));
|
||||
hd44780_ir_write(sc, en, cmd_shift(1, 0));
|
||||
break;
|
||||
|
||||
/* Shift display right. */
|
||||
case HLCD_SHIFT_RIGHT:
|
||||
hd44780_ir_write(sc, cmd_shift(1, 1));
|
||||
hd44780_ir_write(sc, en, cmd_shift(1, 1));
|
||||
break;
|
||||
|
||||
/* Return home. */
|
||||
case HLCD_HOME:
|
||||
hd44780_ir_write(sc, cmd_rethome());
|
||||
hd44780_ir_write(sc, en, cmd_rethome());
|
||||
break;
|
||||
|
||||
/* Write a string to the LCD virtual area. */
|
||||
case HLCD_WRITE:
|
||||
error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_WRITE);
|
||||
error = hd44780_ddram_io(sc, en, hd44780_io(), HD_DDRAM_WRITE);
|
||||
break;
|
||||
|
||||
/* Read LCD virtual area. */
|
||||
case HLCD_READ:
|
||||
error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_READ);
|
||||
error = hd44780_ddram_io(sc, en, hd44780_io(), HD_DDRAM_READ);
|
||||
break;
|
||||
|
||||
/* Write to the LCD visible area. */
|
||||
case HLCD_REDRAW:
|
||||
hd44780_ddram_redraw(sc, hd44780_io());
|
||||
hd44780_ddram_redraw(sc, en, hd44780_io());
|
||||
break;
|
||||
|
||||
/* Write raw instruction. */
|
||||
case HLCD_WRITE_INST:
|
||||
hd44780_ir_write(sc, hd44780_io()->dat);
|
||||
hd44780_ir_write(sc, en, hd44780_io()->dat);
|
||||
break;
|
||||
|
||||
/* Write raw data. */
|
||||
case HLCD_WRITE_DATA:
|
||||
hd44780_dr_write(sc, hd44780_io()->dat);
|
||||
hd44780_dr_write(sc, en, hd44780_io()->dat);
|
||||
break;
|
||||
|
||||
/* Get current chip 0 or 1 (top or bottom) */
|
||||
case HLCD_GET_CHIPNO:
|
||||
*(u_int8_t *)data = sc->sc_curchip;
|
||||
break;
|
||||
|
||||
/* Set current chip 0 or 1 (top or bottom) */
|
||||
case HLCD_SET_CHIPNO:
|
||||
sc->sc_curchip = *(u_int8_t *)data;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -595,8 +644,9 @@ hd44780_ioctl_subr(sc, cmd, data)
|
|||
* Read/write particular area of the LCD screen.
|
||||
*/
|
||||
int
|
||||
hd44780_ddram_io(sc, io, dir)
|
||||
hd44780_ddram_io(sc, en, io, dir)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t en;
|
||||
struct hd44780_io *io;
|
||||
u_char dir;
|
||||
{
|
||||
|
@ -610,11 +660,11 @@ hd44780_ddram_io(sc, io, dir)
|
|||
hi = HD_ROW1_ADDR + sc->sc_vcols;
|
||||
addr = HD_ROW1_ADDR + io->dat;
|
||||
for (; (addr < hi) && (i < io->len); addr++, i++) {
|
||||
hd44780_ir_write(sc, cmd_ddramset(addr));
|
||||
hd44780_ir_write(sc, en, cmd_ddramset(addr));
|
||||
if (dir == HD_DDRAM_READ)
|
||||
io->buf[i] = hd44780_dr_read(sc);
|
||||
io->buf[i] = hd44780_dr_read(sc, en);
|
||||
else
|
||||
hd44780_dr_write(sc, io->buf[i]);
|
||||
hd44780_dr_write(sc, en, io->buf[i]);
|
||||
}
|
||||
}
|
||||
if (io->dat < 2 * sc->sc_vcols) {
|
||||
|
@ -624,11 +674,11 @@ hd44780_ddram_io(sc, io, dir)
|
|||
else
|
||||
addr = HD_ROW2_ADDR;
|
||||
for (; (addr < hi) && (i < io->len); addr++, i++) {
|
||||
hd44780_ir_write(sc, cmd_ddramset(addr));
|
||||
hd44780_ir_write(sc, en, cmd_ddramset(addr));
|
||||
if (dir == HD_DDRAM_READ)
|
||||
io->buf[i] = hd44780_dr_read(sc);
|
||||
io->buf[i] = hd44780_dr_read(sc, en);
|
||||
else
|
||||
hd44780_dr_write(sc, io->buf[i]);
|
||||
hd44780_dr_write(sc, en, io->buf[i]);
|
||||
}
|
||||
if (i < io->len)
|
||||
io->len = i;
|
||||
|
@ -642,32 +692,34 @@ hd44780_ddram_io(sc, io, dir)
|
|||
* Write to the visible area of the display.
|
||||
*/
|
||||
void
|
||||
hd44780_ddram_redraw(sc, io)
|
||||
hd44780_ddram_redraw(sc, en, io)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t en;
|
||||
struct hd44780_io *io;
|
||||
{
|
||||
u_int8_t i;
|
||||
|
||||
hd44780_ir_write(sc, cmd_clear());
|
||||
hd44780_ir_write(sc, cmd_rethome());
|
||||
hd44780_ir_write(sc, en, cmd_clear());
|
||||
hd44780_ir_write(sc, en, cmd_rethome());
|
||||
for (i = 0; (i < io->len) && (i < sc->sc_cols); i++) {
|
||||
hd44780_dr_write(sc, io->buf[i]);
|
||||
hd44780_dr_write(sc, en, io->buf[i]);
|
||||
}
|
||||
hd44780_ir_write(sc, cmd_ddramset(HD_ROW2_ADDR));
|
||||
hd44780_ir_write(sc, en, cmd_ddramset(HD_ROW2_ADDR));
|
||||
for (; (i < io->len); i++)
|
||||
hd44780_dr_write(sc, io->buf[i]);
|
||||
hd44780_dr_write(sc, en, io->buf[i]);
|
||||
}
|
||||
|
||||
void
|
||||
hd44780_busy_wait(sc)
|
||||
hd44780_busy_wait(sc, en)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t en;
|
||||
{
|
||||
int nloops = 100;
|
||||
|
||||
if (sc->sc_flags & HD_TIMEDOUT)
|
||||
return;
|
||||
|
||||
while(nloops-- && (hd44780_ir_read(sc) & BUSY_FLAG) == BUSY_FLAG);
|
||||
while(nloops-- && (hd44780_ir_read(sc, en) & BUSY_FLAG) == BUSY_FLAG);
|
||||
|
||||
if (nloops == 0) {
|
||||
sc->sc_flags |= HD_TIMEDOUT;
|
||||
|
@ -680,9 +732,9 @@ hd44780_busy_wait(sc)
|
|||
* Standard 8-bit version of 'sc_writereg' (8-bit port, 8-bit access)
|
||||
*/
|
||||
void
|
||||
hd44780_writereg(sc, reg, cmd)
|
||||
hd44780_writereg(sc, en, reg, cmd)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t reg;
|
||||
u_int32_t en, reg;
|
||||
u_int8_t cmd;
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
|
@ -704,9 +756,9 @@ hd44780_writereg(sc, reg, cmd)
|
|||
* Standard 8-bit version of 'sc_readreg' (8-bit port, 8-bit access)
|
||||
*/
|
||||
u_int8_t
|
||||
hd44780_readreg(sc, reg)
|
||||
hd44780_readreg(sc, en, reg)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t reg;
|
||||
u_int32_t en, reg;
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
@ -727,9 +779,9 @@ hd44780_readreg(sc, reg)
|
|||
* Standard 4-bit version of 'sc_writereg' (4-bit port, 8-bit access)
|
||||
*/
|
||||
void
|
||||
hd44780_writereg(sc, reg, cmd)
|
||||
hd44780_writereg(sc, en, reg, cmd)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t reg;
|
||||
u_int32_t en, reg;
|
||||
u_int8_t cmd;
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
|
@ -753,9 +805,9 @@ hd44780_writereg(sc, reg, cmd)
|
|||
* Standard 4-bit version of 'sc_readreg' (4-bit port, 8-bit access)
|
||||
*/
|
||||
u_int8_t
|
||||
hd44780_readreg(sc, reg)
|
||||
hd44780_readreg(sc, en, reg)
|
||||
struct hd44780_chip *sc;
|
||||
u_int32_t reg;
|
||||
u_int32_t en, reg;
|
||||
{
|
||||
bus_space_tag_t iot = sc->sc_iot;
|
||||
bus_space_handle_t ioh;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hd44780var.h,v 1.2 2005/02/04 05:58:44 joff Exp $ */
|
||||
/* $NetBSD: hd44780var.h,v 1.3 2005/08/14 02:56:06 joff Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Dennis I. Chernoivanov
|
||||
|
@ -49,14 +49,18 @@
|
|||
#define HLCD_WRITE_INST _IOW('h', 16, struct hd44780_io)
|
||||
#define HLCD_WRITE_DATA _IOW('h', 17, struct hd44780_io)
|
||||
#define HLCD_GET_INFO _IOR('h', 18, struct hd44780_info)
|
||||
#define HLCD_GET_CHIPNO _IOR('h', 19, u_int8_t)
|
||||
#define HLCD_SET_CHIPNO _IOW('h', 20, u_int8_t)
|
||||
|
||||
struct hd44780_dispctl {
|
||||
u_int8_t chip;
|
||||
u_char display_on:1,
|
||||
blink_on:1,
|
||||
cursor_on:1;
|
||||
};
|
||||
|
||||
struct hd44780_io {
|
||||
u_int8_t chip;
|
||||
u_int8_t dat;
|
||||
u_int8_t len;
|
||||
u_int8_t buf[HD_MAX_CHARS];
|
||||
|
@ -90,11 +94,13 @@ struct hd44780_chip {
|
|||
#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 */
|
||||
#define HD_MULTICHIP 0x40 /* two HD44780 controllers (4-line) */
|
||||
u_char sc_flags;
|
||||
|
||||
u_char sc_cols; /* visible columns */
|
||||
u_char sc_vcols; /* virtual columns (normally 40) */
|
||||
u_char sc_dev_ok;
|
||||
u_char sc_curchip;
|
||||
|
||||
bus_space_tag_t sc_iot;
|
||||
|
||||
|
@ -107,38 +113,40 @@ struct hd44780_chip {
|
|||
struct callout redraw; /* wsdisplay refresh/redraw timer */
|
||||
|
||||
/* Generic write/read byte entries. */
|
||||
void (* sc_writereg)(struct hd44780_chip *, u_int32_t, u_int8_t);
|
||||
u_int8_t (* sc_readreg)(struct hd44780_chip *, u_int32_t);
|
||||
void (* sc_writereg)(struct hd44780_chip *, u_int32_t, u_int32_t,
|
||||
u_int8_t);
|
||||
u_int8_t (* sc_readreg)(struct hd44780_chip *, u_int32_t, u_int32_t);
|
||||
};
|
||||
|
||||
#define hd44780_ir_write(sc, dat) \
|
||||
#define hd44780_ir_write(sc, en, dat) \
|
||||
do { \
|
||||
hd44780_busy_wait(sc); \
|
||||
(sc)->sc_writereg((sc), 0, (dat)); \
|
||||
hd44780_busy_wait(sc, (en)); \
|
||||
(sc)->sc_writereg((sc), (en), 0, (dat)); \
|
||||
} while(0)
|
||||
|
||||
#define hd44780_ir_read(sc) \
|
||||
(sc)->sc_readreg((sc), 0)
|
||||
#define hd44780_ir_read(sc, en) \
|
||||
(sc)->sc_readreg((sc), (en), 0)
|
||||
|
||||
#define hd44780_dr_write(sc, dat) \
|
||||
(sc)->sc_writereg((sc), 1, (dat))
|
||||
#define hd44780_dr_write(sc, en, dat) \
|
||||
(sc)->sc_writereg((sc), (en), 1, (dat))
|
||||
|
||||
#define hd44780_dr_read(sc) \
|
||||
(sc)->sc_readreg((sc), 1)
|
||||
#define hd44780_dr_read(sc, en) \
|
||||
(sc)->sc_readreg((sc), (en), 1)
|
||||
|
||||
void hd44780_attach_subr(struct hd44780_chip *);
|
||||
void hd44780_busy_wait(struct hd44780_chip *);
|
||||
void hd44780_busy_wait(struct hd44780_chip *, u_int32_t);
|
||||
int hd44780_init(struct hd44780_chip *);
|
||||
int hd44780_chipinit(struct hd44780_chip *, u_int32_t);
|
||||
int hd44780_ioctl_subr(struct hd44780_chip *, u_long, caddr_t);
|
||||
void hd44780_ddram_redraw(struct hd44780_chip *, struct hd44780_io *);
|
||||
void hd44780_ddram_redraw(struct hd44780_chip *, u_int32_t, struct hd44780_io *);
|
||||
|
||||
#define HD_DDRAM_READ 0x0
|
||||
#define HD_DDRAM_WRITE 0x1
|
||||
int hd44780_ddram_io(struct hd44780_chip *, struct hd44780_io *, u_char);
|
||||
int hd44780_ddram_io(struct hd44780_chip *, u_int32_t, struct hd44780_io *, u_char);
|
||||
|
||||
#if defined(HD44780_STD_WIDE) || defined(HD44780_STD_SHORT)
|
||||
void hd44780_writereg(struct hd44780_chip *, u_int32_t, u_int8_t);
|
||||
u_int8_t hd44780_readreg(struct hd44780_chip *, u_int32_t);
|
||||
void hd44780_writereg(struct hd44780_chip *, u_int32_t, u_int32_t, u_int8_t);
|
||||
u_int8_t hd44780_readreg(struct hd44780_chip *, u_int32_t, u_int32_t);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
|
Loading…
Reference in New Issue