eXoCooLd / Waveshare.EPaperDisplay

.Net Core Library to show images on Waveshare E-Paper Displays
MIT License
30 stars 13 forks source link

GPIO busy - Cs pin in use #17

Open pspeybro opened 2 years ago

pspeybro commented 2 years ago

Hi,

I was trying to test this with a 2.7 inch display on a raspberry pi zero W 2 with .Net 6. I modified the code a little bit to add a config for this display. I have SPI enabled through raspi-config.

If I do this command: sudo cat /sys/kernel/debug/gpio It shows me that a number of GPIO's are in use, and in particular, the SPI pins: gpio-7 ( |spi0 CS1 ) in hi ACTIVE LOW gpio-8 ( |spi0 CS0 ) in hi ACTIVE LOW

I was trying to run the example, but that complained about a missing library for some reason, so I copied the example code to my project to test it. The EPaperDisplayHardware constructor will try to open GPIO8 for the Cs pin and actively control that pin, but this generates an exception because that pin is already claimed for SPI0 CS0 (as the command above indicated).

How come you do not seem to have this issue? Am I missing a setting here?

Would SoftwareSpi work for these kind of displays?

The SpiDevice documentation seems to be lacking some examples or details so it is not easy to find up to date info.

pspeybro commented 2 years ago

If I add an overlay to remap CS0 to another pin (GPIO28): dtoverlay=spi0-1cs,cs0_pin=28

I'm not getting an error, but nothing seems to happen (I suppose I need to work more on the code for this display)

Is this library using the Cs pin as general purpose GPIO or is it using the hardware SPI CS0?

eXoCooLd commented 2 years ago

Looks like the mode of your spi pins is wrong. It is set to "in", but should be "out", is the line "dtparam=spi=on" in your config.txt?

My output on a Pi4: sudo cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-57, parent: platform/fe200000.gpio, pinctrl-bcm2711: ... gpio-7 (SPI_CE1_N |spi0 CS1 ) out hi ACTIVE LOW gpio-8 (SPI_CE0_N |spi0 CS0 ) out hi ACTIVE LOW

The Library talks to the displays over SPI (with System.Device.Spi.SpiDevice) see EPaperDisplayHardware.cs

pspeybro commented 2 years ago

Hi, thanks for the quick response. Yes, I have this in config.txt: dtparam=spi=on Remapping the pin did seem to have a good effect. I updated the DeviceInitialize() method to match the commands in the EPD_2in7.c code and now at least the display is showing something (random noise)

The remapped Cs0 on 28 is shown as an output. If I switch back to just the dtparam=spi=on and reboot: gpiochip0: GPIOs 0-53, parent: platform/3f200000.gpio, pinctrl-bcm2835: gpio-7 ( |spi0 CS1 ) out hi ACTIVE LOW gpio-8 ( |spi0 CS0 ) out hi ACTIVE LOW

Now it is shown as output (not sure whay as input before), but when I run the code, I still get this at the point where it calls: GpioController?.OpenPin(GpioSpiCsPin);

System.IO.IOException: Device or resource busy : '/sys/class/gpio/export' at System.IO.RandomAccess.WriteAtOffset(SafeFileHandle handle, ReadOnlySpan1 buffer, Int64 fileOffset) at System.IO.Strategies.OSFileStreamStrategy.Write(ReadOnlySpan1 buffer) at System.IO.Strategies.BufferedFileStreamStrategy.Flush(Boolean flushToDisk) at System.IO.Strategies.BufferedFileStreamStrategy.Dispose(Boolean disposing) at System.IO.StreamWriter.CloseStreamFromDispose(Boolean disposing) at System.IO.StreamWriter.Dispose(Boolean disposing) at System.IO.File.WriteAllText(String path, String contents) at System.Device.Gpio.Drivers.SysFsDriver.OpenPin(Int32 pinNumber) at System.Device.Gpio.GpioController.OpenPinCore(Int32 pinNumber) at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber) at Waveshare.Common.EPaperDisplayHardware..ctor(SpiDevice spiDevice, GpioController gpioController) in /home/pi/dev/PepperMonitor/Waveshare/Common/EPaperDisplayHardware.cs:line 150 at Waveshare.Common.EPaperDisplayHardware..ctor(GpioController gpio) in /home/pi/dev/Test/Waveshare/Common/EPaperDisplayHardware.cs:line 134 at Waveshare.EPaperDisplay.<>c__DisplayClass4_0.b__0() in /home/pi/dev/Test/Waveshare/EPaperDisplay.cs:line 71 at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue() at System.Lazy1.get_Value() at Waveshare.EPaperDisplay.CreateEPaperDisplay(EPaperDisplayType displayType, GpioController gpio) in /home/pi/dev/Test/Waveshare/EPaperDisplay.cs:line 110 at Waveshare.EPaperDisplay.Create(EPaperDisplayType displayType, GpioController gpio) in /home/pi/dev/Test/Waveshare/EPaperDisplay.cs:line 72

(note I modified it a little for me to pass an existing GpioController object instead of initialzing a new one)

I will see if I can get it working using the remapped pin. From what I see in the code, you seem to use GPIO8 as any other standard GPIO, since you drive that pin manually.

eXoCooLd commented 2 years ago

The Waveshare C Examples did the combo of SPI and direct Pin set for Command / Data (see EPaperDisplayBase.SendCommand / SendData)

Maybe the 2.7 inch Display did not need this.

But i have no idea why your existing GpioController is busy (try with a new one just for testing).

thomasgalliker commented 2 years ago

Guys, I'm was struggling with exactly the same issue yesterday evening :) I'm pretty much a beginner when it comes to GPIO and hardware-oriented programming. Can you let me know which commands you issued on the Raspberry Pi 4 to switch the Pins from "in" to "out"?

eXoCooLd commented 2 years ago

Should be the line "dtparam=spi=on" in the config.txt on the Raspbery Pi. On my Pi4 I never encounterd that problem.

The "Quick Setup" guide in the Wiki should work for existing displays.

pspeybro commented 2 years ago

Unfortunately, I don't know what made it switch from input to output... At this moment I am experimenting to get the 2in7 display going with the remapped pin, since the code (as well as the example C code) seems to use the Cs pin as general GPIO.

So far I updated the Init method with the commands from the corresponding C code and now I can at least start the display and clear the screen or set it to full black. Drawing an image is not working yet.

I noticed that the C code also has a bunch of other methods to draw lines or text, do partial updates that seem to be missing in this library, but at least I am getting somewhere.

thomasgalliker commented 2 years ago

I followed all the steps mentioned in the Wiki page (thanks!) and I enabled the SPI (dtparam=spi=on). Still, it fails to OpenPin. I can remember that your code worked, when I reconfigured the csproj to work with .NET framework (instead of .NET). Very strange.

pi@raspberrypi:~/waveshare_demo $ dotnet Waveshare.Example.dll
Initializing E-Paper Display...Unhandled exception. System.IO.IOException: Device or resource busy : '/sys/class/gpio/export'
   at System.IO.RandomAccess.WriteAtOffset(SafeFileHandle handle, ReadOnlySpan`1 buffer, Int64 fileOffset)
   at System.IO.Strategies.OSFileStreamStrategy.Write(ReadOnlySpan`1 buffer)
   at System.IO.Strategies.BufferedFileStreamStrategy.Flush(Boolean flushToDisk)
   at System.IO.Strategies.BufferedFileStreamStrategy.Dispose(Boolean disposing)
   at System.IO.StreamWriter.CloseStreamFromDispose(Boolean disposing)
   at System.IO.StreamWriter.Dispose(Boolean disposing)
   at System.IO.File.WriteAllText(String path, String contents)
   at System.Device.Gpio.Drivers.SysFsDriver.OpenPin(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPinCore(Int32 pinNumber)
   at System.Device.Gpio.GpioController.OpenPin(Int32 pinNumber)
   at Waveshare.Common.EPaperDisplayHardware..ctor(SpiDevice spiDevice, GpioController gpioController) in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare\Common\EPaperDisplayHardware.cs:line 145
   at Waveshare.Common.EPaperDisplayHardware..ctor() in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare\Common\EPaperDisplayHardware.cs:line 129
   at Waveshare.EPaperDisplay.<>c.<.cctor>b__6_0() in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare\EPaperDisplay.cs:line 55
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Waveshare.EPaperDisplay.CreateEPaperDisplay(EPaperDisplayType displayType) in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare\EPaperDisplay.cs:line 105
   at Waveshare.EPaperDisplay.Create(EPaperDisplayType displayType) in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare\EPaperDisplay.cs:line 70
   at Waveshare.Example.Program.Main(String[] args) in C:\src\github\eXoCooLd\Waveshare.EPaperDisplay\Waveshare.Example\Program.cs:line 58
Aborted
pspeybro commented 2 years ago

@thomasgalliker , can you try with adding this line to config.txt? dtoverlay=spi0-1cs,cs0_pin=28

This will remap the CS0 pin to GPIO28, so that the library can actually use the pin directly.

eXoCooLd commented 2 years ago

Very strange, maybe a OS / Framework change?

What do you guys run on your PIs?

pi@raspberrypi:~ $ dotnet --version 6.0.101 pi@raspberrypi:~ $ uname -a Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux

pspeybro commented 2 years ago

$ dotnet --version 6.0.101 $ uname -a Linux malina 5.10.92-v7+ #1514 SMP Mon Jan 17 17:36:39 GMT 2022 armv7l GNU/Linux

eXoCooLd commented 2 years ago

I did a system upgrade now, but my Display is still working. Can you try o upgrade to the current version too?

sudo apt update sudo apt full-upgrade sudo rpi-update

pi@raspberrypi:~ $ uname -a Linux raspberrypi 5.15.23-v7l+ #1525 SMP Wed Feb 16 14:35:14 GMT 2022 armv7l GNU/Linux

Do you run other GPIO Things on your pi?

thomasgalliker commented 2 years ago

My Raspberry 4 Model B 2GB dumps following:

i@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.92-v7l+ #1514 SMP Mon Jan 17 17:38:03 GMT 2022 armv7l GNU/Linux
pi@raspberrypi:~ $ dotnet --version
6.0.200
pi@raspberrypi:~ $ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.200
 Commit:    4c30de7899

Runtime Environment:
 OS Name:     raspbian
 OS Version:  11
 OS Platform: Linux
 RID:         linux-arm
 Base Path:   /home/pi/dotnet/sdk/6.0.200/

Host (useful for support):
  Version: 6.0.2
  Commit:  839cdfb0ec

.NET SDKs installed:
  5.0.405 [/home/pi/dotnet/sdk]
  6.0.200 [/home/pi/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 5.0.14 [/home/pi/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.2 [/home/pi/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 5.0.14 [/home/pi/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.2 [/home/pi/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download
thomasgalliker commented 2 years ago

@pspeybro your advice resolved the problem, now the image is displayed :) dtoverlay=spi0-1cs,cs0_pin=28

AWESOME. But what does this dtoverlay do and why do I have to do this manually? Just to give the complete picture: I'm using a WaveShare7In5_V2 display type and I did checkout @eXoCooLd master branch, which is currently targeting net6.0. Hmm weird...

eXoCooLd commented 2 years ago

Thats interesting, do you use the Raspberry PI OS from: https://www.raspberrypi.com/software/operating-systems/

If Yes, which Image did you use?

thomasgalliker commented 2 years ago

@eXoCooLd yes, I used the original Raspberry Pi Imager to flash the sdcard. I tried following two operating systems, both had this "is busy" issue:

The 32bit version is the one I have installed now.

eXoCooLd commented 2 years ago

Ok I will try a clean new Installation on the weekend. I hope we find that difference.

pspeybro commented 2 years ago

@thomasgalliker by default, the hardware spi cs0 pin is on gpio8. The dtoverlay line remaps this to a gpio for which there is no pin on the 40-pin header (gpio28). The reason I did this, was because this library and the waveshare example code in C are actively opening the gpio8 pin and setting it high/low, as if it was any other gpio. I'm not really familiar with hardware SPI with chip select, but this does not seem to be the way CS0 is supposed to be used.

@eXoCooLd , yes, i am using other gpio's, in fact, almost all are used for 8 relays, 1-wire, an mcp3008 ADC through software spi, some devices on I2C bus and the 2in7 display.

eXoCooLd commented 2 years ago

Ok I did a clean installation on a other sd-card and now I got the same problem. With the dtoverlay I could fix the issue too. So there must be a change in the OS configuration :-|