summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2012-03-04 16:48:40 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2012-03-04 16:48:40 +0100
commit27800e7bfd8b01c7a1480333588c040ece6c4859 (patch)
treea35c66967c249d590687350e068ea5780322d35e
parent432b42350374fb86a4a6f3cd7177e7676138cb54 (diff)
Implemented get_descriptor() and set_address().
-rw-r--r--main.cpp95
1 files changed, 55 insertions, 40 deletions
diff --git a/main.cpp b/main.cpp
index feb3397..327cd90 100644
--- a/main.cpp
+++ b/main.cpp
@@ -17,50 +17,65 @@ static Pin& usb_dm = PA11;
static Pin& usb_dp = PA12;
static Pin& usb_vbus = PA9;
+void usb_write(uint32_t* bufp, uint32_t len) {
+ OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | len;
+ // PKTCNT
+ OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
+ // EPENA CNAK
+
+ len = (len + 3) >> 2;
+
+ while(len--) {
+ OTG_FS.fifo = *bufp++;
+ }
+}
+
+uint32_t dev_desc[] = {0x02000112, 0x400000ff, 0x56781234, 0x00000000, 0x0100};
+uint32_t conf_desc[] = {0x00090209, 0xc0000100, 0x00};
+
+bool get_descriptor(uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
+ switch(wValue) {
+ case 0x100:
+ usb_write(dev_desc, wLength);
+ return true;
+ case 0x200:
+ usb_write(conf_desc, wLength);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool set_address(uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
+ OTG_FS.dev_reg.DCFG |= wValue << 4;
+ usb_write(0, 0);
+ return true;
+}
+
void handle_setup(const uint32_t* bufp) {
led_red.toggle();
- if(bufp[0] == 0x01000680 && bufp[1] == 0x00080000) {
- OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | 8;
- // PKTCNT
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
- // EPENA CNAK
- OTG_FS.fifo = 0x02000112;
- OTG_FS.fifo = 0x400000ff;
- } else if((bufp[0] & 0xffff) == 0x0500) {
- OTG_FS.dev_reg.DCFG |= ((bufp[0] >> 16) & 0x7f) << 4;
-
- OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | 0;
- // PKTCNT
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
- // EPENA CNAK
- } else if(bufp[0] == 0x01000680 && bufp[1] == 0x00120000) {
- OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | 18;
- // PKTCNT
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
- // EPENA CNAK
- OTG_FS.fifo = 0x02000112;
- OTG_FS.fifo = 0x400000ff;
- OTG_FS.fifo = 0x56781234;
- OTG_FS.fifo = 0x00000000;
- OTG_FS.fifo = 0x00000100;
- } else if(bufp[0] == 0x02000680 && bufp[1] == 0x00040000) {
- OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | 4;
- // PKTCNT
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
- // EPENA CNAK
- OTG_FS.fifo = 0x00090209;
- } else if(bufp[0] == 0x02000680 && bufp[1] == 0x00090000) {
- OTG_FS.dev_iep_reg[0].DIEPTSIZ = (1 << 19) | 9;
- // PKTCNT
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 31) | (1 << 26);
- // EPENA CNAK
- OTG_FS.fifo = 0x00090209;
- OTG_FS.fifo = 0xc0000100;
- OTG_FS.fifo = 0x00000000;
- } else {
- OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 21);
+ uint8_t bmRequestType = bufp[0] & 0xff;
+ uint8_t bRequest = (bufp[0] >> 8) & 0xff;
+ uint16_t wValue = (bufp[0] >> 16) & 0xffff;
+ uint16_t wIndex = bufp[1] & 0xffff;
+ uint16_t wLength = (bufp[1] >> 16) & 0xffff;
+
+ // GET_DESCRIPTOR
+ if(bmRequestType == 0x80 && bRequest == 0x06) {
+ if(get_descriptor(wValue, wIndex, wLength)) {
+ return;
+ }
}
+
+ // SET_ADDRESS
+ if(bmRequestType == 0x00 && bRequest == 0x05) {
+ if(set_address(wValue, wIndex, wLength)) {
+ return;
+ }
+ }
+
+ OTG_FS.dev_iep_reg[0].DIEPCTL |= (1 << 21);
}
static uint32_t buf[16];