Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
pot_calibration.hpp
Go to the documentation of this file.
1// sbl/hw/components/input/pot_calibration.hpp — Two-point ADC calibration
2//
3// Maps raw ADC readings to a normalized integer range using measured endpoint
4// values. Handles inverted ADC layouts (high raw = CCW) and clamps output.
5// Uses uint32_t to support any ADC resolution (12-bit, 16-bit, 24-bit).
6//
7// The I/O stack stays integer — float conversion happens at the stack boundary.
8//
9// Usage:
10// auto cal = PotCalibration::from_two_point(ccw_reading, cw_reading);
11// uint32_t t = cal.normalize(raw_adc); // [0, 65535]
12//
13// // Float conversion at stack boundary
14// float su = t * (1.0f / 65535.0f);
15//
16// See FDP-035 for design rationale.
17
18#ifndef SBL_HW_COMPONENTS_INPUT_POT_CALIBRATION_HPP_
19#define SBL_HW_COMPONENTS_INPUT_POT_CALIBRATION_HPP_
20
21#include <cstdint>
22
23namespace sbl::components::input {
24
26 static constexpr uint32_t kOutputMax = 65535;
27
28 uint32_t raw_min = 0; ///< ADC reading at logical minimum (CCW after inversion)
29 uint32_t raw_max = 65535; ///< ADC reading at logical maximum (CW after inversion)
30 bool inverted = false; ///< true if high ADC value = CCW (knob turned left)
31
32 /// Normalize raw ADC reading to [0, kOutputMax], clamped.
33 uint32_t normalize(uint32_t raw) const {
34 if (raw_max <= raw_min) return 0;
35 uint32_t clamped = raw;
36 if (clamped < raw_min) clamped = raw_min;
37 if (clamped > raw_max) clamped = raw_max;
38 uint32_t val = clamped - raw_min;
39 uint32_t range = raw_max - raw_min;
40 uint32_t result = static_cast<uint32_t>(
41 (static_cast<uint64_t>(val) * kOutputMax) / range);
42 return inverted ? (kOutputMax - result) : result;
43 }
44
45 /// Build calibration from measured CCW and CW ADC readings.
46 /// Automatically detects inversion (if CCW reading > CW reading).
47 static PotCalibration from_two_point(uint32_t ccw_reading, uint32_t cw_reading) {
48 bool inv = ccw_reading > cw_reading;
49 return {
50 inv ? cw_reading : ccw_reading,
51 inv ? ccw_reading : cw_reading,
52 inv
53 };
54 }
55
56 /// Default for Daisy Patch.init() (inverted, ~0–33000 range).
58 return { 0, 33000, true };
59 }
60
61 /// Default full-range (no calibration needed).
63 return { 0, 65535, false };
64 }
65};
66
67} // namespace sbl::components::input
68
69#endif // SBL_HW_COMPONENTS_INPUT_POT_CALIBRATION_HPP_
Pots, buttons, encoders.
Definition button.hpp:24
uint32_t raw_min
ADC reading at logical minimum (CCW after inversion)
uint32_t raw_max
ADC reading at logical maximum (CW after inversion)
static PotCalibration from_two_point(uint32_t ccw_reading, uint32_t cw_reading)
bool inverted
true if high ADC value = CCW (knob turned left)
uint32_t normalize(uint32_t raw) const
Normalize raw ADC reading to [0, kOutputMax], clamped.
static constexpr PotCalibration default_patch_init()
Default for Daisy Patch.init() (inverted, ~0–33000 range).
static constexpr PotCalibration default_full_range()
Default full-range (no calibration needed).