Skip to main content
LVers.1
Associate III
November 30, 2021
Solved

STM32WBxx spi HAL driver seems buggy when transmitting in 8 bit modes (not interrupt nor DMA driven).

  • November 30, 2021
  • 5 replies
  • 2574 views

In STM32Cube_FW_WB_V1.12.1 the function HAL_SPI_Transmit() increase buffer point per sizeof(uint16_t) when sending data in 8 bits mode; this lead to 1 byte every 2 bytes not being send out. See the below snippet from HAL_SPI_Transmit()

/* Transmit data in 16 Bit mode */
 if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 {
 if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 {
 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 hspi->pTxBuffPtr += sizeof(uint16_t);
 hspi->TxXferCount--;
 }
 /* Transmit data in 16 Bit mode */
 while (hspi->TxXferCount > 0U)
 {
 /* Wait until TXE flag is set to send data */
 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
 {
 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 hspi->pTxBuffPtr += sizeof(uint16_t);
 hspi->TxXferCount--;
 }
 else
 {
 /* Timeout management */
 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 {
 errorcode = HAL_TIMEOUT;
 goto error;
 }
 }
 }
 }
 /* Transmit data in 8 Bit mode */
 else
 {
 if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 {
 if (hspi->TxXferCount > 1U)
 {
 /* write on the data register in packing mode */
 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 hspi->pTxBuffPtr += sizeof(uint16_t);
 hspi->TxXferCount -= 2U;
 }
 else
 {
 *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
 hspi->pTxBuffPtr ++;
 hspi->TxXferCount--;
 }
 }
 while (hspi->TxXferCount > 0U)
 {
 /* Wait until TXE flag is set to send data */
 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
 {
 if (hspi->TxXferCount > 1U)
 {
 /* write on the data register in packing mode */
 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 hspi->pTxBuffPtr += sizeof(uint16_t);
 hspi->TxXferCount -= 2U;
 }
 else
 {
 *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
 hspi->pTxBuffPtr++;
 hspi->TxXferCount--;
 }
 }
 else
 {
 /* Timeout management */
 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 {
 errorcode = HAL_TIMEOUT;
 goto error;
 }
 }
 }

See lines 39-41 and 58-60 above. The lines 64-66 seems correct (they handle the case when 1 byte remain in the buffer)

It seems HAL_SPI_TransmitReceive() is affected the same way.

This being said, I have correct this in my project, but of course the file gets overwritten every time i "generate code" from MX. What's the best way to avoid this ? To make the correction in the file inside the STM32Cube_FW_WB_V1.12.1 "repository" that is used by MX ?

Thanks,

Laurent

    This topic has been closed for replies.
    Best answer by TDK

    > hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);

    > hspi->pTxBuffPtr += sizeof(uint16_t);

    This is called data packing. It writes two bytes at the same time into the TXFIFO and increments the pointer by 2. It only does this when there are 2+ bytes to send and when there is room in the TXFIFO. I do not see a bug here.

    5 replies

    TDK
    TDKBest answer
    November 30, 2021

    > hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);

    > hspi->pTxBuffPtr += sizeof(uint16_t);

    This is called data packing. It writes two bytes at the same time into the TXFIFO and increments the pointer by 2. It only does this when there are 2+ bytes to send and when there is room in the TXFIFO. I do not see a bug here.

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    LVers.1
    LVers.1Author
    Associate III
    December 1, 2021

    Thanks a lot for your answer. You are correct, my problem was somewhere else.

    I would have expect the FIFO to be filled by consequent 8 bits write to the DR registers but indeed I now see the reference to "data packing".

    As a side note, any pointer where i could find a datasheet about the SPI peripheral of the STM32WB family ? All i could find is a power point presentation (https://www.st.com/content/ccc/resource/training/technical/product_training/group0/34/7d/28/20/b4/bc/47/69/STM32WB-Peripheral-Serial-Peripheral-interface-SPI/files/STM32WB-Peripheral-Serial-Peripheral-interface-SPI.pdf/jcr:content/translations/en.STM32WB-Peripheral-Serial-Peripheral-interface-SPI.pdf)

    Wish you a nice day,

    Laurent

    TDK
    December 1, 2021

    > As a side note, any pointer where i could find a datasheet about the SPI peripheral of the STM32WB family ?

    The reference manual (not the datasheet) is the best source of information on how the chip works and will include details on the SPI peripheral:

    https://www.st.com/en/microcontrollers-microprocessors/stm32wb55rg.html#documentation

    https://www.st.com/resource/en/reference_manual/rm0434-multiprotocol-wireless-32bit-mcu-armbased-cortexm4-with-fpu-bluetooth-lowenergy-and-802154-radio-solution-stmicroelectronics.pdf

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    LVers.1
    LVers.1Author
    Associate III
    December 1, 2021

    Thanks a lot, that's the document i was indeed looking for.

    Sorry for looking dumb ... i'm coming from the low end 8/16 bits world where C is just another way to write assembler :)

    TDK
    December 1, 2021

    No need to apologize. As long as you post well written question, I'm happy to answer them.

    The reference manual / datasheet difference often trips up new users.

    "If you feel a post has answered your question, please click ""Accept as Solution""."