Incorrect first bit on MOSI during SPI transfer (nRF54L15, Mode 0, prescaler > 2)

Hello,

I'm developing with an nRF54L15 Revision 1 (QFAA-B00). I'm encountering a problem described in the errata:
3.4 [8] SPIM: Wrong data is transmitted on MOSI
(Symptom: When SPIM is used with CPHA=0, prescaler > 2, and the first bit to transmit is '1', the data on MOSI is incorrect).

I am using Zephyr (nRF Connect SDK v3.0.2) and the SPI API (spi_transceive_dt() from <zephyr/drivers/spi.h>).

I have confirmed that the workaround is executed:
USE_WORKAROUND_FOR_ANOMALY_NRF54L_8_NRF54H_212 is defined in the NRFX driver (nrfx_spim.c), and the code performs the actions described in the errata:
- Sets CSNDUR to (prescaler / 2 + 1)
- Writes 0x82 to the SPIM register at offset 0xc84 before starting the transfer
- Resets this register to 0x00 after EVENTS_STARTED

However, even with this workaround active, the first bit problem persists:
- On the oscilloscope, the MOSI line only transitions to ‘1’ on the rising edge of SCK instead of being centered between clock edges
- As a result, the slave samples the wrong value for the first bit if it is ‘1’.
- This behavior only affects the first 8-bit word after each CSN (SS) activation, and only if the first bit is '1'.

My configuration:
- Custom board, nRF54L15 Revision 1 (QFAA-B00), also tested with Engineering B (QFAA-BB0) – same issue
- SPI frequency: 2 MHz (prescaler = 64)
- SPI mode 0 (CPOL=0, CPHA=0)
- Using instance SPIM00
- Zephyr nRF Connect SDK v3.0.2

Oscilloscope captures:

The first bit transitions to ‘1’ on the rising edge of SCK instead of being centered between clock edges
 


Can you confirm if anything else is required on the application (or configuration) side to ensure the workaround is fully effective when using Zephyr’s SPI API? Are there any known limitations or further steps to handle this errata in this context?


Thank you for your support,

Baptiste
Parents
  • Hi

    We have not made any progress no. What pins and sample project(s) are you seeing this issue on? I'd like to reproduce it but haven't been able to yet.

    Best regards,

    Simon

  • Hi, to reproduce this issue you need an nRF54L15 DK v1.0.0:
    https://www.nordicsemi.com/Products/Development-hardware/nRF54L15-DK
    https://docs.zephyrproject.org/latest/boards/nordic/nrf54l15dk/doc/index.html

    I see the same problem on different board revisions and on our custom hardware.
    This DK includes an SPI flash module configured in the device tree, so we can use it to reproduce the behavior.

    To get the SPI signal on the header, you must use the board configurator and disable the external memory, as shown here:

    Below is a minimal example that sends data over SPI using the default SPI00 pinout that is:

    SCK P2.1

    MOSI P2.2



    main.cpp

    #include <zephyr/drivers/spi.h>
    
    int main(void)
    {
        const struct device* spi00 = DEVICE_DT_GET(DT_NODELABEL(spi00));
    
        struct spi_config spi_cfg = {
            .frequency = 2000000,
            .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
            .slave = 0,
            .cs = {.gpio = {.port = NULL, .pin = 0, .dt_flags = 0}, .delay = 0},
        };
    
        uint8_t tx_buffer[] = {0xFF, 0x00, 0xFF, 0x00, 0xAA};
        uint8_t rx_buffer[5] = {0};
    
        struct spi_buf tx_buf = {
            .buf = tx_buffer,
            .len = sizeof(tx_buffer),
        };
    
        struct spi_buf_set tx_bufs = {
            .buffers = &tx_buf,
            .count = 1,
        };
    
        struct spi_buf rx_buf = {
            .buf = rx_buffer,
            .len = sizeof(rx_buffer),
        };
    
        struct spi_buf_set rx_bufs = {
            .buffers = &rx_buf,
            .count = 1,
        };
    
        while (1)
        {
            spi_transceive(spi00, &spi_cfg, &tx_bufs, &rx_bufs);
            k_msleep(10);
        }
    }


    proj.conf

    CONFIG_SPI=y
    

    To build:

    west build -b nrf54l15dk/nrf54l10/cpuapp


    To flash:

    west flash


    There is also hex file:

    2100.merged.hex

    And screen from osciloscope. SCK on top, MOSI on botton:



Reply
  • Hi, to reproduce this issue you need an nRF54L15 DK v1.0.0:
    https://www.nordicsemi.com/Products/Development-hardware/nRF54L15-DK
    https://docs.zephyrproject.org/latest/boards/nordic/nrf54l15dk/doc/index.html

    I see the same problem on different board revisions and on our custom hardware.
    This DK includes an SPI flash module configured in the device tree, so we can use it to reproduce the behavior.

    To get the SPI signal on the header, you must use the board configurator and disable the external memory, as shown here:

    Below is a minimal example that sends data over SPI using the default SPI00 pinout that is:

    SCK P2.1

    MOSI P2.2



    main.cpp

    #include <zephyr/drivers/spi.h>
    
    int main(void)
    {
        const struct device* spi00 = DEVICE_DT_GET(DT_NODELABEL(spi00));
    
        struct spi_config spi_cfg = {
            .frequency = 2000000,
            .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
            .slave = 0,
            .cs = {.gpio = {.port = NULL, .pin = 0, .dt_flags = 0}, .delay = 0},
        };
    
        uint8_t tx_buffer[] = {0xFF, 0x00, 0xFF, 0x00, 0xAA};
        uint8_t rx_buffer[5] = {0};
    
        struct spi_buf tx_buf = {
            .buf = tx_buffer,
            .len = sizeof(tx_buffer),
        };
    
        struct spi_buf_set tx_bufs = {
            .buffers = &tx_buf,
            .count = 1,
        };
    
        struct spi_buf rx_buf = {
            .buf = rx_buffer,
            .len = sizeof(rx_buffer),
        };
    
        struct spi_buf_set rx_bufs = {
            .buffers = &rx_buf,
            .count = 1,
        };
    
        while (1)
        {
            spi_transceive(spi00, &spi_cfg, &tx_bufs, &rx_bufs);
            k_msleep(10);
        }
    }


    proj.conf

    CONFIG_SPI=y
    

    To build:

    west build -b nrf54l15dk/nrf54l10/cpuapp


    To flash:

    west flash


    There is also hex file:

    2100.merged.hex

    And screen from osciloscope. SCK on top, MOSI on botton:



Children
No Data
Related