Delay loops gone crazy

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Delay loops gone crazy

Jump to solution
574 Views
ve3id
Contributor III

I'm picking up a project that I put aside 7 months ago.  It involves using SPI to communicate with a Nordic Semiconductor nRF24l01 module from a FRDM-K64F using MCUExpresso24.12(Build148) IDE.

.  
When I left it, it happily wrote sign-on and copyright banners and then went to handling RF.

While it still sends RF, it is painfully slow sending two screens of data to the HD44870 2x16 display.   Like 3 seconds per character.

As I am using an LCD daughter card designed for the Arduino, it does not have the  BUSY bit wired from the LCD, so I am using delay loops.

But nothing should have been changed in the program, sitting on the shelf!  As of the last time I ran it, the screen update was like a flash, as is evidenced by one FRDM-K64F that still had the old version of the program in it.

I have tried stepping through all delay loops, they have the expected number of cycles.  I have tried trapping unwanted interrupts, even turning of interrupts, no change.  I suspected maybe an update to gcc has an optimisation flag set/no set, but that would have the opposite effect, speeding up the display and getting garbage due to not waiting long enough.  The last working version was compiled with the same version of MCUExpresso.  I am not aware of any updates.

It stays slow whether it is connected to the PC's IDE connection using Linkserver or standalone!

The LCD is not going to be in the final product, it's just for debugging, but this strange anomaly is driving me crazy and I need to get it fixed.

Any help really appreciated, I'm hoping somebody has seen something like this and has an answer!

Thanks in advance,

Cheers,

Nigel

 

 

 

0 Kudos
Reply
1 Solution
525 Views
bobpaddock
Senior Contributor III
GCC when set to build the 'Small' model with -Os can be aggressive about removing code, breaking busy loops that have no side effects.  I always put nop() that has the proper guards into my loops. Odd delay behavior in this case indicates a missing volatile somewhere.

Early AVR-LIBC implementations requires passing a float to the delay functions. Compiler coercions turned it into the required number of cycles. Failing to do that got strange delays. Modern implementations take an unsigned int.

That you can single step does seem to negate those.


static inline void nop( void )
{
__asm__ __volatile__ ("nop");
}

View solution in original post

0 Kudos
Reply
2 Replies
526 Views
bobpaddock
Senior Contributor III
GCC when set to build the 'Small' model with -Os can be aggressive about removing code, breaking busy loops that have no side effects.  I always put nop() that has the proper guards into my loops. Odd delay behavior in this case indicates a missing volatile somewhere.

Early AVR-LIBC implementations requires passing a float to the delay functions. Compiler coercions turned it into the required number of cycles. Failing to do that got strange delays. Modern implementations take an unsigned int.

That you can single step does seem to negate those.


static inline void nop( void )
{
__asm__ __volatile__ ("nop");
}

0 Kudos
Reply
507 Views
ve3id
Contributor III
Thanks, Bob,
I did find one missing volatile in another loop that had previously raised my eyebrows but not important enough to tackle until I had fixed the main problem, however I still have the same problem. But now I am seeing stray interrupts, so that is where I will spend the next little while
0 Kudos
Reply