Root/tornado/fw/tornado.c

Source at commit a11670bb7bb6e506db72463fea6738100b22c9a7 created 11 years 17 days ago.
By Werner Almesberger, tornado/fw/sim/alg.c: accept data from standard input; fix "process"
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 "accel.h"
12
13
14#define HIGH(port) \
15    (MASK(port, CARD_nPWR) | \
16    MASK(port, SW_N) | MASK(port, SW_E) | MASK(port, SW_S) | \
17    MASK(port, SW_W) | MASK(port, SW_SW))
18
19#define OUTPUTS(port) \
20    (MASK(port, CARD_nPWR) | MASK(port, CARD_CLK) | \
21    MASK(port, LED_DS) | MASK(port, LED_LCLK) | MASK(port, LED_SCLK))
22
23
24#if 0
25
26/*
27 * @@@ For testing, connect the LED bar via the 8:10 card slot, so that it
28 * can be disconnected without soldering.
29 */
30
31#define SCLK CARD_DAT1
32#define LCLK CARD_DAT0
33#define DS CARD_CLK
34#define VDD CARD_CMD
35
36#else
37
38#define SCLK LED_SCLK
39#define LCLK LED_LCLK
40#define DS LED_DS
41
42#endif
43
44
45static void send(uint8_t pattern[N_LEDS/8])
46{
47    uint8_t i, j, mask;
48
49    for (i = 0; i != N_LEDS/8; i++) {
50        mask = 1;
51        for (j = 0; j != 8; j++) {
52            if (pattern[i] & mask)
53                SET(DS);
54            else
55                CLR(DS);
56            SET(SCLK);
57            CLR(SCLK);
58            mask <<= 1;
59        }
60    }
61    SET(LCLK);
62    CLR(LCLK);
63}
64
65
66static inline void admux(bool x)
67{
68    ADMUX =
69        1 << REFS0 | /* Vref is AVcc */
70        (x ? ADC_X : ADC_Y);
71}
72
73
74static inline void adcsra(bool start)
75{
76    /*
77     * The ADC needs to run at clkADC <= 200 kHz for full resolution.
78     * At clkADC = 125 kHz, a conversion takes about 110 us.
79     */
80    ADCSRA =
81        1 << ADEN | /* enable ADC */
82        (start ? 1 << ADSC : 0) |
83        1 << ADIE | /* enable ADC interrupts */
84        6; /* clkADC = clk/64 -> 125 kHz */
85}
86
87
88static uint16_t adc(bool x)
89{
90    adcsra(0);
91    admux(x);
92    adcsra(1);
93    while (ADCSRA & (1 << ADSC));
94    return ADC;
95}
96
97
98#define E_SHIFT 3 /* ~ 0.1 */
99#define M_SHIFT 11 /* ~ 1/sample_rate */
100
101#define HYSTERESIS 14
102
103
104static const uint8_t img[] PROGMEM = {
105    #include "img.inc"
106};
107
108
109static void zxing(uint16_t x, uint16_t y)
110{
111    static uint8_t one[LED_BYTES] =
112        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
113    static uint16_t e = 512 << E_SHIFT;
114    static uint32_t m = 512 << M_SHIFT;
115    int16_t d;
116    static bool up = 0;
117    static bool on = 0;
118    static const prog_uint8_t *p;
119    static uint16_t cols = 0;
120
121    e = y+(e-(e >> E_SHIFT));
122    m = y+(m-(m >> M_SHIFT));
123    d = (e >> E_SHIFT)-(m >> M_SHIFT);
124    if (up) {
125        if (d < -HYSTERESIS)
126            up = 0;
127    } else {
128        if (d > HYSTERESIS) {
129            up = 1;
130            p = img;
131            cols = sizeof(img)/LED_BYTES;
132            on = 1;
133        }
134    }
135    if (cols) {
136        led_show_pgm(p);
137        p += 8;
138        cols--;
139    } else {
140        led_off();
141    }
142}
143
144
145int main(void)
146{
147    PORTB = HIGH(B);
148    PORTC = HIGH(C);
149    PORTD = HIGH(D);
150    DDRB = OUTPUTS(B);
151    DDRC = OUTPUTS(C);
152    DDRD = OUTPUTS(D);
153
154    CLR(CARD_nPWR);
155    CLR(SCLK);
156    CLR(LCLK);
157    OUT(SCLK);
158    OUT(LCLK);
159    OUT(DS);
160
161#ifdef VDD
162    SET(VDD);
163    OUT(VDD);
164#endif
165
166    led_init();
167#if 1
168    sample = zxing;
169    accel_start();
170    sei();
171    while (1);
172#else
173    static uint8_t p[LED_BYTES];
174    uint8_t mode = 0;
175    uint16_t n = 0, v;
176
177    while (1) {
178        while (!PIN(SW_SW));
179        if (!PIN(SW_N))
180            mode = 0;
181        if (!PIN(SW_E))
182            mode = 1;
183        if (!PIN(SW_S))
184            mode = 2;
185        switch (mode) {
186        case 1:
187            n = adc(0);
188            p[0] = n;
189            p[1] = n >> 8;
190            p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
191            send(p);
192            break;
193        case 2:
194            n = adc(1);
195            p[0] = n;
196            p[1] = n >> 8;
197            p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
198            send(p);
199            break;
200        default:
201            v = 63-n;
202            if (n & 64)
203                p[(v >> 3) & 7] &= ~(1 << (v & 7));
204            else
205                p[(v >> 3) & 7] |= 1 << (v & 7);
206            led_show(p);
207            n++;
208        }
209        _delay_ms(100);
210    }
211#endif
212}
213

Archive Download this file

Branches:
master
tornado-v1



interactive