⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myudisk.c

📁 这是我学USB时候
💻 C
📖 第 1 页 / 共 2 页
字号:
    //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 + -