X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=firmware%2Flcd.c;fp=firmware%2Flcd.c;h=0000000000000000000000000000000000000000;hb=9c37d18b9c70fdb70dfec453398c4649e9e57586;hp=f4e0387aeccdb5f148c0bbc7b89be943b9d29f17;hpb=49b6b6ad84ec47b4f9eb9ef131975cc5b72372a2;p=model-railway-devices.git diff --git a/firmware/lcd.c b/firmware/lcd.c deleted file mode 100644 index f4e0387..0000000 --- a/firmware/lcd.c +++ /dev/null @@ -1,208 +0,0 @@ -/* -ATMega pinout (with LCD_SHIFTREG): -B0 - HD44780 RS -B1 - HD44780 clock -B2 - shift reg data -B3 - shift reg clock - -ATMega pinout (without LCD_SHIFTREG): -D4 - HD44780 RS -D5 - HD44780 clock -D6 - HD44780 data 0 -D7 - HD44780 data 1 -B0 - HD44780 data 2 -B1 - HD44780 data 3 -B2 - HD44780 data 4 -B3 - HD44780 data 5 -B4 - HD44780 data 6 -B5 - HD44780 data 7 - -In both cases, HD44780 R/W needs to be connected to ground. -*/ -#include -#include "delay.h" -#include "lcd.h" -#include "timer.h" - -#ifdef LCD_SHIFTREG -#define CLOCK_PORT PORTB -#define CLOCK_BIT 0x02 -#define REGSEL_PORT PORTB -#define REGSEL_BIT 0x01 -#else -#define CLOCK_PORT PORTD -#define CLOCK_BIT 0x20 -#define REGSEL_PORT PORTD -#define REGSEL_BIT 0x10 -#endif - -#ifndef LCD_BUFSIZE -#define LCD_BUFSIZE 32 -#endif - -#define NOP() __asm__("nop") - -#ifdef LCD_ASYNC -static volatile uint8_t lcd_busy = 0; -static uint8_t lcd_buffer[LCD_BUFSIZE]; -static volatile uint8_t lcd_buf_head = 0; -static volatile uint8_t lcd_buf_tail = 0; -#endif - -static void lcd_clock(void) -{ - delay_us(1); - CLOCK_PORT |= CLOCK_BIT; - delay_us(1); - CLOCK_PORT &= ~CLOCK_BIT; -} - -static void lcd_set_data(uint8_t d) -{ -#ifdef LCD_SHIFTREG - uint8_t i; - for(i=0; i<8; ++i) - { - PORTB = (PORTB&~0x04)|((d&1)<<2); - PORTB |= 0x08; - NOP(); - PORTB &= ~0x08; - d >>= 1; - } -#else - PORTD = (PORTD&0x3F) | (d<<6); - PORTB = (PORTB&0xC0) | (d>>2); -#endif -} - -static void lcd_command(uint8_t c) -{ - REGSEL_PORT &= ~REGSEL_BIT; - lcd_set_data(c); - lcd_clock(); -} - -static void lcd_delay(uint16_t us) -{ -#ifdef LCD_ASYNC - lcd_busy = 1; - timer_start_us(0, us); -#else - delay_us(us); -#endif -} - -#ifdef LCD_ASYNC -static void lcd_wait(void) -{ - while(lcd_busy) ; -} - -static void lcd_buffer_push(uint8_t byte) -{ - while((lcd_buf_head+1)%sizeof(lcd_buffer)==lcd_buf_tail) ; - lcd_buffer[lcd_buf_head] = byte; - lcd_buf_head = (lcd_buf_head+1)%sizeof(lcd_buffer); -} - -static uint8_t lcd_buffer_pop(void) -{ - uint8_t byte = lcd_buffer[lcd_buf_tail]; - lcd_buf_tail = (lcd_buf_tail+1)%sizeof(lcd_buffer); - return byte; -} - -static void lcd_timer(void) -{ - if(lcd_busy) - { - if(lcd_buf_head!=lcd_buf_tail) - { - uint8_t byte = lcd_buffer_pop(); - if(byte==0xFF) - { - REGSEL_PORT |= REGSEL_BIT; - byte = lcd_buffer_pop(); - } - else if(byte>=0x80) - REGSEL_PORT &= ~REGSEL_BIT; - else - REGSEL_PORT |= REGSEL_BIT; - lcd_set_data(byte); - lcd_clock(); - lcd_delay(50); - } - else - { - lcd_busy = 0; - timer_stop(0); - } - } -} - -TIMER_SET_CALLBACK(0, lcd_timer) -#endif - -void lcd_init(void) -{ -#ifdef LCD_SHIFTREG - DDRB |= 0x0F; - PORTB &= ~0x0F; -#else - DDRD |= 0xF0; - PORTD &= ~0xF0; - DDRB |= 0x3F; - PORTB &= ~0x3F; -#endif - - delay_ms(20); - lcd_command(0x38); - delay_us(50); - lcd_command(0x0C); - delay_us(50); -} - -void lcd_clear(void) -{ -#ifdef LCD_ASYNC - lcd_wait(); -#endif - lcd_command(0x01); - lcd_delay(1700); -} - -void lcd_gotoxy(uint8_t x, uint8_t y) -{ - uint8_t a = x+10*y; - if(y&1) - a += 54; - -#ifdef LCD_ASYNC - if(lcd_busy) - { - lcd_buffer_push(a|0x80); - return; - } -#endif - - lcd_command(a|0x80); - lcd_delay(50); -} - -void lcd_write(uint8_t c) -{ -#ifdef LCD_ASYNC - if(lcd_busy) - { - if(c>=0x80) - lcd_buffer_push(0xFF); - lcd_buffer_push(c); - return; - } -#endif - - REGSEL_PORT |= REGSEL_BIT; - lcd_set_data(c); - lcd_clock(); - lcd_delay(50); -}