📄 gfd_usb_hl.c
字号:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
unsigned char Ucode_1A[]= {
0x0b, 0x00, 0x00, 0x00, 0x1c, 0x06, 0x00, 0x05,
0x00, 0x00, 0x00, 0x00};
/*-------------------------------------------------------------------*
* define declarations
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* 外部变量声明
*-------------------------------------------------------------------*/
extern UINT8 *rd_pages[NUM_RAMDISK_PAGES];
extern UINT8 g_nor_buf[256*1024];
extern int g_nor_blknum;
/*-------------------------------------------------------------------*
* 外部函数声明
*-------------------------------------------------------------------*/
extern ER usb_write_reg(U32 reg, U32 val);
extern ER usb_read_reg(U32 reg);
extern U8 usb_chang_reg32_to_reg8(U32 reg);
extern U16 usb_change_reg32_to_reg16(U32 reg);
extern U8 usb_get_regbit15_to_8(U32 reg);
extern ER USB_DMA_TRANS_RX(U32 srcadd, U32 destadd, U32 srcwidth, U32 destwidth, U32 srcsize, U32 channelnum, U32 transnum);
extern ER USB_DMA_TRANS_TX(U32 srcadd, U32 destadd, U32 srcwidth, U32 destwidth, U32 srcsize, U32 channelnum, U32 transnum);
extern ER usb_lock_readreg(U32 reg);
extern ER usb_RMW_reg(U32 reg, U32 val);
extern ER usb_RMW_clrreg(U32 reg, U32 val);
/*-------------------------------------------------------------------*
* 函数定义
*-------------------------------------------------------------------*/
/*
*批传输:CBW封包
*/
U32 usb_bulk(void)
{
U8 k;
for(k=0; k<31; k++)
MSDevice.dBulkStat.cbw[k] = MSDevice.dCBW.RX[k];
if(MSDevice.dBulkStat.cbw[0] != 0x55)
return -1;
if(MSDevice.dBulkStat.cbw[1] != 0x53)
return -1;
if(MSDevice.dBulkStat.cbw[2] != 0x42)
return -1;
if(MSDevice.dBulkStat.cbw[3] == 0x43)
usb_bulk_cbw();
return 0;
}
U32 usb_bulk_cbw(void)
{
U32 cbwtag;
U8 cbw_len;
U8 ti;
cbwtag = ((MSDevice.dBulkStat.cbw[7]<<24)|(MSDevice.dBulkStat.cbw[6]<<16)|(MSDevice.dBulkStat.cbw[5]<<8)|(MSDevice.dBulkStat.cbw[4]));
MSDevice.dCBW.cbw_dtl = ((MSDevice.dBulkStat.cbw[11]<<24)|(MSDevice.dBulkStat.cbw[10]<<16)|(MSDevice.dBulkStat.cbw[9]<<8)|(MSDevice.dBulkStat.cbw[8]));
MSDevice.dCBW.cbw_direct = MSDevice.dBulkStat.cbw[12];
cbw_len = MSDevice.dBulkStat.cbw[14];
for(ti=0; ti<12; ti++)
MSDevice.dCBW.ufi_cmd[ti] = 0;
for(ti=0; ti<cbw_len; ti++)
MSDevice.dCBW.ufi_cmd[ti] = MSDevice.dBulkStat.cbw[15+ti];
bulk_commmand();
return cbwtag;
}
/*
* UFI 命令解析函数
*/
void bulk_commmand(void)
{
U8 command;
U16 translen;
command = MSDevice.dCBW.ufi_cmd[0];
MSDevice.dBulkData.lblkaddr= (((U32)MSDevice.dCBW.ufi_cmd[2]) << 24) | (((U32)MSDevice.dCBW.ufi_cmd[3]) << 16) | (((U32)MSDevice.dCBW.ufi_cmd[4]) << 8) | ((U32)MSDevice.dCBW.ufi_cmd[5]);
translen = (((U16)MSDevice.dCBW.ufi_cmd[7]) << 8) | ((U16)MSDevice.dCBW.ufi_cmd[8]);
switch(command)
{
case INQUIRY:
MSDevice.dUSBTrans.desc_len = 0x24;
MSDevice.dUSBTrans.head_temp = UInquiry;
MSDevice.dBulkStat.descactu_len = 0x24;
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
MSDevice.dBulkStat.blktrasstate = BULKIN;
break;
case READ:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dBulkData.temblklen = translen;
if(MSDevice.dBulkData.temblklen> LENGH)
{
MSDevice.dBulkData.longblk = LONGBLK;
MSDevice.dBulkData.blktmp = LENGH;
MSDevice.dUSBTrans.desc_len = LENGH*512;
}
else
{
MSDevice.dBulkData.longblk = SHORTBLK;
MSDevice.dBulkData.blktmp = MSDevice.dBulkData.temblklen;
MSDevice.dUSBTrans.desc_len = MSDevice.dBulkData.temblklen*512;
}
#ifdef USBNORFLASH
dev_io_proc(1, (UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf, (UINT16)MSDevice.dBulkData.blktmp, 1);
#endif
#ifdef USBRAMDISK
usbpc_rd_io(0,(UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf,(UINT32)MSDevice.dBulkData.blktmp,1);
#endif
#ifdef USBMMC
mmc_io(2,(UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf, (UINT32)MSDevice.dBulkData.blktmp,1);
#endif
#ifdef USBNANDFLASH
nand_rd_io(3,(UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf, (UINT32)MSDevice.dBulkData.blktmp,1);
#endif
MSDevice.dUSBTrans.head_temp = MSDevice.dUSBTrans.bulkindatebuf;
MSDevice.dBulkStat.descactu_len = translen*512;
MSDevice.dCBW.requlen = translen*512;
break;
case READ_CAPACITY:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dUSBTrans.desc_len = 0x8;
MSDevice.dUSBTrans.head_temp = URead_capacity;
MSDevice.dBulkStat.descactu_len = 0x8;
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
break;
case READ_FORMAT_CAPACITY:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dUSBTrans.desc_len = 0x14;
MSDevice.dUSBTrans.head_temp = URead_format_capacity;
MSDevice.dBulkStat.descactu_len = 0x14;
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
break;
case REQUEST_SENSE:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dUSBTrans.desc_len = 0x12;
MSDevice.dUSBTrans.head_temp = URequest_sense;
MSDevice.dBulkStat.descactu_len = 0x12;
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
break;
case CODE_1A:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dUSBTrans.desc_len = sizeof (Ucode_1A);
MSDevice.dUSBTrans.head_temp = (U32 *)Ucode_1A;
MSDevice.dBulkStat.descactu_len = sizeof (Ucode_1A);
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
break;
case CODE_15:
MSDevice.dBulkStat.blktrasstate = BULKIN;
MSDevice.dUSBTrans.desc_len = sizeof (Ucode_15);
MSDevice.dUSBTrans.head_temp = (U32 *)Ucode_15;
MSDevice.dBulkStat.descactu_len = sizeof (Ucode_15);
MSDevice.dCBW.requlen = MSDevice.dCBW.cbw_dtl;
break;
case WRITE2:
MSDevice.dBulkStat.blktrasstate = BULKOUT;
MSDevice.dBulkData.temblklen = translen;
if(MSDevice.dBulkData.temblklen > LENGH)
{
MSDevice.dBulkData.longblk = LONGBLK;
MSDevice.dBulkData.blktmp = LENGH;
MSDevice.dUSBTrans.desc_len = LENGH*512;
}
else
{
MSDevice.dBulkData.longblk = SHORTBLK;
MSDevice.dBulkData.blktmp = MSDevice.dBulkData.temblklen;
MSDevice.dUSBTrans.desc_len = MSDevice.dBulkData.temblklen*512;
}
MSDevice.dUSBTrans.head_temp = MSDevice.dUSBTrans.bulkindatebuf;
MSDevice.dBulkStat.descactu_len = translen*512;
MSDevice.dCBW.requlen = translen*512;
break;
case TESTUNITREADY :
MSDevice.dBulkStat.unsinglepocket = SINGLE;
break;
case PREVENT :
MSDevice.dBulkStat.unsinglepocket = SINGLE;
MSDevice.dCSW.sing = SI;
break;
default:
break;
}
}
void usb_bulk_csw(void)
{
U32 residue;
MSDevice.dBulkStat.csw[0] = 0x53425355;
MSDevice.dBulkStat.csw[1] = usb_bulk_cbw();
residue = MSDevice.dCBW.requlen - MSDevice.dBulkStat.descactu_len;
MSDevice.dBulkStat.csw[2] = residue;
if(MSDevice.dCSW.sing == UNSI)
{
MSDevice.dBulkStat.csw[3] = 0x00;
}
else
{
MSDevice.dCSW.sing = UNSI;
MSDevice.dBulkStat.csw[3] = 0x01;
}
MSDevice.dCSW.tlengh = 13;
MSDevice.dUSBTrans.head_temp = MSDevice.dBulkStat.csw;
}
U32 transbulk(unsigned char *head)
{
unsigned char *urb;
int j, ti,j1;
U32 P2;
volatile U32 i;
U32 stat,temp = 0;
U32 t;
if(MSDevice.dBulkStat.blktrasstate == BULKIN)
{
/*IN 传输*/
ti = MSDevice.dUSBTrans.desc_len;
urb = head;
if(ti < 64)
{
*(RP)(USB_TXLENGTH) = ti;//包长度不超过64 byte
}
else
{
*(RP)(USB_TXLENGTH) = 64;
}
j = ti/64;
if(MSDevice.dUSBTrans.desc_len < 64)
{
USB_DMA_TRANS_TX((U32)urb,(U32)USB_TXFIFO,0x32,0x32,0x16,CHAN,0x10);
}
else
{
MSDevice.dUSBTrans.longpk = LONGPKSTATE;
USB_DMA_TRANS_TX((U32)urb,(U32)USB_TXFIFO,0x32,0x32,0x16,CHAN,j*0x10);
}
i = *(volatile U32 *)DMACCConfiguration;
while((i & 0x1) != 0)
{
i = *(volatile U32 *)DMACCConfiguration;
}
}
else
{
/*OUT传输*/
ti = MSDevice.dUSBTrans.desc_len;
urb = head;
j=ti/64;
MSDevice.dUSBTrans.usbmod = ti%64;
if(MSDevice.dUSBTrans.desc_len <= 64)
{
USB_DMA_TRANS_RX((U32)USB_RXFIFO,(U32)urb,0x32,0x32,0x16,CHAN,0x10);
}
else
{
MSDevice.dUSBTrans.longpk = LONGPKSTATE;
USB_DMA_TRANS_RX((U32)USB_RXFIFO,(U32)urb,0x32,0x32,0x16,CHAN,j*0x10);
}
i = *(volatile U32 *)DMACCConfiguration;
while((i & 0x1) != 0)
{
i = *(volatile U32 *)DMACCConfiguration;
}
#ifdef USBNORFLASH
dev_io_proc(1,(UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf,(UINT16)MSDevice.dBulkData.blktmp,0);
#endif
#ifdef USBRAMDISK
usbpc_rd_io(0,(UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf,(UINT32)MSDevice.dBulkData.blktmp,0);
#endif
#ifdef USBMMC
mmc_io(0, (UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf, (UINT32)MSDevice.dBulkData.blktmp,0);
#endif
#ifdef USBNANDFLASH
nand_rd_io(3, (UINT32)MSDevice.dBulkData.lblkaddr, MSDevice.dUSBTrans.bulkindatebuf, (UINT32)MSDevice.dBulkData.blktmp,0);
#endif
}
}
/*
* H A _ I N T _ H A N D L E R _ U S B S E R V I C E;获取控制传输阶段主机发送的命令数据
*/
U8 *get_irq_request_cmd(void)
{
static U8 command[8];
command[0] = usb_chang_reg32_to_reg8(USB_EP0OUTBMREQTYPE);
command[1] = usb_chang_reg32_to_reg8(USB_EP0OUTBREQUEST);
command[2] = usb_chang_reg32_to_reg8(USB_EP0OUTWVALUE);
command[3] = usb_get_regbit15_to_8(USB_EP0OUTWVALUE);
command[4] = usb_chang_reg32_to_reg8(USB_EP0OUTWINDEX);
command[5] = usb_get_regbit15_to_8(USB_EP0OUTWINDEX);
command[6] = usb_chang_reg32_to_reg8(USB_EP0OUTWLENGTH);
command[7] = usb_get_regbit15_to_8(USB_EP0OUTWLENGTH);
return command;
}
void usb_irq_setup(void)
{
U8* command_request;
command_request = get_irq_request_cmd();
pdc_bus_ctrl_pipe_notificaion(PDC_SETUP_COMMAND, command_request);
if(MSDevice.dUSBStat.setconstate == SETCONFIG)
{
MSDevice.dUSBStat.setconstate = NSETCONFIG;
}
else
{
transcl((unsigned char *)MSDevice.dUSBTrans.head_temp);
}
return;
}
U32 pdc_bus_ctrl_pipe_notificaion(unsigned long notif_type, unsigned char *cmd)
{
U8 RequestType;
U8 bmRequest ;
if(notif_type == PDC_SETUP_COMMAND)
{
RequestType = cmd[0] & 0x60;
switch(RequestType)
{
case STANDARD_REQUEST:
/* 执行主机的标准请求 */
bmRequest = cmd[1];
switch (bmRequest)
{
case GET_DESCRIPTOR:
usb_RMW_reg(USB_EP0OUTSTAT,0x0a);
pdc_bus_get_descriptor(cmd);
break;
case SET_CONFIGURATION:
usb_RMW_reg(USB_EP0OUTSTAT,0x0a);
pdc_bus_SET_CONFIGURATION();
MSDevice.dUSBStat.setconstate = SETCONFIG;
break;
default:
usb_RMW_reg(USB_EP0OUTSTAT,0x0a);
break;
}
case CLASS_REQUEST:
/*执行主机的类请求*/
usb_RMW_reg(USB_EP0OUTSTAT,0x0a);
bmRequest = cmd[1];
/*bulk-only类请求 -get max LUN */
if(bmRequest == 0xFE)
{
MSDevice.dUSBTrans.head_temp = (U32*)(unsigned char*)empty;
MSDevice.dUSBTrans.desc_len = 1;
}
/*bulk-only 类请求-Mass Storage reset */
else if(bmRequest == 0xFF)
{
MSDevice.dUSBStat.usbdmapp = NAPP;
MSDevice.dUSBTrans.head_temp = (U32*)NULL;
MSDevice.dUSBTrans.desc_len = 1;
MSDevice.dUSBTrans.longpk = SHORTPK;
MSDevice.dUSBTrans.usbmod = 0;
MSDevice.dBulkStat.blkstate = BLKCMD;
MSDevice.dBulkStat.unsinglepocket = UNSINGLE;
}
break;
case VENDOR_REQUEST:
/*执行厂商特定请求*/
break;
default:
usb_RMW_reg(USB_EP0OUTSTAT,0x0a);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -