1
0
mirror of https://github.com/gdsports/USBHost_t36 synced 2024-11-22 00:52:19 -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 // When any of the USBDriverTimer objects a driver creates generates
// a timer event, this function is called. // 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. // When a device disconnects from the USB, this function is called.
// The driver must free all resources it allocated and update any // The driver must free all resources it allocated and update any
@ -291,6 +291,7 @@ public:
void start(uint32_t microseconds); void start(uint32_t microseconds);
void *pointer; void *pointer;
uint32_t integer; uint32_t integer;
uint32_t started_micros; // testing only
private: private:
USBDriver *driver; USBDriver *driver;
uint32_t usec; uint32_t usec;
@ -309,6 +310,7 @@ public:
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 control(const Transfer_t *transfer);
virtual void timer_event(USBDriverTimer *whichTimer);
virtual void disconnect(); virtual void disconnect();
void poweron(uint32_t port); void poweron(uint32_t port);
void getstatus(uint32_t port); void getstatus(uint32_t port);
@ -320,6 +322,7 @@ protected:
void update_status(); void update_status();
USBDriverTimer mytimer; USBDriverTimer mytimer;
USBDriverTimer othertimer; USBDriverTimer othertimer;
USBDriverTimer mytimers[7];
setup_t setup; setup_t setup;
uint8_t hub_desc[16]; uint8_t hub_desc[16];
uint8_t endpoint; uint8_t endpoint;

View File

@ -324,21 +324,35 @@ void USBHost::isr()
} }
if (stat & USBHS_USBSTS_TI1) { // timer 1 - used for USBDriverTimer if (stat & USBHS_USBSTS_TI1) { // timer 1 - used for USBDriverTimer
println("timer1"); 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) void USBDriverTimer::start(uint32_t microseconds)
{ {
Serial.print("start_timer, usec = "); Serial.print("start_timer, us = ");
Serial.print(usec); Serial.print(microseconds);
Serial.print(", driver = "); Serial.print(", driver = ");
Serial.print((uint32_t)driver, HEX); Serial.print((uint32_t)driver, HEX);
Serial.print(", this = "); Serial.print(", this = ");
Serial.println((uint32_t)this, HEX); Serial.println((uint32_t)this, HEX);
#if 1
if (!driver) return; if (!driver) return;
if (microseconds < 100) return; // minimum timer duration if (microseconds < 100) return; // minimum timer duration
started_micros = micros();
if (active_timers == NULL) { if (active_timers == NULL) {
// schedule is empty, just add this timer
usec = microseconds; usec = microseconds;
next = NULL; next = NULL;
prev = NULL; prev = NULL;
@ -347,10 +361,47 @@ void USBDriverTimer::start(uint32_t microseconds)
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN; USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
return; return;
} }
#endif uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF;
// TODO, add to active_timers list Serial.print("remain = ");
//uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF; 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 #endif
#if 0
println("Periodic Schedule:"); println("Periodic Schedule:");
for (uint32_t i=0; i < PERIODIC_LIST_SIZE; i++) { for (uint32_t i=0; i < PERIODIC_LIST_SIZE; i++) {
if (i < 10) print(" "); if (i < 10) print(" ");
@ -932,6 +984,7 @@ void USBHost::add_qh_to_periodic_schedule(Pipe_t *pipe)
print(": "); print(": ");
print_qh_list((Pipe_t *)(periodictable[i] & 0xFFFFFFE0)); 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 // timer testing TODO: remove this later
mytimer.init(this); mytimer.init(this);
mytimer.pointer = (void *)"This is mytimer";
mytimer.start(99129); mytimer.start(99129);
othertimer.pointer = (void *)"Hello, I'm othertimer";
othertimer.start(12345); othertimer.start(12345);
for (int i=0; i < 7; i++) {
mytimers[i].init(this);
//mytimers[i].start((i + 1) * 10000);
}
// check for HUB type // check for HUB type
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false; 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; 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) void USBHub::poweron(uint32_t port)
{ {
mk_setup(setup, 0x23, 3, 8, port, 0); mk_setup(setup, 0x23, 3, 8, port, 0);