|
- #include "stdafx.h"
- #include "NcAdpt.h"
- #include "Device.h"
- #include "NccmdDispatcher85A.h"
-
- #define FILE_ID 'NBP8'
-
- ////////////////////////////////////////////////////////////////////////////////
- // SynPort
- //
- class ISynPort
- {
- public:
- ISynPort();
- virtual ~ISynPort();
- virtual void Synchronize() = 0;
- protected:
- static ISynPort* ms_pSysPorts[64];
- friend class CSynPortManager;
- };
-
- ISynPort* ISynPort::ms_pSysPorts[64] = {NULL};
- ISynPort::ISynPort()
- {
- for (int _i = 0; _i < _countof(ms_pSysPorts); _i++)
- {
- if (ms_pSysPorts[_i] == NULL)
- {
- ms_pSysPorts[_i] = this;
- break;
- }
- }
- }
-
- ISynPort::~ISynPort()
- {
- for (int _i = 0; _i < _countof(ms_pSysPorts); _i++)
- {
- if (ms_pSysPorts[_i] == this)
- {
- ms_pSysPorts[_i] = NULL;
- break;
- }
- }
- }
-
- CSynPortManager* CSynPortManager::ms_pInstance = NULL;
- CSynPortManager* GetSynPortManager()
- {
- return CSynPortManager::ms_pInstance;
- }
-
- CSynPortManager::CSynPortManager()
- {
- CHECK_PARAM(ms_pInstance == NULL);
- ms_pInstance = this;
- }
-
- CSynPortManager::~CSynPortManager()
- {
- CHECK_PARAM(ms_pInstance == this);
- ms_pInstance = NULL;
- }
-
- void CSynPortManager::Synchronize()
- {
- for (int _i = 0; _i < _countof(ISynPort::ms_pSysPorts); _i++)
- {
- if (ISynPort::ms_pSysPorts[_i])
- ISynPort::ms_pSysPorts[_i]->Synchronize();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CLambdaAnalogOutPort
- //
- class CLambdaAnalogOutPort : public CAnalogOutPort
- {
- public:
- CLambdaAnalogOutPort(const char* pszName_) : CAnalogOutPort(pszName_){ TRACE("CLambdaAnalogOutPort\n"); }
- protected:
- virtual void OutByte(UINT nAddr_, BYTE nData_);
- };
-
- void CLambdaAnalogOutPort::OutByte(UINT nAddr_, BYTE nData_)
- {
- #if defined (SIMUDRIVER)
- return __super::OutByte(nAddr_, nData_);
- #endif
- CHECK_PARAM(GetBlockFrom32Addr(nAddr_) == 0x01);
- ((CNcBoardPcimc85A*)GetDevice())->SetOutPortMap(GetOffsetFrom32Addr(nAddr_), nData_);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CLambdaAnalogPort
- //
- class CLambdaAnalogPort : public CAnalogPort
- {
- public:
- CLambdaAnalogPort(const char* pszName_) : CAnalogPort(pszName_) { TRACE("CLambdaAnalogPort\n"); }
- virtual ~CLambdaAnalogPort() { m_analogPortInfo.nType = APT_INVALID; } // 析构函数调不到子类的虚函数
- protected:
- virtual bool InBit(UINT64 nAddr_);
- virtual void OutBit(UINT64 nAddr_, bool bValue_);
- virtual BYTE InByte(UINT nAddr_);
- virtual void OutByte(UINT nAddr_, BYTE nData_);
- };
-
- bool CLambdaAnalogPort::InBit(UINT64 nAddr_)
- {
- #if defined (SIMUDRIVER)
- return __super::InBit(nAddr_);
- #endif
- CHECK_PARAM(GetBlockFrom64Addr(nAddr_) == 0x01);
- BYTE _val = InByte(GetOffsetFrom64Addr(nAddr_));
- DWORD _bit = GetBitFrom64Addr(nAddr_);
- BYTE _mask = 1 << _bit;
-
- return (_val & _mask) != 0;
- }
-
- void CLambdaAnalogPort::OutBit(UINT64 nAddr_, bool bValue_)
- {
- #if defined (SIMUDRIVER)
- return __super::OutBit(nAddr_, bValue_);
- #endif
- CHECK_PARAM(GetBlockFrom64Addr(nAddr_) == 0x01);
- UINT32 _addr = GetOffsetFrom64Addr(nAddr_);
- DWORD _bit = GetBitFrom64Addr(nAddr_);
- BYTE _mask = 1 << _bit;
-
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- BYTE _map = _pDevice->GetOutPortMap(_addr);
- if (bValue_)
- _map |= _mask;
- else
- _map &= ~_mask;
-
- _pDevice->SetOutPortMap(_addr, _map);
- }
-
- BYTE CLambdaAnalogPort::InByte(UINT nAddr_)
- {
- #if defined (SIMUDRIVER)
- return __super::InByte(nAddr_);
- #endif
- CHECK_PARAM(GetBlockFrom32Addr(nAddr_) == 0x01);
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- return _pDevice->GetInPortMap(GetOffsetFrom32Addr(nAddr_));
- }
-
- void CLambdaAnalogPort::OutByte(UINT nAddr_, BYTE nData_)
- {
- #if defined (SIMUDRIVER)
- return __super::OutByte(nAddr_, nData_);
- #endif
-
- CHECK_PARAM(GetBlockFrom32Addr(nAddr_) == 0x01);
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- _pDevice->SetOutPortMap(GetOffsetFrom32Addr(nAddr_), nData_);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CLambdaInputPort
- //
- class CLambdaInputPort : public CInputPort
- {
- public:
- CLambdaInputPort(const char* pszName_) : CInputPort(pszName_) { TRACE("CLambdaInputPort\n"); }
- protected:
- virtual BYTE InByte(UINT nAddr_);
- virtual void OutByte(UINT nAddr_, BYTE nData_);
- };
-
- BYTE CLambdaInputPort::InByte(UINT nAddr_)
- {
- #if defined (SIMUDRIVER)
- return __super::InByte(nAddr_);
- #endif
- CHECK_PARAM(GetBlockFrom32Addr(nAddr_) == 0x01);
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- return ~_pDevice->GetInPortMap(GetOffsetFrom32Addr(nAddr_));
- }
-
- void CLambdaInputPort::OutByte(UINT nAddr_, BYTE nData_)
- {
- FatalError(FILE_ID, __LINE__);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CLambdaOutputPort
- //
- class CLambdaOutputPort : public COutputPort
- {
- public:
- CLambdaOutputPort(const char* pszName_) : COutputPort(pszName_) { TRACE("CLambdaOutputPort\n"); }
- protected:
- virtual BYTE InByte(UINT nAddr_);
- virtual void OutByte(UINT nAddr_, BYTE nData_);
- };
-
- BYTE CLambdaOutputPort::InByte(UINT nAddr_)
- {
- #if defined (SIMUDRIVER)
- return __super::InByte(nAddr_);
- #endif
- // 这里是为了得到初值的,对于Lambda的通信方案,输入和输出是分立的,一个端口
- // 即使既可以输入也可以输出,也不保证其输入和输出地址是一样的。所以初值就不
- // 要去读取来了,统一就是0就行了。 ---- 杨开锦 2014-02-11
- return ~BYTE(0);
- }
-
- void CLambdaOutputPort::OutByte(UINT nAddr_, BYTE nData_)
- {
- #if defined (SIMUDRIVER)
- return __super::OutByte(nAddr_, nData_);
- #endif
- CHECK_PARAM(GetBlockFrom32Addr(nAddr_) == 0x01);
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- _pDevice->SetOutPortMap(GetOffsetFrom32Addr(nAddr_), ~nData_);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CLambdaRS232
- //
- class CLambdaRS232 : public CLambdaPacketFifo
- {
- public:
- struct Info
- {
- CRS232Fifo* pTxFifo;
- CRS232Fifo* pRxFifo;
- unsigned short nID;
- unsigned char nBRCode;
- };
- CLambdaRS232(CLambdaController* pCtrl_, Info* pInfo_);
- virtual ~CLambdaRS232();
- virtual bool Update(int nUs_);
- virtual bool Dispatch(PACKAGE* pPackage_);
- protected:
- static const WORD c_nPnnRS232BR = 0x2200;
- static const WORD c_nPnnRS232TR = 0x2300;
- Info* m_pInfo;
- unsigned char m_nBRCode;
- };
-
- CLambdaRS232::CLambdaRS232(CLambdaController* pCtrl_, Info* pInfo_)
- {
- TRACE("CLambdaRS232 ID=0x%04X\n", pInfo_->nID);
- m_pInfo = pInfo_;
- m_nBRCode = 0xFF;
- pCtrl_->Add(this);
- }
-
- CLambdaRS232::~CLambdaRS232()
- {
- TRACE("~CLambdaRS232 ID=0x%04X\n", m_pInfo->nID);
- GetController()->Remove(this);
- }
-
- bool CLambdaRS232::Update(int nUs_)
- {
- if (!GetController())
- return false;
- if (!m_pInfo)
- return false;
-
- // 先设置波特率 ---- 杨开锦 2014-09-022
- if (m_nBRCode != m_pInfo->nBRCode)
- {
- PACKAGE _p;
- _p.nPnnCmd = DCMD_APPINFO;
- _p.nPnnLength = 6;
- _p.nPnnSubcmd = c_nPnnRS232BR + (m_pInfo->nID & 0xFF);
- _p.nPnnData[0] = m_pInfo->nBRCode;
- if (!GetController()->WritePacket(&_p, NULL))
- {
- TRACE("CLambdaRS232::Update => ID=0x%04X send BRCode error\n", m_pInfo->nID);
- return false;
- }
- m_nBRCode = m_pInfo->nBRCode;
- TRACE("CLambdaRS232::Update => ID=0x%04X BRCode=0x%02X\n", m_pInfo->nID, m_pInfo->nBRCode);
- }
-
- // 再发数据 ---- 杨开锦 2014-09-22
- if (GetController()->GetDownFreeSpace() < 256)
- return false;
- if (m_pInfo->pTxFifo->GetCount() > 0)
- {
- BYTE _nDataLen = min(m_pInfo->pTxFifo->GetCount(), 16);
- PACKAGE _p;
- _p.nPnnCmd = DCMD_APPINFO;
- _p.nPnnLength = _nDataLen + 5;
- _p.nPnnSubcmd = c_nPnnRS232TR + (m_pInfo->nID & 0xFF);
- m_pInfo->pTxFifo->Read((BYTE*)_p.nPnnData, _nDataLen);
- if (!GetController()->WritePacket(&_p, NULL))
- {
- TRACE("CLambdaRS232::Update => ID=0x%04X Tx error\n", m_pInfo->nID);
- return false;
- }
- TRACE("CLambdaRS232::Update => ID=0x%04X Tx", m_pInfo->nID);
- TRACE_HEX(_p.nPnnData, _nDataLen);
- }
-
- return true;
- }
-
- bool CLambdaRS232::Dispatch(PACKAGE* pPackage_)
- {
- if (!GetController())
- return false;
- if (!m_pInfo)
- return false;
-
- if (pPackage_ == NULL)
- return false;
- if (pPackage_->nPnnCmd != DCMD_APPINFO)
- return false;
- if (pPackage_->nPnnLength < 6)
- return false;
- if ((pPackage_->nPnnSubcmd & 0xFF00) != c_nPnnRS232TR)
- return false;
- if ((pPackage_->nPnnSubcmd & 0x00FF) != (m_pInfo->nID & 0xFF))
- return false;
-
- BYTE _nDataLen = pPackage_->nPnnLength - 5;
- m_pInfo->pRxFifo->Write((BYTE*)pPackage_->nPnnData, _nDataLen);
- TRACE("CLambdaRS232::Update => ID=0x%04X Rx", m_pInfo->nID);
- TRACE_HEX(pPackage_->nPnnData, _nDataLen);
- return true;
- }
-
- class CLambdaRS232Manager : public CRS232
- {
- public:
- CLambdaRS232Manager(const char* pszName_);
- virtual ~CLambdaRS232Manager();
- protected:
- CLambdaRS232* m_pRS232[15];
- virtual void DoTransmission();
- virtual void DoReception() {}
- };
-
- CLambdaRS232Manager::CLambdaRS232Manager(const char* pszName_) : CRS232(pszName_)
- {
- TRACE("CLambdaRS232Manager constructor...\n");
- TRACE_INDENT;
- for (int _i = 0; _i < _countof(m_pRS232); _i++)
- {
- m_pRS232[_i] = NULL;
- }
- }
-
- CLambdaRS232Manager::~CLambdaRS232Manager()
- {
- TRACE("CLambdaRS232Manager destructor...\n");
- TRACE_INDENT;
- for (int _i = 0; _i < _countof(m_pRS232); _i++)
- {
- if (m_pRS232[_i])
- {
- delete m_pRS232[_i];
- m_pRS232[_i] = NULL;
- }
- }
- }
-
- void CLambdaRS232Manager::DoTransmission()
- {
- C_ASSERT(_countof(m_pRS232) == _countof(m_rs232InfoSlots));
- C_ASSERT(sizeof(__super::RS232Info) >= sizeof(CLambdaRS232::Info));
- C_ASSERT(FIELD_OFFSET(__super::RS232Info, pTxFifo) == FIELD_OFFSET(CLambdaRS232::Info, pTxFifo));
- C_ASSERT(RTL_FIELD_SIZE(__super::RS232Info, pTxFifo) == RTL_FIELD_SIZE(CLambdaRS232::Info, pTxFifo));
- C_ASSERT(FIELD_OFFSET(__super::RS232Info, pRxFifo) == FIELD_OFFSET(CLambdaRS232::Info, pRxFifo));
- C_ASSERT(RTL_FIELD_SIZE(__super::RS232Info, pRxFifo) == RTL_FIELD_SIZE(CLambdaRS232::Info, pRxFifo));
- C_ASSERT(FIELD_OFFSET(__super::RS232Info, nID) == FIELD_OFFSET(CLambdaRS232::Info, nID));
- C_ASSERT(RTL_FIELD_SIZE(__super::RS232Info, nID) == RTL_FIELD_SIZE(CLambdaRS232::Info, nID));
- C_ASSERT(FIELD_OFFSET(__super::RS232Info, nBRCode) == FIELD_OFFSET(CLambdaRS232::Info, nBRCode));
- C_ASSERT(RTL_FIELD_SIZE(__super::RS232Info, nBRCode) == RTL_FIELD_SIZE(CLambdaRS232::Info, nBRCode));
- for (int _i = 0; _i < _countof(m_rs232InfoSlots); _i++)
- {
- CLambdaRS232::Info* _pInfo = (CLambdaRS232::Info*)(m_rs232InfoSlots + _i);
- if (_pInfo->pTxFifo == NULL && _pInfo->pRxFifo == NULL)
- continue;
- if (m_pRS232[_i] != NULL)
- continue;
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- if (_pDevice == NULL || _pDevice->m_pAdapter == NULL)
- continue;
- CLambdaBus* _pBus = _pDevice->m_pAdapter->GetBus(HIBYTE(_pInfo->nID) >> 4);
- if (_pBus == NULL || _pBus->GetEnable() == false)
- continue;
- CLambdaController* _pCtrl = _pBus->GetController(HIBYTE(_pInfo->nID) & 0x0F);
- if (_pCtrl == NULL || _pCtrl->GetEnable() == false)
- continue;
- m_pRS232[_i] = new CLambdaRS232(_pCtrl, _pInfo);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CCounter85A
- //
- class CCounter85A : public CFnap, public CCounter
- {
- public:
- CCounter85A(const char* pszName_);
- virtual ~CCounter85A();
-
- virtual void Initialize(UINT nAddr_);
- virtual void Update();
- virtual int GetCount();
-
- private:
- UINT m_nAddr;
- int* m_pnCountInSW;
- NTSTATUS FnapConfigureCounter(FNAP_CONFIGURE_COUNTER* pFnap_);
- };
-
- CCounter85A::CCounter85A(const char* pszName_) : CFnap(pszName_)
- {
- m_nAddr = Make32Addr(250);
- m_pnCountInSW = (int*)GetSwitchArea()->Allocate(sizeof(int));
- if (!m_pnCountInSW)
- FatalError(FILE_ID, __LINE__);
- GetFnapManager()->Register(this, "FnapConfigureCounter", (PFNAP_FUNC)&CCounter85A::FnapConfigureCounter, true);
- }
-
- CCounter85A::~CCounter85A()
- {
- GetSwitchArea()->Free(m_pnCountInSW);
- }
-
- // 手轮计数是InMap中的上行数据,占4个字节 ---- 杨开锦 2014-05-22
- int CCounter85A::GetCount()
- {
- CHECK_PARAM(GetBlockFrom32Addr(m_nAddr) == 0x01);
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
-
- union
- {
- BYTE buffer[4];
- UINT32 val;
- }_val;
-
- _val.buffer[0] = _pDevice->GetInPortMap(GetOffsetFrom32Addr(m_nAddr));
- _val.buffer[1] = _pDevice->GetInPortMap(GetOffsetFrom32Addr(m_nAddr) + 1 );
- _val.buffer[2] = _pDevice->GetInPortMap(GetOffsetFrom32Addr(m_nAddr) + 2 );
- _val.buffer[3] = _pDevice->GetInPortMap(GetOffsetFrom32Addr(m_nAddr) + 3 );
-
- return _val.val;
- }
-
- void CCounter85A::Initialize(UINT nAddr_)
- {
- m_nAddr = nAddr_;
- }
-
- void CCounter85A::Update()
- {
- // No need to update
- }
-
- NTSTATUS CCounter85A::FnapConfigureCounter(FNAP_CONFIGURE_COUNTER* pFnap_)
- {
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_HEADER));
- CHECK_PARAM(pFnap_->nOutSize == sizeof(FNAP_CONFIGURE_COUNTER));
- pFnap_->pnCountInSW = (::GetSwitchArea()->ConvertToR3Address(m_pnCountInSW));
- return STATUS_SUCCESS;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CFpgaUpdate 更新板卡的Fpga程序 ---- 杨开锦 2014-05-30
- //
- class CFpgaUpdateFifo : public CRingBuffer<BYTE, 8 * 1024>
- {
- public:
- bool HasPacket()
- {
- if (GetCount() < 3)
- return false;
- BYTE _nLen = m_data[(m_nReadIndex + 1) % c_nN];
- return (GetCount() >= _nLen);
- }
- };
- #pragma pack(push,8)
- struct FNAP_FPGA_UPDATE : FNAP_HEADER
- {
- DWORD nType; // [传入信息],1->控制卡,2->端子板
- DWORD nNA; // [传入信息],保留
- void* __ptr32 pFifo; // [返回信息],数据缓冲区
- BYTE* __ptr32 pnStatusBits; // [返回信息],更新状态位
- };
- #pragma pack(pop)
- class CFpgaUpdate : public CFnap
- {
- public:
- CFpgaUpdate(const char* pszName_);
- virtual ~CFpgaUpdate();
-
- protected:
- PUCHAR m_pDataPort;
- PUCHAR m_pStatusPort;
- PUCHAR m_pCommandPort;
- CPortFifo m_UpFifo;
- CPortFifo m_DownFifo;
- BYTE* m_pnStatusBits;
- CFpgaUpdateFifo* m_pFifo;
- KEVENT m_eventURTerminator;
- static void UpdateRoutine1(PVOID pData_);
- static void UpdateRoutine2(PVOID pData_);
- static int UR2_ReadUp(CFpgaUpdate* pFU_);
- static int UR2_WriteDown(CFpgaUpdate* pFU_);
-
- WORD m_nStage;
- NTSTATUS FnapBeginUpdate(FNAP_FPGA_UPDATE* pFnap_);
- NTSTATUS FnapEndUpdate(FNAP_HEADER* pFnap_);
- };
-
- CFpgaUpdate::CFpgaUpdate(const char* pszName_)
- : CFnap(pszName_)
- {
- TRACE("Driver::CFpgaUpdate::Constructor\n");
-
- m_nStage = 0;
- KeInitializeEvent(&m_eventURTerminator, NotificationEvent, FALSE);
-
- m_pnStatusBits = (BYTE*)GetSwitchArea()->Allocate(sizeof(BYTE));
- if (!m_pnStatusBits)
- FatalError(FILE_ID, __LINE__);
- *m_pnStatusBits = 0;
- m_pFifo = (CFpgaUpdateFifo*)GetSwitchArea()->Allocate(sizeof(CFpgaUpdateFifo));
- if (!m_pFifo)
- FatalError(FILE_ID, __LINE__);
- m_pFifo->CFpgaUpdateFifo::CFpgaUpdateFifo();
-
- CNcBoardPcimc85A* _pDevice = (CNcBoardPcimc85A*)GetDevice();
- CLambdaAdapter* _pAdapter = _pDevice->m_pAdapter;
- ADAPTER_BASE_INFO_V2* _pABI = _pAdapter->GetAdapterBaseInfo();
- CHECK_PARAM(_pDevice);
- CHECK_PARAM(_pAdapter);
- CHECK_PARAM(_pABI);
-
- m_UpFifo.Bind(
- _pAdapter->GetCHType(),
- _pAdapter->GetPortBase() + _pABI->Ctrls[0].nUpFifoPort,
- _pABI->Ctrls[0].nUpFifoLength);
-
- m_DownFifo.Bind(
- _pAdapter->GetCHType(),
- _pAdapter->GetPortBase() + _pABI->Ctrls[0].nDownFifoPort,
- _pABI->Ctrls[0].nDownFifoLength);
-
- m_pDataPort = _pAdapter->GetPortBase() + _pABI->nAdapterFifoPort;
-
- m_pStatusPort = m_pDataPort + 1;
- m_pCommandPort = m_pDataPort + 2;
-
- GetFnapManager()->Register(this, "FnapBeginUpdate", (PFNAP_FUNC)&CFpgaUpdate::FnapBeginUpdate, true);
- GetFnapManager()->Register(this, "FnapEndUpdate", (PFNAP_FUNC)&CFpgaUpdate::FnapEndUpdate, true);
- }
-
- CFpgaUpdate::~CFpgaUpdate()
- {
- if (KeSetEvent(&m_eventURTerminator, 1, FALSE) == 0)
- {
- SleepAtPassiveLevel(40);
- }
-
- GetSwitchArea()->Free(m_pFifo);
- GetSwitchArea()->Free(m_pnStatusBits);
-
- TRACE("Driver::CFpgaUpdate::Destructor\n");
- }
-
- void CFpgaUpdate::UpdateRoutine1(PVOID pData_)
- {
- CHECK_PARAM(pData_ != NULL);
- TRACE("CFpgaUpdate::UpdateRoutine1 begin...\n");
-
- CFpgaUpdate* _pFU = (CFpgaUpdate*)pData_;
-
- // 这是更新的主函数,在独立线程中运行,负责下传数据并更新状态 ---- 杨开锦 2014-06-07
- // BeginUpdate时创建此线程,EndUpdate时停掉
- // 循环从缓冲区读,写入到硬件
- // 一个周期最多工作5ms,周期间隔1ms
- // 线程切换是操作系统决定的,很可能达不到1ms切换,此处的意思是尽快回来
- // 硬件写Flash的速度约为5us/Byte
- // 但硬件中做的是先写入,再读出校验,可能会再慢一些
- // 由于线程切换,有效工作时间不长,实际速度是此值的若干分之一,假设是1/4
- // 我们目前的FPGA程序一般为300-500K
- // 但写入的是帧数据,有效载荷会少一些
- // 以每帧16Byte载荷为例,载荷比为 16/24
- // 可推知,更新过程大概要15秒(算上了3s擦除时间),这应该是可以的
- int _nWriteCount = 0;
- __int64 _nWaitTime = -10000; // 1ms
- while (STATUS_TIMEOUT == KeWaitForSingleObject(&_pFU->m_eventURTerminator,
- Executive, KernelMode, FALSE, (LARGE_INTEGER*)&_nWaitTime))
- {
- int _nWC = 0;
- LARGE_INTEGER _freq;
- __int64 _tickBegin = KeQueryPerformanceCounter(&_freq).QuadPart;
- __int64 _tickCurrent = _tickBegin;
- __int64 _tickBusy = _tickBegin;
- while (_tickCurrent - _tickBegin < _freq.QuadPart * 5 / 1000)
- {
- _tickCurrent = KeQueryPerformanceCounter(NULL).QuadPart;
- UCHAR _nStatus = READ_PORT_UCHAR(_pFU->m_pStatusPort);
- BYTE _nSBits = *_pFU->m_pnStatusBits;
- if ((_nStatus & 0x01) == 0) _nSBits |= 0x80; // 向R3提供的状态字只有三个位
- if ((_nStatus & 0x02) == 0) _nSBits |= 0x02; // Bit0:擦除完成、Bit1:更新完成、Bit7更新错误
- if ((_nStatus & 0x04) == 0) _nSBits |= 0x01; // 对于Crc8错误也算到更新错误中
- if ((_nStatus & 0x08) == 0) _nSBits |= 0x80; // 且换算为正逻辑,即1有效
- *_pFU->m_pnStatusBits = _nSBits;
- if (_nSBits & 0x82)
- {
- break;
- }
-
- if (_pFU->m_pFifo->IsEmpty())
- break;
-
- // Bit4: FIFO空,高有效
- // Bit5: FIFO满,高有效
- if ((_nStatus & 0x20) != 0)
- {
- if (_tickCurrent - _tickBusy < _freq.QuadPart * 1 / 1000)
- continue;
- else
- break;
- }
- _tickBusy = _tickCurrent;
-
- BYTE _nData;
- _pFU->m_pFifo->Read(&_nData);
- WRITE_PORT_UCHAR(_pFU->m_pDataPort, _nData);
- _nWC++;
- }
-
- _nWriteCount += _nWC;
- if (_nWC > 0) TRACE("CFpgaUpdate::UpdateRoutine1 => _nWC=%d\n", _nWC);
- }
-
- TRACE("CFpgaUpdate::UpdateRoutine1 => _nWriteCount=%d\n", _nWriteCount);
- TRACE("CFpgaUpdate::UpdateRoutine1 end.\n");
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
-
- void CFpgaUpdate::UpdateRoutine2(PVOID pData_)
- {
- CHECK_PARAM(pData_ != NULL);
- TRACE("CFpgaUpdate::UpdateRoutine2 begin...\n");
- NTSTATUS _nRet = STATUS_SUCCESS;
-
- CFpgaUpdate* _pFU = (CFpgaUpdate*)pData_;
-
- int _nReadPacket = 0;
- int _nWritePacket = 0;
- __int64 _nWaitTime = 0;
- while (STATUS_TIMEOUT == KeWaitForSingleObject(&_pFU->m_eventURTerminator,
- Executive, KernelMode, FALSE, (LARGE_INTEGER*)&_nWaitTime))
- {
- LARGE_INTEGER _freq;
- __int64 _tickBegin = KeQueryPerformanceCounter(&_freq).QuadPart;
- __int64 _tickCurrent = _tickBegin;
- int _nIdleCount = 0;
- while (_tickCurrent - _tickBegin < _freq.QuadPart * 5 / 1000 && _nIdleCount < 5)
- {
- _tickCurrent = KeQueryPerformanceCounter(NULL).QuadPart;
-
- // 先读状态 ---- 杨开锦 2014-06-07
- int _nR = UR2_ReadUp(_pFU);
- if (_nR < 0)
- {
- _nRet = STATUS_UNSUCCESSFUL;
- break;
- }
- _nReadPacket += _nR;
-
- // 再写数据 ---- 杨开锦 2014-06-07
- int _nW = 0;
- if (_nWritePacket - _nReadPacket < 11) // 限流
- _nW = UR2_WriteDown(_pFU);
- _nWritePacket += _nW;
- _nIdleCount = (_nW > 0) ? 0 : _nIdleCount + 1;
- }
-
- if (_nRet != STATUS_SUCCESS)
- break;
- }
-
- TRACE("CFpgaUpdate::UpdateRoutine2 => _nReadPacket=%d\n", _nReadPacket);
- TRACE("CFpgaUpdate::UpdateRoutine2 => _nWritePacket=%d\n", _nWritePacket);
- TRACE("CFpgaUpdate::UpdateRoutine2 end. _nRet = 0x%02X\n", _nRet);
- PsTerminateSystemThread(_nRet);
- }
-
- int CFpgaUpdate::UR2_ReadUp(CFpgaUpdate* pFU_)
- {
- CHECK_PARAM(pFU_);
- int _nRet = 0;
-
- #pragma pack(push, 1)
- struct _PACKAGE
- {
- BYTE nHead;
- BYTE nLength;
- WORD nPnn;
- BYTE nStatus;
- BYTE nCRC8;
- };
- #pragma pack(pop)
- while (BYTE* _p = pFU_->m_UpFifo.Read())
- {
- BYTE _nLen = _p[1];
- if (_nLen < 2)
- {
- TRACE("CFpgaUpdate::UR2_ReadUp => _nLen < 2\n");
- _nRet = -1;
- break;
- }
-
- while (_p[0] == UCMD_TUNNEL_NONRT || _p[0] == UCMD_TUNNEL_DISRT || _p[0] == UCMD_TUNNEL_UNDRT)
- {
- if (_p[_nLen - 1] != CalculateCRC8(_p, _nLen - 1))
- {
- TRACE("CFpgaUpdate::UR2_ReadUp => TUNNEL CRC Error\n");
- TRACE_INDENT;
- TRACE_HEX(_p, _nLen);
- _nRet = -1;
- break;
- }
- _p += 2;
- _nLen = _p[1];
- }
- if (_nRet < 0)
- break;
-
- if (_p[_nLen - 1] != CalculateCRC8(_p, _nLen - 1))
- {
- TRACE("CFpgaUpdate::UR2_ReadUp => CRC Error\n");
- TRACE_INDENT;
- TRACE_HEX(_p, _nLen);
- _nRet = -1;
- break;
- }
-
- _PACKAGE* _pSYS = (_PACKAGE*)_p;
- if (_pSYS->nHead != UCMD_SYSINFO)
- continue;
- if (_pSYS->nPnn != 0xFF00 && _pSYS->nPnn != 0xFF01 && _pSYS->nPnn != 0xFF02)
- continue;
- if (_pSYS->nLength != sizeof(_PACKAGE))
- {
- TRACE("CFpgaUpdate::UR2_ReadUp => _pSYS->nLength Error\n");
- TRACE_INDENT;
- TRACE_HEX(_pSYS, _pSYS->nLength);
- _nRet = -1;
- break;
- }
-
- _nRet++;
- pFU_->m_nStage = _pSYS->nPnn;
- *pFU_->m_pnStatusBits = _pSYS->nStatus;
- }
-
- return _nRet;
- }
-
- int CFpgaUpdate::UR2_WriteDown(CFpgaUpdate* pFU_)
- {
- CHECK_PARAM(pFU_);
-
- int _nRet = 0;
- while (_nRet < 4 && pFU_->m_pFifo->HasPacket() && pFU_->m_DownFifo.GetFree() >= 256)
- {
- BYTE _p[256];
- pFU_->m_pFifo->Read(_p + 0);
- pFU_->m_pFifo->Read(_p + 1);
- for (int _i = 2; _i < _p[1]; _i++)
- {
- pFU_->m_pFifo->Read(_p + _i);
- }
-
- _nRet++;
- pFU_->m_DownFifo.Write(_p);
- }
-
- return _nRet;
- }
-
- NTSTATUS CFpgaUpdate::FnapBeginUpdate(FNAP_FPGA_UPDATE* pFnap_)
- {
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_FPGA_UPDATE));
- CHECK_PARAM(pFnap_->nOutSize == sizeof(FNAP_FPGA_UPDATE));
- CHECK_PARAM(pFnap_->nType == 1 || pFnap_->nType == 2);
- CHECK_PARAM(pFnap_->nNA == 0);
- CHECK_PARAM(pFnap_->pFifo == NULL);
- CHECK_PARAM(pFnap_->pnStatusBits == NULL);
- TRACE("CFpgaUpdate::FnapBeginUpdate begin...\n");
- TRACE_INDENT;
-
- if (pFnap_->nType == 1)
- {
- // 初始化: ---- 杨开锦 2014-05-30
- // 1.切换到非更新状态
- // 2.清除缓冲区
- // 3.切换到更新状态
- // 控制字
- // Bit0: 更新使能,低有效
- // Bit1: 清除FIFO,高有效
- WRITE_PORT_UCHAR(m_pCommandPort, 0x01);
- SleepAtPassiveLevel(10);
- WRITE_PORT_UCHAR(m_pCommandPort, 0x03);
- SleepAtPassiveLevel(10);
- WRITE_PORT_UCHAR(m_pCommandPort, 0x00);
- }
-
- // 开一个工作线程来进行数据下行传输 ---- 杨开锦 2014-06-07
- // 先结束上一次的更新Routine(应用层可能没调FnapEndUpdate)
- // 再创建一个新的线程
- // 系统线程不能被杀掉只能自己退出
- // 通过设置事件的方式叫线程函数退出
- KeSetEvent(&m_eventURTerminator, 1, FALSE);
- SleepAtPassiveLevel(40);
- m_pFifo->Reset();
- *m_pnStatusBits = 0;
- m_nStage = 0;
- KeClearEvent(&m_eventURTerminator);
- HANDLE _hThread;
- NTSTATUS _nStatus = PsCreateSystemThread(
- &_hThread,
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- NULL,
- pFnap_->nType == 1 ? CFpgaUpdate::UpdateRoutine1 : CFpgaUpdate::UpdateRoutine2,
- this);
- if (!NT_SUCCESS(_nStatus))
- {
- TRACE("PsCreateSystemThread failed\n");
- KeSetEvent(&m_eventURTerminator, 1, FALSE);
- return _nStatus;
- }
- ZwClose(_hThread);
-
- // 将更新的状态通过状态位告知给上层应用程序 ---- 杨开锦 2014-09-05
- // 这里的状态码即为硬件给上来状态码
- // 所有位全0表示正确,有非0表示异常
- pFnap_->pFifo = (::GetSwitchArea()->ConvertToR3Address(m_pFifo));
- pFnap_->pnStatusBits = (BYTE*)::GetSwitchArea()->ConvertToR3Address(m_pnStatusBits);
- return STATUS_SUCCESS;
- }
-
- NTSTATUS CFpgaUpdate::FnapEndUpdate(FNAP_HEADER* pFnap_)
- {
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_HEADER));
- CHECK_PARAM(pFnap_->nOutSize == 0);
- TRACE("CFpgaUpdate::FnapEndUpdate begin...\n");
- TRACE_INDENT;
-
- bool _bSucceed = (*m_pnStatusBits == 0x00 && m_nStage == 0xFF02);
-
- // 结束线程函数 ---- 杨开锦 2014-06-07
- KeSetEvent(&m_eventURTerminator, 1, FALSE);
- SleepAtPassiveLevel(40);
- m_pFifo->Reset();
- *m_pnStatusBits = 0;
- m_nStage = 0;
-
- // 使硬件退出在线更新的状态 ---- 杨开锦 2014-05-31
- WRITE_PORT_UCHAR(m_pCommandPort, 0x01);
-
- // 擦除正确且更新完成,则是成功,否则失败 ---- 杨开锦 2014-05-31
- return _bSucceed ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CSynPort,实现Lambda主控结点以外结点的同步端口控制 ---- 杨开锦 2015-03-09
- //
- #pragma pack(push,8)
- struct FNAP_SYN_PORT : FNAP_HEADER
- {
- bool* __ptr32 pbEnable; // [返回信息],使能
- int nCount; // [传入信息],缓冲数
- DWORD nAddr; // [传入信息],端口地址
- DWORD nMask; // [传入信息],端口位掩码
- };
- #pragma pack(pop)
- class CSynPort : public CFnap, public ISynPort, public CLambdaPacketFifo
- {
- public:
- CSynPort(const char* pszName_, CLambdaAdapter* pAdapter_);
- virtual ~CSynPort();
-
- protected:
- bool* m_pbEnable;
- BYTE m_nCount;
- DWORD m_nAddr;
- DWORD m_nMask;
- DWORD m_nCache;
- int m_nDifference; // in 1/1000000;正=>要补;负=>要扔
- CLambdaAdapter* m_pAdapter;
- NTSTATUS FnapConfigureSynPort(FNAP_SYN_PORT* pFnap_);
-
- BYTE m_nLastBuffer;
- CRingBuffer<BYTE, 256> m_SoftBuffer;
- virtual void Synchronize();
-
- static const BYTE c_nPnn = 0x07;
- BYTE m_nHardBufferCount;
- virtual bool Update(int nUs_);
- virtual bool Dispatch(PACKAGE* pPackage_);
- };
-
- CSynPort::CSynPort(const char* pszName_, CLambdaAdapter* pAdapter_) : CFnap(pszName_)
- {
- TRACE("Driver::CSynPort::Constructor\n");
- m_pbEnable = (bool*)GetSwitchArea()->Allocate(sizeof(bool));
- if (!m_pbEnable)
- FatalError(FILE_ID, __LINE__);
- *m_pbEnable = false;
- m_nCount = 0;
- m_nAddr = 0;
- m_nMask = 0;
- m_nCache = 0;
- m_nDifference = 0;
- m_pAdapter = pAdapter_;
- m_nLastBuffer = 0;
- m_SoftBuffer.Reset();
- m_nHardBufferCount = 0;
- GetFnapManager()->Register(this, "FnapConfigureSynPort", (PFNAP_FUNC)&CSynPort::FnapConfigureSynPort, true);
- }
-
- CSynPort::~CSynPort()
- {
- CLambdaController* _pCtrl = GetController();
- if (_pCtrl)
- {
- _pCtrl->Remove(this);
- SetController(NULL);
- }
-
- GetSwitchArea()->Free(m_pbEnable);
- TRACE("Driver::CSynPort::Destructor\n");
- }
-
- NTSTATUS CSynPort::FnapConfigureSynPort(FNAP_SYN_PORT* pFnap_)
- {
- CHECK_PARAM(pFnap_);
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_SYN_PORT));
- CHECK_PARAM(pFnap_->nOutSize == sizeof(FNAP_SYN_PORT));
- TRACE("CSynPort::FnapConfigureSynPort begin...\n");
- TRACE_INDENT;
- if (pFnap_->pbEnable || pFnap_->nCount <= 0 || pFnap_->nCount >= 128)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- WORD _offset = LOWORD(pFnap_->nAddr);
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- CHECK_PARAM(_nBus < 4 && _nBus >= 0);
- CHECK_PARAM(_nCtrl < 8 && _nCtrl >= 0);
- CHECK_PARAM(_nByte < 256 && _nByte >= 0);
- if (m_pAdapter == NULL
- || m_pAdapter->GetBus(_nBus) == NULL
- || m_pAdapter->GetBus(_nBus)->GetController(_nCtrl) == NULL)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- #ifndef SIMUDRIVER
- if (!GetController())
- m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->Add(this);
- if (GetController()->GetOrder() != _nCtrl || GetController()->GetOwnerBus()->GetBusNo() != _nBus)
- return STATUS_UNSUCCESSFUL;
- #endif
-
- pFnap_->pbEnable = (bool*)::GetSwitchArea()->ConvertToR3Address(m_pbEnable);
- m_nCount = BYTE(pFnap_->nCount);
- m_nAddr = pFnap_->nAddr;
- m_nMask = pFnap_->nMask;
- TRACE("Bus = %d\n", _nBus);
- TRACE("Ctrl = %d\n", _nCtrl);
- TRACE("Byte = %d\n", _nByte);
- TRACE("Count = %d\n", m_nCount);
- return STATUS_SUCCESS;
- }
-
- void CSynPort::Synchronize()
- {
- #if defined (SIMUDRIVER)
- return;
- #else
- CLambdaController* _pCtrl = GetController();
- if (!_pCtrl || !_pCtrl->IsInitialized())
- return;
-
- BYTE _nPortValue = 0;
- if (m_SoftBuffer.IsFull())
- m_SoftBuffer.Read(&_nPortValue);
- _nPortValue = _pCtrl->GetSendPulse()->GetSynOut(m_nAddr & 0xFF);
-
- // 在 CMDDN_SYNPORT::nReserved 中记录了这个开关端口的准确时刻的小数部分
- // 大小是 0-15,单位是 1/16,量纲是毫秒(准确的说是控制周期)
- // 现实现为 0-7则前半个控制周期开/关,8-15则后半个控制周期开/关
- CSynPortManager* _pSynPortManager = GetSynPortManager();
- CHECK_PARAM(_pSynPortManager);
- if (_pSynPortManager->GetSynPortReserved(m_nAddr) <= 7)
- m_SoftBuffer.Write(&_nPortValue);
- else
- m_SoftBuffer.Write(&m_nLastBuffer);
-
- m_SoftBuffer.Write(&_nPortValue);
- m_nLastBuffer = _nPortValue;
- #endif
- }
-
- bool CSynPort::Update(int nUs_)
- {
- #if defined (SIMUDRIVER)
- return false;
- #else
- CLambdaController* _pCtrl = GetController();
- if (!_pCtrl || !_pCtrl->IsInitialized())
- return false;
-
- // 缓存Cache中前三个BYTE分别是参数包中的三个分量:开关、字节序、位掩码 ---- 杨开锦 2015-03-09
- BYTE _nEN = *m_pbEnable ? 0x81 : 0;
- BYTE _nAddr = m_nAddr & 0xFF;
- BYTE _nMask = m_nMask & 0xFF;
- DWORD _nCache = (DWORD(_nEN) << 0) | (DWORD(_nAddr) << 8) | (DWORD(_nMask) << 16);
- if (_nCache != m_nCache)
- {
- BYTE _p[] = { DCMD_APPINFO, 9, c_nPnn, 0x00, _nEN, _nAddr, _nMask, 0x01, 0x00 };
- if (_pCtrl->GetDownFreeSpace() < sizeof(_p) + 3 * 7)
- return false;
- _pCtrl->WritePacket((PACKAGE*)_p, NULL);
-
- // 请求返回30A当前缓冲区组数 ---- DingQiang 2015-05-20
- BYTE _pReadBufferCount[] = { DCMD_APPINFO, 6, 0x03, c_nPnn, 0x01, 0x00};
- _pCtrl->WritePacket((PACKAGE*)_pReadBufferCount, NULL);
- m_nCache = _nCache;
- }
-
- // 发数据,维持硬件中有稳定的组数 ---- 杨开锦 2015-03-09
- // 设置一个低通滤波器,以避免有时补上了过一会又还回去的情况。
- // 公式: Y(n) = A*X(n) + (1-A)*Y(n-1)
- // 其中 X(n) -- 本次采样
- // Y(n-1) -- 上次滤波输出
- // A -- 滤波系数,通常远小于1
- // Y(n) -- 本次滤波输出
- // 此滤波公式用于模拟具有较大惯性的低通滤波器功能
- // 截止频率: fL = A/(2PI*t) (t为采样周期)。
- // 现在此功能的应用场景是Lambda5S+EX30A,在EX30A上添加此端口缓冲区
- // 硬件上EX30A和Lambda的晶振选型是一样的,83.3MHz
- // 且已把EX30A的中断Tick数改成跟Lambda的脉冲周期Tick数一致,16384*5
- // 故不一致的地方应该是晶振的个体差异,从说明书上看到是正负50ppm
- // 计算得 50ppm*2=100ppm=1/10000 => 10000ms差1ms => 10s差1ms
- // 即最快10s会差一个控制周期,考虑滤波截止频率为0.2Hz
- // A = fL * (2PI*t) = 0.2Hz * 2 * 3.14 * 0.001s = 0.001256
- //
- // 修改:硬件上把EX30A的端口控制频率从1KHz改为2KHz ---- 杨开锦 2015-04-17
- // 目的是期望能把端口与脉冲的同步做到更精准
- // 软件上需要把一个1ms的端口数据分为两份控制数据来发入缓冲区
- // 并可以做到1ms端口状态的前0.5ms和后0.5ms不同,相当于其控制周期做到了0.5ms
- if (m_SoftBuffer.GetCount() > 10)
- TRACE("CSynPort::Update => SoftBuffer.Count=%d > 10", m_SoftBuffer.GetCount());
- int _nCount = (int)m_SoftBuffer.GetCount();
- int _nNeed = ((int)m_nHardBufferCount >= m_nCount) ? 0 : (m_nCount - (int)m_nHardBufferCount);
- int _nSend = _nCount;
- const int c_n1 = 1000000;
- const int c_nA = 1256;
- m_nDifference = int(((__int64)c_nA * (_nNeed - _nCount) * c_n1 + (__int64)(c_n1 - c_nA) * m_nDifference) / c_n1);
- if (m_nDifference >= c_n1)
- {
- CHECK_PARAM(_nSend < 255);
- _nSend++;
- m_nDifference -= c_n1;
- TRACE("CSynPort::Update => Count=%d Need=%d Send=%d", _nCount, _nNeed, _nSend);
- }
- if (m_nDifference <= -c_n1)
- {
- CHECK_PARAM(_nSend > 0);
- _nSend--;
- m_nDifference += c_n1;
- TRACE("CSynPort::Update => Count=%d Need=%d Send=%d", _nCount, _nNeed, _nSend);
- }
- BYTE _pPush[] = { DCMD_APPINFO, 6, 0x04, c_nPnn, _pCtrl->GetSendPulse()->GetSynOut(_nAddr), 0x00 };
- for (int _i = 0; _i < _nSend; _i++)
- {
- if (_pCtrl->GetDownFreeSpace() < sizeof(_pPush) + 3 * 7)
- {
- TRACE("CSynPort::Update => _pCtrl->GetDownFreeSpace() < sizeof(_pPush) + 3 * 7");
- break;
- }
- m_nHardBufferCount++;
- m_SoftBuffer.Read(_pPush + 4);
- _pCtrl->WritePacket((PACKAGE*)_pPush, NULL);
- }
- m_SoftBuffer.Reset();
- return true;
- #endif
- }
-
- bool CSynPort::Dispatch(PACKAGE* pPackage_)
- {
- if (!pPackage_
- || pPackage_->nPnnCmd != DCMD_APPINFO
- || pPackage_->nPnnLength != 6
- || pPackage_->nPnnSubcmd != MAKEWORD(0x03, c_nPnn))
- {
- return false;
- }
-
- m_nHardBufferCount = pPackage_->nPnnData[0];
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // FeedbackStream
- //
- #pragma pack(push, 8)
- struct FNAP_FEEDBACK_STREAM : FNAP_HEADER
- {
- BYTE nBusNo; // [传入信息],总线序号
- BYTE nReserved[2]; // [传入信息],保留
- BYTE nNumofAxes; // [返回信息],轴数
- void* __ptr32 pFeedbackFifo; // [返回信息],缓冲区指针
- };
- C_ASSERT(sizeof(FNAP_FEEDBACK_STREAM) == 72);
- template<int N>
- struct FeedbackNode
- {
- DWORD nReserved; // 保留
- DWORD nTimeStamp; // 时间戳
- DWORD nNccmdSN; // 当前发送到的脉冲序号
- DWORD nFeedback[N]; // 编码器反馈计数(原始值)
- };
- class CFeedbackFifo : public CRingBuffer<FeedbackNode<5>, 8 * 1024> {};
- #pragma pack(pop)
-
- class CFeedbackStream : public CFnap, public CLambdaPacketFifo
- {
- public:
- CFeedbackStream(const char* pszName_, CLambdaAdapter* pAdapter_);
- virtual ~CFeedbackStream();
-
- protected:
- BYTE m_nReserved[2];
- CLambdaAdapter* m_pAdapter;
- CFeedbackFifo* m_pFeedbackFifo;
- NTSTATUS FnapConfigureFeedbackStream(FNAP_FEEDBACK_STREAM* pFnap_);
-
- virtual bool Dispatch(PACKAGE* pPackage_);
- };
-
- CFeedbackStream::CFeedbackStream(const char* pszName_, CLambdaAdapter* pAdapter_) : CFnap(pszName_)
- {
- TRACE("Driver::CFeedbackStream::Constructor\n");
- m_nReserved[0] = 0;
- m_nReserved[1] = 0;
- m_pAdapter = pAdapter_;
- m_pFeedbackFifo = (CFeedbackFifo*)GetSwitchArea()->Allocate(sizeof(CFeedbackFifo));
- if (!m_pFeedbackFifo)
- FatalError(FILE_ID, __LINE__);
- m_pFeedbackFifo->CFeedbackFifo::CFeedbackFifo();
- GetFnapManager()->Register(this, "FnapConfigureFeedbackStream", (PFNAP_FUNC)&CFeedbackStream::FnapConfigureFeedbackStream, true);
- }
-
- CFeedbackStream::~CFeedbackStream()
- {
- CLambdaController* _pCtrl = GetController();
- if (_pCtrl)
- {
- _pCtrl->Remove(this);
- SetController(NULL);
- }
-
- GetSwitchArea()->Free(m_pFeedbackFifo);
- TRACE("Driver::CFeedbackStream::Destructor\n");
- }
-
- NTSTATUS CFeedbackStream::FnapConfigureFeedbackStream(FNAP_FEEDBACK_STREAM* pFnap_)
- {
- CHECK_PARAM(pFnap_);
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_FEEDBACK_STREAM));
- CHECK_PARAM(pFnap_->nOutSize == sizeof(FNAP_FEEDBACK_STREAM));
- CHECK_PARAM(pFnap_->nBusNo == 0);
- TRACE("CFeedbackStream::FnapConfigureFeedbackStream begin...\n");
- TRACE_INDENT;
- if (pFnap_->nNumofAxes != 0)
- return STATUS_UNSUCCESSFUL;
- if (pFnap_->pFeedbackFifo != NULL)
- return STATUS_UNSUCCESSFUL;
-
- #ifndef SIMUDRIVER
- if (!GetController())
- m_pAdapter->GetBus(pFnap_->nBusNo)->GetController(0)->Add(this);
- if (GetController()->GetOrder() != 0 || GetController()->GetOwnerBus()->GetBusNo() != pFnap_->nBusNo)
- return STATUS_UNSUCCESSFUL;
- #endif
-
- m_nReserved[0] = pFnap_->nReserved[0];
- m_nReserved[1] = pFnap_->nReserved[1];
- pFnap_->nNumofAxes = 5;
- pFnap_->pFeedbackFifo = GetSwitchArea()->ConvertToR3Address(m_pFeedbackFifo);
- return STATUS_SUCCESS;
- }
-
- bool CFeedbackStream::Dispatch(PACKAGE* pPackage_)
- {
- CLambdaController* _pCtrl = GetController();
- if (!_pCtrl || !_pCtrl->IsInitialized() || _pCtrl->GetControllerBaseInfo()->nNumofAxis != 5)
- return false;
-
- if (!pPackage_ || pPackage_->nCmd != UCMD_FEEDBACK)
- return false;
-
- #pragma pack(push, 1)
- struct Feedback
- {
- BYTE nCmd;
- BYTE nLenght;
- UINT32 nTimestamp;
- UINT32 nNccmdSN;
- UINT32 nFeedback[1];
- //BYTE nCRC;
- };
- #pragma pack(pop)
- int _nSize = sizeof(Feedback) + sizeof(UINT32) * (5 - 1) + 1;
- if(pPackage_->nLength != _nSize)
- {
- GetController()->SetErrorCode('CE');
- return false;
- }
-
- // 随反馈脉冲流提上去OUTMAP中一个指定的Byte ---- 杨开锦 2015-05-13
- // 使用 FNAP_FEEDBACK_STREAM 中的 nReserved 保留字节(2bytes)
- // nReserved[0] = 0x80 => 锁存Outmap一个Byte
- // nReserved[1] = Bus(1bit) | Ctrl(3bits) | Byte(4bits)
- // 锁到的Byte值通过 FeedbackNode 中的 nReserved 传上去
- // FeedbackNode::nReserved 为 DWORD
- // 置其第0个Byte为0x80,表示这是此处锁存的信息
- // 置其第3个Byte为锁到的值
- // 其中第1、2个Byte留空为0不予使用
- DWORD _nReserved = 0;
- if ((m_nReserved[0] & 0xF0) == 0x80)
- {
- #ifndef SIMUDRIVER
- int _nBusNo = (m_nReserved[1] >> 7) & 0x01;
- int _nCtrlOrder = (m_nReserved[1] >> 4) & 0x07;
- int _nByteIndex = (m_nReserved[1] >> 0) & 0x0F;
- CLambdaBus* _pBus = m_pAdapter ? m_pAdapter->GetBus(_nBusNo) : NULL;
- CLambdaController* _pCtrl = _pBus ? _pBus->GetController(_nCtrlOrder) : NULL;
- CLambdaOutput* _pOutput = _pCtrl ? _pCtrl->GetOutput() : NULL;
- if (_pOutput)
- {
- BYTE* _pReserved = (BYTE*)&_nReserved;
- _pReserved[0] = 0x80;
- _pReserved[3] = _pOutput->Get(_nByteIndex);
- }
- #endif
- }
-
- // 添加EX30A电容值的提取,用保留位的第1个Byte的高4Bit表示,0x40表示锁输入端
- // 口中的4个Byte。
- // nReserved[0] = 0x40 => 锁存Inmap四个Byte
- // nReserved[1] = Bus(1bit)|Ctrl(3bits)|Byte(4bits) ---- 杨开锦 2015-10-29
- if (m_nReserved[0] == 0x40)
- {
- #ifndef SIMUDRIVER
- int _nBusNo = (m_nReserved[1] >> 7) & 0x01;
- int _nCtrlOrder = (m_nReserved[1] >> 4) & 0x07;
- int _nByteIndex = (m_nReserved[1] >> 0) & 0x0F;
- CLambdaBus* _pBus = m_pAdapter ? m_pAdapter->GetBus(_nBusNo) : NULL;
- CLambdaController* _pCtrl = _pBus ? _pBus->GetController(_nCtrlOrder) : NULL;
- CLambdaInput* _pInput = _pCtrl ? _pCtrl->GetInput() : NULL;
- if (_pInput)
- {
- BYTE* _pReserved = (BYTE*)&_nReserved;
- _pReserved[0] = _pInput->Get(_nByteIndex + 0);
- _pReserved[1] = _pInput->Get(_nByteIndex + 1);
- _pReserved[2] = _pInput->Get(_nByteIndex + 2);
- _pReserved[3] = _pInput->Get(_nByteIndex + 3);
- }
- #endif
- }
-
- // 添加EX30A调试位的提取,用保留位的第1个Byte的低4Bit来表示,0x04相当于就固
- // 定了。0x04的Bit是 0100,表示Bus0、Ctrl1、Byte00起的两个Byte。
- // 让它可以一下锁两个Byte是为扩展方便,可能有的数据是2Byte的,就本次来说
- // 确实只用其Byte1而不用Byte0。 ---- 杨开锦 2015-10-29
- if ((m_nReserved[0] & 0x0F) == 0x04)
- {
- #ifndef SIMUDRIVER
- CLambdaBus* _pBus = m_pAdapter ? m_pAdapter->GetBus(0) : NULL;
- CLambdaController* _pCtrl = _pBus ? _pBus->GetController(1) : NULL;
- CLambdaInput* _pInput = _pCtrl ? _pCtrl->GetInput() : NULL;
- if (_pInput)
- {
- BYTE* _pReserved = (BYTE*)&_nReserved;
- _pReserved[0] |= 0x04;
- _pReserved[1] = _pInput->Get(0);
- _pReserved[2] = _pInput->Get(1);
- }
- #endif
- }
-
- if (!m_pFeedbackFifo->IsFull())
- {
- FeedbackNode<5> _node;
- memset(&_node, 0, sizeof(FeedbackNode<5>));
- Feedback* _pFeedback = (Feedback*)pPackage_;
- _node.nReserved = _nReserved;
- _node.nTimeStamp = _pFeedback->nTimestamp;
- _node.nNccmdSN = _pFeedback->nNccmdSN;
- memcpy(_node.nFeedback, _pFeedback->nFeedback, sizeof(UINT32) * 5);
- m_pFeedbackFifo->Write(&_node);
- }
-
- return true;
- }
-
- #include "NcBoardPcimc85A_PnnPacketFifo.inl"
-
- ////////////////////////////////////////////////////////////////////////////////
- // CNcBoardPcimc85A
- //
- CNcBoardPcimc85A::CNcBoardPcimc85A(PDEVICE_OBJECT pFdo_, PDEVICE_OBJECT pPdo_, const char* pszName_)
- : CDevice(pFdo_, pPdo_, pszName_)
- {
- TRACE0("CNcBoardPcimc85A::CNcBoardPcimc85A begin ...\n");
- TRACE_INDENT;
-
- m_pAdapter = CLambdaAdapterFactory::Create();
-
- m_bNccmdToSendValid = false;
- memset(m_nNccmdToSend, 0, sizeof(m_nNccmdToSend));
- memset(m_bNccmdToSend, 0, sizeof(m_bNccmdToSend));
- m_bRS232ToSendValid = false;
- memset(m_nRS232ToSend, 0, sizeof(m_nRS232ToSend));
- m_bEnableNcboardBuffer = true;
-
- for (int _i = 0; _i < _countof(m_nSynPortReserved); _i++)
- {
- m_nSynPortReserved[_i][0] = 0;
- m_nSynPortReserved[_i][1] = 0;
- }
-
- // 替换掉m_pSpindlePort ---- 杨开锦 2014-02-11
- if (m_pSpindlePort)
- {
- char _szName[c_nFNAP_OBJNAME_LENGTH] = {0};
- strcpy(_szName, m_pSpindlePort->GetName());
- delete m_pSpindlePort;
- m_pSpindlePort = new CLambdaAnalogOutPort(_szName);
- }
-
- m_pAppSysDown = NULL;
- m_pAppSysUp = NULL;
-
- GetFnapManager()->Register(this, "FnapWritePackage",(PFNAP_FUNC)&CNcBoardPcimc85A::FnapWritePackage,true);
- GetFnapManager()->Register(this, "FnapConfigAppSysFifo",(PFNAP_FUNC)&CNcBoardPcimc85A::FnapConfigAppSysFifo, false);
- }
-
- CNcBoardPcimc85A::~CNcBoardPcimc85A()
- {
- TRACE0("CNcBoardPcimc85A::~CNcBoardPcimc85A begin ...\n");
- TRACE_INDENT;
-
- if(m_pAppSysDown != NULL)
- {
- GetSwitchArea()->Free(m_pAppSysDown);
- m_pAppSysDown = NULL;
- }
-
- if(m_pAppSysUp != NULL)
- {
- GetSwitchArea()->Free(m_pAppSysUp);
- m_pAppSysUp = NULL;
- }
- }
-
- NTSTATUS CNcBoardPcimc85A::SetIoBaseAddress(PVOID pIoBaseAddress_, int nLength_, int nIndex_/* = 0*/)
- {
- TRACE0("CNcBoardPcimc85A::SetIoBaseAddress begin ...\n");
- TRACE_INDENT;
-
- // PM85A只会有一块地址,6A、75A也都是
- // NC65A和PM95A是两块地址
- // 我们只使用第一块
- if (nIndex_ > 0)
- {
- return STATUS_SUCCESS;
- }
-
- m_pAdapter->SetPortBase((PUCHAR)pIoBaseAddress_);
- return __super::SetIoBaseAddress(pIoBaseAddress_, nLength_, nIndex_);
- }
-
- CFnap* CNcBoardPcimc85A::AllocResource(FNAP_RESOURCE_ALLOC* _pResourceAlloc)
- {
- TRACE0("CNcBoardPcimc85A::AllocResource begin ...\n");
- TRACE_INDENT;
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_ANALOG_OUT_PORT)
- {
- return new CLambdaAnalogOutPort(_pResourceAlloc->szComponentName);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_ANALOG_PORT)
- {
- return new CLambdaAnalogPort(_pResourceAlloc->szComponentName);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_RS232)
- {
- return new CLambdaRS232Manager(_pResourceAlloc->szComponentName);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_FPGA_UPDATE)
- {
- return new CFpgaUpdate(_pResourceAlloc->szComponentName);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_SYN_PORT)
- {
- return new CSynPort(_pResourceAlloc->szComponentName, m_pAdapter);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_FEEDBACK_STREAM)
- {
- return new CFeedbackStream(_pResourceAlloc->szComponentName, m_pAdapter);
- }
- if(_pResourceAlloc->m_nResource == dir_resource_type_t::RES_PNN_PACKET_FIFO)
- {
- return new CPnnPacketFifo(_pResourceAlloc->szComponentName, m_pAdapter);
- }
- return __super::AllocResource(_pResourceAlloc);
- }
-
- void CNcBoardPcimc85A::FreeResource(CFnap* pFnap, dir_resource_type_t _dirResourceType)
- {
- TRACE0("CNcBoardPcimc85A::FreeResource begin ...\n");
- TRACE_INDENT;
- if(_dirResourceType == dir_resource_type_t::RES_ANALOG_OUT_PORT)
- {
- delete (CLambdaAnalogOutPort*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_ANALOG_PORT)
- {
- delete (CLambdaAnalogPort*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_RS232)
- {
- delete (CLambdaRS232Manager*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_FPGA_UPDATE)
- {
- delete (CFpgaUpdate*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_SYN_PORT)
- {
- delete (CSynPort*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_FEEDBACK_STREAM)
- {
- delete (CFeedbackStream*)pFnap;
- return;
- }
- if(_dirResourceType == dir_resource_type_t::RES_PNN_PACKET_FIFO)
- {
- delete (CPnnPacketFifo*)pFnap;
- return;
- }
- __super::FreeResource(pFnap, _dirResourceType);
- }
-
- void CNcBoardPcimc85A::DeviceError(IN ULONG_PTR nParam1_, IN ULONG_PTR nParam2_, IN ULONG_PTR nParam3_, IN ULONG_PTR nParam4_)
- {
- TRACE("CNcBoardPcimc85A::DeviceError => {0x%X, 0x%X, 0x%X, 0x%X}\n", nParam1_, nParam2_, nParam3_, nParam4_);
-
- // 把驱动置为紧停,提示类型为硬件错误,提示的额外信息为文件行号 ---- 杨开锦 2014-08-12
- CResourceSolt* _pRS = GetDevice()->GetResourceSolt(dir_resource_type_t::RES_CHANNEL);
- if (_pRS)
- {
- for (int _i = 0; _i < _pRS->GetCount(); _i++)
- {
- TRACE("CNcBoardPcimc85A::DeviceError => _i = %d\n", _i);
- CChannel* _pChannel = (CChannel*)_pRS->GetIndex(_i);
- _pChannel->SetState(true, drv_state_t::ESTOP_STATE, ncprompt_t::NCPROMPT_ESTOP_DEVICEERROR, nParam2_);
- }
- }
- }
-
- void CNcBoardPcimc85A::Initialize() // 初始化必备的资源描
- {
- TRACE0("CNcBoardPcimc85A::Initialize begin ...\n");
- TRACE_INDENT;
- SetInputPort(new CLambdaInputPort("InputPort"));
- SetOutputPort(new CLambdaOutputPort("OutputPort"));
- m_pCounter = new CCounter85A("Counter0");
-
- __super::Initialize();
-
- if(m_pAppSysDown == NULL)
- {
- m_pAppSysDown = (CCmdInfoBuffer*)GetSwitchArea()->Allocate(sizeof(CCmdInfoBuffer));
- if (!m_pAppSysDown)
- FatalError(FILE_ID, __LINE__);
-
- m_pAppSysDown->CCmdInfoBuffer::CCmdInfoBuffer();
- }
-
- if(m_pAppSysUp == NULL)
- {
- m_pAppSysUp = (CCmdInfoBuffer*)GetSwitchArea()->Allocate(sizeof(CCmdInfoBuffer));
- if (!m_pAppSysUp)
- FatalError(FILE_ID, __LINE__);
-
- m_pAppSysUp->CCmdInfoBuffer::CCmdInfoBuffer();
- }
-
- m_pFuncServiceRoutine = (PKSERVICE_ROUTINE)CCh365::Ncadpt_InterruptHandler;
-
- #if !defined (SIMUDRIVER)
- m_Guid = NCADPT_GUID_85A;
- #endif
-
- SetNccmdDispatcher(new CNccmdDispatcher85A("NccmdDispatcher"));
- }
-
- NTSTATUS CNcBoardPcimc85A::OnStartDevice()
- {
- TRACE0("CNcBoardPcimc85A::OnStartDevice begin ...\n");
- TRACE_INDENT;
-
- // Mase时钟 ---- 杨开锦 2014-03-29
- GetPortManager()->OutBit(Make64Addr(2, 0x02), false);
-
- NTSTATUS _status = __super::OnStartDevice();
- if(!NT_SUCCESS(_status))
- return _status;
-
- if (m_pAdapter->GetCHType() == CH_CH36x)
- m_pAdapter->SetCHType(CH_CH365);
- m_pAdapter->SetOwnerDevice(this);
- m_pAdapter->SetTimeOut(60);
- m_pAdapter->Initialize(false);
- return _status;
- }
-
- NTSTATUS CNcBoardPcimc85A::OnCreateDevice()
- {
- TRACE0("CNcBoardPcimc85A::OnCreateDevice begin ...\n");
- TRACE_INDENT;
-
- NTSTATUS _nStatus = __super::OnCreateDevice();
- if (_nStatus == STATUS_UNSUCCESSFUL)
- {
- TRACE("CNcBoardPcimc85A::OnCreateDevice => STATUS_UNSUCCESSFUL\n");
- return _nStatus;
- }
-
- if(!m_pAdapter->Initialize(true))
- return STATUS_UNSUCCESSFUL;
-
- return _nStatus;
- }
-
- NTSTATUS CNcBoardPcimc85A::ConnectInterrupt()
- {
- TRACE0("CNcBoardPcimc85A::ConnectInterrupt begin ...\n");
- TRACE_INDENT;
-
- return __super::ConnectInterrupt();
- }
-
- NTSTATUS CNcBoardPcimc85A::OnCloseDevice()
- {
- TRACE0("CNcBoardPcimc85A::OnCloseDevice begin ...\n");
- TRACE_INDENT;
-
- m_pAdapter->UnInitialize();
- return __super::OnCloseDevice();
- }
-
- void CNcBoardPcimc85A::DisableBoard()
- {
- TRACE0("CNcBoardPcimc85A::DisableBoard begin ...\n");
- TRACE_INDENT;
- ASSERT_IRQL(DISPATCH_LEVEL);
- WriteSynchPortBit(Make64Addr(1, 0x00), 0x1);
- }
-
- void CNcBoardPcimc85A::EnableBoard()
- {
- TRACE0("CNcBoardPcimc85A::EnableBoard begin ...\n");
- TRACE_INDENT;
- ASSERT_IRQL(DISPATCH_LEVEL);
- WriteSynchPortBit(Make64Addr(1, 0x00), 0x0);
- }
-
- bool CNcBoardPcimc85A::GetBoardState()
- {
- TRACE0("CNcBoardPcimc85A::GetBoardState begin ...\n");
- TRACE_INDENT;
- ASSERT_IRQL(DISPATCH_LEVEL);
- return !ReadSynchPortBit(Make64Addr(1, 0x00));
- }
-
- UINT CNcBoardPcimc85A::GetMaseFreqence()
- {
- return 4166666;
- }
-
- UINT64 CNcBoardPcimc85A::GetMaseDataClkAddr()
- {
- return Make64Addr(2, 0x02);
- }
-
- UINT64 CNcBoardPcimc85A::GetMaseDataInAddr()
- {
- return Make64Addr(1, 0x02);
- }
-
- UINT64 CNcBoardPcimc85A::GetMaseResetAddr()
- {
- return Make64Addr(0, 0x02);
- }
-
- UINT64 CNcBoardPcimc85A::GetMaseDataOutAddr()
- {
- return Make64Addr(0, 0x11);
- }
-
- UINT64 CNcBoardPcimc85A::GetEepromDataOutAddr()
- {
- return Make64Addr(0, 0x10);
- }
-
- UINT64 CNcBoardPcimc85A::GetEepromDataInAddr()
- {
- return Make64Addr(0, 0x01);
- }
-
- UINT64 CNcBoardPcimc85A::GetEepromChipSelectedAddr()
- {
- return Make64Addr(2, 0x01);
- }
-
- UINT64 CNcBoardPcimc85A::GetEepromClockAddr()
- {
- return Make64Addr(1, 0x01);
- }
-
- UINT32 CNcBoardPcimc85A::GetRtcStart()
- {
- return Make32Addr(B85A_RTC_CTRL);
- }
-
- UINT32 CNcBoardPcimc85A::GetSpindleDataAddr()
- {
- // 在Lambda协议下,输出是一整个映像,一般会把模拟量排在最前面。
- // 但这里是使用2字节的,低字节在前,高10位有效(芯片宽度是10位)。
- // 可以继续沿用8位,只用高8位,这样只相当于降低了一点精度。
- // 以Lambda5S为例: ..2#112#.... 后一个2#为SVC。
- // ---- 杨开锦 2014-08-21
- return Make32Addr(0x07);
- }
-
- UINT32 CNcBoardPcimc85A::GetHandwheelEncoderDataAddr()
- {
- // 暂不考虑手轮,用250标示这个无效的地址 ---- 杨开锦 2014-05-22
- return Make32Addr(250);
- }
-
- int CNcBoardPcimc85A::GetHandwheelEncoder()
- {
- return 0;
- }
-
- int CNcBoardPcimc85A::GetEncoderFeedbackByAxis(int nIndex_)
- {
- CHECK_PARAM(nIndex_ >= 0 && nIndex_ < c_nMAX_NUM_OF_AXES_85A);
- #if defined (SIMUDRIVER)
- return 0;
- #else
- // 所有轴的编号是这样编的:
- // 把Bus0上各Controller上的轴依次排上,再排Bus1上的
- // 排完后得到的轴数组,具体某轴在数组中的下标就是其轴号
- const ADAPTER_BASE_INFO_V2* _pAdpInfo = m_pAdapter->GetAdapterBaseInfo();
- int _nBusCount = 1 + _pAdpInfo->nNumofAuxiliary;
- for (int _nBusNo = 0; _nBusNo < _nBusCount; _nBusNo++)
- {
- CLambdaBus* _pBus = m_pAdapter->GetBus(_nBusNo);
- if (!_pBus || !_pBus->IsInitialized() ||!_pBus->GetEnable())
- break;
-
- for (int _nCtrlOder = 0; _nCtrlOder < 8; _nCtrlOder++)
- {
- CLambdaController* _pCtrl = _pBus->GetController(_nCtrlOder);
- if (!_pCtrl || !_pCtrl->IsInitialized() || !_pCtrl->GetEnable())
- break;
-
- const CONTROLLER_BASE_INFO_V2* _pInfo = _pCtrl->GetControllerBaseInfo();
- if (nIndex_ >= _pInfo->nNumofAxis)
- {
- nIndex_ -= _pInfo->nNumofAxis;
- continue;
- }
-
- return _pCtrl->GetFeedback()->Get(nIndex_);
- }
- }
-
- ASSERT(FALSE);
- return 0;
- #endif
- }
-
- int CNcBoardPcimc85A::GetSendPulseByAxis(int nIndex)
- {
- return 0;
- }
-
- const char* CNcBoardPcimc85A::GetBoardType()
- {
- return "WH-PCIMC85A";
- }
-
- DWORD CNcBoardPcimc85A::GetBoardTypeId()
- {
- return '85A';
- }
-
- int CNcBoardPcimc85A::GetCycleTimeUs()
- {
- return 1000;
- }
-
- int CNcBoardPcimc85A::GetMaxPPC()
- {
- return 1000;
- }
-
- int CNcBoardPcimc85A::GetMaxNumOfAxes()
- {
- return c_nMAX_NUM_OF_AXES_85A;
- }
-
- int CNcBoardPcimc85A::GetMaxNumOfChannel()
- {
- return c_nMAX_NUM_OF_CHANNEL_85A;
- }
-
- BOOLEAN CNcBoardPcimc85A::OnInterrupt()
- {
- #if defined (SIMUDRIVER)
- m_bNccmdToSendValid = false;
- __super::OnInterrupt();
- return true;
- #else
- m_pAdapter->Update(1000);
- return true;
- #endif
- }
-
- #pragma pack(push, 8)
- struct FNAP_LAMBDA_PACKAGE : FNAP_HEADER
- {
- BYTE nBusIndex;
- BYTE nControllerIndex;
- BYTE nNA0[2];
- BYTE nHeader;
- BYTE nNA2;
- BYTE nDataLength;
- BYTE pData[1];
- };
- #pragma pack(pop)
- NTSTATUS CNcBoardPcimc85A::FnapWritePackage(FNAP_LAMBDA_PACKAGE* pFnap_)
- {
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_LAMBDA_PACKAGE) + pFnap_->nDataLength - 1);
- CHECK_PARAM(pFnap_->nOutSize == 0);
- TRACE0("CNcBoardPcimc85A::FnapWritePackage: begin ...\n");
- TRACE_INDENT;
- if (pFnap_->nBusIndex >= 4) // 最多4路总线通道
- return STATUS_UNSUCCESSFUL;
- if (pFnap_->nControllerIndex >= 8) // 每路总线最多级联8级
- return STATUS_UNSUCCESSFUL;
- if (pFnap_->nBusIndex != 0) // 暂不支持
- return STATUS_UNSUCCESSFUL;
-
- PACKAGE _packAge;
- memset(&_packAge, 0, sizeof(PACKAGE));
- _packAge.nCmd = pFnap_->nHeader;
- _packAge.nLength = pFnap_->nDataLength + 3;
- memcpy(_packAge.data, pFnap_->pData, (int)pFnap_->nDataLength);
-
- if(!m_pAdapter->GetBus(pFnap_->nBusIndex)->GetController(pFnap_->nControllerIndex)->WritePacket(&_packAge, NULL))
- return STATUS_UNSUCCESSFUL;
-
- TRACE_HEX(_packAge.buffer, _packAge.nLength);
- return STATUS_SUCCESS;
- }
-
- #pragma pack(push,8)
- struct FNAP_CONFIG_APPSYSFIFO : FNAP_HEADER
- {
- CCmdInfoBuffer* __ptr32 pDownFifo; // R0R3下行缓冲区
- CCmdInfoBuffer* __ptr32 pUpFifo; // R0R3上行缓冲区
- };
- #pragma pack(pop)
-
- NTSTATUS CNcBoardPcimc85A::FnapConfigAppSysFifo( FNAP_CONFIG_APPSYSFIFO* pFnap_ )
- {
- CHECK_PARAM(pFnap_->nInSize == sizeof(FNAP_CONFIG_APPSYSFIFO));
- CHECK_PARAM(pFnap_->nOutSize == sizeof(FNAP_CONFIG_APPSYSFIFO));
- TRACE0("CNcBoardPcimc85A::FnapConfigAppSysFifo: begin ...\n");
- TRACE_INDENT;
-
- pFnap_->pDownFifo = (CCmdInfoBuffer*)GetSwitchArea()->ConvertToR3Address(m_pAppSysDown);
- pFnap_->pUpFifo = (CCmdInfoBuffer*)GetSwitchArea()->ConvertToR3Address(m_pAppSysUp);
-
- #ifndef SIMUDRIVER
- if (m_pAppSysDown != NULL)
- {
- m_pAppSysDown->Reset();
- }
-
- if (m_pAppSysUp != NULL)
- {
- m_pAppSysUp->Reset();
- }
-
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(0));
- ASSERT(m_pAdapter->GetBus(0)->GetController(0));
- ASSERT(m_pAdapter->GetBus(0)->GetController(0)->GetSendPulse());
-
- CLambdaBus* _pBus = m_pAdapter->GetBus(0);
- CLambdaController* _pCtl = _pBus->GetController(0);
- CLambdaAppSysFifo* _pAppSys = _pCtl->GetAppSysFifo();
-
- _pAppSys->Set(m_pAppSysDown, m_pAppSysUp);
- #endif
-
- return STATUS_SUCCESS;
- }
-
- BYTE CNcBoardPcimc85A::GetInPortMap(UINT32 nAddr_)
- {
- WORD _offset = LOWORD(nAddr_);
-
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- ASSERT(_nBus < 4 && _nBus >= 0);
- ASSERT(_nCtrl < 8 && _nCtrl >= 0);
- ASSERT(_nByte < 256 && _nByte >= 0);
-
- #if defined (SIMUDRIVER)
- return 0x00;
- #else
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(_nBus));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetInput());
- return m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetInput()->Get(_nByte);
- #endif
- }
-
- BYTE CNcBoardPcimc85A::GetOutPortMap(UINT32 nAddr_)
- {
- WORD _offset = LOWORD(nAddr_);
-
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- ASSERT(_nBus < 4 && _nBus >= 0);
- ASSERT(_nCtrl < 8 && _nCtrl >= 0);
- ASSERT(_nByte < 256 && _nByte >= 0);
-
- #if defined (SIMUDRIVER)
- return 0x00;
- #else
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(_nBus));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetOutput());
- return m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetOutput()->Get(_nByte);
- #endif
- }
-
- void CNcBoardPcimc85A::SetOutPortMap(UINT32 nAddr_, BYTE nValue_)
- {
- WORD _offset = LOWORD(nAddr_);
-
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- ASSERT(_nBus < 4 && _nBus >= 0);
- ASSERT(_nCtrl < 8 && _nCtrl >= 0);
- ASSERT(_nByte < 256 && _nByte >= 0);
-
- #if defined (SIMUDRIVER)
- return;
- #else
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(_nBus));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetOutput());
- m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetOutput()->Set(_nByte, nValue_);
- #endif
- }
-
- BYTE CNcBoardPcimc85A::GetSynPortMap(UINT32 nAddr_)
- {
- WORD _offset = LOWORD(nAddr_);
-
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- ASSERT(_nBus < 4 && _nBus >= 0);
- ASSERT(_nCtrl < 8 && _nCtrl >= 0);
- ASSERT(_nByte < 256 && _nByte >= 0);
-
- #if defined (SIMUDRIVER)
- return 0x00;
- #else
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(_nBus));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetSendPulse());
- return m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetSendPulse()->GetSynOut(_nByte);
- #endif
- }
-
- void CNcBoardPcimc85A::SetSynPortMap(UINT32 nAddr_, BYTE nValue_)
- {
- WORD _offset = LOWORD(nAddr_);
-
- BYTE _nBus = HIBYTE(_offset) >> 4;
- BYTE _nCtrl = HIBYTE(_offset) & 0x0F;
- BYTE _nByte = LOBYTE(_offset);
- ASSERT(_nBus < 4 && _nBus >= 0);
- ASSERT(_nCtrl < 8 && _nCtrl >= 0);
- ASSERT(_nByte < 256 && _nByte >= 0);
-
- #if defined (SIMUDRIVER)
- return;
- #else
- ASSERT(m_pAdapter);
- ASSERT(m_pAdapter->GetBus(_nBus));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl));
- ASSERT(m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetSendPulse());
- m_pAdapter->GetBus(_nBus)->GetController(_nCtrl)->GetSendPulse()->SetSynOut(_nByte, nValue_);
- #endif
- }
-
- bool CNcBoardPcimc85A::Update()
- {
- m_bNccmdToSendValid = false;
-
- #if !defined (SIMUDRIVER)
- // for EX33A, 实现INMAP&OUTMAP的端口重定位 ---- 杨开锦 2016-12-23
- // 判别条件:如果用了EX33A上的Z轴,则表明在使用二代随动
- // 在驱动里实现把一代随动和二代随动的INMAP、OUTMAP空间的同步映射
- // 以便应用层可以不用去重配端口,使用相同地址的端口就可以包管一代和二代随动
- // 具体为:
- // LD5S INMAP '..2#114###........' OUTMAP '..2#112#....'
- // LD5S-04 INMAP '..2#114###........2#' OUTMAP '..2#112#....2#2#.'
- // EX30A INMAP '..4###2#.2#2#2#' OUTMAP '..2#2#2#11..'
- // EX33A INMAP '..4###2#.2#2#2#2#' OUTMAP '..2#2#2#11...2#2#..'
- CLambdaController* _pCtrl00 = m_pAdapter->GetBus(0)->GetController(0);
- CLambdaController* _pCtrl01 = m_pAdapter->GetBus(0)->GetController(1);
- bool _bEX33A = false;
- if (_pCtrl01)
- {
- const CONTROLLER_BASE_INFO_V2* _pInfo = _pCtrl01->GetControllerBaseInfo();
- const char* _pName = _pInfo->szName;
- if (_pName[0] == 'E' && _pName[1] == 'X' && _pName[2] == '3' && _pName[3] == '3' && _pName[4] == '\0')
- {
- _bEX33A = true;
- }
- }
-
- // 映射OUTMAP
- if (_bEX33A)
- {
- // 随动相关
- BYTE _nLDOUTByte12 = _pCtrl00->GetOutput()->Get(12);
- BYTE _nLDOUTByte13 = _pCtrl00->GetOutput()->Get(13);
- BYTE _nLDOUTByte14 = _pCtrl00->GetOutput()->Get(14);
- BYTE _nLDOUTByte15 = _pCtrl00->GetOutput()->Get(15);
- BYTE _nLDOUTByte16 = _pCtrl00->GetOutput()->Get(16);
- _pCtrl01->GetOutput()->Set(13, _nLDOUTByte12);
- _pCtrl01->GetOutput()->Set(14, _nLDOUTByte13);
- _pCtrl01->GetOutput()->Set(15, _nLDOUTByte14);
- _pCtrl01->GetOutput()->Set(16, _nLDOUTByte15);
- // _pCtrl01->GetOutput()->Set(17, _nLDOUTByte16);
-
- // 轴相关: 伺服使能 & 伺服清除
- // LD5S.Byte9.Bit3 => EX33A.Byte18.Bit0
- // LD5S.Byte10.Bit3 => EX33A.Byte18.Bit4
- /*BYTE _nLDOUTByte9 = _pCtrl00->GetOutput()->Get(9);
- BYTE _nLDOUTByte10 = _pCtrl00->GetOutput()->Get(10);
- BYTE _nEX33OUTByte18 = _pCtrl01->GetOutput()->Get(18);
- _nEX33OUTByte18 = ((_nLDOUTByte9 & 0x08) >> 3) + ((_nLDOUTByte10 & 0x08) >> 3);
- _pCtrl01->GetOutput()->Set(18, _nEX33OUTByte18);*/
- }
-
- // 映射INMAP
- if (_bEX33A)
- {
- // 随动相关
- BYTE _nEX33INByte15 = _pCtrl01->GetInput()->Get(15);
- BYTE _nEX33INByte16 = _pCtrl01->GetInput()->Get(16);
- _pCtrl00->GetInput()->Set(18, _nEX33INByte15);
- _pCtrl00->GetInput()->Set(19, _nEX33INByte16);
-
- // 轴相关: 伺服使能 & 伺服清除
- // EX33A.Byte17.Bit0 => LD5S.Byte12.Bit3
- // EX33A.Byte17.Bit4 => LD5S.Byte13.Bit3
- /*BYTE _nEX33INByte17 = _pCtrl01->GetInput()->Get(17);
- BYTE _nLDINByte12 = _pCtrl00->GetInput()->Get(12);
- BYTE _nLDINByte13 = _pCtrl00->GetInput()->Get(13);
- _nLDINByte12 = (_nLDINByte12 & 0xF7) | ((_nEX33INByte17 & 0x01) << 3);
- _pCtrl00->GetInput()->Set(12, _nLDINByte12);
- _nLDINByte13 = (_nLDINByte13 & 0xF7) | ((_nEX33INByte17 & 0x10) >> 1);
- _pCtrl00->GetInput()->Set(13, _nLDINByte13);*/
- }
- #endif
-
- CDevice::OnInterrupt();
-
- Synchronize();
- return m_bNccmdToSendValid;
- }
-
- bool CNcBoardPcimc85A::GetEnableBuffer()
- {
- return m_bEnableNcboardBuffer;
- }
-
- bool CNcBoardPcimc85A::GetOutPortMapIsValid()
- {
- return !GetOutputPort()->GetForceUpdated();
- }
-
- // 约定:一定是先发Ctrl0的脉冲,再发Ctrl1的脉冲,再Ctrl2,依此类推
- // 总的有无数据的标志是 m_bNccmdToSendValid
- // 各轴分别的数据标志是 m_bNccmdToSend[N]
- // CNccmdDispatcher85A填数据的时候是一起填进去的,所以总的标志跟分标志是同步的
- // 此处发送时,是逐个Controller发的,当所有填了数据的轴脉冲都发完了总标志就复位
- // ---- 杨开锦 2012-12-23
- bool CNcBoardPcimc85A::GetNccmd(int nIndex_, int* _pnPulse, int _nLength, BYTE* _pSynOutMap, int _nSynOutMapLength)
- {
- if(!m_bNccmdToSendValid)
- return false;
-
- int _nBegin = 0; // Begin Axis Index
- int _nBusNo = (nIndex_ & 0xF0) >> 4;
- int _nCtrlOder = (nIndex_ & 0x0F);
- CLambdaBus* _pBus = m_pAdapter->GetBus(_nBusNo);
- for (int _i = 0; _i < _nCtrlOder; _i++)
- {
- CLambdaController* _pCtrlI = _pBus->GetController(_i);
- const CONTROLLER_BASE_INFO_V2* _pInfo = _pCtrlI->GetControllerBaseInfo();
- _nBegin += _pInfo->nNumofAxis;
- }
-
- bool _bRet = false;
- C_ASSERT(_countof(m_nNccmdToSend) == _countof(m_bNccmdToSend));
- CHECK_PARAM(_nBegin + _nLength <= _countof(m_nNccmdToSend));
- for (int _i = 0; _i < _nLength; _i++)
- {
- // 向CLambdaDeviceProvider提供数据时,其单位是1/128 ---- 杨开锦 2014-09-13
- // Phoenix协议上,共有三种脉冲包:
- // 1.零脉冲包,各轴脉冲均为0,不需要携带脉冲数据;
- // 2.整数脉冲包,各轴脉冲均为整数,每轴的脉冲占2字节;
- // 3.小数脉冲包,名轴脉冲不均为整数,每轴脉冲占4字节,低7位为小数。
- // 因此,向CLambdaDeviceProvider提供时统一以1/128单位提交;
- // 发送脉冲处,可以根据收到的数据决定以哪种包形式进行下发。
- _pnPulse[_i] = m_nNccmdToSend[_nBegin + _i] * 128;
- if (m_bNccmdToSend[_nBegin + _i])
- _bRet = true;
-
- m_bNccmdToSend[_nBegin + _i] = false;
- }
-
- bool _bHasMore = false; // 所有轴都发完了就清总标志
- for (int _i = _nBegin + _nLength; _i < _countof(m_nNccmdToSend); _i++)
- {
- if (m_bNccmdToSend[_i])
- {
- _bHasMore = true;
- break;
- }
- }
- if (!_bHasMore)
- {
- m_bNccmdToSendValid = false;
- }
-
- return _bRet;
- }
-
- NTSTATUS CNcBoardPcimc85A::FnapGetVersion(FNAP_GET_VERSION* pFnap_)
- {
- NTSTATUS _nRet = __super::FnapGetVersion(pFnap_);
- m_pAdapter->GetTestString(pFnap_->BoardInfo.szSelfTest, sizeof(pFnap_->BoardInfo.szSelfTest));
- return _nRet;
- }
-
- BYTE CNcBoardPcimc85A::GetSynPortReserved(UINT32 nAddr_)
- {
- for (int _i = 0; _i < _countof(m_nSynPortReserved); _i++)
- {
- if (m_nSynPortReserved[_i][0] == nAddr_)
- return (BYTE)m_nSynPortReserved[_i][1];
- }
-
- return 0;
- }
-
- void CNcBoardPcimc85A::SetSynPortReserved(UINT32 nAddr_, BYTE nReserved_)
- {
- for (int _i = 0; _i < _countof(m_nSynPortReserved); _i++)
- {
- if (m_nSynPortReserved[_i][0] == 0)
- m_nSynPortReserved[_i][0] = nAddr_;
- if (m_nSynPortReserved[_i][0] == nAddr_)
- m_nSynPortReserved[_i][1] = (UINT32)nReserved_;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // CNcBoardPciemc85A
- //
- CNcBoardPciemc85A::CNcBoardPciemc85A(PDEVICE_OBJECT pFdo_, PDEVICE_OBJECT pPdo_, const char* pszName_)
- : CNcBoardPcimc85A(pFdo_, pPdo_, pszName_)
- {
- TRACE0("CNcBoardPciemc85A::CNcBoardPciemc85A begin ...\n");
- TRACE_INDENT;
- }
-
- CNcBoardPciemc85A::~CNcBoardPciemc85A()
- {
- TRACE0("CNcBoardPciemc85A::~CNcBoardPciemc85A begin ...\n");
- TRACE_INDENT;
- }
-
- void CNcBoardPciemc85A::Initialize()
- {
- TRACE0("CNcBoardPciemc85A::Initialize begin ...\n");
- TRACE_INDENT;
- __super::Initialize();
- m_pFuncServiceRoutine = (PKSERVICE_ROUTINE)CCh367::Ncadpt_InterruptHandler;
- }
-
- NTSTATUS CNcBoardPciemc85A::OnStartDevice()
- {
- TRACE0("CNcBoardPciemc85A::OnStartDevice begin ...\n");
- TRACE_INDENT;
- CCh367::InitializeBaseAddress(this->GetIoBaseAddress());
- m_pAdapter->SetCHType(CH_CH367);
- return __super::OnStartDevice();
- }
-
- NTSTATUS CNcBoardPciemc85A::OnCloseDevice()
- {
- TRACE0("CNcBoardPciemc85A::OnCloseDevice begin ...\n");
- TRACE_INDENT;
- CCh367::InitializeBaseAddress(NULL);
- return __super::OnCloseDevice();
- }
-
- NTSTATUS CNcBoardPciemc85A::ConnectInterrupt()
- {
- CCh367::PrepareConnectInterrupt();
- return __super::ConnectInterrupt();
- }
-
- NTSTATUS CNcBoardPciemc85A::DisconnectInterrupt()
- {
- CCh367::PrepareDisconnectInterrupt();
- return __super::DisconnectInterrupt();
- }
-
- const char* CNcBoardPciemc85A::GetBoardType()
- {
- return "WH-NC65A";
- }
-
- DWORD CNcBoardPciemc85A::GetBoardTypeId()
- {
- return '65A';
- }
-
- UINT CNcBoardPciemc85A::GetMaseFreqence()
- {
- return 1488095;
- }
|