I have been converting my TWI calls to be asynchronous by specifying a twi_handler, but my NRF52840 does not sleep during the TWI calls.
I use SDK15.3 and s140 softdevice. (I plan to upgrade to SDK17 soon)
When reading the 32 latest XYZ values (192 bytes) from my accelerometer (LIS3DH) I see overall power usage of ~6.6mA for 7.3ms on my PPK2 power profiler.

When I profile the LIS3DH power usage in isolation I see that it is using ~1mA for ~5ms.

I have tested with my custom board and also with a breadboarded NRF52840 Dongle + Sparkfun LIS3DH. I see almost exactly the same on my custom board as on the breadboard with a NRF52840 dongle + Sparkfun LIS3DH
I do not understand why the NRF52840 is not sleeping.
I see ~11uA power usage before and after the TWI calls.
To talk to the LIS3DH I wrote a state machine which runs every ~1100ms, started by a timer. I make the following TWI calls in the state machine.
if (twi_LIS3DH_step == 100)
{
uint8_t reg = LIS3DH_FIFO_SRC_REG;
nrf_drv_twi_tx(&m_twi, LIS3DH_ADDRESS , ®, 1, false); // ask for fifo_src
}
else if (twi_LIS3DH_step == 101)
{
nrf_drv_twi_rx(&m_twi, LIS3DH_ADDRESS , &fifo_src, 1); // read fifo_src to get num_samples to read
}
else if (twi_LIS3DH_step == 102)
{
num_samples = fifo_src & 0b00011111;
uint8_t reg = LIS3DH_OUT_X_L | 0x80;
nrf_drv_twi_tx(&m_twi, LIS3DH_ADDRESS , ®, 1, true); // ask for samples
}
else if (twi_LIS3DH_step == 103)
{
nrf_drv_twi_rx(&m_twi, LIS3DH_ADDRESS , byte_array, 6*num_samples); // read samples (6*num_samples)
}
else if (twi_LIS3DH_step == 104)
{
//Here I normally call a function to process the samples we received but it is commented out at the moment
twi_LIS3DH_step = 0;
}
twi_LIS3DH_step++;
twi_LIS3DH_can_step = false; //wait until twi_handler sets this to true before doing next step
My main loop steps the state machine.
// Enter main loop.
for (;;)
{
// send_data_to_peers();
if (twi_LIS3DH_can_step)
{
LIS3DH_step();
}
if (twi_TMP112_can_step)
{
TMP112_step();
}
idle_state_handle();
}
idle_state_handle looks like this. I have disabled logging with NRF_LOG_ENABLED = 0. I do not printf anything
static void idle_state_handle(void)
{
while (NRF_LOG_PROCESS());
nrf_pwr_mgmt_run();
}
The twi_handler allows the next step to proceed by setting twi_LIS3DH_can_step = true
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
static uint8_t slave_address;
slave_address = p_event->xfer_desc.address;
if (slave_address == LIS3DH_ADDRESS)
{
if (twi_LIS3DH_step >= 100)
{
twi_LIS3DH_can_step = true;
}
}
else if (slave_address == TMP112_ADDRESS)
{
if (twi_TMP112_step >= 100)
{
twi_TMP112_can_step = true;
}
}
}
I have tried setting the TWI .frequency to 400khz, 250K and 100K which just makes the transmission proportionally more time-consuming.
When I reduce the number of bytes requested from 192 to 100, 10 etc I see an approximately proportionally shorter transmission time.
I have tried changing the TWI .interrupt_priority to APP_IRQ_PRIORITY_LOW, APP_IRQ_PRIORITY_MID and APP_IRQ_PRIORITY_HIGH.
What else could be causing this?
Any help is greatly appreciated. I have spent several days on this and I'm running out of ideas.
Kind regards,
-Jason



