mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-21 16:45:04 -05:00
Support for Silicon labs: CP210x
Did a quick add of support for the Slicon Labs CP210x drivers. Did similar like messages as FTDI, based on their documents on line: https://www.silabs.com/documents/public/application-notes/AN571.pdf
This commit is contained in:
parent
12be685ab1
commit
ec4a7ac24c
@ -943,7 +943,7 @@ private:
|
|||||||
USBDriverTimer txtimer;
|
USBDriverTimer txtimer;
|
||||||
uint32_t bigbuffer[(BUFFER_SIZE+3)/4];
|
uint32_t bigbuffer[(BUFFER_SIZE+3)/4];
|
||||||
setup_t setup;
|
setup_t setup;
|
||||||
uint8_t setupdata[8];
|
uint8_t setupdata[16]; //
|
||||||
uint32_t baudrate;
|
uint32_t baudrate;
|
||||||
uint32_t format_;
|
uint32_t format_;
|
||||||
Pipe_t *rxpipe;
|
Pipe_t *rxpipe;
|
||||||
@ -968,7 +968,7 @@ private:
|
|||||||
uint8_t pl2303_v2;
|
uint8_t pl2303_v2;
|
||||||
uint8_t interface;
|
uint8_t interface;
|
||||||
bool control_queued;
|
bool control_queued;
|
||||||
typedef enum { UNKNOWN=0, CDCACM, FTDI, PL2303, CH341 } sertype_t;
|
typedef enum { UNKNOWN=0, CDCACM, FTDI, PL2303, CH341, CP210X } sertype_t;
|
||||||
sertype_t sertype;
|
sertype_t sertype;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
132
serial.cpp
132
serial.cpp
@ -42,7 +42,10 @@ USBSerial::product_vendor_mapping_t USBSerial::pid_vid_mapping[] = {
|
|||||||
// CH341
|
// CH341
|
||||||
{0x4348, 0x5523, USBSerial::CH341 },
|
{0x4348, 0x5523, USBSerial::CH341 },
|
||||||
{0x1a86, 0x7523, USBSerial::CH341 },
|
{0x1a86, 0x7523, USBSerial::CH341 },
|
||||||
{0x1a86, 0x5523, USBSerial::CH341 }
|
{0x1a86, 0x5523, USBSerial::CH341 },
|
||||||
|
|
||||||
|
// Silex CP210...
|
||||||
|
{0x10c4, 0xea60, USBSerial::CP210X }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -307,6 +310,7 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
|||||||
txpipe->callback_function = tx_callback;
|
txpipe->callback_function = tx_callback;
|
||||||
baudrate = 115200;
|
baudrate = 115200;
|
||||||
|
|
||||||
|
// 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
|
||||||
mk_setup(setup, 0xC0, 0x1, 0x8484, 0, 1);
|
mk_setup(setup, 0xC0, 0x1, 0x8484, 0, 1);
|
||||||
@ -381,6 +385,71 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
// 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");
|
||||||
|
// Need to setup the data the line coding data
|
||||||
|
mk_setup(setup, 0x41, 0x11, 0, 0, 0);
|
||||||
|
queue_Control_Transfer(dev, &setup, NULL, this);
|
||||||
|
control_queued = true;
|
||||||
|
setup_state = 1; // We are at step one of setup...
|
||||||
|
pending_control = 0xf;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
// PID:VID - not in our product list.
|
// PID:VID - not in our product list.
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -917,6 +986,66 @@ void USBSerial::control(const Transfer_t *transfer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// First CP210X
|
||||||
|
if (sertype == CP210X) {
|
||||||
|
if (pending_control & 1) {
|
||||||
|
pending_control &= ~1;
|
||||||
|
// set data format
|
||||||
|
uint16_t cp210x_format = (format_ & 0xf) << 8; // This should give us the number of bits.
|
||||||
|
|
||||||
|
// now lets extract the parity from our encoding bits 5-7 and in theres 4-7
|
||||||
|
cp210x_format |= (format_ & 0xe0) >> 1; // they encode bits 9-11
|
||||||
|
|
||||||
|
// See if two stop bits
|
||||||
|
if (format_ & 0x100) cp210x_format |= 2;
|
||||||
|
|
||||||
|
mk_setup(setup, 0x41, 3, cp210x_format, 0, 0); // data format 8N1
|
||||||
|
queue_Control_Transfer(device, &setup, NULL, this);
|
||||||
|
control_queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// set baud rate
|
||||||
|
if (pending_control & 2) {
|
||||||
|
pending_control &= ~2;
|
||||||
|
setupdata[0] = (baudrate) & 0xff; // Setup baud rate 115200 - 0x1C200
|
||||||
|
setupdata[1] = (baudrate >> 8) & 0xff;
|
||||||
|
setupdata[2] = (baudrate >> 16) & 0xff;
|
||||||
|
setupdata[3] = (baudrate >> 24) & 0xff;
|
||||||
|
mk_setup(setup, 0x40, 0x1e, 0, 0, 4);
|
||||||
|
queue_Control_Transfer(device, &setup, setupdata, this);
|
||||||
|
control_queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// configure flow control
|
||||||
|
if (pending_control & 4) {
|
||||||
|
pending_control &= ~4;
|
||||||
|
memset(setupdata, 0, sizeof(setupdata)); // clear out the data
|
||||||
|
setupdata[0] = 1; // Set dtr active?
|
||||||
|
mk_setup(setup, 0x41, 13, 0, 0, 0x10);
|
||||||
|
queue_Control_Transfer(device, &setup, setupdata, this);
|
||||||
|
control_queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// set DTR
|
||||||
|
if (pending_control & 8) {
|
||||||
|
pending_control &= ~8;
|
||||||
|
mk_setup(setup, 0x41, 7, 0x0101, 0, 0);
|
||||||
|
queue_Control_Transfer(device, &setup, NULL, this);
|
||||||
|
control_queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// clear DTR
|
||||||
|
if (pending_control & 0x80) {
|
||||||
|
pending_control &= ~0x80;
|
||||||
|
println("CP210x clear DTR");
|
||||||
|
mk_setup(setup, 0x40, 1, 0x0100, 0, 0);
|
||||||
|
queue_Control_Transfer(device, &setup, NULL, this);
|
||||||
|
control_queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CH341_BAUDBASE_FACTOR 1532620800
|
#define CH341_BAUDBASE_FACTOR 1532620800
|
||||||
@ -1170,6 +1299,7 @@ void USBSerial::begin(uint32_t baud, uint32_t format)
|
|||||||
case FTDI: pending_control |= (format_changed? 0xf : 0xe); break; // Set BAUD, FLOW, DTR
|
case FTDI: pending_control |= (format_changed? 0xf : 0xe); break; // Set BAUD, FLOW, DTR
|
||||||
case PL2303: pending_control |= 0x1e; break; // set more stuff...
|
case PL2303: pending_control |= 0x1e; break; // set more stuff...
|
||||||
case CH341: pending_control |= 0x1e; break;
|
case CH341: pending_control |= 0x1e; break;
|
||||||
|
case CP210X: pending_control |= 0xf; break;
|
||||||
}
|
}
|
||||||
if (!control_queued) control(NULL);
|
if (!control_queued) control(NULL);
|
||||||
NVIC_ENABLE_IRQ(IRQ_USBHS);
|
NVIC_ENABLE_IRQ(IRQ_USBHS);
|
||||||
|
Loading…
Reference in New Issue
Block a user