Kiibohd Controller
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

usb_serial.c 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2013 PJRC.COM, LLC.
  4. * Modified by Jacob Alexander 2013-2016
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * 1. The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * 2. If the Software is incorporated into a build system that allows
  18. * selection among a list of target devices, then similar target
  19. * devices manufactured by PJRC.COM must be included in the list of
  20. * target devices and selectable in the same manner.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  26. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29. * SOFTWARE.
  30. */
  31. #include <kll_defs.h>
  32. #if enableVirtualSerialPort_define == 1
  33. // ----- Includes -----
  34. // Compiler Includes
  35. #include <string.h> // For memcpy
  36. // Project Includes
  37. #include <Lib/OutputLib.h>
  38. // Local Includes
  39. #include "usb_dev.h"
  40. #include "usb_serial.h"
  41. // ----- Defines -----
  42. #define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */
  43. // Maximum number of transmit packets to queue so we don't starve other endpoints for memory
  44. #define TX_PACKET_LIMIT 8
  45. // When the PC isn't listening, how long do we wait before discarding data? If this is
  46. // too short, we risk losing data during the stalls that are common with ordinary desktop
  47. // software. If it's too long, we stall the user's program when no software is running.
  48. #define TX_TIMEOUT_MSEC 70
  49. #if F_CPU == 96000000
  50. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
  51. #elif F_CPU == 72000000
  52. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) // XXX Correct?
  53. #elif F_CPU == 48000000
  54. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
  55. #elif F_CPU == 24000000
  56. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
  57. #endif
  58. // ----- Variables -----
  59. // Serial port settings (baud rate, control signals, etc) set by the host
  60. // These are *ignored*, except to return back to the host if requested
  61. volatile USBCDCLineCoding usb_cdc_line_coding = {
  62. 115200,
  63. 0,
  64. 0,
  65. 8,
  66. };
  67. volatile uint8_t usb_cdc_line_rtsdtr = 0;
  68. volatile uint8_t usb_cdc_transmit_flush_timer = 0;
  69. static usb_packet_t *rx_packet = NULL;
  70. static usb_packet_t *tx_packet = NULL;
  71. static volatile uint8_t tx_noautoflush = 0;
  72. // When we've suffered the transmit timeout, don't wait again until the computer
  73. // begins accepting data. If no software is running to receive, we'll just discard
  74. // data as rapidly as Serial.print() can generate it, until there's something to
  75. // actually receive it.
  76. static uint8_t transmit_previous_timeout = 0;
  77. // ----- Functions -----
  78. // get the next character, or -1 if nothing received
  79. int usb_serial_getchar()
  80. {
  81. unsigned int i;
  82. int c;
  83. if ( !rx_packet )
  84. {
  85. if ( !usb_configuration )
  86. return -1;
  87. rx_packet = usb_rx( CDC_RX_ENDPOINT );
  88. if ( !rx_packet )
  89. return -1;
  90. }
  91. i = rx_packet->index;
  92. c = rx_packet->buf[i++];
  93. if ( i >= rx_packet->len )
  94. {
  95. usb_free( rx_packet );
  96. rx_packet = NULL;
  97. }
  98. else
  99. {
  100. rx_packet->index = i;
  101. }
  102. return c;
  103. }
  104. // peek at the next character, or -1 if nothing received
  105. int usb_serial_peekchar()
  106. {
  107. if ( !rx_packet )
  108. {
  109. if ( !usb_configuration )
  110. return -1;
  111. rx_packet = usb_rx( CDC_RX_ENDPOINT );
  112. if ( !rx_packet )
  113. return -1;
  114. }
  115. if ( !rx_packet )
  116. return -1;
  117. return rx_packet->buf[ rx_packet->index ];
  118. }
  119. // number of bytes available in the receive buffer
  120. int usb_serial_available()
  121. {
  122. int count = usb_rx_byte_count( CDC_RX_ENDPOINT );
  123. if ( rx_packet )
  124. count += rx_packet->len - rx_packet->index;
  125. return count;
  126. }
  127. // read a block of bytes to a buffer
  128. int usb_serial_read( void *buffer, uint32_t size )
  129. {
  130. uint8_t *p = (uint8_t *)buffer;
  131. uint32_t qty, count=0;
  132. while ( size )
  133. {
  134. if ( !usb_configuration )
  135. break;
  136. if ( !rx_packet )
  137. {
  138. rx:
  139. rx_packet = usb_rx(CDC_RX_ENDPOINT);
  140. if ( !rx_packet )
  141. break;
  142. if ( rx_packet->len == 0 )
  143. {
  144. usb_free(rx_packet);
  145. goto rx;
  146. }
  147. }
  148. qty = rx_packet->len - rx_packet->index;
  149. if ( qty > size )
  150. qty = size;
  151. memcpy( p, rx_packet->buf + rx_packet->index, qty );
  152. p += qty;
  153. count += qty;
  154. size -= qty;
  155. rx_packet->index += qty;
  156. if ( rx_packet->index >= rx_packet->len )
  157. {
  158. usb_free( rx_packet );
  159. rx_packet = NULL;
  160. }
  161. }
  162. return count;
  163. }
  164. // discard any buffered input
  165. void usb_serial_flush_input()
  166. {
  167. usb_packet_t *rx;
  168. if ( !usb_configuration )
  169. return;
  170. if ( rx_packet )
  171. {
  172. usb_free( rx_packet );
  173. rx_packet = NULL;
  174. }
  175. while (1)
  176. {
  177. rx = usb_rx( CDC_RX_ENDPOINT );
  178. if ( !rx )
  179. break;
  180. usb_free( rx );
  181. }
  182. }
  183. // transmit a character. 0 returned on success, -1 on error
  184. int usb_serial_putchar( uint8_t c )
  185. {
  186. return usb_serial_write( &c, 1 );
  187. }
  188. int usb_serial_write( const void *buffer, uint32_t size )
  189. {
  190. uint32_t len;
  191. uint32_t wait_count;
  192. const uint8_t *src = (const uint8_t *)buffer;
  193. uint8_t *dest;
  194. tx_noautoflush = 1;
  195. while ( size > 0 )
  196. {
  197. if ( !tx_packet )
  198. {
  199. wait_count = 0;
  200. while ( 1 )
  201. {
  202. if ( !usb_configuration )
  203. {
  204. tx_noautoflush = 0;
  205. return -1;
  206. }
  207. if ( usb_tx_packet_count( CDC_TX_ENDPOINT ) < TX_PACKET_LIMIT )
  208. {
  209. tx_noautoflush = 1;
  210. tx_packet = usb_malloc();
  211. if ( tx_packet )
  212. break;
  213. tx_noautoflush = 0;
  214. }
  215. if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
  216. {
  217. transmit_previous_timeout = 1;
  218. return -1;
  219. }
  220. yield();
  221. }
  222. }
  223. transmit_previous_timeout = 0;
  224. len = CDC_TX_SIZE - tx_packet->index;
  225. if ( len > size )
  226. len = size;
  227. dest = tx_packet->buf + tx_packet->index;
  228. tx_packet->index += len;
  229. size -= len;
  230. while ( len-- > 0 )
  231. *dest++ = *src++;
  232. if ( tx_packet->index >= CDC_TX_SIZE )
  233. {
  234. tx_packet->len = CDC_TX_SIZE;
  235. usb_tx( CDC_TX_ENDPOINT, tx_packet );
  236. tx_packet = NULL;
  237. }
  238. usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  239. }
  240. tx_noautoflush = 0;
  241. return 0;
  242. }
  243. void usb_serial_flush_output()
  244. {
  245. if ( !usb_configuration )
  246. return;
  247. tx_noautoflush = 1;
  248. if ( tx_packet )
  249. {
  250. usb_cdc_transmit_flush_timer = 0;
  251. tx_packet->len = tx_packet->index;
  252. usb_tx( CDC_TX_ENDPOINT, tx_packet );
  253. tx_packet = NULL;
  254. }
  255. else
  256. {
  257. usb_packet_t *tx = usb_malloc();
  258. if ( tx )
  259. {
  260. usb_cdc_transmit_flush_timer = 0;
  261. usb_tx( CDC_TX_ENDPOINT, tx );
  262. }
  263. else
  264. {
  265. usb_cdc_transmit_flush_timer = 1;
  266. }
  267. }
  268. tx_noautoflush = 0;
  269. }
  270. void usb_serial_flush_callback()
  271. {
  272. if ( tx_noautoflush )
  273. return;
  274. if ( tx_packet )
  275. {
  276. tx_packet->len = tx_packet->index;
  277. usb_tx( CDC_TX_ENDPOINT, tx_packet );
  278. tx_packet = NULL;
  279. } else {
  280. usb_packet_t *tx = usb_malloc();
  281. if ( tx )
  282. {
  283. usb_tx( CDC_TX_ENDPOINT, tx );
  284. }
  285. else
  286. {
  287. usb_cdc_transmit_flush_timer = 1;
  288. }
  289. }
  290. }
  291. #endif