#include "USART.h" ////////////////////////////////////////////////////////////////////////// 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 << m_ui8RXEN ); } else { *m_vui8pUCSRB &= ~( 1 << m_ui8RXEN ); } } ////////////////////////////////////////////////////////////////////////// void USART0::setTXState( bool bEnable ) { if( bEnable ) { *m_vui8pUCSRB |= ( 1 << m_ui8TXEN ); } else { *m_vui8pUCSRB &= ~( 1 << m_ui8TXEN ); } } ////////////////////////////////////////////////////////////////////////// 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 << m_ui8UCSZ0 ); } else { ui8UCSRC &= ~( 1 << m_ui8UCSZ0 ); } if( bOneBit ) { ui8UCSRC |= ( 1 << m_ui8UCSZ1 ); } else { ui8UCSRC &= ~( 1 << m_ui8UCSZ1 ); } *m_vui8pUCSRB &= ~( 1 << m_ui8UCSZ2 ); } else { ui8UCSRC |= ( 1 << m_ui8UCSZ1 ) | ( 1 << m_ui8UCSZ0 ); *m_vui8pUCSRB |= ( 1 << m_ui8UCSZ2 ); } setUCSRC( ui8UCSRC ); } ////////////////////////////////////////////////////////////////////////// void USART0::setParity( Parity enmParity ) { uint8_t ui8UCSRC = readUCSRC(); if( enmParity == Parity::DISABLED ) { ui8UCSRC &= ~( ( 1 << m_ui8UPM1 ) | ( 1 << m_ui8UPM0 ) ); } else if( enmParity == Parity::ODD ) { ui8UCSRC |= ( ( 1 << m_ui8UPM1 ) | ( 1 << m_ui8UPM0 ) ); } else if( enmParity == Parity::EVEN ) { ui8UCSRC &= ~( ( 1 << m_ui8UPM0 ) ); ui8UCSRC |= ( ( 1 << m_ui8UPM1 ) ); } setUCSRC( ui8UCSRC ); } ////////////////////////////////////////////////////////////////////////// void USART0::setStopBits( StopBit enmStopBits ) { uint8_t ui8UCSRC = readUCSRC(); if( enmStopBits == StopBit::ONE ) { ui8UCSRC &= ~( 1 << m_ui8USBS ); } else if( enmStopBits == StopBit::TWO ) { ui8UCSRC |= ( 1 << m_ui8USBS ); } setUCSRC( ui8UCSRC ); } ////////////////////////////////////////////////////////////////////////// void USART0::setMode( Mode enmMode ) { uint8_t ui8UCSRC = readUCSRC(); #ifdef USART_SPI if( enmMode == Mode::ASYNCHRONOUS ) { ui8UCSRC &= ~( ( 1 << m_ui8UMSEL1 ) | ( 1 << m_ui8UMSEL0 ) ); } else if( enmMode == Mode::SYNCHRONOUS ) { ui8UCSRC &= ~( 1 << m_ui8UMSEL1 ); ui8UCSRC |= ( 1 << m_ui8UMSEL0 ); } else if( enmMode == Mode::MASTERSPI ) { ui8UCSRC |= ( ( 1 << m_ui8UMSEL1 ) | ( 1 << m_ui8UMSEL0 ) ); } #else if( enmMode == Mode::ASYNCHRONOUS ) { ui8UCSRC &= ~( 1 << m_ui8UMSEL ); } else if( enmMode == Mode::SYNCHRONOUS ) { ui8UCSRC |= ( 1 << m_ui8UMSEL ); } #endif setUCSRC( ui8UCSRC ); } ////////////////////////////////////////////////////////////////////////// USART0::USART0() : USART0( 9600, 8, Parity::DISABLED, StopBit::ONE, Mode::ASYNCHRONOUS ) {} ////////////////////////////////////////////////////////////////////////// USART0::USART0( uint32_t ui32BaudRate, uint8_t ui8DataBits, Parity enmParity, StopBit enmStopBits, Mode enmMode /* = Mode::ASYNCHRONOUS */ ) { #ifdef USART_SHAREDIO m_vui8pUCSRA = &UCSRA; m_vui8pUCSRB = &UCSRB; m_vui8pUCSRC = &UCSRC; m_vui8pUBRRH = &UBRRH; m_vui8pUBRRL = &UBRRL; m_vui8pUDR = &UDR; m_ui8RXEN = RXEN; m_ui8TXEN = TXEN; m_ui8UCSZ0 = UCSZ0; m_ui8UCSZ1 = UCSZ1; m_ui8UCSZ2 = UCSZ2; m_ui8UPM0 = UPM0; m_ui8UPM1 = UPM1; m_ui8USBS = USBS; m_ui8RXC = RXC; m_ui8UDRE = UDRE; #endif #ifndef USART_SHAREDIO m_vui8pUCSRA = &UCSR0A; m_vui8pUCSRB = &UCSR0B; m_vui8pUCSRC = &UCSR0C; m_vui8pUBRRH = &UBRR0H; m_vui8pUBRRL = &UBRR0L; m_vui8pUDR = &UDR0; m_ui8RXEN = RXEN0; m_ui8TXEN = TXEN0; m_ui8UCSZ0 = UCSZ00; m_ui8UCSZ1 = UCSZ01; m_ui8UCSZ2 = UCSZ02; m_ui8UPM0 = UPM00; m_ui8UPM1 = UPM01; m_ui8USBS = USBS0; m_ui8RXC = RXC0; m_ui8UDRE = UDRE0; #endif #ifdef USART_SPI m_ui8UMSEL0 = UMSEL00; m_ui8UMSEL1 = UMSEL01; #else m_ui8UMSEL = UMSEL; #endif init( ui32BaudRate, ui8DataBits, enmParity, enmStopBits, enmMode ); } ////////////////////////////////////////////////////////////////////////// USART0::~USART0() {} ////////////////////////////////////////////////////////////////////////// void USART0::init( uint32_t ui32BaudRate, uint8_t ui8DataBits, Parity enmParity, StopBit enmStopBits, Mode enmMode /* = Mode::ASYNCHRONOUS */ ) { setBaudRate( ui32BaudRate ); setDataBits( ui8DataBits ); setParity( enmParity ); setStopBits( enmStopBits ); setMode( enmMode ); setRXState( true ); setTXState( true ); } ////////////////////////////////////////////////////////////////////////// bool USART0::receiveByte( unsigned char &chData, uint32_t ui32DelayMS ) { const uint8_t ui8ClockCyclesPerIteration = 6; double dDelayS = ui32DelayMS / 1000.0; uint32_t ui32Iterations = static_cast( ( dDelayS * F_CPU ) / ui8ClockCyclesPerIteration ); do { if( ( *m_vui8pUCSRA & ( 1 << m_ui8RXC ) ) ) { chData = *m_vui8pUDR; return true; } } while( --ui32Iterations > 0 ); return false; } ////////////////////////////////////////////////////////////////////////// unsigned char USART0::receiveByte() { while( !( *m_vui8pUCSRA & ( 1 << m_ui8RXC ) ) ); return *m_vui8pUDR; } ////////////////////////////////////////////////////////////////////////// string USART0::receiveLine( string strLineTerminator /* = "\r\n" */, size_t sizeMaxSize /* = 1024 */ ) { string strReceived; while( strReceived.length() < sizeMaxSize ) { strReceived += receiveByte(); size_t sizeLineTerminator = strReceived.rfind( strLineTerminator ); if( sizeLineTerminator != string::npos ) { strReceived = strReceived.substr( 0, sizeLineTerminator ); break; } } return strReceived; } ////////////////////////////////////////////////////////////////////////// void USART0::receive( char &chReceived ) { chReceived = receiveByte(); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( unsigned char &uchReceived ) { uchReceived = receiveByte(); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( short int &shiReceived ) { long int liInput; receive( liInput ); shiReceived = static_cast( liInput ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( unsigned short int &ushiReceived ) { unsigned long int uliInput; receive( uliInput ); ushiReceived = static_cast( uliInput ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( int &iReceived ) { long int liInput; receive( liInput ); iReceived = static_cast( liInput ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( unsigned int &uiReceived ) { unsigned long int uliInput; receive( uliInput ); uiReceived = static_cast( uliInput ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( long int &liReceived ) { string strInput; unsigned char uchRead; while( !isspace( uchRead = receiveByte() ) ) { strInput += uchRead; } liReceived = strtol( strInput.c_str(), nullptr, 10 ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( unsigned long int &uliReceived ) { string strInput; unsigned char uchRead; while( !isspace( uchRead = receiveByte() ) ) { strInput += uchRead; } uliReceived = strtoul( strInput.c_str(), nullptr, 10 ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( long long int &lliReceived ) { long int liInput; receive( liInput ); lliReceived = liInput; } ////////////////////////////////////////////////////////////////////////// void USART0::receive( unsigned long long int &ulliReceived ) { unsigned long int uliInput; receive( uliInput ); ulliReceived = uliInput; } ////////////////////////////////////////////////////////////////////////// void USART0::receive( float &fReceived ) { double dInput; receive( dInput ); fReceived = dInput; } ////////////////////////////////////////////////////////////////////////// void USART0::receive( double &dReceived ) { string strInput; unsigned char uchRead; while( !isspace( uchRead = receiveByte() ) ) { strInput += uchRead; } dReceived = strtod( strInput.c_str(), nullptr ); } ////////////////////////////////////////////////////////////////////////// void USART0::receive( long double &ldReceived ) { double dInput; receive( dInput ); ldReceived = dInput; } ////////////////////////////////////////////////////////////////////////// void USART0::transmitByte( unsigned char byteData ) { while( !( *m_vui8pUCSRA & ( 1 << m_ui8UDRE ) ) ); *m_vui8pUDR = byteData; } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( string strData ) { for( size_t i = 0; i < strData.length(); ++i ) { transmitByte( strData[i] ); } } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( char chData ) { transmitByte( chData ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned char uchData ) { vector vecBuffer( 4 ); sprintf( vecBuffer.data(), "%hhu", uchData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( short int shiData ) { vector vecBuffer( 6 ); sprintf( vecBuffer.data(), "%hd", shiData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned short int ushiData ) { vector vecBuffer( 6 ); sprintf( vecBuffer.data(), "%hu", ushiData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( int iData ) { vector vecBuffer( 6 ); sprintf( vecBuffer.data(), "%d", iData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned int uiData ) { vector vecBuffer( 6 ); sprintf( vecBuffer.data(), "%u", uiData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long int liData ) { vector vecBuffer( 11 ); sprintf( vecBuffer.data(), "%ld", liData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned long int uliData ) { vector vecBuffer( 11 ); sprintf( vecBuffer.data(), "%lu", uliData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long long int lliData ) { vector vecBuffer( 21 ); sprintf( vecBuffer.data(), "%lld", lliData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned long long int ulliData ) { vector vecBuffer( 21 ); sprintf( vecBuffer.data(), "%llu", ulliData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( float fData ) { vector vecBuffer( 64 ); sprintf( vecBuffer.data(), "%f", static_cast( fData ) ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( double dData ) { vector vecBuffer( 64 ); sprintf( vecBuffer.data(), "%f", dData ); transmit( vecBuffer.data() ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long double ldData ) { vector vecBuffer( 64 ); sprintf( vecBuffer.data(), "%f", static_cast( ldData ) ); transmit( vecBuffer.data() ); } #ifdef SECOND_USART ////////////////////////////////////////////////////////////////////////// USART1::USART1() : USART1( 9600, 8, Parity::DISABLED, StopBit::ONE, Mode::ASYNCHRONOUS ) {} ////////////////////////////////////////////////////////////////////////// USART1::USART1( uint32_t ui32BaudRate, uint8_t ui8DataBits, Parity enmParity, StopBit enmStopBits, Mode enmMode /* = Mode::ASYNCHRONOUS */ ) { m_vui8pUCSRA = &UCSR1A; m_vui8pUCSRB = &UCSR1B; m_vui8pUCSRC = &UCSR1C; m_vui8pUBRRH = &UBRR1H; m_vui8pUBRRL = &UBRR1L; m_vui8pUDR = &UDR1; m_ui8RXEN = RXEN1; m_ui8TXEN = TXEN1; m_ui8UCSZ0 = UCSZ10; m_ui8UCSZ1 = UCSZ11; m_ui8UCSZ2 = UCSZ12; m_ui8UPM0 = UPM10; m_ui8UPM1 = UPM11; m_ui8USBS = USBS1; m_ui8RXC = RXC1; m_ui8UDRE = UDRE1; m_ui8UMSEL0 = UMSEL10; m_ui8UMSEL1 = UMSEL11; init( ui32BaudRate, ui8DataBits, enmParity, enmStopBits, enmMode ); } ////////////////////////////////////////////////////////////////////////// USART1::~USART1() {} #endif