Browse Source

Add USB transmit timeout

teensy4-core
PaulStoffregen 5 years ago
parent
commit
a554067ee0
1 changed files with 30 additions and 54 deletions
  1. +30
    -54
      teensy4/usb_serial.c

+ 30
- 54
teensy4/usb_serial.c View File

#endif #endif
} }


// Maximum number of transmit packets to queue so we don't starve other endpoints for memory
//#define TX_PACKET_LIMIT 8

// When the PC isn't listening, how long do we wait before discarding data? If this is // When the PC isn't listening, how long do we wait before discarding data? If this is
// too short, we risk losing data during the stalls that are common with ordinary desktop // too short, we risk losing data during the stalls that are common with ordinary desktop
// software. If it's too long, we stall the user's program when no software is running. // software. If it's too long, we stall the user's program when no software is running.
#define TX_TIMEOUT_MSEC 70

/*#if F_CPU == 240000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1600)
#elif F_CPU == 216000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1440)
#elif F_CPU == 192000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1280)
#elif F_CPU == 180000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1200)
#elif F_CPU == 168000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100)
#elif F_CPU == 144000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932)
#elif F_CPU == 120000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764)
#elif F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 72000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512)
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
#endif */
#define TX_TIMEOUT_MSEC 120



// When we've suffered the transmit timeout, don't wait again until the computer // 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 // 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 // data as rapidly as Serial.print() can generate it, until there's something to
// actually receive it. // actually receive it.
//static uint8_t transmit_previous_timeout=0;
static uint8_t transmit_previous_timeout=0;




// transmit a character. 0 returned on success, -1 on error // transmit a character. 0 returned on success, -1 on error
if (!usb_configuration) return 0; if (!usb_configuration) return 0;
while (size > 0) { while (size > 0) {
transfer_t *xfer = tx_transfer + tx_head; 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) { while (!tx_available) {
//digitalWriteFast(3, HIGH); //digitalWriteFast(3, HIGH);
uint32_t status = usb_transfer_status(xfer); uint32_t status = usb_transfer_status(xfer);
if (status & 0x7F) {
printf("ERROR status = %x, i=%d, ms=%u\n", status, tx_head, systick_millis_count);
}
if (!(status & 0x80)) { if (!(status & 0x80)) {
// TODO: what if status has errors???
if (status & 0x68) {
// TODO: what if status has errors???
printf("ERROR status = %x, i=%d, ms=%u\n",
status, tx_head, systick_millis_count);
}
tx_available = TX_SIZE; tx_available = TX_SIZE;
transmit_previous_timeout = 0;
break; break;
}/* else {
if (!waiting) {
wait_begin_at = systick_millis_count;
waiting = 1;
} else {
if (systick_millis_count - wait_begin_at > 250) {
printf("\nstop, waited too long\n");
printf("status = %x\n", status);
printf("tx head=%d\n", tx_head);
printf("TXFILLTUNING=%08lX\n", USB1_TXFILLTUNING);
usb_print_transfer_log();
while (1) ;
}
}
} */
// TODO: proper timout?
// TODO: check for USB offline
}
if (!waiting) {
wait_begin_at = systick_millis_count;
waiting = 1;
}
if (transmit_previous_timeout) return sent;
if (systick_millis_count - wait_begin_at > TX_TIMEOUT_MSEC) {
// waited too long, assume the USB host isn't listening
transmit_previous_timeout = 1;
return sent;
//printf("\nstop, waited too long\n");
//printf("status = %x\n", status);
//printf("tx head=%d\n", tx_head);
//printf("TXFILLTUNING=%08lX\n", USB1_TXFILLTUNING);
//usb_print_transfer_log();
//while (1) ;
}
if (!usb_configuration) return sent;
yield();
} }
//digitalWriteFast(3, LOW); //digitalWriteFast(3, LOW);

uint8_t *txdata = txbuffer + (tx_head * TX_SIZE) + (TX_SIZE - tx_available); uint8_t *txdata = txbuffer + (tx_head * TX_SIZE) + (TX_SIZE - tx_available);

if (size >= tx_available) { if (size >= tx_available) {
memcpy(txdata, data, tx_available); memcpy(txdata, data, tx_available);
//*(txbuffer + (tx_head * TX_SIZE)) = 'A' + tx_head; // to see which buffer //*(txbuffer + (tx_head * TX_SIZE)) = 'A' + tx_head; // to see which buffer

Loading…
Cancel
Save