📄 usb.c
字号:
else
{
USBOTG_FUNC_STALL_EP(USB_EP_ADDR(0, EP_OUT_DIR));
}
}
}
void _Ep0Received(void)
{
DWORD temp;
//clear the interrupt flag
usb_int.ep_done &= ~0x01;
//check whether we got an set up packet
temp = *(volatile DWORD *)(USBOTG_EP_BASE + 0);
if(temp & 0x40000000)
{
//read the data out
*(DWORD *)&SetupPacket[0] = *(volatile DWORD *)(USBOTG_DATA_BASE + 0);
*(DWORD *)&SetupPacket[4] = *(volatile DWORD *)(USBOTG_DATA_BASE + 4);
//clear x status.
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(0, EP_OUT_DIR));
process_setup_packet();
}
else if(bTransferOver == 0)
{
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(0, EP_OUT_DIR));
bTransferOver = 1;
}
else
{
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(0, EP_OUT_DIR));
}
USBOTG_FUNC_CLR_EP0_SETUP();
USBOTG_FUNC_SET_EP_XFER_LEN(0, EP_OUT_DIR, 8);
}
#if 0
void OutputUSBBuffer()
{
#define SIZE_1K 1024
unsigned int i;
DbgPutString ("\r\n");
for (i=0; i<16*SIZE_1K; i+=4)
{
DbgPutHex(*(unsigned int *)(SDRAM_IMG_CACHE_START + i));
DbgPutString ("\r\n");
}
}
#endif
void _Ep0Transmit(void)
{
//clear the interrupt flag
usb_int.ep_done &= ~0x02;
bWaitForXmit = 0;
if (bSetAddress)
{
USBOTG_FC_DEV_ADDRESS_ADDR = iDevAddr;
bSetAddress = 0;
}
else if (bTransferOver == 0)
{
send_ep0_data();
}
else if (bStatusStage)
{
bStatusStage = 0;
if(bWriteImage)
{
bWriteImage = 0;
NandWriteCurImg();
#ifdef USING_USB_DMA_MODE
USB_ResetState();
pCurImgCache = (unsigned char *)SDRAM_IMG_CACHE_START;
OTG_FuncDmaCfg(2, (DWORD)pCurImgCache);
#endif // USING_USB_DMA_MODE
}
if(bWriteToc)
{
bWriteToc = 0;
NandWriteToc();
}
if(bChangeCS)
{
bChangeCS = 0;
DbgPutString("\r\nChange Nand CS : ");
DbgPutHex(g_nNandCS);
FMD_Init();
}
}
}
void USB_Run(void)
{
if(usb_int.connect_detect)
{
USB_Reset();
}
if(usb_int.ep_done & 0x02)
_Ep0Transmit();
if(usb_int.ep_done & 0x08)
bulk_in_ep1();
if(usb_int.ep_done & 0x04)
bulk_out_ep1();
if(usb_int.ep_done & 0x20)
bulk_in_ep2();
if(usb_int.ep_done & 0x01 && !bWaitForXmit)
{
//Since we share the buffer bewteen EP0_IN and EP0_OUT, don't handle EP0_Rec until the
//last EP0_Xmt is done
_Ep0Received();
//prepare for receiving the next packet
USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(0, EP_OUT_DIR));
}
if(usb_int.ep_done & 0x10)
{
#ifdef USING_USB_DMA_MODE
pCurImgCache += 64;
OTG_FuncDmaCfg(2, (DWORD)pCurImgCache);
#else // USING_USB_DMA_MODE
bulk_out_ep2();
#endif // USING_USB_DMA_MODE
}
usb_int.intr = 0;
}
void vendor_command(void)
{
switch(BREQUEST_V)
{
case ATLAS_MSG_REQUEST_IMG_BUF:
//Store the image at
iNeededLen = 4;
pCurImgCache = (unsigned char *)SDRAM_IMG_CACHE_START;
iCurImgTransfered = 0;
pEp0Data = (unsigned char *)(&pCurImgCache);
iXferedLen = 0;
bTransferOver = 0;
g_iCurImgLength = WVALUE_LO_V | (WVALUE_HI_V << 8) | (WINDEX_LO_V << 16) | (WINDEX_HI_V << 24);
send_ep0_data();
break;
case ATLAS_MSG_SET_NAND_CS:
{
DWORD cs;
cs = (unsigned)(((((unsigned)WVALUE_LO_V) & 0xff) | ((((unsigned)WVALUE_HI_V) & 0xff) << 8)));
if( g_nNandCS != cs)
{
g_nNandCS = cs;
bChangeCS = 1;
}
}
break;
case ATLAS_MSG_SET_CUR_IMG_TYPE:
g_nCurImg= (unsigned)(((((unsigned)WVALUE_LO_V) & 0xff) | ((((unsigned)WVALUE_HI_V) & 0xff) << 8)));
break;
case ATLAS_MSG_WRITE_IMG_2_NAND:
bWriteImage = 1;
break;
case ATLAS_MSG_UPDATE_NAND_TOC:
bWriteToc = 1;
break;
case ATLAS_MSG_GET_BOOT_STAGE:
//Store the image at
iNeededLen = 4;
iValue = ATLAS_BOOT_STAGE_NBOOT;
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_BOOTLOADER_VERSION:
iNeededLen = 4;
iValue = ATLAS_BOOTLOADER_NBOOT_VER;
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_CPU_INFO:
iNeededLen = 4;
iValue = ATLAS_CPU_INFO;
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_HARDWARE_NAME:
iNeededLen = 20;
pEp0Data = (unsigned char *)(ATLAS_HARDWARE_NAME);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_SOFTWARE_NAME:
iNeededLen = 20;
pEp0Data = (unsigned char *)(BSP_NAME);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_IMG_TYPE:
iNeededLen = 20;
pEp0Data = (unsigned char *)(ATLAS_IMG_TYPE_NBOOT);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_NANDXIP_INFO:
iNeededLen = 4;
// iValue = ((SECTOR_TO_FILE_SIZE(g_pTOC->nandxipInfo.dwCodePages)<<16)|g_pTOC->nandxipInfo.dwCopies);
iValue = (((g_pTOC->nandxipInfo.dwCodePages*512)<<16)|g_pTOC->nandxipInfo.dwCopies);
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_EBOOT_RESERVEDBLOCKS:
iNeededLen = 4;
iValue = SECTOR_TO_FILE_SIZE(g_pTOC->id[TOC_EBOOT_ENTRY].dwTtlSectors);
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_DM_RESERVEDBLOCKS:
iNeededLen = 4;
iValue = SECTOR_TO_FILE_SIZE(g_pTOC->id[TOC_DM_ENTRY].dwTtlSectors);
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_NK_RESERVEDBLOCKS:
iNeededLen = 4;
iValue = 0;
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_NBOOT_RESERVEDBLOCKS:
iNeededLen = 4;
iValue = SECTOR_TO_FILE_SIZE(BOOT_BLOCK_TO_SECTOR(1));
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_GET_USB_PIPE_INDEX:
iNeededLen = 4;
//The PC need a pipe index according to the order reported in the descriptor.
//This index don't count the control pipe.
//The highest byte is the bulk in for debug msg. Index is 2
//The second highest byte is the bulk out for debug msg. Index is 1
//The third highest byte is the bulk in for status polling. Index is 0
//The lowest byte is the bulk out for downloading image. Index is 3
iValue |= 3;
iValue = 0x02010003;
pEp0Data = (unsigned char *)(&iValue);
iXferedLen = 0;
bTransferOver = 0;
send_ep0_data();
break;
case ATLAS_MSG_BEGIN_SESSION:
bulk_in_ep1();
g_bTransportChange = 1;
g_iDevStatus = ATLAS_DEV_STATUS_IN_USB_SESSION_NBOOT;
break;
case ATLAS_MSG_END_SESSION:
g_bTransportChange = 1;
g_iDevStatus = ATLAS_DEV_STATUS_IDLE_NBOOT;
break;
default:
break;
}
}
#ifndef USING_USB_DMA_MODE
void bulk_out_ep2()
{
DWORD *pdwBuf = (DWORD *)&pCurImgCache[iCurImgTransfered];
int i;
usb_int.ep_done &= ~0x10;
USBOTG_FUNC_CLR_EP_READY(USB_EP_ADDR(2, EP_OUT_DIR));
for(i = 0; i < 64; i+=4)
{
//EP2 is using USBOTG_DATA_BASE+0xC8 as its xsa
*pdwBuf++ = *((volatile DWORD *)(USBOTG_DATA_BASE + 0x48 + i));
}
iCurImgTransfered += 64;
if (USBOTG_FC_DONE_REG_ADDR & 0x10)
{
DbgPutString ("ep stat not clear!\r\n");
}
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(2, EP_OUT_DIR));
USBOTG_FUNC_SET_EP_XFER_LEN(2, EP_OUT_DIR, 64);
USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(2, EP_OUT_DIR));
}
#endif // USING_USB_DMA_MODE
void bulk_in_ep1(void)
{
//this endpoint is used to report the dev status
USBOTG_FUNC_PREPARE_EP(1, EP_IN_DIR);
USBOTG_FUNC_SET_EP_XFER_LEN(1, EP_IN_DIR, 4);
*(volatile DWORD *)(USBOTG_DATA_BASE + 0x28) = g_iDevStatus;
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(1, EP_IN_DIR));
USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(1, EP_IN_DIR));
usb_int.ep_done &= ~0x08;
}
void bulk_in_ep2(void)
{
//this endpoint is used to send out debug string
int len, len2;
len = strlen((char*)pDbgMsg);
if(len > 64)
{
len = 64;
bNeedZeroPkt = 0;
}
else if(len == 64)
{
len = 64;
bNeedZeroPkt = 1;
}
else
{
bNeedZeroPkt = 0;
}
if(len || bNeedZeroPkt)
{
if(len % 4)
len2 = (len + 3) & ~3;
else
len2 = len;
if(len2)
{
memcpy((unsigned char *)(volatile DWORD *)(USBOTG_DATA_BASE + 0xC8), pDbgMsg, len2);
pDbgMsg += len;
}
USBOTG_FUNC_SET_EP_XFER_LEN(2, EP_IN_DIR, len);
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(2, EP_IN_DIR));
USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(2, EP_IN_DIR));
}
if(len == 0 && !bNeedZeroPkt)
{
g_iDevStatus = ATLAS_DEV_STATUS_IN_USB_SESSION_NBOOT;
//We need to reprepare the status
bulk_in_ep1();
}
usb_int.ep_done &= ~0x20;
}
void bulk_out_ep1(void)
{
unsigned int i, len;
len = *((volatile unsigned *)(USBOTG_EP_BASE+USB_EP_ADDR(1, EP_OUT_DIR)*16+12));
len &= 0xfffff;
len = 16 - len;
usb_int.ep_done &= ~0x04;
USBOTG_FUNC_CLR_EP_READY(USB_EP_ADDR(1, EP_OUT_DIR));
for(i = 0; i < len; i+=4)
{
//EP2 is using USBOTG_DATA_BASE+0xC8 as its xsa
*(unsigned *)(&g_dbgMsg[i]) = *((volatile DWORD *)(USBOTG_DATA_BASE + 0x8 + i));
}
g_dbgMsg[len] = 0;
bInstRcvd = 1;
USBOTG_FUNC_SET_XBUF(USB_EP_ADDR(1, EP_OUT_DIR));
USBOTG_FUNC_SET_EP_XFER_LEN(1, EP_OUT_DIR, 16);
USBOTG_FUNC_SET_EP_READY(USB_EP_ADDR(1, EP_OUT_DIR));
}
char * USB_GetInstruction(void)
{
if(bInstRcvd)
{
bInstRcvd = 0;
return g_dbgMsg;
}
return NULL;
}
void USB_OutputString(const char *p)
{
pDbgMsg = (uchar *)p;
g_iDevStatus = ATLAS_DEV_STATUS_SENDING_MSG_NBOOT;
INT_RISC_MASK &= ~INT_MASK_USB;
bulk_in_ep2();
INT_RISC_MASK |= INT_MASK_USB;
USB_Process();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -