We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello everyone,
I am trying to make communication between an STM32F3 microcontroller and a custom board baser on PIC microcontroller using SPI protocol.
The STM32F3 acts as a Slave and the custom board as a Master. The clock is set to 10 MHz. I’m using NSS hardware, and getting EXTI once CS gets low in NSS pin. The CPOL and CPHA are compatible between the two boards. I am using Interrupt base communication in the Slave side. The application consists of: 1) The Master sends a command to the Slave, then a data of 4 bytes : This part works fine 2) The Master sends continuously different commands, The Slave process the command, then sends its proper data (4 bytes) depending on the received command. The Updating frequency sends by the Master is about 20 KHz.
I have a problem with the second case, in fact, when the Master sends a command, let’s say 0x01, the Slave process this address and then sends back a frame let’s say 0x410547AF.
In the MISO line the frame is shifted, c.a.d (0x47, 0xAF, 0x41, 0x05, 0x05) instead of (0xXX, 0x41,0x05, 0x47, 0xAF), because the first byte corresponds to the byte when the address is received. I also used the debug mode to view the SR register and I can see that the FIFO transmission level is always at 2, that explains why the frame is shifted by 2 bytes. But I can’t find a solution to my problem, do you have an idea what would be the problem please? If you want some code sample, I can post it. I hope that my problem is clear. Thanks in advance Best regards
It is quite common that the master uses a standard GPIO pin to drive the slave select. The reasons are two: 1) The master can then have individual slave-select signals for multiple slaves. 2) The master then can decide if it should deactivate the slave-select as soon as the transmitter runs empty, or if the master wants to be able to think a bit and then add more data to send, to form a rather large packet, before it releases the slave select.
So it's irrelevant if the master chains the slave-select function to the SPI hardware or drives it "manually" using a GPIO bit.
But it is imperative that the slave reacts instantly, because there may be a very short delay between assertion of slave select and the first critical change of the clock and/or data signal for the slave. An interrupt handler is often not quick enough. The slave really is expected to handle the slave select in the SPI hardware.
If your slave isn't enabled before the master sends the first word, and stays enabled through every single bit of the transfer from the master, then the slave will get out-of-sync and fail with at least one word still not correctly sent. That is why it is so imperative that the slave is ready instantly when the slave-select line goes active.
And another thing - since there may be a very short interval between slave-select and first transfer, the SPI slave already needs to have a word ready to send - you aren't likely to have time to handle any transmit-empty interrupt quick enough. So the slave is normally given a dummy word to be able to directly send concurrently with the first word from the master. And if the master doesn't give a bit of a pause after having sent the last command word, before starting to send dummy words while waiting for the answer, then you might need to define your protocol to do an extra dummy transfer in both directions just to give the slave time to pick up the command, process it and hand over the answer to the SPI hardware.
In the end, it's trivial to manually bit-bang an SPI master, since the master is the one controlling all timing. If it's slow, then the slave will not mind. It's only when the master is too fast that the slave will fail. Which is why it is normally never a good idea to have the slave do any SPI operations in software - it should just focus on keeping the transmit buffer non-empty, and picking up incoming data.
Thank you sirs Hans-Bernhard and Per for your precious explanations.
I tried to use the hardware slave select pin in the Slave side but i didn't succeed. I have read many posts about the NSS deficiencies in the STM32.
Please would you have some details how to manage this signal?
Thanks in advance,
Best regards