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

How to achieve non-blocking I2C and use different flags for the Watchdog?

Hi,

I've been using the Thingy:91 to communicate with some sensors. One of this sensors is causing us some trouble: sometimes the I2C communication with him seems to fail and produces the following behaviour:

-Program blocks, waiting for the response of the unresponsive sensor.

-Watchdog triggers but fails to reset the device (callback function executes).

In order to solve the first problem, ideally it would be that the sensor never fails, but for robustness purposes it would be nice to be able to force a stop condition (or something that would free the i2c communication) on the bus after a certain amount of time. Searching in the devzone I have found information on non-blocking TWI but some of these posts are 2 years old and I am not sure if the code they talk about is the way to go with the Thingy:91. Additionally I am not aware of a timeout possibility when using i2c.h. Could you explain me when to use i2c/twi/twim functions and when not? Is there any function I could use in order to implement a timeout?

Moreover, I have a problem with the Wathcdog. When the watchdog triggers due to the i2c blockage, it executes the callback function (where I make the LEDs on the Thingy:91 blink white) but afterwards it fails to reset the device. Motivated by this error, I tried other behaviours when the wathcdog triggers, which are defined on its setup. I found out that when I use the flags "WDT_FLAG_RESET_CPU_CORE" and "WDT_FLAG_RESET_NONE" there is an error and the device enters a rebooting loop. Would this be a normal behaviour, meaning that the only flag I can use is "WDT_FLAG_RESET_SOC"?

Thank you very much for your help.

Aleix.

  • Hi,

     

    -Watchdog triggers but fails to reset the device (callback function executes).

    Are you sure the watchdog is configured correctly? it will reset your device if it expires. 

     

    In order to solve the first problem, ideally it would be that the sensor never fails, but for robustness purposes it would be nice to be able to force a stop condition (or something that would free the i2c communication) on the bus after a certain amount of time. Searching in the devzone I have found information on non-blocking TWI but some of these posts are 2 years old and I am not sure if the code they talk about is the way to go with the Thingy:91. Additionally I am not aware of a timeout possibility when using i2c.h. Could you explain me when to use i2c/twi/twim functions and when not? Is there any function I could use in order to implement a timeout?

     How does the communication on the SCL/SDA lines look while this happens? Is the slave performing clock-stretching?

    The i2c driver in zephyr (the nRF port file can be found here: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/i2c/i2c_nrfx_twim.c) does not have a asynchronous API. You can run the i2c logic in its own thread to mimic asynchronous operation, seen from the applications point of view, as it would then yield for other threads in your system.

    Which TWIMx peripheral are you using? Note that SPI*/UART/TWI* peripherals are shared peripherals, meaning that you cannot have UART1 and SPIM1 (or TWIM1 for that matter) enabled simultaneously.

     

    Moreover, I have a problem with the Wathcdog. When the watchdog triggers due to the i2c blockage, it executes the callback function (where I make the LEDs on the Thingy:91 blink white) but afterwards it fails to reset the device. Motivated by this error, I tried other behaviours when the wathcdog triggers, which are defined on its setup. I found out that when I use the flags "WDT_FLAG_RESET_CPU_CORE" and "WDT_FLAG_RESET_NONE" there is an error and the device enters a rebooting loop. Would this be a normal behaviour, meaning that the only flag I can use is "WDT_FLAG_RESET_SOC"?

     _RESET_SOC will produce an error: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/watchdog/wdt_nrfx.c#L81

    Can you share your implementation of the watchdog init and enable? Does this sample also not work if you try it? https://github.com/nrfconnect/sdk-zephyr/blob/master/samples/drivers/watchdog/src/main.c

     

    Kind regards,

    Håkon

  • Hi Håkon,

    Are you sure the watchdog is configured correctly? it will reset your device if it expires. 

    I noticed that the watchdog may be resetting the device, but that it fails to boot after the reset due to external electrical problems. Nothing related to the software, I guess.

     How does the communication on the SCL/SDA lines look while this happens? Is the slave performing clock-stretching?

    I have seen these lines pulled-down but I remember that only one of them at a time. Also, shorting them to VDD have sometimes unblocked the communication

    The i2c driver in zephyr (the nRF port file can be found here: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/i2c/i2c_nrfx_twim.c) does not have a asynchronous API. You can run the i2c logic in its own thread to mimic asynchronous operation, seen from the applications point of view, as it would then yield for other threads in your system.

    Do you advise me to change to this library and use i2c_nrfx_twim_transfer instead of a regular i2c_read? Is there any advantage?

    Which TWIMx peripheral are you using? Note that SPI*/UART/TWI* peripherals are shared peripherals, meaning that you cannot have UART1 and SPIM1 (or TWIM1 for that matter) enabled simultaneously.

    I am using TWIM2 and not using either SPIM2 nor UART2.

    Oh okay, I did not know that, thank you!

    In conclusion: I think there was not a software problem with the watchdog, besides the _RESET_SOC point. I will implement the i2c in a thread in order to achieve "asynchronous communication" and I wait for your advise on if I should change my library and on how could I unblock the i2c communication via software without resetting the device.

    Thank you very much!

    Aleix.

  • Hi,

     

    Krawlow said:
    I have seen these lines pulled-down but I remember that only one of them at a time. Also, shorting them to VDD have sometimes unblocked the communication

    Can you capture the i2c communication using a logic analyzer to see what happens ?

     Its hard to comment without seeing more detailed info of why it blocks your application for longer periods.

     

    Krawlow said:
    Do you advise me to change to this library and use i2c_nrfx_twim_transfer instead of a regular i2c_read? Is there any advantage?

     Its the same library. i2c.h functions map to this file using syscalls (function pointers).

    You can use the NRFX driver directly (NRFX_TWIM=y), if you'd like, but then you have to re-write your application, and you cannot use the pre-made libraries for sensors.

     

    Kind regards,

    Håkon

Related