-
-
Notifications
You must be signed in to change notification settings - Fork 179
neopixel: Support using SPI to send data #771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
One thing I'm unable to test, and is probably quite important for how this would be used out in the wild, is whether it works properly on Pi 4 and older hardware. On the Pi 5 the SPI clock rate is controlled by the RP1's clock, which is fixed at 200MHz. On older Pi hardware the SPI clock is determined by the core clock, so the actual SPI clock rate might be much slower than requested, depending on how the core clock is scaled at the time of sending data. Any suggestions on how to get some willing testers? I'm also unsure of whether sending this direct to Kalico is appropriate, instead of to Klipper? I'm leaving this as draft for a few days as I want to do some final rounds of testing as soon as I get back to the same room as my hardware. I /think/ it's pretty much ready for review, though. |
de86afd to
f4b6e68
Compare
|
For maximum compatibility with WS2812 clones and revisions it is best if 1 bits are high for at least 800ns. You shouldn't need to make the patterns longer. Just switch some 0 to 1. See Klipper3d/klipper#7113 for my reasoning. (Even Klipper's current T1H = 650 is not long enough for my LEDs.) |
Good timing (😉). Actually even easier, I believe running at 4MHz may solve the problem (1us T1H, 1us T1L, 500ns T0H, 1.5us T0L), and that's user-configurable here -- but switching 1 of the 1-bit bits would probably give wider ranges of compatibility. I need to work through the timings again, anyways. I veered away from what the Adafruit libraries were doing because I couldn't find documentation about the reasoning, but I'll look again with an eye towards this, thanks. I'll also use your test macros, looks more thorough than what I'd been doing.
Would you be willing to help test out this patch? |
|
500ns may be too long for T0H. My research seems to indicate 200 to 300 is best, and 400+ will generate bug reports. The general idea of using SPI and DMA to avoid pre-emption trouble on the Raspberry Pi goes back pretty much all the way to the original launch, although I am not sure how well it ever worked. At the moment I can only test on RP2040 as I don't have a stand-alone voltage shifter to use with other boards, other than the one on my SB0000 toolhead breakout. I have the parts to build one on order though. |
|
I put together a spreadsheet to show the different timings from various bit patterns and how they would work out for different SPI data rates: https://docs.google.com/spreadsheets/d/15FCtdJybMRscKh2xRNOzyStjmfH_7MbzbncTJFRtUMw It seems like a default SPI data rate around 5-6MHz and a bit pattern of 2 high bits for a 0 and 5 for a 1 would be a good range, and hopefully the fact that the SPI data rate is configurable by the user would allow even more flexibility for compatibility. WDYT? The main thing I still wanted to check is what exactly happens on the boards I have when you request a SPI rate that the board doesn't support -- I can't remember if both the Pi and STM32 gave the closest possible rate, or some other behaviour. |
I don't know much about the RP2040, but if it supports SPI on the pin you're using for your neopixels that'd be a useful datapoint on a piece of hardware that I don't have (and so haven't tested on). |
|
I have a SB2209/RP2040. The LED port is GPIO16. That's a SPI Rx, so it won't work for me. When I get the parts I can test a generic Pico. I have never touched SPI on RP2040 as PIO is the go to for signal synthesis. Afaik Klipper does not use it because it is arch specific, but it is really powerful. |
This change allows the use of a SPI bus to send correctly timed data to a string of neopixels. The current bitbang approach cannot be used directly from a Raspberry Pi secondary MCU as the bitbang timing is not precise enough. Using the SPI bus to send data to neopixels is a commonly used technique among other open source projects, and seems to work well in Kalico, too. On the devices I have tested (Raspberry Pi 5 and STM32F427) the available SPI speeds work with the data patterns that I have hardcoded, but it is conceivable that it may be necessary to make the data configurable or automatically generated based on requested bus speed in order to support some devices. Signed-off-by: Russell Cloran <[email protected]>
This change allows the use of a SPI bus to send correctly timed data to a string of neopixels.
The bitbang approach cannot be used directly from a Raspberry Pi secondary MCU as the bitbang timing is not precise enough. Using the SPI bus to send data to neopixels is a commonly used technique among other open source projects, and seems to work well in Kalico, too.
On the devices I have tested (Raspberry Pi 5 and STM32F427) the available SPI speeds work with the data patterns that I have hardcoded, but it is conceivable that it may be necessary to make the data configurable or automatically generated based on requested bus speed in order to support some devices.
Checklist