My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

udc.c 29KB

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