📄 usb.c
字号:
}
#define USB_DOWN_DEV 0x200
#define USB_DOWN_ATTR ((USB_DOWN_DEV<<16)|SRC_LOC_APB|SRC_ADDR_FIXED|DST_LOC_AHB|DST_ADDR_INC|REQ_USB_EP3)
#if USBDMA_DEMAND
#define USB_DOWN_MODE (DEMAND_MODE|SYNC_APB|DONE_GEN_INT|TSZ_UNIT|SINGLE_SVC|HW_TRIG|RELOAD_OFF|DSZ_8b)
#else
#define USB_DOWN_MODE (HANDSHAKE_MODE|SYNC_APB|DONE_GEN_INT|TSZ_UNIT|SINGLE_SVC|HW_TRIG|RELOAD_OFF|DSZ_8b)
#endif
u_short SetDMARun(u_int attr, u_int src_addr, u_int dst_addr, u_int len)
{
u_short DevID, ReqSrc, ch;
DevID = attr>>16;
ReqSrc = attr&0xf;
ch = (attr&0xf0)>>4;
#ifdef DMA_CHECK_ATTR
if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
return 1;
if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
return 1;
#endif
DMAChannel[ch].pDMA->DISRC = src_addr;
DMAChannel[ch].pDMA->DIDST = dst_addr;
DMAChannel[ch].pDMA->DCON &= ~0xfffff;
DMAChannel[ch].pDMA->DCON |= len&0xfffff;
if(attr&DMA_START)
{
if(DMAChannel[ch].used==DMA_IS_HWTRIG)
DMAChannel[ch].pDMA->DMASKTRIG = 2; //channel on
if(DMAChannel[ch].used==DMA_IS_SWTRIG)
DMAChannel[ch].pDMA->DMASKTRIG = 3; //sw_trig
}
return 0;
}
u_int RequestDMA(u_int attr, u_int mode)
{
u_short DevID, ReqSrc, ch;
u_int ret=REQUEST_DMA_FAIL;
DevID = attr>>16;
ReqSrc = attr&0xff;
if(((ReqSrc>>4)>=MAX_DMA_CHANNEL)||((ReqSrc&0xf)>4))
return ret;
// EnterCritical(&r);
if(DMAChannel[ReqSrc>>4].used!=DMA_IS_FREE)
{
u_char src = ReqSrc;
if(src==REQ_IISDI)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x21;
}
else if(src==REQ_SDI)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x31;
}
else
ReqSrc = 0x22;
}
else if(src==REQ_SPI)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x32;
}
else if(src==REQ_TIMER)
{
if(DMAChannel[2].used!=DMA_IS_FREE)
{
if(DMAChannel[3].used!=DMA_IS_FREE)
goto RequestDmaExit;
else
ReqSrc = 0x33;
}
else
ReqSrc = 0x23;
}
else
goto RequestDmaExit;
}
ch = ReqSrc>>4;
if(mode&HW_TRIG)
DMAChannel[ch].used = DMA_IS_HWTRIG;
else
DMAChannel[ch].used = DMA_IS_SWTRIG;
DMAChannel[ch].DevID = DevID;
DMAChannel[ch].pDMA = (DMA *)(0x4b000000+(ch)*0x40);
DMAChannel[ch].pDMA->DMASKTRIG = 1<<2; //stop dma
DMAChannel[ch].pDMA->DISRCC = (attr>>8)&3;
DMAChannel[ch].pDMA->DIDSTC = (attr>>12)&3;
mode &= ~0x07000000;
mode |= (ReqSrc&0x7)<<24;
DMAChannel[ch].pDMA->DCON = mode;
ret = (DevID<<16)|ReqSrc;
RequestDmaExit:
//ExitCritical(&r);
return ret;
}
void ConfigEp3DmaMode(u_int bufAddr,u_int count)
{
count=count&0xfffff; //transfer size should be <1MB
UsbDevReq = RequestDMA(USB_DOWN_ATTR, USB_DOWN_MODE);
if(UsbDevReq==REQUEST_DMA_FAIL)
{
printf("Request DMA fail!\n");
return;
}
SetDMARun(UsbDevReq|DMA_START, ADDR_EP3_FIFO, bufAddr, count);
rINDEX_REG=3;
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0x0f;
rOUT_CSR2_REG=rOUT_CSR2_REG|EPO_AUTO_CLR|EPO_OUT_DMA_INT_MASK;
#if USBDMA_DEMAND
rEP3_DMA_UNIT=EP3_PKT_SIZE; //DMA transfer unit=64 bytes
rEP3_DMA_CON=UDMA_DEMAND_MODE|UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
#else
rEP3_DMA_UNIT=0x01; //DMA transfer unit=1byte
rEP3_DMA_CON=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
#endif
//wait until DMA_CON is effective.
{
register i = rEP3_DMA_CON;
for(i=0;i<10;i++);
}
}
int USBDownload()
{
u_char tempMem[16];
u_short dnCS,cs;
u_int i,j,temp;
checkSum = 0;
downPt = tempMem; //This address is used for receiving first 8 byte.
download_addr =0; //_RAM_STARTADDRESS;
download_len = 0;
printf("Wait for USB connection\n\r");
while(!isUSBSet);
printf("USB Connected\n\r");
while(download_len==0);
#if USBDMA
ClearEp3OutPktReady(); //clear first out packet
if(download_len>EP3_PKT_SIZE)
{
if(download_len<=(0x80000))
ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,download_len-EP3_PKT_SIZE);
else
ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
totalDmaCount=0;
}
else // download_len < EP3_PKT_SIZE
totalDmaCount=download_len;
#endif
printf("Now, Downloading [ADDRESS:%xh,TOTAL:%d]\n\r",download_addr, download_len);
j=0x80000;
#if USBDMA
while(1)
{
if((rDCDST2-(u_int)download_addr+8)>=j)
{
j+=0x80000;
printf("\b\b\b\b\b\b\b\b%8d",totalDmaCount);
}
//printf("\b\b\b\b\b\b\b\b%8d",totalDmaCount);
if (totalDmaCount>=download_len) break;
}
//printf("DMA Count:%d\n\r",totalDmaCount);
#endif
#if USBDMA
/*******************************/
/* Verify check sum */
/*******************************/
printf("Now, Checksum calculation\n\r");
cs=0;
i=(download_addr);
j=(download_addr+download_len-10)&0xfffffffc;
while(i<j)
{
temp=*((u_int *)i);
i+=4;
cs+=(u_short)(temp&0xff);
cs+=(u_short)((temp&0xff00)>>8);
cs+=(u_short)((temp&0xff0000)>>16);
cs+=(u_short)((temp&0xff000000)>>24);
}
i=(download_addr+download_len-10)&0xfffffffc;
j=(download_addr+download_len-10);
while(i<j)
{
cs+=*((u_char *)i++);
}
checkSum = cs;
#endif
dnCS=*((unsigned char *)(download_addr+download_len-8-2))+(*((unsigned char *)(download_addr+download_len-8-1))<<8);
if(checkSum!=dnCS)
{
printf("Error!!! MEM:%x DN:%x\n\r", checkSum, dnCS);
return 0;
}
printf("USB Image Checksum Ok\n\r");
download_len-=10;
//rGPGCON &= 0xfff3ffff; //GPG9 input
return download_len;
}
u_short ReleaseDMA(u_int attr)
{
u_short DevID, ReqSrc, ch;
DevID = attr>>16;
ReqSrc = attr&0xf;
ch = (attr&0xf0)>>4;
#if DMA_CHECK_ATTR
if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
return 1;
if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
return 1;
#endif
DMAChannel[ch].pDMA->DMASKTRIG = 0;//4; //stop dma and channel off
DMAChannel[ch].used = DMA_IS_FREE;
return 0;
}
void ConfigEp3IntMode(void)
{
ReleaseDMA(UsbDevReq); //release and stop dma
rINDEX_REG=3;
rOUT_CSR2_REG=rOUT_CSR2_REG&~(EPO_AUTO_CLR/*|EPO_OUT_DMA_INT_MASK*/);
//AUTOCLEAR off,interrupt_enabled (???)
rEP3_DMA_UNIT=1;
rEP3_DMA_CON=0;
//deamnd disable,out_dma_run=stop,in_dma_run=stop,DMA mode disable
//wait until DMA_CON is effective.
{
register i = rEP3_DMA_CON;
for(i=0;i<10;i++);
}
}
void ReConfigEp3Dma(u_int bufAddr, u_int count)
{
SetDMARun(UsbDevReq|DMA_START, ADDR_EP3_FIFO, bufAddr, count);
}
void IsrForUSBDma2(void)
{
u_char out_csr3;
u_char saveIndexReg = rINDEX_REG;
rINDEX_REG = 3;
out_csr3 = rOUT_CSR1_REG;
ClearPending(BIT_DMA2);
totalDmaCount += 0x80000;
if(totalDmaCount>=download_len)// is last?
{
totalDmaCount = download_len;
ConfigEp3IntMode();
if(out_csr3& EPO_OUT_PKT_READY)
{
CLR_EP3_OUT_PKT_READY();
}
Disable_Int(nDMA2_INT);//
Enable_Int(nUSBD_INT);//rINTMSK&=~(BIT_USBD);
}
else
{
ReConfigEp3Dma(download_addr+totalDmaCount-8, ((download_len-totalDmaCount)>0x80000)?0x80000:(download_len-totalDmaCount));
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L = 0xff;
rEP3_DMA_TTC_M = 0xff;
rEP3_DMA_TTC_H = 0xf; //0xfffff;
}
}
rINDEX_REG = saveIndexReg;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -