Fix up all the newly imported Teensy code

Change-Id: Id051083a16336617add1d5f16fc7b7d78a30a5fe
diff --git a/motors/usb/usb_serial.c b/motors/usb/usb_serial.c
index a312176..e7e6115 100644
--- a/motors/usb/usb_serial.c
+++ b/motors/usb/usb_serial.c
@@ -28,114 +28,124 @@
  * SOFTWARE.
  */
 
-#include "usb_dev.h"
-#include "usb_serial.h"
-#include "core_pins.h" // for yield()
-//#include "HardwareSerial.h"
-#include <string.h> // for memcpy()
+#include "motors/usb/usb_dev.h"
+#include "motors/usb/usb_serial.h"
+#include <string.h>
 
-// defined by usb_dev.h -> usb_desc.h
-#if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
-#if F_CPU >= 20000000
-
+// These are shared between the two serial ports because they're ignored
+// anyways.
 uint32_t usb_cdc_line_coding[2];
 volatile uint32_t usb_cdc_line_rtsdtr_millis;
 volatile uint8_t usb_cdc_line_rtsdtr=0;
-volatile uint8_t usb_cdc_transmit_flush_timer=0;
 
-static usb_packet_t *rx_packet=NULL;
-static usb_packet_t *tx_packet=NULL;
-static volatile uint8_t tx_noautoflush=0;
+typedef struct {
+	usb_packet_t *rx_packet;
+	usb_packet_t *tx_packet;
+
+	uint32_t rx_endpoint;
+	uint32_t tx_endpoint;
+
+	volatile uint8_t tx_noautoflush;
+	volatile uint8_t transmit_flush_timer;
+} State;
+State states[2];
+
+volatile uint8_t *usb_cdc_transmit_flush_timer =
+    &states[0].transmit_flush_timer;
+volatile uint8_t *usb_cdc2_transmit_flush_timer =
+    &states[1].transmit_flush_timer;
 
 #define TRANSMIT_FLUSH_TIMEOUT	5   /* in milliseconds */
 
+void usb_serial_init(void) {
+	states[0].rx_endpoint = CDC_RX_ENDPOINT;
+	states[0].tx_endpoint = CDC_TX_ENDPOINT;
+	states[1].rx_endpoint = CDC2_RX_ENDPOINT;
+	states[1].tx_endpoint = CDC2_TX_ENDPOINT;
+}
+
 // get the next character, or -1 if nothing received
-int usb_serial_getchar(void)
+int usb_serial_getchar(int port)
 {
+	State *const state = &states[port];
 	unsigned int i;
 	int c;
 
-	if (!rx_packet) {
+	if (!state->rx_packet) {
 		if (!usb_configuration) return -1;
-		rx_packet = usb_rx(CDC_RX_ENDPOINT);
-		if (!rx_packet) return -1;
+		state->rx_packet = usb_rx(state->rx_endpoint);
+		if (!state->rx_packet) return -1;
 	}
-	i = rx_packet->index;
-	c = rx_packet->buf[i++];
-	if (i >= rx_packet->len) {
-		usb_free(rx_packet);
-		rx_packet = NULL;
+	i = state->rx_packet->index;
+	c = state->rx_packet->buf[i++];
+	if (i >= state->rx_packet->len) {
+		usb_free(state->rx_packet);
+		state->rx_packet = NULL;
 	} else {
-		rx_packet->index = i;
+		state->rx_packet->index = i;
 	}
 	return c;
 }
 
 // peek at the next character, or -1 if nothing received
-int usb_serial_peekchar(void)
+int usb_serial_peekchar(int port)
 {
-	if (!rx_packet) {
+	State *const state = &states[port];
+	if (!state->rx_packet) {
 		if (!usb_configuration) return -1;
-		rx_packet = usb_rx(CDC_RX_ENDPOINT);
-		if (!rx_packet) return -1;
+		state->rx_packet = usb_rx(state->rx_endpoint);
+		if (!state->rx_packet) return -1;
 	}
-	if (!rx_packet) return -1;
-	return rx_packet->buf[rx_packet->index];
-}
-
-// number of bytes available in the receive buffer
-int usb_serial_available(void)
-{
-	int count;
-	count = usb_rx_byte_count(CDC_RX_ENDPOINT);
-	if (rx_packet) count += rx_packet->len - rx_packet->index;
-	return count;
+	if (!state->rx_packet) return -1;
+	return state->rx_packet->buf[state->rx_packet->index];
 }
 
 // read a block of bytes to a buffer
-int usb_serial_read(void *buffer, uint32_t size)
+int usb_serial_read(int port, void *buffer, uint32_t size)
 {
+	State *const state = &states[port];
 	uint8_t *p = (uint8_t *)buffer;
 	uint32_t qty, count=0;
 
 	while (size) {
 		if (!usb_configuration) break;
-		if (!rx_packet) {
+		if (!state->rx_packet) {
 			rx:
-			rx_packet = usb_rx(CDC_RX_ENDPOINT);
-			if (!rx_packet) break;
-			if (rx_packet->len == 0) {
-				usb_free(rx_packet);
+			state->rx_packet = usb_rx(state->rx_endpoint);
+			if (!state->rx_packet) break;
+			if (state->rx_packet->len == 0) {
+				usb_free(state->rx_packet);
 				goto rx;
 			}
 		}
-		qty = rx_packet->len - rx_packet->index;
+		qty = state->rx_packet->len - state->rx_packet->index;
 		if (qty > size) qty = size;
-		memcpy(p, rx_packet->buf + rx_packet->index, qty);
+		memcpy(p, state->rx_packet->buf + state->rx_packet->index, qty);
 		p += qty;
 		count += qty;
 		size -= qty;
-		rx_packet->index += qty;
-		if (rx_packet->index >= rx_packet->len) {
-			usb_free(rx_packet);
-			rx_packet = NULL;
+		state->rx_packet->index += qty;
+		if (state->rx_packet->index >= state->rx_packet->len) {
+			usb_free(state->rx_packet);
+			state->rx_packet = NULL;
 		}
 	}
 	return count;
 }
 
 // discard any buffered input
-void usb_serial_flush_input(void)
+void usb_serial_flush_input(int port)
 {
+	State *const state = &states[port];
 	usb_packet_t *rx;
 
 	if (!usb_configuration) return;
-	if (rx_packet) {
-		usb_free(rx_packet);
-		rx_packet = NULL;
+	if (state->rx_packet) {
+		usb_free(state->rx_packet);
+		state->rx_packet = NULL;
 	}
 	while (1) {
-		rx = usb_rx(CDC_RX_ENDPOINT);
+		rx = usb_rx(state->rx_endpoint);
 		if (!rx) break;
 		usb_free(rx);
 	}
@@ -173,133 +183,83 @@
   #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
 #endif
 
-// When we've suffered the transmit timeout, don't wait again until the computer
-// begins accepting data.  If no software is running to receive, we'll just discard
-// data as rapidly as Serial.print() can generate it, until there's something to
-// actually receive it.
-static uint8_t transmit_previous_timeout=0;
-
-
-// transmit a character.  0 returned on success, -1 on error
-int usb_serial_putchar(uint8_t c)
+int usb_serial_write(int port, const void *buffer, uint32_t size)
 {
-	return usb_serial_write(&c, 1);
-}
-
-
-int usb_serial_write(const void *buffer, uint32_t size)
-{
-	uint32_t ret = size;
+	State *const state = &states[port];
 	uint32_t len;
-	uint32_t wait_count;
 	const uint8_t *src = (const uint8_t *)buffer;
 	uint8_t *dest;
 
-	tx_noautoflush = 1;
+	state->tx_noautoflush = 1;
 	while (size > 0) {
-		if (!tx_packet) {
-			wait_count = 0;
+		if (!state->tx_packet) {
 			while (1) {
 				if (!usb_configuration) {
-					tx_noautoflush = 0;
+					state->tx_noautoflush = 0;
 					return -1;
 				}
-				if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) {
-					tx_noautoflush = 1;
-					tx_packet = usb_malloc();
-					if (tx_packet) break;
-					tx_noautoflush = 0;
+				if (usb_tx_packet_count(state->tx_endpoint) < TX_PACKET_LIMIT) {
+					state->tx_noautoflush = 1;
+					state->tx_packet = usb_malloc();
+					if (state->tx_packet) break;
+					state->tx_noautoflush = 0;
 				}
-				if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
-					transmit_previous_timeout = 1;
-					return -1;
-				}
-				yield();
+				return -1;
 			}
 		}
-		transmit_previous_timeout = 0;
-		len = CDC_TX_SIZE - tx_packet->index;
+		len = CDC_TX_SIZE - state->tx_packet->index;
 		if (len > size) len = size;
-		dest = tx_packet->buf + tx_packet->index;
-		tx_packet->index += len;
+		dest = state->tx_packet->buf + state->tx_packet->index;
+		state->tx_packet->index += len;
 		size -= len;
 		while (len-- > 0) *dest++ = *src++;
-		if (tx_packet->index >= CDC_TX_SIZE) {
-			tx_packet->len = CDC_TX_SIZE;
-			usb_tx(CDC_TX_ENDPOINT, tx_packet);
-			tx_packet = NULL;
+		if (state->tx_packet->index >= CDC_TX_SIZE) {
+			state->tx_packet->len = CDC_TX_SIZE;
+			usb_tx(state->tx_endpoint, state->tx_packet);
+			state->tx_packet = NULL;
 		}
-		usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
+		state->transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
 	}
-	tx_noautoflush = 0;
-	return ret;
+	state->tx_noautoflush = 0;
+	return size;
 }
 
-int usb_serial_write_buffer_free(void)
+void usb_serial_flush_output(int port)
 {
-	uint32_t len;
-
-	tx_noautoflush = 1;
-	if (!tx_packet) {
-		if (!usb_configuration ||
-		  usb_tx_packet_count(CDC_TX_ENDPOINT) >= TX_PACKET_LIMIT ||
-		  (tx_packet = usb_malloc()) == NULL) {
-			tx_noautoflush = 0;
-			return 0;
-		}
-	}
-	len = CDC_TX_SIZE - tx_packet->index;
-	// TODO: Perhaps we need "usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT"
-	// added here, so the SOF interrupt can't take away the available buffer
-	// space we just promised the user could write without blocking?
-	// But does this come with other performance downsides?  Could it lead to
-	// buffer data never actually transmitting in some usage cases?  More
-	// investigation is needed.
-	// https://github.com/PaulStoffregen/cores/issues/10#issuecomment-61514955
-	tx_noautoflush = 0;
-	return len;
-}
-
-void usb_serial_flush_output(void)
-{
+	State *const state = &states[port];
 	if (!usb_configuration) return;
-	tx_noautoflush = 1;
-	if (tx_packet) {
-		usb_cdc_transmit_flush_timer = 0;
-		tx_packet->len = tx_packet->index;
-		usb_tx(CDC_TX_ENDPOINT, tx_packet);
-		tx_packet = NULL;
+	state->tx_noautoflush = 1;
+	if (state->tx_packet) {
+		state->transmit_flush_timer = 0;
+		state->tx_packet->len = state->tx_packet->index;
+		usb_tx(state->tx_endpoint, state->tx_packet);
+		state->tx_packet = NULL;
 	} else {
 		usb_packet_t *tx = usb_malloc();
 		if (tx) {
-			usb_cdc_transmit_flush_timer = 0;
-			usb_tx(CDC_TX_ENDPOINT, tx);
+			state->transmit_flush_timer = 0;
+			usb_tx(state->tx_endpoint, tx);
 		} else {
-			usb_cdc_transmit_flush_timer = 1;
+			state->transmit_flush_timer = 1;
 		}
 	}
-	tx_noautoflush = 0;
+	state->tx_noautoflush = 0;
 }
 
-void usb_serial_flush_callback(void)
+void usb_serial_flush_callback(int port)
 {
-	if (tx_noautoflush) return;
-	if (tx_packet) {
-		tx_packet->len = tx_packet->index;
-		usb_tx(CDC_TX_ENDPOINT, tx_packet);
-		tx_packet = NULL;
+	State *const state = &states[port];
+	if (state->tx_noautoflush) return;
+	if (state->tx_packet) {
+		state->tx_packet->len = state->tx_packet->index;
+		usb_tx(state->tx_endpoint, state->tx_packet);
+		state->tx_packet = NULL;
 	} else {
 		usb_packet_t *tx = usb_malloc();
 		if (tx) {
-			usb_tx(CDC_TX_ENDPOINT, tx);
+			usb_tx(state->tx_endpoint, tx);
 		} else {
-			usb_cdc_transmit_flush_timer = 1;
+			state->transmit_flush_timer = 1;
 		}
 	}
 }
-
-
-
-
-#endif // F_CPU
-#endif // CDC_STATUS_INTERFACE && CDC_DATA_INTERFACE