diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index 4092f86..008ee03 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -1,3 +1,5 @@ +#include + #include "canconmanager.h" @@ -18,8 +20,14 @@ CANConManager::CANConManager(QObject *parent): QObject(parent) mTimer.setInterval(250); /*tick 4 times a second */ mTimer.setSingleShot(false); mTimer.start(); + + resetTimeBasis(); } +void CANConManager::resetTimeBasis() +{ + mTimestampBasis = QDateTime::currentMSecsSinceEpoch() * 1000; +} CANConManager::~CANConManager() { @@ -70,6 +78,10 @@ void CANConManager::refreshCanList() } } +uint64_t CANConManager::getTimeBasis() +{ + return mTimestampBasis; +} QList& CANConManager::getConnections() { @@ -139,6 +151,7 @@ bool CANConManager::sendFrame(const CANFrame& pFrame) { workingFrame.bus -= busBase; workingFrame.isReceived = false; + workingFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() * 1000) - mTimestampBasis); txFrame = conn->getQueue().get(); *txFrame = workingFrame; conn->getQueue().queue(); diff --git a/connections/canconmanager.h b/connections/canconmanager.h index d9c7e40..dc94431 100644 --- a/connections/canconmanager.h +++ b/connections/canconmanager.h @@ -20,6 +20,9 @@ public: CANConnection* getByName(const QString& pName) const; + uint64_t getTimeBasis(); + void resetTimeBasis(); + int getNumBuses(); /** @@ -46,6 +49,7 @@ private: static CANConManager* mInstance; QList mConns; QTimer mTimer; + uint64_t mTimestampBasis; }; #endif // CANCONNECTIONMODEL_H diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index c76a5ee..90a79a1 100644 --- a/connections/gvretserial.cpp +++ b/connections/gvretserial.cpp @@ -18,7 +18,8 @@ GVRetSerial::GVRetSerial(QString portName) : gotValidated = true; isAutoRestart = false; - txTimestampBasis = QDateTime::currentMSecsSinceEpoch(); + timeBasis = 0; + lastSystemTimeBasis = 0; readSettings(); } @@ -147,18 +148,10 @@ bool GVRetSerial::piSendFrame(const CANFrame& frame) int c; int ID; CANFrame tempFrame = frame; - tempFrame.isReceived = false; - tempFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() - txTimestampBasis) * 1000); + tempFrame.isReceived = false; //qDebug() << "Sending out frame with id " << frame->ID; - //show our sent frames in the list too. This happens even if we're not connected. - /* model lives in UI thread, we need to call invokeMethod */ - //QMetaObject::invokeMethod(model, "addFrame", - // Qt::QueuedConnection, - // Q_ARG(CANFrame, tempFrame), - // Q_ARG(bool, false)); - framesRapid++; if (serial == NULL) return false; @@ -240,7 +233,7 @@ void GVRetSerial::connectDevice() output.append((char)0xF1); //another command to the GVRET output.append((char)0x07); //request device information - output.append((char)0xF1); + /*output.append((char)0xF1); output.append((char)0x08); //setting singlewire mode if (settings.value("Main/SingleWireMode", false).toBool()) { @@ -249,7 +242,7 @@ void GVRetSerial::connectDevice() else { output.append((char)0xFF); //signal we don't want single wire mode - } + }*/ output.append((char)0xF1); //yet another command output.append((char)0x09); //comm validation command @@ -293,7 +286,8 @@ void GVRetSerial::disconnectDevice() { void GVRetSerial::connectionTimeout() { //one second after trying to connect are we actually connected? - if (CANCon::NOT_CONNECTED==getStatus()) //no? + //if (CANCon::NOT_CONNECTED==getStatus()) //no? + if (!gotValidated) { //then emit the the failure signal and see if anyone cares qDebug() << "Failed to connect to GVRET at that com port"; @@ -307,10 +301,11 @@ void GVRetSerial::readSerialData() { QByteArray data = serial->readAll(); unsigned char c; - //qDebug() << (tr("Got data from serial. Len = %0").arg(data.length())); + qDebug() << (tr("Got data from serial. Len = %0").arg(data.length())); for (int i = 0; i < data.length(); i++) { c = data.at(i); + //qDebug() << c << " " << QString::number(c, 16) << " " << QString(c); procRXChar(c); } } @@ -376,6 +371,8 @@ void GVRetSerial::procRXChar(unsigned char c) break; case 3: buildFrame.timestamp |= (uint)c << 24; + + buildFrame.timestamp += timeBasis; break; case 4: buildFrame.ID = c; @@ -425,7 +422,7 @@ void GVRetSerial::procRXChar(unsigned char c) qDebug() << "can't get a frame, ERROR"; //take the time the frame came in and try to resync the time base. - if (continuousTimeSync) txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - (buildFrame.timestamp / 1000); + //if (continuousTimeSync) txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - (buildFrame.timestamp / 1000); } } break; @@ -447,7 +444,9 @@ void GVRetSerial::procRXChar(unsigned char c) case 3: buildTimeBasis += ((uint32_t)c << 24); qDebug() << "GVRET firmware reports timestamp of " << buildTimeBasis; - txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - ((uint64_t)buildTimeBasis / (uint64_t)1000ull); + + rebuildLocalTimeBasis(); + continuousTimeSync = false; rx_state = IDLE; break; @@ -576,11 +575,28 @@ void GVRetSerial::procRXChar(unsigned char c) } } +void GVRetSerial::rebuildLocalTimeBasis() +{ + uint64_t currTime = QDateTime::currentMSecsSinceEpoch() * 1000; + + /* + our time basis is the value we have to modulate the main system basis by in order + to sync the GVRET timestamps to the rest of the system. + The rest of the system uses CANConManager::getInstance()->getTimeBasis as the basis. + GVRET returns to us the current time since boot up in microseconds. + currTime stores the "system" timestamp when the GVRET timestamp was retrieved. + */ + lastSystemTimeBasis = CANConManager::getInstance()->getTimeBasis(); + int64_t systemDelta = currTime - lastSystemTimeBasis; + int32_t localDelta = buildTimeBasis - systemDelta; + timeBasis = localDelta; +} void GVRetSerial::handleTick() { + if (lastSystemTimeBasis != CANConManager::getInstance()->getTimeBasis()) rebuildLocalTimeBasis(); //qDebug() << "Tick!"; - +/* if( CANCon::CONNECTED == getStatus() ) { if (!gotValidated && doValidation) @@ -600,7 +616,7 @@ void GVRetSerial::handleTick() } } } - +*/ if (doValidation && serial && serial->isOpen()) sendCommValidation(); } diff --git a/connections/gvretserial.h b/connections/gvretserial.h index 4038a01..915af16 100644 --- a/connections/gvretserial.h +++ b/connections/gvretserial.h @@ -10,10 +10,9 @@ #include /*************/ - #include "canframemodel.h" #include "canconnection.h" - +#include "canconmanager.h" namespace SERIALSTATE { @@ -65,12 +64,12 @@ private: void readSettings(); void procRXChar(unsigned char); void sendCommValidation(); + void rebuildLocalTimeBasis(); protected: QTimer mTimer; QThread mThread; - bool doValidation; bool gotValidated; bool isAutoRestart; @@ -85,8 +84,9 @@ protected: bool can0ListenOnly, can1ListenOnly; int deviceBuildNum; int deviceSingleWireMode; - uint64_t txTimestampBasis; uint32_t buildTimeBasis; + int32_t timeBasis; + uint64_t lastSystemTimeBasis; }; #endif // GVRETSERIAL_H diff --git a/connections/socketcan.cpp b/connections/socketcan.cpp index b49e1fe..771f686 100644 --- a/connections/socketcan.cpp +++ b/connections/socketcan.cpp @@ -155,6 +155,8 @@ void SocketCan::framesReceived() /* test */ bool sndNotif = false; + uint64_t timeBasis = CANConManager::getInstance()->getTimeBasis(); + /* sanity checks */ if(!mDev_p) return; @@ -185,7 +187,7 @@ void SocketCan::framesReceived() frame_p->extended = false; frame_p->ID = recFrame.frameId(); frame_p->isReceived = true; - frame_p->timestamp = recFrame.timeStamp().seconds()*1000000 + recFrame.timeStamp().microSeconds(); + frame_p->timestamp = (recFrame.timeStamp().seconds()*1000000 + recFrame.timeStamp().microSeconds()) - timeBasis; /* enqueue frame */ getQueue().queue(); diff --git a/connections/socketcan.h b/connections/socketcan.h index c303236..debd091 100644 --- a/connections/socketcan.h +++ b/connections/socketcan.h @@ -8,6 +8,7 @@ #include "canframemodel.h" #include "canconnection.h" +#include "canconmanager.h" class SocketCan : public CANConnection diff --git a/mainwindow.cpp b/mainwindow.cpp index 9498a0c..0d73526 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -477,8 +477,8 @@ void MainWindow::filterClearAll() void MainWindow::tickGUIUpdate() { rxFrames = model->sendBulkRefresh(); - if(rxFrames>0) - { + //if(rxFrames>0) + //{ int elapsed = elapsedTime->elapsed(); if(elapsed) { framesPerSec = rxFrames * 1000 / elapsed; @@ -499,7 +499,7 @@ void MainWindow::tickGUIUpdate() if (model->needsFilterRefresh()) updateFilterList(); rxFrames = 0; - } + //} } void MainWindow::gotFrames(int framesSinceLastUpdate) @@ -533,6 +533,7 @@ void MainWindow::clearFrames() { ui->canFramesView->scrollToTop(); model->clearFrames(); + CANConManager::getInstance()->resetTimeBasis(); ui->lbNumFrames->setText(QString::number(model->rowCount())); bDirty = false; loadedFileName = "";