Subversion Repositories FlightCtrl

Rev

Rev 1796 | Rev 1864 | Go to most recent revision | Only display areas with differences | Ignore 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
270
 
267
 
-
 
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;
-
 
423
                                numofbuffers--;
422
        numofbuffers--;
424
                        }
423
      }
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;
463
   
465
 
-
 
466
                if (len--)
464
    if(len--) rxd_buffer[ptrOut++] = x; else break;
467
                        rxd_buffer[ptrOut++] = x;
-
 
468
                else
-
 
469
                        break;
-
 
470
                if (len--)
465
    if(len--) rxd_buffer[ptrOut++] = y; else break;
471
                        rxd_buffer[ptrOut++] = y;
-
 
472
                else
-
 
473
                        break;
-
 
474
                if (len--)
466
    if(len--) rxd_buffer[ptrOut++] = z; else break;
475
                        rxd_buffer[ptrOut++] = z;
-
 
476
                else
-
 
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;
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;
-
 
668
 
-
 
669
        if (request_VerInfo && txd_complete) {
-
 
670
                SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo,
-
 
671
                                sizeof(UART_VersionInfo));
-
 
672
                request_VerInfo = FALSE;
-
 
673
        }
-
 
674
 
-
 
675
        if (request_Display && txd_complete) {
-
 
676
                LCD_PrintMenu();
-
 
677
                SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine),
-
 
678
                                &DisplayBuff[DisplayLine * 20], 20);
-
 
679
                DisplayLine++;
-
 
680
                if (DisplayLine >= 4)
-
 
681
                        DisplayLine = 0;
-
 
682
                request_Display = FALSE;
-
 
683
        }
-
 
684
 
-
 
685
        if (request_Display1 && txd_complete) {
-
 
686
                LCD_PrintMenu();
-
 
687
                SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem,
-
 
688
                                sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
-
 
689
                request_Display1 = FALSE;
-
 
690
        }
-
 
691
 
-
 
692
        if (request_DebugLabel != 0xFF) { // Texte für die Analogdaten
-
 
693
                uint8_t label[16]; // local sram buffer
-
 
694
                memcpy_P(label, ANALOG_LABEL[request_DebugLabel], 16); // read lable from flash to sram buffer
-
 
695
                SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &request_DebugLabel,
-
 
696
                                sizeof(request_DebugLabel), label, 16);
-
 
697
                request_DebugLabel = 0xFF;
-
 
698
        }
643
 
-
 
644
  if(request_VerInfo && txd_complete) {
-
 
645
    SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, sizeof(UART_VersionInfo));
-
 
646
    request_VerInfo = FALSE;
-
 
647
  }
-
 
648
 
-
 
649
  if(request_Display && txd_complete) {
-
 
650
    LCD_PrintMenu();
-
 
651
    SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20);
-
 
652
    DisplayLine++;
-
 
653
    if(DisplayLine >= 4) DisplayLine = 0;
-
 
654
    request_Display = FALSE;
-
 
655
  }
-
 
656
 
-
 
657
  if(request_Display1 && txd_complete) {
-
 
658
    LCD_PrintMenu();
-
 
659
    SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
-
 
660
    request_Display1 = FALSE;
-
 
661
  }
-
 
662
 
-
 
663
  if(request_DebugLabel != 0xFF) { // Texte für die Analogdaten
-
 
664
    uint8_t label[16]; // local sram buffer
-
 
665
    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);
-
 
667
    request_DebugLabel = 0xFF;
-
 
668
  }
-
 
669
 
699
 
670
  if(ConfirmFrame && txd_complete) {   // Datensatz ohne CRC bestätigen
700
        if (ConfirmFrame && txd_complete) { // Datensatz ohne CRC bestätigen
-
 
701
                SendOutData('B', FC_ADDRESS, 1, (uint8_t*) &ConfirmFrame,
671
    SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(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) {
-
 
726
                SendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl,
691
    SendOutData('G', FC_ADDRESS, 1,(uint8_t *) &externalControl, sizeof(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