Subversion Repositories FlightCtrl

Rev

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

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