diff --git a/arch/arm/src/at32/at32_otgfsdev.c b/arch/arm/src/at32/at32_otgfsdev.c index 613ed8b34f293..722e68422b8b9 100644 --- a/arch/arm/src/at32/at32_otgfsdev.c +++ b/arch/arm/src/at32/at32_otgfsdev.c @@ -1337,7 +1337,7 @@ static void at32_epin_request(struct at32_usbdev_s *priv, * The flag is cleared whenever a packet is sent in the loop below. */ - privep->zlp = true; + privep->zlp = true; } /* Add one more packet to the TxFIFO. We will wait for the transfer @@ -2195,31 +2195,31 @@ static inline void at32_ep0out_testmode(struct at32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTGFS_TESTMODE_J; - break; - - case 2: - priv->testmode = OTGFS_TESTMODE_K; - break; - - case 3: - priv->testmode = OTGFS_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTGFS_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTGFS_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTGFS_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTGFS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGFS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGFS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGFS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGFS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGFS_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2245,365 +2245,371 @@ static inline void at32_ep0out_stdrequest(struct at32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_EPGETSTATUS), 0); - privep = at32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADEPGETSTATUS), + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_EPGETSTATUS), 0); - priv->stalled = true; + privep = at32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace( + TRACE_DEVERROR(AT32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + at32_ep0in_setupresponse(priv, priv->ep0data, 2); + } } - else + break; + + case USB_REQ_RECIPIENT_DEVICE: { - if (privep->stalled) + if (ctrlreq->index == 0) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace(TRACE_INTDECODE( + AT32_TRACEINTID_DEVGETSTATUS), + 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + at32_ep0in_setupresponse(priv, priv->ep0data, 2); } else { - priv->ep0data[0] = 0; /* Not stalled */ + usbtrace(TRACE_DEVERROR( + AT32_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; } - - priv->ep0data[1] = 0; - at32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_INTERFACE: { - usbtrace(TRACE_INTDECODE( - AT32_TRACEINTID_DEVGETSTATUS), + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_IFGETSTATUS), 0); - - /* Features: Remote Wakeup and self-powered */ - - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; at32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace(TRACE_DEVERROR( - AT32_TRACEERR_BADDEVGETSTATUS), + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETSTATUS), 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = at32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + at32_ep_clrstall(privep); + at32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + at32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - at32_ep0in_setupresponse(priv, priv->ep0data, 2); + at32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; - default: + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = at32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + at32_ep_setstall(privep); + at32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + at32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + at32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETSTATUS), 0); + /* Actually, I think we could just stall here. */ + + at32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = at32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - at32_ep_clrstall(privep); - at32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - at32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - at32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + at32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + at32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = at32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - at32_ep_setstall(privep); - at32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - at32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - at32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - at32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - at32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - at32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + at32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + at32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) - { - at32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - at32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = at32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = at32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSETIF), 0); - at32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_GETSETIF), 0); + at32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3280,144 +3286,147 @@ static inline void at32_rxinterrupt(struct at32_usbdev_s *priv) switch (regval & OTGFS_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit - * has taken effect. + /* Global OUT NAK. This indicate that the global OUT NAK bit + * has taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, - * DPID = Don't Care. + * PKTSTS = DataOUT, BCNT = size of the received data OUT + * packet, EPNUM = EPNUM on which the packet was received, DPID + * = Actual Data PID. */ - case OTGFS_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTNAK), 0); - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> + OTGFS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + at32_epout_receive(privep, bcnt); + } + } + break; - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, DPID = Actual - * Data PID. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> - OTGFS_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - at32_epout_receive(privep, bcnt); - } - } - break; + /* OUT transfer completed. This indicates that an OUT data + * transfer for the specified OUT endpoint has completed. + * After this entry is popped from the receive FIFO, the core + * asserts a Transfer Completed interrupt on the specified OUT + * endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP + * Num on which the data transfer is complete, DPID = Don't + * Care. + */ - /* OUT transfer completed. This indicates that an OUT data - * transfer for the specified OUT endpoint has completed. - * After this entry is popped from the receive FIFO, the core - * asserts a Transfer Completed interrupt on the specified OUT - * endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP - * Num on which the data transfer is complete, DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTDONE), epphy); - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP transaction completed. This indicates that the Setup - * stage for the specified endpoint has completed and the Data - * stage has started. - * After this entry is popped from the receive FIFO, the core - * asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETUPDONE), epphy); - - /* Now that the Setup Phase is complete if it was an OUT - * enable the endpoint - * (Doing this here prevents the loss of the first FIFO word) - */ + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. + * After this entry is popped from the receive FIFO, the core + * asserts a Setup interrupt on the specified control OUT + * endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETUPDONE), + epphy); - if (priv->ep0state == EP0STATE_SETUP_OUT) - { - /* Clear NAKSTS so that we can receive the data */ + /* Now that the Setup Phase is complete if it was an OUT + * enable the endpoint (Doing this here prevents the loss + * of the first FIFO word) + */ - regval = at32_getreg(AT32_OTGFS_DOEPCTL0); - regval |= OTGFS_DOEPCTL0_CNAK; - at32_putreg(regval, AT32_OTGFS_DOEPCTL0); - } - } - break; + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ - /* SETUP data packet received. This indicates that a SETUP - * packet for the specified endpoint is now available for - * reading from the receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + regval = at32_getreg(AT32_OTGFS_DOEPCTL0); + regval |= OTGFS_DOEPCTL0_CNAK; + at32_putreg(regval, AT32_OTGFS_DOEPCTL0); + } + } + break; - case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; + /* SETUP data packet received. This indicates that a SETUP + * packet for the specified endpoint is now available for + * reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETUPRECVD), - epphy); + case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup - * packets and only that last SETUP packet will be processed. - */ + usbtrace(TRACE_INTDECODE(AT32_TRACEINTID_SETUPRECVD), + epphy); - at32_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); + /* Read EP0 setup data. NOTE: If multiple SETUP packets + * are received, the last one overwrites the previous setup + * packets and only that last SETUP packet will be + * processed. + */ - /* Was this an IN or an OUT SETUP packet. If it is an OUT - * SETUP, then we need to wait for the completion of the - * data phase to process the setup command. If it is an - * IN SETUP packet, then we must processing the command - * BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ + at32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the + * data phase to process the setup command. If it is an + * IN SETUP packet, then we must processing the command + * BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - /* Wait for the data phase. */ - - priv->ep0state = EP0STATE_SETUP_OUT; - priv->ep0datlen = 0; - } - else - { - /* We can process the setup data as soon as SETUP done - * word is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Wait for the data phase. */ - default: - { - usbtrace(TRACE_DEVERROR(AT32_TRACEERR_INVALIDPARMS), - (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> - OTGFS_GRXSTSD_PKTSTS_SHIFT); - } - break; + priv->ep0state = EP0STATE_SETUP_OUT; + priv->ep0datlen = 0; + } + else + { + /* We can process the setup data as soon as SETUP done + * word is popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(AT32_TRACEERR_INVALIDPARMS), + (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> + OTGFS_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -5539,8 +5548,9 @@ static void at32_hwinitialize(struct at32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_ENUMDNE | - OTGFS_GINT_IEP | OTGFS_GINT_OEP | OTGFS_GINT_USBRST); + regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_WKUP | + OTGFS_GINT_ENUMDNE | OTGFS_GINT_IEP | OTGFS_GINT_OEP | + OTGFS_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTGFS_GINT_IISOIXFR | OTGFS_GINT_IISOOXFR); diff --git a/arch/arm/src/common/stm32/stm32_otgfsdev_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_otgfsdev_m3m4_v1.c index af02d027c98cd..34dd2e726c201 100644 --- a/arch/arm/src/common/stm32/stm32_otgfsdev_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_otgfsdev_m3m4_v1.c @@ -1283,7 +1283,7 @@ static void stm32_epin_request(struct stm32_usbdev_s *priv, * The flag is cleared whenever a packet is sent in the loop below. */ - privep->zlp = true; + privep->zlp = true; } /* Add one more packet to the TxFIFO. We will wait for the transfer @@ -2154,31 +2154,31 @@ static inline void stm32_ep0out_testmode(struct stm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTGFS_TESTMODE_J; - break; - - case 2: - priv->testmode = OTGFS_TESTMODE_K; - break; - - case 3: - priv->testmode = OTGFS_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTGFS_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTGFS_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTGFS_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTGFS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGFS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGFS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGFS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGFS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGFS_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2204,365 +2204,372 @@ static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - privep = stm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - priv->stalled = true; + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace( + TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } } - else + break; + + case USB_REQ_RECIPIENT_DEVICE: { - if (privep->stalled) + if (ctrlreq->index == 0) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace(TRACE_INTDECODE( + STM32_TRACEINTID_DEVGETSTATUS), + 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } else { - priv->ep0data[0] = 0; /* Not stalled */ + usbtrace(TRACE_DEVERROR( + STM32_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; } - - priv->ep0data[1] = 0; - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_INTERFACE: { - usbtrace(TRACE_INTDECODE( - STM32_TRACEINTID_DEVGETSTATUS), + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); - - /* Features: Remote Wakeup and self-powered */ - - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADDEVGETSTATUS), + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + stm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; - default: + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + /* Actually, I think we could just stall here. */ + + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_clrstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - stm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_setstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - stm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - stm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); - stm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3278,144 +3285,148 @@ static inline void stm32_rxinterrupt(struct stm32_usbdev_s *priv) switch (regval & OTGFS_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit - * has taken effect. + /* Global OUT NAK. This indicate that the global OUT NAK bit + * has taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, - * DPID = Don't Care. + * PKTSTS = DataOUT, BCNT = size of the received data OUT + * packet, EPNUM = EPNUM on which the packet was received, DPID + * = Actual Data PID. */ - case OTGFS_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), + epphy); + bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> + OTGFS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, DPID = Actual - * Data PID. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> - OTGFS_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - stm32_epout_receive(privep, bcnt); - } - } - break; + /* OUT transfer completed. This indicates that an OUT data + * transfer for the specified OUT endpoint has completed. + * After this entry is popped from the receive FIFO, the core + * asserts a Transfer Completed interrupt on the specified OUT + * endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP + * Num on which the data transfer is complete, DPID = Don't + * Care. + */ - /* OUT transfer completed. This indicates that an OUT data - * transfer for the specified OUT endpoint has completed. - * After this entry is popped from the receive FIFO, the core - * asserts a Transfer Completed interrupt on the specified OUT - * endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP - * Num on which the data transfer is complete, DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP transaction completed. This indicates that the Setup - * stage for the specified endpoint has completed and the Data - * stage has started. - * After this entry is popped from the receive FIFO, the core - * asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); - - /* Now that the Setup Phase is complete if it was an OUT - * enable the endpoint - * (Doing this here prevents the loss of the first FIFO word) - */ + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. + * After this entry is popped from the receive FIFO, the core + * asserts a Setup interrupt on the specified control OUT + * endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), + epphy); - if (priv->ep0state == EP0STATE_SETUP_OUT) - { - /* Clear NAKSTS so that we can receive the data */ + /* Now that the Setup Phase is complete if it was an OUT + * enable the endpoint (Doing this here prevents the loss + * of the first FIFO word) + */ - regval = stm32_getreg(STM32_OTGFS_DOEPCTL0); - regval |= OTGFS_DOEPCTL0_CNAK; - stm32_putreg(regval, STM32_OTGFS_DOEPCTL0); - } - } - break; + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ - /* SETUP data packet received. This indicates that a SETUP - * packet for the specified endpoint is now available for - * reading from the receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + regval = stm32_getreg(STM32_OTGFS_DOEPCTL0); + regval |= OTGFS_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTGFS_DOEPCTL0); + } + } + break; - case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; + /* SETUP data packet received. This indicates that a SETUP + * packet for the specified endpoint is now available for + * reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), - epphy); + case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup - * packets and only that last SETUP packet will be processed. - */ + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), + epphy); - stm32_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); + /* Read EP0 setup data. NOTE: If multiple SETUP packets + * are received, the last one overwrites the previous setup + * packets and only that last SETUP packet will be + * processed. + */ - /* Was this an IN or an OUT SETUP packet. If it is an OUT - * SETUP, then we need to wait for the completion of the - * data phase to process the setup command. If it is an - * IN SETUP packet, then we must processing the command - * BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ + stm32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the + * data phase to process the setup command. If it is an + * IN SETUP packet, then we must processing the command + * BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - /* Wait for the data phase. */ - - priv->ep0state = EP0STATE_SETUP_OUT; - priv->ep0datlen = 0; - } - else - { - /* We can process the setup data as soon as SETUP done - * word is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Wait for the data phase. */ - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), - (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> - OTGFS_GRXSTSD_PKTSTS_SHIFT); - } - break; + priv->ep0state = EP0STATE_SETUP_OUT; + priv->ep0datlen = 0; + } + else + { + /* We can process the setup data as soon as SETUP done + * word is popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> + OTGFS_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -5533,8 +5544,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_ENUMDNE | - OTGFS_GINT_IEP | OTGFS_GINT_OEP | OTGFS_GINT_USBRST); + regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_WKUP | + OTGFS_GINT_ENUMDNE | OTGFS_GINT_IEP | OTGFS_GINT_OEP | + OTGFS_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTGFS_GINT_IISOIXFR | OTGFS_GINT_IISOOXFR); diff --git a/arch/arm/src/common/stm32/stm32_otghsdev_m3m4_v1.c b/arch/arm/src/common/stm32/stm32_otghsdev_m3m4_v1.c index 4a0e61a213236..42c59aa5c1534 100644 --- a/arch/arm/src/common/stm32/stm32_otghsdev_m3m4_v1.c +++ b/arch/arm/src/common/stm32/stm32_otghsdev_m3m4_v1.c @@ -2075,31 +2075,31 @@ static inline void stm32_ep0out_testmode(struct stm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTGHS_TESTMODE_J; - break; - - case 2: - priv->testmode = OTGHS_TESTMODE_K; - break; - - case 3: - priv->testmode = OTGHS_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTGHS_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTGHS_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTGHS_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTGHS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGHS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGHS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGHS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGHS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGHS_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2124,365 +2124,374 @@ static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - privep = stm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace( - TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0); - priv->stalled = true; - } - else - { - if (privep->stalled) + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), + 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace( + TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; } else { - priv->ep0data[0] = 0; /* Not stalled */ + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - - priv->ep0data[1] = 0; - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_DEVICE: { - usbtrace( - TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0); + if (ctrlreq->index == 0) + { + usbtrace( + TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), + 0); - /* Features: Remote Wakeup and self-powered */ + /* Features: Remote Wakeup and self-powered */ - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace( + TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace( - TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), + 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + stm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ - default: + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_clrstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - stm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_setstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - stm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - stm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE || + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_INTERFACE) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE || - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_INTERFACE) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); - stm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3193,131 +3202,132 @@ static inline void stm32_rxinterrupt(struct stm32_usbdev_s *priv) switch (regval & OTGHS_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit has - * taken effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, - * EPNUM = Don't Care, DPID = Don't Care. - */ + /* Global OUT NAK. This indicate that the global OUT NAK bit has + * taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, + * EPNUM = Don't Care, DPID = Don't Care. + */ - case OTGHS_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); - } - break; + case OTGHS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, - * DPID = Actual Data PID. - */ + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, + * DPID = Actual Data PID. + */ - case OTGHS_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTGHS_GRXSTSD_BCNT_MASK) >> - OTGHS_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - stm32_epout_receive(privep, bcnt); - } - } - break; + case OTGHS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTGHS_GRXSTSD_BCNT_MASK) >> + OTGHS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; - /* OUT transfer completed. This indicates that an OUT data transfer - * for the specified OUT endpoint has completed. After this entry is - * popped from the receive FIFO, the core asserts a Transfer - * Completed interrupt on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ + /* OUT transfer completed. This indicates that an OUT data + * transfer for the specified OUT endpoint has completed. After + * this entry is popped from the receive FIFO, the core asserts a + * Transfer Completed interrupt on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ - case OTGHS_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); - } - break; + case OTGHS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP transaction completed. This indicates that the Setup stage - * for the specified endpoint has completed and the Data stage has - * started. After this entry is popped from the receive FIFO, the - * core asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ - - case OTGHS_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); - } - break; + /* SETUP transaction completed. This indicates that the Setup stage + * for the specified endpoint has completed and the Data stage has + * started. After this entry is popped from the receive FIFO, the + * core asserts a Setup interrupt on the specified control OUT + * endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ - /* SETUP data packet received. This indicates that a SETUP packet - * for the specified endpoint is now available for reading from the - * receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + case OTGHS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + } + break; - case OTGHS_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; - - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); - - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup packets - * and only that last SETUP packet will be processed. - */ - - stm32_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); - - /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, - * then we need to wait for the completion of the data phase to - * process the setup command. If it is an IN SETUP packet, then - * we must processing the command BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ - - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - /* Clear NAKSTS so that we can receive the data */ - - regval = stm32_getreg(STM32_OTGHS_DOEPCTL0); - regval |= OTGHS_DOEPCTL0_CNAK; - stm32_putreg(regval, STM32_OTGHS_DOEPCTL0); - - /* Wait for the data phase. */ - - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data as soon as SETUP done word - * is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + /* SETUP data packet received. This indicates that a SETUP packet + * for the specified endpoint is now available for reading from the + * receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), - (regval & OTGHS_GRXSTSD_PKTSTS_MASK) - >> OTGHS_GRXSTSD_PKTSTS_SHIFT); - } - break; + case OTGHS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets are + * received, the last one overwrites the previous setup packets + * and only that last SETUP packet will be processed. + */ + + stm32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the data + * phase to process the setup command. If it is an IN SETUP + * packet, then we must processing the command BEFORE we enter + * the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = stm32_getreg(STM32_OTGHS_DOEPCTL0); + regval |= OTGHS_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTGHS_DOEPCTL0); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word + * is popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTGHS_GRXSTSD_PKTSTS_MASK) + >> OTGHS_GRXSTSD_PKTSTS_SHIFT); + } + break; } } @@ -5426,8 +5436,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTGHS_GINT_RXFLVL | OTGHS_GINT_USBSUSP | OTGHS_GINT_ENUMDNE | - OTGHS_GINT_IEP | OTGHS_GINT_OEP | OTGHS_GINT_USBRST); + regval = (OTGHS_GINT_RXFLVL | OTGHS_GINT_USBSUSP | OTGHS_GINT_WKUP | + OTGHS_GINT_ENUMDNE | OTGHS_GINT_IEP | OTGHS_GINT_OEP | + OTGHS_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTGHS_GINT_IISOIXFR | OTGHS_GINT_IISOOXFR); diff --git a/arch/arm/src/efm32/efm32_usbdev.c b/arch/arm/src/efm32/efm32_usbdev.c index 8d0af3ebfff2f..5662fbdca0ba3 100644 --- a/arch/arm/src/efm32/efm32_usbdev.c +++ b/arch/arm/src/efm32/efm32_usbdev.c @@ -2086,31 +2086,31 @@ static inline void efm32_ep0out_testmode(struct efm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = _USB_DCTL_TSTCTL_J; - break; - - case 2: - priv->testmode = _USB_DCTL_TSTCTL_K; - break; - - case 3: - priv->testmode = _USB_DCTL_TSTCTL_SE0NAK; - break; - - case 4: - priv->testmode = _USB_DCTL_TSTCTL_PACKET; - break; - - case 5: - priv->testmode = _USB_DCTL_TSTCTL_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = _USB_DCTL_TSTCTL_DISABLE; - priv->stalled = true; + case 1: + priv->testmode = _USB_DCTL_TSTCTL_J; + break; + + case 2: + priv->testmode = _USB_DCTL_TSTCTL_K; + break; + + case 3: + priv->testmode = _USB_DCTL_TSTCTL_SE0NAK; + break; + + case 4: + priv->testmode = _USB_DCTL_TSTCTL_PACKET; + break; + + case 5: + priv->testmode = _USB_DCTL_TSTCTL_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = _USB_DCTL_TSTCTL_DISABLE; + priv->stalled = true; } priv->dotest = true; @@ -2136,364 +2136,371 @@ efm32_ep0out_stdrequest(struct efm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPGETSTATUS), 0); - privep = efm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADEPGETSTATUS), + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPGETSTATUS), 0); - priv->stalled = true; - } - else - { - if (privep->stalled) + privep = efm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace( + TRACE_DEVERROR(EFM32_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; } else { - priv->ep0data[0] = 0; /* Not stalled */ + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + efm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - - priv->ep0data[1] = 0; - efm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_DEVICE: { - usbtrace(TRACE_INTDECODE( - EFM32_TRACEINTID_DEVGETSTATUS), 0); + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE( + EFM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and selfpowered */ - /* Features: Remote Wakeup and selfpowered */ + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + efm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR( + EFM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; efm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace(TRACE_DEVERROR( - EFM32_TRACEERR_BADDEVGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSTATUS), + 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = efm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + efm32_ep_clrstall(privep); + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + efm32_ep0in_transmitzlp(priv); + } + else { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + /* Actually, I think we could just stall here. */ - efm32_ep0in_setupresponse(priv, priv->ep0data, 2); + efm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = efm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + efm32_ep_setstall(privep); + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + efm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + efm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ - default: + efm32_req_dispatch(priv, &priv->ctrlreq); + } + else { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = efm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - efm32_ep_clrstall(privep); - efm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - efm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - efm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. + * We cannot actually change to the next address until + * the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + efm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + efm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = efm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - efm32_ep_setstall(privep); - efm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - efm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - efm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - efm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. - * We cannot actually change to the next address until - * the completion of the status phase. - */ - - efm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - efm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + efm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) - { - efm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - efm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = efm32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = efm32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETIF), 0); - efm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_GETSETIF), 0); + efm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3205,130 +3212,131 @@ static inline void efm32_rxinterrupt(struct efm32_usbdev_s *priv) switch (regval & _USB_GRXSTSP_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit has taken - * effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't - * Care. - */ - - case USB_GRXSTSP_PKTSTS_GOUTNAK: - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTNAK), 0); - } - break; + /* Global OUT NAK. This indicate that the global OUT NAK bit has taken + * effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't + * Care. + */ - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, DPID = Actual Data - * PID. - */ + case USB_GRXSTSP_PKTSTS_GOUTNAK: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTNAK), 0); + } + break; - case USB_GRXSTSP_PKTSTS_PKTRCV: - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & _USB_GRXSTSP_BCNT_MASK) >> _USB_GRXSTSP_BCNT_SHIFT; - if (bcnt > 0) - { - efm32_epout_receive(privep, bcnt); - } - } - break; + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, DPID = Actual Data + * PID. + */ - /* OUT transfer completed. This indicates that an OUT data transfer for - * the specified OUT endpoint has completed. After this entry is popped - * from the receive FIFO, the core asserts a Transfer Completed interrupt - * on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ + case USB_GRXSTSP_PKTSTS_PKTRCV: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & _USB_GRXSTSP_BCNT_MASK) >> + _USB_GRXSTSP_BCNT_SHIFT; + if (bcnt > 0) + { + efm32_epout_receive(privep, bcnt); + } + } + break; - case USB_GRXSTSP_PKTSTS_XFERCOMPL: - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTDONE), epphy); - } - break; + /* OUT transfer completed. This indicates that an OUT data transfer + * for the specified OUT endpoint has completed. After this entry is + * popped from the receive FIFO, the core asserts a Transfer Completed + * interrupt on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ - /* SETUP transaction completed. This indicates that the Setup stage for - * the specified endpoint has completed and the Data stage has started. - * After this entry is popped from the receive FIFO, the core asserts a - * Setup interrupt on the specified control OUT endpoint (triggers an - * interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ - - case USB_GRXSTSP_PKTSTS_SETUPCOMPL: - { - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPDONE), epphy); - } - break; + case USB_GRXSTSP_PKTSTS_XFERCOMPL: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP data packet received. - * This indicates that a SETUP packet for the specified endpoint - * is now available for reading from the receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + /* SETUP transaction completed. This indicates that the Setup stage for + * the specified endpoint has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core asserts a + * Setup interrupt on the specified control OUT endpoint (triggers an + * interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ - case USB_GRXSTSP_PKTSTS_SETUPRCV: - { - uint16_t datlen; + case USB_GRXSTSP_PKTSTS_SETUPCOMPL: + { + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPDONE), epphy); + } + break; - usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPRECVD), epphy); + /* SETUP data packet received. + * This indicates that a SETUP packet for the specified endpoint + * is now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - /* Read EP0 setup data. - * NOTE: If multiple SETUP packets are received, - * the last one overwrites the previous setup packets and only that - * last SETUP packet will be processed. - */ + case USB_GRXSTSP_PKTSTS_SETUPRCV: + { + uint16_t datlen; - efm32_rxfifo_read(&priv->epout[EP0], (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); + usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SETUPRECVD), epphy); - /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, - * then we need to wait for the completion of the data phase to - * process the setup command. If it is an IN SETUP packet, then - * we must processing the command BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero length, - * then, of course, we don't need to wait. - */ + /* Read EP0 setup data. + * NOTE: If multiple SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ + + efm32_rxfifo_read(&priv->epout[EP0], (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero length, + * then, of course, we don't need to wait. + */ - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - /* Clear NAKSTS so that we can receive the data */ + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ - regval = efm32_getreg(EFM32_USB_DOEP0CTL); - regval |= USB_DOEP0CTL_CNAK; - efm32_putreg(regval, EFM32_USB_DOEP0CTL); + regval = efm32_getreg(EFM32_USB_DOEP0CTL); + regval |= USB_DOEP0CTL_CNAK; + efm32_putreg(regval, EFM32_USB_DOEP0CTL); - /* Wait for the data phase. */ + /* Wait for the data phase. */ - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data as soon as SETUP done word is - * popped of the RxFIFO. - */ + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word is + * popped of the RxFIFO. + */ - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; - default: - { - usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), - (regval & _USB_GRXSTSP_PKTSTS_MASK) >> - _USB_GRXSTSP_PKTSTS_SHIFT); - } - break; + default: + { + usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_INVALIDPARMS), + (regval & _USB_GRXSTSP_PKTSTS_MASK) >> + _USB_GRXSTSP_PKTSTS_SHIFT); + } + break; } /* Enable the Rx Status Queue Level interrupt */ @@ -5488,8 +5496,9 @@ static void efm32_hwinitialize(struct efm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ regval = (USB_GINTMSK_RXFLVLMSK | USB_GINTMSK_USBSUSPMSK | - USB_GINTMSK_ENUMDONEMSK | USB_GINTMSK_IEPINTMSK | - USB_GINTMSK_OEPINTMSK | USB_GINTMSK_USBRSTMSK); + USB_GINTMSK_WKUPINTMSK | USB_GINTMSK_ENUMDONEMSK | + USB_GINTMSK_IEPINTMSK | USB_GINTMSK_OEPINTMSK | + USB_GINTMSK_USBRSTMSK); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (USB_GINTMSK_INCOMPISOINMSK | USB_GINTMSK_INCOMPLPMSK); diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index 96be757e9e3f9..10ee9f2ad2a12 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -2194,31 +2194,31 @@ static inline void stm32_ep0out_testmode(struct stm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTG_TESTMODE_J; - break; - - case 2: - priv->testmode = OTG_TESTMODE_K; - break; - - case 3: - priv->testmode = OTG_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTG_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTG_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTG_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTG_TESTMODE_J; + break; + + case 2: + priv->testmode = OTG_TESTMODE_K; + break; + + case 3: + priv->testmode = OTG_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTG_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTG_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTG_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2243,363 +2243,370 @@ static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - privep = stm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - priv->stalled = true; - } - else - { - if (privep->stalled) + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace( + TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; } else { - priv->ep0data[0] = 0; /* Not stalled */ + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - - priv->ep0data[1] = 0; - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_DEVICE: { - usbtrace( - TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), - 0); + if (ctrlreq->index == 0) + { + usbtrace( + TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), + 0); + + /* Features: Remote Wakeup and self-powered */ - /* Features: Remote Wakeup and self-powered */ + priv->ep0data[0] = + (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= + (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace( + TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; + } + } + break; - priv->ep0data[0] = - (priv->selfpowered << USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= - (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0data[0] = 0; priv->ep0data[1] = 0; stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace( - TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), - 0); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), + 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + stm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; - default: + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_clrstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - stm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->index == 0 && ctrlreq->len == 0 + && ctrlreq->value < 128 + && priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + stm32_setaddress(priv, (uint16_t) priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_setstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - stm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device, interface + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->index == 0 && ctrlreq->len == 0 - && ctrlreq->value < 128 - && priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - stm32_setaddress(priv, (uint16_t) priv->ctrlreq.value[0]); - stm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; - - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device, interface - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); - if (((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) || - ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_INTERFACE)) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if (((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) || + ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_INTERFACE)) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->value == 0 && ctrlreq->index == 0 - && ctrlreq->len == 1) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->value == 0 && ctrlreq->index == 0 + && ctrlreq->len == 1) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->index == 0 && ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->index == 0 && ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - int ret = stm32_req_dispatch(priv, &priv->ctrlreq); + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - if (ret == OK) - { - uint8_t cfg = (uint8_t) ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t) ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); - stm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3306,135 +3313,136 @@ static inline void stm32_rxinterrupt(struct stm32_usbdev_s *priv) switch (regval & OTG_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit has - * taken effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = - * Don't Care. - */ + /* Global OUT NAK. This indicate that the global OUT NAK bit has + * taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = + * Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); - } - break; + case OTG_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; - /* OUT data packet received. PKTSTS = DataOUT, BCNT = size of the - * received data OUT packet, EPNUM = EPNUM on which the packet was - * received, DPID = Actual Data PID. - */ + /* OUT data packet received. PKTSTS = DataOUT, BCNT = size of + * the received data OUT packet, EPNUM = EPNUM on which the + * packet was received, DPID = Actual Data PID. + */ - case OTG_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> - OTG_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - stm32_epout_receive(privep, bcnt); - } - } - break; + case OTG_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> + OTG_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; - /* OUT transfer completed. This indicates that an OUT data - * transfer for the specified OUT endpoint has completed. After - * this entry is popped from the receive FIFO, the core asserts - * a Transfer Completed interrupt on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ + /* OUT transfer completed. This indicates that an OUT data + * transfer for the specified OUT endpoint has completed. After + * this entry is popped from the receive FIFO, the core asserts + * a Transfer Completed interrupt on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num + * on which the data transfer is complete, DPID = Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); - } - break; + case OTG_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP transaction completed. This indicates that the Setup stage - * for the specified endpoint has completed and the Data stage has - * started. After this entry is popped from the receive FIFO, the - * core asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. After this entry is popped from the + * receive FIFO, the core asserts a Setup interrupt on the + * specified control OUT endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + case OTG_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); - /* Now that the Setup Phase is complete if it was an OUT enable - * the endpoint (Doing this here prevents the loss of the first - * FIFO word) - */ + /* Now that the Setup Phase is complete if it was an OUT enable + * the endpoint (Doing this here prevents the loss of the first + * FIFO word) + */ - if (priv->ep0state == EP0STATE_SETUP_OUT) - { - /* Clear NAKSTS so that we can receive the data */ + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ - regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); - regval |= OTG_DOEPCTL0_CNAK; - stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); - } - } - break; + regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); + regval |= OTG_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); + } + } + break; - /* SETUP data packet received. This indicates that a SETUP packet - * for the specified endpoint is now available for reading from the - * receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + /* SETUP data packet received. This indicates that a SETUP + * packet for the specified endpoint is now available for reading + * from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - case OTG_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; + case OTG_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup packets - * and only that last SETUP packet will be processed. - */ + /* Read EP0 setup data. NOTE: If multiple SETUP packets are + * received, the last one overwrites the previous setup packets + * and only that last SETUP packet will be processed. + */ - stm32_rxfifo_read(&priv->epout[EP0], - (uint8_t *) & priv->ctrlreq, - USB_SIZEOF_CTRLREQ); + stm32_rxfifo_read(&priv->epout[EP0], + (uint8_t *) & priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the data + * phase to process the setup command. If it is an IN SETUP + * packet, then we must processing the command BEFORE we enter + * the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ - /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, - * then we need to wait for the completion of the data phase to - * process the setup command. If it is an IN SETUP packet, then - * we must processing the command BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word + * is popped of the RxFIFO. + */ - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data as soon as SETUP done word - * is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), - (regval & OTG_GRXSTSD_PKTSTS_MASK) >> - OTG_GRXSTSD_PKTSTS_SHIFT); - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTG_GRXSTSD_PKTSTS_MASK) >> + OTG_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -3977,25 +3985,25 @@ static int stm32_epout_configure(struct stm32_ep_s *privep, switch (maxpacket) { - case 8: - mpsiz = OTG_DOEPCTL0_MPSIZ_8; - break; + case 8: + mpsiz = OTG_DOEPCTL0_MPSIZ_8; + break; - case 16: - mpsiz = OTG_DOEPCTL0_MPSIZ_16; - break; + case 16: + mpsiz = OTG_DOEPCTL0_MPSIZ_16; + break; - case 32: - mpsiz = OTG_DOEPCTL0_MPSIZ_32; - break; + case 32: + mpsiz = OTG_DOEPCTL0_MPSIZ_32; + break; - case 64: - mpsiz = OTG_DOEPCTL0_MPSIZ_64; - break; + case 64: + mpsiz = OTG_DOEPCTL0_MPSIZ_64; + break; - default: - uerr("Unsupported maxpacket: %d\n", maxpacket); - return -EINVAL; + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; } } @@ -4074,25 +4082,25 @@ static int stm32_epin_configure(struct stm32_ep_s *privep, switch (maxpacket) { - case 8: - mpsiz = OTG_DIEPCTL0_MPSIZ_8; - break; + case 8: + mpsiz = OTG_DIEPCTL0_MPSIZ_8; + break; - case 16: - mpsiz = OTG_DIEPCTL0_MPSIZ_16; - break; + case 16: + mpsiz = OTG_DIEPCTL0_MPSIZ_16; + break; - case 32: - mpsiz = OTG_DIEPCTL0_MPSIZ_32; - break; + case 32: + mpsiz = OTG_DIEPCTL0_MPSIZ_32; + break; - case 64: - mpsiz = OTG_DIEPCTL0_MPSIZ_64; - break; + case 64: + mpsiz = OTG_DIEPCTL0_MPSIZ_64; + break; - default: - uerr("Unsupported maxpacket: %d\n", maxpacket); - return -EINVAL; + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; } } @@ -5666,8 +5674,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_ENUMDNE | - OTG_GINT_IEP | OTG_GINT_OEP | OTG_GINT_USBRST); + regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_WKUP | + OTG_GINT_ENUMDNE | OTG_GINT_IEP | OTG_GINT_OEP | + OTG_GINT_USBRST); # ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTG_GINT_IISOIXFR | OTG_GINT_IISOOXFR); diff --git a/arch/arm/src/stm32h7/stm32_otgdev.c b/arch/arm/src/stm32h7/stm32_otgdev.c index d185b987a03fc..f97123a5c2973 100644 --- a/arch/arm/src/stm32h7/stm32_otgdev.c +++ b/arch/arm/src/stm32h7/stm32_otgdev.c @@ -1316,7 +1316,7 @@ static void stm32_epin_request(struct stm32_usbdev_s *priv, * The flag is cleared whenever a packet is sent in the loop below. */ - privep->zlp = true; + privep->zlp = true; } /* Add one more packet to the TxFIFO. We will wait for the transfer @@ -2170,31 +2170,31 @@ static inline void stm32_ep0out_testmode(struct stm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTG_TESTMODE_J; - break; - - case 2: - priv->testmode = OTG_TESTMODE_K; - break; - - case 3: - priv->testmode = OTG_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTG_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTG_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTG_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTG_TESTMODE_J; + break; + + case 2: + priv->testmode = OTG_TESTMODE_K; + break; + + case 3: + priv->testmode = OTG_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTG_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTG_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTG_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2220,366 +2220,372 @@ void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); - privep = stm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADEPGETSTATUS), 0); - priv->stalled = true; - } - else - { - if (privep->stalled) + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), + 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace(TRACE_DEVERROR( + STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; } else { - priv->ep0data[0] = 0; /* Not stalled */ + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - - priv->ep0data[1] = 0; - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_DEVICE: { - usbtrace(TRACE_INTDECODE( - STM32_TRACEINTID_DEVGETSTATUS), 0); + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE( + STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ - /* Features: Remote Wakeup and self-powered */ + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR( + STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADDEVGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), + 0); priv->stalled = true; } + break; } + } + } + break; - break; + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ - case USB_REQ_RECIPIENT_INTERFACE: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + stm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ - default: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, + ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + break; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_clrstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - stm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. + * We cannot actually change to the next address until + * the completion of the status phase. + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) - { - stm32_ep_setstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - stm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. - * We cannot actually change to the next address until - * the completion of the status phase. - */ - - stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - stm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); - stm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3286,141 +3292,141 @@ static inline void stm32_rxinterrupt(struct stm32_usbdev_s *priv) switch (regval & OTG_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. - * This indicate that the global OUT NAK bit - * has taken effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, - * DPID = Don'tCare. - */ + /* Global OUT NAK. + * This indicate that the global OUT NAK bit + * has taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, + * DPID = Don'tCare. + */ - case OTG_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); - } - break; + case OTG_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, - * DPID = Actual Data PID. - */ + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, + * DPID = Actual Data PID. + */ - case OTG_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> - OTG_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - stm32_epout_receive(privep, bcnt); - } - } - break; + case OTG_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> + OTG_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. + * This indicates that an OUT data transfer for the specified OUT + * endpoint has completed. After this entry is popped from the + * receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ - /* OUT transfer completed. - * This indicates that an OUT data transfer for the specified OUT - * endpoint has completed. After this entry is popped from the - * receive FIFO, the core asserts a Transfer Completed interrupt - * on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ + case OTG_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. After this entry is popped from the receive + * FIFO, the core asserts a Setup interrupt on the specified + * control OUT endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); - } - break; + case OTG_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); - /* SETUP transaction completed. - * This indicates that the Setup stage for the specified endpoint - * has completed and the Data stage has started. - * After this entry is popped from the receive FIFO, the core asserts - * a Setup interrupt on the specified control OUT endpoint (triggers - * an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ + /* Now that the Setup Phase is complete if it was an OUT enable + * the endpoint + * (Doing this here prevents the loss of the first FIFO word) + */ - case OTG_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ - /* Now that the Setup Phase is complete if it was an OUT enable - * the endpoint - * (Doing this here prevents the loss of the first FIFO word) - */ + regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); + regval |= OTG_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); + } + } + break; - if (priv->ep0state == EP0STATE_SETUP_OUT) - { - /* Clear NAKSTS so that we can receive the data */ + /* SETUP data packet received. This indicates that a SETUP packet + * for the specified endpoint is now available for reading from the + * receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); - regval |= OTG_DOEPCTL0_CNAK; - stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); - } - } - break; + case OTG_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; - /* SETUP data packet received. - * This indicates that a SETUP packet for the specified endpoint is - * now available for reading from the receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); - case OTG_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; - - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); - - /* Read EP0 setup data. - * NOTE: If multiple SETUP packets are received, the last one - * overwrites the previous setup packets and only that last - * SETUP packet will be processed. - */ - - stm32_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); - - /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, - * then we need to wait for the completion of the data phase to - * process the setup command. If it is an IN SETUP packet, then - * we must processing the command BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ - - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data as soon as SETUP done word - * is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + /* Read EP0 setup data. + * NOTE: If multiple SETUP packets are received, the last one + * overwrites the previous setup packets and only that last + * SETUP packet will be processed. + */ - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), - (regval & OTG_GRXSTSD_PKTSTS_MASK) >> - OTG_GRXSTSD_PKTSTS_SHIFT); - } - break; + stm32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the data + * phase to process the setup command. If it is an IN SETUP + * packet, then we must processing the command BEFORE we enter + * the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word + * is popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTG_GRXSTSD_PKTSTS_MASK) >> + OTG_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -5565,8 +5571,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_ENUMDNE | - OTG_GINT_IEP | OTG_GINT_OEP | OTG_GINT_USBRST); + regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_WKUP | + OTG_GINT_ENUMDNE | OTG_GINT_IEP | OTG_GINT_OEP | + OTG_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTG_GINT_IISOIXFR | OTG_GINT_IISOOXFR); diff --git a/arch/arm/src/stm32l4/stm32l4_otgfsdev.c b/arch/arm/src/stm32l4/stm32l4_otgfsdev.c index af2df0c32ada4..a27b45b24c142 100644 --- a/arch/arm/src/stm32l4/stm32l4_otgfsdev.c +++ b/arch/arm/src/stm32l4/stm32l4_otgfsdev.c @@ -1343,7 +1343,7 @@ static void stm32_epin_request(struct stm32_usbdev_s *priv, * The flag is cleared whenever a packet is sent in the loop below. */ - privep->zlp = true; + privep->zlp = true; } /* Add one more packet to the TxFIFO. We will wait for the transfer @@ -2191,31 +2191,31 @@ static inline void stm32_ep0out_testmode(struct stm32_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTGFS_TESTMODE_J; - break; - - case 2: - priv->testmode = OTGFS_TESTMODE_K; - break; - - case 3: - priv->testmode = OTGFS_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTGFS_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTGFS_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTGFS_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTGFS_TESTMODE_J; + break; + + case 2: + priv->testmode = OTGFS_TESTMODE_K; + break; + + case 3: + priv->testmode = OTGFS_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTGFS_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTGFS_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTGFS_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2241,368 +2241,369 @@ void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || - ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE( - STM32_TRACEINTID_EPGETSTATUS), 0); - privep = stm32_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADEPGETSTATUS), 0); - priv->stalled = true; + usbtrace(TRACE_INTDECODE( + STM32_TRACEINTID_EPGETSTATUS), 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR( + STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } } - else + break; + + case USB_REQ_RECIPIENT_DEVICE: { - if (privep->stalled) + if (ctrlreq->index == 0) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace(TRACE_INTDECODE( + STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << + USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << + USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } else { - priv->ep0data[0] = 0; /* Not stalled */ + usbtrace(TRACE_DEVERROR( + STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; } - - priv->ep0data[1] = 0; - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_INTERFACE: { usbtrace(TRACE_INTDECODE( - STM32_TRACEINTID_DEVGETSTATUS), 0); - - /* Features: Remote Wakeup and self-powered */ - - priv->ep0data[0] = (priv->selfpowered << - USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= (priv->wakeup << - USB_FEATURE_REMOTEWAKEUP); - priv->ep0data[1] = 0; + STM32_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; stm32_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADDEVGETSTATUS), 0); + STM32_TRACEERR_BADGETSTATUS), 0); priv->stalled = true; } + break; } - break; + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ - case USB_REQ_RECIPIENT_INTERFACE: + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != + NULL) + { + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) { - usbtrace(TRACE_INTDECODE( - STM32_TRACEINTID_IFGETSTATUS), 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ - stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + stm32_req_dispatch(priv, &priv->ctrlreq); } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; - default: + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != + NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) { - usbtrace(TRACE_DEVERROR( - STM32_TRACEERR_BADGETSTATUS), 0); + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != - NULL) - { - stm32_ep_clrstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - stm32_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != - NULL) - { - stm32_ep_setstall(privep); - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - stm32_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - stm32_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0 && - ctrlreq->value < 128 && - priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - stm32_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == 0 && - ctrlreq->index == 0 && - ctrlreq->len == 1) - { - stm32_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE && - ctrlreq->index == 0 && - ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ - - int ret = stm32_req_dispatch(priv, &priv->ctrlreq); - - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ - - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); - stm32_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3329,141 +3330,141 @@ static inline void stm32_rxinterrupt(struct stm32_usbdev_s *priv) switch (regval & OTGFS_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. - * This indicate that the global OUT NAK bit has taken effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, - * DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); - } - break; + /* Global OUT NAK. + * This indicate that the global OUT NAK bit has taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, + * DPID = Don't Care. + */ - /* OUT data packet received. - * - * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, - * EPNUM = EPNUM on which the packet was received, - * DPID = Actual Data PID. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), - epphy); - bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> - OTGFS_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - stm32_epout_receive(privep, bcnt); - } - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; - /* OUT transfer completed. - * This indicates that an OUT data transfer for the specified - * OUT endpoint has completed. After this entry is popped from - * the receive FIFO, the core asserts a Transfer Completed - * interrupt on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, - * EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); - } - break; + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT + * packet, EPNUM = EPNUM on which the packet was received, DPID + * = Actual Data PID. + */ - /* SETUP transaction completed. - * This indicates that the Setup stage for the specified endpoint - * has completed and the Data stage has started. - * After this entry is popped from the receive FIFO, the core - * asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ - - case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), - epphy); - - /* On the L4 This event does not occur on the next SETUP - * after a SETUP OUT. - */ - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), + epphy); + bcnt = (regval & OTGFS_GRXSTSD_BCNT_MASK) >> + OTGFS_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; - /* SETUP data packet received. - * This indicates that a SETUP packet for the specified endpoint - * is now available for reading from the receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ - - case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; - - usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), - epphy); - - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup - * packets and only that last SETUP packet will be processed. - */ - - stm32_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); - - /* Was this an IN or an OUT SETUP packet. If it is an OUT - * SETUP, then we need to wait for the completion of the data - * phase to process the setup command. If it is an IN SETUP - * packet, then we must processing the command BEFORE we - * enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ - - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - /* Reset the endpoint and Stop NAK-ing */ - - stm32_ep0out_ctrlsetup(priv); - - /* Wait for the data phase. */ - - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data Now no need to wait for - * SETUP done word to be popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - stm32_ep0out_setup(priv); - } - } - break; + /* OUT transfer completed. + * This indicates that an OUT data transfer for the specified + * OUT endpoint has completed. After this entry is popped from + * the receive FIFO, the core asserts a Transfer Completed + * interrupt on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, + * EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ - default: - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), - (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> - OTGFS_GRXSTSD_PKTSTS_SHIFT); - } - break; + case OTGFS_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. After this entry is popped from the + * receive FIFO, the core asserts a Setup interrupt on the + * specified control OUT endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), + epphy); + + /* On the L4 This event does not occur on the next SETUP + * after a SETUP OUT. + */ + } + break; + + /* SETUP data packet received. This indicates that a SETUP + * packet for the specified endpoint is now available for + * reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case OTGFS_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), + epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets + * are received, the last one overwrites the previous setup + * packets and only that last SETUP packet will be + * processed. + */ + + stm32_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the + * data phase to process the setup command. If it is an IN + * SETUP packet, then we must processing the command BEFORE + * we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Reset the endpoint and Stop NAK-ing */ + + stm32_ep0out_ctrlsetup(priv); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data Now no need to wait + * for SETUP done word to be popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + stm32_ep0out_setup(priv); + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTGFS_GRXSTSD_PKTSTS_MASK) >> + OTGFS_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -5594,8 +5595,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_ENUMDNE | - OTGFS_GINT_IEP | OTGFS_GINT_OEP | OTGFS_GINT_USBRST); + regval = (OTGFS_GINT_RXFLVL | OTGFS_GINT_USBSUSP | OTGFS_GINT_WKUP | + OTGFS_GINT_ENUMDNE | OTGFS_GINT_IEP | OTGFS_GINT_OEP | + OTGFS_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTGFS_GINT_IISOIXFR | OTGFS_GINT_IISOOXFR); diff --git a/arch/xtensa/src/esp32s3/esp32s3_otg_device.c b/arch/xtensa/src/esp32s3/esp32s3_otg_device.c index 6d9386652dd6d..e82023f89471a 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_otg_device.c +++ b/arch/xtensa/src/esp32s3/esp32s3_otg_device.c @@ -2132,31 +2132,31 @@ static void esp32s3_ep0out_testmode(struct esp32s3_usbdev_s *priv, testmode = index >> 8; switch (testmode) { - case 1: - priv->testmode = OTG_TESTMODE_J; - break; - - case 2: - priv->testmode = OTG_TESTMODE_K; - break; - - case 3: - priv->testmode = OTG_TESTMODE_SE0_NAK; - break; - - case 4: - priv->testmode = OTG_TESTMODE_PACKET; - break; - - case 5: - priv->testmode = OTG_TESTMODE_FORCE; - break; - - default: - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADTESTMODE), testmode); - priv->dotest = false; - priv->testmode = OTG_TESTMODE_DISABLED; - priv->stalled = true; + case 1: + priv->testmode = OTG_TESTMODE_J; + break; + + case 2: + priv->testmode = OTG_TESTMODE_K; + break; + + case 3: + priv->testmode = OTG_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTG_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTG_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTG_TESTMODE_DISABLED; + priv->stalled = true; } priv->dotest = true; @@ -2181,368 +2181,373 @@ static void esp32s3_ep0out_stdrequest(struct esp32s3_usbdev_s *priv, switch (ctrlreq->req) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSTATUS), 0); - if (!priv->addressed || - ctrlreq->len != 2 || - USB_REQ_ISOUT(ctrlreq->type) || ctrlreq->value != 0) - { - priv->stalled = true; - } - else - { - switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) - { - case USB_REQ_RECIPIENT_ENDPOINT: + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_EPGETSTATUS), - 0); - privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index); - if (!privep) + case USB_REQ_RECIPIENT_ENDPOINT: { - usbtrace(TRACE_DEVERROR( - ESP32S3_TRACEERR_BADEPGETSTATUS), - 0); - priv->stalled = true; + usbtrace( + TRACE_INTDECODE(ESP32S3_TRACEINTID_EPGETSTATUS), 0); + privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR( + ESP32S3_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = + (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + esp32s3_ep0in_setupresponse(priv, + priv->ep0data, 2); + } } - else + break; + + case USB_REQ_RECIPIENT_DEVICE: { - if (privep->stalled) + if (ctrlreq->index == 0) { - priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + usbtrace( + TRACE_INTDECODE(ESP32S3_TRACEINTID_DEVGETSTATUS), + 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = + (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= + (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + esp32s3_ep0in_setupresponse(priv, + priv->ep0data, 2); } else { - priv->ep0data[0] = 0; /* Not stalled */ + usbtrace( + TRACE_DEVERROR(ESP32S3_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; } - - priv->ep0data[1] = 0; - esp32s3_ep0in_setupresponse(priv, priv->ep0data, 2); } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (ctrlreq->index == 0) + case USB_REQ_RECIPIENT_INTERFACE: { usbtrace( - TRACE_INTDECODE(ESP32S3_TRACEINTID_DEVGETSTATUS), - 0); - - /* Features: Remote Wakeup and self-powered */ - - priv->ep0data[0] = - (priv->selfpowered << USB_FEATURE_SELFPOWERED); - priv->ep0data[0] |= - (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + TRACE_INTDECODE(ESP32S3_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; priv->ep0data[1] = 0; esp32s3_ep0in_setupresponse(priv, priv->ep0data, 2); } - else + break; + + default: { - usbtrace( - TRACE_DEVERROR(ESP32S3_TRACEERR_BADDEVGETSTATUS), - 0); + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETSTATUS), + 0); priv->stalled = true; } + break; } - break; + } + } + break; - case USB_REQ_RECIPIENT_INTERFACE: + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index)) + != NULL) { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_IFGETSTATUS), - 0); - priv->ep0data[0] = 0; - priv->ep0data[1] = 0; + esp32s3_ep_clrstall(privep); + esp32s3_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + esp32s3_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + esp32s3_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ - esp32s3_ep0in_setupresponse(priv, priv->ep0data, 2); + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index)) + != NULL) + { + esp32s3_ep_setstall(privep); + esp32s3_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + esp32s3_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + esp32s3_ep0out_testmode(priv, ctrlreq->index); } - break; + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ - default: + esp32s3_req_dispatch(priv, &priv->ctrlreq); + } + else { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETSTATUS), 0); + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETFEATURE), + 0); priv->stalled = true; } - break; - } - } - } - break; + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_CLEARFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index)) - != NULL) - { - esp32s3_ep_clrstall(privep); - esp32s3_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 0; - esp32s3_ep0in_transmitzlp(priv); - } - else - { - /* Actually, I think we could just stall here. */ - - esp32s3_req_dispatch(priv, &priv->ctrlreq); - } - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADCLEARFEATURE), 0); - priv->stalled = true; - } - } - break; + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETADDRESS), + ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->index == 0 && ctrlreq->len == 0 + && ctrlreq->value < 128 + && priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ + esp32s3_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + esp32s3_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETFEATURE), 0); - if (priv->addressed != 0 && ctrlreq->len == 0) - { - uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; - if (recipient == USB_REQ_RECIPIENT_ENDPOINT && - ctrlreq->value == USB_FEATURE_ENDPOINTHALT && - (privep = esp32s3_ep_findbyaddr(priv, ctrlreq->index)) - != NULL) - { - esp32s3_ep_setstall(privep); - esp32s3_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) - { - priv->wakeup = 1; - esp32s3_ep0in_transmitzlp(priv); - } - else if (recipient == USB_REQ_RECIPIENT_DEVICE && - ctrlreq->value == USB_FEATURE_TESTMODE && - ((ctrlreq->index & 0xff) == 0)) - { - esp32s3_ep0out_testmode(priv, ctrlreq->index); - } - else if (priv->configured) - { - /* Actually, I think we could just stall here. */ - - esp32s3_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETFEATURE), 0); - priv->stalled = true; - } - } - break; + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device, interface + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - case USB_REQ_SETADDRESS: - { + case USB_REQ_SETDESCRIPTOR: /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor */ - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETADDRESS), - ctrlreq->value); - if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->index == 0 && ctrlreq->len == 0 - && ctrlreq->value < 128 - && priv->devstate != DEVSTATE_CONFIGURED) - { - /* Save the address. We cannot actually change to the next - * address until the completion of the status phase. - */ - - esp32s3_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); - esp32s3_ep0in_transmitzlp(priv); - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETADDRESS), 0); - priv->stalled = true; - } - } - break; - - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device, interface - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSETDESC), 0); - if (((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE) || - ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_INTERFACE)) - { - esp32s3_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETSETDESC), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSETDESC), 0); + if (((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) || + ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_INTERFACE)) + { + esp32s3_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->value == 0 && ctrlreq->index == 0 - && ctrlreq->len == 1) - { - esp32s3_req_dispatch(priv, &priv->ctrlreq); - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETCONFIG), 0); - priv->stalled = true; - } - } - break; + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->value == 0 && ctrlreq->index == 0 + && ctrlreq->len == 1) + { + esp32s3_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETCONFIG), 0); - if (priv->addressed && - (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == - USB_REQ_RECIPIENT_DEVICE - && ctrlreq->index == 0 && ctrlreq->len == 0) - { - /* Give the configuration to the class driver */ + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE + && ctrlreq->index == 0 && ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ - int ret = esp32s3_req_dispatch(priv, &priv->ctrlreq); + int ret = esp32s3_req_dispatch(priv, &priv->ctrlreq); - /* If the class driver accepted the configuration, then mark the - * device state as configured (or not, depending on the - * configuration). - */ + /* If the class driver accepted the configuration, then mark + * the device state as configured (or not, depending on the + * configuration). + */ - if (ret == OK) - { - uint8_t cfg = (uint8_t)ctrlreq->value; - if (cfg != 0) - { - priv->devstate = DEVSTATE_CONFIGURED; - priv->configured = true; - } - else - { - priv->devstate = DEVSTATE_ADDRESSED; - priv->configured = false; - } - } - } - else - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETCONFIG), 0); - priv->stalled = true; - } - } - break; + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSETIF), 0); - esp32s3_req_dispatch(priv, &priv->ctrlreq); - } - break; + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_GETSETIF), 0); + esp32s3_req_dispatch(priv, &priv->ctrlreq); + } + break; - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SYNCHFRAME), 0); - } - break; + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SYNCHFRAME), 0); + } + break; - default: - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_INVALIDCTRLREQ), 0); - priv->stalled = true; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; } } @@ -3249,135 +3254,137 @@ static inline void esp32s3_rxinterrupt(struct esp32s3_usbdev_s *priv) switch (regval & OTG_GRXSTSD_PKTSTS_MASK) { - /* Global OUT NAK. This indicate that the global OUT NAK bit has - * taken effect. - * - * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = - * Don't Care. - */ + /* Global OUT NAK. This indicate that the global OUT NAK bit has + * taken effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = + * Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_OUTNAK: - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTNAK), 0); - } - break; + case OTG_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTNAK), 0); + } + break; - /* OUT data packet received. PKTSTS = DataOUT, BCNT = size of the - * received data OUT packet, EPNUM = EPNUM on which the packet was - * received, DPID = Actual Data PID. - */ + /* OUT data packet received. PKTSTS = DataOUT, BCNT = size of + * the received data OUT packet, EPNUM = EPNUM on which the + * packet was received, DPID = Actual Data PID. + */ - case OTG_GRXSTSD_PKTSTS_OUTRECVD: - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTRECVD), epphy); - bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> - OTG_GRXSTSD_BCNT_SHIFT; - if (bcnt > 0) - { - esp32s3_epout_receive(privep, bcnt); - } - } - break; + case OTG_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> + OTG_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + esp32s3_epout_receive(privep, bcnt); + } + } + break; - /* OUT transfer completed. This indicates that an OUT data - * transfer for the specified OUT endpoint has completed. After - * this entry is popped from the receive FIFO, the core asserts - * a Transfer Completed interrupt on the specified OUT endpoint. - * - * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on - * which the data transfer is complete, DPID = Don't Care. - */ + /* OUT transfer completed. This indicates that an OUT data + * transfer for the specified OUT endpoint has completed. After + * this entry is popped from the receive FIFO, the core asserts + * a Transfer Completed interrupt on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num + * on which the data transfer is complete, DPID = Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_OUTDONE: - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTDONE), epphy); - } - break; + case OTG_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_OUTDONE), epphy); + } + break; - /* SETUP transaction completed. This indicates that the Setup stage - * for the specified endpoint has completed and the Data stage has - * started. After this entry is popped from the receive FIFO, the - * core asserts a Setup interrupt on the specified control OUT - * endpoint (triggers an interrupt). - * - * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, - * DPID = Don't Care. - */ + /* SETUP transaction completed. This indicates that the Setup + * stage for the specified endpoint has completed and the Data + * stage has started. After this entry is popped from the + * receive FIFO, the core asserts a Setup interrupt on the + * specified control OUT endpoint (triggers an interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ - case OTG_GRXSTSD_PKTSTS_SETUPDONE: - { - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETUPDONE), epphy); + case OTG_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETUPDONE), epphy); - /* Now that the Setup Phase is complete if it was an OUT enable - * the endpoint (Doing this here prevents the loss of the first - * FIFO word) - */ + /* Now that the Setup Phase is complete if it was an OUT enable + * the endpoint (Doing this here prevents the loss of the first + * FIFO word) + */ - if (priv->ep0state == EP0STATE_SETUP_OUT) - { - /* Clear NAKSTS so that we can receive the data */ + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Clear NAKSTS so that we can receive the data */ - regval = esp32s3_getreg(ESP32S3_OTG_DOEPCTL(0)); - regval |= OTG_DOEPCTL0_CNAK; - esp32s3_putreg(regval, ESP32S3_OTG_DOEPCTL(0)); - } - } - break; + regval = esp32s3_getreg(ESP32S3_OTG_DOEPCTL(0)); + regval |= OTG_DOEPCTL0_CNAK; + esp32s3_putreg(regval, ESP32S3_OTG_DOEPCTL(0)); + } + } + break; - /* SETUP data packet received. This indicates that a SETUP packet - * for the specified endpoint is now available for reading from the - * receive FIFO. - * - * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. - */ + /* SETUP data packet received. This indicates that a SETUP + * packet for the specified endpoint is now available for reading + * from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ - case OTG_GRXSTSD_PKTSTS_SETUPRECVD: - { - uint16_t datlen; + case OTG_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; - usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETUPRECVD), epphy); + usbtrace(TRACE_INTDECODE(ESP32S3_TRACEINTID_SETUPRECVD), + epphy); - /* Read EP0 setup data. NOTE: If multiple SETUP packets are - * received, the last one overwrites the previous setup packets - * and only that last SETUP packet will be processed. - */ + /* Read EP0 setup data. NOTE: If multiple SETUP packets are + * received, the last one overwrites the previous setup packets + * and only that last SETUP packet will be processed. + */ - esp32s3_rxfifo_read(&priv->epout[EP0], - (uint8_t *)&priv->ctrlreq, - USB_SIZEOF_CTRLREQ); + esp32s3_rxfifo_read(&priv->epout[EP0], + (uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT + * SETUP, then we need to wait for the completion of the data + * phase to process the setup command. If it is an IN SETUP + * packet, then we must processing the command BEFORE we enter + * the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero + * length, then, of course, we don't need to wait. + */ - /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, - * then we need to wait for the completion of the data phase to - * process the setup command. If it is an IN SETUP packet, then - * we must processing the command BEFORE we enter the DATA phase. - * - * If the data associated with the OUT SETUP packet is zero - * length, then, of course, we don't need to wait. - */ + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word + * is popped of the RxFIFO. + */ - datlen = GETUINT16(priv->ctrlreq.len); - if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) - { - priv->ep0state = EP0STATE_SETUP_OUT; - } - else - { - /* We can process the setup data as soon as SETUP done word - * is popped of the RxFIFO. - */ - - priv->ep0state = EP0STATE_SETUP_READY; - } - } - break; + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; - default: - { - usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_INVALIDPARMS), - (regval & OTG_GRXSTSD_PKTSTS_MASK) >> - OTG_GRXSTSD_PKTSTS_SHIFT); - } - break; + default: + { + usbtrace(TRACE_DEVERROR(ESP32S3_TRACEERR_INVALIDPARMS), + (regval & OTG_GRXSTSD_PKTSTS_MASK) >> + OTG_GRXSTSD_PKTSTS_SHIFT); + } + break; } } } @@ -3920,25 +3927,25 @@ static int esp32s3_epout_configure(struct esp32s3_ep_s *privep, switch (maxpacket) { - case 8: - mpsiz = OTG_DOEPCTL0_MPSIZ_8; - break; + case 8: + mpsiz = OTG_DOEPCTL0_MPSIZ_8; + break; - case 16: - mpsiz = OTG_DOEPCTL0_MPSIZ_16; - break; + case 16: + mpsiz = OTG_DOEPCTL0_MPSIZ_16; + break; - case 32: - mpsiz = OTG_DOEPCTL0_MPSIZ_32; - break; + case 32: + mpsiz = OTG_DOEPCTL0_MPSIZ_32; + break; - case 64: - mpsiz = OTG_DOEPCTL0_MPSIZ_64; - break; + case 64: + mpsiz = OTG_DOEPCTL0_MPSIZ_64; + break; - default: - uerr("Unsupported maxpacket: %d\n", maxpacket); - return -EINVAL; + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; } } @@ -4018,25 +4025,25 @@ static int esp32s3_epin_configure(struct esp32s3_ep_s *privep, switch (maxpacket) { - case 8: - mpsiz = OTG_DIEPCTL0_MPSIZ_8; - break; + case 8: + mpsiz = OTG_DIEPCTL0_MPSIZ_8; + break; - case 16: - mpsiz = OTG_DIEPCTL0_MPSIZ_16; - break; + case 16: + mpsiz = OTG_DIEPCTL0_MPSIZ_16; + break; - case 32: - mpsiz = OTG_DIEPCTL0_MPSIZ_32; - break; + case 32: + mpsiz = OTG_DIEPCTL0_MPSIZ_32; + break; - case 64: - mpsiz = OTG_DIEPCTL0_MPSIZ_64; - break; + case 64: + mpsiz = OTG_DIEPCTL0_MPSIZ_64; + break; - default: - uerr("Unsupported maxpacket: %d\n", maxpacket); - return -EINVAL; + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; } } @@ -5540,8 +5547,9 @@ static void esp32s3_hwinitialize(struct esp32s3_usbdev_s *priv) /* Enable the interrupts in the INTMSK */ - regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_ENUMDNE | - OTG_GINT_IEP | OTG_GINT_OEP | OTG_GINT_USBRST); + regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_WKUP | + OTG_GINT_ENUMDNE | OTG_GINT_IEP | OTG_GINT_OEP | + OTG_GINT_USBRST); #ifdef CONFIG_USBDEV_ISOCHRONOUS regval |= (OTG_GINT_IISOIXFR | OTG_GINT_IISOOXFR);