20 static constexpr bool DebugDriver =
false;
25 using Debug = ConditionalDebug<DebugDriver,
"ADC">;
32 static constexpr uint16_t MeasurementMask = 0xFFF0;
43 enum class RegisterOffset : uint8_t
46 VoltageInternalSupply = 0x01,
47 VoltageAuxiliarySupply = 0x02,
48 VoltageDedicated = 0x03,
49 VoltageInternalPositiveReference = 0x04,
50 VoltageInternalNegativeReference = 0x05,
51 VoltageBlockRamSupply = 0x06,
61 VoltageAuxiliary0 = 0x10,
62 VoltageAuxiliary1 = 0x11,
63 VoltageAuxiliary2 = 0x12,
64 VoltageAuxiliary3 = 0x13,
65 VoltageAuxiliary4 = 0x14,
66 VoltageAuxiliary5 = 0x15,
67 VoltageAuxiliary6 = 0x16,
68 VoltageAuxiliary7 = 0x17,
69 VoltageAuxiliary8 = 0x18,
70 VoltageAuxiliary9 = 0x19,
71 VoltageAuxiliary10 = 0x1A,
72 VoltageAuxiliary11 = 0x1B,
73 VoltageAuxiliary12 = 0x1C,
74 VoltageAuxiliary13 = 0x1D,
75 VoltageAuxiliary14 = 0x1E,
76 VoltageAuxiliary15 = 0x1F,
87 ConfigRegister0 = 0x40,
88 ConfigRegister1 = 0x41,
89 ConfigRegister2 = 0x42,
102 enum ConfigRegister2Field : uint16_t
109 PowerDownMask = 0x3 << 4,
121 ClockDividerMask = 0xFF << 8,
129 [[nodiscard, gnu::always_inline]]
volatile uint32_t *registers()
const
142 [[nodiscard]] uint16_t register_read(RegisterOffset reg)
const
144 uint8_t registerOffset =
static_cast<uint8_t
>(reg);
145 return static_cast<uint16_t
>(registers()[registerOffset]);
157 void register_write(RegisterOffset reg, uint16_t value)
const
159 uint8_t registerOffset =
static_cast<uint8_t
>(reg);
160 registers()[registerOffset] =
static_cast<uint32_t
>(value);
174 void register_set_bits(RegisterOffset reg,
176 uint16_t bitValues)
const
178 uint16_t registerBits = register_read(reg);
179 registerBits &= ~bitMask;
180 registerBits |= bitMask & bitValues;
181 return register_write(reg, registerBits);
195 ArduinoA0 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary4),
196 ArduinoA1 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary12),
197 ArduinoA2 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary5),
198 ArduinoA3 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary13),
199 ArduinoA4 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary6),
200 ArduinoA5 =
static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliary14),
201 Temperature =
static_cast<uint8_t
>(RegisterOffset::Temperature),
202 VoltageInternalSupply =
203 static_cast<uint8_t
>(RegisterOffset::VoltageInternalSupply),
204 VoltageAuxiliarySupply =
205 static_cast<uint8_t
>(RegisterOffset::VoltageAuxiliarySupply),
206 VoltageInternalReferencePositive =
static_cast<uint8_t
>(
207 RegisterOffset::VoltageInternalPositiveReference),
208 VoltageInternalReferenceNegative =
static_cast<uint8_t
>(
209 RegisterOffset::VoltageInternalNegativeReference),
210 VoltageBlockRamSupply =
211 static_cast<uint8_t
>(RegisterOffset::VoltageBlockRamSupply),
224 BothConverters = 0b11,
236 static constexpr size_t RegisterSize = 16;
237 static constexpr size_t MeasurementBitWidth = 12;
247 static constexpr size_t MaxClockFrequencyHz = 26 * 1000 * 1000;
302 Debug::Assert((divider >= 2),
"The ADC divider must be at least 2");
305 "The given divider causes the ADC clock to underclock its minimum.");
307 (CPU_TIMER_HZ / divider <= MaxClockFrequencyHz),
308 "The given divider causes the ADC clock to overclock its maximum.");
310 RegisterOffset::ConfigRegister2, ClockDividerMask, (divider << 8));
322 register_set_bits(RegisterOffset::ConfigRegister2,
324 (
static_cast<uint16_t
>(powerdown) << 4));
342 uint16_t measurement = register_read(
static_cast<RegisterOffset
>(reg));
343 measurement &= MeasurementMask;
344 measurement >>= (RegisterSize - MeasurementBitWidth);
351 return static_cast<int16_t
>(measurement);