Files
bcrt/bcmil.cpp
2025-09-16 12:08:45 +03:00

221 lines
5.1 KiB
C++

#include <QDebug>
#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";
}