hpm_usb_drv.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_USB_DRV_H
  8. #define HPM_USB_DRV_H
  9. /*---------------------------------------------------------------------
  10. * Includes
  11. *---------------------------------------------------------------------
  12. */
  13. #include "hpm_common.h"
  14. #include "hpm_usb_regs.h"
  15. #include "hpm_soc_feature.h"
  16. /**
  17. * @brief USB driver APIs
  18. * @defgroup usb_interface USB driver APIs
  19. * @ingroup communication_interfaces
  20. * @{
  21. */
  22. /*---------------------------------------------------------------------
  23. * Macro Constant Declarations
  24. *---------------------------------------------------------------------
  25. */
  26. #define USB_PHY_INIT_DELAY_COUNT (16U) /**< a delay count for USB phy initialization */
  27. #define USB_HOST_FRAMELIST_SIZE (8U) /**< a frame list size in USB host mode */
  28. /*---------------------------------------------------------------------
  29. * Macro Enum Declarations
  30. *---------------------------------------------------------------------
  31. */
  32. /**
  33. * @brief USB transfer direction types
  34. */
  35. typedef enum {
  36. usb_dir_out = 0,
  37. usb_dir_in = 1,
  38. usb_dir_in_mask = 0x80
  39. } usb_dir_t;
  40. /**
  41. * @brief USB transfer types
  42. */
  43. typedef enum {
  44. usb_xfer_control = 0,
  45. usb_xfer_isochronous,
  46. usb_xfer_bulk,
  47. usb_xfer_interrupt
  48. } usb_xfer_type_t;
  49. /**
  50. * @brief USB controller work modes
  51. */
  52. typedef enum {
  53. usb_ctrl_mode_otg = 0,
  54. usb_ctrl_mode_device = 2,
  55. usb_ctrl_mode_host = 3
  56. } usb_controller_mode_t;
  57. /**
  58. * @brief USB line state
  59. */
  60. typedef enum {
  61. usb_line_state0 = 0,
  62. usb_line_state1 = 1,
  63. usb_line_state2 = 2
  64. } usb_line_state_t;
  65. /**
  66. * @brief USB transceiver
  67. */
  68. typedef enum {
  69. usb_tran_parallel = 0,
  70. usb_tran_serial = 1
  71. } usb_transceiver_t;
  72. /*---------------------------------------------------------------------
  73. * Structure Declarations
  74. *---------------------------------------------------------------------
  75. */
  76. /**
  77. * @brief Control request structure
  78. */
  79. typedef struct __attribute__ ((packed)) {
  80. union {
  81. struct __attribute__ ((packed)) {
  82. uint8_t recipient : 5;
  83. uint8_t type : 2;
  84. uint8_t direction : 1;
  85. } bmRequestType_bit;
  86. uint8_t bmRequestType;
  87. };
  88. uint8_t bRequest;
  89. uint16_t wValue;
  90. uint16_t wIndex;
  91. uint16_t wLength;
  92. } usb_control_request_t;
  93. /**
  94. * @brief Endpoint config structure
  95. */
  96. typedef struct {
  97. uint8_t xfer;
  98. uint8_t ep_addr;
  99. uint16_t max_packet_size;
  100. } usb_endpoint_config_t;
  101. #if defined __cplusplus
  102. extern "C" {
  103. #endif /* __cplusplus */
  104. /*---------------------------------------------------------------------
  105. * Common API
  106. *---------------------------------------------------------------------
  107. */
  108. /**
  109. * @brief Get the mask of all enabled interrupts
  110. *
  111. * @param[in] ptr A USB peripheral base address.
  112. * @retval Mask of all enabled interrupts.
  113. */
  114. static inline uint32_t usb_get_interrupts(USB_Type *ptr)
  115. {
  116. return ptr->USBINTR;
  117. }
  118. /**
  119. * @brief Enable interrupts
  120. *
  121. * @param[in] ptr A USB peripheral base address
  122. * @param[in] mask Mask value for interrupt events
  123. */
  124. static inline void usb_enable_interrupts(USB_Type *ptr, uint32_t mask)
  125. {
  126. ptr->USBINTR |= mask;
  127. }
  128. /**
  129. * @brief Get all USB status flags
  130. *
  131. * @param[in] ptr A USB peripheral base address
  132. * @retval The USB interrupt status flags
  133. */
  134. static inline uint32_t usb_get_status_flags(USB_Type *ptr)
  135. {
  136. return ptr->USBSTS;
  137. }
  138. /**
  139. * @brief Clear status flags
  140. *
  141. * Only the specified flags can be cleared by writing USBSTS register.
  142. *
  143. * @param[in] ptr A USB peripheral base address
  144. * @param[in] mask Mask value for flags to be cleared.
  145. */
  146. static inline void usb_clear_status_flags(USB_Type *ptr, uint32_t mask)
  147. {
  148. ptr->USBSTS = mask;
  149. }
  150. /**
  151. * @brief Get USB suspend status
  152. *
  153. * @param[in] ptr A USB peripheral base address
  154. * @retval The USB controller suspend status
  155. */
  156. static inline uint8_t usb_get_suspend_status(USB_Type *ptr)
  157. {
  158. return USB_PORTSC1_SUSP_GET(ptr->PORTSC1);
  159. }
  160. /**
  161. * @brief Get USB reset status
  162. *
  163. * @param[in] ptr A USB peripheral base address
  164. * @retval The USB controller reset status
  165. */
  166. static inline bool usb_get_port_reset_status(USB_Type *ptr)
  167. {
  168. return USB_PORTSC1_PR_GET(ptr->PORTSC1);
  169. }
  170. /**
  171. * @brief Get USB current connect status
  172. *
  173. * @param[in] ptr A USB peripheral base address
  174. * @retval The USB controller reset status
  175. */
  176. static inline bool usb_get_port_ccs(USB_Type *ptr)
  177. {
  178. return USB_PORTSC1_CCS_GET(ptr->PORTSC1);
  179. }
  180. /**
  181. * @brief Get USB port speed status
  182. *
  183. * @param[in] ptr A USB peripheral base address
  184. * @retval The USB controller port speed status
  185. */
  186. static inline uint8_t usb_get_port_speed(USB_Type *ptr)
  187. {
  188. return USB_PORTSC1_PSPD_GET(ptr->PORTSC1);
  189. }
  190. /*---------------------------------------------------------------------
  191. * Device API
  192. *---------------------------------------------------------------------
  193. */
  194. /**
  195. * @brief Initialize USB phy
  196. *
  197. * @param[in] ptr A USB peripheral base address
  198. */
  199. void usb_phy_init(USB_Type *ptr);
  200. /**
  201. * @brief USB device bus reset
  202. *
  203. * @param[in] ptr A USB peripheral base address
  204. * @param[in] ep0_max_packet_size The maximum packet size of endpoint 0
  205. */
  206. void usb_dcd_bus_reset(USB_Type *ptr, uint16_t ep0_max_packet_size);
  207. /**
  208. * @brief Initialize controller to device mode
  209. *
  210. * @param[in] ptr A USB peripheral base address
  211. */
  212. void usb_dcd_init(USB_Type *ptr);
  213. /**
  214. * @brief Deinitialize controller to device
  215. *
  216. * @param[in] ptr A USB peripheral base address
  217. */
  218. void usb_dcd_deinit(USB_Type *ptr);
  219. /**
  220. * @brief Wakeup from host
  221. *
  222. * @param[in] ptr A USB peripheral base address
  223. */
  224. void usb_dcd_remote_wakeup(USB_Type *ptr);
  225. /**
  226. * @brief Open an endpoint
  227. *
  228. * @param[in] ptr A USB peripheral base address
  229. * @param[in] config A pointer to the specified endpoint config struct
  230. */
  231. void usb_dcd_edpt_open(USB_Type *ptr, usb_endpoint_config_t *config);
  232. /**
  233. * @brief get a specified endpoint type
  234. *
  235. * @param[in] ptr A USB peripheral base address
  236. * @param[in] ep_addr Endpoint address
  237. */
  238. uint8_t usb_dcd_edpt_get_type(USB_Type *ptr, uint8_t ep_addr);
  239. /**
  240. * @brief Submit a transfer
  241. *
  242. * @param[in] ptr A USB peripheral base address
  243. * @param[in] ep_idx An index of the specified endpoint
  244. */
  245. void usb_dcd_edpt_xfer(USB_Type *ptr, uint8_t ep_idx);
  246. /**
  247. * @brief Stall endpoint
  248. *
  249. * @param[in] ptr A USB peripheral base address
  250. * @param[in] ep_addr An address of the specified endpoint
  251. */
  252. void usb_dcd_edpt_stall(USB_Type *ptr, uint8_t ep_addr);
  253. /**
  254. * @brief Clear stall
  255. *
  256. * @param[in] ptr A USB peripheral base address
  257. * @param[in] ep_addr An address of the specified endpoint
  258. */
  259. void usb_dcd_edpt_clear_stall(USB_Type *ptr, uint8_t ep_addr);
  260. /**
  261. * @brief Close a specified endpoint
  262. *
  263. * @param[in] ptr A USB peripheral base address
  264. * @param[in] ep_addr An address of the specified endpoint
  265. */
  266. void usb_dcd_edpt_close(USB_Type *ptr, uint8_t ep_addr);
  267. /**
  268. * @brief Connect by enabling internal pull-up resistor on D+/D-
  269. *
  270. * @param[in] ptr A USB peripheral base address
  271. */
  272. void usb_dcd_connect(USB_Type *ptr);
  273. /**
  274. * @brief Disconnect by disabling internal pull-up resistor on D+/D-
  275. *
  276. * @param[in] ptr A USB peripheral base address
  277. */
  278. void usb_dcd_disconnect(USB_Type *ptr);
  279. /**
  280. * @brief Get setup status of endpoint
  281. *
  282. * @param[in] ptr A USB peripheral base address
  283. * @retval The status of setup endpoint
  284. */
  285. static inline uint32_t usb_dcd_get_edpt_setup_status(USB_Type *ptr)
  286. {
  287. return ptr->ENDPTSETUPSTAT;
  288. }
  289. /**
  290. * @brief Clear the setup status of all specified endpoints
  291. *
  292. * @param[in] ptr A USB peripheral base address
  293. * @param[in] mask A mask of all specified endpoints
  294. */
  295. static inline void usb_dcd_clear_edpt_setup_status(USB_Type *ptr, uint32_t mask)
  296. {
  297. ptr->ENDPTSETUPSTAT = mask;
  298. }
  299. /**
  300. * @brief Set address
  301. *
  302. * @param[in] ptr A USB peripheral base address
  303. * @param[in] dev_addr An assigned endpoint address from USB host
  304. */
  305. static inline void usb_dcd_set_address(USB_Type *ptr, uint8_t dev_addr)
  306. {
  307. ptr->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(dev_addr) | USB_DEVICEADDR_USBADRA_MASK;
  308. }
  309. /**
  310. * @brief Set endpoint list address
  311. *
  312. * @param[in] ptr A USB peripheral base address
  313. * @param[in] addr A start address of the endpoint qtd list
  314. */
  315. static inline void usb_dcd_set_edpt_list_addr(USB_Type *ptr, uint32_t addr)
  316. {
  317. ptr->ENDPTLISTADDR = addr & USB_ENDPTLISTADDR_EPBASE_MASK;
  318. }
  319. /**
  320. * @brief Get device address
  321. *
  322. * @param[in] ptr A USB peripheral base address
  323. * @retval The endpoint address
  324. */
  325. static inline uint8_t usb_dcd_get_device_addr(USB_Type *ptr)
  326. {
  327. return USB_DEVICEADDR_USBADR_GET(ptr->DEVICEADDR);
  328. }
  329. /**
  330. * @brief Get complete status of endpoint
  331. *
  332. * @param[in] ptr A USB peripheral base address
  333. * @retval The complete status od endpoint
  334. */
  335. static inline uint32_t usb_dcd_get_edpt_complete_status(USB_Type *ptr)
  336. {
  337. return ptr->ENDPTCOMPLETE;
  338. }
  339. /**
  340. * @brief Clear complete status of endpoint
  341. *
  342. * @param[in] ptr A USB peripheral base address
  343. * @param[in] mask A mask of the specified endpoints
  344. */
  345. static inline void usb_dcd_clear_edpt_complete_status(USB_Type *ptr, uint32_t mask)
  346. {
  347. ptr->ENDPTCOMPLETE = mask;
  348. }
  349. /*---------------------------------------------------------------------
  350. * Host API
  351. *---------------------------------------------------------------------
  352. */
  353. /**
  354. * @brief Initialize controller to host mode
  355. *
  356. * @param[in] ptr A USB peripheral base address
  357. * @param[in] int_mask A mask of all required interrupts
  358. * @param[in] framelist_size A size of the frame list
  359. */
  360. bool usb_hcd_init(USB_Type *ptr, uint32_t int_mask, uint16_t framelist_size);
  361. /**
  362. * @brief Initialize controller to host modeHost Reset port
  363. *
  364. * @param[in] ptr A USB peripheral base address
  365. */
  366. void usb_hcd_port_reset(USB_Type *ptr);
  367. /**
  368. * @brief Initialize controller to host modeHost set command register
  369. *
  370. * @param[in] ptr A USB peripheral base address
  371. * @param[in] mask A mask of all required commands
  372. */
  373. static inline void usb_hcd_set_command(USB_Type *ptr, uint32_t mask)
  374. {
  375. ptr->USBCMD |= mask;
  376. }
  377. /**
  378. * @brief Get frame index
  379. *
  380. * @param[in] ptr A USB peripheral base address
  381. * @retval A index of the current frame list
  382. */
  383. static inline uint32_t usb_hcd_get_frame_index(USB_Type *ptr)
  384. {
  385. return ptr->FRINDEX;
  386. }
  387. /**
  388. * @brief Get port connect status change
  389. *
  390. * @param[in] ptr A USB peripheral base address
  391. * @retval A connect status change
  392. */
  393. static inline bool usb_hcd_get_port_csc(USB_Type *ptr)
  394. {
  395. return USB_PORTSC1_CSC_GET(ptr->PORTSC1);
  396. }
  397. /**
  398. * @brief Enable port power
  399. *
  400. * @param[in] ptr A USB peripheral base address
  401. */
  402. static inline void usb_hcd_enable_port_power(USB_Type *ptr)
  403. {
  404. ptr->PORTSC1 |= USB_PORTSC1_PP_MASK;
  405. }
  406. /**
  407. * @brief Get port connect status changeSet async list address
  408. *
  409. * @param[in] ptr A USB peripheral base address
  410. * @param[in] addr An the start address of the async endpoint list
  411. */
  412. static inline void usb_hcd_set_async_list_addr(USB_Type *ptr, uint32_t addr)
  413. {
  414. ptr->ASYNCLISTADDR = addr & USB_ASYNCLISTADDR_ASYBASE_MASK;
  415. }
  416. /**
  417. * @brief Set periodic list address
  418. *
  419. * @param[in] ptr A USB peripheral base address
  420. * @param[in] addr An start address of the periodic endpoint list
  421. */
  422. static inline void usb_hcd_set_periodic_list_addr(USB_Type *ptr, uint32_t addr)
  423. {
  424. ptr->PERIODICLISTBASE = addr & USB_PERIODICLISTBASE_BASEADR_MASK;
  425. }
  426. /**
  427. * @brief Start hcd controller
  428. *
  429. * @param[in] ptr A USB peripheral base address
  430. */
  431. static inline void usb_hcd_run(USB_Type *ptr)
  432. {
  433. ptr->USBCMD |= USB_USBCMD_RS_MASK;
  434. }
  435. /**
  436. * @brief Stop hcd controller
  437. *
  438. * @param[in] ptr A USB peripheral base address
  439. */
  440. static inline void usb_hcd_stop(USB_Type *ptr)
  441. {
  442. ptr->USBCMD &= ~USB_USBCMD_RS_MASK;
  443. }
  444. #if defined __cplusplus
  445. }
  446. #endif /* __cplusplus */
  447. /** @} */
  448. #endif /* HPM_USB_DRV_H */