Browse Source

FTDI transmit, add partial packet output

main
PaulStoffregen 7 years ago
parent
commit
5575f9fcae
3 changed files with 96 additions and 26 deletions
  1. +4
    -1
      USBHost_t36.h
  2. +33
    -0
      ehci.cpp
  3. +59
    -25
      serial.cpp

+ 4
- 1
USBHost_t36.h View File

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
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);
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);
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
- 0
ehci.cpp View File

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,

+ 59
- 25
serial.cpp View File

#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));
} }




/************************************************************/
// Control Transfer For Configuration
/************************************************************/




void USBSerial::control(const Transfer_t *transfer) 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;
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)
{ {


void USBSerial::end(void) void USBSerial::end(void)
{ {
// TODO: lower DTR
} }


int USBSerial::available(void) int USBSerial::available(void)
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…
Cancel
Save