cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeF0 - SPI functions problem

yilmazkircicek
Associate III
Posted on July 13, 2016 at 09:27

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.

0690X00000602xaQAA.jpg

0690X000006036gQAA.jpg

#stm32cubef0-spi
18 REPLIES 18
qwer.asdf
Senior
Posted on August 15, 2016 at 15:32

> Yes, sure.

But.. look at the picture, every single transmission consists of 16 CLKs/bits.

yilmazkircicek
Associate III
Posted on August 15, 2016 at 15:44

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 correct

yilmazkircicek
Associate III
Posted on August 15, 2016 at 15:46

00 or FF depending of the number of byte to read

qwer.asdf
Senior
Posted on August 15, 2016 at 15:47

What is the return value of

HAL_SPI_Receive 

function when it fails to work as intended?

yilmazkircicek
Associate III
Posted on August 16, 2016 at 07:32

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(); 
}

3FTI
Associate II
Posted on January 16, 2017 at 01:30

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.

Dana Myers
Senior
Posted on January 17, 2017 at 03:10

I had exactly this issue (STM32 CubeMX, STM32F072RB, etc.). I found this presentation after quite a bit of searching:

http://www.st.com/content/ccc/resource/training/technical/product_training/d9/cf/69/ae/71/43/4f/23/STM32L4_Peripheral_SPI.pdf/files/STM32L4_Peripheral_SPI.pdf/jcr:content/translations/en.STM32L4_Peripheral_SPI.pdf

 

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

Posted on January 17, 2017 at 12:50

Thanks for sharing that Dana, it works like a charm!

Dmytro  Kryvyi
Associate
Posted on December 18, 2017 at 05:55

Hello,

I stuck with the same problem. But I found solution:

When U use Receive only,

SPI

receive data

automatically

. So, just add this code to body of

SPI

_Receive function before enabling

SPI

. U

always

got last byte as first byte for your

rx

buffer. And this first byte was

always

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

);

}