📄 gfd_usb_hl.c
字号:
while(1);
}
if(evnt & traerr)
{
usb_RMW_clrreg(USB_INTR,0x7fffffef);
while(1);
}
}
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;
}
/* 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;
}
/*响应主机的OUT 请求*/
ER OUTINTR(void)
{
U32 t1,t2,compare0,compare1;
int ti,j;
ER stat;
volatile U32 i;
stat = usb_lock_readreg(USB_EPINFO);
if((stat &= 0x1f) != 0x0)
{
/*BLKCMD 阶段*/
if(MSDevice.dBulkStat.blkstate == BLKCMD)
{
usb_write_reg((U32)USB_INTRMASK, 0x176);
t2 = *(RP)(USB_RECEIVETYPE) & 0x4;
while((t2 == 0x0))
{
t2 = *(RP)(USB_RECEIVETYPE) & 0X4;
}
if(t2 == 0x4)
{
/*CBW 阶段*/
MSDevice.dUSBStat.usbdmapp = APP;
memset(MSDevice.dCBW.RX,0,64);
USB_DMA_TRANS_RX((U32)USB_RXFIFO,(U32)MSDevice.dCBW.RX,0x32,0x32,0x16,CHAN,0x10);
i = *(volatile U32 *)DMACCConfiguration;
while((i & 0x1) != 0)
{
i = *(volatile U32 *)DMACCConfiguration;
}
compare0=(MSDevice.dCBW.RX[3]<<24)|(MSDevice.dCBW.RX[2]<<16)|(MSDevice.dCBW.RX[1]<<8)|MSDevice.dCBW.RX[0];
compare1=(MSDevice.dCBW.RX[7]<<24)|(MSDevice.dCBW.RX[6]<<16)|(MSDevice.dCBW.RX[5]<<8)|MSDevice.dCBW.RX[4];
if((compare0== device_desc[0])&&(compare1== device_desc[1]))
while(1)
;
else
while(1)
;
}
}
}
else
{
*(RP)USB_RECEIVETYPE &= 0x07;
}
return(0);
}
void pdc_bus_SET_CONFIGURATION(void)
{
}
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;
}
}
return 0;
}
void pdc_bus_get_descriptor(U8 *command)
{
U16 req_len;
U8 des_tmp;
switch( command[3])
{
case PDC_DEV_DESC_TYPE:
MSDevice.dUSBTrans.head_temp = device_desc;
MSDevice.dUSBTrans.desc_len = 0x12;
break;
case PDC_CONFIG_DESC_TYPE:
MSDevice.dUSBTrans.head_temp = conf_desc;
des_tmp = command[6]|(command[7]<<8);
MSDevice.dUSBTrans.desc_len = (des_tmp > 0x20)? 0x20 : des_tmp;
if(des_tmp > 0x20)
MSDevice.dCtrlTrans.statempty = EMPTY;
break;
case PDC_STRING_DESC_TYPE:
switch(command[2])
{
case 0:
MSDevice.dUSBTrans.head_temp = (U32*)(unsigned char *)unicode_string;
MSDevice.dUSBTrans.desc_len = sizeof(unicode_string);
break;
case 1:
MSDevice.dUSBTrans.head_temp = (U32*)(unsigned char *)mfg_string;
MSDevice.dUSBTrans.desc_len = sizeof(mfg_string);
break;
case 2:
MSDevice.dUSBTrans.head_temp = (U32*)(unsigned char *)product_string;
MSDevice.dUSBTrans.desc_len = sizeof(product_string);
break;
case 3:
MSDevice.dUSBTrans.head_temp = (U32*)(unsigned char *)serial_string;
MSDevice.dUSBTrans.desc_len = sizeof(serial_string);
break;
default:
break;
}
break;
default:
break;
}
//urb
if(MSDevice.dUSBTrans.head_temp)
{
/*传输所要求的长度的数据 */
req_len =command[6]|(command[7]<<8);
if (MSDevice.dUSBTrans.desc_len > req_len )
{
MSDevice.dUSBTrans.desc_len = req_len ;
}
}
}
U32 transcl(unsigned char *head)
{
unsigned char *urb;
int j, ti;
U32 t;
ti = MSDevice.dUSBTrans.desc_len;
urb = head;
if(ti < 8)
{
*(RP)(USB_TXLENGTH) = ti;//SETUP事务的数据包长度每次不超过8个字节--由硬件决定
}
else
{
*(RP)(USB_TXLENGTH) = 8;
}
j=ti/8;
MSDevice.dUSBTrans.usbmod = ti%8;
if(MSDevice.dUSBStat.usbstate == USBCG)
{
if(MSDevice.dUSBTrans.desc_len <= 8)
{
USB_DMA_TRANS_TX((U32)urb,(U32)USB_TXFIFO,0x32,0x32,0x16,CHAN,0x10);
}
else
{
MSDevice.dUSBTrans.longpk = LONGPKSTATE;
MSDevice.dUSBTrans.longurb = head + j*64;
if(MSDevice.dUSBTrans.usbmod ||(MSDevice.dCtrlTrans.statempty == EMPTY))
{
MSDevice.dUSBStat.usbdmapp = APP;
}
else if (!MSDevice.dUSBTrans.usbmod)
{
MSDevice.dUSBTrans.longpk = SHORTPK;
}
USB_DMA_TRANS_TX((U32)urb,(U32)USB_TXFIFO,0x32,0x32,0x16,CHAN,j*0x10);
}
}
else //第一个包传输
{
MSDevice.dUSBStat.usbstate = USBCG;//标志配置主机
USB_DMA_TRANS_TX((U32)urb,(U32)USB_TXFIFO,0x32,0x32,0x16,CHAN,0x10);
}
}
U32 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;
}
}
}
/*
*批传输: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;
}
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -