Browse Source

Add USB Serial flush

teensy4-core
PaulStoffregen 5 years ago
parent
commit
b062b68308
3 changed files with 63 additions and 36 deletions
  1. +9
    -1
      teensy4/usb.c
  2. +3
    -0
      teensy4/usb_dev.h
  3. +51
    -35
      teensy4/usb_serial.c

+ 9
- 1
teensy4/usb.c View File

@@ -79,6 +79,8 @@ volatile uint8_t usb_configuration = 0;
static uint8_t endpoint0_buffer[8];
static uint8_t usb_reboot_timer = 0;

void (*usb_timer0_callback)(void) = NULL;
void (*usb_timer1_callback)(void) = NULL;

static void isr(void);
static void endpoint0_setup(uint64_t setupdata);
@@ -265,6 +267,12 @@ static void isr(void)
//printf("shut off USB\n");
//}
}
if (status & USB_USBSTS_TI0) {
if (usb_timer0_callback != NULL) usb_timer0_callback();
}
if (status & USB_USBSTS_TI1) {
if (usb_timer1_callback != NULL) usb_timer1_callback();
}
if (status & USB_USBSTS_PCI) {
if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
//printf("port at 480 Mbit\n");
@@ -636,7 +644,7 @@ static void run_callbacks(endpoint_t *ep)
{
transfer_t *t, *next;

printf("run_callbacks\n");
//printf("run_callbacks\n");
t = ep->first_transfer;
while (t && (uint32_t)t != 1) {
if (!(t->status & (1<<7))) {

+ 3
- 0
teensy4/usb_dev.h View File

@@ -24,4 +24,7 @@ void usb_transmit(int endpoint_number, transfer_t *transfer);
void usb_receive(int endpoint_number, transfer_t *transfer);
uint32_t usb_transfer_status(const transfer_t *transfer);

extern void (*usb_timer0_callback)(void);
extern void (*usb_timer1_callback)(void);



+ 51
- 35
teensy4/usb_serial.c View File

@@ -50,8 +50,13 @@ volatile uint8_t usb_cdc_transmit_flush_timer=0;
//static usb_packet_t *tx_packet=NULL;
static volatile uint8_t tx_noautoflush=0;

#define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */
// TODO: should be 2 different timeouts, high speed (480) vs full speed (12)
#define TRANSMIT_FLUSH_TIMEOUT 75 /* in microseconds */

static void timer_config(void (*callback)(void), uint32_t microseconds);
static void timer_start_oneshot();
static void timer_stop();
static void usb_serial_flush_callback(void);


#define RX_NUM 3
@@ -64,7 +69,7 @@ static void rx_event(transfer_t *t)
{
int len = CDC_RX_SIZE - ((t->status >> 16) & 0x7FFF);
int index = t->callback_param;
printf("rx event, len=%d, i=%d\n", len, index);
//printf("rx event, len=%d, i=%d\n", len, index);
rx_count[index] = len;
rx_index[index] = 0;
}
@@ -83,6 +88,7 @@ void usb_serial_configure(void)
usb_config_tx(CDC_TX_ENDPOINT, CDC_TX_SIZE, 0, NULL);
usb_prepare_transfer(rx_transfer + 0, rx_buffer + 0, CDC_RX_SIZE, 0);
usb_receive(CDC_RX_ENDPOINT, rx_transfer + 0);
timer_config(usb_serial_flush_callback, TRANSMIT_FLUSH_TIMEOUT);
}


@@ -256,6 +262,30 @@ static uint16_t tx_available=0;

extern volatile uint32_t systick_millis_count;

static void timer_config(void (*callback)(void), uint32_t microseconds);
static void timer_start_oneshot();
static void timer_stop();

static void timer_config(void (*callback)(void), uint32_t microseconds)
{
usb_timer0_callback = callback;
USB1_GPTIMER0CTRL = 0;
USB1_GPTIMER0LD = microseconds - 1;
USB1_USBINTR |= USB_USBINTR_TIE0;
}

static void timer_start_oneshot(void)
{
// restarts timer if already running (retriggerable one-shot)
USB1_GPTIMER0CTRL = USB_GPTIMERCTRL_GPTRUN | USB_GPTIMERCTRL_GPTRST;
}

static void timer_stop(void)
{
USB1_GPTIMER0CTRL = 0;
}


int usb_serial_write(const void *buffer, uint32_t size)
{
uint32_t sent=0;
@@ -264,8 +294,8 @@ int usb_serial_write(const void *buffer, uint32_t size)
if (!usb_configuration) return 0;
while (size > 0) {
transfer_t *xfer = tx_transfer + tx_head;
int waiting=0;
uint32_t wait_begin_at=0;
//int waiting=0;
//uint32_t wait_begin_at=0;
while (!tx_available) {
//digitalWriteFast(3, HIGH);
uint32_t status = usb_transfer_status(xfer);
@@ -309,11 +339,13 @@ int usb_serial_write(const void *buffer, uint32_t size)
sent += tx_available;
data += tx_available;
tx_available = 0;
timer_stop();
} else {
memcpy(txdata, data, size);
tx_available -= size;
sent += size;
size = 0;
timer_start_oneshot();
}
}
return sent;
@@ -349,44 +381,28 @@ int usb_serial_write_buffer_free(void)

void usb_serial_flush_output(void)
{
#if 0
if (!usb_configuration) return;
if (tx_available == 0) 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;
} else {
usb_packet_t *tx = usb_malloc();
if (tx) {
usb_cdc_transmit_flush_timer = 0;
usb_tx(CDC_TX_ENDPOINT, tx);
} else {
usb_cdc_transmit_flush_timer = 1;
}
}
transfer_t *xfer = tx_transfer + tx_head;
usb_prepare_transfer(xfer, txbuffer + (tx_head * TX_SIZE), TX_SIZE - tx_available, 0);
usb_transmit(CDC_TX_ENDPOINT, xfer);
if (++tx_head >= TX_NUM) tx_head = 0;
tx_available = 0;
tx_noautoflush = 0;
#endif
}

void usb_serial_flush_callback(void)
static void usb_serial_flush_callback(void)
{
#if 0
if (tx_noautoflush) return;
if (tx_packet) {
tx_packet->len = tx_packet->index;
usb_tx(CDC_TX_ENDPOINT, tx_packet);
tx_packet = NULL;
} else {
usb_packet_t *tx = usb_malloc();
if (tx) {
usb_tx(CDC_TX_ENDPOINT, tx);
} else {
usb_cdc_transmit_flush_timer = 1;
}
}
#endif
if (!usb_configuration) return;
if (tx_available == 0) return;
//printf("flush callback, %d bytes\n", TX_SIZE - tx_available);
transfer_t *xfer = tx_transfer + tx_head;
usb_prepare_transfer(xfer, txbuffer + (tx_head * TX_SIZE), TX_SIZE - tx_available, 0);
usb_transmit(CDC_TX_ENDPOINT, xfer);
if (++tx_head >= TX_NUM) tx_head = 0;
tx_available = 0;
}



Loading…
Cancel
Save