Kiibohd Controller
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
このリポジトリはアーカイブされています。 ファイルの閲覧とクローンは可能ですが、プッシュや、課題・プルリクエストのオープンはできません。

usb_serial.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #include "usb_dev.h"
  2. #include "usb_serial.h"
  3. #include <Lib/USBLib.h>
  4. // defined by usb_dev.h -> usb_desc.h
  5. #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
  6. uint8_t usb_cdc_line_coding[7];
  7. volatile uint8_t usb_cdc_line_rtsdtr=0;
  8. volatile uint8_t usb_cdc_transmit_flush_timer=0;
  9. static usb_packet_t *rx_packet=NULL;
  10. static usb_packet_t *tx_packet=NULL;
  11. static volatile uint8_t tx_noautoflush=0;
  12. #define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */
  13. static void usb_serial_receive(void)
  14. {
  15. if (!usb_configuration) return;
  16. if (rx_packet) return;
  17. while (1) {
  18. rx_packet = usb_rx(CDC_RX_ENDPOINT);
  19. if (rx_packet == NULL) return;
  20. if (rx_packet->len > 0) return;
  21. usb_free(rx_packet);
  22. rx_packet = NULL;
  23. }
  24. }
  25. // get the next character, or -1 if nothing received
  26. int usb_serial_getchar(void)
  27. {
  28. unsigned int i;
  29. int c;
  30. usb_serial_receive();
  31. if (!rx_packet) return -1;
  32. i = rx_packet->index;
  33. c = rx_packet->buf[i++];
  34. if (i >= rx_packet->len) {
  35. usb_free(rx_packet);
  36. rx_packet = NULL;
  37. } else {
  38. rx_packet->index = i;
  39. }
  40. return c;
  41. }
  42. // peek at the next character, or -1 if nothing received
  43. int usb_serial_peekchar(void)
  44. {
  45. usb_serial_receive();
  46. if (!rx_packet) return -1;
  47. return rx_packet->buf[rx_packet->index];
  48. }
  49. // number of bytes available in the receive buffer
  50. int usb_serial_available(void)
  51. {
  52. int count=0;
  53. if (usb_configuration) {
  54. count = usb_rx_byte_count(CDC_RX_ENDPOINT);
  55. }
  56. if (rx_packet) count += rx_packet->len - rx_packet->index;
  57. return count;
  58. }
  59. // discard any buffered input
  60. void usb_serial_flush_input(void)
  61. {
  62. usb_packet_t *rx;
  63. if (!usb_configuration) return;
  64. if (rx_packet) {
  65. usb_free(rx_packet);
  66. rx_packet = NULL;
  67. }
  68. while (1) {
  69. rx = usb_rx(CDC_RX_ENDPOINT);
  70. if (!rx) break;
  71. usb_free(rx);
  72. }
  73. }
  74. // Maximum number of transmit packets to queue so we don't starve other endpoints for memory
  75. #define TX_PACKET_LIMIT 8
  76. // When the PC isn't listening, how long do we wait before discarding data? If this is
  77. // too short, we risk losing data during the stalls that are common with ordinary desktop
  78. // software. If it's too long, we stall the user's program when no software is running.
  79. #define TX_TIMEOUT_MSEC 70
  80. #if F_CPU == 96000000
  81. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
  82. #elif F_CPU == 48000000
  83. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
  84. #elif F_CPU == 24000000
  85. #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
  86. #endif
  87. // When we've suffered the transmit timeout, don't wait again until the computer
  88. // begins accepting data. If no software is running to receive, we'll just discard
  89. // data as rapidly as Serial.print() can generate it, until there's something to
  90. // actually receive it.
  91. static uint8_t transmit_previous_timeout=0;
  92. // transmit a character. 0 returned on success, -1 on error
  93. int usb_serial_putchar(uint8_t c)
  94. {
  95. #if 1
  96. return usb_serial_write(&c, 1);
  97. #endif
  98. #if 0
  99. uint32_t wait_count;
  100. tx_noautoflush = 1;
  101. if (!tx_packet) {
  102. wait_count = 0;
  103. while (1) {
  104. if (!usb_configuration) {
  105. tx_noautoflush = 0;
  106. return -1;
  107. }
  108. if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) {
  109. tx_noautoflush = 1;
  110. tx_packet = usb_malloc();
  111. if (tx_packet) break;
  112. tx_noautoflush = 0;
  113. }
  114. if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
  115. transmit_previous_timeout = 1;
  116. return -1;
  117. }
  118. }
  119. }
  120. transmit_previous_timeout = 0;
  121. tx_packet->buf[tx_packet->index++] = c;
  122. if (tx_packet->index < CDC_TX_SIZE) {
  123. usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  124. } else {
  125. tx_packet->len = CDC_TX_SIZE;
  126. usb_cdc_transmit_flush_timer = 0;
  127. usb_tx(CDC_TX_ENDPOINT, tx_packet);
  128. tx_packet = NULL;
  129. }
  130. tx_noautoflush = 0;
  131. return 0;
  132. #endif
  133. }
  134. int usb_serial_write(const void *buffer, uint32_t size)
  135. {
  136. #if 1
  137. uint32_t len;
  138. uint32_t wait_count;
  139. const uint8_t *src = (const uint8_t *)buffer;
  140. uint8_t *dest;
  141. tx_noautoflush = 1;
  142. while (size > 0) {
  143. if (!tx_packet) {
  144. wait_count = 0;
  145. while (1) {
  146. if (!usb_configuration) {
  147. tx_noautoflush = 0;
  148. return -1;
  149. }
  150. if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) {
  151. tx_noautoflush = 1;
  152. tx_packet = usb_malloc();
  153. if (tx_packet) break;
  154. tx_noautoflush = 0;
  155. }
  156. if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
  157. transmit_previous_timeout = 1;
  158. return -1;
  159. }
  160. yield();
  161. }
  162. }
  163. transmit_previous_timeout = 0;
  164. len = CDC_TX_SIZE - tx_packet->index;
  165. if (len > size) len = size;
  166. dest = tx_packet->buf + tx_packet->index;
  167. tx_packet->index += len;
  168. size -= len;
  169. while (len-- > 0) *dest++ = *src++;
  170. if (tx_packet->index < CDC_TX_SIZE) {
  171. usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  172. } else {
  173. tx_packet->len = CDC_TX_SIZE;
  174. usb_cdc_transmit_flush_timer = 0;
  175. usb_tx(CDC_TX_ENDPOINT, tx_packet);
  176. tx_packet = NULL;
  177. }
  178. }
  179. tx_noautoflush = 0;
  180. return 0;
  181. #endif
  182. #if 0
  183. const uint8_t *p = (const uint8_t *)buffer;
  184. int r;
  185. while (size) {
  186. r = usb_serial_putchar(*p++);
  187. if (r < 0) return -1;
  188. size--;
  189. }
  190. return 0;
  191. #endif
  192. }
  193. void usb_serial_flush_output(void)
  194. {
  195. if (!usb_configuration) return;
  196. //serial_print("usb_serial_flush_output\n");
  197. if (tx_packet && tx_packet->index > 0) {
  198. usb_cdc_transmit_flush_timer = 0;
  199. tx_packet->len = tx_packet->index;
  200. usb_tx(CDC_TX_ENDPOINT, tx_packet);
  201. tx_packet = NULL;
  202. }
  203. // while (usb_tx_byte_count(CDC_TX_ENDPOINT) > 0) ; // wait
  204. }
  205. void usb_serial_flush_callback(void)
  206. {
  207. if (tx_noautoflush) return;
  208. //serial_print("usb_flush_callback \n");
  209. tx_packet->len = tx_packet->index;
  210. usb_tx(CDC_TX_ENDPOINT, tx_packet);
  211. tx_packet = NULL;
  212. //serial_print("usb_flush_callback end\n");
  213. }
  214. #endif // CDC_STATUS_INTERFACE && CDC_DATA_INTERFACE