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

power optimal twi tx/rx

Hi - I am wondering what is the power optimal way to read/write with the TWI module. I do a tx and rx with the TWI interface. I have something like this, from the examples to read data from a i2c supported device:

// read from i2c device

uint16_t timeout = 10000;
nrf_drv_twi_tx();

while((!twi_tx_done) && --timeout); // twi_tx_done is in the twi_handler for NRF_DRV_TWI_XFER_TX event
twi_tx_done = false;

timeout = 10000;
nrf_drv_twi_rx();
while((!twi_rx_done) && --timeout); // twi_rx_done is in the twi_handler for NRF_DRV_TWI_XFER_RX event
twi_rx_done = false;

I am not sure if this is the most optimal way of waiting, since it's in a busy loop. Is there a better way to write this?

  • By "optimal" do you really mean "minimum" - or do you also have other factors to consider ?

    Just spinning in a busy loop is never going to be low-power - as it requires the CPU to be running at full speed, without letting it do anything useful.

    Could you not let it sleep, and wake on the "finished" event?

  • Yes, I mean minimal. Not sure what other factors may be involved? In this case it is really about minimizing current draw. 

    I agree busy loop is not optimal. How do I let it sleep until I get an event, say a NRF_DRV_TWI_XFER_TX or NRF_DRV_TWI_XFER_RX? Do I use _WFE() ?

  • Yes, you can use _WFE(). But we recommend using the idle_state_handle() function which flushes the NRF_LOG and runs nrf_pwr_mgmt_run(). Please see the ...\nRF5_SDK_15.0.0_a53641a\examples\ble_central\ble_app_blinky_c example for reference.

    Best regards,

    Simon

  • Not sure what other factors may be involved?

    Common things include:

    • You might need some things to stay active/responsive while you sleep;
    • The more you shut down, the more you have to wake up again to get back into "normal operation";
    • The deeper you sleep, the longer it takes to wake again;
    • Deeper sleep options often have more limited wakeup options;
    • etc, etc, ...

    As says, many (most?) of the SDK examples illustrate sleeping while waiting for events ...

  • I know there is an idle state handler in most examples. May I frame my question slightly differently.

    If I understand correctly the nrf_drv_twi_tx/nrf_drv_twi_rx calls are non-blocking since a twi handler gets a callback when a tx or rx event is complete. So let's say when I want to read a register, so we do a tx and then an rx. Now until I receive the rx event in the handler I haven't actually received the value correctly. If I want to write an API to read a register where I pass a value that will be filled with the register value, I will have to jump to the twi handler and then back or just simply waitusing a delay which is not efficient. So my question would be do you have any suggestion to write this effectively? 

Related