Skip to content
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

SPI frequency changes when cpu is throttled #194

Open
hungerpirat opened this issue Jun 6, 2017 · 12 comments
Open

SPI frequency changes when cpu is throttled #194

hungerpirat opened this issue Jun 6, 2017 · 12 comments

Comments

@hungerpirat
Copy link

hungerpirat commented Jun 6, 2017

I have been playing around with the SPI mode on a RPi3.
my config:

my LEDs configuration:
LED_COUNT = 7 # Number of LED pixels.
LED_PIN = 10 # MISO (SPI)
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
LED_DMA = 5 # DMA channel to use for generating signal (try 5)
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)

Running the test script:
In the oscilloscope I see a proper signal, but the frequency is at 500kHz, all LEDs are white.
If I put some load on the RPi3 cpu, it switches to the specified 800kHz and I see the rainbow like expected.
Once the cpu load has been gone, it switches back to 500kHz and all LEDs are white again.

Maybe this bug is related to #184

@hungerpirat
Copy link
Author

Just checked the cpu frequency while running the test. The phenomenon is clearly related to the cpu throttling state.

@hungerpirat
Copy link
Author

hungerpirat commented Jun 6, 2017

more test results:

Setting LED_FREQ_HZ to 1200000 works in both cpu speeds 600MHz and 1.2GHz. The resulting SPI frequencies are 600kHz, respectively 1.2MHz.
The data sheet of ws281x LEDs mentions bit timings of 1.25µs with ±600ns tolerance. The calculated valid freq range is 540kHz to 1.5MHz and includes both of the frequencies above.

@penfold42
Copy link
Contributor

Strictly speaking it's the core clock speed changes that cause this.

The SPI hardware is set by a divisor and the kernel uses the core clock speed when the device is opened to calculate this.

The clock governors then mess with this to save power and temperature which inadvertently impacts the spi clock.

The best solution is for the kernel to also recalculate the divisor.

One workaround is to force_turbo=1

@hungerpirat
Copy link
Author

hungerpirat commented Jun 7, 2017 via email

@penfold42
Copy link
Contributor

The kernel should be doing it - user space asks for a speed and at the moment, this isn't guaranteed.

Something to investigate is repeatedly opening and closing the device on every write.
Assuming there's no great overhead, this should work better.
If changes happen I'd write, it won't help for that update tho.

@penfold42
Copy link
Contributor

@hungerpirat
Copy link
Author

thanks - that's very helpful.
If I will find some time, I will test your proposal about opening the device every time.

@penfold42
Copy link
Contributor

I don't think it works - I tried it with Hyperion.

Re-reading the responses to the other issue implies that the spi subsystem is lied to with the highest possible core clock frequency - it doesn't appear to be a dynamic.

@wheresthecode
Copy link

I was running off PWM but am trying to switch to SPI to free up PWM for audio. I added core_freq=250 to /boot/config.txt which seems to work. However, I've noticed that all the colors are incorrect.

I think the signal is getting shifted because if I try to set the LEDs to red, I will get all yellow LEDs except the first LED will be white.

I'm on a pi3, python 2.7. LED frequency is set to 800000. Coloring order is WS2811_STRIP_GRB which worked as expected using PWM and GPIO pin 18.

Any ideas how to correct this color shift?

@pwr33
Copy link

pwr33 commented Nov 26, 2018

I'm getting the same problem on a pi zero, with the core_freq=250 setting in config.txt, which makes the difference between lockup/fail and just not quite working, any solution to this odd colour shifting?

@timvandenhof
Copy link

I was running off PWM but am trying to switch to SPI to free up PWM for audio. I added core_freq=250 to /boot/config.txt which seems to work. However, I've noticed that all the colors are incorrect.

I think the signal is getting shifted because if I try to set the LEDs to red, I will get all yellow LEDs except the first LED will be white.

I'm on a pi3, python 2.7. LED frequency is set to 800000. Coloring order is WS2811_STRIP_GRB which worked as expected using PWM and GPIO pin 18.

Any ideas how to correct this color shift?

It's a while ago now, but have you found a way to resolve your issue? I might be facing something similar. I opened a tread about it on the Raspberry Pi Forums: https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=260037

The issue I'm facing is that it works fine over PWM, but using SPI results in wrong white flashing colors, where one LED lights up green. I've seen issues with python2 and python3, but also experienced issues with .Net Core on Raspbian dotnet/iot#257

Still investigating, I'm expecting a raspberry pi configuration error / user mistake, not a library issue. Hence the tread over at the Rpi Forum.

@stephbellemare
Copy link

I was running off PWM but am trying to switch to SPI to free up PWM for audio. I added core_freq=250 to /boot/config.txt which seems to work. However, I've noticed that all the colors are incorrect.
I think the signal is getting shifted because if I try to set the LEDs to red, I will get all yellow LEDs except the first LED will be white.
I'm on a pi3, python 2.7. LED frequency is set to 800000. Coloring order is WS2811_STRIP_GRB which worked as expected using PWM and GPIO pin 18.
Any ideas how to correct this color shift?

It's a while ago now, but have you found a way to resolve your issue? I might be facing something similar. I opened a tread about it on the Raspberry Pi Forums: https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=260037

The issue I'm facing is that it works fine over PWM, but using SPI results in wrong white flashing colors, where one LED lights up green. I've seen issues with python2 and python3, but also experienced issues with .Net Core on Raspbian dotnet/iot#257

Still investigating, I'm expecting a raspberry pi configuration error / user mistake, not a library issue. Hence the tread over at the Rpi Forum.

use this:
On an RPi 3 you have to change the GPU core frequency to 250 MHz, otherwise
the SPI clock has the wrong frequency.

Do this by adding the following line to /boot/config.txt and reboot:

    core_freq=250

On an RPi 4 you must set a fixed frequency to avoid the idle CPU scaling changing the SPI frequency and breaking the ws281x timings:

Do this by adding the following lines to /boot/config.txt and reboot:

    core_freq=500
    core_freq_min=500

SPI requires you to be in the gpio group if you wish to control your LEDs
without root.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants