forked from OpenPanzerProject/OP-Config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconsole.cpp
192 lines (155 loc) · 7.59 KB
/
console.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include "console.h"
Console::Console()
{
// Objects
// ---------------------------------------------------------------------------------------------------------------------------------->>
serial = new QSerialPort(this);
// setSettingsRestoredOnClose will be deprecated in QT 6 and beyond. If true, it means QSerialPort will restore the
// previous settings on close, which is the default. Some have found that if prior to opening the DTR was low, QSerialPort
// will set DTR back to low on disconnect. In our case that is not really a terrible problem (it resets the device, which we
// may want to do anyway). The bigger issue is resetting on connect, but we have sort of found a way to work around that.
// Sadly, regardless of what we put this setting to or any other, I can not get QSerialPort to behave consistently with regards
// to DTR on open.
serial->setSettingsRestoredOnClose(false);
// ---------------------------------------------------------------------------------------------------------------------------------->>
// Signals and Slots
// ---------------------------------------------------------------------------------------------------------------------------------->>
// Console Connection connections
connect(this, SIGNAL(ConnectionChanged(boolean)), this, SLOT(ProcessConnectionChange(boolean)));
// Serial connections
connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
}
void Console::begin()
{
Connected = false;
NumErrors = 0;
ClearResponseData();
}
//------------------------------------------------------------------------------------------------------------------------>>
// PORT: OPEN, CLOSE, ETC
//------------------------------------------------------------------------------------------------------------------------>>
void Console::updatePortSettings(QString comName)
{
#define USB_BAUD_RATE QSerialPort::Baud115200
currentPortSettings.name = comName;
currentPortSettings.baudRate = USB_BAUD_RATE;
currentPortSettings.stringBaudRate = QString::number(currentPortSettings.baudRate);
currentPortSettings.dataBits = QSerialPort::Data8;
currentPortSettings.stringDataBits = QStringLiteral("8");
currentPortSettings.parity = QSerialPort::NoParity;
currentPortSettings.stringParity = tr("None");
currentPortSettings.stopBits = QSerialPort::OneStop;
currentPortSettings.stringStopBits = QStringLiteral("1");
currentPortSettings.flowControl = QSerialPort::NoFlowControl; // We don't want hardware flow control
currentPortSettings.stringFlowControl = tr("None");
}
void Console::openSerial(void)
{
serial->setPortName(currentPortSettings.name);
serial->setBaudRate(currentPortSettings.baudRate);
serial->setDataBits(currentPortSettings.dataBits);
serial->setParity(currentPortSettings.parity);
serial->setStopBits(currentPortSettings.stopBits);
serial->setFlowControl(currentPortSettings.flowControl);
if (serial->isOpen()) { serial->close(); } // Close before opening
if (serial->open(QIODevice::ReadWrite)) // This statement can take a while to complete
{ // When checking isDataTerminalReady(), a return value of true means DTR is high, return false means DTR is low.
// However, when using the setDataTerminalReady(bool) function, you set it to to high by passing false, and low by passing true.
// In other words, you use the opposite commands when setting. Although it does make sense given the terminology of the
// functions, it can be confusing.
// On the Arduino boards as well as the TCB, DTR is not used for flow control, instead setting the pin to low causes a hardware reset.
// This can be useful, but if all we want is to communicate, we don't want the host (pc) to set DTR low (mean data terminal is ready) -
// because that will restart the board and we will never get to communicate. So we explicitly set data terminal NOT ready,
// which has the effect of putting DTR high.
// Note, this can only be set after the serial port is open.
serial->setDataTerminalReady(false); // False here means "set DTR pin High"
emit ConnectionChanged(true); // Let the Main window know we successfully opened the COM port
}
else
{
emit ConnectionChanged(false); // Let the Main window know we did not connect
//qDebug() << serial->errorString();
}
}
void Console::closeSerial()
{
// We also try to reset the device
toggleDTR(); // This is the same as resetDevice in OpenPanzerComm. We are probably going to be snooping on Arduino's mostly
// so might as well.
// Close the port
if (serial->isOpen())
{ // Make sure DTR is high at the end, in case it makes any difference next time
serial->setDataTerminalReady(false); // False here means "set DTR pin High"
serial->close();
}
Connected = false;
emit ConnectionChanged(false); // Now we can emit our connection signal
}
void Console::ProcessConnectionChange(boolean connected)
{ // This slot gets called any time the connection status changes
if (connected)
{
// Clear the error count
NumErrors = 0;
}
else
{
}
}
void Console::toggleDTR()
{ // We toggle the DTR pin low. This causes the device to reboot.
if (serial->isOpen())
{
serial->setDataTerminalReady(true); // True here means "set DTR pin Low." This will cause device to reset.
serial->setDataTerminalReady(false); // False here means "set DTR pin High"
}
}
//------------------------------------------------------------------------------------------------------------------------>>
// RECEIVING
//------------------------------------------------------------------------------------------------------------------------>>
void Console::readData()
{
// This is what Console example does
// QByteArray data = serial->readAll();
// console->putData(data);
// Then on the console side, putData is defined as:
// void Console::putData(const QByteArray &data)
// {
// insertPlainText(QString(data));
// QScrollBar *bar = verticalScrollBar();
// bar->setValue(bar->maximum());
// }
responseData += serial->readAll();
emit AnyData(); // Just to let us know something has come in
// while (serial->waitForReadyRead(10))
}
//------------------------------------------------------------------------------------------------------------------------>>
// UTILITIES
//------------------------------------------------------------------------------------------------------------------------>>
void Console::ClearResponseData(void)
{
responseData = 0;
}
boolean Console::isConnected(void)
{
return Connected;
}
//------------------------------------------------------------------------------------------------------------------------>>
// ERROR HANDLING
//------------------------------------------------------------------------------------------------------------------------>>
void Console::handleError(QSerialPort::SerialPortError error)
{
// What the Qt Console example does:
// if (error == QSerialPort::ResourceError)
// {
// qDebug() << serial->errorString();
// closeSerialPort();
// }
// What OpenPanzerComm does: basically ignores anything
if (error != 0)
{
emit CommError(serial->errorString(), serial->error());
serial->clearError();
}
}