mirror of
https://github.com/gdsports/USBHost_t36
synced 2025-02-16 06:50:14 -05:00
FTDI transmit, add partial packet output
This commit is contained in:
parent
b58d4c7191
commit
5575f9fcae
@ -391,6 +391,7 @@ public:
|
|||||||
USBDriverTimer(USBDriver *d) : driver(d) { }
|
USBDriverTimer(USBDriver *d) : driver(d) { }
|
||||||
void init(USBDriver *d) { driver = d; };
|
void init(USBDriver *d) { driver = d; };
|
||||||
void start(uint32_t microseconds);
|
void start(uint32_t microseconds);
|
||||||
|
void stop();
|
||||||
void *pointer;
|
void *pointer;
|
||||||
uint32_t integer;
|
uint32_t integer;
|
||||||
uint32_t started_micros; // testing only
|
uint32_t started_micros; // testing only
|
||||||
@ -747,7 +748,7 @@ private:
|
|||||||
class USBSerial: public USBDriver, public Stream {
|
class USBSerial: public USBDriver, public Stream {
|
||||||
public:
|
public:
|
||||||
enum { BUFFER_SIZE = 390 }; // 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) : txtimer(this) { 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);
|
||||||
virtual int available(void);
|
virtual int available(void);
|
||||||
@ -760,6 +761,7 @@ 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 control(const Transfer_t *transfer);
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
|
virtual void timer_event(USBDriverTimer *whichTimer);
|
||||||
private:
|
private:
|
||||||
static void rx_callback(const Transfer_t *transfer);
|
static void rx_callback(const Transfer_t *transfer);
|
||||||
static void tx_callback(const Transfer_t *transfer);
|
static void tx_callback(const Transfer_t *transfer);
|
||||||
@ -772,6 +774,7 @@ private:
|
|||||||
private:
|
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)));
|
||||||
|
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[8];
|
||||||
|
33
ehci.cpp
33
ehci.cpp
@ -457,6 +457,39 @@ void USBDriverTimer::start(uint32_t microseconds)
|
|||||||
list->next = this;
|
list->next = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBDriverTimer::stop()
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
if (active_timers) {
|
||||||
|
if (active_timers == this) {
|
||||||
|
USBHS_GPTIMER1CTL = 0;
|
||||||
|
if (next) {
|
||||||
|
uint32_t usec_til_next = USBHS_GPTIMER1CTL & 0xFFFFFF;
|
||||||
|
usec_til_next += next->usec;
|
||||||
|
next->usec = usec_til_next;
|
||||||
|
USBHS_GPTIMER1LD = usec_til_next;
|
||||||
|
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
|
||||||
|
next->prev = NULL;
|
||||||
|
active_timers = next;
|
||||||
|
} else {
|
||||||
|
active_timers = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (USBDriverTimer *t = active_timers->next; t; t = t->next) {
|
||||||
|
if (t == this) {
|
||||||
|
t->prev->next = t->next;
|
||||||
|
if (t->next) {
|
||||||
|
t->next->usec += t->usec;
|
||||||
|
t->next->prev = t->prev;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t QH_capabilities1(uint32_t nak_count_reload, uint32_t control_endpoint_flag,
|
static uint32_t QH_capabilities1(uint32_t nak_count_reload, uint32_t control_endpoint_flag,
|
||||||
uint32_t max_packet_length, uint32_t head_of_list, uint32_t data_toggle_control,
|
uint32_t max_packet_length, uint32_t head_of_list, uint32_t data_toggle_control,
|
||||||
|
88
serial.cpp
88
serial.cpp
@ -28,6 +28,11 @@
|
|||||||
#define print USBHost::print
|
#define print USBHost::print
|
||||||
#define println USBHost::println
|
#define println USBHost::println
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
// Initialization and claiming of devices & interfaces
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
void USBSerial::init()
|
void USBSerial::init()
|
||||||
{
|
{
|
||||||
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
|
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
|
||||||
@ -135,6 +140,9 @@ void USBSerial::disconnect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
// Control Transfer For Configuration
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
|
||||||
void USBSerial::control(const Transfer_t *transfer)
|
void USBSerial::control(const Transfer_t *transfer)
|
||||||
@ -177,6 +185,11 @@ void USBSerial::control(const Transfer_t *transfer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
// Interrupt-based Data Movement
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
void USBSerial::rx_callback(const Transfer_t *transfer)
|
void USBSerial::rx_callback(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
if (!transfer->driver) return;
|
if (!transfer->driver) return;
|
||||||
@ -281,14 +294,54 @@ void USBSerial::tx_data(const Transfer_t *transfer)
|
|||||||
println("tx2:");
|
println("tx2:");
|
||||||
txstate &= 0xFD;
|
txstate &= 0xFD;
|
||||||
}
|
}
|
||||||
// TODO: anything need to be done with latency timeout?
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USBSerial::timer_event(USBDriverTimer *whichTimer)
|
||||||
|
{
|
||||||
|
println("txtimer");
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t head = txhead;
|
||||||
|
uint32_t tail = txtail;
|
||||||
|
if (head == tail) {
|
||||||
|
return; // nothing to transmit
|
||||||
|
} else if (head > tail) {
|
||||||
|
count = head - tail;
|
||||||
|
} else {
|
||||||
|
count = txsize + head - tail;
|
||||||
|
}
|
||||||
|
uint8_t *p;
|
||||||
|
if ((txstate & 0x01) == 0) {
|
||||||
|
p = tx1;
|
||||||
|
txstate |= 0x01;
|
||||||
|
} else if ((txstate & 0x02) == 0) {
|
||||||
|
p = tx2;
|
||||||
|
txstate |= 0x02;
|
||||||
|
} else {
|
||||||
|
txtimer.start(1200);
|
||||||
|
return; // no outgoing buffers available, try again later
|
||||||
|
}
|
||||||
|
if (++tail >= txsize) tail = 0;
|
||||||
|
uint32_t n = txsize - tail;
|
||||||
|
if (n > count) n = count;
|
||||||
|
memcpy(p, txbuf + tail, n);
|
||||||
|
if (n >= count) {
|
||||||
|
tail += n - 1;
|
||||||
|
if (tail >= txsize) tail = 0;
|
||||||
|
} else {
|
||||||
|
uint32_t len = count - n;
|
||||||
|
memcpy(p + n, txbuf, len);
|
||||||
|
tail = len - 1;
|
||||||
|
}
|
||||||
|
txtail = tail;
|
||||||
|
queue_Data_Transfer(txpipe, p, count, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
// User Functions - must disable USBHQ IRQ for EHCI access
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
void USBSerial::begin(uint32_t baud, uint32_t format)
|
void USBSerial::begin(uint32_t baud, uint32_t format)
|
||||||
{
|
{
|
||||||
@ -301,6 +354,7 @@ void USBSerial::begin(uint32_t baud, uint32_t format)
|
|||||||
|
|
||||||
void USBSerial::end(void)
|
void USBSerial::end(void)
|
||||||
{
|
{
|
||||||
|
// TODO: lower DTR
|
||||||
}
|
}
|
||||||
|
|
||||||
int USBSerial::available(void)
|
int USBSerial::available(void)
|
||||||
@ -407,32 +461,12 @@ size_t USBSerial::write(uint8_t c)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: otherwise set a latency timer to transmit partial packet
|
// otherwise, set a latency timer to later transmit partial packet
|
||||||
|
txtimer.stop();
|
||||||
|
txtimer.start(3500);
|
||||||
NVIC_ENABLE_IRQ(IRQ_USBHS);
|
NVIC_ENABLE_IRQ(IRQ_USBHS);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user