Tool/software:
I'm trying to configure the ADS131E08S over SPI with my nRF52840 Dongle but I get no response from the ADC. I checked with my MSO that the SPI commands are actually sent out and they are but I can't read the registers because there is no answer and the data ready pin is always high and never toggles. I have tried as simple as only sending the start command 0x08 but again the data ready pin never changes. I use SPI mode 1 and here's the code:
#include <zephyr/drivers/gpio.h> #include <zephyr/drivers/spi.h> #include <zephyr/kernel.h> // SPI #define SPI_NODE DT_NODELABEL(spi2) #define CS_PORT DT_NODELABEL(gpio0) #define CS_PIN 20 const struct device *spi_dev = DEVICE_DT_GET(SPI_NODE); const struct device *cs_dev = DEVICE_DT_GET(CS_PORT); // DRDY Pin #define DATA_READY_NODE DT_NODELABEL(data_ready) const struct gpio_dt_spec drdy = GPIO_DT_SPEC_GET(DATA_READY_NODE, gpios); volatile _Bool isr_flag = false; volatile uint32_t start, end, diff_cycles; volatile uint64_t diff_us; // SPI #define NUM_SAMPLES 1000 #define FRAME_SIZE 27 volatile uint8_t adc_data[NUM_SAMPLES][FRAME_SIZE]; volatile int sample_index = 0; volatile bool buffer_full = false; uint8_t rx_buf[FRAME_SIZE]; struct spi_buf rx_buf_struct = { .buf = rx_buf, .len = sizeof(rx_buf), }; struct spi_buf_set rx = { .buffers = &rx_buf_struct, .count = 1, }; int8_t tx_buf[] = {0x00, 0x00, 0x00}; struct spi_buf tx = { .buf = tx_buf, .len = sizeof(tx_buf), }; struct spi_buf_set tx_set = { .buffers = &tx, .count = 1, }; struct spi_config spi_cfg = { .frequency = 4000000, .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPHA, }; // Interrupt static void drdy_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { printk("Interrupt ausgelöst\n"); start = k_cycle_get_32(); // ISR: if (buffer_full) return; // keine neuen Daten, wenn Puffer voll spi_read(spi_dev, NULL, &rx); memcpy((void *)adc_data[sample_index], rx_buf, FRAME_SIZE); sample_index++; if (sample_index >= NUM_SAMPLES) { sample_index = 0; buffer_full = true; } // End ISR end = k_cycle_get_32(); printk("Samplenr.: %i\n", sample_index); diff_cycles = end - start; diff_us = (uint64_t)diff_cycles * 1000000 / sys_clock_hw_cycles_per_sec(); printk("Zeitdiff: %llu us\n\n", diff_us); } static struct gpio_callback drdy_cb_data; int main(void) { printk("\nInitializaion...\n\n"); k_msleep(5000); int ret; // DRDY Pin if(!device_is_ready(drdy.port)) { printk("GPIO device not ready\n"); } if (!device_is_ready(cs_dev)) { printk("CS device not ready\n"); } if(gpio_pin_configure_dt(&drdy, GPIO_INPUT) < 0) { printk("Error configuring Data Ready pin\n"); } // Interrupt gpio_init_callback(&drdy_cb_data, drdy_cb, BIT(drdy.pin)); gpio_add_callback(drdy.port, &drdy_cb_data); if(gpio_pin_interrupt_configure_dt(&drdy, GPIO_INT_EDGE_FALLING) < 0) { printk("Error configuring interrupt\n"); } // SPI gpio_pin_configure(cs_dev, CS_PIN, GPIO_OUTPUT_HIGH); // CS idle high if(!device_is_ready(spi_dev)) { printk("SPI device not ready\n"); } // Sensor initialization tx.len = 1; tx_buf[0] = 0x06; gpio_pin_set(cs_dev, CS_PIN, 0); // CS low (select) ret = spi_write(spi_dev, &spi_cfg, &tx_set); k_msleep(1); gpio_pin_set(cs_dev, CS_PIN, 1); // CS high (deselect) k_msleep(100); tx_buf[0] = 0x11; gpio_pin_set(cs_dev, CS_PIN, 0); // CS low (select) ret = spi_write(spi_dev, &spi_cfg, &tx_set); k_msleep(1); gpio_pin_set(cs_dev, CS_PIN, 1); // CS high (deselect) k_msleep(100); tx.len = 3; tx_buf[0] = 0x41; tx_buf[1] = 0x00; tx_buf[2] = 0x96; gpio_pin_set(cs_dev, CS_PIN, 0); // CS low (select) ret = spi_write(spi_dev, &spi_cfg, &tx_set); k_msleep(1); gpio_pin_set(cs_dev, CS_PIN, 1); // CS high (deselect) k_msleep(1000); tx.len = 1; tx_buf[0] = 0x08; // start conversions gpio_pin_set(cs_dev, CS_PIN, 0); // CS low (select) ret = spi_write(spi_dev, &spi_cfg, &tx_set); k_msleep(1); gpio_pin_set(cs_dev, CS_PIN, 1); // CS high (deselect) k_msleep(1000); k_msleep(100); printk("----- Device Ready!-----\n\n"); while (1) { /*if(gpio_pin_get(drdy.port, drdy.pin)) { printk("DRDY PIN High\n"); } else { printk("DRDY PIN Low\n"); }*/ if (buffer_full) { // Jetzt Daten verarbeiten (z. B. wandeln und ausgeben) for (int i = 0; i < NUM_SAMPLES; i++) { printk("Sample %d:\n", i); int offset = 3; for (int ch = 0; ch < 8; ch++) { uint32_t raw = (adc_data[i][offset] << 16) | (adc_data[i][offset + 1] << 8) | adc_data[i][offset + 2]; if (raw & 0x800000) raw |= 0xFF000000; printk(" CH%d = %d\n", ch, (int32_t)raw); offset += 3; } } // Nach Ausgabe ggf. wieder für nächste Sekunde freigeben sample_index = 0; } k_msleep(1000); // kurze Pause, kein Busy-Waiting buffer_full = false; } }