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

SPIM3 transfer raises sleep current by 700 uA from then on

I have two SPI buses on my board, with a different type of slave chip on each.  Only a few bytes are read from each during boot.  When I use SPIM0, 1 or 2 for them there is no effect on the sleep current (about 2uA in my system).  When I use SPIM3 for either bus, the sleep current after the first SPI transfer goes up to 700 uA and stays there forever (until reset).  The only change to the code is to change the module used.

I also tried it with SPI Extended features enabled - same results.

Here is the code:

    nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
    spi_config.frequency      = IMU_SCK_FREQUENCY;  // 4M
    spi_config.ss_pin         = IMU_NRFX_SPIM_SS_PIN;
    spi_config.miso_pin       = IMU_NRFX_SPIM_MISO_PIN;
    spi_config.mosi_pin       = IMU_NRFX_SPIM_MOSI_PIN;
    spi_config.sck_pin        = IMU_NRFX_SPIM_SCK_PIN;
    spi_config.ss_active_high = false;
    spi_config.orc            = 0xFF;
    spi_config.mode           = 0;
    APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));

    nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buf, m_tx_length, m_rx_buf, m_rx_length);
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf, 0, m_rx_length);
    spi_xfer_done = false;
    // Start the SPI sequence
    APP_ERROR_CHECK(nrfx_spim_xfer(&spi, &xfer_desc, 0));
    while (!spi_xfer_done)
    {
        __WFE();    /* sleep, wait for event to wake */
    }

Why is SPIM3 acting so different?  This seems like more of a possible SoftDevice problem than hardware since I would expect the SPI to stop when not in use.  I am using S113 version 7.2.0, and the SDK is version 17.0.2.

Parents Reply
  • Yes, it is definitely the nRF52833.  I just tried adding NRF_SPIM3->ENABLE = 0 to the end of the SPI transactions (without the extra register write in the workaround) and that was enough to get rid of the extra 700 uA.

    As you can see, I was using higher level code rather than direct register writes, and I didn't see any function to disable an SPI like that direct register write does.  Since SPI0, 1, and 2 seem to stop using current when they aren't in use, I assumed they were somehow being shut down by the SoftDevice or something.  Should I be using the ENABLE register to shut them down too?  It is curious that only SPIM3 continues to use current after a transfer with exactly the same code.  Does that indicate that some code in the SoftDevice for SPIM0-2 needs to be extended to SPIM3 as well?

    Anyway, the ENABLE register solve my problem, so thank you!

Children
  • The SPIM3 HW implementation is in fact a bit different than SPIM0-2 (because of some resource sharing with TWI), so I suspect that the problem is due to some HW issues which are only present in SPIM3. I will report this internally so that we can try to figure out what is going on here. Anyways, I think it is good practice to disable the peripheral manually when not in use. You can check out the nrfx_spim_uninit() function, which should be equivalent to using the ENABLE register. I also think it is good practice to stick with the nrfx driver and avoid using registers directly (unless it's required by the errata workarounds). So if you can try the nrfx_spim_uninit() function with SPIM3 and see if that solves the issue instead of using the ENABLE register, I think that would be better. Or at least run the nrfx uninit before the register write, so that the driver is properly uninitialized first.

  • I replaced the register write with 

    nrfx_spim_uninit(&spi);
    and that worked.  That also makes it more universal to work with any SPIM module selected for spi.  Thanks!
Related