Subversion Repositories FlightCtrl

Rev

Rev 2159 | Rev 2164 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2159 Rev 2160
1
#include <avr/io.h>
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
2
#include <avr/interrupt.h>
3
#include <avr/wdt.h>
3
#include <avr/wdt.h>
4
#include <avr/pgmspace.h>
4
#include <avr/pgmspace.h>
5
#include <stdarg.h>
5
#include <stdarg.h>
6
#include <string.h>
6
#include <string.h>
7
 
7
 
8
#include "eeprom.h"
8
#include "eeprom.h"
9
#include "menu.h"
9
#include "menu.h"
10
#include "timer0.h"
10
#include "timer0.h"
11
#include "uart0.h"
11
#include "uart0.h"
12
#include "rc.h"
12
#include "rc.h"
13
#include "externalControl.h"
13
#include "externalControl.h"
14
#include "output.h"
14
#include "output.h"
15
#include "attitude.h"
15
#include "attitude.h"
16
#include "commands.h"
16
#include "commands.h"
17
 
17
 
18
#ifdef USE_DIRECT_GPS
18
#ifdef USE_DIRECT_GPS
19
#include "mk3mag.h"
19
#include "mk3mag.h"
20
#endif
20
#endif
21
 
21
 
22
#define FC_ADDRESS 1
22
#define FC_ADDRESS 1
23
#define NC_ADDRESS 2
23
#define NC_ADDRESS 2
24
#define MK3MAG_ADDRESS 3
24
#define MK3MAG_ADDRESS 3
25
 
25
 
26
#define FALSE   0
26
#define FALSE   0
27
#define TRUE    1
27
#define TRUE    1
28
 
28
 
29
uint8_t requestedDebugLabel = 255;
29
uint8_t requestedDebugLabel = 255;
30
 
30
 
31
uint8_t request_verInfo = FALSE;
31
uint8_t request_verInfo = FALSE;
32
uint8_t request_externalControl = FALSE;
32
uint8_t request_externalControl = FALSE;
33
uint8_t request_display = FALSE;
33
uint8_t request_display = FALSE;
34
uint8_t request_display1 = FALSE;
34
uint8_t request_display1 = FALSE;
35
uint8_t request_debugData = FALSE;
35
uint8_t request_debugData = FALSE;
36
uint8_t request_data3D = FALSE;
36
uint8_t request_data3D = FALSE;
37
uint8_t request_PPMChannels = FALSE;
37
uint8_t request_PPMChannels = FALSE;
38
uint8_t request_motorTest = FALSE;
38
uint8_t request_motorTest = FALSE;
39
uint8_t request_variables = FALSE;
39
uint8_t request_variables = FALSE;
40
uint8_t request_OSD = FALSE;
40
uint8_t request_OSD = FALSE;
41
 
41
 
42
/*
42
/*
43
#define request_verInfo         (1<<0)
43
#define request_verInfo         (1<<0)
44
#define request_externalControl (1<<1)
44
#define request_externalControl (1<<1)
45
#define request_display         (1<<3)
45
#define request_display         (1<<3)
46
#define request_display1        (1<<4)
46
#define request_display1        (1<<4)
47
#define request_debugData       (1<<5)
47
#define request_debugData       (1<<5)
48
#define request_data3D          (1<<6)
48
#define request_data3D          (1<<6)
49
#define request_PPMChannels     (1<<7)
49
#define request_PPMChannels     (1<<7)
50
#define request_motorTest       (1<<8)
50
#define request_motorTest       (1<<8)
51
#define request_variables       (1<<9)
51
#define request_variables       (1<<9)
52
#define request_OSD             (1<<10)
52
#define request_OSD             (1<<10)
53
*/
53
*/
54
 
54
 
55
//uint16_t request = 0;
55
//uint16_t request = 0;
56
 
56
 
57
uint8_t displayLine = 0;
57
uint8_t displayLine = 0;
58
 
58
 
59
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
59
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
60
volatile uint8_t rxd_buffer_locked = FALSE;
60
volatile uint8_t rxd_buffer_locked = FALSE;
61
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
61
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
62
volatile uint8_t txd_complete = TRUE;
62
volatile uint8_t txd_complete = TRUE;
63
volatile uint8_t receivedBytes = 0;
63
volatile uint8_t receivedBytes = 0;
64
volatile uint8_t *pRxData = 0;
64
volatile uint8_t *pRxData = 0;
65
volatile uint8_t rxDataLen = 0;
65
volatile uint8_t rxDataLen = 0;
66
 
66
 
67
uint8_t motorTestActive = 0;
67
uint8_t motorTestActive = 0;
68
uint8_t motorTest[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
68
uint8_t motorTest[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
69
uint8_t confirmFrame;
69
uint8_t confirmFrame;
70
 
70
 
71
typedef struct {
71
typedef struct {
72
        int16_t heading;
72
        int16_t heading;
73
}__attribute__((packed)) Heading_t;
73
}__attribute__((packed)) Heading_t;
74
 
74
 
75
Data3D_t data3D;
75
Data3D_t data3D;
76
 
76
 
77
uint16_t debugData_timer;
77
uint16_t debugData_timer;
78
uint16_t data3D_timer;
78
uint16_t data3D_timer;
79
uint16_t OSD_timer;
79
uint16_t OSD_timer;
80
uint16_t debugData_interval = 0; // in 1ms
80
uint16_t debugData_interval = 0; // in 1ms
81
uint16_t data3D_interval = 0; // in 1ms
81
uint16_t data3D_interval = 0; // in 1ms
82
uint16_t OSD_interval = 0;
82
uint16_t OSD_interval = 0;
83
 
83
 
84
#ifdef USE_DIRECT_GPS
84
#ifdef USE_DIRECT_GPS
85
int16_t toMk3MagTimer;
85
int16_t toMk3MagTimer;
86
#endif
86
#endif
87
 
87
 
88
// keep lables in flash to save 512 bytes of sram space
88
// keep lables in flash to save 512 bytes of sram space
89
const prog_uint8_t ANALOG_LABEL[32][16] = {
89
const prog_uint8_t ANALOG_LABEL[32][16] = {
90
                //1234567890123456
90
                //1234567890123456
91
                "AnglePitch      ", //0
91
                "AnglePitch      ", //0
92
                "AngleRoll       ",
92
                "AngleRoll       ",
93
                "AngleYaw        ",
93
                "AngleYaw        ",
94
                "GyroPitch       ",
94
                "GyroPitch       ",
95
                "GyroRoll        ",
95
                "GyroRoll        ",
96
                "GyroYaw         ", //5
96
                "GyroYaw         ", //5
97
                "PitchTerm       ",
97
                "correctionSum pi",
98
                "RollTerm        ",
98
                "correctionSum ro",
99
                "ThrottleTerm    ",
99
                "ThrottleTerm    ",
100
                "YawTerm         ",
100
                "YawTerm         ",
101
                "heightP         ", //10
101
                "gyroDPitch      ", //10
102
                "heightI         ",
102
                "gyroDRoll       ",
103
        "heightD         ",
103
        "zerothOrderCorr ",
104
                "gyroActivity    ",
104
                "DriftCompPitch  ",
105
                "ca              ",
105
                "DriftCompRoll   ",
106
                "GActivityDivider", //15
106
                "GActivityDivider", //15
107
                "NaviMode        ",
107
                "AccPitch        ",
108
                "NaviStatus      ",
108
                "AccRoll         ",
109
        "NaviStickP      ",
109
        "                ",
110
                "NaviStickR      ",
110
                "                ",
111
                "control act wghd", //20
111
                "control act wghd", //20
112
                "acc vector wghd ",
112
                "acc vector wghd ",
113
                "Height[dm]      ",
113
                "Height[dm]      ",
114
                "dHeight         ",
114
                "dHeight         ",
115
                "acc vector      ",
115
                "acc vector      ",
116
                "EFT             ", //25
116
                "EFT             ", //25
117
                "naviPitch       ",
117
                "naviPitch       ",
118
                "naviRoll        ",
118
                "naviRoll        ",
119
                "tolerance       ",
119
                "Rate Tolerance  ",
120
                "Gyro Act Cont.  ",
120
                "Gyro Act Cont.  ",
121
                "GPS altitude    ", //30
121
                "GPS altitude    ", //30
122
                "GPS vert accura "
122
                "GPS vert accura "
123
  };
123
  };
124
 
124
 
125
/****************************************************************/
125
/****************************************************************/
126
/*              Initialization of the USART0                    */
126
/*              Initialization of the USART0                    */
127
/****************************************************************/
127
/****************************************************************/
128
void usart0_init(void) {
128
void usart0_init(void) {
129
        uint8_t sreg = SREG;
129
        uint8_t sreg = SREG;
130
        uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * USART0_BAUD) - 1);
130
        uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * USART0_BAUD) - 1);
131
 
131
 
132
        // disable all interrupts before configuration
132
        // disable all interrupts before configuration
133
        cli();
133
        cli();
134
 
134
 
135
        // disable RX-Interrupt
135
        // disable RX-Interrupt
136
        UCSR0B &= ~(1 << RXCIE0);
136
        UCSR0B &= ~(1 << RXCIE0);
137
        // disable TX-Interrupt
137
        // disable TX-Interrupt
138
        UCSR0B &= ~(1 << TXCIE0);
138
        UCSR0B &= ~(1 << TXCIE0);
139
 
139
 
140
        // set direction of RXD0 and TXD0 pins
140
        // set direction of RXD0 and TXD0 pins
141
        // set RXD0 (PD0) as an input pin
141
        // set RXD0 (PD0) as an input pin
142
        PORTD |= (1 << PORTD0);
142
        PORTD |= (1 << PORTD0);
143
        DDRD &= ~(1 << DDD0);
143
        DDRD &= ~(1 << DDD0);
144
        // set TXD0 (PD1) as an output pin
144
        // set TXD0 (PD1) as an output pin
145
        PORTD |= (1 << PORTD1);
145
        PORTD |= (1 << PORTD1);
146
        DDRD |= (1 << DDD1);
146
        DDRD |= (1 << DDD1);
147
 
147
 
148
        // USART0 Baud Rate Register
148
        // USART0 Baud Rate Register
149
        // set clock divider
149
        // set clock divider
150
        UBRR0H = (uint8_t) (ubrr >> 8);
150
        UBRR0H = (uint8_t) (ubrr >> 8);
151
        UBRR0L = (uint8_t) ubrr;
151
        UBRR0L = (uint8_t) ubrr;
152
 
152
 
153
        // USART0 Control and Status Register A, B, C
153
        // USART0 Control and Status Register A, B, C
154
 
154
 
155
        // enable double speed operation in
155
        // enable double speed operation in
156
        UCSR0A |= (1 << U2X0);
156
        UCSR0A |= (1 << U2X0);
157
        // enable receiver and transmitter in
157
        // enable receiver and transmitter in
158
        UCSR0B = (1 << TXEN0) | (1 << RXEN0);
158
        UCSR0B = (1 << TXEN0) | (1 << RXEN0);
159
        // set asynchronous mode
159
        // set asynchronous mode
160
        UCSR0C &= ~(1 << UMSEL01);
160
        UCSR0C &= ~(1 << UMSEL01);
161
        UCSR0C &= ~(1 << UMSEL00);
161
        UCSR0C &= ~(1 << UMSEL00);
162
        // no parity
162
        // no parity
163
        UCSR0C &= ~(1 << UPM01);
163
        UCSR0C &= ~(1 << UPM01);
164
        UCSR0C &= ~(1 << UPM00);
164
        UCSR0C &= ~(1 << UPM00);
165
        // 1 stop bit
165
        // 1 stop bit
166
        UCSR0C &= ~(1 << USBS0);
166
        UCSR0C &= ~(1 << USBS0);
167
        // 8-bit
167
        // 8-bit
168
        UCSR0B &= ~(1 << UCSZ02);
168
        UCSR0B &= ~(1 << UCSZ02);
169
        UCSR0C |= (1 << UCSZ01);
169
        UCSR0C |= (1 << UCSZ01);
170
        UCSR0C |= (1 << UCSZ00);
170
        UCSR0C |= (1 << UCSZ00);
171
 
171
 
172
        // flush receive buffer
172
        // flush receive buffer
173
        while (UCSR0A & (1 << RXC0))
173
        while (UCSR0A & (1 << RXC0))
174
                UDR0;
174
                UDR0;
175
 
175
 
176
        // enable interrupts at the end
176
        // enable interrupts at the end
177
        // enable RX-Interrupt
177
        // enable RX-Interrupt
178
        UCSR0B |= (1 << RXCIE0);
178
        UCSR0B |= (1 << RXCIE0);
179
        // enable TX-Interrupt
179
        // enable TX-Interrupt
180
        UCSR0B |= (1 << TXCIE0);
180
        UCSR0B |= (1 << TXCIE0);
181
 
181
 
182
        // initialize the debug timer
182
        // initialize the debug timer
183
        debugData_timer = setDelay(debugData_interval);
183
        debugData_timer = setDelay(debugData_interval);
184
 
184
 
185
        // unlock rxd_buffer
185
        // unlock rxd_buffer
186
        rxd_buffer_locked = FALSE;
186
        rxd_buffer_locked = FALSE;
187
        pRxData = 0;
187
        pRxData = 0;
188
        rxDataLen = 0;
188
        rxDataLen = 0;
189
 
189
 
190
        // no bytes to send
190
        // no bytes to send
191
        txd_complete = TRUE;
191
        txd_complete = TRUE;
192
 
192
 
193
#ifdef USE_DIRECT_GPS
193
#ifdef USE_DIRECT_GPS
194
        toMk3MagTimer = setDelay(220);
194
        toMk3MagTimer = setDelay(220);
195
#endif
195
#endif
196
 
196
 
197
        versionInfo.SWMajor = VERSION_MAJOR;
197
        versionInfo.SWMajor = VERSION_MAJOR;
198
        versionInfo.SWMinor = VERSION_MINOR;
198
        versionInfo.SWMinor = VERSION_MINOR;
199
        versionInfo.SWPatch = VERSION_PATCH;
199
        versionInfo.SWPatch = VERSION_PATCH;
200
        versionInfo.protoMajor = VERSION_SERIAL_MAJOR;
200
        versionInfo.protoMajor = VERSION_SERIAL_MAJOR;
201
        versionInfo.protoMinor = VERSION_SERIAL_MINOR;
201
        versionInfo.protoMinor = VERSION_SERIAL_MINOR;
202
 
202
 
203
        // restore global interrupt flags
203
        // restore global interrupt flags
204
        SREG = sreg;
204
        SREG = sreg;
205
}
205
}
206
 
206
 
207
/****************************************************************/
207
/****************************************************************/
208
/* USART0 transmitter ISR                                       */
208
/* USART0 transmitter ISR                                       */
209
/****************************************************************/
209
/****************************************************************/
210
ISR(USART0_TX_vect) {
210
ISR(USART0_TX_vect) {
211
        static uint16_t ptr_txd_buffer = 0;
211
        static uint16_t ptr_txd_buffer = 0;
212
        uint8_t tmp_tx;
212
        uint8_t tmp_tx;
213
        if (!txd_complete) { // transmission not completed
213
        if (!txd_complete) { // transmission not completed
214
                ptr_txd_buffer++; // die [0] wurde schon gesendet
214
                ptr_txd_buffer++; // die [0] wurde schon gesendet
215
                tmp_tx = txd_buffer[ptr_txd_buffer];
215
                tmp_tx = txd_buffer[ptr_txd_buffer];
216
                // if terminating character or end of txd buffer was reached
216
                // if terminating character or end of txd buffer was reached
217
                if ((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) {
217
                if ((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) {
218
                        ptr_txd_buffer = 0; // reset txd pointer
218
                        ptr_txd_buffer = 0; // reset txd pointer
219
                        txd_complete = 1; // stop transmission
219
                        txd_complete = 1; // stop transmission
220
                }
220
                }
221
                UDR0 = tmp_tx; // send current byte will trigger this ISR again
221
                UDR0 = tmp_tx; // send current byte will trigger this ISR again
222
        }
222
        }
223
        // transmission completed
223
        // transmission completed
224
        else
224
        else
225
                ptr_txd_buffer = 0;
225
                ptr_txd_buffer = 0;
226
}
226
}
227
 
227
 
228
/****************************************************************/
228
/****************************************************************/
229
/* USART0 receiver               ISR                            */
229
/* USART0 receiver               ISR                            */
230
/****************************************************************/
230
/****************************************************************/
231
ISR(USART0_RX_vect) {
231
ISR(USART0_RX_vect) {
232
        static uint16_t checksum;
232
        static uint16_t checksum;
233
        static uint8_t ptr_rxd_buffer = 0;
233
        static uint8_t ptr_rxd_buffer = 0;
234
        uint8_t checksum1, checksum2;
234
        uint8_t checksum1, checksum2;
235
        uint8_t c;
235
        uint8_t c;
236
 
236
 
237
        c = UDR0; // catch the received byte
237
        c = UDR0; // catch the received byte
238
 
238
 
239
        if (rxd_buffer_locked)
239
        if (rxd_buffer_locked)
240
                return; // if rxd buffer is locked immediately return
240
                return; // if rxd buffer is locked immediately return
241
 
241
 
242
        // the rxd buffer is unlocked
242
        // the rxd buffer is unlocked
243
        if ((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received
243
        if ((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received
244
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
244
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
245
                checksum = c; // init checksum
245
                checksum = c; // init checksum
246
        }
246
        }
247
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes
247
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes
248
                if (c != '\r') { // no termination character
248
                if (c != '\r') { // no termination character
249
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
249
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
250
                        checksum += c; // update checksum
250
                        checksum += c; // update checksum
251
                } else { // termination character was received
251
                } else { // termination character was received
252
                        // the last 2 bytes are no subject for checksum calculation
252
                        // the last 2 bytes are no subject for checksum calculation
253
                        // they are the checksum itself
253
                        // they are the checksum itself
254
                        checksum -= rxd_buffer[ptr_rxd_buffer - 2];
254
                        checksum -= rxd_buffer[ptr_rxd_buffer - 2];
255
                        checksum -= rxd_buffer[ptr_rxd_buffer - 1];
255
                        checksum -= rxd_buffer[ptr_rxd_buffer - 1];
256
                        // calculate checksum from transmitted data
256
                        // calculate checksum from transmitted data
257
                        checksum %= 4096;
257
                        checksum %= 4096;
258
                        checksum1 = '=' + checksum / 64;
258
                        checksum1 = '=' + checksum / 64;
259
                        checksum2 = '=' + checksum % 64;
259
                        checksum2 = '=' + checksum % 64;
260
                        // compare checksum to transmitted checksum bytes
260
                        // compare checksum to transmitted checksum bytes
261
                        if ((checksum1 == rxd_buffer[ptr_rxd_buffer - 2]) && (checksum2
261
                        if ((checksum1 == rxd_buffer[ptr_rxd_buffer - 2]) && (checksum2
262
                                        == rxd_buffer[ptr_rxd_buffer - 1])) {
262
                                        == rxd_buffer[ptr_rxd_buffer - 1])) {
263
                                // checksum valid
263
                                // checksum valid
264
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
264
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
265
                                receivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
265
                                receivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
266
                                rxd_buffer_locked = TRUE; // lock the rxd buffer
266
                                rxd_buffer_locked = TRUE; // lock the rxd buffer
267
                                // if 2nd byte is an 'R' enable watchdog that will result in an reset
267
                                // if 2nd byte is an 'R' enable watchdog that will result in an reset
268
                                if (rxd_buffer[2] == 'R') {
268
                                if (rxd_buffer[2] == 'R') {
269
                                        wdt_enable(WDTO_250MS);
269
                                        wdt_enable(WDTO_250MS);
270
                                } // Reset-Commando
270
                                } // Reset-Commando
271
                        } else { // checksum invalid
271
                        } else { // checksum invalid
272
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
272
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
273
                        }
273
                        }
274
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
274
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
275
                }
275
                }
276
        } else { // rxd buffer overrun
276
        } else { // rxd buffer overrun
277
                ptr_rxd_buffer = 0; // reset rxd buffer
277
                ptr_rxd_buffer = 0; // reset rxd buffer
278
                rxd_buffer_locked = FALSE; // unlock rxd buffer
278
                rxd_buffer_locked = FALSE; // unlock rxd buffer
279
        }
279
        }
280
}
280
}
281
 
281
 
282
// --------------------------------------------------------------------------
282
// --------------------------------------------------------------------------
283
void addChecksum(uint16_t datalen) {
283
void addChecksum(uint16_t datalen) {
284
        uint16_t tmpchecksum = 0, i;
284
        uint16_t tmpchecksum = 0, i;
285
        for (i = 0; i < datalen; i++) {
285
        for (i = 0; i < datalen; i++) {
286
                tmpchecksum += txd_buffer[i];
286
                tmpchecksum += txd_buffer[i];
287
        }
287
        }
288
        tmpchecksum %= 4096;
288
        tmpchecksum %= 4096;
289
        txd_buffer[i++] = '=' + (tmpchecksum >> 6);
289
        txd_buffer[i++] = '=' + (tmpchecksum >> 6);
290
        txd_buffer[i++] = '=' + (tmpchecksum & 0x3F);
290
        txd_buffer[i++] = '=' + (tmpchecksum & 0x3F);
291
        txd_buffer[i++] = '\r';
291
        txd_buffer[i++] = '\r';
292
        txd_complete = FALSE;
292
        txd_complete = FALSE;
293
        UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
293
        UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
294
}
294
}
295
 
295
 
296
// --------------------------------------------------------------------------
296
// --------------------------------------------------------------------------
297
// application example:
297
// application example:
298
// sendOutData('A', FC_ADDRESS, 2, (uint8_t *)&request_DebugLabel, sizeof(request_DebugLabel), label, 16);
298
// sendOutData('A', FC_ADDRESS, 2, (uint8_t *)&request_DebugLabel, sizeof(request_DebugLabel), label, 16);
299
/*
299
/*
300
 void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
300
 void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
301
 va_list ap;
301
 va_list ap;
302
 uint16_t txd_bufferIndex = 0;
302
 uint16_t txd_bufferIndex = 0;
303
 uint8_t *currentBuffer;
303
 uint8_t *currentBuffer;
304
 uint8_t currentBufferIndex;
304
 uint8_t currentBufferIndex;
305
 uint16_t lengthOfCurrentBuffer;
305
 uint16_t lengthOfCurrentBuffer;
306
 uint8_t shift = 0;
306
 uint8_t shift = 0;
307
 
307
 
308
 txd_buffer[txd_bufferIndex++] = '#';                   // Start character
308
 txd_buffer[txd_bufferIndex++] = '#';                   // Start character
309
 txd_buffer[txd_bufferIndex++] = 'a' + addr;            // Address (a=0; b=1,...)
309
 txd_buffer[txd_bufferIndex++] = 'a' + addr;            // Address (a=0; b=1,...)
310
 txd_buffer[txd_bufferIndex++] = cmd;                   // Command
310
 txd_buffer[txd_bufferIndex++] = cmd;                   // Command
311
 
311
 
312
 va_start(ap, numofbuffers);
312
 va_start(ap, numofbuffers);
313
 
313
 
314
 while(numofbuffers) {
314
 while(numofbuffers) {
315
 currentBuffer = va_arg(ap, uint8_t*);
315
 currentBuffer = va_arg(ap, uint8_t*);
316
 lengthOfCurrentBuffer = va_arg(ap, int);
316
 lengthOfCurrentBuffer = va_arg(ap, int);
317
 currentBufferIndex = 0;
317
 currentBufferIndex = 0;
318
 // Encode data: 3 bytes of data are encoded into 4 bytes,
318
 // Encode data: 3 bytes of data are encoded into 4 bytes,
319
 // where the 2 most significant bits are both 0.
319
 // where the 2 most significant bits are both 0.
320
 while(currentBufferIndex != lengthOfCurrentBuffer) {
320
 while(currentBufferIndex != lengthOfCurrentBuffer) {
321
 if (!shift) txd_buffer[txd_bufferIndex] = 0;
321
 if (!shift) txd_buffer[txd_bufferIndex] = 0;
322
 txd_buffer[txd_bufferIndex]  |= currentBuffer[currentBufferIndex] >> (shift + 2);
322
 txd_buffer[txd_bufferIndex]  |= currentBuffer[currentBufferIndex] >> (shift + 2);
323
 txd_buffer[++txd_bufferIndex] = (currentBuffer[currentBufferIndex] << (4 - shift)) & 0b00111111;
323
 txd_buffer[++txd_bufferIndex] = (currentBuffer[currentBufferIndex] << (4 - shift)) & 0b00111111;
324
 shift += 2;
324
 shift += 2;
325
 if (shift == 6) { shift=0; txd_bufferIndex++; }
325
 if (shift == 6) { shift=0; txd_bufferIndex++; }
326
 currentBufferIndex++;
326
 currentBufferIndex++;
327
 }
327
 }
328
 }
328
 }
329
 // If the number of data bytes was not divisible by 3, stuff
329
 // If the number of data bytes was not divisible by 3, stuff
330
 //  with 0 pseudodata  until length is again divisible by 3.
330
 //  with 0 pseudodata  until length is again divisible by 3.
331
 if (shift == 2) {
331
 if (shift == 2) {
332
 // We need to stuff with zero bytes at the end.
332
 // We need to stuff with zero bytes at the end.
333
 txd_buffer[txd_bufferIndex]  &= 0b00110000;
333
 txd_buffer[txd_bufferIndex]  &= 0b00110000;
334
 txd_buffer[++txd_bufferIndex] = 0;
334
 txd_buffer[++txd_bufferIndex] = 0;
335
 shift = 4;
335
 shift = 4;
336
 }
336
 }
337
 if (shift == 4) {
337
 if (shift == 4) {
338
 // We need to stuff with zero bytes at the end.
338
 // We need to stuff with zero bytes at the end.
339
 txd_buffer[txd_bufferIndex++] &= 0b00111100;
339
 txd_buffer[txd_bufferIndex++] &= 0b00111100;
340
 txd_buffer[txd_bufferIndex]    = 0;
340
 txd_buffer[txd_bufferIndex]    = 0;
341
 }
341
 }
342
 va_end(ap);
342
 va_end(ap);
343
 Addchecksum(pt); // add checksum after data block and initates the transmission
343
 Addchecksum(pt); // add checksum after data block and initates the transmission
344
 }
344
 }
345
 */
345
 */
346
 
346
 
347
void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
347
void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
348
        va_list ap;
348
        va_list ap;
349
        uint16_t pt = 0;
349
        uint16_t pt = 0;
350
        uint8_t a, b, c;
350
        uint8_t a, b, c;
351
        uint8_t ptr = 0;
351
        uint8_t ptr = 0;
352
 
352
 
353
        uint8_t *pdata = 0;
353
        uint8_t *pdata = 0;
354
        int len = 0;
354
        int len = 0;
355
 
355
 
356
        txd_buffer[pt++] = '#'; // Start character
356
        txd_buffer[pt++] = '#'; // Start character
357
        txd_buffer[pt++] = 'a' + addr; // Address (a=0; b=1,...)
357
        txd_buffer[pt++] = 'a' + addr; // Address (a=0; b=1,...)
358
        txd_buffer[pt++] = cmd; // Command
358
        txd_buffer[pt++] = cmd; // Command
359
 
359
 
360
        va_start(ap, numofbuffers);
360
        va_start(ap, numofbuffers);
361
 
361
 
362
        if (numofbuffers) {
362
        if (numofbuffers) {
363
                pdata = va_arg(ap, uint8_t*);
363
                pdata = va_arg(ap, uint8_t*);
364
                len = va_arg(ap, int);
364
                len = va_arg(ap, int);
365
                ptr = 0;
365
                ptr = 0;
366
                numofbuffers--;
366
                numofbuffers--;
367
        }
367
        }
368
 
368
 
369
        while (len) {
369
        while (len) {
370
                if (len) {
370
                if (len) {
371
                        a = pdata[ptr++];
371
                        a = pdata[ptr++];
372
                        len--;
372
                        len--;
373
                        if ((!len) && numofbuffers) {
373
                        if ((!len) && numofbuffers) {
374
                                pdata = va_arg(ap, uint8_t*);
374
                                pdata = va_arg(ap, uint8_t*);
375
                                len = va_arg(ap, int);
375
                                len = va_arg(ap, int);
376
                                ptr = 0;
376
                                ptr = 0;
377
                                numofbuffers--;
377
                                numofbuffers--;
378
                        }
378
                        }
379
                } else
379
                } else
380
                        a = 0;
380
                        a = 0;
381
                if (len) {
381
                if (len) {
382
                        b = pdata[ptr++];
382
                        b = pdata[ptr++];
383
                        len--;
383
                        len--;
384
                        if ((!len) && numofbuffers) {
384
                        if ((!len) && numofbuffers) {
385
                                pdata = va_arg(ap, uint8_t*);
385
                                pdata = va_arg(ap, uint8_t*);
386
                                len = va_arg(ap, int);
386
                                len = va_arg(ap, int);
387
                                ptr = 0;
387
                                ptr = 0;
388
                                numofbuffers--;
388
                                numofbuffers--;
389
                        }
389
                        }
390
                } else
390
                } else
391
                        b = 0;
391
                        b = 0;
392
                if (len) {
392
                if (len) {
393
                        c = pdata[ptr++];
393
                        c = pdata[ptr++];
394
                        len--;
394
                        len--;
395
                        if ((!len) && numofbuffers) {
395
                        if ((!len) && numofbuffers) {
396
                                pdata = va_arg(ap, uint8_t*);
396
                                pdata = va_arg(ap, uint8_t*);
397
                                len = va_arg(ap, int);
397
                                len = va_arg(ap, int);
398
                                ptr = 0;
398
                                ptr = 0;
399
                                numofbuffers--;
399
                                numofbuffers--;
400
                        }
400
                        }
401
                } else
401
                } else
402
                        c = 0;
402
                        c = 0;
403
                txd_buffer[pt++] = '=' + (a >> 2);
403
                txd_buffer[pt++] = '=' + (a >> 2);
404
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
404
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
405
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
405
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
406
                txd_buffer[pt++] = '=' + (c & 0x3f);
406
                txd_buffer[pt++] = '=' + (c & 0x3f);
407
        }
407
        }
408
        va_end(ap);
408
        va_end(ap);
409
        addChecksum(pt); // add checksum after data block and initates the transmission
409
        addChecksum(pt); // add checksum after data block and initates the transmission
410
}
410
}
411
 
411
 
412
// --------------------------------------------------------------------------
412
// --------------------------------------------------------------------------
413
void decode64(void) {
413
void decode64(void) {
414
        uint8_t a, b, c, d;
414
        uint8_t a, b, c, d;
415
        uint8_t x, y, z;
415
        uint8_t x, y, z;
416
        uint8_t ptrIn = 3;
416
        uint8_t ptrIn = 3;
417
        uint8_t ptrOut = 3;
417
        uint8_t ptrOut = 3;
418
        uint8_t len = receivedBytes - 6;
418
        uint8_t len = receivedBytes - 6;
419
 
419
 
420
        while (len) {
420
        while (len) {
421
                a = rxd_buffer[ptrIn++] - '=';
421
                a = rxd_buffer[ptrIn++] - '=';
422
                b = rxd_buffer[ptrIn++] - '=';
422
                b = rxd_buffer[ptrIn++] - '=';
423
                c = rxd_buffer[ptrIn++] - '=';
423
                c = rxd_buffer[ptrIn++] - '=';
424
                d = rxd_buffer[ptrIn++] - '=';
424
                d = rxd_buffer[ptrIn++] - '=';
425
                //if(ptrIn > ReceivedBytes - 3) break;
425
                //if(ptrIn > ReceivedBytes - 3) break;
426
 
426
 
427
                x = (a << 2) | (b >> 4);
427
                x = (a << 2) | (b >> 4);
428
                y = ((b & 0x0f) << 4) | (c >> 2);
428
                y = ((b & 0x0f) << 4) | (c >> 2);
429
                z = ((c & 0x03) << 6) | d;
429
                z = ((c & 0x03) << 6) | d;
430
 
430
 
431
                if (len--)
431
                if (len--)
432
                        rxd_buffer[ptrOut++] = x;
432
                        rxd_buffer[ptrOut++] = x;
433
                else
433
                else
434
                        break;
434
                        break;
435
                if (len--)
435
                if (len--)
436
                        rxd_buffer[ptrOut++] = y;
436
                        rxd_buffer[ptrOut++] = y;
437
                else
437
                else
438
                        break;
438
                        break;
439
                if (len--)
439
                if (len--)
440
                        rxd_buffer[ptrOut++] = z;
440
                        rxd_buffer[ptrOut++] = z;
441
                else
441
                else
442
                        break;
442
                        break;
443
        }
443
        }
444
        pRxData = &rxd_buffer[3];
444
        pRxData = &rxd_buffer[3];
445
        rxDataLen = ptrOut - 3;
445
        rxDataLen = ptrOut - 3;
446
}
446
}
447
 
447
 
448
// --------------------------------------------------------------------------
448
// --------------------------------------------------------------------------
449
void usart0_processRxData(void) {
449
void usart0_processRxData(void) {
450
        // We control the motorTestActive var from here: Count it down.
450
        // We control the motorTestActive var from here: Count it down.
451
        if (motorTestActive)
451
        if (motorTestActive)
452
                motorTestActive--;
452
                motorTestActive--;
453
        // if data in the rxd buffer are not locked immediately return
453
        // if data in the rxd buffer are not locked immediately return
454
        if (!rxd_buffer_locked)
454
        if (!rxd_buffer_locked)
455
                return;
455
                return;
456
        uint8_t tempchar[3];
456
        uint8_t tempchar[3];
457
        decode64(); // decode data block in rxd_buffer
457
        decode64(); // decode data block in rxd_buffer
458
 
458
 
459
        switch (rxd_buffer[1] - 'a') {
459
        switch (rxd_buffer[1] - 'a') {
460
 
460
 
461
        case FC_ADDRESS:
461
        case FC_ADDRESS:
462
                switch (rxd_buffer[2]) {
462
                switch (rxd_buffer[2]) {
463
#ifdef USE_DIRECT_GPS
463
#ifdef USE_DIRECT_GPS
464
                case 'K':// compass value
464
                case 'K':// compass value
465
                  // What is the point of this - the compass will overwrite this soon?
465
                  // What is the point of this - the compass will overwrite this soon?
466
                magneticHeading = ((Heading_t *)pRxData)->heading;
466
                magneticHeading = ((Heading_t *)pRxData)->heading;
467
                // compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180;
467
                // compassOffCourse = ((540 + compassHeading - compassCourse) % 360) - 180;
468
                break;
468
                break;
469
#endif
469
#endif
470
                case 't': // motor test
470
                case 't': // motor test
471
                        if (rxDataLen > 20) {
471
                        if (rxDataLen > 20) {
472
                                memcpy(&motorTest[0], (uint8_t*) pRxData, sizeof(motorTest));
472
                                memcpy(&motorTest[0], (uint8_t*) pRxData, sizeof(motorTest));
473
                        } else {
473
                        } else {
474
                                memcpy(&motorTest[0], (uint8_t*) pRxData, 4);
474
                                memcpy(&motorTest[0], (uint8_t*) pRxData, 4);
475
                        }
475
                        }
476
                        motorTestActive = 255;
476
                        motorTestActive = 255;
477
                        externalControlActive = 255;
477
                        externalControlActive = 255;
478
                        break;
478
                        break;
479
 
479
 
480
                case 'n':// Read motor mixer
480
                case 'n':// Read motor mixer
481
            tempchar[0] = EEMIXER_REVISION;
481
            tempchar[0] = EEMIXER_REVISION;
482
            tempchar[1] = sizeof(MotorMixer_t);
482
            tempchar[1] = sizeof(MotorMixer_t);
483
            while (!txd_complete)
483
            while (!txd_complete)
484
                ; // wait for previous frame to be sent
484
                ; // wait for previous frame to be sent
485
                        sendOutData('N', FC_ADDRESS, 2, &tempchar, 2, (uint8_t*)&motorMixer, sizeof(motorMixer));
485
                        sendOutData('N', FC_ADDRESS, 2, &tempchar, 2, (uint8_t*)&motorMixer, sizeof(motorMixer));
486
                        break;
486
                        break;
487
 
487
 
488
                case 'm':// "Set Mixer Table
488
                case 'm':// "Set Mixer Table
489
                        if (pRxData[0] == EEMIXER_REVISION && (pRxData[1] == sizeof(MotorMixer_t))) {
489
                        if (pRxData[0] == EEMIXER_REVISION && (pRxData[1] == sizeof(MotorMixer_t))) {
490
                                memcpy(&motorMixer, (uint8_t*)&pRxData[2], sizeof(motorMixer));
490
                                memcpy(&motorMixer, (uint8_t*)&pRxData[2], sizeof(motorMixer));
491
                                motorMixer_writeToEEProm();
491
                                motorMixer_writeToEEProm();
492
                                while (!txd_complete)
492
                                while (!txd_complete)
493
                                        ; // wait for previous frame to be sent
493
                                        ; // wait for previous frame to be sent
494
                                tempchar[0] = 1;
494
                                tempchar[0] = 1;
495
                        } else {
495
                        } else {
496
                                tempchar[0] = 0;
496
                                tempchar[0] = 0;
497
                        }
497
                        }
498
                        sendOutData('M', FC_ADDRESS, 1, &tempchar, 1);
498
                        sendOutData('M', FC_ADDRESS, 1, &tempchar, 1);
499
                        break;
499
                        break;
500
 
500
 
501
                case 'p': // get PPM channels
501
                case 'p': // get PPM channels
502
                        request_PPMChannels = TRUE;
502
                        request_PPMChannels = TRUE;
503
                        break;
503
                        break;
504
 
504
 
505
        case 'i':// Read IMU configuration
505
        case 'i':// Read IMU configuration
506
            tempchar[0] = IMUCONFIG_REVISION;
506
            tempchar[0] = IMUCONFIG_REVISION;
507
            tempchar[1] = sizeof(IMUConfig);
507
            tempchar[1] = sizeof(IMUConfig);
508
            while (!txd_complete)
508
            while (!txd_complete)
509
                ; // wait for previous frame to be sent
509
                ; // wait for previous frame to be sent
510
            sendOutData('I', FC_ADDRESS, 2, &tempchar, 2, (uint8_t *) &IMUConfig, sizeof(IMUConfig));
510
            sendOutData('I', FC_ADDRESS, 2, &tempchar, 2, (uint8_t *) &IMUConfig, sizeof(IMUConfig));
511
            break;
511
            break;
512
 
512
 
513
        case 'j':// Save IMU configuration
513
        case 'j':// Save IMU configuration
514
          if (!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors are off
514
          if (!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors are off
515
          {
515
          {
516
              if ((pRxData[0] == IMUCONFIG_REVISION) && (pRxData[1] == sizeof(IMUConfig))) {
516
              if ((pRxData[0] == IMUCONFIG_REVISION) && (pRxData[1] == sizeof(IMUConfig))) {
517
                  memcpy(&IMUConfig, (uint8_t*) &pRxData[2], sizeof(IMUConfig));
517
                  memcpy(&IMUConfig, (uint8_t*) &pRxData[2], sizeof(IMUConfig));
518
                  IMUConfig_writeToEEprom();
518
                  IMUConfig_writeToEEprom();
519
                  tempchar[0] = 1; //indicate ok data
519
                  tempchar[0] = 1; //indicate ok data
520
              } else {
520
              } else {
521
                  tempchar[0] = 0; //indicate bad data
521
                  tempchar[0] = 0; //indicate bad data
522
              }
522
              }
523
              while (!txd_complete)
523
              while (!txd_complete)
524
                  ; // wait for previous frame to be sent
524
                  ; // wait for previous frame to be sent
525
              sendOutData('J', FC_ADDRESS, 1, &tempchar, 1);
525
              sendOutData('J', FC_ADDRESS, 1, &tempchar, 1);
526
          }
526
          }
527
          break;
527
          break;
528
 
528
 
529
                case 'q':// request settings
529
                case 'q':// request settings
530
                        if (pRxData[0] == 0xFF) {
530
                        if (pRxData[0] == 0xFF) {
531
                                pRxData[0] = getParamByte(PID_ACTIVE_SET);
531
                                pRxData[0] = getParamByte(PID_ACTIVE_SET);
532
                        }
532
                        }
533
                        // limit settings range
533
                        // limit settings range
534
                        if (pRxData[0] < 1)
534
                        if (pRxData[0] < 1)
535
                                pRxData[0] = 1; // limit to 1
535
                                pRxData[0] = 1; // limit to 1
536
                        else if (pRxData[0] > 5)
536
                        else if (pRxData[0] > 5)
537
                                pRxData[0] = 5; // limit to 5
537
                                pRxData[0] = 5; // limit to 5
538
                        // load requested parameter set
538
                        // load requested parameter set
539
 
539
 
540
                        paramSet_readFromEEProm(pRxData[0]);
540
                        paramSet_readFromEEProm(pRxData[0]);
541
 
541
 
542
                        tempchar[0] = pRxData[0];
542
                        tempchar[0] = pRxData[0];
543
                        tempchar[1] = EEPARAM_REVISION;
543
                        tempchar[1] = EEPARAM_REVISION;
544
                        tempchar[2] = sizeof(staticParams);
544
                        tempchar[2] = sizeof(staticParams);
545
                        while (!txd_complete)
545
                        while (!txd_complete)
546
                                ; // wait for previous frame to be sent
546
                                ; // wait for previous frame to be sent
547
                        sendOutData('Q', FC_ADDRESS, 2, &tempchar, 3, (uint8_t *) &staticParams, sizeof(staticParams));
547
                        sendOutData('Q', FC_ADDRESS, 2, &tempchar, 3, (uint8_t *) &staticParams, sizeof(staticParams));
548
                        break;
548
                        break;
549
 
549
 
550
                case 's': // save settings
550
                case 's': // save settings
551
                        if (!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors are off
551
                        if (!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors are off
552
                        {
552
                        {
553
                                if ((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION) && (pRxData[2] == sizeof(staticParams))) // check for setting to be in range and version of settings
553
                                if ((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION) && (pRxData[2] == sizeof(staticParams))) // check for setting to be in range and version of settings
554
                                {
554
                                {
555
                                        memcpy(&staticParams, (uint8_t*) &pRxData[3], sizeof(staticParams));
555
                                        memcpy(&staticParams, (uint8_t*) &pRxData[3], sizeof(staticParams));
556
                                        paramSet_writeToEEProm(pRxData[0]);
556
                                        paramSet_writeToEEProm(pRxData[0]);
557
                                        setActiveParamSet(pRxData[0]);
557
                                        setActiveParamSet(pRxData[0]);
558
                                        configuration_paramSetDidChange();
558
                                        configuration_paramSetDidChange();
559
                                        tempchar[0] = getActiveParamSet();
559
                                        tempchar[0] = getActiveParamSet();
560
                                        beepNumber(tempchar[0]);
560
                                        beepNumber(tempchar[0]);
561
                                } else {
561
                                } else {
562
                                        tempchar[0] = 0; //indicate bad data
562
                                        tempchar[0] = 0; //indicate bad data
563
                                }
563
                                }
564
                                while (!txd_complete)
564
                                while (!txd_complete)
565
                                        ; // wait for previous frame to be sent
565
                                        ; // wait for previous frame to be sent
566
                                sendOutData('S', FC_ADDRESS, 1, &tempchar, 1);
566
                                sendOutData('S', FC_ADDRESS, 1, &tempchar, 1);
567
                        }
567
                        }
568
                        break;
568
                        break;
569
 
569
 
570
                default:
570
                default:
571
                        //unsupported command received
571
                        //unsupported command received
572
                        break;
572
                        break;
573
                } // case FC_ADDRESS:
573
                } // case FC_ADDRESS:
574
 
574
 
575
        default: // any Slave Address
575
        default: // any Slave Address
576
                switch (rxd_buffer[2]) {
576
                switch (rxd_buffer[2]) {
577
                case 'a':// request for labels of the analog debug outputs
577
                case 'a':// request for labels of the analog debug outputs
578
                        requestedDebugLabel = pRxData[0];
578
                        requestedDebugLabel = pRxData[0];
579
                        if (requestedDebugLabel > 31)
579
                        if (requestedDebugLabel > 31)
580
                                requestedDebugLabel = 31;
580
                                requestedDebugLabel = 31;
581
                        break;
581
                        break;
582
 
582
 
583
                case 'b': // submit extern control
583
                case 'b': // submit extern control
584
                        memcpy(&externalControl, (uint8_t*) pRxData, sizeof(externalControl));
584
                        memcpy(&externalControl, (uint8_t*) pRxData, sizeof(externalControl));
585
                        confirmFrame = externalControl.frame;
585
                        confirmFrame = externalControl.frame;
586
                        externalControlActive = 255;
586
                        externalControlActive = 255;
587
                        break;
587
                        break;
588
 
588
 
589
                case 'h':// request for display columns
589
                case 'h':// request for display columns
590
                        remoteKeys |= pRxData[0];
590
                        remoteKeys |= pRxData[0];
591
                        if (remoteKeys)
591
                        if (remoteKeys)
592
                                displayLine = 0;
592
                                displayLine = 0;
593
                        request_display = TRUE;
593
                        request_display = TRUE;
594
                        break;
594
                        break;
595
 
595
 
596
                case 'l':// request for display columns
596
                case 'l':// request for display columns
597
                        menuItem = pRxData[0];
597
                        menuItem = pRxData[0];
598
                        request_display1 = TRUE;
598
                        request_display1 = TRUE;
599
                        break;
599
                        break;
600
 
600
 
601
                case 'o':// request for OSD data (FC style)
601
                case 'o':// request for OSD data (FC style)
602
                  OSD_interval = (uint16_t) pRxData[0] * 10;
602
                  OSD_interval = (uint16_t) pRxData[0] * 10;
603
                  if (OSD_interval > 0)
603
                  if (OSD_interval > 0)
604
                    request_OSD = TRUE;
604
                    request_OSD = TRUE;
605
                  break;
605
                  break;
606
                 
606
                 
607
                case 'v': // request for version and board release
607
                case 'v': // request for version and board release
608
                        request_verInfo = TRUE;
608
                        request_verInfo = TRUE;
609
                        break;
609
                        break;
610
 
610
 
611
                case 'x':
611
                case 'x':
612
                        request_variables = TRUE;
612
                        request_variables = TRUE;
613
                        break;
613
                        break;
614
 
614
 
615
                case 'g':// get external control data
615
                case 'g':// get external control data
616
                        request_externalControl = TRUE;
616
                        request_externalControl = TRUE;
617
                        break;
617
                        break;
618
 
618
 
619
                case 'd': // request for the debug data
619
                case 'd': // request for the debug data
620
                        debugData_interval = (uint16_t) pRxData[0] * 10;
620
                        debugData_interval = (uint16_t) pRxData[0] * 10;
621
                        if (debugData_interval > 0)
621
                        if (debugData_interval > 0)
622
                                request_debugData = TRUE;
622
                                request_debugData = TRUE;
623
                        break;
623
                        break;
624
 
624
 
625
                case 'c': // request for the 3D data
625
                case 'c': // request for the 3D data
626
                        data3D_interval = (uint16_t) pRxData[0] * 10;
626
                        data3D_interval = (uint16_t) pRxData[0] * 10;
627
                        if (data3D_interval > 0)
627
                        if (data3D_interval > 0)
628
                                request_data3D = TRUE;
628
                                request_data3D = TRUE;
629
                        break;
629
                        break;
630
 
630
 
631
                default:
631
                default:
632
                        //unsupported command received
632
                        //unsupported command received
633
                        break;
633
                        break;
634
                }
634
                }
635
                break; // default:
635
                break; // default:
636
        }
636
        }
637
        // unlock the rxd buffer after processing
637
        // unlock the rxd buffer after processing
638
        pRxData = 0;
638
        pRxData = 0;
639
        rxDataLen = 0;
639
        rxDataLen = 0;
640
        rxd_buffer_locked = FALSE;
640
        rxd_buffer_locked = FALSE;
641
}
641
}
642
 
642
 
643
/************************************************************************/
643
/************************************************************************/
644
/* Routine f�r die Serielle Ausgabe                                     */
644
/* Routine f�r die Serielle Ausgabe                                     */
645
/************************************************************************/
645
/************************************************************************/
646
int16_t uart_putchar(int8_t c) {
646
int16_t uart_putchar(int8_t c) {
647
        if (c == '\n')
647
        if (c == '\n')
648
                uart_putchar('\r');
648
                uart_putchar('\r');
649
        // wait until previous character was send
649
        // wait until previous character was send
650
        loop_until_bit_is_set(UCSR0A, UDRE0);
650
        loop_until_bit_is_set(UCSR0A, UDRE0);
651
        // send character
651
        // send character
652
        UDR0 = c;
652
        UDR0 = c;
653
        return (0);
653
        return (0);
654
}
654
}
655
 
655
 
656
//---------------------------------------------------------------------------------------------
656
//---------------------------------------------------------------------------------------------
657
void usart0_transmitTxData(void) {
657
void usart0_transmitTxData(void) {
658
        if (!txd_complete)
658
        if (!txd_complete)
659
                return;
659
                return;
660
 
660
 
661
        if (request_verInfo && txd_complete) {
661
        if (request_verInfo && txd_complete) {
662
                sendOutData('V', FC_ADDRESS, 1, (uint8_t *) &versionInfo, sizeof(versionInfo));
662
                sendOutData('V', FC_ADDRESS, 1, (uint8_t *) &versionInfo, sizeof(versionInfo));
663
                request_verInfo = FALSE;
663
                request_verInfo = FALSE;
664
        }
664
        }
665
 
665
 
666
        if (request_display && txd_complete) {
666
        if (request_display && txd_complete) {
667
                LCD_printMenu();
667
                LCD_printMenu();
668
                sendOutData('H', FC_ADDRESS, 2, &displayLine, sizeof(displayLine),
668
                sendOutData('H', FC_ADDRESS, 2, &displayLine, sizeof(displayLine),
669
                                &displayBuff[displayLine * 20], 20);
669
                                &displayBuff[displayLine * 20], 20);
670
                displayLine++;
670
                displayLine++;
671
                if (displayLine >= 4)
671
                if (displayLine >= 4)
672
                        displayLine = 0;
672
                        displayLine = 0;
673
                request_display = FALSE;
673
                request_display = FALSE;
674
        }
674
        }
675
 
675
 
676
        if (request_display1 && txd_complete) {
676
        if (request_display1 && txd_complete) {
677
                LCD_printMenu();
677
                LCD_printMenu();
678
                sendOutData('L', FC_ADDRESS, 3, &menuItem, sizeof(menuItem), &maxMenuItem,
678
                sendOutData('L', FC_ADDRESS, 3, &menuItem, sizeof(menuItem), &maxMenuItem,
679
                                sizeof(maxMenuItem), displayBuff, sizeof(displayBuff));
679
                                sizeof(maxMenuItem), displayBuff, sizeof(displayBuff));
680
                request_display1 = FALSE;
680
                request_display1 = FALSE;
681
        }
681
        }
682
 
682
 
683
        if (requestedDebugLabel != 0xFF && txd_complete) { // Texte f�r die Analogdaten
683
        if (requestedDebugLabel != 0xFF && txd_complete) { // Texte f�r die Analogdaten
684
                uint8_t label[16]; // local sram buffer
684
                uint8_t label[16]; // local sram buffer
685
                memcpy_P(label, ANALOG_LABEL[requestedDebugLabel], 16); // read lable from flash to sram buffer
685
                memcpy_P(label, ANALOG_LABEL[requestedDebugLabel], 16); // read lable from flash to sram buffer
686
                sendOutData('A', FC_ADDRESS, 2, (uint8_t *) &requestedDebugLabel,
686
                sendOutData('A', FC_ADDRESS, 2, (uint8_t *) &requestedDebugLabel,
687
                                sizeof(requestedDebugLabel), label, 16);
687
                                sizeof(requestedDebugLabel), label, 16);
688
                requestedDebugLabel = 0xFF;
688
                requestedDebugLabel = 0xFF;
689
        }
689
        }
690
 
690
 
691
        if (confirmFrame && txd_complete) { // Datensatz ohne checksum best�tigen
691
        if (confirmFrame && txd_complete) { // Datensatz ohne checksum best�tigen
692
                sendOutData('B', FC_ADDRESS, 1, (uint8_t*) &confirmFrame, sizeof(confirmFrame));
692
                sendOutData('B', FC_ADDRESS, 1, (uint8_t*) &confirmFrame, sizeof(confirmFrame));
693
                confirmFrame = 0;
693
                confirmFrame = 0;
694
        }
694
        }
695
 
695
 
696
        if (((debugData_interval && checkDelay(debugData_timer)) || request_debugData)
696
        if (((debugData_interval && checkDelay(debugData_timer)) || request_debugData)
697
                        && txd_complete) {
697
                        && txd_complete) {
698
                sendOutData('D', FC_ADDRESS, 1, (uint8_t *) &debugOut, sizeof(debugOut));
698
                sendOutData('D', FC_ADDRESS, 1, (uint8_t *) &debugOut, sizeof(debugOut));
699
                debugData_timer = setDelay(debugData_interval);
699
                debugData_timer = setDelay(debugData_interval);
700
                request_debugData = FALSE;
700
                request_debugData = FALSE;
701
        }
701
        }
702
 
702
 
703
        if (((data3D_interval && checkDelay(data3D_timer)) || request_data3D) && txd_complete) {
703
        if (((data3D_interval && checkDelay(data3D_timer)) || request_data3D) && txd_complete) {
704
                sendOutData('C', FC_ADDRESS, 1, (uint8_t *) &data3D, sizeof(data3D));
704
                sendOutData('C', FC_ADDRESS, 1, (uint8_t *) &data3D, sizeof(data3D));
705
                data3D.anglePitch = (int16_t) (attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
705
                data3D.anglePitch = (int16_t) (attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
706
                data3D.angleRoll = (int16_t) (attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
706
                data3D.angleRoll = (int16_t) (attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
707
                data3D.heading = (int16_t) (heading / (GYRO_DEG_FACTOR_YAW/10)); // convert to multiple of 0.1 deg
707
                data3D.heading = (int16_t) (heading / (GYRO_DEG_FACTOR_YAW/10)); // convert to multiple of 0.1 deg
708
                data3D_timer = setDelay(data3D_interval);
708
                data3D_timer = setDelay(data3D_interval);
709
                request_data3D = FALSE;
709
                request_data3D = FALSE;
710
        }
710
        }
711
 
711
 
712
        if (request_externalControl && txd_complete) {
712
        if (request_externalControl && txd_complete) {
713
                sendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl,
713
                sendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl,
714
                                sizeof(externalControl));
714
                                sizeof(externalControl));
715
                request_externalControl = FALSE;
715
                request_externalControl = FALSE;
716
        }
716
        }
717
 
717
 
718
#ifdef USE_DIRECT_GPS
718
#ifdef USE_DIRECT_GPS
719
        if((checkDelay(toMk3MagTimer)) && txd_complete) {
719
        if((checkDelay(toMk3MagTimer)) && txd_complete) {
720
                toMk3Mag.attitude[0] = (int16_t)(attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // approx. 0.1 deg
720
                toMk3Mag.attitude[0] = (int16_t)(attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // approx. 0.1 deg
721
                toMk3Mag.attitude[1] = (int16_t)(attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // approx. 0.1 deg
721
                toMk3Mag.attitude[1] = (int16_t)(attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // approx. 0.1 deg
722
                toMk3Mag.userParam[0] = dynamicParams.userParams[0];
722
                toMk3Mag.userParam[0] = dynamicParams.userParams[0];
723
                toMk3Mag.userParam[1] = dynamicParams.userParams[1];
723
                toMk3Mag.userParam[1] = dynamicParams.userParams[1];
724
                toMk3Mag.calState = compassCalState;
724
                toMk3Mag.calState = compassCalState;
725
                sendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &toMk3Mag,sizeof(toMk3Mag));
725
                sendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &toMk3Mag,sizeof(toMk3Mag));
726
                // the last state is 5 and should be send only once to avoid multiple flash writing
726
                // the last state is 5 and should be send only once to avoid multiple flash writing
727
                if(compassCalState > 4) compassCalState = 0;
727
                if(compassCalState > 4) compassCalState = 0;
728
                toMk3MagTimer = setDelay(99);
728
                toMk3MagTimer = setDelay(99);
729
        }
729
        }
730
#endif
730
#endif
731
 
731
 
732
        if (request_motorTest && txd_complete) {
732
        if (request_motorTest && txd_complete) {
733
                sendOutData('T', FC_ADDRESS, 0);
733
                sendOutData('T', FC_ADDRESS, 0);
734
                request_motorTest = FALSE;
734
                request_motorTest = FALSE;
735
        }
735
        }
736
 
736
 
737
        if (request_PPMChannels && txd_complete) {
737
        if (request_PPMChannels && txd_complete) {
-
 
738
                uint8_t length = MAX_CHANNELS;
738
                sendOutData('P', FC_ADDRESS, 1, (uint8_t *) &PPM_in, sizeof(PPM_in));
739
                sendOutData('P', FC_ADDRESS, 2, &length, 1, (uint8_t*)&PPM_in, sizeof(PPM_in));
739
                request_PPMChannels = FALSE;
740
                request_PPMChannels = FALSE;
740
        }
741
        }
741
 
742
 
742
        if (request_variables && txd_complete) {
743
        if (request_variables && txd_complete) {
743
                sendOutData('X', FC_ADDRESS, 1, (uint8_t *) &variables, sizeof(variables));
744
                sendOutData('X', FC_ADDRESS, 1, (uint8_t *) &variables, sizeof(variables));
744
                request_variables = FALSE;
745
                request_variables = FALSE;
745
        }
746
        }
-
 
747
 
746
 
748
#ifdef USE_DIRECT_GPS
747
        if (((OSD_interval && checkDelay(OSD_timer)) || request_OSD) && txd_complete) {
749
        if (((OSD_interval && checkDelay(OSD_timer)) || request_OSD) && txd_complete) {
748
          int32_t height = analog_getHeight();
750
          int32_t height = analog_getHeight();
749
          data3D.anglePitch = (int16_t) (attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
751
          data3D.anglePitch = (int16_t) (attitude[PITCH] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
750
          data3D.angleRoll = (int16_t) (attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
752
          data3D.angleRoll = (int16_t) (attitude[ROLL] / (GYRO_DEG_FACTOR_PITCHROLL/10)); // convert to multiple of 0.1 deg
751
          data3D.heading = (int16_t) (heading / (GYRO_DEG_FACTOR_YAW/10)); // convert to multiple of 0.1 deg
753
          data3D.heading = (int16_t) (heading / (GYRO_DEG_FACTOR_YAW/10)); // convert to multiple of 0.1 deg
752
          sendOutData('O', FC_ADDRESS, 4, (uint8_t*)&data3D, sizeof(data3D), (uint8_t*)&GPSInfo, sizeof(GPSInfo), (uint8_t*)&height, sizeof(height), (uint8_t*)UBat, sizeof(UBat));
754
          sendOutData('O', FC_ADDRESS, 4, (uint8_t*)&data3D, sizeof(data3D), (uint8_t*)&GPSInfo, sizeof(GPSInfo), (uint8_t*)&height, sizeof(height), (uint8_t*)UBat, sizeof(UBat));
753
          OSD_timer = setDelay(OSD_interval);
755
          OSD_timer = setDelay(OSD_interval);
754
          request_OSD = FALSE;
756
          request_OSD = FALSE;
755
        }
757
        }
-
 
758
#endif
756
}
759
}
757
 
760