11
11
* The LCD controller is used in 4-bit mode with a full bi-directional
12
12
* interface (i.e. R/~W is connected) so the busy flag can be read.
14
* $Id: hd44780.c,v 1.3 2006/10/08 21:47:36 joerg_wunsch Exp $
14
* $Id: hd44780.c,v 1.3.2.1 2009/06/25 20:21:16 joerg_wunsch Exp $
17
17
#include "defines.h"
25
25
#include "hd44780.h"
27
27
#define GLUE(a, b) a##b
28
#define PORT(x) GLUE(PORT, x)
29
#define PIN(x) GLUE(PIN, x)
30
#define DDR(x) GLUE(DDR, x)
32
#define HD44780_PORTOUT PORT(HD44780_PORT)
33
#define HD44780_PORTIN PIN(HD44780_PORT)
34
#define HD44780_DDR DDR(HD44780_PORT)
36
#define HD44780_DATABITS \
37
(_BV(HD44780_D4)|_BV(HD44780_D5)|_BV(HD44780_D6)|_BV(HD44780_D7))
29
/* single-bit macros, used for control bits */
30
#define SET_(what, p, m) GLUE(what, p) |= (1 << (m))
31
#define CLR_(what, p, m) GLUE(what, p) &= ~(1 << (m))
32
#define GET_(/* PIN, */ p, m) GLUE(PIN, p) & (1 << (m))
33
#define SET(what, x) SET_(what, x)
34
#define CLR(what, x) CLR_(what, x)
35
#define GET(/* PIN, */ x) GET_(x)
37
/* nibble macros, used for data path */
38
#define ASSIGN_(what, p, m, v) GLUE(what, p) = (GLUE(what, p) & \
39
~((1 << (m)) | (1 << ((m) + 1)) | \
40
(1 << ((m) + 2)) | (1 << ((m) + 3)))) | \
42
#define READ_(what, p, m) (GLUE(what, p) & ((1 << (m)) | (1 << ((m) + 1)) | \
43
(1 << ((m) + 2)) | (1 << ((m) + 3)))) >> (m)
44
#define ASSIGN(what, x, v) ASSIGN_(what, x, v)
45
#define READ(what, x) READ_(what, x)
39
47
#define HD44780_BUSYFLAG 0x80
78
86
# endif /* F_CPU > 1000000UL */
81
x = HD44780_PORTIN & HD44780_DATABITS;
89
x = READ(PIN, HD44780_D4);
84
HD44780_PORTOUT &= ~_BV(HD44780_E);
93
101
hd44780_outnibble(uint8_t n, uint8_t rs)
97
HD44780_PORTOUT &= ~_BV(HD44780_RW);
103
CLR(PORT, HD44780_RW);
99
HD44780_PORTOUT |= _BV(HD44780_RS);
105
SET(PORT, HD44780_RS);
101
HD44780_PORTOUT &= ~_BV(HD44780_RS);
102
x = (HD44780_PORTOUT & ~HD44780_DATABITS) | ((n << HD44780_D4) & HD44780_DATABITS);
107
CLR(PORT, HD44780_RS);
108
ASSIGN(PORT, HD44780_D4, n);
104
109
(void)hd44780_pulse_e(false);
126
HD44780_PORTOUT |= _BV(HD44780_RW);
127
HD44780_DDR &= ~HD44780_DATABITS;
131
SET(PORT, HD44780_RW);
132
ASSIGN(DDR, HD44780_D4, 0x00);
129
HD44780_PORTOUT |= _BV(HD44780_RS);
134
SET(PORT, HD44780_RS);
131
HD44780_PORTOUT &= ~_BV(HD44780_RS);
136
CLR(PORT, HD44780_RS);
132
137
x = hd44780_pulse_e(true);
133
HD44780_DDR |= HD44780_DATABITS;
134
HD44780_PORTOUT &= ~_BV(HD44780_RW);
138
ASSIGN(DDR, HD44780_D4, 0x0F);
139
CLR(PORT, HD44780_RW);
136
return (x & HD44780_DATABITS) >> HD44780_D4;
171
183
hd44780_init(void)
174
HD44780_DDR = _BV(HD44780_RS) | _BV(HD44780_RW) | _BV(HD44780_E)
185
SET(DDR, HD44780_RS);
186
SET(DDR, HD44780_RW);
188
ASSIGN(DDR, HD44780_D4, 0x0F);
177
190
_delay_ms(15); /* 40 ms needed for Vcc = 2.7 V */
178
191
hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
180
193
hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
182
195
hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
184
198
hd44780_outnibble(HD44780_FNSET(0, 1, 0) >> 4, 0);
185
hd44780_wait_ready();
199
hd44780_wait_ready(false);
186
200
hd44780_outcmd(HD44780_FNSET(0, 1, 0));
187
hd44780_wait_ready();
201
hd44780_wait_ready(false);
188
202
hd44780_outcmd(HD44780_DISPCTL(0, 0, 0));
189
hd44780_wait_ready();
203
hd44780_wait_ready(false);
207
* Prepare the LCD controller pins for powerdown.
210
hd44780_powerdown(void)
212
ASSIGN(PORT, HD44780_D4, 0);
213
CLR(PORT, HD44780_RS);
214
CLR(PORT, HD44780_RW);
215
CLR(PORT, HD44780_E);