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.
 
 
 
 
 
 

317 rivejä
8.4 KiB

  1. /** @defgroup usb_control_file Generic USB Control Requests
  2. @ingroup USB
  3. @brief <b>Generic USB Control Requests</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 <stdlib.h>
  30. #include <libopencm3/usb/usbd.h>
  31. #include "usb_private.h"
  32. /*
  33. * According to the USB 2.0 specification, section 8.5.3, when a control
  34. * transfer is stalled, the pipe becomes idle. We provide one utility to stall
  35. * a transaction to reduce boilerplate code.
  36. */
  37. static void stall_transaction(usbd_device *usbd_dev)
  38. {
  39. usbd_ep_stall_set(usbd_dev, 0, 1);
  40. usbd_dev->control_state.state = IDLE;
  41. }
  42. /**
  43. * If we're replying with _some_ data, but less than the host is expecting,
  44. * then we normally just do a short transfer. But if it's short, but a
  45. * multiple of the endpoint max packet size, we need an explicit ZLP.
  46. * @param len how much data we want to transfer
  47. * @param wLength how much the host asked for
  48. * @param ep_size
  49. * @return
  50. */
  51. static bool needs_zlp(uint16_t len, uint16_t wLength, uint8_t ep_size)
  52. {
  53. if (len < wLength) {
  54. if (len && (len % ep_size == 0)) {
  55. return true;
  56. }
  57. }
  58. return false;
  59. }
  60. /* Register application callback function for handling USB control requests. */
  61. int usbd_register_control_callback(usbd_device *usbd_dev, uint8_t type,
  62. uint8_t type_mask,
  63. usbd_control_callback callback)
  64. {
  65. int i;
  66. for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) {
  67. if (usbd_dev->user_control_callback[i].cb) {
  68. continue;
  69. }
  70. usbd_dev->user_control_callback[i].type = type;
  71. usbd_dev->user_control_callback[i].type_mask = type_mask;
  72. usbd_dev->user_control_callback[i].cb = callback;
  73. return 0;
  74. }
  75. return -1;
  76. }
  77. static void usb_control_send_chunk(usbd_device *usbd_dev)
  78. {
  79. if (usbd_dev->desc->bMaxPacketSize0 <
  80. usbd_dev->control_state.ctrl_len) {
  81. /* Data stage, normal transmission */
  82. usbd_ep_write_packet(usbd_dev, 0,
  83. usbd_dev->control_state.ctrl_buf,
  84. usbd_dev->desc->bMaxPacketSize0);
  85. usbd_dev->control_state.state = DATA_IN;
  86. usbd_dev->control_state.ctrl_buf +=
  87. usbd_dev->desc->bMaxPacketSize0;
  88. usbd_dev->control_state.ctrl_len -=
  89. usbd_dev->desc->bMaxPacketSize0;
  90. } else {
  91. /* Data stage, end of transmission */
  92. usbd_ep_write_packet(usbd_dev, 0,
  93. usbd_dev->control_state.ctrl_buf,
  94. usbd_dev->control_state.ctrl_len);
  95. usbd_dev->control_state.state =
  96. usbd_dev->control_state.needs_zlp ?
  97. DATA_IN : LAST_DATA_IN;
  98. usbd_dev->control_state.needs_zlp = false;
  99. usbd_dev->control_state.ctrl_len = 0;
  100. usbd_dev->control_state.ctrl_buf = NULL;
  101. }
  102. }
  103. static int usb_control_recv_chunk(usbd_device *usbd_dev)
  104. {
  105. uint16_t packetsize = MIN(usbd_dev->desc->bMaxPacketSize0,
  106. usbd_dev->control_state.req.wLength -
  107. usbd_dev->control_state.ctrl_len);
  108. uint16_t size = usbd_ep_read_packet(usbd_dev, 0,
  109. usbd_dev->control_state.ctrl_buf +
  110. usbd_dev->control_state.ctrl_len,
  111. packetsize);
  112. if (size != packetsize) {
  113. stall_transaction(usbd_dev);
  114. return -1;
  115. }
  116. usbd_dev->control_state.ctrl_len += size;
  117. return packetsize;
  118. }
  119. static enum usbd_request_return_codes
  120. usb_control_request_dispatch(usbd_device *usbd_dev,
  121. struct usb_setup_data *req)
  122. {
  123. int i, result = 0;
  124. struct user_control_callback *cb = usbd_dev->user_control_callback;
  125. /* Call user command hook function. */
  126. for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) {
  127. if (cb[i].cb == NULL) {
  128. break;
  129. }
  130. if ((req->bmRequestType & cb[i].type_mask) == cb[i].type) {
  131. result = cb[i].cb(usbd_dev, req,
  132. &(usbd_dev->control_state.ctrl_buf),
  133. &(usbd_dev->control_state.ctrl_len),
  134. &(usbd_dev->control_state.complete));
  135. if (result == USBD_REQ_HANDLED ||
  136. result == USBD_REQ_NOTSUPP) {
  137. return result;
  138. }
  139. }
  140. }
  141. /* Try standard request if not already handled. */
  142. return _usbd_standard_request(usbd_dev, req,
  143. &(usbd_dev->control_state.ctrl_buf),
  144. &(usbd_dev->control_state.ctrl_len));
  145. }
  146. /* Handle commands and read requests. */
  147. static void usb_control_setup_read(usbd_device *usbd_dev,
  148. struct usb_setup_data *req)
  149. {
  150. usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf;
  151. usbd_dev->control_state.ctrl_len = req->wLength;
  152. if (usb_control_request_dispatch(usbd_dev, req)) {
  153. if (req->wLength) {
  154. usbd_dev->control_state.needs_zlp =
  155. needs_zlp(usbd_dev->control_state.ctrl_len,
  156. req->wLength,
  157. usbd_dev->desc->bMaxPacketSize0);
  158. /* Go to data out stage if handled. */
  159. usb_control_send_chunk(usbd_dev);
  160. } else {
  161. /* Go to status stage if handled. */
  162. usbd_ep_write_packet(usbd_dev, 0, NULL, 0);
  163. usbd_dev->control_state.state = STATUS_IN;
  164. }
  165. } else {
  166. /* Stall endpoint on failure. */
  167. stall_transaction(usbd_dev);
  168. }
  169. }
  170. static void usb_control_setup_write(usbd_device *usbd_dev,
  171. struct usb_setup_data *req)
  172. {
  173. if (req->wLength > usbd_dev->ctrl_buf_len) {
  174. stall_transaction(usbd_dev);
  175. return;
  176. }
  177. /* Buffer into which to write received data. */
  178. usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf;
  179. usbd_dev->control_state.ctrl_len = 0;
  180. /* Wait for DATA OUT stage. */
  181. if (req->wLength > usbd_dev->desc->bMaxPacketSize0) {
  182. usbd_dev->control_state.state = DATA_OUT;
  183. } else {
  184. usbd_dev->control_state.state = LAST_DATA_OUT;
  185. }
  186. usbd_ep_nak_set(usbd_dev, 0, 0);
  187. }
  188. /* Do not appear to belong to the API, so are omitted from docs */
  189. /**@}*/
  190. void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea)
  191. {
  192. struct usb_setup_data *req = &usbd_dev->control_state.req;
  193. (void)ea;
  194. usbd_dev->control_state.complete = NULL;
  195. usbd_ep_nak_set(usbd_dev, 0, 1);
  196. if (req->wLength == 0) {
  197. usb_control_setup_read(usbd_dev, req);
  198. } else if (req->bmRequestType & 0x80) {
  199. usb_control_setup_read(usbd_dev, req);
  200. } else {
  201. usb_control_setup_write(usbd_dev, req);
  202. }
  203. }
  204. void _usbd_control_out(usbd_device *usbd_dev, uint8_t ea)
  205. {
  206. (void)ea;
  207. switch (usbd_dev->control_state.state) {
  208. case DATA_OUT:
  209. if (usb_control_recv_chunk(usbd_dev) < 0) {
  210. break;
  211. }
  212. if ((usbd_dev->control_state.req.wLength -
  213. usbd_dev->control_state.ctrl_len) <=
  214. usbd_dev->desc->bMaxPacketSize0) {
  215. usbd_dev->control_state.state = LAST_DATA_OUT;
  216. }
  217. break;
  218. case LAST_DATA_OUT:
  219. if (usb_control_recv_chunk(usbd_dev) < 0) {
  220. break;
  221. }
  222. /*
  223. * We have now received the full data payload.
  224. * Invoke callback to process.
  225. */
  226. if (usb_control_request_dispatch(usbd_dev,
  227. &(usbd_dev->control_state.req))) {
  228. /* Go to status stage on success. */
  229. usbd_ep_write_packet(usbd_dev, 0, NULL, 0);
  230. usbd_dev->control_state.state = STATUS_IN;
  231. } else {
  232. stall_transaction(usbd_dev);
  233. }
  234. break;
  235. case STATUS_OUT:
  236. usbd_ep_read_packet(usbd_dev, 0, NULL, 0);
  237. usbd_dev->control_state.state = IDLE;
  238. if (usbd_dev->control_state.complete) {
  239. usbd_dev->control_state.complete(usbd_dev,
  240. &(usbd_dev->control_state.req));
  241. }
  242. usbd_dev->control_state.complete = NULL;
  243. break;
  244. default:
  245. stall_transaction(usbd_dev);
  246. }
  247. }
  248. void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea)
  249. {
  250. (void)ea;
  251. struct usb_setup_data *req = &(usbd_dev->control_state.req);
  252. switch (usbd_dev->control_state.state) {
  253. case DATA_IN:
  254. usb_control_send_chunk(usbd_dev);
  255. break;
  256. case LAST_DATA_IN:
  257. usbd_dev->control_state.state = STATUS_OUT;
  258. usbd_ep_nak_set(usbd_dev, 0, 0);
  259. break;
  260. case STATUS_IN:
  261. if (usbd_dev->control_state.complete) {
  262. usbd_dev->control_state.complete(usbd_dev,
  263. &(usbd_dev->control_state.req));
  264. }
  265. /* Exception: Handle SET ADDRESS function here... */
  266. if ((req->bmRequestType == 0) &&
  267. (req->bRequest == USB_REQ_SET_ADDRESS)) {
  268. usbd_dev->driver->set_address(usbd_dev, req->wValue);
  269. }
  270. usbd_dev->control_state.state = IDLE;
  271. break;
  272. default:
  273. stall_transaction(usbd_dev);
  274. }
  275. }