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