4 Copyright 2011 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
23 * This "Part" simulates the business end of a HD44780 LCD display
24 * It supports from 8x1 to 20x4 or even 40x4 (not sure that exists)
26 * It works both in 4 bits and 8 bits mode and supports a "quicky" method
27 * of driving that is commonly used on AVR, namely
28 * (msb) RW:E:RS:D7:D6:D5:D4 (lsb)
30 * + As usual, the "RW" pin is optional if you are willing to wait for the
31 * specific number of cycles as per the datasheet (37uS between operations)
32 * + If you decide to use the RW pin, the "busy" flag is supported and will
33 * be automaticly cleared on the second read, to exercisee the code a bit.
34 * + Cursor is supported, but now "display shift"
35 * + The Character RAM is supported, but is not currently drawn.
37 * To interface this part, you can use the "INPUT" IRQs and hook them to the
38 * simavr instance, if you use the RW pins or read back frim the display, you
39 * can hook the data pins /back/ to the AVR too.
41 * The "part" also provides various IRQs that are there to be placed in a VCD file
42 * to show what is sent, and some of the internal status.
44 * This part has been tested with two different implementation of an AVR driver
45 * for the hd44780. The one shipped in this directory is straight out of the
46 * avr-libc example code.
54 IRQ_HD44780_ALL = 0, // Only if (msb) RW:E:RS:D7:D6:D5:D4 (lsb) configured
59 IRQ_HD44780_D0,IRQ_HD44780_D1,IRQ_HD44780_D2,IRQ_HD44780_D3,
60 IRQ_HD44780_D4,IRQ_HD44780_D5,IRQ_HD44780_D6,IRQ_HD44780_D7,
61 IRQ_HD44780_INPUT_COUNT,
63 IRQ_HD44780_BUSY = IRQ_HD44780_INPUT_COUNT, // for VCD traces sake...
71 HD44780_FLAG_F = 0, // 1: 5x10 Font, 0: 5x7 Font
72 HD44780_FLAG_N, // 1: 2/4-lines Display, 0: 1-line Display,
73 HD44780_FLAG_D_L, // 1: 4-Bit Interface, 0: 8-Bit Interface
74 HD44780_FLAG_R_L, // 1: Shift right, 0: shift left
75 HD44780_FLAG_S_C, // 1: Display shift, 0: Cursor move
76 HD44780_FLAG_B, // 1: Cursor Blink
77 HD44780_FLAG_C, // 1: Cursor on
78 HD44780_FLAG_D, // 1: Set Entire Display memory (for clear)
79 HD44780_FLAG_S, // 1: Follow display shift
80 HD44780_FLAG_I_D, // 1: Increment, 0: Decrement
83 * Internal flags, not HD44780
85 HD44780_FLAG_LOWNIBBLE, // 1: 4 bits mode, write/read low nibble
86 HD44780_FLAG_BUSY, // 1: Busy between instruction, 0: ready
87 HD44780_FLAG_REENTRANT, // 1: Do not update pins
89 HD44780_FLAG_DIRTY, // 1: needs redisplay...
90 HD44780_FLAG_CRAM_DIRTY, // 1: Character memory has changed
94 typedef struct hd44780_t
98 int w, h; // width and height of the LCD
100 uint16_t cursor; // offset in vram
101 uint8_t vram[80 + 64];
103 uint16_t pinstate; // 'actual' LCd data pins (IRQ bit field)
104 // uint16_t oldstate; /// previous pins
105 uint8_t datapins; // composite of 4 high bits, or 8 bits
108 uint16_t flags; // LCD flags ( HD44780_FLAG_*)
114 struct hd44780_t * b,
119 struct hd44780_t *b);
123 hd44780_t *b, uint16_t bit, int val)
125 int old = b->flags & (1 << bit);
126 b->flags = (b->flags & ~(1 << bit)) | (val ? (1 << bit) : 0);
132 hd44780_t *b, uint16_t bit)
134 return (b->flags & (1 << bit)) != 0;