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

GPIOTE and SPI high power consumption on sleep

Hello everyone.

I am currently working on a device with some peripherals. I have SPI slaves and other sensors that I am monitoring using GPIOTE driver.

I noticed a consumption of 0.470mA while sleeping under the following circumstances:

  • Configure SPI1 as master using DMA
  • Make a simple exchange with the slave
  • Enable GPIOTE IN to detect an interrupt on a PIN
  • Go to sleep (sd_app_event_wait())
  • Use non deferred LOGs

Note that the residual consumption happens IF AND ONLY IF the exchange happens on SPI AND GPIOTE is enabled after this exchange. SPI code alone does not make that consumption to happen, neither that GPIOTE.

I am currently building a project to make it easier for you to reproduce so that I will share it here.

[EDIT] :

Here is a project code than can be placed in <SDK_root>/examples/peripheral

spi_and_gpiote.zip

To reproduce the issue:

  • flash a PCA10040 with the SPIS example (board A)
  • extract the zip file attached in the SDK, compile and/or load on another PCA10040 (board B)
  • Link both boards with SPI bus, connect respective PINs P0.03, P0.04, P0.28, P0.29 to one another
  • Cut the SB9 on the board B to hook current measures here
  • Start both boards: you will see no extra consumption
  • Push any button on the master board to trig the sent of a packet on SPI lines and watch the current rise and then lower to no less that 0.470uA

[/EDIT]

Configuration:

  • NRF52832
  • Softdevice S132
  • PCA10040 x2, consumption measured on the board that is the master, the second one runs the slave SPIS example from the SDK
  • SDK 12.1.0 (nRF5_SDK_12.1.0_0d23e2a)

Here is my current main:

int main(void)
{
    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;

    // Init GPIOTE driver
    APP_ERROR_CHECK(nrf_drv_gpiote_init());
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_INFO("Start Silego BU project\r\n");
    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);

    // Initialize SoftDevice.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
    // - Buttons and leds
    buttons_leds_init();
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = 29;
    spi_config.miso_pin = 28;
    spi_config.mosi_pin = 4;
    spi_config.sck_pin  = 3;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));

    // Exchange with SPI slave
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));

    #define PIN_TEST    23
    // Configure interrupt as rising edge...
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    
    // ... and no pull action on the line
    in_config.pull = NRF_GPIO_PIN_PULLDOWN;
    //in_config.pull = NRF_GPIO_PIN_NOPULL;
    
    // Init GPIOTE with configuration on PINs
    APP_ERROR_CHECK(nrf_drv_gpiote_in_init(PIN_TEST, &in_config, silego_irq_handler));
    nrf_drv_gpiote_in_event_enable(PIN_TEST, true);

    // Enter main loop.
    for (;;)
    {
        NRF_LOG_DEBUG("EnterPWR MGT\r\n");
        APP_ERROR_CHECK(sd_app_evt_wait());
        NRF_LOG_DEBUG("Exit PWR MGT\r\n");
        LEDS_INVERT(BSP_LED_0);
    }
}
Related