diff --git a/CI/utils/patch/HAL/F1/0001-F1-I2C-HAL-fix-generate-Start-only-once-Stop-is-fini.patch b/CI/utils/patch/HAL/F1/0001-F1-I2C-HAL-fix-generate-Start-only-once-Stop-is-fini.patch
deleted file mode 100644
index 1350923187..0000000000
--- a/CI/utils/patch/HAL/F1/0001-F1-I2C-HAL-fix-generate-Start-only-once-Stop-is-fini.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 4aba75ec152a2d2c65d07c1912da9eb4ea08be2e Mon Sep 17 00:00:00 2001
-From: Alexandre Bourdiol <alexandre.bourdiol@st.com>
-Date: Mon, 27 Jan 2020 18:23:15 +0100
-Subject: [PATCH 1/1] [F1] I2C HAL fix: generate Start only once Stop is
- finished
-
----
- .../Src/stm32f1xx_hal_i2c.c                   | 87 ++++++++++++++++++-
- 1 file changed, 86 insertions(+), 1 deletion(-)
-
-diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
-index 6e74e699..fc108e0b 100644
---- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
-+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
-@@ -3492,6 +3492,27 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16
-       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-     }
- 
-+    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-+    /* Wait until STOP flag is reset */
-+    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-+    do
-+    {
-+      count--;
-+      if (count == 0U)
-+      {
-+        hi2c->PreviousState       = I2C_STATE_NONE;
-+        hi2c->State               = HAL_I2C_STATE_READY;
-+        hi2c->Mode                = HAL_I2C_MODE_NONE;
-+        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-+
-+        /* Process Unlocked */
-+        __HAL_UNLOCK(hi2c);
-+
-+        return HAL_ERROR;
-+      }
-+    }
-+    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-+
-     /* Process Locked */
-     __HAL_LOCK(hi2c);
- 
-@@ -3591,6 +3612,27 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint1
-       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-     }
- 
-+    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-+    /* Wait until STOP flag is reset */
-+    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-+    do
-+    {
-+      count--;
-+      if (count == 0U)
-+      {
-+        hi2c->PreviousState       = I2C_STATE_NONE;
-+        hi2c->State               = HAL_I2C_STATE_READY;
-+        hi2c->Mode                = HAL_I2C_MODE_NONE;
-+        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-+
-+        /* Process Unlocked */
-+        __HAL_UNLOCK(hi2c);
-+
-+        return HAL_ERROR;
-+      }
-+    }
-+    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-+
-     /* Process Locked */
-     __HAL_LOCK(hi2c);
- 
-@@ -3757,6 +3799,27 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_
-       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-     }
- 
-+    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-+    /* Wait until STOP flag is reset */
-+    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-+    do
-+    {
-+      count--;
-+      if (count == 0U)
-+      {
-+        hi2c->PreviousState       = I2C_STATE_NONE;
-+        hi2c->State               = HAL_I2C_STATE_READY;
-+        hi2c->Mode                = HAL_I2C_MODE_NONE;
-+        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-+
-+        /* Process Unlocked */
-+        __HAL_UNLOCK(hi2c);
-+
-+        return HAL_ERROR;
-+      }
-+    }
-+    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-+
-     /* Process Locked */
-     __HAL_LOCK(hi2c);
- 
-@@ -3882,6 +3945,27 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16
-       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-     }
- 
-+    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-+    /* Wait until STOP flag is reset */
-+    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-+    do
-+    {
-+      count--;
-+      if (count == 0U)
-+      {
-+        hi2c->PreviousState       = I2C_STATE_NONE;
-+        hi2c->State               = HAL_I2C_STATE_READY;
-+        hi2c->Mode                = HAL_I2C_MODE_NONE;
-+        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-+
-+        /* Process Unlocked */
-+        __HAL_UNLOCK(hi2c);
-+
-+        return HAL_ERROR;
-+      }
-+    }
-+    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-+
-     /* Process Locked */
-     __HAL_LOCK(hi2c);
- 
-@@ -4565,7 +4649,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevA
-   UNUSED(DevAddress);
- 
-   /* Abort Master transfer during Receive or Transmit process    */
--  if (hi2c->Mode == HAL_I2C_MODE_MASTER)
-+  if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && (hi2c->Mode == HAL_I2C_MODE_MASTER))
-   {
-     /* Process Locked */
-     __HAL_LOCK(hi2c);
-@@ -4596,6 +4680,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevA
-   {
-     /* Wrong usage of abort function */
-     /* This function should be used only in case of abort monitored by master device */
-+    /* Or periphal is not in busy state, mean there is no active sequence to be abort */
-     return HAL_ERROR;
-   }
- }
--- 
-2.25.1.windows.1
-
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
index ba2f673e8b..35092c0531 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
@@ -57,6 +57,7 @@ typedef enum
   * @}
   */
 /* Exported types ------------------------------------------------------------*/
+extern __IO uint32_t uwTick;
 extern uint32_t uwTickPrio;
 extern HAL_TickFreqTypeDef uwTickFreq;
 
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
index 42f4c8b2a6..87471adb29 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
@@ -108,8 +108,8 @@ typedef struct
 /** @defgroup HCD_Speed HCD Speed
   * @{
   */
-#define HCD_SPEED_FULL               USBH_FS_SPEED
-#define HCD_SPEED_LOW                USBH_LS_SPEED
+#define HCD_SPEED_FULL               USBH_FSLS_SPEED
+#define HCD_SPEED_LOW                USBH_FSLS_SPEED
 
 /**
   * @}
@@ -142,9 +142,9 @@ typedef struct
 
 /* Exported macro ------------------------------------------------------------*/
 /** @defgroup HCD_Exported_Macros HCD Exported Macros
- *  @brief macros to handle interrupts and specific clock configurations
- * @{
- */
+  *  @brief macros to handle interrupts and specific clock configurations
+  * @{
+  */
 #define __HAL_HCD_ENABLE(__HANDLE__)                   (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
 #define __HAL_HCD_DISABLE(__HANDLE__)                  (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
 
@@ -169,19 +169,15 @@ typedef struct
 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
   * @{
   */
-HAL_StatusTypeDef      HAL_HCD_Init(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef      HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef      HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
-                                       uint8_t ch_num,
-                                       uint8_t epnum,
-                                       uint8_t dev_address,
-                                       uint8_t speed,
-                                       uint8_t ep_type,
-                                       uint16_t mps);
+HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
+                                  uint8_t epnum, uint8_t dev_address,
+                                  uint8_t speed, uint8_t ep_type, uint16_t mps);
 
-HAL_StatusTypeDef     HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num);
-void                  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd);
-void                  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num);
+void              HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd);
+void              HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
 
 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
 /** @defgroup HAL_HCD_Callback_ID_enumeration_definition HAL USB OTG HCD Callback ID enumeration definition
@@ -190,14 +186,14 @@ void                  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
   */
 typedef enum
 {
-  HAL_HCD_SOF_CB_ID           = 0x01,       /*!< USB HCD SOF callback ID           */
-  HAL_HCD_CONNECT_CB_ID       = 0x02,       /*!< USB HCD Connect callback ID       */
-  HAL_HCD_DISCONNECT_CB_ID   = 0x03,       /*!< USB HCD Disconnect callback ID    */
-  HAL_HCD_PORT_ENABLED_CB_ID   = 0x04,      /*!< USB HCD Port Enable callback ID   */
-  HAL_HCD_PORT_DISABLED_CB_ID  = 0x05,      /*!< USB HCD Port Disable callback ID  */
+  HAL_HCD_SOF_CB_ID            = 0x01,       /*!< USB HCD SOF callback ID           */
+  HAL_HCD_CONNECT_CB_ID        = 0x02,       /*!< USB HCD Connect callback ID       */
+  HAL_HCD_DISCONNECT_CB_ID     = 0x03,       /*!< USB HCD Disconnect callback ID    */
+  HAL_HCD_PORT_ENABLED_CB_ID   = 0x04,       /*!< USB HCD Port Enable callback ID   */
+  HAL_HCD_PORT_DISABLED_CB_ID  = 0x05,       /*!< USB HCD Port Disable callback ID  */
 
-  HAL_HCD_MSPINIT_CB_ID       = 0x06,       /*!< USB HCD MspInit callback ID       */
-  HAL_HCD_MSPDEINIT_CB_ID     = 0x07        /*!< USB HCD MspDeInit callback ID     */
+  HAL_HCD_MSPINIT_CB_ID        = 0x06,       /*!< USB HCD MspInit callback ID       */
+  HAL_HCD_MSPDEINIT_CB_ID      = 0x07        /*!< USB HCD MspDeInit callback ID     */
 
 } HAL_HCD_CallbackIDTypeDef;
 /**
@@ -217,10 +213,16 @@ typedef void (*pHCD_HC_NotifyURBChangeCallbackTypeDef)(HCD_HandleTypeDef *hhcd,
   * @}
   */
 
-HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback);
-HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID);
+HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
+                                           HAL_HCD_CallbackIDTypeDef CallbackID,
+                                           pHCD_CallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd,
+                                             HAL_HCD_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
+                                                             pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback);
 
-HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback);
 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd);
 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
 /**
@@ -231,25 +233,21 @@ HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef
 /** @addtogroup HCD_Exported_Functions_Group2 Input and Output operation functions
   * @{
   */
-HAL_StatusTypeDef       HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
-                                                 uint8_t ch_num,
-                                                 uint8_t direction,
-                                                 uint8_t ep_type,
-                                                 uint8_t token,
-                                                 uint8_t *pbuff,
-                                                 uint16_t length,
-                                                 uint8_t do_ping);
+HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
+                                           uint8_t direction, uint8_t ep_type,
+                                           uint8_t token, uint8_t *pbuff,
+                                           uint16_t length, uint8_t do_ping);
 
 /* Non-Blocking mode: Interrupt */
-void             HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd);
-void             HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,
-                                                     uint8_t chnum,
-                                                     HCD_URBStateTypeDef urb_state);
+void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum,
+                                         HCD_URBStateTypeDef urb_state);
 /**
   * @}
   */
@@ -258,9 +256,12 @@ void             HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,
 /** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions
   * @{
   */
-HAL_StatusTypeDef       HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef       HAL_HCD_Start(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef       HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
+/**
+  * @}
+  */
 /**
   * @}
   */
@@ -271,10 +272,11 @@ HAL_StatusTypeDef       HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
   */
 HCD_StateTypeDef        HAL_HCD_GetState(HCD_HandleTypeDef *hhcd);
 HCD_URBStateTypeDef     HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-uint32_t                HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum);
 HCD_HCStateTypeDef      HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+uint32_t                HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum);
 uint32_t                HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd);
 uint32_t                HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
+
 /**
   * @}
   */
@@ -285,13 +287,11 @@ uint32_t                HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
 
 /* Private macros ------------------------------------------------------------*/
 /** @defgroup HCD_Private_Macros HCD Private Macros
- * @{
- */
-
+  * @{
+  */
 /**
   * @}
   */
-
 /* Private functions prototypes ----------------------------------------------*/
 /** @defgroup HCD_Private_Functions_Prototypes HCD Private Functions Prototypes
   * @{
@@ -306,14 +306,6 @@ uint32_t                HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
   * @{
   */
 
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
 /**
   * @}
   */
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
index cdcf2daeef..216a2fcbef 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
@@ -170,6 +170,7 @@ typedef enum
 #define HAL_I2C_ERROR_TIMEOUT           0x00000020U    /*!< Timeout Error         */
 #define HAL_I2C_ERROR_SIZE              0x00000040U    /*!< Size Management error */
 #define HAL_I2C_ERROR_DMA_PARAM         0x00000080U    /*!< DMA Parameter Error   */
+#define HAL_I2C_WRONG_START             0x00000200U    /*!< Wrong start Error     */
 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
 #define HAL_I2C_ERROR_INVALID_CALLBACK  0x00000100U    /*!< Invalid Callback error */
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
@@ -181,7 +182,11 @@ typedef enum
   * @brief  I2C handle Structure definition
   * @{
   */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
 typedef struct __I2C_HandleTypeDef
+#else
+typedef struct
+#endif  /* USE_HAL_I2C_REGISTER_CALLBACKS */
 {
   I2C_TypeDef                *Instance;      /*!< I2C registers base address               */
 
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
index fde128c79c..49982338cd 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
@@ -18,21 +18,18 @@
   */
 
 /* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PCD_H
-#define __STM32F1xx_HAL_PCD_H
+#ifndef STM32F1xx_HAL_PCD_H
+#define STM32F1xx_HAL_PCD_H
 
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f1xx_ll_usb.h"
 
+#if defined (USB) || defined (USB_OTG_FS)
+
 /** @addtogroup STM32F1xx_HAL_Driver
   * @{
   */
@@ -51,68 +48,106 @@
   */
 typedef enum
 {
-  HAL_PCD_STATE_RESET   = 0x00U,
-  HAL_PCD_STATE_READY   = 0x01U,
-  HAL_PCD_STATE_ERROR   = 0x02U,
-  HAL_PCD_STATE_BUSY    = 0x03U,
-  HAL_PCD_STATE_TIMEOUT = 0x04U
+  HAL_PCD_STATE_RESET   = 0x00,
+  HAL_PCD_STATE_READY   = 0x01,
+  HAL_PCD_STATE_ERROR   = 0x02,
+  HAL_PCD_STATE_BUSY    = 0x03,
+  HAL_PCD_STATE_TIMEOUT = 0x04
 } PCD_StateTypeDef;
 
-#if defined (USB)
-/**
-  * @brief  PCD double buffered endpoint direction
-  */
+/* Device LPM suspend state */
 typedef enum
 {
-  PCD_EP_DBUF_OUT,
-  PCD_EP_DBUF_IN,
-  PCD_EP_DBUF_ERR,
-}PCD_EP_DBUF_DIR;
+  LPM_L0 = 0x00, /* on */
+  LPM_L1 = 0x01, /* LPM L1 sleep */
+  LPM_L2 = 0x02, /* suspend */
+  LPM_L3 = 0x03, /* off */
+} PCD_LPM_StateTypeDef;
 
-/**
-  * @brief  PCD endpoint buffer number
-  */
 typedef enum
 {
-  PCD_EP_NOBUF,
-  PCD_EP_BUF0,
-  PCD_EP_BUF1
-}PCD_EP_BUF_NUM;
-#endif /* USB */
+  PCD_LPM_L0_ACTIVE = 0x00, /* on */
+  PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
+} PCD_LPM_MsgTypeDef;
 
+typedef enum
+{
+  PCD_BCD_ERROR                     = 0xFF,
+  PCD_BCD_CONTACT_DETECTION         = 0xFE,
+  PCD_BCD_STD_DOWNSTREAM_PORT       = 0xFD,
+  PCD_BCD_CHARGING_DOWNSTREAM_PORT  = 0xFC,
+  PCD_BCD_DEDICATED_CHARGING_PORT   = 0xFB,
+  PCD_BCD_DISCOVERY_COMPLETED       = 0x00,
+
+} PCD_BCD_MsgTypeDef;
+
+#if defined (USB)
+
+#endif /* defined (USB) */
 #if defined (USB_OTG_FS)
 typedef USB_OTG_GlobalTypeDef  PCD_TypeDef;
 typedef USB_OTG_CfgTypeDef     PCD_InitTypeDef;
 typedef USB_OTG_EPTypeDef      PCD_EPTypeDef;
-#endif /* USB_OTG_FS */
-
+#endif /* defined (USB_OTG_FS) */
 #if defined (USB)
 typedef USB_TypeDef        PCD_TypeDef;
 typedef USB_CfgTypeDef     PCD_InitTypeDef;
 typedef USB_EPTypeDef      PCD_EPTypeDef;
-#endif /* USB */
+#endif /* defined (USB) */
 
 /**
   * @brief  PCD Handle Structure definition
   */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+typedef struct __PCD_HandleTypeDef
+#else
 typedef struct
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 {
-  PCD_TypeDef             *Instance;   /*!< Register base address               */
-  PCD_InitTypeDef         Init;        /*!< PCD required parameters             */
-  __IO uint8_t            USB_Address; /*!< USB Address: not used by USB OTG FS */
-  PCD_EPTypeDef           IN_ep[16];   /*!< IN endpoint parameters              */
-  PCD_EPTypeDef           OUT_ep[16];  /*!< OUT endpoint parameters             */
-  HAL_LockTypeDef         Lock;        /*!< PCD peripheral status               */
-  __IO PCD_StateTypeDef   State;       /*!< PCD communication state             */
-  uint32_t                Setup[12U];   /*!< Setup packet buffer                 */
-  void                    *pData;      /*!< Pointer to upper stack Handler      */
+  PCD_TypeDef             *Instance;   /*!< Register base address             */
+  PCD_InitTypeDef         Init;        /*!< PCD required parameters           */
+  __IO uint8_t            USB_Address; /*!< USB Address                       */
+#if defined (USB_OTG_FS)
+  PCD_EPTypeDef           IN_ep[16];   /*!< IN endpoint parameters            */
+  PCD_EPTypeDef           OUT_ep[16];  /*!< OUT endpoint parameters           */
+#endif /* defined (USB_OTG_FS) */
+#if defined (USB)
+  PCD_EPTypeDef           IN_ep[8];   /*!< IN endpoint parameters             */
+  PCD_EPTypeDef           OUT_ep[8];  /*!< OUT endpoint parameters            */
+#endif /* defined (USB) */
+  HAL_LockTypeDef         Lock;        /*!< PCD peripheral status             */
+  __IO PCD_StateTypeDef   State;       /*!< PCD communication state           */
+  __IO  uint32_t          ErrorCode;   /*!< PCD Error code                    */
+  uint32_t                Setup[12];   /*!< Setup packet buffer               */
+  PCD_LPM_StateTypeDef    LPM_State;   /*!< LPM State                         */
+  uint32_t                BESL;
+
+  void                    *pData;      /*!< Pointer to upper stack Handler */
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+  void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd);                              /*!< USB OTG PCD SOF callback                */
+  void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd);                       /*!< USB OTG PCD Setup Stage callback        */
+  void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd);                            /*!< USB OTG PCD Reset callback              */
+  void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Suspend callback            */
+  void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd);                           /*!< USB OTG PCD Resume callback             */
+  void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Connect callback            */
+  void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd);                       /*!< USB OTG PCD Disconnect callback         */
+
+  void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);      /*!< USB OTG PCD Data OUT Stage callback     */
+  void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);       /*!< USB OTG PCD Data IN Stage callback      */
+  void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);  /*!< USB OTG PCD ISO OUT Incomplete callback */
+  void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);   /*!< USB OTG PCD ISO IN Incomplete callback  */
+
+  void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Msp Init callback           */
+  void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd);                        /*!< USB OTG PCD Msp DeInit callback         */
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 } PCD_HandleTypeDef;
 
 /**
   * @}
   */
 
-/* Include PCD HAL Extension module */
+/* Include PCD HAL Extended module */
 #include "stm32f1xx_hal_pcd_ex.h"
 
 /* Exported constants --------------------------------------------------------*/
@@ -123,9 +158,7 @@ typedef struct
 /** @defgroup PCD_Speed PCD Speed
   * @{
   */
-#define PCD_SPEED_HIGH                                                0U /* Not Supported */
-#define PCD_SPEED_HIGH_IN_FULL                                        1U /* Not Supported */
-#define PCD_SPEED_FULL                                                2U
+#define PCD_SPEED_FULL               USBD_FS_SPEED
 /**
   * @}
   */
@@ -133,17 +166,21 @@ typedef struct
 /** @defgroup PCD_PHY_Module PCD PHY Module
   * @{
   */
-#define PCD_PHY_EMBEDDED                                              2U
+#define PCD_PHY_ULPI                 1U
+#define PCD_PHY_EMBEDDED             2U
+#define PCD_PHY_UTMI                 3U
 /**
   * @}
   */
 
-/** @defgroup PCD_Turnaround_Timeout Turnaround Timeout Value
+/** @defgroup PCD_Error_Code_definition PCD Error Code definition
+  * @brief  PCD Error Code definition
   * @{
   */
-#ifndef USBD_FS_TRDT_VALUE
- #define USBD_FS_TRDT_VALUE           5U
-#endif /* USBD_FS_TRDT_VALUE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+#define  HAL_PCD_ERROR_INVALID_CALLBACK                        (0x00000010U)    /*!< Invalid Callback error  */
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
 /**
   * @}
   */
@@ -154,84 +191,54 @@ typedef struct
 
 /* Exported macros -----------------------------------------------------------*/
 /** @defgroup PCD_Exported_Macros PCD Exported Macros
- *  @brief macros to handle interrupts and specific clock configurations
- * @{
- */
+  *  @brief macros to handle interrupts and specific clock configurations
+  * @{
+  */
 #if defined (USB_OTG_FS)
+#define __HAL_PCD_ENABLE(__HANDLE__)                       (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_DISABLE(__HANDLE__)                      (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
 
-#define __HAL_PCD_ENABLE(__HANDLE__)                                  USB_EnableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_PCD_DISABLE(__HANDLE__)                                 USB_DisableGlobalInt ((__HANDLE__)->Instance)
-
-#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__)                 ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
-#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)               (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
-#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__)                    (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
-
-#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__)                         *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= \
-                                                                      ~(USB_OTG_PCGCCTL_STOPCLK)
-
-#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__)                           *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
+#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__)      ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
+#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)    (((__HANDLE__)->Instance->GINTSTS) &=  (__INTERRUPT__))
+#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__)         (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
 
-#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__)                        ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
 
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT()                      EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT()                     EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG()                       EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG()                     EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
+#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__)       *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
 
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE()                 \
-                        do{                                               \
-                            EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
-                            EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE;    \
-                          } while(0U)
+#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__)         *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
 
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE()                \
-                        do{                                               \
-                            EXTI->FTSR |= (USB_OTG_FS_WAKEUP_EXTI_LINE);  \
-                            EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
-                          } while(0U)
+#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__)      ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
 
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE()         \
-                        do{                                               \
-                            EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
-                            EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
-                            EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE;    \
-                            EXTI->FTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE;    \
-                          } while(0U)
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT()    EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT()   EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG()     EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG()   EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
 
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT()                  (EXTI->SWIER |= USB_OTG_FS_WAKEUP_EXTI_LINE)
-#endif /* USB_OTG_FS */
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
+  do { \
+    EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
+    EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
+  } while(0U)
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
-#define __HAL_PCD_ENABLE(__HANDLE__)                                  USB_EnableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_PCD_DISABLE(__HANDLE__)                                 USB_DisableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_ENABLE(__HANDLE__)                                  (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_DISABLE(__HANDLE__)                                 (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
 #define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__)                 ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
-#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)               (((__HANDLE__)->Instance->ISTR) &= ~(__INTERRUPT__))
+#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)               (((__HANDLE__)->Instance->ISTR) &= (uint16_t)(~(__INTERRUPT__)))
 
 #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)
 #define __HAL_USB_WAKEUP_EXTI_GET_FLAG()                              EXTI->PR & (USB_WAKEUP_EXTI_LINE)
 #define __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG()                            EXTI->PR = USB_WAKEUP_EXTI_LINE
 
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE()                 \
-                        do{                                        \
-                            EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
-                            EXTI->RTSR |= USB_WAKEUP_EXTI_LINE;    \
-                          } while(0U)
+#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
+  do { \
+    EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
+    EXTI->RTSR |= USB_WAKEUP_EXTI_LINE; \
+  } while(0U)
 
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE()                \
-                        do{                                        \
-                            EXTI->FTSR |= (USB_WAKEUP_EXTI_LINE);  \
-                            EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
-                          } while(0U)
-
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE()         \
-                        do{                                        \
-                            EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
-                            EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
-                            EXTI->RTSR |= USB_WAKEUP_EXTI_LINE;    \
-                            EXTI->FTSR |= USB_WAKEUP_EXTI_LINE;    \
-                          } while(0U)
-#endif /* USB */
+#endif /* defined (USB) */
 
 /**
   * @}
@@ -247,33 +254,102 @@ typedef struct
   * @{
   */
 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_DeInit (PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
+  * @brief  HAL USB OTG PCD Callback ID enumeration definition
+  * @{
+  */
+typedef enum
+{
+  HAL_PCD_SOF_CB_ID          = 0x01,      /*!< USB PCD SOF callback ID          */
+  HAL_PCD_SETUPSTAGE_CB_ID   = 0x02,      /*!< USB PCD Setup Stage callback ID  */
+  HAL_PCD_RESET_CB_ID        = 0x03,      /*!< USB PCD Reset callback ID        */
+  HAL_PCD_SUSPEND_CB_ID      = 0x04,      /*!< USB PCD Suspend callback ID      */
+  HAL_PCD_RESUME_CB_ID       = 0x05,      /*!< USB PCD Resume callback ID       */
+  HAL_PCD_CONNECT_CB_ID      = 0x06,      /*!< USB PCD Connect callback ID      */
+  HAL_PCD_DISCONNECT_CB_ID   = 0x07,      /*!< USB PCD Disconnect callback ID   */
+
+  HAL_PCD_MSPINIT_CB_ID      = 0x08,      /*!< USB PCD MspInit callback ID      */
+  HAL_PCD_MSPDEINIT_CB_ID    = 0x09       /*!< USB PCD MspDeInit callback ID    */
+
+} HAL_PCD_CallbackIDTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
+  * @brief  HAL USB OTG PCD Callback pointer definition
+  * @{
+  */
+
+typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd);                                   /*!< pointer to a common USB OTG PCD callback function  */
+typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);        /*!< pointer to USB OTG PCD Data OUT Stage callback     */
+typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);         /*!< pointer to USB OTG PCD Data IN Stage callback      */
+typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);        /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */
+typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);         /*!< pointer to USB OTG PCD ISO IN Incomplete callback  */
+
+/**
+  * @}
+  */
+
+HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
+                                           HAL_PCD_CallbackIDTypeDef CallbackID,
+                                           pPCD_CallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd,
+                                             HAL_PCD_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
+                                                       pPCD_DataOutStageCallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd);
+
+HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
+                                                      pPCD_DataInStageCallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd);
+
+HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
+                                                       pPCD_IsoOutIncpltCallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd);
+
+HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
+                                                      pPCD_IsoInIncpltCallbackTypeDef pCallback);
+
+HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd);
+
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 /**
   * @}
   */
 
 /* I/O operation functions  ***************************************************/
 /* Non-Blocking mode: Interrupt */
-/** @addtogroup PCD_Exported_Functions_Group2 IO operation functions
+/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
   * @{
   */
 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd);
 
-void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
+
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
 /**
   * @}
   */
@@ -285,16 +361,24 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
-HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type);
+HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
+                                  uint16_t ep_mps, uint8_t ep_type);
+
 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
-HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
-uint16_t          HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
+                                     uint8_t *pBuf, uint32_t len);
+
+HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
+                                      uint8_t *pBuf, uint32_t len);
+
+
 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
+
+uint32_t          HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
 /**
   * @}
   */
@@ -320,28 +404,24 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
   * @{
   */
 #if defined (USB_OTG_FS)
-#define USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE                            0x08U
-#define USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE                           0x0CU
-#define USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE                    0x10U
-
-#define USB_OTG_FS_WAKEUP_EXTI_LINE                                    0x00040000U  /*!< External interrupt line 18 Connected to the USB EXTI Line */
-#endif /* USB_OTG_FS */
+#define USB_OTG_FS_WAKEUP_EXTI_LINE                                   (0x1U << 18)  /*!< USB FS EXTI Line WakeUp Interrupt */
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
-#define  USB_WAKEUP_EXTI_LINE                                         0x00040000U  /*!< External interrupt line 18 Connected to the USB EXTI Line */
-#endif /* USB */
+#define USB_WAKEUP_EXTI_LINE                                          (0x1U << 18)  /*!< USB FS EXTI Line WakeUp Interrupt */
+#endif /* defined (USB) */
+
 /**
   * @}
   */
-
 #if defined (USB)
 /** @defgroup PCD_EP0_MPS PCD EP0 MPS
   * @{
   */
-#define PCD_EP0MPS_64                                                 DEP0CTL_MPS_64
-#define PCD_EP0MPS_32                                                 DEP0CTL_MPS_32
-#define PCD_EP0MPS_16                                                 DEP0CTL_MPS_16
-#define PCD_EP0MPS_08                                                 DEP0CTL_MPS_8
+#define PCD_EP0MPS_64                                                 EP_MPS_64
+#define PCD_EP0MPS_32                                                 EP_MPS_32
+#define PCD_EP0MPS_16                                                 EP_MPS_16
+#define PCD_EP0MPS_08                                                 EP_MPS_8
 /**
   * @}
   */
@@ -349,14 +429,14 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 /** @defgroup PCD_ENDP PCD ENDP
   * @{
   */
-#define PCD_ENDP0                                                     ((uint8_t)0)
-#define PCD_ENDP1                                                     ((uint8_t)1)
-#define PCD_ENDP2                                                     ((uint8_t)2)
-#define PCD_ENDP3                                                     ((uint8_t)3)
-#define PCD_ENDP4                                                     ((uint8_t)4)
-#define PCD_ENDP5                                                     ((uint8_t)5)
-#define PCD_ENDP6                                                     ((uint8_t)6)
-#define PCD_ENDP7                                                     ((uint8_t)7)
+#define PCD_ENDP0                                                     0U
+#define PCD_ENDP1                                                     1U
+#define PCD_ENDP2                                                     2U
+#define PCD_ENDP3                                                     3U
+#define PCD_ENDP4                                                     4U
+#define PCD_ENDP5                                                     5U
+#define PCD_ENDP6                                                     6U
+#define PCD_ENDP7                                                     7U
 /**
   * @}
   */
@@ -369,167 +449,185 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 /**
   * @}
   */
-#endif /* USB */
+#endif /* defined (USB) */
 /**
   * @}
   */
 
+#if defined (USB_OTG_FS)
+#ifndef USB_OTG_DOEPINT_OTEPSPR
+#define USB_OTG_DOEPINT_OTEPSPR                (0x1UL << 5)      /*!< Status Phase Received interrupt */
+#endif
+
+#ifndef USB_OTG_DOEPMSK_OTEPSPRM
+#define USB_OTG_DOEPMSK_OTEPSPRM               (0x1UL << 5)      /*!< Setup Packet Received interrupt mask */
+#endif
+
+#ifndef USB_OTG_DOEPINT_NAK
+#define USB_OTG_DOEPINT_NAK                    (0x1UL << 13)      /*!< NAK interrupt */
+#endif
+
+#ifndef USB_OTG_DOEPMSK_NAKM
+#define USB_OTG_DOEPMSK_NAKM                   (0x1UL << 13)      /*!< OUT Packet NAK interrupt mask */
+#endif
+
+#ifndef USB_OTG_DOEPINT_STPKTRX
+#define USB_OTG_DOEPINT_STPKTRX                (0x1UL << 15)      /*!< Setup Packet Received interrupt */
+#endif
+
+#ifndef USB_OTG_DOEPMSK_NYETM
+#define USB_OTG_DOEPMSK_NYETM                  (0x1UL << 14)      /*!< Setup Packet Received interrupt mask */
+#endif
+#endif /* defined (USB_OTG_FS) */
+
 /* Private macros ------------------------------------------------------------*/
-/** @addtogroup PCD_Private_Macros PCD Private Macros
- * @{
- */
+/** @defgroup PCD_Private_Macros PCD Private Macros
+  * @{
+  */
 #if defined (USB)
+/********************  Bit definition for USB_COUNTn_RX register  *************/
+#define USB_CNTRX_NBLK_MSK                    (0x1FU << 10)
+#define USB_CNTRX_BLSIZE                      (0x1U << 15)
+
 /* SetENDPOINT */
-#define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue)  (*(&(USBx)->EP0R + (bEpNum) * 2U)= (uint16_t)(wRegValue))
+#define PCD_SET_ENDPOINT(USBx, bEpNum, wRegValue)  (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)) = (uint16_t)(wRegValue))
 
 /* GetENDPOINT */
-#define PCD_GET_ENDPOINT(USBx, bEpNum)            (*(&(USBx)->EP0R + (bEpNum) * 2U))
+#define PCD_GET_ENDPOINT(USBx, bEpNum)             (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)))
 
 /* ENDPOINT transfer */
-#define USB_EP0StartXfer                          USB_EPStartXfer
+#define USB_EP0StartXfer                           USB_EPStartXfer
 
 /**
   * @brief  sets the type in the endpoint register(bits EP_TYPE[1:0])
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wType: Endpoint Type.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wType Endpoint Type.
   * @retval None
   */
-#define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
-                                           ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) )))
+#define PCD_SET_EPTYPE(USBx, bEpNum, wType) (PCD_SET_ENDPOINT((USBx), (bEpNum), ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) | USB_EP_CTR_TX | USB_EP_CTR_RX)))
 
 /**
   * @brief  gets the type in the endpoint register(bits EP_TYPE[1:0])
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval Endpoint Type
   */
 #define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD)
 
 /**
   * @brief free buffer used from the application realizing it to the line
-          toggles bit SW_BUF in the double buffered endpoint register
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  bDir: Direction
+  *         toggles bit SW_BUF in the double buffered endpoint register
+  * @param USBx USB device.
+  * @param   bEpNum, bDir
   * @retval None
   */
-#define PCD_FreeUserBuffer(USBx, bEpNum, bDir)\
-{\
-  if ((bDir) == PCD_EP_DBUF_OUT)\
-  { /* OUT double buffered endpoint */\
-    PCD_TX_DTOG((USBx), (bEpNum));\
-  }\
-  else if ((bDir) == PCD_EP_DBUF_IN)\
-  { /* IN double buffered endpoint */\
-    PCD_RX_DTOG((USBx), (bEpNum));\
-  }\
-}
-
-/**
-  * @brief gets direction of the double buffered endpoint
-  * @param   USBx: USB peripheral instance register address.
-  * @param   bEpNum: Endpoint Number.
-  * @retval EP_DBUF_OUT, EP_DBUF_IN,
-  *         EP_DBUF_ERR if the endpoint counter not yet programmed.
-  */
-#define PCD_GET_DB_DIR(USBx, bEpNum)\
-{\
-  if ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum)) & 0xFC00) != 0)\
-    return(PCD_EP_DBUF_OUT);\
-  else if (((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x03FF) != 0)\
-    return(PCD_EP_DBUF_IN);\
-  else\
-    return(PCD_EP_DBUF_ERR);\
-}
+#define PCD_FreeUserBuffer(USBx, bEpNum, bDir) \
+  do { \
+    if ((bDir) == 0U) \
+    { \
+      /* OUT double buffered endpoint */ \
+      PCD_TX_DTOG((USBx), (bEpNum)); \
+    } \
+    else if ((bDir) == 1U) \
+    { \
+      /* IN double buffered endpoint */ \
+      PCD_RX_DTOG((USBx), (bEpNum)); \
+    } \
+  } while(0)
 
 /**
   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]).
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wState: new state
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wState new state
   * @retval None
   */
-#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) { register uint16_t _wRegVal;\
-   \
-    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK;\
-   /* toggle first bit ? */     \
-   if((USB_EPTX_DTOG1 & (wState))!= 0U)\
-   {                                                                            \
-     _wRegVal ^= USB_EPTX_DTOG1;        \
-   }                                                                            \
-   /* toggle second bit ?  */         \
-   if((USB_EPTX_DTOG2 & (wState))!= 0U)      \
-   {                                                                            \
-     _wRegVal ^= USB_EPTX_DTOG2;        \
-   }                                                                            \
-   PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX));\
-  } /* PCD_SET_EP_TX_STATUS */
+#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK; \
+    /* toggle first bit ? */ \
+    if ((USB_EPTX_DTOG1 & (wState))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPTX_DTOG1; \
+    } \
+    /* toggle second bit ?  */ \
+    if ((USB_EPTX_DTOG2 & (wState))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPTX_DTOG2; \
+    } \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_SET_EP_TX_STATUS */
 
 /**
   * @brief  sets the status for rx transfer (bits STAT_TX[1:0])
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wState: new state
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wState new state
   * @retval None
   */
-#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) {\
-    register uint16_t _wRegVal;   \
+#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) \
+  do { \
+    uint16_t _wRegVal; \
     \
-    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK;\
-    /* toggle first bit ? */  \
-    if((USB_EPRX_DTOG1 & (wState))!= 0U) \
-    {                                                                             \
-      _wRegVal ^= USB_EPRX_DTOG1;  \
-    }                                                                             \
-    /* toggle second bit ? */  \
-    if((USB_EPRX_DTOG2 & (wState))!= 0U) \
-    {                                                                             \
-      _wRegVal ^= USB_EPRX_DTOG2;  \
-    }                                                                             \
-    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX)); \
-  } /* PCD_SET_EP_RX_STATUS */
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK; \
+    /* toggle first bit ? */ \
+    if ((USB_EPRX_DTOG1 & (wState))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPRX_DTOG1; \
+    } \
+    /* toggle second bit ? */ \
+    if ((USB_EPRX_DTOG2 & (wState))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPRX_DTOG2; \
+    } \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_SET_EP_RX_STATUS */
 
 /**
   * @brief  sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wStaterx: new state.
-  * @param  wStatetx: new state.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wStaterx new state.
+  * @param  wStatetx new state.
   * @retval None
   */
-#define PCD_SET_EP_TXRX_STATUS(USBx,bEpNum,wStaterx,wStatetx) {\
-    register uint32_t _wRegVal;   \
+#define PCD_SET_EP_TXRX_STATUS(USBx, bEpNum, wStaterx, wStatetx) \
+  do { \
+    uint16_t _wRegVal; \
     \
-    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK |USB_EPTX_STAT) ;\
-    /* toggle first bit ? */  \
-    if((USB_EPRX_DTOG1 & ((wStaterx)))!= 0U) \
-    {                                                                                    \
-      _wRegVal ^= USB_EPRX_DTOG1;  \
-    }                                                                                    \
-    /* toggle second bit ? */  \
-    if((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
-    {                                                                                    \
-      _wRegVal ^= USB_EPRX_DTOG2;  \
-    }                                                                                    \
-    /* toggle first bit ? */     \
-    if((USB_EPTX_DTOG1 & (wStatetx))!= 0U)      \
-    {                                                                                    \
-      _wRegVal ^= USB_EPTX_DTOG1;        \
-    }                                                                                    \
-    /* toggle second bit ?  */         \
-    if((USB_EPTX_DTOG2 & (wStatetx))!= 0U)      \
-    {                                                                                    \
-      _wRegVal ^= USB_EPTX_DTOG2;        \
-    }                                                                                    \
-    PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX);    \
-  } /* PCD_SET_EP_TXRX_STATUS */
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK | USB_EPTX_STAT); \
+    /* toggle first bit ? */ \
+    if ((USB_EPRX_DTOG1 & (wStaterx))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPRX_DTOG1; \
+    } \
+    /* toggle second bit ? */ \
+    if ((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPRX_DTOG2; \
+    } \
+    /* toggle first bit ? */ \
+    if ((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPTX_DTOG1; \
+    } \
+    /* toggle second bit ?  */ \
+    if ((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \
+    { \
+      _wRegVal ^= USB_EPTX_DTOG2; \
+    } \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_SET_EP_TXRX_STATUS */
 
 /**
   * @brief  gets the status for tx/rx transfer (bits STAT_TX[1:0]
   *         /STAT_RX[1:0])
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval status
   */
 #define PCD_GET_EP_TX_STATUS(USBx, bEpNum)     ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT)
@@ -537,8 +635,8 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  sets directly the VALID tx/rx-status into the endpoint register
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
 #define PCD_SET_EP_TX_VALID(USBx, bEpNum)      (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID))
@@ -546,30 +644,41 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  checks stall condition in an endpoint.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval TRUE = endpoint in stall condition.
   */
-#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) \
-                                   == USB_EP_TX_STALL)
-#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) \
-                                   == USB_EP_RX_STALL)
+#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) == USB_EP_TX_STALL)
+#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) == USB_EP_RX_STALL)
 
 /**
   * @brief  set & clear EP_KIND bit.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
-#define PCD_SET_EP_KIND(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \
-                                (USB_EP_CTR_RX|USB_EP_CTR_TX|((PCD_GET_ENDPOINT((USBx), (bEpNum)) | USB_EP_KIND) & USB_EPREG_MASK))))
-#define PCD_CLEAR_EP_KIND(USBx, bEpNum)  (PCD_SET_ENDPOINT((USBx), (bEpNum), \
-                                (USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK))))
+#define PCD_SET_EP_KIND(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_KIND)); \
+  } while(0) /* PCD_SET_EP_KIND */
+
+#define PCD_CLEAR_EP_KIND(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK; \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_CLEAR_EP_KIND */
 
 /**
   * @brief  Sets/clears directly STATUS_OUT bit in the endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
 #define PCD_SET_OUT_STATUS(USBx, bEpNum)       PCD_SET_EP_KIND((USBx), (bEpNum))
@@ -577,8 +686,8 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  Sets/clears directly EP_KIND bit in the endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
 #define PCD_SET_EP_DBUF(USBx, bEpNum)          PCD_SET_EP_KIND((USBx), (bEpNum))
@@ -586,77 +695,139 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
-#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT((USBx), (bEpNum),\
-                                   PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK))
-#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT((USBx), (bEpNum),\
-                                   PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK))
+#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_CLEAR_RX_EP_CTR */
+
+#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX)); \
+  } while(0) /* PCD_CLEAR_TX_EP_CTR */
 
 /**
   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
-#define PCD_RX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \
-                                   USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
-#define PCD_TX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \
-                                   USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
+#define PCD_RX_DTOG(USBx, bEpNum) \
+  do { \
+    uint16_t _wEPVal; \
+    \
+    _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_RX)); \
+  } while(0) /* PCD_RX_DTOG */
 
+#define PCD_TX_DTOG(USBx, bEpNum) \
+  do { \
+    uint16_t _wEPVal; \
+    \
+    _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_TX)); \
+  } while(0) /* PCD_TX_DTOG */
 /**
   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
-#define PCD_CLEAR_RX_DTOG(USBx, bEpNum)  if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_RX) != 0U)\
-                                         {                                                              \
-                                           PCD_RX_DTOG((USBx), (bEpNum));                               \
-                                         }
-#define PCD_CLEAR_TX_DTOG(USBx, bEpNum)  if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_TX) != 0U)\
-                                         {                                                              \
-                                            PCD_TX_DTOG((USBx), (bEpNum));                              \
-                                         }
+#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
+    \
+    if ((_wRegVal & USB_EP_DTOG_RX) != 0U)\
+    { \
+      PCD_RX_DTOG((USBx), (bEpNum)); \
+    } \
+  } while(0) /* PCD_CLEAR_RX_DTOG */
+
+#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
+    \
+    if ((_wRegVal & USB_EP_DTOG_TX) != 0U)\
+    { \
+      PCD_TX_DTOG((USBx), (bEpNum)); \
+    } \
+  } while(0) /* PCD_CLEAR_TX_DTOG */
 
 /**
   * @brief  Sets address in an endpoint register.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  bAddr: Address.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  bAddr Address.
   * @retval None
   */
-#define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT((USBx), (bEpNum),\
-    USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr))
+#define PCD_SET_EP_ADDRESS(USBx, bEpNum, bAddr) \
+  do { \
+    uint16_t _wRegVal; \
+    \
+    _wRegVal = (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr); \
+    \
+    PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
+  } while(0) /* PCD_SET_EP_ADDRESS */
 
+/**
+  * @brief  Gets address in an endpoint register.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @retval None
+  */
 #define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD))
 
-#define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U)*2U+     ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+2U)*2U+  ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+4U)*2U+  ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+6U)*2U+  ((uint32_t)(USBx) + 0x400U)))
-
-#define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) {\
-    uint32_t *pdwReg = PCD_EP_RX_CNT((USBx), (bEpNum)); \
-    PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
-  }
+#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
+#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
 
 /**
   * @brief  sets address of the tx/rx buffer.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wAddr: address to be set (must be word aligned).
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wAddr address to be set (must be word aligned).
   * @retval None
   */
-#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_TX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
-#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_RX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
+#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wAddr) \
+  do { \
+    __IO uint16_t *_wRegVal; \
+    uint32_t _wRegBase = (uint32_t)USBx; \
+    \
+    _wRegBase += (uint32_t)(USBx)->BTABLE; \
+    _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + (((uint32_t)(bEpNum) * 8U) * PMA_ACCESS)); \
+    *_wRegVal = ((wAddr) >> 1) << 1; \
+  } while(0) /* PCD_SET_EP_TX_ADDRESS */
+
+#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wAddr) \
+  do { \
+    __IO uint16_t *_wRegVal; \
+    uint32_t _wRegBase = (uint32_t)USBx; \
+    \
+    _wRegBase += (uint32_t)(USBx)->BTABLE; \
+    _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 4U) * PMA_ACCESS)); \
+    *_wRegVal = ((wAddr) >> 1) << 1; \
+  } while(0) /* PCD_SET_EP_RX_ADDRESS */
 
 /**
   * @brief  Gets address of the tx/rx buffer.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval address of the buffer.
   */
 #define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum)))
@@ -664,92 +835,130 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  Sets counter of rx buffer with no. of blocks.
-  * @param  dwReg: Register
-  * @param  wCount: Counter.
-  * @param  wNBlocks: no. of Blocks.
+  * @param  pdwReg Register pointer
+  * @param  wCount Counter.
+  * @param  wNBlocks no. of Blocks.
   * @retval None
   */
-#define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) {\
-    (wNBlocks) = (wCount) >> 5U;\
-    if(((wCount) & 0x1FU) == 0U)\
-    {                                                  \
-      (wNBlocks)--;\
-    }                                                  \
-    *pdwReg = (uint16_t)((uint16_t)((wNBlocks) << 10U) | 0x8000U); \
-  }/* PCD_CALC_BLK32 */
-
-#define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) {\
-    (wNBlocks) = (wCount) >> 1U;\
-    if(((wCount) & 0x01U) != 0U)\
-    {                                                  \
-      (wNBlocks)++;\
-    }                                                  \
-    *pdwReg = (uint16_t)((wNBlocks) << 10U);\
-  }/* PCD_CALC_BLK2 */
-
-#define PCD_SET_EP_CNT_RX_REG(dwReg,wCount)  {\
-    uint16_t wNBlocks;\
-    if((wCount) > 62U)                                \
-    {                                                \
-      PCD_CALC_BLK32((dwReg),(wCount),wNBlocks);     \
-    }                                                \
-    else                                             \
-    {                                                \
-      PCD_CALC_BLK2((dwReg),(wCount),wNBlocks);      \
-    }                                                \
-  }/* PCD_SET_EP_CNT_RX_REG */
-
-#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum,wCount) {\
-    uint32_t *pdwReg = PCD_EP_TX_CNT((USBx), (bEpNum)); \
-    PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
-  }
+#define PCD_CALC_BLK32(pdwReg, wCount, wNBlocks) \
+  do { \
+    (wNBlocks) = (wCount) >> 5; \
+    if (((wCount) & 0x1fU) == 0U) \
+    { \
+      (wNBlocks)--; \
+    } \
+    *(pdwReg) = (uint16_t)(((wNBlocks) << 10) | USB_CNTRX_BLSIZE); \
+  } while(0) /* PCD_CALC_BLK32 */
+
+#define PCD_CALC_BLK2(pdwReg, wCount, wNBlocks) \
+  do { \
+    (wNBlocks) = (wCount) >> 1; \
+    if (((wCount) & 0x1U) != 0U) \
+    { \
+      (wNBlocks)++; \
+    } \
+    *(pdwReg) = (uint16_t)((wNBlocks) << 10); \
+  } while(0) /* PCD_CALC_BLK2 */
+
+#define PCD_SET_EP_CNT_RX_REG(pdwReg, wCount) \
+  do { \
+    uint32_t wNBlocks; \
+    if ((wCount) == 0U) \
+    { \
+      *(pdwReg) &= (uint16_t)~USB_CNTRX_NBLK_MSK; \
+      *(pdwReg) |= USB_CNTRX_BLSIZE; \
+    } \
+    else if((wCount) <= 62U) \
+    { \
+      PCD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \
+    } \
+    else \
+    { \
+      PCD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \
+    } \
+  } while(0) /* PCD_SET_EP_CNT_RX_REG */
+
+#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum, wCount) \
+  do { \
+    uint32_t _wRegBase = (uint32_t)(USBx); \
+    __IO uint16_t *pdwReg; \
+    \
+    _wRegBase += (uint32_t)(USBx)->BTABLE; \
+    pdwReg = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
+    PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount)); \
+  } while(0)
 
 /**
   * @brief  sets counter for the tx/rx buffer.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wCount: Counter value.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wCount Counter value.
   * @retval None
   */
-#define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT((USBx), (bEpNum)) = (wCount))
-
+#define PCD_SET_EP_TX_CNT(USBx, bEpNum, wCount) \
+  do { \
+    uint32_t _wRegBase = (uint32_t)(USBx); \
+    __IO uint16_t *_wRegVal; \
+    \
+    _wRegBase += (uint32_t)(USBx)->BTABLE; \
+    _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
+    *_wRegVal = (uint16_t)(wCount); \
+  } while(0)
+
+#define PCD_SET_EP_RX_CNT(USBx, bEpNum, wCount) \
+  do { \
+    uint32_t _wRegBase = (uint32_t)(USBx); \
+    __IO uint16_t *_wRegVal; \
+    \
+    _wRegBase += (uint32_t)(USBx)->BTABLE; \
+    _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
+    PCD_SET_EP_CNT_RX_REG(_wRegVal, (wCount)); \
+  } while(0)
 
 /**
   * @brief  gets counter of the tx buffer.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval Counter value
   */
-#define PCD_GET_EP_TX_CNT(USBx, bEpNum)        ((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3FFU)
-#define PCD_GET_EP_RX_CNT(USBx, bEpNum)        ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3FFU)
+#define PCD_GET_EP_TX_CNT(USBx, bEpNum)        ((uint32_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3ffU)
+#define PCD_GET_EP_RX_CNT(USBx, bEpNum)        ((uint32_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3ffU)
 
 /**
   * @brief  Sets buffer 0/1 address in a double buffer endpoint.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  wBuf0Addr: buffer 0 address.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  wBuf0Addr buffer 0 address.
   * @retval Counter value
   */
-#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum,wBuf0Addr) {PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr));}
-#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum,wBuf1Addr) {PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr));}
+#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr) \
+  do { \
+    PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr)); \
+  } while(0) /* PCD_SET_EP_DBUF0_ADDR */
+
+#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr) \
+  do { \
+    PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr)); \
+  } while(0) /* PCD_SET_EP_DBUF1_ADDR */
 
 /**
   * @brief  Sets addresses in a double buffer endpoint.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @param  wBuf0Addr: buffer 0 address.
   * @param  wBuf1Addr = buffer 1 address.
   * @retval None
   */
-#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum,wBuf0Addr,wBuf1Addr) { \
-    PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr));\
-    PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr));\
-  } /* PCD_SET_EP_DBUF_ADDR */
+#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum, wBuf0Addr, wBuf1Addr) \
+  do { \
+    PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr)); \
+    PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr)); \
+  } while(0) /* PCD_SET_EP_DBUF_ADDR */
 
 /**
   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
 #define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum)    (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum)))
@@ -757,52 +966,68 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 
 /**
   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
-  * @param  bDir: endpoint dir  EP_DBUF_OUT = OUT
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
+  * @param  bDir endpoint dir  EP_DBUF_OUT = OUT
   *         EP_DBUF_IN  = IN
   * @param  wCount: Counter value
   * @retval None
   */
-#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount)  { \
-    if((bDir) == PCD_EP_DBUF_OUT)\
+#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) \
+  do { \
+    if ((bDir) == 0U) \
       /* OUT endpoint */ \
-    {PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum),(wCount));} \
-    else if((bDir) == PCD_EP_DBUF_IN)\
-      /* IN endpoint */ \
-      *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount);  \
-  } /* SetEPDblBuf0Count*/
-
-#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount)  { \
-    if((bDir) == PCD_EP_DBUF_OUT)\
-    {/* OUT endpoint */                                       \
-      PCD_SET_EP_RX_CNT((USBx), (bEpNum),(wCount));           \
-    }                                                         \
-    else if((bDir) == PCD_EP_DBUF_IN)\
-    {/* IN endpoint */                                        \
-      *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount); \
-    }                                                         \
-  } /* SetEPDblBuf1Count */
-
-#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) {\
+    { \
+      PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum), (wCount)); \
+    } \
+    else \
+    { \
+      if ((bDir) == 1U) \
+      { \
+        /* IN endpoint */ \
+        PCD_SET_EP_TX_CNT((USBx), (bEpNum), (wCount)); \
+      } \
+    } \
+  } while(0) /* SetEPDblBuf0Count*/
+
+#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) \
+  do { \
+    uint32_t _wBase = (uint32_t)(USBx); \
+    __IO uint16_t *_wEPRegVal; \
+    \
+    if ((bDir) == 0U) \
+    { \
+      /* OUT endpoint */ \
+      PCD_SET_EP_RX_CNT((USBx), (bEpNum), (wCount)); \
+    } \
+    else \
+    { \
+      if ((bDir) == 1U) \
+      { \
+        /* IN endpoint */ \
+        _wBase += (uint32_t)(USBx)->BTABLE; \
+        _wEPRegVal = (__IO uint16_t *)(_wBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
+        *_wEPRegVal = (uint16_t)(wCount); \
+      } \
+    } \
+  } while(0) /* SetEPDblBuf1Count */
+
+#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) \
+  do { \
     PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \
     PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \
-  } /* PCD_SET_EP_DBUF_CNT  */
+  } while(0) /* PCD_SET_EP_DBUF_CNT */
 
 /**
   * @brief  Gets buffer 0/1 rx/tx counter for double buffering.
-  * @param  USBx: USB peripheral instance register address.
-  * @param  bEpNum: Endpoint Number.
+  * @param  USBx USB peripheral instance register address.
+  * @param  bEpNum Endpoint Number.
   * @retval None
   */
 #define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum)     (PCD_GET_EP_TX_CNT((USBx), (bEpNum)))
 #define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum)     (PCD_GET_EP_RX_CNT((USBx), (bEpNum)))
 
-#endif /* USB */
-
-/**
-  * @}
-  */
+#endif /* defined (USB) */
 
 /**
   * @}
@@ -815,17 +1040,12 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
 /**
   * @}
   */
-
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
+#endif /* defined (USB) || defined (USB_OTG_FS) */
 
 #ifdef __cplusplus
 }
 #endif
 
-
-#endif /* __STM32F1xx_HAL_PCD_H */
+#endif /* STM32F1xx_HAL_PCD_H */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
index 443a531f52..458270226c 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
@@ -18,21 +18,17 @@
   */
 
 /* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PCD_EX_H
-#define __STM32F1xx_HAL_PCD_EX_H
+#ifndef STM32F1xx_HAL_PCD_EX_H
+#define STM32F1xx_HAL_PCD_EX_H
 
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f1xx_hal_def.h"
 
+#if defined (USB) || defined (USB_OTG_FS)
 /** @addtogroup STM32F1xx_HAL_Driver
   * @{
   */
@@ -40,7 +36,6 @@
 /** @addtogroup PCDEx
   * @{
   */
-
 /* Exported types ------------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
 /* Exported macros -----------------------------------------------------------*/
@@ -51,31 +46,29 @@
 /** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
   * @{
   */
+
 #if defined (USB_OTG_FS)
 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
-#endif /* USB_OTG_FS */
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
-HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
-                                     uint16_t ep_addr,
-                                     uint16_t ep_kind,
-                                     uint32_t pmaadress);
-#endif /* USB */
-/**
-  * @}
-  */
+HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
+                                       uint16_t ep_kind, uint32_t pmaadress);
 
-/** @addtogroup PCDEx_Exported_Functions_Group2 Peripheral State functions
-  * @{
-  */
 void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
+#endif /* defined (USB) */
+void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg);
+void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg);
+
 /**
   * @}
   */
+
 /**
   * @}
   */
+
 /**
   * @}
   */
@@ -83,16 +76,13 @@ void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
 /**
   * @}
   */
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
+#endif /* defined (USB) || defined (USB_OTG_FS) */
 
 #ifdef __cplusplus
 }
 #endif
 
 
-#endif /* __STM32F1xx_HAL_PCD_EX_H */
+#endif /* STM32F1xx_HAL_PCD_EX_H */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
index 7916f5fc73..d29b6b409c 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
@@ -729,8 +729,8 @@ __STATIC_INLINE uint32_t LL_I2C_GetClockPeriod(I2C_TypeDef *I2Cx)
 __STATIC_INLINE void LL_I2C_ConfigSpeed(I2C_TypeDef *I2Cx, uint32_t PeriphClock, uint32_t ClockSpeed,
                                         uint32_t DutyCycle)
 {
-  register uint32_t freqrange = 0x0U;
-  register uint32_t clockconfig = 0x0U;
+  uint32_t freqrange = 0x0U;
+  uint32_t clockconfig = 0x0U;
 
   /* Compute frequency range */
   freqrange = __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock);
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
index e186a74260..135d8f7451 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
@@ -18,21 +18,17 @@
   */
 
 /* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_USB_H
-#define __STM32F1xx_LL_USB_H
+#ifndef STM32F1xx_LL_USB_H
+#define STM32F1xx_LL_USB_H
 
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f1xx_hal_def.h"
 
+#if defined (USB) || defined (USB_OTG_FS)
 /** @addtogroup STM32F1xx_HAL_Driver
   * @{
   */
@@ -42,36 +38,37 @@
   */
 
 /* Exported types ------------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Types USB Low Layer Exported Types
-  * @{
-  */
+
 /**
   * @brief  USB Mode definition
   */
+#if defined (USB_OTG_FS)
+
 typedef enum
 {
-   USB_DEVICE_MODE  = 0,
-   USB_HOST_MODE    = 1,
-   USB_DRD_MODE     = 2
-}USB_ModeTypeDef;
+  USB_DEVICE_MODE  = 0,
+  USB_HOST_MODE    = 1,
+  USB_DRD_MODE     = 2
+} USB_ModeTypeDef;
 
-#if defined (USB_OTG_FS)
 /**
   * @brief  URB States definition
   */
-typedef enum {
+typedef enum
+{
   URB_IDLE = 0,
   URB_DONE,
   URB_NOTREADY,
   URB_NYET,
   URB_ERROR,
   URB_STALL
-}USB_OTG_URBStateTypeDef;
+} USB_OTG_URBStateTypeDef;
 
 /**
   * @brief  Host channel States  definition
   */
-typedef enum {
+typedef enum
+{
   HC_IDLE = 0,
   HC_XFRC,
   HC_HALTED,
@@ -81,216 +78,249 @@ typedef enum {
   HC_XACTERR,
   HC_BBLERR,
   HC_DATATGLERR
-}USB_OTG_HCStateTypeDef;
+} USB_OTG_HCStateTypeDef;
 
 /**
-  * @brief  USB OTG Initialization Structure definition
+  * @brief  USB Instance Initialization Structure definition
   */
 typedef struct
 {
-  uint32_t dev_endpoints;        /*!< Device Endpoints number.
-                                      This parameter depends on the used USB core.
-                                      This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+  uint32_t dev_endpoints;           /*!< Device Endpoints number.
+                                         This parameter depends on the used USB core.
+                                         This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+  uint32_t Host_channels;           /*!< Host Channels number.
+                                         This parameter Depends on the used USB core.
+                                         This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+  uint32_t speed;                   /*!< USB Core speed.
+                                         This parameter can be any value of @ref USB_Core_Speed                 */
+
+  uint32_t dma_enable;              /*!< Enable or disable of the USB embedded DMA used only for OTG HS.        */
+
+  uint32_t ep0_mps;                 /*!< Set the Endpoint 0 Max Packet size.                                    */
 
-  uint32_t Host_channels;        /*!< Host Channels number.
-                                      This parameter Depends on the used USB core.
-                                      This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+  uint32_t phy_itface;              /*!< Select the used PHY interface.
+                                         This parameter can be any value of @ref USB_Core_PHY                   */
 
-  uint32_t speed;                /*!< USB Core speed.
-                                      This parameter can be any value of @ref USB_Core_Speed_                */
+  uint32_t Sof_enable;              /*!< Enable or disable the output of the SOF signal.                        */
 
-  uint32_t ep0_mps;              /*!< Set the Endpoint 0 Max Packet size.
-                                      This parameter can be any value of @ref USB_EP0_MPS_                   */
+  uint32_t low_power_enable;        /*!< Enable or disable the low power mode.                                  */
 
-  uint32_t Sof_enable;           /*!< Enable or disable the output of the SOF signal.                        */
+  uint32_t lpm_enable;              /*!< Enable or disable Link Power Management.                               */
 
-  uint32_t low_power_enable;     /*!< Enable or disable the low power mode.                                  */
+  uint32_t battery_charging_enable; /*!< Enable or disable Battery charging.                                    */
 
-  uint32_t vbus_sensing_enable;  /*!< Enable or disable the VBUS Sensing feature.                            */
+  uint32_t vbus_sensing_enable;     /*!< Enable or disable the VBUS Sensing feature.                            */
 
-  uint32_t use_external_vbus;    /*!< Enable or disable the use of the external VBUS.                        */
-}USB_OTG_CfgTypeDef;
+  uint32_t use_dedicated_ep1;       /*!< Enable or disable the use of the dedicated EP1 interrupt.              */
+
+  uint32_t use_external_vbus;       /*!< Enable or disable the use of the external VBUS.                        */
+
+} USB_OTG_CfgTypeDef;
 
 typedef struct
 {
-  uint8_t   num;            /*!< Endpoint number
-                                This parameter must be a number between Min_Data = 1 and Max_Data = 15    */
+  uint8_t   num;                  /*!< Endpoint number
+                                       This parameter must be a number between Min_Data = 1 and Max_Data = 15   */
 
-  uint8_t   is_in;          /*!< Endpoint direction
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
+  uint8_t   is_in;                /*!< Endpoint direction
+                                       This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
 
-  uint8_t   is_stall;       /*!< Endpoint stall condition
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
+  uint8_t   is_stall;             /*!< Endpoint stall condition
+                                       This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
 
-  uint8_t   type;           /*!< Endpoint type
-                                 This parameter can be any value of @ref USB_EP_Type_                     */
+  uint8_t   type;                 /*!< Endpoint type
+                                       This parameter can be any value of @ref USB_EP_Type_                     */
 
-  uint8_t   data_pid_start; /*!< Initial data PID
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
+  uint8_t   data_pid_start;       /*!< Initial data PID
+                                       This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
 
-  uint8_t   even_odd_frame; /*!< IFrame parity
-                                 This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
+  uint8_t   even_odd_frame;       /*!< IFrame parity
+                                       This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
 
-  uint16_t  tx_fifo_num;    /*!< Transmission FIFO number
-                                 This parameter must be a number between Min_Data = 1 and Max_Data = 15   */
+  uint16_t  tx_fifo_num;          /*!< Transmission FIFO number
+                                       This parameter must be a number between Min_Data = 1 and Max_Data = 15   */
 
-  uint32_t  maxpacket;      /*!< Endpoint Max packet size
-                                 This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
+  uint32_t  maxpacket;            /*!< Endpoint Max packet size
+                                       This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
 
-  uint8_t   *xfer_buff;     /*!< Pointer to transfer buffer                                               */
+  uint8_t   *xfer_buff;           /*!< Pointer to transfer buffer                                               */
 
-  uint32_t  dma_addr;       /*!< 32 bits aligned transfer buffer address                                  */
+  uint32_t  dma_addr;             /*!< 32 bits aligned transfer buffer address                                  */
 
-  uint32_t  xfer_len;       /*!< Current transfer length                                                  */
+  uint32_t  xfer_len;             /*!< Current transfer length                                                  */
 
-  uint32_t  xfer_count;     /*!< Partial transfer length in case of multi packet transfer                 */
-
-  uint16_t  pending0;        /*!, Fact, that double buffering transfer have pended data                    */
-  uint16_t  pending1;        /*!, Fact, that double buffering transfer have pended data                    */
-}USB_OTG_EPTypeDef;
+  uint32_t  xfer_count;           /*!< Partial transfer length in case of multi packet transfer                 */
+} USB_OTG_EPTypeDef;
 
 typedef struct
 {
-  uint8_t   dev_addr ;     /*!< USB device address.
-                                This parameter must be a number between Min_Data = 1 and Max_Data = 255    */
+  uint8_t   dev_addr;           /*!< USB device address.
+                                     This parameter must be a number between Min_Data = 1 and Max_Data = 255    */
 
-  uint8_t   ch_num;        /*!< Host channel number.
-                                This parameter must be a number between Min_Data = 1 and Max_Data = 15     */
+  uint8_t   ch_num;             /*!< Host channel number.
+                                     This parameter must be a number between Min_Data = 1 and Max_Data = 15     */
 
-  uint8_t   ep_num;        /*!< Endpoint number.
-                                This parameter must be a number between Min_Data = 1 and Max_Data = 15     */
+  uint8_t   ep_num;             /*!< Endpoint number.
+                                     This parameter must be a number between Min_Data = 1 and Max_Data = 15     */
 
-  uint8_t   ep_is_in;      /*!< Endpoint direction
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
+  uint8_t   ep_is_in;           /*!< Endpoint direction
+                                     This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
 
-  uint8_t   speed;         /*!< USB Host speed.
-                                This parameter can be any value of @ref USB_Core_Speed_                    */
+  uint8_t   speed;              /*!< USB Host speed.
+                                     This parameter can be any value of @ref USB_Core_Speed_                    */
 
-  uint8_t   do_ping;       /*!< Enable or disable the use of the PING protocol for HS mode.                */
+  uint8_t   do_ping;            /*!< Enable or disable the use of the PING protocol for HS mode.                */
 
-  uint8_t   process_ping;  /*!< Execute the PING protocol for HS mode.                                     */
+  uint8_t   process_ping;       /*!< Execute the PING protocol for HS mode.                                     */
 
-  uint8_t   ep_type;       /*!< Endpoint Type.
-                                This parameter can be any value of @ref USB_EP_Type_                       */
+  uint8_t   ep_type;            /*!< Endpoint Type.
+                                     This parameter can be any value of @ref USB_EP_Type_                       */
 
-  uint16_t  max_packet;    /*!< Endpoint Max packet size.
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 64KB   */
+  uint16_t  max_packet;         /*!< Endpoint Max packet size.
+                                     This parameter must be a number between Min_Data = 0 and Max_Data = 64KB   */
 
-  uint8_t   data_pid;      /*!< Initial data PID.
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
+  uint8_t   data_pid;           /*!< Initial data PID.
+                                     This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
 
-  uint8_t   *xfer_buff;    /*!< Pointer to transfer buffer.                                                */
+  uint8_t   *xfer_buff;         /*!< Pointer to transfer buffer.                                                */
 
-  uint32_t  xfer_len;      /*!< Current transfer length.                                                   */
+  uint32_t  xfer_len;           /*!< Current transfer length.                                                   */
 
-  uint32_t  xfer_count;    /*!< Partial transfer length in case of multi packet transfer.                  */
+  uint32_t  xfer_count;         /*!< Partial transfer length in case of multi packet transfer.                  */
 
-  uint8_t   toggle_in;     /*!< IN transfer current toggle flag.
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
+  uint8_t   toggle_in;          /*!< IN transfer current toggle flag.
+                                     This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
 
-  uint8_t   toggle_out;    /*!< OUT transfer current toggle flag
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
+  uint8_t   toggle_out;         /*!< OUT transfer current toggle flag
+                                     This parameter must be a number between Min_Data = 0 and Max_Data = 1      */
 
-  uint32_t  dma_addr;      /*!< 32 bits aligned transfer buffer address.                                   */
+  uint32_t  dma_addr;           /*!< 32 bits aligned transfer buffer address.                                   */
 
-  uint32_t  ErrCnt;        /*!< Host channel error count.*/
+  uint32_t  ErrCnt;             /*!< Host channel error count.                                                  */
 
-  USB_OTG_URBStateTypeDef  urb_state;  /*!< URB state.
-                                           This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
+  USB_OTG_URBStateTypeDef urb_state;  /*!< URB state.
+                                            This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
 
-  USB_OTG_HCStateTypeDef   state;     /*!< Host Channel state.
-                                           This parameter can be any value of @ref USB_OTG_HCStateTypeDef  */
-}USB_OTG_HCTypeDef;
-#endif /* USB_OTG_FS */
+  USB_OTG_HCStateTypeDef state;       /*!< Host Channel state.
+                                            This parameter can be any value of @ref USB_OTG_HCStateTypeDef  */
+} USB_OTG_HCTypeDef;
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
+
+typedef enum
+{
+  USB_DEVICE_MODE  = 0
+} USB_ModeTypeDef;
+
 /**
   * @brief  USB Initialization Structure definition
   */
 typedef struct
 {
-  uint32_t dev_endpoints;        /*!< Device Endpoints number.
-                                      This parameter depends on the used USB core.
-                                      This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+  uint32_t dev_endpoints;           /*!< Device Endpoints number.
+                                         This parameter depends on the used USB core.
+                                         This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
 
-  uint32_t speed;                /*!< USB Core speed.
-                                      This parameter can be any value of @ref USB_Core_Speed                 */
+  uint32_t speed;                   /*!< USB Core speed.
+                                         This parameter can be any value of @ref USB_Core_Speed                 */
 
-  uint32_t ep0_mps;              /*!< Set the Endpoint 0 Max Packet size.
-                                      This parameter can be any value of @ref USB_EP0_MPS                    */
+  uint32_t ep0_mps;                 /*!< Set the Endpoint 0 Max Packet size.                                    */
 
-  uint32_t phy_itface;           /*!< Select the used PHY interface.
-                                      This parameter can be any value of @ref USB_Core_PHY                   */
+  uint32_t phy_itface;              /*!< Select the used PHY interface.
+                                         This parameter can be any value of @ref USB_Core_PHY                   */
 
-  uint32_t Sof_enable;           /*!< Enable or disable the output of the SOF signal.                        */
+  uint32_t Sof_enable;              /*!< Enable or disable the output of the SOF signal.                        */
 
-  uint32_t low_power_enable;       /*!< Enable or disable Low Power mode                                      */
+  uint32_t low_power_enable;        /*!< Enable or disable Low Power mode                                       */
 
-  uint32_t lpm_enable;             /*!< Enable or disable Battery charging.                                  */
+  uint32_t lpm_enable;              /*!< Enable or disable Battery charging.                                    */
 
-  uint32_t battery_charging_enable; /*!< Enable or disable Battery charging.                                  */
+  uint32_t battery_charging_enable; /*!< Enable or disable Battery charging.                                    */
 } USB_CfgTypeDef;
 
 typedef struct
 {
-  uint8_t   num;            /*!< Endpoint number
-                                This parameter must be a number between Min_Data = 1 and Max_Data = 15    */
+  uint8_t   num;             /*!< Endpoint number
+                                  This parameter must be a number between Min_Data = 1 and Max_Data = 15    */
+
+  uint8_t   is_in;           /*!< Endpoint direction
+                                  This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
 
-  uint8_t   is_in;          /*!< Endpoint direction
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
+  uint8_t   is_stall;        /*!< Endpoint stall condition
+                                  This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
 
-  uint8_t   is_stall;       /*!< Endpoint stall condition
-                                This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
+  uint8_t   type;            /*!< Endpoint type
+                                  This parameter can be any value of @ref USB_EP_Type                       */
 
-  uint8_t   type;           /*!< Endpoint type
-                                 This parameter can be any value of @ref USB_EP_Type                      */
+  uint8_t   data_pid_start;  /*!< Initial data PID
+                                  This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
 
-  uint16_t  pmaadress;      /*!< PMA Address
-                                 This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
+  uint16_t  pmaadress;       /*!< PMA Address
+                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K    */
 
-  uint16_t  pmaaddr0;       /*!< PMA Address0
-                                 This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
+  uint16_t  pmaaddr0;        /*!< PMA Address0
+                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K    */
 
   uint16_t  pmaaddr1;        /*!< PMA Address1
-                                 This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
+                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K    */
 
   uint8_t   doublebuffer;    /*!< Double buffer enable
-                                 This parameter can be 0 or 1                                             */
+                                  This parameter can be 0 or 1                                              */
 
-  uint16_t  tx_fifo_num;    /*!< This parameter is not required by USB Device FS peripheral, it is used
-                                 only by USB OTG FS peripheral
-                                 This parameter is added to ensure compatibility across USB peripherals   */
+  uint16_t  tx_fifo_num;     /*!< This parameter is not required by USB Device FS peripheral, it is used
+                                  only by USB OTG FS peripheral
+                                  This parameter is added to ensure compatibility across USB peripherals    */
 
-  uint32_t  maxpacket;      /*!< Endpoint Max packet size
-                                 This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
+  uint32_t  maxpacket;       /*!< Endpoint Max packet size
+                                  This parameter must be a number between Min_Data = 0 and Max_Data = 64KB  */
 
-  uint8_t   *xfer_buff;     /*!< Pointer to transfer buffer                                               */
+  uint8_t   *xfer_buff;      /*!< Pointer to transfer buffer                                                */
 
+  uint32_t  xfer_len;        /*!< Current transfer length                                                   */
 
-  uint32_t  xfer_len;       /*!< Current transfer length                                                  */
+  uint32_t  xfer_count;      /*!< Partial transfer length in case of multi packet transfer                  */
 
-  uint32_t  xfer_count;     /*!< Partial transfer length in case of multi packet transfer                 */
+  uint32_t  xfer_len_db;      /*!< double buffer transfer length used with bulk double buffer in           */
 
-  uint16_t  pending0;        /*!, Fact, that double buffering transfer have pended data                    */
-  uint16_t  pending1;        /*!, Fact, that double buffering transfer have pended data                    */
+  uint8_t   xfer_fill_db;     /*!< double buffer Need to Fill new buffer  used with bulk_in                */
 
 } USB_EPTypeDef;
-#endif /* USB */
+#endif /* defined (USB) */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup PCD_Exported_Constants PCD Exported Constants
+  * @{
+  */
+
+#if defined (USB_OTG_FS)
+/** @defgroup USB_OTG_CORE VERSION ID
+  * @{
+  */
+#define USB_OTG_CORE_ID_300A          0x4F54300AU
+#define USB_OTG_CORE_ID_310A          0x4F54310AU
 /**
   * @}
   */
 
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Constants USB Low Layer Exported Constants
+/** @defgroup USB_Core_Mode_ USB Core Mode
   * @{
   */
-#if defined (USB_OTG_FS)
-/** @defgroup USB_LL_Core_Mode USB Low Layer Core Mode
+#define USB_OTG_MODE_DEVICE                    0U
+#define USB_OTG_MODE_HOST                      1U
+#define USB_OTG_MODE_DRD                       2U
+/**
+  * @}
+  */
+
+/** @defgroup USB_LL Device Speed
   * @{
   */
-#define USB_OTG_MODE_DEVICE                    0
-#define USB_OTG_MODE_HOST                      1
-#define USB_OTG_MODE_DRD                       2
+#define USBD_FS_SPEED                          2U
+#define USBH_FSLS_SPEED                        1U
 /**
   * @}
   */
@@ -298,9 +328,7 @@ typedef struct
 /** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
   * @{
   */
-#define USB_OTG_SPEED_LOW                      2
-#define USB_OTG_SPEED_FULL                     3
-
+#define USB_OTG_SPEED_FULL                     3U
 /**
   * @}
   */
@@ -308,8 +336,19 @@ typedef struct
 /** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
   * @{
   */
-#define USB_OTG_ULPI_PHY                       1
-#define USB_OTG_EMBEDDED_PHY                   2
+#define USB_OTG_ULPI_PHY                       1U
+#define USB_OTG_EMBEDDED_PHY                   2U
+/**
+  * @}
+  */
+
+/** @defgroup USB_LL_Turnaround_Timeout Turnaround Timeout Value
+  * @{
+  */
+#ifndef USBD_FS_TRDT_VALUE
+#define USBD_FS_TRDT_VALUE                     5U
+#define USBD_DEFAULT_TRDT_VALUE                9U
+#endif /* USBD_HS_TRDT_VALUE */
 /**
   * @}
   */
@@ -317,8 +356,8 @@ typedef struct
 /** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
   * @{
   */
-#define USB_OTG_FS_MAX_PACKET_SIZE             64
-#define USB_OTG_MAX_EP0_SIZE                   64
+#define USB_OTG_FS_MAX_PACKET_SIZE            64U
+#define USB_OTG_MAX_EP0_SIZE                  64U
 /**
   * @}
   */
@@ -326,9 +365,9 @@ typedef struct
 /** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
   * @{
   */
-#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     (1 << 1)
-#define DSTS_ENUMSPD_LS_PHY_6MHZ               (2 << 1)
-#define DSTS_ENUMSPD_FS_PHY_48MHZ              (3 << 1)
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ     (0U << 1)
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     (1U << 1)
+#define DSTS_ENUMSPD_FS_PHY_48MHZ              (3U << 1)
 /**
   * @}
   */
@@ -336,10 +375,10 @@ typedef struct
 /** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
   * @{
   */
-#define DCFG_FRAME_INTERVAL_80                 0
-#define DCFG_FRAME_INTERVAL_85                 1
-#define DCFG_FRAME_INTERVAL_90                 2
-#define DCFG_FRAME_INTERVAL_95                 3
+#define DCFG_FRAME_INTERVAL_80                 0U
+#define DCFG_FRAME_INTERVAL_85                 1U
+#define DCFG_FRAME_INTERVAL_90                 2U
+#define DCFG_FRAME_INTERVAL_95                 3U
 /**
   * @}
   */
@@ -347,10 +386,10 @@ typedef struct
 /** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
   * @{
   */
-#define DEP0CTL_MPS_64                         0
-#define DEP0CTL_MPS_32                         1
-#define DEP0CTL_MPS_16                         2
-#define DEP0CTL_MPS_8                          3
+#define EP_MPS_64                        0U
+#define EP_MPS_32                        1U
+#define EP_MPS_16                        2U
+#define EP_MPS_8                         3U
 /**
   * @}
   */
@@ -358,9 +397,9 @@ typedef struct
 /** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
   * @{
   */
-#define EP_SPEED_LOW                           0
-#define EP_SPEED_FULL                          1
-#define EP_SPEED_HIGH                          2
+#define EP_SPEED_LOW                           0U
+#define EP_SPEED_FULL                          1U
+#define EP_SPEED_HIGH                          2U
 /**
   * @}
   */
@@ -368,11 +407,11 @@ typedef struct
 /** @defgroup USB_LL_EP_Type USB Low Layer EP Type
   * @{
   */
-#define EP_TYPE_CTRL                           0
-#define EP_TYPE_ISOC                           1
-#define EP_TYPE_BULK                           2
-#define EP_TYPE_INTR                           3
-#define EP_TYPE_MSK                            3
+#define EP_TYPE_CTRL                           0U
+#define EP_TYPE_ISOC                           1U
+#define EP_TYPE_BULK                           2U
+#define EP_TYPE_INTR                           3U
+#define EP_TYPE_MSK                            3U
 /**
   * @}
   */
@@ -380,11 +419,11 @@ typedef struct
 /** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
   * @{
   */
-#define STS_GOUT_NAK                           1
-#define STS_DATA_UPDT                          2
-#define STS_XFER_COMP                          3
-#define STS_SETUP_COMP                         4
-#define STS_SETUP_UPDT                         6
+#define STS_GOUT_NAK                           1U
+#define STS_DATA_UPDT                          2U
+#define STS_XFER_COMP                          3U
+#define STS_SETUP_COMP                         4U
+#define STS_SETUP_UPDT                         6U
 /**
   * @}
   */
@@ -392,9 +431,9 @@ typedef struct
 /** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
   * @{
   */
-#define HCFG_30_60_MHZ                         0
-#define HCFG_48_MHZ                            1
-#define HCFG_6_MHZ                             2
+#define HCFG_30_60_MHZ                         0U
+#define HCFG_48_MHZ                            1U
+#define HCFG_6_MHZ                             2U
 /**
   * @}
   */
@@ -402,48 +441,48 @@ typedef struct
 /** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
   * @{
   */
-#define HPRT0_PRTSPD_HIGH_SPEED                0
-#define HPRT0_PRTSPD_FULL_SPEED                1
-#define HPRT0_PRTSPD_LOW_SPEED                 2
+#define HPRT0_PRTSPD_HIGH_SPEED                0U
+#define HPRT0_PRTSPD_FULL_SPEED                1U
+#define HPRT0_PRTSPD_LOW_SPEED                 2U
 /**
   * @}
   */
 
-#define HCCHAR_CTRL                            0
-#define HCCHAR_ISOC                            1
-#define HCCHAR_BULK                            2
-#define HCCHAR_INTR                            3
+#define HCCHAR_CTRL                            0U
+#define HCCHAR_ISOC                            1U
+#define HCCHAR_BULK                            2U
+#define HCCHAR_INTR                            3U
 
-#define HC_PID_DATA0                           0
-#define HC_PID_DATA2                           1
-#define HC_PID_DATA1                           2
-#define HC_PID_SETUP                           3
+#define HC_PID_DATA0                           0U
+#define HC_PID_DATA2                           1U
+#define HC_PID_DATA1                           2U
+#define HC_PID_SETUP                           3U
 
-#define GRXSTS_PKTSTS_IN                       2
-#define GRXSTS_PKTSTS_IN_XFER_COMP             3
-#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR          5
-#define GRXSTS_PKTSTS_CH_HALTED                7
+#define GRXSTS_PKTSTS_IN                       2U
+#define GRXSTS_PKTSTS_IN_XFER_COMP             3U
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR          5U
+#define GRXSTS_PKTSTS_CH_HALTED                7U
 
-#define USBx_PCGCCTL                           *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
-#define USBx_HPRT0                             *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE)
+#define USBx_PCGCCTL    *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE)
+#define USBx_HPRT0      *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE)
 
-#define USBx_DEVICE                            ((USB_OTG_DeviceTypeDef *)((uint32_t )USBx + USB_OTG_DEVICE_BASE))
-#define USBx_INEP(i)                           ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
-#define USBx_OUTEP(i)                          ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
-#define USBx_DFIFO(i)                          *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE)
+#define USBx_DEVICE     ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE))
+#define USBx_INEP(i)    ((USB_OTG_INEndpointTypeDef *)(USBx_BASE + USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
+#define USBx_OUTEP(i)   ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
+#define USBx_DFIFO(i)   *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
 
-#define USBx_HOST                              ((USB_OTG_HostTypeDef *)((uint32_t )USBx + USB_OTG_HOST_BASE))
-#define USBx_HC(i)                             ((USB_OTG_HostChannelTypeDef *)((uint32_t)USBx + USB_OTG_HOST_CHANNEL_BASE + (i)*USB_OTG_HOST_CHANNEL_SIZE))
-#endif /* USB_OTG_FS */
+#define USBx_HOST       ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE))
+#define USBx_HC(i)      ((USB_OTG_HostChannelTypeDef *)(USBx_BASE + USB_OTG_HOST_CHANNEL_BASE + ((i) * USB_OTG_HOST_CHANNEL_SIZE)))
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
 /** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
   * @{
   */
-#define DEP0CTL_MPS_64                         0
-#define DEP0CTL_MPS_32                         1
-#define DEP0CTL_MPS_16                         2
-#define DEP0CTL_MPS_8                          3
+#define EP_MPS_64                              0U
+#define EP_MPS_32                              1U
+#define EP_MPS_16                              2U
+#define EP_MPS_8                               3U
 /**
   * @}
   */
@@ -451,22 +490,37 @@ typedef struct
 /** @defgroup USB_LL_EP_Type USB Low Layer EP Type
   * @{
   */
-#define EP_TYPE_CTRL                           0
-#define EP_TYPE_ISOC                           1
-#define EP_TYPE_BULK                           2
-#define EP_TYPE_INTR                           3
-#define EP_TYPE_MSK                            3
+#define EP_TYPE_CTRL                           0U
+#define EP_TYPE_ISOC                           1U
+#define EP_TYPE_BULK                           2U
+#define EP_TYPE_INTR                           3U
+#define EP_TYPE_MSK                            3U
 /**
   * @}
   */
 
-#define BTABLE_ADDRESS                         (0x000)
-#endif /* USB */
+/** @defgroup USB_LL Device Speed
+  * @{
+  */
+#define USBD_FS_SPEED                          2U
+/**
+  * @}
+  */
+
+#define BTABLE_ADDRESS                         0x000U
+#define PMA_ACCESS                             2U
+#endif /* defined (USB) */
+#if defined (USB_OTG_FS)
+#define EP_ADDR_MSK                            0xFU
+#endif /* defined (USB_OTG_FS) */
+#if defined (USB)
+#define EP_ADDR_MSK                            0x7U
+#endif /* defined (USB) */
 /**
   * @}
   */
 
-/* Exported macros -----------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
 /** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
   * @{
   */
@@ -476,7 +530,7 @@ typedef struct
 
 #define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__)          (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
 #define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__)         (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
-#endif /* USB_OTG_FS */
+#endif /* defined (USB_OTG_FS) */
 /**
   * @}
   */
@@ -485,99 +539,100 @@ typedef struct
 /** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
   * @{
   */
-/** @addtogroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
-  * @{
-  */
 #if defined (USB_OTG_FS)
-HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
-HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
+HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
+HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode);
-HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed);
-HAL_StatusTypeDef USB_FlushRxFifo (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num );
+HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, uint32_t hclk, uint8_t speed);
+HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode);
+HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed);
+HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num);
 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
-void *            USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
-HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address);
-HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
+                                  uint8_t ch_ep_num, uint16_t len);
+
+void             *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
+HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address);
+HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx);
 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx);
 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup);
 uint8_t           USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx);
 uint32_t          USB_GetMode(USB_OTG_GlobalTypeDef *USBx);
-uint32_t          USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx);
-uint32_t          USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
-uint32_t          USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
-uint32_t          USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
-uint32_t          USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
-void              USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
-
-HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
-HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq);
+uint32_t          USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx);
+uint32_t          USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
+uint32_t          USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
+uint32_t          USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
+uint32_t          USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
+void              USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
+
+HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
+HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq);
 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state);
-uint32_t          USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx);
-uint32_t          USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
-                              uint8_t ch_num,
-                              uint8_t epnum,
-                              uint8_t dev_address,
-                              uint8_t speed,
-                              uint8_t ep_type,
-                              uint16_t mps);
-HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc);
-uint32_t          USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num);
-HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num);
+HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state);
+uint32_t          USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx);
+uint32_t          USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
+                              uint8_t epnum, uint8_t dev_address, uint8_t speed,
+                              uint8_t ep_type, uint16_t mps);
+HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx,
+                                   USB_OTG_HCTypeDef *hc);
+
+uint32_t          USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num);
+HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num);
 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
-#endif /* USB_OTG_FS */
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
-HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
-HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
+HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg);
+HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg);
 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx);
 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode);
-HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx , uint8_t speed);
-HAL_StatusTypeDef USB_FlushRxFifo (USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num );
+HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode);
+HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num);
 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
-void *            USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len);
-HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address);
-HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address);
+HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx);
 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx);
 HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup);
-uint32_t          USB_ReadInterrupts (USB_TypeDef *USBx);
-uint32_t          USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx);
-uint32_t          USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
-uint32_t          USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx);
-uint32_t          USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
-void              USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt);
-
+uint32_t          USB_ReadInterrupts(USB_TypeDef *USBx);
+uint32_t          USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx);
+uint32_t          USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum);
+uint32_t          USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx);
+uint32_t          USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum);
+void              USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt);
 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx);
 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx);
-void USB_WritePMA(USB_TypeDef  *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
-void USB_ReadPMA(USB_TypeDef  *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
-#endif /* USB */
+
+void              USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf,
+                               uint16_t wPMABufAddr, uint16_t wNBytes);
+
+void              USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf,
+                              uint16_t wPMABufAddr, uint16_t wNBytes);
+#endif /* defined (USB) */
 /**
   * @}
   */
+
 /**
   * @}
   */
@@ -589,17 +644,13 @@ void USB_ReadPMA(USB_TypeDef  *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, ui
 /**
   * @}
   */
-
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
+#endif /* defined (USB) || defined (USB_OTG_FS) */
 
 #ifdef __cplusplus
 }
 #endif
 
 
-#endif /* __STM32F1xx_LL_USB_H */
+#endif /* STM32F1xx_LL_USB_H */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/License.md b/system/Drivers/STM32F1xx_HAL_Driver/License.md
new file mode 100644
index 0000000000..017be725e6
--- /dev/null
+++ b/system/Drivers/STM32F1xx_HAL_Driver/License.md
@@ -0,0 +1,3 @@
+# Copyright (c) 2016 STMicroelectronics
+
+This software component is licensed by STMicroelectronics under the **BSD 3-Clause** license. You may not use this file except in compliance with this license. You may obtain a copy of the license [here](https://opensource.org/licenses/BSD-3-Clause).
\ No newline at end of file
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/README.md b/system/Drivers/STM32F1xx_HAL_Driver/README.md
new file mode 100644
index 0000000000..a972b7cbcc
--- /dev/null
+++ b/system/Drivers/STM32F1xx_HAL_Driver/README.md
@@ -0,0 +1,50 @@
+# STM32CubeF1 HAL Driver MCU Component
+
+## Overview
+
+**STM32Cube** is an STMicroelectronics original initiative to ease the developers life by reducing efforts, time and cost.
+
+**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform, delivered for each STM32 series.
+   * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product
+   * The STM32 HAL-LL drivers : an abstraction drivers layer, the API ensuring maximized portability across the STM32 portfolio
+   * The BSP Drivers of each evaluation or demonstration board provided by this STM32 series
+   * A consistent set of middlewares components such as RTOS, USB, FatFS, Graphics, STM32_TouchSensing_Library ...
+   * A full set of software projects (basic examples, applications or demonstrations) for each board provided by this STM32 series
+
+Two models of publication are proposed for the STM32Cube embedded software:
+   * The monolithic **MCU Package** : all STM32Cube software modules of one STM32 series are present (Drivers, Middlewares, Projects, Utilities) in the repo (usual name **STM32Cubexx**, xx corresponding to the STM32 series)
+   * The **MCU component** : progressively from November 2019, each STM32Cube software module being part of the STM32Cube MCU Package, will be delivered as an individual repo, allowing the user to select and get only the required software functions.
+
+## Description
+
+This **stm32f1xx_hal_driver** MCU component repo is one element of the STM32CubeF1 MCU embedded software package, providing the **HAL-LL Drivers** part.
+
+## License
+
+Copyright (c) 2016 STMicroelectronics.
+
+This software component is licensed by STMicroelectronics under BSD 3-Clause license. You may not use this file except in compliance with the License.
+You may obtain a copy of the License [here](https://opensource.org/licenses/BSD-3-Clause).
+
+## Release note
+
+Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/stm32f1xx_hal_driver/blob/master/Release_Notes.html).
+
+## Compatibility information
+
+In this table, you can find the successive versions of this HAL-LL Driver component, in line with the corresponding versions of the full MCU package:
+
+It is **crucial** that you use a consistent set of versions for the CMSIS Core - CMSIS Device - HAL, as mentioned in this table.
+
+HAL Driver F1 | CMSIS Device F1 | CMSIS Core | Was delivered in the full MCU package
+------------- | --------------- | ---------- | -------------------------------------
+Tag v1.1.4 | Tag v4.3.1 | Tag v5.4.0_cm3 | Tag v1.8.0 (and following, if any, till next new tag)
+Tag v1.1.5 | Tag v4.3.1 | Tag v5.4.0_cm3 | Tag v1.8.1 (and following, if any, till next new tag)
+
+The full **STM32CubeF1** MCU package is available [here](https://github.com/STMicroelectronics/STM32CubeF1).
+
+## Troubleshooting
+
+If you have any issue with the **Software content** of this repo, you can [file an issue on Github](https://github.com/STMicroelectronics/stm32f1xx_hal_driver/issues/new).
+
+For any other question related to the product, the tools, the environment, you can submit a topic on the [ST Community/STM32 MCUs forum](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus).
\ No newline at end of file
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Release_Notes.html b/system/Drivers/STM32F1xx_HAL_Driver/Release_Notes.html
index 9482c5cb8a..8639489432 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Release_Notes.html
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Release_Notes.html
@@ -38,11 +38,68 @@ <h1 id="license"><strong>License</strong></h1>
 <div class="col-sm-12 col-lg-8">
 <h1 id="update-history"><strong>Update History</strong></h1>
 <div class="collapse">
-<input type="checkbox" id="collapse-section11" aria-hidden="true"> <label for="collapse-section11" aria-hidden="true"><strong>V1.1.4 / 26-June-2019</strong></label>
+<input type="checkbox" id="collapse-section1_1_5" aria-hidden="true"> <label for="collapse-section1_1_5" aria-hidden="true"><strong>V1.1.5 / 30-July-2020</strong></label>
 <div>
 <h2 id="main-changes">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation</li>
+</ul>
+<h2 id="contents">Contents</h2>
+<ul>
+<li><strong>HAL</strong> driver
+<ul>
+<li>Enhance HAL_SetTickFreq() API robustness
+<ul>
+<li>Restore previous tick frequency when a wrong tick initialization occurs.</li>
+</ul></li>
+</ul></li>
+<li><strong>HAL/LL I2C</strong> update
+<ul>
+<li>Update HAL_I2C_ER_IRQHandler() API to fix acknowledge failure issue with I2C memory IT processes
+<ul>
+<li>Add stop condition generation when NACK occurs.</li>
+</ul></li>
+<li>Update I2C_DMAXferCplt(), I2C_DMAError() and I2C_DMAAbort() APIs to fix hardfault issue when hdmatx and hdmarx parameters in i2c handle aren’t initialized (NULL pointer).
+<ul>
+<li>Add additional check on hi2c-&gt;hdmtx and hi2c-&gt;hdmarx before resetting DMA Tx/Rx complete callbacks</li>
+</ul></li>
+<li>Update HAL_I2C_ER_IRQHandler() API to fix acknowledge failure issue with I2C memory IT processes
+<ul>
+<li>Add stop condition generation when NACK occursHAL SMBUS</li>
+</ul></li>
+<li>Update HAL_I2C_Init() API to force software reset before setting new I2C configuration.</li>
+<li>Update HAL I2C processes to report ErrorCode when wrong I2C start condition occurs
+<ul>
+<li>Add new ErrorCode define: HAL_I2C_WRONG_START</li>
+<li>Set ErrorCode parameter in I2C handle to HAL_I2C_WRONG_START</li>
+</ul></li>
+<li>Update sequential APIs to avoid requesting a START when a STOP condition is not fully treated
+<ul>
+<li>Wait the end of STOP treatment by polling (with a timeout) the STOP bit on Control register CR1</li>
+</ul></li>
+<li>Update I2C_MasterReceiveRXNE() static API to avoid set the STOP bit again after the bit clearing by Hardware during the masking operation
+<ul>
+<li>Add new API I2C_WaitOnSTOPRequestThroughIT() to wait for stop bit.</li>
+</ul></li>
+</ul></li>
+<li><strong>HAL/LL USB</strong> driver
+<ul>
+<li>Bug fix: USB_ReadPMA() and USB_WritePMA() by ensuring 16-bits access to USB PMA memory</li>
+<li>Bug fix: correct USB RX count calculation</li>
+<li>Fix USB Bulk transfer double buffer mode</li>
+<li>Remove register keyword from USB defined macros as no more supported by C++ compiler</li>
+<li>Minor rework on USBD_Start() and USBD_Stop() APIs: stopping device will be handled by HAL_PCD_DeInit() API.</li>
+<li>Remove non used API for USB device mode.</li>
+</ul></li>
+</ul>
+</div>
+</div>
+<div class="collapse">
+<input type="checkbox" id="collapse-section11" aria-hidden="true"> <label for="collapse-section11" aria-hidden="true"><strong>V1.1.4 / 26-June-2019</strong></label>
+<div>
+<h2 id="main-changes-1">Main Changes</h2>
+<ul>
+<li>General updates to fix known defects and enhancements implementation</li>
 <li>Add support of HAL callback registration feature</li>
 <li>Add new <strong>HAL EXTI</strong> driver</li>
 <li>General updates to fix CodeSonar compilation warnings</li>
@@ -56,7 +113,7 @@ <h2 id="main-changes">Main Changes</h2>
 <li>The feature disabled by default is available for the following HAL drivers:
 <ul>
 <li><strong>ADC, CEC, CAN, DAC, ETH, HCD, UART, USART, IRDA, SMARTCARD,</strong></li>
-<li><strong>MMC, NAND, NOR, PCCARD, PCD, RTC, SD, SRAM, I2C, SPI, I2S, TIM and WWDG</strong></li>
+<li><strong>MMC, NAND, NOR, PCCARD, PCD, RTC, SD, SRAM, SPI, I2S, TIM and WWDG</strong></li>
 </ul></li>
 <li>The feature may be enabled individually per HAL PPP driver by setting the corresponding definition USE_HAL_PPP_REGISTER_CALLBACKS to 1U in stm32f1xx_hal_conf.h project configuration file (template file stm32f1xx_hal_conf_template.h available from Drivers/STM32F1xx_HAL_Driver/Inc)</li>
 <li>Once enabled , the user application may resort to HAL_PPP_RegisterCallback() to register specific callback function(s) and unregister it(them) with HAL_PPP_UnRegisterCallback()</li>
@@ -170,32 +227,6 @@ <h2 id="main-changes">Main Changes</h2>
 <li>Add callback identifiers in HAL_SD_CallbackIDTypeDef enumerated typedef</li>
 </ul></li>
 </ul></li>
-<li><strong>HAL I2C</strong> update
-<ul>
-<li>I2C API changes for MISRA-C 2012 compliance:
-<ul>
-<li>Rename HAL_I2C_Master_Sequential_Transmit_IT() to HAL_I2C_Master_Seq_Transmit_IT()</li>
-<li>Rename HAL_I2C_Master_Sequentiel_Receive_IT() to HAL_I2C_Master_Seq_Receive_IT()</li>
-<li>Rename HAL_I2C_Slave_Sequentiel_Transmit_IT() to HAL_I2C_Slave_Seq_Transmit_IT()</li>
-<li>Rename HAL_I2C_Slave_Sequentiel_Receive_DMA() to HAL_I2C_Slave_Seq_Receive_DMA()</li>
-</ul></li>
-<li>Add support of I2C repeated start feature in DMA Mode With the following new API’s
-<ul>
-<li>HAL_I2C_Master_Seq_Transmit_DMA()</li>
-<li>HAL_I2C_Master_Seq_Receive_DMA()</li>
-<li>HAL_I2C_Slave_Seq_Transmit_DMA()</li>
-<li>HAL_I2C_Slave_Seq_Receive_DMA()</li>
-</ul></li>
-<li>Add new I2C transfer options to easy manage the sequential transfers
-<ul>
-<li>I2C_OTHER_FRAME</li>
-<li>I2C_OTHER_AND_LAST_FRAME</li>
-</ul></li>
-<li>Fix I2C send break issue in IT processes
-<ul>
-<li>Add additional check on hi2c-&gt;hdmatxand hi2c-&gt;hdmarx to avoid the DMA request enable when ITmode is used.</li>
-</ul></li>
-</ul></li>
 <li><strong>HAL SPI</strong> update
 <ul>
 <li>Align HAL/LL SPI driver with latest updates and enhancements</li>
@@ -273,7 +304,7 @@ <h2 id="main-changes">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section10" aria-hidden="true"> <label for="collapse-section10" aria-hidden="true"><strong>V1.1.3 / 09-October-2018</strong></label>
 <div>
-<h2 id="main-changes-1">Main Changes</h2>
+<h2 id="main-changes-2">Main Changes</h2>
 <ul>
 <li><strong>Maintenance release to fix known defects and enhancements implementation</strong></li>
 <li><strong>Generic drivers changes</strong></li>
@@ -316,7 +347,7 @@ <h2 id="main-changes-1">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section9" aria-hidden="true"> <label for="collapse-section9" aria-hidden="true"><strong>V1.1.2 / 09-March-2018</strong></label>
 <div>
-<h2 id="main-changes-2">Main Changes</h2>
+<h2 id="main-changes-3">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation</li>
 <li>Remove Date and version from header files</li>
@@ -394,7 +425,7 @@ <h2 id="main-changes-2">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section8" aria-hidden="true"> <label for="collapse-section8" aria-hidden="true"><strong>V1.1.1 / 12-May-2017</strong></label>
 <div>
-<h2 id="main-changes-3">Main Changes</h2>
+<h2 id="main-changes-4">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation</li>
 <li><strong>HAL Generic</strong> update
@@ -420,7 +451,7 @@ <h2 id="main-changes-3">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section7" aria-hidden="true"> <label for="collapse-section7" aria-hidden="true"><strong>V1.1.0 / 14-April-2017</strong></label>
 <div>
-<h2 id="main-changes-4">Main Changes</h2>
+<h2 id="main-changes-5">Main Changes</h2>
 <ul>
 <li><strong>Add Low Layer drivers allowing performance and footprint optimization</strong>
 <ul>
@@ -702,7 +733,7 @@ <h2 id="main-changes-4">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section6" aria-hidden="true"> <label for="collapse-section6" aria-hidden="true"><strong>V1.0.5 / 06-December-2016</strong></label>
 <div>
-<h2 id="main-changes-5">Main Changes</h2>
+<h2 id="main-changes-6">Main Changes</h2>
 <ul>
 <li>General updates to fix mainly known I2C defects and enhancements implementation</li>
 <li><strong>The following changes done on the HAL drivers require an update on the application code based on HAL V1.0.4</strong>
@@ -798,7 +829,7 @@ <h2 id="main-changes-5">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section5" aria-hidden="true"> <label for="collapse-section5" aria-hidden="true"><strong>V1.0.4 / 29-April-2016</strong></label>
 <div>
-<h2 id="main-changes-6">Main Changes</h2>
+<h2 id="main-changes-7">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation.</li>
 <li><strong>HAL RCC</strong>
@@ -838,7 +869,7 @@ <h2 id="main-changes-6">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section4" aria-hidden="true"> <label for="collapse-section4" aria-hidden="true"><strong>V1.0.3 / 11-January-2016</strong></label>
 <div>
-<h2 id="main-changes-7">Main Changes</h2>
+<h2 id="main-changes-8">Main Changes</h2>
 <ul>
 <li>Remove the #if defined(USE_HAL_LEGACY) condition to include Legacy/stm32_hal_legacy.h by default, in stm32f1xx_hal_def.h.</li>
 </ul>
@@ -847,7 +878,7 @@ <h2 id="main-changes-7">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section3" aria-hidden="true"> <label for="collapse-section3" aria-hidden="true"><strong>V1.0.2 / 18-December-2015</strong></label>
 <div>
-<h2 id="main-changes-8">Main Changes</h2>
+<h2 id="main-changes-9">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation.</li>
 <li><strong>HAL generic</strong>
@@ -933,7 +964,7 @@ <h2 id="main-changes-8">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section2" aria-hidden="true"> <label for="collapse-section2" aria-hidden="true"><strong>V1.0.1 / 31-July-2015</strong></label>
 <div>
-<h2 id="main-changes-9">Main Changes</h2>
+<h2 id="main-changes-10">Main Changes</h2>
 <ul>
 <li>General updates to fix known defects and enhancements implementation.</li>
 <li><strong>HAL generic</strong>
@@ -1035,7 +1066,7 @@ <h2 id="main-changes-9">Main Changes</h2>
 <div class="collapse">
 <input type="checkbox" id="collapse-section1" aria-hidden="true"> <label for="collapse-section1" aria-hidden="true"><strong>V1.0.0 / 15-December-2014</strong></label>
 <div>
-<h2 id="main-changes-10">Main Changes</h2>
+<h2 id="main-changes-11">Main Changes</h2>
 <ul>
 <li>First Official release of <strong>STM32F1xx HAL Drivers</strong> for all STM32F1 devices.</li>
 <li>This release is in line with <strong>STM32Cube Firmware specification Rev1.0</strong> document</li>
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
index 252f97353d..fbe94fd628 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
@@ -53,11 +53,11 @@
   * @{
   */
 /**
- * @brief STM32F1xx HAL Driver version number V1.1.4
+ * @brief STM32F1xx HAL Driver version number V1.1.5
    */
 #define __STM32F1xx_HAL_VERSION_MAIN   (0x01U) /*!< [31:24] main version */
 #define __STM32F1xx_HAL_VERSION_SUB1   (0x01U) /*!< [23:16] sub1 version */
-#define __STM32F1xx_HAL_VERSION_SUB2   (0x04U) /*!< [15:8]  sub2 version */
+#define __STM32F1xx_HAL_VERSION_SUB2   (0x05U) /*!< [15:8]  sub2 version */
 #define __STM32F1xx_HAL_VERSION_RC     (0x00U) /*!< [7:0]  release candidate */
 #define __STM32F1xx_HAL_VERSION         ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
                                         |(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
@@ -322,15 +322,25 @@ uint32_t HAL_GetTickPrio(void)
 HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
 {
   HAL_StatusTypeDef status  = HAL_OK;
+  HAL_TickFreqTypeDef prevTickFreq;
+
   assert_param(IS_TICKFREQ(Freq));
 
   if (uwTickFreq != Freq)
   {
+    /* Back up uwTickFreq frequency */
+    prevTickFreq = uwTickFreq;
+
+    /* Update uwTickFreq global variable used by HAL_InitTick() */
+    uwTickFreq = Freq;
+
     /* Apply the new tick Freq  */
     status = HAL_InitTick(uwTickPrio);
-    if (status == HAL_OK)
+
+    if (status != HAL_OK)
     {
-      uwTickFreq = Freq;
+      /* Restore previous tick frequency */
+      uwTickFreq = prevTickFreq;
     }
   }
 
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
index b1d50ba830..1da34936d3 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
@@ -88,8 +88,8 @@ static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
   */
 
 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
- *  @brief    Initialization and Configuration functions
- *
+  *  @brief    Initialization and Configuration functions
+  *
 @verbatim
  ===============================================================================
           ##### Initialization and de-initialization functions #####
@@ -595,6 +595,18 @@ void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
   }
 }
 
+
+/**
+  * @brief  Handles HCD Wakeup interrupt request.
+  * @param  hhcd HCD handle
+  * @retval HAL status
+  */
+void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
+{
+  UNUSED(hhcd);
+}
+
+
 /**
   * @brief  SOF callback.
   * @param  hhcd HCD handle
@@ -714,7 +726,9 @@ __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t
   * @param  pCallback pointer to the Callback function
   * @retval HAL status
   */
-HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback)
+HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
+                                           HAL_HCD_CallbackIDTypeDef CallbackID,
+                                           pHCD_CallbackTypeDef pCallback)
 {
   HAL_StatusTypeDef status = HAL_OK;
 
@@ -802,7 +816,7 @@ HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_Call
 
 /**
   * @brief  Unregister an USB HCD Callback
-  *         USB HCD callabck is redirected to the weak predefined callback
+  *         USB HCD callback is redirected to the weak predefined callback
   * @param  hhcd USB HCD handle
   * @param  CallbackID ID of the callback to be unregistered
   *         This parameter can be one of the following values:
@@ -906,7 +920,8 @@ HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_Ca
   * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
   * @retval HAL status
   */
-HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
+HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
+                                                             pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
 {
   HAL_StatusTypeDef status = HAL_OK;
 
@@ -941,7 +956,7 @@ HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *
 }
 
 /**
-  * @brief  UnRegister the USB HCD Host Channel Notify URB Change Callback
+  * @brief  Unregister the USB HCD Host Channel Notify URB Change Callback
   *         USB HCD Host Channel Notify URB Change Callback is redirected to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
   * @param  hhcd HCD handle
   * @retval HAL status
@@ -978,8 +993,8 @@ HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef
   */
 
 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
- *  @brief   Management functions
- *
+  *  @brief   Management functions
+  *
 @verbatim
  ===============================================================================
                       ##### Peripheral Control functions #####
@@ -1037,8 +1052,8 @@ HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
   */
 
 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
- *  @brief   Peripheral State functions
- *
+  *  @brief   Peripheral State functions
+  *
 @verbatim
  ===============================================================================
                       ##### Peripheral State functions #####
@@ -1166,6 +1181,13 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
   }
+  else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR)
+  {
+    __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
+    hhcd->hc[ch_num].state = HC_BBLERR;
+    __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
+    (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
+  }
   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
   {
     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
@@ -1224,6 +1246,7 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
     else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC)
     {
       hhcd->hc[ch_num].urb_state = URB_DONE;
+      hhcd->hc[ch_num].toggle_in ^= 1U;
 
 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
       hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
@@ -1279,6 +1302,11 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
       tmpreg |= USB_OTG_HCCHAR_CHENA;
       USBx_HC(ch_num)->HCCHAR = tmpreg;
     }
+    else if (hhcd->hc[ch_num].state == HC_BBLERR)
+    {
+      hhcd->hc[ch_num].ErrCnt++;
+      hhcd->hc[ch_num].urb_state = URB_ERROR;
+    }
     else
     {
       /* ... */
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
index 61a3818485..66c603dfee 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
@@ -337,6 +337,7 @@
   */
 #define I2C_TIMEOUT_FLAG          35U         /*!< Timeout 35 ms             */
 #define I2C_TIMEOUT_BUSY_FLAG     25U         /*!< Timeout 25 ms             */
+#define I2C_TIMEOUT_STOP_FLAG     5U          /*!< Timeout 5 ms              */
 #define I2C_NO_OPTION_FRAME       0xFFFF0000U /*!< XferOptions default value */
 
 /* Private define for @ref PreviousState usage */
@@ -377,6 +378,7 @@ static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
 static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
 static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
 static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnSTOPRequestThroughIT(I2C_HandleTypeDef *hi2c);
 static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c);
 
 /* Private functions for I2C transfer IRQ handler */
@@ -396,6 +398,8 @@ static void I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c, uint32_t IT2Flags);
 static void I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c);
 static void I2C_Slave_AF(I2C_HandleTypeDef *hi2c);
 
+static void I2C_MemoryTransmit_TXE_BTF(I2C_HandleTypeDef *hi2c);
+
 /* Private function to Convert Specific options */
 static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c);
 /**
@@ -504,6 +508,10 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
   /* Disable the selected I2C peripheral */
   __HAL_I2C_DISABLE(hi2c);
 
+  /*Reset I2C*/
+  hi2c->Instance->CR1 |= I2C_CR1_SWRST;
+  hi2c->Instance->CR1 &= ~I2C_CR1_SWRST;
+
   /* Get PCLK1 frequency */
   pclk1 = HAL_RCC_GetPCLK1Freq();
 
@@ -1162,6 +1170,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA
   */
 HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
 {
+  __IO uint32_t count = 0U;
+
   /* Init tickstart for timeout management*/
   uint32_t tickstart = HAL_GetTick();
 
@@ -1344,10 +1354,27 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd
           hi2c->XferCount--;
 
           /* Wait until BTF flag is set */
-          if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+          count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+          do
           {
-            return HAL_ERROR;
+            count--;
+            if (count == 0U)
+            {
+              hi2c->PreviousState       = I2C_STATE_NONE;
+              hi2c->State               = HAL_I2C_STATE_READY;
+              hi2c->Mode                = HAL_I2C_MODE_NONE;
+              hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
+
+              /* Re-enable IRQs */
+              __enable_irq();
+
+              /* Process Unlocked */
+              __HAL_UNLOCK(hi2c);
+
+              return HAL_ERROR;
+            }
           }
+          while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET);
 
           /* Generate Stop */
           SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
@@ -2567,6 +2594,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
   */
 HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
 {
+  __IO uint32_t count = 0U;
+
   /* Init tickstart for timeout management*/
   uint32_t tickstart = HAL_GetTick();
 
@@ -2751,10 +2780,27 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
           hi2c->XferCount--;
 
           /* Wait until BTF flag is set */
-          if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+          count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+          do
           {
-            return HAL_ERROR;
+            count--;
+            if (count == 0U)
+            {
+              hi2c->PreviousState       = I2C_STATE_NONE;
+              hi2c->State               = HAL_I2C_STATE_READY;
+              hi2c->Mode                = HAL_I2C_MODE_NONE;
+              hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
+
+              /* Re-enable IRQs */
+              __enable_irq();
+
+              /* Process Unlocked */
+              __HAL_UNLOCK(hi2c);
+
+              return HAL_ERROR;
+            }
           }
+          while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET);
 
           /* Generate Stop */
           SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
@@ -3100,6 +3146,27 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
         /* Send Slave Address and Memory Address */
         if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
         {
+          /* Abort the ongoing DMA */
+          dmaxferstatus = HAL_DMA_Abort_IT(hi2c->hdmarx);
+
+          /* Prevent unused argument(s) compilation and MISRA warning */
+          UNUSED(dmaxferstatus);
+
+          /* Clear directly Complete callback as no XferAbortCallback is used to finalize Abort treatment */
+          if (hi2c->hdmatx != NULL)
+          {
+            hi2c->hdmatx->XferCpltCallback = NULL;
+          }
+
+          /* Disable Acknowledge */
+          CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+          hi2c->XferSize = 0U;
+          hi2c->XferCount = 0U;
+
+          /* Disable I2C peripheral to prevent dummy data in buffer */
+          __HAL_I2C_DISABLE(hi2c);
+
           return HAL_ERROR;
         }
 
@@ -3243,6 +3310,27 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
         /* Send Slave Address and Memory Address */
         if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
         {
+          /* Abort the ongoing DMA */
+          dmaxferstatus = HAL_DMA_Abort_IT(hi2c->hdmarx);
+
+          /* Prevent unused argument(s) compilation and MISRA warning */
+          UNUSED(dmaxferstatus);
+
+          /* Clear directly Complete callback as no XferAbortCallback is used to finalize Abort treatment */
+          if (hi2c->hdmarx != NULL)
+          {
+            hi2c->hdmarx->XferCpltCallback = NULL;
+          }
+
+          /* Disable Acknowledge */
+          CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+          hi2c->XferSize = 0U;
+          hi2c->XferCount = 0U;
+
+          /* Disable I2C peripheral to prevent dummy data in buffer */
+          __HAL_I2C_DISABLE(hi2c);
+
           return HAL_ERROR;
         }
 
@@ -3367,7 +3455,11 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
       /* Wait until SB flag is set */
       if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
       {
-        return HAL_ERROR;
+        if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+        {
+          hi2c->ErrorCode = HAL_I2C_WRONG_START;
+        }
+        return HAL_TIMEOUT;
       }
 
       /* Send slave address */
@@ -3469,7 +3561,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16
   if (hi2c->State == HAL_I2C_STATE_READY)
   {
     /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+    if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
     {
       /* Wait until BUSY flag is reset */
       count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
@@ -3492,27 +3584,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16
       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
     }
 
-    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-    /* Wait until STOP flag is reset */
-    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-    do
-    {
-      count--;
-      if (count == 0U)
-      {
-        hi2c->PreviousState       = I2C_STATE_NONE;
-        hi2c->State               = HAL_I2C_STATE_READY;
-        hi2c->Mode                = HAL_I2C_MODE_NONE;
-        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hi2c);
-
-        return HAL_ERROR;
-      }
-    }
-    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-
     /* Process Locked */
     __HAL_LOCK(hi2c);
 
@@ -3589,7 +3660,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint1
   if (hi2c->State == HAL_I2C_STATE_READY)
   {
     /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+    if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
     {
       /* Wait until BUSY flag is reset */
       count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
@@ -3612,27 +3683,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint1
       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
     }
 
-    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-    /* Wait until STOP flag is reset */
-    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-    do
-    {
-      count--;
-      if (count == 0U)
-      {
-        hi2c->PreviousState       = I2C_STATE_NONE;
-        hi2c->State               = HAL_I2C_STATE_READY;
-        hi2c->Mode                = HAL_I2C_MODE_NONE;
-        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hi2c);
-
-        return HAL_ERROR;
-      }
-    }
-    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-
     /* Process Locked */
     __HAL_LOCK(hi2c);
 
@@ -3776,7 +3826,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_
   if (hi2c->State == HAL_I2C_STATE_READY)
   {
     /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+    if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
     {
       /* Wait until BUSY flag is reset */
       count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
@@ -3799,27 +3849,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_
       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
     }
 
-    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-    /* Wait until STOP flag is reset */
-    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-    do
-    {
-      count--;
-      if (count == 0U)
-      {
-        hi2c->PreviousState       = I2C_STATE_NONE;
-        hi2c->State               = HAL_I2C_STATE_READY;
-        hi2c->Mode                = HAL_I2C_MODE_NONE;
-        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hi2c);
-
-        return HAL_ERROR;
-      }
-    }
-    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-
     /* Process Locked */
     __HAL_LOCK(hi2c);
 
@@ -3922,7 +3951,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16
   if (hi2c->State == HAL_I2C_STATE_READY)
   {
     /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+    if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
     {
       /* Wait until BUSY flag is reset */
       count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
@@ -3945,27 +3974,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16
       while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
     }
 
-    /* Before any new treatment like start or restart, check that there is no pending STOP request */
-    /* Wait until STOP flag is reset */
-    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-    do
-    {
-      count--;
-      if (count == 0U)
-      {
-        hi2c->PreviousState       = I2C_STATE_NONE;
-        hi2c->State               = HAL_I2C_STATE_READY;
-        hi2c->Mode                = HAL_I2C_MODE_NONE;
-        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hi2c);
-
-        return HAL_ERROR;
-      }
-    }
-    while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
-
     /* Process Locked */
     __HAL_LOCK(hi2c);
 
@@ -4645,11 +4653,14 @@ HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
   */
 HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
 {
+  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
+
   /* Prevent unused argument(s) compilation warning */
   UNUSED(DevAddress);
 
   /* Abort Master transfer during Receive or Transmit process    */
-  if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && (hi2c->Mode == HAL_I2C_MODE_MASTER))
+  if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && (CurrentMode == HAL_I2C_MODE_MASTER))
   {
     /* Process Locked */
     __HAL_LOCK(hi2c);
@@ -4752,7 +4763,14 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
         /* BTF set -------------------------------------------------------------*/
         else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
         {
-          I2C_MasterTransmit_BTF(hi2c);
+          if (CurrentMode == HAL_I2C_MODE_MASTER)
+          {
+            I2C_MasterTransmit_BTF(hi2c);
+          }
+          else /* HAL_I2C_MODE_MEM */
+          {
+            I2C_MemoryTransmit_TXE_BTF(hi2c);
+          }
         }
         else
         {
@@ -4867,6 +4885,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
   uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1);
   uint32_t itsources  = READ_REG(hi2c->Instance->CR2);
   uint32_t error      = HAL_I2C_ERROR_NONE;
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
 
   /* I2C Bus error interrupt occurred ----------------------------------------*/
   if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BERR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
@@ -4892,7 +4911,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
   /* I2C Acknowledge failure error interrupt occurred ------------------------*/
   if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
   {
-    tmp1 = hi2c->Mode;
+    tmp1 = CurrentMode;
     tmp2 = hi2c->XferCount;
     tmp3 = hi2c->State;
     tmp4 = hi2c->PreviousState;
@@ -4910,7 +4929,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
       error |= HAL_I2C_ERROR_AF;
 
       /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
-      if (hi2c->Mode == HAL_I2C_MODE_MASTER)
+      if ((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM))
       {
         /* Generate Stop */
         SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
@@ -5235,59 +5254,7 @@ static void I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c)
     {
       if (hi2c->Mode == HAL_I2C_MODE_MEM)
       {
-        if (hi2c->EventCount == 0U)
-        {
-          /* If Memory address size is 8Bit */
-          if (hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT)
-          {
-            /* Send Memory Address */
-            hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
-
-            hi2c->EventCount += 2U;
-          }
-          /* If Memory address size is 16Bit */
-          else
-          {
-            /* Send MSB of Memory Address */
-            hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress);
-
-            hi2c->EventCount++;
-          }
-        }
-        else if (hi2c->EventCount == 1U)
-        {
-          /* Send LSB of Memory Address */
-          hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
-
-          hi2c->EventCount++;
-        }
-        else if (hi2c->EventCount == 2U)
-        {
-          if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
-          {
-            /* Generate Restart */
-            hi2c->Instance->CR1 |= I2C_CR1_START;
-          }
-          else if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
-          {
-            /* Write data to DR */
-            hi2c->Instance->DR = *hi2c->pBuffPtr;
-
-            /* Increment Buffer pointer */
-            hi2c->pBuffPtr++;
-
-            /* Update counter */
-            hi2c->XferCount--;
-          }
-          else
-          {
-            /* Do nothing */
-          }
-        }
-        else
-        {
-          /* Do nothing */
-        }
+        I2C_MemoryTransmit_TXE_BTF(hi2c);
       }
       else
       {
@@ -5359,28 +5326,103 @@ static void I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c)
 
         hi2c->PreviousState = I2C_STATE_NONE;
         hi2c->State = HAL_I2C_STATE_READY;
+        hi2c->Mode = HAL_I2C_MODE_NONE;
 
-        if (hi2c->Mode == HAL_I2C_MODE_MEM)
-        {
-          hi2c->Mode = HAL_I2C_MODE_NONE;
 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
-          hi2c->MemTxCpltCallback(hi2c);
+        hi2c->MasterTxCpltCallback(hi2c);
 #else
-          HAL_I2C_MemTxCpltCallback(hi2c);
+        HAL_I2C_MasterTxCpltCallback(hi2c);
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
-        }
-        else
-        {
-          hi2c->Mode = HAL_I2C_MODE_NONE;
+      }
+    }
+  }
+  else
+  {
+    /* Do nothing */
+  }
+}
+
+/**
+  * @brief  Handle TXE and BTF flag for Memory transmitter
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_MemoryTransmit_TXE_BTF(I2C_HandleTypeDef *hi2c)
+{
+  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+  HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+  if (hi2c->EventCount == 0U)
+  {
+    /* If Memory address size is 8Bit */
+    if (hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT)
+    {
+      /* Send Memory Address */
+      hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
 
+      hi2c->EventCount += 2U;
+    }
+    /* If Memory address size is 16Bit */
+    else
+    {
+      /* Send MSB of Memory Address */
+      hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress);
+
+      hi2c->EventCount++;
+    }
+  }
+  else if (hi2c->EventCount == 1U)
+  {
+    /* Send LSB of Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
+
+    hi2c->EventCount++;
+  }
+  else if (hi2c->EventCount == 2U)
+  {
+    if (CurrentState == HAL_I2C_STATE_BUSY_RX)
+    {
+      /* Generate Restart */
+      hi2c->Instance->CR1 |= I2C_CR1_START;
+    }
+    else if ((hi2c->XferCount > 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX))
+    {
+      /* Write data to DR */
+      hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+      /* Increment Buffer pointer */
+      hi2c->pBuffPtr++;
+
+      /* Update counter */
+      hi2c->XferCount--;
+    }
+    else if ((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX))
+    {
+      /* Generate Stop condition then Call TxCpltCallback() */
+      /* Disable EVT, BUF and ERR interrupt */
+      __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+      hi2c->PreviousState = I2C_STATE_NONE;
+      hi2c->State = HAL_I2C_STATE_READY;
+      hi2c->Mode = HAL_I2C_MODE_NONE;
 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
-          hi2c->MasterTxCpltCallback(hi2c);
+      hi2c->MemTxCpltCallback(hi2c);
 #else
-          HAL_I2C_MasterTxCpltCallback(hi2c);
+      HAL_I2C_MemTxCpltCallback(hi2c);
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
-        }
-      }
     }
+    else
+    {
+      /* Do nothing */
+    }
+  }
+  else
+  {
+    /* Do nothing */
   }
 }
 
@@ -5418,43 +5460,70 @@ static void I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
     }
     else if ((hi2c->XferOptions != I2C_FIRST_AND_NEXT_FRAME) && ((tmp == 1U) || (tmp == 0U)))
     {
-      /* Disable Acknowledge */
-      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+      if (I2C_WaitOnSTOPRequestThroughIT(hi2c) == HAL_OK)
+      {
+        /* Disable Acknowledge */
+        CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
 
-      /* Disable EVT, BUF and ERR interrupt */
-      __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+        /* Disable EVT, BUF and ERR interrupt */
+        __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
 
-      /* Read data from DR */
-      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
 
-      /* Increment Buffer pointer */
-      hi2c->pBuffPtr++;
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
 
-      /* Update counter */
-      hi2c->XferCount--;
+        /* Update counter */
+        hi2c->XferCount--;
 
-      hi2c->State = HAL_I2C_STATE_READY;
+        hi2c->State = HAL_I2C_STATE_READY;
 
-      if (hi2c->Mode == HAL_I2C_MODE_MEM)
-      {
-        hi2c->Mode = HAL_I2C_MODE_NONE;
-        hi2c->PreviousState = I2C_STATE_NONE;
+        if (hi2c->Mode == HAL_I2C_MODE_MEM)
+        {
+          hi2c->Mode = HAL_I2C_MODE_NONE;
+          hi2c->PreviousState = I2C_STATE_NONE;
 
 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
-        hi2c->MemRxCpltCallback(hi2c);
+          hi2c->MemRxCpltCallback(hi2c);
 #else
-        HAL_I2C_MemRxCpltCallback(hi2c);
+          HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+        }
+        else
+        {
+          hi2c->Mode = HAL_I2C_MODE_NONE;
+          hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+          hi2c->MasterRxCpltCallback(hi2c);
+#else
+          HAL_I2C_MasterRxCpltCallback(hi2c);
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+        }
       }
       else
       {
+        /* Disable EVT, BUF and ERR interrupt */
+        __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
+
+        /* Update counter */
+        hi2c->XferCount--;
+
+        hi2c->State = HAL_I2C_STATE_READY;
         hi2c->Mode = HAL_I2C_MODE_NONE;
-        hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
 
+        /* Call user error callback */
 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
-        hi2c->MasterRxCpltCallback(hi2c);
+        hi2c->ErrorCallback(hi2c);
 #else
-        HAL_I2C_MasterRxCpltCallback(hi2c);
+        HAL_I2C_ErrorCallback(hi2c);
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
       }
     }
@@ -5625,13 +5694,11 @@ static void I2C_Master_SB(I2C_HandleTypeDef *hi2c)
         hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
       }
 
-      if ((hi2c->hdmatx != NULL) || (hi2c->hdmarx != NULL))
+      if (((hi2c->hdmatx != NULL) && (hi2c->hdmatx->XferCpltCallback != NULL))
+          || ((hi2c->hdmarx != NULL) && (hi2c->hdmarx->XferCpltCallback != NULL)))
       {
-        if ((hi2c->hdmatx->XferCpltCallback != NULL) || (hi2c->hdmarx->XferCpltCallback != NULL))
-        {
-          /* Enable DMA Request */
-          SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
-        }
+        /* Enable DMA Request */
+        SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
       }
     }
     else
@@ -6244,8 +6311,10 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c)
 {
   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
   HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+  HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+  uint32_t CurrentError;
 
-  if ((hi2c->Mode == HAL_I2C_MODE_MASTER) && (CurrentState == HAL_I2C_STATE_BUSY_RX))
+  if (((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) && (CurrentState == HAL_I2C_STATE_BUSY_RX))
   {
     /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */
     hi2c->Instance->CR1 &= ~I2C_CR1_POS;
@@ -6264,9 +6333,9 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c)
     if ((READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN) && (CurrentState != HAL_I2C_STATE_ABORT))
     {
       hi2c->State = HAL_I2C_STATE_READY;
+      hi2c->Mode = HAL_I2C_MODE_NONE;
     }
     hi2c->PreviousState = I2C_STATE_NONE;
-    hi2c->Mode = HAL_I2C_MODE_NONE;
   }
 
   /* Abort DMA transfer */
@@ -6363,15 +6432,24 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c)
     HAL_I2C_ErrorCallback(hi2c);
 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
   }
-  /* STOP Flag is not set after a NACK reception */
+
+  /* STOP Flag is not set after a NACK reception, BusError, ArbitrationLost, OverRun */
+  CurrentError = hi2c->ErrorCode;
+
+  if (((CurrentError & HAL_I2C_ERROR_BERR) == HAL_I2C_ERROR_BERR) || \
+      ((CurrentError & HAL_I2C_ERROR_ARLO) == HAL_I2C_ERROR_ARLO) || \
+      ((CurrentError & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)     || \
+      ((CurrentError & HAL_I2C_ERROR_OVR) == HAL_I2C_ERROR_OVR))
+  {
+    /* Disable EVT, BUF and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+  }
+
   /* So may inform upper layer that listen phase is stopped */
   /* during NACK error treatment */
   CurrentState = hi2c->State;
   if (((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF) && (CurrentState == HAL_I2C_STATE_LISTEN))
   {
-    /* Disable EVT, BUF and ERR interrupt */
-    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
     hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
     hi2c->PreviousState = I2C_STATE_NONE;
     hi2c->State         = HAL_I2C_STATE_READY;
@@ -6419,7 +6497,11 @@ static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_
   /* Wait until SB flag is set */
   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
   {
-    return HAL_ERROR;
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
   }
 
   if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
@@ -6488,7 +6570,11 @@ static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t
   /* Wait until SB flag is set */
   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
   {
-    return HAL_ERROR;
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
   }
 
   if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
@@ -6525,7 +6611,11 @@ static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t
     /* Wait until SB flag is set */
     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
     {
-      return HAL_ERROR;
+      if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+      {
+        hi2c->ErrorCode = HAL_I2C_WRONG_START;
+      }
+      return HAL_TIMEOUT;
     }
 
     /* Send header of slave address */
@@ -6561,7 +6651,11 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_
   /* Wait until SB flag is set */
   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
   {
-    return HAL_ERROR;
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
   }
 
   /* Send slave address */
@@ -6640,7 +6734,11 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t
   /* Wait until SB flag is set */
   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
   {
-    return HAL_ERROR;
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
   }
 
   /* Send slave address */
@@ -6710,7 +6808,11 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t
   /* Wait until SB flag is set */
   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
   {
-    return HAL_ERROR;
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
   }
 
   /* Send slave address */
@@ -6743,8 +6845,14 @@ static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma)
   __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
 
   /* Clear Complete callback */
-  hi2c->hdmatx->XferCpltCallback = NULL;
-  hi2c->hdmarx->XferCpltCallback = NULL;
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferCpltCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferCpltCallback = NULL;
+  }
 
   if ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_TX) == (uint32_t)HAL_I2C_STATE_BUSY_TX) || ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_RX) == (uint32_t)HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE)))
   {
@@ -6867,8 +6975,14 @@ static void I2C_DMAError(DMA_HandleTypeDef *hdma)
   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
 
   /* Clear Complete callback */
-  hi2c->hdmatx->XferCpltCallback = NULL;
-  hi2c->hdmarx->XferCpltCallback = NULL;
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferCpltCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferCpltCallback = NULL;
+  }
 
   /* Disable Acknowledge */
   CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
@@ -6893,14 +7007,35 @@ static void I2C_DMAError(DMA_HandleTypeDef *hdma)
   */
 static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
 {
+  __IO uint32_t count = 0U;
   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
 
   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
   HAL_I2C_StateTypeDef CurrentState = hi2c->State;
 
+  /* During abort treatment, check that there is no pending STOP request */
+  /* Wait until STOP flag is reset */
+  count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+  do
+  {
+    if (count == 0U)
+    {
+      hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+      break;
+    }
+    count--;
+  }
+  while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
+
   /* Clear Complete callback */
-  hi2c->hdmatx->XferCpltCallback = NULL;
-  hi2c->hdmarx->XferCpltCallback = NULL;
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferCpltCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferCpltCallback = NULL;
+  }
 
   /* Disable Acknowledge */
   CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
@@ -6908,8 +7043,14 @@ static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
   hi2c->XferCount = 0U;
 
   /* Reset XferAbortCallback */
-  hi2c->hdmatx->XferAbortCallback = NULL;
-  hi2c->hdmarx->XferAbortCallback = NULL;
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferAbortCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferAbortCallback = NULL;
+  }
 
   /* Disable I2C peripheral to prevent dummy data in buffer */
   __HAL_I2C_DISABLE(hi2c);
@@ -7155,6 +7296,33 @@ static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
   return HAL_OK;
 }
 
+/**
+  * @brief  This function handles I2C Communication Timeout for specific usage of STOP request through Interrupt.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef I2C_WaitOnSTOPRequestThroughIT(I2C_HandleTypeDef *hi2c)
+{
+  __IO uint32_t count = 0U;
+
+  /* Wait until STOP flag is reset */
+  count = I2C_TIMEOUT_STOP_FLAG * (SystemCoreClock / 25U / 1000U);
+  do
+  {
+    count--;
+    if (count == 0U)
+    {
+      hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
+
+      return HAL_ERROR;
+    }
+  }
+  while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
+
+  return HAL_OK;
+}
+
 /**
   * @brief  This function handles I2C Communication Timeout for specific usage of RXNE flag.
   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
index 89c903a549..a37814aa82 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
@@ -22,14 +22,11 @@
 
      (#) Fill parameters of Init structure in HCD handle
 
-     (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
+     (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
 
      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
-         (##) Enable the PCD/USB Low Level interface clock using the following macro
-              (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
-                    on STM32F102xx and STM32F103xx devices
-              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
-                    on STM32F105xx and STM32F107xx devices
+         (##) Enable the PCD/USB Low Level interface clock using
+              (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device only FS peripheral
 
          (##) Initialize the related GPIO clocks
          (##) Configure PCD pin-out
@@ -38,7 +35,7 @@
      (#)Associate the Upper USB device stack to the HAL PCD Driver:
          (##) hpcd.pData = pdev;
 
-     (#)Enable HCD transmission and reception:
+     (#)Enable PCD transmission and reception:
          (##) HAL_PCD_Start();
 
   @endverbatim
@@ -63,20 +60,15 @@
   * @{
   */
 
-
-
-#ifdef HAL_PCD_MODULE_ENABLED
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
 /** @defgroup PCD PCD
   * @brief PCD HAL module driver
   * @{
   */
 
+#ifdef HAL_PCD_MODULE_ENABLED
+
+#if defined (USB) || defined (USB_OTG_FS)
+
 /* Private types -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private constants ---------------------------------------------------------*/
@@ -84,30 +76,27 @@
 /** @defgroup PCD_Private_Macros PCD Private Macros
   * @{
   */
-#define PCD_PENDED_ZLP 0xffff
-#define PCD_PENDED_PROCESSED 0xfffe
-#define PCD_OUT_DTOG(value) (((value) & USB_EP_DTOG_RX) != 0)
-#define PCD_OUT_SW(value) (((value) & USB_EP_DTOG_TX) != 0)
-#define PCD_IN_DTOG(value) (((value) & USB_EP_DTOG_TX) != 0)
-#define PCD_IN_SW(value) (((value) & USB_EP_DTOG_RX) != 0)
+#define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
+#define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
 /**
   * @}
   */
 
-/* Private functions ---------------------------------------------------------*/
+/* Private functions prototypes ----------------------------------------------*/
 /** @defgroup PCD_Private_Functions PCD Private Functions
   * @{
   */
 #if defined (USB_OTG_FS)
 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
-#endif /* USB_OTG_FS */
+static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
+static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
-#endif /* USB */
-
-static HAL_StatusTypeDef HAL_PCD_EP_ReceiveData(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef* ep);
-
+static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
+static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
+#endif /* defined (USB) */
 /**
   * @}
   */
@@ -118,8 +107,8 @@ static HAL_StatusTypeDef HAL_PCD_EP_ReceiveData(PCD_HandleTypeDef *hpcd, PCD_EPT
   */
 
 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
- *  @brief    Initialization and Configuration functions
- *
+  *  @brief    Initialization and Configuration functions
+  *
 @verbatim
  ===============================================================================
             ##### Initialization and de-initialization functions #####
@@ -132,16 +121,19 @@ static HAL_StatusTypeDef HAL_PCD_EP_ReceiveData(PCD_HandleTypeDef *hpcd, PCD_EPT
 
 /**
   * @brief  Initializes the PCD according to the specified
-  *         parameters in the PCD_InitTypeDef and create the associated handle.
-  * @param  hpcd: PCD handle
+  *         parameters in the PCD_InitTypeDef and initialize the associated handle.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
 {
-  uint32_t index = 0U;
+#if defined (USB_OTG_FS)
+  USB_OTG_GlobalTypeDef *USBx;
+#endif /* defined (USB_OTG_FS) */
+  uint8_t i;
 
   /* Check the PCD handle allocation */
-  if(hpcd == NULL)
+  if (hpcd == NULL)
   {
     return HAL_ERROR;
   }
@@ -149,75 +141,112 @@ HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
   /* Check the parameters */
   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
 
-  if(hpcd->State == HAL_PCD_STATE_RESET)
+#if defined (USB_OTG_FS)
+  USBx = hpcd->Instance;
+#endif /* defined (USB_OTG_FS) */
+
+  if (hpcd->State == HAL_PCD_STATE_RESET)
   {
     /* Allocate lock resource and initialize it */
     hpcd->Lock = HAL_UNLOCKED;
 
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->SOFCallback = HAL_PCD_SOFCallback;
+    hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
+    hpcd->ResetCallback = HAL_PCD_ResetCallback;
+    hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
+    hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
+    hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
+    hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
+    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
+    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
+    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
+    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
+
+    if (hpcd->MspInitCallback == NULL)
+    {
+      hpcd->MspInitCallback = HAL_PCD_MspInit;
+    }
+
+    /* Init the low level hardware */
+    hpcd->MspInitCallback(hpcd);
+#else
     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
     HAL_PCD_MspInit(hpcd);
+#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
   }
 
   hpcd->State = HAL_PCD_STATE_BUSY;
 
+#if defined (USB_OTG_FS)
+  /* Disable DMA mode for FS instance */
+  if ((USBx->CID & (0x1U << 8)) == 0U)
+  {
+    hpcd->Init.dma_enable = 0U;
+  }
+#endif /* defined (USB_OTG_FS) */
+
   /* Disable the Interrupts */
   __HAL_PCD_DISABLE(hpcd);
 
   /*Init the Core (common init.) */
-  USB_CoreInit(hpcd->Instance, hpcd->Init);
+  if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
+  {
+    hpcd->State = HAL_PCD_STATE_ERROR;
+    return HAL_ERROR;
+  }
 
   /* Force Device Mode*/
-  USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
+  (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
 
   /* Init endpoints structures */
-  for (index = 0U; index < 15U ; index++)
+  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
   {
     /* Init ep structure */
-    hpcd->IN_ep[index].is_in = 1U;
-    hpcd->IN_ep[index].num = index;
-    hpcd->IN_ep[index].tx_fifo_num = index;
-    /* Control until ep is actvated */
-    hpcd->IN_ep[index].type = EP_TYPE_CTRL;
-    hpcd->IN_ep[index].maxpacket =  0U;
-    hpcd->IN_ep[index].xfer_buff = 0U;
-    hpcd->IN_ep[index].xfer_len = 0U;
-    hpcd->IN_ep[index].pending0 = 0U;
-    hpcd->IN_ep[index].pending1 = 0U;
-  }
-
-  for (index = 0U; index < 15U ; index++)
-  {
-    hpcd->OUT_ep[index].is_in = 0U;
-    hpcd->OUT_ep[index].num = index;
-    hpcd->OUT_ep[index].tx_fifo_num = index;
+    hpcd->IN_ep[i].is_in = 1U;
+    hpcd->IN_ep[i].num = i;
+    hpcd->IN_ep[i].tx_fifo_num = i;
     /* Control until ep is activated */
-    hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
-    hpcd->OUT_ep[index].maxpacket = 0U;
-    hpcd->OUT_ep[index].xfer_buff = 0U;
-    hpcd->OUT_ep[index].xfer_len = 0U;
-    hpcd->OUT_ep[index].pending0 = 0U;
-    hpcd->OUT_ep[index].pending1 = 0U;
+    hpcd->IN_ep[i].type = EP_TYPE_CTRL;
+    hpcd->IN_ep[i].maxpacket = 0U;
+    hpcd->IN_ep[i].xfer_buff = 0U;
+    hpcd->IN_ep[i].xfer_len = 0U;
+  }
+
+  for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
+  {
+    hpcd->OUT_ep[i].is_in = 0U;
+    hpcd->OUT_ep[i].num = i;
+    /* Control until ep is activated */
+    hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
+    hpcd->OUT_ep[i].maxpacket = 0U;
+    hpcd->OUT_ep[i].xfer_buff = 0U;
+    hpcd->OUT_ep[i].xfer_len = 0U;
   }
 
   /* Init Device */
-  USB_DevInit(hpcd->Instance, hpcd->Init);
+  if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
+  {
+    hpcd->State = HAL_PCD_STATE_ERROR;
+    return HAL_ERROR;
+  }
 
   hpcd->USB_Address = 0U;
-  hpcd->State= HAL_PCD_STATE_READY;
+  hpcd->State = HAL_PCD_STATE_READY;
+  (void)USB_DevDisconnect(hpcd->Instance);
 
-  USB_DevDisconnect (hpcd->Instance);
   return HAL_OK;
 }
 
 /**
-  * @brief  DeInitializes the PCD peripheral
-  * @param  hpcd: PCD handle
+  * @brief  DeInitializes the PCD peripheral.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
 {
   /* Check the PCD handle allocation */
-  if(hpcd == NULL)
+  if (hpcd == NULL)
   {
     return HAL_ERROR;
   }
@@ -225,10 +254,23 @@ HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
   hpcd->State = HAL_PCD_STATE_BUSY;
 
   /* Stop Device */
-  HAL_PCD_Stop(hpcd);
+  if (USB_StopDevice(hpcd->Instance) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+  if (hpcd->MspDeInitCallback == NULL)
+  {
+    hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
+  }
 
   /* DeInit the low level hardware */
+  hpcd->MspDeInitCallback(hpcd);
+#else
+  /* DeInit the low level hardware: CLOCK, NVIC.*/
   HAL_PCD_MspDeInit(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 
   hpcd->State = HAL_PCD_STATE_RESET;
 
@@ -237,13 +279,14 @@ HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
 
 /**
   * @brief  Initializes the PCD MSP.
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval None
   */
 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_MspInit could be implemented in the user file
    */
@@ -251,25 +294,548 @@ __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
 
 /**
   * @brief  DeInitializes PCD MSP.
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval None
   */
 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_MspDeInit could be implemented in the user file
    */
 }
 
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+/**
+  * @brief  Register a User USB PCD Callback
+  *         To be used instead of the weak predefined callback
+  * @param  hpcd USB PCD handle
+  * @param  CallbackID ID of the callback to be registered
+  *         This parameter can be one of the following values:
+  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
+  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
+  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
+  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
+  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
+  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
+  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
+  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
+  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
+  * @param  pCallback pointer to the Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
+                                           HAL_PCD_CallbackIDTypeDef CallbackID,
+                                           pPCD_CallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+    return HAL_ERROR;
+  }
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    switch (CallbackID)
+    {
+      case HAL_PCD_SOF_CB_ID :
+        hpcd->SOFCallback = pCallback;
+        break;
+
+      case HAL_PCD_SETUPSTAGE_CB_ID :
+        hpcd->SetupStageCallback = pCallback;
+        break;
+
+      case HAL_PCD_RESET_CB_ID :
+        hpcd->ResetCallback = pCallback;
+        break;
+
+      case HAL_PCD_SUSPEND_CB_ID :
+        hpcd->SuspendCallback = pCallback;
+        break;
+
+      case HAL_PCD_RESUME_CB_ID :
+        hpcd->ResumeCallback = pCallback;
+        break;
+
+      case HAL_PCD_CONNECT_CB_ID :
+        hpcd->ConnectCallback = pCallback;
+        break;
+
+      case HAL_PCD_DISCONNECT_CB_ID :
+        hpcd->DisconnectCallback = pCallback;
+        break;
+
+      case HAL_PCD_MSPINIT_CB_ID :
+        hpcd->MspInitCallback = pCallback;
+        break;
+
+      case HAL_PCD_MSPDEINIT_CB_ID :
+        hpcd->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (hpcd->State == HAL_PCD_STATE_RESET)
+  {
+    switch (CallbackID)
+    {
+      case HAL_PCD_MSPINIT_CB_ID :
+        hpcd->MspInitCallback = pCallback;
+        break;
+
+      case HAL_PCD_MSPDEINIT_CB_ID :
+        hpcd->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+  return status;
+}
+
+/**
+  * @brief  Unregister an USB PCD Callback
+  *         USB PCD callabck is redirected to the weak predefined callback
+  * @param  hpcd USB PCD handle
+  * @param  CallbackID ID of the callback to be unregistered
+  *         This parameter can be one of the following values:
+  *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
+  *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
+  *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
+  *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
+  *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
+  *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
+  *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
+  *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
+  *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  /* Setup Legacy weak Callbacks  */
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    switch (CallbackID)
+    {
+      case HAL_PCD_SOF_CB_ID :
+        hpcd->SOFCallback = HAL_PCD_SOFCallback;
+        break;
+
+      case HAL_PCD_SETUPSTAGE_CB_ID :
+        hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
+        break;
+
+      case HAL_PCD_RESET_CB_ID :
+        hpcd->ResetCallback = HAL_PCD_ResetCallback;
+        break;
+
+      case HAL_PCD_SUSPEND_CB_ID :
+        hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
+        break;
+
+      case HAL_PCD_RESUME_CB_ID :
+        hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
+        break;
+
+      case HAL_PCD_CONNECT_CB_ID :
+        hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
+        break;
+
+      case HAL_PCD_DISCONNECT_CB_ID :
+        hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
+        break;
+
+      case HAL_PCD_MSPINIT_CB_ID :
+        hpcd->MspInitCallback = HAL_PCD_MspInit;
+        break;
+
+      case HAL_PCD_MSPDEINIT_CB_ID :
+        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
+        break;
+
+      default :
+        /* Update the error code */
+        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (hpcd->State == HAL_PCD_STATE_RESET)
+  {
+    switch (CallbackID)
+    {
+      case HAL_PCD_MSPINIT_CB_ID :
+        hpcd->MspInitCallback = HAL_PCD_MspInit;
+        break;
+
+      case HAL_PCD_MSPDEINIT_CB_ID :
+        hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
+        break;
+
+      default :
+        /* Update the error code */
+        hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+  return status;
+}
+
+/**
+  * @brief  Register USB PCD Data OUT Stage Callback
+  *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
+                                                       pPCD_DataOutStageCallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->DataOutStageCallback = pCallback;
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Unregister the USB PCD Data OUT Stage Callback
+  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Register USB PCD Data IN Stage Callback
+  *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
+                                                      pPCD_DataInStageCallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->DataInStageCallback = pCallback;
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Unregister the USB PCD Data IN Stage Callback
+  *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Register USB PCD Iso OUT incomplete Callback
+  *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
+                                                       pPCD_IsoOutIncpltCallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->ISOOUTIncompleteCallback = pCallback;
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Unregister the USB PCD Iso OUT incomplete Callback
+  *         USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Register USB PCD Iso IN incomplete Callback
+  *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
+                                                      pPCD_IsoInIncpltCallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->ISOINIncompleteCallback = pCallback;
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+/**
+  * @brief  Unregister the USB PCD Iso IN incomplete Callback
+  *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Process locked */
+  __HAL_LOCK(hpcd);
+
+  if (hpcd->State == HAL_PCD_STATE_READY)
+  {
+    hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
+  }
+  else
+  {
+    /* Update the error code */
+    hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hpcd);
+
+  return status;
+}
+
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
 /**
   * @}
   */
 
-/** @defgroup PCD_Exported_Functions_Group2 IO operation functions
- *  @brief   Data transfers functions
- *
+/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
+  *  @brief   Data transfers functions
+  *
 @verbatim
  ===============================================================================
                       ##### IO operation functions #####
@@ -283,141 +849,204 @@ __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
   */
 
 /**
-  * @brief  Start The USB Device.
-  * @param  hpcd: PCD handle
+  * @brief  Start the USB device
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
 {
   __HAL_LOCK(hpcd);
-  HAL_PCDEx_SetConnectionState (hpcd, 1);
-  USB_DevConnect (hpcd->Instance);
   __HAL_PCD_ENABLE(hpcd);
+
+#if defined (USB)
+  HAL_PCDEx_SetConnectionState(hpcd, 1U);
+#endif /* defined (USB) */
+
+  (void)USB_DevConnect(hpcd->Instance);
   __HAL_UNLOCK(hpcd);
+
   return HAL_OK;
 }
 
 /**
-  * @brief  Stop The USB Device.
-  * @param  hpcd: PCD handle
+  * @brief  Stop the USB device.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
 {
   __HAL_LOCK(hpcd);
   __HAL_PCD_DISABLE(hpcd);
-  USB_StopDevice(hpcd->Instance);
-  USB_DevDisconnect (hpcd->Instance);
+
+#if defined (USB)
+  HAL_PCDEx_SetConnectionState(hpcd, 0U);
+#endif /* defined (USB) */
+
+  (void)USB_DevDisconnect(hpcd->Instance);
+
+#if defined (USB_OTG_FS)
+  (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
+#endif /* defined (USB_OTG_FS) */
+
   __HAL_UNLOCK(hpcd);
+
   return HAL_OK;
 }
 
 #if defined (USB_OTG_FS)
 /**
-  * @brief  This function handles PCD interrupt request.
-  * @param  hpcd: PCD handle
+  * @brief  Handles PCD interrupt request.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
 {
   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
-  uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
-  uint32_t fifoemptymsk = 0U, temp = 0U;
-  USB_OTG_EPTypeDef *ep = NULL;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t i, ep_intr, epint, epnum;
+  uint32_t fifoemptymsk, temp;
+  USB_OTG_EPTypeDef *ep;
 
   /* ensure that we are in device mode */
   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
   {
     /* avoid spurious interrupt */
-    if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
+    if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
     {
       return;
     }
 
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
     {
-     /* incorrect mode, acknowledge the interrupt */
+      /* incorrect mode, acknowledge the interrupt */
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
     }
 
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
+    /* Handle RxQLevel Interrupt */
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
+    {
+      USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+
+      temp = USBx->GRXSTSP;
+
+      ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
+
+      if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
+      {
+        if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
+        {
+          (void)USB_ReadPacket(USBx, ep->xfer_buff,
+                               (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
+
+          ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+          ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+        }
+      }
+      else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
+      {
+        (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
+        ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+      }
+      else
+      {
+        /* ... */
+      }
+      USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+    }
+
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
     {
       epnum = 0U;
 
       /* Read in the device interrupt bits */
       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
 
-      while ( ep_intr )
+      while (ep_intr != 0U)
       {
-        if (ep_intr & 0x1U)
+        if ((ep_intr & 0x1U) != 0U)
         {
-          epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
+          epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
 
-          if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
+          if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
           {
             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
-
-            HAL_PCD_DataOutStageCallback(hpcd, epnum);
+            (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
           }
 
-          if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
+          if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
           {
-            /* Inform the upper layer that a setup packet is available */
-            HAL_PCD_SetupStageCallback(hpcd);
             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
+            /* Class B setup phase done for previous decoded setup */
+            (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
           }
 
-          if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
+          if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
           {
             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
           }
+
+          /* Clear Status Phase Received interrupt */
+          if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
+          {
+            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
+          }
+
+          /* Clear OUT NAK interrupt */
+          if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
+          {
+            CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
+          }
         }
         epnum++;
         ep_intr >>= 1U;
       }
     }
 
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
     {
       /* Read in the device interrupt bits */
       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
 
       epnum = 0U;
 
-      while ( ep_intr )
+      while (ep_intr != 0U)
       {
-        if (ep_intr & 0x1U) /* In ITR */
+        if ((ep_intr & 0x1U) != 0U) /* In ITR */
         {
-          epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
+          epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
 
-          if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
+          if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
           {
-            fifoemptymsk = 0x1U << epnum;
+            fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
 
             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
 
-            HAL_PCD_DataInStageCallback(hpcd, epnum);
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+            hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
+#else
+            HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
           }
-          if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
+          if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
           {
             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
           }
-          if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
+          if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
           {
             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
           }
-          if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
+          if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
           {
             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
           }
-          if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
+          if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
           {
             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
           }
-          if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
+          if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
           {
-            PCD_WriteEmptyTxFifo(hpcd , epnum);
+            (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
           }
         }
         epnum++;
@@ -426,361 +1055,487 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
     }
 
     /* Handle Resume Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
     {
-     /* Clear the Remote Wake-up signalling */
+      /* Clear the Remote Wake-up Signaling */
       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
 
-     HAL_PCD_ResumeCallback(hpcd);
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->ResumeCallback(hpcd);
+#else
+      HAL_PCD_ResumeCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 
-     __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
+      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
     }
 
     /* Handle Suspend Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
     {
-      if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+      if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
       {
-
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+        hpcd->SuspendCallback(hpcd);
+#else
         HAL_PCD_SuspendCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
       }
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
     }
-
     /* Handle Reset Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
     {
       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
-      USB_FlushTxFifo(hpcd->Instance ,  0x10U);
+      (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
 
-      for (index = 0U; index < hpcd->Init.dev_endpoints ; index++)
+      for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
       {
-        USBx_INEP(index)->DIEPINT = 0xFFU;
-        USBx_OUTEP(index)->DOEPINT = 0xFFU;
+        USBx_INEP(i)->DIEPINT = 0xFB7FU;
+        USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+        USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
+        USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
+        USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+        USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
       }
-      USBx_DEVICE->DAINT = 0xFFFFFFFFU;
       USBx_DEVICE->DAINTMSK |= 0x10001U;
 
-      USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
-      USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
+      if (hpcd->Init.use_dedicated_ep1 != 0U)
+      {
+        USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
+                                   USB_OTG_DOEPMSK_XFRCM |
+                                   USB_OTG_DOEPMSK_EPDM;
+
+        USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
+                                  USB_OTG_DIEPMSK_XFRCM |
+                                  USB_OTG_DIEPMSK_EPDM;
+      }
+      else
+      {
+        USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
+                                USB_OTG_DOEPMSK_XFRCM |
+                                USB_OTG_DOEPMSK_EPDM |
+                                USB_OTG_DOEPMSK_OTEPSPRM |
+                                USB_OTG_DOEPMSK_NAKM;
+
+        USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
+                                USB_OTG_DIEPMSK_XFRCM |
+                                USB_OTG_DIEPMSK_EPDM;
+      }
 
       /* Set Default Address to 0 */
       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
 
       /* setup EP0 to receive SETUP packets */
-      USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+      (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
 
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
     }
 
     /* Handle Enumeration done Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
     {
-      USB_ActivateSetup(hpcd->Instance);
-      hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
-
-      hpcd->Init.speed            = USB_OTG_SPEED_FULL;
-      hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE ;
-      hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
-
-      HAL_PCD_ResetCallback(hpcd);
-
-      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
-    }
-
-    /* Handle RxQLevel Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
-    {
-      USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
-      temp = USBx->GRXSTSP;
-      ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
-
-      if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_DATA_UPDT)
-      {
-        if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
-        {
-          USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
-          ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
-          ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
-        }
-      }
-      else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_SETUP_UPDT)
-      {
-        USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
-        ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
-      }
-      USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+      (void)USB_ActivateSetup(hpcd->Instance);
+      hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
+
+      /* Set USB Turnaround time */
+      (void)USB_SetTurnaroundTime(hpcd->Instance,
+                                  HAL_RCC_GetHCLKFreq(),
+                                  (uint8_t)hpcd->Init.speed);
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->ResetCallback(hpcd);
+#else
+      HAL_PCD_ResetCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
     }
 
     /* Handle SOF Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
     {
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->SOFCallback(hpcd);
+#else
       HAL_PCD_SOFCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
     }
 
     /* Handle Incomplete ISO IN Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
     {
-      HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
+      /* Keep application checking the corresponding Iso IN endpoint
+      causing the incomplete Interrupt */
+      epnum = 0U;
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
+#else
+      HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
     }
 
     /* Handle Incomplete ISO OUT Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
     {
-      HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
+      /* Keep application checking the corresponding Iso OUT endpoint
+      causing the incomplete Interrupt */
+      epnum = 0U;
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
+#else
+      HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
     }
 
     /* Handle Connection event Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
     {
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->ConnectCallback(hpcd);
+#else
       HAL_PCD_ConnectCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
     }
 
     /* Handle Disconnection event Interrupt */
-    if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
+    if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
     {
       temp = hpcd->Instance->GOTGINT;
 
-      if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
+      if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
       {
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+        hpcd->DisconnectCallback(hpcd);
+#else
         HAL_PCD_DisconnectCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
       }
       hpcd->Instance->GOTGINT |= temp;
     }
   }
 }
-#endif /* USB_OTG_FS */
+
+
+/**
+  * @brief  Handles PCD Wakeup interrupt request.
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+  /* Clear EXTI pending Bit */
+  __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
+}
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
 /**
   * @brief  This function handles PCD interrupt request.
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
 {
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
+  uint16_t store_ep[8];
+  uint8_t i;
+
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
   {
     /* servicing of the endpoint correct transfer interrupt */
     /* clear of the CTR flag into the sub */
-    PCD_EP_ISR_Handler(hpcd);
+    (void)PCD_EP_ISR_Handler(hpcd);
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
   {
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->ResetCallback(hpcd);
+#else
     HAL_PCD_ResetCallback(hpcd);
-    HAL_PCD_SetAddress(hpcd, 0U);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+    (void)HAL_PCD_SetAddress(hpcd, 0U);
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
   {
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
   }
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
+
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
   {
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
   {
-    hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
-    hpcd->Instance->CNTR &= ~(USB_CNTR_FSUSP);
+    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE);
+    hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
 
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->ResumeCallback(hpcd);
+#else
     HAL_PCD_ResumeCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
   {
+    /* WA: To Clear Wakeup flag if raised with suspend signal */
+
+    /* Store Endpoint register */
+    for (i = 0U; i < 8U; i++)
+    {
+      store_ep[i] = PCD_GET_ENDPOINT(hpcd->Instance, i);
+    }
+
+    /* FORCE RESET */
+    hpcd->Instance->CNTR |= (uint16_t)(USB_CNTR_FRES);
+
+    /* CLEAR RESET */
+    hpcd->Instance->CNTR &= (uint16_t)(~USB_CNTR_FRES);
+
+    /* wait for reset flag in ISTR */
+    while ((hpcd->Instance->ISTR & USB_ISTR_RESET) == 0U)
+    {
+    }
+
+    /* Clear Reset Flag */
+    __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
+
+    /* Restore Registre */
+    for (i = 0U; i < 8U; i++)
+    {
+      PCD_SET_ENDPOINT(hpcd->Instance, i, store_ep[i]);
+    }
+
     /* Force low-power mode in the macrocell */
-    hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
+    hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
 
     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
 
-    hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
-    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
-    {
-      HAL_PCD_SuspendCallback(hpcd);
-    }
+    hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LP_MODE;
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->SuspendCallback(hpcd);
+#else
+    HAL_PCD_SuspendCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
   {
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->SOFCallback(hpcd);
+#else
     HAL_PCD_SOFCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
   }
 
-  if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
+  if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
   {
     /* clear ESOF flag in ISTR */
     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
   }
 }
-#endif /* USB */
+
+
+/**
+  * @brief  Handles PCD Wakeup interrupt request.
+  * @param  hpcd PCD handle
+  * @retval HAL status
+  */
+void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+  /* Clear EXTI pending Bit */
+  __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
+}
+#endif /* defined (USB) */
 
 /**
-  * @brief  Data out stage callbacks
-  * @param  hpcd: PCD handle
-  * @param  epnum: endpoint number
+  * @brief  Data OUT stage callback.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
   * @retval None
   */
- __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
   UNUSED(epnum);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_DataOutStageCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Data IN stage callbacks
-  * @param  hpcd: PCD handle
-  * @param  epnum: endpoint number
+  * @brief  Data IN stage callback
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
   * @retval None
   */
- __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
   UNUSED(epnum);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_DataInStageCallback could be implemented in the user file
    */
 }
 /**
   * @brief  Setup stage callback
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_SetupStageCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  USB Start Of Frame callbacks
-  * @param  hpcd: PCD handle
+  * @brief  USB Start Of Frame callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_SOFCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  USB Reset callbacks
-  * @param  hpcd: PCD handle
+  * @brief  USB Reset callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_ResetCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Suspend event callbacks
-  * @param  hpcd: PCD handle
+  * @brief  Suspend event callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_SuspendCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Resume event callbacks
-  * @param  hpcd: PCD handle
+  * @brief  Resume event callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_ResumeCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Incomplete ISO OUT callbacks
-  * @param  hpcd: PCD handle
-  * @param  epnum: endpoint number
+  * @brief  Incomplete ISO OUT callback.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
   * @retval None
   */
- __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
   UNUSED(epnum);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Incomplete ISO IN  callbacks
-  * @param  hpcd: PCD handle
-  * @param  epnum: endpoint number
+  * @brief  Incomplete ISO IN callback.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
   * @retval None
   */
- __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
   UNUSED(epnum);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Connection event callbacks
-  * @param  hpcd: PCD handle
+  * @brief  Connection event callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_ConnectCallback could be implemented in the user file
    */
 }
 
 /**
-  * @brief  Disconnection event callbacks
-  * @param  hpcd: PCD handle
+  * @brief  Disconnection event callback.
+  * @param  hpcd PCD handle
   * @retval None
   */
- __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(hpcd);
+
   /* NOTE : This function should not be modified, when the callback is needed,
             the HAL_PCD_DisconnectCallback could be implemented in the user file
    */
@@ -791,8 +1546,8 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
   */
 
 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
- *  @brief   management functions
- *
+  *  @brief   management functions
+  *
 @verbatim
  ===============================================================================
                       ##### Peripheral Control functions #####
@@ -807,127 +1562,161 @@ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
 
 /**
   * @brief  Connect the USB device
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
 {
   __HAL_LOCK(hpcd);
-  HAL_PCDEx_SetConnectionState (hpcd, 1);
-  USB_DevConnect(hpcd->Instance);
+
+#if defined (USB)
+  HAL_PCDEx_SetConnectionState(hpcd, 1U);
+#endif /* defined (USB) */
+
+  (void)USB_DevConnect(hpcd->Instance);
   __HAL_UNLOCK(hpcd);
+
   return HAL_OK;
 }
 
 /**
-  * @brief  Disconnect the USB device
-  * @param  hpcd: PCD handle
+  * @brief  Disconnect the USB device.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
 {
   __HAL_LOCK(hpcd);
-  HAL_PCDEx_SetConnectionState (hpcd, 0U);
-  USB_DevDisconnect(hpcd->Instance);
+
+#if defined (USB)
+  HAL_PCDEx_SetConnectionState(hpcd, 0U);
+#endif /* defined (USB) */
+
+  (void)USB_DevDisconnect(hpcd->Instance);
   __HAL_UNLOCK(hpcd);
+
   return HAL_OK;
 }
 
 /**
-  * @brief  Set the USB Device address
-  * @param  hpcd: PCD handle
-  * @param  address: new device address
+  * @brief  Set the USB Device address.
+  * @param  hpcd PCD handle
+  * @param  address new device address
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
 {
   __HAL_LOCK(hpcd);
   hpcd->USB_Address = address;
-  USB_SetDevAddress(hpcd->Instance, address);
+  (void)USB_SetDevAddress(hpcd->Instance, address);
   __HAL_UNLOCK(hpcd);
+
   return HAL_OK;
 }
 /**
-  * @brief  Open and configure an endpoint
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
-  * @param  ep_mps: endpoint max packet size
-  * @param  ep_type: endpoint type
+  * @brief  Open and configure an endpoint.
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
+  * @param  ep_mps endpoint max packet size
+  * @param  ep_type endpoint type
   * @retval HAL status
   */
-HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
+HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
+                                  uint16_t ep_mps, uint8_t ep_type)
 {
   HAL_StatusTypeDef  ret = HAL_OK;
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
 
   if ((ep_addr & 0x80U) == 0x80U)
   {
-    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 1U;
   }
   else
   {
-    ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 0U;
   }
+
+  ep->num = ep_addr & EP_ADDR_MSK;
   ep->maxpacket = ep_mps;
   ep->type = ep_type;
 
+  if (ep->is_in != 0U)
+  {
+    /* Assign a Tx FIFO */
+    ep->tx_fifo_num = ep->num;
+  }
+  /* Set initial data PID. */
+  if (ep_type == EP_TYPE_BULK)
+  {
+    ep->data_pid_start = 0U;
+  }
+
   __HAL_LOCK(hpcd);
-  USB_ActivateEndpoint(hpcd->Instance , ep);
+  (void)USB_ActivateEndpoint(hpcd->Instance, ep);
   __HAL_UNLOCK(hpcd);
+
   return ret;
 }
 
 /**
-  * @brief  Deactivate an endpoint
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
+  * @brief  Deactivate an endpoint.
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
 
   if ((ep_addr & 0x80U) == 0x80U)
   {
-    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 1U;
   }
   else
   {
-    ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 0U;
   }
+  ep->num   = ep_addr & EP_ADDR_MSK;
 
   __HAL_LOCK(hpcd);
-  USB_DeactivateEndpoint(hpcd->Instance , ep);
+  (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
   __HAL_UNLOCK(hpcd);
   return HAL_OK;
 }
 
+
 /**
-  * @brief  Receive an amount of data
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
-  * @param  pBuf: pointer to the reception buffer
-  * @param  len: amount of data to be received
+  * @brief  Receive an amount of data.
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
+  * @param  pBuf pointer to the reception buffer
+  * @param  len amount of data to be received
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
 
-  ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+  ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
 
   /*setup and start the Xfer */
   ep->xfer_buff = pBuf;
   ep->xfer_len = len;
   ep->xfer_count = 0U;
+  ep->is_in = 0U;
+  ep->num = ep_addr & EP_ADDR_MSK;
 
-  if ((ep_addr & 0x7FU) == 0U)
+  if ((ep_addr & EP_ADDR_MSK) == 0U)
   {
-    USB_EP0StartXfer(hpcd->Instance , ep);
+    (void)USB_EP0StartXfer(hpcd->Instance, ep);
   }
   else
   {
-    HAL_PCD_EP_ReceiveData(hpcd, ep);
+    (void)USB_EPStartXfer(hpcd->Instance, ep);
   }
 
   return HAL_OK;
@@ -935,40 +1724,46 @@ HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, u
 
 /**
   * @brief  Get Received Data Size
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
   * @retval Data Size
   */
-uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 {
-  return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
+  return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
 }
 /**
   * @brief  Send an amount of data
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
-  * @param  pBuf: pointer to the transmission buffer
-  * @param  len: amount of data to be sent
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
+  * @param  pBuf pointer to the transmission buffer
+  * @param  len amount of data to be sent
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
 
-  ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+  ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
 
   /*setup and start the Xfer */
   ep->xfer_buff = pBuf;
   ep->xfer_len = len;
+#if defined (USB)
+  ep->xfer_fill_db = 1U;
+  ep->xfer_len_db = len;
+#endif /* defined (USB) */
   ep->xfer_count = 0U;
+  ep->is_in = 1U;
+  ep->num = ep_addr & EP_ADDR_MSK;
 
-  if ((ep_addr & 0x7FU) == 0U)
+  if ((ep_addr & EP_ADDR_MSK) == 0U)
   {
-    USB_EP0StartXfer(hpcd->Instance , ep);
+    (void)USB_EP0StartXfer(hpcd->Instance, ep);
   }
   else
   {
-    USB_EPStartXfer(hpcd->Instance , ep);
+    (void)USB_EPStartXfer(hpcd->Instance, ep);
   }
 
   return HAL_OK;
@@ -976,31 +1771,42 @@ HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
 
 /**
   * @brief  Set a STALL condition over an endpoint
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
+
+  if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
+  {
+    return HAL_ERROR;
+  }
 
   if ((0x80U & ep_addr) == 0x80U)
   {
-    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 1U;
   }
   else
   {
     ep = &hpcd->OUT_ep[ep_addr];
+    ep->is_in = 0U;
   }
 
   ep->is_stall = 1U;
+  ep->num = ep_addr & EP_ADDR_MSK;
 
   __HAL_LOCK(hpcd);
-  USB_EPSetStall(hpcd->Instance , ep);
-  if((ep_addr & 0x7FU) == 0U)
+
+  (void)USB_EPSetStall(hpcd->Instance, ep);
+
+  if ((ep_addr & EP_ADDR_MSK) == 0U)
   {
-    USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+    (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
   }
+
   __HAL_UNLOCK(hpcd);
 
   return HAL_OK;
@@ -1008,27 +1814,35 @@ HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 
 /**
   * @brief  Clear a STALL condition over in an endpoint
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
+
+  if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
+  {
+    return HAL_ERROR;
+  }
 
   if ((0x80U & ep_addr) == 0x80U)
   {
-    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 1U;
   }
   else
   {
-    ep = &hpcd->OUT_ep[ep_addr];
+    ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
+    ep->is_in = 0U;
   }
 
   ep->is_stall = 0U;
+  ep->num = ep_addr & EP_ADDR_MSK;
 
   __HAL_LOCK(hpcd);
-  USB_EPClearStall(hpcd->Instance , ep);
+  (void)USB_EPClearStall(hpcd->Instance, ep);
   __HAL_UNLOCK(hpcd);
 
   return HAL_OK;
@@ -1036,8 +1850,8 @@ HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 
 /**
   * @brief  Flush an endpoint
-  * @param  hpcd: PCD handle
-  * @param  ep_addr: endpoint address
+  * @param  hpcd PCD handle
+  * @param  ep_addr endpoint address
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
@@ -1046,11 +1860,11 @@ HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 
   if ((ep_addr & 0x80U) == 0x80U)
   {
-    USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7FU);
+    (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
   }
   else
   {
-    USB_FlushRxFifo(hpcd->Instance);
+    (void)USB_FlushRxFifo(hpcd->Instance);
   }
 
   __HAL_UNLOCK(hpcd);
@@ -1059,31 +1873,32 @@ HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
 }
 
 /**
-  * @brief  HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
-  * @param  hpcd: PCD handle
+  * @brief  Activate remote wakeup signalling
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
 {
-  return(USB_ActivateRemoteWakeup(hpcd->Instance));
+  return (USB_ActivateRemoteWakeup(hpcd->Instance));
 }
 
 /**
-  * @brief  HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
-  * @param  hpcd: PCD handle
+  * @brief  De-activate remote wakeup signalling.
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
 {
-  return(USB_DeActivateRemoteWakeup(hpcd->Instance));
+  return (USB_DeActivateRemoteWakeup(hpcd->Instance));
 }
+
 /**
   * @}
   */
 
 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
- *  @brief   Peripheral State functions
- *
+  *  @brief   Peripheral State functions
+  *
 @verbatim
  ===============================================================================
                       ##### Peripheral State functions #####
@@ -1097,8 +1912,8 @@ HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
   */
 
 /**
-  * @brief  Return the PCD state
-  * @param  hpcd: PCD handle
+  * @brief  Return the PCD handle state.
+  * @param  hpcd PCD handle
   * @retval HAL state
   */
 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
@@ -1114,27 +1929,33 @@ PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
   * @}
   */
 
+/* Private functions ---------------------------------------------------------*/
 /** @addtogroup PCD_Private_Functions
   * @{
   */
 #if defined (USB_OTG_FS)
 /**
-  * @brief  DCD_WriteEmptyTxFifo
-  *         check FIFO for the next packet to be loaded
-  * @param  hpcd: PCD handle
-  * @param  epnum : endpoint number
-  *          This parameter can be a value from 0 to 15
+  * @brief  Check FIFO for the next packet to be loaded.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
   * @retval HAL status
   */
 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
 {
   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
-  USB_OTG_EPTypeDef *ep = NULL;
-  int32_t len = 0;
-  uint32_t len32b = 0U;
-  uint32_t fifoemptymsk = 0U;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  USB_OTG_EPTypeDef *ep;
+  uint32_t len;
+  uint32_t len32b;
+  uint32_t fifoemptymsk;
 
   ep = &hpcd->IN_ep[epnum];
+
+  if (ep->xfer_count > ep->xfer_len)
+  {
+    return HAL_ERROR;
+  }
+
   len = ep->xfer_len - ep->xfer_count;
 
   if (len > ep->maxpacket)
@@ -1144,74 +1965,142 @@ static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t
 
   len32b = (len + 3U) / 4U;
 
-  while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
-         ep->xfer_count < ep->xfer_len &&
-         ep->xfer_len != 0U)
+  while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
+         (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
   {
     /* Write the FIFO */
     len = ep->xfer_len - ep->xfer_count;
 
-    if ((uint32_t)len > ep->maxpacket)
+    if (len > ep->maxpacket)
     {
       len = ep->maxpacket;
     }
     len32b = (len + 3U) / 4U;
 
-    USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
+    (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
 
     ep->xfer_buff  += len;
     ep->xfer_count += len;
   }
 
-  if(len <= 0)
+  if (ep->xfer_len <= ep->xfer_count)
   {
-    fifoemptymsk = 0x01U << epnum;
+    fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
-
   }
 
   return HAL_OK;
 }
 
-HAL_StatusTypeDef HAL_PCD_EP_ReceiveData(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef* ep)
+
+/**
+  * @brief  process EP OUT transfer complete interrupt.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
 {
-  USB_EPStartXfer(hpcd->Instance, ep);
+  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
+  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
+
+  if (gSNPSiD == USB_OTG_CORE_ID_310A)
+  {
+    /* StupPktRcvd = 1 this is a setup packet */
+    if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
+    {
+      CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
+    }
+    else
+    {
+      if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
+      {
+        CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
+      }
+
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
+#else
+      HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+    }
+  }
+  else
+  {
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+    hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
+#else
+    HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+  }
+
+  return HAL_OK;
 }
 
-#endif /* USB_OTG_FS */
+
+/**
+  * @brief  process EP OUT setup packet received interrupt.
+  * @param  hpcd PCD handle
+  * @param  epnum endpoint number
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
+{
+  USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
+  uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
+
+  if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
+      ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
+  {
+    CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
+  }
+
+  /* Inform the upper layer that a setup packet is available */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+  hpcd->SetupStageCallback(hpcd);
+#else
+  HAL_PCD_SetupStageCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+  return HAL_OK;
+}
+#endif /* defined (USB_OTG_FS) */
 
 #if defined (USB)
 /**
   * @brief  This function handles PCD Endpoint interrupt request.
-  * @param  hpcd: PCD handle
+  * @param  hpcd PCD handle
   * @retval HAL status
   */
 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
 {
-  PCD_EPTypeDef *ep = NULL;
-  uint16_t count = 0;
-  uint16_t pmaBuffer = 0;
-  uint8_t epindex = 0;
-  __IO uint16_t wIstr = 0;
-  __IO uint16_t wEPVal = 0;
+  PCD_EPTypeDef *ep;
+  uint16_t count, wIstr, wEPVal, TxByteNbre;
+  uint8_t epindex;
 
   /* stay in loop while pending interrupts */
-  while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
+  while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
   {
+    wIstr = hpcd->Instance->ISTR;
+
     /* extract highest priority endpoint number */
     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
 
-    if (epindex == 0)
+    if (epindex == 0U)
     {
       /* Decode and service control endpoint interrupt */
 
       /* DIR bit = origin of the interrupt */
-      if ((wIstr & USB_ISTR_DIR) == 0)
+      if ((wIstr & USB_ISTR_DIR) == 0U)
       {
         /* DIR = 0 */
 
-        /* DIR = 0      => IN  int */
-        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
+        /* DIR = 0 => IN  int */
+        /* DIR = 0 implies that (EP_CTR_TX = 1) always */
         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
         ep = &hpcd->IN_ep[0];
 
@@ -1219,12 +2108,15 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
         ep->xfer_buff += ep->xfer_count;
 
         /* TX COMPLETE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+        hpcd->DataInStageCallback(hpcd, 0U);
+#else
         HAL_PCD_DataInStageCallback(hpcd, 0U);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 
-
-        if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
+        if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
         {
-          hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
+          hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
           hpcd->USB_Address = 0U;
         }
       }
@@ -1232,37 +2124,50 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
       {
         /* DIR = 1 */
 
-        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
+        /* DIR = 1 & CTR_RX => SETUP or OUT int */
         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
-        ep = &hpcd->OUT_ep[0U];
+        ep = &hpcd->OUT_ep[0];
         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
 
         if ((wEPVal & USB_EP_SETUP) != 0U)
         {
-          /* Get SETUP Packet*/
+          /* Get SETUP Packet */
           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
-          USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
-          /* SETUP bit kept frozen while CTR_RX = 1*/
+
+          USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
+                      ep->pmaadress, (uint16_t)ep->xfer_count);
+
+          /* SETUP bit kept frozen while CTR_RX = 1 */
           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
 
           /* Process SETUP Packet*/
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+          hpcd->SetupStageCallback(hpcd);
+#else
           HAL_PCD_SetupStageCallback(hpcd);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
         }
-
         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
         {
           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
-          /* Get Control Data OUT Packet*/
+
+          /* Get Control Data OUT Packet */
           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
 
-          if (ep->xfer_count != 0U)
+          if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
           {
-            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
-            ep->xfer_buff+=ep->xfer_count;
-          }
+            USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
+                        ep->pmaadress, (uint16_t)ep->xfer_count);
+
+            ep->xfer_buff += ep->xfer_count;
 
-          /* Process Control Data OUT Packet*/
-          HAL_PCD_DataOutStageCallback(hpcd, 0U);
+            /* Process Control Data OUT Packet */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+            hpcd->DataOutStageCallback(hpcd, 0U);
+#else
+            HAL_PCD_DataOutStageCallback(hpcd, 0U);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+          }
 
           PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
           PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
@@ -1271,129 +2176,79 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
     }
     else
     {
-      /* Decode and service non control endpoints interrupt  */
-
-      /*
-       * SW - DTOG_TX in USB_EPnR register (it act as SW_BUF for dbl buf OUT ep)
-       * P0 - if ep->pending0 have non-zero value
-       * P1 - if ep->pending1 have non-zero value
-       *
-       * We can get one of following variants here:
-       * SW P1 P0
-       *  0  0  0 - read buffer 0. ^SW when have buffer, +P0 otherwise
-       *  0  1  0 - same, but interrupt happens in danger zone. As before, -P1
-       *  1  1  0 - unprocessed buffer in queue - do nothing and +P0
-       *  1  1  1 - same, but interrupt happens in danger zone. As before
-       *
-       *  1  0  0 - read buffer 1. ^SW when have buffer, +P1 otherwise
-       *  1  0  1 - same, but interrupt happens in danger zone. As before, -P0
-       *  0  0  1 - unprocessed buffer in queue - do nothing and +P1
-       *  0  1  1 - same, but interrupt happens in danger zone. As before
-       *
-       * Variant tables:
-       *
-       * buffer selection   Buffer 1 abort     Buffer 0 abort     Clear pending
-       * TX  /P1/P0 \       TX  /P1/P0 \       TX  /P1/P0 \       TX  /P1/P0 \
-       * |  /        \      |  /        \      |  /        \      |  /        \
-       * | 00 01 11 10      | 00 01 11 10      | 00 01 11 10      | 00 01 11 10
-       * 0: 0  1  1  0      0: x  A  A  x      0: -  x  x  -      0: .  x  x  N
-       * 1: 1  1  0  0      1: -  -  x  x      1: x  x  A  A      1: .  Z  x  x
-       *
-       * legend:
-       * 0: must read buffer 0
-       * 1: must read buffer 1
-       * x: impossible to get here
-       * A: abort read, wait for main thread, and set other buffer to pended
-       * -: does not abort, this is regular read
-       * N: must clear pending oNe (in case of IRQ asserting in danger zone)
-       * Z: must clear pending Zero (in case of IRQ asserting in danger zone)
-       * .: pending clearing can be performed, because it's already clear
-       *
-       * resulting logic expressions
-       * 1: SW ? !P1 : P0     A1: !SW   N: !SW
-       * 0: SW ? P1 : !P0     A0: SW    Z: SW
-       *
-       * SW ? !P1 : P0 - test to determine, then buffer 1 used.
-       * if this case, SW determine regular read, or !SW, that we must abort IRQ
-       * in other case, !SW determine regular read, SW - abort IRQ
-       * if IRQ asserted in danger zone, two cases require extra pending clear
-       * with 1 0 1, clearing P0, with 0 1 0 - clear P1
-       * but, many other cases aborted before, and clear something, that already
-       * empty - is do nothing - so clear P1, then !SW, and P0 then SW
-       *
-       * Danger zone - is time after PCD_FreeUserBuffer and before
-       * ep->pendingX = 0 in HAL_PCD_EP_ReceiveData
-       */
-
+      /* Decode and service non control endpoints interrupt */
       /* process related endpoint register */
       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
+
       if ((wEPVal & USB_EP_CTR_RX) != 0U)
       {
         /* clear int flag */
         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
         ep = &hpcd->OUT_ep[epindex];
 
-        /* OUT double Buffering*/
+        /* OUT Single Buffering */
         if (ep->doublebuffer == 0U)
         {
-          count     = (uint16_t) PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
-          pmaBuffer = ep->pmaadress;
-        }
-        else if (PCD_OUT_SW(wEPVal) ? ep->pending1 == 0 : ep->pending0 != 0)
-        {
-          count     = (uint16_t) PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
-          pmaBuffer = ep->pmaaddr1;
-          if (ep->xfer_len == 0 || ep->xfer_buff == 0 || !PCD_OUT_SW(wEPVal))
+          count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+
+          if (count != 0U)
           {
-            ep->pending1 = (uint16_t) (count == 0 ? PCD_PENDED_ZLP : count);
-            return HAL_OK;
+            USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
           }
-          ep->pending0 = 0;
         }
         else
         {
-          count     = (uint16_t) PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
-          pmaBuffer = ep->pmaaddr0;
-          if (ep->xfer_len == 0 || ep->xfer_buff == 0 || PCD_OUT_SW(wEPVal))
+          /* manage double buffer bulk out */
+          if (ep->type == EP_TYPE_BULK)
           {
-            ep->pending0 = (uint16_t) (count == 0 ? PCD_PENDED_ZLP : count);
-            return HAL_OK;
+            count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
           }
-          ep->pending1 = 0;
-        }
-
-        if (count != 0U)
-        {
-          /* buffer doesn't contains enough space, stall and error */
-          if (count > ep->xfer_len)
+          else /* manage double buffer iso out */
           {
-            USB_EPSetStall(hpcd->Instance, ep);
-            return HAL_ERROR;
+            /* free EP OUT Buffer */
+            PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
+
+            if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
+            {
+              /* read from endpoint BUF0Addr buffer */
+              count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+
+              if (count != 0U)
+              {
+                USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
+              }
+            }
+            else
+            {
+              /* read from endpoint BUF1Addr buffer */
+              count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+
+              if (count != 0U)
+              {
+                USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
+              }
+            }
           }
-          USB_ReadPMA(hpcd->Instance, ep->xfer_buff, pmaBuffer, count);
-        }
-
-        if (ep->doublebuffer != 0U)
-        {
-          PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
         }
-
-        /*multi-packet on the NON control OUT endpoint*/
-        ep->xfer_count+=count;
-        ep->xfer_buff+=count;
-        ep->xfer_len-=count;
+        /* multi-packet on the NON control OUT endpoint */
+        ep->xfer_count += count;
+        ep->xfer_buff += count;
 
         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
         {
           /* RX COMPLETE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+          hpcd->DataOutStageCallback(hpcd, ep->num);
+#else
           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
         }
-        else if (ep->doublebuffer == 0U)
+        else
         {
-          PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID);
+          (void) USB_EPStartXfer(hpcd->Instance, ep);
         }
 
-      } /* if((wEPVal & EP_CTR_RX) */
+      }
 
       if ((wEPVal & USB_EP_CTR_TX) != 0U)
       {
@@ -1402,155 +2257,306 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
         /* clear int flag */
         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
 
-        /* IN double Buffering*/
-        if (ep->doublebuffer == 0U)
-        {
-          ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
-        }
-        else
+        /* Manage all non bulk transaction or Bulk Single Buffer Transaction */
+        if ((ep->type != EP_TYPE_BULK) ||
+            ((ep->type == EP_TYPE_BULK) && ((wEPVal & USB_EP_KIND) == 0U)))
         {
-          if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
+          /* multi-packet on the NON control IN endpoint */
+          TxByteNbre = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+
+          if (ep->xfer_len > TxByteNbre)
           {
-            /*read from endpoint BUF0Addr buffer*/
-            ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+            ep->xfer_len -= TxByteNbre;
           }
           else
           {
-            /*read from endpoint BUF1Addr buffer*/
-            ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+            ep->xfer_len = 0U;
           }
-          PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);
-        }
-        /*multi-packet on the NON control IN endpoint*/
-        ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
-        ep->xfer_buff+=ep->xfer_count;
 
-        /* Zero Length Packet? */
-        if (ep->xfer_len == 0U)
-        {
-          /* TX COMPLETE */
-          HAL_PCD_DataInStageCallback(hpcd, ep->num);
+          /* Zero Length Packet? */
+          if (ep->xfer_len == 0U)
+          {
+            /* TX COMPLETE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+            hpcd->DataInStageCallback(hpcd, ep->num);
+#else
+            HAL_PCD_DataInStageCallback(hpcd, ep->num);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+          }
+          else
+          {
+            /* Transfer is not yet Done */
+            ep->xfer_buff += TxByteNbre;
+            ep->xfer_count += TxByteNbre;
+            (void)USB_EPStartXfer(hpcd->Instance, ep);
+          }
         }
+        /* bulk in double buffer enable in case of transferLen> Ep_Mps */
         else
         {
-          HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
+          (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
         }
       }
     }
   }
+
   return HAL_OK;
 }
 
-HAL_StatusTypeDef HAL_PCD_EP_ReceiveData(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef* ep)
+
+/**
+  * @brief  Manage double buffer bulk out transaction from ISR
+  * @param  hpcd PCD handle
+  * @param  ep current endpoint handle
+  * @param  wEPVal Last snapshot of EPRx register value taken in ISR
+  * @retval HAL status
+  */
+static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
+                                      PCD_EPTypeDef *ep, uint16_t wEPVal)
 {
   uint16_t count;
-  uint16_t pmaBuffer;
-  volatile uint16_t wEPVal;
-  volatile uint16_t tmpVal;
-  volatile uint16_t *pCount;
 
-  wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, ep->num);
-  count = (wEPVal & USB_EP_DTOG_TX) ? ep->pending1 : ep->pending0;
-  while (count != 0 && count != PCD_PENDED_PROCESSED)
+  /* Manage Buffer0 OUT */
+  if ((wEPVal & USB_EP_DTOG_RX) != 0U)
   {
-    if (ep->xfer_buff == 0 || ep->xfer_len == 0)
+    /* Get count of received Data on buffer0 */
+    count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+
+    if (ep->xfer_len >= count)
     {
-      return HAL_OK;
+      ep->xfer_len -= count;
+    }
+    else
+    {
+      ep->xfer_len = 0U;
     }
 
-    if (PCD_OUT_SW(wEPVal))
+    if (ep->xfer_len == 0U)
     {
-      ep->pending1 = PCD_PENDED_PROCESSED;
-      pmaBuffer = ep->pmaaddr1;
+      /* set NAK to OUT endpoint since double buffer is enabled */
+      PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
     }
-    else
+
+    /* Check if Buffer1 is in blocked sate which requires to toggle */
+    if ((wEPVal & USB_EP_DTOG_TX) != 0U)
+    {
+      PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
+    }
+
+    if (count != 0U)
     {
-      ep->pending0 = PCD_PENDED_PROCESSED;
-      pmaBuffer = ep->pmaaddr0;
+      USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
     }
+  }
+  /* Manage Buffer 1 DTOG_RX=0 */
+  else
+  {
+    /* Get count of received data */
+    count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
 
-    if (count == PCD_PENDED_ZLP)
+    if (ep->xfer_len >= count)
     {
-      count = 0;
+      ep->xfer_len -= count;
     }
-    else if (count > ep->xfer_len)
+    else
     {
-      /* buffer doesn't contains enough space, stall and error */
-      USB_EPSetStall(hpcd->Instance, ep);
-      return HAL_ERROR;
+      ep->xfer_len = 0U;
     }
 
-    USB_ReadPMA(hpcd->Instance, ep->xfer_buff, pmaBuffer, count);
+    if (ep->xfer_len == 0U)
+    {
+      /* set NAK on the current endpoint */
+      PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
+    }
 
-    /*multi-packet on the NON control OUT endpoint*/
-    ep->xfer_count += count;
-    ep->xfer_buff += count;
-    ep->xfer_len -= count;
+    /*Need to FreeUser Buffer*/
+    if ((wEPVal & USB_EP_DTOG_TX) == 0U)
+    {
+      PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
+    }
 
-    if (ep->xfer_len == 0U || count < ep->maxpacket)
+    if (count != 0U)
     {
-      /* RX COMPLETE */
-      HAL_PCD_DataOutStageCallback(hpcd, ep->num);
+      USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
     }
+  }
+
+  return count;
+}
+
+
+/**
+  * @brief  Manage double buffer bulk IN transaction from ISR
+  * @param  hpcd PCD handle
+  * @param  ep current endpoint handle
+  * @param  wEPVal Last snapshot of EPRx register value taken in ISR
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
+                                                PCD_EPTypeDef *ep, uint16_t wEPVal)
+{
+  uint32_t len;
+  uint16_t TxByteNbre;
 
-    /*
-     * ENTER DANGER ZONE
-     * Yes, disable interrupts can be used (or CTRM in USB_CNTR can be cleared)
-     * but it's not good. We can rule concurrency (or just simple determine, if
-     * interrupt asserted in danger zone or not)
-     */
-    PCD_FreeUserBuffer(hpcd->Instance, ep->num, ep->is_in);
+  /* Data Buffer0 ACK received */
+  if ((wEPVal & USB_EP_DTOG_TX) != 0U)
+  {
+    /* multi-packet on the NON control IN endpoint */
+    TxByteNbre = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
 
-    if (PCD_OUT_SW(wEPVal))
+    if (ep->xfer_len > TxByteNbre)
     {
-      pCount = &ep->pending1;
+      ep->xfer_len -= TxByteNbre;
     }
     else
     {
-      pCount = &ep->pending0;
+      ep->xfer_len = 0U;
     }
-
-    do
+    /* Transfer is completed */
+    if (ep->xfer_len == 0U)
     {
-      /*
-       * ep->pendingX can be changed in some cases in the IRQ handler.
-       * under these cases, new value must be used, clearing must be skipped.
-       */
-      tmpVal = __LDREXH(pCount);
+      /* TX COMPLETE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->DataInStageCallback(hpcd, ep->num);
+#else
+      HAL_PCD_DataInStageCallback(hpcd, ep->num);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+      if ((wEPVal & USB_EP_DTOG_RX) != 0U)
+      {
+        PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
+      }
     }
-    while (tmpVal == PCD_PENDED_PROCESSED &&  __STREXH(0, pCount));
-    /*
-     * EXIT DANGER ZONE
-     */
+    else /* Transfer is not yet Done */
+    {
+      /* need to Free USB Buff */
+      if ((wEPVal & USB_EP_DTOG_RX) != 0U)
+      {
+        PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
+      }
 
-    wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, ep->num);
-    count = (wEPVal & USB_EP_DTOG_TX) ? ep->pending1 : ep->pending0;
+      /* Still there is data to Fill in the next Buffer */
+      if (ep->xfer_fill_db == 1U)
+      {
+        ep->xfer_buff += TxByteNbre;
+        ep->xfer_count += TxByteNbre;
+
+        /* Calculate the len of the new buffer to fill */
+        if (ep->xfer_len_db >= ep->maxpacket)
+        {
+          len = ep->maxpacket;
+          ep->xfer_len_db -= len;
+        }
+        else if (ep->xfer_len_db == 0U)
+        {
+          len = TxByteNbre;
+          ep->xfer_fill_db = 0U;
+        }
+        else
+        {
+          ep->xfer_fill_db = 0U;
+          len = ep->xfer_len_db;
+          ep->xfer_len_db = 0U;
+        }
+
+        /* Write remaining Data to Buffer */
+        /* Set the Double buffer counter for pma buffer1 */
+        PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
+
+        /* Copy user buffer to USB PMA */
+        USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr0, (uint16_t)len);
+      }
+    }
   }
-  if (ep->doublebuffer == 0 && ep->xfer_buff != 0 && ep->xfer_len != 0)
+  else /* Data Buffer1 ACK received */
   {
-    PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID);
+    /* multi-packet on the NON control IN endpoint */
+    TxByteNbre = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+
+    if (ep->xfer_len >= TxByteNbre)
+    {
+      ep->xfer_len -= TxByteNbre;
+    }
+    else
+    {
+      ep->xfer_len = 0U;
+    }
+
+    /* Transfer is completed */
+    if (ep->xfer_len == 0U)
+    {
+      /* TX COMPLETE */
+#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+      hpcd->DataInStageCallback(hpcd, ep->num);
+#else
+      HAL_PCD_DataInStageCallback(hpcd, ep->num);
+#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+
+      /*need to Free USB Buff*/
+      if ((wEPVal & USB_EP_DTOG_RX) == 0U)
+      {
+        PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
+      }
+    }
+    else /* Transfer is not yet Done */
+    {
+      /* need to Free USB Buff */
+      if ((wEPVal & USB_EP_DTOG_RX) == 0U)
+      {
+        PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
+      }
+
+      /* Still there is data to Fill in the next Buffer */
+      if (ep->xfer_fill_db == 1U)
+      {
+        ep->xfer_buff += TxByteNbre;
+        ep->xfer_count += TxByteNbre;
+
+        /* Calculate the len of the new buffer to fill */
+        if (ep->xfer_len_db >= ep->maxpacket)
+        {
+          len = ep->maxpacket;
+          ep->xfer_len_db -= len;
+        }
+        else if (ep->xfer_len_db == 0U)
+        {
+          len = TxByteNbre;
+          ep->xfer_fill_db = 0U;
+        }
+        else
+        {
+          len = ep->xfer_len_db;
+          ep->xfer_len_db = 0U;
+          ep->xfer_fill_db = 0;
+        }
+
+        /* Set the Double buffer counter for pmabuffer1 */
+        PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
+
+        /* Copy the user buffer to USB PMA */
+        USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr1, (uint16_t)len);
+      }
+    }
   }
+
+  /*enable endpoint IN*/
+  PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
+
   return HAL_OK;
 }
 
-#endif /* USB */
+#endif /* defined (USB) */
 
 /**
   * @}
   */
+#endif /* defined (USB) || defined (USB_OTG_FS) */
+#endif /* HAL_PCD_MODULE_ENABLED */
 
 /**
   * @}
   */
 
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
-
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-
 /**
   * @}
   */
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
index 0ef163a7fc..42e135c74b 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
@@ -28,26 +28,21 @@
   * @{
   */
 
-#ifdef HAL_PCD_MODULE_ENABLED
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
-
 /** @defgroup PCDEx PCDEx
   * @brief PCD Extended HAL module driver
   * @{
   */
 
+#ifdef HAL_PCD_MODULE_ENABLED
 
+#if defined (USB) || defined (USB_OTG_FS)
 /* Private types -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
 /* Private constants ---------------------------------------------------------*/
 /* Private macros ------------------------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 /* Exported functions --------------------------------------------------------*/
+
 /** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
   * @{
   */
@@ -57,28 +52,26 @@
   *
 @verbatim
  ===============================================================================
-              ##### Extended Peripheral Control functions #####
+                 ##### Extended features functions #####
  ===============================================================================
     [..]  This section provides functions allowing to:
-      (+) Update FIFO (USB_OTG_FS)
-      (+) Update PMA configuration (USB)
+      (+) Update FIFO configuration
 
 @endverbatim
   * @{
   */
-
 #if defined (USB_OTG_FS)
 /**
   * @brief  Set Tx FIFO
-  * @param  hpcd: PCD handle
-  * @param  fifo: The number of Tx fifo
-  * @param  size: Fifo size
+  * @param  hpcd PCD handle
+  * @param  fifo The number of Tx fifo
+  * @param  size Fifo size
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
 {
-  uint8_t index = 0;
-  uint32_t Tx_Offset = 0U;
+  uint8_t i;
+  uint32_t Tx_Offset;
 
   /*  TXn min size = 16 words. (n  : Transmit FIFO index)
       When a TxFIFO is not used, the Configuration should be as follows:
@@ -92,21 +85,20 @@ HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uin
 
   Tx_Offset = hpcd->Instance->GRXFSIZ;
 
-  if(fifo == 0U)
+  if (fifo == 0U)
   {
-    hpcd->Instance->DIEPTXF0_HNPTXFSIZ = (size << 16U) | Tx_Offset;
+    hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset;
   }
   else
   {
-    Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16U;
-    for(index = 0; index < (fifo - 1); index++)
+    Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16;
+    for (i = 0U; i < (fifo - 1U); i++)
     {
-      Tx_Offset += (hpcd->Instance->DIEPTXF[index] >> 16U);
+      Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16);
     }
 
     /* Multiply Tx_Size by 2 to get higher performance */
-    hpcd->Instance->DIEPTXF[fifo - 1U] = (size << 16U) | Tx_Offset;
-
+    hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
   }
 
   return HAL_OK;
@@ -114,23 +106,23 @@ HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uin
 
 /**
   * @brief  Set Rx FIFO
-  * @param  hpcd: PCD handle
-  * @param  size: Size of Rx fifo
+  * @param  hpcd PCD handle
+  * @param  size Size of Rx fifo
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
 {
   hpcd->Instance->GRXFSIZ = size;
+
   return HAL_OK;
 }
-#endif /* USB_OTG_FS */
-
+#endif /* defined (USB_OTG_FS) */
 #if defined (USB)
 /**
   * @brief  Configure PMA for EP
-  * @param  hpcd : Device instance
-  * @param  ep_addr: endpoint address
-  * @param  ep_kind: endpoint Kind
+  * @param  hpcd  Device instance
+  * @param  ep_addr endpoint address
+  * @param  ep_kind endpoint Kind
   *                  USB_SNG_BUF: Single Buffer used
   *                  USB_DBL_BUF: Double Buffer used
   * @param  pmaadress: EP address in The PMA: In case of single buffer endpoint
@@ -143,18 +135,15 @@ HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
   * @retval HAL status
   */
 
-HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
-                                       uint16_t ep_addr,
-                                       uint16_t ep_kind,
-                                       uint32_t pmaadress)
-
+HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
+                                       uint16_t ep_kind, uint32_t pmaadress)
 {
-  PCD_EPTypeDef *ep = NULL;
+  PCD_EPTypeDef *ep;
 
   /* initialize ep structure*/
-  if ((ep_addr & 0x80U) == 0x80U)
+  if ((0x80U & ep_addr) == 0x80U)
   {
-    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+    ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
   }
   else
   {
@@ -164,37 +153,29 @@ HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
   /* Here we check if the endpoint is single or double Buffer*/
   if (ep_kind == PCD_SNG_BUF)
   {
-    /*Single Buffer*/
+    /* Single Buffer */
     ep->doublebuffer = 0U;
-    /*Configure te PMA*/
+    /* Configure the PMA */
     ep->pmaadress = (uint16_t)pmaadress;
   }
-  else /*USB_DBL_BUF*/
+  else /* USB_DBL_BUF */
   {
-    /*Double Buffer Endpoint*/
+    /* Double Buffer Endpoint */
     ep->doublebuffer = 1U;
-    /*Configure the PMA*/
-    ep->pmaaddr0 =  pmaadress & 0x0000FFFFU;
-    ep->pmaaddr1 =  (pmaadress & 0xFFFF0000U) >> 16U;
+    /* Configure the PMA */
+    ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
+    ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
   }
 
   return HAL_OK;
 }
-#endif /* USB */
-/**
-  * @}
-  */
 
-/** @defgroup PCDEx_Exported_Functions_Group2 Peripheral State functions
-  * @brief    Manage device connection state
-  * @{
-  */
 /**
   * @brief  Software Device Connection,
   *         this function is not required by USB OTG FS peripheral, it is used
   *         only by USB Device FS peripheral.
-  * @param  hpcd: PCD handle
-  * @param  state: connection state (0 : disconnected / 1: connected)
+  * @param  hpcd PCD handle
+  * @param  state connection state (0 : disconnected / 1: connected)
   * @retval None
   */
 __weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
@@ -206,9 +187,41 @@ __weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
             the HAL_PCDEx_SetConnectionState could be implemented in the user file
    */
 }
+#endif /* defined (USB) */
+
 /**
-  * @}
+  * @brief  Send LPM message to user layer callback.
+  * @param  hpcd PCD handle
+  * @param  msg LPM message
+  * @retval HAL status
+  */
+__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hpcd);
+  UNUSED(msg);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_PCDEx_LPM_Callback could be implemented in the user file
+   */
+}
+
+/**
+  * @brief  Send BatteryCharging message to user layer callback.
+  * @param  hpcd PCD handle
+  * @param  msg LPM message
+  * @retval HAL status
   */
+__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hpcd);
+  UNUSED(msg);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_PCDEx_BCD_Callback could be implemented in the user file
+   */
+}
 
 /**
   * @}
@@ -217,14 +230,12 @@ __weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
 /**
   * @}
   */
-
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
-
+#endif /* defined (USB) || defined (USB_OTG_FS) */
 #endif /* HAL_PCD_MODULE_ENABLED */
 
+/**
+  * @}
+  */
 
 /**
   * @}
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
index f4800626b2..29a0224bb5 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
@@ -89,6 +89,7 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
 
   RCC_OscInitTypeDef        RCC_OscInitStruct;
   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
+  HAL_StatusTypeDef         status;
 
 #ifdef RTC_CLOCK_SOURCE_LSE
   /* Configue LSE as RTC clock soucre */
@@ -111,76 +112,94 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
 #else
 #error Please select the RTC Clock source
 #endif /* RTC_CLOCK_SOURCE_LSE */
-
-  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
+  status = HAL_RCC_OscConfig(&RCC_OscInitStruct);
+  if (status == HAL_OK)
   {
     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
-    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK)
+    status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+    if (status == HAL_OK)
     {
       /* Enable RTC Clock */
       __HAL_RCC_RTC_ENABLE();
 
-      hRTC_Handle.Instance = RTC;
       /* Configure RTC time base to 10Khz */
+      hRTC_Handle.Instance = RTC;
       hRTC_Handle.Init.AsynchPrediv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC) / 10000) - 1;
       hRTC_Handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
-      HAL_RTC_Init(&hRTC_Handle);
-
-      /* Disable the write protection for RTC registers */
-      __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
+      status = HAL_RTC_Init(&hRTC_Handle);
+    }
+  }
+  if (status == HAL_OK)
+  {
+    /* Disable the write protection for RTC registers */
+    __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
 
-      /* Clear flag alarm A */
-      __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
+    /* Clear flag alarm A */
+    __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
 
-      counter = 0U;
-      /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
-      while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
+    counter = 0U;
+    /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
+    while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
+    {
+      if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
       {
-        if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
-        {
-          return HAL_ERROR;
-        }
+        status = HAL_ERROR;
       }
+    }
+  }
+  if (status == HAL_OK)
+  {
+    /* Set RTC COUNTER MSB word */
+    hRTC_Handle.Instance->ALRH = 0x00U;
+    /* Set RTC COUNTER LSB word */
+    hRTC_Handle.Instance->ALRL = 0x09U;
 
-      /* Set RTC COUNTER MSB word */
-      hRTC_Handle.Instance->ALRH = 0x00U;
-      /* Set RTC COUNTER LSB word */
-      hRTC_Handle.Instance->ALRL = 0x09U;
-
-      /* RTC Alarm Interrupt Configuration: EXTI configuration */
-      __HAL_RTC_ALARM_EXTI_ENABLE_IT();
-      __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
+    /* RTC Alarm Interrupt Configuration: EXTI configuration */
+    __HAL_RTC_ALARM_EXTI_ENABLE_IT();
+    __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
 
-      /* Clear Second and overflow flags */
-      CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
+    /* Clear Second and overflow flags */
+    CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
 
-      /* Set RTC COUNTER MSB word */
-      hRTC_Handle.Instance->CNTH = 0x00U;
-      /* Set RTC COUNTER LSB word */
-      hRTC_Handle.Instance->CNTL = 0x00U;
+    /* Set RTC COUNTER MSB word */
+    hRTC_Handle.Instance->CNTH = 0x00U;
+    /* Set RTC COUNTER LSB word */
+    hRTC_Handle.Instance->CNTL = 0x00U;
 
-      /* Configure the Alarm interrupt */
-      __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
+    /* Configure the Alarm interrupt */
+    __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
 
-      /* Enable the write protection for RTC registers */
-      __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
+    /* Enable the write protection for RTC registers */
+    __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
 
-      /* Wait till RTC is in INIT state and if Time out is reached exit */
-      counter = 0U;
-      while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+    /* Wait till RTC is in INIT state and if Time out is reached exit */
+    counter = 0U;
+    while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+    {
+      if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
       {
-        if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
-        {
-          return HAL_ERROR;
-        }
+        status = HAL_ERROR;
       }
+    }
+  }
+  if (status == HAL_OK)
+  {
+    /* Enable the RTC global Interrupt */
+    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
 
-      HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority, 0U);
-      HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
-      return HAL_OK;
+    /* Configure the SysTick IRQ priority */
+    if (TickPriority < (1UL << __NVIC_PRIO_BITS))
+    {
+      HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority ,0U);
+      uwTickPrio = TickPriority;
+    }
+    else
+    {
+      status = HAL_ERROR;
     }
   }
-  return HAL_ERROR;
+
+  return status;
 }
 
 /**
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
index e3dd8e4149..9069e87b10 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
@@ -58,12 +58,8 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
   uint32_t              uwTimclock, uwAPB1Prescaler = 0U;
   uint32_t              uwPrescalerValue = 0U;
   uint32_t              pFLatency;
+  HAL_StatusTypeDef     status = HAL_OK;
 
-  /*Configure the TIM2 IRQ priority */
-  HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0U);
-
-  /* Enable the TIM2 global Interrupt */
-  HAL_NVIC_EnableIRQ(TIM2_IRQn);
 
   /* Enable TIM2 clock */
   __HAL_RCC_TIM2_CLK_ENABLE();
@@ -101,14 +97,31 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
   TimHandle.Init.ClockDivision = 0U;
   TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
   TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
-  if (HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
+  status = HAL_TIM_Base_Init(&TimHandle);
+  if (status == HAL_OK)
   {
     /* Start the TIM time Base generation in interrupt mode */
-    return HAL_TIM_Base_Start_IT(&TimHandle);
+    status = HAL_TIM_Base_Start_IT(&TimHandle);
+    if (status == HAL_OK)
+    {
+      /* Enable the TIM2 global Interrupt */
+      HAL_NVIC_EnableIRQ(TIM2_IRQn);
+
+      if (TickPriority < (1UL << __NVIC_PRIO_BITS))
+      {
+        /*Configure the TIM2 IRQ priority */
+        HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority ,0);
+        uwTickPrio = TickPriority;
+      }
+      else
+      {
+        status = HAL_ERROR;
+      }
+    }
   }
 
   /* Return function status */
-  return HAL_ERROR;
+  return status;
 }
 
 /**
diff --git a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
index 73bf4c6d48..0b89546a9a 100644
--- a/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
+++ b/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
@@ -40,82 +40,156 @@
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f1xx_hal.h"
 
-/** @addtogroup STM32F1xx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup USB_LL USB Low Layer
-  * @brief Low layer module for USB_FS and USB_OTG_FS drivers
+/** @addtogroup STM32F1xx_LL_USB_DRIVER
   * @{
   */
 
 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
-    defined(STM32F103x6) || defined(STM32F103xB) || \
-    defined(STM32F103xE) || defined(STM32F103xG) || \
-    defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Private types -------------------------------------------------------------*/
+#if defined (USB) || defined (USB_OTG_FS)
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
 /* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
 /* Private functions ---------------------------------------------------------*/
 #if defined (USB_OTG_FS)
-/** @defgroup USB_LL_Private_Functions USB Low Layer Private Functions
-  * @{
-  */
 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
-/**
-  * @}
-  */
-#endif /* USB_OTG_FS */
 
 /* Exported functions --------------------------------------------------------*/
 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
   * @{
   */
 
-/** @defgroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
- *  @brief   management functions
- *
+/** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
+  *  @brief    Initialization and Configuration functions
+  *
 @verbatim
  ===============================================================================
-                      ##### Peripheral Control functions #####
+                      ##### Initialization/de-initialization functions #####
  ===============================================================================
-    [..]
-    This subsection provides a set of functions allowing to control the PCD data
-    transfers.
 
 @endverbatim
   * @{
   */
 
-/*==============================================================================
-    USB OTG FS peripheral available on STM32F105xx and STM32F107xx devices
-==============================================================================*/
-#if defined (USB_OTG_FS)
-
 /**
   * @brief  Initializes the USB Core
-  * @param  USBx: USB Instance
-  * @param  cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+  * @param  USBx USB Instance
+  * @param  cfg pointer to a USB_OTG_CfgTypeDef structure that contains
   *         the configuration information for the specified USBx peripheral.
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(cfg);
+  HAL_StatusTypeDef ret;
 
-  /* Select FS Embedded PHY */
-  USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+  if (cfg.phy_itface == USB_OTG_ULPI_PHY)
+  {
+    USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
+
+    /* Init The ULPI Interface */
+    USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
+
+    /* Select vbus source */
+    USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
+    if (cfg.use_external_vbus == 1U)
+    {
+      USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
+    }
+    /* Reset after a PHY select  */
+    ret = USB_CoreReset(USBx);
+  }
+  else /* FS interface (embedded Phy) */
+  {
+    /* Select FS Embedded PHY */
+    USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+
+    /* Reset after a PHY select */
+    ret = USB_CoreReset(USBx);
+
+    /* Activate the USB Transceiver */
+    USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
+  }
+
+  return ret;
+}
+
+
+/**
+  * @brief  Set the USB turnaround time
+  * @param  USBx USB Instance
+  * @param  hclk: AHB clock frequency
+  * @retval USB turnaround time In PHY Clocks number
+  */
+HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
+                                        uint32_t hclk, uint8_t speed)
+{
+  uint32_t UsbTrd;
 
-  /* Reset after a PHY select and set Host mode */
-  USB_CoreReset(USBx);
+  /* The USBTRD is configured according to the tables below, depending on AHB frequency
+  used by application. In the low AHB frequency range it is used to stretch enough the USB response
+  time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
+  latency to the Data FIFO */
+  if (speed == USBD_FS_SPEED)
+  {
+    if ((hclk >= 14200000U) && (hclk < 15000000U))
+    {
+      /* hclk Clock Range between 14.2-15 MHz */
+      UsbTrd = 0xFU;
+    }
+    else if ((hclk >= 15000000U) && (hclk < 16000000U))
+    {
+      /* hclk Clock Range between 15-16 MHz */
+      UsbTrd = 0xEU;
+    }
+    else if ((hclk >= 16000000U) && (hclk < 17200000U))
+    {
+      /* hclk Clock Range between 16-17.2 MHz */
+      UsbTrd = 0xDU;
+    }
+    else if ((hclk >= 17200000U) && (hclk < 18500000U))
+    {
+      /* hclk Clock Range between 17.2-18.5 MHz */
+      UsbTrd = 0xCU;
+    }
+    else if ((hclk >= 18500000U) && (hclk < 20000000U))
+    {
+      /* hclk Clock Range between 18.5-20 MHz */
+      UsbTrd = 0xBU;
+    }
+    else if ((hclk >= 20000000U) && (hclk < 21800000U))
+    {
+      /* hclk Clock Range between 20-21.8 MHz */
+      UsbTrd = 0xAU;
+    }
+    else if ((hclk >= 21800000U) && (hclk < 24000000U))
+    {
+      /* hclk Clock Range between 21.8-24 MHz */
+      UsbTrd = 0x9U;
+    }
+    else if ((hclk >= 24000000U) && (hclk < 27700000U))
+    {
+      /* hclk Clock Range between 24-27.7 MHz */
+      UsbTrd = 0x8U;
+    }
+    else if ((hclk >= 27700000U) && (hclk < 32000000U))
+    {
+      /* hclk Clock Range between 27.7-32 MHz */
+      UsbTrd = 0x7U;
+    }
+    else /* if(hclk >= 32000000) */
+    {
+      /* hclk Clock Range between 32-200 MHz */
+      UsbTrd = 0x6U;
+    }
+  }
+  else
+  {
+    UsbTrd = USBD_DEFAULT_TRDT_VALUE;
+  }
 
-  /* Deactivate the power down*/
-  USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
+  USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
+  USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
 
   return HAL_OK;
 }
@@ -123,7 +197,7 @@ HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
 /**
   * @brief  USB_EnableGlobalInt
   *         Enables the controller's Global Int in the AHB Config reg
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
@@ -135,9 +209,9 @@ HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
 /**
   * @brief  USB_DisableGlobalInt
   *         Disable the controller's Global Int in the AHB Config reg
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
-*/
+  */
 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
 {
   USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
@@ -145,20 +219,19 @@ HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
 }
 
 /**
-  * @brief  USB_SetCurrentMode : Set functional mode
-  * @param  USBx : Selected device
-  * @param  mode :  current core mode
-  *          This parameter can be one of the these values:
-  *            @arg USB_DEVICE_MODE: Peripheral mode mode
-  *            @arg USB_HOST_MODE: Host mode
-  *            @arg USB_DRD_MODE: Dual Role Device mode
+  * @brief  USB_SetCurrentMode Set functional mode
+  * @param  USBx  Selected device
+  * @param  mode  current core mode
+  *          This parameter can be one of these values:
+  *            @arg USB_DEVICE_MODE Peripheral mode
+  *            @arg USB_HOST_MODE Host mode
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode)
+HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
 {
   USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
 
-  if ( mode == USB_HOST_MODE)
+  if (mode == USB_HOST_MODE)
   {
     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
   }
@@ -166,139 +239,164 @@ HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeD
   {
     USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
   }
-  HAL_Delay(50);
+  else
+  {
+    return HAL_ERROR;
+  }
+  HAL_Delay(50U);
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DevInit : Initializes the USB_OTG controller registers
+  * @brief  USB_DevInit Initializes the USB_OTG controller registers
   *         for device mode
-  * @param  USBx : Selected device
-  * @param  cfg  : pointer to a USB_OTG_CfgTypeDef structure that contains
+  * @param  USBx  Selected device
+  * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
   *         the configuration information for the specified USBx peripheral.
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
 {
-  uint32_t index = 0;
+  HAL_StatusTypeDef ret = HAL_OK;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t i;
 
-  for (index = 0; index < 15 ; index++)
+  for (i = 0U; i < 15U; i++)
   {
-    USBx->DIEPTXF[index] = 0;
+    USBx->DIEPTXF[i] = 0U;
   }
 
-  /*Activate VBUS Sensing B */
+  /* Enable HW VBUS sensing */
   USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
 
   /* Restart the Phy Clock */
-  USBx_PCGCCTL = 0;
+  USBx_PCGCCTL = 0U;
 
   /* Device mode configuration */
   USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
 
-  /* Set Full speed phy */
-  USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
+  /* Set Core speed to Full speed mode */
+  (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
 
   /* Flush the FIFOs */
-  USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
-  USB_FlushRxFifo(USBx);
+  if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
+  {
+    ret = HAL_ERROR;
+  }
+
+  if (USB_FlushRxFifo(USBx) != HAL_OK)
+  {
+    ret = HAL_ERROR;
+  }
 
   /* Clear all pending Device Interrupts */
-  USBx_DEVICE->DIEPMSK = 0;
-  USBx_DEVICE->DOEPMSK = 0;
-  USBx_DEVICE->DAINT = 0xFFFFFFFF;
-  USBx_DEVICE->DAINTMSK = 0;
+  USBx_DEVICE->DIEPMSK = 0U;
+  USBx_DEVICE->DOEPMSK = 0U;
+  USBx_DEVICE->DAINTMSK = 0U;
 
-  for (index = 0; index < cfg.dev_endpoints; index++)
+  for (i = 0U; i < cfg.dev_endpoints; i++)
   {
-    if ((USBx_INEP(index)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+    if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
     {
-      USBx_INEP(index)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
+      if (i == 0U)
+      {
+        USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
+      }
+      else
+      {
+        USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
+      }
     }
     else
     {
-      USBx_INEP(index)->DIEPCTL = 0;
+      USBx_INEP(i)->DIEPCTL = 0U;
     }
 
-    USBx_INEP(index)->DIEPTSIZ = 0;
-    USBx_INEP(index)->DIEPINT  = 0xFF;
+    USBx_INEP(i)->DIEPTSIZ = 0U;
+    USBx_INEP(i)->DIEPINT  = 0xFB7FU;
   }
 
-  for (index = 0; index < cfg.dev_endpoints; index++)
+  for (i = 0U; i < cfg.dev_endpoints; i++)
   {
-    if ((USBx_OUTEP(index)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+    if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
     {
-      USBx_OUTEP(index)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
+      if (i == 0U)
+      {
+        USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
+      }
+      else
+      {
+        USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
+      }
     }
     else
     {
-      USBx_OUTEP(index)->DOEPCTL = 0;
+      USBx_OUTEP(i)->DOEPCTL = 0U;
     }
 
-    USBx_OUTEP(index)->DOEPTSIZ = 0;
-    USBx_OUTEP(index)->DOEPINT  = 0xFF;
+    USBx_OUTEP(i)->DOEPTSIZ = 0U;
+    USBx_OUTEP(i)->DOEPINT  = 0xFB7FU;
   }
 
   USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
 
   /* Disable all interrupts. */
-  USBx->GINTMSK = 0;
+  USBx->GINTMSK = 0U;
 
   /* Clear any pending interrupts */
-  USBx->GINTSTS = 0xBFFFFFFF;
+  USBx->GINTSTS = 0xBFFFFFFFU;
 
   /* Enable the common interrupts */
   USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
 
   /* Enable interrupts matching to the Device mode ONLY */
-  USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
-                    USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
-                    USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM|\
-                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+  USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
+                   USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
+                   USB_OTG_GINTMSK_OEPINT   | USB_OTG_GINTMSK_IISOIXFRM |
+                   USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
 
-  if(cfg.Sof_enable)
+  if (cfg.Sof_enable != 0U)
   {
     USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
   }
 
-  if (cfg.vbus_sensing_enable == ENABLE)
+  if (cfg.vbus_sensing_enable == 1U)
   {
     USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
   }
 
-  return HAL_OK;
+  return ret;
 }
 
 /**
   * @brief  USB_OTG_FlushTxFifo : Flush a Tx FIFO
-  * @param  USBx : Selected device
-  * @param  num : FIFO number
+  * @param  USBx  Selected device
+  * @param  num  FIFO number
   *         This parameter can be a value from 1 to 15
             15 means Flush all Tx FIFOs
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
+HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
 {
-  uint32_t count = 0;
+  uint32_t count = 0U;
 
-  USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)(num << 6));
+  USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
 
   do
   {
-    if (++count > 200000)
+    if (++count > 200000U)
     {
       return HAL_TIMEOUT;
     }
-  }
-  while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
 
   return HAL_OK;
 }
 
 /**
   * @brief  USB_FlushRxFifo : Flush Rx FIFO
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
@@ -309,57 +407,53 @@ HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
 
   do
   {
-    if (++count > 200000)
+    if (++count > 200000U)
     {
       return HAL_TIMEOUT;
     }
-  }
-  while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
+  * @brief  USB_SetDevSpeed  Initializes the DevSpd field of DCFG register
   *         depending the PHY type and the enumeration speed of the device.
-  * @param  USBx : Selected device
-  * @param  speed : device speed
-  *          This parameter can be one of the these values:
+  * @param  USBx  Selected device
+  * @param  speed  device speed
+  *          This parameter can be one of these values:
   *            @arg USB_OTG_SPEED_FULL: Full speed mode
-  *            @arg USB_OTG_SPEED_LOW: Low speed mode
   * @retval  Hal status
   */
-HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
+HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
 
   USBx_DEVICE->DCFG |= speed;
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_GetDevSpeed :Return the  Dev Speed
-  * @param  USBx : Selected device
-  * @retval speed : device speed
-  *          This parameter can be one of the these values:
-  *            @arg USB_OTG_SPEED_FULL: Full speed mode
-  *            @arg USB_OTG_SPEED_LOW: Low speed mode
+  * @brief  USB_GetDevSpeed  Return the Dev Speed
+  * @param  USBx  Selected device
+  * @retval speed  device speed
+  *          This parameter can be one of these values:
+  *            @arg PCD_SPEED_FULL: Full speed mode
   */
 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint8_t speed = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint8_t speed;
+  uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
 
-  if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
-      ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
+  if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
+      (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
   {
-    speed = USB_OTG_SPEED_FULL;
+    speed = USBD_FS_SPEED;
   }
-  else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
+  else
   {
-    speed = USB_OTG_SPEED_LOW;
+    speed = 0xFU;
   }
 
   return speed;
@@ -367,45 +461,76 @@ uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
 
 /**
   * @brief  Activate and configure an endpoint
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
-  if (ep->is_in)
+  if (ep->is_in == 1U)
   {
-    /* Assign a Tx FIFO */
-    ep->tx_fifo_num = ep->num;
+    USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
+
+    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
+    {
+      USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
+                                   ((uint32_t)ep->type << 18) | (epnum << 22) |
+                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+                                   USB_OTG_DIEPCTL_USBAEP;
+    }
   }
-  /* Set initial data PID. */
-  if (ep->type == EP_TYPE_BULK )
+  else
   {
-    ep->data_pid_start = 0;
+    USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
+
+    if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
+    {
+      USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
+                                    ((uint32_t)ep->type << 18) |
+                                    USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+                                    USB_OTG_DOEPCTL_USBAEP;
+    }
   }
+  return HAL_OK;
+}
 
-  if (ep->is_in == 1)
-  {
-   USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
+/**
+  * @brief  Activate and configure a dedicated endpoint
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
+  * @retval HAL status
+  */
+HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
-    if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1U)
+  {
+    if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
     {
-      USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
-        ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
+      USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
+                                   ((uint32_t)ep->type << 18) | (epnum << 22) |
+                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+                                   USB_OTG_DIEPCTL_USBAEP;
     }
+
+    USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
   }
   else
   {
-     USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
-
-    if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
+    if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
     {
-      USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
-       (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
+      USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
+                                    ((uint32_t)ep->type << 18) | (epnum << 22) |
+                                    USB_OTG_DOEPCTL_USBAEP;
     }
+
+    USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
   }
 
   return HAL_OK;
@@ -413,52 +538,110 @@ HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTy
 
 /**
   * @brief  De-activate and de-initialize an endpoint
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
+
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1U)
+  {
+    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+    {
+      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
+      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
+    }
+
+    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
+    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
+    USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
+                                   USB_OTG_DIEPCTL_MPSIZ |
+                                   USB_OTG_DIEPCTL_TXFNUM |
+                                   USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
+                                   USB_OTG_DIEPCTL_EPTYP);
+  }
+  else
+  {
+    if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+    {
+      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
+    }
+
+    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
+    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
+    USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
+                                    USB_OTG_DOEPCTL_MPSIZ |
+                                    USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
+                                    USB_OTG_DOEPCTL_EPTYP);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  De-activate and de-initialize a dedicated endpoint
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
+  * @retval HAL status
+  */
+HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
   /* Read DEPCTLn register */
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
-    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
-    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
-    USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
+    if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+    {
+      USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_SNAK;
+      USBx_INEP(epnum)->DIEPCTL  |= USB_OTG_DIEPCTL_EPDIS;
+    }
+
+    USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
+    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
   }
   else
   {
-    USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
-    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
-    USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
+    if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+    {
+      USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_SNAK;
+      USBx_OUTEP(epnum)->DOEPCTL  |= USB_OTG_DOEPCTL_EPDIS;
+    }
+
+    USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
+    USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
   }
+
   return HAL_OK;
 }
 
 /**
   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  uint16_t pktcnt = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
+  uint16_t pktcnt;
 
   /* IN endpoint */
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
     /* Zero Length Packet? */
-    if (ep->xfer_len == 0)
+    if (ep->xfer_len == 0U)
     {
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
     }
     else
     {
@@ -467,45 +650,40 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDe
       * short_packet pktcnt = N + (short_packet
       * exist ? 1 : 0)
       */
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
 
       if (ep->type == EP_TYPE_ISOC)
       {
-        USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
-        USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
+        USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
+        USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
       }
     }
+    /* EP enable, IN data in FIFO */
+    USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
 
     if (ep->type != EP_TYPE_ISOC)
     {
       /* Enable the Tx FIFO Empty Interrupt for this EP */
-      if (ep->xfer_len > 0)
+      if (ep->xfer_len > 0U)
       {
-        USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
+        USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
       }
     }
-
-    if (ep->type == EP_TYPE_ISOC)
+    else
     {
-      if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+      if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
       {
-        USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
+        USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
       }
       else
       {
-        USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
+        USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
       }
-    }
-
-    /* EP enable, IN data in FIFO */
-    USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
 
-    if (ep->type == EP_TYPE_ISOC)
-    {
-      USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len);
+      (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
     }
   }
   else /* OUT endpoint */
@@ -514,34 +692,34 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDe
     * pktcnt = N
     * xfersize = N * maxpacket
     */
-    USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
-    USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
 
-    if (ep->xfer_len == 0)
+    if (ep->xfer_len == 0U)
     {
-      USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
-      USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+      USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
+      USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
     }
     else
     {
-      pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
-      USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
-      USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
+      pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
+      USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
+      USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt);
     }
 
     if (ep->type == EP_TYPE_ISOC)
     {
-      if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+      if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
       {
-        USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
+        USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
       }
       else
       {
-        USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
+        USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
       }
     }
     /* EP enable */
-    USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+    USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
   }
 
   return HAL_OK;
@@ -549,24 +727,24 @@ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDe
 
 /**
   * @brief  USB_EP0StartXfer : setup and starts a transfer over the EP  0
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
   /* IN endpoint */
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
     /* Zero Length Packet? */
-    if (ep->xfer_len == 0)
+    if (ep->xfer_len == 0U)
     {
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
     }
     else
     {
@@ -575,25 +753,25 @@ HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeD
       * short_packet pktcnt = N + (short_packet
       * exist ? 1 : 0)
       */
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
-      USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+      USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
 
-      if(ep->xfer_len > ep->maxpacket)
+      if (ep->xfer_len > ep->maxpacket)
       {
         ep->xfer_len = ep->maxpacket;
       }
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
-      USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
+      USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
     }
 
+    /* EP enable, IN data in FIFO */
+    USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+
     /* Enable the Tx FIFO Empty Interrupt for this EP */
-    if (ep->xfer_len > 0)
+    if (ep->xfer_len > 0U)
     {
-      USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);
+      USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
     }
-
-    /* EP enable, IN data in FIFO */
-    USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
   }
   else /* OUT endpoint */
   {
@@ -601,19 +779,19 @@ HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeD
     * pktcnt = N
     * xfersize = N * maxpacket
     */
-    USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
-    USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+    USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
 
-    if (ep->xfer_len > 0)
+    if (ep->xfer_len > 0U)
     {
       ep->xfer_len = ep->maxpacket;
     }
 
-    USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
-    USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
+    USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
+    USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
 
     /* EP enable */
-    USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+    USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
   }
 
   return HAL_OK;
@@ -622,104 +800,108 @@ HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeD
 /**
   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
   *         with the EP/channel
-  * @param  USBx : Selected device
-  * @param  src :  pointer to source buffer
-  * @param  ch_ep_num : endpoint or host channel number
-  * @param  len : Number of bytes to write
+  * @param  USBx  Selected device
+  * @param  src   pointer to source buffer
+  * @param  ch_ep_num  endpoint or host channel number
+  * @param  len  Number of bytes to write
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
+                                  uint8_t ch_ep_num, uint16_t len)
 {
-  uint32_t count32b = 0 , index = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t *pSrc = (uint32_t *)src;
+  uint32_t count32b, i;
 
-  count32b =  (len + 3) / 4;
-  for (index = 0; index < count32b; index++, src += 4)
+  count32b = ((uint32_t)len + 3U) / 4U;
+  for (i = 0U; i < count32b; i++)
   {
-    USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
+    USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
+    pSrc++;
   }
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_ReadPacket : read a packet from the Tx FIFO associated
-  *         with the EP/channel
-  * @param  USBx : Selected device
-  * @param  dest : destination pointer
-  * @param  len : Number of bytes to read
+  * @brief  USB_ReadPacket : read a packet from the RX FIFO
+  * @param  USBx  Selected device
+  * @param  dest  source pointer
+  * @param  len  Number of bytes to read
   * @retval pointer to destination buffer
   */
 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
 {
-  uint32_t index = 0;
-  uint32_t count32b = (len + 3) / 4;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t *pDest = (uint32_t *)dest;
+  uint32_t i;
+  uint32_t count32b = ((uint32_t)len + 3U) / 4U;
 
-  for ( index = 0; index < count32b; index++, dest += 4 )
+  for (i = 0U; i < count32b; i++)
   {
-    *(__packed uint32_t *)dest = USBx_DFIFO(0);
-
+    __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
+    pDest++;
   }
-  return ((void *)dest);
+
+  return ((void *)pDest);
 }
 
 /**
   * @brief  USB_EPSetStall : set a stall condition over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
-    if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)
+    if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
     {
-      USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
+      USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
     }
-    USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
+    USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
   }
   else
   {
-    if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)
+    if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
     {
-      USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
+      USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
     }
-    USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
+    USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
   }
+
   return HAL_OK;
 }
 
 /**
   * @brief  USB_EPClearStall : Clear a stall condition over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx  Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t epnum = (uint32_t)ep->num;
 
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
-    USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
-    if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+    USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+    if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
     {
-       USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+      USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
     }
   }
   else
   {
-    USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
-    if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+    USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+    if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
     {
-      USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+      USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
     }
   }
   return HAL_OK;
@@ -727,210 +909,215 @@ HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDe
 
 /**
   * @brief  USB_StopDevice : Stop the usb device mode
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint32_t index = 0;
+  HAL_StatusTypeDef ret;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t i;
 
   /* Clear Pending interrupt */
-  for (index = 0; index < 15 ; index++)
+  for (i = 0U; i < 15U; i++)
   {
-    USBx_INEP(index)->DIEPINT  = 0xFF;
-    USBx_OUTEP(index)->DOEPINT  = 0xFF;
+    USBx_INEP(i)->DIEPINT = 0xFB7FU;
+    USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
   }
-  USBx_DEVICE->DAINT = 0xFFFFFFFF;
 
   /* Clear interrupt masks */
-  USBx_DEVICE->DIEPMSK  = 0;
-  USBx_DEVICE->DOEPMSK  = 0;
-  USBx_DEVICE->DAINTMSK = 0;
+  USBx_DEVICE->DIEPMSK  = 0U;
+  USBx_DEVICE->DOEPMSK  = 0U;
+  USBx_DEVICE->DAINTMSK = 0U;
 
   /* Flush the FIFO */
-  USB_FlushRxFifo(USBx);
-  USB_FlushTxFifo(USBx ,  0x10 );
+  ret = USB_FlushRxFifo(USBx);
+  if (ret != HAL_OK)
+  {
+    return ret;
+  }
 
-  return HAL_OK;
+  ret = USB_FlushTxFifo(USBx,  0x10U);
+  if (ret != HAL_OK)
+  {
+    return ret;
+  }
+
+  return ret;
 }
 
 /**
   * @brief  USB_SetDevAddress : Stop the usb device mode
-  * @param  USBx : Selected device
-  * @param  address : new device address to be assigned
+  * @param  USBx  Selected device
+  * @param  address  new device address to be assigned
   *          This parameter can be a value from 0 to 255
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
+HAL_StatusTypeDef  USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  UNUSED(address);
-  USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
-  USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
+  USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
+  USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
-  * @param  USBx : Selected device
+  * @brief  USB_DevConnect : Connect the USB device by enabling Rpu
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef  USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
 
-  USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
-  HAL_Delay(3);
+  /* In case phy is stopped, ensure to ungate and restore the phy CLK */
+  USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
+
+  USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
-  * @param  USBx : Selected device
+  * @brief  USB_DevDisconnect : Disconnect the USB device by disabling Rpu
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef  USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
+  /* In case phy is stopped, ensure to ungate and restore the phy CLK */
+  USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
 
   USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
-  HAL_Delay(3);
 
   return HAL_OK;
 }
 
 /**
   * @brief  USB_ReadInterrupts: return the global USB interrupt status
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-uint32_t  USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
+uint32_t  USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint32_t tmpreg = 0;
+  uint32_t tmpreg;
 
   tmpreg = USBx->GINTSTS;
   tmpreg &= USBx->GINTMSK;
+
   return tmpreg;
 }
 
 /**
   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint32_t tmpreg = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t tmpreg;
 
   tmpreg  = USBx_DEVICE->DAINT;
   tmpreg &= USBx_DEVICE->DAINTMSK;
-  return ((tmpreg & 0xffff0000) >> 16);
+
+  return ((tmpreg & 0xffff0000U) >> 16);
 }
 
 /**
   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint32_t tmpreg = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t tmpreg;
 
   tmpreg  = USBx_DEVICE->DAINT;
   tmpreg &= USBx_DEVICE->DAINTMSK;
-  return ((tmpreg & 0xFFFF));
+
+  return ((tmpreg & 0xFFFFU));
 }
 
 /**
   * @brief  Returns Device OUT EP Interrupt register
-  * @param  USBx : Selected device
-  * @param  epnum : endpoint number
+  * @param  USBx  Selected device
+  * @param  epnum  endpoint number
   *          This parameter can be a value from 0 to 15
   * @retval Device OUT EP Interrupt register
   */
-uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t tmpreg;
 
-  uint32_t tmpreg = 0;
-  tmpreg  = USBx_OUTEP(epnum)->DOEPINT;
+  tmpreg  = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
   tmpreg &= USBx_DEVICE->DOEPMSK;
+
   return tmpreg;
 }
 
 /**
   * @brief  Returns Device IN EP Interrupt register
-  * @param  USBx : Selected device
-  * @param  epnum : endpoint number
+  * @param  USBx  Selected device
+  * @param  epnum  endpoint number
   *          This parameter can be a value from 0 to 15
   * @retval Device IN EP Interrupt register
   */
-uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
 {
-  uint32_t tmpreg = 0, msk = 0, emp = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t tmpreg, msk, emp;
 
   msk = USBx_DEVICE->DIEPMSK;
   emp = USBx_DEVICE->DIEPEMPMSK;
-  msk |= ((emp >> epnum) & 0x1) << 7;
-  tmpreg = USBx_INEP(epnum)->DIEPINT & msk;
+  msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
+  tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
+
   return tmpreg;
 }
 
 /**
   * @brief  USB_ClearInterrupts: clear a USB interrupt
-  * @param  USBx : Selected device
-  * @param  interrupt : interrupt flag
+  * @param  USBx  Selected device
+  * @param  interrupt  flag
   * @retval None
   */
-void  USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
+void  USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
 {
   USBx->GINTSTS |= interrupt;
 }
 
 /**
   * @brief  Returns USB core mode
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval return core mode : Host or Device
-  *          This parameter can be one of the these values:
+  *          This parameter can be one of these values:
   *           0 : Host
   *           1 : Device
   */
 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-
-  return ((USBx->GINTSTS ) & 0x1);
+  return ((USBx->GINTSTS) & 0x1U);
 }
 
 /**
   * @brief  Activate EP0 for Setup transactions
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
+HAL_StatusTypeDef  USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  /* Set the MPS of the IN EP based on the enumeration speed */
-  USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
+  /* Set the MPS of the IN EP0 to 64 bytes */
+  USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
 
-  if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
-  {
-    USBx_INEP(0)->DIEPCTL |= 3;
-  }
   USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
 
   return HAL_OK;
@@ -938,19 +1125,61 @@ HAL_StatusTypeDef  USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
 
 /**
   * @brief  Prepare the EP0 to start the first control setup
-  * @param  USBx : Selected device
-  * @param  psetup : pointer to setup packet
+  * @param  USBx  Selected device
+  * @param  psetup  pointer to setup packet
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
   UNUSED(psetup);
-  USBx_OUTEP(0)->DOEPTSIZ = 0;
-  USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
-  USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
-  USBx_OUTEP(0)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
+
+  if (gSNPSiD > USB_OTG_CORE_ID_300A)
+  {
+    if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+    {
+      return HAL_OK;
+    }
+  }
+
+  USBx_OUTEP(0U)->DOEPTSIZ = 0U;
+  USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
+  USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
+  USBx_OUTEP(0U)->DOEPTSIZ |=  USB_OTG_DOEPTSIZ_STUPCNT;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Reset the USB Core (needed after USB clock settings change)
+  * @param  USBx  Selected device
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
+{
+  uint32_t count = 0U;
+
+  /* Wait for AHB master IDLE state. */
+  do
+  {
+    if (++count > 200000U)
+    {
+      return HAL_TIMEOUT;
+    }
+  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
+
+  /* Core Soft Reset */
+  count = 0U;
+  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+
+  do
+  {
+    if (++count > 200000U)
+    {
+      return HAL_TIMEOUT;
+    }
+  } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
 
   return HAL_OK;
 }
@@ -958,69 +1187,57 @@ HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
 /**
   * @brief  USB_HostInit : Initializes the USB OTG controller registers
   *         for Host mode
-  * @param  USBx : Selected device
-  * @param  cfg  : pointer to a USB_OTG_CfgTypeDef structure that contains
+  * @param  USBx  Selected device
+  * @param  cfg   pointer to a USB_OTG_CfgTypeDef structure that contains
   *         the configuration information for the specified USBx peripheral.
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
 {
-  uint32_t index = 0;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t i;
 
   /* Restart the Phy Clock */
-  USBx_PCGCCTL = 0;
+  USBx_PCGCCTL = 0U;
 
-  /* no VBUS sensing*/
-  USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
-  USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
-
-  /* Disable the FS/LS support mode only */
-  if((cfg.speed == USB_OTG_SPEED_FULL)&&
-     (USBx != USB_OTG_FS))
-  {
-    USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
-  }
-  else
-  {
-    USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
-  }
+  /* Disable VBUS sensing */
+  USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSASEN);
+  USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSBSEN);
+  /* Set default Max speed support */
+  USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
 
   /* Make sure the FIFOs are flushed. */
-  USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
-  USB_FlushRxFifo(USBx);
+  (void)USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
+  (void)USB_FlushRxFifo(USBx);
 
   /* Clear all pending HC Interrupts */
-  for (index = 0; index < cfg.Host_channels; index++)
+  for (i = 0U; i < cfg.Host_channels; i++)
   {
-    USBx_HC(index)->HCINT = 0xFFFFFFFF;
-    USBx_HC(index)->HCINTMSK = 0;
+    USBx_HC(i)->HCINT = 0xFFFFFFFFU;
+    USBx_HC(i)->HCINTMSK = 0U;
   }
 
   /* Enable VBUS driving */
-  USB_DriveVbus(USBx, 1);
+  (void)USB_DriveVbus(USBx, 1U);
 
-  HAL_Delay(200);
+  HAL_Delay(200U);
 
   /* Disable all interrupts. */
-  USBx->GINTMSK = 0;
+  USBx->GINTMSK = 0U;
 
   /* Clear any pending interrupts */
-  USBx->GINTSTS = 0xFFFFFFFF;
-
-  if(USBx == USB_OTG_FS)
-  {
-    /* set Rx FIFO size */
-    USBx->GRXFSIZ  = (uint32_t )0x80;
-    USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
-    USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
-  }
+  USBx->GINTSTS = 0xFFFFFFFFU;
 
+  /* set Rx FIFO size */
+  USBx->GRXFSIZ  = 0x80U;
+  USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
+  USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
   /* Enable the common interrupts */
   USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
 
   /* Enable interrupts matching to the Host mode ONLY */
-  USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM |\
-                    USB_OTG_GINTMSK_SOFM             |USB_OTG_GINTSTS_DISCINT|\
+  USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM | \
+                    USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \
                     USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);
 
   return HAL_OK;
@@ -1029,79 +1246,85 @@ HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef
 /**
   * @brief  USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
   *         HCFG register on the PHY type and set the right frame interval
-  * @param  USBx : Selected device
-  * @param  freq : clock frequency
-  *          This parameter can be one of the these values:
+  * @param  USBx  Selected device
+  * @param  freq  clock frequency
+  *          This parameter can be one of these values:
   *           HCFG_48_MHZ : Full Speed 48 MHz Clock
   *           HCFG_6_MHZ : Low Speed 6 MHz Clock
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
+HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
 
   USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
-  USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
+  USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
 
-  if (freq ==  HCFG_48_MHZ)
+  if (freq == HCFG_48_MHZ)
   {
-    USBx_HOST->HFIR = (uint32_t)48000;
+    USBx_HOST->HFIR = 48000U;
   }
-  else if (freq ==  HCFG_6_MHZ)
+  else if (freq == HCFG_6_MHZ)
   {
-    USBx_HOST->HFIR = (uint32_t)6000;
+    USBx_HOST->HFIR = 6000U;
   }
+  else
+  {
+    /* ... */
+  }
+
   return HAL_OK;
 }
 
 /**
-* @brief  USB_OTG_ResetPort : Reset Host Port
-  * @param  USBx : Selected device
+  * @brief  USB_OTG_ResetPort : Reset Host Port
+  * @param  USBx  Selected device
   * @retval HAL status
-  * @note : (1)The application must wait at least 10 ms
+  * @note (1)The application must wait at least 10 ms
   *   before clearing the reset bit.
   */
 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
 {
-  __IO uint32_t hprt0 = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
+  __IO uint32_t hprt0 = 0U;
 
   hprt0 = USBx_HPRT0;
 
-  hprt0 &= ~(USB_OTG_HPRT_PENA    | USB_OTG_HPRT_PCDET |\
-    USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+  hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
+             USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
 
   USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
-  HAL_Delay (10);                                /* See Note #1 */
+  HAL_Delay(100U);                                 /* See Note #1 */
   USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
+  HAL_Delay(10U);
+
   return HAL_OK;
 }
 
 /**
   * @brief  USB_DriveVbus : activate or de-activate vbus
-  * @param  state : VBUS state
-  *          This parameter can be one of the these values:
-  *           0 : VBUS Active
-  *           1 : VBUS Inactive
+  * @param  state  VBUS state
+  *          This parameter can be one of these values:
+  *           0 : Deactivate VBUS
+  *           1 : Activate VBUS
   * @retval HAL status
-*/
-HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
+  */
+HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
 {
-  __IO uint32_t hprt0 = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  __IO uint32_t hprt0 = 0U;
 
   hprt0 = USBx_HPRT0;
-  hprt0 &= ~(USB_OTG_HPRT_PENA    | USB_OTG_HPRT_PCDET |\
-          USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
 
-  if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))
+  hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
+             USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
+
+  if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
   {
     USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
   }
-  if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))
+  if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
   {
     USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
   }
@@ -1110,17 +1333,16 @@ HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
 
 /**
   * @brief  Return Host Core speed
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval speed : Host speed
-  *          This parameter can be one of the these values:
-  *            @arg USB_OTG_SPEED_FULL: Full speed mode
-  *            @arg USB_OTG_SPEED_LOW: Low speed mode
+  *          This parameter can be one of these values:
+  *            @arg HCD_SPEED_FULL: Full speed mode
+  *            @arg HCD_SPEED_LOW: Low speed mode
   */
-uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
+uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
 {
-  __IO uint32_t hprt0 = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  __IO uint32_t hprt0 = 0U;
 
   hprt0 = USBx_HPRT0;
   return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
@@ -1128,209 +1350,236 @@ uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
 
 /**
   * @brief  Return Host Current Frame number
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval current frame number
-*/
-uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
+  */
+uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
 
   return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
 }
 
 /**
   * @brief  Initialize a host channel
-  * @param  USBx : Selected device
-  * @param  ch_num : Channel number
+  * @param  USBx  Selected device
+  * @param  ch_num  Channel number
   *         This parameter can be a value from 1 to 15
-  * @param  epnum : Endpoint number
+  * @param  epnum  Endpoint number
   *          This parameter can be a value from 1 to 15
-  * @param  dev_address : Current device address
+  * @param  dev_address  Current device address
   *          This parameter can be a value from 0 to 255
-  * @param  speed : Current device speed
-  *          This parameter can be one of the these values:
+  * @param  speed  Current device speed
+  *          This parameter can be one of these values:
   *            @arg USB_OTG_SPEED_FULL: Full speed mode
   *            @arg USB_OTG_SPEED_LOW: Low speed mode
-  * @param  ep_type : Endpoint Type
-  *          This parameter can be one of the these values:
+  * @param  ep_type  Endpoint Type
+  *          This parameter can be one of these values:
   *            @arg EP_TYPE_CTRL: Control type
   *            @arg EP_TYPE_ISOC: Isochronous type
   *            @arg EP_TYPE_BULK: Bulk type
   *            @arg EP_TYPE_INTR: Interrupt type
-  * @param  mps : Max Packet Size
+  * @param  mps  Max Packet Size
   *          This parameter can be a value from 0 to32K
   * @retval HAL state
   */
-HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
-                              uint8_t ch_num,
-                              uint8_t epnum,
-                              uint8_t dev_address,
-                              uint8_t speed,
-                              uint8_t ep_type,
-                              uint16_t mps)
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
+                              uint8_t epnum, uint8_t dev_address, uint8_t speed,
+                              uint8_t ep_type, uint16_t mps)
 {
+  HAL_StatusTypeDef ret = HAL_OK;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t HCcharEpDir, HCcharLowSpeed;
+
   /* Clear old interrupt conditions for this host channel. */
-  USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
+  USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
 
   /* Enable channel interrupts required for this transfer. */
   switch (ep_type)
   {
-  case EP_TYPE_CTRL:
-  case EP_TYPE_BULK:
-    USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\
-                                USB_OTG_HCINTMSK_STALLM |\
-                                USB_OTG_HCINTMSK_TXERRM |\
-                                USB_OTG_HCINTMSK_DTERRM |\
-                                USB_OTG_HCINTMSK_AHBERR |\
-                                USB_OTG_HCINTMSK_NAKM ;
-
-    if (epnum & 0x80)
-    {
-      USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
-    }
-    break;
+    case EP_TYPE_CTRL:
+    case EP_TYPE_BULK:
+      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
+                                            USB_OTG_HCINTMSK_STALLM |
+                                            USB_OTG_HCINTMSK_TXERRM |
+                                            USB_OTG_HCINTMSK_DTERRM |
+                                            USB_OTG_HCINTMSK_AHBERR |
+                                            USB_OTG_HCINTMSK_NAKM;
+
+      if ((epnum & 0x80U) == 0x80U)
+      {
+        USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+      }
+      break;
 
-  case EP_TYPE_INTR:
-    USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\
-                                USB_OTG_HCINTMSK_STALLM |\
-                                USB_OTG_HCINTMSK_TXERRM |\
-                                USB_OTG_HCINTMSK_DTERRM |\
-                                USB_OTG_HCINTMSK_NAKM   |\
-                                USB_OTG_HCINTMSK_AHBERR |\
-                                USB_OTG_HCINTMSK_FRMORM ;
+    case EP_TYPE_INTR:
+      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
+                                            USB_OTG_HCINTMSK_STALLM |
+                                            USB_OTG_HCINTMSK_TXERRM |
+                                            USB_OTG_HCINTMSK_DTERRM |
+                                            USB_OTG_HCINTMSK_NAKM   |
+                                            USB_OTG_HCINTMSK_AHBERR |
+                                            USB_OTG_HCINTMSK_FRMORM;
+
+      if ((epnum & 0x80U) == 0x80U)
+      {
+        USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+      }
 
-    if (epnum & 0x80)
-    {
-      USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
-    }
+      break;
 
-    break;
+    case EP_TYPE_ISOC:
+      USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |
+                                            USB_OTG_HCINTMSK_ACKM   |
+                                            USB_OTG_HCINTMSK_AHBERR |
+                                            USB_OTG_HCINTMSK_FRMORM;
 
-  case EP_TYPE_ISOC:
-    USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM  |\
-                                USB_OTG_HCINTMSK_ACKM   |\
-                                USB_OTG_HCINTMSK_AHBERR |\
-                                USB_OTG_HCINTMSK_FRMORM ;
+      if ((epnum & 0x80U) == 0x80U)
+      {
+        USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
+      }
+      break;
 
-    if (epnum & 0x80)
-    {
-      USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
-    }
-    break;
+    default:
+      ret = HAL_ERROR;
+      break;
   }
 
   /* Enable the top level host channel interrupt. */
-  USBx_HOST->HAINTMSK |= (1 << ch_num);
+  USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
 
   /* Make sure host channel interrupts are enabled. */
   USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
 
   /* Program the HCCHAR register */
-  USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD)  |\
-                             (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
-                             ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
-                             (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
-                             ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
-                             (mps & USB_OTG_HCCHAR_MPSIZ));
+  if ((epnum & 0x80U) == 0x80U)
+  {
+    HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
+  }
+  else
+  {
+    HCcharEpDir = 0U;
+  }
+
+  if (speed == HPRT0_PRTSPD_LOW_SPEED)
+  {
+    HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
+  }
+  else
+  {
+    HCcharLowSpeed = 0U;
+  }
+
+  USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
+                                      ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
+                                      (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
+                                      ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
 
   if (ep_type == EP_TYPE_INTR)
   {
-    USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
+    USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
   }
 
-  return HAL_OK;
+  return ret;
 }
 
 /**
   * @brief  Start a transfer over a host channel
-  * @param  USBx : Selected device
-  * @param  hc : pointer to host channel structure
+  * @param  USBx  Selected device
+  * @param  hc  pointer to host channel structure
   * @retval HAL state
   */
-#if defined   (__CC_ARM) /*!< ARM Compiler */
-#pragma O0
-#elif defined (__GNUC__) /*!< GNU Compiler */
-#pragma GCC optimize ("O0")
-#endif /* __CC_ARM */
 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
 {
-  uint8_t  is_oddframe = 0;
-  uint16_t len_words = 0;
-  uint16_t num_packets = 0;
-  uint16_t max_hc_pkt_count = 256;
-  uint32_t tmpreg = 0;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t ch_num = (uint32_t)hc->ch_num;
+  static __IO uint32_t tmpreg = 0U;
+  uint8_t  is_oddframe;
+  uint16_t len_words;
+  uint16_t num_packets;
+  uint16_t max_hc_pkt_count = 256U;
 
   /* Compute the expected number of packets associated to the transfer */
-  if (hc->xfer_len > 0)
+  if (hc->xfer_len > 0U)
   {
-    num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
+    num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
 
     if (num_packets > max_hc_pkt_count)
     {
       num_packets = max_hc_pkt_count;
-      hc->xfer_len = num_packets * hc->max_packet;
+      hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
     }
   }
   else
   {
-    num_packets = 1;
+    num_packets = 1U;
   }
-  if (hc->ep_is_in)
+  if (hc->ep_is_in != 0U)
   {
-    hc->xfer_len = num_packets * hc->max_packet;
+    hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
   }
 
   /* Initialize the HCTSIZn register */
-  USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
-    ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
-      (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
+  USBx_HC(ch_num)->HCTSIZ = (hc->xfer_len & USB_OTG_HCTSIZ_XFRSIZ) |
+                            (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
+                            (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
 
-  is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
-  USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
-  USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
+  is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
+  USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
+  USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
 
   /* Set host channel enable */
-  tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
+  tmpreg = USBx_HC(ch_num)->HCCHAR;
   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+
+  /* make sure to set the correct ep direction */
+  if (hc->ep_is_in != 0U)
+  {
+    tmpreg |= USB_OTG_HCCHAR_EPDIR;
+  }
+  else
+  {
+    tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
+  }
   tmpreg |= USB_OTG_HCCHAR_CHENA;
-  USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
+  USBx_HC(ch_num)->HCCHAR = tmpreg;
 
-  if((hc->ep_is_in == 0) && (hc->xfer_len > 0))
+  if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
   {
-    switch(hc->ep_type)
+    switch (hc->ep_type)
     {
       /* Non periodic transfer */
-    case EP_TYPE_CTRL:
-    case EP_TYPE_BULK:
-      len_words = (hc->xfer_len + 3) / 4;
+      case EP_TYPE_CTRL:
+      case EP_TYPE_BULK:
 
-      /* check if there is enough space in FIFO space */
-      if(len_words > (USBx->HNPTXSTS & 0xFFFF))
-      {
-        /* need to process data in nptxfempty interrupt */
-        USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
-      }
-      break;
+        len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
+
+        /* check if there is enough space in FIFO space */
+        if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
+        {
+          /* need to process data in nptxfempty interrupt */
+          USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
+        }
+        break;
 
       /* Periodic transfer */
-    case EP_TYPE_INTR:
-    case EP_TYPE_ISOC:
-      len_words = (hc->xfer_len + 3) / 4;
-      /* check if there is enough space in FIFO space */
-      if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
-      {
-        /* need to process data in ptxfempty interrupt */
-        USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
-      }
-      break;
+      case EP_TYPE_INTR:
+      case EP_TYPE_ISOC:
+        len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
+        /* check if there is enough space in FIFO space */
+        if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
+        {
+          /* need to process data in ptxfempty interrupt */
+          USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
+        }
+        break;
 
-    default:
-      break;
+      default:
+        break;
     }
 
     /* Write packet into the Tx FIFO. */
-    USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len);
+    (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
   }
 
   return HAL_OK;
@@ -1338,76 +1587,73 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe
 
 /**
   * @brief Read all host channel interrupts status
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL state
   */
-uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
+uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
 
-  return ((USBx_HOST->HAINT) & 0xFFFF);
+  return ((USBx_HOST->HAINT) & 0xFFFFU);
 }
 
 /**
   * @brief  Halt a host channel
-  * @param  USBx : Selected device
-  * @param  hc_num : Host Channel number
+  * @param  USBx  Selected device
+  * @param  hc_num  Host Channel number
   *         This parameter can be a value from 1 to 15
   * @retval HAL state
   */
-HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
+HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
 {
-  uint32_t count = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t hcnum = (uint32_t)hc_num;
+  uint32_t count = 0U;
+  uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
 
   /* Check for space in the request queue to issue the halt. */
-  if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) ||
-     (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
+  if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
   {
-    USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+    USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
 
-    if ((USBx->HNPTXSTS & 0xFFFF) == 0)
+    if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
     {
-      USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
-      USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
-      USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+      USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
       do
       {
-        if (++count > 1000)
+        if (++count > 1000U)
         {
           break;
         }
-      }
-      while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+      } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
     }
     else
     {
-      USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
     }
   }
   else
   {
-    USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+    USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
 
-    if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)
+    if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
     {
-      USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
-      USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
-      USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+      USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
       do
       {
-        if (++count > 1000)
+        if (++count > 1000U)
         {
           break;
         }
-      }
-      while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+      } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
     }
     else
     {
-       USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+      USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
     }
   }
 
@@ -1416,125 +1662,124 @@ HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
 
 /**
   * @brief  Initiate Do Ping protocol
-  * @param  USBx : Selected device
-  * @param  hc_num : Host Channel number
+  * @param  USBx  Selected device
+  * @param  hc_num  Host Channel number
   *         This parameter can be a value from 1 to 15
   * @retval HAL state
   */
-HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
+HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
 {
-  uint8_t  num_packets = 1;
-  uint32_t tmpreg = 0;
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t chnum = (uint32_t)ch_num;
+  uint32_t num_packets = 1U;
+  uint32_t tmpreg;
 
-  USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
-                                USB_OTG_HCTSIZ_DOPING;
+  USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
+                           USB_OTG_HCTSIZ_DOPING;
 
   /* Set host channel enable */
-  tmpreg = USBx_HC(ch_num)->HCCHAR;
+  tmpreg = USBx_HC(chnum)->HCCHAR;
   tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
   tmpreg |= USB_OTG_HCCHAR_CHENA;
-  USBx_HC(ch_num)->HCCHAR = tmpreg;
+  USBx_HC(chnum)->HCCHAR = tmpreg;
 
   return HAL_OK;
 }
 
 /**
   * @brief  Stop Host Core
-  * @param  USBx : Selected device
+  * @param  USBx  Selected device
   * @retval HAL state
   */
 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
 {
-  uint8_t index;
-  uint32_t count = 0;
-  uint32_t value = 0;
+  uint32_t USBx_BASE = (uint32_t)USBx;
+  uint32_t count = 0U;
+  uint32_t value;
+  uint32_t i;
 
-  USB_DisableGlobalInt(USBx);
+  (void)USB_DisableGlobalInt(USBx);
 
-    /* Flush FIFO */
-  USB_FlushTxFifo(USBx, 0x10);
-  USB_FlushRxFifo(USBx);
+  /* Flush FIFO */
+  (void)USB_FlushTxFifo(USBx, 0x10U);
+  (void)USB_FlushRxFifo(USBx);
 
   /* Flush out any leftover queued requests. */
-  for (index = 0; index <= 15; index++)
+  for (i = 0U; i <= 15U; i++)
   {
-    value = USBx_HC(index)->HCCHAR;
+    value = USBx_HC(i)->HCCHAR;
     value |=  USB_OTG_HCCHAR_CHDIS;
     value &= ~USB_OTG_HCCHAR_CHENA;
     value &= ~USB_OTG_HCCHAR_EPDIR;
-    USBx_HC(index)->HCCHAR = value;
+    USBx_HC(i)->HCCHAR = value;
   }
 
   /* Halt all channels to put them into a known state. */
-  for (index = 0; index <= 15; index++)
+  for (i = 0U; i <= 15U; i++)
   {
-    value = USBx_HC(index)->HCCHAR ;
+    value = USBx_HC(i)->HCCHAR;
     value |= USB_OTG_HCCHAR_CHDIS;
     value |= USB_OTG_HCCHAR_CHENA;
     value &= ~USB_OTG_HCCHAR_EPDIR;
-    USBx_HC(index)->HCCHAR = value;
+    USBx_HC(i)->HCCHAR = value;
 
     do
     {
-      if (++count > 1000)
+      if (++count > 1000U)
       {
         break;
       }
-    }
-    while ((USBx_HC(index)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+    } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
   }
 
   /* Clear any pending Host interrupts */
-  USBx_HOST->HAINT = 0xFFFFFFFF;
-  USBx->GINTSTS = 0xFFFFFFFF;
-  USB_EnableGlobalInt(USBx);
+  USBx_HOST->HAINT = 0xFFFFFFFFU;
+  USBx->GINTSTS = 0xFFFFFFFFU;
+
+  (void)USB_EnableGlobalInt(USBx);
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
-  * @param  USBx : Selected device
+  * @brief  USB_ActivateRemoteWakeup active remote wakeup signalling
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
+  if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
   {
     /* active Remote wakeup signalling */
     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
   }
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
-  * @param  USBx : Selected device
+  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
 {
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
+  uint32_t USBx_BASE = (uint32_t)USBx;
+
   /* active Remote wakeup signalling */
-   USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
+  USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
+
   return HAL_OK;
 }
+#endif /* defined (USB_OTG_FS) */
 
-#endif /* USB_OTG_FS */
-
-/*==============================================================================
-    USB Device FS peripheral available on STM32F102xx and STM32F103xx devices
-==============================================================================*/
 #if defined (USB)
 /**
   * @brief  Initializes the USB Core
-  * @param  USBx: USB Instance
-  * @param  cfg : pointer to a USB_CfgTypeDef structure that contains
+  * @param  USBx USB Instance
+  * @param  cfg pointer to a USB_CfgTypeDef structure that contains
   *         the configuration information for the specified USBx peripheral.
   * @retval HAL status
   */
@@ -1543,29 +1788,36 @@ HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
   UNUSED(cfg);
+
   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
               only by USB OTG FS peripheral.
             - This function is added to ensure compatibility across platforms.
    */
+
   return HAL_OK;
 }
 
 /**
   * @brief  USB_EnableGlobalInt
   *         Enables the controller's Global Int in the AHB Config reg
-  * @param  USBx : Selected device
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
 {
-  uint32_t winterruptmask = 0;
+  uint32_t winterruptmask;
+
+  /* Clear pending interrupts */
+  USBx->ISTR = 0U;
 
   /* Set winterruptmask variable */
-  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
-     | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
+                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
+                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
+                   USB_CNTR_RESETM;
 
   /* Set interrupt mask */
-  USBx->CNTR |= winterruptmask;
+  USBx->CNTR = (uint16_t)winterruptmask;
 
   return HAL_OK;
 }
@@ -1573,36 +1825,39 @@ HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
 /**
   * @brief  USB_DisableGlobalInt
   *         Disable the controller's Global Int in the AHB Config reg
-  * @param  USBx : Selected device
+  * @param  USBx Selected device
   * @retval HAL status
-*/
+  */
 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
 {
-  uint32_t winterruptmask = 0;
+  uint32_t winterruptmask;
 
   /* Set winterruptmask variable */
-  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
-    | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+  winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
+                   USB_CNTR_SUSPM | USB_CNTR_ERRM |
+                   USB_CNTR_SOFM | USB_CNTR_ESOFM |
+                   USB_CNTR_RESETM;
 
   /* Clear interrupt mask */
-  USBx->CNTR &= ~winterruptmask;
+  USBx->CNTR &= (uint16_t)(~winterruptmask);
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_SetCurrentMode : Set functional mode
-  * @param  USBx : Selected device
-  * @param  mode :  current core mode
+  * @brief  USB_SetCurrentMode Set functional mode
+  * @param  USBx Selected device
+  * @param  mode current core mode
   *          This parameter can be one of the these values:
-  *            @arg USB_DEVICE_MODE: Peripheral mode mode
+  *            @arg USB_DEVICE_MODE Peripheral mode
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode)
+HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
   UNUSED(mode);
+
   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
               only by USB OTG FS peripheral.
             - This function is added to ensure compatibility across platforms.
@@ -1611,174 +1866,170 @@ HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode)
 }
 
 /**
-  * @brief  USB_DevInit : Initializes the USB controller registers
+  * @brief  USB_DevInit Initializes the USB controller registers
   *         for device mode
-  * @param  USBx : Selected device
-  * @param  cfg  : pointer to a USB_CfgTypeDef structure that contains
+  * @param  USBx Selected device
+  * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
   *         the configuration information for the specified USBx peripheral.
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_DevInit (USB_TypeDef *USBx, USB_CfgTypeDef cfg)
+HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(cfg);
 
   /* Init Device */
-  /*CNTR_FRES = 1*/
-  USBx->CNTR = USB_CNTR_FRES;
+  /* CNTR_FRES = 1 */
+  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
 
-  /*CNTR_FRES = 0*/
-  USBx->CNTR = 0;
+  /* CNTR_FRES = 0 */
+  USBx->CNTR = 0U;
 
-  /*Clear pending interrupts*/
-  USBx->ISTR = 0;
+  /* Clear pending interrupts */
+  USBx->ISTR = 0U;
 
   /*Set Btable Address*/
   USBx->BTABLE = BTABLE_ADDRESS;
 
-  /* Enable USB Device Interrupt mask */
-  USB_EnableGlobalInt(USBx);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  USB_FlushTxFifo : Flush a Tx FIFO
-  * @param  USBx : Selected device
-  * @param  num : FIFO number
-  *         This parameter can be a value from 1 to 15
-            15 means Flush all Tx FIFOs
-  * @retval HAL status
-  */
-HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  UNUSED(num);
-  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
-              only by USB OTG FS peripheral.
-            - This function is added to ensure compatibility across platforms.
-   */
-  return HAL_OK;
-}
-
-/**
-  * @brief  USB_FlushRxFifo : Flush Rx FIFO
-  * @param  USBx : Selected device
-  * @retval HAL status
-  */
-HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
-              only by USB OTG FS peripheral.
-            - This function is added to ensure compatibility across platforms.
-   */
   return HAL_OK;
 }
 
 /**
   * @brief  Activate and configure an endpoint
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 {
+  HAL_StatusTypeDef ret = HAL_OK;
+  uint16_t wEpRegVal;
+
+  wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
+
   /* initialize Endpoint */
   switch (ep->type)
   {
-  case EP_TYPE_CTRL:
-    PCD_SET_EPTYPE(USBx, ep->num, USB_EP_CONTROL);
-    break;
-  case EP_TYPE_BULK:
-    PCD_SET_EPTYPE(USBx, ep->num, USB_EP_BULK);
-    break;
-  case EP_TYPE_INTR:
-    PCD_SET_EPTYPE(USBx, ep->num, USB_EP_INTERRUPT);
-    break;
-  case EP_TYPE_ISOC:
-    PCD_SET_EPTYPE(USBx, ep->num, USB_EP_ISOCHRONOUS);
-    break;
-  default:
+    case EP_TYPE_CTRL:
+      wEpRegVal |= USB_EP_CONTROL;
+      break;
+
+    case EP_TYPE_BULK:
+      wEpRegVal |= USB_EP_BULK;
+      break;
+
+    case EP_TYPE_INTR:
+      wEpRegVal |= USB_EP_INTERRUPT;
+      break;
+
+    case EP_TYPE_ISOC:
+      wEpRegVal |= USB_EP_ISOCHRONOUS;
+      break;
+
+    default:
+      ret = HAL_ERROR;
       break;
   }
 
+  PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
+
   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
 
-  if (ep->doublebuffer == 0)
+  if (ep->doublebuffer == 0U)
   {
-    if (ep->is_in == 1)
+    if (ep->is_in != 0U)
     {
-      /* Set the endpoint Transmit buffer address */
+      /*Set the endpoint Transmit buffer address */
       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
-      /* Configure NAK status for the Endpoint */
-      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+
+      if (ep->type != EP_TYPE_ISOC)
+      {
+        /* Configure NAK status for the Endpoint */
+        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+      }
+      else
+      {
+        /* Configure TX Endpoint to disabled state */
+        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+      }
     }
     else
     {
-      /* Set the endpoint Receive buffer address */
+      /*Set the endpoint Receive buffer address */
       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
-      /* Set the endpoint Receive buffer counter */
+
+      /*Set the endpoint Receive buffer counter*/
       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
-      /* All ep must NAK to every host request before PrepareReceive */
-      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
+
+      /* Configure VALID status for the Endpoint*/
+      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
     }
   }
-  /* Double Buffer */
+  /*Double Buffer*/
   else
   {
     /* Set the endpoint as double buffered */
     PCD_SET_EP_DBUF(USBx, ep->num);
+
     /* Set buffer address for double buffered mode */
-    PCD_SET_EP_DBUF_ADDR(USBx, ep->num,ep->pmaaddr0, ep->pmaaddr1);
+    PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
 
-    if (ep->is_in == 1)
+    if (ep->is_in == 0U)
     {
       /* Clear the data toggle bits for the endpoint IN/OUT */
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
-      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
-      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+
+      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
     }
     else
     {
-      PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
       /* Clear the data toggle bits for the endpoint IN/OUT */
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
-      /* All ep must NAK to every host request before PrepareReceive */
-      /* Reset value of the data toggle bits for the endpoint out */
-      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
-      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+
+      if (ep->type != EP_TYPE_ISOC)
+      {
+        /* Configure NAK status for the Endpoint */
+        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+      }
+      else
+      {
+        /* Configure TX Endpoint to disabled state */
+        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+      }
+
+      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
     }
   }
 
-  return HAL_OK;
+  return ret;
 }
 
 /**
   * @brief  De-activate and de-initialize an endpoint
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @param  USBx Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 {
-  if (ep->doublebuffer == 0)
+  if (ep->doublebuffer == 0U)
   {
-    if (ep->is_in == 1)
+    if (ep->is_in != 0U)
     {
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
       /* Configure DISABLE status for the Endpoint*/
       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
     }
     else
     {
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
+
       /* Configure DISABLE status for the Endpoint*/
       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
     }
@@ -1786,25 +2037,28 @@ HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
   /*Double Buffer*/
   else
   {
-    if (ep->is_in == 1)
+    if (ep->is_in == 0U)
     {
       /* Clear the data toggle bits for the endpoint IN/OUT*/
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
-      PCD_RX_DTOG(USBx, ep->num);
-      /* Configure DISABLE status for the Endpoint*/
-      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+
+      /* Reset value of the data toggle bits for the endpoint out*/
+      PCD_TX_DTOG(USBx, ep->num);
+
       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
     }
     else
     {
       /* Clear the data toggle bits for the endpoint IN/OUT*/
       PCD_CLEAR_RX_DTOG(USBx, ep->num);
       PCD_CLEAR_TX_DTOG(USBx, ep->num);
-      /* Reset value of the data toggle bits for the endpoint out*/
-      PCD_TX_DTOG(USBx, ep->num);
-      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+      PCD_RX_DTOG(USBx, ep->num);
+
+      /* Configure DISABLE status for the Endpoint*/
       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
     }
   }
 
@@ -1812,253 +2066,359 @@ HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 }
 
 /**
-  * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @brief  USB_EPStartXfer setup and starts a transfer over an EP
+  * @param  USBx Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 {
-  uint16_t pmabuffer;
   uint32_t len;
+  uint16_t pmabuffer;
+  uint16_t wEPVal;
 
   /* IN endpoint */
-  if (ep->is_in == 1)
+  if (ep->is_in == 1U)
   {
-    /* Multi packet transfer */
+    /*Multi packet transfer*/
     if (ep->xfer_len > ep->maxpacket)
     {
-      len=ep->maxpacket;
-      ep->xfer_len-=len;
+      len = ep->maxpacket;
     }
     else
     {
-      len=ep->xfer_len;
-      ep->xfer_len =0;
+      len = ep->xfer_len;
     }
 
     /* configure and validate Tx endpoint */
-    if (ep->doublebuffer == 0)
+    if (ep->doublebuffer == 0U)
     {
+      USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
-      pmabuffer = ep->pmaadress;
     }
     else
     {
-      /* Write the data to the USB endpoint */
-      if (PCD_GET_ENDPOINT(USBx, ep->num)& USB_EP_DTOG_TX)
+      /* double buffer bulk management */
+      if (ep->type == EP_TYPE_BULK)
       {
-        /* Set the Double buffer counter for pmabuffer1 */
-        PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
-        pmabuffer = ep->pmaaddr1;
-      }
+        if (ep->xfer_len_db > ep->maxpacket)
+        {
+          /* enable double buffer */
+          PCD_SET_EP_DBUF(USBx, ep->num);
+
+          /* each Time to write in PMA xfer_len_db will */
+          ep->xfer_len_db -= len;
+
+          /* Fill the two first buffer in the Buffer0 & Buffer1 */
+          if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
+          {
+            /* Set the Double buffer counter for pmabuffer1 */
+            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
+            pmabuffer = ep->pmaaddr1;
+
+            /* Write the user buffer to USB PMA */
+            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+            ep->xfer_buff += len;
+
+            if (ep->xfer_len_db > ep->maxpacket)
+            {
+              ep->xfer_len_db -= len;
+            }
+            else
+            {
+              len = ep->xfer_len_db;
+              ep->xfer_len_db = 0U;
+            }
+
+            /* Set the Double buffer counter for pmabuffer0 */
+            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
+            pmabuffer = ep->pmaaddr0;
+
+            /* Write the user buffer to USB PMA */
+            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+          }
+          else
+          {
+            /* Set the Double buffer counter for pmabuffer0 */
+            PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
+            pmabuffer = ep->pmaaddr0;
+
+            /* Write the user buffer to USB PMA */
+            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+            ep->xfer_buff += len;
+
+            if (ep->xfer_len_db > ep->maxpacket)
+            {
+              ep->xfer_len_db -= len;
+            }
+            else
+            {
+              len = ep->xfer_len_db;
+              ep->xfer_len_db = 0U;
+            }
+
+            /* Set the Double buffer counter for pmabuffer1 */
+            PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
+            pmabuffer = ep->pmaaddr1;
+
+            /* Write the user buffer to USB PMA */
+            USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+          }
+        }
+        /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
+        else
+        {
+          len = ep->xfer_len_db;
+
+          /* disable double buffer mode */
+          PCD_CLEAR_EP_DBUF(USBx, ep->num);
+
+          /* Set Tx count with nbre of byte to be transmitted */
+          PCD_SET_EP_TX_CNT(USBx, ep->num, len);
+          pmabuffer = ep->pmaaddr0;
+
+          /* Write the user buffer to USB PMA */
+          USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+        }
+      }/* end if bulk double buffer */
+
+      /* manage isochronous double buffer IN mode */
       else
       {
-        /* Set the Double buffer counter for pmabuffer0 */
-        PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
-        pmabuffer = ep->pmaaddr0;
+        /* Write the data to the USB endpoint */
+        if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
+        {
+          /* Set the Double buffer counter for pmabuffer1 */
+          PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
+          pmabuffer = ep->pmaaddr1;
+        }
+        else
+        {
+          /* Set the Double buffer counter for pmabuffer0 */
+          PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
+          pmabuffer = ep->pmaaddr0;
+        }
+
+        USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
+        PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
       }
     }
 
-    USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t) len);
-
-    if (ep->doublebuffer == 0)
+    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+  }
+  else /* OUT endpoint */
+  {
+    if (ep->doublebuffer == 0U)
     {
-      PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+      /* Multi packet transfer */
+      if (ep->xfer_len > ep->maxpacket)
+      {
+        len = ep->maxpacket;
+        ep->xfer_len -= len;
+      }
+      else
+      {
+        len = ep->xfer_len;
+        ep->xfer_len = 0U;
+      }
+      /* configure and validate Rx endpoint */
+      PCD_SET_EP_RX_CNT(USBx, ep->num, len);
     }
     else
     {
-      PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
+      /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
+      /* Set the Double buffer counter */
+      if (ep->type == EP_TYPE_BULK)
+      {
+        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
+
+        /* Coming from ISR */
+        if (ep->xfer_count != 0U)
+        {
+          /* update last value to check if there is blocking state */
+          wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
+
+          /*Blocking State */
+          if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
+              (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
+          {
+            PCD_FreeUserBuffer(USBx, ep->num, 0U);
+          }
+        }
+      }
+      /* iso out double */
+      else if (ep->type == EP_TYPE_ISOC)
+      {
+        /* Multi packet transfer */
+        if (ep->xfer_len > ep->maxpacket)
+        {
+          len = ep->maxpacket;
+          ep->xfer_len -= len;
+        }
+        else
+        {
+          len = ep->xfer_len;
+          ep->xfer_len = 0U;
+        }
+        PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
+      }
+      else
+      {
+        return HAL_ERROR;
+      }
     }
-  }
-  else
-  {
+
     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
   }
 
   return HAL_OK;
 }
 
-/**
-  * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
-  *         with the EP/channel
-  * @param  USBx : Selected device
-  * @param  src :  pointer to source buffer
-  * @param  ch_ep_num : endpoint or host channel number
-  * @param  len : Number of bytes to write
-  * @retval HAL status
-  */
-HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  UNUSED(src);
-  UNUSED(ch_ep_num);
-  UNUSED(len);
-  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
-              only by USB OTG FS peripheral.
-            - This function is added to ensure compatibility across platforms.
-   */
-  return HAL_OK;
-}
 
 /**
-  * @brief  USB_ReadPacket : read a packet from the Tx FIFO associated
-  *         with the EP/channel
-  * @param  USBx : Selected device
-  * @param  dest : destination pointer
-  * @param  len : Number of bytes to read
-  * @retval pointer to destination buffer
-  */
-void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(USBx);
-  UNUSED(dest);
-  UNUSED(len);
-  /* NOTE : - This function is not required by USB Device FS peripheral, it is used
-              only by USB OTG FS peripheral.
-            - This function is added to ensure compatibility across platforms.
-   */
-  return ((void *)NULL);
-}
-
-/**
-  * @brief  USB_EPSetStall : set a stall condition over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @brief  USB_EPSetStall set a stall condition over an EP
+  * @param  USBx Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
-HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 {
-  if (ep->num == 0)
+  if (ep->is_in != 0U)
   {
-    /* This macro sets STALL status for RX & TX*/
-    PCD_SET_EP_TXRX_STATUS(USBx, ep->num, USB_EP_RX_STALL, USB_EP_TX_STALL);
+    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
   }
   else
   {
-    if (ep->is_in)
-    {
-      PCD_SET_EP_TX_STATUS(USBx, ep->num , USB_EP_TX_STALL);
-    }
-    else
-    {
-      PCD_SET_EP_RX_STATUS(USBx, ep->num , USB_EP_RX_STALL);
-    }
+    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
   }
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_EPClearStall : Clear a stall condition over an EP
-  * @param  USBx : Selected device
-  * @param  ep: pointer to endpoint structure
+  * @brief  USB_EPClearStall Clear a stall condition over an EP
+  * @param  USBx Selected device
+  * @param  ep pointer to endpoint structure
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
 {
-  if (ep->is_in)
-  {
-    PCD_CLEAR_TX_DTOG(USBx, ep->num);
-    PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
-  }
-  else
+  if (ep->doublebuffer == 0U)
   {
-    PCD_CLEAR_RX_DTOG(USBx, ep->num);
-    PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+    if (ep->is_in != 0U)
+    {
+      PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
+      if (ep->type != EP_TYPE_ISOC)
+      {
+        /* Configure NAK status for the Endpoint */
+        PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+      }
+    }
+    else
+    {
+      PCD_CLEAR_RX_DTOG(USBx, ep->num);
+
+      /* Configure VALID status for the Endpoint */
+      PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+    }
   }
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_StopDevice : Stop the usb device mode
-  * @param  USBx : Selected device
+  * @brief  USB_StopDevice Stop the usb device mode
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
 {
   /* disable all interrupts and force USB reset */
-  USBx->CNTR = USB_CNTR_FRES;
+  USBx->CNTR = (uint16_t)USB_CNTR_FRES;
 
   /* clear interrupt status register */
-  USBx->ISTR = 0;
+  USBx->ISTR = 0U;
 
   /* switch-off device */
-  USBx->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN);
+  USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_SetDevAddress : Stop the usb device mode
-  * @param  USBx : Selected device
-  * @param  address : new device address to be assigned
+  * @brief  USB_SetDevAddress Stop the usb device mode
+  * @param  USBx Selected device
+  * @param  address new device address to be assigned
   *          This parameter can be a value from 0 to 255
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address)
+HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
 {
-  if(address == 0)
+  if (address == 0U)
   {
-   /* set device address and enable function */
-   USBx->DADDR = USB_DADDR_EF;
+    /* set device address and enable function */
+    USBx->DADDR = (uint16_t)USB_DADDR_EF;
   }
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
-  * @param  USBx : Selected device
+  * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
+  * @param  USBx Selected device
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_DevConnect (USB_TypeDef *USBx)
+HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
+
   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
               only by USB OTG FS peripheral.
             - This function is added to ensure compatibility across platforms.
    */
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
-  * @param  USBx : Selected device
+  * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
+  * @param  USBx Selected device
   * @retval HAL status
   */
-HAL_StatusTypeDef  USB_DevDisconnect (USB_TypeDef *USBx)
+HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
+
   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
               only by USB OTG FS peripheral.
             - This function is added to ensure compatibility across platforms.
    */
+
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_ReadInterrupts: return the global USB interrupt status
-  * @param  USBx : Selected device
+  * @brief  USB_ReadInterrupts return the global USB interrupt status
+  * @param  USBx Selected device
   * @retval HAL status
   */
-uint32_t  USB_ReadInterrupts (USB_TypeDef *USBx)
+uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
 {
-  uint32_t tmpreg = 0;
+  uint32_t tmpreg;
 
   tmpreg = USBx->ISTR;
   return tmpreg;
 }
 
 /**
-  * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
-  * @param  USBx : Selected device
+  * @brief  USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
+  * @param  USBx Selected device
   * @retval HAL status
   */
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx)
+uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
@@ -2070,11 +2430,11 @@ uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx)
 }
 
 /**
-  * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
-  * @param  USBx : Selected device
+  * @brief  USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
+  * @param  USBx Selected device
   * @retval HAL status
   */
-uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx)
+uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
@@ -2087,12 +2447,12 @@ uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx)
 
 /**
   * @brief  Returns Device OUT EP Interrupt register
-  * @param  USBx : Selected device
-  * @param  epnum : endpoint number
+  * @param  USBx Selected device
+  * @param  epnum endpoint number
   *          This parameter can be a value from 0 to 15
   * @retval Device OUT EP Interrupt register
   */
-uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
@@ -2106,12 +2466,12 @@ uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
 
 /**
   * @brief  Returns Device IN EP Interrupt register
-  * @param  USBx : Selected device
-  * @param  epnum : endpoint number
+  * @param  USBx Selected device
+  * @param  epnum endpoint number
   *          This parameter can be a value from 0 to 15
   * @retval Device IN EP Interrupt register
   */
-uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
@@ -2125,11 +2485,11 @@ uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
 
 /**
   * @brief  USB_ClearInterrupts: clear a USB interrupt
-  * @param  USBx : Selected device
-  * @param  interrupt : interrupt flag
+  * @param  USBx Selected device
+  * @param  interrupt  flag
   * @retval None
   */
-void  USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt)
+void  USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
 {
   /* Prevent unused argument(s) compilation warning */
   UNUSED(USBx);
@@ -2142,8 +2502,8 @@ void  USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt)
 
 /**
   * @brief  Prepare the EP0 to start the first control setup
-  * @param  USBx : Selected device
-  * @param  psetup : pointer to setup packet
+  * @param  USBx Selected device
+  * @param  psetup pointer to setup packet
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
@@ -2160,139 +2520,114 @@ HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
 
 /**
   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
-  * @param  USBx : Selected device
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
 {
-  USBx->CNTR |= USB_CNTR_RESUME;
+  USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
 
   return HAL_OK;
 }
 
 /**
-  * @brief  USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
-  * @param  USBx : Selected device
+  * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
+  * @param  USBx Selected device
   * @retval HAL status
   */
 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
 {
-  USBx->CNTR &= ~(USB_CNTR_RESUME);
+  USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
+
   return HAL_OK;
 }
 
 /**
-  * @brief  Copy a buffer from user memory area to packet memory area (PMA)
-  * @param  USBx : pointer to USB register.
-  * @param  pbUsrBuf : pointer to user memory area.
-  * @param  wPMABufAddr : address into PMA.
-  * @param  wNBytes : number of bytes to be copied.
+  * @brief Copy a buffer from user memory area to packet memory area (PMA)
+  * @param   USBx USB peripheral instance register address.
+  * @param   pbUsrBuf pointer to user memory area.
+  * @param   wPMABufAddr address into PMA.
+  * @param   wNBytes no. of bytes to be copied.
   * @retval None
   */
 void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
 {
-  uint32_t nbytes = (wNBytes + 1) >> 1;   /* nbytes = (wNBytes + 1) / 2 */
-  uint32_t index = 0, temp1 = 0, temp2 = 0;
-  uint16_t *pdwVal = NULL;
+  uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
+  uint32_t BaseAddr = (uint32_t)USBx;
+  uint32_t i, temp1, temp2;
+  __IO uint16_t *pdwVal;
+  uint8_t *pBuf = pbUsrBuf;
+
+  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
 
-  pdwVal = (uint16_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
-  for (index = nbytes; index != 0; index--)
+  for (i = n; i != 0U; i--)
   {
-    temp1 = (uint16_t) * pbUsrBuf;
-    pbUsrBuf++;
-    temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
-    *pdwVal++ = temp2;
+    temp1 = *pBuf;
+    pBuf++;
+    temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
+    *pdwVal = (uint16_t)temp2;
     pdwVal++;
-    pbUsrBuf++;
+
+#if PMA_ACCESS > 1U
+    pdwVal++;
+#endif
+
+    pBuf++;
   }
 }
 
 /**
-  * @brief  Copy a buffer from user memory area to packet memory area (PMA)
-  * @param  USBx : pointer to USB register.
-* @param  pbUsrBuf : pointer to user memory area.
-  * @param  wPMABufAddr : address into PMA.
-  * @param  wNBytes : number of bytes to be copied.
+  * @brief Copy data from packet memory area (PMA) to user memory buffer
+  * @param   USBx USB peripheral instance register address.
+  * @param   pbUsrBuf pointer to user memory area.
+  * @param   wPMABufAddr address into PMA.
+  * @param   wNBytes no. of bytes to be copied.
   * @retval None
   */
 void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
 {
-  uint32_t nbytes = (wNBytes + 1) >> 1;/* /2*/
-  uint32_t index = 0;
-  uint32_t *pdwVal = NULL;
+  uint32_t n = (uint32_t)wNBytes >> 1;
+  uint32_t BaseAddr = (uint32_t)USBx;
+  uint32_t i, temp;
+  __IO uint16_t *pdwVal;
+  uint8_t *pBuf = pbUsrBuf;
 
-  pdwVal = (uint32_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
-  for (index = nbytes; index != 0; index--)
-  {
-    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
-    pbUsrBuf++;
-  }
-}
-
-#endif /* USB */
-
-/**
-  * @}
-  */
-/**
-  * @}
-  */
+  pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
 
-#if defined (USB_OTG_FS)
-/** @addtogroup USB_LL_Private_Functions
-  * @{
-  */
-/**
-  * @brief  Reset the USB Core (needed after USB clock settings change)
-  * @param  USBx : Selected device
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
-{
-  uint32_t count = 0;
-
-  /* Wait for AHB master IDLE state. */
-  do
+  for (i = n; i != 0U; i--)
   {
-    if (++count > 200000)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-  while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
+    temp = *(__IO uint16_t *)pdwVal;
+    pdwVal++;
+    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
+    pBuf++;
+    *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
+    pBuf++;
 
-  /* Core Soft Reset */
-  count = 0;
-  USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+#if PMA_ACCESS > 1U
+    pdwVal++;
+#endif
+  }
 
-  do
+  if ((wNBytes % 2U) != 0U)
   {
-    if (++count > 200000)
-    {
-      return HAL_TIMEOUT;
-    }
+    temp = *pdwVal;
+    *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
   }
-  while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
-
-  return HAL_OK;
 }
+#endif /* defined (USB) */
+
 /**
   * @}
   */
-#endif /* USB_OTG_FS */
-
-#endif /* STM32F102x6 || STM32F102xB || */
-       /* STM32F103x6 || STM32F103xB || */
-       /* STM32F103xE || STM32F103xG || */
-       /* STM32F105xC || STM32F107xC    */
-
-#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
 
 /**
   * @}
   */
+#endif /* defined (USB) || defined (USB_OTG_FS) */
+#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
 
 /**
   * @}
   */
+
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/system/Drivers/STM32YYxx_HAL_Driver_version.md b/system/Drivers/STM32YYxx_HAL_Driver_version.md
index c1aeeca37c..48287df0cc 100644
--- a/system/Drivers/STM32YYxx_HAL_Driver_version.md
+++ b/system/Drivers/STM32YYxx_HAL_Driver_version.md
@@ -1,7 +1,7 @@
 # STM32YYxx HAL Drivers version:
 
   * STM32F0: 1.7.4
-  * STM32F1: 1.1.4
+  * STM32F1: 1.1.5
   * STM32F2: 1.2.4
   * STM32F3: 1.5.4
   * STM32F4: 1.7.8