1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_USB_DRV_H
9 #define HPM_USB_DRV_H
10 /*---------------------------------------------------------------------
11  * Includes
12  *---------------------------------------------------------------------
13  */
14 #include "hpm_common.h"
15 #include "hpm_usb_regs.h"
16 #include "hpm_soc_feature.h"
17 
18 /**
19  * @brief USB driver APIs
20  * @defgroup usb_interface USB driver APIs
21  * @ingroup communication_interfaces
22  * @{
23  */
24 
25 /*---------------------------------------------------------------------
26  *  Macro Constant Declarations
27  *---------------------------------------------------------------------
28  */
29 #define USB_PHY_INIT_DELAY_COUNT  (16U) /**< a delay count for USB phy initialization */
30 #define USB_HOST_FRAMELIST_SIZE   (8U)  /**< a frame list size in USB host mode */
31 
32 /*---------------------------------------------------------------------
33  *  Macro Enum Declarations
34  *---------------------------------------------------------------------
35  */
36 /**
37  * @brief USB transfer direction types
38  */
39 typedef enum {
40     usb_dir_out     = 0,
41     usb_dir_in      = 1,
42     usb_dir_in_mask = 0x80
43 } usb_dir_t;    /**< usb_dir_t */
44 
45 /**
46  * @brief USB transfer types
47  */
48 typedef enum {
49     usb_xfer_control = 0,
50     usb_xfer_isochronous,
51     usb_xfer_bulk,
52     usb_xfer_interrupt
53 } usb_xfer_type_t;    /**< usb_xfer_type_t */
54 
55 /**
56  * @brief USB controller work modes
57  */
58 typedef enum {
59     usb_ctrl_mode_otg    = 0,
60     usb_ctrl_mode_device = 2,
61     usb_ctrl_mode_host   = 3
62 } usb_controller_mode_t;    /**< usb_controller_mode_t */
63 
64 /**
65  * @brief USB line state
66  */
67 typedef enum {
68     usb_line_state0 = 0,
69     usb_line_state1 = 1,
70     usb_line_state2 = 2
71 } usb_line_state_t;    /**< usb_line_state_t */
72 
73 /**
74  * @brief USB transceiver
75  */
76 typedef enum {
77     usb_tran_parallel = 0,
78     usb_tran_serial = 1
79 } usb_transceiver_t;    /**< usb_transceiver_t */
80 
81 /**
82  * @brief USB test modes
83  */
84 typedef enum {
85     usb_test_mode_disable = 0,
86     usb_test_j_state,
87     usb_test_k_state,
88     usb_test_se0_nak,
89     usb_test_packet,
90     usb_test_force_hs,
91     usb_test_force_fs,
92     usb_test_force_ls,
93 } usb_test_mode_t;    /**< usb_test_mode_t */
94 
95 /**
96  * @brief USB vbus wakeup source
97  */
98 typedef enum {
99     usb_vbus_wakeup_vbus_valid = 0,
100     usb_vbus_wakeup_session_valid,
101 } usb_vbus_wakeup_source_t;    /**< usb_vbus_wakeup_source_t */
102 
103 /*---------------------------------------------------------------------
104  * Structure Declarations
105  *---------------------------------------------------------------------
106  */
107 /**
108  * @brief Control request structure
109  */
110 typedef struct  __attribute__ ((packed)) {
111     union {
112         struct  __attribute__ ((packed)) {
113             uint8_t recipient :  5;
114             uint8_t type      :  2;
115             uint8_t direction :  1;
116         } bmRequestType_bit;
117 
118         uint8_t bmRequestType;
119     };
120 
121     uint8_t  bRequest;
122     uint16_t wValue;
123     uint16_t wIndex;
124     uint16_t wLength;
125 } usb_control_request_t;
126 
127 /**
128  * @brief Endpoint config structure
129  */
130 typedef struct {
131     uint8_t  xfer;
132     uint8_t  ep_addr;
133     uint16_t max_packet_size;
134 } usb_endpoint_config_t;
135 
136 #if defined __cplusplus
137 extern "C" {
138 #endif /* __cplusplus */
139 
140 /*---------------------------------------------------------------------
141  * Common API
142  *---------------------------------------------------------------------
143  */
144 
145 /**
146  * @brief Get the mask of all enabled interrupts
147  *
148  * @param[in] ptr A USB peripheral base address.
149  * @retval Mask of all enabled interrupts.
150  */
usb_get_interrupts(USB_Type * ptr)151 static inline uint32_t usb_get_interrupts(USB_Type *ptr)
152 {
153     return ptr->USBINTR;
154 }
155 
156 /**
157  * @brief Enable interrupts
158  *
159  * @param[in] ptr A USB peripheral base address
160  * @param[in] mask Mask value for interrupt events
161  */
usb_enable_interrupts(USB_Type * ptr,uint32_t mask)162 static inline void usb_enable_interrupts(USB_Type *ptr, uint32_t mask)
163 {
164     ptr->USBINTR |= mask;
165 }
166 
167 /**
168  * @brief Get all USB status flags
169  *
170  * @param[in] ptr A USB peripheral base address
171  * @retval The USB interrupt status flags
172  */
usb_get_status_flags(USB_Type * ptr)173 static inline uint32_t usb_get_status_flags(USB_Type *ptr)
174 {
175     return ptr->USBSTS;
176 }
177 
178 /**
179  * @brief Clear status flags
180  *
181  * Only the specified flags can be cleared by writing USBSTS register.
182  *
183  * @param[in] ptr A USB peripheral base address
184  * @param[in] mask Mask value for flags to be cleared.
185  */
186 
usb_clear_status_flags(USB_Type * ptr,uint32_t mask)187 static inline void usb_clear_status_flags(USB_Type *ptr, uint32_t mask)
188 {
189     ptr->USBSTS = mask;
190 }
191 
192 /**
193  * @brief Enable otg vbus wakeup
194  *
195  * @param[in] ptr A USB peripheral base address
196  */
usb_otg_enable_vbus_wakeup(USB_Type * ptr)197 static inline void usb_otg_enable_vbus_wakeup(USB_Type *ptr)
198 {
199     ptr->OTG_CTRL0 |=  USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK;
200 }
201 
202 /**
203  * @brief Disbable otg vbus wakeup
204  *
205  * @param[in] ptr A USB peripheral base address
206  */
usb_otg_disable_vbus_wakeup(USB_Type * ptr)207 static inline void usb_otg_disable_vbus_wakeup(USB_Type *ptr)
208 {
209     ptr->OTG_CTRL0 &=  ~USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK;
210 }
211 
212 /**
213  * @brief Set otg vbus wakeup source
214  *
215  * @param[in] ptr A USB peripheral base address
216  * @param[in] src wakeup source, @ref usb_vbus_wakeup_source_t
217  */
usb_otg_set_vbus_wakeup_source(USB_Type * ptr,usb_vbus_wakeup_source_t src)218 static inline void usb_otg_set_vbus_wakeup_source(USB_Type *ptr, usb_vbus_wakeup_source_t src)
219 {
220     ptr->OTG_CTRL0 = (ptr->OTG_CTRL0 & ~USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK) | USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SET(src);
221 }
222 
223 /**
224  * @brief Enable otg wakeup interrupt
225  *
226  * @param[in] ptr A USB peripheral base address
227  */
usb_otg_enable_wakeup_int(USB_Type * ptr)228 static inline void usb_otg_enable_wakeup_int(USB_Type *ptr)
229 {
230     ptr->OTG_CTRL0 |=  USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK;
231 }
232 
233 /**
234  * @brief Disable otg wakeup interrupt
235  *
236  * @param[in] ptr A USB peripheral base address
237  */
usb_otg_disable_wakeup_int(USB_Type * ptr)238 static inline void usb_otg_disable_wakeup_int(USB_Type *ptr)
239 {
240     ptr->OTG_CTRL0 &= ~USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK;
241 }
242 
243 /**
244  * @brief Get otg wakeup status flags
245  *
246  * @param[in] ptr A USB peripheral base address
247  * @retval The USB otg wakeup interrupt status flag
248  */
usb_get_otg_wakeup_int_flag(USB_Type * ptr)249 static inline bool usb_get_otg_wakeup_int_flag(USB_Type *ptr)
250 {
251     return (USB_TOP_STATUS_WAKEUP_INT_STATUS_GET(ptr->TOP_STATUS) != 0) ? true : false;
252 }
253 
254 /**
255  * @brief Get USB suspend status
256  *
257  * @param[in] ptr A USB peripheral base address
258  * @retval The USB controller suspend status
259  */
usb_get_suspend_status(USB_Type * ptr)260 static inline uint8_t usb_get_suspend_status(USB_Type *ptr)
261 {
262     return USB_PORTSC1_SUSP_GET(ptr->PORTSC1);
263 }
264 
265 /**
266  * @brief Get USB reset status
267  *
268  * @param[in] ptr A USB peripheral base address
269  * @retval The USB controller reset status
270  */
usb_get_port_reset_status(USB_Type * ptr)271 static inline bool usb_get_port_reset_status(USB_Type *ptr)
272 {
273     return USB_PORTSC1_PR_GET(ptr->PORTSC1);
274 }
275 
276 /**
277  * @brief Get USB current connect status
278  *
279  * @param[in] ptr A USB peripheral base address
280  * @retval The USB controller reset status
281  */
usb_get_port_ccs(USB_Type * ptr)282 static inline bool usb_get_port_ccs(USB_Type *ptr)
283 {
284     return USB_PORTSC1_CCS_GET(ptr->PORTSC1);
285 }
286 
287 /**
288  * @brief Get USB port speed status
289  *
290  * @param[in] ptr A USB peripheral base address
291  * @retval The USB controller port speed status
292  */
usb_get_port_speed(USB_Type * ptr)293 static inline uint8_t usb_get_port_speed(USB_Type *ptr)
294 {
295     return USB_PORTSC1_PSPD_GET(ptr->PORTSC1);
296 }
297 
298 /**
299  * @brief Set port test control mode
300  *
301  * @param[in] ptr A USB peripheral base address
302  * @param[in] test_mode usb test mode, @ref usb_test_mode_t
303  */
usb_set_port_test_mode(USB_Type * ptr,usb_test_mode_t test_mode)304 static inline void usb_set_port_test_mode(USB_Type *ptr, usb_test_mode_t test_mode)
305 {
306     ptr->PORTSC1 = (ptr->PORTSC1 & ~USB_PORTSC1_PTC_MASK) | USB_PORTSC1_PTC_SET(test_mode);
307 }
308 
309 /**
310  * @brief USB set port suspend
311  *
312  * @param[in] ptr A USB peripheral base address
313  * @param[in] suspend true - suspend, false - not suspend
314  */
usb_set_port_suspend(USB_Type * ptr,bool suspend)315 static inline void usb_set_port_suspend(USB_Type *ptr, bool suspend)
316 {
317     ptr->PORTSC1 = (ptr->PORTSC1 & ~USB_PORTSC1_SUSP_MASK) | USB_PORTSC1_SUSP_SET(suspend);
318 }
319 
320 /**
321  * @brief USB force port resume
322  *
323  * @param[in] ptr A USB peripheral base address
324  */
usb_force_port_resume(USB_Type * ptr)325 static inline void usb_force_port_resume(USB_Type *ptr)
326 {
327     ptr->PORTSC1 |= USB_PORTSC1_FPR_MASK;
328 }
329 
330 /**
331  * @brief USB phy enter low power suspend
332  *
333  * @param[in] ptr A USB peripheral base address
334  */
usb_phy_enter_low_power_suspend(USB_Type * ptr)335 static inline void usb_phy_enter_low_power_suspend(USB_Type *ptr)
336 {
337     ptr->PORTSC1 |= USB_PORTSC1_PHCD_MASK;
338 }
339 
340 /**
341  * @brief USB phy exit low power suspend
342  *
343  * @param[in] ptr A USB peripheral base address
344  */
usb_phy_exit_low_power_suspend(USB_Type * ptr)345 static inline void usb_phy_exit_low_power_suspend(USB_Type *ptr)
346 {
347     ptr->PORTSC1 &= ~USB_PORTSC1_PHCD_MASK;
348     /* otg utmi clock detection */
349     ptr->PHY_STATUS |= USB_PHY_STATUS_UTMI_CLK_VALID_MASK;                 /* write 1 to clear valid status */
350     while (USB_PHY_STATUS_UTMI_CLK_VALID_GET(ptr->PHY_STATUS) == 0) {      /* get utmi clock status */
351         ;
352     }
353 }
354 
355 /**
356  * @brief Get phy session valid flag
357  *
358  * @param[in] ptr A USB peripheral base address
359  * @retval The phy session valid flag
360  */
usb_phy_get_session_valid_flag(USB_Type * ptr)361 static inline bool usb_phy_get_session_valid_flag(USB_Type *ptr)
362 {
363     return (USB_PHY_STATUS_UTMI_SESS_VALID_GET(ptr->PHY_STATUS) != 0) ? true : false;
364 }
365 
366 /**
367  * @brief enable otgsc session valid change interrupt
368  *
369  * @param[in] ptr A USB peripheral base address
370  */
usb_otgsc_enable_session_valid_chg_int(USB_Type * ptr)371 static inline void usb_otgsc_enable_session_valid_chg_int(USB_Type *ptr)
372 {
373     ptr->OTGSC |= USB_OTGSC_ASVIE_MASK;
374 }
375 
376 /**
377  * @brief disable otgsc session valid change interrupt
378  *
379  * @param[in] ptr A USB peripheral base address
380  */
usb_otgsc_disable_session_valid_chg_int(USB_Type * ptr)381 static inline void usb_otgsc_disable_session_valid_chg_int(USB_Type *ptr)
382 {
383     ptr->OTGSC &= ~USB_OTGSC_ASVIE_MASK;
384 }
385 
386 /**
387  * @brief get otgsc session valid change flag
388  *
389  * @param[in] ptr A USB peripheral base address
390  * @retval The otgsc session valid flag
391  */
usb_otgsc_get_session_valid_chg_flag(USB_Type * ptr)392 static inline bool usb_otgsc_get_session_valid_chg_flag(USB_Type *ptr)
393 {
394     return (USB_OTGSC_ASVIS_SET(ptr->OTGSC) != 0) ? true : false;
395 }
396 
397 /**
398  * @brief clear otgsc session valid change flag
399  *
400  * @param[in] ptr A USB peripheral base address
401  */
usb_otgsc_clear_session_valid_chg_flag(USB_Type * ptr)402 static inline void usb_otgsc_clear_session_valid_chg_flag(USB_Type *ptr)
403 {
404     ptr->OTGSC |= USB_OTGSC_ASVIS_MASK;
405 }
406 
407 /**
408  * @brief Get otgsc session valid flag
409  *
410  * @param[in] ptr A USB peripheral base address
411  * @retval The otgsc session valid flag
412  */
usb_otgsc_get_session_valid_flag(USB_Type * ptr)413 static inline bool usb_otgsc_get_session_valid_flag(USB_Type *ptr)
414 {
415     return (USB_OTGSC_ASV_GET(ptr->OTGSC) != 0) ? true : false;
416 }
417 
418 /**
419  * @brief Initialize USB phy
420  *
421  * @param[in] ptr A USB peripheral base address
422  */
423 void usb_phy_init(USB_Type *ptr);
424 
425 /**
426  * @brief USB phy get line status
427  *
428  * @param[in] ptr A USB peripheral base address
429  */
usb_phy_get_line_state(USB_Type * ptr)430 static inline uint8_t usb_phy_get_line_state(USB_Type *ptr)
431 {
432     return USB_PHY_STATUS_LINE_STATE_GET(ptr->PHY_STATUS);
433 }
434 
435 /**
436  * @brief USB phy using internal vbus
437  *
438  * @param[in] ptr A USB peripheral base address
439  */
usb_phy_using_internal_vbus(USB_Type * ptr)440 static inline void usb_phy_using_internal_vbus(USB_Type *ptr)
441 {
442     ptr->PHY_CTRL0 |= (USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK | USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK)
443                     | (USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK | USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK);
444 }
445 
446 /**
447  * @brief USB phy using external vbus
448  *
449  * @param[in] ptr A USB peripheral base address
450  */
usb_phy_using_external_vbus(USB_Type * ptr)451 static inline void usb_phy_using_external_vbus(USB_Type *ptr)
452 {
453     ptr->PHY_CTRL0 &= ~((USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK | USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK)
454                       | (USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK | USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK));
455 }
456 
457 /**
458  * @brief USB phy disconnect dp/dm pins pulldown resistance
459  *
460  * @param[in] ptr A USB peripheral base address
461  */
usb_phy_disable_dp_dm_pulldown(USB_Type * ptr)462 static inline void usb_phy_disable_dp_dm_pulldown(USB_Type *ptr)
463 {
464     ptr->PHY_CTRL0 |= 0x001000E0u;
465 }
466 
467 /**
468  * @brief USB phy connect dp/dm pins pulldown resistance
469  *
470  * @param[in] ptr A USB peripheral base address
471  */
usb_phy_enable_dp_dm_pulldown(USB_Type * ptr)472 static inline void usb_phy_enable_dp_dm_pulldown(USB_Type *ptr)
473 {
474     ptr->PHY_CTRL0 &= ~0x001000E0u;
475 }
476 
477 /**
478  * @brief Set phyctrl1 not utmi suspend
479  *
480  * @param[in] ptr A USB peripheral base address
481  */
usb_phyctrl1_set_not_utmi_suspend(USB_Type * ptr)482 static inline void usb_phyctrl1_set_not_utmi_suspend(USB_Type *ptr)
483 {
484     ptr->PHY_CTRL1 |= USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK;
485 }
486 
487 /*---------------------------------------------------------------------
488  * Device API
489  *---------------------------------------------------------------------
490  */
491 
492 /**
493  * @brief USB device bus reset
494  *
495  * @param[in] ptr A USB peripheral base address
496  * @param[in] ep0_max_packet_size The maximum packet size of endpoint 0
497  */
498 void usb_dcd_bus_reset(USB_Type *ptr, uint16_t ep0_max_packet_size);
499 
500 /**
501  * @brief Initialize controller to device mode
502  *
503  * @param[in] ptr A USB peripheral base address
504  */
505 void usb_dcd_init(USB_Type *ptr);
506 
507 /**
508  * @brief Deinitialize controller to device
509  *
510  * @param[in] ptr A USB peripheral base address
511  */
512 void usb_dcd_deinit(USB_Type *ptr);
513 
514 /**
515  * @brief Wakeup from host
516  *
517  * @param[in] ptr A USB peripheral base address
518  */
519 void usb_dcd_remote_wakeup(USB_Type *ptr);
520 
521 /**
522  * @brief Open an endpoint
523  *
524  * @param[in] ptr A USB peripheral base address
525  * @param[in] config A pointer to the specified endpoint config struct
526  */
527 void usb_dcd_edpt_open(USB_Type *ptr, usb_endpoint_config_t *config);
528 
529 /**
530  * @brief get a specified endpoint type
531  *
532  * @param[in] ptr A USB peripheral base address
533  * @param[in] ep_addr Endpoint address
534  */
535 uint8_t usb_dcd_edpt_get_type(USB_Type *ptr, uint8_t ep_addr);
536 
537 /**
538  * @brief Submit a transfer
539  *
540  * @param[in] ptr A USB peripheral base address
541  * @param[in] ep_idx An index of the specified endpoint
542  */
543 void usb_dcd_edpt_xfer(USB_Type *ptr, uint8_t ep_idx);
544 
545 /**
546  * @brief Stall endpoint
547  *
548  * @param[in] ptr A USB peripheral base address
549  * @param[in] ep_addr An address of the specified endpoint
550  */
551 void usb_dcd_edpt_stall(USB_Type *ptr, uint8_t ep_addr);
552 
553 /**
554  * @brief Clear stall
555  *
556  * @param[in] ptr A USB peripheral base address
557  * @param[in] ep_addr An address of the specified endpoint
558  */
559 void usb_dcd_edpt_clear_stall(USB_Type *ptr, uint8_t ep_addr);
560 
561 /**
562  * @brief Clear stall
563  *
564  * @param[in] ptr A USB peripheral base address
565  * @param[in] ep_addr An address of the specified endpoint
566  * @retval The status of endpoint stall, true is stall, false is not stall
567  */
568 bool usb_dcd_edpt_check_stall(USB_Type *ptr, uint8_t ep_addr);
569 
570 /**
571  * @brief Close a specified endpoint
572  *
573  * @param[in] ptr A USB peripheral base address
574  * @param[in] ep_addr An address of the specified endpoint
575  */
576 void usb_dcd_edpt_close(USB_Type *ptr, uint8_t ep_addr);
577 
578 /**
579  * @brief Connect by enabling internal pull-up resistor on D+/D-
580  *
581  * @param[in] ptr A USB peripheral base address
582  */
583 void usb_dcd_connect(USB_Type *ptr);
584 
585 /**
586  * @brief Disconnect by disabling internal pull-up resistor on D+/D-
587  *
588  * @param[in] ptr A USB peripheral base address
589  */
590 void usb_dcd_disconnect(USB_Type *ptr);
591 
592 /**
593  * @brief Get setup status of endpoint
594  *
595  * @param[in] ptr A USB peripheral base address
596  * @retval The status of setup endpoint
597  */
usb_dcd_get_edpt_setup_status(USB_Type * ptr)598 static inline uint32_t usb_dcd_get_edpt_setup_status(USB_Type *ptr)
599 {
600     return ptr->ENDPTSETUPSTAT;
601 }
602 
603 /**
604  * @brief Clear the setup status of all specified endpoints
605  *
606  * @param[in] ptr A USB peripheral base address
607  * @param[in] mask A mask of all specified endpoints
608  */
usb_dcd_clear_edpt_setup_status(USB_Type * ptr,uint32_t mask)609 static inline void usb_dcd_clear_edpt_setup_status(USB_Type *ptr, uint32_t mask)
610 {
611     ptr->ENDPTSETUPSTAT = mask;
612 }
613 
614 /**
615  * @brief Set address
616  *
617  * @param[in] ptr A USB peripheral base address
618  * @param[in] dev_addr An assigned endpoint address from USB host
619  */
usb_dcd_set_address(USB_Type * ptr,uint8_t dev_addr)620 static inline void usb_dcd_set_address(USB_Type *ptr, uint8_t dev_addr)
621 {
622     ptr->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(dev_addr) | USB_DEVICEADDR_USBADRA_MASK;
623 }
624 
625 /**
626  * @brief Set endpoint list address
627  *
628  * @param[in] ptr A USB peripheral base address
629  * @param[in] addr A start address of the endpoint qtd list
630  */
usb_dcd_set_edpt_list_addr(USB_Type * ptr,uint32_t addr)631 static inline void usb_dcd_set_edpt_list_addr(USB_Type *ptr, uint32_t addr)
632 {
633     ptr->ENDPTLISTADDR = addr & USB_ENDPTLISTADDR_EPBASE_MASK;
634 }
635 
636 /**
637  * @brief Get device address
638  *
639  * @param[in] ptr A USB peripheral base address
640  * @retval The endpoint address
641  */
usb_dcd_get_device_addr(USB_Type * ptr)642 static inline uint8_t usb_dcd_get_device_addr(USB_Type *ptr)
643 {
644     return USB_DEVICEADDR_USBADR_GET(ptr->DEVICEADDR);
645 }
646 
647 /**
648  * @brief Get complete status of endpoint
649  *
650  * @param[in] ptr A USB peripheral base address
651  * @retval The complete status od endpoint
652  */
usb_dcd_get_edpt_complete_status(USB_Type * ptr)653 static inline uint32_t usb_dcd_get_edpt_complete_status(USB_Type *ptr)
654 {
655     return ptr->ENDPTCOMPLETE;
656 }
657 
658 /**
659  * @brief Clear complete status of endpoint
660  *
661  * @param[in] ptr A USB peripheral base address
662  * @param[in] mask A mask of the specified endpoints
663  */
usb_dcd_clear_edpt_complete_status(USB_Type * ptr,uint32_t mask)664 static inline void usb_dcd_clear_edpt_complete_status(USB_Type *ptr, uint32_t mask)
665 {
666     ptr->ENDPTCOMPLETE = mask;
667 }
668 
669 /*---------------------------------------------------------------------
670  * Host API
671  *---------------------------------------------------------------------
672  */
673 /**
674  * @brief Initialize controller to host mode
675  *
676  * @param[in] ptr A USB peripheral base address
677  * @param[in] int_mask A mask of all required interrupts
678  * @param[in] framelist_size A size of the frame list
679  */
680 bool usb_hcd_init(USB_Type *ptr, uint32_t int_mask, uint16_t framelist_size);
681 
682 /**
683  * @brief Initialize controller to host modeHost Reset port
684  *
685  * @param[in] ptr A USB peripheral base address
686  */
687 void usb_hcd_port_reset(USB_Type *ptr);
688 
689 /**
690  * @brief Initialize controller to host modeHost set command register
691  *
692  * @param[in] ptr A USB peripheral base address
693  * @param[in] mask A mask of all required commands
694  */
usb_hcd_set_command(USB_Type * ptr,uint32_t mask)695 static inline void usb_hcd_set_command(USB_Type *ptr, uint32_t mask)
696 {
697     ptr->USBCMD |= mask;
698 }
699 
700 /**
701  * @brief Get frame index
702  *
703  * @param[in] ptr A USB peripheral base address
704  * @retval A index of the current frame list
705  */
usb_hcd_get_frame_index(USB_Type * ptr)706 static inline uint32_t usb_hcd_get_frame_index(USB_Type *ptr)
707 {
708     return ptr->FRINDEX;
709 }
710 
711 /**
712  * @brief Get port connect status change
713  *
714  * @param[in] ptr A USB peripheral base address
715  * @retval A connect status change
716  */
usb_hcd_get_port_csc(USB_Type * ptr)717 static inline bool usb_hcd_get_port_csc(USB_Type *ptr)
718 {
719     return USB_PORTSC1_CSC_GET(ptr->PORTSC1);
720 }
721 
722 /**
723  * @brief Set power ctrl polarity
724  *
725  * @param[in] ptr A USB peripheral base address
726  * @param[in] high true - vbus high level enable, false - vbus low level enable
727  */
usb_hcd_set_power_ctrl_polarity(USB_Type * ptr,bool high)728 static inline void usb_hcd_set_power_ctrl_polarity(USB_Type *ptr, bool high)
729 {
730     if (high) {
731         ptr->OTG_CTRL0 |= USB_OTG_CTRL0_OTG_POWER_MASK_MASK;
732     } else {
733         ptr->OTG_CTRL0 &= ~USB_OTG_CTRL0_OTG_POWER_MASK_MASK;
734     }
735 }
736 
737 /**
738  * @brief Enable port power
739  *
740  * @param[in] ptr A USB peripheral base address
741  */
usb_hcd_enable_port_power(USB_Type * ptr)742 static inline void usb_hcd_enable_port_power(USB_Type *ptr)
743 {
744     ptr->PORTSC1 |= USB_PORTSC1_PP_MASK;
745 }
746 
747 /**
748  * @brief Get port connect status changeSet async list address
749  *
750  * @param[in] ptr A USB peripheral base address
751  * @param[in] addr An the start address of the async endpoint list
752  */
usb_hcd_set_async_list_addr(USB_Type * ptr,uint32_t addr)753 static inline void usb_hcd_set_async_list_addr(USB_Type *ptr, uint32_t addr)
754 {
755     ptr->ASYNCLISTADDR = addr & USB_ASYNCLISTADDR_ASYBASE_MASK;
756 }
757 
758 /**
759  * @brief Set periodic list address
760  *
761  * @param[in] ptr A USB peripheral base address
762  * @param[in] addr An start address of the periodic endpoint list
763  */
usb_hcd_set_periodic_list_addr(USB_Type * ptr,uint32_t addr)764 static inline void usb_hcd_set_periodic_list_addr(USB_Type *ptr, uint32_t addr)
765 {
766     ptr->PERIODICLISTBASE = addr & USB_PERIODICLISTBASE_BASEADR_MASK;
767 }
768 
769 /**
770  * @brief Start hcd controller
771  *
772  * @param[in] ptr A USB peripheral base address
773  */
usb_hcd_run(USB_Type * ptr)774 static inline void usb_hcd_run(USB_Type *ptr)
775 {
776     ptr->USBCMD |= USB_USBCMD_RS_MASK;
777 }
778 
779 /**
780  * @brief Stop hcd controller
781  *
782  * @param[in] ptr A USB peripheral base address
783  */
usb_hcd_stop(USB_Type * ptr)784 static inline void usb_hcd_stop(USB_Type *ptr)
785 {
786     ptr->USBCMD &= ~USB_USBCMD_RS_MASK;
787 }
788 
789 #if defined __cplusplus
790 }
791 #endif /* __cplusplus */
792 
793 /** @} */
794 #endif /* HPM_USB_DRV_H */
795