Skip to content

Commit

Permalink
Fix cursor handling in segmented DDRAM of HD44780
Browse files Browse the repository at this point in the history
HD44780 has only 80 bytes of DDRAM, which consists of two 40 bytes
long segments. The segment starting at address 0x00 contains the
data for the first line of the display, while the segment starting
at address 0x40 contains the data for the second line of the
display. This means that there are invalid ranges in the 7-bit
address space of the DDRAM (0x00+40 .. 0x3f and 0x40+40 .. 0x7f).
The cursor (address counter) of the HD44780 automatically "jumps
over" these regions whenever auto-incremented/decremented. This
commit implements this behaviour.

Moreover, this commit also fixes the 4-lines mode. When in a
4-lines setup, the first 20 bytes of the first and the second
memory segments control what is displayed in the first two lines,
as usual. However, the second 20 bytes of the memory segments
contain the data for the third and fourth lines of the display.
This means that the starting addresses of lines 3 & 4 are 0x00+20
and 0x40+20.
  • Loading branch information
akosthekiss committed Oct 8, 2020
1 parent cb6fcbe commit f97e7f0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
41 changes: 31 additions & 10 deletions examples/parts/hd44780.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ hd44780_print(
hd44780_t *b)
{
printf("/******************\\\n");
const uint8_t offset[] = { 0, 0x40, 0x20, 0x60 };
const uint8_t offset[] = { 0x00, 0x40, 0x00 + 20, 0x40 + 20 };
for (int i = 0; i < b->h; i++) {
printf("| ");
fwrite(b->vram + offset[i], 1, b->w, stdout);
Expand Down Expand Up @@ -83,16 +83,33 @@ static void
hd44780_kick_cursor(
hd44780_t *b)
{
if (hd44780_get_flag(b, HD44780_FLAG_I_D)) {
if (b->cursor < 0x80-1)
if (hd44780_get_flag(b, HD44780_FLAG_I_D)) { // incrementing
if (b->cursor < 0x80) { // cursor in DDRAM
b->cursor++;
else if (b->cursor < 0x80+0x40-1)
b->cursor++;
} else {
if (b->cursor < 0x80 && b->cursor)
b->cursor--;
else if (b->cursor > 0x80)
b->cursor--;
if (b->cursor >= 0x00 + 40 && b->cursor < 0x40) // jump from end of first memory segment to the start of the second segment
b->cursor = 0x40;
else if (b->cursor >= 0x40 + 40) // wrap around from the end of the second memory segment to the start of the first segment
b->cursor = 0x00;
} else { // cursor in CGRAM
if (b->cursor == 0x80 + 0x3f) // wrap around in CGRAM
b->cursor = 0x80;
else
b->cursor++;
}
} else { // decrementing
if (b->cursor < 0x80) { // cursor in DDRAM
if (b->cursor == 0x40) // fall back from the start of the second memory segment to the end of the first segment
b->cursor = 0x00 + 39;
else if (b->cursor == 0x00) // wrap around from the start of the first memory segment to the end of the second segment
b->cursor = 0x40 + 39;
else
b->cursor--;
} else { // cursor in CGRAM
if (b->cursor == 0x80) // wrap around in CGRAM
b->cursor = 0x80 + 0x3f;
else
b->cursor--;
}
hd44780_set_flag(b, HD44780_FLAG_DIRTY, 1);
avr_raise_irq(b->irq + IRQ_HD44780_ADDR, b->cursor);
}
Expand Down Expand Up @@ -136,6 +153,10 @@ hd44780_write_command(
// Set DDRAM address
case 7: // 1 ADD ADD ADD ADD ADD ADD ADD
b->cursor = b->datapins & 0x7f;
if (b->cursor >= 0x00 + 40 && b->cursor < 0x40) // illegal address after the first memory segment -> set cursor to start of second segment
b->cursor = 0x40;
else if (b->cursor >= 0x40 + 40) // illegal address after the second memory segment -> set cursor to start of first segment
b->cursor = 0x00;
break;
// Set CGRAM address
case 6: // 0 1 ADD ADD ADD ADD ADD ADD ADD
Expand Down
2 changes: 1 addition & 1 deletion examples/parts/hd44780_glut.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ hd44780_gl_draw(
glEnd();

glColor3f(1.0f, 1.0f, 1.0f);
const uint8_t offset[] = { 0, 0x40, 0x20, 0x60 };
const uint8_t offset[] = { 0x00, 0x40, 0x00 + 20, 0x40 + 20 };
for (int v = 0 ; v < b->h; v++) {
glPushMatrix();
for (int i = 0; i < b->w; i++) {
Expand Down

0 comments on commit f97e7f0

Please sign in to comment.