Merge pull request #284 from collin80/WIP
Merge WIP changes back into Master
This commit is contained in:
+23
-2
@@ -311,6 +311,8 @@ void CANFrameModel::recalcOverwrite()
|
||||
uint64_t idAugmented; //id in lower 29 bits, bus number shifted up 29 bits
|
||||
foreach(CANFrame frame, frames)
|
||||
{
|
||||
if (frame.frameType() != frame.DataFrame) continue;
|
||||
|
||||
idAugmented = frame.frameId();
|
||||
idAugmented = idAugmented + (frame.bus << 29ull);
|
||||
if (!overWriteFrames.contains(idAugmented))
|
||||
@@ -445,7 +447,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
tempString.append(QString::number(thisFrame.frameId() & 0x7));
|
||||
return tempString;
|
||||
}
|
||||
if (thisFrame.frameType() != QCanBusFrame::RemoteRequestFrame) {
|
||||
if (thisFrame.frameType() == QCanBusFrame::DataFrame) {
|
||||
if (dataLen < 0) dataLen = 0;
|
||||
//if (dLen > 8) dLen = 8;
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
@@ -457,6 +459,10 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
tempString.append(QString::fromUtf8(&byt, 1));
|
||||
}
|
||||
}
|
||||
if (thisFrame.frameType() == QCanBusFrame::ErrorFrame)
|
||||
{
|
||||
tempString = "ERROR";
|
||||
}
|
||||
return tempString;
|
||||
case Column::Data:
|
||||
if (dataLen < 0) dataLen = 0;
|
||||
@@ -470,8 +476,23 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
||||
else tempString.append(QString::number(data[i], 10));
|
||||
tempString.append(" ");
|
||||
}
|
||||
if (thisFrame.frameType() == thisFrame.ErrorFrame)
|
||||
{
|
||||
if (thisFrame.error() & thisFrame.TransmissionTimeoutError) tempString.append("\nTX Timeout");
|
||||
if (thisFrame.error() & thisFrame.LostArbitrationError) tempString.append("\nLost Arbitration");
|
||||
if (thisFrame.error() & thisFrame.ControllerError) tempString.append("\nController Error");
|
||||
if (thisFrame.error() & thisFrame.ProtocolViolationError) tempString.append("\nProtocol Violation");
|
||||
if (thisFrame.error() & thisFrame.TransceiverError) tempString.append("\nTransceiver Error");
|
||||
if (thisFrame.error() & thisFrame.MissingAcknowledgmentError) tempString.append("\nMissing ACK");
|
||||
if (thisFrame.error() & thisFrame.BusOffError) tempString.append("\nBus OFF");
|
||||
if (thisFrame.error() & thisFrame.BusError) tempString.append("\nBus ERR");
|
||||
if (thisFrame.error() & thisFrame.ControllerRestartError) tempString.append("\nController restart err");
|
||||
if (thisFrame.error() & thisFrame.UnknownError) tempString.append("\nUnknown error type");
|
||||
}
|
||||
//TODO: technically the actual returned bytes for an error frame encode some more info. Not interpreting it yet.
|
||||
|
||||
//now, if we're supposed to interpret the data and the DBC handler is loaded then use it
|
||||
if (dbcHandler != nullptr && interpretFrames)
|
||||
if ( (dbcHandler != nullptr) && interpretFrames && (thisFrame.frameType() == thisFrame.DataFrame) )
|
||||
{
|
||||
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
|
||||
if (msg != nullptr)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CONFIG
|
||||
#define CONFIG
|
||||
|
||||
#define VERSION 200
|
||||
#define VERSION 201
|
||||
|
||||
//try to keep this in sync.
|
||||
//SavvyCAN will complain if you connect a GVRET board with a revision
|
||||
|
||||
@@ -150,7 +150,7 @@ void ConnectionWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("ConnWindow/WindowSize", QSize(956, 665)).toSize());
|
||||
move(settings.value("ConnWindow/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("ConnWindow/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -184,55 +184,22 @@ void SerialBusConnection::framesReceived()
|
||||
if(frame_p) {
|
||||
frame_p->setPayload(recFrame.payload());
|
||||
frame_p->bus = 0;
|
||||
|
||||
if (recFrame.frameType() == QCanBusFrame::ErrorFrame) {
|
||||
// Constants defined in include/uapi/linux/can/error.h
|
||||
//since the whole program uses QCanBusFrame now we can just grab errors directly out of the proper place from now on
|
||||
/*
|
||||
switch (recFrame.error()) {
|
||||
case QCanBusFrame::TransmissionTimeoutError:
|
||||
frame_p->setFrameId(0x20000001);
|
||||
break;
|
||||
case QCanBusFrame::LostArbitrationError:
|
||||
frame_p->ID = 0x20000002;
|
||||
break;
|
||||
case QCanBusFrame::ControllerError:
|
||||
frame_p->ID = 0x20000004;
|
||||
break;
|
||||
case QCanBusFrame::ProtocolViolationError:
|
||||
frame_p->ID = 0x20000008;
|
||||
break;
|
||||
case QCanBusFrame::TransceiverError:
|
||||
frame_p->ID = 0x20000010;
|
||||
break;
|
||||
case QCanBusFrame::MissingAcknowledgmentError:
|
||||
frame_p->ID = 0x20000020;
|
||||
break;
|
||||
case QCanBusFrame::BusOffError:
|
||||
frame_p->ID = 0x20000040;
|
||||
break;
|
||||
case QCanBusFrame::BusError:
|
||||
frame_p->ID = 0x20000080;
|
||||
break;
|
||||
case QCanBusFrame::ControllerRestartError:
|
||||
frame_p->ID = 0x20000100;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
frame_p->extended = true;
|
||||
*/
|
||||
frame_p->isReceived = true;
|
||||
} else {
|
||||
if (recFrame.frameType() == recFrame.ErrorFrame)
|
||||
{
|
||||
frame_p->setExtendedFrameFormat(recFrame.hasExtendedFrameFormat());
|
||||
frame_p->setFrameId(recFrame.frameId() + 0x20000000ull);
|
||||
frame_p->isReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame_p->setExtendedFrameFormat(recFrame.hasExtendedFrameFormat());
|
||||
frame_p->setFrameId(recFrame.frameId());
|
||||
frame_p->setTimeStamp(recFrame.timeStamp());
|
||||
frame_p->setFrameType(recFrame.frameType());
|
||||
frame_p->setError(recFrame.error());
|
||||
|
||||
/* If recorded frame has a local echo, it is a Tx message, and thus should not be marked as Rx */
|
||||
frame_p->isReceived = !recFrame.hasLocalEcho();
|
||||
}
|
||||
frame_p->setTimeStamp(recFrame.timeStamp());
|
||||
frame_p->setFrameType(recFrame.frameType());
|
||||
frame_p->setError(recFrame.error());
|
||||
/* If recorded frame has a local echo, it is a Tx message, and thus should not be marked as Rx */
|
||||
frame_p->isReceived = !recFrame.hasLocalEcho();
|
||||
|
||||
if (useSystemTime) {
|
||||
frame_p->setTimeStamp(QCanBusFrame::TimeStamp(0, QDateTime::currentMSecsSinceEpoch() * 1000ul));
|
||||
|
||||
@@ -6,8 +6,30 @@
|
||||
DBC_MESSAGE::DBC_MESSAGE()
|
||||
{
|
||||
sigHandler = new DBCSignalHandler;
|
||||
ID = 0;
|
||||
len = 0;
|
||||
multiplexorSignal = nullptr;
|
||||
sender = nullptr;
|
||||
}
|
||||
|
||||
DBC_SIGNAL::DBC_SIGNAL()
|
||||
{
|
||||
bias = 0;
|
||||
isMultiplexed = false;
|
||||
isMultiplexor = false;
|
||||
max = 1;
|
||||
min = 0;
|
||||
multiplexValue = 0;
|
||||
factor = 1.0;
|
||||
intelByteOrder = false;
|
||||
parentMessage = nullptr;
|
||||
receiver = nullptr;
|
||||
signalSize = 1;
|
||||
startBit = 1;
|
||||
valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The way that the DBC file format works is kind of weird... For intel format signals you count up
|
||||
from the start bit to the end bit which is (startbit + signallength - 1). At each point
|
||||
|
||||
@@ -106,6 +106,7 @@ public: //TODO: this is sloppy. It shouldn't all be public!
|
||||
QList<DBC_ATTRIBUTE_VALUE> attributes;
|
||||
QList<DBC_VAL_ENUM_ENTRY> valList;
|
||||
|
||||
DBC_SIGNAL();
|
||||
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true);
|
||||
bool processAsInt(const CANFrame &frame, int32_t &outValue);
|
||||
bool processAsDouble(const CANFrame &frame, double &outValue);
|
||||
|
||||
+49
-32
@@ -281,6 +281,7 @@ DBCFile::DBCFile()
|
||||
messageHandler->setMatchingCriteria(EXACT);
|
||||
messageHandler->setFilterLabeling(false);
|
||||
isDirty = false;
|
||||
fileName = "<Unsaved File>";
|
||||
}
|
||||
|
||||
DBCFile::DBCFile(const DBCFile& cpy) : QObject()
|
||||
@@ -759,7 +760,7 @@ bool DBCFile::parseDefaultAttrLine(QString line)
|
||||
return false;
|
||||
}
|
||||
|
||||
void DBCFile::loadFile(QString fileName)
|
||||
bool DBCFile::loadFile(QString fileName)
|
||||
{
|
||||
QFile *inFile = new QFile(fileName);
|
||||
QString line, rawLine;
|
||||
@@ -777,7 +778,8 @@ void DBCFile::loadFile(QString fileName)
|
||||
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
delete inFile;
|
||||
return;
|
||||
qDebug() << "Could not load the file!";
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "Starting DBC load";
|
||||
@@ -1039,6 +1041,7 @@ void DBCFile::loadFile(QString fileName)
|
||||
filePath = fileName.left(fileName.length() - this->fileName.length());
|
||||
assocBuses = -1;
|
||||
isDirty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant DBCFile::processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ)
|
||||
@@ -1156,7 +1159,7 @@ bool DBCFile::parseAttribute(QString inpString, DBC_ATTRIBUTE &attr)
|
||||
return goodAttr;
|
||||
}
|
||||
|
||||
void DBCFile::saveFile(QString fileName)
|
||||
bool DBCFile::saveFile(QString fileName)
|
||||
{
|
||||
int nodeNumber = 1;
|
||||
int msgNumber = 1;
|
||||
@@ -1168,7 +1171,7 @@ void DBCFile::saveFile(QString fileName)
|
||||
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
{
|
||||
delete outFile;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//right now it outputs a standard hard coded boilerplate
|
||||
@@ -1454,6 +1457,7 @@ void DBCFile::saveFile(QString fileName)
|
||||
QStringList fileList = fileName.split('/');
|
||||
this->fileName = fileList[fileList.length() - 1]; //whoops... same name as parameter in this function.
|
||||
filePath = fileName.left(fileName.length() - this->fileName.length());
|
||||
return true;
|
||||
}
|
||||
|
||||
void DBCHandler::saveDBCFile(int idx)
|
||||
@@ -1534,6 +1538,7 @@ int DBCHandler::createBlankFile()
|
||||
falseNode.name = "Vector__XXX";
|
||||
falseNode.comment = "Default node if none specified";
|
||||
newFile.dbc_nodes.append(falseNode);
|
||||
newFile.setAssocBus(-1);
|
||||
|
||||
loadedFiles.append(newFile);
|
||||
return loadedFiles.count();
|
||||
@@ -1542,9 +1547,16 @@ int DBCHandler::createBlankFile()
|
||||
DBCFile* DBCHandler::loadDBCFile(QString filename)
|
||||
{
|
||||
DBCFile newFile;
|
||||
newFile.loadFile(filename);
|
||||
loadedFiles.append(newFile);
|
||||
return &loadedFiles.last();
|
||||
if (newFile.loadFile(filename))
|
||||
{
|
||||
loadedFiles.append(newFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
//createBlankFile();
|
||||
}
|
||||
if (loadedFiles.count()> 0) return &loadedFiles.last();
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
//the only reason to even bother sending the index is to see if
|
||||
@@ -1587,6 +1599,7 @@ DBCFile* DBCHandler::loadJSONFile(QString filename)
|
||||
|
||||
createBlankFile();
|
||||
thisFile = &loadedFiles.last();
|
||||
|
||||
QFile *inFile = new QFile(filename);
|
||||
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
@@ -1843,40 +1856,44 @@ DBCHandler::DBCHandler()
|
||||
// Load previously saved DBC file settings
|
||||
QSettings settings;
|
||||
int filecount = settings.value("DBC/FileCount", 0).toInt();
|
||||
qDebug() << "Previously loaded DBC file count: " << filecount;
|
||||
for (int i=0; i<filecount; i++)
|
||||
{
|
||||
QString filename = settings.value("DBC/Filename_" + QString(i),"").toString();
|
||||
DBCFile * file = loadDBCFile(filename);
|
||||
int bus = settings.value("DBC/AssocBus_" + QString(i),0).toInt();
|
||||
file->setAssocBus(bus);
|
||||
if (file)
|
||||
{
|
||||
int bus = settings.value("DBC/AssocBus_" + QString(i),0).toInt();
|
||||
file->setAssocBus(bus);
|
||||
|
||||
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString(i),0).toInt();
|
||||
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString(i),0).toInt();
|
||||
|
||||
DBC_ATTRIBUTE attr;
|
||||
DBC_ATTRIBUTE attr;
|
||||
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = matchingCriteria;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "matchingcriteria";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setMatchingCriteria(matchingCriteria);
|
||||
|
||||
bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = filterLabeling;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setFilterLabeling(filterLabeling);
|
||||
bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
|
||||
attr.attrType = MESSAGE;
|
||||
attr.defaultValue = filterLabeling;
|
||||
attr.enumVals.clear();
|
||||
attr.lower = 0;
|
||||
attr.upper = 0;
|
||||
attr.name = "filterlabeling";
|
||||
attr.valType = QINT;
|
||||
file->dbc_attributes.append(attr);
|
||||
file->messageHandler->setFilterLabeling(filterLabeling);
|
||||
|
||||
qInfo() << "Loaded DBC file" << filename << " (bus:" << bus
|
||||
<< ", Matching Criteria:" << (int)matchingCriteria << "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
|
||||
qInfo() << "Loaded DBC file" << filename << " (bus:" << bus
|
||||
<< ", Matching Criteria:" << (int)matchingCriteria << "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ public:
|
||||
DBC_ATTRIBUTE *findAttributeByName(QString name);
|
||||
DBC_ATTRIBUTE *findAttributeByIdx(int idx);
|
||||
void findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE> *list);
|
||||
void saveFile(QString);
|
||||
void loadFile(QString);
|
||||
bool saveFile(QString);
|
||||
bool loadFile(QString);
|
||||
QString getFullFilename();
|
||||
QString getFilename();
|
||||
QString getPath();
|
||||
|
||||
+11
-7
@@ -133,7 +133,7 @@ void DBCMainEditor::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DBCMainEditor/WindowSize", QSize(1103, 571)).toSize());
|
||||
move(settings.value("DBCMainEditor/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DBCMainEditor/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,8 +370,8 @@ void DBCMainEditor::updatedMessage(DBC_MESSAGE *msg)
|
||||
item->setText(0, msgInfo);
|
||||
//editor could have changed the parent Node too. Have to figure out which node
|
||||
//is parent in the GUI and compare that to parent in the data.
|
||||
DBC_NODE *oldParent = dbcFile->findNodeByName(item->parent()->text(0));
|
||||
if (oldParent != msg->sender)
|
||||
DBC_NODE *oldParent = dbcFile->findNodeByName(item->parent()->text(0).split(" - ")[0]);
|
||||
if (oldParent != msg->sender && oldParent)
|
||||
{
|
||||
qDebug() << "Changed parent of message. Trying to rehome it.";
|
||||
QTreeWidgetItem *newParent = nullptr;
|
||||
@@ -448,7 +448,11 @@ void DBCMainEditor::newMessage()
|
||||
nodeItem = msgItem->parent();
|
||||
}
|
||||
|
||||
DBC_NODE *node = dbcFile->findNodeByName(nodeItem->data(0, Qt::DisplayRole).toString());
|
||||
//if there was a comment this will find the location of the comment and snip it out.
|
||||
QString nodeName = nodeItem->data(0, Qt::DisplayRole).toString().split(" - ")[0];
|
||||
|
||||
DBC_NODE *node = dbcFile->findNodeByName(nodeName);
|
||||
if (!node) node = dbcFile->findNodeByIdx(0);
|
||||
DBC_MESSAGE msg;
|
||||
DBC_MESSAGE *msgPtr;
|
||||
if (msgItem)
|
||||
@@ -467,17 +471,17 @@ void DBCMainEditor::newMessage()
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.name = nodeItem->text(0) + "Msg" + QString::number(randGen.bounded(500));
|
||||
msg.name = nodeName + "Msg" + QString::number(randGen.bounded(500));
|
||||
msg.ID = 0;
|
||||
msg.len = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.name = nodeItem->text(0) + "Msg" + QString::number(randGen.bounded(500));
|
||||
msg.name = nodeName + "Msg" + QString::number(randGen.bounded(500));
|
||||
msg.ID = 0;
|
||||
msg.len = 0;
|
||||
}
|
||||
}
|
||||
msg.sender = node;
|
||||
|
||||
dbcFile->messageHandler->addMessage(msg);
|
||||
|
||||
@@ -187,7 +187,7 @@ void DBCMessageEditor::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DBCMessageEditor/WindowSize", QSize(340, 400)).toSize());
|
||||
move(settings.value("DBCMessageEditor/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DBCMessageEditor/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ void DBCNodeEditor::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DBCNodeEditor/WindowSize", QSize(312, 128)).toSize());
|
||||
move(settings.value("DBCNodeEditor/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DBCNodeEditor/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ void DBCSignalEditor::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DBCSignalEditor/WindowSize", QSize(1000, 600)).toSize());
|
||||
move(settings.value("DBCSignalEditor/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DBCSignalEditor/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -149,7 +149,7 @@ void FirmwareUploaderWindow::sendFirmwareChunk()
|
||||
for (int i = 0; i < 6; i++) xorByte = xorByte ^ static_cast<unsigned char>(output->payload()[i]);
|
||||
output->payload()[6] = xorByte;
|
||||
output->setPayload(bytes);
|
||||
sendCANFrame(output);
|
||||
CANConManager::getInstance()->sendFrame(*output);
|
||||
timer->start();
|
||||
}
|
||||
|
||||
@@ -187,16 +187,18 @@ void FirmwareUploaderWindow::handleStartStopTransfer()
|
||||
QByteArray bytes(8,0);
|
||||
output->bus = bus;
|
||||
output->setFrameId(baseAddress);
|
||||
output->setFrameType(QCanBusFrame::DataFrame);
|
||||
|
||||
output->payload()[0] = 0xEF;
|
||||
output->payload()[1] = 0xBE;
|
||||
output->payload()[2] = 0xAD;
|
||||
output->payload()[3] = 0xDE;
|
||||
output->payload()[4] = token & 0xFF;
|
||||
output->payload()[5] = (token >> 8) & 0xFF;
|
||||
output->payload()[6] = (token >> 16) & 0xFF;
|
||||
output->payload()[7] = (token >> 24) & 0xFF;
|
||||
sendCANFrame(output);
|
||||
bytes[0] = 0xEF;
|
||||
bytes[1] = 0xBE;
|
||||
bytes[2] = 0xAD;
|
||||
bytes[3] = 0xDE;
|
||||
bytes[4] = token & 0xFF;
|
||||
bytes[5] = (token >> 8) & 0xFF;
|
||||
bytes[6] = (token >> 16) & 0xFF;
|
||||
bytes[7] = (token >> 24) & 0xFF;
|
||||
output->setPayload(bytes);
|
||||
CANConManager::getInstance()->sendFrame(*output);
|
||||
}
|
||||
else //stop anything in process
|
||||
{
|
||||
|
||||
@@ -19,9 +19,6 @@ public:
|
||||
explicit FirmwareUploaderWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
|
||||
~FirmwareUploaderWindow();
|
||||
|
||||
signals:
|
||||
void sendCANFrame(const CANFrame *);
|
||||
|
||||
public slots:
|
||||
void gotTargettedFrame(CANFrame frame);
|
||||
|
||||
|
||||
+106
@@ -13,6 +13,19 @@
|
||||
|
||||
QFile FrameFileIO::continuousFile;
|
||||
|
||||
struct TeslaAPCANRecord
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
int64_t sec;
|
||||
int32_t nano;
|
||||
int32_t padding1;
|
||||
uint16_t id;
|
||||
uint8_t ctr;
|
||||
uint8_t data[8];
|
||||
uint8_t padding2;
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
FrameFileIO::FrameFileIO()
|
||||
{
|
||||
}
|
||||
@@ -172,6 +185,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
|
||||
filters.append(QString(tr("Generic ID/Data CSV (*.csv *.CSV)")));
|
||||
filters.append(QString(tr("Cabana Log (*.csv *.CSV)")));
|
||||
filters.append(QString(tr("CANOpen Magic (*.csv *.CSV)")));
|
||||
filters.append(QString(tr("Tesla Autopilot Snapshot (*.CAN *.can)")));
|
||||
|
||||
dialog.setDirectory(settings.value("FileIO/LoadSaveDirectory", dialog.directory().path()).toString());
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
@@ -214,6 +228,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
|
||||
if (selectedNameFilter == filters[18]) result = loadGenericCSVFile(filename, frameCache);
|
||||
if (selectedNameFilter == filters[19]) result = loadCabanaFile(filename, frameCache);
|
||||
if (selectedNameFilter == filters[20]) result = loadCANOpenFile(filename, frameCache);
|
||||
if (selectedNameFilter == filters[21]) result = loadTeslaAPFile(filename, frameCache);
|
||||
|
||||
progress.cancel();
|
||||
|
||||
@@ -264,6 +279,16 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector<CANFrame>* frames
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Attempting Tesla AP Snapshot";
|
||||
if (isTeslaAPFile(filename))
|
||||
{
|
||||
if (loadTeslaAPFile(filename, frames))
|
||||
{
|
||||
qDebug() << "Loaded as Tesla AP Snapshot successfully!";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Attempting canalyzer ASC";
|
||||
if (isCanalyzerASC(filename))
|
||||
{
|
||||
@@ -3915,3 +3940,84 @@ bool FrameFileIO::saveCabanaFile(QString filename, const QVector<CANFrame>* fram
|
||||
delete outFile;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FrameFileIO::isTeslaAPFile(QString filename)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
CANFrame thisFrame;
|
||||
QByteArray data;
|
||||
bool isValidFile = true;
|
||||
TeslaAPCANRecord record;
|
||||
|
||||
if (!inFile->open(QIODevice::ReadOnly))
|
||||
{
|
||||
delete inFile;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!inFile->atEnd())
|
||||
{
|
||||
inFile->read((char *)&record, sizeof(TeslaAPCANRecord));
|
||||
if (record.id > 0x7FF) isValidFile = false;
|
||||
if ((record.ctr >> 4) > 8) isValidFile = false;
|
||||
if ((record.ctr & 0xF) > 6) isValidFile = false;
|
||||
}
|
||||
|
||||
inFile->close();
|
||||
delete inFile;
|
||||
return isValidFile;
|
||||
}
|
||||
|
||||
bool FrameFileIO::loadTeslaAPFile(QString filename, QVector<CANFrame>* frames)
|
||||
{
|
||||
QFile *inFile = new QFile(filename);
|
||||
CANFrame thisFrame;
|
||||
int lineCounter = 0;
|
||||
QByteArray data;
|
||||
int timeOffset = 0;
|
||||
int64_t lastTimeStamp = 0;
|
||||
bool foundErrors = false;
|
||||
thisFrame.setFrameType(QCanBusFrame::DataFrame);
|
||||
TeslaAPCANRecord record;
|
||||
|
||||
if (!inFile->open(QIODevice::ReadOnly))
|
||||
{
|
||||
delete inFile;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!inFile->atEnd())
|
||||
{
|
||||
lineCounter++;
|
||||
if (lineCounter > 100)
|
||||
{
|
||||
qApp->processEvents();
|
||||
lineCounter = 0;
|
||||
}
|
||||
|
||||
inFile->read((char *)&record, sizeof(TeslaAPCANRecord));
|
||||
|
||||
thisFrame.isReceived = true;
|
||||
thisFrame.setExtendedFrameFormat(false); //format is incapable of extended frames
|
||||
thisFrame.setFrameType(QCanBusFrame::DataFrame);
|
||||
qint64 tempStamp;
|
||||
tempStamp = record.sec * 1000000 + (record.nano/1000);
|
||||
thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, tempStamp));
|
||||
thisFrame.setFrameId(record.id);
|
||||
int numBytes = (record.ctr >> 4);
|
||||
thisFrame.bus = (record.ctr & 0xF);
|
||||
QByteArray bytes(numBytes, 0);
|
||||
|
||||
if (numBytes <= 8)
|
||||
{
|
||||
for (int d = 0; d < numBytes; d++) bytes[d] = record.data[d];
|
||||
thisFrame.setPayload(bytes);
|
||||
frames->append(thisFrame);
|
||||
}
|
||||
else foundErrors = true;
|
||||
}
|
||||
|
||||
inFile->close();
|
||||
delete inFile;
|
||||
return !foundErrors;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
static bool loadCANHackerFile(QString filename, QVector<CANFrame>* frames);
|
||||
static bool loadCabanaFile(QString filename, QVector<CANFrame>* frames);
|
||||
static bool loadCANOpenFile(QString filename, QVector<CANFrame>* frames);
|
||||
static bool loadTeslaAPFile(QString filename, QVector<CANFrame>* frames);
|
||||
|
||||
//functions that pre-scan a file to try to figure out if they could read it. Used to automatically determine
|
||||
//file type and load it.
|
||||
@@ -72,6 +73,7 @@ public:
|
||||
static bool isCANHackerFile(QString filename);
|
||||
static bool isCabanaFile(QString filename);
|
||||
static bool isCANOpenFile(QString filename);
|
||||
static bool isTeslaAPFile(QString filename);
|
||||
|
||||
static bool saveCRTDFile(QString, const QVector<CANFrame>*);
|
||||
static bool saveNativeCSVFile(QString, const QVector<CANFrame>*);
|
||||
|
||||
@@ -143,7 +143,7 @@ void FramePlaybackWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("Playback/WindowSize", QSize(742, 606)).toSize());
|
||||
move(settings.value("Playback/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("Playback/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
if (settings.value("Playback/AutoLoop", false).toBool())
|
||||
{
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
#include <QtDebug>
|
||||
#include "utility.h"
|
||||
#include "helpwindow.h"
|
||||
#include "ui_helpwindow.h"
|
||||
|
||||
@@ -32,7 +33,7 @@ void HelpWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("HelpViewer/WindowSize", QSize(600, 700)).toSize());
|
||||
move(settings.value("HelpViewer/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("HelpViewer/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -324,7 +324,8 @@ void MainWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("Main/WindowSize", QSize(800, 750)).toSize());
|
||||
move(settings.value("Main/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("Main/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
|
||||
ui->canFramesView->setColumnWidth(0, settings.value("Main/TimeColumn", 150).toUInt()); //time stamp
|
||||
ui->canFramesView->setColumnWidth(1, settings.value("Main/IDColumn", 70).toUInt()); //frame ID
|
||||
ui->canFramesView->setColumnWidth(2, settings.value("Main/ExtColumn", 40).toUInt()); //extended
|
||||
|
||||
@@ -66,7 +66,7 @@ void DBCComparatorWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DBCComparator/WindowSize", QSize(720, 631)).toSize());
|
||||
move(settings.value("DBCComparator/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DBCComparator/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ void DiscreteStateWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("DiscreteState/WindowSize", QSize(400, 300)).toSize());
|
||||
move(settings.value("DiscreteState/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("DiscreteState/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ void FileComparatorWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("FileComparator/WindowSize", QSize(720, 631)).toSize());
|
||||
move(settings.value("FileComparator/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("FileComparator/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ void FlowViewWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("FlowView/WindowSize", QSize(1078, 621)).toSize());
|
||||
move(settings.value("FlowView/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("FlowView/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
|
||||
if (settings.value("FlowView/AutoRef", false).toBool())
|
||||
|
||||
@@ -170,7 +170,7 @@ void FrameInfoWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("FrameInfo/WindowSize", QSize(794, 694)).toSize());
|
||||
move(settings.value("FrameInfo/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("FrameInfo/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
useOpenGL = settings.value("Main/UseOpenGL", false).toBool();
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ void GraphingWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("Graphing/WindowSize", QSize(800, 600)).toSize());
|
||||
move(settings.value("Graphing/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("Graphing/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
secondsMode = settings.value("Main/TimeSeconds", false).toBool();
|
||||
useOpenGL = settings.value("Main/UseOpenGL", false).toBool();
|
||||
|
||||
@@ -112,7 +112,7 @@ void ISOTP_InterpreterWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("ISODecodeWindow/WindowSize", this->size()).toSize());
|
||||
move(settings.value("ISODecodeWindow/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("ISODecodeWindow/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ void RangeStateWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("RangeStateView/WindowSize", QSize(765, 615)).toSize());
|
||||
move(settings.value("RangeStateView/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("RangeStateView/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "helpwindow.h"
|
||||
#include "connections/canconmanager.h"
|
||||
#include "SnifferDelegate.h"
|
||||
#include "utility.h"
|
||||
|
||||
SnifferWindow::SnifferWindow(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
@@ -73,7 +74,7 @@ void SnifferWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("Sniffer/WindowSize", QSize(1100, 750)).toSize());
|
||||
move(settings.value("Sniffer/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("Sniffer/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
ui->treeView->setColumnWidth(0, settings.value("Sniffer/DeltaColumn", 110).toUInt());
|
||||
ui->treeView->setColumnWidth(1, settings.value("Sniffer/IDColumn", 70).toUInt());
|
||||
ui->treeView->setColumnWidth(2, settings.value("Sniffer/Data0Column", 92).toUInt());
|
||||
|
||||
@@ -91,7 +91,7 @@ void TemporalGraphWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("Temporal/WindowSize", QSize(800, 600)).toSize());
|
||||
move(settings.value("Temporal/WindowPos", QPoint(50, 50)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("Temporal/WindowPos", QPoint(50, 50)).toPoint()));
|
||||
}
|
||||
useOpenGL = settings.value("Main/UseOpenGL", false).toBool();
|
||||
}
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ void ScriptingWindow::readSettings()
|
||||
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
||||
{
|
||||
resize(settings.value("ScriptingWindow/WindowSize", QSize(860, 650)).toSize());
|
||||
move(settings.value("ScriptingWindow/WindowPos", QPoint(100, 100)).toPoint());
|
||||
move(Utility::constrainedWindowPos(settings.value("ScriptingWindow/WindowPos", QPoint(100, 100)).toPoint()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
#include <QRect>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
class Utility
|
||||
{
|
||||
@@ -16,6 +19,19 @@ public:
|
||||
static bool sysTimeMode;
|
||||
static QString timeFormat;
|
||||
|
||||
//determines whether the window position is within any available screens. If it is not we default
|
||||
//back to 0,0 which is going to be on screen. This fixes a problem where some operating systems would
|
||||
//otherwise let you put windows on a second monitor, disconnect that monitor, and still put windows on it.
|
||||
static QPoint constrainedWindowPos(QPoint originalPos)
|
||||
{
|
||||
QScreen *screen = QGuiApplication::screenAt(originalPos);
|
||||
if (!screen)
|
||||
{
|
||||
return QPoint(0,0);
|
||||
}
|
||||
return originalPos;
|
||||
}
|
||||
|
||||
static QString unQuote(QString inStr)
|
||||
{
|
||||
QStringList temp;
|
||||
|
||||
Reference in New Issue
Block a user