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

📄 ch365dll.c

📁 PCI总线接口芯片CH365的应用层接口库
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	PVOID			mAddress;
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	if ( iAddr >= (PVOID)dllMemBaseAddr[ iIndex ] ) mAddress = iAddr;  // 直接指定地址
	else mAddress = (PUCHAR)dllMemBaseAddr[ iIndex ] + (ULONG)iAddr;  // 只是指定偏移地址,要加上基址
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncWriteMemByte;  // 以字节为单位写入存储器
	mCommand.mAddress = mAddress;
	mCommand.mLength = 1;
	mCommand.mBuffer[0] = iByte;  // 待写入的字节数据
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) )
		return( TRUE );
	else return( FALSE );
}

BOOL	WINAPI	CH365mWriteMemDword(  // 向存储器写入一个双字
	ULONG			iIndex,  // 指定CH365设备序号
	PVOID			iAddr,  // 指定存储器的地址,虚拟地址
	ULONG			iDword )  // 待写入的双字数据
{
	PVOID			mAddress;
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	if ( iAddr >= (PVOID)dllMemBaseAddr[ iIndex ] ) mAddress = iAddr;  // 直接指定地址
	else mAddress = (PUCHAR)dllMemBaseAddr[ iIndex ] + (ULONG)iAddr;  // 只是指定偏移地址,要加上基址
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncWriteMemDword;  // 以双字为单位写入存储器
	mCommand.mAddress = mAddress;
	mCommand.mLength = 4;
	*(PULONG) & mCommand.mBuffer[0] = iDword;  // 待写入的双字数据
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) )
		return( TRUE );
	else return( FALSE );
}

BOOL	WINAPI	CH365mReadConfig(  // 从配置空间读取一个字节数据
	ULONG			iIndex,  // 指定CH365设备序号
	PVOID			iOffset,  // 指定偏移地址
	PUCHAR			oByte )  // 指向一个字节单元,用于保存读取的字节数据
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncReadConfig;  // 以字节为单位读取配置空间
	mCommand.mAddress = iOffset;
	mCommand.mLength = 1;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		*oByte = mCommand.mBuffer[0];  // 返回读取的字节数据
		return( TRUE );
	}
	else return( FALSE );
}

BOOL	WINAPI	CH365mWriteConfig(  // 向配置空间写入一个字节数据
	ULONG			iIndex,  // 指定CH365设备序号
	PVOID			iOffset,  // 指定偏移地址
	UCHAR			iByte )  // 待写入的字节数据
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncWriteConfig;  // 以字节为单位写入配置空间
	mCommand.mAddress = iOffset;
	mCommand.mLength = 1;
	mCommand.mBuffer[0] = iByte;  // 待写入的字节数据
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) )
		return( TRUE );
	else return( FALSE );
}

BOOL	WINAPI	CH365mSetA15_A8(  // 设置高地址,即设置A15-A8的输出
	ULONG			iIndex,  // 指定CH365设备序号
	UCHAR			iA15_A8 )  // 位7-位0对应A15-A8的输出,1为高电平,0为低电平
{
	PVOID			mAddress;
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncWriteIoByte;  // 以字节为单位写入I/O端口
	mCommand.mAddress = & dllIoBaseAddr[ iIndex ] -> mCh365MemAddrH;  // A15-A8地址设定寄存器
	mCommand.mLength = 1;
	mCommand.mBuffer[0] = iA15_A8;  // 改变A15-A8
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) )
		return( TRUE );
	return( FALSE );
}

BOOL	WINAPI	CH365mReadI2C(  // 从I2C接口读取一个字节数据
	ULONG			iIndex,  // 指定CH365设备序号
	UCHAR			iDevice,  // 低7位指定I2C设备地址
	UCHAR			iAddr,  // 指定数据单元的地址
	PUCHAR			oByte )  // 指向一个字节单元,用于保存读取的字节数据
{
	UCHAR			mByte;
	if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cDev, (UCHAR) ( iDevice << 1 | 0x01 ) ) ) {  // 设备地址和命令
		if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cAddr, iAddr ) ) {  // 设定地址
			if ( CH365mReadIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, &mByte ) ) {  // 读取控制和状态
				mByte |= 0x01;  // 位0置1则启动操作
				if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, mByte ) ) {  // 开始读操作
					while ( mByte & 0x01 ) CH365mReadIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, &mByte );  // 等待读操作完成
					if ( CH365mReadIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cData, oByte ) ) {  // 返回读取的数据
						CH365DelayUS( 4 );  // 延时4uS作为两次I2C操作的间隔
						return( TRUE );
					}
				}
			}
		}
	}
	return( FALSE );
}

BOOL	WINAPI	CH365mWriteI2C(  // 向I2C接口写入一个字节数据
	ULONG			iIndex,  // 指定CH365设备序号
	UCHAR			iDevice,  // 低7位指定I2C设备地址
	UCHAR			iAddr,  // 指定数据单元的地址
	UCHAR			iByte )  // 待写入的字节数据
{
	UCHAR			mByte;
	if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cDev, (UCHAR) ( iDevice << 1 | 0x00 ) ) ) {  // 设备地址和命令
		if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cAddr, iAddr ) ) {  // 设定地址
			if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cData, iByte ) ) {  // 待写入的数据
				if ( CH365mReadIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, &mByte ) ) {  // 读取控制和状态
					mByte |= 0x01;  // 位0置1则启动操作
					if ( CH365mWriteIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, mByte ) ) {  // 开始写操作
						while ( mByte & 0x01 ) CH365mReadIoByte( iIndex, & dllIoBaseAddr[ iIndex ] -> mCh365I2cCtrl, &mByte );  // 等待写操作完成
						CH365DelayUS( 4 );  // 延时4uS作为两次I2C操作的间隔
						return( TRUE );
					}
				}
			}
		}
	}
	return( FALSE );
}

BOOL	WINAPI	CH365DelayUS(  // 延时指定微秒
	ULONG			iDelay )  // 指定要延时的微秒数,如果延时小于10则误差较大
{
	UCHAR			mByte;
	UCHAR			mTime;
	ULONG			ms, us;
	ULONG			mIndex;
	for ( mIndex = 0; mIndex < mCH365_MAX_NUMBER; ++mIndex ) if ( dllHandle[ mIndex ] != INVALID_HANDLE_VALUE ) break;  // 搜索一个有效句柄
	if ( mIndex >= mCH365_MAX_NUMBER ) return( FALSE );  // 设备句柄无效
	ms = iDelay / 983;  // 计算硬件计时周期, 983.04uS, 近似1毫秒
	us = iDelay % 983;  // 计算剩余微秒数
	while ( ms -- ) {  // CH365硬件循环计数周期
		CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 读取硬件循环计数寄存器 */
		mTime = mByte;
		while ( mByte == mTime ) CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 等待计数开始 */
		while ( mByte != mTime ) CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 等待一个计数周期 */
	}
	if ( us > 10 ) {  /* 剩余微秒数大于10 */
		mTime = (UCHAR)( ( 50 * us ) / (ULONG)( 50 * 3.84 ) );  /* 计算硬件计时数, 3.84uS */
		CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 读取硬件循环计数寄存器 */
		mTime += mByte;  /* 加上起始值为计数终值 */
		while ( mByte != mTime ) CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 等待计数结束 */
	}
	else {  /* 剩余微秒数小于10 */
		while ( us -- ) {  /* 每个周期近似1uS */
			CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 读取硬件循环计数寄存器 */
			CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 读取硬件循环计数寄存器 */
			CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte );  /* 读取硬件循环计数寄存器 */
		}
	}
}

BOOL	WINAPI	CH365mAccessBlock(  // 读取或者写入数据块
	ULONG			iIndex,  // 指定CH365设备序号
	ULONG			iAccessMode,  // 参考下面的说明
	PVOID			iAddr,  // 指定I/O端口或者存储器的地址
	PVOID			ioBuffer,  // 指向输入或者输出的缓冲区,存放读出的数据或者准备写出的数据
	ULONG			iLength )  // 数据块长度,也就是读取或者写入的字节数,长度不超过32KB
// iAccessMode 定义如下
// #define		mFuncReadIoByte			0x00000010	// 读取输入输出端口,在同一个端口地址以字节为单位连续读取,最大长度32KB
// #define		mFuncReadIoWord			0x00000011	// 读取输入输出端口,在同一个端口地址以字为单位连续读取,最大长度32KB
// #define		mFuncReadIoDword		0x00000012	// 读取输入输出端口,在同一个端口地址以双字为单位连续读取,最大长度32KB
// #define		mFuncReadIoBlock		0x00000013	// 读取输入输出端口,每读取一个字节,端口地址加一,最大长度240B(从偏移地址00H读到EFH)
// #define		mFuncWriteIoByte		0x00000014	// 写入输入输出端口,在同一个端口地址以字节为单位连续写入,最大长度32KB
// #define		mFuncWriteIoWord		0x00000015	// 写入输入输出端口,在同一个端口地址以字为单位连续写入,最大长度32KB
// #define		mFuncWriteIoDword		0x00000016	// 写入输入输出端口,在同一个端口地址以双字为单位连续写入,最大长度32KB
// #define		mFuncWriteIoBlock		0x00000017	// 写入输入输出端口,每写入一个字节,端口地址加一,最大长度240B(从偏移地址00H写到EFH)
// #define		mFuncReadMemByte		0x00000018	// 读取存储器/寄存器,以字节为单位连续读,每读取一个字节,地址加一,最大长度32KB(从偏移地址0000H读到7FFFH)
// #define		mFuncReadMemWord		0x00000019	// 读取存储器/寄存器,以字为单位连续读,每读取一个字,地址加二,最大长度32KB(从偏移地址0000H读到7FFFH)
// #define		mFuncReadMemDword		0x0000001a	// 读取存储器/寄存器,以双字为单位连续读,每读取一个字节,地址加四,最大长度32KB(从偏移地址0000H读到7FFFH)
// #define		mFuncWriteMemByte		0x0000001c	// 写入存储器/寄存器,以字节为单位连续写,每读取一个字节,地址加一,最大长度32KB(从偏移地址0000H写到7FFFH)
// #define		mFuncWriteMemWord		0x0000001d	// 写入存储器/寄存器,以字为单位连续写,每读取一个字,地址加二,最大长度32KB(从偏移地址0000H写到7FFFH)
// #define		mFuncWriteMemDword		0x0000001e	// 写入存储器/寄存器,以双字为单位连续写,每读取一个双字,地址加四,最大长度32KB(从偏移地址0000H写到7FFFH)
// 其它方式不支持,上述定义在文件CH365DLL.H中
{
	BOOL			mRead;
	PVOID			mAddress;
	ULONG			mLength;
	UCHAR			mBuffer[ mWIN32_COMMAND_HEAD + 1024 ];
	mPWIN32_COMMAND	mpCommand;
	mRead = FALSE;
	switch ( iAccessMode ) {
		case mFuncReadIoByte:
		case mFuncReadIoWord:
		case mFuncReadIoDword:
			mRead = TRUE;
		case mFuncWriteIoByte:
		case mFuncWriteIoWord:
		case mFuncWriteIoDword:
//			if ( iAddr >= (PVOID)dllIoBaseAddr[ iIndex ] ) mAddress = iAddr;  // 直接指定地址
			if ( iAddr >= (PVOID)0x0100 ) mAddress = iAddr;  // 本址定址功能的ISA兼容地址
			else mAddress = (PUCHAR)dllIoBaseAddr[ iIndex ] + (ULONG)iAddr;  // 只是指定偏移地址,要加上基址
			break;
		case mFuncReadIoBlock:
			mRead = TRUE;
		case mFuncWriteIoBlock:
//			if ( iAddr >= (PVOID)dllIoBaseAddr[ iIndex ] ) mAddress = iAddr;  // 直接指定地址
			if ( iAddr >= (PVOID)0x0100 ) mAddress = iAddr;  // 本址定址功能的ISA兼容地址
			else mAddress = (PUCHAR)dllIoBaseAddr[ iIndex ] + (ULONG)iAddr;  // 只是指定偏移地址,要加上基址
			if ( ( (ULONG)mAddress & 0x00ff ) + iLength >= mOFFSET( mCH365_IO_REG, mCh365MemAddr ) ) return( FALSE );  /* 超出I/O连续地址范围 */
			break;
		case mFuncReadMemByte:
		case mFuncReadMemWord:
		case mFuncReadMemDword:
			mRead = TRUE;
		case mFuncWriteMemByte:
		case mFuncWriteMemWord:
		case mFuncWriteMemDword:
			if ( iAddr >= (PVOID)dllMemBaseAddr[ iIndex ] ) mAddress = iAddr;  // 直接指定地址
			else mAddress = (PUCHAR)dllMemBaseAddr[ iIndex ] + (ULONG)iAddr;  // 只是指定偏移地址,要加上基址
			break;
		default:
			return( FALSE );
			break;
	}
	mLength = mWIN32_COMMAND_HEAD + iLength;  // 缓冲区长度为命令结构头的长度加上数据长度
	if ( iLength == 0 ) return( TRUE );
	else if ( iLength <= 1024 ) mpCommand = (PVOID)mBuffer;  // 不超过默认缓冲区长度
	else if ( iLength > mMAX_BUFFER_LENGTH ) return( FALSE );  // 非正常长度
	else {  // 需要另外分配内存
		mpCommand = (mPWIN32_COMMAND)LocalAlloc( LMEM_FIXED, mLength );  // 分配内存
		if ( mpCommand == NULL ) return( FALSE );  // 分配内存失败
	}
	mpCommand -> mFunction = iAccessMode;  // 存取I/O端口或者存储器
	mpCommand -> mAddress = mAddress;
	mpCommand -> mLength = iLength;
	if ( mRead == FALSE ) CopyMemory( & mpCommand -> mBuffer[0], ioBuffer, iLength );  // 复制准备写入的数据
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, mpCommand, mLength, mpCommand, mLength, &mLength, NULL ) ) {
		if ( mRead == TRUE ) CopyMemory( ioBuffer, & mpCommand -> mBuffer[0], iLength );  // 返回读取的数据
		if ( (PUCHAR)mpCommand != mBuffer ) LocalFree( mpCommand );  // 如果是分配的内存则释放
		return( TRUE );
	}
	else {  // 出错
		if ( (PUCHAR)mpCommand != mBuffer ) LocalFree( mpCommand );  // 如果是分配的内存则释放
		return( FALSE );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -