a27bf10b821ae74236ec19e6ba77324ea936a304
[protos/rc_servos.git] / main.c
1 #include <aversive.h>
2
3 struct servo {
4         uint8_t bit;
5         uint16_t command;
6 };
7
8 static struct servo servo_table[] = {
9         {
10                 .bit = 0,
11                 .command = 0,
12         },
13         {
14                 .bit = 1,
15                 .command = 512,
16         },
17         {
18                 .bit = 2,
19                 .command = 1023,
20         },
21 };
22
23 static volatile uint8_t rxbuf[16];
24 register uint8_t rxlen asm("r2");
25 register uint8_t done asm("r3");
26 register uint8_t portval asm("r4");
27
28 SIGNAL(TIMER1_COMPA_vect)
29 {
30         PORTC = portval;
31         TIMSK1 &= ~_BV(OCIE1A);
32         done = 1;
33 }
34
35 static void poll_spi(void)
36 {
37 }
38
39 static void load_timer_at(uint16_t t)
40 {
41         OCR1A = t;
42         TIMSK1 |= _BV(OCIE1A);
43 }
44
45 static void do_one_servo(struct servo *s)
46 {
47         uint16_t t;
48
49         /* set bit */
50         done = 0;
51         //portval = PORTC | (1 << s->bit);
52         portval = (1 << s->bit);
53         t = TCNT1;
54         load_timer_at(t + 150);
55         while (done == 0)
56                 poll_spi();
57
58         /* reset bit */
59         done = 0;
60         portval = 0;
61         //portval = PORTC & (~(1 << s->bit));
62         load_timer_at(t + 150 + 8000 + s->command * 8);
63         while (done == 0)
64                 poll_spi();
65 }
66
67 int main(void)
68 {
69         uint8_t i;
70         uint8_t t, diff;
71
72         DDRB = 0x20;
73         DDRC = 0x7;
74
75         /* start timer1 at clk/1 (8Mhz) */
76         TCNT1 = 0;
77         TCCR1B = _BV(CS10);
78
79         /* start timer0 at clk/1024 (~8Khz) */
80         TCNT0 = 0;
81         TCCR0B = _BV(CS02) | _BV(CS00);
82
83         sei();
84
85         while (1) {
86                 t = TCNT0;
87                 for (i = 0; i < sizeof(servo_table)/sizeof(*servo_table); i++) {
88                         do_one_servo(&servo_table[i]);
89                 }
90                 /* wait 20 ms */
91                 while (1) {
92                         diff = TCNT0 - t;
93                         if (diff >= 160)
94                                 break;
95                         poll_spi();
96                 }
97         }
98
99         return 0;
100 }