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

📄 ch375.c

📁 CH375按照从设备外置固件模式
💻 C
📖 第 1 页 / 共 3 页
字号:
       buff1[i]=0x0;
    buff1[0]=0xf8;
    buff1[1]=0xff;
    //==========================================
    //first FAT
    addr=0x200;
    for (i=0;i<512;i++)
        USBDISK[addr++] = buff1[i];
    buff1[0] = 0;
    buff1[1] = 0;    
    for(j=0;j<15;j++)
	 for (i=0;i<512;i++)
        USBDISK[addr++] = buff1[i];
    //===========================================   
    buff1[0]=0xf8;
    buff1[1]=0xff;
    //second FAT
    for (i=0;i<512;i++)
        USBDISK[addr++] = buff1[i];
    buff1[0] = 0;
    buff1[1] = 0;    
    for(j=0;j<15;j++)
	 for (i=0;i<512;i++)
        USBDISK[addr++] = buff1[i];
    //===========================================
	//direction
	for(j=0;j<32;j++)
	 for (i=0;i<512;i++)
        USBDISK[addr++] = buff1[i];
}


//==================================
void UsbDeviceInit(void)
{
	Uart_Printf("begin usb device!\n"); 		
	CH375_WR_CMD_PORT( CMD_SET_USB_ID ); 				  		// 设置外部自定义的USB设备VID和PID,可选操作
 	CH375_WR_DAT_PORT( (unsigned char)MY_USB_VENDOR_ID ); 		// 写入厂商ID的低字节
 	CH375_WR_DAT_PORT( (unsigned char)(MY_USB_VENDOR_ID>>8) );  // 写入厂商ID的高字节
 	CH375_WR_DAT_PORT( (unsigned char)MY_USB_DEVICE_ID ); 		// 写入设备ID的低字节
 	CH375_WR_DAT_PORT( (unsigned char)(MY_USB_DEVICE_ID>>8) ); 	// 写入设备ID的高字节
	if (set_usb_mode(1) )  			 // 设置USB从机外置固件模式
	   Uart_Printf("Set device mode done!\n");
    SystemStatus = CBWIdle;
}

void ProcessCSW(void)
{
		
			   //Uart_Printf("CSW\n");
		       SystemStatus = CBWIdle;
		       SystemBuffer[0] = 0x55;//
		       SystemBuffer[1] = 0x53;
		       SystemBuffer[2] = 0x42;
		       SystemBuffer[3] = 0x53;
		       SystemBuffer[4] = dCBWTag[0];             //在CSW中返回
			   SystemBuffer[5] = dCBWTag[1];
			   SystemBuffer[6] = dCBWTag[2];
			   SystemBuffer[7] = dCBWTag[3];
				//dCSWDataResidue
			   SystemBuffer[8]  =((unsigned char*)&dCBWDataTransferLength)[0];
			   SystemBuffer[9]  =((unsigned char*)&dCBWDataTransferLength)[1];
			   SystemBuffer[10] =((unsigned char*)&dCBWDataTransferLength)[2];
			   SystemBuffer[11] =((unsigned char*)&dCBWDataTransferLength)[3];
			   SystemBuffer[12] =  0x0; //bCSWStatus
		       wr_usb_data(13,SystemBuffer);
}

// CH375中断服务程序,CH375的INT#引脚连接到eint0
void __irq CH375Interrupt(void)
{
	unsigned char InterruptStatus;
	unsigned char length, len,c1,CH375FLAGERR;
	unsigned char cbw_error;
	unsigned char  point;
	unsigned char tmp,command;
	rI_ISPC=BIT_EINT0;	
	CH375_WR_CMD_PORT(CMD_GET_STATUS);       //获取中断状态并取消中断请求 
	delay2us();
	CH375FLAGERR =0;
 	InterruptStatus = CH375_RD_DAT_PORT();   //获取中断状态
 	//Uart_Printf("InterruptStatus:%02x\n",InterruptStatus);
 	switch( InterruptStatus ) 				 //分析中断状态
	{
		case    USB_INT_EP2_OUT:   		     // 批量端点下传成功
		        CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); //从当前USB中断的端点缓冲区读取数据块,并释放缓冲区
			 	length = CH375_RD_DAT_PORT(); //首先读取后续数据长度
			 	if ( length != 0 )  		   //如果长度为0则不处理
			 	{
			    	for (len=0;len<length;len++)
			      	{
			      		SystemBuffer[len] = CH375_RD_DAT_PORT();
			      		//Uart_Printf("%02x ",SystemBuffer[len]);
			      		delay2us();
			      	}
			      	//Uart_Printf("\n");
			 	}
			 	//============CBW===============
			 	if (SystemStatus ==CBWIdle)//处理命令状态
			 	{
			 	  	cbw_error = FALSE;
  					point=0;
  	    			if(SystemBuffer[0]!=0x55)
				      cbw_error=TRUE;
				 	if(SystemBuffer[1]!=0x53)
				      cbw_error=TRUE;
				 	if(SystemBuffer[2]!=0x42)
				      cbw_error=TRUE;
				 	if(SystemBuffer[3]!=0x43)
				      cbw_error=TRUE;
				   
				  	dCBWTag[0] = SystemBuffer[4];             //在CSW中返回
				  	dCBWTag[1] = SystemBuffer[5];
				  	dCBWTag[2] = SystemBuffer[6];
				  	dCBWTag[3] = SystemBuffer[7];
				  	((unsigned char*)&dCBWDataTransferLength)[0] = SystemBuffer[8];//dCBWDataTransferLength
				  	((unsigned char*)&dCBWDataTransferLength)[1] = SystemBuffer[9];
				  	((unsigned char*)&dCBWDataTransferLength)[2] = SystemBuffer[10];
				  	((unsigned char*)&dCBWDataTransferLength)[3] = SystemBuffer[11];
				   	if (SystemBuffer[12] != 0x00)   // store bmCBWFlags.bit7
				    {                                  //数据从设备向host传输 in
				    	//Usb_CBWFlag_in();
				    }
				    else
				    {
				       //Usb_CBWFlag_out();
				    }
				    //only 1 drive supported 
				    SendFlag = 0x01;
				    tmp = SystemBuffer[13];                  // dummy LUN read 
				    CBWCBLength = SystemBuffer[14];          // dummy CBWCBLength read 
				    command=SystemBuffer[15];	
					//Uart_Printf("Length=%d,Command=%02x\n",dCBWDataTransferLength,command);
				    switch(command)
				    {
				       case 0x03://request sense
					            dCBWDataTransferLength=0;
				                wr_usb_data(14,request_tab3);
				                SystemStatus = CSWSend;
				       break; 
				       case 0x12://inquiry
				       			dCBWDataTransferLength=0;
								wr_usb_data(36,Inquiry_tab);
								SystemStatus = CSWSend;
				       break;
				       case 0x1e:
				       			ProcessCSW();
				       break;
				       case 0x23://read format capacities
				       			dCBWDataTransferLength=0xe8;//0xfc-0x14 
								wr_usb_data(20,FormatCapacities);
								SystemStatus = CSWSend;
				       break;
				       case 0x25://read capacity
								dCBWDataTransferLength=0;
				  				wr_usb_data(8,Capacity_tab);
				  				SystemStatus = CSWSend;
					   break;
				       case 0x28://read 10
				             tmp = SystemBuffer[16];//usefuless data
				            ((unsigned char*)&LBA_adder)[3] =   SystemBuffer[17];
							((unsigned char*)&LBA_adder)[2] =   SystemBuffer[18];
							((unsigned char*)&LBA_adder)[1] =   SystemBuffer[19];
							((unsigned char*)&LBA_adder)[0] =   SystemBuffer[20];	
				            ((unsigned char*)&BlockLength)[1] = SystemBuffer[22];
							((unsigned char*)&BlockLength)[0] = SystemBuffer[23];//逻辑块数
							//Block = LBA_adder/20;
				            //Page  = LBA_adder%20;
				           	//Read_Page(Block,Page,SystemBuffer);
				           	//Uart_Printf("\n LBA=%X BLOCK=%d \n",LBA_adder,BlockLength);
				           	SystemStatus  = CBWSend;
				            UsbWritePoint = LBA_adder*512;
				           	//发出一包数据
				           	wr_usb_data(64,&USBDISK[UsbWritePoint]);
				           	UsbWritePoint+=64;
				           	dCBWDataTransferLength-=64;
				           	SendFlag = 0x01;
						break;
				      case 0x2a://write 10
				             tmp =SystemBuffer[16];//usefuless data
				            ((unsigned char*)&LBA_adder)[3] =   SystemBuffer[17];
							((unsigned char*)&LBA_adder)[2] =   SystemBuffer[18];
							((unsigned char*)&LBA_adder)[1] =   SystemBuffer[19];
							((unsigned char*)&LBA_adder)[0] =   SystemBuffer[20];	
				            ((unsigned char*)&BlockLength)[1] = SystemBuffer[22];
							((unsigned char*)&BlockLength)[0] = SystemBuffer[23];
							Block = LBA_adder/20;
				            Page  = LBA_adder%20;
				            SystemStatus = CBWReceive;
				            UsbWritePoint = LBA_adder*512;
				        break;
				      case 0x5a://MODE SENSE
				      		if (SystemBuffer[17]==0x1c)
				      		{
				  			   wr_usb_data(16,ModeSense_1c);
				  			   dCBWDataTransferLength=0;
				  			   SystemStatus = CSWSend;
				  			}
				  			else if (SystemBuffer[17]==0x3f)
				  			{
				  				wr_usb_data(64,ModeSense_3f);
				  				dCBWDataTransferLength=8;
				  				SystemStatus = CBWSend;
				   				SendFlag = 0x02;
				  			}
				  			
				        break;  
				      case 0x1a:
			  			   wr_usb_data(4,command1a);
						   dCBWDataTransferLength=0xbc;
				  		   SystemStatus = CSWSend;
				       break;  
				      case 0://test unit ready
				      ProcessCSW();
				        break;
				    } //end switch
			     }//if cbwidle
				else  if (SystemStatus ==CBWReceive)
			 	{ 
			      	if (dCBWDataTransferLength>0)
		       		{
		    	  		//wr_usb_data(64,&USBDISK[UsbWritePoint]);
		    	  		for (len=0;len<length;len++)
		    	  		   USBDISK[UsbWritePoint++]=SystemBuffer[len];
				  		dCBWDataTransferLength-=64;
		       		}
		    		else   
		    		{	
		    			ProcessCSW();
		    		}
			 	}
		    break;
		case   USB_INT_EP2_IN: //批量端点上传成功
		    if (SystemStatus ==CBWSend)
			{
			   //Uart_Printf("*");
			   if (SendFlag == 0x01)
			   {
				   if (dCBWDataTransferLength>0)
			       {
			          wr_usb_data(64,&USBDISK[UsbWritePoint]);
					  UsbWritePoint+=64;
					  dCBWDataTransferLength-=64;
			       }
			    	else   	
			    		ProcessCSW();
			  }
			  else if(SendFlag == 0x02)
			  {
		    	  wr_usb_data(8,&ModeSense_3f[64]);
		    	  SystemStatus = CSWSend;
			  }
			}
		    else if (SystemStatus == CSWSend)//csw
		    {
		       ProcessCSW();
		    }
			CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); //释放缓冲区
			break;
			
	//==========================================================================
	 case   USB_INT_EP0_SETUP: 											//控制端点建立成功
	    	CH375_WR_CMD_PORT(CMD_RD_USB_DATA);
	    	//EZUSB_Delay(20);
	    	delay2us();
			length=CH375_RD_DAT_PORT();
			for( len=0;len<length;len++ )
			{
				   Request.buffer[len] = CH375_RD_DAT_PORT();   // 取出数据
				   //Uart_Printf("[%02x] ",Request.buffer[len]);
				   delay2us();
			 }
			//Uart_Printf("\n"); // 取出数据
			
			if(length==0x08)
			{
			    mVarSetupLength=Request.buffer[6];	//控制传输数据长度最大设置为128
				//if((c1=Request.r.bmReuestType)&0x40)
				//{         					 //厂商请求,未处理
				//}
				if((c1=Request.r.bmReuestType)&0x20)
				{// printf("b\n");         					//类请求,未处理
					if(Request.buffer[1]==0x0a)
					{
					  //Uart_Printf("c\n");
					}										//SET_IDLE
					else if( (Request.buffer[0]==0xa1)&&(Request.buffer[1]==0xff) )
					{
							Request.buffer[0]=0;
					}
					CH375FLAGERR=0;
				}
				else if(!((c1=Request.r.bmReuestType)&0x60))
				{          				//标准请求
					mVarSetupRequest=Request.r.bRequest;			//暂存标准请求码
					switch(Request.r.bRequest)
					{  // 分析标准请求
						  
						case DEF_USB_CLR_FEATURE:					//清除特性
							if((c1=Request.r.bmReuestType&0x1F)==0X02)
							{					//不是端点不支持
								switch(Request.buffer[4])
								{
									case 0x82:
										CH375_WR_CMD_PORT(CMD_SET_ENDP7);					//清除端点2上传
										CH375_WR_DAT_PORT(0x8E);                			//发命令清除端点
										break;
									case 0x02:
										CH375_WR_CMD_PORT(CMD_SET_ENDP6);
										CH375_WR_DAT_PORT(0x80);							//清除端点2下传
										break;
									case 0x81:
										CH375_WR_CMD_PORT(CMD_SET_ENDP5);					//清除端点1上传
										CH375_WR_DAT_PORT(0x8E);
										break;
									case 0x01:
										CH375_WR_CMD_PORT(CMD_SET_ENDP4);					//清除端点1下传
										CH375_WR_DAT_PORT(0x80);
										break;
									default:
										break;
								}
							}
							else
							{
								CH375FLAGERR=1;								//不支持的清除特性,置错误标志
							}
							break;
						case DEF_USB_GET_STATUS:								//获得状态
							Request.buffer[0]=0;
							Request.buffer[1]=0;								//上传状态
							break;
						case DEF_USB_SET_ADDRESS:								//设置地址
							   VarUsbAddress=Request.buffer[2];					//暂存USB主机发来的地址
							   //CH375_WR_CMD_PORT(CMD_SET_USB_ADDR);
							   //CH375_WR_DAT_PORT(VarUsbAddress);	
							   //delay2us();
							   //Uart_Printf("new adderss:%d\n",VarUsbAddress);
							break;
						  case DEF_USB_GET_DESCR: 								//获得描述符
								if(Request.buffer[3]==1)							//设备描述符上传
								{
									VarSetupDescr=DevDes;
									mVarSetupLength=sizeof(DevDes);
								}
								else if(Request.buffer[3]==2)		 					//配置描述符上传
								{
									VarSetupDescr=ConDes;
									if(mVarSetupLength>sizeof(ConDes))
									  mVarSetupLength=sizeof(ConDes);
								}
								mCh375DesUp();										//其余描述符不支持					          							
							break;
						case DEF_USB_GET_CONFIG:									//获得配置
							Request.buffer[0]=0;									//没有配置则传0
							if(CH375CONFLAG) Request.buffer[0]=1;									//已经配置则传1;这是在描述符里规定的
							break;
						case DEF_USB_SET_CONFIG:                 					//设置配置
							CH375CONFLAG=0;
							if ( Request.buffer[2] != 0 )
							{
								CH375CONFLAG=1;											//设置配置标志
							}
							break;
						case DEF_USB_GET_INTERF:										//得到接口
							Request.buffer[0]=1;									//上传接口数,本事例只支持一个接口
							break;
						default :
							CH375FLAGERR=1;											//不支持的标准请求
							break;
					}
				}
			}
			else 
			{  //不支持的控制传输,不是8字节的控制传输
				CH375FLAGERR=1;
			}
			if(!CH375FLAGERR) 
			  mCh375Ep0Up();										//没有错误/调用数据上传,,长度为0上传为状态
			else 
			{
				//Uart_Printf("stall\n");
				CH375_WR_CMD_PORT(CMD_SET_ENDP3);				//设置端点1为STALL,指示一个错误
				CH375_WR_DAT_PORT(0x0f);
			}
			break;
		case   USB_INT_EP0_IN:	
			Uart_Printf("%dEP0_IN\n",mVarSetupRequest);	
			//EZUSB_Delay(20);										//控制端点上传成功
			if(mVarSetupRequest==DEF_USB_GET_DESCR)
			{	
			     	mCh375DesUp();
				    mCh375Ep0Up();	
			}
			else if(mVarSetupRequest==DEF_USB_SET_ADDRESS)
			{							//设置地址
			     CH375_WR_CMD_PORT(CMD_SET_USB_ADDR);
			     delay2us();
				 CH375_WR_DAT_PORT(VarUsbAddress);	
				 delay2us();
				 //Uart_Printf("new adderss:%d\n",VarUsbAddress);
				
	 		}
			CH375_WR_CMD_PORT (CMD_UNLOCK_USB);							//释放缓冲区
			break;
		case   USB_INT_EP0_OUT:		
			CH375_WR_CMD_PORT(CMD_RD_USB_DATA);									//发出读数据命令
			//Uart_Printf("EP0_OUT\n");	
			delay2us();
			length=CH375_RD_DAT_PORT();
			if(length)
			{							    			//长度为0跳出
				for(len=0;len!=length;len++)
				{
					//Uart_Printf("-%02x",CH375_RD_DAT_PORT());					//取出下传数据
					c1=CH375_RD_DAT_PORT();					//取出下传数据
				}
			}
			break;
		default:
		    if((InterruptStatus&0x03)==0x03)
			{									//总线复位
				CH375FLAGERR=0;													//错误清0
				CH375CONFLAG=0;													//配置清0
				mVarSetupLength=0;
												//清配置完成输出
			}
			else
			{																//命令不支持
				;
			}
			CH375_WR_CMD_PORT (CMD_UNLOCK_USB);									//释放缓冲区
			CH375_RD_DAT_PORT();
			break;
	 }//
	 
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -