|
|
@ -19,6 +19,8 @@ |
|
|
|
#include "QGC.h" |
|
|
|
#include "QGC.h" |
|
|
|
#include <MG.h> |
|
|
|
#include <MG.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, bool parity, |
|
|
|
SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, bool parity, |
|
|
|
int dataBits, int stopBits) : |
|
|
|
int dataBits, int stopBits) : |
|
|
|
m_bytesRead(0), |
|
|
|
m_bytesRead(0), |
|
|
@ -137,8 +139,7 @@ void SerialLink::writeSettings() |
|
|
|
void SerialLink::run() |
|
|
|
void SerialLink::run() |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Initialize the connection
|
|
|
|
// Initialize the connection
|
|
|
|
if (!hardwareConnect()) |
|
|
|
if (!hardwareConnect()) { |
|
|
|
{ |
|
|
|
|
|
|
|
//Need to error out here.
|
|
|
|
//Need to error out here.
|
|
|
|
emit communicationError(getName(),"Error connecting: " + m_port->errorString()); |
|
|
|
emit communicationError(getName(),"Error connecting: " + m_port->errorString()); |
|
|
|
disconnect(); // This tidies up and sends the necessary signals
|
|
|
|
disconnect(); // This tidies up and sends the necessary signals
|
|
|
@ -155,30 +156,25 @@ void SerialLink::run() |
|
|
|
qint64 timeout = 5000; |
|
|
|
qint64 timeout = 5000; |
|
|
|
int linkErrorCount = 0; |
|
|
|
int linkErrorCount = 0; |
|
|
|
|
|
|
|
|
|
|
|
forever |
|
|
|
forever { |
|
|
|
{ |
|
|
|
QMutexLocker locker(&this->m_stoppMutex); |
|
|
|
{ |
|
|
|
if(m_stopp) { |
|
|
|
QMutexLocker locker(&this->m_stoppMutex); |
|
|
|
m_stopp = false; |
|
|
|
if(m_stopp) |
|
|
|
break; // exit the thread
|
|
|
|
{ |
|
|
|
} |
|
|
|
m_stopp = false; |
|
|
|
|
|
|
|
break; // exit the thread
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_reqReset) |
|
|
|
if (m_reqReset) { |
|
|
|
{ |
|
|
|
m_reqReset = false; |
|
|
|
m_reqReset = false; |
|
|
|
emit communicationUpdate(getName(),"Reset requested via DTR signal"); |
|
|
|
communicationUpdate(getName(),"Reset requested via DTR signal"); |
|
|
|
m_port->setDataTerminalReady(true); |
|
|
|
m_port->setDataTerminalReady(true); |
|
|
|
msleep(250); |
|
|
|
msleep(250); |
|
|
|
m_port->setDataTerminalReady(false); |
|
|
|
m_port->setDataTerminalReady(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (isConnected() && (linkErrorCount > 100)) { |
|
|
|
if (isConnected() && (linkErrorCount > 100)) { |
|
|
|
qDebug() << "linkErrorCount too high: disconnecting!"; |
|
|
|
qDebug() << "linkErrorCount too high: disconnecting!"; |
|
|
|
linkErrorCount = 0; |
|
|
|
linkErrorCount = 0; |
|
|
|
communicationError("SerialLink", tr("Disconnecting on too many link errors")); |
|
|
|
emit communicationUpdate(getName(), tr("Disconnecting on too many link errors")); |
|
|
|
disconnect(); |
|
|
|
disconnect(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -186,19 +182,21 @@ void SerialLink::run() |
|
|
|
QMutexLocker writeLocker(&m_writeMutex); |
|
|
|
QMutexLocker writeLocker(&m_writeMutex); |
|
|
|
int numWritten = m_port->write(m_transmitBuffer); |
|
|
|
int numWritten = m_port->write(m_transmitBuffer); |
|
|
|
bool txSuccess = m_port->waitForBytesWritten(1); |
|
|
|
bool txSuccess = m_port->waitForBytesWritten(1); |
|
|
|
if (!txSuccess || (numWritten != m_transmitBuffer.count())) |
|
|
|
if (!txSuccess || (numWritten != m_transmitBuffer.count())) { |
|
|
|
{ |
|
|
|
|
|
|
|
linkErrorCount++; |
|
|
|
linkErrorCount++; |
|
|
|
qDebug() << "TX Error! wrote" << numWritten << ", asked for " << m_transmitBuffer.count() << "bytes"; |
|
|
|
qDebug() << "TX Error! wrote" << numWritten << ", asked for " << m_transmitBuffer.count() << "bytes"; |
|
|
|
} else { |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
linkErrorCount = 0; |
|
|
|
linkErrorCount = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
m_transmitBuffer = m_transmitBuffer.remove(0, numWritten); |
|
|
|
m_transmitBuffer = m_transmitBuffer.remove(0, numWritten); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//wait n msecs for data to be ready
|
|
|
|
|
|
|
|
//[TODO][BB] lower to SerialLink::poll_interval?
|
|
|
|
bool success = m_port->waitForReadyRead(10); |
|
|
|
bool success = m_port->waitForReadyRead(10); |
|
|
|
|
|
|
|
|
|
|
|
if (success) { // Waits for 1/2 second [TODO][BB] lower to SerialLink::poll_interval?
|
|
|
|
if (success) { |
|
|
|
QByteArray readData = m_port->readAll(); |
|
|
|
QByteArray readData = m_port->readAll(); |
|
|
|
while (m_port->waitForReadyRead(10)) |
|
|
|
while (m_port->waitForReadyRead(10)) |
|
|
|
readData += m_port->readAll(); |
|
|
|
readData += m_port->readAll(); |
|
|
@ -210,24 +208,21 @@ void SerialLink::run() |
|
|
|
m_bitsReceivedTotal += readData.length() * 8; |
|
|
|
m_bitsReceivedTotal += readData.length() * 8; |
|
|
|
linkErrorCount = 0; |
|
|
|
linkErrorCount = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
linkErrorCount++; |
|
|
|
linkErrorCount++; |
|
|
|
//qDebug() << "Wait read response timeout" << QTime::currentTime().toString();
|
|
|
|
qDebug() << "Wait read response timeout" << QTime::currentTime().toString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (bytes != m_bytesRead) // i.e things are good and data is being read.
|
|
|
|
if (bytes != m_bytesRead) { // i.e things are good and data is being read.
|
|
|
|
{ |
|
|
|
|
|
|
|
bytes = m_bytesRead; |
|
|
|
bytes = m_bytesRead; |
|
|
|
msecs = QDateTime::currentMSecsSinceEpoch(); |
|
|
|
msecs = QDateTime::currentMSecsSinceEpoch(); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else { |
|
|
|
{ |
|
|
|
if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) { |
|
|
|
if (QDateTime::currentMSecsSinceEpoch() - msecs > timeout) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
//It's been 10 seconds since the last data came in. Reset and try again
|
|
|
|
//It's been 10 seconds since the last data came in. Reset and try again
|
|
|
|
msecs = QDateTime::currentMSecsSinceEpoch(); |
|
|
|
msecs = QDateTime::currentMSecsSinceEpoch(); |
|
|
|
if (msecs - initialmsecs > 25000) |
|
|
|
if (msecs - initialmsecs > 25000) { |
|
|
|
{ |
|
|
|
|
|
|
|
//After initial 25 seconds, timeouts are increased to 30 seconds.
|
|
|
|
//After initial 25 seconds, timeouts are increased to 30 seconds.
|
|
|
|
//This prevents temporary silences from things like calibration commands
|
|
|
|
//This prevents temporary silences from things like calibration commands
|
|
|
|
//from screwing things up. In all reality, timeouts should be enabled/disabled
|
|
|
|
//from screwing things up. In all reality, timeouts should be enabled/disabled
|
|
|
@ -235,25 +230,22 @@ void SerialLink::run() |
|
|
|
//TODO ^^
|
|
|
|
//TODO ^^
|
|
|
|
timeout = 30000; |
|
|
|
timeout = 30000; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!triedDTR && triedreset) |
|
|
|
if (!triedDTR && triedreset) { |
|
|
|
{ |
|
|
|
|
|
|
|
triedDTR = true; |
|
|
|
triedDTR = true; |
|
|
|
communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); |
|
|
|
emit communicationUpdate(getName(),"No data to receive on COM port. Attempting to reset via DTR signal"); |
|
|
|
qDebug() << "No data!!! Attempting reset via DTR."; |
|
|
|
qDebug() << "No data!!! Attempting reset via DTR."; |
|
|
|
m_port->setDataTerminalReady(true); |
|
|
|
m_port->setDataTerminalReady(true); |
|
|
|
msleep(250); |
|
|
|
msleep(250); |
|
|
|
m_port->setDataTerminalReady(false); |
|
|
|
m_port->setDataTerminalReady(false); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (!triedreset) |
|
|
|
else if (!triedreset) { |
|
|
|
{ |
|
|
|
|
|
|
|
qDebug() << "No data!!! Attempting reset via reboot command."; |
|
|
|
qDebug() << "No data!!! Attempting reset via reboot command."; |
|
|
|
communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); |
|
|
|
emit communicationUpdate(getName(),"No data to receive on COM port. Assuming possible terminal mode, attempting to reset via \"reboot\" command"); |
|
|
|
m_port->write("reboot\r\n",8); |
|
|
|
m_port->write("reboot\r\n",8); |
|
|
|
triedreset = true; |
|
|
|
triedreset = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else { |
|
|
|
{ |
|
|
|
emit communicationUpdate(getName(),"No data to receive on COM port...."); |
|
|
|
communicationUpdate(getName(),"No data to receive on COM port...."); |
|
|
|
|
|
|
|
qDebug() << "No data!!!"; |
|
|
|
qDebug() << "No data!!!"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -406,8 +398,7 @@ bool SerialLink::connect() |
|
|
|
**/ |
|
|
|
**/ |
|
|
|
bool SerialLink::hardwareConnect() |
|
|
|
bool SerialLink::hardwareConnect() |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(m_port) |
|
|
|
if(m_port) { |
|
|
|
{ |
|
|
|
|
|
|
|
qDebug() << "SerialLink:" << QString::number((long)this, 16) << "closing port"; |
|
|
|
qDebug() << "SerialLink:" << QString::number((long)this, 16) << "closing port"; |
|
|
|
m_port->close(); |
|
|
|
m_port->close(); |
|
|
|
delete m_port; |
|
|
|
delete m_port; |
|
|
@ -416,21 +407,19 @@ bool SerialLink::hardwareConnect() |
|
|
|
qDebug() << "SerialLink: hardwareConnect to " << m_portName; |
|
|
|
qDebug() << "SerialLink: hardwareConnect to " << m_portName; |
|
|
|
m_port = new QSerialPort(m_portName); |
|
|
|
m_port = new QSerialPort(m_portName); |
|
|
|
|
|
|
|
|
|
|
|
if (m_port == NULL) |
|
|
|
if (m_port == NULL) { |
|
|
|
{ |
|
|
|
|
|
|
|
emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); |
|
|
|
emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); |
|
|
|
return false; // couldn't create serial port.
|
|
|
|
return false; // couldn't create serial port.
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(m_port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); |
|
|
|
QObject::connect(m_port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected())); |
|
|
|
QObject::connect(m_port, SIGNAL(error(QSerialPort::SerialPortError)), |
|
|
|
QObject::connect(m_port, SIGNAL(error(SerialLinkPortError_t)), |
|
|
|
this, SLOT(linkError(QSerialPort::SerialPortError))); |
|
|
|
this, SLOT(linkError(SerialLinkPortError_t))); |
|
|
|
|
|
|
|
|
|
|
|
// port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
|
|
|
|
// port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
|
|
|
|
m_connectionStartTime = MG::TIME::getGroundTimeNow(); |
|
|
|
m_connectionStartTime = MG::TIME::getGroundTimeNow(); |
|
|
|
|
|
|
|
|
|
|
|
if (!m_port->open(QIODevice::ReadWrite)) |
|
|
|
if (!m_port->open(QIODevice::ReadWrite)) { |
|
|
|
{ |
|
|
|
|
|
|
|
emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); |
|
|
|
emit communicationUpdate(getName(),"Error opening port: " + m_port->errorString()); |
|
|
|
m_port->close(); |
|
|
|
m_port->close(); |
|
|
|
return false; // couldn't open serial port
|
|
|
|
return false; // couldn't open serial port
|
|
|
@ -456,7 +445,7 @@ bool SerialLink::hardwareConnect() |
|
|
|
return true; // successful connection
|
|
|
|
return true; // successful connection
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SerialLink::linkError(QSerialPort::SerialPortError error) |
|
|
|
void SerialLink::linkError(SerialLinkPortError_t error) |
|
|
|
{ |
|
|
|
{ |
|
|
|
qDebug() << error; |
|
|
|
qDebug() << error; |
|
|
|
} |
|
|
|
} |
|
|
|