diff --git a/SavvyCAN.pro b/SavvyCAN.pro index 9df479e..34c629a 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -20,6 +20,7 @@ QMAKE_INFO_PLIST = Info.plist.template ICON = icons/SavvyIcon.icns SOURCES += main.cpp\ + connections/lawicel_serial.cpp \ connections/mqtt_bus.cpp \ mqtt/qmqtt_client.cpp \ mqtt/qmqtt_client_p.cpp \ @@ -98,6 +99,7 @@ SOURCES += main.cpp\ HEADERS += mainwindow.h \ can_structs.h \ canframemodel.h \ + connections/lawicel_serial.h \ connections/socketcand.h \ connections/mqtt_bus.h \ mqtt/qmqtt.h \ diff --git a/connections/canconconst.h b/connections/canconconst.h index 7f479c1..2cf53cc 100644 --- a/connections/canconconst.h +++ b/connections/canconconst.h @@ -20,6 +20,7 @@ namespace CANCon { REMOTE, KAYAK, MQTT, + LAWICEL, NONE }; } diff --git a/connections/canconfactory.cpp b/connections/canconfactory.cpp index 1fc461c..77daf09 100644 --- a/connections/canconfactory.cpp +++ b/connections/canconfactory.cpp @@ -4,10 +4,11 @@ #include "gvretserial.h" #include "mqtt_bus.h" #include "socketcand.h" +#include "lawicel_serial.h" using namespace CANCon; -CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDriverName) +CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed) { switch(pType) { case SERIALBUS: @@ -16,6 +17,8 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri return new GVRetSerial(pPortName, false); 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); case KAYAK: return new SocketCANd(pPortName); case MQTT: diff --git a/connections/canconfactory.h b/connections/canconfactory.h index 668568e..c23ce8b 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); + static CANConnection* create(CANCon::type, QString pPortName, QString pDriverName, int pSerialSpeed, int pBusSpeed); }; #endif // CANCONFACTORY_H diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index 8f0e231..dca0490 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -5,6 +5,8 @@ CANConnection::CANConnection(QString pPort, QString pDriver, CANCon::type pType, + int pSerialSpeed, + int pBusSpeed, int pNumBuses, int pQueueLen, bool pUseThread) : @@ -13,6 +15,7 @@ CANConnection::CANConnection(QString pPort, mPort(pPort), mDriver(pDriver), mType(pType), + mSerialSpeed(pSerialSpeed), mIsCapSuspended(false), mStatus(CANCon::NOT_CONNECTED), mStarted(false), @@ -34,6 +37,8 @@ CANConnection::CANConnection(QString pPort, mBusData[i].mConfigured = false; } + if (pBusSpeed > 0) mBusData[0].mBus.setSpeed(pBusSpeed); + /* if needed, create a thread and move ourself into it */ if(pUseThread) { mThread_p = new QThread(); diff --git a/connections/canconnection.h b/connections/canconnection.h index 38d1160..ab53fc8 100644 --- a/connections/canconnection.h +++ b/connections/canconnection.h @@ -21,13 +21,17 @@ protected: * @param pPort: string containing port name * @param pDriver: string containing driver name - Really only used for SerialBus connections * @param pType: the type of connection @ref CANCon::type + * @param pSerialSpeed: for devices with variable serial speed this is that speed. + * @param pBusSpeed: set an initial speed when opening this connection * @param pNumBuses: the number of buses the device has * @param pQueueLen: the length of the lock free queue to use * @param pUseThread: if set to true, object will be execute in a dedicated thread */ CANConnection(QString pPort, QString pDriver, - CANCon::type pType, + CANCon::type pType, + int pSerialSpeed, + int pBusSpeed, int pNumBuses, int pQueueLen, bool pUseThread); @@ -201,6 +205,7 @@ protected: int mNumBuses; //protected to allow connected device to figure out how many buses are available QVector mBusData; bool mConsoleOutput; //send debugging info to the console? + int mSerialSpeed; //determine if the passed frame is part of a filter or not. void checkTargettedFrame(CANFrame &frame); diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp index aba9c7c..32a277f 100644 --- a/connections/canconnectionmodel.cpp +++ b/connections/canconnectionmodel.cpp @@ -86,6 +86,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const case CANCon::SERIALBUS: return "SerialBus"; case CANCon::GVRET_SERIAL: return "GVRET"; case CANCon::KAYAK: return "socketcand"; + case CANCon::LAWICEL: return "LAWICEL"; default: {} } else qDebug() << "Tried to show connection type but connection was nullptr"; diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index a446078..043bda8 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -250,6 +250,8 @@ void ConnectionWindow::handleNewConn() CANCon::type newType; QString newPort; QString newDriver; + int newSerialSpeed; + int newBusSpeed; CANConnection *conn; if (thisDialog->exec() == QDialog::Accepted) @@ -257,7 +259,9 @@ void ConnectionWindow::handleNewConn() newType = thisDialog->getConnectionType(); newPort = thisDialog->getPortName(); newDriver = thisDialog->getDriverName(); - conn = create(newType, newPort, newDriver); + newSerialSpeed = thisDialog->getSerialSpeed(); + newBusSpeed = thisDialog->getBusSpeed(); + conn = create(newType, newPort, newDriver, newSerialSpeed, newBusSpeed); if (conn) { connModel->add(conn); @@ -292,6 +296,7 @@ void ConnectionWindow::handleResetConn() { QString port, driver; CANCon::type type; + int serSpeed, busSpeed; int selIdx = ui->tableConnections->selectionModel()->currentIndex().row(); if (selIdx <0) return; @@ -304,13 +309,15 @@ void ConnectionWindow::handleResetConn() type = conn_p->getType(); port = conn_p->getPort(); driver = conn_p->getDriver(); + serSpeed = 0; //TODO: implement these + busSpeed = 0; /* stop and delete connection */ conn_p->stop(); conn_p = nullptr; - conn_p = create(type, port, driver); + conn_p = create(type, port, driver, serSpeed, busSpeed); if (conn_p) connModel->replace(selIdx, conn_p); } @@ -476,12 +483,12 @@ void ConnectionWindow::handleSendText() { emit sendDebugData(bytes); } -CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver) +CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed) { CANConnection* conn_p; /* create connection */ - conn_p = CanConFactory::create(pTye, pPortName, pDriver); + conn_p = CanConFactory::create(pTye, pPortName, pDriver, pSerialSpeed, pBusSpeed); if(conn_p) { /* connect signal */ @@ -516,7 +523,8 @@ void ConnectionWindow::loadConnections() for(int i = 0 ; i < portNames.count() ; i++) { - CANConnection* conn_p = create((CANCon::type)devTypes[i], portNames[i], driverNames[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); /* add connection to model */ connModel->add(conn_p); } @@ -534,6 +542,8 @@ void ConnectionWindow::saveConnections() QVector portNames; QVector devTypes; QVector driverNames; + QVector serialSpeeds; + QVector busSpeeds; /* save connections */ foreach(CANConnection* conn_p, conns) diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index b13f31f..9bc3076 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); + CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver, int pSerialSpeed, int pBusSpeed); void populateBusDetails(int offset); void loadConnections(); void saveConnections(); diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index c307b44..c7d340f 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, 3, 4000, true), + CANConnection(portName, "gvret", CANCon::GVRET_SERIAL, 0, 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 new file mode 100644 index 0000000..b312bf7 --- /dev/null +++ b/connections/lawicel_serial.cpp @@ -0,0 +1,496 @@ +#include +#include +#include +#include +#include +#include +#include + +#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), + mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ +{ + sendDebug("LAWICELSerial()"); + + serial = nullptr; + isAutoRestart = false; + + readSettings(); +} + + +LAWICELSerial::~LAWICELSerial() +{ + stop(); + sendDebug("~LAWICELSerial()"); +} + +void LAWICELSerial::sendDebug(const QString debugText) +{ + qDebug() << debugText; + debugOutput(debugText); +} + +void LAWICELSerial::sendToSerial(const QByteArray &bytes) +{ + if (serial == nullptr) + { + sendDebug("Attempt to write to serial port when it has not been initialized!"); + return; + } + + if (serial && !serial->isOpen()) + { + sendDebug("Attempt to write to serial port when it is not open!"); + return; + } + + QString buildDebug; + buildDebug = "Write to serial -> "; + foreach (int byt, bytes) { + byt = (unsigned char)byt; + buildDebug = buildDebug % QString::number(byt, 16) % " "; + } + sendDebug(buildDebug); + + if (serial) serial->write(bytes); +} + +void LAWICELSerial::piStarted() +{ + connectDevice(); +} + + +void LAWICELSerial::piSuspend(bool pSuspend) +{ + /* update capSuspended */ + setCapSuspended(pSuspend); + + /* flush queue if we are suspended */ + if(isCapSuspended()) + getQueue().flush(); +} + + +void LAWICELSerial::piStop() +{ + mTimer.stop(); + disconnectDevice(); +} + + +bool LAWICELSerial::piGetBusSettings(int pBusIdx, CANBus& pBus) +{ + return getBusConfig(pBusIdx, pBus); +} + + +void LAWICELSerial::piSetBusSettings(int pBusIdx, CANBus bus) +{ + /* sanity checks */ + if( (pBusIdx < 0) || pBusIdx >= getNumBuses()) + return; + + /* copy bus config */ + setBusConfig(pBusIdx, bus); +/* + qDebug() << "About to update bus " << pBusIdx << " on GVRET"; + if (pBusIdx == 0) + { + can0Baud = bus.getSpeed(); + can0Baud |= 0x80000000; + if (bus.isActive()) + { + can0Baud |= 0x40000000; + can0Enabled = true; + } + else can0Enabled = false; + + if (bus.isListenOnly()) + { + can0Baud |= 0x20000000; + can0ListenOnly = true; + } + else can0ListenOnly = false; + } +*/ + if (pBusIdx < 2) { + /* update baud rates */ + QByteArray buffer; + //sendDebug("Got signal to update bauds. 1: " + QString::number((can0Baud & 0xFFFFFFF))); + buffer[0] = (char)0xF1; //start of a command over serial + //sendToSerial(buffer); + } + +} + + +bool LAWICELSerial::piSendFrame(const CANFrame& frame) +{ + QByteArray buffer; + int c; + quint32 ID; + + //qDebug() << "Sending out lawicel frame with id " << frame.ID << " on bus " << frame.bus; + + framesRapid++; + + if (serial == nullptr) return false; + if (serial && !serial->isOpen()) return false; + //if (!isConnected) return false; + + // Doesn't make sense to send an error frame + // to an adapter + if (frame.frameId() & 0x20000000) { + return true; + } + + ID = frame.frameId(); + if (frame.hasExtendedFrameFormat()) ID |= 1u << 31; + + int idx = 0; + QString buildStr; + 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) + { + buffer[idx] = chr.toLatin1(); + idx++; + } + + for (c = 0; c < frame.payload().length(); c++) + { + QString byt = Utility::formatByteAsHex(frame.payload()[c]); + buffer[idx + (c * 2)] = byt[0].toLatin1(); + buffer[idx + (c * 2) + 1] = byt[1].toLatin1(); + } + buffer[idx + (frame.payload().length() * 2)] = 13; //CR + + sendToSerial(buffer); + + return true; +} + + + +/****************************************************************/ + +void LAWICELSerial::readSettings() +{ + QSettings settings; +} + + +void LAWICELSerial::connectDevice() +{ + QSettings settings; + + /* disconnect device */ + if(serial) + disconnectDevice(); + + /* open new device */ + + qDebug() << "Serial port: " << getPort(); + + serial = new QSerialPort(QSerialPortInfo(getPort())); + if(!serial) { + sendDebug("can't open serial port " + getPort()); + return; + } + sendDebug("Created Serial Port Object"); + + /* connect reading event */ + connect(serial, SIGNAL(readyRead()), this, SLOT(readSerialData())); + connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(serialError(QSerialPort::SerialPortError))); + + /* configure */ + serial->setBaudRate(mSerialSpeed); + serial->setDataBits(serial->Data8); + + serial->setFlowControl(serial->HardwareControl); + //serial->setFlowControl(serial->NoFlowControl); + if (!serial->open(QIODevice::ReadWrite)) + { + //sendDebug("Error returned during port opening: " + serial->errorString()); + } + else + { + //serial->setDataTerminalReady(true); //Seemingly these two lines used to be needed + //serial->setRequestToSend(true); //But, really both ends should automatically handle these + deviceConnected(); + } +} + +void LAWICELSerial::deviceConnected() +{ + sendDebug("Connecting to LAWICEL Device!"); + + QByteArray output; + + output.clear(); + output.append('C'); //close the bus in case it was already up + output.append(13); + sendToSerial(output); + + 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; + } + output.append('\x0D'); + + sendToSerial(output); + + output.clear(); + output.append('O'); //open bus now that we set the speed + output.append(13); + + sendToSerial(output); + + mNumBuses = 1; + setStatus(CANCon::CONNECTED); + CANConStatus stats; + stats.conStatus = getStatus(); + stats.numHardwareBuses = mNumBuses; + mBusData[0].mConfigured = true; + mBusData[0].mBus.setActive(true); + //mBusData[0].mBus.setSpeed(); + emit status(stats); +} + +void LAWICELSerial::disconnectDevice() { + if (serial != nullptr) + { + if (serial->isOpen()) + { + //serial->clear(); + serial->close(); + + } + serial->disconnect(); //disconnect all signals + delete serial; + serial = nullptr; + } + + setStatus(CANCon::NOT_CONNECTED); + CANConStatus stats; + stats.conStatus = getStatus(); + stats.numHardwareBuses = mNumBuses; + emit status(stats); +} + +void LAWICELSerial::serialError(QSerialPort::SerialPortError err) +{ + QString errMessage; + bool killConnection = false; + switch (err) + { + case QSerialPort::NoError: + return; + case QSerialPort::DeviceNotFoundError: + errMessage = "Device not found error on serial"; + killConnection = true; + piStop(); + break; + case QSerialPort::PermissionError: + errMessage = "Permission error on serial port"; + killConnection = true; + piStop(); + break; + case QSerialPort::OpenError: + errMessage = "Open error on serial port"; + killConnection = true; + piStop(); + break; + case QSerialPort::ParityError: + errMessage = "Parity error on serial port"; + break; + case QSerialPort::FramingError: + errMessage = "Framing error on serial port"; + break; + case QSerialPort::BreakConditionError: + errMessage = "Break error on serial port"; + break; + case QSerialPort::WriteError: + errMessage = "Write error on serial port"; + piStop(); + break; + case QSerialPort::ReadError: + errMessage = "Read error on serial port"; + piStop(); + break; + case QSerialPort::ResourceError: + errMessage = "Serial port seems to have disappeared."; + killConnection = true; + piStop(); + break; + case QSerialPort::UnsupportedOperationError: + errMessage = "Unsupported operation on serial port"; + killConnection = true; + break; + case QSerialPort::UnknownError: + errMessage = "Beats me what happened to the serial port."; + killConnection = true; + piStop(); + break; + case QSerialPort::TimeoutError: + errMessage = "Timeout error on serial port"; + killConnection = true; + break; + case QSerialPort::NotOpenError: + errMessage = "The serial port isn't open"; + killConnection = true; + piStop(); + break; + } + /* + if (serial) + { + serial->clearError(); + serial->flush(); + serial->close(); + }*/ + if (errMessage.length() > 1) + { + sendDebug(errMessage); + } + if (killConnection) + { + qDebug() << "Shooting the serial object in the head. It deserves it."; + disconnectDevice(); + } +} + + +void LAWICELSerial::connectionTimeout() +{ + //one second after trying to connect are we actually connected? + if (CANCon::NOT_CONNECTED==getStatus()) //no? + { + //then emit the the failure signal and see if anyone cares + sendDebug("Failed to connect to LAWICEL at that com port"); + + disconnectDevice(); + connectDevice(); + } + else + { + /* start timer */ + connect(&mTimer, SIGNAL(timeout()), this, SLOT(handleTick())); + mTimer.setInterval(250); //tick four times per second + mTimer.setSingleShot(false); //keep ticking + mTimer.start(); + } +} + +void LAWICELSerial::readSerialData() +{ + QByteArray data; + unsigned char c; + QString debugBuild; + CANFrame buildFrame; + QByteArray buildData; + + if (serial) data = serial->readAll(); + + sendDebug("Got data from serial. Len = " % QString::number(data.length())); + for (int i = 0; i < data.length(); i++) + { + c = data.at(i); + //qDebug() << c << " " << QString::number(c, 16) << " " << QString(c); + debugBuild = debugBuild % QString::number(c, 16).rightJustified(2,'0') % " "; + //procRXChar(c); + mBuildLine.append(c); + if (c == 13) //all lawicel commands end in CR + { + qDebug() << "Got CR!"; + switch (mBuildLine[0].toLatin1()) + { + case 't': //standard frame + //tIIILDD + buildFrame.setFrameId(mBuildLine.mid(1, 3).toInt(nullptr, 16)); + buildFrame.isReceived = true; + buildFrame.setFrameType(QCanBusFrame::FrameType::DataFrame); + buildData.resize(mBuildLine.mid(4, 1).toInt()); + 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 'T': //extended frame + break; + } + mBuildLine.clear(); + } + } + debugOutput(debugBuild); + //qDebug() << debugBuild; +} + +//Debugging data sent from connection window. Inject it into Comm traffic. +void LAWICELSerial::debugInput(QByteArray bytes) { + sendToSerial(bytes); +} + +void LAWICELSerial::handleTick() +{ + //qDebug() << "Tick!"; +} + diff --git a/connections/lawicel_serial.h b/connections/lawicel_serial.h new file mode 100644 index 0000000..555d089 --- /dev/null +++ b/connections/lawicel_serial.h @@ -0,0 +1,66 @@ +#ifndef LAWICELSERIAL_H +#define LAWICELSERIAL_H + +#include +#include +#include +#include + +/*************/ +#include +/*************/ + +#include "canframemodel.h" +#include "canconnection.h" +#include "canconmanager.h" + +class LAWICELSerial : public CANConnection +{ + Q_OBJECT + +public: + LAWICELSerial(QString portName, int serialSpeed, int lawicelSpeed); + virtual ~LAWICELSerial(); + +protected: + + virtual void piStarted(); + virtual void piStop(); + virtual void piSetBusSettings(int pBusIdx, CANBus pBus); + virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus); + virtual void piSuspend(bool pSuspend); + virtual bool piSendFrame(const CANFrame&) ; + + void disconnectDevice(); + +public slots: + void debugInput(QByteArray bytes); + +private slots: + void connectDevice(); + void connectionTimeout(); + void readSerialData(); + void serialError(QSerialPort::SerialPortError err); + void deviceConnected(); + void handleTick(); + +private: + void readSettings(); + void rebuildLocalTimeBasis(); + void sendToSerial(const QByteArray &bytes); + void sendDebug(const QString debugText); + +protected: + QTimer mTimer; + QThread mThread; + QString mBuildLine; + + bool isAutoRestart; + QSerialPort *serial; + int framesRapid; + CANFrame buildFrame; + bool can0Enabled; + bool can0ListenOnly; +}; + +#endif // LAWICELSERIAL_H diff --git a/connections/mqtt_bus.cpp b/connections/mqtt_bus.cpp index 6b05be5..bfaa04b 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, 1, 4000, true), + CANConnection(topicName, "mqtt_client", CANCon::MQTT, 0, 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 db4a721..88383b0 100644 --- a/connections/newconnectiondialog.cpp +++ b/connections/newconnectiondialog.cpp @@ -27,12 +27,17 @@ NewConnectionDialog::NewConnectionDialog(QVector* gvretips, QVectorrbRemote, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbKayak, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->rbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); + connect(ui->rbLawicel, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged); connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged); connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton); ui->lblDeviceType->setHidden(true); ui->cbDeviceType->setHidden(true); + ui->cbCANSpeed->setHidden(true); + ui->cbSerialSpeed->setHidden(true); + ui->lblCANSpeed->setHidden(true); + ui->lblSerialSpeed->setHidden(true); selectSerial(); qDebug() << "Was passed " << remoteDeviceIPGVRET->count() << " remote GVRET IPs"; @@ -53,6 +58,7 @@ void NewConnectionDialog::handleConnTypeChanged() { if (ui->rbGVRET->isChecked()) selectSerial(); if (ui->rbSocketCAN->isChecked()) selectSocketCan(); + if (ui->rbLawicel->isChecked()) selectLawicel(); if (ui->rbRemote->isChecked()) selectRemote(); if (ui->rbKayak->isChecked()) selectKayak(); if (ui->rbMQTT->isChecked()) selectMQTT(); @@ -68,12 +74,57 @@ void NewConnectionDialog::handleDeviceTypeChanged() ui->cbPort->addItem(canDevices[i].name()); } +void NewConnectionDialog::selectLawicel() +{ + ui->lPort->setText("Serial Port:"); + + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); + + ui->cbCANSpeed->setHidden(false); + ui->cbSerialSpeed->setHidden(false); + ui->lblCANSpeed->setHidden(false); + ui->lblSerialSpeed->setHidden(false); + + ui->cbPort->clear(); + ports = QSerialPortInfo::availablePorts(); + + for (int i = 0; i < ports.count(); i++) + ui->cbPort->addItem(ports[i].portName()); + + if (ui->cbCANSpeed->count() == 0) + { + ui->cbCANSpeed->addItem("10000"); + ui->cbCANSpeed->addItem("20000"); + ui->cbCANSpeed->addItem("50000"); + ui->cbCANSpeed->addItem("100000"); + ui->cbCANSpeed->addItem("125000"); + ui->cbCANSpeed->addItem("250000"); + ui->cbCANSpeed->addItem("500000"); + ui->cbCANSpeed->addItem("1000000"); + } + if (ui->cbSerialSpeed->count() == 0) + { + ui->cbSerialSpeed->addItem("115200"); + ui->cbSerialSpeed->addItem("150000"); + ui->cbSerialSpeed->addItem("250000"); + ui->cbSerialSpeed->addItem("500000"); + ui->cbSerialSpeed->addItem("1000000"); + ui->cbSerialSpeed->addItem("2000000"); + } + +} + void NewConnectionDialog::selectSerial() { ui->lPort->setText("Serial Port:"); 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->cbPort->clear(); ports = QSerialPortInfo::availablePorts(); @@ -87,6 +138,10 @@ void NewConnectionDialog::selectSocketCan() ui->lPort->setText("Port:"); ui->lblDeviceType->setHidden(false); ui->cbDeviceType->setHidden(false); + ui->cbCANSpeed->setHidden(true); + ui->cbSerialSpeed->setHidden(true); + ui->lblCANSpeed->setHidden(true); + ui->lblSerialSpeed->setHidden(true); ui->cbDeviceType->clear(); QStringList plugins; @@ -99,8 +154,14 @@ void NewConnectionDialog::selectSocketCan() void NewConnectionDialog::selectRemote() { ui->lPort->setText("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->cbPort->clear(); foreach(QString pName, *remoteDeviceIPGVRET) { @@ -111,8 +172,14 @@ void NewConnectionDialog::selectRemote() void NewConnectionDialog::selectKayak() { ui->lPort->setText("Available Bus(ses):"); + 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->cbPort->clear(); foreach(QString pName, *remoteBusKayak) { @@ -123,8 +190,14 @@ void NewConnectionDialog::selectKayak() void NewConnectionDialog::selectMQTT() { ui->lPort->setText("Topic Name:"); + 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->cbPort->clear(); } @@ -148,6 +221,8 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt case CANCon::MQTT: ui->rbMQTT->setChecked(true); break; + case CANCon::LAWICEL: + ui->rbLawicel->setChecked(true); default: {} } @@ -157,6 +232,7 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt switch(pType) { case CANCon::GVRET_SERIAL: + case CANCon::LAWICEL: { int idx = ui->cbPort->findText(pPortName); if( idx<0 ) idx=0; @@ -201,6 +277,7 @@ QString NewConnectionDialog::getPortName() case CANCon::SERIALBUS: case CANCon::REMOTE: case CANCon::MQTT: + case CANCon::LAWICEL: return ui->cbPort->currentText(); case CANCon::KAYAK: return ui->cbPort->currentText(); @@ -220,6 +297,24 @@ QString NewConnectionDialog::getDriverName() return "N/A"; } +int NewConnectionDialog::getSerialSpeed() +{ + if (getConnectionType() == CANCon::LAWICEL) + { + return ui->cbSerialSpeed->currentText().toInt(); + } + else return 0; +} + +int NewConnectionDialog::getBusSpeed() +{ + if (getConnectionType() == CANCon::LAWICEL) + { + return ui->cbCANSpeed->currentText().toInt(); + } + else return 0; +} + CANCon::type NewConnectionDialog::getConnectionType() { if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL; @@ -227,6 +322,7 @@ CANCon::type NewConnectionDialog::getConnectionType() if (ui->rbRemote->isChecked()) return CANCon::REMOTE; if (ui->rbKayak->isChecked()) return CANCon::KAYAK; if (ui->rbMQTT->isChecked()) return CANCon::MQTT; + if (ui->rbLawicel->isChecked()) return CANCon::LAWICEL; qDebug() << "getConnectionType: error"; return CANCon::NONE; diff --git a/connections/newconnectiondialog.h b/connections/newconnectiondialog.h index 1410b42..938d2d2 100644 --- a/connections/newconnectiondialog.h +++ b/connections/newconnectiondialog.h @@ -24,6 +24,8 @@ public: CANCon::type getConnectionType(); QString getPortName(); QString getDriverName(); + int getSerialSpeed(); + int getBusSpeed(); public slots: void handleConnTypeChanged(); @@ -43,6 +45,7 @@ private: void selectRemote(); void selectKayak(); void selectMQTT(); + void selectLawicel(); bool isSerialBusAvailable(); void setPortName(CANCon::type pType, QString pPortName, QString pDriver); }; diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index 6ea71c3..b1a2f6e 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -12,7 +12,7 @@ /***********************************/ SerialBusConnection::SerialBusConnection(QString portName, QString driverName) : - CANConnection(portName, driverName, CANCon::SERIALBUS, 1, 4000, true), + CANConnection(portName, driverName, CANCon::SERIALBUS,0 ,0 ,1, 4000, true), mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */ { } diff --git a/connections/socketcand.cpp b/connections/socketcand.cpp index 9bbddbb..6fbf5e4 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, 1, 4000, true), + CANConnection(portName, "kayak", CANCon::KAYAK, 0, 0, 1, 4000, true), mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ { diff --git a/ui/newconnectiondialog.ui b/ui/newconnectiondialog.ui index faa847a..a257907 100644 --- a/ui/newconnectiondialog.ui +++ b/ui/newconnectiondialog.ui @@ -6,8 +6,8 @@ 0 0 - 356 - 282 + 426 + 540 @@ -23,6 +23,30 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + socketcand (SocketCAN over Ethernet) + + + + + + + false + + + QT SerialBus Devices (SocketCAN, PeakCAN, etc) + + + + + + + MQTT Connection + + + @@ -40,27 +64,10 @@ - - - - false - + + - QT SerialBus Devices (SocketCAN, PeakCAN, etc) - - - - - - - socketcand (SocketCAN over Ethernet) - - - - - - - MQTT Connection + LAWICEL / SLCAN Serial @@ -109,6 +116,39 @@ + + + + Serial Port Speed: + + + + + + + + + + CAN Bus Speed: + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + +