-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibapt.h
252 lines (210 loc) · 8.2 KB
/
libapt.h
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#ifndef __APTDEVICE_H__
#define __APTDEVICE_H__
#pragma once
#include <termios.h> // Contains POSIX terminal control definitions
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include "apt_def.h"
#define APT_DEBUG 0
#define APT_MGMSG_SIZE 6
#define APT_SERAIL_DEFAULT_TIMEOUT_MS 1000
#define APT_SERIAL_DEFAULT_BUFFER_SIZE 255
#define APT_SERIAL_DEFAULT_BAUDRATE BaudRate::B_115200
#define APT_SERIAL_DEFAULT_DEVICE "/dev/ttyUSB0"
#define APT_MAX_TIRES 5
#define APT_SLEEP_US 1000
// custom baudrates are not implemented for a complete implementation see
// https://blog.mbedded.ninja/programming/operating-systems/linux/linux-serial-ports-using-c-cpp/
// https://github.com/gbmhunter/CppLinuxSerial/blob/master/src/SerialPort.cpp
namespace aptserial {
// ==================================================================================================================
enum class BaudRate : speed_t {
B_57600 = B57600,
B_115200 = B115200,
B_230400 = B230400,
B_460800 = B460800,
B_500000 = B500000,
B_576000 = B576000,
B_921600 = B921600,
B_1000000 = B1000000,
B_1152000 = B1152000,
B_1500000 = B1500000,
B_2000000 = B2000000,
B_2500000 = B2500000,
B_3000000 = B3000000,
B_3500000 = B3500000,
B_4000000 = B4000000,
};
enum class State {
CLOSED,
OPEN,
};
const std::string timeStamp();
void printData(const std::string _message, const char* _ptrData, const size_t _length);
void printRawData(const std::string _message, const char* _ptrData, const size_t _length);
void LogMessage(const char* _source, const char* _function, const char* _message);
void LogMessage(const char* _source, const std::string& _function, const std::string& _message="");
class SerialPortException : public std::runtime_error {
private:
std::string m_msg;
public:
explicit SerialPortException(const char* _source, const char* _function, const char* _message) : std::runtime_error(_message) {
std::stringstream out;
out << "[" << timeStamp() << "] : " << std::setw(18) << std::string(_source) << " : " << std::setw(30) << std::string(_function) << " : " << std::string(_message);
m_msg = out.str();
}
~SerialPortException() throw() {}
const char *what() const throw() override {
return m_msg.c_str();
}
};
// ---- SerialPort --------------------------------------------------------------------------------------------------
class SerialPort {
private:
int m_fileDescriptor;
std::string m_device;
BaudRate m_baudRate;
speed_t m_baudRateCustom; // future
int32_t m_timeout_ms = APT_SERAIL_DEFAULT_TIMEOUT_MS;
bool m_echo;
State m_state;
std::vector<char> m_readBuffer;
struct termios GetTermios();
void SetTermios(struct termios& _tty);
void ConfigureTermios();
public:
SerialPort(const std::string& _device=APT_SERIAL_DEFAULT_DEVICE, BaudRate _baudRate=APT_SERIAL_DEFAULT_BAUDRATE);
~SerialPort();
void SetDevice(const std::string& _device) {
m_device = _device; m_device = _device;
}
const std::string GetDevice() {
return m_device;
}
void SetBaudRate(BaudRate _baudRate) {
m_baudRate = _baudRate;
}
void SetTimeout(int32_t _timeout_ms) {
m_timeout_ms = _timeout_ms;
}
void SetEcho(bool _echo) {
m_echo = _echo;
}
void Open();
void Close();
size_t Write(const std::vector<char>& _data);
const std::vector<char> Read();
};
// ==================================================================================================================
// ==================================================================================================================
// page 31
struct stCommand {
uint16_t messageId;
uint8_t param1;
uint8_t param2;
uint8_t destination;
uint8_t source;
} __attribute__((packed));
// page 31
struct stDataCommand {
uint16_t messageId;
uint16_t dataLength;
uint8_t destination;
uint8_t source;
} __attribute__((packed));
// #define APT_MGMSG_MAX_DATA_SIZE 0xFFFF // max uint16_t
#define APT_MGMSG_MAX_DATA_SIZE 0xFF
#define APT_MGMSG_SIZE 6
union uHeader {
struct stCommand command;
struct stDataCommand dataCommand;
char raw[APT_MGMSG_SIZE] = {0}; // guarantee zeros
};
// page 47
struct stHWInfo {
uint32_t serial = 0x00000000;
char model[8] = {0};
uint16_t type;
struct stFW {
uint8_t minor = 0x00;
uint8_t interim = 0x00;
uint8_t major = 0x00;
uint8_t unused = 0x00;
} __attribute__((packed)) fw;
char internal[60] = {0};
uint16_t hw = 0x0000;
uint16_t mod = 0x0000;
uint16_t nChannels = 0x0000;
// char __more[84] = {0};
} __attribute__((packed));
struct stStatus {
uint16_t channel = 0x0000;
uint16_t voltage = 0x0000;
uint16_t position = 0x0000;
uint8_t status[4] = {0};
};
struct HWInfo {
std::string identifier;
std::string serial;
std::string model;
std::string type;
std::string firmware;
std::string hardware;
std::string mod;
int nChannels;
std::string toString() const {
return "identifier: "+identifier+", model: "+model+", serial: "+serial+", type:"+type;
}
};
inline bool operator==(const HWInfo& lhs, const HWInfo& rhs) {
return ((lhs.serial == rhs.serial) && (lhs.model == rhs.model));
}
class IncorrectHeaderException : public SerialPortException {
private:
std::string m_msg;
public:
explicit IncorrectHeaderException(const char* _source, const char* _function) : SerialPortException(_source, _function, "Incorrect Header") {}
~IncorrectHeaderException() throw() {}
const char *what() const throw() override {
return SerialPortException::what();
}
};
// ---- APTDevice ---------------------------------------------------------------------------------------------------
class APTDevice {
protected:
SerialPort m_serialPort;
HWInfo m_hwInfo;
const uint8_t m_idSrcDest;
void updateHWInfo();
size_t Write(const uint16_t _messageId, const uint8_t _destination, const uint8_t _param1=0, const uint8_t _param2=0);
size_t Write(const uint16_t _messageId, const uint8_t _destination, const char* _ptrData, const uint16_t _dataLength);
const std::vector<char> Read(const uint16_t _expectMessageId, const uint8_t _expectLength=0);
const std::vector<char> Try_Write_Read(const uint16_t _messageId, const uint16_t _expectMessageId, const uint8_t _destination, const uint8_t _expectLength=0, const uint8_t _param1=0, const uint8_t _param2=0);
const std::vector<char> Try_Write_Read(const uint16_t _messageId, const uint16_t _expectMessageId, const uint8_t _destination, const char* _ptrData, const uint16_t _dataLength, const uint8_t _expectLength=0);
const std::vector<char> Write_Try_Read(const uint16_t _messageId, const uint16_t _expectMessageId, const uint8_t _destination, const uint8_t _expectLength=0, const uint8_t _param1=0, const uint8_t _param2=0);
const std::vector<char> Write_Try_Read(const uint16_t _messageId, const uint16_t _expectMessageId, const uint8_t _destination, const char* _ptrData, const uint16_t _dataLength, const uint8_t _expectLength=0);
public:
APTDevice(const std::string _deviceFileName, const uint8_t _idSrcDest);
~APTDevice();
HWInfo getHWInfo() {
return m_hwInfo;
}
void stopUpdateMessages();
void identifyDevice(const APT_CHANNEL _channelId);
void setDisplaySettings(const uint16_t _brightness_adu);
void getDisplaySettings(uint16_t& _brightness_adu);
void setChannelEnableState(const APT_STATE _state, const APT_CHANNEL _channelId);
void getChannelEnableState(APT_STATE& _state, const APT_CHANNEL _channelId);
void disconnectDevice();
};
// ------------------------------------------------------------------------------------------------------------------
const std::string channelToString(const APT_CHANNEL _channel);
const bool stringToChannel(const std::string _channelString, APT_CHANNEL& _channel);
const std::string stateToString(const APT_STATE _state);
const bool stringToState(const std::string _stateString, APT_STATE& _state);
}
#endif /* __APTDEVICE_H__ */