📄 massstorage.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 + -