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

📄 ch375hft.c

📁 USB芯片CH372的驱动代码。较为详细
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -