#ifndef ADC_HPP #define ADC_HPP #include "config.hpp" #include "hardware.hpp" #include #include "../io/io.hpp" 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 class Adc { public: static_assert(sizeof(Input) == -1, "Invalid input source selected"); }; template class Adc : public detail::AdcImpl { public: static_assert(detail::supports_adc_v, "Pin does not support ADC"); }; template class Adc : public detail::AdcImpl { }; } // namespace adc #endif ////////////////////////////////////////////////////////////////////////// #ifdef ADC_INT_VECTOR #include #include namespace adc { namespace detail { #if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega328P__) void (*fnAdcIntHandler)(uint16_t) = nullptr; using reg_ptr_t = volatile uint8_t *; template static inline reg_ptr_t getRegPtr() { return reinterpret_cast(Address); } ISR(ADC_vect) { if (fnAdcIntHandler) { const auto adcSample = *getRegPtr() | (*getRegPtr() << 8); fnAdcIntHandler(adcSample); } } #else #error "This chip is not supported" #endif } // namespace detail } // namespace adc #undef ADC_INT_VECTORS #endif