-
Notifications
You must be signed in to change notification settings - Fork 5.2k
RPI4 SPI controller CS deasserts too early at 1MHz #5655
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
Comments
That's strange, because we use GPIO (software-controlled) CS lines on Pi 4 (and other Pis). Can you confirm which custom config.txt entries you have applied? |
And which SPI interface you are using. |
We use |
Is this actually causing problems for you? The smallest gap I've seen is 48ns, which isn't large, but it also isn't negative. What kind of gap does your application require? |
The application requires 5ns. The problem is that we actually go below this or even into the negative, which is of course not ok. Also note: I could not reproduce this with calls to spidev_test or other setups. Also on 2 different RPI4, the error occurs on different parts of the program. |
I'm wondering if the problem is that TX FIFO empty is not the same as idle. @l1k You've done a lot of work on the SPI driver over the years, and I wouldn't be surprised if you've intentionally used TX FIFO empty to allow for a bit of overlap to reduce the gap between transfers - is that correct? Is there a neat way of forcing it to wait until the transfer is complete before de-asserting CS? |
Are there any error messages or warnings in dmesg? How large are the messages being transferred? If they're just a few bytes long, the driver uses polling, i.e. it alternatingly writes, then reads bytes from the FIFO until the message is complete. If the message is larger, DMA is used and then it gets more complicated. I don't think "TX FIFO empty" semantics play a role here. Since SPI is full duplex, the message is not complete until the same amount of bytes has been received which has been sent. I could imagine that the clock calculations in |
Oh also, if the CPU is not under heavy load, it is clocked down. E.g. on a CM3 the core clock is reduced from 1200 MHz to 600 MHz. That will halve the bandwidth of the SPI bus. The workaround is to switch to "performance" cpufreq governor in sysfs. That will pin the clock at 1200 MHz and thus lead to predictable SPI clocks. Just something to keep in mind. |
Another side comment: On the tpm_tis (in-kernel) driver, the same problem seems to have occurd. |
Describe the bug
When using the SPI controller via the spidev driver from userspace, the timing between the last falling edge of the CLK and the deassertion of CS is somehow off.
It even happens that CS is deasserted before the last CLK fall.
This is worst at around 1MHz. It get's much better below 500kHz and above 2MHz.
Blue is CLK, Green is CS

Steps to reproduce the behaviour
I need a payload that uses 2 ioctls and leaves CS asserted between those two via the
cs_change
parameter= 1
.Attached you find a simple python script that reproduces this issue.
I had to insert the "waiting with asserted CS" between byte 4 and 5:
spidev-test.py.txt
Device (s)
Raspberry Pi 4 Mod. B
System
cat /etc/rpi-issue
Raspberry Pi reference 2023-05-03
Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, 47eee1f0ddcf8811559d51eea1c1bb48335e3e88, stage2
vcgencmd version
Mar 17 2023 10:50:39
Copyright (c) 2012 Broadcom
version 82f3750a65fadae9a38077e3c2e217ad158c8d54 (clean) (release) (start)
uname -a
Linux raspberrypi-arael 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
Logs
Blue is CLK, Green is CS



Additional context
No response
The text was updated successfully, but these errors were encountered: