Keyboard firmwares for Atmel AVR and Cortex-M
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.

usb_debug.c 1.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <avr/interrupt.h>
  2. #include "usb_debug.h"
  3. // the time remaining before we transmit any partially full
  4. // packet, or send a zero length packet.
  5. volatile uint8_t debug_flush_timer=0;
  6. // transmit a character. 0 returned on success, -1 on error
  7. int8_t usb_debug_putchar(uint8_t c)
  8. {
  9. static uint8_t previous_timeout=0;
  10. uint8_t timeout, intr_state;
  11. // if we're not online (enumerated and configured), error
  12. if (!usb_configured()) return -1;
  13. // interrupts are disabled so these functions can be
  14. // used from the main program or interrupt context,
  15. // even both in the same program!
  16. intr_state = SREG;
  17. cli();
  18. UENUM = DEBUG_TX_ENDPOINT;
  19. // if we gave up due to timeout before, don't wait again
  20. if (previous_timeout) {
  21. if (!(UEINTX & (1<<RWAL))) {
  22. SREG = intr_state;
  23. return -1;
  24. }
  25. previous_timeout = 0;
  26. }
  27. // wait for the FIFO to be ready to accept data
  28. timeout = UDFNUML + 4;
  29. while (1) {
  30. // are we ready to transmit?
  31. if (UEINTX & (1<<RWAL)) break;
  32. SREG = intr_state;
  33. // have we waited too long?
  34. if (UDFNUML == timeout) {
  35. previous_timeout = 1;
  36. return -1;
  37. }
  38. // has the USB gone offline?
  39. if (!usb_configured()) return -1;
  40. // get ready to try checking again
  41. intr_state = SREG;
  42. cli();
  43. UENUM = DEBUG_TX_ENDPOINT;
  44. }
  45. // actually write the byte into the FIFO
  46. UEDATX = c;
  47. // if this completed a packet, transmit it now!
  48. if (!(UEINTX & (1<<RWAL))) {
  49. UEINTX = 0x3A;
  50. debug_flush_timer = 0;
  51. } else {
  52. debug_flush_timer = 2;
  53. }
  54. SREG = intr_state;
  55. return 0;
  56. }
  57. // immediately transmit any buffered output.
  58. void usb_debug_flush_output(void)
  59. {
  60. uint8_t intr_state;
  61. intr_state = SREG;
  62. cli();
  63. if (debug_flush_timer) {
  64. UENUM = DEBUG_TX_ENDPOINT;
  65. while ((UEINTX & (1<<RWAL))) {
  66. UEDATX = 0;
  67. }
  68. UEINTX = 0x3A;
  69. debug_flush_timer = 0;
  70. }
  71. SREG = intr_state;
  72. }