Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2136 - 1
/*************************************************************************
2
Title:    Interrupt UART library with receive/transmit circular buffers
3
Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
4
File:     $Id: uart.c,v 1.6.2.2 2009/11/29 08:56:12 Peter Exp $
5
Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
6
Hardware: any AVR with built-in UART,
7
License:  GNU General Public License
8
 
9
DESCRIPTION:
10
    An interrupt is generated when the UART has finished transmitting or
11
    receiving a byte. The interrupt handling routines use circular buffers
12
    for buffering received and transmitted data.
13
 
14
    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
15
    the buffer size in bytes. Note that these variables must be a
16
    power of 2.
17
 
18
USAGE:
19
    Refere to the header file uart.h for a description of the routines.
20
    See also example test_uart.c.
21
 
22
NOTES:
23
    Based on Atmel Application Note AVR306
24
 
25
LICENSE:
26
    Copyright (C) 2006 Peter Fleury
27
 
28
    This program is free software; you can redistribute it and/or modify
29
    it under the terms of the GNU General Public License as published by
30
    the Free Software Foundation; either version 2 of the License, or
31
    any later version.
32
 
33
    This program is distributed in the hope that it will be useful,
34
    but WITHOUT ANY WARRANTY; without even the implied warranty of
35
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
    GNU General Public License for more details.
37
 
38
*************************************************************************/
39
 
40
//############################################################################
41
//# HISTORY  uart1.c
42
//#
43
//# 08.08.2015 CB
44
//# - chg: Umbau ISR(USART1_RX_vect) um Behandlung der NMEA Datensätze
45
//#
46
//# 06.08.2015 CB
47
//# - add: uint8_t receiveNMEA              // Flag zur Empfangssteuerung in ISR(USART1_RX_vect)
48
//# - add: Erweiterung ISR(USART1_RX_vect) um Behandlung der NMEA Datensätze
49
//#
50
//# 26.06.2014 OG
51
//# - del: receiveNMEA
52
//#
53
//# 04.07.2013 Cebra
54
//# - add: neue Funktion uart1_peek
55
//############################################################################
56
 
57
 
58
#include <avr/io.h>
59
#include <avr/interrupt.h>
60
#include <avr/pgmspace.h>
61
#include <string.h>
62
#include <stdbool.h>
63
#include "uart1.h"
64
#include "usart.h"
65
#include "../main.h"
66
#include "../bluetooth/bluetooth.h"
67
#include "../tracking/tracking.h"
68
#include "../avr-nmea-gps-library/nmea.h"
69
 
70
//
71
//  constants and macros
72
//
73
 
74
 
75
// size of RX/TX buffers
76
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
77
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
78
 
79
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
80
#error RX buffer size is not a power of 2
81
#endif
82
 
83
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
84
#error TX buffer size is not a power of 2
85
#endif
86
 
87
 
88
// ATmega with two USART
89
 
90
#define ATMEGA_USART1
91
 
92
#define UART1_STATUS   UCSR1A
93
#define UART1_CONTROL  UCSR1B
94
#define UART1_DATA     UDR1
95
#define UART1_UDRIE    UDRIE1
96
 
97
 
98
 
99
//
100
//  module global variables
101
//
102
 
103
#if defined( ATMEGA_USART1 )
104
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
105
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
106
static volatile unsigned char UART1_TxHead;
107
static volatile unsigned char UART1_TxTail;
108
static volatile unsigned char UART1_RxHead;
109
static volatile unsigned char UART1_RxTmpHead;
110
static volatile unsigned char UART1_RxTail;
111
static volatile unsigned char UART1_LastRxError;
112
 
113
static volatile unsigned char UART1_RxTmpHead;;
114
 
115
volatile uint16_t UART1_RxError;
116
 
117
#endif
118
 
119
volatile uint8_t UART1_receiveNMEA = false;
120
 
121
 
122
void SetBaudUart1(uint8_t Baudrate)
123
{
124
  switch (Baudrate)
125
  {
126
  case Baud_2400: uart1_init( UART_BAUD_SELECT(2400,F_CPU) );  break;
127
  case Baud_4800: uart1_init( UART_BAUD_SELECT(4800,F_CPU) );  break;
128
//  case Baud_9600: uart1_init( UART_BAUD_SELECT(9600,F_CPU) );  break;
129
  case Baud_9600: uart1_init( 129);  break;
130
  case Baud_19200: uart1_init( UART_BAUD_SELECT(19200,F_CPU) );  break;
131
  case Baud_38400: uart1_init( UART_BAUD_SELECT(38400,F_CPU) );  break;
132
  case Baud_57600: uart1_init( UART_BAUD_SELECT(57600,F_CPU) );  break;
133
//  case Baud_57600: uart1_init( 21);  break;
134
//  case Baud_115200: uart1_init( UART_BAUD_SELECT(115200,F_CPU) );  break;
135
  case Baud_115200: uart1_init( 10 );  break;
136
  }
137
}
138
 
139
//
140
// these functions are only for ATmegas with two USART
141
//
142
 
143
 
144
#if defined( ATMEGA_USART1 )
145
 
146
#if 0
147
//--------------------------------------------------------------
148
// Function: UART1 Receive Complete interrupt
149
// Purpose:  called when the UART1 has received a character
150
//--------------------------------------------------------------
151
ISR(USART1_RX_vect)
152
{
153
    unsigned char tmphead;
154
    unsigned char data;
155
    unsigned char usr;
156
    unsigned char lastRxError;
157
 
158
 
159
    // read UART status register and UART data register
160
    usr  = UART1_STATUS;
161
    data = UART1_DATA;
162
 
163
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
164
 
165
    // calculate buffer index
166
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
167
 
168
    if ( tmphead == UART1_RxTail )
169
    {
170
        // error: receive buffer overflow
171
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
172
        UART1_RxError++;
173
    }
174
    else
175
    {
176
        // store new index
177
        UART1_RxHead = tmphead;
178
        // store received data in buffer
179
        UART1_RxBuf[tmphead] = data;
180
    }
181
    UART1_LastRxError = lastRxError;
182
}
183
#else
184
 
185
#warning Test neue UART ISR für NMEA
186
 
187
//--------------------------------------------------------------
188
// Function: UART1 Receive Complete interrupt, decode NMEA GPGGA
189
// Purpose:  called when the UART1 has received a character
190
//--------------------------------------------------------------
191
ISR(USART1_RX_vect)
192
{
193
    unsigned char tmphead;
194
    unsigned char data;
195
    unsigned char usr;
196
    unsigned char lastRxError;
197
 
198
    usr  = UART1_STATUS;
199
    data = UART1_DATA;
200
 
201
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
202
 
203
    // calculate buffer index
204
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
205
 
206
    if ( tmphead == UART1_RxTail )
207
    {
208
        // error: receive buffer overflow
209
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
210
        UART1_RxError++;
211
    }
212
        else
213
          {
214
           if (UART1_receiveNMEA)
215
              {
216
               fusedata(data);                  // NMEA Daten bearbeiten
217
              }
218
 
219
          else  // if (UART1_receiveNMEA)
220
 
221
            {
222
                // store new index
223
                UART1_RxHead = tmphead;
224
                // store received data in buffer
225
                UART1_RxBuf[tmphead] = data;
226
            }
227
    }
228
    UART1_LastRxError = lastRxError;
229
}
230
 
231
////--------------------------------------------------------------
232
//// Function: UART1 Receive Complete interrupt, decode NMEA GPGGA
233
//// Purpose:  called when the UART1 has received a character
234
////--------------------------------------------------------------
235
//ISR(USART1_RX_vect)
236
//{
237
//    unsigned char tmphead;
238
//    unsigned char data;
239
//    unsigned char usr;
240
//    unsigned char lastRxError;
241
//
242
//    static volatile uint8_t GGA;
243
//    static char buffer[6];
244
//    static volatile uint8_t bufferindex;
245
//    static volatile uint8_t NMEAstart,NMEAend = false;
246
//
247
//    // read UART status register and UART data register
248
//    usr  = UART1_STATUS;
249
//    data = UART1_DATA;
250
//
251
//    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
252
//
253
//    // calculate buffer index
254
//
255
//    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
256
//
257
//    if ( tmphead == UART1_RxTail )
258
//    {
259
//        // error: receive buffer overflow
260
//        lastRxError = UART_BUFFER_OVERFLOW >> 8;
261
//        UART1_RxError++;
262
//    }
263
//    else
264
//      {
265
//        if (UART1_receiveNMEA)
266
//          {
267
//            cli();
268
//            switch(data)
269
//              {
270
//                case '$':                       //start of a packet
271
//
272
//                  if (!NMEAstart && GGA)         // falls mitten im  Datensatz eine neuer kommt, warum auch immer
273
//                    {
274
//                      // restore index, war kein GPGGA Datensatz
275
//                      UART1_RxHead = UART1_RxTmpHead;
276
//                      memset(buffer,0,6);
277
//                      bufferindex=0;                //wipe all these so they can be reused
278
//                    }
279
//                  NMEAstart = true;
280
//                  NMEAend = false;
281
//                  GGA=false;
282
//                  bufferindex=0;                //wipe all these so they can be reused
283
//
284
//                  UART1_RxTmpHead = tmphead-1;       // erstmal sichern, Start des NMEA Datensatzes
285
//                  // store new index, erstam in den Buffer schreiben
286
//                  UART1_RxHead = tmphead;
287
//                  // store received data in buffer
288
//                  UART1_RxBuf[tmphead] = data;
289
////                  USART_putc(data);
290
//                  sei();
291
//                  break;
292
//
293
//                default:                        //we have some of the CSV data
294
//                  if(bufferindex<6)             //dont mess up ! Dont overflow
295
//                  {
296
//                        buffer[bufferindex]=data;  //stick the character in our buffer
297
//                  }
298
//
299
//                  if(GGA)
300
//                    {
301
//                      // store new index, erstam in den Buffer schreiben
302
//                      UART1_RxHead = tmphead;
303
//                      // store received data in buffer
304
//                      UART1_RxBuf[tmphead] = data;
305
////                      USART_putc(data);
306
//
307
//
308
//                      switch ( data)
309
//                        {
310
//                         case '\r' :
311
//                             GGA = false;
312
//                             bufferindex=0;                //wipe all these so they can be reused
313
//                             NMEAstart = false;
314
//                             NMEAend = true;
315
//                             UART1_GPGGA++;
316
//                             memset(buffer,0,6);
317
//                             break;          // Ende mit NMEA Datensatz
318
//
319
//                         case '\n' :
320
//                             GGA = false;
321
//                             bufferindex=0;                //wipe all these so they can be reused
322
//                             NMEAstart = false;
323
//                             NMEAend = true;
324
//                             UART1_GPGGA++;
325
//                             memset(buffer,0,6);
326
//                             break;          // Ende mit NMEA Datensatz
327
//                        }
328
//
329
//                    }
330
//
331
//                  else if(NMEAstart)                  //the header, erstes Komma noch nicht gekommen
332
//
333
//                    {
334
//                      if(bufferindex<4)
335
//
336
//                        {
337
//                         bufferindex++;          //increase the position in the buffer
338
//
339
//                         // store new index, erstmal in den Buffer schreiben
340
//                         UART1_RxHead = tmphead;
341
//                         // store received data in buffer
342
//                         UART1_RxBuf[tmphead] = data;
343
////                         USART_putc(data);
344
//
345
//
346
//                        }
347
//                      else
348
//
349
//                        {
350
////                          cli();
351
//                          if(!strcmp(buffer,"GPGGA"))    //the last character will be a 0(end of string)
352
//
353
//                            {
354
//                             GGA=true;
355
//                             NMEAstart = false;
356
//                             // store new index, erstmal in den Buffer schreiben
357
//                             UART1_RxHead = tmphead;
358
//                             // store received data in buffer
359
//                             UART1_RxBuf[tmphead] = data;
360
////                             USART_putc(data);
361
////                             sei();
362
//                            }
363
//
364
//                          else
365
//
366
//                            {
367
//                             // restore index, war kein GPGGA Datensatz
368
//
369
//                             UART1_RxHead = UART1_RxTmpHead;
370
////                             commacount=0;
371
//                             memset(buffer,0,6);
372
//                             bufferindex=0;                //wipe all these so they can be reused
373
//                             NMEAstart = false;
374
////                             sei();
375
//                            }
376
//                        }
377
//                    }
378
//                      else if (!NMEAend && !GGA) UART1_RxHead = UART1_RxTmpHead; // Zeichen verwerfen
379
//
380
//              } // end switch (data)
381
//          }
382
//
383
//        else  // if (UART1_receiveNMEA)
384
//
385
//          {
386
//              // store new index
387
//              UART1_RxHead = tmphead;
388
//              // store received data in buffer
389
//              UART1_RxBuf[tmphead] = data;
390
//          }
391
//      }
392
//    UART1_LastRxError = lastRxError;
393
//}
394
#endif
395
 
396
//--------------------------------------------------------------
397
// Function: UART1 Data Register Empty interrupt
398
// Purpose:  called when the UART1 is ready to transmit the next byte
399
//--------------------------------------------------------------
400
ISR(USART1_UDRE_vect)
401
{
402
    unsigned char tmptail;
403
 
404
 
405
    if ( UART1_TxHead != UART1_TxTail)
406
    {
407
        // calculate and store new buffer index
408
        tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
409
        UART1_TxTail = tmptail;
410
        // get one byte from buffer and write it to UART
411
        UART1_DATA = UART1_TxBuf[tmptail];  // start transmission
412
    }
413
    else
414
    {
415
        // tx buffer empty, disable UDRE interrupt
416
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
417
    }
418
}
419
 
420
 
421
//--------------------------------------------------------------
422
// Function: uart1_init()
423
// Purpose:  initialize UART1 and set baudrate
424
// Input:   baudrate using macro UART_BAUD_SELECT()
425
// Returns:  none
426
//--------------------------------------------------------------
427
void uart1_init(unsigned int baudrate)
428
{
429
    UART1_TxHead = 0;
430
    UART1_TxTail = 0;
431
    UART1_RxHead = 0;
432
    UART1_RxTail = 0;
433
    UART1_RxError = 0;
434
    UART1_receiveNMEA = false;  //Empfang von NMEA Daten aus
435
 
436
 
437
    // Set baud rate
438
    if ( baudrate & 0x8000 )
439
    {
440
        UART1_STATUS = (1<<U2X1);  //Enable 2x speed
441
        baudrate &= ~0x8000;
442
    }
443
    UBRR1H = (unsigned char)(baudrate>>8);
444
    UBRR1L = (unsigned char) baudrate;
445
 
446
    // Enable USART receiver and transmitter and receive complete interrupt
447
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
448
 
449
    // Set frame format: asynchronous, 8data, no parity, 1stop bit
450
#ifdef URSEL1
451
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
452
#else
453
    UCSR1C = (3<<UCSZ10);
454
//  UCSR1C = (1<<UCSZ11) | (1<<UCSZ10); // 8data Bit
455
#endif
456
 
457
 
458
 
459
}
460
 
461
 
462
//--------------------------------------------------------------
463
// Function: uart1_getc()
464
// Purpose:  return byte from ringbuffer
465
// Returns:  lower byte:  received byte from ringbuffer
466
//           higher byte: last receive error
467
//--------------------------------------------------------------
468
unsigned int uart1_getc(void)
469
{
470
    unsigned char tmptail;
471
    unsigned char data;
472
 
473
 
474
    if ( UART1_RxHead == UART1_RxTail )
475
    {
476
        return UART_NO_DATA;   // no data available
477
    }
478
 
479
    // calculate /store buffer index
480
    tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
481
    UART1_RxTail = tmptail;
482
 
483
    // get data from receive buffer
484
    data = UART1_RxBuf[tmptail];
485
 
486
    return (UART1_LastRxError << 8) + data;
487
 
488
}/* uart1_getc */
489
 
490
 
491
//--------------------------------------------------------------
492
// Function: uart1_peek()
493
// Purpose:  Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer
494
// Returns:  lower byte:  received byte from ringbuffer
495
//           higher byte: last receive error
496
//--------------------------------------------------------------
497
int uart1_peek(void)
498
{
499
        unsigned char tmptail;
500
        unsigned char data;
501
 
502
 
503
        if ( UART1_RxHead == UART1_RxTail )
504
        {
505
                return -1;   // no data available
506
        }
507
 
508
        // calculate /store buffer index
509
        tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
510
 
511
        // get data from receive buffer
512
        data = UART1_RxBuf[tmptail];
513
 
514
        return (UART1_LastRxError << 8) + data;
515
 
516
}/* uart1_getc */
517
 
518
 
519
//int HardwareSerial::peek(void)
520
//{
521
//  if (_rx_buffer->head == _rx_buffer->tail) {
522
//    return -1;
523
//  } else {
524
//    return _rx_buffer->buffer[_rx_buffer->tail];
525
//  }
526
//}
527
 
528
 
529
//--------------------------------------------------------------
530
// Function: uart1_putc()
531
// Purpose:  write byte to ringbuffer for transmitting via UART
532
// Input:    byte to be transmitted
533
// Returns:  1 on succes, 0 if remote not ready
534
//--------------------------------------------------------------
535
int uart1_putc(unsigned char data)
536
{
537
    unsigned char tmphead;
538
 
539
 
540
    tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
541
 
542
    while ( tmphead == UART1_TxTail )
543
    {;}  // wait for free space in buffer
544
 
545
    UART1_TxBuf[tmphead] = data;
546
    UART1_TxHead = tmphead;
547
 
548
    // enable UDRE interrupt
549
    UART1_CONTROL |= _BV(UART1_UDRIE);
550
    return (UART1_LastRxError << 8) + data;
551
}
552
 
553
 
554
//--------------------------------------------------------------
555
// Function: uart1_puts()
556
// Purpose:  transmit string to UART1
557
// Input:    string to be transmitted
558
// Returns:  none
559
//--------------------------------------------------------------
560
void uart1_puts(const char *s )
561
{
562
    while (*s)
563
        uart1_putc(*s++);
564
}
565
 
566
 
567
//--------------------------------------------------------------
568
// Function: uart1_puts_p()
569
// Purpose:  transmit string from program memory to UART1
570
// Input:    program memory string to be transmitted
571
// Returns:  none
572
//--------------------------------------------------------------
573
void uart1_puts_p(const char *progmem_s )
574
{
575
    register char c;
576
    while ( (c = pgm_read_byte(progmem_s++)) )
577
        uart1_putc(c);
578
}
579
 
580
 
581
//--------------------------------------------------------------
582
// Function: uart1_available()
583
// Purpose:  Determine the number of bytes waiting in the receive buffer
584
// Input:    None
585
// Returns:  Integer number of bytes in the receive buffer
586
//--------------------------------------------------------------
587
uint16_t uart1_available(void)
588
{
589
    return (UART_RX_BUFFER_MASK + UART1_RxHead - UART1_RxTail) % UART_RX_BUFFER_MASK;
590
}
591
 
592
 
593
 
594
//--------------------------------------------------------------
595
// Function: uart1_flush()
596
// Purpose:  Flush bytes waiting the receive buffer.  Acutally ignores them.
597
// Input:    None
598
// Returns:  None
599
//--------------------------------------------------------------
600
void uart1_flush(void)
601
{
602
    UART1_RxHead = UART1_RxTail;
603
}
604
 
605
 
606
/*************************************************************************
607
Function: utoa()
608
Purpose:  convert unsigned integer to ascii
609
Input:    string_buffer, string_buffer_size, unsigned integer value
610
Returns:  first ascii character
611
**************************************************************************/
612
char *utoa1(char* buffer, const unsigned int size, unsigned int value)
613
{
614
  char *p;
615
 
616
  // p points to last char
617
  p = buffer+size-1;
618
 
619
  // Set terminating Zero
620
  *p='\0';
621
 
622
  do
623
  {
624
    *--p = value%10 + '0';
625
    value = value/10;
626
  } while (value!=0 && p>buffer);
627
 
628
  return p;
629
}/* utoa */
630
 
631
 
632
 
633
 
634
 
635
 
636
#endif
637
//#endif
638