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

TWI transfert stuck

Hi,

I'm communicate with my sensor by using TWI ( i2c) driver. Most of the time, no problem.

But yesterday , i was debugging, and and ble disconnect event happen ( it print in the console). After that, i was surprised to see that my programmin were stuck somewhere.

It was in this communication sensor function where i'm waiting for transfert to be complete : 

      m_xfer_done = false;
      err_code = nrf_drv_twi_tx(&m_twi, slaveAddr, &cmd, 4, REPEAT_START_CONDITION);
      APP_ERROR_CHECK(err_code);
      while (m_xfer_done == false);

I don't know why the transfert didn't fully finished, but i need a way to not stay stuck here. Is there handler or timeout mecanism to use may be to avoid this issue please with TWI module ?

Thank you !

Parents
  • Hi,

    You can always use the application timer library and start a timer before the loop that sets the flag to true after a certain time has elapsed. However, I think it would be better to find the root cause of the issue. Is the application resetting when the the ble disconnects? Could it be that the I2C bus is left in a invalid state such as this?

    regards

    Jared

  • Hi Jared, thanks for fast reply.

    There is no problem with communication with the sensor. I can connect, disconnect without having issue with communication in "normal mode".

    Good point is that i can reproduce on demand the problem. 

    It happens always , when with our own flutter app, we read a certain characteristic.

    With nrfConnect android app, it never happens by reading this same caracteristic.

    With our app, it seems to read the characteristic and then, make occurs a disconnection of the nrf52833.

    When we read other characteristics, no problem.

    I'm surprised, first because with nrfConnect there is no problem, and then, why does it produce an effect on twi. It is stucked on this while waiting for the flag to be set by the TWI Event Handler, that in the three possible case, should set this flag to true, event if there is an error:

    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
                {
                   m_xfer_done = true;
                }
                m_xfer_done = true;
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_ERROR("i2C data NACK");
                m_xfer_done = true;                 //to not be stuck, even if there is an issue
           case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_ERROR("i2C adress NACK");
                m_xfer_done = true;                //false to adresse means no device connected
                m_xfer_ack_adress_ok = false;
                break;
            default:
                break;
        }
    }

    That's mean, when the disconnect event occurs, i'm not able to reach the TWI event anymore.

    Witch register can i checked to understand the problem ? Could be a priority that avoid TWI to create an event or something like this may be ?

    thank you 

Reply
  • Hi Jared, thanks for fast reply.

    There is no problem with communication with the sensor. I can connect, disconnect without having issue with communication in "normal mode".

    Good point is that i can reproduce on demand the problem. 

    It happens always , when with our own flutter app, we read a certain characteristic.

    With nrfConnect android app, it never happens by reading this same caracteristic.

    With our app, it seems to read the characteristic and then, make occurs a disconnection of the nrf52833.

    When we read other characteristics, no problem.

    I'm surprised, first because with nrfConnect there is no problem, and then, why does it produce an effect on twi. It is stucked on this while waiting for the flag to be set by the TWI Event Handler, that in the three possible case, should set this flag to true, event if there is an error:

    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
                {
                   m_xfer_done = true;
                }
                m_xfer_done = true;
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_ERROR("i2C data NACK");
                m_xfer_done = true;                 //to not be stuck, even if there is an issue
           case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_ERROR("i2C adress NACK");
                m_xfer_done = true;                //false to adresse means no device connected
                m_xfer_ack_adress_ok = false;
                break;
            default:
                break;
        }
    }

    That's mean, when the disconnect event occurs, i'm not able to reach the TWI event anymore.

    Witch register can i checked to understand the problem ? Could be a priority that avoid TWI to create an event or something like this may be ?

    thank you 

Children
  • Hi,

    Olfox said:

    With our app, it seems to read the characteristic and then, make occurs a disconnection of the nrf52833.

    So the application is probably hitting an error when you try to write to the characteristic from your own custom app. This error is probably causing sd_ble_gap_disconnect() to be called somewhere in your code resulting in the disconnect. This is somehow affecting the TWI communication.

    What I would like to know about the ble communication is:

    1. What kind of error is causing the disconnection? Set a breakpoint in the ble handler where you call sd_ble_gap_disconnect() and check what event that is causing the disconnect. Could you also take a nRF Sniffer trace while you reproduce the error? Upload the trace here. 
    2. What is the state of the application after it has disconnected? Is it stuck in the error handler?  Does the application reset? Is it stuck somewhere else in your application? This can easily be verified by using a debugger.

    What I would like to know about the TWI communication is:

    1. If you reset the Nordic IC. Does the TWI slave respond again? 
    2. Could you upload a trace of the SDA and SCL line when application is stuck? 
    3. Could you print something in the beginning of the twi_handler() before the switch case and see if the handler is called at all after the disconnection. 
    4. You're missing a break; in the error handler in the NRF_DRV_TWI_EVT_DATA_NACK case.

    As you may understand, I need to know a lot more of what exactly happens to find the root cause. I would appreciate it if you answered the questions above to the best of your capability. 

    regards
    Jared 

  • Hi Jared,

    1. I have installed the ble siniffer on my 10100 dev kit (52833 but seems to work with 52832 .hex)

    ------------

    But i'm totally stuck at the moemnt with bootloader. As i'm using dfu, i have bootloader dfu . But as it checked every time crc i decided to move on debug bootloader that normally doesn't check. But now i'm unable to debug my fw, it is programmed, but normally after that there is a breakpoint in the main entry point but here nothing happen, the programm seems to run but nothing happen i can't debug anymore...

    Even when i come back on secure bootloader and generate settings, i can't start debugging my fw.

    Disappointed

    -------------

    For the TWI bug, in fact i realise it happen on the board where the sensor is not connected ( i have to type of board , but one software). So when error happen, it jump to adress NACK in the handler twi, but goes nowhere after that. May be should i clear an error flag or something?

    ------------

    I will ry your proposal a soon as i'm able to debug again.

  • i remeber i add to set ram and flash adress in the past , may be it has move?

    here my bootloader that i flash:

    here section settings of the bootloader

    i'm working with nrf52833

    Here when i flash my application:

    I'm really not confident with dfu bootloader, setting , checked signature, CRC etc ... it is a bit a weak point that i need to work on

  • Ok i found the issue, it came from breakpoint ... i had to clear all breakpoint. Now i can debug without generating each time the setting.page.

    I also make progress. There is a link between disconnection and the fact that our app try to write more than 20bytes into our characteristic. on this we do some stroke to managae each field individually and update some variable.

    So i have updated the NRF_SDH_BLE_GATT_MAX_MTU_SIZE in file sdk_config.h

    And i get an error on build:

    After updating the RAM start and size:

    I receive all my char !

    Q1:But when i'm looking the log i see this: 

    It works anyway...

    Q2: In my characteristics, i update timer periode by first stopping, change variable, and start again. It seems to not generate interupt anymore. After using stopped timer function, isa  last interupt rasied before to be totally inactive ? In that case it will be dangerous because when i stop a timer, i also switch off sensors, so if a last interupt occurs after switch off, it will not be good at all.

    Concerning the TWI issue, i think it was a side effect of all this combinaison of problems and was certainly not directly linked to this. I also avod to try to communicate with this missing device by searching for it one time a initialisation step. If missing, all communication with it will not be done in all code, to avoid wasting time and getting errors. It will also never be hot plugged so no problem.

    For the product with the sensors, i will try to re create issu by removing it once in communication to see if program get stucked in case of nack of adress or data because i dont like to let a while like this that coud block all the system...

    Q3: concerning disconnexion, i was responsible of it with the fw. Our app set a field that toogle the product in a mode where we disconnect all connexion and advertise each minute, then sleep again. I was juste not aware that this field was set by our app at this time ... lol. How is it possible to know if we are advertising, is here a function to know it ? or if we are advertising, to relaunch an advertising sequence ( exemple, i'm advertising for already 8sec/10 after timeout, i want to restart adverting for 10sec without waiting the end of the first sequence without triggered this error that i have at the moment: 

    Thanks a lot for your help Jared, Nordic is really the best for support , i don't regret my choice to move from NXP to you :D 

  • Hi again,

    So I've read through your recent replies but I'm not sure what to conclude. It seems that you have solved some of the issues but still have some questions you would like to get answered:

     

    Olfox said:

    Q1:But when i'm looking the log i see this: 

     I can't see that the log is actually reporting any errors? Anything specifically about it you were wondering about?

     

    Olfox said:

    In my characteristics, i update timer periode by first stopping, change variable, and start again. It seems to not generate interupt anymore. After using stopped timer function, isa  last interupt rasied before to be totally inactive ? In that case it will be dangerous because when i stop a timer, i also switch off sensors, so if a last interupt occurs after switch off, it will not be good at all.

    Concerning the TWI issue, i think it was a side effect of all this combinaison of problems and was certainly not directly linked to this. I also avod to try to communicate with this missing device by searching for it one time a initialisation step. If missing, all communication with it will not be done in all code, to avoid wasting time and getting errors. It will also never be hot plugged so no problem.

    For the product with the sensors, i will try to re create issu by removing it once in communication to see if program get stucked in case of nack of adress or data because i dont like to let a while like this that coud block all the system...

     I'm not sure if I understood this correctly. The application timer will not generate another interrupt after the timer has been stopped. 

    Olfox said:
    concerning disconnexion, i was responsible of it with the fw. Our app set a field that toogle the product in a mode where we disconnect all connexion and advertise each minute, then sleep again. I was juste not aware that this field was set by our app at this time ... lol. How is it possible to know if we are advertising, is here a function to know it ? or if we are advertising, to relaunch an advertising sequence ( exemple, i'm advertising for already 8sec/10 after timeout, i want to restart adverting for 10sec without waiting the end of the first sequence without triggered this error that i have at the moment: 

     Then you have to stop advertising, and then start it again with a new set of advertising parameters that has the new timeout. Trying to start advertising when it's already advertising will result in a INVALID STATE error. 

    happy to help! Slight smile

    best regards

    Jared

Related