Fixed osr calculation. Added DC block. With OSR = 512, sps = 8k, however noise is higher with values swinging wildly
This commit is contained in:
parent
d69d0b5dfb
commit
a43256ac5e
@ -11,6 +11,15 @@
|
|||||||
|
|
||||||
// using namespace esphome::spi;
|
// using namespace esphome::spi;
|
||||||
|
|
||||||
|
/*
|
||||||
|
//https://github.com/espressif/esp-idf/blob/v6.0.1/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c
|
||||||
|
//Allocate memory for the pixel buffers
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), mem_cap);
|
||||||
|
assert(lines[i] != NULL);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ads131m08 {
|
namespace ads131m08 {
|
||||||
|
|
||||||
@ -100,10 +109,8 @@ void ADS131M08Hub::dump_config() {
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGCONFIG(TAG, " Clock frequency: %.3fMHz", this->clock_frequency_ / 1000000);
|
ESP_LOGCONFIG(TAG, " Clock frequency: %.3fMHz", this->clock_frequency_ / 1000000);
|
||||||
}
|
}
|
||||||
uint16_t osr = 1 << (7 + this->osr_);
|
uint16_t osr = convert_adc_osr_to_value(this->osr_);
|
||||||
if (osr == 16384) {
|
|
||||||
osr = 16256;
|
|
||||||
}
|
|
||||||
ESP_LOGCONFIG(TAG, " Oversampling ratio: %" PRId32, osr);
|
ESP_LOGCONFIG(TAG, " Oversampling ratio: %" PRId32, osr);
|
||||||
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
|
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
|
||||||
ESP_LOGCONFIG(TAG, " SPI Mode: %d", this->mode_);
|
ESP_LOGCONFIG(TAG, " SPI Mode: %d", this->mode_);
|
||||||
@ -158,19 +165,19 @@ float ADS131M08Hub::update_conversion_factor() {
|
|||||||
bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
||||||
this->adc_init_++;
|
this->adc_init_++;
|
||||||
update_adc_word_length();
|
update_adc_word_length();
|
||||||
if (!adc_register_write(REG_CLOCK, reg_clock_allch_off)) {
|
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off | this->osr_ << 2), __LINE__)) {
|
||||||
ESP_LOGE(TAG, "CLOCK register write / read to turn off all channels failed");
|
ESP_LOGE(TAG, "CLOCK register write / read to turn off all channels failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "Turned off all channels so short frames can be written during config");
|
ESP_LOGV(TAG, "Turned off all channels so short frames can be written during config");
|
||||||
|
|
||||||
if (!adc_register_write(REG_MODE, MODE_MASK_RESET_HAPPENED & reg_mode_cfg24)) {
|
if (!adc_register_write(REG_MODE, MODE_MASK_RESET_HAPPENED & reg_mode_cfg24, __LINE__)) {
|
||||||
ESP_LOGE(TAG, "MODE register write / read to set word size to 24bits failed");
|
ESP_LOGE(TAG, "MODE register write / read to set word size to 24bits failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "Written MODE register; Cleared the RESET flag, made DRDY active low pulse");
|
ESP_LOGV(TAG, "Written MODE register; Cleared the RESET flag, made DRDY active low pulse");
|
||||||
|
|
||||||
if (!adc_register_write(REG_THRSHLD_LSB, 0x09)) {
|
if (!adc_register_write(REG_THRSHLD_LSB, 0x09, __LINE__)) {
|
||||||
ESP_LOGE(TAG, "THRSHLD_LSB register write / read to set DBLOCK filter failed");
|
ESP_LOGE(TAG, "THRSHLD_LSB register write / read to set DBLOCK filter failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -179,7 +186,7 @@ bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
|||||||
if (!adc_set_word_length(word_length))
|
if (!adc_set_word_length(word_length))
|
||||||
return false;
|
return false;
|
||||||
// we leave should channels off, as the individual sensors should turn it on
|
// we leave should channels off, as the individual sensors should turn it on
|
||||||
if (!adc_register_write(REG_CLOCK, reg_clock_allch_off)) {
|
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off | this->osr_ << 2), __LINE__)) {
|
||||||
ESP_LOGE(TAG, "CLOCK register write / read to turn-off all channels failed");
|
ESP_LOGE(TAG, "CLOCK register write / read to turn-off all channels failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,20 +199,44 @@ bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ADS131M08Hub::adc_restore_registers() {
|
||||||
|
uint8_t start_addr = REG_MODE;
|
||||||
|
uint16_str stored_regs(MAX_FRAME_SIZE - 2, 0);
|
||||||
|
bool success = true;
|
||||||
|
int j = 0;
|
||||||
|
success = adc_register_write(start_addr, settings.data[j], __LINE__, false);
|
||||||
|
j++;
|
||||||
|
start_addr++;
|
||||||
|
while(success && (j < sizeof(settings.data))) {
|
||||||
|
int i = 0;
|
||||||
|
stored_regs.resize(MAX_FRAME_SIZE - 2);
|
||||||
|
while((i < MAX_FRAME_SIZE - 2) && (j < sizeof(settings.data))) {
|
||||||
|
stored_regs[i++] = settings.data[j++];
|
||||||
|
}
|
||||||
|
stored_regs.resize(i);
|
||||||
|
success = adc_register_write(start_addr, stored_regs, __LINE__, false);
|
||||||
|
ESP_LOGD(TAG, "start_addr: %02X i: %02X", start_addr, i);
|
||||||
|
start_addr += i;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::adc_set_word_length(uint8_t word_length) {
|
bool ADS131M08Hub::adc_set_word_length(uint8_t word_length) {
|
||||||
uint16_t setting;
|
uint16_t value;
|
||||||
switch (word_length) {
|
switch (word_length) {
|
||||||
case 32:
|
case 32:
|
||||||
setting = reg_mode_cfg32;
|
value = reg_mode_cfg32;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
setting = reg_mode_cfg16;
|
value = reg_mode_cfg16;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setting = reg_mode_cfg24;
|
value = reg_mode_cfg24;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!adc_register_write_masked(REG_MODE, setting, reg_mode_cfg_mask, __LINE__)) {
|
uint16_t mask = reg_mode_cfg_mask;
|
||||||
|
//ESP_LOGD(TAG, "WL: %d stored value: %04X / %04X new value: %04X masked value %04X mask: %04X", word_length, this->settings.reg.mode, this->settings.data[REG_MODE-2], value, value & mask, mask );
|
||||||
|
if (!adc_register_write_masked(REG_MODE, value, mask, __LINE__)) {
|
||||||
ESP_LOGE(TAG, "MODE register write / read to set word size to %ubits failed", word_length);
|
ESP_LOGE(TAG, "MODE register write / read to set word size to %ubits failed", word_length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -269,8 +300,8 @@ void ADS131M08Hub::loop()
|
|||||||
{
|
{
|
||||||
CHIP_SELECTx
|
CHIP_SELECTx
|
||||||
uint64_t start = micros();
|
uint64_t start = micros();
|
||||||
this->txf_init(); // implementing datasheet recommended TXF init
|
///this->txf_init(); // implementing datasheet recommended TXF init
|
||||||
//this->adc_sync();
|
this->adc_sync();
|
||||||
if (rms_calc_req_) {
|
if (rms_calc_req_) {
|
||||||
float_str result = read_multi();
|
float_str result = read_multi();
|
||||||
num_samples = result[0];
|
num_samples = result[0];
|
||||||
@ -449,28 +480,54 @@ int32_t ADS131M08Hub::get_sign_ext_frame_word(const spiframe &frame, int w_index
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADS131M08Hub::adc_hard_reset() {
|
uint32_t ADS131M08Hub::adc_hard_reset() {
|
||||||
float cycle_micros = 1000000 / this->clock_frequency_; // one cycle duration in micro seconds
|
uint32_t pulse_duration = convert_adc_clock_cycles_to_micros(2150);
|
||||||
uint32_t reset_pulse_duration = static_cast<uint32_t>(
|
|
||||||
1.05 * 2048 * cycle_micros); // 2048 clock cycles converted to microseconds, multiplied by 1.05 to ensure we meet
|
|
||||||
// the minimum pulse duration requirement
|
|
||||||
if (reset_pulse_duration < 1) {
|
|
||||||
reset_pulse_duration = 1; // set it to 1 microsecond
|
|
||||||
}
|
|
||||||
sync_reset_pin_->digital_write(false); // Pull SYNC/RESET pin low to reset the ADC
|
sync_reset_pin_->digital_write(false); // Pull SYNC/RESET pin low to reset the ADC
|
||||||
delay_microseconds_safe(reset_pulse_duration); // Hold reset for the calculated duration
|
delay_microseconds_safe(pulse_duration); // Hold reset for the calculated duration
|
||||||
sync_reset_pin_->digital_write(true); // Set SYNC/RESET pin high to allow normal operation
|
sync_reset_pin_->digital_write(true); // Set SYNC/RESET pin high to allow normal operation
|
||||||
|
return convert_adc_clock_cycles_to_micros(T_SETTLE_OSR1024);
|
||||||
}
|
}
|
||||||
void ADS131M08Hub::adc_sync() {
|
|
||||||
float cycle_micros = 1000000 / this->clock_frequency_; // one cycle duration in micro seconds
|
uint32_t ADS131M08Hub::adc_sync() {
|
||||||
uint32_t sync_pulse_duration =
|
uint32_t pulse_duration = convert_adc_clock_cycles_to_micros(50);
|
||||||
static_cast<uint32_t>(std::round(50 * cycle_micros)); // minimum is 1/clock freq, max = 2047/clock freq
|
|
||||||
if (sync_pulse_duration < 1) {
|
|
||||||
sync_pulse_duration = 1; // set it to 1 microsecond
|
|
||||||
}
|
|
||||||
sync_reset_pin_->digital_write(false); // Pull SYNC/RESET pin low to sync the ADC
|
sync_reset_pin_->digital_write(false); // Pull SYNC/RESET pin low to sync the ADC
|
||||||
delay_microseconds_safe(sync_pulse_duration); // Hold sync for the calculated duration
|
delay_microseconds_safe(pulse_duration); // Hold sync for the calculated duration
|
||||||
sync_reset_pin_->digital_write(true); // Set SYNC/RESET pin high to allow normal operation
|
sync_reset_pin_->digital_write(true); // Set SYNC/RESET pin high to allow normal operation
|
||||||
|
return get_filter_settling_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ADS131M08Hub::get_filter_settling_time() {
|
||||||
|
uint16_t cycles = T_SETTLE_OSR16384;
|
||||||
|
switch(this->osr_) {
|
||||||
|
case OSR_128:
|
||||||
|
cycles = T_SETTLE_OSR128;
|
||||||
|
break;
|
||||||
|
case OSR_256:
|
||||||
|
cycles = T_SETTLE_OSR256;
|
||||||
|
break;
|
||||||
|
case OSR_512:
|
||||||
|
cycles = T_SETTLE_OSR512;
|
||||||
|
break;
|
||||||
|
case OSR_1024:
|
||||||
|
cycles = T_SETTLE_OSR1024;
|
||||||
|
break;
|
||||||
|
case OSR_2048:
|
||||||
|
cycles = T_SETTLE_OSR2048;
|
||||||
|
break;
|
||||||
|
case OSR_4096:
|
||||||
|
cycles = T_SETTLE_OSR4096;
|
||||||
|
break;
|
||||||
|
case OSR_8192:
|
||||||
|
cycles = T_SETTLE_OSR8192;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return convert_adc_clock_cycles_to_micros(cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ADS131M08Hub::convert_adc_clock_cycles_to_micros(uint32_t cycles)
|
||||||
|
{
|
||||||
|
float cycle_micros = 1000000 / this->clock_frequency_; // one cycle duration in micro seconds
|
||||||
|
return 1 + static_cast<uint32_t>(std::round(cycle_micros * cycles));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************** from datasheet ************************
|
// ********************** from datasheet ************************
|
||||||
@ -496,7 +553,7 @@ bool ADS131M08Hub::adc_reset_retry() {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < sizeof(retry_wordlengths) && !reset_ok) {
|
while (i < sizeof(retry_wordlengths) && !reset_ok) {
|
||||||
adc_word_length_ = retry_wordlengths[i];
|
adc_word_length_ = retry_wordlengths[i];
|
||||||
// ESP_LOGW(TAG, "ADC word length: %d", adc_word_length_);
|
ESP_LOGW(TAG, "ADC word length: %d", adc_word_length_);
|
||||||
reset_ok = adc_soft_reset();
|
reset_ok = adc_soft_reset();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -506,7 +563,7 @@ bool ADS131M08Hub::adc_reset_retry() {
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (i < sizeof(retry_wordlengths) && !reset_ok) {
|
while (i < sizeof(retry_wordlengths) && !reset_ok) {
|
||||||
adc_word_length_ = retry_wordlengths[i];
|
adc_word_length_ = retry_wordlengths[i];
|
||||||
// ESP_LOGW(TAG, "ADC word length: %d", adc_word_length_);
|
ESP_LOGW(TAG, "ADC word length: %d", adc_word_length_);
|
||||||
reset_ok = adc_soft_reset();
|
reset_ok = adc_soft_reset();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -690,6 +747,7 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
uint16_t drdy_status, status;
|
uint16_t drdy_status, status;
|
||||||
int i, iteration = 0;
|
int i, iteration = 0;
|
||||||
uint32_t elapsed_time = 0;
|
uint32_t elapsed_time = 0;
|
||||||
|
uint32_t sample_time = this->sample_time_;
|
||||||
uint32_t loop_start_time = micros();
|
uint32_t loop_start_time = micros();
|
||||||
int word_nbytes = adc_word_length_ >> 3;
|
int word_nbytes = adc_word_length_ >> 3;
|
||||||
int frame_length = numFrameWords * word_nbytes;
|
int frame_length = numFrameWords * word_nbytes;
|
||||||
@ -703,8 +761,8 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
sample_sum_[i] = 0;
|
sample_sum_[i] = 0;
|
||||||
sample_squared_sum_[i] = 0;
|
sample_squared_sum_[i] = 0;
|
||||||
}
|
}
|
||||||
|
uint32_t settling_end_time = loop_start_time;
|
||||||
while ((elapsed_time < this->sample_time_) && (iteration++ < 1000)) {
|
while ((elapsed_time < sample_time) && (iteration++ < 1000)) {
|
||||||
result[2] = iteration;
|
result[2] = iteration;
|
||||||
setup_frame(rx_frame, numFrameWords);
|
setup_frame(rx_frame, numFrameWords);
|
||||||
this->transfer_array(rx_frame);
|
this->transfer_array(rx_frame);
|
||||||
@ -715,7 +773,17 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
update_adc_word_length(status);
|
update_adc_word_length(status);
|
||||||
crc_ok = check_crc(rx_frame);
|
crc_ok = check_crc(rx_frame);
|
||||||
if (crc_ok) {
|
if (crc_ok) {
|
||||||
// skip frame immediately afte resync
|
if(status & MASK_STATUS_RESET) {
|
||||||
|
adc_reset_retry();
|
||||||
|
adc_restore_registers();
|
||||||
|
ESP_LOGW(TAG, "Mid data-read reset detected; restored registers");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(status & MASK_STATUS_RESYNC) {
|
||||||
|
settling_end_time = elapsed_time + get_filter_settling_time() + 50; // add 50us for good measure
|
||||||
|
}
|
||||||
|
if(elapsed_time > settling_end_time) {
|
||||||
if ((status & MASK_STATUS_RESYNC) == 0) {
|
if ((status & MASK_STATUS_RESYNC) == 0) {
|
||||||
drdy_status = status & MASK_STATUS_DRDY;
|
drdy_status = status & MASK_STATUS_DRDY;
|
||||||
// sample channels
|
// sample channels
|
||||||
@ -747,7 +815,10 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
result[1]++;
|
result[1]++;
|
||||||
// ESP_LOGW(TAG, "iteration: %d, frame: %s CRC error", iteration, frame_to_string(frame).c_str());
|
// ESP_LOGW(TAG, "iteration: %d, frame: %s CRC error", iteration, frame_to_string(frame).c_str());
|
||||||
}
|
}
|
||||||
@ -917,9 +988,19 @@ bool ADS131M08Hub::adc_register_write_masked(uint8_t address, uint16_t value, ui
|
|||||||
}
|
}
|
||||||
// ESP_LOGW(TAG, "1: reg contents: 0x%04X, address: 0x%02X, value: 0x%04X, mask: 0x%04X, caller: %d",
|
// ESP_LOGW(TAG, "1: reg contents: 0x%04X, address: 0x%02X, value: 0x%04X, mask: 0x%04X, caller: %d",
|
||||||
// reg_contents[0],address, value,mask, line );
|
// reg_contents[0],address, value,mask, line );
|
||||||
reg_contents[0] = (reg_contents[0] & ~mask) | (value & mask);
|
auto new_value = (reg_contents[0] & ~mask) | (value & mask);
|
||||||
// ESP_LOGW(TAG, "After applying mask - reg contents: 0x%04X, caller: %d", reg_contents[0], line );
|
if(new_value == reg_contents[0]) {
|
||||||
return adc_register_write(address, reg_contents);
|
ESP_LOGW(TAG, "1: No update needed. reg: %02X data: %04X / %04X Line: %d", address, value, new_value, line);
|
||||||
|
int bup_index = address - REG_MODE;
|
||||||
|
ESP_LOGW(TAG, "Storing: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), value, settings.data[bup_index], line);
|
||||||
|
// we backup data irrespective
|
||||||
|
settings.data[bup_index] = value;
|
||||||
|
return true; // no need for an adc reg update
|
||||||
|
}
|
||||||
|
reg_contents[0] = new_value;
|
||||||
|
//ESP_LOGW(TAG, "After applying mask - reg contents: 0x%04X, caller: %d", reg_contents[0], line );
|
||||||
|
//ESP_LOGD(TAG, "adc_register_write_masked: address: %02X value: %04X reg_contents: %04X mask: %04X new value: %04X Line:%d", address, value, reg_contents[0], mask, new_value, line);
|
||||||
|
return adc_register_write(address, reg_contents, line);
|
||||||
}
|
}
|
||||||
/// @brief
|
/// @brief
|
||||||
/// @param start_address - first register address
|
/// @param start_address - first register address
|
||||||
@ -943,34 +1024,54 @@ bool ADS131M08Hub::adc_register_write_masked(uint8_t start_address, const uint16
|
|||||||
ESP_LOGW(TAG, "No contents read from adc. Expected %d values. Register write aborted.", nregs);
|
ESP_LOGW(TAG, "No contents read from adc. Expected %d values. Register write aborted.", nregs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool update_required = false;
|
||||||
for (int i = 0; i < nregs; i++) {
|
for (int i = 0; i < nregs; i++) {
|
||||||
// ESP_LOGW(TAG, "Before change %d: reg contents: 0x%04X, address: 0x%02X, value: 0x%04X, mask: 0x%04X, caller: %d",
|
//ESP_LOGW(TAG, "Before change %d: reg contents: 0x%04X, address: 0x%02X, value: 0x%04X, mask: 0x%04X, caller: %d",
|
||||||
// i, reg_contents[i], start_address + i, values[i], masks[i], line);
|
// i, reg_contents[i], start_address + i, values[i], masks[i], line);
|
||||||
reg_contents[i] = (reg_contents[i] & ~masks[i]) | (values[i] & masks[i]);
|
auto new_value = (reg_contents[i] & ~masks[i]) | (values[i] & masks[i]);
|
||||||
// ESP_LOGW(TAG, "After applying mask - reg contents: 0x%04X, caller: %d", reg_contents[i], line);
|
if(reg_contents[i] != new_value)
|
||||||
|
update_required = true;
|
||||||
|
reg_contents[i] = new_value;
|
||||||
|
//ESP_LOGW(TAG, "After applying mask - reg contents: 0x%04X, caller: %d", reg_contents[i], line);
|
||||||
}
|
}
|
||||||
return adc_register_write(start_address, reg_contents);
|
if(!update_required) {
|
||||||
|
ESP_LOGW(TAG, "2: No update needed. start reg: %02X first data: %04X Line: %d", start_address, values[0], line);
|
||||||
|
// we backup data irrespective
|
||||||
|
int bup_index = start_address - REG_MODE;
|
||||||
|
for(auto i = values.begin(); i != values.end(); i++) {
|
||||||
|
ESP_LOGW(TAG, "Storing: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), *i, settings.data[bup_index], line);
|
||||||
|
settings.data[bup_index++] = *i;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return adc_register_write(start_address, reg_contents, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::adc_register_write(uint16_t address, uint16_t data) {
|
bool ADS131M08Hub::adc_register_write(uint16_t address, uint16_t data, int line, bool backup_data) {
|
||||||
uint16_str arg;
|
uint16_str arg;
|
||||||
arg += data;
|
arg += data;
|
||||||
return adc_register_write(address, arg);
|
return adc_register_write(address, arg, line, backup_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &data, int line, bool backup_data) {
|
||||||
//https://github.com/espressif/esp-idf/blob/v6.0.1/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c
|
|
||||||
//Allocate memory for the pixel buffers
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), mem_cap);
|
|
||||||
assert(lines[i] != NULL);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &data) {
|
|
||||||
int nregs = data.size();
|
int nregs = data.size();
|
||||||
if (nregs == 0) {
|
if (nregs == 0) {
|
||||||
return false; // invalid
|
return false; // invalid
|
||||||
}
|
}
|
||||||
|
if(backup_data) {
|
||||||
|
int bup_index = start_address - REG_MODE;
|
||||||
|
for(auto i = data.begin(); i != data.end(); i++) {
|
||||||
|
ESP_LOGW(TAG, "Storing: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), *i, settings.data[bup_index], line);
|
||||||
|
settings.data[bup_index++] = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int bup_index = start_address - REG_MODE;
|
||||||
|
for(auto i = data.begin(); i != data.end(); i++) {
|
||||||
|
ESP_LOGD(TAG, "Restoring: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), *i, settings.data[bup_index], line);
|
||||||
|
bup_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
int wreg_nwords = 2 + nregs; // ensure room for crc
|
int wreg_nwords = 2 + nregs; // ensure room for crc
|
||||||
int rreg_resp_framelength = 2 + (nregs == 1 ? -1 : nregs); // add room for CRC if nregs > 1
|
int rreg_resp_framelength = 2 + (nregs == 1 ? -1 : nregs); // add room for CRC if nregs > 1
|
||||||
//spiframe frame(wreg_nwords, 0);
|
//spiframe frame(wreg_nwords, 0);
|
||||||
@ -1010,7 +1111,7 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
|||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recommended not to read more than 20 registers at a time
|
// recommended not to read more than 8 registers at a time
|
||||||
uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) {
|
uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) {
|
||||||
uint16_str result;
|
uint16_str result;
|
||||||
if (nregs == 0) {
|
if (nregs == 0) {
|
||||||
@ -1045,6 +1146,7 @@ uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) {
|
|||||||
if (nregs > 1) {
|
if (nregs > 1) {
|
||||||
bool crc_ok = check_crc(rx_frame);
|
bool crc_ok = check_crc(rx_frame);
|
||||||
if (!crc_ok) {
|
if (!crc_ok) {
|
||||||
|
ESP_LOGD(TAG, "Recv Frame: %s", frame_to_string(rx_frame).c_str());
|
||||||
ESP_LOGW(TAG, "CRC failed reading ADC registers!");
|
ESP_LOGW(TAG, "CRC failed reading ADC registers!");
|
||||||
result.clear();
|
result.clear();
|
||||||
return result; // invalid
|
return result; // invalid
|
||||||
@ -1070,28 +1172,46 @@ uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_reg_osr() {
|
bool ADS131M08Hub::set_reg_osr() {
|
||||||
uint16_t osr = 3; // default
|
uint16_t mask = MASK_CLOCK_OSR;
|
||||||
if (this->osr_ <= 16256 && this->osr_ >= 128) {
|
uint16_t value = this->osr_ << 2;
|
||||||
if (this->osr_ == 16256)
|
// ESP_LOGD(TAG, "adc_register_write_masked(REG_CLOCK=%02X, value=%04X, mask=%04X, __LINE__)", REG_CLOCK,
|
||||||
osr = 7;
|
// value, mask);
|
||||||
|
//this->settings.reg.clock = value & mask;
|
||||||
|
return adc_register_write_masked(REG_CLOCK, value, mask, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ADS131M08Hub::convert_value_to_adc_osr(uint16_t osr_value) {
|
||||||
|
uint16_t adc_osr = OSR_1024; // default
|
||||||
|
if (osr_value <= 16256 && osr_value >= 128) {
|
||||||
|
if (osr_value == 16256)
|
||||||
|
adc_osr = OSR_16256;
|
||||||
else {
|
else {
|
||||||
osr = 0;
|
adc_osr = OSR_128;
|
||||||
auto tmp = this->osr_ / 128;
|
auto tmp = osr_value / 128;
|
||||||
while (tmp >>= 1)
|
while (tmp >>= 1)
|
||||||
osr++;
|
adc_osr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return adc_register_write_masked(REG_CLOCK, osr << 2, MASK_CLOCK_OSR, __LINE__);
|
return adc_osr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ADS131M08Hub::convert_adc_osr_to_value(uint16_t adc_osr) {
|
||||||
|
uint16_t osr_value = 1 << (7 + adc_osr);
|
||||||
|
if (osr_value == 16384) {
|
||||||
|
osr_value = 16256;
|
||||||
|
}
|
||||||
|
return osr_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_enable(uint8_t channel, bool enable) {
|
bool ADS131M08Hub::set_channel_enable(uint8_t channel, bool enable) {
|
||||||
if (channel >= ADC_CHANNELS)
|
if (channel >= ADC_CHANNELS)
|
||||||
return false;
|
return false;
|
||||||
uint16_t enable_mask = MASK_CLOCK_CH0 << channel;
|
uint16_t mask = MASK_CLOCK_CH0 << channel;
|
||||||
uint16_t reg_value = (enable) ? enable_mask : 0;
|
uint16_t value = (enable) ? mask : 0;
|
||||||
// ESP_LOGD(TAG, "adc_register_write_masked(REG_CLOCK=%02X, reg_value=%04X, enable_mask=%04X, __LINE__)", REG_CLOCK,
|
// ESP_LOGD(TAG, "adc_register_write_masked(REG_CLOCK=%02X, value=%04X, mask=%04X, __LINE__)", REG_CLOCK,
|
||||||
// reg_value, enable_mask);
|
// value, mask);
|
||||||
return adc_register_write_masked(REG_CLOCK, reg_value, enable_mask, __LINE__);
|
//this->settings.reg.clock = value & mask;
|
||||||
|
return adc_register_write_masked(REG_CLOCK, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_gain(uint8_t channel, uint8_t gain) {
|
bool ADS131M08Hub::set_channel_gain(uint8_t channel, uint8_t gain) {
|
||||||
@ -1101,16 +1221,26 @@ bool ADS131M08Hub::set_channel_gain(uint8_t channel, uint8_t gain) {
|
|||||||
uint8_t shift = (channel % 4) << 2;
|
uint8_t shift = (channel % 4) << 2;
|
||||||
uint16_t mask = MASK_GAIN_PGAGAIN0 << shift;
|
uint16_t mask = MASK_GAIN_PGAGAIN0 << shift;
|
||||||
uint16_t value = gain << shift;
|
uint16_t value = gain << shift;
|
||||||
|
//if(reg == REG_GAIN1)
|
||||||
|
//this->settings.reg.gain1 = value & mask;
|
||||||
|
//else
|
||||||
|
//this->settings.reg.gain2 = value & mask;
|
||||||
// ESP_LOGW(TAG, "Ch%d: Set Gain: reg: %02X pga: %04X mask: %04X ", channel, reg, value, mask);
|
// ESP_LOGW(TAG, "Ch%d: Set Gain: reg: %02X pga: %04X mask: %04X ", channel, reg, value, mask);
|
||||||
return adc_register_write_masked(reg, value, mask, __LINE__);
|
return adc_register_write_masked(reg, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADS131M08Hub::set_global_chop(uint16_t global_chop) {
|
bool ADS131M08Hub::set_global_chop(uint16_t global_chop) {
|
||||||
adc_register_write_masked(REG_CFG, global_chop << 8, MASK_CFG_GC_EN, __LINE__);
|
uint16_t mask = MASK_CFG_GC_EN;
|
||||||
|
uint16_t value = global_chop << 8;
|
||||||
|
//this->settings.reg.cfg = value & mask;
|
||||||
|
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADS131M08Hub::set_global_chop_delay(uint16_t delay) {
|
bool ADS131M08Hub::set_global_chop_delay(uint16_t delay) {
|
||||||
adc_register_write_masked(REG_CFG, delay << 9, MASK_CFG_GC_DLY, __LINE__);
|
uint16_t mask = MASK_CFG_GC_DLY;
|
||||||
|
uint16_t value = delay << 9;
|
||||||
|
//this->settings.reg.cfg = value & mask;
|
||||||
|
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_phase_calibration(uint8_t channel, int16_t phase_offset) {
|
bool ADS131M08Hub::set_channel_phase_calibration(uint8_t channel, int16_t phase_offset) {
|
||||||
@ -1119,22 +1249,31 @@ bool ADS131M08Hub::set_channel_phase_calibration(uint8_t channel, int16_t phase_
|
|||||||
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
||||||
if (phase_offset < -512 || phase_offset > 511)
|
if (phase_offset < -512 || phase_offset > 511)
|
||||||
return false;
|
return false;
|
||||||
return adc_register_write_masked(reg_addr, (phase_offset << 6), MASK_CHX_CFG_PHASE, __LINE__);
|
uint16_t mask = MASK_CHX_CFG_PHASE;
|
||||||
|
uint16_t value = phase_offset << 6;
|
||||||
|
////this->settings.reg.chan[channel].ch_cfg = value & mask;
|
||||||
|
return adc_register_write_masked(reg_addr, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_dcblock_filter_disable(uint8_t channel, bool disable) {
|
bool ADS131M08Hub::set_dcblock_filter_disable(uint8_t channel, bool disable) {
|
||||||
if (channel > 7)
|
if (channel > 7)
|
||||||
return false;
|
return false;
|
||||||
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
||||||
uint16_t reg_value = (disable) ? MASK_CHX_CFG_DCBLKX_DIS : 0;
|
uint16_t mask = MASK_CHX_CFG_DCBLKX_DIS;
|
||||||
return adc_register_write_masked(reg_addr, reg_value, MASK_CHX_CFG_DCBLKX_DIS, __LINE__);
|
uint16_t value = (disable) ? mask : 0;
|
||||||
|
////this->settings.reg.chan[channel].ch_cfg = value & mask;
|
||||||
|
ESP_LOGI(TAG, "Setting DC BLOCK of Ch%d reg:%02X to %s [%04X]", channel, reg_addr, (disable ? "disable" : "enable"), value);
|
||||||
|
return adc_register_write_masked(reg_addr, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_input_selection(uint8_t channel, ADC_INPUT_CHANNEL_MUX input) {
|
bool ADS131M08Hub::set_channel_input_selection(uint8_t channel, ADC_INPUT_CHANNEL_MUX input) {
|
||||||
if (channel > 7)
|
if (channel > 7)
|
||||||
return false;
|
return false;
|
||||||
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
uint16_t reg_addr = 5 * channel + REG_CH0_CFG;
|
||||||
return adc_register_write_masked(reg_addr, input, MASK_CHX_CFG_MUX, __LINE__);
|
uint16_t mask = MASK_CHX_CFG_MUX;
|
||||||
|
uint16_t value = input;
|
||||||
|
////this->settings.reg.chan[channel].ch_cfg = value & mask;
|
||||||
|
return adc_register_write_masked(reg_addr, value, mask, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_offset_calibration(uint8_t channel, int32_t offset) {
|
bool ADS131M08Hub::set_channel_offset_calibration(uint8_t channel, int32_t offset) {
|
||||||
@ -1142,11 +1281,15 @@ bool ADS131M08Hub::set_channel_offset_calibration(uint8_t channel, int32_t offse
|
|||||||
return false;
|
return false;
|
||||||
if (offset < -8388608 || offset > 8388607)
|
if (offset < -8388608 || offset > 8388607)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint16_t MSB = offset >> 8;
|
uint16_t MSB = offset >> 8;
|
||||||
uint16_t LSB = offset << 8;
|
uint16_t LSB = offset << 8;
|
||||||
uint16_t reg_addr = 5 * channel + REG_CH0_OCAL_MSB;
|
uint16_t reg_addr = 5 * channel + REG_CH0_OCAL_MSB;
|
||||||
return adc_register_write_masked(reg_addr, {MSB, LSB}, {MASK_CHX_OCAL_MSB, MASK_CHX_OCAL_LSB}, __LINE__);
|
|
||||||
|
uint16_str masks = {MASK_CHX_OCAL_MSB, MASK_CHX_OCAL_LSB};
|
||||||
|
uint16_str values = {MSB, LSB};
|
||||||
|
////this->settings.reg.chan[channel].ch_ocal_msb = values[0] & masks[0];
|
||||||
|
//this->settings.reg.chan[channel].ch_ocal_lsb = values[1] & masks[1];
|
||||||
|
return adc_register_write_masked(reg_addr, values, masks, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ADS131M08Hub::set_channel_gain_calibration(uint8_t channel, uint32_t gain) {
|
bool ADS131M08Hub::set_channel_gain_calibration(uint8_t channel, uint32_t gain) {
|
||||||
@ -1158,7 +1301,11 @@ bool ADS131M08Hub::set_channel_gain_calibration(uint8_t channel, uint32_t gain)
|
|||||||
uint16_t MSB = gain >> 8;
|
uint16_t MSB = gain >> 8;
|
||||||
uint8_t LSB = gain;
|
uint8_t LSB = gain;
|
||||||
uint16_t reg_addr = 5 * channel + REG_CH0_GCAL_MSB;
|
uint16_t reg_addr = 5 * channel + REG_CH0_GCAL_MSB;
|
||||||
return adc_register_write_masked(reg_addr, {MSB, LSB}, {MASK_CHX_GCAL_MSB, MASK_CHX_GCAL_LSB}, __LINE__);
|
uint16_str masks = {MASK_CHX_GCAL_MSB, MASK_CHX_GCAL_LSB};
|
||||||
|
uint16_str values = {MSB, LSB};
|
||||||
|
//this->settings.reg.chan[channel].ch_gcal_msb = values[0] & masks[0];
|
||||||
|
//this->settings.reg.chan[channel].ch_gcal_lsb = values[1] & masks[1];
|
||||||
|
return adc_register_write_masked(reg_addr, values, masks, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debug only - remove references, declarations and definitions before submitting for production
|
// for debug only - remove references, declarations and definitions before submitting for production
|
||||||
@ -1336,10 +1483,11 @@ std::string ADS131M08Hub::reg_data_to_string(int address, uint16_t data, bool na
|
|||||||
str += " / EXT VREF=";
|
str += " / EXT VREF=";
|
||||||
str += ((data & MASK_CLOCK_EXTREF_EN) != 0) ? "EN" : "DIS";
|
str += ((data & MASK_CLOCK_EXTREF_EN) != 0) ? "EN" : "DIS";
|
||||||
{
|
{
|
||||||
uint16_t osr = 1 << (7 + ((data & MASK_CLOCK_OSR) >> 2));
|
//uint16_t osr = 1 << (7 + ((data & MASK_CLOCK_OSR) >> 2));
|
||||||
if (osr == 16384) {
|
//if (osr == 16384) {
|
||||||
osr = 16256;
|
// osr = 16256;
|
||||||
}
|
//}
|
||||||
|
uint16_t osr = convert_adc_osr_to_value((data & MASK_CLOCK_OSR) >> 2);
|
||||||
snprintf(buffer, sizeof(buffer), " / OSR=%d", osr);
|
snprintf(buffer, sizeof(buffer), " / OSR=%d", osr);
|
||||||
str += buffer;
|
str += buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class ADS131M08Hub : public Component,
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// register config values used
|
// register config values used
|
||||||
static constexpr uint16_t reg_clock_cfg = MASK_CLOCK_EXTREF_EN | OSR_1024 | PM_HIGH_RESOLUTION;
|
static constexpr uint16_t reg_clock_cfg = MASK_CLOCK_EXTREF_EN | PM_HIGH_RESOLUTION; // OSR must be added
|
||||||
static constexpr uint16_t reg_clock_allch_on = MASK_CLOCK_ALLCH | reg_clock_cfg;
|
static constexpr uint16_t reg_clock_allch_on = MASK_CLOCK_ALLCH | reg_clock_cfg;
|
||||||
static constexpr uint16_t reg_clock_allch_off = ~MASK_CLOCK_ALLCH & reg_clock_cfg;
|
static constexpr uint16_t reg_clock_allch_off = ~MASK_CLOCK_ALLCH & reg_clock_cfg;
|
||||||
static constexpr uint16_t reg_mode_cfg = DRDY_FMT_PULSE | TIMEOUT_ENABLED | CRC_REC_ENABLE | CRC_REG_ENABLE;
|
static constexpr uint16_t reg_mode_cfg = DRDY_FMT_PULSE | TIMEOUT_ENABLED | CRC_REC_ENABLE | CRC_REG_ENABLE;
|
||||||
@ -62,6 +62,29 @@ class ADS131M08Hub : public Component,
|
|||||||
static constexpr uint16_t reg_clock_cfg_mask = MASK_CLOCK_EXTREF_EN | MASK_CLOCK_OSR | MASK_CLOCK_PWR;
|
static constexpr uint16_t reg_clock_cfg_mask = MASK_CLOCK_EXTREF_EN | MASK_CLOCK_OSR | MASK_CLOCK_PWR;
|
||||||
static constexpr uint16_t reg_clock_allch_mask = MASK_CLOCK_ALLCH_OFF | reg_clock_cfg_mask;
|
static constexpr uint16_t reg_clock_allch_mask = MASK_CLOCK_ALLCH_OFF | reg_clock_cfg_mask;
|
||||||
static constexpr uint16_t reg_mode_cfg_mask = MASK_MODE_WLENGTH | MASK_MODE_DRDY_FMT | MASK_MODE_TIMEOUT | MASK_MODE_RX_CRC_EN | MASK_MODE_REG_CRC_EN;
|
static constexpr uint16_t reg_mode_cfg_mask = MASK_MODE_WLENGTH | MASK_MODE_DRDY_FMT | MASK_MODE_TIMEOUT | MASK_MODE_RX_CRC_EN | MASK_MODE_REG_CRC_EN;
|
||||||
|
struct adc_channel_settings {
|
||||||
|
uint16_t ch_cfg;
|
||||||
|
uint16_t ch_ocal_msb;
|
||||||
|
uint16_t ch_ocal_lsb;
|
||||||
|
uint16_t ch_gcal_msb;
|
||||||
|
uint16_t ch_gcal_lsb;
|
||||||
|
};
|
||||||
|
struct adc_register_settings {
|
||||||
|
uint16_t mode;
|
||||||
|
uint16_t clock;
|
||||||
|
uint16_t gain1;
|
||||||
|
uint16_t gain2;
|
||||||
|
uint16_t cfg;
|
||||||
|
uint16_t threshold_msb;
|
||||||
|
uint16_t threshold_lsb;
|
||||||
|
adc_channel_settings chan[8];
|
||||||
|
//uint16_t regmap_crc;
|
||||||
|
};
|
||||||
|
union regmap {
|
||||||
|
adc_register_settings reg;
|
||||||
|
uint16_t data[sizeof(adc_register_settings)/2];
|
||||||
|
};
|
||||||
|
|
||||||
// Semaphore handles
|
// Semaphore handles
|
||||||
SemaphoreHandle_t data_ready_semhandle = NULL;
|
SemaphoreHandle_t data_ready_semhandle = NULL;
|
||||||
SemaphoreHandle_t update_avg = NULL;
|
SemaphoreHandle_t update_avg = NULL;
|
||||||
@ -70,8 +93,10 @@ class ADS131M08Hub : public Component,
|
|||||||
bool firstRead = true; // Flag to tell us if we are reading ADC data for the first time
|
bool firstRead = true; // Flag to tell us if we are reading ADC data for the first time
|
||||||
// signed long adcData; // Location where DMA will store ADC data in memory, length defined elsewhere
|
// signed long adcData; // Location where DMA will store ADC data in memory, length defined elsewhere
|
||||||
// ADS131M08Hub();
|
// ADS131M08Hub();
|
||||||
|
regmap settings;
|
||||||
void txf_init();
|
void txf_init();
|
||||||
bool adc_initialize(uint8_t word_length);
|
bool adc_initialize(uint8_t word_length);
|
||||||
|
bool adc_restore_registers();
|
||||||
bool adc_set_word_length(uint8_t word_length);
|
bool adc_set_word_length(uint8_t word_length);
|
||||||
|
|
||||||
void setup() override;
|
void setup() override;
|
||||||
@ -86,8 +111,8 @@ class ADS131M08Hub : public Component,
|
|||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
bool set_channel_enable(uint8_t channel, bool enable);
|
bool set_channel_enable(uint8_t channel, bool enable);
|
||||||
void set_global_chop(uint16_t global_chop);
|
bool set_global_chop(uint16_t global_chop);
|
||||||
void set_global_chop_delay(uint16_t delay);
|
bool set_global_chop_delay(uint16_t delay);
|
||||||
bool set_channel_input_selection(uint8_t channel, ADC_INPUT_CHANNEL_MUX input);
|
bool set_channel_input_selection(uint8_t channel, ADC_INPUT_CHANNEL_MUX input);
|
||||||
bool set_channel_offset_calibration(uint8_t channel, int32_t offset);
|
bool set_channel_offset_calibration(uint8_t channel, int32_t offset);
|
||||||
bool set_channel_gain_calibration(uint8_t channel, uint32_t gain);
|
bool set_channel_gain_calibration(uint8_t channel, uint32_t gain);
|
||||||
@ -96,8 +121,12 @@ class ADS131M08Hub : public Component,
|
|||||||
bool set_channel_gain(uint8_t channel, uint8_t gain);
|
bool set_channel_gain(uint8_t channel, uint8_t gain);
|
||||||
bool set_measure_rms(uint8_t channel, bool enable);
|
bool set_measure_rms(uint8_t channel, bool enable);
|
||||||
float get_sampled_value(uint8_t channel) { return sampled_values_[channel]; }
|
float get_sampled_value(uint8_t channel) { return sampled_values_[channel]; }
|
||||||
|
uint32_t get_filter_settling_time();
|
||||||
//float get_average(uint8_t channel, bool read_ac);
|
//float get_average(uint8_t channel, bool read_ac);
|
||||||
bool set_reg_osr();
|
bool set_reg_osr();
|
||||||
|
uint16_t convert_value_to_adc_osr(uint16_t osr_value);
|
||||||
|
uint16_t convert_adc_osr_to_value(uint16_t adc_osr);
|
||||||
|
uint32_t convert_adc_clock_cycles_to_micros(uint32_t cycles);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HighFrequencyLoopRequester high_freq_;
|
HighFrequencyLoopRequester high_freq_;
|
||||||
@ -117,15 +146,15 @@ class ADS131M08Hub : public Component,
|
|||||||
void SET_IRAM read_single();
|
void SET_IRAM read_single();
|
||||||
float_str SET_IRAM read_multi();
|
float_str SET_IRAM read_multi();
|
||||||
bool adc_lock(bool enable);
|
bool adc_lock(bool enable);
|
||||||
bool adc_register_write(uint16_t address, uint16_t data);
|
bool adc_register_write(uint16_t address, uint16_t data, int line, bool backup_date = true);
|
||||||
bool adc_register_write(uint16_t address, const uint16_str &data);
|
bool adc_register_write(uint16_t address, const uint16_str &data, int line, bool backup_date = true);
|
||||||
uint16_str adc_register_read(uint8_t address, uint8_t nregs);
|
uint16_str adc_register_read(uint8_t address, uint8_t nregs);
|
||||||
bool adc_register_write_masked(uint8_t address, uint16_t value, uint16_t mask, int line);
|
bool adc_register_write_masked(uint8_t address, uint16_t value, uint16_t mask, int line);
|
||||||
bool adc_register_write_masked(uint8_t start_address, const uint16_str &values, const uint16_str &masks, int line);
|
bool adc_register_write_masked(uint8_t start_address, const uint16_str &values, const uint16_str &masks, int line);
|
||||||
bool adc_reset_retry();
|
bool adc_reset_retry();
|
||||||
bool adc_soft_reset();
|
bool adc_soft_reset();
|
||||||
void adc_hard_reset();
|
uint32_t adc_hard_reset();
|
||||||
void adc_sync();
|
uint32_t adc_sync();
|
||||||
void SET_IRAM transfer_array(spiframe &frame);
|
void SET_IRAM transfer_array(spiframe &frame);
|
||||||
//void transfer_array(const spiframe &data_out, spiframe &data_in);
|
//void transfer_array(const spiframe &data_out, spiframe &data_in);
|
||||||
uint16_t SET_IRAM get_crc(const spiframe &frame);
|
uint16_t SET_IRAM get_crc(const spiframe &frame);
|
||||||
@ -179,7 +208,7 @@ class ADS131M08Hub : public Component,
|
|||||||
uint8_t update_state_[MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t update_state_[MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
uint8_t adc_word_length_{24};
|
uint8_t adc_word_length_{24};
|
||||||
float conversion_factor_{1.25 / 8388608.0}; // updated when word length changes
|
float conversion_factor_{1.25 / 8388608.0}; // updated when word length changes
|
||||||
const uint32_t sample_time_ = 20000; // 250 ms
|
const uint32_t sample_time_ = 40000; // 40 ms
|
||||||
float sps_{0.0f};
|
float sps_{0.0f};
|
||||||
uint32_t num_samples_[ADC_CHANNELS];
|
uint32_t num_samples_[ADC_CHANNELS];
|
||||||
float sample_sum_[ADC_CHANNELS];
|
float sample_sum_[ADC_CHANNELS];
|
||||||
|
|||||||
@ -13,6 +13,7 @@ enum ADC_DRDY_STATE : uint8_t {
|
|||||||
DS_HI_Z = 1
|
DS_HI_Z = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// no shift
|
||||||
enum ADC_POWERMODE : uint16_t {
|
enum ADC_POWERMODE : uint16_t {
|
||||||
PM_VERY_LOW_POWER = 0,
|
PM_VERY_LOW_POWER = 0,
|
||||||
PM_LOW_POWER = 1,
|
PM_LOW_POWER = 1,
|
||||||
@ -39,26 +40,27 @@ enum ADC_INPUT_CHANNEL_MUX : uint8_t {
|
|||||||
ICM_NEGATIVE_DC_TEST_SIGNAL = 3,
|
ICM_NEGATIVE_DC_TEST_SIGNAL = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// must be shifted << 2
|
||||||
enum ADC_OVERSAMPLING_RATIO : uint16_t {
|
enum ADC_OVERSAMPLING_RATIO : uint16_t {
|
||||||
OSR_128 = 0,
|
OSR_128 = 0,
|
||||||
OSR_256 = 1,
|
OSR_256 = 1,
|
||||||
OSR_512 = 2,
|
OSR_512 = 2,
|
||||||
OSR_1024 = 3, // default
|
OSR_1024 = 3,
|
||||||
OSR_2048 = 4,
|
OSR_2048 = 4,
|
||||||
OSR_4096 = 5,
|
OSR_4096 = 5,
|
||||||
OSR_8192 = 6,
|
OSR_8192 = 6,
|
||||||
OSR_16256 = 7
|
OSR_16256 = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ADC_WAIT_TIME : uint16_t {
|
enum ADC_SETTLING_TIME : uint16_t {
|
||||||
WT_128 = 856,
|
T_SETTLE_OSR128 = 856,
|
||||||
WT_256 = 1112,
|
T_SETTLE_OSR256 = 1112,
|
||||||
WT_512 = 1624,
|
T_SETTLE_OSR512 = 1624,
|
||||||
WT_1024 = 2648,
|
T_SETTLE_OSR1024 = 2648,
|
||||||
WT_2048 = 4696,
|
T_SETTLE_OSR2048 = 4696,
|
||||||
WT_4096 = 8792,
|
T_SETTLE_OSR4096 = 8792,
|
||||||
WT_8192 = 16984,
|
T_SETTLE_OSR8192 = 16984,
|
||||||
WT_16384 = 33368
|
T_SETTLE_OSR16384 = 33368,
|
||||||
};
|
};
|
||||||
|
|
||||||
// delays in microseconds
|
// delays in microseconds
|
||||||
@ -67,6 +69,7 @@ enum ADC_DELAY {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static constexpr uint16_t MODE_MASK_RESET_HAPPENED = ~0x0400; // DEFAULT
|
static constexpr uint16_t MODE_MASK_RESET_HAPPENED = ~0x0400; // DEFAULT
|
||||||
static constexpr uint16_t MODE_RESET_HAPPENED = 0x0400;
|
static constexpr uint16_t MODE_RESET_HAPPENED = 0x0400;
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,10 @@ CONF_OFFSET_CALIBRATION = "offset_calibration"
|
|||||||
CONF_GAIN_CALIBRATION = "gain_calibration"
|
CONF_GAIN_CALIBRATION = "gain_calibration"
|
||||||
CONF_PHASE_CALIBRATION = "phase_calibration"
|
CONF_PHASE_CALIBRATION = "phase_calibration"
|
||||||
CONF_INPUT_SELECT = "input_select"
|
CONF_INPUT_SELECT = "input_select"
|
||||||
|
CONF_DC_BLOCK = "dc_block"
|
||||||
ICON_CURRENT_DC = "mdi:current-dc"
|
ICON_CURRENT_DC = "mdi:current-dc"
|
||||||
|
|
||||||
|
|
||||||
DEPENDENCIES = ["ads131m08"]
|
DEPENDENCIES = ["ads131m08"]
|
||||||
|
|
||||||
GAIN = ads131m08_ns.enum("ADC_PGA_GAIN")
|
GAIN = ads131m08_ns.enum("ADC_PGA_GAIN")
|
||||||
@ -59,6 +61,7 @@ CONFIG_SCHEMA = CONFIG_SCHEMA_RMS_SENSORS.extend(
|
|||||||
cv.Optional(CONF_GAIN_CALIBRATION, default=1): cv.float_range(min=0, max=2),
|
cv.Optional(CONF_GAIN_CALIBRATION, default=1): cv.float_range(min=0, max=2),
|
||||||
cv.Optional(CONF_PHASE_CALIBRATION, default=0): cv.int_range(min=-512, max=511), # should use degrees, but need to figure out conversion function first
|
cv.Optional(CONF_PHASE_CALIBRATION, default=0): cv.int_range(min=-512, max=511), # should use degrees, but need to figure out conversion function first
|
||||||
cv.Optional(CONF_INPUT_SELECT, default='normal'): cv.enum(ALLOWED_MUX_INP, int=False),
|
cv.Optional(CONF_INPUT_SELECT, default='normal'): cv.enum(ALLOWED_MUX_INP, int=False),
|
||||||
|
cv.Optional(CONF_DC_BLOCK, default=False): cv.boolean,
|
||||||
}
|
}
|
||||||
).extend(
|
).extend(
|
||||||
{
|
{
|
||||||
@ -84,6 +87,8 @@ async def to_code(config):
|
|||||||
cg.add(channel_sensor.set_offset_calibration(offset_cal))
|
cg.add(channel_sensor.set_offset_calibration(offset_cal))
|
||||||
phase_cal = config[CONF_PHASE_CALIBRATION]
|
phase_cal = config[CONF_PHASE_CALIBRATION]
|
||||||
cg.add(channel_sensor.set_phase_calibration(phase_cal))
|
cg.add(channel_sensor.set_phase_calibration(phase_cal))
|
||||||
|
dc_block = config[CONF_DC_BLOCK]
|
||||||
|
cg.add(channel_sensor.set_dc_block(dc_block))
|
||||||
await cg.register_component(channel_sensor, config)
|
await cg.register_component(channel_sensor, config)
|
||||||
if dc_sensor := await to_code_dc(config):
|
if dc_sensor := await to_code_dc(config):
|
||||||
await cg.register_parented(dc_sensor, channel_sensor)
|
await cg.register_parented(dc_sensor, channel_sensor)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ads131m08 {
|
namespace ads131m08 {
|
||||||
|
|
||||||
static const char *const TAG = "adsm131m08.sensor";
|
static const char *const TAG = "ads131m08.sensor";
|
||||||
|
|
||||||
void Channel::loop()
|
void Channel::loop()
|
||||||
{
|
{
|
||||||
@ -16,7 +16,7 @@ void Channel::loop()
|
|||||||
this->parent_->set_channel_phase_calibration(this->channel_, this->normalised_phase_calibration());
|
this->parent_->set_channel_phase_calibration(this->channel_, this->normalised_phase_calibration());
|
||||||
this->parent_->set_channel_offset_calibration(this->channel_, this->normalised_offset_calibration());
|
this->parent_->set_channel_offset_calibration(this->channel_, this->normalised_offset_calibration());
|
||||||
this->parent_->set_channel_gain_calibration(this->channel_, this->normalised_gain_calibration());
|
this->parent_->set_channel_gain_calibration(this->channel_, this->normalised_gain_calibration());
|
||||||
this->parent_->set_dcblock_filter_disable(this->channel_, true);
|
this->parent_->set_dcblock_filter_disable(this->channel_, !this->dc_block_);
|
||||||
this->parent_->set_channel_enable(this->channel_, true);
|
this->parent_->set_channel_enable(this->channel_, true);
|
||||||
this->first_reading_ = false;
|
this->first_reading_ = false;
|
||||||
}
|
}
|
||||||
@ -53,6 +53,7 @@ void Channel::dump_config() {
|
|||||||
ESP_LOGCONFIG(TAG, " Gain calibration: %f", this->gain_cal_);
|
ESP_LOGCONFIG(TAG, " Gain calibration: %f", this->gain_cal_);
|
||||||
ESP_LOGCONFIG(TAG, " Offset calibration: %" PRIu32, this->offset_cal_);
|
ESP_LOGCONFIG(TAG, " Offset calibration: %" PRIu32, this->offset_cal_);
|
||||||
ESP_LOGCONFIG(TAG, " Phase calibration: %" PRId32, this->phase_cal_);
|
ESP_LOGCONFIG(TAG, " Phase calibration: %" PRId32, this->phase_cal_);
|
||||||
|
ESP_LOGCONFIG(TAG, " DC block: %s", this->dc_block_ ? "YES" : "NO");
|
||||||
ESP_LOGCONFIG(TAG, " Input select: %s", (this->input_ == ICM_AIN0P_AIN0N) ? "normal" \
|
ESP_LOGCONFIG(TAG, " Input select: %s", (this->input_ == ICM_AIN0P_AIN0N) ? "normal" \
|
||||||
: (this->input_ == ICM_INPUT_SHORTED) ? "shorted" \
|
: (this->input_ == ICM_INPUT_SHORTED) ? "shorted" \
|
||||||
: (this->input_ == ICM_POSITIVE_DC_TEST_SIGNAL) ? "positive_dc" \
|
: (this->input_ == ICM_POSITIVE_DC_TEST_SIGNAL) ? "positive_dc" \
|
||||||
|
|||||||
@ -25,6 +25,7 @@ class Channel : public sensor::Sensor,
|
|||||||
void set_gain_calibration(float value) { this->gain_cal_ = value; }
|
void set_gain_calibration(float value) { this->gain_cal_ = value; }
|
||||||
void set_offset_calibration(int value) { this->offset_cal_ = value; }
|
void set_offset_calibration(int value) { this->offset_cal_ = value; }
|
||||||
void set_phase_calibration(int value) { this->phase_cal_ = value; }
|
void set_phase_calibration(int value) { this->phase_cal_ = value; }
|
||||||
|
void set_dc_block(bool enable) { this->dc_block_ = enable; }
|
||||||
bool set_calc_rms(bool enable) { this->calc_rms_ = enable; return this->parent_ != nullptr ? this->parent_->set_measure_rms(this->channel_, enable) : false; }
|
bool set_calc_rms(bool enable) { this->calc_rms_ = enable; return this->parent_ != nullptr ? this->parent_->set_measure_rms(this->channel_, enable) : false; }
|
||||||
//float get_average(bool read_ac) { return this->parent_->get_average(this->channel_, read_ac); }
|
//float get_average(bool read_ac) { return this->parent_->get_average(this->channel_, read_ac); }
|
||||||
void set_mux_input(ADC_INPUT_CHANNEL_MUX value) { this->input_ = value; }
|
void set_mux_input(ADC_INPUT_CHANNEL_MUX value) { this->input_ = value; }
|
||||||
@ -38,6 +39,7 @@ class Channel : public sensor::Sensor,
|
|||||||
int offset_cal_;
|
int offset_cal_;
|
||||||
float gain_cal_;
|
float gain_cal_;
|
||||||
bool calc_rms_;
|
bool calc_rms_;
|
||||||
|
bool dc_block_;
|
||||||
uint8_t gain_;
|
uint8_t gain_;
|
||||||
ADC_INPUT_CHANNEL_MUX input_;
|
ADC_INPUT_CHANNEL_MUX input_;
|
||||||
bool first_reading_{true};
|
bool first_reading_{true};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user