uart/hardware0.hpp

96 lines
2.3 KiB
C++
Raw Normal View History

#pragma once
2019-07-28 12:15:19 +02:00
#include "config.hpp"
#include "hardware.hpp"
#define FORCE_INLINE __attribute__((always_inline))
namespace uart {
namespace detail {
2019-07-30 20:29:38 +02:00
#if defined(__AVR_ATmega1284P__)
struct Registers0 {
static constexpr volatile auto *IO_REG = &UDR0;
static constexpr volatile auto *CTRL_STAT_REG_A = &UCSR0A;
static constexpr volatile auto *CTRL_STAT_REG_B = &UCSR0B;
static constexpr volatile auto *CTRL_STAT_REG_C = &UCSR0C;
static constexpr volatile auto *BAUD_REG_L = &UBRR0L;
static constexpr volatile auto *BAUD_REG_H = &UBRR0H;
};
enum class ControlFlagsA0 {
2019-07-30 20:56:16 +02:00
MULTI_PROC_COMM_MODE = MPCM0,
SPEED_2X = U2X0,
PARITY_ERROR = UPE0,
DATA_OVER_RUN = DOR0,
FRAME_ERROR = FE0,
DATA_REG_EMPTY = UDRE0,
TRANSMIT_COMPLETE = TXC0,
RECEIVE_COMPLETE = RXC0,
};
enum class ControlFlagsB0 {
2019-07-30 20:56:16 +02:00
TX_DATA_BIT_8 = TXB80,
RX_DATA_BIT_8 = RXB80,
CHAR_SIZE_2 = UCSZ02,
TX_ENABLE = TXEN0,
RX_ENABLE = RXEN0,
DATA_REG_EMPTY_INT_ENABLE = UDRIE0,
TX_INT_ENABLE = TXCIE0,
RX_INT_ENABLE = RXCIE0,
};
enum class ControlFlagsC0 {
2019-07-30 20:56:16 +02:00
CLK_POLARITY = UCPOL0,
CHAR_SIZE_0 = UCSZ00,
CHAR_SIZE_1 = UCSZ01,
STOP_BIT_SEL = USBS0,
PARITY_MODE_0 = UPM00,
PARITY_MODE_1 = UPM01,
MODE_SEL_0 = UMSEL00,
MODE_SEL_1 = UMSEL01,
};
2019-07-30 21:51:13 +02:00
// clang-format off
constexpr int operator<<(const int &lhs, const ControlFlagsA0 &rhs) { return lhs << static_cast<int>(rhs); }
constexpr int operator<<(const int &lhs, const ControlFlagsB0 &rhs) { return lhs << static_cast<int>(rhs); }
constexpr int operator<<(const int &lhs, const ControlFlagsC0 &rhs) { return lhs << static_cast<int>(rhs); }
// clang-format on
2019-07-30 20:29:38 +02:00
#else
#error "This chip is not supported"
#endif
} // namespace detail
template <Mode mode = Mode::ASYNCHRONOUS, class cfg = Config<>, Driven driven = Driven::INTERRUPT>
class Hardware0 {
public:
using data_t = typename cfg::data_t;
static constexpr auto DATA_BITS = cfg::DATA_BITS;
2019-07-30 21:48:00 +02:00
static void init() FORCE_INLINE
{
HardwareImpl::init();
}
static void txByte(data_t byte) FORCE_INLINE
{
HardwareImpl::txByte(byte);
}
2019-07-30 21:48:00 +02:00
static data_t rxByte() FORCE_INLINE {}
2019-07-30 21:48:00 +02:00
static data_t peek() FORCE_INLINE {}
private:
using HardwareImpl = detail::Hardware<detail::Registers0, detail::ControlFlagsA0, detail::ControlFlagsB0,
detail::ControlFlagsC0, cfg, mode>;
};
} // namespace uart
#undef FORCE_INLINE