forked from GerhardHoffmann/DCLibraries
430 lines
14 KiB
C++
430 lines
14 KiB
C++
#include "com.h"
|
|
#include <QDebug>
|
|
//#include "controlBus.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
///
|
|
/// serial hardware layer
|
|
///
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static int64_t com_want2read;
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// --------- PUBLIC --------------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
|
|
void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength)
|
|
{
|
|
sendBuffer=data;
|
|
sendLen=sendLength;
|
|
if (CatSerial->isOpen())
|
|
{
|
|
//qDebug() << "sending..." << sendBuffer;
|
|
CatSerial->write(sendBuffer);
|
|
} else
|
|
qDebug() << "error sending, port is not open";
|
|
|
|
}
|
|
|
|
|
|
bool T_com::readFromSerial(QByteArray &data, uint16_t &sendLength)
|
|
{
|
|
// return one time true if new data (completly) read.
|
|
// return new data in &data and &sendLength to other objects
|
|
uint16_t ll=rawInLen;
|
|
if (!CatSerial->isOpen())
|
|
return false;
|
|
data.clear();
|
|
data.append(rawInput);
|
|
sendLength=ll;
|
|
rawInLen=0; // beim 2. Aufruf 0 zurück weil nichts neues da
|
|
if (ll>0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// --------- PRIVATES --------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
T_com::T_com(QObject *parent) : QObject(parent)
|
|
{
|
|
// port settings come from tabCom->Sdata->serial
|
|
|
|
gpi_serialChanged();
|
|
CatSerial = new QSerialPort(); // PortHW object for Control&Analyse Tool
|
|
//CatSerial->clear();
|
|
//CatSerial->clearError();
|
|
|
|
connect(CatSerial, &QSerialPort::readyRead, this, &T_com::readSomeBytes);
|
|
// still reading, not sure if complete, undefined number of calls while reading
|
|
|
|
connect(CatSerial, &QSerialPort::bytesWritten, this, &T_com::serialSendComplete);
|
|
// system confirms sending complete
|
|
|
|
//connect(CatSerial, &QSerialPort::dataTerminalReadyChanged, this, &T_com::incomingWake);
|
|
//connect(CatSerial, &QSerialPort::requestToSendChanged, this, &T_com::incomingWake);
|
|
|
|
// timer detects time gap in input flow
|
|
serRecTime = new QTimer();
|
|
connect(serRecTime, SIGNAL(timeout()), this, SLOT(receiveTO()));
|
|
serRecTime->setSingleShot(true); // single shot! only one impulse if receive complete
|
|
serRecTime->stop(); // on hold
|
|
|
|
// check COM-TAB periodic if user wants to connect or disconnect
|
|
QTimer *ChkConnectTimer = new QTimer();
|
|
connect(ChkConnectTimer, SIGNAL(timeout()), this, SLOT(ser_ISR100ms()));
|
|
ChkConnectTimer->setSingleShot(false);
|
|
ChkConnectTimer->start(100); // in ms
|
|
com_want2read=0;
|
|
}
|
|
|
|
|
|
|
|
|
|
T_com::~T_com()
|
|
{
|
|
if (CatSerial->isOpen())
|
|
CatSerial->close();
|
|
}
|
|
|
|
|
|
void T_com::ser_ISR100ms()
|
|
{
|
|
// call every 100ms to check if user(HMI) wants to connect or disconnect
|
|
|
|
//qDebug() << "~~>LIB" << "checking connect button... " ;
|
|
|
|
uint8_t chkConn = gpi_getSerialConn(); // from global GUI buffer (Sdata)
|
|
switch (chkConn)
|
|
{
|
|
case 0: // 0 button "connect" was just released
|
|
closeSerialPort();
|
|
gpi_serialChanged(); // set chkConn to 2, thus getting edge
|
|
break;
|
|
case 1: // 1 button "connect" was just pressed
|
|
open_Serial_Port();
|
|
gpi_serialChanged(); // set chkConn to 2, thus getting edge
|
|
break;
|
|
}
|
|
|
|
|
|
if (CatSerial->isOpen())
|
|
gpi_serialIsOpen(true);
|
|
else
|
|
gpi_serialIsOpen(false);
|
|
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
|
|
char T_com::open_Serial_Port()
|
|
{
|
|
bool ret;
|
|
QString myString=nullptr, myPortName=nullptr, myBaudStr=nullptr;
|
|
int myBaudNr;
|
|
|
|
if (CatSerial->isOpen())
|
|
return 0; // opening twice is not allowed
|
|
|
|
//qDebug() << "connecting..." << myPortName;
|
|
myPortName=gpi_getComPortName(); // was selected and stored from GUI
|
|
CatSerial->setPortName(myPortName);
|
|
myBaudNr=gpi_getBaudNr(); // was selected and stored from GUI
|
|
switch (myBaudNr)
|
|
{
|
|
// 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200
|
|
case 0: CatSerial->setBaudRate(QSerialPort::Baud1200); myBaudStr="1200"; break;
|
|
case 1: CatSerial->setBaudRate(QSerialPort::Baud9600); myBaudStr="9600"; break;
|
|
case 2: CatSerial->setBaudRate(QSerialPort::Baud19200); myBaudStr="19200"; break;
|
|
case 3: CatSerial->setBaudRate(QSerialPort::Baud38400); myBaudStr="38400"; break;
|
|
case 4: CatSerial->setBaudRate(QSerialPort::Baud57600); myBaudStr="57600"; break;
|
|
case 5: CatSerial->setBaudRate(QSerialPort::Baud115200); myBaudStr="115200"; break;
|
|
}
|
|
|
|
CatSerial->setDataBits(QSerialPort::Data8);
|
|
// alt: QSerialPort::Data5,6,7,8
|
|
|
|
CatSerial->setParity(QSerialPort::NoParity);
|
|
// alt: EvenParity, OddParity, NoParity
|
|
|
|
CatSerial->setStopBits(QSerialPort::OneStop);
|
|
// alternative: OneStop, TwoStop, OneAndHalfStop
|
|
|
|
CatSerial->setFlowControl(QSerialPort::NoFlowControl);
|
|
// alt: HardwareControl, SoftwareControl, NoFlowControl
|
|
|
|
ret=CatSerial->open(QIODevice::ReadWrite);
|
|
// alt: QIODevice::ReadWrite QIODevice::ReadOnly QIODevice::WriteOnly
|
|
if (!ret)
|
|
{
|
|
myString.clear();
|
|
myString = "error ";
|
|
myString.append(CatSerial->errorString());
|
|
qDebug() << myString;
|
|
gpi_setTxt4comStateLine(myString);
|
|
return 0;
|
|
} else
|
|
{
|
|
myString.clear();
|
|
myString.append(myPortName);
|
|
//lang=myString.size();
|
|
myString.append(" opened with ");
|
|
myString.append(myBaudStr);
|
|
myString.append(" 8N1");
|
|
qDebug() << myString;
|
|
gpi_setTxt4comStateLine(myString);
|
|
gpi_setTxt4RsDiagWin(myString+"\n");
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void T_com::closeSerialPort()
|
|
{
|
|
if (CatSerial->isOpen())
|
|
{
|
|
qDebug() << "closing connection";
|
|
CatSerial->close();
|
|
gpi_setTxt4comStateLine("closed");
|
|
gpi_setTxt4RsDiagWin("closed");
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void T_com::readSomeBytes(void)
|
|
{
|
|
// called by serial-read-detection
|
|
// restart off-time as input flow is ongoing
|
|
|
|
// timer for slow receive
|
|
// and serves as timeout for fast receive is msg is shorter as expected
|
|
serRecTime->stop();
|
|
serRecTime->start(20); // in ms
|
|
|
|
//qDebug()<< "com-rec read some bytes";
|
|
|
|
this->receiveByLength(); // since 14.12.21: fast receive
|
|
}
|
|
|
|
void T_com::receiveFixLen(int64_t nrOfbytesToReceive)
|
|
{
|
|
// call this before sending a request to slave
|
|
// then we know exactly when reception is complete -> much faster
|
|
com_want2read=nrOfbytesToReceive;
|
|
// since 14.12.21: FastDevice Protocol has two lengthen:
|
|
// fast: 12byte reception long: 68byte
|
|
}
|
|
|
|
void T_com::receiveByLength(void)
|
|
{
|
|
|
|
if (CatSerial->isOpen())
|
|
{
|
|
QString myString=nullptr, tmpStr=nullptr;
|
|
int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes
|
|
|
|
//qDebug()<< "com-rec current Len: "<< nrOfBytesreceived;
|
|
|
|
if (nrOfBytesreceived >= com_want2read)
|
|
{
|
|
QByteArray data = CatSerial->readAll(); // erst auslesen wenn alles da! löscht den Empfangspuffer
|
|
serRecTime->stop(); // stop timeout to avoid 2nd emit
|
|
rawInLen=uint16_t (nrOfBytesreceived);
|
|
rawInput.clear();
|
|
rawInput.append(data);
|
|
//qDebug()<< "com-recFinished by Len "<< rawInLen;
|
|
gpi_set2ndTxt4RsDiagWin(myString); // 4.10.23 hier neu
|
|
emit receivingFinished();
|
|
}
|
|
}
|
|
}
|
|
|
|
void T_com::receiveTO(void)
|
|
{
|
|
// no new input data for 20ms, --> assuming frame complete
|
|
// save data in private "rawInput"-buffer
|
|
|
|
if (CatSerial->isOpen())
|
|
{
|
|
|
|
QString myString=nullptr, tmpStr=nullptr;
|
|
int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes
|
|
QByteArray data = CatSerial->readAll();
|
|
|
|
rawInLen=uint16_t (nrOfBytesreceived);
|
|
rawInput.clear();
|
|
rawInput.append(data);
|
|
//rawInput[rawInLen]=0; // Zwangsterminierung bei QByteArray nicht nötig
|
|
|
|
// diag display in serial in/out window and debug window
|
|
myString.clear();
|
|
myString.setNum(rawInLen);
|
|
myString.append(" in: ");
|
|
//myString.append(rawInput);
|
|
for (int ii=0; ii<rawInLen; ii++)
|
|
{
|
|
tmpStr.clear();
|
|
tmpStr.setNum(rawInput[ii],16); // problem: wenn >0x80 dann wird EIN Byte 16 stellig angezeigt
|
|
int ll=tmpStr.length();
|
|
if (ll>2)
|
|
{
|
|
myString.append(tmpStr[ll-2]);
|
|
myString.append(tmpStr[ll-1]);
|
|
} else
|
|
{
|
|
myString.append(tmpStr);
|
|
}
|
|
myString.append(" ");
|
|
}
|
|
myString.append("\n");
|
|
#ifdef PRINTALLDEBUGS
|
|
qDebug() << "VCP:" << myString; // display all inputs and outputs in output window
|
|
#endif
|
|
//gpi_setTxt4RsDiagWin(myString);
|
|
gpi_set2ndTxt4RsDiagWin(myString); // 4.10.23: diese verwenden weil die gpi_setTxt4RsDiagWin() durch Ausgabe ueberschrieben wird
|
|
//qDebug()<< "com-recFinished by TO";
|
|
emit receivingFinished();
|
|
}
|
|
}
|
|
|
|
void T_com::serialSendComplete(void)
|
|
{
|
|
// system confirms sending complete, diag display
|
|
QString myString=nullptr, tmpStr=nullptr;
|
|
|
|
myString.clear();
|
|
myString.setNum(sendLen);
|
|
myString.append(" out: ");
|
|
|
|
for (int ii=0; ii<sendLen; ii++)
|
|
{
|
|
tmpStr.clear();
|
|
tmpStr.setNum(sendBuffer[ii],16); // problem: wenn >0x80 dann 16stellig
|
|
int ll=tmpStr.length();
|
|
if (ll>2)
|
|
{
|
|
//qDebug() << "long_string" << ll << "\n";
|
|
myString.append(tmpStr[ll-2]);
|
|
myString.append(tmpStr[ll-1]);
|
|
|
|
} else
|
|
{
|
|
myString.append(tmpStr);
|
|
}
|
|
myString.append(" ");
|
|
}
|
|
|
|
#ifdef PRINTALLDEBUGS
|
|
myString.append("\n");
|
|
qDebug() << myString; // display all output data in out-window
|
|
#endif
|
|
|
|
gpi_setTxt4RsDiagWin(myString);
|
|
|
|
emit sendingFinished(); // for whom it may interest
|
|
}
|
|
|
|
|
|
bool T_com::isPortOpen(void)
|
|
{
|
|
if (CatSerial->isOpen())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------------------------------------
|
|
|
|
/*
|
|
uint8_t T_com::getAllPortPins(void)
|
|
{
|
|
uint8_t rs232pins=0;
|
|
rs232pins= uint8_t(CatSerial->pinoutSignals());
|
|
// rs232pins: all signals bitwise coded in one byte:
|
|
// readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output)
|
|
// unused inputs: bit1=RxD bit 3=DCD bit 5 = RING
|
|
// handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80)
|
|
//qDebug()<<"serial port pins: " << rs232pins;
|
|
return rs232pins;
|
|
}
|
|
|
|
bool T_com::getHSin_CTS(void)
|
|
{
|
|
// return the used Handshake IN (CTS, alt. DSR): true= high level (+8V)
|
|
|
|
uint8_t rs232pins=0;
|
|
|
|
rs232pins= uint8_t(CatSerial->pinoutSignals());
|
|
// rs232pins: all signals bitwise coded in one byte:
|
|
// readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output)
|
|
// unused inputs: bit1=RxD bit 3=DCD bit 5 = RING
|
|
// handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80)
|
|
|
|
if (rs232pins & 0x80) // CTS
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool T_com::getHSin_DSR(void)
|
|
{
|
|
uint8_t rs232pins=0;
|
|
rs232pins= uint8_t(CatSerial->pinoutSignals());
|
|
if (rs232pins & 0x10) // DSR
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void T_com::incomingWake(void) //(bool LevelOfTheBit)
|
|
{
|
|
emit wasWokenBySerialHandshake();
|
|
}
|
|
|
|
bool T_com::setHSout_RTS(bool hsout)
|
|
{
|
|
// hsout true=positiv voltage +12V false= -12V
|
|
// retval: true=setting OK
|
|
|
|
bool cc;
|
|
// 10.5.19, am Windows-PC nachgemessen, funktioniert gut
|
|
// false ergibt -12V true ergibt +12V
|
|
|
|
cc=CatSerial->setRequestToSend(hsout); // RTS out
|
|
// retval true means "setting was successful"
|
|
|
|
// alternative: use DTR as Handshake:
|
|
//cc=CatSerial->setDataTerminalReady(false); // DTR out
|
|
// retval true means "setting was successful"
|
|
//qDebug()<<"RTS " <<cc;
|
|
return cc;
|
|
}
|
|
|
|
bool T_com::setHSout_DTR(bool hsout)
|
|
{
|
|
// hsout true=positiv voltage +12V false= -12V
|
|
// retval: true=setting OK
|
|
|
|
bool cc;
|
|
// 10.5.19, am Windows-PC nachgemessen, funktioniert gut
|
|
// false ergibt -12V true ergibt +12V
|
|
|
|
cc=CatSerial->setDataTerminalReady(hsout); // DTR out
|
|
// retval true means "setting was successful"
|
|
//qDebug()<<"DTR " <<cc;
|
|
return cc;
|
|
}
|
|
*/
|