|
|
#include "StdAfx.h"
|
|
|
#include "PciCh365Mgr.h"
|
|
|
#include "LogMgr.h"
|
|
|
#include "LaipuVbDllMgr.h"
|
|
|
#include "PciPortMgr.h"
|
|
|
#include "ExceptionMsg.h"
|
|
|
#include "MotionCtrl.h"
|
|
|
#include "WarningMgr.h"
|
|
|
|
|
|
CPciCh365Mgr *gPciCh365Mgr = new CPciCh365Mgr;
|
|
|
CPciCh365Mgr::CPciCh365Mgr(void)
|
|
|
{
|
|
|
m_bIni = false;//pci 卡是否初始化成功
|
|
|
}
|
|
|
CPciCh365Mgr::~CPciCh365Mgr(void)
|
|
|
{
|
|
|
}
|
|
|
bool CPciCh365Mgr::ReadDll()
|
|
|
{
|
|
|
m_PciCh365Handle = LoadLibrary( "CH365DLL.DLL" );
|
|
|
if( !m_PciCh365Handle )
|
|
|
{
|
|
|
CString AddInfo;
|
|
|
AddInfo += "Read CH365DLL Error";
|
|
|
return false;
|
|
|
}
|
|
|
//读取需要的函数地址
|
|
|
bool result = true;
|
|
|
result &= ((CH365mOpenDevice = (pCH365mOpenDevice)GetProcAddress( m_PciCh365Handle, "CH365mOpenDevice" )) != NULL);
|
|
|
result &= ((CH365mReadIoByte = (pCH365mReadIoByte)GetProcAddress( m_PciCh365Handle, "CH365mReadIoByte" )) != NULL);
|
|
|
result &= ((CH365mSetA15_A8 = (pCH365mSetA15_A8)GetProcAddress( m_PciCh365Handle, "CH365mSetA15_A8" )) != NULL);
|
|
|
result &= ((CH365mWriteIoByte = (pCH365mWriteIoByte)GetProcAddress( m_PciCh365Handle, "CH365mWriteIoByte" )) != NULL);
|
|
|
result &= ((CH365mCloseDevice = (pCH365mCloseDevice)GetProcAddress( m_PciCh365Handle, "CH365mCloseDevice" )) != NULL);
|
|
|
if(!result)
|
|
|
{
|
|
|
CString AddInfo;
|
|
|
AddInfo += "Get Proc Address Error";
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
void CPciCh365Mgr::InitIOTestComb(CComboBox &PortNumComb)
|
|
|
{
|
|
|
CString Str;
|
|
|
for(int k=0;k<ALL_PORT_CNT;k++)
|
|
|
{
|
|
|
Str.Format("%ld",k);
|
|
|
PortNumComb.AddString(Str);
|
|
|
}
|
|
|
|
|
|
PortNumComb.SetCurSel(0);
|
|
|
}
|
|
|
|
|
|
#if 1
|
|
|
//初始化pci 卡
|
|
|
void CPciCh365Mgr::OnAppInitialize()
|
|
|
{
|
|
|
return;
|
|
|
InitCard();
|
|
|
}
|
|
|
void CPciCh365Mgr::InitCard()
|
|
|
{
|
|
|
m_OutPortStateLow = 0;//记录当前输出端口的状态--用于向端口写数据
|
|
|
m_OutPortStateHigh = 0;//记录当前输出端口的状态--用于向端口写数据
|
|
|
//获取硬件支持的高精度计数器的频率
|
|
|
IniClockFre();
|
|
|
if(ReadDll())//读取dll
|
|
|
{
|
|
|
//自己初始化pci 卡
|
|
|
if(IniPciCard())
|
|
|
{
|
|
|
//初始化输出 端口的状态
|
|
|
IniOutPortState();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//检查pci 卡的状态
|
|
|
bool CPciCh365Mgr::CheckPciCardState()
|
|
|
{
|
|
|
HANDLE DeviceHandle = CH365mOpenDevice(0,true,true);
|
|
|
if((int)DeviceHandle==-1)
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|
|
|
//自己初始化pci 卡
|
|
|
bool CPciCh365Mgr::IniPciCard()
|
|
|
{
|
|
|
//初始化pci 卡
|
|
|
m_DeviceHandle = CH365mOpenDevice(0,true,true);
|
|
|
if((int)m_DeviceHandle==-1)
|
|
|
{
|
|
|
CString AddInfo;
|
|
|
AddInfo += "Not Find device";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//初始化输入端口(否则输入端口无法读取)
|
|
|
UCHAR ChByte = 0xFF;
|
|
|
CH365mSetA15_A8(0,ChByte);//恢复高8位地址
|
|
|
|
|
|
m_bIni = true;
|
|
|
gLogMgr->WriteDebugLog("PciCh365 Init Ok");
|
|
|
return true;
|
|
|
}
|
|
|
//初始化输出 端口的状态
|
|
|
void CPciCh365Mgr::IniOutPortState()
|
|
|
{
|
|
|
gLogMgr->WriteDebugLog("IniOutPortState",_LOG_FUNC);
|
|
|
|
|
|
int OutPortDefaultStateL = gPciPortMgr->GetOutPortDefaultStateL();
|
|
|
int OutPortDefaultStateH = gPciPortMgr->GetOutPortDefaultStateH();
|
|
|
for(int i=0;i<8;i++)//低八位
|
|
|
{
|
|
|
if(IsBitOn((BYTE)OutPortDefaultStateL,i))
|
|
|
{
|
|
|
SPciPort PciPort;
|
|
|
PciPort.num = i;
|
|
|
WritePortState(PciPort,true);
|
|
|
}
|
|
|
}
|
|
|
for(int i=0;i<8;i++)//高八位
|
|
|
{
|
|
|
if(IsBitOn((BYTE)OutPortDefaultStateH,i))
|
|
|
{
|
|
|
SPciPort PciPort;
|
|
|
PciPort.num = i+8;
|
|
|
WritePortState(PciPort,true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//检查pci 是否初始化了,没有则抛出异常,也就是说调用这个函数时PCI 必须初始化
|
|
|
void CPciCh365Mgr::CheckIniState()
|
|
|
{
|
|
|
if(!m_bIni)
|
|
|
{
|
|
|
CString str(_T("PciCh365 Init Error"));
|
|
|
CExceptionMsg Msg;
|
|
|
Msg.SetMsg(str);
|
|
|
throw Msg;
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
#if 1//延时
|
|
|
//微秒级延时,us为微秒
|
|
|
void CPciCh365Mgr::DelayTime(unsigned int us)
|
|
|
{
|
|
|
if(m_bHasSmartClock && us>0)
|
|
|
{
|
|
|
LARGE_INTEGER start, end;
|
|
|
LONGLONG count = (us*m_ClockFre.QuadPart)/(1000*1000);
|
|
|
QueryPerformanceCounter(&start);
|
|
|
count = count + start.QuadPart ;
|
|
|
do
|
|
|
{
|
|
|
QueryPerformanceCounter(&end);
|
|
|
}while(end.QuadPart<count);
|
|
|
}
|
|
|
}
|
|
|
//获取硬件支持的高精度计数器的频率
|
|
|
void CPciCh365Mgr::IniClockFre()
|
|
|
{
|
|
|
m_bHasSmartClock = QueryPerformanceFrequency(&m_ClockFre);
|
|
|
if(!m_bHasSmartClock)
|
|
|
{
|
|
|
CString AddInfo;
|
|
|
AddInfo += "QueryPerformanceFrequency Error";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
gLogMgr->WriteDebugLog("QueryPerformanceFrequency Ok");
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
#if 1
|
|
|
//从指定端口读入一个字节
|
|
|
BOOL CPciCh365Mgr::ReadIoPortByte(int PortAddr,long &PortVal)
|
|
|
{
|
|
|
BOOL result = FALSE;
|
|
|
UCHAR ChByte;
|
|
|
USHORT mAddr=(USHORT)PortAddr;
|
|
|
UINT mIndex= 0 ;
|
|
|
if(PortAddr<255)
|
|
|
{
|
|
|
if(CH365mReadIoByte(mIndex,(PVOID)mAddr,&ChByte))
|
|
|
{
|
|
|
PortVal = (long)ChByte;
|
|
|
result = TRUE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ChByte = PortAddr/256;
|
|
|
CH365mSetA15_A8(0,ChByte);//设定高8位地址
|
|
|
|
|
|
PortAddr = PortAddr%256;
|
|
|
if(CH365mReadIoByte(mIndex,(PVOID)&PortAddr,&ChByte))
|
|
|
{
|
|
|
PortVal = (long)ChByte;
|
|
|
result = TRUE;
|
|
|
}
|
|
|
ChByte = 0xFF;
|
|
|
CH365mSetA15_A8(0,ChByte);//恢复高8位地址
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
//向指定端口写入一个字节
|
|
|
void CPciCh365Mgr::WriteIoPortByte(int PortAddr,long PortVal)
|
|
|
{
|
|
|
UCHAR ChByte;
|
|
|
if(PortAddr<255)
|
|
|
{
|
|
|
USHORT mAddr=(USHORT)PortAddr;
|
|
|
ChByte = (UCHAR)PortVal;
|
|
|
CH365mWriteIoByte(0,(PVOID)mAddr,ChByte);//端口写入一次时间大约需要4us
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ChByte = PortAddr>>8;
|
|
|
CH365mSetA15_A8(0,ChByte);//设定高8位地址
|
|
|
|
|
|
USHORT mAddr=(USHORT)(PortAddr%256);
|
|
|
ChByte = (UCHAR)PortVal;
|
|
|
CH365mWriteIoByte(0,(PVOID)mAddr,ChByte);
|
|
|
ChByte = 0xFF;
|
|
|
CH365mSetA15_A8(0,ChByte);//恢复高8位地址
|
|
|
}
|
|
|
}
|
|
|
//设置端口状态
|
|
|
void CPciCh365Mgr::WritePortState(SPciPort PciPort,bool bOpen)
|
|
|
{
|
|
|
//检查pci 初始化状态
|
|
|
CheckIniState();
|
|
|
|
|
|
if(PciPort.num == -1)
|
|
|
return;
|
|
|
//处理高八位还是低八位
|
|
|
bool bLow = LowOrHight(PciPort.num);
|
|
|
//获得输出端口状态
|
|
|
long &OutPortState = GetOutPortState(bLow);
|
|
|
//获得端口地址
|
|
|
int PortAddr = GetPortAddr(bLow,true);
|
|
|
//反向操作
|
|
|
if(PciPort.bReverse)
|
|
|
{
|
|
|
bOpen = !bOpen;
|
|
|
}
|
|
|
|
|
|
if(bOpen)
|
|
|
{
|
|
|
OutPortState = SetBitOn(OutPortState,PciPort.num);
|
|
|
WriteIoPortByte(PortAddr,OutPortState);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
OutPortState = SetBitOff(OutPortState,PciPort.num);
|
|
|
WriteIoPortByte(PortAddr,OutPortState);
|
|
|
}
|
|
|
}
|
|
|
//PortIdx 0~15
|
|
|
void CPciCh365Mgr::WritePortByIdx(int PortIdx,bool bOpen)
|
|
|
{
|
|
|
CString log;
|
|
|
log.Format(" PortIdx = %ld,bOn = %ld",PortIdx,bOpen);
|
|
|
log = "PciCh365---->" + log;
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
|
|
|
SPciPort PciPort;
|
|
|
PciPort.num = PortIdx;
|
|
|
WritePortState(PciPort,bOpen);
|
|
|
}
|
|
|
#endif
|