Sign in Join
Wiki copytemporary

Lazarus on Raspberry Pi: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-<img src="Lazarus_on_Raspberry_Pi_Raspian_Wheezy_version_2012-10-28.png" title="Lazarus on Raspbian Wheezy" width="200" />
1+![](/wiki-images/e/ef/Lazarus_on_Raspberry_Pi_Raspian_Wheezy_version_2012-10-28.png)
22
33*(Raspberry Pi only)*
44
55The **Raspberry Pi** is a credit-card-sized single-board computer. It has been developed in the UK by the Raspberry Pi Foundation with the intention of stimulating the teaching of basic computer science in schools. Raspberry Pis are also used for multiple other purposes that are as different as media servers, robotics and control engineering.
66
77The Raspberry Pi Foundation recommends [[Raspbian|the Pasperry Pi OS]] as standard operating system. Alternative systems running on RPI include RISC OS and various [[Portal:Linux|Linux]] distributions, as well as [[Portal:Android|Android]] and [[Portal:FreeBSD|FreeBSD]].
88
99Lazarus runs natively under the Raspbian operating system.
1010
1111## Installing and compiling Lazarus
1212
1313### Introduction
1414
1515Installing FPC and Lazarus on a Raspberry Pi is very little different from other Linux boxes, so please refer to [[Installing Lazarus on Linux]]. How ever, there are some RasPi particularities worth noting.
1616
1717- RasPi do not always have enough memory to build Lazarus, this affects the routine rebuild of the IDE that happens when installing packages for example. The solution is to increase swap size (below).
1818- The Lazarus SourceForge repository does not include a pre-made RasPi package.
1919- If you are using the Raspberry Pi OS, its based on Debian and Debian has quite a long release cycle. So, at any one time, the repo provided Lazarus is likely to be out of date and, occasionally, so will the FPC be.
2020- Notwithstanding the above point, at present, late 2023, the Debian Bookworm based Raspberry Pi OS has the appropriate FPC and a Lazarus that suits most people. This will change !
2121
2222### Correcting swap file size
2323
2424(Info from forum user "Thaddy", updated.) If you have RPi with memory size less then 4Gb, and you want to build Lazarus from source or use FPCUPdeluxe or just rebuild the IDE after installing a package you need to allocate at least 1G if not 2G of swap. This appears to be particularly so with Raspberry Pi OS based on Bookworm rather than Bullseye.
2525
2626To increase swap you should firstly ensure you have a couple of gig free and -
2727
2828- sudo dphys-swapfile swapoff
2929- sudo nano /etc/dphys-swapfile
3030- in the file, find CONF_SWAPSIZE and change the value to 2048 (or 1024) and save it.
3131- sudo dphys-swapfile setup
3232- sudo dphys-swapfile swapon
3333
3434You should now see the file, /var/swap, increase to 2G (or 1G). On some other operating systems, eg a "pure" debian, you may need to install the dphys-swapfile package.
3535
3636If you don't have enough memory (real memory and swap) then, your compile processes (particularly assembling) will stop and the whole machine freezes. You have been warned !
3737
3838While you are fiddling with the swap file, consider, if possible, moving the swap file from /var/swap to somewhere off the SDCard, unfortunately, SDCards are not good at the repetitive writes that happen in a swap file. Not critical but a good idea.
3939
4040If you have problems making the swap file, see this <https://forums.raspberrypi.com/viewtopic.php?p=1881546>
4141
4242### Simple installation
4343
4444Most distributions have a graphic installer of some sort, look for entries like "Add / Remove Software" in your menus. Alternatively, all systems will have a command line interface. As hinted above, its likely that your distribution will have a current FPC, if so, best to use it. More interesting is Lazarus, as it changes more frequently, consider your needs. The Raspberry Pi OS, late 2023, has Lazarus 2.2.6. While version 3.0 of Lazarus is released now, it will take awhile to make it into distro's repos. Some users will, for the time being, be quite happy with Lazarus 2.2.6. Later on, you can remove the distro supplied Lazarus 2.2.6 and build 3.0 from source yourself, its easy.
4545
4646A advantage of using the distro supplied FPC and Lazarus is that they test them, make sure everything needed is there and its very easy.
4747
4848See [the Package Manager Model](https://wiki.freepascal.org/Installing_Lazarus_on_Linux#The_Package_Manager_Model).
4949
5050### Not Quite as Simple Install
5151
5252There are two other functional alternatives for installing Lazarus, building from source and using [[fpcupdeluxe]], an application that you run on your computer to manage your FPC / Lazarus install. Its very suited to people who just want to get a working install quickly, fpcupdeluxe will do the thinking for them. Fpcupdelux will install (and manage) both FPC and Lazarus and you should use them together.
5353
5454Installing a non distro FPC is a touch more complicated still. Its [possible](https://wiki.freepascal.org/Installing_the_Free_Pascal_Compiler#Compiling_the_FPC_source.2C_using_preinstalled_FPC) to build a new FPC using an older, existing, FPC, might be a challenge for a less powerful Pi. An better option is to [download and install](https://wiki.freepascal.org/Installing_the_Free_Pascal_Compiler#Downloading_FPC_tar_balls) a tarball.
5555
5656Its quite reasonable to use the distro provided FPC and build your own Lazarus. In fact, many users have several lazarus versions installed this way.
5757
5858Building Lazarus [from source](https://wiki.freepascal.org/Installing_Lazarus_on_Linux#Build_Lazarus_from_Source) on a Raspberry Pi is no different from other Linuxes, except, perhaps, for the [[Lazarus on Raspberry Pi|memory issue]].
5959
6060<File:Lazarus> 0 9 30 4 on RPi 2.png\|Lazarus "out of the box" on Raspberry Pi 2
6161
6262### Cross compiling for the Raspberry Pi from Windows
6363
64641\. Using fpcup
6565
6666One way is to use fpcup to set up a cross compiler; follow these instructions: [[fpcup|fpcup#Linux_ARM_cross_compiler]]
6767
68682\. Using scripts
6969
7070Alternatively, for a more manual approach using batch files, you can follow these steps.
7171
72722.1 Prerequisites
7373
7474`FPC 2.7.1 or higher installed with source code`\
7575`Install the Windows version from the Linaro binutils for linux gnueabihf into %FPCPATH%/bin/win32-armhf-linux `[`1`](https://launchpad.net/linaro-toolchain-binaries/trunk/2013.10/+download/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_win32.zip)
7676
77772.2 Example Windows Batch file (adapt paths as needed)
7878
7979``` bat
8080set PATH=C:\pp\bin\i386-win32;%PATH%;
8181set FPCMAKEPATH=C:/pp
8282set FPCPATH=C:/pp
8383set OUTPATH=C:/pp271
8484%FPCMAKEPATH%/bin/i386-win32/make distclean OS_TARGET=linux CPU_TARGET=arm CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
8585
8686%FPCMAKEPATH%/bin/i386-win32/make all OS_TARGET=linux CPU_TARGET=arm CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
8787if errorlevel 1 goto quit
8888%FPCMAKEPATH%/bin/i386-win32/make crossinstall CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" OS_TARGET=linux CPU_TARGET=arm FPC=%FPCPATH%/bin/i386-win32/ppc386.exe INSTALL_BASEDIR=%OUTPATH%
8989
9090:quit
9191pause
9292```
9393
9494With the resulting ppcrossarm.exe and ARM RTL you will be able to build a cross Lazarus version as usual and compile FPC projects for the Raspberry Pi and other armhf devices.
9595
9696Remember that not all - especially Windows - libraries are available for Linux arm.
9797
9898### Cross compiling for the Raspberry Pi from Linux
9999
100100Please see this page <https://wiki.freepascal.org/Cross_Compile_to_RasPi_from_Linux>
101101
102102## Accessing external hardware
103103
104-<img src="rpi_pinout_all_50.png" title="Raspberry Pi pinout of external connectors" width="300" />
104+![](/wiki-images/f/f2/Rpi_pinout_all_50.png)
105105
106106One of the goals in the development of Raspberry Pi was to facilitate effortless access to external devices like sensors and actuators. There are many ways to access the I/O facilities from Lazarus and Free Pascal:
107107
1081081. [[Lazarus on Raspberry Pi|Direct access]] using the [[BaseUnix]] unit
1091092. Access through [[Lazarus on Raspberry Pi|encapsulated shell calls]]
1101103. Access through the [[Lazarus on Raspberry Pi|wiringPi library]].
1111114. Access through Unit [[Lazarus on Raspberry Pi|rpi_hal]].
1121125. Access through Unit [[Lazarus on Raspberry Pi|PiGpio]].
1131136. Access through the [PascalIO](https://github.com/SAmeis/pascalio) library.
1141147. Access through the [PXL](http://asphyre.net/products/pxl) library.
115115
116116### Native hardware access
117117
118118![Simple test program for accessing the GPIO port on Raspberry Pi\|thumb\|300px\|right](/wiki-images/d/d2/Testprogram_for_GPIO_on_RPI_annotated.png) ![Test circuit for GPIO access with the described program\|thumb\|300px\|right](/wiki-images/7/7c/Rpi_testcircuit_1d.png) ![Simple demo implementation of the circuit from above on a breadboard\|thumb\|300px\|right](/wiki-images/7/7e/Rpi_testcircuit_1p_annotaded.png) This method provides access to external hardware that doesn't require additional libraries. The only requirement is the BaseUnix library that is part of Free Pascal's RTL.
119119
120120#### Switching a device via the GPIO port
121121
122122The following example lists a simple program that controls the GPIO pin 17 as output to switch an LED, transistor or relays. This program contains a [[doc:lcl/stdctrls/ttogglebox.html|ToggleBox]] with name *GPIO17ToggleBox* and for logging return codes a [[doc:lcl/stdctrls/tmemo.html|TMemo]] called *LogMemo*.
123123
124124For the example, the anode of a LED has been connected with Pin 11 on the Pi's connector (corresponding to GPIO pin 17 of the BCM2835 SOC) and the LED's cathode was wired via a 68 Ohm resistor to pin 6 of the connector (GND) as previously described by Upton and Halfacree. Subsequently, the LED may be switched on and off with the application's toggle box.
125125
126126The code may at first require to be run as root, i.e. either from a root account (not recommended) or via **su**. A better option is to add the user to the gpio group, the i2c group and the spi group.
127127
128128``` bash
129129sudo adduser pi gpio
130130sudo adduser pi i2c
131131sudo adduser pi spi
132132```
133133
134134*Controlling unit:*
135135
136136``` pascal
137137unit Unit1;
138138
139139{Demo application for GPIO on Raspberry Pi}
140140{Inspired by the Python input/output demo application by Gareth Halfacree}
141141{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
142142
143143{$mode objfpc}{$H+}
144144
145145interface
146146
147147uses
148148 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
149149 Unix, BaseUnix;
150150
151151type
152152
153153 { TForm1 }
154154
155155 TForm1 = class(TForm)
156156 LogMemo: TMemo;
157157 GPIO17ToggleBox: TToggleBox;
158158 procedure FormActivate(Sender: TObject);
159159 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
160160 procedure GPIO17ToggleBoxChange(Sender: TObject);
161161 private
162162 { private declarations }
163163 public
164164 { public declarations }
165165 end;
166166
167167const
168168 PIN_17: PChar = '17';
169169 PIN_ON: PChar = '1';
170170 PIN_OFF: PChar = '0';
171171 OUT_DIRECTION: PChar = 'out';
172172
173173var
174174 Form1: TForm1;
175175 gReturnCode: longint; {stores the result of the IO operation}
176176
177177implementation
178178
179179{$R *.lfm}
180180
181181{ TForm1 }
182182
183183procedure TForm1.FormActivate(Sender: TObject);
184184var
185185 fileDesc: integer;
186186begin
187187 { Prepare SoC pin 17 (pin 11 on GPIO port) for access: }
188188 try
189189 fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
190190 gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
191191 LogMemo.Lines.Add(IntToStr(gReturnCode));
192192 finally
193193 gReturnCode := fpclose(fileDesc);
194194 LogMemo.Lines.Add(IntToStr(gReturnCode));
195195 end;
196196 { Set SoC pin 17 as output: }
197197 try
198198 fileDesc := fpopen('/sys/class/gpio/gpio17/direction', O_WrOnly);
199199 gReturnCode := fpwrite(fileDesc, OUT_DIRECTION[0], 3);
200200 LogMemo.Lines.Add(IntToStr(gReturnCode));
201201 finally
202202 gReturnCode := fpclose(fileDesc);
203203 LogMemo.Lines.Add(IntToStr(gReturnCode));
204204 end;
205205end;
206206
207207procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
208208var
209209 fileDesc: integer;
210210begin
211211 { Free SoC pin 17: }
212212 try
213213 fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
214214 gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
215215 LogMemo.Lines.Add(IntToStr(gReturnCode));
216216 finally
217217 gReturnCode := fpclose(fileDesc);
218218 LogMemo.Lines.Add(IntToStr(gReturnCode));
219219 end;
220220end;
221221
222222procedure TForm1.GPIO17ToggleBoxChange(Sender: TObject);
223223var
224224 fileDesc: integer;
225225begin
226226 if GPIO17ToggleBox.Checked then
227227 begin
228228 { Swith SoC pin 17 on: }
229229 try
230230 fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
231231 gReturnCode := fpwrite(fileDesc, PIN_ON[0], 1);
232232 LogMemo.Lines.Add(IntToStr(gReturnCode));
233233 finally
234234 gReturnCode := fpclose(fileDesc);
235235 LogMemo.Lines.Add(IntToStr(gReturnCode));
236236 end;
237237 end
238238 else
239239 begin
240240 { Switch SoC pin 17 off: }
241241 try
242242 fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
243243 gReturnCode := fpwrite(fileDesc, PIN_OFF[0], 1);
244244 LogMemo.Lines.Add(IntToStr(gReturnCode));
245245 finally
246246 gReturnCode := fpclose(fileDesc);
247247 LogMemo.Lines.Add(IntToStr(gReturnCode));
248248 end;
249249 end;
250250end;
251251
252252end.
253253```
254254
255255*Main program:*
256256
257257``` pascal
258258program io_test;
259259
260260{$mode objfpc}{$H+}
261261
262262uses
263263 {$IFDEF UNIX}{$IFDEF UseCThreads}
264264 cthreads,
265265 {$ENDIF}{$ENDIF}
266266 Interfaces, // this includes the LCL widgetset
267267 Forms, Unit1
268268 { you can add units after this };
269269
270270{$R *.res}
271271
272272begin
273273 Application.Initialize;
274274 Application.CreateForm(TForm1, Form1);
275275 Application.Run;
276276end.
277277```
278278
279279#### Reading the status of a pin
280280
281281![Demo program for reading the status of a GPIO pin\|thumb\|300px\|right](/wiki-images/7/73/2013-04-28-193243_1280x1024_scrot.png) ![Test circuit for GPIO access with the described program\|thumb\|300px\|right](/wiki-images/f/f4/Rpi_testcircuit_2d.png) ![Possible implementation of this test circuit\|thumb\|300px\|right](/wiki-images/2/2f/Rpi_testcircuit_2p_annotaded.png)
282282
283283Of course it is also possible to read the status of e.g. a switch that is connected to the GPIO port.
284284
285285The following simple example is very similar to the previous one. It controls the GPIO pin 18 as input for a binary device like a switch, transistor or relais. This program contains a [[doc:lcl/stdctrls/tcheckbox.html|CheckBox]] with name *GPIO18CheckBox* and for logging return codes a [[doc:lcl/stdctrls/tmemo.html|TMemo]] called *LogMemo*.
286286
287287For the example, one pole of a push-button has been connected to Pin 12 on the Pi's connector (corresponding to GPIO pin 18 of the BCM2835 SOC) and via a 10k Ohm pull-up resistor with pin 1 (+3.3V, see wiring diagram). The other pole has been wired to pin 6 of the connector (GND). The program senses the status of the button and correspondingly switches the checkbox on or off, respectively.
288288
289289Note that the potential of pin 18 is high if the button is released (by virtue of the connection to pin 1 via the pull-up resistor) and low if it is pressed (since in this situation pin 18 is connected to GND via the switch). Therefore, the GPIO pin signals 0 if the button is pressed and 1 if it is released.
290290
291291This program has again to be executed as root.
292292
293293*Controlling unit:*
294294
295295``` pascal
296296unit Unit1;
297297
298298{Demo application for GPIO on Raspberry Pi}
299299{Inspired by the Python input/output demo application by Gareth Halfacree}
300300{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
301301
302302{This application reads the status of a push-button}
303303
304304{$mode objfpc}{$H+}
305305
306306interface
307307
308308uses
309309 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
310310 ButtonPanel, Unix, BaseUnix;
311311
312312type
313313
314314 { TForm1 }
315315
316316 TForm1 = class(TForm)
317317 ApplicationProperties1: TApplicationProperties;
318318 GPIO18CheckBox: TCheckBox;
319319 LogMemo: TMemo;
320320 procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
321321 procedure FormActivate(Sender: TObject);
322322 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
323323 private
324324 { private declarations }
325325 public
326326 { public declarations }
327327 end;
328328
329329const
330330 PIN_18: PChar = '18';
331331 IN_DIRECTION: PChar = 'in';
332332
333333var
334334 Form1: TForm1;
335335 gReturnCode: longint; {stores the result of the IO operation}
336336
337337implementation
338338
339339{$R *.lfm}
340340
341341{ TForm1 }
342342
343343procedure TForm1.FormActivate(Sender: TObject);
344344var
345345 fileDesc: integer;
346346begin
347347 { Prepare SoC pin 18 (pin 12 on GPIO port) for access: }
348348 try
349349 fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
350350 gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
351351 LogMemo.Lines.Add(IntToStr(gReturnCode));
352352 finally
353353 gReturnCode := fpclose(fileDesc);
354354 LogMemo.Lines.Add(IntToStr(gReturnCode));
355355 end;
356356 { Set SoC pin 18 as input: }
357357 try
358358 fileDesc := fpopen('/sys/class/gpio/gpio18/direction', O_WrOnly);
359359 gReturnCode := fpwrite(fileDesc, IN_DIRECTION[0], 2);
360360 LogMemo.Lines.Add(IntToStr(gReturnCode));
361361 finally
362362 gReturnCode := fpclose(fileDesc);
363363 LogMemo.Lines.Add(IntToStr(gReturnCode));
364364 end;
365365end;
366366
367367procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
368368var
369369 fileDesc: integer;
370370 buttonStatus: string[1] = '1';
371371begin
372372 try
373373 { Open SoC pin 18 (pin 12 on GPIO port) in read-only mode: }
374374 fileDesc := fpopen('/sys/class/gpio/gpio18/value', O_RdOnly);
375375 if fileDesc > 0 then
376376 begin
377377 { Read status of this pin (0: button pressed, 1: button released): }
378378 gReturnCode := fpread(fileDesc, buttonStatus[1], 1);
379379 LogMemo.Lines.Add(IntToStr(gReturnCode) + ': ' + buttonStatus);
380380 LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
381381 if buttonStatus = '0' then
382382 GPIO18CheckBox.Checked := true
383383 else
384384 GPIO18CheckBox.Checked := false;
385385 end;
386386 finally
387387 { Close SoC pin 18 (pin 12 on GPIO port) }
388388 gReturnCode := fpclose(fileDesc);
389389 LogMemo.Lines.Add(IntToStr(gReturnCode));
390390 LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
391391 end;
392392end;
393393
394394procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
395395var
396396 fileDesc: integer;
397397begin
398398 { Free SoC pin 18: }
399399 try
400400 fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
401401 gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
402402 LogMemo.Lines.Add(IntToStr(gReturnCode));
403403 finally
404404 gReturnCode := fpclose(fileDesc);
405405 LogMemo.Lines.Add(IntToStr(gReturnCode));
406406 end;
407407end;
408408
409409end.
410410```
411411
412412The main program is identical to that of the example from above.
413413
414414### Hardware access via encapsulated shell calls
415415
416416Another way to access the hardware is by encapsulating terminal commands. This is achieved by using the [[Executing External Programs|fpsystem]] function. This method gives access to functions that are not supported by the BaseUnix unit. The following code implements a program that has the same functionality as the program resulting from the first listing above.
417417
418418*Controlling unit:*
419419
420420``` pascal
421421unit Unit1;
422422
423423{Demo application for GPIO on Raspberry Pi}
424424{Inspired by the Python input/output demo application by Gareth Halfacree}
425425{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
426426
427427{$mode objfpc}{$H+}
428428
429429interface
430430
431431uses
432432 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Unix;
433433
434434type
435435
436436 { TForm1 }
437437
438438 TForm1 = class(TForm)
439439 LogMemo: TMemo;
440440 GPIO17ToggleBox: TToggleBox;
441441 procedure FormActivate(Sender: TObject);
442442 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
443443 procedure GPIO17ToggleBoxChange(Sender: TObject);
444444 private
445445 { private declarations }
446446 public
447447 { public declarations }
448448 end;
449449
450450var
451451 Form1: TForm1;
452452 gReturnCode: longint; {stores the result of the IO operation}
453453
454454implementation
455455
456456{$R *.lfm}
457457
458458{ TForm1 }
459459
460460procedure TForm1.FormActivate(Sender: TObject);
461461begin
462462 { Prepare SoC pin 17 (pin 11 on GPIO port) for access: }
463463 gReturnCode := fpsystem('echo "17" > /sys/class/gpio/export');
464464 LogMemo.Lines.Add(IntToStr(gReturnCode));
465465 { Set SoC pin 17 as output: }
466466 gReturnCode := fpsystem('echo "out" > /sys/class/gpio/gpio17/direction');
467467 LogMemo.Lines.Add(IntToStr(gReturnCode));
468468end;
469469
470470procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
471471begin
472472 { Free SoC pin 17: }
473473 gReturnCode := fpsystem('echo "17" > /sys/class/gpio/unexport');
474474 LogMemo.Lines.Add(IntToStr(gReturnCode));
475475end;
476476
477477procedure TForm1.GPIO17ToggleBoxChange(Sender: TObject);
478478begin
479479 if GPIO17ToggleBox.Checked then
480480 begin
481481 { Swith SoC pin 17 on: }
482482 gReturnCode := fpsystem('echo "1" > /sys/class/gpio/gpio17/value');
483483 LogMemo.Lines.Add(IntToStr(gReturnCode));
484484 end
485485 else
486486 begin
487487 { Switch SoC pin 17 off: }
488488 gReturnCode := fpsystem('echo "0" > /sys/class/gpio/gpio17/value');
489489 LogMemo.Lines.Add(IntToStr(gReturnCode));
490490 end;
491491end;
492492
493493end.
494494```
495495
496496The main program is identical to that of the example above. This program has to be executed with root privileges, too.
497497
498498### wiringPi procedures and functions
499499
500500Alex Schaller's wrapper unit for Gordon Henderson's Arduino compatible wiringPi library provides a numbering scheme that resembles that of Arduino boards.
501501
502502**Function wiringPiSetup:longint:** Initializes wiringPi system using the wiringPi pin numbering scheme.
503503
504504**Procedure wiringPiGpioMode(mode:longint):** Initializes wiringPi system with the Broadcom GPIO pin numbering scheme.
505505
506506**Procedure pullUpDnControl(pin:longint;** pud:longint): controls the internal pull-up/down resistors on a GPIO pin.
507507
508508**Procedure pinMode(pin:longint; mode:longint):** sets the mode of a pin to either INPUT, OUTPUT, or PWM_OUTPUT.
509509
510510**Procedure digitalWrite(pin:longint; value:longint):** sets an output bit.
511511
512512**Procedure pwmWrite(pin:longint; value:longint):** sets an output PWM value between 0 and 1024.
513513
514514**Function digitalRead(pin:longint):longint:** reads the value of a given Pin, returning 1 or 0.
515515
516516**Procedure delay(howLong:dword):** waits for at least howLong milliseconds.
517517
518518**Procedure delayMicroseconds(howLong:dword):** waits for at least howLong microseconds.
519519
520520**Function millis:dword:** returns the number of milliseconds since the program called one of the wiringPiSetup functions.
521521
522522### rpi_hal-Hardware Abstraction Library (GPIO, I2C and SPI functions and procedures)
523523
524524This Unit with around 1700 Lines of Code provided by Stefan Fischer, delivers procedures and functions to access the rpi HW I2C, SPI and GPIO:
525525
526526Just an excerpt of the available functions and procedures:
527527
528528**procedure gpio_set_pin (pin:longword;highlevel:boolean);** { Set RPi GPIO pin to high or low level; Speed @ 700MHz -\> 0.65MHz }
529529
530530**function gpio_get_PIN (pin:longword):boolean;** { Get RPi GPIO pin Level is true when Pin level is '1'; false when '0'; Speed @ 700MHz -\> 1.17MHz }
531531
532532**procedure gpio_set_input (pin:longword);** { Set RPi GPIO pin to input direction }
533533
534534**procedure gpio_set_output(pin:longword);** { Set RPi GPIO pin to output direction }
535535
536536**procedure gpio_set_alt (pin,altfunc:longword);** { Set RPi GPIO pin to alternate function nr. 0..5 }
537537
538538**procedure gpio_set_gppud (mask:longword);** { set RPi GPIO Pull-up/down Register (GPPUD) with mask }
539539
540540...
541541
542542**function rpi_snr :string;** { delivers SNR: 0000000012345678 }
543543
544544**function rpi_hw :string;** { delivers Processor Type: BCM2708 }
545545
546546**function rpi_proc:string;** { ARMv6-compatible processor rev 7 (v6l) }
547547
548548...
549549
550550**function i2c_bus_write(baseadr,reg:word; var <data:databuf_t>; lgt:byte; testnr:integer) : integer;**
551551
552552**function i2c_bus_read (baseadr,reg:word; var <data:databuf_t>; lgt:byte; testnr:integer) : integer;**
553553
554554**function i2c_string_read(baseadr,reg:word; var <data:databuf_t>; lgt:byte; testnr:integer) : string;**
555555
556556**function i2c_string_write(baseadr,reg:word; s:string; testnr:integer) : integer;**
557557
558558...
559559
560560**procedure SPI_Write(devnum:byte; reg,data:word);**
561561
562562**function SPI_Read(devnum:byte; reg:word) : byte;**
563563
564564**procedure SPI_BurstRead2Buffer (devnum,start_reg:byte; xferlen:longword);**
565565
566566**procedure SPI_BurstWriteBuffer (devnum,start_reg:byte; xferlen:longword);** { Write 'len' Bytes from Buffer SPI Dev startig at address 'reg' }
567567
568568...
569569
570570*Test Program (testrpi.pas):*
571571
572572``` pascal
573573//Simple Test program, which is using rpi_hal;
574574
575575 program testrpi;
576576 uses rpi_hal;
577577 begin
578578 writeln('Show CPU-Info, RPI-HW-Info and Registers:');
579579 rpi_show_all_info;
580580 writeln('Let Status LED Blink. Using GPIO functions:');
581581 GPIO_PIN_TOGGLE_TEST;
582582 writeln('Test SPI Read function. (piggy back board with installed RFM22B Module is required!)');
583583 Test_SPI;
584584 end.
585585```
586586
587587### PiGpio Low-level native pascal unit (GPIO control instead of wiringPi c library)
588588
589589*This Unit (pigpio.pas[2](https://docs.google.com/file/d/0B-b-5ooIWPvGN1BIcEJzRDgyeUE/edit?usp=sharing)) with 270 Lines of Code provided by Gabor Szollosi, works very fast (for ex. GPIO pin output switching frequency 8 MHz) :*
590590
591591``` pascal
592592
593593unit PiGpio;
594594{
595595 BCM2835 GPIO Registry Driver, also can use to manipulate cpu other registry areas
596596
597597 This code is tested only Broadcom bcm2835 cpu, different arm cpus may need different
598598 gpio driver implementation
599599
600600 2013 Gabor Szollosi
601601}
602602{$mode objfpc}{$H+}
603603
604604interface
605605
606606uses
607607 Classes, SysUtils;
608608
609609const
610610 REG_GPIO = $3F000;// bcm2835 gpio register 0x2000 0000 (RPi1), 0x3F00 0000 (RPi2)
611611 // new fpMap uses page offset, one page is 4096 bytes = 0x1000 so simply calculate 0x2000 0000 / 0x1000 = 0x2000 0
612612 PAGE_SIZE = 4096;
613613 BLOCK_SIZE = 4096;
614614 // The BCM2835 has 54 GPIO pins.
615615 // BCM2835 data sheet, Page 90 onwards.
616616 // There are 6 control registers, each control the functions of a block
617617 // of 10 pins.
618618
619619 CLOCK_BASE = (REG_GPIO + $101);
620620 GPIO_BASE = (REG_GPIO + $200);
621621 GPIO_PWM = (REG_GPIO + $20C);
622622
623623 INPUT = 0;
624624 OUTPUT = 1;
625625 PWM_OUTPUT = 2;
626626 LOW = False;
627627 HIGH = True;
628628 PUD_OFF = 0;
629629 PUD_DOWN = 1;
630630 PUD_UP = 2;
631631
632632 // PWM
633633
634634 PWM_CONTROL = 0;
635635 PWM_STATUS = 4;
636636 PWM0_RANGE = 16;
637637 PWM0_DATA = 20;
638638 PWM1_RANGE = 32;
639639 PWM1_DATA = 36;
640640
641641 PWMCLK_CNTL = 160;
642642 PWMCLK_DIV = 164;
643643
644644 PWM1_MS_MODE = $8000; // Run in MS mode
645645 PWM1_USEFIFO = $2000; // Data from FIFO
646646 PWM1_REVPOLAR = $1000; // Reverse polarity
647647 PWM1_OFFSTATE = $0800; // Ouput Off state
648648 PWM1_REPEATFF = $0400; // Repeat last value if FIFO empty
649649 PWM1_SERIAL = $0200; // Run in serial mode
650650 PWM1_ENABLE = $0100; // Channel Enable
651651
652652 PWM0_MS_MODE = $0080; // Run in MS mode
653653 PWM0_USEFIFO = $0020; // Data from FIFO
654654 PWM0_REVPOLAR = $0010; // Reverse polarity
655655 PWM0_OFFSTATE = $0008; // Ouput Off state
656656 PWM0_REPEATFF = $0004; // Repeat last value if FIFO empty
657657 PWM0_SERIAL = $0002; // Run in serial mode
658658 PWM0_ENABLE = $0001; // Channel Enable
659659
660660type
661661
662662 { TIoPort }
663663
664664 TIoPort = class // IO bank object
665665 private //
666666
667667 //function get_pinDirection(aPin: TGpIoPin): TGpioPinConf;
668668
669669 public
670670 FGpio: ^LongWord;
671671 FClk: ^LongWord;
672672 FPwm: ^LongWord;
673673 procedure SetPinMode(gpin, mode: byte);
674674 function GetBit(gpin : byte):boolean;inline; // gets pin bit}
675675 procedure ClearBit(gpin : byte);inline;// write pin to 0
676676 procedure SetBit(gpin : byte);inline;// write pin to 1
677677 procedure SetPullMode(gpin, mode: byte);
678678 procedure PwmWrite(gpin : byte; value : LongWord);inline;// write pin to pwm value
679679 end;
680680
681681 { TIoDriver }
682682
683683 TIoDriver = class
684684 private
685685
686686 public
687687 destructor Destroy;override;
688688 function MapIo:boolean;// creates io memory mapping
689689 procedure UnmapIoRegisrty(FMap: TIoPort);// close io memory mapping
690690 function CreatePort(PortGpio, PortClk, PortPwm: LongWord):TIoPort; // create new IO port
691691 end;
692692
693693var
694694
695695 fd: integer;// /dev/mem file handle
696696procedure delayNanoseconds (howLong : LongWord);
697697
698698implementation
699699
700700uses
701701 baseUnix, Unix;
702702
703703procedure delayNanoseconds (howLong : LongWord);
704704var
705705 sleeper, dummy : timespec;
706706begin
707707 sleeper.tv_sec := 0 ;
708708 sleeper.tv_nsec := howLong ;
709709 fpnanosleep (@sleeper,@dummy) ;
710710end;
711711{ TIoDriver }
712712//*******************************************************************************
713713destructor TIoDriver.Destroy;
714714begin
715715 inherited Destroy;
716716end;
717717//*******************************************************************************
718718function TIoDriver.MapIo: boolean;
719719begin
720720 Result := True;
721721 fd := fpopen('/dev/mem', O_RdWr or O_Sync); // Open the master /dev/memory device
722722 if fd < 0 then
723723 begin
724724 Result := False; // unsuccessful memory mapping
725725 end;
726726 //
727727end;
728728//*******************************************************************************
729729procedure TIoDriver.UnmapIoRegisrty(FMap:TIoPort);
730730begin
731731 if FMap.FGpio <> nil then
732732 begin
733733 fpMUnmap(FMap.FGpio,PAGE_SIZE);
734734 FMap.FGpio := Nil;
735735 end;
736736 if FMap.FClk <> nil then
737737 begin
738738 fpMUnmap(FMap.FClk,PAGE_SIZE);
739739 FMap.FClk := Nil;
740740 end;
741741 if FMap.FPwm <> nil then
742742 begin
743743 fpMUnmap(FMap.FPwm ,PAGE_SIZE);
744744 FMap.FPwm := Nil;
745745 end;
746746end;
747747//*******************************************************************************
748748function TIoDriver.CreatePort(PortGpio, PortClk, PortPwm: LongWord): TIoPort;
749749begin
750750 Result := TIoPort.Create;// new io port, pascal calls new fpMap, where offst is page sized 4096 bytes!!!
751751 Result.FGpio := FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortGpio); // port config gpio memory
752752 Result.FClk:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortClk);; // port clk
753753 Result.FPwm:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortPwm);; // port pwm
754754end;
755755//*******************************************************************************
756756procedure TIoPort.SetPinMode(gpin, mode: byte);
757757var
758758 fSel, shift, alt : byte;
759759 gpiof, clkf, pwmf : ^LongWord;
760760begin
761761 fSel := (gpin div 10)*4 ; //Select Gpfsel 0 to 5 register
762762 shift := (gpin mod 10)*3 ; //0-9 pin shift
763763 gpiof := Pointer(LongWord(Self.FGpio)+fSel);
764764 if (mode = INPUT) then
765765 gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) //7 shl shift komplemens - Sets bits to zero = input
766766 else if (mode = OUTPUT) then
767767 begin
768768 gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (1 shl shift);
769769 end
770770 else if (mode = PWM_OUTPUT) then
771771 begin
772772 Case gpin of
773773 12,13,40,41,45 : alt:= 4 ;
774774 18,19 : alt:= 2 ;
775775 else alt:= 0 ;
776776 end;
777777 If alt > 0 then
778778 begin
779779 gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (alt shl shift);
780780 clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
781781 clkf^ := $5A000011 or (1 shl 5) ; //stop clock
782782 delayNanoseconds(200);
783783 clkf := Pointer(LongWord(Self.FClk)+PWMCLK_DIV);
784784 clkf^ := $5A000000 or (32 shl 12) ; // set pwm clock div to 32 (19.2/3 = 600KHz)
785785 clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
786786 clkf^ := $5A000011 ; //start clock
787787 Self.ClearBit(gpin);
788788 pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
789789 pwmf^ := 0 ; // Disable PWM
790790 delayNanoseconds(200);
791791 pwmf := Pointer(LongWord(Self.FPwm)+PWM0_RANGE);
792792 pwmf^ := $400 ; //max: 1023
793793 delayNanoseconds(200);
794794 pwmf := Pointer(LongWord(Self.FPwm)+PWM1_RANGE);
795795 pwmf^ := $400 ; //max: 1023
796796 delayNanoseconds(200);
797797 // Enable PWMs
798798 pwmf := Pointer(LongWord(Self.FPwm)+PWM0_DATA);
799799 pwmf^ := 0 ; //start value
800800 pwmf := Pointer(LongWord(Self.FPwm)+PWM1_DATA);
801801 pwmf^ := 0 ; //start value
802802 pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
803803 pwmf^ := PWM0_ENABLE or PWM1_ENABLE ;
804804 end;
805805 end;
806806end;
807807//*******************************************************************************
808808procedure TIoPort.SetBit(gpin : byte);
809809var
810810 gpiof : ^LongWord;
811811begin
812812 gpiof := Pointer(LongWord(Self.FGpio) + 28 + (gpin shr 5) shl 2);
813813 gpiof^ := 1 shl gpin;
814814end;
815815//*******************************************************************************
816816procedure TIoPort.ClearBit(gpin : byte);
817817var
818818 gpiof : ^LongWord;
819819begin
820820 gpiof := Pointer(LongWord(Self.FGpio) + 40 + (gpin shr 5) shl 2);
821821 gpiof^ := 1 shl gpin;
822822end;
823823//*******************************************************************************
824824function TIoPort.GetBit(gpin : byte):boolean;
825825var
826826 gpiof : ^LongWord;
827827begin
828828 gpiof := Pointer(LongWord(Self.FGpio) + 52 + (gpin shr 5) shl 2);
829829 if (gpiof^ and (1 shl gpin)) = 0 then Result := False else Result := True;
830830end;
831831//*******************************************************************************
832832procedure TIoPort.SetPullMode(gpin, mode: byte);
833833var
834834 pudf, pudclkf : ^LongWord;
835835begin
836836 pudf := Pointer(LongWord(Self.FGpio) + 148 );
837837 pudf^ := mode; //mode = 0, 1, 2 :Off, Down, Up
838838 delayNanoseconds(200);
839839 pudclkf := Pointer(LongWord(Self.FGpio) + 152 + (gpin shr 5) shl 2);
840840 pudclkf^ := 1 shl gpin ;
841841 delayNanoseconds(200);
842842 pudf^ := 0 ;
843843 pudclkf^ := 0 ;
844844end;
845845//*******************************************************************************
846846procedure TIoPort.PwmWrite(gpin : byte; value : Longword);
847847var
848848 pwmf : ^LongWord;
849849 port : byte;
850850begin
851851 Case gpin of
852852 12,18,40 : port:= PWM0_DATA ;
853853 13,19,41,45 : port:= PWM1_DATA ;
854854 else exit;
855855 end;
856856 pwmf := Pointer(LongWord(Self.FPwm) + port);
857857 pwmf^ := value and $FFFFFBFF; // $400 complemens
858858end;
859859//*******************************************************************************
860860end.
861861```
862862
863863*Controlling Lazarus unit:(Project files[3](https://drive.google.com/folderview?id=0B-b-5ooIWPvGU043ZTZ0cUc2YkE&usp=sharing))*
864864
865865``` pascal
866866unit Unit1;
867867
868868{Demo application for GPIO on Raspberry Pi}
869869{Inspired by the Python input/output demo application by Gareth Halfacree}
870870{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
871871
872872{$mode objfpc}{$H+}
873873
874874interface
875875
876876uses
877877 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
878878 ExtCtrls, Unix, PiGpio;
879879
880880type
881881
882882 { TForm1 }
883883
884884 TForm1 = class(TForm)
885885 GPIO25In: TButton;
886886 SpeedButton: TButton;
887887 LogMemo: TMemo;
888888 GPIO23switch: TToggleBox;
889889 Timer1: TTimer;
890890 GPIO18Pwm: TToggleBox;
891891 Direction: TToggleBox;
892892 procedure DirectionChange(Sender: TObject);
893893 procedure GPIO18PwmChange(Sender: TObject);
894894 procedure GPIO25InClick(Sender: TObject);
895895 procedure FormActivate(Sender: TObject);
896896 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
897897 procedure GPIO23switchChange(Sender: TObject);
898898 procedure SpeedButtonClick(Sender: TObject);
899899 procedure Timer1Timer(Sender: TObject);
900900 private
901901 { private declarations }
902902 public
903903 { public declarations }
904904 end;
905905
906906const
907907 INPUT = 0;
908908 OUTPUT = 1;
909909 PWM_OUTPUT = 2;
910910 LOW = False;
911911 HIGH = True;
912912 PUD_OFF = 0;
913913 PUD_DOWN = 1;
914914 PUD_UP = 2;
915915 // Convert Raspberry Pi P1 pins (Px) to GPIO port
916916 P3 = 0;
917917 P5 = 1;
918918 P7 = 4;
919919 P8 = 14;
920920 P10 = 15;
921921 P11 = 17;
922922 P12 = 18;
923923 P13 = 21;
924924 P15 = 22;
925925 P16 = 23;
926926 P18 = 24;
927927 P19 = 10;
928928 P21 = 9;
929929 P22 = 25;
930930 P23 = 11;
931931 P24 = 8;
932932 P26 = 7;
933933
934934var
935935 Form1: TForm1;
936936 GPIO_Driver: TIoDriver;
937937 GpF: TIoPort;
938938 PWM :Boolean;
939939 i, d : integer;
940940 Pin,Pout,Ppwm : byte;
941941
942942implementation
943943
944944{$R *.lfm}
945945
946946{ TForm1 }
947947
948948procedure TForm1.FormActivate(Sender: TObject);
949949begin
950950 if not GPIO_Driver.MapIo then
951951 begin
952952 LogMemo.Lines.Add('Error mapping gpio registry');
953953 end
954954 else
955955 begin
956956 GpF := GpIo_Driver.CreatePort(GPIO_BASE, CLOCK_BASE, GPIO_PWM);
957957 end ;
958958 Timer1.Enabled:= True;
959959 Timer1.Interval:= 25; //25 ms controll interval
960960 Pin := P22;
961961 Pout := P16;
962962 Ppwm := P12;
963963 i:=1;
964964 GpF.SetPinMode(Pout,OUTPUT);
965965 GpF.SetPinMode(Pin,INPUT);
966966 GpF.SetPullMode(Pin,PUD_Up); // Input PullUp High level
967967end;
968968
969969procedure TForm1.GPIO25InClick(Sender: TObject);
970970begin
971971 If GpF.GetBit(Pin) then LogMemo.Lines.Add('In: '+IntToStr(1))
972972 else LogMemo.Lines.Add('In: '+IntToStr(0));
973973end;
974974
975975procedure TForm1.GPIO18PwmChange(Sender: TObject);
976976begin
977977 if GPIO18Pwm.Checked then
978978 begin
979979 GpF.SetPinMode(Ppwm,PWM_OUTPUT);
980980 PWM := True; //PWM on
981981 end
982982 else
983983 begin
984984 GpF.SetPinMode(Ppwm,INPUT);
985985 PWM := False; //PWM off
986986 end;
987987end;
988988
989989procedure TForm1.DirectionChange(Sender: TObject);
990990begin
991991 if Direction.Checked then d:=10 else d:=-10;
992992end;
993993
994994
995995procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
996996begin
997997 GpF.SetPinMode(Ppwm,INPUT);
998998 GpF.ClearBit(Pout);
999999 GpIo_Driver.UnmapIoRegisrty(GpF);
10001000end;
10011001
10021002procedure TForm1.GPIO23switchChange(Sender: TObject);
10031003
10041004Begin
10051005 Timer1.Enabled := False;
10061006 if GPIO23switch.Checked then
10071007 begin
10081008 GpF.SetBit(Pout); //Turn LED on
10091009 end
10101010 else
10111011 begin
10121012 GpF.ClearBit(Pout); //Turn LED off
10131013 end;
10141014 Timer1.Enabled := True;
10151015end;
10161016
10171017procedure TForm1.SpeedButtonClick(Sender: TObject);
10181018var
10191019 i,p,k,v: longint;
10201020 ido:TDateTime;
10211021begin
10221022 ido:= Time;
10231023 k:= TimeStampToMSecs(DateTimeToTimeStamp(ido));
10241024 LogMemo.Lines.Add('Start: '+TimeToStr(ido));
10251025 p:=10000000 ;
10261026 For i:=1 to p do Begin
10271027 GpF.SetBit(P16);
10281028 GpF.ClearBit(P16);
10291029 end;
10301030 ido:= Time;
10311031 v:= TimeStampToMSecs(DateTimeToTimeStamp(ido));
10321032 LogMemo.Lines.Add('Stop: '+TimeToStr(ido)+' Frequency: '+
10331033 IntToStr(p div (v-k))+' kHz');
10341034end;
10351035
10361036procedure TForm1.Timer1Timer(Sender: TObject);
10371037begin
10381038 If PWM then Begin
10391039 If (d > 0) and (i+d < 1024) then begin
10401040 i:=i+d;
10411041 GpF.PwmWrite(Ppwm,i);
10421042 end ;
10431043 If (d < 0) and (i+d > -1) then begin
10441044 i:=i+d;
10451045 GpF.PwmWrite(Ppwm,i);
10461046 end;
10471047 end;
10481048end;
10491049
10501050
10511051end.
10521052```
10531053
10541054### PXL (Platform eXtended Library) for low level native access to GPIO, I²C, SPI, PWM, UART, V4L2, displays and sensors
10551055
10561056- Easy and fast access to GPIO, I²C, SPI, PWM, UART and high precision CPU timer.
10571057- V4L2 video/image capture using onboard and USB cameras. Serial cameras such as VC0706 and LSY201.
10581058- OpenGL ES hardware rendering with and without X server. Software rendering.
10591059- I²C and SPI displays such as SSD1306, SSD1351, PCB8544 (Nokia), HX8357 and ILI9340.
10601060- Character LCDs with direct pin wiring.
10611061- Support for Software SPI and UART (bit-banging).
10621062- Support for SC16IS7x0 (UART controller connected via I²C or SPI), including extra GPIO pins.
10631063- Support for sensors such as BMP180, DHT22, L3GD20, LSM303 and SHT10.
10641064- Other features like networking, math, image transformation, effects, drawing primitives...
10651065
10661066*More info and download of [PXL library](http://asphyre.net/products/pxl).*
10671067
10681068*The PinDrive property is not implemented in the latest download from Asphyre so I am posting the code for my implementation in case anyone needs it. I found that the definition for TPinDrive is incorrect for the BCM2837 chip so I added some code to change it. This could be accomplished more easily by changing the definition but that file could conceivably be used for multiple chips (and I don't control the code) so I made all changes in the code to set the drive mode.*
10691069
10701070``` pascal
10711071
10721072procedure TFastGPIO.SetPinDrive(const Pin: TPinIdentifier; const Value: TPinDrive);
10731073const
10741074 GPPUDadr = $94;
10751075 GPPclkadr = $98;
10761076type
10771077 TBCM28PinDrive = (drvNone, drvPullDown, drvPullUp);
10781078var
10791079 dValue: TBCM28PinDrive;
10801080 PinBCM: TPinIdentifier;
10811081 GPPUD, GPPclk: Pointer;
10821082begin
10831083 case Value of
10841084 TPinDrive.PullUp: dValue := TBCM28PinDrive.drvPullDown;
10851085 TPinDrive.PullDown: dValue := TBCM28PinDrive.drvPullUp;
10861086 else
10871087 dValue := TBCM28PinDrive.drvNone;
10881088
10891089 PinBCM := ProcessPinNumber(Pin);
10901090
10911091 GPPUD := GetOffsetPointer(GPPUDadr);
10921092 WriteMemSafe(GPPUD, Cardinal(dValue));
10931093 FSystemCore.MicroDelay(1);
10941094
10951095 GPPclk := GetOffsetPointer(GPPclkadr + (Cardinal(PinBCM) div 32) * 4);
10961096 WriteMemSafe(GPPclk, 1 shl (PinBCM mod 32));
10971097 FSystemCore.MicroDelay(1);
10981098
10991099 WriteMemSafe(GPPUD, 0);
11001100 WriteMemSafe(GPPclk, 0);
11011101end;
11021102```
11031103
11041104## References
11051105
11061106- Eben Upton and Gareth Halfacree. Raspberry Pi User Guide. John Wiley and Sons, Chichester 2012, ISBN 111846446X
11071107- B. J. Rao (2013) The Raspberry Pi, Pi Vision and Lazarus/FPC. [Blaise Pascal Magazine](http://www.blaisepascal.eu). 29: 14-21.
11081108
11091109## External and Other Links
11101110
11111111- If you want to install the latest stable release of fpc and, additional and isolated, the trunk fpc compiler: you can read the following guide.
11121112
11131113It was written using gentoo but this guide will be useful with any distro: [[Install fpc on Raspberry with Gentoo]] (very out of date)
11141114
11151115- [Raspberry Pi Foundation](http://www.raspberrypi.org)
11161116- [Raspberry Pi Spy: Raspberry Pi tutorials, scripts, help and downloads](http://www.raspberrypi-spy.co.uk)
11171117- [Lazarus wrapper unit for Gordon Henderson's wiringPi C library](http://www.lazarus.freepascal.org/index.php/topic,17404.0.html)
11181118- [Another wiringPi wrapper with waitForInterrupt() and wiringPiISR()](https://github.com/laz2wiringpi/laz2wiringpi)
11191119- [Yet another wiringPi wrapper with waitForInterrupt(), wiringPiISR(), i2c, spi and serial](https://forum.lazarus.freepascal.org/index.php/topic,17404.msg405237.html#msg405237)
11201120- [Pin layout of the wiringPi library](https://projects.drogon.net/raspberry-pi/wiringpi/pins/)
11211121- [wiringPi fork updated for latest hardware](https://github.com/WiringPi/WiringPi)
11221122- [Additional information on Lazarus and Raspberry Pi at eLinux.org](http://www.elinux.org/Lazarus_on_RPi)
11231123- [Getting Started with Pascal on the Pi](http://www.pp4s.co.uk/main/gs-pi-intro.html) (noted dead link in late 2023)
11241124- [Getting Started with Led, Switch and DC motor on Pi](http://www.pp4s.co.uk/main/gs-pi-gpio-intro.html) (noted dead link in late 2023)
11251125- [lazi2cdev - General i2c with drivers for ADS1015 ADC, MCP23017 IO, MCP4725 DAC, PCA9685 PWM and HD44780 LCD](https://github.com/laz2wiringpi/lazI2cdev)
11261126- [Lazberry Pi: Comprehensive information on Lazarus on the Raspberry Pi computer](http://superbitysoft.co.uk/lazberrypi/). (noted dead link in late 2023)
11271127- Stefan Fischer's [rpi_hal library](https://github.com/rudiratlos/rpi-hal) and [rpi_hal discussion topic](http://www.lazarus.freepascal.org/index.php/topic,20991.0.html) on Lazarus forum.
11281128- [Improved Lazarus Unit for fast access to GPIO](http://www.meltonisl.com/pigpio.pas).
11291129- [PXL - Platform eXtended Library](http://asphyre.net/products/pxl).
11301130- [RPIIO - Raspberry Pi GPIO and I2C library](https://github.com/zipplet/rpiio).
11311131
11321132---
11331133*From the Free Pascal wiki, page "Lazarus on Raspberry Pi", as it stood on 2023-12-31 after a change by Dbannon, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history