3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
7 ATMega pinout (with LCD_SHIFTREG):
13 ATMega pinout (without LCD_SHIFTREG):
25 In both cases, HD44780 R/W needs to be connected to ground.
33 #define CLOCK_PORT PORTB
34 #define CLOCK_BIT 0x02
35 #define REGSEL_PORT PORTB
36 #define REGSEL_BIT 0x01
38 #define CLOCK_PORT PORTD
39 #define CLOCK_BIT 0x20
40 #define REGSEL_PORT PORTD
41 #define REGSEL_BIT 0x10
45 #define LCD_BUFSIZE 32
48 #define NOP() __asm__("nop")
51 static volatile uint8_t lcd_busy = 0;
52 static uint8_t lcd_buffer[LCD_BUFSIZE];
53 static volatile uint8_t lcd_buf_head = 0;
54 static volatile uint8_t lcd_buf_tail = 0;
57 static void lcd_clock(void)
60 CLOCK_PORT |= CLOCK_BIT;
62 CLOCK_PORT &= ~CLOCK_BIT;
65 static void lcd_set_data(uint8_t d)
71 PORTB = (PORTB&~0x04)|((d&1)<<2);
78 PORTD = (PORTD&0x3F) | (d<<6);
79 PORTB = (PORTB&0xC0) | (d>>2);
83 static void lcd_command(uint8_t c)
85 REGSEL_PORT &= ~REGSEL_BIT;
90 static void lcd_delay(uint16_t us)
94 timer_start_us(0, us);
101 static void lcd_wait(void)
106 static void lcd_buffer_push(uint8_t byte)
108 while((lcd_buf_head+1)%sizeof(lcd_buffer)==lcd_buf_tail) ;
109 lcd_buffer[lcd_buf_head] = byte;
110 lcd_buf_head = (lcd_buf_head+1)%sizeof(lcd_buffer);
113 static uint8_t lcd_buffer_pop(void)
115 uint8_t byte = lcd_buffer[lcd_buf_tail];
116 lcd_buf_tail = (lcd_buf_tail+1)%sizeof(lcd_buffer);
120 static void lcd_timer(void)
124 if(lcd_buf_head!=lcd_buf_tail)
126 uint8_t byte = lcd_buffer_pop();
129 REGSEL_PORT |= REGSEL_BIT;
130 byte = lcd_buffer_pop();
133 REGSEL_PORT &= ~REGSEL_BIT;
135 REGSEL_PORT |= REGSEL_BIT;
148 TIMER_SET_CALLBACK(0, lcd_timer)
179 void lcd_gotoxy(uint8_t x, uint8_t y)
188 lcd_buffer_push(a|0x80);
197 void lcd_write(uint8_t c)
203 lcd_buffer_push(0xFF);
209 REGSEL_PORT |= REGSEL_BIT;