diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index ecb40c713..7d2fa3209 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -3816,7 +3816,7 @@ static void executeEscInfoCommand(const char *cmdName, uint8_t escIndex) static void cliDshotProg(const char *cmdName, char *cmdline) { - if (isEmpty(cmdline) || motorConfig()->dev.motorPwmProtocol < PWM_TYPE_DSHOT150) { + if (isEmpty(cmdline) || !isMotorProtocolDshot()) { cliShowParseError(cmdName); return; diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 65ad98f73..77c4d0454 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -276,10 +276,9 @@ static const char * const lookupTableCameraControlMode[] = { #endif static const char * const lookupTablePwmProtocol[] = { - "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT", "BRUSHED", -#ifdef USE_DSHOT - "DSHOT150", "DSHOT300", "DSHOT600", "PROSHOT1000" -#endif + "PWM", "ONESHOT125", "ONESHOT42", "MULTISHOT", "BRUSHED", + "DSHOT150", "DSHOT300", "DSHOT600", "PROSHOT1000", + "DISABLED" }; static const char * const lookupTableRcInterpolation[] = { diff --git a/src/main/config/config.c b/src/main/config/config.c index d4f7ab412..ac17fab05 100644 --- a/src/main/config/config.c +++ b/src/main/config/config.c @@ -509,27 +509,16 @@ static void validateAndFixConfig(void) #endif #endif + bool configuredMotorProtocolDshot = false; + checkMotorProtocolEnabled(&motorConfig()->dev, &configuredMotorProtocolDshot); #if defined(USE_DSHOT) - bool usingDshotProtocol; - switch (motorConfig()->dev.motorPwmProtocol) { - case PWM_TYPE_PROSHOT1000: - case PWM_TYPE_DSHOT600: - case PWM_TYPE_DSHOT300: - case PWM_TYPE_DSHOT150: - usingDshotProtocol = true; - break; - default: - usingDshotProtocol = false; - break; - } - // If using DSHOT protocol disable unsynched PWM as it's meaningless - if (usingDshotProtocol) { + if (configuredMotorProtocolDshot) { motorConfigMutable()->dev.useUnsyncedPwm = false; } #if defined(USE_DSHOT_TELEMETRY) - if ((!usingDshotProtocol || (motorConfig()->dev.useDshotBitbang == DSHOT_BITBANG_OFF && motorConfig()->dev.useBurstDshot == DSHOT_DMAR_ON) || systemConfig()->schedulerOptimizeRate == SCHEDULER_OPTIMIZE_RATE_OFF) + if ((!configuredMotorProtocolDshot || (motorConfig()->dev.useDshotBitbang == DSHOT_BITBANG_OFF && motorConfig()->dev.useBurstDshot == DSHOT_DMAR_ON) || systemConfig()->schedulerOptimizeRate == SCHEDULER_OPTIMIZE_RATE_OFF) && motorConfig()->dev.useDshotTelemetry) { motorConfigMutable()->dev.useDshotTelemetry = false; } @@ -650,8 +639,10 @@ void validateAndFixGyroConfig(void) } if (motorConfig()->dev.useUnsyncedPwm) { + bool configuredMotorProtocolDshot = false; + checkMotorProtocolEnabled(&motorConfig()->dev, &configuredMotorProtocolDshot); // Prevent overriding the max rate of motors - if ((motorConfig()->dev.motorPwmProtocol <= PWM_TYPE_BRUSHED) && (motorConfig()->dev.motorPwmProtocol != PWM_TYPE_STANDARD)) { + if (!configuredMotorProtocolDshot && motorConfig()->dev.motorPwmProtocol != PWM_TYPE_STANDARD) { const uint32_t maxEscRate = lrintf(1.0f / motorUpdateRestriction); motorConfigMutable()->dev.motorPwmRate = MIN(motorConfig()->dev.motorPwmRate, maxEscRate); } diff --git a/src/main/drivers/dshot.c b/src/main/drivers/dshot.c index 777657467..b90fdb381 100644 --- a/src/main/drivers/dshot.c +++ b/src/main/drivers/dshot.c @@ -38,7 +38,6 @@ #include "drivers/motor.h" #include "drivers/timer.h" -#include "drivers/dshot.h" #include "drivers/dshot_dpwm.h" // for motorDmaOutput_t, should be gone #include "drivers/dshot_command.h" #include "drivers/nvic.h" @@ -46,21 +45,20 @@ #include "fc/rc_controls.h" // for flight3DConfig_t -#include "pg/motor.h" - #include "rx/rx.h" +#include "dshot.h" -void dshotInitEndpoints(float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) { +void dshotInitEndpoints(const motorConfig_t *motorConfig, float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) { float outputLimitOffset = (DSHOT_MAX_THROTTLE - DSHOT_MIN_THROTTLE) * (1 - outputLimit); *disarm = DSHOT_CMD_MOTOR_STOP; if (featureIsEnabled(FEATURE_3D)) { - *outputLow = DSHOT_MIN_THROTTLE + ((DSHOT_3D_FORWARD_MIN_THROTTLE - 1 - DSHOT_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig()->digitalIdleOffsetValue); + *outputLow = DSHOT_MIN_THROTTLE + ((DSHOT_3D_FORWARD_MIN_THROTTLE - 1 - DSHOT_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig->digitalIdleOffsetValue); *outputHigh = DSHOT_MAX_THROTTLE - outputLimitOffset / 2; - *deadbandMotor3dHigh = DSHOT_3D_FORWARD_MIN_THROTTLE + ((DSHOT_MAX_THROTTLE - DSHOT_3D_FORWARD_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig()->digitalIdleOffsetValue); + *deadbandMotor3dHigh = DSHOT_3D_FORWARD_MIN_THROTTLE + ((DSHOT_MAX_THROTTLE - DSHOT_3D_FORWARD_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig->digitalIdleOffsetValue); *deadbandMotor3dLow = DSHOT_3D_FORWARD_MIN_THROTTLE - 1 - outputLimitOffset / 2; } else { - *outputLow = DSHOT_MIN_THROTTLE + ((DSHOT_MAX_THROTTLE - DSHOT_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig()->digitalIdleOffsetValue); + *outputLow = DSHOT_MIN_THROTTLE + ((DSHOT_MAX_THROTTLE - DSHOT_MIN_THROTTLE) / 100.0f) * CONVERT_PARAMETER_TO_PERCENT(motorConfig->digitalIdleOffsetValue); *outputHigh = DSHOT_MAX_THROTTLE - outputLimitOffset; } } diff --git a/src/main/drivers/dshot.h b/src/main/drivers/dshot.h index c88c1643d..4c69e19f9 100644 --- a/src/main/drivers/dshot.h +++ b/src/main/drivers/dshot.h @@ -22,6 +22,8 @@ #include "common/time.h" +#include "pg/motor.h" + #define DSHOT_MIN_THROTTLE 48 #define DSHOT_MAX_THROTTLE 2047 #define DSHOT_3D_FORWARD_MIN_THROTTLE 1048 @@ -53,7 +55,7 @@ typedef struct dshotProtocolControl_s { bool requestTelemetry; } dshotProtocolControl_t; -void dshotInitEndpoints(float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow); +void dshotInitEndpoints(const motorConfig_t *motorConfig, float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow); float dshotConvertFromExternal(uint16_t externalValue); uint16_t dshotConvertToExternal(float motorValue); diff --git a/src/main/drivers/dshot_dpwm.h b/src/main/drivers/dshot_dpwm.h index 4f1fefe53..55bcb854a 100644 --- a/src/main/drivers/dshot_dpwm.h +++ b/src/main/drivers/dshot_dpwm.h @@ -22,6 +22,7 @@ #pragma once +#include "drivers/dshot.h" #include "drivers/motor.h" #define MOTOR_DSHOT600_HZ MHZ_TO_HZ(12) @@ -155,8 +156,6 @@ typedef struct motorDmaOutput_s { motorDmaOutput_t *getMotorDmaOutput(uint8_t index); -bool isMotorProtocolDshot(void); - void pwmWriteDshotInt(uint8_t index, uint16_t value); bool pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output); #ifdef USE_DSHOT_TELEMETRY diff --git a/src/main/drivers/motor.c b/src/main/drivers/motor.c index 6fe7dc769..c51bd5610 100644 --- a/src/main/drivers/motor.c +++ b/src/main/drivers/motor.c @@ -33,8 +33,6 @@ #include "config/feature.h" #include "drivers/dshot.h" // for DSHOT_ constants in initEscEndpoints; may be gone in the future - -#include "drivers/motor.h" #include "drivers/pwm_output.h" // for PWM_TYPE_* and others #include "drivers/time.h" #include "drivers/dshot_bitbang.h" @@ -42,10 +40,13 @@ #include "fc/rc_controls.h" // for flight3DConfig_t -#include "pg/motor.h" +#include "motor.h" static FAST_RAM_ZERO_INIT motorDevice_t *motorDevice; +static bool motorProtocolEnabled = false; +static bool motorProtocolDshot = false; + void motorShutdown(void) { motorDevice->vTable.shutdown(); @@ -78,7 +79,7 @@ int motorCount(void) } // This is not motor generic anymore; should be moved to analog pwm module -static void analogInitEndpoints(float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) { +static void analogInitEndpoints(const motorConfig_t *motorConfig, float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) { if (featureIsEnabled(FEATURE_3D)) { float outputLimitOffset = (flight3DConfig()->limit3d_high - flight3DConfig()->limit3d_low) * (1 - outputLimit) / 2; *disarm = flight3DConfig()->neutral3d; @@ -87,28 +88,69 @@ static void analogInitEndpoints(float outputLimit, float *outputLow, float *outp *deadbandMotor3dHigh = flight3DConfig()->deadband3d_high; *deadbandMotor3dLow = flight3DConfig()->deadband3d_low; } else { - *disarm = motorConfig()->mincommand; - *outputLow = motorConfig()->minthrottle; - *outputHigh = motorConfig()->maxthrottle - ((motorConfig()->maxthrottle - motorConfig()->minthrottle) * (1 - outputLimit)); + *disarm = motorConfig->mincommand; + *outputLow = motorConfig->minthrottle; + *outputHigh = motorConfig->maxthrottle - ((motorConfig->maxthrottle - motorConfig->minthrottle) * (1 - outputLimit)); } } -// End point initialization is called from mixerInit before motorDevInit; can't use vtable... -void motorInitEndpoints(float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) +bool checkMotorProtocolEnabled(const motorDevConfig_t *motorDevConfig, bool *isProtocolDshot) { - switch (motorConfig()->dev.motorPwmProtocol) { + bool enabled = false; + bool isDshot = false; + + switch (motorDevConfig->motorPwmProtocol) { + case PWM_TYPE_STANDARD: + case PWM_TYPE_ONESHOT125: + case PWM_TYPE_ONESHOT42: + case PWM_TYPE_MULTISHOT: + case PWM_TYPE_BRUSHED: + enabled = true; + + break; + #ifdef USE_DSHOT - case PWM_TYPE_PROSHOT1000: - case PWM_TYPE_DSHOT600: - case PWM_TYPE_DSHOT300: case PWM_TYPE_DSHOT150: - dshotInitEndpoints(outputLimit, outputLow, outputHigh, disarm, deadbandMotor3dHigh, deadbandMotor3dLow); + case PWM_TYPE_DSHOT300: + case PWM_TYPE_DSHOT600: + case PWM_TYPE_PROSHOT1000: + enabled = true; + isDshot = true; + break; #endif default: - analogInitEndpoints(outputLimit, outputLow, outputHigh, disarm, deadbandMotor3dHigh, deadbandMotor3dLow); + break; } + + if (isProtocolDshot) { + *isProtocolDshot = isDshot; + } + + return enabled; +} + +static void checkMotorProtocol(const motorDevConfig_t *motorDevConfig) +{ + motorProtocolEnabled = checkMotorProtocolEnabled(motorDevConfig, &motorProtocolDshot); +} + +// End point initialization is called from mixerInit before motorDevInit; can't use vtable... +void motorInitEndpoints(const motorConfig_t *motorConfig, float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3dHigh, float *deadbandMotor3dLow) +{ + checkMotorProtocol(&motorConfig->dev); + + if (isMotorProtocolEnabled()) { + if (!isMotorProtocolDshot()) { + analogInitEndpoints(motorConfig, outputLimit, outputLow, outputHigh, disarm, deadbandMotor3dHigh, deadbandMotor3dLow); + } +#ifdef USE_DSHOT + else { + dshotInitEndpoints(motorConfig, outputLimit, outputLow, outputHigh, disarm, deadbandMotor3dHigh, deadbandMotor3dLow); + } +#endif + } } float motorConvertFromExternal(uint16_t externalValue) @@ -121,8 +163,6 @@ uint16_t motorConvertToExternal(float motorValue) return motorDevice->vTable.convertMotorToExternal(motorValue); } -static bool isDshot = false; // XXX Should go somewhere else - void motorPostInit() { motorDevice->vTable.postInit(); @@ -204,43 +244,36 @@ static motorDevice_t motorNullDevice = { .enabled = false, }; -void motorDevInit(const motorDevConfig_t *motorConfig, uint16_t idlePulse, uint8_t motorCount) { +bool isMotorProtocolEnabled(void) +{ + return motorProtocolEnabled; +} + +bool isMotorProtocolDshot(void) +{ + return motorProtocolDshot; +} + +void motorDevInit(const motorDevConfig_t *motorDevConfig, uint16_t idlePulse, uint8_t motorCount) { memset(motors, 0, sizeof(motors)); - bool useUnsyncedPwm = motorConfig->useUnsyncedPwm; + bool useUnsyncedPwm = motorDevConfig->useUnsyncedPwm; - switch (motorConfig->motorPwmProtocol) { - default: - case PWM_TYPE_STANDARD: - case PWM_TYPE_ONESHOT125: - case PWM_TYPE_ONESHOT42: - case PWM_TYPE_MULTISHOT: - case PWM_TYPE_BRUSHED: - motorDevice = motorPwmDevInit(motorConfig, idlePulse, motorCount, useUnsyncedPwm); - break; - -#ifdef USE_DSHOT - case PWM_TYPE_DSHOT150: - case PWM_TYPE_DSHOT300: - case PWM_TYPE_DSHOT600: - case PWM_TYPE_PROSHOT1000: -#ifdef USE_DSHOT_BITBANG - if (isDshotBitbangActive(motorConfig)) { - motorDevice = dshotBitbangDevInit(motorConfig, motorCount); - } else -#endif - { - motorDevice = dshotPwmDevInit(motorConfig, idlePulse, motorCount, useUnsyncedPwm); + if (isMotorProtocolEnabled()) { + if (!isMotorProtocolDshot()) { + motorDevice = motorPwmDevInit(motorDevConfig, idlePulse, motorCount, useUnsyncedPwm); } - - isDshot = true; - break; +#ifdef USE_DSHOT + else { +#ifdef USE_DSHOT_BITBANG + if (isDshotBitbangActive(motorDevConfig)) { + motorDevice = dshotBitbangDevInit(motorDevConfig, motorCount); + } else #endif - -#if 0 // not yet - case PWM_TYPE_DSHOT_UART: - //motorDevice = dshotSerialInit(motorConfig, idlePulse, motorCount, useUnsyncedPwm); - break; + { + motorDevice = dshotPwmDevInit(motorDevConfig, idlePulse, motorCount, useUnsyncedPwm); + } + } #endif } @@ -280,11 +313,6 @@ bool motorIsMotorEnabled(uint8_t index) return motorDevice->vTable.isMotorEnabled(index); } -bool isMotorProtocolDshot(void) -{ - return isDshot; -} - #ifdef USE_DSHOT timeMs_t motorGetMotorEnableTimeMs(void) { @@ -293,10 +321,9 @@ timeMs_t motorGetMotorEnableTimeMs(void) #endif #ifdef USE_DSHOT_BITBANG -bool isDshotBitbangActive(const motorDevConfig_t *motorConfig) { - return motorConfig->useDshotBitbang == DSHOT_BITBANG_ON || - (motorConfig->useDshotBitbang == DSHOT_BITBANG_AUTO && motorConfig->useDshotTelemetry && motorConfig->motorPwmProtocol != PWM_TYPE_PROSHOT1000); +bool isDshotBitbangActive(const motorDevConfig_t *motorDevConfig) { + return motorDevConfig->useDshotBitbang == DSHOT_BITBANG_ON || + (motorDevConfig->useDshotBitbang == DSHOT_BITBANG_AUTO && motorDevConfig->useDshotTelemetry && motorDevConfig->motorPwmProtocol != PWM_TYPE_PROSHOT1000); } #endif - #endif // USE_MOTOR diff --git a/src/main/drivers/motor.h b/src/main/drivers/motor.h index 87bff1716..52f3ca201 100644 --- a/src/main/drivers/motor.h +++ b/src/main/drivers/motor.h @@ -24,19 +24,20 @@ #include "common/time.h" +#include "pg/motor.h" + typedef enum { PWM_TYPE_STANDARD = 0, PWM_TYPE_ONESHOT125, PWM_TYPE_ONESHOT42, PWM_TYPE_MULTISHOT, PWM_TYPE_BRUSHED, -#ifdef USE_DSHOT PWM_TYPE_DSHOT150, PWM_TYPE_DSHOT300, PWM_TYPE_DSHOT600, // PWM_TYPE_DSHOT1200, removed PWM_TYPE_PROSHOT1000, -#endif + PWM_TYPE_DISABLED, PWM_TYPE_MAX } motorPwmProtocolTypes_e; @@ -75,14 +76,16 @@ void motorUpdateCompleteNull(void); void motorPostInit(); void motorWriteAll(float *values); -void motorInitEndpoints(float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3DHigh, float *deadbandMotor3DLow); +void motorInitEndpoints(const motorConfig_t *motorConfig, float outputLimit, float *outputLow, float *outputHigh, float *disarm, float *deadbandMotor3DHigh, float *deadbandMotor3DLow); float motorConvertFromExternal(uint16_t externalValue); uint16_t motorConvertToExternal(float motorValue); struct motorDevConfig_s; // XXX Shouldn't be needed once pwm_output* is really cleaned up. void motorDevInit(const struct motorDevConfig_s *motorConfig, uint16_t idlePulse, uint8_t motorCount); +bool checkMotorProtocolEnabled(const motorDevConfig_t *motorConfig, bool *protocolIsDshot); bool isMotorProtocolDshot(void); +bool isMotorProtocolEnabled(void); void motorDisable(void); void motorEnable(void); diff --git a/src/main/fc/core.c b/src/main/fc/core.c index f9ab88eab..8aed83b1b 100644 --- a/src/main/fc/core.c +++ b/src/main/fc/core.c @@ -388,33 +388,37 @@ void updateArmingStatus(void) } #endif + if (!isMotorProtocolEnabled()) { + setArmingDisabled(ARMING_DISABLED_MOTOR_PROTOCOL); + } + if (!isUsingSticksForArming()) { - /* Ignore ARMING_DISABLED_CALIBRATING if we are going to calibrate gyro on first arm */ - bool ignoreGyro = armingConfig()->gyro_cal_on_first_arm - && !(getArmingDisableFlags() & ~(ARMING_DISABLED_ARM_SWITCH | ARMING_DISABLED_CALIBRATING)); - - /* Ignore ARMING_DISABLED_THROTTLE (once arm switch is on) if we are in 3D mode */ - bool ignoreThrottle = featureIsEnabled(FEATURE_3D) - && !IS_RC_MODE_ACTIVE(BOX3D) - && !flight3DConfig()->switched_mode3d - && !(getArmingDisableFlags() & ~(ARMING_DISABLED_ARM_SWITCH | ARMING_DISABLED_THROTTLE)); - - if (!IS_RC_MODE_ACTIVE(BOXARM)) { + if (!IS_RC_MODE_ACTIVE(BOXARM)) { #ifdef USE_RUNAWAY_TAKEOFF - unsetArmingDisabled(ARMING_DISABLED_RUNAWAY_TAKEOFF); + unsetArmingDisabled(ARMING_DISABLED_RUNAWAY_TAKEOFF); #endif - unsetArmingDisabled(ARMING_DISABLED_CRASH_DETECTED); - } + unsetArmingDisabled(ARMING_DISABLED_CRASH_DETECTED); + } - // If arming is disabled and the ARM switch is on - if (isArmingDisabled() - && !ignoreGyro - && !ignoreThrottle - && IS_RC_MODE_ACTIVE(BOXARM)) { - setArmingDisabled(ARMING_DISABLED_ARM_SWITCH); - } else if (!IS_RC_MODE_ACTIVE(BOXARM)) { - unsetArmingDisabled(ARMING_DISABLED_ARM_SWITCH); - } + /* Ignore ARMING_DISABLED_CALIBRATING if we are going to calibrate gyro on first arm */ + bool ignoreGyro = armingConfig()->gyro_cal_on_first_arm + && !(getArmingDisableFlags() & ~(ARMING_DISABLED_ARM_SWITCH | ARMING_DISABLED_CALIBRATING)); + + /* Ignore ARMING_DISABLED_THROTTLE (once arm switch is on) if we are in 3D mode */ + bool ignoreThrottle = featureIsEnabled(FEATURE_3D) + && !IS_RC_MODE_ACTIVE(BOX3D) + && !flight3DConfig()->switched_mode3d + && !(getArmingDisableFlags() & ~(ARMING_DISABLED_ARM_SWITCH | ARMING_DISABLED_THROTTLE)); + + // If arming is disabled and the ARM switch is on + if (isArmingDisabled() + && !ignoreGyro + && !ignoreThrottle + && IS_RC_MODE_ACTIVE(BOXARM)) { + setArmingDisabled(ARMING_DISABLED_ARM_SWITCH); + } else if (!IS_RC_MODE_ACTIVE(BOXARM)) { + unsetArmingDisabled(ARMING_DISABLED_ARM_SWITCH); + } } if (isArmingDisabled()) { @@ -732,7 +736,6 @@ bool isAirmodeActivated() } - /* * processRx called from taskUpdateRxMain */ diff --git a/src/main/fc/runtime_config.c b/src/main/fc/runtime_config.c index d6050e484..290482454 100644 --- a/src/main/fc/runtime_config.c +++ b/src/main/fc/runtime_config.c @@ -32,7 +32,7 @@ uint16_t flightModeFlags = 0; static uint32_t enabledSensors = 0; -// Must be shorter than OSD_WARNINGS_MAX_SIZE (11) to be displayed fully in OSD +// Must be no longer than OSD_WARNINGS_MAX_SIZE (11) to be displayed fully in OSD const char *armingDisableFlagNames[]= { "NOGYRO", "FAILSAFE", @@ -58,6 +58,7 @@ const char *armingDisableFlagNames[]= { "REBOOT_REQD", "DSHOT_BBANG", "NO_ACC_CAL", + "MOTOR_PROTO", "ARMSWITCH", }; diff --git a/src/main/fc/runtime_config.h b/src/main/fc/runtime_config.h index cecdddf85..c8f411856 100644 --- a/src/main/fc/runtime_config.h +++ b/src/main/fc/runtime_config.h @@ -64,7 +64,8 @@ typedef enum { ARMING_DISABLED_REBOOT_REQUIRED = (1 << 21), ARMING_DISABLED_DSHOT_BITBANG = (1 << 22), ARMING_DISABLED_ACC_CALIBRATION = (1 << 23), - ARMING_DISABLED_ARM_SWITCH = (1 << 24), // Needs to be the last element, since it's always activated if one of the others is active when arming + ARMING_DISABLED_MOTOR_PROTOCOL = (1 << 24), + ARMING_DISABLED_ARM_SWITCH = (1 << 25), // Needs to be the last element, since it's always activated if one of the others is active when arming } armingDisableFlags_e; #define ARMING_DISABLE_FLAGS_COUNT (LOG2(ARMING_DISABLED_ARM_SWITCH) + 1) diff --git a/src/main/flight/mixer.c b/src/main/flight/mixer.c index 1753d9a7a..3f1fef56e 100644 --- a/src/main/flight/mixer.c +++ b/src/main/flight/mixer.c @@ -346,7 +346,7 @@ void initEscEndpoints(void) motorOutputLimit = currentPidProfile->motor_output_limit / 100.0f; } - motorInitEndpoints(motorOutputLimit, &motorOutputLow, &motorOutputHigh, &disarmMotorOutput, &deadbandMotor3dHigh, &deadbandMotor3dLow); + motorInitEndpoints(motorConfig(), motorOutputLimit, &motorOutputLow, &motorOutputHigh, &disarmMotorOutput, &deadbandMotor3dHigh, &deadbandMotor3dLow); rcCommandThrottleRange = PWM_RANGE_MAX - PWM_RANGE_MIN; } diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c index 17f407c9c..5171cb850 100644 --- a/src/main/msp/msp.c +++ b/src/main/msp/msp.c @@ -595,41 +595,39 @@ static bool mspCommonProcessOutCommand(int16_t cmdMSP, sbuf_t *dst, mspPostProce #else sbufWriteU8(dst, 0); // 0 == FC #endif + // Target capabilities (uint8) -#define TARGET_HAS_VCP_BIT 0 -#define TARGET_HAS_SOFTSERIAL_BIT 1 -#define TARGET_IS_UNIFIED_BIT 2 -#define TARGET_HAS_FLASH_BOOTLOADER_BIT 3 -#define TARGET_SUPPORTS_CUSTOM_DEFAULTS_BIT 4 -#define TARGET_HAS_CUSTOM_DEFAULTS_BIT 5 -#define TARGET_SUPPORTS_RX_BIND_BIT 6 -#define TARGET_ACC_NEEDS_CALIBRATION_BIT 7 +#define TARGET_HAS_VCP 0 +#define TARGET_HAS_SOFTSERIAL 1 +#define TARGET_IS_UNIFIED 2 +#define TARGET_HAS_FLASH_BOOTLOADER 3 +#define TARGET_SUPPORTS_CUSTOM_DEFAULTS 4 +#define TARGET_HAS_CUSTOM_DEFAULTS 5 +#define TARGET_SUPPORTS_RX_BIND 6 uint8_t targetCapabilities = 0; #ifdef USE_VCP - targetCapabilities |= 1 << TARGET_HAS_VCP_BIT; + targetCapabilities |= BIT(TARGET_HAS_VCP); #endif #if defined(USE_SOFTSERIAL1) || defined(USE_SOFTSERIAL2) - targetCapabilities |= 1 << TARGET_HAS_SOFTSERIAL_BIT; + targetCapabilities |= BIT(TARGET_HAS_SOFTSERIAL); #endif #if defined(USE_UNIFIED_TARGET) - targetCapabilities |= 1 << TARGET_IS_UNIFIED_BIT; + targetCapabilities |= BIT(TARGET_IS_UNIFIED); #endif #if defined(USE_FLASH_BOOT_LOADER) - targetCapabilities |= 1 << TARGET_HAS_FLASH_BOOTLOADER_BIT; + targetCapabilities |= BIT(TARGET_HAS_FLASH_BOOTLOADER); #endif #if defined(USE_CUSTOM_DEFAULTS) - targetCapabilities |= 1 << TARGET_SUPPORTS_CUSTOM_DEFAULTS_BIT; + targetCapabilities |= BIT(TARGET_SUPPORTS_CUSTOM_DEFAULTS); if (hasCustomDefaults()) { - targetCapabilities |= 1 << TARGET_HAS_CUSTOM_DEFAULTS_BIT; + targetCapabilities |= BIT(TARGET_HAS_CUSTOM_DEFAULTS); } #endif #if defined(USE_RX_BIND) - targetCapabilities |= (getRxBindSupported() << TARGET_SUPPORTS_RX_BIND_BIT); -#endif - -#if defined(USE_ACC) - targetCapabilities |= (!accHasBeenCalibrated() << TARGET_ACC_NEEDS_CALIBRATION_BIT); + if (getRxBindSupported()) { + targetCapabilities |= BIT(TARGET_SUPPORTS_RX_BIND); + } #endif sbufWriteU8(dst, targetCapabilities); @@ -667,9 +665,27 @@ static bool mspCommonProcessOutCommand(int16_t cmdMSP, sbuf_t *dst, mspPostProce // Added in API version 1.42 sbufWriteU8(dst, systemConfig()->configurationState); - //Added in API version 1.43 + // Added in API version 1.43 sbufWriteU16(dst, gyro.sampleRateHz); // informational so the configurator can display the correct gyro/pid frequencies in the drop-down + // Configuration warnings / problems (uint32_t) +#define PROBLEM_ACC_NEEDS_CALIBRATION 0 +#define PROBLEM_MOTOR_PROTOCOL_DISABLED 1 + + uint32_t configurationProblems = 0; + +#if defined(USE_ACC) + if (!accHasBeenCalibrated()) { + configurationProblems |= BIT(PROBLEM_ACC_NEEDS_CALIBRATION); + } +#endif + + if (!checkMotorProtocolEnabled(&motorConfig()->dev, NULL)) { + configurationProblems |= BIT(PROBLEM_MOTOR_PROTOCOL_DISABLED); + } + + sbufWriteU32(dst, configurationProblems); + break; } @@ -2454,11 +2470,7 @@ static mspResult_e mspProcessInCommand(mspDescriptor_t srcDesc, int16_t cmdMSP, sbufReadU8(src); // was gyroConfigMutable()->gyro_sync_denom - removed in API 1.43 pidConfigMutable()->pid_process_denom = sbufReadU8(src); motorConfigMutable()->dev.useUnsyncedPwm = sbufReadU8(src); -#ifdef USE_DSHOT - motorConfigMutable()->dev.motorPwmProtocol = constrain(sbufReadU8(src), 0, PWM_TYPE_MAX - 1); -#else - motorConfigMutable()->dev.motorPwmProtocol = constrain(sbufReadU8(src), 0, PWM_TYPE_BRUSHED); -#endif + motorConfigMutable()->dev.motorPwmProtocol = sbufReadU8(src); motorConfigMutable()->dev.motorPwmRate = sbufReadU16(src); if (sbufBytesRemaining(src) >= 2) { motorConfigMutable()->digitalIdleOffsetValue = sbufReadU16(src); diff --git a/src/main/msp/msp_box.c b/src/main/msp/msp_box.c index b20a06253..205fc2733 100644 --- a/src/main/msp/msp_box.c +++ b/src/main/msp/msp_box.c @@ -240,7 +240,9 @@ void initActiveBoxIds(void) } #ifdef USE_DSHOT - if (isMotorProtocolDshot()) { + bool configuredMotorProtocolDshot; + checkMotorProtocolEnabled(&motorConfig()->dev, &configuredMotorProtocolDshot); + if (configuredMotorProtocolDshot) { BME(BOXFLIPOVERAFTERCRASH); } #endif diff --git a/src/main/pg/motor.c b/src/main/pg/motor.c index 0ac02e97a..37c7f667b 100644 --- a/src/main/pg/motor.c +++ b/src/main/pg/motor.c @@ -54,7 +54,7 @@ void pgResetFn_motorConfig(motorConfig_t *motorConfig) { motorConfig->minthrottle = 1070; motorConfig->dev.motorPwmRate = BRUSHLESS_MOTORS_PWM_RATE; - motorConfig->dev.motorPwmProtocol = PWM_TYPE_ONESHOT125; + motorConfig->dev.motorPwmProtocol = PWM_TYPE_DISABLED; } #endif // BRUSHED_MOTORS diff --git a/src/test/unit/arming_prevention_unittest.cc b/src/test/unit/arming_prevention_unittest.cc index 2e89b5e38..57aa92045 100644 --- a/src/test/unit/arming_prevention_unittest.cc +++ b/src/test/unit/arming_prevention_unittest.cc @@ -22,6 +22,7 @@ extern "C" { #include "build/debug.h" #include "common/maths.h" #include "config/feature.h" + #include "pg/motor.h" #include "pg/pg.h" #include "pg/pg_ids.h" #include "pg/rx.h" @@ -55,6 +56,7 @@ extern "C" { PG_REGISTER(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 0); PG_REGISTER(telemetryConfig_t, telemetryConfig, PG_TELEMETRY_CONFIG, 0); PG_REGISTER(failsafeConfig_t, failsafeConfig, PG_FAILSAFE_CONFIG, 0); + PG_REGISTER(motorConfig_t, motorConfig, PG_MOTOR_CONFIG, 0); float rcCommand[4]; int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; @@ -1104,4 +1106,5 @@ extern "C" { timeDelta_t rxGetFrameDelta(timeDelta_t *) { return 0; } void updateRcRefreshRate(timeUs_t) {}; uint16_t getAverageSystemLoadPercent(void) { return 0; } + bool isMotorProtocolEnabled(void) { return true; } } diff --git a/src/test/unit/vtx_unittest.cc b/src/test/unit/vtx_unittest.cc index a456dc15b..221a45e62 100644 --- a/src/test/unit/vtx_unittest.cc +++ b/src/test/unit/vtx_unittest.cc @@ -22,9 +22,6 @@ extern "C" { #include "build/debug.h" #include "common/maths.h" #include "config/feature.h" - #include "pg/pg.h" - #include "pg/pg_ids.h" - #include "pg/rx.h" #include "config/config.h" #include "fc/controlrate_profile.h" #include "fc/core.h" @@ -39,6 +36,10 @@ extern "C" { #include "io/beeper.h" #include "io/gps.h" #include "io/vtx.h" + #include "pg/motor.h" + #include "pg/pg.h" + #include "pg/pg_ids.h" + #include "pg/rx.h" #include "rx/rx.h" #include "scheduler/scheduler.h" #include "sensors/acceleration.h" @@ -57,6 +58,7 @@ extern "C" { PG_REGISTER(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 0); PG_REGISTER(telemetryConfig_t, telemetryConfig, PG_TELEMETRY_CONFIG, 0); PG_REGISTER(failsafeConfig_t, failsafeConfig, PG_FAILSAFE_CONFIG, 0); + PG_REGISTER(motorConfig_t, motorConfig, PG_MOTOR_CONFIG, 0); float rcCommand[4]; int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; @@ -189,4 +191,5 @@ extern "C" { timeDelta_t rxGetFrameDelta(timeDelta_t *) { return 0; } void updateRcRefreshRate(timeUs_t) {}; uint16_t getAverageSystemLoadPercent(void) { return 0; } + bool isMotorProtocolEnabled(void) { return false; } }