#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 << 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::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 ); } ////////////////////////////////////////////////////////////////////////// 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 } ////////////////////////////////////////////////////////////////////////// USART0::~USART0() {} ////////////////////////////////////////////////////////////////////////// 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 ); } ////////////////////////////////////////////////////////////////////////// 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 << RXC_D ) ) ) { chData = *m_vui8pUDR; return true; } } while( --ui32Iterations > 0 ); return false; } ////////////////////////////////////////////////////////////////////////// unsigned char USART0::receiveByte() { while( !( *m_vui8pUCSRA & ( 1 << RXC_D ) ) ); 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 << UDRE_D ) ) ); *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 ) { sprintf( m_szConvertBuffer, "%hhu", uchData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( short int shiData ) { sprintf( m_szConvertBuffer, "%hd", shiData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned short int ushiData ) { sprintf( m_szConvertBuffer, "%hu", ushiData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( int iData ) { sprintf( m_szConvertBuffer, "%d", iData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned int uiData ) { sprintf( m_szConvertBuffer, "%u", uiData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long int liData ) { sprintf( m_szConvertBuffer, "%ld", liData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned long int uliData ) { sprintf( m_szConvertBuffer, "%lu", uliData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long long int lliData ) { sprintf( m_szConvertBuffer, "%lld", lliData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( unsigned long long int ulliData ) { sprintf( m_szConvertBuffer, "%llu", ulliData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( float fData ) { sprintf( m_szConvertBuffer, "%f", static_cast( fData ) ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( double dData ) { sprintf( m_szConvertBuffer, "%f", dData ); transmit( m_szConvertBuffer ); } ////////////////////////////////////////////////////////////////////////// void USART0::transmit( long double ldData ) { sprintf( m_szConvertBuffer, "%f", static_cast( ldData ) ); transmit( m_szConvertBuffer ); } #ifdef SECOND_USART ////////////////////////////////////////////////////////////////////////// USART1::USART1() { m_vui8pUCSRA = &UCSR1A; m_vui8pUCSRB = &UCSR1B; m_vui8pUCSRC = &UCSR1C; m_vui8pUBRRH = &UBRR1H; m_vui8pUBRRL = &UBRR1L; m_vui8pUDR = &UDR1; } ////////////////////////////////////////////////////////////////////////// USART1::~USART1() {} #endif