1
0
mirror of https://github.com/gdsports/USBHost_t36 synced 2024-11-21 08:35:03 -05:00

Implement driver timers

This commit is contained in:
PaulStoffregen 2017-02-27 04:17:43 -08:00
parent b30d8a4f48
commit 8ee6d28432
3 changed files with 83 additions and 40 deletions

View File

@ -258,7 +258,7 @@ protected:
// When any of the USBDriverTimer objects a driver creates generates
// a timer event, this function is called.
virtual void timer(USBDriverTimer &whichTimer) { }
virtual void timer_event(USBDriverTimer *whichTimer) { }
// When a device disconnects from the USB, this function is called.
// The driver must free all resources it allocated and update any
@ -291,6 +291,7 @@ public:
void start(uint32_t microseconds);
void *pointer;
uint32_t integer;
uint32_t started_micros; // testing only
private:
USBDriver *driver;
uint32_t usec;
@ -309,6 +310,7 @@ public:
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 timer_event(USBDriverTimer *whichTimer);
virtual void disconnect();
void poweron(uint32_t port);
void getstatus(uint32_t port);
@ -320,6 +322,7 @@ protected:
void update_status();
USBDriverTimer mytimer;
USBDriverTimer othertimer;
USBDriverTimer mytimers[7];
setup_t setup;
uint8_t hub_desc[16];
uint8_t endpoint;

View File

@ -324,21 +324,35 @@ void USBHost::isr()
}
if (stat & USBHS_USBSTS_TI1) { // timer 1 - used for USBDriverTimer
println("timer1");
USBDriverTimer *timer = active_timers;
if (timer) {
USBDriverTimer *next = timer->next;
active_timers = next;
if (next) {
// more timers scheduled
next->prev = NULL;
USBHS_GPTIMER1LD = next->usec - 1;
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
}
// TODO: call multiple timers if 0 elapsed between them?
timer->driver->timer_event(timer); // call driver's timer()
}
}
}
void USBDriverTimer::start(uint32_t microseconds)
{
Serial.print("start_timer, usec = ");
Serial.print(usec);
Serial.print("start_timer, us = ");
Serial.print(microseconds);
Serial.print(", driver = ");
Serial.print((uint32_t)driver, HEX);
Serial.print(", this = ");
Serial.println((uint32_t)this, HEX);
#if 1
if (!driver) return;
if (microseconds < 100) return; // minimum timer duration
started_micros = micros();
if (active_timers == NULL) {
// schedule is empty, just add this timer
usec = microseconds;
next = NULL;
prev = NULL;
@ -347,10 +361,47 @@ void USBDriverTimer::start(uint32_t microseconds)
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
return;
}
#endif
// TODO, add to active_timers list
//uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF;
uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF;
Serial.print("remain = ");
Serial.println(remain);
if (microseconds < remain) {
// this timer event is before any on the schedule
__disable_irq();
USBHS_GPTIMER1CTL = 0;
USBHS_USBSTS = USBHS_USBSTS_TI1; // TODO: UPI & UAI safety?!
usec = microseconds;
next = active_timers;
prev = NULL;
active_timers->usec = remain - microseconds;
active_timers->prev = this;
active_timers = this;
USBHS_GPTIMER1LD = microseconds - 1;
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
__enable_irq();
return;
}
// add this timer to the schedule, somewhere after the first timer
microseconds -= remain;
USBDriverTimer *list = active_timers;
while (list->next) {
list = list->next;
if (microseconds < list->usec) {
// add timer into middle of list
list->usec -= microseconds;
usec = microseconds;
next = list;
prev = list->prev;
list->prev = this;
prev->next = this;
return;
}
microseconds -= list->usec;
}
// add timer to the end of the schedule
usec = microseconds;
next = NULL;
prev = list;
list->next = this;
}
@ -925,6 +976,7 @@ void USBHost::add_qh_to_periodic_schedule(Pipe_t *pipe)
}
}
#endif
#if 0
println("Periodic Schedule:");
for (uint32_t i=0; i < PERIODIC_LIST_SIZE; i++) {
if (i < 10) print(" ");
@ -932,6 +984,7 @@ void USBHost::add_qh_to_periodic_schedule(Pipe_t *pipe)
print(": ");
print_qh_list((Pipe_t *)(periodictable[i] & 0xFFFFFFE0));
}
#endif
}
@ -1046,35 +1099,3 @@ void USBHost::delete_Pipe(Pipe_t *pipe)
}

19
hub.cpp
View File

@ -39,8 +39,14 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t
// timer testing TODO: remove this later
mytimer.init(this);
mytimer.pointer = (void *)"This is mytimer";
mytimer.start(99129);
othertimer.pointer = (void *)"Hello, I'm othertimer";
othertimer.start(12345);
for (int i=0; i < 7; i++) {
mytimers[i].init(this);
//mytimers[i].start((i + 1) * 10000);
}
// check for HUB type
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false;
@ -84,6 +90,19 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t
return true;
}
void USBHub::timer_event(USBDriverTimer *timer)
{
uint32_t us = micros() - timer->started_micros;
print("timer event (");
print(us);
print(" us): ");
print((char *)timer->pointer);
print(", this = ");
print((uint32_t)this, HEX);
println(", timer = ", (uint32_t)timer, HEX);
}
void USBHub::poweron(uint32_t port)
{
mk_setup(setup, 0x23, 3, 8, port, 0);