Implemented all modes

This commit is contained in:
BlackMark 2020-02-21 21:53:48 +01:00
parent 05c799c466
commit bcae00c0f3

67
adc.hpp
View File

@ -27,13 +27,25 @@ class AdcImpl {
public: public:
static uint16_t read() static uint16_t read()
{ {
return 0; *getRegPtr<Registers::CTRL_STAT_A_ADDR>() |= 1 << ControlFlagsA::START_CONV;
while (*getRegPtr<Registers::CTRL_STAT_A_ADDR>() & (1 << ControlFlagsA::START_CONV))
;
uint16_t adcSample = *getRegPtr<Registers::DATA_L_ADDR>();
adcSample |= *getRegPtr<Registers::DATA_H_ADDR>() << 8;
return adcSample;
} }
protected: protected:
static void init(uint8_t muxVal) static void init(uint8_t muxVal)
{ {
*getRegPtr<Registers::MUX_SEL_ADDR>() = muxVal | calcRef(); *getRegPtr<Registers::MUX_SEL_ADDR>() = muxVal | calcRef();
auto ctrlStatA = calcCtrlStatA(detail::fnAdcIntHandler != nullptr);
*getRegPtr<Registers::CTRL_STAT_A_ADDR>() = ctrlStatA;
constexpr auto ctrlStatB = calcCtrlStatB();
*getRegPtr<Registers::CTRL_STAT_B_ADDR>() = ctrlStatB;
} }
static constexpr auto calcRef() static constexpr auto calcRef()
@ -48,6 +60,59 @@ class AdcImpl {
return muxVal; return muxVal;
} }
static constexpr uint8_t calcPrescaler()
{
constexpr auto validPrescaler = Cfg::PRESCALER == 2 || Cfg::PRESCALER == 4 || Cfg::PRESCALER == 8 ||
Cfg::PRESCALER == 16 || Cfg::PRESCALER == 32 || Cfg::PRESCALER == 64 ||
Cfg::PRESCALER == 128;
static_assert(validPrescaler, "Invalid prescaler");
// clang-format off
switch (Cfg::PRESCALER) {
case 2: return 1;
case 4: return 2;
case 8: return 3;
case 16: return 4;
case 32: return 5;
case 64: return 6;
case 128: return 7;
}
// clang-format on
}
static auto calcCtrlStatA(bool interruptEnable)
{
uint8_t ctrlStatA = 1 << ControlFlagsA::ENABLE;
if constexpr (Cfg::MODE == Mode::AUTO) {
ctrlStatA |= 1 << ControlFlagsA::AUTO_TRIGGER;
} else if (interruptEnable) {
ctrlStatA |= 1 << ControlFlagsA::CONV_COMPLETE_INT_ENABLE;
}
return ctrlStatA | calcPrescaler();
}
static constexpr uint8_t calcCtrlStatB()
{
if constexpr (Cfg::MODE == Mode::AUTO) {
// clang-format off
switch (Cfg::TRIGGER_SRC) {
case TriggerSource::FREE_RUNNING: return 0;
case TriggerSource::ANALOG_COMP: return 1;
case TriggerSource::EXTERNAL_INT_0: return 2;
case TriggerSource::TIMER0_COMP_A: return 3;
case TriggerSource::TIMER0_OVERFLOW: return 4;
case TriggerSource::TIMER1_COMP_B: return 5;
case TriggerSource::TIMER1_OVERFLOW: return 6;
case TriggerSource::TIMER1_CAPTURE: return 7;
}
// clang-format on
}
return 0;
}
}; };
} // namespace detail } // namespace detail