Lazarus

Installation => Linux => Topic started by: AlanTheBeast on February 18, 2021, 06:02:25 pm

Title: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 06:02:25 pm
Hi,

I don't need Laz for my Pi project.  But I do need access to the GPIO.

How do I go about that?  Are there units I can DL for that?  Current v. is FPC 3.0.4 under 32b Rasp Pi OS.

Thanks,
Alan.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 18, 2021, 06:36:08 pm
Check out the wiki page: https://wiki.freepascal.org/Raspberry_Pi
Thats a very good guide for gpio access.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 18, 2021, 06:52:29 pm
In any event the GPIO bits are exposed via a standard API in the /sys tree, and I believe that there's also a newer (and higher performance) way of driving the bits by accessing /dev devices although I've not played with it yet.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 07:03:47 pm
Thanks both MarkMLI and ojzOr -

I hope to also be able to easily link assembly code.  But that is next week (waiting for the parts to come (GPS, Accel/gyro)).


So, you send me a link that says:   "https://wiki.freepascal.org/Raspberry_Pi"

And I end up on the page: "https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi"

Argghh ... Oh, well, it's a start!  I'll figure out (I hope) how to strip Laz out of that....  I really only want/need a CLI as the project will be headless in the end...
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 18, 2021, 07:16:56 pm
Its not hard to strip the Lazarus part out,  if you get stuck t can send you an example based on that guide that im currently running on a RPi Zero W.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 07:26:48 pm
ojzOr - well don't delay, act now!  Thanks. 

(Yes, I'm lazy!).

Thanks

I'll be doing a Pi zero eventually as a remote sensor with a LoRa ... maybe in a month... want to do some airborne experiments too ( carry on a drone ).
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 18, 2021, 07:28:51 pm
The RPi is a standard Linux-based computer, albeit a bit smaller than most and with not-quite-standard startup and video arrangement.

Lazarus is an IDE that is entirely suitable for non-GUI development: scratch the surface and you'll find that many if not most of the FPC core developers use it to work on the compiler.

If you don't want to use Lazarus then use some other editor and makefiles etc., but assume that much of the Lazarus (as distinct from LCL) documentation actually pertains to the underlying compiler.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 07:46:38 pm
@Mark,

I'm not familiar with Lazarus.
OTOH, I'm quite happy to write Pascal in a basic text editor or lite IDE.  Indeed there's one I found with the Rasp OS distro called Geany that recognizes Pascal and invokes FPC.  I was surprised.

The "overhead" of Lazarus, etc., just gets in the way of my project timewise - I don't want to invest much into it when I won't be implementing or using it.  A CLI is all I need to run, test and complete the work.

I'm trying to avoid C because I despise C.  I'd rather write in assembler than C (but I don't know the ARM machine that well so another learning process to avoid...).  (I did an Arduino project in "C" (ish) which reminded me how bad it is...)

Plain old Pascal is all I need (of the Turbo vein with units)... I'll even jump to Python 3 (spit!) if need be...

That said, I'll install Lazarus on the Pi and try the demo at the linked page... you never know... I might succumb...

Thanks!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: JuhaManninen on February 18, 2021, 08:22:44 pm
The "overhead" of Lazarus, etc., just gets in the way of my project timewise - I don't want to invest much into it when I won't be implementing or using it.  A CLI is all I need to run, test and complete the work.
What overhead do you mean? How does it get in the way?
In reality it is snappy. It does everything that Geany does + a lot more.
Lazarus trunk is speed optimized recently. Especially startup in Unix related systems is faster now. Raspberry Pi users please test. The memory and HW requirements however remain the same because compilation and especially linking hog resources.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 18, 2021, 08:34:01 pm
The "overhead" of Lazarus, etc., just gets in the way of my project timewise

What overhead? It's a better-than-average text editor (not as good as Multi-Edit on DOS, but nothing is) with the major advantage of a properly-integrated debugger.

I'm not sure that "underhead" is a word, but criticising it due to automatically assuming that it introduces an unacceptable amount of cruft is at best underhand :-)

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 09:25:08 pm

I mean overhead in the code, generally.  Also the overhead of learning Lazarus when all I need is access to the GPIO pins.

For example "https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Switching_a_device_via_the_GPIO_port" uses a TForm ...  don't need that ... at all.

In essence when someone wants access to the GPIO pins (or other h/w) then the abstraction should be about that w/o showing all the rest.

I don't need "objects" to access a pin on a header.

etc and so on
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 18, 2021, 09:52:23 pm
Lazarus is an IDE. The LCL is GUI stuff. Objects have their uses even if you aren't using GUI-oriented components.

The first part of that example manipulates the GPIO bits via- AS I HAVE ALREADY SAID- the /sys tree. The GUI stuff is there entirely as eye-candy.

The second part goes via /dev/mem (which is a non-standard RPi-specific interface)... again, the GUI-based stuff is completely irrelevant except that it's easier to drop a couple of buttons onto a form than to implement an interactive text-based demo (I'll leave you to work out how I know).

The second part /does/ use a couple of classes to encapsulate functionality, I'm undecided as to whether that's justified without seeing a larger project that demonstrates the author's intent.

If you cited an interface which was distributed as a Lazarus package and couldn't easily be unbundled from its visual component then your reservations would be justified. As it is, you are criticising from an uninformed position: AS I HAVE ALREADY SAID the Lazarus IDE is an exceptionally good development environment for character (console) based programs (and I've used- and sold- quite a few in my time).

MarkMLl


Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 10:47:51 pm
I appreciate the help (and yes I realize that Laz is an IDE).

However it seems like all examples around here must pass through the GUI stuff (Forms, etc).
Why do I need objpascal?  Do I need objpascal?  (Certainly don't want it).

I just want to know the very basic things I need to do to get at that h/w and would be much happier without all the cruft of forms, etc.

I don't use object Pascal - so the purpose of (Sender: TOBject) is pretty opaque to me in the example.  Yes, I can figure it out or muddle my way through   I'd rather write (or use) a simple, clear, clean, fast, unit -no objects.

So (IMO) when people make examples, they should make the simplest example possible w/o all the wrappers, bells and whistles that are not related to the specifics - to make things clearer.

Sorry to vent when people are helping!

Thanks!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 18, 2021, 11:04:27 pm
Object Pascal is a somewhat extended variant of Turbo Pascal, which is a somewhat extended variant of J&W Pascal. You don't want me to start going on about the precursors or the politics that resulted in Pascal. Honest.

If you don't want or need the OP extensions, then don't use them. Simple as that.

If you feel like writing something that is text-menu based or has an internal command line then do so, but don't knock the efforts of people who've gone to the trouble of providing examples (e.g. of how to get at GPIO bits) and have chosen to save themself effort by using form-based GUI stuff as a wrapper.

FFS, man, *READ* those examples and you'll see that by and large they show you how to do things like accessing the GPIO bits independent of the GUI wrapper. You asked for an example, somebody gave you one: study it.

Now before you tax the community's patience any further, I strongly suggest that you install Lazarus and experiment with using it to develop and debug a couple of simple console-based ** application programs. If you don't like it that's fine, but don't go on to complain that the FP editor or some out-of-tree IDE has poor debugger support (unless, of course, you're prepared to contribute by improving it).

** Text-only. Non-GUI. No forms involved. Runs from the shell. etc. Start off with the canonical "Hello, World!".

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 18, 2021, 11:58:19 pm
Hi Mark,

Don't assume I'm not reading.

I'll be working on the project tomorrow.

Cheers,
Alan

Where do I pay the back taxes?

As to the history of Pascal, I do know that had attention been paid to rapidly adding to the initial Wirth version early and not kept ring fenced it would likely be a major language today.  Indeed, Ada could have been built around it as a core instead of merely inspired by it had such attention been paid earlier...

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 09:25:50 am
Don't assume I'm not reading.

I'll be working on the project tomorrow.

:-)

Quote
As to the history of Pascal, I do know that had attention been paid to rapidly adding to the initial Wirth version early and not kept ring fenced it would likely be a major language today.  Indeed, Ada could have been built around it as a core instead of merely inspired by it had such attention been paid earlier...

It's deeper than that: Pascal was the result of ALGOL-68 being sabotaged. And my major use for Ada is using it to point out that when the DoD was looking for a language base they didn't seriously consider Lisp, although I've seen other people revisiting it comparatively recently and being impressed https://www.revk.uk/2017/11/ada.html

One thing I'd throw in about GPIO etc. is that you probably appreciate that in order to get /really/ high-speed access you'd need to get involved with a kernel module: I don't think there's a way to get a GPIO event to interrupt or signal a userspace program directly. And realistically, writing Linux kernel modules needs C. And of course, Linux is not a real-time OS (RTOS) so makes no promises about latency etc.

Over the last few months I've been playing with a CH341 board as discussed at https://hackaday.com/2018/02/21/linux-adds-ch341-gpio/ I found that I had to tweak the module/driver slightly in order to get predictable kernel-generated names, but after that it behaved very much as would be expected on an RPi. I was using GPIO access via /sys, which is the "old" kernel standard, there's also a "new" kernel standard interface via /dev/gpiochip* which I've not yet played with, and the RPi-specific one via /dev/mem which I've /definitely/ not played with https://embeddedbits.org/new-linux-kernel-gpio-user-space-interface/

HTH

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 19, 2021, 10:39:23 am
First off I'd like to second that Lazarus is really light weight.
However since I'm new to both Pascal and Lazarus I have not got around to do actual coding in Lazarus (its on my todo list).
I've written everything in Nano and compiled with "fpc <program>" directly on the RPi and launching with "./<program>".

Here are the units i have created to make my life easier. (It probably looks like crap to experienced programmers)
You can use it as an example or straight up if you find it sufficient for your needs.

Basically my example contains 3 units:
- GVL.pas: "Global variable list", i use it in the program/sub-units to access the GPIO globaly with "GVL.GPIO[17]" for example.
With this you need to call procedures "GVL.readInputs()" before using the inputs and "GVL.setOutputs()" to set the outputs. When terminating the application you would use the "GVL.unexportGPIO()" to restore the GPIO again.
- iolist.pas: This is the I/O-list i use to map the individual GPIO's as input/output. This is the basis for the last module.
- IO_GPIO.pas: This is the actual "driver" based on the /sys example in the wiki. This one contains procedures used by GVL.pas.

Example how to use:
Code: Pascal  [Select][+][-]
  1. program main(input, output);
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.         ..., GVL;
  6.  
  7. begin
  8.         repeat                          // Loop
  9.         GVL.readInputs();               // Read the inputs defined in iolist.pas
  10.  
  11.         if GVL.GPIO[17] then            // Use GPIO 17
  12.         begin
  13.                 GVL.GPIO[18] := true;   // Set GPIO 18
  14.         end;
  15.  
  16.         GVL.setOutputs();               // Set the output state of GPIO's defined in iolist.pas
  17.        
  18.         until not GVL.GPIO[20]          // Escape loop
  19.  
  20.         GVL.unexportGPIO();             // Unexport/free the GPIO from /sys upon program termination
  21. end.
  22.  

Edit: Spelling mistake.
I forgot to mention: my setup is positive voltage to GPIO input = TRUE. Output TRUE = positive voltage on GPIO pin. This can be switched in the IO_GPIO.pas unit.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 12:24:03 pm
First off I'd like to second that Lazarus is really light weight.
However since I'm new to both Pascal and Lazarus I have not got around to do actual coding in Lazarus (its on my todo list).
I've written everything in Nano and compiled with "fpc <program>" directly on the RPi and launching with "./<program>".

Here are the units i have created to make my life easier. (It probably looks like crap to experienced programmers)
You can use it as an example or straight up if you find it sufficient for your needs.

Remember: you're writing /in/ Pascal, using the Lazarus IDE as a tool. If you want to use GUI facilities you will end up pulling in stuff from the LCL, otherwise you'll be using the FPC runtime library (RTL) and possibly stuff from the non-GUI FPC Class Library (FCL).

I mention the distinction between RTL and FCL because of the documentation subtrees at https://www.freepascal.org/docs.html which are obviously distinct from https://lazarus-ccr.sourceforge.io/docs/lcl/

One thing I have to ask about your attachment: why are you importing the Crt unit? I'd also query why you've got those GPIO arrays in the interface unit: if you have to have that then put it in the implementation part and access it via a function (to read) or procedure (to write) so that you've got /some/ semblance of control over what can do what.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 19, 2021, 12:44:14 pm
Well the Crt part is a leftover from previous experimenting, i have yet to completely cleaned up all parts of my code.

I did not attach all my code, maybe the complete project would give a hint at what i was aiming for putting the array in the interface part.
Basically for (again) my use case, i would read the inputs at beginning of a loop and then do logic in between and then set the outputs at the end of the loop, ie i dont use the GPIO inputs in "real time" but an image of the status when entering the loop and writing outputs at the end. So by putting the array in the interface i can use the GPIO[n] freely within the programming without calling a procedure or function to return the instantaneous result.
As i'm writing this i see that it comes of as niché, pascal is a hobby to me and my day job is programming industrial control systems (PLC/DCS) so the concept is to resemble that.

I merely attached the units to give the OP some example based on the wiki /sys example without the form part.
I'm not trying to step on anybodys toes, i know im fresh and not a software engineer, i just want to help.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 01:14:57 pm
Even if the GPIO array is only temporary, accepted practice would be to have it in one place with published/exported routines for getting and setting pins. You could also have a unit-level property to make it look like you were accessing a variable.

That would have the undeniable advantage that you could put a breakpoint on the setter and see exactly what was happening, and any overhead that the compiler didn't optimise out would be miniscule compared with what the kernel was having to do to process your 0/1 character through the standard API, and then put it through a module/driver to access the physical bit.

/However/, speaking as somebody else who is industrially-oriented and departing from accepted doctrine, I would not argue that it improved system robustness. Neither FPC nor the underlying OS, and for that matter not the hardware either, implements the sort of segmented architecture which would allow you to say "this physical access routine can only be called by this other part of the code". It is, at a pinch, possible to contrive schemes with access tokens etc. but without physical protection they can always be spoofed.

Linux (in fact POSIX) does have a capabilities mechanism which means that control of the GPIO bits can be enabled or disabled on a per-process/program basis, but it doesn't provide any finer (e.g. per-thread) protection than that and once a handle has been granted I don't think it can be revoked.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 03:24:29 pm
@Mark: re: Ada, I read part of the linked article.  One doesn't typically "do Ada" because "want to try using it".  One does Ada because they get hired by an aerospace or defence co. and the Booch is thrown on their desk, "to get familiar" before having some code thrown at them to change.   And here's the company style guide. And here's the flowed down B----g contract paragraph that says: "No recursion and no task rendez-vous".  Here's how you check out code.  Report before you leave for the day.

(I actually had the benefit of an in-house class ... [funny moment: as I was coding an exercise the instructor commented: wouldn't it be nice if indenting was all you needed for a code block.  I chuckled.  Did he know about Python?])

re: real time:  I do hope to be able to set up a timer interrupt at 1 KHz, possibly 2 KHz.  That will be essential to sampling my sensors as well as running a Kalman-ish filter at 10 Hz.  Otherwise I'll have to turn the Pi into an embedded system w/o OS.  (I'd prefer that in some ways...)

@ojzOr: thanks for the code - that's more my cuppa!

EDIT: Forgot to mention, last night installed Laz on the Pi, and made the project from the Wiki, got it to build and run.  All I get is a blank form.  Not sure if I need to set up the hardware to 'drive' that, but should get to it sometime today.
Laz is pretty clunky on the Pi (Pi 4 B (4 cores/1.5GHz) with 8 GB of ram).
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 03:35:53 pm
@Mark: re: Ada, I read part of the linked article.  One doesn't typically "do Ada" because "want to try using it".  One does Ada because they get hired by an aerospace or defence co. and the Booch is thrown on their desk, "to get familiar" before having some code thrown at them to change.   And here's the company style guide. And here's the flowed down B----g contract paragraph that says: "No recursion and no task rendez-vous".  Here's how you check out code.  Report before you leave for the day.

You obviously aren't familiar with the author. He's ex-BigCorporate, designs and builds high-throughput Internet devices, and runs an ISP. The sort of ISP where one doesn't need any magic words to get through to somebody who knows what he's doing.

https://xkcd.com/806/
https://hackaday.com/2017/12/14/adsl-robustness-verified-by-running-over-wet-string/

Not sure where you're going to be with a high-speed timer interrupt though. That's a very "non-unix" thing to ask... you might be able to do something with a looping thread and either fpSelect() or fpNanoSleep(), but by and large things that require that degree of aggression have specific kernel support.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 19, 2021, 03:57:41 pm
Even if the GPIO array is only temporary, accepted practice would be to have it in one place with published/exported routines for getting and setting pins. You could also have a unit-level property to make it look like you were accessing a variable.

That would have the undeniable advantage that you could put a breakpoint on the setter and see exactly what was happening, and any overhead that the compiler didn't optimise out would be miniscule compared with what the kernel was having to do to process your 0/1 character through the standard API, and then put it through a module/driver to access the physical bit.

Sadly I don't have the experience/deep enough knowlage to relate to what you mean. I have an easier time learning by studying examples and trying it out.
Do you have some kind of example of this method? Or a wiki page/tutorial link explaining?
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 04:03:30 pm
Not impugning the guy, it's just that Ada is not something one does for fun.  It is the anti-C.  It's hard work (to do right) and usually because it is a requirement, not a desire.  That said, he can indeed do it for himself or co. if he seriously wants to build stronger, more reliable code.  But there is a cost to it in time.  I haven't touched it in decades (literally) and the only time my code was in production it was in 8086 assembler in a system that was otherwise almost 100% Ada (early 90's).

Also, see my revised comment above ("EDIT").

As to real time, I do need a pretty crisp sampling rate and period.  I assumed that Linux' nous as an embedded system core would support that... ah well, if it comes to it I can go OS-less on the sensor end.  Heck, write in Ada.  (kidding).
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 04:15:31 pm
re: real time:  I do hope to be able to set up a timer interrupt at 1 KHz, possibly 2 KHz.  That will be essential to sampling my sensors as well as running a Kalman-ish filter at 10 Hz.  Otherwise I'll have to turn the Pi into an embedded system w/o OS.  (I'd prefer that in some ways...)

Linux isn't an embedded OS. People try to use it as an embedded OS, just as they try to use Android as an embedded OS (e.g. in 4G USB sticks), but it's not an RTOS and generally speaking (I've not checked the specific GPIO case) it's not easy to hook an interrupt or bitbang.

Quote
EDIT: Forgot to mention, last night installed Laz on the Pi, and made the project from the Wiki, got it to build and run.  All I get is a blank form.  Not sure if I need to set up the hardware to 'drive' that, but should get to it sometime today.

In that case post your code so that we can take a look at it (having to be careful here since I don't currently have an RPi set up).

ALWAYS be ready to post your code when complaining about a non-obvious problem.

Quote
Laz is pretty clunky on the Pi (Pi 4 B (4 cores/1.5GHz) with 8 GB of ram).

Shouldn't be. Are you using a direct keyboard/video connection or are you doing something like tunneling X11 over SSH?

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 04:33:29 pm
I'll complete the h/w setup before coming back - and I'll open a new thread if it comes to it.

I do notice, that although the code runs, during compilation there are crtbegin.o and crtend.o not found errors.  Surprised that it linked... FPC install error?



Clunkiness is just v. my Mac (i7 4 HT cores, 3.4 GHz).  And yes I have a mouse/KB on the Pi (the Rasp foundation KB is pretty bad in itself, the mouse is good).

And the general clunky feeling of Linux desktops generally.

Further, I made the error of buying a 1080 p monitor for the project to save money.  Should have gone 4K.

(I'm also VNCing in from the Mac and that is borderline unworkable for scrolling around code...)
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 04:58:33 pm
Ignore the crtbegin/crtend error, it's one of a couple of benign linker errors.

Normally VNC performs a bit better than X11-over-SSH, because of the implicit buffering/caching... I've seen a couple of apps behaving /very/ badly with remote X11 due AIUI to input device polling issues.

However, that might depend on whether VNC is looking at the system's root window, or is set up to have a dedicated session. In the former case it effectively has to scrape the X11 buffer of the root (GUI console) session, while in the latter case it implements an X11 server for client apps (i.e. Lazarus, the desktop environment etc.) which it then sends over the LAN using its own protocol.

MarkMLl


Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 05:20:25 pm
@ojzOr well your code compiles ... :)

But there was an error in there - a comma instead of a semicolon in GVL.pas in the code you sent w/o further units below.

Testing me, eh?

Code: Pascal  [Select][+][-]
  1. implementation
  2. uses
  3.         IO_GPIO,
  4.  

edit:
Then tried your test code (main) which was full of errors, but managed to fix those.

Runs (and quits immediately) - I guess because I haven't wired it up yet... not sure why you're testing on GPIO 20, oh, well, I should be able to sort it out from here....
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 19, 2021, 06:24:23 pm
@ojzOr well your code compiles ... :)

But there was an error in there - a comma instead of a semicolon in GVL.pas in the code you sent w/o further units below.

Testing me, eh?

Code: Pascal  [Select][+][-]
  1. implementation
  2. uses
  3.         IO_GPIO,
  4.  

edit:
Then tried your test code (main) which was full of errors, but managed to fix those.

Runs (and quits immediately) - I guess because I haven't wired it up yet... not sure why you're testing on GPIO 20, oh, well, I should be able to sort it out from here....

Oh yeah the units. I had to delete some other IO_ units, i had SPI "drivers" for some mcp's (adc & dac) also declared in the GVL unit.

The code embedded was just a generic example how i use it. You have to declare the pins in the iolist. The pin 20 was just a random number i picked when writing the post.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 06:28:25 pm
Quote
Oh yeah the units. I had to delete some other IO_ units, i had SPI "drivers" for some mcp's (adc & dac) also declared in the GVL unit.

The code embedded was just a generic example how i use it. You have to declare the pins in the iolist. The pin 20 was just a random number i picked when writing the post.

Ok!  If you have SPI code, please don't be shy.  My laziness is boundless!

I notice 7 others have downloaded the .zip file you posted ... I guess laziness is fun for everyone!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 07:54:22 pm
First Success.  Using ojz0r (just realized that was a 0) 's code, managed to read an input and turn on a LED when the button was pushed.
(Not using Laz, using Geany.  Less fuss).

Code: Pascal  [Select][+][-]
  1. program testGVL(input, output);
  2. (* {mode objfpc}{$H+} *)
  3.  
  4. uses
  5.         GVL, IO_GPIO, sysutils;
  6.        
  7. const
  8.         SecPerDay = 86400;
  9.        
  10. var
  11.         i:longword=0;
  12.         make:boolean=false;
  13.         breaker: boolean = false;
  14.         time : TDateTime;
  15.         statechange: boolean;
  16.        
  17.  
  18. begin
  19.         time := now;
  20.         repeat                          // Loop
  21.         GVL.readInput();               // Read the inputs defined in iolist.pas
  22.         StateChange := false;
  23.  
  24.         if (not make) and (GVL.GPIO[17]) then            // Use GPIO 17
  25.         begin
  26.                 GVL.GPIO[22] := false;   // Set GPIO 18
  27.                 writeln ('up');
  28.                 make := true;
  29.                 breaker := false;
  30.                 statechange := true;
  31.         end;
  32.         if (not breaker) and (not GVL.GPIO[17]) then
  33.         begin
  34.                 writeln ('down');
  35.                 GVL.GPIO[22] :=true;
  36.                 breaker := true;
  37.                 make := false;
  38.                 statechange := true;
  39.                        
  40.         end;
  41.  
  42.         if statechange then
  43.                 begin
  44.                         GVL.setOutput();               // Set the output state of GPIO's defined in iolist.pas
  45.                         inc(i);
  46.                 end;
  47.         sleep(50);
  48.  
  49.         until ((now - time) * SecPerDay) > 10;    // Escape loop
  50.  
  51.         IO_GPIO.unexportGPIO();             // Unexport/free the GPIO from /sys upon program termination
  52.         writeln(i);
  53. end.
  54.  
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r on February 19, 2021, 08:10:37 pm
Well the SPI part is also based on the wiki example, allthough i could not get it to work at first so i had to do alot of work arounds.
The IO_MCPxxxx units are not so generic since i have hard coded the SPI request for each types control registers.
Note that (atleast) the RPi Zero only have two chip select pins, be careful not to get that confused or weird stuff can happen. They are defined in the constants part.
The chips are MCP3208 (8x 12-bit ADC) and MCP4922 (2x 12-bit DAC).

I use the SPI I/O the same way as the GPIO: Read at beginning of cycle and write at the end.
Code: Pascal  [Select][+][-]
  1. GVL.readInputs();
  2.  
  3. GVL.aoCH[0] := GVL.aiCH[0];
  4.  
  5. GVL.setOutputs();
  6.  

One weird thing i had when terminating the program was that the analog output would assume a seemingly random value.
To remedy that i added a "GVL.aoCH[n] := 0;" (followed by setOutputs procedure) right before the "end." outside the main loop.

Again i suspect that the code continues the same newbie mistakes as the last attachment.

I notice 7 others have downloaded the .zip file you posted ... I guess laziness is fun for everyone!

Thats probably curiosity.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 08:28:23 pm
Thanks ojz0r!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 19, 2021, 09:52:47 pm
Over the last few months I've been playing with a CH341 board as discussed at https://hackaday.com/2018/02/21/linux-adds-ch341-gpio/ I found that I had to tweak the module/driver slightly in order to get predictable kernel-generated names, but after that it behaved very much as would be expected on an RPi. I was using GPIO access via /sys, which is the "old" kernel standard, there's also a "new" kernel standard interface via /dev/gpiochip* which I've not yet played with, and the RPi-specific one via /dev/mem which I've /definitely/ not played with https://embeddedbits.org/new-linux-kernel-gpio-user-space-interface/

The "new-style" (kernel 4.8 and newer) API appears to work- at least with a CH341 attached to a PC- without changes to the module/driver. The /dev/gpiochipX device is still root:root, I don't know whether there's a way to hotplug it into e.g. a gpio group to which users could be added.

I've not investigated the API yet, but looking at the source of gpiomon suggests that it polls the device rather than using something like FAM to request that it be advised promptly by the kernel when something changes. Frankly I feel it's a bit /meh/...

Somewhat later: there's a Java bug from 2015 which relates to the fact that creation of directories in /sys/class/gpiochip* isn't handled reliably by FAM, but that doesn't say anything about whether gpio*/value updates are detected... I suspect not but I might be tempted to investigate further.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 19, 2021, 10:57:15 pm
@Mark,

I'll be looking at the /dev/gpio_____ methods tomorrow.  Glad for now that I have ojz0r's code compiled and running.

Not much for me to do now ... I'm waiting for the GPS and Accel/Gyro to show up.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 10:06:52 am
I'll be looking at the /dev/gpio_____ methods tomorrow.  Glad for now that I have ojz0r's code compiled and running.

That might need a Pascal binding to libgpiod and I'm not sure such a thing exists yet. I might have a chance to take a look over the weekend, I've had it pencilled in for a while.

The API does have a "wait for change with timeout" function and I'd expect that to be far more responsive than going through /sys/class/gpio. Assuming that your RPi has kernel >= 4.8, what is the user:group ownership of your /dev/gpiochip* ?

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 02:47:08 pm
Quote
Assuming that your RPi has kernel >= 4.8, what is the user:group ownership of your /dev/gpiochip* ?

Code: Text  [Select][+][-]
  1. pi@raspberrypi:/dev $ uname -r
  2. 5.10.11-v7l+
  3. pi@raspberrypi:/dev $ ls -al | grep gpio
  4. crw-rw----   1 root gpio    254,   0 Feb 17 20:46 gpiochip0
  5. crw-rw----   1 root gpio    254,   1 Feb 17 20:46 gpiochip1
  6. crw-rw----   1 root gpio    246,   0 Feb 17 20:46 gpiomem
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 03:06:19 pm
Quote
Assuming that your RPi has kernel >= 4.8, what is the user:group ownership of your /dev/gpiochip* ?

Code: Text  [Select][+][-]
  1. pi@raspberrypi:/dev $ uname -r
  2. 5.10.11-v7l+
  3. pi@raspberrypi:/dev $ ls -al | grep gpio
  4. crw-rw----   1 root gpio    254,   0 Feb 17 20:46 gpiochip0
  5. crw-rw----   1 root gpio    254,   1 Feb 17 20:46 gpiochip1
  6. crw-rw----   1 root gpio    246,   0 Feb 17 20:46 gpiomem

Thanks for that, I suspected that the RPi people would have taken the trouble to make that (relatively) accessible. Don't try using it yet though, I don't think there's a Pascal binding to libgpiod or a unit for direct access to the kernel: stick to /sys/class/gpio for the moment.

My development RPi uses the classic hack of an RPi kernel with standard Debian on top, but over the last few months the WiFi has stopped working for reasons that nobody seems to understand. Time for a "Delete all and insert", but I'll probably stick to Raspbian (or whatever it's called these days) since I don't have a user insisting on having three as desktop systems.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 03:16:45 pm
Quote
I'll probably stick to Raspbian (or whatever it's called these days)

They call it "Raspberry Pi OS".

https://www.raspberrypi.org/software/ (https://www.raspberrypi.org/software/)
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 07:39:04 pm
Quote
And my major use for Ada is using it to point out that when the DoD was looking for a language base they didn't seriously consider Lisp, although I've seen other people revisiting it comparatively recently and being impressed https://www.revk.uk/2017/11/ada.html

I just installed Ada on the Pi and tested it out.

DL, install, write a program (HellWorld), make ... a few minutes.

It used to take our 80186 cross compiler on the VAX 24 hours to compile and link about 5000 lines of code...

... astounding ...
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 08:05:52 pm
It used to take our 80186 cross compiler on the VAX 24 hours to compile and link about 5000 lines of code...

On the one hand, it's reasonable to assume that an RPi is more powerful- at least for single-user stuff- than a VAX.

On the other hand, it's reasonable to assume that some of the paranoid checks that were in late-80s/early-90s Ada might have been omitted. There's certainly a lot of the workbench stuff that has been.

The gripping hand is that there's probably also been a lot of changes in compiler technology, so even if the platform and facilities were identical speed might still be substantially improved. But we don't know for certain.

MarkMLl

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 09:13:37 pm
Two labs began Ada at about the same time.  Each chose a different compiler vendor.

Our lab had to meet US military s/w standards for avionics, they had to meet commercial.  (The US military generally uses commercial standards for s/w these days).  We were at similar criticality (about DO-160B level C).

Both had to meet divisional standards for s/w (which was a melding of both to a large degree).

Yes, the compiler was full compliance and that was a big part of the slowness.  Obviously we would avoid full builds as much as possible.
Quote
it's reasonable to assume that an RPi is more powerful- at least for single-user stuff- than a VAX.
But yes, a 4 core Pi at 1.5GHz could host many virtual VAX-785's (16 MHz IIRC) and 16 MB of RAM...

https://www.linkedin.com/pulse/vaxcluster-raspberry-pi-wilm-boerhout

The other lab's compiler seemed much faster though...

another:
https://www.askwoody.com/2020/ibm-system-370-on-a-raspberry-pi/

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 09:32:09 pm
Two labs began Ada at about the same time.  Each chose a different compiler vendor.

Our lab had to meet US military s/w standards for avionics, they had to meet commercial.  (The US military generally uses commercial standards for s/w these days).  We were at similar criticality (about DO-160B level C).

Both had to meet divisional standards for s/w (which was a melding of both to a large degree).

Yes, the compiler was full compliance and that was a big part of the slowness.  Obviously we would avoid full builds as much as possible.

I could tell you were an ex-Ada man. You're one of the minority who knows how to spell it...

I seem to remember discussing it with a few people during my GM days in Devon, but I can't remember how many of those converted into sales (most customers went direct to Alsys). I do however recall that we sold a copy of Logitech Modula-2 on a QIC cartridge for a VAX... it's an extreme minority who remembers Logitech as a compiler supplier.

Quote
Quote
it's reasonable to assume that an RPi is more powerful- at least for single-user stuff- than a VAX.
But yes, a 4 core Pi at 1.5GHz could host many virtual VAX-785's (16 MHz IIRC) and 16 MB of RAM...

https://www.linkedin.com/pulse/vaxcluster-raspberry-pi-wilm-boerhout

The other lab's compiler seemed much faster though...

another:
https://www.askwoody.com/2020/ibm-system-370-on-a-raspberry-pi/

Yes. There's stuff in the FPC-distributed variant of Lnet specifically to support the x2741 terminal emulator that I use to talk to a VM/CMS guest system, although that terminal emulator's strength is actually APL.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 09:57:24 pm
Revisiting the empty Tform ..... (see attached screen grab).

Main:
Code: Pascal  [Select][+][-]
  1.                                                                                                                          program io_test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Interfaces, // this includes the LCL widgetset
  10.   Forms, Unit1
  11.   { you can add units after this };
  12.  
  13. {$R *.res}
  14.  
  15. begin
  16.   Application.Initialize;
  17.   Application.CreateForm(TForm1, Form1);
  18.   Application.Run;
  19. end.

Unit
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {Demo application for GPIO on Raspberry Pi}
  4. {Inspired by the Python input/output demo application by Gareth Halfacree}
  5. {written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
  6.  
  7. {This application reads the status of a push-button}
  8.  
  9. {$mode objfpc}{$H+}
  10.  
  11. interface
  12.  
  13. uses
  14.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  15.   ButtonPanel, Unix, BaseUnix;
  16.  
  17. type
  18.  
  19.   { TForm1 }
  20.  
  21.   TForm1 = class(TForm)
  22.     ApplicationProperties1: TApplicationProperties;
  23.     GPIO18CheckBox: TCheckBox;
  24.     LogMemo: TMemo;
  25.     procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
  26.     procedure FormActivate(Sender: TObject);
  27.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  28.   private
  29.     { private declarations }
  30.   public
  31.     { public declarations }
  32.   end;
  33.  
  34. const
  35.   PIN_18: PChar = '18';
  36.   IN_DIRECTION: PChar = 'in';
  37.  
  38. var
  39.   Form1: TForm1;
  40.   gReturnCode: longint; {stores the result of the IO operation}
  41.  
  42. implementation
  43.  
  44. {$R *.lfm}
  45.  
  46. { TForm1 }
  47.  
  48. procedure TForm1.FormActivate(Sender: TObject);
  49. var
  50.   fileDesc: integer;
  51. begin
  52.   { Prepare SoC pin 18 (pin 12 on GPIO port) for access: }
  53.   try
  54.     fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
  55.     gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
  56.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  57.   finally
  58.     gReturnCode := fpclose(fileDesc);
  59.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  60.   end;
  61.   { Set SoC pin 18 as input: }
  62.   try
  63.     fileDesc := fpopen('/sys/class/gpio/gpio18/direction', O_WrOnly);
  64.     gReturnCode := fpwrite(fileDesc, IN_DIRECTION[0], 2);
  65.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  66.   finally
  67.     gReturnCode := fpclose(fileDesc);
  68.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  69.   end;
  70. end;
  71.  
  72. procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
  73. var
  74.   fileDesc: integer;
  75.   buttonStatus: string[1] = '1';
  76. begin
  77.   try
  78.     { Open SoC pin 18 (pin 12 on GPIO port) in read-only mode: }
  79.     fileDesc := fpopen('/sys/class/gpio/gpio18/value', O_RdOnly);
  80.     if fileDesc > 0 then
  81.     begin
  82.       { Read status of this pin (0: button pressed, 1: button released): }
  83.       gReturnCode := fpread(fileDesc, buttonStatus[1], 1);
  84.       LogMemo.Lines.Add(IntToStr(gReturnCode) + ': ' + buttonStatus);
  85.       LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
  86.       if buttonStatus = '0' then
  87.         GPIO18CheckBox.Checked := true
  88.       else
  89.         GPIO18CheckBox.Checked := false;
  90.     end;
  91.   finally
  92.     { Close SoC pin 18 (pin 12 on GPIO port) }
  93.     gReturnCode := fpclose(fileDesc);
  94.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  95.     LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
  96.   end;
  97. end;
  98.  
  99. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  100. var
  101.   fileDesc: integer;
  102. begin
  103.   { Free SoC pin 18: }
  104.   try
  105.     fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
  106.     gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
  107.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  108.   finally
  109.     gReturnCode := fpclose(fileDesc);
  110.     LogMemo.Lines.Add(IntToStr(gReturnCode));
  111.   end;
  112. end;
  113.  
  114. end.

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 10:30:35 pm
Quote
I could tell you were an ex-Ada man. You're one of the minority who knows how to spell it...

Well, I took a class at work (about 4 days, the instructor brought along a UNIX system with about 10 terminals - UNIX was not known to us much.  We were all assembler / FORTRAN / Pascal types (and most not even Pascal)).  2 people per terminal (teams).  I was paired with a Belgian engineer who though HOL's were an abomination to mankind.

But I never wrote a line of production code in Ada - as I mentioned earlier - my contribution was a section in assembler to the system that was 98% in Ada 83.  I had moved to marketing by then and didn't want to waste time learning how to make it work in Ada and I wasn't confident in the timing issues (I was allocated 2ms per 40ms on a machine that had IIRC an 8 MHz clock).  So took the shortcut and banged it out in assembler and shaved weeks off the schedule...  :P

I remember a very experienced and highly respected engineer say "Wow.  This record construct could be really useful!"
( I don't recall her ever doing anything other than assembler before that - HP-2100 ...)

A few years ago, I requested here, that FPC be modified to allow undeclared counter/index vars in procedures and functions as in Ada.  People beat the crap out of me - you may have been one of them!  Still seems like a good idea to me!

Quote

I do however recall that we sold a copy of Logitech Modula-2 on a QIC cartridge for a VAX... it's an extreme minority who remembers Logitech as a compiler supplier.

You're right.  Never thought of them at all like that.

I did write some Modula-2 (Borland) back OUAT ... I seem to recall it was a university class for an easy A.  (I never went to class so I think I hit a B- on that...).  In those (DOS) days it was pretty tedious IIRC as one had to edit the unit interface file separately from the implementation.  So main, units (interface), units (implementation).  That was a loooong time ago though.  I might have preferred it over Pascal if editing wasn't so tedious.  Then TP 4 came out with Units and - wow! What an improvement.

I believe, had Wirth simply extended Pascal with concepts from Modula-2, that Ada could have begun there...

I do seem to recall buying stuff from Logitech and getting 'bonus packs' of s/w of all sorts...

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 10:33:47 pm
Revisiting the empty Tform ..... (see attached screen grab).

Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 10:56:18 pm
I remember a very experienced and highly respected programmer say "Wow.  This record construct could be really useful!"
( I don't recall her ever doing anything other than assembler before that - HP-2100 ...)

I've seen "systems programmers"- basically glorified operators- boggled by assembler. Until an older colleague pulled a reference card out of her drawer.

Quote
A few years ago, I requested here, that FPC be modified to allow undeclared counter/index vars in procedures and functions as in Ada.  People beat the crap out of me - you may have been one of them!  Still seems like a good idea to me!

Probably not me. (a) I've only been using the forum for a year, before that I used the mailing lists. (b) While I don't like undeclared variables, I believe that declaring the index variable inside a for..do would be an advance since the current situation where the index value is undefined on loop termination (unless by break) is most unpleasant.

Quote
I did write some Modula-2 (Borland) back OUAT ... I seem to recall it was a university class for an easy A.  (I never went to class so I think I hit a B- on that...).  In those (DOS) days it was pretty tedious IIRC as one had to edit the unit interface file separately from the implementation.  So main, units (interface), units (implementation).  That was a loooong time ago though.  I might have preferred it over Pascal if editing wasn't so tedious.  Then TP 4 came out with Units and - wow! What an improvement.

Borland Modula-2 became TopSpeed. There were various "goings on" that I can't discuss because if I get the details wrong they'd be libellous.

Having separate definition files in M2 has the advantage that (a) they can be marked as read-only to all but senior staff and (b) they can be written as a "statement of fact" with no indication of implementation details... there's a legal storm brewing because C (etc.) specifically doesn't have that separation.

Quote
I believe, had Wirth simply extended Pascal with concepts from Modula-2, that Ada could have begun there...

Remember that Wirth was on one of the Ada teams or on the approvals committee, and eyebrows were raised since he was the only one being paid.

There was a great deal of dodginess that led to Pascal, but basically I believe that Wirth rushed it out with the specific intention of breaking compatibility with ALGOL-60. It was completely unforgivable that Pascal had the "dangling else" problem when that was fixed in ALGOL-68, Wirth obviously fixed that in Modula-2 but Pascal was a rush job... look at Wirth's early coding style and you'd see why.

Quote
I do seem to recall buying stuff from Logitech and getting 'bonus packs' of s/w of all sorts...

Although the various addon packs sounds more like a TopSpeed thing, and they were of decidedly mixed quality. Logitech had a Mouse Programmer's Toolkit which effectively gave you a large chunk of a Windows-like OS as source, and they had a damn good debugger which was subsequently spun off as Multiscope.

They also had their own share of scandals which I can't discuss. For a while I was their de-facto UK tech support.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 11:17:04 pm
Quote
While I don't like undeclared variables, I believe that declaring the index variable inside a for..do would be an advance since the current situation where the index value is undefined on loop termination (unless by break) is most unpleasant.

I seem to recall that everywhere (from class to code manuals) it was pretty clearly pointed out that the value of the index variable at the end of a for loop was undefined - so don't assume anything.  Further of course, if it compiles on one system with a behaviour it may do something else on another... in particular if the compiler writer is doing an efficient job by using registers for the index...

Quote
Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.
I'll pack everything in a .zip asap - need to separate the project from all sorts of other files first.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 20, 2021, 11:31:34 pm
Quote
Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.
I'll pack everything in a .zip asap - need to separate the project from all sorts of other files first.

Background: the main unit is the .lpr file. At the bottom of that you can see where the resources in the .lfm file(s) are parsed to create components of various types on the form(s). It's likely that the project you're using has lost a button or something comparable.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 20, 2021, 11:44:00 pm
Quote
Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.

attached

Or find at: https://www.dropbox.com/s/ymtk3389e1jtr4g/unit1.pas.tar
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 11:38:22 am
Rule 1: don't believe everything you read on the Internet, particularly if somebody says "this is a working example" :-)

I think your example was derived from https://wiki.freepascal.org/Raspberry_Pi_:_BerryClip but it had been copied around by various people and in the process had lost the contents of its form. That not only meant that there was nothing to display any output but- crucially- it meant that noting was generating events and passing them to the event handlers in your program.

I've fixed up your example to the extent that you can single-step through it and see what's going on, I've not attempted to debug it against my own PC-based GPIO since I don't want to change your code more than necessary.

What I have done is add several calls to Application.ProcessMessages (colloquially referred to as APM) to make sure that output to the memo on the form appears as early as possible.

I've resisted the temptation of starting other methodical fixups since once one starts...

Use Lazarus to open the .lpi, compile it and set breakpoints near the start of TForm1.FormActivate() and TForm1.ApplicationProperties1Idle(), then step through line-by line paying particular attention to the result of opening or accessing your /sys/class/gpio pseudo-files.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 21, 2021, 01:51:51 pm
The code I posted is that from https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi - the first two code blocks beginning at:
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Switching_a_device_via_the_GPIO_port

The rest in the tarball was generated by the compiler.

Thanks for the patch.  As soon as the coffee kicks in I'll get to it!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 01:55:55 pm
The code I posted is that from https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi - the first two code blocks beginning at:
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Switching_a_device_via_the_GPIO_port

Yes, and that didn't include a form so was worthless. Wiki author's fault, not yours.

See the link I gave you which is rather more comprehensive.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 21, 2021, 02:05:01 pm
@Mark,

I believe you mentioned Devon earlier - England?  Is that where you are now?

Closest I got to Devon was Yeovil...
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 02:21:05 pm
@Mark,

I believe you mentioned Devon earlier - England?  Is that where you are now?

Closest I got to Devon was Yeovil...

Currently in Sussex which is the other side of the country. I mentioned Devon because at one time there was an importer of compilers etc. in a small town there, purveyors of quality development tools and libraries to just about everybody basically but the business wilted (at least in part because it supplied tools from all suppliers impartially, and they started looking for exclusive distributors).

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 21, 2021, 02:29:48 pm
OK - running.  Need to make some wiring changes to test that.

WARNING: Rant follows.

But, this illustrates exactly what I meant earlier about not wrapping a hardware demo in all the trappings of GUI.

Discovery 1.  For this to work, the main program had be .lpi, not .pas.  (How would I have known that from the Wiki page).

2. I have no idea how the form got generated.  From the source code?  From the form file?

3. What happened to the main program?

Ah well,  I'll plodge through it ...

Thanks.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 02:50:02 pm
OK - running.  Need to make some wiring changes to test that.

WARNING: Rant follows.

But, this illustrates exactly what I meant earlier about not wrapping a hardware demo in all the trappings of GUI.

If you don't want the GUI stuff don't use it. As I've already said, there are lots of advantages to using Lazarus for the debugger etc.

Quote
Discovery 1.  For this to work, the main program had be .lpi, not .pas.  (How would I have known that from the Wiki page).

No, the main program is the .lpr. The .lpi is the project information file that tells the development environment what units, forms etc. are in the overall scope of the project.

Quote
2. I have no idea how the form got generated.  From the source code?  From the form file?

I answered that a couple of days before you asked.

Quote
3. What happened to the main program?

Ah well,  I'll plodge through it ...

Thanks.

Stop complaining and fix the bugs.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 21, 2021, 03:28:27 pm
Well.  It works.

And it's slow.

And it misses button presses.

I'll start stripping it down...

Thanks.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 03:42:53 pm
Well.  It works.

And it's slow.

And it misses button presses.

I'll start stripping it down...

My first suspect would be that all the processing is hung off an application idle event. I've not used it but I think that that's supposed to be the lowest priority possible, try putting a timer with a 10mSec repetition on it, or possibly an IdleTimer.

I'm currently trying to look at the file alteration monitor stuff to see if that's operational inside /sys/class/gpio but I'm not very optimistic. The new (kernel >=4.8) API appears to have its own equivalent.

Slightly later: I'm pretty sure the FAM stuff doesn't work in that context, so basically pins/bits have to be polled. I note that the driver for the CH341 chip talks about its being possible to put an interrupt on one pin at a time, but I haven't a clue how that translates to the user-accessible API.

I've not investigated the speed, but I'd be disappointed if it couldn't handle of the order of 100 events a second... https://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/ suggests somewhat better.

However as I've said before Linux isn't an RTOS, and this is reporting level rather than edge, so unless you're using an interlocked/acknowledged protocol (i.e. a bit like ye olde Centronics interface) you can expect dropped inputs and erratically-timed outputs on occasion.

I'll try to put a bit of time into the new GPIO API over the next few days.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 21, 2021, 04:11:31 pm
Is there a description of that API anywhere?  I've searched and come up dry.

Ah, you slipped in an edit.  Well, two can play at that!

I look forward to your API!

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...
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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.  
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 21, 2021, 09:05:57 pm
I'd be cautious about the performance of all of those fpopen() fpclose() syscalls.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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?
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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...)

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: DonAlfredo on February 22, 2021, 05:39:10 am
Quote
Don't need no stinkin' OS.
https://ultibo.org/
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: ojz0r 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: PascalDragon 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 (https://github.com/bztsrc) (Rpi3) or this (https://github.com/isometimes/rpi4-osdev) (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.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl 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
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast 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!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 22, 2021, 03:14:58 pm
Quote
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

Nice!  Funny that the question is "what is the correct way" and yet the solution is most likely the least correct way!  (I haven't looked yet...).  That's great for me!

Quote

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.


If it's robust to my solution, that's all I need.  I'll put it up (if I go that way) with specificity warnings.

Quote
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.

Thanks.  Not sure I can get to it before Friday.  Maybe tomorrow morning.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 22, 2021, 04:34:22 pm
Nice!  Funny that the question is "what is the correct way" and yet the solution is most likely the least correct way!  (I haven't looked yet...).  That's great for me!

Well, it can be semantically valid to ask the correct way to operate something even if the result of operating it is abhorrent.

At the risk of being inflammatory, "what is the correct way to operate the napalm dispenser if the enemy fires on the field hospital?". :-/

I anticipate that the gpiod API will operate substantially faster than the /sys/class/gpio one, but relying on "good enough" thoughput is no alternative to a properly designed physical interface.

Here's a minimal gpiod example, it checks the basic calling conventions but doesn't go much further than that:

Code: Pascal  [Select][+][-]
  1. (* A numbered list of ports is prepared at startup, or any time this is called
  2.   and no port is open. The list is returned as a StringList, which should be
  3.   freed by the caller. Entries in the StringList comprise a GpioChip name,
  4.   optionally followed by a space and a device name in parentheses.
  5. *)
  6. FUNCTION ListGpioChardevPorts(currentPort: THandle= InvalidGpioHandle): TStringList;
  7.  
  8. var
  9.   searchRec: TSearchRec;
  10.   gpiochip, gpioname, gpiolabel: string;
  11.   pChip: pgpiod_chip;
  12.  
  13. begin
  14.   if currentPort <> InvalidGpioHandle then
  15.     exit(nil);
  16.   if not DirectoryExists('/dev') then
  17.     exit(nil);
  18.   result := TStringList.Create;
  19.   try
  20.     result.Sorted := true;
  21.     result.Duplicates := dupIgnore;
  22.     IF FindFirst('/dev/gpiochip*', faAnyFile, searchRec) = 0 THEN
  23.       REPEAT
  24.         gpiochip := '/dev/' + searchRec.Name;
  25. //        if not Gpiod.gpiod_is_gpiochip_device(PChar(gpiochip)) then
  26. //          continue;
  27.         pChip := Gpiod.gpiod_chip_open(PChar(gpiochip));
  28.         if pChip = nil then
  29.           continue;
  30.         try
  31.           gpioname := StrPas(Gpiod.gpiod_chip_name(pChip)); (* Same as searchRec.Name? *)
  32.           gpiolabel := StrPas(Gpiod.gpiod_chip_label(pChip));
  33.           gpiochip := searchrec.name;
  34.           if gpioLabel <> '' then
  35.             gpiochip += ' (' { + 'gpiod, ' } + gpioLabel + ')';
  36.           result.Add(gpiochip)
  37.         finally
  38.           Gpiod.gpiod_chip_close(pChip)
  39.         end
  40.       UNTIL FindNext(searchRec) <> 0;
  41.     FindClose(searchRec)
  42.   finally
  43.     if result.Count = 0 then
  44.       FreeAndNil(result)
  45.   end
  46. end { ListGpioChardevPorts } ;
  47.  

That should work identically for either the gpiod or the gpiod_dynamic unit, the "magic" being that the explicit Gpiod. is required.

There looks to be a bit of variability between versions of the library, for example gpiod_is_gpiochip_device() is declared in the header files shipped by the kernel but not in the binary library from Debian (and Raspbian is a Debian derivative). If there's a mismatch of that type the static linkage will fail at build time, while I'd expect the dynamic linkage to throw an exception at runtime.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 22, 2021, 10:32:36 pm

At the risk of being inflammatory, "what is the correct way to operate the napalm dispenser ..."


Operating that correctly would indeed be inflammatory... 8)

I'll look into the rest tomorrow or Friday.  Herself believes I have "communal chores" to catch up on... and if she believes it, well...

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 22, 2021, 11:07:13 pm
I'll look into the rest tomorrow or Friday.  Herself believes I have "communal chores" to catch up on... and if she believes it, well...

So far I'm happy with the interface units. What I'm not happy about is that there's information in /sys/class/gpio that doesn't have a counterpart in the gpiod API... you'll probably not see it on an RPi but in brief the gpiod API always numbers I/O lines starting at zero while /sys/class/gpio allows you to deduce whether there's inaccessible bits which means that the first accessible bit should have some higher number.

The CH341 board I'm using has two possible drivers: i2c-ch431 (eight GPIO lines) and spi-ch431 (two GPIO lines). If I use the /sys/class/gpio interface I can work out the physical correspondence, if I use gpiod I can't... I might possibly be able to force line names in the module/driver but I'm not at all confident.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 22, 2021, 11:40:06 pm
Noted.

And it looks like housework is good for me as my mind wanders...  While I have to confirm the behaviour, I recalled that the gyro/accel module can be configured to output the data at a desired sampling rate.  It has an OCXO, so the sampling should be reasonably accurate.  Can set rates well in excess of 1 Khz.  Each sample 'frame' would be about 20 bytes or so... I assume that Linux will buffer serial data coming in ???  I can hit it pretty often to 'drain' and process...

I have to see how well I can use the GPS to 'frame' the timing of the gyro/accel - but for that I would have liked to use the 1PPS pin - that no longer seems viable.  I was going to set the GPS to 10 Hz frames, but it can be up to 18 (such a messy number hopefully I can set it to 16 Hz).

Edit:
As part of this, I suppose I can use my fav:  "now" to do rough RT dispatching of tasks and "now" and GPS time to discipline some sort of local to the code soft clock and some sort of task to back fill time on recent accel/gyro frames.  The actuator part of this job will be relatively slow at about 40 - 100 Hz.  I think.  TBD.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 23, 2021, 01:13:54 am
Quote
Don't need no stinkin' OS.
https://ultibo.org/

Just visited that site and it looks very promising.  Thanks!!!!!

Edit: may be a dead group.     :'(

Edit: there is life there.  Registration turned out to be manual and I've received e-mail from them...

I'll look into it more towards the weekend.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: DonAlfredo on February 23, 2021, 05:59:08 am
Not dead I guess.
Last update 20 days ago : https://github.com/ultibohub/Core
Last update 8 days ago : https://github.com/ultibohub/Tools
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 23, 2021, 07:55:54 am
Noted.

And it looks like housework is good for me as my mind wanders...  While I have to confirm the behaviour, I recalled that the gyro/accel module can be configured to output the data at a desired sampling rate.  It has an OCXO, so the sampling should be reasonably accurate.  Can set rates well in excess of 1 Khz.  Each sample 'frame' would be about 20 bytes or so... I assume that Linux will buffer serial data coming in ???  I can hit it pretty often to 'drain' and process...

Surely you'll be using I2C or similar for that, not GPIO?

Quote
I have to see how well I can use the GPS to 'frame' the timing of the gyro/accel - but for that I would have liked to use the 1PPS pin - that no longer seems viable.  I was going to set the GPS to 10 Hz frames, but it can be up to 18 (such a messy number hopefully I can set it to 16 Hz).

Edit:
As part of this, I suppose I can use my fav:  "now" to do rough RT dispatching of tasks and "now" and GPS time to discipline some sort of local to the code soft clock and some sort of task to back fill time on recent accel/gyro frames.  The actuator part of this job will be relatively slow at about 40 - 100 Hz.  I think.  TBD.

PPS will /definitely/ need to trigger an interrupt, even on something like a Teensy: polling isn't sufficiently accurate.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 23, 2021, 01:35:32 pm
@MarkMLI,

Yes, I2C or the UART which are on the GPIO header.  Waiting on hardware from the US.  Seems to be trapped in NJ for some reason - maybe Canadian Customs has to be placated first. TBD.

PPS trailing edge interrupt would be fantastic.  Not sure if I can do this in Linux.  Possibly if I go the Ultibo route that DonAlfredo pointed out.

It's not clear to me yet that I actually need PPS.  But for sure that would be the most accurate time check possible if not for the app then for testing.  I may buy a USB sillyscope to check timing between my code and the GPS PPS signal - if the software can 'manage' time well enough, then the PPS won't be needed.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 23, 2021, 01:54:21 pm
PPS trailing edge interrupt would be fantastic.  Not sure if I can do this in Linux.  Possibly if I go the Ultibo route that DonAlfredo pointed out.

I don't think it's safe to assume you can do that without a kernel module, although the gpiod API has a monitor capability... which still might not get you better than 10 mSec resolution.

And in any event- again- LINUX IS NOT AN RTOS so you can never rely on its latency.

Quote
It's not clear to me yet that I actually need PPS.  But for sure that would be the most accurate time check possible if not for the app then for testing.  I may buy a USB sillyscope to check timing between my code and the GPS PPS signal - if the software can 'manage' time well enough, then the PPS won't be needed.

Remember that you'll find it difficult to get a calibration certificate for GPS, so "the most accurate time check possible" has to be treated cautiously. "The most accurate readily available" perhaps.

A Royal Navy ship (possibly a minesweeper) experimentally disconnected its GPS a few years ago, and found that its primary radar stopped working. A certain amount of paranoia is, IMO, justified.

Re. DSO: https://forum.lazarus.freepascal.org/index.php/topic,53058.msg392300.html#msg392300

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 23, 2021, 06:40:36 pm
Quote
Quote
PPS trailing edge interrupt would be fantastic.  Not sure if I can do this in Linux.  Possibly if I go the Ultibo route that DonAlfredo pointed out.

I don't think it's safe to assume you can do that without a kernel module, although the gpiod API has a monitor capability... which still might not get you better than 10 mSec resolution.

And in any event- again- LINUX IS NOT AN RTOS so you can never rely on its latency.

No need to repeat ... got it the first time.  I will, post integration, also try DonAlfredo's suggestion...

As to resolution, if as I believe, the gyro/accel module samples as described, then the integration of that data can take place in nearish realtime and can be soft aligned.  If they have a serial number or timestamp, even better (but I don't believe so).  IOW counting those frames will provide me a time reference at 1/frame_rate s.  I don't know offhand if there's a checksum, so reasonableness checking might be needed as well.

Quote
Quote
It's not clear to me yet that I actually need PPS.  But for sure that would be the most accurate time check possible if not for the app then for testing.  I may buy a USB sillyscope to check timing between my code and the GPS PPS signal - if the software can 'manage' time well enough, then the PPS won't be needed.

Remember that you'll find it difficult to get a calibration certificate for GPS, so "the most accurate time check possible" has to be treated cautiously. "The most accurate readily available" perhaps.

The PPS is the calibration.  These things are, even in the cheapest sensors, on the order of 100 ns or better compared to UTC (at the phase centre of the antenna - if you have cable from the antenna to the correlator front end, then account for propagation in the cable at about 2/3 the speed of light).  IAC I don't care about UTC - I do care about the period.  This necessitates an interrupt, obviously.

The first GPS I'm buying states about 40ns (IIRC).    1 usec period accuracy would be much more than accurate enough for my project.

Quote
A Royal Navy ship (possibly a minesweeper) experimentally disconnected its GPS a few years ago, and found that its primary radar stopped working. A certain amount of paranoia is, IMO, justified.

Shipboard systems (of which I have little experience) have been ever more integrated with what I call hodepodge.  (I'm probably being too cynical).  Shipboard radar systems often integrate GPS for a variety of functions from target indicator computations (velocity, course, etc.) but also to aid signal processing (clutter suppression I believe - don't quote me) as well as simple things like actual bearing v. relative bearing indications.

I'm surprised the radar system didn't have a fallback mode however.  Such in aviation is simply unacceptable for many systems (DO-178B/C level B or A [Boeing didn't heed that on the Max]) and even lesser level systems typically have some functionality when aiding data is not provided.

Quote

Re. DSO: https://forum.lazarus.freepascal.org/index.php/topic,53058.msg392300.html#msg392300

Very interesting.   Not sure why you posted that - if I get a silly scope I'll be running it off of a separate computer with the included s/w.
Haven't decided I'll need it yet.  You did remind me of a product I worked on in the late 80s/ early 90's with a TMS320C25 (or C40) however.

In the meantime since I appreciate everything you've written over the last while (very much!), I will reward you with a curse:
https://www.youtube.com/watch?v=d4EgbgTm0Bg (quaternions - which you may be familiar with... I've found some very nicely done C source code on GitHub that I'll translate to Pascal at some point in the not distant future ...).

https://github.com/MartinWeigel/Quaternion/blob/master/Quaternion.c
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 23, 2021, 07:21:06 pm
No need to repeat ... got it the first time.  I will, post integration, also try DonAlfredo's suggestion...

With respect to everybody concerned, I've looked only slightly at Ultibo and so far I don't recall seeing anything about a *guaranteed* interrupt latency.

Quote
As to resolution, if as I believe, the gyro/accel module samples as described, then the integration of that data can take place in nearish realtime and can be soft aligned.  If they have a serial number or timestamp, even better (but I don't believe so).  IOW counting those frames will provide me a time reference at 1/frame_rate s.  I don't know offhand if there's a checksum, so reasonableness checking might be needed as well.

Perhaps I should have put latency rather than resolution there: don't expect much better than 10 mSec from Linux.

Generally speaking most OSes these days are written to set up hardware transfers of a few Kb and to only have to service a single interrupt on completion. As a reminder that Linux is not an RTOS, it took quite a lot of cleaning up in the 2.5 era to get it good enough to drive MIDI.

Quote
The PPS is the calibration.  These things are, even in the cheapest sensors, on the order of 100 ns or better compared to UTC (at the phase centre of the antenna - if you have cable from the antenna to the correlator front end, then account for propagation in the cable at about 2/3 the speed of light).  IAC I don't care about UTC - I do care about the period.  This necessitates an interrupt, obviously.

The first GPS I'm buying states about 40ns (IIRC).    1 usec period accuracy would be much more than accurate enough for my project.

You misunderstand. Correct me it I'm wrong, but I don't believe that the DoD give out calibration certificates or guarantees of service level.

Quote
I'm surprised the radar system didn't have a fallback mode however.  Such in aviation is simply unacceptable for many systems (DO-178B/C level B or A [Boeing didn't heed that on the Max]) and even lesser level systems typically have some functionality when aiding data is not provided.

Fun fact: you might recall that a French plane was lost in the South Atlantic a few years ago, and they recovered the "black box" in the nick of time before its battery ran out. I read the report, and it appeared that the pilots- at least one of whom wasn't exactly the sharpest knife in the rack- had made absolutely no attempt to refer to GPS to deduce their altitude or rate of ascent/descent. And the report- which was of course French- didn't seem to think that was in any way out of the ordinary.

Quote
In the meantime since I appreciate everything you've written over the last while (very much!), I will reward you with a curse:
https://www.youtube.com/watch?v=d4EgbgTm0Bg (quaternions - which you may be familiar with... I've found some very nicely done C source code on GitHub that I'll translate to Pascal at some point in the not distant future ...).

https://github.com/MartinWeigel/Quaternion/blob/master/Quaternion.c

I'm familiar with them from BRL-CAD, where chunks of the UI are pretty much unusable unless you grok them.

Meanwhile, I'm still trying to sort out some aspects of the gpiod stuff, and am rebuilding my WPi to help out with that. It's the usual sort of Linux problem: sometimes you need to map from a named device in /dev to a more detailed description in /sys, and that can be tedious.

But so far the interface units I posted don't look too bad.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 23, 2021, 10:04:36 pm
Quote
With respect to everybody concerned, I've looked only slightly at Ultibo and so far I don't recall seeing anything about a *guaranteed* interrupt latency.

If it's as bare as claimed, and
if it allows the programmer to set a timer, and
if that timer can trigger an interrupt,
that the programmer can set the vector to point at his code,

then I would expect sub microsecond latency.  I'd prefer to code this part in assembler but not a killer if it isn't.  (And I'm not familiar with ARM assembly language and don't want to be unless pressed).  Ultibo does support inline assembler. 

Paired with that I'd want to know what other interrupts are being serviced, for what reason and if there is a priority scheme.  Can I get the highest priority interrupt?  I won't be in there that long.  Promise!

IAC it would appear to have far lower latency risk than Linux, which rumour has it is not an RTOS.  Not sure where I heard that.

Quote
You misunderstand. Correct me it I'm wrong, but I don't believe that the DoD give out calibration certificates or guarantees of service level.

You're quite correct.  They don't.  But it's irrelevant.

US DOD provide the clocks in orbit and monitor them on a four hour cycle against a ground based truth (the 4 hour policy may have changed over the years).  They are very accurate.  Beyond the signal leaving the satellite, the DOD's interest in the matter ends (other than for its government clients).  So first off we trust the US DOD on this.  (No point here in discussing 'what if's' on this IMO.)

Receiver manufacturers derive the 1 PPS (I've forgotten the exact method) in hardware, but it is not difficult to do and it is definitely easy to verify against standards at those labs that have them (depending on the accuracy required)).  It is derived from the signal but the s/w in the receiver has to gate it on once the receiver has sufficient signal from space [number of sats needed depends on the application - a ground station that is accurately surveyed could do with a single satellite, I believe; an aircraft would need 4].  The manufacturers declare in their spec how accurate their 1 PPS signal is for the operating conditions of the spec.  So you trust (and perhaps verify) the accuracy of the device as it is marketed.

Just re-reading the spec sheet for the first device coming in:
60 ns, 99% of the time. 
(This is marketed as "Professional grade". Not sure but seems to be everything that isn't consumer or automotive.  Certainly can't include commercial aviation.)

Further, a pin can be programmed to any rate between 10 MHz down to 4 seconds based on that.  With such I could set up an interrupt at whatever rate convenient to the project...

So we trust and perhaps verify.

Quote
I read the report, and it appeared that the pilots- at least one of whom wasn't exactly the sharpest knife in the rack- had made absolutely no attempt to refer to GPS to deduce their altitude or rate of ascent/descent. And the report- which was of course French- didn't seem to think that was in any way out of the ordinary.

GPS is not a source of altitude info, to begin with, in normal flight operations.  That particular A-340 almost certainly did not have a GPS with VNAV capability (it would be passing PVT to the INS of course).  There is no cockpit indication at all of altitude from GPS other than (possibly) diving into the FMS (to the INS).

Finally, IIRC, the crew merely had to cross check left and right sources and that should have been enough to have them at least suspect they were losing altitude quickly .... also IIRC the left side pitot/static system was the culprit (and there was an airworthiness directive open on that model that Air France hadn't gotten around to sorting out yet...)

Link to the report - je lis le français tres bien ....

Quote
Meanwhile, I'm still trying to sort out some aspects of the gpiod stuff, and am rebuilding my WPi to help out with that. It's the usual sort of Linux problem: sometimes you need to map from a named device in /dev to a more detailed description in /sys, and that can be tedious.

But so far the interface units I posted don't look too bad.

I'll wait until the weekend to get to that....
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 24, 2021, 10:47:12 pm

Very positive reply from the Ultibo team.

It is very clear that it will handle a high rate of interrupts (way beyond my needs) and that it is direct to my code (must play nice - haven't read the 'rules' but I assume one must handle it fast and reliably...)

Also clear that one can set code to run on a particular core and stick there - though I'm not sure that I'll require that or any particular sensitivity to which core is the running core.

So, what I will aim to do is:

- Program the GPS Timepulse pin to 1 KHz or higher (perhaps 4 Khz) to signal(v) processing cycles and be the time keeper.   Generate flags for lower rate processes as well.  This 'rate' will be extremely accurate (based on GPS time incl. 1 PPS - I assume the GPS receiver has an internal counter slaved to the 1PPS and hopefully that it re-calibrates v. 1 PPS over runtime...)  IAC that level of accuracy (sub 100ns) is not needed.  usec level accuracy is good enough... one issue is that this signal is 3V.  May need to step that up to 5V.

- The Ulbito library provides for queued UART i/o at speeds well in excess of my needs.  There may be a way to electrically sync the accels/gyros to the GPS.  TBD.

- I2C from the accel/gyros I bought maxes out at 400 Kb/s.  This should support 1 KHz sampling - depends how many bytes per frame...  The accel/gyro that supports SPI was out of stock.

I'll probably begin by reviewing MarkMLI's code and using it with current setup to see how far I can push it.

Key parts are still in the Fedex universe somewhere... other parts have trickled in at least.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 25, 2021, 11:29:57 am
Wrapping this up from my POV, after comparing GPIO handling on a PC and a Raspberry Pi, with particular emphasis on the (new) gpiod API.

On an RPi, the on-board GPIO lines are handled by code statically linked into the kernel, so it should be possible to rely on their naming order even in the absence of other "hints". That does not apply to a PC, or to any other target where GPIO support is loaded from a kernel module; in that case the device order will change depending on the order that kernel modules are loaded at boot and/or the order that GPIO devices are plugged in.

I can confirm that on an RPi, Raspbian ("Raspberry Pi OS") associates both on-board and USB-connected GPIO ports with group "gpio", while on a PC (Debian) the user will need root privilege to perform most operations. This might be an oversight or might be intentional, since a significant proportion of Linux PCs are operating as servers and there have already been reports of badly-configured hardware and software allowing access to critical system buses and devices.

Now to discuss the "hints".

The classic GPIO text-based API, which is used by almost all demos so far, puts entries in /sys/class/gpio where the names are related to the bus position. So on an RPi with internal GPIO devices one sees

gpiochip0  gpiochip100  gpiochip504

while on an RPi which also has a USB-connected CH341 board (plus kernel module) one sees

gpiochip0  gpiochip100  gpiochip496  gpiochip504

In this particular case it is the gpiochip496 device which is USB-connected, but assume that number will "wander" depending on the USB topology.

There will also be /dev/gpiochip* devices, but these are numbered sequentially:

gpiochip0  gpiochip1  gpiochip2  gpiochip3

If the gpiod package is installed, the gpiodetect command describes these as


# gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)
gpiochip1 [brcmvirt-gpio] (2 lines)
gpiochip2 [raspberrypi-exp-gpio] (8 lines)
gpiochip3 [i2c-ch341] (8 lines)


and this may be cross-referenced with what's in /sys/class/gpio:


# cat gpiochip0/label
pinctrl-bcm2835
# cat gpiochip100/label
brcmvirt-gpio
# cat gpiochip504/label
raspberrypi-exp-gpio
# cat gpiochip496/label
i2c-ch341


If multiple CH341 (or similar) cards were plugged in, it would be difficult to distinguish them. However for USB devices I think this is relevant:


# ls -ld /sys/class/gpio/gpiochip496/device/gpiochip*
drwxrwx--- 3 root gpio 0 Feb 25 09:41 gpiochip496/device/gpiochip3


Hence assuming that the labels associated with on-board GPIO devices are unique, I think it's possible to get sufficient "hints" to work out the disposition of devices that might "wander".

The reason that this is important is that the "new" gpiod API opens devices by device name (i.e. /dev/gpiochip3 etc.) and can then extract the label and the number of GPIO lines:

Code: Pascal  [Select][+][-]
  1.   chipHandle := Gpiod.gpiod_chip_open(PChar('/dev/gpiochip3');
  2.   if chipHandle = nil then
  3.     exit;
  4.   ngpio := Gpiod.gpiod_chip_num_lines(chipHandle);
  5.   chipLabel := StrPas(Gpiod.gpiod_chip_label(chipHandle));
  6.  

What it can't extract however is the base of the group of GPIO lines physically supported by the chip, and knowing that can be important if the lowest GPIO line on a device can vary. As a concrete example, the CH341 can be handled either as an I2C+GPIO device with 8x GPIO lines, or an SPI+GPIO device with only 2x GPIO lines... the *top* two, but despite the physical difference in both cases the GPIO lines are numbered from zero (0..7 or 0..1 respectively).

I think that covers most details, I suppose I ought to tack it into the wiki at some point.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 25, 2021, 01:58:05 pm
MarkMLI wrote:
Quote
Wrapping this up from my POV, after comparing GPIO handling on a PC and a Raspberry Pi, with particular emphasis on the (new) gpiod API.

By the weekend I may even understand enough of that (just rolled out of bed - haven't had enough coffee yet ...

Thanks.  I look forward to trying that out with the package you posted the other day.  Big day at work today, finalizing the 2020 books for tax time.. almost done - then I should have more time for this.  My components are still jammed up in NJ/FedEx. 

What I get for choosing the cheapest shipping option "FedEx mail".

I did purchase a 4K monitor which allegedly arrives today.  That should make working with Lazarus on the Pi a lot easier than the 1080p screen presently attached.

Cheers!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 25, 2021, 02:19:43 pm
Thanks.  I look forward to trying that out with the package you posted the other day.

I believe that the stuff I posted the other day is functionally OK. Cosmetically it's a bit of a mess since it's had the minimum TLC necessary to convert the .h to a .inc which my (unpublished) preprocessor can then use to generate static and dynamic .pas wrappers.

You might find that there's one or two functions which aren't in the library version that distreaux are currently shipping. This will obviously cause a link error if you're using static linkage, but a runtime error if you're using dynamic... hence e.g.

Code: Pascal  [Select][+][-]
  1. // Older versions of libgpiod e.g. as shipped with Debian "Buster" might not
  2. // support this entry point.
  3.  
  4.           try
  5.             x := Gpiod.gpiod_line_is_active_low(lineHandle)
  6.           except
  7.             x := false
  8.           end
  9.  

After coming across a number of places where this happened I changed the dynamic loading unit to have this in the two LoadRoutine() functions:

Code: Pascal  [Select][+][-]
  1.     raise DynamicModuleException.Create(FLastError)
  2.  

MarkMLl



MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 26, 2021, 02:30:37 pm
Quote
I believe that the stuff I posted the other day is functionally OK.

I guess I missed something along the road.  I'll look for the latest version.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 26, 2021, 02:38:30 pm
Quote
I believe that the stuff I posted the other day is functionally OK.

I guess I missed something along the road.  I'll look for the latest version.

Only been posted once. See #73 of this thread.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 27, 2021, 01:04:33 am

Quote
Only been posted once. See #73 of this thread.
Great - already DL'd - not unpacked yet.  Probably tomorrow.  I have a test target - an old GPS with a serial port.

Cheers,
Have a great weekend!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 27, 2021, 04:55:11 pm
Quote
  I have a test target - an old GPS with a serial port.

... which I can't use directly with the Pi because it's 5V, and Pi needs 3V.  So I need to find some level converters first... delays, delays...

I'll delve into MarkMLI's GPIO package in the meantime.  Can't get it to link - even though  lgpiod is in the same folder as the project ( or in its subfolder)
Code: Text  [Select][+][-]
  1. Compile Project, Target: pharosGPS: Exit code 1, Errors: 1, Warnings: 2
  2. pharosGPS.lpr(12,0) Warning: "crtbegin.o" not found, this will probably cause a linking failure
  3. pharosGPS.lpr(12,0) Warning: "crtend.o" not found, this will probably cause a linking failure
  4. /usr/bin/ld.bfd: cannot find -lgpiod
  5. pharosGPS.lpr(12,0) Error: Error while linking
  6.  
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 27, 2021, 06:06:02 pm
Have you installed the gpiod development package? My Lazarus "Other unit files" setting included gpiod (i.e. as a subdirectory of the project directory and that contained


./gui_test.lpi

./gpiod
...
./gpiod/gpiod.pas
./gpiod/gpiodDefs.inc
./gpiod/gpiod_dynamic.pas
./gpiod/headers
./gpiod/headers/gpiod.h
./gpiod/headers/gpiod.pp-
./gpiod/headers/gpiod-original.h
./gpiod/gpiod-macros.inc
./gpiod/Makefile
./gpiod/WHENCE
./gpiod/dynamicmodule.pas
./gpiod/dynamicmodule.pas~
...
./pollgpiochardev.pas
./gpiochardevhardware.pas


Assume that some of that is cruft that you won't have, I'm showing it "warts and all".

Otherwise you might do better using the dynamic unit to start with, but note the two changed statements I mentioned a couple of days ago.

MarkMLl


Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 27, 2021, 06:33:26 pm

Sounds right.  Wasn't clear I had to "install" anything -  I thought the package (so to speak) would just be a complete thing - soup to nuts.

Yes - folder is there.  I had moved some of those files into the same folder as where my main program (project) file is located.


I'll plow on,,,

(I also have to re-install Lazarus ... alas I re-installed the OS because of something I munged up in Linux land..., at least I had backed up all the other stuff done to date).
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 27, 2021, 07:08:38 pm
Sounds right.  Wasn't clear I had to "install" anything -  I thought the package (so to speak) would just be a complete thing - soup to nuts.

You've got a Raspberry Pi. Running Raspbian or whatever they call it these days. I suggest you familiarise yourself with its SOP, and the significance of lines like this which describe Raspbian (nee Debian) packages:

gpiod - Tools for interacting with Linux GPIO character device - binary
libgpiod-dev - C library for interacting with Linux GPIO device - static libraries and headers

The basic gpiod package will include a dynamically-linkable library, to which gpiod_dynamic.pas should interface.

The libgpiod-dev package will include a statically-linkable library, to which gpiod.pas should interface.

Absolutely nothing to do with Lazarus. this is RPi stuff.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 27, 2021, 07:56:32 pm
Quote
gpiod - Tools for interacting with Linux GPIO character device - binary
libgpiod-dev - C library for interacting with Linux GPIO device - static libraries and headers

The basic gpiod package will include a dynamically-linkable library, to which gpiod_dynamic.pas should interface.

The libgpiod-dev package will include a statically-linkable library, to which gpiod.pas should interface.

Absolutely nothing to do with Lazarus. this is RPi stuff.

Thanks - I confused that error with the names of the folder you had in your package (gpiod) containing gpiod.pas ...;;

OTOH:
Code: Text  [Select][+][-]
  1. pi@raspberrypi:~/Documents/PharosGPS $ sudo apt-get install gpiod
  2. Reading package lists... Done
  3. Building dependency tree      
  4. Reading state information... Done
  5. gpiod is already the newest version (1.2-3+rpi1).
  6. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
  7.  
  8. pi@raspberrypi:~/Documents/PharosGPS $ sudo apt-get install lgpiod-dev
  9. Reading package lists... Done
  10. Building dependency tree      
  11. Reading state information... Done
  12. E: Unable to locate package lgpiod-dev
  13.  
  14.  

yet: ( line 5 of below):

Code: Text  [Select][+][-]
  1. Compile Project, Target: pharosGPS: Exit code 1, Errors: 1, Warnings: 2
  2. pharosGPS.pas(13,60) Warning: "crtbegin.o" not found, this will probably cause a linking failure
  3. pharosGPS.pas(13,60) Warning: "crtend.o" not found, this will probably cause a linking failure
  4. /usr/bin/ld.bfd: warning: /home/pi/Documents/PharosGPS/link.res contains output sections; did you forget -T?
  5. /usr/bin/ld.bfd: cannot find -lgpiod
  6. pharosGPS.pas(13,60) Error: Error while linking
  7.  
  8.  



Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 27, 2021, 08:16:29 pm
have you installed the libgpiod-dev package? Are you using gpiod.pas or gpiod_dynamic.pas?

I had this stuff running painlessly on a newly-configured RPi a couple of days ago, so I know it works.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 27, 2021, 08:34:13 pm
What a difference a few chars make ... libgpiod-dev  , not lgpiod-dev  :-[

So, it compiles (with the crt begin/end errors), runs (I have it write a random number to a file).

So, on to some blinking lights.

Thanks!!!
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on February 28, 2021, 03:59:49 pm
@MarkMLI:

In a post further up (#76), you posted what I assume is a demo function to list all of the ports.  I tried to use this but it won't compile using your units:

Example:
Code: Pascal  [Select][+][-]
  1. FUNCTION ListGpioChardevPorts(currentPort: THandle= InvalidGpioHandle): TStringList;

Code: Text  [Select][+][-]
  1. pharosGPS.pas(14,53) Error: Identifier not found "InvalidGpioHandle"

"InvalidGpioHandle"is not defined anywhere in your package that I can find. The compiler threw other errors with that function, as well

Searched for it and it's only in my testcode:
Code: Text  [Select][+][-]
  1. pi@raspberrypi:~/Documents/PharosGPS $ grep -rnw  -e 'InvalidGpioHandle'
  2. backup/pharosGPS.pas:14:FUNCTION ListGpioChardevPorts(currentPort: THandle= InvalidGpioHandle): TStringList;
  3. backup/pharosGPS.pas:22:  if currentPort <> InvalidGpioHandle then
  4. pharosGPS.pas:14:FUNCTION ListGpioChardevPorts(currentPort: THandle= InvalidGpioHandle): TStringList;
  5. pharosGPS.pas:22:  if currentPort <> InvalidGpioHandle then
  6. pi@raspberrypi:~/Documents/PharosGPS $
  7.  

The problem with me is, as stated, everything LCL, object programming is in between me (simple programmer) and the hardware.

Your package is so abstract to me that I can't make heads or tails of where the code meets the hardware,   Your objective is good, but the implementation might as well be Chinese to me,

Could you post as _few lines_ as possible of CLI code that, using your units, will do, and only do:

Code: Pascal  [Select][+][-]
  1. program Alanisasimpledumbass;
  2. USES
  3.     crt,  //if need be
  4.     gpiod,
  5.     gpiod_dynamic,
  6.     Dynamicmodule,
  7.     SysUtils ,
  8.     Classes //,
  9.     ;  
  10.  
  11. type
  12.            //
  13. var
  14.           i: integer;
  15.  
  16. // set GPIO pin 17 to output mode.
  17.          <  >
  18.  
  19.         for i := 1 to 10 do
  20.              begin
  21. // turn the pin on
  22.                    < >
  23.                   sleep(100);
  24. //turn the pin off.
  25.                    < >
  26.                   sleep(100);
  27.              end;
  28. //- return the pin to the system (equivalent to Unexport).
  29.           <  >
  30. //- other'
  31.            < >
  32.  
  33.  
  34. end.
  35.  

With a working version of that, I'll be able to trace the code down to understand how it works.

Thanks,
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on February 28, 2021, 06:42:08 pm
Assume InvalidGpioHandle is -1. That wasn't so much working demo code as an illustration of how to call the entry points, noting IN PARTICULAR that the leading "Gpiod." is REQUIRED for both the static and dynamic variants.

Apart from that, the function of the various entry points is as described in the documentation for the gpiod library. I suggest familiarising yourself with that and with their examples: my units are a /very/ thin wrapper around that with no attempt to convert their API into something object-based.

Looking briefly at your code, use EITHER the gpiod unit, OR the gpiod_dynamic unit, not both since that has your program trying to use two different library interfaces for the same functionality. I would suggest using gpiod_dynamic, since (a) that doesn't need the -dev package and (b) I've already pointed out that some of the documented gpiod functionality (i.e. from the POV of the kernel developers) isn't actually in the library version shipped by Debian so might or might not be in the one shipped by Raspbian, and if you use dynamic linkage you'll get a run-time exception which you can work around.

I've not got code that you can easily drop into a project and run, but below are two snippets that you can use to see the sequence I've used... apart from that you're going to have to read the documentation.

Assume that e indicates whether a line is enabled, x whether it needs to be inverted (xor operation) and v its value. You don't want to see the GUI stuff.

Code: Pascal  [Select][+][-]
  1.         e := true;
  2.         v := 0;
  3.         lineHandle := Gpiod.gpiod_chip_get_line(chipHandle, i);
  4.         if lineHandle = nil then
  5.           e := false;
  6.         if e and Gpiod.gpiod_line_is_used(lineHandle) then
  7.           e := false;
  8.         if e and (Gpiod.gpiod_line_direction(linehandle) <> GPIOD_LINE_DIRECTION_INPUT) then
  9.           e := false;
  10.         if e and (Gpiod.gpiod_line_request_input(lineHandle, Pchar('GuiTest')) <> 0) then
  11.           e := false;
  12.         if e then
  13.  
  14. // Older versions of libgpiod e.g. as shipped with Debian "Buster" might not
  15. // support this entry point.
  16.  
  17.           try
  18.             x := Gpiod.gpiod_line_is_active_low(lineHandle)
  19.           except
  20.             x := false
  21.           end
  22.         else
  23.           x := false;
  24.         if e then begin                 (* Accessible and input                 *)
  25.           v := Gpiod.gpiod_line_get_value(lineHandle); // Bit from GPIO
  26.           if not (v in [0, 1]) then
  27.             continue;
  28.           v := v xor Ord(x);
  29.           linesForDisplay.Append(Format('d%d:%d', [i - lowest, v])); // Bit to GUI
  30.           Gpiod.gpiod_line_release(lineHandle)
  31.         end
  32.       end;
  33.  
  34. ...
  35.  
  36.         e := true;
  37.         v := Ord(guiTestForm.DigitalOutValue[i - lowest]); // Bit from GUI
  38.         lineHandle := Gpiod.gpiod_chip_get_line(chipHandle, i);
  39.         if lineHandle = nil then
  40.           e := false;
  41.         if e and Gpiod.gpiod_line_is_used(lineHandle) then
  42.           e := false;
  43.         if e and (Gpiod.gpiod_line_direction(linehandle) <> GPIOD_LINE_DIRECTION_OUTPUT) then
  44.           e := false;
  45.         if e and (Gpiod.gpiod_line_request_output(lineHandle, Pchar('GuiTest'), 0) <> 0) then
  46.           e := false;
  47.         if e then
  48.  
  49. // Older versions of libgpiod e.g. as shipped with Debian "Buster" might not
  50. // support this entry point.
  51.  
  52.           try
  53.             x := Gpiod.gpiod_line_is_active_low(lineHandle)
  54.           except
  55.             x := false
  56.           end
  57.         else
  58.           x := false;
  59.         if e then begin                 (* Accessible and output                *)
  60.           if Gpiod.gpiod_line_set_value(lineHandle, Ord((v <> 0) xor x)) = 0 then // Bit to GPIO
  61.             linesForDisplay.Append(Format('d%d:%d', [i - lowest, Ord((v <> 0) xor x)])); // Bit to GUI
  62.           Gpiod.gpiod_line_release(lineHandle)
  63.         end
  64.  

I've not investigated using that API to set directions. What I've done so far is set them using the sysfs API, then unexport the line to make it unused hence available to the dev interface. As I've already written up, there's a gpiod program to show you chip/line status.

I've been working hard outdoors all day, and now have to do paperwork.

MarkMLl

Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on March 01, 2021, 12:01:12 am

Minor progress... (between errands etc.).

Can't seem to get a valid line handle. (probably because the chip handle is not valid?)

Many variations on path used:    /dev/gpiochip0 (and 1, and via /sys/class, etc and so on...

Compiles, runs, crashes on attempting to

a) testing the path (commented out below) and

b)   lineHandle := gpiod.gpiod_chip_get_line(chipHandle, i); 

because presumably the returned chip handle is not valid because the path is wrong?

Code: Pascal  [Select][+][-]
  1. program pharosGPS;
  2. //{$mode objfpc}{$H+}
  3. USES
  4.     crt,
  5. //    gpiod,
  6.     gpiod_dynamic,
  7.     Dynamicmodule,SysUtils,
  8.     Classes
  9.  
  10.     ;
  11. Const GPIOPath : Pchar = '/dev/gpiochip0/';       // tried via  /sys/class/gpio/... also
  12.  
  13. var
  14.   e: boolean;
  15.   v: integer;
  16.   x: boolean;
  17.   i: word = 22;
  18.   lineHandle: Pgpiod_line;
  19.   chiphandle: Pgpiod_chip;
  20.  
  21. begin
  22.      writeln ('START: ',GPIOPath);
  23.   e := true;
  24.   v := 0;
  25.   //writeln(gpiod.gpiod_is_gpiochip_device(GPIOPath));   //    <- this crashes too
  26.  
  27.   chiphandle := gpiod.gpiod_chip_open (GPIOPath);
  28.  
  29.   writeln ('LH');
  30.   lineHandle := gpiod.gpiod_chip_get_line(chipHandle, i);     //crashes here
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on March 01, 2021, 01:14:23 am
Go back and look at my example.

Code: Pascal  [Select][+][-]
  1.         pChip := Gpiod.gpiod_chip_open(PChar(gpiochip));
  2.         if pChip = nil then
  3. ...
  4.  

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on March 01, 2021, 03:42:50 pm

Without changing my code, but changing the path again, it finally worked.  Some typo before? (rhetoric)

Anyway, path
      Const
       GPIOPath : Pchar = '/dev/gpiochip0';
works

      GPIOPath : Pchar = '/sys/class/gpio/gpiochip0';   
does not work, returns a nil for the chiphandle.

Onward ...
Thanks.
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on March 01, 2021, 07:28:07 pm
      GPIOPath : Pchar = '/sys/class/gpio/gpiochip0';   
does not work, returns a nil for the chiphandle.

Of course it doesn't work! Have you taken the trouble to read my #89, and in particular did you read the bit that referred to the gpiodetect command and gave you an example of its output? Did you look at the gpiodetect manpage, and in particular the "see also" section that pointed you at the various utility commands... the source for which you can read if you're in any doubt about the documented API?

The two set of names- those in sysfs and those in /dev- are for DIFFERENT APIS, and you can't just mix-and-match at random and expect things to work.

Except obviously where you have to, for reasons that I did my best to explain, and even then you're effectively running them in parallel rather than chucking them into a communal pot.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on March 01, 2021, 10:31:20 pm

I had tried both paths without success.  (And for the avoidance of doubt, in case it matters, I did remove the gpiod unit).

And had compiled, running (crash or not) code with the correct one.  Something else was amiss.  So I try things to see what happens.

pi@raspberrypi:~/Documents/PharosGPS $ gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

Doesn't really clarify where they are, now does it? (other than that there is -h and -v ... no other commands).

Further the following call does not work (crashes) with a valid path in it:
           t := gpiod.gpiod_is_gpiochip_device(PChar('/dev/gpiochip0'));

Which sends one down other rabbit holes...

Now trying to figure out serial data (UART).  That is truly opaque in this well documented program.

Esp. as I don't have a reliable source of UART input that I know for sure is outputting data to the pin...
Perhaps a loop back from terminal ... tbd.

I get you're frustrated.  To me, all of this is abstracted to the point of incomprehensibility and densely worded documentation doesn't show clearly.  Also: I'm not a Linux guy.  At all.  I don't use API's much.  At all.   When I had hardware to interface to, I always did it at the lowest level possible.  Not portable.  That was never the intention.  Nor is it with the current project.

Cheers,

Big boom from Hermann in your old home town the other day ...
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: MarkMLl on March 02, 2021, 08:25:03 am
pi@raspberrypi:~/Documents/PharosGPS $ gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)

Doesn't really clarify where they are, now does it? (other than that there is -h and -v ... no other commands).

As I said, that is a problem. Refer to your hardware documentation to find out which are which.

Quote
Further the following call does not work (crashes) with a valid path in it:
           t := gpiod.gpiod_is_gpiochip_device(PChar('/dev/gpiochip0'));

I ALREADY TOLD YOU THAT ONE WASN'T IMPLEMENTED!!!!! Message #76, and being able to cope with that sort of thing is one of the big advantages of dynamic linkage.

Quote
Now trying to figure out serial data (UART).  That is truly opaque in this well documented program.

Esp. as I don't have a reliable source of UART input that I know for sure is outputting data to the pin...

Not my problem until you start looking at the serial.pp unit. In a separate topic.

MarkMLl
Title: Re: FPC on Rasp Pi, non Lazarus, use of GPIO.
Post by: AlanTheBeast on March 02, 2021, 02:08:59 pm

Sorry Mark,

The mind wanders - didn't realize I repeated that.

I'll be looking more at the UART later this week.  Full work days ahead, alas.
TinyPortal © 2005-2018