usbd_sdr.c 14 KB

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