Root/fw/accel.c

Source at commit 2dc2fb278cf17368265e066d025c2584d640f1a7 created 11 years 11 days ago.
By Werner Almesberger, tornado/fw/tornado.c: update signal processing from sim/alg.c
1/*
2 * fw/accel.c - Acceleration sensor
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stddef.h>
15#include <stdbool.h>
16#include <stdint.h>
17
18#include <avr/io.h>
19#include <avr/interrupt.h>
20#define F_CPU 8000000UL
21#include <util/delay.h>
22
23#include "io.h"
24#include "accel.h"
25
26
27void (*sample)(bool x, uint16_t v) = NULL;
28
29
30static bool chan_x;
31
32
33static inline void admux(bool x)
34{
35    ADMUX =
36        1 << REFS0 | /* Vref is AVcc */
37        (x ? ADC_X : ADC_Y);
38}
39
40
41static inline void adcsra(bool start)
42{
43    /*
44     * The ADC needs to run at clkADC <= 200 kHz for full resolution.
45     * At clkADC = 125 kHz, a conversion takes about 110 us.
46     */
47    ADCSRA =
48        1 << ADEN | /* enable ADC */
49        (start ? 1 << ADSC : 0) |
50        1 << ADIE | /* enable ADC interrupts */
51        6; /* clkADC = clk/64 -> 125 kHz */
52}
53
54
55uint16_t measure_ref(void)
56{
57    while (ADCSRA & (1 << ADSC));
58    adcsra(0);
59    ADMUX =
60        1 << REFS0 | /* Vref is AVcc */
61        14; /* Vbg (1.1 V) */
62    _delay_us(100);
63    adcsra(1);
64    while (ADCSRA & (1 << ADSC));
65    return ADC;
66}
67
68
69ISR(ADC_vect)
70{
71    uint16_t v;
72
73    v = ADC;
74    if (sample)
75        sample(chan_x, v);
76
77    if (chan_x) {
78        chan_x = 0;
79        admux(0);
80        adcsra(1);
81    }
82}
83
84
85ISR(TIMER0_OVF_vect)
86{
87    chan_x = 1;
88    admux(1);
89    adcsra(1);
90}
91
92
93void accel_start(void)
94{
95    adcsra(0);
96
97    TCNT0 = 0;
98    OCR0A = 125; /* 8 MHz/64/125 = 1 kHz */
99    TCCR0A =
100        1 << WGM01 | /* WG Mode 7 (Fast PWM to OCR0A) */
101        1 << WGM00;
102    TCCR0B =
103        1 << WGM02 | /* WG Mode 7, continued */
104        1 << CS01 | /* clkIO/64 */
105        1 << CS00;
106    TIMSK0 = 1 << TOIE0; /* interrupt on overflow */
107}
108

Archive Download this file

Branches:
master
tornado-v1



interactive