#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 /* 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 /* * 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; 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<