PageRenderTime 26ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/BmFW/AVR/ASF/Benchmark/Benchmark/src/asf/common/services/usb/udc/udc.c

http://usb-travis.googlecode.com/
C | 1030 lines | 612 code | 126 blank | 292 comment | 133 complexity | c80eda151c65216e982ad54ff020ea79 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, LGPL-2.0
  1. /**
  2. * \file
  3. *
  4. * \brief USB Device Controller (UDC)
  5. *
  6. * Copyright (C) 2009 Atmel Corporation. All rights reserved.
  7. *
  8. * \page License
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. *
  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. *
  20. * 3. The name of Atmel may not be used to endorse or promote products derived
  21. * from this software without specific prior written permission.
  22. *
  23. * 4. This software may only be redistributed and used in connection with an
  24. * Atmel AVR product.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  27. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  28. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  29. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  30. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  32. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  33. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  36. * DAMAGE.
  37. */
  38. #include "conf_usb.h"
  39. #include "usb_protocol.h"
  40. #include "udd.h"
  41. #include "udc_desc.h"
  42. #include "udi.h"
  43. #include "udc.h"
  44. /**
  45. * \addtogroup udc_group
  46. * @{
  47. */
  48. //! \name Internal variables to manage the USB device
  49. //! @{
  50. //! Device status state (see enum usb_device_status in usb_protocol.h)
  51. static le16_t udc_device_status;
  52. //! Device Configuration number selected by the USB host
  53. static uint8_t udc_num_configuration = 0;
  54. //! Pointer on the selected speed device configuration
  55. static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf;
  56. //! Pointer on interface descriptor used by SETUP request.
  57. static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface;
  58. //! @}
  59. //! \name Internal structure to store the USB device main strings
  60. //! @{
  61. /**
  62. * \brief Language ID of USB device (US ID by default)
  63. */
  64. COMPILER_WORD_ALIGNED
  65. static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = {
  66. .desc.bLength = sizeof(usb_str_lgid_desc_t),
  67. .desc.bDescriptorType = USB_DT_STRING,
  68. .string = {LE16(USB_LANGID_EN_US)}
  69. };
  70. /**
  71. * \brief USB device manufacture name storage
  72. * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared
  73. * by usb application configuration
  74. */
  75. #ifdef USB_DEVICE_MANUFACTURE_NAME
  76. static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME;
  77. #define USB_DEVICE_MANUFACTURE_NAME_SIZE (sizeof(udc_string_manufacturer_name)-1)
  78. #else
  79. #define USB_DEVICE_MANUFACTURE_NAME_SIZE 0
  80. #endif
  81. /**
  82. * \brief USB device product name storage
  83. * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared
  84. * by usb application configuration
  85. */
  86. #ifdef USB_DEVICE_PRODUCT_NAME
  87. static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME;
  88. #define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1)
  89. #else
  90. #define USB_DEVICE_PRODUCT_NAME_SIZE 0
  91. #endif
  92. /**
  93. * \brief USB device serial number storage
  94. * String is allocated only if USB_DEVICE_SERIAL_NAME is declared
  95. * by usb application configuration
  96. */
  97. #ifdef USB_DEVICE_SERIAL_NAME
  98. static uint8_t udc_string_serial_name[] = USB_DEVICE_SERIAL_NAME;
  99. #define USB_DEVICE_SERIAL_NAME_SIZE (sizeof(udc_string_serial_name)-1)
  100. #else
  101. #define USB_DEVICE_SERIAL_NAME_SIZE 0
  102. #endif
  103. /**
  104. * \brief USB device string descriptor
  105. * Structure used to transfer ASCII strings to USB String descriptor structure.
  106. */
  107. struct udc_string_desc_t {
  108. usb_str_desc_t header;
  109. le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \
  110. USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)];
  111. };
  112. COMPILER_WORD_ALIGNED
  113. static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {
  114. .header.bDescriptorType = USB_DT_STRING
  115. };
  116. //! @}
  117. usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void)
  118. {
  119. return udc_ptr_iface;
  120. }
  121. /**
  122. * \brief Returns a value to check the end of USB Configuration descriptor
  123. *
  124. * \return address after the last byte of USB Configuration descriptor
  125. */
  126. static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void)
  127. {
  128. return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *)
  129. udc_ptr_conf->desc +
  130. le16_to_cpu(udc_ptr_conf->desc->wTotalLength));
  131. }
  132. #if (0!=USB_DEVICE_MAX_EP)
  133. /**
  134. * \brief Search specific descriptor in global interface descriptor
  135. *
  136. * \param desc Address of interface descriptor
  137. * or previous specific descriptor found
  138. * \param desc_id Descriptor ID to search
  139. *
  140. * \return address of specific descriptor found
  141. * \return NULL if it is the end of global interface descriptor
  142. */
  143. static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t
  144. UDC_DESC_STORAGE * desc, uint8_t desc_id)
  145. {
  146. usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc;
  147. ptr_eof_desc = udc_get_eof_conf();
  148. // Go to next descriptor
  149. desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
  150. desc->bLength);
  151. // Check the end of configuration descriptor
  152. while (ptr_eof_desc > desc) {
  153. // If new interface descriptor is found,
  154. // then it is the end of the current global interface descriptor
  155. if (USB_DT_INTERFACE == desc->bDescriptorType)
  156. break; // End of global interface descriptor
  157. if (desc_id == desc->bDescriptorType)
  158. return desc; // Specific descriptor found
  159. // Go to next descriptor
  160. desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
  161. desc->bLength);
  162. }
  163. return NULL; // No specific descriptor found
  164. }
  165. #endif
  166. /**
  167. * \brief Search an interface descriptor
  168. * This routine updates the internal pointer udc_ptr_iface.
  169. *
  170. * \param iface_num Interface number to find in Configuration Descriptor
  171. * \param setting_num Setting number of interface to find
  172. *
  173. * \return 1 if found or 0 if not found
  174. */
  175. static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num)
  176. {
  177. usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc;
  178. if (0 == udc_num_configuration)
  179. return false;
  180. if (iface_num >= udc_ptr_conf->desc->bNumInterfaces)
  181. return false;
  182. // Start at the beginning of configuration descriptor
  183. udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)
  184. udc_ptr_conf->desc;
  185. // Check the end of configuration descriptor
  186. ptr_end_desc = udc_get_eof_conf();
  187. while (ptr_end_desc >
  188. (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) {
  189. if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) {
  190. // A interface descriptor is found
  191. // Check interface and alternate setting number
  192. if ((iface_num == udc_ptr_iface->bInterfaceNumber)
  193. && (setting_num ==
  194. udc_ptr_iface->
  195. bAlternateSetting))
  196. return true; // Interface found
  197. }
  198. // Go to next descriptor
  199. udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ((uint8_t
  200. *) udc_ptr_iface +
  201. udc_ptr_iface->bLength);
  202. }
  203. return false; // Interface not found
  204. }
  205. /**
  206. * \brief Disables an usb device interface (UDI)
  207. * This routine call the UDI corresponding to interface number
  208. *
  209. * \param iface_num Interface number to disable
  210. *
  211. * \return 1 if it is done or 0 if interface is not found
  212. */
  213. static bool udc_iface_disable(uint8_t iface_num)
  214. {
  215. udi_api_t UDC_DESC_STORAGE *udi_api;
  216. // Select first alternate setting of the interface to update udc_ptr_iface
  217. // before call iface->getsetting()
  218. if (!udc_update_iface_desc(iface_num, 0))
  219. return false;
  220. // Select the interface with the current alternate setting
  221. udi_api = udc_ptr_conf->udi_apis[iface_num];
  222. #if (0!=USB_DEVICE_MAX_EP)
  223. if (!udc_update_iface_desc(iface_num, udi_api->getsetting()))
  224. return false;
  225. // Start at the beginning of interface descriptor
  226. {
  227. usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
  228. ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
  229. while (1) {
  230. // Search Endpoint descriptor included in global interface descriptor
  231. ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
  232. udc_next_desc_in_iface((UDC_DESC_STORAGE
  233. usb_conf_desc_t *)
  234. ep_desc, USB_DT_ENDPOINT);
  235. if (NULL == ep_desc)
  236. break;
  237. // Free the endpoint used by the interface
  238. udd_ep_free(ep_desc->bEndpointAddress);
  239. }
  240. }
  241. #endif
  242. // Disable interface
  243. udi_api->disable();
  244. return true;
  245. }
  246. /**
  247. * \brief Enables an usb device interface (UDI)
  248. * This routine calls the UDI corresponding
  249. * to the interface and setting number.
  250. *
  251. * \param iface_num Interface number to enable
  252. * \param setting_num Setting number to enable
  253. *
  254. * \return 1 if it is done or 0 if interface is not found
  255. */
  256. static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num)
  257. {
  258. // Select the interface descriptor
  259. if (!udc_update_iface_desc(iface_num, setting_num))
  260. return false;
  261. #if (0!=USB_DEVICE_MAX_EP)
  262. usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
  263. // Start at the beginning of the global interface descriptor
  264. ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
  265. while (1) {
  266. // Search Endpoint descriptor included in the global interface descriptor
  267. ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
  268. udc_next_desc_in_iface((UDC_DESC_STORAGE
  269. usb_conf_desc_t *) ep_desc,
  270. USB_DT_ENDPOINT);
  271. if (NULL == ep_desc)
  272. break;
  273. // Alloc the endpoint used by the interface
  274. if (!udd_ep_alloc(ep_desc->bEndpointAddress,
  275. ep_desc->bmAttributes,
  276. le16_to_cpu
  277. (ep_desc->wMaxPacketSize)))
  278. return false;
  279. }
  280. #endif
  281. // Enable the interface
  282. return udc_ptr_conf->udi_apis[iface_num]->enable();
  283. }
  284. /**
  285. * \brief Reset the current configuration of the USB device,
  286. * This routines can be called by UDD when a RESET on the USB line occurs.
  287. */
  288. void udc_reset(void)
  289. {
  290. uint8_t iface_num;
  291. if (udc_num_configuration) {
  292. for (iface_num = 0;
  293. iface_num < udc_ptr_conf->desc->bNumInterfaces;
  294. iface_num++) {
  295. udc_iface_disable(iface_num);
  296. }
  297. }
  298. udc_num_configuration = 0;
  299. #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
  300. == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
  301. if (0 != (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status)) {
  302. // Remote wakeup is enabled then disable it
  303. UDC_REMOTEWAKEUP_DISABLE();
  304. }
  305. #endif
  306. udc_device_status =
  307. #if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED)
  308. CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED);
  309. #else
  310. CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED);
  311. #endif
  312. }
  313. void udc_sof_notify(void)
  314. {
  315. #ifndef UDC_INTERFACE_SOF_HANDLERS_DISABLED
  316. uint8_t iface_num;
  317. if (udc_num_configuration) {
  318. for (iface_num = 0;
  319. iface_num < udc_ptr_conf->desc->bNumInterfaces;
  320. iface_num++) {
  321. if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) {
  322. udc_ptr_conf->udi_apis[iface_num]->sof_notify();
  323. }
  324. }
  325. }
  326. #endif
  327. }
  328. /**
  329. * \brief Standard device request to get device status
  330. *
  331. * \return true if success
  332. */
  333. static bool udc_req_std_dev_get_status(void)
  334. {
  335. if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status))
  336. return false;
  337. udd_set_setup_payload(
  338. (uint8_t *) & udc_device_status,
  339. sizeof(udc_device_status));
  340. return true;
  341. }
  342. #if (0!=USB_DEVICE_MAX_EP)
  343. /**
  344. * \brief Standard endpoint request to get endpoint status
  345. *
  346. * \return true if success
  347. */
  348. static bool udc_req_std_ep_get_status(void)
  349. {
  350. static le16_t udc_ep_status;
  351. if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status))
  352. return false;
  353. udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req.
  354. wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0;
  355. udd_set_setup_payload(
  356. (uint8_t *) & udc_ep_status,
  357. sizeof(udc_ep_status));
  358. return true;
  359. }
  360. #endif
  361. /**
  362. * \brief Standard device request to change device status
  363. *
  364. * \return true if success
  365. */
  366. static bool udc_req_std_dev_clear_feature(void)
  367. {
  368. if (udd_g_ctrlreq.req.wLength != 0)
  369. return false;
  370. if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) {
  371. udc_device_status &= CPU_TO_LE16(~USB_DEV_STATUS_REMOTEWAKEUP);
  372. #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
  373. == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
  374. UDC_REMOTEWAKEUP_DISABLE();
  375. #endif
  376. return true;
  377. }
  378. return false;
  379. }
  380. #if (0!=USB_DEVICE_MAX_EP)
  381. /**
  382. * \brief Standard endpoint request to clear endpoint feature
  383. *
  384. * \return true if success
  385. */
  386. static bool udc_req_std_ep_clear_feature(void)
  387. {
  388. if (udd_g_ctrlreq.req.wLength != 0)
  389. return false;
  390. if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
  391. return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
  392. }
  393. return false;
  394. }
  395. #endif
  396. /**
  397. * \brief Standard device request to set a feature
  398. *
  399. * \return true if success
  400. */
  401. static bool udc_req_std_dev_set_feature(void)
  402. {
  403. if (udd_g_ctrlreq.req.wLength != 0)
  404. return false;
  405. switch (udd_g_ctrlreq.req.wValue) {
  406. case USB_DEV_FEATURE_REMOTE_WAKEUP:
  407. #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
  408. == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
  409. udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP);
  410. UDC_REMOTEWAKEUP_ENABLE();
  411. return true;
  412. #else
  413. return false;
  414. #endif
  415. #ifdef USB_DEVICE_HS_SUPPORT
  416. case USB_DEV_FEATURE_TEST_MODE:
  417. if (!udd_is_high_speed())
  418. break;
  419. if (udd_g_ctrlreq.req.wIndex & 0xff)
  420. break;
  421. // Unconfigure the device, terminating all ongoing requests
  422. udc_reset();
  423. switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) {
  424. case USB_DEV_TEST_MODE_J:
  425. udd_g_ctrlreq.callback = udd_test_mode_j;
  426. return true;
  427. case USB_DEV_TEST_MODE_K:
  428. udd_g_ctrlreq.callback = udd_test_mode_k;
  429. return true;
  430. case USB_DEV_TEST_MODE_SE0_NAK:
  431. udd_g_ctrlreq.callback = udd_test_mode_se0_nak;
  432. return true;
  433. case USB_DEV_TEST_MODE_PACKET:
  434. udd_g_ctrlreq.callback = udd_test_mode_packet;
  435. return true;
  436. case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports
  437. default:
  438. break;
  439. }
  440. break;
  441. #endif
  442. #ifdef USB_OTG
  443. // TODO
  444. case USB_DEV_FEATURE_OTG_B_HNP_ENABLE:
  445. break;
  446. case USB_DEV_FEATURE_OTG_A_HNP_SUPPORT:
  447. break;
  448. case USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT:
  449. break;
  450. #endif
  451. }
  452. return false;
  453. }
  454. /**
  455. * \brief Standard endpoint request to halt an endpoint
  456. *
  457. * \return true if success
  458. */
  459. #if (0!=USB_DEVICE_MAX_EP)
  460. static bool udc_req_std_epset_feature(void)
  461. {
  462. if (udd_g_ctrlreq.req.wLength != 0)
  463. return false;
  464. if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
  465. return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
  466. }
  467. return false;
  468. }
  469. #endif
  470. /**
  471. * \brief Change the address of device
  472. * Callback called at the end of request set address
  473. */
  474. static void udc_valid_address(void)
  475. {
  476. udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F);
  477. }
  478. /**
  479. * \brief Standard device request to set device address
  480. *
  481. * \return true if success
  482. */
  483. static bool udc_req_std_dev_set_address(void)
  484. {
  485. if (udd_g_ctrlreq.req.wLength != 0)
  486. return false;
  487. // The address must be changed at the end of setup request after the handshake
  488. // then we use a callback to change address
  489. udd_g_ctrlreq.callback = udc_valid_address;
  490. return true;
  491. }
  492. /**
  493. * \brief Standard device request to get device string descriptor
  494. *
  495. * \return true if success
  496. */
  497. static bool udc_req_std_dev_get_str_desc(void)
  498. {
  499. uint8_t i;
  500. uint8_t *str;
  501. uint8_t str_lgt=0;
  502. // Link payload pointer to the string corresponding at request
  503. switch (udd_g_ctrlreq.req.wValue & 0xff) {
  504. case 0:
  505. udd_set_setup_payload(
  506. (uint8_t *) & udc_string_desc_languageid,
  507. sizeof(udc_string_desc_languageid));
  508. break;
  509. #ifdef USB_DEVICE_MANUFACTURE_NAME
  510. case 1:
  511. str_lgt = USB_DEVICE_MANUFACTURE_NAME_SIZE;
  512. str = udc_string_manufacturer_name;
  513. break;
  514. #endif
  515. #ifdef USB_DEVICE_PRODUCT_NAME
  516. case 2:
  517. str_lgt = USB_DEVICE_PRODUCT_NAME_SIZE;
  518. str = udc_string_product_name;
  519. break;
  520. #endif
  521. #ifdef USB_DEVICE_SERIAL_NAME
  522. case 3:
  523. str_lgt = USB_DEVICE_SERIAL_NAME_SIZE;
  524. str = udc_string_serial_name;
  525. break;
  526. #endif
  527. default:
  528. #ifdef UDC_GET_EXTRA_STRING
  529. if (UDC_GET_EXTRA_STRING())
  530. break;
  531. #endif
  532. return false;
  533. }
  534. if (str_lgt != 0) {
  535. for(i = 0; i < str_lgt; i++) {
  536. udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]);
  537. }
  538. udc_string_desc.header.bLength = 2 + (str_lgt) * 2;
  539. udd_set_setup_payload(
  540. (uint8_t *) &udc_string_desc,
  541. udc_string_desc.header.bLength);
  542. }
  543. return true;
  544. }
  545. /**
  546. * \brief Standard device request to get descriptors about USB device
  547. *
  548. * \return true if success
  549. */
  550. static bool udc_req_std_dev_get_descriptor(void)
  551. {
  552. uint8_t conf_num;
  553. conf_num = udd_g_ctrlreq.req.wValue & 0xff;
  554. // Check descriptor ID
  555. switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) {
  556. case USB_DT_DEVICE:
  557. // Device descriptor requested
  558. #ifdef USB_DEVICE_HS_SUPPORT
  559. if (!udd_is_high_speed()) {
  560. udd_set_setup_payload(
  561. (uint8_t *) udc_config.confdev_hs,
  562. udc_config.confdev_hs->bLength);
  563. } else
  564. #endif
  565. {
  566. udd_set_setup_payload(
  567. (uint8_t *) udc_config.confdev_lsfs,
  568. udc_config.confdev_lsfs->bLength);
  569. }
  570. break;
  571. case USB_DT_CONFIGURATION:
  572. // Configuration descriptor requested
  573. #ifdef USB_DEVICE_HS_SUPPORT
  574. if (udd_is_high_speed()) {
  575. // HS descriptor
  576. if (conf_num >= udc_config.confdev_hs->
  577. bNumConfigurations)
  578. return false;
  579. udd_set_setup_payload(
  580. (uint8_t *)udc_config.conf_hs[conf_num].desc,
  581. le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
  582. } else
  583. #endif
  584. {
  585. // FS descriptor
  586. if (conf_num >= udc_config.confdev_lsfs->
  587. bNumConfigurations)
  588. return false;
  589. udd_set_setup_payload(
  590. (uint8_t *)udc_config.conf_lsfs[conf_num].desc,
  591. le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
  592. }
  593. ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
  594. USB_DT_CONFIGURATION;
  595. break;
  596. #ifdef USB_DEVICE_HS_SUPPORT
  597. case USB_DT_DEVICE_QUALIFIER:
  598. // Device qualifier descriptor requested
  599. udd_set_setup_payload(
  600. (uint8_t *) udc_config.qualifier,
  601. udc_config.qualifier->bLength);
  602. break;
  603. case USB_DT_OTHER_SPEED_CONFIGURATION:
  604. // Other configuration descriptor requested
  605. if (!udd_is_high_speed()) {
  606. // HS descriptor
  607. if (conf_num >= udc_config.confdev_hs->
  608. bNumConfigurations)
  609. return false;
  610. udd_set_setup_payload(
  611. (uint8_t *)udc_config.conf_hs[conf_num].desc,
  612. le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
  613. } else {
  614. // FS descriptor
  615. if (conf_num >= udc_config.confdev_lsfs->
  616. bNumConfigurations)
  617. return false;
  618. udd_set_setup_payload(
  619. (uint8_t *)udc_config.conf_lsfs[conf_num].desc,
  620. le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
  621. }
  622. ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
  623. USB_DT_OTHER_SPEED_CONFIGURATION;
  624. break;
  625. #endif
  626. case USB_DT_STRING:
  627. // String descriptor requested
  628. if (!udc_req_std_dev_get_str_desc()) {
  629. return false;
  630. }
  631. break;
  632. default:
  633. // Unknown descriptor requested
  634. return false;
  635. }
  636. // if the descriptor is larger than length requested, then reduce it
  637. if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size)
  638. udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength;
  639. return true;
  640. }
  641. /**
  642. * \brief Standard device request to get configuration number
  643. *
  644. * \return true if success
  645. */
  646. static bool udc_req_std_dev_get_configuration(void)
  647. {
  648. if (udd_g_ctrlreq.req.wLength != 1)
  649. return false;
  650. udd_set_setup_payload(&udc_num_configuration,1);
  651. return true;
  652. }
  653. /**
  654. * \brief Standard device request to enable a configuration
  655. *
  656. * \return true if success
  657. */
  658. static bool udc_req_std_dev_set_configuration(void)
  659. {
  660. uint8_t iface_num;
  661. // Check request length
  662. if (udd_g_ctrlreq.req.wLength != 0)
  663. return false;
  664. // Authorize configuration only if the address is valid
  665. if (!udd_getaddress())
  666. return false;
  667. // Check the configuration number requested
  668. #ifdef USB_DEVICE_HS_SUPPORT
  669. if (udd_is_high_speed()) {
  670. // HS descriptor
  671. if ((udd_g_ctrlreq.req.wValue & 0xFF) >
  672. udc_config.confdev_hs->bNumConfigurations)
  673. return false;
  674. } else
  675. #endif
  676. {
  677. // FS descriptor
  678. if ((udd_g_ctrlreq.req.wValue & 0xFF) >
  679. udc_config.confdev_lsfs->bNumConfigurations)
  680. return false;
  681. }
  682. // Reset current configuration
  683. udc_reset();
  684. // Enable new configuration
  685. udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF;
  686. if (udc_num_configuration == 0) {
  687. return true; // Default empty configuration requested
  688. }
  689. // Update pointer of the configuration descriptor
  690. #ifdef USB_DEVICE_HS_SUPPORT
  691. if (udd_is_high_speed()) {
  692. // HS descriptor
  693. udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1];
  694. } else
  695. #endif
  696. {
  697. // FS descriptor
  698. udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1];
  699. }
  700. // Enable all interfaces of the selected configuration
  701. for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces;
  702. iface_num++) {
  703. if (!udc_iface_enable(iface_num, 0))
  704. return false;
  705. }
  706. return true;
  707. }
  708. /**
  709. * \brief Standard interface request
  710. * to get the alternate setting number of an interface
  711. *
  712. * \return true if success
  713. */
  714. static bool udc_req_std_iface_get_setting(void)
  715. {
  716. static uint8_t udc_iface_setting;
  717. uint8_t iface_num;
  718. udi_api_t UDC_DESC_STORAGE *udi_api;
  719. if (udd_g_ctrlreq.req.wLength != 1)
  720. return false; // Error in request
  721. if (!udc_num_configuration)
  722. return false; // The device is not is configured state yet
  723. // Check the interface number included in the request
  724. iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
  725. if (iface_num >= udc_ptr_conf->desc->bNumInterfaces)
  726. return false;
  727. // Select first alternate setting of the interface to update udc_ptr_iface
  728. // before call iface->getsetting()
  729. if (!udc_update_iface_desc(iface_num, 0))
  730. return false;
  731. // Get alternate setting from UDI
  732. udi_api = udc_ptr_conf->udi_apis[iface_num];
  733. udc_iface_setting = udi_api->getsetting();
  734. // Link value to payload pointer of request
  735. udd_set_setup_payload(&udc_iface_setting,1);
  736. return true;
  737. }
  738. /**
  739. * \brief Standard interface request
  740. * to set an alternate setting of an interface
  741. *
  742. * \return true if success
  743. */
  744. static bool udc_req_std_iface_set_setting(void)
  745. {
  746. uint8_t iface_num, setting_num;
  747. if (udd_g_ctrlreq.req.wLength != 0)
  748. return false; // Error in request
  749. if (!udc_num_configuration)
  750. return false; // The device is not is configured state yet
  751. iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
  752. setting_num = udd_g_ctrlreq.req.wValue & 0xFF;
  753. // Disable current setting
  754. if (!udc_iface_disable(iface_num))
  755. return false;
  756. // Enable new setting
  757. return udc_iface_enable(iface_num, setting_num);
  758. }
  759. /**
  760. * \brief Main routine to manage the standard USB SETUP request
  761. *
  762. * \return true if the request is supported
  763. */
  764. static bool udc_reqstd(void)
  765. {
  766. if (Udd_setup_is_in()) {
  767. // GET Standard Requests
  768. if (udd_g_ctrlreq.req.wLength == 0)
  769. return false; // Error for USB host
  770. if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
  771. // Standard Get Device request
  772. switch (udd_g_ctrlreq.req.bRequest) {
  773. case USB_REQ_GET_STATUS:
  774. return udc_req_std_dev_get_status();
  775. case USB_REQ_GET_DESCRIPTOR:
  776. return udc_req_std_dev_get_descriptor();
  777. case USB_REQ_GET_CONFIGURATION:
  778. return udc_req_std_dev_get_configuration();
  779. }
  780. }
  781. if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
  782. // Standard Get Interface request
  783. switch (udd_g_ctrlreq.req.bRequest) {
  784. case USB_REQ_GET_INTERFACE:
  785. return udc_req_std_iface_get_setting();
  786. }
  787. }
  788. #if (0!=USB_DEVICE_MAX_EP)
  789. if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
  790. // Standard Get Endpoint request
  791. switch (udd_g_ctrlreq.req.bRequest) {
  792. case USB_REQ_GET_STATUS:
  793. return udc_req_std_ep_get_status();
  794. }
  795. }
  796. #endif
  797. } else {
  798. // SET Standard Requests
  799. if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
  800. // Standard Set Device request
  801. switch (udd_g_ctrlreq.req.bRequest) {
  802. case USB_REQ_SET_ADDRESS:
  803. return udc_req_std_dev_set_address();
  804. case USB_REQ_CLEAR_FEATURE:
  805. return udc_req_std_dev_clear_feature();
  806. case USB_REQ_SET_FEATURE:
  807. return udc_req_std_dev_set_feature();
  808. case USB_REQ_SET_CONFIGURATION:
  809. return udc_req_std_dev_set_configuration();
  810. case USB_REQ_SET_DESCRIPTOR:
  811. /* Not supported (defined as optional by the USB 2.0 spec) */
  812. break;
  813. }
  814. }
  815. if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
  816. // Standard Set Interface request
  817. switch (udd_g_ctrlreq.req.bRequest) {
  818. case USB_REQ_SET_INTERFACE:
  819. return udc_req_std_iface_set_setting();
  820. }
  821. }
  822. #if (0!=USB_DEVICE_MAX_EP)
  823. if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
  824. // Standard Set Endpoint request
  825. switch (udd_g_ctrlreq.req.bRequest) {
  826. case USB_REQ_CLEAR_FEATURE:
  827. return udc_req_std_ep_clear_feature();
  828. case USB_REQ_SET_FEATURE:
  829. return udc_req_std_epset_feature();
  830. }
  831. }
  832. #endif
  833. }
  834. return false;
  835. }
  836. /**
  837. * \brief Send the SETUP interface request to UDI
  838. *
  839. * \return true if the request is supported
  840. */
  841. static bool udc_req_iface(void)
  842. {
  843. uint8_t iface_num;
  844. udi_api_t UDC_DESC_STORAGE *udi_api;
  845. if (0 == udc_num_configuration)
  846. return false; // The device is not is configured state yet
  847. // Check interface number
  848. iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
  849. if (iface_num >= udc_ptr_conf->desc->bNumInterfaces)
  850. return false;
  851. //* To update udc_ptr_iface with the selected interface in request
  852. // Select first alternate setting of interface to update udc_ptr_iface
  853. // before calling udi_api->getsetting()
  854. if (!udc_update_iface_desc(iface_num, 0))
  855. return false;
  856. // Select the interface with the current alternate setting
  857. udi_api = udc_ptr_conf->udi_apis[iface_num];
  858. if (!udc_update_iface_desc(iface_num, udi_api->getsetting()))
  859. return false;
  860. // Send the SETUP request to the UDI corresponding to the interface number
  861. return udi_api->setup();
  862. }
  863. /**
  864. * \brief Main routine to manage the USB SETUP request.
  865. *
  866. * This function parses a USB SETUP request and submits an appropriate
  867. * response back to the host or, in the case of SETUP OUT requests
  868. * with data, sets up a buffer for receiving the data payload.
  869. *
  870. * The main standard requests defined by the USB 2.0 standard are handled
  871. * internally. The interface requests are sent to UDI, and the specific request
  872. * sent to a specific application callback.
  873. *
  874. * \return true if the request is supported, else the request is stalled by UDD
  875. */
  876. bool udc_process_setup(void)
  877. {
  878. // By default no data (receive/send) and no callbacks registered
  879. udd_g_ctrlreq.payload_size = 0;
  880. udd_g_ctrlreq.callback = NULL;
  881. udd_g_ctrlreq.over_under_run = NULL;
  882. if (Udd_setup_is_in()) {
  883. if (udd_g_ctrlreq.req.wLength == 0)
  884. return false; // Error from USB host
  885. }
  886. // If standard request then try to decode it in UDC
  887. if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) {
  888. if (udc_reqstd())
  889. return true;
  890. }
  891. // If interface request then try to decode it in UDI
  892. if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) {
  893. if (udc_req_iface())
  894. return true;
  895. }
  896. // Here SETUP request unknown by UDC and UDIs
  897. #ifdef USB_DEVICE_SPECIFIC_REQUEST
  898. // Try to decode it in specific callback
  899. return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,...
  900. #else
  901. return false;
  902. #endif
  903. }
  904. //! @}