Skip to content
Merged
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
141 changes: 97 additions & 44 deletions src/main/fc/fc_msp.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,15 +409,6 @@ static void sbufReadAxisU16(sbuf_t *src, int16_t *arr)
arr[Z] = sbufReadU16(src);
}

static void mspReadRates(sbuf_t *src, uint8_t *rates)
{
for (int i = 0; i < 3; ++i) {
uint8_t v = sbufReadU8(src);
rates[i] = (i == FD_YAW) ? constrain(v, SETTING_YAW_RATE_MIN, SETTING_YAW_RATE_MAX)
: constrain(v, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
}
}

static void mspDeserializeServoParams(sbuf_t *src, uint8_t servoIndex)
{
servoParamsMutable(servoIndex)->min = sbufReadU16(src);
Expand Down Expand Up @@ -2133,6 +2124,46 @@ static void mspFcDataFlashReadCommand(sbuf_t *dst, sbuf_t *src)
}
#endif

typedef struct PACKED {
uint8_t rcRate8; // unused, kept for protocol compatibility
uint8_t stabilizedRcExpo8;
uint8_t rollRate;
uint8_t pitchRate;
uint8_t yawRate;
uint8_t dynPID;
uint8_t throttleRcMid8;
uint8_t throttleRcExpo8;
uint16_t throttlePaBreakpoint;
} mspSetRcTuning_t;
STATIC_ASSERT(sizeof(mspSetRcTuning_t) == 10, mspSetRcTuning_t_size);

typedef struct PACKED {
uint8_t throttleRcMid8;
uint8_t throttleRcExpo8;
uint8_t throttleDynPID;
uint16_t throttlePaBreakpoint;
uint8_t stabilizedRcExpo8;
uint8_t stabilizedRcYawExpo8;
uint8_t stabilizedRollRate;
uint8_t stabilizedPitchRate;
uint8_t stabilizedYawRate;
uint8_t manualRcExpo8;
uint8_t manualRcYawExpo8;
uint8_t manualRollRate;
uint8_t manualPitchRate;
uint8_t manualYawRate;
} mspSetRateProfile_t;
STATIC_ASSERT(sizeof(mspSetRateProfile_t) == 15, mspSetRateProfile_t_size);

typedef struct PACKED {
uint8_t sublinkID;
uint16_t uplinkTXPower;
uint16_t downlinkTXPower;
uint8_t band[4];
uint8_t mode[6];
} mspSetMspRcInfo_t;
STATIC_ASSERT(sizeof(mspSetMspRcInfo_t) == 15, mspSetMspRcInfo_t_size);

static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
{
uint8_t tmp_u8;
Expand Down Expand Up @@ -2242,18 +2273,32 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break;

case MSP_SET_RC_TUNING:
if ((dataSize == 10) || (dataSize == 11)) {
sbufReadU8(src); //Read rcRate8, kept for protocol compatibility reasons
// Lenient gate: accept payloads longer than the current struct from newer
// senders (MSP payloads only gain fields at the end); trailing bytes ignored.
if (dataSize >= sizeof(mspSetRcTuning_t)) {
mspSetRcTuning_t pkt;
if (!sbufReadDataSafe(src, &pkt, sizeof(pkt))) {
return MSP_RESULT_ERROR;
}
sbufAdvance(src, sizeof(pkt)); // sbufReadDataSafe() does not advance src itself

// need to cast away const to set controlProfile
((controlConfig_t*)currentControlProfile)->stabilized.rcExpo8 = sbufReadU8(src);
mspReadRates(src, ((controlConfig_t*)currentControlProfile)->stabilized.rates);
tmp_u8 = sbufReadU8(src);
((controlConfig_t*)currentControlProfile)->throttle.dynPID = MIN(tmp_u8, SETTING_TPA_RATE_MAX);
((controlConfig_t*)currentControlProfile)->throttle.rcMid8 = sbufReadU8(src);
((controlConfig_t*)currentControlProfile)->throttle.rcExpo8 = sbufReadU8(src);
((controlConfig_t*)currentControlProfile)->throttle.pa_breakpoint = sbufReadU16(src);
if (dataSize > 10) {
((controlConfig_t*)currentControlProfile)->stabilized.rcYawExpo8 = sbufReadU8(src);
controlConfig_t *currentControlProfile_p = (controlConfig_t*)currentControlProfile;
currentControlProfile_p->stabilized.rcExpo8 = pkt.stabilizedRcExpo8;
currentControlProfile_p->stabilized.rates[FD_ROLL] = constrain(pkt.rollRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->stabilized.rates[FD_PITCH] = constrain(pkt.pitchRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->stabilized.rates[FD_YAW] = constrain(pkt.yawRate, SETTING_YAW_RATE_MIN, SETTING_YAW_RATE_MAX);
currentControlProfile_p->throttle.dynPID = MIN(pkt.dynPID, SETTING_TPA_RATE_MAX);
currentControlProfile_p->throttle.rcMid8 = pkt.throttleRcMid8;
currentControlProfile_p->throttle.rcExpo8 = pkt.throttleRcExpo8;
currentControlProfile_p->throttle.pa_breakpoint = pkt.throttlePaBreakpoint;

if (dataSize > sizeof(mspSetRcTuning_t)) {
uint8_t rcYawExpo8;
if (!sbufReadDataSafe(src, &rcYawExpo8, sizeof(rcYawExpo8))) {
return MSP_RESULT_ERROR;
}
currentControlProfile_p->stabilized.rcYawExpo8 = rcYawExpo8;
}

schedulePidGainsUpdate();
Expand All @@ -2263,24 +2308,35 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break;

case MSP2_INAV_SET_RATE_PROFILE:
if (dataSize == 15) {
// Lenient gate: accept payloads longer than the current struct from newer
// senders (MSP payloads only gain fields at the end); trailing bytes ignored.
if (dataSize >= sizeof(mspSetRateProfile_t)) {
mspSetRateProfile_t pkt;
if (!sbufReadDataSafe(src, &pkt, sizeof(pkt))) {
return MSP_RESULT_ERROR;
}

controlConfig_t *currentControlProfile_p = (controlConfig_t*)currentControlProfile; // need to cast away const to set controlProfile

// throttle
currentControlProfile_p->throttle.rcMid8 = sbufReadU8(src);
currentControlProfile_p->throttle.rcExpo8 = sbufReadU8(src);
currentControlProfile_p->throttle.dynPID = sbufReadU8(src);
currentControlProfile_p->throttle.pa_breakpoint = sbufReadU16(src);
currentControlProfile_p->throttle.rcMid8 = pkt.throttleRcMid8;
currentControlProfile_p->throttle.rcExpo8 = pkt.throttleRcExpo8;
currentControlProfile_p->throttle.dynPID = pkt.throttleDynPID;
currentControlProfile_p->throttle.pa_breakpoint = pkt.throttlePaBreakpoint;

// stabilized
currentControlProfile_p->stabilized.rcExpo8 = sbufReadU8(src);
currentControlProfile_p->stabilized.rcYawExpo8 = sbufReadU8(src);
mspReadRates(src, currentControlProfile_p->stabilized.rates);
currentControlProfile_p->stabilized.rcExpo8 = pkt.stabilizedRcExpo8;
currentControlProfile_p->stabilized.rcYawExpo8 = pkt.stabilizedRcYawExpo8;
currentControlProfile_p->stabilized.rates[FD_ROLL] = constrain(pkt.stabilizedRollRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->stabilized.rates[FD_PITCH] = constrain(pkt.stabilizedPitchRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->stabilized.rates[FD_YAW] = constrain(pkt.stabilizedYawRate, SETTING_YAW_RATE_MIN, SETTING_YAW_RATE_MAX);

// manual
currentControlProfile_p->manual.rcExpo8 = sbufReadU8(src);
currentControlProfile_p->manual.rcYawExpo8 = sbufReadU8(src);
mspReadRates(src, currentControlProfile_p->manual.rates);
currentControlProfile_p->manual.rcExpo8 = pkt.manualRcExpo8;
currentControlProfile_p->manual.rcYawExpo8 = pkt.manualRcYawExpo8;
currentControlProfile_p->manual.rates[FD_ROLL] = constrain(pkt.manualRollRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->manual.rates[FD_PITCH] = constrain(pkt.manualPitchRate, SETTING_CONSTANT_ROLL_PITCH_RATE_MIN, SETTING_CONSTANT_ROLL_PITCH_RATE_MAX);
currentControlProfile_p->manual.rates[FD_YAW] = constrain(pkt.manualYawRate, SETTING_YAW_RATE_MIN, SETTING_YAW_RATE_MAX);

} else {
return MSP_RESULT_ERROR;
Expand Down Expand Up @@ -3393,23 +3449,20 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break;

case MSP2_COMMON_SET_MSP_RC_INFO: {
if (dataSize >= 15) {
uint8_t sublinkID = sbufReadU8(src);

if (sublinkID == 0) {
rxLinkStatistics.uplinkTXPower = sbufReadU16(src);
rxLinkStatistics.downlinkTXPower = sbufReadU16(src);
if (dataSize >= sizeof(mspSetMspRcInfo_t)) {
mspSetMspRcInfo_t pkt;
if (!sbufReadDataSafe(src, &pkt, sizeof(pkt))) {
return MSP_RESULT_ERROR;
}

for (int i = 0; i < 4; i++) {
rxLinkStatistics.band[i] = sbufReadU8(src);
}
if (pkt.sublinkID == 0) {
rxLinkStatistics.uplinkTXPower = pkt.uplinkTXPower;
rxLinkStatistics.downlinkTXPower = pkt.downlinkTXPower;

memcpy(rxLinkStatistics.band, pkt.band, sizeof(rxLinkStatistics.band));
sl_toupperptr(rxLinkStatistics.band);

for (int i = 0; i < 6; i++) {
rxLinkStatistics.mode[i] = sbufReadU8(src);
}

memcpy(rxLinkStatistics.mode, pkt.mode, sizeof(rxLinkStatistics.mode));
sl_toupperptr(rxLinkStatistics.mode);
}

Expand Down
Loading