Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1915 - 1
/*****************************************************************************
2
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
3
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
4
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
5
 *   Copyright (C) 2011 Harald Bongartz                                      *
6
 *                                                                           *
7
 *   This program is free software; you can redistribute it and/or modify    *
8
 *   it under the terms of the GNU General Public License as published by    *
9
 *   the Free Software Foundation; either version 2 of the License.          *
10
 *                                                                           *
11
 *   This program is distributed in the hope that it will be useful,         *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
14
 *   GNU General Public License for more details.                            *
15
 *                                                                           *
16
 *   You should have received a copy of the GNU General Public License       *
17
 *   along with this program; if not, write to the                           *
18
 *   Free Software Foundation, Inc.,                                         *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
20
 *                                                                           *
21
 *                                                                           *
22
 *   Credits to:                                                             *
23
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
24
 *                          http://www.mikrokopter.de                        *
25
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
26
 *   Thomas Kaiser "thkais" for the original project. See                    *
27
 *                          http://www.ft-fanpage.de/mikrokopter/            *
28
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
29
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
30
 *                          http://www.mylifesucks.de/oss/c-osd/             *
31
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
32
 *****************************************************************************/
33
 
34
 
35
#include <avr/io.h>
36
#include <avr/interrupt.h>
37
#include <avr/pgmspace.h>
38
#include <avr/wdt.h>
39
#include "../cpu.h"
40
#include <util/delay.h>
41
#include <stdarg.h>
42
 
43
#include "../main.h"
44
#include "usart.h"
45
#include "../lcd/lcd.h"
46
#include "../timer/timer.h"
47
#include "uart1.h"
48
#include "../eeprom/eeprom.h"
49
#include "../osd/osd.h"
50
 
51
 
52
uint8_t buffer[30];
53
 
54
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
55
volatile uint8_t txd_complete = TRUE;
56
 
57
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
58
volatile uint8_t rxd_buffer_locked = FALSE;
59
volatile uint8_t ReceivedBytes = 0;
60
volatile uint8_t *pRxData = 0;
61
volatile uint8_t RxDataLen = 0;
62
 
63
volatile uint16_t stat_crc_error = 0;
64
volatile uint16_t stat_overflow_error = 0;
65
 
66
volatile uint8_t rx_byte;
67
volatile uint8_t rxFlag = 0;
68
 
69
 
70
#define UART_RXBUFSIZE 64
71
#define UART_NO_DATA          0x0100              /* no receive data available   */
72
 
73
volatile static uint8_t rxbuf[UART_RXBUFSIZE];
74
volatile static uint8_t *volatile rxhead, *volatile rxtail;
75
 
76
 
77
/*
78
 
79
//-----------------------------------------------------------------------------
80
// USART1 transmitter ISR
81
ISR (USART1_TX_vect)
82
{
83
        static uint16_t ptr_txd1_buffer = 0;
84
        uint8_t tmp_tx1;
85
 
86
        if(!txd1_complete) // transmission not completed
87
        {
88
                ptr_txd1_buffer++;                    // [0] was already sent
89
                tmp_tx1 = txd1_buffer[ptr_txd1_buffer];
90
                // if terminating character or end of txd buffer was reached
91
                if((tmp_tx1 == '\r') || (ptr_txd1_buffer == TXD_BUFFER_LEN))
92
                {
93
                        ptr_txd1_buffer = 0;            // reset txd pointer
94
                        txd1_complete = TRUE;   // stop transmission
95
                }
96
                UDR1 = tmp_tx1; // send current byte will trigger this ISR again
97
        }
98
        // transmission completed
99
        else ptr_txd1_buffer = 0;
100
}
101
 
102
*/
103
 
104
 
105
#ifdef USART_INT
106
//-----------------------------------------------------------------------------
107
// USART0 transmitter ISR
108
ISR (USART_TX_vect)
109
{
110
        static uint16_t ptr_txd_buffer = 0;
111
        uint8_t tmp_tx;
112
 
113
        if(!txd_complete) // transmission not completed
114
        {
115
                ptr_txd_buffer++;                    // [0] was already sent
116
                tmp_tx = txd_buffer[ptr_txd_buffer];
117
                // if terminating character or end of txd buffer was reached
118
                if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
119
                {
120
                        ptr_txd_buffer = 0;             // reset txd pointer
121
                        txd_complete = TRUE;    // stop transmission
122
                }
123
                UDR = tmp_tx; // send current byte will trigger this ISR again
124
        }
125
        // transmission completed
126
        else ptr_txd_buffer = 0;
127
}
128
#endif
129
 
130
 
131
void SetBaudUart0(uint8_t Baudrate)
132
{
133
  switch (Baudrate)
134
  {
135
  case Baud_2400: USART_Init( UART_BAUD_SELECT(2400,F_CPU) );  break;
136
  case Baud_4800: USART_Init( UART_BAUD_SELECT(4800,F_CPU) );  break;
137
  case Baud_9600: USART_Init( UART_BAUD_SELECT(9600,F_CPU) );  break;
138
  case Baud_19200: USART_Init( UART_BAUD_SELECT(19200,F_CPU) );  break;
139
  case Baud_38400: USART_Init( UART_BAUD_SELECT(38400,F_CPU) );  break;
140
  case Baud_57600: USART_Init( UART_BAUD_SELECT(57600,F_CPU) );  break;
141
//  case Baud_115200: USART_Init( UART_BAUD_SELECT(115200,F_CPU) );  break;
142
  // Macro erechnet falschen Wert (9,85 = 9) für 115200 Baud mit 20Mhz Quarz, zu grosse Abweichung
143
 
144
//#warning "Baurate prüfen wenn kein 20 Mhz Quarz verwendet wird"
145
 
146
  case Baud_115200: USART_Init( 10 );  break;
147
  }
148
}
149
 
150
 
151
//-----------------------------------------------------------------------------
152
//
153
 
154
//
155
//uint8_t uart_getc_nb(uint8_t *c)
156
//{
157
//      if (rxhead==rxtail) return 0;
158
//      *c = *rxtail;
159
//      if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
160
//      return 1;
161
//}
162
 
163
 
164
 
165
 
166
ISR (USART0_RX_vect)
167
{
168
        static uint16_t crc;
169
        static uint8_t ptr_rxd_buffer = 0;
170
        uint8_t crc1, crc2;
171
        uint8_t c;
172
//      IdleTimer = 0;
173
        if (current_hardware == Wi232)
174
        {
175
//              rx_byte = c;
176
//              rxFlag = 1;
177
                int diff;
178
                uint8_t c;
179
                c=UDR;
180
                diff = rxhead - rxtail;
181
                if (diff < 0) diff += UART_RXBUFSIZE;
182
                if (diff < UART_RXBUFSIZE -1)
183
                {
184
                        *rxhead = c;
185
                        ++rxhead;
186
                        if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
187
                };
188
//              USART_putc (c);
189
                return;
190
        }
191
 
192
 
193
        if (current_hardware == MKGPS)
194
        {
195
//              rx_byte = c;
196
//              rxFlag = 1;
197
                int diff;
198
                uint8_t c;
199
                c=UDR;
200
                diff = rxhead - rxtail;
201
                if (diff < 0) diff += UART_RXBUFSIZE;
202
                if (diff < UART_RXBUFSIZE -1)
203
                {
204
                        *rxhead = c;
205
                        ++rxhead;
206
                        if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
207
                };
208
 
209
                return;
210
        }
211
 
212
        c = UDR;  // catch the received byte
213
        if (OSD_active && Config.OSD_SendOSD)          // Daten an SV2 senden
214
          uart1_putc(c);
215
 
216
 
217
        if (rxd_buffer_locked)
218
                return; // if rxd buffer is locked immediately return
219
 
220
        // the rxd buffer is unlocked
221
        if ((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
222
        {
223
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
224
                crc = c; // init crc
225
        }
226
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
227
        {
228
                if(c != '\r') // no termination character
229
                {
230
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
231
                        crc += c; // update crc
232
                }
233
                else // termination character was received
234
                {
235
                        // the last 2 bytes are no subject for checksum calculation
236
                        // they are the checksum itself
237
                        crc -= rxd_buffer[ptr_rxd_buffer-2];
238
                        crc -= rxd_buffer[ptr_rxd_buffer-1];
239
                        // calculate checksum from transmitted data
240
                        crc %= 4096;
241
                        crc1 = '=' + crc / 64;
242
                        crc2 = '=' + crc % 64;
243
                        // compare checksum to transmitted checksum bytes
244
                        if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
245
                        {   // checksum valid
246
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
247
                                ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
248
                                if (mode == rxd_buffer[2])
249
                                {
250
                                        rxd_buffer_locked = TRUE;          // lock the rxd buffer
251
                                        // if 2nd byte is an 'R' enable watchdog that will result in an reset
252
                                        if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
253
                                }
254
                        }
255
                        else
256
                        {       // checksum invalid
257
                                stat_crc_error++;
258
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
259
                        }
260
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
261
                }
262
        }
263
        else // rxd buffer overrun
264
        {
265
                stat_overflow_error++;
266
                ptr_rxd_buffer = 0; // reset rxd buffer
267
                rxd_buffer_locked = FALSE; // unlock rxd buffer
268
        }
269
}
270
 
271
 
272
//-----------------------------------------------------------------------------
273
// Function: uart0_getc()
274
// Purpose:  return byte from ringbuffer
275
// Returns:  lower byte:  received byte from ringbuffer
276
//           higher byte: last receive error
277
//-----------------------------------------------------------------------------
278
char USART_getc(void)
279
{
280
        char val;
281
 
282
//      while(rxhead==rxtail) ;
283
        if (rxhead==rxtail)
284
                return val=0;
285
//      IdleTimer = 0;
286
        val = *rxtail;
287
        if (++rxtail == (rxbuf + UART_RXBUFSIZE))
288
                rxtail = rxbuf;
289
 
290
        return val;
291
}
292
 
293
 
294
uint8_t uart_getc_nb(uint8_t *c)
295
{
296
        if (rxhead==rxtail)
297
                return 0;
298
//      IdleTimer = 0;
299
        *c = *rxtail;
300
        if (++rxtail == (rxbuf + UART_RXBUFSIZE))
301
                rxtail = rxbuf;
302
        return 1;
303
}
304
//-----------------------------------------------------------------------------
305
//
306
 
307
 
308
 
309
 
310
 
311
//-----------------------------------------------------------------------------
312
//
313
void USART_Init (unsigned int baudrate)
314
{
315
        // set clock divider
316
//      #undef BAUD
317
//      #define BAUD baudrate
318
//      #include <util/setbaud.h>
319
//      UBRRH = UBRRH_VALUE;
320
//      UBRRL = UBRRL_VALUE;
321
 
322
//#ifndef F_CPU
323
///* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
324
//   F_CPU im Makefile definiert werden, eine nochmalige Definition
325
//   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
326
//   #ifndef/#endif
327
//
328
//   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
329
//   verwendet wird und dort eine andere, nicht zur Hardware passende
330
//   Taktrate eingestellt ist: Dann wird die folgende Definition
331
//   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
332
//   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
333
//   noch nicht definiert: */
334
//#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
335
//#define F_CPU 18432000UL  // Systemtakt in Hz - Definition als unsigned long beachten
336
                         // Ohne ergeben sich unten Fehler in der Berechnung
337
//#endif
338
//#define BAUD 115200UL      // Baudrate
339
//
340
//// Berechnungen
341
//#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
342
//#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
343
//#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
344
//
345
//
346
//#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
347
//  #error "Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!"
348
//#endif
349
 
350
 
351
        UBRRH = (unsigned char)(baudrate>>8);
352
        UBRRL = (unsigned char) baudrate;
353
//        UBRRH = (unsigned char)(BAUD_REAL>>8);
354
//        UBRRL = (unsigned char) BAUD_REAL;
355
 
356
#if USE_2X
357
        UCSRA |= (1 << U2X);    // enable double speed operation
358
#else
359
        UCSRA &= ~(1 << U2X);   // disable double speed operation
360
#endif
361
 
362
        // set 8N1
363
#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
364
        UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
365
#else
366
        UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
367
#endif
368
        UCSRB &= ~(1 << UCSZ2);
369
 
370
        // flush receive buffer
371
        while ( UCSRA & (1 << RXC) ) UDR;
372
 
373
        UCSRB |= (1 << RXEN) | (1 << TXEN);
374
#ifdef USART_INT
375
        UCSRB |= (1 << RXCIE) | (1 << TXCIE);
376
#else
377
        UCSRB |= (1 << RXCIE);
378
#endif
379
 
380
        rxhead = rxtail = rxbuf;
381
 
382
}
383
 
384
 
385
 
386
 
387
 
388
//-----------------------------------------------------------------------------
389
// disable the txd pin of usart
390
void USART_DisableTXD (void)
391
{
392
#ifdef USART_INT
393
        UCSRB &= ~(1 << TXCIE);         // disable TX-Interrupt
394
#endif
395
        UCSRB &= ~(1 << TXEN);          // disable TX in USART
396
        DDRB  &= ~(1 << DDB3);          // set TXD pin as input
397
        PORTB &= ~(1 << PORTB3);        // disable pullup on TXD pin
398
}
399
 
400
//-----------------------------------------------------------------------------
401
// enable the txd pin of usart
402
void USART_EnableTXD (void)
403
{
404
        DDRB  |=  (1 << DDB3);          // set TXD pin as output
405
        PORTB &= ~(1 << PORTB3);        // disable pullup on TXD pin
406
        UCSRB |=  (1 << TXEN);          // enable TX in USART
407
#ifdef USART_INT
408
        UCSRB |=  (1 << TXCIE);         // enable TX-Interrupt
409
#endif
410
}
411
 
412
//-----------------------------------------------------------------------------
413
// short script to directly send a request thorugh usart including en- and disabling it
414
// where <address> is the address of the receipient, <label> is which data set to request
415
// and <ms> represents the milliseconds delay between data
416
void USART_request_mk_data (uint8_t cmd, uint8_t addr, uint8_t ms)
417
{
418
        USART_EnableTXD ();     // re-enable TXD pin
419
 
420
        unsigned char mstenth = ms/10;
421
        SendOutData(cmd, addr, 1, &mstenth, 1);
422
        // wait until command transmitted
423
        while (txd_complete == FALSE);
424
 
425
        USART_DisableTXD ();    // disable TXD pin again
426
}
427
 
428
//-----------------------------------------------------------------------------
429
//
430
void USART_putc (char c)
431
{
432
#ifdef USART_INT
433
#else
434
        loop_until_bit_is_set(UCSRA, UDRE);
435
        UDR = c;
436
#endif
437
}
438
 
439
 
440
 
441
//-----------------------------------------------------------------------------
442
//
443
void USART_puts (char *s)
444
{
445
#ifdef USART_INT
446
#else
447
        while (*s)
448
        {
449
                USART_putc (*s);
450
                s++;
451
        }
452
#endif
453
}
454
 
455
//-----------------------------------------------------------------------------
456
//
457
void USART_puts_p (const char *s)
458
{
459
#ifdef USART_INT
460
#else
461
        while (pgm_read_byte(s))
462
        {
463
                USART_putc (pgm_read_byte(s));
464
                s++;
465
        }
466
#endif
467
}
468
 
469
//-----------------------------------------------------------------------------
470
//
471
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) // uint8_t *pdata, uint8_t len, ...
472
{
473
        va_list ap;
474
        uint16_t pt = 0;
475
        uint8_t a,b,c;
476
        uint8_t ptr = 0;
477
        uint16_t tmpCRC = 0;
478
 
479
        uint8_t *pdata = 0;
480
        int len = 0;
481
 
482
        txd_buffer[pt++] = '#';                                 // Start character
483
        txd_buffer[pt++] = 'a' + addr;  // Address (a=0; b=1,...)
484
        txd_buffer[pt++] = cmd;                                 // Command
485
 
486
        va_start(ap, numofbuffers);
487
        if(numofbuffers)
488
        {
489
                pdata = va_arg (ap, uint8_t*);
490
                len = va_arg (ap, int);
491
                ptr = 0;
492
                numofbuffers--;
493
        }
494
 
495
        while(len)
496
        {
497
                if(len)
498
                {
499
                        a = pdata[ptr++];
500
                        len--;
501
                        if((!len) && numofbuffers)
502
                        {
503
                                pdata = va_arg(ap, uint8_t*);
504
                                len = va_arg(ap, int);
505
                                ptr = 0;
506
                                numofbuffers--;
507
                        }
508
                }
509
                else
510
                        a = 0;
511
 
512
                if(len)
513
                {
514
                        b = pdata[ptr++];
515
                        len--;
516
                        if((!len) && numofbuffers)
517
                        {
518
                                pdata = va_arg(ap, uint8_t*);
519
                                len = va_arg(ap, int);
520
                                ptr = 0;
521
                                numofbuffers--;
522
                        }
523
                }
524
                else
525
                        b = 0;
526
 
527
                if(len)
528
                {
529
                        c = pdata[ptr++];
530
                        len--;
531
                        if((!len) && numofbuffers)
532
                        {
533
                                pdata = va_arg(ap, uint8_t*);
534
                                len = va_arg(ap, int);
535
                                ptr = 0;
536
                                numofbuffers--;
537
                        }
538
                }
539
                else
540
                        c = 0;
541
 
542
                txd_buffer[pt++] = '=' + (a >> 2);
543
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
544
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
545
                txd_buffer[pt++] = '=' + ( c & 0x3f);
546
        }
547
        va_end(ap);
548
 
549
        for(a = 0; a < pt; a++)
550
        {
551
                tmpCRC += txd_buffer[a];
552
        }
553
        tmpCRC %= 4096;
554
        txd_buffer[pt++] = '=' + tmpCRC / 64;
555
        txd_buffer[pt++] = '=' + tmpCRC % 64;
556
        txd_buffer[pt++] = '\r';
557
 
558
        txd_complete = FALSE;
559
#ifdef USART_INT
560
        UDR = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
561
#else
562
        for(a = 0; a < pt; a++)
563
        {
564
                loop_until_bit_is_set(UCSRA, UDRE);
565
                UDR = txd_buffer[a];
566
        }
567
        txd_complete = TRUE;
568
#endif
569
}
570
 
571
//-----------------------------------------------------------------------------
572
//
573
void Decode64 (void)
574
{
575
        uint8_t a,b,c,d;
576
        uint8_t ptrIn = 3;
577
        uint8_t ptrOut = 3;
578
        uint8_t len = ReceivedBytes - 6;
579
 
580
        while (len)
581
        {
582
                a = rxd_buffer[ptrIn++] - '=';
583
                b = rxd_buffer[ptrIn++] - '=';
584
                c = rxd_buffer[ptrIn++] - '=';
585
                d = rxd_buffer[ptrIn++] - '=';
586
                //if(ptrIn > ReceivedBytes - 3) break;
587
 
588
                if (len--)
589
                        rxd_buffer[ptrOut++] = (a << 2) | (b >> 4);
590
                else
591
                        break;
592
 
593
                if (len--)
594
                        rxd_buffer[ptrOut++] = ((b & 0x0f) << 4) | (c >> 2);
595
                else
596
                        break;
597
 
598
                if (len--)
599
                        rxd_buffer[ptrOut++] = ((c & 0x03) << 6) | d;
600
                else
601
                        break;
602
        }
603
        pRxData = &rxd_buffer[3];
604
        RxDataLen = ptrOut - 3;
605
}
606
 
607
 
608
//-----------------------------------------------------------------------------
609
//
610
void SwitchToNC (void)
611
{
612
 
613
        if(hardware == NC)
614
        {
615
                // switch to NC
616
                USART_putc (0x1b);
617
                USART_putc (0x1b);
618
                USART_putc (0x55);
619
                USART_putc (0xaa);
620
                USART_putc (0x00);
621
                current_hardware = NC;
622
                _delay_ms (50);
623
        }
624
}
625
 
626
//-----------------------------------------------------------------------------
627
//
628
 
629
 
630
//-----------------------------------------------------------------------------
631
//
632
void SwitchToWi232 (void)
633
{
634
 
635
//      if(hardware == NC)
636
        {
637
                // switch to Wi232
638
                current_hardware = Wi232;
639
                _delay_ms (50);
640
        }
641
}
642
 
643
//-----------------------------------------------------------------------------
644
//
645
void SwitchToFC (void)
646
{
647
        uint8_t cmd;
648
 
649
        if (current_hardware == NC)
650
        {
651
                // switch to FC
652
                cmd = 0x00;     // 0 = FC, 1 = MK3MAG, 2 = MKGPS
653
                SendOutData('u', ADDRESS_NC, 1, &cmd, 1);
654
                current_hardware = FC;
655
                _delay_ms (50);
656
        }
657
}
658
 
659
//-----------------------------------------------------------------------------
660
//
661
void SwitchToMAG (void)
662
{
663
        uint8_t cmd;
664
 
665
        if (current_hardware == NC)
666
        {
667
                // switch to MK3MAG
668
                cmd = 0x01;     // 0 = FC, 1 = MK3MAG, 2 = MKGPS
669
                SendOutData('u', ADDRESS_NC, 1, &cmd, 1);
670
                current_hardware = MK3MAG;
671
                _delay_ms (50);
672
        }
673
}
674
 
675
//-----------------------------------------------------------------------------
676
//
677
void SwitchToGPS (void)
678
{
679
        uint8_t cmd;
680
        if (current_hardware == NC)
681
        {
682
                // switch to MKGPS
683
                cmd = 0x02;     // 0 = FC, 1 = MK3MAG, 2 = MKGPS
684
                SendOutData('u', ADDRESS_NC, 1, &cmd, 1);
685
                current_hardware = MKGPS;
686
                _delay_ms (50);
687
        }
688
}