Root/tornado/fw/tornado.c

Source at commit 45f14d214ab31fe28644ef8f61552a3e25330ccf created 11 years 16 days ago.
By Werner Almesberger, tornado/fw/tornado.c: experimental code to log ADC samples to memory card
1#include <stdbool.h>
2#include <stdint.h>
3
4#include <avr/interrupt.h>
5#include <avr/pgmspace.h>
6#define F_CPU 8000000UL
7#include <util/delay.h>
8
9#include "io.h"
10#include "led.h"
11#include "mmc.h"
12#include "accel.h"
13
14
15#define HIGH(port) \
16    (MASK(port, CARD_nPWR) | \
17    MASK(port, SW_N) | MASK(port, SW_E) | MASK(port, SW_S) | \
18    MASK(port, SW_W) | MASK(port, SW_SW))
19
20#define OUTPUTS(port) \
21    (MASK(port, CARD_nPWR) | MASK(port, CARD_CLK) | \
22    MASK(port, LED_DS) | MASK(port, LED_LCLK) | MASK(port, LED_SCLK))
23
24
25#if 0
26
27/*
28 * @@@ For testing, connect the LED bar via the 8:10 card slot, so that it
29 * can be disconnected without soldering.
30 */
31
32#define SCLK CARD_DAT1
33#define LCLK CARD_DAT0
34#define DS CARD_CLK
35#define VDD CARD_CMD
36
37#else
38
39#define SCLK LED_SCLK
40#define LCLK LED_LCLK
41#define DS LED_DS
42
43#endif
44
45
46static void send(uint8_t pattern[N_LEDS/8])
47{
48    uint8_t i, j, mask;
49
50    for (i = 0; i != N_LEDS/8; i++) {
51        mask = 1;
52        for (j = 0; j != 8; j++) {
53            if (pattern[i] & mask)
54                SET(DS);
55            else
56                CLR(DS);
57            SET(SCLK);
58            CLR(SCLK);
59            mask <<= 1;
60        }
61    }
62    SET(LCLK);
63    CLR(LCLK);
64}
65
66
67static inline void admux(bool x)
68{
69    ADMUX =
70        1 << REFS0 | /* Vref is AVcc */
71        (x ? ADC_X : ADC_Y);
72}
73
74
75static inline void adcsra(bool start)
76{
77    /*
78     * The ADC needs to run at clkADC <= 200 kHz for full resolution.
79     * At clkADC = 125 kHz, a conversion takes about 110 us.
80     */
81    ADCSRA =
82        1 << ADEN | /* enable ADC */
83        (start ? 1 << ADSC : 0) |
84        1 << ADIE | /* enable ADC interrupts */
85        6; /* clkADC = clk/64 -> 125 kHz */
86}
87
88
89static uint16_t adc(bool x)
90{
91    adcsra(0);
92    admux(x);
93    adcsra(1);
94    while (ADCSRA & (1 << ADSC));
95    return ADC;
96}
97
98
99#define E_SHIFT 3 /* ~ 0.1 */
100#define M_SHIFT 11 /* ~ 1/sample_rate */
101
102#define HYSTERESIS 14
103
104
105static const uint8_t img[] PROGMEM = {
106    #include "img.inc"
107};
108
109
110static uint8_t one[LED_BYTES] =
111    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
112
113static volatile uint16_t sample_t = 0, sample_v;
114
115
116static void zxing(uint16_t x, uint16_t y)
117{
118    static uint16_t e = 512 << E_SHIFT;
119    static uint32_t m = 512 << M_SHIFT;
120    int16_t d;
121    static bool up = 0;
122    static bool on = 0;
123    static const prog_uint8_t *p;
124    static uint16_t cols = 0;
125
126    sample_t++;
127    sample_v = x;
128return;
129
130    e = y+(e-(e >> E_SHIFT));
131    m = y+(m-(m >> M_SHIFT));
132    d = (e >> E_SHIFT)-(m >> M_SHIFT);
133    if (up) {
134        if (d < -HYSTERESIS)
135            up = 0;
136    } else {
137        if (d > HYSTERESIS) {
138            up = 1;
139            p = img;
140            cols = sizeof(img)/LED_BYTES;
141            on = 1;
142        }
143    }
144    if (cols) {
145        led_show_pgm(p);
146        p += 8;
147        cols--;
148    } else {
149        led_off();
150    }
151}
152
153
154static void panic(void)
155{
156    cli();
157    while (1) {
158        led_show(one);
159        _delay_ms(100);
160        led_off();
161        _delay_ms(100);
162    }
163}
164
165
166int main(void)
167{
168    PORTB = HIGH(B);
169    PORTC = HIGH(C);
170    PORTD = HIGH(D);
171    DDRB = OUTPUTS(B);
172    DDRC = OUTPUTS(C);
173    DDRD = OUTPUTS(D);
174
175    CLR(CARD_nPWR);
176    CLR(SCLK);
177    CLR(LCLK);
178    OUT(SCLK);
179    OUT(LCLK);
180    OUT(DS);
181
182#ifdef VDD
183    SET(VDD);
184    OUT(VDD);
185#endif
186
187    led_init();
188
189#if 0
190    led_show(one);
191
192    if (!mmc_init())
193        panic();
194    if (!mmc_begin_write(0))
195        panic();
196
197    uint16_t n = 0;
198
199    for (n = 0; n != 512; n += 2) {
200        mmc_write(n);
201        mmc_write(n >> 8);
202    }
203
204    if (!mmc_end_write())
205        panic();
206
207    if (!mmc_begin_write(n))
208        panic();
209
210    for (; n != 1024; n += 2) {
211        mmc_write(n);
212        mmc_write(n >> 8);
213    }
214
215    if (!mmc_end_write())
216        panic();
217
218    _delay_ms(1000);
219
220    led_off();
221
222    while (1);
223#endif
224
225#if 1
226    uint16_t last_t = 0;
227    uint32_t n = 0;
228
229    sample = zxing;
230    if (!mmc_init())
231        panic();
232    accel_start();
233    sei();
234    while (1) {
235        uint16_t t, v;
236
237        if (!(n & 511)) {
238            if (n && !mmc_end_write())
239                panic();
240            if (!mmc_begin_write(n))
241                panic();
242        }
243
244#if 0
245    t = n;
246    v = 0;
247#else
248        do {
249            cli();
250            t = sample_t;
251            v = sample_v;
252            sei();
253        }
254        while (t == last_t);
255#endif
256
257        last_t = t;
258        mmc_write(t);
259        mmc_write(t >> 8);
260        mmc_write(v);
261        mmc_write(v >> 8);
262        n += 4;
263    }
264#endif
265
266#if 0
267    static uint8_t p[LED_BYTES];
268    uint8_t mode = 0;
269    uint16_t n = 0, v;
270
271    while (1) {
272        while (!PIN(SW_SW));
273        if (!PIN(SW_N))
274            mode = 0;
275        if (!PIN(SW_E))
276            mode = 1;
277        if (!PIN(SW_S))
278            mode = 2;
279        switch (mode) {
280        case 1:
281            n = adc(0);
282            p[0] = n;
283            p[1] = n >> 8;
284            p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
285            send(p);
286            break;
287        case 2:
288            n = adc(1);
289            p[0] = n;
290            p[1] = n >> 8;
291            p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
292            send(p);
293            break;
294        default:
295            v = 63-n;
296            if (n & 64)
297                p[(v >> 3) & 7] &= ~(1 << (v & 7));
298            else
299                p[(v >> 3) & 7] |= 1 << (v & 7);
300            led_show(p);
301            n++;
302        }
303        _delay_ms(100);
304    }
305#endif
306}
307

Archive Download this file

Branches:
master
tornado-v1



interactive