The code for the second port was accidentally expanded into
usb_serial3.c, while the code for the third port was expanded in
usb_serial2.c.
Fixes: cd4c30fde5 ("Expand all USB serial 2 & 3 stuff (needed for Arduino IDE use)")
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
main
| */ | */ | ||||
| #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 |