Subversion Repositories FlightCtrl

Rev

Rev 1461 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1455 acid 1
 
2
#include <string.h>
3
#include <avr/interrupt.h>
4
#include <avr/eeprom.h>
5
#include <util/delay.h>
6
#include "servoboard.h"
7
#include "twislave.h"
1459 acid 8
#include "uart.h"
1455 acid 9
 
10
 
1461 acid 11
uint8_t eeprom_neutral_pos[6] EEMEM;
12
uint16_t eeprom_pwm_limit[6] EEMEM;
1459 acid 13
 
1461 acid 14
volatile uint8_t pwm_signal[6];
15
volatile uint8_t pwm_neutral_position[6];
16
volatile uint8_t pwm_position[6];
17
volatile uint16_t pwm_limit[6];
18
volatile uint8_t pwm_active;
1455 acid 19
 
20
 
21
void pwm_init() {
22
 
23
        SERVODDR = 0xff;
24
 
25
        set_pwm();
26
 
27
        TCCR1B = (1 << CS11);
28
        TCCR0 = (1 << CS00);
29
 
30
}
31
 
32
void set_pwm() {
33
 
34
        for(uint8_t n = 0; n < 6; n++) {
35
                pwm_signal[n] = pwm_position[n] - 127 + pwm_neutral_position[n];
36
                if (pwm_limit[n] != 0) {
37
                        uint8_t l, h;
38
                        l = pwm_limit[n] & 0xff;
39
                        h = pwm_limit[n] >> 8;
40
                        if (pwm_signal[n] < l) {
41
                                pwm_signal[n] = l;
42
                        }
43
                        if (pwm_signal[n] > h) {
44
                                pwm_signal[n] = h;
45
                        }
46
                }
47
        }
48
 
49
}
50
 
51
void set_pwm_neutral() {
52
 
53
        for(uint8_t i = 0; i < 6; i++) {
54
                pwm_position[i] = 127;
55
        }
56
        set_pwm();
57
 
58
}
59
 
1461 acid 60
void pwm_check_active() {
61
 
62
        // check if pwm is configured
63
        pwm_active  = (pwm_limit[0] != 0xffff) ? (1 << SERVO1) : 0;
64
        pwm_active |= (pwm_limit[1] != 0xffff) ? (2 << SERVO1) : 0;
65
        pwm_active |= (pwm_limit[2] != 0xffff) ? (3 << SERVO1) : 0;
66
        pwm_active |= (pwm_limit[3] != 0xffff) ? (4 << SERVO1) : 0;
67
        pwm_active |= (pwm_limit[4] != 0xffff) ? (5 << SERVO1) : 0;
68
        pwm_active |= (pwm_limit[5] != 0xffff) ? (6 << SERVO1) : 0;
69
 
70
}
71
 
72
 
1455 acid 73
void eeprom_init() {
74
 
75
        eeprom_busy_wait();
1459 acid 76
        eeprom_read_block(&pwm_neutral_position[0], &eeprom_neutral_pos, sizeof(pwm_neutral_position));
77
        eeprom_read_block(&pwm_limit[0], &eeprom_pwm_limit, sizeof(pwm_limit));
1461 acid 78
        pwm_check_active();
1455 acid 79
 
80
}
81
 
82
void eeprom_write() {
83
 
84
        cli();
1459 acid 85
        eeprom_write_block(&pwm_neutral_position[0], &eeprom_neutral_pos, sizeof(pwm_neutral_position));
86
        eeprom_write_block(&pwm_limit[0], &eeprom_pwm_limit, sizeof(pwm_limit));
1455 acid 87
        sei();
88
 
89
}
90
 
91
void delay(int ms) {
92
 
93
        while(ms--) {
94
                _delay_ms(1);
95
        }
96
 
97
}
98
 
99
 
100
int main(void) {
101
 
1461 acid 102
        uint8_t blink_counter = 0;
103
        uint8_t blink = 0;
104
 
105
        // intialize
1456 acid 106
        DDRD = 0x80;
107
        PORTD = 0x80;
1455 acid 108
 
109
        DDRC &= ~0x0f;
110
        PORTC |= 0x0f;
111
 
112
        cli();
1459 acid 113
        uart_init();
1455 acid 114
        eeprom_init();
1459 acid 115
        i2c_init(0x82);
1455 acid 116
        pwm_init();
1456 acid 117
        set_pwm_neutral();
1455 acid 118
        sei();
119
 
1461 acid 120
        // start pwm
1455 acid 121
        TCNT1 = 0;
122
        while(1) {
123
 
124
                cli();
1461 acid 125
                SERVOPORT = pwm_active;
126
 
127
                // show status
128
                blink_counter++;
129
 
130
                if (pwm_active == 0) { // not configured
131
 
132
                        blink = 50;
133
 
134
                } else {
135
 
136
                        if (I2C_timeout == 0) { // no i2c signal
137
                                blink = 0;
138
                        } else {
139
                                I2C_timeout--;
140
                                blink = 5;
141
                        }
142
 
143
                }
144
 
145
                if (blink == 0) {
146
                        LED_ON;
147
                } else if (blink_counter % blink == 0) {
148
                        blink_counter = 1;
149
                        if (LED_IS_ON) {
150
                                LED_OFF;
151
                        } else {
152
                                LED_ON;
153
                        }
154
                }
155
 
156
                // wait with high pwm signal
1455 acid 157
                while(TCNT1 < 300) ;
158
 
1461 acid 159
                // check servos setting pwm to low
1455 acid 160
                for(uint8_t i = 0; i < 255; i++) {
161
 
162
                        TCNT0 = 0;
163
 
164
                        if (i == pwm_signal[0]) {
165
                                SERVOPORT &= ~(1<<SERVO1);
166
                        }
167
                        if (i == pwm_signal[1]) {
168
                                SERVOPORT &= ~(1<<SERVO2);
169
                        }
170
                        if (i == pwm_signal[2]) {
171
                                SERVOPORT &= ~(1<<SERVO3);
172
                        }
173
                        if (i == pwm_signal[3]) {
174
                                SERVOPORT &= ~(1<<SERVO4);
175
                        }
176
                        if (i == pwm_signal[4]) {
177
                                SERVOPORT &= ~(1<<SERVO5);
178
                        }
179
                        if (i == pwm_signal[5]) {
180
                                SERVOPORT &= ~(1<<SERVO6);
181
                        }
182
 
183
                        while (TCNT0 < 60) ;
184
 
185
                }
186
                sei();
187
 
1461 acid 188
                // set all servos to low
1455 acid 189
                SERVOPORT = 0;
190
 
1461 acid 191
                // update signals
1455 acid 192
                set_pwm();
193
 
1461 acid 194
                // wait till 20ms are reached
1455 acid 195
                while(TCNT1 < 20000) ;
196
                TCNT1 = 0;
197
 
198
        }
199
 
200
        return 0;
201
}
202