8 #include "crsf_protocol.h"
9 #include "telemetry_protocol.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
29 uint8_t switchEncMode
:1,
38 uint8_t uplink_RSSI_1
:7,
40 uint8_t uplink_RSSI_2
:7,
45 } PACKED OTA_LinkStats_s
;
48 uint8_t raw
[5]; // 4x 10-bit channels, see PackUInt11ToChannels4x10 for encoding
49 } PACKED OTA_Channels_4x10
;
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
57 /** PACKET_TYPE_RCDATA **/
64 uint32_t packetNum
; // LittleEndian
66 } PACKED dbg_linkstats
;
67 /** PACKET_TYPE_MSP **/
69 uint8_t packageIndex
:7,
71 uint8_t payload
[ELRS4_MSP_BYTES_PER_CALL
];
73 /** PACKET_TYPE_SYNC **/
75 /** PACKET_TYPE_TLM **/
77 uint8_t type
:ELRS4_TELEMETRY_SHIFT
,
78 packageIndex
:(8 - ELRS4_TELEMETRY_SHIFT
);
81 OTA_LinkStats_s stats
;
83 } PACKED ul_link_stats
;
84 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
86 } tlm_dl
; // PACKET_TYPE_TLM
87 /** PACKET_TYPE_AIRPORT **/
89 uint8_t type
:ELRS4_TELEMETRY_SHIFT
,
90 count
:(8 - ELRS4_TELEMETRY_SHIFT
);
91 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
95 } PACKED OTA_Packet4_s
;
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
102 /** PACKET_TYPE_RCDATA **/
104 uint8_t packetType
: 2,
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
113 uint8_t packetType
; // actually struct rc's first byte
114 uint32_t packetNum
; // LittleEndian
116 } PACKED dbg_linkstats
;
117 /** PACKET_TYPE_MSP **/
119 uint8_t packetType
: 2,
122 uint8_t payload
[ELRS8_MSP_BYTES_PER_CALL
];
124 /** PACKET_TYPE_SYNC **/
126 uint8_t packetType
; // only low 2 bits
130 /** PACKET_TYPE_TLM **/
132 uint8_t packetType
: 2,
133 containsLinkStats
: 1,
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
143 /** PACKET_TYPE_AIRPORT **/
145 uint8_t packetType
: 2,
146 containsLinkStats
: 1,
148 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
];
151 uint16_t crc
; // crc16 LittleEndian
152 } PACKED OTA_Packet8_s
;
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
;
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
);
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
;
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
;