Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

473 lines
12KB

  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. // quick hack - ultimately USBHost print & println need to be renamed
  26. #define print USBHost::print
  27. #define println USBHost::println
  28. /************************************************************/
  29. // Initialization and claiming of devices & interfaces
  30. /************************************************************/
  31. void USBSerial::init()
  32. {
  33. contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
  34. contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_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. if (transfer->buffer == tx1) {
  269. println("tx1:");
  270. txstate &= 0xFE;
  271. } else if (transfer->buffer == tx2) {
  272. println("tx2:");
  273. txstate &= 0xFD;
  274. }
  275. }
  276. void USBSerial::timer_event(USBDriverTimer *whichTimer)
  277. {
  278. println("txtimer");
  279. uint32_t count;
  280. uint32_t head = txhead;
  281. uint32_t tail = txtail;
  282. if (head == tail) {
  283. return; // nothing to transmit
  284. } else if (head > tail) {
  285. count = head - tail;
  286. } else {
  287. count = txsize + head - tail;
  288. }
  289. uint8_t *p;
  290. if ((txstate & 0x01) == 0) {
  291. p = tx1;
  292. txstate |= 0x01;
  293. } else if ((txstate & 0x02) == 0) {
  294. p = tx2;
  295. txstate |= 0x02;
  296. } else {
  297. txtimer.start(1200);
  298. return; // no outgoing buffers available, try again later
  299. }
  300. if (++tail >= txsize) tail = 0;
  301. uint32_t n = txsize - tail;
  302. if (n > count) n = count;
  303. memcpy(p, txbuf + tail, n);
  304. if (n >= count) {
  305. tail += n - 1;
  306. if (tail >= txsize) tail = 0;
  307. } else {
  308. uint32_t len = count - n;
  309. memcpy(p + n, txbuf, len);
  310. tail = len - 1;
  311. }
  312. txtail = tail;
  313. queue_Data_Transfer(txpipe, p, count, this);
  314. }
  315. /************************************************************/
  316. // User Functions - must disable USBHQ IRQ for EHCI access
  317. /************************************************************/
  318. void USBSerial::begin(uint32_t baud, uint32_t format)
  319. {
  320. NVIC_DISABLE_IRQ(IRQ_USBHS);
  321. baudrate = baud;
  322. pending_control |= 2;
  323. if (!control_queued) control(NULL);
  324. NVIC_ENABLE_IRQ(IRQ_USBHS);
  325. }
  326. void USBSerial::end(void)
  327. {
  328. // TODO: lower DTR
  329. }
  330. int USBSerial::available(void)
  331. {
  332. if (!device) return 0;
  333. uint32_t head = rxhead;
  334. uint32_t tail = rxtail;
  335. if (head >= tail) return head - tail;
  336. return rxsize + head - tail;
  337. }
  338. int USBSerial::peek(void)
  339. {
  340. if (!device) return -1;
  341. uint32_t head = rxhead;
  342. uint32_t tail = rxtail;
  343. if (head == tail) return -1;
  344. if (++tail >= rxsize) tail = 0;
  345. return rxbuf[tail];
  346. }
  347. int USBSerial::read(void)
  348. {
  349. if (!device) return -1;
  350. uint32_t head = rxhead;
  351. uint32_t tail = rxtail;
  352. if (head == tail) return -1;
  353. if (++tail >= rxsize) tail = 0;
  354. int c = rxbuf[tail];
  355. rxtail = tail;
  356. if ((rxstate & 0x03) != 0x03) {
  357. NVIC_DISABLE_IRQ(IRQ_USBHS);
  358. rx_queue_packets(head, tail);
  359. NVIC_ENABLE_IRQ(IRQ_USBHS);
  360. }
  361. return c;
  362. }
  363. int USBSerial::availableForWrite()
  364. {
  365. if (!device) return 0;
  366. uint32_t head = txhead;
  367. uint32_t tail = txtail;
  368. if (head >= tail) return txsize - 1 - head + tail;
  369. return tail - head - 1;
  370. }
  371. size_t USBSerial::write(uint8_t c)
  372. {
  373. if (!device) return 0;
  374. uint32_t head = txhead;
  375. if (++head >= txsize) head = 0;
  376. while (txtail == head) {
  377. // wait...
  378. }
  379. txbuf[head] = c;
  380. txhead = head;
  381. //print("head=", head);
  382. //println(", tail=", txtail);
  383. // if full packet in buffer and tx packet ready, queue it
  384. NVIC_DISABLE_IRQ(IRQ_USBHS);
  385. uint32_t tail = txtail;
  386. if ((txstate & 0x03) != 0x03) {
  387. // at least one packet buffer is ready to transmit
  388. uint32_t count;
  389. if (head >= tail) {
  390. count = head - tail;
  391. } else {
  392. count = txsize + head - tail;
  393. }
  394. uint32_t packetsize = tx2 - tx1;
  395. if (count >= packetsize) {
  396. //println("txsize=", txsize);
  397. uint8_t *p;
  398. if ((txstate & 0x01) == 0) {
  399. p = tx1;
  400. txstate |= 0x01;
  401. } else /* if ((txstate & 0x02) == 0) */ {
  402. p = tx2;
  403. txstate |= 0x02;
  404. }
  405. // copy data to packet buffer
  406. if (++tail >= txsize) tail = 0;
  407. uint32_t n = txsize - tail;
  408. if (n > packetsize) n = packetsize;
  409. //print("memcpy, offset=", tail);
  410. //println(", len=", n);
  411. memcpy(p, txbuf + tail, n);
  412. if (n >= packetsize) {
  413. tail += n - 1;
  414. if (tail >= txsize) tail = 0;
  415. } else {
  416. //n = txsize - n;
  417. uint32_t len = packetsize - n;
  418. //println("memcpy, offset=0, len=", len);
  419. memcpy(p + n, txbuf, len);
  420. tail = len - 1;
  421. }
  422. txtail = tail;
  423. //println("queue tx packet, newtail=", tail);
  424. queue_Data_Transfer(txpipe, p, packetsize, this);
  425. NVIC_ENABLE_IRQ(IRQ_USBHS);
  426. return 1;
  427. }
  428. }
  429. // otherwise, set a latency timer to later transmit partial packet
  430. txtimer.stop();
  431. txtimer.start(3500);
  432. NVIC_ENABLE_IRQ(IRQ_USBHS);
  433. return 1;
  434. }