diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf911321f14..f3a856bc7f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,6 +107,16 @@ jobs: with: name: targets path: targets.txt + - name: Save PR number + if: github.event_name == 'pull_request' + run: echo "${{ github.event.pull_request.number }}" > pr_number.txt + - name: Upload PR number + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: pr-number + path: pr_number.txt + retention-days: 1 build-SITL-Linux-arm64: runs-on: ubuntu-22.04-arm diff --git a/.github/workflows/pr-test-builds.yml b/.github/workflows/pr-test-builds.yml new file mode 100644 index 00000000000..cf4a32b7b57 --- /dev/null +++ b/.github/workflows/pr-test-builds.yml @@ -0,0 +1,153 @@ +name: PR Test Builds + +# Runs after "Build firmware" completes. Uses workflow_run (rather than +# pull_request directly) so that secrets are available even for PRs from forks. +# +# Requires a repository secret PR_BUILDS_TOKEN with Contents: write access +# to iNavFlight/pr-test-builds (fine-grained PAT or classic PAT with repo scope). +on: + workflow_run: + workflows: ["Build firmware"] + types: [completed] + +jobs: + publish: + runs-on: ubuntu-latest + # Only act on pull_request-triggered runs that succeeded. + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + # Prevent concurrent runs for the same PR branch racing on the + # release delete/create cycle. + concurrency: + group: pr-test-build-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }} + cancel-in-progress: true + permissions: + actions: read # to download artifacts from the triggering workflow run + issues: write # github.rest.issues.* endpoints used to post PR comments + pull-requests: write # to post the PR comment + + steps: + - name: Download PR number + uses: actions/download-artifact@v4 + with: + name: pr-number + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Read PR number + id: pr + run: | + PR_NUM=$(tr -dc '0-9' < pr_number.txt) + if [ -z "$PR_NUM" ]; then + echo "::error::Invalid PR number in artifact" + exit 1 + fi + echo "number=${PR_NUM}" >> $GITHUB_OUTPUT + + - name: Download firmware artifacts + uses: actions/download-artifact@v4 + with: + pattern: matrix-inav-* + merge-multiple: true + path: hexes + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get build info + id: info + run: | + COUNT=$(find hexes -name '*.hex' -type f | wc -l) + if [ "$COUNT" -eq 0 ]; then + echo "::error::No .hex files found in downloaded artifacts" + exit 1 + fi + echo "count=${COUNT}" >> $GITHUB_OUTPUT + echo "short_sha=$(echo '${{ github.event.workflow_run.head_sha }}' | cut -c1-7)" >> $GITHUB_OUTPUT + + # Delete the previous release for this PR (if any) so assets are replaced + # cleanly on each new commit. --cleanup-tag removes the old tag so it is + # recreated fresh pointing to the new commit. + - name: Delete existing PR release + env: + GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }} + run: | + gh release delete "pr-${{ steps.pr.outputs.number }}" \ + --repo iNavFlight/pr-test-builds --cleanup-tag --yes 2>/dev/null || true + + - name: Create PR release + env: + GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }} + PR_NUMBER: ${{ steps.pr.outputs.number }} + SHORT_SHA: ${{ steps.info.outputs.short_sha }} + HEX_COUNT: ${{ steps.info.outputs.count }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + REPO: ${{ github.repository }} + run: | + PR_URL="https://github.com/${REPO}/pull/${PR_NUMBER}" + printf '%s\n\n%s\n\n%s\n' \ + "Test build for [PR #${PR_NUMBER}](${PR_URL}) — commit \`${SHORT_SHA}\`" \ + "**${HEX_COUNT} targets built.** Find your board's \`.hex\` file by name (e.g. \`MATEKF405SE.hex\`)." \ + "> Development build for testing only. Use Full Chip Erase when flashing." \ + > release-notes.md + gh release create "pr-${PR_NUMBER}" hexes/*.hex \ + --repo iNavFlight/pr-test-builds \ + --prerelease \ + --target "${HEAD_SHA}" \ + --title "PR #${PR_NUMBER} (${SHORT_SHA})" \ + --notes-file release-notes.md + + - name: Post or update PR comment + uses: actions/github-script@v7 + env: + PR_NUMBER: ${{ steps.pr.outputs.number }} + SHORT_SHA: ${{ steps.info.outputs.short_sha }} + HEX_COUNT: ${{ steps.info.outputs.count }} + with: + script: | + const prNumber = parseInt(process.env.PR_NUMBER, 10); + if (isNaN(prNumber)) throw new Error(`Invalid PR number: ${process.env.PR_NUMBER}`); + const shortSha = process.env.SHORT_SHA; + const count = process.env.HEX_COUNT; + const releaseUrl = `https://github.com/iNavFlight/pr-test-builds/releases/tag/pr-${prNumber}`; + + const body = [ + '', + '**Test firmware build ready** — commit `' + shortSha + '`', + '', + `[Download firmware for PR #${prNumber}](${releaseUrl})`, + '', + `${count} targets built. Find your board's \`.hex\` file by name on that page ` + + '(e.g. `MATEKF405SE.hex`). Files are individually downloadable — no GitHub login required.', + '', + '> Development build for testing only. Use Full Chip Erase when flashing.', + ].join('\n'); + + const comments = await github.paginate( + github.rest.issues.listComments, + { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + } + ); + + const existing = comments.find(c => + c.user.type === 'Bot' && c.body.includes('') + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body, + }); + } diff --git a/docs/policies/NEW_HARDWARE_POLICY.md b/docs/policies/NEW_HARDWARE_POLICY.md index bd4bddedf05..10767524700 100644 --- a/docs/policies/NEW_HARDWARE_POLICY.md +++ b/docs/policies/NEW_HARDWARE_POLICY.md @@ -67,7 +67,7 @@ If one of the core developers has the hardware in possession they may opt in and 1. Requester is advised to open a feature request to add support for certain hardware to INAV by following [this link](https://github.com/iNavFlight/inav/issues/new/choose) -2. After opening a feature request, Requester is advised to contact the core development team by [email](mailto:coredev@inavflight.com) mentioning the open feature request and communicate with developer team via email to arrange hardware and specifications delivery. +2. After opening a feature request, Requester is advised to contact the core development team via [Discord](https://discord.gg/peg2hhbYwN) mentioning the open feature request and communicate with developer team via email to arrange hardware and specifications delivery. ## See also diff --git a/src/main/blackbox/blackbox.c b/src/main/blackbox/blackbox.c index e4c2afb3eec..7597f6d581f 100644 --- a/src/main/blackbox/blackbox.c +++ b/src/main/blackbox/blackbox.c @@ -99,7 +99,7 @@ #define BLACKBOX_INVERTED_CARD_DETECTION 0 #endif -PG_REGISTER_WITH_RESET_TEMPLATE(blackboxConfig_t, blackboxConfig, PG_BLACKBOX_CONFIG, 4); +PG_REGISTER_WITH_RESET_TEMPLATE(blackboxConfig_t, blackboxConfig, PG_BLACKBOX_CONFIG, 5); PG_RESET_TEMPLATE(blackboxConfig_t, blackboxConfig, .device = DEFAULT_BLACKBOX_DEVICE, diff --git a/src/main/blackbox/blackbox.h b/src/main/blackbox/blackbox.h index 1901201fa22..296291af0c7 100644 --- a/src/main/blackbox/blackbox.h +++ b/src/main/blackbox/blackbox.h @@ -54,11 +54,11 @@ typedef enum BlackboxState { } BlackboxState; typedef struct blackboxConfig_s { + uint32_t includeFlags; uint16_t rate_num; uint16_t rate_denom; uint8_t device; uint8_t invertedCardDetection; - uint32_t includeFlags; int8_t arm_control; } blackboxConfig_t; diff --git a/src/main/fc/stats.c b/src/main/fc/stats.c index 2fc4c63633d..f48b0862330 100644 --- a/src/main/fc/stats.c +++ b/src/main/fc/stats.c @@ -21,7 +21,7 @@ #define MIN_FLIGHT_DISTANCE_M 30 // minimum distance flown for a flight to be registered [m] -PG_REGISTER_WITH_RESET_TEMPLATE(statsConfig_t, statsConfig, PG_STATS_CONFIG, 2); +PG_REGISTER_WITH_RESET_TEMPLATE(statsConfig_t, statsConfig, PG_STATS_CONFIG, 3); PG_RESET_TEMPLATE(statsConfig_t, statsConfig, .stats_enabled = SETTING_STATS_DEFAULT, diff --git a/src/main/fc/stats.h b/src/main/fc/stats.h index d0b4b162b60..b2195165ffc 100644 --- a/src/main/fc/stats.h +++ b/src/main/fc/stats.h @@ -5,10 +5,10 @@ typedef struct statsConfig_s { uint32_t stats_total_time; // [Seconds] uint32_t stats_total_dist; // [Metres] - uint16_t stats_flight_count; #ifdef USE_ADC uint32_t stats_total_energy; // deciWatt hour (x0.1Wh) #endif + uint16_t stats_flight_count; uint8_t stats_enabled; } statsConfig_t; diff --git a/src/main/flight/pid.c b/src/main/flight/pid.c index 0a2faa648ca..cab56d73618 100644 --- a/src/main/flight/pid.c +++ b/src/main/flight/pid.c @@ -179,7 +179,7 @@ static EXTENDED_FASTRAM bool angleHoldIsLevel = false; static EXTENDED_FASTRAM float fixedWingLevelTrim; static EXTENDED_FASTRAM pidController_t fixedWingLevelTrimController; -PG_REGISTER_PROFILE_WITH_RESET_TEMPLATE(pidProfile_t, pidProfile, PG_PID_PROFILE, 11); +PG_REGISTER_PROFILE_WITH_RESET_TEMPLATE(pidProfile_t, pidProfile, PG_PID_PROFILE, 12); PG_RESET_TEMPLATE(pidProfile_t, pidProfile, .bank_mc = { diff --git a/src/main/flight/pid.h b/src/main/flight/pid.h index ff2e85031b7..523af380bb0 100644 --- a/src/main/flight/pid.h +++ b/src/main/flight/pid.h @@ -97,71 +97,72 @@ typedef enum { } itermRelax_e; typedef struct pidProfile_s { - uint8_t pidControllerType; + // Fields ordered largest-to-smallest to eliminate alignment padding holes pidBank_t bank_fw; pidBank_t bank_mc; - uint8_t dterm_lpf_type; // Dterm LPF type: PT1, BIQUAD - uint16_t dterm_lpf_hz; - - uint8_t yaw_lpf_hz; - - uint8_t heading_hold_rate_limit; // Maximum rotation rate HEADING_HOLD mode can feed to yaw rate PID controller - - uint8_t itermWindupPointPercent; // Experimental ITerm windup threshold, percent of motor saturation - - uint32_t axisAccelerationLimitYaw; // Max rate of change of yaw angular rate setpoint (deg/s^2 = dps/s) - uint32_t axisAccelerationLimitRollPitch; // Max rate of change of roll/pitch angular rate setpoint (deg/s^2 = dps/s) - - int16_t max_angle_inclination[ANGLE_INDEX_COUNT]; // Max possible inclination (roll and pitch axis separately - - uint16_t pidItermLimitPercent; - // Airplane-specific parameters float fixedWingReferenceAirspeed; // Reference tuning airspeed for the airplane - the speed for which PID gains are tuned float fixedWingCoordinatedYawGain; // This is the gain of the yaw rate required to keep the yaw rate consistent with the turn rate for a coordinated turn. - float fixedWingCoordinatedPitchGain; // This is the gain of the pitch rate to keep the pitch angle constant during coordinated turns. - uint16_t fixedWingYawItermBankFreeze; // Freeze yaw Iterm when bank angle is more than this many degrees - + float fixedWingCoordinatedPitchGain; // This is the gain of the pitch rate to keep the pitch angle constant during coordinated turns. float navVelXyDTermLpfHz; - uint8_t navVelXyDtermAttenuation; // VEL_XY dynamic Dterm scale: Dterm will be attenuatedby this value (in percent) when UAV is traveling with more than navVelXyDtermAttenuationStart percents of max velocity - uint8_t navVelXyDtermAttenuationStart; // VEL_XY dynamic Dterm scale: Dterm attenuation will begin at this percent of max velocity - uint8_t navVelXyDtermAttenuationEnd; // VEL_XY dynamic Dterm scale: Dterm will be fully attenuated at this percent of max velocity - uint8_t iterm_relax_cutoff; // This cutoff frequency specifies a low pass filter which predicts average response of the quad to setpoint - uint8_t iterm_relax; // Enable iterm suppression during stick input + float fixedWingLevelTrim; + float fixedWingLevelTrimGain; #ifdef USE_D_BOOST float dBoostMin; float dBoostMax; float dBoostMaxAtAlleceleration; - uint8_t dBoostGyroDeltaLpfHz; #endif #ifdef USE_ANTIGRAVITY float antigravityGain; float antigravityAccelerator; - uint8_t antigravityCutoff; #endif - uint16_t navFwPosHdgPidsumLimit; - uint8_t controlDerivativeLpfHz; - - float fixedWingLevelTrim; - float fixedWingLevelTrimGain; - - uint8_t fwAltControlResponseFactor; - bool fwAltControlUsePos; #ifdef USE_SMITH_PREDICTOR float smithPredictorStrength; float smithPredictorDelay; - uint16_t smithPredictorFilterHz; #endif + uint32_t axisAccelerationLimitYaw; // Max rate of change of yaw angular rate setpoint (deg/s^2 = dps/s) + uint32_t axisAccelerationLimitRollPitch; // Max rate of change of roll/pitch angular rate setpoint (deg/s^2 = dps/s) + int16_t max_angle_inclination[ANGLE_INDEX_COUNT]; // Max possible inclination (roll and pitch axis separately + uint16_t pidItermLimitPercent; + uint16_t fixedWingYawItermBankFreeze; // Freeze yaw Iterm when bank angle is more than this many degrees + uint16_t navFwPosHdgPidsumLimit; uint16_t fwItermLockTimeMaxMs; + uint16_t dterm_lpf_hz; + +#ifdef USE_SMITH_PREDICTOR + uint16_t smithPredictorFilterHz; +#endif + + uint8_t pidControllerType; + uint8_t dterm_lpf_type; // Dterm LPF type: PT1, BIQUAD + uint8_t yaw_lpf_hz; + uint8_t heading_hold_rate_limit; // Maximum rotation rate HEADING_HOLD mode can feed to yaw rate PID controller + uint8_t itermWindupPointPercent; // Experimental ITerm windup threshold, percent of motor saturation + uint8_t navVelXyDtermAttenuation; // VEL_XY dynamic Dterm scale: Dterm will be attenuated by this value (in percent) when UAV is traveling with more than navVelXyDtermAttenuationStart percents of max velocity + uint8_t navVelXyDtermAttenuationStart; // VEL_XY dynamic Dterm scale: Dterm attenuation will begin at this percent of max velocity + uint8_t navVelXyDtermAttenuationEnd; // VEL_XY dynamic Dterm scale: Dterm will be fully attenuated at this percent of max velocity + uint8_t iterm_relax_cutoff; // This cutoff frequency specifies a low pass filter which predicts average response of the quad to setpoint + uint8_t iterm_relax; // Enable iterm suppression during stick input + uint8_t controlDerivativeLpfHz; + uint8_t fwAltControlResponseFactor; + bool fwAltControlUsePos; uint8_t fwItermLockRateLimit; uint8_t fwItermLockEngageThreshold; +#ifdef USE_D_BOOST + uint8_t dBoostGyroDeltaLpfHz; +#endif + +#ifdef USE_ANTIGRAVITY + uint8_t antigravityCutoff; +#endif + } pidProfile_t; typedef struct pidAutotuneConfig_s { diff --git a/src/main/io/displayport_msp_osd.c b/src/main/io/displayport_msp_osd.c index 9dc99889bc1..2e70b8548f7 100644 --- a/src/main/io/displayport_msp_osd.c +++ b/src/main/io/displayport_msp_osd.c @@ -64,7 +64,6 @@ typedef enum { // defines are from hdzero code SD_3016, HD_5018, - HD_3016, // Special HDZERO mode that just sends the centre 30x16 of the 50x18 canvas to the VRX HD_6022, // added to support DJI wtfos 60x22 grid HD_5320 // added to support Avatar and BetaflightHD } resolutionType_e; @@ -139,31 +138,6 @@ static int output(displayPort_t *displayPort, uint8_t cmd, uint8_t *subcmd, int return sent; } -static uint8_t determineHDZeroOsdMode(void) -{ - if (cmsInMenu) { - return HD_5018; - } - - // Check if all visible widgets are in the center 30x16 chars of the canvas. - int activeLayout = osdGetActiveLayout(NULL); - osd_items_e index = 0; - do { - index = osdIncElementIndex(index); - uint16_t pos = osdLayoutsConfig()->item_pos[activeLayout][index]; - if (OSD_VISIBLE(pos)) { - uint8_t elemPosX = OSD_X(pos); - uint8_t elemPosY = OSD_Y(pos); - if (!osdItemIsFixed(index) && (elemPosX < 10 || elemPosX > 39 || elemPosY == 0 || elemPosY == 17)) { - return HD_5018; - } - } - } while (index > 0); - - return HD_3016; -} - - uint8_t setAttrPage(uint8_t origAttr, uint8_t page) { return (origAttr & ~DISPLAYPORT_MSP_ATTR_FONTPAGE_MASK) | (page & DISPLAYPORT_MSP_ATTR_FONTPAGE_MASK); @@ -181,10 +155,6 @@ uint8_t setAttrVersion(uint8_t origAttr, uint8_t version) static int setDisplayMode(displayPort_t *displayPort) { - if (osdVideoSystem == VIDEO_SYSTEM_HDZERO) { - currentOsdMode = determineHDZeroOsdMode(); // Can change between layouts - } - uint8_t subcmd[] = { MSP_DP_OPTIONS, 0, currentOsdMode }; // Font selection, mode (SD/HD) return output(displayPort, MSP_DISPLAYPORT, subcmd, sizeof(subcmd)); } diff --git a/src/main/navigation/navigation.h b/src/main/navigation/navigation.h index ddc7e23e76d..f4cb5120fc3 100644 --- a/src/main/navigation/navigation.h +++ b/src/main/navigation/navigation.h @@ -167,11 +167,11 @@ typedef struct geoZoneConfig_s typedef struct geozone_config_s { uint32_t fenceDetectionDistance; + uint32_t copterFenceStopDistance; uint16_t avoidAltitudeRange; uint16_t safeAltitudeDistance; bool nearestSafeHomeAsInclusivZone; uint8_t safeHomeFenceAction; - uint32_t copterFenceStopDistance; uint8_t noWayHomeAction; } geozone_config_t; diff --git a/src/main/navigation/navigation_geozone.c b/src/main/navigation/navigation_geozone.c index dfc7539859b..beb3051e0c5 100755 --- a/src/main/navigation/navigation_geozone.c +++ b/src/main/navigation/navigation_geozone.c @@ -124,7 +124,7 @@ static bool lockRTZ = false; geozone_t geozone; -PG_REGISTER_WITH_RESET_TEMPLATE(geozone_config_t, geoZoneConfig, PG_GEOZONE_CONFIG, 0); +PG_REGISTER_WITH_RESET_TEMPLATE(geozone_config_t, geoZoneConfig, PG_GEOZONE_CONFIG, 1); PG_RESET_TEMPLATE(geozone_config_t, geoZoneConfig, .fenceDetectionDistance = SETTING_GEOZONE_DETECTION_DISTANCE_DEFAULT, diff --git a/src/main/target/SDMODELH7V2/CMakeLists.txt b/src/main/target/SDMODELH7V2/CMakeLists.txt new file mode 100644 index 00000000000..ac26094e636 --- /dev/null +++ b/src/main/target/SDMODELH7V2/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32h743xi(SDMODELH7V2) diff --git a/src/main/target/SDMODELH7V2/config.c b/src/main/target/SDMODELH7V2/config.c new file mode 100644 index 00000000000..47f9da30bc5 --- /dev/null +++ b/src/main/target/SDMODELH7V2/config.c @@ -0,0 +1,38 @@ +/* + * This file is part of INAV. + * + * INAV 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. + * + * INAV 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 INAV. If not, see . + */ + +#include + +#include "platform.h" + +#include "fc/fc_msp_box.h" +#include "fc/config.h" + +#include "io/piniobox.h" +#include "drivers/serial.h" +#include "io/serial.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; + pinioBoxConfigMutable()->permanentId[2] = findBoxByActiveBoxId(BOXARM)->permanentId; + + // UART2 is connected to an onboard Bluetooth module (not user-accessible) + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART2)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART2)].msp_baudrateIndex = BAUD_115200; +} diff --git a/src/main/target/SDMODELH7V2/target.c b/src/main/target/SDMODELH7V2/target.c new file mode 100644 index 00000000000..b3da3c075b1 --- /dev/null +++ b/src/main/target/SDMODELH7V2/target.c @@ -0,0 +1,45 @@ +/* + * This file is part of INAV. + * + * INAV 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. + * + * INAV 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 INAV. If not, see . + */ + +#include + +#include "platform.h" + +#include "drivers/bus.h" +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" +#include "drivers/pinio.h" +#include "drivers/sensor.h" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 1), // M2 + + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 2), // M3 + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 0, 3), // M4 + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 4), // M5 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 5), // M6 + + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 6), // M7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 7), // M8 + + DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 14), // LED strip +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/SDMODELH7V2/target.h b/src/main/target/SDMODELH7V2/target.h new file mode 100644 index 00000000000..fcdc0898f18 --- /dev/null +++ b/src/main/target/SDMODELH7V2/target.h @@ -0,0 +1,183 @@ +/* + * This file is part of INAV. + * + * INAV 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. + * + * INAV 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 INAV. If not, see . + */ + +#pragma once + +#define TARGET_BOARD_IDENTIFIER "SDH7V2" +#define USBD_PRODUCT_STRING "SDMODELH7V2" + +#define USE_TARGET_CONFIG + +// *************** LED / BEEPER ********************** +#define LED0 PC2 + +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** SPI1 - SD Card ******************** +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +// *************** SPI2 - OSD (MAX7456) ************** +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// *************** SPI4 - IMU (MPU6000) ************** +#define USE_SPI_DEVICE_4 +#define SPI4_SCK_PIN PE2 +#define SPI4_MISO_PIN PE5 +#define SPI4_MOSI_PIN PE6 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG +#define MPU6000_SPI_BUS BUS_SPI4 +#define MPU6000_CS_PIN PE4 +#define MPU6000_EXTI_PIN PE1 + +// *************** I2C1 - Baro / Mag ***************** +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_IST8310 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS BUS_I2C1 + +// *************** SD Card (SPI) ********************* +#define USE_SDCARD +#define USE_SDCARD_SPI +#define SDCARD_SPI_BUS BUS_SPI1 +#define SDCARD_CS_PIN PA4 +#define SDCARD_DETECT_PIN PA3 +#define SDCARD_DETECT_INVERTED + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +// *************** UART ****************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define USE_UART2 +#define UART2_TX_PIN PD5 +#define UART2_RX_PIN PD6 + +#define USE_UART3 +#define UART3_TX_PIN PD8 +#define UART3_RX_PIN PD9 + +#define USE_UART4 +#define UART4_TX_PIN PD1 +#define UART4_RX_PIN PD0 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +// UART7 RX-only (ESC sensor); TX pin not routed but AF mapping requires a valid pin +#define USE_UART7 +#define UART7_TX_PIN PE8 +#define UART7_RX_PIN PE7 + +#define SERIAL_PORT_COUNT 7 // VCP, UART1-4, UART6, UART7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART6 + +// *************** ADC ******************************* +#define USE_ADC +#define ADC_INSTANCE ADC1 + +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC1 +#define ADC_CHANNEL_3_PIN PC5 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +#define VBAT_SCALE_DEFAULT 1090 +#define CURRENT_METER_SCALE 168 + +// *************** USB detect ************************ +#define USB_DETECT_PIN PA8 + +// *************** PINIO ***************************** +#define USE_PINIO +#define USE_PINIOBOX + +// VTX power +#define PINIO1_PIN PB11 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED + +// Cam pin +#define PINIO2_PIN PE9 +#define PINIO2_FLAGS PINIO_FLAGS_INVERTED + +// Bluetooth (off on arm) +#define PINIO3_PIN PE13 +#define PINIO3_FLAGS PINIO_FLAGS_INVERTED + +// *************** LED STRIP ************************* +#define USE_LED_STRIP +#define WS2811_PIN PD12 + +// *************** DEFAULT FEATURES ****************** +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) + +// *************** SERIAL 4WAY *********************** +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +// *************** ESC SENSOR ************************ +#define USE_ESC_SENSOR + +// *************** DSHOT ***************************** +#define USE_DSHOT + +// *************** IO PORT MASK ********************** +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff +#define TARGET_IO_PORTE 0xffff + +#define MAX_PWM_OUTPUT_PORTS 8