You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
8.8 KiB
230 lines
8.8 KiB
//
|
|
// Created by dipak on 18.05.18.
|
|
//
|
|
|
|
#ifndef ATMEGA_SERIAL_H
|
|
#define ATMEGA_SERIAL_H
|
|
|
|
#ifndef F_CPU
|
|
#define F_CPU 16000000
|
|
#endif
|
|
|
|
#include <avr/interrupt.h>
|
|
|
|
#if defined(UBRR0H)
|
|
#define HAS_USART0
|
|
#endif
|
|
|
|
#if defined(UBRR1H)
|
|
//#define HAS_USART1
|
|
#endif
|
|
|
|
#if defined(UBRR2H)
|
|
#define HAS_USART2
|
|
#endif
|
|
|
|
#if defined(UBRR3H)
|
|
#define HAS_USART3
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
/* Defining ISR vectors */
|
|
/****************************************************************/
|
|
extern "C" void USART0_RX_vect(void) __attribute__ ((signal));
|
|
extern "C" void USART0_UDRE_vect(void) __attribute__ ((signal));
|
|
//extern "C" void USART1_RX_vect(void) __attribute__ ((signal));
|
|
//extern "C" void USART1_UDRE_vect(void) __attribute__ ((signal));
|
|
extern "C" void USART2_RX_vect(void) __attribute__ ((signal));
|
|
extern "C" void USART2_UDRE_vect(void) __attribute__ ((signal));
|
|
extern "C" void USART3_RX_vect(void) __attribute__ ((signal));
|
|
extern "C" void USART3_UDRE_vect(void) __attribute__ ((signal));
|
|
|
|
|
|
#define TERMINATOR '\r'
|
|
|
|
/****************************************************************/
|
|
/* Enumeration of communication modes supported by USART */
|
|
/****************************************************************/
|
|
enum class USARTOperatingMode
|
|
{
|
|
ASYNC_NORMAL = 0, /*!<Asynchronous Normal mode */
|
|
ASYNC_DOUBLE_SPEED = 1, /*!<Asynchronous Double Speed */
|
|
SYNC_MASTER = 2 /*!<Synchronous Master mode */
|
|
};
|
|
|
|
/****************************************************************/
|
|
/* Enumeration defining communication parity modes */
|
|
/****************************************************************/
|
|
enum class USARTParity
|
|
{
|
|
NONE = 0,
|
|
EVEN = 2,
|
|
ODD = 3
|
|
};
|
|
|
|
/****************************************************************/
|
|
/* Enumeration defining communication stop bits */
|
|
/****************************************************************/
|
|
enum class USARTStopBits
|
|
{
|
|
ONE = 1,
|
|
TWO = 2
|
|
};
|
|
|
|
/****************************************************************/
|
|
/* Enumeration defining communication frame length */
|
|
/****************************************************************/
|
|
enum class USARTFrameLength
|
|
{
|
|
FIVE_BITS = 5,
|
|
SIX_BITS = 6,
|
|
SEVEN_BITS = 7,
|
|
EIGHT_BITS = 8,
|
|
NINE_BITS = 9
|
|
};
|
|
|
|
class Serial
|
|
{
|
|
public:
|
|
explicit Serial(uint8_t port);
|
|
~Serial();
|
|
static const uint32_t BUFFER_SIZE = 128;
|
|
void begin(uint32_t baud,
|
|
USARTOperatingMode mode = USARTOperatingMode::ASYNC_NORMAL,
|
|
USARTParity parity = USARTParity::NONE,
|
|
USARTStopBits stopBits = USARTStopBits::ONE,
|
|
USARTFrameLength frameLength = USARTFrameLength::EIGHT_BITS);
|
|
|
|
void setFrameLength(USARTFrameLength frameLength);
|
|
void setStopBit(USARTStopBits stopBit);
|
|
void setParity(USARTParity parity);
|
|
void setOpMode(uint32_t baud, USARTOperatingMode mode);
|
|
bool clear();
|
|
void flushBuffer();
|
|
uint8_t read();
|
|
void write(uint8_t data);
|
|
void write(const char *data);
|
|
void writeln(const char *data);
|
|
void write(const uint8_t *data);
|
|
void write(char data);
|
|
uint8_t msgPending();
|
|
bool rxDataAvailable();
|
|
// friend operation which deals with USARTn_RX_vector(s) interrupts
|
|
// using friend operation allows to access private fields of this class
|
|
friend void USART0_RX_vect(void);
|
|
friend void USART0_UDRE_vect(void);
|
|
friend void USART1_RX_vect(void);
|
|
friend void USART1_UDRE_vect(void);
|
|
friend void USART2_RX_vect(void);
|
|
friend void USART2_UDRE_vect(void);
|
|
friend void USART3_RX_vect(void);
|
|
friend void USART3_UDRE_vect(void);
|
|
|
|
|
|
private:
|
|
|
|
#if defined(HAS_USART0)
|
|
static Serial *Serial0; /*!< Static member for Serial port 0*/
|
|
#endif
|
|
#if defined(HAS_USART1)
|
|
static Serial *Serial1; /*!< Static member for Serial port 0*/
|
|
#endif
|
|
#if defined(HAS_USART2)
|
|
static Serial *Serial2; /*!< Static member for Serial port 0*/
|
|
#endif
|
|
#if defined(HAS_USART3)
|
|
static Serial *Serial3; /*!< Static member for Serial port 0*/
|
|
#endif
|
|
|
|
uint8_t portNumber; /*!< Serial communication port number*/
|
|
USARTOperatingMode OperatingMode;
|
|
USARTParity Parity;
|
|
USARTStopBits StopBits;
|
|
USARTFrameLength FrameLength;
|
|
|
|
inline void handleRXInterrupt(); /*!< Private function to handle RX interrupt calls*/
|
|
inline void handleUDREInterrupt(); /*!< Private function to handle UDRE interrupt calls*/
|
|
|
|
/** MCU used registry */
|
|
volatile uint8_t *UDRn;
|
|
volatile uint8_t *UCSRnA;
|
|
volatile uint8_t *UCSRnB;
|
|
volatile uint8_t *UCSRnC;
|
|
volatile uint8_t *UBRRnH;
|
|
volatile uint8_t *UBRRnL;
|
|
|
|
// Buffer Setup
|
|
// Receiving buffer - Rx
|
|
volatile uint8_t pending;
|
|
volatile uint8_t rxBuffer[BUFFER_SIZE]; /*!< Receiver buffer to hold values received from USART */
|
|
volatile uint8_t rxHeadIndex; /*!< Receiver buffer head index. Indexes to the oldest values within the buffer
|
|
* that hasn't been read yet */
|
|
volatile uint8_t rxTailIndex; /*!< Receiver buffer tail index. Indexes to the latest value that was received */
|
|
// Transmission buffer - Rx
|
|
volatile uint8_t txBuffer[BUFFER_SIZE]; /*!< Transmission buffer to hold values before being sent on the USART */
|
|
volatile uint8_t txHeadIndex; /*!< Transmission buffer head index. Indexes to the latest value written to the
|
|
* transmission buffer*/
|
|
volatile uint8_t txTailIndex; /*!< Transmission buffer tail index. Indexes to the value that shall be
|
|
* transmitted when USART line is free*/
|
|
|
|
|
|
/* MCU dependent registry bits (positions) */
|
|
// TXENn: Transmitter Enable n
|
|
// Writing this bit to one enables the USART Transmitter. The Transmitter will override normal port operation for the
|
|
//TxDn pin when enabled. The disabling of the Transmitter (writing TXENn to zero) will not become effective until
|
|
//ongoing and pending transmissions are completed, that is, when the Transmit Shift Register and Transmit Buffer
|
|
//Register do not contain data to be transmitted. When disabled, the Transmitter will no longer override the TxDn
|
|
//port.
|
|
uint8_t TXENn;
|
|
// UDREn: USART Data Register Empty
|
|
// The UDREn Flag indicates if the transmit buffer (UDRn) is ready to receive new data. If UDREn is one, the buffer is
|
|
//empty, and therefore ready to be written. The UDREn Flag can generate a Data Register Empty interrupt (see
|
|
//description of the UDRIEn bit).
|
|
uint8_t RXENn;
|
|
// UDREn: USART Data Register Empty
|
|
//The UDREn Flag indicates if the transmit buffer (UDRn) is ready to receive new data. If UDREn is one, the buffer is
|
|
//empty, and therefore ready to be written. The UDREn Flag can generate a Data Register Empty interrupt (see
|
|
//description of the UDRIEn bit).
|
|
//UDREn is set after a reset to indicate that the Transmitter is ready.
|
|
uint8_t UDREn;
|
|
// U2Xn: Double the USART Transmission Speed
|
|
//This bit only has effect for the asynchronous operation. Write this bit to zero when using synchronous operation.
|
|
//Writing this bit to one will reduce the divisor of the baud rate divider from 16 to 8 effectively doubling the transfer
|
|
//rate for asynchronous communication.
|
|
uint8_t U2Xn;
|
|
// RXCIEn: RX Complete Interrupt Enable n
|
|
//Writing this bit to one enables interrupt on the RXCn Flag. A USART Receive Complete interrupt will be generated
|
|
//only if the RXCIEn bit is written to one, the Global Interrupt Flag in SREG is written to one and the RXCn bit in
|
|
//UCSRnA is set.
|
|
uint8_t RXCIEn;
|
|
// USBSn: Stop Bit Select
|
|
//This bit selects the number of stop bits to be inserted by the Transmitter. The Receiver ignores this setting.
|
|
uint8_t USBSn;
|
|
// UPMn1:0: Parity Mode
|
|
//These bits enable and set type of parity generation and check. If enabled, the Transmitter will automatically generate
|
|
//and send the parity of the transmitted data bits within each frame. The Receiver will generate a parity value for
|
|
//the incoming data and compare it to the UPMn setting. If a mismatch is detected, the UPEn Flag in UCSRnA will be
|
|
//set.
|
|
uint8_t UPMn0;
|
|
uint8_t UPMn1;
|
|
// UCSZn1:0: Character Size
|
|
//The UCSZn1:0 bits combined with the UCSZn2 bit in UCSRnB sets the number of data bits (Character SiZe) in a
|
|
//frame the Receiver and Transmitter use.
|
|
uint8_t UCSZn0;
|
|
uint8_t UCSZn1;
|
|
uint8_t UCSZn2;
|
|
// UMSELn1:0 USART Mode Select
|
|
//These bits select the mode of operation of the USARTn
|
|
uint8_t UMSELn0;
|
|
uint8_t UMSELn1;
|
|
// UDRIEn: USART Data Register Empty Interrupt Enable n
|
|
//Writing this bit to one enables interrupt on the UDREn Flag. A Data Register Empty interrupt will be generated only
|
|
//if the UDRIEn bit is written to one, the Global Interrupt Flag in SREG is written to one and the UDREn bit in UCSRnA
|
|
//is set.
|
|
uint8_t UDRIEn;
|
|
};
|
|
|
|
extern Serial Debug;
|
|
#endif //ATMEGA_SERIAL_H
|