You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
			
		
		
		
		
			
		
			
				
	
	
		
			707 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			707 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
/*
 | 
						|
 * Modified  for different BUFFER_SIZE for UART0 && UART1
 | 
						|
 * see below: UART0_RX_BUFFER_SIZE/UART1_RX_BUFFER_SIZE && UART0_TX_BUFFER_SIZE/UART1_TX_BUFFER_SIZE
 | 
						|
 * Ibragimov M. 7/03/2015
 | 
						|
*/
 | 
						|
/*************************************************************************
 | 
						|
Title:    Interrupt UART library with receive/transmit circular buffers
 | 
						|
Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
 | 
						|
File:     $Id: uart.c,v 1.12 2014/01/08 21:58:12 peter Exp $
 | 
						|
Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
 | 
						|
Hardware: any AVR with built-in UART, 
 | 
						|
License:  GNU General Public License 
 | 
						|
          
 | 
						|
DESCRIPTION:
 | 
						|
    An interrupt is generated when the UART has finished transmitting or
 | 
						|
    receiving a byte. The interrupt handling routines use circular buffers
 | 
						|
    for buffering received and transmitted data.
 | 
						|
    
 | 
						|
    The UART0[1]_RX_BUFFER_SIZE and UART0[1]_TX_BUFFER_SIZE variables define
 | 
						|
    the buffer size in bytes. Note that these variables must be a 
 | 
						|
    power of 2.
 | 
						|
    
 | 
						|
USAGE:
 | 
						|
    Refere to the header file uart.h for a description of the routines. 
 | 
						|
    See also example test_uart.c.
 | 
						|
 | 
						|
NOTES:
 | 
						|
    Based on Atmel Application Note AVR306
 | 
						|
                    
 | 
						|
LICENSE:
 | 
						|
    Copyright (C) 2006 Peter Fleury
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU General Public License as published by
 | 
						|
    the Free Software Foundation; either version 2 of the License, or
 | 
						|
    any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
                        
 | 
						|
*************************************************************************/
 | 
						|
#include <avr/io.h>
 | 
						|
#include <avr/interrupt.h>
 | 
						|
#include <avr/pgmspace.h>
 | 
						|
#include "uart_extd.h"
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  constants and macros
 | 
						|
 */
 | 
						|
 | 
						|
/* size of RX0/TX0 buffers */
 | 
						|
#define UART0_RX_BUFFER_MASK ( UART0_RX_BUFFER_SIZE - 1)
 | 
						|
#define UART0_TX_BUFFER_MASK ( UART0_TX_BUFFER_SIZE - 1)
 | 
						|
 | 
						|
#if ( UART0_RX_BUFFER_SIZE & UART0_RX_BUFFER_MASK )
 | 
						|
#error RX0 buffer size is not a power of 2
 | 
						|
#endif
 | 
						|
#if ( UART0_TX_BUFFER_SIZE & UART0_TX_BUFFER_MASK )
 | 
						|
#error TX0 buffer size is not a power of 2
 | 
						|
#endif
 | 
						|
 | 
						|
/* size of RX1/TX1 buffers */
 | 
						|
#define UART1_RX_BUFFER_MASK ( UART1_RX_BUFFER_SIZE - 1)
 | 
						|
#define UART1_TX_BUFFER_MASK ( UART1_TX_BUFFER_SIZE - 1)
 | 
						|
 | 
						|
#if ( UART1_RX_BUFFER_SIZE & UART1_RX_BUFFER_MASK )
 | 
						|
#error RX1 buffer size is not a power of 2
 | 
						|
#endif
 | 
						|
#if ( UART1_TX_BUFFER_SIZE & UART1_TX_BUFFER_MASK )
 | 
						|
#error TX1 buffer size is not a power of 2
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#if defined(__AVR_AT90S2313__) \
 | 
						|
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
 | 
						|
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
 | 
						|
 || defined(__AVR_ATmega103__)
 | 
						|
 /* old AVR classic or ATmega103 with one UART */
 | 
						|
 #define AT90_UART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 | 
						|
 #define UART0_STATUS   USR
 | 
						|
 #define UART0_CONTROL  UCR
 | 
						|
 #define UART0_DATA     UDR  
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
 | 
						|
 /* old AVR classic with one UART */
 | 
						|
 #define AT90_UART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR 
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif  defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
 | 
						|
  || defined(__AVR_ATmega323__)
 | 
						|
  /* ATmega with one USART */
 | 
						|
 #define ATMEGA_USART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART_RXC_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
 | 
						|
 #define ATMEGA_USART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined(__AVR_ATmega163__)
 | 
						|
  /* ATmega163 with one UART */
 | 
						|
 #define ATMEGA_UART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined(__AVR_ATmega162__) 
 | 
						|
 /* ATmega with two USART */
 | 
						|
 #define ATMEGA_USART0
 | 
						|
 #define ATMEGA_USART1
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART0_RXC_vect
 | 
						|
 #define UART1_RECEIVE_INTERRUPT   USART1_RXC_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR0A
 | 
						|
 #define UART0_CONTROL  UCSR0B
 | 
						|
 #define UART0_DATA     UDR0
 | 
						|
 #define UART0_UDRIE    UDRIE0
 | 
						|
 #define UART1_STATUS   UCSR1A
 | 
						|
 #define UART1_CONTROL  UCSR1B
 | 
						|
 #define UART1_DATA     UDR1
 | 
						|
 #define UART1_UDRIE    UDRIE1
 | 
						|
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
 | 
						|
 /* ATmega with two USART */
 | 
						|
 #define ATMEGA_USART0
 | 
						|
 #define ATMEGA_USART1
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
 #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR0A
 | 
						|
 #define UART0_CONTROL  UCSR0B
 | 
						|
 #define UART0_DATA     UDR0
 | 
						|
 #define UART0_UDRIE    UDRIE0
 | 
						|
 #define UART1_STATUS   UCSR1A
 | 
						|
 #define UART1_CONTROL  UCSR1B
 | 
						|
 #define UART1_DATA     UDR1
 | 
						|
 #define UART1_UDRIE    UDRIE1
 | 
						|
#elif defined(__AVR_ATmega161__)
 | 
						|
 /* ATmega with UART */
 | 
						|
 #error "AVR ATmega161 currently not supported by this libaray !"
 | 
						|
#elif defined(__AVR_ATmega169__) 
 | 
						|
 /* ATmega with one USART */
 | 
						|
 #define ATMEGA_USART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \
 | 
						|
 || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__)
 | 
						|
 /* ATmega with one USART */
 | 
						|
 #define ATMEGA_USART0
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR0A
 | 
						|
 #define UART0_CONTROL  UCSR0B
 | 
						|
 #define UART0_DATA     UDR0
 | 
						|
 #define UART0_UDRIE    UDRIE0
 | 
						|
#elif defined(__AVR_ATtiny2313__) 
 | 
						|
 #define ATMEGA_USART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSRA
 | 
						|
 #define UART0_CONTROL  UCSRB
 | 
						|
 #define UART0_DATA     UDR
 | 
						|
 #define UART0_UDRIE    UDRIE
 | 
						|
#elif defined(__AVR_ATmega329__) || \
 | 
						|
      defined(__AVR_ATmega649__) || \
 | 
						|
      defined(__AVR_ATmega325__) || \
 | 
						|
      defined(__AVR_ATmega645__) 
 | 
						|
  /* ATmega with one USART */
 | 
						|
  #define ATMEGA_USART0
 | 
						|
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
  #define UART0_STATUS   UCSR0A
 | 
						|
  #define UART0_CONTROL  UCSR0B
 | 
						|
  #define UART0_DATA     UDR0
 | 
						|
  #define UART0_UDRIE    UDRIE0
 | 
						|
#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__)  || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__)
 | 
						|
/* ATmega with two USART */
 | 
						|
  #define ATMEGA_USART0
 | 
						|
  #define ATMEGA_USART1
 | 
						|
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
  #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
 | 
						|
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 | 
						|
  #define UART0_STATUS   UCSR0A
 | 
						|
  #define UART0_CONTROL  UCSR0B
 | 
						|
  #define UART0_DATA     UDR0
 | 
						|
  #define UART0_UDRIE    UDRIE0
 | 
						|
  #define UART1_STATUS   UCSR1A
 | 
						|
  #define UART1_CONTROL  UCSR1B
 | 
						|
  #define UART1_DATA     UDR1
 | 
						|
  #define UART1_UDRIE    UDRIE1  
 | 
						|
#elif defined(__AVR_ATmega644__)
 | 
						|
 /* ATmega with one USART */
 | 
						|
 #define ATMEGA_USART0
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR0A
 | 
						|
 #define UART0_CONTROL  UCSR0B
 | 
						|
 #define UART0_DATA     UDR0
 | 
						|
 #define UART0_UDRIE    UDRIE0
 | 
						|
#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
 | 
						|
 /* ATmega with two USART */
 | 
						|
 #define ATMEGA_USART0
 | 
						|
 #define ATMEGA_USART1
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 | 
						|
 #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 | 
						|
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR0A
 | 
						|
 #define UART0_CONTROL  UCSR0B
 | 
						|
 #define UART0_DATA     UDR0
 | 
						|
 #define UART0_UDRIE    UDRIE0
 | 
						|
 #define UART1_STATUS   UCSR1A
 | 
						|
 #define UART1_CONTROL  UCSR1B
 | 
						|
 #define UART1_DATA     UDR1
 | 
						|
 #define UART1_UDRIE    UDRIE1
 | 
						|
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)
 | 
						|
 /* AT90USBxx with one USART */
 | 
						|
 #define AT90USB_USART
 | 
						|
 #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect
 | 
						|
 #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 | 
						|
 #define UART0_STATUS   UCSR1A
 | 
						|
 #define UART0_CONTROL  UCSR1B
 | 
						|
 #define UART0_DATA     UDR1
 | 
						|
 #define UART0_UDRIE    UDRIE1
 | 
						|
#else
 | 
						|
 #error "no UART definition for MCU available"
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  module global variables
 | 
						|
 */
 | 
						|
static volatile unsigned char UART_TxBuf[UART0_TX_BUFFER_SIZE];
 | 
						|
static volatile unsigned char UART_RxBuf[UART0_RX_BUFFER_SIZE];
 | 
						|
static volatile unsigned char UART_TxHead;
 | 
						|
static volatile unsigned char UART_TxTail;
 | 
						|
static volatile unsigned char UART_RxHead;
 | 
						|
static volatile unsigned char UART_RxTail;
 | 
						|
static volatile unsigned char UART_LastRxError;
 | 
						|
 | 
						|
#if defined( ATMEGA_USART1 )
 | 
						|
static volatile unsigned char UART1_TxBuf[UART1_TX_BUFFER_SIZE];
 | 
						|
static volatile unsigned char UART1_RxBuf[UART1_RX_BUFFER_SIZE];
 | 
						|
static volatile unsigned char UART1_TxHead;
 | 
						|
static volatile unsigned char UART1_TxTail;
 | 
						|
static volatile unsigned char UART1_RxHead;
 | 
						|
static volatile unsigned char UART1_RxTail;
 | 
						|
static volatile unsigned char UART1_LastRxError;
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
 | 
						|
ISR (UART0_RECEIVE_INTERRUPT)	
 | 
						|
/*************************************************************************
 | 
						|
Function: UART Receive Complete interrupt
 | 
						|
Purpose:  called when the UART has received a character
 | 
						|
**************************************************************************/
 | 
						|
{
 | 
						|
    unsigned char tmphead;
 | 
						|
    unsigned char data;
 | 
						|
    unsigned char usr;
 | 
						|
    unsigned char lastRxError;
 | 
						|
 
 | 
						|
 
 | 
						|
    /* read UART status register and UART data register */ 
 | 
						|
    usr  = UART0_STATUS;
 | 
						|
    data = UART0_DATA;
 | 
						|
    
 | 
						|
    /* */
 | 
						|
#if defined( AT90_UART )
 | 
						|
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
 | 
						|
#elif defined( ATMEGA_USART )
 | 
						|
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
 | 
						|
#elif defined( ATMEGA_USART0 )
 | 
						|
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
 | 
						|
#elif defined ( ATMEGA_UART )
 | 
						|
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
 | 
						|
#elif defined( AT90USB_USART )
 | 
						|
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
 | 
						|
#endif
 | 
						|
        
 | 
						|
    /* calculate buffer index */ 
 | 
						|
    tmphead = ( UART_RxHead + 1) & UART0_RX_BUFFER_MASK;
 | 
						|
    
 | 
						|
    if ( tmphead == UART_RxTail ) {
 | 
						|
        /* error: receive buffer overflow */
 | 
						|
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
 | 
						|
    }else{
 | 
						|
        /* store new index */
 | 
						|
        UART_RxHead = tmphead;
 | 
						|
        /* store received data in buffer */
 | 
						|
        UART_RxBuf[tmphead] = data;
 | 
						|
    }
 | 
						|
    UART_LastRxError |= lastRxError;   
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
ISR (UART0_TRANSMIT_INTERRUPT)
 | 
						|
/*************************************************************************
 | 
						|
Function: UART Data Register Empty interrupt
 | 
						|
Purpose:  called when the UART is ready to transmit the next byte
 | 
						|
**************************************************************************/
 | 
						|
{
 | 
						|
    unsigned char tmptail;
 | 
						|
 | 
						|
    
 | 
						|
    if ( UART_TxHead != UART_TxTail) {
 | 
						|
        /* calculate and store new buffer index */
 | 
						|
        tmptail = (UART_TxTail + 1) & UART0_TX_BUFFER_MASK;
 | 
						|
        UART_TxTail = tmptail;
 | 
						|
        /* get one byte from buffer and write it to UART */
 | 
						|
        UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
 | 
						|
    }else{
 | 
						|
        /* tx buffer empty, disable UDRE interrupt */
 | 
						|
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart_init()
 | 
						|
Purpose:  initialize UART and set baudrate
 | 
						|
Input:    baudrate using macro UART_BAUD_SELECT()
 | 
						|
Returns:  none
 | 
						|
**************************************************************************/
 | 
						|
void uart_init(unsigned int baudrate)
 | 
						|
{
 | 
						|
    UART_TxHead = 0;
 | 
						|
    UART_TxTail = 0;
 | 
						|
    UART_RxHead = 0;
 | 
						|
    UART_RxTail = 0;
 | 
						|
    
 | 
						|
#if defined( AT90_UART )
 | 
						|
    /* set baud rate */
 | 
						|
    UBRR = (unsigned char)baudrate; 
 | 
						|
 | 
						|
    /* enable UART receiver and transmmitter and receive complete interrupt */
 | 
						|
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
 | 
						|
 | 
						|
#elif defined (ATMEGA_USART)
 | 
						|
    /* Set baud rate */
 | 
						|
    if ( baudrate & 0x8000 )
 | 
						|
    {
 | 
						|
    	 UART0_STATUS = (1<<U2X);  //Enable 2x speed 
 | 
						|
    	 baudrate &= ~0x8000;
 | 
						|
    }
 | 
						|
    UBRRH = (unsigned char)(baudrate>>8);
 | 
						|
    UBRRL = (unsigned char) baudrate;
 | 
						|
   
 | 
						|
    /* Enable USART receiver and transmitter and receive complete interrupt */
 | 
						|
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
 | 
						|
    
 | 
						|
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
 | 
						|
    #ifdef URSEL
 | 
						|
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
 | 
						|
    #else
 | 
						|
    UCSRC = (3<<UCSZ0);
 | 
						|
    #endif 
 | 
						|
    
 | 
						|
#elif defined (ATMEGA_USART0 )
 | 
						|
    /* Set baud rate */
 | 
						|
    if ( baudrate & 0x8000 ) 
 | 
						|
    {
 | 
						|
   		UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
 | 
						|
   		baudrate &= ~0x8000;
 | 
						|
   	}
 | 
						|
    UBRR0H = (unsigned char)(baudrate>>8);
 | 
						|
    UBRR0L = (unsigned char) baudrate;
 | 
						|
 | 
						|
    /* Enable USART receiver and transmitter and receive complete interrupt */
 | 
						|
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
 | 
						|
    
 | 
						|
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
 | 
						|
    #ifdef URSEL0
 | 
						|
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
 | 
						|
    #else
 | 
						|
    UCSR0C = (3<<UCSZ00);
 | 
						|
    #endif 
 | 
						|
 | 
						|
#elif defined ( ATMEGA_UART )
 | 
						|
    /* set baud rate */
 | 
						|
    if ( baudrate & 0x8000 ) 
 | 
						|
    {
 | 
						|
    	UART0_STATUS = (1<<U2X);  //Enable 2x speed 
 | 
						|
    	baudrate &= ~0x8000;
 | 
						|
    }
 | 
						|
    UBRRHI = (unsigned char)(baudrate>>8);
 | 
						|
    UBRR   = (unsigned char) baudrate;
 | 
						|
 | 
						|
    /* Enable UART receiver and transmitter and receive complete interrupt */
 | 
						|
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
 | 
						|
 | 
						|
#elif defined ( AT90USB_USART )
 | 
						|
   /* set baud rate */
 | 
						|
    if ( baudrate & 0x8000 ) 
 | 
						|
    {
 | 
						|
    	UART0_STATUS = (1<<U2X1 );  //Enable 2x speed 
 | 
						|
    	baudrate &= ~0x8000;
 | 
						|
    }
 | 
						|
    UBRR1H = (unsigned char)(baudrate>>8);
 | 
						|
    UBRR1L = (unsigned char) baudrate;
 | 
						|
 | 
						|
    /* Enable UART receiver and transmitter and receive complete interrupt */
 | 
						|
    UART0_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
 | 
						|
    
 | 
						|
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
 | 
						|
    UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
 | 
						|
#endif
 | 
						|
 | 
						|
}/* uart_init */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart_getc()
 | 
						|
Purpose:  return byte from ringbuffer  
 | 
						|
Returns:  lower byte:  received byte from ringbuffer
 | 
						|
          higher byte: last receive error
 | 
						|
**************************************************************************/
 | 
						|
unsigned int uart_getc(void)
 | 
						|
{    
 | 
						|
    unsigned char tmptail;
 | 
						|
    unsigned char data;
 | 
						|
 | 
						|
 | 
						|
    if ( UART_RxHead == UART_RxTail ) {
 | 
						|
        return UART_NO_DATA;   /* no data available */
 | 
						|
    }
 | 
						|
    
 | 
						|
    /* calculate /store buffer index */
 | 
						|
    tmptail = (UART_RxTail + 1) & UART0_RX_BUFFER_MASK;
 | 
						|
    UART_RxTail = tmptail; 
 | 
						|
    
 | 
						|
    /* get data from receive buffer */
 | 
						|
    data = UART_RxBuf[tmptail];
 | 
						|
    
 | 
						|
    data = (UART_LastRxError << 8) + data;
 | 
						|
    UART_LastRxError = 0;
 | 
						|
    return data;
 | 
						|
 | 
						|
}/* uart_getc */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart_putc()
 | 
						|
Purpose:  write byte to ringbuffer for transmitting via UART
 | 
						|
Input:    byte to be transmitted
 | 
						|
Returns:  none          
 | 
						|
**************************************************************************/
 | 
						|
void uart_putc(unsigned char data)
 | 
						|
{
 | 
						|
    unsigned char tmphead;
 | 
						|
 | 
						|
    
 | 
						|
    tmphead  = (UART_TxHead + 1) & UART0_TX_BUFFER_MASK;
 | 
						|
    
 | 
						|
    while ( tmphead == UART_TxTail ){
 | 
						|
        ;/* wait for free space in buffer */
 | 
						|
    }
 | 
						|
    
 | 
						|
    UART_TxBuf[tmphead] = data;
 | 
						|
    UART_TxHead = tmphead;
 | 
						|
 | 
						|
    /* enable UDRE interrupt */
 | 
						|
    UART0_CONTROL    |= _BV(UART0_UDRIE);
 | 
						|
 | 
						|
}/* uart_putc */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart_puts()
 | 
						|
Purpose:  transmit string to UART
 | 
						|
Input:    string to be transmitted
 | 
						|
Returns:  none          
 | 
						|
**************************************************************************/
 | 
						|
void uart_puts(const char *s )
 | 
						|
{
 | 
						|
    while (*s) 
 | 
						|
      uart_putc(*s++);
 | 
						|
 | 
						|
}/* uart_puts */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart_puts_p()
 | 
						|
Purpose:  transmit string from program memory to UART
 | 
						|
Input:    program memory string to be transmitted
 | 
						|
Returns:  none
 | 
						|
**************************************************************************/
 | 
						|
void uart_puts_p(const char *progmem_s )
 | 
						|
{
 | 
						|
    register char c;
 | 
						|
    
 | 
						|
    while ( (c = pgm_read_byte(progmem_s++)) ) 
 | 
						|
      uart_putc(c);
 | 
						|
 | 
						|
}/* uart_puts_p */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * these functions are only for ATmegas with two USART
 | 
						|
 */
 | 
						|
#if defined( ATMEGA_USART1 )
 | 
						|
 | 
						|
ISR(UART1_RECEIVE_INTERRUPT)
 | 
						|
/*************************************************************************
 | 
						|
Function: UART1 Receive Complete interrupt
 | 
						|
Purpose:  called when the UART1 has received a character
 | 
						|
**************************************************************************/
 | 
						|
{
 | 
						|
    unsigned char tmphead;
 | 
						|
    unsigned char data;
 | 
						|
    unsigned char usr;
 | 
						|
    unsigned char lastRxError;
 | 
						|
 
 | 
						|
 
 | 
						|
    /* read UART status register and UART data register */ 
 | 
						|
    usr  = UART1_STATUS;
 | 
						|
    data = UART1_DATA;
 | 
						|
    
 | 
						|
    /* */
 | 
						|
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
 | 
						|
        
 | 
						|
    /* calculate buffer index */ 
 | 
						|
    tmphead = ( UART1_RxHead + 1) & UART1_RX_BUFFER_MASK;
 | 
						|
    
 | 
						|
    if ( tmphead == UART1_RxTail ) {
 | 
						|
        /* error: receive buffer overflow */
 | 
						|
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
 | 
						|
    }else{
 | 
						|
        /* store new index */
 | 
						|
        UART1_RxHead = tmphead;
 | 
						|
        /* store received data in buffer */
 | 
						|
        UART1_RxBuf[tmphead] = data;
 | 
						|
    }
 | 
						|
    UART1_LastRxError |= lastRxError;   
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
ISR(UART1_TRANSMIT_INTERRUPT)
 | 
						|
/*************************************************************************
 | 
						|
Function: UART1 Data Register Empty interrupt
 | 
						|
Purpose:  called when the UART1 is ready to transmit the next byte
 | 
						|
**************************************************************************/
 | 
						|
{
 | 
						|
    unsigned char tmptail;
 | 
						|
 | 
						|
    
 | 
						|
    if ( UART1_TxHead != UART1_TxTail) {
 | 
						|
        /* calculate and store new buffer index */
 | 
						|
        tmptail = (UART1_TxTail + 1) & UART1_TX_BUFFER_MASK;
 | 
						|
        UART1_TxTail = tmptail;
 | 
						|
        /* get one byte from buffer and write it to UART */
 | 
						|
        UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
 | 
						|
    }else{
 | 
						|
        /* tx buffer empty, disable UDRE interrupt */
 | 
						|
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart1_init()
 | 
						|
Purpose:  initialize UART1 and set baudrate
 | 
						|
Input:    baudrate using macro UART_BAUD_SELECT()
 | 
						|
Returns:  none
 | 
						|
**************************************************************************/
 | 
						|
void uart1_init(unsigned int baudrate)
 | 
						|
{
 | 
						|
    UART1_TxHead = 0;
 | 
						|
    UART1_TxTail = 0;
 | 
						|
    UART1_RxHead = 0;
 | 
						|
    UART1_RxTail = 0;
 | 
						|
    
 | 
						|
 | 
						|
    /* Set baud rate */
 | 
						|
    if ( baudrate & 0x8000 ) 
 | 
						|
    {
 | 
						|
    	UART1_STATUS = (1<<U2X1);  //Enable 2x speed 
 | 
						|
      baudrate &= ~0x8000;
 | 
						|
    }
 | 
						|
    UBRR1H = (unsigned char)(baudrate>>8);
 | 
						|
    UBRR1L = (unsigned char) baudrate;
 | 
						|
 | 
						|
    /* Enable USART receiver and transmitter and receive complete interrupt */
 | 
						|
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
 | 
						|
    
 | 
						|
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */   
 | 
						|
    #ifdef URSEL1
 | 
						|
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
 | 
						|
    #else
 | 
						|
    UCSR1C = (3<<UCSZ10);
 | 
						|
    #endif 
 | 
						|
}/* uart_init */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart1_getc()
 | 
						|
Purpose:  return byte from ringbuffer  
 | 
						|
Returns:  lower byte:  received byte from ringbuffer
 | 
						|
          higher byte: last receive error
 | 
						|
**************************************************************************/
 | 
						|
unsigned int uart1_getc(void)
 | 
						|
{    
 | 
						|
    unsigned char tmptail;
 | 
						|
    unsigned char data;
 | 
						|
 | 
						|
 | 
						|
    if ( UART1_RxHead == UART1_RxTail ) {
 | 
						|
        return UART_NO_DATA;   /* no data available */
 | 
						|
    }
 | 
						|
    
 | 
						|
    /* calculate /store buffer index */
 | 
						|
    tmptail = (UART1_RxTail + 1) & UART1_RX_BUFFER_MASK;
 | 
						|
    UART1_RxTail = tmptail; 
 | 
						|
    
 | 
						|
    /* get data from receive buffer */
 | 
						|
    data = UART1_RxBuf[tmptail];
 | 
						|
    
 | 
						|
    data = (UART1_LastRxError << 8) + data;
 | 
						|
    UART1_LastRxError = 0;
 | 
						|
    return data;
 | 
						|
 | 
						|
}/* uart1_getc */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart1_putc()
 | 
						|
Purpose:  write byte to ringbuffer for transmitting via UART
 | 
						|
Input:    byte to be transmitted
 | 
						|
Returns:  none          
 | 
						|
**************************************************************************/
 | 
						|
void uart1_putc(unsigned char data)
 | 
						|
{
 | 
						|
    unsigned char tmphead;
 | 
						|
 | 
						|
    
 | 
						|
    tmphead  = (UART1_TxHead + 1) & UART1_TX_BUFFER_MASK;
 | 
						|
    
 | 
						|
    while ( tmphead == UART1_TxTail ){
 | 
						|
        ;/* wait for free space in buffer */
 | 
						|
    }
 | 
						|
    
 | 
						|
    UART1_TxBuf[tmphead] = data;
 | 
						|
    UART1_TxHead = tmphead;
 | 
						|
 | 
						|
    /* enable UDRE interrupt */
 | 
						|
    UART1_CONTROL    |= _BV(UART1_UDRIE);
 | 
						|
 | 
						|
}/* uart1_putc */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart1_puts()
 | 
						|
Purpose:  transmit string to UART1
 | 
						|
Input:    string to be transmitted
 | 
						|
Returns:  none          
 | 
						|
**************************************************************************/
 | 
						|
void uart1_puts(const char *s )
 | 
						|
{
 | 
						|
    while (*s) 
 | 
						|
      uart1_putc(*s++);
 | 
						|
 | 
						|
}/* uart1_puts */
 | 
						|
 | 
						|
 | 
						|
/*************************************************************************
 | 
						|
Function: uart1_puts_p()
 | 
						|
Purpose:  transmit string from program memory to UART1
 | 
						|
Input:    program memory string to be transmitted
 | 
						|
Returns:  none
 | 
						|
**************************************************************************/
 | 
						|
void uart1_puts_p(const char *progmem_s )
 | 
						|
{
 | 
						|
    register char c;
 | 
						|
    
 | 
						|
    while ( (c = pgm_read_byte(progmem_s++)) ) 
 | 
						|
      uart1_putc(c);
 | 
						|
 | 
						|
}/* uart1_puts_p */
 | 
						|
 | 
						|
 | 
						|
#endif
 |