drv_usbd.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-09-17 CHChen First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #ifdef BSP_USING_USBD
  14. #include <rtthread.h>
  15. #include <rtdevice.h>
  16. #include <string.h>
  17. #include "NuMicro.h"
  18. #define LOG_TAG "drv.usbd"
  19. #define DBG_ENABLE
  20. #define DBG_SECTION_NAME "drv.usbd"
  21. #define DBG_LEVEL DBG_ERROR
  22. #define DBG_COLOR
  23. #include <rtdbg.h>
  24. /* Private define ---------------------------------------------------------------*/
  25. /* Define EP maximum packet size */
  26. #define EP0_MAX_PKT_SIZE 64
  27. #define EP1_MAX_PKT_SIZE EP0_MAX_PKT_SIZE /* EP0 and EP1 are assigned the same size for control endpoint */
  28. #define EP2_MAX_PKT_SIZE 64
  29. #define EP3_MAX_PKT_SIZE 64
  30. #define EP4_MAX_PKT_SIZE 64
  31. #define EP5_MAX_PKT_SIZE 64
  32. #define EP6_MAX_PKT_SIZE 64
  33. #define EP7_MAX_PKT_SIZE 64
  34. #define EP8_MAX_PKT_SIZE 64
  35. #define EP9_MAX_PKT_SIZE 64
  36. #define EP10_MAX_PKT_SIZE 64
  37. #define EP11_MAX_PKT_SIZE 64
  38. #define SETUP_BUF_BASE 0
  39. #define SETUP_BUF_LEN 8
  40. #define EP0_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
  41. #define EP0_BUF_LEN EP0_MAX_PKT_SIZE
  42. #define EP1_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
  43. #define EP1_BUF_LEN EP1_MAX_PKT_SIZE
  44. #define EP2_BUF_BASE (EP1_BUF_BASE + EP1_BUF_LEN)
  45. #define EP2_BUF_LEN EP2_MAX_PKT_SIZE
  46. #define EP3_BUF_BASE (EP2_BUF_BASE + EP2_BUF_LEN)
  47. #define EP3_BUF_LEN EP3_MAX_PKT_SIZE
  48. #define EP4_BUF_BASE (EP3_BUF_BASE + EP3_BUF_LEN)
  49. #define EP4_BUF_LEN EP4_MAX_PKT_SIZE
  50. #define EP5_BUF_BASE (EP4_BUF_BASE + EP4_BUF_LEN)
  51. #define EP5_BUF_LEN EP5_MAX_PKT_SIZE
  52. #define EP6_BUF_BASE (EP5_BUF_BASE + EP5_BUF_LEN)
  53. #define EP6_BUF_LEN EP6_MAX_PKT_SIZE
  54. #define EP7_BUF_BASE (EP6_BUF_BASE + EP6_BUF_LEN)
  55. #define EP7_BUF_LEN EP7_MAX_PKT_SIZE
  56. #define EP8_BUF_BASE (EP7_BUF_BASE + EP7_BUF_LEN)
  57. #define EP8_BUF_LEN EP8_MAX_PKT_SIZE
  58. #define EP9_BUF_BASE (EP8_BUF_BASE + EP8_BUF_LEN)
  59. #define EP9_BUF_LEN EP9_MAX_PKT_SIZE
  60. #define EP10_BUF_BASE (EP9_BUF_BASE + EP9_BUF_LEN)
  61. #define EP10_BUF_LEN EP10_MAX_PKT_SIZE
  62. #define EP11_BUF_BASE (EP10_BUF_BASE + EP10_BUF_LEN)
  63. #define EP11_BUF_LEN EP11_MAX_PKT_SIZE
  64. #define EPADR_SW2HW(address) ((((address & USB_EPNO_MASK) * 2) + (!(address & USB_DIR_IN))))
  65. #define EPADR_HW2SW(address) ((address & USB_EPNO_MASK) / 2)
  66. /* Private typedef --------------------------------------------------------------*/
  67. typedef struct _nu_usbd_t
  68. {
  69. USBD_T *Instance; /* REG base */
  70. uint8_t address_tmp; /* Keep assigned address for flow control */
  71. } nu_usbd_t;
  72. /* Private variables ------------------------------------------------------------*/
  73. static nu_usbd_t nu_usbd =
  74. {
  75. .Instance = USBD,
  76. .address_tmp = 0,
  77. };
  78. static struct udcd _rt_obj_udc;
  79. static struct ep_id _ep_pool[] =
  80. {
  81. {EPADR_HW2SW(EP0), USB_EP_ATTR_CONTROL, USB_DIR_INOUT, EP0_MAX_PKT_SIZE, ID_ASSIGNED },
  82. {EPADR_HW2SW(EP2), USB_EP_ATTR_BULK, USB_DIR_IN, EP2_MAX_PKT_SIZE, ID_UNASSIGNED},
  83. {EPADR_HW2SW(EP3), USB_EP_ATTR_BULK, USB_DIR_OUT, EP3_MAX_PKT_SIZE, ID_UNASSIGNED},
  84. {EPADR_HW2SW(EP4), USB_EP_ATTR_INT, USB_DIR_IN, EP4_MAX_PKT_SIZE, ID_UNASSIGNED},
  85. {EPADR_HW2SW(EP5), USB_EP_ATTR_INT, USB_DIR_OUT, EP5_MAX_PKT_SIZE, ID_UNASSIGNED},
  86. {EPADR_HW2SW(EP6), USB_EP_ATTR_BULK, USB_DIR_IN, EP6_MAX_PKT_SIZE, ID_UNASSIGNED},
  87. {EPADR_HW2SW(EP7), USB_EP_ATTR_BULK, USB_DIR_OUT, EP7_MAX_PKT_SIZE, ID_UNASSIGNED},
  88. {EPADR_HW2SW(EP8), USB_EP_ATTR_INT, USB_DIR_IN, EP8_MAX_PKT_SIZE, ID_UNASSIGNED},
  89. {EPADR_HW2SW(EP9), USB_EP_ATTR_INT, USB_DIR_OUT, EP9_MAX_PKT_SIZE, ID_UNASSIGNED},
  90. {EPADR_HW2SW(EP10), USB_EP_ATTR_BULK, USB_DIR_IN, EP6_MAX_PKT_SIZE, ID_UNASSIGNED},
  91. {EPADR_HW2SW(EP11), USB_EP_ATTR_BULK, USB_DIR_OUT, EP7_MAX_PKT_SIZE, ID_UNASSIGNED},
  92. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  93. };
  94. static void _nu_ep_partition(void)
  95. {
  96. /* Init setup packet buffer */
  97. /* Buffer range for setup packet -> [0 ~ 0x7] */
  98. USBD->STBUFSEG = SETUP_BUF_BASE;
  99. /*****************************************************/
  100. /* EP0 ==> control IN endpoint, address 0 */
  101. USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP0));
  102. /* Buffer range for EP0 */
  103. USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);
  104. /* EP1 ==> control OUT endpoint, address 0 */
  105. USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP1));
  106. /* Buffer range for EP1 */
  107. USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);
  108. /*****************************************************/
  109. /* EP2 ==> Bulk IN endpoint, address 1 */
  110. USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP2));
  111. /* Buffer range for EP2 */
  112. USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);
  113. /* EP3 ==> Bulk OUT endpoint, address 1 */
  114. USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP3));
  115. /* Buffer range for EP3 */
  116. USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
  117. /*****************************************************/
  118. /* EP4 ==> Interrupt IN endpoint, address 2 */
  119. USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP4));
  120. /* Buffer range for EP4 */
  121. USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE);
  122. /* EP5 ==> Interrupt Out endpoint, address 2 */
  123. USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP5));
  124. /* Buffer range for EP5 */
  125. USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE);
  126. /*****************************************************/
  127. /* EP6 ==> Bulk IN endpoint, address 3 */
  128. USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP6));
  129. /* Buffer range for EP4 */
  130. USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE);
  131. /* EP7 ==> Bulk Out endpoint, address 3 */
  132. USBD_CONFIG_EP(EP7, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP7));
  133. /* Buffer range for EP5 */
  134. USBD_SET_EP_BUF_ADDR(EP7, EP7_BUF_BASE);
  135. /*****************************************************/
  136. /* EP8 ==> Interrupt IN endpoint, address 4 */
  137. USBD_CONFIG_EP(EP8, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP8));
  138. /* Buffer range for EP4 */
  139. USBD_SET_EP_BUF_ADDR(EP8, EP8_BUF_BASE);
  140. /* EP9 ==> Interrupt Out endpoint, address 4 */
  141. USBD_CONFIG_EP(EP9, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP9));
  142. /* Buffer range for EP9 */
  143. USBD_SET_EP_BUF_ADDR(EP9, EP9_BUF_BASE);
  144. /*****************************************************/
  145. /* EP10 ==> Bulk IN endpoint, address 5 */
  146. USBD_CONFIG_EP(EP10, USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP10));
  147. /* Buffer range for EP10 */
  148. USBD_SET_EP_BUF_ADDR(EP10, EP10_BUF_BASE);
  149. /* EP11 ==> Bulk Out endpoint, address 5 */
  150. USBD_CONFIG_EP(EP11, USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP11));
  151. /* Buffer range for EP11 */
  152. USBD_SET_EP_BUF_ADDR(EP11, EP11_BUF_BASE);
  153. }
  154. static rt_err_t _ep_set_stall(rt_uint8_t address)
  155. {
  156. USBD_SET_EP_STALL(EPADR_SW2HW(address));
  157. return RT_EOK;
  158. }
  159. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  160. {
  161. USBD_ClearStall(EPADR_SW2HW(address));
  162. return RT_EOK;
  163. }
  164. static rt_err_t _set_address(rt_uint8_t address)
  165. {
  166. if (0 != address)
  167. {
  168. nu_usbd.address_tmp = address;
  169. }
  170. return RT_EOK;
  171. }
  172. static rt_err_t _set_config(rt_uint8_t address)
  173. {
  174. return RT_EOK;
  175. }
  176. static rt_err_t _ep_enable(uep_t ep)
  177. {
  178. RT_ASSERT(ep != RT_NULL);
  179. RT_ASSERT(ep->ep_desc != RT_NULL);
  180. USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)),
  181. USBD_CFG_CSTALL
  182. | ((EP_ADDRESS(ep) & USB_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT)
  183. | (EP_ADDRESS(ep) & USB_EPNO_MASK));
  184. return RT_EOK;
  185. }
  186. static rt_err_t _ep_disable(uep_t ep)
  187. {
  188. RT_ASSERT(ep != RT_NULL);
  189. RT_ASSERT(ep->ep_desc != RT_NULL);
  190. USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)), USBD_CFG_EPMODE_DISABLE);
  191. return RT_EOK;
  192. }
  193. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  194. {
  195. rt_size_t size = 0;
  196. rt_uint8_t *buf;
  197. rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
  198. RT_ASSERT(!(address & USB_DIR_IN));
  199. RT_ASSERT(buffer != RT_NULL);
  200. size = USBD_GET_PAYLOAD_LEN(hw_ep_num);
  201. buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
  202. USBD_MemCopy(buffer, (uint8_t *)buf, size);
  203. return size;
  204. }
  205. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  206. {
  207. RT_ASSERT(!(address & USB_DIR_IN));
  208. USBD_SET_PAYLOAD_LEN(EPADR_SW2HW(address), size);
  209. return size;
  210. }
  211. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  212. {
  213. RT_ASSERT((address & USB_DIR_IN));
  214. /* even number is for IN endpoint */
  215. rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
  216. uint8_t *buf;
  217. buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
  218. USBD_MemCopy(buf, (uint8_t *)buffer, size);
  219. USBD_SET_PAYLOAD_LEN(hw_ep_num, size);
  220. return size;
  221. }
  222. static rt_err_t _ep0_send_status(void)
  223. {
  224. /* Status stage */
  225. USBD_SET_DATA1(EP0);
  226. USBD_SET_PAYLOAD_LEN(EP0, 0);
  227. return RT_EOK;
  228. }
  229. static rt_err_t _suspend(void)
  230. {
  231. return RT_EOK;
  232. }
  233. static rt_err_t _wakeup(void)
  234. {
  235. return RT_EOK;
  236. }
  237. __STATIC_INLINE void _USBD_IRQHandler(void)
  238. {
  239. rt_uint32_t u32IntSts = USBD_GET_INT_FLAG();
  240. rt_uint32_t u32State = USBD_GET_BUS_STATE();
  241. //------------------------------------------------------------------
  242. if (u32IntSts & USBD_INTSTS_VBDETIF_Msk)
  243. {
  244. // Floating detect
  245. USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
  246. if (USBD_IS_ATTACHED())
  247. {
  248. /* USB Plug In */
  249. USBD_ENABLE_USB();
  250. rt_usbd_connect_handler(&_rt_obj_udc);
  251. }
  252. else
  253. {
  254. /* USB Unplug */
  255. USBD_DISABLE_USB();
  256. rt_usbd_disconnect_handler(&_rt_obj_udc);
  257. }
  258. }
  259. if (u32IntSts & USBD_INTSTS_SOFIF_Msk)
  260. {
  261. USBD_CLR_INT_FLAG(USBD_INTSTS_SOFIF_Msk);
  262. rt_usbd_sof_handler(&_rt_obj_udc);
  263. }
  264. //------------------------------------------------------------------
  265. if (u32IntSts & USBD_INTSTS_BUSIF_Msk)
  266. {
  267. /* Clear event flag */
  268. USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
  269. if (u32State & USBD_ATTR_USBRST_Msk)
  270. {
  271. USBD_ENABLE_USB();
  272. /* Reset PID DATA0 */
  273. for (rt_uint32_t i = 0ul; i < USBD_MAX_EP; i++)
  274. {
  275. nu_usbd.Instance->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
  276. }
  277. /* Reset USB device address */
  278. USBD_SET_ADDR(0ul);
  279. /* Bus reset */
  280. rt_usbd_reset_handler(&_rt_obj_udc);
  281. }
  282. if (u32State & USBD_ATTR_SUSPEND_Msk)
  283. {
  284. /* Enable USB but disable PHY */
  285. USBD_DISABLE_PHY();
  286. }
  287. if (u32State & USBD_ATTR_RESUME_Msk)
  288. {
  289. /* Enable USB and enable PHY */
  290. USBD_ENABLE_USB();
  291. }
  292. }
  293. //------------------------------------------------------------------
  294. if (u32IntSts & USBD_INTSTS_WAKEUP)
  295. {
  296. /* Clear event flag */
  297. USBD_CLR_INT_FLAG(USBD_INTSTS_WAKEUP);
  298. USBD_ENABLE_USB();
  299. }
  300. if (u32IntSts & USBD_INTSTS_USBIF_Msk)
  301. {
  302. // USB event
  303. if (u32IntSts & USBD_INTSTS_SETUP_Msk)
  304. {
  305. // Setup packet
  306. /* Clear event flag */
  307. USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
  308. /* Clear the data IN/OUT ready flag of control end-points */
  309. USBD_STOP_TRANSACTION(EP0);
  310. USBD_STOP_TRANSACTION(EP1);
  311. USBD_SET_DATA1(EP0);
  312. rt_usbd_ep0_setup_handler(&_rt_obj_udc, (struct urequest *)USBD_BUF_BASE);
  313. }
  314. // EP events
  315. if (u32IntSts & USBD_INTSTS_EP0)
  316. {
  317. /* Clear event flag */
  318. USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
  319. if ((USBD_GET_ADDR() == 0)
  320. && (nu_usbd.address_tmp)
  321. )
  322. {
  323. USBD_SET_ADDR(nu_usbd.address_tmp);
  324. LOG_I("SET ADDR: 0x%02x", nu_usbd.address_tmp);
  325. nu_usbd.address_tmp = 0;
  326. }
  327. rt_usbd_ep0_in_handler(&_rt_obj_udc);
  328. }
  329. if (u32IntSts & USBD_INTSTS_EP1)
  330. {
  331. /* Clear event flag */
  332. USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
  333. rt_usbd_ep0_out_handler(&_rt_obj_udc, 0);
  334. }
  335. if (u32IntSts & USBD_INTSTS_EP2)
  336. {
  337. /* Clear event flag */
  338. USBD_CLR_INT_FLAG(USBD_INTSTS_EP2);
  339. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP2), 0);
  340. }
  341. if (u32IntSts & USBD_INTSTS_EP3)
  342. {
  343. /* Clear event flag */
  344. USBD_CLR_INT_FLAG(USBD_INTSTS_EP3);
  345. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP3), 0);
  346. }
  347. if (u32IntSts & USBD_INTSTS_EP4)
  348. {
  349. /* Clear event flag */
  350. USBD_CLR_INT_FLAG(USBD_INTSTS_EP4);
  351. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP4), 0);
  352. }
  353. if (u32IntSts & USBD_INTSTS_EP5)
  354. {
  355. /* Clear event flag */
  356. USBD_CLR_INT_FLAG(USBD_INTSTS_EP5);
  357. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP5), 0);
  358. }
  359. if (u32IntSts & USBD_INTSTS_EP6)
  360. {
  361. /* Clear event flag */
  362. USBD_CLR_INT_FLAG(USBD_INTSTS_EP6);
  363. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP6), 0);
  364. }
  365. if (u32IntSts & USBD_INTSTS_EP7)
  366. {
  367. /* Clear event flag */
  368. USBD_CLR_INT_FLAG(USBD_INTSTS_EP7);
  369. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP7), 0);
  370. }
  371. if (u32IntSts & USBD_INTSTS_EP8)
  372. {
  373. /* Clear event flag */
  374. USBD_CLR_INT_FLAG(USBD_INTSTS_EP8);
  375. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP8), 0);
  376. }
  377. if (u32IntSts & USBD_INTSTS_EP9)
  378. {
  379. /* Clear event flag */
  380. USBD_CLR_INT_FLAG(USBD_INTSTS_EP9);
  381. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP9), 0);
  382. }
  383. if (u32IntSts & USBD_INTSTS_EP10)
  384. {
  385. /* Clear event flag */
  386. USBD_CLR_INT_FLAG(USBD_INTSTS_EP10);
  387. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EP10), 0);
  388. }
  389. if (u32IntSts & USBD_INTSTS_EP11)
  390. {
  391. /* Clear event flag */
  392. USBD_CLR_INT_FLAG(USBD_INTSTS_EP11);
  393. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EP11), 0);
  394. }
  395. }
  396. }
  397. void USBD_IRQHandler(void)
  398. {
  399. rt_interrupt_enter();
  400. _USBD_IRQHandler();
  401. rt_interrupt_leave();
  402. }
  403. static rt_err_t _init(rt_device_t device)
  404. {
  405. nu_usbd_t *nu_usbd = (nu_usbd_t *)device->user_data;
  406. #if !defined(BSP_USING_OTG)
  407. /* Initialize USB PHY */
  408. SYS_UnlockReg();
  409. /* Select USBD */
  410. SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_OTGPHYEN_Msk | SYS_USBPHY_SBO_Msk;
  411. SYS_ResetModule(USBD_RST);
  412. SYS_LockReg();
  413. #endif
  414. _nu_ep_partition();
  415. /* Initial USB engine */
  416. nu_usbd->Instance->ATTR = 0x6D0ul;
  417. /* Force SE0 */
  418. USBD_SET_SE0();
  419. NVIC_EnableIRQ(USBD_IRQn);
  420. USBD_Start();
  421. return RT_EOK;
  422. }
  423. const static struct udcd_ops _udc_ops =
  424. {
  425. _set_address,
  426. _set_config,
  427. _ep_set_stall,
  428. _ep_clear_stall,
  429. _ep_enable,
  430. _ep_disable,
  431. _ep_read_prepare,
  432. _ep_read,
  433. _ep_write,
  434. _ep0_send_status,
  435. _suspend,
  436. _wakeup,
  437. };
  438. #ifdef RT_USING_DEVICE_OPS
  439. const static struct rt_device_ops _ops =
  440. {
  441. _init,
  442. RT_NULL,
  443. RT_NULL,
  444. RT_NULL,
  445. RT_NULL,
  446. RT_NULL,
  447. };
  448. #endif
  449. int nu_usbd_register(void)
  450. {
  451. if (RT_NULL != rt_device_find("usbd"))
  452. {
  453. LOG_E("\nUSBD Register failed. Another USBD device registered\n");
  454. return -RT_ERROR;
  455. }
  456. rt_memset((void *)&_rt_obj_udc, 0, sizeof(struct udcd));
  457. _rt_obj_udc.parent.type = RT_Device_Class_USBDevice;
  458. #ifdef RT_USING_DEVICE_OPS
  459. _rt_obj_udc.parent.ops = &_ops;
  460. #else
  461. _rt_obj_udc.parent.init = _init;
  462. #endif
  463. _rt_obj_udc.parent.user_data = &nu_usbd;
  464. _rt_obj_udc.ops = &_udc_ops;
  465. /* Register endpoint information */
  466. _rt_obj_udc.ep_pool = _ep_pool;
  467. _rt_obj_udc.ep0.id = &_ep_pool[0];
  468. _rt_obj_udc.device_is_hs = RT_FALSE; /* Support Full-Speed only */
  469. rt_device_register((rt_device_t)&_rt_obj_udc, "usbd", 0);
  470. rt_usb_device_init();
  471. return RT_EOK;
  472. }
  473. INIT_DEVICE_EXPORT(nu_usbd_register);
  474. #endif