Closed pgrawehr closed 4 years ago
@pgrawehr can you include exact repro steps? (what to put in config.txt; example device you are using and sample code)
I'll try but so far I did not experience this issue. I had to use software CS selection sometimes because of the way the end device was working. And yes, the config.txt and anything that will help to recreate the same hardware setup and software setup is needed in this case. Version of the OS you are running as well to recreate the full conditions.
I've got example code to reproduce the behavior, but it needs a bit of cleanup. I'll provide more information later today.
How to reproduce the problem To reproduce, check out my branch https://github.com/pgrawehr/iot/tree/BoardApproach3 (PR #1128 ), then run the sample in devices/Board/samples
boot/config.txt
only contains the relevant line dtparam=spi=on
.
After booting, we have the following pin configuration (relevant for this case are BCM pins 9, 10, 11 and 8):
pi@raspberrypi:~ $ gpio readall
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | ALT4 | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT0 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | OUT | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | ALT4 | 1 | 27 || 28 | 1 | ALT4 | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | ALT4 | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | ALT0 | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | ALT0 | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
This shows that the CS line (here named CE0) is set to out and high.
The sample application reads from an MCP3008 connected to these pins (the CI test setup should work for it). The first test runs the MCP with software controlled CS settings (Pin 8 is set to output and manually controlled). This works fine.
The second test uses hardware CS and therefore sets pin 8 to ALT0. Now it only reads Zero values, which is certainly not correct.
How to fix it
After adding an extra line with dtoverlay=spi0-hw-cs
to /boot/config.txt, this already looks better after startup:
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | OUT | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | ALT0 | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | ALT0 | CE1 | 11 | 7 |
And magically... both tests pass now!
Conclusion
So this is solved, however the documentation for this behavior is ... suboptimal. And it does mean that the second parameter in public SpiConnectionSettings(int busId, int chipSelectLine = -1)
now does have a meaning. If it is -1, everything will be as before, but if it is 0 (what at least some samples do), the spi0-hw-cs
overlay needs to be enabled, or the device won't work.
So this is solved
So that's the good news!
however the documentation for this behavior is ... suboptimal
Yes, I agree. We were discussing that with @krwq few weeks ago. So as soon as we'll have a bit of bandwidth, SPI, I2C and Serial activation and setup should be better documented. That would include using external dongles as well.
So as soon as we'll have a bit of bandwidth, SPI, I2C and Serial activation and setup should be better documented. That would include using external dongles as well.
I think the whole thing will become much simpler for the user once we have the pin management in (see #1128). Once this works, we can suggest a single set of config.txt settings (or maybe two, for Pi3 and Pi4), that will work for most situations. Because with that, once the kernel drivers are loaded, the library can handle all pin assignments automatically.
@pgrawehr the spi0-hw-cs
solution you mention is depreciated. I've been creating documentation on how to active all this properly with the new dtoverlays.
If you want, you can check that your scenario is working with the new dtoverlays and also the documentation if anything is not clear enough.
@pgrawehr @Ellerbach can this be closed now?
@krwq , fine for me to close as it seems to be exactly as I described now. It has evolved over time. And more consistent now. Now, that can be reopen if the behavior will change one more time.
Sounds good, feel free to re-open if there is something unresolved here
For each SPI bus (up to 6 on the Raspi4), there are 2 or 3 designated pins for Chip Select (CS)*. The underlying hardware driver normally expects that one of these is also used. For SPI0, pins 7 and 8 serve as CS1 and CS0 respectively, when set to mode ALT0.
Problem 1: This doesn't work. When setting pin 8 to ALT0, the Chip never answers (to be investigated in detail with a scope, but I don't have mine at hand right now).
Problem 2: Even though the SpiConnectionSettings structure takes this member and sets it in the driver, this has also no effect, because it doesn't set the pin mode.
Problem 3: Many (all?) bindings fail to control the CS line at all, relying on the low-level driver, which can't work because of Problem 2.
We should:
CC: @Ellerbach, as you've had some experience with SPI, I think
(*) See Alternate Pin Assignments in the BCM2711 ARM Peripherals Guide.