|
|
|
|
|
|
|
|
#define print USBHost::print_ |
|
|
#define print USBHost::print_ |
|
|
#define println USBHost::println_ |
|
|
#define println USBHost::println_ |
|
|
|
|
|
|
|
|
|
|
|
//#define ENABLE_DEBUG_PINS |
|
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_DEBUG_PINS |
|
|
|
|
|
#define debugDigitalToggle(pin) {digitalWriteFast(pin, !digitalReadFast(pin));} |
|
|
|
|
|
#define debugDigitalWrite(pin, state) {digitalWriteFast(pin, state);} |
|
|
|
|
|
#else |
|
|
|
|
|
#define debugDigitalToggle(pin) {;} |
|
|
|
|
|
#define debugDigitalWrite(pin, state) {;} |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
/************************************************************/ |
|
|
/************************************************************/ |
|
|
// Define mapping VID/PID - to Serial Device type. |
|
|
// Define mapping VID/PID - to Serial Device type. |
|
|
/************************************************************/ |
|
|
/************************************************************/ |
|
|
|
|
|
|
|
|
println(", tx:", tx_ep); |
|
|
println(", tx:", tx_ep); |
|
|
if (!rx_ep || !tx_ep) return false; // did not get our two end points |
|
|
if (!rx_ep || !tx_ep) return false; // did not get our two end points |
|
|
if (!init_buffers(rx_size, tx_size)) return false; |
|
|
if (!init_buffers(rx_size, tx_size)) return false; |
|
|
|
|
|
println(" rx buffer size:", rxsize); |
|
|
|
|
|
println(" tx buffer size:", txsize); |
|
|
rxpipe = new_Pipe(dev, 2, rx_ep & 15, 1, rx_size); |
|
|
rxpipe = new_Pipe(dev, 2, rx_ep & 15, 1, rx_size); |
|
|
if (!rxpipe) return false; |
|
|
if (!rxpipe) return false; |
|
|
txpipe = new_Pipe(dev, 2, tx_ep, 0, tx_size); |
|
|
txpipe = new_Pipe(dev, 2, tx_ep, 0, tx_size); |
|
|
|
|
|
|
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
if (sertype == UNKNOWN) return false; // not one of ours |
|
|
|
|
|
|
|
|
|
|
|
// Lets try to locate the end points. Code is common across these devices |
|
|
|
|
|
println("len = ", len); |
|
|
|
|
|
uint8_t count_end_points = descriptors[4]; |
|
|
|
|
|
if (count_end_points < 2) return false; // not enough end points |
|
|
|
|
|
if (len < 23) return false; |
|
|
|
|
|
if (descriptors[0] != 9) return false; // length 9 |
|
|
|
|
|
|
|
|
|
|
|
// Lets walk through end points and see if we |
|
|
|
|
|
// can find an RX and TX bulk transfer end point. |
|
|
|
|
|
//Example vid=67B, pid=2303 |
|
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 |
|
|
|
|
|
//09 04 00 00 03 FF 00 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00 07 05 83 02 40 00 00 |
|
|
|
|
|
uint32_t rxep = 0; |
|
|
|
|
|
uint32_t txep = 0; |
|
|
|
|
|
uint16_t rx_size = 0; |
|
|
|
|
|
uint16_t tx_size = 0; |
|
|
|
|
|
uint32_t descriptor_index = 9; |
|
|
|
|
|
while (count_end_points-- && ((rxep == 0) || txep == 0)) { |
|
|
|
|
|
if (descriptors[descriptor_index] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[descriptor_index+1] != 5) return false; // ep desc |
|
|
|
|
|
if ((descriptors[descriptor_index+3] == 2) |
|
|
|
|
|
&& (descriptors[descriptor_index+4] <= 64) |
|
|
|
|
|
&& (descriptors[descriptor_index+5] == 0)) { |
|
|
|
|
|
// have a bulk EP size |
|
|
|
|
|
if (descriptors[descriptor_index+2] & 0x80 ) { |
|
|
|
|
|
rxep = descriptors[descriptor_index+2]; |
|
|
|
|
|
rx_size = descriptors[descriptor_index+4]; |
|
|
|
|
|
} else { |
|
|
|
|
|
txep = descriptors[descriptor_index+2]; |
|
|
|
|
|
tx_size = descriptors[descriptor_index+4]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
descriptor_index += 7; // setup to look at next one... |
|
|
|
|
|
} |
|
|
|
|
|
// Try to verify the end points. |
|
|
|
|
|
if (!check_rxtx_ep(rxep, txep)) return false; |
|
|
|
|
|
print("USBSerial, rxep=", rxep & 15); |
|
|
|
|
|
print("(", rx_size); |
|
|
|
|
|
print("), txep=", txep); |
|
|
|
|
|
print("(", tx_size); |
|
|
|
|
|
println(")"); |
|
|
|
|
|
|
|
|
|
|
|
if (!init_buffers(rx_size, tx_size)) return false; |
|
|
|
|
|
println(" rx buffer size:", rxsize); |
|
|
|
|
|
println(" tx buffer size:", txsize); |
|
|
|
|
|
|
|
|
|
|
|
rxpipe = new_Pipe(dev, 2, rxep & 15, 1, rx_size); |
|
|
|
|
|
if (!rxpipe) return false; |
|
|
|
|
|
txpipe = new_Pipe(dev, 2, txep, 0, tx_size); |
|
|
|
|
|
if (!txpipe) { |
|
|
|
|
|
//free_Pipe(rxpipe); |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
queue_Data_Transfer(rxpipe, rx1, rx_size, this); |
|
|
|
|
|
rxstate = 1; |
|
|
|
|
|
txstate = 0; |
|
|
|
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
baudrate = 115200; |
|
|
|
|
|
|
|
|
|
|
|
// Now do specific setup per type |
|
|
switch (sertype) { |
|
|
switch (sertype) { |
|
|
//--------------------------------------------------------------------- |
|
|
//--------------------------------------------------------------------- |
|
|
// FTDI |
|
|
// FTDI |
|
|
case FTDI: |
|
|
case FTDI: |
|
|
{ |
|
|
{ |
|
|
// FTDI FT232 |
|
|
|
|
|
println("len = ", len); |
|
|
|
|
|
if (len < 23) return false; |
|
|
|
|
|
if (descriptors[0] != 9) return false; // length 9 |
|
|
|
|
|
if (descriptors[9] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[10] != 5) return false; // ep desc |
|
|
|
|
|
uint32_t rxep = descriptors[11]; |
|
|
|
|
|
if (descriptors[12] != 2) return false; // bulk type |
|
|
|
|
|
if (descriptors[13] != 64) return false; // size 64 |
|
|
|
|
|
if (descriptors[14] != 0) return false; |
|
|
|
|
|
if (descriptors[16] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[17] != 5) return false; // ep desc |
|
|
|
|
|
uint32_t txep = descriptors[18]; |
|
|
|
|
|
if (descriptors[19] != 2) return false; // bulk type |
|
|
|
|
|
if (descriptors[20] != 64) return false; // size 64 |
|
|
|
|
|
if (descriptors[21] != 0) return false; |
|
|
|
|
|
if (!check_rxtx_ep(rxep, txep)) return false; |
|
|
|
|
|
print("FTDI, rxep=", rxep & 15); |
|
|
|
|
|
println(", txep=", txep); |
|
|
|
|
|
if (!init_buffers(64, 64)) return false; |
|
|
|
|
|
rxpipe = new_Pipe(dev, 2, rxep & 15, 1, 64); |
|
|
|
|
|
if (!rxpipe) return false; |
|
|
|
|
|
txpipe = new_Pipe(dev, 2, txep, 0, 64); |
|
|
|
|
|
if (!txpipe) { |
|
|
|
|
|
// TODO: free rxpipe |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
sertype = FTDI; |
|
|
|
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
rxsize = 64; |
|
|
|
|
|
queue_Data_Transfer(rxpipe, rx1, 64, this); |
|
|
|
|
|
rxstate = 1; |
|
|
|
|
|
txsize = 64; |
|
|
|
|
|
txstate = 0; |
|
|
|
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
baudrate = 115200; |
|
|
|
|
|
pending_control = 0x0F; |
|
|
pending_control = 0x0F; |
|
|
mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port |
|
|
mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port |
|
|
queue_Control_Transfer(dev, &setup, NULL, this); |
|
|
queue_Control_Transfer(dev, &setup, NULL, this); |
|
|
|
|
|
|
|
|
// TODO: Note: there are probably more vendor/product pairs.. Maybe should create table of them |
|
|
// TODO: Note: there are probably more vendor/product pairs.. Maybe should create table of them |
|
|
case PL2303: |
|
|
case PL2303: |
|
|
{ |
|
|
{ |
|
|
// Prolific Technology, Inc. PL2303 Serial Port |
|
|
|
|
|
println("len = ", len); |
|
|
|
|
|
uint8_t count_end_points = descriptors[4]; |
|
|
|
|
|
if (count_end_points < 2) return false; // not enough end points |
|
|
|
|
|
if (len < 23) return false; |
|
|
|
|
|
if (descriptors[0] != 9) return false; // length 9 |
|
|
|
|
|
|
|
|
|
|
|
// Lets walk through end points and see if we |
|
|
|
|
|
// can find an RX and TX bulk transfer end point. |
|
|
|
|
|
//vid=67B, pid=2303 |
|
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 |
|
|
|
|
|
//09 04 00 00 03 FF 00 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00 07 05 83 02 40 00 00 |
|
|
|
|
|
uint32_t rxep = 0; |
|
|
|
|
|
uint32_t txep = 0; |
|
|
|
|
|
uint32_t descriptor_index = 9; |
|
|
|
|
|
while (count_end_points-- && ((rxep == 0) || txep == 0)) { |
|
|
|
|
|
if (descriptors[descriptor_index] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[descriptor_index+1] != 5) return false; // ep desc |
|
|
|
|
|
if ((descriptors[descriptor_index+3] == 2) |
|
|
|
|
|
&& (descriptors[descriptor_index+4] == 64) |
|
|
|
|
|
&& (descriptors[descriptor_index+5] == 0)) { |
|
|
|
|
|
// have a bulk EP size |
|
|
|
|
|
if (descriptors[descriptor_index+2] & 0x80 ) { |
|
|
|
|
|
rxep = descriptors[descriptor_index+2]; |
|
|
|
|
|
rxsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} else { |
|
|
|
|
|
txep = descriptors[descriptor_index+2]; |
|
|
|
|
|
txsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
descriptor_index += 7; // setup to look at next one... |
|
|
|
|
|
} |
|
|
|
|
|
// Try to verify the end points. |
|
|
|
|
|
if (!check_rxtx_ep(rxep, txep)) return false; |
|
|
|
|
|
print("PL2303, rxep=", rxep & 15); |
|
|
|
|
|
println(", txep=", txep); |
|
|
|
|
|
if (!init_buffers(64, 64)) return false; |
|
|
|
|
|
rxpipe = new_Pipe(dev, 2, rxep & 15, 1, 64); |
|
|
|
|
|
if (!rxpipe) return false; |
|
|
|
|
|
txpipe = new_Pipe(dev, 2, txep, 0, 64); |
|
|
|
|
|
if (!txpipe) { |
|
|
|
|
|
// TODO: free rxpipe |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sertype = PL2303; |
|
|
|
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
queue_Data_Transfer(rxpipe, rx1, 64, this); |
|
|
|
|
|
rxstate = 1; |
|
|
|
|
|
txstate = 0; |
|
|
|
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
baudrate = 115200; |
|
|
|
|
|
|
|
|
|
|
|
// First attempt keep it simple... |
|
|
// First attempt keep it simple... |
|
|
println("PL2303: readRegister(0x04)"); |
|
|
println("PL2303: readRegister(0x04)"); |
|
|
// Need to setup the data the line coding data |
|
|
// Need to setup the data the line coding data |
|
|
|
|
|
|
|
|
// CH341 |
|
|
// CH341 |
|
|
case CH341: |
|
|
case CH341: |
|
|
{ |
|
|
{ |
|
|
println("len = ", len); |
|
|
|
|
|
uint8_t count_end_points = descriptors[4]; |
|
|
|
|
|
if (count_end_points < 2) return false; // not enough end points |
|
|
|
|
|
if (len < 23) return false; |
|
|
|
|
|
if (descriptors[0] != 9) return false; // length 9 |
|
|
|
|
|
|
|
|
|
|
|
// Lets walk through end points and see if we |
|
|
|
|
|
// can find an RX and TX bulk transfer end point. |
|
|
|
|
|
// vid=1A86, pid=7523, bDeviceClass = 255, bDeviceSubClass = 0, bDeviceProtocol = 0 |
|
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 |
|
|
|
|
|
//09 04 00 00 03 FF 01 02 00 07 05 82 02 20 00 00 07 05 02 02 20 00 00 07 05 81 03 08 00 01 |
|
|
|
|
|
uint32_t rxep = 0; |
|
|
|
|
|
uint32_t txep = 0; |
|
|
|
|
|
uint32_t descriptor_index = 9; |
|
|
|
|
|
while (count_end_points-- && ((rxep == 0) || txep == 0)) { |
|
|
|
|
|
if (descriptors[descriptor_index] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[descriptor_index+1] != 5) return false; // ep desc |
|
|
|
|
|
if ((descriptors[descriptor_index+3] == 2) |
|
|
|
|
|
&& (descriptors[descriptor_index+4] <= 64) |
|
|
|
|
|
&& (descriptors[descriptor_index+5] == 0)) { |
|
|
|
|
|
// have a bulk EP size |
|
|
|
|
|
if (descriptors[descriptor_index+2] & 0x80 ) { |
|
|
|
|
|
rxep = descriptors[descriptor_index+2]; |
|
|
|
|
|
rxsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} else { |
|
|
|
|
|
txep = descriptors[descriptor_index+2]; |
|
|
|
|
|
txsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
descriptor_index += 7; // setup to look at next one... |
|
|
|
|
|
} |
|
|
|
|
|
// Try to verify the end points. |
|
|
|
|
|
if (!check_rxtx_ep(rxep, txep)) return false; |
|
|
|
|
|
print("ch341, rxep=", rxep & 15); |
|
|
|
|
|
println(", txep=", txep); |
|
|
|
|
|
if (!init_buffers(rxsize, txsize)) return false; |
|
|
|
|
|
rxpipe = new_Pipe(dev, 2, rxep & 15, 1, rxsize); |
|
|
|
|
|
if (!rxpipe) return false; |
|
|
|
|
|
txpipe = new_Pipe(dev, 2, txep, 0, txsize); |
|
|
|
|
|
if (!txpipe) { |
|
|
|
|
|
// TODO: free rxpipe |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
queue_Data_Transfer(rxpipe, rx1, rxsize, this); |
|
|
|
|
|
rxstate = 1; |
|
|
|
|
|
txstate = 0; |
|
|
|
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
baudrate = 115200; |
|
|
|
|
|
|
|
|
|
|
|
println("CH341: 0xC0, 0x5f, 0, 0, 8"); |
|
|
println("CH341: 0xC0, 0x5f, 0, 0, 8"); |
|
|
// Need to setup the data the line coding data |
|
|
// Need to setup the data the line coding data |
|
|
mk_setup(setup, 0xC0, 0x5f, 0, 0, sizeof(setupdata)); |
|
|
mk_setup(setup, 0xC0, 0x5f, 0, 0, sizeof(setupdata)); |
|
|
|
|
|
|
|
|
// CP210X |
|
|
// CP210X |
|
|
case CP210X: |
|
|
case CP210X: |
|
|
{ |
|
|
{ |
|
|
println("len = ", len); |
|
|
|
|
|
uint8_t count_end_points = descriptors[4]; |
|
|
|
|
|
if (count_end_points < 2) return false; // not enough end points |
|
|
|
|
|
if (len < 23) return false; |
|
|
|
|
|
if (descriptors[0] != 9) return false; // length 9 |
|
|
|
|
|
|
|
|
|
|
|
// Lets walk through end points and see if we |
|
|
|
|
|
// can find an RX and TX bulk transfer end point. |
|
|
|
|
|
// BUGBUG: should factor out this code as duplicated... |
|
|
|
|
|
// vid=10C4, pid=EA60, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0 |
|
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 |
|
|
|
|
|
//09 04 00 00 02 FF 00 00 02 07 05 81 02 40 00 00 07 05 01 02 40 00 00 |
|
|
|
|
|
uint32_t rxep = 0; |
|
|
|
|
|
uint32_t txep = 0; |
|
|
|
|
|
uint32_t descriptor_index = 9; |
|
|
|
|
|
while (count_end_points-- && ((rxep == 0) || txep == 0)) { |
|
|
|
|
|
if (descriptors[descriptor_index] != 7) return false; // length 7 |
|
|
|
|
|
if (descriptors[descriptor_index+1] != 5) return false; // ep desc |
|
|
|
|
|
if ((descriptors[descriptor_index+3] == 2) |
|
|
|
|
|
&& (descriptors[descriptor_index+4] <= 64) |
|
|
|
|
|
&& (descriptors[descriptor_index+5] == 0)) { |
|
|
|
|
|
// have a bulk EP size |
|
|
|
|
|
if (descriptors[descriptor_index+2] & 0x80 ) { |
|
|
|
|
|
rxep = descriptors[descriptor_index+2]; |
|
|
|
|
|
rxsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} else { |
|
|
|
|
|
txep = descriptors[descriptor_index+2]; |
|
|
|
|
|
txsize = descriptors[descriptor_index+4]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
descriptor_index += 7; // setup to look at next one... |
|
|
|
|
|
} |
|
|
|
|
|
// Try to verify the end points. |
|
|
|
|
|
if (!check_rxtx_ep(rxep, txep)) return false; |
|
|
|
|
|
print("CP210X, rxep=", rxep & 15); |
|
|
|
|
|
println(", txep=", txep); |
|
|
|
|
|
if (!init_buffers(rxsize, txsize)) return false; |
|
|
|
|
|
rxpipe = new_Pipe(dev, 2, rxep & 15, 1, rxsize); |
|
|
|
|
|
if (!rxpipe) return false; |
|
|
|
|
|
txpipe = new_Pipe(dev, 2, txep, 0, txsize); |
|
|
|
|
|
if (!txpipe) { |
|
|
|
|
|
// TODO: free rxpipe |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
queue_Data_Transfer(rxpipe, rx1, rxsize, this); |
|
|
|
|
|
rxstate = 1; |
|
|
|
|
|
txstate = 0; |
|
|
|
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
baudrate = 115200; |
|
|
|
|
|
|
|
|
|
|
|
println("CP210X: 0x41, 0x11, 0, 0, 0 - reset port"); |
|
|
println("CP210X: 0x41, 0x11, 0, 0, 0 - reset port"); |
|
|
// Need to setup the data the line coding data |
|
|
// Need to setup the data the line coding data |
|
|
mk_setup(setup, 0x41, 0x11, 0, 0, 0); |
|
|
mk_setup(setup, 0x41, 0x11, 0, 0, 0); |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF); |
|
|
uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF); |
|
|
|
|
|
|
|
|
|
|
|
debugDigitalToggle(6); |
|
|
// first update rxstate bitmask, since buffer is no longer queued |
|
|
// first update rxstate bitmask, since buffer is no longer queued |
|
|
if (transfer->buffer == rx1) { |
|
|
if (transfer->buffer == rx1) { |
|
|
rxstate &= 0xFE; |
|
|
rxstate &= 0xFE; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (len > 0) { |
|
|
if (len > 0) { |
|
|
|
|
|
print("rx token: ", transfer->qtd.token, HEX); |
|
|
|
|
|
print(" transfer length: ", transfer->length, DEC); |
|
|
|
|
|
print(" len:", len, DEC); |
|
|
|
|
|
print(" - ", *p, HEX); |
|
|
|
|
|
println(" ", *(p+1), HEX); |
|
|
print("rx: "); |
|
|
print("rx: "); |
|
|
print_hexbytes(p, len); |
|
|
print_hexbytes(p, len); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
uint32_t mask; |
|
|
uint32_t mask; |
|
|
uint8_t *p = (uint8_t *)transfer->buffer; |
|
|
uint8_t *p = (uint8_t *)transfer->buffer; |
|
|
|
|
|
debugDigitalWrite(5, HIGH); |
|
|
if (p == tx1) { |
|
|
if (p == tx1) { |
|
|
println("tx1:"); |
|
|
println("tx1:"); |
|
|
mask = 1; |
|
|
mask = 1; |
|
|
|
|
|
|
|
|
mask = 2; |
|
|
mask = 2; |
|
|
//txstate &= 0xFD; |
|
|
//txstate &= 0xFD; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
debugDigitalWrite(5, LOW); |
|
|
return; // should never happen |
|
|
return; // should never happen |
|
|
} |
|
|
} |
|
|
// check how much more data remains in the transmit buffer |
|
|
// check how much more data remains in the transmit buffer |
|
|
|
|
|
|
|
|
count = txsize + head - tail; |
|
|
count = txsize + head - tail; |
|
|
} |
|
|
} |
|
|
uint32_t packetsize = tx2 - tx1; |
|
|
uint32_t packetsize = tx2 - tx1; |
|
|
if (count < packetsize) { |
|
|
|
|
|
|
|
|
// Only output full packets unless the flush bit was set. |
|
|
|
|
|
if ((count == 0) || ((count < packetsize) && ((txstate & 0x4) == 0) )) { |
|
|
// not enough data in buffer to fill a full packet |
|
|
// not enough data in buffer to fill a full packet |
|
|
txstate &= ~mask; |
|
|
|
|
|
|
|
|
txstate &= ~(mask | 4); // turn off that transfer and make sure the flush bit is not set |
|
|
|
|
|
debugDigitalWrite(5, LOW); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
// immediately transmit another full packet, if we have enough data |
|
|
// immediately transmit another full packet, if we have enough data |
|
|
|
|
|
if (count >= packetsize) count = packetsize; |
|
|
|
|
|
else txstate &= ~(mask | 4); // This packet will complete any outstanding flush |
|
|
|
|
|
|
|
|
println("TX:moar data!!!!"); |
|
|
println("TX:moar data!!!!"); |
|
|
if (++tail >= txsize) tail = 0; |
|
|
if (++tail >= txsize) tail = 0; |
|
|
uint32_t n = txsize - tail; |
|
|
uint32_t n = txsize - tail; |
|
|
if (n > packetsize) n = packetsize; |
|
|
|
|
|
|
|
|
if (n > count) n = count; |
|
|
memcpy(p, txbuf + tail, n); |
|
|
memcpy(p, txbuf + tail, n); |
|
|
if (n >= packetsize) { |
|
|
|
|
|
|
|
|
if (n >= count) { |
|
|
tail += n - 1; |
|
|
tail += n - 1; |
|
|
if (tail >= txsize) tail = 0; |
|
|
if (tail >= txsize) tail = 0; |
|
|
} else { |
|
|
} else { |
|
|
uint32_t len = packetsize - n; |
|
|
|
|
|
|
|
|
uint32_t len = count - n; |
|
|
memcpy(p + n, txbuf, len); |
|
|
memcpy(p + n, txbuf, len); |
|
|
tail = len - 1; |
|
|
tail = len - 1; |
|
|
} |
|
|
} |
|
|
txtail = tail; |
|
|
txtail = tail; |
|
|
queue_Data_Transfer(txpipe, p, packetsize, this); |
|
|
|
|
|
|
|
|
queue_Data_Transfer(txpipe, p, count, this); |
|
|
|
|
|
debugDigitalWrite(5, LOW); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void USBSerial::flush() |
|
|
|
|
|
{ |
|
|
|
|
|
print("USBSerial::flush"); |
|
|
|
|
|
if (txhead == txtail) { |
|
|
|
|
|
println(" - Empty"); |
|
|
|
|
|
return; // empty. |
|
|
|
|
|
} |
|
|
|
|
|
debugDigitalWrite(32, HIGH); |
|
|
|
|
|
NVIC_DISABLE_IRQ(IRQ_USBHS); |
|
|
|
|
|
txtimer.stop(); // Stop longer timer. |
|
|
|
|
|
txtimer.start(100); // Start a mimimal timeout |
|
|
|
|
|
// timer_event(nullptr); // Try calling direct - fails to work |
|
|
|
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
|
|
|
while (txstate & 3) ; // wait for all of the USB packets to be sent. |
|
|
|
|
|
println(" completed"); |
|
|
|
|
|
debugDigitalWrite(32, LOW); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void USBSerial::timer_event(USBDriverTimer *whichTimer) |
|
|
void USBSerial::timer_event(USBDriverTimer *whichTimer) |
|
|
{ |
|
|
{ |
|
|
|
|
|
debugDigitalWrite(7, HIGH); |
|
|
println("txtimer"); |
|
|
println("txtimer"); |
|
|
uint32_t count; |
|
|
uint32_t count; |
|
|
uint32_t head = txhead; |
|
|
uint32_t head = txhead; |
|
|
uint32_t tail = txtail; |
|
|
uint32_t tail = txtail; |
|
|
if (pending_control) { |
|
|
|
|
|
// We are still doing setup postpone for awhile.. |
|
|
|
|
|
txtimer.start(1200); |
|
|
|
|
|
println(" Postpone: setup pending_control"); |
|
|
|
|
|
return; // no outgoing buffers available, try again later |
|
|
|
|
|
} |
|
|
|
|
|
if (head == tail) { |
|
|
if (head == tail) { |
|
|
println(" *** Empty ***"); |
|
|
println(" *** Empty ***"); |
|
|
|
|
|
debugDigitalWrite(7, LOW); |
|
|
return; // nothing to transmit |
|
|
return; // nothing to transmit |
|
|
} else if (head > tail) { |
|
|
} else if (head > tail) { |
|
|
count = head - tail; |
|
|
count = head - tail; |
|
|
} else { |
|
|
} else { |
|
|
count = txsize + head - tail; |
|
|
count = txsize + head - tail; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint8_t *p; |
|
|
uint8_t *p; |
|
|
if ((txstate & 0x01) == 0) { |
|
|
if ((txstate & 0x01) == 0) { |
|
|
p = tx1; |
|
|
p = tx1; |
|
|
|
|
|
|
|
|
p = tx2; |
|
|
p = tx2; |
|
|
txstate |= 0x02; |
|
|
txstate |= 0x02; |
|
|
} else { |
|
|
} else { |
|
|
txtimer.start(1200); |
|
|
|
|
|
|
|
|
txstate |= 4; // Tell the TX code to do flush code. |
|
|
println(" *** No buffers ***"); |
|
|
println(" *** No buffers ***"); |
|
|
|
|
|
debugDigitalWrite(7, LOW); |
|
|
return; // no outgoing buffers available, try again later |
|
|
return; // no outgoing buffers available, try again later |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t packetsize = tx2 - tx1; |
|
|
|
|
|
|
|
|
|
|
|
// Possible for remaining ? packet size and not have both? |
|
|
|
|
|
if (count > packetsize) { |
|
|
|
|
|
txstate |= 4; // One of the active transfers will handle the remaining parts |
|
|
|
|
|
count = packetsize; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (++tail >= txsize) tail = 0; |
|
|
if (++tail >= txsize) tail = 0; |
|
|
uint32_t n = txsize - tail; |
|
|
uint32_t n = txsize - tail; |
|
|
if (n > count) n = count; |
|
|
if (n > count) n = count; |
|
|
|
|
|
|
|
|
print(") "); |
|
|
print(") "); |
|
|
print_hexbytes(p, count); |
|
|
print_hexbytes(p, count); |
|
|
queue_Data_Transfer(txpipe, p, count, this); |
|
|
queue_Data_Transfer(txpipe, p, count, this); |
|
|
|
|
|
debugDigitalWrite(7, LOW); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
txtail = tail; |
|
|
txtail = tail; |
|
|
//println("queue tx packet, newtail=", tail); |
|
|
//println("queue tx packet, newtail=", tail); |
|
|
|
|
|
debugDigitalWrite(7, HIGH); |
|
|
queue_Data_Transfer(txpipe, p, packetsize, this); |
|
|
queue_Data_Transfer(txpipe, p, packetsize, this); |
|
|
|
|
|
debugDigitalWrite(7, LOW); |
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// otherwise, set a latency timer to later transmit partial packet |
|
|
// otherwise, set a latency timer to later transmit partial packet |
|
|
txtimer.stop(); |
|
|
txtimer.stop(); |
|
|
txtimer.start(3500); |
|
|
|
|
|
|
|
|
txtimer.start(write_timeout_); |
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |