예제 #1
0
파일: usb.c 프로젝트: Neonkoala/openiBoot
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;
}
예제 #2
0
파일: usb.c 프로젝트: DahlJ92/openiBoot
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;
}