summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2012-09-08 00:58:25 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2012-09-08 17:07:23 +0200
commit929ba5dddbbbf2aaee90047531533cdd2f48ff9d (patch)
tree1f5c71e996b4ab5dfdc2ed95e12c7d5409229423
parent9ae91599772ee81d352014a8ff293c5feec0439b (diff)
temp
-rw-r--r--usb/dwc_otg.h25
-rw-r--r--usb/generic.h22
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