QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
SerialGPSTransport.cc
Go to the documentation of this file.
2
4
5#ifdef Q_OS_ANDROID
6#include "qserialport.h"
7#else
8#include <QtSerialPort/QSerialPort>
9#endif
10
11#include <QtCore/QThread>
12
13#include <utility>
14
15QGC_LOGGING_CATEGORY(SerialGPSTransportLog, "GPS.SerialGPSTransport")
16
17SerialGPSTransport::SerialGPSTransport(QString device, const std::atomic_bool &requestStop)
18 : _device(std::move(device))
19 , _requestStop(requestStop)
20{
21}
22
24
26{
27 _serial = std::make_unique<QSerialPort>();
28 _serial->setPortName(_device);
29 if (!_serial->open(QIODevice::ReadWrite)) {
30 // Device can take 10-20s to become accessible after startup.
31 uint32_t retries = 60;
32 while ((retries-- > 0) && !_requestStop && (_serial->error() == QSerialPort::PermissionError)) {
33 qCDebug(SerialGPSTransportLog) << "Cannot open device... retrying";
34 QThread::msleep(500);
35 if (_serial->open(QIODevice::ReadWrite)) {
36 _serial->clearError();
37 break;
38 }
39 }
40
41 if (_serial->error() != QSerialPort::NoError) {
42 qCWarning(SerialGPSTransportLog) << "GPS: Failed to open Serial Device" << _device << _serial->errorString();
43 return false;
44 }
45 }
46
47 (void) _serial->setBaudRate(QSerialPort::Baud9600);
48 (void) _serial->setDataBits(QSerialPort::Data8);
49 (void) _serial->setParity(QSerialPort::NoParity);
50 (void) _serial->setStopBits(QSerialPort::OneStop);
51 (void) _serial->setFlowControl(QSerialPort::NoFlowControl);
52
53 return true;
54}
55
57{
58 return _serial
59 && (_serial->error() != QSerialPort::NoError)
60 && (_serial->error() != QSerialPort::TimeoutError);
61}
62
63int SerialGPSTransport::read(uint8_t *buffer, int length, int timeoutMs)
64{
65 if (_requestStop) {
66 return -1; // abort an in-flight configure/receive so disconnect joins promptly
67 }
68 if (_serial->bytesAvailable() == 0) {
69 if (!_serial->waitForReadyRead(timeoutMs)) {
70 return 0;
71 }
72 }
73 return _serial->read(reinterpret_cast<char *>(buffer), length);
74}
75
76int SerialGPSTransport::write(const uint8_t *buffer, int length)
77{
78 if (_requestStop) {
79 return -1;
80 }
81 int written = 0;
82 while (written < length) {
83 const qint64 n = _serial->write(reinterpret_cast<const char *>(buffer) + written, length - written);
84 if (n < 0) {
85 return -1;
86 }
87 written += static_cast<int>(n);
88 if (!_serial->waitForBytesWritten(kWriteTimeoutMs)) {
89 return -1;
90 }
91 }
92 return written;
93}
94
95bool SerialGPSTransport::setBaudrate(unsigned baudrate)
96{
97 return _serial->setBaudRate(baudrate);
98}
#define QGC_LOGGING_CATEGORY(name, categoryStr)
bool setBaudrate(unsigned baudrate) override
Set the link baud rate. Returns true on success.
bool fatalError() const
True once the port hits an error the receive loop should stop retrying past.
int write(const uint8_t *buffer, int length) override
Write length bytes. Returns bytes written, or -1 on error.
~SerialGPSTransport() override
int read(uint8_t *buffer, int length, int timeoutMs) override