Browse Source

FTDI serial receive working, still no transmit

main
PaulStoffregen 7 years ago
parent
commit
3a43ebf73b
2 changed files with 39 additions and 12 deletions
  1. +3
    -1
      USBHost_t36.h
  2. +36
    -11
      serial.cpp

+ 3
- 1
USBHost_t36.h View File



class USBSerial: public USBDriver, public Stream { class USBSerial: public USBDriver, public Stream {
public: public:
enum { BUFFER_SIZE = 4200 }; // must hold at least 6 max size packets, plus 2 extra bytes
enum { BUFFER_SIZE = 390 }; // must hold at least 6 max size packets, plus 2 extra bytes
USBSerial(USBHost &host) { init(); } USBSerial(USBHost &host) { init(); }
void begin(uint32_t baud, uint32_t format=0); void begin(uint32_t baud, uint32_t format=0);
void end(void); void end(void);
static void tx_callback(const Transfer_t *transfer); static void tx_callback(const Transfer_t *transfer);
void rx_data(const Transfer_t *transfer); void rx_data(const Transfer_t *transfer);
void tx_data(const Transfer_t *transfer); void tx_data(const Transfer_t *transfer);
void rx_queue_packets(uint32_t head, uint32_t tail);
void init(); void init();
static bool check_rxtx_ep(uint32_t &rxep, uint32_t &txep); static bool check_rxtx_ep(uint32_t &rxep, uint32_t &txep);
bool init_buffers(uint32_t rsize, uint32_t tsize); bool init_buffers(uint32_t rsize, uint32_t tsize);
volatile uint8_t rxstate;// bitmask: which receive packets are queued volatile uint8_t rxstate;// bitmask: which receive packets are queued
volatile uint8_t txstate; volatile uint8_t txstate;
uint8_t pending_control; uint8_t pending_control;
bool control_queued;
enum { CDCACM, FTDI, PL2303, CH341 } sertype; enum { CDCACM, FTDI, PL2303, CH341 } sertype;
}; };



+ 36
- 11
serial.cpp View File

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);
control_queued = true;
return true; return true;
} }
} }
void USBSerial::control(const Transfer_t *transfer) void USBSerial::control(const Transfer_t *transfer)
{ {
println("control callback (serial)"); println("control callback (serial)");
control_queued = false;


// set data format // set data format
if (pending_control & 1) { if (pending_control & 1) {
pending_control &= ~1; pending_control &= ~1;
mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1 mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1
queue_Control_Transfer(device, &setup, NULL, this); queue_Control_Transfer(device, &setup, NULL, this);
control_queued = true;
return; return;
} }
// set baud rate // set baud rate
uint32_t baudval = 3000000 / baudrate; uint32_t baudval = 3000000 / baudrate;
mk_setup(setup, 0x40, 3, baudval, 0, 0); mk_setup(setup, 0x40, 3, baudval, 0, 0);
queue_Control_Transfer(device, &setup, NULL, this); queue_Control_Transfer(device, &setup, NULL, this);
control_queued = true;
return; return;
} }
// configure flow control // configure flow control
pending_control &= ~4; pending_control &= ~4;
mk_setup(setup, 0x40, 2, 0, 0, 0); mk_setup(setup, 0x40, 2, 0, 0, 0);
queue_Control_Transfer(device, &setup, NULL, this); queue_Control_Transfer(device, &setup, NULL, this);
control_queued = true;
return; return;
} }
// set DTR // set DTR
pending_control &= ~8; pending_control &= ~8;
mk_setup(setup, 0x40, 1, 0x0101, 0, 0); mk_setup(setup, 0x40, 1, 0x0101, 0, 0);
queue_Control_Transfer(device, &setup, NULL, this); queue_Control_Transfer(device, &setup, NULL, this);
control_queued = true;
return; return;
} }

} }


void USBSerial::rx_callback(const Transfer_t *transfer) void USBSerial::rx_callback(const Transfer_t *transfer)
len = 0; len = 0;
} }
} }
if (len > 0) {
print("rx: ");
print_hexbytes(p, len);
}
//if (len > 0) {
//print("rx: ");
//print_hexbytes(p, len);
//}
// Copy data from packet buffer to circular buffer. // Copy data from packet buffer to circular buffer.
// Assume the buffer will always have space, since we // Assume the buffer will always have space, since we
// check before queuing the buffers // check before queuing the buffers
uint32_t head = rxhead; uint32_t head = rxhead;
uint32_t tail = rxtail; uint32_t tail = rxtail;
if (++head >= rxsize) head = 0;
uint32_t avail; uint32_t avail;
if (len > 0) { if (len > 0) {
//print("head=", head);
//print(", tail=", tail);
avail = rxsize - head; avail = rxsize - head;
//print(", avail=", avail);
//println(", rxsize=", rxsize);
if (avail > len) avail = len; if (avail > len) avail = len;
memcpy(rxbuf + head, p, avail); memcpy(rxbuf + head, p, avail);
if (len <= avail) { if (len <= avail) {
head += avail;
head += avail - 1;
if (head >= rxsize) head = 0; if (head >= rxsize) head = 0;
} else { } else {
head = len - avail;
memcpy(rxbuf, p + avail, head);
head = len - avail - 1;
memcpy(rxbuf, p + avail, head + 1);
} }
rxhead = head; rxhead = head;
} }
// re-queue packet buffer(s) if possible
rx_queue_packets(head, tail);
}

// re-queue packet buffer(s) if possible
void USBSerial::rx_queue_packets(uint32_t head, uint32_t tail)
{
uint32_t avail;
if (head >= tail) { if (head >= tail) {
avail = rxsize - 1 - head + tail; avail = rxsize - 1 - head + tail;
} else { } else {


void USBSerial::begin(uint32_t baud, uint32_t format) void USBSerial::begin(uint32_t baud, uint32_t format)
{ {
NVIC_DISABLE_IRQ(IRQ_USBHS);
baudrate = baud;
pending_control |= 2;
if (!control_queued) control(NULL);
NVIC_ENABLE_IRQ(IRQ_USBHS);
} }


void USBSerial::end(void) void USBSerial::end(void)
uint32_t head = rxhead; uint32_t head = rxhead;
uint32_t tail = rxtail; uint32_t tail = rxtail;
if (head >= tail) return head - tail; if (head >= tail) return head - tail;
return 0;
return rxsize + head - tail;
} }


int USBSerial::peek(void) int USBSerial::peek(void)
if (++tail >= rxsize) tail = 0; if (++tail >= rxsize) tail = 0;
int c = rxbuf[tail]; int c = rxbuf[tail];
rxtail = tail; rxtail = tail;
// TODO: if rx packet not queued, and buffer now can fit a full packet, queue it
if ((rxstate & 0x03) != 0x03) {
NVIC_DISABLE_IRQ(IRQ_USBHS);
rx_queue_packets(head, tail);
NVIC_ENABLE_IRQ(IRQ_USBHS);
}
return c; return c;
} }



Loading…
Cancel
Save