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 "config.hpp"
|
||||||
#include "hardware.hpp"
|
#include "hardware.hpp"
|
||||||
@ -9,6 +10,30 @@
|
|||||||
|
|
||||||
namespace adc {
|
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>
|
template <typename Cfg, typename Input, Input src>
|
||||||
class Adc {
|
class Adc {
|
||||||
public:
|
public:
|
||||||
@ -16,43 +41,57 @@ class Adc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Cfg, io::P pin>
|
template <typename Cfg, io::P pin>
|
||||||
class Adc<Cfg, io::P, pin> {
|
class Adc<Cfg, io::P, pin> : public detail::AdcImpl {
|
||||||
private:
|
|
||||||
using callback_t = void (*)(uint16_t);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static_assert(detail::supports_adc_v<pin>, "Pin does not support ADC");
|
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>
|
template <typename Cfg, InputSource src>
|
||||||
class Adc<Cfg, InputSource, src> {
|
class Adc<Cfg, InputSource, src> : public detail::AdcImpl {
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace adc
|
} // 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 adc {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
SINGLE,
|
SINGLE,
|
||||||
AUTO,
|
AUTO,
|
||||||
FREE_RUNNING,
|
FREE_RUNNING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
enum class TriggerSource {
|
enum class TriggerSource {
|
||||||
FREE_RUNNING,
|
FREE_RUNNING,
|
||||||
ANALOG_COMP,
|
ANALOG_COMP,
|
||||||
@ -46,6 +50,24 @@ enum class InputSource {
|
|||||||
|
|
||||||
template <class Mode, VoltageRef vref = VoltageRef::AVCC, uint8_t prescaler = 128>
|
template <class Mode, VoltageRef vref = VoltageRef::AVCC, uint8_t prescaler = 128>
|
||||||
struct Config {
|
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
|
} // namespace adc
|
||||||
|
Loading…
Reference in New Issue
Block a user