diff --git a/.gitignore b/.gitignore index 9b72fa8305a..6d7138e6bd5 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,7 @@ launch.json # Assitnow token and files for test script tokens.yaml *.ubx + +# Local development files +.semgrepignore +build_sitl/ diff --git a/CMakeLists.txt b/CMakeLists.txt index dc34f9da32b..14db3259720 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ else() endif() -project(INAV VERSION 9.0.0) +project(INAV VERSION 9.0.1) enable_language(ASM) diff --git a/src/main/fc/fc_core.c b/src/main/fc/fc_core.c index 0cf6240771f..11bbd6cf3cc 100644 --- a/src/main/fc/fc_core.c +++ b/src/main/fc/fc_core.c @@ -946,7 +946,12 @@ void taskMainPidLoop(timeUs_t currentTimeUs) processPilotAndFailSafeActions(dT); - updateArmingStatus(); + // Check battery, GPS signal, arming status etc @ 200 Hz + static uint8_t armingStatusDivider = 0; + if (++armingStatusDivider >= 10) { + armingStatusDivider = 0; + updateArmingStatus(); + } if (rxConfig()->rcFilterFrequency) { rcInterpolationApply(isRXDataNew, currentTimeUs); diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 455d5f20897..45379d1caa4 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -1550,6 +1550,12 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU8(dst, vtxDevice->capability.bandCount); sbufWriteU8(dst, vtxDevice->capability.channelCount); sbufWriteU8(dst, vtxDevice->capability.powerCount); + + uint8_t minPowerIndex = 1; + if (deviceType == VTXDEV_MSP) { + minPowerIndex = 0; + } + sbufWriteU8(dst, minPowerIndex); } else { sbufWriteU8(dst, VTXDEV_UNKNOWN); // no VTX configured diff --git a/src/main/io/gps_ublox.c b/src/main/io/gps_ublox.c index f0899aa69d5..82e1a4f655d 100755 --- a/src/main/io/gps_ublox.c +++ b/src/main/io/gps_ublox.c @@ -1231,11 +1231,9 @@ STATIC_PROTOTHREAD(gpsProtocolStateThread) if (gpsState.hwVersion == UBX_HW_VERSION_UNKNOWN) { pollVersion(); - ptWaitTimeout((_ack_state == UBX_ACK_GOT_ACK || _ack_state == UBX_ACK_GOT_NAK), GPS_CFG_CMD_TIMEOUT_MS); } pollGnssCapabilities(); - ptWaitTimeout((_ack_state == UBX_ACK_GOT_ACK || _ack_state == UBX_ACK_GOT_NAK), GPS_CFG_CMD_TIMEOUT_MS); } } } diff --git a/src/main/navigation/navigation_pos_estimator.c b/src/main/navigation/navigation_pos_estimator.c index 35245d9f7f0..4252b952c27 100644 --- a/src/main/navigation/navigation_pos_estimator.c +++ b/src/main/navigation/navigation_pos_estimator.c @@ -228,6 +228,7 @@ void onNewGPSData(void) /* If not the first update - calculate velocities */ if (!isFirstGPSUpdate) { float dT = US2S(getGPSDeltaTimeFilter(currentTimeUs - lastGPSNewDataTime)); + posEstimator.gps.updateDt = dT; /* Use VELNED provided by GPS if available, calculate from coordinates otherwise */ float gpsScaleLonDown = constrainf(cos_approx((ABS(gpsSol.llh.lat) / 10000000.0f) * 0.0174532925f), 0.01f, 1.0f); @@ -298,12 +299,15 @@ void updatePositionEstimator_BaroTopic(timeUs_t currentTimeUs) posEstimator.baro.epv = positionEstimationConfig()->baro_epv; posEstimator.baro.lastUpdateTime = currentTimeUs; - if (baroDtUs <= MS2US(INAV_BARO_TIMEOUT_MS)) { - posEstimator.baro.alt = pt1FilterApply3(&posEstimator.baro.avgFilter, posEstimator.baro.alt, US2S(baroDtUs)); + if (baroDtUs > 0 && baroDtUs <= MS2US(INAV_BARO_TIMEOUT_MS)) { + const float baroDtSec = US2S(baroDtUs); + posEstimator.baro.updateDt = baroDtSec; + + posEstimator.baro.alt = pt1FilterApply3(&posEstimator.baro.avgFilter, posEstimator.baro.alt, baroDtSec); // baro altitude rate static float baroAltPrevious = 0; - posEstimator.baro.baroAltRate = (posEstimator.baro.alt - baroAltPrevious) / US2S(baroDtUs); + posEstimator.baro.baroAltRate = (posEstimator.baro.alt - baroAltPrevious) / baroDtSec; baroAltPrevious = posEstimator.baro.alt; updateBaroAltitudeRate(posEstimator.baro.baroAltRate); } @@ -354,7 +358,7 @@ static bool gravityCalibrationComplete(void) static void updateIMUEstimationWeight(const float dt) { static float acc_clip_factor = 1.0f; - // If accelerometer measurement is clipped - drop the acc weight to 0.3 + // If accelerometer measurement is clipped - drop the acc weight to 0.5 // and gradually restore weight back to 1.0 over time if (accIsClipped()) { acc_clip_factor = 0.5f; @@ -576,72 +580,84 @@ static bool estimationCalculateCorrection_Z(estimationContext_t * ctx) } if (ctx->newFlags & EST_BARO_VALID && wBaro) { - bool isAirCushionEffectDetected = false; - static float baroGroundAlt = 0.0f; + if (posEstimator.baro.updateDt) { // only update corrections once every sensor update + ctx->applyCorrections = true; + const float dT = posEstimator.baro.updateDt; - if (STATE(MULTIROTOR)) { - static bool isBaroGroundValid = false; + bool isAirCushionEffectDetected = false; + static float baroGroundAlt = 0.0f; - if (!ARMING_FLAG(ARMED)) { - baroGroundAlt = posEstimator.baro.alt; - isBaroGroundValid = true; - } - else if (isBaroGroundValid) { - // We might be experiencing air cushion effect during takeoff - use sonar or baro ground altitude to detect it - if (isMulticopterThrottleAboveMidHover()) { - // Disable ground effect detection at lift off when est alt and baro alt converge. Always disable if baro alt > 1m. - isBaroGroundValid = fabsf(posEstimator.est.pos.z - posEstimator.baro.alt) > 20.0f && posEstimator.baro.alt < 100.0f; - } + if (STATE(MULTIROTOR)) { + static bool isBaroGroundValid = false; - isAirCushionEffectDetected = (isEstimatedAglTrusted() && posEstimator.surface.alt < 20.0f) || posEstimator.baro.alt < baroGroundAlt + 20.0f; + if (!ARMING_FLAG(ARMED)) { + baroGroundAlt = posEstimator.baro.alt; + isBaroGroundValid = true; + } + else if (isBaroGroundValid) { + // We might be experiencing air cushion effect during takeoff - use sonar or baro ground altitude to detect it + if (isMulticopterThrottleAboveMidHover()) { + // Disable ground effect detection at lift off when est alt and baro alt converge. Always disable if baro alt > 1m. + isBaroGroundValid = fabsf(posEstimator.est.pos.z - posEstimator.baro.alt) > 20.0f && posEstimator.baro.alt < 100.0f; + } + + isAirCushionEffectDetected = (isEstimatedAglTrusted() && posEstimator.surface.alt < 20.0f) || + posEstimator.baro.alt < baroGroundAlt + 20.0f; + } } - } - // Altitude - float baroAltResidual = wBaro * ((isAirCushionEffectDetected ? baroGroundAlt : posEstimator.baro.alt) - posEstimator.est.pos.z); + // Altitude + float baroAltResidual = wBaro * ((isAirCushionEffectDetected ? baroGroundAlt : posEstimator.baro.alt) - posEstimator.est.pos.z); - // Disable alt pos correction at point of lift off if ground effect active - if (isAirCushionEffectDetected && isMulticopterThrottleAboveMidHover()) { - baroAltResidual = 0.0f; - } + // Disable alt pos correction at point of lift off if ground effect active + if (isAirCushionEffectDetected && isMulticopterThrottleAboveMidHover()) { + baroAltResidual = 0.0f; + } - const float baroVelZResidual = isAirCushionEffectDetected ? 0.0f : wBaro * (posEstimator.baro.baroAltRate - posEstimator.est.vel.z); - const float w_z_baro_p = positionEstimationConfig()->w_z_baro_p; - const float w_z_baro_v = positionEstimationConfig()->w_z_baro_v; + const float baroVelZResidual = isAirCushionEffectDetected ? 0.0f : wBaro * (posEstimator.baro.baroAltRate - posEstimator.est.vel.z); + const float w_z_baro_p = positionEstimationConfig()->w_z_baro_p; + const float w_z_baro_v = positionEstimationConfig()->w_z_baro_v; - ctx->estPosCorr.z += baroAltResidual * w_z_baro_p * ctx->dt; - ctx->estVelCorr.z += baroVelZResidual * w_z_baro_v * ctx->dt; + ctx->estPosCorr.z = baroAltResidual * w_z_baro_p * dT; + ctx->estVelCorr.z = baroVelZResidual * w_z_baro_v * dT; - ctx->newEPV = updateEPE(posEstimator.est.epv, ctx->dt, MAX(posEstimator.baro.epv, fabsf(baroAltResidual)), w_z_baro_p); + ctx->newEPV = updateEPE(posEstimator.est.epv, dT, MAX(posEstimator.baro.epv, fabsf(baroAltResidual)), w_z_baro_p); - // Accelerometer bias - if (!isAirCushionEffectDetected) { - ctx->accBiasCorr.z += (baroAltResidual * sq(w_z_baro_p) + baroVelZResidual * sq(w_z_baro_v)); + // Accelerometer bias + if (!isAirCushionEffectDetected) { + ctx->accBiasCorr.z = dT * (baroAltResidual * sq(w_z_baro_p) + baroVelZResidual * sq(w_z_baro_v)); + } } correctOK = ARMING_FLAG(WAS_EVER_ARMED); // No correction until first armed } if (ctx->newFlags & EST_GPS_Z_VALID && (wGps || !(ctx->newFlags & EST_Z_VALID))) { - // Reset current estimate to GPS altitude if estimate not valid (used for GPS and Baro) - if (!(ctx->newFlags & EST_Z_VALID)) { - posEstimator.est.pos.z = posEstimator.gps.pos.z; - posEstimator.est.vel.z = posEstimator.gps.vel.z; - ctx->newEPV = posEstimator.gps.epv; - } - else { - // Altitude - const float gpsAltResidual = wGps * (posEstimator.gps.pos.z - posEstimator.est.pos.z); - const float gpsVelZResidual = wGps * (posEstimator.gps.vel.z - posEstimator.est.vel.z); - const float w_z_gps_p = positionEstimationConfig()->w_z_gps_p; - const float w_z_gps_v = positionEstimationConfig()->w_z_gps_v; + if (posEstimator.gps.updateDt) { // only update corrections once every sensor update + // Reset current estimate to GPS altitude if estimate not valid (used for GPS and Baro) + if (!(ctx->newFlags & EST_Z_VALID)) { + posEstimator.est.pos.z = posEstimator.gps.pos.z; + posEstimator.est.vel.z = posEstimator.gps.vel.z; + ctx->newEPV = posEstimator.gps.epv; + } + else { + ctx->applyCorrections = true; + const float dT = posEstimator.gps.updateDt; - ctx->estPosCorr.z += gpsAltResidual * w_z_gps_p * ctx->dt; - ctx->estVelCorr.z += gpsVelZResidual * w_z_gps_v * ctx->dt; - ctx->newEPV = updateEPE(posEstimator.est.epv, ctx->dt, MAX(posEstimator.gps.epv, fabsf(gpsAltResidual)), w_z_gps_p); + // Altitude + const float gpsAltResidual = wGps * (posEstimator.gps.pos.z - posEstimator.est.pos.z); + const float gpsVelZResidual = wGps * (posEstimator.gps.vel.z - posEstimator.est.vel.z); + const float w_z_gps_p = positionEstimationConfig()->w_z_gps_p; + const float w_z_gps_v = positionEstimationConfig()->w_z_gps_v; - // Accelerometer bias - ctx->accBiasCorr.z += (gpsAltResidual * sq(w_z_gps_p) + gpsVelZResidual * sq(w_z_gps_v)); + ctx->estPosCorr.z += gpsAltResidual * w_z_gps_p * dT; + ctx->estVelCorr.z += gpsVelZResidual * w_z_gps_v * dT; + + ctx->newEPV = updateEPE(ctx->newEPV, dT, MAX(posEstimator.gps.epv, fabsf(gpsAltResidual)), w_z_gps_p); + + // Accelerometer bias + ctx->accBiasCorr.z += dT * (gpsAltResidual * sq(w_z_gps_p) + gpsVelZResidual * sq(w_z_gps_v)); + } } correctOK = ARMING_FLAG(WAS_EVER_ARMED); // No correction until first armed @@ -658,6 +674,9 @@ static bool estimationCalculateCorrection_Z(estimationContext_t * ctx) static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx) { if (ctx->newFlags & EST_GPS_XY_VALID) { + if (!posEstimator.gps.updateDt) { // only update corrections once every sensor update + return true; + } /* If GPS is valid and our estimate is NOT valid - reset it to GPS coordinates and velocity */ if (!(ctx->newFlags & EST_XY_VALID)) { posEstimator.est.pos.x = posEstimator.gps.pos.x; @@ -667,6 +686,9 @@ static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx) ctx->newEPH = posEstimator.gps.eph; } else { + ctx->applyCorrections = true; + const float dT = posEstimator.gps.updateDt; + const float gpsPosXResidual = posEstimator.gps.pos.x - posEstimator.est.pos.x; const float gpsPosYResidual = posEstimator.gps.pos.y - posEstimator.est.pos.y; const float gpsVelXResidual = posEstimator.gps.vel.x - posEstimator.est.vel.x; @@ -680,19 +702,19 @@ static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx) const float w_xy_gps_v = positionEstimationConfig()->w_xy_gps_v * sq(gpsWeightScaler); // Coordinates - ctx->estPosCorr.x += gpsPosXResidual * w_xy_gps_p * ctx->dt; - ctx->estPosCorr.y += gpsPosYResidual * w_xy_gps_p * ctx->dt; + ctx->estPosCorr.x = gpsPosXResidual * w_xy_gps_p * dT; + ctx->estPosCorr.y = gpsPosYResidual * w_xy_gps_p * dT; // Velocity from direct measurement - ctx->estVelCorr.x += gpsVelXResidual * w_xy_gps_v * ctx->dt; - ctx->estVelCorr.y += gpsVelYResidual * w_xy_gps_v * ctx->dt; + ctx->estVelCorr.x = gpsVelXResidual * w_xy_gps_v * dT; + ctx->estVelCorr.y = gpsVelYResidual * w_xy_gps_v * dT; // Accelerometer bias - ctx->accBiasCorr.x += (gpsPosXResidual * sq(w_xy_gps_p) + gpsVelXResidual * sq(w_xy_gps_v)); - ctx->accBiasCorr.y += (gpsPosYResidual * sq(w_xy_gps_p) + gpsVelYResidual * sq(w_xy_gps_v)); + ctx->accBiasCorr.x = dT * (gpsPosXResidual * sq(w_xy_gps_p) + gpsVelXResidual * sq(w_xy_gps_v)); + ctx->accBiasCorr.y = dT * (gpsPosYResidual * sq(w_xy_gps_p) + gpsVelYResidual * sq(w_xy_gps_v)); /* Adjust EPH */ - ctx->newEPH = updateEPE(posEstimator.est.eph, ctx->dt, MAX(posEstimator.gps.eph, gpsPosResidualMag), w_xy_gps_p); + ctx->newEPH = updateEPE(posEstimator.est.eph, dT, MAX(posEstimator.gps.eph, gpsPosResidualMag), w_xy_gps_p); } return true; @@ -736,9 +758,9 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs) return; } - /* Calculate new EPH and EPV for the case we didn't update position */ - ctx.newEPH = posEstimator.est.eph * ((posEstimator.est.eph <= max_eph_epv) ? 1.0f + ctx.dt : 1.0f); - ctx.newEPV = posEstimator.est.epv * ((posEstimator.est.epv <= max_eph_epv) ? 1.0f + ctx.dt : 1.0f); + /* Calculate new degraded EPH and EPV for the case we didn't update estimation from sensors - linear degradation in max 10s */ + ctx.newEPH = posEstimator.est.eph + ((posEstimator.est.eph <= max_eph_epv) ? 100.0f * ctx.dt : 0.0f); + ctx.newEPV = posEstimator.est.epv + ((posEstimator.est.epv <= max_eph_epv) ? 100.0f * ctx.dt : 0.0f); ctx.newFlags = calculateCurrentValidityFlags(currentTimeUs); vectorZero(&ctx.estPosCorr); @@ -760,40 +782,53 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs) // If we can't apply correction or accuracy is off the charts - decay velocity to zero if (!estXYCorrectOk || ctx.newEPH > max_eph_epv) { - ctx.estVelCorr.x = -posEstimator.est.vel.x * positionEstimationConfig()->w_xy_res_v * ctx.dt; - ctx.estVelCorr.y = -posEstimator.est.vel.y * positionEstimationConfig()->w_xy_res_v * ctx.dt; + const float w_xy_res_v = positionEstimationConfig()->w_xy_res_v; + posEstimator.est.vel.x -= posEstimator.est.vel.x * w_xy_res_v * ctx.dt; + posEstimator.est.vel.y -= posEstimator.est.vel.y * w_xy_res_v * ctx.dt; } if (!estZCorrectOk || ctx.newEPV > max_eph_epv) { - ctx.estVelCorr.z = -posEstimator.est.vel.z * positionEstimationConfig()->w_z_res_v * ctx.dt; + posEstimator.est.vel.z -= posEstimator.est.vel.z * positionEstimationConfig()->w_z_res_v * ctx.dt; } - // Boost the corrections based on accWeight - vectorScale(&ctx.estPosCorr, &ctx.estPosCorr, 1.0f / posEstimator.imu.accWeightFactor); - vectorScale(&ctx.estVelCorr, &ctx.estVelCorr, 1.0f / posEstimator.imu.accWeightFactor); + // Only apply corrections if new sensor update available + if (ctx.applyCorrections) { + ctx.applyCorrections = false; - // Constrain corrections to prevent instability - const float corrLimit = INAV_EST_CORR_LIMIT_VALUE * ctx.dt; - for (uint8_t axis = 0; axis < 3; axis++) { - ctx.estPosCorr.v[axis] = constrainf(ctx.estPosCorr.v[axis], -corrLimit, corrLimit); - ctx.estVelCorr.v[axis] = constrainf(ctx.estVelCorr.v[axis], -corrLimit, corrLimit); - } + // Boost the corrections based on accWeight + vectorScale(&ctx.estPosCorr, &ctx.estPosCorr, 1.0f / posEstimator.imu.accWeightFactor); + vectorScale(&ctx.estVelCorr, &ctx.estVelCorr, 1.0f / posEstimator.imu.accWeightFactor); - // Apply corrections - vectorAdd(&posEstimator.est.pos, &posEstimator.est.pos, &ctx.estPosCorr); - vectorAdd(&posEstimator.est.vel, &posEstimator.est.vel, &ctx.estVelCorr); + // Constrain corrections to prevent instability + float maxUpdateDt = MAX(posEstimator.gps.updateDt, posEstimator.baro.updateDt); + maxUpdateDt = MAX(maxUpdateDt, posEstimator.flow.updateDt); + const float correctionLimit = INAV_EST_CORR_LIMIT_VALUE * maxUpdateDt; + for (uint8_t axis = 0; axis < 3; axis++) { + ctx.estPosCorr.v[axis] = constrainf(ctx.estPosCorr.v[axis], -correctionLimit, correctionLimit); + ctx.estVelCorr.v[axis] = constrainf(ctx.estVelCorr.v[axis], -correctionLimit, correctionLimit); + } - /* Correct accelerometer bias */ - const float w_acc_bias = positionEstimationConfig()->w_acc_bias; - if (w_acc_bias > 0.0f) { - /* Correct accel bias */ - posEstimator.imu.accelBias.x += ctx.accBiasCorr.x * w_acc_bias * ctx.dt; - posEstimator.imu.accelBias.y += ctx.accBiasCorr.y * w_acc_bias * ctx.dt; - posEstimator.imu.accelBias.z += ctx.accBiasCorr.z * w_acc_bias * ctx.dt; + // Apply corrections + vectorAdd(&posEstimator.est.pos, &posEstimator.est.pos, &ctx.estPosCorr); + vectorAdd(&posEstimator.est.vel, &posEstimator.est.vel, &ctx.estVelCorr); + + /* Correct accelerometer bias */ + const float w_acc_bias = positionEstimationConfig()->w_acc_bias; + if (w_acc_bias > 0.0f) { + /* Correct accel bias */ + posEstimator.imu.accelBias.x += ctx.accBiasCorr.x * w_acc_bias; + posEstimator.imu.accelBias.y += ctx.accBiasCorr.y * w_acc_bias; + posEstimator.imu.accelBias.z += ctx.accBiasCorr.z * w_acc_bias; + + posEstimator.imu.accelBias.x = constrainf(posEstimator.imu.accelBias.x, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); + posEstimator.imu.accelBias.y = constrainf(posEstimator.imu.accelBias.y, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); + posEstimator.imu.accelBias.z = constrainf(posEstimator.imu.accelBias.z, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); + } - posEstimator.imu.accelBias.x = constrainf(posEstimator.imu.accelBias.x, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); - posEstimator.imu.accelBias.y = constrainf(posEstimator.imu.accelBias.y, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); - posEstimator.imu.accelBias.z = constrainf(posEstimator.imu.accelBias.z, -INAV_ACC_BIAS_ACCEPTANCE_VALUE, INAV_ACC_BIAS_ACCEPTANCE_VALUE); + // Reset sensor update time deltas once sensor corrections applied after sensor update + posEstimator.gps.updateDt = 0.0f; + posEstimator.baro.updateDt = 0.0f; + posEstimator.flow.updateDt = 0.0f; } /* Update ground course */ diff --git a/src/main/navigation/navigation_pos_estimator_agl.c b/src/main/navigation/navigation_pos_estimator_agl.c index 03b5bd8ccf0..38788e20a77 100644 --- a/src/main/navigation/navigation_pos_estimator_agl.c +++ b/src/main/navigation/navigation_pos_estimator_agl.c @@ -149,7 +149,7 @@ void estimationCalculateAGL(estimationContext_t * ctx) // Update estimate posEstimator.est.aglAlt += posEstimator.est.aglVel * ctx->dt; posEstimator.est.aglAlt += posEstimator.imu.accelNEU.z * sq(ctx->dt) / 2.0f * posEstimator.imu.accWeightFactor; - posEstimator.est.aglVel += posEstimator.imu.accelNEU.z * ctx->dt * sq(posEstimator.imu.accWeightFactor); + posEstimator.est.aglVel += posEstimator.imu.accelNEU.z * ctx->dt * posEstimator.imu.accWeightFactor; // Apply correction if (posEstimator.est.aglQual == SURFACE_QUAL_HIGH) { diff --git a/src/main/navigation/navigation_pos_estimator_flow.c b/src/main/navigation/navigation_pos_estimator_flow.c index 8656c4919f4..36325f5dc1a 100644 --- a/src/main/navigation/navigation_pos_estimator_flow.c +++ b/src/main/navigation/navigation_pos_estimator_flow.c @@ -73,6 +73,13 @@ bool estimationCalculateCorrection_XY_FLOW(estimationContext_t * ctx) return false; } + if (!opflow.updateDt) { + return true; + } + posEstimator.flow.updateDt = opflow.updateDt; + opflow.updateDt = 0.0f; + const float dt = posEstimator.flow.updateDt; + // Calculate linear velocity based on angular velocity and altitude // Technically we should calculate arc length here, but for fast sampling this is accurate enough fpVector3_t flowVel = { @@ -88,8 +95,9 @@ bool estimationCalculateCorrection_XY_FLOW(estimationContext_t * ctx) const float flowVelXInnov = flowVel.x - posEstimator.est.vel.x; const float flowVelYInnov = flowVel.y - posEstimator.est.vel.y; - ctx->estVelCorr.x = flowVelXInnov * positionEstimationConfig()->w_xy_flow_v * ctx->dt; - ctx->estVelCorr.y = flowVelYInnov * positionEstimationConfig()->w_xy_flow_v * ctx->dt; + const float w_xy_flow_v = positionEstimationConfig()->w_xy_flow_v; + ctx->estVelCorr.x = flowVelXInnov * w_xy_flow_v * dt; + ctx->estVelCorr.y = flowVelYInnov * w_xy_flow_v * dt; // Calculate position correction if possible/allowed if ((ctx->newFlags & EST_GPS_XY_VALID)) { @@ -98,16 +106,17 @@ bool estimationCalculateCorrection_XY_FLOW(estimationContext_t * ctx) posEstimator.est.flowCoordinates[Y] = posEstimator.gps.pos.y; } else if (positionEstimationConfig()->allow_dead_reckoning) { - posEstimator.est.flowCoordinates[X] += flowVel.x * ctx->dt; - posEstimator.est.flowCoordinates[Y] += flowVel.y * ctx->dt; + posEstimator.est.flowCoordinates[X] += flowVel.x * dt; + posEstimator.est.flowCoordinates[Y] += flowVel.y * dt; const float flowResidualX = posEstimator.est.flowCoordinates[X] - posEstimator.est.pos.x; const float flowResidualY = posEstimator.est.flowCoordinates[Y] - posEstimator.est.pos.y; - ctx->estPosCorr.x = flowResidualX * positionEstimationConfig()->w_xy_flow_p * ctx->dt; - ctx->estPosCorr.y = flowResidualY * positionEstimationConfig()->w_xy_flow_p * ctx->dt; + const float w_xy_flow_p = positionEstimationConfig()->w_xy_flow_p; + ctx->estPosCorr.x = flowResidualX * w_xy_flow_p * dt; + ctx->estPosCorr.y = flowResidualY * w_xy_flow_p * dt; - ctx->newEPH = updateEPE(posEstimator.est.eph, ctx->dt, calc_length_pythagorean_2D(flowResidualX, flowResidualY), positionEstimationConfig()->w_xy_flow_p); + ctx->newEPH = updateEPE(posEstimator.est.eph, dt, calc_length_pythagorean_2D(flowResidualX, flowResidualY), w_xy_flow_p); } DEBUG_SET(DEBUG_FLOW, 0, RADIANS_TO_DEGREES(posEstimator.flow.flowRate[X])); @@ -115,7 +124,7 @@ bool estimationCalculateCorrection_XY_FLOW(estimationContext_t * ctx) DEBUG_SET(DEBUG_FLOW, 2, posEstimator.est.flowCoordinates[X]); DEBUG_SET(DEBUG_FLOW, 3, posEstimator.est.flowCoordinates[Y]); - return true; + return ctx->applyCorrections = true; #else UNUSED(ctx); return false; diff --git a/src/main/navigation/navigation_pos_estimator_private.h b/src/main/navigation/navigation_pos_estimator_private.h index fc824eb534e..8a91afe268b 100644 --- a/src/main/navigation/navigation_pos_estimator_private.h +++ b/src/main/navigation/navigation_pos_estimator_private.h @@ -71,6 +71,7 @@ typedef struct { fpVector3_t vel; // GPS velocity (cms) float eph; float epv; + float updateDt; } navPositionEstimatorGPS_t; typedef struct { @@ -79,6 +80,7 @@ typedef struct { float alt; // Raw barometric altitude (cm) float epv; float baroAltRate; // Baro altitude rate of change (cm/s) + float updateDt; } navPositionEstimatorBARO_t; typedef struct { @@ -105,6 +107,7 @@ typedef struct { float quality; float flowRate[2]; float bodyRate[2]; + float updateDt; } navPositionEstimatorFLOW_t; typedef struct { @@ -180,6 +183,7 @@ typedef struct { fpVector3_t estPosCorr; fpVector3_t estVelCorr; fpVector3_t accBiasCorr; + bool applyCorrections; } estimationContext_t; extern navigationPosEstimator_t posEstimator; diff --git a/src/main/sensors/opflow.c b/src/main/sensors/opflow.c index f82d8f16a58..024c5d403cf 100755 --- a/src/main/sensors/opflow.c +++ b/src/main/sensors/opflow.c @@ -171,6 +171,7 @@ void opflowUpdate(timeUs_t currentTimeUs) if (opflow.dev.updateFn(&opflow.dev)) { // Indicate valid update opflow.isHwHealty = true; + opflow.updateDt = US2S(currentTimeUs - opflow.lastValidUpdate); opflow.lastValidUpdate = currentTimeUs; opflow.rawQuality = opflow.dev.rawData.quality; diff --git a/src/main/sensors/opflow.h b/src/main/sensors/opflow.h index afe94ec79ac..a2f82745816 100755 --- a/src/main/sensors/opflow.h +++ b/src/main/sensors/opflow.h @@ -53,6 +53,7 @@ typedef struct opflow_s { opflowQuality_e flowQuality; timeUs_t lastValidUpdate; + float updateDt; bool isHwHealty; float flowRate[2]; // optical flow angular rate in rad/sec measured about the X and Y body axis float bodyRate[2]; // body inertial angular rate in rad/sec measured about the X and Y body axis diff --git a/src/main/target/DYSF4/CMakeLists.txt b/src/main/target/DYSF4/CMakeLists.txt new file mode 100644 index 00000000000..ec00b5acc49 --- /dev/null +++ b/src/main/target/DYSF4/CMakeLists.txt @@ -0,0 +1,2 @@ +target_stm32f405xg(DYSF4PRO) +target_stm32f405xg(DYSF4PROV2) diff --git a/src/main/target/DYSF4/target.c b/src/main/target/DYSF4/target.c new file mode 100644 index 00000000000..d6de2e9bf25 --- /dev/null +++ b/src/main/target/DYSF4/target.c @@ -0,0 +1,47 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include + +#include +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" +#include "drivers/bus.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT D1_ST7 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT D1_ST2 + DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S3_OUT D1_ST6 + DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT D1_ST1 + + // { TIM9, IO_TAG(PA3), TIM_Channel_2, 1, IOCFG_AF_PP_PD, GPIO_AF_TIM9, TIM_USE_OUTPUT_AUTO }, // MOTOR_3 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT MOTOR, SERVO or LED + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT + + + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PPM, 0, 0), // PPM + DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0), // S2_IN + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // S3_IN, UART6_TX + DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // S4_IN, UART6_RX + DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0), // S5_IN + DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0), // S6_IN + +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/DYSF4/target.h b/src/main/target/DYSF4/target.h new file mode 100644 index 00000000000..76e79106afa --- /dev/null +++ b/src/main/target/DYSF4/target.h @@ -0,0 +1,159 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#pragma once + +// This directory contains: DYSF4PRO, DYSF4PROV2 + +#if defined(DYSF4PRO) +#define TARGET_BOARD_IDENTIFIER "DYS4" +#elif defined(DYSF4PROV2) +#define TARGET_BOARD_IDENTIFIER "DY42" +#endif + +#define USBD_PRODUCT_STRING "DysF4Pro" + +#define LED0 PB5 + +#define BEEPER PB4 +#define BEEPER_INVERTED + +#if defined(DYSF4PROV2) +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 +#define I2C_EXT_BUS BUS_I2C1 +#else +#define USE_I2C +#define USE_I2C_DEVICE_2 +#define I2C_DEVICE_2_SHARES_UART3 +#define I2C_EXT_BUS BUS_I2C2 +#endif + +#define UG2864_I2C_BUS I2C_EXT_BUS + +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW180_DEG + +#define USE_MAG +#define MAG_I2C_BUS I2C_EXT_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS I2C_EXT_BUS + +#define USE_BARO +#define BARO_I2C_BUS I2C_EXT_BUS +#define USE_BARO_BMP085 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 + +#define PITOT_I2C_BUS I2C_EXT_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS I2C_EXT_BUS + +#define USE_VCP +#define VBUS_SENSING_PIN PC5 +#define VBUS_SENSING_ENABLED + + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 +#define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PC8 +#define SOFTSERIAL_1_TX_PIN PC9 + +#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +#define USE_SPI + +#define USE_SPI_DEVICE_1 + + +#define USE_SPI_DEVICE_3 +#define SPI3_NSS_PIN PB3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT +#define M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 + +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 + +#ifdef DYSF4PRO + #define ADC_CHANNEL_3_PIN PC3 +#else + #define ADC_CHANNEL_3_PIN PA0 +#endif + +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO) + +#define USE_LED_STRIP +#define WS2811_PIN PA1 + +#define DISABLE_RX_PWM_FEATURE +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_VBAT | FEATURE_OSD) + +#define USE_SPEKTRUM_BIND +#define BIND_PIN PB11 // USART3 RX + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +// Number of available PWM outputs +#define MAX_PWM_OUTPUT_PORTS 6 +#define TARGET_MOTOR_COUNT 6 +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + diff --git a/src/main/target/NEXUSX/target.h b/src/main/target/NEXUSX/target.h index 24c035b4cae..abe7bbaef28 100644 --- a/src/main/target/NEXUSX/target.h +++ b/src/main/target/NEXUSX/target.h @@ -32,7 +32,7 @@ #define SPI1_MOSI_PIN PA7 #define USE_IMU_ICM42605 // is actually ICM42688P -#define IMU_ICM42605_ALIGN CW180_DEG +#define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN PA4 #define ICM42605_EXTI_PIN PB8 #define ICM42605_SPI_BUS BUS_SPI1 diff --git a/src/main/target/OMNIBUSF4/CMakeLists.txt b/src/main/target/OMNIBUSF4/CMakeLists.txt index 0e2bf2002c0..28f13c7cd5b 100644 --- a/src/main/target/OMNIBUSF4/CMakeLists.txt +++ b/src/main/target/OMNIBUSF4/CMakeLists.txt @@ -1,12 +1 @@ -target_stm32f405xg(DYSF4PRO) -target_stm32f405xg(DYSF4PROV2) target_stm32f405xg(OMNIBUSF4) -# the OMNIBUSF4SD has an SDCARD instead of flash, a BMP280 baro and therefore a slightly different ppm/pwm and SPI mapping -target_stm32f405xg(OMNIBUSF4PRO) -target_stm32f405xg(OMNIBUSF4V3_S5_S6_2SS) -target_stm32f405xg(OMNIBUSF4V3_S5S6_SS) -target_stm32f405xg(OMNIBUSF4V3_S6_SS) -# OMNIBUSF4V3 is a (almost identical) variant of OMNIBUSF4PRO target, -# except for an inverter on UART6. -target_stm32f405xg(OMNIBUSF4V3) -target_stm32f405xg(OMNIBUSF4V3_ICM SKIP_RELEASES) diff --git a/src/main/target/OMNIBUSF4/target.c b/src/main/target/OMNIBUSF4/target.c index be85e9fbce3..d6de2e9bf25 100644 --- a/src/main/target/OMNIBUSF4/target.c +++ b/src/main/target/OMNIBUSF4/target.c @@ -31,36 +31,16 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT D1_ST1 // { TIM9, IO_TAG(PA3), TIM_Channel_2, 1, IOCFG_AF_PP_PD, GPIO_AF_TIM9, TIM_USE_OUTPUT_AUTO }, // MOTOR_3 -#if (defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3)) && !(defined(OMNIBUSF4PRO_LEDSTRIPM5) || defined(OMNIBUSF4V3_S6_SS) || defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS)) - - DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT - DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT -#elif defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS) - DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0), // S5_OUT SOFTSERIAL - DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0), // S6_OUT SOFTSERIAL -#elif defined(OMNIBUSF4V3_S6_SS) - DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT - DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0), // S6_OUT SOFTSERIAL -#else DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT MOTOR, SERVO or LED DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT -#endif -#if (defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3)) - DEF_TIM(TIM4, CH1, PB6, TIM_USE_LED, 0, 0), // LED strip for F4 V2 / F4-Pro-0X and later (RCD_CS for F4) -#endif -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) - // DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM - DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0), // S2_IN -#else // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0), // S2_IN -#endif DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // S3_IN, UART6_TX DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // S4_IN, UART6_RX - DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0), // S5_IN // pad labelled CH5 on OMNIBUSF4PRO - DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0), // S6_IN // pad labelled CH6 on OMNIBUSF4PRO + DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0), // S5_IN + DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0), // S6_IN }; diff --git a/src/main/target/OMNIBUSF4/target.h b/src/main/target/OMNIBUSF4/target.h index fcd89fb0e46..af906bb8b12 100644 --- a/src/main/target/OMNIBUSF4/target.h +++ b/src/main/target/OMNIBUSF4/target.h @@ -17,86 +17,27 @@ #pragma once -//Same target as OMNIBUSF4PRO with LED strip in M5 -#ifdef OMNIBUSF4PRO_LEDSTRIPM5 -#define OMNIBUSF4PRO -#endif -//Same target as OMNIBUSF4V3 with softserial in M5 and M6 -#if defined(OMNIBUSF4V3_S6_SS) || defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS) -#define OMNIBUSF4V3 -#endif - -#ifdef OMNIBUSF4PRO -#define TARGET_BOARD_IDENTIFIER "OBSD" -#elif defined(OMNIBUSF4V3) -#define TARGET_BOARD_IDENTIFIER "OB43" -#elif defined(OMNIBUSF4V3_ICM) -#define TARGET_BOARD_IDENTIFIER "OB4I" -#elif defined(DYSF4PRO) -#define TARGET_BOARD_IDENTIFIER "DYS4" -#elif defined(DYSF4PROV2) -#define TARGET_BOARD_IDENTIFIER "DY42" -#else #define TARGET_BOARD_IDENTIFIER "OBF4" -#endif -#if defined(DYSF4PRO) || defined(DYSF4PROV2) -#define USBD_PRODUCT_STRING "DysF4Pro" -#else #define USBD_PRODUCT_STRING "Omnibus F4" -#endif #define LED0 PB5 #define BEEPER PB4 #define BEEPER_INVERTED -#if defined(DYSF4PROV2) -#define USE_I2C -#define USE_I2C_DEVICE_1 -#define I2C1_SCL PB8 -#define I2C1_SDA PB9 -#define I2C_EXT_BUS BUS_I2C1 -#else #define USE_I2C #define USE_I2C_DEVICE_2 #define I2C_DEVICE_2_SHARES_UART3 #define I2C_EXT_BUS BUS_I2C2 -#endif #define UG2864_I2C_BUS I2C_EXT_BUS #define MPU6000_CS_PIN PA4 #define MPU6000_SPI_BUS BUS_SPI1 -#if defined(OMNIBUSF4V3_ICM) - #define USE_IMU_ICM42605 - #define IMU_ICM42605_ALIGN CW180_DEG - #define ICM42605_CS_PIN PA4 - #define ICM42605_SPI_BUS BUS_SPI1 -#endif - -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define USE_IMU_MPU6000 - #define IMU_MPU6000_ALIGN CW270_DEG -#else - #define USE_IMU_MPU6000 - #define IMU_MPU6000_ALIGN CW180_DEG -#endif - -// Support for OMNIBUS F4 PRO CORNER - it has MPU6500/ICM20608 instead of MPU6000 -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define MPU6500_CS_PIN MPU6000_CS_PIN - #define MPU6500_SPI_BUS MPU6000_SPI_BUS - #define USE_IMU_MPU6500 - #define IMU_MPU6500_ALIGN IMU_MPU6000_ALIGN - - //BMI270 - #define USE_IMU_BMI270 - #define IMU_BMI270_ALIGN IMU_MPU6000_ALIGN - #define BMI270_SPI_BUS MPU6000_SPI_BUS - #define BMI270_CS_PIN MPU6000_CS_PIN -#endif +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW180_DEG #define USE_MAG #define MAG_I2C_BUS I2C_EXT_BUS @@ -105,21 +46,10 @@ #define TEMPERATURE_I2C_BUS I2C_EXT_BUS #define USE_BARO - -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define USE_BARO_BMP280 - #define BMP280_SPI_BUS BUS_SPI3 - #define BMP280_CS_PIN PB3 // v1 - // Support external barometers - #define BARO_I2C_BUS I2C_EXT_BUS - #define USE_BARO_BMP085 - #define USE_BARO_MS5611 -#else - #define BARO_I2C_BUS I2C_EXT_BUS - #define USE_BARO_BMP085 - #define USE_BARO_BMP280 - #define USE_BARO_MS5611 -#endif +#define BARO_I2C_BUS I2C_EXT_BUS +#define USE_BARO_BMP085 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 #define PITOT_I2C_BUS I2C_EXT_BUS @@ -130,17 +60,11 @@ #define VBUS_SENSING_PIN PC5 #define VBUS_SENSING_ENABLED -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) -#define USE_UART_INVERTER -#endif #define USE_UART1 #define UART1_RX_PIN PA10 #define UART1_TX_PIN PA9 #define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2 -#if defined(OMNIBUSF4PRO) -#define INVERTER_PIN_UART1_RX PC0 // PC0 has never been used as inverter control on genuine OMNIBUS F4 variants, but leave it as is since some clones actually implement it. -#endif #define USE_UART3 #define UART3_RX_PIN PB11 @@ -149,51 +73,13 @@ #define USE_UART6 #define UART6_RX_PIN PC7 #define UART6_TX_PIN PC6 -#if defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define INVERTER_PIN_UART6_RX PC8 - #define INVERTER_PIN_UART6_TX PC9 -#endif - -#if (defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM)) && !(defined(OMNIBUSF4V3_S6_SS) || defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS)) -#define USE_SOFTSERIAL1 -#define SOFTSERIAL_1_RX_PIN PC6 // shared with UART6 TX -#define SOFTSERIAL_1_TX_PIN PC6 // shared with UART6 TX - -#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 -#elif defined(OMNIBUSF4V3_S6_SS) // one softserial on S6 #define USE_SOFTSERIAL1 -#define SOFTSERIAL_1_RX_PIN PA8 // S6 output -#define SOFTSERIAL_1_TX_PIN PA8 // S6 output +#define SOFTSERIAL_1_RX_PIN PC8 +#define SOFTSERIAL_1_TX_PIN PC9 #define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 -#elif defined(OMNIBUSF4V3_S5S6_SS) // one softserial on S5/RX S6/TX -#define USE_SOFTSERIAL1 -#define SOFTSERIAL_1_RX_PIN PA1 // S5 output -#define SOFTSERIAL_1_TX_PIN PA8 // S6 output - -#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 - -#elif defined(OMNIBUSF4V3_S5_S6_2SS) // two softserials, one on S5 and one on S6 -#define USE_SOFTSERIAL1 -#define SOFTSERIAL_1_RX_PIN PA1 // S5 output -#define SOFTSERIAL_1_TX_PIN PA1 // S5 output - -#define USE_SOFTSERIAL2 -#define SOFTSERIAL_2_RX_PIN PA8 // S6 output -#define SOFTSERIAL_2_TX_PIN PA8 // S6 output - -#define SERIAL_PORT_COUNT 6 // VCP, USART1, USART3, USART6, SOFTSERIAL1, SOFTSERIAL2 - -#else // One softserial on versions other than OMNIBUSF4V3 -#define USE_SOFTSERIAL1 -#define SOFTSERIAL_1_RX_PIN PC8 // pad labelled CH5 on OMNIBUSF4PRO -#define SOFTSERIAL_1_TX_PIN PC9 // pad labelled CH6 on OMNIBUSF4PRO - -#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 -#endif - #define DEFAULT_RX_TYPE RX_TYPE_SERIAL #define SERIALRX_PROVIDER SERIALRX_SBUS #define SERIALRX_UART SERIAL_PORT_USART1 @@ -202,20 +88,8 @@ #define USE_SPI_DEVICE_1 -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define USE_SPI_DEVICE_2 - #define SPI2_NSS_PIN PB12 - #define SPI2_SCK_PIN PB13 - #define SPI2_MISO_PIN PB14 - #define SPI2_MOSI_PIN PB15 -#endif - #define USE_SPI_DEVICE_3 -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define SPI3_NSS_PIN PA15 -#else - #define SPI3_NSS_PIN PB3 -#endif +#define SPI3_NSS_PIN PB3 #define SPI3_SCK_PIN PC10 #define SPI3_MISO_PIN PC11 #define SPI3_MOSI_PIN PC12 @@ -224,33 +98,16 @@ #define MAX7456_SPI_BUS BUS_SPI3 #define MAX7456_CS_PIN PA15 -#if defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM) - #define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT - #define USE_SDCARD - #define USE_SDCARD_SPI - - #define SDCARD_SPI_BUS BUS_SPI2 - #define SDCARD_CS_PIN SPI2_NSS_PIN - - #define SDCARD_DETECT_PIN PB7 - #define SDCARD_DETECT_INVERTED -#else - #define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT - #define M25P16_CS_PIN SPI3_NSS_PIN - #define M25P16_SPI_BUS BUS_SPI3 - #define USE_FLASHFS - #define USE_FLASH_M25P16 -#endif +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT +#define M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 #define USE_ADC #define ADC_CHANNEL_1_PIN PC1 #define ADC_CHANNEL_2_PIN PC2 - -#ifdef DYSF4PRO - #define ADC_CHANNEL_3_PIN PC3 -#else - #define ADC_CHANNEL_3_PIN PA0 -#endif +#define ADC_CHANNEL_3_PIN PA0 #define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 #define VBAT_ADC_CHANNEL ADC_CHN_2 @@ -259,11 +116,7 @@ #define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO) #define USE_LED_STRIP -#if (defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3) || defined(OMNIBUSF4V3_ICM)) && !defined(OMNIBUSF4PRO_LEDSTRIPM5) - #define WS2811_PIN PB6 -#else - #define WS2811_PIN PA1 -#endif +#define WS2811_PIN PA1 #define DISABLE_RX_PWM_FEATURE #define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_VBAT | FEATURE_OSD) @@ -283,7 +136,3 @@ #define TARGET_IO_PORTB 0xffff #define TARGET_IO_PORTC 0xffff #define TARGET_IO_PORTD 0xffff - -#ifdef OMNIBUSF4PRO -#define CURRENT_METER_SCALE 265 -#endif diff --git a/src/main/target/OMNIBUSF4PRO/CMakeLists.txt b/src/main/target/OMNIBUSF4PRO/CMakeLists.txt new file mode 100644 index 00000000000..e09984ac0a9 --- /dev/null +++ b/src/main/target/OMNIBUSF4PRO/CMakeLists.txt @@ -0,0 +1,5 @@ +# OMNIBUSF4PRO has SD card, BMP280 baro +target_stm32f405xg(OMNIBUSF4PRO) +# OMNIBUSF4V3 is similar to PRO but with UART6 inverter +target_stm32f405xg(OMNIBUSF4V3) +target_stm32f405xg(OMNIBUSF4V3_ICM SKIP_RELEASES) diff --git a/src/main/target/OMNIBUSF4PRO/target.c b/src/main/target/OMNIBUSF4PRO/target.c new file mode 100644 index 00000000000..29cb945af85 --- /dev/null +++ b/src/main/target/OMNIBUSF4PRO/target.c @@ -0,0 +1,48 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include + +#include +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" +#include "drivers/bus.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT D1_ST7 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT D1_ST2 + DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S3_OUT D1_ST6 + DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT D1_ST1 + + // { TIM9, IO_TAG(PA3), TIM_Channel_2, 1, IOCFG_AF_PP_PD, GPIO_AF_TIM9, TIM_USE_OUTPUT_AUTO }, // MOTOR_3 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT + + DEF_TIM(TIM4, CH1, PB6, TIM_USE_LED, 0, 0), // LED strip for F4 V2 / F4-Pro-0X and later (RCD_CS for F4) + + // DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM + DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0), // S2_IN + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // S3_IN, UART6_TX + DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // S4_IN, UART6_RX + DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0), // S5_IN // pad labelled CH5 on OMNIBUSF4PRO + DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0), // S6_IN // pad labelled CH6 on OMNIBUSF4PRO + +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/OMNIBUSF4PRO/target.h b/src/main/target/OMNIBUSF4PRO/target.h new file mode 100644 index 00000000000..f9d7e3af4de --- /dev/null +++ b/src/main/target/OMNIBUSF4PRO/target.h @@ -0,0 +1,202 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#pragma once + +// This directory contains: OMNIBUSF4PRO, OMNIBUSF4V3, OMNIBUSF4V3_ICM +// Softserial variants are in separate OMNIBUSF4V3_SS/ directory + +#ifdef OMNIBUSF4V3_ICM +#define OMNIBUSF4V3 +#endif + +#ifdef OMNIBUSF4PRO +#define TARGET_BOARD_IDENTIFIER "OBSD" +#elif defined(OMNIBUSF4V3) +#define TARGET_BOARD_IDENTIFIER "OB43" +#endif + +#define USBD_PRODUCT_STRING "Omnibus F4" + +#define LED0 PB5 + +#define BEEPER PB4 +#define BEEPER_INVERTED + +#define USE_I2C +#define USE_I2C_DEVICE_2 +#define I2C_DEVICE_2_SHARES_UART3 +#define I2C_EXT_BUS BUS_I2C2 + +#define UG2864_I2C_BUS I2C_EXT_BUS + +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG + +// Support for OMNIBUS F4 PRO CORNER - it has ICM20608 instead of MPU6000 +#define MPU6500_CS_PIN MPU6000_CS_PIN +#define MPU6500_SPI_BUS MPU6000_SPI_BUS +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN IMU_MPU6000_ALIGN + +//BMI270 +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN IMU_MPU6000_ALIGN +#define BMI270_SPI_BUS MPU6000_SPI_BUS +#define BMI270_CS_PIN MPU6000_CS_PIN + +#ifdef OMNIBUSF4V3_ICM +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW180_DEG +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 +#endif + +#define USE_MAG +#define MAG_I2C_BUS I2C_EXT_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS I2C_EXT_BUS + +#define USE_BARO +#define USE_BARO_BMP280 +#define BMP280_SPI_BUS BUS_SPI3 +#define BMP280_CS_PIN PB3 // v1 +// Support external barometers +#define BARO_I2C_BUS I2C_EXT_BUS +#define USE_BARO_BMP085 +#define USE_BARO_MS5611 + +#define PITOT_I2C_BUS I2C_EXT_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS I2C_EXT_BUS + +#define USE_VCP +#define VBUS_SENSING_PIN PC5 +#define VBUS_SENSING_ENABLED + +#define USE_UART_INVERTER + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 +#define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2 +#if defined(OMNIBUSF4PRO) +#define INVERTER_PIN_UART1_RX PC0 // PC0 has never been used as inverter control on genuine OMNIBUS F4 variants, but leave it as is since some clones actually implement it. +#endif + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 +#if defined(OMNIBUSF4V3) + #define INVERTER_PIN_UART6_RX PC8 + #define INVERTER_PIN_UART6_TX PC9 +#endif + +#if defined(OMNIBUSF4V3) +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PC6 // shared with UART6 TX +#define SOFTSERIAL_1_TX_PIN PC6 // shared with UART6 TX + +#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 + +#else // OMNIBUSF4PRO +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PC8 // pad labelled CH5 on OMNIBUSF4PRO +#define SOFTSERIAL_1_TX_PIN PC9 // pad labelled CH6 on OMNIBUSF4PRO + +#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 +#endif + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +#define USE_SPI + +#define USE_SPI_DEVICE_1 + +#define USE_SPI_DEVICE_2 +#define SPI2_NSS_PIN PB12 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_NSS_PIN PA15 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT +#define USE_SDCARD +#define USE_SDCARD_SPI + +#define SDCARD_SPI_BUS BUS_SPI2 +#define SDCARD_CS_PIN SPI2_NSS_PIN + +#define SDCARD_DETECT_PIN PB7 +#define SDCARD_DETECT_INVERTED + +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PA0 + +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO) + +#define USE_LED_STRIP +#define WS2811_PIN PB6 + +#define DISABLE_RX_PWM_FEATURE +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_VBAT | FEATURE_OSD) + +#define USE_SPEKTRUM_BIND +#define BIND_PIN PB11 // USART3 RX + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +// Number of available PWM outputs +#define MAX_PWM_OUTPUT_PORTS 6 +#define TARGET_MOTOR_COUNT 6 +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#ifdef OMNIBUSF4PRO +#define CURRENT_METER_SCALE 265 +#endif diff --git a/src/main/target/OMNIBUSF4V3_SS/CMakeLists.txt b/src/main/target/OMNIBUSF4V3_SS/CMakeLists.txt new file mode 100644 index 00000000000..321eeb211d1 --- /dev/null +++ b/src/main/target/OMNIBUSF4V3_SS/CMakeLists.txt @@ -0,0 +1,4 @@ +# OMNIBUSF4V3 softserial variants with different S5/S6 timer configurations +target_stm32f405xg(OMNIBUSF4V3_S6_SS) +target_stm32f405xg(OMNIBUSF4V3_S5S6_SS) +target_stm32f405xg(OMNIBUSF4V3_S5_S6_2SS) diff --git a/src/main/target/OMNIBUSF4V3_SS/target.c b/src/main/target/OMNIBUSF4V3_SS/target.c new file mode 100644 index 00000000000..95b496e8bfb --- /dev/null +++ b/src/main/target/OMNIBUSF4V3_SS/target.c @@ -0,0 +1,53 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include + +#include +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" +#include "drivers/bus.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT D1_ST7 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT D1_ST2 + DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S3_OUT D1_ST6 + DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT D1_ST1 + + // { TIM9, IO_TAG(PA3), TIM_Channel_2, 1, IOCFG_AF_PP_PD, GPIO_AF_TIM9, TIM_USE_OUTPUT_AUTO }, // MOTOR_3 +#if defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS) + DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0), // S5_OUT SOFTSERIAL + DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0), // S6_OUT SOFTSERIAL +#elif defined(OMNIBUSF4V3_S6_SS) + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT + DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0), // S6_OUT SOFTSERIAL +#endif + + DEF_TIM(TIM4, CH1, PB6, TIM_USE_LED, 0, 0), // LED strip for F4 V2 / F4-Pro-0X and later (RCD_CS for F4) + + // DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM + DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0), // S2_IN + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // S3_IN, UART6_TX + DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // S4_IN, UART6_RX + DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0), // S5_IN + DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0), // S6_IN + +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/OMNIBUSF4V3_SS/target.h b/src/main/target/OMNIBUSF4V3_SS/target.h new file mode 100644 index 00000000000..f3cbf6c4a49 --- /dev/null +++ b/src/main/target/OMNIBUSF4V3_SS/target.h @@ -0,0 +1,193 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#pragma once + +// This directory contains: OMNIBUSF4V3_S6_SS, OMNIBUSF4V3_S5S6_SS, OMNIBUSF4V3_S5_S6_2SS +// Softserial variants of OMNIBUSF4V3 with different S5/S6 timer configurations +#if defined(OMNIBUSF4V3_S6_SS) || defined(OMNIBUSF4V3_S5S6_SS) || defined(OMNIBUSF4V3_S5_S6_2SS) +#define OMNIBUSF4V3 +#endif + +#define TARGET_BOARD_IDENTIFIER "OB43" + +#define USBD_PRODUCT_STRING "Omnibus F4" + +#define LED0 PB5 + +#define BEEPER PB4 +#define BEEPER_INVERTED + +#define USE_I2C +#define USE_I2C_DEVICE_2 +#define I2C_DEVICE_2_SHARES_UART3 +#define I2C_EXT_BUS BUS_I2C2 + +#define UG2864_I2C_BUS I2C_EXT_BUS + +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG + +// Support for OMNIBUS F4 PRO CORNER - it has ICM20608 instead of MPU6000 +#define MPU6500_CS_PIN MPU6000_CS_PIN +#define MPU6500_SPI_BUS MPU6000_SPI_BUS +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN IMU_MPU6000_ALIGN + +//BMI270 +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN IMU_MPU6000_ALIGN +#define BMI270_SPI_BUS MPU6000_SPI_BUS +#define BMI270_CS_PIN MPU6000_CS_PIN + +#define USE_MAG +#define MAG_I2C_BUS I2C_EXT_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS I2C_EXT_BUS + +#define USE_BARO +#define USE_BARO_BMP280 +#define BMP280_SPI_BUS BUS_SPI3 +#define BMP280_CS_PIN PB3 // v1 +// Support external barometers +#define BARO_I2C_BUS I2C_EXT_BUS +#define USE_BARO_BMP085 +#define USE_BARO_MS5611 + +#define PITOT_I2C_BUS I2C_EXT_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS I2C_EXT_BUS + +#define USE_VCP +#define VBUS_SENSING_PIN PC5 +#define VBUS_SENSING_ENABLED + +#define USE_UART_INVERTER + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 +#define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 +#define INVERTER_PIN_UART6_RX PC8 +#define INVERTER_PIN_UART6_TX PC9 + +#if defined(OMNIBUSF4V3_S6_SS) // one softserial on S6 +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PA8 // S6 output +#define SOFTSERIAL_1_TX_PIN PA8 // S6 output + +#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 + +#elif defined(OMNIBUSF4V3_S5S6_SS) // one softserial on S5/RX S6/TX +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PA1 // S5 output +#define SOFTSERIAL_1_TX_PIN PA8 // S6 output + +#define SERIAL_PORT_COUNT 5 // VCP, USART1, USART3, USART6, SOFTSERIAL1 + +#elif defined(OMNIBUSF4V3_S5_S6_2SS) // two softserials, one on S5 and one on S6 +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_RX_PIN PA1 // S5 output +#define SOFTSERIAL_1_TX_PIN PA1 // S5 output + +#define USE_SOFTSERIAL2 +#define SOFTSERIAL_2_RX_PIN PA8 // S6 output +#define SOFTSERIAL_2_TX_PIN PA8 // S6 output + +#define SERIAL_PORT_COUNT 6 // VCP, USART1, USART3, USART6, SOFTSERIAL1, SOFTSERIAL2 +#endif + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +#define USE_SPI + +#define USE_SPI_DEVICE_1 + +#define USE_SPI_DEVICE_2 +#define SPI2_NSS_PIN PB12 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_NSS_PIN PA15 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT +#define USE_SDCARD +#define USE_SDCARD_SPI + +#define SDCARD_SPI_BUS BUS_SPI2 +#define SDCARD_CS_PIN SPI2_NSS_PIN + +#define SDCARD_DETECT_PIN PB7 +#define SDCARD_DETECT_INVERTED + +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PA0 + +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO) + +#define USE_LED_STRIP +#define WS2811_PIN PB6 + +#define DISABLE_RX_PWM_FEATURE +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_VBAT | FEATURE_OSD) + +#define USE_SPEKTRUM_BIND +#define BIND_PIN PB11 // USART3 RX + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +// Number of available PWM outputs +#define MAX_PWM_OUTPUT_PORTS 6 +#define TARGET_MOTOR_COUNT 6 +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff +