SPI read failure after upgrading from NCS 3.2.4 to 3.4.0 on nRF52840 custom board

Hi,

I am experiencing an issue where SPI read operations fail after upgrading from NCS 3.2.4 to NCS 3.4.0.

Hardware:

  • Custom board based on nRF52840
  • ADS1294 (ECG ADC IC) connected via SPI
  • The board has a proven track record working with nRF5 SDK and NCS 3.2.4, so hardware issues are ruled out

Symptoms:

  • SPI read works correctly on NCS 3.2.4
  • After upgrading to NCS 3.4.0, SPI read always returns 0xFF, suggesting that MISO is not being driven and the SPI read itself is not functioning

What I have tried:

  • Added spi-cs-setup-delay-ns and spi-cs-hold-delay-ns to the SPI device child node as per Zephyr 4.3.0 migration guide → no improvement

Questions:

  • Are there any breaking changes in NCS 3.4.0 / Zephyr 4.3.0 related to SPI that I might be missing?
  • Is there any additional configuration required for SPI on NCS 3.4.0?

Any help would be greatly appreciated.

Thank you.

Parents
  • Hie Yoshihiro, 

    Thanks for sending your logs and steps you have already verified. You are completely right by adopting to the migration guide entry regarding SPI_DT_SPEC_GET to add spi-cs-setup-delay-ns and spi-cs-hold-delay-ns to Devicetree.

    Since the error is still persisting, Can you please check the following:
    1. In the latest version NCS 3.4.0 (Zephyr 4.3.3),the third parameter (delay) was removed from SPI_DT_SPEC_GET(). SInce you havent changed your main code, can you verify that you are passing only two arguments: node and operation to the SPI_DT_SPEC_GET()?

    2.
    In the new SDK version (NCS v3.4.0), if you are calling a spi_write() immediately followed by spi_read() call to fetch the register data, the driver automatically pull CS HIGH, the instant the write finishes. If this happens mid-sequence, ie. during the continous communication exchange, the SPI sensor ADS1294 will assume you have cancelled the operation and hence will stop communicating and go in sleep state. Thus, the consecutive read functions doesn't get any response from ADC and will read all 0xFFs.
    To fix this, combine the read and write in 1 single command spi_transceive_dt()

    Please let me know if updating the call to spi_transceive_dt() resolves the 0xFF reads on your setup!

    Best regards

    Pallavi

Reply
  • Hie Yoshihiro, 

    Thanks for sending your logs and steps you have already verified. You are completely right by adopting to the migration guide entry regarding SPI_DT_SPEC_GET to add spi-cs-setup-delay-ns and spi-cs-hold-delay-ns to Devicetree.

    Since the error is still persisting, Can you please check the following:
    1. In the latest version NCS 3.4.0 (Zephyr 4.3.3),the third parameter (delay) was removed from SPI_DT_SPEC_GET(). SInce you havent changed your main code, can you verify that you are passing only two arguments: node and operation to the SPI_DT_SPEC_GET()?

    2.
    In the new SDK version (NCS v3.4.0), if you are calling a spi_write() immediately followed by spi_read() call to fetch the register data, the driver automatically pull CS HIGH, the instant the write finishes. If this happens mid-sequence, ie. during the continous communication exchange, the SPI sensor ADS1294 will assume you have cancelled the operation and hence will stop communicating and go in sleep state. Thus, the consecutive read functions doesn't get any response from ADC and will read all 0xFFs.
    To fix this, combine the read and write in 1 single command spi_transceive_dt()

    Please let me know if updating the call to spi_transceive_dt() resolves the 0xFF reads on your setup!

    Best regards

    Pallavi

Children
  • Hi Pallavi

    Thanks for advise. The root cause was how the chip select (CS) was being obtained.

    Before:

    static const struct device *dev_spim1 = DEVICE_DT_GET(DT_NODELABEL(spi1)); static const struct spi_config cfg_spim1 = { .operation = (SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_MODE_CPHA), .frequency = 4000000U, .cs.gpio = GPIO_DT_SPEC_GET(DT_NODELABEL(spi1), cs_gpios), .slave = 0, };

    After:

    static const struct spi_dt_spec spec_ads1294 = SPI_DT_SPEC_GET(DT_NODELABEL(ads1294), (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPHA), 0);

    In the previous code, I was trying to get the CS directly from the bus node (spi1) using GPIO_DT_SPEC_GET. However, the mapping between cs-gpios and each device is determined by the reg property of the child node, so CS was not being asserted correctly.

    By using SPI_DT_SPEC_GET with the child device node (ads1294) instead, the CS is obtained correctly. This worked on both NCS v3.2.4 and v3.4.0.

    Note: SPI_DT_SPEC_GET requires 3 arguments on NCS v3.2.4, with the third argument being the CS delay (set to 0).

Related