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 

  • Hi Jared,

    1. In the log you see that MTU is set to 247, but then, it go back to 27. It has no effect and works, but i'm surprised to see this.

    2. Good if Timer will not generate interrupt once stopped. I have read it will go until the end ( but may be without generate int). In fact, i can change the timer period on the fly by writing the characteristic, even  when it is running. So, to avoid changing the variable period on the fly while timer is running, my idea was to stopped the timer, update the variable, and start the timer again. Is it the good way to do or if I change the timer period variable while it is running it will just take into account the new value after interupt ?

    3.Yes invalid error was linked to advertise while it is advertising, my state machine was not robust. It depends on advertising timeout setting  and i didn't reach adevertising timeout that i start a new one...

    4.New question: I have a lot of trouble to connect fast. It always take 2 or 3 second with nrf connect, and even worth with our custom app where it could take 6 or 7 second resulting of no connecxion and advertising timeout when i set advertising timeout to 5sec. As now i have sniffer, how can i improve this connexion time (ideally in one second max) or how can i check how is the slowest on my systeme ?

    Thank you !

  • Hi,

    1. Aha, I understand. So, the data length can be changed by either the peripheral itself or by the peer. I assume that the app acts a central and would therefore have the final say regarding the connection parameters. A sniffer trace would clarify which device that asks for the change in data length.  The benefit of a small MTU is that it has less chance of interference. Interference would cause you to re-transmit the whole data pack, which is not good if you have a large data pack such as 247 bytes. It's therefore typical that the data length changes accordingly to the size of the data that is sent. 
    2. If you referring to the application timer, then It won't generate any events after you have stopped it. Yes, the safest would be to stop the timer and initialize it again with new timer period, and then restart it. 
    3. Ok
    4. The best method would be to do a direct advertising during start up. You should also use a short scan interval, short scan window, and a short advertising interval. 

    best regards

    Jared 

  • The best method would be to do a direct advertising during start up. You should also use a short scan interval, short scan window, and a short advertising interval. 

    HI Jared,

    Ok I see , most of the time my system sleeps. With accelerometre it wakes up and start to advertise. My settings are:

    #define APP_ADV_INTERVAL                100//fle debug300                                         /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
    #define APP_ADV_DURATION                1000 //180 00 :180sec , 100 :1sec            /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
    
    #define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(10, UNIT_1_25_MS)            /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)            /**< Maximum acceptable connection interval (0.2 second). */
    #define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds). */
    
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
    #define SEC_PARAM_MITM                  1                                           /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC                  0                                           /**< LE Secure Connections not enabled. */
    #define SEC_PARAM_KEYPRESS              0                                           /**< Keypress notifications not enabled. */
    #define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_DISPLAY_ONLY                        /**< No I/O capabilities. */
    #define SEC_PARAM_OOB                   0                                           /**< Out Of Band data not available. */
    #define SEC_PARAM_MIN_KEY_SIZE          7                                           /**< Minimum encryption key size. */
    #define SEC_PARAM_MAX_KEY_SIZE          16                                          /**< Maximum encryption key size. */
    
    #define DEAD_BEEF                       0xDEADBEEF    
    

    I have to admit i'm sure of what is doing what, that could explain the time to connect also. Do you think i can improve some of these setting to be more efficient ? What could be the impact in terme of consumption increasing?

    I join you a sniffer trace : 

    with_nrfConnect.pcapng

  • HI Jared ,

    Our connexion latency is solved ( it was linked to our system).

    I will open dedicated topics for other issue i have , and there is ... Smiley

  • Hi,

    Ok. Just want to comment that you need to start capturing before the link is decrypted. The sniffer trace doesn't fully show the communication as the link is encrypted. You have either turn off pairing or capture a trace when they pair so that the key can be sniffed by the sniffer and so that it can decrypt the link.

    regards

    Jared 

Reply Children
  • You point exactly the probleme i'm faced at the moment: 

    I was working on pairing because i have this strange issue:

    My program is based on hrs example + dfu merging.

    I was thinking that, by using pairing protection with 6 digit fixed pathkey( no other choice cause no IO), i would not be able to read/write my characteriqtics. But with nrfConnect, if you are fast enough, when bounding window pops up , and you click cancel and really fast after, you are able to click on the row to read a characteristics, the connexion is maintained and you have access to all , without been securly paired !!! 

    I know i can protect each caracteristic by using : BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM , what i did. 

    But a side effect appears: after first pairing on the phone by writing the 6 digit passkey, the same windows pops up FOR EACH characteristic you read ( only the first time) ... so it s a bit anoying because you have the feeling to have paired at connexion step , but in fact it has absolutely no impact on security.

    If you click cancel you are still connected and if fast enough you can even have access to all. If you paired successfully, you will have to enter this same path key for each characteristic you have protected, what give a strange effect to the final user, he has the feeling that first pairing didn't worked.

    What i need is : ask pairing after connect. If android user enter correct path kay , no more ask user to enter pathkey. If no or cancel, close connexion or retry but doesn't give access. Only paired device should have access.

    But now i get this error when i want to enter the passkey on android phone:

    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> nrf_sdh_ble: BLE event: 0x13.
    <error> peer_manager_sm: Could not perform security procedure. smd_params_reply() or smd_link_secure() returned NRF_ERROR_INVALID_ADDR. conn_handle: 0
    <error> peer_manager_handler: Unexpected fatal error occurred: error: NRF_ERROR_INVALID_ADDR
    <error> peer_manager_handler: Asserting.
    <error> app: ERROR 16 [NRF_ERROR_INVALID_ADDR] at C:\nordic\nRF5SDK160098a08e2\components\ble\peer_manager\peer_manager_handler.c:294
    

  • Hi,

    My understanding is that the original problem regarding the TWI has been solved. We are happy to help you with the issue regarding pairing but would prefer that you made a new ticket for it. That makes it easier for other users on this forum to follow this thread when they have a similar twi problem etc.. 

    best regards

    Jared

  • I agree , i understand , i already move quiet a lot from original subject, new ticket is already created , thanks a lot !

Related