static void handleRxInterrupts(int endpoint) { if(!outInterruptStatus[endpoint]) { return; } //uartPrintf("\tendpoint %d has an RX interrupt\r\n", endpoint); if((outInterruptStatus[endpoint] & USB_EPINT_Back2BackSetup) == USB_EPINT_Back2BackSetup) { OutEPRegs[endpoint].interrupt = USB_EPINT_Back2BackSetup; } if((outInterruptStatus[endpoint] & USB_EPINT_OUTTknEPDis) == USB_EPINT_OUTTknEPDis) { OutEPRegs[endpoint].interrupt = USB_EPINT_OUTTknEPDis; } if((outInterruptStatus[endpoint] & USB_EPINT_AHBErr) == USB_EPINT_AHBErr) { OutEPRegs[endpoint].interrupt = USB_EPINT_AHBErr; } if((outInterruptStatus[endpoint] & USB_EPINT_EPDisbld) == USB_EPINT_EPDisbld) { OutEPRegs[endpoint].interrupt = USB_EPINT_EPDisbld; } if((outInterruptStatus[endpoint] & USB_EPINT_XferCompl) == USB_EPINT_XferCompl) { OutEPRegs[endpoint].interrupt = USB_EPINT_XferCompl; if(endpoint == 0) { receiveControl(controlRecvBuffer, sizeof(USBSetupPacket)); } } }
int usb_start(USBEnumerateHandler hEnumerate, USBStartHandler hStart) { enumerateHandler = hEnumerate; startHandler = hStart; currentlySending = 0xFF; if(txQueue == NULL) txQueue = createRingBuffer(TX_QUEUE_LEN); initializeDescriptors(); if(controlSendBuffer == NULL) controlSendBuffer = memalign(DMA_ALIGN, CONTROL_SEND_BUFFER_LEN); if(controlRecvBuffer == NULL) controlRecvBuffer = memalign(DMA_ALIGN, CONTROL_RECV_BUFFER_LEN); SET_REG(USB + GAHBCFG, GAHBCFG_DMAEN | GAHBCFG_BSTLEN_INCR8 | GAHBCFG_MASKINT); SET_REG(USB + GUSBCFG, GUSBCFG_PHYIF16BIT | GUSBCFG_SRPENABLE | GUSBCFG_HNPENABLE | ((5 & GUSBCFG_TURNAROUND_MASK) << GUSBCFG_TURNAROUND_SHIFT)); SET_REG(USB + DCFG, DCFG_HISPEED); // some random setting. See specs SET_REG(USB + DCFG, GET_REG(USB + DCFG) & ~(DCFG_DEVICEADDRMSK)); InEPRegs[0].control = USB_EPCON_ACTIVE; OutEPRegs[0].control = USB_EPCON_ACTIVE; SET_REG(USB + GRXFSIZ, RX_FIFO_DEPTH); SET_REG(USB + GNPTXFSIZ, (TX_FIFO_DEPTH << GNPTXFSIZ_DEPTH_SHIFT) | TX_FIFO_STARTADDR); int i; for(i = 0; i < USB_NUM_ENDPOINTS; i++) { InEPRegs[i].interrupt = USB_EPINT_INEPNakEff | USB_EPINT_INTknEPMis | USB_EPINT_INTknTXFEmp | USB_EPINT_TimeOUT | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; OutEPRegs[i].interrupt = USB_EPINT_OUTTknEPDis | USB_EPINT_SetUp | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; InEPRegs[i].control = (InEPRegs[i].control & ~(DCTL_NEXTEP_MASK << DCTL_NEXTEP_SHIFT)); } SET_REG(USB + GINTMSK, GINTMSK_OTG | GINTMSK_SUSPEND | GINTMSK_RESET | GINTMSK_INEP | GINTMSK_OEP | GINTMSK_DISCONNECT); SET_REG(USB + DAINTMSK, DAINTMSK_ALL); SET_REG(USB + DOEPMSK, USB_EPINT_XferCompl | USB_EPINT_SetUp | USB_EPINT_Back2BackSetup); SET_REG(USB + DIEPMSK, USB_EPINT_XferCompl | USB_EPINT_AHBErr | USB_EPINT_TimeOUT); InEPRegs[0].interrupt = USB_EPINT_ALL; OutEPRegs[0].interrupt = USB_EPINT_ALL; SET_REG(USB + DCTL, DCTL_PROGRAMDONE + DCTL_CGOUTNAK + DCTL_CGNPINNAK); udelay(USB_PROGRAMDONE_DELAYUS); SET_REG(USB + GOTGCTL, GET_REG(USB + GOTGCTL) | GOTGCTL_SESSIONREQUEST); receiveControl(controlRecvBuffer, sizeof(USBSetupPacket)); change_state(USBPowered); interrupt_enable(USB_INTERRUPT); return 0; }
T_GeneratorError C_RemoteControl::TaskProcedure() { T_GeneratorError L_error_code ; while (M_state != C_TaskControl::E_STATE_STOPPED ) { L_error_code = receiveControl() ; if (L_error_code != E_GEN_NO_ERROR) { M_state = C_TaskControl::E_STATE_STOPPED ; } else { messageReceivedControl (); } } return (L_error_code); }
static int resetUSB() { SET_REG(USB + DCFG, GET_REG(USB + DCFG) & ~DCFG_DEVICEADDRMSK); int endpoint; for(endpoint = 0; endpoint < USB_NUM_ENDPOINTS; endpoint++) { OutEPRegs[endpoint].control = OutEPRegs[endpoint].control | USB_EPCON_SETNAK; } // enable interrupts for endpoint 0 SET_REG(USB + DAINTMSK, GET_REG(USB + DAINTMSK) | ((1 << USB_CONTROLEP) << DAINTMSK_OUT_SHIFT) | ((1 << USB_CONTROLEP) << DAINTMSK_IN_SHIFT)); SET_REG(USB + DOEPMSK, USB_EPINT_XferCompl | USB_EPINT_SetUp | USB_EPINT_Back2BackSetup); SET_REG(USB + DIEPMSK, USB_EPINT_XferCompl | USB_EPINT_AHBErr | USB_EPINT_TimeOUT); receiveControl(controlRecvBuffer, sizeof(USBSetupPacket)); return 0; }
static void usbIRQHandler(uint32_t token) { // we need to mask because GINTSTS is set for a particular interrupt even if it's masked in GINTMSK (GINTMSK just prevents an interrupt being generated) uint32_t status = GET_REG(USB + GINTSTS) & GET_REG(USB + GINTMSK); int process = FALSE; //uartPrintf("<begin interrupt: %x>\r\n", status); if(status) { process = TRUE; } while(process) { if((status & GINTMSK_OTG) == GINTMSK_OTG) { // acknowledge OTG interrupt (these bits are all R_SS_WC which means Write Clear, a write of 1 clears the bits) SET_REG(USB + GOTGINT, GET_REG(USB + GOTGINT)); // acknowledge interrupt (this bit is actually RO, but should've been cleared when we cleared GOTGINT. Still, iBoot pokes it as if it was WC, so we will too) SET_REG(USB + GINTSTS, GINTMSK_OTG); process = TRUE; } else { // we only care about OTG process = FALSE; } if((status & GINTMSK_RESET) == GINTMSK_RESET) { if(usb_state < USBError) { bufferPrintf("usb: reset detected\r\n"); change_state(USBPowered); } int retval = resetUSB(); SET_REG(USB + GINTSTS, GINTMSK_RESET); if(retval) { bufferPrintf("usb: listening for further usb events\r\n"); return; } process = TRUE; } if(((status & GINTMSK_INEP) == GINTMSK_INEP) || ((status & GINTMSK_OEP) == GINTMSK_OEP)) { // aha, got something on one of the endpoints. Now the real fun begins // first, let's get the interrupt status of individual endpoints getEndpointInterruptStatuses(); if(isSetupPhaseDone()) { // recall our earlier receiveControl calls. We now should have 8 bytes of goodness in controlRecvBuffer. USBSetupPacket* setupPacket = (USBSetupPacket*) controlRecvBuffer; uint16_t length; uint32_t totalLength; USBStringDescriptor* strDesc; if(USBSetupPacketRequestTypeType(setupPacket->bmRequestType) != USBSetupPacketVendor) { switch(setupPacket->bRequest) { case USB_GET_DESCRIPTOR: length = setupPacket->wLength; // descriptor type is high, descriptor index is low switch(setupPacket->wValue >> 8) { case USBDeviceDescriptorType: if(length > sizeof(USBDeviceDescriptor)) length = sizeof(USBDeviceDescriptor); memcpy(controlSendBuffer, usb_get_device_descriptor(), length); break; case USBConfigurationDescriptorType: // hopefully SET_ADDRESS was received beforehand to set the speed totalLength = getConfigurationTree(setupPacket->wValue & 0xFF, usb_speed, controlSendBuffer); if(length > totalLength) length = totalLength; break; case USBStringDescriptorType: strDesc = usb_get_string_descriptor(setupPacket->wValue & 0xFF); if(length > strDesc->bLength) length = strDesc->bLength; memcpy(controlSendBuffer, strDesc, length); break; case USBDeviceQualifierDescriptorType: if(length > sizeof(USBDeviceQualifierDescriptor)) length = sizeof(USBDeviceQualifierDescriptor); memcpy(controlSendBuffer, usb_get_device_qualifier_descriptor(), length); break; default: bufferPrintf("Unknown descriptor request: %d\r\n", setupPacket->wValue >> 8); if(usb_state < USBError) { change_state(USBUnknownDescriptorRequest); } } if(usb_state < USBError) { sendControl(controlSendBuffer, length); } break; case USB_SET_ADDRESS: usb_speed = DSTS_GET_SPEED(GET_REG(USB + DSTS)); usb_max_packet_size = packetsizeFromSpeed(usb_speed); SET_REG(USB + DCFG, (GET_REG(USB + DCFG) & ~DCFG_DEVICEADDRMSK) | ((setupPacket->wValue & DCFG_DEVICEADDR_UNSHIFTED_MASK) << DCFG_DEVICEADDR_SHIFT)); // send an acknowledgement sendControl(controlSendBuffer, 0); if(usb_state < USBError) { change_state(USBAddress); } break; case USB_SET_INTERFACE: // send an acknowledgement sendControl(controlSendBuffer, 0); break; case USB_GET_STATUS: // FIXME: iBoot doesn't really care about this status *((uint16_t*) controlSendBuffer) = 0; sendControl(controlSendBuffer, sizeof(uint16_t)); break; case USB_GET_CONFIGURATION: // FIXME: iBoot just puts out a debug message on console for this request. break; case USB_SET_CONFIGURATION: setConfiguration(0); // send an acknowledgment sendControl(controlSendBuffer, 0); if(usb_state < USBError) { change_state(USBConfigured); startHandler(); } break; default: if(usb_state < USBError) { change_state(USBUnknownRequest); } } // get the next SETUP packet receiveControl(controlRecvBuffer, sizeof(USBSetupPacket)); } } else { //uartPrintf("\t<begin callEndpointHandlers>\r\n"); callEndpointHandlers(); //uartPrintf("\t<end callEndpointHandlers>\r\n"); } process = TRUE; }