Added basic structure to support interrupt driven operation
This commit is contained in:
parent
a13a1ca9ab
commit
3aeb43ee1e
19
hardware.hpp
19
hardware.hpp
@ -19,7 +19,8 @@ enum class Driven {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <class Registers, typename CtrlFlagsA, typename CtrlFlagsB, typename CtrlFlagsC, class cfg, Mode mode>
|
template <class Registers, typename CtrlFlagsA, typename CtrlFlagsB, typename CtrlFlagsC, class cfg, Mode mode,
|
||||||
|
Driven driven>
|
||||||
class Hardware {
|
class Hardware {
|
||||||
public:
|
public:
|
||||||
static void init() FORCE_INLINE
|
static void init() FORCE_INLINE
|
||||||
@ -35,15 +36,16 @@ class Hardware {
|
|||||||
constexpr auto modeVal = calcMode();
|
constexpr auto modeVal = calcMode();
|
||||||
constexpr auto enableRx = calcRxState<true>();
|
constexpr auto enableRx = calcRxState<true>();
|
||||||
constexpr auto enableTx = calcTxState<true>();
|
constexpr auto enableTx = calcTxState<true>();
|
||||||
|
constexpr auto interruptVal = calcInterrupt();
|
||||||
|
|
||||||
constexpr uint8_t controlRegB = dataBitsVal.regBVal | enableRx | enableTx;
|
constexpr uint8_t controlRegB = dataBitsVal.regBVal | enableRx | enableTx | interruptVal;
|
||||||
constexpr uint8_t controlRegC = dataBitsVal.regCVal | parityVal | stopBitsVal | modeVal;
|
constexpr uint8_t controlRegC = dataBitsVal.regCVal | parityVal | stopBitsVal | modeVal;
|
||||||
|
|
||||||
*Registers::CTRL_STAT_REG_B = controlRegB;
|
*Registers::CTRL_STAT_REG_B = controlRegB;
|
||||||
*Registers::CTRL_STAT_REG_C = controlRegC;
|
*Registers::CTRL_STAT_REG_C = controlRegC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void txByte(typename cfg::data_t byte) FORCE_INLINE
|
static void txByteBlocking(typename cfg::data_t byte) FORCE_INLINE
|
||||||
{
|
{
|
||||||
while (!(*Registers::CTRL_STAT_REG_A & (1 << CtrlFlagsA::DATA_REG_EMPTY)))
|
while (!(*Registers::CTRL_STAT_REG_A & (1 << CtrlFlagsA::DATA_REG_EMPTY)))
|
||||||
;
|
;
|
||||||
@ -146,6 +148,17 @@ class Hardware {
|
|||||||
|
|
||||||
return enableVal;
|
return enableVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr auto calcInterrupt()
|
||||||
|
{
|
||||||
|
uint8_t interruptVal = 0;
|
||||||
|
|
||||||
|
if (driven == Driven::INTERRUPT)
|
||||||
|
interruptVal |= (1 << CtrlFlagsB::DATA_REG_EMPTY_INT_ENABLE) | (1 << CtrlFlagsB::RX_INT_ENABLE) |
|
||||||
|
(1 << CtrlFlagsB::TX_INT_ENABLE);
|
||||||
|
|
||||||
|
return interruptVal;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -59,6 +59,28 @@ constexpr int operator<<(const int &lhs, const ControlFlagsB0 &rhs) { return lhs
|
|||||||
constexpr int operator<<(const int &lhs, const ControlFlagsC0 &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
|
// clang-format on
|
||||||
|
|
||||||
|
static void (*fnDataReg0EmptyIntHandler)() = nullptr;
|
||||||
|
static void (*fnRx0IntHandler)() = nullptr;
|
||||||
|
static void (*fnTx0IntHandler)() = nullptr;
|
||||||
|
|
||||||
|
ISR(USART0_UDRE_vect)
|
||||||
|
{
|
||||||
|
if (fnDataReg0EmptyIntHandler)
|
||||||
|
fnDataReg0EmptyIntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART0_RX_vect)
|
||||||
|
{
|
||||||
|
if (fnRx0IntHandler)
|
||||||
|
fnRx0IntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART0_TX_vect)
|
||||||
|
{
|
||||||
|
if (fnTx0IntHandler)
|
||||||
|
fnTx0IntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "This chip is not supported"
|
#error "This chip is not supported"
|
||||||
#endif
|
#endif
|
||||||
@ -78,7 +100,7 @@ class Hardware0 {
|
|||||||
|
|
||||||
static void txByte(data_t byte) FORCE_INLINE
|
static void txByte(data_t byte) FORCE_INLINE
|
||||||
{
|
{
|
||||||
HardwareImpl::txByte(byte);
|
HardwareImpl::txByteBlocking(byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static data_t rxByte() FORCE_INLINE {}
|
static data_t rxByte() FORCE_INLINE {}
|
||||||
@ -87,7 +109,51 @@ class Hardware0 {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
using HardwareImpl = detail::Hardware<detail::Registers0, detail::ControlFlagsA0, detail::ControlFlagsB0,
|
using HardwareImpl = detail::Hardware<detail::Registers0, detail::ControlFlagsA0, detail::ControlFlagsB0,
|
||||||
detail::ControlFlagsC0, cfg, mode>;
|
detail::ControlFlagsC0, cfg, mode, driven>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <Mode mode, class cfg>
|
||||||
|
class Hardware0<mode, cfg, Driven::INTERRUPT> {
|
||||||
|
public:
|
||||||
|
using data_t = typename cfg::data_t;
|
||||||
|
static constexpr auto DATA_BITS = cfg::DATA_BITS;
|
||||||
|
|
||||||
|
static void init() FORCE_INLINE
|
||||||
|
{
|
||||||
|
detail::fnDataReg0EmptyIntHandler = dataRegEmptyIntHandler;
|
||||||
|
detail::fnRx0IntHandler = rxIntHandler;
|
||||||
|
detail::fnTx0IntHandler = txIntHandler;
|
||||||
|
|
||||||
|
HardwareImpl::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void txByte(data_t byte) FORCE_INLINE
|
||||||
|
{
|
||||||
|
HardwareImpl::txByteBlocking(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
static data_t rxByte() FORCE_INLINE {}
|
||||||
|
|
||||||
|
static data_t peek() FORCE_INLINE {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
using HardwareImpl = detail::Hardware<detail::Registers0, detail::ControlFlagsA0, detail::ControlFlagsB0,
|
||||||
|
detail::ControlFlagsC0, cfg, mode, Driven::INTERRUPT>;
|
||||||
|
|
||||||
|
static void dataRegEmptyIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rxIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void txIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace uart
|
} // namespace uart
|
||||||
|
@ -59,6 +59,28 @@ constexpr int operator<<(const int &lhs, const ControlFlagsB1 &rhs) { return lhs
|
|||||||
constexpr int operator<<(const int &lhs, const ControlFlagsC1 &rhs) { return lhs << static_cast<int>(rhs); }
|
constexpr int operator<<(const int &lhs, const ControlFlagsC1 &rhs) { return lhs << static_cast<int>(rhs); }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
static void (*fnDataReg1EmptyIntHandler)() = nullptr;
|
||||||
|
static void (*fnRx1IntHandler)() = nullptr;
|
||||||
|
static void (*fnTx1IntHandler)() = nullptr;
|
||||||
|
|
||||||
|
ISR(USART1_UDRE_vect)
|
||||||
|
{
|
||||||
|
if (fnDataReg1EmptyIntHandler)
|
||||||
|
fnDataReg1EmptyIntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART1_RX_vect)
|
||||||
|
{
|
||||||
|
if (fnRx1IntHandler)
|
||||||
|
fnRx1IntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(USART1_TX_vect)
|
||||||
|
{
|
||||||
|
if (fnTx1IntHandler)
|
||||||
|
fnTx1IntHandler();
|
||||||
|
}
|
||||||
|
|
||||||
#define HAS_UART1
|
#define HAS_UART1
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -82,7 +104,7 @@ class Hardware1 {
|
|||||||
|
|
||||||
static void txByte(data_t byte) FORCE_INLINE
|
static void txByte(data_t byte) FORCE_INLINE
|
||||||
{
|
{
|
||||||
HardwareImpl::txByte(byte);
|
HardwareImpl::txByteBlocking(byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static data_t rxByte() FORCE_INLINE {}
|
static data_t rxByte() FORCE_INLINE {}
|
||||||
@ -91,7 +113,51 @@ class Hardware1 {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
using HardwareImpl = detail::Hardware<detail::Registers1, detail::ControlFlagsA1, detail::ControlFlagsB1,
|
using HardwareImpl = detail::Hardware<detail::Registers1, detail::ControlFlagsA1, detail::ControlFlagsB1,
|
||||||
detail::ControlFlagsC1, cfg, mode>;
|
detail::ControlFlagsC1, cfg, mode, driven>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <Mode mode, class cfg>
|
||||||
|
class Hardware1<mode, cfg, Driven::INTERRUPT> {
|
||||||
|
public:
|
||||||
|
using data_t = typename cfg::data_t;
|
||||||
|
static constexpr auto DATA_BITS = cfg::DATA_BITS;
|
||||||
|
|
||||||
|
static void init() FORCE_INLINE
|
||||||
|
{
|
||||||
|
detail::fnDataReg1EmptyIntHandler = dataRegEmptyIntHandler;
|
||||||
|
detail::fnRx1IntHandler = rxIntHandler;
|
||||||
|
detail::fnTx1IntHandler = txIntHandler;
|
||||||
|
|
||||||
|
HardwareImpl::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void txByte(data_t byte) FORCE_INLINE
|
||||||
|
{
|
||||||
|
HardwareImpl::txByteBlocking(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
static data_t rxByte() FORCE_INLINE {}
|
||||||
|
|
||||||
|
static data_t peek() FORCE_INLINE {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
using HardwareImpl = detail::Hardware<detail::Registers1, detail::ControlFlagsA1, detail::ControlFlagsB1,
|
||||||
|
detail::ControlFlagsC1, cfg, mode, Driven::INTERRUPT>;
|
||||||
|
|
||||||
|
static void dataRegEmptyIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rxIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void txIntHandler()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user