cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-F767ZI + ADS1298 board - SPI communication issues

bog201
Associate II

Hi everyone,

I am having issues interfacing an ADS1298 board with a NUCLEO F767ZI. 

 

 

 

void ADS1298_ReadConfig1(SPI_HandleTypeDef *hspi) {
    uint8_t command[2] = {0x20 | 0x00, 0x00};  // RREG command for sending ID
    uint8_t sdatacCmd = 0x11; // SDATAC mode command for sending data

    GPIOA->BSRR = GPIO_BSRR_BR4; // CS LOW

    *(volatile uint8_t *)&SPI1->DR = sdatacCmd; // SDATAC command, stop reading data so the ADS1298 can receive commands -- direct register access method
	while (!(SPI1->SR & SPI_SR_TXE)); // Wait until TXE (Transmit buffer empty) is set
	while (SPI1->SR & SPI_SR_BSY);   // Wait for transmission to complete
	while (!(SPI1->SR & SPI_SR_RXNE)); // Wait until RXNE (Receive buffer empty) is set
	volatile uint8_t sdatac_status = *(volatile uint8_t *)&SPI1->DR; // Discard

	*(volatile  uint8_t *)&SPI1->DR = command[0];
	while (!(SPI1->SR & SPI_SR_TXE));
	while (SPI1->SR & SPI_SR_BSY); 
	while (!(SPI1->SR & SPI_SR_RXNE));
	volatile uint8_t rreg_status1 = *(volatile uint8_t *)&SPI1->DR; // Discard

	*(volatile uint8_t *)&SPI1->DR = command[1];
	while (!(SPI1->SR & SPI_SR_TXE)); 
	while (SPI1->SR & SPI_SR_BSY); 
	while (!(SPI1->SR & SPI_SR_RXNE));
	volatile uint8_t rreg_status2 = *(volatile uint8_t *)&SPI1->DR; // Discard

	*(volatile uint8_t *)&SPI1->DR = 0xFF; // Dummy byte
	while (!(SPI1->SR & SPI_SR_TXE)); 
	while (SPI1->SR & SPI_SR_BSY);
	while (!(SPI1->SR & SPI_SR_RXNE));
	response = *(volatile uint8_t *)&SPI1->DR; // Save ID in a buffer

	for ( int i = 0; i < 10; i++); // Small delay to have >2 us between last CLK falling edge and CS high
    GPIOA->BSRR = GPIO_BSRR_BS4; // CS HIGH
    printf("CONFIG1: 0x%02X\n", response);
}

 

 

DS1Z_QuickPrint7.png

I set DRDY (data ready pin) as an interrupt, meaning that this function runs every time DRDY toggles. It seems like I am getting the correct ID 0x92 at address 0x20 | 0x00, but for some reason I am also reading the CONFIG1 register 0x86 which is 0x20 | 0x01 at the beginning of each new SPI transaction. From the printf function I see CONFIG1: 0x86, even though it should be 0x92. 

 

I thought I am flushing the FIFO by reading the buffer each time I send a byte. Does anyone have any suggestions on what could cause the extra byte at the beginning of the SPI transactions? I also asked on the TI forums as it might be more ADS1298 related than the STM32 NUCLEO board.

1 REPLY 1
JaiGanesh
Associate II

Hi ,

Thanks for sharing your experience! I'm currently working on a similar ECG data acquisition project, but using the ADS1293 with an STM32U5 MCU to display ECG signals on a TouchGFX interface.

I noticed you're directly handling SPI register access and managing SDATAC and RREG commands, which is something I’m also exploring (though the ADS1293 has some differences in protocol and register structure compared to the ADS1298).

Right now, I'm facing issues with:

  • Getting clean ECG signals consistently across all channels (especially CH2 for Lead II).

  • Understanding the correct register initialization sequence for enabling 3 channels.

  • Ensuring correct SPI timing and DRDY handling with STM32 HAL or LL drivers.

Would you (or anyone here) have any suggestions or example initialization sequences or SPI logic (especially for handling burst reads and multi-channel configs)?

Also, if you eventually get the ADS1298 SPI transaction issue resolved, I'd be very interested in your findings—it might help uncover nuances in the SPI state machine or buffer behavior that could be relevant to the ADS1293 as well.

Thanks in advance, and good luck with your project too!

Ganesh