usbd_ctlreq.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. /**
  2. ******************************************************************************
  3. * @file usbd_req.c
  4. * @author MCD Application Team
  5. * @version V2.4.2
  6. * @date 11-December-2015
  7. * @brief This file provides the standard USB requests following chapter 9.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  12. *
  13. * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  14. * You may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at:
  16. *
  17. * http://www.st.com/software_license_agreement_liberty_v2
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *
  25. ******************************************************************************
  26. */
  27. /* Includes ------------------------------------------------------------------*/
  28. #include "usbd_ctlreq.h"
  29. #include "usbd_ioreq.h"
  30. static USBD_StatusTypeDef USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
  31. USBD_SetupReqTypedef *req);
  32. static USBD_StatusTypeDef USBD_SetAddress(USBD_HandleTypeDef *pdev,
  33. USBD_SetupReqTypedef *req);
  34. static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
  35. USBD_SetupReqTypedef *req);
  36. static USBD_StatusTypeDef USBD_GetConfig(USBD_HandleTypeDef *pdev,
  37. USBD_SetupReqTypedef *req);
  38. static USBD_StatusTypeDef USBD_GetStatus(USBD_HandleTypeDef *pdev,
  39. USBD_SetupReqTypedef *req);
  40. static USBD_StatusTypeDef USBD_SetFeature(USBD_HandleTypeDef *pdev,
  41. USBD_SetupReqTypedef *req);
  42. static USBD_StatusTypeDef USBD_ClrFeature(USBD_HandleTypeDef *pdev,
  43. USBD_SetupReqTypedef *req);
  44. static USBD_StatusTypeDef USBD_GetMicrosoftDescriptor(USBD_HandleTypeDef *pdev,
  45. USBD_SetupReqTypedef *req);
  46. static uint8_t USBD_GetLen(uint8_t *buf);
  47. /**
  48. * @brief USBD_StdDevReq
  49. * Handle standard usb device requests
  50. * @param pdev: device instance
  51. * @param req: usb request
  52. * @retval status
  53. */
  54. USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  55. {
  56. USBD_StatusTypeDef ret = USBD_OK;
  57. if(req->bRequest == USB_REQ_VENDOR_FEATURE) // Debug Äîáàâèòü îòâåò òîëüêî âî âðåìÿ ðàáîòû ñ âåíäîð ïðîòîêîëîì
  58. {
  59. ret = USBD_GetMicrosoftDescriptor(pdev, req);
  60. return ret;
  61. }
  62. // ~~~~~~~~~~~~~ Legacy support ~~~~~~~~~~~~~~~~~~~~~~~
  63. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  64. {
  65. case USB_REQ_TYPE_VENDOR:
  66. {
  67. ret = USBD_StdEPReq( pdev, req );
  68. return ret;
  69. }
  70. break;
  71. }
  72. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  73. switch (req->bRequest)
  74. {
  75. case USB_REQ_GET_DESCRIPTOR:
  76. ret = USBD_GetDescriptor(pdev, req);
  77. break;
  78. case USB_REQ_SET_ADDRESS:
  79. ret = USBD_SetAddress(pdev, req);
  80. break;
  81. case USB_REQ_SET_CONFIGURATION:
  82. ret = USBD_SetConfig(pdev, req);
  83. break;
  84. case USB_REQ_GET_CONFIGURATION:
  85. ret = USBD_GetConfig(pdev, req);
  86. break;
  87. case USB_REQ_GET_INTERFACE:
  88. ret = USBD_FAIL;
  89. break;
  90. case USB_REQ_GET_STATUS:
  91. ret = USBD_GetStatus(pdev, req);
  92. break;
  93. case USB_REQ_SET_FEATURE:
  94. ret = USBD_SetFeature(pdev, req);
  95. break;
  96. case USB_REQ_CLEAR_FEATURE:
  97. ret = USBD_ClrFeature(pdev, req);
  98. break;
  99. default:
  100. ret = USBD_FAIL;
  101. break;
  102. }
  103. return ret;
  104. }
  105. /**
  106. * @brief USBD_StdItfReq
  107. * Handle standard usb interface requests
  108. * @param pdev: device instance
  109. * @param req: usb request
  110. * @retval status
  111. */
  112. USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  113. {
  114. USBD_StatusTypeDef ret = USBD_OK;
  115. switch (pdev->dev_state)
  116. {
  117. case USBD_STATE_CONFIGURED:
  118. {
  119. if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
  120. {
  121. ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
  122. if( USBD_OK == ret )
  123. {
  124. if( req->wLength == 0 )
  125. {
  126. USBD_CtlSendStatus(pdev);
  127. }
  128. }
  129. else
  130. {
  131. ret = USBD_FAIL;
  132. }
  133. }
  134. else
  135. {
  136. ret = USBD_FAIL;
  137. }
  138. }
  139. break;
  140. default:
  141. ret = USBD_FAIL;
  142. break;
  143. }
  144. return ret;
  145. }
  146. /**
  147. * @brief USBD_StdEPReq
  148. * Handle standard usb endpoint requests
  149. * @param pdev: device instance
  150. * @param req: usb request
  151. * @retval status
  152. */
  153. USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  154. {
  155. uint8_t ep_addr;
  156. USBD_StatusTypeDef ret = USBD_OK;
  157. USBD_EndpointTypeDef *pep;
  158. ep_addr = LOBYTE(req->wIndex);
  159. /* Check if it is a USB-class request or a USB-vendor request */
  160. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  161. {
  162. case USB_REQ_TYPE_CLASS:
  163. case USB_REQ_TYPE_VENDOR:
  164. {
  165. // pass the request to the class handler
  166. ret = (USBD_StatusTypeDef)pdev->pClass->Setup (pdev, req);
  167. return ret;
  168. }
  169. break;
  170. }
  171. switch (req->bRequest)
  172. {
  173. case USB_REQ_SET_FEATURE :
  174. {
  175. switch (pdev->dev_state)
  176. {
  177. case USBD_STATE_ADDRESSED:
  178. {
  179. if ((ep_addr != 0x00) && (ep_addr != 0x80))
  180. {
  181. USBD_LL_StallEP(pdev, ep_addr);
  182. }
  183. }
  184. break;
  185. case USBD_STATE_CONFIGURED:
  186. {
  187. if (req->wValue == USB_FEATURE_EP_HALT)
  188. {
  189. if ((ep_addr != 0x00) && (ep_addr != 0x80))
  190. {
  191. USBD_LL_StallEP(pdev, ep_addr);
  192. }
  193. }
  194. ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
  195. if( USBD_OK == ret )
  196. {
  197. USBD_CtlSendStatus(pdev);
  198. }
  199. }
  200. break;
  201. default:
  202. ret = USBD_FAIL;
  203. break;
  204. }
  205. }
  206. break;
  207. case USB_REQ_CLEAR_FEATURE:
  208. {
  209. switch( pdev->dev_state )
  210. {
  211. case USBD_STATE_ADDRESSED:
  212. {
  213. if ((ep_addr != 0x00) && (ep_addr != 0x80))
  214. {
  215. USBD_LL_StallEP(pdev, ep_addr);
  216. }
  217. }
  218. break;
  219. case USBD_STATE_CONFIGURED:
  220. {
  221. if (req->wValue == USB_FEATURE_EP_HALT)
  222. {
  223. if ((ep_addr & 0x7F) != 0x00)
  224. {
  225. // First: clear EP status by default (VALID STATE)
  226. USBD_LL_ClearStallEP(pdev, ep_addr);
  227. // then: call user handler (user can override EP status now)
  228. ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
  229. }
  230. if( USBD_OK == ret )
  231. {
  232. USBD_CtlSendStatus(pdev);
  233. }
  234. }
  235. }
  236. break;
  237. default:
  238. ret = USBD_FAIL;
  239. break;
  240. }
  241. }
  242. break;
  243. case USB_REQ_GET_STATUS:
  244. {
  245. switch (pdev->dev_state)
  246. {
  247. case USBD_STATE_ADDRESSED:
  248. {
  249. if ((ep_addr & 0x7F) != 0x00)
  250. {
  251. USBD_LL_StallEP(pdev, ep_addr);
  252. }
  253. }
  254. break;
  255. case USBD_STATE_CONFIGURED:
  256. {
  257. pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
  258. &pdev->ep_out[ep_addr & 0x7F];
  259. if(USBD_LL_IsStallEP(pdev, ep_addr))
  260. {
  261. pep->status = 0x0001;
  262. }
  263. else
  264. {
  265. pep->status = 0x0000;
  266. }
  267. USBD_CtlSendData(pdev,
  268. (uint8_t *)&pep->status,
  269. 2);
  270. }
  271. break;
  272. default:
  273. ret = USBD_FAIL;
  274. break;
  275. }
  276. }
  277. break;
  278. default:
  279. ret = USBD_FAIL;
  280. break;
  281. }
  282. return ret;
  283. }
  284. /**
  285. * @brief USBD_GetMicrosoftDescriptor
  286. * Handle Get Microsoft Descriptor requests
  287. * @param pdev: device instance
  288. * @param req: usb request
  289. * @retval status
  290. */
  291. static USBD_StatusTypeDef USBD_GetMicrosoftDescriptor(USBD_HandleTypeDef *pdev,
  292. USBD_SetupReqTypedef *req)
  293. {
  294. uint16_t len;
  295. const uint8_t *pbuf = NULL;
  296. USBD_StatusTypeDef ret = USBD_OK;
  297. switch(req->wIndex)
  298. {
  299. case USB_REQ_EXT_COMPAT_ID_OS_FEATURE_DESCRIPTOR:
  300. {
  301. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  302. ret = USBD_CallGetDescriptorHandler( pdev,
  303. eGetDescriptorHandlerType_ExtCompatIdOsFeat,
  304. &pbuf,
  305. &len );
  306. #else
  307. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetExtCompatIdOsFeatureDescriptor );
  308. #endif
  309. }
  310. break;
  311. case USB_REQ_EXT_PROPERTIES_OS_FEATURE_DESCRIPTOR:
  312. {
  313. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  314. ret = USBD_CallGetDescriptorHandler( pdev,
  315. eGetDescriptorHandlerType_ExtPropertiesOsFeat,
  316. &pbuf,
  317. &len );
  318. #else
  319. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetExtPropertiesOsFeatureDescriptor );
  320. #endif
  321. }
  322. break;
  323. }
  324. if( USBD_FAIL != ret )
  325. {
  326. if( (len != 0) && (req->wLength != 0) )
  327. {
  328. len = MIN(len , req->wLength);
  329. USBD_CtlSendData(pdev,
  330. pbuf,
  331. len);
  332. }
  333. else
  334. {
  335. ret = USBD_FAIL;
  336. }
  337. }
  338. return ret;
  339. }
  340. /**
  341. * @brief USBD_GetDescriptor
  342. * Handle Get Descriptor requests
  343. * @param pdev: device instance
  344. * @param req: usb request
  345. * @retval status
  346. */
  347. static USBD_StatusTypeDef USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
  348. USBD_SetupReqTypedef *req)
  349. {
  350. uint16_t len;
  351. const uint8_t *pbuf = NULL;
  352. USBD_StatusTypeDef ret = USBD_OK;
  353. switch (req->wValue >> 8)
  354. {
  355. case USB_DESC_TYPE_DEVICE:
  356. {
  357. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  358. ret = USBD_CallGetDescriptorHandler( pdev,
  359. eGetDescriptorHandlerType_Device,
  360. &pbuf,
  361. &len );
  362. #else
  363. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetDeviceDescriptor );
  364. #endif
  365. }
  366. break;
  367. case USB_DESC_TYPE_CONFIGURATION:
  368. {
  369. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  370. ret = USBD_CallGetDescriptorHandler( pdev,
  371. eGetDescriptorHandlerType_Config,
  372. &pbuf,
  373. &len );
  374. #else
  375. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetConfigDescriptor );
  376. #endif
  377. }
  378. break;
  379. case USB_DESC_TYPE_STRING:
  380. {
  381. switch ((uint8_t)(req->wValue))
  382. {
  383. case USBD_IDX_LANGID_STR:
  384. {
  385. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  386. ret = USBD_CallGetDescriptorHandler( pdev,
  387. eGetDescriptorHandlerType_LangIdStr,
  388. &pbuf,
  389. &len );
  390. #else
  391. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetLangIDStrDescriptor );
  392. #endif
  393. }
  394. break;
  395. case USBD_IDX_MFC_STR:
  396. {
  397. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  398. ret = USBD_CallGetDescriptorHandler( pdev,
  399. eGetDescriptorHandlerType_ManufacturerStr,
  400. &pbuf,
  401. &len );
  402. #else
  403. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetManufacturerStrDescriptor );
  404. #endif
  405. }
  406. break;
  407. case USBD_IDX_PRODUCT_STR:
  408. {
  409. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  410. ret = USBD_CallGetDescriptorHandler( pdev,
  411. eGetDescriptorHandlerType_ProductStr,
  412. &pbuf,
  413. &len );
  414. #else
  415. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetProductStrDescriptor );
  416. #endif
  417. }
  418. break;
  419. #if USBD_IDX_SERIAL_STR != 0
  420. case USBD_IDX_SERIAL_STR:
  421. {
  422. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  423. ret = USBD_CallGetDescriptorHandler( pdev,
  424. eGetDescriptorHandlerType_SerialStr,
  425. &pbuf,
  426. &len );
  427. #else
  428. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetSerialStrDescriptor );
  429. #endif
  430. }
  431. break;
  432. #endif
  433. case USBD_IDX_CONFIG_STR:
  434. {
  435. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  436. ret = USBD_CallGetDescriptorHandler( pdev,
  437. eGetDescriptorHandlerType_ConfigurationStr,
  438. &pbuf,
  439. &len );
  440. #else
  441. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetConfigurationStrDescriptor );
  442. #endif
  443. }
  444. break;
  445. case USBD_IDX_INTERFACE_STR:
  446. {
  447. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  448. ret = USBD_CallGetDescriptorHandler( pdev,
  449. eGetDescriptorHandlerType_InterfaceStr,
  450. &pbuf,
  451. &len );
  452. #else
  453. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetInterfaceStrDescriptor );
  454. #endif
  455. }
  456. break;
  457. case USB_REQ_MS_OS_STRING_DESCRIPTOR:
  458. {
  459. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  460. ret = USBD_CallGetDescriptorHandler( pdev,
  461. eGetDescriptorHandlerType_MsOsString,
  462. &pbuf,
  463. &len );
  464. #else
  465. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pbuf, len, GetMsOsStringDescriptor );
  466. #endif
  467. }
  468. break;
  469. default:
  470. {
  471. #if (USBD_SUPPORT_USER_STRING == 1)
  472. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  473. if( NULL != pdev->pDesc && pdev->pDesc->GetUsrStrDescriptor )
  474. pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
  475. else
  476. if( NULL != pdev->pClass->pDesc && pdev->pClass->pDesc->GetUsrStrDescriptor )
  477. pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
  478. else
  479. ret = USBD_FAIL;
  480. #else
  481. if( NULL != pdev->pClass->pDesc && pdev->pClass->pDesc->GetUsrStrDescriptor )
  482. pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
  483. else
  484. ret = USBD_FAIL;
  485. #endif
  486. #else
  487. ret = USBD_FAIL;
  488. #endif
  489. }
  490. break;
  491. }
  492. }
  493. break;
  494. default:
  495. ret = USBD_FAIL;
  496. break;
  497. }
  498. if( USBD_FAIL != ret )
  499. {
  500. if( (len != 0) && (req->wLength != 0) )
  501. {
  502. len = MIN(len , req->wLength);
  503. USBD_CtlSendData(pdev,
  504. pbuf,
  505. len);
  506. }
  507. else
  508. {
  509. ret = USBD_FAIL;
  510. }
  511. }
  512. return ret;
  513. }
  514. /**
  515. * @brief USBD_SetAddress
  516. * Set device address
  517. * @param pdev: device instance
  518. * @param req: usb request
  519. * @retval status
  520. */
  521. static USBD_StatusTypeDef USBD_SetAddress(USBD_HandleTypeDef *pdev,
  522. USBD_SetupReqTypedef *req)
  523. {
  524. uint8_t dev_addr;
  525. USBD_StatusTypeDef ret = USBD_OK;
  526. if ((req->wIndex == 0) && (req->wLength == 0))
  527. {
  528. dev_addr = (uint8_t)(req->wValue) & 0x7F;
  529. if (pdev->dev_state == USBD_STATE_CONFIGURED)
  530. {
  531. ret = USBD_FAIL;
  532. }
  533. else
  534. {
  535. pdev->dev_address = dev_addr;
  536. USBD_LL_SetUSBAddress(pdev, dev_addr);
  537. USBD_CtlSendStatus(pdev);
  538. if (dev_addr != 0)
  539. {
  540. pdev->dev_state = USBD_STATE_ADDRESSED;
  541. }
  542. else
  543. {
  544. pdev->dev_state = USBD_STATE_DEFAULT;
  545. }
  546. }
  547. }
  548. else
  549. {
  550. ret = USBD_FAIL;
  551. }
  552. return ret;
  553. }
  554. /**
  555. * @brief USBD_SetConfig
  556. * Handle Set device configuration request
  557. * @param pdev: device instance
  558. * @param req: usb request
  559. * @retval status
  560. */
  561. static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
  562. USBD_SetupReqTypedef *req)
  563. {
  564. static uint8_t cfgidx;
  565. USBD_StatusTypeDef ret = USBD_OK;
  566. cfgidx = (uint8_t)(req->wValue);
  567. if (cfgidx > USBD_MAX_NUM_CONFIGURATION )
  568. {
  569. ret = USBD_FAIL;
  570. }
  571. else
  572. {
  573. switch (pdev->dev_state)
  574. {
  575. case USBD_STATE_ADDRESSED:
  576. {
  577. if(cfgidx > 0)
  578. {
  579. pdev->dev_config = cfgidx;
  580. pdev->dev_state = USBD_STATE_CONFIGURED;
  581. ret = USBD_SetClassConfig(pdev, cfgidx);
  582. if( USBD_OK == ret )
  583. {
  584. USBD_CtlSendStatus(pdev);
  585. }
  586. }
  587. else
  588. {
  589. USBD_CtlSendStatus(pdev);
  590. }
  591. }
  592. break;
  593. case USBD_STATE_CONFIGURED:
  594. {
  595. if (cfgidx == 0)
  596. {
  597. pdev->dev_state = USBD_STATE_ADDRESSED;
  598. pdev->dev_config = cfgidx;
  599. USBD_ClrClassConfig(pdev, cfgidx);
  600. USBD_CtlSendStatus(pdev);
  601. }
  602. else if (cfgidx != pdev->dev_config)
  603. {
  604. /* Clear old configuration */
  605. USBD_ClrClassConfig(pdev, pdev->dev_config);
  606. /* set new configuration */
  607. pdev->dev_config = cfgidx;
  608. ret = USBD_SetClassConfig(pdev, cfgidx);
  609. if( USBD_OK == ret )
  610. {
  611. USBD_CtlSendStatus(pdev);
  612. }
  613. }
  614. else
  615. {
  616. USBD_CtlSendStatus(pdev);
  617. }
  618. }
  619. break;
  620. default:
  621. ret = USBD_FAIL;
  622. break;
  623. }
  624. }
  625. return ret;
  626. }
  627. /**
  628. * @brief USBD_GetConfig
  629. * Handle Get device configuration request
  630. * @param pdev: device instance
  631. * @param req: usb request
  632. * @retval status
  633. */
  634. static USBD_StatusTypeDef USBD_GetConfig(USBD_HandleTypeDef *pdev,
  635. USBD_SetupReqTypedef *req)
  636. {
  637. USBD_StatusTypeDef ret = USBD_OK;
  638. if (req->wLength != 1)
  639. {
  640. ret = USBD_FAIL;
  641. }
  642. else
  643. {
  644. switch (pdev->dev_state )
  645. {
  646. case USBD_STATE_ADDRESSED:
  647. {
  648. pdev->dev_default_config = 0;
  649. USBD_CtlSendData(pdev,
  650. (uint8_t *)&pdev->dev_default_config,
  651. 1);
  652. }
  653. break;
  654. case USBD_STATE_CONFIGURED:
  655. {
  656. USBD_CtlSendData(pdev,
  657. (uint8_t *)&pdev->dev_config,
  658. 1);
  659. }
  660. break;
  661. default:
  662. ret = USBD_FAIL;
  663. break;
  664. }
  665. }
  666. return ret;
  667. }
  668. /**
  669. * @brief USBD_GetStatus
  670. * Handle Get Status request
  671. * @param pdev: device instance
  672. * @param req: usb request
  673. * @retval status
  674. */
  675. static USBD_StatusTypeDef USBD_GetStatus(USBD_HandleTypeDef *pdev,
  676. USBD_SetupReqTypedef *req)
  677. {
  678. USBD_StatusTypeDef ret = USBD_OK;
  679. switch (pdev->dev_state)
  680. {
  681. case USBD_STATE_ADDRESSED:
  682. case USBD_STATE_CONFIGURED:
  683. {
  684. #if ( USBD_SELF_POWERED == 1)
  685. pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
  686. #else
  687. pdev->dev_config_status = 0;
  688. #endif
  689. if (pdev->dev_remote_wakeup)
  690. {
  691. pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
  692. }
  693. USBD_CtlSendData(pdev,
  694. (const uint8_t *)& pdev->dev_config_status,
  695. 2);
  696. }
  697. break;
  698. default :
  699. ret = USBD_FAIL;
  700. break;
  701. }
  702. return ret;
  703. }
  704. /**
  705. * @brief USBD_SetFeature
  706. * Handle Set device feature request
  707. * @param pdev: device instance
  708. * @param req: usb request
  709. * @retval status
  710. */
  711. static USBD_StatusTypeDef USBD_SetFeature(USBD_HandleTypeDef *pdev,
  712. USBD_SetupReqTypedef *req)
  713. {
  714. USBD_StatusTypeDef ret = USBD_OK;
  715. if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
  716. {
  717. pdev->dev_remote_wakeup = 1;
  718. pdev->pClass->Setup(pdev, req);
  719. USBD_CtlSendStatus(pdev);
  720. }
  721. else
  722. {
  723. ret = USBD_FAIL;
  724. }
  725. return ret;
  726. }
  727. /**
  728. * @brief USBD_ClrFeature
  729. * Handle clear device feature request
  730. * @param pdev: device instance
  731. * @param req: usb request
  732. * @retval status
  733. */
  734. static USBD_StatusTypeDef USBD_ClrFeature(USBD_HandleTypeDef *pdev,
  735. USBD_SetupReqTypedef *req)
  736. {
  737. USBD_StatusTypeDef ret = USBD_OK;
  738. switch (pdev->dev_state)
  739. {
  740. case USBD_STATE_ADDRESSED:
  741. case USBD_STATE_CONFIGURED:
  742. {
  743. if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
  744. {
  745. pdev->dev_remote_wakeup = 0;
  746. pdev->pClass->Setup(pdev, req);
  747. USBD_CtlSendStatus(pdev);
  748. }
  749. else
  750. {
  751. ret = USBD_FAIL;
  752. }
  753. }
  754. break;
  755. default :
  756. ret = USBD_FAIL;
  757. break;
  758. }
  759. return ret;
  760. }
  761. /**
  762. * @brief USBD_ParseSetupRequest
  763. * Copy buffer into setup structure
  764. * @param pdev: device instance
  765. * @param req: usb request
  766. * @retval None
  767. */
  768. void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
  769. {
  770. req->bmRequest = *(uint8_t *) (pdata);
  771. req->bRequest = *(uint8_t *) (pdata + 1);
  772. req->wValue = SWAPBYTE (pdata + 2);
  773. req->wIndex = SWAPBYTE (pdata + 4);
  774. req->wLength = SWAPBYTE (pdata + 6);
  775. }
  776. /**
  777. * @brief USBD_CtlError
  778. * Handle USB low level Error
  779. * @param pdev: device instance
  780. * @param req: usb request
  781. * @retval None
  782. */
  783. void USBD_CtlError( USBD_HandleTypeDef *pdev,
  784. USBD_SetupReqTypedef *req)
  785. {
  786. USBD_LL_StallEP(pdev, 0x80);
  787. USBD_LL_StallEP(pdev, 0);
  788. }
  789. /**
  790. * @brief USBD_GetString
  791. * Convert Ascii string into unicode one
  792. * @param desc : descriptor buffer
  793. * @param unicode : Formatted string buffer (unicode)
  794. * @param len : descriptor length
  795. * @retval None
  796. */
  797. void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
  798. {
  799. uint8_t idx = 0;
  800. if (desc != NULL)
  801. {
  802. *len = USBD_GetLen(desc) * 2 + 2;
  803. unicode[idx++] = *len;
  804. unicode[idx++] = USB_DESC_TYPE_STRING;
  805. while (*desc != '\0')
  806. {
  807. unicode[idx++] = *desc++;
  808. unicode[idx++] = 0x00;
  809. }
  810. }
  811. }
  812. /**
  813. * @brief USBD_GetLen
  814. * return the string length
  815. * @param buf : pointer to the ascii string buffer
  816. * @retval string length
  817. */
  818. static uint8_t USBD_GetLen(uint8_t *buf)
  819. {
  820. uint8_t len = 0;
  821. while (*buf != '\0')
  822. {
  823. len++;
  824. buf++;
  825. }
  826. return len;
  827. }