[fpc-pascal] AVR Busy Wait implementation

Simon Ameis SAmeis.fpc at web.de
Sat Jan 16 01:26:13 CET 2016

Am 14.01.2016 um 23:57 schrieb Marc Santhoff:
> On Do, 2016-01-14 at 21:33 +0100, Simon Ameis wrote:
>> In general I already know these documents; what I'm looking for is an
>> implementation of a busy wait, not how to use it.
>> For C/C++ it's easy to get the code files. But I don't know where to get
>> compiler built-in procedures for gcc or other language's compilers.
> If you want to write Pascal code and don not need nano seconds accuracy,
> you have no need to now compiler internals. Only use time values and the
> divider factors.
I don't talk of FPC compiler internals but of gcc compiler internals.
E.g. the C implementation uses a compiler specific procedure
__builtin_avr_delay_cycles; I can't find a source to get known how it is
inlined in the resulting assembler code.
Please see for reference:

The same is true for Basic.
>> The algorithm itself isn't that complicated:
>> 1. assume you know how fast the cpu is (e.g. 1 MHz, 12 MHz or what ever
>> fixed value)
>> 2. calculate cpu cycles for given time to wait: cycle count := time to
>> wait / (1/(cpu speed in MHz))
> In cas of AVR you need to use the prescalers value, too. Look in the
> datasheet for the chip used, it has good information and code samples
> (although in C and Assembler).
>> 3. call a loop with known cpu cycle usage
>> Point 1 a fixed cpu speed is assumed for ease and compile time
>> optimization (in fact you always need to know the speed of the clock
>> source as it can't be determined by the MCU).
> There is normally a definition set in the Makefile or in the C-Code. And
> since you are building the firmware code you should now it's name.
> sth. like
> #define SYSTEM_CLOCK 16000000ULL
> In Pascal this would be a constant:
> const
>   SYSTEM_CLOCK = 16000000;
> This constant can well be used in any calculation.
>> For point 3 there is a very good explanation in German at
>> http://www.avr-asm-tutorial.net/avr_de/zeitschleifen/index.html.
>> The wicked thing is the calculation of the cpu cycles. The C
>> implementation uses floating point arithmetics wich is evaluated at
>> compile time. It doesn't work with wait times which are calculated at
>> runtime.
> Why not use calculated constants? The compiler can evaluate simple
> arithmetics at compile time:
> const
>   sclk = int(round(SYSTEM_CLOCK / 42));
> The resulting number will be as close to the float value as possible.
FPC doesn't support floating point on AVR; thus no floating point
constants are allowed, even if they can be evaluated to an integer
expression at compile time. FPC obviously first checks types and then
does optimization on known types.

Thus only this code is valid on AVR:
  sclk = SYSTEM_CLOCK div 42;

The question isn't how to calculate this but how to fit it into a word
boundary for function call without loosing required accuracy.
>> Am 12.01.2016 um 14:54 schrieb Marc Santhoff:
>>> On Mo, 2016-01-11 at 23:19 +0100, Simon Ameis wrote:
>>>> Hello,
>>>> has anyone already written a busy wait procedure for AVR or any other
>>>> embedded processors?
>>>> I'm currently facing issues converting Arduino's calculation of time
>>>> (millisecons/microseconds) to cpu cycles as they rely on compile time
>>>> elimination of floating point calculation.
>>> No, but I would search something published freely or having a fitting
>>> license like BSD and translate it to Pascal.
>>> Look there for eample:
>>> https://www.mikrocontroller.net/articles/AVR
>>> There are lot of projects, the complicated part will be to find the
>>> license. But if you write soemthing inspired by existing code but do it
>>> yourself, imho will be OK.
>>> Marc
>> _______________________________________________
>> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

More information about the fpc-pascal mailing list