From 7f12ad2a8c7638912e15a66a22da62bf749db2f3 Mon Sep 17 00:00:00 2001 From: Bradley Scott Date: Mon, 10 Apr 2017 15:28:19 -0400 Subject: [PATCH] STM32F3: Correct handling of USB ISTR and endpoint registers The USB ISTR register consists of a mix of bits that are write-zero-to-clear and read only bits. As such, to clear a bit in the ISTR, you should simply write the bitwise-NOT of the bit to clear. Previously, the __HAL_PCD_CLEAR_FLAG() macro would do a bitwise-AND with the ISTR register contents to clear a bit, but this could result in another bit being inadvertently cleared if it is set by hardware between the read and the write of the ISTR register. Similarly, the USB endpoint registers have two bits that are write-zero-to-clear, USB_EP_CTR_RX and USB_EP_CTR_TX, but the PCD_CLEAR_RX_EP_CTR() and PCD_CLEAR_TX_EP_CTR() macros wrote back the last read value for one of these bits when clearing the other bit. This could result in inadvertent clearing of one of these bits if it were set by the hardware between the read and the write. These macros have now both been adjusted to always write one to the bit not being cleared to prevent inadvertent clears. --- .../TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_pcd.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_pcd.h b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_pcd.h index afc7234c16..624dc3bd9b 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_pcd.h +++ b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_pcd.h @@ -232,7 +232,7 @@ typedef struct * @{ */ #define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISTR) & (__INTERRUPT__)) == (__INTERRUPT__)) -#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISTR) &= (uint16_t)(~(__INTERRUPT__)))) +#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISTR) = (uint16_t)(~(__INTERRUPT__)))) // MBED fix #define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_WAKEUP_EXTI_LINE #define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_WAKEUP_EXTI_LINE) @@ -622,9 +622,9 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd); * @retval None */ #define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ - PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK)) + ( PCD_GET_ENDPOINT((USBx), (bEpNum)) | USB_EP_CTR_TX ) & ~USB_EP_CTR_RX & USB_EPREG_MASK)) // MBED fix #define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ - PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK)) + ( PCD_GET_ENDPOINT((USBx), (bEpNum)) | USB_EP_CTR_RX ) & ~USB_EP_CTR_TX & USB_EPREG_MASK)) // MBED fix /** * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register.