1
0

usbd_std.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /*!
  2. \file usbd_std.c
  3. \brief USB 2.0 standard handler driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.0, firmware for GD32F30x
  8. */
  9. #include "usbd_std.h"
  10. #include "usb_core.h"
  11. static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  12. static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  13. static usbd_status_enum usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  14. static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req);
  15. static void usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  16. static void usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  17. static void usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  18. static void usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  19. static void usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  20. static void usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  21. static void usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  22. static void usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  23. static void usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  24. static void usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  25. static void usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  26. static void usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req);
  27. static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
  28. static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
  29. static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
  30. static void (*StandardDeviceRequest[])(usb_core_handle_struct *pudev, usb_device_req_struct *req) =
  31. {
  32. usbd_getstatus,
  33. usbd_clrfeature,
  34. usbd_reserved,
  35. usbd_setfeature,
  36. usbd_reserved,
  37. usbd_setaddress,
  38. usbd_getdescriptor,
  39. usbd_setdescriptor,
  40. usbd_getconfig,
  41. usbd_setconfig,
  42. usbd_getinterface,
  43. usbd_setinterface,
  44. usbd_synchframe,
  45. };
  46. /* get standard descriptor handler */
  47. static uint8_t* (*standard_descriptor_get[])(usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) =
  48. {
  49. usbd_device_descriptor_get,
  50. usbd_configuration_descriptor_get,
  51. usbd_string_descriptor_get
  52. };
  53. /*!
  54. \brief USB setup stage processing
  55. \param[in] pudev: pointer to USB device instance
  56. \param[out] none
  57. \retval USB device operation status
  58. */
  59. usbd_status_enum usbd_setup_transaction(usb_core_handle_struct *pudev)
  60. {
  61. usb_device_req_struct req;
  62. usbd_setup_request_parse(pudev, &req);
  63. switch (req.bmRequestType & USB_REQ_MASK) {
  64. /* standard device request */
  65. case USB_STANDARD_REQ:
  66. usbd_standard_request(pudev, &req);
  67. break;
  68. /* device class request */
  69. case USB_CLASS_REQ:
  70. usbd_device_class_request(pudev, &req);
  71. break;
  72. /* vendor defined request */
  73. case USB_VENDOR_REQ:
  74. usbd_vendor_request(pudev, &req);
  75. break;
  76. default:
  77. usbd_ep_stall(pudev, req.bmRequestType & 0x80U);
  78. break;
  79. }
  80. return USBD_OK;
  81. }
  82. /*!
  83. \brief data out stage processing
  84. \param[in] pudev: pointer to USB device instance
  85. \param[in] ep_id: endpoint identifier(0..7)
  86. \param[out] none
  87. \retval USB device operation status
  88. */
  89. usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
  90. {
  91. usb_ep_struct *ep;
  92. if (0U == endp_num) {
  93. ep = &pudev->dev.out_ep[0];
  94. if (USB_CTRL_DATA_OUT == pudev->dev.ctl_status) {
  95. if (pudev->dev.remain_len > ep->endp_mps) {
  96. pudev->dev.remain_len -= ep->endp_mps;
  97. usbd_ep_rx (pudev,
  98. 0U,
  99. ep->xfer_buff,
  100. (uint16_t)USB_MIN(pudev->dev.remain_len, ep->endp_mps));
  101. } else {
  102. if (USB_STATUS_CONFIGURED == pudev->dev.status) {
  103. pudev->dev.class_data_handler(pudev, USB_RX, 0U);
  104. }
  105. usbd_ctlstatus_tx(pudev);
  106. }
  107. }
  108. } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
  109. pudev->dev.class_data_handler(pudev, USB_RX, endp_num);
  110. } else {
  111. /* no operation */
  112. }
  113. return USBD_OK;
  114. }
  115. /*!
  116. \brief data in stage processing
  117. \param[in] pudev: pointer to USB device instance
  118. \param[in] ep_id: endpoint identifier(0..7)
  119. \param[out] none
  120. \retval USB device operation status
  121. */
  122. usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
  123. {
  124. usb_ep_struct *ep;
  125. if (0U == endp_num) {
  126. ep = &pudev->dev.in_ep[0];
  127. if (USB_CTRL_DATA_IN == pudev->dev.ctl_status) {
  128. if (pudev->dev.remain_len > ep->endp_mps) {
  129. pudev->dev.remain_len -= ep->endp_mps;
  130. usbd_ep_tx (pudev, 0U, ep->xfer_buff, pudev->dev.remain_len);
  131. usbd_ep_rx (pudev, 0U, NULL, 0U);
  132. } else {
  133. /* last packet is MPS multiple, so send ZLP packet */
  134. if ((pudev->dev.sum_len % ep->endp_mps == 0U) &&
  135. (pudev->dev.sum_len >= ep->endp_mps) &&
  136. (pudev->dev.sum_len < pudev->dev.ctl_len)) {
  137. usbd_ep_tx (pudev, 0U, NULL, 0U);
  138. pudev->dev.ctl_len = 0U;
  139. usbd_ep_rx (pudev, 0U, NULL, 0U);
  140. } else {
  141. if (USB_STATUS_CONFIGURED == pudev->dev.status) {
  142. pudev->dev.class_data_handler(pudev, USB_TX, 0U);
  143. }
  144. usbd_ctlstatus_rx(pudev);
  145. }
  146. }
  147. }
  148. } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
  149. pudev->dev.class_data_handler(pudev, USB_TX, endp_num);
  150. } else {
  151. /* no operation */
  152. }
  153. return USBD_OK;
  154. }
  155. /*!
  156. \brief handle USB standard device request
  157. \param[in] pudev: pointer to USB device instance
  158. \param[in] req: pointer to USB device request
  159. \param[out] none
  160. \retval USB device operation status
  161. */
  162. static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  163. {
  164. /* call device request handle function */
  165. (*StandardDeviceRequest[req->bRequest])(pudev, req);
  166. return USBD_OK;
  167. }
  168. /*!
  169. \brief handle USB device class request
  170. \param[in] pudev: pointer to USB device instance
  171. \param[in] req: pointer to USB device class request
  172. \param[out] none
  173. \retval USB device operation status
  174. */
  175. static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  176. {
  177. usbd_status_enum ret = USBD_OK;
  178. switch (pudev->dev.status) {
  179. case USB_STATUS_CONFIGURED:
  180. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  181. ret = (usbd_status_enum)(pudev->dev.class_req_handler(pudev, req));
  182. if ((0U == req->wLength) && (USBD_OK == ret)) {
  183. /* no data stage */
  184. usbd_ctlstatus_tx(pudev);
  185. }
  186. } else {
  187. usbd_enum_error(pudev, req);
  188. }
  189. break;
  190. default:
  191. usbd_enum_error(pudev, req);
  192. break;
  193. }
  194. return ret;
  195. }
  196. /*!
  197. \brief handle USB vendor request
  198. \param[in] pudev: pointer to USB device instance
  199. \param[in] req: pointer to USB vendor request
  200. \param[out] none
  201. \retval USB device operation status
  202. */
  203. static usbd_status_enum usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  204. {
  205. /* added by user... */
  206. return USBD_OK;
  207. }
  208. /*!
  209. \brief no operation, just for reserved
  210. \param[in] pudev: pointer to USB device instance
  211. \param[in] req: pointer to USB device request
  212. \param[out] none
  213. \retval none
  214. */
  215. static void usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  216. {
  217. /* no operation... */
  218. }
  219. /*!
  220. \brief get the device descriptor
  221. \brief[in] index: no use
  222. \param[in] none
  223. \param[out] pLen: data length pointer
  224. \retval descriptor buffer pointer
  225. */
  226. static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  227. {
  228. *pLen = pudev->dev.dev_desc[0];
  229. return pudev->dev.dev_desc;
  230. }
  231. /*!
  232. \brief get the configuration descriptor
  233. \brief[in] index: no use
  234. \param[in] none
  235. \param[out] pLen: data length pointer
  236. \retval descriptor buffer pointer
  237. */
  238. static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  239. {
  240. *pLen = pudev->dev.config_desc[2];
  241. return pudev->dev.config_desc;
  242. }
  243. /*!
  244. \brief get string descriptor
  245. \param[in] index: string descriptor index
  246. \param[in] pLen: pointer to string length
  247. \param[out] none
  248. \retval none
  249. */
  250. static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  251. {
  252. uint8_t *desc = pudev->dev.strings[index];
  253. *pLen = desc[0];
  254. return desc;
  255. }
  256. /*!
  257. \brief handle Get_Status request
  258. \param[in] pudev: pointer to USB device instance
  259. \param[in] req: pointer to USB device request
  260. \param[out] none
  261. \retval none
  262. */
  263. static void usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  264. {
  265. }
  266. /*!
  267. \brief handle USB Clear_Feature request
  268. \param[in] pudev: pointer to USB device instance
  269. \param[in] req: USB device request
  270. \param[out] none
  271. \retval none
  272. */
  273. static void usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  274. {
  275. uint8_t ep_addr = 0U;
  276. switch (req->bmRequestType & USB_REQTYPE_MASK) {
  277. case USB_REQTYPE_DEVICE:
  278. switch (pudev->dev.status) {
  279. case USB_STATUS_ADDRESSED:
  280. case USB_STATUS_CONFIGURED:
  281. if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
  282. pudev->dev.remote_wakeup = 0U;
  283. pudev->dev.class_req_handler(pudev, req);
  284. usbd_ctlstatus_tx(pudev);
  285. }
  286. break;
  287. default:
  288. usbd_enum_error(pudev, req);
  289. break;
  290. }
  291. break;
  292. case USB_REQTYPE_INTERFACE:
  293. switch (pudev->dev.status) {
  294. case USB_STATUS_ADDRESSED:
  295. usbd_enum_error(pudev, req);
  296. break;
  297. case USB_STATUS_CONFIGURED:
  298. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  299. /* no operation */
  300. } else {
  301. usbd_enum_error(pudev, req);
  302. }
  303. break;
  304. default:
  305. break;
  306. }
  307. break;
  308. case USB_REQTYPE_ENDPOINT:
  309. ep_addr = LOWBYTE(req->wIndex);
  310. switch (pudev->dev.status) {
  311. case USB_STATUS_ADDRESSED:
  312. if (IS_NOT_EP0(ep_addr)) {
  313. usbd_ep_stall(pudev, ep_addr);
  314. }
  315. break;
  316. case USB_STATUS_CONFIGURED:
  317. if (USB_FEATURE_ENDP_HALT == req->wValue) {
  318. if (IS_NOT_EP0(ep_addr)) {
  319. usbd_ep_clear_stall(pudev, ep_addr);
  320. pudev->dev.class_req_handler(pudev, req);
  321. }
  322. }
  323. usbd_ctlstatus_tx(pudev);
  324. break;
  325. default:
  326. break;
  327. }
  328. break;
  329. default:
  330. usbd_enum_error(pudev, req);
  331. break;
  332. }
  333. }
  334. /*!
  335. \brief handle USB Set_Feature request
  336. \param[in] pudev: pointer to USB device instance
  337. \param[in] req: pointer to USB device request
  338. \param[out] none
  339. \retval none
  340. */
  341. static void usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  342. {
  343. uint8_t ep_addr = 0U;
  344. __IO uint32_t DctlrStatus;
  345. switch (req->bmRequestType & USB_REQ_MASK) {
  346. case USB_REQTYPE_DEVICE:
  347. switch (pudev->dev.status) {
  348. case USB_STATUS_ADDRESSED:
  349. case USB_STATUS_CONFIGURED:
  350. if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
  351. pudev->dev.remote_wakeup = 1U;
  352. pudev->dev.class_req_handler(pudev, req);
  353. usbd_ctlstatus_tx(pudev);
  354. } else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
  355. (0U == (req->wIndex & 0xFFU))) {
  356. DctlrStatus = USB_DCTL;
  357. usbd_ctlstatus_tx(pudev);
  358. } else {
  359. /* no operation */
  360. }
  361. break;
  362. default:
  363. break;
  364. }
  365. break;
  366. case USB_REQTYPE_INTERFACE:
  367. switch (pudev->dev.status) {
  368. case USB_STATUS_ADDRESSED:
  369. usbd_enum_error(pudev, req);
  370. break;
  371. case USB_STATUS_CONFIGURED:
  372. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  373. /* no operation */
  374. } else {
  375. usbd_enum_error(pudev, req);
  376. }
  377. break;
  378. default:
  379. break;
  380. }
  381. break;
  382. case USB_REQTYPE_ENDPOINT:
  383. switch (pudev->dev.status) {
  384. case USB_STATUS_ADDRESSED:
  385. if (IS_NOT_EP0(ep_addr)) {
  386. usbd_ep_stall(pudev, ep_addr);
  387. }
  388. break;
  389. case USB_STATUS_CONFIGURED:
  390. if (USB_FEATURE_ENDP_HALT == req->wValue) {
  391. if (IS_NOT_EP0(ep_addr)) {
  392. usbd_ep_stall(pudev, ep_addr);
  393. }
  394. }
  395. pudev->dev.class_req_handler(pudev, req);
  396. usbd_ctlstatus_tx(pudev);
  397. break;
  398. default:
  399. break;
  400. }
  401. break;
  402. default:
  403. usbd_enum_error(pudev, req);
  404. break;
  405. }
  406. }
  407. /*!
  408. \brief handle USB Set_Address request
  409. \param[in] pudev: pointer to USB device instance
  410. \param[in] req: pointer to USB device request
  411. \param[out] none
  412. \retval none
  413. */
  414. static void usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  415. {
  416. uint8_t DevAddr;
  417. if ((0U == req->wIndex) && (0U == req->wLength)) {
  418. DevAddr = (uint8_t)(req->wValue) & 0x7FU;
  419. if (USB_STATUS_CONFIGURED == pudev->dev.status) {
  420. usbd_enum_error(pudev, req);
  421. } else {
  422. USB_SET_DEVADDR((uint32_t)DevAddr);
  423. usbd_ctlstatus_tx(pudev);
  424. if (0U != DevAddr) {
  425. pudev->dev.status = USB_STATUS_ADDRESSED;
  426. } else {
  427. pudev->dev.status = USB_STATUS_DEFAULT;
  428. }
  429. }
  430. } else {
  431. usbd_enum_error(pudev, req);
  432. }
  433. }
  434. /*!
  435. \brief handle USB Get_Descriptor request
  436. \param[in] pudev: pointer to USB device instance
  437. \param[in] req: pointer to USB device request
  438. \param[out] none
  439. \retval none
  440. */
  441. static void usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  442. {
  443. if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQTYPE_MASK)) {
  444. uint8_t desc_index = (uint8_t)(req->wValue >> 8U);
  445. if (desc_index <= 0x03U) {
  446. uint16_t len;
  447. uint8_t *pbuf;
  448. /* call corresponding descriptor get function */
  449. pbuf = standard_descriptor_get[desc_index - 1U](pudev, (uint8_t)(req->wValue) & 0xFFU, &len);
  450. if ((0U != len) && (0U != req->wLength)) {
  451. len = USB_MIN(len, req->wLength);
  452. if ((1U == desc_index) && (64U == req->wLength)) {
  453. len = 8U;
  454. }
  455. usbd_ctltx(pudev, pbuf, len);
  456. }
  457. } else {
  458. usbd_enum_error(pudev, req);
  459. }
  460. } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQTYPE_MASK)) {
  461. pudev->dev.class_req_handler(pudev, req);
  462. } else {
  463. /* no operation */
  464. }
  465. }
  466. /*!
  467. \brief handle USB Set_Descriptor request
  468. \param[in] pudev: pointer to USB device instance
  469. \param[in] req: pointer to USB device request
  470. \param[out] none
  471. \retval none
  472. */
  473. static void usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  474. {
  475. /* no handle... */
  476. }
  477. /*!
  478. \brief handle USB Get_Configuration request
  479. \param[in] pudev: pointer to USB device instance
  480. \param[in] req: pointer to USB device request
  481. \param[out] none
  482. \retval none
  483. */
  484. static void usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  485. {
  486. uint32_t USBD_default_config = 0U;
  487. if (1U != req->wLength) {
  488. usbd_enum_error(pudev, req);
  489. } else {
  490. switch (pudev->dev.status) {
  491. case USB_STATUS_ADDRESSED:
  492. usbd_ctltx(pudev, (uint8_t *)&USBD_default_config, 1U);
  493. break;
  494. case USB_STATUS_CONFIGURED:
  495. usbd_ctltx(pudev, &pudev->dev.config_num, 1U);
  496. break;
  497. default:
  498. usbd_enum_error(pudev, req);
  499. break;
  500. }
  501. }
  502. }
  503. /*!
  504. \brief handle USB Set_Configuration request
  505. \param[in] pudev: pointer to USB device instance
  506. \param[in] req: pointer to USB device request
  507. \param[out] none
  508. \retval none
  509. */
  510. static void usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  511. {
  512. static uint8_t cfgidx;
  513. cfgidx = (uint8_t)(req->wValue);
  514. if (cfgidx > USBD_CFG_MAX_NUM) {
  515. usbd_enum_error(pudev, req);
  516. } else {
  517. switch (pudev->dev.status) {
  518. case USB_STATUS_ADDRESSED:
  519. if (cfgidx) {
  520. pudev->dev.config_num = cfgidx;
  521. pudev->dev.status = USB_STATUS_CONFIGURED;
  522. pudev->dev.class_init(pudev, cfgidx);
  523. }
  524. usbd_ctlstatus_tx(pudev);
  525. break;
  526. case USB_STATUS_CONFIGURED:
  527. if (0U == cfgidx) {
  528. pudev->dev.status = USB_STATUS_ADDRESSED;
  529. pudev->dev.config_num = cfgidx;
  530. pudev->dev.class_deinit(pudev, cfgidx);
  531. } else if (cfgidx != pudev->dev.config_num) {
  532. /* clear old configuration */
  533. pudev->dev.class_deinit(pudev, pudev->dev.config_num);
  534. /* set new configuration */
  535. pudev->dev.config_num = cfgidx;
  536. pudev->dev.class_init(pudev, cfgidx);
  537. } else {
  538. /* no operation */
  539. }
  540. usbd_ctlstatus_tx(pudev);
  541. break;
  542. default:
  543. usbd_enum_error(pudev, req);
  544. break;
  545. }
  546. }
  547. }
  548. /*!
  549. \brief handle USB Get_Interface request
  550. \param[in] pudev: pointer to USB device instance
  551. \param[in] req: pointer to USB device request
  552. \param[out] none
  553. \retval none
  554. */
  555. static void usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  556. {
  557. pudev->dev.class_req_handler(pudev, req);
  558. }
  559. /*!
  560. \brief handle USB Set_Interface request
  561. \param[in] pudev: pointer to USB device instance
  562. \param[in] req: pointer to USB device request
  563. \param[out] none
  564. \retval none
  565. */
  566. static void usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  567. {
  568. pudev->dev.class_req_handler(pudev, req);
  569. }
  570. /*!
  571. \brief handle USB SynchFrame request
  572. \param[in] pudev: pointer to USB device instance
  573. \param[in] req: pointer to USB device request
  574. \param[out] none
  575. \retval none
  576. */
  577. static void usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req)
  578. {
  579. /* no handle... */
  580. }
  581. /*!
  582. \brief decode setup data packet
  583. \param[in] pudev: pointer to USB device instance
  584. \param[in] req: pointer to USB device request
  585. \param[out] none
  586. \retval none
  587. */
  588. static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req)
  589. {
  590. uint8_t *psetup = pudev->dev.setup_packet;
  591. req->bmRequestType = *psetup;
  592. req->bRequest = *(uint8_t *)(psetup + 1U);
  593. req->wValue = SWAPBYTE (psetup + 2U);
  594. req->wIndex = SWAPBYTE (psetup + 4U);
  595. req->wLength = SWAPBYTE (psetup + 6U);
  596. pudev->dev.ctl_len = req->wLength;
  597. }
  598. /*!
  599. \brief handle USB low level error event
  600. \param[in] pudev: pointer to USB device instance
  601. \param[in] req: pointer to USB device request
  602. \param[out] none
  603. \retval none
  604. */
  605. void usbd_enum_error(usb_core_handle_struct *pudev, usb_device_req_struct *req)
  606. {
  607. usbd_ep_stall(pudev, 0x80U);
  608. usbd_ep_stall(pudev, 0x00U);
  609. usb_ep0_startout(pudev);
  610. }