I have been trying to get SPI communication between an STM32f767ZI Nucleo (slave, MBed v6) and a Raspberry Pi 3B+ (master, Raspbian buster) to work, but have been having issues with incorrect bytes being received/sent.
In my test setup, I have SPI1 of the Pi connected to SPI1 of the STM board.
I tested the SPI functionality by running a Python script on the Pi (which does 10 transfers with the bytes 0 to 10) and having the STM echo the received bytes. I used 100KHz and mode 0.
The following is the Pi’s script:
from periphery import SPI
spi = SPI("/dev/spidev0.1", 0, 100000)
for i in range(10):
data_in = spi.transfer([i])
print(bin(data_in[0]))
spi.close()
And the code running on the STM:
// SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel);
SPISlave slave(PB_5, PB_4, PB_3, PA_4);
int main() {
slave.frequency(100000);
slave.format(8, 0);
SEGGER_RTT_printf(0, "Init\n");
// Prime initial reply
slave.reply(0x01);
for (;;) {
if (slave.receive()) {
int v = slave.read();
SEGGER_RTT_printf(0, "received %d\n", v);
// Send message on next receive
slave.reply(v);
}
}
}
The two issues I had were:
- It seems like bytes are sometimes not received on the STM side
Here is an example of the output from the STM (using SEGGER RTT)
Init
received 0
received 1
received 2
received 3
received 4
received 6 # missing 5?
received 7
received 8
received 9
Here the 5 is missing, I had different cases where other bytes were missing.
- The bytes received on the Pi were sometimes incorrect, e.g. a bit flip.
This is an example from the Pi’s output:
0b1 # master sent 0, slave replies initial 0x01
0b0 # master sent 1, slave replies previous input, which is 0
0b1
0b10
0b10 # expected 0b11, bit flip?
0b100
0b1 # expected 0b101?
0b110
0b111
0b1000
I have tried different frequencies (the Pi has a core clock speed of 250 MHz, with a 16-bit prescaler, I believe SPI1 of the f767 has a clock of max 108MHz) and different SPI modes for both of the devices. I have also tried using SPI4 of the STM, but I get the same issues with those setups.
Am I doing something incorrectly or is there a fundamental problem I am missing?