usb.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /*
  2. * usb.c
  3. *
  4. * Copyright (C) 2019 Sylvain Munaut
  5. * All rights reserved.
  6. *
  7. * LGPL v3+, see LICENSE.lgpl3
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 3 of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this program; if not, write to the Free Software Foundation,
  21. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. */
  23. #include <stdint.h>
  24. #include <stdbool.h>
  25. #include <string.h>
  26. #include <no2usb/usb_hw.h>
  27. #include <no2usb/usb_priv.h>
  28. #include <no2usb/usb.h>
  29. #include "console.h"
  30. /* Main stack state */
  31. struct usb_stack g_usb;
  32. /* Helpers */
  33. /* ------- */
  34. /* Data buffer access */
  35. void
  36. usb_data_write(unsigned int dst_ofs, const void *src, int len)
  37. {
  38. /* FIXME unaligned ofs */
  39. const uint32_t *src_u32 = src;
  40. volatile uint32_t *dst_u32 = (volatile uint32_t *)((USB_DATA_BASE) + dst_ofs);
  41. len = (len + 3) >> 2;
  42. while (len--)
  43. *dst_u32++ = *src_u32++;
  44. }
  45. void
  46. usb_data_read (void *dst, unsigned int src_ofs, int len)
  47. {
  48. /* FIXME unaligned ofs */
  49. volatile uint32_t *src_u32 = (volatile uint32_t *)((USB_DATA_BASE) + src_ofs);
  50. uint32_t *dst_u32 = dst;
  51. int i = len >> 2;
  52. while (i--)
  53. *dst_u32++ = *src_u32++;
  54. if ((len &= 3) != 0) {
  55. uint32_t x = *src_u32;
  56. uint8_t *dst_u8 = (uint8_t *)dst_u32;
  57. while (len--) {
  58. *dst_u8++ = x & 0xff;
  59. x >>= 8;
  60. }
  61. }
  62. }
  63. /* Descriptors */
  64. const void *
  65. usb_desc_find(const void *sod, const void *eod, uint8_t dt)
  66. {
  67. const uint8_t *sod_p = sod, *eod_p = eod;
  68. while ((eod_p - sod_p) >= 2) {
  69. if (sod_p[1] == dt)
  70. return sod_p;
  71. sod_p += sod_p[0];
  72. }
  73. return NULL;
  74. }
  75. const void *
  76. usb_desc_next(const void *sod)
  77. {
  78. const uint8_t *sod_p = sod;
  79. return sod_p + sod_p[0];
  80. }
  81. const struct usb_conf_desc *
  82. usb_desc_find_conf(uint8_t cfg_value)
  83. {
  84. for (int i=0; i<g_usb.stack_desc->n_conf; i++)
  85. if (g_usb.stack_desc->conf[i]->bConfigurationValue == cfg_value)
  86. return g_usb.stack_desc->conf[i];
  87. return NULL;
  88. }
  89. const struct usb_intf_desc *
  90. usb_desc_find_intf(const struct usb_conf_desc *conf, uint8_t idx, uint8_t alt,
  91. const struct usb_intf_desc **alt0)
  92. {
  93. const struct usb_intf_desc *intf = NULL;
  94. const void *sod, *eod;
  95. /* Config select */
  96. if (!conf)
  97. conf = g_usb.conf;
  98. if (!conf)
  99. return NULL;
  100. /* Bound the search */
  101. sod = conf;
  102. eod = sod + conf->wTotalLength;
  103. while (1) {
  104. sod = usb_desc_find(sod, eod, USB_DT_INTF);
  105. if (!sod)
  106. break;
  107. intf = (void*)sod;
  108. if (intf->bInterfaceNumber == idx) {
  109. if (alt0 && !intf->bAlternateSetting)
  110. *alt0 = intf;
  111. if (intf->bAlternateSetting == alt)
  112. return intf;
  113. }
  114. sod = usb_desc_next(sod);
  115. }
  116. return NULL;
  117. }
  118. /* Callback dispatching */
  119. void
  120. usb_dispatch_sof(void)
  121. {
  122. struct usb_fn_drv *p = g_usb.fnd;
  123. while (p) {
  124. if (p->sof)
  125. p->sof();
  126. p = p->next;
  127. }
  128. }
  129. void
  130. usb_dipatch_bus_reset(void)
  131. {
  132. struct usb_fn_drv *p = g_usb.fnd;
  133. while (p) {
  134. if (p->bus_reset)
  135. p->bus_reset();
  136. p = p->next;
  137. }
  138. }
  139. void
  140. usb_dispatch_state_chg(enum usb_dev_state state)
  141. {
  142. struct usb_fn_drv *p = g_usb.fnd;
  143. while (p) {
  144. if (p->state_chg)
  145. p->state_chg(state);
  146. p = p->next;
  147. }
  148. }
  149. enum usb_fnd_resp
  150. usb_dispatch_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
  151. {
  152. struct usb_fn_drv *p = g_usb.fnd;
  153. enum usb_fnd_resp rv = USB_FND_CONTINUE;
  154. while (p) {
  155. if (p->ctrl_req) {
  156. rv = p->ctrl_req(req, xfer);
  157. if (rv != USB_FND_CONTINUE)
  158. return rv;
  159. }
  160. p = p->next;
  161. }
  162. return rv;
  163. }
  164. enum usb_fnd_resp
  165. usb_dispatch_set_conf(const struct usb_conf_desc *desc)
  166. {
  167. struct usb_fn_drv *p = g_usb.fnd;
  168. enum usb_fnd_resp rv = USB_FND_SUCCESS;
  169. while (p) {
  170. if (p->set_conf) {
  171. if (p->set_conf(desc) == USB_FND_ERROR)
  172. rv = USB_FND_ERROR;
  173. }
  174. p = p->next;
  175. }
  176. return rv;
  177. }
  178. enum usb_fnd_resp
  179. usb_dispatch_set_intf(const struct usb_intf_desc *base, const struct usb_intf_desc *sel)
  180. {
  181. struct usb_fn_drv *p = g_usb.fnd;
  182. enum usb_fnd_resp rv = USB_FND_CONTINUE;
  183. while (p) {
  184. if (p->set_intf) {
  185. rv = p->set_intf(base, sel);
  186. if (rv != USB_FND_CONTINUE)
  187. return rv;
  188. }
  189. p = p->next;
  190. }
  191. return rv;
  192. }
  193. enum usb_fnd_resp
  194. usb_dispatch_get_intf(const struct usb_intf_desc *base, uint8_t *sel)
  195. {
  196. struct usb_fn_drv *p = g_usb.fnd;
  197. enum usb_fnd_resp rv = USB_FND_CONTINUE;
  198. while (p) {
  199. if (p->get_intf) {
  200. rv = p->get_intf(base, sel);
  201. if (rv != USB_FND_CONTINUE)
  202. return rv;
  203. }
  204. p = p->next;
  205. }
  206. return rv;
  207. }
  208. /* Debug */
  209. /* ----- */
  210. static void
  211. _fast_print_hex(uint32_t v)
  212. {
  213. const char _hex[] = "0123456789abcdef";
  214. int i;
  215. for (i=0; i<4; i++) {
  216. putchar(_hex[(v & 0xf0) >> 4]);
  217. putchar(_hex[ v & 0x0f ]);
  218. putchar(' ');
  219. v >>= 8;
  220. }
  221. }
  222. void
  223. usb_debug_print_ep(int ep, int dir)
  224. {
  225. volatile struct usb_ep *ep_regs = dir ? &usb_ep_regs[ep].in : &usb_ep_regs[ep].out;
  226. printf("EP%d %s\n", ep, dir ? "IN" : "OUT");
  227. printf("\tS %04x\n", ep_regs->status);
  228. printf("\tBD0.0 %04x\n", ep_regs->bd[0].csr);
  229. printf("\tBD0.1 %04x\n", ep_regs->bd[0].ptr);
  230. printf("\tBD1.0 %04x\n", ep_regs->bd[1].csr);
  231. printf("\tBD1.1 %04x\n", ep_regs->bd[1].ptr);
  232. printf("\n");
  233. }
  234. void
  235. usb_debug_print_data(int ofs, int len)
  236. {
  237. volatile uint32_t *data = (volatile uint32_t *)((USB_DATA_BASE) + (ofs << 2));
  238. int i;
  239. for (i=0; i<len; i++) {
  240. _fast_print_hex(*data++);
  241. putchar((((i & 3) == 3) | (i == (len-1))) ? '\n' : ' ');
  242. }
  243. puts("\n");
  244. }
  245. void
  246. usb_debug_print(void)
  247. {
  248. printf("Stack:\n");
  249. printf("\tState: %d\n", g_usb.state);
  250. printf("HW:\n");
  251. printf("\tSR : %04x\n", usb_regs->csr);
  252. printf("\tTick : %04x\n", g_usb.tick);
  253. printf("\n");
  254. usb_debug_print_ep(0, 0);
  255. usb_debug_print_ep(0, 1);
  256. printf("Data:\n");
  257. usb_debug_print_data(0, 4);
  258. }
  259. /* Internal API */
  260. /* ------------ */
  261. static volatile struct usb_ep *
  262. _usb_hw_get_ep(uint8_t ep_addr)
  263. {
  264. return (ep_addr & 0x80) ?
  265. &usb_ep_regs[ep_addr & 0xf].in :
  266. &usb_ep_regs[ep_addr & 0xf].out;
  267. }
  268. static void
  269. _usb_hw_reset_ep(volatile struct usb_ep *ep)
  270. {
  271. ep->status = 0;
  272. ep->bd[0].csr = 0;
  273. ep->bd[0].ptr = 0;
  274. ep->bd[1].csr = 0;
  275. ep->bd[1].ptr = 0;
  276. }
  277. static void
  278. _usb_hw_reset(bool pu)
  279. {
  280. /* Clear all descriptors */
  281. for (int i=0; i<16; i++) {
  282. _usb_hw_reset_ep(&usb_ep_regs[i].out);
  283. _usb_hw_reset_ep(&usb_ep_regs[i].in);
  284. }
  285. /* Main control */
  286. usb_regs->csr = (pu ? USB_CSR_PU_ENA : 0) | USB_CSR_CEL_ENA | USB_CSR_ADDR_MATCH | USB_CSR_ADDR(0);
  287. usb_regs->ar = USB_AR_BUS_RST_CLEAR | USB_AR_SOF_CLEAR | USB_AR_CEL_RELEASE;
  288. }
  289. static void
  290. usb_bus_reset(void)
  291. {
  292. /* Reset hw */
  293. _usb_hw_reset(true);
  294. /* Reset memory alloc */
  295. g_usb.ep_cfg.mem[0] = 0x80; // 2 * 64b for EP0 OUT/SETUP
  296. g_usb.ep_cfg.mem[1] = 0x40; // 1 * 64b for EP0 IN
  297. /* Reset EP0 */
  298. usb_ep0_reset();
  299. /* Dispatch event */
  300. usb_dipatch_bus_reset();
  301. /* Set state */
  302. usb_set_state(USB_DS_DEFAULT);
  303. }
  304. /* Exposed API */
  305. /* ----------- */
  306. void
  307. usb_init(const struct usb_stack_descriptors *stack_desc)
  308. {
  309. /* Main state reset */
  310. memset(&g_usb, 0x00, sizeof(g_usb));
  311. /* Stack setup */
  312. g_usb.state = USB_DS_DISCONNECTED;
  313. g_usb.stack_desc = stack_desc;
  314. usb_register_function_driver(&usb_ctrl_std_drv);
  315. /* Reset and enable the core */
  316. _usb_hw_reset(false);
  317. }
  318. void
  319. usb_poll(void)
  320. {
  321. uint32_t csr;
  322. /* Active ? */
  323. if (g_usb.state < USB_DS_CONNECTED)
  324. return;
  325. /* Read CSR */
  326. csr = usb_regs->csr;
  327. /* Check for pending bus reset */
  328. if (csr & USB_CSR_BUS_RST_PENDING) {
  329. if (csr & USB_CSR_BUS_RST)
  330. return;
  331. usb_bus_reset();
  332. }
  333. /* If we've not been reset, only reset is of interest */
  334. if (g_usb.state < USB_DS_DEFAULT)
  335. return;
  336. /* Supspend handling */
  337. if (csr & USB_CSR_BUS_SUSPEND) {
  338. if (!(g_usb.state & USB_DS_SUSPENDED)) {
  339. usb_set_state(USB_DS_SUSPENDED);
  340. }
  341. return;
  342. } else if (g_usb.state & USB_DS_SUSPENDED) {
  343. usb_set_state(USB_DS_RESUME);
  344. }
  345. /* SOF Tick */
  346. if (csr & USB_CSR_SOF_PENDING) {
  347. g_usb.tick++;
  348. usb_regs->ar = USB_AR_SOF_CLEAR;
  349. usb_dispatch_sof();
  350. }
  351. /* Check for activity */
  352. if (!(csr & USB_CSR_EVT_PENDING))
  353. return;
  354. csr = usb_regs->evt;
  355. /* Poll EP0 (control) */
  356. usb_ep0_poll();
  357. }
  358. void
  359. usb_set_state(enum usb_dev_state new_state)
  360. {
  361. /* Handle resume/suspend 'markers' */
  362. if (new_state == USB_DS_RESUME)
  363. new_state = g_usb.state & ~USB_DS_SUSPENDED;
  364. else if (new_state == USB_DS_SUSPENDED)
  365. new_state = g_usb.state | USB_DS_SUSPENDED;
  366. /* If state is new, update */
  367. if (g_usb.state != new_state) {
  368. g_usb.state = new_state;
  369. usb_dispatch_state_chg(usb_get_state());
  370. }
  371. }
  372. enum usb_dev_state
  373. usb_get_state(void)
  374. {
  375. return (g_usb.state & USB_DS_SUSPENDED) ? USB_DS_SUSPENDED : g_usb.state;
  376. }
  377. uint32_t
  378. usb_get_tick(void)
  379. {
  380. return g_usb.tick;
  381. }
  382. void
  383. usb_connect(void)
  384. {
  385. /* Sanity check */
  386. if (g_usb.state != USB_DS_DISCONNECTED)
  387. return;
  388. /* Turn-off pull-up */
  389. usb_regs->csr |= USB_CSR_PU_ENA;
  390. /* Stack update */
  391. usb_set_state(USB_DS_CONNECTED);
  392. }
  393. void
  394. usb_disconnect(void)
  395. {
  396. /* Sanity check */
  397. if (g_usb.state < USB_DS_CONNECTED)
  398. return;
  399. /* Turn-off pull-up */
  400. usb_regs->csr &= ~USB_CSR_PU_ENA;
  401. /* Stack state */
  402. usb_set_state(USB_DS_DISCONNECTED);
  403. }
  404. void
  405. usb_set_address(uint8_t addr)
  406. {
  407. usb_regs->csr = USB_CSR_PU_ENA | USB_CSR_CEL_ENA | USB_CSR_ADDR_MATCH | USB_CSR_ADDR(addr);
  408. }
  409. void
  410. usb_register_function_driver(struct usb_fn_drv *drv)
  411. {
  412. drv->next = g_usb.fnd;
  413. g_usb.fnd = drv;
  414. }
  415. void
  416. usb_unregister_function_driver(struct usb_fn_drv *drv)
  417. {
  418. struct usb_fn_drv **p = &g_usb.fnd;
  419. while (*p) {
  420. if (*p == drv) {
  421. *p = drv->next;
  422. drv->next = NULL;
  423. break;
  424. }
  425. p = &(*p)->next->next;
  426. }
  427. }
  428. static volatile struct usb_ep *
  429. _get_ep_regs(uint8_t ep)
  430. {
  431. return (ep & 0x80) ?
  432. &usb_ep_regs[ep & 0xf].in :
  433. &usb_ep_regs[ep & 0xf].out;
  434. }
  435. bool
  436. usb_ep_is_configured(uint8_t ep)
  437. {
  438. volatile struct usb_ep *epr = _get_ep_regs(ep);
  439. uint32_t s = epr->status;
  440. return USB_EP_TYPE(s) != USB_EP_TYPE_NONE;
  441. }
  442. bool
  443. usb_ep_is_halted(uint8_t ep)
  444. {
  445. volatile struct usb_ep *epr = _get_ep_regs(ep);
  446. uint32_t s = epr->status;
  447. return USB_EP_TYPE_IS_BCI(s) && (s & USB_EP_TYPE_HALTED);
  448. }
  449. bool
  450. usb_ep_halt(uint8_t ep)
  451. {
  452. volatile struct usb_ep *epr = _get_ep_regs(ep);
  453. uint32_t s = epr->status;
  454. if (!USB_EP_TYPE_IS_BCI(s))
  455. return false;
  456. epr->status = s | USB_EP_TYPE_HALTED;
  457. return true;
  458. }
  459. bool
  460. usb_ep_resume(uint8_t ep)
  461. {
  462. volatile struct usb_ep *epr = _get_ep_regs(ep);
  463. uint32_t s = epr->status;
  464. if (!USB_EP_TYPE_IS_BCI(s))
  465. return false;
  466. epr->status = s & ~(USB_EP_TYPE_HALTED | USB_EP_DT_BIT); /* DT bit clear needed by CLEAR_FEATURE */
  467. return true;
  468. }
  469. static uint32_t
  470. _usb_alloc_buf(unsigned int size, bool in)
  471. {
  472. uint32_t v = g_usb.ep_cfg.mem[in];
  473. g_usb.ep_cfg.mem[in] += size;
  474. return v;
  475. }
  476. static bool
  477. _usb_ep_conf(uint8_t ep_addr, const struct usb_ep_desc *ep)
  478. {
  479. volatile struct usb_ep *ep_regs;
  480. uint32_t csr, ml;
  481. ep_regs = _usb_hw_get_ep(ep_addr);
  482. csr = ep_regs->status;
  483. csr &= USB_EP_BD_DUAL;
  484. ml = 0;
  485. if (ep) {
  486. const uint8_t types[4] = {
  487. USB_EP_TYPE_CTRL,
  488. USB_EP_TYPE_ISOC,
  489. USB_EP_TYPE_BULK,
  490. USB_EP_TYPE_INT,
  491. };
  492. csr |= types[ep->bmAttributes & 3];
  493. ml = ep->wMaxPacketSize;
  494. }
  495. ep_regs->status = csr;
  496. ep_regs->_rsvd[3] = ml;
  497. ep_regs->bd[0].csr = 0;
  498. ep_regs->bd[1].csr = 0;
  499. return true;
  500. }
  501. bool
  502. usb_ep_reconf(const struct usb_intf_desc *intf, uint8_t ep_addr)
  503. {
  504. const struct usb_conf_desc *conf = g_usb.conf;
  505. const struct usb_ep_desc *ep;
  506. const void *eod;
  507. eod = ((uint8_t*)intf) + conf->wTotalLength;
  508. ep = (void*) intf;
  509. for (int i=0; i<intf->bNumEndpoints; i++) {
  510. ep = usb_desc_find(usb_desc_next(ep), eod, USB_DT_EP);
  511. if (ep->bEndpointAddress == ep_addr)
  512. return _usb_ep_conf(ep_addr, ep);
  513. }
  514. return false;
  515. }
  516. bool
  517. usb_ep_boot(const struct usb_intf_desc *intf, uint8_t ep_addr, bool dual_bd)
  518. {
  519. const struct usb_conf_desc *conf = g_usb.conf;
  520. const struct usb_intf_desc *intf_alt;
  521. const struct usb_ep_desc *ep, *ep_def = NULL;
  522. const void *eod;
  523. volatile struct usb_ep *ep_regs;
  524. uint16_t wMaxPacketSize = 0;
  525. /* Scan all alt config to find the max packet size for that EP */
  526. eod = ((uint8_t*)intf) + conf->wTotalLength;
  527. for (intf_alt=intf;
  528. (intf_alt != NULL) && (intf_alt->bInterfaceNumber == intf->bInterfaceNumber);
  529. intf_alt = usb_desc_find(usb_desc_next(intf_alt), eod, USB_DT_INTF))
  530. {
  531. ep = (void*) intf_alt;
  532. for (int i=0; i<intf_alt->bNumEndpoints; i++) {
  533. ep = usb_desc_find(usb_desc_next(ep), eod, USB_DT_EP);
  534. if (ep->bEndpointAddress != ep_addr)
  535. continue;
  536. if (ep->wMaxPacketSize > wMaxPacketSize)
  537. wMaxPacketSize = ep->wMaxPacketSize;
  538. if (intf_alt->bAlternateSetting == 0)
  539. ep_def = ep;
  540. break;
  541. }
  542. }
  543. if (!wMaxPacketSize)
  544. return false;
  545. /* Allocate and setup BDs */
  546. ep_regs = _usb_hw_get_ep(ep_addr);
  547. ep_regs->status = dual_bd ? USB_EP_BD_DUAL : 0;
  548. ep_regs->_rsvd[2] = wMaxPacketSize;
  549. for (int i=0; i<(dual_bd?2:1); i++) {
  550. ep_regs->bd[i].csr = 0x0000;
  551. ep_regs->bd[i].ptr = _usb_alloc_buf(wMaxPacketSize, (ep_addr & 0x80) ? true : false);
  552. printf("%02x %d %x\n",ep_addr, i, ep_regs->bd[i].ptr);
  553. }
  554. /* Configure with the altsetting 0 config */
  555. return _usb_ep_conf(ep_addr, ep_def);
  556. }