Kiibohd Controller
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
Repozitorijs ir arhivēts. Tam var aplūkot failus un to var klonēt, bet nevar iesūtīt jaunas izmaiņas, kā arī atvērt jaunas problēmas/izmaiņu pieprasījumus.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /* Copyright (c) 2011,2012 Simon Schubert <[email protected]>.
  2. * Modifications by Jacob Alexander 2014-2016 <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. // ----- Compiler Includes -----
  18. #include <sys/types.h>
  19. #include <inttypes.h>
  20. #include <string.h>
  21. // ----- Local Includes -----
  22. #include "usb.h"
  23. #include "usb-internal.h"
  24. #include "dfu.desc.h"
  25. // ----- Variables -----
  26. static uint8_t ep0_buf[2][EP0_BUFSIZE] __attribute__((aligned(4)));
  27. struct usbd_t usb;
  28. // ----- Functions -----
  29. /**
  30. * Returns: 0 when this is was the last transfer, 1 if there is still
  31. * more to go.
  32. */
  33. /* Defaults to EP0 for now */
  34. static int usb_tx_next(struct usbd_ep_pipe_state_t *s)
  35. {
  36. /**
  37. * Us being here means the previous transfer just completed
  38. * successfully. That means the host just toggled its data
  39. * sync bit, and so do we.
  40. */
  41. s->data01 ^= 1;
  42. if (s->transfer_size > 0) {
  43. size_t thislen = s->transfer_size;
  44. if (thislen > s->ep_maxsize)
  45. thislen = s->ep_maxsize;
  46. void *addr = s->data_buf + s->pos;
  47. if (s->copy_source) {
  48. /* Bounce buffer mode */
  49. addr = s->data_buf;
  50. memcpy(addr, s->copy_source + s->pos, thislen);
  51. }
  52. s->pos += thislen;
  53. s->transfer_size -= thislen;
  54. usb_queue_next(s, addr, thislen);
  55. s->pingpong ^= 1;
  56. return (1);
  57. }
  58. /**
  59. * All data has been shipped. Do we need to send a short
  60. * packet?
  61. */
  62. if (s->short_transfer) {
  63. s->short_transfer = 0;
  64. usb_queue_next(s, NULL, 0);
  65. s->pingpong ^= 1;
  66. return (1);
  67. }
  68. if (s->callback)
  69. s->callback(s->data_buf, s->pos, s->callback_data);
  70. return (0);
  71. }
  72. static void setup_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  73. {
  74. s->data_buf = (void *)buf;
  75. s->copy_source = NULL;
  76. s->transfer_size = len;
  77. s->pos = 0;
  78. s->callback = cb;
  79. s->callback_data = cb_data;
  80. if (s->transfer_size > reqlen)
  81. s->transfer_size = reqlen;
  82. if (s->transfer_size < reqlen && s->transfer_size % s->ep_maxsize == 0)
  83. s->short_transfer = 1;
  84. else
  85. s->short_transfer = 0;
  86. }
  87. static void submit_tx(struct usbd_ep_pipe_state_t *s)
  88. {
  89. /* usb_tx_next() flips the data toggle, so invert this here. */
  90. s->data01 ^= 1;
  91. usb_tx_next(s);
  92. }
  93. /**
  94. * send USB data (IN device transaction)
  95. *
  96. * So far this function is specialized for EP 0 only.
  97. *
  98. * Returns: size to be transfered, or -1 on error.
  99. */
  100. int usb_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  101. {
  102. setup_tx(s, buf, len, reqlen, cb, cb_data);
  103. submit_tx(s);
  104. return (s->transfer_size);
  105. }
  106. /**
  107. * Returns: 0 when this is was the last transfer, 1 if there is still
  108. * more to go.
  109. */
  110. /* Defaults to EP0 for now */
  111. /* XXX pass usb_stat to validate pingpong */
  112. static int usb_rx_next(struct usbd_ep_pipe_state_t *s)
  113. {
  114. /**
  115. * Us being here means the previous transfer just completed
  116. * successfully. That means the host just toggled its data
  117. * sync bit, and so do we.
  118. */
  119. s->data01 ^= 1;
  120. size_t thislen = usb_ep_get_transfer_size(s);
  121. s->transfer_size -= thislen;
  122. s->pos += thislen;
  123. /**
  124. * We're done with this buffer now. Switch the pingpong now
  125. * before we might have to receive the next piece of data.
  126. */
  127. s->pingpong ^= 1;
  128. /**
  129. * If this is a short transfer, or we received what we
  130. * expected, we're done.
  131. */
  132. if (thislen < s->ep_maxsize || s->transfer_size == 0) {
  133. if (s->callback)
  134. s->callback(s->data_buf, s->pos, s->callback_data);
  135. return (0);
  136. }
  137. /**
  138. * Otherwise we still need to receive more data.
  139. */
  140. size_t nextlen = s->transfer_size;
  141. if (nextlen > s->ep_maxsize)
  142. nextlen = s->ep_maxsize;
  143. void *addr = s->data_buf + s->pos;
  144. usb_queue_next(s, addr, nextlen);
  145. return (1);
  146. }
  147. /**
  148. * Receive USB data (OUT device transaction)
  149. *
  150. * Returns: size to be received, or -1 on error.
  151. */
  152. int usb_rx(struct usbd_ep_pipe_state_t *s, void *buf, size_t len, ep_callback_t cb, void *cb_data)
  153. {
  154. s->data_buf = buf;
  155. s->transfer_size = len;
  156. s->pos = 0;
  157. s->callback = cb;
  158. s->callback_data = cb_data;
  159. size_t thislen = s->transfer_size;
  160. if (thislen > s->ep_maxsize)
  161. thislen = s->ep_maxsize;
  162. usb_queue_next(s, s->data_buf, thislen);
  163. return (len);
  164. }
  165. int usb_ep0_tx_cp(const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  166. {
  167. struct usbd_ep_pipe_state_t *s = &usb.ep_state[0].tx;
  168. enum usb_ep_pingpong pp = s->pingpong;
  169. setup_tx(s, ep0_buf[pp], len, reqlen, cb, cb_data);
  170. s->copy_source = buf;
  171. submit_tx(s);
  172. return (s->transfer_size);
  173. }
  174. void *usb_ep0_tx_inplace_prepare(size_t len)
  175. {
  176. enum usb_ep_pingpong pp = usb.ep_state[0].tx.pingpong;
  177. if (len > EP0_BUFSIZE)
  178. return (NULL);
  179. return (ep0_buf[pp]);
  180. }
  181. int usb_ep0_tx(void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
  182. {
  183. return (usb_tx(&usb.ep_state[0].tx, buf, len, reqlen, cb, cb_data));
  184. }
  185. int usb_ep0_rx(void *buf, size_t len, ep_callback_t cb, void *cb_data)
  186. {
  187. return (usb_rx(&usb.ep_state[0].rx, buf, len, cb, cb_data));
  188. }
  189. const struct usbd_config *
  190. usb_get_config_data(int config)
  191. {
  192. if (config <= 0)
  193. config = usb.config;
  194. if (config != 0)
  195. return (usb.identity->configs[config - 1]);
  196. else
  197. return (NULL);
  198. }
  199. static int usb_set_config(int config)
  200. {
  201. const struct usbd_config *config_data;
  202. if (usb.config != 0) {
  203. config_data = usb_get_config_data(-1);
  204. if (config_data != NULL && config_data->init != NULL)
  205. config_data->init(0);
  206. }
  207. if (config != 0) {
  208. /* XXX overflow */
  209. config_data = usb_get_config_data(config);
  210. if (config_data != NULL && config_data->init != NULL)
  211. config_data->init(1);
  212. }
  213. usb.config = config;
  214. return (0);
  215. }
  216. static int usb_set_interface(int iface, int altsetting)
  217. {
  218. int iface_count = 0;
  219. for (struct usbd_function_ctx_header *fh = &usb.functions;
  220. fh != NULL;
  221. fh = fh->next, iface_count += fh->function->interface_count) {
  222. if (iface - iface_count < fh->function->interface_count) {
  223. if (fh->function->configure != NULL)
  224. return (fh->function->configure(iface,
  225. iface - iface_count,
  226. altsetting,
  227. fh));
  228. /* Default to a single altsetting */
  229. if (altsetting != 0)
  230. return (-1);
  231. else
  232. return (0);
  233. }
  234. }
  235. return (-1);
  236. }
  237. static int usb_tx_config_desc(int idx, int reqlen)
  238. {
  239. const struct usb_desc_config_t *d = usb.identity->configs[idx]->desc;
  240. usb_ep0_tx_cp(d, d->wTotalLength, reqlen, NULL, NULL);
  241. return (0);
  242. }
  243. static int usb_tx_string_desc(int idx, int reqlen)
  244. {
  245. struct usb_desc_string_t * const *d;
  246. for (d = usb.identity->string_descs; idx != 0 && *d != NULL; ++d)
  247. --idx;
  248. switch ((uintptr_t)*d) {
  249. case (uintptr_t)NULL:
  250. return (-1);
  251. case (uintptr_t)USB_DESC_STRING_SERIALNO:
  252. return (usb_tx_serialno(reqlen));
  253. default:
  254. usb_ep0_tx_cp(*d, (*d)->bLength, reqlen, NULL, NULL);
  255. return (0);
  256. }
  257. }
  258. static void usb_handle_control_done(void *data, ssize_t len, void *cbdata)
  259. {
  260. if (usb.state == USBD_STATE_SETTING_ADDRESS) {
  261. usb.state = USBD_STATE_ADDRESS;
  262. usb_set_addr(usb.address);
  263. }
  264. usb_setup_control();
  265. }
  266. void usb_handle_control_status_cb(ep_callback_t cb)
  267. {
  268. /* empty status transfer */
  269. switch (usb.ctrl_dir) {
  270. case USB_CTRL_REQ_IN:
  271. usb.ep_state[0].rx.data01 = USB_DATA01_DATA1;
  272. usb_rx(&usb.ep_state[0].rx, NULL, 0, cb, NULL);
  273. break;
  274. default:
  275. usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
  276. usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, cb, NULL);
  277. break;
  278. }
  279. }
  280. void usb_handle_control_status(int fail)
  281. {
  282. if (fail) {
  283. usb_pipe_stall(&usb.ep_state[0].rx);
  284. usb_pipe_stall(&usb.ep_state[0].tx);
  285. } else {
  286. usb_handle_control_status_cb(usb_handle_control_done);
  287. }
  288. }
  289. /**
  290. * Dispatch non-standard request to registered USB functions.
  291. */
  292. static void usb_handle_control_nonstd(struct usb_ctrl_req_t *req)
  293. {
  294. /* XXX filter by interface/endpoint? */
  295. for (struct usbd_function_ctx_header *fh = &usb.functions; fh != NULL; fh = fh->next) {
  296. /* ->control() returns != 0 if it handled the request */
  297. if (fh->function->control != NULL &&
  298. fh->function->control(req, fh))
  299. return;
  300. }
  301. usb_handle_control_status(-1);
  302. }
  303. /**
  304. *
  305. * Great resource: http://wiki.osdev.org/Universal_Serial_Bus
  306. *
  307. * Control Transfers
  308. * -----------------
  309. *
  310. * A control transfer consists of a SETUP transaction (1), zero or
  311. * more data transactions (IN or OUT) (2), and a final status
  312. * transaction (3).
  313. *
  314. * Token sequence (data toggle):
  315. * 1. SETUP (0)
  316. * (2a. OUT (1) ... (toggling))
  317. * 3a. IN (1)
  318. *
  319. * or
  320. * 1. SETUP (0)
  321. * 2b. IN (1) ... (toggling)
  322. * 3b. OUT (1)
  323. *
  324. * Report errors by STALLing the control EP after (1) or (2), so that
  325. * (3) will STALL. Seems we need to clear the STALL after that so
  326. * that the next SETUP can make it through.
  327. *
  328. *
  329. */
  330. /**
  331. * The following code is not written defensively, but instead only
  332. * asserts values that are essential for correct execution. It
  333. * accepts a superset of the protocol defined by the standard. We do
  334. * this to save space.
  335. */
  336. static void usb_handle_control(void *data, ssize_t len, void *cbdata)
  337. {
  338. struct usb_ctrl_req_t *req = data;
  339. uint16_t zero16 = 0;
  340. int fail = 1;
  341. usb.ctrl_dir = req->in;
  342. if (req->type != USB_CTRL_REQ_STD) {
  343. usb_handle_control_nonstd(req);
  344. return;
  345. }
  346. /* Only STD requests here */
  347. switch (req->bRequest) {
  348. case USB_CTRL_REQ_GET_STATUS:
  349. /**
  350. * Because we don't support remote wakeup or
  351. * self-powered operation, and we are specialized to
  352. * only EP 0 so far, all GET_STATUS replies are just
  353. * empty.
  354. */
  355. usb_ep0_tx_cp(&zero16, sizeof(zero16), req->wLength, NULL, NULL);
  356. break;
  357. case USB_CTRL_REQ_CLEAR_FEATURE:
  358. case USB_CTRL_REQ_SET_FEATURE:
  359. /**
  360. * Nothing to do. Maybe return STALLs on illegal
  361. * accesses?
  362. */
  363. break;
  364. case USB_CTRL_REQ_SET_ADDRESS:
  365. /**
  366. * We must keep our previous address until the end of
  367. * the status stage; therefore we can't set the
  368. * address right now. Since this is a special case,
  369. * the EP 0 handler will take care of this later on.
  370. */
  371. usb.address = req->wValue & 0x7f;
  372. usb.state = USBD_STATE_SETTING_ADDRESS;
  373. break;
  374. case USB_CTRL_REQ_GET_DESCRIPTOR:
  375. switch (req->wValue >> 8) {
  376. case USB_DESC_DEV:
  377. usb_ep0_tx_cp(usb.identity->dev_desc, usb.identity->dev_desc->bLength,
  378. req->wLength, NULL, NULL);
  379. fail = 0;
  380. break;
  381. case USB_DESC_CONFIG:
  382. fail = usb_tx_config_desc(req->wValue & 0xff, req->wLength);
  383. break;
  384. case USB_DESC_STRING:
  385. fail = usb_tx_string_desc(req->wValue & 0xff, req->wLength);
  386. break;
  387. default:
  388. fail = -1;
  389. break;
  390. }
  391. /* we set fail already, so we can go directly to `err' */
  392. goto err;
  393. case USB_CTRL_REQ_GET_CONFIGURATION:
  394. usb_ep0_tx_cp(&usb.config, 1, req->wLength, NULL, NULL); /* XXX implicit LE */
  395. break;
  396. case USB_CTRL_REQ_SET_CONFIGURATION:
  397. if (usb_set_config(req->wValue) < 0)
  398. goto err;
  399. break;
  400. case USB_CTRL_REQ_GET_INTERFACE:
  401. /* We only support iface setting 0 */
  402. usb_ep0_tx_cp(&zero16, 1, req->wLength, NULL, NULL);
  403. break;
  404. case USB_CTRL_REQ_SET_INTERFACE:
  405. if (usb_set_interface(req->wIndex, req->wValue) < 0)
  406. goto err;
  407. break;
  408. default:
  409. goto err;
  410. }
  411. fail = 0;
  412. err:
  413. usb_handle_control_status(fail);
  414. }
  415. void usb_setup_control(void)
  416. {
  417. void *buf = ep0_buf[usb.ep_state[0].rx.pingpong];
  418. usb.ep_state[0].rx.data01 = USB_DATA01_DATA0;
  419. usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
  420. usb_rx(&usb.ep_state[0].rx, buf, EP0_BUFSIZE, usb_handle_control, NULL);
  421. }
  422. /**
  423. * This is called by the interrupt handler
  424. */
  425. void usb_handle_transaction(struct usb_xfer_info *info)
  426. {
  427. enum usb_tok_pid pid = usb_get_xfer_pid(info);
  428. struct usbd_ep_state_t *eps = &usb.ep_state[usb_get_xfer_ep(info)];
  429. struct usbd_ep_pipe_state_t *s = &eps->pipe[usb_get_xfer_dir(info)];
  430. switch (pid) {
  431. case USB_PID_SETUP:
  432. case USB_PID_OUT:
  433. /**
  434. * If we receive a SETUP transaction, but don't expect
  435. * it (callback set to somewhere else), stall the EP.
  436. */
  437. if (pid == USB_PID_SETUP && s->callback != usb_handle_control)
  438. usb_handle_control_status(1);
  439. else
  440. usb_rx_next(s);
  441. if (pid == USB_PID_SETUP)
  442. usb_enable_xfers();
  443. break;
  444. case USB_PID_IN:
  445. usb_tx_next(s);
  446. break;
  447. default:
  448. break;
  449. }
  450. }
  451. struct usbd_ep_pipe_state_t *usb_init_ep(struct usbd_function_ctx_header *ctx, int ep, enum usb_ep_dir dir, size_t size)
  452. {
  453. struct usbd_ep_pipe_state_t *s;
  454. if (dir == USB_EP_RX)
  455. s = &usb.ep_state[ctx->ep_rx_offset + ep].rx;
  456. else
  457. s = &usb.ep_state[ctx->ep_tx_offset + ep].tx;
  458. memset(s, 0, sizeof(*s));
  459. s->ep_maxsize = size;
  460. s->ep_num = ep;
  461. s->ep_dir = dir;
  462. usb_pipe_enable(s);
  463. return (s);
  464. }
  465. void usb_restart(void)
  466. {
  467. const struct usbd_device *identity = usb.identity;
  468. /* XXX reset existing functions? */
  469. memset(&usb, 0, sizeof(usb));
  470. usb.functions.function = &usb.control_function;
  471. usb.identity = identity;
  472. usb_init_ep(&usb.functions, 0, USB_EP_RX, EP0_BUFSIZE);
  473. usb_init_ep(&usb.functions, 0, USB_EP_TX, EP0_BUFSIZE);
  474. usb_setup_control();
  475. }
  476. void usb_attach_function(const struct usbd_function *function, struct usbd_function_ctx_header *ctx)
  477. {
  478. /* XXX right now this requires a sequential initialization */
  479. struct usbd_function_ctx_header *prev = &usb.functions;
  480. while (prev->next != NULL)
  481. prev = prev->next;
  482. ctx->next = NULL;
  483. ctx->function = function;
  484. ctx->interface_offset = prev->interface_offset + prev->function->interface_count;
  485. ctx->ep_rx_offset = prev->ep_rx_offset + prev->function->ep_rx_count;
  486. ctx->ep_tx_offset = prev->ep_tx_offset + prev->function->ep_tx_count;
  487. prev->next = ctx;
  488. }
  489. // XXX
  490. // Int32 to Hex16 UTF16LE
  491. // This function takes advantage of a few things to save on flash space
  492. // 1) Does not set anything if zero
  493. // 2) No padding
  494. void int32ToHex16( uint32_t num, uint16_t* str )
  495. {
  496. for ( ; num; num /= 16 )
  497. {
  498. uint32_t cur = num % 16;
  499. *--str = (uint16_t)( cur + (( cur < 10 ) ? '0' : 'A' - 10) );
  500. }
  501. }
  502. void usb_init(const struct usbd_device *identity)
  503. {
  504. // Set the device serial number to the reserved iSerial string memory
  505. int32ToHex16( SIM_UIDH, &(dfu_device_str_desc[3]->bString[8]) );
  506. int32ToHex16( SIM_UIDMH, &(dfu_device_str_desc[3]->bString[16]) );
  507. int32ToHex16( SIM_UIDML, &(dfu_device_str_desc[3]->bString[24]) );
  508. int32ToHex16( SIM_UIDL, &(dfu_device_str_desc[3]->bString[32]) );
  509. usb.identity = identity;
  510. usb_enable();
  511. }