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