# HG changeset patch # User John Tsiombikas # Date 1383291620 -7200 # Node ID 050c04723d3761233f3db29392e2e2ea910f24d4 initial commit diff -r 000000000000 -r 050c04723d37 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Nov 01 09:40:20 2013 +0200 @@ -0,0 +1,6 @@ +\.swp$ +\.o$ +\.hex$ +\.eep$ +\.map$ +^pwcdecode$ diff -r 000000000000 -r 050c04723d37 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Fri Nov 01 09:40:20 2013 +0200 @@ -0,0 +1,34 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +bin = pwcdecode +hex = $(bin).hex +eep = $(bin).eep + +mcu_gcc = atmega168 +mcu_dude = m168 + +CC = avr-gcc +OBJCOPY = avr-objcopy + +CFLAGS = -O2 -pedantic -Wall -mmcu=$(mcu_gcc) +LDFLAGS = -Wl,-Map,$(bin).map -mmcu=$(mcu_gcc) -Wl,-u,vfprintf -lprintf_flt -lm + +.PHONY: all +all: $(hex) $(eep) + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +$(hex): $(bin) + $(OBJCOPY) -j .text -j .data -O ihex -R .eeprom $< $@ + +$(eep): $(bin) + $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ + +.PHONY: program +program: $(hex) + avrdude -c usbtiny -p $(mcu_dude) -e -U flash:w:$(hex) + +.PHONY: clean +clean: + rm -f $(bin) $(obj) $(hex) $(eep) $(bin).map diff -r 000000000000 -r 050c04723d37 pwcdecode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pwcdecode.c Fri Nov 01 09:40:20 2013 +0200 @@ -0,0 +1,272 @@ +#define F_CLK 1000000 +#define F_CPU 1000000 + +#include +#include +#include +#include + +/* hardware setup + * - PORT D: data bits + * - PORT C + * bit 3: RS + * bit 4: R/W + * bit 5: E + */ +#define LCD_BUS_WIDTH 8 + +#define BIT_RS 3 +#define BIT_RW 4 +#define BIT_E 5 + +#define CMD_CLEAR 1 +#define CMD_RET (1 << 1) +#define CMD_ENTRY_MODE (1 << 2) +#define CMD_ONOFF (1 << 3) +#define CMD_SHIFT (1 << 4) +#define CMD_FUNC (1 << 5) +#define CMD_CGRAM_ADDR (1 << 6) +#define CMD_DDRAM_ADDR (1 << 7) + +#define FUNC_BUS_4BIT 0 +#define FUNC_BUS_8BIT (1 << 4) +#define FUNC_LINES_1 0 +#define FUNC_LINES_2 (1 << 3) +#define FUNC_FONT_5x8 0 +#define FUNC_FONT_5x11 (1 << 2) + +#define ONOFF_DISP (1 << 2) +#define ONOFF_CURSOR (1 << 1) +#define ONOFF_CURSOR_POS 1 + +void lcd_init(void); +void lcd_clear(void); +void lcd_set_cursor_addr(unsigned int addr); +void lcd_putchar(char c); +void lcd_putstr(const char *str); +int lcd_stream_write(char c, FILE *fp); +void lcd_wait_busy(void); +static void enable(void); +static void set_bit(int bit); +static void clear_bit(int bit); +void delay(int x); + +#define NSDELAY() asm volatile ("nop") +#define DEBUG(i) (PORTB = (1 << (i))) + +FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE); + +unsigned int pulse_time; + +int main(void) +{ + stdout = stderr = &stream_lcd; + + DDRB = 0; /* set port B as input (bit 0 is used to measure pulse width) */ + PORTB = 0; /* disable pullups */ + + DDRD = 0xff; + DDRC = 0xfe; + PORTC = 0; /* disable pullups */ + + lcd_init(); + lcd_clear(); + + printf("initializing..."); + + TCCR1B |= (1 << ICES1); /* set first capture to occur on a rising edge */ + TCCR1B = (TCCR1B & 0xf8) | 1; /* no prescaling */ + TIMSK1 |= (1 << ICIE1); /* enable timer1 input capture interrupt */ + sei(); + + for(;;) { + static int blink = 0; + + PORTB = blink ? 1 : 0; + blink = (blink + 1) & 1; + + lcd_set_cursor_addr(0); + printf("pulse time: %u us ", pulse_time); + lcd_set_cursor_addr(64); + printf("pos: %u%% ", (pulse_time - 1000) / 10); + _delay_ms(100); + } + return 0; +} + +ISR(TIMER1_CAPT_vect) +{ + static int rising; + + rising = !rising; + if(rising) { + /* rising edge: reset the timer */ + TCNT1 = 0; + /* and set a falling edge trigger */ + TCCR1B &= ~(1 << ICES1); + } else { + /* falling edge: calculate the time since the last rise */ + pulse_time = ICR1; + /* and set a rising edge trigger */ + TCCR1B |= 1 << ICES1; + } +} + +void lcd_write_byte(unsigned char byte) +{ +#if LCD_BUS_WIDTH == 8 + DDRD = 0xff; + PORTD = byte; +#else + DDRD = (DDRD & 0xf0) | 0xf; + + PORTD = (PORTD & 0xf0) | ((byte >> 4) & 0xf); + PORTD = (PORTD & 0xf0) | (byte & 0xf); +#endif +} + +unsigned char lcd_read_byte(void) +{ +#if LCD_BUS_WIDTH == 8 + DDRD = 0; + PORTD = 0; /* disable pull-ups */ + + return PIND; +#else + unsigned char byte; + + DDRD = DDRD & 0xf0; + PORTD &= 0xf0; /* disable pull-ups */ + + byte = (PIND & 0xf) << 4; + return byte | (PIND & 0xf); +#endif +} + +void lcd_init(void) +{ + /* make sure the display has time to boot up */ + _delay_ms(20); + + clear_bit(BIT_RW); + + clear_bit(BIT_E); + clear_bit(BIT_RS); +#if LCD_BUS_WIDTH == 8 + lcd_write_byte(CMD_FUNC | FUNC_BUS_8BIT | FUNC_LINES_2 | FUNC_FONT_5x8); +#else + lcd_write_byte(CMD_FUNC | FUNC_BUS_4BIT | FUNC_LINES_2 | FUNC_FONT_5x8); +#endif + enable(); + lcd_wait_busy(); + + clear_bit(BIT_RS); + lcd_write_byte(CMD_ONOFF | ONOFF_DISP); + enable(); + lcd_wait_busy(); + + clear_bit(BIT_RS); + lcd_write_byte(CMD_ENTRY_MODE | (1 << 1)); + enable(); + lcd_wait_busy(); +} + +void lcd_clear(void) +{ + clear_bit(BIT_RW); + + clear_bit(BIT_E); + clear_bit(BIT_RS); + lcd_write_byte(CMD_CLEAR); + enable(); + lcd_wait_busy(); +} + +void lcd_set_cursor_addr(unsigned int addr) +{ + clear_bit(BIT_RW); + + clear_bit(BIT_E); + clear_bit(BIT_RS); + lcd_write_byte(CMD_DDRAM_ADDR | addr); + enable(); + lcd_wait_busy(); +} + +void lcd_putchar(char c) +{ + clear_bit(BIT_RW); + + set_bit(BIT_RS); + lcd_write_byte(c); + enable(); + lcd_wait_busy(); +} + +void lcd_putstr(const char *str) +{ + while(*str) { + lcd_putchar(*str++); + } +} + +int lcd_stream_write(char c, FILE *fp) +{ + /* TODO terminal shit handling */ + lcd_putchar(c); + return 0; +} + +void lcd_wait_busy(void) +{ + unsigned char data; + + do { + NSDELAY(); + clear_bit(BIT_E); + clear_bit(BIT_RS); + set_bit(BIT_RW); + /*PIND = 0xff;*/ + + NSDELAY(); + set_bit(BIT_E); + NSDELAY(); + data = lcd_read_byte(); + clear_bit(BIT_E); + clear_bit(BIT_RW); + + } while(data & (1 << 7)); +} + +static void enable(void) +{ + NSDELAY(); + set_bit(BIT_E); + NSDELAY(); + clear_bit(BIT_E); + NSDELAY(); +} + +static void set_bit(int bit) +{ + PORTC |= 1 << bit; +} + +static void clear_bit(int bit) +{ + PORTC &= ~(1 << bit); +} + + +void delay(int x) +{ + int i, j; + + while(x-- > 0) { + for(i=0; i<90; i++) { + for(j=0; j<6; j++) { + asm volatile("nop"); + } + } + } +}