Skip to content

Commit 2be5978

Browse files
committed
Use boost serial port API instead of QT due to loss of packets on windows
1 parent 272090a commit 2be5978

File tree

9 files changed

+204
-64
lines changed

9 files changed

+204
-64
lines changed

qt/programmer.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,10 @@ Programmer::~Programmer()
3939

4040
int Programmer::serialPortConnect()
4141
{
42-
serialPort.setPortName(usbDevName);
43-
serialPort.setBaudRate(SERIAL_PORT_SPEED);
44-
45-
if (!serialPort.open(QIODevice::ReadWrite))
42+
if (!serialPort.start(usbDevName.toLatin1(), SERIAL_PORT_SPEED))
4643
{
4744
qCritical() << "Failed to open serial port " << usbDevName << ": " <<
48-
serialPort.errorString();
45+
serialPort.errorString().c_str();
4946
return -1;
5047
}
5148

@@ -54,7 +51,7 @@ int Programmer::serialPortConnect()
5451

5552
void Programmer::serialPortDisconnect()
5653
{
57-
serialPort.close();
54+
serialPort.stop();
5855
}
5956

6057
void Programmer::connectCb(int ret)

qt/programmer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
#define PROGRAMMER_H
88

99
#include <QObject>
10-
#include <QtSerialPort/QSerialPort>
1110
#include <QByteArray>
1211
#include <cstdint>
1312
#include "writer.h"
1413
#include "reader.h"
1514
#include "cmd.h"
1615
#include "parallel_chip_db.h"
1716
#include "spi_chip_db.h"
17+
#include "serial_port.h"
1818

1919
using namespace std;
2020

@@ -44,7 +44,7 @@ class Programmer : public QObject
4444
};
4545
const uint32_t flashPageSize = 0x800;
4646

47-
QSerialPort serialPort;
47+
SerialPort serialPort;
4848
QString usbDevName;
4949
Writer writer;
5050
Reader reader;

qt/qt.pro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#
1010
#-------------------------------------------------
1111

12-
QT += core gui serialport
12+
QT += core gui
1313

1414
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
1515

@@ -34,6 +34,7 @@ SOURCES += main.cpp\
3434
programmer.cpp \
3535
logger.cpp \
3636
buffer_table_model.cpp \
37+
serial_port.cpp \
3738
spi_chip_db.cpp \
3839
spi_chip_db_dialog.cpp \
3940
spi_chip_db_table_model.cpp \
@@ -56,6 +57,7 @@ HEADERS += main_window.h \
5657
logger.h \
5758
buffer_table_model.h \
5859
cmd.h \
60+
serial_port.h \
5961
spi_chip_db.h \
6062
spi_chip_db_dialog.h \
6163
spi_chip_db_table_model.h \
@@ -79,6 +81,8 @@ FORMS += main_window.ui \
7981
QMAKE_CXXFLAGS += -std=c++11 -Wextra -Werror
8082
mingw:QMAKE_CXXFLAGS += -mno-ms-bitfields
8183

84+
LIBS += -lboost_system
85+
8286
DISTFILES += \
8387
nando_parallel_chip_db.csv \
8488
nando_spi_chip_db.csv

qt/reader.cpp

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ int Reader::write(const uint8_t *data, uint32_t len)
3838
qint64 ret;
3939

4040
ret = serialPort->write(reinterpret_cast<const char *>(data), len);
41-
if (ret < 0)
41+
if (!ret)
4242
{
43-
logErr(QString("Failed to write: %1").arg(serialPort->errorString()));
43+
logErr(QString("Failed to write: %1").arg(serialPort->errorString()
44+
.c_str()));
4445
return -1;
4546
}
4647
else if (ret < len)
@@ -58,17 +59,18 @@ int Reader::readStart()
5859
return write(wbuf, wlen);
5960
}
6061

61-
int Reader::read(uint8_t *pbuf, uint32_t len)
62+
int Reader::read(char *pbuf, uint32_t len)
6263
{
6364
qint64 ret;
6465

65-
if (!serialPort->waitForReadyRead(READ_TIMEOUT))
66-
{
67-
logErr("Read data timeout");
68-
return -1;
69-
}
66+
//TODO: handle timeout
67+
// if (!serialPort->waitForReadyRead(READ_TIMEOUT))
68+
// {
69+
// logErr("Read data timeout");
70+
// return -1;
71+
// }
7072

71-
ret = serialPort->read(reinterpret_cast<char *>(pbuf), len);
73+
ret = serialPort->read(pbuf, len);
7274
if (ret < 0)
7375
{
7476
logErr("Failed to read data");
@@ -78,7 +80,7 @@ int Reader::read(uint8_t *pbuf, uint32_t len)
7880
return static_cast<int>(ret);
7981
}
8082

81-
int Reader::handleBadBlock(uint8_t *pbuf, uint32_t len, bool isSkipped)
83+
int Reader::handleBadBlock(char *pbuf, uint32_t len, bool isSkipped)
8284
{
8385
RespBadBlock *badBlock = reinterpret_cast<RespBadBlock *>(pbuf);
8486
size_t size = sizeof(RespBadBlock);
@@ -102,7 +104,7 @@ int Reader::handleBadBlock(uint8_t *pbuf, uint32_t len, bool isSkipped)
102104
return static_cast<int>(size);
103105
}
104106

105-
int Reader::handleError(uint8_t *pbuf, uint32_t len)
107+
int Reader::handleError(char *pbuf, uint32_t len)
106108
{
107109
RespError *err = reinterpret_cast<RespError *>(pbuf);
108110
size_t size = sizeof(RespError);
@@ -116,7 +118,7 @@ int Reader::handleError(uint8_t *pbuf, uint32_t len)
116118
return -1;
117119
}
118120

119-
int Reader::handleProgress(uint8_t *pbuf, uint32_t len)
121+
int Reader::handleProgress(char *pbuf, uint32_t len)
120122
{
121123
RespProgress *resp = reinterpret_cast<RespProgress *>(pbuf);
122124
size_t size = sizeof(RespProgress);
@@ -129,7 +131,7 @@ int Reader::handleProgress(uint8_t *pbuf, uint32_t len)
129131
return static_cast<int>(size);
130132
}
131133

132-
int Reader::handleStatus(uint8_t *pbuf, uint32_t len)
134+
int Reader::handleStatus(char *pbuf, uint32_t len)
133135
{
134136
RespHeader *header = reinterpret_cast<RespHeader *>(pbuf);
135137

@@ -156,7 +158,7 @@ int Reader::handleStatus(uint8_t *pbuf, uint32_t len)
156158
return 0;
157159
}
158160

159-
int Reader::handleData(uint8_t *pbuf, uint32_t len)
161+
int Reader::handleData(char *pbuf, uint32_t len)
160162
{
161163
RespHeader *header = reinterpret_cast<RespHeader *>(pbuf);
162164
uint8_t dataSize = header->info;
@@ -185,7 +187,7 @@ int Reader::handleData(uint8_t *pbuf, uint32_t len)
185187
return static_cast<int>(packetSize);
186188
}
187189

188-
int Reader::handlePacket(uint8_t *pbuf, uint32_t len)
190+
int Reader::handlePacket(char *pbuf, uint32_t len)
189191
{
190192
RespHeader *header = reinterpret_cast<RespHeader *>(pbuf);
191193

@@ -205,7 +207,7 @@ int Reader::handlePacket(uint8_t *pbuf, uint32_t len)
205207
}
206208
}
207209

208-
int Reader::handlePackets(uint8_t *pbuf, uint32_t len)
210+
int Reader::handlePackets(char *pbuf, uint32_t len)
209211
{
210212
int ret;
211213
uint32_t offset = 0;
@@ -229,7 +231,7 @@ int Reader::handlePackets(uint8_t *pbuf, uint32_t len)
229231

230232
int Reader::readData()
231233
{
232-
uint8_t pbuf[BUF_SIZE];
234+
char pbuf[BUF_SIZE];
233235
int len, offset = 0;
234236

235237
do
@@ -257,24 +259,24 @@ int Reader::readData()
257259

258260
int Reader::serialPortCreate()
259261
{
260-
serialPort = new QSerialPort();
262+
serialPort = new SerialPort();
261263

262-
serialPort->setPortName(portName);
263-
serialPort->setBaudRate(baudRate);
264+
//TODO: error handling
265+
// if (!serialPort->open(QIODevice::ReadWrite))
266+
// {
267+
// logErr(QString("Failed to open serial port: %1")
268+
// .arg(serialPort->errorString()));
269+
// return -1;
270+
// }
264271

265-
if (!serialPort->open(QIODevice::ReadWrite))
266-
{
267-
logErr(QString("Failed to open serial port: %1")
268-
.arg(serialPort->errorString()));
269-
return -1;
270-
}
272+
serialPort->start(portName.toLatin1(), baudRate);
271273

272274
return 0;
273275
}
274276

275277
void Reader::serialPortDestroy()
276278
{
277-
serialPort->close();
279+
serialPort->stop();
278280
delete serialPort;
279281
}
280282

qt/reader.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
#define READER_H
88

99
#include <QThread>
10-
#include <QSerialPort>
10+
#include "serial_port.h"
1111

1212
class Reader : public QThread
1313
{
1414
Q_OBJECT
1515

16-
QSerialPort *serialPort;
16+
SerialPort *serialPort;
1717
QString portName;
1818
qint32 baudRate;
1919
uint8_t *rbuf;
@@ -30,14 +30,14 @@ class Reader : public QThread
3030
void serialPortDestroy();
3131
int write(const uint8_t *data, uint32_t len);
3232
int readStart();
33-
int read(uint8_t *pbuf, uint32_t len);
34-
int handleError(uint8_t *pbuf, uint32_t len);
35-
int handleProgress(uint8_t *pbuf, uint32_t len);
36-
int handleBadBlock(uint8_t *pbuf, uint32_t len, bool isSkipped);
37-
int handleStatus(uint8_t *pbuf, uint32_t len);
38-
int handleData(uint8_t *pbuf, uint32_t len);
39-
int handlePacket(uint8_t *pbuf, uint32_t len);
40-
int handlePackets(uint8_t *pbuf, uint32_t len);
33+
int read(char *pbuf, uint32_t len);
34+
int handleError(char *pbuf, uint32_t len);
35+
int handleProgress(char *pbuf, uint32_t len);
36+
int handleBadBlock(char *pbuf, uint32_t len, bool isSkipped);
37+
int handleStatus(char *pbuf, uint32_t len);
38+
int handleData(char *pbuf, uint32_t len);
39+
int handlePacket(char *pbuf, uint32_t len);
40+
int handlePackets(char *pbuf, uint32_t len);
4141
int readData();
4242
void run() override;
4343
void logErr(const QString& msg);

qt/serial_port.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* Copyright (C) 2020 NANDO authors
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License version 3.
4+
*/
5+
6+
#include "serial_port.h"
7+
8+
SerialPort::SerialPort()
9+
{
10+
}
11+
12+
SerialPort::~SerialPort()
13+
{
14+
stop();
15+
}
16+
17+
int SerialPort::write(const char *buf, int size)
18+
{
19+
int ret;
20+
21+
if (!port)
22+
return -1;
23+
24+
if (!size)
25+
return 0;
26+
27+
if (!(ret = port->write_some(boost::asio::buffer(buf, size), ec)))
28+
return -1;
29+
30+
return ret;
31+
}
32+
33+
int SerialPort::read(char *buf, int size)
34+
{
35+
int ret;
36+
37+
if (!port || !port.get() || !port->is_open())
38+
return -1;
39+
40+
if (!(ret = port->read_some(boost::asio::buffer(buf, size), ec)))
41+
return -1;
42+
43+
return ret;
44+
}
45+
46+
std::string SerialPort::errorString()
47+
{
48+
return ec.message();
49+
}
50+
51+
bool SerialPort::start(const char *portName, int baudRate)
52+
{
53+
boost::system::error_code ec;
54+
55+
if (port)
56+
{
57+
std::cout << "error : port is already opened..." << std::endl;
58+
return false;
59+
}
60+
61+
port = serial_port_ptr(new boost::asio::serial_port(ioService));
62+
port->open(portName, ec);
63+
if (ec)
64+
{
65+
std::cout << "error : port_->open() failed...com_port_name="
66+
<< portName << ", e=" << ec.message().c_str() << std::endl;
67+
return false;
68+
}
69+
70+
port->set_option(boost::asio::serial_port_base::baud_rate(baudRate));
71+
port->set_option(boost::asio::serial_port_base::character_size(8));
72+
port->set_option(boost::asio::serial_port_base::
73+
stop_bits(boost::asio::serial_port_base::stop_bits::one));
74+
port->set_option(boost::asio::serial_port_base::
75+
parity(boost::asio::serial_port_base::parity::none));
76+
port->set_option(boost::asio::serial_port_base::
77+
flow_control(boost::asio::serial_port_base::flow_control::none));
78+
79+
return true;
80+
}
81+
82+
void SerialPort::stop()
83+
{
84+
if (port)
85+
{
86+
port->cancel();
87+
port->close();
88+
port.reset();
89+
port = nullptr;
90+
}
91+
92+
ioService.stop();
93+
ioService.reset();
94+
}

0 commit comments

Comments
 (0)