This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Is Errata 109 occurrence related to SPI frequency?

I have been having issues with our Flash component (S25FL256S) over SPI with the nRF52832 using easyDMA. When reading out values of a peripheral, the returned contents are sometimes empty. This has been seen very often when using a low SPI frequency (256 kHz), and much less frequently at 8 MHz.

We init the flash with the nrf_drv_spi abstraction layer.

nrf_gpio_cfg_output( FLASHMEM_CS );
nrf_gpio_pin_set( FLASHMEM_CS );

nrf_delay_ms( 100 );

nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;

spi_config.ss_pin   = FLASHMEM_CS;
spi_config.miso_pin = FLASHMEM_SDO;
spi_config.mosi_pin = FLASHMEM_SDI;
spi_config.sck_pin  = FLASHMEM_SCK;
spi_config.frequency = NRF_DRV_SPI_FREQ_8M;

spi_config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;

spi_config.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST;
spi_config.mode = NRF_SPI_MODE_0;  //CPHA = 0 CPOL = 0
LOG_FLASH( "Trying to init SPI\n" );
ret_code_t ret_code =  nrf_drv_spi_init( &spi, &spi_config, spi_event_handler, NULL /* p_context  */ );
LOG_FLASH( "nrf_drv_spi_init - ret_code %d\n", ret_code );
APP_ERROR_CHECK( ret_code );

and are making our spi calls through a function to abstrtact the nrf_drv_spi_transfer command

static bool spiXfer( spi_cmd_t * spiCmd ) {
    uint32_t rxLength = 0;
    ret_code_t ret_code;

    // if queue empty, return
    if ( spiCmd == &CUSTOM__EMPTY_SPI_CMD) return true;

    memset( spi_rx_buf, 0, CUSTOM__SPI_BFF_SIZE );

    logSpiCmdDetails(spiCmd);

    // nordic uses a shift buffer, rx must be length of tx+rx
    if(spiCmd->rxLength){
        rxLength += spiCmd->txLength;
        rxLength += spiCmd->rxLength;
    }

    ret_code = nrf_drv_spi_transfer( &spi,
                                     spiCmd->txData,
                                     spiCmd->txLength,
                                     spi_rx_buf,
                                     rxLength );

    APP_ERROR_CHECK( ret_code );
    return((ret_code == 0) ? true : false);
}

the values being passed into this function have been confirmed as correct.

Since this issue has a similar symptom of Errata 109, I was wondering if it could be related.

In this case, enabling the Errata 109 workaround is having no effect on the results.

  • The receive buffer has a default callback, which manages a queue of SPI commands. Read commands are provided with additional nested function pointers to read out the data (ex. memcopy). This nested function pointer is the last part of the default callback.

    At the beginning of each function which uses spiXfer first check a spiBusy flag, if this is true, the command will be ignored, and an error code is returned (to manage a retry). If it is not true, we write true, and proceed to send the command. It will only be marked to false again after the default SPI callback inclusive of the nested function pointer finishes with or without an error.

  • It sounds like your approach should work. It would help if you could share some logic traces of the transfer, and also upload your entire SPI related code or the whole project. If you do not want to share it in public, you can create a case on MyPage and link to this thread.

  • I wanted to say thanks for the help, but we have not been seeing this issue since reducing the amount of work being done alongside the flash reads and writes. For now I am not sure if this problem has anything to do with Errata 109, but instead could have been an issue with resources.

    I will close this issue until we have more time to revisit the builds where this was a problem since some of our changes have proved themselves as an effective workaround.

Related