# HG changeset patch # User John Tsiombikas # Date 1314115271 -10800 # Node ID 0c17075080709ed5eb2eed554018dbcf2c245cf8 initial commit diff -r 000000000000 -r 0c1707508070 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Aug 23 19:01:11 2011 +0300 @@ -0,0 +1,6 @@ +\.d$ +\.o$ +\.swp$ +^odometer.map$ +^odometer.eep$ +^odometer.hex$ diff -r 000000000000 -r 0c1707508070 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Tue Aug 23 19:01:11 2011 +0300 @@ -0,0 +1,38 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +bin = odometer +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) + +.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: fuses +fuses: + avrdude -c usbtiny -p $(mcu_dude) -U lfuse:w:0x66:m + +.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 0c1707508070 odometer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/odometer.c Tue Aug 23 19:01:11 2011 +0300 @@ -0,0 +1,132 @@ +/* PORT USAGE + * + * D0-D3: data bus, connected to the D0-D3 pins of all the 4511 chips + * C0-C5,D4,D5: directly driving the 8 speed graph LEDs + * B0-B2: connected to the decoder controlling the 4511 latches as such: + * 000 - speed most significant + * 001 - speed least significant + * 010 - dist most significant + * 011 - dist middle + * 100 - dist least significant + * 101 - all latches are off (high) + * B3-B5: ISP. B4 also acts as generic pushbutton input + * B6,B7: XTAL + * D6,D7: comparator, hall effect sensor input and threshold trimpot. + */ + +/* 16mhz resonator */ +#define F_CPU 2000000 + +#include +#include +#include + +void latch(int n); +void update_display(void); + +int state; +int debug_mode = 1; + +unsigned long nrot; + +/* wheel perimeter in centimeters */ +#define WHEEL_PERIMETER 100 + +int main(void) +{ + int i; + + DDRB = 0xf; /* only first four bits are outputs */ + DDRC = 0xff; /* speed leds 6 bits */ + DDRD = 0xff; /* 4bits data bus, 2 bits speed leds, 2 bits comparator (don't care) */ + + /* zero-out the displays and disable all pullups except for the reset pin */ + PORTB = 0; + PORTC = 0x40; /* 6th bit set, C6 is reset */ + PORTD = 0; + + for(i=0; i<5; i++) { + latch(i); + } + + /* read initial comparator state */ + state = (ACSR >> ACO) & 1; + + if(debug_mode) { + int i, j, leds, leds_val; + + for(i=0; ; i++) { + for(j=0; j<5; j++) { + /* set bits */ + PORTD = (PORTD & 0xf0) | (((i + j) % 10) & 0xf); + /* latch */ + latch(j); + } + + leds_val = 0; + leds = i % 8; + for(j=0; j<8; j++) { + if(j <= leds) { + leds_val |= (1 << j); + } + } + PORTC = leds_val; + PORTD = (PORTD & 0xf) | ((leds_val >> 2) & (3 << 4)); + + _delay_ms(1000); + } + } + + /* disable digital input buffer for the AINn pins */ + /*DIDR1 = 0;*/ + + ACSR = (1 << ACIE); + /* in debug mode we want an interrupt both on rising and falling edge + * to be able to blink leds when the wheel goes past. otherwise we only need + * a rising edge interrupt to increment the rotation counter. + */ + if(!debug_mode) { + /* rising edge interrupt */ + ACSR |= (3 << ACIS0); + } + + sei(); + + for(;;); + return 0; +} + +void latch(int n) +{ + unsigned char upper = PORTB & 0xf0; + /* pull latch low */ + PORTB = upper | n; + asm volatile("nop"); + /* pull all latches high again */ + PORTB = upper | 5; +} + +ISR(ANALOG_COMP_vect) +{ + if(debug_mode) { + int state = (ACSR >> ACO) & 1; + + if(state) { + PORTB |= 1; + nrot++; + } else { + PORTB &= ~1; + } + } else { + nrot++; + } + + update_display(); +} + +void update_display(void) +{ + unsigned long dist_cm = (nrot * WHEEL_PERIMETER); + + /* TODO */ +}