1 /**
2   ******************************************************************************
3   * @file    stm32u0xx_ll_usb.h
4   * @author  MCD Application Team
5   * @brief   Header file of USB Low Layer HAL module.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2023 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 STM32U0xx_LL_USB_H
21 #define STM32U0xx_LL_USB_H
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif /* __cplusplus */
26 
27 /* Includes ------------------------------------------------------------------*/
28 #include "stm32u0xx_hal_def.h"
29 
30 #if defined (USB_DRD_FS)
31 /** @addtogroup STM32U0xx_HAL_Driver
32   * @{
33   */
34 
35 /** @addtogroup USB_LL
36   * @{
37   */
38 
39 /* Exported types ------------------------------------------------------------*/
40 
41 /**
42   * @brief  USB Mode definition
43   */
44 
45 typedef enum
46 {
47   USB_DEVICE_MODE = 0
48 } USB_ModeTypeDef;
49 
50 
51 /**
52   * @brief  USB Instance Initialization Structure definition
53   */
54 typedef struct
55 {
56   uint8_t dev_endpoints;            /*!< Device Endpoints number.
57                                          This parameter depends on the used USB core.
58                                          This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
59 
60   uint8_t speed;                   /*!< USB Core speed.
61                                         This parameter can be any value of @ref PCD_Speed/HCD_Speed
62                                                                                 (HCD_SPEED_xxx, HCD_SPEED_xxx) */
63 
64   uint8_t ep0_mps;                 /*!< Set the Endpoint 0 Max Packet size.                                    */
65 
66   uint8_t phy_itface;              /*!< Select the used PHY interface.
67                                         This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module  */
68 
69   uint8_t Sof_enable;              /*!< Enable or disable the output of the SOF signal.                        */
70 
71   uint8_t low_power_enable;        /*!< Enable or disable the low Power Mode.                                  */
72 
73   uint8_t lpm_enable;              /*!< Enable or disable Link Power Management.                               */
74 
75   uint8_t battery_charging_enable; /*!< Enable or disable Battery charging.                                    */
76 } USB_CfgTypeDef;
77 
78 typedef struct
79 {
80   uint8_t   num;                  /*!< Endpoint number
81                                        This parameter must be a number between Min_Data = 1 and Max_Data = 15   */
82 
83   uint8_t   is_in;                /*!< Endpoint direction
84                                        This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
85 
86   uint8_t   is_stall;             /*!< Endpoint stall condition
87                                        This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
88 
89   uint8_t   type;                 /*!< Endpoint type
90                                        This parameter can be any value of @ref USB_LL_EP_Type                   */
91 
92   uint8_t   data_pid_start;       /*!< Initial data PID
93                                        This parameter must be a number between Min_Data = 0 and Max_Data = 1    */
94 
95 
96   uint16_t  pmaadress;            /*!< PMA Address
97                                        This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
98 
99   uint16_t  pmaaddr0;             /*!< PMA Address0
100                                        This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
101 
102   uint16_t  pmaaddr1;             /*!< PMA Address1
103                                        This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
104 
105   uint8_t   doublebuffer;         /*!< Double buffer enable
106                                        This parameter can be 0 or 1                                             */
107 
108 
109   uint32_t  maxpacket;            /*!< Endpoint Max packet size
110                                        This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
111 
112   uint8_t   *xfer_buff;           /*!< Pointer to transfer buffer                                               */
113 
114   uint32_t  xfer_len;             /*!< Current transfer length                                                  */
115 
116   uint32_t  xfer_count;           /*!< Partial transfer length in case of multi packet transfer                 */
117 
118   uint32_t  xfer_len_db;          /*!< double buffer transfer length used with bulk double buffer in            */
119 
120   uint8_t   xfer_fill_db;         /*!< double buffer Need to Fill new buffer  used with bulk_in                 */
121 } USB_EPTypeDef;
122 
123 typedef USB_ModeTypeDef    USB_DRD_ModeTypeDef;
124 typedef USB_CfgTypeDef     USB_DRD_CfgTypeDef;
125 typedef USB_EPTypeDef      USB_DRD_EPTypeDef;
126 
127 /* Exported constants --------------------------------------------------------*/
128 
129 /** @defgroup PCD_Exported_Constants PCD Exported Constants
130   * @{
131   */
132 /** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
133   * @{
134   */
135 #define EP_MPS_64                              0U
136 #define EP_MPS_32                              1U
137 #define EP_MPS_16                              2U
138 #define EP_MPS_8                               3U
139 /**
140   * @}
141   */
142 
143 /** @defgroup USB_LL_EP_Type USB Low Layer EP Type
144   * @{
145   */
146 #define EP_TYPE_CTRL                           0U
147 #define EP_TYPE_ISOC                           1U
148 #define EP_TYPE_BULK                           2U
149 #define EP_TYPE_INTR                           3U
150 #define EP_TYPE_MSK                            3U
151 /**
152   * @}
153   */
154 
155 /** @defgroup USB_LL Device Speed
156   * @{
157   */
158 #define USBD_FS_SPEED                          2U
159 #define USBH_FSLS_SPEED                        1U
160 /**
161   * @}
162   */
163 
164 #define EP_ADDR_MSK                            0x7U
165 
166 #ifndef USE_USB_DOUBLE_BUFFER
167 #define USE_USB_DOUBLE_BUFFER                  1U
168 #endif /* USE_USB_DOUBLE_BUFFER */
169 
170 #define USB_EMBEDDED_PHY                       2U
171 /* First available address in PMA */
172 #define PMA_START_ADDR          (0x10U + (8U *(USB_DRD_USED_CHANNELS - 2U)))
173 #define PMA_END_ADDR             USB_DRD_PMA_SIZE
174 
175 /* Exported macro ------------------------------------------------------------*/
176 /**
177   * @}
178   */
179 /********************  Bit definition for USB_COUNTn_RX register  *************/
180 #define USB_CNTRX_NBLK_MSK                    (0x1FU << 26)
181 #define USB_CNTRX_BLSIZE                      (0x1U << 31)
182 
183 
184 /*Set Channel/Endpoint to the USB Register */
185 #define USB_DRD_SET_CHEP(USBx, bEpChNum, wRegValue)  (*(__IO uint32_t *)\
186                                                       (&(USBx)->CHEP0R + (bEpChNum)) = (uint32_t)(wRegValue))
187 
188 /*Get Channel/Endpoint from the USB Register */
189 #define USB_DRD_GET_CHEP(USBx, bEpChNum)             (*(__IO uint32_t *)(&(USBx)->CHEP0R + (bEpChNum)))
190 
191 
192 /**
193   * @brief free buffer used from the application realizing it to the line
194   *         toggles bit SW_BUF in the double buffered endpoint register
195   * @param USBx USB device.
196   * @param   bEpChNum, bDir
197   * @retval None
198   */
199 #define USB_DRD_FREE_USER_BUFFER(USBx, bEpChNum, bDir) \
200   do { \
201     if ((bDir) == 0U) \
202     { \
203       /* OUT double buffered endpoint */ \
204       USB_DRD_TX_DTOG((USBx), (bEpChNum)); \
205     } \
206     else if ((bDir) == 1U) \
207     { \
208       /* IN double buffered endpoint */ \
209       USB_DRD_RX_DTOG((USBx), (bEpChNum)); \
210     } \
211   } while(0)
212 
213 
214 /**
215   * @brief Set the Setup bit in the corresponding channel, when a Setup
216      transaction is needed.
217   * @param USBx USB device.
218   * @param   bEpChNum
219   * @retval None
220   */
221 #define USB_DRD_CHEP_TX_SETUP(USBx, bEpChNum) \
222   do { \
223     uint32_t _wRegVal; \
224     \
225     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) ; \
226     \
227     /* Set Setup bit */ \
228     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_SETUP)); \
229   } while(0)
230 
231 
232 /**
233   * @brief  Clears bit ERR_RX in the Channel register
234   * @param  USBx USB peripheral instance register address.
235   * @param  bChNum Endpoint Number.
236   * @retval None
237   */
238 #define USB_DRD_CLEAR_CHEP_RX_ERR(USBx, bChNum) \
239   do { \
240     uint32_t _wRegVal; \
241     \
242     _wRegVal = USB_DRD_GET_CHEP((USBx), (bChNum)); \
243     _wRegVal = (_wRegVal & USB_CHEP_REG_MASK & (~USB_CHEP_ERRRX) & (~USB_CHEP_VTRX)) | \
244                (USB_CHEP_VTTX | USB_CHEP_ERRTX); \
245     \
246     USB_DRD_SET_CHEP((USBx), (bChNum), _wRegVal); \
247   } while(0) /* USB_DRD_CLEAR_CHEP_RX_ERR */
248 
249 
250 /**
251   * @brief  Clears bit ERR_TX in the Channel register
252   * @param  USBx USB peripheral instance register address.
253   * @param  bChNum Endpoint Number.
254   * @retval None
255   */
256 #define USB_DRD_CLEAR_CHEP_TX_ERR(USBx, bChNum) \
257   do { \
258     uint32_t _wRegVal; \
259     \
260     _wRegVal = USB_DRD_GET_CHEP((USBx), (bChNum)); \
261     _wRegVal = (_wRegVal & USB_CHEP_REG_MASK & (~USB_CHEP_ERRTX) & (~USB_CHEP_VTTX)) | \
262                (USB_CHEP_VTRX|USB_CHEP_ERRRX); \
263     \
264     USB_DRD_SET_CHEP((USBx), (bChNum), _wRegVal); \
265   } while(0) /* USB_DRD_CLEAR_CHEP_TX_ERR */
266 
267 
268 /**
269   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]).
270   * @param  USBx USB peripheral instance register address.
271   * @param  bEpChNum Endpoint Number.
272   * @param  wState new state
273   * @retval None
274   */
275 #define USB_DRD_SET_CHEP_TX_STATUS(USBx, bEpChNum, wState) \
276   do { \
277     uint32_t _wRegVal; \
278     \
279     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_TX_DTOGMASK; \
280     /* toggle first bit ? */ \
281     if ((USB_CHEP_TX_DTOG1 & (wState)) != 0U) \
282     { \
283       _wRegVal ^= USB_CHEP_TX_DTOG1; \
284     } \
285     /* toggle second bit ?  */ \
286     if ((USB_CHEP_TX_DTOG2 & (wState)) != 0U) \
287     { \
288       _wRegVal ^= USB_CHEP_TX_DTOG2; \
289     } \
290     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX| USB_CHEP_VTTX)); \
291   } while(0) /* USB_DRD_SET_CHEP_TX_STATUS */
292 
293 
294 /**
295   * @brief  sets the status for rx transfer (bits STAT_TX[1:0])
296   * @param  USBx USB peripheral instance register address.
297   * @param  bEpChNum Endpoint Number.
298   * @param  wState new state
299   * @retval None
300   */
301 #define USB_DRD_SET_CHEP_RX_STATUS(USBx, bEpChNum, wState) \
302   do { \
303     uint32_t _wRegVal; \
304     \
305     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_RX_DTOGMASK; \
306     /* toggle first bit ? */ \
307     if ((USB_CHEP_RX_DTOG1 & (wState)) != 0U) \
308     { \
309       _wRegVal ^= USB_CHEP_RX_DTOG1; \
310     } \
311     /* toggle second bit ? */ \
312     if ((USB_CHEP_RX_DTOG2 & (wState)) != 0U) \
313     { \
314       _wRegVal ^= USB_CHEP_RX_DTOG2; \
315     } \
316     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \
317   } while(0) /* USB_DRD_SET_CHEP_RX_STATUS */
318 
319 
320 /**
321   * @brief  gets the status for tx/rx transfer (bits STAT_TX[1:0]
322   *         /STAT_RX[1:0])
323   * @param  USBx USB peripheral instance register address.
324   * @param  bEpChNum Endpoint Number.
325   * @retval status
326   */
327 #define USB_DRD_GET_CHEP_TX_STATUS(USBx, bEpChNum) \
328   ((uint16_t)USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_DRD_CHEP_TX_STTX)
329 
330 #define USB_DRD_GET_CHEP_RX_STATUS(USBx, bEpChNum) \
331   ((uint16_t)USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_DRD_CHEP_RX_STRX)
332 
333 
334 /**
335   * @brief  set  EP_KIND bit.
336   * @param  USBx USB peripheral instance register address.
337   * @param  bEpChNum Endpoint Number.
338   * @retval None
339   */
340 #define USB_DRD_SET_CHEP_KIND(USBx, bEpChNum) \
341   do { \
342     uint32_t _wRegVal; \
343     \
344     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \
345     \
346     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_KIND)); \
347   } while(0) /* USB_DRD_SET_CHEP_KIND */
348 
349 
350 /**
351   * @brief  clear EP_KIND bit.
352   * @param  USBx USB peripheral instance register address.
353   * @param  bEpChNum Endpoint Number.
354   * @retval None
355   */
356 #define USB_DRD_CLEAR_CHEP_KIND(USBx, bEpChNum) \
357   do { \
358     uint32_t _wRegVal; \
359     \
360     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_EP_KIND_MASK; \
361     \
362     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \
363   } while(0) /* USB_DRD_CLEAR_CHEP_KIND */
364 
365 
366 /**
367   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register.
368   * @param  USBx USB peripheral instance register address.
369   * @param  bEpChNum Endpoint Number.
370   * @retval None
371   */
372 #define USB_DRD_CLEAR_RX_CHEP_CTR(USBx, bEpChNum) \
373   do { \
374     uint32_t _wRegVal; \
375     \
376     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & (0xFFFF7FFFU & USB_CHEP_REG_MASK); \
377     \
378     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTTX)); \
379   } while(0) /* USB_CLEAR_RX_CHEP_CTR */
380 
381 #define USB_DRD_CLEAR_TX_CHEP_CTR(USBx, bEpChNum) \
382   do { \
383     uint32_t _wRegVal; \
384     \
385     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & (0xFFFFFF7FU & USB_CHEP_REG_MASK); \
386     \
387     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX)); \
388   } while(0) /* USB_CLEAR_TX_CHEP_CTR */
389 
390 
391 /**
392   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
393   * @param  USBx USB peripheral instance register address.
394   * @param  bEpChNum Endpoint Number.
395   * @retval None
396   */
397 #define USB_DRD_RX_DTOG(USBx, bEpChNum) \
398   do { \
399     uint32_t _wEPVal; \
400     \
401     _wEPVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \
402     \
403     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wEPVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_DTOG_RX)); \
404   } while(0) /* USB_DRD_RX_DTOG */
405 
406 #define USB_DRD_TX_DTOG(USBx, bEpChNum) \
407   do { \
408     uint32_t _wEPVal; \
409     \
410     _wEPVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \
411     \
412     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wEPVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_DTOG_TX)); \
413   } while(0) /* USB_TX_DTOG */
414 
415 
416 /**
417   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register.
418   * @param  USBx USB peripheral instance register address.
419   * @param  bEpChNum Endpoint Number.
420   * @retval None
421   */
422 #define USB_DRD_CLEAR_RX_DTOG(USBx, bEpChNum) \
423   do { \
424     uint32_t _wRegVal; \
425     \
426     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)); \
427     \
428     if ((_wRegVal & USB_CHEP_DTOG_RX) != 0U) \
429     { \
430       USB_DRD_RX_DTOG((USBx), (bEpChNum)); \
431     } \
432   } while(0) /* USB_DRD_CLEAR_RX_DTOG */
433 
434 #define USB_DRD_CLEAR_TX_DTOG(USBx, bEpChNum) \
435   do { \
436     uint32_t _wRegVal; \
437     \
438     _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)); \
439     \
440     if ((_wRegVal & USB_CHEP_DTOG_TX) != 0U) \
441     { \
442       USB_DRD_TX_DTOG((USBx), (bEpChNum)); \
443     } \
444   } while(0) /* USB_DRD_CLEAR_TX_DTOG */
445 
446 
447 /**
448   * @brief  Sets address in an endpoint register.
449   * @param  USBx USB peripheral instance register address.
450   * @param  bEpChNum Endpoint Number.
451   * @param  bAddr Address.
452   * @retval None
453   */
454 #define USB_DRD_SET_CHEP_ADDRESS(USBx, bEpChNum, bAddr) \
455   do { \
456     uint32_t _wRegVal; \
457     \
458     /*Read the USB->CHEPx into _wRegVal, Reset(DTOGRX/STRX/DTOGTX/STTX) and set the EpAddress*/ \
459     _wRegVal = (USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK) | (bAddr); \
460     \
461     /*Set _wRegVal in USB->CHEPx and set Transmit/Receive Valid Transfer  (x=bEpChNum)*/ \
462     USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \
463   } while(0) /* USB_DRD_SET_CHEP_ADDRESS */
464 
465 
466 /* PMA API Buffer Descriptor Management ------------------------------------------------------------*/
467 /* Buffer Descriptor Table   TXBD0/RXBD0 --- > TXBD7/RXBD7  8 possible descriptor
468 * The buffer descriptor is located inside the packet buffer memory (USB_PMA_BUFF)
469 *          TXBD    [Reserve         |Countx| Address_Tx]
470 *          RXBD    [BLSIEZ|NUM_Block |CounRx| Address_Rx] */
471 
472 /* Set TX Buffer Descriptor Address Field */
473 #define USB_DRD_SET_CHEP_TX_ADDRESS(USBx, bEpChNum, wAddr) \
474   do { \
475     /* Reset old Address */ \
476     (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD &= USB_PMA_TXBD_ADDMSK; \
477     \
478     /* Bit0 & Bit1 should be =0 PMA must be Word aligned */ \
479     (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD |= (uint32_t)(((uint32_t)(wAddr) >> 2U) << 2U); \
480   } while(0) /* USB_DRD_SET_CHEP_TX_ADDRESS */
481 
482 /* Set RX Buffer Descriptor Address Field */
483 #define USB_DRD_SET_CHEP_RX_ADDRESS(USBx, bEpChNum, wAddr) \
484   do { \
485     /* Reset old Address */ \
486     (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD &= USB_PMA_RXBD_ADDMSK; \
487     \
488     /* Bit0 & Bit1 should be =0 PMA must be Word aligned */ \
489     (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD |= (uint32_t)(((uint32_t)(wAddr) >> 2U) << 2U); \
490   } while(0) /* USB_SET_CHEP_RX_ADDRESS */
491 
492 
493 /**
494   * @brief  Sets counter of rx buffer with no. of blocks.
495   * @param  pdwReg Register pointer
496   * @param  wCount Counter.
497   * @param  wNBlocks no. of Blocks.
498   * @retval None
499   */
500 #define USB_DRD_CALC_BLK32(pdwReg, wCount, wNBlocks) \
501   do { \
502     /* Divide PacketSize by 32 to calculate the Nb of Block32 */ \
503     (wNBlocks) =((uint32_t)(wCount) >> 5U); \
504     if (((uint32_t)(wCount) % 32U) == 0U)  \
505     { \
506       (wNBlocks)--; \
507     } \
508     \
509     (pdwReg)|= (uint32_t)((((wNBlocks) << 26U)) | USB_CNTRX_BLSIZE); \
510   } while(0) /* USB_DRD_CALC_BLK32 */
511 
512 #define USB_DRD_CALC_BLK2(pdwReg, wCount, wNBlocks) \
513   do { \
514     /* Divide PacketSize by 32 to calculate the Nb of Block32 */ \
515     (wNBlocks) = (uint32_t)((uint32_t)(wCount) >> 1U); \
516     if (((wCount) & 0x1U) != 0U) \
517     { \
518       (wNBlocks)++; \
519     } \
520     (pdwReg) |= (uint32_t)((wNBlocks) << 26U); \
521   } while(0) /* USB_DRD_CALC_BLK2 */
522 
523 #define USB_DRD_SET_CHEP_CNT_RX_REG(pdwReg, wCount) \
524   do { \
525     uint32_t wNBlocks; \
526     \
527     (pdwReg) &= ~(USB_CNTRX_BLSIZE | USB_CNTRX_NBLK_MSK); \
528     \
529     if ((wCount) == 0U) \
530     { \
531       (pdwReg) |= USB_CNTRX_BLSIZE; \
532     } \
533     else if ((wCount) <= 62U) \
534     { \
535       USB_DRD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \
536     } \
537     else \
538     { \
539       USB_DRD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \
540     } \
541   } while(0) /* USB_DRD_SET_CHEP_CNT_RX_REG */
542 
543 
544 /**
545   * @brief  sets counter for the tx/rx buffer.
546   * @param  USBx USB peripheral instance register address.
547   * @param  bEpChNum Endpoint Number.
548   * @param  wCount Counter value.
549   * @retval None
550   */
551 #define USB_DRD_SET_CHEP_TX_CNT(USBx,bEpChNum, wCount) \
552   do { \
553     /* Reset old TX_Count value */ \
554     (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD &= USB_PMA_TXBD_COUNTMSK; \
555     \
556     /* Set the wCount in the dedicated EP_TXBuffer */ \
557     (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD |= (uint32_t)((uint32_t)(wCount) << 16U); \
558   } while(0)
559 
560 #define USB_DRD_SET_CHEP_RX_DBUF0_CNT(USBx, bEpChNum, wCount) \
561   USB_DRD_SET_CHEP_CNT_RX_REG(((USB_DRD_PMA_BUFF + (bEpChNum))->TXBD), (wCount))
562 
563 #define USB_DRD_SET_CHEP_RX_CNT(USBx, bEpChNum, wCount) \
564   USB_DRD_SET_CHEP_CNT_RX_REG(((USB_DRD_PMA_BUFF + (bEpChNum))->RXBD), (wCount))
565 
566 /**
567   * @brief  gets counter of the tx buffer.
568   * @param  USBx USB peripheral instance register address.
569   * @param  bEpChNum Endpoint Number.
570   * @retval Counter value
571   */
572 #define USB_DRD_GET_CHEP_TX_CNT(USBx, bEpChNum)           (((USB_DRD_PMA_BUFF + (bEpChNum))->TXBD & 0x03FF0000U) >> 16U)
573 #define USB_DRD_GET_CHEP_RX_CNT(USBx, bEpChNum)           (((USB_DRD_PMA_BUFF + (bEpChNum))->RXBD & 0x03FF0000U) >> 16U)
574 
575 #define USB_DRD_GET_EP_TX_CNT                             USB_GET_CHEP_TX_CNT
576 #define USB_DRD_GET_CH_TX_CNT                             USB_GET_CHEP_TX_CNT
577 
578 #define USB_DRD_GET_EP_RX_CNT                             USB_DRD_GET_CHEP_RX_CNT
579 #define USB_DRD_GET_CH_RX_CNT                             USB_DRD_GET_CHEP_RX_CNT
580 /**
581   * @brief  Sets buffer 0/1 address in a double buffer endpoint.
582   * @param  USBx USB peripheral instance register address.
583   * @param  bEpChNum Endpoint Number.
584   * @param  wBuf0Addr buffer 0 address.
585   * @retval Counter value
586   */
587 #define USB_DRD_SET_CHEP_DBUF0_ADDR(USBx, bEpChNum, wBuf0Addr) \
588   USB_DRD_SET_CHEP_TX_ADDRESS((USBx), (bEpChNum), (wBuf0Addr))
589 
590 #define USB_DRD_SET_CHEP_DBUF1_ADDR(USBx, bEpChNum, wBuf1Addr) \
591   USB_DRD_SET_CHEP_RX_ADDRESS((USBx), (bEpChNum), (wBuf1Addr))
592 
593 
594 /**
595   * @brief  Sets addresses in a double buffer endpoint.
596   * @param  USBx USB peripheral instance register address.
597   * @param  bEpChNum Endpoint Number.
598   * @param  wBuf0Addr: buffer 0 address.
599   * @param  wBuf1Addr = buffer 1 address.
600   * @retval None
601   */
602 #define USB_DRD_SET_CHEP_DBUF_ADDR(USBx, bEpChNum, wBuf0Addr, wBuf1Addr) \
603   do { \
604     USB_DRD_SET_CHEP_DBUF0_ADDR((USBx), (bEpChNum), (wBuf0Addr)); \
605     USB_DRD_SET_CHEP_DBUF1_ADDR((USBx), (bEpChNum), (wBuf1Addr)); \
606   } while(0) /* USB_DRD_SET_CHEP_DBUF_ADDR */
607 
608 
609 /**
610   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
611   * @param  USBx USB peripheral instance register address.
612   * @param  bEpChNum Endpoint Number.
613   * @param  bDir endpoint dir  EP_DBUF_OUT = OUT
614   *         EP_DBUF_IN  = IN
615   * @param  wCount: Counter value
616   * @retval None
617   */
618 #define USB_DRD_SET_CHEP_DBUF0_CNT(USBx, bEpChNum, bDir, wCount) \
619   do { \
620     if ((bDir) == 0U) \
621     { \
622       /* OUT endpoint */ \
623       USB_DRD_SET_CHEP_RX_DBUF0_CNT((USBx), (bEpChNum), (wCount)); \
624     } \
625     else \
626     { \
627       if ((bDir) == 1U) \
628       { \
629         /* IN endpoint */ \
630         USB_DRD_SET_CHEP_TX_CNT((USBx), (bEpChNum), (wCount)); \
631       } \
632     } \
633   } while(0) /* USB_DRD_SET_CHEP_DBUF0_CNT */
634 
635 #define USB_DRD_SET_CHEP_DBUF1_CNT(USBx, bEpChNum, bDir, wCount) \
636   do { \
637     if ((bDir) == 0U) \
638     { \
639       /* OUT endpoint */ \
640       USB_DRD_SET_CHEP_RX_CNT((USBx), (bEpChNum), (wCount)); \
641     } \
642     else \
643     { \
644       if ((bDir) == 1U) \
645       { \
646         /* IN endpoint */ \
647         (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD &= USB_PMA_TXBD_COUNTMSK; \
648         (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD |= (uint32_t)((uint32_t)(wCount) << 16U); \
649       } \
650     } \
651   } while(0) /* USB_DRD_SET_CHEP_DBUF1_CNT */
652 
653 #define USB_DRD_SET_CHEP_DBUF_CNT(USBx, bEpChNum, bDir, wCount) \
654   do { \
655     USB_DRD_SET_CHEP_DBUF0_CNT((USBx), (bEpChNum), (bDir), (wCount)); \
656     USB_DRD_SET_CHEP_DBUF1_CNT((USBx), (bEpChNum), (bDir), (wCount)); \
657   } while(0) /* USB_DRD_SET_EPCH_DBUF_CNT  */
658 
659 /**
660   * @brief  Gets buffer 0/1 rx/tx counter for double buffering.
661   * @param  USBx USB peripheral instance register address.
662   * @param  bEpChNum Endpoint Number.
663   * @retval None
664   */
665 #define USB_DRD_GET_CHEP_DBUF0_CNT(USBx, bEpChNum)     (USB_DRD_GET_CHEP_TX_CNT((USBx), (bEpChNum)))
666 #define USB_DRD_GET_CHEP_DBUF1_CNT(USBx, bEpChNum)     (USB_DRD_GET_CHEP_RX_CNT((USBx), (bEpChNum)))
667 
668 /**
669   * @}
670   */
671 
672 /* Exported macro ------------------------------------------------------------*/
673 /**
674   * @}
675   */
676 
677 /* Exported functions --------------------------------------------------------*/
678 /** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
679   * @{
680   */
681 
682 
683 HAL_StatusTypeDef USB_CoreInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg);
684 HAL_StatusTypeDef USB_DevInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg);
685 HAL_StatusTypeDef USB_EnableGlobalInt(USB_DRD_TypeDef *USBx);
686 HAL_StatusTypeDef USB_DisableGlobalInt(USB_DRD_TypeDef *USBx);
687 HAL_StatusTypeDef USB_SetCurrentMode(USB_DRD_TypeDef *USBx, USB_DRD_ModeTypeDef mode);
688 
689 HAL_StatusTypeDef USB_FlushRxFifo(USB_DRD_TypeDef const *USBx);
690 HAL_StatusTypeDef USB_FlushTxFifo(USB_DRD_TypeDef const *USBx, uint32_t num);
691 
692 #if defined (HAL_PCD_MODULE_ENABLED)
693 HAL_StatusTypeDef USB_ActivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
694 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
695 HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
696 HAL_StatusTypeDef USB_EPSetStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
697 HAL_StatusTypeDef USB_EPClearStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
698 HAL_StatusTypeDef USB_EPStopXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep);
699 #endif /* defined (HAL_PCD_MODULE_ENABLED) */
700 
701 HAL_StatusTypeDef USB_SetDevAddress(USB_DRD_TypeDef *USBx, uint8_t address);
702 HAL_StatusTypeDef USB_DevConnect(USB_DRD_TypeDef *USBx);
703 HAL_StatusTypeDef USB_DevDisconnect(USB_DRD_TypeDef *USBx);
704 HAL_StatusTypeDef USB_StopDevice(USB_DRD_TypeDef *USBx);
705 uint32_t          USB_ReadInterrupts(USB_DRD_TypeDef const *USBx);
706 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_DRD_TypeDef *USBx);
707 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_DRD_TypeDef *USBx);
708 
709 void              USB_WritePMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf,
710                                uint16_t wPMABufAddr, uint16_t wNBytes);
711 
712 void              USB_ReadPMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf,
713                               uint16_t wPMABufAddr, uint16_t wNBytes);
714 
715 /**
716   * @}
717   */
718 
719 /**
720   * @}
721   */
722 
723 /**
724   * @}
725   */
726 
727 /**
728   * @}
729   */
730 #endif /* defined (USB_DRD_FS) */
731 
732 #ifdef __cplusplus
733 }
734 #endif /* __cplusplus */
735 
736 
737 #endif /* STM32U0xx_LL_USB_H */
738