Subversion Repositories FlightCtrl

Rev

Rev 1466 | 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];
1475 acid 15
uint8_t volatile pwm_neutral_position[6];
16
uint8_t volatile pwm_position[6];
17
uint16_t volatile pwm_limit[6];
1465 acid 18
uint8_t pwm_active;
19
uint8_t pwm_status = 1;
1475 acid 20
#if DEBUG_SIGNAL
21
uint8_t volatile display_values = 0;
22
#endif
1455 acid 23
 
24
void pwm_init() {
25
 
1475 acid 26
        SERVODDR = (1<<SERVO1) | (1<<SERVO2) | (1<<SERVO3) | (1<<SERVO4) | (1<<SERVO5) | (1<<SERVO6);
1455 acid 27
 
28
        set_pwm();
29
 
30
        TCCR1B = (1 << CS11);
31
        TCCR0 = (1 << CS00);
32
 
33
}
34
 
35
void set_pwm() {
36
 
37
        for(uint8_t n = 0; n < 6; n++) {
38
                pwm_signal[n] = pwm_position[n] - 127 + pwm_neutral_position[n];
39
                if (pwm_limit[n] != 0) {
40
                        uint8_t l, h;
41
                        l = pwm_limit[n] & 0xff;
42
                        h = pwm_limit[n] >> 8;
43
                        if (pwm_signal[n] < l) {
44
                                pwm_signal[n] = l;
45
                        }
46
                        if (pwm_signal[n] > h) {
47
                                pwm_signal[n] = h;
48
                        }
49
                }
50
        }
51
 
52
}
53
 
54
void set_pwm_neutral() {
55
 
56
        for(uint8_t i = 0; i < 6; i++) {
57
                pwm_position[i] = 127;
58
        }
59
        set_pwm();
60
 
61
}
62
 
1461 acid 63
void pwm_check_active() {
64
 
65
        // check if pwm is configured
1475 acid 66
        pwm_active  = (pwm_limit[0] != 0xffff) ? (1<<SERVO1) : 0;
67
        pwm_active |= (pwm_limit[1] != 0xffff) ? (1<<SERVO2) : 0;
68
        pwm_active |= (pwm_limit[2] != 0xffff) ? (1<<SERVO3) : 0;
69
        pwm_active |= (pwm_limit[3] != 0xffff) ? (1<<SERVO4) : 0;
70
        pwm_active |= (pwm_limit[4] != 0xffff) ? (1<<SERVO5) : 0;
71
        pwm_active |= (pwm_limit[5] != 0xffff) ? (1<<SERVO6) : 0;
1461 acid 72
 
73
}
74
 
75
 
1455 acid 76
void eeprom_init() {
77
 
78
        eeprom_busy_wait();
1459 acid 79
        eeprom_read_block(&pwm_neutral_position[0], &eeprom_neutral_pos, sizeof(pwm_neutral_position));
80
        eeprom_read_block(&pwm_limit[0], &eeprom_pwm_limit, sizeof(pwm_limit));
1461 acid 81
        pwm_check_active();
1455 acid 82
 
83
}
84
 
85
void eeprom_write() {
86
 
87
        cli();
1459 acid 88
        eeprom_write_block(&pwm_neutral_position[0], &eeprom_neutral_pos, sizeof(pwm_neutral_position));
89
        eeprom_write_block(&pwm_limit[0], &eeprom_pwm_limit, sizeof(pwm_limit));
1455 acid 90
        sei();
91
 
92
}
93
 
1475 acid 94
/*
1455 acid 95
void delay(int ms) {
96
 
97
        while(ms--) {
98
                _delay_ms(1);
99
        }
100
 
101
}
1475 acid 102
*/
1455 acid 103
 
104
int main(void) {
105
 
1461 acid 106
        uint8_t blink_counter = 0;
107
        uint8_t blink = 0;
108
 
109
        // intialize
1475 acid 110
        DDRD = (1<<PD7);
111
        PORTD = (1<<PD7);
1455 acid 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
 
121
        while(1) {
122
 
1475 acid 123
                // start pwm
1455 acid 124
                cli();
1475 acid 125
                TCNT1 = 0;
1461 acid 126
                SERVOPORT = pwm_active;
127
 
1475 acid 128
                // update signals
129
                set_pwm();
130
 
1461 acid 131
                // show status
132
                blink_counter++;
133
 
134
                if (pwm_active == 0) { // not configured
135
 
136
                        blink = 50;
1465 acid 137
                        pwm_status = 1;
1461 acid 138
 
139
                } else {
140
 
1475 acid 141
                        if (I2C_timeout) {
1461 acid 142
                                I2C_timeout--;
1466 acid 143
                                if (I2C_timeout == 0) { // no i2c signal
144
                                        blink = 0;
145
                                        pwm_status = 2;
1465 acid 146
                                        set_pwm_neutral();
147
                                        set_pwm();
148
                                }
1461 acid 149
                                blink = 5;
1465 acid 150
                                pwm_status = 0;
1461 acid 151
                        }
152
 
153
                }
154
 
155
                if (blink == 0) {
156
                        LED_ON;
157
                } else if (blink_counter % blink == 0) {
158
                        blink_counter = 1;
159
                        if (LED_IS_ON) {
1464 acid 160
                                LED_OFF;
1461 acid 161
                        } else {
162
                                LED_ON;
163
                        }
164
                }
165
 
1475 acid 166
                // till here the code execution takes less than 70ys, plenty enough time for some more calculations
167
 
168
                // wait till 300ys are reached
1455 acid 169
                while(TCNT1 < 300) ;
170
 
1475 acid 171
                // check servo settings and set pwm to low
1455 acid 172
                for(uint8_t i = 0; i < 255; i++) {
173
 
174
                        TCNT0 = 0;
175
 
176
                        if (i == pwm_signal[0]) {
177
                                SERVOPORT &= ~(1<<SERVO1);
178
                        }
179
                        if (i == pwm_signal[1]) {
180
                                SERVOPORT &= ~(1<<SERVO2);
181
                        }
182
                        if (i == pwm_signal[2]) {
183
                                SERVOPORT &= ~(1<<SERVO3);
184
                        }
185
                        if (i == pwm_signal[3]) {
186
                                SERVOPORT &= ~(1<<SERVO4);
187
                        }
188
                        if (i == pwm_signal[4]) {
189
                                SERVOPORT &= ~(1<<SERVO5);
190
                        }
191
                        if (i == pwm_signal[5]) {
192
                                SERVOPORT &= ~(1<<SERVO6);
193
                        }
194
 
195
                        while (TCNT0 < 60) ;
196
 
197
                }
198
 
1461 acid 199
                // set all servos to low
1455 acid 200
                SERVOPORT = 0;
201
 
1475 acid 202
                // enable interrupts and receive data while waiting till 20ms are reached and the next pulse has to be sent
203
                sei();
1455 acid 204
 
1475 acid 205
#if DEBUG_SIGNAL
206
                if (display_values) {
207
 
208
                        cli();
209
                        uart_putchar('\r');
210
                        for(uint8_t i = 0; i < 6; i++) {
211
                                uart_putchar(i+49);
212
                                uart_putchar(':');
213
                                uart_putchar((pwm_signal[i]/100)%10+48);
214
                                uart_putchar((pwm_signal[i]/10)%10+48);
215
                                uart_putchar((pwm_signal[i])%10+48);
216
                                uart_putchar(' ');
217
                        }
218
                        sei();
219
 
220
                }
221
#endif
222
 
1455 acid 223
                while(TCNT1 < 20000) ;
224
 
1475 acid 225
 
1455 acid 226
        }
227
 
228
        return 0;
229
}
230