Hi folks,
My research on how to use Free Pascal to target the AVR (on my Arduino) led me to two main resources:
http://wiki.freepascal.org/AVR, and
FPC/Lazarus Arduino TutorialThe information regarding building the cross compiler between those two resources is conflicting. The Wiki page says to use "make buildbase installbase ..." and the forum tutorial says, "make clean crossall crossinstall ..."
What's the difference?
Since I like simple, and since the Wiki page is dated later than the forum thread, I decided to try that method using v3.0.0 on Linux with the v3.1.1 fpc.zip trunk snapshot:
make buildbase installbase CPU_TARGET=avr OS_TARGET=embedded SUBARCH=avr5 CROSSINSTALL=1 INSTALL_PREFIX=~/opt/fpc NOGDB=1 PP=/usr/bin/fpc CROSSBINDIR=/opt/cross/bin BINUTILSPREFIX=avr-
That completed with no errors. But the Wiki instructions basically stop there. So, now what?
I found two directories in ~/opt/fpc: bin and lib. There was
nothing in bin, but I found ppcrossavr in lib/fpc/3.1.1 along with a units directory.
Okay, so I downloaded and extracted Blinky.zip from the forum thread linked above. Then copied Blinky.lpr to ~/opt/fpc/lib/fpc/3.1.1 and, after some experimentation, finally got it to compile with:
./ppcrossavr Blinky.lpr -Tembedded -Pavr -MDelphi -Scghi -CX -O3 -Xs -XX -l -vewnhibq -Fiunits/avr-embedded/rtl -Fu. -FUunits/avr-embedded/rtl -Cpavr5 -Wpatmega328p -a -XPavr- -OoFastMath -OoNoStackFrame -XX -CX
And then uploaded it to my Arduino Uno with:
avrdude -v -patmega328p -carduino -P/dev/ttyUSB0 -b115200 -Uflash:w:blinky.hex:i
The Uno on-board LED blinked as it was being programmed and verified, and then, nothing. No blinking, visual silence.
I thought at first I may have 'bricked' my Arduino. But, an upload of a HEX file generated from C showed everything was good.
Looking at the assembly in the respective ELF files did me no good as assembly is like Greek to me. But it did give me an idea.
In Blinky.lpr, I replaced the two calls to the SomeDelay procedure with the For loop contained within that procedure and removed the procedure. I think this would be similar to inlining a procedure.
Now it works correctly: blink, blink, blink, ... (where ',' = normal pause and blink length is the same).
Then I tried actually inlining the procedure, ie. "procedure SomeDelay; inline;". That also works, but not correctly. The timing is obviously incorrect: blink blink, blink blink, blink blink, ... (short duration blinks).
Could someone help me understand why there is a difference between the procedures given on the Wiki and in the Tutorial, and why one would want to use one over the other?
And why does physically inlining the delay work while using a delay procedure does not? And why does declaring the procedure "inline" work but with incorrect timing?