Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /* USB EHCI Host for Teensy 3.6
  2. * Copyright 2017 Paul Stoffregen (paul@pjrc.com)
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <Arduino.h>
  24. #include "USBHost_t36.h" // Read this header first for key info
  25. #define print USBHost::print_
  26. #define println USBHost::println_
  27. /************************************************************/
  28. // Initialization and claiming of devices & interfaces
  29. /************************************************************/
  30. void USBSerial::init()
  31. {
  32. contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
  33. contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t));
  34. contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
  35. driver_ready_for_device(this);
  36. }
  37. bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
  38. {
  39. // only claim at interface level
  40. println("USBSerial claim this=", (uint32_t)this, HEX);
  41. print("vid=", dev->idVendor, HEX);
  42. println(", pid=", dev->idProduct, HEX);
  43. if (type == 0) {
  44. if (dev->idVendor == 0x0403 && dev->idProduct == 0x6001) {
  45. // FTDI FT232
  46. println("len = ", len);
  47. if (len < 23) return false;
  48. if (descriptors[0] != 9) return false; // length 9
  49. if (descriptors[9] != 7) return false; // length 7
  50. if (descriptors[10] != 5) return false; // ep desc
  51. uint32_t rxep = descriptors[11];
  52. if (descriptors[12] != 2) return false; // bulk type
  53. if (descriptors[13] != 64) return false; // size 64
  54. if (descriptors[14] != 0) return false;
  55. if (descriptors[16] != 7) return false; // length 7
  56. if (descriptors[17] != 5) return false; // ep desc
  57. uint32_t txep = descriptors[18];
  58. if (descriptors[19] != 2) return false; // bulk type
  59. if (descriptors[20] != 64) return false; // size 64
  60. if (descriptors[21] != 0) return false;
  61. if (!check_rxtx_ep(rxep, txep)) return false;
  62. print("FTDI, rxep=", rxep & 15);
  63. println(", txep=", txep);
  64. if (!init_buffers(64, 64)) return false;
  65. rxpipe = new_Pipe(dev, 2, rxep & 15, 1, 64);
  66. if (!rxpipe) return false;
  67. txpipe = new_Pipe(dev, 2, txep, 0, 64);
  68. if (!txpipe) {
  69. // TODO: free rxpipe
  70. return false;
  71. }
  72. sertype = FTDI;
  73. rxpipe->callback_function = rx_callback;
  74. queue_Data_Transfer(rxpipe, rx1, 64, this);
  75. rxstate = 1;
  76. if (rxsize > 128) {
  77. queue_Data_Transfer(rxpipe, rx2, 64, this);
  78. rxstate = 3;
  79. }
  80. txstate = 0;
  81. txpipe->callback_function = tx_callback;
  82. baudrate = 115200;
  83. pending_control = 0x0F;
  84. mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port
  85. queue_Control_Transfer(dev, &setup, NULL, this);
  86. control_queued = true;
  87. return true;
  88. }
  89. }
  90. return false;
  91. }
  92. // check if two legal endpoints, 1 receive & 1 transmit
  93. bool USBSerial::check_rxtx_ep(uint32_t &rxep, uint32_t &txep)
  94. {
  95. if ((rxep & 0x0F) == 0) return false;
  96. if ((txep & 0x0F) == 0) return false;
  97. uint32_t rxdir = rxep & 0xF0;
  98. uint32_t txdir = txep & 0xF0;
  99. if (rxdir == 0x80 && txdir == 0x00) {
  100. return true;
  101. }
  102. if (rxdir == 0x00 && txdir == 0x80) {
  103. std::swap(rxep, txep);
  104. return true;
  105. }
  106. return false;
  107. }
  108. // initialize buffer sizes and pointers
  109. bool USBSerial::init_buffers(uint32_t rsize, uint32_t tsize)
  110. {
  111. // buffer must be able to hold 2 of each packet, plus have room to
  112. if (sizeof(bigbuffer) < (rsize + tsize) * 3 + 2) return false;
  113. rx1 = (uint8_t *)bigbuffer;
  114. rx2 = rx1 + rsize;
  115. tx1 = rx2 + rsize;
  116. tx2 = tx1 + tsize;
  117. rxbuf = tx2 + tsize;
  118. // FIXME: this assume 50-50 split - not true when rsize != tsize
  119. rxsize = (sizeof(bigbuffer) - (rsize + tsize) * 2) / 2;
  120. txsize = rxsize;
  121. txbuf = rxbuf + rxsize;
  122. rxhead = 0;
  123. rxtail = 0;
  124. txhead = 0;
  125. txtail = 0;
  126. rxstate = 0;
  127. return true;
  128. }
  129. void USBSerial::disconnect()
  130. {
  131. }
  132. /************************************************************/
  133. // Control Transfer For Configuration
  134. /************************************************************/
  135. void USBSerial::control(const Transfer_t *transfer)
  136. {
  137. println("control callback (serial)");
  138. control_queued = false;
  139. // set data format
  140. if (pending_control & 1) {
  141. pending_control &= ~1;
  142. mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1
  143. queue_Control_Transfer(device, &setup, NULL, this);
  144. control_queued = true;
  145. return;
  146. }
  147. // set baud rate
  148. if (pending_control & 2) {
  149. pending_control &= ~2;
  150. uint32_t baudval = 3000000 / baudrate;
  151. mk_setup(setup, 0x40, 3, baudval, 0, 0);
  152. queue_Control_Transfer(device, &setup, NULL, this);
  153. control_queued = true;
  154. return;
  155. }
  156. // configure flow control
  157. if (pending_control & 4) {
  158. pending_control &= ~4;
  159. mk_setup(setup, 0x40, 2, 0, 0, 0);
  160. queue_Control_Transfer(device, &setup, NULL, this);
  161. control_queued = true;
  162. return;
  163. }
  164. // set DTR
  165. if (pending_control & 8) {
  166. pending_control &= ~8;
  167. mk_setup(setup, 0x40, 1, 0x0101, 0, 0);
  168. queue_Control_Transfer(device, &setup, NULL, this);
  169. control_queued = true;
  170. return;
  171. }
  172. }
  173. /************************************************************/
  174. // Interrupt-based Data Movement
  175. /************************************************************/
  176. void USBSerial::rx_callback(const Transfer_t *transfer)
  177. {
  178. if (!transfer->driver) return;
  179. ((USBSerial *)(transfer->driver))->rx_data(transfer);
  180. }
  181. void USBSerial::tx_callback(const Transfer_t *transfer)
  182. {
  183. if (!transfer->driver) return;
  184. ((USBSerial *)(transfer->driver))->tx_data(transfer);
  185. }
  186. void USBSerial::rx_data(const Transfer_t *transfer)
  187. {
  188. uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
  189. // first update rxstate bitmask, since buffer is no longer queued
  190. if (transfer->buffer == rx1) {
  191. rxstate &= 0xFE;
  192. } else if (transfer->buffer == rx2) {
  193. rxstate &= 0xFD;
  194. }
  195. // get start of data and actual length
  196. const uint8_t *p = (const uint8_t *)transfer->buffer;
  197. if (sertype == FTDI) {
  198. if (len >= 2) {
  199. p += 2;
  200. len -= 2;
  201. } else {
  202. len = 0;
  203. }
  204. }
  205. //if (len > 0) {
  206. //print("rx: ");
  207. //print_hexbytes(p, len);
  208. //}
  209. // Copy data from packet buffer to circular buffer.
  210. // Assume the buffer will always have space, since we
  211. // check before queuing the buffers
  212. uint32_t head = rxhead;
  213. uint32_t tail = rxtail;
  214. if (++head >= rxsize) head = 0;
  215. uint32_t avail;
  216. if (len > 0) {
  217. //print("head=", head);
  218. //print(", tail=", tail);
  219. avail = rxsize - head;
  220. //print(", avail=", avail);
  221. //println(", rxsize=", rxsize);
  222. if (avail > len) avail = len;
  223. memcpy(rxbuf + head, p, avail);
  224. if (len <= avail) {
  225. head += avail - 1;
  226. if (head >= rxsize) head = 0;
  227. } else {
  228. head = len - avail - 1;
  229. memcpy(rxbuf, p + avail, head + 1);
  230. }
  231. rxhead = head;
  232. }
  233. // TODO: can be this more efficient? We know from above which
  234. // buffer is no longer queued, so possible skip most of this work?
  235. rx_queue_packets(head, tail);
  236. }
  237. // re-queue packet buffer(s) if possible
  238. void USBSerial::rx_queue_packets(uint32_t head, uint32_t tail)
  239. {
  240. uint32_t avail;
  241. if (head >= tail) {
  242. avail = rxsize - 1 - head + tail;
  243. } else {
  244. avail = tail - head - 1;
  245. }
  246. uint32_t packetsize = rx2 - rx1;
  247. if (avail >= packetsize) {
  248. if ((rxstate & 0x01) == 0) {
  249. queue_Data_Transfer(rxpipe, rx1, packetsize, this);
  250. rxstate |= 0x01;
  251. } else if ((rxstate & 0x02) == 0) {
  252. queue_Data_Transfer(rxpipe, rx2, packetsize, this);
  253. rxstate |= 0x02;
  254. }
  255. if ((rxstate & 0x03) != 0x03 && avail >= packetsize * 2) {
  256. if ((rxstate & 0x01) == 0) {
  257. queue_Data_Transfer(rxpipe, rx1, packetsize, this);
  258. rxstate |= 0x01;
  259. } else if ((rxstate & 0x02) == 0) {
  260. queue_Data_Transfer(rxpipe, rx2, packetsize, this);
  261. rxstate |= 0x02;
  262. }
  263. }
  264. }
  265. }
  266. void USBSerial::tx_data(const Transfer_t *transfer)
  267. {
  268. uint32_t mask;
  269. uint8_t *p = (uint8_t *)transfer->buffer;
  270. if (p == tx1) {
  271. println("tx1:");
  272. mask = 1;
  273. //txstate &= 0xFE;
  274. } else if (p == tx2) {
  275. println("tx2:");
  276. mask = 2;
  277. //txstate &= 0xFD;
  278. } else {
  279. return; // should never happen
  280. }
  281. // check how much more data remains in the transmit buffer
  282. uint32_t head = txhead;
  283. uint32_t tail = txtail;
  284. uint32_t count;
  285. if (head >= tail) {
  286. count = head - tail;
  287. } else {
  288. count = txsize + head - tail;
  289. }
  290. uint32_t packetsize = tx2 - tx1;
  291. if (count < packetsize) {
  292. // not enough data in buffer to fill a full packet
  293. txstate &= ~mask;
  294. return;
  295. }
  296. // immediately transmit another full packet, if we have enough data
  297. println("TX:moar data!!!!");
  298. if (++tail >= txsize) tail = 0;
  299. uint32_t n = txsize - tail;
  300. if (n > packetsize) n = packetsize;
  301. memcpy(p, txbuf + tail, n);
  302. if (n >= packetsize) {
  303. tail += n - 1;
  304. if (tail >= txsize) tail = 0;
  305. } else {
  306. uint32_t len = packetsize - n;
  307. memcpy(p + n, txbuf, len);
  308. tail = len - 1;
  309. }
  310. txtail = tail;
  311. queue_Data_Transfer(txpipe, p, packetsize, this);
  312. }
  313. void USBSerial::timer_event(USBDriverTimer *whichTimer)
  314. {
  315. println("txtimer");
  316. uint32_t count;
  317. uint32_t head = txhead;
  318. uint32_t tail = txtail;
  319. if (head == tail) {
  320. return; // nothing to transmit
  321. } else if (head > tail) {
  322. count = head - tail;
  323. } else {
  324. count = txsize + head - tail;
  325. }
  326. uint8_t *p;
  327. if ((txstate & 0x01) == 0) {
  328. p = tx1;
  329. txstate |= 0x01;
  330. } else if ((txstate & 0x02) == 0) {
  331. p = tx2;
  332. txstate |= 0x02;
  333. } else {
  334. txtimer.start(1200);
  335. return; // no outgoing buffers available, try again later
  336. }
  337. if (++tail >= txsize) tail = 0;
  338. uint32_t n = txsize - tail;
  339. if (n > count) n = count;
  340. memcpy(p, txbuf + tail, n);
  341. if (n >= count) {
  342. tail += n - 1;
  343. if (tail >= txsize) tail = 0;
  344. } else {
  345. uint32_t len = count - n;
  346. memcpy(p + n, txbuf, len);
  347. tail = len - 1;
  348. }
  349. txtail = tail;
  350. queue_Data_Transfer(txpipe, p, count, this);
  351. }
  352. /************************************************************/
  353. // User Functions - must disable USBHQ IRQ for EHCI access
  354. /************************************************************/
  355. void USBSerial::begin(uint32_t baud, uint32_t format)
  356. {
  357. NVIC_DISABLE_IRQ(IRQ_USBHS);
  358. baudrate = baud;
  359. pending_control |= 2;
  360. if (!control_queued) control(NULL);
  361. NVIC_ENABLE_IRQ(IRQ_USBHS);
  362. }
  363. void USBSerial::end(void)
  364. {
  365. // TODO: lower DTR
  366. }
  367. int USBSerial::available(void)
  368. {
  369. if (!device) return 0;
  370. uint32_t head = rxhead;
  371. uint32_t tail = rxtail;
  372. if (head >= tail) return head - tail;
  373. return rxsize + head - tail;
  374. }
  375. int USBSerial::peek(void)
  376. {
  377. if (!device) return -1;
  378. uint32_t head = rxhead;
  379. uint32_t tail = rxtail;
  380. if (head == tail) return -1;
  381. if (++tail >= rxsize) tail = 0;
  382. return rxbuf[tail];
  383. }
  384. int USBSerial::read(void)
  385. {
  386. if (!device) return -1;
  387. uint32_t head = rxhead;
  388. uint32_t tail = rxtail;
  389. if (head == tail) return -1;
  390. if (++tail >= rxsize) tail = 0;
  391. int c = rxbuf[tail];
  392. rxtail = tail;
  393. if ((rxstate & 0x03) != 0x03) {
  394. NVIC_DISABLE_IRQ(IRQ_USBHS);
  395. rx_queue_packets(head, tail);
  396. NVIC_ENABLE_IRQ(IRQ_USBHS);
  397. }
  398. return c;
  399. }
  400. int USBSerial::availableForWrite()
  401. {
  402. if (!device) return 0;
  403. uint32_t head = txhead;
  404. uint32_t tail = txtail;
  405. if (head >= tail) return txsize - 1 - head + tail;
  406. return tail - head - 1;
  407. }
  408. size_t USBSerial::write(uint8_t c)
  409. {
  410. if (!device) return 0;
  411. uint32_t head = txhead;
  412. if (++head >= txsize) head = 0;
  413. while (txtail == head) {
  414. // wait...
  415. }
  416. txbuf[head] = c;
  417. txhead = head;
  418. //print("head=", head);
  419. //println(", tail=", txtail);
  420. // if full packet in buffer and tx packet ready, queue it
  421. NVIC_DISABLE_IRQ(IRQ_USBHS);
  422. uint32_t tail = txtail;
  423. if ((txstate & 0x03) != 0x03) {
  424. // at least one packet buffer is ready to transmit
  425. uint32_t count;
  426. if (head >= tail) {
  427. count = head - tail;
  428. } else {
  429. count = txsize + head - tail;
  430. }
  431. uint32_t packetsize = tx2 - tx1;
  432. if (count >= packetsize) {
  433. //println("txsize=", txsize);
  434. uint8_t *p;
  435. if ((txstate & 0x01) == 0) {
  436. p = tx1;
  437. txstate |= 0x01;
  438. } else /* if ((txstate & 0x02) == 0) */ {
  439. p = tx2;
  440. txstate |= 0x02;
  441. }
  442. // copy data to packet buffer
  443. if (++tail >= txsize) tail = 0;
  444. uint32_t n = txsize - tail;
  445. if (n > packetsize) n = packetsize;
  446. //print("memcpy, offset=", tail);
  447. //println(", len=", n);
  448. memcpy(p, txbuf + tail, n);
  449. if (n >= packetsize) {
  450. tail += n - 1;
  451. if (tail >= txsize) tail = 0;
  452. } else {
  453. //n = txsize - n;
  454. uint32_t len = packetsize - n;
  455. //println("memcpy, offset=0, len=", len);
  456. memcpy(p + n, txbuf, len);
  457. tail = len - 1;
  458. }
  459. txtail = tail;
  460. //println("queue tx packet, newtail=", tail);
  461. queue_Data_Transfer(txpipe, p, packetsize, this);
  462. NVIC_ENABLE_IRQ(IRQ_USBHS);
  463. return 1;
  464. }
  465. }
  466. // otherwise, set a latency timer to later transmit partial packet
  467. txtimer.stop();
  468. txtimer.start(3500);
  469. NVIC_ENABLE_IRQ(IRQ_USBHS);
  470. return 1;
  471. }