2016-02-28 07:15 AM
Hi,
I'm using ST's driver for SPI in full -duplex, 8 bit, master mode. The function HAL_SPI_TransmitReceive() returns sometimes HAL_TIMEOUT. After inspecting code I don't understand the following:The code below at line marked A===>: Waits for RXNE to get set. Then DR is read. this should clear the RXNE flag. When this is last read operation in loop, we continue to B===>.In B===> we again wait for RXNE to get set.My questions are: 1. How can RXNE be set if data was not sent on TX? 2. Sometimes the check of RXNE in B===> passes. I can't understand how RXNE was set if prior to B we read DR (and therefore I would expect the flag to be cleared)? Thanks, Ari =========================================== /* Transmit and Receive data in 8 Bit mode */ else { hspi->Instance->DR = (*hspi->pTxBuffPtr++); hspi->TxXferCount--; if(hspi->TxXferCount == 0) { /* Enable CRC Transmission */ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) { hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; } /* Wait until RXNE flag is set */ if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } (*hspi->pRxBuffPtr) = hspi->Instance->DR; hspi->RxXferCount--; } else { while(hspi->TxXferCount > 0) { /* Wait until TXE flag is set to send data */ if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } hspi->Instance->DR = (*hspi->pTxBuffPtr++); hspi->TxXferCount--; /* Enable CRC Transmission */ if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)) { hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; }A===> /* Wait until RXNE flag is set */ if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } (*hspi->pRxBuffPtr++) = hspi->Instance->DR; hspi->RxXferCount--; }B===> /* Wait until RXNE flag is set */ if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } (*hspi->pRxBuffPtr++) = hspi->Instance->DR; hspi->RxXferCount--; } }2016-02-29 04:23 AM
Found problem:
HAL_SPI_TransmitReceive sends data over MOSI when TXE becomes true.So, the second byte is sent immediately after first byte is shifted to SPI's TxBuffer (HW). The RXNE is true onle at end of 8'th bit clock. So if an interrupt (or contex switch) occured right after transmission of the first byte, when we return to read DR it may be overwitten by the second clock, so we missed the first DR!Solutions: A) We can mask interrupts - Not secommended! B) Use updated HAL_SPI_TransmitReceive(): Here we do not take advantage of the TxBuffer, rather, upon each transmission we wait for RXNE to become true. Then read DR and proceed with next Tx (write DR). // This way, even if an nterrupt occured between transmit and receive we get back always to read the DR that xcorresponds to the last TX.2016-07-20 08:46 AM
Hello,
Can you tell me where to find the update HAL_SPI_TransmitReceive ? Thanks a lot !2016-08-18 07:28 AM
Hello,
I would be also very interested in what the updated HAL_SPI_TransmitReceive() refers to. We are using version v1.4.0 of the HAL driver from May/2016 here. Apparently there had been an update to that function, but we are facing similar problems.2016-08-18 10:07 PM
We are using F0 and SPI has alot of problem.
Functions has weird behaviours. [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/BUG%20%20-%20%20HAL_SPI_Receive%20%20%20%28STM32F0%20%20CubeF0%29&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=33]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fBUG%20%20-%20%20HAL_SPI_Receive%20%20%20%28STM32F0%20%20CubeF0%29&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=33