📄 usbd.c
字号:
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 + -