?? hostdisk.c
字號:
/* ********** SCSI/RBC/UFI命令層 ********** */
/* 獲取磁盤特性 */
UINT8 mDiskInquiry( PUINT8 DataBuf )
{
#ifdef BIG_ENDIAN
mBOC.mCBW.mCBW_DataLen = 0x24000000;
#else
mBOC.mCBW.mCBW_DataLen = 0x00000024;
#endif
mBOC.mCBW.mCBW_Flag = 0x80;
mBOC.mCBW.mCBW_CB_Len = 6;
mBOC.mCBW.mCBW_CB_Buf[0] = 0x12; /* 命令碼 */
mBOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[2] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[3] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[4] = 0x24;
mBOC.mCBW.mCBW_CB_Buf[5] = 0x00;
return( mBulkOnlyCmd( DataBuf ) ); /* 執(zhí)行基于BulkOnly協(xié)議的命令 */
}
/* 獲取磁盤容量 */
UINT8 mDiskCapacity( PUINT8 DataBuf )
{
#ifdef BIG_ENDIAN
mBOC.mCBW.mCBW_DataLen = 0x08000000;
#else
mBOC.mCBW.mCBW_DataLen = 0x00000008;
#endif
mBOC.mCBW.mCBW_Flag = 0x80;
mBOC.mCBW.mCBW_CB_Len = 10;
mBOC.mCBW.mCBW_CB_Buf[0] = 0x25; /* 命令碼 */
mBOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[2] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[3] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[4] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[5] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[6] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[7] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[8] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[9] = 0x00;
return( mBulkOnlyCmd( DataBuf ) ); /* 執(zhí)行基于BulkOnly協(xié)議的命令 */
}
/* 測試磁盤是否就緒 */
UINT8 mDiskTestReady( void )
{
mBOC.mCBW.mCBW_DataLen = 0;
mBOC.mCBW.mCBW_Flag = 0x00;
mBOC.mCBW.mCBW_CB_Len = 6;
mBOC.mCBW.mCBW_CB_Buf[0] = 0x00; /* 命令碼 */
mBOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[2] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[3] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[4] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[5] = 0x00;
return( mBulkOnlyCmd( NULL ) ); /* 執(zhí)行基于BulkOnly協(xié)議的命令 */
}
/* 以扇區(qū)為單位從磁盤讀取數(shù)據(jù) */
UINT8 mReadSector( UINT32 StartLba, UINT8 SectCount, PUINT8 DataBuf )
{
UINT32 len;
len = (UINT32)SectCount << 9;
#ifdef BIG_ENDIAN
mBOC.mCBW.mCBW_DataLen = mSwapEndian( len );
#else
mBOC.mCBW.mCBW_DataLen = len;
#endif
mBOC.mCBW.mCBW_Flag = 0x80;
mBOC.mCBW.mCBW_CB_Len = 10;
mBOC.mCBW.mCBW_CB_Buf[0] = 0x28; /* 命令碼 */
mBOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[2] = (UINT8)( StartLba >> 24 );
mBOC.mCBW.mCBW_CB_Buf[3] = (UINT8)( StartLba >> 16 );
mBOC.mCBW.mCBW_CB_Buf[4] = (UINT8)( StartLba >> 8 );
mBOC.mCBW.mCBW_CB_Buf[5] = (UINT8)( StartLba );
mBOC.mCBW.mCBW_CB_Buf[6] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[7] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[8] = SectCount;
mBOC.mCBW.mCBW_CB_Buf[9] = 0x00;
return( mBulkOnlyCmd( DataBuf ) ); /* 執(zhí)行基于BulkOnly協(xié)議的命令 */
}
/* 以扇區(qū)為單位將數(shù)據(jù)寫入磁盤 */
UINT8 mWriteSector( UINT32 StartLba, UINT8 SectCount, PUINT8 DataBuf )
{
UINT32 len;
len = (UINT32)SectCount << 9;
#ifdef BIG_ENDIAN
mBOC.mCBW.mCBW_DataLen = mSwapEndian( len );
#else
mBOC.mCBW.mCBW_DataLen = len;
#endif
mBOC.mCBW.mCBW_Flag = 0x00;
mBOC.mCBW.mCBW_CB_Len = 10;
mBOC.mCBW.mCBW_CB_Buf[0] = 0x2A; /* 命令碼 */
mBOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[2] = (UINT8)( StartLba >> 24 );
mBOC.mCBW.mCBW_CB_Buf[3] = (UINT8)( StartLba >> 16 );
mBOC.mCBW.mCBW_CB_Buf[4] = (UINT8)( StartLba >> 8 );
mBOC.mCBW.mCBW_CB_Buf[5] = (UINT8)( StartLba );
mBOC.mCBW.mCBW_CB_Buf[6] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[7] = 0x00;
mBOC.mCBW.mCBW_CB_Buf[8] = SectCount;
mBOC.mCBW.mCBW_CB_Buf[9] = 0x00;
return( mBulkOnlyCmd( DataBuf ) ); /* 執(zhí)行基于BulkOnly協(xié)議的命令 */
}
/* ********** 主程序 ********** */
/* 為printf和getkey輸入輸出初始化串口 */
void mInitSTDIO( )
{
SCON = 0x50;
PCON = 0x80;
TL2 = RCAP2L = 0 - 13; /* 24MHz晶振, 57600bps */
TH2 = RCAP2H = 0xFF;
T2CON = 0x34; /* 定時器2用于串口的波特率發(fā)生器 */
TI = 1;
}
int main( void ) // USB host
{
UINT8 i, s;
UINT8 idata buf[64];
UINT8 xdata DISK_BUF[512];
// P1&=0xF8; // 如果在U盤文件讀寫模塊上試用本程序必須加上本行
mDelaymS( 50 ); // 等待CH374復位完成
CH374_PORT_INIT( ); /* CH374接口初始化 */
mInitSTDIO( ); /* 為了讓計算機通過串口監(jiān)控演示過程 */
printf( "Start CH374 Host\n" );
Init374Host( ); // 初始化USB主機
while ( 1 ) {
HostSetBusFree( ); // 設定USB主機空閑
printf( "Wait Device In\n" );
while ( 1 ) {
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主機中斷則處理
if ( Query374DeviceIn( ) ) break; // 有USB設備
}
mDelaymS( 200 ); // 由于USB設備剛插入尚未穩(wěn)定,故等待USB設備數(shù)百毫秒,消除插拔抖動
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主機中斷則處理
printf( "Reset Device\n" );
HostSetBusReset( ); // USB總線復位
for ( i = 0; i < 100; i ++ ) { // 等待USB設備復位后重新連接
if ( Query374DeviceIn( ) ) break; // 有USB設備
mDelaymS( 1 );
}
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主機中斷則處理
if ( Query374DeviceIn( ) ) { // 有USB設備
if ( Query374DevFullSpeed( ) ) {
printf( "Start Full-Speed Device\n" );
HostSetFullSpeed( ); // 檢測到全速USB設備
}
else {
printf( "Start Low-Speed Device\n" );
HostSetLowSpeed( ); // 檢測到低速USB設備
}
}
else {
printf( "Device gone !\n" );
continue; // 設備已經(jīng)斷開,繼續(xù)等待
}
mDelaymS( 20 );
printf( "GetDeviceDescr: " );
s = GetDeviceDescr( buf ); // 獲取設備描述符
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
for ( i = 0; i < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) );
printf( "\n" );
printf( "SetUsbAddress: " );
s = SetUsbAddress( 0x02 ); // 設置USB設備地址
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
printf( "\n" );
printf( "GetConfigDescr: " );
s = GetConfigDescr( buf ); // 獲取配置描述符
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
for ( i = 0; i < ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) );
printf( "\n" );
/* 分析配置描述符,獲取端點數(shù)據(jù)/各端點地址/各端點大小等,更新變量endp_addr和endp_size等 */
mDiskBulkInEndp = 0;
mDiskBulkOutEndp = 0;
for ( i = 0; i < 2; i ++ ) { /* 分析前兩個端點 */
if ( ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].wMaxPacketSize == 0x40 && ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bmAttributes == 2 ) { /* 64字節(jié)長度的批量端點 */
if ( ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bEndpointAddress & 0x80 ) mDiskBulkInEndp = ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bEndpointAddress & 0x0F; /* IN端點 */
else mDiskBulkOutEndp = ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bEndpointAddress & 0x0F; /* OUT端點 */
}
}
if ( ( (PUSB_CFG_DESCR_LONG)buf ) -> itf_descr.bInterfaceClass != 0x08 || mDiskBulkInEndp == 0 || mDiskBulkOutEndp == 0 ) { /* 不是USB存儲類設備,不支持 */
printf( "Not USB Mass Storage Device\n" );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
printf( "SetUsbConfig: " );
s = SetUsbConfig( ( (PUSB_CFG_DESCR)buf ) -> bConfigurationValue ); // 設置USB設備配置
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
printf( "\n" );
mSaveDevEndpTog = 0x00; // 清同步標志
printf( "Disk Inquiry: " );
s = mDiskInquiry( buf ); /* 獲取磁盤特性 */
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
for ( i = 0; i < 8; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) );
printf( ", " );
for ( i = 8; i < 36; i ++ ) printf( "%c", buf[i] );
printf( "\n" );
mDelaymS( 100 );
printf( "Disk Capacity: " );
s = mDiskCapacity( buf ); /* 獲取磁盤容量 */
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
}
else {
for ( i = 0; i < 8; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) );
printf( ", %3d MB\n", (UINT16)( ( (UINT32)( buf[1] ) << 16 | (UINT16)( buf[2] ) << 8 | buf[3] ) >> 11 ) );
}
printf( "Disk Ready: " );
s = mDiskTestReady( ); /* 測試磁盤是否就緒 */
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
}
else printf( "\n" );
printf( "Disk Read First Sector: " );
s = mReadSector( 0x00000000, 1, DISK_BUF ); /* 以扇區(qū)為單位從磁盤讀取數(shù)據(jù) */
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
for ( i = 0; i < 16; i ++ ) printf( "%02X ", (UINT16)( DISK_BUF[i] ) );
printf( "\n" );
DISK_BUF[0] ^= 0xFF;
DISK_BUF[1] ^= 0xFF;
DISK_BUF[510] ^= 0xFF;
DISK_BUF[511] ^= 0xFF;
printf( "Disk Write Second Sector: " );
s = mWriteSector( 0x00000001, 1, DISK_BUF ); /* 以扇區(qū)為單位將數(shù)據(jù)寫入磁盤 */
if ( s != USB_INT_SUCCESS ) {
printf( "ERROR = %02X\n", (UINT16)s );
goto WaitDeviceOut; // 終止操作,等待USB設備拔出
}
for ( i = 0; i < 16; i ++ ) printf( "%02X ", (UINT16)( DISK_BUF[i] ) );
printf( "\n" );
WaitDeviceOut: // 等待USB設備拔出
printf( "Wait Device Out\n" );
while ( 1 ) {
if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主機中斷則處理
if ( Query374DeviceIn( ) == FALSE ) break; // 沒有USB設備
}
mDelaymS( 100 ); // 等待設備完全斷開,消除插拔抖動
if ( Query374DeviceIn( ) ) goto WaitDeviceOut; // 沒有完全斷開
// HostSetBusFree( ); // 設定USB主機空閑,主要目的是關閉SOF
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -