usbd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /**************************************************************************//**
  2. * @file usbd.c
  3. * @version V1.00
  4. * $Revision: 21 $
  5. * $Date: 15/08/21 3:34p $
  6. * @brief M451 series USBD driver source file
  7. *
  8. * @note
  9. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  10. *****************************************************************************/
  11. #include <string.h>
  12. #include "M451Series.h"
  13. #if 0
  14. #define DBG_PRINTF printf
  15. #else
  16. #define DBG_PRINTF(...)
  17. #endif
  18. #ifdef __cplusplus
  19. extern "C"
  20. {
  21. #endif
  22. /** @addtogroup Standard_Driver Standard Driver
  23. @{
  24. */
  25. /** @addtogroup USBD_Driver USBD Driver
  26. @{
  27. */
  28. /** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions
  29. @{
  30. */
  31. /* Global variables for Control Pipe */
  32. uint8_t g_usbd_SetupPacket[8] = {0}; /*!< Setup packet buffer */
  33. volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */
  34. /**
  35. * @cond HIDDEN_SYMBOLS
  36. */
  37. static volatile uint8_t *g_usbd_CtrlInPointer = 0;
  38. static volatile uint32_t g_usbd_CtrlInSize = 0;
  39. static volatile uint8_t *g_usbd_CtrlOutPointer = 0;
  40. static volatile uint32_t g_usbd_CtrlOutSize = 0;
  41. static volatile uint32_t g_usbd_CtrlOutSizeLimit = 0;
  42. static volatile uint32_t g_usbd_UsbAddr = 0;
  43. static volatile uint32_t g_usbd_UsbConfig = 0;
  44. static volatile uint32_t g_usbd_CtrlMaxPktSize = 8;
  45. static volatile uint32_t g_usbd_UsbAltInterface = 0;
  46. /**
  47. * @endcond
  48. */
  49. const S_USBD_INFO_T *g_usbd_sInfo; /*!< A pointer for USB information structure */
  50. VENDOR_REQ g_usbd_pfnVendorRequest = NULL; /*!< USB Vendor Request Functional Pointer */
  51. CLASS_REQ g_usbd_pfnClassRequest = NULL; /*!< USB Class Request Functional Pointer */
  52. SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL; /*!< USB Set Interface Functional Pointer */
  53. SET_CONFIG_CB g_usbd_pfnSetConfigCallback = NULL; /*!< USB Set configuration callback function pointer */
  54. uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */
  55. /**
  56. * @brief This function makes USBD module to be ready to use
  57. *
  58. * @param[in] param The structure of USBD information.
  59. * @param[in] pfnClassReq USB Class request callback function.
  60. * @param[in] pfnSetInterface USB Set Interface request callback function.
  61. *
  62. * @return None
  63. *
  64. * @details This function will enable USB controller, USB PHY transceiver and pull-up resistor of USB_D+ pin. USB PHY will drive SE0 to bus.
  65. */
  66. void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
  67. {
  68. g_usbd_sInfo = param;
  69. g_usbd_pfnClassRequest = pfnClassReq;
  70. g_usbd_pfnSetInterface = pfnSetInterface;
  71. /* get EP0 maximum packet size */
  72. g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
  73. /* Initial USB engine */
  74. USBD->ATTR = 0x7D0;
  75. /* Force SE0 */
  76. USBD_SET_SE0();
  77. }
  78. /**
  79. * @brief This function makes USB host to recognize the device
  80. *
  81. * @param None
  82. *
  83. * @return None
  84. *
  85. * @details Enable WAKEUP, FLDET, USB and BUS interrupts. Disable software-disconnect function after 100ms delay with SysTick timer.
  86. */
  87. void USBD_Start(void)
  88. {
  89. CLK_SysTickDelay(100000);
  90. /* Disable software-disconnect function */
  91. USBD_CLR_SE0();
  92. /* Clear USB-related interrupts before enable interrupt */
  93. USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
  94. /* Enable USB-related interrupts. */
  95. USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
  96. }
  97. /**
  98. * @brief Get the received SETUP packet
  99. *
  100. * @param[in] buf A buffer pointer used to store 8-byte SETUP packet.
  101. *
  102. * @return None
  103. *
  104. * @details Store SETUP packet to a user-specified buffer.
  105. *
  106. */
  107. void USBD_GetSetupPacket(uint8_t *buf)
  108. {
  109. USBD_MemCopy(buf, g_usbd_SetupPacket, 8);
  110. }
  111. /**
  112. * @brief Process SETUP packet
  113. *
  114. * @param None
  115. *
  116. * @return None
  117. *
  118. * @details Parse SETUP packet and perform the corresponding action.
  119. *
  120. */
  121. void USBD_ProcessSetupPacket(void)
  122. {
  123. /* Get SETUP packet from USB buffer */
  124. USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
  125. /* Check the request type */
  126. switch(g_usbd_SetupPacket[0] & 0x60)
  127. {
  128. case REQ_STANDARD: // Standard
  129. {
  130. USBD_StandardRequest();
  131. break;
  132. }
  133. case REQ_CLASS: // Class
  134. {
  135. if(g_usbd_pfnClassRequest != NULL)
  136. {
  137. g_usbd_pfnClassRequest();
  138. }
  139. break;
  140. }
  141. case REQ_VENDOR: // Vendor
  142. {
  143. if(g_usbd_pfnVendorRequest != NULL)
  144. {
  145. g_usbd_pfnVendorRequest();
  146. }
  147. break;
  148. }
  149. default: // reserved
  150. {
  151. /* Setup error, stall the device */
  152. USBD_SET_EP_STALL(EP0);
  153. USBD_SET_EP_STALL(EP1);
  154. break;
  155. }
  156. }
  157. }
  158. /**
  159. * @brief Process GetDescriptor request
  160. *
  161. * @param None
  162. *
  163. * @return None
  164. *
  165. * @details Parse GetDescriptor request and perform the corresponding action.
  166. *
  167. */
  168. void USBD_GetDescriptor(void)
  169. {
  170. uint32_t u32Len;
  171. u32Len = 0;
  172. u32Len = g_usbd_SetupPacket[7];
  173. u32Len <<= 8;
  174. u32Len += g_usbd_SetupPacket[6];
  175. switch(g_usbd_SetupPacket[3])
  176. {
  177. // Get Device Descriptor
  178. case DESC_DEVICE:
  179. {
  180. u32Len = Minimum(u32Len, LEN_DEVICE);
  181. DBG_PRINTF("Get device desc, %d\n", u32Len);
  182. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len);
  183. break;
  184. }
  185. // Get Configuration Descriptor
  186. case DESC_CONFIG:
  187. {
  188. uint32_t u32TotalLen;
  189. u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3];
  190. u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8);
  191. DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen);
  192. u32Len = Minimum(u32Len, u32TotalLen);
  193. DBG_PRINTF("Minimum len %d\n", u32Len);
  194. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len);
  195. break;
  196. }
  197. // Get HID Descriptor
  198. case DESC_HID:
  199. {
  200. /* CV3.0 HID Class Descriptor Test,
  201. Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */
  202. uint32_t u32ConfigDescOffset; // u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index)
  203. u32Len = Minimum(u32Len, LEN_HID);
  204. DBG_PRINTF("Get HID desc, %d\n", u32Len);
  205. u32ConfigDescOffset = g_usbd_sInfo->gu32ConfigHidDescIdx[g_usbd_SetupPacket[4]];
  206. USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[u32ConfigDescOffset], u32Len);
  207. break;
  208. }
  209. // Get Report Descriptor
  210. case DESC_HID_RPT:
  211. {
  212. DBG_PRINTF("Get HID report, %d\n", u32Len);
  213. u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[g_usbd_SetupPacket[4]]);
  214. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[g_usbd_SetupPacket[4]], u32Len);
  215. break;
  216. }
  217. // Get String Descriptor
  218. case DESC_STRING:
  219. {
  220. // Get String Descriptor
  221. if(g_usbd_SetupPacket[2] < 4)
  222. {
  223. u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]);
  224. DBG_PRINTF("Get string desc %d\n", u32Len);
  225. USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len);
  226. break;
  227. }
  228. else
  229. {
  230. // Not support. Reply STALL.
  231. USBD_SET_EP_STALL(EP0);
  232. USBD_SET_EP_STALL(EP1);
  233. DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]);
  234. break;
  235. }
  236. }
  237. default:
  238. // Not support. Reply STALL.
  239. USBD_SET_EP_STALL(EP0);
  240. USBD_SET_EP_STALL(EP1);
  241. DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n");
  242. break;
  243. }
  244. }
  245. /**
  246. * @brief Process standard request
  247. *
  248. * @param None
  249. *
  250. * @return None
  251. *
  252. * @details Parse standard request and perform the corresponding action.
  253. *
  254. */
  255. void USBD_StandardRequest(void)
  256. {
  257. /* clear global variables for new request */
  258. g_usbd_CtrlInPointer = 0;
  259. g_usbd_CtrlInSize = 0;
  260. if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */
  261. {
  262. // Device to host
  263. switch(g_usbd_SetupPacket[1])
  264. {
  265. case GET_CONFIGURATION:
  266. {
  267. // Return current configuration setting
  268. /* Data stage */
  269. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig;
  270. USBD_SET_DATA1(EP0);
  271. USBD_SET_PAYLOAD_LEN(EP0, 1);
  272. /* Status stage */
  273. USBD_PrepareCtrlOut(0,0);
  274. DBG_PRINTF("Get configuration\n");
  275. break;
  276. }
  277. case GET_DESCRIPTOR:
  278. {
  279. USBD_GetDescriptor();
  280. USBD_PrepareCtrlOut(0, 0); /* For status stage */
  281. break;
  282. }
  283. case GET_INTERFACE:
  284. {
  285. // Return current interface setting
  286. /* Data stage */
  287. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface;
  288. USBD_SET_DATA1(EP0);
  289. USBD_SET_PAYLOAD_LEN(EP0, 1);
  290. /* Status stage */
  291. USBD_PrepareCtrlOut(0, 0);
  292. DBG_PRINTF("Get interface\n");
  293. break;
  294. }
  295. case GET_STATUS:
  296. {
  297. // Device
  298. if(g_usbd_SetupPacket[0] == 0x80)
  299. {
  300. uint8_t u8Tmp;
  301. u8Tmp = 0;
  302. if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered.
  303. if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up
  304. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp;
  305. }
  306. // Interface
  307. else if(g_usbd_SetupPacket[0] == 0x81)
  308. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0;
  309. // Endpoint
  310. else if(g_usbd_SetupPacket[0] == 0x82)
  311. {
  312. uint8_t ep = g_usbd_SetupPacket[4] & 0xF;
  313. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0;
  314. }
  315. M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0;
  316. /* Data stage */
  317. USBD_SET_DATA1(EP0);
  318. USBD_SET_PAYLOAD_LEN(EP0, 2);
  319. /* Status stage */
  320. USBD_PrepareCtrlOut(0, 0);
  321. DBG_PRINTF("Get status\n");
  322. break;
  323. }
  324. default:
  325. {
  326. /* Setup error, stall the device */
  327. USBD_SET_EP_STALL(EP0);
  328. USBD_SET_EP_STALL(EP1);
  329. DBG_PRINTF("Unknown request. stall ctrl pipe.\n");
  330. break;
  331. }
  332. }
  333. }
  334. else
  335. {
  336. // Host to device
  337. switch(g_usbd_SetupPacket[1])
  338. {
  339. case CLEAR_FEATURE:
  340. {
  341. if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
  342. {
  343. int32_t epNum, i;
  344. /* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
  345. a flag: g_u32EpStallLock is added to support it */
  346. epNum = g_usbd_SetupPacket[4] & 0xF;
  347. for(i = 0; i < USBD_MAX_EP; i++)
  348. {
  349. if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0))
  350. {
  351. USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk;
  352. DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP);
  353. }
  354. }
  355. }
  356. else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
  357. g_usbd_RemoteWakeupEn = 0;
  358. /* Status stage */
  359. USBD_SET_DATA1(EP0);
  360. USBD_SET_PAYLOAD_LEN(EP0, 0);
  361. DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]);
  362. break;
  363. }
  364. case SET_ADDRESS:
  365. {
  366. g_usbd_UsbAddr = g_usbd_SetupPacket[2];
  367. DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr);
  368. // DATA IN for end of setup
  369. /* Status Stage */
  370. USBD_SET_DATA1(EP0);
  371. USBD_SET_PAYLOAD_LEN(EP0, 0);
  372. break;
  373. }
  374. case SET_CONFIGURATION:
  375. {
  376. g_usbd_UsbConfig = g_usbd_SetupPacket[2];
  377. if(g_usbd_pfnSetConfigCallback)
  378. g_usbd_pfnSetConfigCallback();
  379. // DATA IN for end of setup
  380. /* Status stage */
  381. USBD_SET_DATA1(EP0);
  382. USBD_SET_PAYLOAD_LEN(EP0, 0);
  383. DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig);
  384. break;
  385. }
  386. case SET_FEATURE:
  387. {
  388. if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
  389. {
  390. USBD_SetStall(g_usbd_SetupPacket[4] & 0xF);
  391. DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF);
  392. }
  393. else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
  394. {
  395. g_usbd_RemoteWakeupEn = 1;
  396. DBG_PRINTF("Set feature. enable remote wakeup\n");
  397. }
  398. /* Status stage */
  399. USBD_SET_DATA1(EP0);
  400. USBD_SET_PAYLOAD_LEN(EP0, 0);
  401. break;
  402. }
  403. case SET_INTERFACE:
  404. {
  405. g_usbd_UsbAltInterface = g_usbd_SetupPacket[2];
  406. if(g_usbd_pfnSetInterface != NULL)
  407. g_usbd_pfnSetInterface();
  408. /* Status stage */
  409. USBD_SET_DATA1(EP0);
  410. USBD_SET_PAYLOAD_LEN(EP0, 0);
  411. DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface);
  412. break;
  413. }
  414. default:
  415. {
  416. /* Setup error, stall the device */
  417. USBD_SET_EP_STALL(EP0);
  418. USBD_SET_EP_STALL(EP1);
  419. DBG_PRINTF("Unsupported request. stall ctrl pipe.\n");
  420. break;
  421. }
  422. }
  423. }
  424. }
  425. /**
  426. * @brief Prepare the first Control IN pipe
  427. *
  428. * @param[in] pu8Buf The pointer of data sent to USB host.
  429. * @param[in] u32Size The IN transfer size.
  430. *
  431. * @return None
  432. *
  433. * @details Prepare data for Control IN transfer.
  434. *
  435. */
  436. void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size)
  437. {
  438. DBG_PRINTF("Prepare Ctrl In %d\n", u32Size);
  439. if(u32Size > g_usbd_CtrlMaxPktSize)
  440. {
  441. // Data size > MXPLD
  442. g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize;
  443. g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize;
  444. USBD_SET_DATA1(EP0);
  445. USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize);
  446. USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
  447. }
  448. else
  449. {
  450. // Data size <= MXPLD
  451. g_usbd_CtrlInPointer = 0;
  452. g_usbd_CtrlInSize = 0;
  453. USBD_SET_DATA1(EP0);
  454. USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size);
  455. USBD_SET_PAYLOAD_LEN(EP0, u32Size);
  456. }
  457. }
  458. /**
  459. * @brief Repeat Control IN pipe
  460. *
  461. * @param None
  462. *
  463. * @return None
  464. *
  465. * @details This function processes the remained data of Control IN transfer.
  466. *
  467. */
  468. void USBD_CtrlIn(void)
  469. {
  470. static uint8_t u8ZeroFlag = 0;
  471. DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize);
  472. if(g_usbd_CtrlInSize)
  473. {
  474. // Process remained data
  475. if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize)
  476. {
  477. // Data size > MXPLD
  478. USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
  479. USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
  480. g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
  481. g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
  482. }
  483. else
  484. {
  485. // Data size <= MXPLD
  486. USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize);
  487. USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize);
  488. if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize)
  489. u8ZeroFlag = 1;
  490. g_usbd_CtrlInPointer = 0;
  491. g_usbd_CtrlInSize = 0;
  492. }
  493. }
  494. else // No more data for IN token
  495. {
  496. // In ACK for Set address
  497. if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS))
  498. {
  499. if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0))
  500. {
  501. USBD_SET_ADDR(g_usbd_UsbAddr);
  502. }
  503. }
  504. /* For the case of data size is integral times maximum packet size */
  505. if(u8ZeroFlag)
  506. {
  507. USBD_SET_PAYLOAD_LEN(EP0, 0);
  508. u8ZeroFlag = 0;
  509. }
  510. DBG_PRINTF("Ctrl In done.\n");
  511. }
  512. }
  513. /**
  514. * @brief Prepare the first Control OUT pipe
  515. *
  516. * @param[in] pu8Buf The pointer of data received from USB host.
  517. * @param[in] u32Size The OUT transfer size.
  518. *
  519. * @return None
  520. *
  521. * @details This function is used to prepare the first Control OUT transfer.
  522. *
  523. */
  524. void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size)
  525. {
  526. g_usbd_CtrlOutPointer = pu8Buf;
  527. g_usbd_CtrlOutSize = 0;
  528. g_usbd_CtrlOutSizeLimit = u32Size;
  529. USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
  530. }
  531. /**
  532. * @brief Repeat Control OUT pipe
  533. *
  534. * @param None
  535. *
  536. * @return None
  537. *
  538. * @details This function processes the successive Control OUT transfer.
  539. *
  540. */
  541. void USBD_CtrlOut(void)
  542. {
  543. uint32_t u32Size;
  544. DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize);
  545. if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
  546. {
  547. u32Size = USBD_GET_PAYLOAD_LEN(EP1);
  548. USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size);
  549. g_usbd_CtrlOutPointer += u32Size;
  550. g_usbd_CtrlOutSize += u32Size;
  551. if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
  552. USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
  553. }
  554. }
  555. /**
  556. * @brief Reset software flags
  557. *
  558. * @param None
  559. *
  560. * @return None
  561. *
  562. * @details This function resets all variables for protocol and resets USB device address to 0.
  563. *
  564. */
  565. void USBD_SwReset(void)
  566. {
  567. int i;
  568. // Reset all variables for protocol
  569. g_usbd_CtrlInPointer = 0;
  570. g_usbd_CtrlInSize = 0;
  571. g_usbd_CtrlOutPointer = 0;
  572. g_usbd_CtrlOutSize = 0;
  573. g_usbd_CtrlOutSizeLimit = 0;
  574. g_u32EpStallLock = 0;
  575. memset(g_usbd_SetupPacket, 0, 8);
  576. /* Reset PID DATA0 */
  577. for(i=0; i<USBD_MAX_EP; i++)
  578. USBD->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
  579. // Reset USB device address
  580. USBD_SET_ADDR(0);
  581. }
  582. /**
  583. * @brief USBD Set Vendor Request
  584. *
  585. * @param[in] pfnVendorReq Vendor Request Callback Function
  586. *
  587. * @return None
  588. *
  589. * @details This function is used to set USBD vendor request callback function
  590. */
  591. void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq)
  592. {
  593. g_usbd_pfnVendorRequest = pfnVendorReq;
  594. }
  595. /**
  596. * @brief The callback function which called when get SET CONFIGURATION request
  597. *
  598. * @param[in] pfnSetConfigCallback Callback function pointer for SET CONFIGURATION request
  599. *
  600. * @return None
  601. *
  602. * @details This function is used to set the callback function which will be called at SET CONFIGURATION request.
  603. */
  604. void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback)
  605. {
  606. g_usbd_pfnSetConfigCallback = pfnSetConfigCallback;
  607. }
  608. /**
  609. * @brief EP stall lock function to avoid stall clear by USB SET FEATURE request.
  610. *
  611. * @param[in] u32EpBitmap Use bitmap to select which endpoints will be locked
  612. *
  613. * @return None
  614. *
  615. * @details This function is used to lock relative endpoint to avoid stall clear by SET FEATURE requst.
  616. * If ep stall locked, user needs to reset USB device or re-configure device to clear it.
  617. */
  618. void USBD_LockEpStall(uint32_t u32EpBitmap)
  619. {
  620. g_u32EpStallLock = u32EpBitmap;
  621. }
  622. /*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */
  623. /*@}*/ /* end of group USBD_Driver */
  624. /*@}*/ /* end of group Standard_Driver */
  625. #ifdef __cplusplus
  626. }
  627. #endif
  628. /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/