LUA: show protocol2 only on receivers with serial1_TX or PWM pins defined (#2999)
[ExpressLRS.git] / src / lib / OTA / OTA.h
blobdb8243cc7d8c891a9487120a1a6a833d6a014f48
1 #ifndef H_OTA
2 #define H_OTA
4 #include <cstddef>
6 #include "crc.h"
7 #include "CRSF.h"
8 #include "crsf_protocol.h"
9 #include "telemetry_protocol.h"
10 #include "FIFO.h"
12 #define OTA4_PACKET_SIZE 8U
13 #define OTA4_CRC_CALC_LEN offsetof(OTA_Packet4_s, crcLow)
14 #define OTA8_PACKET_SIZE 13U
15 #define OTA8_CRC_CALC_LEN offsetof(OTA_Packet8_s, crc)
17 // Packet header types (ota.std.type)
18 #define PACKET_TYPE_RCDATA 0b00
19 #define PACKET_TYPE_MSPDATA 0b01
20 #define PACKET_TYPE_TLM 0b11
21 #define PACKET_TYPE_SYNC 0b10
23 // Mask used to XOR the ModelId into the SYNC packet for ModelMatch
24 #define MODELMATCH_MASK 0x3f
26 typedef struct {
27 uint8_t fhssIndex;
28 uint8_t nonce;
29 uint8_t switchEncMode:1,
30 newTlmRatio:3,
31 rateIndex:4;
32 uint8_t UID3;
33 uint8_t UID4;
34 uint8_t UID5;
35 } PACKED OTA_Sync_s;
37 typedef struct {
38 uint8_t uplink_RSSI_1:7,
39 antenna:1;
40 uint8_t uplink_RSSI_2:7,
41 modelMatch:1;
42 uint8_t lq:7,
43 mspConfirm:1;
44 int8_t SNR;
45 } PACKED OTA_LinkStats_s;
47 typedef struct {
48 uint8_t raw[5]; // 4x 10-bit channels, see PackUInt11ToChannels4x10 for encoding
49 } PACKED OTA_Channels_4x10;
51 typedef struct {
52 // The packet type must always be the low two bits of the first byte of the
53 // packet to match the same placement in OTA_Packet8_s
54 uint8_t type: 2,
55 crcHigh: 6;
56 union {
57 /** PACKET_TYPE_RCDATA **/
58 struct {
59 OTA_Channels_4x10 ch;
60 uint8_t switches:7,
61 ch4:1;
62 } rc;
63 struct {
64 uint32_t packetNum; // LittleEndian
65 uint8_t free[2];
66 } PACKED dbg_linkstats;
67 /** PACKET_TYPE_MSP **/
68 struct {
69 uint8_t packageIndex:7,
70 tlmFlag:1;
71 uint8_t payload[ELRS4_MSP_BYTES_PER_CALL];
72 } msp_ul;
73 /** PACKET_TYPE_SYNC **/
74 OTA_Sync_s sync;
75 /** PACKET_TYPE_TLM **/
76 struct {
77 uint8_t type:ELRS4_TELEMETRY_SHIFT,
78 packageIndex:(8 - ELRS4_TELEMETRY_SHIFT);
79 union {
80 struct {
81 OTA_LinkStats_s stats;
82 uint8_t free;
83 } PACKED ul_link_stats;
84 uint8_t payload[ELRS4_TELEMETRY_BYTES_PER_CALL];
86 } tlm_dl; // PACKET_TYPE_TLM
87 /** PACKET_TYPE_AIRPORT **/
88 struct {
89 uint8_t type:ELRS4_TELEMETRY_SHIFT,
90 count:(8 - ELRS4_TELEMETRY_SHIFT);
91 uint8_t payload[ELRS4_TELEMETRY_BYTES_PER_CALL];
92 } PACKED airport;
94 uint8_t crcLow;
95 } PACKED OTA_Packet4_s;
97 typedef struct {
98 // Like OTA_Packet4_s **the type is always the low two bits of the first byte**,
99 // but they are speficied in each type in the union as the other bits there
100 // are not universal
101 union {
102 /** PACKET_TYPE_RCDATA **/
103 struct {
104 uint8_t packetType: 2,
105 telemetryStatus: 1,
106 uplinkPower: 3, // CRSF_power_level - 1 (1-8 is 0-7 in the air)
107 isHighAux: 1, // true if chHigh are AUX6-9
108 ch4: 1; // AUX1, included up here so ch0 starts on a byte boundary
109 OTA_Channels_4x10 chLow; // CH0-CH3
110 OTA_Channels_4x10 chHigh; // AUX2-5 or AUX6-9
111 } PACKED rc;
112 struct {
113 uint8_t packetType; // actually struct rc's first byte
114 uint32_t packetNum; // LittleEndian
115 uint8_t free[6];
116 } PACKED dbg_linkstats;
117 /** PACKET_TYPE_MSP **/
118 struct {
119 uint8_t packetType: 2,
120 packageIndex: 5,
121 tlmFlag: 1;
122 uint8_t payload[ELRS8_MSP_BYTES_PER_CALL];
123 } msp_ul;
124 /** PACKET_TYPE_SYNC **/
125 struct {
126 uint8_t packetType; // only low 2 bits
127 OTA_Sync_s sync;
128 uint8_t free[4];
129 } PACKED sync;
130 /** PACKET_TYPE_TLM **/
131 struct {
132 uint8_t packetType: 2,
133 containsLinkStats: 1,
134 packageIndex: 5;
135 union {
136 struct {
137 OTA_LinkStats_s stats;
138 uint8_t payload[ELRS8_TELEMETRY_BYTES_PER_CALL - sizeof(OTA_LinkStats_s)];
139 } PACKED ul_link_stats; // containsLinkStats == true
140 uint8_t payload[ELRS8_TELEMETRY_BYTES_PER_CALL]; // containsLinkStats == false
142 } PACKED tlm_dl;
143 /** PACKET_TYPE_AIRPORT **/
144 struct {
145 uint8_t packetType: 2,
146 containsLinkStats: 1,
147 count: 5;
148 uint8_t payload[ELRS8_TELEMETRY_BYTES_PER_CALL];
149 } PACKED airport;
151 uint16_t crc; // crc16 LittleEndian
152 } PACKED OTA_Packet8_s;
154 typedef struct {
155 union {
156 OTA_Packet4_s std;
157 OTA_Packet8_s full;
159 } PACKED OTA_Packet_s;
161 extern bool OtaIsFullRes;
162 extern volatile uint8_t OtaNonce;
163 extern uint16_t OtaCrcInitializer;
164 void OtaUpdateCrcInitFromUid();
166 enum OtaSwitchMode_e { smWideOr8ch = 0, smHybridOr16ch = 1, sm12ch = 2 };
167 void OtaUpdateSerializers(OtaSwitchMode_e const mode, uint8_t packetSize);
168 extern OtaSwitchMode_e OtaSwitchModeCurrent;
170 // CRC
171 typedef bool (*ValidatePacketCrc_t)(OTA_Packet_s * const otaPktPtr);
172 typedef void (*GeneratePacketCrc_t)(OTA_Packet_s * const otaPktPtr);
173 extern ValidatePacketCrc_t OtaValidatePacketCrc;
174 extern GeneratePacketCrc_t OtaGeneratePacketCrc;
175 // Value is implicit leading 1, comment is Koopman formatting (implicit trailing 1) https://users.ece.cmu.edu/~koopman/crc/
176 #define ELRS_CRC_POLY 0x07 // 0x83
177 #define ELRS_CRC14_POLY 0x2E57 // 0x372b
178 #define ELRS_CRC16_POLY 0x3D65 // 0x9eb2
180 #if defined(TARGET_TX) || defined(UNIT_TEST)
181 typedef void (*PackChannelData_t)(OTA_Packet_s * const otaPktPtr, const uint32_t *channelData, bool TelemetryStatus, uint8_t tlmDenom);
182 extern PackChannelData_t OtaPackChannelData;
183 #if defined(UNIT_TEST)
184 void OtaSetHybrid8NextSwitchIndex(uint8_t idx);
185 void OtaSetFullResNextChannelSet(bool next);
186 #endif
187 #endif
189 #if defined(TARGET_RX) || defined(UNIT_TEST)
190 typedef bool (*UnpackChannelData_t)(OTA_Packet_s const * const otaPktPtr, uint32_t *channelData, uint8_t tlmDenom);
191 extern UnpackChannelData_t OtaUnpackChannelData;
192 #endif
194 void OtaPackAirportData(OTA_Packet_s * const otaPktPtr, FIFO<AP_MAX_BUF_LEN> *inputBuffer);
195 void OtaUnpackAirportData(OTA_Packet_s const * const otaPktPtr, FIFO<AP_MAX_BUF_LEN> *outputBuffer);
197 #if defined(DEBUG_RCVR_LINKSTATS)
198 extern uint32_t debugRcvrLinkstatsPacketId;
199 #endif
201 #endif // H_OTA