drv_usbd.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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. * 2021-03-16 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 <string.h>
  17. #include "NuMicro.h"
  18. #include <nu_bitutil.h>
  19. #include "drv_sys.h"
  20. #define LOG_TAG "drv.usbd"
  21. //#define DBG_ENABLE
  22. #define DBG_SECTION_NAME "drv.usbd"
  23. //#define DBG_LEVEL DBG_ERROR
  24. #define DBG_COLOR
  25. #include <rtdbg.h>
  26. /* Private define ---------------------------------------------------------------*/
  27. #define ENABLE_FULL_SPEED_MODE_ONLY 0 /* 0: default hi-speed mode; 1: full-speed mode only */
  28. /* Define EP maximum packet size */
  29. #define CEP_MAX_PKT_SIZE 64
  30. #define CEP_OTHER_MAX_PKT_SIZE 64
  31. #define EPA_MAX_PKT_SIZE 512
  32. #define EPA_OTHER_MAX_PKT_SIZE 64
  33. #define EPB_MAX_PKT_SIZE 512
  34. #define EPB_OTHER_MAX_PKT_SIZE 64
  35. #define EPC_MAX_PKT_SIZE 64
  36. #define EPC_OTHER_MAX_PKT_SIZE 64
  37. #define EPD_MAX_PKT_SIZE 64
  38. #define EPD_OTHER_MAX_PKT_SIZE 64
  39. #define EPE_MAX_PKT_SIZE 512
  40. #define EPE_OTHER_MAX_PKT_SIZE 64
  41. #define EPF_MAX_PKT_SIZE 512
  42. #define EPF_OTHER_MAX_PKT_SIZE 64
  43. #define EPG_MAX_PKT_SIZE 64
  44. #define EPG_OTHER_MAX_PKT_SIZE 64
  45. #define EPH_MAX_PKT_SIZE 64
  46. #define EPH_OTHER_MAX_PKT_SIZE 64
  47. #define EPI_MAX_PKT_SIZE 512
  48. #define EPI_OTHER_MAX_PKT_SIZE 64
  49. #define EPJ_MAX_PKT_SIZE 512
  50. #define EPJ_OTHER_MAX_PKT_SIZE 64
  51. #define EPK_MAX_PKT_SIZE 64
  52. #define EPK_OTHER_MAX_PKT_SIZE 64
  53. #define EPL_MAX_PKT_SIZE 64
  54. #define EPL_OTHER_MAX_PKT_SIZE 64
  55. #define CEP_BUF_BASE 0
  56. #define CEP_BUF_LEN CEP_MAX_PKT_SIZE
  57. #define EPA_BUF_BASE (CEP_BUF_BASE + CEP_BUF_LEN)
  58. #define EPA_BUF_LEN EPA_MAX_PKT_SIZE
  59. #define EPB_BUF_BASE (EPA_BUF_BASE + EPA_BUF_LEN)
  60. #define EPB_BUF_LEN EPB_MAX_PKT_SIZE
  61. #define EPC_BUF_BASE (EPB_BUF_BASE + EPB_BUF_LEN)
  62. #define EPC_BUF_LEN EPC_MAX_PKT_SIZE
  63. #define EPD_BUF_BASE (EPC_BUF_BASE + EPC_BUF_LEN)
  64. #define EPD_BUF_LEN EPD_MAX_PKT_SIZE
  65. #define EPE_BUF_BASE (EPD_BUF_BASE + EPD_BUF_LEN)
  66. #define EPE_BUF_LEN EPE_MAX_PKT_SIZE
  67. #define EPF_BUF_BASE (EPE_BUF_BASE + EPE_BUF_LEN)
  68. #define EPF_BUF_LEN EPF_MAX_PKT_SIZE
  69. #define EPG_BUF_BASE (EPF_BUF_BASE + EPF_BUF_LEN)
  70. #define EPG_BUF_LEN EPG_MAX_PKT_SIZE
  71. #define EPH_BUF_BASE (EPG_BUF_BASE + EPG_BUF_LEN)
  72. #define EPH_BUF_LEN EPH_MAX_PKT_SIZE
  73. #define EPI_BUF_BASE (EPH_BUF_BASE + EPH_BUF_LEN)
  74. #define EPI_BUF_LEN EPI_MAX_PKT_SIZE
  75. #define EPJ_BUF_BASE (EPI_BUF_BASE + EPI_BUF_LEN)
  76. #define EPJ_BUF_LEN EPJ_MAX_PKT_SIZE
  77. #define EPK_BUF_BASE (EPJ_BUF_BASE + EPJ_BUF_LEN)
  78. #define EPK_BUF_LEN EPK_MAX_PKT_SIZE
  79. #define EPL_BUF_BASE (EPK_BUF_BASE + EPK_BUF_LEN)
  80. #define EPL_BUF_LEN EPL_MAX_PKT_SIZE
  81. #define EPADR_SW2HW(address) ((address & USB_EPNO_MASK) - 1) /* for non-control endpoint */
  82. #define EPADR_HW2SW(address) ((address & USB_EPNO_MASK) + 1) /* for non-control endpoint */
  83. /* Private typedef --------------------------------------------------------------*/
  84. typedef struct _nu_usbd_t
  85. {
  86. USBD_T *base; /* REG base */
  87. char *name;
  88. IRQn_Type irqn;
  89. E_SYS_IPRST rstidx;
  90. E_SYS_IPCLK clkidx;
  91. uint8_t address_tmp; /* Keep assigned address for flow control */
  92. uint8_t plugging_status; /* For debounce, 0: Unplug, 1: plug-in */
  93. } nu_usbd_t;
  94. typedef struct
  95. {
  96. uint32_t u32BufferBase;
  97. uint32_t u32BufferLength;
  98. uint32_t u32OtherMaxPktSize;
  99. } S_EP_CXT;
  100. /* Private variables ------------------------------------------------------------*/
  101. static nu_usbd_t nu_usbd =
  102. {
  103. .base = USBD,
  104. .name = "usbd",
  105. .irqn = IRQ_USBD,
  106. .rstidx = USBDRST,
  107. .clkidx = USBDCKEN,
  108. .address_tmp = 0,
  109. .plugging_status = 0,
  110. };
  111. static struct udcd _rt_obj_udc;
  112. static S_EP_CXT _ep_cxt_pool[] =
  113. {
  114. { EPA_BUF_BASE, EPA_BUF_LEN, EPA_OTHER_MAX_PKT_SIZE}, //EPA
  115. { EPB_BUF_BASE, EPB_BUF_LEN, EPB_OTHER_MAX_PKT_SIZE}, //EPB
  116. { EPC_BUF_BASE, EPC_BUF_LEN, EPC_OTHER_MAX_PKT_SIZE}, //EPC
  117. { EPD_BUF_BASE, EPD_BUF_LEN, EPD_OTHER_MAX_PKT_SIZE}, //EPD
  118. { EPE_BUF_BASE, EPE_BUF_LEN, EPE_OTHER_MAX_PKT_SIZE}, //EPE
  119. { EPF_BUF_BASE, EPF_BUF_LEN, EPF_OTHER_MAX_PKT_SIZE}, //EPF
  120. { EPG_BUF_BASE, EPG_BUF_LEN, EPG_OTHER_MAX_PKT_SIZE}, //EPG
  121. { EPH_BUF_BASE, EPH_BUF_LEN, EPH_OTHER_MAX_PKT_SIZE}, //EPH
  122. { EPI_BUF_BASE, EPI_BUF_LEN, EPI_OTHER_MAX_PKT_SIZE}, //EPI
  123. { EPJ_BUF_BASE, EPJ_BUF_LEN, EPJ_OTHER_MAX_PKT_SIZE}, //EPJ
  124. { EPK_BUF_BASE, EPK_BUF_LEN, EPK_OTHER_MAX_PKT_SIZE}, //EPK
  125. { EPL_BUF_BASE, EPL_BUF_LEN, EPL_OTHER_MAX_PKT_SIZE} //EPL
  126. };
  127. static struct ep_id _ep_pool[] =
  128. {
  129. {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, CEP_MAX_PKT_SIZE, ID_ASSIGNED },
  130. {EPADR_HW2SW(EPA), USB_EP_ATTR_BULK, USB_DIR_IN, EPA_MAX_PKT_SIZE, ID_UNASSIGNED},
  131. {EPADR_HW2SW(EPB), USB_EP_ATTR_BULK, USB_DIR_OUT, EPB_MAX_PKT_SIZE, ID_UNASSIGNED},
  132. {EPADR_HW2SW(EPC), USB_EP_ATTR_INT, USB_DIR_IN, EPC_MAX_PKT_SIZE, ID_UNASSIGNED},
  133. {EPADR_HW2SW(EPD), USB_EP_ATTR_INT, USB_DIR_OUT, EPD_MAX_PKT_SIZE, ID_UNASSIGNED},
  134. {EPADR_HW2SW(EPE), USB_EP_ATTR_BULK, USB_DIR_IN, EPE_MAX_PKT_SIZE, ID_UNASSIGNED},
  135. {EPADR_HW2SW(EPF), USB_EP_ATTR_BULK, USB_DIR_OUT, EPF_MAX_PKT_SIZE, ID_UNASSIGNED},
  136. {EPADR_HW2SW(EPG), USB_EP_ATTR_INT, USB_DIR_IN, EPG_MAX_PKT_SIZE, ID_UNASSIGNED},
  137. {EPADR_HW2SW(EPH), USB_EP_ATTR_INT, USB_DIR_OUT, EPH_MAX_PKT_SIZE, ID_UNASSIGNED},
  138. {EPADR_HW2SW(EPI), USB_EP_ATTR_BULK, USB_DIR_IN, EPE_MAX_PKT_SIZE, ID_UNASSIGNED},
  139. {EPADR_HW2SW(EPJ), USB_EP_ATTR_BULK, USB_DIR_OUT, EPF_MAX_PKT_SIZE, ID_UNASSIGNED},
  140. {EPADR_HW2SW(EPK), USB_EP_ATTR_INT, USB_DIR_IN, EPG_MAX_PKT_SIZE, ID_UNASSIGNED},
  141. {EPADR_HW2SW(EPL), USB_EP_ATTR_INT, USB_DIR_OUT, EPH_MAX_PKT_SIZE, ID_UNASSIGNED},
  142. {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
  143. };
  144. static void _nu_ep_partition_set(int isHighSpeed)
  145. {
  146. int i;
  147. for (i = 0; i < USBD_MAX_EP; i++)
  148. {
  149. uint32_t u32NuEPTypeDef = 0x0;
  150. uint32_t u32NuEPDirDef = 0x0;
  151. if (_ep_pool[i + 1].type == USB_EP_ATTR_BULK)
  152. u32NuEPTypeDef = USB_EP_CFG_TYPE_BULK;
  153. else if (_ep_pool[i + 1].type == USB_EP_ATTR_INT)
  154. u32NuEPTypeDef = USB_EP_CFG_TYPE_INT;
  155. else
  156. continue;
  157. if (_ep_pool[i + 1].dir == USB_DIR_IN)
  158. u32NuEPDirDef = USB_EP_CFG_DIR_IN;
  159. else if (_ep_pool[i + 1].dir == USB_DIR_OUT)
  160. u32NuEPDirDef = USB_EP_CFG_DIR_OUT;
  161. else
  162. continue;
  163. USBD_SetEpBufAddr(i, _ep_cxt_pool[i].u32BufferBase, _ep_cxt_pool[i].u32BufferLength);
  164. if (isHighSpeed)
  165. USBD_SET_MAX_PAYLOAD(i, _ep_cxt_pool[i].u32BufferLength);
  166. else
  167. USBD_SET_MAX_PAYLOAD(i, _ep_cxt_pool[i].u32OtherMaxPktSize);
  168. USBD_ConfigEp(i, EPADR_HW2SW(i), u32NuEPTypeDef, u32NuEPDirDef);
  169. if (u32NuEPDirDef == USB_EP_CFG_DIR_OUT)
  170. USBD_ENABLE_EP_INT(i, USBD_EPINTEN_RXPKIEN_Msk);
  171. } //for
  172. }
  173. static void _nu_ep_partition(void)
  174. {
  175. /* Configure USB controller */
  176. /* Enable USB BUS, CEP and EPA ~ EPH global interrupt */
  177. USBD_ENABLE_USB_INT(USBD_GINTEN_USBIE_Msk
  178. | USBD_GINTEN_CEPIE_Msk
  179. | USBD_GINTEN_EPAIE_Msk
  180. | USBD_GINTEN_EPBIE_Msk
  181. | USBD_GINTEN_EPCIE_Msk
  182. | USBD_GINTEN_EPDIE_Msk
  183. | USBD_GINTEN_EPEIE_Msk
  184. | USBD_GINTEN_EPFIE_Msk
  185. | USBD_GINTEN_EPGIE_Msk
  186. | USBD_GINTEN_EPHIE_Msk
  187. | USBD_GINTEN_EPIIE_Msk
  188. | USBD_GINTEN_EPJIE_Msk
  189. | USBD_GINTEN_EPKIE_Msk
  190. | USBD_GINTEN_EPLIE_Msk);
  191. /* Enable BUS interrupt */
  192. USBD_ENABLE_BUS_INT(USBD_BUSINTEN_DMADONEIEN_Msk
  193. | USBD_BUSINTEN_RESUMEIEN_Msk
  194. | USBD_BUSINTEN_RSTIEN_Msk
  195. | USBD_BUSINTEN_VBUSDETIEN_Msk);
  196. /* Reset Address to 0 */
  197. USBD_SET_ADDR(0);
  198. /*****************************************************/
  199. /* Control endpoint */
  200. USBD_SetEpBufAddr(CEP, CEP_BUF_BASE, CEP_BUF_LEN);
  201. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk
  202. | USBD_CEPINTEN_STSDONEIEN_Msk);
  203. _nu_ep_partition_set(1);
  204. }
  205. static void NU_SetupStageCallback(nu_usbd_t *nu_udc)
  206. {
  207. struct urequest setup_packet;
  208. /* Setup packet process */
  209. setup_packet.request_type = (uint8_t)(nu_udc->base->SETUP1_0 & 0xfful);
  210. setup_packet.bRequest = (uint8_t)((nu_udc->base->SETUP1_0 >> 8) & 0xfful);
  211. setup_packet.wValue = (uint16_t) nu_udc->base->SETUP3_2;
  212. setup_packet.wIndex = (uint16_t) nu_udc->base->SETUP5_4;
  213. setup_packet.wLength = (uint16_t) nu_udc->base->SETUP7_6;
  214. rt_usbd_ep0_setup_handler(&_rt_obj_udc, (struct urequest *)&setup_packet);
  215. }
  216. __STATIC_INLINE void nu_udc_enable(void)
  217. {
  218. USBD_ENABLE_USB();
  219. }
  220. __STATIC_INLINE void nu_udc_disable(void)
  221. {
  222. int i;
  223. USBD_ENABLE_CEP_INT(0);
  224. USBD_CLR_CEP_INT_FLAG(0xffff);
  225. USBD_SET_CEP_STATE(inpw(REG_USBD_CEPCTL) | USB_CEPCTL_FLUSH);
  226. for (i = 0; i < USBD_MAX_EP; i++)
  227. USBD->EP[i].EPRSPCTL = USB_EP_RSPCTL_FLUSH | USB_EP_RSPCTL_TOGGLE;
  228. USBD_DISABLE_USB();
  229. }
  230. static rt_err_t _ep_set_stall(rt_uint8_t address)
  231. {
  232. if (address & USB_EPNO_MASK)
  233. {
  234. USBD_SetEpStall(EPADR_SW2HW(address));
  235. }
  236. else
  237. {
  238. /* Not support. Reply STALL. */
  239. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  240. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPPKIF_Msk);
  241. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
  242. }
  243. return RT_EOK;
  244. }
  245. static rt_err_t _ep_clear_stall(rt_uint8_t address)
  246. {
  247. if (address & USB_EPNO_MASK)
  248. {
  249. USBD_ClearEpStall(EPADR_SW2HW(address));
  250. }
  251. return RT_EOK;
  252. }
  253. static rt_err_t _set_address(rt_uint8_t address)
  254. {
  255. if (0 != address)
  256. {
  257. nu_usbd.address_tmp = address;
  258. }
  259. return RT_EOK;
  260. }
  261. static rt_err_t _set_config(rt_uint8_t address)
  262. {
  263. return RT_EOK;
  264. }
  265. static rt_err_t _ep_enable(uep_t ep)
  266. {
  267. RT_ASSERT(ep != RT_NULL);
  268. RT_ASSERT(ep->ep_desc != RT_NULL);
  269. USBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPRSPCTL = USB_EP_RSPCTL_TOGGLE;
  270. USBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPCFG |= USB_EP_CFG_VALID;
  271. return RT_EOK;
  272. }
  273. static rt_err_t _ep_disable(uep_t ep)
  274. {
  275. RT_ASSERT(ep != RT_NULL);
  276. RT_ASSERT(ep->ep_desc != RT_NULL);
  277. USBD->EP[EPADR_SW2HW(ep->ep_desc->bEndpointAddress)].EPCFG &= ~USB_EP_CFG_VALID;
  278. return RT_EOK;
  279. }
  280. static rt_err_t _ep0_send_status(void)
  281. {
  282. /* Status Stage */
  283. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk
  284. | USBD_CEPINTSTS_SETUPPKIF_Msk);
  285. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  286. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  287. return RT_EOK;
  288. }
  289. __STATIC_INLINE void nu_buffer_cpy(rt_uint8_t address, void *buffer, rt_size_t size)
  290. {
  291. rt_uint32_t i, cnt;
  292. rt_uint32_t *_buf_word;
  293. rt_uint8_t *_buf_byte;
  294. _buf_word = (rt_uint32_t *)buffer;
  295. cnt = size >> 2;
  296. _buf_byte = (rt_uint8_t *)((rt_uint8_t *)buffer + (cnt * 4));
  297. if ((address & USB_EPNO_MASK)) //EPs
  298. {
  299. if (address & USB_DIR_IN) //IN
  300. {
  301. /* Non-control endpoint IN*/
  302. for (i = 0; i < cnt; i++)
  303. {
  304. USBD->EP[EPADR_SW2HW(address)].ep.EPDAT = _buf_word[i];
  305. }
  306. for (i = 0ul; i < (size % 4ul); i++)
  307. USBD->EP[EPADR_SW2HW(address)].ep.EPDAT_BYTE = _buf_byte[i];
  308. }
  309. else //OUT
  310. {
  311. for (i = 0; i < cnt; i++)
  312. {
  313. _buf_word[i] = USBD->EP[EPADR_SW2HW(address)].ep.EPDAT;
  314. }
  315. for (i = 0ul; i < (size % 4ul); i++)
  316. _buf_byte[i] = USBD->EP[EPADR_SW2HW(address)].ep.EPDAT_BYTE;
  317. }
  318. }
  319. else //Control
  320. {
  321. if (address & USB_DIR_IN) //IN
  322. {
  323. for (i = 0; i < cnt; i++)
  324. {
  325. USBD->cep.CEPDAT = _buf_word[i];
  326. }
  327. for (i = 0ul; i < (size % 4ul); i++)
  328. USBD->cep.CEPDAT_BYTE = _buf_byte[i];
  329. }
  330. else //OUT
  331. {
  332. for (i = 0; i < cnt; i++)
  333. {
  334. _buf_word[i] = USBD->cep.CEPDAT;
  335. }
  336. for (i = 0ul; i < (size % 4ul); i++)
  337. _buf_byte[i] = USBD->cep.CEPDAT_BYTE;
  338. }
  339. }
  340. }
  341. static rt_size_t _ep_read(rt_uint8_t address, void *buffer)
  342. {
  343. rt_size_t size = 0;
  344. RT_ASSERT(!(address & USB_DIR_IN));
  345. if ((address & USB_EPNO_MASK))
  346. {
  347. RT_ASSERT(buffer != RT_NULL);
  348. size = USBD->EP[EPADR_SW2HW(address)].EPDATCNT & 0xffff;
  349. nu_buffer_cpy(address, buffer, size);
  350. }
  351. else //control transfer
  352. {
  353. size = USBD->CEPRXCNT & 0xffff;
  354. if (size)
  355. {
  356. RT_ASSERT(_rt_obj_udc.stage == STAGE_DOUT);
  357. nu_buffer_cpy(address, buffer, size);
  358. }
  359. _ep0_send_status();
  360. }
  361. return size;
  362. }
  363. static rt_size_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
  364. {
  365. RT_ASSERT(!(address & USB_DIR_IN));
  366. if ((address & USB_EPNO_MASK))
  367. {
  368. USBD_ENABLE_EP_INT(EPADR_SW2HW(address),
  369. USBD_EPINTEN_RXPKIEN_Msk);
  370. }
  371. else //control transfer
  372. {
  373. if (size)
  374. {
  375. RT_ASSERT(_rt_obj_udc.stage == STAGE_DOUT);
  376. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_OUTTKIEN_Msk);
  377. }
  378. else
  379. {
  380. RT_ASSERT(_rt_obj_udc.stage == STAGE_STATUS_OUT);
  381. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPPKIF_Msk
  382. | USBD_CEPINTSTS_STSDONEIF_Msk);
  383. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk
  384. | USBD_CEPINTEN_STSDONEIEN_Msk);
  385. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  386. }
  387. }
  388. return size;
  389. }
  390. static rt_size_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
  391. {
  392. RT_ASSERT((address & USB_DIR_IN));
  393. if (!(address & USB_EPNO_MASK)) //control transfer
  394. {
  395. if (size)
  396. {
  397. nu_buffer_cpy(address, buffer, size);
  398. USBD_START_CEP_IN(size);
  399. }
  400. else//zero length
  401. {
  402. USBD_SET_CEP_STATE(USB_CEPCTL_ZEROLEN);
  403. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk
  404. | USBD_CEPINTSTS_SETUPPKIF_Msk);
  405. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk
  406. | USBD_CEPINTEN_STSDONEIEN_Msk);
  407. }
  408. if (_rt_obj_udc.stage == STAGE_DIN)
  409. {
  410. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_TXPKIF_Msk);
  411. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_TXPKIEN_Msk);
  412. }
  413. else if (_rt_obj_udc.stage == STAGE_DOUT)
  414. {
  415. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_RXPKIF_Msk);
  416. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_RXPKIEN_Msk);
  417. }
  418. }
  419. else
  420. {
  421. /* Non-control endpoint IN*/
  422. nu_buffer_cpy(address, buffer, size);
  423. USBD->EP[EPADR_SW2HW(address)].EPRSPCTL = USB_EP_RSPCTL_SHORTTXEN; // packet end
  424. USBD->EP[EPADR_SW2HW(address)].EPTXCNT = size;
  425. if ((USBD->EP[EPADR_SW2HW(address)].EPCFG & USBD_EPCFG_EPTYPE_Msk) == USB_EP_CFG_TYPE_INT)
  426. {
  427. USBD_ENABLE_EP_INT(EPADR_SW2HW(address), USBD_EPINTEN_INTKIEN_Msk); //for interrupt transfer timing
  428. }
  429. else
  430. {
  431. USBD_ENABLE_EP_INT(EPADR_SW2HW(address), USBD_EPINTEN_TXPKIEN_Msk); //for bulk transfer timing
  432. }
  433. }
  434. return size;
  435. }
  436. static rt_err_t _suspend(void)
  437. {
  438. return RT_EOK;
  439. }
  440. static rt_err_t _wakeup(void)
  441. {
  442. return RT_EOK;
  443. }
  444. static void nu_usbd_isr(int vector, void *param)
  445. {
  446. __IO rt_uint32_t IrqStL, IrqSt;
  447. int i;
  448. int IrqStAllEP;
  449. /* Igrone event if role is USBH*/
  450. if (nu_sys_usb0_role() != USB0_ID_DEVICE) return;
  451. IrqStL = USBD->GINTSTS & USBD->GINTEN; /* get interrupt status */
  452. if (!IrqStL) return;
  453. /* USB interrupt */
  454. if (IrqStL & USBD_GINTSTS_USBIF_Msk)
  455. {
  456. IrqSt = USBD->BUSINTSTS & USBD->BUSINTEN;
  457. if (IrqSt & USBD_BUSINTSTS_SOFIF_Msk)
  458. {
  459. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_SOFIF_Msk);
  460. rt_usbd_sof_handler(&_rt_obj_udc);
  461. }
  462. if (IrqSt & USBD_BUSINTSTS_RSTIF_Msk)
  463. {
  464. /* Reset USB device address */
  465. USBD_SET_ADDR(0ul);
  466. USBD_ResetDMA();
  467. for (i = 0; i < USBD_MAX_EP; i++)
  468. USBD->EP[i].EPRSPCTL = USBD_EPRSPCTL_FLUSH_Msk;
  469. if (USBD->OPER & 0x04) /* high speed */
  470. {
  471. LOG_I("-High Speed-");
  472. _nu_ep_partition_set(1);
  473. }
  474. else /* full speed */
  475. {
  476. LOG_I("-Full Speed-");
  477. _nu_ep_partition_set(0);
  478. }
  479. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
  480. USBD_ENABLE_BUS_INT(USBD_BUSINTEN_RSTIEN_Msk
  481. | USBD_BUSINTEN_RESUMEIEN_Msk
  482. | USBD_BUSINTEN_SUSPENDIEN_Msk
  483. | USBD_BUSINTEN_VBUSDETIEN_Msk);
  484. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_RSTIF_Msk);
  485. USBD_CLR_CEP_INT_FLAG(0x1ffc);
  486. for (i = 0ul; i < USBD_MAX_EP; i++)
  487. {
  488. if ((USBD->EP[i].EPCFG & 0x1ul) == 0x1ul)
  489. {
  490. USBD->EP[i].EPRSPCTL = USB_EP_RSPCTL_TOGGLE;
  491. }
  492. }
  493. rt_usbd_reset_handler(&_rt_obj_udc);
  494. USBD_ENABLE_USB();
  495. }
  496. if (IrqSt & USBD_BUSINTSTS_RESUMEIF_Msk)
  497. {
  498. LOG_I("-Resume-");
  499. USBD_ENABLE_BUS_INT(USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk);
  500. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_RESUMEIF_Msk);
  501. }
  502. if (IrqSt & USBD_BUSINTSTS_SUSPENDIF_Msk)
  503. {
  504. LOG_I("-Suspend-");
  505. USBD_ENABLE_BUS_INT(USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_VBUSDETIEN_Msk);
  506. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_SUSPENDIF_Msk);
  507. }
  508. if (IrqSt & USBD_BUSINTSTS_HISPDIF_Msk)
  509. {
  510. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
  511. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_HISPDIF_Msk);
  512. }
  513. if (IrqSt & USBD_BUSINTSTS_DMADONEIF_Msk)
  514. {
  515. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_DMADONEIF_Msk);
  516. if (!(USBD->DMACTL & USBD_DMACTL_DMARD_Msk))
  517. {
  518. USBD_ENABLE_EP_INT(EPD, USBD_EPINTEN_RXPKIEN_Msk);
  519. }
  520. }
  521. if (IrqSt & USBD_BUSINTSTS_PHYCLKVLDIF_Msk)
  522. {
  523. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_PHYCLKVLDIF_Msk);
  524. }
  525. if (IrqSt & USBD_BUSINTSTS_VBUSDETIF_Msk)
  526. {
  527. if (USBD_IS_ATTACHED())
  528. {
  529. if (!nu_usbd.plugging_status)
  530. {
  531. LOG_I("PLUG IN");
  532. /* USB Plug In */
  533. nu_udc_enable();
  534. rt_usbd_connect_handler(&_rt_obj_udc);
  535. nu_usbd.plugging_status = 1;
  536. }
  537. }
  538. else
  539. {
  540. if (nu_usbd.plugging_status)
  541. {
  542. LOG_I("Un-Plug");
  543. /* USB Un-plug */
  544. nu_udc_disable();
  545. rt_usbd_disconnect_handler(&_rt_obj_udc);
  546. nu_usbd.plugging_status = 0;
  547. }
  548. }
  549. USBD_CLR_BUS_INT_FLAG(USBD_BUSINTSTS_VBUSDETIF_Msk);
  550. }
  551. } //if (IrqStL & USBD_GINTSTS_USBIF_Msk)
  552. /* Control Transfer */
  553. if (IrqStL & USBD_GINTSTS_CEPIF_Msk)
  554. {
  555. IrqSt = USBD->CEPINTSTS & USBD->CEPINTEN;
  556. if (IrqSt & USBD_CEPINTSTS_SETUPTKIF_Msk)
  557. {
  558. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPTKIF_Msk);
  559. return;
  560. }
  561. if (IrqSt & USBD_CEPINTSTS_SETUPPKIF_Msk)
  562. {
  563. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPPKIF_Msk);
  564. NU_SetupStageCallback(&nu_usbd);
  565. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk
  566. | USBD_CEPINTSTS_RXPKIF_Msk
  567. | USBD_CEPINTSTS_STSDONEIF_Msk);
  568. return;
  569. }
  570. if (IrqSt & USBD_CEPINTSTS_OUTTKIF_Msk)
  571. {
  572. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_OUTTKIF_Msk);
  573. rt_usbd_ep0_out_handler(&_rt_obj_udc, 0);
  574. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_RXPKIEN_Msk);
  575. return;
  576. }
  577. if (IrqSt & USBD_CEPINTSTS_INTKIF_Msk)
  578. {
  579. USBD_ENABLE_CEP_INT(0);
  580. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
  581. rt_usbd_ep0_in_handler(&_rt_obj_udc);
  582. return;
  583. }
  584. if (IrqSt & USBD_CEPINTSTS_PINGIF_Msk)
  585. {
  586. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_PINGIF_Msk);
  587. return;
  588. }
  589. if (IrqSt & USBD_CEPINTSTS_TXPKIF_Msk)
  590. {
  591. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_TXPKIF_Msk
  592. | USBD_CEPINTSTS_SETUPPKIF_Msk
  593. | USBD_CEPINTSTS_STSDONEIF_Msk);
  594. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk
  595. | USBD_CEPINTEN_SETUPPKIEN_Msk
  596. | USBD_CEPINTEN_STSDONEIEN_Msk);
  597. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  598. return;
  599. }
  600. if (IrqSt & USBD_CEPINTSTS_RXPKIF_Msk)
  601. {
  602. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_SETUPPKIF_Msk
  603. | USBD_CEPINTSTS_STSDONEIF_Msk
  604. | USBD_CEPINTSTS_RXPKIF_Msk);
  605. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  606. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk
  607. | USBD_CEPINTEN_STSDONEIEN_Msk
  608. | USBD_CEPINTEN_RXPKIEN_Msk);
  609. return;
  610. }
  611. if (IrqSt & USBD_CEPINTSTS_NAKIF_Msk)
  612. {
  613. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_NAKIF_Msk);
  614. return;
  615. }
  616. if (IrqSt & USBD_CEPINTSTS_STALLIF_Msk)
  617. {
  618. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STALLIF_Msk);
  619. return;
  620. }
  621. if (IrqSt & USBD_CEPINTSTS_ERRIF_Msk)
  622. {
  623. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_ERRIF_Msk);
  624. return;
  625. }
  626. if (IrqSt & USBD_CEPINTSTS_STSDONEIF_Msk)
  627. {
  628. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk | USBD_CEPINTSTS_SETUPPKIF_Msk);
  629. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_SETUPPKIEN_Msk);
  630. if ((USBD_GET_ADDR() == 0)
  631. && ((uint8_t)((nu_usbd.base->SETUP1_0 >> 8) & 0xfful) == SET_ADDRESS))
  632. {
  633. USBD_SET_ADDR(nu_usbd.address_tmp);
  634. LOG_I("SET ADDR: 0x%02x", nu_usbd.address_tmp);
  635. nu_usbd.address_tmp = 0;
  636. }
  637. return;
  638. }
  639. if (IrqSt & USBD_CEPINTSTS_BUFFULLIF_Msk)
  640. {
  641. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_BUFFULLIF_Msk);
  642. return;
  643. }
  644. if (IrqSt & USBD_CEPINTSTS_BUFEMPTYIF_Msk)
  645. {
  646. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_BUFEMPTYIF_Msk);
  647. return;
  648. }
  649. } //if (IrqStL & USBD_GINTSTS_CEPIF_Msk)
  650. // For End-points
  651. IrqStAllEP = (IrqStL >> USBD_GINTSTS_EPAIF_Pos) & ((1 << USBD_MAX_EP) - 1);
  652. // Find the position of first '1' in allch_sts.
  653. while ((i = nu_ctz(IrqStAllEP)) != 32)
  654. {
  655. IrqSt = USBD->EP[i].EPINTSTS & USBD->EP[i].EPINTEN;
  656. if (_ep_pool[i + 1].dir == USB_DIR_IN)
  657. USBD_ENABLE_EP_INT(i, 0);
  658. USBD_CLR_EP_INT_FLAG(i, IrqSt);
  659. rt_usbd_ep_in_handler(&_rt_obj_udc, _ep_pool[i + 1].dir | EPADR_HW2SW(i), 0);
  660. IrqStAllEP &= ~(1 << i);
  661. }
  662. }
  663. static rt_err_t _init(rt_device_t device)
  664. {
  665. nu_sys_ipclk_enable(nu_usbd.clkidx);
  666. nu_sys_ip_reset(nu_usbd.rstidx);
  667. rt_hw_us_delay(1000);
  668. /* USBD Open */
  669. USBD_ENABLE_USB();
  670. while (1)
  671. {
  672. USBD->EP[EPA].EPMPS = 0x20ul;
  673. if (USBD->EP[EPA].EPMPS == 0x20ul)
  674. {
  675. break;
  676. }
  677. }
  678. /* Force SE0 */
  679. USBD_SET_SE0();
  680. _nu_ep_partition();
  681. #if ENABLE_FULL_SPEED_MODE_ONLY
  682. USBD->OPER &= ~USBD_OPER_HISPDEN_Msk;
  683. #else
  684. USBD->OPER |= USBD_OPER_HISPDEN_Msk;
  685. #endif
  686. /* Install USBD interrupt */
  687. rt_hw_interrupt_install(nu_usbd.irqn, nu_usbd_isr, &nu_usbd, nu_usbd.name);
  688. rt_hw_interrupt_set_priority(nu_usbd.irqn, IRQ_LEVEL_1);
  689. /* Enable USBD interrupt */
  690. rt_hw_interrupt_umask(nu_usbd.irqn);
  691. /* Start transaction */
  692. USBD_CLR_SE0();
  693. /* Get currect cable status */
  694. nu_usbd.plugging_status = USBD_IS_ATTACHED() >> USBD_PHYCTL_VBUSDET_Pos;
  695. return RT_EOK;
  696. }
  697. const static struct udcd_ops _udc_ops =
  698. {
  699. _set_address,
  700. _set_config,
  701. _ep_set_stall,
  702. _ep_clear_stall,
  703. _ep_enable,
  704. _ep_disable,
  705. _ep_read_prepare,
  706. _ep_read,
  707. _ep_write,
  708. _ep0_send_status,
  709. _suspend,
  710. _wakeup,
  711. };
  712. #ifdef RT_USING_DEVICE_OPS
  713. const static struct rt_device_ops _ops =
  714. {
  715. _init,
  716. RT_NULL,
  717. RT_NULL,
  718. RT_NULL,
  719. RT_NULL,
  720. RT_NULL,
  721. };
  722. #endif
  723. int nu_usbd_register(void)
  724. {
  725. rt_err_t result = RT_EOK;
  726. rt_memset((void *)&_rt_obj_udc, 0, sizeof(struct udcd));
  727. _rt_obj_udc.parent.type = RT_Device_Class_USBDevice;
  728. #ifdef RT_USING_DEVICE_OPS
  729. _rt_obj_udc.parent.ops = &_ops;
  730. #else
  731. _rt_obj_udc.parent.init = _init;
  732. #endif
  733. _rt_obj_udc.parent.user_data = &nu_usbd;
  734. _rt_obj_udc.ops = &_udc_ops;
  735. /* Register endpoint information */
  736. _rt_obj_udc.ep_pool = _ep_pool;
  737. _rt_obj_udc.ep0.id = &_ep_pool[0];
  738. #if ENABLE_FULL_SPEED_MODE_ONLY
  739. _rt_obj_udc.device_is_hs = RT_FALSE; /* Enable Full-speed only */
  740. #else
  741. _rt_obj_udc.device_is_hs = RT_TRUE; /* Support Hi-Speed */
  742. #endif
  743. result = rt_device_register((rt_device_t)&_rt_obj_udc, nu_usbd.name, 0);
  744. RT_ASSERT(result == RT_EOK);
  745. return rt_usb_device_init();
  746. }
  747. INIT_DEVICE_EXPORT(nu_usbd_register);
  748. #endif