diff options
author | Andre Hartmann <aha_1980@gmx.de> | 2017-01-13 22:35:13 +0100 |
---|---|---|
committer | André Hartmann <aha_1980@gmx.de> | 2017-01-17 15:11:30 +0000 |
commit | 19d4d81e8dd7ccb9831bea725989d2a08d258207 (patch) | |
tree | af1867778dbb33c3786b24becbe0dcfcf8b376ef | |
parent | d4bbdb83b26f8219b6c64bcff3967aa15db07d9c (diff) |
CAN: Introduce CAN FD flag Error State Indicator (ESI)
Added hasErrorStateIndicator and setErrorStateIndicator to QCanBusFrame.
* Setting QCanBusFrame::setErrorStateIndicator(true)
also sets QCanBusFrame::setFlexibleDataRateFormat(true)
* Setting QCanBusFrame::setFlexibleDataRateFormat(false)
also sets QCanBusFrame::setErrorStateIndicator(false)
[ChangeLog][QCanBusFrame] Added error state indicator flag
to QCanBusFrame and set it appropriate receiving CAN FD
frames with the SocketCAN plugin. Setting this flag for
testing purposes is also possible.
Change-Id: I406b693fc7b7cde8a0d6b2c34c1f313800f11203
Reviewed-by: Rolf Eike Beer <eb@emlix.com>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r-- | examples/serialbus/can/mainwindow.cpp | 14 | ||||
-rw-r--r-- | src/plugins/canbus/socketcan/socketcanbackend.cpp | 3 | ||||
-rw-r--r-- | src/serialbus/qcanbusframe.cpp | 30 | ||||
-rw-r--r-- | src/serialbus/qcanbusframe.h | 17 | ||||
-rw-r--r-- | tests/auto/qcanbusframe/tst_qcanbusframe.cpp | 42 |
5 files changed, 100 insertions, 6 deletions
diff --git a/examples/serialbus/can/mainwindow.cpp b/examples/serialbus/can/mainwindow.cpp index b27baaa..86938f3 100644 --- a/examples/serialbus/can/mainwindow.cpp +++ b/examples/serialbus/can/mainwindow.cpp @@ -184,6 +184,17 @@ void MainWindow::closeEvent(QCloseEvent *event) event->accept(); } +static QString frameFlags(const QCanBusFrame &frame) +{ + if (frame.hasBitrateSwitch() && frame.hasErrorStateIndicator()) + return QStringLiteral(" B E "); + if (frame.hasBitrateSwitch()) + return QStringLiteral(" B - "); + if (frame.hasErrorStateIndicator()) + return QStringLiteral(" - E "); + return QStringLiteral(" - - "); +} + void MainWindow::checkMessages() { if (!m_canDevice) @@ -202,8 +213,7 @@ void MainWindow::checkMessages() .arg(frame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) .arg(frame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); - const QString flags = frame.hasBitrateSwitch() - ? QStringLiteral(" B - ") : QStringLiteral(" - - "); + const QString flags = frameFlags(frame); m_ui->receivedMessagesEdit->append(time + flags + view); } diff --git a/src/plugins/canbus/socketcan/socketcanbackend.cpp b/src/plugins/canbus/socketcan/socketcanbackend.cpp index 53836b0..a41c8d1 100644 --- a/src/plugins/canbus/socketcan/socketcanbackend.cpp +++ b/src/plugins/canbus/socketcan/socketcanbackend.cpp @@ -450,6 +450,7 @@ bool SocketCanBackend::writeFrame(const QCanBusFrame &newData) frame.len = newData.payload().size(); frame.can_id = canId; frame.flags = newData.hasBitrateSwitch() ? CANFD_BRS : 0; + frame.flags |= newData.hasErrorStateIndicator() ? CANFD_ESI : 0; ::memcpy(frame.data, newData.payload().constData(), frame.len); bytesWritten = ::write(canSocket, &frame, sizeof(frame)); @@ -679,6 +680,8 @@ void SocketCanBackend::readSocket() bufferedFrame.setFrameType(QCanBusFrame::ErrorFrame); if (frame.flags & CANFD_BRS) bufferedFrame.setBitrateSwitch(true); + if (frame.flags & CANFD_ESI) + bufferedFrame.setErrorStateIndicator(true); bufferedFrame.setFrameId(frame.can_id & CAN_EFF_MASK); diff --git a/src/serialbus/qcanbusframe.cpp b/src/serialbus/qcanbusframe.cpp index 26e1964..4f00c88 100644 --- a/src/serialbus/qcanbusframe.cpp +++ b/src/serialbus/qcanbusframe.cpp @@ -288,6 +288,30 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QCanBusFrame::hasErrorStateIndicator() const + \since 5.9 + + Returns \c true if the CAN uses \e {Flexible Data-Rate} with \e {Error State Indicator} set. + + This flag is set by the transmitter's CAN FD hardware to indicate the transmitter's error state. + + \sa setErrorStateIndicator() +*/ + +/*! + \fn void QCanBusFrame::setErrorStateIndicator(bool errorStateIndicator) + \since 5.9 + + Set the \e {Flexible Data-Rate} flag \e {Error State Indicator} flag to \a errorStateIndicator. + + When sending CAN FD frames, this flag is automatically set by the CAN FD hardware. + \c QCanBusFrame::setErrorStateIndicator() should only be used for application testing, + e.g. on virtual CAN FD busses. + + \sa hasErrorStateIndicator() +*/ + +/*! \class QCanBusFrame::TimeStamp \inmodule QtSerialBus \since 5.8 @@ -397,7 +421,7 @@ QDataStream &operator<<(QDataStream &out, const QCanBusFrame &frame) out << stamp.seconds(); out << stamp.microSeconds(); if (frame.version >= QCanBusFrame::Version::Qt_5_9) - out << frame.hasBitrateSwitch(); + out << frame.hasBitrateSwitch() << frame.hasErrorStateIndicator(); return out; } @@ -414,6 +438,7 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame) bool extendedFrameFormat; bool flexibleDataRate; bool bitrateSwitch = false; + bool errorStateIndicator = false; QByteArray payload; qint64 seconds; qint64 microSeconds; @@ -422,7 +447,7 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame) >> payload >> seconds >> microSeconds; if (version >= QCanBusFrame::Version::Qt_5_9) - in >> bitrateSwitch; + in >> bitrateSwitch >> errorStateIndicator; frame.setFrameId(frameId); frame.version = version; @@ -431,6 +456,7 @@ QDataStream &operator>>(QDataStream &in, QCanBusFrame &frame) frame.setExtendedFrameFormat(extendedFrameFormat); frame.setFlexibleDataRateFormat(flexibleDataRate); frame.setBitrateSwitch(bitrateSwitch); + frame.setErrorStateIndicator(errorStateIndicator); frame.setPayload(payload); frame.setTimeStamp(QCanBusFrame::TimeStamp(seconds, microSeconds)); diff --git a/src/serialbus/qcanbusframe.h b/src/serialbus/qcanbusframe.h index 2c32cd8..7cab3e9 100644 --- a/src/serialbus/qcanbusframe.h +++ b/src/serialbus/qcanbusframe.h @@ -77,6 +77,7 @@ public: version(Qt_5_9), isFlexibleDataRate(0x0), isBitrateSwitch(0x0), + isErrorStateIndicator(0x0), reserved0(0x0) { Q_UNUSED(reserved0); @@ -109,6 +110,7 @@ public: version(Qt_5_9), isFlexibleDataRate(data.length() > 8 ? 0x1 : 0x0), isBitrateSwitch(0x0), + isErrorStateIndicator(0x0), reserved0(0x0), load(data) { @@ -226,8 +228,10 @@ public: void setFlexibleDataRateFormat(bool isFlexibleData) Q_DECL_NOTHROW { isFlexibleDataRate = (isFlexibleData & 0x1); - if (!isFlexibleData) + if (!isFlexibleData) { isBitrateSwitch = 0x0; + isErrorStateIndicator = 0x0; + } } bool hasBitrateSwitch() const Q_DECL_NOTHROW { return (isBitrateSwitch & 0x1); } @@ -238,6 +242,14 @@ public: isFlexibleDataRate = 0x1; } + bool hasErrorStateIndicator() const Q_DECL_NOTHROW { return (isErrorStateIndicator & 0x1); } + void setErrorStateIndicator(bool errorStateIndicator) Q_DECL_NOTHROW + { + isErrorStateIndicator = (errorStateIndicator & 0x1); + if (errorStateIndicator) + isFlexibleDataRate = 0x1; + } + #ifndef QT_NO_DATASTREAM friend Q_SERIALBUS_EXPORT QDataStream &operator<<(QDataStream &, const QCanBusFrame &); friend Q_SERIALBUS_EXPORT QDataStream &operator>>(QDataStream &, QCanBusFrame &); @@ -258,7 +270,8 @@ private: quint8 isFlexibleDataRate:1; quint8 isBitrateSwitch:1; - quint8 reserved0:7; + quint8 isErrorStateIndicator:1; + quint8 reserved0:6; // reserved for future use quint8 reserved[2]; diff --git a/tests/auto/qcanbusframe/tst_qcanbusframe.cpp b/tests/auto/qcanbusframe/tst_qcanbusframe.cpp index 4decffa..7907017 100644 --- a/tests/auto/qcanbusframe/tst_qcanbusframe.cpp +++ b/tests/auto/qcanbusframe/tst_qcanbusframe.cpp @@ -49,6 +49,7 @@ private slots: void payload(); void timeStamp(); void bitRateSwitch(); + void errorStateIndicator(); void tst_isValid_data(); void tst_isValid(); @@ -222,6 +223,47 @@ void tst_QCanBusFrame::bitRateSwitch() QVERIFY(!frame2.hasBitrateSwitch()); } +void tst_QCanBusFrame::errorStateIndicator() +{ + QCanBusFrame frame(QCanBusFrame::DataFrame); + QVERIFY(!frame.hasErrorStateIndicator()); + + // set CAN FD does not set ESI + frame.setFlexibleDataRateFormat(true); + QVERIFY(frame.hasFlexibleDataRateFormat()); + QVERIFY(!frame.hasErrorStateIndicator()); + + // set ESI keeps CAN FD + frame.setErrorStateIndicator(true); + QVERIFY(frame.hasFlexibleDataRateFormat()); + QVERIFY(frame.hasErrorStateIndicator()); + + // clear ESI keeps CAN FD + frame.setErrorStateIndicator(false); + QVERIFY(frame.hasFlexibleDataRateFormat()); + QVERIFY(!frame.hasErrorStateIndicator()); + + // clear CAN FD + frame.setFlexibleDataRateFormat(false); + QVERIFY(!frame.hasFlexibleDataRateFormat()); + QVERIFY(!frame.hasErrorStateIndicator()); + + // set ESI sets CAN FD + frame.setErrorStateIndicator(true); + QVERIFY(frame.hasFlexibleDataRateFormat()); + QVERIFY(frame.hasErrorStateIndicator()); + + // clear CAN FD clears ESI + frame.setFlexibleDataRateFormat(false); + QVERIFY(!frame.hasFlexibleDataRateFormat()); + QVERIFY(!frame.hasErrorStateIndicator()); + + // default constructed CAN FD frame has no ESI + const QCanBusFrame frame2(0x123, QByteArray(10, 0x55)); + QVERIFY(frame2.hasFlexibleDataRateFormat()); + QVERIFY(!frame2.hasErrorStateIndicator()); +} + void tst_QCanBusFrame::tst_isValid_data() { QTest::addColumn<QCanBusFrame::FrameType>("frameType"); |