2022-11-20 07:36 AM
Problem description:
1-2 bytes in a ~30 byte message (usually at the same spot in the msg) are sometimes missing. Usually it is the 13th byte.
If I send shorter msgs via SPI like 10 bytes, the other party receives them correctly.
If I wait 50us after pulling NSS low, the other party receives even long msgs correctly.
Let us assume, that after pulling NSS low, the transmission starts too soon. Why is a byte in the middle of the msg missing then and not at the beginning?
Maybe it's an oscillating NSS pin that goes high/low but I couldn't see anyhting on the oscilloscope. I know that the probe will add to the capacitance of the trace so any signal rise will be slower and any oscillation dampened just by hooking up the probe.
Fix for now:
Wait 50us after pulling NSS low.
Question1:
But I don't understand why the fix works... it makes no sense to me. NSS goes high/low in about 200ns (measured with probe, ultra short GND connection). A different measurement showed 1300ns (with long lead on the probe).
The datasheet states 320ns with a 50pF capacitance. So the first measurement should be ok. 200ns is about 3 clock cycles.
I initialize a 60 byte array and do a 30 byte memcpy after pulling NSS low. That should be enough time for NSS to become low.
Why does waiting fix it? Why is a byte missing in the middle? Not at the start?
Question2:
Why is MOSI on the oscilloscope so broken? How come I can even send correct messages with such a MOSI graph? See attached picture. MOSI has a rise time of about 2.5us. Which is way too long. Why? If it was because of the oscilloscope, I'd see the same phenomenon on SCK, NSS or MISO. But I don't.
Environment:
SPI speed: 8 MHz
SPI Mode: Master, Full Duplex
Clock speed: 16 MHz
MCU: STM32L0
VCC: 1V8
SCK trace: ~33mm, 8 mil
MOSI trace: ~43mm, 8 mil
SPI GPIO speed settings: highest speed
NSS speed setting: low
Oscilloscope
input capacitance: 15pF
Probe capacitance: 18-22pF
Probe compensation: 10-35pF
Probe setting: 10x
Solved! Go to Solution.
2022-11-24 10:15 AM
Finally I think I've found the reason why there were bytes missing.
The communication was between an STM32 and a radio MCU. The command that sometimes failed was a command to fill the FIFO of the radio MCU.
Probably the reason why it only worked if I the MCU waited after NSS was driven low, was, that the radio MCU needed time to change its mode from RX to STANDBY. It didn't make a difference whether the wait happened before NSS was driven low or after that. So NSS was not the problem.
Most probably the SPI communication was fully intact but the FIFO was not filled correctly because it was done exactly at that point in time where the mode of the receiver was switching from RX to STANDBY.
Nevertheless I've reduced SPI speed from very high to high and kept that change because it's working with a lower speed and I want to avoid any EMI or over-/undershoot.
I've removed all wait code/cycles and only wait for the mode change of the radio MCU to complete now.