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
18 #define PACKET_TYPE_DATA 0b01
19 // Uplink only header types
20 #define PACKET_TYPE_RCDATA 0b00
21 #define PACKET_TYPE_SYNC 0b10
22 // Downlink only header types
23 #define PACKET_TYPE_LINKSTATS 0b00
25 // Mask used to XOR the ModelId into the SYNC packet for ModelMatch
26 #define MODELMATCH_MASK 0x3f
32 uint8_t switchEncMode
:1,
41 uint8_t uplink_RSSI_1
:7,
43 uint8_t uplink_RSSI_2
:7,
48 } PACKED OTA_LinkStats_s
;
51 uint8_t raw
[5]; // 4x 10-bit channels, see PackUInt11ToChannels4x10 for encoding
52 } PACKED OTA_Channels_4x10
;
55 // The packet type must always be the low two bits of the first byte of the
56 // packet to match the same placement in OTA_Packet8_s
60 /** PACKET_TYPE_RCDATA **/
67 uint32_t packetNum
; // LittleEndian
69 } PACKED dbg_linkstats
;
70 /** PACKET_TYPE_MSP **/
72 uint8_t packageIndex
:7,
74 uint8_t payload
[ELRS4_MSP_BYTES_PER_CALL
];
76 /** PACKET_TYPE_SYNC **/
78 /** PACKET_TYPE_TLM **/
85 OTA_LinkStats_s stats
;
87 } PACKED ul_link_stats
;
88 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
90 } tlm_dl
; // PACKET_TYPE_TLM
91 /** PACKET_TYPE_AIRPORT **/
95 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
99 } PACKED OTA_Packet4_s
;
102 // Like OTA_Packet4_s **the type is always the low two bits of the first byte**,
103 // but they are speficied in each type in the union as the other bits there
106 /** PACKET_TYPE_RCDATA **/
108 uint8_t packetType
: 2,
110 uplinkPower
: 3, // CRSF_power_level - 1 (1-8 is 0-7 in the air)
111 isHighAux
: 1, // true if chHigh are AUX6-9
112 ch4
: 1; // AUX1, included up here so ch0 starts on a byte boundary
113 OTA_Channels_4x10 chLow
; // CH0-CH3
114 OTA_Channels_4x10 chHigh
; // AUX2-5 or AUX6-9
117 uint8_t packetType
; // actually struct rc's first byte
118 uint32_t packetNum
; // LittleEndian
120 } PACKED dbg_linkstats
;
121 /** PACKET_TYPE_MSP **/
123 uint8_t packetType
: 2,
126 uint8_t payload
[ELRS8_MSP_BYTES_PER_CALL
];
128 /** PACKET_TYPE_SYNC **/
130 uint8_t packetType
; // only low 2 bits
134 /** PACKET_TYPE_TLM **/
136 uint8_t packetType
: 2,
141 OTA_LinkStats_s stats
;
142 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
- sizeof(OTA_LinkStats_s
)];
143 } PACKED ul_link_stats
; // containsLinkStats == true
144 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
]; // containsLinkStats == false
147 /** PACKET_TYPE_AIRPORT **/
149 uint8_t packetType
: 2,
152 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
];
155 uint16_t crc
; // crc16 LittleEndian
156 } PACKED OTA_Packet8_s
;
163 } PACKED OTA_Packet_s
;
165 extern bool OtaIsFullRes
;
166 extern volatile uint8_t OtaNonce
;
167 extern uint16_t OtaCrcInitializer
;
168 void OtaUpdateCrcInitFromUid();
170 enum OtaSwitchMode_e
{ smWideOr8ch
= 0, smHybridOr16ch
= 1, sm12ch
= 2 };
171 void OtaUpdateSerializers(OtaSwitchMode_e
const mode
, uint8_t packetSize
);
172 extern OtaSwitchMode_e OtaSwitchModeCurrent
;
175 typedef bool (*ValidatePacketCrc_t
)(OTA_Packet_s
* const otaPktPtr
);
176 typedef void (*GeneratePacketCrc_t
)(OTA_Packet_s
* const otaPktPtr
);
177 extern ValidatePacketCrc_t OtaValidatePacketCrc
;
178 extern GeneratePacketCrc_t OtaGeneratePacketCrc
;
179 // Value is implicit leading 1, comment is Koopman formatting (implicit trailing 1) https://users.ece.cmu.edu/~koopman/crc/
180 #define ELRS_CRC_POLY 0x07 // 0x83
181 #define ELRS_CRC14_POLY 0x2E57 // 0x372b
182 #define ELRS_CRC16_POLY 0x3D65 // 0x9eb2
184 #if defined(TARGET_TX) || defined(UNIT_TEST)
185 typedef void (*PackChannelData_t
)(OTA_Packet_s
* const otaPktPtr
, const uint32_t *channelData
, bool TelemetryStatus
, uint8_t tlmDenom
);
186 extern PackChannelData_t OtaPackChannelData
;
187 #if defined(UNIT_TEST)
188 void OtaSetHybrid8NextSwitchIndex(uint8_t idx
);
189 void OtaSetFullResNextChannelSet(bool next
);
193 #if defined(TARGET_RX) || defined(UNIT_TEST)
194 typedef bool (*UnpackChannelData_t
)(OTA_Packet_s
const * const otaPktPtr
, uint32_t *channelData
, uint8_t tlmDenom
);
195 extern UnpackChannelData_t OtaUnpackChannelData
;
198 void OtaPackAirportData(OTA_Packet_s
* const otaPktPtr
, FIFO
<AP_MAX_BUF_LEN
> *inputBuffer
);
199 void OtaUnpackAirportData(OTA_Packet_s
const * const otaPktPtr
, FIFO
<AP_MAX_BUF_LEN
> *outputBuffer
);
201 #if defined(DEBUG_RCVR_LINKSTATS)
202 extern uint32_t debugRcvrLinkstatsPacketId
;