rc_servos: first version, generating PWM
[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 static volatile uint8_t rxbuf[16];
23 static volatile uint8_t rxlen;
24 static volatile uint8_t portval;
25 static volatile uint8_t done;
26
27 SIGNAL(TIMER1_COMPA_vect)
28 {
29         PORTC = portval;
30         TIMSK1 &= ~_BV(OCIE1A);
31         done = 1;
32 }
33
34 static void poll_spi(void)
35 {
36 }
37
38 static void load_timer_at(uint16_t t)
39 {
40         OCR1A = t;
41         TIMSK1 |= _BV(OCIE1A);
42 }
43
44 static void do_one_servo(struct servo *s)
45 {
46         uint16_t t;
47
48         /* set bit */
49         done = 0;
50         //portval = PORTC | (1 << s->bit);
51         portval = (1 << s->bit);
52         t = TCNT1;
53         load_timer_at(t + 150);
54         while (done == 0)
55                 poll_spi();
56
57         /* reset bit */
58         done = 0;
59         portval = 0;
60         //portval = PORTC & (~(1 << s->bit));
61         load_timer_at(t + 150 + 8000 + s->command * 8);
62         while (done == 0)
63                 poll_spi();
64 }
65
66 int main(void)
67 {
68         uint8_t i;
69         uint8_t t, diff;
70
71         DDRB = 0x20;
72         DDRC = 0x7;
73
74         /* start timer1 at clk/1 (8Mhz) */
75         TCNT1 = 0;
76         TCCR1B = _BV(CS10);
77
78         /* start timer0 at clk/1024 (~8Khz) */
79         TCNT0 = 0;
80         TCCR0B = _BV(CS02) | _BV(CS00);
81
82         sei();
83
84         while (1) {
85                 t = TCNT0;
86                 for (i = 0; i < sizeof(servo_table)/sizeof(*servo_table); i++) {
87                         do_one_servo(&servo_table[i]);
88                 }
89                 /* wait 20 ms */
90                 while (1) {
91                         diff = TCNT0 - t;
92                         if (diff >= 160)
93                                 break;
94                         poll_spi();
95                 }
96         }
97
98         return 0;
99 }