This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS131E08S: SPI communication not working

Part Number: ADS131E08S

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;
    }
    
}

  • Hi Michael,

    Can you send a logic analyzer plot showing the communication signals from/to the ADC when you send a command to the ADC? Your schematic will be very helpful, you can share it with me via message if you do not want to share it publicly.

    BR,

    Dale