AD7190 SPI interface issue
Posted: Fri Feb 13, 2026 10:03 am
Hi All,
I'm the process of porting a project to ESP32-S3 and I'm using ESP-IDF. I'm configuring an ADC AD7190. I can read and write to various registers reliably. but have an issue with one register in particular, the CONF register. The ADC is set to continuous mode and the board has CS routed to GND - it is the only device on the SPI bus.
When reading the register on startup the default value should be 0x117. But I always read 0x116. So I've written 0x3FF as a test, and I read back 0x3FE. the LSB is always zero no matter what I write to it. However the MODE register read/write works correctly.
The original project was on an Arduino RP2040 nano connect and uses the Arduino SPI library writing 0x257 to CONF and reading it back as 0x257 at all times. There's probably some "under the hood magic" happening. I'm in the process of porting it to ESP-IDF and getting into the low level SPI issues at the moment.
SPI Frequency set to 500000
Using HSPI pins
this is my init code
Write register and read register functions
Writing to the CONF register - the debug messages will show what's written and received
the LSB is always 0 no matter what I try. Is there something in my spi init that can be changed? Writing and Reading from the other registers is working. I've spend around 8 to 12 hrs trying to get to the bottom of this. I would appreciate assistance.
Thanks.
I'm the process of porting a project to ESP32-S3 and I'm using ESP-IDF. I'm configuring an ADC AD7190. I can read and write to various registers reliably. but have an issue with one register in particular, the CONF register. The ADC is set to continuous mode and the board has CS routed to GND - it is the only device on the SPI bus.
When reading the register on startup the default value should be 0x117. But I always read 0x116. So I've written 0x3FF as a test, and I read back 0x3FE. the LSB is always zero no matter what I write to it. However the MODE register read/write works correctly.
The original project was on an Arduino RP2040 nano connect and uses the Arduino SPI library writing 0x257 to CONF and reading it back as 0x257 at all times. There's probably some "under the hood magic" happening. I'm in the process of porting it to ESP-IDF and getting into the low level SPI issues at the moment.
SPI Frequency set to 500000
Using HSPI pins
this is my init code
Code: Select all
esp_err_t ad7190_spi_init(void) {
const char *TAG = "AD7190_SPI_INIT";
esp_err_t ret;
spi_bus_config_t bus_config = {
.miso_io_num = SPI_MISO_PIN,
.mosi_io_num = SPI_MOSI_PIN,
.sclk_io_num = SPI_SCLK_PIN,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 32,
};
spi_device_interface_config_t device_config = {
.clock_speed_hz = SPI_FREQUENCY,
.mode = 3,
.spics_io_num = -1,
.queue_size = 1,
.flags = 0
};
ret = spi_bus_initialize(SPI2_HOST, &bus_config, SPI_DMA_CH_AUTO);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SPI bus (%s)", esp_err_to_name(ret));
return ret;
}
ret = spi_bus_add_device(SPI2_HOST, &device_config, &spi_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to add SPI device (%s)", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(TAG, "SPI device initialized successfully");
return ESP_OK;
}Code: Select all
void ad7190_write_register_value(uint8_t reg, uint32_t value, uint8_t num_bytes) {
const char *TAG = "write register value";
uint8_t tx[4] = {0};
uint8_t rx[4] = {0};
tx[0] = AD7190_COMM(reg, AD7190_COMM_WRITE);
ESP_LOGI(TAG, "Writing register 0x%02X with command byte 0x%02X", reg, tx[0]);
for (int i = 0; i < num_bytes; i++) {
tx[i + 1] = (value >> (8 * (num_bytes - 1 - i))) & 0xFF;
}
// Debug: Print raw received bytes
ESP_LOGI(TAG, "TX raw: %02X %02X %02X %02X",
tx[0], tx[1], tx[2], tx[3]);
spi_transaction_t t = {0};
t.length = (num_bytes + 1) * 8; // Command byte + data bytes
t.tx_buffer = tx;
t.rx_buffer = rx;
esp_err_t ret = spi_device_transmit(spi_handle, &t);
ESP_LOGI(TAG, "RX during write: %02X %02X %02X %02X", rx[0], rx[1], rx[2], rx[3]); // See what comes back
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to transmit SPI data (%s)", esp_err_to_name(ret));
}
}
uint32_t ad7190_get_register_value(uint8_t reg, uint8_t num_bytes) {
const char *TAG = "get register value";
uint8_t tx[5] = {0};
uint8_t rx[5] = {0};
tx[0] = AD7190_COMM(reg, AD7190_COMM_READ);
ESP_LOGI(TAG, "Reading register 0x%02X with command byte 0x%02X", reg, tx[0]);
for (int i = 1; i <= num_bytes; i++) {
tx[i] = 0xFF; // Dummy bytes to clock out the data
//ESP_LOGI(TAG, "Dummy Data: 0x%02X", tx[i]);
}
// Debug: Print raw received bytes
ESP_LOGI(TAG, "TX raw: %02X %02X %02X %02X",
tx[0], tx[1], tx[2], tx[3]);
spi_transaction_t t = {0};
t.length = (num_bytes + 1) * 8; // Command byte + data bytes
t.tx_buffer = tx;
t.rx_buffer = rx;
spi_device_transmit(spi_handle, &t);
// Debug: Print raw received bytes
ESP_LOGI(TAG, "RX raw: %02X %02X %02X %02X",
rx[0], rx[1], rx[2], rx[3]);
uint32_t value = 0;
for (int i = 0; i < num_bytes; i++) {
value <<= 8;
value |= rx[i + 1]; // Skip command response
}
return value;
}Code: Select all
ESP_LOGI(TAG, "Writing CONF register");
ad7190_write_register_value(AD7190_CONF_REG, 0x000257, 3);
vTaskDelay(pdMS_TO_TICKS(100));
ESP_LOGI(TAG, "Reading CONF register");
uint32_t conf_reg = ad7190_get_register_value(AD7190_CONF_REG, 3);
ESP_LOGI(TAG, "CONF: %" PRIx32, conf_reg); Code: Select all
I (535) app main: Writing CONF register
I (535) write register value: Writing register 0x02 with command byte 0x10
I (535) write register value: TX raw: 10 00 02 57
I (535) write register value: RX during write: 00 01 FF FF
I (705) app main: Reading CONF register
I (705) get register value: Reading register 0x02 with command byte 0x50
I (715) get register value: TX raw: 50 FF FF FF
I (725) get register value: RX raw: 00 00 02 56
I (725) app main: CONF: 256Thanks.