diff --git a/.gitignore b/.gitignore index b2c3b9ff546..6b7c8734dca 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ cov-int* /downloads/ /debug/ /release/ +/*_SITL/ # script-generated files docs/Manual.pdf diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100755 index 00000000000..6e7d914b25a --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,66 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceRoot}/src/main/**", + "${workspaceRoot}/lib/main/**", + "/usr/include/**" + ], + "browse": { + "limitSymbolsToIncludedHeaders": false, + "path": [ + "${workspaceRoot}/src/main/**", + "${workspaceRoot}/lib/main/**" + ] + }, + "intelliSenseMode": "linux-gcc-arm", + "cStandard": "c11", + "cppStandard": "c++17", + "defines": [ + "MCU_FLASH_SIZE 512", + "USE_NAV", + "NAV_FIXED_WING_LANDING", + "USE_OSD", + "USE_GYRO_NOTCH_1", + "USE_GYRO_NOTCH_2", + "USE_DTERM_NOTCH", + "USE_ACC_NOTCH", + "USE_GYRO_BIQUAD_RC_FIR2", + "USE_D_BOOST", + "USE_SERIALSHOT", + "USE_ANTIGRAVITY", + "USE_ASYNC_GYRO_PROCESSING", + "USE_RPM_FILTER", + "USE_GLOBAL_FUNCTIONS", + "USE_DYNAMIC_FILTERS", + "USE_IMU_BNO055", + "USE_SECONDARY_IMU", + "USE_DSHOT", + "FLASH_SIZE 480", + "USE_I2C_IO_EXPANDER", + "USE_PCF8574", + "USE_ESC_SENSOR", + "USE_PROGRAMMING_FRAMEWORK", + "USE_SERIALRX_GHST", + "USE_TELEMETRY_GHST", + "USE_CMS", + "USE_DJI_HD_OSD", + "USE_GYRO_KALMAN", + "USE_RANGEFINDER", + "USE_RATE_DYNAMICS", + "USE_SMITH_PREDICTOR", + "USE_ALPHA_BETA_GAMMA_FILTER", + "USE_MAG_VCM5883", + "USE_TELEMETRY_JETIEXBUS", + "USE_NAV", + "USE_SDCARD_SDIO", + "USE_SDCARD", + "USE_Q_TUNE", + "USE_GYRO_FFT_FILTER" + ], + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2cece3ee127..604b497ad6b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,11 +2,15 @@ "files.associations": { "chrono": "c", "cmath": "c", - "ranges": "c" + "ranges": "c", + "platform.h": "c", + "timer.h": "c", + "bus.h": "c" }, "editor.tabSize": 4, "editor.insertSpaces": true, "editor.detectIndentation": false, "editor.expandTabs": true, "C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: Google, IndentWidth: 4, BreakBeforeBraces: Mozilla }" + } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100755 index 00000000000..3ca90b787d3 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Matek F722-SE", + "type": "shell", + "command": "make MATEKF722SE", + "group": "build", + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}/build" + } + }, + { + "label": "Build Matek F722", + "type": "shell", + "command": "make MATEKF722", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}/build" + } + } + , + { + "label": "CMAKE Update", + "type": "shell", + "command": "cmake ..", + "group": "build", + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}/build" + } + } + ] +} \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 2a1f2744c48..7c2f94fcdb1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -56,6 +56,7 @@ Krzysztof Rosinski Kyle Manna Larry Davis Marc Egli +Marcelo Bezerra Mark Williams Martin Budden Matthew Evans diff --git a/CMakeLists.txt b/CMakeLists.txt index af42e31d7c1..3a2bd54e6e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ else() endif() endif() -project(INAV VERSION 7.0.0) +project(INAV VERSION 7.1.2) enable_language(ASM) diff --git a/Dockerfile b/Dockerfile index 9c816b0c183..4d2c144f57d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,9 @@ ARG USER_ID ARG GROUP_ID ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get install -y git cmake make ruby gcc python3 python3-pip gcc-arm-none-eabi +RUN apt-get update && apt-get install -y git cmake make ruby gcc python3 python3-pip gcc-arm-none-eabi ninja-build + +RUN if [ "$GDB" = "yes" ]; then apt-get install -y gdb; fi RUN pip install pyyaml @@ -13,6 +15,7 @@ RUN addgroup --gid $GROUP_ID inav; exit 0; RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID inav; exit 0; USER inav + RUN git config --global --add safe.directory /src VOLUME /src diff --git a/cmake/docker.sh b/cmake/docker.sh index 3c10ebc8e1d..843e03a48a2 100755 --- a/cmake/docker.sh +++ b/cmake/docker.sh @@ -6,7 +6,7 @@ CURR_REV="$(git rev-parse HEAD)" initialize_cmake() { echo -e "*** CMake was not initialized yet, doing it now.\n" - cmake .. + cmake -GNinja .. echo "$CURR_REV" > "$LAST_CMAKE_AT_REV_FILE" } @@ -26,4 +26,4 @@ else fi # Let Make handle the arguments coming from the build script -make "$@" +ninja "$@" diff --git a/cmake/docker_build_sitl.sh b/cmake/docker_build_sitl.sh new file mode 100644 index 00000000000..a79742ae0ff --- /dev/null +++ b/cmake/docker_build_sitl.sh @@ -0,0 +1,7 @@ +#!/bin/bash +rm -r build_SITL +mkdir -p build_SITL +#cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -GNinja -B build_SITL .. +cmake -DSITL=ON -DDEBUG=ON -DWARNINGS_AS_ERRORS=ON -GNinja -B build_SITL .. +cd build_SITL +ninja \ No newline at end of file diff --git a/cmake/docker_run_sitl.sh b/cmake/docker_run_sitl.sh new file mode 100644 index 00000000000..b2089137ccb --- /dev/null +++ b/cmake/docker_run_sitl.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd build_SITL + +#Lauch SITL - configurator only mode +./inav_7.0.0_SITL + +#Launch SITL - connect to X-Plane. IP address should be host IP address, not 127.0.0.1. Can be found in X-Plane "Network" tab. +#./inav_7.0.0_SITL --sim=xp --simip=192.168.2.105 --simport=49000 \ No newline at end of file diff --git a/cmake/sitl.cmake b/cmake/sitl.cmake index 24a4ae9b27e..ee43aa9a93a 100644 --- a/cmake/sitl.cmake +++ b/cmake/sitl.cmake @@ -34,7 +34,7 @@ set(SITL_LINK_OPTIONS -Wl,-L${STM32_LINKER_DIR} ) -if(${WIN32} OR ${CYGWIN}) +if(${CYGWIN}) set(SITL_LINK_OPTIONS ${SITL_LINK_OPTIONS} "-static-libgcc") endif() @@ -53,6 +53,11 @@ set(SITL_COMPILE_OPTIONS -funsigned-char ) +if(DEBUG) + message(STATUS "Debug mode enabled. Adding -g to SITL_COMPILE_OPTIONS.") + list(APPEND SITL_COMPILE_OPTIONS -g) +endif() + if(NOT MACOSX) set(SITL_COMPILE_OPTIONS ${SITL_COMPILE_OPTIONS} -Wno-return-local-addr @@ -126,7 +131,7 @@ function (target_sitl name) target_link_options(${exe_target} PRIVATE -T${script_path}) endif() - if(${WIN32} OR ${CYGWIN}) + if(${CYGWIN}) set(exe_filename ${CMAKE_BINARY_DIR}/${binary_name}.exe) else() set(exe_filename ${CMAKE_BINARY_DIR}/${binary_name}) diff --git a/docs/Controls.md b/docs/Controls.md index 1b63f90e2a3..3cc62b4e740 100644 --- a/docs/Controls.md +++ b/docs/Controls.md @@ -44,9 +44,9 @@ The stick positions are combined to activate different functions: | Bypass Nav Arm disable | LOW | HIGH | CENTER | CENTER | | Save setting | LOW | LOW | LOW | HIGH | | Enter OSD Menu (CMS) | CENTER | LOW | HIGH | CENTER | -| Enter Camera OSD(RuncamDevice)| RIGHT | CENTER | CENTER | CENTER | -| Exit Camera OSD (RuncamDevice)| LEFT | CENTER | CENTER | CENTER | -| Confirm - Camera OSD | RIGHT | CENTER | CENTER | CENTER | +| Enter Camera OSD(RuncamDevice)| CENTER | HIGH | CENTER | CENTER | +| Exit Camera OSD (RuncamDevice)| CENTER | LOW | CENTER | CENTER | +| Confirm - Camera OSD | CENTER | HIGH | CENTER | CENTER | | Navigation - Camera OSD | CENTER | CENTER | * | * | For graphical stick position in all transmitter modes, check out [this page](https://www.mrd-rc.com/tutorials-tools-and-testing/inav-flight/inav-stick-commands-for-all-transmitter-modes/). diff --git a/docs/Fixed Wing Landing.md b/docs/Fixed Wing Landing.md new file mode 100644 index 00000000000..10eff364f34 --- /dev/null +++ b/docs/Fixed Wing Landing.md @@ -0,0 +1,102 @@ +# Fixed Wing Landing + +## Introducion + +INAV supports advanced automatic landings for fixed wing aircraft from version 7.1. +The procedure is based on landings for man-carrying aircraft, so that safe landings at a specific location are possible. +Supported are landings at safehome after "Return to Home" or at a defined LAND waypoint for missions. +Every landing locations can be defined with a target point and 2 different approach headings (colinear to the landing strips) with exclusive direction or opposite directions allowed. +This enables up to 4 different approach directions, based on the landing site and surrounding area. + +## General procedure: + +1. After reaching Safehome/LAND Waypoint the altitude is corrected to "Approach Altitude". +2. The aircraft circles for at least 30 seconds to determine the wind direction and strength. +3. The landing direction and the approach waypoints are calculated on the basis of the measured wind parameters. If no headwind landing is possible or the wind strength is greater than "Max. tailwind" (see Global Parameters), return to point 2. +4. The landing is initiated. The aircraft flies the downwind course, "Approach Altitude" is held. +5. Base Leg: the altitude is reduced from 2/3 of "Approach Altitude". +6. Final Appraoch: The engine power is reduced using "Pitch2throttle modifier" to reduce speed and the altitude is reduced to "Land Altitude". +7. Glide: When "Glide Altitude" is reached, the motor is switched off and the pitch angle of "Glide Pitch" is held. +7. Flare: Only if a LIDAR/Rangefinder sensor is present: the motor remains switched off and the pitch angle of "Flare Pitch" is held +8. Landing: As soon as INAV has detected the landing, it is automatically disarmed, see setting `nav_disarm_on_landing`. + +To activate the automatic landing, the parameter `nav_rth_allow_landing` must be set to `ALWAYS` or `FAILSAFE`. + +> [!WARNING] +> If landing is activated and no parameters are set for the landing site (Safehome and/or landing waypoint), the old landing procedure (circling until close to the ground, then hovering out) is performed. +> This is probably not what you want. + +The following graphics illustrate the process: + +![Approach Drawing Up](/docs/assets/images/Approach-Drawing-Up.png "Approach Drawing Up") + +![Approach Drawing Side](/docs/assets/images/Approach-Drawing-Side.png "Approach Drawing Side") + +## Landing site parameters + +### The following parameters are set for each landing site (Safefome/LAND waypoint): + +All settings can also be conveniently made in the Configurator via Mission Control. + +CLI command `fwapproach`: +`fwapproach ` + +`fwapproach` has 17 slots in which landing parameters can be stored. In slot 0-7 the landing parameters for Safehome are stored, in 8 - 16 the parameters for waypoint missions. Only one landing point per mission can be saved. + +* index: 0 - 17, 0 - 7 Safehome, 8 - 16 Mission +* Approach direction: 0 - Left, 1 - Right. Always seen from the primary landing direction (positive value), i.e. whether the aircraft flies left or right turns on approach. +* Approach Altitude: Initial altitude of the approach, the altitude at which the wind direction is determined and the downwind approach, in cm +* Land Altitude: Altitude of the landing site, in cm +* Approach heading 1 and 2: Two landing directions can be set, values: 0 - +/-360. 0 = landing direction is deactivated. +A positive value means that you can approach in both directions, a negative value means that this direction is exclusive. +Example: 90 degrees: It is possible to land in 90 degrees as well as in 270 degrees. -90 means that you can only land in a 90 degree direction. +This means that practically 4 landing directions can be saved. +* Sea Level: 0 - Deactivated, 1 - Activated. If activated, approach and land altitude refer to normal zero (sea level), otherwise relative altitude to the altitude during first GPS fix. + +> [!CAUTION] +> The Configuator automatically determines the ground altitude based on databases on the Internet, which may be inaccurate. Please always compare with the measured GPS altitude at the landing site to avoid crashes. + +### Global parameters + +All settings are available via “Advanced Tuning” in the Configurator. + +* `nav_fw_land_approach_length`: Length of the final approach, measured from the land site (Safehome/Waypoint) to the last turning point. +In cm. Max: 100000, Min: 100, Default: 35000 + +* `nav_fw_land_final_approach_pitch2throttle_mod`: Modifier for pitch to throttle ratio at final approach. This parameter can be used to reduce speed during the final approach. +Example: If the parameter is set to 200% and Pitch To Throttle Ratio is set to 15, Pitch To Throttle Ratio is set to 30 on the final approach. This causes a reduction in engine power on approach when the nose is pointing downwards. +In Percent. Min: 100, Max: 400, Default: 100 + +* `nav_fw_land_glide_alt`: Initial altitude of the glide phase. The altitude refers to "Landing Altitude", see above under "Landing site parameters" +In cm. Min: 100, Max: 5000, Default: 200 + +* `nav_fw_land_flare_alt`: Initial altitude of the flare phase. The altitude refers to "Landing Altitude", see above under "Landing site parameters" +In cm. Min: 0, Max: 5000, Default: 200 + +* `nav_fw_land_glide_pitch`: Pitch value for glide phase. +In degrees. Min: 0, Max: 45, Default: 0 + +* `nav_fw_land_flare_pitch`: Pitch value for flare phase. + In degrees. Min: 0, Max: 45, Default: 8 + +* `nav_fw_land_max_tailwind`: Max. tailwind if no landing direction with downwind is available. Wind strengths below this value are ignored (error tolerance in the wind measurement). Landing then takes place in the main direction. If, for example, 90 degrees is configured, landing takes place in this direction, NOT in 270 degrees (see above). +In cm/s. Min: 0; Max: 3000, Default: 140 + +## Waypoint missions + +Only one landing waypoint per mission can be active and saved and the landing waypoint must be the last waypoint of the mission. +If the altitude of the waypoint and the "Approach Altitude" are different, the altitude of the waypoint is approached first and then the altitude is corrected to "Approach Altitude". + +## Logic Conditions + +The current landing state can be retrieved via ID 41 in "Flight" (FW Land State). This allows additional actions to be executed according to the landing phases, e.g. deployment of the landing flaps. + +| Returned value | State | +| --- | --- | +| 0 | Idle/Inactive | +| 1 | Loiter | +| 2 | Downwind | +| 3 | Base Leg | +| 4 | Final Approach | +| 5 | Glide | +| 6 | Flare | diff --git a/docs/LED pin PWM.md b/docs/LED pin PWM.md new file mode 100644 index 00000000000..2aead4cd7a0 --- /dev/null +++ b/docs/LED pin PWM.md @@ -0,0 +1,90 @@ +# LED pin PWM + +Normally LED pin is used to drive WS2812 led strip. LED pin is held low, and every 10ms or 20ms a set of pulses is sent to change color of the 32 LEDs: + +![alt text](/docs/assets/images/ws2811_packets.png "ws2811 packets") +![alt text](/docs/assets/images/ws2811_data.png "ws2811 data") + +As alternative function, it is possible to generate PWM signal with specified duty ratio on the LED pin. + +Feature can be used to drive external devices. It is also used to simulate [OSD joystick](OSD%20Joystick.md) to control cameras. + +PWM frequency is fixed to 24kHz with duty ratio between 0 and 100%: + +![alt text](/docs/assets/images/led_pin_pwm.png "led pin pwm") + +There are four modes of operation: +- low +- high +- shared_low +- shared_high + +Mode is configured using ```led_pin_pwm_mode``` setting: ```LOW```, ```HIGH```, ```SHARED_LOW```, ```SHARED_HIGH``` + +*Note that in any mode, there will be ~2 seconds LOW pulse on boot.* + +## LOW +LED Pin is initialized to output low level by default and can be used to generate PWM signal. + +ws2812 strip can not be controlled. + +## HIGH +LED Pin is initialized to output high level by default and can be used to generate PWM signal. + +ws2812 strip can not be controlled. + +## SHARED_LOW (default) +LED Pin is used to drive WS2812 strip. Pauses between pulses are low: + +![alt text](/docs/assets/images/ws2811_packets.png "ws2811 packets") + +It is possible to generate PWM signal with duty ratio >0...100%. + +While PWM signal is generated, ws2811 strip is not updated. + +When PWM generation is disabled, LED pin is used to drive ws2812 strip. + +Total ws2812 pulses duration is ~1ms with ~9ms pauses. Thus connected device should ignore PWM signal with duty ratio < ~10%. + +## SHARED_HIGH +LED Pin is used to drive WS2812 strip. Pauses between pulses are high. ws2812 pulses are prefixed with 50us low 'reset' pulse: + +![alt text](/docs/assets/images/ws2811_packets_high.png "ws2811 packets_high") +![alt text](/docs/assets/images/ws2811_data_high.png "ws2811 data_high") + + It is possible to generate PWM signal with duty ratio 0...<100%. + + While PWM signal is generated, ws2811 strip is not updated. + + When PWM generation is disabled, LED pin is used to drive ws2812 strip. Total ws2812 pulses duration is ~1ms with ~9ms pauses. Thus connected device should ignore PWM signal with duty ratio > ~90%. + + After sending ws2812 protocol pulses for 32 LEDS, we held line high for 9ms, then send 50us low 'reset' pulse. Datasheet for ws2812 protocol does not describe behavior for long high pulse, but in practice it works the same as 'reset' pulse. To be safe, we also send correct low 'reset' pulse before starting next LEDs update sequence. + + This mode is used to simulate OSD joystick. It is Ok that effectively voltage level is held >90% while driving LEDs, because OSD joystick keypress voltages are below 90%. + + See [OSD Joystick](OSD%20Joystick.md) for more information. + +# Generating PWM signal with programming framework + +See "LED Pin PWM" operation in [Programming Framework](Programming%20Framework.md) + + +# Generating PWM signal from CLI + +```ledpinpwm ``` - value = 0...100 - enable PWM generation with specified duty cycle + +```ledpinpwm``` - disable PWM generation ( disable to allow ws2812 LEDs updates in shared modes ) + + +# Example of driving LED + +It is possible to drive single color LED with brightness control. Current consumption should not be greater then 1-2ma, thus LED can be used for indication only. + +![alt text](/docs/assets/images/ledpinpwmled.png "led pin pwm led") + +# Example of driving powerfull white LED + +To drive power LED with brightness control, Mosfet should be used: + +![alt text](/docs/assets/images/ledpinpwmpowerled.png "led pin pwm power_led") + diff --git a/docs/LedStrip.md b/docs/LedStrip.md index d19660530a2..cecd630ecc9 100644 --- a/docs/LedStrip.md +++ b/docs/LedStrip.md @@ -7,7 +7,7 @@ require that all the LEDs in the strip show the same color. Addressable LED strips can be used to show information from the flight controller system, the current implementation supports the following: -* Up to 32 LEDs. +* Up to 128 LEDs. _If using more than 20 LEDs, you should look to use a separate power supply._ * Indicators showing pitch/roll stick positions. * Heading/Orientation lights. * Flight mode specific color schemes. @@ -17,12 +17,12 @@ supports the following: * RSSI level. * Battery level. -Support for more than 32 LEDs is possible, it just requires additional development. +Support for more than 128 LEDs is possible, it just requires additional development. ## Supported hardware -Only strips of 32 WS2811/WS2812 LEDs are supported currently. If the strip is longer than 32 LEDs it does not matter, -but only the first 32 are used. +Only strips of 128 WS2811/WS2812 LEDs are supported currently. If the strip is longer than 128 LEDs it does not matter, +but only the first 128 are used. WS2812 LEDs require an 800khz signal and precise timings and thus requires the use of a dedicated hardware timer. @@ -42,11 +42,11 @@ It could be possible to be able to specify the timings required via CLI if users WS2812 LED strips generally require a single data line, 5V and GND. -WS2812 LEDs on full brightness can consume quite a bit of current. It is recommended to verify the current draw and ensure your -supply can cope with the load. On a multirotor that uses multiple BEC ESC's you can try use a different BEC to the one the FC -uses. e.g. ESC1/BEC1 -> FC, ESC2/BEC2 -> LED strip. It's also possible to power one half of the strip from one BEC and the other half -from another BEC. Just ensure that the GROUND is the same for all BEC outputs and LEDs. +WS2812 LEDs on full brightness can consume quite a bit of current. **It is recommended to verify the current draw of you LEDs and ensure your supply can cope with the load. Remember, your flight controller will likely be using the same BEC to operate.** Check the specs of the LED chips. Some are more power hungry than others. Remember that if using the flight controller's 5v supply. This is also powering other components on your flight controller. Make sure there is enough overhead so that they don't brownout. +On a multirotor that uses multiple BEC ESC's you can try use a different BEC to the one the FC uses. e.g. ESC1/BEC1 -> FC, ESC2/BEC2 -> LED strip. It's also possible to power one half of the strip from one BEC and the other half from another BEC. Just ensure that the GROUND is the same for all BEC outputs and LEDs. + +If using a large number of LEDs. It would be more efficient to use 12v LEDs and power them with a separate regulated supply. Especially if using long strips. You would use the data line (LED pad) from the flight controller. Make sure there is continuity between the ground on the LEDS and the ground on the flight controller. | Target | Pin | LED Strip | Signal | | --------------------- | ---- | --------- | -------| @@ -605,4 +605,4 @@ This also means that you can make sure that each R,G and B LED in each LED modul After a short delay the LEDs will show the unarmed color sequence and or low-battery warning sequence. -Also check that the feature `LED_STRIP` was correctly enabled and that it does not conflict with other features, as above. +Also check that the feature `LED_STRIP` was correctly enabled and that it does not conflict with other features, as above. \ No newline at end of file diff --git a/docs/MixerProfile.md b/docs/MixerProfile.md index f6688feaeec..55aedd3a30b 100644 --- a/docs/MixerProfile.md +++ b/docs/MixerProfile.md @@ -1,80 +1,30 @@ # MixerProfile -A MixerProfile is a set of motor mixer, servo-mixer and platform type configuration settings to enable VTOL transitions. +A MixerProfile is a set of motor mixer, servo-mixer and platform type configuration settings. It is designed for experienced inav users. -Currently two profiles are supported on targets other than F411 and F722 (due to resource constraints on these FC). i.e VTOL transition is not available on F411 and F722 targets. +### For a tutorial of vtol setup, Read https://github.com/iNavFlight/inav/blob/master/docs/VTOL.md -By default, switching between profiles requires reboot to take affect. However, when all conditions are met, and a suitable [configuration](#configuration) has been applied, `mixer_profile` also allows in-flight profile [switching](#rc-mode-settings) to allow things like VTOL operation. This is the recommended operating mode. +Not limited to VTOL. air/land/sea mixed vehicle is also achievable with this feature. Model behaves according to current mixer_profile's platform_type and configured custom motor/servo mixer -Please note that this is an emerging / experimental capability that will require some effort by the pilot to implement. - -## Setup for VTOL -- A VTOL specific FC target or `timer_output_mode` overrides was required in the early stage of the development, But since unified mapping introduced in INAV 7.0 It is not needed anymore. -- ~~For mixer profile switching it is necessary to keep motor and servo PWM mapping consistent between Fixed-Wing (FW) and Multi-rotor (MR) profiles~~ -- ~~Traditionally, FW and MR have had different enumerations to define the PWM mappings. For VTOL operation it is necessary to set the `timer_output_mode` overrides to allow a consistent enumeration and thus mapping between MR and FW modes.~~ -- ~~In operation, it is necessary to set the `mixer_profile` and the `pid_profile` separately and to set a [RC mode](#rc-mode-settings) to switch between them.~~ -## Configuration -### Timer overrides -Set the timer overrides for the outputs that you are intended to use. -For SITL builds, is not necessary to set timer overrides. -Please note that there are some display issues on the configurator that will show wrong mapping on the mixer_profile which has less motor/servo compared with the another -### Profile Switch - -Setup the FW mode and MR mode separately in two different mixer profiles: - -In this example, FW mode is `mixer_profile` 1 and MR mode is `mixer_profile` 2. - -Currently, the INAV Configurator does not fully support `mixer_profile`, so some of the settings have to be done in CLI. - -Add `set mixer_pid_profile_linking = ON` in order to enable `pid_profile` auto handling. It will change the `pid profile` index according to the `mixer_profile` index on FC boot and allow `mixer_profile` hot switching (this is recommended usage). - -The following 2 `mixer_profile` sections are added in the CLI: - -``` -#switch to mixer_profile by cli -mixer_profile 1 - -set platform_type = AIRPLANE -set model_preview_type = 26 -# motor stop feature have been moved to here -set motorstop_on_low = ON -# enable pid_profile auto handling (recommended). -set mixer_pid_profile_linking = ON -save -``` -Then finish the aeroplane setting on mixer_profile 1 - -``` -mixer_profile 2 - -set platform_type = TRICOPTER -set model_preview_type = 1 -# also enable pid_profile auto handling -set mixer_pid_profile_linking = ON -save -``` -Then finish the multi-rotor setting on `mixer_profile` 2. +Currently two profiles are supported on targets other than F411(due to resource constraints on F411). i.e VTOL transition is not available on F411. -Note that default profile is profile `1`. +For VTOL setup. one mixer_profile is used for multi-rotor(MR) and the other is used for fixed-wing(FW) +By default, switching between profiles requires reboot to take affect. However, using the RC mode: `MIXER PROFILE 2` will allow in flight switching for things like VTOL operation +. And will re-initialize pid and navigation controllers for current MC or FW flying mode. -You can use `MAX` servo input to set a fixed input for the tilting servo. Speed setting for `MAX` input is available in the CLI. - -It is recommended to have some amount of control surface (elevon / elevator) mapped for stabilization even in MR mode to get improved authority when airspeed is high. - -**Double check all settings in CLI with the `diff all` command**; make sure you have set the correct settings. Also check what will change with `mixer_profile`. For example servo output min / max range will not change. But `smix` and `mmix` will change. +Please note that this is an emerging / experimental capability that will require some effort by the pilot to implement. -### Mixer Transition input +## Mixer Transition input Typically, 'transition input' will be useful in MR mode to gain airspeed. -Both the servo mixer and motor mixer can accept transition mode as an input. The associated motor or servo will then move accordingly when transition mode is activated. Transition input is disabled when navigation mode is activate The use of Transition Mode is recommended to enable further features and future developments like fail-safe support. Mapping motor to servo output, or servo with logic conditions is **not** recommended -#### Servo +## Servo -38 is the input source for transition input; use this to tilt motor to gain airspeed. +`Mixer Transition` is the input source for transition input; use this to tilt motor to gain airspeed. Example: Increase servo 1 output by +45 with speed of 150 when transition mode is activated for tilted motor setup: @@ -82,15 +32,14 @@ Example: Increase servo 1 output by +45 with speed of 150 when transition mode i # rule no; servo index; input source; rate; speed; activate logic function number smix 6 1 38 45 150 -1 ``` -Please note there will be a time window that tilting motors is providing up lift but rear motor isn't. Result in a sudden pitch raise on the entering of the mode. More forward tilting servo position on transition input(you can use 'speed' in servo rules to slowly move to this position), A faster tilting servo speed on `MAX` servo input will reduce the time window. OR lower the throttle on the entering of the FW mode to mitigate the effect. -#### Motor +## Motor -The default `mmix` throttle value is 0.0, It will not show in `diff` command when throttle value is 0.0 (unused); this causes the motor to stop. +The default `mmix` throttle value is 0.0, It will not show in `diff` command when throttle value is 0.0 (unused); - 0.0```, value = 0...100 to find out PWM values for each voltage. +5. Specify PWM values in configuration and save: + +```set osd_joystick_down=0``` + +```set osd_joystick_up=48``` + +```set osd_joystick_left=63``` + +```set osd_joystick_right=28``` + +```set osd_joystick_enter=75``` + +```save``` + +# Entering OSD Joystick emulation mode + +Emulation can be enabled in unarmed state only. + +OSD Joystick emulation mode is enabled using the following stick combination: + +```Throttle:CENTER Yaw:RIGHT``` + + +Than camera OSD can be navigated using right stick. See [Controls](Controls.md) for all stick combinations. + +*Note that the same stick combination is used to enable 5keys joystick emulation with RuncamDevice protocol.* + +Mode is exited using stick combination: + +```Throttle:CENTER Yaw:LEFT``` + +# RC Box + +There are 3 RC Boxes which can be used in armed and unarmed state: +- Camera 1 - Enter +- Camera 2 - Up +- Camera 3 - Down + +Other keys can be emulated using Programming framework ( see [LED pin PWM](LED%20pin%20PWM.md) for more details ). + +# Behavior on boot + +There is ~2 seconds LOW pulse during boot sequence, which corresponds to DOWN key. Fortunately, cameras seem to ignore any key events few seconds after statup. diff --git a/docs/OSD.md b/docs/OSD.md index 64530f0e2c7..b3526d0d761 100644 --- a/docs/OSD.md +++ b/docs/OSD.md @@ -5,163 +5,190 @@ The On Screen Display, or OSD, is a feature that overlays flight data over the v ## Features and Limitations Not all OSDs are created equally. This table shows the differences between the different systems available. -| OSD System | Character grid | Character | Canvas | MSP DisplayPort | All elements supported | -|---------------|-------------------|-----------|-----------|-------------------|---------------------------| -| Analogue PAL | 30 x 16 | X | | | YES | -| Analogue NTSC | 30 x 13 | X | | | YES | -| PixelOSD | As PAL or NTSC | | X | | YES | -| DJI OSD | 30 x 16 | X | | | NO - BF Characters only | -| DJI WTFOS | 60 x 22 | X | | X | YES | -| HDZero | 50 x 18 | X | | X | YES | -| Avatar | 53 x 20 | X | | X | YES | -| DJI O3 | 53 x 20 (HD) | X | | X (partial) | NO - BF Characters only | +| OSD System | Character grid | Character | Canvas | MSP DisplayPort | All elements supported | +|---------------|----------------|-----------|--------|-----------------|-------------------------| +| Analogue PAL | 30 x 16 | X | | | YES | +| Analogue NTSC | 30 x 13 | X | | | YES | +| PixelOSD | As PAL or NTSC | | X | | YES | +| DJI OSD | 30 x 16 | X | | | NO - BF Characters only | +| DJI WTFOS | 60 x 22 | X | | X | YES | +| HDZero | 50 x 18 | X | | X | YES | +| Avatar | 53 x 20 | X | | X | YES | +| DJI O3 | 53 x 20 (HD) | X | | X (partial) | NO - BF Characters only | ## OSD Elements Here are the OSD Elements provided by INAV. -| ID | Element | Added | -|-------|-----------------------------------------------|-------| -| 0 | OSD_RSSI_VALUE | 1.0.0 | -| 1 | OSD_MAIN_BATT_VOLTAGE | 1.0.0 | -| 2 | OSD_CROSSHAIRS | 1.0.0 | -| 3 | OSD_ARTIFICIAL_HORIZON | 1.0.0 | -| 4 | OSD_HORIZON_SIDEBARS | 1.0.0 | -| 5 | OSD_ONTIME | 1.0.0 | -| 6 | OSD_FLYTIME | 1.0.0 | -| 7 | OSD_FLYMODE | 1.0.0 | -| 8 | OSD_CRAFT_NAME | 1.0.0 | -| 9 | OSD_THROTTLE_POS | 1.0.0 | -| 10 | OSD_VTX_CHANNEL | 1.0.0 | -| 11 | OSD_CURRENT_DRAW | 1.0.0 | -| 12 | OSD_MAH_DRAWN | 1.0.0 | -| 13 | OSD_GPS_SPEED | 1.0.0 | -| 14 | OSD_GPS_SATS | 1.0.0 | -| 15 | OSD_ALTITUDE | 1.0.0 | -| 16 | OSD_ROLL_PIDS | 1.6.0 | -| 17 | OSD_PITCH_PIDS | 1.6.0 | -| 18 | OSD_YAW_PIDS | 1.6.0 | -| 19 | OSD_POWER | 1.6.0 | -| 20 | OSD_GPS_LON | 1.6.0 | -| 21 | OSD_GPS_LAT | 1.6.0 | -| 22 | OSD_HOME_DIR | 1.6.0 | -| 23 | OSD_HOME_DIST | 1.6.0 | -| 24 | OSD_HEADING | 1.6.0 | -| 25 | OSD_VARIO | 1.6.0 | -| 26 | OSD_VARIO_NUM | 1.6.0 | -| 27 | OSD_AIR_SPEED | 1.7.3 | -| 28 | OSD_ONTIME_FLYTIME | 1.8.0 | -| 29 | OSD_RTC_TIME | 1.8.0 | -| 30 | OSD_MESSAGES | 1.8.0 | -| 31 | OSD_GPS_HDOP | 1.8.0 | -| 32 | OSD_MAIN_BATT_CELL_VOLTAGE | 1.8.0 | -| 33 | OSD_SCALED_THROTTLE_POS | 1.8.0 | -| 34 | OSD_HEADING_GRAPH | 1.8.0 | -| 35 | OSD_EFFICIENCY_MAH_PER_KM | 1.9.0 | -| 36 | OSD_WH_DRAWN | 1.9.0 | -| 37 | OSD_BATTERY_REMAINING_CAPACITY | 1.9.0 | -| 38 | OSD_BATTERY_REMAINING_PERCENT | 1.9.0 | -| 39 | OSD_EFFICIENCY_WH_PER_KM | 1.9.0 | -| 40 | OSD_TRIP_DIST | 1.9.1 | -| 41 | OSD_ATTITUDE_PITCH | 2.0.0 | -| 42 | OSD_ATTITUDE_ROLL | 2.0.0 | -| 43 | OSD_MAP_NORTH | 2.0.0 | -| 44 | OSD_MAP_TAKEOFF | 2.0.0 | -| 45 | OSD_RADAR | 2.0.0 | -| 46 | OSD_WIND_SPEED_HORIZONTAL | 2.0.0 | -| 47 | OSD_WIND_SPEED_VERTICAL | 2.0.0 | -| 48 | OSD_REMAINING_FLIGHT_TIME_BEFORE_RTH | 2.0.0 | -| 49 | OSD_REMAINING_DISTANCE_BEFORE_RTH | 2.0.0 | -| 50 | OSD_HOME_HEADING_ERROR | 2.0.0 | -| 51 | OSD_COURSE_HOLD_ERROR | 2.0.0 | -| 52 | OSD_COURSE_HOLD_ADJUSTMENT | 2.0.0 | -| 53 | OSD_SAG_COMPENSATED_MAIN_BATT_VOLTAGE | 2.0.0 | -| 54 | OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE | 2.0.0 | -| 55 | OSD_POWER_SUPPLY_IMPEDANCE | 2.0.0 | -| 56 | OSD_LEVEL_PIDS | 2.0.0 | -| 57 | OSD_POS_XY_PIDS | 2.0.0 | -| 58 | OSD_POS_Z_PIDS | 2.0.0 | -| 59 | OSD_VEL_XY_PIDS | 2.0.0 | -| 60 | OSD_VEL_Z_PIDS | 2.0.0 | -| 61 | OSD_HEADING_P | 2.0.0 | -| 62 | OSD_BOARD_ALIGN_ROLL | 2.0.0 | -| 63 | OSD_BOARD_ALIGN_PITCH | 2.0.0 | -| 64 | OSD_RC_EXPO | 2.0.0 | -| 65 | OSD_RC_YAW_EXPO | 2.0.0 | -| 66 | OSD_THROTTLE_EXPO | 2.0.0 | -| 67 | OSD_PITCH_RATE | 2.0.0 | -| 68 | OSD_ROLL_RATE | 2.0.0 | -| 69 | OSD_YAW_RATE | 2.0.0 | -| 70 | OSD_MANUAL_RC_EXPO | 2.0.0 | -| 71 | OSD_MANUAL_RC_YAW_EXPO | 2.0.0 | -| 72 | OSD_MANUAL_PITCH_RATE | 2.0.0 | -| 73 | OSD_MANUAL_ROLL_RATE | 2.0.0 | -| 74 | OSD_MANUAL_YAW_RATE | 2.0.0 | -| 75 | OSD_NAV_FW_CRUISE_THR | 2.0.0 | -| 76 | OSD_NAV_FW_PITCH2THR | 2.0.0 | -| 77 | OSD_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE | 2.0.0 | -| 78 | OSD_DEBUG | 2.0.0 | -| 79 | OSD_FW_ALT_PID_OUTPUTS | 2.0.0 | -| 80 | OSD_FW_POS_PID_OUTPUTS | 2.0.0 | -| 81 | OSD_MC_VEL_X_PID_OUTPUTS | 2.0.0 | -| 82 | OSD_MC_VEL_Y_PID_OUTPUTS | 2.0.0 | -| 83 | OSD_MC_VEL_Z_PID_OUTPUTS | 2.0.0 | -| 84 | OSD_MC_POS_XYZ_P_OUTPUTS | 2.0.0 | -| 85 | OSD_3D_SPEED | 2.1.0 | -| 86 | OSD_IMU_TEMPERATURE | 2.1.0 | -| 87 | OSD_BARO_TEMPERATURE | 2.1.0 | -| 88 | OSD_TEMP_SENSOR_0_TEMPERATURE | 2.1.0 | -| 89 | OSD_TEMP_SENSOR_1_TEMPERATURE | 2.1.0 | -| 90 | OSD_TEMP_SENSOR_2_TEMPERATURE | 2.1.0 | -| 91 | OSD_TEMP_SENSOR_3_TEMPERATURE | 2.1.0 | -| 92 | OSD_TEMP_SENSOR_4_TEMPERATURE | 2.1.0 | -| 93 | OSD_TEMP_SENSOR_5_TEMPERATURE | 2.1.0 | -| 94 | OSD_TEMP_SENSOR_6_TEMPERATURE | 2.1.0 | -| 95 | OSD_TEMP_SENSOR_7_TEMPERATURE | 2.1.0 | -| 96 | OSD_ALTITUDE_MSL | 2.1.0 | -| 97 | OSD_PLUS_CODE | 2.1.0 | -| 98 | OSD_MAP_SCALE | 2.2.0 | -| 99 | OSD_MAP_REFERENCE | 2.2.0 | -| 100 | OSD_GFORCE | 2.2.0 | -| 101 | OSD_GFORCE_X | 2.2.0 | -| 102 | OSD_GFORCE_Y | 2.2.0 | -| 103 | OSD_GFORCE_Z | 2.2.0 | -| 104 | OSD_RC_SOURCE | 2.2.0 | -| 105 | OSD_VTX_POWER | 2.2.0 | -| 106 | OSD_ESC_RPM | 2.3.0 | -| 107 | OSD_ESC_TEMPERATURE | 2.5.0 | -| 108 | OSD_AZIMUTH | 2.6.0 | -| 109 | OSD_CRSF_RSSI_DBM | 2.6.0 | -| 110 | OSD_CRSF_LQ | 2.6.0 | -| 111 | OSD_CRSF_SNR_DB | 2.6.0 | -| 112 | OSD_CRSF_TX_POWER | 2.6.0 | -| 113 | OSD_GVAR_0 | 2.6.0 | -| 114 | OSD_GVAR_1 | 2.6.0 | -| 115 | OSD_GVAR_2 | 2.6.0 | -| 116 | OSD_GVAR_3 | 2.6.0 | -| 117 | OSD_TPA | 2.6.0 | -| 118 | OSD_NAV_FW_CONTROL_SMOOTHNESS | 2.6.0 | -| 119 | OSD_VERSION | 3.0.0 | -| 120 | OSD_RANGEFINDER | 3.0.0 | -| 121 | OSD_PLIMIT_REMAINING_BURST_TIME | 3.0.0 | -| 122 | OSD_PLIMIT_ACTIVE_CURRENT_LIMIT | 3.0.0 | -| 123 | OSD_PLIMIT_ACTIVE_POWER_LIMIT | 3.0.0 | -| 124 | OSD_GLIDESLOPE | 3.0.1 | -| 125 | OSD_GPS_MAX_SPEED | 4.0.0 | -| 126 | OSD_3D_MAX_SPEED | 4.0.0 | -| 127 | OSD_AIR_MAX_SPEED | 4.0.0 | -| 128 | OSD_ACTIVE_PROFILE | 4.0.0 | -| 129 | OSD_MISSION | 4.0.0 | -| 130 | OSD_SWITCH_INDICATOR_0 | 5.0.0 | -| 131 | OSD_SWITCH_INDICATOR_1 | 5.0.0 | -| 132 | OSD_SWITCH_INDICATOR_2 | 5.0.0 | -| 133 | OSD_SWITCH_INDICATOR_3 | 5.0.0 | -| 134 | OSD_TPA_TIME_CONSTANT | 5.0.0 | -| 135 | OSD_FW_LEVEL_TRIM | 5.0.0 | -| 136 | OSD_GLIDE_TIME_REMAINING | 6.0.0 | -| 137 | OSD_GLIDE_RANGE | 6.0.0 | -| 138 | OSD_CLIMB_EFFICIENCY | 6.0.0 | -| 139 | OSD_NAV_WP_MULTI_MISSION_INDEX | 6.0.0 | -| 140 | OSD_GROUND_COURSE | 6.0.0 | -| 141 | OSD_CROSS_TRACK_ERROR | 6.0.0 | -| 142 | OSD_PILOT_NAME | 6.0.0 | -| 143 | OSD_PAN_SERVO_CENTRED | 6.0.0 | \ No newline at end of file +| ID | Element | Added | +|-----|--------------------------------------------------|--------| +| 0 | OSD_RSSI_VALUE | 1.0.0 | +| 1 | OSD_MAIN_BATT_VOLTAGE | 1.0.0 | +| 2 | OSD_CROSSHAIRS | 1.0.0 | +| 3 | OSD_ARTIFICIAL_HORIZON | 1.0.0 | +| 4 | OSD_HORIZON_SIDEBARS | 1.0.0 | +| 5 | OSD_ONTIME | 1.0.0 | +| 6 | OSD_FLYTIME | 1.0.0 | +| 7 | OSD_FLYMODE | 1.0.0 | +| 8 | OSD_CRAFT_NAME | 1.0.0 | +| 9 | OSD_THROTTLE_POS | 1.0.0 | +| 10 | OSD_VTX_CHANNEL | 1.0.0 | +| 11 | OSD_CURRENT_DRAW | 1.0.0 | +| 12 | OSD_MAH_DRAWN | 1.0.0 | +| 13 | OSD_GPS_SPEED | 1.0.0 | +| 14 | OSD_GPS_SATS | 1.0.0 | +| 15 | OSD_ALTITUDE | 1.0.0 | +| 16 | OSD_ROLL_PIDS | 1.6.0 | +| 17 | OSD_PITCH_PIDS | 1.6.0 | +| 18 | OSD_YAW_PIDS | 1.6.0 | +| 19 | OSD_POWER | 1.6.0 | +| 20 | OSD_GPS_LON | 1.6.0 | +| 21 | OSD_GPS_LAT | 1.6.0 | +| 22 | OSD_HOME_DIR | 1.6.0 | +| 23 | OSD_HOME_DIST | 1.6.0 | +| 24 | OSD_HEADING | 1.6.0 | +| 25 | OSD_VARIO | 1.6.0 | +| 26 | OSD_VARIO_NUM | 1.6.0 | +| 27 | OSD_AIR_SPEED | 1.7.3 | +| 28 | OSD_ONTIME_FLYTIME | 1.8.0 | +| 29 | OSD_RTC_TIME | 1.8.0 | +| 30 | OSD_MESSAGES | 1.8.0 | +| 31 | OSD_GPS_HDOP | 1.8.0 | +| 32 | OSD_MAIN_BATT_CELL_VOLTAGE | 1.8.0 | +| 33 | OSD_SCALED_THROTTLE_POS | 1.8.0 | +| 34 | OSD_HEADING_GRAPH | 1.8.0 | +| 35 | OSD_EFFICIENCY_MAH_PER_KM | 1.9.0 | +| 36 | OSD_WH_DRAWN | 1.9.0 | +| 37 | OSD_BATTERY_REMAINING_CAPACITY | 1.9.0 | +| 38 | OSD_BATTERY_REMAINING_PERCENT | 1.9.0 | +| 39 | OSD_EFFICIENCY_WH_PER_KM | 1.9.0 | +| 40 | OSD_TRIP_DIST | 1.9.1 | +| 41 | OSD_ATTITUDE_PITCH | 2.0.0 | +| 42 | OSD_ATTITUDE_ROLL | 2.0.0 | +| 43 | OSD_MAP_NORTH | 2.0.0 | +| 44 | OSD_MAP_TAKEOFF | 2.0.0 | +| 45 | OSD_RADAR | 2.0.0 | +| 46 | OSD_WIND_SPEED_HORIZONTAL | 2.0.0 | +| 47 | OSD_WIND_SPEED_VERTICAL | 2.0.0 | +| 48 | OSD_REMAINING_FLIGHT_TIME_BEFORE_RTH | 2.0.0 | +| 49 | OSD_REMAINING_DISTANCE_BEFORE_RTH | 2.0.0 | +| 50 | OSD_HOME_HEADING_ERROR | 2.0.0 | +| 51 | OSD_COURSE_HOLD_ERROR | 2.0.0 | +| 52 | OSD_COURSE_HOLD_ADJUSTMENT | 2.0.0 | +| 53 | OSD_SAG_COMPENSATED_MAIN_BATT_VOLTAGE | 2.0.0 | +| 54 | OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE | 2.0.0 | +| 55 | OSD_POWER_SUPPLY_IMPEDANCE | 2.0.0 | +| 56 | OSD_LEVEL_PIDS | 2.0.0 | +| 57 | OSD_POS_XY_PIDS | 2.0.0 | +| 58 | OSD_POS_Z_PIDS | 2.0.0 | +| 59 | OSD_VEL_XY_PIDS | 2.0.0 | +| 60 | OSD_VEL_Z_PIDS | 2.0.0 | +| 61 | OSD_HEADING_P | 2.0.0 | +| 62 | OSD_BOARD_ALIGN_ROLL | 2.0.0 | +| 63 | OSD_BOARD_ALIGN_PITCH | 2.0.0 | +| 64 | OSD_RC_EXPO | 2.0.0 | +| 65 | OSD_RC_YAW_EXPO | 2.0.0 | +| 66 | OSD_THROTTLE_EXPO | 2.0.0 | +| 67 | OSD_PITCH_RATE | 2.0.0 | +| 68 | OSD_ROLL_RATE | 2.0.0 | +| 69 | OSD_YAW_RATE | 2.0.0 | +| 70 | OSD_MANUAL_RC_EXPO | 2.0.0 | +| 71 | OSD_MANUAL_RC_YAW_EXPO | 2.0.0 | +| 72 | OSD_MANUAL_PITCH_RATE | 2.0.0 | +| 73 | OSD_MANUAL_ROLL_RATE | 2.0.0 | +| 74 | OSD_MANUAL_YAW_RATE | 2.0.0 | +| 75 | OSD_NAV_FW_CRUISE_THR | 2.0.0 | +| 76 | OSD_NAV_FW_PITCH2THR | 2.0.0 | +| 77 | OSD_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE | 2.0.0 | +| 78 | OSD_DEBUG | 2.0.0 | +| 79 | OSD_FW_ALT_PID_OUTPUTS | 2.0.0 | +| 80 | OSD_FW_POS_PID_OUTPUTS | 2.0.0 | +| 81 | OSD_MC_VEL_X_PID_OUTPUTS | 2.0.0 | +| 82 | OSD_MC_VEL_Y_PID_OUTPUTS | 2.0.0 | +| 83 | OSD_MC_VEL_Z_PID_OUTPUTS | 2.0.0 | +| 84 | OSD_MC_POS_XYZ_P_OUTPUTS | 2.0.0 | +| 85 | OSD_3D_SPEED | 2.1.0 | +| 86 | OSD_IMU_TEMPERATURE | 2.1.0 | +| 87 | OSD_BARO_TEMPERATURE | 2.1.0 | +| 88 | OSD_TEMP_SENSOR_0_TEMPERATURE | 2.1.0 | +| 89 | OSD_TEMP_SENSOR_1_TEMPERATURE | 2.1.0 | +| 90 | OSD_TEMP_SENSOR_2_TEMPERATURE | 2.1.0 | +| 91 | OSD_TEMP_SENSOR_3_TEMPERATURE | 2.1.0 | +| 92 | OSD_TEMP_SENSOR_4_TEMPERATURE | 2.1.0 | +| 93 | OSD_TEMP_SENSOR_5_TEMPERATURE | 2.1.0 | +| 94 | OSD_TEMP_SENSOR_6_TEMPERATURE | 2.1.0 | +| 95 | OSD_TEMP_SENSOR_7_TEMPERATURE | 2.1.0 | +| 96 | OSD_ALTITUDE_MSL | 2.1.0 | +| 97 | OSD_PLUS_CODE | 2.1.0 | +| 98 | OSD_MAP_SCALE | 2.2.0 | +| 99 | OSD_MAP_REFERENCE | 2.2.0 | +| 100 | OSD_GFORCE | 2.2.0 | +| 101 | OSD_GFORCE_X | 2.2.0 | +| 102 | OSD_GFORCE_Y | 2.2.0 | +| 103 | OSD_GFORCE_Z | 2.2.0 | +| 104 | OSD_RC_SOURCE | 2.2.0 | +| 105 | OSD_VTX_POWER | 2.2.0 | +| 106 | OSD_ESC_RPM | 2.3.0 | +| 107 | OSD_ESC_TEMPERATURE | 2.5.0 | +| 108 | OSD_AZIMUTH | 2.6.0 | +| 109 | OSD_CRSF_RSSI_DBM | 2.6.0 | +| 110 | OSD_CRSF_LQ | 2.6.0 | +| 111 | OSD_CRSF_SNR_DB | 2.6.0 | +| 112 | OSD_CRSF_TX_POWER | 2.6.0 | +| 113 | OSD_GVAR_0 | 2.6.0 | +| 114 | OSD_GVAR_1 | 2.6.0 | +| 115 | OSD_GVAR_2 | 2.6.0 | +| 116 | OSD_GVAR_3 | 2.6.0 | +| 117 | OSD_TPA | 2.6.0 | +| 118 | OSD_NAV_FW_CONTROL_SMOOTHNESS | 2.6.0 | +| 119 | OSD_VERSION | 3.0.0 | +| 120 | OSD_RANGEFINDER | 3.0.0 | +| 121 | OSD_PLIMIT_REMAINING_BURST_TIME | 3.0.0 | +| 122 | OSD_PLIMIT_ACTIVE_CURRENT_LIMIT | 3.0.0 | +| 123 | OSD_PLIMIT_ACTIVE_POWER_LIMIT | 3.0.0 | +| 124 | OSD_GLIDESLOPE | 3.0.1 | +| 125 | OSD_GPS_MAX_SPEED | 4.0.0 | +| 126 | OSD_3D_MAX_SPEED | 4.0.0 | +| 127 | OSD_AIR_MAX_SPEED | 4.0.0 | +| 128 | OSD_ACTIVE_PROFILE | 4.0.0 | +| 129 | OSD_MISSION | 4.0.0 | +| 130 | OSD_SWITCH_INDICATOR_0 | 5.0.0 | +| 131 | OSD_SWITCH_INDICATOR_1 | 5.0.0 | +| 132 | OSD_SWITCH_INDICATOR_2 | 5.0.0 | +| 133 | OSD_SWITCH_INDICATOR_3 | 5.0.0 | +| 134 | OSD_TPA_TIME_CONSTANT | 5.0.0 | +| 135 | OSD_FW_LEVEL_TRIM | 5.0.0 | +| 136 | OSD_GLIDE_TIME_REMAINING | 6.0.0 | +| 137 | OSD_GLIDE_RANGE | 6.0.0 | +| 138 | OSD_CLIMB_EFFICIENCY | 6.0.0 | +| 139 | OSD_NAV_WP_MULTI_MISSION_INDEX | 6.0.0 | +| 140 | OSD_GROUND_COURSE | 6.0.0 | +| 141 | OSD_CROSS_TRACK_ERROR | 6.0.0 | +| 142 | OSD_PILOT_NAME | 6.0.0 | +| 143 | OSD_PAN_SERVO_CENTRED | 6.0.0 | +| 144 | OSD_MULTI_FUNCTION | 7.0.0 | +| 145 | OSD_ODOMETER | 7.0.0 | +| 146 | OSD_PILOT_LOGO | 7.0.0 | + +# Pilot Logos + +From INAV 7.0.0, pilots can add their own logos to the OSD. These can appear in 2 places: the power on/arming screens or as an element on the standard OSD. Please note that the power on/arming screen large pilot logos are only available on HD systems. + +To use the pilot logos, you will need to make a custom font for your OSD system. Base fonts and information can be found in the [OSD folder](https://github.com/iNavFlight/inav-configurator/tree/master/resources/osd) in the Configurator resources. Each system will need a specific method to create the font image files. So they will not be covered here. There are two pilot logos. + +Default small INAV Pilot logoThe small pilot logo appears on standard OSD layouts, when you add the elemement to the OSD screen. This is a 3 character wide symbol (characters 469-471). + +Default large INAV Pilot logoThe large pilot logo appears on the power on and arming screens, when you enable the feature in the CLI. To do this, set the `osd_use_pilot_logo` parameter to `on`. This is a 10 character wide, 4 character high symbol (characters 472-511). + +## Settings + +* `osd_arm_screen_display_time` The amount of time the arming screen is displayed. +* `osd_inav_to_pilot_logo_spacing` The spacing between two logos. This can be set to `0`, so the original INAV logo and Pilot Logo can be combined in to a larger logo. Any non-0 value will be adjusted to best align the logos. For example, the Avatar system has an odd number of columns. If you set the spacing to 8, the logos would look misaligned. So the even number will be changed to an odd number for better alignment. +* `osd_use_pilot_logo` Enable to use the large pilot logo. + +## Examples + +This is an example of the arming screen with the pilot logo enabled. This is using the default settings. +![Arming screen example using default settings with osd_use_pilot_logo set to on](https://user-images.githubusercontent.com/17590174/271817487-eb18da4d-0911-44b2-b670-ea5940f79176.png) + +This is an example of setting the `osd_inav_to_pilot_logo_spacing` to 0. This will allow a larger, single logo. +![Power on screen example with 0 spacing between logos](https://user-images.githubusercontent.com/17590174/271817352-6206402c-9da4-4682-9d83-790cc2396b00.png) diff --git a/docs/Programming Framework.md b/docs/Programming Framework.md index 42a4f2a83f6..9f95fdb25d5 100644 --- a/docs/Programming Framework.md +++ b/docs/Programming Framework.md @@ -83,7 +83,7 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 35 | Trigonometry: Tangent | Computes TAN of `Operand A` value in degrees. Output is multiplied by `Operand B` value. If `Operand B` is `0`, result is multiplied by `500` | | 36 | MAP_INPUT | Scales `Operand A` from [`0` : `Operand B`] to [`0` : `1000`]. Note: input will be constrained and then scaled | | 37 | MAP_OUTPUT | Scales `Operand A` from [`0` : `1000`] to [`0` : `Operand B`]. Note: input will be constrained and then scaled | -| 38 | RC_CHANNEL_OVERRIDE | Overrides channel set by `Operand A` to value of `Operand B` | +| 38 | RC_CHANNEL_OVERRIDE | Overrides channel set by `Operand A` to value of `Operand B`. Note operand A should normally be set as a "Value", NOT as "Get RC Channel"| | 39 | SET_HEADING_TARGET | Sets heading-hold target to `Operand A`, in degrees. Value wraps-around. | | 40 | Modulo | Modulo. Divide `Operand A` by `Operand B` and returns the remainder | | 41 | LOITER_RADIUS_OVERRIDE | Sets the loiter radius to `Operand A` [`0` : `100000`] in cm. If the value is lower than the loiter radius set in the **Advanced Tuning**, that will be used. | @@ -97,6 +97,7 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 49 | TIMER | A simple on - off timer. `true` for the duration of `Operand A` [ms]. Then `false` for the duration of `Operand B` [ms]. | | 50 | DELTA | This returns `true` when the value of `Operand A` has changed by the value of `Operand B` or greater within 100ms. | | 51 | APPROX_EQUAL | `true` if `Operand B` is within 1% of `Operand A`. | +| 52 | LED_PIN_PWM | Value `Operand A` from [`0` : `100`] starts PWM generation on LED Pin. See [LED pin PWM](LED%20pin%20PWM.md). Any other value stops PWM generation (stop to allow ws2812 LEDs updates in shared modes)| ### Operands @@ -152,6 +153,10 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 35 | AGL_STATUS | boolean `1` when AGL can be trusted, `0` when AGL estimate can not be trusted | | 36 | AGL | integer Above The Groud Altitude in `cm` | | 37 | RANGEFINDER_RAW | integer raw distance provided by the rangefinder in `cm` | +| 38 | ACTIVE_MIXER_PROFILE | Which mixers are currently active (for vtol etc) | +| 39 | MIXER_TRANSITION_ACTIVE | Currently switching between mixers (quad to plane etc) | +| 40 | ATTITUDE_YAW | current heading (yaw) in `degrees` | +| 41 | FW Land Sate | integer `1` - `5`, indicates the status of the FW landing, 0 Idle, 1 Downwind, 2 Base Leg, 3 Final Approach, 4 Glide, 5 Flare | #### FLIGHT_MODE diff --git a/docs/Runcam device.md b/docs/Runcam device.md new file mode 100644 index 00000000000..b8c6ef80fd1 --- /dev/null +++ b/docs/Runcam device.md @@ -0,0 +1,32 @@ +# Runcam device + +Cameras which support [Runcam device protocol](https://support.runcam.com/hc/en-us/articles/360014537794-RunCam-Device-Protocol), can be configured using sticks. + +Note that for cameras which has OSD pin, there is alternative functionality: [OSD Joystick](OSD%20Joystick.md). + +Camera's RX/TX should be connected to FC's UART, which has "Runcam device" option selected. + +# Entering Joystick emulation mode + +Emulation can be enabled in unarmed state only. + +Joystick emulation mode is enabled using the following stick combination: + +```RIGHT CENTER``` + + +Than camera OSD can be navigated using right stick. See [Controls](Controls.md) for all stick combinations. + +*Note that the same stick combination is used to enable [OSD Joystick](OSD%20Joystick.md).* + +Mode is exited using stick combination: + +```LEFT CENTER``` + +# RC Box + +There are 3 RC Boxes which can be used in armed and unarmed state: +- Camera 1 - Simulate Wifi button +- Camera 2 - Simulate POWER button +- Camera 3 - Simulate Change Mode button. + diff --git a/docs/SITL/RealFlight.md b/docs/SITL/RealFlight.md index a30963af025..6124b1e7b57 100644 --- a/docs/SITL/RealFlight.md +++ b/docs/SITL/RealFlight.md @@ -3,8 +3,15 @@ Supported are RealFlight 9.5S and RealFlight Evolution, NOT RealFlight-X. RealFlight is very well suited to simulate the model flight specific aspects. Autolaunch and the mixers can be used. -However, since the sceneries do not correspond to a real environment, the GPS data must be "faked". The position is always shown somewhere in southern Nevada ;). -GPS data and flight modes work fine though, only for missions with waypoints it is of course not ideal. + +The RealFlight 3D sceneries are based on real topographic data of the Sierra Nevada in Southern Spain. +INAV uses as reference the scenery "RealFlight Ranch" which is located at the coordinates Lat: 37.118949°, Lon: -2.772960. +Use these scenery to use the mission planner and other GPS features. + +> [!CAUTION]: +> The immediate surroundings of the airfield have been levelled in the scenery. If, for example, Autoland is to be tested here, do not use "Sea level ref" and the automatically determined heights of the Configurator. +> Either use relarive elevations or correct the elevation manually. +> The altitude of the airfield is exactly 1300 metres. ## Joystick In the settings, calibrate the joystick, set it up and assign the axes in the same order as in INAV. diff --git a/docs/Screenshots/mixerprofile_4puls1_mix.png b/docs/Screenshots/mixerprofile_4puls1_mix.png new file mode 100644 index 00000000000..9fdae07077a Binary files /dev/null and b/docs/Screenshots/mixerprofile_4puls1_mix.png differ diff --git a/docs/Screenshots/mixerprofile_flow.png b/docs/Screenshots/mixerprofile_flow.png new file mode 100644 index 00000000000..292949b23b7 Binary files /dev/null and b/docs/Screenshots/mixerprofile_flow.png differ diff --git a/docs/Screenshots/mixerprofile_fw_mixer.png b/docs/Screenshots/mixerprofile_fw_mixer.png new file mode 100644 index 00000000000..b27b1b4b78a Binary files /dev/null and b/docs/Screenshots/mixerprofile_fw_mixer.png differ diff --git a/docs/Screenshots/mixerprofile_mc_mixer.png b/docs/Screenshots/mixerprofile_mc_mixer.png new file mode 100644 index 00000000000..fe1766665ae Binary files /dev/null and b/docs/Screenshots/mixerprofile_mc_mixer.png differ diff --git a/docs/Screenshots/mixerprofile_servo_transition_mix.png b/docs/Screenshots/mixerprofile_servo_transition_mix.png new file mode 100644 index 00000000000..31e40ff5480 Binary files /dev/null and b/docs/Screenshots/mixerprofile_servo_transition_mix.png differ diff --git a/docs/Servo.md b/docs/Servo.md index 42acfaa3c9b..d3322b02f02 100644 --- a/docs/Servo.md +++ b/docs/Servo.md @@ -1,6 +1,6 @@ # Servo configuration -Servos can be configured from the graphical user interface's `Servos` tab. +Servos can be configured from the graphical user interface's `Outputs` tab. * MID: middle/neutral point of the servo * MIN: the minimum value that can be sent to the servo is MIN * Rate diff --git a/docs/Settings.md b/docs/Settings.md index c919327194b..9817422595e 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -242,6 +242,16 @@ Inertial Measurement Unit KP Gain for compass measurements --- +### ahrs_gps_yaw_weight + +Arhs gps yaw weight when mag is avaliable, 0 means no gps yaw, 100 means equal weight as compass + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 500 | + +--- + ### ahrs_gps_yaw_windcomp Wind compensation in heading estimation from gps groundcourse(fixed wing only) @@ -258,7 +268,7 @@ Inertia force compensation method when gps is avaliable, VELNED use the acclerat | Default | Min | Max | | --- | --- | --- | -| VELNED | | | +| ADAPTIVE | | | --- @@ -872,6 +882,96 @@ Enable when BLHeli32 Auto Telemetry function is used. Disable in every other cas --- +### ez_aggressiveness + +EzTune aggressiveness + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + +### ez_axis_ratio + +EzTune axis ratio + +| Default | Min | Max | +| --- | --- | --- | +| 110 | 25 | 175 | + +--- + +### ez_damping + +EzTune damping + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + +### ez_enabled + +Enables EzTune feature + +| Default | Min | Max | +| --- | --- | --- | +| OFF | OFF | ON | + +--- + +### ez_expo + +EzTune expo + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + +### ez_filter_hz + +EzTune filter cutoff frequency + +| Default | Min | Max | +| --- | --- | --- | +| 110 | 10 | 300 | + +--- + +### ez_rate + +EzTune rate + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + +### ez_response + +EzTune response + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + +### ez_stability + +EzTune stability + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 0 | 200 | + +--- + ### failsafe_delay Time in deciseconds to wait before activating failsafe when signal is lost. See [Failsafe documentation](Failsafe.md#failsafe_delay). @@ -1222,16 +1322,6 @@ Iterm is not allowed to grow when stick position is above threshold. This solves --- -### fw_iterm_throw_limit - -Limits max/min I-term value in stabilization PID controller in case of Fixed Wing. It solves the problem of servo saturation before take-off/throwing the airplane into the air. By default, error accumulated in I-term can not exceed 1/3 of servo throw (around 165us). Set 0 to disable completely. - -| Default | Min | Max | -| --- | --- | --- | -| 165 | FW_ITERM_THROW_LIMIT_MIN | FW_ITERM_THROW_LIMIT_MAX | - ---- - ### fw_level_pitch_gain I-gain for the pitch trim for self-leveling flight modes. Higher values means that AUTOTRIM will be faster but might introduce oscillations @@ -1394,11 +1484,11 @@ Enable automatic configuration of UBlox GPS receivers. ### gps_dyn_model -GPS navigation model: Pedestrian, Air_1g, Air_4g. Default is AIR_1G. Use pedestrian with caution, can cause flyaways with fast flying. +GPS navigation model: Pedestrian, Automotive, Air<1g, Air<2g, Air<4g. Default is AIR_2G. Use pedestrian/Automotive with caution, can cause flyaways with fast flying. | Default | Min | Max | | --- | --- | --- | -| AIR_1G | | | +| AIR_2G | | | --- @@ -1754,7 +1844,7 @@ Allows to chose when the home position is reset. Can help prevent resetting home ### inav_use_gps_no_baro -_// TODO_ +Defines if INAV should use only use GPS data for altitude estimation and not barometer. If set to ON, INAV will allow GPS assisted modes and RTH even when there is no barometer installed. | Default | Min | Max | | --- | --- | --- | @@ -1832,19 +1922,9 @@ Decay coefficient for estimated velocity when GPS reference for position is lost --- -### inav_w_xyz_acc_p - -_// TODO_ - -| Default | Min | Max | -| --- | --- | --- | -| 1.0 | 0 | 1 | - ---- - ### inav_w_z_baro_p -Weight of barometer measurements in estimated altitude and climb rate +Weight of barometer measurements in estimated altitude and climb rate. Setting is used on both airplanes and multirotors. | Default | Min | Max | | --- | --- | --- | @@ -1854,7 +1934,7 @@ Weight of barometer measurements in estimated altitude and climb rate ### inav_w_z_gps_p -Weight of GPS altitude measurements in estimated altitude. Setting is used only of airplanes +Weight of GPS altitude measurements in estimated altitude. Setting is used on both airplanes and multirotors. | Default | Min | Max | | --- | --- | --- | @@ -1932,6 +2012,16 @@ Used to prevent Iterm accumulation on during maneuvers. Iterm will be dampened w --- +### led_pin_pwm_mode + +PWM mode of LED pin. + +| Default | Min | Max | +| --- | --- | --- | +| SHARED_LOW | | | + +--- + ### ledstrip_visual_beeper _// TODO_ @@ -2354,7 +2444,7 @@ This is the maximum value (in us) sent to esc when armed. Default of 1850 are OK ### mc_cd_lpf_hz -Cutoff frequency for Control Derivative. Lower value smoother reaction on fast stick movements. With higher values, response will be more aggressive, jerky +Cutoff frequency for Control Derivative. This controls the cutoff for the LPF that is applied to the CD (Feed Forward) signal to the PID controller. Lower value will produce a smoother CD gain to the controller, but it will be more delayed. Higher values will produce CD gain that may have more noise in the signal depending on your RC link but wil be less delayed. | Default | Min | Max | | --- | --- | --- | @@ -2364,7 +2454,7 @@ Cutoff frequency for Control Derivative. Lower value smoother reaction on fast s ### mc_cd_pitch -Multicopter Control Derivative gain for PITCH +Multicopter Control Derivative gain for PITCH (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough. | Default | Min | Max | | --- | --- | --- | @@ -2374,7 +2464,7 @@ Multicopter Control Derivative gain for PITCH ### mc_cd_roll -Multicopter Control Derivative gain for ROLL +Multicopter Control Derivative gain for ROLL (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough. | Default | Min | Max | | --- | --- | --- | @@ -2384,7 +2474,7 @@ Multicopter Control Derivative gain for ROLL ### mc_cd_yaw -Multicopter Control Derivative gain for YAW +Multicopter Control Derivative gain for YAW (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough. | Default | Min | Max | | --- | --- | --- | @@ -2822,6 +2912,16 @@ P gain of Heading Hold controller (Fixedwing) --- +### nav_fw_land_approach_length + +Length of the final approach + +| Default | Min | Max | +| --- | --- | --- | +| 35000 | 100 | 100000 | + +--- + ### nav_fw_land_dive_angle Dive angle that airplane will use during final landing phase. During dive phase, motor is stopped or IDLE and roll control is locked to 0 degrees @@ -2832,13 +2932,63 @@ Dive angle that airplane will use during final landing phase. During dive phase, --- -### nav_fw_launch_abort_deadband +### nav_fw_land_final_approach_pitch2throttle_mod -Launch abort stick deadband in [r/c points], applied after r/c deadband and expo. The Roll/Pitch stick needs to be deflected beyond this deadband to abort the launch. +Modifier for pitch to throttle ratio at final approach. In Percent. | Default | Min | Max | | --- | --- | --- | -| 100 | 2 | 250 | +| 100 | 100 | 400 | + +--- + +### nav_fw_land_flare_alt + +Initial altitude of the flare phase + +| Default | Min | Max | +| --- | --- | --- | +| 150 | 0 | 10000 | + +--- + +### nav_fw_land_flare_pitch + +Pitch value for flare phase. In degrees + +| Default | Min | Max | +| --- | --- | --- | +| 8 | -15 | 45 | + +--- + +### nav_fw_land_glide_alt + +Initial altitude of the glide phase + +| Default | Min | Max | +| --- | --- | --- | +| 200 | 100 | 5000 | + +--- + +### nav_fw_land_glide_pitch + +Pitch value for glide phase. In degrees. + +| Default | Min | Max | +| --- | --- | --- | +| 0 | -15 | 45 | + +--- + +### nav_fw_land_max_tailwind + +Max. tailwind (in cm/s) if no landing direction with downwind is available + +| Default | Min | Max | +| --- | --- | --- | +| 140 | 0 | 3000 | --- @@ -2902,6 +3052,16 @@ Launch idle throttle - throttle to be set before launch sequence is initiated. I --- +### nav_fw_launch_land_abort_deadband + +Launch and landing abort stick deadband in [r/c points], applied after r/c deadband and expo. The Roll/Pitch stick needs to be deflected beyond this deadband to abort the launch or landing. + +| Default | Min | Max | +| --- | --- | --- | +| 100 | 2 | 250 | + +--- + ### nav_fw_launch_manual_throttle Allows launch with manually controlled throttle. INAV only levels wings and controls climb pitch during launch. Throttle is controlled directly by throttle stick movement. IF USED WITHOUT A GPS LOCK plane must be launched immediately after throttle is increased to avoid issues with climb out stabilisation and the launch ending sooner than expected (launch end timer starts as soon as the throttle stick is raised). @@ -3438,7 +3598,7 @@ Multicopter hover throttle hint for altitude controller. Should be set to approx | Default | Min | Max | | --- | --- | --- | -| 1500 | 1000 | 2000 | +| 1300 | 1000 | 2000 | --- @@ -3602,6 +3762,16 @@ When ON, NAV engine will slow down when switching to the next waypoint. This pri --- +### nav_min_ground_speed + +Minimum ground speed for navigation flight modes [m/s]. Currently, this only affects fixed wing. Default 7 m/s. + +| Default | Min | Max | +| --- | --- | --- | +| 7 | 6 | 50 | + +--- + ### nav_min_rth_distance Minimum distance from homepoint when RTH full procedure will be activated [cm]. Below this distance, the mode will activate at the current location and the final phase is executed (loiter / land). Above this distance, the full procedure is activated, which may include initial climb and flying directly to the homepoint before entering the loiter / land phase. @@ -3732,6 +3902,16 @@ If set to ON, aircraft will execute initial climb regardless of position sensor --- +### nav_rth_fs_landing_delay + +If landing is active on Failsafe and this is above 0. The aircraft will hover or loiter for X seconds before performing the landing. If the battery enters the warning or critical levels, the land will proceed. Default = 0 [seconds] + +| Default | Min | Max | +| --- | --- | --- | +| 0 | 0 | 1800 | + +--- + ### nav_rth_home_altitude Aircraft will climb/descend to this altitude after reaching home if landing is not enabled. Set to 0 to stay at `nav_rth_altitude` (default) [cm] @@ -4012,6 +4192,16 @@ Value above which to make the OSD relative altitude indicator blink (meters) --- +### osd_arm_screen_display_time + +Amount of time to display the arm screen [ms] + +| Default | Min | Max | +| --- | --- | --- | +| 1500 | 1000 | 5000 | + +--- + ### osd_baro_temp_alarm_max Temperature above which the baro temperature OSD element will start blinking (decidegrees centigrade) @@ -4342,6 +4532,76 @@ Temperature under which the IMU temperature OSD element will start blinking (dec --- +### osd_inav_to_pilot_logo_spacing + +The space between the INAV and pilot logos, if `osd_use_pilot_logo` is `ON`. This number may be adjusted so that it fits the odd/even col width displays. For example, if using an odd column width display, such as Walksnail, and this is set to 4. 1 will be added so that the logos are equally spaced from the centre of the screen. + +| Default | Min | Max | +| --- | --- | --- | +| 8 | 0 | 20 | + +--- + +### osd_joystick_down + +PWM value for DOWN key + +| Default | Min | Max | +| --- | --- | --- | +| 0 | 0 | 100 | + +--- + +### osd_joystick_enabled + +Enable OSD Joystick emulation + +| Default | Min | Max | +| --- | --- | --- | +| OFF | OFF | ON | + +--- + +### osd_joystick_enter + +PWM value for ENTER key + +| Default | Min | Max | +| --- | --- | --- | +| 75 | 0 | 100 | + +--- + +### osd_joystick_left + +PWM value for LEFT key + +| Default | Min | Max | +| --- | --- | --- | +| 63 | 0 | 100 | + +--- + +### osd_joystick_right + +PWM value for RIGHT key + +| Default | Min | Max | +| --- | --- | --- | +| 28 | 0 | 100 | + +--- + +### osd_joystick_up + +PWM value for UP key + +| Default | Min | Max | +| --- | --- | --- | +| 48 | 0 | 100 | + +--- + ### osd_left_sidebar_scroll _// TODO_ @@ -4372,9 +4632,9 @@ LQ % indicator blinks below this value. For Crossfire use 70%, for Tracer use 50 --- -### osd_mah_used_precision +### osd_mah_precision -Number of digits used to display mAh used. +Number of digits used for mAh precision. Currently used by mAh Used and Battery Remaining Capacity | Default | Min | Max | | --- | --- | --- | @@ -4762,6 +5022,16 @@ IMPERIAL, METRIC, UK --- +### osd_use_pilot_logo + +Use custom pilot logo with/instead of the INAV logo. The pilot logo must be characters 473 to 511 + +| Default | Min | Max | +| --- | --- | --- | +| OFF | OFF | ON | + +--- + ### osd_video_system Video system used. Possible values are `AUTO`, `PAL`, `NTSC`, `HDZERO`, 'DJIWTF', 'AVATAR' and `BF43COMPAT` @@ -4772,6 +5042,16 @@ Video system used. Possible values are `AUTO`, `PAL`, `NTSC`, `HDZERO`, 'DJIWTF' --- +### pid_iterm_limit_percent + +Limits max/min I-term value in stabilization PID controller. It solves the problem of servo saturation before take-off/throwing the airplane into the air. Or multirotors with low authority. By default, error accumulated in I-term can not exceed 33% of total pid throw (around 165us on deafult pidsum_limit of pitch/roll). Set 0 to disable completely. + +| Default | Min | Max | +| --- | --- | --- | +| 33 | 0 | 200 | + +--- + ### pid_type Allows to set type of PID controller used in control loop. Possible values: `NONE`, `PID`, `PIFF`, `AUTO`. Change only in case of experimental platforms like VTOL, tailsitters, rovers, boats, etc. Airplanes should always use `PIFF` and multirotors `PID` @@ -4868,7 +5148,7 @@ Selection of pitot hardware. | Default | Min | Max | | --- | --- | --- | -| VIRTUAL | | | +| NONE | | | --- @@ -5572,6 +5852,16 @@ Delay before disarming when requested by switch (ms) [0-1000] --- +### tailsitter_orientation_offset + +Apply a 90 deg pitch offset in sensor aliment for tailsitter flying mode + +| Default | Min | Max | +| --- | --- | --- | +| OFF | OFF | ON | + +--- + ### telemetry_halfduplex S.Port telemetry only: Turn UART into UNIDIR for usage on F1 and F4 target. See Telemetry.md for details @@ -5672,9 +5962,19 @@ See tpa_rate. --- +### tpa_on_yaw + +Throttle PID attenuation also reduces influence on YAW for multi-rotor, Should be set to ON for tilting rotors. + +| Default | Min | Max | +| --- | --- | --- | +| OFF | OFF | ON | + +--- + ### tpa_rate -Throttle PID attenuation reduces influence of P on ROLL and PITCH as throttle increases. For every 1% throttle after the TPA breakpoint, P is reduced by the TPA rate. +Throttle PID attenuation reduces influence of PDFF on ROLL and PITCH of multi-rotor, PIDFF on ROLL,PITCH,YAW OF fixed_wing as throttle increases. For every 1% throttle after the TPA breakpoint, P is reduced by the TPA rate. | Default | Min | Max | | --- | --- | --- | @@ -5794,11 +6094,11 @@ Warning voltage per cell, this triggers battery-warning alarms, in 0.01V units, ### vtx_band -Configure the VTX band. Set to zero to use `vtx_freq`. Bands: 1: A, 2: B, 3: E, 4: F, 5: Race. +Configure the VTX band. Bands: 1: A, 2: B, 3: E, 4: F, 5: Race. | Default | Min | Max | | --- | --- | --- | -| 1 | VTX_SETTINGS_NO_BAND | VTX_SETTINGS_MAX_BAND | +| 1 | VTX_SETTINGS_MIN_BAND | VTX_SETTINGS_MAX_BAND | --- diff --git a/docs/VTOL.md b/docs/VTOL.md new file mode 100644 index 00000000000..64afb333d11 --- /dev/null +++ b/docs/VTOL.md @@ -0,0 +1,236 @@ +# Welcome to INAV VTOL + +Thank you for trying the INAV VTOL. Read every line in this tutorial. Your patience can save both time and potential repair costs for the model. + +## Who Should Use This Tutorial? + +This tutorial is designed for individuals who +- have prior experience with **both INAV multi-rotor and INAV fixed-wing configurations/operations.** +- know how to create a custom mixer for their model. +- know basic physics of vtol operation + +## Firmware Status + +The firmware is in a flyable state, but it hasn't undergone extensive testing yet. This means there may be potential issues that have not yet been discovered. + +## Future Changes + +Please be aware that both the setup procedure and firmware may change in response to user feedback and testing results. +## Your Feedback Matters + +We highly value your feedback as it plays a crucial role in the development and refinement of INAV VTOL capabilities. Please share your experiences, suggestions, and any issues you encounter during testing. Your insights are invaluable in making INAV VTOL better for everyone. + +# VTOL Configuration Steps + +### The VTOL functionality is achieved by switching/transitioning between two configurations stored in the FC. VTOL specific configurations are Mixer Profiles with associated PID profiles. One profile set is for fixed-wing(FW) mode, One is for multi-copter(MC) mode. Configuration/Settings other than Mixer/PID profiles are shared among two modes +![Alt text](Screenshots/mixerprofile_flow.png) + +0. **Find a DIFF ALL file for your model and start from there if possible** + - Be aware that `MIXER PROFILE 2` RC mode setting introduced by diff file can get your stuck in a mixer_profile. remove or change channel to proceed +1. **Setup Profile 1:** + - Configure it as a normal fixed-wing/multi-copter. + +2. **Setup Profile 2:** + - Configure it as a normal multi-copter/fixed-wing. + +3. **Mode Tab Settings:** + - Set up switching in the mode tab. + +4. *(Recommended)* **Transition Mixing (Multi-Rotor Profile):** + - Configure transition mixing to gain airspeed in the multi-rotor profile. + +5. *(Optional)* **Automated Switching (RTH):** + - Optionally, set up automated switching in case of failsafe. + +# STEP0: Load parameter preset/templates +Find a working diff file if you can and start from there. If not, select keep current settings and apply following parameter in cli but read description about which one to apply. + +``` +set small_angle = 180 +set gyro_main_lpf_hz = 80 +set dynamic_gyro_notch_min_hz = 50 +set dynamic_gyro_notch_mode = 3D +set motor_pwm_protocol = DSHOT300 #Try dshot first and see if it works +set airmode_type = STICK_CENTER_ONCE + + +set nav_disarm_on_landing = OFF #band-aid for false landing detection in NAV landing of multi-copter +set nav_rth_allow_landing = FS_ONLY +set nav_wp_max_safe_distance = 500 +set nav_fw_control_smoothness = 2 +set nav_fw_launch_max_altitude = 5000 + +set servo_pwm_rate = 160 #If model using servo for stabilization in MC mode and servo can tolerate it +set servo_lpf_hz = 30 #If model using servo for stabilization in MC mode + + +## profile 1 as airplane and profile 2 as multi rotor +mixer_profile 1 + +set platform_type = AIRPLANE +set model_preview_type = 26 +set motorstop_on_low = ON +set mixer_pid_profile_linking = ON + +mixer_profile 2 + +set platform_type = TRICOPTER +set model_preview_type = 1 +set mixer_pid_profile_linking = ON + +profile 1 #pid profile +set dterm_lpf_hz = 10 +set d_boost_min = 1.000 +set d_boost_max = 1.000 +set fw_level_pitch_trim = 5.000 +set roll_rate = 18 +set pitch_rate = 9 +set yaw_rate = 3 +set fw_turn_assist_pitch_gain = 0.4 +set max_angle_inclination_rll = 450 +set fw_ff_pitch = 80 +set fw_ff_roll = 50 +set fw_p_pitch = 15 +set fw_p_roll = 15 + +profile 2 +set dterm_lpf_hz = 60 +set dterm_lpf_type = PT3 +set d_boost_min = 0.800 +set d_boost_max = 1.200 +set d_boost_gyro_delta_lpf_hz = 60 +set antigravity_gain = 2.000 +set antigravity_accelerator = 5.000 +set smith_predictor_delay = 1.500 +set tpa_rate = 20 +set tpa_breakpoint = 1200 +set tpa_on_yaw = ON #If model using control surface/tilt mechanism for stabilization in MC mode +set roll_rate = 18 +set pitch_rate = 18 +set yaw_rate = 9 +set mc_iterm_relax = RPY + +save +``` + +# STEP1&2: Configuring as a Normal fixed-wing/Multi-Copter in two profiles separately + +1. **Select the fisrt Mixer Profile and PID Profile:** + - In the CLI, switch to the mixer_profile and pid_profile you wish to set first. You can also switch mixer_profile/pid_profile through gui if with aforementioned presets loaded. + ``` + mixer_profile 1 #in this example, we set profile 1 first + set mixer_pid_profile_linking = ON # Let the mixer_profile handle the pid_profile switch on this mixer_profile + set platform_type = AIRPLANE + save + ``` + +2. **Configure the fixed-wing/Multi-Copter:** + - Configure your fixed-wing/Multi-Copter as you normally would, or you can copy and paste default settings to expedite the process. + - Dshot esc protocol availability might be limited depends on outputs and fc board you are using. change the motor wiring or use oneshot/multishot esc protocol and calibrate throttle range. + - You can use throttle = -1 as a placeholder for the motor you wish to stop if the motor isn't the last motor + - Consider conducting a test flight to ensure that everything operates as expected. And tune the settings, trim the servos. + +![Alt text](Screenshots/mixerprofile_fw_mixer.png) + +3. **Switch to Another Mixer Profile with PID Profile:** + - In the CLI, switch to another mixer_profile along with the appropriate pid_profile. You can also switch mixer_profile/pid_profile through gui if with aforementioned presets loaded. + ``` + mixer_profile 2 + set mixer_pid_profile_linking = ON + set platform_type = MULTIROTOR/TRICOPTER + save + ``` + +4. **Configure the Multi-Copter/fixed-wing:** + - Set up your multi-copter/fixed-wing as usual, this time for mixer_profile 2 and pid_profile 2. + - Utilize the 'MAX' input in the servo mixer to tilt the motors without altering the servo midpoint. + - At this stage, focus on configuring profile-specific settings. You can streamline this process by copying and pasting the default PID settings. + - you can set -1 in motor mixer throttle as a place holder: disable that motor but will load following motor rules + - compass is required to enable navigation modes for multi-rotor profile. + - Consider conducting a test flight to ensure that everything operates as expected. And tune the settings. + - It is advisable to have a certain degree of control surface (elevon / elevator) mapping for stabilization even in multi-copter mode. This helps improve control authority when airspeed is high. It might be unable to recover from a dive without them. + +![Alt text](Screenshots/mixerprofile_mc_mixer.png) + +5. **Tailsitters:planned for INAV 7.1** + - Configure the fixed-wing mode/profile sets normally. Use MultiCopter platform type for tail_sitting flying mode/profile sets. + - The baseline board aliment is FW mode(ROLL axis is the trust axis). So set `tailsitter_orientation_offset = ON ` in the tail_sitting MC mode. + - Configure mixer ROLL/YAW mixing according to tail_sitting orientation in the tail_sitting MC mode. YAW axis is the trust axis. + - Conduct a bench test and see the orientation of the model changes in inav-configurator setup tab + +# STEP3: Mode Tab Settings: +### We recommend using an 3-pos switch on you radio to activate these modes, So pilot can jump in or bell out at any moment. +### Here is a example, in the bottom of inav-configurator Modes tab: +![Alt text](Screenshots/mixer_profile.png) +| 1000~1300 | 1300~1700 | 1700~2000 | +| :-- | :-- | :-- | +| Profile1(FW) with transition off | Profile2(MC) with transition on | Profile2(MC) with transition off | + +- Profile file switching becomes available after completing the runtime sensor calibration(15-30s after booting). And It is **not available** when a navigation mode or position hold is active. + +- By default, `mixer_profile 1` is used. `mixer_profile 2` is used when the `MIXER PROFILE 2` mode is activate. Once configured successfully, you will notice that the profiles and model preview changes accordingly when you refresh the relevant INAV Configurator tabs. + +- Use the `MIXER TRANSITION` mode to gain airspeed in MC profile, set `MIXER TRANSITION` accordingly. + +Conduct a bench test on the model (without props attached). The model can now switch between fixed-wing and multi-copter modes while armed. Furthermore, it is capable of mid-air switching, resulting in an immediate stall upon entering fixed-wing profile + +# STEP4: Transition Mixing (Multi-Rotor Profile)(Recommended) +### Transition Mixing is typically useful in multi-copter profile to gain airspeed in prior to entering the fixed-wing profile. When the `MIXER TRANSITION` mode is activated, the associated motor or servo will move according to your configured Transition Mixing. + +Please note that transition input is disabled when a navigation mode is activated. The use of Transition Mixing is necessary to enable additional features such as VTOL RTH with out stalling. +## Servo 'Transition Mixing': Tilting rotor configuration. +Add new servo mixer rules, and select 'Mixer Transition' in input. Set the weight/rate according to your desired angle. This will allow tilting the motor for tilting rotor model. + +![Alt text](Screenshots/mixerprofile_servo_transition_mix.png) + +## Motor 'Transition Mixing': Dedicated forward motor configuration +In motor mixer set: +- -2.0 < throttle < -1.0: The motor will spin regardless of the radio's throttle position at a speed of `abs(throttle) - 1` multiplied by throttle range only when Mixer Transition is activated. + +![Alt text](Screenshots/mixerprofile_4puls1_mix.png) + +## TailSitter 'Transition Mixing': +No additional settings needed, 45deg off set will be added to target pitch angle for angle mode in the firmware. + +### With aforementioned settings, your model should be able to enter fixed-wing profile without stalling. + +# Automated Switching (RTH) (Optional): +### This is one of the least tested features. This feature is primarily designed for Return to Home (RTH) in the event of a failsafe. +When configured correctly, the model will use the Fixed-Wing (FW) mode to efficiently return home and then transition to Multi-Copter (MC) mode for easier landing. + +To enable this feature, type following command in cli + +1. In your MC mode mixer profile (e.g., mixer_profile 2), set `mixer_automated_switch` to `ON`. leave it to `OFF` if burning remaining battery capacity on the way home is acceptable. +``` +mixer_profile 2or1 +set mixer_automated_switch= ON +``` + +2. Set `mixer_switch_trans_timer` ds in cli in the MC mode mixer profile to specify the time required for your model to gain sufficient airspeed before transitioning to FW mode. +``` +mixer_profile 2or1 +set mixer_switch_trans_timer = 30 # 3s, 3000ms +``` +3. In your FW mode mixer profile (e.g., mixer_profile 1), also set `mixer_automated_switch` to `ON`. leave it to `OFF` if automated landing in fixed-wing is acceptable. +``` +mixer_profile 1or2 +set mixer_automated_switch = ON +``` +4. Save your settings. type `save` in cli. + +If you set `mixer_automated_switch` to `OFF` for all mixer profiles (the default setting), the model will not perform automated transitions. You can always enable navigation modes after performing a manual transition. + + +# Notes and Experiences +## General +- VTOL model operating in multi-copter (MC) mode may encounter challenges in windy conditions. Please exercise caution when testing in such conditions. +- Make sure you can recover from a complete stall before trying the mid air transition +- It will be much safer if you can understand every line in diff all, read your diff all before maiden + +## Tilting-rotor +- In some tilting motor models, you may experience roll/yaw coupled oscillations when `MIXER TRANSITION` is activated. To address this issue, you can try the following: + 1. Use prop blade meets at top/rear prop direction for tilting motors to balance the effects of torque and P-factor. + 2. In addition to 1. Add a little yaw mixing(about 0.2) in tilt motors. +- There will be a time window that tilting motors is providing up lift but rear motor isn't. Result in a sudden pitch raise on the entering of the mode. Use the max speed or faster speed in tiling servo to reduce the time window. OR lower the throttle on the entering of the FW mode to mitigate the effect. +## Dedicated forward motor +- Easiest way to setup a vtol. and efficiency can be improved by using different motor/prop for hover and forward flight \ No newline at end of file diff --git a/docs/assets/images/Approach-Drawing-Side.png b/docs/assets/images/Approach-Drawing-Side.png new file mode 100644 index 00000000000..a5be8b594c4 Binary files /dev/null and b/docs/assets/images/Approach-Drawing-Side.png differ diff --git a/docs/assets/images/Approach-Drawing-Up.png b/docs/assets/images/Approach-Drawing-Up.png new file mode 100644 index 00000000000..c11f1570d1d Binary files /dev/null and b/docs/assets/images/Approach-Drawing-Up.png differ diff --git a/docs/assets/images/led_pin_pwm.png b/docs/assets/images/led_pin_pwm.png new file mode 100644 index 00000000000..93bab8d1df4 Binary files /dev/null and b/docs/assets/images/led_pin_pwm.png differ diff --git a/docs/assets/images/ledpinpwmfilter.png b/docs/assets/images/ledpinpwmfilter.png new file mode 100644 index 00000000000..d27acea6bc6 Binary files /dev/null and b/docs/assets/images/ledpinpwmfilter.png differ diff --git a/docs/assets/images/ledpinpwmled.png b/docs/assets/images/ledpinpwmled.png new file mode 100644 index 00000000000..3286e51ae30 Binary files /dev/null and b/docs/assets/images/ledpinpwmled.png differ diff --git a/docs/assets/images/ledpinpwmpowerled.png b/docs/assets/images/ledpinpwmpowerled.png new file mode 100644 index 00000000000..2cc0d4bd1cf Binary files /dev/null and b/docs/assets/images/ledpinpwmpowerled.png differ diff --git a/docs/assets/images/osd_joystick.jpg b/docs/assets/images/osd_joystick.jpg new file mode 100644 index 00000000000..9b2ad0bac09 Binary files /dev/null and b/docs/assets/images/osd_joystick.jpg differ diff --git a/docs/assets/images/osd_joystick_keys.png b/docs/assets/images/osd_joystick_keys.png new file mode 100644 index 00000000000..d21b7b7d659 Binary files /dev/null and b/docs/assets/images/osd_joystick_keys.png differ diff --git a/docs/assets/images/ws2811_data.png b/docs/assets/images/ws2811_data.png new file mode 100644 index 00000000000..ce95ef947fc Binary files /dev/null and b/docs/assets/images/ws2811_data.png differ diff --git a/docs/assets/images/ws2811_data_high.png b/docs/assets/images/ws2811_data_high.png new file mode 100644 index 00000000000..c77e89e5ece Binary files /dev/null and b/docs/assets/images/ws2811_data_high.png differ diff --git a/docs/assets/images/ws2811_packets.png b/docs/assets/images/ws2811_packets.png new file mode 100644 index 00000000000..ef5cdca72b5 Binary files /dev/null and b/docs/assets/images/ws2811_packets.png differ diff --git a/docs/assets/images/ws2811_packets_high.png b/docs/assets/images/ws2811_packets_high.png new file mode 100644 index 00000000000..49c4711e417 Binary files /dev/null and b/docs/assets/images/ws2811_packets_high.png differ diff --git a/docs/boards/MAMBAH743_2022B.md b/docs/boards/MAMBAH743_2022B.md new file mode 100644 index 00000000000..d3d91e14c14 --- /dev/null +++ b/docs/boards/MAMBAH743_2022B.md @@ -0,0 +1,9 @@ +# VTX Power SWITCH + +Contrary to what the documentation suggests, VTX power is actually on USER2. + +# Dual Gyros + +INAV 7.1 changed the default gyro of the board from the gyro on SPI4 back to the one on SPI1. A new tagrt ```MAMBAH743_2022B_GYRO2``` was added to use gyro on SPI4, in case you suspect an issue with the gyro on SPI1, you can switch to the gyro on SPI4 by using the new target. + + diff --git a/docs/development/Building in Docker.md b/docs/development/Building in Docker.md index 80d661ecf37..575614a95d1 100755 --- a/docs/development/Building in Docker.md +++ b/docs/development/Building in Docker.md @@ -33,12 +33,23 @@ If you are getting error "standard_init_linux.go:219: exec user process caused: You'll have to manually execute the same steps that the build script does: -1. `docker build -t inav-build .` +1. `docker build --build-arg USER_ID=1000 --build-arg GROUP_ID=1000 -t inav-build .` + This step is only needed the first time. -2. `docker run --rm -it -u root -v :/src inav-build ` + + If GDB should be installed in the image, add argument '--build-arg GDB=yes' +2. `docker run --rm -it -v :/src inav-build ` + Where `` must be replaced with the absolute path of where you cloned this repo (see above), and `` with the name of the target that you want to build. - + Note that on Windows/WSL 2 mounted /src folder is writeable for root user only. You have to run build under root user. You can achieve this by using `-u root` option in the command line above, or by removing "USER inav" line from the .\DockerFile before building image. -3. If you need to update `Settings.md`, run `docker run --entrypoint /src/cmake/docker_docs.sh --rm -it -u root -v :/src inav-build` +3. If you need to update `Settings.md`, run: + +`docker run --entrypoint /src/cmake/docker_docs.sh --rm -it -v :/src inav-build` + +4. Building SITL: + +`docker run --rm --entrypoint /src/cmake/docker_build_sitl.sh -it -v :/src inav-build` + +5. Running SITL: + +`docker run -p 5760:5760 -p 5761:5761 -p 5762:5762 -p 5763:5763 -p 5764:5764 -p 5765:5765 -p 5766:5766 -p 5767:5767 --entrypoint /src/cmake/docker_run_sitl.sh --rm -it -v :/src inav-build`. + + SITL command line parameters can be adjusted in `cmake/docker_run_sitl.sh`. Refer to the [Linux](#Linux) instructions or the [build script](/build.sh) for more details. diff --git a/docs/development/Building in Windows 10 or 11 with Linux Subsystem.md b/docs/development/Building in Windows 10 or 11 with Linux Subsystem.md index a2c5894e72f..9cee0ede253 100644 --- a/docs/development/Building in Windows 10 or 11 with Linux Subsystem.md +++ b/docs/development/Building in Windows 10 or 11 with Linux Subsystem.md @@ -36,7 +36,9 @@ To run `cmake` in the latest version you will need to update from Ubuntu `18_04 Mount MS windows C drive and clone INAV 1. `cd /mnt/c` -1. `git clone https://github.com/iNavFlight/inav.git` +2. `git clone https://github.com/iNavFlight/inav.git` +3. `git checkout 6.1.1` (to switch to a specific release tag, for this example INAV version 6.1.1) +4. `git checkout -b my-branch` (to create own branch) You are ready! You now have a folder called inav in the root of C drive that you can edit in windows diff --git a/docs/development/Software In The Loop (HITL) plugin for X-Plane 11.md b/docs/development/Hardware In The Loop (HITL) plugin for X-Plane.md similarity index 83% rename from docs/development/Software In The Loop (HITL) plugin for X-Plane 11.md rename to docs/development/Hardware In The Loop (HITL) plugin for X-Plane.md index 0b7d106e0d1..c166c5117ac 100644 --- a/docs/development/Software In The Loop (HITL) plugin for X-Plane 11.md +++ b/docs/development/Hardware In The Loop (HITL) plugin for X-Plane.md @@ -1,4 +1,4 @@ -# Software In The Loop (HITL) plugin for X-Plane 11 +# Hardware In The Loop (HITL) plugin for X-Plane 11/12 **Hardware-in-the-loop (HITL) simulation**, is a technique that is used in the development and testing of complex real-time embedded systems. @@ -6,6 +6,6 @@ **INAV-X-Plane-HITL** is plugin for **X-Plane** for testing and developing flight controllers with **INAV flight controller firmware** -https://github.com/iNavFlight/inav. +https://github.com/RomanLut/INAV-X-Plane-HITL HITL technique can be used to test features during development. Please check page above for installation instructions. diff --git a/docs/development/IDE - Visual Studio Code with Windows 10.md b/docs/development/IDE - Visual Studio Code with Windows 10.md index ffd0383c555..2baec8b6c24 100644 --- a/docs/development/IDE - Visual Studio Code with Windows 10.md +++ b/docs/development/IDE - Visual Studio Code with Windows 10.md @@ -39,8 +39,7 @@ Edit file `./.vscode/c_cpp_properties.json` to setup enabled `defines` "intelliSenseMode": "msvc-x64", "cStandard": "c11", "cppStandard": "c++17", - "defines": [ - "NAV_FIXED_WING_LANDING", + "defines": [, "USE_OSD", "USE_GYRO_NOTCH_1", "USE_GYRO_NOTCH_2", diff --git a/docs/development/Windows 11 - VS Code - WSL2 - Hardware Debugging.md b/docs/development/Windows 11 - VS Code - WSL2 - Hardware Debugging.md index 3a1738b7ea5..14ac0f31a89 100644 --- a/docs/development/Windows 11 - VS Code - WSL2 - Hardware Debugging.md +++ b/docs/development/Windows 11 - VS Code - WSL2 - Hardware Debugging.md @@ -235,7 +235,6 @@ sudo udevadm control --reload-rules "cStandard": "c11", "cppStandard": "c++17", "defines": [ - "NAV_FIXED_WING_LANDING", "USE_OSD", "USE_GYRO_NOTCH_1", "USE_GYRO_NOTCH_2", diff --git a/lib/main/STM32F4/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/lib/main/STM32F4/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index 5d4d2521693..3c63a978f2c 100644 --- a/lib/main/STM32F4/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/lib/main/STM32F4/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -343,6 +343,12 @@ static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * len--; hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; } + + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[2] = hmsc->bot_data[2] | (1 << 7); + } + return 0; } @@ -365,6 +371,12 @@ static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t len--; hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; } + + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[3] = hmsc->bot_data[3] | (1 << 7); + } + return 0; } diff --git a/lib/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/lib/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index ed3deef5959..b1d76cc25da 100644 --- a/lib/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/lib/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -347,6 +347,12 @@ static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * len--; hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; } + + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[2] = hmsc->bot_data[2] | (1 << 7); + } + return 0; } @@ -370,6 +376,12 @@ static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t len--; hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; } + + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[3] = hmsc->bot_data[3] | (1 << 7); + } + return 0; } diff --git a/lib/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/lib/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index d15d9039a54..ffc615dac5a 100644 --- a/lib/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/lib/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -346,6 +346,12 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p len--; hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; } + + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[2] = hmsc->bot_data[2] | (1 << 7); + } + return 0; } @@ -371,6 +377,11 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; } + // set bit 7 of the device configuration byte to indicate write protection + if (((USBD_StorageTypeDef *)pdev->pMSC_UserData)->IsWriteProtected(lun) != 0) { + hmsc->bot_data[3] = hmsc->bot_data[3] | (1 << 7); + } + return 0; } diff --git a/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index 2533cdb8774..a82ef08a2f0 100644 --- a/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -184,8 +184,8 @@ __ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ __ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; -uint32_t APP_Rx_ptr_in = 0; -uint32_t APP_Rx_ptr_out = 0; +volatile uint32_t APP_Rx_ptr_in = 0; +volatile uint32_t APP_Rx_ptr_out = 0; uint32_t APP_Rx_length = 0; uint8_t USB_Tx_State = USB_CDC_IDLE; @@ -482,8 +482,8 @@ uint8_t usbd_cdc_Init (void *pdev, uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx) { - (void)pdev; - (void)cfgidx; + (void)pdev; + (void)cfgidx; /* Open EP IN */ DCD_EP_Close(pdev, CDC_IN_EP); @@ -594,7 +594,7 @@ uint8_t usbd_cdc_Setup (void *pdev, */ uint8_t usbd_cdc_EP0_RxReady (void *pdev) { - (void)pdev; + (void)pdev; if (cdcCmd != NO_CMD) { /* Process the data */ @@ -617,60 +617,45 @@ uint8_t usbd_cdc_EP0_RxReady (void *pdev) */ uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) { - (void)pdev; - (void)epnum; - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == USB_CDC_BUSY) - { - if (APP_Rx_length == 0) - { - USB_Tx_State = USB_CDC_IDLE; - } - else + (void)pdev; + (void)epnum; + uint16_t USB_Tx_length; + + if (USB_Tx_State == USB_CDC_BUSY) { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - if(USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) + if (APP_Rx_length == 0) { - USB_Tx_State = USB_CDC_ZLP; + USB_Tx_State = USB_CDC_IDLE; + } else { + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + } else { + USB_Tx_length = APP_Rx_length; + + if (USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_State = USB_CDC_ZLP; + } + } + + /* Prepare the available data buffer to be sent on IN endpoint */ + DCD_EP_Tx(pdev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer[APP_Rx_ptr_out], USB_Tx_length); + + // Advance the out pointer + APP_Rx_ptr_out = (APP_Rx_ptr_out + USB_Tx_length) % APP_RX_DATA_SIZE; + APP_Rx_length -= USB_Tx_length; + + return USBD_OK; } - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - return USBD_OK; } - } - - /* Avoid any asynchronous transfer during ZLP */ - if (USB_Tx_State == USB_CDC_ZLP) - { - /*Send ZLP to indicate the end of the current transfer */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - NULL, - 0); - - USB_Tx_State = USB_CDC_IDLE; - } - return USBD_OK; + + /* Avoid any asynchronous transfer during ZLP */ + if (USB_Tx_State == USB_CDC_ZLP) { + /*Send ZLP to indicate the end of the current transfer */ + DCD_EP_Tx(pdev, CDC_IN_EP, NULL, 0); + + USB_Tx_State = USB_CDC_IDLE; + } + return USBD_OK; } /** @@ -731,67 +716,49 @@ uint8_t usbd_cdc_SOF (void *pdev) */ static void Handle_USBAsynchXfer (void *pdev) { - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if(USB_Tx_State == USB_CDC_IDLE) - { - if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_out = 0; - } - - if(APP_Rx_ptr_out == APP_Rx_ptr_in) - { - USB_Tx_State = USB_CDC_IDLE; - return; - } - - if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ - { - APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; - - } - else - { - APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; - - } + uint16_t USB_Tx_length; + + if (USB_Tx_State == USB_CDC_IDLE) { + if (APP_Rx_ptr_out == APP_Rx_ptr_in) { + // Ring buffer is empty + return; + } + + if (APP_Rx_ptr_out > APP_Rx_ptr_in) { + // Transfer bytes up to the end of the ring buffer + APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; + } else { + // Transfer all bytes in ring buffer + APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; + } + #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - APP_Rx_length &= ~0x03; + // Only transfer whole 32 bit words of data + APP_Rx_length &= ~0x03; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + + USB_Tx_State = USB_CDC_BUSY; + } else { + USB_Tx_length = APP_Rx_length; + + if (USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_State = USB_CDC_ZLP; + } else { + USB_Tx_State = USB_CDC_BUSY; + } + } - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - USB_Tx_State = USB_CDC_BUSY; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - if(USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_State = USB_CDC_ZLP; - } - else - { - USB_Tx_State = USB_CDC_BUSY; - } + DCD_EP_Tx (pdev, + CDC_IN_EP, + (uint8_t*)&APP_Rx_Buffer[APP_Rx_ptr_out], + USB_Tx_length); + + APP_Rx_ptr_out = (APP_Rx_ptr_out + USB_Tx_length) % APP_RX_DATA_SIZE; + APP_Rx_length -= USB_Tx_length; } - - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } } /** @@ -803,7 +770,7 @@ static void Handle_USBAsynchXfer (void *pdev) */ static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) { - (void)speed; + (void)speed; *length = sizeof (usbd_cdc_CfgDesc); return usbd_cdc_CfgDesc; } diff --git a/readme.md b/readme.md index b15a17aba8a..fbdf251f967 100644 --- a/readme.md +++ b/readme.md @@ -2,58 +2,57 @@ These are unofficial targets for [INAV](https://github.com/iNavFlight/inav). Some of the targets provide support for flight controller boards that do not have official INAV support. Others add features to boards that are supported, such as adding PINIO or extra servo outputs. -Targets can be found in [src/main/target/](src/main/target/) - -Targets available here include: - -GEPRCF722 -GRAVITYF7 -IFLIGHTF7_SXEMINI -MATEKF405SE_PINIO -MATEKF405SE_PINIO2 -OMNIBUSF4_PINIO: -OMNIBUSF4_PINIOPRO -OMNIBUSF4_PINIOV3 -OMNIBUSF4_PINIOV3_S5_S6_2SS -OMNIBUSF4_PINIOV3_S5S6_SS -OMNIBUSF4_PINIOV3_S6_SS -SKYSTARSF405hd -SKYSTARSF722HDPRO -and more - -New additions are very much welcomed. If you've made your own target, please -send a pull request or send me a zip of your files and I'll add it here. -Improvements are also very much welcomed. Any additions or improvements you -make, please send a PR or let me know. - -Here is some information about how you can make your own target, either to support -an FC that isn't already supported, or to remap resources: -[Building Custom Firmware](https://github.com/iNavFlight/inav/wiki/Building-custom-firmware) - -[Mosca's script](https://github.com/iNavFlight/inav/tree/mosca-target-converter/src/utils) can help make a new INAV target from an existing Betaflight target. - -Getting a new target added to the *offical* inav distribution has certain -[requirements](https://github.com/iNavFlight/inav/blob/master/docs/policies/NEW_HARDWARE_POLICY.md). -On the other hand, all targets are welcome here. - -Please add in your target folder a readme.txt file saying what your target is for and how you've tested it. +# F411 PSA + +> INAV no longer accepts targets based on STM32 F411 MCU. + +> INAV 7 is the last INAV official release available for F411 based flight controllers. The next milestone, INAV 8 will not be available for F411 boards. + +![INAV](http://static.rcgroups.net/forums/attachments/6/1/0/3/7/6/a9088858-102-inav.png) + +# PosHold, Navigation and RTH without compass PSA + +Attention all drone pilots and enthusiasts, + +Are you ready to take your flights to new heights with INAV 7.1? We've got some important information to share with you. + +INAV 7.1 brings an exciting update to navigation capabilities. Now, you can soar through the skies, navigate waypoints, and even return to home without relying on a compass. Yes, you heard that right! But before you launch into the air, there's something crucial to consider. + +While INAV 7.1 may not require a compass for basic navigation functions, we strongly advise you to install one for optimal flight performance. Here's why: + +🛰️ Better Flight Precision: A compass provides essential data for accurate navigation, ensuring smoother and more precise flight paths. + +🌐 Enhanced Reliability: With a compass onboard, your drone can maintain stability even in challenging environments, low speeds and strong wind. + +🚀 Minimize Risks: Although INAV 7.1 can get you where you need to go without a compass, flying without one may result in a bumpier ride and increased risk of drift or inaccurate positioning. + +Remember, safety and efficiency are paramount when operating drones. By installing a compass, you're not just enhancing your flight experience, but also prioritizing safety for yourself and those around you. + +So, before you take off on your next adventure, make sure to equip your drone with a compass. It's the smart choice for smoother flights and better navigation. + +Fly safe, fly smart with INAV 7.1 and a compass by your side! # INAV Community +* [INAV Discord Server](https://discord.gg/peg2hhbYwN) +* [INAV Official on Facebook](https://www.facebook.com/groups/INAVOfficial) + +## Features + * Runs on the most popular F4, F7 and H7 flight controllers -* On Screen Display (OSD) - both character and pixel style -* DJI OSD integration: all elements, system messages and warnings +* MSP Displayport for all the HD Digital FPV systems: DJI, Walksnail and HDZero * Outstanding performance out of the box * Position Hold, Altitude Hold, Return To Home and Waypoint Missions * Excellent support for fixed wing UAVs: airplanes, flying wings +* Blackbox flight recorder logging +* Advanced gyro filtering * Fully configurable mixer that allows to run any hardware you want: multirotor, fixed wing, rovers, boats and other experimental devices * Multiple sensor support: GPS, Pitot tube, sonar, lidar, temperature, ESC with BlHeli_32 telemetry +* Logic Conditions, Global Functions and Global Variables: you can program INAV with a GUI * SmartAudio and IRC Tramp VTX support -* Blackbox flight recorder logging * Telemetry: SmartPort, FPort, MAVlink, LTM, CRSF * Multi-color RGB LED Strip support -* Advanced gyro filtering -* Logic Conditions, Global Functions and Global Variables: you can program INAV with a GUI +* On Screen Display (OSD) - both character and pixel style * And many more! @@ -82,10 +81,6 @@ Command line tools (`blackbox_decode`, `blackbox_render`) for Blackbox log conve Users of EdgeTX and OpenTX radios (Taranis, Horus, Jumper, Radiomaster, Nirvana) can use INAV OpenTX Telemetry Widget screen. Software and installation instruction are available here: [https://github.com/iNavFlight/OpenTX-Telemetry-Widget](https://github.com/iNavFlight/OpenTX-Telemetry-Widget) -### INAV magnetometer alignment helper - -[INAV Magnetometer Alignment helper](https://kernel-machine.github.io/INavMagAlignHelper/) allows to align INAV magnetometer despite position and orientation. This simplifies the process of INAV setup on multirotors with tilted GPS modules. - ### OSD layout Copy, Move, or Replace helper tool [Easy INAV OSD switcher tool](https://www.mrd-rc.com/tutorials-tools-and-testing/useful-tools/inav-osd-switcher-tool/) allows you to easily switch your OSD layouts around in INAV. Choose the from and to OSD layouts, and the method of transfering the layouts. diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index b6e433d97d8..7f076b5e29e 100755 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -341,6 +341,8 @@ main_sources(COMMON_SRC flight/secondary_dynamic_gyro_notch.h flight/dynamic_lpf.c flight/dynamic_lpf.h + flight/ez_tune.c + flight/ez_tune.h io/beeper.c io/beeper.h @@ -369,6 +371,8 @@ main_sources(COMMON_SRC io/rcdevice_cam.c io/rcdevice_cam.h + io/osd/custom_elements.c + msp/msp_serial.c msp/msp_serial.h @@ -523,6 +527,8 @@ main_sources(COMMON_SRC io/osd_grid.h io/osd_hud.c io/osd_hud.h + io/osd_joystick.c + io/osd_joystick.h io/smartport_master.c io/smartport_master.h io/vtx.c diff --git a/src/main/blackbox/blackbox.c b/src/main/blackbox/blackbox.c index cb12a7a8968..1bb0165761e 100644 --- a/src/main/blackbox/blackbox.c +++ b/src/main/blackbox/blackbox.c @@ -310,6 +310,7 @@ static const blackboxDeltaFieldDefinition_t blackboxMainFields[] = { {"accSmooth", 0, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ACC}, {"accSmooth", 1, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ACC}, {"accSmooth", 2, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ACC}, + {"accVib", -1, UNSIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(UNSIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ACC}, {"attitude", 0, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ATTITUDE}, {"attitude", 1, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ATTITUDE}, {"attitude", 2, SIGNED, .Ipredict = PREDICT(0), .Iencode = ENCODING(SIGNED_VB), .Ppredict = PREDICT(AVERAGE_2), .Pencode = ENCODING(SIGNED_VB), FLIGHT_LOG_FIELD_CONDITION_ATTITUDE}, @@ -436,6 +437,7 @@ static const blackboxSimpleFieldDefinition_t blackboxSlowFields[] = { {"escTemperature", -1, SIGNED, PREDICT(PREVIOUS), ENCODING(SIGNED_VB)}, #endif {"rxUpdateRate", -1, UNSIGNED, PREDICT(PREVIOUS), ENCODING(UNSIGNED_VB)}, + {"activeWpNumber", -1, UNSIGNED, PREDICT(0), ENCODING(UNSIGNED_VB)}, }; typedef enum BlackboxState { @@ -487,6 +489,7 @@ typedef struct blackboxMainState_s { int16_t gyroPeaksYaw[DYN_NOTCH_PEAK_COUNT]; int16_t accADC[XYZ_AXIS_COUNT]; + int16_t accVib; int16_t attitude[XYZ_AXIS_COUNT]; int32_t debug[DEBUG32_VALUE_COUNT]; int16_t motor[MAX_SUPPORTED_MOTORS]; @@ -554,6 +557,7 @@ typedef struct blackboxSlowState_s { int8_t escTemperature; #endif uint16_t rxUpdateRate; + uint8_t activeWpNumber; } __attribute__((__packed__)) blackboxSlowState_t; // We pack this struct so that padding doesn't interfere with memcmp() //From rc_controls.c @@ -917,6 +921,7 @@ static void writeIntraframe(void) if (testBlackboxCondition(FLIGHT_LOG_FIELD_CONDITION_ACC)) { blackboxWriteSigned16VBArray(blackboxCurrent->accADC, XYZ_AXIS_COUNT); + blackboxWriteUnsignedVB(blackboxCurrent->accVib); } if (testBlackboxCondition(FLIGHT_LOG_FIELD_CONDITION_ATTITUDE)) { @@ -1182,6 +1187,7 @@ static void writeInterframe(void) if (testBlackboxCondition(FLIGHT_LOG_FIELD_CONDITION_ACC)) { blackboxWriteArrayUsingAveragePredictor16(offsetof(blackboxMainState_t, accADC), XYZ_AXIS_COUNT); + blackboxWriteSignedVB(blackboxCurrent->accVib - blackboxLast->accVib); } if (testBlackboxCondition(FLIGHT_LOG_FIELD_CONDITION_ATTITUDE)) { @@ -1291,6 +1297,7 @@ static void writeSlowFrame(void) blackboxWriteSignedVB(slowHistory.escTemperature); #endif blackboxWriteUnsignedVB(slowHistory.rxUpdateRate); + blackboxWriteUnsignedVB(slowHistory.activeWpNumber); blackboxSlowFrameIterationTimer = 0; } @@ -1301,10 +1308,16 @@ static void writeSlowFrame(void) static void loadSlowState(blackboxSlowState_t *slow) { memcpy(&slow->flightModeFlags, &rcModeActivationMask, sizeof(slow->flightModeFlags)); //was flightModeFlags; - // Also log Nav auto selected flight modes rather than just those selected by boxmode - if (!IS_RC_MODE_ACTIVE(BOXANGLE) && FLIGHT_MODE(ANGLE_MODE)) { + // Also log Nav auto enabled flight modes rather than just those selected by boxmode + if (FLIGHT_MODE(ANGLE_MODE)) { slow->flightModeFlags |= (1 << BOXANGLE); } + if (FLIGHT_MODE(NAV_ALTHOLD_MODE)) { + slow->flightModeFlags |= (1 << BOXNAVALTHOLD); + } + if (FLIGHT_MODE(NAV_RTH_MODE)) { + slow->flightModeFlags |= (1 << BOXNAVRTH); + } if (navigationGetHeadingControlState() == NAV_HEADING_CONTROL_AUTO) { slow->flightModeFlags |= (1 << BOXHEADINGHOLD); } @@ -1368,6 +1381,7 @@ static void loadSlowState(blackboxSlowState_t *slow) #endif slow->rxUpdateRate = getRcUpdateFrequency(); + slow->activeWpNumber = getActiveWpNumber(); } /** @@ -1601,6 +1615,7 @@ static void loadMainState(timeUs_t currentTimeUs) blackboxCurrent->mcVelAxisOutput[i] = lrintf(nav_pids->vel[i].output_constrained); } } + blackboxCurrent->accVib = lrintf(accGetVibrationLevel() * acc.dev.acc_1G); if (STATE(FIXED_WING_LEGACY)) { diff --git a/src/main/cms/cms.h b/src/main/cms/cms.h index f1f8d8017c8..7084df8b50c 100644 --- a/src/main/cms/cms.h +++ b/src/main/cms/cms.h @@ -37,9 +37,9 @@ void cmsYieldDisplay(displayPort_t *pPort, timeMs_t duration); void cmsUpdate(uint32_t currentTimeUs); void cmsSetExternKey(cms_key_e extKey); -#define CMS_STARTUP_HELP_TEXT1 "MENU: THR MID" -#define CMS_STARTUP_HELP_TEXT2 "+ YAW LEFT" -#define CMS_STARTUP_HELP_TEXT3 "+ PITCH UP" +#define CMS_STARTUP_HELP_TEXT1 "MENU: THR MID" +#define CMS_STARTUP_HELP_TEXT2 "+ YAW LEFT" +#define CMS_STARTUP_HELP_TEXT3 "+ PITCH UP" // cmsMenuExit special ptr values #define CMS_EXIT (0) diff --git a/src/main/common/fp_pid.c b/src/main/common/fp_pid.c index 5edaa193b8c..df8ccaad6b7 100644 --- a/src/main/common/fp_pid.c +++ b/src/main/common/fp_pid.c @@ -92,6 +92,11 @@ float navPidApply3( /* Pre-calculate output and limit it if actuator is saturating */ const float outVal = newProportional + (pid->integrator * gainScaler) + newDerivative + newFeedForward; const float outValConstrained = constrainf(outVal, outMin, outMax); + float backCalc = outValConstrained - outVal;//back-calculation anti-windup + if (SIGN(backCalc) == SIGN(pid->integrator)) { + //back calculation anti-windup can only shrink integrator, will not push it to the opposite direction + backCalc = 0.0f; + } pid->proportional = newProportional; pid->integral = pid->integrator; @@ -104,7 +109,7 @@ float navPidApply3( !(pidFlags & PID_ZERO_INTEGRATOR) && !(pidFlags & PID_FREEZE_INTEGRATOR) ) { - const float newIntegrator = pid->integrator + (error * pid->param.kI * gainScaler * dt) + ((outValConstrained - outVal) * pid->param.kT * dt); + const float newIntegrator = pid->integrator + (error * pid->param.kI * gainScaler * dt) + (backCalc * pid->param.kT * dt); if (pidFlags & PID_SHRINK_INTEGRATOR) { // Only allow integrator to shrink diff --git a/src/main/common/maths.h b/src/main/common/maths.h index cc3d1bc5176..9c7781472d4 100644 --- a/src/main/common/maths.h +++ b/src/main/common/maths.h @@ -25,15 +25,15 @@ #endif // Undefine this for use libc sinf/cosf. Keep this defined to use fast sin/cos approximations -#define FAST_MATH // order 9 approximation -//#define VERY_FAST_MATH // order 7 approximation +#define FAST_MATH // order 9 approximation +//#define VERY_FAST_MATH // order 7 approximation // Use floating point M_PI instead explicitly. -#define M_PIf 3.14159265358979323846f -#define M_LN2f 0.69314718055994530942f -#define M_Ef 2.71828182845904523536f +#define M_PIf 3.14159265358979323846f +#define M_LN2f 0.69314718055994530942f +#define M_Ef 2.71828182845904523536f -#define RAD (M_PIf / 180.0f) +#define RAD (M_PIf / 180.0f) #define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100) #define CENTIDEGREES_TO_DEGREES(angle) ((angle) / 100.0f) @@ -56,46 +56,50 @@ #define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD) #define CENTIDEGREES_TO_RADIANS(angle) (((angle) / 100.0f) * RAD) -#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f) -#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f) -#define CENTIMETERS_TO_METERS(cm) (cm / 100.0f) +#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f) +#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f) +#define CENTIMETERS_TO_METERS(cm) (cm / 100.0f) -#define METERS_TO_CENTIMETERS(m) (m * 100) +#define METERS_TO_CENTIMETERS(m) (m * 100) +#define METERS_TO_KILOMETERS(m) (m / 1000.0f) +#define METERS_TO_MILES(m) (m / 1609.344f) +#define METERS_TO_NAUTICALMILES(m) (m / 1852.00f) -#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f) -#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f) -#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f) +#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f) +#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f) +#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f) #define C_TO_KELVIN(temp) (temp + 273.15f) // Standard Sea Level values // Ref:https://en.wikipedia.org/wiki/Standard_sea_level -#define SSL_AIR_DENSITY 1.225f // kg/m^3 -#define SSL_AIR_PRESSURE 101325.01576f // Pascal -#define SSL_AIR_TEMPERATURE 288.15f // K +#define SSL_AIR_DENSITY 1.225f // kg/m^3 +#define SSL_AIR_PRESSURE 101325.01576f // Pascal +#define SSL_AIR_TEMPERATURE 288.15f // K // copied from https://code.google.com/p/cxutil/source/browse/include/cxutil/utility.h#70 -#define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \ - ( __extension__ ({ \ - __typeof__(lexpr) lvar = (lexpr); \ - __typeof__(rexpr) rvar = (rexpr); \ - lvar binoper rvar ? lvar : rvar; \ - })) +#define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \ + ( __extension__ ({ \ + __typeof__(lexpr) lvar = (lexpr); \ + __typeof__(rexpr) rvar = (rexpr); \ + lvar binoper rvar ? lvar : rvar; \ + })) #define _CHOOSE_VAR2(prefix, unique) prefix##unique #define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique) -#define _CHOOSE(binoper, lexpr, rexpr) \ - _CHOOSE2( \ - binoper, \ - lexpr, _CHOOSE_VAR(_left, __COUNTER__), \ - rexpr, _CHOOSE_VAR(_right, __COUNTER__) \ +#define _CHOOSE(binoper, lexpr, rexpr) \ + _CHOOSE2( \ + binoper, \ + lexpr, _CHOOSE_VAR(_left, __COUNTER__), \ + rexpr, _CHOOSE_VAR(_right, __COUNTER__) \ ) #define MIN(a, b) _CHOOSE(<, a, b) #define MAX(a, b) _CHOOSE(>, a, b) +#define SIGN(a) ((a >= 0) ? 1 : -1) -#define _ABS_II(x, var) \ - ( __extension__ ({ \ - __typeof__(x) var = (x); \ - var < 0 ? -var : var; \ +#define _ABS_II(x, var) \ + ( __extension__ ({ \ + __typeof__(x) var = (x); \ + var < 0 ? -var : var; \ })) #define _ABS_I(x, var) _ABS_II(x, var) #define ABS(x) _ABS_I(x, _CHOOSE_VAR(_abs, __COUNTER__)) @@ -114,8 +118,7 @@ typedef union { fp_angles_def angles; } fp_angles_t; -typedef struct stdev_s -{ +typedef struct stdev_s { float m_oldM, m_newM, m_oldS, m_newS; int m_n; } stdev_t; diff --git a/src/main/config/parameter_group_ids.h b/src/main/config/parameter_group_ids.h index 16423639fb8..822e85f137a 100644 --- a/src/main/config/parameter_group_ids.h +++ b/src/main/config/parameter_group_ids.h @@ -120,7 +120,13 @@ #define PG_POWER_LIMITS_CONFIG 1030 #define PG_OSD_COMMON_CONFIG 1031 #define PG_TIMER_OVERRIDE_CONFIG 1032 -#define PG_INAV_END 1032 +#define PG_EZ_TUNE 1033 +#define PG_LEDPIN_CONFIG 1034 +#define PG_OSD_JOYSTICK_CONFIG 1035 +#define PG_FW_AUTOLAND_CONFIG 1036 +#define PG_FW_AUTOLAND_APPROACH_CONFIG 1037 +#define PG_OSD_CUSTOM_ELEMENTS_CONFIG 1038 +#define PG_INAV_END PG_OSD_CUSTOM_ELEMENTS_CONFIG // OSD configuration (subject to change) //#define PG_OSD_FONT_CONFIG 2047 diff --git a/src/main/drivers/accgyro/accgyro_bmi160.c b/src/main/drivers/accgyro/accgyro_bmi160.c index 62fe2f35383..cadaeb22da5 100644 --- a/src/main/drivers/accgyro/accgyro_bmi160.c +++ b/src/main/drivers/accgyro/accgyro_bmi160.c @@ -195,9 +195,9 @@ bool bmi160AccReadScratchpad(accDev_t *acc) bmi160ContextData_t * ctx = busDeviceGetScratchpadMemory(acc->busDev); if (ctx->lastReadStatus) { - acc->ADCRaw[X] = (float) int16_val_little_endian(ctx->gyroRaw, 0); - acc->ADCRaw[Y] = (float) int16_val_little_endian(ctx->gyroRaw, 1); - acc->ADCRaw[Z] = (float) int16_val_little_endian(ctx->gyroRaw, 2); + acc->ADCRaw[X] = (float) int16_val_little_endian(ctx->accRaw, 0); + acc->ADCRaw[Y] = (float) int16_val_little_endian(ctx->accRaw, 1); + acc->ADCRaw[Z] = (float) int16_val_little_endian(ctx->accRaw, 2); return true; } diff --git a/src/main/drivers/accgyro/accgyro_bmi270.c b/src/main/drivers/accgyro/accgyro_bmi270.c index 0b37518a3cf..3e1db222536 100644 --- a/src/main/drivers/accgyro/accgyro_bmi270.c +++ b/src/main/drivers/accgyro/accgyro_bmi270.c @@ -214,7 +214,7 @@ static void bmi270AccAndGyroInit(gyroDev_t *gyro) delay(1); // Configure the accelerometer full-scale range - busWrite(busDev, BMI270_REG_ACC_RANGE, BMI270_ACC_RANGE_8G); + busWrite(busDev, BMI270_REG_ACC_RANGE, BMI270_ACC_RANGE_16G); delay(1); // Configure the gyro @@ -301,7 +301,7 @@ static void bmi270GyroInit(gyroDev_t *gyro) static void bmi270AccInit(accDev_t *acc) { // sensor is configured during gyro init - acc->acc_1G = 4096; // 8G sensor scale + acc->acc_1G = 2048; // 16G sensor scale } bool bmi270AccDetect(accDev_t *acc) diff --git a/src/main/drivers/accgyro/accgyro_icm42605.c b/src/main/drivers/accgyro/accgyro_icm42605.c index 5f536527c7f..082b31540eb 100644 --- a/src/main/drivers/accgyro/accgyro_icm42605.c +++ b/src/main/drivers/accgyro/accgyro_icm42605.c @@ -26,6 +26,7 @@ #include "common/axis.h" #include "common/maths.h" #include "common/utils.h" +#include "common/log.h" #include "drivers/system.h" #include "drivers/time.h" @@ -44,13 +45,20 @@ #define ICM42605_PWR_MGMT0_TEMP_DISABLE_OFF (0 << 5) #define ICM42605_PWR_MGMT0_TEMP_DISABLE_ON (1 << 5) +#define ICM426XX_RA_REG_BANK_SEL 0x76 +#define ICM426XX_BANK_SELECT0 0x00 +#define ICM426XX_BANK_SELECT1 0x01 +#define ICM426XX_BANK_SELECT2 0x02 +#define ICM426XX_BANK_SELECT3 0x03 +#define ICM426XX_BANK_SELECT4 0x04 + #define ICM42605_RA_GYRO_CONFIG0 0x4F #define ICM42605_RA_ACCEL_CONFIG0 0x50 #define ICM42605_RA_GYRO_ACCEL_CONFIG0 0x52 -#define ICM42605_ACCEL_UI_FILT_BW_LOW_LATENCY (14 << 4) -#define ICM42605_GYRO_UI_FILT_BW_LOW_LATENCY (14 << 0) +#define ICM42605_ACCEL_UI_FILT_BW_LOW_LATENCY (15 << 4) +#define ICM42605_GYRO_UI_FILT_BW_LOW_LATENCY (15 << 0) #define ICM42605_RA_GYRO_DATA_X1 0x25 #define ICM42605_RA_ACCEL_DATA_X1 0x1F @@ -78,11 +86,70 @@ #define ICM42605_INT_TPULSE_DURATION_100 (0 << ICM42605_INT_TPULSE_DURATION_BIT) #define ICM42605_INT_TPULSE_DURATION_8 (1 << ICM42605_INT_TPULSE_DURATION_BIT) - #define ICM42605_RA_INT_SOURCE0 0x65 #define ICM42605_UI_DRDY_INT1_EN_DISABLED (0 << 3) #define ICM42605_UI_DRDY_INT1_EN_ENABLED (1 << 3) +#define ICM42605_INTF_CONFIG1 0x4D +#define ICM42605_INTF_CONFIG1_AFSR_MASK 0xC0 +#define ICM42605_INTF_CONFIG1_AFSR_DISABLE 0x40 + +// --- Registers for gyro and acc Anti-Alias Filter --------- +#define ICM426XX_RA_GYRO_CONFIG_STATIC3 0x0C // User Bank 1 +#define ICM426XX_RA_GYRO_CONFIG_STATIC4 0x0D // User Bank 1 +#define ICM426XX_RA_GYRO_CONFIG_STATIC5 0x0E // User Bank 1 +#define ICM426XX_RA_ACCEL_CONFIG_STATIC2 0x03 // User Bank 2 +#define ICM426XX_RA_ACCEL_CONFIG_STATIC3 0x04 // User Bank 2 +#define ICM426XX_RA_ACCEL_CONFIG_STATIC4 0x05 // User Bank 2 + +static bool is42688P = false; + +typedef struct aafConfig_s { + uint16_t freq; + uint8_t delt; + uint16_t deltSqr; + uint8_t bitshift; +} aafConfig_t; + +// Possible gyro Anti-Alias Filter (AAF) cutoffs for ICM-42688P +static aafConfig_t aafLUT42688[] = { // see table in section 5.3 https://invensense.tdk.com/wp-content/uploads/2020/04/ds-000347_icm-42688-p-datasheet.pdf + // freq, delt, deltSqr, bitshift + { 42, 1, 1, 15 }, + { 84, 2, 4, 13 }, + {126, 3, 9, 12 }, + {170, 4, 16, 11 }, + {213, 5, 25, 10 }, + {258, 6, 36, 10 }, + {303, 7, 49, 9 }, + {536, 12, 144, 8 }, + {997, 21, 440, 6 }, + {1962, 37, 1376, 4 }, + { 0, 0, 0, 0}, // 42HZ +}; + +// Possible gyro Anti-Alias Filter (AAF) cutoffs for ICM-42688P +static aafConfig_t aafLUT42605[] = { // see table in section 5.3 https://invensense.tdk.com/wp-content/uploads/2022/09/DS-000292-ICM-42605-v1.7.pdf + // freq, delt, deltSqr, bitshift + { 10, 1, 1, 15 }, + { 21, 2, 4, 13 }, + { 32, 3, 9, 12 }, + { 42, 4, 16, 11 }, + { 99, 9, 81, 9 }, + { 171, 15, 224, 7 }, + { 184, 16, 256, 7 }, + { 196, 17, 288, 7 }, + { 249, 21, 440, 6 }, + { 524, 39, 1536, 4 }, + { 995, 63, 3968, 3 }, + { 0, 0, 0, 0 } +}; + +static const aafConfig_t *getGyroAafConfig(bool is42688, const uint16_t desiredLpf); + +static void setUserBank(const busDevice_t *dev, const uint8_t user_bank) +{ + busWrite(dev, ICM426XX_RA_REG_BANK_SEL, user_bank & 7); +} static void icm42605AccInit(accDev_t *acc) { @@ -157,6 +224,7 @@ static void icm42605AccAndGyroInit(gyroDev_t *gyro) busSetSpeed(dev, BUS_SPEED_INITIALIZATION); + setUserBank(dev, ICM426XX_BANK_SELECT0); busWrite(dev, ICM42605_RA_PWR_MGMT0, ICM42605_PWR_MGMT0_TEMP_DISABLE_OFF | ICM42605_PWR_MGMT0_ACCEL_MODE_LN | ICM42605_PWR_MGMT0_GYRO_MODE_LN); delay(15); @@ -168,9 +236,27 @@ static void icm42605AccAndGyroInit(gyroDev_t *gyro) delay(15); /* LPF bandwidth */ - busWrite(dev, ICM42605_RA_GYRO_ACCEL_CONFIG0, (config->gyroConfigValues[1]) | (config->gyroConfigValues[1] << 4)); + // low latency, same as BF + busWrite(dev, ICM42605_RA_GYRO_ACCEL_CONFIG0, ICM42605_ACCEL_UI_FILT_BW_LOW_LATENCY | ICM42605_GYRO_UI_FILT_BW_LOW_LATENCY); delay(15); + if (gyro->lpf != GYRO_LPF_NONE) { + // Configure gyro Anti-Alias Filter (see section 5.3 "ANTI-ALIAS FILTER") + const aafConfig_t *aafConfig = getGyroAafConfig(is42688P, gyro->lpf); + + setUserBank(dev, ICM426XX_BANK_SELECT1); + busWrite(dev, ICM426XX_RA_GYRO_CONFIG_STATIC3, aafConfig->delt); + busWrite(dev, ICM426XX_RA_GYRO_CONFIG_STATIC4, aafConfig->deltSqr & 0xFF); + busWrite(dev, ICM426XX_RA_GYRO_CONFIG_STATIC5, (aafConfig->deltSqr >> 8) | (aafConfig->bitshift << 4)); + + aafConfig = getGyroAafConfig(is42688P, 256); // This was hard coded on BF + setUserBank(dev, ICM426XX_BANK_SELECT2); + busWrite(dev, ICM426XX_RA_ACCEL_CONFIG_STATIC2, aafConfig->delt << 1); + busWrite(dev, ICM426XX_RA_ACCEL_CONFIG_STATIC3, aafConfig->deltSqr & 0xFF); + busWrite(dev, ICM426XX_RA_ACCEL_CONFIG_STATIC4, (aafConfig->deltSqr >> 8) | (aafConfig->bitshift << 4)); + } + + setUserBank(dev, ICM426XX_BANK_SELECT0); busWrite(dev, ICM42605_RA_INT_CONFIG, ICM42605_INT1_MODE_PULSED | ICM42605_INT1_DRIVE_CIRCUIT_PP | ICM42605_INT1_POLARITY_ACTIVE_HIGH); delay(15); @@ -190,6 +276,15 @@ static void icm42605AccAndGyroInit(gyroDev_t *gyro) busWrite(dev, ICM42605_RA_INT_CONFIG1, intConfig1Value); delay(15); + //Disable AFSR as in BF and Ardupilot + uint8_t intfConfig1Value; + busRead(dev, ICM42605_INTF_CONFIG1, &intfConfig1Value); + intfConfig1Value &= ~ICM42605_INTF_CONFIG1_AFSR_MASK; + intfConfig1Value |= ICM42605_INTF_CONFIG1_AFSR_DISABLE; + busWrite(dev, ICM42605_INTF_CONFIG1, intfConfig1Value); + + delay(15); + busSetSpeed(dev, BUS_SPEED_FAST); } @@ -210,7 +305,10 @@ static bool icm42605DeviceDetect(busDevice_t * dev) switch (tmp) { /* ICM42605 and ICM42688P share the register structure*/ case ICM42605_WHO_AM_I_CONST: + is42688P = false; + return true; case ICM42688P_WHO_AM_I_CONST: + is42688P = true; return true; default: @@ -264,4 +362,57 @@ bool icm42605GyroDetect(gyroDev_t *gyro) return true; } +static uint16_t getAafFreq(const uint8_t gyroLpf) +{ + switch (gyroLpf) { + default: + case GYRO_LPF_256HZ: + return 256; + case GYRO_LPF_188HZ: + return 188; + case GYRO_LPF_98HZ: + return 98; + case GYRO_LPF_42HZ: + return 42; + case GYRO_LPF_20HZ: + return 20; + case GYRO_LPF_10HZ: + return 10; + case GYRO_LPF_5HZ: + return 5; + case GYRO_LPF_NONE: + return 0; + } +} + +static const aafConfig_t *getGyroAafConfig(bool is42688, const uint16_t desiredLpf) +{ + uint16_t desiredFreq = getAafFreq(desiredLpf); + const aafConfig_t *aafConfigs = NULL; + if (is42688) { + aafConfigs = aafLUT42688; + } else { + aafConfigs = aafLUT42605; + } + int i; + int8_t selectedFreq = aafConfigs[0].freq; + const aafConfig_t * candidate = &aafConfigs[0]; + + // Choose closest supported LPF value + for (i = 1; aafConfigs[i].freq != 0; i++) { + if (ABS(desiredFreq - aafConfigs[i].freq) < ABS(desiredFreq - selectedFreq)) { + selectedFreq = aafConfigs[i].freq; + candidate = &aafConfigs[i]; + } + } + + LOG_VERBOSE(GYRO, "ICM426%s AAF CONFIG { %d, %d } -> { %d }; delt: %d deltSqr: %d, shift: %d", + (is42688P ? "88" : "05"), + desiredLpf, desiredFreq, + candidate->freq, + candidate->delt, candidate->deltSqr, candidate->bitshift); + + return candidate; +} + #endif diff --git a/src/main/drivers/adc_at32f43x.c b/src/main/drivers/adc_at32f43x.c index 1975a96e7b0..e2ed2f57b15 100644 --- a/src/main/drivers/adc_at32f43x.c +++ b/src/main/drivers/adc_at32f43x.c @@ -179,11 +179,11 @@ void adcHardwareInit(drv_adc_config_t *init) adcDevice_t * adc = &adcHardware[adcConfig[i].adcDevice]; // init adc gpio port IOInit(IOGetByTag(adcConfig[i].tag), OWNER_ADC, RESOURCE_ADC_CH1 + (i - ADC_CHN_1), 0); - IOConfigGPIO(IOGetByTag(adcConfig[i].tag), IO_CONFIG(GPIO_MODE_ANALOG, 0, GPIO_OUTPUT_OPEN_DRAIN, GPIO_PULL_NONE)); + IOConfigGPIO(IOGetByTag(adcConfig[i].tag), IO_CONFIG(GPIO_MODE_ANALOG, 0, 0, 0)); adcConfig[i].adcChannel = adcChannelByTag(adcConfig[i].tag); adcConfig[i].dmaIndex = adc->usedChannelCount++; - adcConfig[i].sampleTime = ADC_SAMPLETIME_6_5; + adcConfig[i].sampleTime = ADC_SAMPLETIME_640_5; adcConfig[i].enabled = true; adc->enabled = true; diff --git a/src/main/drivers/bus_i2c_at32f43x.c b/src/main/drivers/bus_i2c_at32f43x.c index 97036b6186c..98fdd942468 100644 --- a/src/main/drivers/bus_i2c_at32f43x.c +++ b/src/main/drivers/bus_i2c_at32f43x.c @@ -70,7 +70,7 @@ static void i2cUnstick(IO_t scl, IO_t sda); //Define thi I2C hardware map static i2cDevice_t i2cHardwareMap[I2CDEV_COUNT] = { - { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .speed = I2C_SPEED_400KHZ, .ev_irq = I2C1_EVT_IRQn, .er_irq = I2C1_ERR_IRQn, .af = GPIO_MUX_8 }, + { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .speed = I2C_SPEED_400KHZ, .ev_irq = I2C1_EVT_IRQn, .er_irq = I2C1_ERR_IRQn, .af = GPIO_MUX_4 }, { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .speed = I2C_SPEED_400KHZ, .ev_irq = I2C2_EVT_IRQn, .er_irq = I2C2_ERR_IRQn, .af = GPIO_MUX_4 }, { .dev = I2C3, .scl = IO_TAG(I2C3_SCL), .sda = IO_TAG(I2C3_SDA), .rcc = RCC_APB1(I2C3), .speed = I2C_SPEED_400KHZ, .ev_irq = I2C3_EVT_IRQn, .er_irq = I2C3_ERR_IRQn, .af = GPIO_MUX_4 }, }; diff --git a/src/main/drivers/bus_spi.h b/src/main/drivers/bus_spi.h index e55119564c2..88bbbf286d3 100644 --- a/src/main/drivers/bus_spi.h +++ b/src/main/drivers/bus_spi.h @@ -78,7 +78,7 @@ typedef struct SPIDevice_s { ioTag_t mosi; ioTag_t miso; rccPeriphTag_t rcc; -#if defined(STM32F7) || defined(STM32H7) +#if defined(STM32F7) || defined(STM32H7) || defined(AT32F43x) uint8_t sckAF; uint8_t misoAF; uint8_t mosiAF; diff --git a/src/main/drivers/bus_spi_at32f43x.c b/src/main/drivers/bus_spi_at32f43x.c index 22231f55ae8..6a30f0d0d03 100644 --- a/src/main/drivers/bus_spi_at32f43x.c +++ b/src/main/drivers/bus_spi_at32f43x.c @@ -80,25 +80,61 @@ }; #endif - static spiDevice_t spiHardwareMap[] = { - #ifdef USE_SPI_DEVICE_1 - { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_MUX_5, .divisorMap = spiDivisorMapFast }, - #else - { .dev = NULL }, // No SPI1 - #endif - #ifdef USE_SPI_DEVICE_2 - { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_MUX_5, .divisorMap = spiDivisorMapSlow }, - #else - { .dev = NULL }, // No SPI2 - #endif - #ifdef USE_SPI_DEVICE_3 - { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_MUX_6, .divisorMap = spiDivisorMapSlow }, - #else - { .dev = NULL }, // No SPI3 - #endif - { .dev = NULL }, // No SPI4 - }; +//MAP spi pin config and af +static spiDevice_t spiHardwareMap[] = { +#ifdef USE_SPI_DEVICE_1 +#if defined(SPI1_SCK_AF) || defined(SPI1_MISO_AF) || defined(SPI1_MOSI_AF) +#if !defined(SPI1_SCK_AF) || !defined(SPI1_MISO_AF) || !defined(SPI1_MOSI_AF) +#error SPI1: SCK, MISO and MOSI AFs should be defined together in target.h! +#endif + { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = SPI1_SCK_AF, .misoAF = SPI1_MISO_AF, .mosiAF = SPI1_MOSI_AF, .divisorMap = spiDivisorMapFast }, +#else + { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = GPIO_MUX_5, .misoAF = GPIO_MUX_5, .mosiAF = GPIO_MUX_5, .divisorMap = spiDivisorMapFast }, +#endif +#else + { .dev = NULL }, // No SPI1 +#endif + +#ifdef USE_SPI_DEVICE_2 +#if defined(SPI2_SCK_AF) || defined(SPI2_MISO_AF) || defined(SPI2_MOSI_AF) +#if !defined(SPI2_SCK_AF) || !defined(SPI2_MISO_AF) || !defined(SPI2_MOSI_AF) +#error SPI2: SCK, MISO and MOSI AFs should be defined together in target.h! +#endif + { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .sckAF = SPI2_SCK_AF, .misoAF = SPI2_MISO_AF, .mosiAF = SPI2_MOSI_AF, .divisorMap = spiDivisorMapSlow }, +#else + { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .sckAF = GPIO_MUX_5, .misoAF = GPIO_MUX_5, .mosiAF = GPIO_MUX_5, .divisorMap = spiDivisorMapSlow }, +#endif #else + { .dev = NULL }, // No SPI2 +#endif + +#ifdef USE_SPI_DEVICE_3 +#if defined(SPI3_SCK_AF) || defined(SPI3_MISO_AF) || defined(SPI3_MOSI_AF) +#if !defined(SPI3_SCK_AF) || !defined(SPI3_MISO_AF) || !defined(SPI3_MOSI_AF) +#error SPI3: SCK, MISO and MOSI AFs should be defined together in target.h! +#endif + { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .sckAF = SPI3_SCK_AF, .misoAF = SPI3_MISO_AF, .mosiAF = SPI3_MOSI_AF, .divisorMap = spiDivisorMapSlow }, +#else + { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .sckAF = GPIO_MUX_6, .misoAF = GPIO_MUX_6, .mosiAF = GPIO_MUX_6, .divisorMap = spiDivisorMapSlow }, +#endif +#else + { .dev = NULL }, // No SPI3 +#endif + +#ifdef USE_SPI_DEVICE_4 +#if defined(SPI4_SCK_AF) || defined(SPI4_MISO_AF) || defined(SPI4_MOSI_AF) +#if !defined(SPI4_SCK_AF) || !defined(SPI4_MISO_AF) || !defined(SPI4_MOSI_AF) +#error SPI4: SCK, MISO and MOSI AFs should be defined together in target.h! +#endif + { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = SPI4_SCK_AF, .misoAF = SPI4_MISO_AF, .mosiAF = SPI4_MOSI_AF, .divisorMap = spiDivisorMapSlow } +#else + { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = GPIO_MUX_6, .misoAF = GPIO_MUX_6, .mosiAF = GPIO_MUX_6, .divisorMap = spiDivisorMapSlow } +#endif +#else + { .dev = NULL } // No SPI4 +#endif +}; + #else #error "Invalid CPU" #endif @@ -135,12 +171,13 @@ bool spiInitDevice(SPIDevice device, bool leadingEdge) IOInit(IOGetByTag(spi->miso), OWNER_SPI, RESOURCE_SPI_MISO, device + 1); IOInit(IOGetByTag(spi->mosi), OWNER_SPI, RESOURCE_SPI_MOSI, device + 1); - IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG, spi->af); - IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->af); - IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af); + IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG, spi->sckAF); + IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->misoAF); + IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->mosiAF); if (spi->nss) { - IOConfigGPIOAF(IOGetByTag(spi->nss), SPI_IO_CS_CFG, spi->af); + IOInit(IOGetByTag(spi->nss), OWNER_SPI, RESOURCE_SPI_CS, device + 1); + IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG); } spi_i2s_reset(spi->dev); diff --git a/src/main/drivers/compass/compass_fake.c b/src/main/drivers/compass/compass_fake.c index a95b3297a5f..2ef8692fd2d 100644 --- a/src/main/drivers/compass/compass_fake.c +++ b/src/main/drivers/compass/compass_fake.c @@ -37,7 +37,7 @@ static bool fakeMagInit(magDev_t *magDev) { UNUSED(magDev); // initially point north - fakeMagData[X] = 4096; + fakeMagData[X] = 1024; fakeMagData[Y] = 0; fakeMagData[Z] = 0; return true; diff --git a/src/main/drivers/display.c b/src/main/drivers/display.c index 55e15ff0435..228a735c8c4 100644 --- a/src/main/drivers/display.c +++ b/src/main/drivers/display.c @@ -33,8 +33,6 @@ #include "fc/settings.h" #include "fc/runtime_config.h" -#define SW_BLINK_CYCLE_MS 200 // 200ms on / 200ms off - // XXX: This is the number of characters in a MAX7456 line. // Increment this number appropiately or enable support for // multiple iterations in displayWriteWithAttr() if bigger @@ -66,7 +64,7 @@ static bool displayEmulateTextAttributes(displayPort_t *instance, // We only emulate blink for now, so there's no need to test // for it again. TEXT_ATTRIBUTES_REMOVE_BLINK(*attr); - if ((millis() / SW_BLINK_CYCLE_MS) % 2) { + if (getBlinkOnOff()) { memset(buf, ' ', length); buf[length] = '\0'; // Tell the caller to use buf diff --git a/src/main/drivers/display.h b/src/main/drivers/display.h index add2e8244f5..e23e18fb8bc 100644 --- a/src/main/drivers/display.h +++ b/src/main/drivers/display.h @@ -20,8 +20,14 @@ #include #include +#include "drivers/time.h" + #include "config/parameter_group.h" +#define SW_BLINK_CYCLE_MS 500 // Xms on / Xms off + +#define getBlinkOnOff() ( (millis() / SW_BLINK_CYCLE_MS) & 1 ) + typedef struct osdCharacter_s osdCharacter_t; typedef struct displayConfig_s { diff --git a/src/main/drivers/light_ws2811strip.c b/src/main/drivers/light_ws2811strip.c index 718c96ca8a9..cb56a7fe79a 100644 --- a/src/main/drivers/light_ws2811strip.c +++ b/src/main/drivers/light_ws2811strip.c @@ -43,15 +43,26 @@ #include "drivers/timer.h" #include "drivers/light_ws2811strip.h" +#include "config/parameter_group_ids.h" +#include "fc/settings.h" +#include "fc/runtime_config.h" + #define WS2811_PERIOD (WS2811_TIMER_HZ / WS2811_CARRIER_HZ) #define WS2811_BIT_COMPARE_1 ((WS2811_PERIOD * 2) / 3) #define WS2811_BIT_COMPARE_0 (WS2811_PERIOD / 3) +PG_REGISTER_WITH_RESET_TEMPLATE(ledPinConfig_t, ledPinConfig, PG_LEDPIN_CONFIG, 0); + +PG_RESET_TEMPLATE(ledPinConfig_t, ledPinConfig, + .led_pin_pwm_mode = SETTING_LED_PIN_PWM_MODE_DEFAULT +); + static DMA_RAM timerDMASafeType_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE]; static IO_t ws2811IO = IO_NONE; static TCH_t * ws2811TCH = NULL; static bool ws2811Initialised = false; +static bool pwmMode = false; static hsvColor_t ledColorBuffer[WS2811_LED_STRIP_LENGTH]; @@ -91,6 +102,24 @@ void setStripColors(const hsvColor_t *colors) } } +bool ledConfigureDMA(void) { + /* Compute the prescaler value */ + uint8_t period = WS2811_TIMER_HZ / WS2811_CARRIER_HZ; + + timerConfigBase(ws2811TCH, period, WS2811_TIMER_HZ); + timerPWMConfigChannel(ws2811TCH, 0); + + return timerPWMConfigChannelDMA(ws2811TCH, ledStripDMABuffer, sizeof(ledStripDMABuffer[0]), WS2811_DMA_BUFFER_SIZE); +} + +void ledConfigurePWM(void) { + timerConfigBase(ws2811TCH, 100, WS2811_TIMER_HZ ); + timerPWMConfigChannel(ws2811TCH, 0); + timerPWMStart(ws2811TCH); + timerEnable(ws2811TCH); + pwmMode = true; +} + void ws2811LedStripInit(void) { const timerHardware_t * timHw = timerGetByTag(IO_TAG(WS2811_PIN), TIM_USE_ANY); @@ -104,27 +133,32 @@ void ws2811LedStripInit(void) return; } - /* Compute the prescaler value */ - uint8_t period = WS2811_TIMER_HZ / WS2811_CARRIER_HZ; - ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN)); IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0); IOConfigGPIOAF(ws2811IO, IOCFG_AF_PP_FAST, timHw->alternateFunction); - timerConfigBase(ws2811TCH, period, WS2811_TIMER_HZ); - timerPWMConfigChannel(ws2811TCH, 0); - - // If DMA failed - abort - if (!timerPWMConfigChannelDMA(ws2811TCH, ledStripDMABuffer, sizeof(ledStripDMABuffer[0]), WS2811_DMA_BUFFER_SIZE)) { - ws2811Initialised = false; - return; + if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_LOW ) { + ledConfigurePWM(); + *timerCCR(ws2811TCH) = 0; + } else if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_HIGH ) { + ledConfigurePWM(); + *timerCCR(ws2811TCH) = 100; + } else { + if (!ledConfigureDMA()) { + // If DMA failed - abort + ws2811Initialised = false; + return; + } + + // Zero out DMA buffer + memset(&ledStripDMABuffer, 0, sizeof(ledStripDMABuffer)); + if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_SHARED_HIGH ) { + ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE-1] = 255; + } + ws2811Initialised = true; + + ws2811UpdateStrip(); } - - // Zero out DMA buffer - memset(&ledStripDMABuffer, 0, sizeof(ledStripDMABuffer)); - ws2811Initialised = true; - - ws2811UpdateStrip(); } bool isWS2811LedStripReady(void) @@ -140,7 +174,7 @@ STATIC_UNIT_TESTED void fastUpdateLEDDMABuffer(rgbColor24bpp_t *color) uint32_t grb = (color->rgb.g << 16) | (color->rgb.r << 8) | (color->rgb.b); for (int8_t index = 23; index >= 0; index--) { - ledStripDMABuffer[dmaBufferOffset++] = (grb & (1 << index)) ? WS2811_BIT_COMPARE_1 : WS2811_BIT_COMPARE_0; + ledStripDMABuffer[WS2811_DELAY_BUFFER_LENGTH + dmaBufferOffset++] = (grb & (1 << index)) ? WS2811_BIT_COMPARE_1 : WS2811_BIT_COMPARE_0; } } @@ -153,7 +187,7 @@ void ws2811UpdateStrip(void) static rgbColor24bpp_t *rgb24; // don't wait - risk of infinite block, just get an update next time round - if (timerPWMDMAInProgress(ws2811TCH)) { + if (pwmMode || timerPWMDMAInProgress(ws2811TCH)) { return; } @@ -178,4 +212,40 @@ void ws2811UpdateStrip(void) timerPWMStartDMA(ws2811TCH); } +//value +void ledPinStartPWM(uint16_t value) { + if (ws2811TCH == NULL) { + return; + } + + if ( !pwmMode ) { + timerPWMStopDMA(ws2811TCH); + //FIXME: implement method to release DMA + ws2811TCH->dma->owner = OWNER_FREE; + + ledConfigurePWM(); + } + *timerCCR(ws2811TCH) = value; +} + +void ledPinStopPWM(void) { + if (ws2811TCH == NULL || !pwmMode ) { + return; + } + + if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_HIGH ) { + *timerCCR(ws2811TCH) = 100; + return; + } else if ( ledPinConfig()->led_pin_pwm_mode == LED_PIN_PWM_MODE_LOW ) { + *timerCCR(ws2811TCH) = 0; + return; + } + pwmMode = false; + + if (!ledConfigureDMA()) { + ws2811Initialised = false; + } +} + + #endif diff --git a/src/main/drivers/light_ws2811strip.h b/src/main/drivers/light_ws2811strip.h index d70a255d88a..94c36445ec7 100644 --- a/src/main/drivers/light_ws2811strip.h +++ b/src/main/drivers/light_ws2811strip.h @@ -17,23 +17,41 @@ #pragma once #include "common/color.h" +#include "config/parameter_group.h" -#define WS2811_LED_STRIP_LENGTH 32 +#define WS2811_LED_STRIP_LENGTH 128 #define WS2811_BITS_PER_LED 24 -#define WS2811_DELAY_BUFFER_LENGTH 42 // for 50us delay +#define WS2811_DELAY_BUFFER_LENGTH 42 // for 50us delay #define WS2811_DATA_BUFFER_SIZE (WS2811_BITS_PER_LED * WS2811_LED_STRIP_LENGTH) -#define WS2811_DMA_BUFFER_SIZE (WS2811_DATA_BUFFER_SIZE + WS2811_DELAY_BUFFER_LENGTH) // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes) +#define WS2811_DMA_BUFFER_SIZE (WS2811_DELAY_BUFFER_LENGTH + WS2811_DATA_BUFFER_SIZE + 1) // leading bytes (reset low 302us) + data bytes LEDS*3 + 1 byte(keep line high optionally) #define WS2811_TIMER_HZ 2400000 #define WS2811_CARRIER_HZ 800000 +typedef enum { + LED_PIN_PWM_MODE_SHARED_LOW = 0, + LED_PIN_PWM_MODE_SHARED_HIGH = 1, + LED_PIN_PWM_MODE_LOW = 2, + LED_PIN_PWM_MODE_HIGH = 3 +} led_pin_pwm_mode_e; + +typedef struct ledPinConfig_s { + uint8_t led_pin_pwm_mode; //led_pin_pwm_mode_e +} ledPinConfig_t; + +PG_DECLARE(ledPinConfig_t, ledPinConfig); + void ws2811LedStripInit(void); void ws2811LedStripHardwareInit(void); void ws2811LedStripDMAEnable(void); bool ws2811LedStripDMAInProgress(void); +//value 0...100 +void ledPinStartPWM(uint16_t value); +void ledPinStopPWM(void); + void ws2811UpdateStrip(void); void setLedHsv(uint16_t index, const hsvColor_t *color); diff --git a/src/main/drivers/osd_symbols.h b/src/main/drivers/osd_symbols.h index 147725ab463..d645184e5b4 100644 --- a/src/main/drivers/osd_symbols.h +++ b/src/main/drivers/osd_symbols.h @@ -58,7 +58,7 @@ // 0x26 // 038 ASCII & #define SYM_VTX_POWER 0x27 // 039 VTx Power // 0x28 // 040 to 062 ASCII -#define SYM_AH_NM 0x3F // 063 Ah/NM +#define SYM_AH_NM 0x3F // 063 Ah/NM // 0x40 // 064 to 095 ASCII #define SYM_MAH_NM_0 0x60 // 096 mAh/NM left #define SYM_MAH_NM_1 0x61 // 097 mAh/NM right @@ -78,7 +78,7 @@ #define SYM_WH 0x6D // 109 WH #define SYM_WH_KM 0x6E // 110 WH/KM #define SYM_WH_MI 0x6F // 111 WH/MI -#define SYM_WH_NM 0x70 // 112 Wh/NM +#define SYM_WH_NM 0x70 // 112 Wh/NM #define SYM_WATT 0x71 // 113 WATTS #define SYM_MW 0x72 // 114 mW #define SYM_KILOWATT 0x73 // 115 kW @@ -159,6 +159,7 @@ #define SYM_HEADING_W 0xCB // 203 Heading Graphic west #define SYM_HEADING_DIVIDED_LINE 0xCC // 204 Heading Graphic #define SYM_HEADING_LINE 0xCD // 205 Heading Graphic + #define SYM_MAX 0xCE // 206 MAX symbol #define SYM_PROFILE 0xCF // 207 Profile symbol #define SYM_SWITCH_INDICATOR_LOW 0xD0 // 208 Switch High @@ -175,10 +176,10 @@ #define SYM_FLIGHT_HOURS_REMAINING 0xDB // 219 Flight time (hours) remaining #define SYM_GROUND_COURSE 0xDC // 220 Ground course #define SYM_ALERT 0xDD // 221 General alert symbol - #define SYM_TERRAIN_FOLLOWING 0xFB // 251 Terrain following (also Alt adjust) #define SYM_CROSS_TRACK_ERROR 0xFC // 252 Cross track error + #define SYM_LOGO_START 0x101 // 257 to 297, INAV logo #define SYM_LOGO_WIDTH 10 #define SYM_LOGO_HEIGHT 4 @@ -225,9 +226,10 @@ #define SYM_HUD_SIGNAL_3 0x163 // 355 Hud signal icon 75% #define SYM_HUD_SIGNAL_4 0x164 // 356 Hud signal icon 100% -#define SYM_HOME_DIST 0x165 // 357 DIST +#define SYM_HOME_DIST 0x165 // 357 DIST #define SYM_AH_CH_CENTER 0x166 // 358 Crossair center #define SYM_FLIGHT_DIST_REMAINING 0x167 // 359 Flight distance reminaing +#define SYM_ODOMETER 0x168 // 360 Odometer #define SYM_AH_CH_TYPE3 0x190 // 400 to 402, crosshair 3 #define SYM_AH_CH_TYPE4 0x193 // 403 to 405, crosshair 4 @@ -261,8 +263,13 @@ #define SYM_SERVO_PAN_IS_OFFSET_L 0x1C7 // 455 Pan servo is offset left #define SYM_SERVO_PAN_IS_OFFSET_R 0x1C8 // 456 Pan servo is offset right +#define SYM_PILOT_LOGO_SML_L 0x1D5 // 469 small Pilot logo Left +#define SYM_PILOT_LOGO_SML_C 0x1D6 // 470 small Pilot logo Centre +#define SYM_PILOT_LOGO_SML_R 0x1D7 // 471 small Pilot logo Right +#define SYM_PILOT_LOGO_LRG_START 0x1D8 // 472 to 511, Pilot logo + #else -#define TEMP_SENSOR_SYM_COUNT 0 +#define TEMP_SENSOR_SYM_COUNT 0 #endif // USE_OSD diff --git a/src/main/drivers/serial_tcp.c b/src/main/drivers/serial_tcp.c index 1e2c78f1974..48522508ce8 100644 --- a/src/main/drivers/serial_tcp.c +++ b/src/main/drivers/serial_tcp.c @@ -265,13 +265,8 @@ uint32_t tcpTotalRxBytesWaiting(const serialPort_t *instance) uint32_t tcpTotalTxBytesFree(const serialPort_t *instance) { - tcpPort_t *port = (tcpPort_t*)instance; - - if (port->isClientConnected) { - return TCP_MAX_PACKET_SIZE; - } else { - return 0; - } + UNUSED(instance); + return TCP_MAX_PACKET_SIZE; } bool isTcpTransmitBufferEmpty(const serialPort_t *instance) diff --git a/src/main/drivers/serial_usb_vcp_at32f43x.c b/src/main/drivers/serial_usb_vcp_at32f43x.c index 03e071cadb8..29b96d1a2b6 100644 --- a/src/main/drivers/serial_usb_vcp_at32f43x.c +++ b/src/main/drivers/serial_usb_vcp_at32f43x.c @@ -226,19 +226,12 @@ void OTG_WKUP_HANDLER(void) uint32_t CDC_Send_FreeBytes(void) { - /* - return the bytes free in the circular buffer - - functionally equivalent to: - (APP_Rx_ptr_out > APP_Rx_ptr_in ? APP_Rx_ptr_out - APP_Rx_ptr_in : APP_RX_DATA_SIZE - APP_Rx_ptr_in + APP_Rx_ptr_in) - but without the impact of the condition check. - */ - uint32_t freeBytes; - ATOMIC_BLOCK(NVIC_PRIO_VCP) { - freeBytes = ((UserTxBufPtrOut - UserTxBufPtrIn) + (-((int)(UserTxBufPtrOut <= UserTxBufPtrIn)) & APP_TX_DATA_SIZE)) - 1; - } - - return freeBytes; + cdc_struct_type *pcdc = (cdc_struct_type *)otg_core_struct.dev.class_handler->pdata; + if(pcdc->g_tx_completed){ + return APP_TX_BLOCK_SIZE; + }else{ + return 0; + } } /** @@ -251,92 +244,29 @@ uint32_t CDC_Send_FreeBytes(void) */ uint32_t CDC_Send_DATA(const uint8_t *ptrBuffer, uint32_t sendLength) { - for (uint32_t i = 0; i < sendLength; i++) { - while (CDC_Send_FreeBytes() == 0) { - // block until there is free space in the ring buffer - delay(1); - } - - ATOMIC_BLOCK(NVIC_PRIO_VCP) { - UserTxBuffer[UserTxBufPtrIn] = ptrBuffer[i]; - UserTxBufPtrIn = (UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE; - } + cdc_struct_type *pcdc = (cdc_struct_type *)otg_core_struct.dev.class_handler->pdata; + uint32_t start = millis(); + + uint32_t pos=0; + while(pos < sendLength || (pos==sendLength && sendLength%64 == 0) ){//`==` is intended for sending 0 length packet + int tosend=sendLength-pos; + if(tosend>APP_TX_BLOCK_SIZE){ + tosend=APP_TX_BLOCK_SIZE; } - return sendLength; -} - -void TxTimerConfig(void){ - /* Initialize TIMx peripheral as follow: - + Period = CDC_POLLING_INTERVAL*1000 - 1 every 5ms - + Prescaler = ((SystemCoreClock/2)/10000) - 1 - + ClockDivision = 0 - + Counter direction = Up - */ - crm_periph_clock_enable(CRM_TMR20_PERIPH_CLOCK, TRUE); - //timer, period, perscaler - tmr_base_init(usbTxTmr,(CDC_POLLING_INTERVAL - 1),((system_core_clock)/10000 - 1)); - //TMR_CLOCK_DIV1 = 0X00 NO DIV - tmr_clock_source_div_set(usbTxTmr,TMR_CLOCK_DIV1); - //COUNT UP - tmr_cnt_dir_set(usbTxTmr,TMR_COUNT_UP); - - tmr_period_buffer_enable(usbTxTmr,TRUE); - - tmr_interrupt_enable(usbTxTmr, TMR_OVF_INT, TRUE); - - nvic_irq_enable(TMR20_OVF_IRQn,NVIC_PRIO_USB,0); - - tmr_counter_enable(usbTxTmr,TRUE); - -} - -/** - * @brief TIM period elapsed callback - * @param htim: TIM handle - * @retval None - */ -void TMR20_OVF_IRQHandler(void) -{ - - uint32_t buffsize; - static uint32_t lastBuffsize = 0; - - cdc_struct_type *pcdc = (cdc_struct_type *)otg_core_struct.dev.class_handler->pdata; - - if (pcdc->g_tx_completed == 1) { - // endpoint has finished transmitting previous block - if (lastBuffsize) { - bool needZeroLengthPacket = lastBuffsize % 64 == 0; - - // move the ring buffer tail based on the previous succesful transmission - UserTxBufPtrOut += lastBuffsize; - if (UserTxBufPtrOut == APP_TX_DATA_SIZE) { - UserTxBufPtrOut = 0; - } - lastBuffsize = 0; - - if (needZeroLengthPacket) { - usb_vcp_send_data(&otg_core_struct.dev, (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], 0); - return; - } - } - if (UserTxBufPtrOut != UserTxBufPtrIn) { - if (UserTxBufPtrOut > UserTxBufPtrIn) { /* Roll-back */ - buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOut; - } else { - buffsize = UserTxBufPtrIn - UserTxBufPtrOut; - } - if (buffsize > APP_TX_BLOCK_SIZE) { - buffsize = APP_TX_BLOCK_SIZE; - } - - uint32_t txed=usb_vcp_send_data(&otg_core_struct.dev,(uint8_t*)&UserTxBuffer[UserTxBufPtrOut], buffsize); - if (txed==SUCCESS) { - lastBuffsize = buffsize; - } - } + while(pcdc->g_tx_completed != 1) { + if (millis() - start > USB_TIMEOUT) { + return pos; + } } - tmr_flag_clear(usbTxTmr,TMR_OVF_FLAG); + uint32_t txed=usb_vcp_send_data(&otg_core_struct.dev,(uint8_t *)(ptrBuffer+pos), tosend); + if(pos==sendLength){ + break; + } + if (txed==SUCCESS) { + pos+=tosend; + } + } + return pos; } /************************************************************/ @@ -542,8 +472,6 @@ void usbVcpInitHardware(void) &cdc_class_handler, &cdc_desc_handler); - //config TX timer - TxTimerConfig(); } serialPort_t *usbVcpOpen(void) diff --git a/src/main/drivers/timer_impl_hal.c b/src/main/drivers/timer_impl_hal.c index e800a942353..8df0f7024d3 100644 --- a/src/main/drivers/timer_impl_hal.c +++ b/src/main/drivers/timer_impl_hal.c @@ -81,13 +81,16 @@ void impl_timerConfigBase(TCH_t * tch, uint16_t period, uint32_t hz) TIM_HandleTypeDef * timHandle = tch->timCtx->timHandle; TIM_TypeDef * timer = tch->timCtx->timDef->tim; - if (timHandle->Instance == timer) { + uint16_t period1 = (period - 1) & 0xffff; + uint16_t prescaler1 = lrintf((float)timerGetBaseClock(tch) / hz + 0.01f) - 1; + + if (timHandle->Instance == timer && timHandle->Init.Prescaler == prescaler1 && timHandle->Init.Period == period1) { return; } timHandle->Instance = timer; - timHandle->Init.Prescaler = lrintf((float)timerGetBaseClock(tch) / hz + 0.01f) - 1; - timHandle->Init.Period = (period - 1) & 0xffff; // AKA TIMx_ARR + timHandle->Init.Prescaler = prescaler1; + timHandle->Init.Period = period1; // AKA TIMx_ARR timHandle->Init.RepetitionCounter = 0; timHandle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; timHandle->Init.CounterMode = TIM_COUNTERMODE_UP; @@ -565,6 +568,15 @@ void impl_timerPWMStartDMA(TCH_t * tch) void impl_timerPWMStopDMA(TCH_t * tch) { - (void)tch; - // FIXME + const uint32_t streamLL = lookupDMALLStreamTable[DMATAG_GET_STREAM(tch->timHw->dmaTag)]; + DMA_TypeDef *dmaBase = tch->dma->dma; + + ATOMIC_BLOCK(NVIC_PRIO_MAX) { + LL_TIM_DisableDMAReq_CCx(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex]); + LL_DMA_DisableStream(dmaBase, streamLL); + DMA_CLEAR_FLAG(tch->dma, DMA_IT_TCIF); + } + tch->dmaState = TCH_DMA_IDLE; + + HAL_TIM_Base_Start(tch->timCtx->timHandle); } diff --git a/src/main/drivers/timer_impl_stdperiph.c b/src/main/drivers/timer_impl_stdperiph.c index 5cb3457c77b..d2bd35dd521 100644 --- a/src/main/drivers/timer_impl_stdperiph.c +++ b/src/main/drivers/timer_impl_stdperiph.c @@ -301,7 +301,12 @@ bool impl_timerPWMConfigChannelDMA(TCH_t * tch, void * dmaBuffer, uint8_t dmaBuf TIM_CtrlPWMOutputs(timer, ENABLE); TIM_ARRPreloadConfig(timer, ENABLE); - TIM_CCxCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCx_Enable); + if (tch->timHw->output & TIMER_OUTPUT_N_CHANNEL) { + TIM_CCxNCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCxN_Enable); + } else { + TIM_CCxCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCx_Enable); + } + TIM_Cmd(timer, ENABLE); dmaInit(tch->dma, OWNER_TIMER, 0); @@ -382,7 +387,12 @@ bool impl_timerPWMConfigDMABurst(burstDmaTimer_t *burstDmaTimer, TCH_t * tch, vo TIM_CtrlPWMOutputs(timer, ENABLE); TIM_ARRPreloadConfig(timer, ENABLE); - TIM_CCxCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCx_Enable); + if (tch->timHw->output & TIMER_OUTPUT_N_CHANNEL) { + TIM_CCxNCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCxN_Enable); + } else { + TIM_CCxCmd(timer, lookupTIMChannelTable[tch->timHw->channelIndex], TIM_CCx_Enable); + } + TIM_Cmd(timer, ENABLE); if (!tch->timCtx->dmaBurstRef) { @@ -506,5 +516,6 @@ void impl_timerPWMStopDMA(TCH_t * tch) { DMA_Cmd(tch->dma->ref, DISABLE); TIM_DMACmd(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex], DISABLE); + tch->dmaState = TCH_DMA_IDLE; TIM_Cmd(tch->timHw->tim, ENABLE); } diff --git a/src/main/drivers/timer_impl_stdperiph_at32.c b/src/main/drivers/timer_impl_stdperiph_at32.c index 4579db2bb7d..0cc194897d9 100644 --- a/src/main/drivers/timer_impl_stdperiph_at32.c +++ b/src/main/drivers/timer_impl_stdperiph_at32.c @@ -404,6 +404,6 @@ void impl_timerPWMStopDMA(TCH_t * tch) { dma_channel_enable(tch->dma->ref,FALSE); tmr_dma_request_enable(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex], FALSE); + tch->dmaState = TCH_DMA_IDLE; tmr_counter_enable(tch->timHw->tim, TRUE); - } diff --git a/src/main/drivers/vtx_common.h b/src/main/drivers/vtx_common.h index ed4d5e251a1..021d17f24de 100644 --- a/src/main/drivers/vtx_common.h +++ b/src/main/drivers/vtx_common.h @@ -19,7 +19,6 @@ #include "common/time.h" -#define VTX_SETTINGS_NO_BAND 0 // used for custom frequency selection mode #define VTX_SETTINGS_MIN_BAND 1 #define VTX_SETTINGS_MAX_BAND 5 #define VTX_SETTINGS_MIN_CHANNEL 1 @@ -33,9 +32,6 @@ #define VTX_SETTINGS_DEFAULT_PITMODE_CHANNEL 1 #define VTX_SETTINGS_DEFAULT_LOW_POWER_DISARM 0 -#define VTX_SETTINGS_MIN_FREQUENCY_MHZ 0 //min freq (in MHz) for 'vtx_freq' setting -#define VTX_SETTINGS_MAX_FREQUENCY_MHZ 5999 //max freq (in MHz) for 'vtx_freq' setting - #if defined(USE_VTX_SMARTAUDIO) || defined(USE_VTX_TRAMP) || defined(USE_VTX_MSP) #define VTX_SETTINGS_POWER_COUNT 5 diff --git a/src/main/fc/cli.c b/src/main/fc/cli.c index f2ccec9ec07..6c5d2709e7a 100644 --- a/src/main/fc/cli.c +++ b/src/main/fc/cli.c @@ -68,6 +68,7 @@ bool cliMode = false; #include "drivers/time.h" #include "drivers/usb_msc.h" #include "drivers/vtx_common.h" +#include "drivers/light_ws2811strip.h" #include "fc/fc_core.h" #include "fc/cli.h" @@ -92,6 +93,7 @@ bool cliMode = false; #include "io/gps_ublox.h" #include "io/ledstrip.h" #include "io/osd.h" +#include "io/osd/custom_elements.h" #include "io/serial.h" #include "fc/fc_msp_box.h" @@ -1308,6 +1310,110 @@ static void cliTempSensor(char *cmdline) } #endif +#ifdef USE_FW_AUTOLAND +static void printFwAutolandApproach(uint8_t dumpMask, const navFwAutolandApproach_t *navFwAutolandApproach, const navFwAutolandApproach_t *defaultFwAutolandApproach) +{ + const char *format = "fwapproach %u %d %d %u %d %d %u"; + for (uint8_t i = 0; i < MAX_FW_LAND_APPOACH_SETTINGS; i++) { + bool equalsDefault = false; + if (defaultFwAutolandApproach) { + equalsDefault = navFwAutolandApproach[i].approachDirection == defaultFwAutolandApproach[i].approachDirection + && navFwAutolandApproach[i].approachAlt == defaultFwAutolandApproach[i].approachAlt + && navFwAutolandApproach[i].landAlt == defaultFwAutolandApproach[i].landAlt + && navFwAutolandApproach[i].landApproachHeading1 == defaultFwAutolandApproach[i].landApproachHeading1 + && navFwAutolandApproach[i].landApproachHeading2 == defaultFwAutolandApproach[i].landApproachHeading2 + && navFwAutolandApproach[i].isSeaLevelRef == defaultFwAutolandApproach[i].isSeaLevelRef; + cliDefaultPrintLinef(dumpMask, equalsDefault, format, i, + defaultFwAutolandApproach[i].approachAlt, defaultFwAutolandApproach[i].landAlt, defaultFwAutolandApproach[i].approachDirection, defaultFwAutolandApproach[i].landApproachHeading1, defaultFwAutolandApproach[i].landApproachHeading2, defaultFwAutolandApproach[i].isSeaLevelRef); + } + cliDumpPrintLinef(dumpMask, equalsDefault, format, i, + navFwAutolandApproach[i].approachAlt, navFwAutolandApproach[i].landAlt, navFwAutolandApproach[i].approachDirection, navFwAutolandApproach[i].landApproachHeading1, navFwAutolandApproach[i].landApproachHeading2, navFwAutolandApproach[i].isSeaLevelRef); + } +} + +static void cliFwAutolandApproach(char * cmdline) +{ + if (isEmpty(cmdline)) { + printFwAutolandApproach(DUMP_MASTER, fwAutolandApproachConfig(0), NULL); + } else if (sl_strcasecmp(cmdline, "reset") == 0) { + resetFwAutolandApproach(-1); + } else { + int32_t approachAlt = 0, heading1 = 0, heading2 = 0, landDirection = 0, landAlt = 0; + bool isSeaLevelRef = false; + uint8_t validArgumentCount = 0; + const char *ptr = cmdline; + int8_t i = fastA2I(ptr); + if (i < 0 || i >= MAX_FW_LAND_APPOACH_SETTINGS) { + cliShowArgumentRangeError("fwapproach index", 0, MAX_FW_LAND_APPOACH_SETTINGS - 1); + } else { + if ((ptr = nextArg(ptr))) { + approachAlt = fastA2I(ptr); + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + landAlt = fastA2I(ptr); + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + landDirection = fastA2I(ptr); + + if (landDirection != 0 && landDirection != 1) { + cliShowParseError(); + return; + } + + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + heading1 = fastA2I(ptr); + + if (heading1 < -360 || heading1 > 360) { + cliShowParseError(); + return; + } + + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + heading2 = fastA2I(ptr); + + if (heading2 < -360 || heading2 > 360) { + cliShowParseError(); + return; + } + + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + isSeaLevelRef = fastA2I(ptr); + validArgumentCount++; + } + + if ((ptr = nextArg(ptr))) { + // check for too many arguments + validArgumentCount++; + } + + if (validArgumentCount != 6) { + cliShowParseError(); + } else { + fwAutolandApproachConfigMutable(i)->approachAlt = approachAlt; + fwAutolandApproachConfigMutable(i)->landAlt = landAlt; + fwAutolandApproachConfigMutable(i)->approachDirection = (fwAutolandApproachDirection_e)landDirection; + fwAutolandApproachConfigMutable(i)->landApproachHeading1 = (int16_t)heading1; + fwAutolandApproachConfigMutable(i)->landApproachHeading2 = (int16_t)heading2; + fwAutolandApproachConfigMutable(i)->isSeaLevelRef = isSeaLevelRef; + } + } + } +} +#endif + #if defined(USE_SAFE_HOME) static void printSafeHomes(uint8_t dumpMask, const navSafeHome_t *navSafeHome, const navSafeHome_t *defaultSafeHome) { @@ -1688,6 +1794,20 @@ static void cliModeColor(char *cmdline) cliPrintLinef("mode_color %u %u %u", modeIdx, funIdx, color); } } + +static void cliLedPinPWM(char *cmdline) +{ + int i; + + if (isEmpty(cmdline)) { + ledPinStopPWM(); + cliPrintLine("PWM stopped"); + } else { + i = fastA2I(cmdline); + ledPinStartPWM(i); + cliPrintLinef("PWM started: %d%%",i); + } +} #endif static void cliDelay(char* cmdLine) { @@ -2214,6 +2334,137 @@ static void cliPid(char *cmdline) { } } +static void printOsdCustomElements(uint8_t dumpMask, const osdCustomElement_t *osdCustomElements, const osdCustomElement_t *defaultosdCustomElements) +{ + const char *format = "osd_custom_elements %d %d %d %d %d %d %d %d %d \"%s\""; + + if(CUSTOM_ELEMENTS_PARTS != 3) + { + cliPrintHashLine("Incompatible count of elements for custom OSD elements"); + } + + for (uint8_t i = 0; i < MAX_CUSTOM_ELEMENTS; i++) { + bool equalsDefault = false; + + const osdCustomElement_t osdCustomElement = osdCustomElements[i]; + if(defaultosdCustomElements){ + const osdCustomElement_t defaultValue = defaultosdCustomElements[i]; + equalsDefault = + osdCustomElement.part[0].type == defaultValue.part[0].type && + osdCustomElement.part[0].value == defaultValue.part[0].value && + osdCustomElement.part[1].type == defaultValue.part[1].type && + osdCustomElement.part[1].value == defaultValue.part[1].value && + osdCustomElement.part[2].type == defaultValue.part[2].type && + osdCustomElement.part[2].value == defaultValue.part[2].value && + osdCustomElement.visibility.type == defaultValue.visibility.type && + osdCustomElement.visibility.value == defaultValue.visibility.value && + strcmp(osdCustomElement.osdCustomElementText, defaultValue.osdCustomElementText) == 0; + + cliDefaultPrintLinef(dumpMask, equalsDefault, format, + i, + osdCustomElement.part[0].type, + osdCustomElement.part[0].value, + osdCustomElement.part[1].type, + osdCustomElement.part[1].value, + osdCustomElement.part[2].type, + osdCustomElement.part[2].value, + osdCustomElement.visibility.type, + osdCustomElement.visibility.value, + osdCustomElement.osdCustomElementText + ); + } + + cliDumpPrintLinef(dumpMask, equalsDefault, format, + i, + osdCustomElement.part[0].type, + osdCustomElement.part[0].value, + osdCustomElement.part[1].type, + osdCustomElement.part[1].value, + osdCustomElement.part[2].type, + osdCustomElement.part[2].value, + osdCustomElement.visibility.type, + osdCustomElement.visibility.value, + osdCustomElement.osdCustomElementText + ); + } +} + +static void osdCustom(char *cmdline){ + char * saveptrMain; + char * saveptrParams; + int args[10], check = 0; + char text[OSD_CUSTOM_ELEMENT_TEXT_SIZE]; + uint8_t len = strlen(cmdline); + + if (len == 0) { + printOsdCustomElements(DUMP_MASTER, osdCustomElements(0), NULL); + } else { + //split by ", first are params second is text + char *ptrMain = strtok_r(cmdline, "\"", &saveptrMain); + enum { + INDEX = 0, + PART0_TYPE, + PART0_VALUE, + PART1_TYPE, + PART1_VALUE, + PART2_TYPE, + PART2_VALUE, + VISIBILITY_TYPE, + VISIBILITY_VALUE, + ARGS_COUNT + }; + char *ptrParams = strtok_r(ptrMain, " ", &saveptrParams); + while (ptrParams != NULL && check < ARGS_COUNT) { + args[check++] = fastA2I(ptrParams); + ptrParams = strtok_r(NULL, " ", &saveptrParams); + } + + if (check != ARGS_COUNT) { + cliShowParseError(); + return; + } + + //text + char *ptrText = strtok_r(NULL, "\"", &saveptrMain); + size_t copySize = 0; + if(ptrText != NULL){ + copySize = MIN(strlen(ptrText), (size_t)(sizeof(text) - 1)); + if(copySize > 0){ + memcpy(text, ptrText, copySize); + } + } + text[copySize] = '\0'; + + int32_t i = args[INDEX]; + if ( + i >= 0 && i < MAX_CUSTOM_ELEMENTS && + args[PART0_TYPE] >= 0 && args[PART0_TYPE] <= 7 && + args[PART0_VALUE] >= 0 && args[PART0_VALUE] <= UINT8_MAX && + args[PART1_TYPE] >= 0 && args[PART1_TYPE] <= 7 && + args[PART1_VALUE] >= 0 && args[PART1_VALUE] <= UINT8_MAX && + args[PART2_TYPE] >= 0 && args[PART2_TYPE] <= 7 && + args[PART2_VALUE] >= 0 && args[PART2_VALUE] <= UINT8_MAX && + args[VISIBILITY_TYPE] >= 0 && args[VISIBILITY_TYPE] <= 2 && + args[VISIBILITY_VALUE] >= 0 && args[VISIBILITY_VALUE] <= UINT8_MAX + ) { + osdCustomElementsMutable(i)->part[0].type = args[PART0_TYPE]; + osdCustomElementsMutable(i)->part[0].value = args[PART0_VALUE]; + osdCustomElementsMutable(i)->part[1].type = args[PART1_TYPE]; + osdCustomElementsMutable(i)->part[1].value = args[PART1_VALUE]; + osdCustomElementsMutable(i)->part[2].type = args[PART2_TYPE]; + osdCustomElementsMutable(i)->part[2].value = args[PART2_VALUE]; + osdCustomElementsMutable(i)->visibility.type = args[VISIBILITY_TYPE]; + osdCustomElementsMutable(i)->visibility.value = args[VISIBILITY_VALUE]; + memcpy(osdCustomElementsMutable(i)->osdCustomElementText, text, OSD_CUSTOM_ELEMENT_TEXT_SIZE); + + osdCustom(""); + } else { + cliShowParseError(); + } + } +} + + #endif #ifdef USE_SDCARD @@ -3103,6 +3354,7 @@ static void cliDumpProfile(uint8_t profileIndex, uint8_t dumpMask) cliPrintLinef("profile %d\r\n", getConfigProfile() + 1); dumpAllValues(PROFILE_VALUE, dumpMask); dumpAllValues(CONTROL_RATE_VALUE, dumpMask); + dumpAllValues(EZ_TUNE_VALUE, dumpMask); } static void cliBatteryProfile(char *cmdline) @@ -3784,6 +4036,11 @@ static void printConfig(const char *cmdline, bool doDiff) printSafeHomes(dumpMask, safeHomeConfig_CopyArray, safeHomeConfig(0)); #endif +#ifdef USE_FW_AUTOLAND + cliPrintHashLine("Fixed Wing Approach"); + printFwAutolandApproach(dumpMask, fwAutolandApproachConfig_CopyArray, fwAutolandApproachConfig(0)); +#endif + cliPrintHashLine("features"); printFeature(dumpMask, &featureConfig_Copy, featureConfig()); @@ -3848,6 +4105,10 @@ static void printConfig(const char *cmdline, bool doDiff) cliPrintHashLine("Programming: PID controllers"); printPid(dumpMask, programmingPids_CopyArray, programmingPids(0)); #endif +#ifdef USE_PROGRAMMING_FRAMEWORK + cliPrintHashLine("OSD: custom elements"); + printOsdCustomElements(dumpMask, osdCustomElements_CopyArray, osdCustomElements(0)); +#endif cliPrintHashLine("master"); dumpAllValues(MASTER_VALUE, dumpMask); @@ -4027,6 +4288,9 @@ const clicmd_t cmdTable[] = { CLI_COMMAND_DEF("flash_read", NULL, "
", cliFlashRead), CLI_COMMAND_DEF("flash_write", NULL, "
", cliFlashWrite), #endif +#endif +#ifdef USE_FW_AUTOLAND + CLI_COMMAND_DEF("fwapproach", "Fixed Wing Approach Settings", NULL, cliFwAutolandApproach), #endif CLI_COMMAND_DEF("get", "get variable value", "[name]", cliGet), #ifdef USE_GPS @@ -4035,6 +4299,7 @@ const clicmd_t cmdTable[] = { CLI_COMMAND_DEF("help", NULL, NULL, cliHelp), #ifdef USE_LED_STRIP CLI_COMMAND_DEF("led", "configure leds", NULL, cliLed), + CLI_COMMAND_DEF("ledpinpwm", "start/stop PWM on LED pin, 0..100 duty ratio", "[]\r\n", cliLedPinPWM), #endif CLI_COMMAND_DEF("map", "configure rc channel order", "[]", cliMap), CLI_COMMAND_DEF("memory", "view memory usage", NULL, cliMemory), @@ -4073,6 +4338,10 @@ const clicmd_t cmdTable[] = { CLI_COMMAND_DEF("pid", "configurable PID controllers", "<#>

\r\n" "\treset\r\n", cliPid), + + CLI_COMMAND_DEF("osd_custom_elements", "configurable OSD custom elements", + "<#> \r\n" + , osdCustom), #endif CLI_COMMAND_DEF("set", "change setting", "[=]", cliSet), CLI_COMMAND_DEF("smix", "servo mixer", diff --git a/src/main/fc/config.c b/src/main/fc/config.c index 27ed9eddd00..52cb06f81a6 100755 --- a/src/main/fc/config.c +++ b/src/main/fc/config.c @@ -64,6 +64,7 @@ #include "flight/pid.h" #include "flight/imu.h" #include "flight/failsafe.h" +#include "flight/ez_tune.h" #include "fc/config.h" #include "fc/controlrate_profile.h" @@ -305,6 +306,7 @@ static void activateConfig(void) { activateControlRateConfig(); activateBatteryProfile(); + activateMixerConfig(); resetAdjustmentStates(); @@ -425,6 +427,9 @@ bool setConfigProfile(uint8_t profileIndex) systemConfigMutable()->current_profile_index = profileIndex; // set the control rate profile to match setControlRateProfile(profileIndex); +#ifdef USE_EZ_TUNE + ezTuneUpdate(); +#endif return ret; } @@ -486,7 +491,6 @@ bool setConfigMixerProfile(uint8_t profileIndex) profileIndex = 0; } systemConfigMutable()->current_mixer_profile_index = profileIndex; - // setMixerProfile(profileIndex); return ret; } diff --git a/src/main/fc/controlrate_profile.c b/src/main/fc/controlrate_profile.c index 18f5bd343b6..c8b144e136c 100644 --- a/src/main/fc/controlrate_profile.c +++ b/src/main/fc/controlrate_profile.c @@ -44,6 +44,7 @@ void pgResetFn_controlRateProfiles(controlRateConfig_t *instance) .rcMid8 = SETTING_THR_MID_DEFAULT, .rcExpo8 = SETTING_THR_EXPO_DEFAULT, .dynPID = SETTING_TPA_RATE_DEFAULT, + .dynPID_on_YAW = SETTING_TPA_ON_YAW_DEFAULT, .pa_breakpoint = SETTING_TPA_BREAKPOINT_DEFAULT, .fixedWingTauMs = SETTING_FW_TPA_TIME_CONSTANT_DEFAULT }, diff --git a/src/main/fc/controlrate_profile_config_struct.h b/src/main/fc/controlrate_profile_config_struct.h index e07c328560c..e4038537603 100644 --- a/src/main/fc/controlrate_profile_config_struct.h +++ b/src/main/fc/controlrate_profile_config_struct.h @@ -29,6 +29,7 @@ typedef struct controlRateConfig_s { uint8_t rcMid8; uint8_t rcExpo8; uint8_t dynPID; + bool dynPID_on_YAW; uint16_t pa_breakpoint; // Breakpoint where TPA is activated uint16_t fixedWingTauMs; // Time constant of airplane TPA PT1-filter } throttle; diff --git a/src/main/fc/fc_core.c b/src/main/fc/fc_core.c old mode 100755 new mode 100644 index 87d9fbe7461..0d0863760de --- a/src/main/fc/fc_core.c +++ b/src/main/fc/fc_core.c @@ -106,6 +106,7 @@ enum { #define EMERGENCY_ARMING_TIME_WINDOW_MS 10000 #define EMERGENCY_ARMING_COUNTER_STEP_MS 1000 #define EMERGENCY_ARMING_MIN_ARM_COUNT 10 +#define EMERGENCY_INFLIGHT_REARM_TIME_WINDOW_MS 5000 timeDelta_t cycleTime = 0; // this is the number in micro second to achieve a full loop, it can differ a little and is taken into account in the PID loop static timeUs_t flightTime = 0; @@ -120,6 +121,7 @@ uint8_t motorControlEnable = false; static bool isRXDataNew; static disarmReason_t lastDisarmReason = DISARM_NONE; timeUs_t lastDisarmTimeUs = 0; +timeMs_t emergRearmStabiliseTimeout = 0; static bool prearmWasReset = false; // Prearm must be reset (RC Mode not active) before arming is possible static timeMs_t prearmActivationTime = 0; @@ -315,11 +317,11 @@ static void updateArmingStatus(void) /* CHECK: Do not allow arming if Servo AutoTrim is enabled */ if (IS_RC_MODE_ACTIVE(BOXAUTOTRIM)) { - ENABLE_ARMING_FLAG(ARMING_DISABLED_SERVO_AUTOTRIM); - } + ENABLE_ARMING_FLAG(ARMING_DISABLED_SERVO_AUTOTRIM); + } else { - DISABLE_ARMING_FLAG(ARMING_DISABLED_SERVO_AUTOTRIM); - } + DISABLE_ARMING_FLAG(ARMING_DISABLED_SERVO_AUTOTRIM); + } #ifdef USE_DSHOT /* CHECK: Don't arm if the DShot beeper was used recently, as there is a minimum delay before sending the next DShot command */ @@ -435,6 +437,7 @@ void disarm(disarmReason_t disarmReason) lastDisarmReason = disarmReason; lastDisarmTimeUs = micros(); DISABLE_ARMING_FLAG(ARMED); + DISABLE_STATE(IN_FLIGHT_EMERG_REARM); #ifdef USE_BLACKBOX if (feature(FEATURE_BLACKBOX)) { @@ -453,7 +456,6 @@ void disarm(disarmReason_t disarmReason) #ifdef USE_PROGRAMMING_FRAMEWORK programmingPidReset(); #endif - beeper(BEEPER_DISARMING); // emit disarm tone prearmWasReset = false; @@ -505,14 +507,27 @@ bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm) return counter >= EMERGENCY_ARMING_MIN_ARM_COUNT; } -#define TELEMETRY_FUNCTION_MASK (FUNCTION_TELEMETRY_HOTT | FUNCTION_TELEMETRY_SMARTPORT | FUNCTION_TELEMETRY_LTM | FUNCTION_TELEMETRY_MAVLINK | FUNCTION_TELEMETRY_IBUS) +bool emergInflightRearmEnabled(void) +{ + /* Emergency rearm allowed within 5s timeout period after disarm if craft still flying */ + timeMs_t currentTimeMs = millis(); + emergRearmStabiliseTimeout = 0; -void releaseSharedTelemetryPorts(void) { - serialPort_t *sharedPort = findSharedSerialPort(TELEMETRY_FUNCTION_MASK, FUNCTION_MSP); - while (sharedPort) { - mspSerialReleasePortIfAllocated(sharedPort); - sharedPort = findNextSharedSerialPort(TELEMETRY_FUNCTION_MASK, FUNCTION_MSP); + if ((lastDisarmReason != DISARM_SWITCH && lastDisarmReason != DISARM_KILLSWITCH) || + (currentTimeMs > US2MS(lastDisarmTimeUs) + EMERGENCY_INFLIGHT_REARM_TIME_WINDOW_MS)) { + return false; + } + + // allow emergency rearm if MR has vertical speed at least 1.5 sec after disarm indicating still flying + bool mcDisarmVertVelCheck = STATE(MULTIROTOR) && (currentTimeMs > US2MS(lastDisarmTimeUs) + 1500) && fabsf(getEstimatedActualVelocity(Z)) > 100.0f; + + if (isProbablyStillFlying() || mcDisarmVertVelCheck) { + emergRearmStabiliseTimeout = currentTimeMs + 5000; // activate Angle mode for 5s after rearm to help stabilise craft + ENABLE_STATE(IN_FLIGHT_EMERG_REARM); + return true; } + + return false; // craft doesn't appear to be flying, don't allow emergency rearm } void tryArm(void) @@ -532,15 +547,16 @@ void tryArm(void) if (STATE(MULTIROTOR) && turtleIsActive && !FLIGHT_MODE(TURTLE_MODE) && emergencyArmingCanOverrideArmingDisabled() && isMotorProtocolDshot()) { sendDShotCommand(DSHOT_CMD_SPIN_DIRECTION_REVERSED); ENABLE_ARMING_FLAG(ARMED); - enableFlightMode(TURTLE_MODE); + ENABLE_FLIGHT_MODE(TURTLE_MODE); return; } #endif #ifdef USE_PROGRAMMING_FRAMEWORK - if (!isArmingDisabled() || emergencyArmingIsEnabled() || LOGIC_CONDITION_GLOBAL_FLAG(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_ARMING_SAFETY)) { + if (emergInflightRearmEnabled() || !isArmingDisabled() || emergencyArmingIsEnabled() || + LOGIC_CONDITION_GLOBAL_FLAG(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_ARMING_SAFETY)) { #else - if (!isArmingDisabled() || emergencyArmingIsEnabled()) { + if (emergInflightRearmEnabled() || !isArmingDisabled() || emergencyArmingIsEnabled()) { #endif // If nav_extra_arming_safety was bypassed we always // allow bypassing it even without the sticks set @@ -558,11 +574,14 @@ void tryArm(void) ENABLE_ARMING_FLAG(WAS_EVER_ARMED); //It is required to inform the mixer that arming was executed and it has to switch to the FORWARD direction ENABLE_STATE(SET_REVERSIBLE_MOTORS_FORWARD); - logicConditionReset(); + if (!STATE(IN_FLIGHT_EMERG_REARM)) { + resetLandingDetectorActiveState(); // reset landing detector after arming to avoid false detection before flight + logicConditionReset(); #ifdef USE_PROGRAMMING_FRAMEWORK - programmingPidReset(); + programmingPidReset(); #endif + } headFreeModeHold = DECIDEGREES_TO_DEGREES(attitude.values.yaw); @@ -595,6 +614,16 @@ void tryArm(void) } } +#define TELEMETRY_FUNCTION_MASK (FUNCTION_TELEMETRY_HOTT | FUNCTION_TELEMETRY_SMARTPORT | FUNCTION_TELEMETRY_LTM | FUNCTION_TELEMETRY_MAVLINK | FUNCTION_TELEMETRY_IBUS) + +void releaseSharedTelemetryPorts(void) { + serialPort_t *sharedPort = findSharedSerialPort(TELEMETRY_FUNCTION_MASK, FUNCTION_MSP); + while (sharedPort) { + mspSerialReleasePortIfAllocated(sharedPort); + sharedPort = findNextSharedSerialPort(TELEMETRY_FUNCTION_MASK, FUNCTION_MSP); + } +} + void processRx(timeUs_t currentTimeUs) { // Calculate RPY channel data @@ -645,28 +674,24 @@ void processRx(timeUs_t currentTimeUs) processRcAdjustments(CONST_CAST(controlRateConfig_t*, currentControlRateProfile), canUseRxData); } - bool canUseHorizonMode = true; + // Angle mode forced on briefly after emergency inflight rearm to help stabilise attitude (currently limited to MR) + bool emergRearmAngleEnforce = STATE(MULTIROTOR) && emergRearmStabiliseTimeout > US2MS(currentTimeUs); + bool autoEnableAngle = failsafeRequiresAngleMode() || navigationRequiresAngleMode() || emergRearmAngleEnforce; - if ((IS_RC_MODE_ACTIVE(BOXANGLE) || failsafeRequiresAngleMode() || navigationRequiresAngleMode()) && sensors(SENSOR_ACC)) { - // bumpless transfer to Level mode - canUseHorizonMode = false; + /* Disable stabilised modes initially, will be enabled as required with priority ANGLE > HORIZON > ANGLEHOLD + * MANUAL mode has priority over these modes except when ANGLE auto enabled */ + DISABLE_FLIGHT_MODE(ANGLE_MODE); + DISABLE_FLIGHT_MODE(HORIZON_MODE); + DISABLE_FLIGHT_MODE(ANGLEHOLD_MODE); - if (!FLIGHT_MODE(ANGLE_MODE)) { + if (sensors(SENSOR_ACC) && (!FLIGHT_MODE(MANUAL_MODE) || autoEnableAngle)) { + if (IS_RC_MODE_ACTIVE(BOXANGLE) || autoEnableAngle) { ENABLE_FLIGHT_MODE(ANGLE_MODE); - } - } else { - DISABLE_FLIGHT_MODE(ANGLE_MODE); // failsafe support - } - - if (IS_RC_MODE_ACTIVE(BOXHORIZON) && canUseHorizonMode) { - - DISABLE_FLIGHT_MODE(ANGLE_MODE); - - if (!FLIGHT_MODE(HORIZON_MODE)) { + } else if (IS_RC_MODE_ACTIVE(BOXHORIZON)) { ENABLE_FLIGHT_MODE(HORIZON_MODE); + } else if (STATE(AIRPLANE) && IS_RC_MODE_ACTIVE(BOXANGLEHOLD)) { + ENABLE_FLIGHT_MODE(ANGLEHOLD_MODE); } - } else { - DISABLE_FLIGHT_MODE(HORIZON_MODE); } if (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE)) { @@ -677,18 +702,14 @@ void processRx(timeUs_t currentTimeUs) /* Flaperon mode */ if (IS_RC_MODE_ACTIVE(BOXFLAPERON) && STATE(FLAPERON_AVAILABLE)) { - if (!FLIGHT_MODE(FLAPERON)) { - ENABLE_FLIGHT_MODE(FLAPERON); - } + ENABLE_FLIGHT_MODE(FLAPERON); } else { DISABLE_FLIGHT_MODE(FLAPERON); } /* Turn assistant mode */ if (IS_RC_MODE_ACTIVE(BOXTURNASSIST)) { - if (!FLIGHT_MODE(TURN_ASSISTANT)) { - ENABLE_FLIGHT_MODE(TURN_ASSISTANT); - } + ENABLE_FLIGHT_MODE(TURN_ASSISTANT); } else { DISABLE_FLIGHT_MODE(TURN_ASSISTANT); } @@ -707,9 +728,7 @@ void processRx(timeUs_t currentTimeUs) #if defined(USE_MAG) if (sensors(SENSOR_ACC) || sensors(SENSOR_MAG)) { if (IS_RC_MODE_ACTIVE(BOXHEADFREE) && STATE(MULTIROTOR)) { - if (!FLIGHT_MODE(HEADFREE_MODE)) { - ENABLE_FLIGHT_MODE(HEADFREE_MODE); - } + ENABLE_FLIGHT_MODE(HEADFREE_MODE); } else { DISABLE_FLIGHT_MODE(HEADFREE_MODE); } @@ -727,6 +746,8 @@ void processRx(timeUs_t currentTimeUs) } else { DISABLE_FLIGHT_MODE(MANUAL_MODE); } + } else { + DISABLE_FLIGHT_MODE(MANUAL_MODE); } /* In airmode Iterm should be prevented to grow when Low thottle and Roll + Pitch Centered. @@ -746,52 +767,52 @@ void processRx(timeUs_t currentTimeUs) } else if (rcControlsConfig()->airmodeHandlingType == STICK_CENTER) { if (throttleIsLow) { - if (STATE(AIRMODE_ACTIVE)) { - if ((rollPitchStatus == CENTERED) || (ifMotorstopFeatureEnabled() && !STATE(FIXED_WING_LEGACY))) { - ENABLE_STATE(ANTI_WINDUP); - } - else { - DISABLE_STATE(ANTI_WINDUP); - } - } - else { - DISABLE_STATE(ANTI_WINDUP); - pidResetErrorAccumulators(); - } - } - else { - DISABLE_STATE(ANTI_WINDUP); - } + if (STATE(AIRMODE_ACTIVE)) { + if ((rollPitchStatus == CENTERED) || (ifMotorstopFeatureEnabled() && !STATE(FIXED_WING_LEGACY))) { + ENABLE_STATE(ANTI_WINDUP); + } + else { + DISABLE_STATE(ANTI_WINDUP); + } + } + else { + DISABLE_STATE(ANTI_WINDUP); + pidResetErrorAccumulators(); + } + } + else { + DISABLE_STATE(ANTI_WINDUP); + } } else if (rcControlsConfig()->airmodeHandlingType == STICK_CENTER_ONCE) { if (throttleIsLow) { - if (STATE(AIRMODE_ACTIVE)) { - if ((rollPitchStatus == CENTERED) && !STATE(ANTI_WINDUP_DEACTIVATED)) { - ENABLE_STATE(ANTI_WINDUP); - } - else { - DISABLE_STATE(ANTI_WINDUP); - } - } - else { - DISABLE_STATE(ANTI_WINDUP); - pidResetErrorAccumulators(); - } - } - else { - DISABLE_STATE(ANTI_WINDUP); - if (rollPitchStatus != CENTERED) { - ENABLE_STATE(ANTI_WINDUP_DEACTIVATED); - } - } + if (STATE(AIRMODE_ACTIVE)) { + if ((rollPitchStatus == CENTERED) && !STATE(ANTI_WINDUP_DEACTIVATED)) { + ENABLE_STATE(ANTI_WINDUP); + } + else { + DISABLE_STATE(ANTI_WINDUP); + } + } + else { + DISABLE_STATE(ANTI_WINDUP); + pidResetErrorAccumulators(); + } + } + else { + DISABLE_STATE(ANTI_WINDUP); + if (rollPitchStatus != CENTERED) { + ENABLE_STATE(ANTI_WINDUP_DEACTIVATED); + } + } } else if (rcControlsConfig()->airmodeHandlingType == THROTTLE_THRESHOLD) { - DISABLE_STATE(ANTI_WINDUP); - //This case applies only to MR when Airmode management is throttle threshold activated - if (throttleIsLow && !STATE(AIRMODE_ACTIVE)) { - pidResetErrorAccumulators(); - } - } + DISABLE_STATE(ANTI_WINDUP); + //This case applies only to MR when Airmode management is throttle threshold activated + if (throttleIsLow && !STATE(AIRMODE_ACTIVE)) { + pidResetErrorAccumulators(); + } + } //--------------------------------------------------------- if (currentMixerConfig.platformType == PLATFORM_AIRPLANE) { DISABLE_FLIGHT_MODE(HEADFREE_MODE); @@ -814,7 +835,8 @@ void processRx(timeUs_t currentTimeUs) } } #endif - + // Sound a beeper if the flight mode state has changed + updateFlightModeChangeBeeper(); } // Function for loop trigger @@ -871,7 +893,14 @@ void taskMainPidLoop(timeUs_t currentTimeUs) if (!ARMING_FLAG(ARMED)) { armTime = 0; - processDelayedSave(); + // Delay saving for 0.5s to allow other functions to process save actions on disarm + if (currentTimeUs - lastDisarmTimeUs > USECS_PER_SEC / 2) { + processDelayedSave(); + } + } + + if (armTime > 1 * USECS_PER_SEC) { // reset in flight emerg rearm flag 1 sec after arming once it's served its purpose + DISABLE_STATE(IN_FLIGHT_EMERG_REARM); } #if defined(SITL_BUILD) @@ -923,15 +952,15 @@ void taskMainPidLoop(timeUs_t currentTimeUs) //Servos should be filtered or written only when mixer is using servos or special feaures are enabled #ifdef USE_SIMULATOR - if (!ARMING_FLAG(SIMULATOR_MODE_HITL)) { - if (isServoOutputEnabled()) { - writeServos(); - } - - if (motorControlEnable) { - writeMotors(); - } - } + if (!ARMING_FLAG(SIMULATOR_MODE_HITL)) { + if (isServoOutputEnabled()) { + writeServos(); + } + + if (motorControlEnable) { + writeMotors(); + } + } #else if (isServoOutputEnabled()) { writeServos(); diff --git a/src/main/fc/fc_init.c b/src/main/fc/fc_init.c index 211c6f07047..849cdc2b7c0 100644 --- a/src/main/fc/fc_init.c +++ b/src/main/fc/fc_init.c @@ -96,6 +96,7 @@ #include "flight/power_limits.h" #include "flight/rpm_filter.h" #include "flight/servos.h" +#include "flight/ez_tune.h" #include "io/asyncfatfs/asyncfatfs.h" #include "io/beeper.h" @@ -515,6 +516,10 @@ void init(void) owInit(); #endif +#ifdef USE_EZ_TUNE + ezTuneUpdate(); +#endif + if (!sensorsAutodetect()) { // if gyro was not detected due to whatever reason, we give up now. failureMode(FAILURE_MISSING_ACC); diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 2b2d4a84375..25e9d4c135d 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -78,6 +78,7 @@ #include "flight/mixer.h" #include "flight/pid.h" #include "flight/servos.h" +#include "flight/ez_tune.h" #include "config/config_eeprom.h" #include "config/feature.h" @@ -95,6 +96,8 @@ #include "io/vtx_string.h" #include "io/gps_private.h" //for MSP_SIMULATOR +#include "io/osd/custom_elements.h" + #include "msp/msp.h" #include "msp/msp_protocol.h" #include "msp/msp_serial.h" @@ -463,6 +466,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU8(dst, (getConfigBatteryProfile() << 4) | getConfigProfile()); sbufWriteU32(dst, armingFlags); sbufWriteData(dst, &mspBoxModeFlags, sizeof(mspBoxModeFlags)); + sbufWriteU8(dst, getConfigMixerProfile()); } break; @@ -476,7 +480,7 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF } for (int i = 0; i < 3; i++) { #ifdef USE_MAG - sbufWriteU16(dst, mag.magADC[i]); + sbufWriteU16(dst, lrintf(mag.magADC[i])); #else sbufWriteU16(dst, 0); #endif @@ -522,6 +526,18 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU8(dst, -1); #endif } + if(MAX_MIXER_PROFILE_COUNT==1) break; + for (int i = 0; i < MAX_SERVO_RULES; i++) { + sbufWriteU8(dst, mixerServoMixersByIndex(nextMixerProfileIndex)[i].targetChannel); + sbufWriteU8(dst, mixerServoMixersByIndex(nextMixerProfileIndex)[i].inputSource); + sbufWriteU16(dst, mixerServoMixersByIndex(nextMixerProfileIndex)[i].rate); + sbufWriteU8(dst, mixerServoMixersByIndex(nextMixerProfileIndex)[i].speed); + #ifdef USE_PROGRAMMING_FRAMEWORK + sbufWriteU8(dst, mixerServoMixersByIndex(nextMixerProfileIndex)[i].conditionId); + #else + sbufWriteU8(dst, -1); + #endif + } break; #ifdef USE_PROGRAMMING_FRAMEWORK case MSP2_INAV_LOGIC_CONDITIONS: @@ -567,11 +583,18 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF #endif case MSP2_COMMON_MOTOR_MIXER: for (uint8_t i = 0; i < MAX_SUPPORTED_MOTORS; i++) { - sbufWriteU16(dst, primaryMotorMixer(i)->throttle * 1000); + sbufWriteU16(dst, constrainf(primaryMotorMixer(i)->throttle + 2.0f, 0.0f, 4.0f) * 1000); sbufWriteU16(dst, constrainf(primaryMotorMixer(i)->roll + 2.0f, 0.0f, 4.0f) * 1000); sbufWriteU16(dst, constrainf(primaryMotorMixer(i)->pitch + 2.0f, 0.0f, 4.0f) * 1000); sbufWriteU16(dst, constrainf(primaryMotorMixer(i)->yaw + 2.0f, 0.0f, 4.0f) * 1000); } + if (MAX_MIXER_PROFILE_COUNT==1) break; + for (uint8_t i = 0; i < MAX_SUPPORTED_MOTORS; i++) { + sbufWriteU16(dst, constrainf(mixerMotorMixersByIndex(nextMixerProfileIndex)[i].throttle + 2.0f, 0.0f, 4.0f) * 1000); + sbufWriteU16(dst, constrainf(mixerMotorMixersByIndex(nextMixerProfileIndex)[i].roll + 2.0f, 0.0f, 4.0f) * 1000); + sbufWriteU16(dst, constrainf(mixerMotorMixersByIndex(nextMixerProfileIndex)[i].pitch + 2.0f, 0.0f, 4.0f) * 1000); + sbufWriteU16(dst, constrainf(mixerMotorMixersByIndex(nextMixerProfileIndex)[i].yaw + 2.0f, 0.0f, 4.0f) * 1000); + } break; case MSP_MOTOR: @@ -697,6 +720,9 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF sbufWriteU8(dst, constrain(pidBank()->pid[i].D, 0, 255)); sbufWriteU8(dst, constrain(pidBank()->pid[i].FF, 0, 255)); } + #ifdef USE_EZ_TUNE + ezTuneUpdate(); + #endif break; case MSP_PIDNAMES: @@ -1582,6 +1608,23 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF break; #endif +#ifdef USE_EZ_TUNE + + case MSP2_INAV_EZ_TUNE: + { + sbufWriteU8(dst, ezTune()->enabled); + sbufWriteU16(dst, ezTune()->filterHz); + sbufWriteU8(dst, ezTune()->axisRatio); + sbufWriteU8(dst, ezTune()->response); + sbufWriteU8(dst, ezTune()->damping); + sbufWriteU8(dst, ezTune()->stability); + sbufWriteU8(dst, ezTune()->aggressiveness); + sbufWriteU8(dst, ezTune()->rate); + sbufWriteU8(dst, ezTune()->expo); + } + break; +#endif + #ifdef USE_RATE_DYNAMICS case MSP2_INAV_RATE_DYNAMICS: @@ -1596,12 +1639,30 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF break; #endif +#ifdef USE_PROGRAMMING_FRAMEWORK + case MSP2_INAV_CUSTOM_OSD_ELEMENTS: + sbufWriteU8(dst, MAX_CUSTOM_ELEMENTS); + sbufWriteU8(dst, OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1); + for (int i = 0; i < MAX_CUSTOM_ELEMENTS; i++) { + const osdCustomElement_t *customElement = osdCustomElements(i); + for (int ii = 0; ii < CUSTOM_ELEMENTS_PARTS; ii++) { + sbufWriteU8(dst, customElement->part[ii].type); + sbufWriteU16(dst, customElement->part[ii].value); + } + sbufWriteU8(dst, customElement->visibility.type); + sbufWriteU16(dst, customElement->visibility.value); + for (int ii = 0; ii < OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1; ii++) { + sbufWriteU8(dst, customElement->osdCustomElementText[ii]); + } + } + break; default: return false; } return true; } +#endif #ifdef USE_SAFE_HOME static mspResult_e mspFcSafeHomeOutCommand(sbuf_t *dst, sbuf_t *src) @@ -1619,6 +1680,24 @@ static mspResult_e mspFcSafeHomeOutCommand(sbuf_t *dst, sbuf_t *src) } #endif +#ifdef USE_FW_AUTOLAND +static mspResult_e mspFwApproachOutCommand(sbuf_t *dst, sbuf_t *src) +{ + const uint8_t idx = sbufReadU8(src); + if(idx < MAX_FW_LAND_APPOACH_SETTINGS) { + sbufWriteU8(dst, idx); + sbufWriteU32(dst, fwAutolandApproachConfig(idx)->approachAlt); + sbufWriteU32(dst, fwAutolandApproachConfig(idx)->landAlt); + sbufWriteU8(dst, fwAutolandApproachConfig(idx)->approachDirection); + sbufWriteU16(dst, fwAutolandApproachConfig(idx)->landApproachHeading1); + sbufWriteU16(dst, fwAutolandApproachConfig(idx)->landApproachHeading2); + sbufWriteU8(dst, fwAutolandApproachConfig(idx)->isSeaLevelRef); + return MSP_RESULT_ACK; + } else { + return MSP_RESULT_ERROR; + } +} +#endif static mspResult_e mspFcLogicConditionCommand(sbuf_t *dst, sbuf_t *src) { const uint8_t idx = sbufReadU8(src); @@ -2100,7 +2179,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) case MSP2_COMMON_SET_MOTOR_MIXER: sbufReadU8Safe(&tmp_u8, src); if ((dataSize == 9) && (tmp_u8 < MAX_SUPPORTED_MOTORS)) { - primaryMotorMixerMutable(tmp_u8)->throttle = constrainf(sbufReadU16(src) / 1000.0f, 0.0f, 1.0f); + primaryMotorMixerMutable(tmp_u8)->throttle = constrainf(sbufReadU16(src) / 1000.0f, 0.0f, 4.0f) - 2.0f; primaryMotorMixerMutable(tmp_u8)->roll = constrainf(sbufReadU16(src) / 1000.0f, 0.0f, 4.0f) - 2.0f; primaryMotorMixerMutable(tmp_u8)->pitch = constrainf(sbufReadU16(src) / 1000.0f, 0.0f, 4.0f) - 2.0f; primaryMotorMixerMutable(tmp_u8)->yaw = constrainf(sbufReadU16(src) / 1000.0f, 0.0f, 4.0f) - 2.0f; @@ -2540,6 +2619,29 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) if (sbufBytesRemaining(src) > 0) { vtxSettingsConfigMutable()->lowPowerDisarm = sbufReadU8(src); } + + // ////////////////////////////////////////////////////////// + // this code is taken from BF, it's hack for HDZERO VTX MSP frame + // API version 1.42 - this parameter kept separate since clients may already be supplying + if (sbufBytesRemaining(src) >= 2) { + sbufReadU16(src); //skip pitModeFreq + } + + // API version 1.42 - extensions for non-encoded versions of the band, channel or frequency + if (sbufBytesRemaining(src) >= 4) { + uint8_t newBand = sbufReadU8(src); + const uint8_t newChannel = sbufReadU8(src); + vtxSettingsConfigMutable()->band = newBand; + vtxSettingsConfigMutable()->channel = newChannel; + } + + /* if (sbufBytesRemaining(src) >= 4) { + sbufRead8(src); // freq_l + sbufRead8(src); // freq_h + sbufRead8(src); // band count + sbufRead8(src); // channel count + }*/ + // ////////////////////////////////////////////////////////// } } } @@ -2588,6 +2690,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) case MSP_SET_WP: if (dataSize == 21) { + const uint8_t msp_wp_no = sbufReadU8(src); // get the waypoint number navWaypoint_t msp_wp; msp_wp.action = sbufReadU8(src); // action @@ -2599,8 +2702,23 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) msp_wp.p3 = sbufReadU16(src); // P3 msp_wp.flag = sbufReadU8(src); // future: to set nav flag setWaypoint(msp_wp_no, &msp_wp); - } else + +#ifdef USE_FW_AUTOLAND + static uint8_t mmIdx = 0, fwAppraochStartIdx = 8; +#ifdef USE_SAFE_HOME + fwAppraochStartIdx = MAX_SAFE_HOMES; +#endif + if (msp_wp_no == 0) { + mmIdx = 0; + } else if (msp_wp.flag == NAV_WP_FLAG_LAST) { + mmIdx++; + } + resetFwAutolandApproach(fwAppraochStartIdx + mmIdx); +#endif + } else { return MSP_RESULT_ERROR; + } + break; case MSP2_COMMON_SET_RADAR_POS: if (dataSize == 19) { @@ -2994,6 +3112,14 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) } break; + case MSP2_INAV_SELECT_MIXER_PROFILE: + if (!ARMING_FLAG(ARMED) && sbufReadU8Safe(&tmp_u8, src)) { + setConfigMixerProfileAndWriteEEPROM(tmp_u8); + } else { + return MSP_RESULT_ERROR; + } + break; + #ifdef USE_TEMPERATURE_SENSOR case MSP2_INAV_SET_TEMP_SENSOR_CONFIG: if (dataSize == sizeof(tempSensorConfig_t) * MAX_TEMP_SENSORS) { @@ -3042,24 +3168,76 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) #ifdef USE_SAFE_HOME case MSP2_INAV_SET_SAFEHOME: if (dataSize == 10) { - uint8_t i; - if (!sbufReadU8Safe(&i, src) || i >= MAX_SAFE_HOMES) { - return MSP_RESULT_ERROR; - } - safeHomeConfigMutable(i)->enabled = sbufReadU8(src); - safeHomeConfigMutable(i)->lat = sbufReadU32(src); - safeHomeConfigMutable(i)->lon = sbufReadU32(src); + uint8_t i; + if (!sbufReadU8Safe(&i, src) || i >= MAX_SAFE_HOMES) { + return MSP_RESULT_ERROR; + } + safeHomeConfigMutable(i)->enabled = sbufReadU8(src); + safeHomeConfigMutable(i)->lat = sbufReadU32(src); + safeHomeConfigMutable(i)->lon = sbufReadU32(src); +#ifdef USE_FW_AUTOLAND + resetFwAutolandApproach(i); +#endif } else { return MSP_RESULT_ERROR; } break; #endif +#ifdef USE_FW_AUTOLAND + case MSP2_INAV_SET_FW_APPROACH: + if (dataSize == 15) { + uint8_t i; + if (!sbufReadU8Safe(&i, src) || i >= MAX_FW_LAND_APPOACH_SETTINGS) { + return MSP_RESULT_ERROR; + } + fwAutolandApproachConfigMutable(i)->approachAlt = sbufReadU32(src); + fwAutolandApproachConfigMutable(i)->landAlt = sbufReadU32(src); + fwAutolandApproachConfigMutable(i)->approachDirection = sbufReadU8(src); + + int16_t head1 = 0, head2 = 0; + if (sbufReadI16Safe(&head1, src)) { + fwAutolandApproachConfigMutable(i)->landApproachHeading1 = head1; + } + if (sbufReadI16Safe(&head2, src)) { + fwAutolandApproachConfigMutable(i)->landApproachHeading2 = head2; + } + fwAutolandApproachConfigMutable(i)->isSeaLevelRef = sbufReadU8(src); + } else { + return MSP_RESULT_ERROR; + } + break; +#endif + +#ifdef USE_EZ_TUNE + + case MSP2_INAV_EZ_TUNE_SET: + { + if (dataSize == 10) { + ezTuneMutable()->enabled = sbufReadU8(src); + ezTuneMutable()->filterHz = sbufReadU16(src); + ezTuneMutable()->axisRatio = sbufReadU8(src); + ezTuneMutable()->response = sbufReadU8(src); + ezTuneMutable()->damping = sbufReadU8(src); + ezTuneMutable()->stability = sbufReadU8(src); + ezTuneMutable()->aggressiveness = sbufReadU8(src); + ezTuneMutable()->rate = sbufReadU8(src); + ezTuneMutable()->expo = sbufReadU8(src); + + ezTuneUpdate(); + } else { + return MSP_RESULT_ERROR; + } + } + break; + +#endif + #ifdef USE_RATE_DYNAMICS case MSP2_INAV_SET_RATE_DYNAMICS: - if (dataSize == 8) { + if (dataSize == 6) { ((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.sensitivityCenter = sbufReadU8(src); ((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.sensitivityEnd = sbufReadU8(src); ((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.correctionCenter = sbufReadU8(src); @@ -3074,6 +3252,25 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) break; #endif +#ifdef USE_PROGRAMMING_FRAMEWORK + case MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS: + sbufReadU8Safe(&tmp_u8, src); + if ((dataSize == (OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1) + (MAX_CUSTOM_ELEMENTS * 3) + 4) && (tmp_u8 < MAX_CUSTOM_ELEMENTS)) { + for (int i = 0; i < CUSTOM_ELEMENTS_PARTS; i++) { + osdCustomElementsMutable(tmp_u8)->part[i].type = sbufReadU8(src); + osdCustomElementsMutable(tmp_u8)->part[i].value = sbufReadU16(src); + } + osdCustomElementsMutable(tmp_u8)->visibility.type = sbufReadU8(src); + osdCustomElementsMutable(tmp_u8)->visibility.value = sbufReadU16(src); + for (int i = 0; i < OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1; i++) { + osdCustomElementsMutable(tmp_u8)->osdCustomElementText[i] = sbufReadU8(src); + } + osdCustomElementsMutable(tmp_u8)->osdCustomElementText[OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1] = '\0'; + } else{ + return MSP_RESULT_ERROR; + } + + break; default: @@ -3081,6 +3278,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src) } return MSP_RESULT_ACK; } +#endif static const setting_t *mspReadSetting(sbuf_t *src) { @@ -3259,6 +3457,8 @@ static bool mspSettingInfoCommand(sbuf_t *dst, sbuf_t *src) sbufWriteU8(dst, 0); sbufWriteU8(dst, 0); break; + case EZ_TUNE_VALUE: + FALLTHROUGH; case PROFILE_VALUE: FALLTHROUGH; case CONTROL_RATE_VALUE: @@ -3322,7 +3522,7 @@ bool isOSDTypeSupportedBySimulator(void) { #ifdef USE_OSD displayPort_t *osdDisplayPort = osdGetDisplayPort(); - return (osdDisplayPort && osdDisplayPort->cols == 30 && (osdDisplayPort->rows == 13 || osdDisplayPort->rows == 16)); + return (!!osdDisplayPort && !!osdDisplayPort->vTable->readChar); #else return false; #endif @@ -3334,18 +3534,25 @@ void mspWriteSimulatorOSD(sbuf_t *dst) //scan displayBuffer iteratively //no more than 80+3+2 bytes output in single run //0 and 255 are special symbols - //255 - font bank switch - //0 - font bank switch, blink switch and character repeat + //255 [char] - font bank switch + //0 [flags,count] [char] - font bank switch, blink switch and character repeat + //original 0 is sent as 32 + //original 0xff, 0x100 and 0x1ff are forcibly sent inside command 0 static uint8_t osdPos_y = 0; static uint8_t osdPos_x = 0; + //indicate new format hitl 1.4.0 + sbufWriteU8(dst, 255); if (isOSDTypeSupportedBySimulator()) { displayPort_t *osdDisplayPort = osdGetDisplayPort(); - sbufWriteU8(dst, osdPos_y | (osdDisplayPort->rows == 16 ? 128: 0)); + sbufWriteU8(dst, osdDisplayPort->rows); + sbufWriteU8(dst, osdDisplayPort->cols); + + sbufWriteU8(dst, osdPos_y); sbufWriteU8(dst, osdPos_x); int bytesCount = 0; @@ -3356,7 +3563,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst) bool blink = false; int count = 0; - int processedRows = 16; + int processedRows = osdDisplayPort->rows; while (bytesCount < 80) //whole response should be less 155 bytes at worst. { @@ -3367,7 +3574,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst) while ( true ) { displayReadCharWithAttr(osdDisplayPort, osdPos_x, osdPos_y, &c, &attr); - if (c == 0 || c == 255) c = 32; + if (c == 0) c = 32; //REVIEW: displayReadCharWithAttr() should return mode with _TEXT_ATTRIBUTES_BLINK_BIT ! //for max7456 it returns mode with MAX7456_MODE_BLINK instead (wrong) @@ -3382,7 +3589,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst) lastChar = c; blink1 = blink2; } - else if (lastChar != c || blink2 != blink1 || count == 63) + else if ((lastChar != c) || (blink2 != blink1) || (count == 63)) { break; } @@ -3390,12 +3597,12 @@ void mspWriteSimulatorOSD(sbuf_t *dst) count++; osdPos_x++; - if (osdPos_x == 30) + if (osdPos_x == osdDisplayPort->cols) { osdPos_x = 0; osdPos_y++; processedRows--; - if (osdPos_y == 16) + if (osdPos_y == osdDisplayPort->rows) { osdPos_y = 0; } @@ -3403,6 +3610,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst) } uint8_t cmd = 0; + uint8_t lastCharLow = (uint8_t)(lastChar & 0xff); if (blink1 != blink) { cmd |= 128;//switch blink attr @@ -3418,27 +3626,27 @@ void mspWriteSimulatorOSD(sbuf_t *dst) if (count == 1 && cmd == 64) { - sbufWriteU8(dst, 255); //short command for bank switch + sbufWriteU8(dst, 255); //short command for bank switch with char following sbufWriteU8(dst, lastChar & 0xff); bytesCount += 2; } - else if (count > 2 || cmd !=0 ) + else if ((count > 2) || (cmd !=0) || (lastChar == 255) || (lastChar == 0x100) || (lastChar == 0x1ff)) { cmd |= count; //long command for blink/bank switch and symbol repeat sbufWriteU8(dst, 0); sbufWriteU8(dst, cmd); - sbufWriteU8(dst, lastChar & 0xff); + sbufWriteU8(dst, lastCharLow); bytesCount += 3; } else if (count == 2) //cmd == 0 here { - sbufWriteU8(dst, lastChar & 0xff); - sbufWriteU8(dst, lastChar & 0xff); + sbufWriteU8(dst, lastCharLow); + sbufWriteU8(dst, lastCharLow); bytesCount+=2; } else { - sbufWriteU8(dst, lastChar & 0xff); + sbufWriteU8(dst, lastCharLow); bytesCount++; } @@ -3452,7 +3660,7 @@ void mspWriteSimulatorOSD(sbuf_t *dst) } else { - sbufWriteU8(dst, 255); + sbufWriteU8(dst, 0); } } #endif @@ -3533,7 +3741,11 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu *ret = mspFcSafeHomeOutCommand(dst, src); break; #endif - +#ifdef USE_FW_AUTOLAND + case MSP2_INAV_FW_APPROACH: + *ret = mspFwApproachOutCommand(dst, src); + break; +#endif #ifdef USE_SIMULATOR case MSP_SIMULATOR: tmp_u8 = sbufReadU8(src); // Get the Simulator MSP version @@ -3586,6 +3798,7 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu } #endif ENABLE_ARMING_FLAG(SIMULATOR_MODE_HITL); + ENABLE_STATE(ACCELEROMETER_CALIBRATED); LOG_DEBUG(SYSTEM, "Simulator enabled"); } @@ -3662,15 +3875,11 @@ bool mspFCProcessInOutCommand(uint16_t cmdMSP, sbuf_t *dst, sbuf_t *src, mspResu sbufAdvance(src, sizeof(uint16_t) * XYZ_AXIS_COUNT); } -#if defined(USE_FAKE_BATT_SENSOR) if (SIMULATOR_HAS_OPTION(HITL_EXT_BATTERY_VOLTAGE)) { - fakeBattSensorSetVbat(sbufReadU8(src) * 10); + simulatorData.vbat = sbufReadU8(src); } else { -#endif - fakeBattSensorSetVbat((uint16_t)(SIMULATOR_FULL_BATTERY * 10.0f)); -#if defined(USE_FAKE_BATT_SENSOR) + simulatorData.vbat = SIMULATOR_FULL_BATTERY; } -#endif if (SIMULATOR_HAS_OPTION(HITL_AIRSPEED)) { simulatorData.airSpeed = sbufReadU16(src); diff --git a/src/main/fc/fc_msp_box.c b/src/main/fc/fc_msp_box.c index f7c88d6e5b0..f1c72458bff 100644 --- a/src/main/fc/fc_msp_box.c +++ b/src/main/fc/fc_msp_box.c @@ -102,6 +102,7 @@ static const box_t boxes[CHECKBOX_ITEM_COUNT + 1] = { { .boxId = BOXMULTIFUNCTION, .boxName = "MULTI FUNCTION", .permanentId = 61 }, { .boxId = BOXMIXERPROFILE, .boxName = "MIXER PROFILE 2", .permanentId = 62 }, { .boxId = BOXMIXERTRANSITION, .boxName = "MIXER TRANSITION", .permanentId = 63 }, + { .boxId = BOXANGLEHOLD, .boxName = "ANGLE HOLD", .permanentId = 64 }, { .boxId = CHECKBOX_ITEM_COUNT, .boxName = NULL, .permanentId = 0xFF } }; @@ -202,7 +203,7 @@ void initActiveBoxIds(void) //Camstab mode is enabled always ADD_ACTIVE_BOX(BOXCAMSTAB); - if (STATE(MULTIROTOR)) { + if (STATE(MULTIROTOR) || platformTypeConfigured(PLATFORM_MULTIROTOR) || platformTypeConfigured(PLATFORM_TRICOPTER)) { if ((sensors(SENSOR_ACC) || sensors(SENSOR_MAG))) { ADD_ACTIVE_BOX(BOXHEADFREE); ADD_ACTIVE_BOX(BOXHEADADJ); @@ -219,9 +220,6 @@ void initActiveBoxIds(void) const bool navFlowDeadReckoning = sensors(SENSOR_OPFLOW) && sensors(SENSOR_ACC) && positionEstimationConfig()->allow_dead_reckoning; bool navReadyPosControl = sensors(SENSOR_ACC) && feature(FEATURE_GPS); - if (STATE(MULTIROTOR)) { - navReadyPosControl = navReadyPosControl && getHwCompassStatus() != HW_SENSOR_NONE; - } if (STATE(ALTITUDE_CONTROL) && navReadyAltControl && (navReadyPosControl || navFlowDeadReckoning)) { ADD_ACTIVE_BOX(BOXNAVPOSHOLD); @@ -244,13 +242,13 @@ void initActiveBoxIds(void) #endif } - if (STATE(AIRPLANE)) { + if (STATE(AIRPLANE) || platformTypeConfigured(PLATFORM_AIRPLANE)) { ADD_ACTIVE_BOX(BOXSOARING); } } #ifdef USE_MR_BRAKING_MODE - if (mixerConfig()->platformType == PLATFORM_MULTIROTOR) { + if (mixerConfig()->platformType == PLATFORM_MULTIROTOR || platformTypeConfigured(PLATFORM_MULTIROTOR)) { ADD_ACTIVE_BOX(BOXBRAKING); } #endif @@ -259,11 +257,12 @@ void initActiveBoxIds(void) ADD_ACTIVE_BOX(BOXNAVALTHOLD); } - if (STATE(AIRPLANE) || STATE(ROVER) || STATE(BOAT)) { + if (STATE(AIRPLANE) || STATE(ROVER) || STATE(BOAT) || + platformTypeConfigured(PLATFORM_AIRPLANE) || platformTypeConfigured(PLATFORM_ROVER) || platformTypeConfigured(PLATFORM_BOAT)) { ADD_ACTIVE_BOX(BOXMANUAL); } - if (STATE(AIRPLANE)) { + if (STATE(AIRPLANE) || platformTypeConfigured(PLATFORM_AIRPLANE)) { if (!feature(FEATURE_FW_LAUNCH)) { ADD_ACTIVE_BOX(BOXNAVLAUNCH); } @@ -278,6 +277,9 @@ void initActiveBoxIds(void) if (sensors(SENSOR_BARO)) { ADD_ACTIVE_BOX(BOXAUTOLEVEL); } + if (sensors(SENSOR_ACC)) { + ADD_ACTIVE_BOX(BOXANGLEHOLD); + } } /* @@ -318,7 +320,7 @@ void initActiveBoxIds(void) ADD_ACTIVE_BOX(BOXKILLSWITCH); ADD_ACTIVE_BOX(BOXFAILSAFE); -#ifdef USE_RCDEVICE +#if defined(USE_RCDEVICE) || defined(USE_MSP_DISPLAYPORT) ADD_ACTIVE_BOX(BOXCAMERA1); ADD_ACTIVE_BOX(BOXCAMERA2); ADD_ACTIVE_BOX(BOXCAMERA3); @@ -431,6 +433,7 @@ void packBoxModeFlags(boxBitmask_t * mspBoxModeFlags) CHECK_ACTIVE_BOX(IS_ENABLED(currentMixerProfileIndex), BOXMIXERPROFILE); CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXMIXERTRANSITION)), BOXMIXERTRANSITION); #endif + CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXANGLEHOLD)), BOXANGLEHOLD); memset(mspBoxModeFlags, 0, sizeof(boxBitmask_t)); for (uint32_t i = 0; i < activeBoxIdCount; i++) { if (activeBoxes[activeBoxIds[i]]) { diff --git a/src/main/fc/fc_tasks.c b/src/main/fc/fc_tasks.c index af5f27b5272..607a814bed5 100755 --- a/src/main/fc/fc_tasks.c +++ b/src/main/fc/fc_tasks.c @@ -62,6 +62,7 @@ #include "io/osd.h" #include "io/serial.h" #include "io/rcdevice_cam.h" +#include "io/osd_joystick.h" #include "io/smartport_master.h" #include "io/vtx.h" #include "io/vtx_msp.h" @@ -393,8 +394,12 @@ void fcTasksInit(void) #endif #endif #ifdef USE_RCDEVICE +#ifdef USE_LED_STRIP + setTaskEnabled(TASK_RCDEVICE, rcdeviceIsEnabled() || osdJoystickEnabled()); +#else setTaskEnabled(TASK_RCDEVICE, rcdeviceIsEnabled()); #endif +#endif #ifdef USE_PROGRAMMING_FRAMEWORK setTaskEnabled(TASK_PROGRAMMING_FRAMEWORK, true); #endif diff --git a/src/main/fc/rc_controls.c b/src/main/fc/rc_controls.c index 8a03ed81284..9cce60a2a38 100644 --- a/src/main/fc/rc_controls.c +++ b/src/main/fc/rc_controls.c @@ -119,8 +119,7 @@ throttleStatus_e FAST_CODE NOINLINE calculateThrottleStatus(throttleStatusType_e value = rcCommand[THROTTLE]; } - const uint16_t mid_throttle_deadband = rcControlsConfig()->mid_throttle_deadband; - bool midThrottle = value > (PWM_RANGE_MIDDLE - mid_throttle_deadband) && value < (PWM_RANGE_MIDDLE + mid_throttle_deadband); + bool midThrottle = value > (reversibleMotorsConfig()->deadband_low) && value < (reversibleMotorsConfig()->deadband_high); if ((feature(FEATURE_REVERSIBLE_MOTORS) && midThrottle) || (!feature(FEATURE_REVERSIBLE_MOTORS) && (value < rxConfig()->mincheck))) { return THROTTLE_LOW; } diff --git a/src/main/fc/rc_modes.h b/src/main/fc/rc_modes.h index 6b56fa556b1..fa1827a6ad0 100644 --- a/src/main/fc/rc_modes.h +++ b/src/main/fc/rc_modes.h @@ -81,6 +81,7 @@ typedef enum { BOXMULTIFUNCTION = 52, BOXMIXERPROFILE = 53, BOXMIXERTRANSITION = 54, + BOXANGLEHOLD = 55, CHECKBOX_ITEM_COUNT } boxId_e; diff --git a/src/main/fc/runtime_config.c b/src/main/fc/runtime_config.c index 15dadd1c59e..daeb9cbbcde 100644 --- a/src/main/fc/runtime_config.c +++ b/src/main/fc/runtime_config.c @@ -91,31 +91,16 @@ armingFlag_e isArmingDisabledReason(void) } /** - * Enables the given flight mode. A beep is sounded if the flight mode - * has changed. Returns the new 'flightModeFlags' value. + * Called at Rx update rate. Beeper sounded if flight mode state has changed. */ -uint32_t enableFlightMode(flightModeFlags_e mask) +void updateFlightModeChangeBeeper(void) { - uint32_t oldVal = flightModeFlags; + static uint32_t previousFlightModeFlags = 0; - flightModeFlags |= (mask); - if (flightModeFlags != oldVal) + if (flightModeFlags != previousFlightModeFlags) { beeperConfirmationBeeps(1); - return flightModeFlags; -} - -/** - * Disables the given flight mode. A beep is sounded if the flight mode - * has changed. Returns the new 'flightModeFlags' value. - */ -uint32_t disableFlightMode(flightModeFlags_e mask) -{ - uint32_t oldVal = flightModeFlags; - - flightModeFlags &= ~(mask); - if (flightModeFlags != oldVal) - beeperConfirmationBeeps(1); - return flightModeFlags; + } + previousFlightModeFlags = flightModeFlags; } bool sensors(uint32_t mask) @@ -173,13 +158,16 @@ flightModeForTelemetry_e getFlightModeForTelemetry(void) if (FLIGHT_MODE(HORIZON_MODE)) return FLM_HORIZON; + if (FLIGHT_MODE(ANGLEHOLD_MODE)) + return FLM_ANGLEHOLD; return STATE(AIRMODE_ACTIVE) ? FLM_ACRO_AIR : FLM_ACRO; } #ifdef USE_SIMULATOR simulatorData_t simulatorData = { - .flags = 0, - .debugIndex = 0 + .flags = 0, + .debugIndex = 0, + .vbat = 0 }; #endif diff --git a/src/main/fc/runtime_config.h b/src/main/fc/runtime_config.h index 16d1b411df8..8772c090e04 100644 --- a/src/main/fc/runtime_config.h +++ b/src/main/fc/runtime_config.h @@ -104,12 +104,14 @@ typedef enum { TURN_ASSISTANT = (1 << 14), TURTLE_MODE = (1 << 15), SOARING_MODE = (1 << 16), + ANGLEHOLD_MODE = (1 << 17), + NAV_FW_AUTOLAND = (1 << 18), } flightModeFlags_e; extern uint32_t flightModeFlags; -#define DISABLE_FLIGHT_MODE(mask) disableFlightMode(mask) -#define ENABLE_FLIGHT_MODE(mask) enableFlightMode(mask) +#define DISABLE_FLIGHT_MODE(mask) (flightModeFlags &= ~(mask)) +#define ENABLE_FLIGHT_MODE(mask) (flightModeFlags |= (mask)) #define FLIGHT_MODE(mask) (flightModeFlags & (mask)) typedef enum { @@ -139,6 +141,8 @@ typedef enum { FW_HEADING_USE_YAW = (1 << 24), ANTI_WINDUP_DEACTIVATED = (1 << 25), LANDING_DETECTED = (1 << 26), + IN_FLIGHT_EMERG_REARM = (1 << 27), + TAILSITTER = (1 << 28), //offset the pitch angle by 90 degrees } stateFlags_t; #define DISABLE_STATE(mask) (stateFlags &= ~(mask)) @@ -161,6 +165,7 @@ typedef enum { FLM_CRUISE, FLM_LAUNCH, FLM_FAILSAFE, + FLM_ANGLEHOLD, FLM_COUNT } flightModeForTelemetry_e; @@ -170,7 +175,7 @@ flightModeForTelemetry_e getFlightModeForTelemetry(void); #define SIMULATOR_MSP_VERSION 2 // Simulator MSP version #define SIMULATOR_BARO_TEMP 25 // °C -#define SIMULATOR_FULL_BATTERY 12.6f // Volts +#define SIMULATOR_FULL_BATTERY 126 // Volts*10 #define SIMULATOR_HAS_OPTION(flag) ((simulatorData.flags & flag) != 0) typedef enum { @@ -199,8 +204,7 @@ extern simulatorData_t simulatorData; #endif -uint32_t enableFlightMode(flightModeFlags_e mask); -uint32_t disableFlightMode(flightModeFlags_e mask); +void updateFlightModeChangeBeeper(void); bool sensors(uint32_t mask); void sensorsSet(uint32_t mask); diff --git a/src/main/fc/settings.c b/src/main/fc/settings.c index 8ea69b82f09..109f430f843 100644 --- a/src/main/fc/settings.c +++ b/src/main/fc/settings.c @@ -237,6 +237,8 @@ static uint16_t getValueOffset(const setting_t *value) return value->offset + sizeof(pidProfile_t) * getConfigProfile(); case CONTROL_RATE_VALUE: return value->offset + sizeof(controlRateConfig_t) * getConfigProfile(); + case EZ_TUNE_VALUE: + return value->offset + sizeof(ezTuneSettings_t) * getConfigProfile(); case BATTERY_CONFIG_VALUE: return value->offset + sizeof(batteryProfile_t) * getConfigBatteryProfile(); case MIXER_CONFIG_VALUE: diff --git a/src/main/fc/settings.h b/src/main/fc/settings.h index 7fdfd66bf25..75e8bdbef32 100644 --- a/src/main/fc/settings.h +++ b/src/main/fc/settings.h @@ -35,6 +35,7 @@ typedef enum { CONTROL_RATE_VALUE = (2 << SETTING_SECTION_OFFSET), BATTERY_CONFIG_VALUE = (3 << SETTING_SECTION_OFFSET), MIXER_CONFIG_VALUE = (4 << SETTING_SECTION_OFFSET), + EZ_TUNE_VALUE = (5 << SETTING_SECTION_OFFSET) } setting_section_e; typedef enum { diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml old mode 100755 new mode 100644 index 261bf14a56b..de413d456af --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -50,7 +50,7 @@ tables: values: ["AUTO", "EGNOS", "WAAS", "MSAS", "GAGAN", "SPAN", "NONE"] enum: sbasMode_e - name: gps_dyn_model - values: ["PEDESTRIAN", "AIR_1G", "AIR_4G"] + values: ["PEDESTRIAN","AUTOMOTIVE", "AIR_1G", "AIR_2G", "AIR_4G"] enum: gpsDynModel_e - name: reset_type values: ["NEVER", "FIRST_ARM", "EACH_ARM"] @@ -192,7 +192,10 @@ tables: enum: gpsBaudRate_e - name: nav_mc_althold_throttle values: ["STICK", "MID_STICK", "HOVER"] - enum: navMcAltHoldThrottle_e + enum: navMcAltHoldThrottle_e + - name: led_pin_pwm_mode + values: ["SHARED_LOW", "SHARED_HIGH", "LOW", "HIGH"] + enum: led_pin_pwm_mode_e constants: RPYL_PID_MIN: 0 @@ -585,7 +588,7 @@ groups: members: - name: pitot_hardware description: "Selection of pitot hardware." - default_value: "VIRTUAL" + default_value: "NONE" table: pitot_hardware - name: pitot_lpf_milli_hz min: 0 @@ -1045,7 +1048,7 @@ groups: max: PWM_RANGE_MAX - name: nav_mc_hover_thr description: "Multicopter hover throttle hint for altitude controller. Should be set to approximate throttle value when drone is hovering." - default_value: 1500 + default_value: 1300 field: nav.mc.hover_throttle min: 1000 max: 2000 @@ -1182,8 +1185,13 @@ groups: field: mixer_config.switchTransitionTimer min: 0 max: 200 + - name: tailsitter_orientation_offset + description: "Apply a 90 deg pitch offset in sensor aliment for tailsitter flying mode" + default_value: OFF + field: mixer_config.tailsitterOrientationOffset + type: bool + - - name: PG_REVERSIBLE_MOTORS_CONFIG type: reversibleMotorsConfig_t @@ -1267,7 +1275,7 @@ groups: min: 0 max: 100 - name: tpa_rate - description: "Throttle PID attenuation reduces influence of P on ROLL and PITCH as throttle increases. For every 1% throttle after the TPA breakpoint, P is reduced by the TPA rate." + description: "Throttle PID attenuation reduces influence of PDFF on ROLL and PITCH of multi-rotor, PIDFF on ROLL,PITCH,YAW OF fixed_wing as throttle increases. For every 1% throttle after the TPA breakpoint, P is reduced by the TPA rate." default_value: 0 field: throttle.dynPID min: 0 @@ -1278,6 +1286,11 @@ groups: field: throttle.pa_breakpoint min: PWM_RANGE_MIN max: PWM_RANGE_MAX + - name: tpa_on_yaw + description: "Throttle PID attenuation also reduces influence on YAW for multi-rotor, Should be set to ON for tilting rotors." + type: bool + field: throttle.dynPID_on_YAW + default_value: OFF - name: fw_tpa_time_constant description: "TPA smoothing and delay time constant to reflect non-instant speed/throttle response of the plane. See **PID Attenuation and scaling** Wiki for full details." default_value: 1500 @@ -1452,9 +1465,15 @@ groups: type: bool - name: ahrs_inertia_comp_method description: "Inertia force compensation method when gps is avaliable, VELNED use the accleration from gps, TURNRATE calculates accleration by turnrate multiplied by speed, ADAPTIVE choose best result from two in each ahrs loop" - default_value: VELNED + default_value: ADAPTIVE field: inertia_comp_method table: imu_inertia_comp_method + - name: ahrs_gps_yaw_weight + description: "Arhs gps yaw weight when mag is avaliable, 0 means no gps yaw, 100 means equal weight as compass" + default_value: 100 + field: gps_yaw_weight + min: 0 + max: 500 - name: PG_ARMING_CONFIG type: armingConfig_t @@ -1492,6 +1511,65 @@ groups: min: 0 max: 99 + - name: PG_EZ_TUNE + headers: ["flight/ez_tune.h"] + type: ezTuneSettings_t + value_type: EZ_TUNE_VALUE + members: + - name: ez_enabled + description: "Enables EzTune feature" + default_value: OFF + field: enabled + type: bool + - name: ez_filter_hz + description: "EzTune filter cutoff frequency" + default_value: 110 + field: filterHz + min: 10 + max: 300 + - name: ez_axis_ratio + description: "EzTune axis ratio" + default_value: 110 + field: axisRatio + min: 25 + max: 175 + - name: ez_response + description: "EzTune response" + default_value: 100 + field: response + min: 0 + max: 200 + - name: ez_damping + description: "EzTune damping" + default_value: 100 + field: damping + min: 0 + max: 200 + - name: ez_stability + description: "EzTune stability" + default_value: 100 + field: stability + min: 0 + max: 200 + - name: ez_aggressiveness + description: "EzTune aggressiveness" + default_value: 100 + field: aggressiveness + min: 0 + max: 200 + - name: ez_rate + description: "EzTune rate" + default_value: 100 + field: rate + min: 0 + max: 200 + - name: ez_expo + description: "EzTune expo" + default_value: 100 + field: expo + min: 0 + max: 200 + - name: PG_RPM_FILTER_CONFIG headers: ["flight/rpm_filter.h"] condition: USE_RPM_FILTER @@ -1541,8 +1619,8 @@ groups: table: gps_sbas_mode type: uint8_t - name: gps_dyn_model - description: "GPS navigation model: Pedestrian, Air_1g, Air_4g. Default is AIR_1G. Use pedestrian with caution, can cause flyaways with fast flying." - default_value: "AIR_1G" + description: "GPS navigation model: Pedestrian, Automotive, Air<1g, Air<2g, Air<4g. Default is AIR_2G. Use pedestrian/Automotive with caution, can cause flyaways with fast flying." + default_value: "AIR_2G" field: dynModel table: gps_dyn_model type: uint8_t @@ -1663,7 +1741,7 @@ groups: min: RPYL_PID_MIN max: RPYL_PID_MAX - name: mc_cd_pitch - description: "Multicopter Control Derivative gain for PITCH" + description: "Multicopter Control Derivative gain for PITCH (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough." default_value: 60 field: bank_mc.pid[PID_PITCH].FF min: RPYL_PID_MIN @@ -1687,7 +1765,7 @@ groups: min: RPYL_PID_MIN max: RPYL_PID_MAX - name: mc_cd_roll - description: "Multicopter Control Derivative gain for ROLL" + description: "Multicopter Control Derivative gain for ROLL (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough." default_value: 60 field: bank_mc.pid[PID_ROLL].FF min: RPYL_PID_MIN @@ -1711,7 +1789,7 @@ groups: min: RPYL_PID_MIN max: RPYL_PID_MAX - name: mc_cd_yaw - description: "Multicopter Control Derivative gain for YAW" + description: "Multicopter Control Derivative gain for YAW (known as 'Feed Forward' in Betaflight). The CD intoduces a term to the PID controller that is the magnitude of the Setpoint change. Fast inputs produce a high CD gain to help push the MC into a move; in advance of the P-gain if set high enough." default_value: 60 field: bank_mc.pid[PID_YAW].FF min: RPYL_PID_MIN @@ -1851,12 +1929,6 @@ groups: default_value: 0 min: 0 max: 200 - - name: fw_iterm_throw_limit - description: "Limits max/min I-term value in stabilization PID controller in case of Fixed Wing. It solves the problem of servo saturation before take-off/throwing the airplane into the air. By default, error accumulated in I-term can not exceed 1/3 of servo throw (around 165us). Set 0 to disable completely." - default_value: 165 - field: fixedWingItermThrowLimit - min: FW_ITERM_THROW_LIMIT_MIN - max: FW_ITERM_THROW_LIMIT_MAX - name: fw_reference_airspeed description: "Reference airspeed. Set this to airspeed at which PIDs were tuned. Usually should be set to cruise airspeed. Also used for coordinated turn calculation if airspeed sensor is not present." default_value: 1500 @@ -1905,6 +1977,12 @@ groups: field: itermWindupPointPercent min: 0 max: 90 + - name: pid_iterm_limit_percent + description: "Limits max/min I-term value in stabilization PID controller. It solves the problem of servo saturation before take-off/throwing the airplane into the air. Or multirotors with low authority. By default, error accumulated in I-term can not exceed 33% of total pid throw (around 165us on deafult pidsum_limit of pitch/roll). Set 0 to disable completely." + default_value: 33 + field: pidItermLimitPercent + min: 0 + max: 200 - name: rate_accel_limit_roll_pitch description: "Limits acceleration of ROLL/PITCH rotation speed that can be requested by stick input. In degrees-per-second-squared. Small and powerful UAV flies great with high acceleration limit ( > 5000 dps^2 and even > 10000 dps^2). Big and heavy multirotors will benefit from low acceleration limit (~ 360 dps^2). When set correctly, it greatly improves stopping performance. Value of 0 disables limiting." default_value: 0 @@ -2128,7 +2206,7 @@ groups: table: pidTypeTable default_value: AUTO - name: mc_cd_lpf_hz - description: "Cutoff frequency for Control Derivative. Lower value smoother reaction on fast stick movements. With higher values, response will be more aggressive, jerky" + description: "Cutoff frequency for Control Derivative. This controls the cutoff for the LPF that is applied to the CD (Feed Forward) signal to the PID controller. Lower value will produce a smoother CD gain to the controller, but it will be more delayed. Higher values will produce CD gain that may have more noise in the signal depending on your RC link but wil be less delayed." default_value: 30 field: controlDerivativeLpfHz min: 0 @@ -2210,6 +2288,7 @@ groups: field: use_gps_velned type: bool - name: inav_use_gps_no_baro + description: "Defines if INAV should use only use GPS data for altitude estimation and not barometer. If set to ON, INAV will allow GPS assisted modes and RTH even when there is no barometer installed." field: use_gps_no_baro type: bool default_value: OFF @@ -2238,7 +2317,7 @@ groups: field: w_z_surface_p min: 0 max: 100 - default_value: 3.5 + default_value: 3.5 - name: inav_w_z_surface_v field: w_z_surface_v min: 0 @@ -2255,13 +2334,13 @@ groups: max: 100 default_value: 2.0 - name: inav_w_z_baro_p - description: "Weight of barometer measurements in estimated altitude and climb rate" + description: "Weight of barometer measurements in estimated altitude and climb rate. Setting is used on both airplanes and multirotors." field: w_z_baro_p min: 0 max: 10 default_value: 0.35 - name: inav_w_z_gps_p - description: "Weight of GPS altitude measurements in estimated altitude. Setting is used only of airplanes" + description: "Weight of GPS altitude measurements in estimated altitude. Setting is used on both airplanes and multirotors." field: w_z_gps_p min: 0 max: 10 @@ -2296,11 +2375,6 @@ groups: field: w_xy_res_v min: 0 max: 10 - - name: inav_w_xyz_acc_p - field: w_xyz_acc_p - min: 0 - max: 1 - default_value: 1.0 - name: inav_w_acc_bias description: "Weight for accelerometer drift estimation" default_value: 0.01 @@ -2419,6 +2493,12 @@ groups: field: general.auto_speed min: 10 max: 2000 + - name: nav_min_ground_speed + description: "Minimum ground speed for navigation flight modes [m/s]. Currently, this only affects fixed wing. Default 7 m/s." + default_value: 7 + field: general.min_ground_speed + min: 6 + max: 50 - name: nav_max_auto_speed description: "Maximum speed allowed in fully autonomous modes (RTH, WP) [cm/s] [Multirotor only]" default_value: 1000 @@ -2525,6 +2605,12 @@ groups: default_value: "ALWAYS" field: general.flags.rth_allow_landing table: nav_rth_allow_landing + - name: nav_rth_fs_landing_delay + description: "If landing is active on Failsafe and this is above 0. The aircraft will hover or loiter for X seconds before performing the landing. If the battery enters the warning or critical levels, the land will proceed. Default = 0 [seconds]" + default_value: 0 + min: 0 + max: 1800 + field: general.rth_fs_landing_delay - name: nav_rth_alt_mode description: "Configure how the aircraft will manage altitude on the way home, see Navigation modes on wiki for more details" default_value: "AT_LEAST" @@ -2751,15 +2837,12 @@ groups: field: fw.control_smoothness min: 0 max: 9 - - name: nav_fw_land_dive_angle description: "Dive angle that airplane will use during final landing phase. During dive phase, motor is stopped or IDLE and roll control is locked to 0 degrees" default_value: 2 field: fw.land_dive_angle - condition: NAV_FIXED_WING_LANDING min: -20 max: 20 - - name: nav_fw_launch_velocity description: "Forward velocity threshold for swing-launch detection [cm/s]" default_value: 300 @@ -2836,10 +2919,10 @@ groups: default_value: OFF field: fw.launch_manual_throttle type: bool - - name: nav_fw_launch_abort_deadband - description: "Launch abort stick deadband in [r/c points], applied after r/c deadband and expo. The Roll/Pitch stick needs to be deflected beyond this deadband to abort the launch." + - name: nav_fw_launch_land_abort_deadband + description: "Launch and landing abort stick deadband in [r/c points], applied after r/c deadband and expo. The Roll/Pitch stick needs to be deflected beyond this deadband to abort the launch or landing." default_value: 100 - field: fw.launch_abort_deadband + field: fw.launch_land_abort_deadband min: 2 max: 250 - name: nav_fw_allow_manual_thr_increase @@ -3493,66 +3576,95 @@ groups: max: 6 default_value: 3 - - name: osd_mah_used_precision - description: Number of digits used to display mAh used. - field: mAh_used_precision + - name: osd_mah_precision + description: Number of digits used for mAh precision. Currently used by mAh Used and Battery Remaining Capacity + field: mAh_precision min: 4 max: 6 default_value: 4 + - name: osd_use_pilot_logo + description: Use custom pilot logo with/instead of the INAV logo. The pilot logo must be characters 473 to 511 + field: use_pilot_logo + type: bool + default_value: OFF + + - name: osd_inav_to_pilot_logo_spacing + description: The space between the INAV and pilot logos, if `osd_use_pilot_logo` is `ON`. This number may be adjusted so that it fits the odd/even col width displays. For example, if using an odd column width display, such as Walksnail, and this is set to 4. 1 will be added so that the logos are equally spaced from the centre of the screen. + field: inav_to_pilot_logo_spacing + min: 0 + max: 20 + default_value: 8 + + - name: osd_arm_screen_display_time + description: Amount of time to display the arm screen [ms] + field: arm_screen_display_time + min: 1000 + max: 5000 + default_value: 1500 + - name: osd_switch_indicator_zero_name description: "Character to use for OSD switch incicator 0." field: osd_switch_indicator0_name type: string max: 5 default_value: "FLAP" + - name: osd_switch_indicator_one_name description: "Character to use for OSD switch incicator 1." field: osd_switch_indicator1_name type: string max: 5 default_value: "GEAR" + - name: osd_switch_indicator_two_name description: "Character to use for OSD switch incicator 2." field: osd_switch_indicator2_name type: string max: 5 default_value: "CAM" + - name: osd_switch_indicator_three_name description: "Character to use for OSD switch incicator 3." field: osd_switch_indicator3_name type: string max: 5 default_value: "LIGT" + - name: osd_switch_indicator_zero_channel description: "RC Channel to use for OSD switch indicator 0." field: osd_switch_indicator0_channel min: 5 max: MAX_SUPPORTED_RC_CHANNEL_COUNT default_value: 5 + - name: osd_switch_indicator_one_channel description: "RC Channel to use for OSD switch indicator 1." field: osd_switch_indicator1_channel min: 5 max: MAX_SUPPORTED_RC_CHANNEL_COUNT default_value: 5 + - name: osd_switch_indicator_two_channel description: "RC Channel to use for OSD switch indicator 2." field: osd_switch_indicator2_channel min: 5 max: MAX_SUPPORTED_RC_CHANNEL_COUNT default_value: 5 + - name: osd_switch_indicator_three_channel description: "RC Channel to use for OSD switch indicator 3." field: osd_switch_indicator3_channel min: 5 max: MAX_SUPPORTED_RC_CHANNEL_COUNT default_value: 5 + - name: osd_switch_indicators_align_left description: "Align text to left of switch indicators" field: osd_switch_indicators_align_left type: bool default_value: ON + - name: osd_system_msg_display_time description: System message display cycle time for multiple messages (milliseconds). field: system_msg_display_time @@ -3714,10 +3826,10 @@ groups: condition: USE_VTX_SMARTAUDIO || USE_VTX_TRAMP members: - name: vtx_band - description: "Configure the VTX band. Set to zero to use `vtx_freq`. Bands: 1: A, 2: B, 3: E, 4: F, 5: Race." + description: "Configure the VTX band. Bands: 1: A, 2: B, 3: E, 4: F, 5: Race." default_value: 1 field: band - min: VTX_SETTINGS_NO_BAND + min: VTX_SETTINGS_MIN_BAND max: VTX_SETTINGS_MAX_BAND - name: vtx_channel description: "Channel to use within the configured `vtx_band`. Valid values are [1, 8]." @@ -3926,3 +4038,103 @@ groups: default_value: 1.2 field: attnFilterCutoff max: 100 + + - name: PG_LEDPIN_CONFIG + type: ledPinConfig_t + headers: ["drivers/light_ws2811strip.h"] + members: + - name: led_pin_pwm_mode + condition: USE_LED_STRIP + description: "PWM mode of LED pin." + default_value: "SHARED_LOW" + field: led_pin_pwm_mode + table: led_pin_pwm_mode + + - name: PG_OSD_JOYSTICK_CONFIG + type: osdJoystickConfig_t + headers: ["io/osd_joystick.h"] + condition: USE_RCDEVICE && USE_LED_STRIP + members: + - name: osd_joystick_enabled + description: "Enable OSD Joystick emulation" + default_value: OFF + field: osd_joystick_enabled + type: bool + - name: osd_joystick_down + description: "PWM value for DOWN key" + default_value: 0 + field: osd_joystick_down + min: 0 + max: 100 + - name: osd_joystick_up + description: "PWM value for UP key" + default_value: 48 + field: osd_joystick_up + min: 0 + max: 100 + - name: osd_joystick_left + description: "PWM value for LEFT key" + default_value: 63 + field: osd_joystick_left + min: 0 + max: 100 + - name: osd_joystick_right + description: "PWM value for RIGHT key" + default_value: 28 + field: osd_joystick_right + min: 0 + max: 100 + - name: osd_joystick_enter + description: "PWM value for ENTER key" + default_value: 75 + field: osd_joystick_enter + min: 0 + max: 100 + + - name: PG_FW_AUTOLAND_CONFIG + type: navFwAutolandConfig_t + headers: ["navigation/navigation.h"] + condition: USE_FW_AUTOLAND + members: + - name: nav_fw_land_approach_length + description: "Length of the final approach" + default_value: 35000 + field: approachLength + min: 100 + max: 100000 + - name: nav_fw_land_final_approach_pitch2throttle_mod + description: "Modifier for pitch to throttle ratio at final approach. In Percent." + default_value: 100 + field: finalApproachPitchToThrottleMod + min: 100 + max: 400 + - name: nav_fw_land_glide_alt + description: "Initial altitude of the glide phase" + default_value: 200 + field: glideAltitude + min: 100 + max: 5000 + - name: nav_fw_land_flare_alt + description: "Initial altitude of the flare phase" + default_value: 150 + field: flareAltitude + min: 0 + max: 10000 + - name: nav_fw_land_glide_pitch + description: "Pitch value for glide phase. In degrees." + default_value: 0 + field: glidePitch + min: -15 + max: 45 + - name: nav_fw_land_flare_pitch + description: "Pitch value for flare phase. In degrees" + default_value: 8 + field: flarePitch + min: -15 + max: 45 + - name: nav_fw_land_max_tailwind + description: "Max. tailwind (in cm/s) if no landing direction with downwind is available" + default_value: 140 + field: maxTailwind + min: 0 + max: 3000 diff --git a/src/main/fc/stats.h b/src/main/fc/stats.h index 275460643c3..54b676f6577 100644 --- a/src/main/fc/stats.h +++ b/src/main/fc/stats.h @@ -3,8 +3,8 @@ #ifdef USE_STATS typedef struct statsConfig_s { - uint32_t stats_total_time; // [s] - uint32_t stats_total_dist; // [m] + uint32_t stats_total_time; // [Seconds] + uint32_t stats_total_dist; // [Metres] #ifdef USE_ADC uint32_t stats_total_energy; // deciWatt hour (x0.1Wh) #endif diff --git a/src/main/flight/ez_tune.c b/src/main/flight/ez_tune.c new file mode 100644 index 00000000000..c6c57afbfe5 --- /dev/null +++ b/src/main/flight/ez_tune.c @@ -0,0 +1,143 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#include "fc/config.h" +#include "config/config_reset.h" +#include "config/parameter_group.h" +#include "config/parameter_group_ids.h" + +#include "flight/ez_tune.h" + +#include "fc/settings.h" +#include "flight/pid.h" +#include "sensors/gyro.h" +#include "fc/controlrate_profile.h" + +PG_REGISTER_PROFILE_WITH_RESET_TEMPLATE(ezTuneSettings_t, ezTune, PG_EZ_TUNE, 0); + +PG_RESET_TEMPLATE(ezTuneSettings_t, ezTune, + .enabled = SETTING_EZ_ENABLED_DEFAULT, + .filterHz = SETTING_EZ_FILTER_HZ_DEFAULT, + .axisRatio = SETTING_EZ_AXIS_RATIO_DEFAULT, + .response = SETTING_EZ_RESPONSE_DEFAULT, + .damping = SETTING_EZ_DAMPING_DEFAULT, + .stability = SETTING_EZ_STABILITY_DEFAULT, + .aggressiveness = SETTING_EZ_AGGRESSIVENESS_DEFAULT, + .rate = SETTING_EZ_RATE_DEFAULT, + .expo = SETTING_EZ_EXPO_DEFAULT, +); + +#define EZ_TUNE_PID_RP_DEFAULT { 40, 75, 23, 100 } +#define EZ_TUNE_PID_YAW_DEFAULT { 45, 80, 0, 100 } + +#define EZ_TUNE_YAW_SCALE 0.5f + +static float computePt1FilterDelayMs(uint8_t filterHz) { + return 1000.0f / (2.0f * M_PIf * filterHz); +} + +static float getYawPidScale(float input) { + const float normalized = (input - 100) * 0.01f; + + return 1.0f + (normalized * 0.5f); +} + +/** + * Update INAV settings based on current EZTune settings + * This has to be called every time control profile is changed, or EZTune settings are changed + */ +void ezTuneUpdate(void) { + if (ezTune()->enabled) { + + // Setup filtering + //Set Dterm LPF + pidProfileMutable()->dterm_lpf_hz = MAX(ezTune()->filterHz - 5, 50); + pidProfileMutable()->dterm_lpf_type = FILTER_PT2; + + //Set main gyro filter + gyroConfigMutable()->gyro_main_lpf_hz = ezTune()->filterHz; + gyroConfigMutable()->gyro_main_lpf_type = FILTER_PT1; + + //Set anti-aliasing filter + gyroConfigMutable()->gyro_anti_aliasing_lpf_hz = SETTING_GYRO_ANTI_ALIASING_LPF_HZ_DEFAULT; + gyroConfigMutable()->gyro_anti_aliasing_lpf_type = FILTER_PT1; + + //Enable Smith predictor + pidProfileMutable()->smithPredictorDelay = computePt1FilterDelayMs(ezTune()->filterHz); + +#ifdef USE_DYNAMIC_FILTERS + //Enable dynamic notch + gyroConfigMutable()->dynamicGyroNotchEnabled = 1; + gyroConfigMutable()->dynamicGyroNotchQ = 250; + gyroConfigMutable()->dynamicGyroNotchMinHz = MAX(ezTune()->filterHz * 0.667f, SETTING_DYNAMIC_GYRO_NOTCH_MIN_HZ_DEFAULT); + gyroConfigMutable()->dynamicGyroNotchMode = DYNAMIC_NOTCH_MODE_3D; +#endif + +#ifdef USE_GYRO_KALMAN + //Make sure Kalman filter is enabled + gyroConfigMutable()->kalmanEnabled = 1; + if (ezTune()->filterHz < 150) { + gyroConfigMutable()->kalman_q = 200; + } else { + gyroConfigMutable()->kalman_q = scaleRangef(ezTune()->filterHz, 150, 300, 200, 400); + } +#endif + + //Disable dynamic LPF + gyroConfigMutable()->useDynamicLpf = 0; + + //Setup PID controller + + const uint8_t pidDefaults[4] = EZ_TUNE_PID_RP_DEFAULT; + const uint8_t pidDefaultsYaw[4] = EZ_TUNE_PID_YAW_DEFAULT; + const float pitchRatio = ezTune()->axisRatio / 100.0f; + + //Roll + pidProfileMutable()->bank_mc.pid[PID_ROLL].P = pidDefaults[0] * ezTune()->response / 100.0f; + pidProfileMutable()->bank_mc.pid[PID_ROLL].I = pidDefaults[1] * ezTune()->stability / 100.0f; + pidProfileMutable()->bank_mc.pid[PID_ROLL].D = pidDefaults[2] * ezTune()->damping / 100.0f; + pidProfileMutable()->bank_mc.pid[PID_ROLL].FF = pidDefaults[3] * ezTune()->aggressiveness / 100.0f; + + //Pitch + pidProfileMutable()->bank_mc.pid[PID_PITCH].P = pidDefaults[0] * ezTune()->response / 100.0f * pitchRatio; + pidProfileMutable()->bank_mc.pid[PID_PITCH].I = pidDefaults[1] * ezTune()->stability / 100.0f * pitchRatio; + pidProfileMutable()->bank_mc.pid[PID_PITCH].D = pidDefaults[2] * ezTune()->damping / 100.0f * pitchRatio; + pidProfileMutable()->bank_mc.pid[PID_PITCH].FF = pidDefaults[3] * ezTune()->aggressiveness / 100.0f * pitchRatio; + + //Yaw + pidProfileMutable()->bank_mc.pid[PID_YAW].P = pidDefaultsYaw[0] * getYawPidScale(ezTune()->response); + pidProfileMutable()->bank_mc.pid[PID_YAW].I = pidDefaultsYaw[1] * getYawPidScale(ezTune()->stability); + pidProfileMutable()->bank_mc.pid[PID_YAW].D = pidDefaultsYaw[2] * getYawPidScale(ezTune()->damping); + pidProfileMutable()->bank_mc.pid[PID_YAW].FF = pidDefaultsYaw[3] * getYawPidScale(ezTune()->aggressiveness); + + //Setup rates + ((controlRateConfig_t*)currentControlRateProfile)->stabilized.rates[FD_ROLL] = scaleRange(ezTune()->rate, 0, 200, 30, 90); + ((controlRateConfig_t*)currentControlRateProfile)->stabilized.rates[FD_PITCH] = scaleRange(ezTune()->rate, 0, 200, 30, 90); + ((controlRateConfig_t*)currentControlRateProfile)->stabilized.rates[FD_YAW] = scaleRange(ezTune()->rate, 0, 200, 30, 90) - 10; + + ((controlRateConfig_t*)currentControlRateProfile)->stabilized.rcExpo8 = scaleRange(ezTune()->rate, 0, 200, 40, 100); + ((controlRateConfig_t*)currentControlRateProfile)->stabilized.rcYawExpo8 = scaleRange(ezTune()->rate, 0, 200, 40, 100); + + } +} \ No newline at end of file diff --git a/src/main/flight/ez_tune.h b/src/main/flight/ez_tune.h new file mode 100644 index 00000000000..5fcc1ef6f7f --- /dev/null +++ b/src/main/flight/ez_tune.h @@ -0,0 +1,43 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#pragma once + +#include "config/parameter_group.h" + +typedef struct ezTuneSettings_s { + uint8_t enabled; + uint16_t filterHz; + uint8_t axisRatio; + uint8_t response; + uint8_t damping; + uint8_t stability; + uint8_t aggressiveness; + uint8_t rate; + uint8_t expo; +} ezTuneSettings_t; + +PG_DECLARE_PROFILE(ezTuneSettings_t, ezTune); + +void ezTuneUpdate(void); \ No newline at end of file diff --git a/src/main/flight/failsafe.c b/src/main/flight/failsafe.c index 36f4d86f8e2..9f60dd83a36 100644 --- a/src/main/flight/failsafe.c +++ b/src/main/flight/failsafe.c @@ -239,6 +239,10 @@ static void failsafeActivate(failsafePhase_e newPhase) ENABLE_FLIGHT_MODE(FAILSAFE_MODE); failsafeState.landingShouldBeFinishedAt = millis() + failsafeConfig()->failsafe_off_delay * MILLIS_PER_TENTH_SECOND; +#ifdef USE_FW_AUTOLAND + posControl.fwLandState.landAborted = false; +#endif + failsafeState.events++; } diff --git a/src/main/flight/imu.c b/src/main/flight/imu.c index c9d0f0aacbf..a76a5dd9884 100644 --- a/src/main/flight/imu.c +++ b/src/main/flight/imu.c @@ -49,6 +49,7 @@ #include "flight/imu.h" #include "flight/mixer.h" +#include "flight/mixer_profile.h" #include "flight/pid.h" #if defined(USE_WIND_ESTIMATOR) #include "flight/wind_estimator.h" @@ -77,6 +78,9 @@ #define SPIN_RATE_LIMIT 20 #define MAX_ACC_NEARNESS 0.2 // 20% or G error soft-accepted (0.8-1.2G) +#define MAX_MAG_NEARNESS 0.25 // 25% or magnetic field error soft-accepted (0.75-1.25) +#define COS10DEG 0.985f +#define COS20DEG 0.940f #define IMU_ROTATION_LPF 3 // Hz FASTRAM fpVector3_t imuMeasuredAccelBF; FASTRAM fpVector3_t imuMeasuredRotationBF; @@ -111,6 +115,8 @@ FASTRAM bool gpsHeadingInitialized; FASTRAM bool imuUpdated = false; +static float imuCalculateAccelerometerWeightNearness(fpVector3_t* accBF); + PG_REGISTER_WITH_RESET_TEMPLATE(imuConfig_t, imuConfig, PG_IMU_CONFIG, 2); PG_RESET_TEMPLATE(imuConfig_t, imuConfig, @@ -122,7 +128,8 @@ PG_RESET_TEMPLATE(imuConfig_t, imuConfig, .acc_ignore_rate = SETTING_AHRS_ACC_IGNORE_RATE_DEFAULT, .acc_ignore_slope = SETTING_AHRS_ACC_IGNORE_SLOPE_DEFAULT, .gps_yaw_windcomp = SETTING_AHRS_GPS_YAW_WINDCOMP_DEFAULT, - .inertia_comp_method = SETTING_AHRS_INERTIA_COMP_METHOD_DEFAULT + .inertia_comp_method = SETTING_AHRS_INERTIA_COMP_METHOD_DEFAULT, + .gps_yaw_weight = SETTING_AHRS_GPS_YAW_WEIGHT_DEFAULT ); STATIC_UNIT_TESTED void imuComputeRotationMatrix(void) @@ -326,6 +333,15 @@ bool isGPSTrustworthy(void) return sensors(SENSOR_GPS) && STATE(GPS_FIX) && gpsSol.numSat >= 6; } +static float imuCalculateMcCogWeight(void) +{ + float wCoG = imuCalculateAccelerometerWeightNearness(&imuMeasuredAccelBF); + float rotRateMagnitude = fast_fsqrtf(vectorNormSquared(&imuMeasuredRotationBFFiltered)); + const float rateSlopeMax = DEGREES_TO_RADIANS((imuConfig()->acc_ignore_rate)) * 4.0f; + wCoG *= scaleRangef(constrainf(rotRateMagnitude, 0.0f, rateSlopeMax), 0.0f, rateSlopeMax, 1.0f, 0.0f); + return wCoG; +} + static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVector3_t * accBF, const fpVector3_t * magBF, bool useCOG, float courseOverGround, float accWScaler, float magWScaler) { STATIC_FASTRAM fpVector3_t vGyroDriftEstimate = { 0 }; @@ -339,11 +355,15 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe /* Step 1: Yaw correction */ // Use measured magnetic field vector if (magBF || useCOG) { - static const fpVector3_t vForward = { .v = { 1.0f, 0.0f, 0.0f } }; + float wMag = 1.0f; + float wCoG = 1.0f; + if(magBF){wCoG *= imuConfig()->gps_yaw_weight / 100.0f;} - fpVector3_t vErr = { .v = { 0.0f, 0.0f, 0.0f } }; + fpVector3_t vMagErr = { .v = { 0.0f, 0.0f, 0.0f } }; + fpVector3_t vCoGErr = { .v = { 0.0f, 0.0f, 0.0f } }; if (magBF && vectorNormSquared(magBF) > 0.01f) { + wMag *= bellCurve((fast_fsqrtf(vectorNormSquared(magBF)) - 1024.0f) / 1024.0f, MAX_MAG_NEARNESS); fpVector3_t vMag; // For magnetometer correction we make an assumption that magnetic field is perpendicular to gravity (ignore Z-component in EF). @@ -369,13 +389,20 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe // Reference mag field vector heading is Magnetic North in EF. We compute that by rotating True North vector by declination and assuming Z-component is zero // magnetometer error is cross product between estimated magnetic north and measured magnetic north (calculated in EF) - vectorCrossProduct(&vErr, &vMag, &vCorrectedMagNorth); + vectorCrossProduct(&vMagErr, &vMag, &vCorrectedMagNorth); // Rotate error back into body frame - quaternionRotateVector(&vErr, &vErr, &orientation); + quaternionRotateVector(&vMagErr, &vMagErr, &orientation); } } - else if (useCOG) { + if (useCOG) { + fpVector3_t vForward = { .v = { 0.0f, 0.0f, 0.0f } }; + //vForward as trust vector + if (STATE(MULTIROTOR) && (!isMixerTransitionMixing)){ + vForward.z = 1.0f; + }else{ + vForward.x = 1.0f; + } fpVector3_t vHeadingEF; // Use raw heading error (from GPS or whatever else) @@ -386,6 +413,7 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe // (Rxx; Ryx) - measured (estimated) heading vector (EF) // (-cos(COG), sin(COG)) - reference heading vector (EF) + float airSpeed = gpsSol.groundSpeed; // Compute heading vector in EF from scalar CoG,x axis of accelerometer is pointing backwards. fpVector3_t vCoG = { .v = { -cos_approx(courseOverGround), sin_approx(courseOverGround), 0.0f } }; #if defined(USE_WIND_ESTIMATOR) @@ -395,12 +423,21 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe vectorScale(&vCoG, &vCoG, gpsSol.groundSpeed); vCoG.x += getEstimatedWindSpeed(X); vCoG.y -= getEstimatedWindSpeed(Y); + airSpeed = fast_fsqrtf(vectorNormSquared(&vCoG)); vectorNormalize(&vCoG, &vCoG); } #endif - + wCoG *= scaleRangef(constrainf((airSpeed+gpsSol.groundSpeed)/2, 400, 1000), 400, 1000, 0.0f, 1.0f); // Rotate Forward vector from BF to EF - will yield Heading vector in Earth frame quaternionRotateVectorInv(&vHeadingEF, &vForward, &orientation); + + if (STATE(MULTIROTOR)){ + //when multicopter`s orientation or speed is changing rapidly. less weight on gps heading + wCoG *= imuCalculateMcCogWeight(); + //scale accroading to multirotor`s tilt angle + wCoG *= scaleRangef(constrainf(vHeadingEF.z, COS20DEG, COS10DEG), COS20DEG, COS10DEG, 1.0f, 0.0f); + //for inverted flying, wCoG is lowered by imuCalculateMcCogWeight no additional processing needed + } vHeadingEF.z = 0.0f; // We zeroed out vHeadingEF.z - make sure the whole vector didn't go to zero @@ -409,13 +446,16 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe vectorNormalize(&vHeadingEF, &vHeadingEF); // error is cross product between reference heading and estimated heading (calculated in EF) - vectorCrossProduct(&vErr, &vCoG, &vHeadingEF); + vectorCrossProduct(&vCoGErr, &vCoG, &vHeadingEF); // Rotate error back into body frame - quaternionRotateVector(&vErr, &vErr, &orientation); + quaternionRotateVector(&vCoGErr, &vCoGErr, &orientation); } } - + fpVector3_t vErr = { .v = { 0.0f, 0.0f, 0.0f } }; + vectorScale(&vMagErr, &vMagErr, wMag); + vectorScale(&vCoGErr, &vCoGErr, wCoG); + vectorAdd(&vErr, &vMagErr, &vCoGErr); // Compute and apply integral feedback if enabled if (imuRuntimeConfig.dcm_ki_mag > 0.0f) { // Stop integrating if spinning beyond the certain limit @@ -535,10 +575,10 @@ STATIC_UNIT_TESTED void imuUpdateEulerAngles(void) } } -static float imuCalculateAccelerometerWeightNearness(void) +static float imuCalculateAccelerometerWeightNearness(fpVector3_t* accBF) { fpVector3_t accBFNorm; - vectorScale(&accBFNorm, &compansatedGravityBF, 1.0f / GRAVITY_CMSS); + vectorScale(&accBFNorm, accBF, 1.0f / GRAVITY_CMSS); const float accMagnitudeSq = vectorNormSquared(&accBFNorm); const float accWeight_Nearness = bellCurve(fast_fsqrtf(accMagnitudeSq) - 1.0f, MAX_ACC_NEARNESS); return accWeight_Nearness; @@ -660,6 +700,33 @@ static void imuCalculateTurnRateacceleration(fpVector3_t *vEstcentrifugalAccelBF lastspeed = currentspeed; } +fpQuaternion_t* getTailSitterQuaternion(bool normal2tail){ + static bool firstRun = true; + static fpQuaternion_t qNormal2Tail; + static fpQuaternion_t qTail2Normal; + if(firstRun){ + fpAxisAngle_t axisAngle; + axisAngle.axis.x = 0; + axisAngle.axis.y = 1; + axisAngle.axis.z = 0; + axisAngle.angle = DEGREES_TO_RADIANS(-90); + axisAngleToQuaternion(&qNormal2Tail, &axisAngle); + quaternionConjugate(&qTail2Normal, &qNormal2Tail); + firstRun = false; + } + return normal2tail ? &qNormal2Tail : &qTail2Normal; +} + +void imuUpdateTailSitter(void) +{ + static bool lastTailSitter=false; + if (((bool)STATE(TAILSITTER)) != lastTailSitter){ + fpQuaternion_t* rotation_for_tailsitter= getTailSitterQuaternion(STATE(TAILSITTER)); + quaternionMultiply(&orientation, &orientation, rotation_for_tailsitter); + } + lastTailSitter = STATE(TAILSITTER); +} + static void imuCalculateEstimatedAttitude(float dT) { #if defined(USE_MAG) @@ -672,36 +739,29 @@ static void imuCalculateEstimatedAttitude(float dT) bool useMag = false; bool useCOG = false; #if defined(USE_GPS) - if (STATE(FIXED_WING_LEGACY)) { - bool canUseCOG = isGPSHeadingValid(); + bool canUseCOG = isGPSHeadingValid(); - // Prefer compass (if available) - if (canUseMAG) { - useMag = true; - gpsHeadingInitialized = true; // GPS heading initialised from MAG, continue on GPS if compass fails + // Use compass (if available) + if (canUseMAG) { + useMag = true; + gpsHeadingInitialized = true; // GPS heading initialised from MAG, continue on GPS if compass fails + } + // Use GPS (if available) + if (canUseCOG) { + if (gpsHeadingInitialized) { + courseOverGround = DECIDEGREES_TO_RADIANS(gpsSol.groundCourse); + useCOG = true; } - else if (canUseCOG) { - if (gpsHeadingInitialized) { - courseOverGround = DECIDEGREES_TO_RADIANS(gpsSol.groundCourse); - useCOG = true; - } - else { - // Re-initialize quaternion from known Roll, Pitch and GPS heading - imuComputeQuaternionFromRPY(attitude.values.roll, attitude.values.pitch, gpsSol.groundCourse); - gpsHeadingInitialized = true; + else if (!canUseMAG) { + // Re-initialize quaternion from known Roll, Pitch and GPS heading + imuComputeQuaternionFromRPY(attitude.values.roll, attitude.values.pitch, gpsSol.groundCourse); + gpsHeadingInitialized = true; - // Force reset of heading hold target - resetHeadingHoldTarget(DECIDEGREES_TO_DEGREES(attitude.values.yaw)); - } - } else if (!ARMING_FLAG(ARMED)) { - gpsHeadingInitialized = false; - } - } - else { - // Multicopters don't use GPS heading - if (canUseMAG) { - useMag = true; + // Force reset of heading hold target + resetHeadingHoldTarget(DECIDEGREES_TO_DEGREES(attitude.values.yaw)); } + } else if (!ARMING_FLAG(ARMED)) { + gpsHeadingInitialized = false; } imuCalculateFilters(dT); @@ -719,28 +779,25 @@ static void imuCalculateEstimatedAttitude(float dT) } if (imuConfig()->inertia_comp_method == COMPMETHOD_ADAPTIVE && isGPSTrustworthy() && STATE(AIRPLANE)) { + //pick the best centrifugal acceleration between velned and turnrate fpVector3_t compansatedGravityBF_velned; vectorAdd(&compansatedGravityBF_velned, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned); - float velned_magnitude = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_velned)) - GRAVITY_CMSS); + float velned_error = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_velned)) - GRAVITY_CMSS); fpVector3_t compansatedGravityBF_turnrate; vectorAdd(&compansatedGravityBF_turnrate, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate); - float turnrate_magnitude = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_turnrate)) - GRAVITY_CMSS); - if (velned_magnitude > turnrate_magnitude) - { - compansatedGravityBF = compansatedGravityBF_turnrate; - } - else - { - compansatedGravityBF = compansatedGravityBF_velned; - } + float turnrate_error = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_turnrate)) - GRAVITY_CMSS); + + compansatedGravityBF = velned_error > turnrate_error? compansatedGravityBF_turnrate:compansatedGravityBF_velned; } - else if (imuConfig()->inertia_comp_method == COMPMETHOD_VELNED && isGPSTrustworthy()) + else if (((imuConfig()->inertia_comp_method == COMPMETHOD_VELNED) || (imuConfig()->inertia_comp_method == COMPMETHOD_ADAPTIVE)) && isGPSTrustworthy()) { + //velned centrifugal force compensation, quad will use this method vectorAdd(&compansatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned); } else if (STATE(AIRPLANE)) { + //turnrate centrifugal force compensation vectorAdd(&compansatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate); } else @@ -754,7 +811,7 @@ static void imuCalculateEstimatedAttitude(float dT) } compansatedGravityBF = imuMeasuredAccelBF #endif - float accWeight = imuGetPGainScaleFactor() * imuCalculateAccelerometerWeightNearness(); + float accWeight = imuGetPGainScaleFactor() * imuCalculateAccelerometerWeightNearness(&compansatedGravityBF); accWeight = accWeight * imuCalculateAccelerometerWeightRateIgnore(acc_ignore_slope_multipiler); const bool useAcc = (accWeight > 0.001f); @@ -766,6 +823,7 @@ static void imuCalculateEstimatedAttitude(float dT) useCOG, courseOverGround, accWeight, magWeight); + imuUpdateTailSitter(); imuUpdateEulerAngles(); } @@ -809,6 +867,7 @@ void imuUpdateAttitude(timeUs_t currentTimeUs) acc.accADCf[Z] = 0.0f; } } + bool isImuReady(void) { @@ -817,7 +876,7 @@ bool isImuReady(void) bool isImuHeadingValid(void) { - return (sensors(SENSOR_MAG) && STATE(COMPASS_CALIBRATED)) || (STATE(FIXED_WING_LEGACY) && gpsHeadingInitialized); + return (sensors(SENSOR_MAG) && STATE(COMPASS_CALIBRATED)) || gpsHeadingInitialized; } float calculateCosTiltAngle(void) diff --git a/src/main/flight/imu.h b/src/main/flight/imu.h index a3b87e67360..8afcc50e579 100644 --- a/src/main/flight/imu.h +++ b/src/main/flight/imu.h @@ -54,6 +54,7 @@ typedef struct imuConfig_s { uint8_t acc_ignore_slope; uint8_t gps_yaw_windcomp; uint8_t inertia_comp_method; + uint16_t gps_yaw_weight; } imuConfig_t; PG_DECLARE(imuConfig_t, imuConfig); diff --git a/src/main/flight/mixer.c b/src/main/flight/mixer.c index 35674c1f5dc..834841e6580 100644 --- a/src/main/flight/mixer.c +++ b/src/main/flight/mixer.c @@ -161,6 +161,7 @@ void mixerUpdateStateFlags(void) DISABLE_STATE(BOAT); DISABLE_STATE(AIRPLANE); DISABLE_STATE(MOVE_FORWARD_ONLY); + DISABLE_STATE(TAILSITTER); if (currentMixerConfig.platformType == PLATFORM_AIRPLANE) { ENABLE_STATE(FIXED_WING_LEGACY); @@ -186,6 +187,12 @@ void mixerUpdateStateFlags(void) ENABLE_STATE(ALTITUDE_CONTROL); } + if (currentMixerConfig.tailsitterOrientationOffset) { + ENABLE_STATE(TAILSITTER); + } else { + DISABLE_STATE(TAILSITTER); + } + if (currentMixerConfig.hasFlaps) { ENABLE_STATE(FLAPERON_AVAILABLE); } else { diff --git a/src/main/flight/mixer_profile.c b/src/main/flight/mixer_profile.c index 3b0b1fd18f3..7b2590ff70b 100644 --- a/src/main/flight/mixer_profile.c +++ b/src/main/flight/mixer_profile.c @@ -23,6 +23,7 @@ #include "fc/runtime_config.h" #include "fc/settings.h" #include "fc/rc_modes.h" +#include "fc/cli.h" #include "programming/logic_condition.h" #include "navigation/navigation.h" @@ -34,7 +35,7 @@ int currentMixerProfileIndex; bool isMixerTransitionMixing; bool isMixerTransitionMixing_requested; mixerProfileAT_t mixerProfileAT; -int nextProfileIndex; +int nextMixerProfileIndex; PG_REGISTER_ARRAY_WITH_RESET_FN(mixerProfile_t, MAX_MIXER_PROFILE_COUNT, mixerProfiles, PG_MIXER_PROFILE, 1); @@ -52,6 +53,7 @@ void pgResetFn_mixerProfiles(mixerProfile_t *instance) .PIDProfileLinking = SETTING_MIXER_PID_PROFILE_LINKING_DEFAULT, .automated_switch = SETTING_MIXER_AUTOMATED_SWITCH_DEFAULT, .switchTransitionTimer = SETTING_MIXER_SWITCH_TRANS_TIMER_DEFAULT, + .tailsitterOrientationOffset = SETTING_TAILSITTER_ORIENTATION_OFFSET_DEFAULT, }); for (int j = 0; j < MAX_SUPPORTED_MOTORS; j++) { @@ -77,11 +79,15 @@ void pgResetFn_mixerProfiles(mixerProfile_t *instance) } } -void mixerConfigInit(void) -{ +void activateMixerConfig(){ currentMixerProfileIndex = getConfigMixerProfile(); currentMixerConfig = *mixerConfig(); - nextProfileIndex = (currentMixerProfileIndex + 1) % MAX_MIXER_PROFILE_COUNT; + nextMixerProfileIndex = (currentMixerProfileIndex + 1) % MAX_MIXER_PROFILE_COUNT; +} + +void mixerConfigInit(void) +{ + activateMixerConfig(); servosInit(); mixerUpdateStateFlags(); mixerInit(); @@ -103,6 +109,14 @@ void setMixerProfileAT(void) mixerProfileAT.transitionTransEndTime = mixerProfileAT.transitionStartTime + (timeMs_t)currentMixerConfig.switchTransitionTimer * 100; } +bool platformTypeConfigured(flyingPlatformType_e platformType) +{ + if (!isModeActivationConditionPresent(BOXMIXERPROFILE)){ + return false; + } + return mixerConfigByIndex(nextMixerProfileIndex)->platformType == platformType; +} + bool checkMixerATRequired(mixerProfileATRequest_e required_action) { //return false if mixerAT condition is not required or setting is not valid @@ -158,7 +172,7 @@ bool mixerATUpdateState(mixerProfileATRequest_e required_action) isMixerTransitionMixing_requested = true; if (millis() > mixerProfileAT.transitionTransEndTime){ isMixerTransitionMixing_requested = false; - outputProfileHotSwitch(nextProfileIndex); + outputProfileHotSwitch(nextMixerProfileIndex); mixerProfileAT.phase = MIXERAT_PHASE_IDLE; reprocessState = true; //transition is done @@ -183,8 +197,9 @@ bool checkMixerProfileHotSwitchAvalibility(void) } void outputProfileUpdateTask(timeUs_t currentTimeUs) -{ +{ UNUSED(currentTimeUs); + if(cliMode) return; bool mixerAT_inuse = mixerProfileAT.phase != MIXERAT_PHASE_IDLE; // transition mode input for servo mix and motor mix if (!FLIGHT_MODE(FAILSAFE_MODE) && (!mixerAT_inuse)) diff --git a/src/main/flight/mixer_profile.h b/src/main/flight/mixer_profile.h index cb040665ce8..947ca701553 100644 --- a/src/main/flight/mixer_profile.h +++ b/src/main/flight/mixer_profile.h @@ -18,6 +18,7 @@ typedef struct mixerConfig_s { bool PIDProfileLinking; bool automated_switch; int16_t switchTransitionTimer; + bool tailsitterOrientationOffset; } mixerConfig_t; typedef struct mixerProfile_s { mixerConfig_t mixer_config; @@ -54,6 +55,7 @@ bool mixerATUpdateState(mixerProfileATRequest_e required_action); extern mixerConfig_t currentMixerConfig; extern int currentMixerProfileIndex; +extern int nextMixerProfileIndex; extern bool isMixerTransitionMixing; #define mixerConfig() (&(mixerProfiles(systemConfig()->current_mixer_profile_index)->mixer_config)) #define mixerConfigMutable() ((mixerConfig_t *) mixerConfig()) @@ -71,7 +73,9 @@ static inline const mixerProfile_t* mixerProfiles_CopyArray_by_index(int _index) #define mixerMotorMixersByIndex(index) (mixerProfiles(index)->MotorMixers) #define mixerServoMixersByIndex(index) (mixerProfiles(index)->ServoMixers) +bool platformTypeConfigured(flyingPlatformType_e platformType); bool outputProfileHotSwitch(int profile_index); bool checkMixerProfileHotSwitchAvalibility(void); +void activateMixerConfig(void); void mixerConfigInit(void); void outputProfileUpdateTask(timeUs_t currentTimeUs); \ No newline at end of file diff --git a/src/main/flight/pid.c b/src/main/flight/pid.c index 2bb4ab70358..3da150e39dc 100644 --- a/src/main/flight/pid.c +++ b/src/main/flight/pid.c @@ -159,9 +159,11 @@ typedef void (*pidControllerFnPtr)(pidState_t *pidState, flight_dynamics_index_t static EXTENDED_FASTRAM pidControllerFnPtr pidControllerApplyFn; static EXTENDED_FASTRAM filterApplyFnPtr dTermLpfFilterApplyFn; static EXTENDED_FASTRAM bool levelingEnabled = false; +static EXTENDED_FASTRAM bool restartAngleHoldMode = true; +static EXTENDED_FASTRAM bool angleHoldIsLevel = false; #define FIXED_WING_LEVEL_TRIM_MAX_ANGLE 10.0f // Max angle auto trimming can demand -#define FIXED_WING_LEVEL_TRIM_DIVIDER 500.0f +#define FIXED_WING_LEVEL_TRIM_DIVIDER 50.0f #define FIXED_WING_LEVEL_TRIM_MULTIPLIER 1.0f / FIXED_WING_LEVEL_TRIM_DIVIDER #define FIXED_WING_LEVEL_TRIM_CONTROLLER_LIMIT FIXED_WING_LEVEL_TRIM_DIVIDER * FIXED_WING_LEVEL_TRIM_MAX_ANGLE @@ -264,8 +266,8 @@ PG_RESET_TEMPLATE(pidProfile_t, pidProfile, .max_angle_inclination[FD_PITCH] = SETTING_MAX_ANGLE_INCLINATION_PIT_DEFAULT, .pidSumLimit = SETTING_PIDSUM_LIMIT_DEFAULT, .pidSumLimitYaw = SETTING_PIDSUM_LIMIT_YAW_DEFAULT, + .pidItermLimitPercent = SETTING_PID_ITERM_LIMIT_PERCENT_DEFAULT, - .fixedWingItermThrowLimit = SETTING_FW_ITERM_THROW_LIMIT_DEFAULT, .fixedWingReferenceAirspeed = SETTING_FW_REFERENCE_AIRSPEED_DEFAULT, .fixedWingCoordinatedYawGain = SETTING_FW_TURN_ASSIST_YAW_GAIN_DEFAULT, .fixedWingCoordinatedPitchGain = SETTING_FW_TURN_ASSIST_PITCH_GAIN_DEFAULT, @@ -531,7 +533,7 @@ void updatePIDCoefficients(void) pidState[axis].kT = 0.0f; } else { - const float axisTPA = (axis == FD_YAW) ? 1.0f : tpaFactor; + const float axisTPA = (axis == FD_YAW && (!currentControlRateProfile->throttle.dynPID_on_YAW)) ? 1.0f : tpaFactor; pidState[axis].kP = pidBank()->pid[axis].P / FP_PID_RATE_P_MULTIPLIER * axisTPA; pidState[axis].kI = pidBank()->pid[axis].I / FP_PID_RATE_I_MULTIPLIER; pidState[axis].kD = pidBank()->pid[axis].D / FP_PID_RATE_D_MULTIPLIER * axisTPA; @@ -584,10 +586,18 @@ int16_t angleFreefloatDeadband(int16_t deadband, flight_dynamics_index_t axis) static float computePidLevelTarget(flight_dynamics_index_t axis) { // This is ROLL/PITCH, run ANGLE/HORIZON controllers +#ifdef USE_PROGRAMMING_FRAMEWORK + float angleTarget = pidRcCommandToAngle(getRcCommandOverride(rcCommand, axis), pidProfile()->max_angle_inclination[axis]); +#else float angleTarget = pidRcCommandToAngle(rcCommand[axis], pidProfile()->max_angle_inclination[axis]); +#endif // Automatically pitch down if the throttle is manually controlled and reduced bellow cruise throttle +#ifdef USE_FW_AUTOLAND + if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle() && !FLIGHT_MODE(NAV_FW_AUTOLAND)) { +#else if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle()) { +#endif angleTarget += scaleRange(MAX(0, currentBatteryProfile->nav.fw.cruise_throttle - rcCommand[THROTTLE]), 0, currentBatteryProfile->nav.fw.cruise_throttle - PWM_RANGE_MIN, 0, navConfig()->fw.minThrottleDownPitchAngle); } @@ -762,8 +772,9 @@ static void NOINLINE pidApplyFixedWingRateController(pidState_t *pidState, fligh applyItermLimiting(pidState); - if (pidProfile()->fixedWingItermThrowLimit != 0) { - pidState->errorGyroIf = constrainf(pidState->errorGyroIf, -pidProfile()->fixedWingItermThrowLimit, pidProfile()->fixedWingItermThrowLimit); + if (pidProfile()->pidItermLimitPercent != 0){ + float itermLimit = pidState->pidSumLimit * pidProfile()->pidItermLimitPercent * 0.01f; + pidState->errorGyroIf = constrainf(pidState->errorGyroIf, -itermLimit, +itermLimit); } axisPID[axis] = constrainf(newPTerm + newFFTerm + pidState->errorGyroIf + newDTerm, -pidState->pidSumLimit, +pidState->pidSumLimit); @@ -838,6 +849,12 @@ static void FAST_CODE NOINLINE pidApplyMulticopterRateController(pidState_t *pid pidState->errorGyroIf += (itermErrorRate * pidState->kI * antiWindupScaler * dT) + ((newOutputLimited - newOutput) * pidState->kT * antiWindupScaler * dT); + if (pidProfile()->pidItermLimitPercent != 0){ + float itermLimit = pidState->pidSumLimit * pidProfile()->pidItermLimitPercent * 0.01f; + pidState->errorGyroIf = constrainf(pidState->errorGyroIf, -itermLimit, +itermLimit); + } + + // Don't grow I-term if motors are at their limit applyItermLimiting(pidState); @@ -1033,7 +1050,7 @@ void checkItermLimitingActive(pidState_t *pidState) shouldActivate = isFixedWingItermLimitActive(pidState->stickPosition); } else { - shouldActivate = mixerIsOutputSaturated(); + shouldActivate = mixerIsOutputSaturated(); //just in case, since it is already managed by itermWindupPointPercent } pidState->itermLimitActive = STATE(ANTI_WINDUP) || shouldActivate; @@ -1057,9 +1074,62 @@ void checkItermFreezingActive(pidState_t *pidState, flight_dynamics_index_t axis } -void FAST_CODE pidController(float dT) +bool isAngleHoldLevel(void) { + return angleHoldIsLevel; +} + +void updateAngleHold(float *angleTarget, uint8_t axis) +{ + int8_t navAngleHoldAxis = navCheckActiveAngleHoldAxis(); + + if (!restartAngleHoldMode) { // set restart flag when anglehold is inactive + restartAngleHoldMode = !FLIGHT_MODE(ANGLEHOLD_MODE) && navAngleHoldAxis == -1; + } + if ((FLIGHT_MODE(ANGLEHOLD_MODE) || axis == navAngleHoldAxis) && !isFlightAxisAngleOverrideActive(axis)) { + /* angleHoldTarget stores attitude values using a zero datum when level. + * This requires angleHoldTarget pitch to be corrected for fixedWingLevelTrim so it is 0 + * when the craft is level even though attitude pitch is non zero in this case. + * angleTarget pitch is corrected back to fixedWingLevelTrim datum on return from function */ + + static int16_t angleHoldTarget[2]; + + if (restartAngleHoldMode) { // set target attitude to current attitude on activation + angleHoldTarget[FD_ROLL] = attitude.raw[FD_ROLL]; + angleHoldTarget[FD_PITCH] = attitude.raw[FD_PITCH] + DEGREES_TO_DECIDEGREES(fixedWingLevelTrim); + restartAngleHoldMode = false; + } + + // set flag indicating anglehold is level + if (FLIGHT_MODE(ANGLEHOLD_MODE)) { + angleHoldIsLevel = angleHoldTarget[FD_ROLL] == 0 && angleHoldTarget[FD_PITCH] == 0; + } else { + angleHoldIsLevel = angleHoldTarget[navAngleHoldAxis] == 0; + } + + uint16_t bankLimit = pidProfile()->max_angle_inclination[axis]; + + // use Nav bank angle limits if Nav active + if (navAngleHoldAxis == FD_ROLL) { + bankLimit = DEGREES_TO_DECIDEGREES(navConfig()->fw.max_bank_angle); + } else if (navAngleHoldAxis == FD_PITCH) { + bankLimit = DEGREES_TO_DECIDEGREES(navConfig()->fw.max_climb_angle); + } + + int16_t levelTrim = axis == FD_PITCH ? DEGREES_TO_DECIDEGREES(fixedWingLevelTrim) : 0; + if (calculateRollPitchCenterStatus() == CENTERED) { + angleHoldTarget[axis] = ABS(angleHoldTarget[axis]) < 30 ? 0 : angleHoldTarget[axis]; // snap to level when within 3 degs of level + *angleTarget = constrain(angleHoldTarget[axis] - levelTrim, -bankLimit, bankLimit); + } else { + *angleTarget = constrain(attitude.raw[axis] + *angleTarget + levelTrim, -bankLimit, bankLimit); + angleHoldTarget[axis] = attitude.raw[axis] + levelTrim; + } + } +} + +void FAST_CODE pidController(float dT) +{ const float dT_inv = 1.0f / dT; if (!pidFiltersConfigured) { @@ -1072,7 +1142,7 @@ void FAST_CODE pidController(float dT) // In case Yaw override is active, we engage the Heading Hold state if (isFlightAxisAngleOverrideActive(FD_YAW)) { headingHoldState = HEADING_HOLD_ENABLED; - headingHoldTarget = getFlightAxisAngleOverride(FD_YAW, 0); + headingHoldTarget = DECIDEGREES_TO_DEGREES(getFlightAxisAngleOverride(FD_YAW, 0)); } if (headingHoldState == HEADING_HOLD_UPDATE_HEADING) { @@ -1080,7 +1150,6 @@ void FAST_CODE pidController(float dT) } for (int axis = 0; axis < 3; axis++) { - // Step 1: Calculate gyro rates pidState[axis].gyroRate = gyro.gyroADCf[axis]; // Step 2: Read target @@ -1108,21 +1177,35 @@ void FAST_CODE pidController(float dT) #endif } - // Step 3: Run control for ANGLE_MODE, HORIZON_MODE, and HEADING_LOCK - const float horizonRateMagnitude = calcHorizonRateMagnitude(); + // Step 3: Run control for ANGLE_MODE, HORIZON_MODE and ANGLEHOLD_MODE + const float horizonRateMagnitude = FLIGHT_MODE(HORIZON_MODE) ? calcHorizonRateMagnitude() : 0.0f; levelingEnabled = false; + angleHoldIsLevel = false; + for (uint8_t axis = FD_ROLL; axis <= FD_PITCH; axis++) { - if (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE) || isFlightAxisAngleOverrideActive(axis)) { - //If axis angle override, get the correct angle from Logic Conditions + if (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE) || FLIGHT_MODE(ANGLEHOLD_MODE) || isFlightAxisAngleOverrideActive(axis)) { + // If axis angle override, get the correct angle from Logic Conditions float angleTarget = getFlightAxisAngleOverride(axis, computePidLevelTarget(axis)); - //Apply the Level PID controller + //apply 45 deg offset for tailsitter when isMixerTransitionMixing is activated + if (STATE(TAILSITTER) && isMixerTransitionMixing && axis == FD_PITCH){ + angleTarget += DEGREES_TO_DECIDEGREES(45); + } + + if (STATE(AIRPLANE)) { // update anglehold mode + updateAngleHold(&angleTarget, axis); + } + + // Apply the Level PID controller pidLevel(angleTarget, &pidState[axis], axis, horizonRateMagnitude, dT); canUseFpvCameraMix = false; // FPVANGLEMIX is incompatible with ANGLE/HORIZON levelingEnabled = true; + } else { + restartAngleHoldMode = true; } } + // Apply Turn Assistance if ((FLIGHT_MODE(TURN_ASSISTANT) || navigationRequiresTurnAssistance()) && (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE))) { float bankAngleTarget = DECIDEGREES_TO_RADIANS(pidRcCommandToAngle(rcCommand[FD_ROLL], pidProfile()->max_angle_inclination[FD_ROLL])); float pitchAngleTarget = DECIDEGREES_TO_RADIANS(pidRcCommandToAngle(rcCommand[FD_PITCH], pidProfile()->max_angle_inclination[FD_PITCH])); @@ -1130,7 +1213,8 @@ void FAST_CODE pidController(float dT) canUseFpvCameraMix = false; // FPVANGLEMIX is incompatible with TURN_ASSISTANT } - if (canUseFpvCameraMix && IS_RC_MODE_ACTIVE(BOXFPVANGLEMIX) && currentControlRateProfile->misc.fpvCamAngleDegrees) { + // Apply FPV camera mix + if (canUseFpvCameraMix && IS_RC_MODE_ACTIVE(BOXFPVANGLEMIX) && currentControlRateProfile->misc.fpvCamAngleDegrees && STATE(MULTIROTOR)) { pidApplyFpvCameraAngleMix(pidState, currentControlRateProfile->misc.fpvCamAngleDegrees); } @@ -1243,7 +1327,7 @@ void pidInit(void) navPidInit( &fixedWingLevelTrimController, 0.0f, - (float)pidProfile()->fixedWingLevelTrimGain / 100000.0f, + (float)pidProfile()->fixedWingLevelTrimGain / 200.0f, 0.0f, 0.0f, 2.0f, @@ -1255,47 +1339,52 @@ void pidInit(void) const pidBank_t * pidBank(void) { return usedPidControllerType == PID_TYPE_PIFF ? &pidProfile()->bank_fw : &pidProfile()->bank_mc; } + pidBank_t * pidBankMutable(void) { return usedPidControllerType == PID_TYPE_PIFF ? &pidProfileMutable()->bank_fw : &pidProfileMutable()->bank_mc; } +bool isFixedWingLevelTrimActive(void) +{ + return IS_RC_MODE_ACTIVE(BOXAUTOLEVEL) && !areSticksDeflected() && + (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE)) && + !FLIGHT_MODE(SOARING_MODE) && !FLIGHT_MODE(MANUAL_MODE) && + !navigationIsControllingAltitude() && !(navCheckActiveAngleHoldAxis() == FD_PITCH && !angleHoldIsLevel); +} + void updateFixedWingLevelTrim(timeUs_t currentTimeUs) { if (!STATE(AIRPLANE)) { return; } - static timeUs_t previousUpdateTimeUs; - static bool previousArmingState; - const float dT = US2S(currentTimeUs - previousUpdateTimeUs); + static bool previousArmingState = false; - /* - * On every ARM reset the controller - */ - if (ARMING_FLAG(ARMED) && !previousArmingState) { - navPidReset(&fixedWingLevelTrimController); + if (ARMING_FLAG(ARMED)) { + if (!previousArmingState) { // On every ARM reset the controller + navPidReset(&fixedWingLevelTrimController); + } + } else if (previousArmingState) { // On disarm update the default value + pidProfileMutable()->fixedWingLevelTrim = constrainf(fixedWingLevelTrim, -FIXED_WING_LEVEL_TRIM_MAX_ANGLE, FIXED_WING_LEVEL_TRIM_MAX_ANGLE); } + previousArmingState = ARMING_FLAG(ARMED); - /* - * On disarm update the default value - */ - if (!ARMING_FLAG(ARMED) && previousArmingState) { - pidProfileMutable()->fixedWingLevelTrim = constrainf(fixedWingLevelTrim, -FIXED_WING_LEVEL_TRIM_MAX_ANGLE, FIXED_WING_LEVEL_TRIM_MAX_ANGLE); + // return if not active or disarmed + if (!IS_RC_MODE_ACTIVE(BOXAUTOLEVEL) || !ARMING_FLAG(ARMED)) { + return; } + static timeUs_t previousUpdateTimeUs; + const float dT = US2S(currentTimeUs - previousUpdateTimeUs); + previousUpdateTimeUs = currentTimeUs; + /* * Prepare flags for the PID controller */ pidControllerFlags_e flags = PID_LIMIT_INTEGRATOR; - //Iterm should freeze when sticks are deflected - if ( - !IS_RC_MODE_ACTIVE(BOXAUTOLEVEL) || - areSticksDeflected() || - (!FLIGHT_MODE(ANGLE_MODE) && !FLIGHT_MODE(HORIZON_MODE) && !FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) || - FLIGHT_MODE(SOARING_MODE) || - navigationIsControllingAltitude() - ) { + // Iterm should freeze when conditions for setting level trim aren't met or time since last expected update too long ago + if (!isFixedWingLevelTrimActive() || (dT > 5.0f * US2S(TASK_PERIOD_HZ(TASK_AUX_RATE_HZ)))) { flags |= PID_FREEZE_INTEGRATOR; } @@ -1313,8 +1402,6 @@ void updateFixedWingLevelTrim(timeUs_t currentTimeUs) DEBUG_SET(DEBUG_AUTOLEVEL, 4, output); fixedWingLevelTrim = pidProfile()->fixedWingLevelTrim + (output * FIXED_WING_LEVEL_TRIM_MULTIPLIER); - - previousArmingState = !!ARMING_FLAG(ARMED); } float getFixedWingLevelTrim(void) diff --git a/src/main/flight/pid.h b/src/main/flight/pid.h index de0e3126b7c..e0a8b9d310b 100644 --- a/src/main/flight/pid.h +++ b/src/main/flight/pid.h @@ -31,10 +31,6 @@ #define HEADING_HOLD_RATE_LIMIT_MAX 250 #define HEADING_HOLD_RATE_LIMIT_DEFAULT 90 -#define FW_ITERM_THROW_LIMIT_DEFAULT 165 -#define FW_ITERM_THROW_LIMIT_MIN 0 -#define FW_ITERM_THROW_LIMIT_MAX 500 - #define AXIS_ACCEL_MIN_LIMIT 50 #define HEADING_HOLD_ERROR_LPF_FREQ 2 @@ -106,8 +102,8 @@ typedef struct pidProfile_s { pidBank_t bank_mc; uint8_t dterm_lpf_type; // Dterm LPF type: PT1, BIQUAD - uint16_t dterm_lpf_hz; - + 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 @@ -121,15 +117,15 @@ typedef struct pidProfile_s { uint16_t pidSumLimit; uint16_t pidSumLimitYaw; + uint16_t pidItermLimitPercent; // Airplane-specific parameters - uint16_t fixedWingItermThrowLimit; 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. float fixedWingItermLimitOnStickPosition; //Do not allow Iterm to grow when stick position is above this point uint16_t fixedWingYawItermBankFreeze; // Freeze yaw Iterm when bank angle is more than this many degrees - + 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 @@ -221,5 +217,7 @@ void autotuneFixedWingUpdate(const flight_dynamics_index_t axis, float desiredRa pidType_e pidIndexGetType(pidIndex_e pidIndex); +bool isFixedWingLevelTrimActive(void); void updateFixedWingLevelTrim(timeUs_t currentTimeUs); float getFixedWingLevelTrim(void); +bool isAngleHoldLevel(void); diff --git a/src/main/flight/rth_estimator.c b/src/main/flight/rth_estimator.c index eed9adbae36..708c71bd1cf 100644 --- a/src/main/flight/rth_estimator.c +++ b/src/main/flight/rth_estimator.c @@ -209,8 +209,8 @@ float calculateRemainingFlightTimeBeforeRTH(bool takeWindIntoAccount) { // returns meters float calculateRemainingDistanceBeforeRTH(bool takeWindIntoAccount) { - // Fixed wing only for now - if (!(STATE(FIXED_WING_LEGACY) || ARMING_FLAG(ARMED))) { + // Fixed wing only for now, and must be armed + if (!STATE(AIRPLANE) || !ARMING_FLAG(ARMED)) { return -1; } diff --git a/src/main/flight/servos.c b/src/main/flight/servos.c index 4d4bb497d19..f38a4ea108c 100755 --- a/src/main/flight/servos.c +++ b/src/main/flight/servos.c @@ -103,8 +103,14 @@ void pgResetFn_servoParams(servoParam_t *instance) int16_t servo[MAX_SUPPORTED_SERVOS]; static uint8_t servoRuleCount = 0; +static servoMixer_t currentServoMixer[MAX_SERVO_RULES]; + +/* +//Was used to keep track of servo rules in all mixer_profile, In order to Apply mixer speed limit when rules turn off static servoMixer_t currentServoMixer[MAX_SERVO_RULES*MAX_MIXER_PROFILE_COUNT]; -static bool currentServoMixerActivative[MAX_SERVO_RULES*MAX_MIXER_PROFILE_COUNT];// if true, the rule is used by current servo mixer +static bool currentServoMixerActivative[MAX_SERVO_RULES*MAX_MIXER_PROFILE_COUNT]; // if true, the rule is used by current servo mixer +*/ + static bool servoOutputEnabled; static bool mixerUsesServos; @@ -115,7 +121,7 @@ static biquadFilter_t servoFilter[MAX_SUPPORTED_SERVOS]; static bool servoFilterIsSet; static servoMetadata_t servoMetadata[MAX_SUPPORTED_SERVOS]; -static rateLimitFilter_t servoSpeedLimitFilter[MAX_SERVO_RULES*MAX_MIXER_PROFILE_COUNT]; +static rateLimitFilter_t servoSpeedLimitFilter[MAX_SERVO_RULES]; STATIC_FASTRAM pt1Filter_t rotRateFilter; STATIC_FASTRAM pt1Filter_t targetRateFilter; @@ -137,6 +143,33 @@ void servoComputeScalingFactors(uint8_t servoIndex) { servoMetadata[servoIndex].scaleMin = (servoParams(servoIndex)->middle - servoParams(servoIndex)->min) / 500.0f; } +void computeServoCount(void) +{ + static bool firstRun = true; + if (!firstRun) { + return; + } + minServoIndex = 255; + maxServoIndex = 0; + for (int j = 0; j < MAX_MIXER_PROFILE_COUNT; j++) { + for (int i = 0; i < MAX_SERVO_RULES; i++) { + // check if done + if (mixerServoMixersByIndex(j)[i].rate == 0){ + break; + } + if (mixerServoMixersByIndex(j)[i].targetChannel < minServoIndex) { + minServoIndex = mixerServoMixersByIndex(j)[i].targetChannel; + } + + if (mixerServoMixersByIndex(j)[i].targetChannel > maxServoIndex) { + maxServoIndex = mixerServoMixersByIndex(j)[i].targetChannel; + } + mixerUsesServos = true; + } + } + firstRun = false; +} + void servosInit(void) { // give all servos a default command @@ -147,12 +180,12 @@ void servosInit(void) /* * load mixer */ + computeServoCount(); loadCustomServoMixer(); // If there are servo rules after all, update variables - if (servoRuleCount > 0) { + if (mixerUsesServos) { servoOutputEnabled = true; - mixerUsesServos = true; } for (uint8_t i = 0; i < MAX_SUPPORTED_SERVOS; i++) { @@ -161,8 +194,8 @@ void servosInit(void) } int getServoCount(void) -{ - if (servoRuleCount) { +{ + if (mixerUsesServos) { return 1 + maxServoIndex - minServoIndex; } else { @@ -173,30 +206,17 @@ int getServoCount(void) void loadCustomServoMixer(void) { servoRuleCount = 0; - minServoIndex = 255; - maxServoIndex = 0; memset(currentServoMixer, 0, sizeof(currentServoMixer)); - for (int j = 0; j < MAX_MIXER_PROFILE_COUNT; j++) { - const servoMixer_t* tmp_customServoMixers = &mixerServoMixersByIndex(j)[0]; - // load custom mixer into currentServoMixer - for (int i = 0; i < MAX_SERVO_RULES; i++) { - // check if done - if (tmp_customServoMixers[i].rate == 0) - break; - - if (tmp_customServoMixers[i].targetChannel < minServoIndex) { - minServoIndex = tmp_customServoMixers[i].targetChannel; - } - - if (tmp_customServoMixers[i].targetChannel > maxServoIndex) { - maxServoIndex = tmp_customServoMixers[i].targetChannel; - } - - memcpy(¤tServoMixer[servoRuleCount], &tmp_customServoMixers[i], sizeof(servoMixer_t)); - currentServoMixerActivative[servoRuleCount] = j==currentMixerProfileIndex; - servoRuleCount++; + // load custom mixer into currentServoMixer + for (int i = 0; i < MAX_SERVO_RULES; i++) { + // check if done + if (customServoMixers(i)->rate == 0){ + break; } + currentServoMixer[servoRuleCount] = *customServoMixers(i); + servoSpeedLimitFilter[servoRuleCount].state = 0; + servoRuleCount++; } } @@ -353,9 +373,6 @@ void servoMixer(float dT) inputRaw = 0; } #endif - if (!currentServoMixerActivative[i]) { - inputRaw = 0; - } /* * Apply mixer speed limit. 1 [one] speed unit is defined as 10us/s: * 0 = no limiting @@ -368,20 +385,6 @@ void servoMixer(float dT) servo[target] += ((int32_t)inputLimited * currentServoMixer[i].rate) / 100; } - /* - * When not armed, apply servo low position to all outputs that include a throttle or stabilizet throttle in the mix - */ - if (!ARMING_FLAG(ARMED)) { - for (int i = 0; i < servoRuleCount; i++) { - const uint8_t target = currentServoMixer[i].targetChannel; - const uint8_t from = currentServoMixer[i].inputSource; - - if (from == INPUT_STABILIZED_THROTTLE || from == INPUT_RC_THROTTLE) { - servo[target] = motorConfig()->mincommand; - } - } - } - for (int i = 0; i < MAX_SUPPORTED_SERVOS; i++) { /* @@ -412,6 +415,20 @@ void servoMixer(float dT) */ servo[i] = constrain(servo[i], servoParams(i)->min, servoParams(i)->max); } + + /* + * When not armed, apply servo low position to all outputs that include a throttle or stabilizet throttle in the mix + */ + if (!ARMING_FLAG(ARMED)) { + for (int i = 0; i < servoRuleCount; i++) { + const uint8_t target = currentServoMixer[i].targetChannel; + const uint8_t from = currentServoMixer[i].inputSource; + + if (from == INPUT_STABILIZED_THROTTLE || from == INPUT_RC_THROTTLE) { + servo[target] = motorConfig()->mincommand; + } + } + } } #define SERVO_AUTOTRIM_TIMER_MS 2000 @@ -438,7 +455,6 @@ void processServoAutotrimMode(void) if (ARMING_FLAG(ARMED)) { for (int axis = FD_ROLL; axis <= FD_YAW; axis++) { for (int i = 0; i < servoRuleCount; i++) { - if (!currentServoMixerActivative[i]) {continue;} // Reset servo middle accumulator const uint8_t target = currentServoMixer[i].targetChannel; const uint8_t source = currentServoMixer[i].inputSource; @@ -461,7 +477,6 @@ void processServoAutotrimMode(void) if (ARMING_FLAG(ARMED)) { for (int axis = FD_ROLL; axis <= FD_YAW; axis++) { for (int i = 0; i < servoRuleCount; i++) { - if (!currentServoMixerActivative[i]) {continue;} const uint8_t target = currentServoMixer[i].targetChannel; const uint8_t source = currentServoMixer[i].inputSource; if (source == axis) { @@ -474,7 +489,6 @@ void processServoAutotrimMode(void) if ((millis() - trimStartedAt) > SERVO_AUTOTRIM_TIMER_MS) { for (int axis = FD_ROLL; axis <= FD_YAW; axis++) { for (int i = 0; i < servoRuleCount; i++) { - if (!currentServoMixerActivative[i]) {continue;} const uint8_t target = currentServoMixer[i].targetChannel; const uint8_t source = currentServoMixer[i].inputSource; if (source == axis) { @@ -508,7 +522,6 @@ void processServoAutotrimMode(void) if (trimState == AUTOTRIM_SAVE_PENDING) { for (int axis = FD_ROLL; axis <= FD_YAW; axis++) { for (int i = 0; i < servoRuleCount; i++) { - if (!currentServoMixerActivative[i]) {continue;} const uint8_t target = currentServoMixer[i].targetChannel; const uint8_t source = currentServoMixer[i].inputSource; if (source == axis) { diff --git a/src/main/flight/wind_estimator.c b/src/main/flight/wind_estimator.c index e0b13a5310d..6420f6547b1 100644 --- a/src/main/flight/wind_estimator.c +++ b/src/main/flight/wind_estimator.c @@ -38,6 +38,8 @@ #include "flight/imu.h" +#include "navigation/navigation_pos_estimator_private.h" + #include "io/gps.h" @@ -105,9 +107,9 @@ void updateWindEstimator(timeUs_t currentTimeUs) // Get current 3D velocity from GPS in cm/s // relative to earth frame - groundVelocity[X] = gpsSol.velNED[X]; - groundVelocity[Y] = gpsSol.velNED[Y]; - groundVelocity[Z] = gpsSol.velNED[Z]; + groundVelocity[X] = posEstimator.gps.vel.x; + groundVelocity[Y] = posEstimator.gps.vel.y; + groundVelocity[Z] = posEstimator.gps.vel.z; // Fuselage direction in earth frame fuselageDirection[X] = HeadVecEFFiltered.x; diff --git a/src/main/io/displayport_msp_bf_compat.c b/src/main/io/displayport_msp_bf_compat.c index 7cfa8f1bf63..7067ac140f5 100644 --- a/src/main/io/displayport_msp_bf_compat.c +++ b/src/main/io/displayport_msp_bf_compat.c @@ -96,10 +96,31 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) case SYM_AH_DECORATION_DOWN: return BF_SYM_AH_DECORATION_DOWN; - - case SYM_DIRECTION: - return BF_SYM_DIRECTION; */ + case SYM_DIRECTION: + return BF_SYM_ARROW_NORTH; + + case SYM_DIRECTION + 1: // NE pointing arrow + return BF_SYM_ARROW_7; + + case SYM_DIRECTION + 2: // E pointing arrow + return BF_SYM_ARROW_EAST; + + case SYM_DIRECTION + 3: // SE pointing arrow + return BF_SYM_ARROW_3; + + case SYM_DIRECTION + 4: // S pointing arrow + return BF_SYM_ARROW_SOUTH; + + case SYM_DIRECTION + 5: // SW pointing arrow + return BF_SYM_ARROW_15; + + case SYM_DIRECTION + 6: // W pointing arrow + return BF_SYM_ARROW_WEST; + + case SYM_DIRECTION + 7: // NW pointing arrow + return BF_SYM_ARROW_11; + case SYM_VOLT: return BF_SYM_VOLT; @@ -187,13 +208,9 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) case SYM_ALT_M: return BF_SYM_M; -/* - case SYM_TRIP_DIST: - return BF_SYM_TRIP_DIST; - case SYM_TOTAL: - return BF_SYM_TOTAL; - + return BF_SYM_TOTAL_DISTANCE; +/* case SYM_ALT_KM: return BF_SYM_ALT_KM; @@ -226,20 +243,19 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) /* case SYM_NM: return BF_SYM_NM; - +*/ case SYM_WIND_HORIZONTAL: - return BF_SYM_WIND_HORIZONTAL; + return 'W'; // W for wind +/* case SYM_WIND_VERTICAL: return BF_SYM_WIND_VERTICAL; case SYM_3D_KT: return BF_SYM_3D_KT; - - - case SYM_AIR: - return BF_SYM_AIR; */ + case SYM_AIR: + return 'A'; // A for airspeed case SYM_3D_KMH: return BF_SYM_KPH; @@ -277,13 +293,12 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) case SYM_THR: return BF_SYM_THR; -/* case SYM_TEMP_F: - return BF_SYM_TEMP_F; + return BF_SYM_F; case SYM_TEMP_C: - return BF_SYM_TEMP_C; -*/ + return BF_SYM_C; + case SYM_BLANK: return BF_SYM_BLANK; /* @@ -334,10 +349,12 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) case SYM_PITCH_DOWN: return BF_SYM_PITCH_DOWN; + */ case SYM_GFORCE: - return BF_SYM_GFORCE; + return 'G'; +/* case SYM_GFORCE_X: return BF_SYM_GFORCE_X; @@ -560,6 +577,48 @@ uint8_t getBfCharacter(uint8_t ch, uint8_t page) case (SYM_AH_V_START+4): case (SYM_AH_V_START+5): return BF_SYM_AH_BAR9_4; + + // BF for ESP_RADAR Symbols + case SYM_HUD_CARDINAL: + return BF_SYM_ARROW_SOUTH; + case SYM_HUD_CARDINAL + 1: + return BF_SYM_ARROW_16; + case SYM_HUD_CARDINAL + 2: + return BF_SYM_ARROW_15; + case SYM_HUD_CARDINAL + 3: + return BF_SYM_ARROW_WEST; + case SYM_HUD_CARDINAL + 4: + return BF_SYM_ARROW_12; + case SYM_HUD_CARDINAL + 5: + return BF_SYM_ARROW_11; + case SYM_HUD_CARDINAL + 6: + return BF_SYM_ARROW_NORTH; + case SYM_HUD_CARDINAL + 7: + return BF_SYM_ARROW_7; + case SYM_HUD_CARDINAL + 8: + return BF_SYM_ARROW_6; + case SYM_HUD_CARDINAL + 9: + return BF_SYM_ARROW_EAST; + case SYM_HUD_CARDINAL + 10: + return BF_SYM_ARROW_3; + case SYM_HUD_CARDINAL + 11: + return BF_SYM_ARROW_2; + + case SYM_HUD_ARROWS_R3: + return BF_SYM_AH_RIGHT; + case SYM_HUD_ARROWS_L3: + return BF_SYM_AH_LEFT; + + case SYM_HUD_SIGNAL_0: + return BF_SYM_AH_BAR9_1; + case SYM_HUD_SIGNAL_1: + return BF_SYM_AH_BAR9_3; + case SYM_HUD_SIGNAL_2: + return BF_SYM_AH_BAR9_4; + case SYM_HUD_SIGNAL_3: + return BF_SYM_AH_BAR9_5; + case SYM_HUD_SIGNAL_4: + return BF_SYM_AH_BAR9_7; /* case SYM_VARIO_UP_2A: return BF_SYM_VARIO_UP_2A; diff --git a/src/main/io/displayport_msp_osd.c b/src/main/io/displayport_msp_osd.c index 17f49c8b78d..e1e6cb29676 100644 --- a/src/main/io/displayport_msp_osd.c +++ b/src/main/io/displayport_msp_osd.c @@ -42,6 +42,7 @@ #include "drivers/osd_symbols.h" #include "fc/rc_modes.h" +#include "fc/runtime_config.h" #include "io/osd.h" #include "io/displayport_msp.h" @@ -113,6 +114,10 @@ static void checkVtxPresent(void) if (vtxActive && (millis()-vtxHeartbeat) > VTX_TIMEOUT) { vtxActive = false; } + + if (ARMING_FLAG(SIMULATOR_MODE_HITL)) { + vtxActive = true; + } } static int output(displayPort_t *displayPort, uint8_t cmd, uint8_t *subcmd, int len) @@ -288,7 +293,8 @@ static int drawScreen(displayPort_t *displayPort) // 250Hz uint8_t len = 4; do { bitArrayClr(dirty, pos); - subcmd[len++] = isBfCompatibleVideoSystem(osdConfig()) ? getBfCharacter(screen[pos++], page): screen[pos++]; + subcmd[len] = isBfCompatibleVideoSystem(osdConfig()) ? getBfCharacter(screen[pos++], page): screen[pos++]; + len++; if (bitArrayGet(dirty, pos)) { next = pos; @@ -325,7 +331,7 @@ static int drawScreen(displayPort_t *displayPort) // 250Hz vtxReset = false; } -return 0; + return 0; } static void resync(displayPort_t *displayPort) @@ -356,6 +362,10 @@ static bool getFontMetadata(displayFontMetadata_t *metadata, const displayPort_t static textAttributes_t supportedTextAttributes(const displayPort_t *displayPort) { UNUSED(displayPort); + + //textAttributes_t attr = TEXT_ATTRIBUTES_NONE; + //TEXT_ATTRIBUTES_ADD_BLINK(attr); + //return attr; return TEXT_ATTRIBUTES_NONE; } diff --git a/src/main/io/gps.c b/src/main/io/gps.c index 0fae3a7f318..f71abe897d4 100755 --- a/src/main/io/gps.c +++ b/src/main/io/gps.c @@ -453,7 +453,7 @@ bool isGPSHealthy(void) bool isGPSHeadingValid(void) { - return sensors(SENSOR_GPS) && STATE(GPS_FIX) && gpsSol.numSat >= 6 && gpsSol.groundSpeed >= 300; + return sensors(SENSOR_GPS) && STATE(GPS_FIX) && gpsSol.numSat >= 6 && gpsSol.groundSpeed >= 400; } #endif diff --git a/src/main/io/gps.h b/src/main/io/gps.h index 199652a3a24..3e9d073c54c 100755 --- a/src/main/io/gps.h +++ b/src/main/io/gps.h @@ -76,7 +76,9 @@ typedef enum { typedef enum { GPS_DYNMODEL_PEDESTRIAN = 0, + GPS_DYNMODEL_AUTOMOTIVE, GPS_DYNMODEL_AIR_1G, + GPS_DYNMODEL_AIR_2G, GPS_DYNMODEL_AIR_4G, } gpsDynModel_e; diff --git a/src/main/io/gps_fake.c b/src/main/io/gps_fake.c index 6d574893436..5b0de8c50b5 100644 --- a/src/main/io/gps_fake.c +++ b/src/main/io/gps_fake.c @@ -31,6 +31,7 @@ #include "platform.h" #include "build/build_config.h" +#include "common/log.h" #if defined(USE_GPS_FAKE) diff --git a/src/main/io/gps_ublox.c b/src/main/io/gps_ublox.c index d03c3390776..5b91523cdb3 100755 --- a/src/main/io/gps_ublox.c +++ b/src/main/io/gps_ublox.c @@ -391,9 +391,10 @@ static void configureGNSS10(void) {UBLOX_CFG_SIGNAL_GAL_E1_ENA, gpsState.gpsConfig->ubloxUseGalileo}, // Beidou + // M10 can't use BDS_B1I and Glonass together. Instead, use BDS_B1C {UBLOX_CFG_SIGNAL_BDS_ENA, gpsState.gpsConfig->ubloxUseBeidou}, - {UBLOX_CFG_SIGNAL_BDS_B1_ENA, gpsState.gpsConfig->ubloxUseBeidou}, - {UBLOX_CFG_SIGNAL_BDS_B1C_ENA, 0}, + {UBLOX_CFG_SIGNAL_BDS_B1_ENA, gpsState.gpsConfig->ubloxUseBeidou && ! gpsState.gpsConfig->ubloxUseGlonass}, + {UBLOX_CFG_SIGNAL_BDS_B1C_ENA, gpsState.gpsConfig->ubloxUseBeidou && gpsState.gpsConfig->ubloxUseGlonass}, // Should be enabled with GPS {UBLOX_CFG_QZSS_ENA, 1}, @@ -800,10 +801,16 @@ STATIC_PROTOTHREAD(gpsConfigure) case GPS_DYNMODEL_PEDESTRIAN: configureNAV5(UBX_DYNMODEL_PEDESTRIAN, UBX_FIXMODE_AUTO); break; - case GPS_DYNMODEL_AIR_1G: // Default to this - default: + case GPS_DYNMODEL_AUTOMOTIVE: + configureNAV5(UBX_DYNMODEL_AUTOMOVITE, UBX_FIXMODE_AUTO); + break; + case GPS_DYNMODEL_AIR_1G: configureNAV5(UBX_DYNMODEL_AIR_1G, UBX_FIXMODE_AUTO); break; + case GPS_DYNMODEL_AIR_2G: // Default to this + default: + configureNAV5(UBX_DYNMODEL_AIR_2G, UBX_FIXMODE_AUTO); + break; case GPS_DYNMODEL_AIR_4G: configureNAV5(UBX_DYNMODEL_AIR_4G, UBX_FIXMODE_AUTO); break; @@ -948,12 +955,18 @@ STATIC_PROTOTHREAD(gpsConfigure) // Configure GNSS for M8N and later if (gpsState.hwVersion >= UBX_HW_VERSION_UBLOX8) { - gpsSetProtocolTimeout(GPS_SHORT_TIMEOUT); - if(gpsState.hwVersion >= UBX_HW_VERSION_UBLOX10 || (gpsState.swVersionMajor>=23 && gpsState.swVersionMinor >= 1)) { + gpsSetProtocolTimeout(GPS_SHORT_TIMEOUT); + bool use_VALSET = 0; + if ( (gpsState.swVersionMajor > 23) || (gpsState.swVersionMajor == 23 && gpsState.swVersionMinor > 1) ) { + use_VALSET = 1; + } + + if ( use_VALSET && (gpsState.hwVersion >= UBX_HW_VERSION_UBLOX10) ) { configureGNSS10(); - } else { + } else { configureGNSS(); - } + } + ptWaitTimeout((_ack_state == UBX_ACK_GOT_ACK || _ack_state == UBX_ACK_GOT_NAK), GPS_CFG_CMD_TIMEOUT_MS); if(_ack_state == UBX_ACK_GOT_NAK) { @@ -1042,12 +1055,15 @@ STATIC_PROTOTHREAD(gpsProtocolStateThread) gpsState.autoConfigStep = 0; ubx_capabilities.supported = ubx_capabilities.enabledGnss = ubx_capabilities.defaultGnss = 0; - do { - pollGnssCapabilities(); - gpsState.autoConfigStep++; - ptWaitTimeout((ubx_capabilities.capMaxGnss != 0), GPS_CFG_CMD_TIMEOUT_MS); - } while (gpsState.autoConfigStep < GPS_VERSION_RETRY_TIMES && ubx_capabilities.capMaxGnss == 0); - + // M7 and earlier will never get pass this step, so skip it (#9440). + // UBLOX documents that this is M8N and later + if (gpsState.hwVersion > UBX_HW_VERSION_UBLOX7) { + do { + pollGnssCapabilities(); + gpsState.autoConfigStep++; + ptWaitTimeout((ubx_capabilities.capMaxGnss != 0), GPS_CFG_CMD_TIMEOUT_MS); + } while (gpsState.autoConfigStep < GPS_VERSION_RETRY_TIMES && ubx_capabilities.capMaxGnss == 0); + } // Configure GPS module if enabled if (gpsState.gpsConfig->autoConfig) { // Configure GPS diff --git a/src/main/io/gps_ublox.h b/src/main/io/gps_ublox.h index 00b42eeb2b7..8ec9be16d09 100644 --- a/src/main/io/gps_ublox.h +++ b/src/main/io/gps_ublox.h @@ -34,7 +34,9 @@ extern "C" { #define GPS_CAPA_INTERVAL 5000 #define UBX_DYNMODEL_PEDESTRIAN 3 +#define UBX_DYNMODEL_AUTOMOVITE 4 #define UBX_DYNMODEL_AIR_1G 6 +#define UBX_DYNMODEL_AIR_2G 7 #define UBX_DYNMODEL_AIR_4G 8 #define UBX_FIXMODE_2D_ONLY 1 diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index ab5b72f3885..644409b9e0a 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -21,7 +21,7 @@ #include "common/color.h" #include "rx/rx.h" -#define LED_MAX_STRIP_LENGTH 32 +#define LED_MAX_STRIP_LENGTH 128 #define LED_CONFIGURABLE_COLOR_COUNT 16 #define LED_MODE_COUNT 6 #define LED_DIRECTION_COUNT 6 diff --git a/src/main/io/osd.c b/src/main/io/osd.c index f5daeaf63c2..f0cc50bbaa1 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -72,6 +72,8 @@ #include "io/vtx.h" #include "io/vtx_string.h" +#include "io/osd/custom_elements.h" + #include "fc/config.h" #include "fc/controlrate_profile.h" #include "fc/fc_core.h" @@ -131,7 +133,6 @@ #define STATS_PAGE1 (checkStickPosition(ROL_LO)) #define SPLASH_SCREEN_DISPLAY_TIME 4000 // ms -#define ARMED_SCREEN_DISPLAY_TIME 1500 // ms #define STATS_SCREEN_DISPLAY_TIME 60000 // ms #define EFFICIENCY_UPDATE_INTERVAL (5 * 1000) @@ -155,8 +156,9 @@ #define OSD_MIN_FONT_VERSION 3 -static timeMs_t notify_settings_saved = 0; -static bool savingSettings = false; +static timeMs_t linearDescentMessageMs = 0; +static timeMs_t notify_settings_saved = 0; +static bool savingSettings = false; static unsigned currentLayout = 0; static int layoutOverride = -1; @@ -209,7 +211,7 @@ static bool osdDisplayHasCanvas; #define AH_MAX_PITCH_DEFAULT 20 // Specify default maximum AHI pitch value displayed (degrees) -PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 8); +PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 9); PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 1); void osdStartedSaveProcess(void) { @@ -316,7 +318,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals) case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), FEET_PER_MILE, decimals, 3, digits)) { + if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), FEET_PER_MILE, decimals, 3, digits, false)) { buff[sym_index] = symbol_mi; } else { buff[sym_index] = symbol_ft; @@ -326,7 +328,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals) case OSD_UNIT_METRIC_MPH: FALLTHROUGH; case OSD_UNIT_METRIC: - if (osdFormatCentiNumber(buff, dist, METERS_PER_KILOMETER, decimals, 3, digits)) { + if (osdFormatCentiNumber(buff, dist, METERS_PER_KILOMETER, decimals, 3, digits, false)) { buff[sym_index] = symbol_km; } else { buff[sym_index] = symbol_m; @@ -334,7 +336,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals) buff[sym_index + 1] = '\0'; break; case OSD_UNIT_GA: - if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), (uint32_t)FEET_PER_NAUTICALMILE, decimals, 3, digits)) { + if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), (uint32_t)FEET_PER_NAUTICALMILE, decimals, 3, digits, false)) { buff[sym_index] = symbol_nm; } else { buff[sym_index] = symbol_ft; @@ -489,7 +491,7 @@ static void osdFormatWindSpeedStr(char *buff, int32_t ws, bool isValid) break; } - osdFormatCentiNumber(buff, centivalue, 0, 2, 0, 3); + osdFormatCentiNumber(buff, centivalue, 0, 2, 0, 3, false); if (!isValid && ((millis() / 1000) % 4 < 2)) suffix = '*'; @@ -562,7 +564,7 @@ void osdFormatAltitudeSymbol(char *buff, int32_t alt) case OSD_UNIT_GA: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - if (osdFormatCentiNumber(buff + totalDigits - digits, CENTIMETERS_TO_CENTIFEET(alt), 1000, 0, 2, digits)) { + if (osdFormatCentiNumber(buff + totalDigits - digits, CENTIMETERS_TO_CENTIFEET(alt), 1000, 0, 2, digits, false)) { // Scaled to kft buff[symbolIndex++] = symbolKFt; } else { @@ -575,7 +577,7 @@ void osdFormatAltitudeSymbol(char *buff, int32_t alt) FALLTHROUGH; case OSD_UNIT_METRIC: // alt is alredy in cm - if (osdFormatCentiNumber(buff + totalDigits - digits, alt, 1000, 0, 2, digits)) { + if (osdFormatCentiNumber(buff + totalDigits - digits, alt, 1000, 0, 2, digits, false)) { // Scaled to km buff[symbolIndex++] = SYM_ALT_KM; } else { @@ -983,24 +985,33 @@ static const char * osdFailsafePhaseMessage(void) static const char * osdFailsafeInfoMessage(void) { - if (failsafeIsReceivingRxData()) { + if (failsafeIsReceivingRxData() && !FLIGHT_MODE(NAV_FW_AUTOLAND)) { // User must move sticks to exit FS mode return OSD_MESSAGE_STR(OSD_MSG_MOVE_EXIT_FS); } return OSD_MESSAGE_STR(OSD_MSG_RC_RX_LINK_LOST); } + #if defined(USE_SAFE_HOME) static const char * divertingToSafehomeMessage(void) { +#ifdef USE_FW_AUTOLAND + if (!posControl.fwLandState.landWp && (NAV_Status.state != MW_NAV_STATE_HOVER_ABOVE_HOME && posControl.safehomeState.isApplied)) { +#else if (NAV_Status.state != MW_NAV_STATE_HOVER_ABOVE_HOME && posControl.safehomeState.isApplied) { - return OSD_MESSAGE_STR(OSD_MSG_DIVERT_SAFEHOME); - } - return NULL; -} #endif + return OSD_MESSAGE_STR(OSD_MSG_DIVERT_SAFEHOME); + } +#endif + return NULL; +} + static const char * navigationStateMessage(void) { + if (!posControl.rthState.rthLinearDescentActive && linearDescentMessageMs != 0) + linearDescentMessageMs = 0; + switch (NAV_Status.state) { case MW_NAV_STATE_NONE: break; @@ -1012,7 +1023,13 @@ static const char * navigationStateMessage(void) if (posControl.flags.rthTrackbackActive) { return OSD_MESSAGE_STR(OSD_MSG_RTH_TRACKBACK); } else { - return OSD_MESSAGE_STR(OSD_MSG_HEADING_HOME); + if (posControl.rthState.rthLinearDescentActive && (linearDescentMessageMs == 0 || linearDescentMessageMs > millis())) { + if (linearDescentMessageMs == 0) + linearDescentMessageMs = millis() + 5000; // Show message for 5 seconds. + + return OSD_MESSAGE_STR(OSD_MSG_RTH_LINEAR_DESCENT); + } else + return OSD_MESSAGE_STR(OSD_MSG_HEADING_HOME); } case MW_NAV_STATE_HOLD_INFINIT: // Used by HOLD flight modes. No information to add. @@ -1048,11 +1065,18 @@ static const char * navigationStateMessage(void) case MW_NAV_STATE_LANDED: return OSD_MESSAGE_STR(OSD_MSG_LANDED); case MW_NAV_STATE_LAND_SETTLE: + { + // If there is a FS landing delay occurring. That is handled by the calling function. + if (posControl.landingDelay > 0) + break; + return OSD_MESSAGE_STR(OSD_MSG_PREPARING_LAND); + } case MW_NAV_STATE_LAND_START_DESCENT: // Not used break; } + return NULL; } @@ -1134,7 +1158,7 @@ static void osdFormatThrottlePosition(char *buff, bool useScaled, textAttributes #endif int8_t throttlePercent = getThrottlePercent(useScaled); if ((useScaled && throttlePercent <= 0) || !ARMING_FLAG(ARMED)) { - const char* message = ARMING_FLAG(ARMED) ? throttlePercent == 0 ? "IDLE" : "STOP" : "DARM"; + const char* message = ARMING_FLAG(ARMED) ? (throttlePercent == 0 && !ifMotorstopFeatureEnabled()) ? "IDLE" : "STOP" : "DARM"; buff[0] = SYM_THR; strcpy(buff + 1, message); return; @@ -1151,7 +1175,7 @@ static void osdFormatGVar(char *buff, uint8_t index) buff[1] = '0'+index; buff[2] = ':'; #ifdef USE_PROGRAMMING_FRAMEWORK - osdFormatCentiNumber(buff + 3, (int32_t)gvGet(index)*(int32_t)100, 1, 0, 0, 5); + osdFormatCentiNumber(buff + 3, (int32_t)gvGet(index)*(int32_t)100, 1, 0, 0, 5, false); #endif } @@ -1162,7 +1186,7 @@ static void osdFormatRpm(char *buff, uint32_t rpm) if (rpm) { if ( digitCount(rpm) > osdConfig()->esc_rpm_precision) { uint8_t rpmMaxDecimals = (osdConfig()->esc_rpm_precision - 3); - osdFormatCentiNumber(buff + 1, rpm / 10, 0, rpmMaxDecimals, rpmMaxDecimals, osdConfig()->esc_rpm_precision-1); + osdFormatCentiNumber(buff + 1, rpm / 10, 0, rpmMaxDecimals, rpmMaxDecimals, osdConfig()->esc_rpm_precision-1, false); buff[osdConfig()->esc_rpm_precision] = 'K'; buff[osdConfig()->esc_rpm_precision+1] = '\0'; } @@ -1202,7 +1226,7 @@ int32_t osdGetAltitude(void) static inline int32_t osdGetAltitudeMsl(void) { - return getEstimatedActualPosition(Z)+GPS_home.alt; + return getEstimatedActualPosition(Z) + posControl.gpsOrigin.alt; } uint16_t osdGetRemainingGlideTime(void) { @@ -1486,13 +1510,13 @@ static void osdFormatPidControllerOutput(char *buff, const char *label, const pi strcpy(buff, label); for (uint8_t i = strlen(label); i < 5; ++i) buff[i] = ' '; uint8_t decimals = showDecimal ? 1 : 0; - osdFormatCentiNumber(buff + 5, pidController->proportional * scale, 0, decimals, 0, 4); + osdFormatCentiNumber(buff + 5, pidController->proportional * scale, 0, decimals, 0, 4, false); buff[9] = ' '; - osdFormatCentiNumber(buff + 10, pidController->integrator * scale, 0, decimals, 0, 4); + osdFormatCentiNumber(buff + 10, pidController->integrator * scale, 0, decimals, 0, 4, false); buff[14] = ' '; - osdFormatCentiNumber(buff + 15, pidController->derivative * scale, 0, decimals, 0, 4); + osdFormatCentiNumber(buff + 15, pidController->derivative * scale, 0, decimals, 0, 4, false); buff[19] = ' '; - osdFormatCentiNumber(buff + 20, pidController->output_constrained * scale, 0, decimals, 0, 4); + osdFormatCentiNumber(buff + 20, pidController->output_constrained * scale, 0, decimals, 0, 4, false); buff[24] = '\0'; } @@ -1508,7 +1532,7 @@ static void osdDisplayBatteryVoltage(uint8_t elemPosX, uint8_t elemPosY, uint16_ elemAttr = TEXT_ATTRIBUTES_NONE; digits = MIN(digits, 5); - osdFormatCentiNumber(buff, voltage, 0, decimals, 0, digits); + osdFormatCentiNumber(buff, voltage, 0, decimals, 0, digits, false); buff[digits] = SYM_VOLT; buff[digits+1] = '\0'; const batteryState_e batteryVoltageState = checkBatteryVoltageState(); @@ -1602,7 +1626,7 @@ static void osdDisplayAdjustableDecimalValue(uint8_t elemPosX, uint8_t elemPosY, displayWrite(osdDisplayPort, elemPosX, elemPosY, str); elemAttr = TEXT_ATTRIBUTES_NONE; - osdFormatCentiNumber(buff, value * 100, 0, maxDecimals, 0, MIN(valueLength, 8)); + osdFormatCentiNumber(buff, value * 100, 0, maxDecimals, 0, MIN(valueLength, 8), false); if (isAdjustmentFunctionSelected(adjFunc)) TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); displayWriteWithAttr(osdDisplayPort, elemPosX + strlen(str) + 1 + valueOffset, elemPosY, buff, elemAttr); @@ -1673,6 +1697,21 @@ static bool osdDrawSingleElement(uint8_t item) char buff[32] = {0}; switch (item) { + case OSD_CUSTOM_ELEMENT_1: + { + customElementDrawElement(buff, 0); + break; + } + case OSD_CUSTOM_ELEMENT_2: + { + customElementDrawElement(buff, 1); + break; + } + case OSD_CUSTOM_ELEMENT_3: + { + customElementDrawElement(buff, 2); + break; + } case OSD_RSSI_VALUE: { uint16_t osdRssi = osdConvertRSSI(); @@ -1707,7 +1746,7 @@ static bool osdDrawSingleElement(uint8_t item) } case OSD_CURRENT_DRAW: { - osdFormatCentiNumber(buff, getAmperage(), 0, 2, 0, 3); + osdFormatCentiNumber(buff, getAmperage(), 0, 2, 0, 3, false); buff[3] = SYM_AMP; buff[4] = '\0'; @@ -1719,22 +1758,18 @@ static bool osdDrawSingleElement(uint8_t item) } case OSD_MAH_DRAWN: { - uint8_t mah_digits = osdConfig()->mAh_used_precision; // Initialize to config value - bool bfcompat = false; // Assume BFCOMPAT is off + uint8_t mah_digits = osdConfig()->mAh_precision; // Initialize to config value #ifndef DISABLE_MSP_BF_COMPAT // IF BFCOMPAT is not supported, there's no need to check for it if (isBfCompatibleVideoSystem(osdConfig())) { - bfcompat = true; - } -#endif - - if (bfcompat) { //BFcompat is unable to work with scaled values and it only has mAh symbol to work with - tfp_sprintf(buff, "%5d", (int)getMAhDrawn()); // Use 5 digits to allow 10Ah+ packs + tfp_sprintf(buff, "%5d", (int)getMAhDrawn()); // Use 5 digits to allow packs below 100Ah buff[5] = SYM_MAH; buff[6] = '\0'; - } else { - if (osdFormatCentiNumber(buff, getMAhDrawn() * 100, 1000, 0, (mah_digits - 2), mah_digits)) { + } else +#endif + { + if (osdFormatCentiNumber(buff, getMAhDrawn() * 100, 1000, 0, (mah_digits - 2), mah_digits, false)) { // Shown in Ah buff[mah_digits] = SYM_AH; } else { @@ -1749,32 +1784,57 @@ static bool osdDrawSingleElement(uint8_t item) } case OSD_WH_DRAWN: - osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); + osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3, false); osdUpdateBatteryCapacityOrVoltageTextAttributes(&elemAttr); buff[3] = SYM_WH; buff[4] = '\0'; break; case OSD_BATTERY_REMAINING_CAPACITY: + { + bool unitsDrawn = false; if (currentBatteryProfile->capacity.value == 0) tfp_sprintf(buff, " NA"); else if (!batteryWasFullWhenPluggedIn()) tfp_sprintf(buff, " NF"); - else if (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH) - tfp_sprintf(buff, "%4lu", (unsigned long)getBatteryRemainingCapacity()); - else // currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH - osdFormatCentiNumber(buff + 1, getBatteryRemainingCapacity() / 10, 0, 2, 0, 3); + else if (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH) { + uint8_t mah_digits = osdConfig()->mAh_precision; // Initialize to config value - buff[4] = currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH; - buff[5] = '\0'; +#ifndef DISABLE_MSP_BF_COMPAT // IF BFCOMPAT is not supported, there's no need to check for it + if (isBfCompatibleVideoSystem(osdConfig())) { + //BFcompat is unable to work with scaled values and it only has mAh symbol to work with + tfp_sprintf(buff, "%5d", (int)getBatteryRemainingCapacity()); // Use 5 digits to allow packs below 100Ah + buff[5] = SYM_MAH; + buff[6] = '\0'; + unitsDrawn = true; + } else +#endif + { + if (osdFormatCentiNumber(buff, getBatteryRemainingCapacity() * 100, 1000, 0, (mah_digits - 2), mah_digits, false)) { + // Shown in Ah + buff[mah_digits] = SYM_AH; + } else { + // Shown in mAh + buff[mah_digits] = SYM_MAH; + } + buff[mah_digits + 1] = '\0'; + unitsDrawn = true; + } + } else // currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH + osdFormatCentiNumber(buff + 1, getBatteryRemainingCapacity() / 10, 0, 2, 0, 3, false); + + if (!unitsDrawn) { + buff[4] = currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH; + buff[5] = '\0'; + } if (batteryUsesCapacityThresholds()) { osdUpdateBatteryCapacityOrVoltageTextAttributes(&elemAttr); } break; - + } case OSD_BATTERY_REMAINING_PERCENT: osdFormatBatteryChargeSymbol(buff); tfp_sprintf(buff + 1, "%3d%%", calculateBatteryPercentage()); @@ -1834,7 +1894,7 @@ static bool osdDrawSingleElement(uint8_t item) buff[0] = SYM_GLIDESLOPE; if (glideSlope > 0.0f && glideSlope < 100.0f) { - osdFormatCentiNumber(buff + 1, glideSlope * 100.0f, 0, 2, 0, 3); + osdFormatCentiNumber(buff + 1, glideSlope * 100.0f, 0, 2, 0, 3, false); } else { buff[1] = buff[2] = buff[3] = '-'; } @@ -1912,6 +1972,38 @@ static bool osdDrawSingleElement(uint8_t item) osdFormatDistanceSymbol(buff + 1, getTotalTravelDistance(), 0); break; + case OSD_ODOMETER: + { + displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_ODOMETER); + float_t odometerDist = CENTIMETERS_TO_METERS(getTotalTravelDistance()); +#ifdef USE_STATS + odometerDist+= statsConfig()->stats_total_dist; +#endif + + switch (osdConfig()->units) { + case OSD_UNIT_UK: + FALLTHROUGH; + case OSD_UNIT_IMPERIAL: + osdFormatCentiNumber(buff, METERS_TO_MILES(odometerDist) * 100, 1, 1, 1, 6, true); + buff[6] = SYM_MI; + break; + default: + case OSD_UNIT_GA: + osdFormatCentiNumber(buff, METERS_TO_NAUTICALMILES(odometerDist) * 100, 1, 1, 1, 6, true); + buff[6] = SYM_NM; + break; + case OSD_UNIT_METRIC_MPH: + FALLTHROUGH; + case OSD_UNIT_METRIC: + osdFormatCentiNumber(buff, METERS_TO_KILOMETERS(odometerDist) * 100, 1, 1, 1, 6, true); + buff[6] = SYM_KM; + break; + } + buff[7] = '\0'; + elemPosX++; + } + break; + case OSD_GROUND_COURSE: { buff[0] = SYM_GROUND_COURSE; @@ -1994,7 +2086,7 @@ static bool osdDrawSingleElement(uint8_t item) digits = 3U; } #endif - osdFormatCentiNumber(&buff[2], centiHDOP, 0, 1, 0, digits); + osdFormatCentiNumber(&buff[2], centiHDOP, 0, 1, 0, digits, false); break; } @@ -2147,43 +2239,48 @@ static bool osdDrawSingleElement(uint8_t item) updatedTimestamp = currentTimeUs; } #endif - //buff[0] = SYM_TRIP_DIST; displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_FLIGHT_DIST_REMAINING); + if ((!ARMING_FLAG(ARMED)) || (distanceMeters == -1)) { - buff[4] = SYM_BLANK; - buff[5] = '\0'; - strcpy(buff + 1, "---"); + buff[3] = SYM_BLANK; + buff[4] = '\0'; + strcpy(buff, "---"); } else if (distanceMeters == -2) { // Wind is too strong to come back with cruise throttle - buff[1] = buff[2] = buff[3] = SYM_WIND_HORIZONTAL; + buff[0] = buff[1] = buff[2] = SYM_WIND_HORIZONTAL; switch ((osd_unit_e)osdConfig()->units){ case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - buff[4] = SYM_DIST_MI; + buff[3] = SYM_DIST_MI; break; case OSD_UNIT_METRIC_MPH: FALLTHROUGH; case OSD_UNIT_METRIC: - buff[4] = SYM_DIST_KM; + buff[3] = SYM_DIST_KM; break; case OSD_UNIT_GA: - buff[4] = SYM_DIST_NM; + buff[3] = SYM_DIST_NM; break; } - buff[5] = '\0'; + buff[4] = '\0'; TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); } else { - osdFormatDistanceSymbol(buff + 1, distanceMeters * 100, 0); + osdFormatDistanceSymbol(buff, distanceMeters * 100, 0); if (distanceMeters == 0) TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); } + elemPosX++; break; case OSD_FLYMODE: { char *p = "ACRO"; - +#ifdef USE_FW_AUTOLAND + if (FLIGHT_MODE(NAV_FW_AUTOLAND)) + p = "LAND"; + else +#endif if (FLIGHT_MODE(FAILSAFE_MODE)) p = "!FS!"; else if (FLIGHT_MODE(MANUAL_MODE)) @@ -2204,7 +2301,7 @@ static bool osdDrawSingleElement(uint8_t item) p = " WP "; else if (FLIGHT_MODE(NAV_ALTHOLD_MODE) && navigationRequiresAngleMode()) { // If navigationRequiresAngleMode() returns false when ALTHOLD is active, - // it means it can be combined with ANGLE, HORIZON, ACRO, etc... + // it means it can be combined with ANGLE, HORIZON, ANGLEHOLD, ACRO, etc... // and its display is handled by OSD_MESSAGES rather than OSD_FLYMODE. p = " AH "; } @@ -2212,6 +2309,8 @@ static bool osdDrawSingleElement(uint8_t item) p = "ANGL"; else if (FLIGHT_MODE(HORIZON_MODE)) p = "HOR "; + else if (FLIGHT_MODE(ANGLEHOLD_MODE)) + p = "ANGH"; displayWrite(osdDisplayPort, elemPosX, elemPosY, p); return true; @@ -2225,6 +2324,12 @@ static bool osdDrawSingleElement(uint8_t item) osdFormatPilotName(buff); break; + case OSD_PILOT_LOGO: + displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_PILOT_LOGO_SML_L); + displayWriteChar(osdDisplayPort, elemPosX+1, elemPosY, SYM_PILOT_LOGO_SML_C); + displayWriteChar(osdDisplayPort, elemPosX+2, elemPosY, SYM_PILOT_LOGO_SML_R); + break; + case OSD_THROTTLE_POS: { osdFormatThrottlePosition(buff, false, &elemAttr); @@ -2423,7 +2528,7 @@ static bool osdDrawSingleElement(uint8_t item) buff[0] = SYM_ROLL_LEVEL; if (ABS(attitude.values.roll) >= 1) buff[0] += (attitude.values.roll < 0 ? -1 : 1); - osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.roll)), 0, 1, 0, 3); + osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.roll)), 0, 1, 0, 3, false); break; case OSD_ATTITUDE_PITCH: @@ -2433,7 +2538,7 @@ static bool osdDrawSingleElement(uint8_t item) buff[0] = SYM_PITCH_DOWN; else if (attitude.values.pitch < 0) buff[0] = SYM_PITCH_UP; - osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.pitch)), 0, 1, 0, 3); + osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.pitch)), 0, 1, 0, 3, false); break; case OSD_ARTIFICIAL_HORIZON: @@ -2494,7 +2599,7 @@ static bool osdDrawSingleElement(uint8_t item) break; } - osdFormatCentiNumber(buff, value, 0, 1, 0, 3); + osdFormatCentiNumber(buff, value, 0, 1, 0, 3, false); buff[3] = sym; buff[4] = '\0'; break; @@ -2527,7 +2632,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_UNIT_IMPERIAL: // mAh/foot if (efficiencyValid) { - osdFormatCentiNumber(buff, (value * METERS_PER_FOOT), 1, 2, 2, 3); + osdFormatCentiNumber(buff, (value * METERS_PER_FOOT), 1, 2, 2, 3, false); tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_FT_0, SYM_AH_V_FT_1); } else { buff[0] = buff[1] = buff[2] = '-'; @@ -2541,7 +2646,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_UNIT_METRIC: // mAh/metre if (efficiencyValid) { - osdFormatCentiNumber(buff, value, 1, 2, 2, 3); + osdFormatCentiNumber(buff, value, 1, 2, 2, 3, false); tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_M_0, SYM_AH_V_M_1); } else { buff[0] = buff[1] = buff[2] = '-'; @@ -2836,7 +2941,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_POWER: { - bool kiloWatt = osdFormatCentiNumber(buff, getPower(), 1000, 2, 2, 3); + bool kiloWatt = osdFormatCentiNumber(buff, getPower(), 1000, 2, 2, 3, false); buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[4] = '\0'; @@ -2999,7 +3104,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10, 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10, 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); } else { @@ -3013,7 +3118,7 @@ static bool osdDrawSingleElement(uint8_t item) } break; case OSD_UNIT_GA: - moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10, 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10, 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); } else { @@ -3029,7 +3134,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_UNIT_METRIC_MPH: FALLTHROUGH; case OSD_UNIT_METRIC: - moreThanAh = osdFormatCentiNumber(buff, value * 100, 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, value * 100, 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); } else { @@ -3070,17 +3175,17 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10000, 0, 2, 0, 3); + osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10000, 0, 2, 0, 3, false); buff[3] = SYM_WH_MI; break; case OSD_UNIT_GA: - osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10000, 0, 2, 0, 3); + osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10000, 0, 2, 0, 3, false); buff[3] = SYM_WH_NM; break; case OSD_UNIT_METRIC_MPH: FALLTHROUGH; case OSD_UNIT_METRIC: - osdFormatCentiNumber(buff, value / 10, 0, 2, 0, 3); + osdFormatCentiNumber(buff, value / 10, 0, 2, 0, 3, false); buff[3] = SYM_WH_KM; break; } @@ -3094,7 +3199,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_GFORCE: { buff[0] = SYM_GFORCE; - osdFormatCentiNumber(buff + 1, GForce, 0, 2, 0, 3); + osdFormatCentiNumber(buff + 1, GForce, 0, 2, 0, 3, false); if (GForce > osdConfig()->gforce_alarm * 100) { TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); } @@ -3107,7 +3212,7 @@ static bool osdDrawSingleElement(uint8_t item) { float GForceValue = GForceAxis[item - OSD_GFORCE_X]; buff[0] = SYM_GFORCE_X + item - OSD_GFORCE_X; - osdFormatCentiNumber(buff + 1, GForceValue, 0, 2, 0, 4); + osdFormatCentiNumber(buff + 1, GForceValue, 0, 2, 0, 4, false); if ((GForceValue < osdConfig()->gforce_axis_alarm_min * 100) || (GForceValue > osdConfig()->gforce_axis_alarm_max * 100)) { TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); } @@ -3283,7 +3388,7 @@ static bool osdDrawSingleElement(uint8_t item) } buff[0] = SYM_SCALE; if (osdMapData.scale > 0) { - bool scaled = osdFormatCentiNumber(&buff[1], osdMapData.scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3); + bool scaled = osdFormatCentiNumber(&buff[1], osdMapData.scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3, false); buff[4] = scaled ? symScaled : symUnscaled; // Make sure this is cleared if the map stops being drawn osdMapData.scale = 0; @@ -3452,14 +3557,14 @@ static bool osdDrawSingleElement(uint8_t item) #ifdef USE_POWER_LIMITS case OSD_PLIMIT_REMAINING_BURST_TIME: - osdFormatCentiNumber(buff, powerLimiterGetRemainingBurstTime() * 100, 0, 1, 0, 3); + osdFormatCentiNumber(buff, powerLimiterGetRemainingBurstTime() * 100, 0, 1, 0, 3, false); buff[3] = 'S'; buff[4] = '\0'; break; case OSD_PLIMIT_ACTIVE_CURRENT_LIMIT: if (currentBatteryProfile->powerLimits.continuousCurrent) { - osdFormatCentiNumber(buff, powerLimiterGetActiveCurrentLimit(), 0, 2, 0, 3); + osdFormatCentiNumber(buff, powerLimiterGetActiveCurrentLimit(), 0, 2, 0, 3, false); buff[3] = SYM_AMP; buff[4] = '\0'; @@ -3473,7 +3578,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_PLIMIT_ACTIVE_POWER_LIMIT: { if (currentBatteryProfile->powerLimits.continuousPower) { - bool kiloWatt = osdFormatCentiNumber(buff, powerLimiterGetActivePowerLimit(), 1000, 2, 2, 3); + bool kiloWatt = osdFormatCentiNumber(buff, powerLimiterGetActivePowerLimit(), 1000, 2, 2, 3, false); buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[4] = '\0'; @@ -3702,7 +3807,7 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig, .pan_servo_offcentre_warning = SETTING_OSD_PAN_SERVO_OFFCENTRE_WARNING_DEFAULT, .pan_servo_indicator_show_degrees = SETTING_OSD_PAN_SERVO_INDICATOR_SHOW_DEGREES_DEFAULT, .esc_rpm_precision = SETTING_OSD_ESC_RPM_PRECISION_DEFAULT, - .mAh_used_precision = SETTING_OSD_MAH_USED_PRECISION_DEFAULT, + .mAh_precision = SETTING_OSD_MAH_PRECISION_DEFAULT, .osd_switch_indicator0_name = SETTING_OSD_SWITCH_INDICATOR_ZERO_NAME_DEFAULT, .osd_switch_indicator0_channel = SETTING_OSD_SWITCH_INDICATOR_ZERO_CHANNEL_DEFAULT, .osd_switch_indicator1_name = SETTING_OSD_SWITCH_INDICATOR_ONE_NAME_DEFAULT, @@ -3715,6 +3820,9 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig, .system_msg_display_time = SETTING_OSD_SYSTEM_MSG_DISPLAY_TIME_DEFAULT, .units = SETTING_OSD_UNITS_DEFAULT, .main_voltage_decimals = SETTING_OSD_MAIN_VOLTAGE_DECIMALS_DEFAULT, + .use_pilot_logo = SETTING_OSD_USE_PILOT_LOGO_DEFAULT, + .inav_to_pilot_logo_spacing = SETTING_OSD_INAV_TO_PILOT_LOGO_SPACING_DEFAULT, + .arm_screen_display_time = SETTING_OSD_ARM_SCREEN_DISPLAY_TIME_DEFAULT, #ifdef USE_WIND_ESTIMATOR .estimations_wind_compensation = SETTING_OSD_ESTIMATIONS_WIND_COMPENSATION_DEFAULT, @@ -3750,6 +3858,7 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig) //line 2 osdLayoutsConfig->item_pos[0][OSD_HOME_DIST] = OSD_POS(1, 1); osdLayoutsConfig->item_pos[0][OSD_TRIP_DIST] = OSD_POS(1, 2); + osdLayoutsConfig->item_pos[0][OSD_ODOMETER] = OSD_POS(1, 3); osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_CELL_VOLTAGE] = OSD_POS(12, 1); osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE] = OSD_POS(12, 1); osdLayoutsConfig->item_pos[0][OSD_GPS_SPEED] = OSD_POS(23, 1); @@ -3787,6 +3896,7 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig) osdLayoutsConfig->item_pos[0][OSD_CRAFT_NAME] = OSD_POS(20, 2); osdLayoutsConfig->item_pos[0][OSD_PILOT_NAME] = OSD_POS(20, 3); + osdLayoutsConfig->item_pos[0][OSD_PILOT_LOGO] = OSD_POS(20, 3); osdLayoutsConfig->item_pos[0][OSD_VTX_CHANNEL] = OSD_POS(8, 6); #ifdef USE_SERIALRX_CRSF @@ -3909,79 +4019,78 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig) } } -static void osdSetNextRefreshIn(uint32_t timeMs) { - resumeRefreshAt = micros() + timeMs * 1000; - refreshWaitForResumeCmdRelease = true; -} +/** + * @brief Draws the INAV and/or pilot logos on the display + * + * @param singular If true, only one logo will be drawn. If false, both logos will be drawn, separated by osdConfig()->inav_to_pilot_logo_spacing characters + * @param row The row number to start drawing the logos. If not singular, both logos are drawn on the same rows. + * @return uint8_t The row number after the logo(s). + */ +uint8_t drawLogos(bool singular, uint8_t row) { + uint8_t logoRow = row; + uint8_t logoColOffset = 0; + bool usePilotLogo = (osdConfig()->use_pilot_logo && osdDisplayIsHD()); + +#ifndef DISABLE_MSP_BF_COMPAT // IF BFCOMPAT is in use, the pilot logo cannot be used, due to font issues. + if (isBfCompatibleVideoSystem(osdConfig())) + usePilotLogo = false; +#endif -static void osdCompleteAsyncInitialization(void) -{ - if (!displayIsReady(osdDisplayPort)) { - // Update the display. - // XXX: Rename displayDrawScreen() and associated functions - // to displayUpdate() - displayDrawScreen(osdDisplayPort); - return; - } + uint8_t logoSpacing = osdConfig()->inav_to_pilot_logo_spacing; - osdDisplayIsReady = true; + if (logoSpacing > 0 && ((osdDisplayPort->cols % 2) != (logoSpacing % 2))) { + logoSpacing++; // Add extra 1 character space between logos, if the odd/even of the OSD cols doesn't match the odd/even of the logo spacing + } -#if defined(USE_CANVAS) - if (osdConfig()->force_grid) { - osdDisplayHasCanvas = false; + // Draw Logo(s) + if (usePilotLogo && !singular) { + logoColOffset = ((osdDisplayPort->cols - (SYM_LOGO_WIDTH * 2)) - logoSpacing) / 2; } else { - osdDisplayHasCanvas = displayGetCanvas(&osdCanvas, osdDisplayPort); + logoColOffset = floorf((osdDisplayPort->cols - SYM_LOGO_WIDTH) / 2.0f); } -#endif - displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); - displayClearScreen(osdDisplayPort); - - uint8_t y = 1; - displayFontMetadata_t metadata; - bool fontHasMetadata = displayGetFontMetadata(&metadata, osdDisplayPort); - LOG_DEBUG(OSD, "Font metadata version %s: %u (%u chars)", - fontHasMetadata ? "Y" : "N", metadata.version, metadata.charCount); - - if (fontHasMetadata && metadata.charCount > 256) { - hasExtendedFont = true; + // Draw INAV logo + if ((singular && !usePilotLogo) || !singular) { unsigned logo_c = SYM_LOGO_START; - unsigned logo_x = OSD_CENTER_LEN(SYM_LOGO_WIDTH); - for (unsigned ii = 0; ii < SYM_LOGO_HEIGHT; ii++) { - for (unsigned jj = 0; jj < SYM_LOGO_WIDTH; jj++) { - displayWriteChar(osdDisplayPort, logo_x + jj, y, logo_c++); + uint8_t logo_x = logoColOffset; + for (uint8_t lRow = 0; lRow < SYM_LOGO_HEIGHT; lRow++) { + for (uint8_t lCol = 0; lCol < SYM_LOGO_WIDTH; lCol++) { + displayWriteChar(osdDisplayPort, logo_x + lCol, logoRow, logo_c++); } - y++; + logoRow++; } - y++; - } else if (!fontHasMetadata) { - const char *m = "INVALID FONT"; - displayWrite(osdDisplayPort, OSD_CENTER_S(m), 3, m); - y = 4; } - if (fontHasMetadata && metadata.version < OSD_MIN_FONT_VERSION) { - const char *m = "INVALID FONT VERSION"; - displayWrite(osdDisplayPort, OSD_CENTER_S(m), y++, m); - } + // Draw the pilot logo + if (usePilotLogo) { + unsigned logo_c = SYM_PILOT_LOGO_LRG_START; + uint8_t logo_x = 0; + logoRow = row; + if (singular) { + logo_x = logoColOffset; + } else { + logo_x = logoColOffset + SYM_LOGO_WIDTH + logoSpacing; + } - char string_buffer[30]; - tfp_sprintf(string_buffer, "INAV VERSION: %s", FC_VERSION_STRING); - uint8_t xPos = osdDisplayIsHD() ? 15 : 5; - displayWrite(osdDisplayPort, xPos, y++, string_buffer); -#ifdef USE_CMS - displayWrite(osdDisplayPort, xPos+2, y++, CMS_STARTUP_HELP_TEXT1); - displayWrite(osdDisplayPort, xPos+6, y++, CMS_STARTUP_HELP_TEXT2); - displayWrite(osdDisplayPort, xPos+6, y++, CMS_STARTUP_HELP_TEXT3); -#endif -#ifdef USE_STATS + for (uint8_t lRow = 0; lRow < SYM_LOGO_HEIGHT; lRow++) { + for (uint8_t lCol = 0; lCol < SYM_LOGO_WIDTH; lCol++) { + displayWriteChar(osdDisplayPort, logo_x + lCol, logoRow, logo_c++); + } + logoRow++; + } + } + return logoRow; +} - uint8_t statNameX = osdDisplayIsHD() ? 14 : 4; - uint8_t statValueX = osdDisplayIsHD() ? 34 : 24; +uint8_t drawStats(uint8_t row) { +#ifdef USE_STATS + char string_buffer[30]; + uint8_t statNameX = (osdDisplayPort->cols - 22) / 2; + uint8_t statValueX = statNameX + 21; if (statsConfig()->stats_enabled) { - displayWrite(osdDisplayPort, statNameX, ++y, "ODOMETER:"); + displayWrite(osdDisplayPort, statNameX, row, "ODOMETER:"); switch (osdConfig()->units) { case OSD_UNIT_UK: FALLTHROUGH; @@ -4002,39 +4111,39 @@ static void osdCompleteAsyncInitialization(void) break; } string_buffer[6] = '\0'; - displayWrite(osdDisplayPort, statValueX-5, y, string_buffer); + displayWrite(osdDisplayPort, statValueX-5, row, string_buffer); - displayWrite(osdDisplayPort, statNameX, ++y, "TOTAL TIME:"); + displayWrite(osdDisplayPort, statNameX, ++row, "TOTAL TIME:"); uint32_t tot_mins = statsConfig()->stats_total_time / 60; - tfp_sprintf(string_buffer, "%2d:%02dHM", (int)(tot_mins / 60), (int)(tot_mins % 60)); - displayWrite(osdDisplayPort, statValueX-5, y, string_buffer); + tfp_sprintf(string_buffer, "%2d:%02dH:M", (int)(tot_mins / 60), (int)(tot_mins % 60)); + displayWrite(osdDisplayPort, statValueX-7, row, string_buffer); #ifdef USE_ADC if (feature(FEATURE_VBAT) && feature(FEATURE_CURRENT_METER)) { - displayWrite(osdDisplayPort, statNameX, ++y, "TOTAL ENERGY:"); - osdFormatCentiNumber(string_buffer, statsConfig()->stats_total_energy / 10, 0, 2, 0, 4); - strcat(string_buffer, "\xAB"); // SYM_WH - displayWrite(osdDisplayPort, statValueX-4, y, string_buffer); + displayWrite(osdDisplayPort, statNameX, ++row, "TOTAL ENERGY:"); + osdFormatCentiNumber(string_buffer, statsConfig()->stats_total_energy / 10, 0, 2, 0, 4, false); + displayWrite(osdDisplayPort, statValueX-4, row, string_buffer); + displayWriteChar(osdDisplayPort, statValueX, row, SYM_WH); - displayWrite(osdDisplayPort, statNameX, ++y, "AVG EFFICIENCY:"); + displayWrite(osdDisplayPort, statNameX, ++row, "AVG EFFICIENCY:"); if (statsConfig()->stats_total_dist) { uint32_t avg_efficiency = statsConfig()->stats_total_energy / (statsConfig()->stats_total_dist / METERS_PER_KILOMETER); // mWh/km switch (osdConfig()->units) { case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_IMPERIAL: - osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3); + osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3, false); string_buffer[3] = SYM_WH_MI; break; case OSD_UNIT_GA: - osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3); + osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3, false); string_buffer[3] = SYM_WH_NM; break; default: case OSD_UNIT_METRIC_MPH: FALLTHROUGH; case OSD_UNIT_METRIC: - osdFormatCentiNumber(string_buffer, avg_efficiency / 10000 * METERS_PER_MILE, 0, 2, 0, 3); + osdFormatCentiNumber(string_buffer, avg_efficiency / 10000 * METERS_PER_MILE, 0, 2, 0, 3, false); string_buffer[3] = SYM_WH_KM; break; } @@ -4042,10 +4151,75 @@ static void osdCompleteAsyncInitialization(void) string_buffer[0] = string_buffer[1] = string_buffer[2] = '-'; } string_buffer[4] = '\0'; - displayWrite(osdDisplayPort, statValueX-3, y, string_buffer); + displayWrite(osdDisplayPort, statValueX-3, row++, string_buffer); } #endif // USE_ADC } +#endif // USE_STATS + return row; +} + +static void osdSetNextRefreshIn(uint32_t timeMs) { + resumeRefreshAt = micros() + timeMs * 1000; + refreshWaitForResumeCmdRelease = true; +} + +static void osdCompleteAsyncInitialization(void) +{ + if (!displayIsReady(osdDisplayPort)) { + // Update the display. + // XXX: Rename displayDrawScreen() and associated functions + // to displayUpdate() + displayDrawScreen(osdDisplayPort); + return; + } + + osdDisplayIsReady = true; + +#if defined(USE_CANVAS) + if (osdConfig()->force_grid) { + osdDisplayHasCanvas = false; + } else { + osdDisplayHasCanvas = displayGetCanvas(&osdCanvas, osdDisplayPort); + } +#endif + + displayBeginTransaction(osdDisplayPort, DISPLAY_TRANSACTION_OPT_RESET_DRAWING); + displayClearScreen(osdDisplayPort); + + uint8_t y = 1; + displayFontMetadata_t metadata; + bool fontHasMetadata = displayGetFontMetadata(&metadata, osdDisplayPort); + LOG_DEBUG(OSD, "Font metadata version %s: %u (%u chars)", + fontHasMetadata ? "Y" : "N", metadata.version, metadata.charCount); + + if (fontHasMetadata && metadata.charCount > 256) { + hasExtendedFont = true; + + y = drawLogos(false, y); + y++; + } else if (!fontHasMetadata) { + const char *m = "INVALID FONT"; + displayWrite(osdDisplayPort, OSD_CENTER_S(m), y++, m); + } + + if (fontHasMetadata && metadata.version < OSD_MIN_FONT_VERSION) { + const char *m = "INVALID FONT VERSION"; + displayWrite(osdDisplayPort, OSD_CENTER_S(m), y++, m); + } + + char string_buffer[30]; + tfp_sprintf(string_buffer, "INAV VERSION: %s", FC_VERSION_STRING); + uint8_t xPos = (osdDisplayPort->cols - 19) / 2; // Automatically centre, regardless of resolution. In the case of odd number screens, bias to the left. + displayWrite(osdDisplayPort, xPos, y++, string_buffer); +#ifdef USE_CMS + displayWrite(osdDisplayPort, xPos+2, y++, CMS_STARTUP_HELP_TEXT1); + displayWrite(osdDisplayPort, xPos+6, y++, CMS_STARTUP_HELP_TEXT2); + displayWrite(osdDisplayPort, xPos+6, y++, CMS_STARTUP_HELP_TEXT3); +#endif + +#ifdef USE_STATS + y = drawStats(++y); #endif displayCommitTransaction(osdDisplayPort); @@ -4249,22 +4423,22 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) if (isSinglePageStatsCompatible || page == 1) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); - osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); + osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2, false); } else { displayWrite(osdDisplayPort, statNameX, top, "MIN CELL VOLTAGE :"); - osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3); + osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3, false); } tfp_sprintf(buff, "%s%c", buff, SYM_VOLT); displayWrite(osdDisplayPort, statValuesX, top++, buff); if (feature(FEATURE_CURRENT_METER)) { displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :"); - osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3); + osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3, false); tfp_sprintf(buff, "%s%c", buff, SYM_AMP); displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :"); - bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3); + bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3, false); buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[4] = '\0'; displayWrite(osdDisplayPort, statValuesX, top++, buff); @@ -4273,7 +4447,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { tfp_sprintf(buff, "%d%c", (int)getMAhDrawn(), SYM_MAH); } else { - osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); + osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3, false); tfp_sprintf(buff, "%s%c", buff, SYM_WH); } displayWrite(osdDisplayPort, statValuesX, top++, buff); @@ -4295,7 +4469,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) FALLTHROUGH; case OSD_UNIT_IMPERIAL: if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); } else { @@ -4308,7 +4482,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) buff[5] = '\0'; } } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, digits); + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, digits, false); tfp_sprintf(buff, "%s%c", buff, SYM_WH_MI); if (!efficiencyValid) { buff[0] = buff[1] = buff[2] = '-'; @@ -4317,7 +4491,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) break; case OSD_UNIT_GA: if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); } else { @@ -4330,7 +4504,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) buff[5] = '\0'; } } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, digits); + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, digits, false); tfp_sprintf(buff, "%s%c", buff, SYM_WH_NM); if (!efficiencyValid) { buff[0] = buff[1] = buff[2] = '-'; @@ -4341,7 +4515,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) FALLTHROUGH; case OSD_UNIT_METRIC: if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { - moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, digits); + moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, digits, false); if (!moreThanAh) { tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); } else { @@ -4354,7 +4528,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) buff[5] = '\0'; } } else { - osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, digits); + osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, digits, false); tfp_sprintf(buff, "%s%c", buff, SYM_WH_KM); if (!efficiencyValid) { buff[0] = buff[1] = buff[2] = '-'; @@ -4369,19 +4543,19 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) const float max_gforce = accGetMeasuredMaxG(); displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :"); - osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3); + osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3, false); displayWrite(osdDisplayPort, statValuesX, top++, buff); const acc_extremes_t *acc_extremes = accGetMeasuredExtremes(); const float acc_extremes_min = acc_extremes[Z].min; const float acc_extremes_max = acc_extremes[Z].max; displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); - osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4); + osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4, false); osdLeftAlignString(buff); strcat(osdFormatTrimWhiteSpace(buff),"/"); multiValueLengthOffset = strlen(buff); displayWrite(osdDisplayPort, statValuesX, top, buff); - osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3); + osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3, false); osdLeftAlignString(buff); displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); } @@ -4399,85 +4573,205 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page) displayCommitTransaction(osdDisplayPort); } -// called when motors armed -static void osdShowArmed(void) +// HD arming screen. based on the minimum HD OSD grid size of 50 x 18 +static void osdShowHDArmScreen(void) { - dateTime_t dt; - char buf[MAX(32, FORMATTED_DATE_TIME_BUFSIZE)]; - char craftNameBuf[MAX_NAME_LENGTH]; - char versionBuf[30]; - char *date; - char *time; - // We need 12 visible rows, start row never < first fully visible row 1 - uint8_t y = osdDisplayPort->rows > 13 ? (osdDisplayPort->rows - 12) / 2 : 1; + dateTime_t dt; + char buf[MAX(osdDisplayPort->cols, FORMATTED_DATE_TIME_BUFSIZE)]; + char buf2[MAX(osdDisplayPort->cols, FORMATTED_DATE_TIME_BUFSIZE)]; + char craftNameBuf[MAX_NAME_LENGTH]; + char versionBuf[osdDisplayPort->cols]; + uint8_t safehomeRow = 0; + uint8_t armScreenRow = 2; // Start at row 2 - displayClearScreen(osdDisplayPort); - strcpy(buf, "ARMED"); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y, buf); - y += 2; + armScreenRow = drawLogos(false, armScreenRow); + armScreenRow++; if (strlen(systemConfig()->craftName) > 0) { osdFormatCraftName(craftNameBuf); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(systemConfig()->craftName)) / 2, y, craftNameBuf ); - y += 1; + strcpy(buf2, "ARMED!"); + tfp_sprintf(buf, "%s - %s", craftNameBuf, buf2); + } else { + strcpy(buf, "ARMED!"); } + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); +#if defined(USE_GPS) +#if defined (USE_SAFE_HOME) + if (posControl.safehomeState.distance) { + safehomeRow = armScreenRow; + armScreenRow++; + } +#endif // USE_SAFE_HOME +#endif // USE_GPS + armScreenRow++; + if (posControl.waypointListValid && posControl.waypointCount > 0) { #ifdef USE_MULTI_MISSION tfp_sprintf(buf, "MISSION %u/%u (%u WP)", posControl.loadedMultiMissionIndex, posControl.multiMissionCount, posControl.waypointCount); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y, buf); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); #else strcpy(buf, "*MISSION LOADED*"); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y, buf); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); #endif } - y += 1; + armScreenRow++; #if defined(USE_GPS) if (feature(FEATURE_GPS)) { if (STATE(GPS_FIX_HOME)) { - if (osdConfig()->osd_home_position_arm_screen){ + if (osdConfig()->osd_home_position_arm_screen) { osdFormatCoordinate(buf, SYM_LAT, GPS_home.lat); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y, buf); - osdFormatCoordinate(buf, SYM_LON, GPS_home.lon); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y + 1, buf); + osdFormatCoordinate(buf2, SYM_LON, GPS_home.lon); + uint8_t gap = 1; + uint8_t col = strlen(buf) + strlen(buf2) + gap; + + if ((osdDisplayPort->cols %2) != (col %2)) { + gap++; + col++; + } + + col = (osdDisplayPort->cols - col) / 2; + + displayWrite(osdDisplayPort, col, armScreenRow, buf); + displayWrite(osdDisplayPort, col + strlen(buf) + gap, armScreenRow++, buf2); + int digits = osdConfig()->plus_code_digits; olc_encode(GPS_home.lat, GPS_home.lon, digits, buf, sizeof(buf)); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y + 2, buf); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); } - y += 4; + #if defined (USE_SAFE_HOME) if (posControl.safehomeState.distance) { // safehome found during arming if (navConfig()->general.flags.safehome_usage_mode == SAFEHOME_USAGE_OFF) { strcpy(buf, "SAFEHOME FOUND; MODE OFF"); } else { - char buf2[12]; // format the distance first osdFormatDistanceStr(buf2, posControl.safehomeState.distance); - tfp_sprintf(buf, "%c - %s -> SAFEHOME %u", SYM_HOME, buf2, posControl.safehomeState.index); + tfp_sprintf(buf, "%c SAFEHOME %u @ %s", SYM_HOME, posControl.safehomeState.index, buf2); } textAttributes_t elemAttr = _TEXT_ATTRIBUTES_BLINK_BIT; - // write this message above the ARMED message to make it obvious - displayWriteWithAttr(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y - 8, buf, elemAttr); + // write this message below the ARMED message to make it obvious + displayWriteWithAttr(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, safehomeRow, buf, elemAttr); } #endif } else { strcpy(buf, "!NO HOME POSITION!"); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y, buf); - y += 1; + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); } + armScreenRow++; + } +#endif + + if (rtcGetDateTimeLocal(&dt)) { + tfp_sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", dt.year, dt.month, dt.day, dt.hours, dt.minutes, dt.seconds); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); + armScreenRow++; } + + tfp_sprintf(versionBuf, "INAV VERSION: %s", FC_VERSION_STRING); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(versionBuf)) / 2, armScreenRow++, versionBuf); + armScreenRow++; + +#ifdef USE_STATS + if (armScreenRow < (osdDisplayPort->rows - 4)) + armScreenRow = drawStats(armScreenRow); +#endif // USE_STATS +} + +static void osdShowSDArmScreen(void) +{ + dateTime_t dt; + char buf[MAX(osdDisplayPort->cols, FORMATTED_DATE_TIME_BUFSIZE)]; + char buf2[MAX(osdDisplayPort->cols, FORMATTED_DATE_TIME_BUFSIZE)]; + char craftNameBuf[MAX_NAME_LENGTH]; + char versionBuf[osdDisplayPort->cols]; + // We need 12 visible rows, start row never < first fully visible row 1 + uint8_t armScreenRow = osdDisplayPort->rows > 13 ? (osdDisplayPort->rows - 12) / 2 : 1; + uint8_t safehomeRow = 0; + + strcpy(buf, "ARMED!"); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); + safehomeRow = armScreenRow; + armScreenRow++; + + if (strlen(systemConfig()->craftName) > 0) { + osdFormatCraftName(craftNameBuf); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(systemConfig()->craftName)) / 2, armScreenRow++, craftNameBuf ); + } + + if (posControl.waypointListValid && posControl.waypointCount > 0) { +#ifdef USE_MULTI_MISSION + tfp_sprintf(buf, "MISSION %u/%u (%u WP)", posControl.loadedMultiMissionIndex, posControl.multiMissionCount, posControl.waypointCount); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow, buf); +#else + strcpy(buf, "*MISSION LOADED*"); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow, buf); #endif + } + armScreenRow++; - if (rtcGetDateTime(&dt)) { - dateTimeFormatLocal(buf, &dt); - dateTimeSplitFormatted(buf, &date, &time); +#if defined(USE_GPS) + if (feature(FEATURE_GPS)) { + if (STATE(GPS_FIX_HOME)) { + if (osdConfig()->osd_home_position_arm_screen) { + osdFormatCoordinate(buf, SYM_LAT, GPS_home.lat); + osdFormatCoordinate(buf2, SYM_LON, GPS_home.lon); + + uint8_t gpsStartCol = (osdDisplayPort->cols - (strlen(buf) + strlen(buf2) + 2)) / 2; + displayWrite(osdDisplayPort, gpsStartCol, armScreenRow, buf); + displayWrite(osdDisplayPort, gpsStartCol + strlen(buf) + 2, armScreenRow++, buf2); + + int digits = osdConfig()->plus_code_digits; + olc_encode(GPS_home.lat, GPS_home.lon, digits, buf, sizeof(buf)); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); + } - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(date)) / 2, y, date); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(time)) / 2, y + 1, time); - y += 3; +#if defined (USE_SAFE_HOME) + if (posControl.safehomeState.distance) { // safehome found during arming + if (navConfig()->general.flags.safehome_usage_mode == SAFEHOME_USAGE_OFF) { + strcpy(buf, "SAFEHOME FOUND; MODE OFF"); + } else { + osdFormatDistanceStr(buf2, posControl.safehomeState.distance); + tfp_sprintf(buf, "%c SAFEHOME %u @ %s", SYM_HOME, posControl.safehomeState.index, buf2); + } + textAttributes_t elemAttr = _TEXT_ATTRIBUTES_BLINK_BIT; + // write this message below the ARMED message to make it obvious + displayWriteWithAttr(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, safehomeRow, buf, elemAttr); + } +#endif + } else { + strcpy(buf, "!NO HOME POSITION!"); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); + } + armScreenRow++; + } +#endif + + if (rtcGetDateTimeLocal(&dt)) { + tfp_sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", dt.year, dt.month, dt.day, dt.hours, dt.minutes, dt.seconds); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, armScreenRow++, buf); + armScreenRow++; } tfp_sprintf(versionBuf, "INAV VERSION: %s", FC_VERSION_STRING); - displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(versionBuf)) / 2, y, versionBuf); + displayWrite(osdDisplayPort, (osdDisplayPort->cols - strlen(versionBuf)) / 2, armScreenRow++, versionBuf); + armScreenRow++; + +#ifdef USE_STATS + if (armScreenRow < (osdDisplayPort->rows - 4)) + armScreenRow = drawStats(armScreenRow); +#endif // USE_STATS +} + +// called when motors armed +static void osdShowArmed(void) +{ + displayClearScreen(osdDisplayPort); + + if (osdDisplayIsHD()) { + osdShowHDArmScreen(); + } else { + osdShowSDArmScreen(); + } } static void osdFilterData(timeUs_t currentTimeUs) { @@ -4578,10 +4872,14 @@ static void osdRefresh(timeUs_t currentTimeUs) statsDisplayed = false; osdResetStats(); osdShowArmed(); - uint32_t delay = ARMED_SCREEN_DISPLAY_TIME; + uint16_t delay = osdConfig()->arm_screen_display_time; + if (STATE(IN_FLIGHT_EMERG_REARM)) { + delay = 500; + } #if defined(USE_SAFE_HOME) - if (posControl.safehomeState.distance) - delay *= 3; + else if (posControl.safehomeState.distance) { + delay += 3000; + } #endif osdSetNextRefreshIn(delay); } else { @@ -4843,8 +5141,13 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter const char *invertedInfoMessage = NULL; if (ARMING_FLAG(ARMED)) { +#ifdef USE_FW_AUTOLAND + if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding() || FLIGHT_MODE(NAV_FW_AUTOLAND)) { + if (isWaypointMissionRTHActive() && !posControl.fwLandState.landWp) { +#else if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding()) { if (isWaypointMissionRTHActive()) { +#endif // if RTH activated whilst WP mode selected, remind pilot to cancel WP mode to exit RTH messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_WP_RTH_CANCEL); } @@ -4869,12 +5172,28 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter messages[messageCount++] = messageBuf; } - } else { - const char *navStateMessage = navigationStateMessage(); - if (navStateMessage) { - messages[messageCount++] = navStateMessage; + } else if (NAV_Status.state == MW_NAV_STATE_LAND_SETTLE && posControl.landingDelay > 0) { + uint16_t remainingHoldSec = MS2S(posControl.landingDelay - millis()); + tfp_sprintf(messageBuf, "LANDING DELAY: %3u SECONDS", remainingHoldSec); + + messages[messageCount++] = messageBuf; + } + + else { +#ifdef USE_FW_AUTOLAND + if (canFwLandCanceld()) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_MOVE_STICKS); + } else if (!FLIGHT_MODE(NAV_FW_AUTOLAND)) { +#endif + const char *navStateMessage = navigationStateMessage(); + if (navStateMessage) { + messages[messageCount++] = navStateMessage; + } +#ifdef USE_FW_AUTOLAND } +#endif } + #if defined(USE_SAFE_HOME) const char *safehomeMessage = divertingToSafehomeMessage(); if (safehomeMessage) { @@ -4903,10 +5222,9 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter } } else { if (FLIGHT_MODE(NAV_ALTHOLD_MODE) && !navigationRequiresAngleMode()) { - // ALTHOLD might be enabled alongside ANGLE/HORIZON/ACRO + // ALTHOLD might be enabled alongside ANGLE/HORIZON/ANGLEHOLD/ACRO // when it doesn't require ANGLE mode (required only in FW - // right now). If if requires ANGLE, its display is handled - // by OSD_FLYMODE. + // right now). If it requires ANGLE, its display is handled by OSD_FLYMODE. messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_ALTITUDE_HOLD); } if (STATE(MULTIROTOR) && FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { @@ -4928,8 +5246,8 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_AUTOTUNE_ACRO); } } - if (IS_RC_MODE_ACTIVE(BOXAUTOLEVEL) && (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE) || (navigationRequiresAngleMode() && !navigationIsControllingAltitude()))) { - messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_AUTOLEVEL); + if (isFixedWingLevelTrimActive()) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_AUTOLEVEL); } if (FLIGHT_MODE(HEADFREE_MODE)) { messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_HEADFREE); @@ -4943,6 +5261,16 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter if (STATE(LANDING_DETECTED)) { messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_LANDED); } + if (IS_RC_MODE_ACTIVE(BOXANGLEHOLD)) { + int8_t navAngleHoldAxis = navCheckActiveAngleHoldAxis(); + if (isAngleHoldLevel()) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_ANGLEHOLD_LEVEL); + } else if (navAngleHoldAxis == FD_ROLL) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_ANGLEHOLD_ROLL); + } else if (navAngleHoldAxis == FD_PITCH) { + messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_ANGLEHOLD_PITCH); + } + } } } } else if (ARMING_FLAG(ARMING_DISABLED_ALL_FLAGS)) { @@ -5198,4 +5526,5 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff) return elemAttr; } + #endif // OSD diff --git a/src/main/io/osd.h b/src/main/io/osd.h index 04794c6cec2..8e1a38891f5 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -93,6 +93,7 @@ #define OSD_MSG_RTH_CLIMB "ADJUSTING RTH ALTITUDE" #define OSD_MSG_RTH_TRACKBACK "RTH BACK TRACKING" #define OSD_MSG_HEADING_HOME "EN ROUTE TO HOME" +#define OSD_MSG_RTH_LINEAR_DESCENT "BEGIN LINEAR DESCENT" #define OSD_MSG_WP_FINISHED "WP END>HOLDING POSITION" #define OSD_MSG_WP_LANDED "WP END>LANDED" #define OSD_MSG_PREPARE_NEXT_WP "PREPARING FOR NEXT WAYPOINT" @@ -118,6 +119,10 @@ #define OSD_MSG_UNABLE_ARM "UNABLE TO ARM" #define OSD_MSG_SAVING_SETTNGS "** SAVING SETTINGS **" #define OSD_MSG_SETTINGS_SAVED "** SETTINGS SAVED **" +#define OSD_MSG_ANGLEHOLD_ROLL "(ANGLEHOLD ROLL)" +#define OSD_MSG_ANGLEHOLD_PITCH "(ANGLEHOLD PITCH)" +#define OSD_MSG_ANGLEHOLD_LEVEL "(ANGLEHOLD LEVEL)" +#define OSD_MSG_MOVE_STICKS "MOVE STICKS TO ABORT" #ifdef USE_DEV_TOOLS #define OSD_MSG_GRD_TEST_MODE "GRD TEST > MOTORS DISABLED" @@ -274,15 +279,20 @@ typedef enum { OSD_PILOT_NAME, OSD_PAN_SERVO_CENTRED, OSD_MULTI_FUNCTION, + OSD_ODOMETER, + OSD_PILOT_LOGO, + OSD_CUSTOM_ELEMENT_1, + OSD_CUSTOM_ELEMENT_2, + OSD_CUSTOM_ELEMENT_3, OSD_ITEM_COUNT // MUST BE LAST } osd_items_e; typedef enum { OSD_UNIT_IMPERIAL, OSD_UNIT_METRIC, - OSD_UNIT_METRIC_MPH, // Old UK units, all metric except speed in mph - OSD_UNIT_UK, // Show everything in imperial, temperature in C - OSD_UNIT_GA, // General Aviation: Knots, Nautical Miles, Feet, Degrees C + OSD_UNIT_METRIC_MPH, // Old UK units, all metric except speed in mph + OSD_UNIT_UK, // Show everything in imperial, temperature in C + OSD_UNIT_GA, // General Aviation: Knots, Nautical Miles, Feet, Degrees C OSD_UNIT_MAX = OSD_UNIT_GA, } osd_unit_e; @@ -343,111 +353,112 @@ PG_DECLARE(osdLayoutsConfig_t, osdLayoutsConfig); typedef struct osdConfig_s { // Alarms - uint8_t rssi_alarm; // rssi % - uint16_t time_alarm; // fly minutes - uint16_t alt_alarm; // positive altitude in m - uint16_t dist_alarm; // home distance in m - uint16_t neg_alt_alarm; // abs(negative altitude) in m - uint8_t current_alarm; // current consumption in A - int16_t imu_temp_alarm_min; - int16_t imu_temp_alarm_max; - int16_t esc_temp_alarm_min; - int16_t esc_temp_alarm_max; - float gforce_alarm; - float gforce_axis_alarm_min; - float gforce_axis_alarm_max; + uint8_t rssi_alarm; // rssi % + uint16_t time_alarm; // fly minutes + uint16_t alt_alarm; // positive altitude in m + uint16_t dist_alarm; // home distance in m + uint16_t neg_alt_alarm; // abs(negative altitude) in m + uint8_t current_alarm; // current consumption in A + int16_t imu_temp_alarm_min; + int16_t imu_temp_alarm_max; + int16_t esc_temp_alarm_min; + int16_t esc_temp_alarm_max; + float gforce_alarm; + float gforce_axis_alarm_min; + float gforce_axis_alarm_max; #ifdef USE_SERIALRX_CRSF - int8_t snr_alarm; //CRSF SNR alarm in dB - int8_t link_quality_alarm; - int16_t rssi_dbm_alarm; // in dBm - int16_t rssi_dbm_max; // Perfect RSSI. Set to High end of curve. RSSI at 100% - int16_t rssi_dbm_min; // Worst RSSI. Set to low end of curve or RX sensitivity level. RSSI at 0% + int8_t snr_alarm; //CRSF SNR alarm in dB + int8_t link_quality_alarm; + int16_t rssi_dbm_alarm; // in dBm + int16_t rssi_dbm_max; // Perfect RSSI. Set to High end of curve. RSSI at 100% + int16_t rssi_dbm_min; // Worst RSSI. Set to low end of curve or RX sensitivity level. RSSI at 0% #endif #ifdef USE_BARO - int16_t baro_temp_alarm_min; - int16_t baro_temp_alarm_max; + int16_t baro_temp_alarm_min; + int16_t baro_temp_alarm_max; #endif #ifdef USE_TEMPERATURE_SENSOR osd_alignment_e temp_label_align; #endif #ifdef USE_PITOT - float airspeed_alarm_min; - float airspeed_alarm_max; + float airspeed_alarm_min; + float airspeed_alarm_max; #endif - videoSystem_e video_system; - uint8_t row_shiftdown; - int16_t msp_displayport_fullframe_interval; + videoSystem_e video_system; + uint8_t row_shiftdown; + int16_t msp_displayport_fullframe_interval; // Preferences - uint8_t main_voltage_decimals; - uint8_t ahi_reverse_roll; - uint8_t ahi_max_pitch; - uint8_t crosshairs_style; // from osd_crosshairs_style_e - int8_t horizon_offset; - int8_t camera_uptilt; - bool ahi_camera_uptilt_comp; - uint8_t camera_fov_h; - uint8_t camera_fov_v; - uint8_t hud_margin_h; - uint8_t hud_margin_v; - bool hud_homing; - bool hud_homepoint; - uint8_t hud_radar_disp; - uint16_t hud_radar_range_min; - uint16_t hud_radar_range_max; - uint8_t hud_radar_alt_difference_display_time; - uint8_t hud_radar_distance_display_time; - uint8_t hud_wp_disp; - - uint8_t left_sidebar_scroll; // from osd_sidebar_scroll_e - uint8_t right_sidebar_scroll; // from osd_sidebar_scroll_e - uint8_t sidebar_scroll_arrows; - - uint8_t units; // from osd_unit_e - uint8_t stats_energy_unit; // from osd_stats_energy_unit_e - uint8_t stats_min_voltage_unit; // from osd_stats_min_voltage_unit_e - uint8_t stats_page_auto_swap_time; // stats page auto swap interval time (seconds) + uint8_t main_voltage_decimals; + uint8_t ahi_reverse_roll; + uint8_t ahi_max_pitch; + uint8_t crosshairs_style; // from osd_crosshairs_style_e + int8_t horizon_offset; + int8_t camera_uptilt; + bool ahi_camera_uptilt_comp; + uint8_t camera_fov_h; + uint8_t camera_fov_v; + uint8_t hud_margin_h; + uint8_t hud_margin_v; + bool hud_homing; + bool hud_homepoint; + uint8_t hud_radar_disp; + uint16_t hud_radar_range_min; + uint16_t hud_radar_range_max; + uint8_t hud_radar_alt_difference_display_time; + uint8_t hud_radar_distance_display_time; + uint8_t hud_wp_disp; + + uint8_t left_sidebar_scroll; // from osd_sidebar_scroll_e + uint8_t right_sidebar_scroll; // from osd_sidebar_scroll_e + uint8_t sidebar_scroll_arrows; + + uint8_t units; // from osd_unit_e + uint8_t stats_energy_unit; // from osd_stats_energy_unit_e + uint8_t stats_min_voltage_unit; // from osd_stats_min_voltage_unit_e + uint8_t stats_page_auto_swap_time; // stats page auto swap interval time (seconds) #ifdef USE_WIND_ESTIMATOR - bool estimations_wind_compensation; // use wind compensation for estimated remaining flight/distance + bool estimations_wind_compensation; // use wind compensation for estimated remaining flight/distance #endif - - uint8_t coordinate_digits; - - bool osd_failsafe_switch_layout; - uint8_t plus_code_digits; // Number of digits to use in OSD_PLUS_CODE - uint8_t plus_code_short; - uint8_t ahi_style; - uint8_t force_grid; // Force a pixel based OSD to use grid mode. - uint8_t ahi_bordered; // Only used by the AHI widget - uint8_t ahi_width; // In pixels, only used by the AHI widget - uint8_t ahi_height; // In pixels, only used by the AHI widget - int8_t ahi_vertical_offset; // Offset from center in pixels. Positive moves the AHI down. Widget only. - int8_t sidebar_horizontal_offset; // Horizontal offset from default position. Units are grid slots for grid OSDs, pixels for pixel based OSDs. Positive values move sidebars closer to the edges. - uint8_t left_sidebar_scroll_step; // How many units each sidebar step represents. 0 means the default value for the scroll type. - uint8_t right_sidebar_scroll_step; // Same as left_sidebar_scroll_step, but for the right sidebar. - bool osd_home_position_arm_screen; - uint8_t pan_servo_index; // Index of the pan servo used for home direction offset - int8_t pan_servo_pwm2centideg; // Centidegrees of servo rotation per us pwm - uint8_t pan_servo_offcentre_warning; // Degrees around the centre, that is assumed camera is wanted to be facing forwards, but isn't centred - bool pan_servo_indicator_show_degrees; // Show the degrees of offset for the pan servo - uint8_t crsf_lq_format; - uint8_t sidebar_height; // sidebar height in rows, 0 turns off sidebars leaving only level indicator arrows - uint8_t telemetry; // use telemetry on displayed pixel line 0 - uint8_t esc_rpm_precision; // Number of characters used for the RPM numbers. - uint16_t system_msg_display_time; // system message display time for multiple messages (ms) - uint8_t mAh_used_precision; // Number of numbers used for mAh drawn. Plently of packs now are > 9999 mAh - uint8_t ahi_pitch_interval; // redraws AHI at set pitch interval (Not pixel OSD) - char osd_switch_indicator0_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 0. - uint8_t osd_switch_indicator0_channel; // RC Channel to use for switch indicator 0. - char osd_switch_indicator1_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 1. - uint8_t osd_switch_indicator1_channel; // RC Channel to use for switch indicator 1. - char osd_switch_indicator2_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 2. - uint8_t osd_switch_indicator2_channel; // RC Channel to use for switch indicator 2. - char osd_switch_indicator3_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 3. - uint8_t osd_switch_indicator3_channel; // RC Channel to use for switch indicator 3. - bool osd_switch_indicators_align_left; // Align switch indicator name to left of the switch. + uint8_t coordinate_digits; + bool osd_failsafe_switch_layout; + uint8_t plus_code_digits; // Number of digits to use in OSD_PLUS_CODE + uint8_t plus_code_short; + uint8_t ahi_style; + uint8_t force_grid; // Force a pixel based OSD to use grid mode. + uint8_t ahi_bordered; // Only used by the AHI widget + uint8_t ahi_width; // In pixels, only used by the AHI widget + uint8_t ahi_height; // In pixels, only used by the AHI widget + int8_t ahi_vertical_offset; // Offset from center in pixels. Positive moves the AHI down. Widget only. + int8_t sidebar_horizontal_offset; // Horizontal offset from default position. Units are grid slots for grid OSDs, pixels for pixel based OSDs. Positive values move sidebars closer to the edges. + uint8_t left_sidebar_scroll_step; // How many units each sidebar step represents. 0 means the default value for the scroll type. + uint8_t right_sidebar_scroll_step; // Same as left_sidebar_scroll_step, but for the right sidebar. + bool osd_home_position_arm_screen; + uint8_t pan_servo_index; // Index of the pan servo used for home direction offset + int8_t pan_servo_pwm2centideg; // Centidegrees of servo rotation per us pwm + uint8_t pan_servo_offcentre_warning; // Degrees around the centre, that is assumed camera is wanted to be facing forwards, but isn't centred + bool pan_servo_indicator_show_degrees; // Show the degrees of offset for the pan servo + uint8_t crsf_lq_format; + uint8_t sidebar_height; // sidebar height in rows, 0 turns off sidebars leaving only level indicator arrows + uint8_t telemetry; // use telemetry on displayed pixel line 0 + uint8_t esc_rpm_precision; // Number of characters used for the RPM numbers. + uint16_t system_msg_display_time; // system message display time for multiple messages (ms) + uint8_t mAh_precision; // Number of numbers used for mAh drawn. Plently of packs now are > 9999 mAh + uint8_t ahi_pitch_interval; // redraws AHI at set pitch interval (Not pixel OSD) + char osd_switch_indicator0_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 0. + uint8_t osd_switch_indicator0_channel; // RC Channel to use for switch indicator 0. + char osd_switch_indicator1_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 1. + uint8_t osd_switch_indicator1_channel; // RC Channel to use for switch indicator 1. + char osd_switch_indicator2_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 2. + uint8_t osd_switch_indicator2_channel; // RC Channel to use for switch indicator 2. + char osd_switch_indicator3_name[OSD_SWITCH_INDICATOR_NAME_LENGTH + 1]; // Name to use for switch indicator 3. + uint8_t osd_switch_indicator3_channel; // RC Channel to use for switch indicator 3. + bool osd_switch_indicators_align_left; // Align switch indicator name to left of the switch. + bool use_pilot_logo; // If enabled, the pilot logo (last 40 characters of page 2 font) will be used with the INAV logo. + uint8_t inav_to_pilot_logo_spacing; // The space between the INAV and pilot logos, if pilot logo is used. This number may be adjusted so that it fits the odd/even col width. + uint16_t arm_screen_display_time; // Length of time the arm screen is displayed } osdConfig_t; PG_DECLARE(osdConfig_t, osdConfig); @@ -483,7 +494,7 @@ void osdStartedSaveProcess(void); void osdShowEEPROMSavedNotification(void); void osdCrosshairPosition(uint8_t *x, uint8_t *y); -bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length); +bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros); void osdFormatAltitudeSymbol(char *buff, int32_t alt); void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max); // Returns a heading angle in degrees normalized to [0, 360). diff --git a/src/main/io/osd/custom_elements.c b/src/main/io/osd/custom_elements.c new file mode 100644 index 00000000000..fbd05e2be61 --- /dev/null +++ b/src/main/io/osd/custom_elements.c @@ -0,0 +1,141 @@ +/* + * 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 "config/config_reset.h" +#include "config/parameter_group.h" +#include "config/parameter_group_ids.h" + +#include "common/string_light.h" +#include "common/maths.h" + +#include "programming/logic_condition.h" +#include "programming/global_variables.h" + +#include "io/osd.h" +#include "io/osd/custom_elements.h" + +#include "drivers/osd_symbols.h" + +PG_REGISTER_ARRAY_WITH_RESET_FN(osdCustomElement_t, MAX_CUSTOM_ELEMENTS, osdCustomElements, PG_OSD_CUSTOM_ELEMENTS_CONFIG, 1); + +void pgResetFn_osdCustomElements(osdCustomElement_t *instance) +{ + for (int i = 0; i < MAX_CUSTOM_ELEMENTS; i++) { + RESET_CONFIG(osdCustomElement_t, &instance[i], + .part[0] = {.type = CUSTOM_ELEMENT_TYPE_NONE, .value = 0}, + .part[1] = {.type = CUSTOM_ELEMENT_TYPE_NONE, .value = 0}, + .part[2] = {.type = CUSTOM_ELEMENT_TYPE_NONE, .value = 0}, + .visibility = {.type = CUSTOM_ELEMENT_VISIBILITY_ALWAYS, .value = 0}, + .osdCustomElementText = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + ); + } +} + +bool isCustomelementVisible(const osdCustomElement_t* customElement){ + if(customElement->visibility.type == CUSTOM_ELEMENT_VISIBILITY_ALWAYS){ + return true; + } + + if(customElement->visibility.type == CUSTOM_ELEMENT_VISIBILITY_GV && gvGet(customElement->visibility.value)){ + return true; + } + + if(customElement->visibility.type == CUSTOM_ELEMENT_VISIBILITY_LOGIC_CON && logicConditionGetValue(customElement->visibility.value)){ + return true; + } + + return false; +} + +uint8_t customElementDrawPart(char *buff, uint8_t customElementIndex, uint8_t customElementItemIndex){ + const osdCustomElement_t* customElement = osdCustomElements(customElementIndex); + const int customPartType = osdCustomElements(customElementIndex)->part[customElementItemIndex].type; + const int customPartValue = osdCustomElements(customElementIndex)->part[customElementItemIndex].value; + + switch (customPartType) { + case CUSTOM_ELEMENT_TYPE_GV: + { + osdFormatCentiNumber(buff, (int32_t) gvGet(customPartValue) * (int32_t) 100, 1, 0, 0, 6, false); + return 6; + } + case CUSTOM_ELEMENT_TYPE_GV_FLOAT: + { + osdFormatCentiNumber(buff, (int32_t) gvGet(customPartValue), 1, 2, 0, 6, false); + return 6; + } + case CUSTOM_ELEMENT_TYPE_GV_SMALL: + { + osdFormatCentiNumber(buff, (int32_t) ((gvGet(customPartValue) % 1000 ) * (int32_t) 100), 1, 0, 0, 3, false); + return 3; + } + case CUSTOM_ELEMENT_TYPE_GV_SMALL_FLOAT: + { + osdFormatCentiNumber(buff, (int32_t) ((gvGet(customPartValue) % 100) * (int32_t) 10), 1, 1, 0, 2, false); + return 2; + } + case CUSTOM_ELEMENT_TYPE_ICON_GV: + { + *buff = (uint8_t)gvGet(customPartValue); + return 1; + } + case CUSTOM_ELEMENT_TYPE_ICON_STATIC: + { + *buff = (uint8_t)customPartValue; + return 1; + } + case CUSTOM_ELEMENT_TYPE_TEXT: + { + for (int i = 0; i < OSD_CUSTOM_ELEMENT_TEXT_SIZE; i++) { + if (customElement->osdCustomElementText[i] == 0){ + return i; + } + *buff = sl_toupper((unsigned char)customElement->osdCustomElementText[i]); + buff++; + } + return OSD_CUSTOM_ELEMENT_TEXT_SIZE; + } + } + + return 0; +} + +void customElementDrawElement(char *buff, uint8_t customElementIndex){ + + if(customElementIndex >= MAX_CUSTOM_ELEMENTS){ + return; + } + + static uint8_t prevLength[MAX_CUSTOM_ELEMENTS]; + + uint8_t buffSeek = 0; + const osdCustomElement_t* customElement = osdCustomElements(customElementIndex); + if(isCustomelementVisible(customElement)) + { + for (uint8_t i = 0; i < CUSTOM_ELEMENTS_PARTS; ++i) { + uint8_t currentSeek = customElementDrawPart(buff, customElementIndex, i); + buff += currentSeek; + buffSeek += currentSeek; + } + } + + for (uint8_t i = buffSeek; i < prevLength[customElementIndex]; i++) { + *buff++ = SYM_BLANK; + } + prevLength[customElementIndex] = buffSeek; +} + diff --git a/src/main/io/osd/custom_elements.h b/src/main/io/osd/custom_elements.h new file mode 100644 index 00000000000..a55b010f01a --- /dev/null +++ b/src/main/io/osd/custom_elements.h @@ -0,0 +1,61 @@ +/* + * 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 + +#include "config/parameter_group.h" + +#define OSD_CUSTOM_ELEMENT_TEXT_SIZE 16 +#define CUSTOM_ELEMENTS_PARTS 3 +#define MAX_CUSTOM_ELEMENTS 3 + +typedef enum { + CUSTOM_ELEMENT_TYPE_NONE = 0, + CUSTOM_ELEMENT_TYPE_TEXT = 1, + CUSTOM_ELEMENT_TYPE_ICON_STATIC = 2, + CUSTOM_ELEMENT_TYPE_ICON_GV = 3, + CUSTOM_ELEMENT_TYPE_GV = 4, + CUSTOM_ELEMENT_TYPE_GV_FLOAT = 5, + CUSTOM_ELEMENT_TYPE_GV_SMALL = 6, + CUSTOM_ELEMENT_TYPE_GV_SMALL_FLOAT = 7, +} osdCustomElementType_e; + +typedef enum { + CUSTOM_ELEMENT_VISIBILITY_ALWAYS = 0, + CUSTOM_ELEMENT_VISIBILITY_GV = 1, + CUSTOM_ELEMENT_VISIBILITY_LOGIC_CON = 2, +} osdCustomElementTypeVisibility_e; + +typedef struct { + osdCustomElementType_e type; + uint16_t value; +} osdCustomElementItem_t; + +typedef struct { + osdCustomElementTypeVisibility_e type; + uint16_t value; +} osdCustomElementVisibility_t; + +typedef struct { + osdCustomElementItem_t part[CUSTOM_ELEMENTS_PARTS]; + osdCustomElementVisibility_t visibility; + char osdCustomElementText[OSD_CUSTOM_ELEMENT_TEXT_SIZE]; +} osdCustomElement_t; + +PG_DECLARE_ARRAY(osdCustomElement_t, MAX_CUSTOM_ELEMENTS, osdCustomElements); + +void customElementDrawElement(char *buff, uint8_t customElementIndex); \ No newline at end of file diff --git a/src/main/io/osd_canvas.c b/src/main/io/osd_canvas.c index d5c84aa88ca..47dd4ee47bc 100644 --- a/src/main/io/osd_canvas.c +++ b/src/main/io/osd_canvas.c @@ -345,7 +345,9 @@ static bool osdCanvasDrawArtificialHorizonWidget(displayPort_t *display, display int ahiWidth = osdConfig()->ahi_width; int ahiX = (canvas->width - ahiWidth) / 2; int ahiHeight = osdConfig()->ahi_height; - int ahiY = ((canvas->height - ahiHeight) / 2) + osdConfig()->ahi_vertical_offset; + int ahiY = ((canvas->height - ahiHeight) / 2); + ahiY += osdConfig()->ahi_vertical_offset; + if (ahiY < 0) { ahiY = 0; } diff --git a/src/main/io/osd_common.c b/src/main/io/osd_common.c index a6a772ac61b..6969e181a5d 100644 --- a/src/main/io/osd_common.c +++ b/src/main/io/osd_common.c @@ -44,7 +44,6 @@ #include "navigation/navigation.h" #include "sensors/pitotmeter.h" - #if defined(USE_OSD) || defined(USE_DJI_HD_OSD) PG_REGISTER_WITH_RESET_TEMPLATE(osdCommonConfig_t, osdCommonConfig, PG_OSD_COMMON_CONFIG, 0); @@ -148,11 +147,17 @@ void osdDrawArtificialHorizon(displayPort_t *display, displayCanvas_t *canvas, c { uint8_t gx; uint8_t gy; + #if defined(USE_CANVAS) if (canvas) { osdCanvasDrawArtificialHorizon(display, canvas, p, pitchAngle, rollAngle); } else { #endif + // Correct pitch when inverted + if (rollAngle < -1.570796f || rollAngle > 1.570796f) { + pitchAngle = -pitchAngle; + } + osdDrawPointGetGrid(&gx, &gy, display, canvas, p); osdGridDrawArtificialHorizon(display, gx, gy, pitchAngle, rollAngle); #if defined(USE_CANVAS) diff --git a/src/main/io/osd_dji_hd.c b/src/main/io/osd_dji_hd.c index e79ddc0dfd3..8edf8288d03 100644 --- a/src/main/io/osd_dji_hd.c +++ b/src/main/io/osd_dji_hd.c @@ -300,6 +300,7 @@ static void djiPackBoxModeBitmask(boxBitmask_t * flightModeBitmask) case FLM_ALTITUDE_HOLD: case FLM_POSITION_HOLD: case FLM_MISSION: + case FLM_ANGLEHOLD: default: // Unsupported ATM, keep at ANGLE bitArraySet(flightModeBitmask->bits, 1); // DJI: 1 << 1 : ANGLE @@ -1058,6 +1059,10 @@ static bool djiFormatMessages(char *buff) if (FLIGHT_MODE(MANUAL_MODE)) { messages[messageCount++] = "(MANUAL)"; } + + if (FLIGHT_MODE(NAV_FW_AUTOLAND)) { + messages[messageCount++] = "(LAND)"; + } } } // Pick one of the available messages. Each message lasts diff --git a/src/main/io/osd_hud.c b/src/main/io/osd_hud.c index 2e209fd2826..47cc96f834b 100644 --- a/src/main/io/osd_hud.c +++ b/src/main/io/osd_hud.c @@ -256,18 +256,18 @@ void osdHudDrawPoi(uint32_t poiDistance, int16_t poiDirection, int32_t poiAltitu case OSD_UNIT_IMPERIAL: { if (poiType == 1) { - osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 4, 4); + osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 4, 4, false); } else { - osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 3, 3); + osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 3, 3, false); } } break; case OSD_UNIT_GA: { if (poiType == 1) { - osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 4, 4); + osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 4, 4, false); } else { - osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 3, 3); + osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 3, 3, false); } } break; @@ -278,9 +278,9 @@ void osdHudDrawPoi(uint32_t poiDistance, int16_t poiDirection, int32_t poiAltitu case OSD_UNIT_METRIC: { if (poiType == 1) { - osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 4, 4); + osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 4, 4, false); } else { - osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 3, 3); + osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 3, 3, false); } } break; diff --git a/src/main/io/osd_joystick.c b/src/main/io/osd_joystick.c new file mode 100644 index 00000000000..c1d9dee5a5a --- /dev/null +++ b/src/main/io/osd_joystick.c @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "platform.h" + +#include "common/crc.h" +#include "common/maths.h" +#include "common/streambuf.h" +#include "common/utils.h" + +#include "build/build_config.h" + +#include "config/parameter_group.h" +#include "config/parameter_group_ids.h" +#include "fc/settings.h" +#include "fc/runtime_config.h" + +#include "drivers/time.h" +#include "drivers/light_ws2811strip.h" + +#include "io/serial.h" +#include "io/rcdevice.h" + +#include "osd_joystick.h" + +#ifdef USE_RCDEVICE +#ifdef USE_LED_STRIP + + +PG_REGISTER_WITH_RESET_TEMPLATE(osdJoystickConfig_t, osdJoystickConfig, PG_OSD_JOYSTICK_CONFIG, 0); + +PG_RESET_TEMPLATE(osdJoystickConfig_t, osdJoystickConfig, + .osd_joystick_enabled = SETTING_OSD_JOYSTICK_ENABLED_DEFAULT, + .osd_joystick_down = SETTING_OSD_JOYSTICK_DOWN_DEFAULT, + .osd_joystick_up = SETTING_OSD_JOYSTICK_UP_DEFAULT, + .osd_joystick_left = SETTING_OSD_JOYSTICK_LEFT_DEFAULT, + .osd_joystick_right = SETTING_OSD_JOYSTICK_RIGHT_DEFAULT, + .osd_joystick_enter = SETTING_OSD_JOYSTICK_ENTER_DEFAULT +); + +bool osdJoystickEnabled(void) { + return osdJoystickConfig()->osd_joystick_enabled; +} + + +void osdJoystickSimulate5KeyButtonPress(uint8_t operation) { + switch (operation) { + case RCDEVICE_CAM_KEY_ENTER: + ledPinStartPWM( osdJoystickConfig()->osd_joystick_enter ); + break; + case RCDEVICE_CAM_KEY_LEFT: + ledPinStartPWM( osdJoystickConfig()->osd_joystick_left ); + break; + case RCDEVICE_CAM_KEY_UP: + ledPinStartPWM( osdJoystickConfig()->osd_joystick_up ); + break; + case RCDEVICE_CAM_KEY_RIGHT: + ledPinStartPWM( osdJoystickConfig()->osd_joystick_right ); + break; + case RCDEVICE_CAM_KEY_DOWN: + ledPinStartPWM( osdJoystickConfig()->osd_joystick_down ); + break; + } +} + + +void osdJoystickSimulate5KeyButtonRelease(void) { + ledPinStopPWM(); +} + + +#endif +#endif diff --git a/src/main/io/osd_joystick.h b/src/main/io/osd_joystick.h new file mode 100644 index 00000000000..574b8e3b776 --- /dev/null +++ b/src/main/io/osd_joystick.h @@ -0,0 +1,26 @@ +#pragma once + +#include "config/parameter_group.h" + +#ifdef USE_RCDEVICE +#ifdef USE_LED_STRIP + +typedef struct osdJoystickConfig_s { + bool osd_joystick_enabled; + uint8_t osd_joystick_down; + uint8_t osd_joystick_up; + uint8_t osd_joystick_left; + uint8_t osd_joystick_right; + uint8_t osd_joystick_enter; +} osdJoystickConfig_t; + +PG_DECLARE(osdJoystickConfig_t, osdJoystickConfig); + +bool osdJoystickEnabled(void); + +// 5 key osd cable simulation +void osdJoystickSimulate5KeyButtonPress(uint8_t operation); +void osdJoystickSimulate5KeyButtonRelease(void); + +#endif +#endif \ No newline at end of file diff --git a/src/main/io/osd_utils.c b/src/main/io/osd_utils.c index 194be36f952..6675be8783b 100644 --- a/src/main/io/osd_utils.c +++ b/src/main/io/osd_utils.c @@ -38,7 +38,7 @@ int digitCount(int32_t value) } -bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length) +bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros) { char *ptr = buff; char *dec; @@ -86,7 +86,11 @@ bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int ma // Done counting. Time to write the characters. // Write spaces at the start while (remaining > 0) { - *ptr = SYM_BLANK; + if (leadingZeros) + *ptr = '0'; + else + *ptr = SYM_BLANK; + ptr++; remaining--; } @@ -98,7 +102,11 @@ bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int ma // Add any needed remaining leading spaces while(rem_spaces > 0) { - *ptr = SYM_BLANK; + if (leadingZeros) + *ptr = '0'; + else + *ptr = SYM_BLANK; + ptr++; remaining--; rem_spaces--; diff --git a/src/main/io/osd_utils.h b/src/main/io/osd_utils.h index 2f9c61a3202..7f10f2bf8f9 100644 --- a/src/main/io/osd_utils.h +++ b/src/main/io/osd_utils.h @@ -33,6 +33,6 @@ int digitCount(int32_t value); * of the same length. If the value doesn't fit into the provided length * it will be divided by scale and true will be returned. */ -bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length); +bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros); #endif diff --git a/src/main/io/rcdevice_cam.c b/src/main/io/rcdevice_cam.c index 36a0f998690..0edbc8bf979 100644 --- a/src/main/io/rcdevice_cam.c +++ b/src/main/io/rcdevice_cam.c @@ -29,6 +29,7 @@ #include "io/beeper.h" #include "io/rcdevice_cam.h" +#include "io/osd_joystick.h" #include "rx/rx.h" @@ -47,6 +48,14 @@ bool waitingDeviceResponse = false; static bool isFeatureSupported(uint8_t feature) { +#ifndef UNIT_TEST +#ifdef USE_LED_STRIP + if (!rcdeviceIsEnabled() && osdJoystickEnabled() ) { + return true; + } +#endif +#endif + if (camDevice->info.features & feature) { return true; } @@ -72,6 +81,7 @@ static void rcdeviceCameraControlProcess(void) } uint8_t behavior = RCDEVICE_PROTOCOL_CAM_CTRL_UNKNOWN_CAMERA_OPERATION; + uint8_t behavior1 = RCDEVICE_PROTOCOL_CAM_CTRL_UNKNOWN_CAMERA_OPERATION; switch (i) { case BOXCAMERA1: if (isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_SIMULATE_WIFI_BUTTON)) { @@ -81,11 +91,13 @@ static void rcdeviceCameraControlProcess(void) if (!ARMING_FLAG(ARMED)) { behavior = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_WIFI_BTN; } + behavior1 = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_WIFI_BTN; } break; case BOXCAMERA2: if (isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_SIMULATE_POWER_BUTTON)) { behavior = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_POWER_BTN; + behavior1 = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_POWER_BTN; } break; case BOXCAMERA3: @@ -94,16 +106,43 @@ static void rcdeviceCameraControlProcess(void) if (!ARMING_FLAG(ARMED)) { behavior = RCDEVICE_PROTOCOL_CAM_CTRL_CHANGE_MODE; } + behavior1 = RCDEVICE_PROTOCOL_CAM_CTRL_CHANGE_MODE; } break; default: break; } - if (behavior != RCDEVICE_PROTOCOL_CAM_CTRL_UNKNOWN_CAMERA_OPERATION) { + if ((behavior != RCDEVICE_PROTOCOL_CAM_CTRL_UNKNOWN_CAMERA_OPERATION) && rcdeviceIsEnabled()) { runcamDeviceSimulateCameraButton(camDevice, behavior); switchStates[switchIndex].isActivated = true; } +#ifndef UNIT_TEST +#ifdef USE_LED_STRIP + else if ((behavior1 != RCDEVICE_PROTOCOL_CAM_CTRL_UNKNOWN_CAMERA_OPERATION) && osdJoystickEnabled()) { + switch (behavior1) { + case RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_WIFI_BTN: + osdJoystickSimulate5KeyButtonPress(RCDEVICE_CAM_KEY_ENTER); + break; + case RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_POWER_BTN: + osdJoystickSimulate5KeyButtonPress(RCDEVICE_CAM_KEY_UP); + break; + case RCDEVICE_PROTOCOL_CAM_CTRL_CHANGE_MODE: + osdJoystickSimulate5KeyButtonPress(RCDEVICE_CAM_KEY_DOWN); + break; + } + switchStates[switchIndex].isActivated = true; + } +#endif +#endif + UNUSED(behavior1); } else { +#ifndef UNIT_TEST +#ifdef USE_LED_STRIP + if (osdJoystickEnabled() && switchStates[switchIndex].isActivated) { + osdJoystickSimulate5KeyButtonRelease(); + } +#endif +#endif switchStates[switchIndex].isActivated = false; } } @@ -225,14 +264,24 @@ static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs) } #endif - if (camDevice->serialPort == 0 || ARMING_FLAG(ARMED)) { + if (ARMING_FLAG(ARMED)) { return; } if (isButtonPressed) { if (IS_MID(YAW) && IS_MID(PITCH) && IS_MID(ROLL)) { - rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE); - waitingDeviceResponse = true; + if ( rcdeviceIsEnabled() ) { + rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE); + waitingDeviceResponse = true; + } +#ifndef UNIT_TEST +#ifdef USE_LED_STRIP + else if (osdJoystickEnabled()) { + osdJoystickSimulate5KeyButtonRelease(); + isButtonPressed = false; + } +#endif +#endif } } else { if (waitingDeviceResponse) { @@ -266,16 +315,33 @@ static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs) } if (key != RCDEVICE_CAM_KEY_NONE) { - rcdeviceSend5KeyOSDCableSimualtionEvent(key); + if ( rcdeviceIsEnabled() ) { + rcdeviceSend5KeyOSDCableSimualtionEvent(key); + waitingDeviceResponse = true; + } +#ifndef UNIT_TEST +#ifdef USE_LED_STRIP + else if (osdJoystickEnabled()) { + if ( key == RCDEVICE_CAM_KEY_CONNECTION_OPEN ) { + rcdeviceInMenu = true; + } else if ( key == RCDEVICE_CAM_KEY_CONNECTION_CLOSE ) { + rcdeviceInMenu = false; + } else { + osdJoystickSimulate5KeyButtonPress(key); + } + } +#endif +#endif isButtonPressed = true; - waitingDeviceResponse = true; } } } void rcdeviceUpdate(timeUs_t currentTimeUs) { - rcdeviceReceive(currentTimeUs); + if ( rcdeviceIsEnabled() ) { + rcdeviceReceive(currentTimeUs); + } rcdeviceCameraControlProcess(); diff --git a/src/main/io/vtx_tramp.c b/src/main/io/vtx_tramp.c index 2791ada2944..540c9c9f222 100644 --- a/src/main/io/vtx_tramp.c +++ b/src/main/io/vtx_tramp.c @@ -575,16 +575,27 @@ const char * const trampPowerNames_5G8_800[VTX_TRAMP_5G8_MAX_POWER_COUNT + 1] = const uint16_t trampPowerTable_1G3_800[VTX_TRAMP_1G3_MAX_POWER_COUNT] = { 25, 200, 800 }; const char * const trampPowerNames_1G3_800[VTX_TRAMP_1G3_MAX_POWER_COUNT + 1] = { "---", "25 ", "200", "800" }; +const uint16_t trampPowerTable_1G3_2000[VTX_TRAMP_1G3_MAX_POWER_COUNT] = { 25, 200, 2000 }; +const char * const trampPowerNames_1G3_2000[VTX_TRAMP_1G3_MAX_POWER_COUNT + 1] = { "---", "25 ", "200", "2000" }; + static void vtxProtoUpdatePowerMetadata(uint16_t maxPower) { switch (vtxSettingsConfig()->frequencyGroup) { case FREQUENCYGROUP_1G3: - vtxState.metadata.powerTablePtr = trampPowerTable_1G3_800; - vtxState.metadata.powerTableCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; + if (maxPower >= 2000) { + vtxState.metadata.powerTablePtr = trampPowerTable_1G3_2000; + vtxState.metadata.powerTableCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; - impl_vtxDevice.capability.powerNames = (char **)trampPowerNames_1G3_800; - impl_vtxDevice.capability.powerCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; + impl_vtxDevice.capability.powerNames = (char **)trampPowerNames_1G3_2000; + impl_vtxDevice.capability.powerCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; + } + else { + vtxState.metadata.powerTablePtr = trampPowerTable_1G3_800; + vtxState.metadata.powerTableCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; + impl_vtxDevice.capability.powerNames = (char **)trampPowerNames_1G3_800; + impl_vtxDevice.capability.powerCount = VTX_TRAMP_1G3_MAX_POWER_COUNT; + } impl_vtxDevice.capability.bandCount = VTX_TRAMP_1G3_BAND_COUNT; impl_vtxDevice.capability.channelCount = VTX_TRAMP_1G3_CHANNEL_COUNT; impl_vtxDevice.capability.bandNames = (char **)vtx1G3BandNames; diff --git a/src/main/msp/msp_protocol_v2_inav.h b/src/main/msp/msp_protocol_v2_inav.h index 9cf1881c732..356cd54ca5a 100755 --- a/src/main/msp/msp_protocol_v2_inav.h +++ b/src/main/msp/msp_protocol_v2_inav.h @@ -92,5 +92,17 @@ #define MSP2_INAV_LED_STRIP_CONFIG_EX 0x2048 #define MSP2_INAV_SET_LED_STRIP_CONFIG_EX 0x2049 +#define MSP2_INAV_FW_APPROACH 0x204A +#define MSP2_INAV_SET_FW_APPROACH 0x204B + #define MSP2_INAV_RATE_DYNAMICS 0x2060 #define MSP2_INAV_SET_RATE_DYNAMICS 0x2061 + +#define MSP2_INAV_EZ_TUNE 0x2070 +#define MSP2_INAV_EZ_TUNE_SET 0x2071 + +#define MSP2_INAV_SELECT_MIXER_PROFILE 0x2080 + +#define MSP2_INAV_CUSTOM_OSD_ELEMENTS 0x2100 +#define MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS 0x2101 + diff --git a/src/main/navigation/navigation.c b/src/main/navigation/navigation.c index 51105f24ff3..9e81024c3af 100644 --- a/src/main/navigation/navigation.c +++ b/src/main/navigation/navigation.c @@ -49,6 +49,7 @@ #include "flight/imu.h" #include "flight/mixer_profile.h" #include "flight/pid.h" +#include "flight/wind_estimator.h" #include "io/beeper.h" #include "io/gps.h" @@ -62,8 +63,11 @@ #include "sensors/acceleration.h" #include "sensors/boardalignment.h" #include "sensors/battery.h" +#include "sensors/gyro.h" +#include "sensors/diagnostics.h" #include "programming/global_variables.h" +#include "sensors/rangefinder.h" // Multirotors: #define MR_RTH_CLIMB_OVERSHOOT_CM 100 // target this amount of cm *above* the target altitude to ensure it is actually reached (Vz > 0 at target alt) @@ -75,6 +79,8 @@ #define FW_RTH_CLIMB_OVERSHOOT_CM 100 #define FW_RTH_CLIMB_MARGIN_MIN_CM 100 #define FW_RTH_CLIMB_MARGIN_PERCENT 15 +#define FW_LAND_LOITER_MIN_TIME 30000000 // usec (30 sec) +#define FW_LAND_LOITER_ALT_TOLERANCE 150 /*----------------------------------------------------------- * Compatibility for home position @@ -85,6 +91,22 @@ int16_t GPS_directionToHome; // direction to home point in degrees radar_pois_t radar_pois[RADAR_MAX_POIS]; +#ifdef USE_FW_AUTOLAND +PG_REGISTER_WITH_RESET_TEMPLATE(navFwAutolandConfig_t, navFwAutolandConfig, PG_FW_AUTOLAND_CONFIG, 0); + +PG_REGISTER_ARRAY(navFwAutolandApproach_t, MAX_FW_LAND_APPOACH_SETTINGS, fwAutolandApproachConfig, PG_FW_AUTOLAND_APPROACH_CONFIG, 0); + +PG_RESET_TEMPLATE(navFwAutolandConfig_t, navFwAutolandConfig, + .approachLength = SETTING_NAV_FW_LAND_APPROACH_LENGTH_DEFAULT, + .finalApproachPitchToThrottleMod = SETTING_NAV_FW_LAND_FINAL_APPROACH_PITCH2THROTTLE_MOD_DEFAULT, + .flareAltitude = SETTING_NAV_FW_LAND_FLARE_ALT_DEFAULT, + .glideAltitude = SETTING_NAV_FW_LAND_GLIDE_ALT_DEFAULT, + .flarePitch = SETTING_NAV_FW_LAND_FLARE_PITCH_DEFAULT, + .maxTailwind = SETTING_NAV_FW_LAND_MAX_TAILWIND_DEFAULT, + .glidePitch = SETTING_NAV_FW_LAND_GLIDE_PITCH_DEFAULT, +); +#endif + #if defined(USE_SAFE_HOME) PG_REGISTER_ARRAY(navSafeHome_t, MAX_SAFE_HOMES, safeHomeConfig, PG_SAFE_HOME_CONFIG , 0); #endif @@ -96,7 +118,7 @@ STATIC_ASSERT(NAV_MAX_WAYPOINTS < 254, NAV_MAX_WAYPOINTS_exceeded_allowable_rang PG_REGISTER_ARRAY(navWaypoint_t, NAV_MAX_WAYPOINTS, nonVolatileWaypointList, PG_WAYPOINT_MISSION_STORAGE, 2); #endif -PG_REGISTER_WITH_RESET_TEMPLATE(navConfig_t, navConfig, PG_NAV_CONFIG, 5); +PG_REGISTER_WITH_RESET_TEMPLATE(navConfig_t, navConfig, PG_NAV_CONFIG, 6); PG_RESET_TEMPLATE(navConfig_t, navConfig, .general = { @@ -131,6 +153,7 @@ PG_RESET_TEMPLATE(navConfig_t, navConfig, #endif .waypoint_load_on_boot = SETTING_NAV_WP_LOAD_ON_BOOT_DEFAULT, // load waypoints automatically during boot .auto_speed = SETTING_NAV_AUTO_SPEED_DEFAULT, // speed in autonomous modes (3 m/s = 10.8 km/h) + .min_ground_speed = SETTING_NAV_MIN_GROUND_SPEED_DEFAULT, // Minimum ground speed (m/s) .max_auto_speed = SETTING_NAV_MAX_AUTO_SPEED_DEFAULT, // max allowed speed autonomous modes .max_auto_climb_rate = SETTING_NAV_AUTO_CLIMB_RATE_DEFAULT, // 5 m/s .max_manual_speed = SETTING_NAV_MANUAL_SPEED_DEFAULT, @@ -154,6 +177,7 @@ PG_RESET_TEMPLATE(navConfig_t, navConfig, .auto_disarm_delay = SETTING_NAV_AUTO_DISARM_DELAY_DEFAULT, // 2000 ms - time delay to disarm when auto disarm after landing enabled .rth_linear_descent_start_distance = SETTING_NAV_RTH_LINEAR_DESCENT_START_DISTANCE_DEFAULT, .cruise_yaw_rate = SETTING_NAV_CRUISE_YAW_RATE_DEFAULT, // 20dps + .rth_fs_landing_delay = SETTING_NAV_RTH_FS_LANDING_DELAY_DEFAULT, // Delay before landing in FS. 0 = immedate landing }, // MC-specific @@ -207,7 +231,7 @@ PG_RESET_TEMPLATE(navConfig_t, navConfig, .launch_climb_angle = SETTING_NAV_FW_LAUNCH_CLIMB_ANGLE_DEFAULT, // 18 degrees .launch_max_angle = SETTING_NAV_FW_LAUNCH_MAX_ANGLE_DEFAULT, // 45 deg .launch_manual_throttle = SETTING_NAV_FW_LAUNCH_MANUAL_THROTTLE_DEFAULT,// OFF - .launch_abort_deadband = SETTING_NAV_FW_LAUNCH_ABORT_DEADBAND_DEFAULT, // 100 us + .launch_land_abort_deadband = SETTING_NAV_FW_LAUNCH_LAND_ABORT_DEADBAND_DEFAULT, // 100 us .allow_manual_thr_increase = SETTING_NAV_FW_ALLOW_MANUAL_THR_INCREASE_DEFAULT, .useFwNavYawControl = SETTING_NAV_USE_FW_YAW_CONTROL_DEFAULT, @@ -223,6 +247,7 @@ PG_RESET_TEMPLATE(navConfig_t, navConfig, static navWapointHeading_t wpHeadingControl; navigationPosControl_t posControl; navSystemStatus_t NAV_Status; +static bool landingDetectorIsActive; EXTENDED_FASTRAM multicopterPosXyCoefficients_t multicopterPosXyCoefficients; @@ -247,6 +272,11 @@ static void resetAltitudeController(bool useTerrainFollowing); static void resetPositionController(void); static void setupAltitudeController(void); static void resetHeadingController(void); + +#ifdef USE_FW_AUTOLAND +static void resetFwAutoland(void); +#endif + void resetGCSFlags(void); static void setupJumpCounters(void); @@ -256,6 +286,7 @@ static void clearJumpCounters(void); static void calculateAndSetActiveWaypoint(const navWaypoint_t * waypoint); static void calculateAndSetActiveWaypointToLocalPosition(const fpVector3_t * pos); void calculateInitialHoldPosition(fpVector3_t * pos); +void calculateFarAwayPos(fpVector3_t * farAwayPos, const fpVector3_t *start, int32_t bearing, int32_t distance); void calculateFarAwayTarget(fpVector3_t * farAwayPos, int32_t bearing, int32_t distance); static bool isWaypointReached(const fpVector3_t * waypointPos, const int32_t * waypointBearing); bool isWaypointAltitudeReached(void); @@ -274,6 +305,13 @@ static bool rthAltControlStickOverrideCheck(unsigned axis); static void updateRthTrackback(bool forceSaveTrackPoint); static fpVector3_t * rthGetTrackbackPos(void); +#ifdef USE_FW_AUTOLAND +static float getLandAltitude(void); +static int32_t calcWindDiff(int32_t heading, int32_t windHeading); +static int32_t calcFinalApproachHeading(int32_t approachHeading, int32_t windAngle); +static void setLandWaypoint(const fpVector3_t *pos, const fpVector3_t *nextWpPos); +#endif + /*************************************************************************************************/ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_IDLE(navigationFSMState_t previousState); static navigationFSMEvent_t navOnEnteringState_NAV_STATE_ALTHOLD_INITIALIZE(navigationFSMState_t previousState); @@ -312,6 +350,14 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_LAUNCH_IN_PROGRESS(navi static navigationFSMEvent_t navOnEnteringState_NAV_STATE_MIXERAT_INITIALIZE(navigationFSMState_t previousState); static navigationFSMEvent_t navOnEnteringState_NAV_STATE_MIXERAT_IN_PROGRESS(navigationFSMState_t previousState); static navigationFSMEvent_t navOnEnteringState_NAV_STATE_MIXERAT_ABORT(navigationFSMState_t previousState); +#ifdef USE_FW_AUTOLAND +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_CLIMB_TO_LOITER(navigationFSMState_t previousState); +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_LOITER(navigationFSMState_t previousState); +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH(navigationFSMState_t previousState); +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE(navigationFSMState_t previousState); +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_FLARE(navigationFSMState_t previousState); +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_ABORT(navigationFSMState_t previousState); +#endif static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = { /** Idle state ******************************************************/ @@ -661,6 +707,8 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = { [NAV_FSM_EVENT_SWITCH_TO_POSHOLD_3D] = NAV_STATE_POSHOLD_3D_INITIALIZE, [NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING] = NAV_STATE_EMERGENCY_LANDING_INITIALIZE, [NAV_FSM_EVENT_SWITCH_TO_MIXERAT] = NAV_STATE_MIXERAT_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING] = NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, + [NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME] = NAV_STATE_RTH_HOVER_ABOVE_HOME, } }, @@ -815,6 +863,8 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = { [NAV_FSM_EVENT_SWITCH_TO_COURSE_HOLD] = NAV_STATE_COURSE_HOLD_INITIALIZE, [NAV_FSM_EVENT_SWITCH_TO_CRUISE] = NAV_STATE_CRUISE_INITIALIZE, [NAV_FSM_EVENT_SWITCH_TO_MIXERAT] = NAV_STATE_MIXERAT_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING] = NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, + [NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED] = NAV_STATE_WAYPOINT_FINISHED, } }, @@ -949,7 +999,7 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = { [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, } }, - + /** MIXER AUTOMATED TRANSITION mode, alternated althod ***************************************************/ [NAV_STATE_MIXERAT_INITIALIZE] = { .persistentId = NAV_PERSISTENT_ID_MIXERAT_INITIALIZE, @@ -992,9 +1042,127 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = { .onEvent = { [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_IDLE, [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, - + + } + }, + +/** Advanced Fixed Wing Autoland **/ +#ifdef USE_FW_AUTOLAND + [NAV_STATE_FW_LANDING_CLIMB_TO_LOITER] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_CLIMB_TO_LOITER, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, + .timeoutMs = 10, + .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_FW_LANDING_LOITER, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_ALTHOLD] = NAV_STATE_ALTHOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_POSHOLD_3D] = NAV_STATE_POSHOLD_3D_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING] = NAV_STATE_EMERGENCY_LANDING_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_COURSE_HOLD] = NAV_STATE_COURSE_HOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_CRUISE] = NAV_STATE_CRUISE_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT] = NAV_STATE_FW_LANDING_ABORT, } }, + + [NAV_STATE_FW_LANDING_LOITER] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_LOITER, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_LOITER, + .timeoutMs = 10, + .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_LOITER, + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_FW_LANDING_APPROACH, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_ALTHOLD] = NAV_STATE_ALTHOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_POSHOLD_3D] = NAV_STATE_POSHOLD_3D_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING] = NAV_STATE_EMERGENCY_LANDING_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_COURSE_HOLD] = NAV_STATE_COURSE_HOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_CRUISE] = NAV_STATE_CRUISE_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT] = NAV_STATE_FW_LANDING_ABORT, + } + }, + + [NAV_STATE_FW_LANDING_APPROACH] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_APPROACH, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH, + .timeoutMs = 10, + .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_WP, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_APPROACH, + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_FW_LANDING_GLIDE, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_ALTHOLD] = NAV_STATE_ALTHOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_POSHOLD_3D] = NAV_STATE_POSHOLD_3D_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING] = NAV_STATE_EMERGENCY_LANDING_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_COURSE_HOLD] = NAV_STATE_COURSE_HOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_CRUISE] = NAV_STATE_CRUISE_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT] = NAV_STATE_FW_LANDING_ABORT, + } + }, + + [NAV_STATE_FW_LANDING_GLIDE] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_GLIDE, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE, + .timeoutMs = 10, + .stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_GLIDE, + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_FW_LANDING_FLARE, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_ALTHOLD] = NAV_STATE_ALTHOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_POSHOLD_3D] = NAV_STATE_POSHOLD_3D_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING] = NAV_STATE_EMERGENCY_LANDING_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_COURSE_HOLD] = NAV_STATE_COURSE_HOLD_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_CRUISE] = NAV_STATE_CRUISE_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT] = NAV_STATE_FW_LANDING_ABORT, + } + }, + + [NAV_STATE_FW_LANDING_FLARE] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_FLARE, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_FLARE, + .timeoutMs = 10, + .stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_FLARE, // re-process the state + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + } + }, + [NAV_STATE_FW_LANDING_ABORT] = { + .persistentId = NAV_PERSISTENT_ID_FW_LANDING_ABORT, + .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_ABORT, + .timeoutMs = 10, + .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH | NAV_RC_POS | NAV_RC_YAW, + .mapToFlightModes = NAV_FW_AUTOLAND, + .mwState = MW_NAV_STATE_LAND_IN_PROGRESS, + .mwError = MW_NAV_ERROR_NONE, + .onEvent = { + [NAV_FSM_EVENT_TIMEOUT] = NAV_STATE_FW_LANDING_ABORT, + [NAV_FSM_EVENT_SUCCESS] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_RTH] = NAV_STATE_RTH_INITIALIZE, + [NAV_FSM_EVENT_SWITCH_TO_IDLE] = NAV_STATE_IDLE, + [NAV_FSM_EVENT_SWITCH_TO_WAYPOINT] = NAV_STATE_WAYPOINT_INITIALIZE, + } + }, +#endif }; static navigationFSMStateFlags_t navGetStateFlags(navigationFSMState_t state) @@ -1026,6 +1194,9 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_IDLE(navigationFSMState resetAltitudeController(false); resetHeadingController(); resetPositionController(); +#ifdef USE_FW_AUTOLAND + resetFwAutoland(); +#endif return NAV_FSM_EVENT_NONE; } @@ -1223,7 +1394,9 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_CRUISE_ADJUSTING(naviga static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_INITIALIZE(navigationFSMState_t previousState) { - UNUSED(previousState); + + if (navConfig()->general.flags.rth_use_linear_descent && posControl.rthState.rthLinearDescentActive) + posControl.rthState.rthLinearDescentActive = false; if ((posControl.flags.estHeadingStatus == EST_NONE) || (posControl.flags.estAltStatus == EST_NONE) || !STATE(GPS_FIX_HOME)) { // Heading sensor, altitude sensor and HOME fix are mandatory for RTH. If not satisfied - switch to emergency landing @@ -1232,9 +1405,14 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_INITIALIZE(navigati return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; } - if (STATE(FIXED_WING_LEGACY) && (posControl.homeDistance < navConfig()->general.min_rth_distance) && !posControl.flags.forcedRTHActivated) { - // Prevent RTH from activating on airplanes if too close to home unless it's a failsafe RTH - return NAV_FSM_EVENT_SWITCH_TO_IDLE; + if (previousState != NAV_STATE_FW_LANDING_ABORT) { +#ifdef USE_FW_AUTOLAND + posControl.fwLandState.landAborted = false; +#endif + if (STATE(FIXED_WING_LEGACY) && (posControl.homeDistance < navConfig()->general.min_rth_distance) && !posControl.flags.forcedRTHActivated) { + // Prevent RTH from activating on airplanes if too close to home unless it's a failsafe RTH + return NAV_FSM_EVENT_SWITCH_TO_IDLE; + } } // If we have valid position sensor or configured to ignore it's loss at initial stage - continue @@ -1430,6 +1608,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_HEAD_HOME(navigatio if (homeDistance <= METERS_TO_CENTIMETERS(navConfig()->general.rth_linear_descent_start_distance)) { posControl.rthState.rthFinalAltitude = posControl.rthState.homePosition.pos.z + navConfig()->general.rth_home_altitude; + posControl.rthState.rthLinearDescentActive = true; } } @@ -1440,6 +1619,12 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_HEAD_HOME(navigatio if (isWaypointReached(tmpHomePos, 0)) { // Successfully reached position target - update XYZ-position setDesiredPosition(tmpHomePos, posControl.rthState.homePosition.heading, NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING); + + posControl.landingDelay = 0; + + if (navConfig()->general.flags.rth_use_linear_descent && posControl.rthState.rthLinearDescentActive) + posControl.rthState.rthLinearDescentActive = false; + return NAV_FSM_EVENT_SUCCESS; // NAV_STATE_RTH_HOVER_PRIOR_TO_LANDING } else { setDesiredPosition(tmpHomePos, 0, NAV_POS_UPDATE_Z | NAV_POS_UPDATE_XY); @@ -1468,9 +1653,24 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_HOVER_PRIOR_TO_LAND return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; } - // If position ok OR within valid timeout - continue + // Action delay before landing if in FS and option enabled + bool pauseLanding = false; + navRTHAllowLanding_e allow = navConfig()->general.flags.rth_allow_landing; + if ((allow == NAV_RTH_ALLOW_LANDING_ALWAYS || allow == NAV_RTH_ALLOW_LANDING_FS_ONLY) && FLIGHT_MODE(FAILSAFE_MODE) && navConfig()->general.rth_fs_landing_delay > 0) { + if (posControl.landingDelay == 0) + posControl.landingDelay = millis() + S2MS(navConfig()->general.rth_fs_landing_delay); + + batteryState_e batteryState = getBatteryState(); + + if (millis() < posControl.landingDelay && batteryState != BATTERY_WARNING && batteryState != BATTERY_CRITICAL) + pauseLanding = true; + else + posControl.landingDelay = 0; + } + + // If landing is not temporarily paused (FS only), position ok, OR within valid timeout - continue // Wait until target heading is reached for MR (with 15 deg margin for error), or continue for Fixed Wing - if ((ABS(wrap_18000(posControl.rthState.homePosition.heading - posControl.actualState.yaw)) < DEGREES_TO_CENTIDEGREES(15)) || STATE(FIXED_WING_LEGACY)) { + if (!pauseLanding && ((ABS(wrap_18000(posControl.rthState.homePosition.heading - posControl.actualState.yaw)) < DEGREES_TO_CENTIDEGREES(15)) || STATE(FIXED_WING_LEGACY))) { resetLandingDetector(); // force reset landing detector just in case updateClimbRateToAltitudeController(0, 0, ROC_TO_ALT_RESET); return navigationRTHAllowsLanding() ? NAV_FSM_EVENT_SUCCESS : NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME; // success = land @@ -1498,7 +1698,9 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_HOVER_ABOVE_HOME(na static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_LANDING(navigationFSMState_t previousState) { +#ifndef USE_FW_AUTOLAND UNUSED(previousState); +#endif //On ROVER and BOAT we immediately switch to the next event if (!STATE(ALTITUDE_CONTROL)) { @@ -1511,34 +1713,66 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_LANDING(navigationF /* If position sensors unavailable - land immediately (wait for timeout on GPS) * Continue to check for RTH sanity during landing */ - if (posControl.flags.estHeadingStatus == EST_NONE || checkForPositionSensorTimeout() || !validateRTHSanityChecker()) { + if (posControl.flags.estHeadingStatus == EST_NONE || checkForPositionSensorTimeout() || (previousState != NAV_STATE_WAYPOINT_REACHED && !validateRTHSanityChecker())) { return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; } - + if (checkMixerATRequired(MIXERAT_REQUEST_LAND)){ return NAV_FSM_EVENT_SWITCH_TO_MIXERAT; } - float descentVelLimited = 0; +#ifdef USE_FW_AUTOLAND + if (STATE(AIRPLANE)) { + int8_t missionIdx = -1, shIdx = -1, missionFwLandConfigStartIdx = 8, approachSettingIdx = -1; +#ifdef USE_MULTI_MISSION + missionIdx = posControl.loadedMultiMissionIndex - 1; +#endif - fpVector3_t tmpHomePos = posControl.rthState.homeTmpWaypoint; - uint32_t remaning_distance = calculateDistanceToDestination(&tmpHomePos); +#ifdef USE_SAFE_HOME + shIdx = posControl.safehomeState.index; + missionFwLandConfigStartIdx = MAX_SAFE_HOMES; +#endif + if (previousState == NAV_STATE_WAYPOINT_REACHED && missionIdx >= 0) { + approachSettingIdx = missionFwLandConfigStartIdx + missionIdx; + } else if (shIdx >= 0) { + approachSettingIdx = shIdx; + } - int32_t landingElevation = posControl.rthState.homeTmpWaypoint.z; - if(STATE(MULTIROTOR) && (remaning_distance>MR_RTH_LAND_MARGIN_CM)){ - descentVelLimited = navConfig()->general.land_minalt_vspd; + if (!posControl.fwLandState.landAborted && approachSettingIdx >= 0 && (fwAutolandApproachConfig(approachSettingIdx)->landApproachHeading1 != 0 || fwAutolandApproachConfig(approachSettingIdx)->landApproachHeading2 != 0)) { + + if (previousState == NAV_STATE_WAYPOINT_REACHED) { + posControl.fwLandState.landPos = posControl.activeWaypoint.pos; + posControl.fwLandState.landWp = true; + } else { + posControl.fwLandState.landPos = posControl.safehomeState.nearestSafeHome; + posControl.fwLandState.landWp = false; + } + + posControl.fwLandState.approachSettingIdx = approachSettingIdx; + posControl.fwLandState.landAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt; + posControl.fwLandState.landAproachAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt; + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING; + } } - // A safeguard - if surface altitude sensors is available and it is reading < 50cm altitude - drop to low descend speed - else if ((posControl.flags.estAglStatus == EST_TRUSTED) && posControl.actualState.agl.pos.z < 50.0f) { - // land_descent_rate == 200 : descend speed = 30 cm/s, gentle touchdown - // Do not allow descent velocity slower than -30cm/s so the landing detector works. +#endif + + float descentVelLimited = 0; + int32_t landingElevation = posControl.rthState.homeTmpWaypoint.z; + + // A safeguard - if surface altitude sensor is available and is reading < 50cm altitude - drop to min descend speed. + // Also slow down to min descent speed during RTH MR landing if MR drifted too far away from home position. + bool minDescentSpeedRequired = (posControl.flags.estAglStatus == EST_TRUSTED && posControl.actualState.agl.pos.z < 50.0f) || + (FLIGHT_MODE(NAV_RTH_MODE) && STATE(MULTIROTOR) && posControl.homeDistance > MR_RTH_LAND_MARGIN_CM); + + // Do not allow descent velocity slower than -30cm/s so the landing detector works (limited by land_minalt_vspd). + if (minDescentSpeedRequired) { descentVelLimited = navConfig()->general.land_minalt_vspd; } else { - // Ramp down descent velocity from 100% at maxAlt altitude to 25% from minAlt to 0cm. + // Ramp down descent velocity from max speed at maxAlt altitude to min speed from minAlt to 0cm. float descentVelScaled = scaleRangef(navGetCurrentActualPositionAndVelocity()->pos.z, - navConfig()->general.land_slowdown_minalt + landingElevation, - navConfig()->general.land_slowdown_maxalt + landingElevation, - navConfig()->general.land_minalt_vspd, navConfig()->general.land_maxalt_vspd); + navConfig()->general.land_slowdown_minalt + landingElevation, + navConfig()->general.land_slowdown_maxalt + landingElevation, + navConfig()->general.land_minalt_vspd, navConfig()->general.land_maxalt_vspd); descentVelLimited = constrainf(descentVelScaled, navConfig()->general.land_minalt_vspd, navConfig()->general.land_maxalt_vspd); } @@ -1586,6 +1820,12 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_WAYPOINT_INITIALIZE(nav resetPositionController(); resetAltitudeController(false); // Make sure surface tracking is not enabled - WP uses global altitude, not AGL +#ifdef USE_FW_AUTOLAND + if (previousState != NAV_STATE_FW_LANDING_ABORT) { + posControl.fwLandState.landAborted = false; + } +#endif + if (posControl.activeWaypointIndex == posControl.startWpIndex || posControl.wpMissionRestart) { /* Use p3 as the volatile jump counter, allowing embedded, rearmed jumps Using p3 minimises the risk of saving an invalid counter if a mission is aborted */ @@ -1795,8 +2035,22 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_WAYPOINT_RTH_LAND(navig { UNUSED(previousState); +#ifdef USE_FW_AUTOLAND + if (posControl.fwLandState.landAborted) { + return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED; + } +#endif + const navigationFSMEvent_t landEvent = navOnEnteringState_NAV_STATE_RTH_LANDING(previousState); - if (landEvent == NAV_FSM_EVENT_SUCCESS) { + +#ifdef USE_FW_AUTOLAND + if (landEvent == NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING) { + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING; + } else +#endif + if (landEvent == NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME) { + return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED; + } else if (landEvent == NAV_FSM_EVENT_SUCCESS) { // Landing controller returned success - invoke RTH finishing state and finish the waypoint navOnEnteringState_NAV_STATE_RTH_FINISHING(previousState); return NAV_FSM_EVENT_SUCCESS; @@ -1839,6 +2093,10 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_EMERGENCY_LANDING_INITI { UNUSED(previousState); +#ifdef USE_FW_AUTOLAND + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; +#endif + if ((posControl.flags.estPosStatus >= EST_USABLE)) { resetPositionController(); setDesiredPosition(&navGetCurrentActualPositionAndVelocity()->pos, 0, NAV_POS_UPDATE_XY); @@ -1903,7 +2161,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_LAUNCH_WAIT(navigationF } // abort NAV_LAUNCH_MODE by moving sticks with low throttle or throttle stick < launch idle throttle - if (abortLaunchAllowed() && isRollPitchStickDeflected(navConfig()->fw.launch_abort_deadband)) { + if (abortLaunchAllowed() && isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { abortFixedWingLaunch(); return NAV_FSM_EVENT_SWITCH_TO_IDLE; } @@ -1986,6 +2244,223 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_MIXERAT_ABORT(navigatio return NAV_FSM_EVENT_SUCCESS; } +#ifdef USE_FW_AUTOLAND +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_CLIMB_TO_LOITER(navigationFSMState_t previousState) +{ + UNUSED(previousState); + + if (isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT; + } + + if (posControl.fwLandState.loiterStartTime == 0) { + posControl.fwLandState.loiterStartTime = micros(); + } + + if (ABS(getEstimatedActualPosition(Z) - posControl.fwLandState.landAproachAltAgl) < (navConfig()->general.waypoint_enforce_altitude > 0 ? navConfig()->general.waypoint_enforce_altitude : FW_LAND_LOITER_ALT_TOLERANCE)) { + updateClimbRateToAltitudeController(0, 0, ROC_TO_ALT_RESET); + posControl.fwLandState.landState = FW_AUTOLAND_STATE_LOITER; + return NAV_FSM_EVENT_SUCCESS; + } + + fpVector3_t tmpHomePos = posControl.rthState.homePosition.pos; + tmpHomePos.z = posControl.fwLandState.landAproachAltAgl; + setDesiredPosition(&tmpHomePos, 0, NAV_POS_UPDATE_Z); + + return NAV_FSM_EVENT_NONE; +} + +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_LOITER(navigationFSMState_t previousState) +{ + UNUSED(previousState); + /* If position sensors unavailable - land immediately (wait for timeout on GPS) */ + if ((posControl.flags.estHeadingStatus == EST_NONE) || checkForPositionSensorTimeout()) { + return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; + } + + if (isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT; + } + + if (micros() - posControl.fwLandState.loiterStartTime > FW_LAND_LOITER_MIN_TIME) { + if (isEstimatedWindSpeedValid()) { + + uint16_t windAngle = 0; + int32_t approachHeading = -1; + float windSpeed = getEstimatedHorizontalWindSpeed(&windAngle); + windAngle = wrap_36000(windAngle + 18000); + + // Ignore low wind speed, could be the error of the wind estimator + if (windSpeed < navFwAutolandConfig()->maxTailwind) { + if (fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading1 != 0) { + approachHeading = posControl.fwLandState.landingDirection = ABS(DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading1)); + } else if ((fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading2 != 0) ) { + approachHeading = posControl.fwLandState.landingDirection = ABS(DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading2)); + } + } else { + int32_t heading1 = calcFinalApproachHeading(DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading1), windAngle); + int32_t heading2 = calcFinalApproachHeading(DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading2), windAngle); + + if (heading1 == heading2 || heading1 == wrap_36000(heading2 + 18000)) { + heading2 = -1; + } + + if (heading1 == -1 && heading2 >= 0) { + posControl.fwLandState.landingDirection = heading2; + approachHeading = DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading2); + } else if (heading1 >= 0 && heading2 == -1) { + posControl.fwLandState.landingDirection = heading1; + approachHeading = DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading1); + } else { + if (calcWindDiff(heading1, windAngle) < calcWindDiff(heading2, windAngle)) { + posControl.fwLandState.landingDirection = heading1; + approachHeading = DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading1); + } else { + posControl.fwLandState.landingDirection = heading2; + approachHeading = DEGREES_TO_CENTIDEGREES(fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landApproachHeading2); + } + } + } + + if (posControl.fwLandState.landingDirection >= 0) { + fpVector3_t tmpPos; + + int32_t finalApproachAlt = posControl.fwLandState.landAproachAltAgl / 3 * 2; + int32_t dir = 0; + if (fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachDirection == FW_AUTOLAND_APPROACH_DIRECTION_LEFT) { + dir = wrap_36000(ABS(approachHeading) - 9000); + } else { + dir = wrap_36000(ABS(approachHeading) + 9000); + } + + calculateFarAwayPos(&tmpPos, &posControl.fwLandState.landPos, posControl.fwLandState.landingDirection, navFwAutolandConfig()->approachLength); + tmpPos.z = posControl.fwLandState.landAltAgl - finalApproachAlt; + posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_LAND] = tmpPos; + + calculateFarAwayPos(&tmpPos, &posControl.fwLandState.landPos, wrap_36000(posControl.fwLandState.landingDirection + 18000), navFwAutolandConfig()->approachLength); + tmpPos.z = finalApproachAlt; + posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_FINAL_APPROACH] = tmpPos; + + calculateFarAwayPos(&tmpPos, &posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_FINAL_APPROACH], dir, MAX((uint32_t)navConfig()->fw.loiter_radius * 4, navFwAutolandConfig()->approachLength / 2)); + tmpPos.z = posControl.fwLandState.landAproachAltAgl; + posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_TURN] = tmpPos; + + setLandWaypoint(&posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_TURN], &posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_FINAL_APPROACH]); + posControl.fwLandState.landCurrentWp = FW_AUTOLAND_WP_TURN; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_DOWNWIND; + + return NAV_FSM_EVENT_SUCCESS; + } else { + posControl.fwLandState.loiterStartTime = micros(); + } + } else { + posControl.fwLandState.loiterStartTime = micros(); + } + } + + fpVector3_t tmpPoint = posControl.fwLandState.landPos; + tmpPoint.z = posControl.fwLandState.landAproachAltAgl; + setDesiredPosition(&tmpPoint, posControl.fwLandState.landPosHeading, NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING); + + return NAV_FSM_EVENT_NONE; +} +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH(navigationFSMState_t previousState) +{ + UNUSED(previousState); + + if ((posControl.flags.estHeadingStatus == EST_NONE) || checkForPositionSensorTimeout()) { + return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; + } + + if (isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT; + } + + if (isLandingDetected()) { + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + //disarm(DISARM_LANDING); + return NAV_FSM_EVENT_SWITCH_TO_IDLE; + } + + if (getLandAltitude() <= fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt + navFwAutolandConfig()->glideAltitude - (fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? GPS_home.alt : 0)) { + resetPositionController(); + posControl.cruise.course = posControl.fwLandState.landingDirection; + posControl.cruise.previousCourse = posControl.cruise.course; + posControl.cruise.lastCourseAdjustmentTime = 0; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_GLIDE; + return NAV_FSM_EVENT_SUCCESS; + } else if (isWaypointReached(&posControl.fwLandState.landWaypoints[posControl.fwLandState.landCurrentWp], &posControl.activeWaypoint.bearing)) { + if (posControl.fwLandState.landCurrentWp == FW_AUTOLAND_WP_TURN) { + setLandWaypoint(&posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_FINAL_APPROACH], &posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_LAND]); + posControl.fwLandState.landCurrentWp = FW_AUTOLAND_WP_FINAL_APPROACH; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_BASE_LEG; + return NAV_FSM_EVENT_NONE; + } else if (posControl.fwLandState.landCurrentWp == FW_AUTOLAND_WP_FINAL_APPROACH) { + setLandWaypoint(&posControl.fwLandState.landWaypoints[FW_AUTOLAND_WP_LAND], NULL); + posControl.fwLandState.landCurrentWp = FW_AUTOLAND_WP_LAND; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_FINAL_APPROACH; + return NAV_FSM_EVENT_NONE; + } + } + + fpVector3_t tmpWaypoint; + tmpWaypoint.x = posControl.activeWaypoint.pos.x; + tmpWaypoint.y = posControl.activeWaypoint.pos.y; + tmpWaypoint.z = scaleRangef(constrainf(posControl.wpDistance, posControl.wpInitialDistance / 10.0f, posControl.wpInitialDistance), + posControl.wpInitialDistance, posControl.wpInitialDistance / 10.0f, + posControl.wpInitialAltitude, posControl.activeWaypoint.pos.z); + setDesiredPosition(&tmpWaypoint, 0, NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_BEARING); + + return NAV_FSM_EVENT_NONE; +} + +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE(navigationFSMState_t previousState) +{ + UNUSED(previousState); + + if (isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { + return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT; + } + + if (getHwRangefinderStatus() == HW_SENSOR_OK && getLandAltitude() <= posControl.fwLandState.landAltAgl + navFwAutolandConfig()->flareAltitude) { + posControl.fwLandState.landState = FW_AUTOLAND_STATE_FLARE; + return NAV_FSM_EVENT_SUCCESS; + } + + if (isLandingDetected()) { + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + //disarm(DISARM_LANDING); + return NAV_FSM_EVENT_SWITCH_TO_IDLE; + } + + setDesiredPosition(NULL, posControl.cruise.course, NAV_POS_UPDATE_HEADING); + return NAV_FSM_EVENT_NONE; +} + +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_FLARE(navigationFSMState_t previousState) +{ + UNUSED(previousState); + + if (isLandingDetected()) { + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + //disarm(DISARM_LANDING); + return NAV_FSM_EVENT_SUCCESS; + } + setDesiredPosition(NULL, posControl.cruise.course, NAV_POS_UPDATE_HEADING); + + return NAV_FSM_EVENT_NONE; +} + +static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_ABORT(navigationFSMState_t previousState) +{ + UNUSED(previousState); + posControl.fwLandState.landAborted = true; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + + return posControl.fwLandState.landWp ? NAV_FSM_EVENT_SWITCH_TO_WAYPOINT : NAV_FSM_EVENT_SWITCH_TO_RTH; +} +#endif + static navigationFSMState_t navSetNewFSMState(navigationFSMState_t newState) { navigationFSMState_t previousState; @@ -2563,7 +3038,7 @@ void setHomePosition(const fpVector3_t * pos, int32_t heading, navSetWaypointFla updateDesiredRTHAltitude(); // Reset RTH sanity checker for new home position if RTH active - if (FLIGHT_MODE(NAV_RTH_MODE)) { + if (FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_FW_AUTOLAND) ) { initializeRTHSanityChecker(); } @@ -2660,11 +3135,15 @@ bool findNearestSafeHome(void) *-----------------------------------------------------------*/ void updateHomePosition(void) { - // Disarmed and have a valid position, constantly update home + // Disarmed and have a valid position, constantly update home before first arm (depending on setting) + // Update immediately after arming thereafter if reset on each arm (required to avoid home reset after emerg in flight rearm) + static bool setHome = false; + navSetWaypointFlags_t homeUpdateFlags = NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING; + if (!ARMING_FLAG(ARMED)) { if (posControl.flags.estPosStatus >= EST_USABLE) { const navigationHomeFlags_t validHomeFlags = NAV_HOME_VALID_XY | NAV_HOME_VALID_Z; - bool setHome = (posControl.rthState.homeFlags & validHomeFlags) != validHomeFlags; + setHome = (posControl.rthState.homeFlags & validHomeFlags) != validHomeFlags; switch ((nav_reset_type_e)positionEstimationConfig()->reset_home_type) { case NAV_RESET_NEVER: break; @@ -2675,24 +3154,16 @@ void updateHomePosition(void) setHome = true; break; } - if (setHome) { -#if defined(USE_SAFE_HOME) - findNearestSafeHome(); -#endif - setHomePosition(&posControl.actualState.abs.pos, posControl.actualState.yaw, NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING, navigationActualStateHomeValidity()); - // save the current location in case it is replaced by a safehome or HOME_RESET - posControl.rthState.originalHomePosition = posControl.rthState.homePosition.pos; - } } } else { static bool isHomeResetAllowed = false; - // If pilot so desires he may reset home position to current position if (IS_RC_MODE_ACTIVE(BOXHOMERESET)) { - if (isHomeResetAllowed && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_RTH_MODE) && !FLIGHT_MODE(NAV_WP_MODE) && (posControl.flags.estPosStatus >= EST_USABLE)) { - const navSetWaypointFlags_t homeUpdateFlags = STATE(GPS_FIX_HOME) ? (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_HEADING) : (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING); - setHomePosition(&posControl.actualState.abs.pos, posControl.actualState.yaw, homeUpdateFlags, navigationActualStateHomeValidity()); + if (isHomeResetAllowed && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_RTH_MODE) && !FLIGHT_MODE(NAV_FW_AUTOLAND) && !FLIGHT_MODE(NAV_WP_MODE) && (posControl.flags.estPosStatus >= EST_USABLE)) { + homeUpdateFlags = 0; + homeUpdateFlags = STATE(GPS_FIX_HOME) ? (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_HEADING) : (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING); + setHome = true; isHomeResetAllowed = false; } } @@ -2707,6 +3178,22 @@ void updateHomePosition(void) posControl.homeDirection = calculateBearingToDestination(tmpHomePos); updateHomePositionCompatibility(); } + + setHome &= !STATE(IN_FLIGHT_EMERG_REARM); // prevent reset following emerg in flight rearm + } + + if (setHome && (!ARMING_FLAG(WAS_EVER_ARMED) || ARMING_FLAG(ARMED))) { +#if defined(USE_SAFE_HOME) + findNearestSafeHome(); +#endif + setHomePosition(&posControl.actualState.abs.pos, posControl.actualState.yaw, homeUpdateFlags, navigationActualStateHomeValidity()); + + if (ARMING_FLAG(ARMED) && positionEstimationConfig()->reset_altitude_type == NAV_RESET_ON_EACH_ARM) { + posControl.rthState.homePosition.pos.z = 0; // force to 0 if reference altitude also reset every arm + } + // save the current location in case it is replaced by a safehome or HOME_RESET + posControl.rthState.originalHomePosition = posControl.rthState.homePosition.pos; + setHome = false; } } @@ -2778,7 +3265,7 @@ static bool rthAltControlStickOverrideCheck(unsigned axis) suspendTracking = false; } - if (navConfig()->general.flags.rth_trackback_mode == RTH_TRACKBACK_OFF || FLIGHT_MODE(NAV_RTH_MODE) || !ARMING_FLAG(ARMED) || suspendTracking) { + if (navConfig()->general.flags.rth_trackback_mode == RTH_TRACKBACK_OFF || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_FW_AUTOLAND) || !ARMING_FLAG(ARMED) || suspendTracking) { return; } @@ -2879,6 +3366,9 @@ static void updateNavigationFlightStatistics(void) } } +/* + * Total travel distance in cm + */ uint32_t getTotalTravelDistance(void) { return lrintf(posControl.totalTripDistance); @@ -2927,11 +3417,16 @@ void setDesiredPosition(const fpVector3_t * pos, int32_t yaw, navSetWaypointFlag } } +void calculateFarAwayPos(fpVector3_t *farAwayPos, const fpVector3_t *start, int32_t bearing, int32_t distance) +{ + farAwayPos->x = start->x + distance * cos_approx(CENTIDEGREES_TO_RADIANS(bearing)); + farAwayPos->y = start->y + distance * sin_approx(CENTIDEGREES_TO_RADIANS(bearing)); + farAwayPos->z = start->z; +} + void calculateFarAwayTarget(fpVector3_t * farAwayPos, int32_t bearing, int32_t distance) { - farAwayPos->x = navGetCurrentActualPositionAndVelocity()->pos.x + distance * cos_approx(CENTIDEGREES_TO_RADIANS(bearing)); - farAwayPos->y = navGetCurrentActualPositionAndVelocity()->pos.y + distance * sin_approx(CENTIDEGREES_TO_RADIANS(bearing)); - farAwayPos->z = navGetCurrentActualPositionAndVelocity()->pos.z; + calculateFarAwayPos(farAwayPos, &navGetCurrentActualPositionAndVelocity()->pos, bearing, distance); } /*----------------------------------------------------------- @@ -2949,14 +3444,15 @@ void updateLandingStatus(timeMs_t currentTimeMs) } lastUpdateTimeMs = currentTimeMs; - static bool landingDetectorIsActive; - DEBUG_SET(DEBUG_LANDING, 0, landingDetectorIsActive); DEBUG_SET(DEBUG_LANDING, 1, STATE(LANDING_DETECTED)); if (!ARMING_FLAG(ARMED)) { + if (STATE(LANDING_DETECTED)) { + landingDetectorIsActive = false; + } resetLandingDetector(); - landingDetectorIsActive = false; + if (!IS_RC_MODE_ACTIVE(BOXARM)) { DISABLE_ARMING_FLAG(ARMING_DISABLED_LANDING_DETECTED); } @@ -2993,11 +3489,28 @@ void resetLandingDetector(void) posControl.flags.resetLandingDetector = true; } +void resetLandingDetectorActiveState(void) +{ + landingDetectorIsActive = false; +} + bool isFlightDetected(void) { return STATE(AIRPLANE) ? isFixedWingFlying() : isMulticopterFlying(); } +bool isProbablyStillFlying(void) +{ + bool inFlightSanityCheck; + if (STATE(MULTIROTOR)) { + inFlightSanityCheck = posControl.actualState.velXY > MC_LAND_CHECK_VEL_XY_MOVING || averageAbsGyroRates() > 4.0f; + } else { + inFlightSanityCheck = isGPSHeadingValid(); + } + + return landingDetectorIsActive && inFlightSanityCheck; +} + /*----------------------------------------------------------- * Z-position controller *-----------------------------------------------------------*/ @@ -3014,12 +3527,12 @@ void updateClimbRateToAltitudeController(float desiredClimbRate, float targetAlt if (mode != ROC_TO_ALT_RESET && desiredClimbRate) { /* ROC_TO_ALT_CONSTANT - constant climb rate * ROC_TO_ALT_TARGET - constant climb rate until close to target altitude reducing to min rate when altitude reached - * Rate reduction starts at distance from target altitude of 5 x climb rate for FW, 1 x climb rate for MC */ + * Rate reduction starts at distance from target altitude of 5 x climb rate */ if (mode == ROC_TO_ALT_TARGET && fabsf(desiredClimbRate) > MIN_TARGET_CLIMB_RATE) { const int8_t direction = desiredClimbRate > 0 ? 1 : -1; const float absClimbRate = fabsf(desiredClimbRate); - const uint16_t maxRateCutoffAlt = STATE(AIRPLANE) ? absClimbRate * 5 : absClimbRate; + const uint16_t maxRateCutoffAlt = absClimbRate * 5; const float verticalVelScaled = scaleRangef(navGetCurrentActualPositionAndVelocity()->pos.z - targetAltitude, 0.0f, -maxRateCutoffAlt * direction, MIN_TARGET_CLIMB_RATE, absClimbRate); @@ -3570,6 +4083,7 @@ bool isNavHoldPositionActive(void) // Also hold position during emergency landing if position valid return (FLIGHT_MODE(NAV_RTH_MODE) && !posControl.flags.rthTrackbackActive) || FLIGHT_MODE(NAV_POSHOLD_MODE) || + (posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER || posControl.navState == NAV_STATE_FW_LANDING_LOITER) || navigationIsExecutingAnEmergencyLanding(); } @@ -3609,7 +4123,9 @@ bool isWaypointNavTrackingActive(void) // is set from current position not previous WP. Works for WP Restart intermediate WP as well as first mission WP. // (NAV_WP_MODE flag isn't set until WP initialisation is finished, i.e. after calculateAndSetActiveWaypoint called) - return FLIGHT_MODE(NAV_WP_MODE) || (posControl.flags.rthTrackbackActive && posControl.activeRthTBPointIndex != posControl.rthTBLastSavedIndex); + return FLIGHT_MODE(NAV_WP_MODE) + || posControl.navState == NAV_STATE_FW_LANDING_APPROACH + || (posControl.flags.rthTrackbackActive && posControl.activeRthTBPointIndex != posControl.rthTBLastSavedIndex); } /*----------------------------------------------------------- @@ -3677,6 +4193,12 @@ void applyWaypointNavigationAndAltitudeHold(void) posControl.flags.horizontalPositionDataConsumed = false; posControl.flags.verticalPositionDataConsumed = false; +#ifdef USE_FW_AUTOLAND + if (!FLIGHT_MODE(NAV_FW_AUTOLAND)) { + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + } +#endif + /* Process controllers */ navigationFSMStateFlags_t navStateFlags = navGetStateFlags(posControl.navState); if (STATE(ROVER) || STATE(BOAT)) { @@ -3713,7 +4235,7 @@ void applyWaypointNavigationAndAltitudeHold(void) void switchNavigationFlightModes(void) { const flightModeFlags_e enabledNavFlightModes = navGetMappedFlightModes(posControl.navState); - const flightModeFlags_e disabledFlightModes = (NAV_ALTHOLD_MODE | NAV_RTH_MODE | NAV_POSHOLD_MODE | NAV_WP_MODE | NAV_LAUNCH_MODE | NAV_COURSE_HOLD_MODE) & (~enabledNavFlightModes); + const flightModeFlags_e disabledFlightModes = (NAV_ALTHOLD_MODE | NAV_RTH_MODE | NAV_FW_AUTOLAND | NAV_POSHOLD_MODE | NAV_WP_MODE | NAV_LAUNCH_MODE | NAV_COURSE_HOLD_MODE) & (~enabledNavFlightModes); DISABLE_FLIGHT_MODE(disabledFlightModes); ENABLE_FLIGHT_MODE(enabledNavFlightModes); } @@ -3778,7 +4300,6 @@ void checkManualEmergencyLandingControl(bool forcedActivation) static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) { - static bool canActivateWaypoint = false; static bool canActivateLaunchMode = false; //We can switch modes only when ARMED @@ -3826,12 +4347,6 @@ static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) } posControl.rthSanityChecker.rthSanityOK = true; - // Keep canActivateWaypoint flag at FALSE if there is no mission loaded - // Also block WP mission if we are executing RTH - if (!isWaypointMissionValid() || isExecutingRTH) { - canActivateWaypoint = false; - } - /* Airplane specific modes */ if (STATE(AIRPLANE)) { // LAUNCH mode has priority over any other NAV mode @@ -3859,30 +4374,48 @@ static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) /* Soaring mode, disables altitude control in Position hold and Course hold modes. * Pitch allowed to freefloat within defined Angle mode deadband */ if (IS_RC_MODE_ACTIVE(BOXSOARING) && (FLIGHT_MODE(NAV_POSHOLD_MODE) || FLIGHT_MODE(NAV_COURSE_HOLD_MODE))) { - if (!FLIGHT_MODE(SOARING_MODE)) { - ENABLE_FLIGHT_MODE(SOARING_MODE); - } + ENABLE_FLIGHT_MODE(SOARING_MODE); } else { DISABLE_FLIGHT_MODE(SOARING_MODE); } } - // Failsafe_RTH (can override MANUAL) + /* If we request forced RTH - attempt to activate it no matter what + * This might switch to emergency landing controller if GPS is unavailable */ if (posControl.flags.forcedRTHActivated) { - // If we request forced RTH - attempt to activate it no matter what - // This might switch to emergency landing controller if GPS is unavailable return NAV_FSM_EVENT_SWITCH_TO_RTH; } - /* Pilot-triggered RTH (can override MANUAL), also fall-back for WP if there is no mission loaded - * Prevent MANUAL falling back to RTH if selected during active mission (canActivateWaypoint is set false on MANUAL selection) - * Also prevent WP falling back to RTH if WP mission planner is active */ - const bool blockWPFallback = IS_RC_MODE_ACTIVE(BOXMANUAL) || posControl.flags.wpMissionPlannerActive; - if (IS_RC_MODE_ACTIVE(BOXNAVRTH) || (IS_RC_MODE_ACTIVE(BOXNAVWP) && !canActivateWaypoint && !blockWPFallback)) { - // Check for isExecutingRTH to prevent switching our from RTH in case of a brief GPS loss - // If don't keep this, loss of any of the canActivateNavigation && canActivateAltHold - // will kick us out of RTH state machine via NAV_FSM_EVENT_SWITCH_TO_IDLE and will prevent any of the fall-back - // logic to kick in (waiting for GPS on airplanes, switch to emergency landing etc) + /* WP mission activation control: + * canActivateWaypoint & waypointWasActivated are used to prevent WP mission + * auto restarting after interruption by Manual or RTH modes. + * WP mode must be deselected before it can be reactivated again + * WP Mode also inhibited when Mission Planner is active */ + static bool waypointWasActivated = false; + bool canActivateWaypoint = isWaypointMissionValid(); + bool wpRthFallbackIsActive = false; + + if (IS_RC_MODE_ACTIVE(BOXMANUAL) || posControl.flags.wpMissionPlannerActive) { + canActivateWaypoint = false; + } else { + if (waypointWasActivated && !FLIGHT_MODE(NAV_WP_MODE)) { + canActivateWaypoint = false; + + if (!IS_RC_MODE_ACTIVE(BOXNAVWP)) { + canActivateWaypoint = true; + waypointWasActivated = false; + } + } + + wpRthFallbackIsActive = IS_RC_MODE_ACTIVE(BOXNAVWP) && !canActivateWaypoint; + } + + /* Pilot-triggered RTH, also fall-back for WP if no mission is loaded. + * Check for isExecutingRTH to prevent switching our from RTH in case of a brief GPS loss + * Without this loss of any of the canActivateNavigation && canActivateAltHold + * will kick us out of RTH state machine via NAV_FSM_EVENT_SWITCH_TO_IDLE and will prevent any of the fall-back + * logic kicking in (waiting for GPS on airplanes, switch to emergency landing etc) */ + if (IS_RC_MODE_ACTIVE(BOXNAVRTH) || wpRthFallbackIsActive) { if (isExecutingRTH || (canActivateNavigation && canActivateAltHold && STATE(GPS_FIX_HOME))) { return NAV_FSM_EVENT_SWITCH_TO_RTH; } @@ -3890,24 +4423,20 @@ static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) // MANUAL mode has priority over WP/PH/AH if (IS_RC_MODE_ACTIVE(BOXMANUAL)) { - canActivateWaypoint = false; // Block WP mode if we are in PASSTHROUGH mode return NAV_FSM_EVENT_SWITCH_TO_IDLE; } - // Pilot-activated waypoint mission. Fall-back to RTH in case of no mission loaded - // Block activation if using WP Mission Planner - // Also check multimission mission change status before activating WP mode + // Pilot-activated waypoint mission. Fall-back to RTH if no mission loaded. + // Also check multimission mission change status before activating WP mode. #ifdef USE_MULTI_MISSION - if (updateWpMissionChange() && IS_RC_MODE_ACTIVE(BOXNAVWP) && !posControl.flags.wpMissionPlannerActive) { + if (updateWpMissionChange() && IS_RC_MODE_ACTIVE(BOXNAVWP)) { #else - if (IS_RC_MODE_ACTIVE(BOXNAVWP) && !posControl.flags.wpMissionPlannerActive) { + if (IS_RC_MODE_ACTIVE(BOXNAVWP)) { #endif - if (FLIGHT_MODE(NAV_WP_MODE) || (canActivateWaypoint && canActivateNavigation && canActivateAltHold && STATE(GPS_FIX_HOME))) + if (FLIGHT_MODE(NAV_WP_MODE) || (canActivateWaypoint && canActivateNavigation && canActivateAltHold && STATE(GPS_FIX_HOME))) { + waypointWasActivated = true; return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT; - } - else { - // Arm the state variable if the WP BOX mode is not enabled - canActivateWaypoint = true; + } } if (IS_RC_MODE_ACTIVE(BOXNAVPOSHOLD)) { @@ -3916,14 +4445,14 @@ static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) } // CRUISE has priority over COURSE_HOLD and AH - if (IS_RC_MODE_ACTIVE(BOXNAVCRUISE) && STATE(AIRPLANE)) { + if (IS_RC_MODE_ACTIVE(BOXNAVCRUISE)) { if ((FLIGHT_MODE(NAV_COURSE_HOLD_MODE) && FLIGHT_MODE(NAV_ALTHOLD_MODE)) || (canActivatePosHold && canActivateAltHold)) return NAV_FSM_EVENT_SWITCH_TO_CRUISE; } // PH has priority over COURSE_HOLD // CRUISE has priority on AH - if (IS_RC_MODE_ACTIVE(BOXNAVCOURSEHOLD) && STATE(AIRPLANE)) { + if (IS_RC_MODE_ACTIVE(BOXNAVCOURSEHOLD)) { if (IS_RC_MODE_ACTIVE(BOXNAVALTHOLD) && ((FLIGHT_MODE(NAV_COURSE_HOLD_MODE) && FLIGHT_MODE(NAV_ALTHOLD_MODE)) || (canActivatePosHold && canActivateAltHold))) { return NAV_FSM_EVENT_SWITCH_TO_CRUISE; } @@ -3937,12 +4466,9 @@ static navigationFSMEvent_t selectNavEventFromBoxModeInput(void) if ((FLIGHT_MODE(NAV_ALTHOLD_MODE)) || (canActivateAltHold)) return NAV_FSM_EVENT_SWITCH_TO_ALTHOLD; } - } - else { - canActivateWaypoint = false; - + } else { // Launch mode can be activated if feature FW_LAUNCH is enabled or BOX is turned on prior to arming (avoid switching to LAUNCH in flight) - canActivateLaunchMode = isNavLaunchEnabled(); + canActivateLaunchMode = isNavLaunchEnabled() && (!sensors(SENSOR_GPS) || (sensors(SENSOR_GPS) && !isGPSHeadingValid())); } return NAV_FSM_EVENT_SWITCH_TO_IDLE; @@ -4021,7 +4547,8 @@ bool navigationPositionEstimateIsHealthy(void) navArmingBlocker_e navigationIsBlockingArming(bool *usedBypass) { - const bool navBoxModesEnabled = IS_RC_MODE_ACTIVE(BOXNAVRTH) || IS_RC_MODE_ACTIVE(BOXNAVWP) || IS_RC_MODE_ACTIVE(BOXNAVPOSHOLD) || (STATE(FIXED_WING_LEGACY) && IS_RC_MODE_ACTIVE(BOXNAVALTHOLD)) || (STATE(FIXED_WING_LEGACY) && (IS_RC_MODE_ACTIVE(BOXNAVCOURSEHOLD) || IS_RC_MODE_ACTIVE(BOXNAVCRUISE))); + const bool navBoxModesEnabled = IS_RC_MODE_ACTIVE(BOXNAVRTH) || IS_RC_MODE_ACTIVE(BOXNAVWP) || IS_RC_MODE_ACTIVE(BOXNAVCOURSEHOLD) || + IS_RC_MODE_ACTIVE(BOXNAVCRUISE) || IS_RC_MODE_ACTIVE(BOXNAVPOSHOLD) || (STATE(FIXED_WING_LEGACY) && IS_RC_MODE_ACTIVE(BOXNAVALTHOLD)); if (usedBypass) { *usedBypass = false; @@ -4051,13 +4578,13 @@ navArmingBlocker_e navigationIsBlockingArming(bool *usedBypass) } } - /* - * Don't allow arming if any of JUMP waypoint has invalid settings - * First WP can't be JUMP - * Can't jump to immediately adjacent WPs (pointless) - * Can't jump beyond WP list - * Only jump to geo-referenced WP types - */ + /* + * Don't allow arming if any of JUMP waypoint has invalid settings + * First WP can't be JUMP + * Can't jump to immediately adjacent WPs (pointless) + * Can't jump beyond WP list + * Only jump to geo-referenced WP types + */ if (posControl.waypointCount) { for (uint8_t wp = posControl.startWpIndex; wp < posControl.waypointCount + posControl.startWpIndex; wp++){ if (posControl.waypointList[wp].action == NAV_WP_ACTION_JUMP){ @@ -4397,7 +4924,7 @@ void abortForcedRTH(void) rthState_e getStateOfForcedRTH(void) { /* If forced RTH activated and in AUTO_RTH or EMERG state */ - if (posControl.flags.forcedRTHActivated && (navGetStateFlags(posControl.navState) & (NAV_AUTO_RTH | NAV_CTL_EMERG | NAV_MIXERAT))) { + if (posControl.flags.forcedRTHActivated && ((navGetStateFlags(posControl.navState) & (NAV_AUTO_RTH | NAV_CTL_EMERG | NAV_MIXERAT)) || FLIGHT_MODE(NAV_FW_AUTOLAND))) { if (posControl.navState == NAV_STATE_RTH_FINISHED || posControl.navState == NAV_STATE_EMERGENCY_LANDING_FINISHED) { return RTH_HAS_LANDED; } @@ -4479,6 +5006,12 @@ bool navigationIsFlyingAutonomousMode(void) bool navigationRTHAllowsLanding(void) { +#ifdef USE_FW_AUTOLAND + if (posControl.fwLandState.landAborted) { + return false; + } +#endif + // WP mission RTH landing setting if (isWaypointMissionRTHActive() && isWaypointMissionValid()) { return posControl.waypointList[posControl.startWpIndex + posControl.waypointCount - 1].p1 > 0; @@ -4533,3 +5066,115 @@ int32_t navigationGetHeadingError(void) { return wrap_18000(posControl.desiredState.yaw - posControl.actualState.cog); } + +int8_t navCheckActiveAngleHoldAxis(void) +{ + int8_t activeAxis = -1; + + if (IS_RC_MODE_ACTIVE(BOXANGLEHOLD)) { + navigationFSMStateFlags_t stateFlags = navGetCurrentStateFlags(); + bool altholdActive = stateFlags & NAV_REQUIRE_ANGLE_FW && !(stateFlags & NAV_REQUIRE_ANGLE); + + if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE) && !FLIGHT_MODE(NAV_ALTHOLD_MODE)) { + activeAxis = FD_PITCH; + } else if (altholdActive) { + activeAxis = FD_ROLL; + } + } + + return activeAxis; +} + +uint8_t getActiveWpNumber(void) +{ + return NAV_Status.activeWpNumber; +} + +#ifdef USE_FW_AUTOLAND + +static void resetFwAutoland(void) +{ + posControl.fwLandState.landAltAgl = 0; + posControl.fwLandState.landAproachAltAgl = 0; + posControl.fwLandState.loiterStartTime = 0; + posControl.fwLandState.approachSettingIdx = 0; + posControl.fwLandState.landPosHeading = -1; + posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; + posControl.fwLandState.landWp = false; +} + +static int32_t calcFinalApproachHeading(int32_t approachHeading, int32_t windAngle) +{ + if (approachHeading == 0) { + return -1; + } + + int32_t windRelToRunway = wrap_36000(windAngle - ABS(approachHeading)); + // Headwind? + if (windRelToRunway >= 27000 || windRelToRunway <= 9000) { + return wrap_36000(ABS(approachHeading)); + } + + if (approachHeading > 0) { + return wrap_36000(approachHeading + 18000); + } + + return -1; +} + +static float getLandAltitude(void) +{ + float altitude = -1; +#ifdef USE_RANGEFINDER + if (rangefinderIsHealthy() && rangefinderGetLatestAltitude() > RANGEFINDER_OUT_OF_RANGE) { + altitude = rangefinderGetLatestAltitude(); + } + else +#endif + if (posControl.flags.estAglStatus >= EST_USABLE) { + altitude = posControl.actualState.agl.pos.z; + } else { + altitude = posControl.actualState.abs.pos.z; + } + return altitude; +} + +static int32_t calcWindDiff(int32_t heading, int32_t windHeading) +{ + return ABS(wrap_18000(windHeading - heading)); +} + +static void setLandWaypoint(const fpVector3_t *pos, const fpVector3_t *nextWpPos) +{ + calculateAndSetActiveWaypointToLocalPosition(pos); + + if (navConfig()->fw.wp_turn_smoothing && nextWpPos != NULL) { + int32_t bearingToNextWp = calculateBearingBetweenLocalPositions(&posControl.activeWaypoint.pos, nextWpPos); + posControl.activeWaypoint.nextTurnAngle = wrap_18000(bearingToNextWp - posControl.activeWaypoint.bearing); + } else { + posControl.activeWaypoint.nextTurnAngle = -1; + } + + posControl.wpInitialDistance = calculateDistanceToDestination(&posControl.activeWaypoint.pos); + posControl.wpInitialAltitude = posControl.actualState.abs.pos.z; + posControl.wpAltitudeReached = false; +} + +void resetFwAutolandApproach(int8_t idx) +{ + if (idx >= 0 && idx < MAX_FW_LAND_APPOACH_SETTINGS) { + memset(fwAutolandApproachConfigMutable(idx), 0, sizeof(navFwAutolandApproach_t)); + } else { + memset(fwAutolandApproachConfigMutable(0), 0, sizeof(navFwAutolandApproach_t) * MAX_FW_LAND_APPOACH_SETTINGS); + } +} + +bool canFwLandCanceld(void) +{ + return posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER + || posControl.navState == NAV_STATE_FW_LANDING_LOITER + || posControl.navState == NAV_STATE_FW_LANDING_APPROACH + || posControl.navState == NAV_STATE_FW_LANDING_GLIDE; +} + +#endif diff --git a/src/main/navigation/navigation.h b/src/main/navigation/navigation.h index 3a9223ff639..6ebdaeccead 100644 --- a/src/main/navigation/navigation.h +++ b/src/main/navigation/navigation.h @@ -31,6 +31,7 @@ #include "io/gps.h" + /* GPS Home location data */ extern gpsLocation_t GPS_home; extern uint32_t GPS_distanceToHome; // distance to home point in meters @@ -40,6 +41,7 @@ extern bool autoThrottleManuallyIncreased; /* Navigation system updates */ void onNewGPSData(void); + #if defined(USE_SAFE_HOME) #define MAX_SAFE_HOMES 8 @@ -58,10 +60,62 @@ typedef enum { PG_DECLARE_ARRAY(navSafeHome_t, MAX_SAFE_HOMES, safeHomeConfig); -void resetSafeHomes(void); // remove all safehomes -bool findNearestSafeHome(void); // Find nearest safehome +void resetSafeHomes(void); // remove all safehomes +bool findNearestSafeHome(void); // Find nearest safehome + #endif // defined(USE_SAFE_HOME) +#ifdef USE_FW_AUTOLAND + +#ifndef MAX_SAFE_HOMES +#define MAX_SAFE_HOMES 0 +#endif + +#define MAX_FW_LAND_APPOACH_SETTINGS (MAX_SAFE_HOMES + 9) + +typedef enum { + FW_AUTOLAND_APPROACH_DIRECTION_LEFT, + FW_AUTOLAND_APPROACH_DIRECTION_RIGHT +} fwAutolandApproachDirection_e; + +typedef enum { + FW_AUTOLAND_STATE_IDLE, + FW_AUTOLAND_STATE_LOITER, + FW_AUTOLAND_STATE_DOWNWIND, + FW_AUTOLAND_STATE_BASE_LEG, + FW_AUTOLAND_STATE_FINAL_APPROACH, + FW_AUTOLAND_STATE_GLIDE, + FW_AUTOLAND_STATE_FLARE +} fwAutolandState_t; + +typedef struct { + int32_t approachAlt; + int32_t landAlt; + bool isSeaLevelRef; + fwAutolandApproachDirection_e approachDirection; + int16_t landApproachHeading1; + int16_t landApproachHeading2; +} navFwAutolandApproach_t; + +PG_DECLARE_ARRAY(navFwAutolandApproach_t, MAX_FW_LAND_APPOACH_SETTINGS, fwAutolandApproachConfig); + +typedef struct navFwAutolandConfig_s +{ + uint32_t approachLength; + uint16_t finalApproachPitchToThrottleMod; + uint16_t glideAltitude; + uint16_t flareAltitude; + uint8_t flarePitch; + uint16_t maxTailwind; + int8_t glidePitch; +} navFwAutolandConfig_t; + +PG_DECLARE(navFwAutolandConfig_t, navFwAutolandConfig); + +void resetFwAutolandApproach(int8_t idx); + +#endif + #ifndef NAV_MAX_WAYPOINTS #define NAV_MAX_WAYPOINTS 15 #endif @@ -203,7 +257,6 @@ typedef struct positionEstimationConfig_s { float w_xy_res_v; float w_acc_bias; // Weight (cutoff frequency) for accelerometer bias estimation. 0 to disable. - float w_xyz_acc_p; float max_eph_epv; // Max estimated position error acceptable for estimation (cm) float baro_epv; // Baro position error @@ -245,6 +298,7 @@ typedef struct navConfig_s { #endif bool waypoint_load_on_boot; // load waypoints automatically during boot uint16_t auto_speed; // autonomous navigation speed cm/sec + uint8_t min_ground_speed; // Minimum navigation ground speed [m/s] uint16_t max_auto_speed; // maximum allowed autonomous navigation speed cm/sec uint16_t max_auto_climb_rate; // max vertical speed limitation cm/sec uint16_t max_manual_speed; // manual velocity control max horizontal speed @@ -268,6 +322,7 @@ typedef struct navConfig_s { uint16_t auto_disarm_delay; // safety time delay for landing detector uint16_t rth_linear_descent_start_distance; // Distance from home to start the linear descent (0 = immediately) uint8_t cruise_yaw_rate; // Max yaw rate (dps) when CRUISE MODE is enabled + uint16_t rth_fs_landing_delay; // Delay upon reaching home before starting landing if in FS (0 = immediate) } general; struct { @@ -315,7 +370,8 @@ typedef struct navConfig_s { uint8_t launch_climb_angle; // Target climb angle for launch (deg) uint8_t launch_max_angle; // Max tilt angle (pitch/roll combined) to consider launch successful. Set to 180 to disable completely [deg] bool launch_manual_throttle; // Allows launch with manual throttle control - uint8_t launch_abort_deadband; // roll/pitch stick movement deadband for launch abort + uint8_t launch_land_abort_deadband; // roll/pitch stick movement deadband for launch abort + uint8_t cruise_yaw_rate; // Max yaw rate (dps) when CRUISE MODE is enabled bool allow_manual_thr_increase; bool useFwNavYawControl; uint8_t yawControlDeadband; @@ -595,7 +651,7 @@ bool isFixedWingAutoThrottleManuallyIncreased(void); bool navigationIsFlyingAutonomousMode(void); bool navigationIsExecutingAnEmergencyLanding(void); bool navigationIsControllingAltitude(void); -/* Returns true iff navConfig()->general.flags.rth_allow_landing is NAV_RTH_ALLOW_LANDING_ALWAYS +/* Returns true if navConfig()->general.flags.rth_allow_landing is NAV_RTH_ALLOW_LANDING_ALWAYS * or if it's NAV_RTH_ALLOW_LANDING_FAILSAFE and failsafe mode is active. */ bool navigationRTHAllowsLanding(void); @@ -610,6 +666,8 @@ const char * fixedWingLaunchStateMessage(void); float calculateAverageSpeed(void); void updateLandingStatus(timeMs_t currentTimeMs); +bool isProbablyStillFlying(void); +void resetLandingDetectorActiveState(void); const navigationPIDControllers_t* getNavigationPIDControllers(void); @@ -625,12 +683,19 @@ bool isEstimatedAglTrusted(void); void checkManualEmergencyLandingControl(bool forcedActivation); float updateBaroAltitudeRate(float newBaroAltRate, bool updateValue); +int8_t navCheckActiveAngleHoldAxis(void); +uint8_t getActiveWpNumber(void); + /* Returns the heading recorded when home position was acquired. * Note that the navigation system uses deg*100 as unit and angles * are in the [0, 360 * 100) interval. */ int32_t navigationGetHomeHeading(void); +#ifdef USE_FW_AUTOLAND +bool canFwLandCanceld(void); +#endif + /* Compatibility data */ extern navSystemStatus_t NAV_Status; diff --git a/src/main/navigation/navigation_fixedwing.c b/src/main/navigation/navigation_fixedwing.c index 3a88e4ea366..2dfebdf8d98 100755 --- a/src/main/navigation/navigation_fixedwing.c +++ b/src/main/navigation/navigation_fixedwing.c @@ -60,9 +60,8 @@ #define NAV_FW_BASE_PITCH_CUTOFF_FREQUENCY_HZ 2.0f #define NAV_FW_BASE_ROLL_CUTOFF_FREQUENCY_HZ 10.0f -// If we are going slower than NAV_FW_MIN_VEL_SPEED_BOOST - boost throttle to fight against the wind +// If we are going slower than the minimum ground speed (navConfig()->general.min_ground_speed) - boost throttle to fight against the wind #define NAV_FW_THROTTLE_SPEED_BOOST_GAIN 1.5f -#define NAV_FW_MIN_VEL_SPEED_BOOST 700.0f // 7 m/s // If this is enabled navigation won't be applied if velocity is below 3 m/s //#define NAV_FW_LIMIT_MIN_FLY_VELOCITY @@ -272,7 +271,7 @@ static int8_t loiterDirection(void) { static void calculateVirtualPositionTarget_FW(float trackingPeriod) { - if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { + if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE) { return; } @@ -406,7 +405,7 @@ static void updatePositionHeadingController_FW(timeUs_t currentTimeUs, timeDelta static bool forceTurnDirection = false; int32_t virtualTargetBearing; - if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { + if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE) { virtualTargetBearing = posControl.desiredState.yaw; } else { // We have virtual position target, calculate heading error @@ -518,8 +517,8 @@ void applyFixedWingPositionController(timeUs_t currentTimeUs) // POSITION_TARGET_UPDATE_RATE_HZ should be chosen keeping in mind that position target shouldn't be reached until next pos update occurs // FIXME: verify the above calculateVirtualPositionTarget_FW(HZ2S(MIN_POSITION_UPDATE_RATE_HZ) * 2); - updatePositionHeadingController_FW(currentTimeUs, deltaMicrosPositionUpdate); + needToCalculateCircularLoiter = false; } else { // Position update has not occurred in time (first iteration or glitch), reset altitude controller @@ -552,10 +551,10 @@ int16_t applyFixedWingMinSpeedController(timeUs_t currentTimeUs) previousTimePositionUpdate = currentTimeUs; if (deltaMicrosPositionUpdate < MAX_POSITION_UPDATE_INTERVAL_US) { - float velThrottleBoost = (NAV_FW_MIN_VEL_SPEED_BOOST - posControl.actualState.velXY) * NAV_FW_THROTTLE_SPEED_BOOST_GAIN * US2S(deltaMicrosPositionUpdate); + float velThrottleBoost = ((navConfig()->general.min_ground_speed * 100.0f) - posControl.actualState.velXY) * NAV_FW_THROTTLE_SPEED_BOOST_GAIN * US2S(deltaMicrosPositionUpdate); // If we are in the deadband of 50cm/s - don't update speed boost - if (fabsf(posControl.actualState.velXY - NAV_FW_MIN_VEL_SPEED_BOOST) > 50) { + if (fabsf(posControl.actualState.velXY - (navConfig()->general.min_ground_speed * 100.0f)) > 50) { throttleSpeedAdjustment += velThrottleBoost; } @@ -589,13 +588,21 @@ int16_t fixedWingPitchToThrottleCorrection(int16_t pitch, timeUs_t currentTimeUs // Apply low-pass filter to pitch angle to smooth throttle correction int16_t filteredPitch = (int16_t)pt1FilterApply4(&pitchToThrFilterState, pitch, getPitchToThrottleSmoothnessCutoffFreq(NAV_FW_BASE_PITCH_CUTOFF_FREQUENCY_HZ), US2S(deltaMicrosPitchToThrCorr)); + int16_t pitchToThrottle = currentBatteryProfile->nav.fw.pitch_to_throttle; + +#ifdef USE_FW_AUTOLAND + if (pitch < 0 && posControl.fwLandState.landState == FW_AUTOLAND_STATE_FINAL_APPROACH) { + pitchToThrottle *= navFwAutolandConfig()->finalApproachPitchToThrottleMod / 100.0f; + } +#endif + if (ABS(pitch - filteredPitch) > navConfig()->fw.pitch_to_throttle_thresh) { // Unfiltered throttle correction outside of pitch deadband - return DECIDEGREES_TO_DEGREES(pitch) * currentBatteryProfile->nav.fw.pitch_to_throttle; + return DECIDEGREES_TO_DEGREES(pitch) * pitchToThrottle; } else { // Filtered throttle correction inside of pitch deadband - return DECIDEGREES_TO_DEGREES(filteredPitch) * currentBatteryProfile->nav.fw.pitch_to_throttle; + return DECIDEGREES_TO_DEGREES(filteredPitch) * pitchToThrottle; } } @@ -620,16 +627,12 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat rcCommand[PITCH] = -pidAngleToRcCommand(pitchCorrection, pidProfile()->max_angle_inclination[FD_PITCH]); int16_t throttleCorrection = fixedWingPitchToThrottleCorrection(pitchCorrection, currentTimeUs); -#ifdef NAV_FIXED_WING_LANDING if (navStateFlags & NAV_CTL_LAND) { - // During LAND we do not allow to raise THROTTLE when nose is up to reduce speed + // During LAND we do not allow to raise THROTTLE when nose is up to reduce speed throttleCorrection = constrain(throttleCorrection, minThrottleCorrection, 0); } else { -#endif throttleCorrection = constrain(throttleCorrection, minThrottleCorrection, maxThrottleCorrection); -#ifdef NAV_FIXED_WING_LANDING } -#endif // Speed controller - only apply in POS mode when NOT NAV_CTL_LAND if ((navStateFlags & NAV_CTL_POS) && !(navStateFlags & NAV_CTL_LAND)) { @@ -640,7 +643,7 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat uint16_t correctedThrottleValue = constrain(currentBatteryProfile->nav.fw.cruise_throttle + throttleCorrection, currentBatteryProfile->nav.fw.min_throttle, currentBatteryProfile->nav.fw.max_throttle); // Manual throttle increase - if (navConfig()->fw.allow_manual_thr_increase && !FLIGHT_MODE(FAILSAFE_MODE)) { + if (navConfig()->fw.allow_manual_thr_increase && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_FW_AUTOLAND)) { if (rcCommand[THROTTLE] < PWM_RANGE_MIN + (PWM_RANGE_MAX - PWM_RANGE_MIN) * 0.95){ correctedThrottleValue += MAX(0, rcCommand[THROTTLE] - currentBatteryProfile->nav.fw.cruise_throttle); } else { @@ -654,12 +657,23 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat rcCommand[THROTTLE] = setDesiredThrottle(correctedThrottleValue, false); } -#ifdef NAV_FIXED_WING_LANDING - /* - * Then altitude is below landing slowdown min. altitude, enable final approach procedure - * TODO refactor conditions in this metod if logic is proven to be correct - */ - if (navStateFlags & NAV_CTL_LAND || STATE(LANDING_DETECTED)) { +#ifdef USE_FW_AUTOLAND + // Advanced autoland + if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE || STATE(LANDING_DETECTED)) { + // Set motor to min. throttle and stop it when MOTOR_STOP feature is enabled + ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); + + if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE) { + rcCommand[PITCH] = pidAngleToRcCommand(-DEGREES_TO_DECIDEGREES(navFwAutolandConfig()->glidePitch), pidProfile()->max_angle_inclination[FD_PITCH]); + } + + if (posControl.navState == NAV_STATE_FW_LANDING_FLARE) { + rcCommand[PITCH] = pidAngleToRcCommand(-DEGREES_TO_DECIDEGREES(navFwAutolandConfig()->flarePitch), pidProfile()->max_angle_inclination[FD_PITCH]); + } + } +#endif + // "Traditional" landing as fallback option + if (navStateFlags & NAV_CTL_LAND) { int32_t finalAltitude = navConfig()->general.land_slowdown_minalt + posControl.rthState.homeTmpWaypoint.z; if ((posControl.flags.estAltStatus >= EST_USABLE && navGetCurrentActualPositionAndVelocity()->pos.z <= finalAltitude) || @@ -675,7 +689,6 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat rcCommand[PITCH] = pidAngleToRcCommand(DEGREES_TO_DECIDEGREES(navConfig()->fw.land_dive_angle), pidProfile()->max_angle_inclination[FD_PITCH]); } } -#endif } bool isFixedWingAutoThrottleManuallyIncreased(void) @@ -695,7 +708,7 @@ bool isFixedWingFlying(void) bool velCondition = posControl.actualState.velXY > 250.0f || airspeed > 250.0f; bool launchCondition = isNavLaunchEnabled() && fixedWingLaunchStatus() == FW_LAUNCH_FLYING; - return (isImuHeadingValid() && throttleCondition && velCondition) || launchCondition; + return (isGPSHeadingValid() && throttleCondition && velCondition) || launchCondition; } /*----------------------------------------------------------- @@ -709,6 +722,7 @@ bool isFixedWingLandingDetected(void) // Basic condition to start looking for landing bool startCondition = (navGetCurrentStateFlags() & (NAV_CTL_LAND | NAV_CTL_EMERG)) || FLIGHT_MODE(FAILSAFE_MODE) + || FLIGHT_MODE(NAV_FW_AUTOLAND) || (!navigationIsControllingThrottle() && throttleStickIsLow()); if (!startCondition || posControl.flags.resetLandingDetector) { diff --git a/src/main/navigation/navigation_fw_launch.c b/src/main/navigation/navigation_fw_launch.c index fe0af4d55a8..5708e5dcaac 100644 --- a/src/main/navigation/navigation_fw_launch.c +++ b/src/main/navigation/navigation_fw_launch.c @@ -251,7 +251,7 @@ static inline bool isLaunchMaxAltitudeReached(void) static inline bool areSticksMoved(timeMs_t initialTime, timeUs_t currentTimeUs) { return (initialTime + currentStateElapsedMs(currentTimeUs)) >= navConfig()->fw.launch_min_time && - isRollPitchStickDeflected(navConfig()->fw.launch_abort_deadband); + isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband); } static inline bool isProbablyNotFlying(void) @@ -420,7 +420,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IN_PROGRESS(timeUs_t if (throttleStickIsLow()) { fwLaunch.currentStateTimeUs = currentTimeUs; fwLaunch.pitchAngle = 0; - if (isRollPitchStickDeflected(navConfig()->fw.launch_abort_deadband)) { + if (isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { return FW_LAUNCH_EVENT_ABORT; } } else { @@ -454,7 +454,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t curr const timeMs_t elapsedTimeMs = currentStateElapsedMs(currentTimeUs); const timeMs_t endTimeMs = navConfig()->fw.launch_end_time; - if (elapsedTimeMs > endTimeMs || isRollPitchStickDeflected(navConfig()->fw.launch_abort_deadband)) { + if (elapsedTimeMs > endTimeMs || isRollPitchStickDeflected(navConfig()->fw.launch_land_abort_deadband)) { return FW_LAUNCH_EVENT_SUCCESS; // End launch go to FW_LAUNCH_STATE_FLYING state } else { diff --git a/src/main/navigation/navigation_multicopter.c b/src/main/navigation/navigation_multicopter.c index 17a1307503a..9baa569a60c 100644 --- a/src/main/navigation/navigation_multicopter.c +++ b/src/main/navigation/navigation_multicopter.c @@ -218,13 +218,12 @@ void resetMulticopterAltitudeController(void) pt1FilterReset(&posControl.pids.vel[Z].dterm_filter_state, 0.0f); if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding()) { - const float maxSpeed = getActiveSpeed(); - nav_speed_up = maxSpeed; - nav_accel_z = maxSpeed; + nav_speed_up = navConfig()->general.max_auto_climb_rate; + nav_accel_z = navConfig()->general.max_auto_climb_rate; nav_speed_down = navConfig()->general.max_auto_climb_rate; } else { - nav_speed_up = navConfig()->general.max_manual_speed; - nav_accel_z = navConfig()->general.max_manual_speed; + nav_speed_up = navConfig()->general.max_manual_climb_rate; + nav_accel_z = navConfig()->general.max_manual_climb_rate; nav_speed_down = navConfig()->general.max_manual_climb_rate; } diff --git a/src/main/navigation/navigation_pos_estimator.c b/src/main/navigation/navigation_pos_estimator.c index 5c314bfddda..f66c641928b 100755 --- a/src/main/navigation/navigation_pos_estimator.c +++ b/src/main/navigation/navigation_pos_estimator.c @@ -54,6 +54,7 @@ #include "sensors/opflow.h" navigationPosEstimator_t posEstimator; +static float initialBaroAltitudeOffset = 0.0f; PG_REGISTER_WITH_RESET_TEMPLATE(positionEstimationConfig_t, positionEstimationConfig, PG_POSITION_ESTIMATION_CONFIG, 5); @@ -69,8 +70,6 @@ PG_RESET_TEMPLATE(positionEstimationConfig_t, positionEstimationConfig, .max_surface_altitude = SETTING_INAV_MAX_SURFACE_ALTITUDE_DEFAULT, - .w_xyz_acc_p = SETTING_INAV_W_XYZ_ACC_P_DEFAULT, - .w_z_baro_p = SETTING_INAV_W_Z_BARO_P_DEFAULT, .w_z_surface_p = SETTING_INAV_W_Z_SURFACE_P_DEFAULT, @@ -110,6 +109,25 @@ static bool updateTimer(navigationTimer_t * tim, timeUs_t interval, timeUs_t cur static bool shouldResetReferenceAltitude(void) { + /* Reference altitudes reset constantly when disarmed. + * On arming ref altitudes saved as backup in case of emerg in flight rearm + * If emerg in flight rearm active ref altitudes reset to backup values to avoid unwanted altitude reset */ + + static float backupInitialBaroAltitudeOffset = 0.0f; + static int32_t backupGpsOriginAltitude = 0; + static bool emergRearmResetCheck = false; + + if (ARMING_FLAG(ARMED) && emergRearmResetCheck) { + if (STATE(IN_FLIGHT_EMERG_REARM)) { + initialBaroAltitudeOffset = backupInitialBaroAltitudeOffset; + posControl.gpsOrigin.alt = backupGpsOriginAltitude; + } else { + backupInitialBaroAltitudeOffset = initialBaroAltitudeOffset; + backupGpsOriginAltitude = posControl.gpsOrigin.alt; + } + } + emergRearmResetCheck = !ARMING_FLAG(ARMED); + switch ((nav_reset_type_e)positionEstimationConfig()->reset_altitude_type) { case NAV_RESET_NEVER: return false; @@ -305,7 +323,6 @@ void onNewGPSData(void) */ void updatePositionEstimator_BaroTopic(timeUs_t currentTimeUs) { - static float initialBaroAltitudeOffset = 0.0f; float newBaroAlt = baroCalculateAltitude(); /* If we are required - keep altitude at zero */ @@ -370,28 +387,30 @@ static bool gravityCalibrationComplete(void) return zeroCalibrationIsCompleteS(&posEstimator.imu.gravityCalibration); } - +#define ACC_VIB_FACTOR_S 1.0f +#define ACC_VIB_FACTOR_E 3.0f static void updateIMUEstimationWeight(const float dt) { - bool isAccClipped = accIsClipped(); - - // If accelerometer measurement is clipped - drop the acc weight to zero + static float acc_clip_factor = 1.0f; + // If accelerometer measurement is clipped - drop the acc weight to 0.3 // and gradually restore weight back to 1.0 over time - if (isAccClipped) { - posEstimator.imu.accWeightFactor = 0.0f; + if (accIsClipped()) { + acc_clip_factor = 0.5f; } else { const float relAlpha = dt / (dt + INAV_ACC_CLIPPING_RC_CONSTANT); - posEstimator.imu.accWeightFactor = posEstimator.imu.accWeightFactor * (1.0f - relAlpha) + 1.0f * relAlpha; + acc_clip_factor = acc_clip_factor * (1.0f - relAlpha) + 1.0f * relAlpha; } - + // Update accelerometer weight based on vibration levels and clipping + float acc_vibration_factor = scaleRangef(constrainf(accGetVibrationLevel(),ACC_VIB_FACTOR_S,ACC_VIB_FACTOR_E),ACC_VIB_FACTOR_S,ACC_VIB_FACTOR_E,1.0f,0.3f); // g/s + posEstimator.imu.accWeightFactor = acc_vibration_factor * acc_clip_factor; // DEBUG_VIBE[0-3] are used in IMU DEBUG_SET(DEBUG_VIBE, 4, posEstimator.imu.accWeightFactor * 1000); } float navGetAccelerometerWeight(void) { - const float accWeightScaled = posEstimator.imu.accWeightFactor * positionEstimationConfig()->w_xyz_acc_p; + const float accWeightScaled = posEstimator.imu.accWeightFactor; DEBUG_SET(DEBUG_VIBE, 5, accWeightScaled * 1000); return accWeightScaled; @@ -534,13 +553,12 @@ static uint32_t calculateCurrentValidityFlags(timeUs_t currentTimeUs) static void estimationPredict(estimationContext_t * ctx) { - const float accWeight = navGetAccelerometerWeight(); /* Prediction step: Z-axis */ if ((ctx->newFlags & EST_Z_VALID)) { posEstimator.est.pos.z += posEstimator.est.vel.z * ctx->dt; - posEstimator.est.pos.z += posEstimator.imu.accelNEU.z * sq(ctx->dt) / 2.0f * accWeight; - posEstimator.est.vel.z += posEstimator.imu.accelNEU.z * ctx->dt * sq(accWeight); + posEstimator.est.pos.z += posEstimator.imu.accelNEU.z * sq(ctx->dt) / 2.0f; + posEstimator.est.vel.z += posEstimator.imu.accelNEU.z * ctx->dt; } /* Prediction step: XY-axis */ @@ -551,10 +569,10 @@ static void estimationPredict(estimationContext_t * ctx) // If heading is valid, accelNEU is valid as well. Account for acceleration if (navIsHeadingUsable() && navIsAccelerationUsable()) { - posEstimator.est.pos.x += posEstimator.imu.accelNEU.x * sq(ctx->dt) / 2.0f * accWeight; - posEstimator.est.pos.y += posEstimator.imu.accelNEU.y * sq(ctx->dt) / 2.0f * accWeight; - posEstimator.est.vel.x += posEstimator.imu.accelNEU.x * ctx->dt * sq(accWeight); - posEstimator.est.vel.y += posEstimator.imu.accelNEU.y * ctx->dt * sq(accWeight); + posEstimator.est.pos.x += posEstimator.imu.accelNEU.x * sq(ctx->dt) / 2.0f; + posEstimator.est.pos.y += posEstimator.imu.accelNEU.y * sq(ctx->dt) / 2.0f; + posEstimator.est.vel.x += posEstimator.imu.accelNEU.x * ctx->dt; + posEstimator.est.vel.y += posEstimator.imu.accelNEU.y * ctx->dt; } } } @@ -570,7 +588,16 @@ static bool estimationCalculateCorrection_Z(estimationContext_t * ctx) DEBUG_SET(DEBUG_ALTITUDE, 5, posEstimator.gps.vel.z); // GPS vertical speed DEBUG_SET(DEBUG_ALTITUDE, 7, accGetClipCount()); // Clip count - if (ctx->newFlags & EST_BARO_VALID) { + bool correctOK = false; + + //ignore baro if difference is too big, baro is probably wrong + const float gpsBaroResidual = ctx->newFlags & EST_GPS_Z_VALID ? fabsf(posEstimator.gps.pos.z - posEstimator.baro.alt) : 0.0f; + //fade out the baro to prevent sudden jump + const float start_epv = positionEstimationConfig()->max_eph_epv; + const float end_epv = positionEstimationConfig()->max_eph_epv * 2.0f; + const float wBaro = scaleRangef(constrainf(gpsBaroResidual, start_epv, end_epv), start_epv, end_epv, 1.0f, 0.0f); + //use both baro and gps + if ((ctx->newFlags & EST_BARO_VALID) && (!positionEstimationConfig()->use_gps_no_baro) && (wBaro > 0.01f)) { timeUs_t currentTimeUs = micros(); if (!ARMING_FLAG(ARMED)) { @@ -580,44 +607,33 @@ static bool estimationCalculateCorrection_Z(estimationContext_t * ctx) } else { if (posEstimator.est.vel.z > 15) { - if (currentTimeUs > posEstimator.state.baroGroundTimeout) { - posEstimator.state.isBaroGroundValid = false; - } + posEstimator.state.isBaroGroundValid = currentTimeUs > posEstimator.state.baroGroundTimeout ? false: true; } else { posEstimator.state.baroGroundTimeout = currentTimeUs + 250000; // 0.25 sec } } - // We might be experiencing air cushion effect - use sonar or baro groung altitude to detect it + // We might be experiencing air cushion effect during takeoff - use sonar or baro ground altitude to detect it bool isAirCushionEffectDetected = ARMING_FLAG(ARMED) && (((ctx->newFlags & EST_SURFACE_VALID) && posEstimator.surface.alt < 20.0f && posEstimator.state.isBaroGroundValid) || ((ctx->newFlags & EST_BARO_VALID) && posEstimator.state.isBaroGroundValid && posEstimator.baro.alt < posEstimator.state.baroGroundAlt)); // Altitude const float baroAltResidual = (isAirCushionEffectDetected ? posEstimator.state.baroGroundAlt : posEstimator.baro.alt) - posEstimator.est.pos.z; - ctx->estPosCorr.z += baroAltResidual * positionEstimationConfig()->w_z_baro_p * ctx->dt; - ctx->estVelCorr.z += baroAltResidual * sq(positionEstimationConfig()->w_z_baro_p) * ctx->dt; - - // If GPS is available - also use GPS climb rate - if (ctx->newFlags & EST_GPS_Z_VALID) { - // Trust GPS velocity only if residual/error is less than 2.5 m/s, scale weight according to gaussian distribution - const float gpsRocResidual = posEstimator.gps.vel.z - posEstimator.est.vel.z; - const float gpsRocScaler = bellCurve(gpsRocResidual, 250.0f); - ctx->estVelCorr.z += gpsRocResidual * positionEstimationConfig()->w_z_gps_v * gpsRocScaler * ctx->dt; - } + ctx->estPosCorr.z += wBaro * baroAltResidual * positionEstimationConfig()->w_z_baro_p * ctx->dt; + ctx->estVelCorr.z += wBaro * baroAltResidual * sq(positionEstimationConfig()->w_z_baro_p) * ctx->dt; ctx->newEPV = updateEPE(posEstimator.est.epv, ctx->dt, posEstimator.baro.epv, positionEstimationConfig()->w_z_baro_p); // Accelerometer bias if (!isAirCushionEffectDetected) { - ctx->accBiasCorr.z -= baroAltResidual * sq(positionEstimationConfig()->w_z_baro_p); + ctx->accBiasCorr.z -= wBaro * baroAltResidual * sq(positionEstimationConfig()->w_z_baro_p); } - return true; + correctOK = true; } - else if ((STATE(FIXED_WING_LEGACY) || positionEstimationConfig()->use_gps_no_baro) && (ctx->newFlags & EST_GPS_Z_VALID)) { - // If baro is not available - use GPS Z for correction on a plane + if (ctx->newFlags & EST_GPS_Z_VALID) { // Reset current estimate to GPS altitude if estimate not valid if (!(ctx->newFlags & EST_Z_VALID)) { ctx->estPosCorr.z += posEstimator.gps.pos.z - posEstimator.est.pos.z; @@ -627,20 +643,21 @@ static bool estimationCalculateCorrection_Z(estimationContext_t * ctx) else { // Altitude const float gpsAltResudual = posEstimator.gps.pos.z - posEstimator.est.pos.z; + const float gpsVelZResudual = posEstimator.gps.vel.z - posEstimator.est.vel.z; ctx->estPosCorr.z += gpsAltResudual * positionEstimationConfig()->w_z_gps_p * ctx->dt; ctx->estVelCorr.z += gpsAltResudual * sq(positionEstimationConfig()->w_z_gps_p) * ctx->dt; - ctx->estVelCorr.z += (posEstimator.gps.vel.z - posEstimator.est.vel.z) * positionEstimationConfig()->w_z_gps_v * ctx->dt; + ctx->estVelCorr.z += gpsVelZResudual * positionEstimationConfig()->w_z_gps_v * ctx->dt; ctx->newEPV = updateEPE(posEstimator.est.epv, ctx->dt, MAX(posEstimator.gps.epv, gpsAltResudual), positionEstimationConfig()->w_z_gps_p); // Accelerometer bias ctx->accBiasCorr.z -= gpsAltResudual * sq(positionEstimationConfig()->w_z_gps_p); } - return true; + correctOK = true; } - return false; + return correctOK; } static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx) @@ -695,15 +712,10 @@ static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx) static void estimationCalculateGroundCourse(timeUs_t currentTimeUs) { + UNUSED(currentTimeUs); if (STATE(GPS_FIX) && navIsHeadingUsable()) { - static timeUs_t lastUpdateTimeUs = 0; - - if (currentTimeUs - lastUpdateTimeUs >= HZ2US(INAV_COG_UPDATE_RATE_HZ)) { // limit update rate - const float dt = US2S(currentTimeUs - lastUpdateTimeUs); - uint32_t groundCourse = wrap_36000(RADIANS_TO_CENTIDEGREES(atan2_approx(posEstimator.est.vel.y * dt, posEstimator.est.vel.x * dt))); - posEstimator.est.cog = CENTIDEGREES_TO_DECIDEGREES(groundCourse); - lastUpdateTimeUs = currentTimeUs; - } + uint32_t groundCourse = wrap_36000(RADIANS_TO_CENTIDEGREES(atan2_approx(posEstimator.est.vel.y, posEstimator.est.vel.x))); + posEstimator.est.cog = CENTIDEGREES_TO_DECIDEGREES(groundCourse); } } @@ -760,7 +772,10 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs) if (!estZCorrectOk || ctx.newEPV > positionEstimationConfig()->max_eph_epv) { ctx.estVelCorr.z = (0.0f - posEstimator.est.vel.z) * positionEstimationConfig()->w_z_res_v * ctx.dt; } - + // Boost the corrections based on accWeight + const float accWeight = navGetAccelerometerWeight(); + vectorScale(&ctx.estPosCorr, &ctx.estPosCorr, 1.0f/accWeight); + vectorScale(&ctx.estVelCorr, &ctx.estVelCorr, 1.0f/accWeight); // Apply corrections vectorAdd(&posEstimator.est.pos, &posEstimator.est.pos, &ctx.estPosCorr); vectorAdd(&posEstimator.est.vel, &posEstimator.est.vel, &ctx.estVelCorr); @@ -798,13 +813,14 @@ static void publishEstimatedTopic(timeUs_t currentTimeUs) { static navigationTimer_t posPublishTimer; - /* IMU operates in decidegrees while INAV operates in deg*100 - * Use course over ground when GPS heading valid */ - int16_t cogValue = isGPSHeadingValid() ? posEstimator.est.cog : attitude.values.yaw; - updateActualHeading(navIsHeadingUsable(), DECIDEGREES_TO_CENTIDEGREES(attitude.values.yaw), DECIDEGREES_TO_CENTIDEGREES(cogValue)); - /* Position and velocity are published with INAV_POSITION_PUBLISH_RATE_HZ */ if (updateTimer(&posPublishTimer, HZ2US(INAV_POSITION_PUBLISH_RATE_HZ), currentTimeUs)) { + /* Publish heading update */ + /* IMU operates in decidegrees while INAV operates in deg*100 + * Use course over ground when GPS heading valid */ + int16_t cogValue = isGPSHeadingValid() ? posEstimator.est.cog : attitude.values.yaw; + updateActualHeading(navIsHeadingUsable(), DECIDEGREES_TO_CENTIDEGREES(attitude.values.yaw), DECIDEGREES_TO_CENTIDEGREES(cogValue)); + /* Publish position update */ if (posEstimator.est.eph < positionEstimationConfig()->max_eph_epv) { // FIXME!!!!! diff --git a/src/main/navigation/navigation_pos_estimator_private.h b/src/main/navigation/navigation_pos_estimator_private.h index 40129f844b0..0b19dbb0023 100644 --- a/src/main/navigation/navigation_pos_estimator_private.h +++ b/src/main/navigation/navigation_pos_estimator_private.h @@ -39,7 +39,6 @@ #define INAV_POSITION_PUBLISH_RATE_HZ 50 // Publish position updates at this rate #define INAV_PITOT_UPDATE_RATE 10 -#define INAV_COG_UPDATE_RATE_HZ 20 // ground course update rate #define INAV_GPS_TIMEOUT_MS 1500 // GPS timeout #define INAV_BARO_TIMEOUT_MS 200 // Baro timeout diff --git a/src/main/navigation/navigation_private.h b/src/main/navigation/navigation_private.h index c408f109c9b..d716c58c496 100644 --- a/src/main/navigation/navigation_private.h +++ b/src/main/navigation/navigation_private.h @@ -158,6 +158,7 @@ typedef enum { NAV_FSM_EVENT_SWITCH_TO_CRUISE, NAV_FSM_EVENT_SWITCH_TO_COURSE_ADJ, NAV_FSM_EVENT_SWITCH_TO_MIXERAT, + NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING, NAV_FSM_EVENT_STATE_SPECIFIC_1, // State-specific event NAV_FSM_EVENT_STATE_SPECIFIC_2, // State-specific event @@ -173,6 +174,7 @@ typedef enum { NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME = NAV_FSM_EVENT_STATE_SPECIFIC_4, NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_RTH_TRACKBACK = NAV_FSM_EVENT_STATE_SPECIFIC_5, NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_RTH_INITIALIZE = NAV_FSM_EVENT_STATE_SPECIFIC_6, + NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT = NAV_FSM_EVENT_STATE_SPECIFIC_6, NAV_FSM_EVENT_COUNT, } navigationFSMEvent_t; @@ -233,6 +235,12 @@ typedef enum { NAV_PERSISTENT_ID_MIXERAT_INITIALIZE = 39, NAV_PERSISTENT_ID_MIXERAT_IN_PROGRESS = 40, NAV_PERSISTENT_ID_MIXERAT_ABORT = 41, + NAV_PERSISTENT_ID_FW_LANDING_CLIMB_TO_LOITER = 42, + NAV_PERSISTENT_ID_FW_LANDING_LOITER = 43, + NAV_PERSISTENT_ID_FW_LANDING_APPROACH = 44, + NAV_PERSISTENT_ID_FW_LANDING_GLIDE = 45, + NAV_PERSISTENT_ID_FW_LANDING_FLARE = 46, + NAV_PERSISTENT_ID_FW_LANDING_ABORT = 47, } navigationPersistentId_e; typedef enum { @@ -279,6 +287,13 @@ typedef enum { NAV_STATE_CRUISE_INITIALIZE, NAV_STATE_CRUISE_IN_PROGRESS, NAV_STATE_CRUISE_ADJUSTING, + + NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, + NAV_STATE_FW_LANDING_LOITER, + NAV_STATE_FW_LANDING_APPROACH, + NAV_STATE_FW_LANDING_GLIDE, + NAV_STATE_FW_LANDING_FLARE, + NAV_STATE_FW_LANDING_ABORT, NAV_STATE_MIXERAT_INITIALIZE, NAV_STATE_MIXERAT_IN_PROGRESS, @@ -350,8 +365,33 @@ typedef struct { float rthInitialDistance; // Distance when starting flight home fpVector3_t homeTmpWaypoint; // Temporary storage for home target fpVector3_t originalHomePosition; // the original rth home - save it, since it could be replaced by safehome or HOME_RESET + bool rthLinearDescentActive; // Activation status of Linear Descent } rthState_t; +#ifdef USE_FW_AUTOLAND +typedef enum { + FW_AUTOLAND_WP_TURN, + FW_AUTOLAND_WP_FINAL_APPROACH, + FW_AUTOLAND_WP_LAND, + FW_AUTOLAND_WP_COUNT, +} fwAutolandWaypoint_t; + +typedef struct { + timeUs_t loiterStartTime; + fpVector3_t landWaypoints[FW_AUTOLAND_WP_COUNT]; + fpVector3_t landPos; + int32_t landPosHeading; + int32_t landingDirection; + int32_t landAproachAltAgl; + int32_t landAltAgl; + uint8_t approachSettingIdx; + fwAutolandWaypoint_t landCurrentWp; + bool landAborted; + bool landWp; + fwAutolandState_t landState; +} fwLandState_t; +#endif + typedef enum { RTH_HOME_ENROUTE_INITIAL, // Initial position for RTH approach RTH_HOME_ENROUTE_PROPORTIONAL, // Prorpotional position for RTH approach @@ -394,6 +434,7 @@ typedef struct { rthState_t rthState; uint32_t homeDistance; // cm int32_t homeDirection; // deg*100 + timeMs_t landingDelay; /* Safehome parameters */ safehomeState_t safehomeState; @@ -432,6 +473,11 @@ typedef struct { int8_t activeRthTBPointIndex; int8_t rthTBWrapAroundCounter; // stores trackpoint array overwrite index position +#ifdef USE_FW_AUTOLAND + /* Fixedwing autoland */ + fwLandState_t fwLandState; +#endif + /* Internals & statistics */ int16_t rcAdjustment[4]; float totalTripDistance; diff --git a/src/main/programming/logic_condition.c b/src/main/programming/logic_condition.c index d3b45453c91..2b10896b718 100644 --- a/src/main/programming/logic_condition.c +++ b/src/main/programming/logic_condition.c @@ -56,6 +56,7 @@ #include "io/vtx.h" #include "drivers/vtx_common.h" +#include "drivers/light_ws2811strip.h" PG_REGISTER_ARRAY_WITH_RESET_FN(logicCondition_t, MAX_LOGIC_CONDITIONS, logicConditions, PG_LOGIC_CONDITIONS, 4); @@ -96,7 +97,7 @@ static int logicConditionCompute( int temporaryValue; #if defined(USE_VTX_CONTROL) vtxDeviceCapability_t vtxDeviceCapability; -#endif +#endif switch (operation) { @@ -153,7 +154,7 @@ static int logicConditionCompute( case LOGIC_CONDITION_NOR: return !(operandA || operandB); - break; + break; case LOGIC_CONDITION_NOT: return !operandA; @@ -169,7 +170,7 @@ static int logicConditionCompute( return false; } - //When both operands are not met, keep current value + //When both operands are not met, keep current value return currentValue; break; @@ -237,7 +238,7 @@ static int logicConditionCompute( gvSet(operandA, operandB); return operandB; break; - + case LOGIC_CONDITION_GVAR_INC: temporaryValue = gvGet(operandA) + operandB; gvSet(operandA, temporaryValue); @@ -269,7 +270,7 @@ static int logicConditionCompute( return operandA; } break; - + case LOGIC_CONDITION_OVERRIDE_ARMING_SAFETY: LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_ARMING_SAFETY); return true; @@ -287,10 +288,10 @@ static int logicConditionCompute( break; case LOGIC_CONDITION_SET_VTX_POWER_LEVEL: -#if defined(USE_VTX_CONTROL) +#if defined(USE_VTX_CONTROL) #if(defined(USE_VTX_SMARTAUDIO) || defined(USE_VTX_TRAMP)) if ( - logicConditionValuesByType[LOGIC_CONDITION_SET_VTX_POWER_LEVEL] != operandA && + logicConditionValuesByType[LOGIC_CONDITION_SET_VTX_POWER_LEVEL] != operandA && vtxCommonGetDeviceCapability(vtxCommonDevice(), &vtxDeviceCapability) ) { logicConditionValuesByType[LOGIC_CONDITION_SET_VTX_POWER_LEVEL] = constrain(operandA, VTX_SETTINGS_MIN_POWER, vtxDeviceCapability.powerCount); @@ -338,18 +339,18 @@ static int logicConditionCompute( LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_INVERT_PITCH); return true; break; - + case LOGIC_CONDITION_INVERT_YAW: LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_INVERT_YAW); return true; break; - + case LOGIC_CONDITION_OVERRIDE_THROTTLE: logicConditionValuesByType[LOGIC_CONDITION_OVERRIDE_THROTTLE] = operandA; LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_THROTTLE); return operandA; break; - + case LOGIC_CONDITION_SET_OSD_LAYOUT: logicConditionValuesByType[LOGIC_CONDITION_SET_OSD_LAYOUT] = operandA; LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_OSD_LAYOUT); @@ -365,18 +366,18 @@ static int logicConditionCompute( case LOGIC_CONDITION_SIN: temporaryValue = (operandB == 0) ? 500 : operandB; - return sin_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; + return sin_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; break; - + case LOGIC_CONDITION_COS: temporaryValue = (operandB == 0) ? 500 : operandB; - return cos_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; + return cos_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; break; break; - + case LOGIC_CONDITION_TAN: temporaryValue = (operandB == 0) ? 500 : operandB; - return tan_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; + return tan_approx(DEGREES_TO_RADIANS(operandA)) * temporaryValue; break; case LOGIC_CONDITION_MIN: @@ -386,11 +387,11 @@ static int logicConditionCompute( case LOGIC_CONDITION_MAX: return (operandA > operandB) ? operandA : operandB; break; - + case LOGIC_CONDITION_MAP_INPUT: return scaleRange(constrain(operandA, 0, operandB), 0, operandB, 0, 1000); break; - + case LOGIC_CONDITION_MAP_OUTPUT: return scaleRange(constrain(operandA, 0, 1000), 0, 1000, 0, operandB); break; @@ -473,11 +474,22 @@ static int logicConditionCompute( } else { return false; } - break; - + break; + +#ifdef USE_LED_STRIP + case LOGIC_CONDITION_LED_PIN_PWM: + + if (operandA >=0 && operandA <= 100) { + ledPinStartPWM((uint8_t)operandA); + } else { + ledPinStopPWM(); + } + return operandA; + break; +#endif default: return false; - break; + break; } } @@ -486,7 +498,7 @@ void logicConditionProcess(uint8_t i) { const int activatorValue = logicConditionGetValue(logicConditions(i)->activatorId); if (logicConditions(i)->enabled && activatorValue && !cliMode) { - + /* * Process condition only when latch flag is not set * Latched LCs can only go from OFF to ON, not the other way @@ -495,13 +507,13 @@ void logicConditionProcess(uint8_t i) { const int operandAValue = logicConditionGetOperandValue(logicConditions(i)->operandA.type, logicConditions(i)->operandA.value); const int operandBValue = logicConditionGetOperandValue(logicConditions(i)->operandB.type, logicConditions(i)->operandB.value); const int newValue = logicConditionCompute( - logicConditionStates[i].value, - logicConditions(i)->operation, - operandAValue, + logicConditionStates[i].value, + logicConditions(i)->operation, + operandAValue, operandBValue, i ); - + logicConditionStates[i].value = newValue; /* @@ -576,7 +588,7 @@ static int logicConditionGetWaypointOperandValue(int operand) { return distance; } break; - + case LOGIC_CONDITION_OPERAND_WAYPOINTS_USER1_ACTION: return (NAV_Status.activeWpIndex > 0) ? ((posControl.waypointList[NAV_Status.activeWpIndex-1].p3 & NAV_WP_USER1) == NAV_WP_USER1) : 0; break; @@ -622,11 +634,11 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_ARM_TIMER: // in s return constrain((uint32_t)getFlightTime(), 0, INT16_MAX); break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_HOME_DISTANCE: //in m return constrain(GPS_distanceToHome, 0, INT16_MAX); break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_TRIP_DISTANCE: //in m return constrain(getTotalTravelDistance() / 100, 0, INT16_MAX); break; @@ -634,7 +646,7 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_RSSI: return constrain(getRSSI() * 100 / RSSI_MAX_VALUE, 0, 99); break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_VBAT: // V / 100 return getBatteryVoltage(); break; @@ -650,7 +662,7 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_CURRENT: // Amp / 100 return getAmperage(); break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_MAH_DRAWN: // mAh return getMAhDrawn(); break; @@ -662,7 +674,7 @@ static int logicConditionGetFlightOperandValue(int operand) { return gpsSol.numSat; } break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_GPS_VALID: // 0/1 return STATE(GPS_FIX) ? 1 : 0; break; @@ -704,21 +716,25 @@ static int logicConditionGetFlightOperandValue(int operand) { return constrain(attitude.values.pitch / 10, -180, 180); break; + case LOGIC_CONDITION_OPERAND_FLIGHT_ATTITUDE_YAW: // deg + return constrain(attitude.values.yaw / 10, 0, 360); + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_IS_ARMED: // 0/1 return ARMING_FLAG(ARMED) ? 1 : 0; break; case LOGIC_CONDITION_OPERAND_FLIGHT_IS_AUTOLAUNCH: // 0/1 return (navGetCurrentStateFlags() & NAV_CTL_LAUNCH) ? 1 : 0; - break; - + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_IS_ALTITUDE_CONTROL: // 0/1 return (navGetCurrentStateFlags() & NAV_CTL_ALT) ? 1 : 0; - break; + break; case LOGIC_CONDITION_OPERAND_FLIGHT_IS_POSITION_CONTROL: // 0/1 return (navGetCurrentStateFlags() & NAV_CTL_POS) ? 1 : 0; - break; + break; case LOGIC_CONDITION_OPERAND_FLIGHT_IS_EMERGENCY_LANDING: // 0/1 return (navGetCurrentStateFlags() & NAV_CTL_EMERG) ? 1 : 0; @@ -726,25 +742,30 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_IS_RTH: // 0/1 return (navGetCurrentStateFlags() & NAV_AUTO_RTH) ? 1 : 0; - break; + break; case LOGIC_CONDITION_OPERAND_FLIGHT_IS_LANDING: // 0/1 - return (navGetCurrentStateFlags() & NAV_CTL_LAND) ? 1 : 0; +#ifdef USE_FW_AUTOLAND + return ((navGetCurrentStateFlags() & NAV_CTL_LAND) || FLIGHT_MODE(NAV_FW_AUTOLAND)) ? 1 : 0; +#else + return ((navGetCurrentStateFlags() & NAV_CTL_LAND)) ? 1 : 0; +#endif + break; case LOGIC_CONDITION_OPERAND_FLIGHT_IS_FAILSAFE: // 0/1 return (failsafePhase() != FAILSAFE_IDLE) ? 1 : 0; break; - - case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_YAW: // + + case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_YAW: // return axisPID[YAW]; break; - - case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_ROLL: // + + case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_ROLL: // return axisPID[ROLL]; break; - - case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_PITCH: // + + case LOGIC_CONDITION_OPERAND_FLIGHT_STABILIZED_PITCH: // return axisPID[PITCH]; break; @@ -771,7 +792,7 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_PROFILE: // int return getConfigProfile() + 1; break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_MIXER_PROFILE: // int return currentMixerProfileIndex + 1; break; @@ -786,15 +807,19 @@ static int logicConditionGetFlightOperandValue(int operand) { case LOGIC_CONDITION_OPERAND_FLIGHT_AGL_STATUS: return isEstimatedAglTrusted(); break; - + case LOGIC_CONDITION_OPERAND_FLIGHT_AGL: return getEstimatedAglPosition(); - break; - + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_RANGEFINDER_RAW: return rangefinderGetLatestRawAltitude(); - break; - + break; +#ifdef USE_FW_AUTOLAND + case LOGIC_CONDITION_OPERAND_FLIGHT_FW_LAND_STATE: + return posControl.fwLandState.landState; + break; +#endif default: return 0; break; @@ -845,13 +870,18 @@ static int logicConditionGetFlightModeOperandValue(int operand) { return (bool) FLIGHT_MODE(HORIZON_MODE); break; + case LOGIC_CONDITION_OPERAND_FLIGHT_MODE_ANGLEHOLD: + return (bool) FLIGHT_MODE(ANGLEHOLD_MODE); + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_MODE_AIR: return (bool) FLIGHT_MODE(AIRMODE_ACTIVE); break; case LOGIC_CONDITION_OPERAND_FLIGHT_MODE_ACRO: - return (((bool) FLIGHT_MODE(ANGLE_MODE) || (bool) FLIGHT_MODE(HORIZON_MODE) || (bool) FLIGHT_MODE(MANUAL_MODE) || (bool) FLIGHT_MODE(NAV_RTH_MODE) || - (bool) FLIGHT_MODE(NAV_POSHOLD_MODE) || (bool) FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || (bool) FLIGHT_MODE(NAV_WP_MODE)) == false); + return (((bool) FLIGHT_MODE(ANGLE_MODE) || (bool) FLIGHT_MODE(HORIZON_MODE) || (bool) FLIGHT_MODE(ANGLEHOLD_MODE) || + (bool) FLIGHT_MODE(MANUAL_MODE) || (bool) FLIGHT_MODE(NAV_RTH_MODE) || (bool) FLIGHT_MODE(NAV_POSHOLD_MODE) || + (bool) FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || (bool) FLIGHT_MODE(NAV_WP_MODE)) == false); break; case LOGIC_CONDITION_OPERAND_FLIGHT_MODE_USER1: @@ -889,7 +919,7 @@ int logicConditionGetOperandValue(logicOperandType_e type, int operand) { //Extract RC channel raw value if (operand >= 1 && operand <= MAX_SUPPORTED_RC_CHANNEL_COUNT) { retVal = rxGetChannelValue(operand - 1); - } + } break; case LOGIC_CONDITION_OPERAND_TYPE_FLIGHT: @@ -917,7 +947,7 @@ int logicConditionGetOperandValue(logicOperandType_e type, int operand) { retVal = programmingPidGetOutput(operand); } break; - + case LOGIC_CONDITION_OPERAND_TYPE_WAYPOINTS: retVal = logicConditionGetWaypointOperandValue(operand); break; @@ -931,7 +961,7 @@ int logicConditionGetOperandValue(logicOperandType_e type, int operand) { /* * conditionId == -1 is always evaluated as true - */ + */ int logicConditionGetValue(int8_t conditionId) { if (conditionId >= 0) { return logicConditionStates[conditionId].value; @@ -1013,7 +1043,7 @@ int16_t getRcChannelOverride(uint8_t channel, int16_t originalValue) { uint32_t getLoiterRadius(uint32_t loiterRadius) { #ifdef USE_PROGRAMMING_FRAMEWORK - if (LOGIC_CONDITION_GLOBAL_FLAG(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_LOITER_RADIUS) && + if (LOGIC_CONDITION_GLOBAL_FLAG(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_LOITER_RADIUS) && !(FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding())) { return constrain(logicConditionValuesByType[LOGIC_CONDITION_LOITER_OVERRIDE], loiterRadius, 100000); } else { diff --git a/src/main/programming/logic_condition.h b/src/main/programming/logic_condition.h index 941e47f8d0d..5d45e447566 100644 --- a/src/main/programming/logic_condition.h +++ b/src/main/programming/logic_condition.h @@ -81,7 +81,8 @@ typedef enum { LOGIC_CONDITION_TIMER = 49, LOGIC_CONDITION_DELTA = 50, LOGIC_CONDITION_APPROX_EQUAL = 51, - LOGIC_CONDITION_LAST = 52, + LOGIC_CONDITION_LED_PIN_PWM = 52, + LOGIC_CONDITION_LAST = 53, } logicOperation_e; typedef enum logicOperandType_s { @@ -135,8 +136,10 @@ typedef enum { LOGIC_CONDITION_OPERAND_FLIGHT_AGL_STATUS, //0,1,2 // 35 LOGIC_CONDITION_OPERAND_FLIGHT_AGL, //0,1,2 // 36 LOGIC_CONDITION_OPERAND_FLIGHT_RANGEFINDER_RAW, //int // 37 - LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_MIXER_PROFILE, //int // 39 - LOGIC_CONDITION_OPERAND_FLIGHT_MIXER_TRANSITION_ACTIVE, //0,1 // 40 + LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_MIXER_PROFILE, //int // 38 + LOGIC_CONDITION_OPERAND_FLIGHT_MIXER_TRANSITION_ACTIVE, //0,1 // 39 + LOGIC_CONDITION_OPERAND_FLIGHT_ATTITUDE_YAW, // deg // 40 + LOGIC_CONDITION_OPERAND_FLIGHT_FW_LAND_STATE, // 41 } logicFlightOperands_e; typedef enum { @@ -156,6 +159,7 @@ typedef enum { LOGIC_CONDITION_OPERAND_FLIGHT_MODE_USER4, // 13 LOGIC_CONDITION_OPERAND_FLIGHT_MODE_ACRO, // 14 LOGIC_CONDITION_OPERAND_FLIGHT_MODE_WAYPOINT_MISSION, // 15 + LOGIC_CONDITION_OPERAND_FLIGHT_MODE_ANGLEHOLD, // 16 } logicFlightModeOperands_e; typedef enum { diff --git a/src/main/rx/jetiexbus.c b/src/main/rx/jetiexbus.c index d9b009342e3..35564833994 100644 --- a/src/main/rx/jetiexbus.c +++ b/src/main/rx/jetiexbus.c @@ -63,7 +63,12 @@ #define JETIEXBUS_BAUDRATE 125000 // EX Bus 125000; EX Bus HS 250000 not supported #define JETIEXBUS_OPTIONS (SERIAL_STOPBITS_1 | SERIAL_PARITY_NO) #define JETIEXBUS_MIN_FRAME_GAP 1000 -#define JETIEXBUS_CHANNEL_COUNT 16 // most Jeti TX transmit 16 channels + +#ifdef USE_24CHANNELS +#define JETIEXBUS_CHANNEL_COUNT 24 +#else +#define JETIEXBUS_CHANNEL_COUNT 16 +#endif #define EXBUS_START_CHANNEL_FRAME (0x3E) @@ -153,6 +158,7 @@ static void jetiExBusDataReceive(uint16_t c, void *data) static timeUs_t jetiExBusTimeLast = 0; static uint8_t *jetiExBusFrame; + static uint8_t jetiExBusFrameMaxSize; const timeUs_t now = microsISR(); // Check if we shall reset frame position due to time @@ -169,11 +175,13 @@ static void jetiExBusDataReceive(uint16_t c, void *data) case EXBUS_START_CHANNEL_FRAME: jetiExBusFrameState = EXBUS_STATE_IN_PROGRESS; jetiExBusFrame = jetiExBusChannelFrame; + jetiExBusFrameMaxSize = EXBUS_MAX_CHANNEL_FRAME_SIZE; break; case EXBUS_START_REQUEST_FRAME: jetiExBusRequestState = EXBUS_STATE_IN_PROGRESS; jetiExBusFrame = jetiExBusRequestFrame; + jetiExBusFrameMaxSize = EXBUS_MAX_CHANNEL_FRAME_SIZE; break; default: @@ -181,6 +189,15 @@ static void jetiExBusDataReceive(uint16_t c, void *data) } } + if (jetiExBusFramePosition == jetiExBusFrameMaxSize) { + // frame overrun + jetiExBusFrameReset(); + jetiExBusFrameState = EXBUS_STATE_ZERO; + jetiExBusRequestState = EXBUS_STATE_ZERO; + + return; + } + // Store in frame copy jetiExBusFrame[jetiExBusFramePosition] = (uint8_t)c; jetiExBusFramePosition++; diff --git a/src/main/rx/rx.h b/src/main/rx/rx.h index 4d5e2b135f8..1aee04ec083 100644 --- a/src/main/rx/rx.h +++ b/src/main/rx/rx.h @@ -83,7 +83,11 @@ typedef enum { SERIALRX_FBUS, } rxSerialReceiverType_e; -#define MAX_SUPPORTED_RC_CHANNEL_COUNT 18 +#ifdef USE_24CHANNELS +#define MAX_SUPPORTED_RC_CHANNEL_COUNT 26 +#else +#define MAX_SUPPORTED_RC_CHANNEL_COUNT 18 +#endif #define NON_AUX_CHANNEL_COUNT 4 #define MAX_AUX_CHANNEL_COUNT (MAX_SUPPORTED_RC_CHANNEL_COUNT - NON_AUX_CHANNEL_COUNT) diff --git a/src/main/sensors/acceleration.c b/src/main/sensors/acceleration.c index f897d7e580a..695f49b00b2 100644 --- a/src/main/sensors/acceleration.c +++ b/src/main/sensors/acceleration.c @@ -576,6 +576,7 @@ void accUpdate(void) // calc difference from this sample and 5hz filtered value, square and filter at 2hz const float accDiff = acc.accADCf[axis] - accFloorFilt; acc.accVibeSq[axis] = pt1FilterApply(&accVibeFilter[axis], accDiff * accDiff); + acc.accVibe = fast_fsqrtf(acc.accVibeSq[X] + acc.accVibeSq[Y] + acc.accVibeSq[Z]); } // Filter acceleration @@ -612,7 +613,7 @@ void accGetVibrationLevels(fpVector3_t *accVibeLevels) float accGetVibrationLevel(void) { - return fast_fsqrtf(acc.accVibeSq[X] + acc.accVibeSq[Y] + acc.accVibeSq[Z]); + return acc.accVibe; } uint32_t accGetClipCount(void) diff --git a/src/main/sensors/acceleration.h b/src/main/sensors/acceleration.h index d81a83a9084..f3385edc6d5 100644 --- a/src/main/sensors/acceleration.h +++ b/src/main/sensors/acceleration.h @@ -27,7 +27,7 @@ #define GRAVITY_CMSS 980.665f #define GRAVITY_MSS 9.80665f -#define ACC_CLIPPING_THRESHOLD_G 7.9f +#define ACC_CLIPPING_THRESHOLD_G 15.9f #define ACC_VIBE_FLOOR_FILT_HZ 5.0f #define ACC_VIBE_FILT_HZ 2.0f @@ -58,6 +58,7 @@ typedef struct acc_s { uint32_t accTargetLooptime; float accADCf[XYZ_AXIS_COUNT]; // acceleration in g float accVibeSq[XYZ_AXIS_COUNT]; + float accVibe; uint32_t accClipCount; bool isClipped; acc_extremes_t extremes[XYZ_AXIS_COUNT]; diff --git a/src/main/sensors/battery.c b/src/main/sensors/battery.c index 78e52f75c2a..3745ed7a8ea 100644 --- a/src/main/sensors/battery.c +++ b/src/main/sensors/battery.c @@ -84,7 +84,7 @@ static bool batteryUseCapacityThresholds = false; static bool batteryFullWhenPluggedIn = false; static bool profileAutoswitchDisable = false; -static uint16_t vbat = 0; // battery voltage in 0.1V steps (filtered) +static uint16_t vbat = 0; // battery voltage in 0.01V steps (filtered) static uint16_t powerSupplyImpedance = 0; // calculated impedance in milliohm static uint16_t sagCompensatedVBat = 0; // calculated no load vbat static bool powerSupplyImpedanceIsValid = false; @@ -134,7 +134,6 @@ void pgResetFn_batteryProfiles(batteryProfile_t *instance) .failsafe_throttle = SETTING_FAILSAFE_THROTTLE_DEFAULT, // default throttle off. .nav = { - .mc = { .hover_throttle = SETTING_NAV_MC_HOVER_THR_DEFAULT, }, @@ -147,7 +146,6 @@ void pgResetFn_batteryProfiles(batteryProfile_t *instance) .launch_throttle = SETTING_NAV_FW_LAUNCH_THR_DEFAULT, .launch_idle_throttle = SETTING_NAV_FW_LAUNCH_IDLE_THR_DEFAULT, // Motor idle or MOTOR_STOP } - }, #if defined(USE_POWER_LIMITS) @@ -297,6 +295,14 @@ static void updateBatteryVoltage(timeUs_t timeDelta, bool justConnected) vbat = 0; break; } + +#ifdef USE_SIMULATOR + if (ARMING_FLAG(SIMULATOR_MODE_HITL) && SIMULATOR_HAS_OPTION(HITL_SIMULATE_BATTERY)) { + vbat = ((uint16_t)simulatorData.vbat)*10; + return; + } +#endif + if (justConnected) { pt1FilterReset(&vbatFilterState, vbat); } else { diff --git a/src/main/sensors/boardalignment.c b/src/main/sensors/boardalignment.c index 86e41880f89..1f149faeff6 100644 --- a/src/main/sensors/boardalignment.c +++ b/src/main/sensors/boardalignment.c @@ -28,6 +28,7 @@ #include "config/parameter_group.h" #include "config/parameter_group_ids.h" +#include "fc/runtime_config.h" #include "drivers/sensor.h" @@ -45,6 +46,7 @@ static bool standardBoardAlignment = true; // board orientation correction static fpMat3_t boardRotMatrix; +static fpMat3_t tailRotMatrix; // no template required since defaults are zero PG_REGISTER(boardAlignment_t, boardAlignment, PG_BOARD_ALIGNMENT, 0); @@ -56,19 +58,19 @@ static bool isBoardAlignmentStandard(const boardAlignment_t *boardAlignment) void initBoardAlignment(void) { - if (isBoardAlignmentStandard(boardAlignment())) { - standardBoardAlignment = true; - } else { - fp_angles_t rotationAngles; - - standardBoardAlignment = false; - - rotationAngles.angles.roll = DECIDEGREES_TO_RADIANS(boardAlignment()->rollDeciDegrees ); - rotationAngles.angles.pitch = DECIDEGREES_TO_RADIANS(boardAlignment()->pitchDeciDegrees); - rotationAngles.angles.yaw = DECIDEGREES_TO_RADIANS(boardAlignment()->yawDeciDegrees ); - - rotationMatrixFromAngles(&boardRotMatrix, &rotationAngles); - } + standardBoardAlignment=isBoardAlignmentStandard(boardAlignment()); + fp_angles_t rotationAngles; + + rotationAngles.angles.roll = DECIDEGREES_TO_RADIANS(boardAlignment()->rollDeciDegrees ); + rotationAngles.angles.pitch = DECIDEGREES_TO_RADIANS(boardAlignment()->pitchDeciDegrees); + rotationAngles.angles.yaw = DECIDEGREES_TO_RADIANS(boardAlignment()->yawDeciDegrees ); + + rotationMatrixFromAngles(&boardRotMatrix, &rotationAngles); + fp_angles_t tailSitter_rotationAngles; + tailSitter_rotationAngles.angles.roll = DECIDEGREES_TO_RADIANS(0); + tailSitter_rotationAngles.angles.pitch = DECIDEGREES_TO_RADIANS(900); + tailSitter_rotationAngles.angles.yaw = DECIDEGREES_TO_RADIANS(0); + rotationMatrixFromAngles(&tailRotMatrix, &tailSitter_rotationAngles); } void updateBoardAlignment(int16_t roll, int16_t pitch) @@ -85,15 +87,23 @@ void updateBoardAlignment(int16_t roll, int16_t pitch) initBoardAlignment(); } +void applyTailSitterAlignment(fpVector3_t *fpVec) +{ + if (!STATE(TAILSITTER)) { + return; + } + rotationMatrixRotateVector(fpVec, fpVec, &tailRotMatrix); +} + void applyBoardAlignment(float *vec) { - if (standardBoardAlignment) { + if (standardBoardAlignment && (!STATE(TAILSITTER))) { return; } fpVector3_t fpVec = { .v = { vec[X], vec[Y], vec[Z] } }; rotationMatrixRotateVector(&fpVec, &fpVec, &boardRotMatrix); - + applyTailSitterAlignment(&fpVec); vec[X] = lrintf(fpVec.x); vec[Y] = lrintf(fpVec.y); vec[Z] = lrintf(fpVec.z); diff --git a/src/main/sensors/boardalignment.h b/src/main/sensors/boardalignment.h index 6bf01272650..17cd08e5ff3 100644 --- a/src/main/sensors/boardalignment.h +++ b/src/main/sensors/boardalignment.h @@ -18,6 +18,7 @@ #pragma once #include "config/parameter_group.h" +#include "common/vector.h" typedef struct boardAlignment_s { int16_t rollDeciDegrees; @@ -30,4 +31,5 @@ PG_DECLARE(boardAlignment_t, boardAlignment); void initBoardAlignment(void); void updateBoardAlignment(int16_t roll, int16_t pitch); void applySensorAlignment(float * dest, float * src, uint8_t rotation); -void applyBoardAlignment(float *vec); \ No newline at end of file +void applyBoardAlignment(float *vec); +void applyTailSitterAlignment(fpVector3_t *vec); \ No newline at end of file diff --git a/src/main/sensors/compass.c b/src/main/sensors/compass.c index 23d45ed7879..02a9df69c44 100644 --- a/src/main/sensors/compass.c +++ b/src/main/sensors/compass.c @@ -472,7 +472,7 @@ void compassUpdate(timeUs_t currentTimeUs) fpVector3_t rotated; rotationMatrixRotateVector(&rotated, &v, &mag.dev.magAlign.externalRotation); - + applyTailSitterAlignment(&rotated); mag.magADC[X] = rotated.x; mag.magADC[Y] = rotated.y; mag.magADC[Z] = rotated.z; @@ -485,4 +485,5 @@ void compassUpdate(timeUs_t currentTimeUs) magUpdatedAtLeastOnce = true; } + #endif diff --git a/src/main/target/AIKONF4/target.h b/src/main/target/AIKONF4/target.h index 22ee824e5f4..cd057f8b871 100644 --- a/src/main/target/AIKONF4/target.h +++ b/src/main/target/AIKONF4/target.h @@ -86,14 +86,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS diff --git a/src/main/target/AIRBOTF4/target.c b/src/main/target/AIRBOTF4/target.c index 988543aa321..9273b3dff7f 100644 --- a/src/main/target/AIRBOTF4/target.c +++ b/src/main/target/AIRBOTF4/target.c @@ -32,12 +32,13 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT DEF_TIM(TIM4, CH1, PB6, TIM_USE_LED | TIM_USE_ANY, 0, 0), // LED D1_ST0, n/a on older AIRBOTF4 - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // PPM (5th pin on FlexiIO port) - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S3_IN - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S4_IN - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S5_IN - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S6_IN + //Airbot F4 don't have those outputs, they exist only in the original Revo + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // PPM (5th pin on FlexiIO port) + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN + // DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S3_IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S4_IN + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S5_IN + // DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S6_IN }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/AIRBOTF4/target.h b/src/main/target/AIRBOTF4/target.h index db9c2ba7e19..9d5b0eef8bb 100644 --- a/src/main/target/AIRBOTF4/target.h +++ b/src/main/target/AIRBOTF4/target.h @@ -41,14 +41,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_MAG3110 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_BARO #define BARO_I2C_BUS BUS_I2C2 @@ -139,4 +132,4 @@ #define TARGET_IO_PORTD 0xffff #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/AIRBOTF7/target.h b/src/main/target/AIRBOTF7/target.h index d77529ed39c..affa3ed4351 100644 --- a/src/main/target/AIRBOTF7/target.h +++ b/src/main/target/AIRBOTF7/target.h @@ -70,12 +70,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/ALIENFLIGHTF4/target.c b/src/main/target/ALIENFLIGHTF4/target.c index e7ee4cf5520..7c6fd6ed84a 100644 --- a/src/main/target/ALIENFLIGHTF4/target.c +++ b/src/main/target/ALIENFLIGHTF4/target.c @@ -23,11 +23,10 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH1, PA8, TIM_USE_PWM | TIM_USE_PPM, 0, 1), // PWM1 - PA8 RC1 - DMA2_ST1 - DEF_TIM(TIM3, CH3, PB0, TIM_USE_PWM, 0, 0), // PWM2 - PB0 RC2 - DMA1_ST5 - DEF_TIM(TIM3, CH4, PB1, TIM_USE_PWM, 0, 0), // PWM3 - PB1 RC3 - DMA1_ST7 - DEF_TIM(TIM1, CH2, PB14, TIM_USE_PWM, 0, 1), // PWM4 - PA14 RC4 - DMA2_ST2 - DEF_TIM(TIM1, CH3, PB15, TIM_USE_PWM | TIM_USE_LED, 0, 0), // PWM5 - PA15 RC5 - DMA2_ST6 + // DEF_TIM(TIM1, CH1, PA8, TIM_USE_PWM | TIM_USE_PPM, 0, 1), // PWM1 - PA8 RC1 - DMA2_ST1 + // DEF_TIM(TIM3, CH3, PB0, TIM_USE_PWM, 0, 0), // PWM2 - PB0 RC2 - DMA1_ST5 + // DEF_TIM(TIM3, CH4, PB1, TIM_USE_PWM, 0, 0), // PWM3 - PB1 RC3 - DMA1_ST7 + // DEF_TIM(TIM1, CH2, PB14, TIM_USE_PWM, 0, 1), // PWM4 - PA14 RC4 - DMA2_ST2 DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM6 - PB8 OUT1 - DMA1_ST7 DEF_TIM(TIM4, CH4, PB9, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM7 - PB9 OUT2 - DMA_NONE DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM8 - PA0 OUT3 - DMA1_ST2 @@ -36,6 +35,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM11 - PC7 OUT6 - DMA2_ST3 DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // PWM13 - PC8 OUT7 - DMA2_ST4 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM13 - PC9 OUT8 - DMA2_ST7 + DEF_TIM(TIM1, CH3, PB15, TIM_USE_LED, 0, 0), // PWM5 - PA15 RC5 - DMA2_ST6 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/ALIENFLIGHTF4/target.h b/src/main/target/ALIENFLIGHTF4/target.h index 5527b45a1d3..52cd4cf4a9d 100644 --- a/src/main/target/ALIENFLIGHTF4/target.h +++ b/src/main/target/ALIENFLIGHTF4/target.h @@ -46,13 +46,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_MPU9250 -#define USE_MAG_HMC5883 -#define USE_MAG_MAG3110 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/ALIENFLIGHTNGF7/target.c b/src/main/target/ALIENFLIGHTNGF7/target.c index 455747923ef..ba8ab6111c3 100644 --- a/src/main/target/ALIENFLIGHTNGF7/target.c +++ b/src/main/target/ALIENFLIGHTNGF7/target.c @@ -23,7 +23,6 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH1, PA8, TIM_USE_PPM | TIM_USE_LED, 0, 1), // PPM - DMA2_ST1 DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM1 - DMA2_ST2 DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM2 - DMA1_ST5 DEF_TIM(TIM8, CH2N, PB14, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM3 - DMA2_ST3 @@ -36,6 +35,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH3N, PB15, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM10 - DMA2_ST6 DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM11 - DMA1_ST7 DEF_TIM(TIM4, CH4, PB9, TIM_USE_OUTPUT_AUTO, 0, 0), // PWM12 - DMA_NONE + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1), // PPM - DMA2_ST1 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/ALIENFLIGHTNGF7/target.h b/src/main/target/ALIENFLIGHTNGF7/target.h index 5971f3d8484..1c8e0f901ef 100644 --- a/src/main/target/ALIENFLIGHTNGF7/target.h +++ b/src/main/target/ALIENFLIGHTNGF7/target.h @@ -44,14 +44,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8963 -#define USE_MAG_MPU9250 -#define USE_MAG_HMC5883 -#define USE_MAG_MAG3110 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define AK8963_CS_PIN PC15 #define AK8963_SPI_BUS BUS_SPI3 diff --git a/src/main/target/ANYFC/target.c b/src/main/target/ANYFC/target.c index 5353b589110..a8adb8578e3 100644 --- a/src/main/target/ANYFC/target.c +++ b/src/main/target/ANYFC/target.c @@ -23,12 +23,12 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // S1_IN - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0), // S3_IN - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0), // S4_IN - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0), // S6_IN - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0), // S5_IN + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // S1_IN + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN + // DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0), // S3_IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0), // S4_IN + // DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0), // S6_IN + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0), // S5_IN DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S10_OUT 16 DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT 12 diff --git a/src/main/target/ANYFC/target.h b/src/main/target/ANYFC/target.h index 1bda97600d4..4e1abcc0d00 100644 --- a/src/main/target/ANYFC/target.h +++ b/src/main/target/ANYFC/target.h @@ -35,12 +35,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_MAG3110 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/ANYFCF7/target.c b/src/main/target/ANYFCF7/target.c index 65f807d7984..b5ef1f12c4a 100644 --- a/src/main/target/ANYFCF7/target.c +++ b/src/main/target/ANYFCF7/target.c @@ -23,23 +23,26 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // S1_IN - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S2_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_IN DMA2_ST2 DMA2_ST2 - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0 ), // S4_IN DMA2_ST3 DMA2_ST2 - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0 ), // S5_IN DMA2_ST4 DMA2_ST2 - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0 ), // S6_IN DMA2_ST7 + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // S1_IN + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S2_IN + + DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_IN DMA2_ST2 DMA2_ST2 + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S4_IN DMA2_ST3 DMA2_ST2 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S5_IN DMA2_ST4 DMA2_ST2 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S6_IN DMA2_ST7 + + DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S10_OUT 1 DMA1_ST7 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S6_OUT 2 DMA1_ST0 + DEF_TIM(TIM4, CH4, PB9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S5_OUT + DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT 4 DMA1_ST1 DMA1_ST3 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT 3 DMA1_ST4 + DEF_TIM(TIM9, CH2, PE6, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_OUT + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S4_OUT DMA1_ST5 + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S7_OUT DMA1_ST2 + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO | TIM_USE_LED, 0, 0 ), // S8_OUT DMA1_ST6 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S9_OUT DMA1_ST4 + - DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S10_OUT 1 DMA1_ST7 - DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S6_OUT 2 DMA1_ST0 - DEF_TIM(TIM4, CH4, PB9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S5_OUT - DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT 4 DMA1_ST1 DMA1_ST3 - DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT 3 DMA1_ST4 - DEF_TIM(TIM9, CH2, PE6, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_OUT - DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S4_OUT DMA1_ST5 - DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S7_OUT DMA1_ST2 - DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO | TIM_USE_LED, 0, 0 ), // S8_OUT DMA1_ST6 - DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S9_OUT DMA1_ST4 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/ANYFCF7/target.h b/src/main/target/ANYFCF7/target.h index b09890a7ef3..179a7211f02 100644 --- a/src/main/target/ANYFCF7/target.h +++ b/src/main/target/ANYFCF7/target.h @@ -35,12 +35,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/ANYFCM7/target.c b/src/main/target/ANYFCM7/target.c index fb69d60a43b..7dd30d2250b 100644 --- a/src/main/target/ANYFCM7/target.c +++ b/src/main/target/ANYFCM7/target.c @@ -26,12 +26,12 @@ #define TIM_EN_N TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // S1_IN - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S2_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0 ), // S3_IN DMA2_ST2 DMA2_ST2 - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0 ), // S4_IN DMA2_ST3 DMA2_ST2 - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0 ), // S5_IN DMA2_ST4 DMA2_ST2 - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0 ), // S6_IN DMA2_ST7 + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // S1_IN + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S2_IN + // DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0 ), // S3_IN DMA2_ST2 DMA2_ST2 + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0 ), // S4_IN DMA2_ST3 DMA2_ST2 + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0 ), // S5_IN DMA2_ST4 DMA2_ST2 + // DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0 ), // S6_IN DMA2_ST7 DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S10_OUT 1 DMA1_ST7 DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S6_OUT 2 DMA1_ST1 diff --git a/src/main/target/ANYFCM7/target.h b/src/main/target/ANYFCM7/target.h index e058ed7a289..ce6cb0e63ab 100644 --- a/src/main/target/ANYFCM7/target.h +++ b/src/main/target/ANYFCM7/target.h @@ -35,12 +35,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/AOCODARCF405AIO/target.c b/src/main/target/AOCODARCF405AIO/target.c index be225da1bf6..d2f3d67c427 100644 --- a/src/main/target/AOCODARCF405AIO/target.c +++ b/src/main/target/AOCODARCF405AIO/target.c @@ -28,7 +28,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, MPU65 BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6500_ALIGN); BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM2, CH2, PA10, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM2, CH2, PA10, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/AOCODARCF405AIO/target.h b/src/main/target/AOCODARCF405AIO/target.h index 859caa51f48..6a95a867cc9 100644 --- a/src/main/target/AOCODARCF405AIO/target.h +++ b/src/main/target/AOCODARCF405AIO/target.h @@ -98,13 +98,7 @@ // Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_MLX90393 +#define USE_MAG_ALL /*** Onboard Flash ***/ #define USE_SPI_DEVICE_3 diff --git a/src/main/target/AOCODARCF4V2/target.c b/src/main/target/AOCODARCF4V2/target.c index 8581cc5bf11..eccd2f06d8c 100644 --- a/src/main/target/AOCODARCF4V2/target.c +++ b/src/main/target/AOCODARCF4V2/target.c @@ -25,7 +25,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S2 diff --git a/src/main/target/AOCODARCF4V2/target.h b/src/main/target/AOCODARCF4V2/target.h index ed524edc906..104ac193afc 100644 --- a/src/main/target/AOCODARCF4V2/target.h +++ b/src/main/target/AOCODARCF4V2/target.h @@ -60,13 +60,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP diff --git a/src/main/target/AOCODARCF4V3/CMakeLists.txt b/src/main/target/AOCODARCF4V3/CMakeLists.txt new file mode 100644 index 00000000000..706b818e2b8 --- /dev/null +++ b/src/main/target/AOCODARCF4V3/CMakeLists.txt @@ -0,0 +1,3 @@ +target_stm32f405xg(AOCODARCF4V3_SD) +target_stm32f405xg(AOCODARCF4V3) + diff --git a/src/main/target/AOCODARCF4V3/config.c b/src/main/target/AOCODARCF4V3/config.c new file mode 100644 index 00000000000..c80a92940a9 --- /dev/null +++ b/src/main/target/AOCODARCF4V3/config.c @@ -0,0 +1,40 @@ +/* + * 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 "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] = BOX_PERMANENT_ID_USER3; + // beeperConfigMutable()->pwmMode = true; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART5)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART5)].msp_baudrateIndex = BAUD_115200; + serialConfigMutable()->portConfigs[4].functionMask = FUNCTION_VTX_TRAMP; + serialConfigMutable()->portConfigs[4].peripheral_baudrateIndex = BAUD_115200; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART2)].functionMask = FUNCTION_RX_SERIAL; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART3)].functionMask = FUNCTION_ESCSERIAL; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_GPS; +} diff --git a/src/main/target/AOCODARCF4V3/target.c b/src/main/target/AOCODARCF4V3/target.c new file mode 100644 index 00000000000..8581cc5bf11 --- /dev/null +++ b/src/main/target/AOCODARCF4V3/target.c @@ -0,0 +1,46 @@ +/* + * 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/io.h" +#include "drivers/timer.h" +#include "drivers/pwm_mapping.h" +#include "drivers/bus.h" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0 ), // PPM IN + + DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S1 + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S2 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S3 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S4 + + DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S5 + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S6 + + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S7 + DEF_TIM(TIM2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S8 + + DEF_TIM(TIM3, CH4, PB1, TIM_USE_LED, 0, 0 ), // LED_STRIP + + +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/AOCODARCF4V3/target.h b/src/main/target/AOCODARCF4V3/target.h new file mode 100644 index 00000000000..0c95564162e --- /dev/null +++ b/src/main/target/AOCODARCF4V3/target.h @@ -0,0 +1,192 @@ +/* + * 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 USE_TARGET_CONFIG + +#ifdef AOCODARCF4V3 +#define TARGET_BOARD_IDENTIFIER "AOF4V3" +#define USBD_PRODUCT_STRING "AOCODARCF4V3" +#else +#define TARGET_BOARD_IDENTIFIER "AOF4V3SD" +#define USBD_PRODUCT_STRING "AOCODARCF4V3_SD" +#endif + +// ******** Board LEDs ********************** +#define LED0 PC13 + +// ******* Beeper *********** +#define BEEPER PB8 +#define BEEPER_INVERTED + + +// ******* GYRO and ACC ******** +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN CW90_DEG +#define MPU6500_SPI_BUS BUS_SPI1 +#define MPU6500_CS_PIN PA4 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW90_DEG +#define MPU6000_SPI_BUS BUS_SPI1 +#define MPU6000_CS_PIN PA4 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + + +// *************** Baro ************************** +#define USE_I2C +#define USE_I2C_DEVICE_1 + +#define I2C1_SCL PB6 // SCL +#define I2C1_SDA PB7 // SDA +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS + +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 + +//*********** Magnetometer / Compass ************* +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +// ******* SERIAL ******** +#define USE_VCP +#define VBUS_SENSING_PIN PB12 +#define VBUS_SENSING_ENABLED + +#define USE_UART1 +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define USE_UART2 +#define UART2_TX_PIN PA2 +#define UART2_RX_PIN PA3 + +#define USE_UART3 +#define UART3_TX_PIN PC10 +#define UART3_RX_PIN PC11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + + +#define SERIAL_PORT_COUNT 6 + + +// ******* SPI ******** +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_NSS_PIN PA13 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_NSS_PIN PC0 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +// ******* ADC ******** +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC3 + +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 + +#define VBAT_SCALE_DEFAULT 1100 +#define CURRENT_METER_SCALE 206 + +// ******* OSD ******** +#define USE_OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PA13 + +//******* FLASH ******** +#if defined(AOCODARCF4V3_SD) +#define USE_SDCARD +#define USE_SDCARD_SPI +#define SDCARD_SPI_BUS BUS_SPI3 +#define SDCARD_CS_PIN PC0 +#define SDCARD_DETECT_INVERTED +#define SDCARD_DETECT_PIN PC14 +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT +#else +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PC0 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT +#endif +// *************** PINIO *************************** +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC5 // VTX power switcher +#define PINIO2_PIN PA14 //bluetooth +#define PINIO3_PIN PC15 //Camera control +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED +#define PINIO2_FLAGS PINIO_FLAGS_INVERTED + +//************ LEDSTRIP ***************** +#define USE_LED_STRIP +#define WS2811_PIN PB1 + +// ******* FEATURES ******** +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_UART SERIAL_PORT_USART2 +#define SERIALRX_PROVIDER SERIALRX_CRSF + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_GPS | FEATURE_BLACKBOX | FEATURE_LED_STRIP) + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 10 + +// ESC-related features +#define USE_DSHOT +#define USE_SERIALSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE diff --git a/src/main/target/AOCODARCF722AIO/CMakeLists.txt b/src/main/target/AOCODARCF722AIO/CMakeLists.txt new file mode 100644 index 00000000000..87553f152fb --- /dev/null +++ b/src/main/target/AOCODARCF722AIO/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(AOCODARCF722AIO) diff --git a/src/main/target/AOCODARCF722AIO/config.c b/src/main/target/AOCODARCF722AIO/config.c new file mode 100644 index 00000000000..8996c3c5d30 --- /dev/null +++ b/src/main/target/AOCODARCF722AIO/config.c @@ -0,0 +1,44 @@ +/* + * @Author: g05047 + * @Date: 2023-03-22 17:15:53 + * @LastEditors: g05047 + * @LastEditTime: 2023-03-23 16:21:45 + * @Description: file content + */ +/* + * 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 "io/piniobox.h" +#include "sensors/boardalignment.h" +#include "sensors/barometer.h" +#include "sensors/compass.h" +#include "sensors/acceleration.h" + +void targetConfiguration(void) +{ + + compassConfigMutable()->mag_align = CW90_DEG; + + // barometerConfigMutable()->baro_hardware = BARO_DPS310; + + boardAlignmentMutable()->rollDeciDegrees = -450; + +} diff --git a/src/main/target/AOCODARCF722AIO/target.c b/src/main/target/AOCODARCF722AIO/target.c new file mode 100644 index 00000000000..038b4121b48 --- /dev/null +++ b/src/main/target/AOCODARCF722AIO/target.c @@ -0,0 +1,40 @@ +/* + * 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/sensor.h" + +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, MPU6500_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6500_ALIGN); + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + + DEF_TIM(TIM3, CH1, PB4, TIM_USE_MOTOR, 0, 0), // S1 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_MOTOR, 0, 0), // S2 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR, 0, 0), // S3 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_MOTOR, 0, 0), // S4 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/AOCODARCF722AIO/target.h b/src/main/target/AOCODARCF722AIO/target.h new file mode 100644 index 00000000000..409bc03bfdd --- /dev/null +++ b/src/main/target/AOCODARCF722AIO/target.h @@ -0,0 +1,170 @@ +/* + * 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 "F722AIO" +#define USBD_PRODUCT_STRING "AocodaRCF722AIO" + +#define LED0 PA4 + +#define USE_BEEPER +#define BEEPER PC13 +#define BEEPER_INVERTED + +/*** UART ***/ +#define USB_IO +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 6 + +/*** Gyro & Acc ***/ +#define USE_TARGET_IMU_HARDWARE_DESCRIPTORS + +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6500 +#define MPU6500_CS_PIN PB2 +#define MPU6500_SPI_BUS BUS_SPI1 +#define MPU6500_EXTI_PIN PC4 + +#define IMU_MPU6500_ALIGN CW180_DEG + +#define USE_IMU_MPU6000 +#define MPU6000_CS_PIN PB2 +#define MPU6000_SPI_BUS BUS_SPI1 +#define MPU6000_EXTI_PIN PC4 + +#define IMU_MPU6000_ALIGN CW180_DEG + +#define USE_IMU_ICM42605 +#define ICM42605_CS_PIN PB2 +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_EXTI_PIN PC4 + +#define IMU_ICM42605_ALIGN CW180_DEG + +/*** I2C (Baro & Mag) ***/ +#define USE_I2C + +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +// Baro +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_SPL06 +#define USE_BARO_DPS310 + +// Mag +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +/*** Onboard Flash ***/ +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PD2 + +#define W25N01G_SPI_BUS BUS_SPI3 +#define W25N01G_CS_PIN PD2 + +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +/*** OSD ***/ +#define USE_OSD +#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 + +/*** ADC ***/ +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC0 +#define ADC_CHANNEL_3_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 +#define RSSI_ADC_CHANNEL ADC_CHN_2 + +/*** LED ***/ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +/*** Optical Flow & Lidar ***/ +#define USE_RANGEFINDER +#define USE_RANGEFINDER_MSP +#define USE_OPFLOW +#define USE_OPFLOW_MSP + +/*** Misc ***/ +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define SERIALRX_UART SERIAL_PORT_USART2 +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define CURRENT_METER_SCALE 250 + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) diff --git a/src/main/target/AOCODARCF7DUAL/target.c b/src/main/target/AOCODARCF7DUAL/target.c index d09fafeda21..2e7de30b5d8 100644 --- a/src/main/target/AOCODARCF7DUAL/target.c +++ b/src/main/target/AOCODARCF7DUAL/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), //PPM + // DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), //PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 D(2, 2, 7) DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 D(2, 3, 7) diff --git a/src/main/target/AOCODARCF7DUAL/target.h b/src/main/target/AOCODARCF7DUAL/target.h index 71d38f174d3..5d4b0fda527 100644 --- a/src/main/target/AOCODARCF7DUAL/target.h +++ b/src/main/target/AOCODARCF7DUAL/target.h @@ -67,13 +67,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/AOCODARCF7MINI/target.c b/src/main/target/AOCODARCF7MINI/target.c index 34360bbc033..f01d2c73e81 100644 --- a/src/main/target/AOCODARCF7MINI/target.c +++ b/src/main/target/AOCODARCF7MINI/target.c @@ -37,7 +37,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM, RX1 + // DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM, RX1 DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 D(1, 4, 5) DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 D(1, 5, 4) diff --git a/src/main/target/AOCODARCF7MINI/target.h b/src/main/target/AOCODARCF7MINI/target.h index ff52565f58f..9f628963d85 100644 --- a/src/main/target/AOCODARCF7MINI/target.h +++ b/src/main/target/AOCODARCF7MINI/target.h @@ -64,13 +64,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/AOCODARCH7DUAL/target.h b/src/main/target/AOCODARCH7DUAL/target.h index 58d9c4893e0..1c12f198a03 100644 --- a/src/main/target/AOCODARCH7DUAL/target.h +++ b/src/main/target/AOCODARCH7DUAL/target.h @@ -116,13 +116,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/ASGARD32F7/target.h b/src/main/target/ASGARD32F7/target.h index ddfc11f15ba..0c5084db5f9 100644 --- a/src/main/target/ASGARD32F7/target.h +++ b/src/main/target/ASGARD32F7/target.h @@ -42,11 +42,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/ATOMRCF405NAVI/target.h b/src/main/target/ATOMRCF405NAVI/target.h index b8ae0ab6a38..5e9c9b1bd4e 100644 --- a/src/main/target/ATOMRCF405NAVI/target.h +++ b/src/main/target/ATOMRCF405NAVI/target.h @@ -74,12 +74,7 @@ */ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /* * Barometer diff --git a/src/main/target/ATOMRCF405NAVI_DELUX/CMakeLists.txt b/src/main/target/ATOMRCF405NAVI_DELUX/CMakeLists.txt new file mode 100644 index 00000000000..b9b7af86341 --- /dev/null +++ b/src/main/target/ATOMRCF405NAVI_DELUX/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(ATOMRCF405NAVI_DELUX) diff --git a/src/main/target/ATOMRCF405NAVI_DELUX/config.c b/src/main/target/ATOMRCF405NAVI_DELUX/config.c new file mode 100644 index 00000000000..e8d9b303920 --- /dev/null +++ b/src/main/target/ATOMRCF405NAVI_DELUX/config.c @@ -0,0 +1,37 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include "platform.h" +#include "fc/fc_msp_box.h" +#include "io/piniobox.h" +#include "io/serial.h" + +void targetConfiguration(void) +{ + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].msp_baudrateIndex = BAUD_115200; + + pinioBoxConfigMutable()->permanentId[0] = BOXARM; +} diff --git a/src/main/target/ATOMRCF405NAVI_DELUX/target.c b/src/main/target/ATOMRCF405NAVI_DELUX/target.c new file mode 100644 index 00000000000..54d715d8cbf --- /dev/null +++ b/src/main/target/ATOMRCF405NAVI_DELUX/target.c @@ -0,0 +1,56 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#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), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + + DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 + + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S9 + DEF_TIM(TIM8, CH2N, PB14, TIM_USE_OUTPUT_AUTO, 0, 0), // S10 + + DEF_TIM(TIM1, CH3N, PB15, TIM_USE_OUTPUT_AUTO, 0, 0), // S11 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED_STRIP +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/ATOMRCF405NAVI_DELUX/target.h b/src/main/target/ATOMRCF405NAVI_DELUX/target.h new file mode 100644 index 00000000000..f04a5d5da6f --- /dev/null +++ b/src/main/target/ATOMRCF405NAVI_DELUX/target.h @@ -0,0 +1,189 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#pragma once +#define TARGET_BOARD_IDENTIFIER "AT4D" + +#define USBD_PRODUCT_STRING "AtomRCF405NAVI_DELUX" + +#define LED0 PA13 +#define LED1 PA14 + +#define BEEPER PB2 +#define BEEPER_INVERTED + +/* + * SPI defines + */ +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PC2 +#define SPI2_MOSI_PIN PC3 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +/* + * I2C defines + */ +#define USE_I2C +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +//ICM42688-P +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 + +/* + * Magnetometer + */ +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +/* + * Barometer + */ +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_ALL + +/* + * Serial ports + */ +#define USE_VCP +#define USE_UART1 +#define USE_UART2 +#define USE_UART3 +#define USE_UART4 +#define USE_UART5 +#define USE_UART6 + +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define UART2_TX_PIN PA2 +#define UART2_RX_PIN PA3 + +#define UART3_TX_PIN PC10 +#define UART3_RX_PIN PC11 + +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define SERIAL_PORT_COUNT 7 + +/* + * ADC + */ +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 + +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC1 +#define ADC_CHANNEL_3_PIN PC4 +#define ADC_CHANNEL_4_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 AIRSPEED_ADC_CHANNEL ADC_CHN_4 + +#define CURRENT_METER_SCALE 128 + +/* + * OSD + */ +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +/* + * SD Card + */ +#define USE_SDCARD +#define USE_SDCARD_SPI +#define SDCARD_SPI_BUS BUS_SPI3 +#define SDCARD_CS_PIN PC14 +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +/* + * LED Strip + */ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +/* + * Other configs + */ +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT ) +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +#define USE_RANGEFINDER +#define USE_RANGEFINDER_MSP +#define USE_OPFLOW +#define USE_OPFLOW_MSP + +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define MAX_PWM_OUTPUT_PORTS 11 + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC15 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED \ No newline at end of file diff --git a/src/main/target/ATOMRCF405V2/CMakeLists.txt b/src/main/target/ATOMRCF405V2/CMakeLists.txt new file mode 100644 index 00000000000..940c2a80fa3 --- /dev/null +++ b/src/main/target/ATOMRCF405V2/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(ATOMRCF405V2 SKIP_RELEASES) diff --git a/src/main/target/ATOMRCF405V2/target.c b/src/main/target/ATOMRCF405V2/target.c new file mode 100644 index 00000000000..848bd0a80eb --- /dev/null +++ b/src/main/target/ATOMRCF405V2/target.c @@ -0,0 +1,47 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#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_MC_MOTOR | TIM_USE_FW_SERVO, 0, 0), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_MC_MOTOR | TIM_USE_FW_SERVO, 0, 0), // S2 + DEF_TIM(TIM3, CH2, PC7, TIM_USE_MC_MOTOR | TIM_USE_FW_SERVO, 0, 0), // S3 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_MC_MOTOR | TIM_USE_FW_SERVO, 0, 0), // S4 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_MC_MOTOR | TIM_USE_FW_MOTOR, 0, 0), // S5 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_MC_MOTOR | TIM_USE_FW_MOTOR, 0, 0), // S6 + + DEF_TIM(TIM4, CH1, PB6, TIM_USE_LED, 0, 0), // LED_STRIP +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/ATOMRCF405V2/target.h b/src/main/target/ATOMRCF405V2/target.h new file mode 100644 index 00000000000..b8315653899 --- /dev/null +++ b/src/main/target/ATOMRCF405V2/target.h @@ -0,0 +1,194 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#pragma once +#define TARGET_BOARD_IDENTIFIER "ARF4" + +#define USBD_PRODUCT_STRING "AtomRCF405V2" + +#define LED0 PC14 +#define LED1 PB2 + +#define BEEPER PC13 +#define BEEPER_INVERTED + +/* + * SPI defines + */ +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PC3 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB5 + +/* + * I2C defines + */ +#define USE_I2C +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +//MPU6000 +//#define USE_IMU_MPU6000 +//#define IMU_MPU6000_ALIGN CW180_DEG +//#define MPU6000_SPI_BUS BUS_SPI1 +//#define MPU6000_CS_PIN PA4 + +//BMI270 +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW180_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PA4 + + +/* + * Magnetometer + */ +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS + +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_MAG3110 +#define USE_MAG_LIS3MDL + +/* + * Barometer + */ +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_BMP085 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 + +/* + * Serial ports + */ +#define USE_VCP +#define USE_UART1 +#define USE_UART2 +#define USE_UART3 +#define USE_UART4 +#define USE_UART5 + +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define UART2_TX_PIN PA2 +#define UART2_RX_PIN PA3 + +#define UART3_TX_PIN PB10 +#define UART3_RX_PIN PB11 + +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define SERIAL_PORT_COUNT 6 + +/* + * ADC + */ +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream4 + +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC1 +#define ADC_CHANNEL_3_PIN PC2 + +#define VBAT_ADC_CHANNEL ADC_CHN_3 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_1 + +#define CURRENT_METER_SCALE 320 + +/* + * OSD + */ +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PA15 + +/* + * Blackbox + */ +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_SPI_BUS BUS_SPI2 +#define M25P16_CS_PIN PB12 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +/* + * LED Strip + */ +#define USE_LED_STRIP +#define WS2811_PIN PB6 + +/* + * Other configs + */ +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT ) +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// #define USE_RANGEFINDER +// #define USE_RANGEFINDER_MSP +// #define USE_OPFLOW +// #define USE_OPFLOW_MSP + +// #define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS +// #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS +// #define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define MAX_PWM_OUTPUT_PORTS 6 + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) diff --git a/src/main/target/AXISFLYINGF7PRO/target.c b/src/main/target/AXISFLYINGF7PRO/target.c index 8d4b966b69c..e6ad7b071f2 100644 --- a/src/main/target/AXISFLYINGF7PRO/target.c +++ b/src/main/target/AXISFLYINGF7PRO/target.c @@ -33,7 +33,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED STRIP - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0), // CAM CONTROL }; diff --git a/src/main/target/AXISFLYINGF7PRO/target.h b/src/main/target/AXISFLYINGF7PRO/target.h index 4a4b95657ec..39c94e47e9a 100644 --- a/src/main/target/AXISFLYINGF7PRO/target.h +++ b/src/main/target/AXISFLYINGF7PRO/target.h @@ -134,11 +134,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/BEEROTORF4/target.c b/src/main/target/BEEROTORF4/target.c index 28e6a77402a..aa4d4893bf1 100644 --- a/src/main/target/BEEROTORF4/target.c +++ b/src/main/target/BEEROTORF4/target.c @@ -24,7 +24,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM IN + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM IN DEF_TIM(TIM1, CH2N, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M1 - DMAR: DMA2_ST5 DEF_TIM(TIM1, CH3N, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // M2 - diff --git a/src/main/target/BEEROTORF4/target.h b/src/main/target/BEEROTORF4/target.h index 4ebde46875d..1ff901b870a 100644 --- a/src/main/target/BEEROTORF4/target.h +++ b/src/main/target/BEEROTORF4/target.h @@ -37,14 +37,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/BETAFLIGHTF4/target.c b/src/main/target/BETAFLIGHTF4/target.c index 0e10cdbf59d..67d8f260adc 100755 --- a/src/main/target/BETAFLIGHTF4/target.c +++ b/src/main/target/BETAFLIGHTF4/target.c @@ -24,7 +24,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM4, CH3, PB8, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM4, CH3, PB8, TIM_USE_PPM, 0, 0), // PPM // Motors DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT D1_ST7 diff --git a/src/main/target/BETAFLIGHTF4/target.h b/src/main/target/BETAFLIGHTF4/target.h index 13e7dd32657..05f35872986 100755 --- a/src/main/target/BETAFLIGHTF4/target.h +++ b/src/main/target/BETAFLIGHTF4/target.h @@ -112,14 +112,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/BETAFPVF411/CMakeLists.txt b/src/main/target/BETAFPVF411/CMakeLists.txt new file mode 100644 index 00000000000..087194803cc --- /dev/null +++ b/src/main/target/BETAFPVF411/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f411xe(BETAFPVF411 SKIP_RELEASES) \ No newline at end of file diff --git a/src/main/target/BETAFPVF411/target.c b/src/main/target/BETAFPVF411/target.c new file mode 100644 index 00000000000..58e44f9780f --- /dev/null +++ b/src/main/target/BETAFPVF411/target.c @@ -0,0 +1,34 @@ +/* + * 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/dma.h" +#include "drivers/timer.h" +#include "drivers/bus.h" +#include "drivers/pwm_mapping.h" + + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/BETAFPVF411/target.h b/src/main/target/BETAFPVF411/target.h new file mode 100644 index 00000000000..1f57281d2f4 --- /dev/null +++ b/src/main/target/BETAFPVF411/target.h @@ -0,0 +1,130 @@ +/* + * 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 + +#define TARGET_BOARD_IDENTIFIER "B411" +#define USBD_PRODUCT_STRING "BETAFPVF411" + +#define LED0 PC13 + +#define BEEPER PB2 +#define BEEPER_INVERTED + +// *************** SPI ********************** +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +// *************** SPI Gyro & ACC ********************** +#define USE_IMU_MPU6000 +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 +#define IMU_MPU6000_ALIGN CW180_DEG + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW90_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PA4 + +// *************** Baro ***************************** + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +// *************** SPI OSD ***************************** +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// *************** SPI FLASH ************************** +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_CS_PIN PB2 +#define M25P16_SPI_BUS BUS_SPI2 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_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 PA2 +#define UART2_RX_PIN PA3 + +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_TX_PIN PB3 +#define SOFTSERIAL_1_RX_PIN PB3 + +#define USE_SOFTSERIAL2 +#define SOFTSERIAL_2_TX_PIN PB10 +#define SOFTSERIAL_2_RX_PIN PB10 + +#define SERIAL_PORT_COUNT 5 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART1 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC_CHANNEL_1_PIN PB0 +#define ADC_CHANNEL_2_PIN PB1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + +#define VBAT_SCALE_DEFAULT 1100 + +// *************** LED2812 ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +// *************** OTHERS ************************* +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_OSD | FEATURE_VBAT | FEATURE_TELEMETRY | FEATURE_BLACKBOX) + +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 4 diff --git a/src/main/target/BETAFPVF435/target.h b/src/main/target/BETAFPVF435/target.h index c8e17bd7c48..fa025b9d7fd 100644 --- a/src/main/target/BETAFPVF435/target.h +++ b/src/main/target/BETAFPVF435/target.h @@ -31,7 +31,7 @@ //#define ENABLE_DSHOT_DMAR DSHOT_DMAR_AUTO //#define DSHOT_BITBANG_DEFAULT DSHOT_BITBANG_AUTO -//#define ENABLE_DSHOT +#define ENABLE_DSHOT // *************** Gyro & ACC ********************** #define USE_SPI @@ -116,14 +116,12 @@ #define MAX7456_CS_PIN PA15 #endif -#if 0 // I2C #define USE_I2C #define USE_I2C_DEVICE_2 #define I2C2_SCL PB10 // SCL pad #define I2C2_SDA PB11 // SDA pad #define USE_I2C_PULLUP -#endif #define USE_BARO #define BARO_I2C_BUS BUS_I2C2 @@ -179,7 +177,7 @@ #define USE_LED_STRIP #define WS2811_PIN PB6 -#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_LED_STRIP ) +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_LED_STRIP ) #define DEFAULT_VOLTAGE_METER_SOURCE VOLTAGE_METER_ADC #define DEFAULT_CURRENT_METER_SOURCE CURRENT_METER_ADC @@ -191,11 +189,13 @@ #define TARGET_IO_PORTC 0xffff #define TARGET_IO_PORTD 0xffff #define TARGET_IO_PORTE BIT(2) +#define TARGET_IO_PORTH (BIT(1)|BIT(2)|BIT(3)) #define MAX_PWM_OUTPUT_PORTS 8 #define USE_SERIAL_4WAY_BLHELI_INTERFACE -//#define USE_DSHOT -//#define USE_ESC_SENSOR -#define USE_ESCSERIAL \ No newline at end of file +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_ESCSERIAL +#define USE_RPM_FILTER diff --git a/src/main/target/BETAFPVF722/target.c b/src/main/target/BETAFPVF722/target.c index e24689c0ca9..d44324cd7ce 100755 --- a/src/main/target/BETAFPVF722/target.c +++ b/src/main/target/BETAFPVF722/target.c @@ -25,7 +25,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR, 0, 0), // S1 D(1, 4, 5) DEF_TIM(TIM3, CH4, PB1, TIM_USE_MOTOR, 0, 0), // S2 D(2, 3, 7) diff --git a/src/main/target/BETAFPVF722/target.h b/src/main/target/BETAFPVF722/target.h index 9d1258385de..cab6d2ff146 100755 --- a/src/main/target/BETAFPVF722/target.h +++ b/src/main/target/BETAFPVF722/target.h @@ -70,12 +70,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/BLACKPILL_F411/target.c b/src/main/target/BLACKPILL_F411/target.c index d36b8c19c24..18c0d2edf6a 100644 --- a/src/main/target/BLACKPILL_F411/target.c +++ b/src/main/target/BLACKPILL_F411/target.c @@ -35,7 +35,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0), //ST1 pad -softserial_tx1 - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 Pad -PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 Pad -PPM }; diff --git a/src/main/target/BLACKPILL_F411/target.h b/src/main/target/BLACKPILL_F411/target.h index 7682595de67..b67480008a8 100644 --- a/src/main/target/BLACKPILL_F411/target.h +++ b/src/main/target/BLACKPILL_F411/target.h @@ -111,13 +111,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/BLUEJAYF4/target.c b/src/main/target/BLUEJAYF4/target.c index 0b968380cf0..ba48551f76c 100644 --- a/src/main/target/BLUEJAYF4/target.c +++ b/src/main/target/BLUEJAYF4/target.c @@ -23,7 +23,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT - DMA1_ST2 DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT - DMA1_ST4 diff --git a/src/main/target/BLUEJAYF4/target.h b/src/main/target/BLUEJAYF4/target.h index 689dba9282d..e62120bdc86 100644 --- a/src/main/target/BLUEJAYF4/target.h +++ b/src/main/target/BLUEJAYF4/target.h @@ -41,12 +41,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/CLRACINGF4AIR/target.c b/src/main/target/CLRACINGF4AIR/target.c index 54fa14c7097..beca9ba67ec 100644 --- a/src/main/target/CLRACINGF4AIR/target.c +++ b/src/main/target/CLRACINGF4AIR/target.c @@ -21,8 +21,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0), - DEF_TIM(TIM4, CH3, PB8, TIM_USE_LED, 0, 0), + // DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0), #if defined(CLRACINGF4AIRV2) || defined(CLRACINGF4AIRV3) DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), @@ -39,6 +38,7 @@ DEF_TIM(TIM12, CH2, PB15, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), #endif + DEF_TIM(TIM4, CH3, PB8, TIM_USE_LED, 0, 0), }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/COLIBRI/target.c b/src/main/target/COLIBRI/target.c index 932188992bc..7affcc4936c 100755 --- a/src/main/target/COLIBRI/target.c +++ b/src/main/target/COLIBRI/target.c @@ -24,14 +24,14 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PA10, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // S1_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0), // S2_IN - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0), // S3_IN - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0), // S4_IN - DEF_TIM(TIM2, CH1, PA15, TIM_USE_PWM, 0, 0), // S5_IN - DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM, 0, 0), // S6_IN - DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM, 0, 0), // S7_IN - DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0), // S8_IN + // DEF_TIM(TIM1, CH3, PA10, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // S1_IN + // DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM, 0, 0), // S2_IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM, 0, 0), // S3_IN + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0), // S4_IN + // DEF_TIM(TIM2, CH1, PA15, TIM_USE_PWM, 0, 0), // S5_IN + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM, 0, 0), // S6_IN + // DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM, 0, 0), // S7_IN + // DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0), // S8_IN DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT diff --git a/src/main/target/COLIBRI/target.h b/src/main/target/COLIBRI/target.h index c76b91b499e..6898448809d 100755 --- a/src/main/target/COLIBRI/target.h +++ b/src/main/target/COLIBRI/target.h @@ -42,12 +42,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C3 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C3 diff --git a/src/main/target/DAKEFPVF405/CMakeLists.txt b/src/main/target/DAKEFPVF405/CMakeLists.txt new file mode 100644 index 00000000000..9a147fdb702 --- /dev/null +++ b/src/main/target/DAKEFPVF405/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(DAKEFPVF405) diff --git a/src/main/target/DAKEFPVF405/config.c b/src/main/target/DAKEFPVF405/config.c new file mode 100644 index 00000000000..73f636cf8c0 --- /dev/null +++ b/src/main/target/DAKEFPVF405/config.c @@ -0,0 +1,31 @@ +/* + * 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 + +#include + +#include "io/serial.h" +#include "rx/rx.h" +#include "fc/fc_msp_box.h" +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; +} diff --git a/src/main/target/DAKEFPVF405/target.c b/src/main/target/DAKEFPVF405/target.c new file mode 100644 index 00000000000..8f31bd7350d --- /dev/null +++ b/src/main/target/DAKEFPVF405/target.c @@ -0,0 +1,36 @@ +/* + * 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 +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + + DEF_TIM(TIM2, CH2, PB3, TIM_USE_LED, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/DAKEFPVF405/target.h b/src/main/target/DAKEFPVF405/target.h new file mode 100644 index 00000000000..41c128668ef --- /dev/null +++ b/src/main/target/DAKEFPVF405/target.h @@ -0,0 +1,168 @@ +/* + * 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 "DAK4" +#define USBD_PRODUCT_STRING "DAKEFPV F405" + +#define LED0 PC14 +#define LED1 PC15 + +#define BEEPER PC3 +#define BEEPER_INVERTED + +// Buses +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB5 + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +// Gyro +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN CW90_DEG +#define MPU6500_CS_PIN PA4 +#define MPU6500_SPI_BUS BUS_SPI1 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW90_DEG +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + +//Baro +#define USE_BARO +#define USE_BARO_BMP280 +#define BMP280_SPI_BUS BUS_SPI2 +#define BMP280_CS_PIN PC13 +#define USE_BARO_DPS310 +#define DPS310_SPI_BUS BUS_SPI2 +#define DPS310_CS_PIN PC13 + +// M25P256 flash +#define USE_FLASHFS +#define USE_FLASH_M25P16 + +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// Serial ports +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +// Mag +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define USE_RANGEFINDER_MSP +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +// ADC +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define RSSI_ADC_CHANNEL ADC_CHN_2 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY ) + +#define USE_LED_STRIP +#define WS2811_PIN PB3 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define MAX_PWM_OUTPUT_PORTS 6 + +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC5 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED \ No newline at end of file diff --git a/src/main/target/DAKEFPVF722/CMakeLists.txt b/src/main/target/DAKEFPVF722/CMakeLists.txt new file mode 100644 index 00000000000..e2385c70c51 --- /dev/null +++ b/src/main/target/DAKEFPVF722/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(DAKEFPVF722) diff --git a/src/main/target/DAKEFPVF722/config.c b/src/main/target/DAKEFPVF722/config.c new file mode 100644 index 00000000000..bfb7ffbef3c --- /dev/null +++ b/src/main/target/DAKEFPVF722/config.c @@ -0,0 +1,28 @@ +/* + * 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 + +#include + +#include "io/serial.h" +#include "rx/rx.h" + +void targetConfiguration(void) +{ +} diff --git a/src/main/target/DAKEFPVF722/target.c b/src/main/target/DAKEFPVF722/target.c new file mode 100644 index 00000000000..8f31bd7350d --- /dev/null +++ b/src/main/target/DAKEFPVF722/target.c @@ -0,0 +1,36 @@ +/* + * 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 +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + + DEF_TIM(TIM2, CH2, PB3, TIM_USE_LED, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/DAKEFPVF722/target.h b/src/main/target/DAKEFPVF722/target.h new file mode 100644 index 00000000000..92cc65783b8 --- /dev/null +++ b/src/main/target/DAKEFPVF722/target.h @@ -0,0 +1,150 @@ +/* + * 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 "DAK7" +#define USBD_PRODUCT_STRING "DAKEFPV F722" + +#define LED0 PC14 +#define LED1 PC15 + +#define BEEPER PC3 +#define BEEPER_INVERTED + +// Buses +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB5 + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +// Gyro +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN CW90_DEG +#define MPU6500_CS_PIN PA4 +#define MPU6500_SPI_BUS BUS_SPI1 + +//Baro +#define USE_BARO +#define USE_BARO_BMP280 +#define BMP280_SPI_BUS BUS_SPI2 +#define BMP280_CS_PIN PA13 + +// M25P256 flash +#define USE_FLASHFS +#define USE_FLASH_M25P16 + +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// Serial ports +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +// Mag +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define USE_RANGEFINDER_MSP +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +// ADC +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define RSSI_ADC_CHANNEL ADC_CHN_2 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY ) + +#define USE_LED_STRIP +#define WS2811_PIN PB3 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define MAX_PWM_OUTPUT_PORTS 6 diff --git a/src/main/target/DALRCF405/target.c b/src/main/target/DALRCF405/target.c index e1cddea2613..816ad3cdeca 100644 --- a/src/main/target/DALRCF405/target.c +++ b/src/main/target/DALRCF405/target.c @@ -22,7 +22,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 (1,7) DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 (2,2) diff --git a/src/main/target/DALRCF405/target.h b/src/main/target/DALRCF405/target.h index 449be6a7150..6a9a5494ffe 100644 --- a/src/main/target/DALRCF405/target.h +++ b/src/main/target/DALRCF405/target.h @@ -82,13 +82,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/DALRCF722DUAL/target.c b/src/main/target/DALRCF722DUAL/target.c index 286c00539a3..8c4fa74475e 100644 --- a/src/main/target/DALRCF722DUAL/target.c +++ b/src/main/target/DALRCF722DUAL/target.c @@ -28,7 +28,7 @@ #define TIM_EN_N TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL timerHardware_t timerHardware[] = { - DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM ,0, 0), + // DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM ,0, 0), DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO,0,0), //S1 DMA2_ST2 T8CH1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO,0,0), //S2 DMA2_ST3 T8CH2 diff --git a/src/main/target/DALRCF722DUAL/target.h b/src/main/target/DALRCF722DUAL/target.h index b7d2b4a0d1a..5c6dc15a3d7 100644 --- a/src/main/target/DALRCF722DUAL/target.h +++ b/src/main/target/DALRCF722DUAL/target.h @@ -63,19 +63,12 @@ #define USE_BARO #define BARO_I2C_BUS BUS_I2C1 -#define USE_BARO_BMP280 -#define USE_BARO_MS5611 -#define USE_BARO_BMP085 +#define USE_BARO_ALL #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/F4BY/target.c b/src/main/target/F4BY/target.c index 37d9db89418..8d1b4622f69 100644 --- a/src/main/target/F4BY/target.c +++ b/src/main/target/F4BY/target.c @@ -6,14 +6,14 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM3, CH4, PC9, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // S1_IN - DEF_TIM(TIM3, CH3, PC8, TIM_USE_PWM, 0, 0), // S2_IN - DEF_TIM(TIM3, CH1, PC6, TIM_USE_PWM, 0, 0), // S3_IN - DEF_TIM(TIM3, CH2, PC7, TIM_USE_PWM, 0, 0), // S4_IN - DEF_TIM(TIM4, CH4, PD15, TIM_USE_PWM, 0, 0), // S5_IN - DEF_TIM(TIM4, CH3, PD14, TIM_USE_PWM, 0, 0), // S6_IN - DEF_TIM(TIM4, CH2, PD13, TIM_USE_PWM, 0, 0), // S7_IN - DEF_TIM(TIM4, CH1, PD12, TIM_USE_PWM, 0, 0), // S8_IN + // DEF_TIM(TIM3, CH4, PC9, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // S1_IN + // DEF_TIM(TIM3, CH3, PC8, TIM_USE_PWM, 0, 0), // S2_IN + // DEF_TIM(TIM3, CH1, PC6, TIM_USE_PWM, 0, 0), // S3_IN + // DEF_TIM(TIM3, CH2, PC7, TIM_USE_PWM, 0, 0), // S4_IN + // DEF_TIM(TIM4, CH4, PD15, TIM_USE_PWM, 0, 0), // S5_IN + // DEF_TIM(TIM4, CH3, PD14, TIM_USE_PWM, 0, 0), // S6_IN + // DEF_TIM(TIM4, CH2, PD13, TIM_USE_PWM, 0, 0), // S7_IN + // DEF_TIM(TIM4, CH1, PD12, TIM_USE_PWM, 0, 0), // S8_IN DEF_TIM(TIM2, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT DEF_TIM(TIM2, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT diff --git a/src/main/target/F4BY/target.h b/src/main/target/F4BY/target.h index f72f78f20e7..21f91c1d49b 100644 --- a/src/main/target/F4BY/target.h +++ b/src/main/target/F4BY/target.h @@ -41,12 +41,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/FF_F35_LIGHTNING/target.c b/src/main/target/FF_F35_LIGHTNING/target.c index 83d75497e4d..617c085a925 100644 --- a/src/main/target/FF_F35_LIGHTNING/target.c +++ b/src/main/target/FF_F35_LIGHTNING/target.c @@ -33,11 +33,11 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0), -#ifdef WINGFC - DEF_TIM(TIM2, CH4, PB11, TIM_USE_PPM, 0, 0), // UART3 RX -#else - DEF_TIM(TIM2, CH3, PB10, TIM_USE_PPM, 0, 0), // UART3 TX -#endif +// #ifdef WINGFC +// DEF_TIM(TIM2, CH4, PB11, TIM_USE_PPM, 0, 0), // UART3 RX +// #else +// DEF_TIM(TIM2, CH3, PB10, TIM_USE_PPM, 0, 0), // UART3 TX +// #endif }; diff --git a/src/main/target/FF_FORTINIF4/target.c b/src/main/target/FF_FORTINIF4/target.c index 5853bc31391..54aae5ce4e6 100644 --- a/src/main/target/FF_FORTINIF4/target.c +++ b/src/main/target/FF_FORTINIF4/target.c @@ -27,7 +27,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 1, 0 ), // S2_OUT - DMA1_ST2 DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 1, 1 ), // S3_OUT - DMA1_ST6 DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 1, 0 ), // S4_OUT - DMA1_ST1 - DEF_TIM(TIM4, CH4, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM4, CH4, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM4, CH2, PB7, TIM_USE_LED, 0, 0), // LED - DMA1_ST3 }; diff --git a/src/main/target/FIREWORKSV2/target.c b/src/main/target/FIREWORKSV2/target.c index 8e7cdb95754..7f96e097145 100644 --- a/src/main/target/FIREWORKSV2/target.c +++ b/src/main/target/FIREWORKSV2/target.c @@ -44,7 +44,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_2_mpu6000, DEVHW_MPU6000, IMU_2_SPI_BUS, IMU_ BUSDEV_REGISTER_SPI_TAG(busdev_2_mpu6500, DEVHW_MPU6500, IMU_2_SPI_BUS, IMU_2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_2_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM // Motor output 1: use different set of timers for MC and FW //DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR | TIM _USE_SERVO, 1, 0), // S1_OUT D(1,7) diff --git a/src/main/target/FIREWORKSV2/target.h b/src/main/target/FIREWORKSV2/target.h index ce8831f4a95..a2f69ae49d8 100644 --- a/src/main/target/FIREWORKSV2/target.h +++ b/src/main/target/FIREWORKSV2/target.h @@ -87,11 +87,7 @@ #else #define MAG_I2C_BUS BUS_I2C2 #endif -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #if defined(OMNIBUSF4V6) #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/FISHDRONEF4/target.c b/src/main/target/FISHDRONEF4/target.c index b0aec49bc4d..93354b51758 100644 --- a/src/main/target/FISHDRONEF4/target.c +++ b/src/main/target/FISHDRONEF4/target.c @@ -23,12 +23,12 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // PPM IN - DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0 ), - DEF_TIM(TIM3, CH3, PB0, TIM_USE_PWM, 0, 0 ), - DEF_TIM(TIM2, CH3, PB10, TIM_USE_PWM, 0, 0 ), - DEF_TIM(TIM2, CH4, PB11, TIM_USE_PWM, 0, 0 ), - DEF_TIM(TIM1, CH1, PA8, TIM_USE_PWM, 0, 0 ), + // DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0 ), + // DEF_TIM(TIM3, CH3, PB0, TIM_USE_PWM, 0, 0 ), + // DEF_TIM(TIM2, CH3, PB10, TIM_USE_PWM, 0, 0 ), + // DEF_TIM(TIM2, CH4, PB11, TIM_USE_PWM, 0, 0 ), + // DEF_TIM(TIM1, CH1, PA8, TIM_USE_PWM, 0, 0 ), DEF_TIM(TIM12, CH1, PB14, TIM_USE_OUTPUT_AUTO, 0, 0 ), DEF_TIM(TIM12, CH2, PB15, TIM_USE_OUTPUT_AUTO, 0, 0 ), diff --git a/src/main/target/FISHDRONEF4/target.h b/src/main/target/FISHDRONEF4/target.h index 741a8aded88..10e325202e3 100644 --- a/src/main/target/FISHDRONEF4/target.h +++ b/src/main/target/FISHDRONEF4/target.h @@ -47,13 +47,7 @@ // *************** Compass ***************************** #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_MPU9250 -#define USE_MAG_MAG3110 -#define USE_MAG_HMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_QMC5883 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** Temperature sensor ***************** #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/FLASHHOBBYF405/CMakeLists.txt b/src/main/target/FLASHHOBBYF405/CMakeLists.txt new file mode 100644 index 00000000000..7fa38644d1f --- /dev/null +++ b/src/main/target/FLASHHOBBYF405/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(FLASHHOBBYF405) diff --git a/src/main/target/FLASHHOBBYF405/target.c b/src/main/target/FLASHHOBBYF405/target.c new file mode 100644 index 00000000000..b088049a07b --- /dev/null +++ b/src/main/target/FLASHHOBBYF405/target.c @@ -0,0 +1,43 @@ +/* +* This file is part of INAV Project. +* +* 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 "platform.h" +#include "drivers/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 1), + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1),//WS2812B + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM | TIM_USE_FW_SERVO, 0, 0), // "C.C" +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); \ No newline at end of file diff --git a/src/main/target/FLASHHOBBYF405/target.h b/src/main/target/FLASHHOBBYF405/target.h new file mode 100644 index 00000000000..937917c95c1 --- /dev/null +++ b/src/main/target/FLASHHOBBYF405/target.h @@ -0,0 +1,164 @@ +/* + * This file is part of INAV Project. + * + * 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 + +#define TARGET_BOARD_IDENTIFIER "FHRCF405" + +#define USBD_PRODUCT_STRING "FLASHHOBBYF405" + +#define LED0 PC14 + +#define BEEPER PB2 +#define BEEPER_INVERTED + +// *************** Gyro & ACC ********************** +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW0_DEG +#define MPU6000_CS_PIN SPI1_NSS_PIN +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW0_DEG +#define BMI270_CS_PIN SPI1_NSS_PIN +#define BMI270_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_SPI_BUS BUS_SPI1 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +// *************** OSD ***************************** +#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_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN + +// *************** FLASH ************************** +#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 M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN NONE + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +// *************** PINIO ************************ +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/FLASHHOBBYF722/CMakeLists.txt b/src/main/target/FLASHHOBBYF722/CMakeLists.txt new file mode 100644 index 00000000000..90566a14d66 --- /dev/null +++ b/src/main/target/FLASHHOBBYF722/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(FLASHHOBBYF722) diff --git a/src/main/target/FLASHHOBBYF722/target.c b/src/main/target/FLASHHOBBYF722/target.c new file mode 100644 index 00000000000..31a8f73544c --- /dev/null +++ b/src/main/target/FLASHHOBBYF722/target.c @@ -0,0 +1,45 @@ +/* +* This file is part of INAV Project. +* +* 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 "platform.h" +#include "drivers/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 1), + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1),//WS2812B + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM | TIM_USE_FW_SERVO, 0, 0), // "C.C" +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + + diff --git a/src/main/target/FLASHHOBBYF722/target.h b/src/main/target/FLASHHOBBYF722/target.h new file mode 100644 index 00000000000..f0cc7881352 --- /dev/null +++ b/src/main/target/FLASHHOBBYF722/target.h @@ -0,0 +1,162 @@ +/* + * This file is part of INAV Project. + * + * 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 + +#define TARGET_BOARD_IDENTIFIER "FHRCF722" +#define USBD_PRODUCT_STRING "FLASHHOBBYF722" + +#define LED0 PC14 + +#define BEEPER PC15 +#define BEEPER_INVERTED + +// *************** Gyro & ACC ********************** +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW0_DEG +#define MPU6000_CS_PIN SPI1_NSS_PIN +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW0_DEG +#define BMI270_CS_PIN SPI1_NSS_PIN +#define BMI270_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_SPI_BUS BUS_SPI1 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +// *************** FLASH ************************** +#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 M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** OSD ***************************** +#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_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN NONE + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +// *************** PINIO ************************ +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/FLYCOLORF7MINI/target.h b/src/main/target/FLYCOLORF7MINI/target.h index ece951b3c4d..938913d6488 100644 --- a/src/main/target/FLYCOLORF7MINI/target.h +++ b/src/main/target/FLYCOLORF7MINI/target.h @@ -58,13 +58,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/FLYCOLORF7V2/CMakeLists.txt b/src/main/target/FLYCOLORF7V2/CMakeLists.txt new file mode 100644 index 00000000000..378906acc2f --- /dev/null +++ b/src/main/target/FLYCOLORF7V2/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(FLYCOLORF7V2) diff --git a/src/main/target/FLYCOLORF7V2/config.c b/src/main/target/FLYCOLORF7V2/config.c new file mode 100644 index 00000000000..0f32e6d7805 --- /dev/null +++ b/src/main/target/FLYCOLORF7V2/config.c @@ -0,0 +1,33 @@ +/* + * 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 "io/piniobox.h" +#include "io/serial.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART4)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART4)].msp_baudrateIndex = BAUD_115200; +} diff --git a/src/main/target/FLYCOLORF7V2/target.c b/src/main/target/FLYCOLORF7V2/target.c new file mode 100644 index 00000000000..7d8e8c2577c --- /dev/null +++ b/src/main/target/FLYCOLORF7V2/target.c @@ -0,0 +1,40 @@ +/* + * 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, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // WS2812B +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/FLYCOLORF7V2/target.h b/src/main/target/FLYCOLORF7V2/target.h new file mode 100644 index 00000000000..8222e379d8d --- /dev/null +++ b/src/main/target/FLYCOLORF7V2/target.h @@ -0,0 +1,158 @@ +/* + * 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 "FL72" +#define USBD_PRODUCT_STRING "Flycolor F7 V2" + +#define LED0 PC15 + +#define BEEPER PC14 +#define BEEPER_INVERTED + +// *************** SPI1 Gyro & ACC ******************* + +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6500 +#define IMU_MPU6500_ALIGN CW180_DEG_FLIP +#define MPU6500_CS_PIN PA4 +#define MPU6500_SPI_BUS BUS_SPI1 + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 +#define I2C_DEVICE_2_SHARES_UART3 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C2 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C2 +#define PITOT_I2C_BUS BUS_I2C2 +#define RANGEFINDER_I2C_BUS BUS_I2C2 + +// *************** SPI2 OSD *********************** +#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 + +// *************** SPI3 SD BLACKBOX******************* +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB5 + +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PC13 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_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 PA2 +#define UART2_RX_PIN PA3 + +#define USE_UART3 +#define UART3_TX_PIN PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 + +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 +#define RSSI_ADC_CHANNEL ADC_CHN_2 + +// *************** PINIO *************************** +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PB8 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) +#define CURRENT_METER_SCALE 250 +#define CURRENT_METER_OFFSET 0 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 6 +#define USE_DSHOT +#define USE_SERIALSHOT +#define USE_ESC_SENSOR + diff --git a/src/main/target/FLYWOOF405PRO/target.c b/src/main/target/FLYWOOF405PRO/target.c index f61d06ca0e1..c0f1c4eec2d 100644 --- a/src/main/target/FLYWOOF405PRO/target.c +++ b/src/main/target/FLYWOOF405PRO/target.c @@ -34,7 +34,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH2, PA9, TIM_USE_LED, 0, 0), //2812LED D(1,5,3) - DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/FLYWOOF405PRO/target.h b/src/main/target/FLYWOOF405PRO/target.h index 39a3339c108..14b5e9e03cb 100644 --- a/src/main/target/FLYWOOF405PRO/target.h +++ b/src/main/target/FLYWOOF405PRO/target.h @@ -68,13 +68,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_RANGEFINDER #define USE_RANGEFINDER_HCSR04_I2C diff --git a/src/main/target/FLYWOOF405S_AIO/CMakeLists.txt b/src/main/target/FLYWOOF405S_AIO/CMakeLists.txt new file mode 100644 index 00000000000..6e3af8a3cbb --- /dev/null +++ b/src/main/target/FLYWOOF405S_AIO/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(FLYWOOF405S_AIO SKIP_RELEASES) diff --git a/src/main/target/FLYWOOF405S_AIO/target.c b/src/main/target/FLYWOOF405S_AIO/target.c new file mode 100644 index 00000000000..0d51ec0c109 --- /dev/null +++ b/src/main/target/FLYWOOF405S_AIO/target.c @@ -0,0 +1,37 @@ +/* + * 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 +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S1 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 + + DEF_TIM(TIM1, CH2, PA9, TIM_USE_LED, 0, 0), //2812LED D(1,5,3) + DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/FLYWOOF405S_AIO/target.h b/src/main/target/FLYWOOF405S_AIO/target.h new file mode 100644 index 00000000000..c25dedfeb9b --- /dev/null +++ b/src/main/target/FLYWOOF405S_AIO/target.h @@ -0,0 +1,174 @@ +/* + * 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 "F4SA" +#define USBD_PRODUCT_STRING "FLYWOOF405S_AIO" + + +#define LED0 PC14 //Green +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** SPI1 Gyro & ACC ******************* +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG +#define MPU6000_CS_PIN PB12 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW270_DEG +#define BMI270_CS_PIN PB12 +#define BMI270_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN PB12 +#define ICM42605_SPI_BUS BUS_SPI1 + +#define USE_EXTI +#define GYRO_INT_EXTI PB13 +#define USE_MPU_DATA_READY_SIGNAL + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_BMP085 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_AK8963 +#define USE_MAG_AK8975 +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_MAG3110 +#define USE_MAG_LIS3MDL + +#define USE_RANGEFINDER +#define USE_RANGEFINDER_HCSR04_I2C +#define RANGEFINDER_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 +#define TEMPERATURE_I2C_BUS BUS_I2C1 + + + +// *************** SPI2 OSD *************************** +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define USE_OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PB14// + +// *************** Onboard flash ******************** + +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_CS_PIN PB3 +#define M25P16_SPI_BUS BUS_SPI3 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + + +// *************** UART ***************************** +#define USB_IO +#define USE_VCP +#define VBUS_SENSING_PIN PA8 +#define VBUS_SENSING_ENABLED + +#define USE_UART1 +#define UART1_TX_PIN PB6 +#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 PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN NONE +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART3 + + +// *************** ADC *************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC3 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +// *************** LED2812 ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA9 + +// *************** OTHERS ************************* +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY | FEATURE_SOFTSERIAL) +#define CURRENT_METER_SCALE 250 + +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0x0064 + +#define MAX_PWM_OUTPUT_PORTS 8 diff --git a/src/main/target/FLYWOOF411/target.c b/src/main/target/FLYWOOF411/target.c index 965974162b0..3946ad0b404 100644 --- a/src/main/target/FLYWOOF411/target.c +++ b/src/main/target/FLYWOOF411/target.c @@ -25,7 +25,7 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH1, PA2, TIM_USE_PPM, 0, 0), // PPM IN + // DEF_TIM(TIM9, CH1, PA2, TIM_USE_PPM, 0, 0), // PPM IN #ifdef FLYWOOF411_V2 DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1), // S1 - D(2,1) DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 - D(1,6) diff --git a/src/main/target/FLYWOOF411/target.h b/src/main/target/FLYWOOF411/target.h index 286b9863739..ed263d5ee3d 100644 --- a/src/main/target/FLYWOOF411/target.h +++ b/src/main/target/FLYWOOF411/target.h @@ -70,12 +70,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** SPI OSD ***************************** #define USE_MAX7456 diff --git a/src/main/target/FLYWOOF745/config.c b/src/main/target/FLYWOOF745/config.c index 07f6de46971..7dfe40728dd 100644 --- a/src/main/target/FLYWOOF745/config.c +++ b/src/main/target/FLYWOOF745/config.c @@ -22,7 +22,16 @@ #include "io/piniobox.h" +#include "drivers/pwm_output.h" +#include "drivers/pwm_mapping.h" + void targetConfiguration(void) { pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + + // Make sure S1-S4 default to Motors + + timerOverridesMutable(timer2id(TIM3))->outputMode = OUTPUT_MODE_MOTORS; + timerOverridesMutable(timer2id(TIM8))->outputMode = OUTPUT_MODE_MOTORS; + timerOverridesMutable(timer2id(TIM1))->outputMode = OUTPUT_MODE_MOTORS; } diff --git a/src/main/target/FLYWOOF745/target.c b/src/main/target/FLYWOOF745/target.c index 879b66d01fa..a82a708f51a 100644 --- a/src/main/target/FLYWOOF745/target.c +++ b/src/main/target/FLYWOOF745/target.c @@ -30,17 +30,17 @@ #include "drivers/pinio.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PE13, TIM_USE_PPM, 0, 1), // PPM, DMA2_ST6 + // DEF_TIM(TIM1, CH3, PE13, TIM_USE_PPM, 0, 1), // PPM, DMA2_ST6 - DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M1 , DMA1_ST7 - DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // M2 , DMA1_ST2 - DEF_TIM(TIM1, CH1, PE9, TIM_USE_OUTPUT_AUTO, 0, 2), // M3 , DMA2_ST2 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // M1 , DMA1_ST2 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // M2 , DMA2_ST7 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M3 , DMA1_ST7 DEF_TIM(TIM1, CH2, PE11, TIM_USE_OUTPUT_AUTO, 0, 1), // M4 , DMA2_ST4 - DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // M5 , DMA2_ST7 + DEF_TIM(TIM1, CH1, PE9, TIM_USE_OUTPUT_AUTO, 0, 2), // M5 , DMA2_ST2 DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0), // M6 , DMA1_ST1 DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // M7 , DMA1_ST4 DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // M8 , DMA1_ST5 - DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 0), // LED_STRIP, DMA1_ST0 + DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 0), // LED_STRIP, DMA1_ST0 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/FLYWOOF745/target.h b/src/main/target/FLYWOOF745/target.h index e0e012aa60f..c2b1937c611 100644 --- a/src/main/target/FLYWOOF745/target.h +++ b/src/main/target/FLYWOOF745/target.h @@ -140,15 +140,14 @@ #define USE_BARO #define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_BMP085 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 #define BARO_I2C_BUS BUS_I2C1 #define USE_MAG -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_MAG3110 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_ADC #define ADC_CHANNEL_1_PIN PC2 diff --git a/src/main/target/FLYWOOF7DUAL/target.c b/src/main/target/FLYWOOF7DUAL/target.c index d9d5482e3a5..28d5a2ee471 100644 --- a/src/main/target/FLYWOOF7DUAL/target.c +++ b/src/main/target/FLYWOOF7DUAL/target.c @@ -38,7 +38,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000_2, DEVHW_MPU6000, GYRO_2_SPI_BUS, GYRO BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500_2, DEVHW_MPU6500, GYRO_2_SPI_BUS, GYRO_2_CS_PIN, NONE, 1, DEVFLAGS_NONE, GYRO_2_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PPM, 0, 0), // PPM&SBUS + // DEF_TIM(TIM8, CH1, PC6, TIM_USE_PPM, 0, 0), // PPM&SBUS DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 - D(1,2) DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 - D(1,4) diff --git a/src/main/target/FLYWOOF7DUAL/target.h b/src/main/target/FLYWOOF7DUAL/target.h index 58630efe7e0..1a236505214 100644 --- a/src/main/target/FLYWOOF7DUAL/target.h +++ b/src/main/target/FLYWOOF7DUAL/target.h @@ -109,11 +109,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/FOXEERF405/target.c b/src/main/target/FOXEERF405/target.c index 1ad827bb5ca..ca6ebe3507e 100644 --- a/src/main/target/FOXEERF405/target.c +++ b/src/main/target/FOXEERF405/target.c @@ -22,7 +22,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 (1,7) DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 (1,4) diff --git a/src/main/target/FOXEERF405/target.h b/src/main/target/FOXEERF405/target.h index 8ee53eeb700..7f97e832b95 100644 --- a/src/main/target/FOXEERF405/target.h +++ b/src/main/target/FOXEERF405/target.h @@ -104,11 +104,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/FOXEERF722DUAL/config.c b/src/main/target/FOXEERF722DUAL/config.c new file mode 100644 index 00000000000..38763948c3f --- /dev/null +++ b/src/main/target/FOXEERF722DUAL/config.c @@ -0,0 +1,31 @@ +/* + * 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 "platform.h" + +#include "fc/fc_msp_box.h" + +#if defined(FOXEERF722V2) +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; +} +#endif diff --git a/src/main/target/FOXEERF722DUAL/target.c b/src/main/target/FOXEERF722DUAL/target.c index 1933a5134ee..e81731651e3 100644 --- a/src/main/target/FOXEERF722DUAL/target.c +++ b/src/main/target/FOXEERF722DUAL/target.c @@ -22,6 +22,7 @@ #include "drivers/timer.h" #include "drivers/sensor.h" #include "drivers/pwm_mapping.h" +#include "drivers/pinio.h" BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); #if defined(FOXEERF722DUAL) @@ -29,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, #endif timerHardware_t timerHardware[] = { - DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM&SBUS + // DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM&SBUS DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1), // S1 - D(2, 1, 6) #if defined(FOXEERF722V2) diff --git a/src/main/target/FOXEERF722DUAL/target.h b/src/main/target/FOXEERF722DUAL/target.h index 7698fe1abf9..1eafd86af9f 100644 --- a/src/main/target/FOXEERF722DUAL/target.h +++ b/src/main/target/FOXEERF722DUAL/target.h @@ -112,11 +112,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC @@ -151,3 +147,13 @@ #define TARGET_IO_PORTC 0xffff #define TARGET_IO_PORTD (BIT(2)) + +// *************** PINIO *************************** +#if defined(FOXEERF722V2) +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC6 // Enable GPS power +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED +#endif + + diff --git a/src/main/target/FOXEERF722V4/target.h b/src/main/target/FOXEERF722V4/target.h index 3c6ab0b2a77..4d92f85cdeb 100644 --- a/src/main/target/FOXEERF722V4/target.h +++ b/src/main/target/FOXEERF722V4/target.h @@ -124,11 +124,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define BNO055_I2C_BUS BUS_I2C1 diff --git a/src/main/target/FOXEERF745AIO/target.h b/src/main/target/FOXEERF745AIO/target.h index 60666b7611c..860ea18d861 100644 --- a/src/main/target/FOXEERF745AIO/target.h +++ b/src/main/target/FOXEERF745AIO/target.h @@ -112,8 +112,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/FOXEERH743/target.h b/src/main/target/FOXEERH743/target.h index ffb582ea9ad..f2e2f83eb40 100644 --- a/src/main/target/FOXEERH743/target.h +++ b/src/main/target/FOXEERH743/target.h @@ -83,13 +83,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -162,4 +156,4 @@ #define MAX_PWM_OUTPUT_PORTS 8 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/FRSKYPILOT/target.h b/src/main/target/FRSKYPILOT/target.h index d8100f2610c..19944ac24a7 100644 --- a/src/main/target/FRSKYPILOT/target.h +++ b/src/main/target/FRSKYPILOT/target.h @@ -103,12 +103,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C3 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C3 #define PITOT_I2C_BUS BUS_I2C3 diff --git a/src/main/target/FRSKY_ROVERF7/target.h b/src/main/target/FRSKY_ROVERF7/target.h index ea1c62e0d16..ff9672c7424 100755 --- a/src/main/target/FRSKY_ROVERF7/target.h +++ b/src/main/target/FRSKY_ROVERF7/target.h @@ -53,12 +53,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/FURYF4OSD/target.c b/src/main/target/FURYF4OSD/target.c index c820d0c378f..ef414db35e4 100644 --- a/src/main/target/FURYF4OSD/target.c +++ b/src/main/target/FURYF4OSD/target.c @@ -23,7 +23,7 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM8, CH4, PC9, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S1_OUT - D(1, 6, 3) DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT - D(1, 7, 5) DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_OUT - D(1, 2, 5) diff --git a/src/main/target/FURYF4OSD/target.h b/src/main/target/FURYF4OSD/target.h index 46eec2422fd..71abc9a8c68 100644 --- a/src/main/target/FURYF4OSD/target.h +++ b/src/main/target/FURYF4OSD/target.h @@ -45,6 +45,12 @@ #define MPU6000_CS_PIN PA4 #define MPU6000_SPI_BUS BUS_SPI1 +// ICM42605/ICM42688P +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW180_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + #define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT #define USE_SPI_DEVICE_3 #define SPI3_SCK_PIN PC10 @@ -112,21 +118,11 @@ #define USE_BARO #define BARO_I2C_BUS DEFAULT_I2C_BUS -#define USE_BARO_BMP280 -#define USE_BARO_MS5611 -#define USE_BARO_BMP085 -#define USE_BARO_DPS310 +#define USE_BARO_ALL #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS diff --git a/src/main/target/GEPRCF405/target.c b/src/main/target/GEPRCF405/target.c index 68a900898c1..c5f5791a92d 100644 --- a/src/main/target/GEPRCF405/target.c +++ b/src/main/target/GEPRCF405/target.c @@ -24,12 +24,8 @@ #include "drivers/timer.h" #include "drivers/timer_def.h" - - - - timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1), DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1), diff --git a/src/main/target/GEPRCF405/target.h b/src/main/target/GEPRCF405/target.h index 3a628ffe596..0b96d5b8b1e 100644 --- a/src/main/target/GEPRCF405/target.h +++ b/src/main/target/GEPRCF405/target.h @@ -61,21 +61,19 @@ #define USE_I2C_DEVICE_1 #define I2C1_SCL PB8 #define I2C1_SDA PB9 +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 #define USE_BARO -#define BARO_I2C_BUS BUS_I2C1 +#define BARO_I2C_BUS BUS_I2C2 #define USE_BARO_BMP280 #define USE_BARO_DPS310 #define USE_BARO_MS5611 #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/GEPRCF405_BT_HD/CMakeLists.txt b/src/main/target/GEPRCF405_BT_HD/CMakeLists.txt new file mode 100644 index 00000000000..70268ab5ad4 --- /dev/null +++ b/src/main/target/GEPRCF405_BT_HD/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(GEPRCF405_BT_HD) diff --git a/src/main/target/GEPRCF405_BT_HD/config.c b/src/main/target/GEPRCF405_BT_HD/config.c new file mode 100644 index 00000000000..f60fed2bee6 --- /dev/null +++ b/src/main/target/GEPRCF405_BT_HD/config.c @@ -0,0 +1,65 @@ +/* + * 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 + +#include + +#include "common/axis.h" + +#include "config/config_master.h" +#include "config/feature.h" + +#include "drivers/sensor.h" +#include "drivers/pwm_esc_detect.h" +#include "drivers/pwm_output.h" +#include "drivers/serial.h" + +#include "fc/rc_controls.h" + +#include "flight/failsafe.h" +#include "flight/mixer.h" +#include "flight/pid.h" + +#include "rx/rx.h" + +#include "io/serial.h" + +#include "sensors/battery.h" +#include "sensors/sensors.h" + +#include "telemetry/telemetry.h" + +#include "fc/fc_msp_box.h" + +#include "io/piniobox.h" + + +#define BLUETOOTH_MSP_BAUDRATE BAUD_115200 + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[2] = BOX_PERMANENT_ID_USER2; + + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART5)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART5)].msp_baudrateIndex = BLUETOOTH_MSP_BAUDRATE; + + // To improve backwards compatibility with INAV versions 6.x and older + timerOverridesMutable(timer2id(TIM4))->outputMode = OUTPUT_MODE_MOTORS; +} + diff --git a/src/main/target/GEPRCF405_BT_HD/target.c b/src/main/target/GEPRCF405_BT_HD/target.c new file mode 100644 index 00000000000..162c9cd15a0 --- /dev/null +++ b/src/main/target/GEPRCF405_BT_HD/target.c @@ -0,0 +1,44 @@ +/* + * 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/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1), + DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1), + DEF_TIM(TIM1, CH3, PA10, TIM_USE_OUTPUT_AUTO, 0, 1), + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 1, 0), + DEF_TIM(TIM2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 0, 1), + + DEF_TIM(TIM3, CH4, PB1, TIM_USE_LED, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + + diff --git a/src/main/target/GEPRCF405_BT_HD/target.h b/src/main/target/GEPRCF405_BT_HD/target.h new file mode 100644 index 00000000000..185a3970a11 --- /dev/null +++ b/src/main/target/GEPRCF405_BT_HD/target.h @@ -0,0 +1,179 @@ +/* + * 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 "GEPR" + +#define USBD_PRODUCT_STRING "GEPRCF405_BT_HD" + +#define LED0 PC14 +#define LED1 PC15 + + + +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** Gyro & ACC ********************** + +#define USE_SPI +#define USE_SPI_DEVICE_3 + +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW180_DEG +#define MPU6000_CS_PIN PA15 +#define MPU6000_SPI_BUS BUS_SPI3 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW180_DEG +#define BMI270_CS_PIN PA15 +#define BMI270_SPI_BUS BUS_SPI3 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW180_DEG +#define ICM42605_CS_PIN PA15 +#define ICM42605_SPI_BUS BUS_SPI3 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_DPS310 +#define USE_BARO_MS5611 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#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 +#define BNO055_I2C_BUS BUS_I2C1 + +// *************** FLASH ************************** +#define M25P16_CS_PIN PB12 +#define M25P16_SPI_BUS BUS_SPI2 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +// *************** OSD ***************************** +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI1 +#define MAX7456_CS_PIN PA4 + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PB7 +#define UART1_TX_PIN PB6 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PC11 +#define UART3_TX_PIN PC10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// ************PINIO to other +#define PINIO1_PIN PA13 + +// ************PINIO to disable BT***************** +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO2_PIN PA14 +#define PINIO2_FLAGS PINIO_FLAGS_INVERTED + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define RSSI_ADC_CHANNEL ADC_CHN_2 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) + + + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PB1 + + + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/GEPRCF722/target.c b/src/main/target/GEPRCF722/target.c index 851ae376a54..7061c09ffc5 100644 --- a/src/main/target/GEPRCF722/target.c +++ b/src/main/target/GEPRCF722/target.c @@ -27,7 +27,7 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), diff --git a/src/main/target/GEPRCF722/target.h b/src/main/target/GEPRCF722/target.h index bc08477c451..df7cc6d3eca 100644 --- a/src/main/target/GEPRCF722/target.h +++ b/src/main/target/GEPRCF722/target.h @@ -67,12 +67,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/GEPRCF722_BT_HD/target.c b/src/main/target/GEPRCF722_BT_HD/target.c index d1f902eb698..e7a6f1b332d 100644 --- a/src/main/target/GEPRCF722_BT_HD/target.c +++ b/src/main/target/GEPRCF722_BT_HD/target.c @@ -25,10 +25,8 @@ #include "drivers/timer.h" #include "drivers/sensor.h" - - timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), diff --git a/src/main/target/GEPRCF722_BT_HD/target.h b/src/main/target/GEPRCF722_BT_HD/target.h index ca32c210c64..5494ed83009 100644 --- a/src/main/target/GEPRCF722_BT_HD/target.h +++ b/src/main/target/GEPRCF722_BT_HD/target.h @@ -65,12 +65,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/GEPRC_F722_AIO/target.c b/src/main/target/GEPRC_F722_AIO/target.c index a8ee276fce0..60b6b359e89 100644 --- a/src/main/target/GEPRC_F722_AIO/target.c +++ b/src/main/target/GEPRC_F722_AIO/target.c @@ -27,7 +27,7 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), DEF_TIM(TIM8, CH4, PC9, TIM_USE_MOTOR, 0, 0), DEF_TIM(TIM8, CH3, PC8, TIM_USE_MOTOR, 0, 0), diff --git a/src/main/target/GEPRC_F722_AIO/target.h b/src/main/target/GEPRC_F722_AIO/target.h index ce2ebde6a54..f7ed46bd466 100644 --- a/src/main/target/GEPRC_F722_AIO/target.h +++ b/src/main/target/GEPRC_F722_AIO/target.h @@ -65,12 +65,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/HAKRCF405D/target.c b/src/main/target/HAKRCF405D/target.c index 664db476332..0679523028c 100644 --- a/src/main/target/HAKRCF405D/target.c +++ b/src/main/target/HAKRCF405D/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU600 timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 @@ -41,9 +41,9 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH1, PB8, TIM_USE_LED, 0, 0), // LED STRIP(2,6) - DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM, 0, 0), // PWM1 - DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0), // PWM2 - DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PWM3 + // DEF_TIM(TIM5, CH1, PA0, TIM_USE_PWM, 0, 0), // PWM1 + // DEF_TIM(TIM5, CH2, PA1, TIM_USE_PWM, 0, 0), // PWM2 + // DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PWM3 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/HAKRCF405D/target.h b/src/main/target/HAKRCF405D/target.h index 002fd191c3b..d47ec61dc99 100644 --- a/src/main/target/HAKRCF405D/target.h +++ b/src/main/target/HAKRCF405D/target.h @@ -127,11 +127,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/HAKRCF405V2/target.h b/src/main/target/HAKRCF405V2/target.h index 3e7b1420d10..85cc164230b 100644 --- a/src/main/target/HAKRCF405V2/target.h +++ b/src/main/target/HAKRCF405V2/target.h @@ -134,11 +134,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/HAKRCF411D/target.c b/src/main/target/HAKRCF411D/target.c index 1423d2d1992..f4fddb456ac 100644 --- a/src/main/target/HAKRCF411D/target.c +++ b/src/main/target/HAKRCF411D/target.c @@ -23,7 +23,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM IN + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM IN DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/HAKRCF411D/target.h b/src/main/target/HAKRCF411D/target.h index 96ea1a7c77e..5b3a479ed19 100644 --- a/src/main/target/HAKRCF411D/target.h +++ b/src/main/target/HAKRCF411D/target.h @@ -113,11 +113,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/HAKRCF722V2/target.c b/src/main/target/HAKRCF722V2/target.c index f09341633a9..02098ce755d 100644 --- a/src/main/target/HAKRCF722V2/target.c +++ b/src/main/target/HAKRCF722V2/target.c @@ -35,7 +35,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_bmi270_2, DEVHW_BMI270, GYRO_SPI_BUS, GYRO2_CS_PI timerHardware_t timerHardware[] = { DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 - DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1), // S3 DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1), // S4 DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 diff --git a/src/main/target/HAKRCF722V2/target.h b/src/main/target/HAKRCF722V2/target.h index 809f6ddb10f..52c07b6545a 100644 --- a/src/main/target/HAKRCF722V2/target.h +++ b/src/main/target/HAKRCF722V2/target.h @@ -87,7 +87,7 @@ #define USE_FLASH_M25P16 #define M25P16_CS_PIN SPI3_NSS_PIN #define M25P16_SPI_BUS BUS_SPI3 - +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT // *** UART *** #define USE_VCP @@ -137,11 +137,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/HAKRCKD722/target.c b/src/main/target/HAKRCKD722/target.c index 16757ff6416..e114f4410bf 100644 --- a/src/main/target/HAKRCKD722/target.c +++ b/src/main/target/HAKRCKD722/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42 BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/HAKRCKD722/target.h b/src/main/target/HAKRCKD722/target.h index 5b4869951de..0058b75d15b 100644 --- a/src/main/target/HAKRCKD722/target.h +++ b/src/main/target/HAKRCKD722/target.h @@ -102,12 +102,7 @@ // Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** Onboard Flash ***/ #define USE_SPI_DEVICE_3 diff --git a/src/main/target/HGLRCF722/target.c b/src/main/target/HGLRCF722/target.c index 1ebbbf63373..e0e4a73e2ad 100644 --- a/src/main/target/HGLRCF722/target.c +++ b/src/main/target/HGLRCF722/target.c @@ -47,8 +47,8 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 UP1-6 D(1, 3, 2) DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 2), // LED D(2, 6, 0) - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM, RX2 - DEF_TIM(TIM5, CH3, PA2, TIM_USE_PWM, 0, 0), // TX2 & softserial1 + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM, RX2 + // DEF_TIM(TIM5, CH3, PA2, TIM_USE_PWM, 0, 0), // TX2 & softserial1 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/HGLRCF722/target.h b/src/main/target/HGLRCF722/target.h index 3cf2986f75d..348f30d2416 100644 --- a/src/main/target/HGLRCF722/target.h +++ b/src/main/target/HGLRCF722/target.h @@ -72,13 +72,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/IFLIGHTF4_SUCCEXD/target.c b/src/main/target/IFLIGHTF4_SUCCEXD/target.c index ad9ab68c9ea..b79bc160750 100644 --- a/src/main/target/IFLIGHTF4_SUCCEXD/target.c +++ b/src/main/target/IFLIGHTF4_SUCCEXD/target.c @@ -24,7 +24,7 @@ #include "drivers/pinio.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), DEF_TIM(TIM5, CH1, PA0, TIM_USE_MOTOR, 0, 0), DEF_TIM(TIM2, CH3, PB10, TIM_USE_MOTOR, 0, 0), diff --git a/src/main/target/IFLIGHTF4_SUCCEXD/target.h b/src/main/target/IFLIGHTF4_SUCCEXD/target.h index 2d9d7bb5353..6ba059bb63c 100644 --- a/src/main/target/IFLIGHTF4_SUCCEXD/target.h +++ b/src/main/target/IFLIGHTF4_SUCCEXD/target.h @@ -97,13 +97,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/IFLIGHTF4_TWING/target.c b/src/main/target/IFLIGHTF4_TWING/target.c index 87227cf3b04..fcf8b09a85d 100644 --- a/src/main/target/IFLIGHTF4_TWING/target.c +++ b/src/main/target/IFLIGHTF4_TWING/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_imu0, DEVHW_MPU6500, MPU6500_0_SPI_BUS, MPU6 BUSDEV_REGISTER_SPI_TAG(busdev_imu1, DEVHW_MPU6500, MPU6500_1_SPI_BUS, MPU6500_1_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_1_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM // Motors DEF_TIM(TIM1, CH2N, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT D2_ST6 diff --git a/src/main/target/IFLIGHTF4_TWING/target.h b/src/main/target/IFLIGHTF4_TWING/target.h index 77dd3992e01..e0afa9aab58 100644 --- a/src/main/target/IFLIGHTF4_TWING/target.h +++ b/src/main/target/IFLIGHTF4_TWING/target.h @@ -59,12 +59,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/IFLIGHTF7_TWING/target.c b/src/main/target/IFLIGHTF7_TWING/target.c index 6876f07b204..b04f6ee8d32 100644 --- a/src/main/target/IFLIGHTF7_TWING/target.c +++ b/src/main/target/IFLIGHTF7_TWING/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_imu0, DEVHW_MPU6500, MPU6500_0_SPI_BUS, MPU6 BUSDEV_REGISTER_SPI_TAG(busdev_imu1, DEVHW_MPU6500, MPU6500_1_SPI_BUS, MPU6500_1_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_1_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), diff --git a/src/main/target/IFLIGHTF7_TWING/target.h b/src/main/target/IFLIGHTF7_TWING/target.h index 7bfbb0bbc55..1240089c762 100644 --- a/src/main/target/IFLIGHTF7_TWING/target.h +++ b/src/main/target/IFLIGHTF7_TWING/target.h @@ -56,17 +56,12 @@ #define USE_BARO #define BARO_I2C_BUS BUS_I2C2 -#define USE_BARO_BMP280 -#define USE_BARO_DPS310 +#define USE_BARO_ALL + #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/IFLIGHT_2RAW_H743/CMakeLists.txt b/src/main/target/IFLIGHT_2RAW_H743/CMakeLists.txt new file mode 100644 index 00000000000..6a430dc6758 --- /dev/null +++ b/src/main/target/IFLIGHT_2RAW_H743/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32h743xi(IFLIGHT_2RAW_H743) diff --git a/src/main/target/IFLIGHT_2RAW_H743/config.c b/src/main/target/IFLIGHT_2RAW_H743/config.c new file mode 100644 index 00000000000..0f1fec5a816 --- /dev/null +++ b/src/main/target/IFLIGHT_2RAW_H743/config.c @@ -0,0 +1,31 @@ +/* + * 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 "platform.h" + +#include "fc/fc_msp_box.h" +#include "fc/config.h" + +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; +} diff --git a/src/main/target/IFLIGHT_2RAW_H743/target.c b/src/main/target/IFLIGHT_2RAW_H743/target.c new file mode 100644 index 00000000000..23dd0e0c37a --- /dev/null +++ b/src/main/target/IFLIGHT_2RAW_H743/target.c @@ -0,0 +1,49 @@ +/* + * 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), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 2), // S3 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 3), // S4 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 4), // S5 + DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 5), // S6 + + DEF_TIM(TIM4, CH1, PD12, TIM_USE_OUTPUT_AUTO, 0, 6), // S7 + DEF_TIM(TIM4, CH2, PD13, TIM_USE_OUTPUT_AUTO, 0, 7), // S8 + DEF_TIM(TIM4, CH3, PD14, TIM_USE_OUTPUT_AUTO, 0, 0), // S9 + DEF_TIM(TIM4, CH4, PD15, TIM_USE_OUTPUT_AUTO, 0, 0), // S10 DMA_NONE + + DEF_TIM(TIM15, CH1, PE5, TIM_USE_OUTPUT_AUTO, 0, 0), // S11 + DEF_TIM(TIM15, CH2, PE6, TIM_USE_OUTPUT_AUTO, 0, 0), // S12 DMA_NONE + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 9), // LED_2812 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/IFLIGHT_2RAW_H743/target.h b/src/main/target/IFLIGHT_2RAW_H743/target.h new file mode 100644 index 00000000000..d8a33a12ee1 --- /dev/null +++ b/src/main/target/IFLIGHT_2RAW_H743/target.h @@ -0,0 +1,167 @@ +/* + * 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 "2RH7" + +#define USBD_PRODUCT_STRING "IFLIGHT_2RAW_H743" + +#define LED0 PE3 +#define LED1 PE4 + +#define BEEPER PC9 +#define BEEPER_INVERTED + +// SPI Buses +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PD7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +// I2C +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 + +// Gyro +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PC15 + +// OSD +// #define USE_MAX7456 +// #define MAX7456_SPI_BUS BUS_SPI2 +// #define MAX7456_CS_PIN PB12 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C2 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 +#define RANGEFINDER_I2C_BUS BUS_I2C1 + +// *************** 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 PB9 +#define UART4_RX_PIN PB8 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define USE_UART7 +#define UART7_TX_PIN PE8 +#define UART7_RX_PIN PE7 + +#define USE_UART8 +#define UART8_TX_PIN PE1 +#define UART8_RX_PIN PE0 + +#define SERIAL_PORT_COUNT 8 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART6 + +// SD Card +#define USE_SDCARD +#define USE_SDCARD_SPI +#define SDCARD_SPI_BUS BUS_SPI3 +#define SDCARD_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +// 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 ADC_CHANNEL_4_PIN PC4 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 +#define AIRSPEED_ADC_CHANNEL ADC_CHN_4 + +#define VBAT_SCALE_DEFAULT 2100 + +// PINIO +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PD10 +#define PINIO2_PIN PD11 + +// *************** LEDSTRIP ************************ +// #define USE_LED_STRIP +// #define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) +#define CURRENT_METER_SCALE 250 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#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 12 +#define USE_DSHOT +#define USE_ESC_SENSOR + diff --git a/src/main/target/IFLIGHT_BLITZ_ATF435/CMakeLists.txt b/src/main/target/IFLIGHT_BLITZ_ATF435/CMakeLists.txt new file mode 100644 index 00000000000..c0136c9630c --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_ATF435/CMakeLists.txt @@ -0,0 +1 @@ +target_at32f43x_xGT7(IFLIGHT_BLITZ_ATF435) \ No newline at end of file diff --git a/src/main/target/IFLIGHT_BLITZ_ATF435/target.c b/src/main/target/IFLIGHT_BLITZ_ATF435/target.c new file mode 100644 index 00000000000..2de0fd50578 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_ATF435/target.c @@ -0,0 +1,50 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#include + +#include "platform.h" + +#include "drivers/bus.h" +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" + +timerHardware_t timerHardware[] = { + + DEF_TIM(TMR3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0,8), // S1 + DEF_TIM(TMR3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0,9), // S2 + DEF_TIM(TMR8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0,2), // S3 + DEF_TIM(TMR8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0,0), // S4 + + DEF_TIM(TMR4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0,11), // S5 + DEF_TIM(TMR4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0,10), // S6 + DEF_TIM(TMR2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 0,5), //S7 + DEF_TIM(TMR2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 0,6), //S8 + + DEF_TIM(TMR1, CH1, PA8, TIM_USE_LED, 0, 0), // LED STRIP +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + diff --git a/src/main/target/IFLIGHT_BLITZ_ATF435/target.h b/src/main/target/IFLIGHT_BLITZ_ATF435/target.h new file mode 100644 index 00000000000..b29112d5256 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_ATF435/target.h @@ -0,0 +1,164 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#pragma once + +#define TARGET_BOARD_IDENTIFIER "IAT4" + +#define USBD_PRODUCT_STRING "iFlight BLITZ ATF435" + +#define LED0 PC15 + +#define BEEPER PB2 +#define BEEPER_INVERTED + + +// Buses + +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 +// #define USE_I2C_PULLUP + +#define DEFAULT_I2C_BUS BUS_I2C1 + +// Gyro + +// BMI270 +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW0_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PA4 + +// ICM42605/ICM42688P +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + + +// Other sensors + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +// OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// Flash + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PA15 + +#define USE_FLASH_W25N01G +#define W25N01G_SPI_BUS BUS_SPI3 +#define W25N01G_CS_PIN PA15 + +// UARTs +#define USE_VCP +// #define USB_DETECT_PIN PC5 +// #define USE_USB_DETECT + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PC11 +#define UART3_TX_PIN PC10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 + +#define ADC1_DMA_STREAM DMA2_CHANNEL5 + +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY| FEATURE_VBAT | FEATURE_OSD ) + +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff +#define TARGET_IO_PORTE BIT(2) + +#define MAX_PWM_OUTPUT_PORTS 4 +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/IFLIGHT_BLITZ_F722/target.h b/src/main/target/IFLIGHT_BLITZ_F722/target.h index 370cea22672..0ced96ad5fb 100644 --- a/src/main/target/IFLIGHT_BLITZ_F722/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F722/target.h @@ -56,13 +56,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/IFLIGHT_BLITZ_F722_X1/CMakeLists.txt b/src/main/target/IFLIGHT_BLITZ_F722_X1/CMakeLists.txt new file mode 100644 index 00000000000..2d52bdb52e0 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_F722_X1/CMakeLists.txt @@ -0,0 +1,3 @@ +target_stm32f722xe(IFLIGHT_BLITZ_F722_X1) +target_stm32f722xe(IFLIGHT_BLITZ_F722_X1_OSD) + diff --git a/src/main/target/IFLIGHT_BLITZ_F722_X1/config.c b/src/main/target/IFLIGHT_BLITZ_F722_X1/config.c new file mode 100644 index 00000000000..b8796a0d2f3 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_F722_X1/config.c @@ -0,0 +1,29 @@ +/* + * 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 "platform.h" + +#include "config/config_master.h" +#include "config/feature.h" +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; +} diff --git a/src/main/target/IFLIGHT_BLITZ_F722_X1/target.c b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.c new file mode 100644 index 00000000000..5a20c88ff22 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.c @@ -0,0 +1,37 @@ +/* + * 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" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DMA1_S2_CH5 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 DMA1_S7_CH5 + + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S3 DMA2_S4_CH7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 DMA2_S7_CH7 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 DMA1_S0_CH2 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 DMA1_S3_CH2 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // WS2812B +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h new file mode 100644 index 00000000000..03196254420 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h @@ -0,0 +1,167 @@ +/* + * 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 "I7X1" +#define USBD_PRODUCT_STRING "IFLIGHT_BLITZ_F722_X1" + +#define LED0 PC15 +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** SPI1 Gyro & ACC ******************* +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW90_DEG_FLIP +#define BMI270_CS_PIN PA4 +#define BMI270_SPI_BUS BUS_SPI1 + +// ICM42605 +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG_FLIP +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C2 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C2 + +#define PITOT_I2C_BUS BUS_I2C2 + +#define RANGEFINDER_I2C_BUS BUS_I2C2 + +// *************** SPI2 OSD*********************** +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_OSD + +#ifdef IFLIGHT_BLITZ_F722_X1_OSD + #define USE_MAX7456 + #define MAX7456_SPI_BUS BUS_SPI2 + #define MAX7456_CS_PIN PB12 +#endif + +// *************** SPI3 Flash *********************** +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +#define USE_FLASHFS + +#define USE_FLASH_W25N01G +#define W25N01G_SPI_BUS BUS_SPI3 +#define W25N01G_CS_PIN PA15 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** UART ***************************** +#define USE_VCP +#define USB_DETECT_PIN PB2 +#define USE_USB_DETECT + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PC11 +#define UART3_TX_PIN PC10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 + +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL) +#define CURRENT_METER_SCALE 200 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 7 +#define USE_DSHOT +#define USE_SERIALSHOT +#define USE_ESC_SENSOR + +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC0 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED +#define PINIO2_PIN PC14 \ No newline at end of file diff --git a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.c b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.c index 54ba97a4905..e46c36e0507 100644 --- a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.c +++ b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.c @@ -30,7 +30,7 @@ //BUSDEV_REGISTER_SPI_TAG(busdev_icm42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM2, CH2, PB3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PB4, TIM_USE_MOTOR, 0, 0), // S1 DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR, 0, 0), // S2 diff --git a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h index c94da102b11..69ea37e5357 100644 --- a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h @@ -85,12 +85,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.c b/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.c index b4b6f6de0fb..664ff354b4c 100644 --- a/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.c +++ b/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.c @@ -30,7 +30,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_ BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S1 DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.h b/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.h index 03e7d0e2f40..a5361a51904 100644 --- a/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F7_PRO/target.h @@ -62,12 +62,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/IFLIGHT_BLITZ_H7_PRO/CMakeLists.txt b/src/main/target/IFLIGHT_BLITZ_H7_PRO/CMakeLists.txt new file mode 100644 index 00000000000..b8fc79235d4 --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_H7_PRO/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32h743xi(IFLIGHT_BLITZ_H7_PRO) \ No newline at end of file diff --git a/src/main/target/IFLIGHT_BLITZ_H7_PRO/config.c b/src/main/target/IFLIGHT_BLITZ_H7_PRO/config.c new file mode 100644 index 00000000000..1065971614a --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_H7_PRO/config.c @@ -0,0 +1,32 @@ +/* + * 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 "platform.h" + +#include "fc/fc_msp_box.h" +#include "fc/config.h" + +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; + beeperConfigMutable()->pwmMode = true; +} diff --git a/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.c b/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.c new file mode 100644 index 00000000000..23dd0e0c37a --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.c @@ -0,0 +1,49 @@ +/* + * 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), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 2), // S3 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 3), // S4 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 4), // S5 + DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 5), // S6 + + DEF_TIM(TIM4, CH1, PD12, TIM_USE_OUTPUT_AUTO, 0, 6), // S7 + DEF_TIM(TIM4, CH2, PD13, TIM_USE_OUTPUT_AUTO, 0, 7), // S8 + DEF_TIM(TIM4, CH3, PD14, TIM_USE_OUTPUT_AUTO, 0, 0), // S9 + DEF_TIM(TIM4, CH4, PD15, TIM_USE_OUTPUT_AUTO, 0, 0), // S10 DMA_NONE + + DEF_TIM(TIM15, CH1, PE5, TIM_USE_OUTPUT_AUTO, 0, 0), // S11 + DEF_TIM(TIM15, CH2, PE6, TIM_USE_OUTPUT_AUTO, 0, 0), // S12 DMA_NONE + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 9), // LED_2812 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.h b/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.h new file mode 100644 index 00000000000..23fde63466c --- /dev/null +++ b/src/main/target/IFLIGHT_BLITZ_H7_PRO/target.h @@ -0,0 +1,176 @@ +/* + * 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 "IB7P" + +#define USBD_PRODUCT_STRING "IFLIGHT_BLITZ_H7_PRO" + +#define USE_TARGET_CONFIG + +#define LED0 PE3 +#define LED1 PE4 + +#define BEEPER PA15 +#define BEEPER_INVERTED + +// SPI1 +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PD7 + +// SPI2 +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +// SPI3 - not connected +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +// SPI4 - GYRO2 not used in INAV +#define USE_SPI_DEVICE_4 +#define SPI4_SCK_PIN PE12 +#define SPI4_MISO_PIN PE13 +#define SPI4_MOSI_PIN PE14 + +// ICM42605 +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PC15 + +// OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// I2C +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C2 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C2 +#define PITOT_I2C_BUS BUS_I2C2 + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS BUS_I2C1 + +// *************** 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 PB9 +#define UART4_RX_PIN PB8 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define USE_UART7 +#define UART7_TX_PIN PE8 +#define UART7_RX_PIN PE7 + +#define USE_UART8 +#define UART8_TX_PIN PE1 +#define UART8_RX_PIN PE0 + +#define SERIAL_PORT_COUNT 8 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART6 + +// *************** SDIO SD BLACKBOX******************* +#define USE_SDCARD +#define USE_SDCARD_SDIO +#define SDCARD_SDIO_DEVICE SDIODEV_1 +#define SDCARD_SDIO_4BIT + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 + +#define ADC_CHANNEL_1_PIN PC0 //ADC123 VBAT1 +#define ADC_CHANNEL_2_PIN PC1 //ADC123 CURR1 +#define ADC_CHANNEL_3_PIN PC5 //ADC12 RSSI +#define ADC_CHANNEL_4_PIN PC4 //ADC12 AirS + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 +#define AIRSPEED_ADC_CHANNEL ADC_CHN_4 + +// *************** PINIO *************************** +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PD10 // VTX power switcher +#define PINIO2_PIN PD11 // 2xCamera switcher + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) +#define CURRENT_METER_SCALE 212 +#define VBAT_SCALE_DEFAULT 1135 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#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 12 +#define USE_DSHOT +#define USE_ESC_SENSOR \ No newline at end of file diff --git a/src/main/target/IFLIGHT_H743_AIO_V2/target.h b/src/main/target/IFLIGHT_H743_AIO_V2/target.h index 60a235e08c4..c3900376686 100644 --- a/src/main/target/IFLIGHT_H743_AIO_V2/target.h +++ b/src/main/target/IFLIGHT_H743_AIO_V2/target.h @@ -66,13 +66,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/IFLIGHT_JBF7PRO/target.c b/src/main/target/IFLIGHT_JBF7PRO/target.c index 676c3d6dae3..dcf7ae64385 100644 --- a/src/main/target/IFLIGHT_JBF7PRO/target.c +++ b/src/main/target/IFLIGHT_JBF7PRO/target.c @@ -25,7 +25,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/IFLIGHT_JBF7PRO/target.h b/src/main/target/IFLIGHT_JBF7PRO/target.h index 8c2dfd5a765..570e1750e42 100644 --- a/src/main/target/IFLIGHT_JBF7PRO/target.h +++ b/src/main/target/IFLIGHT_JBF7PRO/target.h @@ -59,12 +59,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/JHEH7AIO/target.h b/src/main/target/JHEH7AIO/target.h index 2290b828de0..00ecf856e23 100644 --- a/src/main/target/JHEH7AIO/target.h +++ b/src/main/target/JHEH7AIO/target.h @@ -55,13 +55,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -166,4 +160,4 @@ #define MAX_PWM_OUTPUT_PORTS 4 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/JHEMCUF405/CMakeLists.txt b/src/main/target/JHEMCUF405/CMakeLists.txt new file mode 100644 index 00000000000..1c8253eb464 --- /dev/null +++ b/src/main/target/JHEMCUF405/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(JHEMCUF405) diff --git a/src/main/target/JHEMCUF405/target.c b/src/main/target/JHEMCUF405/target.c new file mode 100644 index 00000000000..463a5cbc0e6 --- /dev/null +++ b/src/main/target/JHEMCUF405/target.c @@ -0,0 +1,39 @@ +/* + * 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 + +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 D(1,3,2) + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 D(1,0,2) + DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S3 D(1,7,5) + DEF_TIM(TIM2, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 D(1,2,5) + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 D(2,4,7) + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 D(2,7,7) + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + + DEF_TIM(TIM1, CH2, PA9, TIM_USE_LED, 0, 0), // 2812LED D(1,5,3) + DEF_TIM(TIM10, CH1, PB8, TIM_USE_PPM, 0, 0), // PPM +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/JHEMCUF405/target.h b/src/main/target/JHEMCUF405/target.h new file mode 100644 index 00000000000..6a5b2f52ab4 --- /dev/null +++ b/src/main/target/JHEMCUF405/target.h @@ -0,0 +1,164 @@ +/* + * 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 "JH45" +#define USBD_PRODUCT_STRING "JHEMCUF405" + +#define LED0 PC14 //Green +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** SPI1 Gyro & ACC ******************* +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW90_DEG +#define MPU6000_CS_PIN PB12 +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW90_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PB12 +#define BMI270_EXTI_PIN GYRO_INT_EXTI + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG +#define ICM42605_CS_PIN PB12 +#define ICM42605_SPI_BUS BUS_SPI1 + +#define USE_EXTI +#define GYRO_INT_EXTI PB13 +#define USE_MPU_DATA_READY_SIGNAL + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_BMP085 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_AK8963 +#define USE_MAG_AK8975 +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_MAG3110 +#define USE_MAG_LIS3MDL + +#define USE_RANGEFINDER +#define USE_RANGEFINDER_HCSR04_I2C +#define RANGEFINDER_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 +#define TEMPERATURE_I2C_BUS BUS_I2C1 + +// *************** SPI2 OSD *************************** +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +#define USE_OSD +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI3 +#define MAX7456_CS_PIN PB14 + +// *************** Onboard flash ******************** +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_CS_PIN PB3 +#define M25P16_SPI_BUS BUS_SPI3 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** UART ***************************** +#define USB_IO +#define USE_VCP +#define VBUS_SENSING_PIN PA8 +#define VBUS_SENSING_ENABLED + +#define USE_UART1 +#define UART1_TX_PIN PB6 +#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 PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define SERIAL_PORT_COUNT 6 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC *************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC3 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +// *************** LED2812 ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA9 + +// *************** OTHERS ************************* +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY | FEATURE_SOFTSERIAL) +#define CURRENT_METER_SCALE 250 + +#define USE_DSHOT +#define USE_ESC_SENSOR + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 8 diff --git a/src/main/target/JHEMCUF405WING/CMakeLists.txt b/src/main/target/JHEMCUF405WING/CMakeLists.txt new file mode 100644 index 00000000000..fb99881c9bd --- /dev/null +++ b/src/main/target/JHEMCUF405WING/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(JHEMCUF405WING) diff --git a/src/main/target/JHEMCUF405WING/config.c b/src/main/target/JHEMCUF405WING/config.c new file mode 100644 index 00000000000..07f44ab29f7 --- /dev/null +++ b/src/main/target/JHEMCUF405WING/config.c @@ -0,0 +1,42 @@ +/* + * This file is part of INAV Project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include + +#include "platform.h" + +#include "fc/fc_msp_box.h" +#include "fc/config.h" +#include "io/serial.h" +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_RX_SERIAL; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART3)].functionMask = FUNCTION_GPS; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART6)].functionMask = FUNCTION_MSP; + + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; +} diff --git a/src/main/target/JHEMCUF405WING/target.c b/src/main/target/JHEMCUF405WING/target.c new file mode 100644 index 00000000000..e8187f936b2 --- /dev/null +++ b/src/main/target/JHEMCUF405WING/target.c @@ -0,0 +1,47 @@ +/* + * 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 +#include + +#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(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 1, 0), // S1 D(1,3,2) + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 1, 0), // S2 D(1,0,2) + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 1, 0), // S3 D(1,7,5) + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 1, 0), // S4 D(1,2,5) + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 1, 0), // S5 D(2,4,7) + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 1, 0), // S6 D(2,7,7) + + DEF_TIM(TIM8, CH2N,PB14, TIM_USE_OUTPUT_AUTO, 1, 0), // S7 + DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 1, 0), // S8 + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 1, 0), // S9 + DEF_TIM(TIM2, CH4, PB11, TIM_USE_OUTPUT_AUTO, 1, 0), // S10 + DEF_TIM(TIM12, CH2,PB15, TIM_USE_OUTPUT_AUTO, 1, 0), // S11 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // 2812LED + DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), // TX2 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/JHEMCUF405WING/target.h b/src/main/target/JHEMCUF405WING/target.h new file mode 100644 index 00000000000..fd64ff153d6 --- /dev/null +++ b/src/main/target/JHEMCUF405WING/target.h @@ -0,0 +1,163 @@ +/* + * 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 USE_TARGET_CONFIG + +#define TARGET_BOARD_IDENTIFIER "JH45" +#define USBD_PRODUCT_STRING "JHEMCUF405WING" + +// LEDs +#define LED0 PA14 //Blue +#define LED1 PA13 //Green + +// Beeper +#define BEEPER PC15 +#define BEEPER_INVERTED + +// SPI1 +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +// SPI2 +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PC2 +#define SPI2_MOSI_PIN PC3 + +// SPI3 +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +// Serial ports +#define USE_VCP + +#define USE_UART1 +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define USE_UART2 +#define UART2_TX_PIN PA2 +#define UART2_RX_PIN PA3 + +#define USE_UART3 +#define UART3_TX_PIN PC10 +#define UART3_RX_PIN PC11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +// Optional Softserial on UART2 TX Pin PA2 +#define USE_SOFTSERIAL1 +#define SOFTSERIAL_1_TX_PIN PA2 +#define SOFTSERIAL_1_RX_PIN PA2 + +#define SERIAL_PORT_COUNT 8 + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +// ICM42605/ICM42688P +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 + +// Baro +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +// Mag +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +#define RANGEFINDER_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 +#define TEMPERATURE_I2C_BUS BUS_I2C1 + +// OSD +#define USE_MAX7456 +#define MAX7456_CS_PIN PB12 +#define MAX7456_SPI_BUS BUS_SPI2 + +// SD Card +#define USE_SDCARD +#define USE_SDCARD_SPI +#define SDCARD_SPI_BUS BUS_SPI3 +#define SDCARD_CS_PIN PC14 + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF +#define SERIALRX_UART SERIAL_PORT_USART1 + +// ADC +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC1 +#define ADC_CHANNEL_3_PIN PC5 +#define ADC_CHANNEL_4_PIN PC4 +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_4 +#define AIRSPEED_ADC_CHANNEL ADC_CHN_3 + +// LED2812 +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +// PINIO +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 // 2xCamera switcher + +// OTHERS +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TELEMETRY | FEATURE_BLACKBOX | FEATURE_AIRMODE) +#define CURRENT_METER_SCALE 175 + +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + +#define MAX_PWM_OUTPUT_PORTS 11 \ No newline at end of file diff --git a/src/main/target/JHEMCUF722/CMakeLists.txt b/src/main/target/JHEMCUF722/CMakeLists.txt new file mode 100644 index 00000000000..abbb496eafd --- /dev/null +++ b/src/main/target/JHEMCUF722/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(JHEMCUF722) diff --git a/src/main/target/JHEMCUF722/config.c b/src/main/target/JHEMCUF722/config.c new file mode 100644 index 00000000000..caaec66ef23 --- /dev/null +++ b/src/main/target/JHEMCUF722/config.c @@ -0,0 +1,28 @@ +/* + * 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 "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; // VTX power switch + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; +} diff --git a/src/main/target/JHEMCUF722/target.c b/src/main/target/JHEMCUF722/target.c new file mode 100644 index 00000000000..68450216a0e --- /dev/null +++ b/src/main/target/JHEMCUF722/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" + +BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0 ), //PPM&SBUS + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 DMA1_S7_CH5 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 - D(1,2) + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 - D(1,4) + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 - D(1,6) + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 - D(2,1) + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 - D(2,4) + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED STRIP(1,5) +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/JHEMCUF722/target.h b/src/main/target/JHEMCUF722/target.h new file mode 100644 index 00000000000..9d34e5c8201 --- /dev/null +++ b/src/main/target/JHEMCUF722/target.h @@ -0,0 +1,182 @@ +/* + * 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 "JHF7" +#define USBD_PRODUCT_STRING "JHEMCUF722" + +#define LED0 PA15 + +#define USE_BEEPER +#define BEEPER PC15 +#define BEEPER_INVERTED + +// PINIO +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC14 +#define PINIO2_PIN PB9 + +// UART +#define USB_IO +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +// Gyro & Acc +#define USE_TARGET_IMU_HARDWARE_DESCRIPTORS + +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC3 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW90_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PA4 +#define BMI270_EXTI_PIN PC3 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW90_DEG +#define MPU6000_SPI_BUS BUS_SPI1 +#define MPU6000_CS_PIN PA4 +#define MPU6000_EXTI_PIN PC3 + +// I2C (Baro & Mag) +#define USE_I2C + +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +// Baro +#define USE_BARO +#define USE_BARO_BMP280 +#define USE_BARO_MS5611 +#define USE_BARO_DPS310 +#define USE_BARO_SPL06 +#define BARO_I2C_BUS BUS_I2C1 + +// Mag +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_IST8308 +#define USE_MAG_MAG3110 +#define USE_MAG_LIS3MDL + +// Onboard Flash +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB5 + +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PC13 + +#define W25N01G_SPI_BUS BUS_SPI3 +#define W25N01G_CS_PIN PC13 + +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define USE_FLASH_W25N01G +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// OSD +#define USE_OSD +#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 + +// ADC +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC2 +#define ADC_CHANNEL_3_PIN PC0 + +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +// LED +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +// Optical Flow & Lidar +#define USE_RANGEFINDER +#define USE_RANGEFINDER_MSP +#define USE_OPFLOW +#define USE_OPFLOW_MSP + +// Misc +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +#define USE_DSHOT +#define USE_ESC_SENSOR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define SERIALRX_UART SERIAL_PORT_USART2 +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS + +#define MAX_PWM_OUTPUT_PORTS 6 + +#define CURRENT_METER_SCALE 250 + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) diff --git a/src/main/target/JHEMCUF745/CMakeLists.txt b/src/main/target/JHEMCUF745/CMakeLists.txt new file mode 100644 index 00000000000..5f5a85e7c5d --- /dev/null +++ b/src/main/target/JHEMCUF745/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f745xg(JHEMCUF745) diff --git a/src/main/target/JHEMCUF745/config.c b/src/main/target/JHEMCUF745/config.c new file mode 100644 index 00000000000..fb2fe04f963 --- /dev/null +++ b/src/main/target/JHEMCUF745/config.c @@ -0,0 +1,29 @@ +/* + * 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 + +#include + +#include "drivers/pwm_mapping.h" + +void targetConfiguration(void) +{ + timerOverridesMutable(timer2id(TIM1))->outputMode = OUTPUT_MODE_MOTORS; + timerOverridesMutable(timer2id(TIM3))->outputMode = OUTPUT_MODE_MOTORS; +} diff --git a/src/main/target/JHEMCUF745/target.c b/src/main/target/JHEMCUF745/target.c new file mode 100644 index 00000000000..f603cbe43be --- /dev/null +++ b/src/main/target/JHEMCUF745/target.c @@ -0,0 +1,44 @@ +/* + * This file is part of INAV. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute 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. + * + * This file 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 this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include "drivers/io.h" +#include "drivers/pwm_mapping.h" +#include "drivers/timer.h" +#include "drivers/bus.h" +#include "drivers/pinio.h" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M1, DMA1_ST7 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // M2, DMA1_ST2 + DEF_TIM(TIM1, CH1, PE9, TIM_USE_OUTPUT_AUTO, 0, 0), // M3 + DEF_TIM(TIM1, CH2, PE11, TIM_USE_OUTPUT_AUTO, 0, 1), // M4, DMA2_ST4 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // M5, DMA2_ST7 + DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0), // M6, DMA1_ST1 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 0), // LED_STRIP, DMA1_ST0 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/JHEMCUF745/target.h b/src/main/target/JHEMCUF745/target.h new file mode 100644 index 00000000000..dfd45749d2d --- /dev/null +++ b/src/main/target/JHEMCUF745/target.h @@ -0,0 +1,157 @@ +/* + * This file is part of INAV. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software 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 and Betaflight are distributed in the hope that they + * 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 this software. + * + * If not, see . + */ + +#pragma once + +#define TARGET_BOARD_IDENTIFIER "JHF7" +#define USBD_PRODUCT_STRING "JHEMCUF745" + +#define LED0 PA2 + +#define BEEPER PD15 +#define BEEPER_INVERTED + +#define USE_DSHOT +#define USE_DSHOT_DMAR +#define USE_ESC_SENSOR + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG +#define GYRO_INT_EXTI PE1 +#define MPU6000_CS_PIN SPI4_NSS_PIN +#define MPU6000_SPI_BUS BUS_SPI4 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN SPI4_NSS_PIN +#define ICM42605_SPI_BUS BUS_SPI4 +#define ICM42605_EXTI_PIN PE1 + +#define USB_IO +#define USE_VCP +#define VBUS_SENSING_ENABLED +#define VBUS_SENSING_PIN PA8 + +#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 PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define USE_UART7 +#define UART7_RX_PIN PE7 +#define UART7_TX_PIN PE8 + +#define SERIAL_PORT_COUNT 8 // VCP,UART1,UART2,UART3,UART4,UART5,UART6 + +#define USE_SPI +#define USE_SPI_DEVICE_1 // FLASH +#define USE_SPI_DEVICE_2 // OSD +#define USE_SPI_DEVICE_4 // ICM20689 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define SPI2_NSS_PIN PB12 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define SPI4_NSS_PIN PE4 +#define SPI4_SCK_PIN PE2 +#define SPI4_MISO_PIN PE5 +#define SPI4_MOSI_PIN PE6 + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN + +#define M25P16_CS_PIN SPI1_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI1 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +// External I2C bus is the same as interal one +#define MAG_I2C_BUS BUS_I2C1 +#define TEMPERATURE_I2C_BUS BUS_I2C1 +#define RANGEFINDER_I2C_BUS BUS_I2C1 +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define USE_BARO_ALL +#define BARO_I2C_BUS BUS_I2C1 + +#define USE_MAG +#define USE_MAG_ALL + +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC3 +#define ADC_CHANNEL_3_PIN PC5 + +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_1 +#define VBAT_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_VBAT | FEATURE_BLACKBOX) +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_UART SERIAL_PORT_USART1 +#define SERIALRX_PROVIDER SERIALRX_SBUS + +#define USE_LED_STRIP +#define WS2811_PIN PD12 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#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 diff --git a/src/main/target/JHEMCUH743HD/CMakeLists.txt b/src/main/target/JHEMCUH743HD/CMakeLists.txt new file mode 100644 index 00000000000..b0192886d6c --- /dev/null +++ b/src/main/target/JHEMCUH743HD/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32h743xi(JHEMCUH743HD) \ No newline at end of file diff --git a/src/main/target/JHEMCUH743HD/config.c b/src/main/target/JHEMCUH743HD/config.c new file mode 100644 index 00000000000..4f0aea919e7 --- /dev/null +++ b/src/main/target/JHEMCUH743HD/config.c @@ -0,0 +1,66 @@ +/* + * 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 + +#include "common/axis.h" + +#include "config/config_master.h" +#include "config/feature.h" + +#include "drivers/sensor.h" +#include "drivers/pwm_esc_detect.h" +#include "drivers/pwm_output.h" +#include "drivers/serial.h" + +#include "fc/rc_controls.h" + +#include "flight/failsafe.h" +#include "flight/mixer.h" +#include "flight/pid.h" + +#include "rx/rx.h" + +#include "io/serial.h" + +#include "sensors/battery.h" +#include "sensors/sensors.h" + +#include "telemetry/telemetry.h" + +#include "io/piniobox.h" + +void targetConfiguration(void) +{ + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + pinioBoxConfigMutable()->permanentId[1] = BOX_PERMANENT_ID_USER2; + + + /* + * UART1 is SerialRX + */ + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_RX_SERIAL; + + /* + * Enable MSP at 115200 at UART4 + */ + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART4)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART4)].msp_baudrateIndex = BAUD_115200; +} diff --git a/src/main/target/JHEMCUH743HD/target.c b/src/main/target/JHEMCUH743HD/target.c new file mode 100644 index 00000000000..adb753b9d17 --- /dev/null +++ b/src/main/target/JHEMCUH743HD/target.c @@ -0,0 +1,49 @@ +/* + * 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" + +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); + + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 2), // S3 + DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 3), // S4 + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 4), // S5 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 5), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 6), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 7), // S8 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 9), // LED_2812 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/JHEMCUH743HD/target.h b/src/main/target/JHEMCUH743HD/target.h new file mode 100644 index 00000000000..92300b52564 --- /dev/null +++ b/src/main/target/JHEMCUH743HD/target.h @@ -0,0 +1,205 @@ +/* + * 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 "JHEH743HD" +#define USBD_PRODUCT_STRING "JHEMCUH743HD" + +#define USE_TARGET_CONFIG + +#define LED0 PE5 +#define LED1 PE4 + +#define BEEPER PE3 +#define BEEPER_INVERTED + +// *************** IMU generic *********************** +#define USE_DUAL_GYRO +#define USE_TARGET_IMU_HARDWARE_DESCRIPTORS + +// *************** SPI1 IMU0 MPU6000 **************** +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW180_DEG +#define MPU6000_SPI_BUS BUS_SPI1 +#define MPU6000_CS_PIN PA4 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW180_DEG +#define BMI270_SPI_BUS BUS_SPI1 +#define BMI270_CS_PIN PA4 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW180_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + +// *************** SPI2 OSD *********************** +#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 + +// *************** SPI3 FLASH *********************** +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB2 +#define SPI3_NSS_PIN PA15 +#define SPI3_SCK_AF GPIO_AF6_SPI3 +#define SPI3_MISO_AF GPIO_AF6_SPI3 +#define SPI3_MOSI_AF GPIO_AF7_SPI3 + +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN SPI3_NSS_PIN + +#define W25N01G_SPI_BUS BUS_SPI3 +#define W25N01G_CS_PIN SPI3_NSS_PIN + +#define USE_BLACKBOX +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define USE_FLASH_W25N01G +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 + +#define USE_I2C_DEVICE_2 +#define I2C2_SCL PB10 +#define I2C2_SDA PB11 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#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 + +// *************** 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_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define USE_UART7 +#define UART7_TX_PIN PE8 +#define UART7_RX_PIN PE7 + +#define USE_UART8 +#define UART8_TX_PIN PE1 +#define UART8_RX_PIN PE0 + +#define SERIAL_PORT_COUNT 9 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC3 + +#ifdef MAMBAH743_2022B + +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC3 +#define ADC_CHANNEL_3_PIN PC0 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define AIRSPEED_ADC_CHANNEL ADC_CHN_3 + +#else + +#define ADC_CHANNEL_1_PIN PC1 +#define ADC_CHANNEL_2_PIN PC3 +#define ADC_CHANNEL_3_PIN PC2 +#define ADC_CHANNEL_4_PIN PC0 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 +#define AIRSPEED_ADC_CHANNEL ADC_CHN_4 + +#endif + +// *************** PINIO *************************** +#define USE_PINIO +#define USE_PINIOBOX + +#define PINIO1_PIN PC2 +#define PINIO2_PIN PC5 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL) +#define CURRENT_METER_SCALE 250 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#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 +#define USE_DSHOT +#define USE_ESC_SENSOR \ No newline at end of file diff --git a/src/main/target/KAKUTEF4/CMakeLists.txt b/src/main/target/KAKUTEF4/CMakeLists.txt index ae1ba2a46a2..caf084129b2 100644 --- a/src/main/target/KAKUTEF4/CMakeLists.txt +++ b/src/main/target/KAKUTEF4/CMakeLists.txt @@ -1,3 +1,4 @@ target_stm32f405xg(KAKUTEF4) target_stm32f405xg(KAKUTEF4V2) -target_stm32f405xg(KAKUTEF4V23) \ No newline at end of file +target_stm32f405xg(KAKUTEF4V23) +target_stm32f405xg(KAKUTEF4V24) \ No newline at end of file diff --git a/src/main/target/KAKUTEF4/target.c b/src/main/target/KAKUTEF4/target.c index bf58e5bdca8..758dfa8b1bf 100755 --- a/src/main/target/KAKUTEF4/target.c +++ b/src/main/target/KAKUTEF4/target.c @@ -29,26 +29,26 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // PPM IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // PPM IN DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT - DMA1_ST7 DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT - DMA1_ST2 DEF_TIM(TIM2, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 1), // S3_OUT - DMA1_ST6 -#if !defined(KAKUTEF4V23) - DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT - DMA1_ST1 -#else - DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT - DMA1_ST1 +#if defined(KAKUTEF4V23) || defined(KAKUTEF4V24) + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT - DMA1_ST1 DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT - DMA1_ST0 DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT - DMA1_ST3 +#else + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT - DMA1_ST1 #endif -#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) +#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) || defined(KAKUTEF4V24) DEF_TIM(TIM8, CH3, PC8, TIM_USE_LED, 0, 0), // LED_STRIP - DMA2_ST2 #else DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT - DMA1_ST2 DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S6_OUT - DMA2_ST4 - DEF_TIM(TIM5, CH2, PA1, TIM_USE_LED, 0, 0), // LED_STRIP - DMA1_ST4 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_LED, 0, 0), // LED_STRIP - DMA1_ST4 #endif }; diff --git a/src/main/target/KAKUTEF4/target.h b/src/main/target/KAKUTEF4/target.h index bf684969336..bc921c9f3f8 100644 --- a/src/main/target/KAKUTEF4/target.h +++ b/src/main/target/KAKUTEF4/target.h @@ -29,6 +29,9 @@ #elif defined(KAKUTEF4V23) # define TARGET_BOARD_IDENTIFIER "KT23" # define USBD_PRODUCT_STRING "KakuteF4-V2.3" +#elif defined(KAKUTEF4V24) +# define TARGET_BOARD_IDENTIFIER "KT24" +# define USBD_PRODUCT_STRING "KakuteF4-V2.4" #else # define TARGET_BOARD_IDENTIFIER "KTV1" # define USBD_PRODUCT_STRING "KakuteF4-V1" @@ -37,7 +40,7 @@ #define LED0 PB5 #define LED1 PB4 -#if !defined(KAKUTEF4V23) +#if defined(KAKUTEF4) || defined(KAKUTEF4V2) # define LED2 PB6 #endif @@ -54,7 +57,7 @@ #define MPU6000_CS_PIN PC4 #define MPU6000_SPI_BUS BUS_SPI1 -#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) +#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) || defined(KAKUTEF4V24) # define USE_I2C # define USE_I2C_DEVICE_1 # define I2C1_SCL PB8 // SCL pad @@ -62,12 +65,7 @@ # define USE_MAG # define MAG_I2C_BUS BUS_I2C1 -# define USE_MAG_HMC5883 -# define USE_MAG_QMC5883 -# define USE_MAG_MAG3110 -# define USE_MAG_IST8310 -# define USE_MAG_IST8308 -# define USE_MAG_LIS3MDL +# define USE_MAG_ALL # define TEMPERATURE_I2C_BUS BUS_I2C1 @@ -84,11 +82,12 @@ #define MAX7456_SPI_BUS BUS_SPI3 #define MAX7456_CS_PIN PB14 -#define M25P16_CS_PIN PB3 -#define M25P16_SPI_BUS BUS_SPI3 - #define USE_FLASHFS + #define USE_FLASH_M25P16 +#define M25P16_CS_PIN PB3 +#define M25P16_SPI_BUS BUS_SPI3 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT #define USB_IO #define USE_VCP @@ -110,7 +109,7 @@ #define UART6_RX_PIN PC7 #define UART6_TX_PIN PC6 -#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) +#if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) || defined(KAKUTEF4V24) # define USE_UART4 # define UART4_RX_PIN PA1 # define UART4_TX_PIN PA0 @@ -158,7 +157,7 @@ #define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 #define RSSI_ADC_CHANNEL ADC_CHN_3 -#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_TELEMETRY | FEATURE_OSD) +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_TELEMETRY | FEATURE_OSD | FEATURE_BLACKBOX) #define DEFAULT_RX_TYPE RX_TYPE_SERIAL #define SERIALRX_PROVIDER SERIALRX_SBUS #define SERIALRX_UART SERIAL_PORT_USART3 diff --git a/src/main/target/KAKUTEF7/target.c b/src/main/target/KAKUTEF7/target.c old mode 100755 new mode 100644 index 53ae9359deb..19d524dc710 --- a/src/main/target/KAKUTEF7/target.c +++ b/src/main/target/KAKUTEF7/target.c @@ -29,7 +29,6 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH3, PE13, TIM_USE_PPM, 0, 1), // PPM, DMA2_ST6 DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // M1 , DMA1_ST7 DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // M2 , DMA1_ST2 @@ -37,8 +36,10 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH2, PE11, TIM_USE_OUTPUT_AUTO, 0, 1), // M4 , DMA2_ST4 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // M5 , DMA2_ST7 DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0), // M6 , DMA1_ST1 + + //DEF_TIM(TIM1, CH3, PE13, TIM_USE_OUTPUT_AUTO, 0, 1), // PPM/M7, DMA2_ST6 - DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 0), // LED_STRIP, DMA1_ST0 + DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 0), // LED_STRIP, DMA1_ST0 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/KAKUTEF7/target.h b/src/main/target/KAKUTEF7/target.h index 064032b7f4b..f3f4edfed40 100644 --- a/src/main/target/KAKUTEF7/target.h +++ b/src/main/target/KAKUTEF7/target.h @@ -135,13 +135,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_MAG3110 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_LIS3MDL -#define USE_MAG_MLX90393 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/KAKUTEF7MINIV3/target.c b/src/main/target/KAKUTEF7MINIV3/target.c index 095038960de..864c1de5204 100644 --- a/src/main/target/KAKUTEF7MINIV3/target.c +++ b/src/main/target/KAKUTEF7MINIV3/target.c @@ -38,7 +38,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED STRIP - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // RX2 + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // RX2 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/KAKUTEF7MINIV3/target.h b/src/main/target/KAKUTEF7MINIV3/target.h index c3d89837252..bf485ebc82b 100644 --- a/src/main/target/KAKUTEF7MINIV3/target.h +++ b/src/main/target/KAKUTEF7MINIV3/target.h @@ -88,6 +88,13 @@ #define MPU6000_SPI_BUS BUS_SPI1 #define MPU6000_CS_PIN PB2 +// ICM42688 +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PB2 +#define ICM42605_EXTI_PIN PA4 + /* * Blackbox Onboard Flash */ @@ -116,11 +123,7 @@ */ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /* * ADC diff --git a/src/main/target/KAKUTEH7/target.h b/src/main/target/KAKUTEH7/target.h index 388515fbbbf..258c7721aa0 100644 --- a/src/main/target/KAKUTEH7/target.h +++ b/src/main/target/KAKUTEH7/target.h @@ -113,6 +113,11 @@ #define IMU_BMI270_ALIGN CW0_DEG #endif +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN PE4 +#define ICM42605_SPI_BUS BUS_SPI4 + #define USE_MAX7456 #define MAX7456_SPI_BUS BUS_SPI2 #define MAX7456_CS_PIN PB12 @@ -132,13 +137,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/KAKUTEH7WING/target.h b/src/main/target/KAKUTEH7WING/target.h index 72cf6b68069..79068b8cd84 100644 --- a/src/main/target/KAKUTEH7WING/target.h +++ b/src/main/target/KAKUTEH7WING/target.h @@ -107,13 +107,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/KROOZX/target.c b/src/main/target/KROOZX/target.c index c77a77aaed5..a445a9656f6 100755 --- a/src/main/target/KROOZX/target.c +++ b/src/main/target/KROOZX/target.c @@ -23,7 +23,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // PPM IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // PPM IN DEF_TIM(TIM5, CH2, PA1, TIM_USE_MOTOR, 0, 0), // PWM4 DEF_TIM(TIM5, CH4, PA3, TIM_USE_MOTOR, 0, 0), // PWM2 diff --git a/src/main/target/KROOZX/target.h b/src/main/target/KROOZX/target.h index 9af00d2f72e..ea5ee6a8e0f 100755 --- a/src/main/target/KROOZX/target.h +++ b/src/main/target/KROOZX/target.h @@ -36,12 +36,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MAMBAF405US/target.c b/src/main/target/MAMBAF405US/target.c index 1781a047e3f..19ba5944c20 100644 --- a/src/main/target/MAMBAF405US/target.c +++ b/src/main/target/MAMBAF405US/target.c @@ -25,7 +25,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN #ifdef MAMBAF405US_I2C DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1 ), // S1 pin A9: DMA2 Stream 6 Channel 0 diff --git a/src/main/target/MAMBAF405US/target.h b/src/main/target/MAMBAF405US/target.h index b6b95cb12b6..1b21fe60e3d 100644 --- a/src/main/target/MAMBAF405US/target.h +++ b/src/main/target/MAMBAF405US/target.h @@ -74,14 +74,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP diff --git a/src/main/target/MAMBAF405_2022A/target.h b/src/main/target/MAMBAF405_2022A/target.h index c4c20e127f6..5a24771288d 100644 --- a/src/main/target/MAMBAF405_2022A/target.h +++ b/src/main/target/MAMBAF405_2022A/target.h @@ -83,14 +83,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP @@ -200,4 +193,4 @@ #define USE_PINIO #define USE_PINIOBOX #define PINIO1_PIN PC2 -#define PINIO2_PIN PC5 \ No newline at end of file +#define PINIO2_PIN PC5 diff --git a/src/main/target/MAMBAF722/target.c b/src/main/target/MAMBAF722/target.c index b97969e57bf..e1afa9b221f 100644 --- a/src/main/target/MAMBAF722/target.c +++ b/src/main/target/MAMBAF722/target.c @@ -25,7 +25,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT – D(2, 4, 7) DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT – D(2, 7, 7) diff --git a/src/main/target/MAMBAF722/target.h b/src/main/target/MAMBAF722/target.h index c536cc6017e..20e907fa87c 100644 --- a/src/main/target/MAMBAF722/target.h +++ b/src/main/target/MAMBAF722/target.h @@ -74,12 +74,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP diff --git a/src/main/target/MAMBAF722_2022A/target.c b/src/main/target/MAMBAF722_2022A/target.c index 9b51f139453..4d371135963 100644 --- a/src/main/target/MAMBAF722_2022A/target.c +++ b/src/main/target/MAMBAF722_2022A/target.c @@ -25,7 +25,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2 diff --git a/src/main/target/MAMBAF722_2022A/target.h b/src/main/target/MAMBAF722_2022A/target.h index 0752bb368b3..4ab5a75bbc8 100644 --- a/src/main/target/MAMBAF722_2022A/target.h +++ b/src/main/target/MAMBAF722_2022A/target.h @@ -86,11 +86,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP @@ -197,4 +193,4 @@ #define USE_PINIO #define USE_PINIOBOX #define PINIO1_PIN PC0 // VTX power switcher -#define PINIO2_PIN PC2 // WiFi Switcher \ No newline at end of file +#define PINIO2_PIN PC2 // WiFi Switcher diff --git a/src/main/target/MAMBAF722_WING/target.h b/src/main/target/MAMBAF722_WING/target.h index a877a74e654..654b9afdfbc 100644 --- a/src/main/target/MAMBAF722_WING/target.h +++ b/src/main/target/MAMBAF722_WING/target.h @@ -55,12 +55,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP @@ -168,4 +163,4 @@ #define USE_PINIO #define USE_PINIOBOX #define PINIO1_PIN PC0 -#define PINIO2_PIN PC2 \ No newline at end of file +#define PINIO2_PIN PC2 diff --git a/src/main/target/MAMBAF722_X8/target.c b/src/main/target/MAMBAF722_X8/target.c index 9b51f139453..4d371135963 100644 --- a/src/main/target/MAMBAF722_X8/target.c +++ b/src/main/target/MAMBAF722_X8/target.c @@ -25,7 +25,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM11, CH1, PB9, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2 diff --git a/src/main/target/MAMBAF722_X8/target.h b/src/main/target/MAMBAF722_X8/target.h index 2c8c84e9d11..1a89d3bf31f 100644 --- a/src/main/target/MAMBAF722_X8/target.h +++ b/src/main/target/MAMBAF722_X8/target.h @@ -53,12 +53,7 @@ //*********** Magnetometer / Compass ************* #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS - -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // ******* SERIAL ******** #define USE_VCP diff --git a/src/main/target/MAMBAH743/CMakeLists.txt b/src/main/target/MAMBAH743/CMakeLists.txt index 61b073da931..801467cdb86 100644 --- a/src/main/target/MAMBAH743/CMakeLists.txt +++ b/src/main/target/MAMBAH743/CMakeLists.txt @@ -1,2 +1,3 @@ target_stm32h743xi(MAMBAH743) -target_stm32h743xi(MAMBAH743_2022B) \ No newline at end of file +target_stm32h743xi(MAMBAH743_2022B) +target_stm32h743xi(MAMBAH743_2022B_GYRO2) diff --git a/src/main/target/MAMBAH743/target.c b/src/main/target/MAMBAH743/target.c index 46231fdbd79..1e4f8fe246b 100644 --- a/src/main/target/MAMBAH743/target.c +++ b/src/main/target/MAMBAH743/target.c @@ -29,7 +29,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); -#ifdef MAMBAH743_2022B +#ifdef USE_IMU_ICM42605 BUSDEV_REGISTER_SPI_TAG(busdev_icm42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); #endif diff --git a/src/main/target/MAMBAH743/target.h b/src/main/target/MAMBAH743/target.h index 27a65ded29d..bc4a73979ee 100644 --- a/src/main/target/MAMBAH743/target.h +++ b/src/main/target/MAMBAH743/target.h @@ -22,6 +22,11 @@ #define TARGET_BOARD_IDENTIFIER "M743" #define USBD_PRODUCT_STRING "MAMBAH743_2022B" +#elif defined(MAMBAH743_2022B_GYRO2) + +#define TARGET_BOARD_IDENTIFIER "M743" +#define USBD_PRODUCT_STRING "MAMBAH743_2022B_GYRO2" + #else #define TARGET_BOARD_IDENTIFIER "M743" @@ -58,13 +63,12 @@ #define BMI270_SPI_BUS BUS_SPI1 #define BMI270_CS_PIN PA4 -#ifdef MAMBAH743_2022B +#define USE_SPI_DEVICE_4 +#define SPI4_SCK_PIN PE12 +#define SPI4_MISO_PIN PE13 +#define SPI4_MOSI_PIN PE14 -// SPI4 is used on the second MPU6000 gyro, we do not use it at the moment -// #define USE_SPI_DEVICE_4 -// #define SPI4_SCK_PIN PE12 -// #define SPI4_MISO_PIN PE13 -// #define SPI4_MOSI_PIN PE14 +#ifdef MAMBAH743_2022B #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG @@ -73,6 +77,15 @@ #endif +#ifdef MAMBAH743_2022B_GYRO2 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_SPI_BUS BUS_SPI4 +#define ICM42605_CS_PIN PE11 + +#endif + // *************** SPI2 OSD *********************** #define USE_SPI_DEVICE_2 #define SPI2_SCK_PIN PB13 @@ -124,13 +137,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -182,7 +189,7 @@ #define USE_ADC #define ADC_INSTANCE ADC3 -#ifdef MAMBAH743_2022B +#if defined(MAMBAH743_2022B) || defined(MAMBAH743_2022B_GYRO2) #define ADC_CHANNEL_1_PIN PC1 #define ADC_CHANNEL_2_PIN PC3 @@ -210,7 +217,7 @@ #define USE_PINIO #define USE_PINIOBOX -#ifdef MAMBAH743_2022B +#if defined(MAMBAH743_2022B) || defined(MAMBAH743_2022B_GYRO2) #define PINIO1_PIN PC2 #define PINIO2_PIN PC5 @@ -238,4 +245,4 @@ #define MAX_PWM_OUTPUT_PORTS 8 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/MATEKF405/target.c b/src/main/target/MATEKF405/target.c index 254707887b2..1706954b7f9 100644 --- a/src/main/target/MATEKF405/target.c +++ b/src/main/target/MATEKF405/target.c @@ -22,7 +22,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 UP(2,1) diff --git a/src/main/target/MATEKF405/target.h b/src/main/target/MATEKF405/target.h index fa2af63384c..667cd2b3fa8 100644 --- a/src/main/target/MATEKF405/target.h +++ b/src/main/target/MATEKF405/target.h @@ -147,14 +147,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS diff --git a/src/main/target/MATEKF405CAN/target.c b/src/main/target/MATEKF405CAN/target.c index 2ab40de1dc4..406a74ecd86 100644 --- a/src/main/target/MATEKF405CAN/target.c +++ b/src/main/target/MATEKF405CAN/target.c @@ -36,7 +36,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM2, CH1, PA15, TIM_USE_LED, 0, 0), //2812LED D(1,5,3) - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 + DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0), //RX2 DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), //TX2 softserial1_Tx }; diff --git a/src/main/target/MATEKF405CAN/target.h b/src/main/target/MATEKF405CAN/target.h index 81aa91ce99a..d12b5e3e1a3 100644 --- a/src/main/target/MATEKF405CAN/target.h +++ b/src/main/target/MATEKF405CAN/target.h @@ -55,13 +55,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_RANGEFINDER #define RANGEFINDER_I2C_BUS BUS_I2C2 diff --git a/src/main/target/MATEKF405SE/target.c b/src/main/target/MATEKF405SE/target.c index ef6fceaca94..6aa586e68ae 100644 --- a/src/main/target/MATEKF405SE/target.c +++ b/src/main/target/MATEKF405SE/target.c @@ -35,7 +35,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM2, CH1, PA15, TIM_USE_LED, 0, 0), //2812LED D(1,5,3) - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), //TX2 softserial1_Tx }; diff --git a/src/main/target/MATEKF405SE/target.h b/src/main/target/MATEKF405SE/target.h index 4c0b4b8b390..38c8f56f5d9 100644 --- a/src/main/target/MATEKF405SE/target.h +++ b/src/main/target/MATEKF405SE/target.h @@ -68,13 +68,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_RANGEFINDER #define USE_RANGEFINDER_US42 diff --git a/src/main/target/MATEKF405TE/target.c b/src/main/target/MATEKF405TE/target.c index 79f6269a528..2240915365a 100644 --- a/src/main/target/MATEKF405TE/target.c +++ b/src/main/target/MATEKF405TE/target.c @@ -42,7 +42,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM3, CH4, PB1, TIM_USE_LED, 0, 0), // 2812LED D(1,2,5) DEF_TIM(TIM11, CH1, PB9, TIM_USE_BEEPER, 0, 0), // BEEPER PWM - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), //RX2 DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), //TX2 softserial1_Tx }; diff --git a/src/main/target/MATEKF405TE/target.h b/src/main/target/MATEKF405TE/target.h index acaed9daf23..fc7c1ad0ce9 100644 --- a/src/main/target/MATEKF405TE/target.h +++ b/src/main/target/MATEKF405TE/target.h @@ -92,12 +92,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define USE_RANGEFINDER #define RANGEFINDER_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF411/target.c b/src/main/target/MATEKF411/target.c index fb2ccde3f14..9a15bfd8d1a 100755 --- a/src/main/target/MATEKF411/target.c +++ b/src/main/target/MATEKF411/target.c @@ -35,7 +35,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 D(1,5,3) - clash with S2 DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0), //softserial_tx2 - 2812LED TIM_USE_LED D(2,1,6) - DEF_TIM(TIM5, CH1, PA0, TIM_USE_PPM, 0, 0), //use rssi pad for PPM/softserial_tx1 + DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0), //use rssi pad for PPM/softserial_tx1 //DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), // TX2 }; diff --git a/src/main/target/MATEKF411/target.h b/src/main/target/MATEKF411/target.h index 0bf0aab1987..6be5949419c 100755 --- a/src/main/target/MATEKF411/target.h +++ b/src/main/target/MATEKF411/target.h @@ -120,11 +120,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF411SE/target.h b/src/main/target/MATEKF411SE/target.h index abb4688457e..db5652e0cac 100755 --- a/src/main/target/MATEKF411SE/target.h +++ b/src/main/target/MATEKF411SE/target.h @@ -103,13 +103,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF411TE/target.h b/src/main/target/MATEKF411TE/target.h index 7ecb2d1cb67..fd2ea8fed43 100644 --- a/src/main/target/MATEKF411TE/target.h +++ b/src/main/target/MATEKF411TE/target.h @@ -88,13 +88,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #define PITOT_I2C_BUS BUS_I2C1 #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF722/target.c b/src/main/target/MATEKF722/target.c index d2575f42f2d..eb4275d39f8 100644 --- a/src/main/target/MATEKF722/target.c +++ b/src/main/target/MATEKF722/target.c @@ -25,7 +25,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 D(1, 4, 5) DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 D(2, 3, 7) diff --git a/src/main/target/MATEKF722/target.h b/src/main/target/MATEKF722/target.h index 49cc5fac09b..1908c6a5b4c 100644 --- a/src/main/target/MATEKF722/target.h +++ b/src/main/target/MATEKF722/target.h @@ -56,12 +56,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 @@ -152,4 +147,4 @@ #define MAX_PWM_OUTPUT_PORTS 7 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/MATEKF722PX/target.c b/src/main/target/MATEKF722PX/target.c index 170b67d9514..da31a68e42d 100755 --- a/src/main/target/MATEKF722PX/target.c +++ b/src/main/target/MATEKF722PX/target.c @@ -40,10 +40,9 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 2), // LED D(2, 3, 6) - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // RX2, PPM - DEF_TIM(TIM5, CH3, PA2, TIM_USE_PWM, 0, 0), // TX2, softserial1_tx - - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // Cam_ctrl reserved + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // RX2, PPM + DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), // TX2, softserial1_tx + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // Cam_ctrl reserved }; diff --git a/src/main/target/MATEKF722PX/target.h b/src/main/target/MATEKF722PX/target.h index ce780e7c93b..ae034074478 100755 --- a/src/main/target/MATEKF722PX/target.h +++ b/src/main/target/MATEKF722PX/target.h @@ -54,13 +54,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF722SE/target.c b/src/main/target/MATEKF722SE/target.c index 6e469dfff3a..585f3bb3994 100644 --- a/src/main/target/MATEKF722SE/target.c +++ b/src/main/target/MATEKF722SE/target.c @@ -43,9 +43,9 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 2), // LED D(2, 6, 0) - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM, RX2 + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM, RX2 - DEF_TIM(TIM5, CH3, PA2, TIM_USE_PWM, 0, 0), // TX2 & softserial1 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0), // TX2 & softserial1 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/MATEKF722SE/target.h b/src/main/target/MATEKF722SE/target.h index 04dc0d81230..0679d3f531d 100644 --- a/src/main/target/MATEKF722SE/target.h +++ b/src/main/target/MATEKF722SE/target.h @@ -68,13 +68,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/MATEKF765/target.c b/src/main/target/MATEKF765/target.c index 712beb4c8c9..6d0599a29f9 100644 --- a/src/main/target/MATEKF765/target.c +++ b/src/main/target/MATEKF765/target.c @@ -52,8 +52,8 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), // LED_2812 D(2,6,0) - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // RX6 PPM - DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // TX6 + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // RX6 PPM + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // TX6 and SoftwareSerial DEF_TIM(TIM11, CH1, PB9, TIM_USE_BEEPER, 0, 0), // BEEPER PWM for MATEKF765SE }; diff --git a/src/main/target/MATEKF765/target.h b/src/main/target/MATEKF765/target.h index e40fe455be3..8a726d56b3c 100644 --- a/src/main/target/MATEKF765/target.h +++ b/src/main/target/MATEKF765/target.h @@ -87,12 +87,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/MATEKH743/CMakeLists.txt b/src/main/target/MATEKH743/CMakeLists.txt index 96a65ca5a40..dcc5019a9d1 100644 --- a/src/main/target/MATEKH743/CMakeLists.txt +++ b/src/main/target/MATEKH743/CMakeLists.txt @@ -1 +1,2 @@ target_stm32h743xi(MATEKH743) +target_stm32h743xi(MATEKH743HD) diff --git a/src/main/target/MATEKH743/target.c b/src/main/target/MATEKH743/target.c index 1923e6623a1..bc2fb01558a 100644 --- a/src/main/target/MATEKH743/target.c +++ b/src/main/target/MATEKH743/target.c @@ -51,10 +51,10 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 9), // LED_2812 DEF_TIM(TIM2, CH1, PA15, TIM_USE_BEEPER, 0, 0), // BEEPER PWM - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // RX6 PPM - DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // TX6 - DEF_TIM(TIM16, CH1, PB8, TIM_USE_ANY, 0, 0), // RX4 - DEF_TIM(TIM17, CH1, PB9, TIM_USE_ANY, 0, 0), // TX4 + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PPM, 0, 0), // RX6 PPM + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // TX6 SoftwareSerial + // DEF_TIM(TIM16, CH1, PB8, TIM_USE_ANY, 0, 0), // RX4 + // DEF_TIM(TIM17, CH1, PB9, TIM_USE_ANY, 0, 0), // TX4 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/MATEKH743/target.h b/src/main/target/MATEKH743/target.h index 37742a88fcc..f2e21b0ee86 100644 --- a/src/main/target/MATEKH743/target.h +++ b/src/main/target/MATEKH743/target.h @@ -19,7 +19,12 @@ #pragma once #define TARGET_BOARD_IDENTIFIER "H743" -#define USBD_PRODUCT_STRING "MATEKH743" + +#if defined(MATEKH743HD) + #define USBD_PRODUCT_STRING "MATEKH743HD" +#else + #define USBD_PRODUCT_STRING "MATEKH743" +#endif #define USE_TARGET_CONFIG @@ -69,14 +74,16 @@ #define ICM42605_CS_PIN PC13 // *************** SPI2 OSD *********************** -#define USE_SPI_DEVICE_2 -#define SPI2_SCK_PIN PB13 -#define SPI2_MISO_PIN PB14 -#define SPI2_MOSI_PIN PB15 + #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 +#if defined(MATEKH743) + #define USE_MAX7456 + #define MAX7456_SPI_BUS BUS_SPI2 + #define MAX7456_CS_PIN PB12 +#endif // *************** SPI3 SPARE for external RM3100 *********** #define USE_SPI_DEVICE_3 @@ -108,12 +115,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 @@ -159,7 +161,7 @@ #define SERIAL_PORT_COUNT 9 #define DEFAULT_RX_TYPE RX_TYPE_SERIAL -#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_PROVIDER SERIALRX_CRSF #define SERIALRX_UART SERIAL_PORT_USART6 // *************** SDIO SD BLACKBOX******************* diff --git a/src/main/target/NEUTRONRCF435MINI/target.c b/src/main/target/NEUTRONRCF435MINI/target.c index 472867af578..9400ae4be1b 100644 --- a/src/main/target/NEUTRONRCF435MINI/target.c +++ b/src/main/target/NEUTRONRCF435MINI/target.c @@ -26,7 +26,7 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TMR1, CH1, PA8, TIM_USE_ANY |TIM_USE_LED, 0,7), // PWM1 - LED MCO1 DMA1 CH2 + DEF_TIM(TMR1, CH1, PA8, TIM_USE_ANY |TIM_USE_LED, 0,6), // PWM1 - LED MCO1 DMA1 CH2 DEF_TIM(TMR4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0,0), // motor1 DMA2 CH7 DEF_TIM(TMR4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0,2), // motor2 DMA2 CH6 diff --git a/src/main/target/NEUTRONRCF435MINI/target.h b/src/main/target/NEUTRONRCF435MINI/target.h index 27fc03ae5e1..2e90f48a69d 100644 --- a/src/main/target/NEUTRONRCF435MINI/target.h +++ b/src/main/target/NEUTRONRCF435MINI/target.h @@ -95,8 +95,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL #define DEFAULT_I2C_BUS BUS_I2C2 // temperature sensors @@ -166,7 +165,7 @@ #define USE_ADC #define ADC_INSTANCE ADC1 -#define ADC1_DMA_STREAM DMA2_CHANNEL5 +#define ADC1_DMA_STREAM DMA2_CHANNEL1 #define ADC_CHANNEL_1_PIN PA0 #define ADC_CHANNEL_2_PIN PA1 //#define ADC_CHANNEL_3_PIN PB0 diff --git a/src/main/target/NEUTRONRCF435SE/target.c b/src/main/target/NEUTRONRCF435SE/target.c index 3a8848911fa..0071615760c 100644 --- a/src/main/target/NEUTRONRCF435SE/target.c +++ b/src/main/target/NEUTRONRCF435SE/target.c @@ -26,20 +26,19 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TMR5, CH1, PA0, TIM_USE_ANY, 0, 13), // TIM_USE_CAMERA_CONTROL - DEF_TIM(TMR5, CH2, PA1, TIM_USE_ANY |TIM_USE_LED, 0,7), // PWM1 - LED MCO1 DMA1 CH2 - DEF_TIM(TMR2, CH4, PA3, TIM_USE_ANY |TIM_USE_PPM, 0,6), // PWM2 - PPM DMA1 CH6 - - DEF_TIM(TMR8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0,0), // motor1 DMA2 CH7 - DEF_TIM(TMR8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0,2), // motor2 DMA2 CH6 - DEF_TIM(TMR3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0,1), // motor3 DMA2 CH5 - DEF_TIM(TMR3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0,3), // motor4 DMA2 CH4 - - DEF_TIM(TMR4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0,11), // PWM1 - OUT5 DMA1 CH7 - DEF_TIM(TMR4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0,10), // PWM2 - OUT6 DMA2 CH1 - DEF_TIM(TMR3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0,9), // PWM3 - OUT7 DMA2 CH2 - DEF_TIM(TMR3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0,8), // PWM4 - OUT8 DMA2 CH3 - + DEF_TIM(TMR8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0,0), // motor1 DMA2 CH7 + DEF_TIM(TMR8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0,2), // motor2 DMA2 CH6 + DEF_TIM(TMR8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0,1), // motor3 DMA2 CH5 + DEF_TIM(TMR8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0,3), // motor4 DMA2 CH4 + + DEF_TIM(TMR4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0,11), // PWM1 - OUT5 DMA1 CH7 + DEF_TIM(TMR4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0,10), // PWM2 - OUT6 DMA2 CH1 + DEF_TIM(TMR3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0,9), // PWM3 - OUT7 DMA2 CH2 + DEF_TIM(TMR3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0,8), // PWM4 - OUT8 DMA2 CH3 + + // DEF_TIM(TMR5, CH1, PA0, TIM_USE_ANY, 0, 13), // TIM_USE_CAMERA_CONTROL + DEF_TIM(TMR5, CH2, PA1, TIM_USE_LED, 0,6), // PWM1 - LED MCO1 DMA1 CH2 + // DEF_TIM(TMR2, CH4, PA3, TIM_USE_ANY |TIM_USE_PPM, 0,6), // PWM2 - PPM DMA1 CH6 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/NEUTRONRCF435SE/target.h b/src/main/target/NEUTRONRCF435SE/target.h index 5d00a099115..48ed7f0c61b 100644 --- a/src/main/target/NEUTRONRCF435SE/target.h +++ b/src/main/target/NEUTRONRCF435SE/target.h @@ -93,8 +93,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL #define DEFAULT_I2C_BUS BUS_I2C2 // temperature sensors @@ -169,7 +168,7 @@ #define USE_ADC #define ADC_INSTANCE ADC1 -#define ADC1_DMA_STREAM DMA2_CHANNEL5 +#define ADC1_DMA_STREAM DMA2_CHANNEL1 #define ADC_CHANNEL_1_PIN PC2 #define ADC_CHANNEL_2_PIN PC1 //#define ADC_CHANNEL_3_PIN PB0 @@ -179,8 +178,8 @@ #define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY| FEATURE_VBAT | FEATURE_OSD ) -// #define USE_LED_STRIP -// #define WS2811_PIN PB10 //TIM2_CH3 +#define USE_LED_STRIP +#define WS2811_PIN PA1 //TIM2_CH3 // telemetry // #define USE_SPEKTRUM_BIND @@ -196,4 +195,4 @@ #define MAX_PWM_OUTPUT_PORTS 8 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/NEUTRONRCF435WING/target.h b/src/main/target/NEUTRONRCF435WING/target.h index 4f56d867782..2438d01ddfc 100644 --- a/src/main/target/NEUTRONRCF435WING/target.h +++ b/src/main/target/NEUTRONRCF435WING/target.h @@ -95,8 +95,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL #define DEFAULT_I2C_BUS BUS_I2C2 // temperature sensors diff --git a/src/main/target/NEUTRONRCH7BT/target.h b/src/main/target/NEUTRONRCH7BT/target.h index 78a1949e04f..9f4ffd118d5 100644 --- a/src/main/target/NEUTRONRCH7BT/target.h +++ b/src/main/target/NEUTRONRCH7BT/target.h @@ -87,12 +87,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/NOX/target.c b/src/main/target/NOX/target.c index e2651956e1c..647c77bfa11 100755 --- a/src/main/target/NOX/target.c +++ b/src/main/target/NOX/target.c @@ -24,8 +24,6 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM2, CH3, PB10, TIM_USE_PPM, 0, 0), //PPM - DEF_TIM(TIM2, CH1, PA0, TIM_USE_LED, 0, 0), //2812LED DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT DEF_TIM(TIM1, CH1N, PA7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT @@ -34,6 +32,9 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM9, CH1, PA2, TIM_USE_ANY, 0, 0), //UART2 TX DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0), //UART2 RX + + // DEF_TIM(TIM2, CH3, PB10, TIM_USE_PPM, 0, 0), //PPM + DEF_TIM(TIM2, CH1, PA0, TIM_USE_LED, 0, 0), //2812LED }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/OMNIBUSF4/target.c b/src/main/target/OMNIBUSF4/target.c index 81b30e11f25..86485aa49fc 100644 --- a/src/main/target/OMNIBUSF4/target.c +++ b/src/main/target/OMNIBUSF4/target.c @@ -24,17 +24,6 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { -#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(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 @@ -63,6 +52,19 @@ timerHardware_t timerHardware[] = { #if (defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3)) && !defined(OMNIBUSF4PRO_LEDSTRIPM5) 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 + }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/OMNIBUSF4/target.h b/src/main/target/OMNIBUSF4/target.h index 2c0bd22801b..2c5a27afbb6 100644 --- a/src/main/target/OMNIBUSF4/target.h +++ b/src/main/target/OMNIBUSF4/target.h @@ -91,13 +91,7 @@ #define USE_MAG #define MAG_I2C_BUS I2C_EXT_BUS -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS I2C_EXT_BUS diff --git a/src/main/target/OMNIBUSF7/target.h b/src/main/target/OMNIBUSF7/target.h index 6a5a9d6ea9b..a5f1bfc6b87 100644 --- a/src/main/target/OMNIBUSF7/target.h +++ b/src/main/target/OMNIBUSF7/target.h @@ -141,12 +141,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/OMNIBUSF7NXT/target.c b/src/main/target/OMNIBUSF7NXT/target.c index b1eb7332dca..573c3e1bcd0 100644 --- a/src/main/target/OMNIBUSF7NXT/target.c +++ b/src/main/target/OMNIBUSF7NXT/target.c @@ -36,7 +36,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, MPU6500_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_MPU6500_ALIGN); timerHardware_t timerHardware[] = { - DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM / UART1_RX + // DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM / UART1_RX // OUTPUT 1-4 DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 1, 0), // D(1, 5, 5) diff --git a/src/main/target/OMNIBUSF7NXT/target.h b/src/main/target/OMNIBUSF7NXT/target.h index 367e8b22a77..6287e83473e 100644 --- a/src/main/target/OMNIBUSF7NXT/target.h +++ b/src/main/target/OMNIBUSF7NXT/target.h @@ -52,11 +52,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/PIXRACER/target.c b/src/main/target/PIXRACER/target.c index 73c9d6937a0..2364e60aec5 100755 --- a/src/main/target/PIXRACER/target.c +++ b/src/main/target/PIXRACER/target.c @@ -37,7 +37,7 @@ BUSDEV_REGISTER_I2C_TAG(busdev_mag3110, DEVHW_MAG3110, MAG_I2C_BUS, BUSDEV_REGISTER_SPI_TAG(busdev_hmc5983_spi, DEVHW_HMC5883, MPU9250_SPI_BUS, PE15, NONE, 1, DEVFLAGS_NONE, 0); timerHardware_t timerHardware[] = { - DEF_TIM(TIM3, CH3, PB0, TIM_USE_PPM, 0, 0), // PPM shared uart6 pc7 + // DEF_TIM(TIM3, CH3, PB0, TIM_USE_PPM, 0, 0), // PPM shared uart6 pc7 DEF_TIM(TIM1, CH4, PE14, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT DEF_TIM(TIM1, CH3, PE13, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT diff --git a/src/main/target/PIXRACER/target.h b/src/main/target/PIXRACER/target.h index 738fc1ad914..bc3bf3a4d96 100755 --- a/src/main/target/PIXRACER/target.h +++ b/src/main/target/PIXRACER/target.h @@ -56,13 +56,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_MPU9250 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/RADIX/target.c b/src/main/target/RADIX/target.c index db78409cdaf..ba10f018188 100644 --- a/src/main/target/RADIX/target.c +++ b/src/main/target/RADIX/target.c @@ -25,7 +25,7 @@ /* TIMERS */ timerHardware_t timerHardware[] = { - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PPM, 0, 0), // PPM In + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PPM, 0, 0), // PPM In DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM5, CH4, PA3, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 DEF_TIM(TIM1, CH3, PA10, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 diff --git a/src/main/target/REVO/target.c b/src/main/target/REVO/target.c index d1203adadc5..e1a2c2e8418 100644 --- a/src/main/target/REVO/target.c +++ b/src/main/target/REVO/target.c @@ -41,12 +41,12 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO | TIM_USE_ANY, 0, 0), // S5_OUT / LED DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT D1_ST2 - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // PPM (5th pin on FlexiIO port) - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN - DEF_TIM(TIM8, CH1, PC6, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S3_IN - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S4_IN - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S5_IN - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM | TIM_USE_OUTPUT_AUTO, 0, 0), // S6_IN + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM, 0, 0), // PPM (5th pin on FlexiIO port) + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0), // S2_IN + DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S3_IN + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_IN + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_IN + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_IN }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/REVO/target.h b/src/main/target/REVO/target.h index 29619624dff..713c1a8ce38 100644 --- a/src/main/target/REVO/target.h +++ b/src/main/target/REVO/target.h @@ -41,12 +41,7 @@ #define USE_DUAL_MAG #define MAG_I2C_BUS_EXT BUS_I2C2 #define MAG_I2C_BUS_INT BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/RUSH_BLADE_F7/target.h b/src/main/target/RUSH_BLADE_F7/target.h index ba5915892bc..2e68f1a392b 100644 --- a/src/main/target/RUSH_BLADE_F7/target.h +++ b/src/main/target/RUSH_BLADE_F7/target.h @@ -75,13 +75,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** Flash **************************** diff --git a/src/main/target/SAGEATF4/target.c b/src/main/target/SAGEATF4/target.c index 48875414672..2d951598ae0 100644 --- a/src/main/target/SAGEATF4/target.c +++ b/src/main/target/SAGEATF4/target.c @@ -26,20 +26,20 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TMR5, CH4, PA3, TIM_USE_PPM, 0, 4), // PPM UART2_RX_PIN DMA1 CH5 - DEF_TIM(TMR2, CH3, PB10, TIM_USE_ANY | TIM_USE_LED, 0,5), // PWM1 - LED MCO1 DMA1 CH6 - DEF_TIM(TMR2, CH4, PB11, TIM_USE_ANY | TIM_USE_BEEPER, 0,6), // PWM2 - BB DMA1 CH7 + // DEF_TIM(TMR5, CH4, PA3, TIM_USE_PPM, 0, 4), // PPM UART2_RX_PIN DMA1 CH5 - DEF_TIM(TMR4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0,0), // motor1 DMA1 CH1 - DEF_TIM(TMR4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0,1), // motor2 DMA1 CH2 - DEF_TIM(TMR2, CH1, PB8, TIM_USE_OUTPUT_AUTO, 0,2), // motor3 DMA1 CH3 - DEF_TIM(TMR2, CH2, PB9, TIM_USE_OUTPUT_AUTO, 0,3), // motor4 DMA1 CH4 + DEF_TIM(TMR4, CH1, PB6, TIM_USE_MOTOR, 0,0), // motor1 DMA1 CH1 + DEF_TIM(TMR4, CH2, PB7, TIM_USE_MOTOR, 0,1), // motor2 DMA1 CH2 + DEF_TIM(TMR4, CH3, PB8, TIM_USE_MOTOR, 0,2), // motor3 DMA1 CH3 + DEF_TIM(TMR4, CH4, PB9, TIM_USE_MOTOR, 0,3), // motor4 DMA1 CH4 - DEF_TIM(TMR3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0,8), // PWM1 - OUT5 DMA2 CH2 DMA2_CHANNEL1->ADC - DEF_TIM(TMR3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0,9), // PWM2 - OUT6 DMA2 CH3 + DEF_TIM(TMR3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0,8), // PWM1 - OUT5 DMA2 CH2 DMA2_CHANNEL1->ADC + DEF_TIM(TMR3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0,9), // PWM2 - OUT6 DMA2 CH3 DEF_TIM(TMR3, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0,10), // PWM3 - OUT7 DMA2 CH4 DEF_TIM(TMR3, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0,11), // PWM4 - OUT8 DMA2 CH5 + DEF_TIM(TMR2, CH3, PB10, TIM_USE_ANY | TIM_USE_LED, 0,5), // PWM1 - LED MCO1 DMA1 CH6 + DEF_TIM(TMR5, CH4, PB11, TIM_USE_ANY | TIM_USE_BEEPER, 0,6), // PWM2 - BB DMA1 CH7 }; const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/SAGEATF4/target.h b/src/main/target/SAGEATF4/target.h index 3ec00a37b3a..6a05cea4f6a 100644 --- a/src/main/target/SAGEATF4/target.h +++ b/src/main/target/SAGEATF4/target.h @@ -80,10 +80,21 @@ // BMI270 #define USE_IMU_BMI270 -#define IMU_BMI270_ALIGN CW0_DEG +#define IMU_BMI270_ALIGN CW90_DEG #define BMI270_SPI_BUS BUS_SPI1 #define BMI270_CS_PIN SPI1_NSS_PIN +//BMI088 +#define USE_IMU_BMI088 + +#define IMU_BMI088_ALIGN CW0_DEG +#define BMI088_SPI_BUS BUS_SPI1 + +#define BMI088_GYRO_CS_PIN SPI1_NSS_PIN +#define BMI088_GYRO_EXTI_PIN PA15 +#define BMI088_ACC_CS_PIN PC13 +#define BMI088_ACC_EXTI_PIN PD13 + // *************** I2C/Baro/Mag/EXT********************* #define USE_I2C #define USE_I2C_DEVICE_3 @@ -98,8 +109,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C3 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL // temperature sensors //#define TEMPERATURE_I2C_BUS BUS_I2C1 @@ -115,6 +125,10 @@ #define SPI2_MISO_PIN PD3//PB14 on LQFP64 #define SPI2_MOSI_PIN PD4//PB15 on LQFP64 #define SPI2_NSS_PIN PD5 //confirm on lqfp64 +#define SPI2_SCK_AF GPIO_MUX_6 +#define SPI2_MISO_AF GPIO_MUX_6 +#define SPI2_MOSI_AF GPIO_MUX_6 + #define USE_MAX7456 #define MAX7456_SPI_BUS BUS_SPI2 @@ -173,7 +187,7 @@ #define USE_ADC #define ADC_INSTANCE ADC1 -#define ADC1_DMA_STREAM DMA2_CHANNEL5 +#define ADC1_DMA_STREAM DMA2_CHANNEL1 #define ADC_CHANNEL_1_PIN PB0 #define ADC_CHANNEL_2_PIN PB1 //#define ADC_CHANNEL_3_PIN PB0 @@ -198,6 +212,6 @@ #define TARGET_IO_PORTD 0xffff #define TARGET_IO_PORTE BIT(2) -#define MAX_PWM_OUTPUT_PORTS 8 +#define MAX_PWM_OUTPUT_PORTS 12 #define USE_DSHOT #define USE_ESC_SENSOR diff --git a/src/main/target/SDMODELH7V1/CMakeLists.txt b/src/main/target/SDMODELH7V1/CMakeLists.txt new file mode 100644 index 00000000000..d8e1f7c3aba --- /dev/null +++ b/src/main/target/SDMODELH7V1/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32h743xi(SDMODELH7V1) diff --git a/src/main/target/SDMODELH7V1/config.c b/src/main/target/SDMODELH7V1/config.c new file mode 100644 index 00000000000..54f980fd8b3 --- /dev/null +++ b/src/main/target/SDMODELH7V1/config.c @@ -0,0 +1,40 @@ +/* + * 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; + + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_MSP; + serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].msp_baudrateIndex = BAUD_115200; + + 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/SDMODELH7V1/target.c b/src/main/target/SDMODELH7V1/target.c new file mode 100644 index 00000000000..8851f95286f --- /dev/null +++ b/src/main/target/SDMODELH7V1/target.c @@ -0,0 +1,44 @@ +/* + * 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), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 2), // S3 + DEF_TIM(TIM2, CH3, PB10, TIM_USE_OUTPUT_AUTO, 0, 3), // S4 + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 4), // S5 + DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 5), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 6), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 7), // S8 + + DEF_TIM(TIM4, CH1, PD12, TIM_USE_LED, 0, 9), // LED_2812 +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/SDMODELH7V1/target.h b/src/main/target/SDMODELH7V1/target.h new file mode 100644 index 00000000000..cc4d39cf6c8 --- /dev/null +++ b/src/main/target/SDMODELH7V1/target.h @@ -0,0 +1,182 @@ +/* + * 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 "SMH71" +#define USBD_PRODUCT_STRING "SDMODELH7V1" + +#define USE_TARGET_CONFIG + +#define LED0 PC2 + +#define BEEPER PC13 +#define BEEPER_INVERTED + +// *************** IMU generic *********************** + + + + +// *************** SPI1 **************** +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_FLASHFS +#define USE_FLASH_W25N01G +#define W25N01G_SPI_BUS BUS_SPI1 +#define W25N01G_CS_PIN PA4 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + + + +// *************** SPI2 *********************** +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +// *************** SPI4 *************** +#define USE_SPI_DEVICE_4 +#define SPI4_SCK_PIN PE2 +#define SPI4_MISO_PIN PE5 +#define SPI4_MOSI_PIN PE6 + +//MPU6000 +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG +#define MPU6000_SPI_BUS BUS_SPI4 +#define MPU6000_CS_PIN PE4 + +//BMI270 +#define USE_IMU_BMI270 +#define BMI270_SPI_BUS BUS_SPI4 +#define BMI270_CS_PIN PE4 + +#define IMU_BMI270_ALIGN CW0_DEG + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// *************** I2C /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_BARO_DPS310 +#define USE_BARO_SPL06 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_IST8308 +#define USE_MAG_MAG3110 +#define USE_MAG_LIS3MDL +#define USE_MAG_VCM5883 + +#define TEMPERATURE_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS BUS_I2C1 + +// *************** 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 + +#define USE_UART7 +#define UART7_RX_PIN PE7 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 + +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC5 +#define ADC_CHANNEL_3_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 +#define RSSI_ADC_CHANNEL ADC_CHN_2 + +// *************** PINIO *************************** +#define USE_PINIO +#define USE_PINIOBOX + +#define PINIO1_PIN PE13 +#define PINIO2_PIN PB11 +#define PINIO1_FLAGS PINIO_FLAGS_INVERTED +#define PINIO2_FLAGS PINIO_FLAGS_INVERTED + + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PD12 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_TELEMETRY | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) +#define CURRENT_METER_SCALE 250 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#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 +#define USE_DSHOT +#define USE_ESC_SENSOR + diff --git a/src/main/target/SITL/sim/realFlight.c b/src/main/target/SITL/sim/realFlight.c index 40a2d85478b..ce3e3acb0ea 100644 --- a/src/main/target/SITL/sim/realFlight.c +++ b/src/main/target/SITL/sim/realFlight.c @@ -58,9 +58,11 @@ #define RF_PORT 18083 #define RF_MAX_CHANNEL_COUNT 12 -// RealFlight scenerys doesn't represent real landscapes, so fake some nice coords: Area 51 ;) -#define FAKE_LAT 37.277127f -#define FAKE_LON -115.799669f + +// "RealFlight Ranch" is located in Sierra Nevada, southern Spain +// This is not the Position of the Ranch, it's the Point of 0,0 in the Map (bottom left corner) +#define FAKE_LAT 36.910610f +#define FAKE_LON -2.876605f static uint8_t pwmMapping[RF_MAX_PWM_OUTS]; static uint8_t mappingCount; @@ -296,9 +298,9 @@ static void exchangeData(void) //rfValues.m_orientationQuaternion_W = getDoubleFromResponse(response, "m-orientationQuaternion-W"); rfValues.m_aircraftPositionX_MTR = getDoubleFromResponse(response, "m-aircraftPositionX-MTR"); rfValues.m_aircraftPositionY_MTR = getDoubleFromResponse(response, "m-aircraftPositionY-MTR"); - //rfValues.m_velocityWorldU_MPS = getDoubleFromResponse(response, "m-velocityWorldU-MPS"); - //rfValues.m_velocityWorldV_MPS = getDoubleFromResponse(response, "m-velocityWorldV-MPS"); - //rfValues.m_velocityWorldW_MPS = getDoubleFromResponse(response, "m-velocityWorldW-MPS"); + rfValues.m_velocityWorldU_MPS = getDoubleFromResponse(response, "m-velocityWorldU-MPS"); + rfValues.m_velocityWorldV_MPS = getDoubleFromResponse(response, "m-velocityWorldV-MPS"); + rfValues.m_velocityWorldW_MPS = getDoubleFromResponse(response, "m-velocityWorldW-MPS"); //rfValues.m_velocityBodyU_MPS = getDoubleFromResponse(response, "m-velocityBodyU-MPS"); //rfValues.m_velocityBodyV_MPS = getDoubleFromResponse(response, "mm-velocityBodyV-MPS"); //rfValues.m_velocityBodyW_MPS = getDoubleFromResponse(response, "m-velocityBodyW-MPS"); @@ -332,7 +334,7 @@ static void exchangeData(void) float lat, lon; fakeCoords(FAKE_LAT, FAKE_LON, rfValues.m_aircraftPositionX_MTR, -rfValues.m_aircraftPositionY_MTR, &lat, &lon); - int16_t course = (int16_t)roundf(convertAzimuth(rfValues.m_azimuth_DEG) * 10); + int16_t course = (int16_t)roundf(RADIANS_TO_DECIDEGREES(atan2_approx(-rfValues.m_velocityWorldU_MPS,rfValues.m_velocityWorldV_MPS))); int32_t altitude = (int32_t)roundf(rfValues.m_altitudeASL_MTR * 100); gpsFakeSet( GPS_FIX_3D, @@ -342,9 +344,9 @@ static void exchangeData(void) altitude, (int16_t)roundf(rfValues.m_groundspeed_MPS * 100), course, - 0, - 0, - 0, + 0,//(int16_t)roundf(rfValues.m_velocityWorldV_MPS * 100), //not sure about the direction + 0,//(int16_t)roundf(-rfValues.m_velocityWorldU_MPS * 100), + 0,//(int16_t)roundf(rfValues.m_velocityWorldW_MPS * 100), 0 ); @@ -357,7 +359,7 @@ static void exchangeData(void) const int16_t roll_inav = (int16_t)roundf(rfValues.m_roll_DEG * 10); const int16_t pitch_inav = (int16_t)roundf(-rfValues.m_inclination_DEG * 10); - const int16_t yaw_inav = course; + const int16_t yaw_inav = (int16_t)roundf(convertAzimuth(rfValues.m_azimuth_DEG) * 10); if (!useImu) { imuSetAttitudeRPY(roll_inav, pitch_inav, yaw_inav); imuUpdateAttitude(micros()); diff --git a/src/main/target/SITL/sim/xplane.c b/src/main/target/SITL/sim/xplane.c index 44089117d2e..d629c2130e3 100644 --- a/src/main/target/SITL/sim/xplane.c +++ b/src/main/target/SITL/sim/xplane.c @@ -421,9 +421,9 @@ static void* listenWorker(void* arg) computeQuaternionFromRPY(&quat, roll_inav, pitch_inav, yaw_inav); transformVectorEarthToBody(&north, &quat); fakeMagSet( - constrainToInt16(north.x * 16000.0f), - constrainToInt16(north.y * 16000.0f), - constrainToInt16(north.z * 16000.0f) + constrainToInt16(north.x * 1024.0f), + constrainToInt16(north.y * 1024.0f), + constrainToInt16(north.z * 1024.0f) ); if (!initalized) { diff --git a/src/main/target/SKYSTARSF405HD/CMakeLists.txt b/src/main/target/SKYSTARSF405HD/CMakeLists.txt index cc9515d9e0c..b097558284c 100644 --- a/src/main/target/SKYSTARSF405HD/CMakeLists.txt +++ b/src/main/target/SKYSTARSF405HD/CMakeLists.txt @@ -1 +1,2 @@ target_stm32f405xg(SKYSTARSF405HD) +target_stm32f405xg(SKYSTARSF405HD2) \ No newline at end of file diff --git a/src/main/target/SKYSTARSF405HD/target.c b/src/main/target/SKYSTARSF405HD/target.c index 40ab18015af..cc4ff1c5a88 100644 --- a/src/main/target/SKYSTARSF405HD/target.c +++ b/src/main/target/SKYSTARSF405HD/target.c @@ -22,12 +22,16 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM1, CH1, PA8, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM1, CH1, PA8, TIM_USE_PPM, 0, 0), DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), +#if defined(SKYSTARSF405HD2) + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), +#endif DEF_TIM(TIM8, CH3, PC8, TIM_USE_LED, 0, 0), }; diff --git a/src/main/target/SKYSTARSF405HD/target.h b/src/main/target/SKYSTARSF405HD/target.h index ac88a720847..9b9805084f2 100644 --- a/src/main/target/SKYSTARSF405HD/target.h +++ b/src/main/target/SKYSTARSF405HD/target.h @@ -45,6 +45,11 @@ #define BMI270_SPI_BUS BUS_SPI1 #define BMI270_CS_PIN PA4 +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW180_DEG_FLIP +#define ICM42605_SPI_BUS BUS_SPI1 +#define ICM42605_CS_PIN PA4 + // *************** M25P256 flash ******************** #define USE_FLASHFS #define USE_FLASH_M25P16 @@ -117,14 +122,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS @@ -158,4 +156,8 @@ #define USE_DSHOT #define USE_ESC_SENSOR +#if defined(SKYSTARSF405HD2) +#define MAX_PWM_OUTPUT_PORTS 6 +#else #define MAX_PWM_OUTPUT_PORTS 4 +#endif diff --git a/src/main/target/SKYSTARSF722HD/CMakeLists.txt b/src/main/target/SKYSTARSF722HD/CMakeLists.txt index 9aadb3609b3..a13320d26ac 100644 --- a/src/main/target/SKYSTARSF722HD/CMakeLists.txt +++ b/src/main/target/SKYSTARSF722HD/CMakeLists.txt @@ -1,2 +1,3 @@ target_stm32f722xe(SKYSTARSF722HD) +target_stm32f722xe(SKYSTARSF722HDPRO) target_stm32f722xe(SKYSTARSF722MINIHD) diff --git a/src/main/target/SKYSTARSF722HD/target.c b/src/main/target/SKYSTARSF722HD/target.c index 72ac8974552..bee870243af 100644 --- a/src/main/target/SKYSTARSF722HD/target.c +++ b/src/main/target/SKYSTARSF722HD/target.c @@ -22,7 +22,7 @@ #include "drivers/timer.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM3, CH1, PB4, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM3, CH1, PB4, TIM_USE_PPM, 0, 0), DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // TIM3_CH3 / TIM8_CH3 DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // TIM3_CH4 / TIM8_CH4 diff --git a/src/main/target/SKYSTARSF722HD/target.h b/src/main/target/SKYSTARSF722HD/target.h index 9c2521380bb..d46e2cf162f 100644 --- a/src/main/target/SKYSTARSF722HD/target.h +++ b/src/main/target/SKYSTARSF722HD/target.h @@ -20,6 +20,9 @@ #ifdef SKYSTARSF7MINIHD #define TARGET_BOARD_IDENTIFIER "SS7M" #define USBD_PRODUCT_STRING "SkystarsF722MiniHD" +#elif defined(SKYSTARSF722HDPRO) +#define TARGET_BOARD_IDENTIFIER "SS7P" +#define USBD_PRODUCT_STRING "SkystarsF722HDPRO" #else #define TARGET_BOARD_IDENTIFIER "SS7D" #define USBD_PRODUCT_STRING "SkystarsF722HD" @@ -45,6 +48,22 @@ #define USE_IMU_MPU6000 #define IMU_MPU6000_ALIGN CW270_DEG +#elif defined(SKYSTARSF722HDPRO) +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW270_DEG_FLIP + +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW90_DEG_FLIP + +#define BMI270_CS_PIN PA4 +#define BMI270_SPI_BUS BUS_SPI1 +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW90_DEG_FLIP + #else #define BMI270_CS_PIN PA4 #define BMI270_SPI_BUS BUS_SPI1 @@ -81,6 +100,11 @@ #define USE_BARO_BMP280 #define BMP280_SPI_BUS BUS_SPI2 #define BMP280_CS_PIN PB1 +#ifdef SKYSTARSF722HDPRO +#define USE_BARO_SPL06 +#define SPL06_SPI_BUS BUS_SPI2 +#define SPL06_CS_PIN PB1 +#endif // *************** UART ***************************** #define USE_VCP @@ -125,14 +149,7 @@ #define USE_MAG #define MAG_I2C_BUS DEFAULT_I2C_BUS -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS diff --git a/src/main/target/SKYSTARSH743HD/target.h b/src/main/target/SKYSTARSH743HD/target.h index d0f9360517a..6e830664c5d 100644 --- a/src/main/target/SKYSTARSH743HD/target.h +++ b/src/main/target/SKYSTARSH743HD/target.h @@ -71,12 +71,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -198,4 +193,4 @@ #define MAX_PWM_OUTPUT_PORTS 10 #define USE_DSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/SPARKY2/target.c b/src/main/target/SPARKY2/target.c index b4b4b295047..9364f231c54 100644 --- a/src/main/target/SPARKY2/target.c +++ b/src/main/target/SPARKY2/target.c @@ -24,11 +24,11 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // PPM IN - DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM, 0, 0 ), // S2_IN - DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S3_IN - GPIO_PartialRemap_TIM3 - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0 ), // S4_IN - DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0 ), // S5_IN + // DEF_TIM(TIM8, CH2, PC7, TIM_USE_PWM | TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM, 0, 0 ), // S2_IN + // DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM, 0, 0 ), // S3_IN - GPIO_PartialRemap_TIM3 + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PWM, 0, 0 ), // S4_IN + // DEF_TIM(TIM8, CH4, PC9, TIM_USE_PWM, 0, 0 ), // S5_IN DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT diff --git a/src/main/target/SPARKY2/target.h b/src/main/target/SPARKY2/target.h index 76d6e93099f..78f80cd609d 100644 --- a/src/main/target/SPARKY2/target.h +++ b/src/main/target/SPARKY2/target.h @@ -36,15 +36,10 @@ #define MPU9250_CS_PIN PC4 #define USE_MAG -#define USE_MAG_MPU9250 #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL + +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/SPEDIXF405/CMakeLists.txt b/src/main/target/SPEDIXF405/CMakeLists.txt new file mode 100644 index 00000000000..62ce61f7c7e --- /dev/null +++ b/src/main/target/SPEDIXF405/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(SPEDIXF405) diff --git a/src/main/target/SPEDIXF405/target.c b/src/main/target/SPEDIXF405/target.c new file mode 100644 index 00000000000..31a8f73544c --- /dev/null +++ b/src/main/target/SPEDIXF405/target.c @@ -0,0 +1,45 @@ +/* +* This file is part of INAV Project. +* +* 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 "platform.h" +#include "drivers/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 1), + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1),//WS2812B + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM | TIM_USE_FW_SERVO, 0, 0), // "C.C" +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + + diff --git a/src/main/target/SPEDIXF405/target.h b/src/main/target/SPEDIXF405/target.h new file mode 100644 index 00000000000..3f46890b48d --- /dev/null +++ b/src/main/target/SPEDIXF405/target.h @@ -0,0 +1,164 @@ +/* + * This file is part of INAV Project. + * + * 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 + +#define TARGET_BOARD_IDENTIFIER "SPDXF405" + +#define USBD_PRODUCT_STRING "SPEDIXF405" + +#define LED0 PC14 + +#define BEEPER PB2 +#define BEEPER_INVERTED + +// *************** Gyro & ACC ********************** +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW0_DEG +#define MPU6000_CS_PIN SPI1_NSS_PIN +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW0_DEG +#define BMI270_CS_PIN SPI1_NSS_PIN +#define BMI270_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_SPI_BUS BUS_SPI1 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS + +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +// *************** OSD ***************************** +#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_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN +// *************** FLASH ************************** +#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 M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN NONE + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +// *************** PINIO ************************ +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/SPEDIXF722/CMakeLists.txt b/src/main/target/SPEDIXF722/CMakeLists.txt new file mode 100644 index 00000000000..e937ebba9ea --- /dev/null +++ b/src/main/target/SPEDIXF722/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(SPEDIXF722) diff --git a/src/main/target/SPEDIXF722/target.c b/src/main/target/SPEDIXF722/target.c new file mode 100644 index 00000000000..31a8f73544c --- /dev/null +++ b/src/main/target/SPEDIXF722/target.c @@ -0,0 +1,45 @@ +/* +* This file is part of INAV Project. +* +* 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 "platform.h" +#include "drivers/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + +timerHardware_t timerHardware[] = { + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 1), + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1),//WS2812B + // DEF_TIM(TIM2, CH2, PB3, TIM_USE_PWM | TIM_USE_FW_SERVO, 0, 0), // "C.C" +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + + diff --git a/src/main/target/SPEDIXF722/target.h b/src/main/target/SPEDIXF722/target.h new file mode 100644 index 00000000000..511381587a0 --- /dev/null +++ b/src/main/target/SPEDIXF722/target.h @@ -0,0 +1,166 @@ +/* + * This file is part of INAV Project. + * + * 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 + +#define TARGET_BOARD_IDENTIFIER "SPDX722" + +#define USBD_PRODUCT_STRING "SPEDIXF722" + +#define LED0 PC14 + +#define BEEPER PC15 +#define BEEPER_INVERTED + +// *************** Gyro & ACC ********************** +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW0_DEG +#define MPU6000_CS_PIN SPI1_NSS_PIN +#define MPU6000_SPI_BUS BUS_SPI1 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW0_DEG +#define BMI270_CS_PIN SPI1_NSS_PIN +#define BMI270_SPI_BUS BUS_SPI1 + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_SPI_BUS BUS_SPI1 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define DEFAULT_I2C_BUS BUS_I2C1 + +#define USE_BARO +#define BARO_I2C_BUS DEFAULT_I2C_BUS +#define USE_BARO_DPS310 + +#define USE_MAG +#define MAG_I2C_BUS DEFAULT_I2C_BUS +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS DEFAULT_I2C_BUS + +#define PITOT_I2C_BUS DEFAULT_I2C_BUS + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS DEFAULT_I2C_BUS + +// *************** FLASH ************************** +#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 M25P16_CS_PIN SPI3_NSS_PIN +#define M25P16_SPI_BUS BUS_SPI3 +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + + +// *************** OSD ***************************** +#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_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PB11 +#define UART3_TX_PIN PB10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN NONE + +#define USE_UART6 +#define UART6_RX_PIN PC7 +#define UART6_TX_PIN PC6 + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) +// *************** PINIO ************************ +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/SPEEDYBEEF4/target.c b/src/main/target/SPEEDYBEEF4/target.c index b45c517bfaa..075640d0f05 100644 --- a/src/main/target/SPEEDYBEEF4/target.c +++ b/src/main/target/SPEEDYBEEF4/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 UP(1,2) DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 UP(2,1) diff --git a/src/main/target/SPEEDYBEEF4/target.h b/src/main/target/SPEEDYBEEF4/target.h index ff7fc7189af..310f6e9b456 100644 --- a/src/main/target/SPEEDYBEEF4/target.h +++ b/src/main/target/SPEEDYBEEF4/target.h @@ -126,11 +126,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL /*** ADC ***/ #define USE_ADC diff --git a/src/main/target/SPEEDYBEEF405MINI/target.h b/src/main/target/SPEEDYBEEF405MINI/target.h index dd5b9f4cfb3..1f25899ed92 100644 --- a/src/main/target/SPEEDYBEEF405MINI/target.h +++ b/src/main/target/SPEEDYBEEF405MINI/target.h @@ -107,13 +107,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -183,4 +177,4 @@ #define USE_DSHOT #define USE_SERIALSHOT -#define USE_ESC_SENSOR \ No newline at end of file +#define USE_ESC_SENSOR diff --git a/src/main/target/SPEEDYBEEF405V3/target.c b/src/main/target/SPEEDYBEEF405V3/target.c index 05c84f1c807..2a7b6272dae 100644 --- a/src/main/target/SPEEDYBEEF405V3/target.c +++ b/src/main/target/SPEEDYBEEF405V3/target.c @@ -45,6 +45,8 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 0), // S9 + DEF_TIM(TIM8, CH4, PC9, TIM_USE_LED, 0, 0), // LED }; diff --git a/src/main/target/SPEEDYBEEF405V3/target.h b/src/main/target/SPEEDYBEEF405V3/target.h index 99711f82deb..6653ea56c0c 100644 --- a/src/main/target/SPEEDYBEEF405V3/target.h +++ b/src/main/target/SPEEDYBEEF405V3/target.h @@ -100,12 +100,7 @@ // Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** Internal SD card ************************** #define USE_SPI_DEVICE_2 @@ -160,7 +155,7 @@ #define DEFAULT_RX_TYPE RX_TYPE_SERIAL #define SERIALRX_PROVIDER SERIALRX_SBUS -#define MAX_PWM_OUTPUT_PORTS 8 +#define MAX_PWM_OUTPUT_PORTS 9 #define CURRENT_METER_SCALE 386 diff --git a/src/main/target/SPEEDYBEEF405V4/target.h b/src/main/target/SPEEDYBEEF405V4/target.h index 8f333db3c28..1c5c847597f 100644 --- a/src/main/target/SPEEDYBEEF405V4/target.h +++ b/src/main/target/SPEEDYBEEF405V4/target.h @@ -106,14 +106,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define USE_RANGEFINDER #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/SPEEDYBEEF405WING/config.c b/src/main/target/SPEEDYBEEF405WING/config.c index 62f5216cbd2..1948682ebb4 100644 --- a/src/main/target/SPEEDYBEEF405WING/config.c +++ b/src/main/target/SPEEDYBEEF405WING/config.c @@ -29,10 +29,13 @@ #include "fc/fc_msp_box.h" #include "io/serial.h" +#include "io/piniobox.h" void targetConfiguration(void) { serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART1)].functionMask = FUNCTION_RX_SERIAL; serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART3)].functionMask = FUNCTION_GPS; serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART6)].functionMask = FUNCTION_MSP; + + pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; } diff --git a/src/main/target/SPEEDYBEEF405WING/target.h b/src/main/target/SPEEDYBEEF405WING/target.h index ad58668268a..1684faabce1 100644 --- a/src/main/target/SPEEDYBEEF405WING/target.h +++ b/src/main/target/SPEEDYBEEF405WING/target.h @@ -115,14 +115,7 @@ //Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8963 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_VCM5883 +#define USE_MAG_ALL #define RANGEFINDER_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 @@ -175,4 +168,8 @@ #define TARGET_IO_PORTC 0xffff #define TARGET_IO_PORTD (BIT(2)) -#define MAX_PWM_OUTPUT_PORTS 11 \ No newline at end of file +#define MAX_PWM_OUTPUT_PORTS 11 + +#define USE_PINIO +#define USE_PINIOBOX +#define PINIO1_PIN PC13 \ No newline at end of file diff --git a/src/main/target/SPEEDYBEEF7/target.c b/src/main/target/SPEEDYBEEF7/target.c index 78821f52594..ac38530b84e 100644 --- a/src/main/target/SPEEDYBEEF7/target.c +++ b/src/main/target/SPEEDYBEEF7/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/SPEEDYBEEF7/target.h b/src/main/target/SPEEDYBEEF7/target.h index 7f5ed751412..032f7479b5b 100644 --- a/src/main/target/SPEEDYBEEF7/target.h +++ b/src/main/target/SPEEDYBEEF7/target.h @@ -109,12 +109,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 #define PITOT_I2C_BUS BUS_I2C2 diff --git a/src/main/target/SPEEDYBEEF745AIO/target.h b/src/main/target/SPEEDYBEEF745AIO/target.h index 1cb7b7dbc19..3e82678f552 100644 --- a/src/main/target/SPEEDYBEEF745AIO/target.h +++ b/src/main/target/SPEEDYBEEF745AIO/target.h @@ -100,12 +100,7 @@ // Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** SPI3 SD BLACKBOX******************* #define USE_SPI_DEVICE_1 diff --git a/src/main/target/SPEEDYBEEF7MINI/target.c b/src/main/target/SPEEDYBEEF7MINI/target.c index 32b5792dda2..2b0777ab573 100644 --- a/src/main/target/SPEEDYBEEF7MINI/target.c +++ b/src/main/target/SPEEDYBEEF7MINI/target.c @@ -46,7 +46,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM8, CH3, PC8, TIM_USE_LED, 0, 0), // LED D(2, 6, 0) - DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM, RX1 + // DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // PPM, RX1 DEF_TIM(TIM5, CH3, PA2, TIM_USE_PWM, 0, 0), // TX2 & softserial1 }; diff --git a/src/main/target/SPEEDYBEEF7MINI/target.h b/src/main/target/SPEEDYBEEF7MINI/target.h index 0dd3a6e7a83..d267ade336d 100644 --- a/src/main/target/SPEEDYBEEF7MINI/target.h +++ b/src/main/target/SPEEDYBEEF7MINI/target.h @@ -70,13 +70,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/SPEEDYBEEF7V2/target.c b/src/main/target/SPEEDYBEEF7V2/target.c index 0914224a05b..abf06021a14 100644 --- a/src/main/target/SPEEDYBEEF7V2/target.c +++ b/src/main/target/SPEEDYBEEF7V2/target.c @@ -27,7 +27,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM1, CH1, PA8, TIM_USE_OUTPUT_AUTO, 0, 1), // S1 DEF_TIM(TIM1, CH2, PA9, TIM_USE_OUTPUT_AUTO, 0, 1), // S2 diff --git a/src/main/target/SPEEDYBEEF7V2/target.h b/src/main/target/SPEEDYBEEF7V2/target.h index 8b53b53b969..9dfcdf232b8 100644 --- a/src/main/target/SPEEDYBEEF7V2/target.h +++ b/src/main/target/SPEEDYBEEF7V2/target.h @@ -95,9 +95,7 @@ // Mag #define USE_MAG -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define MAG_I2C_BUS BUS_I2C2 // *************** Flash ************************** diff --git a/src/main/target/SPEEDYBEEF7V3/config.c b/src/main/target/SPEEDYBEEF7V3/config.c index b064cd99f96..9bc0a52a898 100644 --- a/src/main/target/SPEEDYBEEF7V3/config.c +++ b/src/main/target/SPEEDYBEEF7V3/config.c @@ -26,9 +26,13 @@ #include "fc/fc_msp_box.h" #include "io/serial.h" +#include "drivers/pwm_mapping.h" void targetConfiguration(void) { serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART4)].functionMask = FUNCTION_ESCSERIAL; pinioBoxConfigMutable()->permanentId[0] = BOX_PERMANENT_ID_USER1; + timerOverridesMutable(timer2id(TIM2))->outputMode = OUTPUT_MODE_MOTORS; + timerOverridesMutable(timer2id(TIM3))->outputMode = OUTPUT_MODE_MOTORS; + timerOverridesMutable(timer2id(TIM4))->outputMode = OUTPUT_MODE_MOTORS; } diff --git a/src/main/target/SPEEDYBEEF7V3/target.h b/src/main/target/SPEEDYBEEF7V3/target.h index 7c1d565c377..87eeb7114f7 100644 --- a/src/main/target/SPEEDYBEEF7V3/target.h +++ b/src/main/target/SPEEDYBEEF7V3/target.h @@ -100,12 +100,7 @@ // Mag #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** Internal SD card ************************** diff --git a/src/main/target/SPRACINGF4EVO/target.c b/src/main/target/SPRACINGF4EVO/target.c index deabe8665d6..5b108168c1e 100755 --- a/src/main/target/SPRACINGF4EVO/target.c +++ b/src/main/target/SPRACINGF4EVO/target.c @@ -23,8 +23,8 @@ timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // PPM / PWM1 / UART2 RX - DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PPM / PWM2 / UART2 TX + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // PPM / PWM1 / UART2 RX + // DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PPM / PWM2 / UART2 TX DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 1), // ESC 1 DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 1), // ESC 2 diff --git a/src/main/target/SPRACINGF4EVO/target.h b/src/main/target/SPRACINGF4EVO/target.h index 6eb48977d14..8af6981e54f 100755 --- a/src/main/target/SPRACINGF4EVO/target.h +++ b/src/main/target/SPRACINGF4EVO/target.h @@ -46,13 +46,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_MPU9250 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/SPRACINGF7DUAL/target.c b/src/main/target/SPRACINGF7DUAL/target.c index f47d1a08355..e94835b93c2 100644 --- a/src/main/target/SPRACINGF7DUAL/target.c +++ b/src/main/target/SPRACINGF7DUAL/target.c @@ -35,8 +35,8 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500_2, DEVHW_MPU6500, MPU6500_2_SPI_ timerHardware_t timerHardware[] = { - DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // PPM / PWM1 / UART2 RX - DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PPM / PWM2 / UART2 TX + // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM | TIM_USE_PWM, 0, 0), // PPM / PWM1 / UART2 RX + // DEF_TIM(TIM9, CH1, PA2, TIM_USE_PWM, 0, 0), // PPM / PWM2 / UART2 TX #if (SPRACINGF7DUAL_REV <= 1) DEF_TIM(TIM8, CH2, PC7, TIM_USE_MOTOR, 0, 0), // ESC 1 diff --git a/src/main/target/SPRACINGF7DUAL/target.h b/src/main/target/SPRACINGF7DUAL/target.h index 20e1104720b..11e1bc934d8 100644 --- a/src/main/target/SPRACINGF7DUAL/target.h +++ b/src/main/target/SPRACINGF7DUAL/target.h @@ -57,12 +57,7 @@ #define MAG_I2C_BUS BUS_I2C1 #define USE_MAG -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 diff --git a/src/main/target/TAKERF722SE/CMakeLists.txt b/src/main/target/TAKERF722SE/CMakeLists.txt new file mode 100644 index 00000000000..c4716f616ee --- /dev/null +++ b/src/main/target/TAKERF722SE/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(TAKERF722SE) \ No newline at end of file diff --git a/src/main/target/TAKERF722SE/target.c b/src/main/target/TAKERF722SE/target.c new file mode 100644 index 00000000000..d67062a9fbc --- /dev/null +++ b/src/main/target/TAKERF722SE/target.c @@ -0,0 +1,48 @@ +/* +* This file is part of INAV Project. +* +* 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/io.h" + +#include "drivers/dma.h" +#include "drivers/timer.h" +#include "drivers/timer_def.h" + + + + + +timerHardware_t timerHardware[] = { + + DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), + + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); + + diff --git a/src/main/target/TAKERF722SE/target.h b/src/main/target/TAKERF722SE/target.h new file mode 100644 index 00000000000..817dc535f03 --- /dev/null +++ b/src/main/target/TAKERF722SE/target.h @@ -0,0 +1,186 @@ +/* + * This file is part of INAV Project. + * + * 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. + * + * 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 "GEPR" + +#define USBD_PRODUCT_STRING "TAKERF722SE" + +#define LED0 PC14 + + +// *************** BEEPER ************************ + +#define BEEPER PC13 +#define BEEPER_INVERTED + + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + + +// *************** UART ***************************** +#define USE_VCP + +#define USE_UART1 +#define UART1_TX_PIN PA9 +#define UART1_RX_PIN PA10 + +#define USE_UART2 +#define UART2_TX_PIN PA2 +#define UART2_RX_PIN PA3 + +#define USE_UART3 +#define UART3_TX_PIN PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART5 +#define UART5_TX_PIN PC12 +#define UART5_RX_PIN PD2 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + + +#define SERIAL_PORT_COUNT 7 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART2 + + +// *************** SPI Bus ********************** + +#define USE_SPI + +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PB2 +#define SPI3_SCK_AF GPIO_AF6_SPI3 +#define SPI3_MISO_AF GPIO_AF6_SPI3 +#define SPI3_MOSI_AF GPIO_AF7_SPI3 + + +// *************** Gyro & ACC ********************** + +#define USE_IMU_MPU6000 +#define IMU_MPU6000_ALIGN CW0_DEG +#define MPU6000_CS_PIN PA4 +#define MPU6000_SPI_BUS BUS_SPI1 + + +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 + +// *************** I2C/Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + + +//*************************************************** +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_BMP280 +#define USE_BARO_DPS310 +#define USE_BARO_MS5611 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_HMC5883 +#define USE_MAG_QMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_IST8308 + +#define TEMPERATURE_I2C_BUS BUS_I2C1 + +#define PITOT_I2C_BUS BUS_I2C1 + +#define USE_RANGEFINDER +#define RANGEFINDER_I2C_BUS BUS_I2C1 +#define BNO055_I2C_BUS BUS_I2C1 + +// *************** FLASH ************************** + +#define USE_FLASHFS + +#define USE_FLASH_M25P16 +#define M25P16_CS_PIN PA15 +#define M25P16_SPI_BUS BUS_SPI3 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT + +// *************** OSD ***************************** + +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// *************** ADC ***************************** + +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 +#define ADC_CHANNEL_1_PIN PC3 +#define ADC_CHANNEL_2_PIN PC0 +#define ADC_CHANNEL_3_PIN PC2 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define RSSI_ADC_CHANNEL ADC_CHN_2 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_3 + + +#define DEFAULT_FEATURES (FEATURE_TX_PROF_SEL | FEATURE_CURRENT_METER | FEATURE_TELEMETRY | FEATURE_VBAT | FEATURE_OSD | FEATURE_BLACKBOX) + + + + +//************************************************** + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD (BIT(2)) + + +#define MAX_PWM_OUTPUT_PORTS 8 + +#define USE_DSHOT +#define USE_ESC_SENSOR diff --git a/src/main/target/TMOTORF7/target.c b/src/main/target/TMOTORF7/target.c index 2f96517ba15..0af36aa68ce 100644 --- a/src/main/target/TMOTORF7/target.c +++ b/src/main/target/TMOTORF7/target.c @@ -37,7 +37,7 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), DEF_TIM(TIM4, CH3, PB8, TIM_USE_OUTPUT_AUTO, 0, 0), - DEF_TIM(TIM2, CH1, PA15, TIM_USE_PPM, 0, 0), + // DEF_TIM(TIM2, CH1, PA15, TIM_USE_PPM, 0, 0), DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0), DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 0) diff --git a/src/main/target/TMOTORF7/target.h b/src/main/target/TMOTORF7/target.h index 890e95b353d..068894323d9 100644 --- a/src/main/target/TMOTORF7/target.h +++ b/src/main/target/TMOTORF7/target.h @@ -52,21 +52,11 @@ #define USE_BARO #define BARO_I2C_BUS BUS_I2C2 -#define USE_BARO_BMP280 -#define USE_BARO_MS5611 -#define USE_BARO_DPS310 +#define USE_BARO_ALL #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_AK8975 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL // *************** SPI2 OSD *********************** #define USE_SPI_DEVICE_2 diff --git a/src/main/target/TMOTORF7V2/target.c b/src/main/target/TMOTORF7V2/target.c index 606ac8819dc..c21b0f0229a 100644 --- a/src/main/target/TMOTORF7V2/target.c +++ b/src/main/target/TMOTORF7V2/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM + // DEF_TIM(TIM5, CH4, PA3, TIM_USE_PPM, 0, 0), // PPM DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 diff --git a/src/main/target/TMOTORF7V2/target.h b/src/main/target/TMOTORF7V2/target.h index 5aaab2e3900..f5def98a403 100644 --- a/src/main/target/TMOTORF7V2/target.h +++ b/src/main/target/TMOTORF7V2/target.h @@ -67,6 +67,11 @@ #define USE_IMU_MPU6000 #define IMU_MPU6000_ALIGN CW0_DEG +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW0_DEG +#define ICM42605_CS_PIN PA4 +#define ICM42605_SPI_BUS BUS_SPI1 + // OSD -- SPI2 #define USE_SPI_DEVICE_2 #define SPI2_SCK_PIN PB13 @@ -95,7 +100,7 @@ // BMP280 BARO --- I2C1 #define USE_I2C #define USE_BARO -#define USE_BARO_BMP280 +#define USE_BARO_ALL #define BARO_I2C_BUS BUS_I2C1 #define USE_I2C_DEVICE_1 @@ -104,12 +109,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define PITOT_I2C_BUS BUS_I2C1 diff --git a/src/main/target/TMOTORVELOXF7V2/CMakeLists.txt b/src/main/target/TMOTORVELOXF7V2/CMakeLists.txt new file mode 100644 index 00000000000..15160ea350d --- /dev/null +++ b/src/main/target/TMOTORVELOXF7V2/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f722xe(TMOTORVELOXF7V2) diff --git a/src/main/target/TMOTORVELOXF7V2/config.c b/src/main/target/TMOTORVELOXF7V2/config.c new file mode 100644 index 00000000000..8134059c38d --- /dev/null +++ b/src/main/target/TMOTORVELOXF7V2/config.c @@ -0,0 +1,32 @@ +/* + * 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 "platform.h" + +#include "drivers/pwm_mapping.h" + +#include "fc/fc_msp_box.h" + +#include "io/piniobox.h" +#include "io/serial.h" + +void targetConfiguration(void) +{ + +} diff --git a/src/main/target/TMOTORVELOXF7V2/target.c b/src/main/target/TMOTORVELOXF7V2/target.c new file mode 100644 index 00000000000..7d9ae0d3292 --- /dev/null +++ b/src/main/target/TMOTORVELOXF7V2/target.c @@ -0,0 +1,43 @@ +/* + * 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, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 UP1-2 D(1, 4, 5) + DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 UP1-2 D(1, 5, 5) + DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 UP1-2 D(1, 7, 5) + DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 UP1-2 D(1, 2, 5) + + DEF_TIM(TIM2, CH1, PA15, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 UP1-7 D(1, 5, 3) - clash with S2 + DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 UP1-7 D(1, 6, 3) + DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 UP1-6 D(1, 0, 2) // used to be fw motor + DEF_TIM(TIM4, CH2, PB7, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 UP1-6 D(1, 3, 2) // used to be fw motor + + DEF_TIM(TIM1, CH1, PA8, TIM_USE_LED, 0, 1), // LED +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/TMOTORVELOXF7V2/target.h b/src/main/target/TMOTORVELOXF7V2/target.h new file mode 100644 index 00000000000..09f30857ec8 --- /dev/null +++ b/src/main/target/TMOTORVELOXF7V2/target.h @@ -0,0 +1,147 @@ +/* + * 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 "TVF7" + +#define USBD_PRODUCT_STRING "TMOTORVELOXF7V2" + +#define LED0 PA14 +#define LED1 PA13 + +#define BEEPER PC13 +#define BEEPER_INVERTED + + +// SPI +#define USE_SPI +#define USE_SPI_DEVICE_1 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_SPI_DEVICE_2 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 + +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PC10 +#define SPI3_MISO_PIN PC11 +#define SPI3_MOSI_PIN PC12 + +//GYRO +#define USE_IMU_ICM42605 +#define IMU_ICM42605_ALIGN CW270_DEG +#define ICM42605_CS_PIN PB2 +#define ICM42605_SPI_BUS BUS_SPI1 + + +// *************** I2C /Baro/Mag ********************* +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C1_SCL PB8 +#define I2C1_SDA PB9 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C1 +#define USE_BARO_ALL + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C1 +#define USE_MAG_ALL + +#define TEMPERATURE_I2C_BUS BUS_I2C1 +#define PITOT_I2C_BUS BUS_I2C1 +#define RANGEFINDER_I2C_BUS BUS_I2C1 + +// *************** SPI2 OSD *********************** +#define USE_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN PB12 + +// *************** SPI3 SD BLACKBOX******************* +#define USE_FLASHFS +#define USE_FLASH_M25P16 +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PD2 +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_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 PA2 +#define UART2_RX_PIN PA3 + +#define USE_UART3 +#define UART3_TX_PIN PB10 +#define UART3_RX_PIN PB11 + +#define USE_UART4 +#define UART4_TX_PIN PA0 +#define UART4_RX_PIN PA1 + +#define USE_UART6 +#define UART6_TX_PIN PC6 +#define UART6_RX_PIN PC7 + +#define SERIAL_PORT_COUNT 6 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_SBUS +#define SERIALRX_UART SERIAL_PORT_USART1 + +// *************** ADC ***************************** +#define USE_ADC +#define ADC_INSTANCE ADC1 +#define ADC1_DMA_STREAM DMA2_Stream0 + +#define ADC_CHANNEL_1_PIN PC2 +#define ADC_CHANNEL_2_PIN PC1 +#define ADC_CHANNEL_3_PIN PC0 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define RSSI_ADC_CHANNEL ADC_CHN_3 + +// *************** LEDSTRIP ************************ +#define USE_LED_STRIP +#define WS2811_PIN PA8 + +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT | FEATURE_TX_PROF_SEL | FEATURE_BLACKBOX) +#define CURRENT_METER_SCALE 250 + +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#define TARGET_IO_PORTD 0xffff + +#define MAX_PWM_OUTPUT_PORTS 8 +#define USE_DSHOT +#define USE_SERIALSHOT +#define USE_DSHOT_DMAR +#define USE_ESC_SENSOR + diff --git a/src/main/target/TUNERCF405/CMakeLists.txt b/src/main/target/TUNERCF405/CMakeLists.txt new file mode 100644 index 00000000000..ba4e9fd3cd3 --- /dev/null +++ b/src/main/target/TUNERCF405/CMakeLists.txt @@ -0,0 +1 @@ +target_stm32f405xg(TUNERCF405) diff --git a/src/main/target/TUNERCF405/target.c b/src/main/target/TUNERCF405/target.c new file mode 100644 index 00000000000..bc0b4e86f65 --- /dev/null +++ b/src/main/target/TUNERCF405/target.c @@ -0,0 +1,39 @@ +/* + * This file is part of INAV Project. + * + * 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" + +timerHardware_t timerHardware[] = { + DEF_TIM(TIM1, CH2N, PB0, TIM_USE_MOTOR, 0, 0), //D2s6 + DEF_TIM(TIM1, CH1, PA8, TIM_USE_MOTOR, 0, 0), //D2s6 + DEF_TIM(TIM4, CH3, PB8, TIM_USE_MOTOR, 0, 0), //D1s7 + DEF_TIM(TIM2, CH1, PA15, TIM_USE_MOTOR, 0, 0), //D1s5 + + DEF_TIM(TIM8, CH4, PC9, TIM_USE_OUTPUT_AUTO, 0, 0), //D2s7 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), //D2s2 / D2s4 + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), //D2s2 + DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 0), //D2s2 + + DEF_TIM(TIM3, CH4, PB1, TIM_USE_LED, 0, 0), +}; + +const int timerHardwareCount = sizeof(timerHardware) / sizeof(timerHardware[0]); diff --git a/src/main/target/TUNERCF405/target.h b/src/main/target/TUNERCF405/target.h new file mode 100644 index 00000000000..f193377c6ea --- /dev/null +++ b/src/main/target/TUNERCF405/target.h @@ -0,0 +1,137 @@ +/* + * This file is part of INAV Project. + * + * 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 + +#define TARGET_BOARD_IDENTIFIER "TURC" + +#define USBD_PRODUCT_STRING "TUNERCF405" + +// Indicators +#define LED0 PB9 + +#define BEEPER PB2 +#define BEEPER_INVERTED + +// WS2812 +#define USE_LED_STRIP +#define WS2811_PIN PB1 + +// Gyro & ACC +#define USE_SPI +#define USE_SPI_DEVICE_1 + +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 + +#define USE_IMU_BMI270 +#define IMU_BMI270_ALIGN CW180_DEG +#define BMI270_CS_PIN SPI1_NSS_PIN +#define BMI270_SPI_BUS BUS_SPI1 + +// OSD +#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_MAX7456 +#define MAX7456_SPI_BUS BUS_SPI2 +#define MAX7456_CS_PIN SPI2_NSS_PIN + +// Onboard Flash +#define USE_SPI_DEVICE_3 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 + +#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT +#define USE_FLASHFS +#define USE_FLASH_M25P16 //W25Q32JVXGIQ TR +#define M25P16_SPI_BUS BUS_SPI3 +#define M25P16_CS_PIN PB6 + +// IIC +#define USE_I2C +#define USE_I2C_DEVICE_2 +#define I2C1_SCL PB10 +#define I2C1_SDA PB11 + +#define USE_BARO +#define BARO_I2C_BUS BUS_I2C2 +#define USE_BARO_BMP280 +#define USE_BARO_DPS310 + +#define USE_MAG +#define MAG_I2C_BUS BUS_I2C2 +#define USE_MAG_ALL + +// Serial ports +#define USE_VCP +#define VBUS_SENSING_PIN PB7 +#define VBUS_SENSING_ENABLED + +#define USE_UART1 +#define UART1_RX_PIN PA10 +#define UART1_TX_PIN PA9 + +#define USE_UART2 +#define UART2_RX_PIN PA3 +#define UART2_TX_PIN PA2 + +#define USE_UART3 +#define UART3_RX_PIN PC11 +#define UART3_TX_PIN PC10 + +#define USE_UART4 +#define UART4_RX_PIN PA1 +#define UART4_TX_PIN PA0 + +#define USE_UART5 +#define UART5_RX_PIN PD2 +#define UART5_TX_PIN PC12 + +#define SERIAL_PORT_COUNT 6 + +#define DEFAULT_RX_TYPE RX_TYPE_SERIAL +#define SERIALRX_PROVIDER SERIALRX_CRSF + +// ADC +#define USE_ADC +#define ADC_CHANNEL_1_PIN PC0 +#define ADC_CHANNEL_2_PIN PC1 + +#define VBAT_ADC_CHANNEL ADC_CHN_1 +#define CURRENT_METER_ADC_CHANNEL ADC_CHN_2 +#define CURRENT_METER_SCALE 453 + +// SET +#define DEFAULT_FEATURES (FEATURE_OSD | FEATURE_CURRENT_METER | FEATURE_VBAT ) +#define USE_DSHOT +#define USE_DSHOT_DMAR +#define USE_SERIAL_4WAY_BLHELI_INTERFACE + +#define MAX_PWM_OUTPUT_PORTS 8 +#define TARGET_MOTOR_COUNT 8 + +#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/YUPIF4/target.c b/src/main/target/YUPIF4/target.c index 310ab66b0aa..837647a89b6 100644 --- a/src/main/target/YUPIF4/target.c +++ b/src/main/target/YUPIF4/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, 0, 0 ), // PPM IN + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, 0, 0 ), // PPM IN DEF_TIM(TIM5, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT - DMA1_ST2 DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT - DMA1_ST4 diff --git a/src/main/target/YUPIF4/target.h b/src/main/target/YUPIF4/target.h index ab9f07cd2c5..6a7bb7d545f 100644 --- a/src/main/target/YUPIF4/target.h +++ b/src/main/target/YUPIF4/target.h @@ -57,8 +57,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C2 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C2 diff --git a/src/main/target/YUPIF7/target.c b/src/main/target/YUPIF7/target.c index cd6a17ee683..3587a8bc4bc 100644 --- a/src/main/target/YUPIF7/target.c +++ b/src/main/target/YUPIF7/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" timerHardware_t timerHardware[] = { - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, 0, 1 ), // PPM IN + // DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, 0, 1 ), // PPM IN DEF_TIM(TIM2, CH1, PA0, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S1_OUT - DMA1_ST2 DEF_TIM(TIM5, CH2, PA1, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S2_OUT - DMA1_ST4 DEF_TIM(TIM5, CH3, PA2, TIM_USE_OUTPUT_AUTO, 0, 0 ), // S3_OUT - DMA1_ST1 diff --git a/src/main/target/YUPIF7/target.h b/src/main/target/YUPIF7/target.h index f494222f0f1..bec10358583 100644 --- a/src/main/target/YUPIF7/target.h +++ b/src/main/target/YUPIF7/target.h @@ -36,8 +36,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C1 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 +#define USE_MAG_ALL #define TEMPERATURE_I2C_BUS BUS_I2C1 #define USE_BARO diff --git a/src/main/target/ZEEZF7/target.c b/src/main/target/ZEEZF7/target.c index f1f5356dcb2..79bfc08d2cb 100755 --- a/src/main/target/ZEEZF7/target.c +++ b/src/main/target/ZEEZF7/target.c @@ -32,9 +32,9 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 1), // S5 - DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 - DEF_TIM(TIM3, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 - DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S7 + DEF_TIM(TIM1, CH3N, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 #endif #ifdef ZEEZF7V2 @@ -42,10 +42,10 @@ timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 0, 0), // S2 DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S3 DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S4 - DEF_TIM(TIM3, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 - DEF_TIM(TIM3, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 + DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S5 + DEF_TIM(TIM8, CH2, PC7, TIM_USE_OUTPUT_AUTO, 0, 0), // S6 DEF_TIM(TIM8, CH1, PC6, TIM_USE_OUTPUT_AUTO, 0, 1), // S7 - DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 + DEF_TIM(TIM1, CH3N, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S8 #endif #ifdef ZEEZF7 diff --git a/src/main/target/ZEEZF7/target.h b/src/main/target/ZEEZF7/target.h index 07e22f1d93b..28395b274fb 100755 --- a/src/main/target/ZEEZF7/target.h +++ b/src/main/target/ZEEZF7/target.h @@ -131,13 +131,7 @@ #define USE_MAG #define MAG_I2C_BUS BUS_I2C3 -#define USE_MAG_HMC5883 -#define USE_MAG_QMC5883 -#define USE_MAG_IST8310 -#define USE_MAG_IST8308 -#define USE_MAG_MAG3110 -#define USE_MAG_LIS3MDL -#define USE_MAG_AK8975 +#define USE_MAG_ALL #endif // *************** Flash **************************** diff --git a/src/main/target/common.h b/src/main/target/common.h old mode 100755 new mode 100644 index 713458002b3..a64a7bb7ed7 --- a/src/main/target/common.h +++ b/src/main/target/common.h @@ -140,8 +140,8 @@ #define USE_POWER_LIMITS -#define NAV_FIXED_WING_LANDING #define USE_SAFE_HOME +#define USE_FW_AUTOLAND #define USE_AUTOTUNE_FIXED_WING #define USE_LOG #define USE_STATS @@ -188,6 +188,9 @@ #define USE_SERIALRX_SUMD #define USE_TELEMETRY_HOTT #define USE_HOTT_TEXTMODE -#else +#define USE_24CHANNELS +#define MAX_MIXER_PROFILE_COUNT 2 +#elif !defined(STM32F7) #define MAX_MIXER_PROFILE_COUNT 1 #endif +#define USE_EZ_TUNE diff --git a/src/main/target/common_post.h b/src/main/target/common_post.h index ec7cc836640..d3ccf280b17 100644 --- a/src/main/target/common_post.h +++ b/src/main/target/common_post.h @@ -42,10 +42,48 @@ extern uint8_t __config_end; // Enable MSP BARO & MAG drivers if BARO and MAG sensors are compiled in #if defined(USE_MAG) #define USE_MAG_MSP + +#if defined(USE_MAG_ALL) + +#define USE_MAG_HMC5883 +#define USE_MAG_IST8310 +#define USE_MAG_LIS3MDL +#define USE_MAG_MAG3110 +#define USE_MAG_QMC5883 + +//#if (MCU_FLASH_SIZE > 512) +#define USE_MAG_AK8963 +#define USE_MAG_AK8975 +#define USE_MAG_IST8308 +#define USE_MAG_MLX90393 + +#if defined(USE_IMU_MPU9250) +#define USE_MAG_MPU9250 #endif +#define USE_MAG_RM3100 +#define USE_MAG_VCM5883 +//#endif // MCU_FLASH_SIZE + +#endif // USE_MAG_ALL + +#endif // USE_MAG + #if defined(USE_BARO) #define USE_BARO_MSP + +#if defined(USE_BARO_ALL) +#define USE_BARO_BMP085 +#define USE_BARO_BMP280 +#define USE_BARO_BMP388 +#define USE_BARO_DPS310 +#define USE_BARO_LPS25H +#define USE_BARO_MS5607 +#define USE_BARO_MS5611 +//#define USE_BARO_SPI_BMP280 +#define USE_BARO_SPL06 +#endif + #endif #ifdef USE_ESC_SENSOR diff --git a/src/main/telemetry/crsf.c b/src/main/telemetry/crsf.c index dca381adea9..5ed25de73be 100755 --- a/src/main/telemetry/crsf.c +++ b/src/main/telemetry/crsf.c @@ -352,7 +352,13 @@ static void crsfFrameFlightMode(sbuf_t *dst) flightMode = "ANGL"; } else if (FLIGHT_MODE(HORIZON_MODE)) { flightMode = "HOR"; + } else if (FLIGHT_MODE(ANGLEHOLD_MODE)) { + flightMode = "ANGH"; } +#ifdef USE_FW_AUTOLAND + } else if (FLIGHT_MODE(NAV_FW_AUTOLAND)) { + flightMode = "LAND"; +#endif #ifdef USE_GPS } else if (feature(FEATURE_GPS) && navConfig()->general.flags.extra_arming_safety && (!STATE(GPS_FIX) || !STATE(GPS_FIX_HOME))) { flightMode = "WAIT"; // Waiting for GPS lock diff --git a/src/main/telemetry/ltm.c b/src/main/telemetry/ltm.c index 00e99a80472..c8cefd87257 100644 --- a/src/main/telemetry/ltm.c +++ b/src/main/telemetry/ltm.c @@ -71,6 +71,7 @@ #include "sensors/gyro.h" #include "sensors/sensors.h" #include "sensors/pitotmeter.h" +#include "sensors/diagnostics.h" #include "telemetry/ltm.h" #include "telemetry/telemetry.h" @@ -178,6 +179,10 @@ void ltm_sframe(sbuf_t *dst) lt_flightmode = LTM_MODE_ANGLE; else if (FLIGHT_MODE(HORIZON_MODE)) lt_flightmode = LTM_MODE_HORIZON; +#ifdef USE_FW_AUTOLAND + else if (FLIGHT_MODE(NAV_FW_AUTOLAND)) + lt_flightmode = LTM_MODE_LAND; +#endif else lt_flightmode = LTM_MODE_RATE; // Rate mode diff --git a/src/main/telemetry/mavlink.c b/src/main/telemetry/mavlink.c index 30237c28552..187f959b178 100644 --- a/src/main/telemetry/mavlink.c +++ b/src/main/telemetry/mavlink.c @@ -191,6 +191,7 @@ static APM_COPTER_MODE inavToArduCopterMap(flightModeForTelemetry_e flightMode) case FLM_ACRO_AIR: return COPTER_MODE_ACRO; case FLM_ANGLE: return COPTER_MODE_STABILIZE; case FLM_HORIZON: return COPTER_MODE_STABILIZE; + case FLM_ANGLEHOLD: return COPTER_MODE_STABILIZE; case FLM_ALTITUDE_HOLD: return COPTER_MODE_ALT_HOLD; case FLM_POSITION_HOLD: return COPTER_MODE_POSHOLD; case FLM_RTH: return COPTER_MODE_RTL; @@ -220,6 +221,7 @@ static APM_PLANE_MODE inavToArduPlaneMap(flightModeForTelemetry_e flightMode) case FLM_ACRO_AIR: return PLANE_MODE_ACRO; case FLM_ANGLE: return PLANE_MODE_FLY_BY_WIRE_A; case FLM_HORIZON: return PLANE_MODE_STABILIZE; + case FLM_ANGLEHOLD: return PLANE_MODE_STABILIZE; case FLM_ALTITUDE_HOLD: return PLANE_MODE_FLY_BY_WIRE_B; case FLM_POSITION_HOLD: return PLANE_MODE_LOITER; case FLM_RTH: return PLANE_MODE_RTL; @@ -662,7 +664,7 @@ void mavlinkSendHUDAndHeartbeat(void) // heading Current heading in degrees, in compass units (0..360, 0=north) DECIDEGREES_TO_DEGREES(attitude.values.yaw), // throttle Current throttle setting in integer percent, 0 to 100 - thr, + thr, // alt Current altitude (MSL), in meters, if we have surface or baro use them, otherwise use GPS (less accurate) mavAltitude, // climb Current climb rate in meters/second @@ -1102,9 +1104,9 @@ void handleMAVLinkTelemetry(timeUs_t currentTimeUs) if ((currentTimeUs - lastMavlinkMessage) >= TELEMETRY_MAVLINK_DELAY) { // Only process scheduled data if we didn't serve any incoming request this cycle - if (!incomingRequestServed || + if (!incomingRequestServed || ( - (rxConfig()->receiverType == RX_TYPE_SERIAL) && + (rxConfig()->receiverType == RX_TYPE_SERIAL) && (rxConfig()->serialrx_provider == SERIALRX_MAVLINK) && !tristateWithDefaultOnIsActive(rxConfig()->halfDuplex) ) diff --git a/src/main/telemetry/sim.c b/src/main/telemetry/sim.c index bb5f8b0465a..af58cd5c438 100644 --- a/src/main/telemetry/sim.c +++ b/src/main/telemetry/sim.c @@ -122,7 +122,7 @@ static uint8_t simModuleState = SIM_MODULE_NOT_DETECTED; static int simRssi; static uint8_t accEvent = ACC_EVENT_NONE; static char* accEventDescriptions[] = { "", "HIT! ", "DROP ", "HIT " }; -static char* modeDescriptions[] = { "MAN", "ACR", "AIR", "ANG", "HOR", "ALH", "POS", "RTH", "WP", "CRS", "LAU", "FS" }; +static char* modeDescriptions[] = { "MAN", "ACR", "AIR", "ANG", "HOR", "ALH", "POS", "RTH", "WP", "CRS", "LAU", "FS", "ANH" }; static const char gpsFixIndicators[] = { '!', '*', ' ' }; static bool checkGroundStationNumber(uint8_t* rv) diff --git a/src/main/telemetry/srxl.c b/src/main/telemetry/srxl.c index 8e01e47ef8e..2c73a1e85ea 100644 --- a/src/main/telemetry/srxl.c +++ b/src/main/telemetry/srxl.c @@ -165,11 +165,13 @@ typedef struct INT8 dBm_A, // Average signal for A antenna in dBm INT8 dBm_B; // Average signal for B antenna in dBm. // If only 1 antenna, set B = A + UINT16 spare[2]; + UINT16 fastbootUptime; // bit 15 = fastboot flag. Bits 0-14= uptime in seconds. 0x0000 --> no data } STRU_TELE_RPM; */ #define STRU_TELE_RPM_EMPTY_FIELDS_COUNT 8 -#define STRU_TELE_RPM_EMPTY_FIELDS_VALUE 0xff +#define STRU_TELE_RPM_EMPTY_FIELDS_VALUE 0x00 #define SPEKTRUM_RPM_UNUSED 0xffff #define SPEKTRUM_TEMP_UNUSED 0x7fff diff --git a/src/main/vcpf4/usbd_cdc_vcp.c b/src/main/vcpf4/usbd_cdc_vcp.c index 2fc2da8b1de..15c1f7e39d9 100644 --- a/src/main/vcpf4/usbd_cdc_vcp.c +++ b/src/main/vcpf4/usbd_cdc_vcp.c @@ -19,16 +19,18 @@ ****************************************************************************** */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -#pragma data_alignment = 4 -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - /* Includes ------------------------------------------------------------------*/ #include "usbd_cdc_vcp.h" #include "stm32f4xx_conf.h" -#include "stdbool.h" +#include #include "drivers/time.h" +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED +#pragma data_alignment = 4 +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; + LINE_CODING g_lc; extern __IO uint8_t USB_Tx_State; @@ -38,11 +40,11 @@ __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */ /* This is the buffer for data received from the MCU to APP (i.e. MCU TX, APP RX) */ extern uint8_t APP_Rx_Buffer[]; -extern uint32_t APP_Rx_ptr_out; +extern volatile uint32_t APP_Rx_ptr_out; /* Increment this buffer position or roll it back to start address when writing received data in the buffer APP_Rx_Buffer. */ -extern uint32_t APP_Rx_ptr_in; +extern volatile uint32_t APP_Rx_ptr_in; /* APP TX is the circular buffer for data that is transmitted from the APP (host) @@ -63,7 +65,6 @@ static void *ctrlLineStateCbContext; static void (*baudRateCb)(void *context, uint32_t baud); static void *baudRateCbContext; -__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; CDC_IF_Prop_TypeDef VCP_fops = {VCP_Init, VCP_DeInit, VCP_Ctrl, VCP_DataTx, VCP_DataRx }; @@ -132,7 +133,7 @@ static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len) //Note - hw flow control on UART 1-3 and 6 only case SET_LINE_CODING: // If a callback is provided, tell the upper driver of changes in baud rate - if (plc && (Len == sizeof (*plc))) { + if (plc && (Len == sizeof(*plc))) { if (baudRateCb) { baudRateCb(baudRateCbContext, plc->bitrate); } @@ -142,7 +143,7 @@ static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len) case GET_LINE_CODING: - if (plc && (Len == sizeof (*plc))) { + if (plc && (Len == sizeof(*plc))) { ust_cpy(plc, &g_lc); } break; @@ -150,7 +151,7 @@ static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len) case SET_CONTROL_LINE_STATE: // If a callback is provided, tell the upper driver of changes in DTR/RTS state - if (plc && (Len == sizeof (uint16_t))) { + if (plc && (Len == sizeof(uint16_t))) { if (ctrlLineStateCb) { ctrlLineStateCb(ctrlLineStateCbContext, *((uint16_t *)Buf)); } @@ -183,14 +184,7 @@ uint32_t CDC_Send_DATA(const uint8_t *ptrBuffer, uint32_t sendLength) uint32_t CDC_Send_FreeBytes(void) { - /* - return the bytes free in the circular buffer - - functionally equivalent to: - (APP_Rx_ptr_out > APP_Rx_ptr_in ? APP_Rx_ptr_out - APP_Rx_ptr_in : APP_RX_DATA_SIZE - APP_Rx_ptr_in + APP_Rx_ptr_in) - but without the impact of the condition check. - */ - return ((APP_Rx_ptr_out - APP_Rx_ptr_in) + (-((int)(APP_Rx_ptr_out <= APP_Rx_ptr_in)) & APP_RX_DATA_SIZE)) - 1; + return APP_RX_DATA_SIZE - CDC_Receive_BytesAvailable(); } /** @@ -210,12 +204,13 @@ static uint16_t VCP_DataTx(const uint8_t* Buf, uint32_t Len) while (USB_Tx_State != 0); for (uint32_t i = 0; i < Len; i++) { - APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i]; - APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE; - - while (CDC_Send_FreeBytes() == 0) { + // Stall if the ring buffer is full + while (((APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE) == APP_Rx_ptr_out) { delay(1); } + + APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i]; + APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE; } return USBD_OK; @@ -232,7 +227,7 @@ uint32_t CDC_Receive_DATA(uint8_t* recvBuf, uint32_t len) { uint32_t count = 0; - while (APP_Tx_ptr_out != APP_Tx_ptr_in && count < len) { + while (APP_Tx_ptr_out != APP_Tx_ptr_in && (count < len)) { recvBuf[count] = APP_Tx_Buffer[APP_Tx_ptr_out]; APP_Tx_ptr_out = (APP_Tx_ptr_out + 1) % APP_TX_DATA_SIZE; count++; @@ -243,7 +238,7 @@ uint32_t CDC_Receive_DATA(uint8_t* recvBuf, uint32_t len) uint32_t CDC_Receive_BytesAvailable(void) { /* return the bytes available in the receive circular buffer */ - return APP_Tx_ptr_out > APP_Tx_ptr_in ? APP_TX_DATA_SIZE - APP_Tx_ptr_out + APP_Tx_ptr_in : APP_Tx_ptr_in - APP_Tx_ptr_out; + return (APP_Tx_ptr_in + APP_TX_DATA_SIZE - APP_Tx_ptr_out) % APP_TX_DATA_SIZE; } /** diff --git a/src/test/unit/osd_unittest.cc b/src/test/unit/osd_unittest.cc index 6a8aa6f0918..fd126c5c41a 100644 --- a/src/test/unit/osd_unittest.cc +++ b/src/test/unit/osd_unittest.cc @@ -14,55 +14,55 @@ TEST(OSDTest, TestCentiNumber) //bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length); char buf[11] = "0123456789"; - osdFormatCentiNumber(buf, 12345, 1, 2, 3, 7); + osdFormatCentiNumber(buf, 12345, 1, 2, 3, 7, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, " 123.45")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, 12345, 1, 2, 2, 6); + osdFormatCentiNumber(buf, 12345, 1, 2, 2, 6, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "123.45")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, 12345, 1, 2, 2, 5); + osdFormatCentiNumber(buf, 12345, 1, 2, 2, 5, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "123.4")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, 12345, 1, 2, 2, 4); + osdFormatCentiNumber(buf, 12345, 1, 2, 2, 4, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, " 123")); // this should be causing #8769 memset(buf, 0, 11); - osdFormatCentiNumber(buf, 12345, 1, 2, 2, 3); + osdFormatCentiNumber(buf, 12345, 1, 2, 2, 3, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "123")); std::cout << "'" << buf << "'" << std::endl; memset(buf, 0, 11); - osdFormatCentiNumber(buf, -12345, 1, 2, 2, 8); + osdFormatCentiNumber(buf, -12345, 1, 2, 2, 8, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, " -123.45")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, -12345, 1, 2, 2, 7); + osdFormatCentiNumber(buf, -12345, 1, 2, 2, 7, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "-123.45")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, -12345, 1, 2, 2, 6); + osdFormatCentiNumber(buf, -12345, 1, 2, 2, 6, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "-123.4")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, -12345, 1, 2, 2, 5); + osdFormatCentiNumber(buf, -12345, 1, 2, 2, 5, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, " -123")); memset(buf, 0, 11); - osdFormatCentiNumber(buf, -12345, 1, 2, 2, 4); + osdFormatCentiNumber(buf, -12345, 1, 2, 2, 4, false); std::cout << "'" << buf << "'" << std::endl; EXPECT_FALSE(strcmp(buf, "-123"));