usbd_std.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. /*!
  2. \file usbd_std.c
  3. \brief USB device stand routines
  4. \note about USB standard, please refer to the USB2.0 protocol
  5. \version 2014-12-26, V1.0.0, firmware for GD32F10x
  6. \version 2017-06-20, V2.0.0, firmware for GD32F10x
  7. \version 2018-07-31, V2.1.0, firmware for GD32F10x
  8. */
  9. /*
  10. Copyright (c) 2018, GigaDevice Semiconductor Inc.
  11. All rights reserved.
  12. Redistribution and use in source and binary forms, with or without modification,
  13. are permitted provided that the following conditions are met:
  14. 1. Redistributions of source code must retain the above copyright notice, this
  15. list of conditions and the following disclaimer.
  16. 2. Redistributions in binary form must reproduce the above copyright notice,
  17. this list of conditions and the following disclaimer in the documentation
  18. and/or other materials provided with the distribution.
  19. 3. Neither the name of the copyright holder nor the names of its contributors
  20. may be used to endorse or promote products derived from this software without
  21. specific prior written permission.
  22. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  26. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  31. OF SUCH DAMAGE.
  32. */
  33. #include "usbd_std.h"
  34. uint8_t g_device_address = 0U;
  35. /* USB enumeration handle functions */
  36. static void usbd_getdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  37. static void usbd_setaddress (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  38. static void usbd_setconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  39. static void usbd_getconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  40. static void usbd_getstatus (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  41. static void usbd_setfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  42. static void usbd_clearfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  43. static void usbd_reserved (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  44. static void usbd_setdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  45. static void usbd_getinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  46. static void usbd_setinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  47. static void usbd_synchframe (usbd_core_handle_struct *pudev, usb_device_req_struct *req);
  48. static uint8_t* usbd_device_descriptor_get (usbd_core_handle_struct *pudev,
  49. uint8_t index,
  50. uint16_t *pLen);
  51. static uint8_t* usbd_configuration_descriptor_get (usbd_core_handle_struct *pudev,
  52. uint8_t index,
  53. uint16_t *pLen);
  54. static uint8_t* usbd_string_descriptor_get (usbd_core_handle_struct *pudev,
  55. uint8_t index,
  56. uint16_t *pLen);
  57. #ifdef LPM_ENABLED
  58. static uint8_t* usbd_bos_descriptor_get (usbd_core_handle_struct *pudev, uint16_t *pLen);
  59. #endif /* LPM_ENABLED */
  60. /* standard device request handler */
  61. static void (*standard_device_request[])(usbd_core_handle_struct *pudev, usb_device_req_struct *req) =
  62. {
  63. usbd_getstatus,
  64. usbd_clearfeature,
  65. usbd_reserved,
  66. usbd_setfeature,
  67. usbd_reserved,
  68. usbd_setaddress,
  69. usbd_getdescriptor,
  70. usbd_setdescriptor,
  71. usbd_getconfiguration,
  72. usbd_setconfiguration,
  73. usbd_getinterface,
  74. usbd_setinterface,
  75. usbd_synchframe,
  76. };
  77. /* get standard descriptor handler */
  78. static uint8_t* (*standard_descriptor_get[])(usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) =
  79. {
  80. usbd_device_descriptor_get,
  81. usbd_configuration_descriptor_get,
  82. usbd_string_descriptor_get
  83. };
  84. /*!
  85. \brief USB setup stage processing
  86. \param[in] pudev: pointer to USB device instance
  87. \param[out] none
  88. \retval USB device operation status
  89. */
  90. uint8_t usbd_setup_transaction (usbd_core_handle_struct *pudev)
  91. {
  92. usb_device_req_struct req;
  93. usbd_setup_request_parse (pudev, &req);
  94. switch (req.bmRequestType & USB_REQ_MASK) {
  95. /* standard device request */
  96. case USB_STANDARD_REQ:
  97. usbd_standard_request(pudev, &req);
  98. break;
  99. /* device class request */
  100. case USB_CLASS_REQ:
  101. usbd_device_class_request(pudev, &req);
  102. break;
  103. /* vendor defined request */
  104. case USB_VENDOR_REQ:
  105. usbd_vendor_request(pudev, &req);
  106. break;
  107. default:
  108. usbd_ep_stall(pudev, 0x00U);
  109. break;
  110. }
  111. return USBD_OK;
  112. }
  113. /*!
  114. \brief data out stage processing
  115. \param[in] pudev: pointer to USB device instance
  116. \param[in] ep_num: endpoint identifier(0..7)
  117. \param[out] none
  118. \retval USB device operation status
  119. */
  120. uint8_t usbd_out_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num)
  121. {
  122. usb_ep_struct *ep = &pudev->out_ep[ep_num];
  123. if (0U == ep_num) {
  124. if (0U != pudev->ctl_count) {
  125. if (ep->trs_len > ep->maxpacket) {
  126. /* one data packet has been received, update trs_len */
  127. ep->trs_len -= ep->maxpacket;
  128. /* continue to receive remain data */
  129. usbd_ep_rx(pudev, EP0_OUT, ep->trs_buf, (uint16_t)ep->trs_len);
  130. } else {
  131. if (USBD_CONFIGURED == pudev->status) {
  132. /* device class handle */
  133. pudev->class_data_handler(pudev, USBD_RX, EP0);
  134. }
  135. /* enter the control transaction status stage */
  136. USBD_CONTRL_STATUS_TX();
  137. pudev->ctl_count = 0U;
  138. }
  139. } else {
  140. /* clear endpoint status_out status */
  141. USBD_STATUS_OUT_CLEAR(EP0);
  142. }
  143. } else {
  144. if (USBD_CONFIGURED == pudev->status) {
  145. pudev->class_data_handler(pudev, USBD_RX, ep_num);
  146. }
  147. }
  148. return USBD_OK;
  149. }
  150. /*!
  151. \brief data in stage processing
  152. \param[in] pudev: pointer to USB device instance
  153. \param[in] ep_num: endpoint identifier(0..7)
  154. \param[out] none
  155. \retval USB device operation status
  156. */
  157. uint8_t usbd_in_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num)
  158. {
  159. usb_ep_struct *ep = &pudev->in_ep[ep_num];
  160. if (0U == ep_num) {
  161. if (0U != pudev->ctl_count) {
  162. if (ep->trs_len > ep->maxpacket) {
  163. /* one data packet has been transmited, update trs_len */
  164. ep->trs_len -= ep->maxpacket;
  165. /* continue to transmit remain data */
  166. usbd_ep_tx (pudev, EP0_IN, ep->trs_buf, (uint16_t)ep->trs_len);
  167. usbd_ep_rx (pudev, 0U, NULL, 0U);
  168. } else {
  169. #ifndef USB_DFU
  170. /* transmit length is maxpacket multiple, so send zero length packet */
  171. if ((0U == (ep->trs_len % ep->maxpacket)) && (ep->trs_len < pudev->ctl_count)) {
  172. usbd_ep_tx (pudev, EP0_IN, NULL, 0U);
  173. pudev->ctl_count = 0U;
  174. usbd_ep_rx (pudev, 0U, NULL, 0U);
  175. } else
  176. #endif /* USB_DFU */
  177. {
  178. ep->trs_len = 0U;
  179. if (USBD_CONFIGURED == pudev->status) {
  180. pudev->class_data_handler(pudev, USBD_TX, EP0);
  181. }
  182. USBD_CONTRL_STATUS_RX();
  183. pudev->ctl_count = 0U;
  184. }
  185. }
  186. } else {
  187. if (0U != g_device_address) {
  188. USBD_REG_SET(USBD_DADDR, DADDR_USBEN | g_device_address);
  189. g_device_address = 0U;
  190. }
  191. }
  192. } else {
  193. ep->trs_len -= ep->trs_count;
  194. if (0U == ep->trs_len) {
  195. if (USBD_CONFIGURED == pudev->status) {
  196. pudev->class_data_handler(pudev, USBD_TX, ep_num);
  197. }
  198. } else {
  199. usbd_ep_tx(pudev, ep_num, ep->trs_buf, (uint16_t)ep->trs_len);
  200. }
  201. }
  202. return USBD_OK;
  203. }
  204. /*!
  205. \brief handle USB standard device request
  206. \param[in] pudev: pointer to USB device instance
  207. \param[in] req: pointer to USB device request
  208. \param[out] none
  209. \retval USB device operation status
  210. */
  211. uint8_t usbd_standard_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  212. {
  213. /* call device request handle function */
  214. (*standard_device_request[req->bRequest])(pudev, req);
  215. return USBD_OK;
  216. }
  217. /*!
  218. \brief handle USB device class request
  219. \param[in] pudev: pointer to USB device instance
  220. \param[in] req: pointer to USB device class request
  221. \param[out] none
  222. \retval USB device operation status
  223. */
  224. uint8_t usbd_device_class_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  225. {
  226. usbd_status_enum ret;
  227. switch (pudev->status) {
  228. case USBD_CONFIGURED:
  229. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  230. /* call device class handle function */
  231. ret = (usbd_status_enum)(pudev->class_req_handler(pudev, req));
  232. if ((0U == req->wLength) && (USBD_OK == ret)) {
  233. /* no data stage */
  234. USBD_CONTRL_STATUS_TX();
  235. }
  236. } else {
  237. usbd_enum_error(pudev, req);
  238. }
  239. break;
  240. default:
  241. usbd_enum_error(pudev, req);
  242. break;
  243. }
  244. return USBD_OK;
  245. }
  246. /*!
  247. \brief handle USB vendor request
  248. \param[in] pudev: pointer to USB device instance
  249. \param[in] req: pointer to USB vendor request
  250. \param[out] none
  251. \retval USB device operation status
  252. */
  253. uint8_t usbd_vendor_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  254. {
  255. /* added by user */
  256. return USBD_OK;
  257. }
  258. /*!
  259. \brief no operation, just for reserved
  260. \param[in] pudev: pointer to USB device instance
  261. \param[in] req: pointer to USB device request
  262. \param[out] none
  263. \retval none
  264. */
  265. static void usbd_reserved (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  266. {
  267. /* no operation */
  268. }
  269. #ifdef LPM_ENABLED
  270. /*!
  271. \brief get BOS descriptor
  272. \param[in] pudev: pointer to USB device instance
  273. \param[in] pLen: data length pointer
  274. \param[out] none
  275. \retval descriptor buffer pointer
  276. */
  277. static uint8_t* usbd_bos_descriptor_get (usbd_core_handle_struct *pudev, uint16_t *pLen)
  278. {
  279. *pLen = pudev->bos_desc[2] | ((uint16_t)pudev->bos_desc[3] << 8);
  280. return pudev->bos_desc;
  281. }
  282. #endif /* LPM_ENABLED */
  283. /*!
  284. \brief get the device descriptor
  285. \param[in] pudev: pointer to USB device instance
  286. \param[in] index: no use
  287. \param[out] pLen: data length pointer
  288. \retval descriptor buffer pointer
  289. */
  290. static uint8_t* usbd_device_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  291. {
  292. *pLen = pudev->dev_desc[0];
  293. return pudev->dev_desc;
  294. }
  295. /*!
  296. \brief get the configuration descriptor
  297. \brief[in] pudev: pointer to USB device instance
  298. \brief[in] index: no use
  299. \param[out] pLen: data length pointer
  300. \retval descriptor buffer pointer
  301. */
  302. static uint8_t* usbd_configuration_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  303. {
  304. *pLen = pudev->config_desc[2];
  305. return pudev->config_desc;
  306. }
  307. /*!
  308. \brief get string descriptor
  309. \param[in] pudev: pointer to USB device instance
  310. \param[in] index: string descriptor index
  311. \param[out] pLen: pointer to string length
  312. \retval none
  313. */
  314. static uint8_t* usbd_string_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
  315. {
  316. uint8_t *desc = pudev->strings[index];
  317. *pLen = desc[0];
  318. return desc;
  319. }
  320. /*!
  321. \brief handle Get_Status request
  322. \param[in] pudev: pointer to USB device instance
  323. \param[in] req: pointer to USB device request
  324. \param[out] none
  325. \retval none
  326. */
  327. static void usbd_getstatus (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  328. {
  329. uint8_t ep_addr;
  330. uint16_t config_status = 0x0000U;
  331. uint16_t endp_status = 0x0000U;
  332. switch(req->bmRequestType & USB_REQ_RECIPIENT_MASK) {
  333. case USB_REQTYPE_DEVICE:
  334. switch (pudev->status) {
  335. case USBD_ADDRESSED:
  336. case USBD_CONFIGURED:
  337. #ifdef USBD_SELF_POWERED
  338. config_status = USB_STATUS_SELF_POWERED;
  339. #endif /* USBD_SELF_POWERED */
  340. if (pudev->remote_wakeup) {
  341. config_status |= USB_STATUS_REMOTE_WAKEUP;
  342. }
  343. usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&config_status, 2U);
  344. break;
  345. default:
  346. break;
  347. }
  348. break;
  349. case USB_REQTYPE_INTERFACE:
  350. switch (pudev->status) {
  351. case USBD_ADDRESSED:
  352. usbd_enum_error(pudev, req);
  353. break;
  354. case USBD_CONFIGURED:
  355. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  356. usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&config_status, 2U);
  357. } else {
  358. usbd_enum_error(pudev, req);
  359. }
  360. break;
  361. default:
  362. break;
  363. }
  364. break;
  365. case USB_REQTYPE_ENDPOINT:
  366. /* get enndpoint address */
  367. ep_addr = LOWBYTE(req->wIndex);
  368. switch (pudev->status) {
  369. case USBD_ADDRESSED:
  370. if (IS_NOT_EP0(ep_addr)) {
  371. usbd_enum_error(pudev, req);
  372. }
  373. break;
  374. case USBD_CONFIGURED:
  375. if ((ep_addr & 0x80U) == 0x80U) {
  376. if(pudev->in_ep[ep_addr & 0x7FU].stall) {
  377. endp_status = 0x0001U;
  378. }
  379. } else {
  380. if (pudev->out_ep[ep_addr].stall) {
  381. endp_status = 0x0001U;
  382. }
  383. }
  384. usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&endp_status, 2U);
  385. break;
  386. default:
  387. break;
  388. }
  389. break;
  390. default:
  391. usbd_enum_error(pudev, req);
  392. break;
  393. }
  394. }
  395. /*!
  396. \brief handle USB Clear_Feature request
  397. \param[in] pudev: pointer to USB device instance
  398. \param[in] req: USB device request
  399. \param[out] none
  400. \retval none
  401. */
  402. static void usbd_clearfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  403. {
  404. uint8_t ep_addr = 0U;
  405. switch (req->bmRequestType & USB_REQ_RECIPIENT_MASK) {
  406. case USB_REQTYPE_DEVICE:
  407. switch (pudev->status) {
  408. case USBD_ADDRESSED:
  409. case USBD_CONFIGURED:
  410. /* clear device remote wakeup feature */
  411. if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
  412. pudev->remote_wakeup = 0U;
  413. pudev->class_req_handler(pudev, req);
  414. USBD_CONTRL_STATUS_TX();
  415. } else if (USB_FEATURE_TEST_MODE == req->wValue) {
  416. /* can not clear test_mode feature */
  417. usbd_enum_error(pudev, req);
  418. } else {
  419. /* no operation */
  420. }
  421. break;
  422. default:
  423. break;
  424. }
  425. break;
  426. case USB_REQTYPE_INTERFACE:
  427. switch (pudev->status) {
  428. case USBD_ADDRESSED:
  429. usbd_enum_error (pudev, req);
  430. break;
  431. case USBD_CONFIGURED:
  432. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  433. /* no operation */
  434. } else {
  435. usbd_enum_error(pudev, req);
  436. }
  437. break;
  438. default:
  439. break;
  440. }
  441. break;
  442. case USB_REQTYPE_ENDPOINT:
  443. /* get endpoint address */
  444. ep_addr = LOWBYTE(req->wIndex);
  445. switch (pudev->status) {
  446. case USBD_ADDRESSED:
  447. if (IS_NOT_EP0(ep_addr)) {
  448. usbd_enum_error(pudev, req);
  449. }
  450. break;
  451. case USBD_CONFIGURED:
  452. /* clear endpoint halt feature */
  453. if (USB_FEATURE_ENDP_HALT == req->wValue) {
  454. if (IS_NOT_EP0(ep_addr)) {
  455. usbd_ep_clear_stall(pudev, ep_addr);
  456. }
  457. }
  458. pudev->class_req_handler(pudev, req);
  459. USBD_CONTRL_STATUS_TX();
  460. break;
  461. default:
  462. break;
  463. }
  464. break;
  465. default:
  466. usbd_enum_error(pudev, req);
  467. break;
  468. }
  469. }
  470. /*!
  471. \brief handle USB Set_Feature request
  472. \param[in] pudev: pointer to USB device instance
  473. \param[in] req: pointer to USB device request
  474. \param[out] none
  475. \retval none
  476. */
  477. static void usbd_setfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  478. {
  479. uint8_t ep_addr = 0U;
  480. switch (req->bmRequestType & USB_REQ_RECIPIENT_MASK) {
  481. case USB_REQTYPE_DEVICE:
  482. switch (pudev->status) {
  483. case USBD_ADDRESSED:
  484. case USBD_CONFIGURED:
  485. /* set device remote wakeup feature */
  486. if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
  487. pudev->remote_wakeup = 1U;
  488. USBD_CONTRL_STATUS_TX();
  489. }
  490. break;
  491. default:
  492. break;
  493. }
  494. break;
  495. case USB_REQTYPE_INTERFACE:
  496. switch (pudev->status) {
  497. case USBD_ADDRESSED:
  498. usbd_enum_error(pudev, req);
  499. break;
  500. case USBD_CONFIGURED:
  501. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  502. /* no operation */
  503. } else {
  504. usbd_enum_error(pudev, req);
  505. }
  506. break;
  507. default:
  508. break;
  509. }
  510. break;
  511. case USB_REQTYPE_ENDPOINT:
  512. /* get endpoint address */
  513. ep_addr = LOWBYTE(req->wIndex);
  514. switch (pudev->status) {
  515. case USBD_ADDRESSED:
  516. if (IS_NOT_EP0(ep_addr)) {
  517. usbd_enum_error(pudev, req);
  518. }
  519. break;
  520. case USBD_CONFIGURED:
  521. /* set endpoint halt feature */
  522. if (USB_FEATURE_ENDP_HALT == req->wValue) {
  523. if (IS_NOT_EP0(ep_addr)) {
  524. usbd_ep_stall(pudev, ep_addr);
  525. }
  526. }
  527. USBD_CONTRL_STATUS_TX();
  528. break;
  529. default:
  530. break;
  531. }
  532. break;
  533. default:
  534. usbd_enum_error(pudev, req);
  535. break;
  536. }
  537. }
  538. /*!
  539. \brief handle USB Set_Address request
  540. \param[in] pudev: pointer to USB device instance
  541. \param[in] req: pointer to USB device request
  542. \param[out] none
  543. \retval none
  544. */
  545. static void usbd_setaddress (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  546. {
  547. if ((0U == req->wIndex) && (0U == req->wLength)) {
  548. g_device_address = (uint8_t)(req->wValue) & 0x7FU;
  549. if (USBD_CONFIGURED == pudev->status) {
  550. usbd_enum_error(pudev, req);
  551. } else {
  552. USBD_CONTRL_STATUS_TX();
  553. if (0U != g_device_address) {
  554. pudev->status = USBD_ADDRESSED;
  555. } else {
  556. pudev->status = USBD_DEFAULT;
  557. }
  558. }
  559. } else {
  560. usbd_enum_error(pudev, req);
  561. }
  562. }
  563. /*!
  564. \brief handle USB Get_Descriptor request
  565. \param[in] pudev: pointer to USB device instance
  566. \param[in] req: pointer to USB device request
  567. \param[out] none
  568. \retval none
  569. */
  570. static void usbd_getdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  571. {
  572. if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQ_RECIPIENT_MASK)) {
  573. uint8_t *pbuf = NULL;
  574. uint8_t desc_type = (uint8_t)(req->wValue >> 8);
  575. uint8_t desc_index = (uint8_t)(req->wValue) & 0xFFU;
  576. uint16_t len = 0U;
  577. if ((desc_type <= 0x03U) && (desc_index <= 0x05U)) {
  578. /* call corresponding descriptor get function */
  579. pbuf = standard_descriptor_get[desc_type - 1U](pudev, desc_index, &len);
  580. }
  581. #ifdef LPM_ENABLED
  582. else if (USB_DESCTYPE_BOS == desc_type) {
  583. pbuf = usbd_bos_descriptor_get(pudev, &len);
  584. }
  585. #endif /* LPM_ENABLED */
  586. else {
  587. usbd_enum_error(pudev, req);
  588. }
  589. if ((0U != len) && (0U != req->wLength)) {
  590. len = MIN(len, req->wLength);
  591. usbd_ep_tx (pudev, EP0_IN, pbuf, len);
  592. }
  593. } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQ_RECIPIENT_MASK)) {
  594. if (NULL != pudev->class_req_handler) {
  595. /* get device class special descriptor */
  596. pudev->class_req_handler(pudev, req);
  597. }
  598. } else {
  599. }
  600. }
  601. /*!
  602. \brief handle USB Set_Descriptor request
  603. \param[in] pudev: pointer to USB device instance
  604. \param[in] req: pointer to USB device request
  605. \param[out] none
  606. \retval none
  607. */
  608. static void usbd_setdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  609. {
  610. /* no handle */
  611. }
  612. /*!
  613. \brief handle USB Get_Configuration request
  614. \param[in] pudev: pointer to USB device instance
  615. \param[in] req: pointer to USB device request
  616. \param[out] none
  617. \retval none
  618. */
  619. static void usbd_getconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  620. {
  621. uint32_t usbd_default_config = 0U;
  622. if (req->wLength != 1U) {
  623. usbd_enum_error(pudev, req);
  624. } else {
  625. switch (pudev->status) {
  626. case USBD_ADDRESSED:
  627. usbd_ep_tx (pudev, EP0_IN, (uint8_t *)&usbd_default_config, 1U);
  628. break;
  629. case USBD_CONFIGURED:
  630. usbd_ep_tx (pudev, EP0_IN, &pudev->config_num, 1U);
  631. break;
  632. default:
  633. usbd_enum_error(pudev, req);
  634. break;
  635. }
  636. }
  637. }
  638. /*!
  639. \brief handle USB Set_Configuration request
  640. \param[in] pudev: pointer to USB device instance
  641. \param[in] req: pointer to USB device request
  642. \param[out] none
  643. \retval none
  644. */
  645. static void usbd_setconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  646. {
  647. static uint8_t cfgidx;
  648. cfgidx = (uint8_t)(req->wValue);
  649. if (cfgidx > USBD_CFG_MAX_NUM) {
  650. usbd_enum_error(pudev, req);
  651. } else {
  652. switch (pudev->status) {
  653. case USBD_ADDRESSED:
  654. if (cfgidx){
  655. pudev->config_num = cfgidx;
  656. pudev->status = USBD_CONFIGURED;
  657. pudev->class_init(pudev, cfgidx);
  658. USBD_CONTRL_STATUS_TX();
  659. } else {
  660. USBD_CONTRL_STATUS_TX();
  661. }
  662. break;
  663. case USBD_CONFIGURED:
  664. if (0U == cfgidx) {
  665. pudev->status = USBD_ADDRESSED;
  666. pudev->config_num = cfgidx;
  667. pudev->class_deinit(pudev, cfgidx);
  668. USBD_CONTRL_STATUS_TX();
  669. } else if (cfgidx != pudev->config_num) {
  670. /* clear old configuration */
  671. pudev->class_deinit(pudev, pudev->config_num);
  672. /* set new configuration */
  673. pudev->config_num = cfgidx;
  674. pudev->class_init(pudev, cfgidx);
  675. USBD_CONTRL_STATUS_TX();
  676. } else {
  677. USBD_CONTRL_STATUS_TX();
  678. }
  679. break;
  680. default:
  681. break;
  682. }
  683. }
  684. }
  685. /*!
  686. \brief handle USB Get_Interface request
  687. \param[in] pudev: pointer to USB device instance
  688. \param[in] req: pointer to USB device request
  689. \param[out] none
  690. \retval none
  691. */
  692. static void usbd_getinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  693. {
  694. switch (pudev->status) {
  695. case USBD_ADDRESSED:
  696. usbd_enum_error(pudev, req);
  697. break;
  698. case USBD_CONFIGURED:
  699. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  700. if (NULL != pudev->class_req_handler) {
  701. pudev->class_req_handler(pudev, req);
  702. }
  703. } else {
  704. usbd_enum_error(pudev, req);
  705. }
  706. break;
  707. default:
  708. break;
  709. }
  710. }
  711. /*!
  712. \brief handle USB Set_Interface request
  713. \param[in] pudev: pointer to USB device instance
  714. \param[in] req: pointer to USB device request
  715. \param[out] none
  716. \retval none
  717. */
  718. static void usbd_setinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  719. {
  720. switch (pudev->status) {
  721. case USBD_ADDRESSED:
  722. usbd_enum_error(pudev, req);
  723. break;
  724. case USBD_CONFIGURED:
  725. if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
  726. if (NULL != pudev->class_req_handler) {
  727. pudev->class_req_handler(pudev, req);
  728. }
  729. USBD_CONTRL_STATUS_TX();
  730. } else {
  731. usbd_enum_error(pudev, req);
  732. }
  733. break;
  734. default:
  735. break;
  736. }
  737. }
  738. /*!
  739. \brief handle USB SynchFrame request
  740. \param[in] pudev: pointer to USB device instance
  741. \param[in] req: pointer to USB device request
  742. \param[out] none
  743. \retval none
  744. */
  745. static void usbd_synchframe (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  746. {
  747. /* no handle */
  748. }
  749. /*!
  750. \brief decode setup data packet
  751. \param[in] pudev: pointer to USB device instance
  752. \param[in] req: pointer to USB device request
  753. \param[out] none
  754. \retval none
  755. */
  756. void usbd_setup_request_parse (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  757. {
  758. uint8_t *setup_data = pudev->setup_packet;
  759. req->bmRequestType = *setup_data;
  760. req->bRequest = *(uint8_t *)(setup_data + 1U);
  761. req->wValue = SWAPBYTE (setup_data + 2U);
  762. req->wIndex = SWAPBYTE (setup_data + 4U);
  763. req->wLength = SWAPBYTE (setup_data + 6U);
  764. pudev->ctl_count = req->wLength;
  765. }
  766. /*!
  767. \brief handle USB enumeration error event
  768. \param[in] pudev: pointer to USB device instance
  769. \param[in] req: pointer to USB device request
  770. \param[out] none
  771. \retval none
  772. */
  773. void usbd_enum_error (usbd_core_handle_struct *pudev, usb_device_req_struct *req)
  774. {
  775. usbd_ep_stall(pudev, EP0);
  776. }