diff --git a/tornado/fw/Makefile b/tornado/fw/Makefile index 20ad483..2a02cdb 100644 --- a/tornado/fw/Makefile +++ b/tornado/fw/Makefile @@ -31,7 +31,7 @@ OBJCOPY = $(AVR_PREFIX)objcopy #OBJDUMP = $(AVR_PREFIX)objdump SIZE = $(AVR_PREFIX)size -OBJS = $(NAME).o led.o $(COMMON_OBJS) +OBJS = $(NAME).o accel.o led.o $(COMMON_OBJS) BOOT_OBJS = boot.o $(COMMON_OBJS) COMMON_OBJS = diff --git a/tornado/fw/accel.c b/tornado/fw/accel.c new file mode 100644 index 0000000..2a75644 --- /dev/null +++ b/tornado/fw/accel.c @@ -0,0 +1,109 @@ +/* + * fw/accel.c - Acceleration sensor + * + * Written 2012 by Werner Almesberger + * Copyright 2012 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include +#include + +#include +#include +#define F_CPU 8000000UL +#include + +#include "io.h" +#include "accel.h" + + +void (*sample)(uint16_t x, uint16_t y) = NULL; + + +static bool chan_x; + + +static inline void admux(bool x) +{ + ADMUX = + 1 << REFS0 | /* Vref is AVcc */ + (x ? ADC_X : ADC_Y); +} + + +static inline void adcsra(bool start) +{ + /* + * The ADC needs to run at clkADC <= 200 kHz for full resolution. + * At clkADC = 125 kHz, a conversion takes about 110 us. + */ + ADCSRA = + 1 << ADEN | /* enable ADC */ + (start ? 1 << ADSC : 0) | + 1 << ADIE | /* enable ADC interrupts */ + 6; /* clkADC = clk/64 -> 125 kHz */ +} + + +uint16_t measure_ref(void) +{ + while (ADCSRA & (1 << ADSC)); + adcsra(0); + ADMUX = + 1 << REFS0 | /* Vref is AVcc */ + 14; /* Vbg (1.1 V) */ + _delay_us(100); + adcsra(1); + while (ADCSRA & (1 << ADSC)); + return ADC; +} + + +ISR(ADC_vect) +{ + static uint16_t last_x; + uint16_t v; + + v = ADC; + + if (chan_x) { + last_x = v; + chan_x = 0; + admux(0); + adcsra(1); + } else { + sample(last_x, v); + } +} + + +ISR(TIMER0_OVF_vect) +{ + chan_x = 1; + admux(1); + adcsra(1); +} + + +void accel_start(void) +{ + adcsra(0); + + TCNT0 = 0; + OCR0A = 62; /* 8 MHz/64/62 = 2.02 kHz */ + TCCR0A = + 1 << WGM01 | /* WG Mode 7 (Fast PWM to OCR0A) */ + 1 << WGM00; + TCCR0B = + 1 << WGM02 | /* WG Mode 7, continued */ + 1 << CS01 | /* clkIO/64 */ + 1 << CS00; + TIMSK0 = 1 << TOIE0; /* interrupt on overflow */ +} diff --git a/tornado/fw/accel.h b/tornado/fw/accel.h new file mode 100644 index 0000000..2791352 --- /dev/null +++ b/tornado/fw/accel.h @@ -0,0 +1,26 @@ +/* + * fw/accel.h - Acceleration sensor + * + * Written 2012 by Werner Almesberger + * Copyright 2012 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#ifndef ACCEL_H +#define ACCEL_H + +#include + + +extern void (*sample)(uint16_t x, uint16_t y); + + +uint16_t measure_ref(void); +void accel_start(void); + +#endif /* !ACCEL_H */