From 3c6bfbfa39655d63027cf12652d99c5c542080a0 Mon Sep 17 00:00:00 2001 From: klaute Date: Tue, 23 Aug 2016 19:10:37 +0200 Subject: [PATCH] Dos2Unix... --- firmware/main.c | 1 + firmware/uart/uart.c | 1552 +++++++++++++++++++++--------------------- firmware/uart/uart.h | 414 +++++------ 3 files changed, 983 insertions(+), 984 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index 3c731bb..0a3d165 100755 --- a/firmware/main.c +++ b/firmware/main.c @@ -82,6 +82,7 @@ int main(void) cc_init(); SET_ERR_MASK(ERRMASK_USB_NOTREADY); + GlobalInterruptEnable(); for (;;) diff --git a/firmware/uart/uart.c b/firmware/uart/uart.c index 547c736..d859d81 100755 --- a/firmware/uart/uart.c +++ b/firmware/uart/uart.c @@ -1,777 +1,775 @@ -/************************************************************************* -Title: Interrupt UART library with receive/transmit circular buffers -Author: Peter Fleury http://tinyurl.com/peterfleury -File: $Id: uart.c,v 1.15.2.4 2015/09/05 18:33:32 peter Exp $ -Software: AVR-GCC 4.x -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 UART_RX_BUFFER_SIZE and UART_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) 2015 Peter Fleury, GNU General Public License Version 3 - - 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 -#include -#include -#include "uart.h" - - -/* - * constants and macros - */ - -/* size of RX/TX buffers */ -#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1) -#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1) - -#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) -#error RX buffer size is not a power of 2 -#endif -#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) -#error TX buffer size is not a power of 2 -#endif - - -#if defined(__AVR_AT90S2313__) || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ - defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ - defined(__AVR_ATmega103__) - /* old AVR classic or ATmega103 with one 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 - #define UART0_UBRRL UBRR - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN -#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) - /* old AVR classic with one 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 - #define UART0_UBRRL UBRR - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN -#elif defined(__AVR_AT90PWM216__) || defined(__AVR_AT90PWM316__) - /* AT90PWN216/316 with one 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_CONTROLC UCSRC - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE - #define UART0_UBRRL UBRRL - #define UART0_UBRRH UBRRH - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN - #define UART0_BIT_UCSZ0 UCSZ0 - #define UART0_BIT_UCSZ1 UCSZ1 -#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || \ - defined(__AVR_ATmega16__) || defined(__AVR_ATmega16A__) || \ - defined(__AVR_ATmega32__) || defined(__AVR_ATmega32A__) || \ - defined(__AVR_ATmega323__) - /* ATmega with one 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_CONTROLC UCSRC - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE - #define UART0_UBRRL UBRRL - #define UART0_UBRRH UBRRH - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN - #define UART0_BIT_UCSZ0 UCSZ0 - #define UART0_BIT_UCSZ1 UCSZ1 - #define UART0_BIT_URSEL URSEL -#elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) - #define UART0_RECEIVE_INTERRUPT USART_RX_vect - #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect - #define UART0_STATUS UCSRA - #define UART0_CONTROL UCSRB - #define UART0_CONTROLC UCSRC - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE - #define UART0_UBRRL UBRRL - #define UART0_UBRRH UBRRH - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN - #define UART0_BIT_UCSZ0 UCSZ0 - #define UART0_BIT_UCSZ1 UCSZ1 - #define UART0_BIT_URSEL URSEL -#elif defined(__AVR_ATmega163__) - /* ATmega163 with one 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 - #define UART0_UBRRL UBRR - #define UART0_UBRRH UBRRHI - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN -#elif defined(__AVR_ATmega162__) - /* ATmega with two USART */ - #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_CONTROLC UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART0_UBRRL UBRR0L - #define UART0_UBRRH UBRR0H - #define UART0_BIT_URSEL URSEL0 - #define UART0_BIT_U2X U2X0 - #define UART0_BIT_RXCIE RXCIE0 - #define UART0_BIT_RXEN RXEN0 - #define UART0_BIT_TXEN TXEN0 - #define UART0_BIT_UCSZ0 UCSZ00 - #define UART0_BIT_UCSZ1 UCSZ01 - #define UART1_STATUS UCSR1A - #define UART1_CONTROL UCSR1B - #define UART1_CONTROLC UCSR1C - #define UART1_DATA UDR1 - #define UART1_UDRIE UDRIE1 - #define UART1_UBRRL UBRR1L - #define UART1_UBRRH UBRR1H - #define UART1_BIT_URSEL URSEL1 - #define UART1_BIT_U2X U2X1 - #define UART1_BIT_RXCIE RXCIE1 - #define UART1_BIT_RXEN RXEN1 - #define UART1_BIT_TXEN TXEN1 - #define UART1_BIT_UCSZ0 UCSZ10 - #define UART1_BIT_UCSZ1 UCSZ11 -#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 UART0_RECEIVE_INTERRUPT USART0_RX_vect - #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect - #define UART0_STATUS UCSRA - #define UART0_CONTROL UCSRB - #define UART0_CONTROLC UCSRC - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE - #define UART0_UBRRL UBRRL - #define UART0_UBRRH UBRRH - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN - #define UART0_BIT_UCSZ0 UCSZ0 - #define UART0_BIT_UCSZ1 UCSZ1 -#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48PB__) || \ - defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88PB__) || \ - defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__)|| defined(__AVR_ATmega168P__)|| defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || \ - defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \ - defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__) - /* ATmega with one USART */ - #define UART0_RECEIVE_INTERRUPT USART_RX_vect - #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect - #define UART0_STATUS UCSR0A - #define UART0_CONTROL UCSR0B - #define UART0_CONTROLC UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART0_UBRRL UBRR0L - #define UART0_UBRRH UBRR0H - #define UART0_BIT_U2X U2X0 - #define UART0_BIT_RXCIE RXCIE0 - #define UART0_BIT_RXEN RXEN0 - #define UART0_BIT_TXEN TXEN0 - #define UART0_BIT_UCSZ0 UCSZ00 - #define UART0_BIT_UCSZ1 UCSZ01 -#elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__) - /* ATtiny with one 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_CONTROLC UCSRC - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE - #define UART0_UBRRL UBRRL - #define UART0_UBRRH UBRRH - #define UART0_BIT_U2X U2X - #define UART0_BIT_RXCIE RXCIE - #define UART0_BIT_RXEN RXEN - #define UART0_BIT_TXEN TXEN - #define UART0_BIT_UCSZ0 UCSZ0 - #define UART0_BIT_UCSZ1 UCSZ1 -#elif defined(__AVR_ATmega329__) || defined(__AVR_ATmega649__) || defined(__AVR_ATmega3290__) || defined(__AVR_ATmega6490__) ||\ - defined(__AVR_ATmega169A__) || defined(__AVR_ATmega169PA__) || \ - defined(__AVR_ATmega329A__) || defined(__AVR_ATmega329PA__) || defined(__AVR_ATmega3290A__) || defined(__AVR_ATmega3290PA__) || \ - defined(__AVR_ATmega649A__) || defined(__AVR_ATmega649P__) || defined(__AVR_ATmega6490A__) || defined(__AVR_ATmega6490P__) || \ - defined(__AVR_ATmega165__) || defined(__AVR_ATmega325__) || defined(__AVR_ATmega645__) || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega6450__) || \ - defined(__AVR_ATmega165A__) || defined(__AVR_ATmega165PA__) || \ - defined(__AVR_ATmega325A__) || defined(__AVR_ATmega325PA__) || defined(__AVR_ATmega3250A__) || defined(__AVR_ATmega3250PA__) ||\ - defined(__AVR_ATmega645A__) || defined(__AVR_ATmega645PA__) || defined(__AVR_ATmega6450A__) || defined(__AVR_ATmega6450PA__) || \ - defined(__AVR_ATmega644__) - /* ATmega with one USART */ - #define UART0_RECEIVE_INTERRUPT USART0_RX_vect - #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect - #define UART0_STATUS UCSR0A - #define UART0_CONTROL UCSR0B - #define UART0_CONTROLC UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART0_UBRRL UBRR0L - #define UART0_UBRRH UBRR0H - #define UART0_BIT_U2X U2X0 - #define UART0_BIT_RXCIE RXCIE0 - #define UART0_BIT_RXEN RXEN0 - #define UART0_BIT_TXEN TXEN0 - #define UART0_BIT_UCSZ0 UCSZ00 - #define UART0_BIT_UCSZ1 UCSZ01 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega128A__) ||\ - defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || \ - defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || \ - defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164PA__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) || \ - defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) ||\ - defined(__AVR_ATtiny1634__) - /* ATmega with two USART */ - #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_CONTROLC UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART0_UBRRL UBRR0L - #define UART0_UBRRH UBRR0H - #define UART0_BIT_U2X U2X0 - #define UART0_BIT_RXCIE RXCIE0 - #define UART0_BIT_RXEN RXEN0 - #define UART0_BIT_TXEN TXEN0 - #define UART0_BIT_UCSZ0 UCSZ00 - #define UART0_BIT_UCSZ1 UCSZ01 - #define UART1_STATUS UCSR1A - #define UART1_CONTROL UCSR1B - #define UART1_CONTROLC UCSR1C - #define UART1_DATA UDR1 - #define UART1_UDRIE UDRIE1 - #define UART1_UBRRL UBRR1L - #define UART1_UBRRH UBRR1H - #define UART1_BIT_U2X U2X1 - #define UART1_BIT_RXCIE RXCIE1 - #define UART1_BIT_RXEN RXEN1 - #define UART1_BIT_TXEN TXEN1 - #define UART1_BIT_UCSZ0 UCSZ10 - #define UART1_BIT_UCSZ1 UCSZ11 -#elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || \ - defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \ - defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ - defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__) - #define UART0_RECEIVE_INTERRUPT USART1_RX_vect - #define UART0_TRANSMIT_INTERRUPT USART1_UDRE_vect - #define UART0_STATUS UCSR1A - #define UART0_CONTROL UCSR1B - #define UART0_CONTROLC UCSR1C - #define UART0_DATA UDR1 - #define UART0_UDRIE UDRIE1 - #define UART0_UBRRL UBRR1L - #define UART0_UBRRH UBRR1H - #define UART0_BIT_U2X U2X1 - #define UART0_BIT_RXCIE RXCIE1 - #define UART0_BIT_RXEN RXEN1 - #define UART0_BIT_TXEN TXEN1 - #define UART0_BIT_UCSZ0 UCSZ10 - #define UART0_BIT_UCSZ1 UCSZ11 -#else - #error "no UART definition for MCU available" -#endif - - - -/* - * module global variables - */ -static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; -static volatile unsigned char UART_RxBuf[UART_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[UART_TX_BUFFER_SIZE]; -static volatile unsigned char UART1_RxBuf[UART_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; - - /* get FEn (Frame Error) DORn (Data OverRun) UPEn (USART Parity Error) bits */ -#if defined(FE) && defined(DOR) && defined(UPE) - lastRxError = usr & (_BV(FE)|_BV(DOR)|_BV(UPE) ); -#elif defined(FE0) && defined(DOR0) && defined(UPE0) - lastRxError = usr & (_BV(FE0)|_BV(DOR0)|_BV(UPE0) ); -#elif defined(FE1) && defined(DOR1) && defined(UPE1) - lastRxError = usr & (_BV(FE1)|_BV(DOR1)|_BV(UPE1) ); -#elif defined(FE) && defined(DOR) - lastRxError = usr & (_BV(FE)|_BV(DOR) ); -#endif - - /* calculate buffer index */ - tmphead = ( UART_RxHead + 1) & UART_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) & UART_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; - -#ifdef UART_TEST -#ifndef UART0_BIT_U2X -#warning "UART0_BIT_U2X not defined" -#endif -#ifndef UART0_UBRRH -#warning "UART0_UBRRH not defined" -#endif -#ifndef UART0_CONTROLC -#warning "UART0_CONTROLC not defined" -#endif -#if defined(URSEL) || defined(URSEL0) -#ifndef UART0_BIT_URSEL -#warning "UART0_BIT_URSEL not defined" -#endif -#endif -#endif - - /* Set baud rate */ - if ( baudrate & 0x8000 ) - { - #if UART0_BIT_U2X - UART0_STATUS = (1<>8)&0x80) ; - #endif - UART0_UBRRL = (unsigned char) (baudrate&0x00FF); - - /* Enable USART receiver and transmitter and receive complete interrupt */ - UART0_CONTROL = _BV(UART0_BIT_RXCIE)|(1<> 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) & UART_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; - -#ifdef UART_TEST -#ifndef UART1_BIT_U2X -#warning "UART1_BIT_U2X not defined" -#endif -#ifndef UART1_UBRRH -#warning "UART1_UBRRH not defined" -#endif -#ifndef UART1_CONTROLC -#warning "UART1_CONTROLC not defined" -#endif -#if defined(URSEL) || defined(URSEL1) -#ifndef UART1_BIT_URSEL -#warning "UART1_BIT_URSEL not defined" -#endif -#endif -#endif - - /* Set baud rate */ - if ( baudrate & 0x8000 ) - { - #if UART1_BIT_U2X - UART1_STATUS = (1<>8)&0x80) ; - UART1_UBRRL = (unsigned char) baudrate; - - /* Enable USART receiver and transmitter and receive complete interrupt */ - UART1_CONTROL = _BV(UART1_BIT_RXCIE)|(1< http://tinyurl.com/peterfleury +File: $Id: uart.c,v 1.15.2.4 2015/09/05 18:33:32 peter Exp $ +Software: AVR-GCC 4.x +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 UART_RX_BUFFER_SIZE and UART_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) 2015 Peter Fleury, GNU General Public License Version 3 + + 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 +#include +#include +#include "uart.h" + +/* + * constants and macros + */ + +/* size of RX/TX buffers */ +#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1) +#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1) + +#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) +#error RX buffer size is not a power of 2 +#endif +#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) +#error TX buffer size is not a power of 2 +#endif + + +#if defined(__AVR_AT90S2313__) || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ + defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ + defined(__AVR_ATmega103__) + /* old AVR classic or ATmega103 with one 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 + #define UART0_UBRRL UBRR + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN +#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) + /* old AVR classic with one 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 + #define UART0_UBRRL UBRR + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN +#elif defined(__AVR_AT90PWM216__) || defined(__AVR_AT90PWM316__) + /* AT90PWN216/316 with one 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_CONTROLC UCSRC + #define UART0_DATA UDR + #define UART0_UDRIE UDRIE + #define UART0_UBRRL UBRRL + #define UART0_UBRRH UBRRH + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN + #define UART0_BIT_UCSZ0 UCSZ0 + #define UART0_BIT_UCSZ1 UCSZ1 +#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || \ + defined(__AVR_ATmega16__) || defined(__AVR_ATmega16A__) || \ + defined(__AVR_ATmega32__) || defined(__AVR_ATmega32A__) || \ + defined(__AVR_ATmega323__) + /* ATmega with one 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_CONTROLC UCSRC + #define UART0_DATA UDR + #define UART0_UDRIE UDRIE + #define UART0_UBRRL UBRRL + #define UART0_UBRRH UBRRH + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN + #define UART0_BIT_UCSZ0 UCSZ0 + #define UART0_BIT_UCSZ1 UCSZ1 + #define UART0_BIT_URSEL URSEL +#elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) + #define UART0_RECEIVE_INTERRUPT USART_RX_vect + #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect + #define UART0_STATUS UCSRA + #define UART0_CONTROL UCSRB + #define UART0_CONTROLC UCSRC + #define UART0_DATA UDR + #define UART0_UDRIE UDRIE + #define UART0_UBRRL UBRRL + #define UART0_UBRRH UBRRH + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN + #define UART0_BIT_UCSZ0 UCSZ0 + #define UART0_BIT_UCSZ1 UCSZ1 + #define UART0_BIT_URSEL URSEL +#elif defined(__AVR_ATmega163__) + /* ATmega163 with one 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 + #define UART0_UBRRL UBRR + #define UART0_UBRRH UBRRHI + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN +#elif defined(__AVR_ATmega162__) + /* ATmega with two USART */ + #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_CONTROLC UCSR0C + #define UART0_DATA UDR0 + #define UART0_UDRIE UDRIE0 + #define UART0_UBRRL UBRR0L + #define UART0_UBRRH UBRR0H + #define UART0_BIT_URSEL URSEL0 + #define UART0_BIT_U2X U2X0 + #define UART0_BIT_RXCIE RXCIE0 + #define UART0_BIT_RXEN RXEN0 + #define UART0_BIT_TXEN TXEN0 + #define UART0_BIT_UCSZ0 UCSZ00 + #define UART0_BIT_UCSZ1 UCSZ01 + #define UART1_STATUS UCSR1A + #define UART1_CONTROL UCSR1B + #define UART1_CONTROLC UCSR1C + #define UART1_DATA UDR1 + #define UART1_UDRIE UDRIE1 + #define UART1_UBRRL UBRR1L + #define UART1_UBRRH UBRR1H + #define UART1_BIT_URSEL URSEL1 + #define UART1_BIT_U2X U2X1 + #define UART1_BIT_RXCIE RXCIE1 + #define UART1_BIT_RXEN RXEN1 + #define UART1_BIT_TXEN TXEN1 + #define UART1_BIT_UCSZ0 UCSZ10 + #define UART1_BIT_UCSZ1 UCSZ11 +#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 UART0_RECEIVE_INTERRUPT USART0_RX_vect + #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect + #define UART0_STATUS UCSRA + #define UART0_CONTROL UCSRB + #define UART0_CONTROLC UCSRC + #define UART0_DATA UDR + #define UART0_UDRIE UDRIE + #define UART0_UBRRL UBRRL + #define UART0_UBRRH UBRRH + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN + #define UART0_BIT_UCSZ0 UCSZ0 + #define UART0_BIT_UCSZ1 UCSZ1 +#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48PB__) || \ + defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88PB__) || \ + defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__)|| defined(__AVR_ATmega168P__)|| defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || \ + defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \ + defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__) + /* ATmega with one USART */ + #define UART0_RECEIVE_INTERRUPT USART_RX_vect + #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect + #define UART0_STATUS UCSR0A + #define UART0_CONTROL UCSR0B + #define UART0_CONTROLC UCSR0C + #define UART0_DATA UDR0 + #define UART0_UDRIE UDRIE0 + #define UART0_UBRRL UBRR0L + #define UART0_UBRRH UBRR0H + #define UART0_BIT_U2X U2X0 + #define UART0_BIT_RXCIE RXCIE0 + #define UART0_BIT_RXEN RXEN0 + #define UART0_BIT_TXEN TXEN0 + #define UART0_BIT_UCSZ0 UCSZ00 + #define UART0_BIT_UCSZ1 UCSZ01 +#elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__) + /* ATtiny with one 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_CONTROLC UCSRC + #define UART0_DATA UDR + #define UART0_UDRIE UDRIE + #define UART0_UBRRL UBRRL + #define UART0_UBRRH UBRRH + #define UART0_BIT_U2X U2X + #define UART0_BIT_RXCIE RXCIE + #define UART0_BIT_RXEN RXEN + #define UART0_BIT_TXEN TXEN + #define UART0_BIT_UCSZ0 UCSZ0 + #define UART0_BIT_UCSZ1 UCSZ1 +#elif defined(__AVR_ATmega329__) || defined(__AVR_ATmega649__) || defined(__AVR_ATmega3290__) || defined(__AVR_ATmega6490__) ||\ + defined(__AVR_ATmega169A__) || defined(__AVR_ATmega169PA__) || \ + defined(__AVR_ATmega329A__) || defined(__AVR_ATmega329PA__) || defined(__AVR_ATmega3290A__) || defined(__AVR_ATmega3290PA__) || \ + defined(__AVR_ATmega649A__) || defined(__AVR_ATmega649P__) || defined(__AVR_ATmega6490A__) || defined(__AVR_ATmega6490P__) || \ + defined(__AVR_ATmega165__) || defined(__AVR_ATmega325__) || defined(__AVR_ATmega645__) || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega6450__) || \ + defined(__AVR_ATmega165A__) || defined(__AVR_ATmega165PA__) || \ + defined(__AVR_ATmega325A__) || defined(__AVR_ATmega325PA__) || defined(__AVR_ATmega3250A__) || defined(__AVR_ATmega3250PA__) ||\ + defined(__AVR_ATmega645A__) || defined(__AVR_ATmega645PA__) || defined(__AVR_ATmega6450A__) || defined(__AVR_ATmega6450PA__) || \ + defined(__AVR_ATmega644__) + /* ATmega with one USART */ + #define UART0_RECEIVE_INTERRUPT USART0_RX_vect + #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect + #define UART0_STATUS UCSR0A + #define UART0_CONTROL UCSR0B + #define UART0_CONTROLC UCSR0C + #define UART0_DATA UDR0 + #define UART0_UDRIE UDRIE0 + #define UART0_UBRRL UBRR0L + #define UART0_UBRRH UBRR0H + #define UART0_BIT_U2X U2X0 + #define UART0_BIT_RXCIE RXCIE0 + #define UART0_BIT_RXEN RXEN0 + #define UART0_BIT_TXEN TXEN0 + #define UART0_BIT_UCSZ0 UCSZ00 + #define UART0_BIT_UCSZ1 UCSZ01 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega128A__) ||\ + defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || \ + defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || \ + defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164PA__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) || \ + defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) ||\ + defined(__AVR_ATtiny1634__) + /* ATmega with two USART */ + #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_CONTROLC UCSR0C + #define UART0_DATA UDR0 + #define UART0_UDRIE UDRIE0 + #define UART0_UBRRL UBRR0L + #define UART0_UBRRH UBRR0H + #define UART0_BIT_U2X U2X0 + #define UART0_BIT_RXCIE RXCIE0 + #define UART0_BIT_RXEN RXEN0 + #define UART0_BIT_TXEN TXEN0 + #define UART0_BIT_UCSZ0 UCSZ00 + #define UART0_BIT_UCSZ1 UCSZ01 + #define UART1_STATUS UCSR1A + #define UART1_CONTROL UCSR1B + #define UART1_CONTROLC UCSR1C + #define UART1_DATA UDR1 + #define UART1_UDRIE UDRIE1 + #define UART1_UBRRL UBRR1L + #define UART1_UBRRH UBRR1H + #define UART1_BIT_U2X U2X1 + #define UART1_BIT_RXCIE RXCIE1 + #define UART1_BIT_RXEN RXEN1 + #define UART1_BIT_TXEN TXEN1 + #define UART1_BIT_UCSZ0 UCSZ10 + #define UART1_BIT_UCSZ1 UCSZ11 +#elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || \ + defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \ + defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ + defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__) + #define UART0_RECEIVE_INTERRUPT USART1_RX_vect + #define UART0_TRANSMIT_INTERRUPT USART1_UDRE_vect + #define UART0_STATUS UCSR1A + #define UART0_CONTROL UCSR1B + #define UART0_CONTROLC UCSR1C + #define UART0_DATA UDR1 + #define UART0_UDRIE UDRIE1 + #define UART0_UBRRL UBRR1L + #define UART0_UBRRH UBRR1H + #define UART0_BIT_U2X U2X1 + #define UART0_BIT_RXCIE RXCIE1 + #define UART0_BIT_RXEN RXEN1 + #define UART0_BIT_TXEN TXEN1 + #define UART0_BIT_UCSZ0 UCSZ10 + #define UART0_BIT_UCSZ1 UCSZ11 +#else + #error "no UART definition for MCU available" +#endif + + + +/* + * module global variables + */ +static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; +static volatile unsigned char UART_RxBuf[UART_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[UART_TX_BUFFER_SIZE]; +static volatile unsigned char UART1_RxBuf[UART_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; + + /* get FEn (Frame Error) DORn (Data OverRun) UPEn (USART Parity Error) bits */ +#if defined(FE) && defined(DOR) && defined(UPE) + lastRxError = usr & (_BV(FE)|_BV(DOR)|_BV(UPE) ); +#elif defined(FE0) && defined(DOR0) && defined(UPE0) + lastRxError = usr & (_BV(FE0)|_BV(DOR0)|_BV(UPE0) ); +#elif defined(FE1) && defined(DOR1) && defined(UPE1) + lastRxError = usr & (_BV(FE1)|_BV(DOR1)|_BV(UPE1) ); +#elif defined(FE) && defined(DOR) + lastRxError = usr & (_BV(FE)|_BV(DOR) ); +#endif + + /* calculate buffer index */ + tmphead = ( UART_RxHead + 1) & UART_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) & UART_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; + +#ifdef UART_TEST +#ifndef UART0_BIT_U2X +#warning "UART0_BIT_U2X not defined" +#endif +#ifndef UART0_UBRRH +#warning "UART0_UBRRH not defined" +#endif +#ifndef UART0_CONTROLC +#warning "UART0_CONTROLC not defined" +#endif +#if defined(URSEL) || defined(URSEL0) +#ifndef UART0_BIT_URSEL +#warning "UART0_BIT_URSEL not defined" +#endif +#endif +#endif + + // Set baud rate + if ( baudrate & 0x8000 ) + { + #if UART0_BIT_U2X + UART0_STATUS = (1<>8)&0x80) ; + #endif + UART0_UBRRL = (unsigned char) (baudrate&0x00FF); + + // Enable USART receiver and transmitter and receive complete interrupt + UART0_CONTROL = _BV(UART0_BIT_RXCIE)|(1<> 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) & UART_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; + +#ifdef UART_TEST +#ifndef UART1_BIT_U2X +#warning "UART1_BIT_U2X not defined" +#endif +#ifndef UART1_UBRRH +#warning "UART1_UBRRH not defined" +#endif +#ifndef UART1_CONTROLC +#warning "UART1_CONTROLC not defined" +#endif +#if defined(URSEL) || defined(URSEL1) +#ifndef UART1_BIT_URSEL +#warning "UART1_BIT_URSEL not defined" +#endif +#endif +#endif + + /* Set baud rate */ + if ( baudrate & 0x8000 ) + { + #if UART1_BIT_U2X + UART1_STATUS = (1<>8)&0x80) ; + UART1_UBRRL = (unsigned char) baudrate; + + /* Enable USART receiver and transmitter and receive complete interrupt */ + UART1_CONTROL = _BV(UART1_BIT_RXCIE)|(1< http://tinyurl.com/peterfleury -File: $Id: uart.h,v 1.13 2015/01/11 13:53:25 peter Exp $ -Software: AVR-GCC 4.x, AVR Libc 1.4 or higher -Hardware: any AVR with built-in UART/USART -Usage: see Doxygen manual - -LICENSE: - Copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 - - 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 3 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. - -************************************************************************/ - -/** - * @file - * @defgroup pfleury_uart UART Library - * @code #include @endcode - * - * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers. - * - * This library can be used to transmit and receive data through the built in UART. - * - * 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 UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define - * the size of the circular buffers in bytes. Note that these constants must be a power of 2. - * You may need to adapt these constants to your target and your application by adding - * CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_TX_BUFFER_SIZE=nn to your Makefile. - * - * @note Based on Atmel Application Note AVR306 - * @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury - * @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 - */ - - -#include - -#if (__GNUC__ * 100 + __GNUC_MINOR__) < 405 -#error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !" -#endif - - -/**@{*/ - - -/* -** constants and macros -*/ - - -/** @brief UART Baudrate Expression - * @param xtalCpu system clock in Mhz, e.g. 4000000UL for 4Mhz - * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600 - */ -#define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL) - -/** @brief UART Baudrate Expression for ATmega double speed mode - * @param xtalCpu system clock in Mhz, e.g. 4000000UL for 4Mhz - * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600 - */ -#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000) - -/** @brief Size of the circular receive buffer, must be power of 2 - * - * You may need to adapt this constant to your target and your application by adding - * CDEFS += -DUART_RX_BUFFER_SIZE=nn to your Makefile. - */ -#ifndef UART_RX_BUFFER_SIZE -#define UART_RX_BUFFER_SIZE 32 -#endif - -/** @brief Size of the circular transmit buffer, must be power of 2 - * - * You may need to adapt this constant to your target and your application by adding - * CDEFS += -DUART_TX_BUFFER_SIZE=nn to your Makefile. - */ -#ifndef UART_TX_BUFFER_SIZE -#define UART_TX_BUFFER_SIZE 32 -#endif - -/* test if the size of the circular buffers fits into SRAM */ -#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) ) -#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM" -#endif - -/* -** high byte error return code of uart_getc() -*/ -#define UART_FRAME_ERROR 0x1000 /**< @brief Framing Error by UART */ -#define UART_OVERRUN_ERROR 0x0800 /**< @brief Overrun condition by UART */ -#define UART_PARITY_ERROR 0x0400 /**< @brief Parity Error by UART */ -#define UART_BUFFER_OVERFLOW 0x0200 /**< @brief receive ringbuffer overflow */ -#define UART_NO_DATA 0x0100 /**< @brief no receive data available */ - - -/* -** function prototypes -*/ - -/** - @brief Initialize UART and set baudrate - @param baudrate Specify baudrate using macro UART_BAUD_SELECT() - @return none -*/ -extern void uart_init(unsigned int baudrate); - - -/** - * @brief Get received byte from ringbuffer - * - * Returns in the lower byte the received character and in the - * higher byte the last receive error. - * UART_NO_DATA is returned when no data is available. - * - * @return lower byte: received byte from ringbuffer - * @return higher byte: last receive status - * - \b 0 successfully received data from UART - * - \b UART_NO_DATA - *
no receive data available - * - \b UART_BUFFER_OVERFLOW - *
Receive ringbuffer overflow. - * We are not reading the receive buffer fast enough, - * one or more received character have been dropped - * - \b UART_OVERRUN_ERROR - *
Overrun condition by UART. - * A character already present in the UART UDR register was - * not read by the interrupt handler before the next character arrived, - * one or more received characters have been dropped. - * - \b UART_FRAME_ERROR - *
Framing Error by UART - */ -extern unsigned int uart_getc(void); - - -/** - * @brief Put byte to ringbuffer for transmitting via UART - * @param data byte to be transmitted - * @return none - */ -extern void uart_putc(unsigned char data); - - -/** - * @brief Put string to ringbuffer for transmitting via UART - * - * The string is buffered by the uart library in a circular buffer - * and one character at a time is transmitted to the UART using interrupts. - * Blocks if it can not write the whole string into the circular buffer. - * - * @param s string to be transmitted - * @return none - */ -extern void uart_puts(const char *s ); - - -/** - * @brief Put string from program memory to ringbuffer for transmitting via UART. - * - * The string is buffered by the uart library in a circular buffer - * and one character at a time is transmitted to the UART using interrupts. - * Blocks if it can not write the whole string into the circular buffer. - * - * @param s program memory string to be transmitted - * @return none - * @see uart_puts_P - */ -extern void uart_puts_p(const char *s ); - -/** - * @brief Macro to automatically put a string constant into program memory - */ -#define uart_puts_P(__s) uart_puts_p(PSTR(__s)) - - - -/** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */ -extern void uart1_init(unsigned int baudrate); -/** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */ -extern unsigned int uart1_getc(void); -/** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */ -extern void uart1_putc(unsigned char data); -/** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */ -extern void uart1_puts(const char *s ); -/** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */ -extern void uart1_puts_p(const char *s ); -/** @brief Macro to automatically put a string constant into program memory */ -#define uart1_puts_P(__s) uart1_puts_p(PSTR(__s)) - -/**@}*/ - - -#endif // UART_H - +#ifndef UART_H +#define UART_H +/************************************************************************ +Title: Interrupt UART library with receive/transmit circular buffers +Author: Peter Fleury http://tinyurl.com/peterfleury +File: $Id: uart.h,v 1.13 2015/01/11 13:53:25 peter Exp $ +Software: AVR-GCC 4.x, AVR Libc 1.4 or higher +Hardware: any AVR with built-in UART/USART +Usage: see Doxygen manual + +LICENSE: + Copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 + + 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 3 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. + +************************************************************************/ + +/** + * @file + * @defgroup pfleury_uart UART Library + * @code #include @endcode + * + * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers. + * + * This library can be used to transmit and receive data through the built in UART. + * + * 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 UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define + * the size of the circular buffers in bytes. Note that these constants must be a power of 2. + * You may need to adapt these constants to your target and your application by adding + * CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_TX_BUFFER_SIZE=nn to your Makefile. + * + * @note Based on Atmel Application Note AVR306 + * @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury + * @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 + */ + + +#include + +#if (__GNUC__ * 100 + __GNUC_MINOR__) < 405 +#error "This library requires AVR-GCC 4.5 or later, update to newer AVR-GCC compiler !" +#endif + + +/**@{*/ + + +/* +** constants and macros +*/ + + +/** @brief UART Baudrate Expression + * @param xtalCpu system clock in Mhz, e.g. 4000000UL for 4Mhz + * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600 + */ +#define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL) + +/** @brief UART Baudrate Expression for ATmega double speed mode + * @param xtalCpu system clock in Mhz, e.g. 4000000UL for 4Mhz + * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600 + */ +#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000) + +/** @brief Size of the circular receive buffer, must be power of 2 + * + * You may need to adapt this constant to your target and your application by adding + * CDEFS += -DUART_RX_BUFFER_SIZE=nn to your Makefile. + */ +#ifndef UART_RX_BUFFER_SIZE +#define UART_RX_BUFFER_SIZE 32 +#endif + +/** @brief Size of the circular transmit buffer, must be power of 2 + * + * You may need to adapt this constant to your target and your application by adding + * CDEFS += -DUART_TX_BUFFER_SIZE=nn to your Makefile. + */ +#ifndef UART_TX_BUFFER_SIZE +#define UART_TX_BUFFER_SIZE 32 +#endif + +/* test if the size of the circular buffers fits into SRAM */ +#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) ) +#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM" +#endif + +/* +** high byte error return code of uart_getc() +*/ +#define UART_FRAME_ERROR 0x1000 /**< @brief Framing Error by UART */ +#define UART_OVERRUN_ERROR 0x0800 /**< @brief Overrun condition by UART */ +#define UART_PARITY_ERROR 0x0400 /**< @brief Parity Error by UART */ +#define UART_BUFFER_OVERFLOW 0x0200 /**< @brief receive ringbuffer overflow */ +#define UART_NO_DATA 0x0100 /**< @brief no receive data available */ + + +/* +** function prototypes +*/ + +/** + @brief Initialize UART and set baudrate + @param baudrate Specify baudrate using macro UART_BAUD_SELECT() + @return none +*/ +extern void uart_init(unsigned int baudrate); + + +/** + * @brief Get received byte from ringbuffer + * + * Returns in the lower byte the received character and in the + * higher byte the last receive error. + * UART_NO_DATA is returned when no data is available. + * + * @return lower byte: received byte from ringbuffer + * @return higher byte: last receive status + * - \b 0 successfully received data from UART + * - \b UART_NO_DATA + *
no receive data available + * - \b UART_BUFFER_OVERFLOW + *
Receive ringbuffer overflow. + * We are not reading the receive buffer fast enough, + * one or more received character have been dropped + * - \b UART_OVERRUN_ERROR + *
Overrun condition by UART. + * A character already present in the UART UDR register was + * not read by the interrupt handler before the next character arrived, + * one or more received characters have been dropped. + * - \b UART_FRAME_ERROR + *
Framing Error by UART + */ +extern unsigned int uart_getc(void); + + +/** + * @brief Put byte to ringbuffer for transmitting via UART + * @param data byte to be transmitted + * @return none + */ +extern void uart_putc(unsigned char data); + + +/** + * @brief Put string to ringbuffer for transmitting via UART + * + * The string is buffered by the uart library in a circular buffer + * and one character at a time is transmitted to the UART using interrupts. + * Blocks if it can not write the whole string into the circular buffer. + * + * @param s string to be transmitted + * @return none + */ +extern void uart_puts(const char *s ); + + +/** + * @brief Put string from program memory to ringbuffer for transmitting via UART. + * + * The string is buffered by the uart library in a circular buffer + * and one character at a time is transmitted to the UART using interrupts. + * Blocks if it can not write the whole string into the circular buffer. + * + * @param s program memory string to be transmitted + * @return none + * @see uart_puts_P + */ +extern void uart_puts_p(const char *s ); + +/** + * @brief Macro to automatically put a string constant into program memory + */ +#define uart_puts_P(__s) uart_puts_p(PSTR(__s)) + + + +/** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */ +extern void uart1_init(unsigned int baudrate); +/** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */ +extern unsigned int uart1_getc(void); +/** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */ +extern void uart1_putc(unsigned char data); +/** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */ +extern void uart1_puts(const char *s ); +/** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */ +extern void uart1_puts_p(const char *s ); +/** @brief Macro to automatically put a string constant into program memory */ +#define uart1_puts_P(__s) uart1_puts_p(PSTR(__s)) + +/**@}*/ + + +#endif // UART_H +