#include "lcd.h" #include #include #define B_SRCLK PB0 #define B_LCDE PB3 #define B_SRD_LCDRS PB4 static void lcd_pin(bool value) { /* cheat, put the clock in front. * result: * clk, d0 | clk, d1 | clk... d7 | clk, rs. * ^- first clk ignored ^- last clk from setting R/S */ PORTB |= (1 << B_SRCLK); PORTB &= ~(1 << B_SRCLK); if (value) PORTB |= (1 << B_SRD_LCDRS); else PORTB &= ~(1 << B_SRD_LCDRS); } void lcd_command(uint8_t cmd, bool isdata) { uint8_t i; for (i = 1; i; i <<= 2) lcd_pin(cmd & i); for (i = 1 << 7; i; i >>= 2) lcd_pin(cmd & i); lcd_pin(isdata); __asm__ ("nop\n"); PORTB |= (1 << B_LCDE); __asm__ ("nop\n"); PORTB &= ~(1 << B_LCDE); __asm__ ("nop\n"); if (!isdata) _delay_us(50); } void lcd_puts(const char * PROGMEM ptr, uint8_t cnt) { while (cnt--) { uint8_t ch = __LPM(ptr++); lcd_put(ch); } } const char PROGMEM boot[] = "boot"; void lcd_init(void) { PORTB &= ~((1 << B_SRCLK) | (1 << B_LCDE) | (1 << B_SRD_LCDRS)); DDRB |= (1 << B_SRCLK) | (1 << B_LCDE) | (1 << B_SRD_LCDRS); _delay_ms(15); lcd_command(0x38, 0); lcd_command(0x0c, 0); lcd_command(0x06, 0); lcd_command(0x02, 0); _delay_ms(2); lcd_line1(); lcd_puts(boot, sizeof(boot) - 1); }