⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd.c

📁 W90P910的BOOTLOADER,难找呀,我想应该是第一份吧.
💻 C
📖 第 1 页 / 共 3 页
字号:

	IrqStL = inpw(REG_USBD_IRQ_STAT_L);		/* get interrupt status */
	IrqEnL = inpw(REG_USBD_IRQ_ENB_L);

	if (!(IrqStL & IrqEnL))
	{
		MSG_DEBUG("Not our interrupt!\n");
		return;
	}

	/* USB interrupt */
	if (IrqStL & IRQ_USB_STAT)
	{
		IrqSt = inpw(REG_USBD_IRQ_STAT);
		IrqEn = inpw(REG_USBD_IRQ_ENB);

//MSG_DEBUG("INT status[%x], oper[%x]\n", IrqSt, inpw(REG_USBD_OPER));

		if (IrqSt & USB_SOF & IrqEn)
		{
			MSG_DEBUG("SOF Interrupt\n");
			outpw(REG_USBD_IRQ_STAT, 0x01);
		}

		if (IrqSt & USB_RST_STS & IrqEn)
		{
			//MSG_DEBUG("Reset Status Interrupt\n");
			_usbd_devstate = 0;
			_usbd_speedset = 0;
			_usbd_address = 0;

			// clear flags
			usbdClearAllFlags();
			USBModeFlag=0;
			_usbd_DMA_Flag=0;
			_usbd_Less_MPS=0;
			Bulk_First_Flag=0;

			// reset DMA
			outpw(REG_USBD_DMA_CTRL_STS, 0x80);
			outpw(REG_USBD_DMA_CTRL_STS, 0x00);
			outpw(REG_USBD_EPA_RSP_SC, inpw(REG_USBD_EPA_RSP_SC)|0x01);		// flush fifo
			outpw(REG_USBD_EPB_RSP_SC, inpw(REG_USBD_EPB_RSP_SC)|0x01);		// flush fifo

			_usbd_devstate = 1;		//default state
			_usbd_address = 0;		//zero

			if (inpw(REG_USBD_OPER) & 0x04)
			{
				MSG_DEBUG("High speed after reset\n");
				_usbd_speedset = 2;		//for high speed
				usbdHighSpeedInit();
				//outpw(REG_USBD_OPER, (inpw(REG_USBD_OPER)&0xfffffffd) | 0x02);
				Compare_Length = 512;
			}
			else
			{
				MSG_DEBUG("Full speed after reset\n");
				_usbd_speedset = 1;		//for full speed
				//outpw(REG_USBD_OPER, inpw(REG_USBD_OPER)&0xfffffffd);
				usbdFullSpeedInit();
				Compare_Length = 64;
			}
			outpw(REG_USBD_CEP_IRQ_ENB, 0x002);		//suppkt int

			outpw(REG_USBD_ADDR, 0);
			outpw(REG_USBD_IRQ_ENB, (USB_RST_STS|USB_SUS_REQ));
			outpw(REG_USBD_IRQ_STAT, 0x02);
		}

		if (IrqSt & USB_RESUME & IrqEn)
		{
//			uprintf("Resume Interrupt\n");
			_usbd_resume = 1;
			outpw(REG_USBD_IRQ_ENB, (USB_RST_STS|USB_SUS_REQ));
			outpw(REG_USBD_IRQ_STAT, 0x04);
		}

		if (IrqSt & USB_SUS_REQ & IrqEn)
		{
//			uprintf("Suspend Request Interrupt\n");
			_usbd_resume = 0;
			outpw(REG_USBD_IRQ_ENB, (USB_RST_STS | USB_RESUME));
			outpw(REG_USBD_IRQ_STAT, 0x08);
		}

		if (IrqSt & USB_HS_SETTLE & IrqEn)
		{
			MSG_DEBUG("Device settled in High speed\n");
			_usbd_devstate = 1;		//default state
			_usbd_speedset = 2;		//for high speed
			_usbd_address = 0;		//zero
			outpw(REG_USBD_CEP_IRQ_ENB, 0x002);
			outpw(REG_USBD_IRQ_STAT, 0x10);
		}
		
		if (IrqSt & USB_DMA_REQ & IrqEn)
		{
			_usbd_DMA_Flag = 1;
			outpw(REG_USBD_IRQ_STAT, USB_DMA_REQ);
//sysprintf("C\n");

			if (_usbd_DMA_Dir == Ep_Out)
			{
				MSG_DEBUG("OUT DMA [%d]\n", _usbd_Less_MPS);
				outpw(REG_USBD_EPB_IRQ_ENB, 0x10);
			}
			if (_usbd_DMA_Dir == Ep_In)
			{
				MSG_DEBUG("IN DMA [%d]\n", _usbd_Less_MPS);
				if (_usbd_Less_MPS == 1)
				{
					outpw(REG_USBD_EPA_RSP_SC, (inpw(REG_USBD_EPA_RSP_SC)&0xf7)|0x00000040);	// packet end
					_usbd_Less_MPS = 0;
				}
			}
		}

		if (IrqSt & USABLE_CLK & IrqEn)
			MSG_DEBUG("Usable Clock Interrupt\n");

		outpw(REG_USBD_IRQ_STAT_L, IRQ_USB_STAT);	
	}

	if (IrqStL & IRQ_CEP) 
	{
		IrqSt = inpw(REG_USBD_CEP_IRQ_STAT);
		IrqEn = inpw(REG_USBD_CEP_IRQ_ENB);

//MSG_DEBUG("control INT status[%x]\n", IrqSt);

		if (IrqSt & CEP_SUPTOK & IrqEn)
		{
			//uprintf("Setup Token\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x001);
			return;
		}

		if (IrqSt & CEP_SUPPKT & IrqEn)
		{
//			uprintf("Setup\n");
			usbd_control_packet();
			outpw(REG_USBD_CEP_IRQ_STAT, 0x002);
			return;
		}

		if (IrqSt & CEP_OUT_TOK & IrqEn)
		{
//			uprintf("Out\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x004);
			outpw(REG_USBD_CEP_IRQ_STAT, 0x400);
			outpw(REG_USBD_CEP_IRQ_ENB, 0x402);		// suppkt int//enb sts completion int
			return;
		}

		if (IrqSt & CEP_IN_TOK & IrqEn)
		{
//			uprintf("In[%x]\n", IrqSt);
			if (!(IrqSt & CEP_STS_END))
			{
				outpw(REG_USBD_CEP_IRQ_STAT, 0x420);
				outpw(REG_USBD_CEP_IRQ_ENB, 0x420);
				usbd_send_descriptor();
			}
			else
			{
				outpw(REG_USBD_CEP_IRQ_STAT, 0x020);
				outpw(REG_USBD_CEP_IRQ_ENB, 0x420);
			}
			outpw(REG_USBD_CEP_IRQ_STAT, 0x008);
			return;
		}

		if (IrqSt & CEP_PING_TOK & IrqEn)
		{
			MSG_DEBUG("Ping\n");
			outpw(REG_USBD_CEP_IRQ_ENB, 0x402);		// suppkt int//enb sts completion int
			outpw(REG_USBD_CEP_IRQ_STAT, 0x010);
			return;
		}

		if (IrqSt & CEP_DATA_TXD & IrqEn)
		{
			//MSG_DEBUG("Txd\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x020);
			outpw(REG_USBD_CEP_CTRL_STAT, CEP_NAK_CLEAR);	// clear nak so that sts stage is complete
			outpw(REG_USBD_CEP_IRQ_STAT, 0x400);
			outpw(REG_USBD_CEP_IRQ_ENB, 0x402);		// suppkt int//enb sts completion int
			return;
		}

		if (IrqSt & CEP_DATA_RXD & IrqEn)
		{
			//MSG_DEBUG("Rxd\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x040);
			outpw(REG_USBD_CEP_CTRL_STAT, CEP_NAK_CLEAR);	// clear nak so that sts stage is complete
			outpw(REG_USBD_CEP_IRQ_ENB, 0x43e);		// suppkt int//enb sts completion int
			return;
		}

		if (IrqSt & CEP_NAK_SENT & IrqEn)
		{
			MSG_DEBUG("NAK Sent Interrupt\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x080);
			return;
		}

		if (IrqSt & CEP_STALL_SENT & IrqEn)
		{
//			uprintf("STALL Sent Interrupt\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x100);
			return;
		}

		if (IrqSt & CEP_USB_ERR & IrqEn)
		{
//			uprintf("USB Error Interrupt\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x200);
			return;
		}

		if (IrqSt & CEP_STS_END & IrqEn)
		{
			//MSG_DEBUG("Status\n");
			outpw(REG_USBD_CEP_IRQ_ENB, 0x002);
			usbd_update_device();
			outpw(REG_USBD_CEP_IRQ_STAT, 0x400);
			if (CLASS_CMD_Flag || _usbd_resume || GET_DEV_Flag)
				USBModeFlag = 1;
			//MSG_DEBUG("Status [%x]\n", inpw(REG_USBD_CEP_IRQ_STAT));
			return;
		}

		if (IrqSt & CEP_BUFF_FULL & IrqEn)
		{
			MSG_DEBUG("Buffer Full Interrupt\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x800);
			return;
		}

		if (IrqSt & CEP_BUFF_EMPTY & IrqEn)
		{
			MSG_DEBUG("Buffer Empty Interrupt\n");
			outpw(REG_USBD_CEP_IRQ_STAT, 0x1000);
			return;
		}
		outpw(REG_USBD_IRQ_STAT_L, IRQ_CEP);
	}

	if (IrqStL & IRQ_NCEP) 
	{
		if (IrqStL & 0x04)
		{
			IrqSt = inpw(REG_USBD_EPA_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPA_IRQ_ENB);
			//MSG_DEBUG(" Interrupt from Endpoint A m[%x], s[%x]\n", IrqEn, IrqSt);
			
			outpw(REG_USBD_EPA_IRQ_STAT, 0x40);	//data pkt transmited
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPA_IRQ_STAT, IrqSt);
		}
		
		if (IrqStL & 0x08)
		{
			IrqSt = inpw(REG_USBD_EPB_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPB_IRQ_ENB);
			//MSG_DEBUG(" Interrupt from Endpoint B m[%x], s[%x]\n", IrqEn, IrqSt);

			outpw(REG_USBD_EPB_IRQ_ENB, 0x0);
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPB_IRQ_STAT, IrqSt);
		}

		if (IrqStL & 0x10)
		{
			MSG_DEBUG(" Interrupt from Endpoint C \n");
			IrqSt = inpw(REG_USBD_EPC_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPC_IRQ_ENB);
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPC_IRQ_STAT, IrqSt);
		}

		if (IrqStL & 0x20)
		{
			MSG_DEBUG(" Interrupt from Endpoint D \n");
			IrqSt = inpw(REG_USBD_EPD_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPD_IRQ_ENB);
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPD_IRQ_STAT, IrqSt);
		}

		if (IrqStL & 0x40)
		{
			MSG_DEBUG(" Interrupt from Endpoint E \n");
			IrqSt = inpw(REG_USBD_EPE_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPE_IRQ_ENB);
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPE_IRQ_STAT, IrqSt);
		}

		if (IrqStL & 0x80)
		{
			MSG_DEBUG(" Interrupt from Endpoint F \n");
			IrqSt = inpw(REG_USBD_EPF_IRQ_STAT);
			IrqEn = inpw(REG_USBD_EPF_IRQ_ENB);
			usbd_EP_ISR(IrqSt & IrqEn);
			outpw(REG_USBD_EPF_IRQ_STAT, IrqSt);
		}
		outpw(REG_USBD_IRQ_STAT_L, IRQ_NCEP);
	}
}

void SDRAM_USB_Transfer(UINT8 epname,UINT32 DRAM_Addr ,UINT32 Tran_Size)
{
	if(Tran_Size != 0)
	{
		outpw(REG_USBD_IRQ_ENB, (USB_DMA_REQ | USB_RST_STS | USB_SUS_REQ));
		outpw(REG_USBD_AHB_DMA_ADDR, DRAM_Addr);
		outpw(REG_USBD_DMA_CNT, Tran_Size);
		_usbd_DMA_Flag=0;
		outpw(REG_USBD_DMA_CTRL_STS, inpw(REG_USBD_DMA_CTRL_STS)|0x00000020);
		while(_usbd_DMA_Flag==0);//waiting for DMA complete
	}
}


void usbdHighSpeedInit()
{
	MSG_DEBUG("Device is configured for High Speed\n");
	usbdMaxPacketSize = 0x200;
	/* bulk in */
	outpw(REG_USBD_EPA_IRQ_ENB, 0x00000008);	// data pkt transmited and in token intr enb
	outpw(REG_USBD_EPA_RSP_SC, 0x00000000);		// auto validation
	outpw(REG_USBD_EPA_MPS, 0x00000200);		// mps 512
	outpw(REG_USBD_EPA_CFG, 0x0000001b);		// bulk in ep no 1
	outpw(REG_USBD_EPA_START_ADDR, 0x00000100);
	outpw(REG_USBD_EPA_END_ADDR, 0x000002ff);

	/* bulk out */
	outpw(REG_USBD_EPB_IRQ_ENB, 0x00000010);	// data pkt received  and outtokenb
	outpw(REG_USBD_EPB_RSP_SC, 0x00000000);		// auto validation
	outpw(REG_USBD_EPB_MPS, 0x00000200);		// mps 512
	outpw(REG_USBD_EPB_CFG, 0x00000023);		// bulk out ep no 2
	outpw(REG_USBD_EPB_START_ADDR, 0x00000300);
	outpw(REG_USBD_EPB_END_ADDR, 0x000004ff);
}

void usbdFullSpeedInit()
{
	MSG_DEBUG("Device is configured for Full Speed\n");
	usbdMaxPacketSize = 0x40;
	/* bulk in */
	outpw(REG_USBD_EPA_IRQ_ENB, 0x00000008);	// data pkt transmited and in token intr enb
	outpw(REG_USBD_EPA_RSP_SC, 0x00000000);		// auto validation
	outpw(REG_USBD_EPA_MPS, 0x00000040);		// mps 64
	outpw(REG_USBD_EPA_CFG, 0x0000001b);		// bulk in ep no 1
	outpw(REG_USBD_EPA_START_ADDR, 0x00000100);
	outpw(REG_USBD_EPA_END_ADDR, 0x000002ff);

	/* bulk out */
	outpw(REG_USBD_EPB_IRQ_ENB, 0x00000010);	// data pkt received  and outtokenb
	outpw(REG_USBD_EPB_RSP_SC, 0x00000000);		// auto validation
	outpw(REG_USBD_EPB_MPS, 0x00000040);		// mps 64
	outpw(REG_USBD_EPB_CFG, 0x00000023);		// bulk out ep no 2
	outpw(REG_USBD_EPB_START_ADDR, 0x00000300);
	outpw(REG_USBD_EPB_END_ADDR, 0x000004ff);
}

void USB_Initialize()
{
	/* initial state */
	_usbd_devstate = 0;		//initial state
	_usbd_address  = 0;		//not set 
	_usbd_confsel  = 0;		//not selected
	_usbd_speedset = 2;		// default at high speed mode

	/* 
	 * configure mass storage interface endpoint 
	 */
	/* Device is in High Speed */
	if (_usbd_speedset == 2)
	{
		usbdHighSpeedInit();
	}
	/* Device is in Full Speed */
	else if (_usbd_speedset == 1)
	{
		usbdFullSpeedInit();
	}

	/*
	 * configure USB controller 
	 */
	outpw(REG_USBD_IRQ_ENB_L, 0x0f);	/* enable usb, cep, epa, epb interrupt */
	outpw(REG_USBD_IRQ_ENB, (USB_DMA_REQ | USB_RESUME | USB_RST_STS));
	outpw(REG_USBD_OPER, USB_HS);
	outpw(REG_USBD_ADDR, 0);

	/* allocate 0xff bytes mem for cep */
	outpw(REG_USBD_CEP_START_ADDR, 0);
	outpw(REG_USBD_CEP_END_ADDR, 0x07f);
	outpw(REG_USBD_CEP_IRQ_ENB, (CEP_SUPPKT | CEP_STS_END));

}


static void USBSetInterrupt(volatile UINT32 vector, void (*handler)())
{
	IRQ_HandlerTable[vector] = handler;
}
#if 0
__irq void USBIRQ_IntHandler(void)
{

	volatile UINT32 irq;

	irq=inpw(REG_AIC_ISR);
	if( irq & (0x1<<IRQ_USBD) )
		(*IRQ_HandlerTable[IRQ_USBD])();
	
}
#endif
void USB_Int_Init(void)
{
#if 0	
	{
		INT tmp;
		*((volatile UINT32 *)0x38)=(UINT32)USBIRQ_IntHandler;
		__asm
		{
			MRS	tmp, CPSR
			BIC	tmp, tmp, 0x80
			MSR	CPSR_c, tmp
		}
		
	}
#endif
    USBSetInterrupt(IRQ_USBD, usb_isr) ;
     outpw(REG_AIC_SCR21, (inpw(REG_AIC_SCR21) & 0xFFFFFFF8 | IRQ_LEVEL_1));

     /* enable USB interrupt */
    Enable_Int(IRQ_USBD);

}

int usb_recv(UINT8* buf,UINT32 len)
{
	_usbd_DMA_Dir = Ep_Out;
	
	outpw(REG_USBD_DMA_CTRL_STS, (inpw(REG_USBD_DMA_CTRL_STS)&0xe0) | 0x02);	// bulk out, dma write, ep2
	SDRAM_USB_Transfer(EP_B,(UINT32)buf,len);
	
	outpw(REG_USBD_CEP_IRQ_ENB, (CEP_SUPPKT | CEP_STS_END));//lsshi
	
	Bulk_Out_Transfer_Size = 0;
	
	return len;
}

int usb_send(UINT8* buf,UINT32 len)
{
	
	_usbd_DMA_Dir = Ep_In;
	outpw(REG_USBD_DMA_CTRL_STS, (inpw(REG_USBD_DMA_CTRL_STS)&0xe0) | 0x11);	// bulk in, dma read, ep1
	outpw(REG_USBD_EPA_IRQ_ENB, 0x08);
	while(!(inpw(REG_USBD_EPA_IRQ_STAT) & 0x02));  
	_usbd_Less_MPS=1; 	
   SDRAM_USB_Transfer(EP_A,(UINT32)buf,len);
  
	return len;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -