⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdisk.c

📁 USB驱动程序 共写USB单片机开发者使用
💻 C
📖 第 1 页 / 共 3 页
字号:
	s = HostTransactInter( );  /* 从USB盘的IN端点输入CSW */
	if ( s != ERR_SUCCESS ) return( s );  /* 接收CSW失败 */
	mSaveDevEndpTog ^= BIT_HOST_RECV_TOG;  /* IN端点的数据同步标志翻转 */
	len = Read374Byte( REG_USB_LENGTH );
	Read374Block( RAM_HOST_RECV, len, (PUINT8)( & mBOC.mCSW ) );
	if ( len != USB_BO_CSW_SIZE || mBOC.mCSW.mCSW_Sig != USB_BO_CSW_SIG ) return( USB_INT_DISK_ERR );
	if ( mBOC.mCSW.mCSW_Status == 0 ) return( ERR_SUCCESS );
	else if ( mBOC.mCSW.mCSW_Status >= 2 ) return( mResetErrorBOC( USB_INT_DISK_ERR ) );
	else return( USB_INT_DISK_ERR );  /* 磁盘操作错误 */
}

/* ********** SCSI/RBC/UFI命令层 ********** */

/* 检查磁盘错误状态 */
UINT8	mRequestSense( void )
{
	UINT8	buf[0x12];
	mDelaymS( 20 );  // 延时20毫秒
#ifdef BIG_ENDIAN
	mBOC.mCBW.mCBW_DataLen = 0x12000000;
#else
	mBOC.mCBW.mCBW_DataLen = 0x00000012;
#endif
	mBOC.mCBW.mCBW_Flag = 0x80;
	mBOC.mCBW.mCBW_CB_Len = 6;
	mBOC.mCBW.mCBW_CB_Buf[0] = 0x03;  /* 命令码 */
	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] = 0x12;
	mBOC.mCBW.mCBW_CB_Buf[5] = 0x00;
	return( mBulkOnlyCmd( buf ) );  /* 执行基于BulkOnly协议的命令 */
}

/* 获取磁盘特性 */
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 ) );  /* 执行基于BulkOnly协议的命令 */
}

/* 获取磁盘容量 */
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 ) );  /* 执行基于BulkOnly协议的命令 */
}

/* 测试磁盘是否就绪 */
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 ) );  /* 执行基于BulkOnly协议的命令 */
}

/* 以扇区为单位从磁盘读取数据 */
UINT8	mReadSector( UINT32 StartLba, UINT8 SectCount, PUINT8 DataBuf )
{
	UINT8	err, s;
	UINT32	len;
	len = (UINT32)SectCount << 9;
	for ( err = 0; err < 3; err ++ ) {  /* 错误重试 */
#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;
		s = mBulkOnlyCmd( DataBuf );  /* 执行基于BulkOnly协议的命令 */
		if ( s == ERR_SUCCESS ) return( s );  /* 操作成功 */
		if ( s == USB_INT_DISCONNECT || s == USB_INT_CONNECT || s == USB_INT_CONNECT_LS ) return( s );  /* 检测到USB设备断开事件,磁盘已经断开或者刚刚重新插上 */
		mRequestSense( );
	}
	return( s );  /* 错误 */
}

/* 以扇区为单位将数据写入磁盘 */
UINT8	mWriteSector( UINT32 StartLba, UINT8 SectCount, PUINT8 DataBuf )
{
	UINT8	err, s;
	UINT32	len;
	len = (UINT32)SectCount << 9;
	for ( err = 0; err < 3; err ++ ) {  /* 错误重试 */
#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;
		s = mBulkOnlyCmd( DataBuf );  /* 执行基于BulkOnly协议的命令 */
		if ( s == ERR_SUCCESS ) return( s );  /* 操作成功 */
		if ( s == USB_INT_DISCONNECT || s == USB_INT_CONNECT || s == USB_INT_CONNECT_LS ) return( s );  /* 检测到USB设备断开事件,磁盘已经断开或者刚刚重新插上 */
		mRequestSense( );
	}
	return( s );  /* 错误 */
}

/* ********** 主程序 ********** */

/* 为printf和getkey输入输出初始化串口 */
void	mInitSTDIO( )
{
	SCON = 0x50;
	PCON = 0x80;
	TL2 = RCAP2L = 0 - 13; /* 24MHz晶振, 57600bps */
	TH2 = RCAP2H = 0xFF;
	T2CON = 0x34;  /* 定时器2用于串口的波特率发生器 */
	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( );  /* 为了让计算机通过串口监控演示过程 */
	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设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
		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;  // 设备已经断开,继续等待
		}
		mDelaymS( 20 );

		printf( "GetDeviceDescr: " );
		s = GetDeviceDescr( buf );  // 获取设备描述符
		if ( s != ERR_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 != ERR_SUCCESS ) {
			printf( "ERROR = %02X\n", (UINT16)s );
			goto WaitDeviceOut;  // 终止操作,等待USB设备拔出
		}
		printf( "\n" );

		printf( "GetConfigDescr: " );
		s = GetConfigDescr( buf );  // 获取配置描述符
		if ( s != ERR_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" );

/* 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等 */
		if ( ( (PUSB_CFG_DESCR_LONG)buf ) -> itf_descr.bInterfaceClass != 0x08 ) goto WaitDeviceOut;  /* 不是USB存储类设备 */
		mDiskInterfNumber = ( (PUSB_CFG_DESCR_LONG)buf ) -> itf_descr.bInterfaceNumber;  /* 接口号 */
		mDiskBulkInEndp = 0;
		mDiskBulkOutEndp = 0;
		for ( i = 0; i < 2; i ++ ) {  /* 分析前两个端点 */
			if ( ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].wMaxPacketSize == 64 && ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bmAttributes == 2 ) {  /* 64字节长度的批量端点 */
				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 != ERR_SUCCESS ) {
			printf( "ERROR = %02X\n", (UINT16)s );
			goto WaitDeviceOut;  // 终止操作,等待USB设备拔出
		}
		printf( "\n" );
		mSaveDevEndpTog = 0x00;  // 清同步标志

		printf( "Disk Inquiry: " );
		s = mDiskInquiry( buf );  /* 获取磁盘特性 */
		if ( s != ERR_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" );

		for ( i = 0; i < 5; i ++ ) {
			mDelaymS( 100 );
			printf( "Disk Capacity: " );
			s = mDiskCapacity( buf );  /* 获取磁盘容量 */
			if ( s != ERR_SUCCESS ) {
				printf( "ERROR = %02X\n", (UINT16)s );
				mRequestSense( );
			}
			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 ) );
				break;
			}
		}

		printf( "Disk Ready: " );
		s = mDiskTestReady( );  /* 测试磁盘是否就绪 */
		if ( s != ERR_SUCCESS ) {
			printf( "ERROR = %02X\n", (UINT16)s );
		}
		else printf( "\n" );

		printf( "Disk Read First Sector: " );
		s = mReadSector( 0x00000000, 1, DISK_BUF );  /* 以扇区为单位从磁盘读取数据 */
		if ( s != ERR_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 );  /* 以扇区为单位将数据写入磁盘 */
		if ( s != ERR_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 + -