From 190d51ae90fab4d8de0b3f1397b910d411374df3 Mon Sep 17 00:00:00 2001 From: maciek16c Date: Wed, 22 Nov 2023 14:39:36 +0100 Subject: [PATCH 1/2] LAWICEL CAN-FD support, CAN-FD data rate selection --- SavvyCAN.pro | 2 - connections/canbus.cpp | 13 +- connections/canbus.h | 3 + connections/canconconst.h | 1 - connections/canconfactory.cpp | 7 +- connections/canconfactory.h | 2 +- connections/canconnection.cpp | 4 + connections/canconnection.h | 2 + connections/canconnectionmodel.cpp | 1 - connections/canserver.cpp | 2 +- connections/connectionwindow.cpp | 39 ++++- connections/connectionwindow.h | 2 +- connections/gvretserial.cpp | 2 +- connections/lawicel_serial.cpp | 248 +++++++++++++++++++++++----- connections/lawicel_serial.h | 6 +- connections/mqtt_bus.cpp | 2 +- connections/newconnectiondialog.cpp | 72 +++++--- connections/newconnectiondialog.h | 3 +- connections/serialbusconnection.cpp | 8 +- connections/serialbusconnection.h | 15 -- connections/socketcand.cpp | 2 +- ui/connectionwindow.ui | 12 +- ui/newconnectiondialog.ui | 24 ++- 23 files changed, 354 insertions(+), 118 deletions(-) diff --git a/SavvyCAN.pro b/SavvyCAN.pro index bfdb709..64cbc55 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -21,7 +21,6 @@ ICON = icons/SavvyIcon.icns SOURCES += main.cpp\ canbridgewindow.cpp \ - connections/canlogserver.cpp \ connections/canserver.cpp \ connections/lawicel_serial.cpp \ connections/mqtt_bus.cpp \ @@ -105,7 +104,6 @@ HEADERS += mainwindow.h \ can_structs.h \ canbridgewindow.h \ canframemodel.h \ - connections/canlogserver.h \ connections/canserver.h \ connections/lawicel_serial.h \ connections/socketcand.h \ diff --git a/connections/canbus.cpp b/connections/canbus.cpp index 8986b28..3779e86 100644 --- a/connections/canbus.cpp +++ b/connections/canbus.cpp @@ -9,6 +9,7 @@ CANBus::CANBus() singleWire = false; active = false; canFD = false; + dataRate = 2000000; } @@ -17,7 +18,8 @@ CANBus::CANBus(const CANBus& pBus) : listenOnly(pBus.listenOnly), singleWire(pBus.singleWire), active(pBus.active), - canFD(pBus.canFD) {} + canFD(pBus.canFD), + dataRate(pBus.dataRate){} bool CANBus::operator==(const CANBus& bus) const{ @@ -57,6 +59,15 @@ int CANBus::getSpeed(){ return speed; } +int CANBus::getDataRate(){ + return dataRate; +} + +void CANBus::setDataRate(int newSpeed){ + //qDebug() << "CANBUS SetSpeed = " << newSpeed; + dataRate = newSpeed; +} + bool CANBus::isListenOnly(){ return listenOnly; } diff --git a/connections/canbus.h b/connections/canbus.h index bcbe879..ff3d887 100644 --- a/connections/canbus.h +++ b/connections/canbus.h @@ -17,6 +17,7 @@ public: bool singleWire; bool active; //is this bus turned on? bool canFD; + int dataRate; void setSpeed(int); // new speed void setListenOnly(bool); //bool for whether to only listen @@ -24,6 +25,8 @@ public: void setActive(bool); //whether this bus should be enabled or not. void setCanFD(bool); // enable or disable CANFD support int getSpeed(); + int getDataRate(); + void setDataRate(int newSpeed); bool isListenOnly(); bool isSingleWire(); bool isActive(); diff --git a/connections/canconconst.h b/connections/canconconst.h index 0f7ba9c..88fa31e 100644 --- a/connections/canconconst.h +++ b/connections/canconconst.h @@ -22,7 +22,6 @@ namespace CANCon { MQTT, LAWICEL, CANSERVER, - CANLOGSERVER, NONE }; } diff --git a/connections/canconfactory.cpp b/connections/canconfactory.cpp index db93da2..5fd3035 100644 --- a/connections/canconfactory.cpp +++ b/connections/canconfactory.cpp @@ -6,11 +6,10 @@ #include "socketcand.h" #include "lawicel_serial.h" #include "canserver.h" -#include "canlogserver.h" using namespace CANCon; -CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed) +CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed, bool pCanFd, int pDataRate) { switch(pType) { case SERIALBUS: @@ -23,15 +22,13 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri case REMOTE: return new GVRetSerial(pPortName, true); //it's a special case of GVRET connected over TCP/IP so it uses the same class case LAWICEL: - return new LAWICELSerial(pPortName, pSerialSpeed, pBusSpeed); + return new LAWICELSerial(pPortName, pSerialSpeed, pBusSpeed, pCanFd, pDataRate); case KAYAK: return new SocketCANd(pPortName); case MQTT: return new MQTT_BUS(pPortName); case CANSERVER: return new CANserver(pPortName); - case CANLOGSERVER: - return new CanLogServer(pPortName); default: {} } diff --git a/connections/canconfactory.h b/connections/canconfactory.h index c23ce8b..ecf453d 100644 --- a/connections/canconfactory.h +++ b/connections/canconfactory.h @@ -7,7 +7,7 @@ class CanConFactory { public: - static CANConnection* create(CANCon::type, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed); + static CANConnection* create(CANCon::type, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed, bool pCanFd, int pDataRate); }; #endif // CANCONFACTORY_H diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index 6206045..74e4fb8 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -7,6 +7,8 @@ CANConnection::CANConnection(QString pPort, CANCon::type pType, int pSerialSpeed, int pBusSpeed, + bool pCanFd, + int pDataRate, int pNumBuses, int pQueueLen, bool pUseThread) : @@ -38,6 +40,8 @@ CANConnection::CANConnection(QString pPort, } if (pBusSpeed > 0) mBusData[0].mBus.setSpeed(pBusSpeed); + mBusData[0].mBus.setCanFD(pCanFd); + if (pDataRate > 0) mBusData[0].mBus.setDataRate(pDataRate); /* if needed, create a thread and move ourself into it */ if(pUseThread) { diff --git a/connections/canconnection.h b/connections/canconnection.h index ab53fc8..fde8296 100644 --- a/connections/canconnection.h +++ b/connections/canconnection.h @@ -32,6 +32,8 @@ protected: CANCon::type pType, int pSerialSpeed, int pBusSpeed, + bool pCanFd, + int pDataRate, int pNumBuses, int pQueueLen, bool pUseThread); diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp index c014f55..b3a5e09 100644 --- a/connections/canconnectionmodel.cpp +++ b/connections/canconnectionmodel.cpp @@ -88,7 +88,6 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const case CANCon::KAYAK: return "socketcand"; case CANCon::LAWICEL: return "LAWICEL"; case CANCon::CANSERVER: return "CANserver"; - case CANCon::CANLOGSERVER: return "CanLogServer"; default: {} } else qDebug() << "Tried to show connection type but connection was nullptr"; diff --git a/connections/canserver.cpp b/connections/canserver.cpp index e304f83..a8ad145 100644 --- a/connections/canserver.cpp +++ b/connections/canserver.cpp @@ -16,7 +16,7 @@ #include "canserver.h" CANserver::CANserver(QString serverAddressString) : - CANConnection(serverAddressString, "CANserver", CANCon::CANSERVER, 0, 0, 3, 4000, true), + CANConnection(serverAddressString, "CANserver", CANCon::CANSERVER, 0, 0, false, 0, 3, 4000, true), _udpClient(new QUdpSocket(this)), _heartbeatTimer(new QTimer(this)) { diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index e748e31..639d531 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -253,6 +253,8 @@ void ConnectionWindow::handleNewConn() QString newDriver; int newSerialSpeed; int newBusSpeed; + bool newCanFd; + int newDataRate; CANConnection *conn; if (thisDialog->exec() == QDialog::Accepted) @@ -262,7 +264,9 @@ void ConnectionWindow::handleNewConn() newDriver = thisDialog->getDriverName(); newSerialSpeed = thisDialog->getSerialSpeed(); newBusSpeed = thisDialog->getBusSpeed(); - conn = create(newType, newPort, newDriver, newSerialSpeed, newBusSpeed); + newCanFd=thisDialog->isCanFd(); + newDataRate = thisDialog->getDataRate(); + conn = create(newType, newPort, newDriver, newSerialSpeed, newBusSpeed, newCanFd, newDataRate); if (conn) { connModel->add(conn); @@ -297,7 +301,8 @@ void ConnectionWindow::handleResetConn() { QString port, driver; CANCon::type type; - int serSpeed, busSpeed; + int serSpeed, busSpeed, dataRate; + bool canFd; int selIdx = ui->tableConnections->selectionModel()->currentIndex().row(); if (selIdx <0) return; @@ -312,13 +317,16 @@ void ConnectionWindow::handleResetConn() driver = conn_p->getDriver(); serSpeed = 0; //TODO: implement these busSpeed = 0; + dataRate = 0; + canFd = false; + /* stop and delete connection */ conn_p->stop(); conn_p = nullptr; - conn_p = create(type, port, driver, serSpeed, busSpeed); + conn_p = create(type, port, driver, serSpeed, busSpeed,canFd,dataRate); if (conn_p) connModel->replace(selIdx, conn_p); } @@ -366,6 +374,7 @@ void ConnectionWindow::saveBusSettings() bus.setActive(ui->ckEnable->isChecked()); bus.setListenOnly(ui->ckListenOnly->isChecked()); bus.setCanFD(ui->canFDEnable->isChecked()); + bus.setDataRate(ui->cbDataRate->currentText().toInt()); conn_p->setBusSettings(offset, bus); } } @@ -384,6 +393,8 @@ void ConnectionWindow::populateBusDetails(int offset) //int numBuses; ui->canFDEnable->setVisible(false); ui->canFDEnable_label->setVisible(false); + ui->dataRate_label->setVisible(false); + ui->cbDataRate->setVisible(false); CANConnection* conn_p = connModel->getAtIdx(selIdx); CANBus bus; if(!conn_p) return; @@ -398,11 +409,13 @@ 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) + if (conn_p->getType() == CANCon::type::SERIALBUS || conn_p->getType() == CANCon::type::LAWICEL) { ui->canFDEnable->setVisible(true); ui->canFDEnable_label->setVisible(true); ui->canFDEnable->setChecked(bus.isCanFD()); + ui->cbDataRate->setVisible(true); + ui->dataRate_label->setVisible(true); } bool found = false; @@ -415,7 +428,19 @@ void ConnectionWindow::populateBusDetails(int offset) break; } } + if (!found) ui->cbBusSpeed->addItem(QString::number(bus.getSpeed())); + found = false; + for (int i = 0; i < ui->cbDataRate->count(); i++) + { + if (bus.getDataRate() == ui->cbDataRate->itemText(i).toInt()) + { + found = true; + ui->cbDataRate->setCurrentIndex(i); + break; + } + } + if (!found) ui->cbDataRate->addItem(QString::number(bus.getDataRate())); } } @@ -490,12 +515,12 @@ void ConnectionWindow::handleSendText() { emit sendDebugData(bytes); } -CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed) +CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed, bool pCanFd, int pDataRate) { CANConnection* conn_p; /* create connection */ - conn_p = CanConFactory::create(pTye, pPortName, pDriver, pSerialSpeed, pBusSpeed); + conn_p = CanConFactory::create(pTye, pPortName, pDriver, pSerialSpeed, pBusSpeed, pCanFd, pDataRate); if(conn_p) { /* connect signal */ @@ -533,7 +558,7 @@ void ConnectionWindow::loadConnections() for(int i = 0 ; i < portNames.count() ; i++) { //TODO: add serial speed and bus speed to this properly. - CANConnection* conn_p = create((CANCon::type)devTypes[i], portNames[i], driverNames[i], 0, 0); + CANConnection* conn_p = create((CANCon::type)devTypes[i], portNames[i], driverNames[i], 0, 0, false, 0); /* add connection to model */ connModel->add(conn_p); } diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index 9bc3076..61a94c5 100644 --- a/connections/connectionwindow.h +++ b/connections/connectionwindow.h @@ -65,7 +65,7 @@ private: QVector remoteDeviceIPGVRET; QVector remoteDeviceKayak; - CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed); + CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed, bool pCanFd, int pDataRate); void populateBusDetails(int offset); void loadConnections(); void saveConnections(); diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index e59a668..dc63ae0 100644 --- a/connections/gvretserial.cpp +++ b/connections/gvretserial.cpp @@ -9,7 +9,7 @@ #include "gvretserial.h" GVRetSerial::GVRetSerial(QString portName, bool useTcp) : - CANConnection(portName, "gvret", CANCon::GVRET_SERIAL, 0, 0, 3, 4000, true), + CANConnection(portName, "gvret", CANCon::GVRET_SERIAL, 0, 0, false, 0, 3, 4000, true), mTimer(this), /*NB: set this as parent of timer to manage it from working thread */ useTcp(useTcp) { diff --git a/connections/lawicel_serial.cpp b/connections/lawicel_serial.cpp index 7377151..0b502f8 100644 --- a/connections/lawicel_serial.cpp +++ b/connections/lawicel_serial.cpp @@ -9,8 +9,8 @@ #include "lawicel_serial.h" #include "utility.h" -LAWICELSerial::LAWICELSerial(QString portName, int serialSpeed, int lawicelSpeed) : - CANConnection(portName, "LAWICEL", CANCon::LAWICEL,serialSpeed, lawicelSpeed, 3, 4000, true), +LAWICELSerial::LAWICELSerial(QString portName, int serialSpeed, int lawicelSpeed, bool canFd, int dataRate) : + CANConnection(portName, "LAWICEL", CANCon::LAWICEL,serialSpeed, lawicelSpeed, canFd, dataRate, 3, 4000, true), mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ { sendDebug("LAWICELSerial()"); @@ -154,13 +154,31 @@ bool LAWICELSerial::piSendFrame(const CANFrame& frame) int idx = 0; QString buildStr; - if (frame.hasExtendedFrameFormat()) - { - buildStr = QString::asprintf("T%08X%u", ID, frame.payload().length()); + if(frame.hasFlexibleDataRateFormat()){ + if (frame.hasExtendedFrameFormat()) + { + if (frame.hasBitrateSwitch()) + buildStr = QString::asprintf("B%08X%u", ID, LAWICELSerial::bytes_to_dlc_code(frame.payload().length())); + else + buildStr = QString::asprintf("D%08X%u", ID, LAWICELSerial::bytes_to_dlc_code(frame.payload().length())); + } + else + { + if (frame.hasBitrateSwitch()) + buildStr = QString::asprintf("b%03X%u", ID, LAWICELSerial::bytes_to_dlc_code(frame.payload().length())); + else + buildStr = QString::asprintf("d%03X%u", ID, LAWICELSerial::bytes_to_dlc_code(frame.payload().length())); + } } - else - { - buildStr = QString::asprintf("t%03X%u", ID, frame.payload().length()); + else { + if (frame.hasExtendedFrameFormat()) + { + buildStr = QString::asprintf("T%08X%u", ID, frame.payload().length()); + } + else + { + buildStr = QString::asprintf("t%03X%u", ID, frame.payload().length()); + } } foreach (QChar chr, buildStr) { @@ -245,44 +263,71 @@ void LAWICELSerial::deviceConnected() output.clear(); output.append('S'); //configure speed of bus - switch (this->mBusData[0].mBus.getSpeed()) - { - case 10000: - output.append('0'); - break; - case 20000: - output.append('1'); - break; - case 50000: - output.append('2'); - break; - case 100000: - output.append('3'); - break; - case 125000: - output.append('4'); - break; - case 250000: - output.append('5'); - break; - case 500000: - output.append('6'); - break; - case 800000: - output.append('7'); - break; - case 1000000: - output.append('8'); - break; - default: - output.append('6'); - break; - } + switch (this->mBusData[0].mBus.getSpeed()) + { + case 10000: + output.append('0'); + break; + case 20000: + output.append('1'); + break; + case 50000: + output.append('2'); + break; + case 100000: + output.append('3'); + break; + case 125000: + output.append('4'); + break; + case 250000: + output.append('5'); + break; + case 500000: + output.append('6'); + break; + case 800000: + output.append('7'); + break; + case 1000000: + output.append('8'); + break; + default: + output.append('6'); + break; + } + output.append('\x0D'); sendToSerial(output); output.clear(); + + if (this->canFd){ + switch (this->dataRate) + { + case 1000000: + output.append("Y1"); + break; + case 2000000: + output.append("Y2"); + break; + case 4000000: + output.append("Y4"); + break; + case 5000000: + output.append("Y5"); + break; + default: + output.append("Y2"); + break; + } + + output.append('\x0D'); + sendToSerial(output); + output.clear(); + } + output.append('O'); //open bus now that we set the speed output.append(13); @@ -445,6 +490,8 @@ void LAWICELSerial::readSerialData() if (c == 13) //all lawicel commands end in CR { qDebug() << "Got CR!"; + + buildFrame.setTimeStamp(QDateTime::currentMSecsSinceEpoch() * 1000l); switch (mBuildLine[0].toLatin1()) { case 't': //standard frame @@ -502,6 +549,68 @@ void LAWICELSerial::readSerialData() qDebug() << "can't get a frame, ERROR"; } break; + case 'b': + buildFrame.setBitrateSwitch(true); //BRS enabled + case 'd': //standard fd frame, BRS disabled + //tIIILDD + buildFrame.setFlexibleDataRateFormat(true); + buildFrame.setFrameId(mBuildLine.mid(1, 3).toInt(nullptr, 16)); + buildFrame.isReceived = true; + buildFrame.setFrameType(QCanBusFrame::FrameType::DataFrame); + buildData.resize(LAWICELSerial::dlc_code_to_bytes(mBuildLine.mid(4, 1).toInt(nullptr, 16))); + for (int c = 0; c < buildData.size(); c++) + { + buildData[c] = mBuildLine.mid(5 + (c*2), 2).toInt(nullptr, 16); + } + buildFrame.setPayload(buildData); + if (!isCapSuspended()) + { + /* get frame from queue */ + CANFrame* frame_p = getQueue().get(); + if(frame_p) { + //qDebug() << "Lawicel got frame on bus " << frame_p->bus; + /* copy frame */ + *frame_p = buildFrame; + checkTargettedFrame(buildFrame); + /* enqueue frame */ + getQueue().queue(); + } + else + qDebug() << "can't get a frame, ERROR"; + } + break; + case 'B': + buildFrame.setBitrateSwitch(true); //BRS enabled + case 'D': //extended fd frame + //TIIIIIIIILDD. + buildFrame.setFlexibleDataRateFormat(true); + buildFrame.setBitrateSwitch(true); + buildFrame.setFrameId(mBuildLine.mid(1, 8).toInt(nullptr, 16)); + buildFrame.isReceived = true; + buildFrame.setFrameType(QCanBusFrame::FrameType::DataFrame); + buildFrame.setExtendedFrameFormat(true); + buildData.resize(LAWICELSerial::dlc_code_to_bytes(mBuildLine.mid(4, 1).toInt(nullptr, 16))); + for (int c = 0; c < buildData.size(); c++) + { + buildData[c] = mBuildLine.mid(10 + (c*2), 2).toInt(nullptr, 16); + } + buildFrame.setPayload(buildData); + if (!isCapSuspended()) + { + /* get frame from queue */ + CANFrame* frame_p = getQueue().get(); + if(frame_p) { + //qDebug() << "Lawicel got frame on bus " << frame_p->bus; + /* copy frame */ + *frame_p = buildFrame; + checkTargettedFrame(buildFrame); + /* enqueue frame */ + getQueue().queue(); + } + else + qDebug() << "can't get a frame, ERROR"; + } + break; } mBuildLine.clear(); } @@ -520,3 +629,60 @@ void LAWICELSerial::handleTick() //qDebug() << "Tick!"; } + +// Convert a FDCAN_data_length_code to number of bytes in a message +uint8_t LAWICELSerial::dlc_code_to_bytes(int dlc_code) +{ + if (dlc_code<=8) + return dlc_code; + else{ + switch(dlc_code) + { + case 9: + return 12; + case 10: + return 16; + case 11: + return 20; + case 12: + return 24; + case 13: + return 32; + case 14: + return 48; + case 15: + return 64; + default: + return 0; + } + } +} + +uint8_t LAWICELSerial::bytes_to_dlc_code(uint8_t bytes) +{ + if (bytes<=8) + return bytes; + else{ + switch(bytes) + { + case 12: + return 9; + case 16: + return 10; + case 20: + return 11; + case 24: + return 12; + case 32: + return 13; + case 48: + return 14; + case 64: + return 15; + default: + return 0; + } + } +} + + diff --git a/connections/lawicel_serial.h b/connections/lawicel_serial.h index 555d089..3d32a88 100644 --- a/connections/lawicel_serial.h +++ b/connections/lawicel_serial.h @@ -19,7 +19,7 @@ class LAWICELSerial : public CANConnection Q_OBJECT public: - LAWICELSerial(QString portName, int serialSpeed, int lawicelSpeed); + LAWICELSerial(QString portName, int serialSpeed, int lawicelSpeed, bool canFd, int dataRate); virtual ~LAWICELSerial(); protected: @@ -49,6 +49,8 @@ private: void rebuildLocalTimeBasis(); void sendToSerial(const QByteArray &bytes); void sendDebug(const QString debugText); + uint8_t dlc_code_to_bytes(int dlc_code); + uint8_t bytes_to_dlc_code(uint8_t bytes); protected: QTimer mTimer; @@ -61,6 +63,8 @@ protected: CANFrame buildFrame; bool can0Enabled; bool can0ListenOnly; + bool canFd; + int dataRate; }; #endif // LAWICELSERIAL_H diff --git a/connections/mqtt_bus.cpp b/connections/mqtt_bus.cpp index f8511fa..4220e34 100644 --- a/connections/mqtt_bus.cpp +++ b/connections/mqtt_bus.cpp @@ -9,7 +9,7 @@ #include "mqtt_bus.h" MQTT_BUS::MQTT_BUS(QString topicName) : - CANConnection(topicName, "mqtt_client", CANCon::MQTT, 0, 0, 1, 4000, true), + CANConnection(topicName, "mqtt_client", CANCon::MQTT, 0, 0, false, 0, 1, 4000, true), mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ { diff --git a/connections/newconnectiondialog.cpp b/connections/newconnectiondialog.cpp index a1a1916..a796b08 100644 --- a/connections/newconnectiondialog.cpp +++ b/connections/newconnectiondialog.cpp @@ -29,7 +29,6 @@ NewConnectionDialog::NewConnectionDialog(QVector* gvretips, QVectorrbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbLawicel, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbCANserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); - connect(ui->rbCanlogserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged); connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton); @@ -40,6 +39,10 @@ NewConnectionDialog::NewConnectionDialog(QVector* gvretips, QVectorcbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); + selectSerial(); qDebug() << "Was passed " << remoteDeviceIPGVRET->count() << " remote GVRET IPs"; @@ -65,7 +68,6 @@ void NewConnectionDialog::handleConnTypeChanged() if (ui->rbKayak->isChecked()) selectKayak(); if (ui->rbMQTT->isChecked()) selectMQTT(); if (ui->rbCANserver->isChecked()) selectCANserver(); - if (ui->rbCanlogserver->isChecked()) selectCANlogserver(); } void NewConnectionDialog::handleDeviceTypeChanged() @@ -89,6 +91,9 @@ void NewConnectionDialog::selectLawicel() ui->cbSerialSpeed->setHidden(false); ui->lblCANSpeed->setHidden(false); ui->lblSerialSpeed->setHidden(false); + ui->cbCanFd->setHidden(false); + ui->cbDataRate->setHidden(false); + ui->lblDataRate->setHidden(false); ui->cbPort->clear(); ports = QSerialPortInfo::availablePorts(); @@ -108,6 +113,13 @@ void NewConnectionDialog::selectLawicel() ui->cbCANSpeed->addItem("500000"); ui->cbCANSpeed->addItem("1000000"); } + if (ui->cbDataRate->count() == 0) + { + ui->cbDataRate->addItem("1000000"); + ui->cbDataRate->addItem("2000000"); + ui->cbDataRate->addItem("4000000"); + ui->cbDataRate->addItem("5000000"); + } if (ui->cbSerialSpeed->count() == 0) { ui->cbSerialSpeed->addItem("115200"); @@ -130,6 +142,9 @@ void NewConnectionDialog::selectSerial() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbPort->clear(); ports = QSerialPortInfo::availablePorts(); @@ -147,6 +162,9 @@ void NewConnectionDialog::selectSocketCan() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbDeviceType->clear(); QStringList plugins; @@ -166,6 +184,9 @@ void NewConnectionDialog::selectRemote() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbPort->clear(); foreach(QString pName, *remoteDeviceIPGVRET) @@ -184,6 +205,9 @@ void NewConnectionDialog::selectKayak() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbPort->clear(); foreach(QString pName, *remoteBusKayak) @@ -202,6 +226,9 @@ void NewConnectionDialog::selectMQTT() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbPort->clear(); } @@ -216,20 +243,9 @@ void NewConnectionDialog::selectCANserver() ui->cbSerialSpeed->setHidden(true); ui->lblCANSpeed->setHidden(true); ui->lblSerialSpeed->setHidden(true); - - ui->cbPort->clear(); -} - -void NewConnectionDialog::selectCANlogserver() -{ - ui->lPort->setText("CANlogserver IP Address:"); - - ui->lblDeviceType->setHidden(true); - ui->cbDeviceType->setHidden(true); - ui->cbCANSpeed->setHidden(true); - ui->cbSerialSpeed->setHidden(true); - ui->lblCANSpeed->setHidden(true); - ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); ui->cbPort->clear(); } @@ -260,9 +276,6 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt case CANCon::CANSERVER: ui->rbCANserver->setChecked(true); break; - case CANCon::CANLOGSERVER: - ui->rbCanlogserver->setChecked(true); - break; default: {} } @@ -307,7 +320,6 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt ui->cbPort->setCurrentText(pPortName); break; case CANCon::CANSERVER: - case CANCon::CANLOGSERVER: { ui->cbPort->setCurrentText(pPortName); break; @@ -328,7 +340,6 @@ QString NewConnectionDialog::getPortName() case CANCon::KAYAK: return ui->cbPort->currentText(); case CANCon::CANSERVER: - case CANCon::CANLOGSERVER: return ui->cbPort->currentText(); default: @@ -374,7 +385,6 @@ CANCon::type NewConnectionDialog::getConnectionType() if (ui->rbMQTT->isChecked()) return CANCon::MQTT; if (ui->rbLawicel->isChecked()) return CANCon::LAWICEL; if (ui->rbCANserver->isChecked()) return CANCon::CANSERVER; - if (ui->rbCanlogserver->isChecked()) return CANCon::CANLOGSERVER; qDebug() << "getConnectionType: error"; return CANCon::NONE; @@ -385,3 +395,21 @@ bool NewConnectionDialog::isSerialBusAvailable() if (QCanBus::instance()->plugins().count() > 0) return true; return false; } + +int NewConnectionDialog::getDataRate() +{ + if (getConnectionType() == CANCon::LAWICEL) + { + return ui->cbDataRate->currentText().toInt(); + } + else return 0; +} + +bool NewConnectionDialog::isCanFd() + { + if (getConnectionType() == CANCon::LAWICEL) + { + return ui->cbCanFd; + } + else return 0; + } diff --git a/connections/newconnectiondialog.h b/connections/newconnectiondialog.h index 95dd2b8..e48636f 100644 --- a/connections/newconnectiondialog.h +++ b/connections/newconnectiondialog.h @@ -26,6 +26,8 @@ public: QString getDriverName(); int getSerialSpeed(); int getBusSpeed(); + bool isCanFd(); + int getDataRate(); public slots: void handleConnTypeChanged(); @@ -47,7 +49,6 @@ private: void selectMQTT(); void selectLawicel(); void selectCANserver(); - void selectCANlogserver(); bool isSerialBusAvailable(); void setPortName(CANCon::type pType, QString pPortName, QString pDriver); }; diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index a8809fd..9f9be82 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -12,7 +12,7 @@ /***********************************/ SerialBusConnection::SerialBusConnection(QString portName, QString driverName) : - CANConnection(portName, driverName, CANCon::SERIALBUS,0 ,0 ,1, 4000, true), + CANConnection(portName, driverName, CANCon::SERIALBUS,0 ,0, false, 0 ,1, 4000, true), mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */ { } @@ -78,8 +78,6 @@ bool SerialBusConnection::piGetBusSettings(int pBusIdx, CANBus& pBus) void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) { - quint32 sbusconfig = 0; - //CANConStatus stats; /* sanity checks */ if(0 != pBusIdx) @@ -108,10 +106,6 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) mDev_p->setConfigurationParameter(QCanBusDevice::BitRateKey, bus.speed); mDev_p->setConfigurationParameter(QCanBusDevice::CanFdKey, bus.canFD); - if(bus.listenOnly) - sbusconfig |= EN_SILENT_MODE; - mDev_p->setConfigurationParameter(QCanBusDevice::UserKey, sbusconfig); - /* connect device */ if (!mDev_p->connectDevice()) { disconnectDevice(); diff --git a/connections/serialbusconnection.h b/connections/serialbusconnection.h index f65be43..e430ebd 100644 --- a/connections/serialbusconnection.h +++ b/connections/serialbusconnection.h @@ -7,21 +7,6 @@ #include #include -/* -QCanBusDevice::UserKey -0x00000001 - enable silent mode -0x00000002 - enable loopback mode -0x00000004 - disable auto retransmissions -0x00000008 - enable terminator -0x00000010 - enable automatic bus off recovery -*/ - -#define EN_SILENT_MODE 0x00000001 -#define EN_LOOPBACK_MODE 0x00000002 -#define DIS_AUTO_RETRANSMISSIONS 0x00000004 -#define EN_TERMINATOR 0x00000008 -#define EN_AUTOMATIC_BUSOFF_RECOVERY 0x00000010 - class SerialBusConnection : public CANConnection { Q_OBJECT diff --git a/connections/socketcand.cpp b/connections/socketcand.cpp index 1467d01..83fb144 100644 --- a/connections/socketcand.cpp +++ b/connections/socketcand.cpp @@ -10,7 +10,7 @@ #include "socketcand.h" SocketCANd::SocketCANd(QString portName) : - CANConnection(portName, "kayak", CANCon::KAYAK, 0, 0, 1, 4000, true), + CANConnection(portName, "kayak", CANCon::KAYAK, 0, 0, false, 0, 1, 4000, true), mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ { diff --git a/ui/connectionwindow.ui b/ui/connectionwindow.ui index 6dd573d..4f94395 100644 --- a/ui/connectionwindow.ui +++ b/ui/connectionwindow.ui @@ -104,7 +104,7 @@ - + Save Bus Settings @@ -121,6 +121,16 @@ + + + + + + + CAN FD Data Rate + + + diff --git a/ui/newconnectiondialog.ui b/ui/newconnectiondialog.ui index 46d9123..d03d701 100644 --- a/ui/newconnectiondialog.ui +++ b/ui/newconnectiondialog.ui @@ -78,13 +78,6 @@ - - - - CANlogserver - - - @@ -150,6 +143,23 @@ + + + + CAN-FD + + + + + + + CAN-FD data rate + + + + + + From 2bf078294637d58931fe24370e303fd5169a058b Mon Sep 17 00:00:00 2001 From: maciek16c Date: Wed, 22 Nov 2023 15:23:38 +0100 Subject: [PATCH 2/2] CAN-FD --- SavvyCAN.pro | 2 ++ connections/canconconst.h | 1 + connections/canconfactory.cpp | 3 +++ connections/canconnectionmodel.cpp | 1 + connections/canlogserver.cpp | 2 +- connections/newconnectiondialog.cpp | 25 +++++++++++++++++++++++++ connections/newconnectiondialog.h | 1 + connections/serialbusconnection.cpp | 6 ++++++ connections/serialbusconnection.h | 15 +++++++++++++++ ui/newconnectiondialog.ui | 7 +++++++ 10 files changed, 62 insertions(+), 1 deletion(-) diff --git a/SavvyCAN.pro b/SavvyCAN.pro index 64cbc55..bfdb709 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -21,6 +21,7 @@ ICON = icons/SavvyIcon.icns SOURCES += main.cpp\ canbridgewindow.cpp \ + connections/canlogserver.cpp \ connections/canserver.cpp \ connections/lawicel_serial.cpp \ connections/mqtt_bus.cpp \ @@ -104,6 +105,7 @@ HEADERS += mainwindow.h \ can_structs.h \ canbridgewindow.h \ canframemodel.h \ + connections/canlogserver.h \ connections/canserver.h \ connections/lawicel_serial.h \ connections/socketcand.h \ diff --git a/connections/canconconst.h b/connections/canconconst.h index 88fa31e..0f7ba9c 100644 --- a/connections/canconconst.h +++ b/connections/canconconst.h @@ -22,6 +22,7 @@ namespace CANCon { MQTT, LAWICEL, CANSERVER, + CANLOGSERVER, NONE }; } diff --git a/connections/canconfactory.cpp b/connections/canconfactory.cpp index 5fd3035..ae2bc6b 100644 --- a/connections/canconfactory.cpp +++ b/connections/canconfactory.cpp @@ -6,6 +6,7 @@ #include "socketcand.h" #include "lawicel_serial.h" #include "canserver.h" +#include "canlogserver.h" using namespace CANCon; @@ -29,6 +30,8 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri return new MQTT_BUS(pPortName); case CANSERVER: return new CANserver(pPortName); + case CANLOGSERVER: + return new CanLogServer(pPortName); default: {} } diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp index b3a5e09..c014f55 100644 --- a/connections/canconnectionmodel.cpp +++ b/connections/canconnectionmodel.cpp @@ -88,6 +88,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const case CANCon::KAYAK: return "socketcand"; case CANCon::LAWICEL: return "LAWICEL"; case CANCon::CANSERVER: return "CANserver"; + case CANCon::CANLOGSERVER: return "CanLogServer"; default: {} } else qDebug() << "Tried to show connection type but connection was nullptr"; diff --git a/connections/canlogserver.cpp b/connections/canlogserver.cpp index 8ddc5b0..78a2bc5 100644 --- a/connections/canlogserver.cpp +++ b/connections/canlogserver.cpp @@ -9,7 +9,7 @@ #include "canlogserver.h" CanLogServer::CanLogServer(QString serverAddressString) : - CANConnection(serverAddressString, "CanLogserver", CANCon::CANLOGSERVER, 0, 0, 1, 4000, true), + CANConnection(serverAddressString, "CanLogserver", CANCon::CANLOGSERVER, 0, 0, false, 0, 1, 4000, true), m_ptcpSocket(new QTcpSocket(this)) { diff --git a/connections/newconnectiondialog.cpp b/connections/newconnectiondialog.cpp index a796b08..134e182 100644 --- a/connections/newconnectiondialog.cpp +++ b/connections/newconnectiondialog.cpp @@ -29,6 +29,7 @@ NewConnectionDialog::NewConnectionDialog(QVector* gvretips, QVectorrbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbLawicel, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbCANserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); + connect(ui->rbCanlogserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged); connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton); @@ -68,6 +69,7 @@ void NewConnectionDialog::handleConnTypeChanged() if (ui->rbKayak->isChecked()) selectKayak(); if (ui->rbMQTT->isChecked()) selectMQTT(); if (ui->rbCANserver->isChecked()) selectCANserver(); + if (ui->rbCanlogserver->isChecked()) selectCANlogserver(); } void NewConnectionDialog::handleDeviceTypeChanged() @@ -250,6 +252,23 @@ void NewConnectionDialog::selectCANserver() ui->cbPort->clear(); } +void NewConnectionDialog::selectCANlogserver() +{ + ui->lPort->setText("CANlogserver IP Address:"); + + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); + ui->cbCANSpeed->setHidden(true); + ui->cbSerialSpeed->setHidden(true); + ui->lblCANSpeed->setHidden(true); + ui->lblSerialSpeed->setHidden(true); + ui->cbCanFd->setHidden(true); + ui->cbDataRate->setHidden(true); + ui->lblDataRate->setHidden(true); + + ui->cbPort->clear(); +} + void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QString pDriver) { @@ -276,6 +295,9 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt case CANCon::CANSERVER: ui->rbCANserver->setChecked(true); break; + case CANCon::CANLOGSERVER: + ui->rbCanlogserver->setChecked(true); + break; default: {} } @@ -320,6 +342,7 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt ui->cbPort->setCurrentText(pPortName); break; case CANCon::CANSERVER: + case CANCon::CANLOGSERVER: { ui->cbPort->setCurrentText(pPortName); break; @@ -340,6 +363,7 @@ QString NewConnectionDialog::getPortName() case CANCon::KAYAK: return ui->cbPort->currentText(); case CANCon::CANSERVER: + case CANCon::CANLOGSERVER: return ui->cbPort->currentText(); default: @@ -385,6 +409,7 @@ CANCon::type NewConnectionDialog::getConnectionType() if (ui->rbMQTT->isChecked()) return CANCon::MQTT; if (ui->rbLawicel->isChecked()) return CANCon::LAWICEL; if (ui->rbCANserver->isChecked()) return CANCon::CANSERVER; + if (ui->rbCanlogserver->isChecked()) return CANCon::CANLOGSERVER; qDebug() << "getConnectionType: error"; return CANCon::NONE; diff --git a/connections/newconnectiondialog.h b/connections/newconnectiondialog.h index e48636f..387a4fb 100644 --- a/connections/newconnectiondialog.h +++ b/connections/newconnectiondialog.h @@ -49,6 +49,7 @@ private: void selectMQTT(); void selectLawicel(); void selectCANserver(); + void selectCANlogserver(); bool isSerialBusAvailable(); void setPortName(CANCon::type pType, QString pPortName, QString pDriver); }; diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index 9f9be82..a5ec860 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -78,6 +78,8 @@ bool SerialBusConnection::piGetBusSettings(int pBusIdx, CANBus& pBus) void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) { + quint32 sbusconfig = 0; + //CANConStatus stats; /* sanity checks */ if(0 != pBusIdx) @@ -106,6 +108,10 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) mDev_p->setConfigurationParameter(QCanBusDevice::BitRateKey, bus.speed); mDev_p->setConfigurationParameter(QCanBusDevice::CanFdKey, bus.canFD); + if(bus.listenOnly) + sbusconfig |= EN_SILENT_MODE; + mDev_p->setConfigurationParameter(QCanBusDevice::UserKey, sbusconfig); + /* connect device */ if (!mDev_p->connectDevice()) { disconnectDevice(); diff --git a/connections/serialbusconnection.h b/connections/serialbusconnection.h index e430ebd..f65be43 100644 --- a/connections/serialbusconnection.h +++ b/connections/serialbusconnection.h @@ -7,6 +7,21 @@ #include #include +/* +QCanBusDevice::UserKey +0x00000001 - enable silent mode +0x00000002 - enable loopback mode +0x00000004 - disable auto retransmissions +0x00000008 - enable terminator +0x00000010 - enable automatic bus off recovery +*/ + +#define EN_SILENT_MODE 0x00000001 +#define EN_LOOPBACK_MODE 0x00000002 +#define DIS_AUTO_RETRANSMISSIONS 0x00000004 +#define EN_TERMINATOR 0x00000008 +#define EN_AUTOMATIC_BUSOFF_RECOVERY 0x00000010 + class SerialBusConnection : public CANConnection { Q_OBJECT diff --git a/ui/newconnectiondialog.ui b/ui/newconnectiondialog.ui index d03d701..e459583 100644 --- a/ui/newconnectiondialog.ui +++ b/ui/newconnectiondialog.ui @@ -78,6 +78,13 @@ + + + + CANlogserver + + +