# PIC16: Understanding the bound on the argument to _delay

My PIC16 compiler, XC8, defines a _delay(n) pseudo-function which inserts a delay of n cycles. There is a restriction however (see here, page 59):

The delay argument must be a constant and less than approximately 179,200 for PIC18 devices and approximately 50,659,000 for other devices.

Where do these upper bounds come from? The factorisation of 50,659,000 (2^3 * 5^3 * 7 * 7237) does not seem to shed any insight.

-
Have a look in <xc.h> at the definition (follow the trail if defined in a separate file included in this), this should help to answer the question. –  Oli Glaser Nov 4 '12 at 14:02

_delay is generated at compile time, so the code is not necessarily the same for all values, they can pad, or even compound loops to achieve the exact desired number of cycles.

50659000/2^(8*3) is approximately 3. So probably the core loop they are using is a 3 instruction loop (if an 8 bit microcontroller, 3 decrements are needed for a 3*8 bit variable). Since it jumps in 3's, they can pad with one or two nop to get the exact number of cycles. This requires the decrement and jump if/ifnot zero instruction to be possible (and with/without carry).

-

First, if the answer matters then you shouldn't be using a compiler.

Second, regardless of the reason you want to know, the answer is to look in the source code. This is probably implemented as some kind of macro at compile time. If so, the source has to be where you can see it. If it calls a library routine, then it might not be available. However, you can still build a test program with it and then single step thru the delay in the program memory window in MPLAB to see what is going on.

Most likely, the odd numbers come from nested loops. The inner loop probably is the minimum necessary to do the loop end condition checking and looping, so comes out to however many cycles it comes out to. This could introduce strange looking prime factors into the max cycles.

In any case, this is a bad way to do delays of more than just a few cycles. You should never be anywhere near the maximum this function can delay. If you find yourself wanting to delay by more than a few µs, then you should re-think your architecture. Do longer timing with a regular periodic interrupt, for example.