drv_hsusbd.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  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-5-26 Egbert First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #ifdef BSP_USING_HSUSBD
  14. #include <rtthread.h>
  15. #include <rtdevice.h>
  16. #include <string.h>
  17. #include "NuMicro.h"
  18. #define LOG_TAG "drv.hsusbd"
  19. #define DBG_ENABLE
  20. #define DBG_SECTION_NAME "drv.hsusbd"
  21. #define DBG_LEVEL DBG_ERROR
  22. #define DBG_COLOR
  23. #include <rtdbg.h>
  24. /* Private define ---------------------------------------------------------------*/
  25. #define ENABLE_FULL_SPEED_MODE_ONLY 0 /* 0: default hi-speed mode; 1: full-speed mode only */
  26. /* Define EP maximum packet size */
  27. #define CEP_MAX_PKT_SIZE 64
  28. #define CEP_OTHER_MAX_PKT_SIZE 64
  29. #define EPA_MAX_PKT_SIZE 512
  30. #define EPA_OTHER_MAX_PKT_SIZE 64
  31. #define EPB_MAX_PKT_SIZE 512
  32. #define EPB_OTHER_MAX_PKT_SIZE 64
  33. #define EPC_MAX_PKT_SIZE 64
  34. #define EPC_OTHER_MAX_PKT_SIZE 64
  35. #define EPD_MAX_PKT_SIZE 64
  36. #define EPD_OTHER_MAX_PKT_SIZE 64
  37. #define EPE_MAX_PKT_SIZE 512
  38. #define EPE_OTHER_MAX_PKT_SIZE 64
  39. #define EPF_MAX_PKT_SIZE 512
  40. #define EPF_OTHER_MAX_PKT_SIZE 64
  41. #define EPG_MAX_PKT_SIZE 64
  42. #define EPG_OTHER_MAX_PKT_SIZE 64
  43. #define EPH_MAX_PKT_SIZE 64
  44. #define EPH_OTHER_MAX_PKT_SIZE 64
  45. #define CEP_BUF_BASE 0
  46. #define CEP_BUF_LEN CEP_MAX_PKT_SIZE
  47. #define EPA_BUF_BASE (CEP_BUF_BASE + CEP_BUF_LEN)
  48. #define EPA_BUF_LEN EPA_MAX_PKT_SIZE
  49. #define EPB_BUF_BASE (EPA_BUF_BASE + EPA_BUF_LEN)
  50. #define EPB_BUF_LEN EPB_MAX_PKT_SIZE
  51. #define EPC_BUF_BASE (EPB_BUF_BASE + EPB_BUF_LEN)
  52. #define EPC_BUF_LEN EPC_MAX_PKT_SIZE
  53. #define EPD_BUF_BASE (EPC_BUF_BASE + EPC_BUF_LEN)
  54. #define EPD_BUF_LEN EPD_MAX_PKT_SIZE
  55. #define EPE_BUF_BASE (EPD_BUF_BASE + EPD_BUF_LEN)
  56. #define EPE_BUF_LEN EPE_MAX_PKT_SIZE
  57. #define EPF_BUF_BASE (EPE_BUF_BASE + EPE_BUF_LEN)
  58. #define EPF_BUF_LEN EPF_MAX_PKT_SIZE
  59. #define EPG_BUF_BASE (EPF_BUF_BASE + EPF_BUF_LEN)
  60. #define EPG_BUF_LEN EPG_MAX_PKT_SIZE
  61. #define EPH_BUF_BASE (EPG_BUF_BASE + EPG_BUF_LEN)
  62. #define EPH_BUF_LEN EPH_MAX_PKT_SIZE
  63. #define EPADR_SW2HW(address) ((address & USB_EPNO_MASK) - 1) /* for non-control endpoint */
  64. #define EPADR_HW2SW(address) ((address & USB_EPNO_MASK) + 1) /* for non-control endpoint */
  65. /* Private typedef --------------------------------------------------------------*/
  66. typedef struct _nu_usbd_t
  67. {
  68. HSUSBD_T *Instance; /* REG base */
  69. uint8_t address_tmp; /* Keep assigned address for flow control */
  70. } nu_usbd_t;
  71. /* Private variables ------------------------------------------------------------*/
  72. static nu_usbd_t nu_usbd =
  73. {
  74. .Instance = HSUSBD,
  75. .address_tmp = 0,
  76. };
  77. static struct udcd _rt_obj_udc;
  78. static struct ep_id _ep_pool[] =
  79. {
  80. {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, CEP_MAX_PKT_SIZE, ID_ASSIGNED },
  81. {EPADR_HW2SW(EPA), USB_EP_ATTR_BULK, USB_DIR_IN, EPA_MAX_PKT_SIZE, ID_UNASSIGNED},
  82. {EPADR_HW2SW(EPB), USB_EP_ATTR_BULK, USB_DIR_OUT, EPB_MAX_PKT_SIZE, ID_UNASSIGNED},
  83. {EPADR_HW2SW(EPC), USB_EP_ATTR_INT, USB_DIR_IN, EPC_MAX_PKT_SIZE, ID_UNASSIGNED},
  84. {EPADR_HW2SW(EPD), USB_EP_ATTR_INT, USB_DIR_OUT, EPD_MAX_PKT_SIZE, ID_UNASSIGNED},
  85. {EPADR_HW2SW(EPE), USB_EP_ATTR_BULK, USB_DIR_IN, EPE_MAX_PKT_SIZE, ID_UNASSIGNED},
  86. {EPADR_HW2SW(EPF), USB_EP_ATTR_BULK, USB_DIR_OUT, EPF_MAX_PKT_SIZE, ID_UNASSIGNED},
  87. {EPADR_HW2SW(EPG), USB_EP_ATTR_INT, USB_DIR_IN, EPG_MAX_PKT_SIZE, ID_UNASSIGNED},
  88. {EPADR_HW2SW(EPH), USB_EP_ATTR_INT, USB_DIR_OUT, EPH_MAX_PKT_SIZE, ID_UNASSIGNED},
  89. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  90. };
  91. static void _nu_ep_partition_fs(void)
  92. {
  93. /*****************************************************/
  94. /* EPA ==> Bulk IN endpoint, address 1 */
  95. HSUSBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);
  96. HSUSBD_SET_MAX_PAYLOAD(EPA, EPA_OTHER_MAX_PKT_SIZE);
  97. HSUSBD_ConfigEp(EPA, EPADR_HW2SW(EPA), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_IN);
  98. /* EPB ==> Bulk OUT endpoint, address 2 */
  99. HSUSBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);
  100. HSUSBD_SET_MAX_PAYLOAD(EPB, EPB_OTHER_MAX_PKT_SIZE);
  101. HSUSBD_ConfigEp(EPB, EPADR_HW2SW(EPB), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_OUT);
  102. HSUSBD_ENABLE_EP_INT(EPB, HSUSBD_EPINTEN_RXPKIEN_Msk);
  103. /*****************************************************/
  104. /* EPC ==> Interrupt IN endpoint, address 3 */
  105. HSUSBD_SetEpBufAddr(EPC, EPC_BUF_BASE, EPC_BUF_LEN);
  106. HSUSBD_SET_MAX_PAYLOAD(EPC, EPC_OTHER_MAX_PKT_SIZE);
  107. HSUSBD_ConfigEp(EPC, EPADR_HW2SW(EPC), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_IN);
  108. /* EPD ==> Interrupt OUT endpoint, address 4 */
  109. HSUSBD_SetEpBufAddr(EPD, EPD_BUF_BASE, EPD_BUF_LEN);
  110. HSUSBD_SET_MAX_PAYLOAD(EPD, EPD_OTHER_MAX_PKT_SIZE);
  111. HSUSBD_ConfigEp(EPD, EPADR_HW2SW(EPD), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_OUT);
  112. HSUSBD_ENABLE_EP_INT(EPD, HSUSBD_EPINTEN_RXPKIEN_Msk);
  113. /*****************************************************/
  114. /* EPE ==> Bulk IN endpoint, address 5 */
  115. HSUSBD_SetEpBufAddr(EPE, EPE_BUF_BASE, EPE_BUF_LEN);
  116. HSUSBD_SET_MAX_PAYLOAD(EPE, EPE_OTHER_MAX_PKT_SIZE);
  117. HSUSBD_ConfigEp(EPE, EPADR_HW2SW(EPE), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_IN);
  118. /* EPF ==> Bulk OUT endpoint, address 6 */
  119. HSUSBD_SetEpBufAddr(EPF, EPF_BUF_BASE, EPF_BUF_LEN);
  120. HSUSBD_SET_MAX_PAYLOAD(EPF, EPF_OTHER_MAX_PKT_SIZE);
  121. HSUSBD_ConfigEp(EPF, EPADR_HW2SW(EPF), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_OUT);
  122. HSUSBD_ENABLE_EP_INT(EPF, HSUSBD_EPINTEN_RXPKIEN_Msk);
  123. /*****************************************************/
  124. /* EPG ==> Interrupt IN endpoint, address 7 */
  125. HSUSBD_SetEpBufAddr(EPG, EPG_BUF_BASE, EPG_BUF_LEN);
  126. HSUSBD_SET_MAX_PAYLOAD(EPG, EPG_OTHER_MAX_PKT_SIZE);
  127. HSUSBD_ConfigEp(EPG, EPADR_HW2SW(EPG), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_IN);
  128. /* EPH ==> Interrupt OUT endpoint, address 8 */
  129. HSUSBD_SetEpBufAddr(EPH, EPH_BUF_BASE, EPH_BUF_LEN);
  130. HSUSBD_SET_MAX_PAYLOAD(EPH, EPH_OTHER_MAX_PKT_SIZE);
  131. HSUSBD_ConfigEp(EPH, EPADR_HW2SW(EPH), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_OUT);
  132. HSUSBD_ENABLE_EP_INT(EPH, HSUSBD_EPINTEN_RXPKIEN_Msk);
  133. }
  134. static void _nu_ep_partition_hs(void)
  135. {
  136. /*****************************************************/
  137. /* EPA ==> Bulk IN endpoint, address 1 */
  138. HSUSBD_SetEpBufAddr(EPA, EPA_BUF_BASE, EPA_BUF_LEN);
  139. HSUSBD_SET_MAX_PAYLOAD(EPA, EPA_MAX_PKT_SIZE);
  140. HSUSBD_ConfigEp(EPA, EPADR_HW2SW(EPA), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_IN);
  141. /* EPB ==> Bulk OUT endpoint, address 2 */
  142. HSUSBD_SetEpBufAddr(EPB, EPB_BUF_BASE, EPB_BUF_LEN);
  143. HSUSBD_SET_MAX_PAYLOAD(EPB, EPB_MAX_PKT_SIZE);
  144. HSUSBD_ConfigEp(EPB, EPADR_HW2SW(EPB), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_OUT);
  145. HSUSBD_ENABLE_EP_INT(EPB, HSUSBD_EPINTEN_RXPKIEN_Msk);
  146. /*****************************************************/
  147. /* EPC ==> Interrupt IN endpoint, address 3 */
  148. HSUSBD_SetEpBufAddr(EPC, EPC_BUF_BASE, EPC_BUF_LEN);
  149. HSUSBD_SET_MAX_PAYLOAD(EPC, EPC_MAX_PKT_SIZE);
  150. HSUSBD_ConfigEp(EPC, EPADR_HW2SW(EPC), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_IN);
  151. /* EPD ==> Interrupt OUT endpoint, address 4 */
  152. HSUSBD_SetEpBufAddr(EPD, EPD_BUF_BASE, EPD_BUF_LEN);
  153. HSUSBD_SET_MAX_PAYLOAD(EPD, EPD_MAX_PKT_SIZE);
  154. HSUSBD_ConfigEp(EPD, EPADR_HW2SW(EPD), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_OUT);
  155. HSUSBD_ENABLE_EP_INT(EPD, HSUSBD_EPINTEN_RXPKIEN_Msk);
  156. /*****************************************************/
  157. /* EPE ==> Bulk IN endpoint, address 5 */
  158. HSUSBD_SetEpBufAddr(EPE, EPE_BUF_BASE, EPE_BUF_LEN);
  159. HSUSBD_SET_MAX_PAYLOAD(EPE, EPE_MAX_PKT_SIZE);
  160. HSUSBD_ConfigEp(EPE, EPADR_HW2SW(EPE), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_IN);
  161. /* EPF ==> Bulk OUT endpoint, address 6 */
  162. HSUSBD_SetEpBufAddr(EPF, EPF_BUF_BASE, EPF_BUF_LEN);
  163. HSUSBD_SET_MAX_PAYLOAD(EPF, EPF_MAX_PKT_SIZE);
  164. HSUSBD_ConfigEp(EPF, EPADR_HW2SW(EPF), HSUSBD_EP_CFG_TYPE_BULK, HSUSBD_EP_CFG_DIR_OUT);
  165. HSUSBD_ENABLE_EP_INT(EPF, HSUSBD_EPINTEN_RXPKIEN_Msk);
  166. /*****************************************************/
  167. /* EPG ==> Interrupt IN endpoint, address 7 */
  168. HSUSBD_SetEpBufAddr(EPG, EPG_BUF_BASE, EPG_BUF_LEN);
  169. HSUSBD_SET_MAX_PAYLOAD(EPG, EPG_MAX_PKT_SIZE);
  170. HSUSBD_ConfigEp(EPG, EPADR_HW2SW(EPG), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_IN);
  171. /* EPH ==> Interrupt OUT endpoint, address 8 */
  172. HSUSBD_SetEpBufAddr(EPH, EPH_BUF_BASE, EPH_BUF_LEN);
  173. HSUSBD_SET_MAX_PAYLOAD(EPH, EPH_MAX_PKT_SIZE);
  174. HSUSBD_ConfigEp(EPH, EPADR_HW2SW(EPH), HSUSBD_EP_CFG_TYPE_INT, HSUSBD_EP_CFG_DIR_OUT);
  175. HSUSBD_ENABLE_EP_INT(EPH, HSUSBD_EPINTEN_RXPKIEN_Msk);
  176. }
  177. static void _nu_ep_partition(void)
  178. {
  179. /* Configure USB controller */
  180. /* Enable USB BUS, CEP and EPA ~ EPH global interrupt */
  181. HSUSBD_ENABLE_USB_INT(HSUSBD_GINTEN_USBIEN_Msk
  182. | HSUSBD_GINTEN_CEPIEN_Msk
  183. | HSUSBD_GINTEN_EPAIEN_Msk
  184. | HSUSBD_GINTEN_EPBIEN_Msk
  185. | HSUSBD_GINTEN_EPCIEN_Msk
  186. | HSUSBD_GINTEN_EPDIEN_Msk
  187. | HSUSBD_GINTEN_EPEIEN_Msk
  188. | HSUSBD_GINTEN_EPFIEN_Msk
  189. | HSUSBD_GINTEN_EPGIEN_Msk
  190. | HSUSBD_GINTEN_EPHIEN_Msk
  191. );
  192. /* Enable BUS interrupt */
  193. HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_DMADONEIEN_Msk
  194. | HSUSBD_BUSINTEN_RESUMEIEN_Msk
  195. | HSUSBD_BUSINTEN_RSTIEN_Msk
  196. | HSUSBD_BUSINTEN_VBUSDETIEN_Msk);
  197. /* Reset Address to 0 */
  198. HSUSBD_SET_ADDR(0);
  199. /*****************************************************/
  200. /* Control endpoint */
  201. HSUSBD_SetEpBufAddr(CEP, CEP_BUF_BASE, CEP_BUF_LEN);
  202. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk
  203. | HSUSBD_CEPINTEN_STSDONEIEN_Msk
  204. );
  205. _nu_ep_partition_hs();
  206. }
  207. static void NU_SetupStageCallback(nu_usbd_t *nu_udc)
  208. {
  209. struct urequest setup_packet;
  210. /* Setup packet process */
  211. setup_packet.request_type = (uint8_t)(nu_udc->Instance->SETUP1_0 & 0xfful);
  212. setup_packet.bRequest = (uint8_t)((nu_udc->Instance->SETUP1_0 >> 8) & 0xfful);
  213. setup_packet.wValue = (uint16_t) nu_udc->Instance->SETUP3_2;
  214. setup_packet.wIndex = (uint16_t) nu_udc->Instance->SETUP5_4;
  215. setup_packet.wLength = (uint16_t) nu_udc->Instance->SETUP7_6;
  216. rt_usbd_ep0_setup_handler(&_rt_obj_udc, (struct urequest *)&setup_packet);
  217. }
  218. static rt_err_t _ep_set_stall(rt_uint8_t address)
  219. {
  220. if (address & USB_EPNO_MASK)
  221. {
  222. HSUSBD_SetEpStall(EPADR_SW2HW(address));
  223. }
  224. else
  225. {
  226. /* Not support. Reply STALL. */
  227. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_STALLEN_Msk);
  228. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk);
  229. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
  230. }
  231. return RT_EOK;
  232. }
  233. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  234. {
  235. if (address & USB_EPNO_MASK)
  236. {
  237. HSUSBD_ClearEpStall(EPADR_SW2HW(address));
  238. }
  239. return RT_EOK;
  240. }
  241. static rt_err_t _set_address(rt_uint8_t address)
  242. {
  243. if (0 != address)
  244. {
  245. nu_usbd.address_tmp = address;
  246. }
  247. return RT_EOK;
  248. }
  249. static rt_err_t _set_config(rt_uint8_t address)
  250. {
  251. return RT_EOK;
  252. }
  253. static rt_err_t _ep_enable(uep_t ep)
  254. {
  255. RT_ASSERT(ep != RT_NULL);
  256. RT_ASSERT(ep->ep_desc != RT_NULL);
  257. HSUSBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPRSPCTL = HSUSBD_EP_RSPCTL_TOGGLE;
  258. HSUSBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPCFG |= HSUSBD_EP_CFG_VALID;
  259. return RT_EOK;
  260. }
  261. static rt_err_t _ep_disable(uep_t ep)
  262. {
  263. RT_ASSERT(ep != RT_NULL);
  264. RT_ASSERT(ep->ep_desc != RT_NULL);
  265. HSUSBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPCFG &= ~HSUSBD_EP_CFG_VALID;
  266. return RT_EOK;
  267. }
  268. static rt_err_t _ep0_send_status(void)
  269. {
  270. /* Status Stage */
  271. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk
  272. | HSUSBD_CEPINTSTS_SETUPPKIF_Msk
  273. );
  274. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk);
  275. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
  276. return RT_EOK;
  277. }
  278. __STATIC_INLINE void nu_buffer_cpy(rt_uint8_t address, void *buffer, rt_size_t size)
  279. {
  280. rt_uint32_t i, cnt;
  281. rt_uint32_t *_buf_word;
  282. rt_uint8_t *_buf_byte;
  283. _buf_word = (rt_uint32_t *)buffer;
  284. cnt = size >> 2;
  285. _buf_byte = (rt_uint8_t *)((rt_uint8_t *)buffer + (cnt * 4));
  286. if ((address & USB_EPNO_MASK)) //EPs
  287. {
  288. if (address & USB_DIR_IN) //IN
  289. {
  290. /* Non-control endpoint IN*/
  291. for (i = 0; i < cnt; i++)
  292. {
  293. HSUSBD->EP[EPADR_SW2HW(address)].EPDAT = _buf_word[i];
  294. }
  295. for (i = 0ul; i < (size % 4ul); i++)
  296. HSUSBD->EP[EPADR_SW2HW(address)].EPDAT_BYTE = _buf_byte[i];
  297. }
  298. else //OUT
  299. {
  300. for (i = 0; i < cnt; i++)
  301. {
  302. _buf_word[i] = HSUSBD->EP[EPADR_SW2HW(address)].EPDAT;
  303. }
  304. for (i = 0ul; i < (size % 4ul); i++)
  305. _buf_byte[i] = HSUSBD->EP[EPADR_SW2HW(address)].EPDAT_BYTE;
  306. }
  307. }
  308. else //Control
  309. {
  310. if (address & USB_DIR_IN) //IN
  311. {
  312. for (i = 0; i < cnt; i++)
  313. {
  314. HSUSBD->CEPDAT = _buf_word[i];
  315. }
  316. for (i = 0ul; i < (size % 4ul); i++)
  317. HSUSBD->CEPDAT_BYTE = _buf_byte[i];
  318. }
  319. else //OUT
  320. {
  321. for (i = 0; i < cnt; i++)
  322. {
  323. _buf_word[i] = HSUSBD->CEPDAT;
  324. }
  325. for (i = 0ul; i < (size % 4ul); i++)
  326. _buf_byte[i] = HSUSBD->CEPDAT_BYTE;
  327. }
  328. }
  329. }
  330. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  331. {
  332. rt_size_t size = 0;
  333. RT_ASSERT(!(address & USB_DIR_IN));
  334. if ((address & USB_EPNO_MASK))
  335. {
  336. RT_ASSERT(buffer != RT_NULL);
  337. size = HSUSBD->EP[EPADR_SW2HW(address)].EPDATCNT & 0xffff;
  338. nu_buffer_cpy(address, buffer, size);
  339. }
  340. else //control transfer
  341. {
  342. size = HSUSBD->CEPRXCNT & 0xffff;
  343. if (size)
  344. {
  345. RT_ASSERT(_rt_obj_udc.stage == STAGE_DOUT);
  346. nu_buffer_cpy(address, buffer, size);
  347. }
  348. _ep0_send_status();
  349. }
  350. return size;
  351. }
  352. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  353. {
  354. RT_ASSERT(!(address & USB_DIR_IN));
  355. if ((address & USB_EPNO_MASK))
  356. {
  357. HSUSBD_ENABLE_EP_INT(EPADR_SW2HW(address),
  358. HSUSBD_EPINTEN_RXPKIEN_Msk
  359. );
  360. }
  361. else //control transfer
  362. {
  363. if (size)
  364. {
  365. RT_ASSERT(_rt_obj_udc.stage == STAGE_DOUT);
  366. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_OUTTKIEN_Msk);
  367. }
  368. else
  369. {
  370. RT_ASSERT(_rt_obj_udc.stage == STAGE_STATUS_OUT);
  371. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk
  372. | HSUSBD_CEPINTSTS_STSDONEIF_Msk
  373. );
  374. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk
  375. | HSUSBD_CEPINTEN_STSDONEIEN_Msk
  376. );
  377. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
  378. }
  379. }
  380. return size;
  381. }
  382. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  383. {
  384. RT_ASSERT((address & USB_DIR_IN));
  385. if (!(address & USB_EPNO_MASK)) //control transfer
  386. {
  387. if (size)
  388. {
  389. nu_buffer_cpy(address, buffer, size);
  390. HSUSBD_START_CEP_IN(size);
  391. }
  392. else//zero length
  393. {
  394. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_ZEROLEN);
  395. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk
  396. | HSUSBD_CEPINTSTS_SETUPPKIF_Msk);
  397. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk
  398. | HSUSBD_CEPINTEN_STSDONEIEN_Msk
  399. );
  400. }
  401. if (_rt_obj_udc.stage == STAGE_DIN)
  402. {
  403. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk);
  404. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk);
  405. }
  406. else if (_rt_obj_udc.stage == STAGE_DOUT)
  407. {
  408. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_RXPKIF_Msk);
  409. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_RXPKIEN_Msk);
  410. }
  411. }
  412. else
  413. {
  414. /* Non-control endpoint IN*/
  415. nu_buffer_cpy(address, buffer, size);
  416. HSUSBD->EP[EPADR_SW2HW(address)].EPRSPCTL = HSUSBD_EP_RSPCTL_SHORTTXEN; // packet end
  417. HSUSBD->EP[EPADR_SW2HW(address)].EPTXCNT = size;
  418. if ((HSUSBD->EP[EPADR_SW2HW(address)].EPCFG & HSUSBD_EPCFG_EPTYPE_Msk) == HSUSBD_EP_CFG_TYPE_INT)
  419. {
  420. HSUSBD_ENABLE_EP_INT(EPADR_SW2HW(address), HSUSBD_EPINTEN_INTKIEN_Msk); //for interrupt transfer timing
  421. }
  422. else
  423. {
  424. HSUSBD_ENABLE_EP_INT(EPADR_SW2HW(address), HSUSBD_EPINTEN_TXPKIEN_Msk); //for bulk transfer timing
  425. }
  426. }
  427. return size;
  428. }
  429. static rt_err_t _suspend(void)
  430. {
  431. return RT_EOK;
  432. }
  433. static rt_err_t _wakeup(void)
  434. {
  435. return RT_EOK;
  436. }
  437. void _USBD20_IRQHandler(void)
  438. {
  439. __IO rt_uint32_t IrqStL, IrqSt;
  440. IrqStL = HSUSBD->GINTSTS & HSUSBD->GINTEN; /* get interrupt status */
  441. if (!IrqStL) return;
  442. /* USB interrupt */
  443. if (IrqStL & HSUSBD_GINTSTS_USBIF_Msk)
  444. {
  445. IrqSt = HSUSBD->BUSINTSTS & HSUSBD->BUSINTEN;
  446. if (IrqSt & HSUSBD_BUSINTSTS_SOFIF_Msk)
  447. {
  448. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SOFIF_Msk);
  449. rt_usbd_sof_handler(&_rt_obj_udc);
  450. }
  451. if (IrqSt & HSUSBD_BUSINTSTS_RSTIF_Msk)
  452. {
  453. /* Reset USB device address */
  454. HSUSBD_SET_ADDR(0ul);
  455. HSUSBD_ResetDMA();
  456. HSUSBD->EP[EPA].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  457. HSUSBD->EP[EPB].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  458. HSUSBD->EP[EPC].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  459. HSUSBD->EP[EPD].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  460. HSUSBD->EP[EPE].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  461. HSUSBD->EP[EPF].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  462. HSUSBD->EP[EPG].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  463. HSUSBD->EP[EPH].EPRSPCTL = HSUSBD_EPRSPCTL_FLUSH_Msk;
  464. if (HSUSBD->OPER & 0x04) /* high speed */
  465. {
  466. LOG_I("-High Speed-");
  467. _nu_ep_partition_hs();
  468. }
  469. else /* full speed */
  470. {
  471. LOG_I("-Full Speed-");
  472. _nu_ep_partition_fs();
  473. }
  474. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
  475. HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk
  476. | HSUSBD_BUSINTEN_RESUMEIEN_Msk
  477. | HSUSBD_BUSINTEN_SUSPENDIEN_Msk
  478. | HSUSBD_BUSINTEN_VBUSDETIEN_Msk
  479. );
  480. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RSTIF_Msk);
  481. HSUSBD_CLR_CEP_INT_FLAG(0x1ffc);
  482. for (rt_uint32_t i = 0ul; i < HSUSBD_MAX_EP; i++)
  483. {
  484. if ((HSUSBD->EP[i].EPCFG & 0x1ul) == 0x1ul)
  485. {
  486. HSUSBD->EP[i].EPRSPCTL = HSUSBD_EP_RSPCTL_TOGGLE;
  487. }
  488. }
  489. rt_usbd_reset_handler(&_rt_obj_udc);
  490. HSUSBD_ENABLE_USB();
  491. }
  492. if (IrqSt & HSUSBD_BUSINTSTS_RESUMEIF_Msk)
  493. {
  494. LOG_I("-Resume-");
  495. HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk | HSUSBD_BUSINTEN_SUSPENDIEN_Msk);
  496. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RESUMEIF_Msk);
  497. }
  498. if (IrqSt & HSUSBD_BUSINTSTS_SUSPENDIF_Msk)
  499. {
  500. LOG_I("-Suspend-");
  501. HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk | HSUSBD_BUSINTEN_RESUMEIEN_Msk | HSUSBD_BUSINTEN_VBUSDETIEN_Msk);
  502. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SUSPENDIF_Msk);
  503. }
  504. if (IrqSt & HSUSBD_BUSINTSTS_HISPDIF_Msk)
  505. {
  506. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
  507. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_HISPDIF_Msk);
  508. }
  509. if (IrqSt & HSUSBD_BUSINTSTS_DMADONEIF_Msk)
  510. {
  511. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk);
  512. if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMARD_Msk))
  513. {
  514. HSUSBD_ENABLE_EP_INT(EPD, HSUSBD_EPINTEN_RXPKIEN_Msk);
  515. }
  516. }
  517. if (IrqSt & HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk)
  518. {
  519. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk);
  520. }
  521. if (IrqSt & HSUSBD_BUSINTSTS_VBUSDETIF_Msk)
  522. {
  523. if (HSUSBD_IS_ATTACHED())
  524. {
  525. LOG_I("PLUG IN");
  526. /* USB Plug In */
  527. HSUSBD_ENABLE_USB();
  528. rt_usbd_connect_handler(&_rt_obj_udc);
  529. }
  530. else
  531. {
  532. LOG_I("Un-Plug");
  533. /* USB Un-plug */
  534. HSUSBD_DISABLE_USB();
  535. rt_usbd_disconnect_handler(&_rt_obj_udc);
  536. }
  537. HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_VBUSDETIF_Msk);
  538. }
  539. }
  540. /* Control Transfer */
  541. if (IrqStL & HSUSBD_GINTSTS_CEPIF_Msk)
  542. {
  543. IrqSt = HSUSBD->CEPINTSTS & HSUSBD->CEPINTEN;
  544. if (IrqSt & HSUSBD_CEPINTSTS_SETUPTKIF_Msk)
  545. {
  546. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPTKIF_Msk);
  547. return;
  548. }
  549. if (IrqSt & HSUSBD_CEPINTSTS_SETUPPKIF_Msk)
  550. {
  551. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk);
  552. NU_SetupStageCallback(&nu_usbd);
  553. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk
  554. | HSUSBD_CEPINTSTS_RXPKIF_Msk
  555. | HSUSBD_CEPINTSTS_STSDONEIF_Msk
  556. );
  557. return;
  558. }
  559. if (IrqSt & HSUSBD_CEPINTSTS_OUTTKIF_Msk)
  560. {
  561. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_OUTTKIF_Msk);
  562. rt_usbd_ep0_out_handler(&_rt_obj_udc, 0);
  563. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_RXPKIEN_Msk);
  564. return;
  565. }
  566. if (IrqSt & HSUSBD_CEPINTSTS_INTKIF_Msk)
  567. {
  568. HSUSBD_ENABLE_CEP_INT(0);
  569. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk);
  570. rt_usbd_ep0_in_handler(&_rt_obj_udc);
  571. return;
  572. }
  573. if (IrqSt & HSUSBD_CEPINTSTS_PINGIF_Msk)
  574. {
  575. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_PINGIF_Msk);
  576. return;
  577. }
  578. if (IrqSt & HSUSBD_CEPINTSTS_TXPKIF_Msk)
  579. {
  580. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk
  581. | HSUSBD_CEPINTSTS_SETUPPKIF_Msk
  582. | HSUSBD_CEPINTSTS_STSDONEIF_Msk
  583. );
  584. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk
  585. | HSUSBD_CEPINTEN_SETUPPKIEN_Msk
  586. | HSUSBD_CEPINTEN_STSDONEIEN_Msk
  587. );
  588. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
  589. return;
  590. }
  591. if (IrqSt & HSUSBD_CEPINTSTS_RXPKIF_Msk)
  592. {
  593. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk
  594. | HSUSBD_CEPINTSTS_STSDONEIF_Msk
  595. | HSUSBD_CEPINTSTS_RXPKIF_Msk
  596. );
  597. HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
  598. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk
  599. | HSUSBD_CEPINTEN_STSDONEIEN_Msk
  600. | HSUSBD_CEPINTEN_RXPKIEN_Msk
  601. );
  602. return;
  603. }
  604. if (IrqSt & HSUSBD_CEPINTSTS_NAKIF_Msk)
  605. {
  606. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_NAKIF_Msk);
  607. return;
  608. }
  609. if (IrqSt & HSUSBD_CEPINTSTS_STALLIF_Msk)
  610. {
  611. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STALLIF_Msk);
  612. return;
  613. }
  614. if (IrqSt & HSUSBD_CEPINTSTS_ERRIF_Msk)
  615. {
  616. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_ERRIF_Msk);
  617. return;
  618. }
  619. if (IrqSt & HSUSBD_CEPINTSTS_STSDONEIF_Msk)
  620. {
  621. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk | HSUSBD_CEPINTSTS_SETUPPKIF_Msk);
  622. HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
  623. if ((HSUSBD_GET_ADDR() == 0)
  624. && ((uint8_t)((nu_usbd.Instance->SETUP1_0 >> 8) & 0xfful) == SET_ADDRESS)
  625. )
  626. {
  627. HSUSBD_SET_ADDR(nu_usbd.address_tmp);
  628. LOG_I("SET ADDR: 0x%02x", nu_usbd.address_tmp);
  629. nu_usbd.address_tmp = 0;
  630. }
  631. return;
  632. }
  633. if (IrqSt & HSUSBD_CEPINTSTS_BUFFULLIF_Msk)
  634. {
  635. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFFULLIF_Msk);
  636. return;
  637. }
  638. if (IrqSt & HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk)
  639. {
  640. HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk);
  641. return;
  642. }
  643. }
  644. /* bulk in */
  645. if (IrqStL & HSUSBD_GINTSTS_EPAIF_Msk)
  646. {
  647. IrqSt = HSUSBD->EP[EPA].EPINTSTS & HSUSBD->EP[EPA].EPINTEN;
  648. HSUSBD_ENABLE_EP_INT(EPA, 0);
  649. HSUSBD_CLR_EP_INT_FLAG(EPA, IrqSt);
  650. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EPA), 0);
  651. }
  652. /* bulk out */
  653. if (IrqStL & HSUSBD_GINTSTS_EPBIF_Msk)
  654. {
  655. IrqSt = HSUSBD->EP[EPB].EPINTSTS & HSUSBD->EP[EPB].EPINTEN;
  656. HSUSBD_CLR_EP_INT_FLAG(EPB, IrqSt);
  657. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EPB), 0);
  658. }
  659. /* interrupt in */
  660. if (IrqStL & HSUSBD_GINTSTS_EPCIF_Msk)
  661. {
  662. IrqSt = HSUSBD->EP[EPC].EPINTSTS & HSUSBD->EP[EPC].EPINTEN;
  663. HSUSBD_ENABLE_EP_INT(EPC, 0);
  664. HSUSBD_CLR_EP_INT_FLAG(EPC, IrqSt);
  665. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EPC), 0);
  666. }
  667. /* interrupt out */
  668. if (IrqStL & HSUSBD_GINTSTS_EPDIF_Msk)
  669. {
  670. IrqSt = HSUSBD->EP[EPD].EPINTSTS & HSUSBD->EP[EPD].EPINTEN;
  671. HSUSBD_CLR_EP_INT_FLAG(EPD, IrqSt);
  672. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EPD), 0);
  673. }
  674. /* bulk in */
  675. if (IrqStL & HSUSBD_GINTSTS_EPEIF_Msk)
  676. {
  677. IrqSt = HSUSBD->EP[EPE].EPINTSTS & HSUSBD->EP[EPE].EPINTEN;
  678. HSUSBD_ENABLE_EP_INT(EPE, 0);
  679. HSUSBD_CLR_EP_INT_FLAG(EPE, IrqSt);
  680. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EPE), 0);
  681. }
  682. /* bulk out */
  683. if (IrqStL & HSUSBD_GINTSTS_EPFIF_Msk)
  684. {
  685. IrqSt = HSUSBD->EP[EPF].EPINTSTS & HSUSBD->EP[EPF].EPINTEN;
  686. HSUSBD_CLR_EP_INT_FLAG(EPF, IrqSt);
  687. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EPF), 0);
  688. }
  689. /* interrupt in */
  690. if (IrqStL & HSUSBD_GINTSTS_EPGIF_Msk)
  691. {
  692. IrqSt = HSUSBD->EP[EPG].EPINTSTS & HSUSBD->EP[EPG].EPINTEN;
  693. HSUSBD_ENABLE_EP_INT(EPG, 0);
  694. HSUSBD_CLR_EP_INT_FLAG(EPG, IrqSt);
  695. rt_usbd_ep_in_handler(&_rt_obj_udc, USB_DIR_IN | EPADR_HW2SW(EPG), 0);
  696. }
  697. /* interrupt out */
  698. if (IrqStL & HSUSBD_GINTSTS_EPHIF_Msk)
  699. {
  700. IrqSt = HSUSBD->EP[EPH].EPINTSTS & HSUSBD->EP[EPH].EPINTEN;
  701. HSUSBD_CLR_EP_INT_FLAG(EPH, IrqSt);
  702. rt_usbd_ep_out_handler(&_rt_obj_udc, USB_DIR_OUT | EPADR_HW2SW(EPH), 0);
  703. }
  704. }
  705. void USBD20_IRQHandler(void)
  706. {
  707. rt_interrupt_enter();
  708. _USBD20_IRQHandler();
  709. /* leave interrupt */
  710. rt_interrupt_leave();
  711. }
  712. static rt_err_t _init(rt_device_t device)
  713. {
  714. #if !defined(BSP_USING_HSOTG)
  715. uint32_t volatile i;
  716. /* Initialize USB PHY */
  717. SYS_UnlockReg();
  718. SYS->USBPHY &= ~SYS_USBPHY_HSUSBROLE_Msk; /* select HSUSBD */
  719. /* Enable USB PHY */
  720. SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | SYS_USBPHY_HSUSBEN_Msk;
  721. for (i = 0; i < 0x1000; i++)
  722. __NOP(); // delay > 10 us
  723. SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk;
  724. SYS_LockReg();
  725. #endif
  726. /* HSUSBD Open */
  727. HSUSBD->PHYCTL |= (HSUSBD_PHYCTL_PHYEN_Msk | HSUSBD_PHYCTL_DPPUEN_Msk);
  728. while (1)
  729. {
  730. HSUSBD->EP[EPA].EPMPS = 0x20ul;
  731. if (HSUSBD->EP[EPA].EPMPS == 0x20ul)
  732. {
  733. break;
  734. }
  735. }
  736. /* Force SE0 */
  737. HSUSBD_SET_SE0();
  738. _nu_ep_partition();
  739. #if ENABLE_FULL_SPEED_MODE_ONLY
  740. HSUSBD->OPER &= ~HSUSBD_OPER_HISPDEN_Msk;
  741. #else
  742. HSUSBD->OPER |= HSUSBD_OPER_HISPDEN_Msk;
  743. #endif
  744. /* Enable USBD interrupt */
  745. NVIC_EnableIRQ(USBD20_IRQn);
  746. /* Start transaction */
  747. HSUSBD_Start();
  748. return RT_EOK;
  749. }
  750. const static struct udcd_ops _udc_ops =
  751. {
  752. _set_address,
  753. _set_config,
  754. _ep_set_stall,
  755. _ep_clear_stall,
  756. _ep_enable,
  757. _ep_disable,
  758. _ep_read_prepare,
  759. _ep_read,
  760. _ep_write,
  761. _ep0_send_status,
  762. _suspend,
  763. _wakeup,
  764. };
  765. #ifdef RT_USING_DEVICE_OPS
  766. const static struct rt_device_ops _ops =
  767. {
  768. _init,
  769. RT_NULL,
  770. RT_NULL,
  771. RT_NULL,
  772. RT_NULL,
  773. RT_NULL,
  774. };
  775. #endif
  776. int nu_hsusbd_register(void)
  777. {
  778. if (RT_NULL != rt_device_find("usbd"))
  779. {
  780. LOG_E("\nHSUSBD Register failed. Another USBD device is registered\n");
  781. return -RT_ERROR;
  782. }
  783. rt_memset((void *)&_rt_obj_udc, 0, sizeof(struct udcd));
  784. _rt_obj_udc.parent.type = RT_Device_Class_USBDevice;
  785. #ifdef RT_USING_DEVICE_OPS
  786. _rt_obj_udc.parent.ops = &_ops;
  787. #else
  788. _rt_obj_udc.parent.init = _init;
  789. #endif
  790. _rt_obj_udc.parent.user_data = &nu_usbd;
  791. _rt_obj_udc.ops = &_udc_ops;
  792. /* Register endpoint information */
  793. _rt_obj_udc.ep_pool = _ep_pool;
  794. _rt_obj_udc.ep0.id = &_ep_pool[0];
  795. #if ENABLE_FULL_SPEED_MODE_ONLY
  796. _rt_obj_udc.device_is_hs = RT_FALSE; /* Enable Full-speed only */
  797. #else
  798. _rt_obj_udc.device_is_hs = RT_TRUE; /* Support Hi-Speed */
  799. #endif
  800. rt_device_register((rt_device_t)&_rt_obj_udc, "usbd", 0);
  801. rt_usb_device_init();
  802. return RT_EOK;
  803. }
  804. INIT_DEVICE_EXPORT(nu_hsusbd_register);
  805. #endif