usbd_sdr.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /**
  2. **************************************************************************
  3. * @file usbd_sdr.c
  4. * @version v2.0.6
  5. * @date 2021-12-31
  6. * @brief usb standard device request
  7. **************************************************************************
  8. * Copyright notice & Disclaimer
  9. *
  10. * The software Board Support Package (BSP) that is made available to
  11. * download from Artery official website is the copyrighted work of Artery.
  12. * Artery authorizes customers to use, copy, and distribute the BSP
  13. * software and its related documentation for the purpose of design and
  14. * development in conjunction with Artery microcontrollers. Use of the
  15. * software is governed by this copyright notice and the following disclaimer.
  16. *
  17. * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  18. * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  19. * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  20. * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  21. * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  23. *
  24. **************************************************************************
  25. */
  26. #include "usbd_sdr.h"
  27. #include "common_config.h"
  28. #ifdef PRINTF_STDLIB
  29. #include <stdio.h>
  30. #endif
  31. #ifdef PRINTF_CUSTOM
  32. #include "tinystdio.h"
  33. #endif
  34. /** @addtogroup AT32F403A_407_middlewares_usbd_drivers
  35. * @{
  36. */
  37. /** @defgroup USBD_drivers_standard_request
  38. * @brief usb device standard_request
  39. * @{
  40. */
  41. /** @defgroup USBD_sdr_private_functions
  42. * @{
  43. */
  44. static usb_sts_type usbd_get_descriptor(usbd_core_type *udev);
  45. static usb_sts_type usbd_set_address(usbd_core_type *udev);
  46. static usb_sts_type usbd_get_status(usbd_core_type *udev);
  47. static usb_sts_type usbd_clear_feature(usbd_core_type *udev);
  48. static usb_sts_type usbd_set_feature(usbd_core_type *udev);
  49. static usb_sts_type usbd_get_configuration(usbd_core_type *udev);
  50. static usb_sts_type usbd_set_configuration(usbd_core_type *udev);
  51. /**
  52. * @brief usb parse standard setup request
  53. * @param setup: setup structure
  54. * @param buf: setup buffer
  55. * @retval none
  56. */
  57. void usbd_setup_request_parse(usb_setup_type *setup, uint8_t *buf)
  58. {
  59. setup->bmRequestType = *(uint8_t *) buf;
  60. setup->bRequest = *(uint8_t *) (buf + 1);
  61. setup->wValue = SWAPBYTE(buf + 2);
  62. setup->wIndex = SWAPBYTE(buf + 4);
  63. setup->wLength = SWAPBYTE(buf + 6);
  64. }
  65. /**
  66. * @brief get usb standard device description request
  67. * @param udev: to the structure of usbd_core_type
  68. * @retval status of usb_sts_type
  69. */
  70. static usb_sts_type usbd_get_descriptor(usbd_core_type *udev)
  71. {
  72. usb_sts_type ret = USB_OK;
  73. uint16_t len = 0;
  74. usbd_desc_t *desc = NULL;
  75. uint8_t desc_type = udev->setup.wValue >> 8;
  76. switch(desc_type)
  77. {
  78. case USB_DESCIPTOR_TYPE_DEVICE:
  79. desc = udev->desc_handler->get_device_descriptor();
  80. len = desc->length;
  81. if ((udev->setup.wLength == 64) || (udev->conn_state == USB_CONN_STATE_DEFAULT))
  82. len = 8;
  83. break;
  84. case USB_DESCIPTOR_TYPE_CONFIGURATION:
  85. desc = udev->desc_handler->get_device_configuration();
  86. len = desc->length;
  87. break;
  88. case USB_DESCIPTOR_TYPE_STRING:
  89. {
  90. uint8_t str_desc = (uint8_t)udev->setup.wValue;
  91. switch(str_desc)
  92. {
  93. case USB_LANGID_STRING:
  94. desc = udev->desc_handler->get_device_lang_id();
  95. len = desc->length;
  96. break;
  97. case USB_MFC_STRING:
  98. desc = udev->desc_handler->get_device_manufacturer_string();
  99. len = desc->length;
  100. break;
  101. case USB_PRODUCT_STRING:
  102. desc = udev->desc_handler->get_device_product_string();
  103. len = desc->length;
  104. break;
  105. case USB_SERIAL_STRING:
  106. desc = udev->desc_handler->get_device_serial_string();
  107. len = desc->length;
  108. break;
  109. case USB_CONFIG_STRING:
  110. desc = udev->desc_handler->get_device_config_string();
  111. len = desc->length;
  112. break;
  113. case USB_INTERFACE_STRING:
  114. desc = udev->desc_handler->get_device_interface_string();
  115. len = desc->length;
  116. break;
  117. default:
  118. usbd_ctrl_unsupport(udev);
  119. return ret;
  120. }
  121. break;
  122. }
  123. case USB_DESCIPTOR_TYPE_DEVICE_QUALIFIER:
  124. usbd_ctrl_unsupport(udev);
  125. break;
  126. case USB_DESCIPTOR_TYPE_OTHER_SPEED:
  127. usbd_ctrl_unsupport(udev);
  128. return ret;
  129. default:
  130. usbd_ctrl_unsupport(udev);
  131. return ret;
  132. }
  133. if(desc != NULL)
  134. {
  135. if((len != 0) && (udev->setup.wLength != 0))
  136. {
  137. len = MIN(len, udev->setup.wLength);
  138. usbd_ctrl_send(udev, desc->descriptor, len);
  139. }
  140. }
  141. return ret;
  142. }
  143. /**
  144. * @brief this request sets the device address
  145. * @param udev: to the structure of usbd_core_type
  146. * @retval status of usb_sts_type
  147. */
  148. static usb_sts_type usbd_set_address(usbd_core_type *udev)
  149. {
  150. usb_sts_type ret = USB_OK;
  151. usb_setup_type *setup = &udev->setup;
  152. uint8_t dev_addr;
  153. /* if wIndex or wLength are non-zero, then the behavior of
  154. the device is not specified
  155. */
  156. if(setup->wIndex == 0 && setup->wLength == 0)
  157. {
  158. dev_addr = (uint8_t)(setup->wValue) & 0x7f;
  159. /* device behavior when this request is received
  160. while the device is in the configured state is not specified.*/
  161. if(udev->conn_state == USB_CONN_STATE_CONFIGURED )
  162. {
  163. usbd_ctrl_unsupport(udev);
  164. }
  165. else
  166. {
  167. udev->device_addr = dev_addr;
  168. if(dev_addr != 0)
  169. {
  170. udev->conn_state = USB_CONN_STATE_ADDRESSED;
  171. }
  172. else
  173. {
  174. udev->conn_state = USB_CONN_STATE_DEFAULT;
  175. }
  176. usbd_ctrl_send_status(udev);
  177. }
  178. }
  179. else
  180. {
  181. usbd_ctrl_unsupport(udev);
  182. }
  183. return ret;
  184. }
  185. /**
  186. * @brief get usb status request
  187. * @param udev: to the structure of usbd_core_type
  188. * @retval status of usb_sts_type
  189. */
  190. static usb_sts_type usbd_get_status(usbd_core_type *udev)
  191. {
  192. usb_sts_type ret = USB_OK;
  193. switch(udev->conn_state)
  194. {
  195. case USB_CONN_STATE_ADDRESSED:
  196. case USB_CONN_STATE_CONFIGURED:
  197. if(udev->remote_wakup)
  198. {
  199. udev->config_status |= USB_CONF_REMOTE_WAKEUP;
  200. }
  201. usbd_ctrl_send(udev, (uint8_t *)(&udev->config_status), 2);
  202. break;
  203. default:
  204. usbd_ctrl_unsupport(udev);
  205. break;
  206. }
  207. return ret;
  208. }
  209. /**
  210. * @brief clear usb feature request
  211. * @param udev: to the structure of usbd_core_type
  212. * @retval status of usb_sts_type
  213. */
  214. static usb_sts_type usbd_clear_feature(usbd_core_type *udev)
  215. {
  216. usb_sts_type ret = USB_OK;
  217. usb_setup_type *setup = &udev->setup;
  218. switch(udev->conn_state)
  219. {
  220. case USB_CONN_STATE_ADDRESSED:
  221. case USB_CONN_STATE_CONFIGURED:
  222. if(setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
  223. {
  224. udev->remote_wakup = 0;
  225. udev->config_status &= ~USB_CONF_REMOTE_WAKEUP;
  226. udev->class_handler->setup_handler(udev, &udev->setup);
  227. usbd_ctrl_send_status(udev);
  228. }
  229. break;
  230. default:
  231. usbd_ctrl_unsupport(udev);
  232. break;
  233. }
  234. return ret;
  235. }
  236. /**
  237. * @brief set usb feature request
  238. * @param udev: to the structure of usbd_core_type
  239. * @retval status of usb_sts_type
  240. */
  241. static usb_sts_type usbd_set_feature(usbd_core_type *udev)
  242. {
  243. usb_sts_type ret = USB_OK;
  244. usb_setup_type *setup = &udev->setup;
  245. if(setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
  246. {
  247. udev->remote_wakup = 1;
  248. udev->class_handler->setup_handler(udev, &udev->setup);
  249. usbd_ctrl_send_status(udev);
  250. }
  251. return ret;
  252. }
  253. /**
  254. * @brief get usb configuration request
  255. * @param udev: to the structure of usbd_core_type
  256. * @retval status of usb_sts_type
  257. */
  258. static usb_sts_type usbd_get_configuration(usbd_core_type *udev)
  259. {
  260. usb_sts_type ret = USB_OK;
  261. usb_setup_type *setup = &udev->setup;
  262. if(setup->wLength != 1)
  263. {
  264. usbd_ctrl_unsupport(udev);
  265. }
  266. else
  267. {
  268. switch(udev->conn_state)
  269. {
  270. case USB_CONN_STATE_ADDRESSED:
  271. udev->default_config = 0;
  272. usbd_ctrl_send(udev, (uint8_t *)(&udev->default_config), 1);
  273. break;
  274. case USB_CONN_STATE_CONFIGURED:
  275. usbd_ctrl_send(udev, (uint8_t *)(&udev->dev_config), 1);
  276. break;
  277. default:
  278. usbd_ctrl_unsupport(udev);
  279. break;
  280. }
  281. }
  282. return ret;
  283. }
  284. /**
  285. * @brief sets the usb device configuration request
  286. * @param udev: to the structure of usbd_core_type
  287. * @retval status of usb_sts_type
  288. */
  289. static usb_sts_type usbd_set_configuration(usbd_core_type *udev)
  290. {
  291. usb_sts_type ret = USB_OK;
  292. static uint8_t config_value;
  293. usb_setup_type *setup = &udev->setup;
  294. config_value = (uint8_t)setup->wValue;
  295. if(setup->wIndex == 0 && setup->wLength == 0)
  296. {
  297. switch(udev->conn_state)
  298. {
  299. case USB_CONN_STATE_ADDRESSED:
  300. if(config_value)
  301. {
  302. udev->dev_config = config_value;
  303. udev->conn_state = USB_CONN_STATE_CONFIGURED;
  304. udev->class_handler->init_handler(udev);
  305. usbd_ctrl_send_status(udev);
  306. }
  307. else
  308. {
  309. usbd_ctrl_send_status(udev);
  310. }
  311. break;
  312. case USB_CONN_STATE_CONFIGURED:
  313. if(config_value == 0)
  314. {
  315. udev->conn_state = USB_CONN_STATE_ADDRESSED;
  316. udev->dev_config = config_value;
  317. udev->class_handler->clear_handler(udev);
  318. usbd_ctrl_send_status(udev);
  319. }
  320. else if(config_value == udev->dev_config)
  321. {
  322. udev->class_handler->clear_handler(udev);
  323. udev->dev_config = config_value;
  324. udev->class_handler->init_handler(udev);
  325. usbd_ctrl_send_status(udev);
  326. }
  327. else
  328. {
  329. usbd_ctrl_send_status(udev);
  330. }
  331. break;
  332. default:
  333. usbd_ctrl_unsupport(udev);
  334. break;
  335. }
  336. }
  337. else
  338. {
  339. usbd_ctrl_unsupport(udev);
  340. }
  341. return ret;
  342. }
  343. /**
  344. * @brief standard usb device requests
  345. * @param udev: to the structure of usbd_core_type
  346. * @retval status of usb_sts_type
  347. */
  348. usb_sts_type usbd_device_request(usbd_core_type *udev)
  349. {
  350. usb_sts_type ret = USB_OK;
  351. usb_setup_type *setup = &udev->setup;
  352. if((setup->bmRequestType & USB_REQ_TYPE_RESERVED) != USB_REQ_TYPE_STANDARD)
  353. {
  354. udev->class_handler->setup_handler(udev, &udev->setup);
  355. return ret;
  356. }
  357. switch(udev->setup.bRequest)
  358. {
  359. case USB_STD_REQ_GET_STATUS:
  360. usbd_get_status(udev);
  361. break;
  362. case USB_STD_REQ_CLEAR_FEATURE:
  363. usbd_clear_feature(udev);
  364. break;
  365. case USB_STD_REQ_SET_FEATURE:
  366. usbd_set_feature(udev);
  367. break;
  368. case USB_STD_REQ_SET_ADDRESS:
  369. usbd_set_address(udev);
  370. break;
  371. case USB_STD_REQ_GET_DESCRIPTOR:
  372. usbd_get_descriptor(udev);
  373. break;
  374. case USB_STD_REQ_GET_CONFIGURATION:
  375. usbd_get_configuration(udev);
  376. break;
  377. case USB_STD_REQ_SET_CONFIGURATION:
  378. usbd_set_configuration(udev);
  379. break;
  380. default:
  381. usbd_ctrl_unsupport(udev);
  382. break;
  383. }
  384. return ret;
  385. }
  386. /**
  387. * @brief standard usb interface requests
  388. * @param udev: to the structure of usbd_core_type
  389. * @retval status of usb_sts_type
  390. */
  391. usb_sts_type usbd_interface_request(usbd_core_type *udev)
  392. {
  393. usb_sts_type ret = USB_OK;
  394. usb_setup_type *setup = &udev->setup;
  395. switch(udev->conn_state)
  396. {
  397. case USB_CONN_STATE_CONFIGURED:
  398. udev->class_handler->setup_handler(udev, &udev->setup);
  399. if(setup->wLength == 0)
  400. {
  401. usbd_ctrl_send_status(udev);
  402. }
  403. break;
  404. default:
  405. usbd_ctrl_unsupport(udev);
  406. break;
  407. }
  408. return ret;
  409. }
  410. /**
  411. * @brief standard usb endpoint requests
  412. * @param udev: to the structure of usbd_core_type
  413. * @retval status of usb_sts_type
  414. */
  415. usb_sts_type usbd_endpoint_request(usbd_core_type *udev)
  416. {
  417. usb_sts_type ret = USB_OK;
  418. usb_setup_type *setup = &udev->setup;
  419. uint8_t ept_addr = LBYTE(setup->wIndex);
  420. usb_ept_info *ept_info;
  421. if((setup->bmRequestType & USB_REQ_TYPE_RESERVED) == USB_REQ_TYPE_CLASS)
  422. {
  423. udev->class_handler->setup_handler(udev, &udev->setup);
  424. }
  425. switch(setup->bRequest)
  426. {
  427. case USB_STD_REQ_GET_STATUS:
  428. switch(udev->conn_state)
  429. {
  430. case USB_CONN_STATE_ADDRESSED:
  431. if((ept_addr & 0x7F) != 0)
  432. {
  433. usbd_set_stall(udev, ept_addr);
  434. }
  435. break;
  436. case USB_CONN_STATE_CONFIGURED:
  437. {
  438. if((ept_addr & 0x80) != 0)
  439. {
  440. ept_info = &udev->ept_in[ept_addr & 0x7F];
  441. }
  442. else
  443. {
  444. ept_info = &udev->ept_out[ept_addr & 0x7F];
  445. }
  446. if(ept_info->stall == 1)
  447. {
  448. ept_info->status = 0x0001;
  449. }
  450. else
  451. {
  452. ept_info->status = 0x0000;
  453. }
  454. usbd_ctrl_send(udev, (uint8_t *)(&ept_info->status), 2);
  455. }
  456. break;
  457. default:
  458. usbd_ctrl_unsupport(udev);
  459. break;
  460. }
  461. break;
  462. case USB_STD_REQ_CLEAR_FEATURE:
  463. switch(udev->conn_state)
  464. {
  465. case USB_CONN_STATE_ADDRESSED:
  466. if((ept_addr != 0x00) && (ept_addr != 0x80))
  467. {
  468. usbd_set_stall(udev, ept_addr);
  469. }
  470. break;
  471. case USB_CONN_STATE_CONFIGURED:
  472. if(setup->wValue == USB_FEATURE_EPT_HALT)
  473. {
  474. if((ept_addr & 0x7F) != 0x00 )
  475. {
  476. usbd_clear_stall(udev, ept_addr);
  477. udev->class_handler->setup_handler(udev, &udev->setup);
  478. }
  479. usbd_ctrl_send_status(udev);
  480. }
  481. break;
  482. default:
  483. usbd_ctrl_unsupport(udev);
  484. break;
  485. }
  486. break;
  487. case USB_STD_REQ_SET_FEATURE:
  488. switch(udev->conn_state)
  489. {
  490. case USB_CONN_STATE_ADDRESSED:
  491. if((ept_addr != 0x00) && (ept_addr != 0x80))
  492. {
  493. usbd_set_stall(udev, ept_addr);
  494. }
  495. break;
  496. case USB_CONN_STATE_CONFIGURED:
  497. if(setup->wValue == USB_FEATURE_EPT_HALT)
  498. {
  499. if((ept_addr != 0x00) && (ept_addr != 0x80))
  500. {
  501. usbd_set_stall(udev, ept_addr);
  502. }
  503. }
  504. udev->class_handler->setup_handler(udev, &udev->setup);
  505. usbd_ctrl_send_status(udev);
  506. break;
  507. default:
  508. usbd_ctrl_unsupport(udev);
  509. break;
  510. }
  511. break;
  512. default:
  513. usbd_ctrl_unsupport(udev);
  514. break;
  515. }
  516. return ret;
  517. }
  518. /**
  519. * @}
  520. */
  521. /**
  522. * @}
  523. */
  524. /**
  525. * @}
  526. */