diff --git a/connections/canbus.cpp b/connections/canbus.cpp index 24238f7..97acc05 100644 --- a/connections/canbus.cpp +++ b/connections/canbus.cpp @@ -8,6 +8,7 @@ CANBus::CANBus() listenOnly = false; singleWire = false; active = false; + canFD = false; } @@ -15,14 +16,16 @@ CANBus::CANBus(const CANBus& pBus) : speed(pBus.speed), listenOnly(pBus.listenOnly), singleWire(pBus.singleWire), - active(pBus.active) {} + active(pBus.active), + canFD(pBus.canFD) {} bool CANBus::operator==(const CANBus& bus) const{ return speed == bus.speed && listenOnly == bus.listenOnly && singleWire == bus.singleWire && - active == bus.active; + active == bus.active && + canFD == bus.canFD; } void CANBus::setSpeed(int newSpeed){ @@ -45,6 +48,11 @@ void CANBus::setActive(bool mode){ active = mode; } +void CANBus::setCanFD(bool mode){ + //qDebug() << "CANBUS setCanFD = " << mode; + canFD = mode; +} + int CANBus::getSpeed(){ return speed; } @@ -61,6 +69,10 @@ bool CANBus::isActive(){ return active; } +bool CANBus::isCanFD(){ + return canFD; +} + QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus ) { diff --git a/connections/canbus.h b/connections/canbus.h index b127059..bcbe879 100644 --- a/connections/canbus.h +++ b/connections/canbus.h @@ -16,16 +16,18 @@ public: bool listenOnly; bool singleWire; bool active; //is this bus turned on? - + bool canFD; void setSpeed(int); // new speed void setListenOnly(bool); //bool for whether to only listen void setSingleWire(bool); //bool for whether to use single wire mode void setActive(bool); //whether this bus should be enabled or not. + void setCanFD(bool); // enable or disable CANFD support int getSpeed(); bool isListenOnly(); bool isSingleWire(); bool isActive(); + bool isCanFD(); }; QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus ); diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index d29ebd9..7695442 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -365,6 +365,7 @@ void ConnectionWindow::saveBusSettings() bus.setSpeed(ui->cbBusSpeed->currentText().toInt()); bus.setActive(ui->ckEnable->isChecked()); bus.setListenOnly(ui->ckListenOnly->isChecked()); + bus.setCanFD(ui->canFDEnable->isChecked()); conn_p->setBusSettings(offset, bus); } } @@ -381,7 +382,8 @@ void ConnectionWindow::populateBusDetails(int offset) { //bool ret; //int numBuses; - + ui->canFDEnable->setVisible(false); + ui->canFDEnable_label->setVisible(false); CANConnection* conn_p = connModel->getAtIdx(selIdx); CANBus bus; if(!conn_p) return; @@ -396,6 +398,12 @@ void ConnectionWindow::populateBusDetails(int offset) //ui->lblBusNum->setText(QString::number(busBase + offset)); ui->ckListenOnly->setChecked(bus.isListenOnly()); ui->ckEnable->setChecked(bus.isActive()); + if (conn_p->getType() == CANCon::type::SERIALBUS) + { + ui->canFDEnable->setVisible(true); + ui->canFDEnable_label->setVisible(true); + ui->canFDEnable->setChecked(bus.isCanFD()); + } bool found = false; for (int i = 0; i < ui->cbBusSpeed->count(); i++) diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index b1a2f6e..addaf21 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -47,6 +47,7 @@ void SerialBusConnection::piStarted() mTimer.setSingleShot(false); //keep ticking mTimer.start(); mBusData[0].mBus.setActive(true); + mBusData[0].mBus.setCanFD(false); mBusData[0].mConfigured = true; } @@ -103,6 +104,7 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) //You cannot set the speed of a socketcan interface, it has to be set with console commands. //But, you can probabaly set the speed of many of the other serialbus devices so go ahead and try mDev_p->setConfigurationParameter(QCanBusDevice::BitRateKey, bus.speed); + mDev_p->setConfigurationParameter(QCanBusDevice::CanFdKey, bus.canFD); /* connect device */ if (!mDev_p->connectDevice()) { diff --git a/connections/socketcand.cpp b/connections/socketcand.cpp index a049d8c..abb5ceb 100644 --- a/connections/socketcand.cpp +++ b/connections/socketcand.cpp @@ -288,18 +288,13 @@ QString SocketCANd::decodeFrames(QString data, int busNum) buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, frameParsed[2].toDouble() * 1000000l)); //buildFrame.len = frameParsed[3].length() * 0.5; - if(frameParsed.length() < 4) + int framelength = 0; + + if(frameParsed.length() == 4) { - qDebug() << "Received frame doesn't contain any data: " << data; - - //todo - //this is not totally true, ive seen frames come through that look like < frame 1F020240 1664924225.371291 > - //if we found the closing token but theres no data then remove the message from the buffer - return data; + framelength = frameParsed[3].length() * 0.5; } - int framelength = frameParsed[3].length() * 0.5; - buildData.resize(framelength); int c; @@ -326,8 +321,8 @@ QString SocketCANd::decodeFrames(QString data, int busNum) getQueue().queue(); } } - else - qDebug() << "can't get a frame, capture suspended"; + //else + // qDebug() << "can't get a frame, capture suspended"; //take out the data that we just processed and anything that is in front of it //this should keep broken frames from accumulating at in the data buffer diff --git a/mainwindow.cpp b/mainwindow.cpp index e84da30..dde7691 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -119,6 +119,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->actionFuzzy_Scope, &QAction::triggered, this, &MainWindow::showFuzzyScopeWindow); connect(ui->actionRange_State_2, &QAction::triggered, this, &MainWindow::showRangeWindow); connect(ui->actionSave_Decoded_Frames, &QAction::triggered, this, &MainWindow::handleSaveDecoded); + connect(ui->actionSave_Decoded_Frames_CSV, &QAction::triggered, this, &MainWindow::handleSaveDecodedCsv); connect(ui->actionSingle_Multi_State_2, &QAction::triggered, this, &MainWindow::showSingleMultiWindow); connect(ui->actionFile_Comparison, &QAction::triggered, this, &MainWindow::showComparisonWindow); connect(ui->actionDBC_Comparison, &QAction::triggered, this, &MainWindow::showDBCComparisonWindow); @@ -988,6 +989,16 @@ void MainWindow::handleLoadFilters() } void MainWindow::handleSaveDecoded() +{ + handleSaveDecodedMethod(false); +} + +void MainWindow::handleSaveDecodedCsv() +{ + handleSaveDecodedMethod(true); +} + +void MainWindow::handleSaveDecodedMethod(bool csv) { QString filename; QFileDialog dialog(this); @@ -1006,11 +1017,172 @@ void MainWindow::handleSaveDecoded() { filename = dialog.selectedFiles()[0]; if (!filename.contains('.')) filename += ".txt"; - saveDecodedTextFile(filename); + + if(csv) + saveDecodedTextFileAsColumns(filename); + else + saveDecodedTextFile(filename); + settings.setValue("FileIO/LoadSaveDirectory", dialog.directory().path()); } } +void MainWindow::saveDecodedTextFileAsColumns(QString filename) +{ + QFile *outFile = new QFile(filename); + const QVector *frames = model->getFilteredListReference(); + + const unsigned char *data; + int dataLen; + const CANFrame *frame; + + if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text)) + return; +/* +Time: 205.173000 ID: 0x20E Std Bus: 0 Len: 8 +Data Bytes: 88 10 00 13 BB 00 06 00 + SignalName Value +*/ + QList> msgsAndColumns; + int columnsAdded = 0; + int dataStartCol = 0; + + QString builderString; + //time + builderString += tr("Time") + ","; + dataStartCol++; + //id + builderString += tr("ID") + ","; + dataStartCol++; + //if (frame->hasExtendedFrameFormat()) builderString += tr(" Ext "); + //else builderString += tr(" Std "); + //bus + builderString += tr("Bus") + ","; + dataStartCol++; + //len + builderString += tr("DataLen") + ","; + dataStartCol++; + + columnsAdded = dataStartCol; + + //loop through all the frames and the message data therein + for (int c = 0; c < frames->count(); c++) + { + frame = &frames->at(c); + data = reinterpret_cast(frame->payload().constData()); + dataLen = frame->payload().count(); + + //add all column names + if (dbcHandler != nullptr) + { + DBC_MESSAGE *msg = dbcHandler->findMessage(*frame); + if (msg != nullptr) + { + bool found = false; + for (int j = 0; j < msg->sigHandler->getCount(); j++) + { + if(j==0) + { + for(int m=0; mID) + found = true; + } + if(found == false) + msgsAndColumns.append(QPair(msg->ID, columnsAdded)); + } + + if(found == false) + { + QString temp; + if (msg->sigHandler->findSignalByIdx(j)->processAsText(*frame, temp)) + { + builderString.append(msg->sigHandler->findSignalByIdx(j)->name); + builderString.append(","); + columnsAdded++; + } + } + } + } + } + } + + //add EOL + builderString += "\n"; + //write out the header row + outFile->write(builderString.toUtf8()); + + //builderString = tr("Data Bytes: "); + //for (int temp = 0; temp < dataLen; temp++) + //{ + // builderString += Utility::formatNumber(data[temp]) + " "; + //} + //builderString += "\n"; + //outFile->write(builderString.toUtf8()); + + int dataColumnsAdded = 0; + builderString = ""; + for (int c = 0; c < frames->count(); c++) + { + dataColumnsAdded = 0; + frame = &frames->at(c); + data = reinterpret_cast(frame->payload().constData()); + dataLen = frame->payload().count(); + + QString builderString; + builderString += QString::number((frame->timeStamp().microSeconds() / 1000000.0), 'f', 6) + ","; + dataColumnsAdded++; + //id + builderString += Utility::formatCANID(frame->frameId(), frame->hasExtendedFrameFormat()) + ","; + dataColumnsAdded++; + //if (frame->hasExtendedFrameFormat()) builderString += tr(" Ext "); + //else builderString += tr(" Std "); + //bus + builderString += QString::number(frame->bus) + ","; + dataColumnsAdded++; + //len + builderString += QString::number(dataLen) + ","; + dataColumnsAdded++; + + if (dbcHandler != nullptr) + { + DBC_MESSAGE *msg = dbcHandler->findMessage(*frame); + if (msg != nullptr) + { + for (int j = 0; j < msg->sigHandler->getCount(); j++) + { + if(j==0) + { + for(int i = 0; iID) + { + int startCol = msgsAndColumns[i].second; + while(dataColumnsAdded < startCol) + { + builderString += ","; + dataColumnsAdded++; + } + } + } + } + + QString temp; + if (msg->sigHandler->findSignalByIdx(j)->processAsText(*frame, temp, false)) + { + builderString.append(temp); + builderString.append(","); + dataColumnsAdded++; + } + } + } + builderString.append("\n"); + outFile->write(builderString.toUtf8()); + } + } + outFile->close(); +} + void MainWindow::saveDecodedTextFile(QString filename) { QFile *outFile = new QFile(filename); diff --git a/mainwindow.h b/mainwindow.h index 9967215..64b8cdf 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -91,6 +91,7 @@ private slots: void showDBCComparisonWindow(); void exitApp(); void handleSaveDecoded(); + void handleSaveDecodedCsv(); void connectionStatusUpdated(int conns); void gridClicked(QModelIndex); void gridDoubleClicked(QModelIndex); @@ -195,7 +196,9 @@ private: //private methods QString getSignalNameFromPosition(QPoint pos); uint32_t getMessageIDFromPosition(QPoint pos); + void handleSaveDecodedMethod(bool csv); void saveDecodedTextFile(QString); + void saveDecodedTextFileAsColumns(QString); void addFrameToDisplay(CANFrame &, bool); void updateFileStatus(); void closeEvent(QCloseEvent *event); diff --git a/re/graphingwindow.cpp b/re/graphingwindow.cpp index 44b10bc..30c67e9 100644 --- a/re/graphingwindow.cpp +++ b/re/graphingwindow.cpp @@ -136,7 +136,7 @@ void GraphingWindow::changeEvent(QEvent *event) } else { - setWindowOpacity(0.25); + //setWindowOpacity(0.25); // widget is now inactive qDebug() << "Hide"; } @@ -199,7 +199,7 @@ void GraphingWindow::updatedFrames(int numFrames) ui->graphingView->replot(); //now, redisplay them all } else //just got some new frames. See if they are relevant. - { + { if (numFrames > modelFrames->count()) return; for (int j = 0; j < graphParams.count(); j++) diff --git a/ui/connectionwindow.ui b/ui/connectionwindow.ui index 0cf7ea4..6dd573d 100644 --- a/ui/connectionwindow.ui +++ b/ui/connectionwindow.ui @@ -64,9 +64,6 @@ Qt::AlignCenter - - - @@ -107,15 +104,28 @@ - + Save Bus Settings + + + + + + + Enable CAN FD: + + + + + + diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 77e1b5a..0136c80 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -368,7 +368,7 @@ 0 0 800 - 22 + 21 @@ -415,6 +415,7 @@ + @@ -615,6 +616,11 @@ DBC Comparison + + + Save Decoded Frames CSV + +