📄 cmd_usb_down.c.svn-base
字号:
for(i=0;i<num;i++)
{
buf[i]=(u8)rEP3_FIFO;
checkSum+=buf[i];
}
}
void ClearEp3OutPktReady(void)
{
u8 out_csr3;
rINDEX_REG=3;
out_csr3=rOUT_CSR1_REG;
CLR_EP3_OUT_PKT_READY();
}
void ConfigEp3DmaMode(u32 bufAddr,u32 count)
{
int i;
rINDEX_REG=3;
count=count&0xfffff; //transfer size should be <1MB
rDISRCC2=(1<<1)|(1<<0);
rDISRC2=ADDR_EP3_FIFO; //src=APB,fixed,src=EP3_FIFO
rDIDSTC2=(0<<1)|(0<<0);
rDIDST2=bufAddr; //dst=AHB,increase,dst=bufAddr
rDCON2=(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
rDMASKTRIG2= (1<<1);
//DMA 2 on
//rEP3_DMA_FIFO=0x40; //not needed for OUT operation.
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;
//AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.
rEP3_DMA_UNIT=0x01; //DMA transfer unit=1byte
rEP3_DMA_CON=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.
rEP3_DMA_CON;
for(i=0;i<10;i++);
}
void ConfigEp3IntMode(void)
{
rINDEX_REG=3;
rDMASKTRIG2= (0<<1); // EP3=DMA ch 2
//DMA channel off
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.
rEP3_DMA_CON;
}
void Ep3Handler(void)
{
u8 out_csr3;
int fifoCnt;
rINDEX_REG=3;
out_csr3=rOUT_CSR1_REG;
// dbgprintf("<3:%x]",out_csr3);
if(out_csr3 & EPO_OUT_PKT_READY){ //1
fifoCnt=rOUT_FIFO_CNT1_REG;
// RdPktEp3(ep3Buf,fifoCnt);
// PrintEpoPkt(ep3Buf,fifoCnt);
if(downloadFileSize==0){
RdPktEp3((u8 *)downPt, 8);
// USBdownloadAddress = *((u32 *)(downPt));
USBdownloadAddress = tempDownloadAddress;
downloadFileSize= *((u32 *)(downPt+4));
checkSum=0;
downPt=(u8 *)USBdownloadAddress;
RdPktEp3_CheckSum((u8 *)downPt,fifoCnt-8); //The first 8-bytes are deleted.
downPt+=fifoCnt-8;
//CLR_EP3_OUT_PKT_READY() is not executed.
//So, USBD may generate NAK until DMA2 is configured for USB_EP3;
mask_irq(INT_USBD);
return;
}else{
dbgprintf("<ERROR>");
RdPktEp3_CheckSum((u8 *)downPt,fifoCnt);
downPt+=fifoCnt; //fifoCnt=64
}
CLR_EP3_OUT_PKT_READY();
if(((rOUT_CSR1_REG&0x1)==1) && ((rEP_INT_REG & 0x8)==0)){
fifoCnt=rOUT_FIFO_CNT1_REG;
RdPktEp3_CheckSum((u8 *)downPt,fifoCnt);
downPt+=fifoCnt;
CLR_EP3_OUT_PKT_READY();
}
return;
}
//I think that EPO_SENT_STALL will not be set to 1.
if(out_csr3 & EPO_SENT_STALL){ // 0x40
dbgprintf("[STALL]");
CLR_EP3_SENT_STALL();
return;
}
unmask_irq(INT_USBD);
}
void USB_Download(void)
{
int first = 1, i, j;
u8 key = 0;
u16 cs, dnCS, checkSum = 0;
u32 temp;
u8 tempMem[16];
USBdownloadAddress = (u32)tempMem;
downPt = (u8 *)USBdownloadAddress;
downloadFileSize = 0;
printf("\n\nUSB host is connected\n");
printf("Select the file you wanna download in 'USB Port->Transmit' menu of DNW\n");
printf("Waiting a download... \n");
while(downloadFileSize == 0){
if(ctrlc()){
printf("\ndownload file size is 0 byte.\nusbdown command stopped!!\n\n\n");
in_USB_Download = 0;
return;
}
}
unmask_irq(INT_DMA2);
ClearEp3OutPktReady();
// indicate the first packet is processed.
// has been delayed for DMA2 cofiguration.
if(downloadFileSize > EP3_PKT_SIZE)
{
if(downloadFileSize <= 0x80000)
{
ConfigEp3DmaMode(USBdownloadAddress+EP3_PKT_SIZE-8,downloadFileSize-EP3_PKT_SIZE);
}else{
ConfigEp3DmaMode(USBdownloadAddress+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
if(downloadFileSize>(0x80000*2))//for 1st autoreload
{
rDIDST2=(USBdownloadAddress+0x80000-8); //for 1st autoreload.
rDIDSTC2=(1<<2)|(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
}
}else{
rDIDST2=(USBdownloadAddress+0x80000-8);
rDIDSTC2=(1<<2)|(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
}
}
}
totalDmaCount = 0;
}else{
totalDmaCount=downloadFileSize;
}
printf("\nNow, Downloading [ADDRESS:0x%x ,TOTAL:%d(0x%x) bytes]\n",
USBdownloadAddress, downloadFileSize, downloadFileSize);
printf("Downloading file ... ");
j = 0x10000;
while(1)
{
if( (rDCDST2-(u32)USBdownloadAddress+8) >= j) j += 0x10000;
if(totalDmaCount >= downloadFileSize) break;
}
printf("\n\nRECEIVED FILE SIZE: %d bytes", totalDmaCount);
// Verify check sum
printf("\nNow, Checksum calculation\n");
cs = 0;
i = USBdownloadAddress;
j = (USBdownloadAddress + downloadFileSize-10) & 0xfffffffc;
while(i<j)
{
temp = *((u32 *)i);
i += 4;
cs += (u16)(temp&0xff);
cs += (u16)((temp&0xff00)>>8);
cs += (u16)((temp&0xff0000)>>16);
cs += (u16)((temp&0xff000000)>>24);
}
i = (USBdownloadAddress + downloadFileSize-10) & 0xfffffffc;
j = (USBdownloadAddress + downloadFileSize-10);
while(i<j) cs += *((u8 *)i++);
checkSum = cs;
dnCS = *((unsigned char *)(USBdownloadAddress + downloadFileSize-8-2))+
(*( (unsigned char *)(USBdownloadAddress + downloadFileSize-8-1))<<8);
if(checkSum!=dnCS)
{
printf("Checksum Error!!! MEM:%x DN:%x\n",checkSum,dnCS);
return;
}
printf("Download O.K.\n\n\n");
in_USB_Download = 0;
}
void ISR_int_usbd(void)
{
u8 usbdIntpnd, epIntpnd;
u8 saveIndexReg = rINDEX_REG;
mask_irq(INT_USBD);
usbdIntpnd = rUSB_INT_REG;
epIntpnd = rEP_INT_REG;
// printf("[INT:EP_I=%x,USBI=%x]\n",epIntpnd,usbdIntpnd);
if(usbdIntpnd & SUSPEND_INT) // 1
{
rUSB_INT_REG = SUSPEND_INT;
// printf( "<SUS]");
}
if(usbdIntpnd & RESUME_INT) // 2
{
rUSB_INT_REG=RESUME_INT;
// printf("<RSM]");
}
if(usbdIntpnd & RESET_INT) // 4
{
// printf( "<RST]");
config_usbd();
//RESET_INT should be cleared after ResetUsbd()
rUSB_INT_REG=RESET_INT;
PrepareEp1Fifo();
}
unmask_irq(INT_USBD);
if(epIntpnd & EP0_INT) //1
{
isUsbdSetConfiguration = 1;
rEP_INT_REG=EP0_INT;
Ep0Handler();
}
if(epIntpnd & EP1_INT) //2
{
rEP_INT_REG=EP1_INT;
Ep1Handler();
}
if(epIntpnd & EP3_INT) //8
{
rEP_INT_REG=EP3_INT;
Ep3Handler();
}
rINDEX_REG=saveIndexReg;
clear_irq_pnd(INT_USBD);
}
void ISR_int_dma2(void)
{
u8 out_csr3;
u32 nextTotalDmaCount;
u8 saveIndexReg = rINDEX_REG;
mask_irq(INT_DMA2);
rINDEX_REG = 3;
out_csr3 = rOUT_CSR1_REG;
clear_irq_pnd(INT_DMA2);
totalDmaCount += 0x80000;
if(totalDmaCount >= downloadFileSize)// is last?
{
totalDmaCount = downloadFileSize;
ConfigEp3IntMode();
if(out_csr3& EPO_OUT_PKT_READY) CLR_EP3_OUT_PKT_READY();
mask_irq(INT_DMA2);
unmask_irq(INT_USBD);
}else{
if((totalDmaCount+0x80000)<downloadFileSize){
nextTotalDmaCount=totalDmaCount+0x80000;
if((nextTotalDmaCount+0x80000)<downloadFileSize){
//for (2~n)th autoreload.
while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
rDIDST2=((u32)USBdownloadAddress+nextTotalDmaCount-8);
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
//0xfffff;
}
}else{
while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
rDIDST2=((u32)USBdownloadAddress+nextTotalDmaCount-8);
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-nextTotalDmaCount);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
rEP3_DMA_TTC_M=0xff;
rEP3_DMA_TTC_H=0xf;
//0xfffff;
}
}
}else{
while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
rDIDST2=((u32)USBdownloadAddress+downloadFileSize-8); //for next autoreload.
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0);
//There is no 2nd autoreload. This will not be used.
//rDMA_TX+=0x0; //USBD register
}
unmask_irq(INT_DMA2);
}
rINDEX_REG = saveIndexReg;
}
void usb_slave_port_init(void)
{
// USB device detection control
rGPGCON &= ~(3<<24);
rGPGCON |= (1<<24); // output
rGPGUP |= (1<<12); // pullup disable
rGPGDAT |= (1<<12); // output
rMISCCR &= ~(1<<3); // USBD is selected instead of USBH1
rMISCCR &= ~(1<<13); // USB port 1 is enabled.
return;
}
void usbdown_init(void)
{
// USB device detection control
rGPGCON &= ~(3<<24);
rGPGCON |= (1<<24); // output
rGPGUP |= (1<<12); // pullup disable
rGPGDAT |= (1<<12); // output
// Interrupt initialization
irq_install_handler(INT_USBD, ISR_int_usbd, NULL);
irq_install_handler(INT_DMA2, ISR_int_dma2, NULL);
mask_irq(INT_USBD);
mask_irq(INT_DMA2);
rMISCCR &= ~(1<<3); // USBD is selected instead of USBH1
rMISCCR &= ~(1<<13); // USB port 1 is enabled.
InitDescriptorTable();
config_usbd();
unmask_irq(INT_USBD);
PrepareEp1Fifo();
Clk0_Disable();
Clk1_Disable();
return;
}
void do_usb_down (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
if ((argc < 2) || (argc > 3)){
printf ("inadquate argument count\nUsage:\n%s\n", cmdtp->help);
return -1;
}
tempDownloadAddress = simple_strtoul(argv[1], NULL, 16);
if((tempDownloadAddress<CFG_MEMTEST_START) || (tempDownloadAddress>=CFG_MEMTEST_END)){
printf("memory address must be within the range of 0x%x ~ 0x%x\n",
CFG_MEMTEST_START, CFG_MEMTEST_END);
return -1;
}
if(isUsbdSetConfiguration == 0){
printf("\n\nUSB host is not connected yet.\n");
printf("Connect USB cable to MBA2440 USB slave port and try again!!\n\n\n");
return;
}
unmask_irq(INT_USBD);
in_USB_Download = 1;
while(in_USB_Download == 1) USB_Download();
mask_irq(INT_USBD);
mask_irq(INT_DMA2);
return;
}
U_BOOT_CMD(
usbdown, 2, 1, do_usb_down,
"usbdown - data download using USB slave port.\n",
" - MBA2440 USB download command\n"
" this command is only for DNW\n"
" Connect USB cable, before executing usbdown\n"
"usbdown [download memory address(hex)]\n");
#endif //(CONFIG_COMMANDS & CONFIG_USE_IRQ)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -