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

📄 massstorage.h

📁 用SL811做USB主机的源码
💻 H
字号:
#ifndef __MassStorage_h__
#define __MassStorage_h__

typedef struct _CBW
{
 uint32 dCBWSignature;	 				//0x43425355
 uint32 dCBWTag;
 uint32	dCBWDataTransferLength;
 uint8	bmCBWFlags;				  		//0x80=In; 0x00=Out
 uint8  bCBWLUN;
 uint8	bCBWCBLength;
 uint8  CBWCB[16];
}CBW, *pCBW;

typedef struct _CSW
{
 uint32 dCBWSignature;			  		//0x53425355
 uint32 dCBWTag;
 uint32 dCSWDataResidue;
 uint8  bCSWStatus;
}CSW, *pCSW;

uint8 WriteBlockData[512];  	 	  //U盘一个Block的容量为512字节
uint8 ReadBlockData[512];  	 	      //U盘一个Block的容量为512字节

uint8 Bulk_Data_Toggle = 0;	  //Not used by user

void Printf_ReadBlockDatabuffer(void)
{
	uint16 temp;
	
	printf("Get: %x",ReadBlockData[0]);
	for(temp=1;temp<512;temp++)
		printf(" %x",ReadBlockData[temp]);
	puts("");	
	printf("Means: %c",ReadBlockData[0]);
	for(temp=1;temp<512;temp++)
		printf(" %c",ReadBlockData[temp]);
	puts("\n");		
}


uint8 Bulk_Transfer_Out(uint8 len,uint8* pData)
{
	SL811_WriteEndPoint(USBA_BASEADDRESS,len,pData);
	SL811_ADDR = SL811_USBA_BaseAddress;
	SL811_COMM = USBA_BASEADDRESS;
	SL811_COMM = len;
	SL811_COMM = OUT_PID | BulkOut_PortNum;
	SL811_COMM = UDisk_Address;		
	SL811_ADDR = SL811_Interrupt_Status;
	SL811_COMM = 0xFF;						// clear the DONE bit
	SL811_ADDR = SL811_USBA_Control;
	if(Bulk_Data_Toggle & 0x01) SL811_COMM = 0x67;		
	else SL811_COMM = 0x27;
	delayms(5);
	if( USBA_Status & 0x01 ){Bulk_Data_Toggle++; return 0;}
	else return 0xFF; 		   		 		//return error
}

uint8 Bulk_Transfer_In(uint8 len,uint8* pData)
{
	uint8 getlen,temp;

	SL811_ADDR = SL811_USBA_BaseAddress;
	SL811_COMM = USBA_BASEADDRESS;
	SL811_COMM = 0x40;
	SL811_COMM = IN_PID | BulkIn_PortNum;
	SL811_COMM = UDisk_Address;	
	SL811_ADDR = SL811_Interrupt_Status;
	SL811_COMM = 0xFF;						// clear the DONE bit
	SL811_ADDR = SL811_USBA_Control;
	SL811_COMM = 0x23;	
	delayms(5);
	if(USBA_Status & 0x01)
	{
	   SL811_ADDR = SL811_USBA_DAoTC;
	   getlen = 0x40 - SL811_COMM;
	   //printf("Get data num is %x\n", getlen);
	   temp = (getlen > len)?len:getlen;
	   SL811_ADDR = USBA_BASEADDRESS;
	   do{
	   	  *pData++ = SL811_COMM;
	   }while(--temp);
	   return getlen;	  		  		 	// return data num got
	}
	else return 0xFF;  	  		  		 	// return error		
}


uint8 UDisk_1Block_Read(void)
{
	uint8  getlen;
	uint8  PackageReaded = 0;
	uint8* pbuffer = ReadBlockData;
	
	for(PackageReaded=0;PackageReaded<8;PackageReaded++)
	{
	  SL811_ADDR = SL811_USBA_BaseAddress;
	  SL811_COMM = USBA_BASEADDRESS;
	  SL811_COMM = 0x40;
	  SL811_COMM = IN_PID | BulkIn_PortNum;
	  SL811_COMM = UDisk_Address;	
	  SL811_ADDR = SL811_Interrupt_Status;
	  SL811_COMM = 0xFF;						// clear the DONE bit
	  SL811_ADDR = SL811_USBA_Control;
	  SL811_COMM = 0x23;		
	  delayms(5);
	  if(USBA_Status & 0x01)
	  {
	    SL811_ADDR = SL811_USBA_DAoTC;
	    getlen = 0x40 - SL811_COMM;
	    if(getlen != 0x40) return PackageReaded;
	    SL811_ADDR = USBA_BASEADDRESS;
	    do{
	   	  *pbuffer++ = SL811_COMM;
	    }while(--getlen);
	  }
	  else return PackageReaded;  	  		  		 		// return error
	} // end of for(PackageReaded=0;PackageReaded<8;PackageReaded++)
	
	return PackageReaded;  
}

uint8 UDisk_1Block_Write(void)
{
	uint8  i;
	uint8  PackageWrited;
	uint8* pbuffer = WriteBlockData;

	for(PackageWrited=0;PackageWrited<8;PackageWrited++)
	{
	  SL811_ADDR = USBA_BASEADDRESS;		    // 选择端点
	  for(i=0;i<64;i++)						    // 写缓冲区数据
		SL811_COMM=*(pbuffer++);
	  SL811_ADDR = SL811_USBA_BaseAddress;
	  SL811_COMM = USBA_BASEADDRESS;
	  SL811_COMM = 64;
	  SL811_COMM = OUT_PID | BulkOut_PortNum;
	  SL811_COMM = UDisk_Address;		
	  SL811_ADDR = SL811_Interrupt_Status;
	  SL811_COMM = 0xFF;						// clear the DONE bit
	  SL811_ADDR = SL811_USBA_Control;
	  if( Bulk_Data_Toggle & 0x01 ) SL811_COMM = 0x67;		
	  else SL811_COMM = 0x27;
	  delayms(100);	  		 	  			   	// 10ms - 20ms
	  if( USBA_Status & 0x01 ){Bulk_Data_Toggle++; continue;}
	  else return 0xFF;
	} // end of for(PackageReaded=0;PackageReaded<8;PackageReaded++)
	return 0; 
}

uint8 ResetDevice()
{
 if(USBA_FSendPacket(Reset_MassStorageDevice,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 0x21;
 if(USBAGetPacket(GetDataBuffer, 0, UDisk_Address) == 0xFF ) return 0x22;
 puts("Good when Reset Device!"); 
 return 0;
}

uint8 Get_MaxLun()
{
 if(USBA_FSendPacket(Get_MaxLUN,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 031;
 if(USBAGetPacket(GetDataBuffer, 0,UDisk_Address) == 0xFF ) return 0x32;
 puts("Good when Reset Device!"); 
 return GetDataBuffer[0];
}

uint8 Clear_BulkOut_Port()
{
 Clear_EndPFeature[4] = BulkOut_PortNum;
 if(USBA_SendPacket(Clear_EndPFeature,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 041;
 if(USBAGetPacket(GetDataBuffer, 0,UDisk_Address) == 0xFF ) return 0x42;
 puts("BulkOut_Port cleared!");
 return 0;
}

uint8 Clear_BulkIn_Port()
{
 Clear_EndPFeature[4] = BulkIn_PortNum | 0x80;
 if(USBA_SendPacket(Clear_EndPFeature,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 043;
 if(USBAGetPacket(GetDataBuffer, 0,UDisk_Address) == 0xFF ) return 0x44; 
 puts("BulkIn_Port cleared!"); 
 return 0;
}

uint8 ResetRecover()
{
 uint8 temp;
 
 temp = ResetDevice();
 if(temp) return temp;
 temp = Clear_BulkOut_Port();
 if(temp) return temp;
 temp = Clear_BulkIn_Port();
 if(temp) return temp; 
 return 0;
}

uint8  UFI_Inquiry(void)						   //Good supported
{
 CBW MassStorageCBW;
 uint8 i;
 
 puts("UFI_Inquiry process!"); 
 
 MassStorageCBW.dCBWSignature = 0x43425355;
 MassStorageCBW.dCBWTag = 0x12345678;
 MassStorageCBW.dCBWDataTransferLength = 0x24;	   //Modify
 MassStorageCBW.bmCBWFlags = 0x80;	   	 		   //Modify
 MassStorageCBW.bCBWLUN = 0;
 MassStorageCBW.bCBWCBLength = 0x06;
 
 MassStorageCBW.CBWCB[0] = 0x12;
 MassStorageCBW.CBWCB[1] = 0;
 MassStorageCBW.CBWCB[2] = 0;
 MassStorageCBW.CBWCB[3] = 0;
 MassStorageCBW.CBWCB[4] = 0x24;
 MassStorageCBW.CBWCB[5] = 0;
 
 if(Bulk_Transfer_Out(31,(uint8*)&MassStorageCBW) == 0) 
 {
   puts("Good Bulk Transfer!");
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x10;
   printf("Get data num is %x\n",i);
   Printf_buffer();   
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x11;
   printf("Get data num is %x\n",i);
   Printf_buffer();     
   return GetDataBuffer[12];			  //Return 0 if success, 0x01 = fail, 0x02 = segment error
 }
 else 
 {
   puts("Bad Bulk Transfer!");
   return 0xFF;
 }  
}


uint8  UFI_RequestSense(void) 			  		   //Good supported
{
 CBW MassStorageCBW;
 uint8 i;
 
 //puts("UFI_RequestSense process!");
 
 MassStorageCBW.dCBWSignature = 0x43425355;
 MassStorageCBW.dCBWTag = 0x12345678;
 MassStorageCBW.dCBWDataTransferLength = 18;	   //Modify
 MassStorageCBW.bmCBWFlags = 0x80;	   	 		   //Modify
 MassStorageCBW.bCBWLUN = 0;
 MassStorageCBW.bCBWCBLength = 0x05;
 
 MassStorageCBW.CBWCB[0] = 0x03;
 MassStorageCBW.CBWCB[1] = 0;
 MassStorageCBW.CBWCB[2] = 0;
 MassStorageCBW.CBWCB[3] = 0;
 MassStorageCBW.CBWCB[4] = 18;
 MassStorageCBW.CBWCB[5] = 0;
 
 if(Bulk_Transfer_Out(31,(uint8*)&MassStorageCBW) == 0) 
 {
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x10;
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x11;
   return GetDataBuffer[12];			  //Return 0 if success, 0x01 = fail, 0x02 = segment error
 }
 else 
 {
   puts("Bad Bulk Transfer!");
   return 0xFF;
 }  
}

uint8  UFI_ReadCapacity(void)
{
 CBW MassStorageCBW;
 uint8 i;

 puts("UFI_ReadCapacity process!");
 
 MassStorageCBW.dCBWSignature = 0x43425355;
 MassStorageCBW.dCBWTag = 0x12345678;
 MassStorageCBW.dCBWDataTransferLength = 0x08;
 MassStorageCBW.bmCBWFlags = 0x80;
 MassStorageCBW.bCBWLUN = 0;
 MassStorageCBW.bCBWCBLength = 0x0c;
 
 MassStorageCBW.CBWCB[0] = 0x25;
 MassStorageCBW.CBWCB[1] = 0;
 MassStorageCBW.CBWCB[2] = 0;
 MassStorageCBW.CBWCB[3] = 0;
 MassStorageCBW.CBWCB[4] = 0;
 MassStorageCBW.CBWCB[5] = 0;
 MassStorageCBW.CBWCB[6] = 0;
 MassStorageCBW.CBWCB[7] = 0;
 MassStorageCBW.CBWCB[8] = 0;
 MassStorageCBW.CBWCB[9] = 0;
 MassStorageCBW.CBWCB[10] = 0;
 MassStorageCBW.CBWCB[11] = 0;
   
 if(Bulk_Transfer_Out(31,(uint8*)&MassStorageCBW) == 0) 
 {
   puts("Good Bulk Transfer!");
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x10;
   printf("Get data num is %x\n",i);
   Printf_buffer();   
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x11;
   printf("Get data num is %x\n",i);
   Printf_buffer();   
   UFI_RequestSense();					  // Must?  
   return GetDataBuffer[12];			  // Return 0 if success, 0x01 = fail, 0x02 = segment error
 }
 else 
 {
   puts("Bad Bulk Transfer!");
   return 0xFF;
 }  
}

uint8  UFI_Read10(uint32 LogicalBlockAddress)
{
 CBW MassStorageCBW;
 uint8 i;
 
 MassStorageCBW.dCBWSignature = 0x43425355;
 MassStorageCBW.dCBWTag = 0xFF31E828;
 MassStorageCBW.dCBWDataTransferLength = 0x0200;
 MassStorageCBW.bmCBWFlags = 0x80;
 MassStorageCBW.bCBWLUN = 0;
 MassStorageCBW.bCBWCBLength = 0x0a;
 
 MassStorageCBW.CBWCB[0] = 0x28;
 MassStorageCBW.CBWCB[1] = 0;
 MassStorageCBW.CBWCB[2] = *((uint8*)&LogicalBlockAddress+3);
 MassStorageCBW.CBWCB[3] = *((uint8*)&LogicalBlockAddress+2);
 MassStorageCBW.CBWCB[4] = *((uint8*)&LogicalBlockAddress+1);
 MassStorageCBW.CBWCB[5] = *((uint8*)&LogicalBlockAddress+0);
 MassStorageCBW.CBWCB[6] = 0;
 MassStorageCBW.CBWCB[7] = 0;		   	 	   //Transfer data len MSB
 MassStorageCBW.CBWCB[8] = 1;		   	 	   //Transfer data len LSB
 MassStorageCBW.CBWCB[9] = 0;
 MassStorageCBW.CBWCB[10] = 0;
 MassStorageCBW.CBWCB[11] = 0;

 if(Bulk_Transfer_Out(31,(uint8*)&MassStorageCBW) == 0) 
 {
   //puts("Good Bulk Transfer!");
   i = UDisk_1Block_Read();
   if( Bulk_Transfer_In(64,GetDataBuffer) == 0xFF ) return 0x11;
   //else { puts("Get CSW success!"); Printf_buffer(); }      
   //if( i == 8 ) Printf_ReadBlockDatabuffer();  
   UFI_RequestSense();					  // Must?
   return GetDataBuffer[12];			  // Return 0 if success, 0x01 = fail, 0x02 = segment error
 }
 else 
 {
   //puts("Bad Bulk Transfer!");
   return 0xFF;
 }  
}

uint8  UFI_Write10(uint32 LogiclBlockAddress)
{
 CBW MassStorageCBW;
 uint8 i;
 
 //puts("UFI_Write10 process!");
 
 MassStorageCBW.dCBWSignature = 0x43425355;
 MassStorageCBW.dCBWTag = 0x87654321;
 MassStorageCBW.dCBWDataTransferLength = 0x0200;
 MassStorageCBW.bmCBWFlags = 0x00;
 MassStorageCBW.bCBWLUN = 0;
 MassStorageCBW.bCBWCBLength = 0x0c;
 
 MassStorageCBW.CBWCB[0] = 0x2A;
 MassStorageCBW.CBWCB[1] = 0;
 MassStorageCBW.CBWCB[2] = *((uint8*)&LogiclBlockAddress+3);
 MassStorageCBW.CBWCB[3] = *((uint8*)&LogiclBlockAddress+2);
 MassStorageCBW.CBWCB[4] = *((uint8*)&LogiclBlockAddress+1);
 MassStorageCBW.CBWCB[5] = *((uint8*)&LogiclBlockAddress+0);
 MassStorageCBW.CBWCB[6] = 0;
 MassStorageCBW.CBWCB[7] = 0;		   	 	   //Transfer data len MSB
 MassStorageCBW.CBWCB[8] = 1;		   	 	   //Transfer data len LSB
 MassStorageCBW.CBWCB[9] = 0;
 MassStorageCBW.CBWCB[10] = 0;
 MassStorageCBW.CBWCB[11] = 0;

 if(Bulk_Transfer_Out(31,(uint8*)&MassStorageCBW) == 0) 
 {
   //puts("Good Bulk Transfer!");
   delayms(100);	   			   			  // 10ms -20ms
   i = UDisk_1Block_Write();
   if( i != 0 ) { puts("Fail to Write data!"); return 0x10; }
   delayms(2);
   i = Bulk_Transfer_In(64,GetDataBuffer);
   if( i == 0xFF ) return 0x11;
   //puts("Get CSW:");
   //Printf_buffer();   
   UFI_RequestSense();					  // Must?     
   return GetDataBuffer[12];			  //Return 0 if success, 0x01 = fail, 0x02 = segment error
 }
 else 
 {
   puts("Bad Bulk Transfer!");
   return 0xFF;
 }  
}

#endif

⌨️ 快捷键说明

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