mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-22 00:52:19 -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 available(void);
|
||||||
virtual int peek(void);
|
virtual int peek(void);
|
||||||
virtual int read(void);
|
virtual int read(void);
|
||||||
|
virtual int availableForWrite();
|
||||||
virtual size_t write(uint8_t c);
|
virtual size_t write(uint8_t c);
|
||||||
protected:
|
protected:
|
||||||
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
|
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();
|
virtual void disconnect();
|
||||||
private:
|
private:
|
||||||
static void rx_callback(const Transfer_t *transfer);
|
static void rx_callback(const Transfer_t *transfer);
|
||||||
@ -769,22 +771,27 @@ private:
|
|||||||
Pipe_t mypipes[3] __attribute__ ((aligned(32)));
|
Pipe_t mypipes[3] __attribute__ ((aligned(32)));
|
||||||
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
|
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
|
||||||
uint32_t bigbuffer[(BUFFER_SIZE+3)/4];
|
uint32_t bigbuffer[(BUFFER_SIZE+3)/4];
|
||||||
|
setup_t setup;
|
||||||
|
uint8_t setupdata[8];
|
||||||
|
uint32_t baudrate;
|
||||||
Pipe_t *rxpipe;
|
Pipe_t *rxpipe;
|
||||||
Pipe_t *txpipe;
|
Pipe_t *txpipe;
|
||||||
uint8_t *rx1; // location for first incoming packet
|
uint8_t *rx1; // location for first incoming packet
|
||||||
uint8_t *rx2; // location for second incoming packet
|
uint8_t *rx2; // location for second incoming packet
|
||||||
uint8_t *rxbuf; // receive circular buffer
|
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 *tx1; // location for first outgoing packet
|
||||||
uint8_t *tx2; // location for second outgoing packet
|
uint8_t *tx2; // location for second outgoing packet
|
||||||
uint8_t *txbuf;
|
uint8_t *txbuf;
|
||||||
uint16_t txhead;
|
volatile uint16_t rxhead;// receive head
|
||||||
uint16_t txtail;
|
volatile uint16_t rxtail;// receive tail
|
||||||
|
volatile uint16_t txhead;
|
||||||
|
volatile uint16_t txtail;
|
||||||
uint16_t rxsize;// size of receive circular buffer
|
uint16_t rxsize;// size of receive circular buffer
|
||||||
uint16_t txsize;// size of transmit circular buffer
|
uint16_t txsize;// size of transmit circular buffer
|
||||||
uint8_t rxstate;// bitmask: which receive packets are queued
|
volatile uint8_t rxstate;// bitmask: which receive packets are queued
|
||||||
bool ignore_first_two_bytes;
|
volatile uint8_t txstate;
|
||||||
|
uint8_t pending_control;
|
||||||
|
enum { CDCACM, FTDI, PL2303, CH341 } sertype;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
122
serial.cpp
122
serial.cpp
@ -70,7 +70,7 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
|||||||
// TODO: free rxpipe
|
// TODO: free rxpipe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ignore_first_two_bytes = true;
|
sertype = FTDI;
|
||||||
rxpipe->callback_function = rx_callback;
|
rxpipe->callback_function = rx_callback;
|
||||||
queue_Data_Transfer(rxpipe, rx1, 64, this);
|
queue_Data_Transfer(rxpipe, rx1, 64, this);
|
||||||
rxstate = 1;
|
rxstate = 1;
|
||||||
@ -79,6 +79,10 @@ bool USBSerial::claim(Device_t *dev, int type, const uint8_t *descriptors, uint3
|
|||||||
rxstate = 3;
|
rxstate = 3;
|
||||||
}
|
}
|
||||||
txpipe->callback_function = tx_callback;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,11 +128,48 @@ bool USBSerial::init_buffers(uint32_t rsize, uint32_t tsize)
|
|||||||
return true;
|
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)
|
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)
|
void USBSerial::rx_data(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
|
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) {
|
if (transfer->buffer == rx1) {
|
||||||
rxstate &= 0xFE;
|
rxstate &= 0xFE;
|
||||||
} else if (transfer->buffer == rx2) {
|
} else if (transfer->buffer == rx2) {
|
||||||
@ -156,7 +195,7 @@ void USBSerial::rx_data(const Transfer_t *transfer)
|
|||||||
}
|
}
|
||||||
// get start of data and actual length
|
// get start of data and actual length
|
||||||
const uint8_t *p = (const uint8_t *)transfer->buffer;
|
const uint8_t *p = (const uint8_t *)transfer->buffer;
|
||||||
if (ignore_first_two_bytes) {
|
if (sertype == FTDI) {
|
||||||
if (len >= 2) {
|
if (len >= 2) {
|
||||||
p += 2;
|
p += 2;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
@ -164,18 +203,34 @@ void USBSerial::rx_data(const Transfer_t *transfer)
|
|||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// copy data from packet buffer to circular buffer
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
// TODO: copy to buffer
|
print("rx: ");
|
||||||
|
print_hexbytes(p, len);
|
||||||
}
|
}
|
||||||
// re-queue packet buffer(s) if possible
|
// Copy data from packet buffer to circular buffer.
|
||||||
uint32_t avail;
|
// Assume the buffer will always have space, since we
|
||||||
|
// check before queuing the buffers
|
||||||
uint32_t head = rxhead;
|
uint32_t head = rxhead;
|
||||||
uint32_t tail = rxtail;
|
uint32_t tail = rxtail;
|
||||||
if (head >= tail) {
|
uint32_t avail;
|
||||||
avail = rxsize - 1 + (tail - head);
|
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 {
|
} else {
|
||||||
avail = (tail - head) - 1;
|
head = len - avail;
|
||||||
|
memcpy(rxbuf, p + avail, head);
|
||||||
|
}
|
||||||
|
rxhead = head;
|
||||||
|
}
|
||||||
|
// re-queue packet buffer(s) if possible
|
||||||
|
if (head >= tail) {
|
||||||
|
avail = rxsize - 1 - head + tail;
|
||||||
|
} else {
|
||||||
|
avail = tail - head - 1;
|
||||||
}
|
}
|
||||||
uint32_t packetsize = rx2 - rx1;
|
uint32_t packetsize = rx2 - rx1;
|
||||||
if (avail >= packetsize) {
|
if (avail >= packetsize) {
|
||||||
@ -219,21 +274,57 @@ void USBSerial::end(void)
|
|||||||
|
|
||||||
int USBSerial::available(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int USBSerial::peek(void)
|
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)
|
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)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,8 +356,5 @@ size_t USBSerial::write(uint8_t c)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void USBSerial::disconnect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user