This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPIM3 reads fail when SoftDevice enabled

Hello, 

I am developing a product that uses an external flash chip and we are using SPIM3 at 32 MHz. In addition we have been attempting to utilize the SoftDevice in order to offer some BLE functionality. But after enabling the SoftDevice (nrf_sdh_enable_request) the communication to the flash chip fails. The most basic example is trying to read the manufacturer id. To do this there is a transfer of 1 command byte(0x9F) and 3 dummy bytes in which the ID is received (0xEF4018). There is no problem reading the flash with the SPIM at full speed normally but when I change the #defines to include the SoftDevice code and re-compile and run the project the read comes back with all zeroes. All the nrf function calls during setup and read return normal error codes (NRF_SUCCESS) it is only the received data that is missing. 

We successfully use SPIM1 for other SPI operations for other peripherals, for instance we have an IO expander connected to SPIM1 and as far as I can tell that is not affected. 

I am honestly stumped as to what the SD enable has to do with the SPIM transfer. Any help is appreciated.



Some of the relevant code follows, please let me know if I should provide any additional snippets. 

static const nrfx_spim_t fastspim = NRFX_SPIM_INSTANCE(FASTSPIM_INSTANCE);

uint32_t
initFastSPIM(void* p_context)
//
// Init the 32 MHz Fast SPI Master. The SPIM port structure might not be initialized yet.
// Returns an NRF error code, good is NRF_SUCCESS.
{

nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG;

spim_config.mosi_pin = 17;
spim_config.miso_pin = 19;
spim_config.sck_pin = 15;
spim_config.ss_pin = NRFX_SPIM_PIN_NOT_USED;
spim_config.frequency = NRF_SPIM_FREQ_32M;

ret_code_t err_code = nrfx_spim_init(&fastspim, &spim_config, spim_event_handler, p_context);

APP_ERROR_CHECK(err_code);

return err_code;

}

void
queryFlashID(uint8_t* rx)
//
// Read 3 ID bytes from the flash into rx
// For W25Q128FV, expected result is EF 40 18
{


uint8_t tx[4];
memset(tx, 0, sizeof(tx));

tx[0] = W25_JEDEC_ID; // request manufacturing id

nrf_gpio_pin_set(PINNUM_nCSF0); // ensure Flash 0 is not selected
nrf_gpio_pin_set(PINNUM_nCSF1); // ensure Flash 1 is not selected
nrf_gpio_pin_clear(PINNUM_nCSF0); // select Flash 0


nrfx_spim_xfer_desc_t desc = {
.p_tx_buffer = tx,
.tx_length = 4,
.p_rx_buffer = rx,
.rx_length = 4
};

uint32_t ret;

spim_done = false;

ret = nrfx_spim_xfer(&fastspim, &desc, 0);
APP_ERROR_CHECK(ret);

 while (!spim_done) {
__WFE();
}


nrf_gpio_pin_set(PINNUM_nCSF0); // ensure Flash 0 is not selected
nrf_gpio_pin_set(PINNUM_nCSF1); // ensure Flash 1 is not selected

//rx buffer is then read and compared against expected


}

The MOSI/MISO/SCLK pins are configured like so:

nrf_gpio_cfg_output(17);
nrf_gpio_cfg_input (19, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_output(15);

Parents
  • I am honestly stumped as to what the SD enable has to do with the SPIM transfer. Any help is appreciated.

    Have look into the errata sheet!

    SPIM3 has a nasty DMA bug. The SD probably just makes it more likely to trigger.

    Basically you need to reseve one (or two, depending on usage scenario) complete RAM blocks for SPIM3, so that there is no CPU data access in that block during DMA.

    Together with SD this is a non-trivial linker script/settings modification. The example workaround in the SDK does not work with SD enabled.

  • Are you speaking about Errata 198? I will try the suggested solution although I am not sure if that describes my problem. Verified by the oscilloscope the clock does not pulse when the SPIM is supposed to be sending/receiving. I don't see ANY transmit data, let alone incorrect ones. 

Reply Children
Related