diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-08 00:58:25 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-08 17:07:23 +0200 |
commit | 929ba5dddbbbf2aaee90047531533cdd2f48ff9d (patch) | |
tree | 1f5c71e996b4ab5dfdc2ed95e12c7d5409229423 | |
parent | 9ae91599772ee81d352014a8ff293c5feec0439b (diff) |
temp
-rw-r--r-- | usb/dwc_otg.h | 25 | ||||
-rw-r--r-- | usb/generic.h | 22 |
2 files changed, 45 insertions, 2 deletions
diff --git a/usb/dwc_otg.h b/usb/dwc_otg.h index b68ca0e..f206a44 100644 --- a/usb/dwc_otg.h +++ b/usb/dwc_otg.h @@ -24,8 +24,7 @@ class USB_otg : public USB_generic { // OUT packet. if(type == (0x2 << 17)) { - // TODO: Call endpoint callback. - (void)ep; + handle_out(ep, len); } // SETUP packet. @@ -97,6 +96,8 @@ class USB_otg : public USB_generic { void process() { // USB reset. if(otg.reg.GINTSTS & (1 << 12)) { + handle_reset(); + otg.dev_oep_reg[0].DOEPCTL = (1 << 27); otg.dev_reg.DAINTMSK = (1 << 16) | 1; otg.dev_reg.DOEPMSK = (1 << 3) | 1; @@ -136,6 +137,26 @@ class USB_otg : public USB_generic { otg.fifo[ep].reg = *bufp++; } } + + virtual uint32_t read(uint32_t ep, uint32_t* bufp, uint32_t len) { + if(ep != rxfifo_ep) { + return 0; + } + + if(len > rxfifo_bytes) { + len = rxfifo_bytes; + } + + // TODO: Handle non-mod4 length properly. + + for(uint32_t i = 0; i < len; i += 4) { + bufp[i >> 2] = otg.fifo[0].reg; + } + + rxfifo_bytes -= len; + + return len; + } }; #endif diff --git a/usb/generic.h b/usb/generic.h index 915b25a..60c89c4 100644 --- a/usb/generic.h +++ b/usb/generic.h @@ -17,6 +17,8 @@ class USB_class_driver { virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { return SetupStatus::Unhandled; } + + virtual void handle_out(uint8_t ep, uint32_t len) {} }; class USB_generic { @@ -25,12 +27,14 @@ class USB_generic { desc_t conf_desc; USB_class_driver* control_handlers[4]; + USB_class_driver* out_handlers[6]; public: USB_generic(desc_t dev, desc_t conf) : dev_desc(dev), conf_desc(conf) {} virtual bool ep_ready(uint32_t ep) = 0; virtual void write(uint32_t ep, uint32_t* bufp, uint32_t len) = 0; + virtual uint32_t read(uint32_t ep, uint32_t* bufp, uint32_t len) = 0; virtual void hw_set_address(uint8_t addr) = 0; virtual void hw_conf_ep(uint8_t ep, uint32_t conf) = 0; virtual void hw_set_stall(uint8_t ep) = 0; @@ -46,6 +50,16 @@ class USB_generic { // Handler table is full. return false; } + + bool register_out_handler(USB_class_driver* out_handler, uint8_t ep) { + if(ep >= sizeof(out_handlers) / sizeof(*out_handlers)) { + return false; + } + + out_handlers[ep] = out_handler; + + return true; + } protected: bool get_descriptor(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { @@ -102,6 +116,9 @@ class USB_generic { return true; } + void handle_reset() { + + } void handle_setup(const uint32_t* bufp) { uint8_t bmRequestType = bufp[0] & 0xff; @@ -150,6 +167,11 @@ class USB_generic { hw_set_stall(0); } + void handle_out(uint8_t ep, uint32_t len) { + if(out_handlers[ep]) { + out_handlers[ep]->handle_out(ep, len); + } + } }; #endif |