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
30 uint8_t switchEncMode
:1,
39 uint8_t uplink_RSSI_1
:7,
41 uint8_t uplink_RSSI_2
:7,
46 } PACKED OTA_LinkStats_s
;
49 uint8_t raw
[5]; // 4x 10-bit channels, see PackUInt11ToChannels4x10 for encoding
50 } PACKED OTA_Channels_4x10
;
53 // The packet type must always be the low two bits of the first byte of the
54 // packet to match the same placement in OTA_Packet8_s
58 /** PACKET_TYPE_RCDATA **/
65 uint32_t packetNum
; // LittleEndian
67 } PACKED dbg_linkstats
;
68 /** PACKET_TYPE_MSP **/
70 uint8_t packageIndex
:7,
72 uint8_t payload
[ELRS4_MSP_BYTES_PER_CALL
];
74 /** PACKET_TYPE_SYNC **/
76 /** PACKET_TYPE_TLM **/
78 uint8_t type
:ELRS4_TELEMETRY_SHIFT
,
79 packageIndex
:(8 - ELRS4_TELEMETRY_SHIFT
);
82 OTA_LinkStats_s stats
;
84 } PACKED ul_link_stats
;
85 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
87 } tlm_dl
; // PACKET_TYPE_TLM
88 /** PACKET_TYPE_AIRPORT **/
90 uint8_t type
:ELRS4_TELEMETRY_SHIFT
,
91 count
:(8 - ELRS4_TELEMETRY_SHIFT
);
92 uint8_t payload
[ELRS4_TELEMETRY_BYTES_PER_CALL
];
96 } PACKED OTA_Packet4_s
;
99 // Like OTA_Packet4_s **the type is always the low two bits of the first byte**,
100 // but they are speficied in each type in the union as the other bits there
103 /** PACKET_TYPE_RCDATA **/
105 uint8_t packetType
: 2,
107 uplinkPower
: 3, // CRSF_power_level - 1 (1-8 is 0-7 in the air)
108 isHighAux
: 1, // true if chHigh are AUX6-9
109 ch4
: 1; // AUX1, included up here so ch0 starts on a byte boundary
110 OTA_Channels_4x10 chLow
; // CH0-CH3
111 OTA_Channels_4x10 chHigh
; // AUX2-5 or AUX6-9
114 uint8_t packetType
; // actually struct rc's first byte
115 uint32_t packetNum
; // LittleEndian
117 } PACKED dbg_linkstats
;
118 /** PACKET_TYPE_MSP **/
120 uint8_t packetType
: 2,
123 uint8_t payload
[ELRS8_MSP_BYTES_PER_CALL
];
125 /** PACKET_TYPE_SYNC **/
127 uint8_t packetType
; // only low 2 bits
131 /** PACKET_TYPE_TLM **/
133 uint8_t packetType
: 2,
134 containsLinkStats
: 1,
138 OTA_LinkStats_s stats
;
139 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
- sizeof(OTA_LinkStats_s
)];
140 } PACKED ul_link_stats
; // containsLinkStats == true
141 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
]; // containsLinkStats == false
144 /** PACKET_TYPE_AIRPORT **/
146 uint8_t packetType
: 2,
147 containsLinkStats
: 1,
149 uint8_t payload
[ELRS8_TELEMETRY_BYTES_PER_CALL
];
152 uint16_t crc
; // crc16 LittleEndian
153 } PACKED OTA_Packet8_s
;
160 } PACKED OTA_Packet_s
;
162 extern bool OtaIsFullRes
;
163 extern volatile uint8_t OtaNonce
;
164 extern uint16_t OtaCrcInitializer
;
165 void OtaUpdateCrcInitFromUid();
167 enum OtaSwitchMode_e
{ smWideOr8ch
= 0, smHybridOr16ch
= 1, sm12ch
= 2 };
168 void OtaUpdateSerializers(OtaSwitchMode_e
const mode
, uint8_t packetSize
);
169 extern OtaSwitchMode_e OtaSwitchModeCurrent
;
172 typedef bool (*ValidatePacketCrc_t
)(OTA_Packet_s
* const otaPktPtr
);
173 typedef void (*GeneratePacketCrc_t
)(OTA_Packet_s
* const otaPktPtr
);
174 extern ValidatePacketCrc_t OtaValidatePacketCrc
;
175 extern GeneratePacketCrc_t OtaGeneratePacketCrc
;
176 // Value is implicit leading 1, comment is Koopman formatting (implicit trailing 1) https://users.ece.cmu.edu/~koopman/crc/
177 #define ELRS_CRC_POLY 0x07 // 0x83
178 #define ELRS_CRC14_POLY 0x2E57 // 0x372b
179 #define ELRS_CRC16_POLY 0x3D65 // 0x9eb2
181 #if defined(TARGET_TX) || defined(UNIT_TEST)
182 typedef void (*PackChannelData_t
)(OTA_Packet_s
* const otaPktPtr
, const uint32_t *channelData
, bool TelemetryStatus
, uint8_t tlmDenom
);
183 extern PackChannelData_t OtaPackChannelData
;
184 #if defined(UNIT_TEST)
185 void OtaSetHybrid8NextSwitchIndex(uint8_t idx
);
186 void OtaSetFullResNextChannelSet(bool next
);
190 #if defined(TARGET_RX) || defined(UNIT_TEST)
191 typedef bool (*UnpackChannelData_t
)(OTA_Packet_s
const * const otaPktPtr
, uint32_t *channelData
, uint8_t tlmDenom
);
192 extern UnpackChannelData_t OtaUnpackChannelData
;
195 void OtaPackAirportData(OTA_Packet_s
* const otaPktPtr
, FIFO
<AP_MAX_BUF_LEN
> *inputBuffer
);
196 void OtaUnpackAirportData(OTA_Packet_s
const * const otaPktPtr
, FIFO
<AP_MAX_BUF_LEN
> *outputBuffer
);
198 #if defined(DEBUG_RCVR_LINKSTATS)
199 extern uint32_t debugRcvrLinkstatsPacketId
;