diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-03-04 16:48:40 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-03-04 16:48:40 +0100 |
commit | 27800e7bfd8b01c7a1480333588c040ece6c4859 (patch) | |
tree | a35c66967c249d590687350e068ea5780322d35e | |
parent | 432b42350374fb86a4a6f3cd7177e7676138cb54 (diff) |
Implemented get_descriptor() and set_address().
-rw-r--r-- | main.cpp | 95 |
1 files changed, 55 insertions, 40 deletions
@@ -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]; |