?? ch375hft.c
字號:
xWriteCH375Data( iCount ); /* 后續數據的長度 */
for ( ; iCount != 0; iCount -- ) { /* 根據長度寫入數據 */
xWriteCH375Data( *iBuffer ); /* 將數據寫入 */
iBuffer ++;
}
}
/* 檢查U盤是否寫保護, 返回USB_INT_SUCCESS說明可以寫,返回0xFF說明只讀/寫保護,返回其它值說明是錯誤代碼 */
/* 其它BulkOnly傳輸協議的命令可以參考這個例子處理,修改前必須了解USB MassStorage和SCSI規范 */
UINT8 IsDiskWriteProtect( void )
{
UINT8 mIfSubClass, mLength, mDevSpecParam;
if ( CH375Version2 == 0 ) return( ERR_USB_DISK_ERR ); /* CH375S不支持 */
CH375IntStatus = 0; /* 清中斷標志 */
xWriteCH375Cmd( CMD_GET_DESCR ); /* 獲取描述符的命令 */
xWriteCH375Data( 2 ); /* 配置描述符 */
xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態 */
if ( CH375IntStatus == USB_INT_SUCCESS ) { /* 操作成功 */
ReadUsbData( (UINT8 *)&mCmdParam ); /* 讀取描述符,請確保mCmdParam長度MAX_BYTE_IO大于32字節,否則需另選緩沖區 */
mIfSubClass = mCmdParam.Other.mBuffer[9+6]; /* 子類 USB_CFG_DESCR_LONG.itf_descr.bInterfaceSubClass */
mCmdParam.BOC.mCBW.mCBW_DataLen = 0x10; /* 數據傳輸長度 */
mCmdParam.BOC.mCBW.mCBW_Flag = 0x80; /* 傳輸方向為輸入 */
if ( mIfSubClass == 6 ) { /* 根據子類選擇命令碼 */
mCmdParam.BOC.mCBW.mCBW_CB_Buf[0] = 0x1A; /* 命令塊首字節, MODE SENSE(6) */
mCmdParam.BOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[2] = 0x3F;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[3] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[4] = 0x10;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[5] = 0x00;
}
else {
mCmdParam.BOC.mCBW.mCBW_CB_Buf[0] = 0x5A; /* 命令塊首字節, MODE SENSE(10) */
mCmdParam.BOC.mCBW.mCBW_CB_Buf[1] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[2] = 0x3F;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[3] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[4] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[5] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[6] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[7] = 0x00;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[8] = 0x10;
mCmdParam.BOC.mCBW.mCBW_CB_Buf[9] = 0x00;
}
WriteUsbData( (UINT8 *)&mCmdParam, 31 ); /* 向CH375主機端點的發送緩沖區寫入CBW數據塊,剩余部分CH375自動填補 */
CH375IntStatus = 0;
xWriteCH375Cmd( CMD_DISK_BOC_CMD ); /* 對USB存儲器執行BulkOnly傳輸協議 */
xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態 */
if ( CH375IntStatus == USB_INT_SUCCESS ) { /* 操作成功 */
mLength = ReadUsbData( (UINT8 *)&mCmdParam ); /* 從CH375主機端點的接收緩沖區讀取數據塊 */
if ( mLength > 3 ) { /* MODE SENSE命令返回數據的長度有效 */
if ( mIfSubClass == 6 ) mDevSpecParam = mCmdParam.Other.mBuffer[2]; /* MODE SENSE(6), device specific parameter */
else mDevSpecParam = mCmdParam.Other.mBuffer[3]; /* MODE SENSE(10), device specific parameter */
if ( mDevSpecParam & 0x80 ) return( 0xFF ); /* U盤寫保護 */
else return( USB_INT_SUCCESS ); /* U盤沒有寫保護 */
}
return( ERR_USB_DISK_ERR );
}
mIfSubClass = CH375IntStatus; /* 暫存 */
xWriteCH375Cmd( CMD_DISK_R_SENSE ); /* 檢查USB存儲器錯誤 */
xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態 */
return( mIfSubClass );
}
return( CH375IntStatus );
}
/* 安全移除U盤, 返回USB_INT_SUCCESS說明可以安全移除,否則說明不能安全移除,只能強行移除 */
/* 在操作完U盤準備讓用戶拔出U盤前調用, 防止用戶過早拔出U盤丟失數據 */
UINT8 SafeRemoveDisk( void )
{
UINT8 i;
for ( i = 0; i < 10; i ++ ) { /* 有的U盤總是返回未準備好,不過可以被忽略 */
mDelaymS( 100 );
if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢磁盤是否準備好 */
}
mDelaymS( 10 );
xWriteCH375Cmd( CMD_SET_CONFIG ); /* 設置USB配置 */
xWriteCH375Data( 0 ); /* 取消配置,會導致很多U盤的LED燈滅 */
xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態 */
mDelaymS( 10 );
if ( i < 5 && CH375IntStatus == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); /* 操作成功 */
else return( 0xFF );
/* 以下取消SOF包會導致絕大多數U盤的LED燈滅 */
/* 如果此處取消SOF, 那么與此對應, 在檢測到U盤插入后應該再恢復為模式6即恢復SOF包 */
// xWriteCH375Cmd( CMD_SET_USB_MODE ); /* 設置USB工作模式 */
// xWriteCH375Data( 5 ); /* 停止發出SOF包,檢測到U盤插入后必須用模式6恢復SOF包發出 */
// mDelaymS( 1 );
}
main( ) {
UINT8 i;
LED_OUT_INIT( );
LED_OUT_ACT( ); /* 開機后LED亮一下以示工作 */
mDelaymS( 100 ); /* 延時100毫秒 */
LED_OUT_INACT( );
mInitSTDIO( ); /* 為了讓計算機通過串口監控演示過程 */
printf( "Start\n" );
#if DISK_BASE_BUF_LEN == 0
pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定義CH375的專用緩沖區,而是用緩沖區指針指向其它應用程序的緩沖區便于合用以節約RAM */
#endif
i = CH375LibInit( ); /* 初始化CH375程序庫和CH375芯片,操作成功返回0 */
mStopIfError( i );
/* 其它電路初始化 */
while ( 1 ) {
printf( "Wait Udisk\n" );
while ( CH375DiskStatus < DISK_CONNECT ) { /* 查詢CH375中斷并更新中斷狀態,等待U盤插入 */
CH375DiskConnect( );
mDelaymS( 100 );
}
LED_OUT_ACT( ); /* LED亮 */
mDelaymS( 200 ); /* 延時,可選操作,有的USB存儲器需要幾十毫秒的延時 */
/* 檢查U盤是否準備好,有些U盤不需要這一步,但是某些U盤必須要執行這一步才能工作 */
for ( i = 0; i < 3; i ++ ) { /* 有的U盤總是返回未準備好,不過可以被忽略 */
mDelaymS( 100 );
printf( "Ready ?\n" );
if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢磁盤是否準備好 */
}
#if DISK_BASE_BUF_LEN
if ( DISK_BASE_BUF_LEN < CH375vSectorSize ) { /* 檢查磁盤數據緩沖區是否足夠大,CH375vSectorSize是U盤的實際扇區大小 */
printf( "Too large sector size\n" );
while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelaymS( 100 );
continue;
}
#endif
/* 查詢磁盤物理容量 */
/* printf( "DiskSize\n" );
i = CH375DiskSize( );
mStopIfError( i );
printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * (CH375vSectorSize/512) / 2048 ) ); // 顯示為以MB為單位的容量
// 原計算方法 (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * CH375vSectorSize / 1000000 ) 有可能前兩個數據相乘后導致溢出, 所以修改成上式
*/
LED_RUN_ACT( ); /* 開始操作U盤 */
printf( "Check Disk Write Protect ? ...\n" );
i = IsDiskWriteProtect( ); /* 檢查U盤是否寫保護, 返回USB_INT_SUCCESS說明可以寫,返回0xFF說明只讀/寫保護,返回其它值說明是錯誤代碼 */
if ( i != USB_INT_SUCCESS && i != 0xFF ) { /* 操作失敗 */
printf( "Again ...\n" );
mDelaymS( 100 );
i = IsDiskWriteProtect( ); /* 再試一次 */
}
if ( i == USB_INT_SUCCESS ) { /* 可以寫 */
printf( "... No !\n" );
LED_WR_ACT( ); /* 寫操作 */
printf( "Create a File\n" );
mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "\\NEWFILE.TXT" ); /* 新文件名,在根目錄下 */
i = CH375FileCreate( ); /* 新建文件并打開,如果文件已經存在則先刪除后再新建 */
mStopIfError( i );
mCmdParam.ByteWrite.mByteBuffer[0] = 'O';
mCmdParam.ByteWrite.mByteBuffer[1] = 'K';
mCmdParam.ByteWrite.mByteCount = 2; /* 寫入數據的字符數,單次讀寫的長度不能超過MAX_BYTE_IO,第二次調用時接著剛才的向后寫 */
i = CH375ByteWrite( ); /* 向文件寫入數據 */
mStopIfError( i );
printf( "Close\n" );
mCmdParam.Close.mUpdateLen = 0; /* 不需要自動計算文件長度 */
i = CH375FileClose( );
mStopIfError( i );
LED_WR_INACT( );
if ( SafeRemoveDisk( ) == USB_INT_SUCCESS ) { /* 安全移除U盤 */
printf( "Safe Remove !\n" );
}
else {
printf( "Unsafe Remove !\n" );
}
}
else if ( i == 0xFF ) { /* 寫保護 */
printf( "... Yes !\n" );
}
else {
mStopIfError( i ); /* 顯示錯誤代碼 */
}
LED_RUN_INACT( );
printf( "Take out\n" );
while ( CH375DiskStatus >= DISK_CONNECT ) { /* 查詢CH375中斷并更新中斷狀態,等待U盤拔出 */
CH375DiskConnect( );
mDelaymS( 100 );
}
LED_OUT_INACT( ); /* LED滅 */
mDelaymS( 200 );
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -