Subversion Repositories FlightCtrl

Rev

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