Cosmetics
[opentx.git] / radio / src / pulses / pxx2.h
blob6e32742780400b6924c43744cb3748dbcefb25df
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #ifndef _PULSES_PXX2_H_
22 #define _PULSES_PXX2_H_
24 #include "fifo.h"
25 #include "io/frsky_pxx2.h"
26 #include "./pxx.h"
28 #define PXX2_TYPE_C_MODULE 0x01
29 #define PXX2_TYPE_ID_REGISTER 0x01
30 #define PXX2_TYPE_ID_BIND 0x02
31 #define PXX2_TYPE_ID_CHANNELS 0x03
32 #define PXX2_TYPE_ID_TX_SETTINGS 0x04
33 #define PXX2_TYPE_ID_RX_SETTINGS 0x05
34 #define PXX2_TYPE_ID_HW_INFO 0x06
35 #define PXX2_TYPE_ID_SHARE 0x07
36 #define PXX2_TYPE_ID_RESET 0x08
37 #define PXX2_TYPE_ID_AUTHENTICATION 0x09
38 #define PXX2_TYPE_ID_TELEMETRY 0xFE
40 #define PXX2_TYPE_C_POWER_METER 0x02
41 #define PXX2_TYPE_ID_POWER_METER 0x01
42 #define PXX2_TYPE_ID_SPECTRUM 0x02
44 #define PXX2_TYPE_C_OTA 0xFE
45 #define PXX2_TYPE_ID_OTA 0x02
47 #define PXX2_CHANNELS_FLAG0_FAILSAFE (1 << 6)
48 #define PXX2_CHANNELS_FLAG0_RANGECHECK (1 << 7)
50 #define PXX2_RX_SETTINGS_FLAG0_WRITE (1 << 6)
52 #define PXX2_RX_SETTINGS_FLAG1_TELEMETRY_DISABLED (1 << 7)
53 #define PXX2_RX_SETTINGS_FLAG1_READONLY (1 << 6)
54 #define PXX2_RX_SETTINGS_FLAG1_FASTPWM (1 << 4)
55 #define PXX2_RX_SETTINGS_FLAG1_FPORT (1 << 3)
57 #define PXX2_TX_SETTINGS_FLAG0_WRITE (1 << 6)
58 #define PXX2_TX_SETTINGS_FLAG1_EXTERNAL_ANTENNA (1 << 3)
60 #define PXX2_HW_INFO_TX_ID 0xFF
62 #if defined(COLORLCD)
63 #define SPECTRUM_ANALYSER_POWER_FLOOR -120 /*dBm*/
64 #else
65 #define SPECTRUM_ANALYSER_POWER_FLOOR -120 /*dBm*/
66 #endif
68 #define PXX2_AUTH_REFUSED_FLAG 0xA5
70 enum PXX2ModuleModelID {
71 PXX2_MODULE_NONE,
72 PXX2_MODULE_XJT,
73 PXX2_MODULE_ISRM,
74 PXX2_MODULE_ISRM_PRO,
75 PXX2_MODULE_ISRM_S,
76 PXX2_MODULE_R9M,
77 PXX2_MODULE_R9M_LITE,
78 PXX2_MODULE_R9M_LITE_PRO,
79 PXX2_MODULE_ISRM_N,
80 PXX2_MODULE_ISRM_S_X9,
81 PXX2_MODULE_ISRM_S_X10E,
82 PXX2_MODULE_XJT_LITE,
83 PXX2_MODULE_ISRM_S_X10S,
84 PXX2_MODULE_ISRM_S_X9LITE,
87 static const char * const PXX2ModulesNames[] = {
88 "---",
89 "XJT",
90 "ISRM",
91 "ISRM-PRO",
92 "ISRM-S",
93 "R9M",
94 "R9MLite",
95 "R9MLite-PRO",
96 "ISRM-N",
97 "ISRM-S-X9",
98 "ISRM-S-X10E",
99 "XJT Lite",
100 "ISRM-S-X10S",
101 "ISRM-S-X9Lite"
104 inline const char * getPXX2ModuleName(uint8_t modelId)
106 if (modelId < DIM(PXX2ModulesNames))
107 return PXX2ModulesNames[modelId];
108 else
109 return PXX2ModulesNames[0];
112 enum {
113 MODULE_OPTION_EXTERNAL_ANTENNA,
114 MODULE_OPTION_POWER,
115 MODULE_OPTION_SPECTRUM_ANALYSER,
116 MODULE_OPTION_POWER_METER,
119 /* Module options order:
120 * - External antenna (0x01)
121 * - Power (0x02)
122 * - Spektrum analyser (0x04)
123 * - Power meter (0x08)
125 static const uint8_t PXX2ModuleOptions[] = {
126 #if defined(SIMU)
127 0b11111111, // None = display all options on SIMU
128 #else
129 0b00000000, // None = no option available on unknown modules
130 #endif
131 0b00000001, // XJT
132 0b00000001, // ISRM
133 0b00001101, // ISRM-PRO
134 0b00000101, // ISRM-S
135 0b00000010, // R9M
136 0b00000010, // R9MLite
137 0b00000110, // R9MLite-PRO
138 0b00000100, // ISRM-N
139 0b00000100, // ISRM-S-X9
140 0b00000101, // ISRM-S-X10E
141 0b00000001, // XJT_LITE
142 0b00000101, // ISRM-S-X10S
143 0b00000101, // ISRM-S-X9LITE
146 inline uint8_t getPXX2ModuleOptions(uint8_t modelId)
148 if (modelId < DIM(PXX2ModuleOptions))
149 return PXX2ModuleOptions[modelId];
150 else
151 return PXX2ModuleOptions[0];
154 inline bool isPXX2ModuleOptionAvailable(uint8_t modelId, uint8_t option)
156 return getPXX2ModuleOptions(modelId) & (1 << option);
159 enum ModuleCapabilities {
160 MODULE_CAPABILITY_COUNT
163 static const char * const PXX2ReceiversNames[] = {
164 "---",
165 "X8R",
166 "RX8R",
167 "RX8R-PRO",
168 "RX6R",
169 "RX4R",
170 "G-RX8",
171 "G-RX6",
172 "X6R",
173 "X4R",
174 "X4R-SB",
175 "XSR",
176 "XSR-M",
177 "RXSR",
178 "S6R",
179 "S8R",
180 "XM",
181 "XM+",
182 "XMR",
183 "R9",
184 "R9-SLIM",
185 "R9-SLIM+",
186 "R9-MINI",
187 "R9-MM",
188 "R9-STAB",
189 "R9-MINI-OTA", // this one has OTA (different bootloader)
190 "R9-MM-OTA", // this one has OTA (different bootloader)
191 "R9-SLIM+-OTA", // this one has OTA (different bootloader)
194 inline const char * getPXX2ReceiverName(uint8_t modelId)
196 if (modelId < DIM(PXX2ReceiversNames))
197 return PXX2ReceiversNames[modelId];
198 else
199 return PXX2ReceiversNames[0];
202 enum {
203 RECEIVER_OPTION_OTA,
206 /* Receiver options order:
207 * - OTA (0x01)
209 static const uint8_t PXX2ReceiverOptions[] = {
210 #if defined(SIMU)
211 0b11111111, // None = display all options on SIMU
212 #else
213 0b00000000, // None = display all options on SIMU
214 #endif
215 0b11111110, // X8R
216 0b11111110, // RX8R
217 0b11111110, // RX8R-PRO
218 0b11111110, // RX6R
219 0b11111110, // RX4R
220 0b11111110, // G-RX8
221 0b11111110, // G-RX6
222 0b11111110, // X6R
223 0b11111110, // X4R
224 0b11111110, // X4R-SB
225 0b11111110, // XSR
226 0b11111110, // XSR-M
227 0b11111110, // RXSR
228 0b11111110, // S6R
229 0b11111110, // S8R
230 0b11111110, // XM
231 0b11111110, // XM+
232 0b11111110, // XMR
233 0b11111110, // R9
234 0b11111110, // R9-SLIM
235 0b11111110, // R9-SLIM+
236 0b11111110, // R9-MINI
237 0b11111110, // R9-MM
238 0b11111110, // R9-STAB
239 0b11111111, // R9-MINI+OTA
240 0b11111111, // R9-MM+OTA
241 0b11111111, // R9-SLIM+OTA
244 inline uint8_t getPXX2ReceiverOptions(uint8_t modelId)
246 if (modelId < DIM(PXX2ReceiverOptions))
247 return PXX2ReceiverOptions[modelId];
248 else
249 return PXX2ReceiverOptions[0];
252 inline bool isPXX2ReceiverOptionAvailable(uint8_t modelId, uint8_t option)
254 return getPXX2ReceiverOptions(modelId) & (1 << option);
257 enum ReceiverCapabilities {
258 RECEIVER_CAPABILITY_FPORT,
259 RECEIVER_CAPABILITY_COUNT
262 enum PXX2Variant {
263 PXX2_VARIANT_NONE,
264 PXX2_VARIANT_FCC,
265 PXX2_VARIANT_EU,
266 PXX2_VARIANT_FLEX
269 enum PXX2RegisterSteps {
270 REGISTER_INIT,
271 REGISTER_RX_NAME_RECEIVED,
272 REGISTER_RX_NAME_SELECTED,
273 REGISTER_OK
276 enum PXX2BindSteps {
277 BIND_MODULE_TX_INFORMATION_REQUEST = -2,
278 BIND_MODULE_TX_SETTINGS_REQUEST = -1,
279 BIND_INIT,
280 BIND_RX_NAME_SELECTED,
281 BIND_INFO_REQUEST,
282 BIND_START,
283 BIND_WAIT,
284 BIND_OK
287 enum PXX2OtaUpdateSteps {
288 OTA_UPDATE_START = BIND_OK + 1,
289 OTA_UPDATE_START_ACK,
290 OTA_UPDATE_TRANSFER,
291 OTA_UPDATE_TRANSFER_ACK,
292 OTA_UPDATE_EOF,
293 OTA_UPDATE_EOF_ACK
296 enum PXX2ReceiverStatus {
297 PXX2_HARDWARE_INFO,
298 PXX2_SETTINGS_READ,
299 PXX2_SETTINGS_WRITE,
300 PXX2_SETTINGS_OK
303 extern ModuleFifo intmoduleFifo;
304 extern ModuleFifo extmoduleFifo;
306 class Pxx2CrcMixin {
307 protected:
308 void initCrc()
310 crc = 0xFFFF;
313 void addToCrc(uint8_t byte)
315 crc -= byte;
318 uint16_t crc;
321 class Pxx2Transport: public DataBuffer<uint8_t, 64>, public Pxx2CrcMixin {
322 protected:
323 void addWord(uint32_t word)
325 addByte(word);
326 addByte(word >> 8);
327 addByte(word >> 16);
328 addByte(word >> 24);
331 void addByte(uint8_t byte)
333 Pxx2CrcMixin::addToCrc(byte);
334 addByteWithoutCrc(byte);
337 void addByteWithoutCrc(uint8_t byte)
339 *ptr++ = byte;
343 class Pxx2Pulses: public Pxx2Transport {
344 friend class Pxx2OtaUpdate;
346 public:
347 bool setupFrame(uint8_t module);
348 void setupAuthenticationFrame(uint8_t module, uint8_t mode, const uint8_t * outputMessage);
350 protected:
351 void setupHardwareInfoFrame(uint8_t module);
353 void setupRegisterFrame(uint8_t module);
355 void setupAccstBindFrame(uint8_t module);
357 void setupAccessBindFrame(uint8_t module);
359 void setupResetFrame(uint8_t module);
361 void setupShareMode(uint8_t module);
363 void setupModuleSettingsFrame(uint8_t module);
365 void setupReceiverSettingsFrame(uint8_t module);
367 void setupChannelsFrame(uint8_t module);
369 void setupTelemetryFrame(uint8_t module);
371 void setupSpectrumAnalyser(uint8_t module);
373 void setupPowerMeter(uint8_t module);
375 void sendOtaUpdate(uint8_t module, const char * rxName, uint32_t address, const char * data);
377 void addHead()
379 // send 7E, do not CRC
380 Pxx2Transport::addByteWithoutCrc(0x7E);
382 // reserve 1 byte for LEN
383 Pxx2Transport::addByteWithoutCrc(0x00);
386 void addFrameType(uint8_t type_c, uint8_t type_id)
388 // TYPE_C + TYPE_ID
389 Pxx2Transport::addByte(type_c);
390 Pxx2Transport::addByte(type_id);
393 uint8_t addFlag0(uint8_t module);
395 void addFlag1(uint8_t module);
397 void addPulsesValues(uint16_t low, uint16_t high);
399 void addChannels(uint8_t module);
401 void addFailsafe(uint8_t module);
403 void addCrc()
405 Pxx2Transport::addByteWithoutCrc(Pxx2CrcMixin::crc >> 8);
406 Pxx2Transport::addByteWithoutCrc(Pxx2CrcMixin::crc);
409 void initFrame()
411 // init the CRC counter
412 initCrc();
414 // reset the frame pointer
415 Pxx2Transport::initBuffer();
417 // add the frame head
418 addHead();
421 void endFrame()
423 uint8_t size = getSize() - 2;
425 if (size > 0) {
426 // update the frame LEN = frame length minus the 2 first bytes
427 data[1] = getSize() - 2;
429 // now add the CRC
430 addCrc();
432 else {
433 Pxx2Transport::initBuffer();
438 class Pxx2OtaUpdate {
439 public:
440 Pxx2OtaUpdate(uint8_t module, const char * rxName):
441 module(module),
442 rxName(rxName)
446 void flashFirmware(const char * filename);
448 protected:
449 uint8_t module;
450 const char * rxName;
452 const char * doFlashFirmware(const char * filename);
453 bool waitStep(uint8_t step, uint8_t timeout);
454 const char * nextStep(uint8_t step, const char * rxName, uint32_t address, const uint8_t * buffer);
457 #endif