pwcdecode
changeset 0:050c04723d37
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 01 Nov 2013 09:40:20 +0200 |
parents | |
children | 4ea5d2920f89 |
files | .hgignore Makefile pwcdecode.c |
diffstat | 3 files changed, 312 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Fri Nov 01 09:40:20 2013 +0200 1.3 @@ -0,0 +1,6 @@ 1.4 +\.swp$ 1.5 +\.o$ 1.6 +\.hex$ 1.7 +\.eep$ 1.8 +\.map$ 1.9 +^pwcdecode$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Fri Nov 01 09:40:20 2013 +0200 2.3 @@ -0,0 +1,34 @@ 2.4 +src = $(wildcard *.c) 2.5 +obj = $(src:.c=.o) 2.6 +bin = pwcdecode 2.7 +hex = $(bin).hex 2.8 +eep = $(bin).eep 2.9 + 2.10 +mcu_gcc = atmega168 2.11 +mcu_dude = m168 2.12 + 2.13 +CC = avr-gcc 2.14 +OBJCOPY = avr-objcopy 2.15 + 2.16 +CFLAGS = -O2 -pedantic -Wall -mmcu=$(mcu_gcc) 2.17 +LDFLAGS = -Wl,-Map,$(bin).map -mmcu=$(mcu_gcc) -Wl,-u,vfprintf -lprintf_flt -lm 2.18 + 2.19 +.PHONY: all 2.20 +all: $(hex) $(eep) 2.21 + 2.22 +$(bin): $(obj) 2.23 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.24 + 2.25 +$(hex): $(bin) 2.26 + $(OBJCOPY) -j .text -j .data -O ihex -R .eeprom $< $@ 2.27 + 2.28 +$(eep): $(bin) 2.29 + $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ 2.30 + 2.31 +.PHONY: program 2.32 +program: $(hex) 2.33 + avrdude -c usbtiny -p $(mcu_dude) -e -U flash:w:$(hex) 2.34 + 2.35 +.PHONY: clean 2.36 +clean: 2.37 + rm -f $(bin) $(obj) $(hex) $(eep) $(bin).map
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/pwcdecode.c Fri Nov 01 09:40:20 2013 +0200 3.3 @@ -0,0 +1,272 @@ 3.4 +#define F_CLK 1000000 3.5 +#define F_CPU 1000000 3.6 + 3.7 +#include <stdio.h> 3.8 +#include <avr/io.h> 3.9 +#include <avr/interrupt.h> 3.10 +#include <util/delay.h> 3.11 + 3.12 +/* hardware setup 3.13 + * - PORT D: data bits 3.14 + * - PORT C 3.15 + * bit 3: RS 3.16 + * bit 4: R/W 3.17 + * bit 5: E 3.18 + */ 3.19 +#define LCD_BUS_WIDTH 8 3.20 + 3.21 +#define BIT_RS 3 3.22 +#define BIT_RW 4 3.23 +#define BIT_E 5 3.24 + 3.25 +#define CMD_CLEAR 1 3.26 +#define CMD_RET (1 << 1) 3.27 +#define CMD_ENTRY_MODE (1 << 2) 3.28 +#define CMD_ONOFF (1 << 3) 3.29 +#define CMD_SHIFT (1 << 4) 3.30 +#define CMD_FUNC (1 << 5) 3.31 +#define CMD_CGRAM_ADDR (1 << 6) 3.32 +#define CMD_DDRAM_ADDR (1 << 7) 3.33 + 3.34 +#define FUNC_BUS_4BIT 0 3.35 +#define FUNC_BUS_8BIT (1 << 4) 3.36 +#define FUNC_LINES_1 0 3.37 +#define FUNC_LINES_2 (1 << 3) 3.38 +#define FUNC_FONT_5x8 0 3.39 +#define FUNC_FONT_5x11 (1 << 2) 3.40 + 3.41 +#define ONOFF_DISP (1 << 2) 3.42 +#define ONOFF_CURSOR (1 << 1) 3.43 +#define ONOFF_CURSOR_POS 1 3.44 + 3.45 +void lcd_init(void); 3.46 +void lcd_clear(void); 3.47 +void lcd_set_cursor_addr(unsigned int addr); 3.48 +void lcd_putchar(char c); 3.49 +void lcd_putstr(const char *str); 3.50 +int lcd_stream_write(char c, FILE *fp); 3.51 +void lcd_wait_busy(void); 3.52 +static void enable(void); 3.53 +static void set_bit(int bit); 3.54 +static void clear_bit(int bit); 3.55 +void delay(int x); 3.56 + 3.57 +#define NSDELAY() asm volatile ("nop") 3.58 +#define DEBUG(i) (PORTB = (1 << (i))) 3.59 + 3.60 +FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE); 3.61 + 3.62 +unsigned int pulse_time; 3.63 + 3.64 +int main(void) 3.65 +{ 3.66 + stdout = stderr = &stream_lcd; 3.67 + 3.68 + DDRB = 0; /* set port B as input (bit 0 is used to measure pulse width) */ 3.69 + PORTB = 0; /* disable pullups */ 3.70 + 3.71 + DDRD = 0xff; 3.72 + DDRC = 0xfe; 3.73 + PORTC = 0; /* disable pullups */ 3.74 + 3.75 + lcd_init(); 3.76 + lcd_clear(); 3.77 + 3.78 + printf("initializing..."); 3.79 + 3.80 + TCCR1B |= (1 << ICES1); /* set first capture to occur on a rising edge */ 3.81 + TCCR1B = (TCCR1B & 0xf8) | 1; /* no prescaling */ 3.82 + TIMSK1 |= (1 << ICIE1); /* enable timer1 input capture interrupt */ 3.83 + sei(); 3.84 + 3.85 + for(;;) { 3.86 + static int blink = 0; 3.87 + 3.88 + PORTB = blink ? 1 : 0; 3.89 + blink = (blink + 1) & 1; 3.90 + 3.91 + lcd_set_cursor_addr(0); 3.92 + printf("pulse time: %u us ", pulse_time); 3.93 + lcd_set_cursor_addr(64); 3.94 + printf("pos: %u%% ", (pulse_time - 1000) / 10); 3.95 + _delay_ms(100); 3.96 + } 3.97 + return 0; 3.98 +} 3.99 + 3.100 +ISR(TIMER1_CAPT_vect) 3.101 +{ 3.102 + static int rising; 3.103 + 3.104 + rising = !rising; 3.105 + if(rising) { 3.106 + /* rising edge: reset the timer */ 3.107 + TCNT1 = 0; 3.108 + /* and set a falling edge trigger */ 3.109 + TCCR1B &= ~(1 << ICES1); 3.110 + } else { 3.111 + /* falling edge: calculate the time since the last rise */ 3.112 + pulse_time = ICR1; 3.113 + /* and set a rising edge trigger */ 3.114 + TCCR1B |= 1 << ICES1; 3.115 + } 3.116 +} 3.117 + 3.118 +void lcd_write_byte(unsigned char byte) 3.119 +{ 3.120 +#if LCD_BUS_WIDTH == 8 3.121 + DDRD = 0xff; 3.122 + PORTD = byte; 3.123 +#else 3.124 + DDRD = (DDRD & 0xf0) | 0xf; 3.125 + 3.126 + PORTD = (PORTD & 0xf0) | ((byte >> 4) & 0xf); 3.127 + PORTD = (PORTD & 0xf0) | (byte & 0xf); 3.128 +#endif 3.129 +} 3.130 + 3.131 +unsigned char lcd_read_byte(void) 3.132 +{ 3.133 +#if LCD_BUS_WIDTH == 8 3.134 + DDRD = 0; 3.135 + PORTD = 0; /* disable pull-ups */ 3.136 + 3.137 + return PIND; 3.138 +#else 3.139 + unsigned char byte; 3.140 + 3.141 + DDRD = DDRD & 0xf0; 3.142 + PORTD &= 0xf0; /* disable pull-ups */ 3.143 + 3.144 + byte = (PIND & 0xf) << 4; 3.145 + return byte | (PIND & 0xf); 3.146 +#endif 3.147 +} 3.148 + 3.149 +void lcd_init(void) 3.150 +{ 3.151 + /* make sure the display has time to boot up */ 3.152 + _delay_ms(20); 3.153 + 3.154 + clear_bit(BIT_RW); 3.155 + 3.156 + clear_bit(BIT_E); 3.157 + clear_bit(BIT_RS); 3.158 +#if LCD_BUS_WIDTH == 8 3.159 + lcd_write_byte(CMD_FUNC | FUNC_BUS_8BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 3.160 +#else 3.161 + lcd_write_byte(CMD_FUNC | FUNC_BUS_4BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 3.162 +#endif 3.163 + enable(); 3.164 + lcd_wait_busy(); 3.165 + 3.166 + clear_bit(BIT_RS); 3.167 + lcd_write_byte(CMD_ONOFF | ONOFF_DISP); 3.168 + enable(); 3.169 + lcd_wait_busy(); 3.170 + 3.171 + clear_bit(BIT_RS); 3.172 + lcd_write_byte(CMD_ENTRY_MODE | (1 << 1)); 3.173 + enable(); 3.174 + lcd_wait_busy(); 3.175 +} 3.176 + 3.177 +void lcd_clear(void) 3.178 +{ 3.179 + clear_bit(BIT_RW); 3.180 + 3.181 + clear_bit(BIT_E); 3.182 + clear_bit(BIT_RS); 3.183 + lcd_write_byte(CMD_CLEAR); 3.184 + enable(); 3.185 + lcd_wait_busy(); 3.186 +} 3.187 + 3.188 +void lcd_set_cursor_addr(unsigned int addr) 3.189 +{ 3.190 + clear_bit(BIT_RW); 3.191 + 3.192 + clear_bit(BIT_E); 3.193 + clear_bit(BIT_RS); 3.194 + lcd_write_byte(CMD_DDRAM_ADDR | addr); 3.195 + enable(); 3.196 + lcd_wait_busy(); 3.197 +} 3.198 + 3.199 +void lcd_putchar(char c) 3.200 +{ 3.201 + clear_bit(BIT_RW); 3.202 + 3.203 + set_bit(BIT_RS); 3.204 + lcd_write_byte(c); 3.205 + enable(); 3.206 + lcd_wait_busy(); 3.207 +} 3.208 + 3.209 +void lcd_putstr(const char *str) 3.210 +{ 3.211 + while(*str) { 3.212 + lcd_putchar(*str++); 3.213 + } 3.214 +} 3.215 + 3.216 +int lcd_stream_write(char c, FILE *fp) 3.217 +{ 3.218 + /* TODO terminal shit handling */ 3.219 + lcd_putchar(c); 3.220 + return 0; 3.221 +} 3.222 + 3.223 +void lcd_wait_busy(void) 3.224 +{ 3.225 + unsigned char data; 3.226 + 3.227 + do { 3.228 + NSDELAY(); 3.229 + clear_bit(BIT_E); 3.230 + clear_bit(BIT_RS); 3.231 + set_bit(BIT_RW); 3.232 + /*PIND = 0xff;*/ 3.233 + 3.234 + NSDELAY(); 3.235 + set_bit(BIT_E); 3.236 + NSDELAY(); 3.237 + data = lcd_read_byte(); 3.238 + clear_bit(BIT_E); 3.239 + clear_bit(BIT_RW); 3.240 + 3.241 + } while(data & (1 << 7)); 3.242 +} 3.243 + 3.244 +static void enable(void) 3.245 +{ 3.246 + NSDELAY(); 3.247 + set_bit(BIT_E); 3.248 + NSDELAY(); 3.249 + clear_bit(BIT_E); 3.250 + NSDELAY(); 3.251 +} 3.252 + 3.253 +static void set_bit(int bit) 3.254 +{ 3.255 + PORTC |= 1 << bit; 3.256 +} 3.257 + 3.258 +static void clear_bit(int bit) 3.259 +{ 3.260 + PORTC &= ~(1 << bit); 3.261 +} 3.262 + 3.263 + 3.264 +void delay(int x) 3.265 +{ 3.266 + int i, j; 3.267 + 3.268 + while(x-- > 0) { 3.269 + for(i=0; i<90; i++) { 3.270 + for(j=0; j<6; j++) { 3.271 + asm volatile("nop"); 3.272 + } 3.273 + } 3.274 + } 3.275 +}