2018-06-04 07:16 AM
Hi Everyone,
In HAL_SPI_TransmitReceive, in the part actually transmitting data, there is a txallowed variable, blocking sending until the reception is done. If SR is cached and checked for the RXNE flag first, before the TXE is checked, this flag is not necessary. Why would you need it?
BR,
M.W.
#spi #hal_spi_transmitreceive #tx-rx-sync #data-integrity2018-06-06 08:30 AM
Hello,
the variable helps to keep number of transmitted and received data balanced when SPI is handled by polling. Note timing of TXE and RXNE flags is different. After data is written to DR, TXE becomes active back again once its first bit is transacted out on the bus (DR becomes empty and ready to accept next data as its content is copied into the internal shift register) while RXNE becomes active once the corresponding data frame is fully completed (and data is copied from internal shift register to the DR). It can happen easily, that SPI master has written two data ahead while any of them is received yet. Such an approach produces continuous clock transaction with a risk of data overrun at reception if software doesn’t manage all the DR reading in time. The function is dedicated rather for SPI master and it is written in passive way when clock is not continuous and new data transaction (write) is protected till the current data is fully completed. I don’t suggest this approach at slave case as slave can never rely on not continuous clock provided by master.
Best regards,
Petr
2018-06-07 02:22 AM
Hi Petr,
I understand what you say. However, I disagree.
What you are saying is - the CPU might be too slow to get the byte before the next one is copied to the DR, overwriting the first one and setting the Overflow (which is not tested BTW).
So let me explain why I think this is not the case.
Let's assume you are the bus master. Let's also assume you sample the SR at the beginning of the transceive part of the SendReceive. Let's have RXNE test (and DR reading) first, before TXE. Since the RXNE for frame N will be set before the TXE for the frame N+2 (this is because all the bits of frame N would be received before the first bit of the frame N+1 is shifted out) how would transceive look like?Let's assume first that the CPU is fast enough to loop through transceive of 1 frame faster, than the frame is sent.
Conversely - let's assume CPU is slower than sending 1 frame. But then again there is no problem at all. Since the RXNE is set before TXE, after sending the first frame, on the next loop the RXNE will already be set (CPU is slower than sending 1 frame) so we will get the data out before we have any chance of transmitting the next frame at all.
Let's assume the CPU is the same speed as transceiving one byte. But then (because of bus synchronisation) we either end up in 'faster' or 'slower' scenario. Again - since RXNE will be set before TXE and we read DR before writing to it, we are safe.
To summarise - since RXNE(N) is set before TXE(N+2) and we read before we write - if we are fast enough to send the second frame before the first is received, we are also fast enough to get the data out before overflow. If we are not fast enough to send the second byte before the first is received, then there is no problem, because we read DR before we write to it.
Edit:OK, it does not account for discontinuous CPU clock. How likely is that scenario with software-based SPI transmission?