teensy3: usb_serial: Fix port 2/3 mismatchteensy4-core
*/ | */ | ||||
#include "usb_dev.h" | #include "usb_dev.h" | ||||
#include "usb_serial3.h" | |||||
#include "usb_serial2.h" | |||||
#include "core_pins.h" // for yield() | #include "core_pins.h" // for yield() | ||||
//#include "HardwareSerial.h" | //#include "HardwareSerial.h" | ||||
#include <string.h> // for memcpy() | #include <string.h> // for memcpy() | ||||
// defined by usb_dev.h -> usb_desc.h | // defined by usb_dev.h -> usb_desc.h | ||||
#if defined(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE) | |||||
#if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE) | |||||
#if F_CPU >= 20000000 | #if F_CPU >= 20000000 | ||||
uint32_t usb_cdc3_line_coding[2]; | |||||
volatile uint32_t usb_cdc3_line_rtsdtr_millis; | |||||
volatile uint8_t usb_cdc3_line_rtsdtr=0; | |||||
volatile uint8_t usb_cdc3_transmit_flush_timer=0; | |||||
uint32_t usb_cdc2_line_coding[2]; | |||||
volatile uint32_t usb_cdc2_line_rtsdtr_millis; | |||||
volatile uint8_t usb_cdc2_line_rtsdtr=0; | |||||
volatile uint8_t usb_cdc2_transmit_flush_timer=0; | |||||
static usb_packet_t *rx_packet=NULL; | static usb_packet_t *rx_packet=NULL; | ||||
static usb_packet_t *tx_packet=NULL; | static usb_packet_t *tx_packet=NULL; | ||||
#define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ | #define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ | ||||
// get the next character, or -1 if nothing received | // get the next character, or -1 if nothing received | ||||
int usb_serial3_getchar(void) | |||||
int usb_serial2_getchar(void) | |||||
{ | { | ||||
unsigned int i; | unsigned int i; | ||||
int c; | int c; | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
if (!usb_configuration) return -1; | if (!usb_configuration) return -1; | ||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
i = rx_packet->index; | i = rx_packet->index; | ||||
} | } | ||||
// peek at the next character, or -1 if nothing received | // peek at the next character, or -1 if nothing received | ||||
int usb_serial3_peekchar(void) | |||||
int usb_serial2_peekchar(void) | |||||
{ | { | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
if (!usb_configuration) return -1; | if (!usb_configuration) return -1; | ||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
// number of bytes available in the receive buffer | // number of bytes available in the receive buffer | ||||
int usb_serial3_available(void) | |||||
int usb_serial2_available(void) | |||||
{ | { | ||||
int count; | int count; | ||||
count = usb_rx_byte_count(CDC3_RX_ENDPOINT); | |||||
count = usb_rx_byte_count(CDC2_RX_ENDPOINT); | |||||
if (rx_packet) count += rx_packet->len - rx_packet->index; | if (rx_packet) count += rx_packet->len - rx_packet->index; | ||||
return count; | return count; | ||||
} | } | ||||
// read a block of bytes to a buffer | // read a block of bytes to a buffer | ||||
int usb_serial3_read(void *buffer, uint32_t size) | |||||
int usb_serial2_read(void *buffer, uint32_t size) | |||||
{ | { | ||||
uint8_t *p = (uint8_t *)buffer; | uint8_t *p = (uint8_t *)buffer; | ||||
uint32_t qty, count=0; | uint32_t qty, count=0; | ||||
if (!usb_configuration) break; | if (!usb_configuration) break; | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
rx: | rx: | ||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
if (!rx_packet) break; | if (!rx_packet) break; | ||||
if (rx_packet->len == 0) { | if (rx_packet->len == 0) { | ||||
usb_free(rx_packet); | usb_free(rx_packet); | ||||
} | } | ||||
// discard any buffered input | // discard any buffered input | ||||
void usb_serial3_flush_input(void) | |||||
void usb_serial2_flush_input(void) | |||||
{ | { | ||||
usb_packet_t *rx; | usb_packet_t *rx; | ||||
rx_packet = NULL; | rx_packet = NULL; | ||||
} | } | ||||
while (1) { | while (1) { | ||||
rx = usb_rx(CDC3_RX_ENDPOINT); | |||||
rx = usb_rx(CDC2_RX_ENDPOINT); | |||||
if (!rx) break; | if (!rx) break; | ||||
usb_free(rx); | usb_free(rx); | ||||
} | } | ||||
// transmit a character. 0 returned on success, -1 on error | // transmit a character. 0 returned on success, -1 on error | ||||
int usb_serial3_putchar(uint8_t c) | |||||
int usb_serial2_putchar(uint8_t c) | |||||
{ | { | ||||
return usb_serial3_write(&c, 1); | |||||
return usb_serial2_write(&c, 1); | |||||
} | } | ||||
int usb_serial3_write(const void *buffer, uint32_t size) | |||||
int usb_serial2_write(const void *buffer, uint32_t size) | |||||
{ | { | ||||
uint32_t ret = size; | uint32_t ret = size; | ||||
uint32_t len; | uint32_t len; | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return -1; | return -1; | ||||
} | } | ||||
if (usb_tx_packet_count(CDC3_TX_ENDPOINT) < TX_PACKET_LIMIT) { | |||||
if (usb_tx_packet_count(CDC2_TX_ENDPOINT) < TX_PACKET_LIMIT) { | |||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
tx_packet = usb_malloc(); | tx_packet = usb_malloc(); | ||||
if (tx_packet) break; | if (tx_packet) break; | ||||
} | } | ||||
} | } | ||||
transmit_previous_timeout = 0; | transmit_previous_timeout = 0; | ||||
len = CDC3_TX_SIZE - tx_packet->index; | |||||
len = CDC2_TX_SIZE - tx_packet->index; | |||||
if (len > size) len = size; | if (len > size) len = size; | ||||
dest = tx_packet->buf + tx_packet->index; | dest = tx_packet->buf + tx_packet->index; | ||||
tx_packet->index += len; | tx_packet->index += len; | ||||
size -= len; | size -= len; | ||||
while (len-- > 0) *dest++ = *src++; | while (len-- > 0) *dest++ = *src++; | ||||
if (tx_packet->index >= CDC3_TX_SIZE) { | |||||
tx_packet->len = CDC3_TX_SIZE; | |||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
if (tx_packet->index >= CDC2_TX_SIZE) { | |||||
tx_packet->len = CDC2_TX_SIZE; | |||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} | } | ||||
usb_cdc3_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; | |||||
usb_cdc2_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; | |||||
} | } | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return ret; | return ret; | ||||
} | } | ||||
int usb_serial3_write_buffer_free(void) | |||||
int usb_serial2_write_buffer_free(void) | |||||
{ | { | ||||
uint32_t len; | uint32_t len; | ||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
if (!tx_packet) { | if (!tx_packet) { | ||||
if (!usb_configuration || | if (!usb_configuration || | ||||
usb_tx_packet_count(CDC3_TX_ENDPOINT) >= TX_PACKET_LIMIT || | |||||
usb_tx_packet_count(CDC2_TX_ENDPOINT) >= TX_PACKET_LIMIT || | |||||
(tx_packet = usb_malloc()) == NULL) { | (tx_packet = usb_malloc()) == NULL) { | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
} | } | ||||
len = CDC3_TX_SIZE - tx_packet->index; | |||||
len = CDC2_TX_SIZE - tx_packet->index; | |||||
// TODO: Perhaps we need "usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT" | // 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 | // added here, so the SOF interrupt can't take away the available buffer | ||||
// space we just promised the user could write without blocking? | // space we just promised the user could write without blocking? | ||||
return len; | return len; | ||||
} | } | ||||
void usb_serial3_flush_output(void) | |||||
void usb_serial2_flush_output(void) | |||||
{ | { | ||||
if (!usb_configuration) return; | if (!usb_configuration) return; | ||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
if (tx_packet) { | if (tx_packet) { | ||||
usb_cdc3_transmit_flush_timer = 0; | |||||
usb_cdc2_transmit_flush_timer = 0; | |||||
tx_packet->len = tx_packet->index; | tx_packet->len = tx_packet->index; | ||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} else { | } else { | ||||
usb_packet_t *tx = usb_malloc(); | usb_packet_t *tx = usb_malloc(); | ||||
if (tx) { | if (tx) { | ||||
usb_cdc3_transmit_flush_timer = 0; | |||||
usb_tx(CDC3_TX_ENDPOINT, tx); | |||||
usb_cdc2_transmit_flush_timer = 0; | |||||
usb_tx(CDC2_TX_ENDPOINT, tx); | |||||
} else { | } else { | ||||
usb_cdc3_transmit_flush_timer = 1; | |||||
usb_cdc2_transmit_flush_timer = 1; | |||||
} | } | ||||
} | } | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
} | } | ||||
void usb_serial3_flush_callback(void) | |||||
void usb_serial2_flush_callback(void) | |||||
{ | { | ||||
if (tx_noautoflush) return; | if (tx_noautoflush) return; | ||||
if (tx_packet) { | if (tx_packet) { | ||||
tx_packet->len = tx_packet->index; | tx_packet->len = tx_packet->index; | ||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} else { | } else { | ||||
usb_packet_t *tx = usb_malloc(); | usb_packet_t *tx = usb_malloc(); | ||||
if (tx) { | if (tx) { | ||||
usb_tx(CDC3_TX_ENDPOINT, tx); | |||||
usb_tx(CDC2_TX_ENDPOINT, tx); | |||||
} else { | } else { | ||||
usb_cdc3_transmit_flush_timer = 1; | |||||
usb_cdc2_transmit_flush_timer = 1; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
#endif // F_CPU | #endif // F_CPU | ||||
#endif // CDC3_STATUS_INTERFACE && CDC3_DATA_INTERFACE | |||||
#endif // CDC2_STATUS_INTERFACE && CDC2_DATA_INTERFACE |
*/ | */ | ||||
#include "usb_dev.h" | #include "usb_dev.h" | ||||
#include "usb_serial2.h" | |||||
#include "usb_serial3.h" | |||||
#include "core_pins.h" // for yield() | #include "core_pins.h" // for yield() | ||||
//#include "HardwareSerial.h" | //#include "HardwareSerial.h" | ||||
#include <string.h> // for memcpy() | #include <string.h> // for memcpy() | ||||
// defined by usb_dev.h -> usb_desc.h | // defined by usb_dev.h -> usb_desc.h | ||||
#if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE) | |||||
#if defined(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE) | |||||
#if F_CPU >= 20000000 | #if F_CPU >= 20000000 | ||||
uint32_t usb_cdc2_line_coding[2]; | |||||
volatile uint32_t usb_cdc2_line_rtsdtr_millis; | |||||
volatile uint8_t usb_cdc2_line_rtsdtr=0; | |||||
volatile uint8_t usb_cdc2_transmit_flush_timer=0; | |||||
uint32_t usb_cdc3_line_coding[2]; | |||||
volatile uint32_t usb_cdc3_line_rtsdtr_millis; | |||||
volatile uint8_t usb_cdc3_line_rtsdtr=0; | |||||
volatile uint8_t usb_cdc3_transmit_flush_timer=0; | |||||
static usb_packet_t *rx_packet=NULL; | static usb_packet_t *rx_packet=NULL; | ||||
static usb_packet_t *tx_packet=NULL; | static usb_packet_t *tx_packet=NULL; | ||||
#define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ | #define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ | ||||
// get the next character, or -1 if nothing received | // get the next character, or -1 if nothing received | ||||
int usb_serial2_getchar(void) | |||||
int usb_serial3_getchar(void) | |||||
{ | { | ||||
unsigned int i; | unsigned int i; | ||||
int c; | int c; | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
if (!usb_configuration) return -1; | if (!usb_configuration) return -1; | ||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
i = rx_packet->index; | i = rx_packet->index; | ||||
} | } | ||||
// peek at the next character, or -1 if nothing received | // peek at the next character, or -1 if nothing received | ||||
int usb_serial2_peekchar(void) | |||||
int usb_serial3_peekchar(void) | |||||
{ | { | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
if (!usb_configuration) return -1; | if (!usb_configuration) return -1; | ||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
if (!rx_packet) return -1; | if (!rx_packet) return -1; | ||||
} | } | ||||
// number of bytes available in the receive buffer | // number of bytes available in the receive buffer | ||||
int usb_serial2_available(void) | |||||
int usb_serial3_available(void) | |||||
{ | { | ||||
int count; | int count; | ||||
count = usb_rx_byte_count(CDC2_RX_ENDPOINT); | |||||
count = usb_rx_byte_count(CDC3_RX_ENDPOINT); | |||||
if (rx_packet) count += rx_packet->len - rx_packet->index; | if (rx_packet) count += rx_packet->len - rx_packet->index; | ||||
return count; | return count; | ||||
} | } | ||||
// read a block of bytes to a buffer | // read a block of bytes to a buffer | ||||
int usb_serial2_read(void *buffer, uint32_t size) | |||||
int usb_serial3_read(void *buffer, uint32_t size) | |||||
{ | { | ||||
uint8_t *p = (uint8_t *)buffer; | uint8_t *p = (uint8_t *)buffer; | ||||
uint32_t qty, count=0; | uint32_t qty, count=0; | ||||
if (!usb_configuration) break; | if (!usb_configuration) break; | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
rx: | rx: | ||||
rx_packet = usb_rx(CDC2_RX_ENDPOINT); | |||||
rx_packet = usb_rx(CDC3_RX_ENDPOINT); | |||||
if (!rx_packet) break; | if (!rx_packet) break; | ||||
if (rx_packet->len == 0) { | if (rx_packet->len == 0) { | ||||
usb_free(rx_packet); | usb_free(rx_packet); | ||||
} | } | ||||
// discard any buffered input | // discard any buffered input | ||||
void usb_serial2_flush_input(void) | |||||
void usb_serial3_flush_input(void) | |||||
{ | { | ||||
usb_packet_t *rx; | usb_packet_t *rx; | ||||
rx_packet = NULL; | rx_packet = NULL; | ||||
} | } | ||||
while (1) { | while (1) { | ||||
rx = usb_rx(CDC2_RX_ENDPOINT); | |||||
rx = usb_rx(CDC3_RX_ENDPOINT); | |||||
if (!rx) break; | if (!rx) break; | ||||
usb_free(rx); | usb_free(rx); | ||||
} | } | ||||
// transmit a character. 0 returned on success, -1 on error | // transmit a character. 0 returned on success, -1 on error | ||||
int usb_serial2_putchar(uint8_t c) | |||||
int usb_serial3_putchar(uint8_t c) | |||||
{ | { | ||||
return usb_serial2_write(&c, 1); | |||||
return usb_serial3_write(&c, 1); | |||||
} | } | ||||
int usb_serial2_write(const void *buffer, uint32_t size) | |||||
int usb_serial3_write(const void *buffer, uint32_t size) | |||||
{ | { | ||||
uint32_t ret = size; | uint32_t ret = size; | ||||
uint32_t len; | uint32_t len; | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return -1; | return -1; | ||||
} | } | ||||
if (usb_tx_packet_count(CDC2_TX_ENDPOINT) < TX_PACKET_LIMIT) { | |||||
if (usb_tx_packet_count(CDC3_TX_ENDPOINT) < TX_PACKET_LIMIT) { | |||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
tx_packet = usb_malloc(); | tx_packet = usb_malloc(); | ||||
if (tx_packet) break; | if (tx_packet) break; | ||||
} | } | ||||
} | } | ||||
transmit_previous_timeout = 0; | transmit_previous_timeout = 0; | ||||
len = CDC2_TX_SIZE - tx_packet->index; | |||||
len = CDC3_TX_SIZE - tx_packet->index; | |||||
if (len > size) len = size; | if (len > size) len = size; | ||||
dest = tx_packet->buf + tx_packet->index; | dest = tx_packet->buf + tx_packet->index; | ||||
tx_packet->index += len; | tx_packet->index += len; | ||||
size -= len; | size -= len; | ||||
while (len-- > 0) *dest++ = *src++; | while (len-- > 0) *dest++ = *src++; | ||||
if (tx_packet->index >= CDC2_TX_SIZE) { | |||||
tx_packet->len = CDC2_TX_SIZE; | |||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
if (tx_packet->index >= CDC3_TX_SIZE) { | |||||
tx_packet->len = CDC3_TX_SIZE; | |||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} | } | ||||
usb_cdc2_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; | |||||
usb_cdc3_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; | |||||
} | } | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return ret; | return ret; | ||||
} | } | ||||
int usb_serial2_write_buffer_free(void) | |||||
int usb_serial3_write_buffer_free(void) | |||||
{ | { | ||||
uint32_t len; | uint32_t len; | ||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
if (!tx_packet) { | if (!tx_packet) { | ||||
if (!usb_configuration || | if (!usb_configuration || | ||||
usb_tx_packet_count(CDC2_TX_ENDPOINT) >= TX_PACKET_LIMIT || | |||||
usb_tx_packet_count(CDC3_TX_ENDPOINT) >= TX_PACKET_LIMIT || | |||||
(tx_packet = usb_malloc()) == NULL) { | (tx_packet = usb_malloc()) == NULL) { | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
} | } | ||||
len = CDC2_TX_SIZE - tx_packet->index; | |||||
len = CDC3_TX_SIZE - tx_packet->index; | |||||
// TODO: Perhaps we need "usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT" | // 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 | // added here, so the SOF interrupt can't take away the available buffer | ||||
// space we just promised the user could write without blocking? | // space we just promised the user could write without blocking? | ||||
return len; | return len; | ||||
} | } | ||||
void usb_serial2_flush_output(void) | |||||
void usb_serial3_flush_output(void) | |||||
{ | { | ||||
if (!usb_configuration) return; | if (!usb_configuration) return; | ||||
tx_noautoflush = 1; | tx_noautoflush = 1; | ||||
if (tx_packet) { | if (tx_packet) { | ||||
usb_cdc2_transmit_flush_timer = 0; | |||||
usb_cdc3_transmit_flush_timer = 0; | |||||
tx_packet->len = tx_packet->index; | tx_packet->len = tx_packet->index; | ||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} else { | } else { | ||||
usb_packet_t *tx = usb_malloc(); | usb_packet_t *tx = usb_malloc(); | ||||
if (tx) { | if (tx) { | ||||
usb_cdc2_transmit_flush_timer = 0; | |||||
usb_tx(CDC2_TX_ENDPOINT, tx); | |||||
usb_cdc3_transmit_flush_timer = 0; | |||||
usb_tx(CDC3_TX_ENDPOINT, tx); | |||||
} else { | } else { | ||||
usb_cdc2_transmit_flush_timer = 1; | |||||
usb_cdc3_transmit_flush_timer = 1; | |||||
} | } | ||||
} | } | ||||
tx_noautoflush = 0; | tx_noautoflush = 0; | ||||
} | } | ||||
void usb_serial2_flush_callback(void) | |||||
void usb_serial3_flush_callback(void) | |||||
{ | { | ||||
if (tx_noautoflush) return; | if (tx_noautoflush) return; | ||||
if (tx_packet) { | if (tx_packet) { | ||||
tx_packet->len = tx_packet->index; | tx_packet->len = tx_packet->index; | ||||
usb_tx(CDC2_TX_ENDPOINT, tx_packet); | |||||
usb_tx(CDC3_TX_ENDPOINT, tx_packet); | |||||
tx_packet = NULL; | tx_packet = NULL; | ||||
} else { | } else { | ||||
usb_packet_t *tx = usb_malloc(); | usb_packet_t *tx = usb_malloc(); | ||||
if (tx) { | if (tx) { | ||||
usb_tx(CDC2_TX_ENDPOINT, tx); | |||||
usb_tx(CDC3_TX_ENDPOINT, tx); | |||||
} else { | } else { | ||||
usb_cdc2_transmit_flush_timer = 1; | |||||
usb_cdc3_transmit_flush_timer = 1; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
#endif // F_CPU | #endif // F_CPU | ||||
#endif // CDC2_STATUS_INTERFACE && CDC2_DATA_INTERFACE | |||||
#endif // CDC3_STATUS_INTERFACE && CDC3_DATA_INTERFACE |