2016-07-13 12:27 AM
Hi All,
We are using STM32F072B and faced with SPI comm. problem.
I have seen that Cube SPI functions have some bugs. HAL_SPI_Receive does not reading first three byte and loosing last three byte. I have seen several bug reports about Cube SPI functions but could not find a similar one. Also tried HAL_SPI_TransmitReceive function and stiation is the same. Logic analyzer shows that valid data avaliable on bus but code does not read it.
Error is related with total number of byte transactions. For eg. it is OK for 1 byte TX and three byte RX. But not for 4 bytes of TX and 1 byte of RX.
Is there any workarounds or bug fix ?
Regards. #stm32cubef0-spi2016-08-15 06:32 AM
> Yes, sure.
But.. look at the picture, every single transmission consists of 16 CLKs/bits.2016-08-15 06:44 AM
There are 16 clock but transaction is 2 bytes.
But suspected that it is actually configured as 8 bit.even with the ''hspi1.Init.DataSize = SPI_DATASIZE_8BIT''Because I am trying to write 0...9 to an address and reading it back. Seen that only the even bytes are written properly. I will check the registed in debug manually. Edit : SPI1_CR2 - DS[0:0] = 0111 and seems correct2016-08-15 06:46 AM
00 or FF depending of the number of byte to read
2016-08-15 06:47 AM
What is the return value of
HAL_SPI_Receive
function when it fails to work as intended?
2016-08-15 10:32 PM
SOLVED !
If I just transmit data and then try to read, function first returns previous read data related with transmit transaction then data related with read transaction. I have replaced transmit functions with ..RransmitReceive and it is OK now.uint8_t Ext_Flash_Read_Byte(unsigned int address)
{
EXT_FLASH_CS_Low();
SPI_Tx_Buf[0] = CMD_READ;
SPI_Tx_Buf[1] = ((address >> 16) & 0xFF);
SPI_Tx_Buf[2] = ((address >> 8) & 0xFF);
SPI_Tx_Buf[3] = (address & 0xFF);
// HAL_SPI_Transmit(&hspi1, (uint8_t*)SPI_Tx_Buf, 4, 100);
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)SPI_Tx_Buf, (uint8_t*)SPI_Rx_Buf, 4, 100);
HAL_SPI_Receive(&hspi1, (uint8_t*)SPI_Rx_Buf, 1, 100);
EXT_FLASH_CS_High();
return SPI_Rx_Buf[0];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Ext_Flash_Read(unsigned int address, uint8_t*pData, uint16_t n)
{
EXT_FLASH_CS_Low();
SPI_Tx_Buf[0] = CMD_READ;
SPI_Tx_Buf[1] = ((address >> 16) & 0xFF);
SPI_Tx_Buf[2] = ((address >> 8) & 0xFF);
SPI_Tx_Buf[3] = (address & 0xFF);
// HAL_SPI_Transmit(&hspi1, (uint8_t*)SPI_Tx_Buf, 4, 100);
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)SPI_Tx_Buf, (uint8_t*)pData, 4, 100);
HAL_SPI_Receive(&hspi1, (uint8_t*)pData, n, 100);
EXT_FLASH_CS_High();
}
2017-01-15 04:30 PM
Thanks for posting this. I am struggling with the same issue. I was able to duplicate your success but wanted to add that you have to transmit/receive 4 bytes in the HAL_SPI_TransmitReceive() or it won't work. Any less than 4 and you will only get partially correct results. For instance, I only have to transmit a single address byte but doing this didn't, I had to send the address byte plus 3 dummy bytes and then read out 4 consecutive bytes.
2017-01-16 06:10 PM
I had exactly this issue (STM32 CubeMX, STM32F072RB, etc.). I found this presentation after quite a bit of searching:
This suggests that the CRC is *always* calculated and loaded on receive and needs to be flushed. Simply adding:
HAL_SPIEx_FlushRxFifo( xxx );
before any receive-oriented SPI functions completely resolved the issue for me. It appears the CRC unit always appends the calculated CRC (or, perhaps, mostly always, or possibly even sometimes always, or maybe just once in a while to keep you guessing, it's all the same in the end).
Hope this helps.
Cheers,
Dana
2017-01-17 04:50 AM
Thanks for sharing that Dana, it works like a charm!
2017-12-17 08:55 PM
Hello,
I stuck with the same problem. But I found solution:
When U use Receive only,
SPI
receive dataautomatically
. So, just add this code to body ofSPI
_Receive function before enablingSPI
. Ualways
got last byte as first byte for yourrx
buffer. And this first byte wasalways
outdated.while(
hspi
->Instance->SR &SPI
_FLAG_RXNE
){
/* This workaround needs around 1.06
uS
*//* Read DR to Flush DR and
RXNE
flag */__
IO
uint16_t
tmpdr
=hspi
->Instance->DR;/* To avoid
GCC
warning */UNUSED(
tmpdr
);}