pwcdecode
diff pwcdecode.c @ 0:050c04723d37
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 01 Nov 2013 09:40:20 +0200 |
parents | |
children | 4ea5d2920f89 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/pwcdecode.c Fri Nov 01 09:40:20 2013 +0200 1.3 @@ -0,0 +1,272 @@ 1.4 +#define F_CLK 1000000 1.5 +#define F_CPU 1000000 1.6 + 1.7 +#include <stdio.h> 1.8 +#include <avr/io.h> 1.9 +#include <avr/interrupt.h> 1.10 +#include <util/delay.h> 1.11 + 1.12 +/* hardware setup 1.13 + * - PORT D: data bits 1.14 + * - PORT C 1.15 + * bit 3: RS 1.16 + * bit 4: R/W 1.17 + * bit 5: E 1.18 + */ 1.19 +#define LCD_BUS_WIDTH 8 1.20 + 1.21 +#define BIT_RS 3 1.22 +#define BIT_RW 4 1.23 +#define BIT_E 5 1.24 + 1.25 +#define CMD_CLEAR 1 1.26 +#define CMD_RET (1 << 1) 1.27 +#define CMD_ENTRY_MODE (1 << 2) 1.28 +#define CMD_ONOFF (1 << 3) 1.29 +#define CMD_SHIFT (1 << 4) 1.30 +#define CMD_FUNC (1 << 5) 1.31 +#define CMD_CGRAM_ADDR (1 << 6) 1.32 +#define CMD_DDRAM_ADDR (1 << 7) 1.33 + 1.34 +#define FUNC_BUS_4BIT 0 1.35 +#define FUNC_BUS_8BIT (1 << 4) 1.36 +#define FUNC_LINES_1 0 1.37 +#define FUNC_LINES_2 (1 << 3) 1.38 +#define FUNC_FONT_5x8 0 1.39 +#define FUNC_FONT_5x11 (1 << 2) 1.40 + 1.41 +#define ONOFF_DISP (1 << 2) 1.42 +#define ONOFF_CURSOR (1 << 1) 1.43 +#define ONOFF_CURSOR_POS 1 1.44 + 1.45 +void lcd_init(void); 1.46 +void lcd_clear(void); 1.47 +void lcd_set_cursor_addr(unsigned int addr); 1.48 +void lcd_putchar(char c); 1.49 +void lcd_putstr(const char *str); 1.50 +int lcd_stream_write(char c, FILE *fp); 1.51 +void lcd_wait_busy(void); 1.52 +static void enable(void); 1.53 +static void set_bit(int bit); 1.54 +static void clear_bit(int bit); 1.55 +void delay(int x); 1.56 + 1.57 +#define NSDELAY() asm volatile ("nop") 1.58 +#define DEBUG(i) (PORTB = (1 << (i))) 1.59 + 1.60 +FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE); 1.61 + 1.62 +unsigned int pulse_time; 1.63 + 1.64 +int main(void) 1.65 +{ 1.66 + stdout = stderr = &stream_lcd; 1.67 + 1.68 + DDRB = 0; /* set port B as input (bit 0 is used to measure pulse width) */ 1.69 + PORTB = 0; /* disable pullups */ 1.70 + 1.71 + DDRD = 0xff; 1.72 + DDRC = 0xfe; 1.73 + PORTC = 0; /* disable pullups */ 1.74 + 1.75 + lcd_init(); 1.76 + lcd_clear(); 1.77 + 1.78 + printf("initializing..."); 1.79 + 1.80 + TCCR1B |= (1 << ICES1); /* set first capture to occur on a rising edge */ 1.81 + TCCR1B = (TCCR1B & 0xf8) | 1; /* no prescaling */ 1.82 + TIMSK1 |= (1 << ICIE1); /* enable timer1 input capture interrupt */ 1.83 + sei(); 1.84 + 1.85 + for(;;) { 1.86 + static int blink = 0; 1.87 + 1.88 + PORTB = blink ? 1 : 0; 1.89 + blink = (blink + 1) & 1; 1.90 + 1.91 + lcd_set_cursor_addr(0); 1.92 + printf("pulse time: %u us ", pulse_time); 1.93 + lcd_set_cursor_addr(64); 1.94 + printf("pos: %u%% ", (pulse_time - 1000) / 10); 1.95 + _delay_ms(100); 1.96 + } 1.97 + return 0; 1.98 +} 1.99 + 1.100 +ISR(TIMER1_CAPT_vect) 1.101 +{ 1.102 + static int rising; 1.103 + 1.104 + rising = !rising; 1.105 + if(rising) { 1.106 + /* rising edge: reset the timer */ 1.107 + TCNT1 = 0; 1.108 + /* and set a falling edge trigger */ 1.109 + TCCR1B &= ~(1 << ICES1); 1.110 + } else { 1.111 + /* falling edge: calculate the time since the last rise */ 1.112 + pulse_time = ICR1; 1.113 + /* and set a rising edge trigger */ 1.114 + TCCR1B |= 1 << ICES1; 1.115 + } 1.116 +} 1.117 + 1.118 +void lcd_write_byte(unsigned char byte) 1.119 +{ 1.120 +#if LCD_BUS_WIDTH == 8 1.121 + DDRD = 0xff; 1.122 + PORTD = byte; 1.123 +#else 1.124 + DDRD = (DDRD & 0xf0) | 0xf; 1.125 + 1.126 + PORTD = (PORTD & 0xf0) | ((byte >> 4) & 0xf); 1.127 + PORTD = (PORTD & 0xf0) | (byte & 0xf); 1.128 +#endif 1.129 +} 1.130 + 1.131 +unsigned char lcd_read_byte(void) 1.132 +{ 1.133 +#if LCD_BUS_WIDTH == 8 1.134 + DDRD = 0; 1.135 + PORTD = 0; /* disable pull-ups */ 1.136 + 1.137 + return PIND; 1.138 +#else 1.139 + unsigned char byte; 1.140 + 1.141 + DDRD = DDRD & 0xf0; 1.142 + PORTD &= 0xf0; /* disable pull-ups */ 1.143 + 1.144 + byte = (PIND & 0xf) << 4; 1.145 + return byte | (PIND & 0xf); 1.146 +#endif 1.147 +} 1.148 + 1.149 +void lcd_init(void) 1.150 +{ 1.151 + /* make sure the display has time to boot up */ 1.152 + _delay_ms(20); 1.153 + 1.154 + clear_bit(BIT_RW); 1.155 + 1.156 + clear_bit(BIT_E); 1.157 + clear_bit(BIT_RS); 1.158 +#if LCD_BUS_WIDTH == 8 1.159 + lcd_write_byte(CMD_FUNC | FUNC_BUS_8BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 1.160 +#else 1.161 + lcd_write_byte(CMD_FUNC | FUNC_BUS_4BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 1.162 +#endif 1.163 + enable(); 1.164 + lcd_wait_busy(); 1.165 + 1.166 + clear_bit(BIT_RS); 1.167 + lcd_write_byte(CMD_ONOFF | ONOFF_DISP); 1.168 + enable(); 1.169 + lcd_wait_busy(); 1.170 + 1.171 + clear_bit(BIT_RS); 1.172 + lcd_write_byte(CMD_ENTRY_MODE | (1 << 1)); 1.173 + enable(); 1.174 + lcd_wait_busy(); 1.175 +} 1.176 + 1.177 +void lcd_clear(void) 1.178 +{ 1.179 + clear_bit(BIT_RW); 1.180 + 1.181 + clear_bit(BIT_E); 1.182 + clear_bit(BIT_RS); 1.183 + lcd_write_byte(CMD_CLEAR); 1.184 + enable(); 1.185 + lcd_wait_busy(); 1.186 +} 1.187 + 1.188 +void lcd_set_cursor_addr(unsigned int addr) 1.189 +{ 1.190 + clear_bit(BIT_RW); 1.191 + 1.192 + clear_bit(BIT_E); 1.193 + clear_bit(BIT_RS); 1.194 + lcd_write_byte(CMD_DDRAM_ADDR | addr); 1.195 + enable(); 1.196 + lcd_wait_busy(); 1.197 +} 1.198 + 1.199 +void lcd_putchar(char c) 1.200 +{ 1.201 + clear_bit(BIT_RW); 1.202 + 1.203 + set_bit(BIT_RS); 1.204 + lcd_write_byte(c); 1.205 + enable(); 1.206 + lcd_wait_busy(); 1.207 +} 1.208 + 1.209 +void lcd_putstr(const char *str) 1.210 +{ 1.211 + while(*str) { 1.212 + lcd_putchar(*str++); 1.213 + } 1.214 +} 1.215 + 1.216 +int lcd_stream_write(char c, FILE *fp) 1.217 +{ 1.218 + /* TODO terminal shit handling */ 1.219 + lcd_putchar(c); 1.220 + return 0; 1.221 +} 1.222 + 1.223 +void lcd_wait_busy(void) 1.224 +{ 1.225 + unsigned char data; 1.226 + 1.227 + do { 1.228 + NSDELAY(); 1.229 + clear_bit(BIT_E); 1.230 + clear_bit(BIT_RS); 1.231 + set_bit(BIT_RW); 1.232 + /*PIND = 0xff;*/ 1.233 + 1.234 + NSDELAY(); 1.235 + set_bit(BIT_E); 1.236 + NSDELAY(); 1.237 + data = lcd_read_byte(); 1.238 + clear_bit(BIT_E); 1.239 + clear_bit(BIT_RW); 1.240 + 1.241 + } while(data & (1 << 7)); 1.242 +} 1.243 + 1.244 +static void enable(void) 1.245 +{ 1.246 + NSDELAY(); 1.247 + set_bit(BIT_E); 1.248 + NSDELAY(); 1.249 + clear_bit(BIT_E); 1.250 + NSDELAY(); 1.251 +} 1.252 + 1.253 +static void set_bit(int bit) 1.254 +{ 1.255 + PORTC |= 1 << bit; 1.256 +} 1.257 + 1.258 +static void clear_bit(int bit) 1.259 +{ 1.260 + PORTC &= ~(1 << bit); 1.261 +} 1.262 + 1.263 + 1.264 +void delay(int x) 1.265 +{ 1.266 + int i, j; 1.267 + 1.268 + while(x-- > 0) { 1.269 + for(i=0; i<90; i++) { 1.270 + for(j=0; j<6; j++) { 1.271 + asm volatile("nop"); 1.272 + } 1.273 + } 1.274 + } 1.275 +}