Teensy 4.1 core updated for C++20
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.

преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /* USB API for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/teensyduino.html
  3. * Copyright (c) 2008 PJRC.COM, LLC
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include <avr/io.h>
  24. #include <stdint.h>
  25. #include "usb_common.h"
  26. #include "usb_private.h"
  27. #include "usb_api.h"
  28. #include "wiring.h"
  29. // Public Methods //////////////////////////////////////////////////////////////
  30. void usb_serial_class::begin(long speed)
  31. {
  32. // make sure USB is initialized
  33. peek_buf = -1;
  34. usb_init();
  35. uint16_t begin_wait = (uint16_t)millis();
  36. while (1) {
  37. // wait for the host to finish enumeration
  38. if (usb_configuration) {
  39. delay(200); // a little time for host to load a driver
  40. return;
  41. }
  42. // or for suspend mode (powered without USB)
  43. if (usb_suspended) {
  44. uint16_t begin_suspend = (uint16_t)millis();
  45. while (usb_suspended) {
  46. // must remain suspended for a while, because
  47. // normal USB enumeration causes brief suspend
  48. // states, typically under 0.1 second
  49. if ((uint16_t)millis() - begin_suspend > 250) {
  50. return;
  51. }
  52. }
  53. }
  54. // ... or a timout (powered by a USB power adaptor that
  55. // wiggles the data lines to keep a USB device charging)
  56. if ((uint16_t)millis() - begin_wait > 2500) return;
  57. }
  58. }
  59. void usb_serial_class::end()
  60. {
  61. usb_shutdown();
  62. delay(25);
  63. }
  64. // number of bytes available in the receive buffer
  65. int usb_serial_class::available()
  66. {
  67. uint8_t n=0, i, intr_state;
  68. intr_state = SREG;
  69. cli();
  70. if (usb_configuration) {
  71. UENUM = CDC_RX_ENDPOINT;
  72. n = UEBCLX;
  73. if (!n) {
  74. i = UEINTX;
  75. if (i & (1<<RXOUTI) && !(i & (1<<RWAL))) UEINTX = 0x6B;
  76. }
  77. }
  78. SREG = intr_state;
  79. if (peek_buf >= 0 && n < 255) n++;
  80. return n;
  81. }
  82. int usb_serial_class::peek()
  83. {
  84. if (peek_buf < 0) peek_buf = read();
  85. return peek_buf;
  86. }
  87. // get the next character, or -1 if nothing received
  88. int usb_serial_class::read(void)
  89. {
  90. uint8_t c, intr_state;
  91. if (peek_buf >= 0) {
  92. c = peek_buf;
  93. peek_buf = -1;
  94. return c;
  95. }
  96. // interrupts are disabled so these functions can be
  97. // used from the main program or interrupt context,
  98. // even both in the same program!
  99. intr_state = SREG;
  100. cli();
  101. if (!usb_configuration) {
  102. SREG = intr_state;
  103. return -1;
  104. }
  105. UENUM = CDC_RX_ENDPOINT;
  106. retry:
  107. c = UEINTX;
  108. if (!(c & (1<<RWAL))) {
  109. // no data in buffer
  110. if (c & (1<<RXOUTI)) {
  111. UEINTX = 0x6B;
  112. goto retry;
  113. }
  114. SREG = intr_state;
  115. return -1;
  116. }
  117. // take one byte out of the buffer
  118. c = UEDATX;
  119. // if this drained the buffer, release it
  120. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
  121. SREG = intr_state;
  122. return c;
  123. }
  124. #if ARDUINO >= 100
  125. size_t usb_serial_class::readBytes(char *buffer, size_t length)
  126. {
  127. size_t count=0;
  128. unsigned long startMillis;
  129. uint8_t num, intr_state;
  130. startMillis = millis();
  131. if (length <= 0) return 0;
  132. if (peek_buf >= 0) {
  133. *buffer++ = peek_buf;
  134. peek_buf = -1;
  135. length--;
  136. if (length == 0) return 1;
  137. count = 1;
  138. }
  139. do {
  140. intr_state = SREG;
  141. cli();
  142. if (!usb_configuration) {
  143. SREG = intr_state;
  144. break;
  145. }
  146. UENUM = CDC_RX_ENDPOINT;
  147. if (!(UEINTX & (1<<RXOUTI))) {
  148. SREG = intr_state;
  149. break;
  150. }
  151. num = UEBCLX;
  152. if (num > length) num = length;
  153. for (uint8_t i=0; i < num; i++) {
  154. *buffer++ = UEDATX; // TODO: unroll loop for speed
  155. }
  156. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
  157. SREG = intr_state;
  158. count += num;
  159. length -= num;
  160. if (length == 0) return count;
  161. } while(millis() - startMillis < _timeout);
  162. setReadError();
  163. return count;
  164. }
  165. #endif
  166. #if ARDUINO >= 100
  167. void usb_serial_class::flush()
  168. {
  169. send_now();
  170. }
  171. #else
  172. // discard any buffered input
  173. void usb_serial_class::flush()
  174. {
  175. uint8_t intr_state;
  176. if (usb_configuration) {
  177. intr_state = SREG;
  178. cli();
  179. UENUM = CDC_RX_ENDPOINT;
  180. while ((UEINTX & (1<<RWAL))) {
  181. UEINTX = 0x6B;
  182. }
  183. SREG = intr_state;
  184. }
  185. peek_buf = -1;
  186. }
  187. #endif
  188. #if 0
  189. // transmit a character.
  190. void usb_serial_class::write(uint8_t c)
  191. {
  192. uint8_t timeout, intr_state;
  193. // if we're not online (enumerated and configured), error
  194. if (!usb_configuration) return;
  195. // interrupts are disabled so these functions can be
  196. // used from the main program or interrupt context,
  197. // even both in the same program!
  198. intr_state = SREG;
  199. cli();
  200. UENUM = CDC_TX_ENDPOINT;
  201. // if we gave up due to timeout before, don't wait again
  202. if (transmit_previous_timeout) {
  203. if (!(UEINTX & (1<<RWAL))) {
  204. SREG = intr_state;
  205. return;
  206. }
  207. transmit_previous_timeout = 0;
  208. }
  209. // wait for the FIFO to be ready to accept data
  210. timeout = UDFNUML + TRANSMIT_TIMEOUT;
  211. while (1) {
  212. // are we ready to transmit?
  213. if (UEINTX & (1<<RWAL)) break;
  214. SREG = intr_state;
  215. // have we waited too long? This happens if the user
  216. // is not running an application that is listening
  217. if (UDFNUML == timeout) {
  218. transmit_previous_timeout = 1;
  219. return;
  220. }
  221. // has the USB gone offline?
  222. if (!usb_configuration) return;
  223. // get ready to try checking again
  224. intr_state = SREG;
  225. cli();
  226. UENUM = CDC_TX_ENDPOINT;
  227. }
  228. // actually write the byte into the FIFO
  229. UEDATX = c;
  230. // if this completed a packet, transmit it now!
  231. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
  232. transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  233. SREG = intr_state;
  234. }
  235. #endif
  236. // transmit a block of data
  237. #if ARDUINO >= 100
  238. size_t usb_serial_class::write(const uint8_t *buffer, uint16_t size)
  239. #else
  240. #define setWriteError()
  241. void usb_serial_class::write(const uint8_t *buffer, uint16_t size)
  242. #endif
  243. {
  244. uint8_t timeout, intr_state, write_size;
  245. #if ARDUINO >= 100
  246. size_t count=0;
  247. #endif
  248. // if we're not online (enumerated and configured), error
  249. if (!usb_configuration) {
  250. setWriteError();
  251. goto end;
  252. }
  253. // interrupts are disabled so these functions can be
  254. // used from the main program or interrupt context,
  255. // even both in the same program!
  256. intr_state = SREG;
  257. cli();
  258. UENUM = CDC_TX_ENDPOINT;
  259. // if we gave up due to timeout before, don't wait again
  260. if (transmit_previous_timeout) {
  261. if (!(UEINTX & (1<<RWAL))) {
  262. SREG = intr_state;
  263. setWriteError();
  264. goto end;
  265. }
  266. transmit_previous_timeout = 0;
  267. }
  268. // each iteration of this loop transmits a packet
  269. while (size) {
  270. // wait for the FIFO to be ready to accept data
  271. timeout = UDFNUML + TRANSMIT_TIMEOUT;
  272. while (1) {
  273. // are we ready to transmit?
  274. if (UEINTX & (1<<RWAL)) break;
  275. SREG = intr_state;
  276. // have we waited too long? This happens if the user
  277. // is not running an application that is listening
  278. if (UDFNUML == timeout) {
  279. transmit_previous_timeout = 1;
  280. setWriteError();
  281. goto end;
  282. }
  283. // has the USB gone offline?
  284. if (!usb_configuration) {
  285. setWriteError();
  286. goto end;
  287. }
  288. // get ready to try checking again
  289. intr_state = SREG;
  290. cli();
  291. UENUM = CDC_TX_ENDPOINT;
  292. }
  293. // compute how many bytes will fit into the next packet
  294. write_size = CDC_TX_SIZE - UEBCLX;
  295. if (write_size > size) write_size = size;
  296. size -= write_size;
  297. #if ARDUINO >= 100
  298. count += write_size;
  299. #endif
  300. #define ASM_COPY1(src, dest, tmp) "ld " tmp ", " src "\n\t" "st " dest ", " tmp "\n\t"
  301. #define ASM_COPY2(src, dest, tmp) ASM_COPY1(src, dest, tmp) ASM_COPY1(src, dest, tmp)
  302. #define ASM_COPY4(src, dest, tmp) ASM_COPY2(src, dest, tmp) ASM_COPY2(src, dest, tmp)
  303. #define ASM_COPY8(src, dest, tmp) ASM_COPY4(src, dest, tmp) ASM_COPY4(src, dest, tmp)
  304. #if 1
  305. // write the packet
  306. do {
  307. uint8_t tmp;
  308. asm volatile(
  309. "L%=begin:" "\n\t"
  310. "ldi r30, %4" "\n\t"
  311. "sub r30, %3" "\n\t"
  312. "cpi r30, %4" "\n\t"
  313. "brsh L%=err" "\n\t"
  314. "lsl r30" "\n\t"
  315. "clr r31" "\n\t"
  316. "subi r30, lo8(-(pm(L%=table)))" "\n\t"
  317. "sbci r31, hi8(-(pm(L%=table)))" "\n\t"
  318. "ijmp" "\n\t"
  319. "L%=err:" "\n\t"
  320. "rjmp L%=end" "\n\t"
  321. "L%=table:" "\n\t"
  322. #if (CDC_TX_SIZE == 64)
  323. ASM_COPY8("Y+", "X", "%1")
  324. ASM_COPY8("Y+", "X", "%1")
  325. ASM_COPY8("Y+", "X", "%1")
  326. ASM_COPY8("Y+", "X", "%1")
  327. #endif
  328. #if (CDC_TX_SIZE >= 32)
  329. ASM_COPY8("Y+", "X", "%1")
  330. ASM_COPY8("Y+", "X", "%1")
  331. #endif
  332. #if (CDC_TX_SIZE >= 16)
  333. ASM_COPY8("Y+", "X", "%1")
  334. #endif
  335. ASM_COPY8("Y+", "X", "%1")
  336. "L%=end:" "\n\t"
  337. : "+y" (buffer), "=r" (tmp)
  338. : "x" (&UEDATX), "r" (write_size), "M" (CDC_TX_SIZE)
  339. : "r30", "r31"
  340. );
  341. } while (0);
  342. #endif
  343. // if this completed a packet, transmit it now!
  344. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
  345. transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  346. }
  347. SREG = intr_state;
  348. end:
  349. #if ARDUINO >= 100
  350. return count;
  351. #else
  352. return;
  353. #endif
  354. }
  355. // transmit a string
  356. /*
  357. void usb_serial_class::write(const char *str)
  358. {
  359. uint16_t size=0;
  360. const char *p=str;
  361. while (*p++) size++;
  362. if (size) write((const uint8_t *)str, size);
  363. }
  364. */
  365. // These are Teensy-specific extensions to the Serial object
  366. // immediately transmit any buffered output.
  367. // This doesn't actually transmit the data - that is impossible!
  368. // USB devices only transmit when the host allows, so the best
  369. // we can do is release the FIFO buffer for when the host wants it
  370. void usb_serial_class::send_now(void)
  371. {
  372. uint8_t intr_state;
  373. intr_state = SREG;
  374. cli();
  375. if (usb_configuration && transmit_flush_timer) {
  376. UENUM = CDC_TX_ENDPOINT;
  377. UEINTX = 0x3A;
  378. transmit_flush_timer = 0;
  379. }
  380. SREG = intr_state;
  381. }
  382. uint32_t usb_serial_class::baud(void)
  383. {
  384. return *(uint32_t *)cdc_line_coding;
  385. }
  386. uint8_t usb_serial_class::stopbits(void)
  387. {
  388. return cdc_line_coding[4];
  389. }
  390. uint8_t usb_serial_class::paritytype(void)
  391. {
  392. return cdc_line_coding[5];
  393. }
  394. uint8_t usb_serial_class::numbits(void)
  395. {
  396. return cdc_line_coding[6];
  397. }
  398. uint8_t usb_serial_class::dtr(void)
  399. {
  400. return (cdc_line_rtsdtr & USB_SERIAL_DTR) ? 1 : 0;
  401. }
  402. uint8_t usb_serial_class::rts(void)
  403. {
  404. return (cdc_line_rtsdtr & USB_SERIAL_RTS) ? 1 : 0;
  405. }
  406. usb_serial_class::operator bool()
  407. {
  408. if (usb_configuration &&
  409. (cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS))) {
  410. return true;
  411. }
  412. return false;
  413. }
  414. // Preinstantiate Objects //////////////////////////////////////////////////////
  415. usb_serial_class Serial = usb_serial_class();