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
 |