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

Not Exiting "while loop" after a TWI event

Hi,

I'm facing a weird problem resulting from the following code:

while((!twi_tx_done) && timeout--); 

The main file and the MPU9150.c which includes this command are attached main-2016-02-16.c mpu9150.c. Normally the program should exit this loop whenever a TWI transmit is complete and the handler sets twi_tx_done = true. Timeout is just setting a limit on the wait time for TWI to get completed.

I'll explain below how I tested the program, but the result is that: when the loop is empty, it ALWAYS exits with the timeout = 0 (which is much longer than what a normal twi_tx is). Checking inside the handler and after the while loop show that twi_tx_done is SET TO TRUE by the handler, but the while loop can not detect it!

I tried to add a toggling pin inside the while loop to see when it exits and re-enter the loop. Interestingly, with this single command added, it started working and now it exits at the same time the handler sets the twi_tx_done = true !

As toggling an IO consumes power, I though that maybe adding any command inside the loop can make it work. But, when changed the command to nrf_gpio_pin_clear(x) it again exits at the timeout!

Test setup: Here is the path to the functions including the while loop:

mpu_init->mpu9150_init (main.c) -> mpu9150_write_single (mpu9150.c)

mpu_init->mpu9150_config (main.c) -> mpu9150_write_burst (mpu9150.c)

In the figures below:

CH1-Yellow: SCL = TWI Clock

CH3-Purple: PIN0 = Toggles whenever the handler sets twi_tx_done = true + whenever the while loop exits with a timeout

CH2-Green: PIN3 = Toggles if(twi_tx_done) after the while loop

CH4-Pink: PIN 20 = Toggles whenever program enters write_single & write_burst function + exactly before the while loop

For toggling inside the while loop, PIN20 is used.

CASE 1: When an IO toggle is used inside the loop, the program works as expected image description

Enlarged trace, showing that no timeout occurred image description

CASE 2: The toggle command is NOT used in the write_single function (left half) and the program exits at timeout (vs) Right half, which toggling is used image description

Parents
  • Hi

    When I developed the example I used Optimization level 0 (-O0). Based on a hunch I tried to set it to level 3 (-O3) and now I see something similar to you. I only see four TWI transfers and when using the debugger the timeouts seems to be the issue.

    Setting twi_tx_done and twi_rx_done to volatile like this:

    volatile static bool twi_tx_done = false;
    volatile static bool twi_rx_done = false;
    

    ...seemed to fix the problem for me. A good explanation of why the volatile keyword might help can be found here.

    So what Optimization level do you use?

  • Hi. Thank you for the tips on the timeout. You are right and I have updated the code on github. I'll look into an interrupt driven example if I can find some time for it. Regarding your issue with the interrupt handler let us discuss it in the thread you created here.

Reply Children
No Data
Related