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; }
int usb_setup(USBEnumerateHandler hEnumerate, USBStartHandler hStart) { usb_shutdown(); // This is not relevant to the hardware, // and usb_setup is called when setting up a new // USB protocol. So we should reset the EP // handlers here! -- Ricky26 memset(endpoint_handlers, 0, sizeof(endpoint_handlers)); startHandler = hStart; enumerateHandler = hEnumerate; setupHandler = NULL; if(usb_inited) return 0; if(controlSendBuffer == NULL) controlSendBuffer = memalign(DMA_ALIGN, CONTROL_SEND_BUFFER_LEN); if(controlRecvBuffer == NULL) controlRecvBuffer = memalign(DMA_ALIGN, CONTROL_RECV_BUFFER_LEN); InEPRegs = (USBEPRegisters*)(USB + USB_INREGS); OutEPRegs = (USBEPRegisters*)(USB + USB_OUTREGS); change_state(USBStart); initializeDescriptors(); // Initialize our data structures memset(usb_message_queue, 0, sizeof(usb_message_queue)); #ifdef USB_PHY_1G // Power on hardware power_ctrl(POWER_USB, ON); udelay(USB_START_DELAYUS); #else // Wait for USB hardware to come alive udelay(10000); #endif // Set up the hardware clock_gate_switch(USB_OTGCLOCKGATE, ON); clock_gate_switch(USB_PHYCLOCKGATE, ON); #ifdef USB_PHY_1G clock_gate_switch(EDRAM_CLOCKGATE, ON); #endif // power on OTG SET_REG(USB + PCGCCTL, (GET_REG(USB + PCGCCTL) & (~PCGCCTL_ONOFF_MASK)) | PCGCCTL_ON); udelay(USB_ONOFFSTART_DELAYUS); // Generate a soft disconnect on host //SET_REG(USB + DCTL, GET_REG(USB + DCTL) | DCTL_SFTDISCONNECT); //udelay(USB_SFTDISCONNECT_DELAYUS); // Initialise PHY usb_phy_init(); bufferPrintf("USB: Hardware Configuration\n" " HWCFG1 = 0x%08x\n" " HWCFG2 = 0x%08x\n" " HWCFG3 = 0x%08x\n" " HWCFG4 = 0x%08x\n", GET_REG(USB+GHWCFG1), GET_REG(USB+GHWCFG2), GET_REG(USB+GHWCFG3), GET_REG(USB+GHWCFG4)); usb_inited = TRUE; interrupt_install(USB_INTERRUPT, usbIRQHandler, 0); // Start USB usb_start(); return 0; }