mrvn
Posts: 58
Joined: Wed Jan 09, 2013 6:50 pm

How do I wait 150 cycles (with cache on)?

Tue Apr 07, 2015 8:23 am

Changing the pull up/down resistors for GPIO pins on a Raspberry Pi requires waiting for 150 cycles after enabling and disbaling the clock signal according to specs. Doing it a bit longer doesn't hurt but using a timer to wait is longer by magnitudes so I don't want to do that. So I have this simple busy loop:

Code: Select all

for (int i = 0; i < 150; ++i) { asm volatile (""); }

0:   e3a03096        mov     r3, #150        ; 0x96
4:   e2533001        subs    r3, r3, #1
8:   1afffffd        bne     4 <foo+0x4>
That loops 150 times, executing 300 instructions. Without instruction caching and without branch prediction that certainly is more than 150 cycles. But once those are turned on that loop runs way faster, faster than 150 cycles I think.

So how do I wait at least 150 cycles but not magnitudes longer with or without instruction caches and branch prediction enabled? Note: worst case it could be 2 functions, delay_no_cache() and delay_cache()

User avatar
joan
Posts: 14760
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How do I wait 150 cycles (with cache on)?

Tue Apr 07, 2015 8:29 am

If you can afford to waste a microsecond or two then you could spin on the system microsecond clock.

Page 172 of the peripherals document.

mrvn
Posts: 58
Joined: Wed Jan 09, 2013 6:50 pm

Re: How do I wait 150 cycles (with cache on)?

Tue Apr 07, 2015 12:25 pm

That would produce a delay between 2-3 microsecond per pin (wait for the counter to change, set clock, wait again, remove clock, wait again). I does work but it is rather a lot larger than 150 cycles, which I want to avoid.

User avatar
joan
Posts: 14760
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How do I wait 150 cycles (with cache on)?

Tue Apr 07, 2015 12:33 pm

mrvn wrote:That would produce a delay between 2-3 microsecond per pin (wait for the counter to change, set clock, wait again, remove clock, wait again). I does work but it is rather a lot larger than 150 cycles, which I want to avoid.
Can't say that such a delay would be noticed by most applications. Setting PUD should really be a one-off initialisation exercise.

Return to “Bare metal, Assembly language”