mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-15 05:22:53 +08:00
Report serial port errors for #233
This commit is contained in:
parent
5a6ea37e32
commit
61c0758fad
@ -325,7 +325,6 @@ Rectangle {
|
|||||||
icon.source: checked ? "qrc:/rcc/icons/toolbar/connect.svg" :
|
icon.source: checked ? "qrc:/rcc/icons/toolbar/connect.svg" :
|
||||||
"qrc:/rcc/icons/toolbar/disconnect.svg"
|
"qrc:/rcc/icons/toolbar/disconnect.svg"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Connect/disconnect device when button is clicked
|
// Connect/disconnect device when button is clicked
|
||||||
//
|
//
|
||||||
|
@ -41,6 +41,9 @@ IO::Drivers::Serial::Serial()
|
|||||||
, m_lastSerialDeviceIndex(0)
|
, m_lastSerialDeviceIndex(0)
|
||||||
, m_portIndex(0)
|
, m_portIndex(0)
|
||||||
{
|
{
|
||||||
|
// Populate error list
|
||||||
|
populateErrors();
|
||||||
|
|
||||||
// Read settings
|
// Read settings
|
||||||
readSettings();
|
readSettings();
|
||||||
|
|
||||||
@ -55,6 +58,10 @@ IO::Drivers::Serial::Serial()
|
|||||||
// Update connect button status when user selects a serial device
|
// Update connect button status when user selects a serial device
|
||||||
connect(this, &IO::Drivers::Serial::portIndexChanged, this,
|
connect(this, &IO::Drivers::Serial::portIndexChanged, this,
|
||||||
&IO::Drivers::Serial::configurationChanged);
|
&IO::Drivers::Serial::configurationChanged);
|
||||||
|
|
||||||
|
// Update error list when language is changed
|
||||||
|
connect(this, &IO::Drivers::Serial::languageChanged, this,
|
||||||
|
&IO::Drivers::Serial::populateErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,8 +184,19 @@ bool IO::Drivers::Serial::open(const QIODevice::OpenMode mode)
|
|||||||
m_lastSerialDeviceIndex = m_portIndex;
|
m_lastSerialDeviceIndex = m_portIndex;
|
||||||
Q_EMIT portIndexChanged();
|
Q_EMIT portIndexChanged();
|
||||||
|
|
||||||
// Create new serial port handler
|
// Get port name from device list
|
||||||
m_port = new QSerialPort(ports.at(portId));
|
const auto name = ports.at(portId);
|
||||||
|
|
||||||
|
// Create new serial port handler for native serial ports
|
||||||
|
if (m_deviceNames.contains(name))
|
||||||
|
{
|
||||||
|
const auto handler = validPorts().at(portId - 1);
|
||||||
|
m_port = new QSerialPort(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new serial port handler for user-specified serial ports
|
||||||
|
else if (m_customDevices.contains(name))
|
||||||
|
m_port = new QSerialPort(name);
|
||||||
|
|
||||||
// Configure serial port
|
// Configure serial port
|
||||||
port()->setParity(parity());
|
port()->setParity(parity());
|
||||||
@ -196,7 +214,6 @@ bool IO::Drivers::Serial::open(const QIODevice::OpenMode mode)
|
|||||||
{
|
{
|
||||||
connect(port(), &QIODevice::readyRead, this,
|
connect(port(), &QIODevice::readyRead, this,
|
||||||
&IO::Drivers::Serial::onReadyRead);
|
&IO::Drivers::Serial::onReadyRead);
|
||||||
|
|
||||||
port()->setDataTerminalReady(dtrEnabled());
|
port()->setDataTerminalReady(dtrEnabled());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -218,17 +235,6 @@ bool IO::Drivers::Serial::open(const QIODevice::OpenMode mode)
|
|||||||
// Driver specifics
|
// Driver specifics
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the current serial port device
|
|
||||||
*/
|
|
||||||
QString IO::Drivers::Serial::portName() const
|
|
||||||
{
|
|
||||||
if (port())
|
|
||||||
return port()->portName();
|
|
||||||
|
|
||||||
return tr("No Device");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pointer to the current serial port handler
|
* Returns the pointer to the current serial port handler
|
||||||
*/
|
*/
|
||||||
@ -309,8 +315,8 @@ quint8 IO::Drivers::Serial::flowControlIndex() const
|
|||||||
*/
|
*/
|
||||||
QStringList IO::Drivers::Serial::portList() const
|
QStringList IO::Drivers::Serial::portList() const
|
||||||
{
|
{
|
||||||
if (m_portList.count() > 0)
|
if (m_deviceNames.count() > 0)
|
||||||
return m_portList + m_customDevices;
|
return m_deviceNames + m_customDevices;
|
||||||
|
|
||||||
else
|
else
|
||||||
return QStringList{tr("Select Port")};
|
return QStringList{tr("Select Port")};
|
||||||
@ -456,6 +462,7 @@ void IO::Drivers::Serial::setupExternalConnections()
|
|||||||
// Build serial devices list and refresh it every second
|
// Build serial devices list and refresh it every second
|
||||||
connect(&Misc::TimerEvents::instance(), &Misc::TimerEvents::timeout1Hz, this,
|
connect(&Misc::TimerEvents::instance(), &Misc::TimerEvents::timeout1Hz, this,
|
||||||
&IO::Drivers::Serial::refreshSerialDevices);
|
&IO::Drivers::Serial::refreshSerialDevices);
|
||||||
|
|
||||||
// Update lists when language changes
|
// Update lists when language changes
|
||||||
connect(&Misc::Translator::instance(), &Misc::Translator::languageChanged,
|
connect(&Misc::Translator::instance(), &Misc::Translator::languageChanged,
|
||||||
this, &IO::Drivers::Serial::languageChanged);
|
this, &IO::Drivers::Serial::languageChanged);
|
||||||
@ -516,21 +523,33 @@ void IO::Drivers::Serial::setPortIndex(const quint8 portIndex)
|
|||||||
Q_EMIT portIndexChanged();
|
Q_EMIT portIndexChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers a custom serial device.
|
||||||
|
*
|
||||||
|
* This function allows the registration of a custom serial device by verifying
|
||||||
|
* the validity of the provided path and ensuring it is not already registered.
|
||||||
|
* If the path is valid and not yet registered, it is added to the list of
|
||||||
|
* custom devices.
|
||||||
|
*
|
||||||
|
* @param device The file path of the device to register.
|
||||||
|
*/
|
||||||
void IO::Drivers::Serial::registerDevice(const QString &device)
|
void IO::Drivers::Serial::registerDevice(const QString &device)
|
||||||
{
|
{
|
||||||
QFile path(device);
|
const auto trimmedPath = device.simplified();
|
||||||
|
|
||||||
|
QFile path(trimmedPath);
|
||||||
if (path.exists())
|
if (path.exists())
|
||||||
{
|
{
|
||||||
if (!m_customDevices.contains(device))
|
if (!m_customDevices.contains(trimmedPath))
|
||||||
{
|
{
|
||||||
m_customDevices.append(device);
|
m_customDevices.append(trimmedPath);
|
||||||
refreshSerialDevices();
|
Q_EMIT availablePortsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
Misc::Utilities::showMessageBox(
|
Misc::Utilities::showMessageBox(
|
||||||
tr("\"%1\" is not a valid path").arg(device),
|
tr("\"%1\" is not a valid path").arg(trimmedPath),
|
||||||
tr("Please type another path to register a custom serial device"));
|
tr("Please type another path to register a custom serial device"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,25 +737,28 @@ void IO::Drivers::Serial::refreshSerialDevices()
|
|||||||
{
|
{
|
||||||
// Create device list, starting with dummy header
|
// Create device list, starting with dummy header
|
||||||
// (for a more friendly UI when no devices are attached)
|
// (for a more friendly UI when no devices are attached)
|
||||||
QStringList ports;
|
QStringList names;
|
||||||
ports.append(tr("Select Port"));
|
QStringList locations;
|
||||||
|
locations.append("/dev/null");
|
||||||
|
names.append(tr("Select Port"));
|
||||||
|
|
||||||
// Search for available ports and add them to the lsit
|
// Search for available ports and add them to the lsit
|
||||||
auto validPortList = validPorts();
|
auto validPortList = validPorts();
|
||||||
Q_FOREACH (QSerialPortInfo info, validPortList)
|
Q_FOREACH (QSerialPortInfo info, validPortList)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
if (!info.isNull())
|
||||||
ports.append(info.portName());
|
{
|
||||||
#else
|
names.append(info.portName());
|
||||||
ports.append(info.systemLocation());
|
locations.append(info.systemLocation());
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update list only if necessary
|
// Update list only if necessary
|
||||||
if (portList() != ports)
|
if (m_deviceNames != names)
|
||||||
{
|
{
|
||||||
// Update list
|
// Update list
|
||||||
m_portList = ports;
|
m_deviceNames = names;
|
||||||
|
m_deviceLocations = locations;
|
||||||
|
|
||||||
// Update current port index
|
// Update current port index
|
||||||
bool indexChanged = false;
|
bool indexChanged = false;
|
||||||
@ -784,8 +806,13 @@ void IO::Drivers::Serial::refreshSerialDevices()
|
|||||||
void IO::Drivers::Serial::handleError(QSerialPort::SerialPortError error)
|
void IO::Drivers::Serial::handleError(QSerialPort::SerialPortError error)
|
||||||
{
|
{
|
||||||
if (error != QSerialPort::NoError)
|
if (error != QSerialPort::NoError)
|
||||||
|
{
|
||||||
|
Misc::Utilities::showMessageBox(tr("Critical serial port error"),
|
||||||
|
m_errorDescriptions[error]);
|
||||||
|
|
||||||
Manager::instance().disconnectDevice();
|
Manager::instance().disconnectDevice();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads all the data from the serial port.
|
* Reads all the data from the serial port.
|
||||||
@ -872,6 +899,31 @@ void IO::Drivers::Serial::writeSettings()
|
|||||||
m_settings.setValue(QStringLiteral("IO_DataSource_Serial__BaudRates"), list);
|
m_settings.setValue(QStringLiteral("IO_DataSource_Serial__BaudRates"), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Populates the error descriptions for the serial port driver.
|
||||||
|
*
|
||||||
|
* This function initializes a mapping of QSerialPort error codes to their
|
||||||
|
* corresponding human-readable descriptions. These descriptions provide
|
||||||
|
* detailed context and, where applicable, suggestions for resolving the error.
|
||||||
|
*/
|
||||||
|
void IO::Drivers::Serial::populateErrors()
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
m_errorDescriptions.clear();
|
||||||
|
m_errorDescriptions.insert(QSerialPort::NoError, tr("No error occurred."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::DeviceNotFoundError, tr("The specified device could not be found. Please check the connection and try again."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::PermissionError, tr("Permission denied. Ensure the application has the necessary access rights to the device."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::OpenError, tr("Failed to open the device. It may already be in use or unavailable."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::WriteError, tr("An error occurred while writing data to the device."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::ReadError, tr("An error occurred while reading data from the device."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::ResourceError, tr("A critical resource error occurred. The device may have been disconnected or is no longer accessible."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::UnsupportedOperationError, tr("The requested operation is not supported on this device."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::UnknownError, tr("An unknown error occurred. Please check the device and try again."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::TimeoutError, tr("The operation timed out. The device may not be responding."));
|
||||||
|
m_errorDescriptions.insert(QSerialPort::NotOpenError, tr("The device is not open. Please open the device before attempting this operation."));
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list with all the valid serial port objects
|
* Returns a list with all the valid serial port objects
|
||||||
*/
|
*/
|
||||||
|
@ -44,9 +44,6 @@ class Serial : public HAL_Driver
|
|||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString portName
|
|
||||||
READ portName
|
|
||||||
NOTIFY portChanged)
|
|
||||||
Q_PROPERTY(bool autoReconnect
|
Q_PROPERTY(bool autoReconnect
|
||||||
READ autoReconnect
|
READ autoReconnect
|
||||||
WRITE setAutoReconnect
|
WRITE setAutoReconnect
|
||||||
@ -136,7 +133,6 @@ public:
|
|||||||
[[nodiscard]] quint64 write(const QByteArray &data) override;
|
[[nodiscard]] quint64 write(const QByteArray &data) override;
|
||||||
[[nodiscard]] bool open(const QIODevice::OpenMode mode) override;
|
[[nodiscard]] bool open(const QIODevice::OpenMode mode) override;
|
||||||
|
|
||||||
[[nodiscard]] QString portName() const;
|
|
||||||
[[nodiscard]] QSerialPort *port() const;
|
[[nodiscard]] QSerialPort *port() const;
|
||||||
[[nodiscard]] bool autoReconnect() const;
|
[[nodiscard]] bool autoReconnect() const;
|
||||||
|
|
||||||
@ -180,6 +176,7 @@ private slots:
|
|||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
void readSettings();
|
void readSettings();
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
|
void populateErrors();
|
||||||
void refreshSerialDevices();
|
void refreshSerialDevices();
|
||||||
void handleError(QSerialPort::SerialPortError error);
|
void handleError(QSerialPort::SerialPortError error);
|
||||||
|
|
||||||
@ -206,9 +203,12 @@ private:
|
|||||||
quint8 m_stopBitsIndex;
|
quint8 m_stopBitsIndex;
|
||||||
quint8 m_flowControlIndex;
|
quint8 m_flowControlIndex;
|
||||||
|
|
||||||
QStringList m_portList;
|
QStringList m_deviceNames;
|
||||||
QStringList m_baudRateList;
|
|
||||||
QStringList m_customDevices;
|
QStringList m_customDevices;
|
||||||
|
QStringList m_deviceLocations;
|
||||||
|
|
||||||
|
QStringList m_baudRateList;
|
||||||
|
QMap<QSerialPort::SerialPortError, QString> m_errorDescriptions;
|
||||||
};
|
};
|
||||||
} // namespace Drivers
|
} // namespace Drivers
|
||||||
} // namespace IO
|
} // namespace IO
|
||||||
|
Loading…
x
Reference in New Issue
Block a user