Ver código fonte

Implement driver timers

main
PaulStoffregen 7 anos atrás
pai
commit
8ee6d28432
3 arquivos alterados com 83 adições e 40 exclusões
  1. +4
    -1
      USBHost.h
  2. +60
    -39
      ehci.cpp
  3. +19
    -0
      hub.cpp

+ 4
- 1
USBHost.h Ver arquivo

@@ -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;

+ 60
- 39
ehci.cpp Ver arquivo

@@ -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
- 0
hub.cpp Ver arquivo

@@ -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);

Carregando…
Cancelar
Salvar