summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2012-03-03 15:12:43 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2012-03-04 16:22:27 +0100
commit432b42350374fb86a4a6f3cd7177e7676138cb54 (patch)
treebca07cd9b72e5b10b58e361daa2c0270aa1cf969
parent464ac9db09cc820186df9c4fe2c1f16177837a9f (diff)
Enumeration working.
-rw-r--r--main.cpp78
1 files changed, 76 insertions, 2 deletions
diff --git a/main.cpp b/main.cpp
index 5128062..feb3397 100644
--- a/main.cpp
+++ b/main.cpp
@@ -17,9 +17,74 @@ static Pin& usb_dm = PA11;
static Pin& usb_dp = PA12;
static Pin& usb_vbus = PA9;
+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);
+ }
+}
+
+static uint32_t buf[16];
+
+void handle_rxfifo() {
+
+ uint32_t status = OTG_FS.reg.GRXSTSP;
+
+ uint32_t len = (status & 0x7ff0) >> 6;
+
+ for(uint32_t i = 0; i < len; i++) {
+ buf[i] = OTG_FS.fifo;
+ }
+
+ //if(status == 0x000c0080) {
+ if((status & (0xf << 17)) == (0x4 << 17)) {
+ handle_setup(buf);
+ OTG_FS.dev_oep_reg[0].DOEPCTL |= (1 << 26);
+ }
+}
+
template<>
void interrupt<(Interrupt::IRQ)67>() {
- led_red.toggle();
+ //led_red.toggle();
// USB reset.
if(OTG_FS.reg.GINTSTS & (1 << 12)) {
@@ -39,6 +104,11 @@ void interrupt<(Interrupt::IRQ)67>() {
OTG_FS.reg.GOTGINT = (1 << 2); // SEDET
}
+ // RxFIFO non-empty.
+ if(OTG_FS.reg.GINTSTS & (1 << 4)) {
+ handle_rxfifo();
+ }
+
OTG_FS.reg.GINTSTS = 0xffffffff;
}
@@ -75,12 +145,16 @@ int main() {
OTG_FS.reg.GAHBCFG = 1;
+ //OTG_FS.reg.GRSTCTL |= 1;
+ //while(OTG_FS.reg.GRSTCTL & 1);
+ //Time::sleep(10);
+
// USB configuration
OTG_FS.reg.GUSBCFG = (1 << 30) | (0xf << 10) | (0 << 9) | (0 << 8);
// FDMOD TRDT HNPCAP SRPCAP
// interrupt mask
- OTG_FS.reg.GINTMSK = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 3) | (1 << 2) | (1 << 1);
+ OTG_FS.reg.GINTMSK = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 4);
// ENUMDNEM USBRST USBSUSPM ESUSPM SOFM OTGINT MMISM
// device configuration