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

TWI in Low Power...

Hey guys,

Trying to use TWI in the lowest power way possible, non-blocking. Is this the right way to do it? When I run this, I get the callback event handler to execute once, and once only -- seemingly stuck in WFE() or sd_app_evt_wait() , not waking up with the callback. Any ideas as to why?

  nrf_drv_twi_init(&p_twi_instance, &p_twi_config, twi_event_handler); 
  nrf_drv_twi_enable(&p_twi_instance); // Enable the TWI instance   

while(1) {
 
    nrf_drv_twi_rx(&p_twi_instance, 0x55, dummy_data, 7, false);          

    //power_manage(); //sd_app_evt_wait(); //if using SD                                                                                                                                        
    __WFE();   
}
    
static void twi_event_handler(nrf_drv_twi_evt_t *p_evt){   
    if(p_evt->type == NRF_DRV_TWI_RX_DONE)
    {

      SEGGER_RTT_printf(0, "\n\nDATA: ", dummy_data);
      for(i=0;i<7;i++) SEGGER_RTT_printf(0, "%02x ", dummy_data[i]);

    } 
}
  • Hi. Are you sure the handler is only called once? You might get a lot of other events that is not detected by your if-statement.

    Also, I don't know your application but, but a lot of TWI sensors, memory chips, etc, need you to do a TWI TX operation first to tell which address in the device to read from. With nrf_drv_twi_rx() you just tell a device on a specific address "give me data!". You don't tell the device what data you want and this might cause troubles on your TWI bus. Try to add

    [...]
    else
    {
       SEGGER_RTT_printf(0, "\n\nTWI ERROR: %d ", p_evt->error_src);
    }
    

    Or something to listen for other TWI events.

  • Thanks. You're correct. The handler is getting called as fast as possible... it is not sleeping. Inserted this into the handler. SEGGER_RTT_printf(0, "\n\nTWI ERROR: %d ", p_evt->error_src); The results: TWI ERROR: 2 But not sure that's helpful. NRF_DRV_TWI_ERROR is defined as 2. So what is this telling us? Seems like we're breaking out of WFE before we actually get real data back successfully, and then immediately try to do another i2c transaction before the previous one completes. Could that be the case? Thanks!

  • Yeah... I just put a flag around the call to nrf_drv_twi_rx and that worked.

    if(RX_ready) nrf_drv_twi_rx..., then RX_ready=FALSE

    Then set RX evt handler, I set RX_ready to TRUE.

    Curious why we exit WFE so quickly without valid TWI data though. I don't know of anything else going on that would interrupt things. Has this TWI driver been optimized for power at all?

    Thanks!

  • Error 2 is

    NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk,    /**< NACK received after sending the address. */
    

    as defined in nrf_twi.h

    So I guess you don't get any response from your external device?

  • Maybe you are getting the NACK event I have mentioned in the comment above. You will get the event right after your nRF5x has transmitted the address and not gotten any response. You won't get any valid data either.

Related