?? bulkonly.c
字號:
/****************************************Copyright (c)**************************************************
** CH374做主機(jī)操作U盤讀寫程序
** Bulk-only傳輸協(xié)議層
** 接口函數(shù)
**
** VBeat 0.2
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: Bulkonly.C
**創(chuàng) 建 人: 徐亦朱
**最后修改日期: 2007年9月24日
**描 述: 增加部分UFI命令集支持
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創(chuàng)建人: 徐亦朱
** 版 本: VBeat 0.1
** 日 期: 2007年9月21日
** 描 述: 原始版本
**
**--------------當(dāng)前版本修訂------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007年9月24日
** 描 述: 增加部分UFI命令集支持
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include "HAL.H"
#include "HAL_BASE2.C"
#include "PARA_HW2.C"
#include "Bulkonly.H"
/*********************************************************************************************************
** 函數(shù)名稱: IsDiskConnect
** 功能描述: 檢查磁盤是否連接
**
** 輸 入:
** 輸 出: 返回錯誤碼:
** USB_INT_SUCCESS: 已經(jīng)連接
** USB_INT_CONNECT: 剛連接
** USB_INT_DISCONNECT: 斷開
**
** 全局變量: 無
** 調(diào)用模塊: 無
** 調(diào)試碼: 無
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 IsDiskConnect( void )
{
if ( Read374Byte( REG_INTER_FLAG ) & ( BIT_IF_DEV_DETECT ) ) //檢測到插拔事件
{
SetHostUsbAddr( 0x00 );
HostSetBusFree( ); //USB總線空閑
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_DEV_DETECT | BIT_IF_TRANSFER ); //清中斷標(biāo)志
if( Read374Byte( REG_INTER_FLAG ) & BIT_IF_DEV_ATTACH ) //設(shè)備剛連接
return( USB_INT_CONNECT );
return( USB_INT_DISCONNECT ); //設(shè)備斷開
}
if ( Read374Byte( REG_INTER_FLAG ) & BIT_IF_DEV_ATTACH ) //設(shè)備已連接
{
return( USB_INT_SUCCESS );
}
return( USB_INT_DISCONNECT ) ;
}
/*********************************************************************************************************
** 函數(shù)名稱: mResetErrorBOC
** 功能描述: USB DISK重置
**
** 輸 入: LastError: 重置前的錯誤碼
** 輸 出: 返回重置前的錯誤碼,即Lastrror
**
** 全局變量: 無
** 調(diào)用模塊: 無
** 調(diào)試碼: 無
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 mResetErrorBOC( UINT8 LastError )
{
UINT8 s;
UINT8 ReqBuf[ sizeof( BoResetUsbDisk ) ] ;
s = IsDiskConnect( ); //檢查U盤是否連接
if ( s != USB_INT_SUCCESS ) //斷開或者剛連接
return( s );
memcpy( ReqBuf, BoResetUsbDisk, sizeof( BoResetUsbDisk ) );
( ( PUSB_SETUP_REQ )ReqBuf ) -> wIndexL = mDiskInterfNumber ;
s = HostCtrlTransfer374( ReqBuf, NULL, NULL ) ;
if ( s == USB_INT_DISCONNECT ) //檢測到USB設(shè)備斷開事件,磁盤已經(jīng)斷開
return( s );
mClearEndpStall( mDiskBulkInEndp | 0x80 ) ; //清除IN端點(diǎn)錯誤
mClearEndpStall( mDiskBulkOutEndp ) ; //清除OUT端點(diǎn)錯誤
mSaveDevEndpTog &= ~ ( BIT_HOST_TRAN_TOG | BIT_HOST_RECV_TOG ) ;
return( LastError ) ; //返回原錯誤碼
}
/*********************************************************************************************************
** 函數(shù)名稱: mBulkOnlyCmd
** 功能描述: 執(zhí)行基于Bulk-only協(xié)議的命令
**
** 輸 入: DataBuf: 指向數(shù)據(jù)緩沖區(qū)
** 輸 出:
**
** 全局變量: 無
** 調(diào)用模塊: 無
** 調(diào)試碼: 無
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 mBulkOnlyCmd( PUINT8 DataBuf )
{
UINT8 s ;
UINT8 len ;
UINT32 TotalLen ;
UINT32 DataLength ;
mBOC.mCBW.mCBW_Sig = USB_BO_CBW_SIG ;
mBOC.mCBW.mCBW_Tag = 0x03740374 ;
mBOC.mCBW.mCBW_LUN = 0;
//向CH374主機(jī)端點(diǎn)的發(fā)送緩沖區(qū)寫入CBW
Write374Block( RAM_HOST_TRAN, USB_BO_CBW_SIZE, ( PUINT8 )( & mBOC.mCBW ) ) ;
Write374Byte( REG_USB_LENGTH, USB_BO_CBW_SIZE );
mSetBulkOut( ) ;
s = HostTransactInter( ); //向USB盤的OUT端點(diǎn)輸出CBW
if ( s == USB_INT_DISCONNECT ) //檢測到USB設(shè)備斷開事件,磁盤已經(jīng)斷開
{
return( s ) ;
printf ( " 檢測到USB設(shè)備斷開事件,磁盤已經(jīng)斷開 \n " ) ;
}
if ( s != USB_INT_SUCCESS ) //發(fā)送CBW失敗
{
printf ( " 發(fā)送CBW失敗,準(zhǔn)備復(fù)位重試 \n " ) ;
mResetErrorBOC( s ) ;
//向CH374主機(jī)端點(diǎn)的發(fā)送緩沖區(qū)寫入CBW
Write374Block( RAM_HOST_TRAN, USB_BO_CBW_SIZE, ( PUINT8 )( & mBOC.mCBW ) ) ;
Write374Byte( REG_USB_LENGTH, USB_BO_CBW_SIZE ) ;
mSetBulkOut( );
s = HostTransactInter( ); //向USB盤的OUT端點(diǎn)輸出CBW
if ( s != USB_INT_SUCCESS ) //發(fā)送CBW失敗
{
printf( " 重試失敗,復(fù)位并退出傳輸,返回錯誤碼.\n " ) ;
return( mResetErrorBOC( s ) ) ;
}
}
mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG; //OUT端點(diǎn)的數(shù)據(jù)同步標(biāo)志翻轉(zhuǎn)
if ( mBOC.mCBW.mCBW_DataLen )
{
TotalLen = mBOC.mCBW.mCBW_DataLen ;
DataLength = mBOC.mCBW.mCBW_DataLen ;
if ( mBOC.mCBW.mCBW_Flag & 0x80 ) //IN事務(wù)
{
//Write374Byte( REG_USB_SETUP, Read374Byte( REG_USB_SETUP ) | BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ;
while( TotalLen )
{
mDelayuS( 100 ) ;
mSetBulkIn( );
s = HostTransactInter( ); //接受數(shù)據(jù)
if ( s != USB_INT_SUCCESS ) //操作失敗
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端點(diǎn)錯誤
{
mClearEndpStall( mDiskBulkInEndp | 0x80 ) ;
printf ( " 接收數(shù)據(jù)時(shí)發(fā)生STALL錯誤.\n " ) ;
}
else
{
printf ( " 接收數(shù)據(jù)時(shí)發(fā)生未知錯誤!\n " ) ;
return( USB_INT_DISK_ERR ) ;
}
}
len = Read374Byte( REG_USB_LENGTH ) ;
Read374Block( RAM_HOST_RECV, len, DataBuf );
mSaveDevEndpTog ^= BIT_HOST_RECV_TOG ; //IN端點(diǎn)的數(shù)據(jù)同步標(biāo)志翻轉(zhuǎn)
DataBuf += len ;
if ( TotalLen > len )
TotalLen -= len ;
else
TotalLen = 0 ;
if ( len < 64 )
break;
}
}
else //OUT事務(wù)
{
//Write374Byte( REG_USB_SETUP, Read374Byte( REG_USB_SETUP ) | BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ;
while( TotalLen )
{
mDelayuS( 100 ) ;
len = TotalLen >= 64 ? 64 : TotalLen ;
Write374Block( RAM_HOST_TRAN, len, DataBuf );
Write374Byte( REG_USB_LENGTH, len );
mSetBulkOut( );
s = HostTransactInter( ); //發(fā)送數(shù)據(jù)
if ( s != USB_INT_SUCCESS ) //操作失敗
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端點(diǎn)錯誤
{
mClearEndpStall( mDiskBulkOutEndp );
printf ( " 發(fā)送數(shù)據(jù)時(shí)發(fā)生STALL錯誤!\n " ) ;
break ;
}
else
{
printf ( " 發(fā)送數(shù)據(jù)時(shí)發(fā)生未知錯誤!\n " ) ;
return( USB_INT_DISK_ERR ) ;
}
}
DataBuf += len;
TotalLen -= len ;
mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG ; //OUT端點(diǎn)的數(shù)據(jù)同步標(biāo)志翻轉(zhuǎn)
}
}
}
//全速USB主機(jī)模式,USB總線空閑,發(fā)SOF
//Write374Byte( REG_USB_SETUP, M_SET_RAM_MODE_OFF( BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ) ;
//從USB盤的IN端點(diǎn)輸入CSW
mSetBulkIn( ); //輸入
s = HostTransactInter( ); //發(fā)送數(shù)據(jù)
if ( s != USB_INT_SUCCESS ) //接受CSW失敗
{
printf( "接收CSW失敗!\n" ) ;
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端點(diǎn)錯誤
{
mClearEndpStall( mDiskBulkInEndp | 0x80 );
printf ( " 接收數(shù)據(jù)時(shí)發(fā)生STALL錯誤!\n " ) ;
printf ( " 嘗試重試接收CSW.\n " ) ;
mSetBulkIn( );
s = HostTransactInter( );
if ( s != USB_INT_SUCCESS )
{
printf( " 重試失敗,復(fù)位并退出傳輸,返回錯誤碼.\n " ) ;
return( mResetErrorBOC( s ) ) ;
}
}
else
{
printf ( " 接收CSW時(shí)發(fā)生未知錯誤!\n " ) ;
return( s );
}
}
len = Read374Byte( REG_USB_LENGTH ) ;
Read374Block( RAM_HOST_RECV, len, ( PUINT8 )( & mBOC.mCSW ) );
mSaveDevEndpTog ^= BIT_HOST_RECV_TOG ; //IN端點(diǎn)的數(shù)據(jù)同步標(biāo)志翻轉(zhuǎn)
//確認(rèn)Valid
if ( len != USB_BO_CSW_SIZE || mBOC.mCSW.mCSW_Sig != USB_BO_CSW_SIG )
{
printf( " 收到的CSW: NON-Valid\n " ) ;
return( USB_INT_DISK_ERR ) ;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -