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?

Reply
  • 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?

Children
  • Hi Martin,

    I was using optimization level 3 and as you said when changed the variables to volatile the delay issue is solved.

    Regarding the MPU9150 example you provided, I could get it work with the nRF interrupting the MPU. But the reverse, although I can see the program going into the interrupt handler and requesting data (i.e., tx is done), but no data appears on the line after that (no rx). If it works it will be a good example for everyone I think. Thanks for writing the mpu9150.c

    BTW, I think after using (timeout--) in your loop, you should check for (!(timeout+1)) to get the timeout error OR use (--timeout).

  • 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.

Related