ADS1299EEGFE-PDK: SPI communication between ESP32 and ADS1299 not working

Part Number: ADS1299EEGFE-PDK
Other Parts Discussed in Thread: ADS1299

Hi there,

My name is Mike and im a final year Auckland University of Technology student currently working on a multi-disiplinary project which is a waerable data logger/acqusition system or device. 
In my team im the one who is responsible for the hardware testing and programming which has been a task and I just need some guidance from people who have faced the same issue as me.

I have managed to connect J3 pins of the ADS1299 (CS, CLK, DIN, DOUT, RESET, START, DRDY, GND) to my ESP32 designated pins as follows

PIN_CS    5
PIN_DRDY  4
PIN_MOSI  23
PIN_MISO  21
PIN_SCLK  18
PIN_START 13
PIN_RESET 26

After running a code that i had got from the help of Claude, I am expecting to get a reading of 0x3E which is mentioned on the ADS1299 datasheet for SPI communication.
this occures when DRDY is toggling from 0 and 1 however in my case it has been stuck on HIGH for a long time.

I have tried separating the MMBO from the ADS1299(top layer PCB) thinking it might be going through a conflict of SPI bus control but at the same time I need them connected for correct power supply.

I have also tired powering the ADS1299 with the 5V of the ESP32(VIN) but im affraid it isn't sufficent enough or has inconsistency due to poor jumper wires. However, when trying both i still had 0xFF reading which indicates DRDY never switched/toggled.

#include <Arduino.h>
#include <SPI.h>

#define PIN_CS    5
#define PIN_DRDY  4
#define PIN_MOSI  23
#define PIN_MISO  21
#define PIN_SCLK  18
#define PIN_START 13
#define PIN_RESET 26

SPISettings ads_spi(250000, MSBFIRST, SPI_MODE1);

void sendSDATAC() {
    SPI.beginTransaction(ads_spi);
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(10);
    SPI.transfer(0x11);         // SDATAC command
    delayMicroseconds(10);      // wait 4+ tCLK BEFORE releasing CS
    digitalWrite(PIN_CS, HIGH);
    SPI.endTransaction();
    delayMicroseconds(10);      // wait 4+ tCLK after CS goes high
    delay(10);                  // extra settling time
}

byte readRegister(byte address) {
    byte value = 0;
    SPI.beginTransaction(ads_spi);
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(10);
    SPI.transfer(0x20 | address); // RREG command
    delayMicroseconds(10);
    SPI.transfer(0x00);           // read 1 register
    delayMicroseconds(10);
    value = SPI.transfer(0x00);   // get value
    delayMicroseconds(10);
    digitalWrite(PIN_CS, HIGH);
    SPI.endTransaction();
    delayMicroseconds(10);
    return value;
}

void sendCommand(byte cmd) {
    SPI.beginTransaction(ads_spi);
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(10);
    SPI.transfer(cmd);
    delayMicroseconds(10);
    digitalWrite(PIN_CS, HIGH);
    SPI.endTransaction();
    delayMicroseconds(10);
}

void setup() {
    Serial.begin(921600);
    delay(5000);

    pinMode(PIN_CS,    OUTPUT); digitalWrite(PIN_CS,    HIGH);
    pinMode(PIN_RESET, OUTPUT); digitalWrite(PIN_RESET, LOW);
    pinMode(PIN_START, OUTPUT); digitalWrite(PIN_START, LOW);
    pinMode(PIN_DRDY,  INPUT);

    SPI.begin(PIN_SCLK, PIN_MISO, PIN_MOSI, PIN_CS);

    Serial.println("=== ADS1299 ID Test (TI Forum Fix) ===");

    // Step 1 - Hardware reset
    Serial.println("Step 1: RESET LOW 500ms...");
    digitalWrite(PIN_RESET, LOW);
    delay(500);

    Serial.println("Step 2: RESET HIGH...");
    digitalWrite(PIN_RESET, HIGH);
    delay(1000);    // wait for chip to fully boot

    // Step 3 - Send SDATAC multiple times with proper timing
    Serial.println("Step 3: Sending SDATAC x5 with proper tCLK delays...");
    for (int i = 0; i < 5; i++) {
        sendSDATAC();
        delay(50);
    }
    delay(100);

    // Step 4 - Pull START HIGH
    Serial.println("Step 4: START HIGH...");
    digitalWrite(PIN_START, HIGH);
    delay(100);

    // Step 5 - Watch DRDY
    Serial.println("Step 5: Watching DRDY for 3 seconds...");
    int changes = 0;
    int last = digitalRead(PIN_DRDY);
    unsigned long t = millis();
    while (millis() - t < 3000) {
        int cur = digitalRead(PIN_DRDY);
        if (cur != last) {
            changes++;
            Serial.printf("  DRDY -> %d at %lums\n", cur, millis() - t);
            last = cur;
            if (changes >= 6) break;
        }
    }
    Serial.printf("DRDY changes: %d\n", changes);
    Serial.println(changes > 0 ? "Chip IS converting!" : "Chip not converting");

    // Step 6 - Read ID register 20 times
    Serial.println("\nStep 6: Reading ID register 20 times:");
    for (int i = 0; i < 20; i++) {
        delay(200);
        byte id = readRegister(0x00);
        Serial.printf("  Read %d: 0x%02X %s\n",
            i+1, id,
            ((id & 0x1F) == 0x1E) ? "<-- GOT IT!" : "");
        if ((id & 0x1F) == 0x1E) {
            Serial.println("SUCCESS - ADS1299 communication established!");
            break;
        }
    }

    // Step 7 - MISO state
    pinMode(PIN_MISO, INPUT);
    Serial.printf("\nMISO idle: %s\n",
        digitalRead(PIN_MISO) ? "HIGH" : "LOW");
}

void loop() {}

the below is the reading I base my work on which is from the serial monitor

=== ADS1299 ID Test (TI Forum Fix) ===
Step 1: RESET LOW 500ms...
Step 2: RESET HIGH...
Step 3: Sending SDATAC x5 with proper tCLK delays...
Step 4: START HIGH...
Step 5: Watching DRDY for 3 seconds...
DRDY changes: 0
Chip not converting

Step 6: Reading ID register 20 times:
  Read 1: 0xFF 
  Read 2: 0xFF 
  Read 3: 0xFF 
  Read 4: 0xFF 
  Read 5: 0xFF 
  Read 6: 0xFF 
  Read 7: 0xFF 
  Read 8: 0xFF 
  Read 9: 0xFF 
  Read 10: 0xFF
MISO idle: HIGH


Thank you for reading through all of this and I appriciate fortaking your time.
look forward to any support or feedback i can get.

kind regards

Mike.