cancel
Showing results for 
Search instead for 
Did you mean: 

Bug: STM32F0xx HAL SPI Transmit

stefanoroggerini9175
Associate II
Posted on September 23, 2016 at 11:35

I have found a bug in the STM32F0xx HAL SPI driver, specifically in the HAL_SPI_Transmit andHAL_SPI_TransmitReceive functions. Basically they are converting a pointer to uint8_t into a pointer to uint16_t. The problem with that is that the M0 cannot support unaligned accesses and the uint8_t pointer is not guaranteed to be on a 16 bit boundary. In fact this has happened to me and the software hard faults when the conversion is attempted.

The functions are defined as:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)

They are specifically asking for a pointer to 8 bit data.

In the function:

/* Transmit and Receive data in 16 Bit mode */
if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
{
...
}
/* Transmit and Receive data in 8 Bit mode */
else
{
...
hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount -= 2;

It actually checks whether the data being sent is 8 bits and then converts the pointer to the 8 bit data into a pointer to 16 bit data.

#stm32f0xx_hal

Note: this post was migrated and contained many threaded conversations, some content may be missing.
19 REPLIES 19
Imen.D
ST Employee
Posted on September 23, 2016 at 17:10

Dear User,

Thanks for highlighting this issue. Your feedback is reported internally for checking and  working to resolve this.

We apologize for any inconvenience this may cause and thank you for your understading.

Best Regards

STM32.forum

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Sidlauskas.David
Associate II
Posted on February 22, 2017 at 21:59

I just ran into this exact same problem. When the data pointer is odd the SPI handler crashes, works OK on even bytes.

Here's the offending instruction highlighted in yellow:

0690X00000606KWQAY.png

When r5 is odd execution ends up in the Hard Fault Handler as reported above.

I'm using STM32Cube FW_F0 V1.7.0  with STMCube v4.19.

This bug was reported last September. Is there yet a fix or work around for it?

Thanks,

Dave

stefanoroggerini9175
Associate II
Posted on February 23, 2017 at 10:24

If I remember correctly it is only the blocking function that has this problem.  If you use one of the non-blocking functions (either interrupt or DMA) it should work.

The only other thing to do (until this is fixed) would be to declare your data as 16 bit and then cast it to 8 bit where you need to.

uint16_t array16[4];

uint8_t *array8 = (uint8_t *)array16;

array8[0] = 1;

array8[1] = 2;

While highly undesirable this would guarantee that the array is always created on a 16 bit boundary.

Posted on February 23, 2017 at 16:44

Hi, 

This issue is confirmed and will be fixed in the next release of STM32CubeF0.

Regards

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Posted on February 23, 2017 at 18:29

Thanks for the info.

I used the __align(2) compiler directive to put the data on a 2 byte boundary.

Posted on February 23, 2017 at 19:55

Cool, I didn't realise that was there.

T J
Lead
Posted on February 23, 2017 at 22:34

I dont have any issues with SPI, maybe you can glean some insight from this.

void quickSend8SPI(SPI_HandleTypeDef *hspi){
 while( !( hspi->Instance->SR & SPI_FLAG_TXE)); *((__IO uint8_t *)&hspi->Instance->DR) = TxSPIByte; }void quickSendReceive8SPI(SPI_HandleTypeDef *hspi){
 while( !( hspi->Instance->SR & SPI_FLAG_TXE));
 
 *((__IO uint8_t *)&hspi->Instance->DR) = TxSPIByte; // force the SPI to transceive 8 bit while( !( hspi->Instance->SR & SPI_FLAG_TXE)); while( ( hspi->Instance->SR & SPI_FLAG_BSY)); while( ( hspi->Instance->SR & SPI_FLAG_RXNE)) RxSPIByte1 = hspi->Instance->DR;
}
�?�?�?�?�?�?�?�?�?�?

Posted on February 24, 2017 at 03:27

Hi Nick,

Thanks for the response. Yeah, I’ve seen snippets like that in some of the CubeMX example projects. I was trying to be a purest and use CubeMX and the HAL library exclusively, thereby staying away from direct register access. Perhaps a fools errand. It’s amazing how much code HAL takes to push a byte out of a dataport .

Dave

________________

Attachments :

wlEmoticon-smile[1].png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyr6&d=%2Fa%2F0X0000000bDS%2FFynj0o4tQ.1gGdavLmwp6OaBNApzjIK9bv9vwWUK1QM&asPdf=false
Todor Todorov
Associate II
Posted on August 01, 2017 at 16:10

This issue is still present in CubeMX 4.0 and STM32F0xx HAL 1.8.0.

I am using GCC 6.2.1 with STM32F I get hard faults when I have SPI in 8bit master mode and try to use HAL_SPI_Transmit with a buffer of data instead of single byte. It works only if I comment out all of the packing mode transfer code starting at line 633 in stm32fxx_hal_spi.c:

//if (hspi->TxXferCount > 1U)
//{
// /* write on the data register in packing mode */
// hspi->Instance->DR = *((uint16_t *)pData);
// pData += sizeof(uint16_t);
// hspi->TxXferCount -= 2U;
//}
//else
{
 *((__IO uint8_t *)&hspi->Instance->DR) = (*pData++);
 hspi->TxXferCount--;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Problem is, every time I change something in the CubeMX project, I have to remember and go back to this to comment out the code which causes the grief...