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.
 
 
 
 
 
 

623 rivejä
15 KiB

  1. /** @defgroup usb_standard_file Generic USB Standard Request Interface
  2. @ingroup USB
  3. @brief <b>Generic USB Standard Request Interface</b>
  4. @version 1.0.0
  5. @author @htmlonly &copy; @endhtmlonly 2010
  6. Gareth McMullin <gareth@blacksphere.co.nz>
  7. @date 10 March 2013
  8. LGPL License Terms @ref lgpl_license
  9. */
  10. /*
  11. * This file is part of the libopencm3 project.
  12. *
  13. * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
  14. *
  15. * This library is free software: you can redistribute it and/or modify
  16. * it under the terms of the GNU Lesser General Public License as published by
  17. * the Free Software Foundation, either version 3 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This library is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU Lesser General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Lesser General Public License
  26. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  27. */
  28. /**@{*/
  29. #include <string.h>
  30. #include <libopencm3/usb/usbd.h>
  31. #include "usb_private.h"
  32. int usbd_register_set_config_callback(usbd_device *usbd_dev,
  33. usbd_set_config_callback callback)
  34. {
  35. int i;
  36. for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) {
  37. if (usbd_dev->user_callback_set_config[i]) {
  38. if (usbd_dev->user_callback_set_config[i] == callback) {
  39. return 0;
  40. }
  41. continue;
  42. }
  43. usbd_dev->user_callback_set_config[i] = callback;
  44. return 0;
  45. }
  46. return -1;
  47. }
  48. void usbd_register_set_altsetting_callback(usbd_device *usbd_dev,
  49. usbd_set_altsetting_callback callback)
  50. {
  51. usbd_dev->user_callback_set_altsetting = callback;
  52. }
  53. static uint16_t build_config_descriptor(usbd_device *usbd_dev,
  54. uint8_t index, uint8_t *buf, uint16_t len)
  55. {
  56. uint8_t *tmpbuf = buf;
  57. const struct usb_config_descriptor *cfg = &usbd_dev->config[index];
  58. uint16_t count, total = 0, totallen = 0;
  59. uint16_t i, j, k;
  60. memcpy(buf, cfg, count = MIN(len, cfg->bLength));
  61. buf += count;
  62. len -= count;
  63. total += count;
  64. totallen += cfg->bLength;
  65. /* For each interface... */
  66. for (i = 0; i < cfg->bNumInterfaces; i++) {
  67. /* Interface Association Descriptor, if any */
  68. if (cfg->interface[i].iface_assoc) {
  69. const struct usb_iface_assoc_descriptor *assoc =
  70. cfg->interface[i].iface_assoc;
  71. memcpy(buf, assoc, count = MIN(len, assoc->bLength));
  72. buf += count;
  73. len -= count;
  74. total += count;
  75. totallen += assoc->bLength;
  76. }
  77. /* For each alternate setting... */
  78. for (j = 0; j < cfg->interface[i].num_altsetting; j++) {
  79. const struct usb_interface_descriptor *iface =
  80. &cfg->interface[i].altsetting[j];
  81. /* Copy interface descriptor. */
  82. memcpy(buf, iface, count = MIN(len, iface->bLength));
  83. buf += count;
  84. len -= count;
  85. total += count;
  86. totallen += iface->bLength;
  87. /* Copy extra bytes (function descriptors). */
  88. if (iface->extra) {
  89. memcpy(buf, iface->extra,
  90. count = MIN(len, iface->extralen));
  91. buf += count;
  92. len -= count;
  93. total += count;
  94. totallen += iface->extralen;
  95. }
  96. /* For each endpoint... */
  97. for (k = 0; k < iface->bNumEndpoints; k++) {
  98. const struct usb_endpoint_descriptor *ep =
  99. &iface->endpoint[k];
  100. memcpy(buf, ep, count = MIN(len, ep->bLength));
  101. buf += count;
  102. len -= count;
  103. total += count;
  104. totallen += ep->bLength;
  105. /* Copy extra bytes (class specific). */
  106. if (ep->extra) {
  107. memcpy(buf, ep->extra,
  108. count = MIN(len, ep->extralen));
  109. buf += count;
  110. len -= count;
  111. total += count;
  112. totallen += ep->extralen;
  113. }
  114. }
  115. }
  116. }
  117. /* Fill in wTotalLength.
  118. * Note that tmpbuf is sometimes not halfword-aligned */
  119. memcpy((tmpbuf + 2), &totallen, sizeof(uint16_t));
  120. return total;
  121. }
  122. static int usb_descriptor_type(uint16_t wValue)
  123. {
  124. return wValue >> 8;
  125. }
  126. static int usb_descriptor_index(uint16_t wValue)
  127. {
  128. return wValue & 0xFF;
  129. }
  130. static enum usbd_request_return_codes
  131. usb_standard_get_descriptor(usbd_device *usbd_dev,
  132. struct usb_setup_data *req,
  133. uint8_t **buf, uint16_t *len)
  134. {
  135. int i, array_idx, descr_idx;
  136. struct usb_string_descriptor *sd;
  137. descr_idx = usb_descriptor_index(req->wValue);
  138. switch (usb_descriptor_type(req->wValue)) {
  139. case USB_DT_DEVICE:
  140. *buf = (uint8_t *) usbd_dev->desc;
  141. *len = MIN(*len, usbd_dev->desc->bLength);
  142. return USBD_REQ_HANDLED;
  143. case USB_DT_CONFIGURATION:
  144. *buf = usbd_dev->ctrl_buf;
  145. *len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len);
  146. return USBD_REQ_HANDLED;
  147. case USB_DT_STRING:
  148. sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf;
  149. if (descr_idx == 0) {
  150. /* Send sane Language ID descriptor... */
  151. sd->wData[0] = USB_LANGID_ENGLISH_US;
  152. sd->bLength = sizeof(sd->bLength) +
  153. sizeof(sd->bDescriptorType) +
  154. sizeof(sd->wData[0]);
  155. *len = MIN(*len, sd->bLength);
  156. } else {
  157. array_idx = descr_idx - 1;
  158. if (!usbd_dev->strings) {
  159. /* Device doesn't support strings. */
  160. return USBD_REQ_NOTSUPP;
  161. }
  162. /* Check that string index is in range. */
  163. if (array_idx >= usbd_dev->num_strings) {
  164. return USBD_REQ_NOTSUPP;
  165. }
  166. /* Strings with Language ID differnet from
  167. * USB_LANGID_ENGLISH_US are not supported */
  168. if (req->wIndex != USB_LANGID_ENGLISH_US) {
  169. return USBD_REQ_NOTSUPP;
  170. }
  171. /* This string is returned as UTF16, hence the
  172. * multiplication
  173. */
  174. sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 +
  175. sizeof(sd->bLength) +
  176. sizeof(sd->bDescriptorType);
  177. *len = MIN(*len, sd->bLength);
  178. for (i = 0; i < (*len / 2) - 1; i++) {
  179. sd->wData[i] =
  180. usbd_dev->strings[array_idx][i];
  181. }
  182. }
  183. sd->bDescriptorType = USB_DT_STRING;
  184. *buf = (uint8_t *)sd;
  185. return USBD_REQ_HANDLED;
  186. }
  187. return USBD_REQ_NOTSUPP;
  188. }
  189. static enum usbd_request_return_codes
  190. usb_standard_set_address(usbd_device *usbd_dev,
  191. struct usb_setup_data *req, uint8_t **buf,
  192. uint16_t *len)
  193. {
  194. (void)req;
  195. (void)buf;
  196. (void)len;
  197. /* The actual address is only latched at the STATUS IN stage. */
  198. if ((req->bmRequestType != 0) || (req->wValue >= 128)) {
  199. return USBD_REQ_NOTSUPP;
  200. }
  201. usbd_dev->current_address = req->wValue;
  202. /*
  203. * Special workaround for STM32F10[57] that require the address
  204. * to be set here. This is undocumented!
  205. */
  206. if (usbd_dev->driver->set_address_before_status) {
  207. usbd_dev->driver->set_address(usbd_dev, req->wValue);
  208. }
  209. return USBD_REQ_HANDLED;
  210. }
  211. static enum usbd_request_return_codes
  212. usb_standard_set_configuration(usbd_device *usbd_dev,
  213. struct usb_setup_data *req,
  214. uint8_t **buf, uint16_t *len)
  215. {
  216. unsigned i;
  217. int found_index = -1;
  218. const struct usb_config_descriptor *cfg;
  219. (void)req;
  220. (void)buf;
  221. (void)len;
  222. if (req->wValue > 0) {
  223. for (i = 0; i < usbd_dev->desc->bNumConfigurations; i++) {
  224. if (req->wValue
  225. == usbd_dev->config[i].bConfigurationValue) {
  226. found_index = i;
  227. break;
  228. }
  229. }
  230. if (found_index < 0) {
  231. return USBD_REQ_NOTSUPP;
  232. }
  233. }
  234. usbd_dev->current_config = found_index + 1;
  235. if (usbd_dev->current_config > 0) {
  236. cfg = &usbd_dev->config[usbd_dev->current_config - 1];
  237. /* reset all alternate settings configuration */
  238. for (i = 0; i < cfg->bNumInterfaces; i++) {
  239. if (cfg->interface[i].cur_altsetting) {
  240. *cfg->interface[i].cur_altsetting = 0;
  241. }
  242. }
  243. }
  244. /* Reset all endpoints. */
  245. usbd_dev->driver->ep_reset(usbd_dev);
  246. if (usbd_dev->user_callback_set_config[0]) {
  247. /*
  248. * Flush control callbacks. These will be reregistered
  249. * by the user handler.
  250. */
  251. for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) {
  252. usbd_dev->user_control_callback[i].cb = NULL;
  253. }
  254. for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) {
  255. if (usbd_dev->user_callback_set_config[i]) {
  256. usbd_dev->user_callback_set_config[i](usbd_dev,
  257. req->wValue);
  258. }
  259. }
  260. }
  261. return USBD_REQ_HANDLED;
  262. }
  263. static enum usbd_request_return_codes
  264. usb_standard_get_configuration(usbd_device *usbd_dev,
  265. struct usb_setup_data *req,
  266. uint8_t **buf, uint16_t *len)
  267. {
  268. (void)req;
  269. if (*len > 1) {
  270. *len = 1;
  271. }
  272. if (usbd_dev->current_config > 0) {
  273. const struct usb_config_descriptor *cfg =
  274. &usbd_dev->config[usbd_dev->current_config - 1];
  275. (*buf)[0] = cfg->bConfigurationValue;
  276. } else {
  277. (*buf)[0] = 0;
  278. }
  279. return USBD_REQ_HANDLED;
  280. }
  281. static enum usbd_request_return_codes
  282. usb_standard_set_interface(usbd_device *usbd_dev,
  283. struct usb_setup_data *req,
  284. uint8_t **buf, uint16_t *len)
  285. {
  286. const struct usb_config_descriptor *cfx =
  287. &usbd_dev->config[usbd_dev->current_config - 1];
  288. const struct usb_interface *iface;
  289. (void)buf;
  290. if (req->wIndex >= cfx->bNumInterfaces) {
  291. return USBD_REQ_NOTSUPP;
  292. }
  293. iface = &cfx->interface[req->wIndex];
  294. if (req->wValue >= iface->num_altsetting) {
  295. return USBD_REQ_NOTSUPP;
  296. }
  297. if (iface->cur_altsetting) {
  298. *iface->cur_altsetting = req->wValue;
  299. } else if (req->wValue > 0) {
  300. return USBD_REQ_NOTSUPP;
  301. }
  302. if (usbd_dev->user_callback_set_altsetting) {
  303. usbd_dev->user_callback_set_altsetting(usbd_dev,
  304. req->wIndex,
  305. req->wValue);
  306. }
  307. *len = 0;
  308. return USBD_REQ_HANDLED;
  309. }
  310. static enum usbd_request_return_codes
  311. usb_standard_get_interface(usbd_device *usbd_dev,
  312. struct usb_setup_data *req,
  313. uint8_t **buf, uint16_t *len)
  314. {
  315. uint8_t *cur_altsetting;
  316. const struct usb_config_descriptor *cfx =
  317. &usbd_dev->config[usbd_dev->current_config - 1];
  318. if (req->wIndex >= cfx->bNumInterfaces) {
  319. return USBD_REQ_NOTSUPP;
  320. }
  321. *len = 1;
  322. cur_altsetting = cfx->interface[req->wIndex].cur_altsetting;
  323. (*buf)[0] = (cur_altsetting) ? *cur_altsetting : 0;
  324. return USBD_REQ_HANDLED;
  325. }
  326. static enum usbd_request_return_codes
  327. usb_standard_device_get_status(usbd_device *usbd_dev,
  328. struct usb_setup_data *req,
  329. uint8_t **buf, uint16_t *len)
  330. {
  331. (void)usbd_dev;
  332. (void)req;
  333. /* bit 0: self powered */
  334. /* bit 1: remote wakeup */
  335. if (*len > 2) {
  336. *len = 2;
  337. }
  338. (*buf)[0] = 0;
  339. (*buf)[1] = 0;
  340. return USBD_REQ_HANDLED;
  341. }
  342. static enum usbd_request_return_codes
  343. usb_standard_interface_get_status(usbd_device *usbd_dev,
  344. struct usb_setup_data *req,
  345. uint8_t **buf, uint16_t *len)
  346. {
  347. (void)usbd_dev;
  348. (void)req;
  349. /* not defined */
  350. if (*len > 2) {
  351. *len = 2;
  352. }
  353. (*buf)[0] = 0;
  354. (*buf)[1] = 0;
  355. return USBD_REQ_HANDLED;
  356. }
  357. static enum usbd_request_return_codes
  358. usb_standard_endpoint_get_status(usbd_device *usbd_dev,
  359. struct usb_setup_data *req,
  360. uint8_t **buf, uint16_t *len)
  361. {
  362. (void)req;
  363. if (*len > 2) {
  364. *len = 2;
  365. }
  366. (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0;
  367. (*buf)[1] = 0;
  368. return USBD_REQ_HANDLED;
  369. }
  370. static enum usbd_request_return_codes
  371. usb_standard_endpoint_stall(usbd_device *usbd_dev,
  372. struct usb_setup_data *req,
  373. uint8_t **buf, uint16_t *len)
  374. {
  375. (void)buf;
  376. (void)len;
  377. usbd_ep_stall_set(usbd_dev, req->wIndex, 1);
  378. return USBD_REQ_HANDLED;
  379. }
  380. static enum usbd_request_return_codes
  381. usb_standard_endpoint_unstall(usbd_device *usbd_dev,
  382. struct usb_setup_data *req,
  383. uint8_t **buf, uint16_t *len)
  384. {
  385. (void)buf;
  386. (void)len;
  387. usbd_ep_stall_set(usbd_dev, req->wIndex, 0);
  388. return USBD_REQ_HANDLED;
  389. }
  390. /* Do not appear to belong to the API, so are omitted from docs */
  391. /**@}*/
  392. enum usbd_request_return_codes
  393. _usbd_standard_request_device(usbd_device *usbd_dev,
  394. struct usb_setup_data *req, uint8_t **buf,
  395. uint16_t *len)
  396. {
  397. enum usbd_request_return_codes (*command)(usbd_device *usbd_dev,
  398. struct usb_setup_data *req,
  399. uint8_t **buf, uint16_t *len) = NULL;
  400. switch (req->bRequest) {
  401. case USB_REQ_CLEAR_FEATURE:
  402. case USB_REQ_SET_FEATURE:
  403. if (req->wValue == USB_FEAT_DEVICE_REMOTE_WAKEUP) {
  404. /* Device wakeup code goes here. */
  405. }
  406. if (req->wValue == USB_FEAT_TEST_MODE) {
  407. /* Test mode code goes here. */
  408. }
  409. break;
  410. case USB_REQ_SET_ADDRESS:
  411. /*
  412. * SET ADDRESS is an exception.
  413. * It is only processed at STATUS stage.
  414. */
  415. command = usb_standard_set_address;
  416. break;
  417. case USB_REQ_SET_CONFIGURATION:
  418. command = usb_standard_set_configuration;
  419. break;
  420. case USB_REQ_GET_CONFIGURATION:
  421. command = usb_standard_get_configuration;
  422. break;
  423. case USB_REQ_GET_DESCRIPTOR:
  424. command = usb_standard_get_descriptor;
  425. break;
  426. case USB_REQ_GET_STATUS:
  427. /*
  428. * GET_STATUS always responds with zero reply.
  429. * The application may override this behaviour.
  430. */
  431. command = usb_standard_device_get_status;
  432. break;
  433. case USB_REQ_SET_DESCRIPTOR:
  434. /* SET_DESCRIPTOR is optional and not implemented. */
  435. break;
  436. }
  437. if (!command) {
  438. return USBD_REQ_NOTSUPP;
  439. }
  440. return command(usbd_dev, req, buf, len);
  441. }
  442. enum usbd_request_return_codes
  443. _usbd_standard_request_interface(usbd_device *usbd_dev,
  444. struct usb_setup_data *req, uint8_t **buf,
  445. uint16_t *len)
  446. {
  447. enum usbd_request_return_codes (*command)(usbd_device *usbd_dev,
  448. struct usb_setup_data *req,
  449. uint8_t **buf, uint16_t *len) = NULL;
  450. switch (req->bRequest) {
  451. case USB_REQ_CLEAR_FEATURE:
  452. case USB_REQ_SET_FEATURE:
  453. /* not defined */
  454. break;
  455. case USB_REQ_GET_INTERFACE:
  456. command = usb_standard_get_interface;
  457. break;
  458. case USB_REQ_SET_INTERFACE:
  459. command = usb_standard_set_interface;
  460. break;
  461. case USB_REQ_GET_STATUS:
  462. command = usb_standard_interface_get_status;
  463. break;
  464. }
  465. if (!command) {
  466. return USBD_REQ_NOTSUPP;
  467. }
  468. return command(usbd_dev, req, buf, len);
  469. }
  470. enum usbd_request_return_codes
  471. _usbd_standard_request_endpoint(usbd_device *usbd_dev,
  472. struct usb_setup_data *req, uint8_t **buf,
  473. uint16_t *len)
  474. {
  475. enum usbd_request_return_codes (*command) (usbd_device *usbd_dev,
  476. struct usb_setup_data *req,
  477. uint8_t **buf, uint16_t *len) = NULL;
  478. switch (req->bRequest) {
  479. case USB_REQ_CLEAR_FEATURE:
  480. if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
  481. command = usb_standard_endpoint_unstall;
  482. }
  483. break;
  484. case USB_REQ_SET_FEATURE:
  485. if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
  486. command = usb_standard_endpoint_stall;
  487. }
  488. break;
  489. case USB_REQ_GET_STATUS:
  490. command = usb_standard_endpoint_get_status;
  491. break;
  492. case USB_REQ_SET_SYNCH_FRAME:
  493. /* FIXME: SYNCH_FRAME is not implemented. */
  494. /*
  495. * SYNCH_FRAME is used for synchronization of isochronous
  496. * endpoints which are not yet implemented.
  497. */
  498. break;
  499. }
  500. if (!command) {
  501. return USBD_REQ_NOTSUPP;
  502. }
  503. return command(usbd_dev, req, buf, len);
  504. }
  505. enum usbd_request_return_codes
  506. _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req,
  507. uint8_t **buf, uint16_t *len)
  508. {
  509. /* FIXME: Have class/vendor requests as well. */
  510. if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD) {
  511. return USBD_REQ_NOTSUPP;
  512. }
  513. switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) {
  514. case USB_REQ_TYPE_DEVICE:
  515. return _usbd_standard_request_device(usbd_dev, req, buf, len);
  516. case USB_REQ_TYPE_INTERFACE:
  517. return _usbd_standard_request_interface(usbd_dev, req,
  518. buf, len);
  519. case USB_REQ_TYPE_ENDPOINT:
  520. return _usbd_standard_request_endpoint(usbd_dev, req, buf, len);
  521. default:
  522. return USBD_REQ_NOTSUPP;
  523. }
  524. }