27 Serial.print(
"pin_nRESET = ");
63#ifdef NON_TEMPLATE_VERSION_FOR_START_AND_READ
78 constexpr int bit_length = 32;
81 for (
int i = 0; i < bit_length; i++ ) {
82 if ( value & (0x1 << i) )
104 if ( !timeout_count )
106 printf(
"DRDY signal wait timeout\r\n" );
115 :
AFE_base( spi_addr, hsv, nINT, DRDY, SYN, nRESET )
134 if ( hardware_reset )
145 constexpr uint16_t CHIP_READY = 1 << 13;
146 constexpr auto RETRY = 10;
148 for (
auto i = 0; i < RETRY; i++ )
155 Serial.println(
"NAFE13388 couldn't get ready. Check power supply or pin conections\r\n" );
165 for (
auto i = 0; i < 4; i++ )
168 const uint16_t setbit = 0x1 << ch;
171 if ( cc[ 0 ] & 0x0010 )
172 coeff_uV[ ch ] = ((10.0 / (double)(1L << 24)) /
pga_gain[ (cc[ 0 ] >> 5) & 0x7 ]) * 1e6;
174 coeff_uV[ ch ] = (4.0 / (double)(1L << 24)) * 1e6;
182 constexpr auto bit_length = 16;
186 for (
auto i = 0; i < bit_length; i++ )
188 if ( value & (0x1 << i) )
198 constexpr static double data_rates[] = { 288000, 192000, 144000, 96000, 72000, 48000, 36000, 24000,
199 18000, 12000, 9000, 6000, 4500, 3000, 2250, 1125,
200 562.5, 400, 300, 200, 100, 60, 50, 30,
201 25, 20, 15, 10, 7.5, };
202 constexpr static uint16_t delays[] = { 0, 2, 4, 6, 8, 10, 12, 14,
203 16, 18, 20, 28, 38, 40, 42, 56,
204 64, 76, 90, 128, 154, 178, 204, 224,
206 1024, 1664, 3276, 7680, 19200, 23040, };
213 uint8_t adc_data_rate = (ch_config1 >> 3) & 0x001F;
214 uint8_t adc_sinc = (ch_config1 >> 0) & 0x0007;
215 uint8_t
ch_delay = (ch_config2 >> 10) & 0x003F;
216 bool adc_normal_setting = (ch_config2 >> 9) & 0x0001;
217 bool ch_chop = (ch_config2 >> 7) & 0x0001;
219 double base_freq = data_rates[ adc_data_rate ];
220 double delay_setting = delays[
ch_delay ] / 4608000.00;
225 delay_setting /= 2.00;
228 if ( (28 < adc_data_rate) || (4 < adc_sinc) || ((adc_data_rate < 12) && (adc_sinc)) )
231 if ( !adc_normal_setting )
232 base_freq /= (adc_sinc + 1);
238 printf(
"base_freq = %lf\r\n", base_freq );
239 printf(
"delay_setting = %lf\r\n", delay_setting );
240 printf(
"total delay = %lf\r\n", (1 / base_freq) + delay_setting );
243 return (1 / base_freq) + delay_setting;
248 const ch_setting_t tmp_ch_config = { cc0, cc1, cc2, cc3 };
254 const uint16_t clearingbit = 0x1 << ch;
304 write_r16(
static_cast<uint16_t
>( r ), value );
309 write_r24(
static_cast<uint16_t
>( r ), value );
314 return read_r16(
static_cast<uint16_t
>( r ) );
319 return read_r24(
static_cast<uint16_t
>( r ) );
348 constexpr double pga1x_voltage = 5.0;
349 constexpr int adc_resolution = 24;
350 constexpr double pga_gain_setting = 0.2;
352 constexpr double fullscale_voltage = pga1x_voltage / pga_gain_setting;
354 double fullscale_data = pow( 2, (adc_resolution - 1) );
358 double dv_slope = ref_data_span / ref_voltage_span;
359 double custom_gain = dv_slope * (fullscale_voltage / fullscale_data);
360 double custom_offset = (dv_slope * ref.
low.
voltage - ref.
low.
data) / custom_gain;
364 int32_t gain_coeff_new = round( gain_coeff_cal * custom_gain );
365 int32_t offset_coeff_new = round( custom_offset - offsset_coeff_cal );
370 printf(
"gain_coeff_new = %8ld\r\n", gain_coeff_new );
371 printf(
"offset_coeff_new = %8ld\r\n", offset_coeff_new );
380 constexpr auto low_gain_index = 2;
381 auto channel_in_use =
false;
383 int gain_index =
static_cast<int>( pga_gain_index );
390 channel_in_use =
true;
394 for (
auto i = 0; i < 4; i++ )
402 bool low_gain = (gain_index <= low_gain_index);
404 input_select = low_gain ? 0x5 : 0x6;
408 printf(
"==== self-calibration for PGA gain setting: x%3.1lf\r\n",
pga_gain[ gain_index ] );
409 printf(
"gain = %s\r\n", low_gain ?
"low" :
"high" );
410 printf(
"REF%s = %10.8lfV\r\n", low_gain ?
"H" :
"L", reference_source_voltage );
417 const uint16_t REF_GND = 0x0011 | (gain_index << 5);
418 const uint16_t REF_V = (input_select << (use_positive_side ? 12 : 8)) | REF_GND;
419 const uint16_t REF_COM = 0x7700 | REF_GND;
420 const uint16_t ch_config1 = (gain_index << 12) | 0x00E4;
421 constexpr uint16_t ch_config2 = 0x8480;
422 constexpr uint16_t ch_config3 = 0x0000;
424 const ch_setting_t refh = { REF_V, ch_config1, ch_config2, ch_config3 };
425 const ch_setting_t refg = { REF_GND, ch_config1, ch_config2, ch_config3 };
426 const ch_setting_t refc = { REF_COM, ch_config1, ch_config2 & ~0x0080, ch_config3 };
430 constexpr raw_t default_gain_coeff_value = 0x1UL << 22;
431 constexpr raw_t default_offset_coeff_value = 0;
449 const double fullscale_voltage = 5.00 /
pga_gain[ gain_index ];
450 const double calibrated_gain = (double)(0x1UL << 23) * (reference_source_voltage / fullscale_voltage) / (
double)(data_REF - data_GND);
453 printf(
"data_REF = %8ld (%lfV)\r\n", data_REF,
raw2v( channel_selection, data_REF ) );
454 printf(
"data_GND = %8ld (%lfmV)\r\n", data_GND,
raw2mv( channel_selection, data_GND ) );
455 printf(
"data_COM = %8ld (%lfmV)\r\n", data_COM,
raw2mv( channel_selection, data_COM ) );
456 printf(
"gain adjustment = %8lf (%lfdB)\r\n\r\n", calibrated_gain, 20 * log10( calibrated_gain ) );
459 if ( !( (0.95 < calibrated_gain) && (calibrated_gain < 1.05) ) )
462 const double offset_mv =
raw2mv( channel_selection, data_COM );
464 if ( !( (-10.0 < offset_mv) && (offset_mv < 10.0) ) )
474 if ( channel_in_use )
511 uint16_t pattern[] = {
512 0x8000, 0x0040, 0x0100, 0x0080, 0x0200, 0x0400, 0x0800, 0x1000,
513 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0080,
520 for (
auto j = 0; j < 2; j++ )
522 for (
auto i = 0U; i <
sizeof( pattern ) /
sizeof( uint16_t ); i++ )
531 for (
auto j = 0; j < 4; j++ )
533 for (
auto i = 0; i < 10; i++ )
535 pv = (j % 2) ? pv & ~pattern[ i ] : pv | pattern[ i ];
AFE_base(bool spi_addr, bool highspeed_variant, int nINT, int DRDY, int SYN, int nRESET)
static constexpr uint32_t timeout_limit
static void DRDY_cb(void)
void default_drdy_cb(void)
double raw2mv(int ch, raw_t value)
virtual void reset(bool hardware_reset=false)=0
int bit_count(uint32_t value)
virtual raw_t start_and_read(int ch)
virtual void start(void)=0
int wait_conversion_complete(double delay=-1.0)
static double delay_accuracy
virtual void boot(void)=0
virtual raw_t read(int ch)=0
double raw2v(int ch, raw_t value)
virtual void start_continuous_conversion()
NAFE13388_Base(bool spi_addr, bool highspeed_variant, int nINT, int DRDY, int SYN, int nRESET)
void gain_offset_coeff(const ref_points &ref)
double calc_delay(int ch)
virtual void command(uint16_t com)
virtual raw_t read(int ch)
uint32_t bit_op(T rg, uint32_t mask, uint32_t value)
int self_calibrate(int pga_gain_index, int channel_selection=15, int input_select=0, double reference_source_voltage=0, bool use_positive_side=true)
struct NAFE13388_Base::_ref_points ref_points
virtual void reg(Register16 r, uint16_t value)
uint8_t revision_number(void)
virtual void close_logical_channel(void)
virtual void DRDY_by_sequencer_done(bool flag=true)
uint64_t serial_number(void)
void channel_info_update(uint16_t value)
virtual ~NAFE13388_Base()
virtual void reset(bool hardware_reset=false)
uint32_t part_number(void)
virtual void open_logical_channel(int ch, uint16_t cc0, uint16_t cc1, uint16_t cc2, uint16_t cc3)
NAFE13388_UIM(bool spi_addr=0, bool highspeed_variant=false, int nINT=3, int DRDY=4, int SYN=6, int nRESET=7)
NAFE13388(bool spi_addr=0, bool highspeed_variant=false, int nINT=2, int DRDY=3, int SYN=5, int nRESET=6)
int32_t read_r24(uint16_t reg)
void write_r24(uint16_t reg, uint32_t val)
uint16_t read_r16(uint16_t reg)
void burst(uint32_t *data, int length, int width=3)
void write_r16(uint16_t reg)