Skip to content

Commit

Permalink
H7_HAL/spi: Prevent strict alias error with 16-bit access of TX/RX regs.
Browse files Browse the repository at this point in the history
Without this modification gcc will warn about violation of strict aliasing
rules.  It is crucial to be able to compile the HAL with the strict
aliasing optimisation (-fstrict-aliasing) because the code can function
incorrectly without using this optimisation (at least the SD card driver of
the F4 HAL requires this optimisation).  And the optimisation also brings
noticeable savings in code size along with improved performance.  So
patching the code as is done here is important to allow the H7 HAL to be
compiled with the optimisation enabled (and have no warnings/errors).
  • Loading branch information
dpgeorge committed Mar 25, 2018
1 parent 000df50 commit 90b9961
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@
*/

/* Private macros ------------------------------------------------------------*/

// These macros are used to prevent strict aliasing errors
#define SPI_TXDR_STORE_U16(hspi, value) *(__IO uint16_t*)((uintptr_t)(hspi)->Instance + offsetof(SPI_TypeDef, TXDR)) = value
#define SPI_RXDR_LOAD_U16(hspi) (*(__IO uint16_t*)((uintptr_t)(hspi)->Instance + offsetof(SPI_TypeDef, RXDR)))

/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup SPI_Private_Functions SPI Private Functions
Expand Down Expand Up @@ -590,7 +595,7 @@ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint
}
else
{
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;
}
Expand Down Expand Up @@ -629,7 +634,7 @@ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint
}
else if ((hspi->TxXferCount > 1U) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
{
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount-=2;
}
Expand Down Expand Up @@ -804,7 +809,7 @@ HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint1
}
else
{
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;
}
Expand Down Expand Up @@ -844,7 +849,7 @@ HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint1
}
else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_FRLVL_QUARTER_FULL)
{
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount-=2;
}
Expand Down Expand Up @@ -1021,7 +1026,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxD
}
else
{
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;
}
Expand All @@ -1038,7 +1043,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxD
}
else
{
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;
}
Expand Down Expand Up @@ -1074,7 +1079,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxD
}
else if ((hspi->TxXferCount > 1U) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
{
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount-=2;
}
Expand All @@ -1097,7 +1102,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxD
}
else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_FRLVL_QUARTER_FULL)
{
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount-=2;
}
Expand Down Expand Up @@ -2183,7 +2188,7 @@ void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
/* Receive data in 16 Bit mode */
else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
{
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
}
/* Receive data in 8 Bit mode */
Expand Down Expand Up @@ -2740,7 +2745,7 @@ static void SPI_2linesRxISR_8BIT(SPI_HandleTypeDef *hspi)
static void SPI_2linesRxISR_16BIT(SPI_HandleTypeDef *hspi)
{
/* Receive data in 16 Bit mode */
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;

Expand Down Expand Up @@ -2806,7 +2811,7 @@ static void SPI_2linesTxISR_8BIT(SPI_HandleTypeDef *hspi)
static void SPI_2linesTxISR_16BIT(SPI_HandleTypeDef *hspi)
{
/* Transmit data in 16 Bit mode */
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;

Expand Down Expand Up @@ -2870,7 +2875,7 @@ static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi)
*/
static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi)
{
*((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR);
*((uint16_t *)hspi->pRxBuffPtr) = SPI_RXDR_LOAD_U16(hspi);
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;

Expand Down Expand Up @@ -2933,7 +2938,7 @@ static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi)
{
/* Transmit data in 16 Bit mode */
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
SPI_TXDR_STORE_U16(hspi, *((uint16_t *)hspi->pTxBuffPtr));
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;

Expand Down

0 comments on commit 90b9961

Please sign in to comment.