From 7b0108f3ec40e9dd92737cc4a537042582e1161e Mon Sep 17 00:00:00 2001 From: Eddy Pedroni Date: Sun, 25 Oct 2026 17:18:09 +0100 Subject: Implement ADC without hysteresis, not tested --- firmware/src/adc.hpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/firmware/src/adc.hpp b/firmware/src/adc.hpp index a3bd0b0..ef596bc 100644 --- a/firmware/src/adc.hpp +++ b/firmware/src/adc.hpp @@ -1,6 +1,54 @@ #include #include +namespace +{ + +constexpr std::uint32_t base_address = 0x4004'c000u; +std::uint32_t volatile * const control_status_addr = reinterpret_cast(base_address + 0x0u); +std::uint32_t volatile * const result_addr = reinterpret_cast(base_address + 0x4u); + +void +select_input(std::uint32_t index) +{ + constexpr std::uint32_t ainsel = 0x111u; + *control_status_addr = (*control_status_addr & ~(ainsel << 12)) | ((index & ainsel) << 12); +} + +bool +ready() +{ + return (*control_status_addr & 1u << 8) != 0u; +} + +bool +error() +{ + return (*control_status_addr & 1u << 9) != 0u; +} + +void +start_once() +{ + *control_status_addr |= (1u << 2); +} + +void +enable(bool en) +{ + *control_status_addr |= en ? (1u << 2) : 0u; +} + +std::uint32_t +result() +{ + return *result_addr & 0x0000'0fffu; +} + +std::array previous_samples { 0xffff'ffffu, 0xffff'ffffu }; + +} + namespace adc { @@ -13,13 +61,29 @@ struct Sample void init() { + enable(true); } std::array get_samples() { - // TODO: scale 12-bit range into MIDI 7-bit range with hysteresis - return std::array{{{}, {}}}; + while (!ready()); + + std::array samples {}; + for (std::size_t i = 0; i < samples.size(); i++) + { + select_input(i); + start_once(); + + while (!ready()); + + std::uint32_t const measurement = result(); + samples[i].changed = measurement != previous_samples[i]; + previous_samples[i] = measurement; + samples[i].value = measurement * 127u / 4095u; // TODO add hysteresis + } + + return samples; } } -- cgit v1.2.3