2

I have a CM4 Compute Module and am trying to set the clock phase on the second SPI channel. But the ioctl() to set mode returns an error whenever I attempt to set this phase bit:

int fd = open("/dev/spidev1.0", O_RDWR);
unsigned int mode;

mode = 0;   // normal clock phase
ioctl(fd, SPI_IOC_WR_MODE, &mode);  // this works

mode = 1;   // inverted clock phase
ioctl(fd, SPI_IOC_WR_MODE, &mode);  // this fails!

I have tried the test program spidev_test.c and it has the same problem. The program errors when adding the flag to set the clock phase:

./spidev_test -D /dev/spidev1.0 --cpha
can't set spi mode: Invalid argument
Aborted

./spidev_test -D /dev/spidev1.0
spi mode: 4
bits per word: 8
max speed: 500000 Hz (500 KHz)
(data follows, i.e. this works)

Is there some reason that clock phase can't be set on spidev1.0? Setting the phase does work on spidev0.0.

Here is my kernel version: Linux raspberrypi 5.19.0-rc1-v8 #1 SMP PREEMPT Tue Jun 7 21:32:27 UTC 2022 aarch64 GNU/Linux

Can anyone else with a CM4 verify this behavior? The instructions for downloading and building the spidev-test program can be found here: https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/raspberry-pi/spi-bus-on-raspberry-pi.adoc

2 Answers 2

2

The Pi's auxiliary SPI only supports modes 0 and 2.

See http://abyz.me.uk/rpi/pigpio/cif.html#spiOpen

This was discovered by experiment.

6
  • Any idea if this is a hardware limitation? I read through the Broadcom peripherals documentation and didn’t see anything about a restriction on the second SPI. Perhaps it is being prevented in the driver? And that could be fixed?
    – Jon
    Mar 16 at 15:49
  • 1
    I believe it is a hardware limitation (I remember the chap who designed the auxiliary SPI hardware saying it was very much an afterthought). It is not fixable.
    – joan
    Mar 16 at 15:58
  • Thanks so much for the insider info! To clarify, was this someone from Broadcom or Raspberry Pi? Looking at the BCM2711 peripherals datasheet datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf it doesn't list a limitation on the second SPI port. Both have the register bits to set the phase in the table under 2.3.4 - In rising and Out rising.
    – Jon
    Mar 16 at 17:45
  • It was a chap called Gert van Loo who worked on the Pi design and I think also worked for Broadcom at the time. He did the gertboard.
    – joan
    Mar 16 at 17:52
  • Since I'm on Raspberry Pi 4B compute model, which is only a couple of years old, perhaps that is no longer an issue on this new hardware?
    – Jon
    Mar 16 at 18:06
0

In short, I have determined that joan is correct in saying that the hardware cannot support modes 1 and 3. More detail follows.

I investigated why only modes 0 and 2 are supported in the driver. The code in question is in https://github.com/raspberrypi/linux/blob/rpi-5.15.y/drivers/spi/spi-bcm2835aux.c. The chip's datasheet https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf indicates it has some bits to support the other clock phase. I modified the driver to allow SPI_CPHA to control these bits: "In Rising" and "Out Rising". I built the kernel and tested this out in sending SPI to a serial EPROM. Changing the "Out Rising" bit to 0 has the desired effect of making the data change on the falling edge. But it has an undesired effect sending the data out one clock too soon, essentially shifting the data left by one bit. So the first bit you try to send gets lost and there is an extra 0 bit at the end of the last word. I played around with shifting the data, but it was really feasible. In the end, I solved the problem a different way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.