mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-12-22 07:18:54 -05:00
FTDI serial config & receive (still work in progress)
This commit is contained in:
parent
ac06c74291
commit
2b8ca63069
@ -753,9 +753,11 @@ public:
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual int availableForWrite();
|
||||
virtual size_t write(uint8_t c);
|
||||
protected:
|
||||
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
|
||||
virtual void control(const Transfer_t *transfer);
|
||||
virtual void disconnect();
|
||||
private:
|
||||
static void rx_callback(const Transfer_t *transfer);
|
||||
@ -769,22 +771,27 @@ private:
|
||||
Pipe_t mypipes[3] __attribute__ ((aligned(32)));
|
||||
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
|
||||
uint32_t bigbuffer[(BUFFER_SIZE+3)/4];
|
||||
setup_t setup;
|
||||
uint8_t setupdata[8];
|
||||
uint32_t baudrate;
|
||||
Pipe_t *rxpipe;
|
||||
Pipe_t *txpipe;
|
||||
uint8_t *rx1; // location for first incoming packet
|
||||
uint8_t *rx2; // location for second incoming packet
|
||||
uint8_t *rxbuf; // receive circular buffer
|
||||
uint16_t rxhead;// receive head
|
||||
uint16_t rxtail;// receive tail
|
||||
uint8_t *tx1; // location for first outgoing packet
|
||||
uint8_t *tx2; // location for second outgoing packet
|
||||
uint8_t *txbuf;
|
||||
uint16_t txhead;
|
||||
uint16_t txtail;
|
||||
volatile uint16_t rxhead;// receive head
|
||||
volatile uint16_t rxtail;// receive tail
|
||||
volatile uint16_t txhead;
|
||||
volatile uint16_t txtail;
|
||||
uint16_t rxsize;// size of receive circular buffer
|
||||
uint16_t txsize;// size of transmit circular buffer
|
||||
uint8_t rxstate;// bitmask: which receive packets are queued
|
||||
bool ignore_first_two_bytes;
|
||||
volatile uint8_t rxstate;// bitmask: which receive packets are queued
|
||||
volatile uint8_t txstate;
|
||||
uint8_t pending_control;
|
||||
enum { CDCACM, FTDI, PL2303, CH341 } sertype;
|
||||
};
|
||||
|
||||
|
||||
|
120
serial.cpp
120
serial.cpp
@ -70,7 +70,7 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
||||
// TODO: free rxpipe
|
||||
return false;
|
||||
}
|
||||
ignore_first_two_bytes = true;
|
||||
sertype = FTDI;
|
||||
rxpipe->callback_function = rx_callback;
|
||||
queue_Data_Transfer(rxpipe, rx1, 64, this);
|
||||
rxstate = 1;
|
||||
@ -79,6 +79,10 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
||||
rxstate = 3;
|
||||
}
|
||||
txpipe->callback_function = tx_callback;
|
||||
baudrate = 115200;
|
||||
pending_control = 0x0F;
|
||||
mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port
|
||||
queue_Control_Transfer(dev, &setup, NULL, this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -124,11 +128,48 @@ bool USBSerial::init_buffers(uint32_t rsize, uint32_t tsize)
|
||||
return true;
|
||||
}
|
||||
|
||||
void USBSerial::disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void USBSerial::control(const Transfer_t *transfer)
|
||||
{
|
||||
println("control callback (serial)");
|
||||
|
||||
// set data format
|
||||
if (pending_control & 1) {
|
||||
pending_control &= ~1;
|
||||
mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1
|
||||
queue_Control_Transfer(device, &setup, NULL, this);
|
||||
return;
|
||||
}
|
||||
// set baud rate
|
||||
if (pending_control & 2) {
|
||||
pending_control &= ~2;
|
||||
uint32_t baudval = 3000000 / baudrate;
|
||||
mk_setup(setup, 0x40, 3, baudval, 0, 0);
|
||||
queue_Control_Transfer(device, &setup, NULL, this);
|
||||
return;
|
||||
}
|
||||
// configure flow control
|
||||
if (pending_control & 4) {
|
||||
pending_control &= ~4;
|
||||
mk_setup(setup, 0x40, 2, 0, 0, 0);
|
||||
queue_Control_Transfer(device, &setup, NULL, this);
|
||||
return;
|
||||
}
|
||||
// set DTR
|
||||
if (pending_control & 8) {
|
||||
pending_control &= ~8;
|
||||
mk_setup(setup, 0x40, 1, 0x0101, 0, 0);
|
||||
queue_Control_Transfer(device, &setup, NULL, this);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void USBSerial::rx_callback(const Transfer_t *transfer)
|
||||
{
|
||||
@ -145,10 +186,8 @@ void USBSerial::tx_callback(const Transfer_t *transfer)
|
||||
void USBSerial::rx_data(const Transfer_t *transfer)
|
||||
{
|
||||
uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
|
||||
print("rx: ");
|
||||
print_hexbytes(transfer->buffer, len);
|
||||
|
||||
// first update rxstate bitmask
|
||||
// first update rxstate bitmask, since buffer is no longer queued
|
||||
if (transfer->buffer == rx1) {
|
||||
rxstate &= 0xFE;
|
||||
} else if (transfer->buffer == rx2) {
|
||||
@ -156,7 +195,7 @@ void USBSerial::rx_data(const Transfer_t *transfer)
|
||||
}
|
||||
// get start of data and actual length
|
||||
const uint8_t *p = (const uint8_t *)transfer->buffer;
|
||||
if (ignore_first_two_bytes) {
|
||||
if (sertype == FTDI) {
|
||||
if (len >= 2) {
|
||||
p += 2;
|
||||
len -= 2;
|
||||
@ -164,18 +203,34 @@ void USBSerial::rx_data(const Transfer_t *transfer)
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
// copy data from packet buffer to circular buffer
|
||||
if (len > 0) {
|
||||
// TODO: copy to buffer
|
||||
print("rx: ");
|
||||
print_hexbytes(p, len);
|
||||
}
|
||||
// re-queue packet buffer(s) if possible
|
||||
uint32_t avail;
|
||||
// Copy data from packet buffer to circular buffer.
|
||||
// Assume the buffer will always have space, since we
|
||||
// check before queuing the buffers
|
||||
uint32_t head = rxhead;
|
||||
uint32_t tail = rxtail;
|
||||
uint32_t avail;
|
||||
if (len > 0) {
|
||||
avail = rxsize - head;
|
||||
if (avail > len) avail = len;
|
||||
memcpy(rxbuf + head, p, avail);
|
||||
if (len <= avail) {
|
||||
head += avail;
|
||||
if (head >= rxsize) head = 0;
|
||||
} else {
|
||||
head = len - avail;
|
||||
memcpy(rxbuf, p + avail, head);
|
||||
}
|
||||
rxhead = head;
|
||||
}
|
||||
// re-queue packet buffer(s) if possible
|
||||
if (head >= tail) {
|
||||
avail = rxsize - 1 + (tail - head);
|
||||
avail = rxsize - 1 - head + tail;
|
||||
} else {
|
||||
avail = (tail - head) - 1;
|
||||
avail = tail - head - 1;
|
||||
}
|
||||
uint32_t packetsize = rx2 - rx1;
|
||||
if (avail >= packetsize) {
|
||||
@ -219,21 +274,57 @@ void USBSerial::end(void)
|
||||
|
||||
int USBSerial::available(void)
|
||||
{
|
||||
if (!device) return 0;
|
||||
uint32_t head = rxhead;
|
||||
uint32_t tail = rxtail;
|
||||
if (head >= tail) return head - tail;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int USBSerial::peek(void)
|
||||
{
|
||||
return -1;
|
||||
if (!device) return -1;
|
||||
uint32_t head = rxhead;
|
||||
uint32_t tail = rxtail;
|
||||
if (head == tail) return -1;
|
||||
if (++tail >= rxsize) tail = 0;
|
||||
return rxbuf[tail];
|
||||
}
|
||||
|
||||
int USBSerial::read(void)
|
||||
{
|
||||
return -1;
|
||||
if (!device) return -1;
|
||||
uint32_t head = rxhead;
|
||||
uint32_t tail = rxtail;
|
||||
if (head == tail) return -1;
|
||||
if (++tail >= rxsize) tail = 0;
|
||||
int c = rxbuf[tail];
|
||||
rxtail = tail;
|
||||
// TODO: if rx packet not queued, and buffer now can fit a full packet, queue it
|
||||
return c;
|
||||
}
|
||||
|
||||
int USBSerial::availableForWrite()
|
||||
{
|
||||
if (!device) return 0;
|
||||
uint32_t head = txhead;
|
||||
uint32_t tail = txtail;
|
||||
if (head >= tail) return txsize - 1 - head + tail;
|
||||
return tail - head - 1;
|
||||
}
|
||||
|
||||
size_t USBSerial::write(uint8_t c)
|
||||
{
|
||||
if (!device) return 0;
|
||||
uint32_t head = txhead;
|
||||
if (++head >= txsize) head = 0;
|
||||
while (txtail == head) {
|
||||
// wait...
|
||||
}
|
||||
txbuf[head] = c;
|
||||
txhead = head;
|
||||
// TODO: if full packet in buffer and tx packet ready, queue it
|
||||
// TODO: otherwise set a latency timer to transmit partial packet
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -265,8 +356,5 @@ size_t USBSerial::write(uint8_t c)
|
||||
|
||||
|
||||
|
||||
void USBSerial::disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user