diff options
-rw-r--r-- | examples/serialbus/can/can.pro | 5 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.cpp | 34 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.ui | 125 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.cpp | 182 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.h | 100 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.ui | 211 |
7 files changed, 514 insertions, 145 deletions
diff --git a/examples/serialbus/can/can.pro b/examples/serialbus/can/can.pro index c667dbb..017589a 100644 --- a/examples/serialbus/can/can.pro +++ b/examples/serialbus/can/can.pro @@ -8,14 +8,17 @@ SOURCES += \ connectdialog.cpp \ main.cpp \ mainwindow.cpp \ + sendframebox.cpp HEADERS += \ bitratebox.h \ connectdialog.h \ mainwindow.h \ + sendframebox.h FORMS += mainwindow.ui \ - connectdialog.ui + connectdialog.ui \ + sendframebox.ui RESOURCES += can.qrc diff --git a/examples/serialbus/can/mainwindow.cpp b/examples/serialbus/can/mainwindow.cpp index fa6519b..1cfd414 100644 --- a/examples/serialbus/can/mainwindow.cpp +++ b/examples/serialbus/can/mainwindow.cpp @@ -77,9 +77,9 @@ MainWindow::~MainWindow() void MainWindow::initActionsConnections() { m_ui->actionDisconnect->setEnabled(false); - m_ui->sendMessagesBox->setEnabled(false); + m_ui->sendFrameBox->setEnabled(false); - connect(m_ui->sendButton, &QPushButton::clicked, this, &MainWindow::sendFrame); + connect(m_ui->sendFrameBox, &SendFrameBox::sendFrame, this, &MainWindow::sendFrame); connect(m_ui->actionConnect, &QAction::triggered, m_connectDialog, &ConnectDialog::show); connect(m_connectDialog, &QDialog::accepted, this, &MainWindow::connectDevice); connect(m_ui->actionDisconnect, &QAction::triggered, this, &MainWindow::disconnectDevice); @@ -138,7 +138,7 @@ void MainWindow::connectDevice() m_ui->actionConnect->setEnabled(false); m_ui->actionDisconnect->setEnabled(true); - m_ui->sendMessagesBox->setEnabled(true); + m_ui->sendFrameBox->setEnabled(true); QVariant bitRate = m_canDevice->configurationParameter(QCanBusDevice::BitRateKey); if (bitRate.isValid()) { @@ -164,7 +164,7 @@ void MainWindow::disconnectDevice() m_ui->actionConnect->setEnabled(true); m_ui->actionDisconnect->setEnabled(false); - m_ui->sendMessagesBox->setEnabled(false); + m_ui->sendFrameBox->setEnabled(false); m_status->setText(tr("Disconnected")); } @@ -219,34 +219,10 @@ void MainWindow::processReceivedFrames() } } -void MainWindow::sendFrame() const +void MainWindow::sendFrame(const QCanBusFrame &frame) const { if (!m_canDevice) return; - QString payload = m_ui->lineEdit->displayText(); - QByteArray writings = QByteArray::fromHex(payload.remove(' ').toLatin1()); - - QCanBusFrame frame; - const int maxPayload = m_ui->fdBox->checkState() ? 64 : 8; - writings.truncate(maxPayload); - frame.setPayload(writings); - - qint32 id = m_ui->idEdit->displayText().toInt(nullptr, 16); - if (!m_ui->effBox->checkState() && id > 2047) //11 bits - id = 2047; - - frame.setFrameId(id); - frame.setExtendedFrameFormat(m_ui->effBox->checkState()); - frame.setFlexibleDataRateFormat(m_ui->fdBox->checkState()); - frame.setBitrateSwitch(m_ui->bitrateSwitchBox->checkState()); - - if (m_ui->remoteFrame->isChecked()) - frame.setFrameType(QCanBusFrame::RemoteRequestFrame); - else if (m_ui->errorFrame->isChecked()) - frame.setFrameType(QCanBusFrame::ErrorFrame); - else - frame.setFrameType(QCanBusFrame::DataFrame); - m_canDevice->writeFrame(frame); } diff --git a/examples/serialbus/can/mainwindow.h b/examples/serialbus/can/mainwindow.h index b0c6ef9..4351787 100644 --- a/examples/serialbus/can/mainwindow.h +++ b/examples/serialbus/can/mainwindow.h @@ -68,7 +68,7 @@ public: private slots: void processReceivedFrames(); - void sendFrame() const; + void sendFrame(const QCanBusFrame &frame) const; void processErrors(QCanBusDevice::CanBusError) const; void connectDevice(); void disconnectDevice(); diff --git a/examples/serialbus/can/mainwindow.ui b/examples/serialbus/can/mainwindow.ui index 04f8c93..1d5a657 100644 --- a/examples/serialbus/can/mainwindow.ui +++ b/examples/serialbus/can/mainwindow.ui @@ -14,123 +14,12 @@ <string>CAN Example</string> </property> <widget class="QWidget" name="centralWidget"> - <layout class="QVBoxLayout" name="verticalLayout_3"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QGroupBox" name="sendMessagesBox"> + <widget class="SendFrameBox" name="sendFrameBox"> <property name="title"> - <string>Send CAN message</string> + <string>Send CAN frame</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>&ID (hex)</string> - </property> - <property name="buddy"> - <cstring>idEdit</cstring> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="idEdit"> - <property name="placeholderText"> - <string>123</string> - </property> - </widget> - </item> - <item row="0" column="2" rowspan="4"> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Frame Type</string> - </property> - <property name="checkable"> - <bool>false</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QRadioButton" name="dataFrame"> - <property name="text"> - <string>D&ata</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="remoteFrame"> - <property name="text"> - <string>Re&mote Request</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="errorFrame"> - <property name="text"> - <string>&Error</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="0" column="3"> - <widget class="QCheckBox" name="fdBox"> - <property name="text"> - <string>&Flexible Data-Rate -(64 byte payload)</string> - </property> - </widget> - </item> - <item row="2" column="3"> - <widget class="QCheckBox" name="effBox"> - <property name="toolTip"> - <string>Allow extended frames with 29 bit identifier. -Otherwise, the standard format with 11 bit idenfier is used.</string> - </property> - <property name="text"> - <string>E&xtended Frame -(29 bit identifier)</string> - </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QPushButton" name="sendButton"> - <property name="text"> - <string>&Send</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="lineEdit"> - <property name="placeholderText"> - <string>12 34 AB CE</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>&Data (hex)</string> - </property> - <property name="buddy"> - <cstring>lineEdit</cstring> - </property> - </widget> - </item> - <item row="1" column="3"> - <widget class="QCheckBox" name="bitrateSwitchBox"> - <property name="text"> - <string>&Bitrate Switch -(Higher data rate)</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> </widget> </item> <item> @@ -276,6 +165,14 @@ Otherwise, the standard format with 11 bit idenfier is used.</string> </action> </widget> <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>SendFrameBox</class> + <extends>QGroupBox</extends> + <header location="global">sendframebox.h</header> + <container>1</container> + </customwidget> + </customwidgets> <resources> <include location="can.qrc"/> </resources> diff --git a/examples/serialbus/can/sendframebox.cpp b/examples/serialbus/can/sendframebox.cpp new file mode 100644 index 0000000..a84222d --- /dev/null +++ b/examples/serialbus/can/sendframebox.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sendframebox.h" +#include "ui_sendframebox.h" + +enum { + MaxStandardId = 0x7FF, + MaxExtendedId = 0x10000000 +}; + +enum { + MaxPayload = 8, + MaxPayloadFd = 64 +}; + +HexIntegerValidator::HexIntegerValidator(QObject *parent) : + QValidator(parent), + m_maximum(MaxStandardId) +{ +} + +QValidator::State HexIntegerValidator::validate(QString &input, int &) const +{ + bool ok; + uint value = input.toUInt(&ok, 16); + + if (!value) + return Intermediate; + + if (!ok || value > m_maximum) + return Invalid; + + return Acceptable; +} + +void HexIntegerValidator::setMaximum(uint maximum) +{ + m_maximum = maximum; +} + +HexStringValidator::HexStringValidator(QObject *parent) : + QValidator(parent), + m_maxLength(MaxPayload) +{ +} + +QValidator::State HexStringValidator::validate(QString &input, int &pos) const +{ + const int maxSize = 2 * m_maxLength; + const QChar space = QLatin1Char(' '); + QString data = input; + data.remove(space); + + if (data.isEmpty()) + return Intermediate; + + // limit maximum size and forbid trailing spaces + if ((data.size() > maxSize) || (data.size() == maxSize && input.endsWith(space))) + return Invalid; + + // check if all input is valid + const QRegularExpression re(QStringLiteral("^[[:xdigit:]]*$")); + if (!re.match(data).hasMatch()) + return Invalid; + + // insert a space after every two hex nibbles + const QRegularExpression insertSpace(QStringLiteral("(?:[[:xdigit:]]{2} )*[[:xdigit:]]{3}")); + if (insertSpace.match(input).hasMatch()) { + input.insert(input.size() - 1, space); + pos = input.size(); + } + + return Acceptable; +} + +void HexStringValidator::setMaxLength(int maxLength) +{ + m_maxLength = maxLength; +} + +SendFrameBox::SendFrameBox(QWidget *parent) : + QGroupBox(parent), + m_ui(new Ui::SendFrameBox) +{ + m_ui->setupUi(this); + + m_hexIntegerValidator = new HexIntegerValidator(this); + m_ui->frameIdEdit->setValidator(m_hexIntegerValidator); + m_hexStringValidator = new HexStringValidator(this); + m_ui->payloadEdit->setValidator(m_hexStringValidator); + + connect(m_ui->dataFrame, &QRadioButton::toggled, [this](bool set) { + if (set) + m_ui->flexibleDataRateBox->setEnabled(true); + }); + + connect(m_ui->remoteFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->errorFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->extendedFormatBox, &QCheckBox::toggled, [this](bool set) { + m_hexIntegerValidator->setMaximum(set ? MaxExtendedId : MaxStandardId); + }); + + connect(m_ui->flexibleDataRateBox, &QCheckBox::toggled, [this](bool set) { + m_hexStringValidator->setMaxLength(set ? MaxPayloadFd : MaxPayload); + m_ui->bitrateSwitchBox->setEnabled(set); + if (!set) + m_ui->bitrateSwitchBox->setChecked(false); + }); + + connect(m_ui->sendButton, &QPushButton::clicked, [this]() { + const uint frameId = m_ui->frameIdEdit->text().toUInt(nullptr, 16); + QString data = m_ui->payloadEdit->text(); + const QByteArray payload = QByteArray::fromHex(data.remove(QLatin1Char(' ')).toLatin1()); + + QCanBusFrame frame = QCanBusFrame(frameId, payload); + frame.setExtendedFrameFormat(m_ui->extendedFormatBox->isChecked()); + frame.setFlexibleDataRateFormat(m_ui->flexibleDataRateBox->isChecked()); + frame.setBitrateSwitch(m_ui->bitrateSwitchBox->isChecked()); + + if (m_ui->errorFrame->isChecked()) + frame.setFrameType(QCanBusFrame::ErrorFrame); + else if (m_ui->remoteFrame->isChecked()) + frame.setFrameType(QCanBusFrame::RemoteRequestFrame); + + emit sendFrame(frame); + }); +} + +SendFrameBox::~SendFrameBox() +{ + delete m_ui; +} diff --git a/examples/serialbus/can/sendframebox.h b/examples/serialbus/can/sendframebox.h new file mode 100644 index 0000000..bea4f7d --- /dev/null +++ b/examples/serialbus/can/sendframebox.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SENDFRAMEBOX_H +#define SENDFRAMEBOX_H + +#include <QCanBusFrame> +#include <QGroupBox> +#include <QRegularExpression> +#include <QValidator> + +namespace Ui { +class SendFrameBox; +} + +class HexIntegerValidator : public QValidator +{ + Q_OBJECT +public: + explicit HexIntegerValidator(QObject *parent = nullptr); + + QValidator::State validate(QString &input, int &) const; + + void setMaximum(uint maximum); + +private: + uint m_maximum = 0; +}; + +class HexStringValidator : public QValidator +{ + Q_OBJECT + +public: + explicit HexStringValidator(QObject *parent = nullptr); + + QValidator::State validate(QString &input, int &pos) const; + + void setMaxLength(int maxLength); + +private: + int m_maxLength = 0; +}; + +class SendFrameBox : public QGroupBox +{ + Q_OBJECT + +public: + explicit SendFrameBox(QWidget *parent = nullptr); + ~SendFrameBox(); + +signals: + void sendFrame(const QCanBusFrame &frame); + +private: + Ui::SendFrameBox *m_ui = nullptr; + + HexIntegerValidator *m_hexIntegerValidator = nullptr; + HexStringValidator *m_hexStringValidator = nullptr; +}; + +#endif // SENDFRAMEBOX_H diff --git a/examples/serialbus/can/sendframebox.ui b/examples/serialbus/can/sendframebox.ui new file mode 100644 index 0000000..0abeff5 --- /dev/null +++ b/examples/serialbus/can/sendframebox.ui @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SendFrameBox</class> + <widget class="QGroupBox" name="SendFrameBox"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>485</width> + <height>206</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <property name="title"> + <string/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QGroupBox" name="frameTypeBox"> + <property name="title"> + <string>Frame Type</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="topMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QRadioButton" name="dataFrame"> + <property name="toolTip"> + <string>Sends a CAN data frame.</string> + </property> + <property name="text"> + <string>D&ata Frame</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="remoteFrame"> + <property name="toolTip"> + <string>Sends a CAN remote request frame.</string> + </property> + <property name="text"> + <string>Re&mote Request Frame</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="errorFrame"> + <property name="toolTip"> + <string>Sends an error frame.</string> + </property> + <property name="text"> + <string>&Error Frame</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="frameOptionsBox"> + <property name="title"> + <string>Frame Options</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="extendedFormatBox"> + <property name="toolTip"> + <string>Allows extended frames with 29 bit identifier.</string> + </property> + <property name="text"> + <string>E&xtended Format</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="flexibleDataRateBox"> + <property name="toolTip"> + <string>Allows up to 64 byte payload data.</string> + </property> + <property name="text"> + <string>&Flexible Data-Rate</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="bitrateSwitchBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Sends payload at higher data rate.</string> + </property> + <property name="text"> + <string>&Bitrate Switch</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="frameIdLabel"> + <property name="text"> + <string>Frame &ID (hex)</string> + </property> + <property name="buddy"> + <cstring>frameIdEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="frameIdEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="placeholderText"> + <string>123</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="payloadLabel"> + <property name="text"> + <string>&Payload (hex)</string> + </property> + <property name="buddy"> + <cstring>payloadEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="payloadEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>2</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="placeholderText"> + <string>12 34 AB CE</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="sendButton"> + <property name="text"> + <string>&Send</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |