Recent

Author Topic: FPC on Rasp Pi, non Lazarus, use of GPIO.  (Read 17646 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #60 on: February 21, 2021, 04:32:35 pm »
Is there a description of that API anywhere?  I've searched and come up dry.

gpiod

Quote
It occurs to me that a souped up Arduino could be my "sampler" (easy to program timer interrupts on that), compress the data and ship it to the Pi over serial (of some sort).  I'll look into that possibility too.  Not sure it could manage 1 Khz though.  I did have a main loop on the Arduino running 1300-1400 Hz (16 MHz clock) with all sorts of things going on.  Write tight and good things happen... I could also modify the Arduino to get 20 MHz ... though that's a little more complicated...

https://rasp.io/duino/ is a good start, interfaced either serially or using I2C. Otherwise the Teensy is worth looking at, it has a rawhid interface over USB which should be fast *BUT* that would still leave you at the mercy of Linux and the non-deterministic USB protocol.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #61 on: February 21, 2021, 04:49:10 pm »
Quote
Quote
Quote from: AlanTheBeast on Today at 04:11:31 pm
Is there a description of that API anywhere?  I've searched and come up dry.

gpiod

https://youtu.be/OmBxVfQTuvI?t=15
... what a difference a d makes ....

Quote
https://rasp.io/duino/ is a good start,

Is too neat!  I'll keep that in mind just in case.
« Last Edit: February 21, 2021, 06:17:32 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #62 on: February 21, 2021, 08:42:30 pm »
@ojz0r

I've made some changes (as I was trying to understand it, these made sense to improve the speed).

1- Eliminated GVL.
2- Classless unit (removed try/finally)
3- Added a control array to speed evaluation

This is tested with discrete I/O only.

As I get into this I might tighten up more - TBD.


Code: Pascal  [Select][+][-]
  1. unit IO_GPIO; (* Access GPIO on Raspberry PI 40-pin *)
  2.  
  3. interface
  4.         procedure readInputs;
  5.         procedure setOutputs;
  6.         procedure unexportGPIO;
  7.  
  8. var
  9.         GPIO: array [0..27] of boolean;
  10.  
  11. implementation
  12. uses
  13. (*********************************************************************
  14. Uses system units
  15. *********************************************************************)
  16. SysUtils,
  17. Unix,
  18. BaseUnix,
  19. Crt,
  20.  
  21. (*********************************************************************
  22. Uses user defined units
  23. *********************************************************************)
  24. iolist;
  25.  
  26. type
  27.         Direction = (GPIO_input, GPIO_output,GPIO_NotUsed);
  28. var
  29.         aGPIO: array [0..27, 0..2] of string;
  30.         dGPIO: array [0..27] of Direction;
  31.  
  32. (*********************************************************************
  33. Open GPIO for access
  34. *********************************************************************)
  35. procedure gpioExport(pin, dir: string);
  36. var
  37.         fileDesc: integer;
  38.         gpioPinDirPath: string;
  39.        
  40. begin
  41.         (* Prepare SoC pin for access *)
  42.                 fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
  43.                 fpwrite(fileDesc, pin[1], Length(pin));
  44.                 fpclose(fileDesc);
  45.         (* Set SoC pin (in/out) direction *)
  46.                 gpioPinDirPath := '/sys/class/gpio/'+'gpio'+pin+'/direction';
  47.                 fileDesc := fpopen(gpioPinDirPath, O_WrOnly);
  48.                 fpwrite(fileDesc, dir[1], Length(dir));
  49.                 fpclose(fileDesc);
  50. end;
  51.  
  52. (*********************************************************************
  53. Read GPIO inputs
  54. *********************************************************************)
  55. function input(pin, dir: string): boolean;
  56.  
  57. var
  58.         fileDesc: integer;
  59.         gpioPinValuePath: string;
  60.         state: string = '0';
  61. begin
  62.         input := false;
  63.         gpioPinValuePath := '/sys/class/gpio/'+'gpio'+pin+'/value';
  64.         gpioExport(pin, dir);
  65.         (* Open SoC pin input read-only mode *)
  66.         fileDesc := fpopen(gpioPinValuePath, O_RdOnly);
  67.         if fileDesc > 0 then
  68.                 begin
  69.                         (* Read status of input pin, return true if high *)
  70.                         fpread(fileDesc, state[1], 1);
  71.                         if state = '0' then
  72.                                 input := false
  73.                         else
  74.                                 input := true;
  75.                 end;
  76.         (* Close SoC pin *)
  77.         fpclose(fileDesc);
  78. end;
  79.  
  80. (*********************************************************************
  81. Set GPIO output
  82. *********************************************************************)
  83. procedure output(pin, dir, cmd: string);
  84. var
  85.         fileDesc: integer;
  86.         gpioPinValuePath: string;
  87.        
  88. begin
  89.         gpioPinValuePath := '/sys/class/gpio/'+'gpio'+pin+'/value';
  90.         gpioExport(pin, dir);
  91.         (* Set SoC pin output state *)
  92.         fileDesc := fpopen(gpioPinValuePath, O_WrOnly);
  93.         fpwrite(fileDesc, cmd[1], 1);
  94.         fpclose(fileDesc);
  95. end;
  96.  
  97. (*********************************************************************
  98. Close GPIO
  99. *********************************************************************)
  100. procedure gpioUnexport(pin: string);
  101. var
  102.         fileDesc: integer;
  103.  
  104. begin
  105.         (* Free SoC pin *)
  106.         fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
  107.         fpwrite(fileDesc, pin[1], Length(pin));
  108.         fpclose(fileDesc);
  109. end;
  110.  
  111. (*********************************************************************
  112. Free (unexport) GPIO pins on program exit
  113. *********************************************************************)
  114. procedure unexportGPIO;
  115. var
  116.         io: integer;
  117.  
  118. begin
  119.         for io := 0 to 27 do
  120.                 if dGPIO[io] in [GPIO_Input..GPIO_Output] then
  121.                         gpioUnexport(intToStr(io));
  122. end;
  123.  
  124. (*********************************************************************
  125. Read inputs
  126. *********************************************************************)
  127. procedure readInputs;
  128. var
  129.         io:integer;
  130. begin
  131.         for io := 0 to 27 do
  132.                 if dGPIO[io] = GPIO_Input then
  133.                                 GPIO[io] := input(aGPIO[io][0], aGPIO[io][1]); (* input function, returns boolean input state *)
  134. end;
  135.  
  136. (*********************************************************************
  137. Set outputs
  138. *********************************************************************)
  139. procedure setOutputs;
  140. var
  141.         io: integer;
  142. begin
  143.         for io := 0 to 27 do
  144.                 if dGPIO[io] = GPIO_Output then
  145.                         begin
  146.                                 if GPIO[io] then (* Define command *)
  147.                                         aGPIO[io][2] := '1'
  148.                                 else
  149.                                         aGPIO[io][2] := '0';
  150.                                 output(aGPIO[io][0], aGPIO[io][1], aGPIO[io][2]); (* output procedure, write output state *)
  151.                         end;
  152. end;
  153. // ----------------------------------------------------------------------
  154. Procedure init_GPIO;
  155. var
  156.         i: integer;
  157. begin
  158.         for i := 0 to 27 do
  159.                 begin
  160.                         aGPIO[i][0] := intToStr(i); //define pin
  161.                         case IOlist.GPIO[i] of
  162.                                 'output': begin
  163.                                                         aGPIO[i][1] := 'out';
  164.                                                         aGPIO[i][2] := '0';   // init off state
  165.                                                         dGPIO[i] := GPIO_Output;
  166.                                                   end;
  167.                                 'input' : begin
  168.                                                         aGPIO[i][1] := 'in';
  169.                                                         dGPIO[i] := GPIO_Input;
  170.                                                   end;
  171.                            ELSE
  172.                                                 begin
  173.                                                         dGPIO[i] := GPIO_NotUsed;
  174.                                                 end;
  175.                         end{case};
  176.                 end;
  177.         setOutputs;
  178.         readInputs;
  179.         writeln ('CHG 12');
  180. end;
  181.  
  182. begin
  183.         writeln ('IO_GPIO Mod version');
  184.         init_GPIO;
  185. (*********************************************************************
  186. End unit
  187. *********************************************************************)
  188. end.
  189.  
« Last Edit: February 21, 2021, 08:48:03 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #63 on: February 21, 2021, 09:05:57 pm »
I'd be cautious about the performance of all of those fpopen() fpclose() syscalls.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #64 on: February 21, 2021, 09:16:30 pm »
Can always be restored to the prior.

I doubt it will break...

I do want to look into opening once per program instance and closing once per program instance - that's just more globals to hold the references.
« Last Edit: February 21, 2021, 09:31:39 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #65 on: February 21, 2021, 09:44:01 pm »
I do want to look into opening once per program instance and closing once per program instance - that's just more globals to hold the references.

That's crying out for a class, with procedures/functions ("methods") to set/reset/read a pin and internal storage of the handle or text file assigned to its value.

However, one has to be very careful with all of this stuff since direction and accessibility can change during the lifetime of a program. The test program I'm using to explore this- which was written way before the RPi came out- can cope with that, but I find myself wondering how the monitor functionality of the "new" API copes if the role of a pin it's watching changes.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #66 on: February 21, 2021, 10:23:03 pm »
To me a unit is fine for this w/o needing a class.  A unit has a globals section to hold state and handles whether in the interface or implementation and that's fine for this - at least for my hobby purposes.  And that's how ojz0r's unit was.  Fine.

Old school.  I know.

Generally for h/w applications of the port, I wouldn't expect the direction or configuration of a pin to change during the instance of the program.  If a device were more sophisticated than that, then the programmer would have to up his sophistication to match.

Now that I'm grasping how this GPIO interface is implemented in Linux I have to say I'm really not pleased with it - sucks would be a compliment.  I'm less and less sure I can do my project as originally envisioned.  I may need a sensor processor that is sans OS and has a very tight interface to the general system.

On that note, if I know the memory mapping (ports?) of the devices, can I end run the /sys/class/gpio ??? or will the memory controller intercept that?
« Last Edit: February 21, 2021, 10:31:03 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #67 on: February 21, 2021, 10:31:48 pm »
To me a unit is fine for this w/o needing a class.  A unit has a globals section to hold state and handles whether in the interface or implementation and that's fine for this - at least for my hobby purposes.  And that's how ojz0r's unit was.  Fine.

Old school.  I know.

I suspect I've been doing this stuff longer than you have, so have even more excuse to be set in my ways. And my school was /definitely/ older than yours.

And a pin could usefully be implemented as a class.

Quote
Generally for h/w applications of the port, I wouldn't expect the direction or configuration of a pin to change during the instance of the program.  If a device were more sophisticated than that, then the programmer would have to up his sophistication to match.

Irrespective of what you might expect, the direction/sense/accessibility /can/ be changed during execution of a program... and if the GPIO device is connected via something like USB it might even be unplugged (or a second device plugged in). I'm not thinking about it being done by the program itself, but by a user in a different session.

Quote
Now that I'm grasping how this GPIO interface is implemented in Linux I have to say I'm really not pleased with it - sucks would be a compliment.  I'm less and less sure I can do my project as originally envisioned.  I may need a sensor processor that is sans OS and has a very tight interface to the general system.

The fundamental problem is that Linux isn't an RTOS... add to that that GPIO bits might not be endowed with an adequate number of interrupts.

Use an FPGA... you know you want to :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #68 on: February 21, 2021, 11:31:17 pm »

I'll stick to my liteness on the class issue.

For my project the pins will not be changing direction or function at all.  This is a project where the only person using it will be me. 

An FPGA could do it if I can acquire the processor cell for free - but I don't have a dev environment for that either... not sure how hard it is to do these days for that matter or what it would take out of my non-infinitely deep budget.  I never did an FPGA.  The engineers were stuck with that.  I seem to recall a lot of hair being pulled out.  But that was a long time ago.

A 64 bit Arm or intel SoC mounted on a breakout board and some programming tools would really be all I need.  Don't need no stinkin' OS.  Give me an interrupt controller and a timer and that's all a boy needs for a hot time.  I'd even, yes, I'll say it, lower myself to programming in C <spit!>.  I'll shop around - there has to be something out there that doesn't need Linux.

(32 bit would likely do but nothing is cheaper than brute force when doing one-off projects...)

Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.


ojz0r

  • Jr. Member
  • **
  • Posts: 58
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #70 on: February 22, 2021, 08:32:42 am »
@ojz0r

I've made some changes (as I was trying to understand it, these made sense to improve the speed).

1- Eliminated GVL.
2- Classless unit (removed try/finally)
3- Added a control array to speed evaluation

I just settled when i got it working, i dont really need exceptional speed.
However your code looks much neater, i will check it out more in detail when i get the chance.

An FPGA could do it if I can acquire the processor cell for free - but I don't have a dev environment for that either... not sure how hard it is to do these days for that matter or what it would take out of my non-infinitely deep budget.  I never did an FPGA.  The engineers were stuck with that.  I seem to recall a lot of hair being pulled out.  But that was a long time ago.

I like the FPGA's more, full control of every aspect of the hardware and no pesky OS to hold you back  :D
Just trying to learn.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #71 on: February 22, 2021, 09:02:08 am »
A 64 bit Arm or intel SoC mounted on a breakout board and some programming tools would really be all I need.  Don't need no stinkin' OS.  Give me an interrupt controller and a timer and that's all a boy needs for a hot time.  I'd even, yes, I'll say it, lower myself to programming in C <spit!>.  I'll shop around - there has to be something out there that doesn't need Linux.

You could use bare metal AArch64 examples like this (Rpi3) or this (RPi4). In principle these can be ported to FPC, though FPC does not yet have a enabled aarch64-embedded target, though it wouldn't be that difficult to do so.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #72 on: February 22, 2021, 09:07:27 am »
An FPGA could do it if I can acquire the processor cell for free - but I don't have a dev environment for that either... not sure how hard it is to do these days for that matter or what it would take out of my non-infinitely deep budget.  I never did an FPGA.  The engineers were stuck with that.  I seem to recall a lot of hair being pulled out.  But that was a long time ago.

https://hackaday.io/list/160076-fpga-tutorials
https://hackaday.com/2020/01/24/new-part-day-led-driver-is-fpga-dev-board-in-disguise/

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #73 on: February 22, 2021, 03:05:53 pm »
On that note, if I know the memory mapping (ports?) of the devices, can I end run the /sys/class/gpio ??? or will the memory controller intercept that?

There's this sort of thing, which implies that /dev/gpiomem and possibly /dev/mem might be usable.

https://raspberrypi.stackexchange.com/questions/99785/what-is-the-correct-way-to-use-dev-gpiomem-with-mmap-to-get-access-to-raspberry

That is definitely not something I will be playing with, since it is non-portable (i.e. RPi-specific) and only conceals the performance issue rather than providing a robust solution.

I append a compiles-but-untested implementation of static and dynamic interface units for the gpiod library. Use /either/ gpiod.pas /or/ gpiod_dynamic.pas, the API exposed should be identical and should behave as documented for C etc.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 348
  • My software never cras....
Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
« Reply #74 on: February 22, 2021, 03:08:45 pm »
@PascalDragon
@DonAlfredo
@ojz0r
@MarkMLI

Thanks all for your inputs and suggestions.  I won't have much time for the project until Friday (well, the book keeper is in my office tomorrow, so maybe I'll drag the project to work while she does real work).
Quote
Quote
I've made some changes (as I was trying to understand it, these made sense to improve the speed).

3- Added a control array to speed evaluation

I just settled when i got it working, i dont really need exceptional speed.

However your code looks much neater, i will check it out more in detail when i get the chance.

Not sure about neater - indents didn't paste right and there's more to do in the lower level code - but I have to understand it a bit better first.
I confess to code efficiency creeping elegance syndrome.  MarkMLI would call it 'dangerous optimization' I think.

Quote
I like the FPGA's more, full control of every aspect of the hardware and no pesky OS to hold you back  :D

Esp. the /OS part!
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

 

TinyPortal © 2005-2018