nu_usbd.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /**************************************************************************//**
  2. * @file usbd.c
  3. * @brief N9H30 USBD driver source file
  4. *
  5. * @note
  6. * SPDX-License-Identifier: Apache-2.0
  7. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  8. *****************************************************************************/
  9. #include "N9H30.h"
  10. #include "nu_usbd.h"
  11. /** @addtogroup N9H30_Device_Driver N9H30 Device Driver
  12. @{
  13. */
  14. /** @addtogroup N9H30_USBD_Driver USBD Driver
  15. @{
  16. */
  17. /** @addtogroup N9H30_USBD_EXPORTED_FUNCTIONS USBD Exported Functions
  18. @{
  19. */
  20. /*--------------------------------------------------------------------------*/
  21. /// @cond HIDDEN_SYMBOLS
  22. /*!< Global variables for Control Pipe */
  23. S_USBD_CMD_T gUsbCmd;
  24. S_USBD_INFO_T *g_usbd_sInfo;
  25. VENDOR_REQ g_usbd_pfnVendorRequest = 0;
  26. CLASS_REQ g_usbd_pfnClassRequest = 0;
  27. SET_INTERFACE_REQ g_usbd_pfnSetInterface = 0;
  28. uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */
  29. static uint8_t *g_usbd_CtrlInPointer = 0;
  30. static uint32_t g_usbd_CtrlMaxPktSize = 64;
  31. static uint8_t g_usbd_UsbConfig = 0;
  32. static uint8_t g_usbd_UsbAltInterface = 0;
  33. static uint8_t g_usbd_EnableTestMode = 0;
  34. static uint8_t g_usbd_TestSelector = 0;
  35. #ifdef __ICCARM__
  36. #pragma data_alignment=4
  37. static uint8_t g_usbd_buf[12];
  38. #else
  39. static uint8_t g_usbd_buf[12] __attribute__((aligned(4)));
  40. #endif
  41. uint8_t volatile g_usbd_Configured = 0;
  42. uint8_t g_usbd_CtrlZero = 0;
  43. uint8_t g_usbd_UsbAddr = 0;
  44. uint8_t g_usbd_ShortPacket = 0;
  45. uint32_t volatile g_usbd_DmaDone = 0;
  46. uint32_t g_usbd_CtrlInSize = 0;
  47. /// @endcond HIDDEN_SYMBOLS
  48. /**
  49. * @brief USBD Initial
  50. *
  51. * @param[in] param Descriptor
  52. * @param[in] pfnClassReq Class Request Callback Function
  53. * @param[in] pfnSetInterface SetInterface Request Callback Function
  54. *
  55. * @return None
  56. *
  57. * @details This function is used to initial USBD.
  58. */
  59. void USBD_Open(S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
  60. {
  61. /* Select Vbus detect pin -> GPH0 */
  62. outpw(REG_SYS_GPH_MFPL, (inpw(REG_SYS_GPH_MFPL) & ~0xf) | 0x7);
  63. /* Enable USB device clock */
  64. outpw(REG_CLK_HCLKEN, inpw(REG_CLK_HCLKEN) | 0x80000);
  65. g_usbd_sInfo = param;
  66. g_usbd_pfnClassRequest = pfnClassReq;
  67. g_usbd_pfnSetInterface = pfnSetInterface;
  68. /* get EP0 maximum packet size */
  69. g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
  70. /* Initial USB engine */
  71. /* Enable PHY */
  72. USBD_ENABLE_PHY();
  73. /* wait PHY clock ready */
  74. while (1)
  75. {
  76. USBD->EP[EPA].EPMPS = 0x20;
  77. if (USBD->EP[EPA].EPMPS == 0x20)
  78. break;
  79. }
  80. /* Force SE0, and then clear it to connect*/
  81. USBD_SET_SE0();
  82. }
  83. /**
  84. * @brief USBD Start
  85. *
  86. * @return None
  87. *
  88. * @details This function is used to start transfer
  89. */
  90. void USBD_Start(void)
  91. {
  92. USBD_CLR_SE0();
  93. }
  94. /**
  95. * @brief Process Setup Packet
  96. *
  97. * @return None
  98. *
  99. * @details This function is used to process Setup packet.
  100. */
  101. void USBD_ProcessSetupPacket(void)
  102. {
  103. // Setup packet process
  104. gUsbCmd.bmRequestType = (uint8_t)(USBD->SETUP1_0 & 0xff);
  105. gUsbCmd.bRequest = (int8_t)(USBD->SETUP1_0 >> 8) & 0xff;
  106. gUsbCmd.wValue = (uint16_t)USBD->SETUP3_2;
  107. gUsbCmd.wIndex = (uint16_t)USBD->SETUP5_4;
  108. gUsbCmd.wLength = (uint16_t)USBD->SETUP7_6;
  109. /* USB device request in setup packet: offset 0, D[6..5]: 0=Standard, 1=Class, 2=Vendor, 3=Reserved */
  110. switch (gUsbCmd.bmRequestType & 0x60)
  111. {
  112. case REQ_STANDARD: // Standard
  113. {
  114. USBD_StandardRequest();
  115. break;
  116. }
  117. case REQ_CLASS: // Class
  118. {
  119. if (g_usbd_pfnClassRequest != NULL)
  120. {
  121. g_usbd_pfnClassRequest();
  122. }
  123. break;
  124. }
  125. case REQ_VENDOR: // Vendor
  126. {
  127. if (g_usbd_pfnVendorRequest != NULL)
  128. {
  129. g_usbd_pfnVendorRequest();
  130. }
  131. break;
  132. }
  133. default: // reserved
  134. {
  135. /* Setup error, stall the device */
  136. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  137. break;
  138. }
  139. }
  140. }
  141. /**
  142. * @brief Get Descriptor request
  143. *
  144. * @return None
  145. *
  146. * @details This function is used to process GetDescriptor request.
  147. */
  148. int USBD_GetDescriptor(void)
  149. {
  150. uint32_t u32Len;
  151. u32Len = gUsbCmd.wLength;
  152. g_usbd_CtrlZero = 0;
  153. switch ((gUsbCmd.wValue & 0xff00) >> 8)
  154. {
  155. // Get Device Descriptor
  156. case DESC_DEVICE:
  157. {
  158. u32Len = Minimum(u32Len, LEN_DEVICE);
  159. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len);
  160. break;
  161. }
  162. // Get Configuration Descriptor
  163. case DESC_CONFIG:
  164. {
  165. uint32_t u32TotalLen;
  166. u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3];
  167. u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8);
  168. u32Len = Minimum(u32Len, u32TotalLen);
  169. if ((u32Len % g_usbd_CtrlMaxPktSize) == 0)
  170. g_usbd_CtrlZero = 1;
  171. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len);
  172. break;
  173. }
  174. // Get Qualifier Descriptor
  175. case DESC_QUALIFIER:
  176. {
  177. u32Len = Minimum(u32Len, LEN_QUALIFIER);
  178. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8QualDesc, u32Len);
  179. break;
  180. }
  181. // Get Other Speed Descriptor - Full speed
  182. case DESC_OTHERSPEED:
  183. {
  184. uint32_t u32TotalLen;
  185. u32TotalLen = g_usbd_sInfo->gu8OtherConfigDesc[3];
  186. u32TotalLen = g_usbd_sInfo->gu8OtherConfigDesc[2] + (u32TotalLen << 8);
  187. u32Len = Minimum(u32Len, u32TotalLen);
  188. if ((u32Len % g_usbd_CtrlMaxPktSize) == 0)
  189. g_usbd_CtrlZero = 1;
  190. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8OtherConfigDesc, u32Len);
  191. break;
  192. }
  193. // Get HID Descriptor
  194. case DESC_HID:
  195. {
  196. u32Len = Minimum(u32Len, LEN_HID);
  197. USBD_MemCopy(g_usbd_buf, (uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[LEN_CONFIG + LEN_INTERFACE], u32Len);
  198. USBD_PrepareCtrlIn(g_usbd_buf, u32Len);
  199. break;
  200. }
  201. // Get Report Descriptor
  202. case DESC_HID_RPT:
  203. {
  204. if ((u32Len % g_usbd_CtrlMaxPktSize) == 0)
  205. g_usbd_CtrlZero = 1;
  206. u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[gUsbCmd.wIndex & 0xff]);
  207. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[gUsbCmd.wIndex & 0xff], u32Len);
  208. break;
  209. }
  210. // Get String Descriptor
  211. case DESC_STRING:
  212. {
  213. // Get String Descriptor
  214. if ((gUsbCmd.wValue & 0xff) < 4)
  215. {
  216. u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[gUsbCmd.wValue & 0xff][0]);
  217. if ((u32Len % g_usbd_CtrlMaxPktSize) == 0)
  218. g_usbd_CtrlZero = 1;
  219. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[gUsbCmd.wValue & 0xff], u32Len);
  220. }
  221. else
  222. {
  223. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  224. return 1;
  225. }
  226. break;
  227. }
  228. default:
  229. // Not support. Reply STALL.
  230. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  231. return 1;
  232. }
  233. return 0;
  234. }
  235. /**
  236. * @brief Process USB standard request
  237. *
  238. * @return None
  239. *
  240. * @details This function is used to process USB Standard Request.
  241. */
  242. void USBD_StandardRequest(void)
  243. {
  244. /* clear global variables for new request */
  245. g_usbd_CtrlInPointer = 0;
  246. g_usbd_CtrlInSize = 0;
  247. if (gUsbCmd.bmRequestType & 0x80) /* request data transfer direction */
  248. {
  249. // Device to host
  250. switch (gUsbCmd.bRequest)
  251. {
  252. case GET_CONFIGURATION:
  253. {
  254. // Return current configuration setting
  255. USBD_PrepareCtrlIn((uint8_t *)&g_usbd_UsbConfig, 1);
  256. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
  257. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk);
  258. break;
  259. }
  260. case GET_DESCRIPTOR:
  261. {
  262. if (!USBD_GetDescriptor())
  263. {
  264. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
  265. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk);
  266. }
  267. break;
  268. }
  269. case GET_INTERFACE:
  270. {
  271. // Return current interface setting
  272. USBD_PrepareCtrlIn((uint8_t *)&g_usbd_UsbAltInterface, 1);
  273. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
  274. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk);
  275. break;
  276. }
  277. case GET_STATUS:
  278. {
  279. // Device
  280. if (gUsbCmd.bmRequestType == 0x80)
  281. {
  282. if (g_usbd_sInfo->gu8ConfigDesc[7] & 0x40)
  283. g_usbd_buf[0] = 1; // Self-Powered
  284. else
  285. g_usbd_buf[0] = 0; // bus-Powered
  286. }
  287. // Interface
  288. else if (gUsbCmd.bmRequestType == 0x81)
  289. g_usbd_buf[0] = 0;
  290. // Endpoint
  291. else if (gUsbCmd.bmRequestType == 0x82)
  292. {
  293. uint8_t ep = gUsbCmd.wIndex & 0xF;
  294. g_usbd_buf[0] = USBD_GetStall(ep) ? 1 : 0;
  295. }
  296. g_usbd_buf[1] = 0;
  297. USBD_PrepareCtrlIn(g_usbd_buf, 2);
  298. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk);
  299. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk);
  300. break;
  301. }
  302. default:
  303. {
  304. /* Setup error, stall the device */
  305. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  306. break;
  307. }
  308. }
  309. }
  310. else
  311. {
  312. // Host to device
  313. switch (gUsbCmd.bRequest)
  314. {
  315. case CLEAR_FEATURE:
  316. {
  317. if ((gUsbCmd.wValue & 0xff) == FEATURE_ENDPOINT_HALT)
  318. {
  319. int32_t epNum, i;
  320. /* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
  321. a flag: g_u32EpStallLock is added to support it */
  322. epNum = gUsbCmd.wIndex & 0xF;
  323. for (i = 0; i < USBD_MAX_EP; i++)
  324. {
  325. if ((((USBD->EP[i].EPCFG & 0xf0) >> 4) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0))
  326. {
  327. USBD->EP[i].EPRSPCTL = (USBD->EP[i].EPRSPCTL & 0xef) | USB_EP_RSPCTL_TOGGLE;
  328. }
  329. }
  330. }
  331. /* Status stage */
  332. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
  333. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  334. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  335. break;
  336. }
  337. case SET_ADDRESS:
  338. {
  339. g_usbd_UsbAddr = (uint8_t)gUsbCmd.wValue;
  340. // DATA IN for end of setup
  341. /* Status Stage */
  342. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
  343. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  344. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  345. break;
  346. }
  347. case SET_CONFIGURATION:
  348. {
  349. g_usbd_UsbConfig = (uint8_t)gUsbCmd.wValue;
  350. g_usbd_Configured = 1;
  351. // DATA IN for end of setup
  352. /* Status stage */
  353. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
  354. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  355. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  356. break;
  357. }
  358. case SET_FEATURE:
  359. {
  360. if ((gUsbCmd.wValue & 0x3) == 2) /* TEST_MODE*/
  361. {
  362. g_usbd_EnableTestMode = 1;
  363. g_usbd_TestSelector = gUsbCmd.wIndex >> 8;
  364. }
  365. /* Status stage */
  366. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
  367. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  368. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  369. break;
  370. }
  371. case SET_INTERFACE:
  372. {
  373. g_usbd_UsbAltInterface = (uint8_t)gUsbCmd.wValue;
  374. if (g_usbd_pfnSetInterface != NULL)
  375. g_usbd_pfnSetInterface(g_usbd_UsbAltInterface);
  376. /* Status stage */
  377. USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk);
  378. USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
  379. USBD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk);
  380. break;
  381. }
  382. default:
  383. {
  384. /* Setup error, stall the device */
  385. USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk);
  386. break;
  387. }
  388. }
  389. }
  390. }
  391. #define TEST_J 0x01 /*!< TEST J \hideinitializer */
  392. #define TEST_K 0x02 /*!< TEST K \hideinitializer */
  393. #define TEST_SE0_NAK 0x03 /*!< TEST SE0 \hideinitializer */
  394. #define TEST_PACKET 0x04 /*!< TEST Packet \hideinitializer */
  395. #define TEST_FORCE_ENABLE 0x05 /*!< TEST Force enable \hideinitializer */
  396. /**
  397. * @brief Update Device State
  398. *
  399. * @return None
  400. *
  401. * @details This function is used to update Device state when Setup packet complete
  402. */
  403. void USBD_UpdateDeviceState(void)
  404. {
  405. switch (gUsbCmd.bRequest)
  406. {
  407. case SET_ADDRESS:
  408. {
  409. USBD_SET_ADDR(g_usbd_UsbAddr);
  410. break;
  411. }
  412. case SET_CONFIGURATION:
  413. {
  414. if (g_usbd_UsbConfig == 0)
  415. {
  416. int volatile i;
  417. /* Reset PID DATA0 */
  418. for (i = 0; i < USBD_MAX_EP; i++)
  419. {
  420. if (USBD->EP[i].EPCFG & 0x1)
  421. {
  422. USBD->EP[i].EPRSPCTL = USB_EP_RSPCTL_TOGGLE;
  423. }
  424. }
  425. }
  426. break;
  427. }
  428. case SET_FEATURE:
  429. {
  430. if (gUsbCmd.wValue == FEATURE_ENDPOINT_HALT)
  431. USBD_SetStall(gUsbCmd.wIndex & 0xF);
  432. else if (g_usbd_EnableTestMode)
  433. {
  434. g_usbd_EnableTestMode = 0;
  435. if (g_usbd_TestSelector == TEST_J)
  436. USBD->TEST = TEST_J;
  437. else if (g_usbd_TestSelector == TEST_K)
  438. USBD->TEST = TEST_K;
  439. else if (g_usbd_TestSelector == TEST_SE0_NAK)
  440. USBD->TEST = TEST_SE0_NAK;
  441. else if (g_usbd_TestSelector == TEST_PACKET)
  442. USBD->TEST = TEST_PACKET;
  443. else if (g_usbd_TestSelector == TEST_FORCE_ENABLE)
  444. USBD->TEST = TEST_FORCE_ENABLE;
  445. }
  446. break;
  447. }
  448. case CLEAR_FEATURE:
  449. {
  450. if (gUsbCmd.wValue == FEATURE_ENDPOINT_HALT)
  451. USBD_ClearStall(gUsbCmd.wIndex & 0xF);
  452. break;
  453. }
  454. default:
  455. ;
  456. }
  457. }
  458. /**
  459. * @brief Prepare Control IN transaction
  460. *
  461. * @param[in] pu8Buf Control IN data pointer
  462. * @param[in] u32Size IN transfer size
  463. *
  464. * @return None
  465. *
  466. * @details This function is used to prepare Control IN transfer
  467. */
  468. void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size)
  469. {
  470. g_usbd_CtrlInPointer = pu8Buf;
  471. g_usbd_CtrlInSize = u32Size;
  472. }
  473. /**
  474. * @brief Start Control IN transfer
  475. *
  476. * @return None
  477. *
  478. * @details This function is used to start Control IN
  479. */
  480. void USBD_CtrlIn(void)
  481. {
  482. int volatile i;
  483. uint32_t volatile count;
  484. // Process remained data
  485. if (g_usbd_CtrlInSize >= g_usbd_CtrlMaxPktSize)
  486. {
  487. // Data size > MXPLD
  488. for (i = 0; i < (g_usbd_CtrlMaxPktSize >> 2); i++, g_usbd_CtrlInPointer += 4)
  489. USBD->cep.CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
  490. USBD_START_CEP_IN(g_usbd_CtrlMaxPktSize);
  491. g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
  492. }
  493. else
  494. {
  495. // Data size <= MXPLD
  496. for (i = 0; i < (g_usbd_CtrlInSize >> 2); i++, g_usbd_CtrlInPointer += 4)
  497. USBD->cep.CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
  498. count = g_usbd_CtrlInSize % 4;
  499. for (i = 0; i < count; i++)
  500. USBD->cep.CEPDAT_BYTE = *(uint8_t *)(g_usbd_CtrlInPointer + i);
  501. USBD_START_CEP_IN(g_usbd_CtrlInSize);
  502. g_usbd_CtrlInPointer = 0;
  503. g_usbd_CtrlInSize = 0;
  504. }
  505. }
  506. /**
  507. * @brief Start Control OUT transaction
  508. *
  509. * @param[in] pu8Buf Control OUT data pointer
  510. * @param[in] u32Size OUT transfer size
  511. *
  512. * @return None
  513. *
  514. * @details This function is used to start Control OUT transfer
  515. */
  516. void USBD_CtrlOut(uint8_t *pu8Buf, uint32_t u32Size)
  517. {
  518. int volatile i;
  519. while (1)
  520. {
  521. if (USBD->CEPINTSTS & USBD_CEPINTSTS_RXPKIF_Msk)
  522. {
  523. for (i = 0; i < u32Size; i++)
  524. *(uint8_t *)(pu8Buf + i) = USBD->cep.CEPDAT_BYTE;
  525. USBD->CEPINTSTS = USBD_CEPINTSTS_RXPKIF_Msk;
  526. break;
  527. }
  528. }
  529. }
  530. /**
  531. * @brief Clear all software flags
  532. *
  533. * @return None
  534. *
  535. * @details This function is used to clear all software control flag
  536. */
  537. void USBD_SwReset(void)
  538. {
  539. // Reset all variables for protocol
  540. g_usbd_UsbAddr = 0;
  541. g_usbd_DmaDone = 0;
  542. g_usbd_ShortPacket = 0;
  543. g_usbd_Configured = 0;
  544. // Reset USB device address
  545. USBD_SET_ADDR(0);
  546. }
  547. /**
  548. * @brief USBD Set Vendor Request
  549. *
  550. * @param[in] pfnVendorReq Vendor Request Callback Function
  551. *
  552. * @return None
  553. *
  554. * @details This function is used to set USBD vendor request callback function
  555. */
  556. void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq)
  557. {
  558. g_usbd_pfnVendorRequest = pfnVendorReq;
  559. }
  560. /*@}*/ /* end of group N9H30_USBD_EXPORTED_FUNCTIONS */
  561. /*@}*/ /* end of group N9H30_USBD_Driver */
  562. /*@}*/ /* end of group N9H30_Device_Driver */
  563. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/