drv_usbd.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  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. * 2022-3-15 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_USBD)
  14. #include <rtthread.h>
  15. #include <rtdevice.h>
  16. #include "NuMicro.h"
  17. #include <nu_bitutil.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 32
  31. #define EP5_MAX_PKT_SIZE 32
  32. #define EP6_MAX_PKT_SIZE 64
  33. #define EP7_MAX_PKT_SIZE 64
  34. #define EP8_MAX_PKT_SIZE 32
  35. #define EP9_MAX_PKT_SIZE 32
  36. #define EP10_MAX_PKT_SIZE 64
  37. #define EP11_MAX_PKT_SIZE 64
  38. #define EP12_MAX_PKT_SIZE 32
  39. #define EP13_MAX_PKT_SIZE 32
  40. #define EP14_MAX_PKT_SIZE 64
  41. #define EP15_MAX_PKT_SIZE 64
  42. #define EP16_MAX_PKT_SIZE 32
  43. #define EP17_MAX_PKT_SIZE 32
  44. #define EP18_MAX_PKT_SIZE 64
  45. #define EP19_MAX_PKT_SIZE 64
  46. #define EP20_MAX_PKT_SIZE 32
  47. #define EP21_MAX_PKT_SIZE 32
  48. #define EP22_MAX_PKT_SIZE 64
  49. #define EP23_MAX_PKT_SIZE 64
  50. #define EP24_MAX_PKT_SIZE 32
  51. #define SETUP_BUF_BASE 0
  52. #define SETUP_BUF_LEN 8
  53. #define EPADR_SW2HW(address) ((((address & USB_EPNO_MASK) * 2) + (!(address & USB_DIR_IN))))
  54. #define EPADR_HW2SW(address) ((address & USB_EPNO_MASK) / 2)
  55. /* Private typedef --------------------------------------------------------------*/
  56. struct nu_usbd
  57. {
  58. USBD_T *Instance; /* REG base */
  59. uint8_t address_tmp; /* Keep assigned address for flow control */
  60. };
  61. typedef struct nu_usbd *nu_usbd_t;
  62. typedef struct
  63. {
  64. uint32_t u32BufferBase;
  65. uint32_t u32BufferLength;
  66. uint32_t u32;
  67. } S_EP_CXT;
  68. /* Private variables ------------------------------------------------------------*/
  69. static struct nu_usbd nu_usbd_obj =
  70. {
  71. .Instance = USBD,
  72. .address_tmp = 0,
  73. };
  74. static struct udcd _rt_obj_udc;
  75. static const uint32_t s_au32MaxPktSize[USBD_MAX_EP] =
  76. {
  77. EP0_MAX_PKT_SIZE, //EP0
  78. EP1_MAX_PKT_SIZE, //EP1
  79. EP2_MAX_PKT_SIZE, //EP2
  80. EP3_MAX_PKT_SIZE, //EP3
  81. EP4_MAX_PKT_SIZE, //EP4
  82. EP5_MAX_PKT_SIZE, //EP5
  83. EP6_MAX_PKT_SIZE, //EP6
  84. EP7_MAX_PKT_SIZE, //EP7
  85. EP8_MAX_PKT_SIZE, //EP8
  86. EP9_MAX_PKT_SIZE, //EP9
  87. EP10_MAX_PKT_SIZE, //EP10
  88. EP11_MAX_PKT_SIZE, //EP11
  89. EP12_MAX_PKT_SIZE, //EP12
  90. EP13_MAX_PKT_SIZE, //EP13
  91. EP14_MAX_PKT_SIZE, //EP14
  92. EP15_MAX_PKT_SIZE, //EP15
  93. EP16_MAX_PKT_SIZE, //EP16
  94. EP17_MAX_PKT_SIZE, //EP17
  95. EP18_MAX_PKT_SIZE, //EP18
  96. EP19_MAX_PKT_SIZE, //EP19
  97. EP20_MAX_PKT_SIZE, //EP20
  98. EP21_MAX_PKT_SIZE, //EP21
  99. EP22_MAX_PKT_SIZE, //EP22
  100. EP23_MAX_PKT_SIZE, //EP23
  101. EP24_MAX_PKT_SIZE //EP24
  102. };
  103. static struct ep_id _ep_pool[] =
  104. {
  105. {EPADR_HW2SW(EP0), USB_EP_ATTR_CONTROL, USB_DIR_INOUT, EP0_MAX_PKT_SIZE, ID_ASSIGNED },
  106. {EPADR_HW2SW(EP2), USB_EP_ATTR_BULK, USB_DIR_IN, EP2_MAX_PKT_SIZE, ID_UNASSIGNED},
  107. {EPADR_HW2SW(EP3), USB_EP_ATTR_BULK, USB_DIR_OUT, EP3_MAX_PKT_SIZE, ID_UNASSIGNED},
  108. {EPADR_HW2SW(EP4), USB_EP_ATTR_INT, USB_DIR_IN, EP4_MAX_PKT_SIZE, ID_UNASSIGNED},
  109. {EPADR_HW2SW(EP5), USB_EP_ATTR_INT, USB_DIR_OUT, EP5_MAX_PKT_SIZE, ID_UNASSIGNED},
  110. {EPADR_HW2SW(EP6), USB_EP_ATTR_BULK, USB_DIR_IN, EP6_MAX_PKT_SIZE, ID_UNASSIGNED},
  111. {EPADR_HW2SW(EP7), USB_EP_ATTR_BULK, USB_DIR_OUT, EP7_MAX_PKT_SIZE, ID_UNASSIGNED},
  112. {EPADR_HW2SW(EP8), USB_EP_ATTR_INT, USB_DIR_IN, EP8_MAX_PKT_SIZE, ID_UNASSIGNED},
  113. {EPADR_HW2SW(EP9), USB_EP_ATTR_INT, USB_DIR_OUT, EP9_MAX_PKT_SIZE, ID_UNASSIGNED},
  114. {EPADR_HW2SW(EP10), USB_EP_ATTR_BULK, USB_DIR_IN, EP10_MAX_PKT_SIZE, ID_UNASSIGNED},
  115. {EPADR_HW2SW(EP11), USB_EP_ATTR_BULK, USB_DIR_OUT, EP11_MAX_PKT_SIZE, ID_UNASSIGNED},
  116. {EPADR_HW2SW(EP12), USB_EP_ATTR_INT, USB_DIR_IN, EP12_MAX_PKT_SIZE, ID_UNASSIGNED},
  117. {EPADR_HW2SW(EP13), USB_EP_ATTR_INT, USB_DIR_OUT, EP13_MAX_PKT_SIZE, ID_UNASSIGNED},
  118. {EPADR_HW2SW(EP14), USB_EP_ATTR_BULK, USB_DIR_IN, EP14_MAX_PKT_SIZE, ID_UNASSIGNED},
  119. {EPADR_HW2SW(EP15), USB_EP_ATTR_BULK, USB_DIR_OUT, EP15_MAX_PKT_SIZE, ID_UNASSIGNED},
  120. {EPADR_HW2SW(EP16), USB_EP_ATTR_INT, USB_DIR_IN, EP16_MAX_PKT_SIZE, ID_UNASSIGNED},
  121. {EPADR_HW2SW(EP17), USB_EP_ATTR_INT, USB_DIR_OUT, EP17_MAX_PKT_SIZE, ID_UNASSIGNED},
  122. {EPADR_HW2SW(EP18), USB_EP_ATTR_BULK, USB_DIR_IN, EP18_MAX_PKT_SIZE, ID_UNASSIGNED},
  123. {EPADR_HW2SW(EP19), USB_EP_ATTR_BULK, USB_DIR_OUT, EP19_MAX_PKT_SIZE, ID_UNASSIGNED},
  124. {EPADR_HW2SW(EP20), USB_EP_ATTR_INT, USB_DIR_IN, EP20_MAX_PKT_SIZE, ID_UNASSIGNED},
  125. {EPADR_HW2SW(EP21), USB_EP_ATTR_INT, USB_DIR_OUT, EP21_MAX_PKT_SIZE, ID_UNASSIGNED},
  126. {EPADR_HW2SW(EP22), USB_EP_ATTR_BULK, USB_DIR_IN, EP22_MAX_PKT_SIZE, ID_UNASSIGNED},
  127. {EPADR_HW2SW(EP23), USB_EP_ATTR_BULK, USB_DIR_OUT, EP23_MAX_PKT_SIZE, ID_UNASSIGNED},
  128. {EPADR_HW2SW(EP24), USB_EP_ATTR_INT, USB_DIR_IN, EP24_MAX_PKT_SIZE, ID_UNASSIGNED},
  129. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  130. };
  131. static struct ep_id *get_ep_entry(int ep_addr)
  132. {
  133. int i;
  134. for (i = 0; i < sizeof(_ep_pool) / sizeof(_ep_pool[0]); i++)
  135. {
  136. if (_ep_pool[i].addr == EPADR_HW2SW(ep_addr))
  137. return &_ep_pool[i];
  138. }
  139. return RT_NULL;
  140. }
  141. #define PRINT_EP_BASE(ep, base) rt_kprintf("%d: %08x\n", ep, USBD_GET_EP_BUF_ADDR(ep));
  142. static void _nu_ep_partition(void)
  143. {
  144. int i;
  145. uint32_t u32EPBufBase, u32EPBufLen;
  146. /* Init setup packet buffer */
  147. /* Buffer range for setup packet -> [0 ~ 0x7] */
  148. USBD->STBUFSEG = SETUP_BUF_BASE;
  149. /*****************************************************/
  150. u32EPBufBase = SETUP_BUF_BASE + SETUP_BUF_LEN; //For EP0
  151. /* EP0 ==> control IN endpoint, address 0 */
  152. USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | EPADR_HW2SW(EP0));
  153. /* Buffer range for EP0 */
  154. USBD_SET_EP_BUF_ADDR(EP0, u32EPBufBase);
  155. u32EPBufLen = s_au32MaxPktSize[0]; //EP0 max pkt size
  156. u32EPBufBase += u32EPBufLen;
  157. /* EP1 ==> control OUT endpoint, address 0 */
  158. USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | EPADR_HW2SW(EP1));
  159. /* Buffer range for EP1 */
  160. USBD_SET_EP_BUF_ADDR(EP1, u32EPBufBase);
  161. u32EPBufLen = s_au32MaxPktSize[1]; //EP1 max pkt size
  162. u32EPBufBase += u32EPBufLen;
  163. /*****************************************************/
  164. for (i = EP2; i < USBD_MAX_EP; i++)
  165. {
  166. uint32_t u32Config = EPADR_HW2SW(i);
  167. struct ep_id *psEpId;
  168. u32EPBufLen = s_au32MaxPktSize[i];
  169. RT_ASSERT(u32EPBufBase <= 1536);
  170. psEpId = get_ep_entry(i);
  171. if (psEpId == RT_NULL)
  172. continue;
  173. switch (psEpId->dir)
  174. {
  175. case USB_DIR_IN:
  176. u32Config |= USBD_CFG_EPMODE_IN;
  177. break;
  178. case USB_DIR_OUT:
  179. u32Config |= USBD_CFG_EPMODE_OUT;
  180. break;
  181. default:
  182. continue;
  183. }
  184. /* Endpoint configuration */
  185. USBD_CONFIG_EP(i, u32Config);
  186. /* Buffer range for EP */
  187. USBD_SET_EP_BUF_ADDR(i, u32EPBufBase);
  188. //PRINT_EP_BASE(i, u32EPBufBase);
  189. u32EPBufBase += u32EPBufLen;
  190. }
  191. }
  192. static rt_err_t _ep_set_stall(rt_uint8_t address)
  193. {
  194. USBD_SET_EP_STALL(EPADR_SW2HW(address));
  195. return RT_EOK;
  196. }
  197. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  198. {
  199. USBD_ClearStall(EPADR_SW2HW(address));
  200. return RT_EOK;
  201. }
  202. static rt_err_t _set_address(rt_uint8_t address)
  203. {
  204. if (0 != address)
  205. {
  206. nu_usbd_obj.address_tmp = address;
  207. }
  208. return RT_EOK;
  209. }
  210. static rt_err_t _set_config(rt_uint8_t address)
  211. {
  212. return RT_EOK;
  213. }
  214. static rt_err_t _ep_enable(uep_t ep)
  215. {
  216. RT_ASSERT(ep != RT_NULL);
  217. RT_ASSERT(ep->ep_desc != RT_NULL);
  218. USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)),
  219. USBD_CFG_CSTALL
  220. | ((EP_ADDRESS(ep) & USB_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT)
  221. | (EP_ADDRESS(ep) & USB_EPNO_MASK));
  222. return RT_EOK;
  223. }
  224. static rt_err_t _ep_disable(uep_t ep)
  225. {
  226. RT_ASSERT(ep != RT_NULL);
  227. RT_ASSERT(ep->ep_desc != RT_NULL);
  228. USBD_CONFIG_EP(EPADR_SW2HW(EP_ADDRESS(ep)), USBD_CFG_EPMODE_DISABLE);
  229. return RT_EOK;
  230. }
  231. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  232. {
  233. rt_size_t size = 0;
  234. rt_uint8_t *buf;
  235. rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
  236. RT_ASSERT(!(address & USB_DIR_IN));
  237. RT_ASSERT(buffer != RT_NULL);
  238. size = USBD_GET_PAYLOAD_LEN(hw_ep_num);
  239. buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
  240. USBD_MemCopy(buffer, (uint8_t *)buf, size);
  241. return size;
  242. }
  243. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  244. {
  245. RT_ASSERT(!(address & USB_DIR_IN));
  246. USBD_SET_PAYLOAD_LEN(EPADR_SW2HW(address), size);
  247. return size;
  248. }
  249. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  250. {
  251. RT_ASSERT((address & USB_DIR_IN));
  252. /* even number is for IN endpoint */
  253. rt_uint32_t hw_ep_num = EPADR_SW2HW(address);
  254. uint8_t *buf;
  255. buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(hw_ep_num));
  256. USBD_MemCopy(buf, (uint8_t *)buffer, size);
  257. USBD_SET_PAYLOAD_LEN(hw_ep_num, size);
  258. return size;
  259. }
  260. static rt_err_t _ep0_send_status(void)
  261. {
  262. /* Status stage */
  263. USBD_SET_DATA1(EP0);
  264. USBD_SET_PAYLOAD_LEN(EP0, 0);
  265. return RT_EOK;
  266. }
  267. static rt_err_t _suspend(void)
  268. {
  269. return RT_EOK;
  270. }
  271. static rt_err_t _wakeup(void)
  272. {
  273. return RT_EOK;
  274. }
  275. __STATIC_INLINE void _USBD_IRQHandler(void)
  276. {
  277. rt_uint32_t u32IntSts = USBD_GET_INT_FLAG();
  278. rt_uint32_t u32State = USBD_GET_BUS_STATE();
  279. //------------------------------------------------------------------
  280. if (u32IntSts & USBD_INTSTS_VBDETIF_Msk)
  281. {
  282. // Floating detect
  283. USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
  284. if (USBD_IS_ATTACHED())
  285. {
  286. /* USB Plug In */
  287. USBD_ENABLE_USB();
  288. rt_usbd_connect_handler(&_rt_obj_udc);
  289. }
  290. else
  291. {
  292. /* USB Unplug */
  293. USBD_DISABLE_USB();
  294. rt_usbd_disconnect_handler(&_rt_obj_udc);
  295. }
  296. }
  297. if (u32IntSts & USBD_INTSTS_SOFIF_Msk)
  298. {
  299. USBD_CLR_INT_FLAG(USBD_INTSTS_SOFIF_Msk);
  300. rt_usbd_sof_handler(&_rt_obj_udc);
  301. }
  302. //------------------------------------------------------------------
  303. if (u32IntSts & USBD_INTSTS_BUSIF_Msk)
  304. {
  305. /* Clear event flag */
  306. USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
  307. if (u32State & USBD_ATTR_USBRST_Msk)
  308. {
  309. USBD_ENABLE_USB();
  310. /* Reset PID DATA0 */
  311. for (rt_uint32_t i = 0ul; i < USBD_MAX_EP; i++)
  312. {
  313. nu_usbd_obj.Instance->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
  314. }
  315. /* Reset USB device address */
  316. USBD_SET_ADDR(0ul);
  317. /* Bus reset */
  318. rt_usbd_reset_handler(&_rt_obj_udc);
  319. }
  320. if (u32State & USBD_ATTR_SUSPEND_Msk)
  321. {
  322. /* Enable USB but disable PHY */
  323. USBD_DISABLE_PHY();
  324. }
  325. if (u32State & USBD_ATTR_RESUME_Msk)
  326. {
  327. /* Enable USB and enable PHY */
  328. USBD_ENABLE_USB();
  329. }
  330. }
  331. //------------------------------------------------------------------
  332. if (u32IntSts & USBD_INTSTS_WAKEUP)
  333. {
  334. /* Clear event flag */
  335. USBD_CLR_INT_FLAG(USBD_INTSTS_WAKEUP);
  336. USBD_ENABLE_USB();
  337. }
  338. if (u32IntSts & USBD_INTSTS_USBIF_Msk)
  339. {
  340. // USB event
  341. if (u32IntSts & USBD_INTSTS_SETUP_Msk)
  342. {
  343. // Setup packet
  344. /* Clear event flag */
  345. USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
  346. /* Clear the data IN/OUT ready flag of control end-points */
  347. USBD_STOP_TRANSACTION(EP0);
  348. USBD_STOP_TRANSACTION(EP1);
  349. USBD_SET_DATA1(EP0);
  350. rt_usbd_ep0_setup_handler(&_rt_obj_udc, (struct urequest *)USBD_BUF_BASE);
  351. }
  352. /* Service EP events */
  353. rt_uint32_t u32EpIntSts = USBD_GET_EP_INT_FLAG();
  354. // EP events
  355. if (u32EpIntSts & USBD_EPINTSTS_EPEVT0_Msk)
  356. {
  357. /* Clear event flag */
  358. USBD_CLR_EP_INT_FLAG(USBD_EPINTSTS_EPEVT0_Msk);
  359. if ((USBD_GET_ADDR() == 0)
  360. && (nu_usbd_obj.address_tmp)
  361. )
  362. {
  363. USBD_SET_ADDR(nu_usbd_obj.address_tmp);
  364. LOG_I("SET ADDR: 0x%02x", nu_usbd.address_tmp);
  365. nu_usbd_obj.address_tmp = 0;
  366. }
  367. rt_usbd_ep0_in_handler(&_rt_obj_udc);
  368. }
  369. if (u32EpIntSts & USBD_EPINTSTS_EPEVT1_Msk)
  370. {
  371. /* Clear event flag */
  372. USBD_CLR_EP_INT_FLAG(USBD_EPINTSTS_EPEVT1_Msk);
  373. rt_usbd_ep0_out_handler(&_rt_obj_udc, 0);
  374. }
  375. /* For EP2 ~ EP24 */
  376. {
  377. rt_int32_t u32EpIrqIdx;
  378. rt_int32_t u32EpIrqStatus = u32EpIntSts & (~((1 << EP2) - 1)); // Skip EP0/EP1 traveling.
  379. // Find index of pin is attached in pool.
  380. while ((u32EpIrqIdx = nu_ctz(u32EpIrqStatus)) < USBD_MAX_EP) // Count Trailing Zeros ==> Find First One
  381. {
  382. /* Clear event flag */
  383. USBD_CLR_EP_INT_FLAG(1 << u32EpIrqIdx);
  384. /* Report upper layer. */
  385. rt_usbd_ep_in_handler(&_rt_obj_udc, _ep_pool[u32EpIrqIdx - 1].dir | EPADR_HW2SW(u32EpIrqIdx), 0);
  386. u32EpIrqStatus &= ~(1 << u32EpIrqIdx);
  387. }
  388. }
  389. }
  390. }
  391. void USBD_IRQHandler(void)
  392. {
  393. rt_interrupt_enter();
  394. _USBD_IRQHandler();
  395. rt_interrupt_leave();
  396. }
  397. static rt_err_t _init(rt_device_t device)
  398. {
  399. nu_usbd_t nu_usbd = (nu_usbd_t)device->user_data;
  400. uint32_t u32RegLockBackup = SYS_IsRegLocked();
  401. /* Initialize USB PHY */
  402. SYS_UnlockReg();
  403. /* Select USBD */
  404. SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk;
  405. SYS_ResetModule(USBD_RST);
  406. if (u32RegLockBackup)
  407. SYS_LockReg();
  408. _nu_ep_partition();
  409. /* Initial USB engine */
  410. /*
  411. BYTEM=1: Byte mode: The size of the transfer from CPU to USB SRAM can be Byte only.
  412. PWRDN=1: Turn-on related circuit of PHY transceiver.
  413. DPPUEN=1: Pull-up resistor in USB_D+ bus Active.
  414. */
  415. nu_usbd->Instance->ATTR = 0x7D0ul;
  416. /* Force SE0 */
  417. USBD_SET_SE0();
  418. NVIC_EnableIRQ(USBD_IRQn);
  419. USBD_Start();
  420. return RT_EOK;
  421. }
  422. const static struct udcd_ops _udc_ops =
  423. {
  424. _set_address,
  425. _set_config,
  426. _ep_set_stall,
  427. _ep_clear_stall,
  428. _ep_enable,
  429. _ep_disable,
  430. _ep_read_prepare,
  431. _ep_read,
  432. _ep_write,
  433. _ep0_send_status,
  434. _suspend,
  435. _wakeup,
  436. };
  437. #ifdef RT_USING_DEVICE_OPS
  438. const static struct rt_device_ops _ops =
  439. {
  440. _init,
  441. RT_NULL,
  442. RT_NULL,
  443. RT_NULL,
  444. RT_NULL,
  445. RT_NULL,
  446. };
  447. #endif
  448. int nu_usbd_register(void)
  449. {
  450. if (RT_NULL != rt_device_find("usbd"))
  451. {
  452. LOG_E("\nUSBD Register failed. Another USBD device registered\n");
  453. return -RT_ERROR;
  454. }
  455. rt_memset((void *)&_rt_obj_udc, 0, sizeof(struct udcd));
  456. _rt_obj_udc.parent.type = RT_Device_Class_USBDevice;
  457. #ifdef RT_USING_DEVICE_OPS
  458. _rt_obj_udc.parent.ops = &_ops;
  459. #else
  460. _rt_obj_udc.parent.init = _init;
  461. #endif
  462. _rt_obj_udc.parent.user_data = &nu_usbd_obj;
  463. _rt_obj_udc.ops = &_udc_ops;
  464. /* Register endpoint information */
  465. _rt_obj_udc.ep_pool = _ep_pool;
  466. _rt_obj_udc.ep0.id = &_ep_pool[0];
  467. _rt_obj_udc.device_is_hs = RT_FALSE; /* Support Full-Speed only */
  468. rt_device_register((rt_device_t)&_rt_obj_udc, "usbd", 0);
  469. return rt_usb_device_init();
  470. }
  471. INIT_DEVICE_EXPORT(nu_usbd_register);
  472. #endif