Subversion Repositories FlightCtrl

Rev

Rev 1612 | Rev 1634 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1612 Rev 1623
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) 04.2007 Holger Buss
2
// + Copyright (c) 04.2007 Holger Buss
3
// + Nur für den privaten Gebrauch
3
// + Nur für den privaten Gebrauch
4
// + www.MikroKopter.com
4
// + www.MikroKopter.com
5
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
6
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
7
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
7
// + dass eine Nutzung (auch auszugsweise) nur für den privaten und nicht-kommerziellen Gebrauch zulässig ist.
8
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
8
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
9
// + bzgl. der Nutzungsbedingungen aufzunehmen.
9
// + bzgl. der Nutzungsbedingungen aufzunehmen.
10
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
10
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
11
// + Verkauf von Luftbildaufnahmen, usw.
11
// + Verkauf von Luftbildaufnahmen, usw.
12
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
13
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
14
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
14
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
15
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
16
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
17
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
17
// + auf anderen Webseiten oder Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
18
// + eindeutig als Ursprung verlinkt werden
18
// + eindeutig als Ursprung verlinkt und genannt werden
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
20
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
21
// + Benutzung auf eigene Gefahr
21
// + Benutzung auf eigene Gefahr
22
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
22
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
24
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
25
// + mit unserer Zustimmung zulässig
25
// + mit unserer Zustimmung zulässig
26
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
27
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
29
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
30
// + this list of conditions and the following disclaimer.
30
// + this list of conditions and the following disclaimer.
31
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
31
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
32
// +     from this software without specific prior written permission.
32
// +     from this software without specific prior written permission.
33
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
33
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
34
// +     for non-commercial use (directly or indirectly)
34
// +     for non-commercial use (directly or indirectly)
35
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
35
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
36
// +     with our written permission
36
// +     with our written permission
37
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
37
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
38
// +     clearly linked as origin
38
// +     clearly linked as origin
39
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
39
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
40
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
40
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
43
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-
 
47
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49
// +  POSSIBILITY OF SUCH DAMAGE.
50
// +  POSSIBILITY OF SUCH DAMAGE.
50
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
 
52
 
51
#include <avr/io.h>
53
#include <avr/io.h>
52
#include <avr/interrupt.h>
54
#include <avr/interrupt.h>
53
#include <avr/wdt.h>
55
#include <avr/wdt.h>
54
#include <avr/pgmspace.h>
56
#include <avr/pgmspace.h>
55
#include <stdarg.h>
57
#include <stdarg.h>
56
#include <string.h>
58
#include <string.h>
57
 
59
 
58
#include "eeprom.h"
60
#include "eeprom.h"
59
#include "menu.h"
61
#include "menu.h"
60
#include "timer0.h"
62
#include "timer0.h"
61
#include "uart0.h"
63
#include "uart0.h"
62
#include "attitude.h"
64
#include "attitude.h"
63
#include "rc.h"
65
#include "rc.h"
64
#include "externalControl.h"
66
#include "externalControl.h"
65
 
67
 
66
#if defined (USE_MK3MAG)
68
#if defined (USE_MK3MAG)
67
#include "ubx.h"
69
#include "ubx.h"
68
#endif
70
#endif
69
#ifdef USE_MK3MAG
71
#ifdef USE_MK3MAG
70
#include "mk3mag.h"
72
#include "mk3mag.h"
71
#endif
73
#endif
72
 
74
 
73
#define FC_ADDRESS 1
75
#define FC_ADDRESS 1
74
#define NC_ADDRESS 2
76
#define NC_ADDRESS 2
75
#define MK3MAG_ADDRESS 3
77
#define MK3MAG_ADDRESS 3
76
 
78
 
77
#define FALSE   0
79
#define FALSE   0
78
#define TRUE    1
80
#define TRUE    1
79
//int8_t test __attribute__ ((section (".noinit")));
81
//int8_t test __attribute__ ((section (".noinit")));
80
uint8_t Request_VerInfo                 = FALSE;
82
uint8_t Request_VerInfo                 = FALSE;
81
uint8_t Request_ExternalControl         = FALSE;
83
uint8_t Request_ExternalControl         = FALSE;
82
uint8_t Request_Display                 = FALSE;
84
uint8_t Request_Display                 = FALSE;
83
uint8_t Request_Display1                = FALSE;
85
uint8_t Request_Display1                = FALSE;
84
uint8_t Request_DebugData               = FALSE;
86
uint8_t Request_DebugData               = FALSE;
85
uint8_t Request_Data3D                  = FALSE;
87
uint8_t Request_Data3D                  = FALSE;
86
uint8_t Request_DebugLabel              = 255;
88
uint8_t Request_DebugLabel              = 255;
87
uint8_t Request_PPMChannels             = FALSE;
89
uint8_t Request_PPMChannels             = FALSE;
88
uint8_t Request_MotorTest               = FALSE;
90
uint8_t Request_MotorTest               = FALSE;
89
uint8_t DisplayLine = 0;
91
uint8_t DisplayLine = 0;
90
 
92
 
91
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
93
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
92
volatile uint8_t rxd_buffer_locked = FALSE;
94
volatile uint8_t rxd_buffer_locked = FALSE;
93
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
95
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
94
volatile uint8_t txd_complete = TRUE;
96
volatile uint8_t txd_complete = TRUE;
95
volatile uint8_t ReceivedBytes = 0;
97
volatile uint8_t ReceivedBytes = 0;
96
volatile uint8_t *pRxData = 0;
98
volatile uint8_t *pRxData = 0;
97
volatile uint8_t RxDataLen = 0;
99
volatile uint8_t RxDataLen = 0;
98
 
100
 
99
uint8_t motorTestActive  = 0;
101
uint8_t motorTestActive  = 0;
100
uint8_t motorTest[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
102
uint8_t motorTest[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
101
uint8_t ConfirmFrame;
103
uint8_t ConfirmFrame;
102
 
104
 
103
typedef struct {
105
typedef struct {
104
  int16_t Heading;
106
  int16_t Heading;
105
} __attribute__((packed)) Heading_t;
107
} __attribute__((packed)) Heading_t;
106
 
108
 
107
DebugOut_t              DebugOut;
109
DebugOut_t              DebugOut;
108
Data3D_t                Data3D;
110
Data3D_t                Data3D;
109
UART_VersionInfo_t      UART_VersionInfo;
111
UART_VersionInfo_t      UART_VersionInfo;
110
 
112
 
111
uint16_t DebugData_Timer;
113
uint16_t DebugData_Timer;
112
uint16_t Data3D_Timer;
114
uint16_t Data3D_Timer;
113
uint16_t DebugData_Interval = 500; // in 1ms
115
uint16_t DebugData_Interval = 500; // in 1ms
114
uint16_t Data3D_Interval = 0; // in 1ms
116
uint16_t Data3D_Interval = 0; // in 1ms
115
 
117
 
116
#ifdef USE_MK3MAG
118
#ifdef USE_MK3MAG
117
int16_t Compass_Timer;
119
int16_t Compass_Timer;
118
#endif
120
#endif
119
 
121
 
120
// keep lables in flash to save 512 bytes of sram space
122
// keep lables in flash to save 512 bytes of sram space
121
const prog_uint8_t ANALOG_LABEL[32][16] = {
123
const prog_uint8_t ANALOG_LABEL[32][16] = {
122
    //1234567890123456
124
    //1234567890123456
123
    "AnglePitch      ", //0
125
    "AnglePitch      ", //0
124
    "AngleRoll       ",
126
    "AngleRoll       ",
125
    "AngleYaw        ",
127
    "AngleYaw        ",
126
    "GyroPitch       ",
128
    "GyroPitch       ",
127
    "GyroRoll        ",
129
    "GyroRoll        ",
128
    "GyroYaw         ", //5
130
    "GyroYaw         ", //5
129
    "ACGyroPitch     ",
131
    "ACGyroPitch     ",
130
    "ACGyroRoll      ",
132
    "ACGyroRoll      ",
131
    "ACGyroYaw       ",
133
    "ACGyroYaw       ",
132
    "SetPointYaw     ",
134
    "SetPointYaw     ",
133
    "YawRateIFactor  ", //10
135
    "YawRateIFactor  ", //10
134
    "Gyro I Factor   ",
136
    "Gyro I Factor   ",
135
    "R/C Var 0       ",
137
    "R/C Var 0       ",
136
    "User Param 0    ",
138
    "User Param 0    ",
137
    "R/C Var 4       ",
139
    "R/C Var 4       ",
138
    "User Param 4    ", //15
140
    "User Param 4    ", //15
139
    "RCQuality       ",
141
    "RCQuality       ",
140
    "Ext. Quality    ",
142
    "Ext. Quality    ",
141
    "Looping         ",
143
    "Looping         ",
142
    "throttleTerm    ",
144
    "throttleTerm    ",
143
    "pitchTerm       ", //20
145
    "pitchTerm       ", //20
144
    "rollTerm        ",
146
    "rollTerm        ",
145
    "yawTerm         ",
147
    "yawTerm         ",
146
    "P Pitch         ",
148
    "P Pitch         ",
147
    "I Pitch         ",
149
    "I Pitch         ",
148
    "P+D Pitch       ", //25
150
    "P+D Pitch       ", //25
149
    "Pitch acc noise ",
151
    "Pitch acc noise ",
150
    "Roll acc noise  ",
152
    "Roll acc noise  ",
151
    "Pitch Corr      ",
153
    "Pitch Corr      ",
152
    "Roll Corr       ",
154
    "Roll Corr       ",
153
    "Pitch Noise     ", //30
155
    "Pitch Noise     ", //30
154
    "Roll Noise      "
156
    "Roll Noise      "
155
  };
157
  };
156
 
158
 
157
/****************************************************************/
159
/****************************************************************/
158
/*              Initialization of the USART0                    */
160
/*              Initialization of the USART0                    */
159
/****************************************************************/
161
/****************************************************************/
160
void USART0_Init (void) {
162
void USART0_Init (void) {
161
  uint8_t sreg = SREG;
163
  uint8_t sreg = SREG;
162
  uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART0_BAUD) - 1);
164
  uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART0_BAUD) - 1);
163
 
165
 
164
  // disable all interrupts before configuration
166
  // disable all interrupts before configuration
165
  cli();
167
  cli();
166
 
168
 
167
  // disable RX-Interrupt
169
  // disable RX-Interrupt
168
  UCSR0B &= ~(1 << RXCIE0);
170
  UCSR0B &= ~(1 << RXCIE0);
169
  // disable TX-Interrupt
171
  // disable TX-Interrupt
170
  UCSR0B &= ~(1 << TXCIE0);
172
  UCSR0B &= ~(1 << TXCIE0);
171
 
173
 
172
  // set direction of RXD0 and TXD0 pins
174
  // set direction of RXD0 and TXD0 pins
173
  // set RXD0 (PD0) as an input pin
175
  // set RXD0 (PD0) as an input pin
174
  PORTD |= (1 << PORTD0);
176
  PORTD |= (1 << PORTD0);
175
  DDRD &= ~(1 << DDD0);
177
  DDRD &= ~(1 << DDD0);
176
  // set TXD0 (PD1) as an output pin
178
  // set TXD0 (PD1) as an output pin
177
  PORTD |= (1 << PORTD1);
179
  PORTD |= (1 << PORTD1);
178
  DDRD |=  (1 << DDD1);
180
  DDRD |=  (1 << DDD1);
179
 
181
 
180
  // USART0 Baud Rate Register
182
  // USART0 Baud Rate Register
181
  // set clock divider
183
  // set clock divider
182
  UBRR0H = (uint8_t)(ubrr >> 8);
184
  UBRR0H = (uint8_t)(ubrr >> 8);
183
  UBRR0L = (uint8_t)ubrr;
185
  UBRR0L = (uint8_t)ubrr;
184
 
186
 
185
  // USART0 Control and Status Register A, B, C
187
  // USART0 Control and Status Register A, B, C
186
 
188
 
187
  // enable double speed operation in
189
  // enable double speed operation in
188
  UCSR0A |= (1 << U2X0);
190
  UCSR0A |= (1 << U2X0);
189
  // enable receiver and transmitter in
191
  // enable receiver and transmitter in
190
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
192
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
191
  // set asynchronous mode
193
  // set asynchronous mode
192
  UCSR0C &= ~(1 << UMSEL01);
194
  UCSR0C &= ~(1 << UMSEL01);
193
  UCSR0C &= ~(1 << UMSEL00);
195
  UCSR0C &= ~(1 << UMSEL00);
194
  // no parity
196
  // no parity
195
  UCSR0C &= ~(1 << UPM01);
197
  UCSR0C &= ~(1 << UPM01);
196
  UCSR0C &= ~(1 << UPM00);
198
  UCSR0C &= ~(1 << UPM00);
197
  // 1 stop bit
199
  // 1 stop bit
198
  UCSR0C &= ~(1 << USBS0);
200
  UCSR0C &= ~(1 << USBS0);
199
  // 8-bit
201
  // 8-bit
200
  UCSR0B &= ~(1 << UCSZ02);
202
  UCSR0B &= ~(1 << UCSZ02);
201
  UCSR0C |=  (1 << UCSZ01);
203
  UCSR0C |=  (1 << UCSZ01);
202
  UCSR0C |=  (1 << UCSZ00);
204
  UCSR0C |=  (1 << UCSZ00);
203
 
205
 
204
  // flush receive buffer
206
  // flush receive buffer
205
  while ( UCSR0A & (1<<RXC0) ) UDR0;
207
  while ( UCSR0A & (1<<RXC0) ) UDR0;
206
 
208
 
207
  // enable interrupts at the end
209
  // enable interrupts at the end
208
  // enable RX-Interrupt
210
  // enable RX-Interrupt
209
  UCSR0B |= (1 << RXCIE0);
211
  UCSR0B |= (1 << RXCIE0);
210
  // enable TX-Interrupt
212
  // enable TX-Interrupt
211
  UCSR0B |= (1 << TXCIE0);
213
  UCSR0B |= (1 << TXCIE0);
212
 
214
 
213
  // initialize the debug timer
215
  // initialize the debug timer
214
  DebugData_Timer = SetDelay(DebugData_Interval);
216
  DebugData_Timer = SetDelay(DebugData_Interval);
215
 
217
 
216
  // unlock rxd_buffer
218
  // unlock rxd_buffer
217
  rxd_buffer_locked = FALSE;
219
  rxd_buffer_locked = FALSE;
218
  pRxData = 0;
220
  pRxData = 0;
219
  RxDataLen = 0;
221
  RxDataLen = 0;
220
 
222
 
221
  // no bytes to send
223
  // no bytes to send
222
  txd_complete = TRUE;
224
  txd_complete = TRUE;
223
 
225
 
224
#ifdef USE_MK3MAG
226
#ifdef USE_MK3MAG
225
  Compass_Timer = SetDelay(220);
227
  Compass_Timer = SetDelay(220);
226
#endif
228
#endif
227
 
229
 
228
  UART_VersionInfo.SWMajor = VERSION_MAJOR;
230
  UART_VersionInfo.SWMajor = VERSION_MAJOR;
229
  UART_VersionInfo.SWMinor = VERSION_MINOR;
231
  UART_VersionInfo.SWMinor = VERSION_MINOR;
230
  UART_VersionInfo.SWPatch = VERSION_PATCH;
232
  UART_VersionInfo.SWPatch = VERSION_PATCH;
231
  UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
233
  UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
232
  UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR;
234
  UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR;
233
 
235
 
234
  // restore global interrupt flags
236
  // restore global interrupt flags
235
  SREG = sreg;
237
  SREG = sreg;
236
}
238
}
237
 
239
 
238
/****************************************************************/
240
/****************************************************************/
239
/* USART0 transmitter ISR                                       */
241
/* USART0 transmitter ISR                                       */
240
/****************************************************************/
242
/****************************************************************/
241
ISR(USART0_TX_vect) {
243
ISR(USART0_TX_vect) {
242
  static uint16_t ptr_txd_buffer = 0;
244
  static uint16_t ptr_txd_buffer = 0;
243
  uint8_t tmp_tx;
245
  uint8_t tmp_tx;
244
  if(!txd_complete) { // transmission not completed
246
  if(!txd_complete) { // transmission not completed
245
    ptr_txd_buffer++;                    // die [0] wurde schon gesendet
247
    ptr_txd_buffer++;                    // die [0] wurde schon gesendet
246
    tmp_tx = txd_buffer[ptr_txd_buffer];
248
    tmp_tx = txd_buffer[ptr_txd_buffer];
247
    // if terminating character or end of txd buffer was reached
249
    // if terminating character or end of txd buffer was reached
248
    if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) {
250
    if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN)) {
249
      ptr_txd_buffer = 0; // reset txd pointer
251
      ptr_txd_buffer = 0; // reset txd pointer
250
      txd_complete = 1; // stop transmission
252
      txd_complete = 1; // stop transmission
251
    }
253
    }
252
    UDR0 = tmp_tx; // send current byte will trigger this ISR again
254
    UDR0 = tmp_tx; // send current byte will trigger this ISR again
253
  }
255
  }
254
  // transmission completed
256
  // transmission completed
255
  else ptr_txd_buffer = 0;
257
  else ptr_txd_buffer = 0;
256
}
258
}
257
 
259
 
258
/****************************************************************/
260
/****************************************************************/
259
/* USART0 receiver               ISR                            */
261
/* USART0 receiver               ISR                            */
260
/****************************************************************/
262
/****************************************************************/
261
ISR(USART0_RX_vect) {
263
ISR(USART0_RX_vect) {
262
  static uint16_t crc;
264
  static uint16_t crc;
263
  static uint8_t ptr_rxd_buffer = 0;
265
  static uint8_t ptr_rxd_buffer = 0;
264
  uint8_t crc1, crc2;
266
  uint8_t crc1, crc2;
265
  uint8_t c;
267
  uint8_t c;
266
 
268
 
267
  c = UDR0;  // catch the received byte
269
  c = UDR0;  // catch the received byte
268
 
270
 
269
#if (defined (USE_MK3MAG))
271
#if (defined (USE_MK3MAG))
270
  // If the cpu is not an Atmega644P the ublox module should be conneced to rxd of the 1st uart.
272
  // If the cpu is not an Atmega644P the ublox module should be conneced to rxd of the 1st uart.
271
  if(CPUType != ATMEGA644P) ubx_parser(c);
273
  if(CPUType != ATMEGA644P) ubx_parser(c);
272
#endif
274
#endif
273
 
275
 
274
  if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
276
  if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
275
 
277
 
276
  // the rxd buffer is unlocked
278
  // the rxd buffer is unlocked
277
  if((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received
279
  if((ptr_rxd_buffer == 0) && (c == '#')) { // if rxd buffer is empty and syncronisation character is received
278
    rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
280
    rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
279
    crc = c; // init crc
281
    crc = c; // init crc
280
  }
282
  }
281
#if 0
283
#if 0
282
  else if (ptr_rxd_buffer == 1) { // handle address
284
  else if (ptr_rxd_buffer == 1) { // handle address
283
    rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
285
    rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
284
    crc += c; // update crc
286
    crc += c; // update crc
285
  }
287
  }
286
#endif
288
#endif
287
  else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes
289
  else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes
288
    if(c != '\r') { // no termination character
290
    if(c != '\r') { // no termination character
289
      rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
291
      rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
290
      crc += c; // update crc
292
      crc += c; // update crc
291
    } else { // termination character was received
293
    } else { // termination character was received
292
      // the last 2 bytes are no subject for checksum calculation
294
      // the last 2 bytes are no subject for checksum calculation
293
      // they are the checksum itself
295
      // they are the checksum itself
294
      crc -= rxd_buffer[ptr_rxd_buffer-2];
296
      crc -= rxd_buffer[ptr_rxd_buffer-2];
295
      crc -= rxd_buffer[ptr_rxd_buffer-1];
297
      crc -= rxd_buffer[ptr_rxd_buffer-1];
296
      // calculate checksum from transmitted data
298
      // calculate checksum from transmitted data
297
      crc %= 4096;
299
      crc %= 4096;
298
      crc1 = '=' + crc / 64;
300
      crc1 = '=' + crc / 64;
299
      crc2 = '=' + crc % 64;
301
      crc2 = '=' + crc % 64;
300
      // compare checksum to transmitted checksum bytes
302
      // compare checksum to transmitted checksum bytes
301
      if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1])) {
303
      if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1])) {
302
        // checksum valid
304
        // checksum valid
303
        rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
305
        rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
304
        ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
306
        ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
305
        rxd_buffer_locked = TRUE;          // lock the rxd buffer
307
        rxd_buffer_locked = TRUE;          // lock the rxd buffer
306
        // if 2nd byte is an 'R' enable watchdog that will result in an reset
308
        // if 2nd byte is an 'R' enable watchdog that will result in an reset
307
        if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
309
        if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
308
      } else {  // checksum invalid
310
      } else {  // checksum invalid
309
        rxd_buffer_locked = FALSE; // unlock rxd buffer
311
        rxd_buffer_locked = FALSE; // unlock rxd buffer
310
      }
312
      }
311
      ptr_rxd_buffer = 0; // reset rxd buffer pointer
313
      ptr_rxd_buffer = 0; // reset rxd buffer pointer
312
    }
314
    }
313
  } else { // rxd buffer overrun
315
  } else { // rxd buffer overrun
314
    ptr_rxd_buffer = 0; // reset rxd buffer
316
    ptr_rxd_buffer = 0; // reset rxd buffer
315
    rxd_buffer_locked = FALSE; // unlock rxd buffer
317
    rxd_buffer_locked = FALSE; // unlock rxd buffer
316
  }
318
  }
317
}
319
}
318
 
320
 
319
// --------------------------------------------------------------------------
321
// --------------------------------------------------------------------------
320
void AddCRC(uint16_t datalen) {
322
void AddCRC(uint16_t datalen) {
321
  uint16_t tmpCRC = 0, i;
323
  uint16_t tmpCRC = 0, i;
322
  for(i = 0; i < datalen; i++) {
324
  for(i = 0; i < datalen; i++) {
323
    tmpCRC += txd_buffer[i];
325
    tmpCRC += txd_buffer[i];
324
  }
326
  }
325
  tmpCRC %= 4096;
327
  tmpCRC %= 4096;
326
  txd_buffer[i++] = '=' + tmpCRC / 64;
328
  txd_buffer[i++] = '=' + tmpCRC / 64;
327
  txd_buffer[i++] = '=' + tmpCRC % 64;
329
  txd_buffer[i++] = '=' + tmpCRC % 64;
328
  txd_buffer[i++] = '\r';
330
  txd_buffer[i++] = '\r';
329
  txd_complete = FALSE;
331
  txd_complete = FALSE;
330
  UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
332
  UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
331
}
333
}
332
 
334
 
333
// --------------------------------------------------------------------------
335
// --------------------------------------------------------------------------
334
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
336
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
335
  va_list ap;
337
  va_list ap;
336
  uint16_t pt = 0;
338
  uint16_t pt = 0;
337
  uint8_t a,b,c;
339
  uint8_t a,b,c;
338
  uint8_t ptr = 0;
340
  uint8_t ptr = 0;
339
 
341
 
340
  uint8_t *pdata = 0;
342
  uint8_t *pdata = 0;
341
  int len = 0;
343
  int len = 0;
342
 
344
 
343
  txd_buffer[pt++] = '#';                       // Start character
345
  txd_buffer[pt++] = '#';                       // Start character
344
  txd_buffer[pt++] = 'a' + addr;        // Address (a=0; b=1,...)
346
  txd_buffer[pt++] = 'a' + addr;        // Address (a=0; b=1,...)
345
  txd_buffer[pt++] = cmd;                       // Command
347
  txd_buffer[pt++] = cmd;                       // Command
346
 
348
 
347
  va_start(ap, numofbuffers);
349
  va_start(ap, numofbuffers);
348
 
350
 
349
  if(numofbuffers) {
351
  if(numofbuffers) {
350
    pdata = va_arg(ap, uint8_t*);
352
    pdata = va_arg(ap, uint8_t*);
351
    len = va_arg(ap, int);
353
    len = va_arg(ap, int);
352
    ptr = 0;
354
    ptr = 0;
353
    numofbuffers--;
355
    numofbuffers--;
354
  }
356
  }
355
 
357
 
356
  while(len){
358
  while(len){
357
    if(len) {
359
    if(len) {
358
      a = pdata[ptr++];
360
      a = pdata[ptr++];
359
      len--;
361
      len--;
360
      if((!len) && numofbuffers) {
362
      if((!len) && numofbuffers) {
361
        pdata = va_arg(ap, uint8_t*);
363
        pdata = va_arg(ap, uint8_t*);
362
        len = va_arg(ap, int);
364
        len = va_arg(ap, int);
363
        ptr = 0;
365
        ptr = 0;
364
        numofbuffers--;
366
        numofbuffers--;
365
      }
367
      }
366
    }
368
    }
367
    else a = 0;
369
    else a = 0;
368
    if(len) {
370
    if(len) {
369
      b = pdata[ptr++];
371
      b = pdata[ptr++];
370
      len--;
372
      len--;
371
      if((!len) && numofbuffers) {
373
      if((!len) && numofbuffers) {
372
        pdata = va_arg(ap, uint8_t*);
374
        pdata = va_arg(ap, uint8_t*);
373
        len = va_arg(ap, int);
375
        len = va_arg(ap, int);
374
        ptr = 0;
376
        ptr = 0;
375
        numofbuffers--;
377
        numofbuffers--;
376
      }
378
      }
377
    } else b = 0;
379
    } else b = 0;
378
    if(len) {
380
    if(len) {
379
      c = pdata[ptr++];
381
      c = pdata[ptr++];
380
      len--;
382
      len--;
381
      if((!len) && numofbuffers) {
383
      if((!len) && numofbuffers) {
382
        pdata = va_arg(ap, uint8_t*);
384
        pdata = va_arg(ap, uint8_t*);
383
        len = va_arg(ap, int);
385
        len = va_arg(ap, int);
384
        ptr = 0;
386
        ptr = 0;
385
        numofbuffers--;
387
        numofbuffers--;
386
      }
388
      }
387
    }
389
    }
388
    else c = 0;
390
    else c = 0;
389
    txd_buffer[pt++] = '=' + (a >> 2);
391
    txd_buffer[pt++] = '=' + (a >> 2);
390
    txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
392
    txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
391
    txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
393
    txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
392
    txd_buffer[pt++] = '=' + ( c & 0x3f);
394
    txd_buffer[pt++] = '=' + ( c & 0x3f);
393
  }
395
  }
394
  va_end(ap);
396
  va_end(ap);
395
  AddCRC(pt); // add checksum after data block and initates the transmission
397
  AddCRC(pt); // add checksum after data block and initates the transmission
396
}
398
}
397
 
399
 
398
// --------------------------------------------------------------------------
400
// --------------------------------------------------------------------------
399
void Decode64(void) {
401
void Decode64(void) {
400
  uint8_t a,b,c,d;
402
  uint8_t a,b,c,d;
401
  uint8_t x,y,z;
403
  uint8_t x,y,z;
402
  uint8_t ptrIn = 3;
404
  uint8_t ptrIn = 3;
403
  uint8_t ptrOut = 3;
405
  uint8_t ptrOut = 3;
404
  uint8_t len = ReceivedBytes - 6;
406
  uint8_t len = ReceivedBytes - 6;
405
 
407
 
406
  while(len) {
408
  while(len) {
407
    a = rxd_buffer[ptrIn++] - '=';
409
    a = rxd_buffer[ptrIn++] - '=';
408
    b = rxd_buffer[ptrIn++] - '=';
410
    b = rxd_buffer[ptrIn++] - '=';
409
    c = rxd_buffer[ptrIn++] - '=';
411
    c = rxd_buffer[ptrIn++] - '=';
410
    d = rxd_buffer[ptrIn++] - '=';
412
    d = rxd_buffer[ptrIn++] - '=';
411
    //if(ptrIn > ReceivedBytes - 3) break;
413
    //if(ptrIn > ReceivedBytes - 3) break;
412
   
414
   
413
    x = (a << 2) | (b >> 4);
415
    x = (a << 2) | (b >> 4);
414
    y = ((b & 0x0f) << 4) | (c >> 2);
416
    y = ((b & 0x0f) << 4) | (c >> 2);
415
    z = ((c & 0x03) << 6) | d;
417
    z = ((c & 0x03) << 6) | d;
416
   
418
   
417
    if(len--) rxd_buffer[ptrOut++] = x; else break;
419
    if(len--) rxd_buffer[ptrOut++] = x; else break;
418
    if(len--) rxd_buffer[ptrOut++] = y; else break;
420
    if(len--) rxd_buffer[ptrOut++] = y; else break;
419
    if(len--) rxd_buffer[ptrOut++] = z; else break;
421
    if(len--) rxd_buffer[ptrOut++] = z; else break;
420
  }
422
  }
421
  pRxData = &rxd_buffer[3];
423
  pRxData = &rxd_buffer[3];
422
  RxDataLen = ptrOut - 3;
424
  RxDataLen = ptrOut - 3;
423
}
425
}
424
 
426
 
425
// --------------------------------------------------------------------------
427
// --------------------------------------------------------------------------
426
void USART0_ProcessRxData(void) {
428
void USART0_ProcessRxData(void) {
427
  // if data in the rxd buffer are not locked immediately return
429
  // if data in the rxd buffer are not locked immediately return
428
  if(!rxd_buffer_locked) return;
430
  if(!rxd_buffer_locked) return;
429
 
431
 
430
  uint8_t tempchar1, tempchar2;
432
  uint8_t tempchar1, tempchar2;
431
 
433
 
432
  Decode64(); // decode data block in rxd_buffer
434
  Decode64(); // decode data block in rxd_buffer
433
 
435
 
434
  switch(rxd_buffer[1] - 'a') {
436
  switch(rxd_buffer[1] - 'a') {
435
  case FC_ADDRESS:
437
  case FC_ADDRESS:
436
    switch(rxd_buffer[2]) {
438
    switch(rxd_buffer[2]) {
437
#ifdef USE_MK3MAG
439
#ifdef USE_MK3MAG
438
    case 'K':// compass value
440
    case 'K':// compass value
439
      CompassHeading = ((Heading_t *)pRxData)->Heading;
441
      CompassHeading = ((Heading_t *)pRxData)->Heading;
440
      CompassOffCourse = ((540 + CompassHeading - CompassCourse) % 360) - 180;
442
      CompassOffCourse = ((540 + CompassHeading - CompassCourse) % 360) - 180;
441
      break;
443
      break;
442
#endif
444
#endif
443
     
445
     
444
    case 't':// motor test
446
    case 't':// motor test
445
      if(RxDataLen > 20) //
447
      if(RxDataLen > 20) //
446
        {
448
        {
447
          memcpy(&motorTest[0], (uint8_t*)pRxData, sizeof(motorTest));
449
          memcpy(&motorTest[0], (uint8_t*)pRxData, sizeof(motorTest));
448
        }
450
        }
449
      else
451
      else
450
        {
452
        {
451
          memcpy(&motorTest[0], (uint8_t*)pRxData, 4);
453
          memcpy(&motorTest[0], (uint8_t*)pRxData, 4);
452
        }
454
        }
453
      //Request_MotorTest = TRUE;
455
      //Request_MotorTest = TRUE;
454
      motorTestActive = 255;
456
      motorTestActive = 255;
455
      externalControlActive = 255;
457
      externalControlActive = 255;
456
      break;
458
      break;
457
     
459
     
458
    case 'n':// "Get Mixer Table
460
    case 'n':// "Get Mixer Table
459
      while(!txd_complete); // wait for previous frame to be sent
461
      while(!txd_complete); // wait for previous frame to be sent
460
      SendOutData('N', FC_ADDRESS, 1, (uint8_t *) &Mixer, sizeof(Mixer));
462
      SendOutData('N', FC_ADDRESS, 1, (uint8_t *) &Mixer, sizeof(Mixer));
461
      break;
463
      break;
462
 
464
 
463
    case 'm':// "Set Mixer Table
465
    case 'm':// "Set Mixer Table
464
      if(pRxData[0] == EEMIXER_REVISION)
466
      if(pRxData[0] == EEMIXER_REVISION)
465
        {
467
        {
466
          memcpy(&Mixer, (uint8_t*)pRxData, sizeof(Mixer));
468
          memcpy(&Mixer, (uint8_t*)pRxData, sizeof(Mixer));
467
          MixerTable_WriteToEEProm();
469
          MixerTable_WriteToEEProm();
468
          while(!txd_complete); // wait for previous frame to be sent
470
          while(!txd_complete); // wait for previous frame to be sent
469
          tempchar1 = 1;
471
          tempchar1 = 1;
470
        }
472
        }
471
      else
473
      else
472
        {
474
        {
473
          tempchar1 = 0;
475
          tempchar1 = 0;
474
        }
476
        }
475
      SendOutData('M', FC_ADDRESS,  1, &tempchar1, 1);
477
      SendOutData('M', FC_ADDRESS,  1, &tempchar1, 1);
476
      break;
478
      break;
477
 
479
 
478
    case 'p': // get PPM channels
480
    case 'p': // get PPM channels
479
      Request_PPMChannels = TRUE;
481
      Request_PPMChannels = TRUE;
480
      break;
482
      break;
481
 
483
 
482
    case 'q':// request settings
484
    case 'q':// request settings
483
      if(pRxData[0] == 0xFF)
485
      if(pRxData[0] == 0xFF)
484
        {
486
        {
485
          pRxData[0] = GetParamByte(PID_ACTIVE_SET);
487
          pRxData[0] = GetParamByte(PID_ACTIVE_SET);
486
        }
488
        }
487
      // limit settings range
489
      // limit settings range
488
      if(pRxData[0] < 1) pRxData[0] = 1; // limit to 1
490
      if(pRxData[0] < 1) pRxData[0] = 1; // limit to 1
489
      else if(pRxData[0] > 5) pRxData[0] = 5; // limit to 5
491
      else if(pRxData[0] > 5) pRxData[0] = 5; // limit to 5
490
      // load requested parameter set
492
      // load requested parameter set
491
      ParamSet_ReadFromEEProm(pRxData[0]);
493
      ParamSet_ReadFromEEProm(pRxData[0]);
492
      tempchar1 = pRxData[0];
494
      tempchar1 = pRxData[0];
493
      tempchar2 = EEPARAM_REVISION;
495
      tempchar2 = EEPARAM_REVISION;
494
      while(!txd_complete); // wait for previous frame to be sent
496
      while(!txd_complete); // wait for previous frame to be sent
495
      SendOutData('Q', FC_ADDRESS,3, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), (uint8_t *) &staticParams, sizeof(staticParams));
497
      SendOutData('Q', FC_ADDRESS,3, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), (uint8_t *) &staticParams, sizeof(staticParams));
496
      break;
498
      break;
497
 
499
 
498
    case 's': // save settings
500
    case 's': // save settings
499
      if(!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors ar off
501
      if(!(MKFlags & MKFLAG_MOTOR_RUN)) // save settings only if motors ar off
500
        {
502
        {
501
          if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION)) // check for setting to be in range and version of settings
503
          if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION)) // check for setting to be in range and version of settings
502
            {
504
            {
503
              memcpy(&staticParams, (uint8_t*)&pRxData[2], sizeof(staticParams));
505
              memcpy(&staticParams, (uint8_t*)&pRxData[2], sizeof(staticParams));
504
              ParamSet_WriteToEEProm(pRxData[0]);
506
              ParamSet_WriteToEEProm(pRxData[0]);
505
              /*
507
              /*
506
                TODO: Remove this encapsulation breach
508
                TODO: Remove this encapsulation breach
507
                turnOver180Pitch = (int32_t) staticParams.AngleTurnOverPitch * 2500L;
509
                turnOver180Pitch = (int32_t) staticParams.AngleTurnOverPitch * 2500L;
508
                turnOver180Roll = (int32_t) staticParams.AngleTurnOverRoll * 2500L;
510
                turnOver180Roll = (int32_t) staticParams.AngleTurnOverRoll * 2500L;
509
              */
511
              */
510
              tempchar1 = getActiveParamSet();
512
              tempchar1 = getActiveParamSet();
511
              beepNumber(tempchar1);
513
              beepNumber(tempchar1);
512
            }
514
            }
513
          else
515
          else
514
            {
516
            {
515
              tempchar1 = 0;    //indicate bad data
517
              tempchar1 = 0;    //indicate bad data
516
            }
518
            }
517
          while(!txd_complete); // wait for previous frame to be sent
519
          while(!txd_complete); // wait for previous frame to be sent
518
          SendOutData('S', FC_ADDRESS,1, &tempchar1, sizeof(tempchar1));
520
          SendOutData('S', FC_ADDRESS,1, &tempchar1, sizeof(tempchar1));
519
        }
521
        }
520
      break;
522
      break;
521
 
523
 
522
    default:
524
    default:
523
      //unsupported command received
525
      //unsupported command received
524
      break;
526
      break;
525
    } // case FC_ADDRESS:
527
    } // case FC_ADDRESS:
526
 
528
 
527
  default: // any Slave Address
529
  default: // any Slave Address
528
 
530
 
529
    switch(rxd_buffer[2])
531
    switch(rxd_buffer[2])
530
      {
532
      {
531
      case 'a':// request for labels of the analog debug outputs
533
      case 'a':// request for labels of the analog debug outputs
532
        Request_DebugLabel = pRxData[0];
534
        Request_DebugLabel = pRxData[0];
533
        if(Request_DebugLabel > 31) Request_DebugLabel = 31;
535
        if(Request_DebugLabel > 31) Request_DebugLabel = 31;
534
        externalControlActive = 255;
536
        externalControlActive = 255;
535
        break;
537
        break;
536
 
538
 
537
      case 'b': // submit extern control
539
      case 'b': // submit extern control
538
        memcpy(&externalControl, (uint8_t*)pRxData, sizeof(externalControl));
540
        memcpy(&externalControl, (uint8_t*)pRxData, sizeof(externalControl));
539
        ConfirmFrame = externalControl.frame;
541
        ConfirmFrame = externalControl.frame;
540
        externalControlActive = 255;
542
        externalControlActive = 255;
541
        break;
543
        break;
542
 
544
 
543
      case 'h':// request for display columns
545
      case 'h':// request for display columns
544
        externalControlActive = 255;
546
        externalControlActive = 255;
545
        RemoteKeys |= pRxData[0];
547
        RemoteKeys |= pRxData[0];
546
        if(RemoteKeys) DisplayLine = 0;
548
        if(RemoteKeys) DisplayLine = 0;
547
        Request_Display = TRUE;
549
        Request_Display = TRUE;
548
        break;
550
        break;
549
 
551
 
550
      case 'l':// request for display columns
552
      case 'l':// request for display columns
551
        externalControlActive = 255;
553
        externalControlActive = 255;
552
        MenuItem = pRxData[0];
554
        MenuItem = pRxData[0];
553
        Request_Display1 = TRUE;
555
        Request_Display1 = TRUE;
554
        break;
556
        break;
555
 
557
 
556
      case 'v': // request for version and board release
558
      case 'v': // request for version and board release
557
        Request_VerInfo = TRUE;
559
        Request_VerInfo = TRUE;
558
        break;
560
        break;
559
 
561
 
560
      case 'g':// get external control data
562
      case 'g':// get external control data
561
        Request_ExternalControl = TRUE;
563
        Request_ExternalControl = TRUE;
562
        break;
564
        break;
563
 
565
 
564
      case 'd': // request for the debug data
566
      case 'd': // request for the debug data
565
        DebugData_Interval = (uint16_t) pRxData[0] * 10;
567
        DebugData_Interval = (uint16_t) pRxData[0] * 10;
566
        if(DebugData_Interval > 0) Request_DebugData = TRUE;
568
        if(DebugData_Interval > 0) Request_DebugData = TRUE;
567
        break;
569
        break;
568
 
570
 
569
      case 'c': // request for the 3D data
571
      case 'c': // request for the 3D data
570
        Data3D_Interval = (uint16_t) pRxData[0] * 10;
572
        Data3D_Interval = (uint16_t) pRxData[0] * 10;
571
        if(Data3D_Interval > 0) Request_Data3D = TRUE;
573
        if(Data3D_Interval > 0) Request_Data3D = TRUE;
572
        break;
574
        break;
573
 
575
 
574
      default:
576
      default:
575
        //unsupported command received
577
        //unsupported command received
576
        break;
578
        break;
577
      }
579
      }
578
    break; // default:
580
    break; // default:
579
  }
581
  }
580
  // unlock the rxd buffer after processing
582
  // unlock the rxd buffer after processing
581
  pRxData = 0;
583
  pRxData = 0;
582
  RxDataLen = 0;
584
  RxDataLen = 0;
583
  rxd_buffer_locked = FALSE;
585
  rxd_buffer_locked = FALSE;
584
}
586
}
585
 
587
 
586
//############################################################################
588
//############################################################################
587
//Routine für die Serielle Ausgabe
589
//Routine für die Serielle Ausgabe
588
//############################################################################
590
//############################################################################
589
int16_t uart_putchar (int8_t c) {
591
int16_t uart_putchar (int8_t c) {
590
  if (c == '\n')
592
  if (c == '\n')
591
    uart_putchar('\r');
593
    uart_putchar('\r');
592
  // wait until previous character was send
594
  // wait until previous character was send
593
  loop_until_bit_is_set(UCSR0A, UDRE0);
595
  loop_until_bit_is_set(UCSR0A, UDRE0);
594
  // send character
596
  // send character
595
  UDR0 = c;
597
  UDR0 = c;
596
  return (0);
598
  return (0);
597
}
599
}
598
 
600
 
599
//---------------------------------------------------------------------------------------------
601
//---------------------------------------------------------------------------------------------
600
void USART0_TransmitTxData(void) {
602
void USART0_TransmitTxData(void) {
601
  if(!txd_complete) return;
603
  if(!txd_complete) return;
602
 
604
 
603
  if(Request_VerInfo && txd_complete) {
605
  if(Request_VerInfo && txd_complete) {
604
    SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, sizeof(UART_VersionInfo));
606
    SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, sizeof(UART_VersionInfo));
605
    Request_VerInfo = FALSE;
607
    Request_VerInfo = FALSE;
606
  }
608
  }
607
 
609
 
608
  if(Request_Display && txd_complete) {
610
  if(Request_Display && txd_complete) {
609
    LCD_PrintMenu();
611
    LCD_PrintMenu();
610
    SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20);
612
    SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20);
611
    DisplayLine++;
613
    DisplayLine++;
612
    if(DisplayLine >= 4) DisplayLine = 0;
614
    if(DisplayLine >= 4) DisplayLine = 0;
613
    Request_Display = FALSE;
615
    Request_Display = FALSE;
614
  }
616
  }
615
 
617
 
616
  if(Request_Display1 && txd_complete) {
618
  if(Request_Display1 && txd_complete) {
617
    LCD_PrintMenu();
619
    LCD_PrintMenu();
618
    SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
620
    SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
619
    Request_Display1 = FALSE;
621
    Request_Display1 = FALSE;
620
  }
622
  }
621
 
623
 
622
  if(Request_DebugLabel != 0xFF) { // Texte für die Analogdaten
624
  if(Request_DebugLabel != 0xFF) { // Texte für die Analogdaten
623
    uint8_t label[16]; // local sram buffer
625
    uint8_t label[16]; // local sram buffer
624
    memcpy_P(label, ANALOG_LABEL[Request_DebugLabel], 16); // read lable from flash to sram buffer
626
    memcpy_P(label, ANALOG_LABEL[Request_DebugLabel], 16); // read lable from flash to sram buffer
625
    SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &Request_DebugLabel, sizeof(Request_DebugLabel), label, 16);
627
    SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &Request_DebugLabel, sizeof(Request_DebugLabel), label, 16);
626
    Request_DebugLabel = 0xFF;
628
    Request_DebugLabel = 0xFF;
627
  }
629
  }
628
 
630
 
629
  if(ConfirmFrame && txd_complete) {   // Datensatz ohne CRC bestätigen
631
  if(ConfirmFrame && txd_complete) {   // Datensatz ohne CRC bestätigen
630
    SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(ConfirmFrame));
632
    SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(ConfirmFrame));
631
    ConfirmFrame = 0;
633
    ConfirmFrame = 0;
632
  }
634
  }
633
 
635
 
634
  if(((DebugData_Interval && CheckDelay(DebugData_Timer)) || Request_DebugData) && txd_complete) {
636
  if(((DebugData_Interval && CheckDelay(DebugData_Timer)) || Request_DebugData) && txd_complete) {
635
    SendOutData('D', FC_ADDRESS, 1,(uint8_t *) &DebugOut, sizeof(DebugOut));
637
    SendOutData('D', FC_ADDRESS, 1,(uint8_t *) &DebugOut, sizeof(DebugOut));
636
    DebugData_Timer = SetDelay(DebugData_Interval);
638
    DebugData_Timer = SetDelay(DebugData_Interval);
637
    Request_DebugData = FALSE;
639
    Request_DebugData = FALSE;
638
  }
640
  }
639
 
641
 
640
  if( ((Data3D_Interval && CheckDelay(Data3D_Timer)) || Request_Data3D) && txd_complete) {
642
  if( ((Data3D_Interval && CheckDelay(Data3D_Timer)) || Request_Data3D) && txd_complete) {
641
    SendOutData('C', FC_ADDRESS, 1,(uint8_t *) &Data3D, sizeof(Data3D));
643
    SendOutData('C', FC_ADDRESS, 1,(uint8_t *) &Data3D, sizeof(Data3D));
642
    Data3D.AngleNick = (int16_t)((10 * pitchAngle) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
644
    Data3D.AngleNick = (int16_t)((10 * pitchAngle) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
643
    Data3D.AngleRoll = (int16_t)((10 * rollAngle) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
645
    Data3D.AngleRoll = (int16_t)((10 * rollAngle) / GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
644
    Data3D.Heading   = (int16_t)((10 * yawGyroHeading)   / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1°
646
    Data3D.Heading   = (int16_t)((10 * yawGyroHeading)   / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1°
645
    Data3D_Timer = SetDelay(Data3D_Interval);
647
    Data3D_Timer = SetDelay(Data3D_Interval);
646
    Request_Data3D = FALSE;
648
    Request_Data3D = FALSE;
647
  }
649
  }
648
 
650
 
649
  if(Request_ExternalControl && txd_complete) {
651
  if(Request_ExternalControl && txd_complete) {
650
    SendOutData('G', FC_ADDRESS, 1,(uint8_t *) &externalControl, sizeof(externalControl));
652
    SendOutData('G', FC_ADDRESS, 1,(uint8_t *) &externalControl, sizeof(externalControl));
651
    Request_ExternalControl = FALSE;
653
    Request_ExternalControl = FALSE;
652
  }
654
  }
653
 
655
 
654
#ifdef USE_MK3MAG
656
#ifdef USE_MK3MAG
655
  if((CheckDelay(Compass_Timer)) && txd_complete) {
657
  if((CheckDelay(Compass_Timer)) && txd_complete) {
656
    ToMk3Mag.Attitude[0] = (int16_t)((10 * pitchAngle) / GYRO_DEG_FACTOR_PITCH_ROLL);  // approx. 0.1 deg
658
    ToMk3Mag.Attitude[0] = (int16_t)((10 * pitchAngle) / GYRO_DEG_FACTOR_PITCH_ROLL);  // approx. 0.1 deg
657
    ToMk3Mag.Attitude[1] = (int16_t)((10 * rollAngle) / GYRO_DEG_FACTOR_PITCH_ROLL);  // approx. 0.1 deg
659
    ToMk3Mag.Attitude[1] = (int16_t)((10 * rollAngle) / GYRO_DEG_FACTOR_PITCH_ROLL);  // approx. 0.1 deg
658
    ToMk3Mag.UserParam[0] = dynamicParams.UserParams[0];
660
    ToMk3Mag.UserParam[0] = dynamicParams.UserParams[0];
659
    ToMk3Mag.UserParam[1] = dynamicParams.UserParams[1];
661
    ToMk3Mag.UserParam[1] = dynamicParams.UserParams[1];
660
    ToMk3Mag.CalState = CompassCalState;
662
    ToMk3Mag.CalState = CompassCalState;
661
    SendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &ToMk3Mag,sizeof(ToMk3Mag));
663
    SendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &ToMk3Mag,sizeof(ToMk3Mag));
662
    // the last state is 5 and should be send only once to avoid multiple flash writing
664
    // the last state is 5 and should be send only once to avoid multiple flash writing
663
    if(CompassCalState > 4)  CompassCalState = 0;
665
    if(CompassCalState > 4)  CompassCalState = 0;
664
    Compass_Timer = SetDelay(99);
666
    Compass_Timer = SetDelay(99);
665
  }
667
  }
666
#endif
668
#endif
667
 
669
 
668
  if(Request_MotorTest && txd_complete) {
670
  if(Request_MotorTest && txd_complete) {
669
    SendOutData('T', FC_ADDRESS, 0);
671
    SendOutData('T', FC_ADDRESS, 0);
670
    Request_MotorTest = FALSE;
672
    Request_MotorTest = FALSE;
671
  }
673
  }
672
 
674
 
673
  if(Request_PPMChannels && txd_complete) {
675
  if(Request_PPMChannels && txd_complete) {
674
    SendOutData('P', FC_ADDRESS, 1, (uint8_t *)&PPM_in, sizeof(PPM_in));
676
    SendOutData('P', FC_ADDRESS, 1, (uint8_t *)&PPM_in, sizeof(PPM_in));
675
    Request_PPMChannels = FALSE;
677
    Request_PPMChannels = FALSE;
676
  }
678
  }
677
}
679
}
678
 
680