📄 usb.c
字号:
#include "def.h"
#include "board.h"
#include "utils.h"
#include "2410addr.h"
#include "2410usb.h"
#include "usblib.h"
#include "usbsetup.h"
#include "usbout.h"
#include "usbin.h"
#ifdef USB_DOWNLOAD_SUPPORT
//======================================================
extern volatile U32 download_addr;
extern volatile U32 download_len;
volatile U8 *downPt;
volatile U32 totalDmaCount;
volatile U16 checkSum;
volatile int isUsbdSetConfiguration;
//======================================================
static void __irq IsrUsbd(void)
{
U8 usbdIntpnd, epIntpnd;
U8 saveIndexReg = rINDEX_REG;
usbdIntpnd = rUSB_INT_REG;
epIntpnd = rEP_INT_REG;
if(usbdIntpnd&SUSPEND_INT)
{
rUSB_INT_REG = SUSPEND_INT;
}
if(usbdIntpnd&RESUME_INT)
{
rUSB_INT_REG = RESUME_INT;
}
if(usbdIntpnd&RESET_INT)
{
//ResetUsbd();
ReconfigUsbd();
rUSB_INT_REG = RESET_INT; //RESET_INT should be cleared after ResetUsbd().
//PrepareEp1Fifo();
}
if(epIntpnd&EP0_INT)
{
rEP_INT_REG = EP0_INT;
Ep0Handler();
}
if(epIntpnd&EP1_INT)
{
rEP_INT_REG=EP1_INT;
Ep1Handler();
}
if(epIntpnd&EP2_INT)
{
rEP_INT_REG = EP2_INT;
//Ep2Handler();
}
if(epIntpnd&EP3_INT)
{
rEP_INT_REG = EP3_INT;
Ep3Handler();
}
if(epIntpnd&EP4_INT)
{
rEP_INT_REG = EP4_INT;
//Ep4Handler();
}
ClearPending(BIT_USBD);
rINDEX_REG = saveIndexReg;
}
U32 UsbState;
U32 UsbInLength;
U8 *UsbTxAddr;
void UsbdInit(U8 fun)
{
isUsbdSetConfiguration = 0;
// ChangeUPllValue(40, 4, 1); //UCLK=48Mhz
rUPLLCON = (40<<12) | (4<<4) | 1;
InitDescriptorTable(fun);
ReconfigUsbd();
// PrepareEp1Fifo();
UsbState = 0;
}
//======================================================
static __inline void cpu_arm920_cache_clean_invalidate_all(void)
{
__asm{
mov r1, #0
mov r1, #7 << 5 /* 8 segments */
cache_clean_loop1:
orr r3, r1, #63UL << 26 /* 64 entries */
cache_clean_loop2:
mcr p15, 0, r3, c7, c14, 2 /* clean & invalidate D index */
subs r3, r3, #1 << 26
bcs cache_clean_loop2 /* entries 64 to 0 */
subs r1, r1, #1 << 5
bcs cache_clean_loop1 /* segments 7 to 0 */
mcr p15, 0, r1, c7, c5, 0 /* invalidate I cache */
mcr p15, 0, r1, c7, c10, 4 /* drain WB */
}
}
void cache_clean_invalidate(void)
{
cpu_arm920_cache_clean_invalidate_all();
}
static __inline void cpu_arm920_tlb_invalidate_all(void)
{
__asm{
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 /* drain WB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I & D TLBs */
}
}
void tlb_invalidate(void)
{
cpu_arm920_tlb_invalidate_all();
}
void call_linux(U32 a0, U32 a1, U32 a2)
{
void (*goto_start)(U32, U32);
cache_clean_invalidate();
tlb_invalidate();
__asm{
// mov r0, a0//%0
// mov r1, a1//%1
// mov r2, a2//%2
mov ip, #0
mcr p15, 0, ip, c13, c0, 0 /* zero PID */
mcr p15, 0, ip, c7, c7, 0 /* invalidate I,D caches */
mcr p15, 0, ip, c7, c10, 4 /* drain write buffer */
mcr p15, 0, ip, c8, c7, 0 /* invalidate I,D TLBs */
mrc p15, 0, ip, c1, c0, 0 /* get control register */
bic ip, ip, #0x0001 /* disable MMU */
mcr p15, 0, ip, c1, c0, 0 /* write control register */
//mov pc, r2
//nop
//nop
/* no outpus */
//: "r" (a0), "r" (a1), "r" (a2)
}
// SetClockDivider(1, 1);
// SetSysFclk(FCLK_200M); //start kernel, use 200M
Delay(100);
goto_start = (void (*)(U32, U32))a2;
(*goto_start)(a0, a1);
}
static int WaitDownload(U32 addr);
static int BoardUsbDownload(U32 addr, U32 run)
{
U8 fun;
int len;
rGPHCON = rGPHCON&~(0xf<<18)|(0x5<<18);
//To enhance the USB signal quality.
//CLKOUT 0,1=OUTPUT to reduce the power consumption.
rGPGCON &= 0xfff3ffff; //GPG9 input
/* puts("Please select usb function\n1:download\n2:usb test\n");
while(1)
{
fun = '1';//getch();
if((fun=='1')||(fun=='2'))
{
fun -= '0';
break;
}
}*/
fun = 1;
UsbdInit(fun);
Delay(100);
rGPGCON |= 0x00040000;
rGPGDAT |= 0x0200; //GPG9 ouput 1
pISR_USBD =(unsigned)IsrUsbd;
ClearPending(BIT_USBD);
EnableIrq(BIT_USBD);
len = WaitDownload(addr);
DisableIrq(BIT_USBD);
rGPGCON &= 0xfff3ffff; //GPG9 input
if(len>0) {
printf("\nPress any key to continue...\n");
getch();
if(run) {//getyorn()) {
//void (*fun)(void) = (void (*)(void))download_addr;
//CacheDisable();
//CacheFlush();
rINTMSK = BIT_ALLMSK;
Delay(100);
//(*fun)();
call_linux(0, 193, download_addr);
}
}
return len;
}
static int LoadFileFromUsb(U32 a1, U32 a2, U32 a3, U32 a4)
{
puts("USB download file\n");
return BoardUsbDownload(0, 0);
}
static int LoadProgFromUsb(U32 a1, U32 a2, U32 a3, U32 a4)
{
return BoardUsbDownload(0, 1);
}
static char LoadFileFromUsbTitle[] = "通过USB下载文件";
static char LoadFileFromUsbTip[] = "本程序从USB口下载文件到SDRAM的指定位置,请在DNW的USB Port菜单下选Transmit再选择文件发送,下载地址在Configration里指定";
static char LoadProgFromUsbTitle[] = "通过USB下载程序";
static char LoadProgFromUsbTip[] = "本程序从USB口下载程序到SDRAM的指定位置处并直接运行,请在DNW的USB Port菜单下选Transmit再选择二进制文件发送,下载地址在Configration里指定";
//UsbDownloadItem在prog_entry.c里被引用
TEST_PROGRAM_ITEM LoadFileFromUsbItem = {
LoadFileFromUsb, //入口地址
LoadFileFromUsbTitle, //显示名称
LoadFileFromUsbTip, //帮助或提示信息,可为NULL
1}; //使用printf,puts,putch等函数时在LCD上也显示输出字符(串)
TEST_PROGRAM_ITEM LoadProgFromUsbItem = {
LoadProgFromUsb, //入口地址
LoadProgFromUsbTitle, //显示名称
LoadProgFromUsbTip, //帮助或提示信息,可为NULL
1}; //使用printf,puts,putch等函数时在LCD上也显示输出字符(串)
/*************************************************************/
U32 UsbPoll(void);
static int WaitDownload(U32 addr)
{
U32 UsbConnected = 0;
U32 i, j;
U32 temp;
U8 tempMem[16];
U16 cs, dnCS;
#if 0
MMU_DisableICache();
//For multi-ICE.
//If ICache is not turned-off, debugging is started with ICache-on.
#endif
/*******************************/
/* Test program download */
/*******************************/
checkSum = 0;
downPt = tempMem; //This address is used for receiving first 8 byte.
download_addr = addr; //_RAM_STARTADDRESS;
download_len = 0;
puts("Press Esc key to exit\n");
while(!isUsbdSetConfiguration)
{
if(getkey()==ESC_KEY)
return -1;
}
puts("USB connected\n");
/* DisableIrq(BIT_USBD);
DisableIrq(BIT_DMA2);
while(!UsbPoll())
{
if(getkey()==ESC_KEY)
{
puts("USB download aborted.\n");
return -1;
}
}
DbgOut("End, Received %dBytes\n",(U32)downPt-download_addr);
checkSum=checkSum - *((unsigned char *)(download_addr+download_len-8-2))
- *( (unsigned char *)(download_addr+download_len-8-1) );
goto PollRxEnd;
*/
j=0;
while(download_len==0)
{
if(j%0x50000==0)
LedSet(0xf);
if(j%0x50000==0x28000)
LedSet(0x0);
j++;
if(getkey()==ESC_KEY)
{
puts("USB download aborted.\n");
return -1;
}
if(isUsbdSetConfiguration)
{
if(!UsbConnected)
puts("Now, USB is connected.");
UsbConnected = 1;
}
}
#if USBDMA
ClearEp3OutPktReady(); //中断处理读完第一个包后未清OutPktReady位,在此清掉
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("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n",
download_addr, download_len);
j=0x80000;
#if USBDMA
while(totalDmaCount<download_len)
{
if((rDCDST2-(U32)download_addr+8)>=j)
{
/* static int led = 0x0;
led ^=2;
Led_Display(led);*/
putch('d');
j+=0x80000;
}
if(getkey()==ESC_KEY)
{
int i;
ConfigEp3IntMode();
DisableIrq(BIT_DMA2);
DbgOut("\nReceive process aborted.\n");
DbgOut("Received %d bytes\n", totalDmaCount);
for(i=0; i<32;i++)
{
printf("0x%x = %x\n", download_addr+i*0x100000, *(U32 *)(download_addr+i*0x100000));
}
return -1;
}
}
#else
while(((U32)downPt-download_addr)<(download_len-8))
{
if(((U32)downPt-download_addr)>=j)
{
static int led = 0x0;
led ^= 2;
Led_Display(led);
putch('i');
j+=0x80000;
}
if(getkey()==ESC_KEY)
{
int i;
DbgOut("\nReceive process aborted.\n");
DbgOut("Received %d bytes\n", (U32)downPt-download_addr);
for(i=0;i<48;i++)
{
printf("0x%x = %x\n", download_addr+i*0x100000, *(U32 *)(download_addr+i*0x100000));
}
return -1;
}
}
#endif
#if USBDMA
/*******************************/
/* Verify check sum */
/*******************************/
printf("Now, Checksum calculation\n");
cs=0;
i=(download_addr);
j=(download_addr+download_len-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=(download_addr+download_len-10)&0xfffffffc;
j=(download_addr+download_len-10);
while(i<j)
{
cs+=*((U8 *)i++);
}
checkSum = cs;
#else
//checkSum was calculated including dnCS. So, dnCS should be subtracted.
checkSum=checkSum - *((unsigned char *)(download_addr+download_len-8-2))
- *( (unsigned char *)(download_addr+download_len-8-1) );
#endif
//PollRxEnd:
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", checkSum, dnCS);
return -1;
}
printf("Ok\n");
download_len-=10;
return download_len;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -