Linux SPI master sends 8 bytes data of these every 1 second:
using packet_t = std::array<std::uint8_t, PACKET_LENGTH>;
static packet_t data[] = {
{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00},
{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0},
{0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc},
};
The clock rate is 500kHz.
STM32 SPI slave can receive these data correctly. It tries to echo the received data. But it can only send last 4 bytes in the next master transmission. The rest first 4 bytes can be sent in the 2 steps later in master transmission. I have checked MISO line by the scope. STM32 slave sends the wrong data. So the master sees these:
<1st TXRX>
TX ff 00 ff 00 ff 00 ff 00
RX f0 f0 f0 f0 cc cc cc cc
<2nd TXRX>
TX f0 f0 f0 f0 f0 f0 f0 f0
RX cc cc cc cc ff 00 ff 00
<3rd TXRX>
TX cc cc cc cc cc cc cc cc
RX ff 00 ff 00 f0 f0 f0 f0
<4th TXRX>
TX ff 00 ff 00 ff 00 ff 00
RX f0 f0 f0 f0 cc cc cc cc
The code of callback is here:
#define PACKET_LENGTH 8
uint8_t miso_data[PACKET_LENGTH];
uint8_t mosi_data[PACKET_LENGTH];
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi)
{
HAL_StatusTypeDef retStatus;
if (hspi == m_hspi_nx)
{
...
retStatus = HAL_SPI_TransmitReceive_IT(m_hspi_nx, miso_data, mosi_data, PACKET_LENGTH);
...
osSemaphoreRelease(*m_sem_nx_rx);
}
}
I am using STM32F767.
[Edit] If I don't use the interrupt, it works fine.
HAL_SPI_TransmitReceive(m_hspi_nx, miso_data, mosi_tmp_data, PACKET_LENGTH, HAL_MAX_DELAY);
But I need to use the interrupt.
osSemaphoreRelease(*m_sem_nx_rx);
looks fishy, where exactly do you set/release this? If you set it in main() and do for example some slow buffer copy, that might disrupt the SPI interrupt. \$\endgroup\$