📄 bulkonly.c
字号:
/****************************************Copyright (c)**************************************************
** CH374做主机操作U盘读写程序
** Bulk-only传输协议层
** 接口函数
**
** VBeat 0.2
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: Bulkonly.C
**创 建 人: 徐亦朱
**最后修改日期: 2007年9月24日
**描 述: 增加部分UFI命令集支持
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 徐亦朱
** 版 本: VBeat 0.1
** 日 期: 2007年9月21日
** 描 述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007年9月24日
** 描 述: 增加部分UFI命令集支持
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include "HAL.H"
#include "HAL_BASE2.C"
#include "PARA_HW2.C"
#include "Bulkonly.H"
/*********************************************************************************************************
** 函数名称: IsDiskConnect
** 功能描述: 检查磁盘是否连接
**
** 输 入:
** 输 出: 返回错误码:
** USB_INT_SUCCESS: 已经连接
** USB_INT_CONNECT: 刚连接
** USB_INT_DISCONNECT: 断开
**
** 全局变量: 无
** 调用模块: 无
** 调试码: 无
**
**
** 作 者: 徐亦朱
** 日 期: 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 ); //清中断标志
if( Read374Byte( REG_INTER_FLAG ) & BIT_IF_DEV_ATTACH ) //设备刚连接
return( USB_INT_CONNECT );
return( USB_INT_DISCONNECT ); //设备断开
}
if ( Read374Byte( REG_INTER_FLAG ) & BIT_IF_DEV_ATTACH ) //设备已连接
{
return( USB_INT_SUCCESS );
}
return( USB_INT_DISCONNECT ) ;
}
/*********************************************************************************************************
** 函数名称: mResetErrorBOC
** 功能描述: USB DISK重置
**
** 输 入: LastError: 重置前的错误码
** 输 出: 返回重置前的错误码,即Lastrror
**
** 全局变量: 无
** 调用模块: 无
** 调试码: 无
**
**
** 作 者: 徐亦朱
** 日 期: 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设备断开事件,磁盘已经断开
return( s );
mClearEndpStall( mDiskBulkInEndp | 0x80 ) ; //清除IN端点错误
mClearEndpStall( mDiskBulkOutEndp ) ; //清除OUT端点错误
mSaveDevEndpTog &= ~ ( BIT_HOST_TRAN_TOG | BIT_HOST_RECV_TOG ) ;
return( LastError ) ; //返回原错误码
}
/*********************************************************************************************************
** 函数名称: mBulkOnlyCmd
** 功能描述: 执行基于Bulk-only协议的命令
**
** 输 入: DataBuf: 指向数据缓冲区
** 输 出:
**
** 全局变量: 无
** 调用模块: 无
** 调试码: 无
**
**
** 作 者: 徐亦朱
** 日 期: 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主机端点的发送缓冲区写入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端点输出CBW
if ( s == USB_INT_DISCONNECT ) //检测到USB设备断开事件,磁盘已经断开
{
return( s ) ;
printf ( " 检测到USB设备断开事件,磁盘已经断开 \n " ) ;
}
if ( s != USB_INT_SUCCESS ) //发送CBW失败
{
printf ( " 发送CBW失败,准备复位重试 \n " ) ;
mResetErrorBOC( s ) ;
//向CH374主机端点的发送缓冲区写入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端点输出CBW
if ( s != USB_INT_SUCCESS ) //发送CBW失败
{
printf( " 重试失败,复位并退出传输,返回错误码.\n " ) ;
return( mResetErrorBOC( s ) ) ;
}
}
mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG; //OUT端点的数据同步标志翻转
if ( mBOC.mCBW.mCBW_DataLen )
{
TotalLen = mBOC.mCBW.mCBW_DataLen ;
DataLength = mBOC.mCBW.mCBW_DataLen ;
if ( mBOC.mCBW.mCBW_Flag & 0x80 ) //IN事务
{
//Write374Byte( REG_USB_SETUP, Read374Byte( REG_USB_SETUP ) | BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ;
while( TotalLen )
{
mDelayuS( 100 ) ;
mSetBulkIn( );
s = HostTransactInter( ); //接受数据
if ( s != USB_INT_SUCCESS ) //操作失败
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端点错误
{
mClearEndpStall( mDiskBulkInEndp | 0x80 ) ;
printf ( " 接收数据时发生STALL错误.\n " ) ;
}
else
{
printf ( " 接收数据时发生未知错误!\n " ) ;
return( USB_INT_DISK_ERR ) ;
}
}
len = Read374Byte( REG_USB_LENGTH ) ;
Read374Block( RAM_HOST_RECV, len, DataBuf );
mSaveDevEndpTog ^= BIT_HOST_RECV_TOG ; //IN端点的数据同步标志翻转
DataBuf += len ;
if ( TotalLen > len )
TotalLen -= len ;
else
TotalLen = 0 ;
if ( len < 64 )
break;
}
}
else //OUT事务
{
//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( ); //发送数据
if ( s != USB_INT_SUCCESS ) //操作失败
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端点错误
{
mClearEndpStall( mDiskBulkOutEndp );
printf ( " 发送数据时发生STALL错误!\n " ) ;
break ;
}
else
{
printf ( " 发送数据时发生未知错误!\n " ) ;
return( USB_INT_DISK_ERR ) ;
}
}
DataBuf += len;
TotalLen -= len ;
mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG ; //OUT端点的数据同步标志翻转
}
}
}
//全速USB主机模式,USB总线空闲,发SOF
//Write374Byte( REG_USB_SETUP, M_SET_RAM_MODE_OFF( BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ) ;
//从USB盘的IN端点输入CSW
mSetBulkIn( ); //输入
s = HostTransactInter( ); //发送数据
if ( s != USB_INT_SUCCESS ) //接受CSW失败
{
printf( "接收CSW失败!\n" ) ;
if ( s == ( DEF_USB_PID_STALL | 0x20 ) ) //清除端点错误
{
mClearEndpStall( mDiskBulkInEndp | 0x80 );
printf ( " 接收数据时发生STALL错误!\n " ) ;
printf ( " 尝试重试接收CSW.\n " ) ;
mSetBulkIn( );
s = HostTransactInter( );
if ( s != USB_INT_SUCCESS )
{
printf( " 重试失败,复位并退出传输,返回错误码.\n " ) ;
return( mResetErrorBOC( s ) ) ;
}
}
else
{
printf ( " 接收CSW时发生未知错误!\n " ) ;
return( s );
}
}
len = Read374Byte( REG_USB_LENGTH ) ;
Read374Block( RAM_HOST_RECV, len, ( PUINT8 )( & mBOC.mCSW ) );
mSaveDevEndpTog ^= BIT_HOST_RECV_TOG ; //IN端点的数据同步标志翻转
//确认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 ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -