40get_adc_2d_as_1d(
const int i_adc,
const int i_channel,
const WordType (&adc_matrix)[NWords])
43 static_assert(std::is_integral_v<WordType> && std::is_unsigned_v<WordType>,
44 "WordType must be an unsigned integral type");
46 constexpr int bits_per_word = std::numeric_limits<WordType>::digits;
48 static_assert(BitsPerADC > 0 && BitsPerADC <= bits_per_word);
49 static_assert(ADCSPerChannel * NChannels * BitsPerADC == NWords * bits_per_word);
51 if (i_channel < 0 || i_channel >= NChannels) {
52 throw std::out_of_range(
53 std::format(
"Requested channel of {} is out of channel range 0-{}", i_channel, NChannels - 1));
56 if (i_adc < 0 || i_adc >= ADCSPerChannel) {
57 throw std::out_of_range(std::format(
"Requested ADC index of {} if out of range 0-{}", i_adc, ADCSPerChannel - 1));
61 int i_abs = i_adc * NChannels + i_channel;
63 if constexpr (BitsPerADC == bits_per_word) {
64 return adc_matrix[i_abs];
68 int i_word = BitsPerADC * i_abs / bits_per_word;
69 assert(i_word < NWords);
72 int first_bit_position = (BitsPerADC * i_abs) % bits_per_word;
75 int bits_from_first_word = std::min(BitsPerADC, bits_per_word - first_bit_position);
77 WordType adc_val = adc_matrix[i_word] >> first_bit_position;
79 if (bits_from_first_word < BitsPerADC) {
80 assert(i_word < NWords - 1);
81 adc_val |= adc_matrix[i_word + 1] << bits_from_first_word;
85 return adc_val & ((
static_cast<WordType
>(1) << BitsPerADC) - 1);
94set_adc_2d_as_1d(
const int i_adc,
const int i_channel,
const WordType adc_val, WordType (&adc_matrix)[NWords])
96 static_assert(std::is_integral_v<WordType> && std::is_unsigned_v<WordType>,
97 "WordType must be an unsigned integral type");
99 constexpr int bits_per_word = std::numeric_limits<WordType>::digits;
101 static_assert(BitsPerADC > 0 && BitsPerADC <= bits_per_word);
102 static_assert(ADCSPerChannel * NChannels * BitsPerADC == NWords * bits_per_word);
104 if (i_channel < 0 || i_channel >= NChannels) {
105 throw std::out_of_range(
106 std::format(
"Requested channel of {} is out of channel range 0-{}", i_channel, NChannels - 1));
109 if (i_adc < 0 || i_adc >= ADCSPerChannel) {
110 throw std::out_of_range(std::format(
"Requested ADC index of {} is out of range 0-{}", i_adc, ADCSPerChannel - 1));
113 if constexpr (BitsPerADC < bits_per_word) {
114 if (adc_val >= (
static_cast<WordType
>(1) << BitsPerADC)) {
115 throw std::out_of_range(std::format(
116 "Requested ADC value of {} exceeds max value of {}", adc_val, (
static_cast<WordType
>(1) << BitsPerADC) - 1));
121 int i_abs = i_adc * NChannels + i_channel;
123 if constexpr (BitsPerADC == bits_per_word) {
124 adc_matrix[i_abs] = adc_val;
128 int i_word = BitsPerADC * i_abs / bits_per_word;
129 assert(i_word < NWords);
132 int first_bit_position = (BitsPerADC * i_abs) % bits_per_word;
135 int bits_in_first_word = std::min(BitsPerADC, bits_per_word - first_bit_position);
137 WordType mask = ((
static_cast<WordType
>(1) << bits_in_first_word) - 1) << first_bit_position;
139 adc_matrix[i_word] = (adc_matrix[i_word] & ~mask) | ((
static_cast<WordType
>(adc_val) << first_bit_position) & mask);
142 if (bits_in_first_word < BitsPerADC) {
143 assert(i_word < NWords - 1);
144 int bits_in_second_word = BitsPerADC - bits_in_first_word;
145 WordType mask2 = (
static_cast<WordType
>(1) << bits_in_second_word) - 1;
146 adc_matrix[i_word + 1] = (adc_matrix[i_word + 1] & ~mask2) | ((adc_val >> bits_in_first_word) & mask2);
195set_adc_1d(
const int i_adc, WordType adc_val, WordType (&adc_array)[NWords])
197 static_assert(std::is_integral_v<WordType> && std::is_unsigned_v<WordType>,
198 "WordType must be an unsigned integral type");
200 constexpr int bits_per_word = std::numeric_limits<WordType>::digits;
202 static_assert(BitsPerADC > 0 && BitsPerADC <= bits_per_word);
203 static_assert((NWords * bits_per_word) % BitsPerADC == 0);
205 constexpr int num_adcs = NWords * bits_per_word / BitsPerADC;