2016-03-02 05:13 AM
Hello, and the next SPI bug is insideHAL_SPI_TransmitReceive function.
It hangs communication after a few bytes shifted over SPI. The reason is that code logic is broken (it was correct in previous libraries). I'm using 8 bit mode and sending 7 bytes packets, so I'll show only code I'minterested in:/* Transmit and Receive data in 8 Bit mode */
else
{
while
((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
/* check TXE flag */
if
((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
{
*(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
hspi->TxXferCount--;
#ifdef USE_SPI_CRC
/* Enable CRC Transmission */
if
((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
}
/* Wait until RXNE flag is reset */
if
((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
{
(*(uint8_t *)pRxData++) = hspi->Instance->DR;
hspi->RxXferCount--;
}
if
((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
{
errorcode = HAL_TIMEOUT;
goto
error;
}
}
}
This is wrong, you can't write next byte to DR untill you read received byte from it, otherwise some bytes would be lost on RX direction (overwitten with next TX byte).
#!stm32-!cubemx-!spi-!bug
2016-03-02 06:41 AM
I edited CubeF4 code and my version works correctly
#define WAIT_SPI_FLAG(__flag) \
while
(__HAL_SPI_GET_FLAG(hspi, __flag) == 0){\
if
((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)) {\
errorcode = HAL_TIMEOUT;
goto
error; \
}\
}
__IO uint8_t* dr = (__IO uint8_t*)&hspi->Instance->DR;
while
(hspi->TxXferCount > 0U){
//Wait TX
WAIT_SPI_FLAG(SPI_FLAG_TXE);
//Write TX
*dr = (*pTxData++);
hspi->TxXferCount--;
//Wait RX
WAIT_SPI_FLAG(SPI_FLAG_RXNE);
//Read RX
*pRxData++ = *dr;
hspi->RxXferCount--;
}
#if USE_SPI_CRC
// Enable CRC Transmission
if
(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) {
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
2016-03-10 06:38 AM
2016-03-10 09:01 AM
The mind boggles...
It used too... I just have no confidence in the people working on, and accepting this quality code.
2016-03-11 02:37 AM
Hi serb.sergey,
This is already reported and taken into account. Thanks for your feedback and contribution. -Hannibal-2017-08-22 05:21 AM
I just found and fixed this bug too. More than a year later, in MxCube.Version=4.20.1, the bug persists. I implemented a fix similar to Sergey's above, except checking timeout whilest waiting. The comment near the bug is spot-on, saying '
/* Wait until RXNE flag is reset */
' but the code doesn't wait and instead does a one-time check which is very likely to be successful. I found that it would frequently fail when DMA was enabled for other peripherals (ADC, SDADC etc). The result of the bug would be bytes missing in the RX buffer, the RX buffer being padded with 0xFF and no timeout error returned. For example, bytes on the SPI bus of {0xFF, 0xFF, 0xFF, 0x12} would be received in the RX buffer as {0xFF, 0xFF, 0x12, 0xFF} - Very ugly errors when reading from EEPROM, ADCs etc. The extra trailing 0xFF, by the way, is caused by a 16-bit read of the DR for a byte that hasn't been received.It's likely that, although the bug was reported, simplistic tests passed and therefore the bug was not fixed. The problem can be replicated by repeatedly reading a register of a SPI device and comparing the RX bytes to known good values. Once that works, execute DMA operations for other peripherals and expect random successes and failures.
2017-11-09 08:46 AM
Hello
Is there any bug fix available for this ?
Thanks,
Hugues