STMicroelectronics / STM32CubeL4

STM32Cube MCU Full Package for the STM32L4 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
Other
259 stars 151 forks source link

Calling HAL_SPI_Transmit() forces HAL_SPI_STATE_READY on error #74

Closed fronders closed 1 year ago

fronders commented 1 year ago

SPI handle state field is usually set to HAL_SPI_STATE_RESET prior to HAL_SPI_Init() call. If however HAL_SPI_Transmit() is called before SPI has been initialized, the SPI driver forces the state field value to HAL_SPI_STATE_READY which is a bug.

Here is the problem, HAL_SPI_Transmit() in the very beginning checks the state to be ready, and if it is not - jumps to error label. https://github.com/STMicroelectronics/STM32CubeL4/blob/c5e83f31696c3da4fb374224471afd08d9d457b3/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c#L837-L841 Here is that label at the end of the function, where the state just gets overwritten, irregardless of why error happened https://github.com/STMicroelectronics/STM32CubeL4/blob/c5e83f31696c3da4fb374224471afd08d9d457b3/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c#L990-L994

Exactly the same problem is present also in HAL_SPI_Receive() and HAL_SPI_TransmitReceive() functions.


Another problem, also related to erroneous state overwrite appears when HAL_SPI_Receive() or HAL_SPI_Receive_IT() or HAL_SPI_Receive_DMA() are called before SPI has been initialized.

Here in the very beginning of HAL_SPI_Receive() it falls back to HAL_SPI_TransmitReceive() in case of bidirectional communication, but it forces the state to be HAL_SPI_STATE_BUSY_RX without checking if before it was HAL_SPI_STATE_READY.

https://github.com/STMicroelectronics/STM32CubeL4/blob/c5e83f31696c3da4fb374224471afd08d9d457b3/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c#L1016-L1033

fronders commented 1 year ago

This first issue can be fixed by just taking same approach that the SPI DMA functions use: state is set before jumping to error label and only in places, where it is actually needed, NOT after jumping to the label, thus forcing it for all error cases

https://github.com/STMicroelectronics/STM32CubeL4/blob/c5e83f31696c3da4fb374224471afd08d9d457b3/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c#L1941-L1950

fronders commented 1 year ago

For the second issue, just remove this line with state overwrite and the state will be handled by HAL_SPI_TransmitReceive()

https://github.com/STMicroelectronics/STM32CubeL4/blob/c5e83f31696c3da4fb374224471afd08d9d457b3/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c#L1018

same for HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()

HBOSTM commented 1 year ago

ST Internal Reference: 135724

HBOSTM commented 1 year ago

Hello @fronders

The fix you requested has been implemented and is now available in the frame of the latest stm32l4_hal_driver package V1.18.0 release. This issue can be closed now. Thank you again for your contribution.

Best Regards,