#include #include "bcmil.h" #include "WDMTMKv2.cpp" TTmkEventData tmkEvD; HANDLE hEvent; int nTmk; uint8_t wAddr_RT, wRecTrans; unsigned long dwGoodStarts = 0, dwBusyStarts = 0, dwErrStarts = 0, dwStatStarts = 0; unsigned long dwStarts = 0L; TMK_DATA wSubAddr, wState, wStatus; int bcrtFlag; //RT = 0, BC = 1 //Open the driver, configuration, create event MIL::MIL(int dev_index) { qDebug() << "MIL constructor"; if (TmkOpen()) { qDebug() << "TmkOpen() error"; closeAll(); } else { if ((dev_index > tmkgetmaxn()) || (dev_index < 0)) { closeAll(); } else { this->m_TmkIndex = dev_index; if (tmkconfig(this->m_TmkIndex)) { closeAll(); } } } hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!hEvent) { qDebug() << "CreateEvent() error"; closeAll(); } ResetEvent(hEvent); tmkdefevent(hEvent, TRUE); } int MIL::WaitInt(TMK_DATA wCtrlCode) { //Wait for an interrupt DWORD k; k = WaitForSingleObject(hEvent, 1000); switch (k) { case WAIT_OBJECT_0: ResetEvent(hEvent); break; case WAIT_TIMEOUT: qDebug() << "Interrupt timeout error\n"; return 1; default: qDebug() << "k = " << k; qDebug() << "Interrupt wait error\n"; return 1; } // Get interrupt data // We do not need to check tmkEvD.nInt because bcstartx with CX_NOSIG // guarantees us only single interrupt of single type nInt == 3 tmkgetevd(&tmkEvD); if (tmkEvD.bcx.wResultX & SX_IB_MASK) { // We have set bit(s) in Status Word if (((tmkEvD.bcx.wResultX & SX_ERR_MASK) == SX_NOERR) || ((tmkEvD.bcx.wResultX & SX_ERR_MASK) == SX_TOD)) { wStatus = bcgetansw(wCtrlCode); // We have either no errors or Data Time Out (No Data) error if (wStatus & BUSY_MASK) // We have BUSY bit set ++dwBusyStarts; else // We have unknown bit(s) set ++dwStatStarts; } else // We have an error ++dwErrStarts; } else if (tmkEvD.bcx.wResultX & SX_ERR_MASK) // We have an error ++dwErrStarts; else // We have a completed message ++dwGoodStarts; ++dwStarts; return 0; } void MIL::closeAll() { qDebug() << "Close All"; if(!bcrtFlag) rtreset(); else bcreset(); CloseHandle(hEvent); tmkdone(ALL_TMKS); TmkClose(); } bool MIL::GetEvent(unsigned short Timeout) { //int MASK = 0; if (tmkselect(this->m_TmkIndex)) { qDebug() << "tmkselect() error"; return false; } //MASK = MASK | BUSY; //rtsetanswbits(BUSY); switch (WaitForSingleObject(hEvent, Timeout)) { case WAIT_OBJECT_0: qDebug() << "Interrupt"; ResetEvent(hEvent); tmkgetevd(&tmkEvD); qDebug() << "1 bc wResult " << tmkEvD.bc.wResult; qDebug() << "1 bc wAW1 " << tmkEvD.bc.wAW1; qDebug() << "1 bc wAW2 " << tmkEvD.bc.wAW2; qDebug() << "1 bcx wBase " << tmkEvD.bcx.wBase; qDebug() << "1 bcx wResultX " << tmkEvD.bcx.wResultX; qDebug() << "1 rt wStatus" << tmkEvD.rt.wStatus; qDebug() << "1 rt wCmd" << tmkEvD.rt.wCmd; qDebug() << "1 mt wBase " << tmkEvD.mt.wBase; qDebug() << "1 mt wResultX " << tmkEvD.mt.wResultX; qDebug() << "1 mrt wStatus" << tmkEvD.mrt.wStatus; qDebug() << "1 tmk wRequest" << tmkEvD.tmk.wRequest; return true; break; case WAIT_TIMEOUT: //qDebug() << "No new messages"; return false; break; default: qDebug() << "Interrupt wait error"; return false; break; } } MIL::~MIL() { qDebug() << "MIL destructor"; } BC_MIL::BC_MIL(int dev_index): MIL(dev_index) { qDebug() << "BC_MIL constructor"; //Find first configured device for (nTmk = 0; nTmk <= MAX_TMK_NUMBER; ++nTmk) if (!tmkselect(nTmk)) break; if (nTmk > MAX_TMK_NUMBER) { qDebug() << "tmkselect error"; closeAll(); } //Try to reset in BC mode if (bcreset()) { qDebug() << "bcreset error"; closeAll(); } } BC_MIL::~BC_MIL() { qDebug() << "BC_MIL destructor"; } RT_MIL::RT_MIL(int dev_index, unsigned short Addr): MIL(dev_index) { qDebug() << "RT_MIL constructor"; this->m_Addr = Addr; //Try to reset in RT mode if (rtreset()) { qDebug() << "rtreset() error"; closeAll(); } //Set RT address, set flag mode, enable data irqs rtdefaddress(Addr); rtdefmode(0); rtdefirqmode(rtgetirqmode()&~RT_DATA_BL); //Ready to receive, not ready to transmit for (wSubAddr = 1; wSubAddr <= 30; ++wSubAddr) { rtdefsubaddr(RT_RECEIVE, wSubAddr); rtclrflag(); rtdefsubaddr(RT_TRANSMIT, wSubAddr); rtclrflag(); } } RT_MIL::~RT_MIL() { qDebug() << "RT_MIL destructor"; }