2016-09-23 02:35 AM
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.
2016-09-23 08:10 AM
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.forum2017-02-22 12:59 PM
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:
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
2017-02-23 01:24 AM
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.
2017-02-23 08:44 AM
Hi,
This issue is confirmed and will be fixed in the next release of STM32CubeF0.
Regards
Imen
2017-02-23 10:29 AM
Thanks for the info.
I used the __align(2) compiler directive to put the data on a 2 byte boundary.
2017-02-23 11:55 AM
Cool, I didn't realise that was there.
2017-02-23 01:34 PM
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;
}
�?�?�?�?�?�?�?�?�?�?
2017-02-23 07:27 PM
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=false2017-08-01 07:10 AM
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...