Unified time base now so both GVRET and Socketcan devices yield timestamps in microseconds since the program started or clear was pressed, fixed frames per second display, fixed timestamps for sent frames
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "canconmanager.h"
|
#include "canconmanager.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -18,8 +20,14 @@ CANConManager::CANConManager(QObject *parent): QObject(parent)
|
|||||||
mTimer.setInterval(250); /*tick 4 times a second */
|
mTimer.setInterval(250); /*tick 4 times a second */
|
||||||
mTimer.setSingleShot(false);
|
mTimer.setSingleShot(false);
|
||||||
mTimer.start();
|
mTimer.start();
|
||||||
|
|
||||||
|
resetTimeBasis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CANConManager::resetTimeBasis()
|
||||||
|
{
|
||||||
|
mTimestampBasis = QDateTime::currentMSecsSinceEpoch() * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
CANConManager::~CANConManager()
|
CANConManager::~CANConManager()
|
||||||
{
|
{
|
||||||
@@ -70,6 +78,10 @@ void CANConManager::refreshCanList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t CANConManager::getTimeBasis()
|
||||||
|
{
|
||||||
|
return mTimestampBasis;
|
||||||
|
}
|
||||||
|
|
||||||
QList<CANConnection*>& CANConManager::getConnections()
|
QList<CANConnection*>& CANConManager::getConnections()
|
||||||
{
|
{
|
||||||
@@ -139,6 +151,7 @@ bool CANConManager::sendFrame(const CANFrame& pFrame)
|
|||||||
{
|
{
|
||||||
workingFrame.bus -= busBase;
|
workingFrame.bus -= busBase;
|
||||||
workingFrame.isReceived = false;
|
workingFrame.isReceived = false;
|
||||||
|
workingFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() * 1000) - mTimestampBasis);
|
||||||
txFrame = conn->getQueue().get();
|
txFrame = conn->getQueue().get();
|
||||||
*txFrame = workingFrame;
|
*txFrame = workingFrame;
|
||||||
conn->getQueue().queue();
|
conn->getQueue().queue();
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ public:
|
|||||||
|
|
||||||
CANConnection* getByName(const QString& pName) const;
|
CANConnection* getByName(const QString& pName) const;
|
||||||
|
|
||||||
|
uint64_t getTimeBasis();
|
||||||
|
void resetTimeBasis();
|
||||||
|
|
||||||
int getNumBuses();
|
int getNumBuses();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,6 +49,7 @@ private:
|
|||||||
static CANConManager* mInstance;
|
static CANConManager* mInstance;
|
||||||
QList<CANConnection*> mConns;
|
QList<CANConnection*> mConns;
|
||||||
QTimer mTimer;
|
QTimer mTimer;
|
||||||
|
uint64_t mTimestampBasis;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CANCONNECTIONMODEL_H
|
#endif // CANCONNECTIONMODEL_H
|
||||||
|
|||||||
+34
-18
@@ -18,7 +18,8 @@ GVRetSerial::GVRetSerial(QString portName) :
|
|||||||
gotValidated = true;
|
gotValidated = true;
|
||||||
isAutoRestart = false;
|
isAutoRestart = false;
|
||||||
|
|
||||||
txTimestampBasis = QDateTime::currentMSecsSinceEpoch();
|
timeBasis = 0;
|
||||||
|
lastSystemTimeBasis = 0;
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
@@ -147,18 +148,10 @@ bool GVRetSerial::piSendFrame(const CANFrame& frame)
|
|||||||
int c;
|
int c;
|
||||||
int ID;
|
int ID;
|
||||||
CANFrame tempFrame = frame;
|
CANFrame tempFrame = frame;
|
||||||
tempFrame.isReceived = false;
|
tempFrame.isReceived = false;
|
||||||
tempFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() - txTimestampBasis) * 1000);
|
|
||||||
|
|
||||||
//qDebug() << "Sending out frame with id " << frame->ID;
|
//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++;
|
framesRapid++;
|
||||||
|
|
||||||
if (serial == NULL) return false;
|
if (serial == NULL) return false;
|
||||||
@@ -240,7 +233,7 @@ void GVRetSerial::connectDevice()
|
|||||||
output.append((char)0xF1); //another command to the GVRET
|
output.append((char)0xF1); //another command to the GVRET
|
||||||
output.append((char)0x07); //request device information
|
output.append((char)0x07); //request device information
|
||||||
|
|
||||||
output.append((char)0xF1);
|
/*output.append((char)0xF1);
|
||||||
output.append((char)0x08); //setting singlewire mode
|
output.append((char)0x08); //setting singlewire mode
|
||||||
if (settings.value("Main/SingleWireMode", false).toBool())
|
if (settings.value("Main/SingleWireMode", false).toBool())
|
||||||
{
|
{
|
||||||
@@ -249,7 +242,7 @@ void GVRetSerial::connectDevice()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
output.append((char)0xFF); //signal we don't want single wire mode
|
output.append((char)0xFF); //signal we don't want single wire mode
|
||||||
}
|
}*/
|
||||||
|
|
||||||
output.append((char)0xF1); //yet another command
|
output.append((char)0xF1); //yet another command
|
||||||
output.append((char)0x09); //comm validation command
|
output.append((char)0x09); //comm validation command
|
||||||
@@ -293,7 +286,8 @@ void GVRetSerial::disconnectDevice() {
|
|||||||
void GVRetSerial::connectionTimeout()
|
void GVRetSerial::connectionTimeout()
|
||||||
{
|
{
|
||||||
//one second after trying to connect are we actually connected?
|
//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
|
//then emit the the failure signal and see if anyone cares
|
||||||
qDebug() << "Failed to connect to GVRET at that com port";
|
qDebug() << "Failed to connect to GVRET at that com port";
|
||||||
@@ -307,10 +301,11 @@ void GVRetSerial::readSerialData()
|
|||||||
{
|
{
|
||||||
QByteArray data = serial->readAll();
|
QByteArray data = serial->readAll();
|
||||||
unsigned char c;
|
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++)
|
for (int i = 0; i < data.length(); i++)
|
||||||
{
|
{
|
||||||
c = data.at(i);
|
c = data.at(i);
|
||||||
|
//qDebug() << c << " " << QString::number(c, 16) << " " << QString(c);
|
||||||
procRXChar(c);
|
procRXChar(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,6 +371,8 @@ void GVRetSerial::procRXChar(unsigned char c)
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
buildFrame.timestamp |= (uint)c << 24;
|
buildFrame.timestamp |= (uint)c << 24;
|
||||||
|
|
||||||
|
buildFrame.timestamp += timeBasis;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
buildFrame.ID = c;
|
buildFrame.ID = c;
|
||||||
@@ -425,7 +422,7 @@ void GVRetSerial::procRXChar(unsigned char c)
|
|||||||
qDebug() << "can't get a frame, ERROR";
|
qDebug() << "can't get a frame, ERROR";
|
||||||
|
|
||||||
//take the time the frame came in and try to resync the time base.
|
//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;
|
break;
|
||||||
@@ -447,7 +444,9 @@ void GVRetSerial::procRXChar(unsigned char c)
|
|||||||
case 3:
|
case 3:
|
||||||
buildTimeBasis += ((uint32_t)c << 24);
|
buildTimeBasis += ((uint32_t)c << 24);
|
||||||
qDebug() << "GVRET firmware reports timestamp of " << buildTimeBasis;
|
qDebug() << "GVRET firmware reports timestamp of " << buildTimeBasis;
|
||||||
txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - ((uint64_t)buildTimeBasis / (uint64_t)1000ull);
|
|
||||||
|
rebuildLocalTimeBasis();
|
||||||
|
|
||||||
continuousTimeSync = false;
|
continuousTimeSync = false;
|
||||||
rx_state = IDLE;
|
rx_state = IDLE;
|
||||||
break;
|
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()
|
void GVRetSerial::handleTick()
|
||||||
{
|
{
|
||||||
|
if (lastSystemTimeBasis != CANConManager::getInstance()->getTimeBasis()) rebuildLocalTimeBasis();
|
||||||
//qDebug() << "Tick!";
|
//qDebug() << "Tick!";
|
||||||
|
/*
|
||||||
if( CANCon::CONNECTED == getStatus() )
|
if( CANCon::CONNECTED == getStatus() )
|
||||||
{
|
{
|
||||||
if (!gotValidated && doValidation)
|
if (!gotValidated && doValidation)
|
||||||
@@ -600,7 +616,7 @@ void GVRetSerial::handleTick()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (doValidation && serial && serial->isOpen()) sendCommValidation();
|
if (doValidation && serial && serial->isOpen()) sendCommValidation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
/*************/
|
/*************/
|
||||||
|
|
||||||
|
|
||||||
#include "canframemodel.h"
|
#include "canframemodel.h"
|
||||||
#include "canconnection.h"
|
#include "canconnection.h"
|
||||||
|
#include "canconmanager.h"
|
||||||
|
|
||||||
namespace SERIALSTATE {
|
namespace SERIALSTATE {
|
||||||
|
|
||||||
@@ -65,12 +64,12 @@ private:
|
|||||||
void readSettings();
|
void readSettings();
|
||||||
void procRXChar(unsigned char);
|
void procRXChar(unsigned char);
|
||||||
void sendCommValidation();
|
void sendCommValidation();
|
||||||
|
void rebuildLocalTimeBasis();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QTimer mTimer;
|
QTimer mTimer;
|
||||||
QThread mThread;
|
QThread mThread;
|
||||||
|
|
||||||
|
|
||||||
bool doValidation;
|
bool doValidation;
|
||||||
bool gotValidated;
|
bool gotValidated;
|
||||||
bool isAutoRestart;
|
bool isAutoRestart;
|
||||||
@@ -85,8 +84,9 @@ protected:
|
|||||||
bool can0ListenOnly, can1ListenOnly;
|
bool can0ListenOnly, can1ListenOnly;
|
||||||
int deviceBuildNum;
|
int deviceBuildNum;
|
||||||
int deviceSingleWireMode;
|
int deviceSingleWireMode;
|
||||||
uint64_t txTimestampBasis;
|
|
||||||
uint32_t buildTimeBasis;
|
uint32_t buildTimeBasis;
|
||||||
|
int32_t timeBasis;
|
||||||
|
uint64_t lastSystemTimeBasis;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GVRETSERIAL_H
|
#endif // GVRETSERIAL_H
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ void SocketCan::framesReceived()
|
|||||||
/* test */
|
/* test */
|
||||||
bool sndNotif = false;
|
bool sndNotif = false;
|
||||||
|
|
||||||
|
uint64_t timeBasis = CANConManager::getInstance()->getTimeBasis();
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if(!mDev_p)
|
if(!mDev_p)
|
||||||
return;
|
return;
|
||||||
@@ -185,7 +187,7 @@ void SocketCan::framesReceived()
|
|||||||
frame_p->extended = false;
|
frame_p->extended = false;
|
||||||
frame_p->ID = recFrame.frameId();
|
frame_p->ID = recFrame.frameId();
|
||||||
frame_p->isReceived = true;
|
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 */
|
/* enqueue frame */
|
||||||
getQueue().queue();
|
getQueue().queue();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "canframemodel.h"
|
#include "canframemodel.h"
|
||||||
#include "canconnection.h"
|
#include "canconnection.h"
|
||||||
|
#include "canconmanager.h"
|
||||||
|
|
||||||
|
|
||||||
class SocketCan : public CANConnection
|
class SocketCan : public CANConnection
|
||||||
|
|||||||
+4
-3
@@ -477,8 +477,8 @@ void MainWindow::filterClearAll()
|
|||||||
void MainWindow::tickGUIUpdate()
|
void MainWindow::tickGUIUpdate()
|
||||||
{
|
{
|
||||||
rxFrames = model->sendBulkRefresh();
|
rxFrames = model->sendBulkRefresh();
|
||||||
if(rxFrames>0)
|
//if(rxFrames>0)
|
||||||
{
|
//{
|
||||||
int elapsed = elapsedTime->elapsed();
|
int elapsed = elapsedTime->elapsed();
|
||||||
if(elapsed) {
|
if(elapsed) {
|
||||||
framesPerSec = rxFrames * 1000 / elapsed;
|
framesPerSec = rxFrames * 1000 / elapsed;
|
||||||
@@ -499,7 +499,7 @@ void MainWindow::tickGUIUpdate()
|
|||||||
if (model->needsFilterRefresh()) updateFilterList();
|
if (model->needsFilterRefresh()) updateFilterList();
|
||||||
|
|
||||||
rxFrames = 0;
|
rxFrames = 0;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::gotFrames(int framesSinceLastUpdate)
|
void MainWindow::gotFrames(int framesSinceLastUpdate)
|
||||||
@@ -533,6 +533,7 @@ void MainWindow::clearFrames()
|
|||||||
{
|
{
|
||||||
ui->canFramesView->scrollToTop();
|
ui->canFramesView->scrollToTop();
|
||||||
model->clearFrames();
|
model->clearFrames();
|
||||||
|
CANConManager::getInstance()->resetTimeBasis();
|
||||||
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
ui->lbNumFrames->setText(QString::number(model->rowCount()));
|
||||||
bDirty = false;
|
bDirty = false;
|
||||||
loadedFileName = "";
|
loadedFileName = "";
|
||||||
|
|||||||
Reference in New Issue
Block a user