Skip to content

Commit

Permalink
Merge branch 'master' of github.com:collin80/SavvyCAN into QT6WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
collin80 committed May 1, 2024
2 parents f3ea2c6 + 0447ec1 commit 7587dd7
Show file tree
Hide file tree
Showing 30 changed files with 1,551 additions and 606 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ Makefile
SavvyCAN.pro.qtds
.xcode
SavvyCAN.xcodeproj
.vscode
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SavvyCAN
Qt based cross platform canbus tool
(C) 2015-2021 EVTV and Collin Kidder
(C) 2015-2024 Collin Kidder

A Qt5 based cross platform tool which can be used to load, save, and capture canbus frames.
This tool is designed to help with visualization, reverse engineering, debugging, and
Expand All @@ -17,9 +17,6 @@ The CANDue board must be running the GVRET firmware which can also be found
within the collin80 repos.

It is now possible to use any Qt SerialBus driver (socketcan, Vector, PeakCAN, TinyCAN).
There may, however, be some loss of some functionality as
some functions of SavvyCAN are designed for use directly with the
EVTVDue and CANDue 2.0 boards.

It should, however, be noted that use of a capture device is not required to make use
of this program. It can load and save in several formats:
Expand Down Expand Up @@ -50,8 +47,9 @@ to download it separately.

This project requires 5.14.0 or higher because of a dependency on QtSerialBus and other new additions to Qt.

NOTE: Qt6 currently lacks support for QtSerialBus and many other Qt sub-features. At this time you cannot
use Qt6 to compile SavvyCAN. Support for Qt6 should be possible around Qt6.2.
NOTE: As the code in this master branch sits, it will not properly compile with QT6.
However, there is a QT6WIP branch that should successfully compile. The QT6WIP branch may not
function entirely properly yet.

## Instructions for compiling:

Expand Down
4 changes: 3 additions & 1 deletion SavvyCAN.pro
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ QT = core gui printsupport qml serialbus serialport widgets help network opengl

CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT

CONFIG += c++11
CONFIG += c++17
CONFIG += NO_UNIT_TESTS

DEFINES += QCUSTOMPLOT_USE_OPENGL
Expand All @@ -26,6 +26,7 @@ SOURCES += main.cpp\
connections/lawicel_serial.cpp \
connections/mqtt_bus.cpp \
dbc/dbcnodeduplicateeditor.cpp \
framesenderobject.cpp \
mqtt/qmqtt_client.cpp \
mqtt/qmqtt_client_p.cpp \
mqtt/qmqtt_frame.cpp \
Expand Down Expand Up @@ -113,6 +114,7 @@ HEADERS += mainwindow.h \
connections/mqtt_bus.h \
dbc/dbcnodeduplicateeditor.h \
dbc/dbcnoderebaseeditor.h \
framesenderobject.h \
mqtt/qmqtt.h \
mqtt/qmqtt_client.h \
mqtt/qmqtt_client_p.h \
Expand Down
6 changes: 5 additions & 1 deletion can_trigger_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "can_structs.h"

#include <QList>
#include <QUuid>

enum TriggerMask
{
Expand Down Expand Up @@ -38,13 +39,15 @@ class Trigger
//If ID is -1 then this is the temporary storage register. This is a shadow
//register used to accumulate the results of a multi operation modifier.
//if ID is -2 then this is a look up of our own data bytes stored in the class data.
//Of course, if the ID is positive then we grab bytes or signals from newest message with that ID
class ModifierOperand
{
public:
int ID;
int bus;
int databyte;
bool notOper; //should a bitwise NOT be applied to this prior to doing the actual calculation?
QString signalName; //if ID is positive and there is text in here then we'll look up the signal and use its value
};

//list of operations that can be done between the two operands
Expand Down Expand Up @@ -73,7 +76,8 @@ class ModifierOp
class Modifier
{
public:
int destByte;
int destByte; //if -1 then target one of this ID's signals instead
QString signalName;
QList<ModifierOp> operations;
};

Expand Down
27 changes: 10 additions & 17 deletions connections/canbus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,13 @@ CANBus::CANBus()
}


CANBus::CANBus(const CANBus& pBus) :
speed(pBus.speed),
listenOnly(pBus.listenOnly),
singleWire(pBus.singleWire),
active(pBus.active),
canFD(pBus.canFD),
dataRate(pBus.dataRate){}


bool CANBus::operator==(const CANBus& bus) const{
return speed == bus.speed &&
listenOnly == bus.listenOnly &&
singleWire == bus.singleWire &&
active == bus.active &&
canFD == bus.canFD;
canFD == bus.canFD &&
dataRate == bus.dataRate;
}

void CANBus::setSpeed(int newSpeed){
Expand Down Expand Up @@ -55,11 +47,11 @@ void CANBus::setCanFD(bool mode){
canFD = mode;
}

int CANBus::getSpeed(){
int CANBus::getSpeed() const {
return speed;
}

int CANBus::getDataRate(){
int CANBus::getDataRate() const {
return dataRate;
}

Expand All @@ -68,29 +60,30 @@ void CANBus::setDataRate(int newSpeed){
dataRate = newSpeed;
}

bool CANBus::isListenOnly(){
bool CANBus::isListenOnly() const {
return listenOnly;
}

bool CANBus::isSingleWire(){
bool CANBus::isSingleWire() const {
return singleWire;
}

bool CANBus::isActive(){
bool CANBus::isActive() const {
return active;
}

bool CANBus::isCanFD(){
bool CANBus::isCanFD() const {
return canFD;
}


QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus )
QDataStream& operator<<(QDataStream & pStream, const CANBus& pCanBus)
{
pStream << pCanBus.speed;
pStream << pCanBus.listenOnly;
pStream << pCanBus.singleWire;
pStream << pCanBus.active;
// FIXME CANFD settings missing
return pStream;
}

Expand Down
33 changes: 17 additions & 16 deletions connections/canbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,43 @@

class CANBus
{
public:
CANBus();
CANBus(const CANBus&);
bool operator==(const CANBus&) const;
CANBus& operator=(const CANBus& other) = default;
//virtual ~CANBus(){}

int speed;
bool listenOnly;
bool singleWire;
bool active; //is this bus turned on?
bool canFD;
int dataRate;

friend QDataStream& operator<<(QDataStream & pStream, const CANBus& pCanBus);
friend QDataStream& operator>>(QDataStream & pStream, CANBus& pCanBus);
public:
CANBus();

bool operator==(const CANBus&) const;

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();
int getDataRate();
void setDataRate(int newSpeed);
bool isListenOnly();
bool isSingleWire();
bool isActive();
bool isCanFD();

int getSpeed() const;
int getDataRate() const;
bool isListenOnly() const;
bool isSingleWire() const;
bool isActive() const;
bool isCanFD() const;
};

QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus );
QDataStream & operator>>(QDataStream & pStream, CANBus& pCanBus);
QDataStream& operator<<(QDataStream & pStream, const CANBus& pCanBus);
QDataStream& operator>>(QDataStream & pStream, CANBus& pCanBus);

Q_DECLARE_METATYPE(CANBus);

struct BusData {
CANBus mBus;
bool mConfigured;
bool mConfigured = {};
QVector<CANFltObserver> mTargettedFrames;
};

Expand Down
2 changes: 1 addition & 1 deletion connections/canconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ CANConnection::CANConnection(QString pPort,
int pQueueLen,
bool pUseThread) :
mNumBuses(pNumBuses),
mSerialSpeed(pSerialSpeed),
mQueue(),
mPort(pPort),
mDriver(pDriver),
mType(pType),
mSerialSpeed(pSerialSpeed),
mIsCapSuspended(false),
mStatus(CANCon::NOT_CONNECTED),
mStarted(false),
Expand Down
27 changes: 13 additions & 14 deletions connections/connectionwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) :
//Need to make sure it tries to share the address in case there are
//multiple instances of SavvyCAN running.
rxBroadcastGVRET->bind(QHostAddress::AnyIPv4, 17222, QAbstractSocket::ShareAddress);
connect(rxBroadcastGVRET, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
connect(rxBroadcastGVRET, &QUdpSocket::readyRead, this, &ConnectionWindow::readPendingDatagrams);

//Doing the same for socketcand/kayak hosts:
rxBroadcastKayak = new QUdpSocket(this);
rxBroadcastKayak->bind(QHostAddress::AnyIPv4, 42000, QAbstractSocket::ShareAddress);
connect(rxBroadcastKayak, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
connect(rxBroadcastKayak, &QUdpSocket::readyRead, this, &ConnectionWindow::readPendingDatagrams);

}

Expand Down Expand Up @@ -236,12 +236,12 @@ void ConnectionWindow::consoleEnableChanged(bool checked) {
CANConnection* conn_p = connModel->getAtIdx(selIdx);

if (checked) { //enable console
connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString)));
connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray)));
connect(conn_p, &CANConnection::debugOutput, this, &ConnectionWindow::getDebugText, Qt::UniqueConnection);
connect(this, &ConnectionWindow::sendDebugData, conn_p, &CANConnection::debugInput, Qt::UniqueConnection);
}
else { //turn it off
disconnect(conn_p, SIGNAL(debugOutput(QString)), nullptr, nullptr);
disconnect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray)));
disconnect(conn_p, &CANConnection::debugOutput, nullptr, nullptr);
disconnect(this, &ConnectionWindow::sendDebugData, conn_p, &CANConnection::debugInput);
}
}

Expand Down Expand Up @@ -454,8 +454,8 @@ void ConnectionWindow::currentRowChanged(const QModelIndex &current, const QMode
int selIdx = current.row();
CANConnection* prevConn = connModel->getAtIdx(previous.row());
if(prevConn != nullptr)
disconnect(prevConn, SIGNAL(debugOutput(QString)), nullptr, nullptr);
disconnect(this, SIGNAL(sendDebugData(QByteArray)), nullptr, nullptr);
disconnect(prevConn, &CANConnection::debugOutput, nullptr, nullptr);
disconnect(this, &ConnectionWindow::sendDebugData, nullptr, nullptr);

/* set parameters */
if (selIdx == -1) {
Expand All @@ -472,7 +472,7 @@ void ConnectionWindow::currentRowChanged(const QModelIndex &current, const QMode
if(!conn_p) return;

//because this might have already been setup during the initial setup so tear that one down and then create the normal one.
//disconnect(conn_p, SIGNAL(debugOutput(QString)), 0, 0);
//disconnect(conn_p, &CANConnection::debugOutput, 0, 0);

numBuses = conn_p->getNumBuses();
int numB = ui->tabBuses->count();
Expand All @@ -485,8 +485,8 @@ void ConnectionWindow::currentRowChanged(const QModelIndex &current, const QMode
populateBusDetails(0);
if (ui->ckEnableConsole->isChecked())
{
connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString)));
connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray)));
connect(conn_p, &CANConnection::debugOutput, this, &ConnectionWindow::getDebugText, Qt::UniqueConnection);
connect(this, &ConnectionWindow::sendDebugData, conn_p, &CANConnection::debugInput, Qt::UniqueConnection);
}
}
}
Expand Down Expand Up @@ -524,12 +524,11 @@ CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QS
if(conn_p)
{
/* connect signal */
connect(conn_p, SIGNAL(status(CANConStatus)),
this, SLOT(connectionStatus(CANConStatus)));
connect(conn_p, &CANConnection::status, this, &ConnectionWindow::connectionStatus);
if (ui->ckEnableConsole->isChecked())
{
//set up the debug console to operate if we've selected it. Doing so here allows debugging right away during set up
connect(conn_p, SIGNAL(debugOutput(QString)), this, SLOT(getDebugText(QString)));
connect(conn_p, &CANConnection::debugOutput, this, &ConnectionWindow::getDebugText, Qt::UniqueConnection);
}
/*TODO add return value and checks */
conn_p->start();
Expand Down
2 changes: 2 additions & 0 deletions connections/lawicel_serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ void LAWICELSerial::readSerialData()
break;
case 'b':
buildFrame.setBitrateSwitch(true); //BRS enabled
[[fallthrough]];
case 'd': //standard fd frame, BRS disabled
//tIIILDD
buildFrame.setFlexibleDataRateFormat(true);
Expand Down Expand Up @@ -572,6 +573,7 @@ void LAWICELSerial::readSerialData()
break;
case 'B':
buildFrame.setBitrateSwitch(true); //BRS enabled
[[fallthrough]];
case 'D': //extended fd frame
//TIIIIIIIILDD.
buildFrame.setFlexibleDataRateFormat(true);
Expand Down
15 changes: 7 additions & 8 deletions connections/serialbusconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus)
setBusConfig(0, bus);

/* if bus is not active we are done */
if(!bus.active)
if(!bus.isActive())
return;

/* set configuration */
Expand All @@ -105,10 +105,10 @@ 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);
mDev_p->setConfigurationParameter(QCanBusDevice::BitRateKey, bus.getSpeed());
mDev_p->setConfigurationParameter(QCanBusDevice::CanFdKey, bus.isCanFD());

if(bus.listenOnly)
if(bus.isListenOnly())
sbusconfig |= EN_SILENT_MODE;
mDev_p->setConfigurationParameter(QCanBusDevice::UserKey, sbusconfig);

Expand Down Expand Up @@ -188,6 +188,7 @@ void SerialBusConnection::framesReceived()

/* check frame */
//if (recFrame.payload().length() <= 8) {
if (true) {
CANFrame* frame_p = getQueue().get();
if(frame_p) {
frame_p->setPayload(recFrame.payload());
Expand All @@ -206,7 +207,7 @@ void SerialBusConnection::framesReceived()
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 */
/* 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) {
Expand All @@ -218,11 +219,9 @@ void SerialBusConnection::framesReceived()

/* enqueue frame */
getQueue().queue();
//}
#if 0
}
else
qDebug() << "can't get a frame, ERROR";
#endif
}
}
}
Expand Down
Loading

0 comments on commit 7587dd7

Please sign in to comment.