📄 ch365ckd.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 + -