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