1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_pcd.h
4   * @author  MCD Application Team
5   * @brief   Header file of PCD HAL module.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2017 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 
19 /* Define to prevent recursive inclusion -------------------------------------*/
20 #ifndef STM32L4xx_HAL_PCD_H
21 #define STM32L4xx_HAL_PCD_H
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /* Includes ------------------------------------------------------------------*/
28 #include "stm32l4xx_ll_usb.h"
29 
30 #if defined (USB) || defined (USB_OTG_FS)
31 
32 /** @addtogroup STM32L4xx_HAL_Driver
33   * @{
34   */
35 
36 /** @addtogroup PCD
37   * @{
38   */
39 
40 /* Exported types ------------------------------------------------------------*/
41 /** @defgroup PCD_Exported_Types PCD Exported Types
42   * @{
43   */
44 
45 /**
46   * @brief  PCD State structure definition
47   */
48 typedef enum
49 {
50   HAL_PCD_STATE_RESET   = 0x00,
51   HAL_PCD_STATE_READY   = 0x01,
52   HAL_PCD_STATE_ERROR   = 0x02,
53   HAL_PCD_STATE_BUSY    = 0x03,
54   HAL_PCD_STATE_TIMEOUT = 0x04
55 } PCD_StateTypeDef;
56 
57 /* Device LPM suspend state */
58 typedef enum
59 {
60   LPM_L0 = 0x00, /* on */
61   LPM_L1 = 0x01, /* LPM L1 sleep */
62   LPM_L2 = 0x02, /* suspend */
63   LPM_L3 = 0x03, /* off */
64 } PCD_LPM_StateTypeDef;
65 
66 typedef enum
67 {
68   PCD_LPM_L0_ACTIVE = 0x00, /* on */
69   PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
70 } PCD_LPM_MsgTypeDef;
71 
72 typedef enum
73 {
74   PCD_BCD_ERROR                     = 0xFF,
75   PCD_BCD_CONTACT_DETECTION         = 0xFE,
76   PCD_BCD_STD_DOWNSTREAM_PORT       = 0xFD,
77   PCD_BCD_CHARGING_DOWNSTREAM_PORT  = 0xFC,
78   PCD_BCD_DEDICATED_CHARGING_PORT   = 0xFB,
79   PCD_BCD_DISCOVERY_COMPLETED       = 0x00,
80 
81 } PCD_BCD_MsgTypeDef;
82 
83 #if defined (USB)
84 
85 #endif /* defined (USB) */
86 #if defined (USB_OTG_FS)
87 typedef USB_OTG_GlobalTypeDef  PCD_TypeDef;
88 typedef USB_OTG_CfgTypeDef     PCD_InitTypeDef;
89 typedef USB_OTG_EPTypeDef      PCD_EPTypeDef;
90 #endif /* defined (USB_OTG_FS) */
91 #if defined (USB)
92 typedef USB_TypeDef        PCD_TypeDef;
93 typedef USB_CfgTypeDef     PCD_InitTypeDef;
94 typedef USB_EPTypeDef      PCD_EPTypeDef;
95 #endif /* defined (USB) */
96 
97 /**
98   * @brief  PCD Handle Structure definition
99   */
100 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
101 typedef struct __PCD_HandleTypeDef
102 #else
103 typedef struct
104 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
105 {
106   PCD_TypeDef             *Instance;   /*!< Register base address             */
107   PCD_InitTypeDef         Init;        /*!< PCD required parameters           */
108   __IO uint8_t            USB_Address; /*!< USB Address                       */
109 #if defined (USB_OTG_FS)
110   PCD_EPTypeDef           IN_ep[16];   /*!< IN endpoint parameters            */
111   PCD_EPTypeDef           OUT_ep[16];  /*!< OUT endpoint parameters           */
112 #endif /* defined (USB_OTG_FS) */
113 #if defined (USB)
114   PCD_EPTypeDef           IN_ep[8];    /*!< IN endpoint parameters            */
115   PCD_EPTypeDef           OUT_ep[8];   /*!< OUT endpoint parameters           */
116 #endif /* defined (USB) */
117   HAL_LockTypeDef         Lock;        /*!< PCD peripheral status             */
118   __IO PCD_StateTypeDef   State;       /*!< PCD communication state           */
119   __IO  uint32_t          ErrorCode;   /*!< PCD Error code                    */
120   uint32_t                Setup[12];   /*!< Setup packet buffer               */
121   PCD_LPM_StateTypeDef    LPM_State;   /*!< LPM State                         */
122   uint32_t                BESL;
123   uint32_t                FrameNumber; /*!< Store Current Frame number        */
124 
125 
126   uint32_t lpm_active;                 /*!< Enable or disable the Link Power Management .
127                                        This parameter can be set to ENABLE or DISABLE        */
128 
129   uint32_t battery_charging_active;    /*!< Enable or disable Battery charging.
130                                        This parameter can be set to ENABLE or DISABLE        */
131   void                    *pData;      /*!< Pointer to upper stack Handler */
132 
133 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
134   void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd);                              /*!< USB OTG PCD SOF callback                */
135   void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd);                       /*!< USB OTG PCD Setup Stage callback        */
136   void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd);                            /*!< USB OTG PCD Reset callback              */
137   void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Suspend callback            */
138   void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd);                           /*!< USB OTG PCD Resume callback             */
139   void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Connect callback            */
140   void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd);                       /*!< USB OTG PCD Disconnect callback         */
141 
142   void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);      /*!< USB OTG PCD Data OUT Stage callback     */
143   void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);       /*!< USB OTG PCD Data IN Stage callback      */
144   void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);  /*!< USB OTG PCD ISO OUT Incomplete callback */
145   void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum);   /*!< USB OTG PCD ISO IN Incomplete callback  */
146   void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg);      /*!< USB OTG PCD BCD callback                */
147   void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg);      /*!< USB OTG PCD LPM callback                */
148 
149   void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd);                          /*!< USB OTG PCD Msp Init callback           */
150   void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd);                        /*!< USB OTG PCD Msp DeInit callback         */
151 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
152 } PCD_HandleTypeDef;
153 
154 /**
155   * @}
156   */
157 
158 /* Include PCD HAL Extended module */
159 #include "stm32l4xx_hal_pcd_ex.h"
160 
161 /* Exported constants --------------------------------------------------------*/
162 /** @defgroup PCD_Exported_Constants PCD Exported Constants
163   * @{
164   */
165 
166 /** @defgroup PCD_Speed PCD Speed
167   * @{
168   */
169 #define PCD_SPEED_FULL               USBD_FS_SPEED
170 /**
171   * @}
172   */
173 
174 /** @defgroup PCD_PHY_Module PCD PHY Module
175   * @{
176   */
177 #define PCD_PHY_ULPI                 1U
178 #define PCD_PHY_EMBEDDED             2U
179 #define PCD_PHY_UTMI                 3U
180 /**
181   * @}
182   */
183 
184 /** @defgroup PCD_Error_Code_definition PCD Error Code definition
185   * @brief  PCD Error Code definition
186   * @{
187   */
188 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
189 #define  HAL_PCD_ERROR_INVALID_CALLBACK                        (0x00000010U)    /*!< Invalid Callback error  */
190 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
191 
192 /**
193   * @}
194   */
195 
196 /**
197   * @}
198   */
199 
200 /* Exported macros -----------------------------------------------------------*/
201 /** @defgroup PCD_Exported_Macros PCD Exported Macros
202   *  @brief macros to handle interrupts and specific clock configurations
203   * @{
204   */
205 #define __HAL_PCD_ENABLE(__HANDLE__)                       (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
206 #define __HAL_PCD_DISABLE(__HANDLE__)                      (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
207 
208 #define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \
209   ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
210 
211 #if defined (USB_OTG_FS)
212 #define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)    (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__))
213 #define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__)         (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
214 
215 #define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \
216   *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
217 
218 #define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \
219   *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
220 
221 #define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \
222   ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
223 
224 #define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT()    EXTI->IMR1 |= USB_OTG_FS_WAKEUP_EXTI_LINE
225 #define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT()   EXTI->IMR1 &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
226 #endif /* defined (USB_OTG_FS) */
227 
228 #if defined (USB)
229 #define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)           (((__HANDLE__)->Instance->ISTR)\
230                                                                    &= (uint16_t)(~(__INTERRUPT__)))
231 
232 #define __HAL_USB_WAKEUP_EXTI_ENABLE_IT()                         EXTI->IMR1 |= USB_WAKEUP_EXTI_LINE
233 #define __HAL_USB_WAKEUP_EXTI_DISABLE_IT()                        EXTI->IMR1 &= ~(USB_WAKEUP_EXTI_LINE)
234 #endif /* defined (USB) */
235 
236 /**
237   * @}
238   */
239 
240 /* Exported functions --------------------------------------------------------*/
241 /** @addtogroup PCD_Exported_Functions PCD Exported Functions
242   * @{
243   */
244 
245 /* Initialization/de-initialization functions  ********************************/
246 /** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
247   * @{
248   */
249 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
250 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
251 void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
252 void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
253 
254 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
255 /** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
256   * @brief  HAL USB OTG PCD Callback ID enumeration definition
257   * @{
258   */
259 typedef enum
260 {
261   HAL_PCD_SOF_CB_ID          = 0x01,      /*!< USB PCD SOF callback ID          */
262   HAL_PCD_SETUPSTAGE_CB_ID   = 0x02,      /*!< USB PCD Setup Stage callback ID  */
263   HAL_PCD_RESET_CB_ID        = 0x03,      /*!< USB PCD Reset callback ID        */
264   HAL_PCD_SUSPEND_CB_ID      = 0x04,      /*!< USB PCD Suspend callback ID      */
265   HAL_PCD_RESUME_CB_ID       = 0x05,      /*!< USB PCD Resume callback ID       */
266   HAL_PCD_CONNECT_CB_ID      = 0x06,      /*!< USB PCD Connect callback ID      */
267   HAL_PCD_DISCONNECT_CB_ID   = 0x07,      /*!< USB PCD Disconnect callback ID   */
268 
269   HAL_PCD_MSPINIT_CB_ID      = 0x08,      /*!< USB PCD MspInit callback ID      */
270   HAL_PCD_MSPDEINIT_CB_ID    = 0x09       /*!< USB PCD MspDeInit callback ID    */
271 
272 } HAL_PCD_CallbackIDTypeDef;
273 /**
274   * @}
275   */
276 
277 /** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
278   * @brief  HAL USB OTG PCD Callback pointer definition
279   * @{
280   */
281 
282 typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd);                                   /*!< pointer to a common USB OTG PCD callback function  */
283 typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);        /*!< pointer to USB OTG PCD Data OUT Stage callback     */
284 typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);         /*!< pointer to USB OTG PCD Data IN Stage callback      */
285 typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);        /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */
286 typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum);         /*!< pointer to USB OTG PCD ISO IN Incomplete callback  */
287 typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg);        /*!< pointer to USB OTG PCD LPM callback                */
288 typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg);        /*!< pointer to USB OTG PCD BCD callback                */
289 
290 /**
291   * @}
292   */
293 
294 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID,
295                                            pPCD_CallbackTypeDef pCallback);
296 
297 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID);
298 
299 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
300                                                        pPCD_DataOutStageCallbackTypeDef pCallback);
301 
302 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd);
303 
304 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
305                                                       pPCD_DataInStageCallbackTypeDef pCallback);
306 
307 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd);
308 
309 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
310                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback);
311 
312 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd);
313 
314 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
315                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback);
316 
317 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd);
318 
319 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback);
320 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd);
321 
322 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback);
323 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd);
324 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
325 /**
326   * @}
327   */
328 
329 /* I/O operation functions  ***************************************************/
330 /* Non-Blocking mode: Interrupt */
331 /** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
332   * @{
333   */
334 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
335 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
336 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
337 
338 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
339 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
340 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
341 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
342 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
343 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
344 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
345 
346 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
347 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
348 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
349 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
350 /**
351   * @}
352   */
353 
354 /* Peripheral Control functions  **********************************************/
355 /** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
356   * @{
357   */
358 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
359 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
360 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
361 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type);
362 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
363 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
364 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
365 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
366 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
367 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
368 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
369 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
370 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
371 uint32_t          HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr);
372 /**
373   * @}
374   */
375 
376 /* Peripheral State functions  ************************************************/
377 /** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
378   * @{
379   */
380 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd);
381 /**
382   * @}
383   */
384 
385 /**
386   * @}
387   */
388 
389 /* Private constants ---------------------------------------------------------*/
390 /** @defgroup PCD_Private_Constants PCD Private Constants
391   * @{
392   */
393 /** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
394   * @{
395   */
396 #if defined (USB_OTG_FS)
397 #define USB_OTG_FS_WAKEUP_EXTI_LINE                                   (0x1U << 17)  /*!< USB FS EXTI Line WakeUp Interrupt */
398 #endif /* defined (USB_OTG_FS) */
399 
400 #if defined (USB)
401 #define USB_WAKEUP_EXTI_LINE                                          (0x1U << 17)  /*!< USB FS EXTI Line WakeUp Interrupt */
402 #endif /* defined (USB) */
403 
404 /**
405   * @}
406   */
407 #if defined (USB)
408 /** @defgroup PCD_EP0_MPS PCD EP0 MPS
409   * @{
410   */
411 #define PCD_EP0MPS_64                                                 EP_MPS_64
412 #define PCD_EP0MPS_32                                                 EP_MPS_32
413 #define PCD_EP0MPS_16                                                 EP_MPS_16
414 #define PCD_EP0MPS_08                                                 EP_MPS_8
415 /**
416   * @}
417   */
418 
419 /** @defgroup PCD_ENDP PCD ENDP
420   * @{
421   */
422 #define PCD_ENDP0                                                     0U
423 #define PCD_ENDP1                                                     1U
424 #define PCD_ENDP2                                                     2U
425 #define PCD_ENDP3                                                     3U
426 #define PCD_ENDP4                                                     4U
427 #define PCD_ENDP5                                                     5U
428 #define PCD_ENDP6                                                     6U
429 #define PCD_ENDP7                                                     7U
430 /**
431   * @}
432   */
433 
434 /** @defgroup PCD_ENDP_Kind PCD Endpoint Kind
435   * @{
436   */
437 #define PCD_SNG_BUF                                                   0U
438 #define PCD_DBL_BUF                                                   1U
439 /**
440   * @}
441   */
442 #endif /* defined (USB) */
443 /**
444   * @}
445   */
446 
447 #if defined (USB_OTG_FS)
448 #ifndef USB_OTG_DOEPINT_OTEPSPR
449 #define USB_OTG_DOEPINT_OTEPSPR                (0x1UL << 5)      /*!< Status Phase Received interrupt */
450 #endif /* defined USB_OTG_DOEPINT_OTEPSPR */
451 
452 #ifndef USB_OTG_DOEPMSK_OTEPSPRM
453 #define USB_OTG_DOEPMSK_OTEPSPRM               (0x1UL << 5)      /*!< Setup Packet Received interrupt mask */
454 #endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */
455 
456 #ifndef USB_OTG_DOEPINT_NAK
457 #define USB_OTG_DOEPINT_NAK                    (0x1UL << 13)      /*!< NAK interrupt */
458 #endif /* defined USB_OTG_DOEPINT_NAK */
459 
460 #ifndef USB_OTG_DOEPMSK_NAKM
461 #define USB_OTG_DOEPMSK_NAKM                   (0x1UL << 13)      /*!< OUT Packet NAK interrupt mask */
462 #endif /* defined USB_OTG_DOEPMSK_NAKM */
463 
464 #ifndef USB_OTG_DOEPINT_STPKTRX
465 #define USB_OTG_DOEPINT_STPKTRX                (0x1UL << 15)      /*!< Setup Packet Received interrupt */
466 #endif /* defined USB_OTG_DOEPINT_STPKTRX */
467 
468 #ifndef USB_OTG_DOEPMSK_NYETM
469 #define USB_OTG_DOEPMSK_NYETM                  (0x1UL << 14)      /*!< Setup Packet Received interrupt mask */
470 #endif /* defined USB_OTG_DOEPMSK_NYETM */
471 #endif /* defined (USB_OTG_FS) */
472 
473 /* Private macros ------------------------------------------------------------*/
474 /** @defgroup PCD_Private_Macros PCD Private Macros
475   * @{
476   */
477 #if defined (USB)
478 /********************  Bit definition for USB_COUNTn_RX register  *************/
479 #define USB_CNTRX_NBLK_MSK                    (0x1FU << 10)
480 #define USB_CNTRX_BLSIZE                      (0x1U << 15)
481 
482 /* SetENDPOINT */
483 #define PCD_SET_ENDPOINT(USBx, bEpNum, wRegValue) \
484   (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)) = (uint16_t)(wRegValue))
485 
486 /* GetENDPOINT */
487 #define PCD_GET_ENDPOINT(USBx, bEpNum)             (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)))
488 
489 
490 /**
491   * @brief  sets the type in the endpoint register(bits EP_TYPE[1:0])
492   * @param  USBx USB peripheral instance register address.
493   * @param  bEpNum Endpoint Number.
494   * @param  wType Endpoint Type.
495   * @retval None
496   */
497 #define PCD_SET_EPTYPE(USBx, bEpNum, wType) \
498   (PCD_SET_ENDPOINT((USBx), (bEpNum), \
499                     ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) | USB_EP_CTR_TX | USB_EP_CTR_RX)))
500 
501 
502 /**
503   * @brief  gets the type in the endpoint register(bits EP_TYPE[1:0])
504   * @param  USBx USB peripheral instance register address.
505   * @param  bEpNum Endpoint Number.
506   * @retval Endpoint Type
507   */
508 #define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD)
509 
510 /**
511   * @brief free buffer used from the application realizing it to the line
512   *         toggles bit SW_BUF in the double buffered endpoint register
513   * @param USBx USB device.
514   * @param   bEpNum, bDir
515   * @retval None
516   */
517 #define PCD_FREE_USER_BUFFER(USBx, bEpNum, bDir) \
518   do { \
519     if ((bDir) == 0U) \
520     { \
521       /* OUT double buffered endpoint */ \
522       PCD_TX_DTOG((USBx), (bEpNum)); \
523     } \
524     else if ((bDir) == 1U) \
525     { \
526       /* IN double buffered endpoint */ \
527       PCD_RX_DTOG((USBx), (bEpNum)); \
528     } \
529   } while(0)
530 
531 /**
532   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]).
533   * @param  USBx USB peripheral instance register address.
534   * @param  bEpNum Endpoint Number.
535   * @param  wState new state
536   * @retval None
537   */
538 #define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) \
539   do { \
540     uint16_t _wRegVal; \
541     \
542     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK; \
543     /* toggle first bit ? */ \
544     if ((USB_EPTX_DTOG1 & (wState))!= 0U) \
545     { \
546       _wRegVal ^= USB_EPTX_DTOG1; \
547     } \
548     /* toggle second bit ?  */ \
549     if ((USB_EPTX_DTOG2 & (wState))!= 0U) \
550     { \
551       _wRegVal ^= USB_EPTX_DTOG2; \
552     } \
553     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
554   } while(0) /* PCD_SET_EP_TX_STATUS */
555 
556 /**
557   * @brief  sets the status for rx transfer (bits STAT_TX[1:0])
558   * @param  USBx USB peripheral instance register address.
559   * @param  bEpNum Endpoint Number.
560   * @param  wState new state
561   * @retval None
562   */
563 #define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) \
564   do { \
565     uint16_t _wRegVal; \
566     \
567     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK; \
568     /* toggle first bit ? */ \
569     if ((USB_EPRX_DTOG1 & (wState))!= 0U) \
570     { \
571       _wRegVal ^= USB_EPRX_DTOG1; \
572     } \
573     /* toggle second bit ? */ \
574     if ((USB_EPRX_DTOG2 & (wState))!= 0U) \
575     { \
576       _wRegVal ^= USB_EPRX_DTOG2; \
577     } \
578     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
579   } while(0) /* PCD_SET_EP_RX_STATUS */
580 
581 /**
582   * @brief  sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
583   * @param  USBx USB peripheral instance register address.
584   * @param  bEpNum Endpoint Number.
585   * @param  wStaterx new state.
586   * @param  wStatetx new state.
587   * @retval None
588   */
589 #define PCD_SET_EP_TXRX_STATUS(USBx, bEpNum, wStaterx, wStatetx) \
590   do { \
591     uint16_t _wRegVal; \
592     \
593     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK | USB_EPTX_STAT); \
594     /* toggle first bit ? */ \
595     if ((USB_EPRX_DTOG1 & (wStaterx))!= 0U) \
596     { \
597       _wRegVal ^= USB_EPRX_DTOG1; \
598     } \
599     /* toggle second bit ? */ \
600     if ((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
601     { \
602       _wRegVal ^= USB_EPRX_DTOG2; \
603     } \
604     /* toggle first bit ? */ \
605     if ((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \
606     { \
607       _wRegVal ^= USB_EPTX_DTOG1; \
608     } \
609     /* toggle second bit ?  */ \
610     if ((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \
611     { \
612       _wRegVal ^= USB_EPTX_DTOG2; \
613     } \
614     \
615     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
616   } while(0) /* PCD_SET_EP_TXRX_STATUS */
617 
618 /**
619   * @brief  gets the status for tx/rx transfer (bits STAT_TX[1:0]
620   *         /STAT_RX[1:0])
621   * @param  USBx USB peripheral instance register address.
622   * @param  bEpNum Endpoint Number.
623   * @retval status
624   */
625 #define PCD_GET_EP_TX_STATUS(USBx, bEpNum)     ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT)
626 #define PCD_GET_EP_RX_STATUS(USBx, bEpNum)     ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT)
627 
628 /**
629   * @brief  sets directly the VALID tx/rx-status into the endpoint register
630   * @param  USBx USB peripheral instance register address.
631   * @param  bEpNum Endpoint Number.
632   * @retval None
633   */
634 #define PCD_SET_EP_TX_VALID(USBx, bEpNum)      (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID))
635 #define PCD_SET_EP_RX_VALID(USBx, bEpNum)      (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID))
636 
637 /**
638   * @brief  checks stall condition in an endpoint.
639   * @param  USBx USB peripheral instance register address.
640   * @param  bEpNum Endpoint Number.
641   * @retval TRUE = endpoint in stall condition.
642   */
643 #define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) == USB_EP_TX_STALL)
644 #define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) == USB_EP_RX_STALL)
645 
646 /**
647   * @brief  set & clear EP_KIND bit.
648   * @param  USBx USB peripheral instance register address.
649   * @param  bEpNum Endpoint Number.
650   * @retval None
651   */
652 #define PCD_SET_EP_KIND(USBx, bEpNum) \
653   do { \
654     uint16_t _wRegVal; \
655     \
656     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
657     \
658     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_KIND)); \
659   } while(0) /* PCD_SET_EP_KIND */
660 
661 #define PCD_CLEAR_EP_KIND(USBx, bEpNum) \
662   do { \
663     uint16_t _wRegVal; \
664     \
665     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK; \
666     \
667     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
668   } while(0) /* PCD_CLEAR_EP_KIND */
669 
670 /**
671   * @brief  Sets/clears directly STATUS_OUT bit in the endpoint register.
672   * @param  USBx USB peripheral instance register address.
673   * @param  bEpNum Endpoint Number.
674   * @retval None
675   */
676 #define PCD_SET_OUT_STATUS(USBx, bEpNum)       PCD_SET_EP_KIND((USBx), (bEpNum))
677 #define PCD_CLEAR_OUT_STATUS(USBx, bEpNum)     PCD_CLEAR_EP_KIND((USBx), (bEpNum))
678 
679 /**
680   * @brief  Sets/clears directly EP_KIND bit in the endpoint register.
681   * @param  USBx USB peripheral instance register address.
682   * @param  bEpNum Endpoint Number.
683   * @retval None
684   */
685 #define PCD_SET_BULK_EP_DBUF(USBx, bEpNum)     PCD_SET_EP_KIND((USBx), (bEpNum))
686 #define PCD_CLEAR_BULK_EP_DBUF(USBx, bEpNum)   PCD_CLEAR_EP_KIND((USBx), (bEpNum))
687 
688 /**
689   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register.
690   * @param  USBx USB peripheral instance register address.
691   * @param  bEpNum Endpoint Number.
692   * @retval None
693   */
694 #define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) \
695   do { \
696     uint16_t _wRegVal; \
697     \
698     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \
699     \
700     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_TX)); \
701   } while(0) /* PCD_CLEAR_RX_EP_CTR */
702 
703 #define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) \
704   do { \
705     uint16_t _wRegVal; \
706     \
707     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \
708     \
709     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX)); \
710   } while(0) /* PCD_CLEAR_TX_EP_CTR */
711 
712 /**
713   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
714   * @param  USBx USB peripheral instance register address.
715   * @param  bEpNum Endpoint Number.
716   * @retval None
717   */
718 #define PCD_RX_DTOG(USBx, bEpNum) \
719   do { \
720     uint16_t _wEPVal; \
721     \
722     _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
723     \
724     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_RX)); \
725   } while(0) /* PCD_RX_DTOG */
726 
727 #define PCD_TX_DTOG(USBx, bEpNum) \
728   do { \
729     uint16_t _wEPVal; \
730     \
731     _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
732     \
733     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_TX)); \
734   } while(0) /* PCD_TX_DTOG */
735 /**
736   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register.
737   * @param  USBx USB peripheral instance register address.
738   * @param  bEpNum Endpoint Number.
739   * @retval None
740   */
741 #define PCD_CLEAR_RX_DTOG(USBx, bEpNum) \
742   do { \
743     uint16_t _wRegVal; \
744     \
745     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
746     \
747     if ((_wRegVal & USB_EP_DTOG_RX) != 0U)\
748     { \
749       PCD_RX_DTOG((USBx), (bEpNum)); \
750     } \
751   } while(0) /* PCD_CLEAR_RX_DTOG */
752 
753 #define PCD_CLEAR_TX_DTOG(USBx, bEpNum) \
754   do { \
755     uint16_t _wRegVal; \
756     \
757     _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
758     \
759     if ((_wRegVal & USB_EP_DTOG_TX) != 0U)\
760     { \
761       PCD_TX_DTOG((USBx), (bEpNum)); \
762     } \
763   } while(0) /* PCD_CLEAR_TX_DTOG */
764 
765 /**
766   * @brief  Sets address in an endpoint register.
767   * @param  USBx USB peripheral instance register address.
768   * @param  bEpNum Endpoint Number.
769   * @param  bAddr Address.
770   * @retval None
771   */
772 #define PCD_SET_EP_ADDRESS(USBx, bEpNum, bAddr) \
773   do { \
774     uint16_t _wRegVal; \
775     \
776     _wRegVal = (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr); \
777     \
778     PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
779   } while(0) /* PCD_SET_EP_ADDRESS */
780 
781 /**
782   * @brief  Gets address in an endpoint register.
783   * @param  USBx USB peripheral instance register address.
784   * @param  bEpNum Endpoint Number.
785   * @retval None
786   */
787 #define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD))
788 
789 #define PCD_EP_TX_CNT(USBx, bEpNum) \
790   ((uint16_t *)((((uint32_t)(USBx)->BTABLE + \
791                   ((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
792 
793 #define PCD_EP_RX_CNT(USBx, bEpNum) \
794   ((uint16_t *)((((uint32_t)(USBx)->BTABLE + \
795                   ((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
796 
797 
798 /**
799   * @brief  sets address of the tx/rx buffer.
800   * @param  USBx USB peripheral instance register address.
801   * @param  bEpNum Endpoint Number.
802   * @param  wAddr address to be set (must be word aligned).
803   * @retval None
804   */
805 #define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wAddr) \
806   do { \
807     __IO uint16_t *_wRegVal; \
808     uint32_t _wRegBase = (uint32_t)USBx; \
809     \
810     _wRegBase += (uint32_t)(USBx)->BTABLE; \
811     _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + (((uint32_t)(bEpNum) * 8U) * PMA_ACCESS)); \
812     *_wRegVal = ((wAddr) >> 1) << 1; \
813   } while(0) /* PCD_SET_EP_TX_ADDRESS */
814 
815 #define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wAddr) \
816   do { \
817     __IO uint16_t *_wRegVal; \
818     uint32_t _wRegBase = (uint32_t)USBx; \
819     \
820     _wRegBase += (uint32_t)(USBx)->BTABLE; \
821     _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 4U) * PMA_ACCESS)); \
822     *_wRegVal = ((wAddr) >> 1) << 1; \
823   } while(0) /* PCD_SET_EP_RX_ADDRESS */
824 
825 /**
826   * @brief  Gets address of the tx/rx buffer.
827   * @param  USBx USB peripheral instance register address.
828   * @param  bEpNum Endpoint Number.
829   * @retval address of the buffer.
830   */
831 #define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum)))
832 #define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum)))
833 
834 /**
835   * @brief  Sets counter of rx buffer with no. of blocks.
836   * @param  pdwReg Register pointer
837   * @param  wCount Counter.
838   * @param  wNBlocks no. of Blocks.
839   * @retval None
840   */
841 #define PCD_CALC_BLK32(pdwReg, wCount, wNBlocks) \
842   do { \
843     (wNBlocks) = (wCount) >> 5; \
844     if (((wCount) & 0x1fU) == 0U) \
845     { \
846       (wNBlocks)--; \
847     } \
848     *(pdwReg) |= (uint16_t)(((wNBlocks) << 10) | USB_CNTRX_BLSIZE); \
849   } while(0) /* PCD_CALC_BLK32 */
850 
851 #define PCD_CALC_BLK2(pdwReg, wCount, wNBlocks) \
852   do { \
853     (wNBlocks) = (wCount) >> 1; \
854     if (((wCount) & 0x1U) != 0U) \
855     { \
856       (wNBlocks)++; \
857     } \
858     *(pdwReg) |= (uint16_t)((wNBlocks) << 10); \
859   } while(0) /* PCD_CALC_BLK2 */
860 
861 #define PCD_SET_EP_CNT_RX_REG(pdwReg, wCount) \
862   do { \
863     uint32_t wNBlocks; \
864     \
865     *(pdwReg) &= 0x3FFU; \
866     \
867     if ((wCount) == 0U) \
868     { \
869       *(pdwReg) |= USB_CNTRX_BLSIZE; \
870     } \
871     else if ((wCount) <= 62U) \
872     { \
873       PCD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \
874     } \
875     else \
876     { \
877       PCD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \
878     } \
879   } while(0) /* PCD_SET_EP_CNT_RX_REG */
880 
881 #define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum, wCount) \
882   do { \
883     uint32_t _wRegBase = (uint32_t)(USBx); \
884     __IO uint16_t *pdwReg; \
885     \
886     _wRegBase += (uint32_t)(USBx)->BTABLE; \
887     pdwReg = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
888     PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount)); \
889   } while(0)
890 
891 /**
892   * @brief  sets counter for the tx/rx buffer.
893   * @param  USBx USB peripheral instance register address.
894   * @param  bEpNum Endpoint Number.
895   * @param  wCount Counter value.
896   * @retval None
897   */
898 #define PCD_SET_EP_TX_CNT(USBx, bEpNum, wCount) \
899   do { \
900     uint32_t _wRegBase = (uint32_t)(USBx); \
901     __IO uint16_t *_wRegVal; \
902     \
903     _wRegBase += (uint32_t)(USBx)->BTABLE; \
904     _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
905     *_wRegVal = (uint16_t)(wCount); \
906   } while(0)
907 
908 #define PCD_SET_EP_RX_CNT(USBx, bEpNum, wCount) \
909   do { \
910     uint32_t _wRegBase = (uint32_t)(USBx); \
911     __IO uint16_t *_wRegVal; \
912     \
913     _wRegBase += (uint32_t)(USBx)->BTABLE; \
914     _wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
915     PCD_SET_EP_CNT_RX_REG(_wRegVal, (wCount)); \
916   } while(0)
917 
918 /**
919   * @brief  gets counter of the tx buffer.
920   * @param  USBx USB peripheral instance register address.
921   * @param  bEpNum Endpoint Number.
922   * @retval Counter value
923   */
924 #define PCD_GET_EP_TX_CNT(USBx, bEpNum)        ((uint32_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3ffU)
925 #define PCD_GET_EP_RX_CNT(USBx, bEpNum)        ((uint32_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3ffU)
926 
927 /**
928   * @brief  Sets buffer 0/1 address in a double buffer endpoint.
929   * @param  USBx USB peripheral instance register address.
930   * @param  bEpNum Endpoint Number.
931   * @param  wBuf0Addr buffer 0 address.
932   * @retval Counter value
933   */
934 #define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr) \
935   do { \
936     PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr)); \
937   } while(0) /* PCD_SET_EP_DBUF0_ADDR */
938 
939 #define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr) \
940   do { \
941     PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr)); \
942   } while(0) /* PCD_SET_EP_DBUF1_ADDR */
943 
944 /**
945   * @brief  Sets addresses in a double buffer endpoint.
946   * @param  USBx USB peripheral instance register address.
947   * @param  bEpNum Endpoint Number.
948   * @param  wBuf0Addr: buffer 0 address.
949   * @param  wBuf1Addr = buffer 1 address.
950   * @retval None
951   */
952 #define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum, wBuf0Addr, wBuf1Addr) \
953   do { \
954     PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr)); \
955     PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr)); \
956   } while(0) /* PCD_SET_EP_DBUF_ADDR */
957 
958 /**
959   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
960   * @param  USBx USB peripheral instance register address.
961   * @param  bEpNum Endpoint Number.
962   * @retval None
963   */
964 #define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum)    (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum)))
965 #define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum)    (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum)))
966 
967 /**
968   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
969   * @param  USBx USB peripheral instance register address.
970   * @param  bEpNum Endpoint Number.
971   * @param  bDir endpoint dir  EP_DBUF_OUT = OUT
972   *         EP_DBUF_IN  = IN
973   * @param  wCount: Counter value
974   * @retval None
975   */
976 #define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) \
977   do { \
978     if ((bDir) == 0U) \
979       /* OUT endpoint */ \
980     { \
981       PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum), (wCount)); \
982     } \
983     else \
984     { \
985       if ((bDir) == 1U) \
986       { \
987         /* IN endpoint */ \
988         PCD_SET_EP_TX_CNT((USBx), (bEpNum), (wCount)); \
989       } \
990     } \
991   } while(0) /* SetEPDblBuf0Count*/
992 
993 #define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) \
994   do { \
995     uint32_t _wBase = (uint32_t)(USBx); \
996     __IO uint16_t *_wEPRegVal; \
997     \
998     if ((bDir) == 0U) \
999     { \
1000       /* OUT endpoint */ \
1001       PCD_SET_EP_RX_CNT((USBx), (bEpNum), (wCount)); \
1002     } \
1003     else \
1004     { \
1005       if ((bDir) == 1U) \
1006       { \
1007         /* IN endpoint */ \
1008         _wBase += (uint32_t)(USBx)->BTABLE; \
1009         _wEPRegVal = (__IO uint16_t *)(_wBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
1010         *_wEPRegVal = (uint16_t)(wCount); \
1011       } \
1012     } \
1013   } while(0) /* SetEPDblBuf1Count */
1014 
1015 #define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) \
1016   do { \
1017     PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \
1018     PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \
1019   } while(0) /* PCD_SET_EP_DBUF_CNT */
1020 
1021 /**
1022   * @brief  Gets buffer 0/1 rx/tx counter for double buffering.
1023   * @param  USBx USB peripheral instance register address.
1024   * @param  bEpNum Endpoint Number.
1025   * @retval None
1026   */
1027 #define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum)     (PCD_GET_EP_TX_CNT((USBx), (bEpNum)))
1028 #define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum)     (PCD_GET_EP_RX_CNT((USBx), (bEpNum)))
1029 
1030 #endif /* defined (USB) */
1031 
1032 /**
1033   * @}
1034   */
1035 
1036 /**
1037   * @}
1038   */
1039 
1040 /**
1041   * @}
1042   */
1043 #endif /* defined (USB) || defined (USB_OTG_FS) */
1044 
1045 #ifdef __cplusplus
1046 }
1047 #endif
1048 
1049 #endif /* STM32L4xx_HAL_PCD_H */
1050