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

📄 ch365ckd.c

📁 南京沁恒电子有限公司USB通用设备接口芯片资料
💻 C
字号:
/* 2003.09.10
****************************************
**  Copyright  (C)  W.ch  1999-2003   **
**  Web:  http://www.winchiphead.com  **
****************************************
**  CHK for PCI interface chip CH365  **
**  C, TC2.0                          **
****************************************

 PCI总线接口芯片CH365的功能测试程序  V1.1
 南京沁恒电子有限公司  作者: W.ch 2003.09
 CH365-CHK  V1.1 ,    Support: IO/MEM/INT
 运行环境: DOS
*/

#include	<stdlib.h>
#include	<stdio.h>
#include	<conio.h>
#include	<dos.h>

#include	"CH365DOS.C"


USHORT			mPciAddr;		/* PCI地址,即总线/设备/功能号 */
mPCH365_IO_REG	mIoBase;		/* I/O基址 */
ULONG			mMemBase;		/* 存储器基址,线性地址 */
USHORT			mMemSeg;		/* 存储器的段地址 */
USHORT			mIntLine;		/* 中断号 */


/* 当CH365检测到来自INT_REQ引脚的低电平中断请求,就向PC机申请中断,CPU调用该中断服务程序,
   如果外部中断信号不是低电平脉冲或者不能自动撤消,则中断服务程序应该通知其撤消中断请求 */
void	far	interrupt	InterruptEvent( void )
{
	UCHAR	mChipIoCtrl, mByte, c;
	X86REG	mReg;

	mChipIoCtrl = inportb( (USHORT) & mIoBase -> mCh365IoCtrl );  /* 读取芯片控制寄存器 */

	if ( mChipIoCtrl & mBitIntAction ) {  /* 芯片中断被激活则说明是CH365请求中断 */

/* 如果外部电路向CH365发出低电平中断请求后,不能自动恢复为高电平,为了防止重复中断,
   中断服务程序应该通知外部电路撤消中断请求,恢复为高电平,防止重复中断 */
		outportb( (USHORT) & mIoBase -> mCh365MemAddrH, 0 );

/* 中断程序示例,从偏移地址2读取一个字节 */
		mByte = inportb( (USHORT) & mIoBase -> mCh365IoPort[2] );
/* 中断程序示例,写到存储器的01H地址 */
		pokeb( mMemSeg, 1, mByte );

/* 取消中断,PCI总线的中断一般是电平敏感并且可共享的,所以在确认中断后应该取消中断电平 */
		outportb( (USHORT) & mIoBase -> mCh365IoCtrl, mChipIoCtrl & ~ mBitIntAction );  /* 将中断激活位置为低电平 */

/* 硬件中断必须设置结束标志 */
		if ( mIntLine >= 8 ) {  /* 中断8-15 */
			outportb( 0xa0, 0x20 );  /* 中断8-15,中断结束 */
			if ( inportb( 0xa0 ) == 0 ) outportb( 0x20, 0x20 );  /* 中断嵌套,中断结束 */
		}
		else outportb( 0x20, 0x20 );  /* 中断0-7,中断结束 */
	}

	else {  /* 不是CH365的中断,所以,如果共享中断则应该将中断转交给原中断服务程序,否则直接返回 */

/*		dosOldInterrupt( ); */

	}

}

void	main()
{
	int     i;
	UCHAR	mByte;
	USHORT	mWord;
	FPVOID	mAddr;

	printf( "\nCH365 Check Program V1.0 ,   Copyright (C) W.ch 2003.08\n" );

/* 在进行所有操作前必须先检测CH365设备 */
	printf( "*** CH365CheckDevice " );
	mPciAddr = CH365CheckDevice( );
	if ( mPciAddr == 0 ) return;

/* 使用系统为CH365自动分配的I/O基址,则可以读取后使用,
   如果使用本地硬件定址功能,则在存取相应I/O端口时,可以直接指定I/O地址,
   例如,硬件定址在280H-28FH,则CH365在I/O地址为280H-28FH时可以存取 */
	printf( "*** CH365GetIoBaseAddr " );
	mIoBase = CH365GetIoBaseAddr( );
	printf( "= %04X \n", mIoBase );

/* 如果需要用到存储器,对于DOS4G或者WINDOWS可以直接读取存储器基址,但对于常用的DOS,
   由于DOS不能寻址1MB以上的内存区域,所以应该将存储器基址设置到1MB以下,建议采用自动地址 */
	printf( "*** CH365SetMemBaseAddr: AUTO " );
	if ( CH365SetMemBaseAddr( mCH365_MEM_BASE_AUTO ) == FALSE ) printf( " ERROR \n" );
	else printf( "= OK \n" );

/* 获取存储器的基址 */
	printf( "*** CH365GetMemBaseAddr: " );
	mMemBase = CH365GetMemBaseAddr( );
	printf( "= %08lX \n", mMemBase );
	mMemSeg = mMemBase >> 4;  /* 对于DOS,段地址为线性地址除以16 */

/* 如果需要用到中断,则应该设置中断号,建议自动检测CH365所用的中断号 */
	printf( "*** CH365SetIntLine: AUTO " );
	if ( CH365SetIntLine( mCH365_INT_LINE_AUTO ) == FALSE ) printf( " ERROR \n" );
	else printf( "= OK \n" );

/* 获取中断号,与ISA卡一样,数值为0-15,实际上,CH365只支持有限的几个中断号,
   例如3,4,5,7,9,10,11,12,15等,对于Windows XP,数值有可能是16-23 */
	printf( "*** CH365GetIntLine " );
	mIntLine = CH365GetIntLine( );
	printf( "= %04X \n", mIntLine );

	if ( mIntLine ) {  /* 已经启用中断 */

/* 下面连接中断服务程序,CH365硬件中断后被调用 */
		printf( "*** CH365SetIntRoutine: set interrupt service routine \n" );
		CH365SetIntRoutine( InterruptEvent );

	}

/* 从I/O空间的芯片控制单元读取数据 */
	printf( "*** Read Io Byte: addr=CH365_IO_CTRL, data " );
	mByte = inportb( (USHORT) & mIoBase -> mCh365IoCtrl );
	printf( "= %02X \n", mByte );

/* 向I/O空间的A15-A8地址设定单元写入数据,也可以将其分为两个字节读写 */
	printf( "*** Set A15-A8: data=0x69 " );
	mWord = inport( (USHORT) & mIoBase -> mCh365MemAddrL );
	outportb( (USHORT) & mIoBase -> mCh365MemAddrH, 0x69 );
	printf( "= OK \n" );

/* 向I/O空间的芯片控制单元写入数据,mByte是芯片控制寄存器的原数据 */
	mByte &= ~ mBitAddr15Out;  /* 将A15置为低电平 */
/*	mByte |= mBitSysExtOut;  */ /* 将SYS_EX置为高电平  */
	printf( "*** Write Io Byte: addr=CH365_IO_CTRL, data " );
	outportb( (USHORT) & mIoBase -> mCh365IoCtrl, mByte );
	printf( "= %02X \n", mByte );

/* 从存储器的0x02地址读取一个字节 */
	printf( "*** Read Mem Byte: addr=0x02, data " );
	mByte = peekb( mMemSeg, 0x0002 );  /* 读取一个字节 */
	printf( "= %02X \n", mByte );

/* 将数据加上0x37后写到存储器的0x03地址 */
	if ( mMemSeg ) {  /* 存储器有效 */
		mByte += 0x37;
		printf( "*** Write Mem Byte: addr=0x03, data " );
		pokeb( mMemSeg, 0x0003, mByte );  /* 写入一个字节 */
		printf( "= %02X \n", mByte );
/*		poke( mMemSeg, 0x0002, mWord );  */ /* 写入一个字 */
	}

	for( i=0; i<100; ++i) inportb(0x70);  /* 延时 */

/* 从I/O空间的本地数据输入缓冲寄存器读取数据 */
	printf( "*** Read Io Byte: addr=CH365_IO_BUF, data " );
	mByte = inportb( (USHORT) & mIoBase -> mCh365IoBuf );
	printf( "= %02X \n", mByte );

	printf( "*** Wait for a key to continue, Generate Interrupt if you enabled interrupt \n and connect PCI-STOP of CH365 to INTA of PCI \n " );
	getch();

/* 从I/O端口的偏移地址0x38读取数据,如果本地址端的该地址具有三态数据输出,则会被读出 */
	printf( "*** Read Io Byte: addr=0x38, data " );
	mByte = inportb( (USHORT) & mIoBase -> mCh365IoPort[0x38] );
	printf( "= %02X \n", mByte );

	for( i=0; i<100; ++i) inportb(0x70);  /* 延时 */

/* 从I/O空间的本地数据输入缓冲寄存器读取数据 */
	printf( "*** Read Io Byte: addr=CH365_IO_BUF, data " );
	mByte = inportb( (USHORT) & mIoBase -> mCh365IoBuf );
	printf( "= %02X \n", mByte );

/* 一次从存储器连续读取4个字节,每读取一个字节,地址自动增加1 */
	if ( mMemSeg ) {  /* 存储器有效 */
		printf( "*** Read Mem Byte: start_addr=0x00, length=0x04, data=" );
		mAddr = MK_FP( mMemSeg, 0 );  /* 构造远指针,数据块起始地址 */
		for ( i=0; i<4; ++i ) {
			mByte = *(FPUCHAR)mAddr;
			printf( "%02X-", mByte );
			++(PUCHAR)mAddr;
		}
		printf( "\n" );
	}

/* 数据总线D7-D0的静态状态可以从配置空间中读取,以了解总线空闲时的状态以及工作模式设定 */
	printf( "*** CH365ReadCfgByte: addr=CH365_CFG_DIN, data " );
	mByte = CH365ReadCfgByte( mOFFSET( mCH365_CFG_REG, mCh365CfgDin ) );
	printf( "= %02X \n", mByte );

/* 向A15-A8写入数据 */
	printf( "*** Set A15-A8: data=0x43 " );
	mWord = 0x4300;
	outport( (USHORT) & mIoBase -> mCh365MemAddrL, mWord );
	printf( "= OK \n" );

/* 从I2C接口所挂接的24C0X中读取一个字节的数据, 0x50是24C0X的7位设备地址,该24C0X的A2-A1-A0均接地 */
	printf( "*** CH365ReadI2C: device=0x50, addr=0x01, data " );
	mByte = CH365ReadI2C( 0x50, 0x01 );
	printf( "= %02X \n", mByte );

/* 向I2C接口所挂接的24C0X中写入一个字节的数据, 0x50是24C0X的7位设备地址,该24C0X的A2-A1-A0均接地 */
	mByte += 0x73;
	printf( "*** CH365WriteI2C: device=0x50, addr=0x01, data=%02X ", mByte );
	CH365WriteI2C( 0x50, 0x01, mByte );
	printf( "= OK \n" );
/* 对于EEPROM 24C01A/24C02/24C04/24C08/24C16在写操作后应该延时10毫秒,确保EEPROM擦写周期 */
	CH365DelayUS( 12000 );  /* 延时12000微秒, 即12毫秒 */

/* 从I/O空间的芯片控制单元读取数据 */
	printf( "*** Read Io Byte: addr=CH365_IO_CTRL, data " );
	mByte = inportb( (USHORT) & mIoBase -> mCh365IoCtrl );
	printf( "= %02X \n", mByte );

/* 向I/O空间的芯片控制单元写入数据,清除可能未响应的中断 */
	mByte &= ~ mBitIntAction;  /* 清除中断激活状态 */
	printf( "*** Write Io Byte: addr=CH365_IO_CTRL, data " );
	outportb( (USHORT) & mIoBase -> mCh365IoCtrl, mByte );
	printf( "= %02X \n", mByte );

	printf( "*** Wait for a key to close \n " );
	getch();

	if ( mIntLine ) {  /* 已经启用中断 */

/* 如果启用了中断功能,则应用程序结束前必须先取消中断服务程序 */
		printf( "*** CH365SetIntRountine: NULL \n" );
		CH365SetIntRoutine( NULL );

	}

	printf( "\nExit.\n" );
	getch();
}

⌨️ 快捷键说明

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