jgarff / rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs
BSD 2-Clause "Simplified" License
1.78k stars 622 forks source link

Support for Raspberry Pi 5 #528

Open Puetz opened 11 months ago

Puetz commented 11 months ago

Hi,

I just got a Raspberry Pi 5 and am getting an error that my hardware revision is not supported.

Here is some hardware information from cat /proc/cpuinfo:

Hardware    : BCM2835
Revision    : c04170
Model       : Raspberry Pi 5 Model B Rev 1.0

I also ran this coding to get paddr=10, baddr=C0000000.

I hope someone can use this information to add a new hardware type and support for the Raspberry Pie 5 πŸ™‚ I unfortunately don't know C and have no clue about hardware, so I can't create a PR myself.

Best regards, Thomas

mehrdadfeller commented 8 months ago

Would it be possible to use cortex m3 to run a custom firmware at boot time? If so, this can be quite valuable and can solve several problems:

For example the MCU could drive GPIO and SPI/I2C buses before the Pi boots up (since the boot up can take sometimes around 20 seconds). For example if you have screen, mcu can show a splash or some message to the user.

More importantly, MCU could be used as a fallback options to perform some sort of system recovery if OS is corrupt...

These are ofcourse not related to the specific use case here though

On Tue, Feb 6, 2024, 10:16β€―AM Michael Bishop @.***> wrote:

oh, and i forgot about @G33KatWork https://github.com/G33KatWork 's older stuff, before @MichaelBell https://github.com/MichaelBell found the core0 hack

https://github.com/G33KatWork/RP1-Reverse-Engineering

basically, you can just hard-reset the entire RP1, and re-load the core0 and core1 firmware over i2c, and reboot it that would have better compatibility with the core0 firmware both because your not patching it, and because you choose which core0 version is in use

but linux currently doesnt handle removal of the rp1 cleanly so you need a dtoverlay that disables the rp1, reset it, then a runtime dtoverlay to allow rp1 access and you can only do that once per host boot, so linux has to reboot to do it again

β€” Reply to this email directly, view it on GitHub https://github.com/jgarff/rpi_ws281x/issues/528#issuecomment-1930021595, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4CVJSGZ74RYD3QX36SQ7LYSJCN5AVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZQGAZDCNJZGU . You are receiving this because you were mentioned.Message ID: @.***>

cleverca22 commented 8 months ago

the pi5 goes thru a few phases during boot first it loads a bootcode.bin from SPI flash, and executes it, that brings the dram controller online then it loads bootmain.elf from SPI, and executes it, that deals with booting the whole system, and replaces the old start(4).elf bootmain then has an rp1 firmware baked within its .rodata, it will push that over i2c to the rp1, and confirm its working, before moving on to starting the arm core

that whole chain, is signed with an unknown mechanism at the root, so any attempt to modify it will just result in the pi5 not booting

but once something is running on the main cortex-a76 core, it can just take over the gpio, hard-reset the RP1, and push anything it wants over i2c

@G33KatWork 's repo includes examples of doing that from linux, and i believe its possible to push the original core0 firmware, plus something custom for core1 in theory, you could modify u-boot into doing that as well, so core1 is doing something before linux has even been read from the card

but it cant really be used as a fallback, because you need an arm kernel on the bootfs, to hijack the RP1

but with the pi0-pi3 family, you can run https://github.com/librerpi/lk-overlay as a firmware replacement then you can add whatever custom splash screen you want on any interface you can write drivers for

sadly, the pi5 has the VPU locked down even more then ever, and the open firmware may just never be an option for the 5

jgarff commented 8 months ago

It's interesting that they opted for loading the RP1 over I2c instead of having a small ROM. Makes sense though in that they can always program it from the bootloader of the BCM.

cleverca22 commented 8 months ago

having decompiled the RP1 boot rom, it supports booting in either i2c-slave mode, or spi-master mode so they could have put a second spi chip on the board, and bootstrap the rp1 from that

but that would then drive up the cost of the whole assembly same reason they ditched the vl805 spi chip

willmorris04 commented 7 months ago

It's interesting that they opted for loading the RP1 over I2c instead of having a small ROM. Makes sense though in that they can always program it from the bootloader of the BCM.

Hi jgarff, I appreciate the effort you are making to update the ws281x library. I was wondering if there is a simple way to control the led I have. I only want to turn it on and off at full brightness white. I'm a beginner to microprocessors and would really appreciate some advice. Thanks

jgarff commented 7 months ago

Unfortunately, it's not easy to simply turn on one LED, or any color, without sending the wire protocol. The same basic logic is needed to turn on 1 or 1000.

stephinson commented 7 months ago

It's interesting that they opted for loading the RP1 over I2c instead of having a small ROM. Makes sense though in that they can always program it from the bootloader of the BCM.

Hi jgarff, I appreciate the effort you are making to update the ws281x library. I was wondering if there is a simple way to control the led I have. I only want to turn it on and off at full brightness white. I'm a beginner to microprocessors and would really appreciate some advice. Thanks

You can try SPI to turn on/off LEDs

https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel_SPI/issues/37#issuecomment-1871698900

Lukas200011 commented 7 months ago

I would also be very interested to get ws28xx to work with a Raspberry Pi 5. What is the current situation of fixing this issue and future plans? I don't want to rush you with this post, I am just curious. :) Have a nice week!

hannescam commented 6 months ago

Is there some progress with supporting the RPi5 because in one of my projects I need the processing power of the pi and control 10 separate strips with low latency.

jgarff commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Gadgetoid commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's.

AFAIK first party support for WS281X is still a distinct possibility but we can only sit on our hands and wait, and have no idea exactly how it might perform.

hannescam commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

Gadgetoid commented 6 months ago

Would be interesting to know if a plain SPI bridge chip would have the throughput required. I’d just use a bunch of RP2040 (Pico) boards since they could update potentially thousands of LEDs continuously from an internal buffer.

Had no problem running ~12,000 LEDs split across 20 USB devices from one Pi using RP2040s- https://youtu.be/cm83RIhDbwo?si=fFB7bMm1-oSSfV8Y&t=10m48s

Finn1994 commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night. Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

hannescam commented 6 months ago

Would be interesting to know if a plain SPI bridge chip would have the throughput required. I’d just use a bunch of RP2040 (Pico) boards since they could update potentially thousands of LEDs continuously from an internal buffer.

Had no problem running ~12,000 LEDs split across 20 USB devices from one Pi using RP2040s- https://youtu.be/cm83RIhDbwo?si=fFB7bMm1-oSSfV8Y&t=10m48s

As far as the datasheet is concerned it is fast egnuth and is a bit cheaper than a bunch of Pi Picos (and I hate the idea to make a firmware for them). I am using these chips: CY7C65214D-32LTXI on a custom board that isn't finished yet but i will report my success and my setup used when I receive the board

hannescam commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night. Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that? Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Finn1994 commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that?

Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Yes, I mean the driver to get the strip running on Pi 5. The neopixel library I downloaded worked on Pi 4 but not Pi 5. and can I get two strips running with pi 5?

hannescam commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that? Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Yes, I mean the driver to get the strip running on Pi 5. The neopixel library I downloaded worked on Pi 4 but not Pi 5. and can I get two strips running with pi 5?

You can drive one strip from SPI on the Pi 5 but not 2 then you need to wait for the PWM driver but you can but them in series in the meanwhile

KlausDecOpt commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that? Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Yes, I mean the driver to get the strip running on Pi 5. The neopixel library I downloaded worked on Pi 4 but not Pi 5. and can I get two strips running with pi 5?

You can drive one strip from SPI on the Pi 5 but not 2 then you need to wait for the PWM driver but you can but them in series in the meanwhile

We would like to drive one strip of WS2812B using Python on a RPI5. Our current solution is using https://pypi.org/project/rpi-ws281x/ with SPI0-MOSI / GPIO 10 on a RPI4b. You are stating "You can drive one strip from SPI on the Pi 5" and thus our question is how do you do this?

hannescam commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that? Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Yes, I mean the driver to get the strip running on Pi 5. The neopixel library I downloaded worked on Pi 4 but not Pi 5. and can I get two strips running with pi 5?

You can drive one strip from SPI on the Pi 5 but not 2 then you need to wait for the PWM driver but you can but them in series in the meanwhile

We would like to drive one strip of WS2812B using Python on a RPI5. Our current solution is using https://pypi.org/project/rpi-ws281x/ with SPI0-MOSI / GPIO 10 on a RPI4b. You are stating "You can drive one strip from SPI on the Pi 5" and thus our question is how do you do this?

Sadly this library won't work because even if it is in SPI mode it checks the Pi model that means you need to modify this library slightly to use it with the Pi 5 over SPI but I found another NeoPixel library that will work for the Pi 5 (I have tested it) py-neopixel-spidev I hope this helps :)

androdev88 commented 6 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux is that confirmed I can't find anything in DRAFT document for RP1. If this is true it might be a huge downgrade from RPi 3B which can easily drive 16,000 LED at 30 FPS with SMI and DMA.

If we could use Cortex-M DMA and PIO to push data to port at specific rate it could be possible to implement it by using the shared SRAM it looks like there is 64k, we could create 2 buffers like 16kB each and use one of them to push data via Cortex-M DMA to PIO while the main CPU would use DMA to push data via PCIe to the second buffer.

Since the main CPU is much faster the Cortex-M should never run out of data. The only thing that might be challenging is the timing when switching between buffers e.g. if cortex DMA can't push data directly from shared SRAM and would have to copy to local SRAM, the WS281X is quite strict and any delay in transmission would reset writing back to first LED, but maybe we could use 2 DMA channels in this case one shared SRAM -> Cortex-M SRAM, the other for PIO.

I can't find any info about Cortex-M but if we could clock it to match WS281x 400ns pulse we could use only 3 bits per pulse which would use about 24kB for 1000 led in 8 channels which would alleviate the problem of delay when switching between buffers as two of these frames will fit in 64kB shared SRAM, while it is only half of what RPi 3 can do it is a good start. We could later look at dual core Cortex-M operation and use some of the 32kB non shared SRAM, with which maybe we could push 16 channels of 1000 LED at 30 FPS.

Sadly without RP1 documentation around Cortex-M all of this is speculation.

jakobi commented 6 months ago

Just following this thread, and noting that this is not mentioned in any of the rp1 links to prior work:

There's an old forum thread on spi access via registers rather than spidev; https://forums.raspberrypi.com/viewtopic.php?t=365275

and praktronic's March 2024 reply with his repos, which may help (last message):

https://github.com/praktronics/rpi5-rp1-spi https://github.com/praktronics/rpi5-rp1-gpio

At a glance by a non-expert here, he doesn't bother with rp1 firmware at all, but just uses some offsets from the rp1 docs+reverse-engineering efforts (bar offset, iobank base) to get userland memory access to the registers. Would it be possible to use say DMA from the Cortex-A cores with this, maybe even some pio-access?

hannescam commented 5 months ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

Okay I might switch to USB-SPI bridge chips connected via USB through an USB HUB to the RPi5 with your driver (I saw that your driver supports SPI) but when the driver is ready (full PIO support) i will switch to the direct output of the RPi5

How could I download the driver and use it? And what do I need?

What do you mean by that? Do you mean the driver to drive the NeoPixels over SPI? Because that I got working on a Pi 5 (1 strip with an Adafruit NeoPixel SPI library)

Yes, I mean the driver to get the strip running on Pi 5. The neopixel library I downloaded worked on Pi 4 but not Pi 5. and can I get two strips running with pi 5?

You can drive one strip from SPI on the Pi 5 but not 2 then you need to wait for the PWM driver but you can but them in series in the meanwhile

We would like to drive one strip of WS2812B using Python on a RPI5. Our current solution is using https://pypi.org/project/rpi-ws281x/ with SPI0-MOSI / GPIO 10 on a RPI4b. You are stating "You can drive one strip from SPI on the Pi 5" and thus our question is how do you do this?

Sadly this library won't work because even if it is in SPI mode it checks the Pi model that means you need to modify this library slightly to use it with the Pi 5 over SPI but I found another NeoPixel library that will work for the Pi 5 (I have tested it) py-neopixel-spidev I hope this helps :)

I use now the spidev of the pi with my own library and it works well :)

ikke01 commented 5 months ago

Hallo Jeremy,

We use the application on a 512pixel display, we want to update to a 2048 display to have a higher light intensity, but running the routines in python for the 2048 on the pi4 4gb runs out of memory/cpu.

I understood the 2811 controller also has an option to send more leds’ per pixel

Do you know if this is possible, this would allow us to keep using the 512 pixel routines but use 2048 leds or possibly more

Thanks Raymond

From: Jeremy Garff @.> Sent: Tuesday, 12 March 2024 16:27 To: jgarff/rpi_ws281x @.> Cc: Raymond Garnier @.>; Manual @.> Subject: Re: [jgarff/rpi_ws281x] Support for Raspberry Pi 5 (Issue #528)

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in a easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

β€” Reply to this email directly, view it on GitHubhttps://github.com/jgarff/rpi_ws281x/issues/528#issuecomment-1991917997, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEFBLSN3Z3VQEFVUUXVJBU3YX4NEJAVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOJRHEYTOOJZG4. You are receiving this because you are subscribed to this thread.Message ID: @.**@.>>

ikke01 commented 3 months ago

Hallo jeremy

Would this be a possible workaround , would this be working with you solution.

https://www.hackster.io/nickbild/add-python-programmable-gpio-pins-to-any-computer-3b0259

Thanks Raymond

Sent from Outlook for Androidhttps://aka.ms/AAb9ysg


From: Jeremy Garff @.> Sent: Thursday, January 18, 2024 12:33:43 AM To: jgarff/rpi_ws281x @.> Cc: Raymond Garnier @.>; Manual @.> Subject: Re: [jgarff/rpi_ws281x] Support for Raspberry Pi 5 (Issue #528)

Unfortunately no. Setting any color at all requires transferring a complicated sequence of signals over the wire. The timing required for these signals isn't possible from a software only implementation on Linux due to context switches, driver interrupts, etc..

On Wed, Jan 17, 2024 at 4:25β€―PM felixfeliciz @.***> wrote:

Until then, is there any way to use the WS2812B with a limited range of functions, such as simple switching on and off or simple color changes without fancy gradients or animations?

β€” Reply to this email directly, view it on GitHub https://github.com/jgarff/rpi_ws281x/issues/528#issuecomment-1897423871, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACB55G4J56P375UBL3ZOGW3YPBMXZAVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJXGQZDGOBXGE . You are receiving this because you were mentioned.Message ID: @.***>

β€” Reply to this email directly, view it on GitHubhttps://github.com/jgarff/rpi_ws281x/issues/528#issuecomment-1897461130, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEFBLSLYJAXHTZBCHMIOPF3YPBNVPAVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJXGQ3DCMJTGA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

hannescam commented 3 months ago

Hallo jeremy Would this be a possible workaround , would this be working with you solution. https://www.hackster.io/nickbild/add-python-programmable-gpio-pins-to-any-computer-3b0259 Thanks Raymond Sent from Outlook for Androidhttps://aka.ms/AAb9ysg ____ From: Jeremy Garff @.> Sent: Thursday, January 18, 2024 12:33:43 AM To: jgarff/rpi_ws281x @.> Cc: Raymond Garnier @.>; Manual @.> Subject: Re: [jgarff/rpi_ws281x] Support for Raspberry Pi 5 (Issue #528) Unfortunately no. Setting any color at all requires transferring a complicated sequence of signals over the wire. The timing required for these signals isn't possible from a software only implementation on Linux due to context switches, driver interrupts, etc.. On Wed, Jan 17, 2024 at 4:25β€―PM felixfeliciz @.> wrote: Until then, is there any way to use the WS2812B with a limited range of functions, such as simple switching on and off or simple color changes without fancy gradients or animations? β€” Reply to this email directly, view it on GitHub <#528 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACB55G4J56P375UBL3ZOGW3YPBMXZAVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJXGQZDGOBXGE . You are receiving this because you were mentioned.Message ID: @.> β€” Reply to this email directly, view it on GitHub<#528 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEFBLSLYJAXHTZBCHMIOPF3YPBNVPAVCNFSM6AAAAAA65QFT3CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJXGQ3DCMJTGA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

Yes and no: You will need to rewrite the SPI or PWM function for the library to work with the USB GPIO expander (try to find one with a fast SPI interface)

Gadgetoid commented 3 months ago

I am begging people just to use a microcontroller 😭

The RP2040 has enough RAM to double buffer 34,000 pixels and you can make up any USB, UART, SPI or I2C protocol you want to talk to it.

MoffKalast commented 3 months ago

I am begging people just to use a microcontroller

Okay sure, then we can also use something else like a N100 with UART. Why keep using the Pi if the GPIO header is just there as decoration amirite? I paid for the whole Pi and I'm gonna use the whole Pi πŸ˜ƒ

androdev88 commented 3 months ago

The RP2040 has enough RAM to double buffer 34,000 pixels and you can make up any USB, UART, SPI or I2C protocol you want to talk to it.

you are unlikely to be anywhere near driving this many pixels from RP2040, the data rate needed at 30 FPS is 3MB/s, SPI slave is max 10MHz, USB speed is in 800-900 kB/s range.

Jezorko commented 3 months ago

Since this library is still not updated, and I couldn't find a single working solution, I used praktronic's code mentioned in this comment to try and drive my WS281b strip with SPI.

https://github.com/Jezorko/rpi5-ws2812x-fu/releases/tag/testing_10MHz - here is a working example. If you build and run as root, while your strip is plugged to GPIO 10 (MOSI), it should work. The repository is a mess but then again, it's only a temporary hack until any one of the libraries gets updated. glhf

hannescam commented 3 months ago

Since this library is still not updated, and I couldn't find a single working solution, I used praktronic's code mentioned in this comment to try and drive my WS281b strip with SPI.

https://github.com/Jezorko/rpi5-ws2812x-fu/releases/tag/testing_10MHz - here is a working example. If you build and run as root, while your strip is plugged to GPIO 10 (MOSI), it should work. The repository is a mess but then again, it's only a temporary hack until any one of the libraries gets updated. glhf

I have also made a generic SPI neopixel library that is tested against the Pi 5 and it is also pretty generic so it would work on any computer with an spidev: https://github.com/hannescam/NeoSPI

ddeliopoulos commented 3 months ago

@Jezorko Thank you for your service :vulcan_salute:

vasylenkoserhii commented 2 months ago

Since this library is still not updated, and I couldn't find a single working solution, I used praktronic's code mentioned in this comment to try and drive my WS281b strip with SPI.

https://github.com/Jezorko/rpi5-ws2812x-fu/releases/tag/testing_10MHz - here is a working example. If you build and run as root, while your strip is plugged to GPIO 10 (MOSI), it should work. The repository is a mess but then again, it's only a temporary hack until any one of the libraries gets updated. glhf

Thanks for your work - this code work to some extent. I've found that bits order in lookup_table is opposite to correct one, so when one tried to increase one value say RED from 0 to 255 it will not produce smooth color increase. Changing data sending loop to something like this in rp1-spi.c fixes the issue:

    for (int data_byte = 0; data_byte < data_length; ++data_byte) {
      for(int bit_num = 7; bit_num >= 0; bit_num--) { 
        for (int bits_byte = 0; bits_byte < 2; ++bits_byte) {
            // put the data into the fifo 
            *(volatile uint8_t *)(spi->regbase + DW_SPI_DR) = lookup_table[data[data_byte]][bit_num*2+bits_byte];
            // we now need to pull exactly one byte out of the fifo which would
            // have been clocked in when we wrote the data
            /*uint8_t discard = */*(volatile uint8_t *)(spi->regbase + DW_SPI_DR);
        }
      }
    } 

Unfortunately I also see periodically it sporadically set some unexpected colors. It looks like flickering when colors changed constantly.

JustBKen commented 1 month ago

Any Updates on PWM support?

mehrdadfeller commented 1 month ago

Sadly, the PIO IP in the RP1 doesn't allow for direct access from Linux, and is instead only controllable through the RP1 Cortex-M's. While that is the best long term goal, it's far more complicated, especially in an easily deployable library. In the short term I've written a kernel driver using PWM instead. It's not quite done, but I'm getting closer. I got some waveforms on my scope last night.

Unfortunately, the PWM won't be able to control 10 separate strips at the same time. The RP1 has 2 PWM instances, but one is dedicated to fan control, leaving us with only one 4 channel PWM. In this case 4 strips would be the max.

@jgarff this sounds quite promising. Would you be able to share the existing code base even though still being work in progress and incomplete? I think it can help others jump into it and contribute.

Jezorko commented 1 month ago

@vasylenkoserhii I think the strip I am using has a different bit ordering from yours... ideally, to accomodate possible strip models, a library would offer a configuration of:

  1. LED strip frequency 400Hz and 800Hz
  2. endianness
  3. color order (RGB / GRB / white component)
  4. … probably a ton of other things that I'm not even aware of
vanshksingh commented 2 weeks ago

I will probably contribute to this repo too , but i just wrote an RPi5 specific lib for now pi5neo

muningis commented 2 weeks ago

@vanshksingh FYI - the link is broken (it leads to /issues/ of this repo)

vanshksingh commented 2 weeks ago

@muningis thank you ! I fixed it , it seems you have to affix the link to an word for it work sensibly

c0bra-dev commented 1 week ago

Hi everyone! For a small project I needed a single WS2812B LED running off a standard GPIO on a Raspberry PI 5 with the RP1 chip and I ended up writing some C++ code to do so.

I was able to successfully pull it off by using some timers and the WiringPi library.

I had to edit the timers with an oscilloscope, and discovered there is a sort of wake up time for the RP1 of about 3.5 us, after wich timings are quite accurate. After compensating I was left with a quick and dirty solution to my problem.

I dont expect this to be able to run any kind of large matrix, but if anybody finds it useful, this is the link to my repo with the code:

https://github.com/c0bra-dev/TIMED2812

zytegalaxy commented 1 week ago

@c0bra-dev this is awesome! have you had a chance to try this with more than a single LED? From my understanding, the WS2812B LEDs can tolerate +/-150ns which is quite a wide range compared to the absolute 800ns/400ns pulse width.

I also have a question about your oscilloscope measurement. In your code, you set the T1H value to 680ns. What value does that give you on oscilloscope? 800ns? Is there a linear relationship between timer value and observed value, meaning if you increase T1H by 20ns, does that really increase pulse width by 20ns? Does the load on CPU impact the timings?

#define T1H 680 // Ideal time 800

c0bra-dev commented 1 week ago

@zytegalaxy Thanks! Yes, 680ns on the timer is around 800 ns measured on my oscilloscope. I think there is a fixed value difference of around 100ns between the timer and the real IO operation. It seems linear and it's unexpectedly accurate, so much that I am impressed. For instance on the 400ns i think we have something like +-10ns jitter over 10 different measurment regardless of CPU load (tried running stress --cpu 4)

Wake up times seems random, probably related to both CPU load and RP1 load, and makes the first bit timings unreliable. I edited the code to wake up the RP1 using a very small pulse (20ns) before the start of the sequence and then wait for a reasonable time before starting the sequence, With this edit now also the first bit works like a charme. This init pulse is so fast it gets ignored by the WS2812, and allows to make sure RP1 is responsive to the real sequence. Just tried with 24 LEDS and it's working like a charm.

I update the repo with the revisited code.

SvOlli commented 1 week ago

I just did a short run trying it on the "Waveshare True Color RGB LED pHAT 4x8" (8x4 LED matrix in zero form factor). The transmit looped was just wrapped with another loop that does send 32 times the same data. It's working like 80% of the time. My guess is process scheduling breaks the timing. However, now that it's working to some extend, I can offer to run different tests.

c0bra-dev commented 1 week ago

@SvOlli can you please double check my work on the edited code? I think the problem you are encountering is with the way I used to handle the first bit

SvOlli commented 1 week ago

Already on it. I found a glitch and managed to make it more visible, by changing the line 71 to: color_matrix[i] = colorWheel((colorPos + (i * 256 / LED_NUMBER)) & 255) & 0x070707; This way I could see that there's a bright white flash once in a while. This problem can be intensified by running 7z b in another terminal (7z benchmark). So there's still the scheduler interrupting the transfer every once in a while.

c0bra-dev commented 1 week ago

What about moving the code to a LKM? I might work on it on the next days if you think it's a good idea.

SvOlli commented 1 week ago

@c0bra-dev : if you've got something, I can test it.

zytegalaxy commented 1 week ago

@c0bra-dev Beautiful! I tested it with 27 LEDs on pin GPIO12 and it works well.

https://github.com/user-attachments/assets/b6bd823c-030d-4012-a2e3-d114c9a6fe2c

However, under stress as @SvOlli also suggested, the timings change a bit and introduce white flickers as you can see in video below:

test@ubo-3w:~ $ stress --cpu 8 --io 4 --vm 4 --vm-bytes 1024M --timeout 10s

https://github.com/user-attachments/assets/8944fd27-b549-4c38-b14c-805e71c03ebc

I investigated making a LKM, but the issue is that we cannot use WiringPi anymore and we have use linux libraries and directly drive GPIOs with registers etc which I have not done before. Perhaps @jgarff can give us some guidance on that.

zytegalaxy commented 1 week ago

@c0bra-dev I investigated the stress scenarios further and seems like cpu and io stress do not impact the led patterns but memory parameter --vm does. So If I do:

stress --cpu 4 --io 4

no visible effect on LED patterns can be seem. But if I add --vm, then I see the white flicker:

stress --cpu 4 --io 4 --vm 1
c0bra-dev commented 1 week ago

I investigated further by adding priority to the process, and went as far as having an isolated core dedicated to the program but the problem persist. Oscilloscope shows huge jitter.

LKM is probably the only way.