Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/AlfredoCRSF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ void AlfredoCRSF::handleByteReceived()
if (_rxBufPos > 1)
{
uint8_t len = _rxBuf[1];
// Sanity check the declared length, can't be shorter than Type, X, CRC
if (len < 3 || len > CRSF_MAX_PACKET_LEN)
// Length covers Type + payload + CRC. ELRS 4.0 (PR #3429) allows
// broadcast frames with zero payload, so the minimum value is 2.
if (len < 2 || len > (CRSF_MAX_PACKET_LEN - 2))
{
shiftRxBuffer(1);
reprocess = true;
Expand Down Expand Up @@ -94,6 +95,9 @@ void AlfredoCRSF::checkLinkDown()
void AlfredoCRSF::processPacketIn(uint8_t len)
{
const crsf_header_t *hdr = (crsf_header_t *)_rxBuf;
// ELRS 4.0 forces 0xC8 (CRSF_SYNC_BYTE / FLIGHT_CONTROLLER) on the serial
// wire for every frame, including ATTITUDE which used to be addressed to
// RADIO_TRANSMITTER. Handle ATTITUDE here so it parses on a 4.0 RX.
if (hdr->device_addr == CRSF_ADDRESS_FLIGHT_CONTROLLER) //Rx to FC
{
switch (hdr->type)
Expand All @@ -113,8 +117,11 @@ void AlfredoCRSF::processPacketIn(uint8_t len)
case CRSF_FRAMETYPE_VARIO:
packetVario(hdr);
break;
case CRSF_FRAMETYPE_ATTITUDE:
packetAttitude(hdr);
break;
}
}
}
else if (hdr->device_addr == CRSF_ADDRESS_CRSF_TRANSMITTER) //Headset to TX
{
if (hdr->type == CRSF_FRAMETYPE_RC_CHANNELS_PACKED)
Expand Down
52 changes: 25 additions & 27 deletions src/crsf_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,38 +33,30 @@ typedef enum
CRSF_FRAMETYPE_VARIO = 0x07,
CRSF_FRAMETYPE_BATTERY_SENSOR = 0x08,
CRSF_FRAMETYPE_BARO_ALTITUDE = 0x09,
//CRSF_FRAMETYPE_HEARTBEAT = 0x0B, //no need to support? (rev07)
//CRSF_FRAMETYPE_VIDEO_TRANSMITTER = 0x0F, //no need to support? (rev07)
CRSF_FRAMETYPE_AIRSPEED = 0x0A,
CRSF_FRAMETYPE_HEARTBEAT = 0x0B,
CRSF_FRAMETYPE_RPM = 0x0C,
CRSF_FRAMETYPE_TEMP = 0x0D,
CRSF_FRAMETYPE_CELLS = 0x0E,
CRSF_FRAMETYPE_LINK_STATISTICS = 0x14,
// CRSF_FRAMETYPE_OPENTX_SYNC = 0x10, //not in edgeTX
// CRSF_FRAMETYPE_RADIO_ID = 0x3A, //no need to support?
CRSF_FRAMETYPE_RC_CHANNELS_PACKED = 0x16,
// CRSF_FRAMETYPE_LINK_RX_ID = 0x1C, //no need to support?
// CRSF_FRAMETYPE_LINK_TX_ID = 0x1D, //no need to support?
CRSF_FRAMETYPE_ATTITUDE = 0x1E,
// CRSF_FRAMETYPE_FLIGHT_MODE = 0x21, //no need to support?
CRSF_FRAMETYPE_FLIGHT_MODE = 0x21,
// Extended Header Frames, range: 0x28 to 0x96
// CRSF_FRAMETYPE_DEVICE_PING = 0x28, //no "flight controller" needs to know about this
// CRSF_FRAMETYPE_DEVICE_INFO = 0x29, //no "flight controller" needs to know about this
// CRSF_FRAMETYPE_PARAMETER_SETTINGS_ENTRY = 0x2B, //no "flight controller" needs to know about this
// CRSF_FRAMETYPE_PARAMETER_READ = 0x2C, //no "flight controller" needs to know about this
// CRSF_FRAMETYPE_PARAMETER_WRITE = 0x2D, //no "flight controller" needs to know about this
// CRSF_FRAMETYPE_COMMAND = 0x32, //no "flight controller" needs to know about this
// KISS frames
// CRSF_FRAMETYPE_KISS_REQ = 0x78, //not in edgeTX
// CRSF_FRAMETYPE_KISS_RESP = 0x79, //not in edgeTX
// MSP commands
// CRSF_FRAMETYPE_MSP_REQ = 0x7A, //not in edgeTX
// CRSF_FRAMETYPE_MSP_RESP = 0x7B, //not in edgeTX
// CRSF_FRAMETYPE_MSP_WRITE = 0x7C, //not in edgeTX
// Ardupilot frames
// CRSF_FRAMETYPE_ARDUPILOT_RESP = 0x80,
CRSF_FRAMETYPE_DEVICE_PING = 0x28,
CRSF_FRAMETYPE_DEVICE_INFO = 0x29,
CRSF_FRAMETYPE_PARAMETER_SETTINGS_ENTRY = 0x2B,
CRSF_FRAMETYPE_PARAMETER_READ = 0x2C,
CRSF_FRAMETYPE_PARAMETER_WRITE = 0x2D,
CRSF_FRAMETYPE_ELRS_STATUS = 0x2E, // ELRS good/bad packet count and status flags
CRSF_FRAMETYPE_COMMAND = 0x32,
} crsf_frame_type_e;

typedef enum
{
CRSF_ADDRESS_BROADCAST = 0x00,
CRSF_ADDRESS_USB = 0x10,
CRSF_ADDRESS_BLUETOOTH_WIFI = 0x12,
CRSF_ADDRESS_TBS_CORE_PNP_PRO = 0x80,
CRSF_ADDRESS_RESERVED1 = 0x8A,
CRSF_ADDRESS_CURRENT_SENSOR = 0xC0,
Expand All @@ -76,6 +68,7 @@ typedef enum
CRSF_ADDRESS_RADIO_TRANSMITTER = 0xEA,
CRSF_ADDRESS_CRSF_RECEIVER = 0xEC,
CRSF_ADDRESS_CRSF_TRANSMITTER = 0xEE,
CRSF_ADDRESS_ELRS_LUA = 0xEF,
} crsf_addr_e;

typedef struct crsf_header_s
Expand Down Expand Up @@ -106,6 +99,11 @@ typedef struct crsf_channels_s
uint16_t ch15 : 11;
} PACKED crsf_channels_t;

// ELRS appends an extra status byte after crsf_channels_t in the extended
// CHANNELS_PACKED frame; we ignore it but accept the larger payload size.
#define CRSF_CHANNELS_STATUS_ARMED (1 << 0)
#define CRSF_CHANNELS_STATUS_ARMING_MODE_CH5 (1 << 1)

typedef struct crsfPayloadLinkstatistics_s
{
uint8_t uplink_RSSI_1;
Expand All @@ -115,10 +113,10 @@ typedef struct crsfPayloadLinkstatistics_s
uint8_t active_antenna;
uint8_t rf_Mode;
uint8_t uplink_TX_Power;
uint8_t downlink_RSSI;
uint8_t downlink_RSSI; // ELRS 4.0 calls this downlink_RSSI_1
uint8_t downlink_Link_quality;
int8_t downlink_SNR;
} crsfLinkStatistics_t;
} PACKED crsfLinkStatistics_t;

typedef struct crsf_sensor_battery_s
{
Expand Down Expand Up @@ -152,9 +150,9 @@ typedef struct crsf_sensor_baro_altitude_s

typedef struct crsf_sensor_attitude_s
{
uint16_t pitch; // pitch in radians, BigEndian
uint16_t roll; // roll in radians, BigEndian
uint16_t yaw; // yaw in radians, BigEndian
int16_t pitch; // radians * 10000, BigEndian
int16_t roll; // radians * 10000, BigEndian
int16_t yaw; // radians * 10000, BigEndian
} PACKED crsf_sensor_attitude_t;

// Use standard byte order macros for better portability
Expand Down
Loading