1 /**************************************************************************//**
2  * @file     usbd.h
3  * @version  V3.00
4  * @brief    M460 series USBD driver header file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
8  ****************************************************************************/
9 #ifndef __USBD_H__
10 #define __USBD_H__
11 
12 //#define SUPPORT_LPM     // define to support LPM
13 
14 #ifdef __cplusplus
15 extern "C"
16 {
17 #endif
18 
19 
20 /** @addtogroup Standard_Driver Standard Driver
21   @{
22 */
23 
24 /** @addtogroup USBD_Driver USBD Driver
25   @{
26 */
27 
28 /** @addtogroup USBD_EXPORTED_STRUCT USBD Exported Struct
29   @{
30 */
31 
32 typedef struct s_usbd_info
33 {
34     uint8_t *gu8DevDesc;            /*!< Pointer for USB Device Descriptor          */
35     uint8_t *gu8ConfigDesc;         /*!< Pointer for USB Configuration Descriptor   */
36     uint8_t **gu8StringDesc;        /*!< Pointer for USB String Descriptor pointers */
37     uint8_t **gu8HidReportDesc;     /*!< Pointer for USB HID Report Descriptor      */
38     uint8_t *gu8BosDesc;            /*!< Pointer for USB BOS Descriptor             */
39     uint32_t *gu32HidReportSize;    /*!< Pointer for HID Report descriptor Size */
40     uint32_t *gu32ConfigHidDescIdx; /*!< Pointer for HID Descriptor start index */
41 
42 } S_USBD_INFO_T;  /*!< Device description structure */
43 
44 extern const S_USBD_INFO_T gsInfo;
45 
46 /*@}*/ /* end of group USBD_EXPORTED_STRUCT */
47 
48 
49 /** @addtogroup USBD_EXPORTED_CONSTANTS USBD Exported Constants
50   @{
51 */
52 
53 #define USBD_BUF_BASE   (USBD_BASE+0x800ul)  /*!< USBD buffer base address \hideinitializer */
54 #define USBD_MAX_EP     25ul /*!< Total EP number \hideinitializer */
55 
56 #define EP0     0ul       /*!< Endpoint 0 \hideinitializer */
57 #define EP1     1ul       /*!< Endpoint 1 \hideinitializer */
58 #define EP2     2ul       /*!< Endpoint 2 \hideinitializer */
59 #define EP3     3ul       /*!< Endpoint 3 \hideinitializer */
60 #define EP4     4ul       /*!< Endpoint 4 \hideinitializer */
61 #define EP5     5ul       /*!< Endpoint 5 \hideinitializer */
62 #define EP6     6ul       /*!< Endpoint 6 \hideinitializer */
63 #define EP7     7ul       /*!< Endpoint 7 \hideinitializer */
64 #define EP8     8ul       /*!< Endpoint 8 \hideinitializer */
65 #define EP9     9ul       /*!< Endpoint 9 \hideinitializer */
66 #define EP10    10ul      /*!< Endpoint 10 \hideinitializer */
67 #define EP11    11ul      /*!< Endpoint 11 \hideinitializer */
68 #define EP12    12ul      /*!< Endpoint 12 \hideinitializer */
69 #define EP13    13ul      /*!< Endpoint 13 \hideinitializer */
70 #define EP14    14ul      /*!< Endpoint 14 \hideinitializer */
71 #define EP15    15ul      /*!< Endpoint 15 \hideinitializer */
72 #define EP16    16ul      /*!< Endpoint 16 \hideinitializer */
73 #define EP17    17ul      /*!< Endpoint 17 \hideinitializer */
74 #define EP18    18ul      /*!< Endpoint 18 \hideinitializer */
75 #define EP19    19ul      /*!< Endpoint 19 \hideinitializer */
76 #define EP20    20ul      /*!< Endpoint 20 \hideinitializer */
77 #define EP21    21ul      /*!< Endpoint 21 \hideinitializer */
78 #define EP22    22ul      /*!< Endpoint 22 \hideinitializer */
79 #define EP23    23ul      /*!< Endpoint 23 \hideinitializer */
80 #define EP24    24ul      /*!< Endpoint 24 \hideinitializer */
81 
82 /** @cond HIDDEN_SYMBOLS */
83 /* USB Request Type */
84 #define REQ_STANDARD        0x00ul
85 #define REQ_CLASS           0x20ul
86 #define REQ_VENDOR          0x40ul
87 
88 /* USB Standard Request */
89 #define GET_STATUS          0x00ul
90 #define CLEAR_FEATURE       0x01ul
91 #define SET_FEATURE         0x03ul
92 #define SET_ADDRESS         0x05ul
93 #define GET_DESCRIPTOR      0x06ul
94 #define SET_DESCRIPTOR      0x07ul
95 #define GET_CONFIGURATION   0x08ul
96 #define SET_CONFIGURATION   0x09ul
97 #define GET_INTERFACE       0x0Aul
98 #define SET_INTERFACE       0x0Bul
99 #define SYNC_FRAME          0x0Cul
100 
101 /* USB Descriptor Type */
102 #define DESC_DEVICE         0x01ul
103 #define DESC_CONFIG         0x02ul
104 #define DESC_STRING         0x03ul
105 #define DESC_INTERFACE      0x04ul
106 #define DESC_ENDPOINT       0x05ul
107 #define DESC_QUALIFIER      0x06ul
108 #define DESC_OTHERSPEED     0x07ul
109 #define DESC_IFPOWER        0x08ul
110 #define DESC_OTG            0x09ul
111 #define DESC_BOS            0x0Ful
112 #define DESC_CAPABILITY     0x10ul
113 
114 /* USB Device Capability Type */
115 #define CAP_WIRELESS        0x01ul
116 #define CAP_USB20_EXT       0x02ul
117 
118 /* USB HID Descriptor Type */
119 #define DESC_HID            0x21ul
120 #define DESC_HID_RPT        0x22ul
121 
122 /* USB Descriptor Length */
123 #define LEN_DEVICE          18ul
124 #define LEN_QUALIFIER       10ul
125 #define LEN_CONFIG          9ul
126 #define LEN_INTERFACE       9ul
127 #define LEN_ENDPOINT        7ul
128 #define LEN_OTG             5ul
129 #define LEN_BOS             5ul
130 #define LEN_HID             9ul
131 #define LEN_CCID            0x36ul
132 #define LEN_BOSCAP          7ul
133 
134 /* USB Endpoint Type */
135 #define EP_ISO              0x01
136 #define EP_BULK             0x02
137 #define EP_INT              0x03
138 
139 #define EP_INPUT            0x80
140 #define EP_OUTPUT           0x00
141 
142 /* USB Feature Selector */
143 #define FEATURE_DEVICE_REMOTE_WAKEUP    0x01ul
144 #define FEATURE_ENDPOINT_HALT           0x00ul
145 /** @endcond HIDDEN_SYMBOLS */
146 
147 /******************************************************************************/
148 /*                USB Specific Macros                                         */
149 /******************************************************************************/
150 
151 #define USBD_WAKEUP_EN          USBD_INTEN_WKEN_Msk         /*!< USB Wake-up Enable \hideinitializer */
152 #define USBD_DRVSE0             USBD_SE0_SE0_Msk            /*!< Drive SE0 \hideinitializer */
153 
154 #define USBD_LPMACK             USBD_ATTR_LPMACK_Msk        /*!< LPM Enable \hideinitializer */
155 #define USBD_BYTEM              USBD_ATTR_BYTEM_Msk         /*!< Access Size Mode Selection \hideinitializer */
156 #define USBD_PWRDN              USBD_ATTR_PWRDN_Msk         /*!< PHY Turn-On \hideinitializer */
157 #define USBD_DPPU_EN            USBD_ATTR_DPPUEN_Msk        /*!< USB D+ Pull-up Enable \hideinitializer */
158 #define USBD_USB_EN             USBD_ATTR_USBEN_Msk         /*!< USB Enable \hideinitializer */
159 #define USBD_RWAKEUP            USBD_ATTR_RWAKEUP_Msk       /*!< Remote Wake-Up \hideinitializer */
160 #define USBD_PHY_EN             USBD_ATTR_PHYEN_Msk         /*!< PHY Enable \hideinitializer */
161 
162 #define USBD_INT_BUS            USBD_INTEN_BUSIEN_Msk       /*!< USB Bus Event Interrupt \hideinitializer */
163 #define USBD_INT_USB            USBD_INTEN_USBIEN_Msk       /*!< USB Event Interrupt \hideinitializer */
164 #define USBD_INT_FLDET          USBD_INTEN_VBDETIEN_Msk     /*!< USB VBUS Detection Interrupt \hideinitializer */
165 #define USBD_INT_WAKEUP         (USBD_INTEN_NEVWKIEN_Msk | USBD_INTEN_WKEN_Msk)     /*!< USB No-Event-Wake-Up Interrupt \hideinitializer */
166 #define USBD_INT_SOF            USBD_INTEN_SOFIEN_Msk       /*!< USB Start of Frame Interrupt \hideinitializer */
167 
168 #define USBD_INTSTS_WAKEUP      USBD_INTSTS_NEVWKIF_Msk     /*!< USB No-Event-Wake-Up Interrupt Status \hideinitializer */
169 #define USBD_INTSTS_FLDET       USBD_INTSTS_VBDETIF_Msk     /*!< USB Float Detect Interrupt Status \hideinitializer */
170 #define USBD_INTSTS_BUS         USBD_INTSTS_BUSIF_Msk       /*!< USB Bus Event Interrupt Status \hideinitializer */
171 #define USBD_INTSTS_USB         USBD_INTSTS_USBIF_Msk       /*!< USB Event Interrupt Status \hideinitializer */
172 #define USBD_INTSTS_SETUP       USBD_INTSTS_SETUP_Msk       /*!< USB Setup Event \hideinitializer */
173 #define USBD_INTSTS_EP0         USBD_INTSTS_EPEVT0_Msk      /*!< USB Endpoint 0 Event \hideinitializer */
174 #define USBD_INTSTS_EP1         USBD_INTSTS_EPEVT1_Msk      /*!< USB Endpoint 1 Event \hideinitializer */
175 #define USBD_INTSTS_EP2         USBD_INTSTS_EPEVT2_Msk      /*!< USB Endpoint 2 Event \hideinitializer */
176 #define USBD_INTSTS_EP3         USBD_INTSTS_EPEVT3_Msk      /*!< USB Endpoint 3 Event \hideinitializer */
177 #define USBD_INTSTS_EP4         USBD_INTSTS_EPEVT4_Msk      /*!< USB Endpoint 4 Event \hideinitializer */
178 #define USBD_INTSTS_EP5         USBD_INTSTS_EPEVT5_Msk      /*!< USB Endpoint 5 Event \hideinitializer */
179 #define USBD_INTSTS_EP6         USBD_INTSTS_EPEVT6_Msk      /*!< USB Endpoint 6 Event \hideinitializer */
180 #define USBD_INTSTS_EP7         USBD_INTSTS_EPEVT7_Msk      /*!< USB Endpoint 7 Event \hideinitializer */
181 #define USBD_INTSTS_EP8         USBD_INTSTS_EPEVT8_Msk      /*!< USB Endpoint 8 Event \hideinitializer */
182 #define USBD_INTSTS_EP9         USBD_INTSTS_EPEVT9_Msk      /*!< USB Endpoint 9 Event \hideinitializer */
183 #define USBD_INTSTS_EP10        USBD_INTSTS_EPEVT10_Msk     /*!< USB Endpoint 10 Event \hideinitializer */
184 #define USBD_INTSTS_EP11        USBD_INTSTS_EPEVT11_Msk     /*!< USB Endpoint 11 Event \hideinitializer */
185 
186 #define USBD_EPINTSTS_EP0       USBD_EPINTSTS_EPEVT0_Msk    /*!< USB Endpoint 0 Event \hideinitializer */
187 #define USBD_EPINTSTS_EP1       USBD_EPINTSTS_EPEVT1_Msk    /*!< USB Endpoint 1 Event \hideinitializer */
188 #define USBD_EPINTSTS_EP2       USBD_EPINTSTS_EPEVT2_Msk    /*!< USB Endpoint 2 Event \hideinitializer */
189 #define USBD_EPINTSTS_EP3       USBD_EPINTSTS_EPEVT3_Msk    /*!< USB Endpoint 3 Event \hideinitializer */
190 #define USBD_EPINTSTS_EP4       USBD_EPINTSTS_EPEVT4_Msk    /*!< USB Endpoint 4 Event \hideinitializer */
191 #define USBD_EPINTSTS_EP5       USBD_EPINTSTS_EPEVT5_Msk    /*!< USB Endpoint 5 Event \hideinitializer */
192 #define USBD_EPINTSTS_EP6       USBD_EPINTSTS_EPEVT6_Msk    /*!< USB Endpoint 6 Event \hideinitializer */
193 #define USBD_EPINTSTS_EP7       USBD_EPINTSTS_EPEVT7_Msk    /*!< USB Endpoint 7 Event \hideinitializer */
194 #define USBD_EPINTSTS_EP8       USBD_EPINTSTS_EPEVT8_Msk    /*!< USB Endpoint 8 Event \hideinitializer */
195 #define USBD_EPINTSTS_EP9       USBD_EPINTSTS_EPEVT9_Msk    /*!< USB Endpoint 9 Event \hideinitializer */
196 #define USBD_EPINTSTS_EP10      USBD_EPINTSTS_EPEVT10_Msk   /*!< USB Endpoint 10 Event \hideinitializer */
197 #define USBD_EPINTSTS_EP11      USBD_EPINTSTS_EPEVT11_Msk   /*!< USB Endpoint 11 Event \hideinitializer */
198 #define USBD_EPINTSTS_EP12      USBD_EPINTSTS_EPEVT12_Msk   /*!< USB Endpoint 12 Event \hideinitializer */
199 #define USBD_EPINTSTS_EP13      USBD_EPINTSTS_EPEVT13_Msk   /*!< USB Endpoint 13 Event \hideinitializer */
200 #define USBD_EPINTSTS_EP14      USBD_EPINTSTS_EPEVT14_Msk   /*!< USB Endpoint 14 Event \hideinitializer */
201 #define USBD_EPINTSTS_EP15      USBD_EPINTSTS_EPEVT15_Msk   /*!< USB Endpoint 15 Event \hideinitializer */
202 #define USBD_EPINTSTS_EP16      USBD_EPINTSTS_EPEVT16_Msk   /*!< USB Endpoint 16 Event \hideinitializer */
203 #define USBD_EPINTSTS_EP17      USBD_EPINTSTS_EPEVT17_Msk   /*!< USB Endpoint 17 Event \hideinitializer */
204 #define USBD_EPINTSTS_EP18      USBD_EPINTSTS_EPEVT18_Msk   /*!< USB Endpoint 18 Event \hideinitializer */
205 #define USBD_EPINTSTS_EP19      USBD_EPINTSTS_EPEVT19_Msk   /*!< USB Endpoint 19 Event \hideinitializer */
206 #define USBD_EPINTSTS_EP20      USBD_EPINTSTS_EPEVT20_Msk   /*!< USB Endpoint 20 Event \hideinitializer */
207 #define USBD_EPINTSTS_EP21      USBD_EPINTSTS_EPEVT21_Msk   /*!< USB Endpoint 21 Event \hideinitializer */
208 #define USBD_EPINTSTS_EP22      USBD_EPINTSTS_EPEVT22_Msk   /*!< USB Endpoint 22 Event \hideinitializer */
209 #define USBD_EPINTSTS_EP23      USBD_EPINTSTS_EPEVT23_Msk   /*!< USB Endpoint 23 Event \hideinitializer */
210 #define USBD_EPINTSTS_EP24      USBD_EPINTSTS_EPEVT24_Msk   /*!< USB Endpoint 24 Event \hideinitializer */
211 
212 #define USBD_STATE_USBRST       USBD_ATTR_USBRST_Msk        /*!< USB Bus Reset \hideinitializer */
213 #define USBD_STATE_SUSPEND      USBD_ATTR_SUSPEND_Msk       /*!< USB Bus Suspend \hideinitializer */
214 #define USBD_STATE_RESUME       USBD_ATTR_RESUME_Msk        /*!< USB Bus Resume \hideinitializer */
215 #define USBD_STATE_TIMEOUT      USBD_ATTR_TOUT_Msk          /*!< USB Bus Timeout \hideinitializer */
216 #define USBD_STATE_L1SUSPEND    USBD_ATTR_L1SUSPEND_Msk     /*!< USB Bus L1SUSPEND \hideinitializer */
217 #define USBD_STATE_L1RESUME     USBD_ATTR_L1RESUME_Msk      /*!< USB Bus L1RESUME \hideinitializer */
218 
219 #define USBD_CFG_DB_EN          USBD_CFG_DBEN_Msk           /*!< Double Buffer Enable \hideinitializer */
220 #define USBD_CFG_DBTGACTIVE     USBD_CFG_DBTGACTIVE_Msk     /*!< Double Buffer Toggle Active \hideinitializer */
221 
222 #define USBD_CFGP_SSTALL        USBD_CFGP_SSTALL_Msk        /*!< Set Stall \hideinitializer */
223 #define USBD_CFG_CSTALL         USBD_CFG_CSTALL_Msk         /*!< Clear Stall \hideinitializer */
224 
225 #define USBD_CFG_EPMODE_DISABLE (0ul << USBD_CFG_STATE_Pos) /*!< Endpoint Disable \hideinitializer */
226 #define USBD_CFG_EPMODE_OUT     (1ul << USBD_CFG_STATE_Pos) /*!< Out Endpoint \hideinitializer */
227 #define USBD_CFG_EPMODE_IN      (2ul << USBD_CFG_STATE_Pos) /*!< In Endpoint \hideinitializer */
228 #define USBD_CFG_TYPE_ISO       (1ul << USBD_CFG_ISOCH_Pos) /*!< Isochronous \hideinitializer */
229 
230 /*@}*/ /* end of group USBD_EXPORTED_CONSTANTS */
231 
232 
233 /** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions
234   @{
235 */
236 
237 /**
238   * @brief      Compare two input numbers and return maximum one.
239   *
240   * @param[in]  a   First number to be compared.
241   * @param[in]  b   Second number to be compared.
242   *
243   * @return     Maximum value between a and b.
244   *
245   * @details    If a > b, then return a. Otherwise, return b.
246   * \hideinitializer
247   */
248 #define USBD_Maximum(a,b)        ((a)>(b) ? (a) : (b))
249 
250 /**
251   * @brief      Compare two input numbers and return minimum one
252   *
253   * @param[in]  a   First number to be compared
254   * @param[in]  b   Second number to be compared
255   *
256   * @return     Minimum value between a and b
257   *
258   * @details    If a < b, then return a. Otherwise, return b.
259   * \hideinitializer
260   */
261 #define USBD_Minimum(a,b)        ((a)<(b) ? (a) : (b))
262 
263 /**
264   * @brief    Enable USB
265   *
266   * @param    None
267   *
268   * @return   None
269   *
270   * @details  To set USB ATTR control register to enable USB and PHY.
271   * \hideinitializer
272   */
273 #define USBD_ENABLE_USB()           ((uint32_t)(USBD->ATTR |= 0x7D0))
274 
275 /**
276   * @brief    Disable USB
277   *
278   * @param    None
279   *
280   * @return   None
281   *
282   * @details  To set USB ATTR control register to disable USB.
283   * \hideinitializer
284   */
285 #define USBD_DISABLE_USB()          ((uint32_t)(USBD->ATTR &= ~USBD_USB_EN))
286 
287 /**
288   * @brief    Enable USB PHY
289   *
290   * @param    None
291   *
292   * @return   None
293   *
294   * @details  To set USB ATTR control register to enable USB PHY.
295   * \hideinitializer
296   */
297 #define USBD_ENABLE_PHY()           ((uint32_t)(USBD->ATTR |= USBD_PHY_EN))
298 
299 /**
300   * @brief    Disable USB PHY
301   *
302   * @param    None
303   *
304   * @return   None
305   *
306   * @details  To set USB ATTR control register to disable USB PHY.
307   * \hideinitializer
308   */
309 #define USBD_DISABLE_PHY()          ((uint32_t)(USBD->ATTR &= ~USBD_PHY_EN))
310 
311 /**
312   * @brief    Enable SE0. Force USB PHY transceiver to drive SE0.
313   *
314   * @param    None
315   *
316   * @return   None
317   *
318   * @details  Set DRVSE0 bit of USB_DRVSE0 register to enable software-disconnect function. Force USB PHY transceiver to drive SE0 to bus.
319   * \hideinitializer
320   */
321 #define USBD_SET_SE0()              ((uint32_t)(USBD->SE0 |= USBD_DRVSE0))
322 
323 /**
324   * @brief    Disable SE0
325   *
326   * @param    None
327   *
328   * @return   None
329   *
330   * @details  Clear DRVSE0 bit of USB_DRVSE0 register to disable software-disconnect function.
331   * \hideinitializer
332   */
333 #define USBD_CLR_SE0()              ((uint32_t)(USBD->SE0 &= ~USBD_DRVSE0))
334 
335 /**
336   * @brief       Set USB device address
337   *
338   * @param[in]   addr The USB device address.
339   *
340   * @return      None
341   *
342   * @details     Write USB device address to USB_FADDR register.
343   * \hideinitializer
344   */
345 #define USBD_SET_ADDR(addr)         (USBD->FADDR = (addr))
346 
347 /**
348   * @brief    Get USB device address
349   *
350   * @param    None
351   *
352   * @return   USB device address
353   *
354   * @details  Read USB_FADDR register to get USB device address.
355   * \hideinitializer
356   */
357 #define USBD_GET_ADDR()             ((uint32_t)(USBD->FADDR))
358 
359 /**
360   * @brief      Enable USB interrupt function
361   *
362   * @param[in]  intr The combination of the specified interrupt enable bits.
363   *             Each bit corresponds to a interrupt enable bit.
364   *             This parameter decides which interrupts will be enabled.
365   *             (USBD_INT_SOF, USBD_INT_WAKEUP, USBD_INT_FLDET, USBD_INT_USB, USBD_INT_BUS)
366   *
367   * @return     None
368   *
369   * @details    Enable USB related interrupt functions specified by intr parameter.
370   * \hideinitializer
371   */
372 #define USBD_ENABLE_INT(intr)       (USBD->INTEN |= (intr))
373 
374 /**
375   * @brief    Get interrupt status
376   *
377   * @param    None
378   *
379   * @return   The value of USB_INTSTS register
380   *
381   * @details  Return all interrupt flags of USB_INTSTS register.
382   * \hideinitializer
383   */
384 #define USBD_GET_INT_FLAG()         ((uint32_t)(USBD->INTSTS))
385 
386 /**
387   * @brief      Clear USB interrupt flag
388   *
389   * @param[in]  flag The combination of the specified interrupt flags.
390   *             Each bit corresponds to a interrupt source.
391   *             This parameter decides which interrupt flags will be cleared.
392   *             (USBD_INT_SOF, USBD_INTSTS_WAKEUP, USBD_INTSTS_FLDET, USBD_INTSTS_BUS, USBD_INTSTS_USB)
393   *
394   * @return     None
395   *
396   * @details    Clear USB related interrupt flags specified by flag parameter.
397   * \hideinitializer
398   */
399 #define USBD_CLR_INT_FLAG(flag)     (USBD->INTSTS = (flag))
400 
401 /**
402   * @brief    Get endpoint interrupt status
403   *
404   * @param    None
405   *
406   * @return   The value of USB_EPINTSTS register
407   *
408   * @details  Return all endpoint interrupt flags of USB_EPINTSTS register.
409   * \hideinitializer
410   */
411 #define USBD_GET_EP_INT_FLAG()      ((uint32_t)(USBD->EPINTSTS))
412 
413 /**
414   * @brief      Clear USB endpoint interrupt flag
415   *
416   * @param[in]  flag The combination of the specified endpoint interrupt flags.
417   *             Each bit corresponds to a endpoint interrupt source.
418   *             This parameter decides which endpoint interrupt flags will be cleared.
419   *
420   * @return     None
421   *
422   * @details    Clear USB related interrupt flags specified by flag parameter.
423   * \hideinitializer
424   */
425 #define USBD_CLR_EP_INT_FLAG(flag)     (USBD->EPINTSTS = (flag))
426 
427 /**
428   * @brief    Get endpoint status
429   *
430   * @param    None
431   *
432   * @return   The value of USB_EPSTS register.
433   *
434   * @details  Return all endpoint status.
435   * \hideinitializer
436   */
437 #define USBD_GET_EP_FLAG()          ((uint32_t)(USBD->EPSTS))
438 
439 /**
440   * @brief    Get USB bus state
441   *
442   * @param    None
443   *
444   * @return   The value of USB_ATTR[13:12] and USB_ATTR[3:0].
445   *           Bit 0  indicates USB bus reset status.
446   *           Bit 1  indicates USB bus suspend status.
447   *           Bit 2  indicates USB bus resume status.
448   *           Bit 3  indicates USB bus time-out status.
449   *           Bit 12 indicates USB bus LPM L1 suspend status.
450   *           Bit 13 indicates USB bus LPM L1 resume status.
451   *
452   * @details  Return USB_ATTR[13:12] and USB_ATTR[3:0] for USB bus events.
453   * \hideinitializer
454   */
455 #define USBD_GET_BUS_STATE()        ((uint32_t)(USBD->ATTR & 0x300f))
456 
457 /**
458   * @brief    Check cable connection state
459   *
460   * @param    None
461   *
462   * @retval   0 USB cable is not attached.
463   * @retval   1 USB cable is attached.
464   *
465   * @details  Check the connection state by FLDET bit of USB_FLDET register.
466   * \hideinitializer
467   */
468 #define USBD_IS_ATTACHED()          ((uint32_t)(USBD->VBUSDET & USBD_VBUSDET_VBUSDET_Msk))
469 
470 /**
471   * @brief      Stop USB transaction of the specified endpoint ID
472   *
473   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
474   *
475   * @return     None
476   *
477   * @details    Write 1 to CLRRDY bit of USB_CFGPx register to stop USB transaction of the specified endpoint ID.
478   * \hideinitializer
479   */
480 #define USBD_STOP_TRANSACTION(ep)   (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_CLRRDY_Msk)
481 
482 /**
483   * @brief      Set USB DATA1 PID for the specified endpoint ID
484   *
485   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
486   *
487   * @return     None
488   *
489   * @details    Set DSQ_SYNC bit of USB_CFGx register to specify the DATA1 PID for the following IN token transaction.
490   *             Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
491   * \hideinitializer
492   */
493 #define USBD_SET_DATA1(ep)          (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DSQSYNC_Msk)
494 
495 /**
496   * @brief      Set USB DATA0 PID for the specified endpoint ID
497   *
498   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
499   *
500   * @return     None
501   *
502   * @details    Clear DSQ_SYNC bit of USB_CFGx register to specify the DATA0 PID for the following IN token transaction.
503   *             Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
504   * \hideinitializer
505   */
506 #define USBD_SET_DATA0(ep)          (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DSQSYNC_Msk))
507 
508 /**
509   * @brief      Set USB payload size (IN data)
510   *
511   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
512   *
513   * @param[in]  size The transfer length.
514   *
515   * @return     None
516   *
517   * @details    This macro will write the transfer length to USB_MXPLDx register for IN data transaction.
518   * \hideinitializer
519   */
520 #define USBD_SET_PAYLOAD_LEN(ep, size)  (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))) = (size))
521 
522 /**
523   * @brief      Get USB payload size (OUT data)
524   *
525   * @param[in]  ep The USB endpoint ID. M460 Series supports 8 endpoint ID. This parameter could be 0 ~ 24.
526   *
527   * @return     The value of USB_MXPLDx register.
528   *
529   * @details    Get the data length of OUT data transaction by reading USB_MXPLDx register.
530   * \hideinitializer
531   */
532 #define USBD_GET_PAYLOAD_LEN(ep)        ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))))
533 
534 /**
535   * @brief      Configure endpoint
536   *
537   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
538   *
539   * @param[in]  config The USB configuration.
540   *
541   * @return     None
542   *
543   * @details    This macro will write config parameter to USB_CFGx register of specified endpoint ID.
544   * \hideinitializer
545   */
546 #define USBD_CONFIG_EP(ep, config)      (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) = (config))
547 
548 /**
549   * @brief      Set USB endpoint buffer
550   *
551   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
552   *
553   * @param[in]  offset The SRAM offset.
554   *
555   * @return     None
556   *
557   * @details    This macro will set the SRAM offset for the specified endpoint ID.
558   * \hideinitializer
559   */
560 #define USBD_SET_EP_BUF_ADDR(ep, offset)    (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))) = (offset))
561 
562 /**
563   * @brief      Get the offset of the specified USB endpoint buffer
564   *
565   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
566   *
567   * @return     The offset of the specified endpoint buffer.
568   *
569   * @details    This macro will return the SRAM offset of the specified endpoint ID.
570   * \hideinitializer
571   */
572 #define USBD_GET_EP_BUF_ADDR(ep)        ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))))
573 
574 /**
575   * @brief       Set USB endpoint stall state
576   *
577   * @param[in]   ep  The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
578   *
579   * @return      None
580   *
581   * @details     Set USB endpoint stall state for the specified endpoint ID. Endpoint will respond STALL token automatically.
582   * \hideinitializer
583   */
584 #define USBD_SET_EP_STALL(ep)        (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0ul].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_SSTALL_Msk)
585 
586 /**
587   * @brief       Clear USB endpoint stall state
588   *
589   * @param[in]   ep  The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
590   *
591   * @return      None
592   *
593   * @details     Clear USB endpoint stall state for the specified endpoint ID. Endpoint will respond ACK/NAK token.
594   * \hideinitializer
595   */
596 #define USBD_CLR_EP_STALL(ep)        (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) &= ~USBD_CFGP_SSTALL_Msk)
597 
598 /**
599   * @brief       Get USB endpoint stall state
600   *
601   * @param[in]   ep  The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
602   *
603   * @retval      0      USB endpoint is not stalled.
604   * @retval      Others USB endpoint is stalled.
605   *
606   * @details     Get USB endpoint stall state of the specified endpoint ID.
607   * \hideinitializer
608   */
609 #define USBD_GET_EP_STALL(ep)        (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) & USBD_CFGP_SSTALL_Msk)
610 
611 /**
612   * @brief      Set USB double buffer mode for the specified endpoint ID
613   *
614   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
615   *
616   * @return     None
617   *
618   * @details    Set DBEN bit of USB_CFGx register to enable the double buffer mode of the specified endpoint ID.
619   * \hideinitializer
620   */
621 #define USBD_SET_DB_MODE(ep)          (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DBEN_Msk)
622 
623 /**
624   * @brief      Set USB single buffer mode for the specified endpoint ID
625   *
626   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
627   *
628   * @return     None
629   *
630   * @details    Clear DBEN bit of USB_CFGx register to enable the single buffer mode of the specified endpoint ID.
631   * \hideinitializer
632   */
633 #define USBD_SET_SB_MODE(ep)          (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DBEN_Msk))
634 
635 /**
636   * @brief      Get the buffer mode of the specified USB endpoint buffer
637   *
638   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
639   *
640   * @retval     0 USB is single buffer mode.
641   * @retval     1 USB is double buffer mode.
642   *
643   * @details    This macro will return the buffer mode of the specified endpoint ID.
644   * \hideinitializer
645   */
646 #define USBD_IS_DB_MODE(ep)           (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) & USBD_CFG_DBEN_Msk)
647 
648 /**
649   * @brief      Set to active in USB double buffer mode for the specified endpoint ID
650   *
651   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
652   *
653   * @return     None
654   *
655   * @details    Set DBTGACTIVE bit of USB_CFGx register for toggle active in the double buffer mode of the specified endpoint ID.
656   * \hideinitializer
657   */
658 #define USBD_SET_DB_ACTIVE(ep)        (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DBTGACTIVE_Msk)
659 
660 /**
661   * @brief      Set to inactive in USB double buffer mode for the specified endpoint ID
662   *
663   * @param[in]  ep The USB endpoint ID. M460 Series supports 25 hardware endpoint ID. This parameter could be 0 ~ 24.
664   *
665   * @return     None
666   *
667   * @details    Clear DBTGACTIVE bit of USB_CFGx register for toggle inactive in the double buffer mode of the specified endpoint ID.
668   * \hideinitializer
669   */
670 #define USBD_SET_DB_INACTIVE(ep)      (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DBTGACTIVE_Msk))
671 
672 /**
673   * @brief      To support byte access between USB SRAM and system SRAM
674   *
675   * @param[in]  dest Destination pointer.
676   *
677   * @param[in]  src  Source pointer.
678   *
679   * @param[in]  size Byte count.
680   *
681   * @return     None
682   *
683   * @details    This function will copy the number of data specified by size and src parameters to the address specified by dest parameter.
684   *
685   */
USBD_MemCopy(uint8_t dest[],uint8_t src[],uint32_t size)686 __STATIC_INLINE void USBD_MemCopy(uint8_t dest[], uint8_t src[], uint32_t size)
687 {
688     uint32_t volatile i=0ul;
689 
690     while(size--)
691     {
692         dest[i] = src[i];
693         i++;
694     }
695 }
696 
697 /**
698   * @brief       Set USB endpoint stall state
699   *
700   * @param[in]   epnum  USB endpoint number
701   *
702   * @return      None
703   *
704   * @details     Set USB endpoint stall state. Endpoint will respond STALL token automatically.
705   *
706   */
USBD_SetStall(uint8_t epnum)707 __STATIC_INLINE void USBD_SetStall(uint8_t epnum)
708 {
709     uint32_t u32CfgAddr;
710     uint32_t u32Cfg;
711     uint32_t i;
712 
713     for(i = 0ul; i < USBD_MAX_EP; i++)
714     {
715         u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
716         u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
717 
718         if((u32Cfg & 0xful) == epnum)
719         {
720             u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
721             u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
722 
723             *((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg | USBD_CFGP_SSTALL);
724             break;
725         }
726     }
727 }
728 
729 /**
730   * @brief       Clear USB endpoint stall state
731   *
732   * @param[in]   epnum  USB endpoint number
733   *
734   * @return      None
735   *
736   * @details     Clear USB endpoint stall state. Endpoint will respond ACK/NAK token.
737   *
738   */
USBD_ClearStall(uint8_t epnum)739 __STATIC_INLINE void USBD_ClearStall(uint8_t epnum)
740 {
741     uint32_t u32CfgAddr;
742     uint32_t u32Cfg;
743     uint32_t i;
744 
745     for(i = 0ul; i < USBD_MAX_EP; i++)
746     {
747         u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
748         u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
749 
750         if((u32Cfg & 0xful) == epnum)
751         {
752             u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
753             u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
754 
755             *((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg & ~USBD_CFGP_SSTALL);
756             break;
757         }
758     }
759 }
760 
761 /**
762   * @brief       Get USB endpoint stall state
763   *
764   * @param[in]   epnum  USB endpoint number
765   *
766   * @retval      0      USB endpoint is not stalled.
767   * @retval      Others USB endpoint is stalled.
768   *
769   * @details     Get USB endpoint stall state.
770   *
771   */
USBD_GetStall(uint8_t epnum)772 __STATIC_INLINE uint32_t USBD_GetStall(uint8_t epnum)
773 {
774     uint32_t u32CfgAddr;
775     uint32_t u32Cfg;
776     uint32_t i;
777 
778     for(i = 0ul; i < USBD_MAX_EP; i++)
779     {
780         u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
781         u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
782 
783         if((u32Cfg & 0xful) == epnum)
784         {
785             u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
786             break;
787         }
788     }
789 
790     return ((*((__IO uint32_t *)(u32CfgAddr))) & USBD_CFGP_SSTALL);
791 }
792 
793 extern uint8_t g_usbd_SetupPacket[8];
794 extern volatile uint8_t g_usbd_RemoteWakeupEn;
795 
796 
797 typedef void (*VENDOR_REQ)(void);           /*!< Functional pointer type definition for Vendor class */
798 typedef void (*CLASS_REQ)(void);            /*!< Functional pointer type declaration for USB class request callback handler */
799 typedef void (*SET_INTERFACE_REQ)(uint32_t u32AltInterface);    /*!< Functional pointer type declaration for USB set interface request callback handler */
800 typedef void (*SET_CONFIG_CB)(void);       /*!< Functional pointer type declaration for USB set configuration request callback handler */
801 
802 
803 /*--------------------------------------------------------------------*/
804 void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface);
805 void USBD_Start(void);
806 void USBD_GetSetupPacket(uint8_t *buf);
807 void USBD_ProcessSetupPacket(void);
808 void USBD_GetDescriptor(void);
809 void USBD_StandardRequest(void);
810 void USBD_PrepareCtrlIn(uint8_t pu8Buf[], uint32_t u32Size);
811 void USBD_CtrlIn(void);
812 void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size);
813 void USBD_CtrlOut(void);
814 void USBD_SwReset(void);
815 void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq);
816 void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback);
817 void USBD_LockEpStall(uint32_t u32EpBitmap);
818 
819 
820 /*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */
821 
822 /*@}*/ /* end of group USBD_Driver */
823 
824 /*@}*/ /* end of group Standard_Driver */
825 
826 #ifdef __cplusplus
827 }
828 #endif
829 
830 #endif /*__USBD_H__*/
831