nu_usbd.c 19 KB

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