uart/usart.h

185 lines
4.0 KiB
C++

/*
* Copyright (c) by BlackMark 2015-2018
* Date 12/04/2018
* Version 3.4
*/
#ifndef USART_H
#define USART_H
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#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