File indexing completed on 2024-05-12 04:41:10
0001 /* AtCore KDE Libary for 3D Printers 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2016-2018 Patrick José Pereira <patrickjp@kde.org> 0004 SPDX-FileCopyrightText: 2016-2018 Chris Rizzitello <rizzitello@kde.org> 0005 SPDX-FileCopyrightText: 2016, 2018 Tomaz Canabrava <tcanabrava@kde.org> 0006 SPDX-FileCopyrightText: 2018 Leandro Santiago <leandrosansilva@gmail.com> 0007 */ 0008 0009 #include <QLoggingCategory> 0010 0011 #include "seriallayer.h" 0012 0013 Q_LOGGING_CATEGORY(SERIAL_LAYER, "org.kde.atelier.core.serialLayer") 0014 0015 /** 0016 * @brief The SerialLayerPrivate class 0017 */ 0018 struct SerialLayer::SerialLayerPrivate { 0019 /** _lastError: the last reported error */ 0020 QSerialPort::SerialPortError _lastError = QSerialPort::NoError; 0021 /** New Line String */ 0022 static const QByteArray _newLine; 0023 /** New Line Return String */ 0024 static const QByteArray _newLineReturn; 0025 /** _rawData: the raw serial data */ 0026 QByteArray _rawData; 0027 /** _rByteCommand: received Messages */ 0028 QVector<QByteArray> _rByteCommands; 0029 /** Return String */ 0030 static const QByteArray _return; 0031 /** _sByteCommand: sent Messages */ 0032 QVector<QByteArray> _sByteCommands; 0033 /** _serialOpened: is Serial port opened */ 0034 bool _serialOpened = false; 0035 /** List of valid Baud Rates */ 0036 static const QStringList _validBaudRates; 0037 }; 0038 0039 const QByteArray SerialLayer::SerialLayerPrivate::_newLine = QByteArray("\n"); 0040 const QByteArray SerialLayer::SerialLayerPrivate::_newLineReturn = QByteArray("\n\r"); 0041 const QByteArray SerialLayer::SerialLayerPrivate::_return = QByteArray("\r"); 0042 const QStringList SerialLayer::SerialLayerPrivate::_validBaudRates = {QStringLiteral("9600"), 0043 QStringLiteral("14400"), 0044 QStringLiteral("19200"), 0045 QStringLiteral("28800"), 0046 QStringLiteral("38400"), 0047 QStringLiteral("57600"), 0048 QStringLiteral("76800"), 0049 QStringLiteral("115200"), 0050 QStringLiteral("230400"), 0051 QStringLiteral("250000"), 0052 QStringLiteral("500000"), 0053 QStringLiteral("1000000")}; 0054 0055 SerialLayer::SerialLayer(const QString &port, int32_t baud, QObject *parent) 0056 : QSerialPort(parent) 0057 , d(new SerialLayerPrivate()) 0058 { 0059 setPortName(port); 0060 setBaudRate(baud); 0061 if (open(QIODevice::ReadWrite)) { 0062 d->_serialOpened = true; 0063 connect(this, &QSerialPort::readyRead, this, &SerialLayer::readAllData); 0064 connect(this, &QSerialPort::errorOccurred, this, &SerialLayer::handleError); 0065 } 0066 } 0067 0068 SerialLayer::~SerialLayer() 0069 { 0070 delete d; 0071 }; 0072 0073 void SerialLayer::readAllData() 0074 { 0075 d->_rawData.append(readAll()); 0076 0077 // Remove any \r in the string, then split by \n. 0078 // This removes any trailing \r or \n from the commands 0079 // Proper line endings are added when the command is pushed. 0080 d->_rawData = d->_rawData.replace(d->_return, QByteArray()); 0081 0082 QList<QByteArray> tempList = d->_rawData.split(d->_newLine.at(0)); 0083 for (auto i = tempList.begin(); i != tempList.end(); ++i) { 0084 // Get finished line to _byteCommands 0085 if (i < tempList.end() - 1) { 0086 d->_rByteCommands.append(*i); 0087 Q_EMIT receivedCommand(*i); 0088 } else { 0089 d->_rawData.clear(); 0090 d->_rawData.append(*i); 0091 } 0092 } 0093 } 0094 0095 void SerialLayer::pushCommand(const QByteArray &comm, const QByteArray &term) 0096 { 0097 if (!isOpen()) { 0098 qCDebug(SERIAL_LAYER) << "Serial not connected !"; 0099 return; 0100 } 0101 QByteArray tmp = comm + term; 0102 write(tmp); 0103 Q_EMIT pushedCommand(tmp); 0104 } 0105 0106 void SerialLayer::pushCommand(const QByteArray &comm) 0107 { 0108 pushCommand(comm, d->_newLineReturn); 0109 } 0110 0111 void SerialLayer::add(const QByteArray &comm, const QByteArray &term) 0112 { 0113 QByteArray tmp = comm + term; 0114 d->_sByteCommands.append(tmp); 0115 } 0116 0117 void SerialLayer::add(const QByteArray &comm) 0118 { 0119 add(comm, d->_newLineReturn); 0120 } 0121 0122 void SerialLayer::push() 0123 { 0124 if (!isOpen()) { 0125 qCDebug(SERIAL_LAYER) << "Serial not connected !"; 0126 return; 0127 } 0128 for (const auto &comm : qAsConst(d->_sByteCommands)) { 0129 write(comm); 0130 Q_EMIT pushedCommand(comm); 0131 } 0132 d->_sByteCommands.clear(); 0133 } 0134 0135 bool SerialLayer::commandAvailable() const 0136 { 0137 return !d->_rByteCommands.isEmpty(); 0138 } 0139 0140 QStringList SerialLayer::validBaudRates() const 0141 { 0142 return d->_validBaudRates; 0143 } 0144 0145 void SerialLayer::handleError(QSerialPort::SerialPortError error) 0146 { 0147 if (d->_lastError == error) { 0148 return; 0149 } 0150 0151 d->_lastError = error; 0152 Q_EMIT serialError(error); 0153 }