The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/hd44780_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: hd44780_subr.c,v 1.1 2003/01/20 01:20:50 soren Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2002 Dennis I. Chernoivanov
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 /*
   31  * Subroutines for Hitachi HD44870 style displays
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.1 2003/01/20 01:20:50 soren Exp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/conf.h>
   40 #include <sys/kernel.h>
   41 #include <sys/types.h>
   42 #include <sys/ioccom.h>
   43 
   44 #include <machine/autoconf.h>
   45 #include <machine/intr.h>
   46 #include <machine/bus.h>
   47 
   48 #include <dev/ic/hd44780reg.h>
   49 #include <dev/ic/hd44780_subr.h>
   50 
   51 static void     hd44780_init(struct hd44780_chip *);
   52 
   53 /*
   54  * Finish device attach. sc_writereg, sc_readreg and sc_flags must be properly
   55  * initialized prior to this call.
   56  */
   57 void
   58 hd44780_attach_subr(sc)
   59         struct hd44780_chip *sc;
   60 {
   61         /* Putc/getc are supposed to be set by platform-dependent code. */
   62         if ((sc->sc_rwrite == NULL) || (sc->sc_rread == NULL))
   63                 sc->sc_dev_ok = 0;
   64 
   65         /* Make sure that HD_MAX_CHARS is enough. */
   66         if ((sc->sc_flags & HD_MULTILINE) && (2 * sc->sc_rows > HD_MAX_CHARS))
   67                 sc->sc_dev_ok = 0;
   68         else if (sc->sc_rows > HD_MAX_CHARS)
   69                 sc->sc_dev_ok = 0;
   70 
   71         if (sc->sc_dev_ok) {
   72                 hd44780_init(sc);
   73 
   74                 /* Turn display on and clear it. */
   75                 hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
   76                 hd44780_ir_write(sc, cmd_clear());
   77         }
   78 }
   79 
   80 /*
   81  * Initialize 4-bit or 8-bit connected device.
   82  */
   83 static void
   84 hd44780_init(sc)
   85         struct hd44780_chip *sc;
   86 {
   87         u_int8_t cmd;
   88 
   89         bus_space_tag_t iot;
   90         bus_space_handle_t ioh;
   91 
   92         iot = sc->sc_iot;
   93         ioh = sc->sc_ioir;
   94 
   95         if (sc->sc_irwrite == NULL)
   96                 sc->sc_irwrite = sc->sc_rwrite;
   97 
   98         cmd = cmd_init(sc->sc_flags & HD_8BIT);
   99         sc->sc_irwrite(iot, ioh, cmd);
  100         delay(TIMEOUT_LONG);
  101         sc->sc_irwrite(iot, ioh, cmd);
  102         sc->sc_irwrite(iot, ioh, cmd);
  103 
  104         cmd = cmd_funcset(
  105                         sc->sc_flags & HD_8BIT,
  106                         sc->sc_flags & HD_MULTILINE,
  107                         sc->sc_flags & HD_BIGFONT);
  108 
  109         if ((sc->sc_flags & HD_8BIT) == 0)
  110                 sc->sc_irwrite(iot, ioh, cmd);
  111 
  112         /* Interface is set to the proper width, use normal 'write' op. */
  113         sc->sc_rwrite(iot, ioh, cmd);
  114         cmd = cmd_dispctl(0, 0, 0);
  115         sc->sc_rwrite(iot, ioh, cmd);
  116         cmd = cmd_clear();
  117         sc->sc_rwrite(iot, ioh, cmd);
  118         cmd = cmd_modset(1, 0);
  119         sc->sc_rwrite(iot, ioh, cmd);
  120 }
  121 
  122 /*
  123  * Standard hd44780 ioctl() functions.
  124  */
  125 int
  126 hd44780_ioctl_subr(sc, cmd, data)
  127         struct hd44780_chip *sc;
  128         u_long cmd;
  129         caddr_t data;
  130 {
  131         u_int8_t tmp;
  132         int error = 0;
  133 
  134 #define hd44780_io()    ((struct hd44780_io *)data)
  135 #define hd44780_info()  ((struct hd44780_info*)data)
  136 #define hd44780_ctrl()  ((struct hd44780_dispctl*)data)
  137 
  138         switch (cmd) {
  139                 /* Clear the LCD. */
  140                 case HLCD_CLEAR:
  141                         hd44780_ir_write(sc, cmd_clear());
  142                         break;
  143 
  144                 /* Move the cursor one position to the left. */
  145                 case HLCD_CURSOR_LEFT:
  146                         hd44780_ir_write(sc, cmd_shift(0, 0));
  147                         break;
  148 
  149                 /* Move the cursor one position to the right. */
  150                 case HLCD_CURSOR_RIGHT:
  151                         hd44780_ir_write(sc, cmd_shift(0, 1));
  152                         break;  
  153 
  154                 /* Control the LCD. */
  155                 case HLCD_DISPCTL:
  156                         hd44780_ir_write(sc, cmd_dispctl(
  157                                                 hd44780_ctrl()->display_on,
  158                                                 hd44780_ctrl()->cursor_on,
  159                                                 hd44780_ctrl()->blink_on));
  160                         break;
  161 
  162                 /* Get LCD configuration. */
  163                 case HLCD_GET_INFO:
  164                         hd44780_info()->lines
  165                                 = (sc->sc_flags & HD_MULTILINE) ? 2 : 1;
  166                         hd44780_info()->phys_rows = sc->sc_rows;
  167                         hd44780_info()->virt_rows = sc->sc_vrows;
  168                         hd44780_info()->is_wide = sc->sc_flags & HD_8BIT;
  169                         hd44780_info()->is_bigfont = sc->sc_flags & HD_BIGFONT;
  170                         hd44780_info()->kp_present = sc->sc_flags & HD_KEYPAD;
  171                         break;
  172 
  173 
  174                 /* Reset the LCD. */
  175                 case HLCD_RESET:
  176                         hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
  177                         hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
  178                         hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
  179                         hd44780_ir_write(sc, cmd_init(sc->sc_flags & HD_8BIT));
  180                         hd44780_ir_write(sc, cmd_modset(1, 0));
  181                         hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
  182                         hd44780_ir_write(sc, cmd_clear());
  183                         break;
  184 
  185                 /* Get the current cursor position. */
  186                 case HLCD_GET_CURSOR_POS:
  187                         hd44780_io()->dat = (hd44780_ir_read(sc) & 0x7f);
  188                         break;
  189 
  190                 /* Set the cursor position. */
  191                 case HLCD_SET_CURSOR_POS:
  192                         hd44780_ir_write(sc, cmd_ddramset(hd44780_io()->dat));
  193                         break;
  194 
  195                 /* Get the value at the current cursor position. */
  196                 case HLCD_GETC:
  197                         tmp = (hd44780_ir_read(sc) & 0x7f);
  198                         hd44780_ir_write(sc, cmd_ddramset(tmp));
  199                         hd44780_io()->dat = hd44780_dr_read(sc);
  200                         break;
  201 
  202                 /* Set the character at the cursor position + advance cursor. */
  203                 case HLCD_PUTC:
  204                         hd44780_dr_write(sc, hd44780_io()->dat);
  205                         break;
  206 
  207                 /* Shift display left. */
  208                 case HLCD_SHIFT_LEFT:
  209                         hd44780_ir_write(sc, cmd_shift(1, 0));
  210                         break;
  211 
  212                 /* Shift display right. */
  213                 case HLCD_SHIFT_RIGHT:
  214                         hd44780_ir_write(sc, cmd_shift(1, 1));
  215                         break;
  216 
  217                 /* Return home. */
  218                 case HLCD_HOME:
  219                         hd44780_ir_write(sc, cmd_rethome());
  220                         break;
  221 
  222                 /* Write a string to the LCD virtual area. */
  223                 case HLCD_WRITE:
  224                         error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_WRITE);
  225                         break;  
  226 
  227                 /* Read LCD virtual area. */
  228                 case HLCD_READ:
  229                         error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_READ);
  230                         break;
  231 
  232                 /* Write to the LCD visible area. */
  233                 case HLCD_REDRAW:
  234                         hd44780_ddram_redraw(sc, hd44780_io());
  235                         break;
  236 
  237                 /* Write raw instruction. */
  238                 case HLCD_WRITE_INST:
  239                         hd44780_ir_write(sc, hd44780_io()->dat);
  240                         break;
  241 
  242                 /* Write raw data. */
  243                 case HLCD_WRITE_DATA:
  244                         hd44780_dr_write(sc, hd44780_io()->dat);
  245                         break;
  246 
  247                 default:
  248                         error = EINVAL;
  249         }
  250 
  251         return error;
  252 }
  253 
  254 /*
  255  * Read/write particular area of the LCD screen.
  256  */
  257 int
  258 hd44780_ddram_io(sc, io, dir)
  259         struct hd44780_chip *sc;
  260         struct hd44780_io *io;
  261         u_char dir;
  262 {
  263         u_int8_t hi;
  264         u_int8_t addr;
  265 
  266         int error = 0;
  267         u_int8_t i = 0;
  268 
  269         if (io->dat < sc->sc_vrows) {
  270                 hi = HD_ROW1_ADDR + sc->sc_vrows;
  271                 addr = HD_ROW1_ADDR + io->dat;
  272                 for (; (addr < hi) && (i < io->len); addr++, i++) {
  273                         hd44780_ir_write(sc, cmd_ddramset(addr));
  274                         if (dir == HD_DDRAM_READ)
  275                                 io->buf[i] = hd44780_dr_read(sc);
  276                         else
  277                                 hd44780_dr_write(sc, io->buf[i]);
  278                 }
  279         }
  280         if (io->dat < 2 * sc->sc_vrows) {
  281                 hi = HD_ROW2_ADDR + sc->sc_vrows;
  282                 if (io->dat >= sc->sc_vrows)
  283                         addr = HD_ROW2_ADDR + io->dat - sc->sc_vrows;
  284                 else
  285                         addr = HD_ROW2_ADDR;
  286                 for (; (addr < hi) && (i < io->len); addr++, i++) {
  287                         hd44780_ir_write(sc, cmd_ddramset(addr));
  288                         if (dir == HD_DDRAM_READ)
  289                                 io->buf[i] = hd44780_dr_read(sc);
  290                         else
  291                                 hd44780_dr_write(sc, io->buf[i]);
  292                 }
  293                 if (i < io->len)
  294                         io->len = i;
  295         } else {
  296                 error = EINVAL;
  297         }
  298         return error;
  299 }
  300 
  301 /*
  302  * Write to the visible area of the display.
  303  */
  304 void
  305 hd44780_ddram_redraw(sc, io)
  306         struct hd44780_chip *sc;
  307         struct hd44780_io *io;
  308 {
  309         u_int8_t i;
  310 
  311         hd44780_ir_write(sc, cmd_clear());
  312         hd44780_ir_write(sc, cmd_rethome());
  313         for (i = 0; (i < io->len) && (i < sc->sc_rows); i++) {
  314                 hd44780_dr_write(sc, io->buf[i]);
  315         }
  316         hd44780_ir_write(sc, cmd_ddramset(HD_ROW2_ADDR));
  317         for (; (i < io->len); i++)
  318                 hd44780_dr_write(sc, io->buf[i]);
  319 }
  320 
  321 #if defined(HD44780_STD_WIDE)
  322 /*
  323  * Standard 8-bit version of 'sc_rwrite' (8-bit port, 8-bit access)
  324  */
  325 void
  326 hd44780_rwrite(iot, ioh, cmd)
  327         bus_space_tag_t iot;
  328         bus_space_handle_t ioh;
  329         u_int8_t cmd;
  330 {
  331         bus_space_write_1(iot, ioh, 0x00, cmd);
  332         delay(TIMEOUT_NORMAL);
  333 }
  334 
  335 /*
  336  * Standard 8-bit version of 'sc_rread' (8-bit port, 8-bit access)
  337  */
  338 u_int8_t
  339 hd44780_rread(iot, ioh)
  340         bus_space_tag_t iot;
  341         bus_space_handle_t ioh;
  342 {
  343         delay(TIMEOUT_NORMAL);
  344         return bus_space_read_1(iot, ioh, 0x00);
  345 }
  346 #elif defined(HD44780_STD_SHORT)
  347 /*
  348  * Standard 4-bit version of 'sc_irwrite' (4-bit port, 8-bit access)
  349  */
  350 void
  351 hd44780_irwrite(iot, ioh, cmd)
  352         bus_space_tag_t iot;
  353         bus_space_handle_t ioh;
  354         u_int8_t cmd;
  355 {
  356         /* first four instructions emitted in 8-bit mode */
  357         bus_space_write_1(iot, ioh, 0x00, hi_bits(cmd));
  358         delay(TIMEOUT_NORMAL);
  359 }
  360 
  361 /*
  362  * Standard 4-bit version of 'sc_rrwrite' (4-bit port, 8-bit access)
  363  */
  364 void
  365 hd44780_rwrite(iot, ioh, cmd)
  366         bus_space_tag_t iot;
  367         bus_space_handle_t ioh;
  368         u_int8_t cmd;
  369 {
  370         bus_space_write_1(iot, ioh, 0x00, hi_bits(cmd));
  371         bus_space_write_1(iot, ioh, 0x00, lo_bits(cmd));
  372         delay(TIMEOUT_NORMAL);
  373 }
  374 
  375 /*
  376  * Standard 4-bit version of 'sc_rread' (4-bit port, 8-bit access)
  377  */
  378 u_int8_t
  379 hd44780_rread(iot, ioh)
  380         bus_space_tag_t iot;
  381         bus_space_handle_t ioh;
  382 {
  383         u_int8_t rd;
  384         u_int8_t dat;
  385 
  386         delay(TIMEOUT_NORMAL);
  387         rd = bus_space_read_1(iot, ioh, 0x00);
  388         dat = (rd & 0x0f) << 4;
  389         rd = bus_space_read_1(iot, ioh, 0x00);
  390         return (dat | (rd & 0x0f));
  391 }
  392 #endif

Cache object: 6c420871b4d6be763bcd27edbd47efef


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.