Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
231 killagreg 1
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
// + Copyright (c) 04.2007 Holger Buss
3
// + only for non-profit use
4
// + www.MikroKopter.com
5
// + see the File "License.txt" for further Informations
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
 
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <avr/wdt.h>
11
#include <stdarg.h>
12
#include <string.h>
13
 
14
#include "main.h"
15
#include "menu.h"
16
#include "timer0.h"
17
#include "uart0.h"
18
#include "ubx.h"
19
#include "led.h"
20
 
21
 
22
#define FC_ADDRESS 1
23
#define NC_ADDRESS 2
24
#define MK3MAG_ADDRESS 3
25
 
26
#define FM_ADDRESS 10 // FOLLOW ME
27
 
28
#define FALSE   0
29
#define TRUE    1
30
 
31
//int8_t test __attribute__ ((section (".noinit")));
32
uint8_t Request_VerInfo                 = FALSE;
33
uint8_t Request_Display                 = FALSE;
34
uint8_t Request_Display1                = FALSE;
35
uint8_t Request_ExternalControl = FALSE;
36
uint8_t Request_DebugData               = FALSE;
37
uint8_t Request_DebugLabel              = 255;
333 killagreg 38
uint8_t Request_SendFollowMe    = FALSE;
231 killagreg 39
uint8_t DisplayLine = 0;
40
 
41
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
42
volatile uint8_t rxd_buffer_locked = FALSE;
43
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
44
volatile uint8_t txd_complete = TRUE;
45
volatile uint8_t ReceivedBytes = 0;
46
volatile uint8_t *pRxData = 0;
47
volatile uint8_t RxDataLen = 0;
48
 
49
uint8_t PcAccess = 100;
50
 
51
ExternControl_t ExternControl;
52
DebugOut_t              DebugOut;
53
UART_VersionInfo_t      UART_VersionInfo;
54
 
55
uint16_t DebugData_Timer;
56
uint16_t DebugData_Interval = 500; // in 1ms
57
 
333 killagreg 58
Waypoint_t FollowMe;
231 killagreg 59
 
60
const uint8_t ANALOG_LABEL[32][16] =
61
{
62
   //1234567890123456
356 joko 63
    "Analog_Ch0      ", //0
64
    "Analog_Ch1      ",
65
    "Analog_Ch2      ",
66
    "Analog_Ch3      ",
67
    "Analog_Ch4      ",
68
    "Analog_Ch5      ", //5
69
    "Analog_Ch6      ",
70
    "Analog_Ch7      ",
273 killagreg 71
    "UBat            ",
303 joko 72
    "Speed_North     ",
73
    "Speed_East      ", //10
74
    "Speed_Top       ",
75
    "NumOfSats       ",
76
    "Pos.Longitude   ",
77
    "Pos.Latitude    ",
78
    "Pos.Altitude    ", //15
79
        "Zellenzahl      ",
80
    "PowerOn         ",
231 killagreg 81
    "Debug18         ",
82
    "Debug19         ",
83
    "Debug20         ", //20
84
    "Debug21         ",
85
    "Debug22         ",
86
    "Debug23         ",
87
    "Debug24         ",
88
    "Debug25         ", //25
89
    "Debug26         ",
90
    "Debug27         ",
91
    "Debug28         ",
92
    "Debug29         ",
93
    "Debug30         ", //30
94
    "Debug31         "
95
};
96
 
97
 
98
 
99
/****************************************************************/
100
/*              Initialization of the USART0                    */
101
/****************************************************************/
102
void USART0_Init (void)
103
{
104
        uint8_t sreg = SREG;
105
        uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART0_BAUD) - 1);
106
 
107
        // disable all interrupts before configuration
108
        cli();
109
 
110
        // disable RX-Interrupt
111
        UCSR0B &= ~(1 << RXCIE0);
112
        // disable TX-Interrupt
113
        UCSR0B &= ~(1 << TXCIE0);
114
 
115
        // set direction of RXD0 and TXD0 pins
116
        // set RXD0 (PD0) as an input pin
117
        PORTD |= (1 << PORTD0);
118
        DDRD &= ~(1 << DDD0);
119
        // set TXD0 (PD1) as an output pin
120
        PORTD |= (1 << PORTD1);
121
        DDRD |=  (1 << DDD1);
122
 
123
        // USART0 Baud Rate Register
124
        // set clock divider
125
        UBRR0H = (uint8_t)(ubrr >> 8);
126
        UBRR0L = (uint8_t)ubrr;
127
 
128
        // USART0 Control and Status Register A, B, C
129
 
130
        // enable double speed operation in
131
        UCSR0A |= (1 << U2X0);
132
        // enable receiver and transmitter in
133
        UCSR0B = (1 << TXEN0) | (1 << RXEN0);
134
        // set asynchronous mode
135
        UCSR0C &= ~(1 << UMSEL01);
136
        UCSR0C &= ~(1 << UMSEL00);
137
        // no parity
138
        UCSR0C &= ~(1 << UPM01);
139
        UCSR0C &= ~(1 << UPM00);
140
        // 1 stop bit
141
        UCSR0C &= ~(1 << USBS0);
142
        // 8-bit
143
        UCSR0B &= ~(1 << UCSZ02);
144
        UCSR0C |=  (1 << UCSZ01);
145
        UCSR0C |=  (1 << UCSZ00);
146
 
147
                // flush receive buffer
148
        while ( UCSR0A & (1<<RXC0) ) UDR0;
149
 
150
        // enable interrupts at the end
151
        // enable RX-Interrupt
152
        UCSR0B |= (1 << RXCIE0);
153
        // enable TX-Interrupt
154
        UCSR0B |= (1 << TXCIE0);
155
 
156
        // initialize the debug timer
157
        DebugData_Timer = SetDelay(DebugData_Interval);
158
 
159
        // unlock rxd_buffer
160
        rxd_buffer_locked = FALSE;
161
        pRxData = 0;
162
        RxDataLen = 0;
163
 
164
        // no bytes to send
165
        txd_complete = TRUE;
166
 
167
        UART_VersionInfo.SWMajor = VERSION_MAJOR;
168
        UART_VersionInfo.SWMinor = VERSION_MINOR;
169
        UART_VersionInfo.SWPatch = VERSION_PATCH;
170
        UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
171
        UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR;
172
 
173
        // restore global interrupt flags
174
    SREG = sreg;
175
}
176
 
177
/****************************************************************/
178
/*               USART0 transmitter ISR                         */
179
/****************************************************************/
180
ISR(USART0_TX_vect)
181
{
182
        static uint16_t ptr_txd_buffer = 0;
183
        uint8_t tmp_tx;
184
        if(!txd_complete) // transmission not completed
185
        {
186
                ptr_txd_buffer++;                    // die [0] wurde schon gesendet
187
                tmp_tx = txd_buffer[ptr_txd_buffer];
188
                // if terminating character or end of txd buffer was reached
189
                if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
190
                {
191
                        ptr_txd_buffer = 0; // reset txd pointer
192
                        txd_complete = 1; // stop transmission
193
                }
194
                UDR0 = tmp_tx; // send current byte will trigger this ISR again
195
        }
196
        // transmission completed
197
        else ptr_txd_buffer = 0;
198
}
199
 
200
/****************************************************************/
201
/*               USART0 receiver ISR                            */
202
/****************************************************************/
203
ISR(USART0_RX_vect)
204
{
205
        static uint16_t crc;
206
        static uint8_t ptr_rxd_buffer = 0;
207
        uint8_t crc1, crc2;
208
        uint8_t c;
209
 
210
        c = UDR0;  // catch the received byte
211
 
212
        if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
213
 
214
        // the rxd buffer is unlocked
215
        if((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
216
        {
217
                rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
218
                crc = c; // init crc
219
        }
220
        #if 0
221
        else if (ptr_rxd_buffer == 1) // handle address
222
        {
223
                rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
224
                crc += c; // update crc
225
        }
226
        #endif
227
        else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
228
        {
229
                if(c != '\r') // no termination character
230
                {
231
                        rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
232
                        crc += c; // update crc
233
                }
234
                else // termination character was received
235
                {
236
                        // the last 2 bytes are no subject for checksum calculation
237
                        // they are the checksum itself
238
                        crc -= rxd_buffer[ptr_rxd_buffer-2];
239
                        crc -= rxd_buffer[ptr_rxd_buffer-1];
240
                        // calculate checksum from transmitted data
241
                        crc %= 4096;
242
                        crc1 = '=' + crc / 64;
243
                        crc2 = '=' + crc % 64;
244
                        // compare checksum to transmitted checksum bytes
245
                        if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
246
                        {   // checksum valid
247
                                rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
248
                                ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
249
                                rxd_buffer_locked = TRUE;          // lock the rxd buffer
250
                                // if 2nd byte is an 'R' enable watchdog that will result in an reset
251
                                if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
252
                        }
253
                        else
254
                        {       // checksum invalid
255
                                rxd_buffer_locked = FALSE; // unlock rxd buffer
256
                        }
257
                        ptr_rxd_buffer = 0; // reset rxd buffer pointer
258
                }
259
        }
260
        else // rxd buffer overrun
261
        {
262
                ptr_rxd_buffer = 0; // reset rxd buffer
263
                rxd_buffer_locked = FALSE; // unlock rxd buffer
264
        }
265
 
266
}
267
 
268
 
269
// --------------------------------------------------------------------------
270
void AddCRC(uint16_t datalen)
271
{
272
        uint16_t tmpCRC = 0, i;
273
        for(i = 0; i < datalen; i++)
274
        {
275
                tmpCRC += txd_buffer[i];
276
        }
277
        tmpCRC %= 4096;
278
        txd_buffer[i++] = '=' + tmpCRC / 64;
279
        txd_buffer[i++] = '=' + tmpCRC % 64;
280
        txd_buffer[i++] = '\r';
281
        txd_complete = FALSE;
282
        UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
283
}
284
 
285
 
286
 
287
// --------------------------------------------------------------------------
288
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) // uint8_t *pdata, uint8_t len, ...
289
{
290
        va_list ap;
291
        uint16_t pt = 0;
292
        uint8_t a,b,c;
293
        uint8_t ptr = 0;
294
 
295
        uint8_t *pdata = 0;
296
        int len = 0;
297
 
298
        txd_buffer[pt++] = '#';                 // Start character
299
        txd_buffer[pt++] = 'a' + addr;  // Address (a=0; b=1,...)
300
        txd_buffer[pt++] = cmd;                 // Command
301
 
302
        va_start(ap, numofbuffers);
303
        if(numofbuffers)
304
        {
305
                pdata = va_arg(ap, uint8_t*);
306
                len = va_arg(ap, int);
307
                ptr = 0;
308
                numofbuffers--;
309
        }
310
 
311
        while(len)
312
        {
313
                if(len)
314
                {
315
                        a = pdata[ptr++];
316
                        len--;
317
                        if((!len) && numofbuffers)
318
                        {
319
                                pdata = va_arg(ap, uint8_t*);
320
                                len = va_arg(ap, int);
321
                                ptr = 0;
322
                                numofbuffers--;
323
                        }
324
                }
325
                else a = 0;
326
                if(len)
327
                {
328
                        b = pdata[ptr++];
329
                        len--;
330
                        if((!len) && numofbuffers)
331
                        {
332
                                pdata = va_arg(ap, uint8_t*);
333
                                len = va_arg(ap, int);
334
                                ptr = 0;
335
                                numofbuffers--;
336
                        }
337
                }
338
                else b = 0;
339
                if(len)
340
                {
341
                        c = pdata[ptr++];
342
                        len--;
343
                        if((!len) && numofbuffers)
344
                        {
345
                                pdata = va_arg(ap, uint8_t*);
346
                                len = va_arg(ap, int);
347
                                ptr = 0;
348
                                numofbuffers--;
349
                        }
350
                }
351
                else c = 0;
352
                txd_buffer[pt++] = '=' + (a >> 2);
353
                txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
354
                txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
355
                txd_buffer[pt++] = '=' + ( c & 0x3f);
356
        }
357
        va_end(ap);
358
        AddCRC(pt); // add checksum after data block and initates the transmission
359
}
360
 
361
 
362
// --------------------------------------------------------------------------
363
void Decode64(void)
364
{
365
        uint8_t a,b,c,d;
366
        uint8_t x,y,z;
367
        uint8_t ptrIn = 3;
368
        uint8_t ptrOut = 3;
369
        uint8_t len = ReceivedBytes - 6;
370
 
371
        while(len)
372
        {
373
                a = rxd_buffer[ptrIn++] - '=';
374
                b = rxd_buffer[ptrIn++] - '=';
375
                c = rxd_buffer[ptrIn++] - '=';
376
                d = rxd_buffer[ptrIn++] - '=';
377
                //if(ptrIn > ReceivedBytes - 3) break;
378
 
379
                x = (a << 2) | (b >> 4);
380
                y = ((b & 0x0f) << 4) | (c >> 2);
381
                z = ((c & 0x03) << 6) | d;
382
 
383
                if(len--) rxd_buffer[ptrOut++] = x; else break;
384
                if(len--) rxd_buffer[ptrOut++] = y; else break;
385
                if(len--) rxd_buffer[ptrOut++] = z; else break;
386
        }
387
        pRxData = &rxd_buffer[3];
388
        RxDataLen = ptrOut - 3;
389
}
390
 
391
 
392
// --------------------------------------------------------------------------
393
void USART0_ProcessRxData(void)
394
{
395
        // if data in the rxd buffer are not locked immediately return
396
        if(!rxd_buffer_locked) return;
397
 
398
        Decode64(); // decode data block in rxd_buffer
399
 
400
 
401
        switch(rxd_buffer[1] - 'a')
402
        {
403
                case FM_ADDRESS:
404
 
405
                        switch(rxd_buffer[2])
406
                        {
407
                                default:
408
                                        //unsupported command received
409
                                        break;
410
                        } // case FC_ADDRESS:
411
 
412
                default: // any Slave Address
413
 
414
                switch(rxd_buffer[2])
415
                        {
416
                                case 'a':// request for labels of the analog debug outputs
417
                                        Request_DebugLabel = pRxData[0];
418
                                        if(Request_DebugLabel > 31) Request_DebugLabel = 31;
419
                                        PcAccess = 255;
420
                                        break;
421
 
422
                                case 'h':// request for display columns
423
                                        PcAccess = 255;
424
                                        RemoteKeys |= pRxData[0];
425
                                        if(RemoteKeys) DisplayLine = 0;
426
                                        Request_Display = TRUE;
427
                                        break;
428
 
429
                                case 'l':// request for display columns
430
                                        PcAccess = 255;
431
                                        MenuItem = pRxData[0];
432
                                        Request_Display1 = TRUE;
433
                                        break;
434
 
435
                                case 'v': // request for version and board release
436
                                        Request_VerInfo = TRUE;
437
                                        break;
438
 
439
                                case 'd': // request for the debug data
440
                                        DebugData_Interval = (uint16_t) pRxData[0] * 10;
441
                                        if(DebugData_Interval > 0) Request_DebugData = TRUE;
442
                                        break;
443
 
444
                                case 'g':// get external control data
445
                                        Request_ExternalControl = TRUE;
446
                                        break;
447
 
448
                                default:
449
                                        //unsupported command received
450
                                        break;
451
                }
452
                break; // default:
453
        }
454
        // unlock the rxd buffer after processing
455
        pRxData = 0;
456
        RxDataLen = 0;
457
        rxd_buffer_locked = FALSE;
458
}
459
 
460
//############################################################################
461
//Routine für die Serielle Ausgabe
462
int16_t uart_putchar (int8_t c)
463
//############################################################################
464
{
465
        if (c == '\n')
466
                uart_putchar('\r');
467
        // wait until previous character was send
468
        loop_until_bit_is_set(UCSR0A, UDRE0);
469
        // send character
470
        UDR0 = c;
471
        return (0);
472
}
473
 
474
 
475
//---------------------------------------------------------------------------------------------
476
void USART0_TransmitTxData(void)
477
{
478
        if(!txd_complete) return;
479
 
480
        if(Request_VerInfo && txd_complete)
481
        {
482
                SendOutData('V', FM_ADDRESS, 1, (uint8_t *) &UART_VersionInfo, sizeof(UART_VersionInfo));
483
                Request_VerInfo = FALSE;
484
        }
485
        if(Request_Display && txd_complete)
486
        {
487
                LCD_PrintMenu();
488
                SendOutData('H', FM_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), &DisplayBuff[DisplayLine * 20], 20);
489
                DisplayLine++;
490
                if(DisplayLine >= 4) DisplayLine = 0;
491
                Request_Display = FALSE;
492
        }
493
        if(Request_Display1 && txd_complete)
494
        {
495
                LCD_PrintMenu();
496
                SendOutData('L', FM_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem, sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
497
                Request_Display1 = FALSE;
498
        }
499
        if(Request_DebugLabel != 0xFF) // Texte für die Analogdaten
500
        {
501
                SendOutData('A', FM_ADDRESS, 2, (uint8_t *) &Request_DebugLabel, sizeof(Request_DebugLabel), ANALOG_LABEL[Request_DebugLabel], 16);
502
                Request_DebugLabel = 0xFF;
503
        }
504
        if(Request_ExternalControl && txd_complete)
505
        {
506
                SendOutData('G', FM_ADDRESS, 1,(uint8_t *) &ExternControl, sizeof(ExternControl));
507
                Request_ExternalControl = FALSE;
508
        }
509
        if( ((DebugData_Interval && CheckDelay(DebugData_Timer)) || Request_DebugData) && txd_complete)
510
        {
511
                SendOutData('D', FM_ADDRESS, 1,(uint8_t *) &DebugOut, sizeof(DebugOut));
512
                DebugData_Timer = SetDelay(DebugData_Interval);
513
                Request_DebugData = FALSE;
514
    }
333 killagreg 515
        if(Request_SendFollowMe && txd_complete)
516
        {
517
                SendOutData('s', NC_ADDRESS, 1, (uint8_t *)&FollowMe, sizeof(FollowMe));
518
                FollowMe.Position.Status = PROCESSED;
519
                Request_SendFollowMe = FALSE;
520
        }
231 killagreg 521
}
522