summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Hartmann <aha_1980@gmx.de>2017-01-13 22:35:13 +0100
committerAndré Hartmann <aha_1980@gmx.de>2017-01-17 15:11:30 +0000
commit19d4d81e8dd7ccb9831bea725989d2a08d258207 (patch)
treeaf1867778dbb33c3786b24becbe0dcfcf8b376ef
parentd4bbdb83b26f8219b6c64bcff3967aa15db07d9c (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.cpp14
-rw-r--r--src/plugins/canbus/socketcan/socketcanbackend.cpp3
-rw-r--r--src/serialbus/qcanbusframe.cpp30
-rw-r--r--src/serialbus/qcanbusframe.h17
-rw-r--r--tests/auto/qcanbusframe/tst_qcanbusframe.cpp42
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");