mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-12 19:10:32 +03:00
Use union to access access size sensitive registers
As described in RM0433 section 49.4.13 "Data packing", STM32H7's SPI data register supports data packing and it is sensitive to actual access width. The original code used pointer casting to obtain a code to access the register in a desired size. However, these operation results in strict aliasing warnings (deferencing punned pointer) and are not desirable. Here, we declare a union that allow access to a 32-bit register in 8, 16 or 32-bit width and cast pointer to the original RXDR and TXDR data registers and then access the portion of the register through an appropriate union member. XXX FIXME Only handled 16-bit access case, as 32-bit (original declaration) and 8-bit (allowed) cases do not generate warnings, but these should be handled similarly for correctness and consistency of the code.
This commit is contained in:
parent
8670c05068
commit
7a0d3e73f5
1 changed files with 37 additions and 13 deletions
|
@ -141,6 +141,30 @@ static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi);
|
|||
static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi);
|
||||
static uint32_t SPI_GetPacketSize(SPI_HandleTypeDef *hspi);
|
||||
|
||||
/*
|
||||
* Notes on variable size access to data registers (by jflyper@github.com)
|
||||
*
|
||||
* As described in RM0433 section 49.4.13 "Data packing", STM32H7's SPI data register
|
||||
* supports data packing and it is sensitive to actual access width.
|
||||
* The original code used pointer casting to obtain a code to access the register in
|
||||
* a desired size.
|
||||
* However, these operation results in strict aliasing warnings (deferencing punned pointer)
|
||||
* and are not desirable.
|
||||
*
|
||||
* Here, we declare a union that allow access to a 32-bit register in 8, 16 or 32-bit width
|
||||
* and cast pointer to the original RXDR and TXDR data registers and then access the
|
||||
* portion of the register through an appropriate union member.
|
||||
*
|
||||
* XXX FIXME Only handled 16-bit access case, as 32-bit (original declaration) and 8-bit
|
||||
* (allowed) cases do not generate warnings, but these should be handled similarly for
|
||||
* correct-ness and consistency of the code.
|
||||
*/
|
||||
|
||||
typedef union {
|
||||
__IO uint32_t u_reg32;
|
||||
__IO uint16_t u_reg16;
|
||||
__IO uint8_t u_reg8;
|
||||
} reg_u;
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -588,7 +612,7 @@ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint
|
|||
}
|
||||
else
|
||||
{
|
||||
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount--;
|
||||
}
|
||||
|
@ -627,7 +651,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);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount-=2;
|
||||
}
|
||||
|
@ -802,7 +826,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount--;
|
||||
}
|
||||
|
@ -842,7 +866,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount-=2;
|
||||
}
|
||||
|
@ -1019,7 +1043,7 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxD
|
|||
}
|
||||
else
|
||||
{
|
||||
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount--;
|
||||
}
|
||||
|
@ -1036,7 +1060,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount--;
|
||||
}
|
||||
|
@ -1072,7 +1096,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);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount-=2;
|
||||
}
|
||||
|
@ -1095,7 +1119,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount-=2;
|
||||
}
|
||||
|
@ -2181,7 +2205,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
}
|
||||
/* Receive data in 8 Bit mode */
|
||||
|
@ -2738,7 +2762,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount--;
|
||||
|
||||
|
@ -2804,7 +2828,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);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount--;
|
||||
|
||||
|
@ -2868,7 +2892,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) = ((reg_u *)&hspi->Instance->RXDR)->u_reg16;
|
||||
hspi->pRxBuffPtr += sizeof(uint16_t);
|
||||
hspi->RxXferCount--;
|
||||
|
||||
|
@ -2931,7 +2955,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);
|
||||
((reg_u *)&hspi->Instance->TXDR)->u_reg16 = *((uint16_t *)hspi->pTxBuffPtr);
|
||||
hspi->pTxBuffPtr += sizeof(uint16_t);
|
||||
hspi->TxXferCount--;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue