Skip to content

Commit 3506dbd

Browse files
committed
Rewrite now matches previous features (PROPMAN-31)
- Greatly improved device opening logic (PROPMAN-29) - Previous baud rate now restored after releasing session (PROPMAN-30) - Lengthen reset to improve stability during large Rx (PROPMAN-32) - Prevent manager from multiply connecting sessions/devices (PROPMAN-33) - Custom baud rates are now fully supported (PROPMAN-34) - Add exec() function to PropellerTerminal (PROPMAN-35) - Improved clear() function (PROPMAN-27)
1 parent 359737b commit 3506dbd

File tree

11 files changed

+113
-53
lines changed

11 files changed

+113
-53
lines changed

app/propman/main.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ QStringList devices = manager.listPorts();
3333
QCommandLineOption argList (QStringList() << "l" << "list", QObject::tr("List available devices"));
3434
QCommandLineOption argWrite (QStringList() << "w" << "write", QObject::tr("Write program to EEPROM"));
3535
QCommandLineOption argDevice (QStringList() << "d" << "device", QObject::tr("Device to program (default: first system device)"), "DEV");
36+
QCommandLineOption argBaud (QStringList() << "b" << "baud", QObject::tr("Baud rate for terminal (default: 115200)"), "BAUD");
3637
QCommandLineOption argPin (QStringList() << "p" << "pin", QObject::tr("Pin for GPIO reset"), "PIN");
3738
QCommandLineOption argTerm (QStringList() << "t" << "terminal",QObject::tr("Drop into terminal after download"));
3839
QCommandLineOption argIdentify (QStringList() << "i" << "identify",QObject::tr("Identify device connected at port"));
@@ -41,7 +42,6 @@ QCommandLineOption argClkMode (QStringList() << "clkmode", QObject::tr(
4142
QCommandLineOption argClkFreq (QStringList() << "clkfreq", QObject::tr("Change clock frequency before download"), "FREQ");
4243
QCommandLineOption argHighSpeed (QStringList() << "ultrafast", QObject::tr("Enable two-stage high-speed mode (experimental)"));
4344

44-
4545
int main(int argc, char *argv[])
4646
{
4747
QCoreApplication app(argc, argv);
@@ -61,13 +61,14 @@ int main(int argc, char *argv[])
6161
parser.addOption(argList);
6262
parser.addOption(argWrite);
6363
parser.addOption(argDevice);
64+
parser.addOption(argBaud);
6465
parser.addOption(argPin);
6566
parser.addOption(argTerm);
6667
parser.addOption(argIdentify);
6768
parser.addOption(argInfo);
6869
parser.addOption(argClkMode);
6970
parser.addOption(argClkFreq);
70-
parser.addOption(argHighSpeed);
71+
// parser.addOption(argHighSpeed);
7172

7273
parser.addPositionalArgument("file", QObject::tr("Binary file to download"), "FILE");
7374

@@ -130,6 +131,15 @@ void open_loader(QCommandLineParser &parser, QStringList devices)
130131
error("Device does not exist!");
131132
}
132133

134+
qint32 baudrate = 115200;
135+
if (!parser.value(argBaud).isEmpty())
136+
{
137+
bool ok;
138+
baudrate = parser.value(argBaud).toInt(&ok);
139+
if (baudrate <= 0 || baudrate > 1000000 || !ok)
140+
error(QString("Baud rate %1 is invalid!").arg(baudrate));
141+
}
142+
133143
if (parser.positionalArguments().isEmpty())
134144
{
135145
if (parser.isSet(argTerm))
@@ -168,6 +178,8 @@ void open_loader(QCommandLineParser &parser, QStringList devices)
168178
error("Image is invalid!");
169179

170180

181+
PropellerTerminal terminal(&manager, device, baudrate);
182+
171183
if (parser.isSet(argHighSpeed))
172184
{
173185
// if (!loader.highSpeedUpload(image, parser.isSet(argWrite)))
@@ -178,14 +190,15 @@ void open_loader(QCommandLineParser &parser, QStringList devices)
178190
QObject::connect (&loader, SIGNAL(statusChanged(const QString &)),
179191
&loader, SLOT(message(const QString &)));
180192

181-
if (!loader.upload(image, parser.isSet(argWrite),true,true))
193+
if (!loader.upload(image, parser.isSet(argWrite), true, true))
182194
exit(1);
195+
183196
QObject::disconnect (&loader, SIGNAL(statusChanged(const QString &)),
184197
&loader, SLOT(message(const QString &)));
185198
}
186199

187200
if (parser.isSet(argTerm))
188-
PropellerTerminal terminal(&manager, device);
201+
terminal.exec();
189202
}
190203

191204
void list()

src/device/propellerdevice.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ PropellerDevice::PropellerDevice()
1414
_minimum_timeout = 400;
1515

1616
device.setSettingsRestoredOnClose(false);
17+
device.setBaudRate(115200);
1718

1819
_reset_defaults["ttyAMA"] = "gpio";
1920
_reset_defaults["ttyS"] = "dtr";
@@ -96,15 +97,7 @@ bool PropellerDevice::open()
9697

9798
if (!device.open(QSerialPort::ReadWrite))
9899
{
99-
qCDebug(pdevice) << "Reattempting device open:" << portName();
100-
101-
QTimer wait;
102-
QEventLoop loop;
103-
connect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
104-
wait.start(1000);
105-
loop.exec();
106-
disconnect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
107-
100+
close();
108101
if (!device.open(QSerialPort::ReadWrite))
109102
{
110103
qCDebug(pdevice) << "Failed to open device:" << portName();
@@ -113,7 +106,6 @@ bool PropellerDevice::open()
113106
}
114107

115108
reset();
116-
setBaudRate(115200);
117109

118110
return true;
119111
}
@@ -223,11 +215,27 @@ bool PropellerDevice::reset()
223215
if (_reset == "rts")
224216
{
225217
device.setRequestToSend(true);
218+
219+
QTimer wait;
220+
QEventLoop loop;
221+
connect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
222+
wait.start(20);
223+
loop.exec();
224+
disconnect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
225+
226226
device.setRequestToSend(false);
227227
}
228228
else if (_reset == "dtr")
229229
{
230230
device.setDataTerminalReady(true);
231+
232+
QTimer wait;
233+
QEventLoop loop;
234+
connect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
235+
wait.start(20);
236+
loop.exec();
237+
disconnect(&wait, SIGNAL(timeout()), &loop, SLOT(quit()));
238+
231239
device.setDataTerminalReady(false);
232240
}
233241
else
@@ -269,7 +277,15 @@ quint32 PropellerDevice::resetPeriod()
269277

270278
bool PropellerDevice::isOpen()
271279
{
272-
return device.isOpen();
280+
if (!device.isOpen())
281+
{
282+
if (!open())
283+
{
284+
close();
285+
return open();
286+
}
287+
}
288+
return true;
273289
}
274290

275291
bool PropellerDevice::clear()

src/loader/propellerloader.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ PropellerLoader::PropellerLoader(PropellerManager * manager, const QString & por
3333
_ack = 0;
3434

3535
this->session = new PropellerSession(manager, portname);
36-
session->setBaudRate(115200);
3736

3837
totalTimeout.setSingleShot(true);
3938
handshakeTimeout.setSingleShot(true);
@@ -46,20 +45,20 @@ PropellerLoader::PropellerLoader(PropellerManager * manager, const QString & por
4645
connect(session,&PropellerSession::sendError,
4746
this, &PropellerLoader::error);
4847

49-
QFinalState * s_failure = new QFinalState();
50-
QFinalState * s_success = new QFinalState();
48+
QFinalState * s_failure = new QFinalState();
49+
QFinalState * s_success = new QFinalState();
5150

5251
connect(s_success, SIGNAL(entered()), this, SLOT(success_entry()));
5352
connect(s_failure, SIGNAL(entered()), this, SLOT(failure_entry()));
5453

55-
s_active = new QState();
54+
s_active = new QState();
5655

57-
QState * s_start = new QState(s_active);
58-
QState * s_prepare = new QState(s_active);
59-
QState * s_payload = new QState(s_active);
60-
QState * s_verify = new QState(s_active);
61-
QState * s_write = new QState(s_active);
62-
QState * s_verifywrite = new QState(s_active);
56+
QState * s_start = new QState(s_active);
57+
QState * s_prepare = new QState(s_active);
58+
QState * s_payload = new QState(s_active);
59+
QState * s_verify = new QState(s_active);
60+
QState * s_write = new QState(s_active);
61+
QState * s_verifywrite = new QState(s_active);
6362

6463
s_prepare ->assignProperty(this, "status", tr("Preparing image..."));
6564
s_payload ->assignProperty(this, "status", tr("Downloading to RAM..."));
@@ -72,8 +71,8 @@ PropellerLoader::PropellerLoader(PropellerManager * manager, const QString & por
7271
s_verifywrite->assignProperty(this, "stat", 3);
7372

7473
s_active->setInitialState(s_start);
75-
s_active-> addTransition(this, SIGNAL(failure()), s_failure);
76-
s_active-> addTransition(&machine, SIGNAL(started()), s_prepare);
74+
s_active-> addTransition(this, SIGNAL(failure()), s_failure);
75+
s_active-> addTransition(&machine, SIGNAL(started()), s_prepare);
7776

7877
machine.addState(s_failure);
7978
machine.addState(s_success);
@@ -106,8 +105,6 @@ PropellerLoader::PropellerLoader(PropellerManager * manager, const QString & por
106105
connect(s_verifywrite, SIGNAL(exited()), this, SLOT(acknowledge_exit()));
107106

108107
s_verifywrite->addTransition(this, SIGNAL(success()), s_success);
109-
110-
// connect(this, SIGNAL(statusChanged(const QString &)), this, SLOT(message(const QString &)));
111108
}
112109

113110
PropellerLoader::~PropellerLoader()
@@ -116,7 +113,6 @@ PropellerLoader::~PropellerLoader()
116113
delete session;
117114
}
118115

119-
120116
void PropellerLoader::message(const QString & text)
121117
{
122118
qCDebug(ploader) << qPrintable("["+session->portName()+"]") << qPrintable(text);
@@ -178,7 +174,6 @@ void PropellerLoader::prepare_entry()
178174
_error = NoError;
179175
_completed = 0;
180176
m_stat = 0;
181-
session->setBaudRate(115200);
182177

183178
_command = 2*_write + _run;
184179

@@ -208,7 +203,7 @@ void PropellerLoader::prepare_entry()
208203

209204
void PropellerLoader::handshake_read()
210205
{
211-
// message("BYTES "+QString::number(session->bytesAvailable()));
206+
// qDebug() << "BYTES" << session->bytesAvailable();
212207
if (session->bytesAvailable() == protocol.reply().size() + 4)
213208
{
214209
handshakeTimeout.stop();
@@ -247,7 +242,7 @@ void PropellerLoader::sendpayload_entry()
247242
connect(this, SIGNAL(handshake_received()), this, SLOT(upload_status()));
248243
connect(this, SIGNAL(payload_sent()), this, SLOT(upload_status()));
249244

250-
session->readAll(); // clear mysterious junk data that arrives just before this write().
245+
session->clear(); // clear mysterious junk data that arrives just before this write().
251246
session->write(_payload);
252247
}
253248

@@ -361,6 +356,12 @@ bool PropellerLoader::upload(PropellerImage image, bool write, bool run, bool wa
361356
return false;
362357
}
363358

359+
if (!session->setBaudRate(115200))
360+
{
361+
error("Couldn't set baud rate");
362+
return false;
363+
}
364+
364365
_image = image;
365366
_write = write;
366367
_run = run;

src/manager/connector.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,24 @@ class Connector : public Interface
6969

7070
_target = target;
7171

72-
// qDebug() << "connecting" << this << "to" << _target;
73-
7472
attachSignals();
7573

7674
_attached = true;
7775

76+
// qDebug() << "attached" << this << "to" << _target;
77+
7878
return true;
7979
}
8080

8181
void detach()
8282
{
8383
if (!isAttached()) return;
8484

85-
// qDebug() << "removing" << this << "from" << _target;
86-
8785
detachSignals();
8886

8987
_attached = false;
88+
89+
// qDebug() << "detached" << this;
9090
}
9191

9292
bool isOpen()

src/manager/portmonitor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "portmonitor.h"
22

33
#include "../device/propellerdevice.h"
4+
#include "../util/logging.h"
45

56
PortMonitor::PortMonitor(QObject * parent)
67
: QObject(parent)
@@ -34,6 +35,7 @@ void PortMonitor::check()
3435
if(_ports != newports)
3536
{
3637
_ports = newports;
38+
// qCDebug(pmanager) << "devices changed:" << _ports;
3739
emit listChanged();
3840
}
3941
}

src/manager/propellermanager.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ PropellerManager::~PropellerManager()
2121
bool PropellerManager::beginSession(PropellerSession * session)
2222
{
2323
if (!session) return false;
24+
// qCDebug(pmanager) << "beginning" << session;
2425

2526
SessionInterface * interface = sessions->interface(session);
2627
session->attach(interface);
@@ -31,6 +32,7 @@ bool PropellerManager::beginSession(PropellerSession * session)
3132
void PropellerManager::endSession(PropellerSession * session)
3233
{
3334
if (!session) return;
35+
// qCDebug(pmanager) << "ending" << session;
3436

3537
session->detach();
3638
sessions->remove(session);
@@ -83,12 +85,14 @@ void PropellerManager::release(PropellerSession * session)
8385

8486
void PropellerManager::setPortName(PropellerSession * session, const QString & name)
8587
{
86-
if (name.isEmpty()) return;
87-
8888
SessionInterface * sessionInterface = sessions->interface(session);
8989

90+
91+
bool exists = devices->exists(name);
9092
DeviceInterface * deviceInterface = devices->interface(name);
91-
connect(deviceInterface, SIGNAL(readyRead()), sessions, SLOT(readyBuffer()));
93+
94+
if(!exists)
95+
connect(deviceInterface, SIGNAL(readyRead()), sessions, SLOT(readyBuffer()));
9296

9397
sessionInterface->detach();
9498
sessionInterface->attach(deviceInterface);

src/manager/sessioninterface.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ class SessionInterface : public Connector<DeviceInterface *>
1212

1313
ReadBuffer * _buffer;
1414
bool _reserved;
15+
qint32 _oldbaudrate;
1516

1617
public:
1718
SessionInterface ()
1819
: Connector<DeviceInterface *>()
1920
{
2021
_buffer = new ReadBuffer();
2122
_reserved = false;
23+
_oldbaudrate = 115200;
2224
}
2325

2426
~SessionInterface()
@@ -57,6 +59,16 @@ class SessionInterface : public Connector<DeviceInterface *>
5759
void setReserved(bool reserved)
5860
{
5961
_reserved = reserved;
62+
63+
if (_reserved)
64+
{
65+
_oldbaudrate = _target->baudRate();
66+
}
67+
else
68+
{
69+
// qDebug() << "restoring baud rate to" << _oldbaudrate << "on" << _target->portName();
70+
_target->setBaudRate(_oldbaudrate);
71+
}
6072
}
6173

6274
bool isReserved()

0 commit comments

Comments
 (0)