Date:2012-12-04 01:23:02 (11 years 3 months ago)
Author:Werner Almesberger
Commit:8c868198edb632f167935cfa58e9a762f4d10829
Message:tornado/fw/: acceleration sensor "driver"

Files: tornado/fw/Makefile (1 diff)
tornado/fw/accel.c (1 diff)
tornado/fw/accel.h (1 diff)

Change Details

tornado/fw/Makefile
3131#OBJDUMP = $(AVR_PREFIX)objdump
3232SIZE = $(AVR_PREFIX)size
3333
34OBJS = $(NAME).o led.o $(COMMON_OBJS)
34OBJS = $(NAME).o accel.o led.o $(COMMON_OBJS)
3535BOOT_OBJS = boot.o $(COMMON_OBJS)
3636COMMON_OBJS =
3737
tornado/fw/accel.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)(uint16_t x, uint16_t y) = 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    static uint16_t last_x;
72    uint16_t v;
73
74    v = ADC;
75
76    if (chan_x) {
77        last_x = v;
78        chan_x = 0;
79        admux(0);
80        adcsra(1);
81    } else {
82        sample(last_x, v);
83    }
84}
85
86
87ISR(TIMER0_OVF_vect)
88{
89    chan_x = 1;
90    admux(1);
91    adcsra(1);
92}
93
94
95void accel_start(void)
96{
97    adcsra(0);
98
99    TCNT0 = 0;
100    OCR0A = 62; /* 8 MHz/64/62 = 2.02 kHz */
101    TCCR0A =
102        1 << WGM01 | /* WG Mode 7 (Fast PWM to OCR0A) */
103        1 << WGM00;
104    TCCR0B =
105        1 << WGM02 | /* WG Mode 7, continued */
106        1 << CS01 | /* clkIO/64 */
107        1 << CS00;
108    TIMSK0 = 1 << TOIE0; /* interrupt on overflow */
109}
tornado/fw/accel.h
1/*
2 * fw/accel.h - 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#ifndef ACCEL_H
15#define ACCEL_H
16
17#include <stdint.h>
18
19
20extern void (*sample)(uint16_t x, uint16_t y);
21
22
23uint16_t measure_ref(void);
24void accel_start(void);
25
26#endif /* !ACCEL_H */

Archive Download the corresponding diff file

Branches:
master
tornado-v1



interactive