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

📄 ch365dll.c

📁 PCI总线接口芯片CH365的应用层接口库
💻 C
📖 第 1 页 / 共 4 页
字号:

BOOL	WINAPI	CH365ReadMemByte(  // 从存储器读取一个字节
	PVOID			iAddr,  // 指定存储器的地址,虚拟地址
	PUCHAR			oByte )  // 指向一个字节单元,用于保存读取的字节数据
{
	return( CH365mReadMemByte( 0, iAddr, oByte ) );
}

BOOL	WINAPI	CH365ReadMemDword(  // 从存储器读取一个双字
	PVOID			iAddr,  // 指定存储器的地址,虚拟地址
	PULONG			oDword )  // 指向一个双字单元,用于保存读取的双字数据
{
	return( CH365mReadMemDword( 0, iAddr, oDword ) );
}

BOOL	WINAPI	CH365WriteMemByte(  // 向存储器写入一个字节
	PVOID			iAddr,  // 指定存储器的地址,虚拟地址
	UCHAR			iByte )  // 待写入的字节数据
{
	return( CH365mWriteMemByte( 0, iAddr, iByte ) );
}

BOOL	WINAPI	CH365WriteMemDword(  // 向存储器写入一个双字
	PVOID			iAddr,  // 指定存储器的地址,虚拟地址
	ULONG			iDword )  // 待写入的双字数据
{
	return( CH365mWriteMemDword( 0, iAddr, iDword ) );
}

BOOL	WINAPI	CH365ReadConfig(  // 从配置空间读取一个字节数据
	PVOID			iOffset,  // 指定偏移地址
	PUCHAR			oByte )  // 指向一个字节单元,用于保存读取的字节数据
{
	return( CH365mReadConfig( 0, iOffset, oByte ) );
}

BOOL	WINAPI	CH365WriteConfig(  // 向配置空间写入一个字节数据
	PVOID			iOffset,  // 指定偏移地址
	UCHAR			iByte )  // 待写入的字节数据
{
	return( CH365mWriteConfig( 0, iOffset, iByte ) );
}

BOOL	WINAPI	CH365SetA15_A8(  // 设置高地址,即设置A15-A8的输出
	UCHAR			iA15_A8 )  // 位7-位0对应A15-A8的输出,1为高电平,0为低电平
{
	return( CH365mSetA15_A8( 0, iA15_A8 ) );
}

BOOL	WINAPI	CH365ReadI2C(  // 从I2C接口读取一个字节数据
	UCHAR			iDevice,  // 低7位指定I2C设备地址
	UCHAR			iAddr,  // 指定数据单元的地址
	PUCHAR			oByte )  // 指向一个字节单元,用于保存读取的字节数据
{
	return( CH365mReadI2C( 0, iDevice, iAddr, oByte ) );
}

BOOL	WINAPI	CH365WriteI2C(  // 向I2C接口写入一个字节数据
	UCHAR			iDevice,  // 低7位指定I2C设备地址
	UCHAR			iAddr,  // 指定数据单元的地址
	UCHAR			iByte )  // 待写入的字节数据
{
	return( CH365mWriteI2C( 0, iDevice, iAddr, iByte ) );
}

HANDLE	WINAPI	CH365mOpenDevice(  // 打开CH365设备,返回句柄,出错则无效
	ULONG			iIndex,  // 指定CH365设备序号,0对应第一个设备
	BOOL			iEnableMemory,  // 是否需要支持存储器
	BOOL			iEnableInterrupt )  // 是否需要支持中断
{
	UCHAR								mBuffer[1024];
	LPGUID								mClassGuid;
	HDEVINFO							mDevInfo;
	SP_INTERFACE_DEVICE_DATA			mDevIfData;
	PSP_INTERFACE_DEVICE_DETAIL_DATA	mDevIfDetail;
	if ( iIndex >= mCH365_MAX_NUMBER ) return( INVALID_HANDLE_VALUE );  // 太多设备,不支持
	mClassGuid = ( LPGUID )&CH365Guid;  // 设备类
	mDevInfo = SetupDiGetClassDevs( mClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );  // 获得指定设备类
	if ( mDevInfo == INVALID_HANDLE_VALUE ) return( INVALID_HANDLE_VALUE );
	mDevIfData.cbSize = sizeof( mDevIfData );
	if ( !SetupDiEnumDeviceInterfaces( mDevInfo, NULL, mClassGuid, iIndex, &mDevIfData ) ) {  // 枚举指定序号的设备
		SetupDiDestroyDeviceInfoList( mDevInfo );
		return( INVALID_HANDLE_VALUE );
	}
	mDevIfDetail = ( PSP_INTERFACE_DEVICE_DETAIL_DATA ) mBuffer;
	mDevIfDetail -> cbSize = sizeof( SP_INTERFACE_DEVICE_DETAIL_DATA );
	if ( !SetupDiGetDeviceInterfaceDetail( mDevInfo, &mDevIfData, mDevIfDetail, 1020, NULL, NULL ) ) {  // 获得设备详细信息
		SetupDiDestroyDeviceInfoList( mDevInfo );
		return( INVALID_HANDLE_VALUE );
	}
	lstrcpy( dllDeviceName[ iIndex ], mDevIfDetail -> DevicePath );  // 设备名称
	dllHandle[ iIndex ] = CreateFile( mDevIfDetail -> DevicePath, GENERIC_READ | GENERIC_WRITE,  // 打开设备,不支持重叠操作
							FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	SetupDiDestroyDeviceInfoList( mDevInfo );
	if ( dllHandle[ iIndex ] == INVALID_HANDLE_VALUE ) return( INVALID_HANDLE_VALUE );  // 没有打开CH365设备的权限
	CH365mGetIoBaseAddr( iIndex, & dllIoBaseAddr[ iIndex ] );  // 获取CH365的I/O基址
	CH365mGetMemBaseAddr( iIndex, & dllMemBaseAddr[ iIndex ] );  // 获取CH365的存储器基址
	if ( iEnableMemory && dllMemBaseAddr[ iIndex ] == NULL )  // 如果需要支持存储器并且存储器基址尚未设定
		CH365mSetMemBaseAddr( iIndex, mCH365_MEM_BASE_AUTO );  // 自动设定存储器基址
	CH365mGetIntLine( iIndex, & dllIntLine[ iIndex ] );  // 获得CH365的中断号
	if ( iEnableInterrupt && dllIntLine[ iIndex ] == 0 )  // 如果需要支持中断并且中断号尚未检测
		CH365mSetIntLine( iIndex, mCH365_INT_LINE_AUTO );  // 自动检测中断号
	return( dllHandle[ iIndex ] );
}

VOID	WINAPI	CH365mCloseDevice(  // 关闭CH365设备
	ULONG			iIndex )  // 指定CH365设备序号
{
	dllIntRoutine[ iIndex ] = NULL;  // 取消中断服务程序
	while ( dllIntThreadId[ iIndex ] ) CH365mAbortWaitInt( iIndex );  // 等待线程结束
	CloseHandle( dllHandle[ iIndex ] );  // 关闭句柄
	dllHandle[ iIndex ] = INVALID_HANDLE_VALUE;
}

ULONG	WINAPI	CH365mDriverCommand(  // 直接传递命令给驱动程序,出错则返回0,否则返回数据长度
	ULONG			iIndex,  // 指定CH365设备序号
	mPWIN32_COMMAND	ioCommand )  // 命令结构的指针
// 该程序在调用后返回数据长度,并且仍然返回命令结构,如果是读操作,则数据返回在命令结构中,
// 返回的数据长度在操作失败时为0,操作成功时为整个命令结构的长度,例如读一个字节,则返回mWIN32_COMMAND_HEAD+1,
// 命令结构在调用前,分别提供:命令功能代码,起始地址(可选),存取数据的长度(可选),
// 命令结构在调用后,分别返回:操作状态代码,返回的基址(可选),后续数据的长度(可选),
//   操作状态代码是由WINDOWS定义的代码,可以参考NTSTATUS.H,
//   返回的基址只适用于下列命令:获取I/O基址,获取存储器基址,获取中断号,对于其它命令则保持输入时的起始地址
//   后续数据的长度是指读操作返回的数据长度,数据存放在随后的缓冲区中,对于写操作一般为0
{
	ULONG	mLength;
	mLength = ioCommand -> mLength + mWIN32_COMMAND_HEAD;  // 数据缓冲区长度加上命令结构头的长度
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, ioCommand, mLength, ioCommand, mLength, &mLength, NULL ) )
		return( mLength );  // 返回数据长度
	else return( 0 );  // 出错
}

BOOL	WINAPI	CH365mGetIoBaseAddr(  // 获取I/O端口的基址
	ULONG			iIndex,  // 指定CH365设备序号
	mPCH365_IO_REG	*oIoBaseAddr )  // 保存I/O端口基址的单元地址
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncGetIoBaseAddr;
	mCommand.mAddress = NULL;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		dllIoBaseAddr[ iIndex ] = mCommand.mAddress;  // 返回的I/O端口的基址
		*oIoBaseAddr = dllIoBaseAddr[ iIndex ];  // 返回
		return( TRUE );
	}
	else return( FALSE );  // 出错
}

BOOL	WINAPI	CH365mSetIoBaseAddr(  // 设定I/O端口的基址
	ULONG			iIndex,  // 指定CH365设备序号
	mPCH365_IO_REG	iIoBaseAddr )  // 指定I/O端口基址
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncSetIoBaseAddr;
	mCommand.mAddress = iIoBaseAddr;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		CH365mGetIoBaseAddr( iIndex, & dllIoBaseAddr[ iIndex ] );  // 重新获取I/O端口的基址
		return( TRUE );
	}
	else {  // 出错
		CH365mGetIoBaseAddr( iIndex, & dllIoBaseAddr[ iIndex ] );  // 重新获取I/O端口的基址
		return( FALSE );
	}
}

BOOL	WINAPI	CH365mGetMemBaseAddr(  // 获取存储器的基址
	ULONG			iIndex,  // 指定CH365设备序号
	mPCH365_MEM_REG	*oMemBaseAddr )  // 保存存储器基址的单元地址
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncGetMemBaseAddr;
	mCommand.mAddress = NULL;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		dllMemBaseAddr[ iIndex ] = mCommand.mAddress;  // 返回的存储器的基址
		*oMemBaseAddr = dllMemBaseAddr[ iIndex ];  // 返回
		return( TRUE );
	}
	else return( FALSE );  // 出错
}

BOOL	WINAPI	CH365mSetMemBaseAddr(  // 设定存储器的基址
	ULONG			iIndex,  // 指定CH365设备序号
	mPCH365_MEM_REG	iMemBaseAddr )  // 指定存储器基址,为0则关闭存储器,为-1则自动设定
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncSetMemBaseAddr;
	mCommand.mAddress = iMemBaseAddr;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		CH365mGetMemBaseAddr( iIndex, & dllMemBaseAddr[ iIndex ] );  // 重新获取存储器的基址
		return( TRUE );
	}
	else {  // 出错
		CH365mGetMemBaseAddr( iIndex, & dllMemBaseAddr[ iIndex ] );  // 重新获取存储器的基地
		return( FALSE );
	}
}

BOOL	WINAPI	CH365mGetIntLine(  // 获取中断号
	ULONG			iIndex,  // 指定CH365设备序号
	PULONG			oIntLine )  // 保存中断号的单元地址
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncGetInterLine;
	mCommand.mAddress = NULL;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		dllIntLine[ iIndex ] = (ULONG) mCommand.mAddress;  // 返回的中断号
		*oIntLine = dllIntLine[ iIndex ];  // 返回
		return( TRUE );
	}
	else return( FALSE );  // 出错
}

BOOL	WINAPI	CH365mSetIntLine(  // 设定中断号
	ULONG			iIndex,  // 指定CH365设备序号
	ULONG			iIntLine )  // 指定中断号,为0则关闭中断,为-1则自动检测并设定
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncSetInterLine;
	mCommand.mAddress = (PVOID)iIntLine;
	mCommand.mLength = 0;
	if ( DeviceIoControl( dllHandle[ iIndex ], IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, NULL ) ) {
		CH365mGetIntLine( iIndex, & dllIntLine[ iIndex ] );  // 重新获取中断号
		return( TRUE );
	}
	else {  // 出错
		CH365mGetIntLine( iIndex, & dllIntLine[ iIndex ] );  // 重新获取中断号
		return( FALSE );
	}
}

BOOL	WINAPI	CH365mWaitInterrupt(  // 等待中断事件
	ULONG			iIndex )  // 指定CH365设备序号
{
	ULONG			mLength;
	mWIN32_COMMAND	mCommand;
	mLength = sizeof( mWIN32_COMMAND );
	mCommand.mFunction = mFuncWaitInterrupt;  // 等待中断事件,如果暂时没有中断事件则一直等待,直到发生中断或者放弃等待中断
	mCommand.mAddress = NULL;
	mCommand.mLength = 0;

⌨️ 快捷键说明

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