From 7fd9003f59ad6a1de8d8b70fae74ba16df666c09 Mon Sep 17 00:00:00 2001
From: tmk <nobody@nowhere>
Date: Thu, 23 Sep 2010 20:23:50 +0900
Subject: divide usb_keyboard_debug.[c|h] into usb_device, usb_keyboard,
 usb_debug.

---
 usb_debug.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 usb_debug.c

(limited to 'usb_debug.c')

diff --git a/usb_debug.c b/usb_debug.c
new file mode 100644
index 0000000000..97590184a5
--- /dev/null
+++ b/usb_debug.c
@@ -0,0 +1,80 @@
+#include <avr/interrupt.h>
+#include "usb_debug.h"
+
+
+// the time remaining before we transmit any partially full
+// packet, or send a zero length packet.
+volatile uint8_t debug_flush_timer=0;
+
+
+// transmit a character.  0 returned on success, -1 on error
+int8_t usb_debug_putchar(uint8_t c)
+{
+	static uint8_t previous_timeout=0;
+	uint8_t timeout, intr_state;
+
+	// if we're not online (enumerated and configured), error
+	if (!usb_configured()) return -1;
+	// interrupts are disabled so these functions can be
+	// used from the main program or interrupt context,
+	// even both in the same program!
+	intr_state = SREG;
+	cli();
+	UENUM = DEBUG_TX_ENDPOINT;
+	// if we gave up due to timeout before, don't wait again
+	if (previous_timeout) {
+		if (!(UEINTX & (1<<RWAL))) {
+			SREG = intr_state;
+			return -1;
+		}
+		previous_timeout = 0;
+	}
+	// wait for the FIFO to be ready to accept data
+	timeout = UDFNUML + 4;
+	while (1) {
+		// are we ready to transmit?
+		if (UEINTX & (1<<RWAL)) break;
+		SREG = intr_state;
+		// have we waited too long?
+		if (UDFNUML == timeout) {
+			previous_timeout = 1;
+			return -1;
+		}
+		// has the USB gone offline?
+		if (!usb_configured()) return -1;
+		// get ready to try checking again
+		intr_state = SREG;
+		cli();
+		UENUM = DEBUG_TX_ENDPOINT;
+	}
+	// actually write the byte into the FIFO
+	UEDATX = c;
+	// if this completed a packet, transmit it now!
+	if (!(UEINTX & (1<<RWAL))) {
+		UEINTX = 0x3A;
+		debug_flush_timer = 0;
+	} else {
+		debug_flush_timer = 2;
+	}
+	SREG = intr_state;
+	return 0;
+}
+
+
+// immediately transmit any buffered output.
+void usb_debug_flush_output(void)
+{
+	uint8_t intr_state;
+
+	intr_state = SREG;
+	cli();
+	if (debug_flush_timer) {
+		UENUM = DEBUG_TX_ENDPOINT;
+		while ((UEINTX & (1<<RWAL))) {
+			UEDATX = 0;
+		}
+		UEINTX = 0x3A;
+		debug_flush_timer = 0;
+	}
+	SREG = intr_state;
+}
-- 
cgit v1.2.3