Lazarus

Programming => Operating Systems => Embedded => Topic started by: jcdammeyer on July 17, 2020, 11:21:06 pm

Title: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 17, 2020, 11:21:06 pm
A number of years ago I bought a 4DCAPE-43T for the Beaglebone Black.  I think Rev 7 Wheezy at the time. 
https://www.mouser.ca/datasheet/2/451/en4-4dcape-all_datasheet_r_1_1-1627121.pdf (https://www.mouser.ca/datasheet/2/451/en4-4dcape-all_datasheet_r_1_1-1627121.pdf)
Support from the company was really not there and I think it's been discontinued. 

It's always been my plan to use Lazarus for this or other LCD displays that are non-HDMI as say instrument panels or information panels.  The trouble is in many cases, like for this one, they configure the cape display as the user interface.  But a full Linux screen isn't wanted nor all the borders etc.   

I would rather develop the Lazarus application to run on the Pi or Beagle and create a frame that has all the stuff I want and has the same dimensions as the LCD display.  So if it's 320x280 then that's the size of the frame and all the components are inside that.   If it's an SPI based LCD display then a call to paint should theoretically be able to grab what is essentially an array 320x280 of say 16 bit or 24 bit RGB values.

And dump it out to the display.  In the case of the Beagle Bone I believe this display can be directly addressed through the device ports but from an abstract perspective the starting point needs to be painting the frame or portions of the frame.  Speed can be increased by only painting the button that's been pressed.  As in only that small chuck of screen image needs to be transferred.

Is there already an infrastructure in place for this sort of thing?  I really don't want an HDMI 800x600 screen to the the Linux User Interface screen. 

So which subject heading under Forum here is the best place to discuss this?  It requires knowledge of Beagle/Pi hardware (SPI devices for example) and the painting of parts or whole of a frame.  In fact the Beagle or Pi might even be of the headless type that doesn't have a user display.  ie. command line.  But still I'd like the graphical features that Lazarus provides rather than a GTK or other tool box.  With those we lose what Lazarus gives us for program development.
Thanks
John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 18, 2020, 04:21:07 am
Perhaps I can add onto this a bit.  The two attached screen shots show two images I'd like put onto an LCD display.  The one with the standard window border is a python program.  The chart is a Lazarus program.  Needless to say the Lazarus once was simple to make.

The Python uses the TKinter library but won't run from an SSH session because there is no graphics screen.  Haven't tried the Lazarus one but I suspect it will be the same. 

So how does one run a Lazarus program and make use of all the excellent components from a command line that won't support graphics.  But captures the graphical image to send out via SPI or direct to ports on the processor.

And if this is the wrong subforum  please point me in the right direction.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: DonAlfredo on July 18, 2020, 08:06:40 am
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#PXL_.28Platform_eXtended_Library.29_for_low_level_native_access_to_GPIO.2C_I.C2.B2C.2C_SPI.2C_PWM.2C_UART.2C_V4L2.2C_displays_and_sensors
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 18, 2020, 08:39:21 am
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#PXL_.28Platform_eXtended_Library.29_for_low_level_native_access_to_GPIO.2C_I.C2.B2C.2C_SPI.2C_PWM.2C_UART.2C_V4L2.2C_displays_and_sensors
Thanks! I'll play with that a bit.
John

Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 19, 2020, 09:17:50 am
I captured the Mandelbrot example and compiled it on the Beagle and PC with Lazarus and made the small changes required to compile it with Delphi 10.3.3

Running it from the command line on the beagle in a console window creates the form and draws the figure.  I think if I wanted that output on a say a small adafruit lcd SPI bus LCD display then I'd have to override the paint method to send the the imagebuffer canvas out.
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.FormPaint(Sender: TObject);
  2. begin
  3.   Canvas.Draw(0, 0, ImageBuffer);
  4. end;
  5.  
But running that same application from an SSH terminal

debian@ebb:~/lazarus/Mandelbrot$ ./mandelbrot

(mandelbrot:11924): Gtk-WARNING **: cannot open display:


Which suggests that even if I did change paint to deal with hardware a command line version of Debian wouldn't even allow the Lazarus application to run.

I did find
https://sourceforge.net/projects/asphyre/
with examples for output to SPI LCD. displays.  But then I'm back into the Python etc. world where the graphical objects are placed with coding rather than the convenience of Lazarus.

Is there a solution where FormPaint or Paint or Repaint can be set for custom hardware and still load in a non-window environment?  If I plug in the 4DCAPE-43T the HDMI has to be disabled to run it.  And I don't want the entire window environment sent to it.

Or am I stuck with not using the 4DCAPE-43T and use a system that has graphical and just doesn't have a USB keyboard/mouse and HDMI monitor connected.  And have it start up running the Lazarus app that has paint overridden?

Thanks
John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: DonAlfredo on July 19, 2020, 10:51:48 am
Designing a GUI with Lazarus for a SPI LCD or similar will require you to write a whole new LCL widgetset.
Would be rather nice if you did ... ;-)

PXL allows you to write GUI progs that are more or less transparent with respect to the GUI backend.
But no easy WYSIWYG.

PXL can give you easy access to systems without a standard windows manager.
Have a look here.
https://github.com/LongDirtyAnimAlf/AsphyrePXL
This is a PXL clone adapted to be able to run the test-suite of the mORMot on Android.
I have uploaded some APK to have a look at how this works.
https://github.com/LongDirtyAnimAlf/AsphyrePXL/releases/tag/1.0.0
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 19, 2020, 06:43:29 pm
I don't want to develop on an LCD display.  I have on hand:
1. 4DCAPE-43T  320x240
2. Manga1 -- HDMI  4.3" 800x600
3. Manga2 -- HDMI  5.9" 1080P
4. Adafruit -- HDMI 800x400 c/w touch
5. 2.8" TFT SPI 320x240  (3 of them)
6. Some very tiny 64xsomething LCD displays

Even the Manga2 is  still quite small (cell phone screen) repurposed with hdmi. 

For the HDMI screens clearly the Linux OS will provide the support but I don't want the user desktop and yet I'd like to be able to easily build say a screen like the chart image, develop, test on a full blown Pi or Beagle with larger screen and then install into say a PiZeroW for either SPI or a PC.

For example in the attached screenshot you running (simulated data) an app designed on a Pi, moved and compiled and has run on the Beagle and the screen shot is from a WIN-7 PC where I just compiled it a minute ago.  Notice it's anchor point is 0,0 without the standard desktop frame.  So theoretically if it's designed to be 800x600 it should fill the entire HDMI screen.  If recompiled for 320x280 would still fit on the smaller SPI based screens but rendering it is now different from the larger footprint desktop Linux.  But the rest of the desktop baggage can't be there.

And the data to fill it could all come via a CANopen USB based dongle that talks to remote devices that have One-Wire sensors.  Or via UDP WiFi IOT type stuff.

So one program, multiple displays, special units with paint functions. 

I think...  I don't want to rewrite a graphical user interface when so much is already there in Lazarus.

And http://www.autoartisans.com/images/screen.jpg (http://www.autoartisans.com/images/screen.jpg) is screen shot of an instrument panel for a project back in the late nineties.  Written in Delphi and using an Active X Control library of gauges.  The company that developed those was sold and the buyer locked up the development for internal use and so they vanished with WIN-XP.  We need more of these types of components with Lazarus. 

I'm willing to write these but the end use is still not desktop but embedded hardware.  And I really don't want to go the Python route creating forms inline.  It's a step backwards.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 19, 2020, 06:56:32 pm
One other attachment.  This is from an article I wrote for Circuit Cellar Ink magazine about my CANRF project.  Preceded ZigBee and the new IOT stuff.  A series of yard lights either solar powered or wired and even containing PIR motion detectors.    It was set up as as mesh network with any one sensor then sending messages out to others to also turn on.  The PC application was again written in Delphi.  Overlaid on a JPG of an aerial shot of the property each light is shown by the icon.  And ON/OFF by colour.   

Now I'd probably use a number of inexpensive ESP8266 modules that use the Ardunio development and plant a few WiFi repeaters around but a number of different methods. 

And there could be small LCD based displays in various rooms showing the status and providing user control to say turn on sections or garden lights on pathways.  Not to mention returning information like temperature, RH, rainfall and wind speed/dir.  With Delphi it's even possible to write and compile for iPhones, Android so remote access to the images and menus are possible.  But it's not really able to target the PiZeroW or the new smaller Beagles.

So that consistent user interface on all modules lends itself well to Lazarus and Free Pascal.  And once developers have used it for a while with all the access to the device hardware the desire to go back to Python will seem so antiquated.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on July 19, 2020, 10:32:59 pm
For the HDMI screens clearly the Linux OS will provide the support but I don't want the user desktop and yet I'd like to be able to easily build say a screen like the chart image, develop, test on a full blown Pi or Beagle with larger screen and then install into say a PiZeroW for either SPI or a PC.
Framework to use SPI lcd screens on linux is http://asphyre.net/products/pxl.
For Pi HDMI displays without linux you can use https://ultibo.org/.
And you can always roll your own SPI lcd screen drawing lib.

However, I think that you gave up LCL too easily. Yes, I know that you don't want user desktop, but you can use minimal linux distro that can boot directly into your application without users ever noticing that. There are minimal raspbian editions that can be striped, or you can use Tiny Core and similar Linux striped distros with/without read only feature. According to the screenshots of what you want to achieve, I still think that it would be best to use LCL on some embedded linux window manager.

One of these links could be used to fit the bill:
http://www.tinycorelinux.net/ports.html
http://www.nard.se/
https://dietpi.com/
http://www.linutop.com/software.en.html
https://hallard.me/raspberry-pi-read-only/
https://alpinelinux.org/downloads/
https://www.graphics-muse.org/wiki/pmwiki.php/RaspberryPi/RaspberryPi
https://openwrt.org/toh/raspberry_pi_foundation/raspberry_pi
https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-4

There are also Yocto, Balena, Buildroot, PTXDist, OpenEmbedded...
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 19, 2020, 10:50:18 pm
Thanks for the links.  I have some reading to do.
John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 20, 2020, 04:05:29 am
Here is another example of how easy it is to develop and test on the PC with either Linux or Windows and why I want to use Lazarus as is.

Once I had it working on the PC I did a drag and drop the folder onto in this case a BeagleBone Black running Stretch.  The Beagle has a cable attached to a proto cape that runs to a board with a DS1822 temperature sensor/serial# chip.  The driver on the Beagle automatically updates the file with two lines of information when it's read.

The application loads the File Dialog so you can find the w1_slave file in the folder with the devices serial #.  Then when you click on OK it parses the strings of characters and generate the temperature to update into RackCtls package LED display I found on line by searching Lazarus 7 segment LED display.

The two attached screen shots show the result.  With components like the LEDs and the graphs from Lazarus and an hour to write the application nice user interface applications with small LCD displays are trivial.

I'll add some documentation to the program and zip it up and attach it onto this subject thread.  the program is huge but meant to test the parsing of some of the code.  The LED display was an afterthought.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on July 20, 2020, 08:37:02 am
Here is another example of how easy it is to develop and test on the PC with either Linux or Windows and why I want to use Lazarus as is.
That's one of the reasons why I advise sticking to LCL.

The Beagle has a cable attached to a proto cape that runs to a board with a DS1822 temperature sensor/serial# chip.
Have this in mind: https://www.cnx-software.com/2020/07/13/fake-ds18b20-temperature-sensors-counterfeit-clones/

The LED display was an afterthought.
You made me smile showing 3 decimals for the temperature.  ;)
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 20, 2020, 09:17:05 am
Have this in mind: https://www.cnx-software.com/2020/07/13/fake-ds18b20-temperature-sensors-counterfeit-clones/

You made me smile showing 3 decimals for the temperature.  ;)

Ha ha.  It comes from the driver in the Beagle.
5d 01 4b 46 7f ff 03 10 8c : crc=8c YES
5d 01 4b 46 7f ff 03 10 8c t=21812

Divide by 1000.

Not worried about fakes.  Mine were quite expensive even in 1000 qty.  The board this particular sensor is connected to came from this:
http://www.autoartisans.com/rings/Barge1a.jpg (http://www.autoartisans.com/rings/Barge1a.jpg)  The face of each lamp had one sensor in order to provide a unique serial number for each lamp which were on a CAN bus.  We ended up using the temperature too.
http://www.autoartisans.com/rings/temperatures.jpg (http://www.autoartisans.com/rings/temperatures.jpg)
The set at YVR airport one day in July had some lamps hit 60C. Very red on the display screen.  I wish I'd captured a screen shot from that day now.  When they were cold they were blue. Hover over the lamp indicator and at the bottom of the screen you'd get the reported temperature.
The lamps on the barge also reported DC voltage so the dual display but this screen shot doesn't shot that. http://www.autoartisans.com/rings/BargeRingsTemperatures.JPG (http://www.autoartisans.com/rings/BargeRingsTemperatures.JPG)  The set facing North wasn't was warm as the set facing south.

Oh and the PC software?  Delphi-7.  PIC18F processors in the lamps (C code).  Controller M9S12XDP512 (C-Code).

Going to take a closer look at this tomorrow.  Now after midnight here.


          Platform eXtended Library v1.1.0, dated 9-Dec-2017.
             Copyright (c) 2000 - 2017  Yuriy Kotsarenko
                   https://asphyre.sourceforge.net
                   https://asphyre.net

-------------------------------------------------------------------------------

This product requires either Embarcadero Delphi XE 8 (or any later version) or
FreePascal 3.0 with Lazarus 1.4 (or any later versions).

When used with Embarcadero Delphi, the following platforms are supported:

1) Windows 32 and 64-bit
2) Mac OS X
3) Android
4) iOS 32 and 64-bit


Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on July 20, 2020, 11:02:13 am
This product requires either Embarcadero Delphi XE 8 (or any later version) or
FreePascal 3.0 with Lazarus 1.4 (or any later versions).

I have mentioned it for Pi and BB using Laz/Fpc. This is from https://asphyre.net/products/pxl:
Quote
Raspberry PI
- Fast access to CPU timer, GPIO, I²C, SPI and UART using direct manipulation of SoC registers.
- V4L2 video/image capture using onboard and USB cameras.
- OpenGL ES rendering with and without X server, including drawing to bitmaps. One of examples shows how to render your visual scene with GPU and then pass it to external display via SPI wiring!
- ...and many other features that are available for generic singleboard platforms.

BeagleBone Black
- Easy access to native Linux Sysfs interfaces such as GPIO, PWM, ADC, I²C, SPI and UART.
- Serial cameras such as VC0706 and LSY201.
- I²C and SPI displays such as SSD1306, SSD1351, PCB8544 (Nokia), HX8357 and ILI9340.
- Character LCDs with direct pin wiring.
- Support for Software SPI and UART (bit-banging).
- Support for SC16IS7x0 (UART controller connected via I²C or SPI), including extra GPIO pins.
- Support for sensors such as BMP180, DHT22, L3GD20, LSM303 and SHT10.
- Networking communications through UDP protocol.
- Video/image capturing through generic V4L2 interface.
- Software rendering for visual effects and user interfaces.

You can completely avoid PXL if you use LCL, since there are other libs for access to GPIO, SPI, I2C, serial...
https://wiki.freepascal.org/Hardware_Access
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi
https://wiki.freepascal.org/Raspberry_Pi_-_SPI
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 20, 2020, 06:41:49 pm
This product requires either Embarcadero Delphi XE 8 (or any later version) or
FreePascal 3.0 with Lazarus 1.4 (or any later versions).

I have mentioned it for Pi and BB using Laz/Fpc.
You can completely avoid PXL if you use LCL, since there are other libs for access to GPIO, SPI, I2C, serial...
https://wiki.freepascal.org/Hardware_Access
Yes. And thanks for that link.
But the LCL and the link to
https://wiki.freepascal.org/Hardware_Access (https://wiki.freepascal.org/Hardware_Access)
seem more to address windows parallel ports than what is required for the Beagle. I must admit it's been over two yeas since I let the beagles out of their kennel.  Been too busy with work-work projects.  And the changes in how hardware is accessed over the lifetime of that device has been unsettling.  I'm pretty sure the .dts files are still required.  The Buster version is only available as command line not windowing.  Maybe I should wait just in case the Beagle world has changed yet again.

The easy way to the I/O is just with the file operations. 
Code: Text  [Select][+][-]
  1. debian@ebb:/sys/class/gpio/gpio68$ ls
  2. active_low  device  direction  edge  label  power  subsystem  uevent  value
  3. debian@ebb:/sys/class/gpio/gpio68$ cat label
  4. P8_10
  5. debian@ebb:/sys/class/gpio/gpio68$ cat direction
  6. in
  7. debian@ebb:/sys/class/gpio/gpio68$ cat value
  8. 1
  9. debian@ebb:/sys/class/gpio/gpio68$
  10.  
So slow I/O for turning on relays or reading switches isn't super difficult but certainly isn't compatible with the Pi.  So the moment we dive into the world of control systems the software becomes somewhat system dependent.
But then that's true to a certain extent for embedded systems of any sort.  Although I follow the same style regardless of whether I'm writing for a PIC18, dsPIC30 or PIC32 and M9X12X.

Generally the port bits are represented with a macro or a function that 'hides' the actual hardware so it can be moved inside the IOMapping.h file without affecting the application.

Code: C  [Select][+][-]
  1. if (fPowerSwitch) {
  2.    ...
  3. }
  4.  

The fPowerSwitch may well be a bit in a byte which is kept up to date via a PDO CANopen message from the network or local hardware.  Or it may be local hardware.

In Lazarus or Delphi my guess would be to abstract it with property statements like
Code: Pascal  [Select][+][-]
  1.     property PowerSwitch: TPortBit read FPowerSwitch write FPowerSwitch;
  2.  
and then
Code: Pascal  [Select][+][-]
  1.   if PowerSwitch then begin
  2.      ...
  3.   end;
  4.  

Now once again, depending on the Pi or Beagle or even PC where the power switch is doesn't matter.  It could be on the parallel port of an embedded PC and the LCL ports are used.
Or just as easily on a CANUSB dongle with CAN bus support through the CAN library.
Or SPI bus and a port expansion chip.

But I need to get myself up to to date on how I/O is handled on the Beagle because the changes somewhere around 2017 or so were very significant.  I believe the dts files are still needed. 

At that point I didn't consider using Lazarus between a Pi and a BBB.  But now things have changed.

I'll let you know what I find.

Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 21, 2020, 01:08:26 am
I think the only way to get to the point where I can use Lazarus in the same way that Python is used on the Beagle is to first climb up the learning curve by doing many of the projects in the Second Edition of Derek Molloy's "Exploring Beaglebone".  I also have the First Edition but I think much of the Device Tree stuff has changed.

The attached program is only relevant for a Beagle because the Pi doesn't have the on board USRx LEDs.  But as I work through each of the sample Python programs I'll see what I can do to make them work on both systems.

The attached program is a command line Lazarus TCustomApplication.  Written and debugged on a PC running WIN-7 so there's the ifdef
Code: Pascal  [Select][+][-]
  1.  
  2.   {$IFDEF WIN64}
  3.     LED3_PATH := 'c:/Temp/sys/class/leds/beaglebone/usr3';
  4.   {$ELSE}
  5.     LED3_PATH := '/sys/class/leds/beaglebone:green:usr3';
  6.   {$ENDIF}
  7.  
to set the correct paths to the hardware or simulated files.  There are also two example__.txt file with the examples showing it running on both Windows and the Beagle.

I've also included Derek Molloy's original python example.

This set of mini projects may well be better on a separate thread.  I'm open to suggestions as to where to put it.  I've not added a lot of documentation to the program as the book really explains what it's all about.
John


Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 21, 2020, 04:23:58 am
Reading further into the "Exploring Beaglebone" Edition 2, I find there is also a similar example to control all 4 on board LEDs but this time written in C++ called makeLEDOOP for Make LEDs OOP.

Using the previous program converted from the Python example I created an LED object and modeled the Lazarus program after the C++ other than keeping the TCustomApplication.

Ran in simulated mode on the PC.  copied the 3 files to the Beagle and compiled it there.  Ran perfectly.  No problems.

From Chapter 5 Example 5-17.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 21, 2020, 09:59:05 am
I thought I'd whip out the little sample program on page 260 that shows what bitwise operations do.  Of course it's C++ and I'm using Lazarus so I whipped up "Bits".  After a bit of fine tuning I suddenly realized I'd fallen into the Linux Command line trap.  I hate command line programs.  And here I was writing one and using a ReadLn at the end to keep the window from closing when I tested.

The whole point of Lazarus is that memory is cheap and user's time is not.  Spend a minute typing every 10 minutes and in 10 hours you've lost an hour.  And the silly thing is it didn't take much longer to create "BitsForm"

So here's the source for both.  One's a command line program and on the Beagle compile to 111K while the forms one is almost 600K.  But memory is cheap!  Haven't tried this on the Pi but since it's not hardware sensitive it should compile and work there too.

Hints are enabled so hover over the fields to see how to use it.  No need to type in the command  and try -? or -help  or -h to discover only --help dumps out a few lines of information.

Yes.  Forms based programs take longer to make with all the various 'features' but are so much more user friendly.

John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on July 21, 2020, 10:37:57 am
But the LCL and the link to
https://wiki.freepascal.org/Hardware_Access (https://wiki.freepascal.org/Hardware_Access)
seem more to address windows parallel ports than what is required for the Beagle.
2nd link is more adequate for your needs, especially this subtopic:
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Accessing_external_hardware
I admit that maybe it should have been put at first place, but that's the way it is. You will find there several libs/ways for accessing hardware, and I think that some might even work on both Pi and BB (try 1, 2 and 7).

I think that would be far more convenient then converting examples from Exploring BeagleBone book. Anyway, that's up to you to decide. If you go the book way, then the same author has written Exploring Raspberry Pi book. Might interest you.

If you need to access or manipulate bits in a byte/word/long/quad, then you might want to take a look at BitHelpers library from my signature.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on July 21, 2020, 05:38:46 pm
Thank you for your feedback.  The Pi is easy to work with for hardware.  I did a project a few years ago where CAN messages needed to be captured from power on.  The solution was to use a PIC32 which grabbed and timestamped the messages.  About 18 seconds later after the PiZeroW had booted my application on pulled up the logged CAN messages via SPI.  They were stored to a file and my customer then accessed them to put the logged files up into a cloud database when the vehicle was near WiFi or Cell service.
 
The BBB has the PRUs, crappy video, but also built in CAN bus. And how the hardware is accessed is quite different from the Pi.   

And I didn't really need to write the Bit access code.  I've learned the hard way over the years it's far smarter to not just dive in and do 'the project'.  That puts blinders on and I learn very little because I don't know what I don't know.  So while somewhat isolated due to COVID-19 it's a perfect opportunity to use Derek Molloy's book to revisit the Beagle but do _everything_ with Lazarus. This forces me to use it ways I wouldn't normally do things. 

And along the way if no one minds, I'll post the code examples.  And as per the thread topic, eventually have a simple and understandable method of creating small embedded stand alone systems that use embedded graphical displays and touch screens all done with Lazarus. 
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 10, 2021, 11:06:34 pm
So it's been a while.  Lot's of things happening since the last time I posted which includes discovering an issue in one of the dispaly libraries.

Anyway, I'm back to trying to create a common I/O interface with the hardware and decided to take a stab at the PXL library for Lazarus.  The code compiles and runs properly on a PC with WIN-10.

Deep down into bunxh.inc the call
    Function  FpIOCtl      (Handle:cint;Ndx: TIOCtlRequest; Data: Pointer):cint; external name  'FPC_SYSC_IOCTL';

in the example
\\EBB\ebbHome\lazarus\pxl\Samples\FreePascal\SingleBoard\Generic\DisplaySPI folder

Code: Pascal  [Select][+][-]
  1. function TSysfsSPI.Transfer(const ReadBuffer, WriteBuffer: Pointer; const BufferSize: Cardinal): Cardinal;
  2. var
  3.   Data: spi_ioc_transfer;
  4.   Res: Integer;
  5. begin
  6.   if ((ReadBuffer = nil) and (WriteBuffer = nil)) or (BufferSize <= 0) then
  7.     raise ESysfsInvalidParams.Create(SInvalidParameters);
  8.  
  9.   Data.tx_buf := PtrUInt(WriteBuffer);
  10.   Data.rx_buf := PtrUInt(ReadBuffer);
  11.   Data.len := BufferSize;
  12.   Data.delay_usecs := 0;
  13.   Data.speed_hz := FFrequency;
  14.   Data.bits_per_word := FBitsPerWord;
  15.  
  16.   Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);
  17.   if Res < 0 then
  18.     raise ESysfsSPITransfer.Create(Format(SCannotSPITransferBytes, [BufferSize]));
  19.  
  20.   Result := Cardinal(Res);
  21. end;
  22.  
Quote
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/DisplaySPI$ sudo ./DisplaySPI
[sudo] password for debian:
An unhandled exception occurred at $00032BB0:
                                             ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus.
                                   $00032BB0  TSYSFSSPI__TRANSFER,  line 247 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas
                                                   $00032AC4  TSYSFSSPI__WRITE,  line 228 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas


As I understand it, fpioctl is a free pascal function and part of the system library.  The cannot transfer error doesn't say anything more than "Doesn't work!"  Not why.

I'm working with the BeagleBone group to configure the system so that sudo isn't needed for access to gpio pins so I can install break points etc.

Later today I'll write a very simple Lazarus program that just sets the GPIO48 pin to output and toggles it on a timer.  But that the code in the PXL sample makes it past the configuration of the GPIO48 and GPIO60 pins for DC and RESET on the LCD display suggests there is a different problem.

Looking for suggestions right now.
Thanks
John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 11, 2021, 09:34:55 am
Here's a pretty simple output test program in Lazarus for the BBB.  With an LED connected to the P9-15 (gpio48) it toggles on and off and the memo form shows the operations as they are done.

This program was derived from:
Code: Pascal  [Select][+][-]
  1. {Demo application for GPIO on Raspberry Pi}
  2. {Inspired by the Python input/output demo application by Gareth Halfacree}
  3. {written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
  4. { From https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Accessing_external_hardware }
  5. {
  6. Modified for Beagle P9-15 (GPIO48) MAY2021 by:
  7. John Dammeyer
  8. Automation Artisans Inc.
  9. johnd@autoartisans.com
  10.  
  11.   Expanded information reported on LogMemo so it's clear who is reporting what
  12.   Note.  Run from command line with sudo in order to be able to work with /sys/class/gpio
  13. }
  14.  

As yet I have not yet figured out the issue with fpioctl() and why I get faults.  It might well be again something to do with permissions.
John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 26, 2021, 02:46:59 am
As yet I have not yet figured out the issue with fpioctl() and why I get faults.  It might well be again something to do with permissions.
John
Alright.  Been a few days and I'm closer to getting the LCD display working with the Pi and Beagle via the pxl library.  I've now got the GPIO group permissions set on the beagle so that I can run the applications from inside the IDE.  But the PXL.sysfs.SPI library would fail consistently on both the Pi and the Beagle during the Transfer() function which calls fpioctl().

So I took a step back and connected one of these:
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/spi-sensors-devices (https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/spi-sensors-devices)
to the Pi and got it working with the Python Code.

The Scope photo is actually from the Lazarus application.  I've included the project and the modified pxl file.
In essence the problem with the fpioctl is that the data structure passed has to be filled with zeros first.
Code: Pascal  [Select][+][-]
  1.  
  2.   FillByte(Data, Sizeof(Data), 0);  // Without this FillByte() fpioctl fails.
  3.  
  4.   Data.tx_buf := PtrUInt(WriteBuffer);
  5.   Data.rx_buf := PtrUInt(ReadBuffer);
  6.   Data.len := BufferSize;
  7.   Data.delay_usecs := 0;
  8.   Data.speed_hz := FFrequency;
  9.   Data.bits_per_word := FBitsPerWord;
  10.  

So that solves one problem in that now at least the data flows out the SPI bus but on the Pi still needs to be run from the command line with sudo.
Quote
pi@raspberrypi:~/projects/lazarus/TC $ sudo ./TC
Reading temperature, press any key to exit...
Temperature: 21.75C 71.15F
Temperature: 21.75C 71.15F
Temperature: 21.75C 71.15F

The problems happen here with the fast GPIO in teh pxl Samples folder for
\\RASPBERRYPI\Pi3Home\projects\lazarus\pxl\Samples\FreePascal\SingleBoard\RaspberryPI\DisplaySPI
 
Code: Pascal  [Select][+][-]
  1. begin
  2.   SystemCore := TFastSystemCore.Create;
  3.   try
  4.     GPIO := TFastGPIO.Create(SystemCore);
  5.  
I haven't yet tried this TC application on the Beagle yet.

Any suggestions?
Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on May 26, 2021, 02:45:05 pm
I must admit that I am confused what works for you and what doesn't. Do you have both GPIO and SPI working but only with sudo? Is that the case? Have you added your user to spi and gpio groups? For debugging purpose you could also temporary add your user to sudo users as mentioned here:
https://www.cb-net.co.uk/linux/creating-a-new-raspberry-pi-raspbian-user-with-gpio-access/

I have not yet figured out the issue with fpioctl() and why I get faults.  It might well be again something to do with permissions.
fpioctl should be mapped to linux ioctl calls, so this might be helpful for understanding SPI_IOC_MESSAGE and debugging:
https://www.kernel.org/doc/Documentation/spi/spidev
https://www.kernel.org/doc/Documentation/spi/spi-summary
https://stackoverflow.com/questions/54923582/spi-ioc-messagen-on-raspberry-pi-3

I would check wiring, chip select and data bits, and of course display's datasheet (including display support for 8MHz SPI as is fixed in PXL).

I know you've mentioned that you don't want desktop showing on the display, but I must say that it is a much easier and less challenging route (someone might ask what's the fun in that ;)), so I will give a link to a cheap Pi touch display that works as advertised after you follow steps to let Linux use it as a default display. I haven't tried to use display over SPI from my application - I simply let Linux handle all that so I could use LCL in it's full glory.
https://www.ebay.com/itm/362836286867

It is fun to look at Linux desktop on a small 480x320 display (both portrait and landscape modes are possible). As mentioned earlier, desktop can be skipped and Linux can be tuned to boot directly to your app.

You might also want to check if you're lucky and your display is already supported by that driver:
https://github.com/goodtft/LCD-show
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 26, 2021, 07:15:13 pm
I must admit that I am confused what works for you and what doesn't.
Here's the rundown.
I now have with slight modifications to the code the SPI based thermocouple reading program working on both systems.  Modifications like /dev/spidev0.0 verses /dev/spi/0.0 and which GPIO pins are used since they are named differently.  But all this works now!

The Pi does belong to the gpio group.
Quote
pi@raspberrypi:~/projects/lazarus/TC $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev lpadmin gpio i2c spi
But still requires sudo to run the application as shown in the previous posting while the BBB now can debug from both inside and out of the IDE.
Here's the BBB accessing the thermocouple board.
Quote
debian@ebb:~/lazarus/TC$ ./TC
Reading temperature, press any key to exit...
Temperature: 21.5C 70.7F
Temperature: 21.5C 70.7F
I'm going to have to go back through my postings to the Beaglebone group to see what else I may have done to get it to work without sudo.  It too was having that problem but no longer.

With respect to the graphics and LCD displays the issue is more complicated.  The RPi pxl library uses fast SPI io features that require PXL.Boards.RPi.pas and there is no equivalent library of routines for the BBB to directly deal with the hardware registers.  So the BBB will be slower.

However, the \lazarus\pxl\Samples\FreePascal\SingleBoard\Generic\DisplaySPI doesn't use those and now does compile and run on the Beagle.  Just don't have a display connected yet to verify operation and to see if the Lenna.jpg shows up. 

The point is that the pxl spi transfer() function has been fixed so programs using it now work with stretch and buster on the beagle and on the Pi.  I'm still investigating why the FillByte() function is required.

You asked about showing the screen.  I have a small 64x64 bit SPI display.  I also have a PiZeroW with the EnviroPi board with display.  The code is all Python.  I want to port it to Lazarus.  (Actually I also have 320x240 SPI screens and some others).

I also want to port this:https://github.com/botheredbybees/kilnController (https://github.com/botheredbybees/kilnController)
along with it's parent reflow oven controller to Lazarus.

The more of these types of projects out there the more we can bring people into the much easier Delphi/Lazarus programming world.  IMHO.

Title: Re: LCD Displays on Pi or Beaglebone
Post by: engkin on May 26, 2021, 08:50:50 pm
Regarding fpioctl failure, the returned value is important. I just checked the source code (https://github.com/spotify/linux/blob/master/drivers/spi/spidev.c) for spidev. fpioctl is going to end in spidev_ioctl.

spidev_ioctl which it checks for and the errno it could return:
 SPI_IOC_MAGIC ===> -ENOTTY
 access right (_IOC_WRITE in this case) ===> -EFAULT
 device availability ===> -ESHUTDOWN
 correct size: (the size) mod sizeof(struct spi_ioc_transfer) = 0 ===> -EINVAL
 available kernel memory ===> -ENOMEM
 copy the data kernel memory ===> -EFAULT

and finally it executes the command.


As you noted in your previous post, the driver path could be wrong. You might want to correct this code in PXL sample:
Code: Pascal  [Select][+][-]
  1. constructor TApplication.Create;
  2. begin
  3.   FGPIO := TSysfsGPIO.Create;
  4.   FDataPort := TSysfsSPI.Create('/dev/spidev1.0');
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 26, 2021, 09:55:29 pm
Regarding fpioctl failure, the returned value is important. I just checked the source code (https://github.com/spotify/linux/blob/master/drivers/spi/spidev.c) for spidev. fpioctl is going to end in spidev_ioctl.

spidev_ioctl which it checks for and the errno it could return:
and finally it executes the command.


As you noted in your previous post, the driver path could be wrong. You might want to correct this code in PXL sample:
Code: Pascal  [Select][+][-]
  1. constructor TApplication.Create;
  2. begin
  3.   FGPIO := TSysfsGPIO.Create;
  4.   FDataPort := TSysfsSPI.Create('/dev/spidev1.0');

I'll check that error number.

I've tested it with both.  /dev/spidev1.0 and /dev/spi/0.0 and either is fine.  Not sure why the Beagle creates spidev1.0 while the Pi does spidev0.0.  One of those little mysteries I guess.

For now I'm investigating how portable the examples are for the different types of displays.  I've added this into the uses part of DisplaySPI app but at the moment work-work calls...
Code: Pascal  [Select][+][-]
  1. {$IFDEF DISPLAY_ILI9340}  
  2.   PXL.Displays.ILI9340;
  3. {$ELSE}
  4. PXL.Displays.SSD1351;
  5. {$ENDIF}
  6.  

John
Title: Re: LCD Displays on Pi or Beaglebone
Post by: engkin on May 26, 2021, 10:01:35 pm
One of the links (https://www.kernel.org/doc/Documentation/spi/spidev) posted above by Avra explains:
Quote
For a SPI device with chipselect C on bus B, you should see:
/dev/spidevB.C
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 26, 2021, 10:59:48 pm
One of the links (https://www.kernel.org/doc/Documentation/spi/spidev) posted above by Avra explains:
Quote
For a SPI device with chipselect C on bus B, you should see:
/dev/spidevB.C
That document is written for the low level Linux expert and doesn't help someone who has no idea how to 'bind' something.  Nor does it give any clue as to whether it's referring to a Beagle or a Pi or one of the other ARM based systems.  Unfortunately.
For example:
Which one to choose?
pi@raspberrypi:~/projects/lazarus/TC $ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1


Or here:
debian@ebb:~/lazarus/TC$ ls /dev/spi*
/dev/spidev1.0  /dev/spidev1.1  /dev/spidev2.0  /dev/spidev2.1

/dev/spi:
0.0  0.1  1.0  1.1

We know from reading Python programs (and some C examples) that for the Pi we use 0.0.  For the Beagle unless you disable the HDMI you don't have access to the second SPI port so theoretically it should also be 0.0 but not quite...

Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on May 27, 2021, 08:37:16 am
Which one to choose?
pi@raspberrypi:~/projects/lazarus/TC $ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1

Or here:
debian@ebb:~/lazarus/TC$ ls /dev/spi*
/dev/spidev1.0  /dev/spidev1.1  /dev/spidev2.0  /dev/spidev2.1

/dev/spi:
0.0  0.1  1.0  1.1
If we have a system with a single SPI bus where 3 chip select lines are available for that bus, we would have 0.0, 0.1 and 0.2. Choosing one of them will actually just select which one of the 3 predefined chip select lines will be used.

If we have a system with 3 SPI buses where buses 1 and 2 have 2 chip select lines each, while bus 3 has 4 chip select lines, then we would have 0.0 0.1 for the first bus, 1.0 1.1 for the 2nd bus, and 2.0 2.1 2.2 2.3 for the third bus. Choosing to connect our device to 2.3 would mean that we need to take a look at the documentation to find where are SPI3 MOSI/MISO/SCLK pins, and where is SPI3 CE3 pin. So, our software for 2.3 device will work only if we connect it to appropriate pins.

You can find more info here:
https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md
https://www.emcraft.com/stm32f429discovery/accessing-spi-devices-in-linux

I also want to port this:https://github.com/botheredbybees/kilnController (https://github.com/botheredbybees/kilnController)
along with it's parent reflow oven controller to Lazarus.
Nice and useful Pi project, although I would have personally done it with ESP32.

The more of these types of projects out there the more we can bring people into the much easier Delphi/Lazarus programming world.  IMHO.
That's why I decided to bring SocketCAN to FreePascal when I saw in the forum thread (which has started it all) that many tried but gave up because of lack of SocketCAN experience, although I had everything I needed in C and Python already.

Btw. Although PXL has set SPI default speed at 8MHz for the Pi, according to https://elinux.org/RPi_SPI it seams that Pi will actually use 7.8MHz (because of the clock divider 32). You could enable SPI_DIAGNOSTICS define in PXL.Sysfs.SPI.pas to check that on console output. That link also explains how to do SPI loopback test and how to send bytes from command line to SPI.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 27, 2021, 09:02:40 am
Thanks Avra.  I'll check those out.  I was thinking that if I wanted 4 SPI devices I'd use a 2:4 mux with GPIO pins enabled with the SPI0 CS.  But the code has to expressly do that.  I don't think the Beagle by itself can select 1 of 4 SPI devices. 
I used SPI muxing like that on my ELS project.  Schematics accessible by clicking on each green block.
http://www.autoartisans.com/ELS/ (http://www.autoartisans.com/ELS/)

Tonight I connected the small SSD1306-128x64 I2C display.  I edited the pxl sample to point to the correct media folder and for the proper screen size along with i2c-2.  Worked first time. 

The Beagle has 3 I2C ports.
debian@ebb:~/lazarus/TC$ ls /dev/i2c*
/dev/i2c-0  /dev/i2c-1  /dev/i2c-2

At this point i should be able to ready the K Type Thermocouple via SPI and display it on the tiny OLED display.

My goal with the displays and sensors is to be able to create a Window'd type screen that has a an area defined for the display of interest and fields that a user can enter in values that duplicate what comes from SPI sensors.   The paint call would also do the     

// Send picture to the display.
    FDisplay.Present;

So that way I can develop and test on a full size PC fast compile and then when done on the beagle or Pi displays on the HDMI if there but also paints it out to the I2C or SPI display.




Title: Re: LCD Displays on Pi or Beaglebone
Post by: avra on May 27, 2021, 09:22:20 am
I don't think the Beagle by itself can select 1 of 4 SPI devices.
With little trick you can connect as much as you wish:
https://raspberrypi.stackexchange.com/questions/71448/how-to-connect-multiple-spi-devices-adcs-to-raspberry-pi

Schematics accessible by clicking on each green block.
http://www.autoartisans.com/ELS/ (http://www.autoartisans.com/ELS/)
Ah, good old Protel. Brings back some memories...

My goal with the displays and sensors is to be able to create a Window'd type screen
You can still use LCL for such design. You create a form in designer with the same dimensions as your display, and update it in runtime as normal. You just don't show it, and have a thread or timer which periodically transfers bitmap to SPI or I2C display. You can even cache last shown bitmap to decide which display parts do not need an update.
Title: Re: LCD Displays on Pi or Beaglebone
Post by: jcdammeyer on May 27, 2021, 09:40:20 am
My goal with the displays and sensors is to be able to create a Window'd type screen
You can still use LCL for such design. You create a form in designer with the same dimensions as your display, and update it in runtime as normal. You just don't show it, and have a thread or timer which periodically transfers bitmap to SPI or I2C display. You can even cache last shown bitmap to decide which display parts do not need an update.
Exactly.  Instead of having an HDMI that shows the entire desktop for an embedded system we're really just interested in a subset of the main screen.  Hence write to a canvas and as you say, periodically update the SPI/I2C display(s).

For example, on the Beagle, the MachineKit system creates the standard LinuxCNC screen.  What MachineKit provides with trajectory planning etc is fantastic.  But not everyone wants to learn G-Code.  That's why my ELS was useful for some.  An ELS-Mill for milling machines in essence would give power feed to 3 or 4 axis along with simple start stop locations.  Or, and this would be the really great part, to also parse and run G-code when needed.

And I'd use Lazarus for this as the interface to MachineKit instead of Python and other stuff.
TinyPortal © 2005-2018