📄 usb.c
字号:
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_CLKPWR_REG *s2440PWR = (S3C2440A_CLKPWR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_CLOCK_POWER, FALSE);
volatile int loop_count = 0;
#if(__DEBUG_MSG_)
EdbgOutputDebugString("INFO : IsrUsbd : Interrupt occurred \r\n");
EdbgOutputDebugString("INFO : s2440INT->SRCPND = 0x%x \r\n", s2440INT->SRCPND);
EdbgOutputDebugString("INFO : s2440INT->INTMSK = 0x%x \r\n", s2440INT->INTMSK);
EdbgOutputDebugString("INFO : s2440INT->INTPND = 0x%x \r\n", s2440INT->INTPND);
EdbgOutputDebugString("INFO : s2440PWR->CLKCON = 0x%x \r\n", s2440PWR->CLKCON);
EdbgOutputDebugString("INFO : pUSBCtrlAddr = 0x%x \r\n", pUSBCtrlAddr);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep0_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep0_int_en);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep1_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep1_int_en);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep2_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep2_int_en);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep3_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep3_int_en);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIER.ep4_int_en = 0x%x \r\n", pUSBCtrlAddr->EIER.ep4_int_en);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIR.ep0_int = 0x%x \r\n", pUSBCtrlAddr->EIR.ep0_int);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIR.ep1_int = 0x%x \r\n", pUSBCtrlAddr->EIR.ep1_int);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIR.ep2_int = 0x%x \r\n", pUSBCtrlAddr->EIR.ep2_int);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIR.ep3_int = 0x%x \r\n", pUSBCtrlAddr->EIR.ep3_int);
EdbgOutputDebugString("INFO : pUSBCtrlAddr->EIR.ep4_int = 0x%x \r\n", pUSBCtrlAddr->EIR.ep4_int);
EdbgOutputDebugString("\r\n");
#endif
// by J.I modified(8/22) DMA2--> DMA3
if (s2440INT->INTPND & BIT_DMA3)
{
// DMA2Handler();
DMA3Handler();
goto Exit;
}
if(pUSBCtrlAddr->UIR.sus_int)
{
pUSBCtrlAddr->UIR.sus_int = 1;
// EdbgOutputDebugString("<SUS]\r\n");
}
if(pUSBCtrlAddr->UIR.resume_int)
{
pUSBCtrlAddr->UIR.resume_int = 1;
// EdbgOutputDebugString("<RSM]\r\n");
}
if(pUSBCtrlAddr->UIR.reset_int)
{
//EdbgOutputDebugString("<RSET]\r\n");
ReconfigUsbd();
pUSBCtrlAddr->UIR.reset_int = 1;
PrepareEp1Fifo();
}
if(pUSBCtrlAddr->EIR.ep0_int)
{
// EdbgOutputDebugString("EP0 Interrupt\r\n");
pUSBCtrlAddr->EIR.ep0_int=1;
Ep0Handler();
}
if(pUSBCtrlAddr->EIR.ep1_int)
{
// EdbgOutputDebugString("<1:TBD]\r\n");
pUSBCtrlAddr->EIR.ep1_int=1;
Ep1Handler();
}
if(pUSBCtrlAddr->EIR.ep2_int)
{
pUSBCtrlAddr->EIR.ep2_int=1;
// EdbgOutputDebugString("<2:TBD]\r\n");
}
if(pUSBCtrlAddr->EIR.ep3_int)
{
// EdbgOutputDebugString("<3:TBD]\r\n");
// Ep3Handler();
pUSBCtrlAddr->EIR.ep3_int=1;
}
if(pUSBCtrlAddr->EIR.ep4_int)
{
while(loop_count < DELAY_EP4INT_TO_DIDST3SET) loop_count++; // Need some Delay, sync PC and Board
// EdbgOutputDebugString("<4:TBD]\r\n");
Ep4Handler();
pUSBCtrlAddr->EIR.ep4_int=1; // Clear
}
if (s2440INT->INTPND & BIT_USBD)
{
s2440INT->SRCPND = BIT_USBD;
if (s2440INT->INTPND & BIT_USBD) s2440INT->INTPND = BIT_USBD;
}
Exit:
pUSBCtrlAddr->INDEX.index=saveIndexReg;
}
/*
void Ep3Handler(void)
{
int fifoCnt;
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
pUSBCtrlAddr->INDEX.index=3;
EdbgOutputDebugString("pUSBCtrlAddr->OCSR1.out_pkt_rdy = 0x%x\r\n", pUSBCtrlAddr->OCSR1.out_pkt_rdy);
if(pUSBCtrlAddr->OCSR1.out_pkt_rdy)
{
fifoCnt=pUSBCtrlAddr->OFCR1.out_cnt_low;
downPt = (LPBYTE)(downPtIndex);
RdPktEp3((U8 *)downPt,fifoCnt);
downPtIndex += 64;
s2440INT->INTMSK |= BIT_USBD; // USB Interrupt disable.
EdbgOutputDebugString("Ep3Handler : downPtIndex = 0x%x\r\n", downPtIndex);
return;
}
//I think that EPO_SENT_STALL will not be set to 1.
if(pUSBCtrlAddr->OCSR1.sent_stall)
{
CLR_EP3_SENT_STALL();
return;
}
}*/
/// by J.I inserted(8/22)
void Ep4Handler(void)
{
volatile int fifoCnt;
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
pUSBCtrlAddr->INDEX.index=4;
//EdbgOutputDebugString("pUSBCtrlAddr->OCSR1.out_pkt_rdy = 0x%x\r\n", pUSBCtrlAddr->OCSR1.out_pkt_rdy);
if(pUSBCtrlAddr->OCSR1.out_pkt_rdy)
{
fifoCnt=pUSBCtrlAddr->OFCR1.out_cnt_low;
downPt = (LPBYTE)(downPtIndex);
RdPktEp4((U8 *)downPt,fifoCnt);
downPtIndex += 64;
s2440INT->INTMSK |= BIT_USBD; // USB Interrupt disable.
//EdbgOutputDebugString("Ep4Handler : downPtIndex = 0x%x\r\n", downPtIndex);
return;
}
//I think that EPO_SENT_STALL will not be set to 1.
if(pUSBCtrlAddr->OCSR1.sent_stall)
{
CLR_EP4_SENT_STALL();
return;
}
}
/*
void DMA2Handler(void)
{
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
s2440INT->SRCPND = BIT_DMA2;
if (s2440INT->INTPND & BIT_DMA2) s2440INT->INTPND = BIT_DMA2;
downPtIndex += 0x80000;
v_pDMAregs->DIDST2=((U32)downPtIndex+0x80000);
v_pDMAregs->DIDSTC2=(1<<2)|(0<<1)|(0<<0);
v_pDMAregs->DCON2=v_pDMAregs->DCON2&~(0xfffff)|(0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
pUSBCtrlAddr->EP3DTL.ep3_ttl_l = 0xff;
pUSBCtrlAddr->EP3DTM.ep3_ttl_m = 0xff;
pUSBCtrlAddr->EP3DTH.ep3_ttl_h = 0x0f;
}
}*/
/// by J.I inserted(8/22)
void DMA3Handler(void)
{
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
s2440INT->SRCPND = BIT_DMA3;
if (s2440INT->INTPND & BIT_DMA3){
s2440INT->INTPND = BIT_DMA3;
}
downPtIndex += 0x80000;
// EdbgOutputDebugString("DMA3Handler : downPtIndex = 0x%x\r\n", downPtIndex);
v_pDMAregs->DIDST3=((U32)(VA2PA(downPtIndex))+0x80000);
v_pDMAregs->DIDSTC3=(1<<2)|(0<<1)|(0<<0);
v_pDMAregs->DCON3=v_pDMAregs->DCON3&~(0xfffff)|(0x80000);
while(rEP4_DMA_TTC<0xfffff)
{
// EdbgOutputDebugString("DMA3H loopin : rEP4_DMA_TTC(%x)\r\n", rEP4_DMA_TTC);
pUSBCtrlAddr->EP4DTL.ep4_ttl_l = 0xff;
pUSBCtrlAddr->EP4DTM.ep4_ttl_m = 0xff;
pUSBCtrlAddr->EP4DTH.ep4_ttl_h = 0x0f;
}
// EdbgOutputDebugString("DMA3H loopout : rEP4_DMA_TTC(%x)\r\n", rEP4_DMA_TTC);
}
/*
void ConfigEp3DmaMode(U32 bufAddr,U32 count)
{
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
int i;
pUSBCtrlAddr->INDEX.index=3;
count=count&0xfffff; //transfer size should be <1MB
v_pDMAregs->DISRCC2=(1<<1)|(1<<0);
v_pDMAregs->DISRC2=REAL_PHYSICAL_ADDR_EP3_FIFO; //src=APB,fixed,src=EP3_FIFO
v_pDMAregs->DIDSTC2=(0<<2)|(0<<1)|(0<<0);
v_pDMAregs->DIDST2=bufAddr; //dst=AHB,increase,dst=bufAddr
v_pDMAregs->DCON2=(count)|(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(4<<24)|(1<<23)|(0<<22)|(0<<20);
//handshake,requestor=APB,CURR_TC int enable,unit transfer,
//single service,src=USBD,H/W request,autoreload,byte,CURR_TC
v_pDMAregs->DMASKTRIG2 = (1<<1);
//DMA 2 on
pUSBCtrlAddr->EP3DTL.ep3_ttl_l = 0xff;
pUSBCtrlAddr->EP3DTM.ep3_ttl_m = 0xff;
pUSBCtrlAddr->EP3DTH.ep3_ttl_h = 0x0f;
pUSBCtrlAddr->OCSR2.auto_clr = 1;
pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;
//AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.
pUSBCtrlAddr->EP3DU.ep3_unit_cnt = 1;
*(volatile BYTE *)&pUSBCtrlAddr->EP3DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
// deamnd disable,out_dma_run=run,in_dma_run=stop,DMA mode enable
//wait until DMA_CON is effective.
*(volatile BYTE *)&pUSBCtrlAddr->EP3DC;
for(i=0;i<10;i++);
}*/
/// by J.I inserted(8/22)
void ConfigEp4DmaMode(U32 bufAddr,U32 count)
{
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
int i;
pUSBCtrlAddr->INDEX.index=4;
count=count&0xfffff; //transfer size should be <1MB
v_pDMAregs->DISRCC3=(1<<1)|(1<<0);
v_pDMAregs->DISRC3=REAL_PHYSICAL_ADDR_EP4_FIFO; //src=APB,fixed,src=EP4_FIFO
v_pDMAregs->DIDSTC3=(0<<2)|(0<<1)|(0<<0);
v_pDMAregs->DIDST3=bufAddr; //dst=AHB,increase,dst=bufAddr
v_pDMAregs->DCON3=(count)|(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(4<<24)|(1<<23)|(0<<22)|(0<<20);
//handshake,requestor=APB,CURR_TC int enable,unit transfer,
//single service,src=USBD,H/W request,autoreload,byte,CURR_TC
v_pDMAregs->DMASKTRIG3 = (1<<1);
//DMA 3 on
pUSBCtrlAddr->EP4DTL.ep4_ttl_l = 0xff;
pUSBCtrlAddr->EP4DTM.ep4_ttl_m = 0xff;
pUSBCtrlAddr->EP4DTH.ep4_ttl_h = 0x0f;
pUSBCtrlAddr->OCSR2.auto_clr = 1;
pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;
//AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.
pUSBCtrlAddr->EP4DU.ep4_unit_cnt = 1;
*(volatile BYTE *)&pUSBCtrlAddr->EP4DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
// deamnd disable,out_dma_run=run,in_dma_run=stop,DMA mode enable
//wait until DMA_CON is effective.
*(volatile BYTE *)&pUSBCtrlAddr->EP4DC;
for(i=0;i<10;i++);
}
/*
void ConfigEp3IntMode(void)
{
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
pUSBCtrlAddr->INDEX.index=3;
v_pDMAregs->DMASKTRIG2= (0<<1); // EP3=DMA ch 2
//DMA channel off
pUSBCtrlAddr->OCSR2.auto_clr = 0;
//AUTOCLEAR off,interrupt_enabled (???)
pUSBCtrlAddr->EP3DU.ep3_unit_cnt = 1;
*(volatile BYTE *)&pUSBCtrlAddr->EP3DC=0x0;
//wait until DMA_CON is effective.
*(volatile BYTE *)&pUSBCtrlAddr->EP3DC;
}
/// by J.I inserted(8/22)
void ConfigEp4IntMode(void)
{
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
pUSBCtrlAddr->INDEX.index=4;
v_pDMAregs->DMASKTRIG3= (0<<1); // EP4=DMA ch 3
//DMA channel off
pUSBCtrlAddr->OCSR2.auto_clr = 0;
//AUTOCLEAR off,interrupt_enabled (???)
pUSBCtrlAddr->EP4DU.ep4_unit_cnt = 1;
*(volatile BYTE *)&pUSBCtrlAddr->EP4DC=0x0;
//wait until DMA_CON is effective.
*(volatile BYTE *)&pUSBCtrlAddr->EP4DC;
}
*/
#pragma optimize ("",off)
BOOL UbootReadData(DWORD cbData, LPBYTE pbData)
{
volatile S3C2440A_INTR_REG *s2440INT = (S3C2440A_INTR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_INTR, FALSE);
volatile S3C2440A_IOPORT_REG *s2440IOP = (S3C2440A_IOPORT_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);
volatile S3C2440A_DMA_REG *v_pDMAregs = (S3C2440A_DMA_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_DMA, FALSE);
volatile S3C2440A_CLKPWR_REG *s2440PWR = (S3C2440A_CLKPWR_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_CLOCK_POWER, FALSE);
static int count = 0;
// unsigned int temp;
// int i;
Loop:
#if(__DEBUG_MSG_)
EdbgOutputDebugString("INFO : UbootReadData : s2440PWR->CLKCON = 0x%x\r\n", s2440PWR->CLKCON);
EdbgOutputDebugString("INFO : UbootReadData : s2440INT->INTMSK = 0x%x\r\n", s2440INT->INTMSK);
EdbgOutputDebugString("INFO : UbootReadData : v_pDMAregs->DCDST3 = 0x%x\r\n", v_pDMAregs->DCDST3);
EdbgOutputDebugString("INFO : UbootReadData : downPtIndex = 0x%x\r\n", downPtIndex);
EdbgOutputDebugString("INFO : UbootReadData : readPtIndex + cbData = 0x%x\r\n", readPtIndex + cbData);
#endif
/// by J.I modified(8/22) DMA2 --> DMA3
if ( v_pDMAregs->DCDST3 >= (VA2PA(readPtIndex) + cbData) )
// if ( downPtIndex > readPtIndex + cbData )
{
memcpy((void *)pbData, (void *)readPtIndex, cbData);
readPtIndex += cbData;
loopcnt = 0;
}
else if (loopcnt > 50) // it may be
{
memcpy((void *)pbData, (void *)readPtIndex, cbData);
readPtIndex += cbData;
}
else if (downPtIndex == DMABUFFER_VA)
{
while (downPtIndex == DMABUFFER_VA) {
#if(__DEBUG_MSG_)
// EdbgOutputDebugString("UbootReadData : downPtIndex = 0x%x\r\n", downPtIndex);
#endif
}; // first 64 bytes, get interrupt mode.
#if(__DEBUG_MSG_)
EdbgOutputDebugString("UbootReadData : downPtIndex = 0x%x\r\n", downPtIndex);
#endif
if ( readPtIndex == DMABUFFER_VA )
{
memcpy((void *)pbData, (void *)readPtIndex, cbData);
readPtIndex += cbData;
}
s2440INT->SRCPND = BIT_USBD;
if (s2440INT->INTPND & BIT_USBD) s2440INT->INTPND = BIT_USBD;
s2440INT->INTMSK |= BIT_USBD; // USB Interrupt disable.
/// by J.I modified(8/22) DMA2 --> DMA3
// read data with DMA operation.
s2440INT->SRCPND = BIT_DMA3;
if (s2440INT->INTPND & BIT_DMA3) s2440INT->INTPND = BIT_DMA3;
s2440INT->INTMSK &= ~BIT_DMA3; // DMA Interrupt enable.
/// by J.I modified(8/22) EP3 -> EP4
pUSBCtrlAddr->INDEX.index=4;
CLR_EP4_OUT_PKT_READY();
ConfigEp4DmaMode(VA2PA(downPtIndex),0x80000);
/// by J.I modified(8/22) DMA2 --> DMA3
v_pDMAregs->DIDST3=(VA2PA(downPtIndex)+0x80000); //for 1st autoreload.
v_pDMAregs->DIDSTC3=(1<<2)|(0<<1)|(0<<0);
v_pDMAregs->DCON3=v_pDMAregs->DCON3&~(0xfffff)|(0x80000);
#if(__DEBUG_MSG_)
EdbgOutputDebugString("UbootReadData : +while \r\n");
EdbgOutputDebugString("UbootReadData : &(pUSBCtrlAddr->EP4DTL) = 0x%x \r\n", &(pUSBCtrlAddr->EP4DTL));
#endif
/// by J.I modified(8/22) EP3 -> EP4
while(rEP4_DMA_TTC<0xfffff)
{
#if(__DEBUG_MSG_)
EdbgOutputDebugString("UbootReadData : rEP4_DMA_TTC = 0x%x \r\n", rEP4_DMA_TTC);
EdbgOutputDebugString("INFO : UbootReadData : s2440PWR->CLKCON = 0x%x\r\n", s2440PWR->CLKCON);
EdbgOutputDebugString("INFO : UbootReadData : v_pDMAregs->DCDST3 = 0x%x\r\n", v_pDMAregs->DCDST3);
#endif
pUSBCtrlAddr->EP4DTL.ep4_ttl_l = 0xff;
pUSBCtrlAddr->EP4DTM.ep4_ttl_m = 0xff;
pUSBCtrlAddr->EP4DTH.ep4_ttl_h = 0x0f;
}
// EdbgOutputDebugString("UbootReadData : -while \r\n");
}
else
{
// for (i = 0; i < 60000; i++ )
// {
// }
// loopcnt ++;
// EdbgOutputDebugString("INFO : UbootReadData : loopcnt = 0x%x\r\n", loopcnt);
goto Loop;
}
return TRUE;
}
void USBDisconnect(void)
{
volatile S3C2440A_IOPORT_REG *s2440IOP = (S3C2440A_IOPORT_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);
// GPG12 Low Signal
s2440IOP->GPGCON = (s2440IOP->GPGCON & ~(3<<24)) | (1 << 24);
s2440IOP->GPGUP |= (1<<12);
s2440IOP->GPGDAT &= ~(1<<12);
}
void USBReconnect(void)
{
volatile S3C2440A_IOPORT_REG *s2440IOP = (S3C2440A_IOPORT_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);
// GPG12 Low Signal
s2440IOP->GPGCON = (s2440IOP->GPGCON & ~(3<<24)) | (1 << 24);
s2440IOP->GPGUP |= (1<<12);
s2440IOP->GPGDAT |= (1<<12);
}
#pragma optimize ("",on)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -