diff --git a/usart.cpp b/usart.cpp deleted file mode 100644 index 016ead4..0000000 --- a/usart.cpp +++ /dev/null @@ -1,642 +0,0 @@ -#include "usart.h" - -////////////////////////////////////////////////////////////////////////// -USART0 USART0::sm_cInstance; - -////////////////////////////////////////////////////////////////////////// -USART0::USART0() -{ - #ifdef USART_SHAREDIO - m_vui8pUCSRA = &UCSRA; - m_vui8pUCSRB = &UCSRB; - m_vui8pUCSRC = &UCSRC; - m_vui8pUBRRH = &UBRRH; - m_vui8pUBRRL = &UBRRL; - m_vui8pUDR = &UDR; - #endif - - #ifndef USART_SHAREDIO - m_vui8pUCSRA = &UCSR0A; - m_vui8pUCSRB = &UCSR0B; - m_vui8pUCSRC = &UCSR0C; - m_vui8pUBRRH = &UBRR0H; - m_vui8pUBRRL = &UBRR0L; - m_vui8pUDR = &UDR0; - #endif - - m_vsizeRXBufferHead = 0; - m_vsizeRXBufferTail = 0; - m_vsizeTXBufferHead = 0; - m_vsizeTXBufferTail = 0; -} - -////////////////////////////////////////////////////////////////////////// -uint8_t USART0::readUCSRC() -{ - uint8_t ui8UCSRC; - -#ifdef USART_SHAREDIO - ui8UCSRC = UBRRH; - ui8UCSRC = UCSRC; -#else - ui8UCSRC = *m_vui8pUCSRC; -#endif - - return ui8UCSRC; -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setUCSRC( uint8_t ui8UCSRC ) -{ -#ifdef USART_SHAREDIO - *m_vui8pUCSRC = ( 1 << URSEL ) | ui8UCSRC; -#else - *m_vui8pUCSRC = ui8UCSRC; -#endif -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setRXState( bool bEnable ) -{ - if( bEnable ) - { - *m_vui8pUCSRB |= ( 1 << RXEN_D ); - } - else - { - *m_vui8pUCSRB &= ~( 1 << RXEN_D ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setTXState( bool bEnable ) -{ - if( bEnable ) - { - *m_vui8pUCSRB |= ( 1 << TXEN_D ); - } - else - { - *m_vui8pUCSRB &= ~( 1 << TXEN_D ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setRXInterrupt( bool bEnable ) -{ - if( bEnable ) - { - *m_vui8pUCSRB |= ( 1 << RXCIE_D ); - } - else - { - *m_vui8pUCSRB &= ~( 1 << RXCIE_D ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setUDREInterrupt( bool bEnable ) -{ - if( bEnable ) - { - *m_vui8pUCSRB |= ( 1 << UDRIE_D ); - } - else - { - *m_vui8pUCSRB &= ~( 1 << UDRIE_D ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setBaudRate( uint32_t ui32BaudRate ) -{ - uint16_t ui16UBRR = ( ( F_CPU / ( 16 * ui32BaudRate ) ) - 1 ); - *m_vui8pUBRRH = static_cast( ui16UBRR >> 8 ); - *m_vui8pUBRRL = static_cast( ui16UBRR ); -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setDataBits( uint8_t ui8DataBits ) -{ - uint8_t ui8UCSRC = readUCSRC(); - - if( ui8DataBits < 5 ) - { - ui8DataBits = 5; - } - else if( ui8DataBits > 9 ) - { - ui8DataBits = 9; - } - - if( ui8DataBits <= 8 ) - { - bool bZeroBit = ( ui8DataBits - 5 ) & 1; - bool bOneBit = ( ( ui8DataBits - 5 ) >> 1 ) & 1; - - if( bZeroBit ) - { - ui8UCSRC |= ( 1 << UCSZ0_D ); - } - else - { - ui8UCSRC &= ~( 1 << UCSZ0_D ); - } - - if( bOneBit ) - { - ui8UCSRC |= ( 1 << UCSZ1_D ); - } - else - { - ui8UCSRC &= ~( 1 << UCSZ1_D ); - } - - *m_vui8pUCSRB &= ~( 1 << UCSZ2_D ); - } - else - { - ui8UCSRC |= ( 1 << UCSZ1_D ) | ( 1 << UCSZ0_D ); - *m_vui8pUCSRB |= ( 1 << UCSZ2_D ); - } - - setUCSRC( ui8UCSRC ); -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setParity( Parity enmParity ) -{ - uint8_t ui8UCSRC = readUCSRC(); - - if( enmParity == Parity::DISABLED ) - { - ui8UCSRC &= ~( ( 1 << UPM1_D ) | ( 1 << UPM0_D ) ); - } - else if( enmParity == Parity::ODD ) - { - ui8UCSRC |= ( ( 1 << UPM1_D ) | ( 1 << UPM0_D ) ); - } - else if( enmParity == Parity::EVEN ) - { - ui8UCSRC &= ~( ( 1 << UPM0_D ) ); - ui8UCSRC |= ( ( 1 << UPM1_D ) ); - } - - setUCSRC( ui8UCSRC ); -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setStopBits( StopBit enmStopBits ) -{ - uint8_t ui8UCSRC = readUCSRC(); - - if( enmStopBits == StopBit::ONE ) - { - ui8UCSRC &= ~( 1 << USBS_D ); - } - else if( enmStopBits == StopBit::TWO ) - { - ui8UCSRC |= ( 1 << USBS_D ); - } - - setUCSRC( ui8UCSRC ); -} - -////////////////////////////////////////////////////////////////////////// -void USART0::setMode( Mode enmMode ) -{ - uint8_t ui8UCSRC = readUCSRC(); - -#ifdef USART_SPI - if( enmMode == Mode::ASYNCHRONOUS ) - { - ui8UCSRC &= ~( ( 1 << UMSEL1_D ) | ( 1 << UMSEL0_D ) ); - } - else if( enmMode == Mode::SYNCHRONOUS ) - { - ui8UCSRC &= ~( 1 << UMSEL1_D ); - ui8UCSRC |= ( 1 << UMSEL0_D ); - } - else if( enmMode == Mode::MASTERSPI ) - { - ui8UCSRC |= ( ( 1 << UMSEL1_D ) | ( 1 << UMSEL0_D ) ); - } -#else - if( enmMode == Mode::ASYNCHRONOUS ) - { - ui8UCSRC &= ~( 1 << UMSEL_D ); - } - else if( enmMode == Mode::SYNCHRONOUS ) - { - ui8UCSRC |= ( 1 << UMSEL_D ); - } -#endif - - setUCSRC( ui8UCSRC ); -} - -////////////////////////////////////////////////////////////////////////// -uint32_t USART0::getBaudRate() -{ - uint16_t ui16UBRR; - ui16UBRR = static_cast( *m_vui8pUBRRH ) << 8; - ui16UBRR |= *m_vui8pUBRRL; - - return F_CPU / ( static_cast( 16 ) * ( ui16UBRR + 1 ) ); -} - -////////////////////////////////////////////////////////////////////////// -uint8_t USART0::getDataBits() -{ - if( *m_vui8pUCSRB & ( 1 << UCSZ2_D ) ) - { - return 9; - } - - uint8_t ui8UCSRC = readUCSRC(); - - bool bZeroBit = ui8UCSRC & ( 1 << UCSZ0_D ); - bool bOneBit = ui8UCSRC & ( 1 << UCSZ1_D ); - - return 5 + ( bOneBit << 1 | bZeroBit ); -} - -////////////////////////////////////////////////////////////////////////// -USART0::Parity USART0::getParity() -{ - uint8_t ui8UCSRC = readUCSRC(); - - bool bZeroBit = ui8UCSRC & ( 1 << UPM0_D ); - bool bOneBit = ui8UCSRC & ( 1 << UPM1_D ); - - if( bOneBit && !bZeroBit ) - { - return Parity::EVEN; - } - - if( bOneBit && bZeroBit ) - { - return Parity::ODD; - } - - return Parity::DISABLED; -} - -////////////////////////////////////////////////////////////////////////// -USART0::StopBit USART0::getStopBits() -{ - uint8_t ui8UCSRC = readUCSRC(); - - if( ui8UCSRC & ( 1 << USBS_D ) ) - { - return StopBit::TWO; - } - - return StopBit::ONE; -} - -////////////////////////////////////////////////////////////////////////// -USART0::~USART0() -{ - flushTransmit(); - - setBaudRate( 0 ); - - setRXState( false ); - setTXState( false ); - - setRXInterrupt( false ); - setUDREInterrupt( false ); -} - -////////////////////////////////////////////////////////////////////////// -USART0& USART0::inst() -{ - return sm_cInstance; -} - -////////////////////////////////////////////////////////////////////////// -void USART0::init( uint32_t ui32BaudRate /* = 9600 */, uint8_t ui8DataBits /* = 8 */, Parity enmParity /* = Parity::DISABLED */, StopBit enmStopBits /* = StopBit::ONE */, Mode enmMode /* = Mode::ASYNCHRONOUS */ ) -{ - setBaudRate( ui32BaudRate ); - setDataBits( ui8DataBits ); - setParity( enmParity ); - setStopBits( enmStopBits ); - setMode( enmMode ); - - setRXState( true ); - setTXState( true ); - - setRXInterrupt( true ); - setUDREInterrupt( false ); -} - -////////////////////////////////////////////////////////////////////////// -bool USART0::receiveByte( uint8_t &ui8Data ) -{ - if( m_vsizeRXBufferHead == m_vsizeRXBufferTail && !( SREG & ( 1 << SREG_I ) ) ) - { - while( !( *m_vui8pUCSRA & ( 1 << RXC_D ) ) ); - ui8Data = *m_vui8pUDR; - return true; - } - else if( m_vsizeRXBufferHead == m_vsizeRXBufferTail ) - { - return false; - } - - ui8Data = m_vui8aRXBuffer[m_vsizeRXBufferTail]; - m_vsizeRXBufferTail = ( m_vsizeRXBufferTail + 1 ) % sm_sizeRXBUFFER_SIZE; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool USART0::receiveByte( uint8_t &ui8Data, uint16_t ui16TimeoutMS ) -{ - uint16_t ui16DelayCounter = 0; - - while( !receiveByte( ui8Data ) ) - { - _delay_ms( 1 ); - - if( ui16DelayCounter++ > ui16TimeoutMS ) - { - return false; - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -uint8_t USART0::receiveByteBlocked() -{ - uint8_t ui8Received; - while( !receiveByte( ui8Received ) ); - return ui8Received; -} - -////////////////////////////////////////////////////////////////////////// -uint8_t USART0::receivePeek() -{ - uint8_t ui8Received; - - if( !( SREG & ( 1 << SREG_I ) && m_vsizeRXBufferHead == m_vsizeRXBufferTail ) ) - { - while( !( *m_vui8pUCSRA & ( 1 << RXC_D ) ) ); - ui8Received = *m_vui8pUDR; - - size_t sizeIndex = ( m_vsizeRXBufferHead + 1 ) % sm_sizeRXBUFFER_SIZE; - - if( sizeIndex != m_vsizeRXBufferTail ) - { - m_vui8aRXBuffer[m_vsizeRXBufferHead] = ui8Received; - m_vsizeRXBufferHead = sizeIndex; - } - - return ui8Received; - } - - while( m_vsizeRXBufferHead == m_vsizeRXBufferTail ); - return m_vui8aRXBuffer[m_vsizeRXBufferTail]; -} - -////////////////////////////////////////////////////////////////////////// -bool USART0::receiveLine( char *szBuffer, size_t sizeBufferLength, const char *szLineTerminator /* = "\r\n" */ ) -{ - size_t sizeReceived = 0; - - while( sizeReceived < sizeBufferLength - 1 ) - { - uint8_t ui8ReceiveByte; - - while( !receiveByte( ui8ReceiveByte ) ); - szBuffer[sizeReceived++] = ui8ReceiveByte; - szBuffer[sizeReceived] = '\0'; - - if( strstr( szBuffer, szLineTerminator ) ) - { - szBuffer[sizeReceived - strlen( szLineTerminator )] = '\0'; - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool USART0::receiveLine( char *szBuffer, size_t sizeBufferLength, uint16_t ui16TimeoutMS, const char *szLineTerminator /* = "\r\n" */ ) -{ - size_t sizeReceived = 0; - - while( sizeReceived < sizeBufferLength - 1 ) - { - uint8_t ui8ReceiveByte; - uint16_t ui16DelayCounter = 0; - - while( !receiveByte( ui8ReceiveByte ) ) - { - _delay_ms( 1 ); - - if( ui16DelayCounter++ > ui16TimeoutMS ) - { - szBuffer[sizeReceived] = '\0'; - return false; - } - } - - szBuffer[sizeReceived++] = ui8ReceiveByte; - szBuffer[sizeReceived] = '\0'; - - if( strstr( szBuffer, szLineTerminator ) ) - { - szBuffer[sizeReceived - strlen( szLineTerminator )] = '\0'; - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void USART0::flushReceive() -{ - uint32_t ui32BaudRate = getBaudRate(); - uint8_t ui8BitsPerSymbol = 1; - - ui8BitsPerSymbol += getDataBits(); - - if( getParity() != Parity::DISABLED ) - { - ui8BitsPerSymbol += 1; - } - - if( getStopBits() == StopBit::ONE ) - { - ui8BitsPerSymbol += 1; - } - else - { - ui8BitsPerSymbol += 2; - } - - uint16_t ui16BaudDelayMS = static_cast( ( 1000.0 * ui8BitsPerSymbol ) / ui32BaudRate ) + 1; - - uint8_t ui8Received; - - if( !( SREG & ( 1 << SREG_I ) ) ) - { - while( true ) - { - for( uint16_t i = 0; i < ui16BaudDelayMS; ++i ) - { - _delay_ms( 1 ); - } - - if( m_vsizeRXBufferHead != m_vsizeRXBufferTail ) - { - receiveByte( ui8Received ); - continue; - } - - if( ( *m_vui8pUCSRA & ( 1 << RXC_D ) ) ) - { - ui8Received = *m_vui8pUDR; - continue; - } - - break; - } - } - else - { - while( receiveByte( ui8Received, ui16BaudDelayMS ) ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::transmitByte( uint8_t ui8Data ) -{ - if( m_vsizeTXBufferHead == m_vsizeTXBufferTail && *m_vui8pUCSRA & ( 1 << UDRE_D ) ) - { - *m_vui8pUDR = ui8Data; - return; - } - - size_t sizeIndex = ( m_vsizeTXBufferHead + 1 ) % sm_sizeTXBUFFER_SIZE; - - while( sizeIndex == m_vsizeTXBufferTail ) - { - if( !( SREG & ( 1 << SREG_I ) ) && *m_vui8pUCSRA & ( 1 << UDRE_D ) ) - { - transmitInterruptHandler(); - } - } - - m_vui8aTXBuffer[m_vsizeTXBufferHead] = ui8Data; - m_vsizeTXBufferHead = sizeIndex; - - if( !( SREG & ( 1 << SREG_I ) ) ) - { - while( !( *m_vui8pUCSRA & ( 1 << UDRE_D ) ) ); - transmitInterruptHandler(); - } - else - { - setUDREInterrupt( true ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::transmitString( const char *szString ) -{ - while( *szString ) - { - transmitByte( *szString++ ); - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::flushTransmit() -{ - while( m_vsizeTXBufferHead != m_vsizeTXBufferTail && !( *m_vui8pUCSRA & ( 1 << UDRE_D ) ) ); -} - -////////////////////////////////////////////////////////////////////////// -void USART0::receiveInterruptHandler() -{ - uint8_t ui8ReceivedByte = *m_vui8pUDR; - size_t sizeIndex = ( m_vsizeRXBufferHead + 1 ) % sm_sizeRXBUFFER_SIZE; - - if( sizeIndex != m_vsizeRXBufferTail ) - { - m_vui8aRXBuffer[m_vsizeRXBufferHead] = ui8ReceivedByte; - m_vsizeRXBufferHead = sizeIndex; - } -} - -////////////////////////////////////////////////////////////////////////// -void USART0::transmitInterruptHandler() -{ - uint8_t ui8TransmitByte = m_vui8aTXBuffer[m_vsizeTXBufferTail]; - m_vsizeTXBufferTail = ( m_vsizeTXBufferTail + 1 ) % sm_sizeTXBUFFER_SIZE; - - *m_vui8pUDR = ui8TransmitByte; - - if( m_vsizeTXBufferHead == m_vsizeTXBufferTail ) - { - setUDREInterrupt( false ); - } -} - -////////////////////////////////////////////////////////////////////////// -ISR( USART0_RX_vect_D ) -{ - USART0::inst().receiveInterruptHandler(); -} - -////////////////////////////////////////////////////////////////////////// -ISR( USART0_UDRE_vect_D ) -{ - USART0::inst().transmitInterruptHandler(); -} - -/************************************************************************/ -/************************************************************************/ - -#ifdef SECOND_USART - -////////////////////////////////////////////////////////////////////////// -USART1 USART1::sm_cInstance; - -////////////////////////////////////////////////////////////////////////// -USART1& USART1::inst() -{ - return sm_cInstance; -} - -////////////////////////////////////////////////////////////////////////// -USART1::USART1() -{ - m_vui8pUCSRA = &UCSR1A; - m_vui8pUCSRB = &UCSR1B; - m_vui8pUCSRC = &UCSR1C; - m_vui8pUBRRH = &UBRR1H; - m_vui8pUBRRL = &UBRR1L; - m_vui8pUDR = &UDR1; -} - -////////////////////////////////////////////////////////////////////////// -ISR( USART1_RX_vect_D ) -{ - USART1::inst().receiveInterruptHandler(); -} - -////////////////////////////////////////////////////////////////////////// -ISR( USART1_UDRE_vect_D ) -{ - USART1::inst().transmitInterruptHandler(); -} - -#endif \ No newline at end of file diff --git a/usart.h b/usart.h deleted file mode 100644 index 224f8cf..0000000 --- a/usart.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -* Copyright (c) by BlackMark 2015-2018 -* Date 12/04/2018 -* Version 3.4 -*/ - -#ifndef USART_H -#define USART_H - -#include -#include -#include -#include -#include "../clock.h" - -#if defined (__AVR_ATmega168A__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega644P__) -#define USART_SPI -#define USART0_RX_vect_D USART_RX_vect -#define USART0_UDRE_vect_D USART_UDRE_vect -#endif -#if defined (__AVR_ATmega32A__) || (__AVR_ATmega8__) || (__AVR_ATmega8A__) -#define USART_SHAREDIO -#define USART0_RX_vect_D USART_RXC_vect -#define USART0_UDRE_vect_D USART_UDRE_vect -#endif -#if defined (__AVR_ATmega1284P__) -#define USART_SPI -#define SECOND_USART -#define USART0_RX_vect_D USART0_RX_vect -#define USART1_RX_vect_D USART1_RX_vect -#define USART0_UDRE_vect_D USART0_UDRE_vect -#define USART1_UDRE_vect_D USART1_UDRE_vect -#endif - -#ifdef USART_SHAREDIO -#define RXEN_D RXEN -#define TXEN_D TXEN -#define RXCIE_D RXCIE -#define UDRIE_D UDRIE -#define UCSZ0_D UCSZ0 -#define UCSZ1_D UCSZ1 -#define UCSZ2_D UCSZ2 -#define UPM0_D UPM0 -#define UPM1_D UPM1 -#define USBS_D USBS -#define RXC_D RXC -#define UDRE_D UDRE -#else -#define RXEN_D RXEN0 -#define TXEN_D TXEN0 -#define RXCIE_D RXCIE0 -#define UDRIE_D UDRIE0 -#define UCSZ0_D UCSZ00 -#define UCSZ1_D UCSZ01 -#define UCSZ2_D UCSZ02 -#define UPM0_D UPM00 -#define UPM1_D UPM01 -#define USBS_D USBS0 -#define RXC_D RXC0 -#define UDRE_D UDRE0 -#endif - -#ifdef USART_SPI -#define UMSEL0_D UMSEL00 -#define UMSEL1_D UMSEL01 -#else -#define UMSEL_D UMSEL -#endif - -class USART0 -{ -public: - enum class Mode - { - ASYNCHRONOUS = 0, - SYNCHRONOUS = 1, -#ifdef USART_SPI - MASTERSPI = 2 -#endif - }; - - enum class Parity - { - DISABLED = 0, - ODD = 1, - EVEN = 2 - }; - - enum class StopBit - { - ONE = 1, - TWO = 2 - }; - - static constexpr size_t sm_sizeRXBUFFER_SIZE = 16; - static constexpr size_t sm_sizeTXBUFFER_SIZE = 16; - -protected: - volatile uint8_t *m_vui8pUCSRA; - volatile uint8_t *m_vui8pUCSRB; - volatile uint8_t *m_vui8pUCSRC; - volatile uint8_t *m_vui8pUBRRH; - volatile uint8_t *m_vui8pUBRRL; - volatile uint8_t *m_vui8pUDR; - - volatile size_t m_vsizeRXBufferHead; - volatile size_t m_vsizeRXBufferTail; - volatile size_t m_vsizeTXBufferHead; - volatile size_t m_vsizeTXBufferTail; - - volatile uint8_t m_vui8aRXBuffer[sm_sizeRXBUFFER_SIZE]; - volatile uint8_t m_vui8aTXBuffer[sm_sizeTXBUFFER_SIZE]; - - USART0(); - -private: - static USART0 sm_cInstance; - - uint8_t readUCSRC(); - void setUCSRC( uint8_t ui8UCSRC ); - - void setRXState( bool bEnable ); - void setTXState( bool bEnable ); - void setRXInterrupt( bool bEnable ); - void setUDREInterrupt( bool bEnable ); - void setBaudRate( uint32_t ui32BaudRate ); - void setDataBits( uint8_t ui8DataBits ); - void setParity( Parity enmParity ); - void setStopBits( StopBit enmStopBits ); - void setMode( Mode enmMode ); - - uint32_t getBaudRate(); - uint8_t getDataBits(); - Parity getParity(); - StopBit getStopBits(); - -public: - ~USART0(); - - static USART0& inst(); - USART0( const USART0& ) = delete; - void operator=( const USART0& ) = delete; - - void init( uint32_t ui32BaudRate = 9600, uint8_t ui8DataBits = 8, Parity enmParity = Parity::DISABLED, StopBit enmStopBits = StopBit::ONE, Mode enmMode = Mode::ASYNCHRONOUS ); - - bool receiveByte( uint8_t &ui8Data ); - bool receiveByte( uint8_t &ui8Data, uint16_t ui16TimeoutMS ); - uint8_t receiveByteBlocked(); - uint8_t receivePeek(); - bool receiveLine( char *szBuffer, size_t sizeBufferLength, const char *szLineTerminator = "\r\n" ); - bool receiveLine( char *szBuffer, size_t sizeBufferLength, uint16_t ui16TimeoutMS, const char *szLineTerminator = "\r\n" ); - void flushReceive(); - - void transmitByte( uint8_t ui8Data ); - void transmitString( const char *szString ); - void flushTransmit(); - - void receiveInterruptHandler(); - void transmitInterruptHandler(); - - inline USART0& operator<<( const char *szString ) - { - transmitString( szString ); - return *this; - } -}; - -#ifdef SECOND_USART - -class USART1 : public USART0 -{ -public: - static USART1& inst(); - USART1( const USART1& ) = delete; - void operator=( const USART1& ) = delete; - -private: - static USART1 sm_cInstance; - - USART1(); -}; - -#endif - -#endif \ No newline at end of file