2024-04-01 02:58 AM
Hello everyone,
I am using SPI to communicate two Nucleo Boards (a NUCLEO-L432KC and a NUCLEO-F411RE one), and i found out a weird behavior. The idea was to perform a transaction Master -> Slave in order to select a "register" to read. Once the Slave has received the "register", the Master request the information and the Slave shall send the information to the master.
In order to perform this, interruptios were used in the slave side. The "register" logic is still not present, but the concept is the aforementioned one.
The Master code is as follows (only SPI-Related lines):
HAL_SPI_Transmit(&hspi2, txbuff, 2, 1000);
HAL_Delay(1); /* DELAY BETWEEN TRANSACTIONS */
HAL_SPI_Receive(&hspi2, rxbuff, 12, 1000);
And for the slave, following code is used:
/* USER CODE BEGIN 2 */
HAL_SPI_Receive_IT(&hspi1, buffreg, BUFFREG);
/* USER CODE END 2 */
SPI Interruption handlers are as follows:
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
HAL_SPI_Transmit_IT(&hspi1, buffdat, BUFFDAT);
rxData++;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
HAL_SPI_Receive_IT(&hspi1, buffreg, BUFFREG);
txData++;
}
When the delay (HAL_Delay(1)) in the first pice of code (MASTER code) is not present, the communications cannot be performed properly, and weird values are read in the reception. But when it is pressent, the program works properly.
Are there any way to overcome this delay?
Is there another better approach to do so?
Thanks in advance.
Solved! Go to Solution.
2024-04-03 10:15 AM
(almost) every SPI slave device has a specified minimum time between transactions. Usually spec'd as time from slave select de-asserted to next slave select asserted. Which, BTW, I didn't see any slave select code - are you using the built-in hardware NSS facility? Or are you skipping the slave select signal?
If you want to speed up the slave's response time you will need to bypass the HAL code and write your own minimal implementation. But you will most likely always need SOME delay on the master side between the TX and RX calls.
2024-04-01 07:14 AM
New update...
Performing some tests about the delay, I need to wait at leats 55 clock cycles in the master to start the communication and receive data:
HAL_SPI_Transmit(&hspi2, txbuff, 2, 1000);
//HAL_Delay(1); // OLD APPROACH
for(int i = 0; i < 55; i++) // MINIMUM WAIT
{
asm("NOP");
}
HAL_SPI_Receive(&hspi2, rxbuff, 12, 1000);
2024-04-02 08:33 AM
Of course you need to give the slave time to process the first packet and get ready to transmit the response. If the master starts the read before the slave is ready, you will receive garbage. And that delay may change depending on interrupt priorities and how heavily loaded (busy) the slave MCU is.
2024-04-02 11:17 PM
Hi @Bob S,
Thank you so much for your response. This was what i figured out and the reason behing the blocking delay between transactions.
I've been reviewing the examples and applications at STM32 Firmware libraries and the solution there is to perform a "synchronization" between master and slave in order to determine whether both are synchronized or not, but I don't know if there is a better solution.
In my case, the key is to "play" with the libraries, so I am trying to optimize it as maximum as possible to get the fastest reponse, so if you know a better solution or some kind of "ACK" (despite of the aforementioned one seen at the STM32 examples) i ill apreciate you to share.
Best regards,
Víctor.
2024-04-03 10:15 AM
(almost) every SPI slave device has a specified minimum time between transactions. Usually spec'd as time from slave select de-asserted to next slave select asserted. Which, BTW, I didn't see any slave select code - are you using the built-in hardware NSS facility? Or are you skipping the slave select signal?
If you want to speed up the slave's response time you will need to bypass the HAL code and write your own minimal implementation. But you will most likely always need SOME delay on the master side between the TX and RX calls.
2024-04-06 04:56 AM
I am currently using an implementation without the NSS line, because it is just device to device communication, but i can test it using this line, it is very straightforward...
I've been working with some ASICs (sensors) which do not need time to change between reading and writing operation, and a pure transception may be used with neggible delay between writing and reading operations, but those devices are pure-hardware ones, so a register logic is used instead of code for sure.
Anyway, I'll consider this topic solved, due to as you said, there must be some time between reading and writing in order to reconfigure SPI, select the register, etc... and it is as it was implemented by ST on its examples.
Thank you so much for your time!