Ver código fonte

Define timer API for device drivers

main
PaulStoffregen 7 anos atrás
pai
commit
b30d8a4f48
3 arquivos alterados com 72 adições e 12 exclusões
  1. +33
    -8
      USBHost.h
  2. +33
    -3
      ehci.cpp
  3. +6
    -1
      hub.cpp

+ 33
- 8
USBHost.h Ver arquivo

@@ -32,9 +32,11 @@

class USBHost;
class USBDriver;
typedef struct Device_struct Device_t;
typedef struct Pipe_struct Pipe_t;
typedef struct Transfer_struct Transfer_t;
class USBDriverTimer;
typedef struct Device_struct Device_t;
typedef struct Pipe_struct Pipe_t;
typedef struct Transfer_struct Transfer_t;
//typedef struct DriverTimer_struct DriverTimer_t;

// setup_t holds the 8 byte USB SETUP packet data.
// These unions & structs allow convenient access to
@@ -141,6 +143,7 @@ struct Transfer_struct {
uint32_t unused;
};


/************************************************/
/* Main USB EHCI Controller */
/************************************************/
@@ -227,6 +230,11 @@ protected:

// All USB device drivers inherit from this base class.
class USBDriver : public USBHost {
public:
// TODO: user-level functions
// check if device is bound/active/online
// query vid, pid
// query string: manufacturer, product, serial number
protected:
USBDriver() : next(NULL), device(NULL) {}
// Check if a driver wishes to claim a device or interface or group
@@ -248,6 +256,10 @@ protected:
// transfers and wishes to be notified when they complete.
virtual void control(const Transfer_t *transfer) { }

// When any of the USBDriverTimer objects a driver creates generates
// a timer event, this function is called.
virtual void timer(USBDriverTimer &whichTimer) { }

// When a device disconnects from the USB, this function is called.
// The driver must free all resources it allocated and update any
// internal state necessary to deal with the possibility of user
@@ -268,13 +280,24 @@ protected:
Device_t *device;

friend class USBHost;
public:
// TODO: user-level functions
// check if device is bound/active/online
// query vid, pid
// query string: manufacturer, product, serial number
};

// Device drivers may create these timer objects to schedule a timer call
class USBDriverTimer {
public:
USBDriverTimer() { }
USBDriverTimer(USBDriver *d) : driver(d) { }
void init(USBDriver *d) { driver = d; };
void start(uint32_t microseconds);
void *pointer;
uint32_t integer;
private:
USBDriver *driver;
uint32_t usec;
USBDriverTimer *next;
USBDriverTimer *prev;
friend class USBHost;
};

/************************************************/
/* USB Device Drivers */
@@ -295,6 +318,8 @@ protected:
void status_change(const Transfer_t *transfer);
void new_port_status(uint32_t port, uint32_t status);
void update_status();
USBDriverTimer mytimer;
USBDriverTimer othertimer;
setup_t setup;
uint8_t hub_desc[16];
uint8_t endpoint;

+ 33
- 3
ehci.cpp Ver arquivo

@@ -43,6 +43,7 @@ static Transfer_t *async_followup_first=NULL;
static Transfer_t *async_followup_last=NULL;
static Transfer_t *periodic_followup_first=NULL;
static Transfer_t *periodic_followup_last=NULL;
static USBDriverTimer *active_timers=NULL;


static void init_qTD(volatile Transfer_t *t, void *buf, uint32_t len,
@@ -172,7 +173,7 @@ void USBHost::begin()
// enable interrupts, after this point interruts to all the work
attachInterruptVector(IRQ_USBHS, isr);
NVIC_ENABLE_IRQ(IRQ_USBHS);
USBHS_USBINTR = USBHS_USBINTR_PCE | USBHS_USBINTR_TIE0;
USBHS_USBINTR = USBHS_USBINTR_PCE | USBHS_USBINTR_TIE0 | USBHS_USBINTR_TIE1;
USBHS_USBINTR |= USBHS_USBINTR_UEE | USBHS_USBINTR_SEE;
USBHS_USBINTR |= USBHS_USBINTR_AAE;
USBHS_USBINTR |= USBHS_USBINTR_UPIE | USBHS_USBINTR_UAIE;
@@ -306,8 +307,8 @@ void USBHost::isr()

}
}
if (stat & USBHS_USBSTS_TI0) { // timer 0
println("timer");
if (stat & USBHS_USBSTS_TI0) { // timer 0 - used for built-in port events
println("timer0");
if (port_state == PORT_STATE_DEBOUNCE) {
port_state = PORT_STATE_RESET;
USBHS_PORTSC1 |= USBHS_PORTSC_PR; // begin reset sequence
@@ -321,6 +322,34 @@ void USBHost::isr()
rootdev = new_Device(speed, 0, 0);
}
}
if (stat & USBHS_USBSTS_TI1) { // timer 1 - used for USBDriverTimer
println("timer1");
}
}

void USBDriverTimer::start(uint32_t microseconds)
{
Serial.print("start_timer, usec = ");
Serial.print(usec);
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
if (active_timers == NULL) {
usec = microseconds;
next = NULL;
prev = NULL;
active_timers = this;
USBHS_GPTIMER1LD = microseconds - 1;
USBHS_GPTIMER1CTL = USBHS_GPTIMERCTL_RST | USBHS_GPTIMERCTL_RUN;
return;
}
#endif
// TODO, add to active_timers list
//uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF;

}

@@ -403,6 +432,7 @@ Pipe_t * USBHost::new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
// bulk
} else if (type == 3) {
// interrupt
//pipe->qh.token = 0x80000000; // TODO: OUT starts with DATA0 or DATA1?
}
pipe->qh.capabilities[0] = QH_capabilities1(15, c, maxlen, 0,
dtc, dev->speed, endpoint, 0, dev->address);

+ 6
- 1
hub.cpp Ver arquivo

@@ -24,7 +24,7 @@
#include <Arduino.h>
#include "USBHost.h"

USBHub::USBHub()
USBHub::USBHub() : /* mytimer(this), */ othertimer(this)
{
// TODO: free Device_t, Pipe_t & Transfer_t we will need
driver_ready_for_device(this);
@@ -37,6 +37,11 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t

println("USBHub claim_device this=", (uint32_t)this, HEX);

// timer testing TODO: remove this later
mytimer.init(this);
mytimer.start(99129);
othertimer.start(12345);

// check for HUB type
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false;
// protocol must be 0=FS, 1=HS Single-TT, or 2=HS Multi-TT

Carregando…
Cancelar
Salvar