求助:帮助修改如下函数 UINT8 Bulk_File( void );UINT8 mBulkOnlyCmd( PUINT8 DataBuf ) /* 执行基于BulkOnly协议的命令,该子程序比较简化,并未处理各种错误,实际应用必须处理 */ 楼 底

普通用户

randy { M }
等级:1
发表:1 回复:1
注册时间:2009-4-3

发表于:2009-6-22 11:04:00,来源于:219.234.81.65 发贴心情:
-----------------------------------------------------------------------------------------------------
/*
南京沁恒电子有限公司:
您们好!

前段时间使用贵公司的CH374芯片开发的U盘读写项目开发完工了,在此对贵公司技术
人员的热心服务和精博的知识表示由衷的感谢和敬意!

但在测试时遇到一些问题,希望你们再一次提供及时的帮助。

我开发时一直使用的是我自己的U盘,没有问题,可是在测试时,有一个LG(256M)的USB2.0高速U盘,不能正常通讯。仔细分析调试后,发现问题出在程序上,与芯片无关。U盘枚举能成功,但通讯一段时间后,下位机就不应答了,就不能正常通讯了;用Bus Hound对通讯进行观测时,发现上位机在发UFI 命令:25h (Read Capacity, 要求设备返回当前容量); 23h (Read Format Capacity, 查询当前容量及可用空间) 等命令时下位机就不发送数据了,或者发送数据后就不应答(发送CSW)了。

我的UINT8 Bulk_File( void ) 函数是实现Bulk-Only协议的文件传输的一个子程序(功能是把PC机的Bulk-only数据包通过CH374转发给U盘,同时发送或接收数据,并回传CSW状态码),是根据贵公司提供的USBDISK.c例程中的UINT8 mBulkOnlyCmd( PUINT8 DataBuf ) 子程序修改而来;
UINT8 mBulkOnlyCmd( PUINT8 DataBuf )
/* 执行基于Bulk-Only协议的文件传输,该子程序比较简化,并未处理各种错误,实际应用必须处理 * /

我的UINT8 Bulk_File( void ) 子函数也未对各种错误进行处理,所以导致通讯不正常。
因为对贵公司的CH374芯片不甚了解,希望你们能提供帮助,对我的UINT8 Bulk_File(void)
子程序进行改写,对其中的错误进行处理。(该子程序中用到的其它子函数,您们可查阅你
们的USBDISK.c例程,我没有进行大的修改。)

我感觉问题主要出在以下语句中。
s = HostTransactInter( ); // 接收数据
if ( s != ERR_SUCCESS ) // 操作失败
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) )
mClearEndpStall( mDiskBulkInEndp | 0x80 ); // 清除端点错误
break;
}
在发送CBW命令码,发送数据,接收数据,发送CSW应答码时,上述语句有何异同?又该
分别如何处理?

mResetErrorBOC( s ); // 复位端点错误
mClearEndpStall( mDiskBulkInEndp | 0x80 ); // 清除端点错误
两语句使用起来有何异同?又分别在何种情况下使用?

期待你们的及时回复!!

*/

/* 执行基于Bulk-Only协议的文件传输,该子程序比较简化,并未处理各种错误,实际应用必须处理 */
UINT8 Bulk_File( void )
{
// UINT8 s, len;
// UINT32 TotalLen;

while( (len=BulkOrInterruptOut(&gEp2OutStatus, RAM_HOST_TRAN, &mBOC.BulkBuf)) == 0xFF ) // 向CH374主机端点的发送缓冲区写入CBW
//该语句从主USB芯片接收缓冲区中读出数据到CH374发送缓冲区中,如读出成功,则跳出,否则循环直到读出成功。以下语句类同。
if( len!=USB_BO_CBW_SIZE ) return(0xFF);
Write374Byte( REG_USB_LENGTH, len );
mSetBulkOut( ); // 输出
#ifdef DEBUG_NOW
printf( "*B:C=%02XH\n", (UINT16)( mBOC.mCBW.mCBW_CB_Buf[0] ) );
#endif
s = HostTransactInter( ); // 向USB盘的OUT端点输出CBW
if ( s == USB_INT_DISCONNECT ) return( s ); // 检测到USB设备断开事件,磁盘已经断开
if ( s != ERR_SUCCESS ) // 发送CBW失败,再尝试一次
{
#ifdef DEBUG_NOW
printf( "*B:C1=%02XH\n", (UINT16)s );
#endif
mResetErrorBOC( s ); // 复位端点错误

while( (len=BulkOrInterruptOut(&gEp2OutStatus, RAM_HOST_TRAN,& mBOC.BulkBuf)) == 0xFF ) // 向CH374主机端点的发送缓冲区写入CBW
if( len!=USB_BO_CBW_SIZE ) return(0xFF);
Write374Byte( REG_USB_LENGTH, len );
mSetBulkOut( ); /* 输出 */
#ifdef DEBUG_NOW
printf( "*B:C2=%02XH\n", (UINT16)( mBOC.mCBW.mCBW_CB_Buf[0] ) );
#endif
s = HostTransactInter( ); /* 向USB盘的OUT端点输出CBW */
if ( s != ERR_SUCCESS ) return( mResetErrorBOC( s ) );
}

mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG; /* OUT端点的数据同步标志翻转 */

M_State = ST_BULK_FILE; // 命令传输成功,进入BULK FILE阶段

if ( mBOC.mCBW.mCBW_DataLen ) // 有数据需要传输,此处使用双缓冲区提高效率,但导致程序复杂
{
#ifdef BIG_ENDIAN
TotalLen = mSwapEndian32( mBOC.mCBW.mCBW_DataLen );
#else
TotalLen = mBOC.mCBW.mCBW_DataLen;
#endif

#ifdef CH374_Bulk_File_DOUBLE_BUF //#ifdef CH374_Bulk_File_DOUBLE_BUF #endif

if ( mBOC.mCBW.mCBW_Flag & 0x80 ) // 接收,从磁盘接收数据到PC机IN端点;D-->H
{
Write374Byte( REG_USB_SETUP, M_SET_RAM_MODE_2RX( BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ); /* 全速USB主机模式,USB总线空闲,发SOF,双缓冲区 */

mSetBulkIn( ); // 设置批量数据输入
while ( TotalLen ) // 有数据需要传输; 接收,从磁盘接收数据
{
//%% mSetBulkIn( ); // 设置批量数据输入
#ifdef DEBUG_NOW
printf( "*B:I=%lX\n", TotalLen );
#endif
s = HostTransactInter( ); // 接收数据
if ( s != ERR_SUCCESS ) // 操作失败
{
if ( s == ( DEF_USB_PID_STALL | 0x20 ) )
mClearEndpStall( mDiskBulkInEndp | 0x80 ); /* 清除端点错误 */
break;
}
// 数据操作成功

mSaveDevEndpTog ^= BIT_HOST_RECV_TOG; /* IN端点的数据同步标志翻转 */

len = Read374Byte( REG_USB_LENGTH );

if ( TotalLen > len ) TotalLen -= len;
else TotalLen = 0;

if ( len == 64 && TotalLen ) mSetBulkIn( ); // 准备下一次输入

Read374Block( mSaveDevEndpTog & BIT_HOST_RECV_TOG ? RAM_HOST_RECV : RAM_HOST_EXCH, len, DataBuf );
DataBuf += len;

if ( len < 64 ) break;
}
}
else // 发送,从PC机OUT端点发送数据到磁盘;H-->D
{
Write374Byte( REG_USB_SETUP, M_SET_RAM_MODE_2TX( BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ); /* 全速USB主机模式,USB总线空闲,发SOF,双缓冲区 */

len = TotalLen >= 64 ? 64 : TotalLen;
Write374Block( mSaveDevEndpTog & BIT_HOST_TRAN_TOG ? RAM_HOST_EXCH : RAM_HOST_TRAN, len, DataBuf );
Write374Byte( REG_USB_LENGTH, len );
mSetBulkOut( ); /* 输出 */

while ( TotalLen ) { /* 有数据需要传输 */
#ifdef DEBUG_NOW
printf( "*B:O=%lX\n", TotalLen );
#endif
TotalLen -= len;
DataBuf += len;
if ( len == 64 && TotalLen ) { /* 准备下一次输出 */
len = TotalLen >= 64 ? 64 : TotalLen;
Write374Block( mSaveDevEndpTog & BIT_HOST_TRAN_TOG ? RAM_HOST_TRAN : RAM_HOST_EXCH, len, DataBuf );
}
else len = 0;
s = HostTransactInter( ); /* 发送数据 */
if ( s != ERR_SUCCESS ) { /* 操作失败 */
if ( s == ( DEF_USB_PID_STALL | 0x20 ) )
mClearEndpStall( mDiskBulkOutEndp ); /* 清除端点错误 */
break;
}
mSaveDevEndpTog ^= BIT_HOST_TRAN_TOG; /* OUT端点的数据同步标志翻转 */
if ( len ) {
Write374Byte( REG_USB_LENGTH, len );
mSetBulkOut( ); /* 输出 */
}
else break;
}

}

Write374Byte( REG_USB_SETUP, M_SET_RAM_MODE_OFF( BIT_SETP_HOST_MODE | BIT_SETP_AUTO_SOF ) ); /* 全速USB主机模式,USB总线空闲,发SOF */

#else //#ifdef CH374_Bulk_File_DOUBLE_BUF #endif

if ( mBOC.mCBW.mCBW_Flag & 0x80 ) // 接收,从磁盘接收数据到PC机IN端点;D-->H
{
while ( TotalLen ) // 有数据需要传输; 接收,从磁盘接收数据
{ mSetBulkIn( ); // 设置批量数据输入
#ifdef DEBUG_NOW
printf( "*B:I=%lX\n", TotalLen );
#endif
s