usbd_std.c 23 KB

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