Implemented different configs and refactored implementation into Impl class
This commit is contained in:
parent
045efedd45
commit
c1eadf4cb1
105
adc.hpp
105
adc.hpp
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef ADC_HPP
|
||||
#define ADC_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
#include "hardware.hpp"
|
||||
@ -9,6 +10,30 @@
|
||||
|
||||
namespace adc {
|
||||
|
||||
namespace detail {
|
||||
|
||||
extern void (*fnAdcIntHandler)(uint16_t);
|
||||
|
||||
class AdcImpl {
|
||||
private:
|
||||
using callback_t = void (*)(uint16_t);
|
||||
|
||||
public:
|
||||
static void init(callback_t callback)
|
||||
{
|
||||
detail::fnAdcIntHandler = callback;
|
||||
}
|
||||
|
||||
static void init() {}
|
||||
|
||||
static uint16_t read()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Cfg, typename Input, Input src>
|
||||
class Adc {
|
||||
public:
|
||||
@ -16,43 +41,57 @@ class Adc {
|
||||
};
|
||||
|
||||
template <typename Cfg, io::P pin>
|
||||
class Adc<Cfg, io::P, pin> {
|
||||
private:
|
||||
using callback_t = void (*)(uint16_t);
|
||||
|
||||
class Adc<Cfg, io::P, pin> : public detail::AdcImpl {
|
||||
public:
|
||||
static_assert(detail::supports_adc_v<pin>, "Pin does not support ADC");
|
||||
|
||||
Adc() {}
|
||||
|
||||
Adc(callback_t callback) : m_callback(callback) {}
|
||||
|
||||
uint16_t read()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const callback_t m_callback = nullptr;
|
||||
};
|
||||
|
||||
template <typename Cfg, InputSource src>
|
||||
class Adc<Cfg, InputSource, src> {
|
||||
private:
|
||||
using callback_t = void (*)(uint16_t);
|
||||
|
||||
public:
|
||||
Adc() {}
|
||||
|
||||
Adc(callback_t callback) : m_callback(callback) {}
|
||||
|
||||
uint16_t read()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const callback_t m_callback = nullptr;
|
||||
class Adc<Cfg, InputSource, src> : public detail::AdcImpl {
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef ADC_INT_VECTOR
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
namespace adc {
|
||||
namespace detail {
|
||||
|
||||
#if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega328P__)
|
||||
|
||||
void (*fnAdcIntHandler)(uint16_t) = nullptr;
|
||||
|
||||
using reg_ptr_t = volatile uint8_t *;
|
||||
|
||||
template <uintptr_t Address>
|
||||
static inline reg_ptr_t getRegPtr()
|
||||
{
|
||||
return reinterpret_cast<reg_ptr_t>(Address);
|
||||
}
|
||||
|
||||
ISR(ADC_vect)
|
||||
{
|
||||
if (fnAdcIntHandler) {
|
||||
const auto adcSample = *getRegPtr<Registers::DATA_L_ADDR>() | (*getRegPtr<Registers::DATA_H_ADDR>() << 8);
|
||||
fnAdcIntHandler(adcSample);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#error "This chip is not supported"
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace adc
|
||||
|
||||
#undef ADC_INT_VECTORS
|
||||
|
||||
#endif
|
||||
|
22
config.hpp
22
config.hpp
@ -4,12 +4,16 @@
|
||||
|
||||
namespace adc {
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class Mode {
|
||||
SINGLE,
|
||||
AUTO,
|
||||
FREE_RUNNING,
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
enum class TriggerSource {
|
||||
FREE_RUNNING,
|
||||
ANALOG_COMP,
|
||||
@ -46,6 +50,24 @@ enum class InputSource {
|
||||
|
||||
template <class Mode, VoltageRef vref = VoltageRef::AVCC, uint8_t prescaler = 128>
|
||||
struct Config {
|
||||
static constexpr auto MODE = detail::Mode::AUTO;
|
||||
static constexpr auto TRIGGER_SRC = Mode::SRC;
|
||||
static constexpr auto VREF = vref;
|
||||
static constexpr auto PRESCALER = prescaler;
|
||||
};
|
||||
|
||||
template <VoltageRef vref, uint8_t prescaler>
|
||||
struct Config<FreeRunningMode, vref, prescaler> {
|
||||
static constexpr auto MODE = detail::Mode::FREE_RUNNING;
|
||||
static constexpr auto VREF = vref;
|
||||
static constexpr auto PRESCALER = prescaler;
|
||||
};
|
||||
|
||||
template <VoltageRef vref, uint8_t prescaler>
|
||||
struct Config<SingleMode, vref, prescaler> {
|
||||
static constexpr auto MODE = detail::Mode::SINGLE;
|
||||
static constexpr auto VREF = vref;
|
||||
static constexpr auto PRESCALER = prescaler;
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
Loading…
Reference in New Issue
Block a user