📄 myudisk.c
字号:
//I think that EP0_SENT_STALL will not be set to 1.
if(ep0_csr & EP0_SENT_STALL)
{
DbgPrintf("[STALL]");
CLR_EP0_SENT_STALL();
if(ep0_csr & EP0_OUT_PKT_READY)
{
CLR_EP0_OUT_PKT_RDY();
}
ep0State=EP0_STATE_INIT;
return;
}
if((ep0_csr & EP0_OUT_PKT_READY) && (ep0State==EP0_STATE_INIT))
{
RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE); //注此处直接就是获得建立阶段的数据包。其中的包头信息在硬件中已经处理过了
PrintEp0Pkt((U8 *)(&descSetup)); //DEBUG
switch(descSetup.bRequest) //关于这部分的内容,详见USB协议说明
{
case GET_DESCRIPTOR:
switch(descSetup.bValueH)
{
case DEVICE_TYPE:
DbgPrintf("[GDD]");
CLR_EP0_OUT_PKT_RDY();
ep0State=EP0_STATE_GD_DEV_0; //在下面一个case中发送设备类型信息
break;
case CONFIGURATION_TYPE:
DbgPrintf("[GDC]");
CLR_EP0_OUT_PKT_RDY();
if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)//bLengthH should be used for bLength=0x209 at WIN2K.
ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K
else
ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K
break;
case STRING_TYPE:
DbgPrintf("[GDS]");
CLR_EP0_OUT_PKT_RDY();
break;
case INTERFACE_TYPE:
DbgPrintf("[GDI]");
CLR_EP0_OUT_PKT_RDY();
break;
case ENDPOINT_TYPE:
DbgPrintf("[GDE]");
CLR_EP0_OUT_PKT_RDY();
break;
default:
DbgPrintf("[UE:GD?]");
break;
}
break;
case SET_ADDRESS:
DbgPrintf("[SA:%d]",descSetup.bValueL);
rFUNC_ADDR_REG=descSetup.bValueL | 0x80; //更新USB地址
CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
ep0State=EP0_STATE_INIT;
break;
case SET_CONFIGURATION:
DbgPrintf("[SC]");
CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
ep0State=EP0_STATE_INIT;
break;
//////////////////////// For chapter 9 test ////////////////////
case CLEAR_FEATURE:
DbgPrintf("[CF]");
CLR_EP0_OUTPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
case GET_CONFIGURATION:
DbgPrintf("[GC]");
CLR_EP0_OUT_PKT_RDY();
ep0State=EP0_CONFIG_SET;
break;
case GET_INTERFACE:
DbgPrintf("[GI]");
CLR_EP0_OUT_PKT_RDY();
ep0State=EP0_INTERFACE_GET;
break;
case GET_STATUS:
DbgPrintf("[GS]");
CLR_EP0_OUT_PKT_RDY();
break;
case SET_DESCRIPTOR:
DbgPrintf("[SD]");
CLR_EP0_OUTPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
case SET_FEATURE:
DbgPrintf("[SD]");
CLR_EP0_OUTPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
case SET_INTERFACE:
DbgPrintf("[SI]");
CLR_EP0_OUTPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
case SYNCH_FRAME:
DbgPrintf("[SF]");
ep0State=EP0_STATE_INIT;
break;
//////////////////////////////////////////////////////////////
case GET_MAX_LUN://存储设备的命令
DbgPrintf("[GET_MAX_LUN]");
CLR_EP0_OUT_PKT_RDY();
ep0State=0xf3;
break;
default:
DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest);
CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
ep0State=EP0_STATE_INIT;
break;
}
}
switch(ep0State)
{
case EP0_STATE_INIT:
break;
case 0xf3:
temp = 0x01;
WrPktEp0((U8 *)&temp,1); //EP0_PKT_SIZE
SET_EP0_INPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
//=== GET_DESCRIPTOR:DEVICE ===
case EP0_STATE_GD_DEV_0:
DbgPrintf("[GDD0]");
WrPktEp0((U8 *)&Device_Descriptor+0,8); //EP0_PKT_SIZE
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_DEV_1;
break;
case EP0_STATE_GD_DEV_1:
DbgPrintf("[GDD1]");
WrPktEp0((U8 *)&Device_Descriptor+8,8);
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_DEV_2;
break;
case EP0_STATE_GD_DEV_2:
DbgPrintf("[GDD2]");
WrPktEp0((U8 *)&Device_Descriptor+0x10,2); //8+8+2=0x12
SET_EP0_INPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
//=== GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 ===
//Windows98 gets these 4 descriptors all together by issuing only a request.
//Windows2000 gets each descriptor seperately.
case EP0_STATE_GD_CFG_0:
DbgPrintf("[GDC0]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+0,8); //EP0_PKT_SIZE
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_CFG_1;
break;
case EP0_STATE_GD_CFG_1:
DbgPrintf("[GDC1]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+8,8);
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_CFG_2;
break;
case EP0_STATE_GD_CFG_2:
DbgPrintf("[GDC2]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+16,8);
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_CFG_3;
break;
case EP0_STATE_GD_CFG_3:
DbgPrintf("[GDC3]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+24,8);
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_CFG_4;
break;
case EP0_STATE_GD_CFG_4:
DbgPrintf("[GDC4]");
//zero length data packit
SET_EP0_INPKTRDY_DATAEND(); //表明数据阶段通讯结束
ep0State=EP0_STATE_INIT;
break;
//=== GET_DESCRIPTOR:CONFIGURATION ONLY===
case EP0_STATE_GD_CFG_ONLY_0:
DbgPrintf("[GDCO0]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+0,8); //EP0_PKT_SIZE
SET_EP0_IN_PKT_RDY();
ep0State=EP0_STATE_GD_CFG_ONLY_1;
break;
case EP0_STATE_GD_CFG_ONLY_1:
DbgPrintf("[GDCO1]");
WrPktEp0((U8 *)&Configuration_Descriptor_All+8,1);
SET_EP0_INPKTRDY_DATAEND();
ep0State=EP0_STATE_INIT;
break;
//=== GET_DESCRIPTOR:INTERFACE ONLY===
case EP0_STATE_GD_IF_ONLY_0:
DbgPrintf("[GDI0]");
ep0State=EP0_STATE_GD_IF_ONLY_1;
break;
default:
DbgPrintf("UE:G?D");
break;
}
rINDEX_REG=save ;
}
/**********************************************************************
// 描 述:
// 返 回: void
// 参 数: void
// gyj
// 如果上一包数据被读走的情况下,则IN_PKT_READY被清零产生中断
// 那么此处处理这个中断已准备好下一次要发送的数据
**********************************************************************/
void Ep1Handler(void)
{
U8 in_csr1;
int save = 0;
save = rINDEX_REG ;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<1:%x]",in_csr1);
//I think that EPI_SENT_STALL will not be set to 1.
if(in_csr1 & EPI_SENT_STALL)
{
//USB控制器返回告诉MCU已经往USB主机发送了一个STALL命令。
DbgPrintf("[STALL]");
CLR_EP1_SENT_STALL();
return;
}
if ((g_iIN_NextCount != 0)&&(g_pIN_NextData != NULL))
{
if (g_iIN_NextCount > BULK_PKT_SIZE) //要分成多包发送
{
WrPktEp1(g_pIN_NextData,BULK_PKT_SIZE);
g_pIN_NextData = g_pIN_NextData +BULK_PKT_SIZE;
g_iIN_NextCount = g_iIN_NextCount -BULK_PKT_SIZE;
}
else
{
WrPktEp1(g_pIN_NextData,g_iIN_NextCount); //最后一包
g_pIN_NextData = NULL; //
g_iIN_NextCount = 0; //
}
SET_EP1_IN_PKT_READY();
}
else if (g_iInNeeded == TRUE)
{
TransmitCSW();
g_iInNeeded =FALSE;
}
rINDEX_REG=save ;
return;
}
/**********************************************************************
// 描 述: 接收Out端点上发来的命令并且做出回应
// 注: IN端点和OUT端点的协调传输是这里的关键,当然如果想例子程序那样,
// 以查询的方式进行数据的传输的话会相对比较的简单一些。
// 返 回: void
// 参 数: void
**********************************************************************/
void Ep3Handler(void)
{
U8 out_csr3;
int i;
int fifoCnt;
int save = 0;
save = rINDEX_REG ;
rINDEX_REG=3;
out_csr3=rOUT_CSR1_REG;
DbgPrintf("<3:%x]",out_csr3);
//I think that EPO_SENT_STALL will not be set to 1.
if(out_csr3 & EPO_SENT_STALL)
{
DbgPrintf("[STALL]");
CLR_EP3_SENT_STALL();
return;
}
//接收缓冲区中已经有数据了
if(out_csr3 & EPO_OUT_PKT_READY)
{
fifoCnt=rOUT_FIFO_CNT1_REG; //收到的数据的字节个数
RdPktEp3((U8 *)ep3Buf,fifoCnt);
CLR_EP3_OUT_PKT_READY();
rINDEX_REG=3;
out_csr3=rOUT_CSR1_REG;
DbgPrintf("<6_3:%x]",out_csr3);
bulk_CSW[4] = ep3Buf[4];
bulk_CSW[5] = ep3Buf[5];
bulk_CSW[6] = ep3Buf[6];
bulk_CSW[7] = ep3Buf[7];
for(i=0;i<12;i++) bulk_CBW.CBWCB[i] = ep3Buf[i+15];
switch(bulk_CBW.CBWCB[0])
{
case Inquiry :SCSI_Get_Inquery(); break;
case Mode_Sense :SCSI_Mode_Sense(); break;
case Read10 :SCSI_Read10(); break;
case Read_Capacity :SCSI_Read_Capacity(); break;
case Read_Format_Capacities:SCSI_Read_Format_Capacities();break;
case Test_Unit_Ready:TransmitCSW(); break;
case Verify :TransmitCSW(); break;
case Medium_Removal :TransmitCSW(); break;
case Write10 :SCSI_Write10(); break;
}
}
rINDEX_REG=save ;
return;
}
//////////////////////////////////////////////////////////////////////////
void TransmitCSW(void)//传送状态字
{
U8 in_csr1;
int isave = 0;
isave = rINDEX_REG;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<TransmitCSW]\r\n");
WrPktEp1(bulk_CSW,sizeof(bulk_CSW)); //一个数据包就足够返回所有数据了
g_pIN_NextData =NULL;
g_iIN_NextCount= 0;
g_iInNeeded =FALSE;
SET_EP1_IN_PKT_READY();
rINDEX_REG = isave;
}
void SCSI_Read_Capacity(void)
{
U8 in_csr1;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<Read_Capacity]");
WrPktEp1(B_Read_Capacity,sizeof(B_Read_Capacity));
g_pIN_NextData =NULL;
g_iIN_NextCount= 0;
g_iInNeeded = TRUE;
SET_EP1_IN_PKT_READY();
}
void SCSI_Get_Inquery(void)
{
U8 in_csr1;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<Get_Inquery]");
WrPktEp1(B_InquiryData,32); //注:B_InquiryData中有36个字节,那么一包数据搞不定,需要两包
g_pIN_NextData = B_InquiryData + 32; //剩下的一包数据在Ep1的中断中去发送
g_iIN_NextCount= 4;
g_iInNeeded = TRUE;
SET_EP1_IN_PKT_READY();
}
void SCSI_Mode_Sense(void)
{
U8 in_csr1;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<Mode_Sense]");
if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP) //Page Code=Timer and Potect Page
{WrPktEp1(B_Mode_Sense_TPP,sizeof(B_Mode_Sense_TPP));}
else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL) //Page Code=All
{WrPktEp1(B_Mode_Sense_ALL,sizeof(B_Mode_Sense_ALL));}
else
{WrPktEp1(B_Mode_Sense_ZERO,sizeof(B_Mode_Sense_ZERO));}
g_pIN_NextData = NULL; //需要传输的数据在一包里就能够搞定了!
g_iIN_NextCount= 0;
g_iInNeeded = TRUE;
SET_EP1_IN_PKT_READY();
}
///////////////////////////////////////////////////////////////////////////
void SCSI_Read_Format_Capacities(void)
{
U8 in_csr1;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<Read_Format]");
if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)return; //Host要求返回的数据长度
WrPktEp1(B_Read_Format_capacities,sizeof(B_Read_Format_capacities)); //
g_pIN_NextData = NULL; //需要传输的数据在一包里就能够搞定了!
g_iIN_NextCount= 0;
g_iInNeeded = TRUE;
SET_EP1_IN_PKT_READY();
}
/////////////////////////////////////////////////////////////////////////
void SCSI_Read10(void)//FLASH读处理函数
{
int iLBA;
unsigned char length;
U8 in_csr1;
rINDEX_REG=1;
in_csr1=rIN_CSR1_REG;
DbgPrintf("<Read10]");
/*读操作的扇区起始地址*/
iLBA = bulk_CBW.CBWCB[5] + (bulk_CBW.CBWCB[4]<<8);
length = bulk_CBW.CBWCB[8];
if ((iLBA+length)*512 >= 0x2000000) //总量为32M
{
return ;
}
g_pIN_NextData = (unsigned char *)(MY_UDISK_STARTADDR + iLBA*512);
WrPktEp1(g_pIN_NextData,32); //先发送第一个数据包,在中断处理函数中接着发送后续的包
g_pIN_NextData = g_pIN_NextData + 32; //第二包在中断中发送
g_iIN_NextCount = length*512 - 32; //需要发送的字节数
g_iInNeeded = TRUE; //在所有的数据发送完成之后要接着CSW应答包
SET_EP1_IN_PKT_READY(); //
}
/////////////////////////////////////////////
void SCSI_Write10(void) //FLASH写操作
{
U8 out_csr3;
int fifoCnt;
int iLBA;
unsigned char length;
int i;
DbgPrintf("<Write1010]");
/*读操作的扇区起始地址*/
iLBA = bulk_CBW.CBWCB[5] + (bulk_CBW.CBWCB[4]<<8);
length = bulk_CBW.CBWCB[8]; //给出的是扇区数
if ((iLBA+length)*512 >= 0x2000000) //总量为32M
{
return ;
}
g_pOUT_NextData = (unsigned char *)(MY_UDISK_STARTADDR+iLBA*512); //目的地的起始地址
g_iOUT_NextCount = length*512; //需要接收的数据的长度
DbgPrintf("<AllCount = %d]",g_iOUT_NextCount);
while (g_iOUT_NextCount > 0) //等到把数据接收完成
{
rINDEX_REG=3;
out_csr3=rOUT_CSR1_REG;
while (!(out_csr3 & EPO_OUT_PKT_READY)) //一直等待直到数据到来
{
out_csr3 = rOUT_CSR1_REG;
}
fifoCnt=rOUT_FIFO_CNT1_REG; //收到的数据的字节个数
RdPktEp3((U8 *)ep3Buf,fifoCnt);
CLR_EP3_OUT_PKT_READY();
for (i=0;i<fifoCnt;i++)
{
g_pOUT_NextData[i] = ep3Buf[i];
}
g_pOUT_NextData = g_pOUT_NextData + fifoCnt;
g_iOUT_NextCount = g_iOUT_NextCount - fifoCnt;
DbgPrintf("<Count = %d]",g_iOUT_NextCount);
}
g_pOUT_NextData = NULL;
g_iOUT_NextCount = 0;
TransmitCSW();
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -