30template <
typename SpiType>
36 two_vref_(2.0f * vref_),
37 active_vref_((initial_range ==
Range::TwoVref) ? two_vref_ : vref_),
38 range_(initial_range) {}
44template <
typename SpiType>
47 two_vref_ = 2.0f * vref_;
52template <
typename SpiType>
61template <
typename SpiType>
64 if (initialized_ && !force) {
71template <
typename SpiType>
77 if (!ProgramAuto1Channels(auto1_mask_)) {
82 if (!ProgramAuto2LastChannel(auto2_last_ch_)) {
87 if (!EnterAuto1Mode(
true)) {
99template <
typename SpiType>
113 const uint16_t ctrl = commonControlBits();
126 result.voltage = CountToVoltage(result.count);
133template <
typename SpiType>
143 const uint16_t ctrl = commonControlBits();
144 const uint16_t target_mask = auto1_mask_ & 0x0FFF;
145 const uint8_t num_enabled = popcount16(target_mask);
147 if (num_enabled == 0) {
161 const uint8_t max_frames =
164 for (uint8_t i = 0; i < max_frames; ++i) {
165 uint16_t resp = spiTransfer16(cont);
170 result.count[ch] = data;
171 result.voltage[ch] = CountToVoltage(data);
172 result.valid_mask |=
static_cast<uint16_t
>(1U << ch);
175 if (result.valid_mask == target_mask) {
190template <
typename SpiType>
193 return (
static_cast<float>(count) * active_vref_)
197template <
typename SpiType>
200 if (voltage <= 0.0f)
return 0;
201 float raw = (voltage / active_vref_) *
static_cast<float>(
reg::MAX_COUNT);
203 return static_cast<uint16_t
>(raw);
210template <
typename SpiType>
222template <
typename SpiType>
227 | commonControlBits();
233template <
typename SpiType>
238 | commonControlBits();
248template <
typename SpiType>
256 spiTransfer16(channel_mask & 0x0FFF);
258 auto1_mask_ = channel_mask & 0x0FFF;
266template <
typename SpiType>
274 auto2_last_ch_ = last_channel;
282template <
typename SpiType>
288 if (config.reset_all_registers) {
293 if (config.gpio3_as_powerdown_input) {
298 if (config.gpio2_as_range_input) {
303 switch (config.alarm_mode) {
321 frame |=
static_cast<uint16_t
>(config.direction_mask & 0x0F);
323 spiTransfer16(frame);
331template <
typename SpiType>
334 uint16_t threshold_12bit)
noexcept {
347 default:
return false;
351 spiTransfer16(group_mode);
364 spiTransfer16(alarm_frame);
372template <
typename SpiType>
375 float voltage)
noexcept {
383template <
typename SpiType>
397template <
typename SpiType>
412template <
typename SpiType>
415 gpio_output_state_ = gpio_state & 0x0F;
426template <
typename SpiType>
430 static_cast<uint8_t
>((command >> 8) & 0xFF),
431 static_cast<uint8_t
>(command & 0xFF)};
432 uint8_t rx[2] = {0, 0};
434 spi_.transfer(tx, rx, 2);
436 return (
static_cast<uint16_t
>(rx[0]) << 8) | rx[1];
439template <
typename SpiType>
441uint16_t ADS7952<SpiType>::commonControlBits() const noexcept {
452 bits |=
static_cast<uint16_t
>(gpio_output_state_ & 0x0F);
457template <
typename SpiType>
459constexpr uint8_t ADS7952<SpiType>::popcount16(uint16_t x)
noexcept {
460 x = x - ((x >> 1) & 0x5555);
461 x = (x & 0x3333) + ((x >> 2) & 0x3333);
462 return static_cast<uint8_t
>((((x + (x >> 4)) & 0x0F0F) * 0x0101) >> 8);
Main driver class for the ADS7952 ADC.
constexpr uint8_t READ_ALL_MAX_EXTRA_FRAMES
constexpr uint16_t VoltageToCount(float voltage, float vref) noexcept
Convert a voltage to a 12-bit ADC count.
float CountToVoltage(uint16_t count) const noexcept
Convert raw count to voltage using the currently active reference.
ChannelReadings ReadAllChannels() noexcept
Read all channels in the current Auto-1 sequence.
void SetVref(float vref) noexcept
Update the Vref value for voltage calculations.
bool ProgramAuto2LastChannel(uint8_t last_channel) noexcept
Program the Auto-2 last channel.
void SetGPIOOutputs(uint8_t gpio_state) noexcept
Set GPIO output pin levels (for pins configured as outputs).
bool ProgramGPIO(const GPIOConfig &config) noexcept
Program GPIO pin functions, direction, and alarm routing.
bool ProgramAlarm(uint8_t channel, AlarmBound bound, uint16_t threshold_12bit) noexcept
Program an alarm threshold for a single channel (count-based).
bool ProgramAlarmVoltage(uint8_t channel, AlarmBound bound, float voltage) noexcept
Program an alarm threshold for a single channel (voltage-based).
void SetVA(float va) noexcept
Update the VA supply voltage value.
uint16_t VoltageToCount(float voltage) const noexcept
Convert a voltage to a 12-bit ADC count using the active reference.
bool SetPowerDown(PowerDown pd) noexcept
Set the power-down mode.
ReadResult ReadChannel(uint8_t channel) noexcept
Read a single ADC channel (switches to Manual mode).
bool EnterManualMode(uint8_t channel=0) noexcept
Enter Manual mode, selecting the given channel for conversion.
bool EnterAuto2Mode(bool reset_counter=true) noexcept
Enter Auto-2 mode (sequences channels 0 through last_channel).
bool EnterAuto1Mode(bool reset_counter=true) noexcept
Enter Auto-1 mode (sequences through programmed channel mask).
bool ProgramAuto1Channels(uint16_t channel_mask) noexcept
Program the Auto-1 channel sequence.
bool SetRange(Range range) noexcept
Set the input voltage range and update active reference.
bool EnsureInitialized(bool force=false) noexcept
Ensure the driver is initialized — idempotent, safe to call repeatedly.
ADS7952(SpiType &spi, float vref=ADS7952_CFG::DEFAULT_VREF, float va=ADS7952_CFG::DEFAULT_VA, Range initial_range=ADS7952_CFG::DEFAULT_RANGE) noexcept
Construct a new ADS7952 driver instance.
constexpr uint16_t ChannelSelect(uint8_t ch) noexcept
Encode manual-mode channel selection bits DI[10:7].
constexpr uint16_t Auto2LastChannel(uint8_t ch) noexcept
Encode Auto-2 last-channel field DI[9:6].
@ GPIO0_HighAndLowAlarm
GPIO0 = combined hi/lo alarm output.
@ GPIO0_HighAlarm
GPIO0 = high alarm output.
@ GPIO
Both as general-purpose I/O.
@ GPIO1_HighAlarm
GPIO1 = high alarm output.
@ GPIO1_LowAlarm_GPIO0_HighAlarm
GPIO1=low, GPIO0=high alarm.
@ PowerDown
Device enters power-down.
@ Auto2
Device sequences channels 0 to last_channel.
@ Auto1
Device sequences through programmed channel mask.
@ Manual
Host selects channel each frame.
@ TwoVref
0 to 2*Vref, clamped to VA (RANGE bit = 1)
@ High
High alarm threshold register.
@ InvalidChannel
Channel number out of range (0-11)
@ NotInitialized
Driver not initialized.
@ Timeout
Operation timed out waiting for data.
constexpr uint16_t EXIT_NEXT_FRAME
constexpr uint16_t Threshold12To10(uint16_t adc_12bit) noexcept
Convert 12-bit ADC threshold to 10-bit alarm register format.
constexpr uint16_t HIGH_REGISTER
constexpr uint16_t ChannelInGroup(uint8_t ch_in_group) noexcept
Encode alarm channel index within a 4-channel group.
constexpr uint16_t GPIO0_HI_ALARM
constexpr uint16_t RESET_ALL_REGS
constexpr uint16_t GPIO1_LO_GPIO0_HI_ALARM
constexpr uint16_t GPIO3_PWRDOWN_IN
constexpr uint16_t GPIO0_HI_LO_ALARM
constexpr uint16_t GPIO1_HI_ALARM
constexpr uint16_t GPIO2_RANGE_IN
constexpr uint16_t AUTO_1
constexpr uint16_t AUTO_1_PROG
constexpr uint16_t ALARM_GROUP_0
constexpr uint16_t ALARM_GROUP_1
constexpr uint16_t CONTINUE
constexpr uint16_t GPIO_PROG
constexpr uint16_t AUTO_2_PROG
constexpr uint16_t ALARM_GROUP_2
constexpr uint16_t MANUAL
constexpr uint16_t AUTO_2
constexpr uint8_t GetChannel(uint16_t frame) noexcept
Extract channel descriptor from response frame DO[15:12].
constexpr uint16_t GetData(uint16_t frame) noexcept
Extract conversion data from response frame DO[11:0].
constexpr uint16_t PROGRAM_RETAIN
constexpr uint16_t RANGE_2VREF
constexpr uint16_t NO_RESET_COUNTER
constexpr uint16_t PROGRAM_ENABLE
constexpr uint8_t NUM_CHANNELS
Number of ADC input channels.
constexpr uint16_t POWER_DOWN
constexpr uint16_t MAX_COUNT
Maximum 12-bit conversion value.
constexpr uint16_t RESET_COUNTER
constexpr uint8_t CHANNELS_PER_ALARM_GROUP
Channels per alarm group.
static constexpr uint8_t MAX_CHANNELS