[fpc-pascal] AVR Busy Wait implementation

Simon Ameis SAmeis.fpc at web.de
Sun Jan 17 22:01:54 CET 2016


I've now come up with the code below.

The main problem is, that FPC doesn't inline the procedure _delay_ms.
Thus the calculation of the required ticks is done at runtime wich
timing is merely unpredictable.

What must be done to get this procedure inlined?

The documentation isn't very extensive on this topic (size and recustion
are mentioned).

{$DEFINE F_CPU_HZ :=12000000}
procedure delay_loop_1(__count: Byte); assembler;
label loop;
asm
  loop:
  dec __count
  brne loop
end;

procedure delay_loop_2(__count: Word); assembler;
label loop;
asm
  loop:
  sbiw __count,1
  brne loop
end;

procedure _delay_ms(__ms: Word); inline;
type
  TLongWordRecord = record
  case Integer of
    1: (Value: Longword;);
    2: (low_word: Word; High_Word: Word;)
  end;
var
  ticks: TLongWordRecord;
  ticks_dword    : Longword absolute ticks.Value;
  ticks_word     : Word     absolute ticks.low_word;
  ticks_high_word: Word     absolute ticks.High_Word;
begin
  ticks_dword     := (F_CPU_HZ div 1000) * __ms;

  while ticks_high_word > 0 do
  begin
    delay_loop_2(high(Word)); // TODO: substract loop cycles
    dec(ticks_high_word);
  end;

  if ticks_word > $00FF then
    delay_loop_2(ticks_word)
  else
    delay_loop_1(lo(ticks_word));
end;

Am 14.01.2016 um 21:33 schrieb Simon Ameis:
> 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.
>
> 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))
> 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).
> 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.
>
> 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