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