1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_hal_pcd.h
4   * @author  MCD Application Team
5   * @brief   Header file of PCD HAL module.
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
10   *
11   * Redistribution and use in source and binary forms, with or without modification,
12   * are permitted provided that the following conditions are met:
13   *   1. Redistributions of source code must retain the above copyright notice,
14   *      this list of conditions and the following disclaimer.
15   *   2. Redistributions in binary form must reproduce the above copyright notice,
16   *      this list of conditions and the following disclaimer in the documentation
17   *      and/or other materials provided with the distribution.
18   *   3. Neither the name of STMicroelectronics nor the names of its contributors
19   *      may be used to endorse or promote products derived from this software
20   *      without specific prior written permission.
21   *
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   *
33   ******************************************************************************
34   */
35 
36 
37 
38 /* Define to prevent recursive inclusion -------------------------------------*/
39 #ifndef __STM32L0xx_HAL_PCD_H
40 #define __STM32L0xx_HAL_PCD_H
41 
42 #ifdef __cplusplus
43  extern "C" {
44 #endif
45 
46 #if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L061xx) && !defined (STM32L071xx) && !defined (STM32L081xx)
47 
48 /* Includes ------------------------------------------------------------------*/
49 #include "stm32l0xx_hal_def.h"
50 /** @addtogroup STM32L0xx_HAL_Driver
51   * @{
52   */
53 
54 /** @defgroup PCD PCD
55   * @{
56   */
57 
58 /** @defgroup PCD_Exported_Types PCD Exported Types
59   * @{
60   */
61 /* Exported types ------------------------------------------------------------*/
62 
63    /**
64   * @brief  PCD State structures definition
65   */
66 typedef enum
67 {
68   HAL_PCD_STATE_RESET    = 0x00U,
69   HAL_PCD_STATE_READY    = 0x01U,
70   HAL_PCD_STATE_ERROR    = 0x02U,
71   HAL_PCD_STATE_BUSY     = 0x03U,
72   HAL_PCD_STATE_TIMEOUT  = 0x04U
73 } PCD_StateTypeDef;
74 
75 /* Device LPM suspend state */
76 typedef enum
77 {
78   LPM_L0 = 0x00, /* on */
79   LPM_L1 = 0x01, /* LPM L1 sleep */
80   LPM_L2 = 0x02, /* suspend */
81   LPM_L3 = 0x03, /* off */
82 }PCD_LPM_StateTypeDef;
83 
84 typedef enum
85 {
86   /* double buffered endpoint direction */
87   PCD_EP_DBUF_OUT,
88   PCD_EP_DBUF_IN,
89   PCD_EP_DBUF_ERR,
90 }PCD_EP_DBUF_DIR;
91 
92 /* endpoint buffer number */
93 typedef enum
94 {
95   PCD_EP_NOBUF,
96   PCD_EP_BUF0,
97   PCD_EP_BUF1
98 }PCD_EP_BUF_NUM;
99 
100 
101 /**
102   * @brief  PCD Initialization Structure definition
103   */
104 typedef struct
105 {
106   uint32_t dev_endpoints;        /*!< Device Endpoints number.
107                                       This parameter depends on the used USB core.
108                                       This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
109 
110   uint32_t speed;                /*!< USB Core speed.
111                                       This parameter can be any value of @ref PCD_Speed                */
112 
113   uint32_t ep0_mps;              /*!< Set the Endpoint 0 Max Packet size.
114                                       This parameter can be any value of @ref PCD_USB_EP0_MPS                   */
115 
116   uint32_t phy_itface;           /*!< Select the used PHY interface.
117                                       This parameter can be any value of @ref PCD_USB_Core_PHY                  */
118 
119   uint32_t Sof_enable;           /*!< Enable or disable the output of the SOF signal.
120                                       This parameter can be set to ENABLE or DISABLE                        */
121 
122   uint32_t low_power_enable;       /*!< Enable or disable Low Power mode
123                                         This parameter can be set to ENABLE or DISABLE                      */
124 
125   uint32_t lpm_enable;             /*!< Enable or disable Link Power Management.
126                                         This parameter can be set to ENABLE or DISABLE */
127 
128   uint32_t battery_charging_enable; /*!< Enable or disable Battery charging.
129                                          This parameter can be set to ENABLE or DISABLE */
130 
131 }PCD_InitTypeDef;
132 
133 typedef struct
134 {
135   uint8_t   num;            /*!< Endpoint number
136                                 This parameter must be a number between Min_Data = 1 and Max_Data = 15    */
137 
138   uint8_t   is_in;          /*!< Endpoint direction
139                                 This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
140 
141   uint8_t   is_stall;       /*!< Endpoint stall condition
142                                 This parameter must be a number between Min_Data = 0 and Max_Data = 1     */
143 
144   uint8_t   type;           /*!< Endpoint type
145                                  This parameter can be any value of @ref PCD_USB_EP_Type                     */
146 
147   uint16_t  pmaadress;      /*!< PMA Address
148                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
149 
150 
151   uint16_t  pmaaddr0;       /*!< PMA Address0
152                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
153 
154 
155   uint16_t  pmaaddr1;        /*!< PMA Address1
156                                  This parameter can be any value between Min_addr = 0 and Max_addr = 1K   */
157 
158 
159   uint8_t   doublebuffer;    /*!< Double buffer enable
160                                  This parameter can be 0 or 1                                             */
161 
162   uint32_t  maxpacket;      /*!< Endpoint Max packet size
163                                  This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
164 
165   uint8_t   *xfer_buff;     /*!< Pointer to transfer buffer                                               */
166 
167 
168   uint32_t  xfer_len;       /*!< Current transfer length                                                  */
169 
170   uint32_t  xfer_count;     /*!< Partial transfer length in case of multi packet transfer                 */
171 
172 }PCD_EPTypeDef;
173 
174 typedef   USB_TypeDef PCD_TypeDef;
175 
176 /**
177   * @brief  PCD Handle Structure definition
178   */
179 typedef struct
180 {
181   PCD_TypeDef             *Instance;   /*!< Register base address              */
182   PCD_InitTypeDef         Init;       /*!< PCD required parameters            */
183   __IO uint8_t            USB_Address; /*!< USB Address            */
184   PCD_EPTypeDef           IN_ep[8];  /*!< IN endpoint parameters             */
185   PCD_EPTypeDef           OUT_ep[8]; /*!< OUT endpoint parameters            */
186   HAL_LockTypeDef         Lock;       /*!< PCD peripheral status              */
187   __IO PCD_StateTypeDef   State;      /*!< PCD communication state            */
188   uint32_t                Setup[12];  /*!< Setup packet buffer                */
189     PCD_LPM_StateTypeDef    LPM_State;    /*!< LPM State                          */
190   uint32_t                BESL;
191 
192 
193   uint32_t lpm_active;                  /*!< Enable or disable the Link Power Management .
194                                         This parameter can be set to ENABLE or DISABLE                      */
195 
196   uint32_t battery_charging_active;     /*!< Enable or disable Battery charging.
197                                         This parameter can be set to ENABLE or DISABLE                      */
198   void                    *pData;      /*!< Pointer to upper stack Handler     */
199 
200 } PCD_HandleTypeDef;
201 
202 /**
203   * @}
204   */
205 
206 
207 #include "stm32l0xx_hal_pcd_ex.h"
208 /* Exported constants --------------------------------------------------------*/
209 /** @defgroup PCD_Exported_Constants PCD Exported Constants
210   * @{
211   */
212 
213 /** @defgroup PCD_EndPoint PCD End Point
214   * @{
215   */
216 
217 
218 #define PCD_ENDP0                             ((uint8_t)0U)
219 #define PCD_ENDP1                             ((uint8_t)1U)
220 #define PCD_ENDP2                             ((uint8_t)2U)
221 #define PCD_ENDP3                             ((uint8_t)3U)
222 #define PCD_ENDP4                             ((uint8_t)4U)
223 #define PCD_ENDP5                             ((uint8_t)5U)
224 #define PCD_ENDP6                             ((uint8_t)6U)
225 #define PCD_ENDP7                             ((uint8_t)7U)
226 
227 /*  Endpoint Kind */
228 #define PCD_SNG_BUF                                      0U
229 #define PCD_DBL_BUF                                      1U
230 
231 #define IS_PCD_ALL_INSTANCE            IS_USB_ALL_INSTANCE
232 
233 /**
234   * @}
235   */
236 
237 
238 /** @defgroup PCD_Speed PCD Speed
239   * @{
240   */
241 #define PCD_SPEED_HIGH               0U /* Not Supported */
242 #define PCD_SPEED_FULL               2U
243 /**
244   * @}
245   */
246 
247   /** @defgroup PCD_USB_Core_PHY PCD USB Core PHY
248   * @{
249   */
250 #define PCD_PHY_EMBEDDED             2U
251 /**
252   * @}
253   */
254 
255   /** @defgroup PCD_USB_EP0_MPS PCD USB EP0 MPS
256   * @{
257   */
258 #define DEP0CTL_MPS_64                         0U
259 #define DEP0CTL_MPS_32                         1U
260 #define DEP0CTL_MPS_16                         2U
261 #define DEP0CTL_MPS_8                          3U
262 
263 #define PCD_EP0MPS_64                          DEP0CTL_MPS_64
264 #define PCD_EP0MPS_32                          DEP0CTL_MPS_32
265 #define PCD_EP0MPS_16                          DEP0CTL_MPS_16
266 #define PCD_EP0MPS_08                          DEP0CTL_MPS_8
267 /**
268   * @}
269   */
270 
271 /** @defgroup PCD_USB_EP_Type PCD USB EP Type
272   * @{
273   */
274 #define PCD_EP_TYPE_CTRL                                 0U
275 #define PCD_EP_TYPE_ISOC                                 1U
276 #define PCD_EP_TYPE_BULK                                 2U
277 #define PCD_EP_TYPE_INTR                                 3U
278 /**
279   * @}
280   */
281 
282 
283 /* Exported macros -----------------------------------------------------------*/
284 
285 /** @defgroup PCD_Interrupt_Clock PCD Interrupt
286  *  @brief macros to handle interrupts and specific clock configurations
287  * @{
288  */
289 #define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__)      ((((__HANDLE__)->Instance->ISTR) & (__INTERRUPT__)) == (__INTERRUPT__))
290 #define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)    (((__HANDLE__)->Instance->ISTR) &= (uint16_t) ~(__INTERRUPT__))
291 
292 #define  USB_WAKEUP_EXTI_LINE              (EXTI_IMR_IM18)  /*!< External interrupt line 18 Connected to the USB FS EXTI Line */
293 
294 #define __HAL_USB_WAKEUP_EXTI_ENABLE_IT()    EXTI->IMR |= USB_WAKEUP_EXTI_LINE
295 #define __HAL_USB_WAKEUP_EXTI_DISABLE_IT()   EXTI->IMR &= ~(USB_WAKEUP_EXTI_LINE)
296 #define __HAL_USB_EXTI_GENERATE_SWIT() (EXTI->SWIER |= USB_WAKEUP_EXTI_LINE)
297 
298 /* Internal macros -----------------------------------------------------------*/
299 
300 /* SetENDPOINT */
301 #define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue)  (*(&USBx->EP0R + bEpNum * 2U)= (uint16_t)wRegValue)
302 
303 /* GetENDPOINT */
304 #define PCD_GET_ENDPOINT(USBx, bEpNum)        (*(&USBx->EP0R + bEpNum * 2U))
305 
306 
307 
308 /**
309   * @brief  sets the type in the endpoint register(bits EP_TYPE[1:0])
310   * @param  USBx: USB device.
311   * @param  bEpNum: Endpoint Number.
312   * @param  wType: Endpoint Type.
313   * @retval None
314   */
315 #define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT(USBx, bEpNum,\
316                                   ((PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EP_T_MASK) | wType )))
317 
318 /**
319   * @brief  gets the type in the endpoint register(bits EP_TYPE[1:0])
320   * @param  USBx: USB device.
321   * @param  bEpNum: Endpoint Number.
322   * @retval Endpoint Type
323   */
324 #define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EP_T_FIELD)
325 
326 
327 /**
328   * @brief free buffer used from the application realizing it to the line
329   *         toggles bit SW_BUF in the double buffered endpoint register
330   * @param  USBx: USB device.
331   * @param   bEpNum, bDir
332   * @retval None
333   */
334 #define PCD_FreeUserBuffer(USBx, bEpNum, bDir)\
335 do {\
336   if (bDir == PCD_EP_DBUF_OUT)\
337   { /* OUT double buffered endpoint */\
338     PCD_TX_DTOG(USBx, bEpNum);\
339   }\
340   else if (bDir == PCD_EP_DBUF_IN)\
341   { /* IN double buffered endpoint */\
342     PCD_RX_DTOG(USBx, bEpNum);\
343   }\
344 } while(0)
345 
346 /**
347   * @brief gets direction of the double buffered endpoint
348   * @param  USBx: USB device.
349   * @param   bEpNum: Endpoint Number.
350   * @retval EP_DBUF_OUT, EP_DBUF_IN,
351   *         EP_DBUF_ERR if the endpoint counter not yet programmed.
352   */
353 #define PCD_GET_DB_DIR(USBx, bEpNum)\
354 do {\
355   if ((uint16_t)(*PCD_EP_RX_CNT(USBx, bEpNum) & 0xFC00U) != 0U)\
356     return(PCD_EP_DBUF_OUT);\
357   else if (((uint16_t)(*PCD_EP_TX_CNT(USBx, bEpNum)) & 0x03FFU) != 0U)\
358     return(PCD_EP_DBUF_IN);\
359   else\
360     return(PCD_EP_DBUF_ERR);\
361 } while(0)
362 
363 /**
364   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]).
365   * @param  USBx: USB device.
366   * @param  bEpNum: Endpoint Number.
367   * @param  wState: new state
368   * @retval None
369   */
370 #define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) do {\
371    register uint16_t _wRegVal;       \
372    \
373     _wRegVal = PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPTX_DTOGMASK;\
374    /* toggle first bit ? */     \
375    if((USB_EPTX_DTOG1 & wState)!= 0U)      \
376      _wRegVal ^= USB_EPTX_DTOG1;        \
377    /* toggle second bit ?  */         \
378    if((USB_EPTX_DTOG2 & wState)!= 0U)      \
379      _wRegVal ^= USB_EPTX_DTOG2;        \
380    PCD_SET_ENDPOINT(USBx, bEpNum, (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX));    \
381   } while(0) /* PCD_SET_EP_TX_STATUS */
382 
383 /**
384   * @brief  sets the status for rx transfer (bits STAT_TX[1:0])
385   * @param  USBx: USB device.
386   * @param  bEpNum: Endpoint Number.
387   * @param  wState: new state
388   * @retval None
389   */
390 #define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) do {\
391     register uint16_t _wRegVal;   \
392     \
393     _wRegVal = PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPRX_DTOGMASK;\
394     /* toggle first bit ? */  \
395     if((USB_EPRX_DTOG1 & wState)!= 0U) \
396       _wRegVal ^= USB_EPRX_DTOG1;  \
397     /* toggle second bit ? */  \
398     if((USB_EPRX_DTOG2 & wState)!= 0U) \
399       _wRegVal ^= USB_EPRX_DTOG2;  \
400     PCD_SET_ENDPOINT(USBx, bEpNum, (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX)); \
401   } while(0) /* PCD_SET_EP_RX_STATUS */
402 
403 /**
404   * @brief  sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
405   * @param  USBx: USB device.
406   * @param  bEpNum: Endpoint Number.
407   * @param  wStaterx: new state.
408   * @param  wStatetx: new state.
409   * @retval None
410   */
411 #define PCD_SET_EP_TXRX_STATUS(USBx,bEpNum,wStaterx,wStatetx) do {\
412     register uint32_t _wRegVal;   \
413     \
414     _wRegVal = PCD_GET_ENDPOINT(USBx, bEpNum) & (USB_EPRX_DTOGMASK |USB_EPTX_STAT) ;\
415     /* toggle first bit ? */  \
416     if((USB_EPRX_DTOG1 & wStaterx)!= 0U) \
417       _wRegVal ^= USB_EPRX_DTOG1;  \
418     /* toggle second bit ? */  \
419     if((USB_EPRX_DTOG2 & wStaterx)!= 0U) \
420       _wRegVal ^= USB_EPRX_DTOG2;  \
421     /* toggle first bit ? */     \
422     if((USB_EPTX_DTOG1 & wStatetx)!= 0U)      \
423       _wRegVal ^= USB_EPTX_DTOG1;        \
424     /* toggle second bit ?  */         \
425     if((USB_EPTX_DTOG2 & wStatetx)!= 0U)      \
426       _wRegVal ^= USB_EPTX_DTOG2;        \
427     PCD_SET_ENDPOINT(USBx, bEpNum, _wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX);    \
428   } while(0) /* PCD_SET_EP_TXRX_STATUS */
429 
430 /**
431   * @brief  gets the status for tx/rx transfer (bits STAT_TX[1:0]
432   *         /STAT_RX[1:0])
433   * @param  USBx: USB device.
434   * @param  bEpNum: Endpoint Number.
435   * @retval status
436   */
437 #define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPTX_STAT)
438 
439 #define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPRX_STAT)
440 
441 /**
442   * @brief  sets directly the VALID tx/rx-status into the endpoint register
443   * @param  USBx: USB device.
444   * @param  bEpNum: Endpoint Number.
445   * @retval None
446   */
447 #define PCD_SET_EP_TX_VALID(USBx, bEpNum)     (PCD_SET_EP_TX_STATUS(USBx, bEpNum, USB_EP_TX_VALID))
448 
449 #define PCD_SET_EP_RX_VALID(USBx, bEpNum)     (PCD_SET_EP_RX_STATUS(USBx, bEpNum, USB_EP_RX_VALID))
450 
451 /**
452   * @brief  checks stall condition in an endpoint.
453   * @param  USBx: USB device.
454   * @param  bEpNum: Endpoint Number.
455   * @retval TRUE = endpoint in stall condition.
456   */
457 #define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS(USBx, bEpNum) \
458                                    == USB_EP_TX_STALL)
459 #define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS(USBx, bEpNum) \
460                                    == USB_EP_RX_STALL)
461 
462 /**
463   * @brief  set & clear EP_KIND bit.
464   * @param  USBx: USB device.
465   * @param  bEpNum: Endpoint Number.
466   * @retval None
467   */
468 #define PCD_SET_EP_KIND(USBx, bEpNum)    (PCD_SET_ENDPOINT(USBx, bEpNum, \
469                                 (USB_EP_CTR_RX|USB_EP_CTR_TX|((PCD_GET_ENDPOINT(USBx, bEpNum) | USB_EP_KIND) & USB_EPREG_MASK))))
470 #define PCD_CLEAR_EP_KIND(USBx, bEpNum)  (PCD_SET_ENDPOINT(USBx, bEpNum, \
471                                 (USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPKIND_MASK))))
472 
473 /**
474   * @brief  Sets/clears directly STATUS_OUT bit in the endpoint register.
475   * @param  USBx: USB device.
476   * @param  bEpNum: Endpoint Number.
477   * @retval None
478   */
479 #define PCD_SET_OUT_STATUS(USBx, bEpNum)    PCD_SET_EP_KIND(USBx, bEpNum)
480 #define PCD_CLEAR_OUT_STATUS(USBx, bEpNum)  PCD_CLEAR_EP_KIND(USBx, bEpNum)
481 
482 /**
483   * @brief  Sets/clears directly EP_KIND bit in the endpoint register.
484   * @param  USBx: USB device.
485   * @param  bEpNum: Endpoint Number.
486   * @retval None
487   */
488 #define PCD_SET_EP_DBUF(USBx, bEpNum)   PCD_SET_EP_KIND(USBx, bEpNum)
489 #define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND(USBx, bEpNum)
490 
491 /**
492   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register.
493   * @param  USBx: USB device.
494   * @param  bEpNum: Endpoint Number.
495   * @retval None
496   */
497 #define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT(USBx, bEpNum,\
498                                    PCD_GET_ENDPOINT(USBx, bEpNum) & 0x7FFFU & USB_EPREG_MASK))
499 #define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT(USBx, bEpNum,\
500                                    PCD_GET_ENDPOINT(USBx, bEpNum) & 0xFF7FU & USB_EPREG_MASK))
501 
502 /**
503   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
504   * @param  USBx: USB device.
505   * @param  bEpNum: Endpoint Number.
506   * @retval None
507   */
508 #define PCD_RX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT(USBx, bEpNum, \
509                                    USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPREG_MASK)))
510 #define PCD_TX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT(USBx, bEpNum, \
511                                    USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPREG_MASK)))
512 
513 /**
514   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register.
515   * @param  USBx: USB device.
516   * @param  bEpNum: Endpoint Number.
517   * @retval None
518   */
519 #define PCD_CLEAR_RX_DTOG(USBx, bEpNum)  if((PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EP_DTOG_RX) != 0)\
520     PCD_RX_DTOG(USBx, bEpNum)
521 #define PCD_CLEAR_TX_DTOG(USBx, bEpNum)  if((PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EP_DTOG_TX) != 0)\
522     PCD_TX_DTOG(USBx, bEpNum)
523 
524 /**
525   * @brief  Sets address in an endpoint register.
526   * @param  USBx: USB device.
527   * @param  bEpNum: Endpoint Number.
528   * @param  bAddr: Address.
529   * @retval None
530   */
531 #define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT(USBx, bEpNum,\
532     USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPREG_MASK) | bAddr)
533 
534 /**
535   * @brief  Gets address in an endpoint register.
536   * @param  USBx: USB device.
537   * @param  bEpNum: Endpoint Number.
538   * @retval None
539   */
540 #define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT(USBx, bEpNum) & USB_EPADDR_FIELD))
541 #define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8U)+     ((uint32_t)USBx + 0x400U)))
542 #define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8U+2U)+  ((uint32_t)USBx + 0x400U)))
543 #define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8U+4U)+  ((uint32_t)USBx + 0x400U)))
544 #define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8U+6U)+  ((uint32_t)USBx + 0x400U)))
545 
546 /**
547   * @brief  sets address of the tx/rx buffer.
548   * @param  USBx: USB device.
549   * @param  bEpNum: Endpoint Number.
550   * @param  wAddr: address to be set (must be word aligned).
551   * @retval None
552   */
553 #define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_TX_ADDRESS(USBx, bEpNum) = ((wAddr >> 1U) << 1U))
554 #define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_RX_ADDRESS(USBx, bEpNum) = ((wAddr >> 1U) << 1U))
555 
556 /**
557   * @brief  Gets address of the tx/rx buffer.
558   * @param  USBx: USB device.
559   * @param  bEpNum: Endpoint Number.
560   * @retval address of the buffer.
561   */
562 #define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS(USBx, bEpNum))
563 #define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS(USBx, bEpNum))
564 
565 /**
566   * @brief  Sets counter of rx buffer with no. of blocks.
567   * @param  dwReg: Register.
568   * @param  wCount: Counter.
569   * @param  wNBlocks: Nb of block
570   * @retval None
571   */
572 #define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) do {\
573     wNBlocks = wCount >> 5;\
574     if((wCount & 0x1f) == 0)\
575       wNBlocks--;\
576     *pdwReg = (uint16_t)((wNBlocks << 10U) | 0x8000U);\
577   } while(0) /* PCD_CALC_BLK32 */
578 
579 #define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) do {\
580     wNBlocks = wCount >> 1;\
581     if((wCount & 0x1) != 0)\
582       wNBlocks++;\
583     *pdwReg = (uint16_t)(wNBlocks << 10U);\
584   } while(0) /* PCD_CALC_BLK2 */
585 
586 #define PCD_SET_EP_CNT_RX_REG(dwReg,wCount)  do {\
587     uint16_t wNBlocks;\
588     if(wCount > 62){PCD_CALC_BLK32(dwReg,wCount,wNBlocks);}\
589     else {PCD_CALC_BLK2(dwReg,wCount,wNBlocks);}\
590   } while(0) /* PCD_SET_EP_CNT_RX_REG */
591 
592 #define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum,wCount) do {\
593     uint16_t *pdwReg = PCD_EP_TX_CNT(USBx, bEpNum); \
594     PCD_SET_EP_CNT_RX_REG(pdwReg, wCount);\
595   } while(0)
596 /**
597   * @brief  sets counter for the tx/rx buffer.
598   * @param  USBx: USB device.
599   * @param  bEpNum: Endpoint Number.
600   * @param  wCount: Counter value.
601   * @retval None
602   */
603 #define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT(USBx, bEpNum) = wCount)
604 #define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) do {\
605     uint16_t *pdwReg = PCD_EP_RX_CNT(USBx, bEpNum); \
606     PCD_SET_EP_CNT_RX_REG(pdwReg, wCount);\
607   } while(0)
608 
609 /**
610   * @brief  gets counter of the tx buffer.
611   * @param  USBx: USB device.
612   * @param  bEpNum: Endpoint Number.
613   * @retval Counter value
614   */
615 #define PCD_GET_EP_TX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_TX_CNT(USBx, bEpNum)) & 0x3ffU)
616 #define PCD_GET_EP_RX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_RX_CNT(USBx, bEpNum)) & 0x3ffU)
617 
618 /**
619   * @brief  Sets buffer 0/1 address in a double buffer endpoint.
620   * @param  USBx: USB device.
621   * @param  bEpNum: Endpoint Number.
622   * @param  wBuf0Addr: buffer 0 address.
623   * @retval Counter value
624   */
625 #define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum,wBuf0Addr) {PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wBuf0Addr);}
626 #define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum,wBuf1Addr) {PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wBuf1Addr);}
627 
628 /**
629   * @brief  Sets addresses in a double buffer endpoint.
630   * @param  USBx: USB device.
631   * @param  bEpNum: Endpoint Number.
632   * @param  wBuf0Addr: buffer 0 address.
633   * @param  wBuf1Addr = buffer 1 address.
634   * @retval None
635   */
636 #define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum,wBuf0Addr,wBuf1Addr) { \
637     PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr);\
638     PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr);\
639   } /* PCD_SET_EP_DBUF_ADDR */
640 
641 /**
642   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
643   * @param  USBx: USB device.
644   * @param  bEpNum: Endpoint Number.
645   * @retval None
646   */
647 #define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS(USBx, bEpNum))
648 #define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS(USBx, bEpNum))
649 
650 /**
651   * @brief  Gets buffer 0/1 address of a double buffer endpoint.
652   * @param  USBx: USB device.
653   * @param  bEpNum: Endpoint Number.
654   * @param  bDir: endpoint dir  EP_DBUF_OUT = OUT and EP_DBUF_IN  = IN
655   * @param  wCount: Counter value
656   * @retval None
657   */
658 #define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount)  { \
659     if(bDir == PCD_EP_DBUF_OUT)\
660       /* OUT endpoint */ \
661     {PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum,wCount);} \
662     else if(bDir == PCD_EP_DBUF_IN)\
663       /* IN endpoint */ \
664       *PCD_EP_TX_CNT(USBx, bEpNum) = (uint32_t)wCount;  \
665   } /* SetEPDblBuf0Count*/
666 
667 #define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount)  { \
668     if(bDir == PCD_EP_DBUF_OUT)\
669       /* OUT endpoint */ \
670     {PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount);}\
671     else if(bDir == PCD_EP_DBUF_IN)\
672       /* IN endpoint */\
673       *PCD_EP_RX_CNT(USBx, bEpNum) = (uint32_t)wCount; \
674   } /* SetEPDblBuf1Count */
675 
676 #define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) do {\
677     PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount); \
678     PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount); \
679   } while(0) /* PCD_SET_EP_DBUF_CNT  */
680 
681 /**
682   * @brief  Gets buffer 0/1 rx/tx counter for double buffering.
683   * @param  USBx: USB device.
684   * @param  bEpNum: Endpoint Number.
685   * @retval None
686   */
687 #define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT(USBx, bEpNum))
688 #define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT(USBx, bEpNum))
689 
690 /**
691   * @}
692   */
693 
694 /**
695   * @}
696   */
697 
698 /* Exported functions --------------------------------------------------------*/
699 /** @defgroup PCD_Exported_Functions PCD Exported Functions
700   * @{
701   */
702 
703 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
704  *  @brief    Initialization and Configuration functions
705  * @{
706  */
707 /* Initialization/de-initialization functions  **********************************/
708 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
709 HAL_StatusTypeDef HAL_PCD_DeInit (PCD_HandleTypeDef *hpcd);
710 void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
711 void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
712 /**
713   * @}
714   */
715 /** @defgroup PCD_Exported_Functions_Group2 IO Data transfers functions
716  *  @brief   Data transfers functions
717  *  @{
718  */
719 
720  /* I/O operation functions  *****************************************************/
721  /* Non-Blocking mode: Interrupt */
722 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
723 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
724 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
725 
726 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
727 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
728 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
729 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
730 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
731 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
732 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
733 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
734 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
735 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
736 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
737 /**
738   * @}
739   */
740 
741 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
742  *  @brief   management functions
743  *  @{
744  */
745 /* Peripheral Control functions  ************************************************/
746 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
747 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
748 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
749 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type);
750 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
751 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
752 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
753 uint16_t          HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
754 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
755 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
756 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
757 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
758 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
759 void PCD_WritePMA(USB_TypeDef  *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
760 void PCD_ReadPMA(USB_TypeDef  *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
761 /**
762   * @}
763   */
764 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
765  *  @brief   Peripheral State functions
766  *  @{
767  */
768 
769 /* Peripheral State functions  **************************************************/
770 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
771 
772 /**
773   * @}
774   */
775 
776 /**
777   * @}
778   */
779 
780 /* Define the private group ***********************************/
781 /**************************************************************/
782 /** @defgroup PCD_Private PCD Private
783   * @{
784   */
785 /**
786   * @}
787   */
788 /**************************************************************/
789 
790 /**
791   * @}
792   */
793 
794 /**
795   * @}
796   */
797 
798 #endif /* #if !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L061xx) && !defined (STM32L071xx) && !defined (STM32L081xx) */
799 
800 #ifdef __cplusplus
801 }
802 #endif
803 
804 
805 #endif /* __STM32L0xx_HAL_PCD_H */
806 
807 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
808 
809