Example #1
0
void targetConfiguration(void)
{
    // SOFTSERIAL1 is ESC telemetry input
    const int index = findSerialPortIndexByIdentifier(SERIAL_PORT_SOFTSERIAL1);
    if (index >= 0) {
        serialConfigMutable()->portConfigs[index].functionMask = FUNCTION_ESC_SENSOR;
    }
}
Example #2
0
void targetConfiguration(void)
{
    barometerConfigMutable()->baro_hardware = BARO_DEFAULT;
    serialConfigMutable()->portConfigs[1].functionMask = FUNCTION_MSP; // So SPRacingF3OSD users don't have to change anything.
    serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(TELEMETRY_UART)].functionMask = FUNCTION_TELEMETRY_SMARTPORT;
    telemetryConfigMutable()->halfDuplex = 0;
    telemetryConfigMutable()->telemetry_inverted = true;
}
Example #3
0
void targetConfiguration(void)
{
    if (hardwareMotorType == MOTOR_BRUSHED) {
        motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE;
        motorConfigMutable()->minthrottle = 1049;

#if defined(FF_ACROWHOOPSP)
        rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048;
        rxConfigMutable()->spektrum_sat_bind = 5;
        rxConfigMutable()->spektrum_sat_bind_autoreset = 1;
#else
        serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART2)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB;
        rxConfigMutable()->serialrx_inverted = true;
        featureSet(FEATURE_TELEMETRY);
#endif
        parseRcChannels("TAER1234", rxConfigMutable());

        for (uint8_t pidProfileIndex = 0; pidProfileIndex < MAX_PROFILE_COUNT; pidProfileIndex++) {
            pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex);

            pidProfile->pid[PID_ROLL].P = 80;
            pidProfile->pid[PID_ROLL].I = 37;
            pidProfile->pid[PID_ROLL].D = 35;
            pidProfile->pid[PID_PITCH].P = 100;
            pidProfile->pid[PID_PITCH].I = 37;
            pidProfile->pid[PID_PITCH].D = 35;
            pidProfile->pid[PID_YAW].P = 180;
            pidProfile->pid[PID_YAW].D = 45;
        }

        for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) {
            controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex);

            controlRateConfig->rcRates[FD_ROLL] = 100;
            controlRateConfig->rcRates[FD_PITCH] = 100;
            controlRateConfig->rcRates[FD_YAW] = 100;
            controlRateConfig->rcExpo[FD_ROLL] = 15;
            controlRateConfig->rcExpo[FD_PITCH] = 15;
            controlRateConfig->rcExpo[FD_YAW] = 15;
            controlRateConfig->rates[PID_ROLL] = 80;
            controlRateConfig->rates[PID_PITCH] = 80;
            controlRateConfig->rates[PID_YAW] = 80;
        }
    }
}
Example #4
0
// alternative defaults settings for AlienFlight targets
void targetConfiguration(void)
{
    if (getDetectedMotorType() == MOTOR_BRUSHED) {
        motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE;
        pidConfigMutable()->pid_process_denom = 1;
    }

    if (hardwareRevision == AFF4_REV_1) {
        rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048;
        rxConfigMutable()->spektrum_sat_bind = 5;
        rxConfigMutable()->spektrum_sat_bind_autoreset = 1;
    } else {
        rxConfigMutable()->serialrx_provider = SERIALRX_SBUS;
        rxConfigMutable()->serialrx_inverted = true;
        serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL;
        telemetryConfigMutable()->telemetry_inverted = false;
        batteryConfigMutable()->voltageMeterSource = VOLTAGE_METER_ADC;
        batteryConfigMutable()->currentMeterSource = CURRENT_METER_ADC;
        featureEnable(FEATURE_TELEMETRY);
    }

    for (uint8_t pidProfileIndex = 0; pidProfileIndex < PID_PROFILE_COUNT; pidProfileIndex++) {
        pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex);

        pidProfile->pid[PID_ROLL].P = 53;
        pidProfile->pid[PID_ROLL].I = 45;
        pidProfile->pid[PID_ROLL].D = 52;
        pidProfile->pid[PID_PITCH].P = 53;
        pidProfile->pid[PID_PITCH].I = 45;
        pidProfile->pid[PID_PITCH].D = 52;
        pidProfile->pid[PID_YAW].P = 64;
        pidProfile->pid[PID_YAW].D = 18;
    }

    *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f,  1.0f, -1.0f };    // REAR_R
    *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f,  1.0f };    // FRONT_R
    *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f,  0.414178f,  1.0f,  1.0f };    // REAR_L
    *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f,  0.414178f, -1.0f, -1.0f };    // FRONT_L
    *customMotorMixerMutable(4) = (motorMixer_t){ 1.0f, -1.0f, -0.414178f, -1.0f };    // MIDFRONT_R
    *customMotorMixerMutable(5) = (motorMixer_t){ 1.0f,  1.0f, -0.414178f,  1.0f };    // MIDFRONT_L
    *customMotorMixerMutable(6) = (motorMixer_t){ 1.0f, -1.0f,  0.414178f,  1.0f };    // MIDREAR_R
    *customMotorMixerMutable(7) = (motorMixer_t){ 1.0f,  1.0f,  0.414178f, -1.0f };    // MIDREAR_L
}
Example #5
0
void createDefaultConfig(master_t *config)
{
    // Clear all configuration
    memset(config, 0, sizeof(master_t));

    uint32_t *featuresPtr = &config->enabledFeatures;

    intFeatureClearAll(featuresPtr);
    intFeatureSet(DEFAULT_RX_FEATURE | FEATURE_FAILSAFE , featuresPtr);
#ifdef DEFAULT_FEATURES
    intFeatureSet(DEFAULT_FEATURES, featuresPtr);
#endif

#ifdef OSD
    intFeatureSet(FEATURE_OSD, featuresPtr);
    osdResetConfig(&config->osdProfile);
#endif

#ifdef BOARD_HAS_VOLTAGE_DIVIDER
    // only enable the VBAT feature by default if the board has a voltage divider otherwise
    // the user may see incorrect readings and unexpected issues with pin mappings may occur.
    intFeatureSet(FEATURE_VBAT, featuresPtr);
#endif

    config->version = EEPROM_CONF_VERSION;
    config->mixerMode = MIXER_QUADX;

    // global settings
    config->current_profile_index = 0;    // default profile
    config->dcm_kp = 2500;                // 1.0 * 10000
    config->dcm_ki = 0;                   // 0.003 * 10000
    config->gyro_lpf = 0;                 // 256HZ default
#ifdef STM32F10X
    config->gyro_sync_denom = 8;
    config->pid_process_denom = 1;
#elif defined(USE_GYRO_SPI_MPU6000) || defined(USE_GYRO_SPI_MPU6500)  || defined(USE_GYRO_SPI_ICM20689)
    config->gyro_sync_denom = 1;
    config->pid_process_denom = 4;
#else
    config->gyro_sync_denom = 4;
    config->pid_process_denom = 2;
#endif
    config->gyro_soft_type = FILTER_PT1;
    config->gyro_soft_lpf_hz = 90;
    config->gyro_soft_notch_hz_1 = 400;
    config->gyro_soft_notch_cutoff_1 = 300;
    config->gyro_soft_notch_hz_2 = 200;
    config->gyro_soft_notch_cutoff_2 = 100;

    config->debug_mode = DEBUG_NONE;

    resetAccelerometerTrims(&config->accZero);

    resetSensorAlignment(&config->sensorAlignmentConfig);

    config->boardAlignment.rollDegrees = 0;
    config->boardAlignment.pitchDegrees = 0;
    config->boardAlignment.yawDegrees = 0;
    config->acc_hardware = ACC_DEFAULT;     // default/autodetect
    config->max_angle_inclination = 700;    // 70 degrees
    config->yaw_control_direction = 1;
    config->gyroConfig.gyroMovementCalibrationThreshold = 32;

    // xxx_hardware: 0:default/autodetect, 1: disable
    config->mag_hardware = 1;

    config->baro_hardware = 1;

    resetBatteryConfig(&config->batteryConfig);

#ifndef SKIP_RX_PWM_PPM
    resetPpmConfig(&config->ppmConfig);
    resetPwmConfig(&config->pwmConfig);
#endif

#ifdef TELEMETRY
    resetTelemetryConfig(&config->telemetryConfig);
#endif

#ifdef USE_ADC
    resetAdcConfig(&config->adcConfig);
#endif

#ifdef BEEPER
    resetBeeperConfig(&config->beeperConfig);
#endif

#ifdef SONAR
    resetSonarConfig(&config->sonarConfig);
#endif

#ifdef USE_SDCARD
    intFeatureSet(FEATURE_SDCARD, featuresPtr);
    resetsdcardConfig(&config->sdcardConfig);
#endif

#ifdef SERIALRX_PROVIDER
    config->rxConfig.serialrx_provider = SERIALRX_PROVIDER;
#else
    config->rxConfig.serialrx_provider = 0;
#endif
    config->rxConfig.rx_spi_protocol = RX_SPI_DEFAULT_PROTOCOL;
    config->rxConfig.sbus_inversion = 1;
    config->rxConfig.spektrum_sat_bind = 0;
    config->rxConfig.spektrum_sat_bind_autoreset = 1;
    config->rxConfig.midrc = 1500;
    config->rxConfig.mincheck = 1100;
    config->rxConfig.maxcheck = 1900;
    config->rxConfig.rx_min_usec = 885;          // any of first 4 channels below this value will trigger rx loss detection
    config->rxConfig.rx_max_usec = 2115;         // any of first 4 channels above this value will trigger rx loss detection

    for (int i = 0; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) {
        rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &config->rxConfig.failsafe_channel_configurations[i];
        channelFailsafeConfiguration->mode = (i < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_MODE_AUTO : RX_FAILSAFE_MODE_HOLD;
        channelFailsafeConfiguration->step = (i == THROTTLE) ? CHANNEL_VALUE_TO_RXFAIL_STEP(config->rxConfig.rx_min_usec) : CHANNEL_VALUE_TO_RXFAIL_STEP(config->rxConfig.midrc);
    }

    config->rxConfig.rssi_channel = 0;
    config->rxConfig.rssi_scale = RSSI_SCALE_DEFAULT;
    config->rxConfig.rssi_ppm_invert = 0;
    config->rxConfig.rcInterpolation = RC_SMOOTHING_AUTO;
    config->rxConfig.rcInterpolationInterval = 19;
    config->rxConfig.fpvCamAngleDegrees = 0;
    config->rxConfig.max_aux_channel = MAX_AUX_CHANNELS;
    config->rxConfig.airModeActivateThreshold = 1350;

    resetAllRxChannelRangeConfigurations(config->rxConfig.channelRanges);

    config->inputFilteringMode = INPUT_FILTERING_DISABLED;

    config->gyro_cal_on_first_arm = 0;  // TODO - Cleanup retarded arm support
    config->disarm_kill_switch = 1;
    config->auto_disarm_delay = 5;
    config->small_angle = 25;

    config->airplaneConfig.fixedwing_althold_dir = 1;

    // Motor/ESC/Servo
    resetMixerConfig(&config->mixerConfig);
    resetMotorConfig(&config->motorConfig);
#ifdef USE_SERVOS
    resetServoMixerConfig(&config->servoMixerConfig);
    resetServoConfig(&config->servoConfig);
#endif
    resetFlight3DConfig(&config->flight3DConfig);

#ifdef LED_STRIP
    resetLedStripConfig(&config->ledStripConfig);
#endif

#ifdef GPS
    // gps/nav stuff
    config->gpsConfig.provider = GPS_NMEA;
    config->gpsConfig.sbasMode = SBAS_AUTO;
    config->gpsConfig.autoConfig = GPS_AUTOCONFIG_ON;
    config->gpsConfig.autoBaud = GPS_AUTOBAUD_OFF;
#endif

    resetSerialConfig(&config->serialConfig);

    resetProfile(&config->profile[0]);

    resetRollAndPitchTrims(&config->accelerometerTrims);

    config->mag_declination = 0;
    config->acc_lpf_hz = 10.0f;
    config->accDeadband.xy = 40;
    config->accDeadband.z = 40;
    config->acc_unarmedcal = 1;

#ifdef BARO
    resetBarometerConfig(&config->barometerConfig);
#endif

    // Radio
#ifdef RX_CHANNELS_TAER
    parseRcChannels("TAER1234", &config->rxConfig);
#else
    parseRcChannels("AETR1234", &config->rxConfig);
#endif

    resetRcControlsConfig(&config->rcControlsConfig);

    config->throttle_correction_value = 0;      // could 10 with althold or 40 for fpv
    config->throttle_correction_angle = 800;    // could be 80.0 deg with atlhold or 45.0 for fpv

    // Failsafe Variables
    config->failsafeConfig.failsafe_delay = 10;                            // 1sec
    config->failsafeConfig.failsafe_off_delay = 10;                        // 1sec
    config->failsafeConfig.failsafe_throttle = 1000;                       // default throttle off.
    config->failsafeConfig.failsafe_kill_switch = 0;                       // default failsafe switch action is identical to rc link loss
    config->failsafeConfig.failsafe_throttle_low_delay = 100;              // default throttle low delay for "just disarm" on failsafe condition
    config->failsafeConfig.failsafe_procedure = FAILSAFE_PROCEDURE_DROP_IT;// default full failsafe procedure is 0: auto-landing

#ifdef USE_SERVOS
    // servos
    for (int i = 0; i < MAX_SUPPORTED_SERVOS; i++) {
        config->servoConf[i].min = DEFAULT_SERVO_MIN;
        config->servoConf[i].max = DEFAULT_SERVO_MAX;
        config->servoConf[i].middle = DEFAULT_SERVO_MIDDLE;
        config->servoConf[i].rate = 100;
        config->servoConf[i].angleAtMin = DEFAULT_SERVO_MIN_ANGLE;
        config->servoConf[i].angleAtMax = DEFAULT_SERVO_MAX_ANGLE;
        config->servoConf[i].forwardFromChannel = CHANNEL_FORWARDING_DISABLED;
    }

    // gimbal
    config->gimbalConfig.mode = GIMBAL_MODE_NORMAL;
#endif

#ifdef GPS
    resetGpsProfile(&config->gpsProfile);
#endif

    // custom mixer. clear by defaults.
    for (int i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
        config->customMotorMixer[i].throttle = 0.0f;
    }

#ifdef VTX
    config->vtx_band = 4;    //Fatshark/Airwaves
    config->vtx_channel = 1; //CH1
    config->vtx_mode = 0;    //CH+BAND mode
    config->vtx_mhz = 5740;  //F0
#endif

#ifdef TRANSPONDER
    static const uint8_t defaultTransponderData[6] = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }; // Note, this is NOT a valid transponder code, it's just for testing production hardware

    memcpy(config->transponderData, &defaultTransponderData, sizeof(defaultTransponderData));
#endif

#ifdef BLACKBOX
#if defined(ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT)
    intFeatureSet(FEATURE_BLACKBOX, featuresPtr);
    config->blackbox_device = BLACKBOX_DEVICE_FLASH;
#elif defined(ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT)
    intFeatureSet(FEATURE_BLACKBOX, featuresPtr);
    config->blackbox_device = BLACKBOX_DEVICE_SDCARD;
#else
    config->blackbox_device = BLACKBOX_DEVICE_SERIAL;
#endif

    config->blackbox_rate_num = 1;
    config->blackbox_rate_denom = 1;
    config->blackbox_on_motor_test = 0; // default off
#endif // BLACKBOX

#ifdef SERIALRX_UART
    if (featureConfigured(FEATURE_RX_SERIAL)) {
        int serialIndex = findSerialPortIndexByIdentifier(SERIALRX_UART);
        if (serialIndex >= 0) {
            config->serialConfig.portConfigs[serialIndex].functionMask = FUNCTION_RX_SERIAL;
        }
    }
#endif

#if defined(TARGET_CONFIG)
    targetConfiguration(config);
#endif

    // copy first profile into remaining profile
    for (int i = 1; i < MAX_PROFILE_COUNT; i++) {
        memcpy(&config->profile[i], &config->profile[0], sizeof(profile_t));
    }
}
Example #6
0
void targetConfiguration(void)
{
    serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(GPS_UART)].functionMask = FUNCTION_GPS;
    serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(TELEMETRY_UART)].functionMask = TELEMETRY_PROVIDER_DEFAULT;
    telemetryConfigMutable()->halfDuplex = false;
}
Example #7
0
void targetConfiguration(void)
{
    serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(TELEMETRY_UART)].functionMask = FUNCTION_TELEMETRY_SMARTPORT;
}
Example #8
0
// alternative defaults settings for AlienFlight targets
void targetConfiguration(void)
{
    /* depending on revision ... depends on the LEDs to be utilised. */
    if (hardwareRevision == AFF3_REV_2) {
        statusLedConfigMutable()->inversion = 0
#ifdef LED0_A_INVERTED
            | BIT(0)
#endif
#ifdef LED1_A_INVERTED
            | BIT(1)
#endif
#ifdef LED2_A_INVERTED
            | BIT(2)
#endif
            ;

        for (int i = 0; i < STATUS_LED_NUMBER; i++) {
            statusLedConfigMutable()->ioTags[i] = IO_TAG_NONE;
        }
#ifdef LED0_A
        statusLedConfigMutable()->ioTags[0] = IO_TAG(LED0_A);
#endif
#ifdef LED1_A
        statusLedConfigMutable()->ioTags[1] = IO_TAG(LED1_A);
#endif
#ifdef LED2_A
        statusLedConfigMutable()->ioTags[2] = IO_TAG(LED2_A);
#endif
    } else {
        gyroConfigMutable()->gyro_sync_denom = 2;
        pidConfigMutable()->pid_process_denom = 2;
    }

    if (!haveFrSkyRX) {
        rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048;
        rxConfigMutable()->spektrum_sat_bind = 5;
        rxConfigMutable()->spektrum_sat_bind_autoreset = 1;
        parseRcChannels("TAER1234", rxConfigMutable());
    } else {
        rxConfigMutable()->serialrx_provider = SERIALRX_SBUS;
        rxConfigMutable()->serialrx_inverted = true;
        serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL;
        telemetryConfigMutable()->telemetry_inverted = false;
        featureSet(FEATURE_TELEMETRY);
        beeperDevConfigMutable()->isOpenDrain = false;
        beeperDevConfigMutable()->isInverted = true;
        parseRcChannels("AETR1234", rxConfigMutable());
    }

    if (hardwareMotorType == MOTOR_BRUSHED) {
        motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE;
        pidConfigMutable()->pid_process_denom = 1;
    }

    for (uint8_t pidProfileIndex = 0; pidProfileIndex < MAX_PROFILE_COUNT; pidProfileIndex++) {
        pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex);

        pidProfile->pid[PID_ROLL].P = 90;
        pidProfile->pid[PID_ROLL].I = 44;
        pidProfile->pid[PID_ROLL].D = 60;
        pidProfile->pid[PID_PITCH].P = 90;
        pidProfile->pid[PID_PITCH].I = 44;
        pidProfile->pid[PID_PITCH].D = 60;
    }

    *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f,  1.0f, -1.0f };    // REAR_R
    *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f,  1.0f };    // FRONT_R
    *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f,  0.414178f,  1.0f,  1.0f };    // REAR_L
    *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f,  0.414178f, -1.0f, -1.0f };    // FRONT_L
    *customMotorMixerMutable(4) = (motorMixer_t){ 1.0f, -1.0f, -0.414178f, -1.0f };    // MIDFRONT_R
    *customMotorMixerMutable(5) = (motorMixer_t){ 1.0f,  1.0f, -0.414178f,  1.0f };    // MIDFRONT_L
    *customMotorMixerMutable(6) = (motorMixer_t){ 1.0f, -1.0f,  0.414178f,  1.0f };    // MIDREAR_R
    *customMotorMixerMutable(7) = (motorMixer_t){ 1.0f,  1.0f,  0.414178f, -1.0f };    // MIDREAR_L
}
Example #9
0
void targetConfiguration(void)
{
    if (hardwareMotorType == MOTOR_BRUSHED) {
        motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE;
        motorConfigMutable()->minthrottle = 1030;
        pidConfigMutable()->pid_process_denom = 1;
    }

    for (uint8_t pidProfileIndex = 0; pidProfileIndex < PID_PROFILE_COUNT; pidProfileIndex++) {
        pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex);

        pidProfile->pid[PID_ROLL].P  = 86;
        pidProfile->pid[PID_ROLL].I  = 50;
        pidProfile->pid[PID_ROLL].D  = 60;
        pidProfile->pid[PID_PITCH].P = 90;
        pidProfile->pid[PID_PITCH].I = 55;
        pidProfile->pid[PID_PITCH].D = 60;
        pidProfile->pid[PID_YAW].P   = 123;
        pidProfile->pid[PID_YAW].I   = 75;
    }

    for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) {
        controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex);

        controlRateConfig->rcRates[FD_YAW] = 120;
        controlRateConfig->rcExpo[FD_ROLL] = 15;
        controlRateConfig->rcExpo[FD_PITCH] = 15;
        controlRateConfig->rcExpo[FD_YAW]  = 15;
        controlRateConfig->rates[FD_ROLL]  = 85;
        controlRateConfig->rates[FD_PITCH] = 85;
    }

    batteryConfigMutable()->batteryCapacity = 250;
    batteryConfigMutable()->vbatmincellvoltage = 280;
    batteryConfigMutable()->vbatwarningcellvoltage = 330;

    *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f,  1.0f, -1.0f };    // REAR_R
    *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f,  1.0f };    // FRONT_R
    *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f,  0.414178f,  1.0f,  1.0f };    // REAR_L
    *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f,  0.414178f, -1.0f, -1.0f };    // FRONT_L

    vcdProfileMutable()->video_system = VIDEO_SYSTEM_NTSC;
#if defined(BEESTORM)
    strcpy(pilotConfigMutable()->name, "BeeStorm");
#else
    strcpy(pilotConfigMutable()->name, "BeeBrain V2");
#endif
    osdConfigMutable()->cap_alarm  = 250;
    osdConfigMutable()->item_pos[OSD_CRAFT_NAME]        = OSD_POS(9, 11)  | OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_MAIN_BATT_VOLTAGE] = OSD_POS(23, 10) | OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ITEM_TIMER_2]      = OSD_POS(2, 10)  | OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_FLYMODE]           = OSD_POS(17, 10) | OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_VTX_CHANNEL]       = OSD_POS(10, 10) | OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_RSSI_VALUE]         &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ITEM_TIMER_1]       &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_THROTTLE_POS]       &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_CROSSHAIRS]         &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_HORIZON_SIDEBARS]   &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ARTIFICIAL_HORIZON] &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_CURRENT_DRAW]       &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_MAH_DRAWN]          &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_GPS_SPEED]          &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_GPS_LON]            &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_GPS_LAT]            &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_GPS_SATS]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_HOME_DIR]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_HOME_DIST]          &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_COMPASS_BAR]        &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ALTITUDE]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ROLL_PIDS]          &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_PITCH_PIDS]         &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_YAW_PIDS]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_DEBUG]              &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_POWER]              &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_PIDRATE_PROFILE]    &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_WARNINGS]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_AVG_CELL_VOLTAGE]   &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_PITCH_ANGLE]        &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ROLL_ANGLE]         &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_MAIN_BATT_USAGE]    &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_DISARMED]           &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_NUMERICAL_HEADING]  &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_NUMERICAL_VARIO]    &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ESC_TMP]            &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_ESC_RPM]            &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_G_FORCE]            &= ~OSD_PROFILE_1_FLAG;
    osdConfigMutable()->item_pos[OSD_FLIP_ARROW]         &= ~OSD_PROFILE_1_FLAG;

    modeActivationConditionsMutable(0)->modeId           = BOXANGLE;
    modeActivationConditionsMutable(0)->auxChannelIndex  = AUX2 - NON_AUX_CHANNEL_COUNT;
    modeActivationConditionsMutable(0)->range.startStep  = CHANNEL_VALUE_TO_STEP(900);
    modeActivationConditionsMutable(0)->range.endStep    = CHANNEL_VALUE_TO_STEP(2100);

    analyzeModeActivationConditions();

#if defined(BEEBRAIN_V2D)
    // DSM version
    for (uint8_t rxRangeIndex = 0; rxRangeIndex < NON_AUX_CHANNEL_COUNT; rxRangeIndex++) {
        rxChannelRangeConfig_t *channelRangeConfig = rxChannelRangeConfigsMutable(rxRangeIndex);

        channelRangeConfig->min = 1160;
        channelRangeConfig->max = 1840;
    }
#else
    // Frsky version
    serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL;
    rxConfigMutable()->rssi_channel = BBV2_FRSKY_RSSI_CH_IDX;
    rxFailsafeChannelConfig_t *channelFailsafeConfig = rxFailsafeChannelConfigsMutable(BBV2_FRSKY_RSSI_CH_IDX - 1);
    channelFailsafeConfig->mode = RX_FAILSAFE_MODE_SET;
    channelFailsafeConfig->step = CHANNEL_VALUE_TO_RXFAIL_STEP(1000);
    osdConfigMutable()->item_pos[OSD_RSSI_VALUE]        = OSD_POS(2, 11)  | OSD_PROFILE_1_FLAG;
#endif
}