Browse Source

Added forked version

dev
Englebert 3 years ago
parent
commit
1f3487d629
  1. 94
      AUTHORS
  2. 80
      CMakeLists.txt
  3. 14
      Dockerfile
  4. 31
      JLinkSettings.ini
  5. 674
      LICENSE
  6. 83
      README.md
  7. 32
      Vagrantfile
  8. 32
      build.sh
  9. 60
      build_docs.sh
  10. 172
      cmake/GetGitRevisionDescription.cmake
  11. 41
      cmake/GetGitRevisionDescription.cmake.in
  12. 119
      cmake/arm-none-eabi-checks.cmake
  13. 48
      cmake/arm-none-eabi.cmake
  14. 15
      cmake/ci.cmake
  15. 23
      cmake/cortex-m4f.cmake
  16. 22
      cmake/cortex-m7.cmake
  17. 29
      cmake/docker.sh
  18. 34
      cmake/gcc.cmake
  19. 121
      cmake/main.cmake
  20. 84
      cmake/openocd.cmake
  21. 20
      cmake/openocd_cfg.cmake
  22. 41
      cmake/settings.cmake
  23. 30
      cmake/stm32-bootloader.cmake
  24. 4
      cmake/stm32-stdperiph.cmake
  25. 437
      cmake/stm32.cmake
  26. 16
      cmake/stm32f3-usb.cmake
  27. 95
      cmake/stm32f3.cmake
  28. 59
      cmake/stm32f4-usb.cmake
  29. 155
      cmake/stm32f4.cmake
  30. 48
      cmake/stm32f7-usb.cmake
  31. 140
      cmake/stm32f7.cmake
  32. 41
      cmake/stm32h7-usb.cmake
  33. 220
      cmake/stm32h7.cmake
  34. 16
      cmake/svd.cmake
  35. 40381
      dev/svd/STM32F303.svd
  36. 61681
      dev/svd/STM32F405.svd
  37. 27110
      dev/svd/STM32F411.svd
  38. 63121
      dev/svd/STM32F427.svd
  39. 57155
      dev/svd/STM32F446.svd
  40. 61861
      dev/svd/STM32F7x2.svd
  41. 71136
      dev/svd/STM32F7x5.svd
  42. 70681
      dev/svd/STM32F7x6.svd
  43. 28
      dev/vscode/launch.json
  44. 51
      dev/vscode/tasks.json
  45. 74
      docs/1wire.md
  46. 161
      docs/API/MSP_extensions.md
  47. 59
      docs/Autotune - fixedwing.md
  48. 324
      docs/Battery.md
  49. 262
      docs/Blackbox.md
  50. 85
      docs/Board - Airbot F4 and Flip32 F4.md
  51. 71
      docs/Board - AlienFlight.md
  52. 86
      docs/Board - AnyFC F7.md
  53. 60
      docs/Board - BeeRotor F4.md
  54. 12
      docs/Board - BetFPVF722.md
  55. 106
      docs/Board - DALRCF405.md
  56. 111
      docs/Board - DALRCF722DUAL.md
  57. 33
      docs/Board - FLYWOOF411.md
  58. 16
      docs/Board - FOXEERF405.md
  59. 103
      docs/Board - FOXEERF722DUAL.md
  60. 13
      docs/Board - FrSky Pilot.md
  61. 19
      docs/Board - IFLIGHTF7_TWING.md
  62. 23
      docs/Board - KroozX.md
  63. 30
      docs/Board - Matek F411 Wing.md
  64. 26
      docs/Board - Matek F411-WSE.md
  65. 25
      docs/Board - Matek F722-STD.md
  66. 25
      docs/Board - MatekF405 Wing.md
  67. 124
      docs/Board - MatekF405.md
  68. 92
      docs/Board - MatekF722-SE.md
  69. 14
      docs/Board - MatekF722.md
  70. 28
      docs/Board - MatekF765-Wing.md
  71. 46
      docs/Board - NOX.md
  72. 202
      docs/Board - Omnibus F4.md
  73. 43
      docs/Board - Omnibus F7.md
  74. 94
      docs/Board - PixRacer R14.md
  75. 132
      docs/Board - Revolution.md
  76. 12
      docs/Board - WingFC.md
  77. 38
      docs/Board - YuPiF4.md
  78. 49
      docs/Boards.md
  79. 99
      docs/Buzzer.md
  80. 15
      docs/Channel forwarding.md
  81. 150
      docs/Cli.md
  82. 35
      docs/Configuration.md
  83. 97
      docs/Controls.md
  84. 75
      docs/Display.md
  85. 26
      docs/ESC and servo outputs.md
  86. 146
      docs/Failsafe.md
  87. 107
      docs/Getting Started.md
  88. 25
      docs/INAV PID Controller.md
  89. BIN
      docs/INAV_Autolaunch.pdf
  90. BIN
      docs/INAV_Fixed_Wing_Setup_Guide.pdf
  91. BIN
      docs/INAV_Modes.pdf
  92. BIN
      docs/INAV_Wing_Tuning_Masterclass.pdf
  93. 266
      docs/Inflight Adjustments.md
  94. 30
      docs/Installation.md
  95. 35
      docs/Introduction.md
  96. 599
      docs/LedStrip.md
  97. 33
      docs/Lights.md
  98. 106
      docs/Mixer.md
  99. 112
      docs/Navigation.md
  100. 79
      docs/PID tuning.md

94
AUTHORS

@ -0,0 +1,94 @@
This is at least a partial credits-file of people that have contributed to the INAV project.
If you believe you should be on this list - feel free to open a PR updating it. For faster
inclusion into this list please provide information about which part of code belongs to you.
Albert Kravcov
Alberto García Hierro
Alex Gorbatchev
Alex Zaitsev
Alexander Fedorov
Alexander van Saase
Alexey Stankevich
Andre Bernet
Andreas Tacke
Andrew Payne
Austin St. Aubin
Bas Huisman
Ben Hitchcock
Boris B
Brnadon Miller
ChiggerPepi
Chris Campbell
Chris Mavrakis
Chris Nisbet
Chris Penny
Damjan Adamic
Dave Pitman
David Bieber
Davide Bertola
Denis Kisselev
Dominic Clifton
Frank Zhao
Fredrik Steen
Gareth Wilkins
Gaël James
Gregor Ottmann
Google LLC
Hyon Lim
Hubert Jozwiak
James Harrison
Jan Staal
Jeremy Waters
Joe Hermaszewski
Joe Poser
Joel Fuster
Johannes Kasberger
Jonas Harnesk
Jonathan Hudson
Joshua Bardwell
Juan González
Kemal Hadimli
Kieran Moore
Konstantin Sharlaimov
Krzysztof Rosinski
Kyle Manna
Larry Davis
Marc Egli
Mark Williams
Martin Budden
Matthew Evans
Mauro Mombelli
Max Winterstein
Michael Corcoran
Michael Hope
Michael Jakob
Michel Pastor
Miha Valencic
Mikael Blomqvist
Moritz Ulrich
Moshen Chan
Nathan Tsoi
Nicholas Sherlock
Paul Fertser
Paul Rogalinski
Pawel Spychalski
Petr Ledvina
Phillip Jones
Pierre Hugo
Richard Birkby
Richard Lehey
Richard Marko
Rimas Avizienis
Sam Cook
Sami Korhonen
Samuel Brucksch
Scott Shawcroft
Sean Vig
Stefan Grufman
Stefan Haubold
Steve Amor
Thomas Buck
Tim Eckel
Trey Marc
Tuomas Kuosmanen
Zap Andersson

80
CMakeLists.txt

@ -0,0 +1,80 @@
cmake_minimum_required(VERSION 3.13...3.18)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(MAIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(MAIN_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(MAIN_UTILS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/utils")
set(MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/main")
set(SVD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dev/svd")
set(DOWNLOADS_DIR "${MAIN_DIR}/downloads")
set(TOOLS_DIR "${MAIN_DIR}/tools")
set(TOOLCHAIN_OPTIONS none arm-none-eabi)
set(TOOLCHAIN "arm-none-eabi" CACHE STRING "Toolchain to use. Available: ${TOOLCHAIN_OPTIONS}")
set_property(CACHE TOOLCHAIN PROPERTY STRINGS ${TOOLCHAIN_OPTIONS})
if("" STREQUAL TOOLCHAIN)
set(TOOLCHAIN none)
endif()
if (NOT ${TOOLCHAIN} IN_LIST TOOLCHAIN_OPTIONS)
message(FATAL_ERROR "Invalid toolchain ${TOOLCHAIN}. Valid options are: ${TOOLCHAIN_OPTIONS}")
endif()
option(COMPILER_VERSION_CHECK "Ensure the compiler matches the expected version" ON)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
string(SUBSTRING ${GIT_SHA1} 0 8 GIT_REV)
# Load settings related functions, so the tests can use them
include(main)
include(settings)
if(TOOLCHAIN STREQUAL none)
add_subdirectory(src/test)
else()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${TOOLCHAIN}.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/${TOOLCHAIN}-checks.cmake")
endif()
project(INAV VERSION 3.1.0)
enable_language(ASM)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_program(RUBY_EXECUTABLE ruby)
if (NOT RUBY_EXECUTABLE)
message(FATAL_ERROR "Could not find ruby")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(IS_RELEASE_BUILD ON)
endif()
set(FIRMWARE_VERSION ${PROJECT_VERSION})
option(WARNINGS_AS_ERRORS "Make all warnings into errors")
message("-- toolchain: ${TOOLCHAIN}, WARNINGS_AS_ERRORS: ${WARNINGS_AS_ERRORS}")
set(COMMON_COMPILE_DEFINITIONS
FC_VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}
FC_VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}
FC_VERSION_PATCH_LEVEL=${CMAKE_PROJECT_VERSION_PATCH}
)
include(openocd)
include(svd)
include(stm32)
add_subdirectory(src)
collect_targets()
message("-- Build type: ${CMAKE_BUILD_TYPE}")
include(ci)

14
Dockerfile

@ -0,0 +1,14 @@
FROM ubuntu:focal
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y git cmake make ruby gcc
RUN useradd inav
USER inav
VOLUME /src
WORKDIR /src/build
ENTRYPOINT ["/src/cmake/docker.sh"]

31
JLinkSettings.ini

@ -0,0 +1,31 @@
[BREAKPOINTS]
ShowInfoWin = 1
EnableFlashBP = 2
BPDuringExecution = 0
[CFI]
CFISize = 0x00
CFIAddr = 0x00
[CPU]
OverrideMemMap = 0
AllowSimulation = 1
ScriptFile=""
[FLASH]
MinNumBytesFlashDL = 0
SkipProgOnCRCMatch = 1
VerifyDownload = 1
AllowCaching = 1
EnableFlashDL = 2
Override = 0
Device="AD7160"
[GENERAL]
WorkRAMSize = 0x00
WorkRAMAddr = 0x00
[SWO]
SWOLogFile=""
[MEM]
RdOverrideOrMask = 0x00
RdOverrideAndMask = 0xFFFFFFFF
RdOverrideAddr = 0xFFFFFFFF
WrOverrideOrMask = 0x00
WrOverrideAndMask = 0xFFFFFFFF
WrOverrideAddr = 0xFFFFFFFF

674
LICENSE

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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.
This program 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/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

83
README.md

@ -0,0 +1,83 @@
# INAV - navigation capable flight controller
![INAV](http://static.rcgroups.net/forums/attachments/6/1/0/3/7/6/a9088858-102-inav.png)
## Features
* Runs on the most popular F4 and F7 flight controllers
* Outstanding performance out of the box
* Position Hold, Altitude Hold, Return To Home and Missions
* Excellent support for fixed wing UAVs: airplanes, flying wings
* 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
* SmartAudio and IRC Tramp VTX support
* Blackbox flight recorder logging
* On Screen Display (OSD) - both character and pixel style
* DJI OSD integration: all elements, system messages and warnings
* Telemetry: SmartPort, FPort, MAVlink, LTM
* Multi-color RGB LED Strip support
* Advanced gyro filtering: Matrix Filter and RPM filter
* Logic Conditions, Global Functions and Global Variables: you can program INAV with a GUI
* And many more!
For a list of features, changes and some discussion please review consult the releases [page](https://github.com/iNavFlight/inav/releases) and the documentation.
## Tools
### INAV Configurator
Official tool for INAV can be downloaded [here](https://github.com/iNavFlight/inav-configurator/releases). It can be run on Windows, MacOS and Linux machines and standalone application.
### INAV Blackbox Explorer
Tool for Blackbox logs analysis is available [here](https://github.com/iNavFlight/blackbox-log-viewer/releases)
### Telemetry screen for OpenTX
Users of 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)
## Installation
See: https://github.com/iNavFlight/inav/blob/master/docs/Installation.md
## Documentation, support and learning resources
* [Fixed Wing Guide](docs/INAV_Fixed_Wing_Setup_Guide.pdf)
* [Autolaunch Guide](docs/INAV_Autolaunch.pdf)
* [Modes Guide](docs/INAV_Modes.pdf)
* [Wing Tuning Masterclass](docs/INAV_Wing_Tuning_Masterclass.pdf)
* [Official documentation](https://github.com/iNavFlight/inav/tree/master/docs)
* [Official Wiki](https://github.com/iNavFlight/inav/wiki)
* [INAV Official on Telegram](https://t.me/INAVFlight)
* [INAV Official on Facebook](https://www.facebook.com/groups/INAVOfficial)
* [RC Groups Support](https://www.rcgroups.com/forums/showthread.php?2495732-Cleanflight-iNav-(navigation-rewrite)-project)
* [Video series by Painless360](https://www.youtube.com/playlist?list=PLYsWjANuAm4qdXEGFSeUhOZ10-H8YTSnH)
* [Video series by Paweł Spychalski](https://www.youtube.com/playlist?list=PLOUQ8o2_nCLloACrA6f1_daCjhqY2x0fB)
## Contributing
Contributions are welcome and encouraged. You can contribute in many ways:
* Documentation updates and corrections.
* How-To guides - received help? help others!
* Bug fixes.
* New features.
* Telling us your ideas and suggestions.
* Buying your hardware from this [link](https://inavflight.com/shop/u/bg/)
A good place to start is Telegram channel or Facebook group. Drop in, say hi.
Github issue tracker is a good place to search for existing issues or report a new bug/feature request:
https://github.com/iNavFlight/inav/issues
https://github.com/iNavFlight/inav-configurator/issues
Before creating new issues please check to see if there is an existing one, search first otherwise you waste peoples time when they could be coding instead!
## Developers
Please refer to the development section in the [docs/development](https://github.com/iNavFlight/inav/tree/master/docs/development) folder.
## INAV Releases
https://github.com/iNavFlight/inav/releases

32
Vagrantfile

@ -0,0 +1,32 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "ubuntu/trusty64"
config.vm.synced_folder ".", "/home/vagrant/inav"
config.vm.hostname = "iNavDev"
config.vm.define "iNavDev"
config.vm.provider :virtualbox do |vb|
vb.name = "iNavDev"
end
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
sudo apt-get remove -y --force-yes gcc-arm-none-eabi ruby
sudo apt-add-repository ppa:brightbox/ruby-ng
sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
sudo apt-get update
sudo apt-get install -y --force-yes git gcc-arm-embedded ruby2.4 ruby2.4-dev
SHELL
end

32
build.sh

@ -0,0 +1,32 @@
set -e
if [[ $# == 0 ]]; then
echo -e "\
Usage syntax: ./build.sh <TARGET>
Notes:
* You can specify multiple targets.
* If no targets are specified, *all* of them will be built.
* To clean a target prefix it with \"clean_\".
* To clean all targets just use \"clean\"."
exit 1
fi
if [ -z "$(docker images -q inav-build)" ]; then
echo -e "*** Building image\n"
docker build -t inav-build .
echo -ne "\n"
fi
if [ ! -d ./build ]; then
echo -e "*** Creating build directory\n"
mkdir ./build
fi
echo -e "*** Building targets [$@]\n"
docker run --rm -it -v "$(pwd)":/src inav-build $@
if ls ./build/*.hex &> /dev/null; then
echo -e "\n*** Built targets in ./build:"
stat -c "%n (%.19y)" ./build/*.hex
fi

60
build_docs.sh

@ -0,0 +1,60 @@
#!/bin/bash
filename=Manual
doc_files=(
'Introduction.md'
'Getting Started.md'
'Safety.md'
'Installation.md'
'Configuration.md'
'Cli.md'
'Serial.md'
'Rx.md'
'Spektrum bind.md'
'Failsafe.md'
'Battery.md'
'Gps.md'
'Rssi.md'
'Telemetry.md'
'LedStrip.md'
'Display.md'
'Buzzer.md'
'Sonar.md'
'Profiles.md'
'Modes.md'
'Inflight Adjustments.md'
'Controls.md'
'Gtune.md'
'Blackbox.md'
'Migrating from baseflight.md'
'Boards.md'
'Board - AlienFlight.md'
'Board - ColibriRace.md'
'Board - Motolab.md'
'Board - Paris Air Hero 32.md'
'Board - Sparky.md'
'Board - RMDO.md'
'Board - SPRacingF3.md'
)
if which gimli >/dev/null; then
echo "Building ${filename}.pdf"
pushd . >/dev/null
cd docs
rm -f ${filename}.md
for i in "${doc_files[@]}"
do
cat "$i" >> ${filename}.md
done
rm -f ${filename}.pdf
gimli -f ${filename}.md -stylesheet override.css \
-w '--toc --title "Cleanflight Manual" --footer-right "[page]" --toc-depth 1'
rm ${filename}.md
popd >/dev/null
else
echo -e "\nFAILED"
echo "Install Gimli to build the PDF documentation"
echo -e "https://github.com/walle/gimli\n"
exit 1
fi

172
cmake/GetGitRevisionDescription.cmake

@ -0,0 +1,172 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
if(NOT IS_DIRECTORY "${GIT_DIR}")
file(READ ${GIT_DIR} worktree)
string(REGEX REPLACE "gitdir: (.*)worktrees(.*)\n$" "\\1" GIT_DIR ${worktree})
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
"${GIT_EXECUTABLE}"
diff-index --quiet HEAD --
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var} "CLEAN" PARENT_SCOPE)
else()
set(${_var} "DIRTY" PARENT_SCOPE)
endif()
endfunction()

41
cmake/GetGitRevisionDescription.cmake.in

@ -0,0 +1,41 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

119
cmake/arm-none-eabi-checks.cmake

@ -0,0 +1,119 @@
include(gcc)
set(arm_none_eabi_triplet "arm-none-eabi")
# Keep version in sync with the distribution files below
set(arm_none_eabi_gcc_version "9.3.1")
set(arm_none_eabi_base_url "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update")
# suffix and checksum
set(arm_none_eabi_win32 "win32.zip" 184b3397414485f224e7ba950989aab6)
set(arm_none_eabi_linux_amd64 "x86_64-linux.tar.bz2" 2b9eeccc33470f9d3cda26983b9d2dc6)
set(arm_none_eabi_linux_aarch64 "aarch64-linux.tar.bz2" 000b0888cbe7b171e2225b29be1c327c)
set(arm_none_eabi_gcc_macos "mac.tar.bz2" 75a171beac35453fd2f0f48b3cb239c3)
function(arm_none_eabi_gcc_distname var)
string(REPLACE "/" ";" url_parts ${arm_none_eabi_base_url})
list(LENGTH url_parts n)
math(EXPR last "${n} - 1")
list(GET url_parts ${last} basename)
set(${var} ${basename} PARENT_SCOPE)
endfunction()
function(host_uname_machine var)
# We need to call uname -m manually, since at the point
# this file is included CMAKE_HOST_SYSTEM_PROCESSOR is
# empty because we haven't called project() yet.
execute_process(COMMAND uname -m
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE machine)
set(${var} ${machine} PARENT_SCOPE)
endfunction()
function(arm_none_eabi_gcc_install)
set(dist "")
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(dist ${arm_none_eabi_win32})
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD")
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
message("-- no compiler binaries available for ${CMAKE_HOST_SYSTEM_NAME}, using Linux binaries as a fallback")
endif()
host_uname_machine(machine)
# Linux returns x86_64, FreeBSD returns amd64
if(machine STREQUAL "x86_64" OR machine STREQUAL "amd64")
set(dist ${arm_none_eabi_linux_amd64})
elseif(machine STREQUAL "aarch64")
set(dist ${arm_none_eabi_linux_aarch64})
else()
message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(dist ${arm_none_eabi_gcc_macos})
endif()
if(dist STREQUAL "")
message(FATAL_ERROR "could not install ${arm_none_eabi_triplet}-gcc automatically")
endif()
list(GET dist 0 dist_suffix)
list(GET dist 1 dist_checksum)
set(dist_url "${arm_none_eabi_base_url}-${dist_suffix}")
string(REPLACE "/" ";" url_parts ${dist_url})
list(LENGTH url_parts n)
math(EXPR last "${n} - 1")
list(GET url_parts ${last} basename)
set(output "${DOWNLOADS_DIR}/${basename}")
message("-- downloading ${arm_none_eabi_triplet}-gcc ${arm_none_eabi_gcc_version} from ${dist_url}")
file(DOWNLOAD ${dist_url} ${output}
INACTIVITY_TIMEOUT 30
STATUS status
SHOW_PROGRESS
EXPECTED_HASH MD5=${dist_checksum}
TLS_VERIFY ON
)
list(GET status 0 status_code)
if(NOT status_code EQUAL 0)
list(GET status 1 status_message)
message(FATAL_ERROR "error downloading ${basename}: ${status_message}")
endif()
message("-- extracting ${basename}")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TOOLS_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${output}
RESULT_VARIABLE status
WORKING_DIRECTORY ${TOOLS_DIR}
)
if(NOT status EQUAL 0)
message(FATAL_ERROR "error extracting ${basename}: ${status}")
endif()
endfunction()
function(arm_none_eabi_gcc_add_path)
arm_none_eabi_gcc_distname(dist_name)
set(gcc_path "${TOOLS_DIR}/${dist_name}/bin")
if(CMAKE_HOST_SYSTEM MATCHES ".*Windows.*")
set(sep "\\;")
else()
set(sep ":")
endif()
set(ENV{PATH} "${gcc_path}${sep}$ENV{PATH}")
endfunction()
function(arm_none_eabi_gcc_check)
gcc_get_version(version
TRIPLET ${arm_none_eabi_triplet}
PROGRAM_NAME prog
PROGRAM_PATH prog_path
)
if(NOT version)
message("-- could not find ${prog}")
arm_none_eabi_gcc_install()
return()
endif()
message("-- found ${prog} ${version} at ${prog_path}")
if(COMPILER_VERSION_CHECK AND NOT arm_none_eabi_gcc_version STREQUAL version)
message("-- expecting ${prog} version ${arm_none_eabi_gcc_version}, but got version ${version} instead")
arm_none_eabi_gcc_install()
return()
endif()
endfunction()
arm_none_eabi_gcc_add_path()
arm_none_eabi_gcc_check()

48
cmake/arm-none-eabi.cmake

@ -0,0 +1,48 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
if(WIN32)
set(TOOL_EXECUTABLE_SUFFIX ".exe")
endif()
set(TARGET_TRIPLET "arm-none-eabi")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_ASM_COMPILER "${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "asm compiler")
set(CMAKE_C_COMPILER "${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c compiler")
set(CMAKE_CXX_COMPILER "${TARGET_TRIPLET}-g++${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++ compiler")
set(CMAKE_OBJCOPY "${TARGET_TRIPLET}-objcopy${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objcopy tool")
set(CMAKE_OBJDUMP "${TARGET_TRIPLET}-objdump${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objdump tool")
set(CMAKE_SIZE "${TARGET_TRIPLET}-size${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "size tool")
set(CMAKE_DEBUGGER "${TARGET_TRIPLET}-gdb${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "debugger")
set(CMAKE_CPPFILT "${TARGET_TRIPLET}-c++filt${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++filt")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
if(NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Build Type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES})
set(arm_none_eabi_debug "-Og -g")
# We set -Os or -O2 depending on the MCU family
set(arm_none_eabi_release "-DNDEBUG")
set(arm_none_eabi_relwithdebinfo "-ggdb3 ${arm_none_eabi_release}")
set(CMAKE_C_FLAGS_DEBUG ${arm_none_eabi_debug} CACHE INTERNAL "c compiler flags debug")
set(CMAKE_CXX_FLAGS_DEBUG ${arm_none_eabi_debug} CACHE INTERNAL "c++ compiler flags debug")
set(CMAKE_ASM_FLAGS_DEBUG ${arm_none_eabi_debug} CACHE INTERNAL "asm compiler flags debug")
set(CMAKE_C_FLAGS_RELEASE ${arm_none_eabi_release} CACHE INTERNAL "c compiler flags release")
set(CMAKE_CXX_FLAGS_RELEASE ${arm_none_eabi_release} CACHE INTERNAL "cxx compiler flags release")
set(CMAKE_ASM_FLAGS_RELEASE ${arm_none_eabi_release} CACHE INTERNAL "asm compiler flags release")
set(CMAKE_C_FLAGS_RELWITHDEBINFO ${arm_none_eabi_relwithdebinfo} CACHE INTERNAL "c compiler flags release")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ${arm_none_eabi_relwithdebinfo} CACHE INTERNAL "cxx compiler flags release")
set(CMAKE_ASM_FLAGS_RELWITHDEBINFO ${arm_none_eabi_relwithdebinfo} CACHE INTERNAL "asm compiler flags release")

15
cmake/ci.cmake

@ -0,0 +1,15 @@
if(DEFINED CI_JOB_INDEX AND DEFINED CI_JOB_COUNT)
math(EXPR job_name "${CI_JOB_INDEX}+1")
message("-- configuring CI job ${job_name}/${CI_JOB_COUNT}")
get_property(targets GLOBAL PROPERTY RELEASE_TARGETS)
list(LENGTH targets count)
math(EXPR per_job "(${count}+${CI_JOB_COUNT}-1)/${CI_JOB_COUNT}")
message("-- ${per_job} targets per job")
math(EXPR start "${CI_JOB_INDEX}*${per_job}")
list(SUBLIST targets ${start} ${per_job} ci_targets)
message("-- will build targets: ${ci_targets}")
add_custom_target(ci
${CMAKE_COMMAND} -E true
DEPENDS ${ci_targets}
)
endif()

23
cmake/cortex-m4f.cmake

@ -0,0 +1,23 @@
set(CORTEX_M4F_COMMON_OPTIONS
-mthumb
-mcpu=cortex-m4
-march=armv7e-m
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
-fsingle-precision-constant
-Wdouble-promotion
)
set(CORTEX_M4F_COMPILE_OPTIONS
)
set(CORTEX_M4F_LINK_OPTIONS
)
set(CORTEX_M4F_DEFINITIONS
__FPU_PRESENT=1
ARM_MATH_CM4
ARM_MATH_MATRIX_CHECK
ARM_MATH_ROUNDING
UNALIGNED_SUPPORT_DISABLE
)

22
cmake/cortex-m7.cmake

@ -0,0 +1,22 @@
set(CORTEX_M7_COMMON_OPTIONS
-mthumb
-mcpu=cortex-m7
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
-fsingle-precision-constant
-Wdouble-promotion
)
set(CORTEX_M7_COMPILE_OPTIONS
)
set(CORTEX_M7_LINK_OPTIONS
)
set(CORTEX_M7_DEFINITIONS
__FPU_PRESENT=1
ARM_MATH_CM7
ARM_MATH_MATRIX_CHECK
ARM_MATH_ROUNDING
UNALIGNED_SUPPORT_DISABLE
)

29
cmake/docker.sh

@ -0,0 +1,29 @@
#!/bin/bash
set -e
LAST_CMAKE_AT_REV_FILE="docker_cmake.rev"
CURR_REV="$(git rev-parse HEAD)"
initialize_cmake() {
echo -e "*** CMake was not initialized yet, doing it now.\n"
cmake ..
echo "$CURR_REV" > "$LAST_CMAKE_AT_REV_FILE"
}
# Check if CMake has never been initialized
if [ ! -f Makefile ]; then
initialize_cmake
fi
# Check if CMake was initialized for a different Git revision (new targets may have been added)
if [ -f "$LAST_CMAKE_AT_REV_FILE" ]; then
LAST_CMAKE_AT_REV="$(cat $LAST_CMAKE_AT_REV_FILE)"
if [[ "$LAST_CMAKE_AT_REV" != "SKIP" ]] && [[ "$LAST_CMAKE_AT_REV" != "$CURR_REV" ]]; then
initialize_cmake
fi
else
initialize_cmake
fi
# Let Make handle the arguments coming from the build script
make "$@"

34
cmake/gcc.cmake

@ -0,0 +1,34 @@
function(gcc_get_version var)
cmake_parse_arguments(args
""
"TRIPLET;PROGRAM_NAME;PROGRAM_PATH"
""
${ARGN}
)
set(prog "gcc")
if(args_TRIPLET)
set(prog "${args_TRIPLET}-${prog}")
endif()
if(args_PROGRAM_NAME)
set(${args_PROGRAM_NAME} ${prog} PARENT_SCOPE)
endif()
find_program(gcc ${prog})
if (NOT gcc)
set(${var} OFF PARENT_SCOPE)
endif()
if(args_PROGRAM_PATH)
set(${args_PROGRAM_PATH} ${gcc} PARENT_SCOPE)
endif()
execute_process(COMMAND "${gcc}" -dumpversion
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE version)
if("" STREQUAL version)
set(${var} OFF PARENT_SCOPE)
else()
set(${var} ${version} PARENT_SCOPE)
endif()
endfunction()

121
cmake/main.cmake

@ -0,0 +1,121 @@
set(MAIN_INCLUDE_DIRS
"${MAIN_LIB_DIR}"
"${MAIN_SRC_DIR}"
"${MAIN_LIB_DIR}/main/MAVLink"
)
set(MAIN_DEFINITIONS
__FORKNAME__=inav
__REVISION__="${GIT_REV}"
)
set(MAIN_COMPILE_OPTIONS
-Wall
-Wextra
-Wunsafe-loop-optimizations
-Wdouble-promotion
-Wstrict-prototypes
-Werror=switch
)
macro(main_sources var) # list-var src-1...src-n
set(${var} ${ARGN})
list(TRANSFORM ${var} PREPEND "${MAIN_SRC_DIR}/")
endmacro()
function(exclude_basenames var excludes)
set(filtered "")
foreach(item ${${var}})
get_filename_component(basename ${item} NAME)
if (NOT ${basename} IN_LIST excludes)
list(APPEND filtered ${item})
endif()
endforeach()
set(${var} ${filtered} PARENT_SCOPE)
endfunction()
function(glob_except var pattern excludes)
file(GLOB results ${pattern})
list(LENGTH results count)
if(count EQUAL 0)
message(FATAL_ERROR "glob with pattern '${pattern}' returned no results")
endif()
exclude_basenames(results "${excludes}")
set(${var} ${results} PARENT_SCOPE)
endfunction()
function(get_generated_files_dir output target_name)
set(${output} ${CMAKE_CURRENT_BINARY_DIR}/${target_name} PARENT_SCOPE)
endfunction()
function(setup_executable exe name)
get_generated_files_dir(generated_dir ${name})
target_compile_options(${exe} PRIVATE ${MAIN_COMPILE_OPTIONS})
target_include_directories(${exe} PRIVATE ${generated_dir} ${MAIN_INCLUDE_DIRS})
target_compile_definitions(${exe} PRIVATE ${MAIN_DEFINITIONS} __TARGET__="${name}" ${name})
# XXX: Don't make SETTINGS_GENERATED_C part of the build,
# since it's compiled via #include in settings.c. This will
# change once we move off PGs
target_sources(${exe} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}/${SETTINGS_GENERATED_H}")
set_target_properties(${exe} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
if(IS_RELEASE_BUILD)
set_target_properties(${exe} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION ON
)
endif()
endfunction()
function(setup_firmware_target exe name)
setup_executable(${exe} ${name})
enable_settings(${exe} ${name})
get_property(targets GLOBAL PROPERTY VALID_TARGETS)
list(APPEND targets ${name})
set_property(GLOBAL PROPERTY VALID_TARGETS "${targets}")
setup_openocd(${exe} ${name})
setup_svd(${exe} ${name})
cmake_parse_arguments(args "SKIP_RELEASES" "" "" ${ARGN})
if(args_SKIP_RELEASES)
set_target_properties(${exe} ${name} PROPERTIES SKIP_RELEASES ON)
endif()
endfunction()
function(exclude_from_all target)
set_property(TARGET ${target} PROPERTY
TARGET_MESSAGES OFF
EXCLUDE_FROM_ALL 1
EXCLUDE_FROM_DEFAULT_BUILD 1)
endfunction()
function(collect_targets)
get_property(targets GLOBAL PROPERTY VALID_TARGETS)
list(SORT targets)
set(release_targets)
foreach(target ${targets})
get_target_property(skip_releases ${target} SKIP_RELEASES)
if(NOT skip_releases)
list(APPEND release_targets ${target})
endif()
endforeach()
list(JOIN targets " " target_names)
list(JOIN release_targets " " release_targets_names)
set_property(GLOBAL PROPERTY RELEASE_TARGETS ${release_targets})
set(list_target_name "targets")
add_custom_target(${list_target_name}
COMMAND ${CMAKE_COMMAND} -E echo "Valid targets: ${target_names}"
COMMAND ${CMAKE_COMMAND} -E echo "Release targets: ${release_targets_names}"
)
exclude_from_all(${list_target_name})
set(release_target_name "release")
add_custom_target(${release_target_name}
${CMAKE_COMMAND} -E true
DEPENDS ${release_targets}
)
list(LENGTH targets target_count)
list(LENGTH release_targets release_target_count)
message("-- ${target_count} targets (${release_target_count} for release) found for toolchain ${TOOLCHAIN}")
endfunction()

84
cmake/openocd.cmake

@ -0,0 +1,84 @@
set(OPENOCD "" CACHE STRING "path to openocd (default: search for it)")
set(OPENOCD_CFG "" CACHE STRING "path to openocd configuration (default: generate automatically)")
set(OPENOCD_INTERFACE "" CACHE STRING "openocd interface name (default: automatic depending on target)")
if (OPENOCD)
set(OPENOCD_PATH ${OPENOCD})
else()
find_program(OPENOCD_FOUND_PATH NAMES openocd openocd.exe)
if (NOT OPENOCD_FOUND_PATH)
message(STATUS "Could not find openocd, debugging won't be available")
else()
set(OPENOCD_PATH ${OPENOCD_FOUND_PATH})
endif()
endif()
if(OPENOCD_PATH)
# Retrieve version number as a sanity check
execute_process(COMMAND ${OPENOCD_PATH} -v
OUTPUT_QUIET
ERROR_VARIABLE OPENOCD_HELP
RESULT_VARIABLE OPENOCD_RESULT)
string(REPLACE "\n" ";" OPENOCD_HELP_LINES ${OPENOCD_HELP})
list(GET OPENOCD_HELP_LINES 0 OPENOCD_FIRST_HELP_LINE)
string(REPLACE "\r" "" OPENOCD_HELP_LINE ${OPENOCD_FIRST_HELP_LINE})
if (NOT OPENOCD_RESULT EQUAL 0)
# User provided an incorrect path
message(FATAL_ERROR "error executing ${OPENOCD_PATH} (${OPENOCD_RESULT})")
endif()
message(STATUS "using openocd: ${OPENOCD_HELP_LINE}")
add_custom_target(openocd ${OPENOCD_PATH} -f ${OPENOCD_CFG}
COMMENT "Run openocd using OPENOCD_CFG=(${OPENOCD_CFG}) as configuration"
USES_TERMINAL
)
endif()
function(setup_openocd target_exe target_name)
if(OPENOCD_INTERFACE)
set(openocd_interface ${OPENOCD_INTERFACE})
else()
get_property(openocd_interface TARGET ${target_exe} PROPERTY OPENOCD_DEFAULT_INTERFACE)
endif()
get_property(openocd_target TARGET ${target_exe} PROPERTY OPENOCD_TARGET)
if(OPENOCD_CFG OR (openocd_target AND openocd_interface))
set(openocd_run_target "openocd_${target_name}")
if (OPENOCD_CFG AND NOT OPENOCD_CFG STREQUAL "")
get_filename_component(openocd_cfg_path ${OPENOCD_CFG}
ABSOLUTE
BASE_DIR ${CMAKE_BINARY_DIR})
else()
set(openocd_cfg_path ${CMAKE_BINARY_DIR}/openocd/${target_name}.cfg)
add_custom_command(
OUTPUT ${openocd_cfg_path}
COMMENT "Generating openocd configuration for ${openocd_target} via ${openocd_interface}"
COMMAND ${CMAKE_COMMAND} -P ${MAIN_DIR}/cmake/openocd_cfg.cmake
${openocd_target} ${openocd_interface} ${openocd_cfg_path}
)
endif()
# Target for openocd configuration
set(openocd_cfg_target "openocd_cfg_${target_name}")
add_custom_target(${openocd_cfg_target} DEPENDS ${openocd_cfg_path})
exclude_from_all(${openocd_cfg_target})
# Target for running openocd
add_custom_target(${openocd_run_target} ${OPENOCD_PATH} -f ${openocd_cfg_path}
COMMENT "Running openocd for target ${target_name} via ${openocd_interface}"
DEPENDS ${openocd_cfg_path}
USES_TERMINAL
)
exclude_from_all(${openocd_run_target})
# Target for flashing via openocd
set(openocd_flash_target "openocd_flash_${target_name}")
add_custom_target(${openocd_flash_target} ${CMAKE_COMMAND} -E env
OPENOCD_CMD=${OPENOCD_PATH}
${MAIN_UTILS_DIR}/openocd_flash.py -f
${openocd_cfg_path} $<TARGET_FILE:${target_exe}>
COMMENT "Flashing ${target_name} with openocd"
DEPENDS ${openocd_cfg_path} ${target_exe}
)
exclude_from_all(${openocd_flash_target})
endif()
endfunction()

20
cmake/openocd_cfg.cmake

@ -0,0 +1,20 @@
# This is called from the targets that build the
# openocd.cfg file
if(NOT CMAKE_ARGC EQUAL 6)
message(FATAL_ERROR "usage: cmake -P openocd_cfg.cmake <target> <interface> <output>")
endif()
set(OPENOCD_TARGET ${CMAKE_ARGV3})
set(OPENOCD_INTERFACE ${CMAKE_ARGV4})
set(OUTPUT ${CMAKE_ARGV5})
set(opencd_cfg)
list(APPEND openocd_cfg "source [find interface/${OPENOCD_INTERFACE}.cfg]")
list(APPEND openocd_cfg "source [find target/${OPENOCD_TARGET}.cfg]")
list(APPEND openocd_cfg "init")
list(APPEND openocd_cfg "arm semihosting enable")
list(APPEND openocd_cfg "reset halt")
list(JOIN openocd_cfg "\n" contents)
set(contents "${contents}\n")
file(WRITE ${OUTPUT} ${contents})

41
cmake/settings.cmake

@ -0,0 +1,41 @@
set(SETTINGS_GENERATED "settings_generated")
set(SETTINGS_GENERATED_C "${SETTINGS_GENERATED}.c")
set(SETTINGS_GENERATED_H "${SETTINGS_GENERATED}.h")
set(SETTINGS_FILE "${MAIN_SRC_DIR}/fc/settings.yaml")
set(SETTINGS_GENERATOR "${MAIN_UTILS_DIR}/settings.rb")
include(CMakeParseArguments)
function(enable_settings exe name)
get_generated_files_dir(dir ${name})
get_target_property(options ${exe} COMPILE_OPTIONS)
get_target_property(includes ${exe} INCLUDE_DIRECTORIES)
list(TRANSFORM includes PREPEND "-I")
get_target_property(defs ${exe} COMPILE_DEFINITIONS)
list(TRANSFORM defs PREPEND "-D")
list(APPEND cflags ${options})
list(APPEND cflags ${includes})
list(APPEND cflags ${defs})
cmake_parse_arguments(
args
# Boolean arguments
""
# Single value arguments
"OUTPUTS;SETTINGS_CXX"
# Multi-value arguments
""
# Start parsing after the known arguments
${ARGN}
)
set(output ${dir}/${SETTINGS_GENERATED_H} ${dir}/${SETTINGS_GENERATED_C})
add_custom_command(
OUTPUT ${output}
COMMAND
${CMAKE_COMMAND} -E env CFLAGS="${cflags}" TARGET=${name} PATH=$ENV{PATH} SETTINGS_CXX=${args_SETTINGS_CXX}
${RUBY_EXECUTABLE} ${SETTINGS_GENERATOR} ${MAIN_DIR} ${SETTINGS_FILE} -o "${dir}"
DEPENDS ${SETTINGS_GENERATOR} ${SETTINGS_FILE}
)
set(${args_OUTPUTS} ${output} PARENT_SCOPE)
endfunction()

30
cmake/stm32-bootloader.cmake

@ -0,0 +1,30 @@
main_sources(BOOTLOADER_SOURCES
common/log.c
common/log.h
common/printf.c
common/printf.h
common/string_light.c
common/string_light.h
common/typeconversion.c
common/typeconversion.h
drivers/bus.c
drivers/bus_busdev_i2c.c
drivers/bus_busdev_spi.c
drivers/bus_i2c_soft.c
drivers/io.c
drivers/light_led.c
drivers/persistent.c
drivers/rcc.c
drivers/serial.c
drivers/system.c
drivers/time.c
drivers/timer.c
fc/firmware_update_common.c
fc/firmware_update_common.h
target/common_hardware.c
)
list(APPEND BOOTLOADER_SOURCES ${MAIN_DIR}/src/bl/bl_main.c)

4
cmake/stm32-stdperiph.cmake

@ -0,0 +1,4 @@
main_sources(STM32_STDPERIPH_SRC
drivers/bus_spi.c
drivers/serial_uart.c
)

437
cmake/stm32.cmake

@ -0,0 +1,437 @@
include(stm32-bootloader)
include(stm32f3)
include(stm32f4)
include(stm32f7)
include(stm32h7)
include(CMakeParseArguments)
option(DEBUG_HARDFAULTS "Enable debugging of hard faults via custom handler")
option(SEMIHOSTING "Enable semihosting")
message("-- DEBUG_HARDFAULTS: ${DEBUG_HARDFAULTS}, SEMIHOSTING: ${SEMIHOSTING}")
set(CMSIS_DIR "${MAIN_LIB_DIR}/main/CMSIS")
set(CMSIS_INCLUDE_DIR "${CMSIS_DIR}/Core/Include")
set(CMSIS_DSP_DIR "${MAIN_LIB_DIR}/main/CMSIS/DSP")
set(CMSIS_DSP_INCLUDE_DIR "${CMSIS_DSP_DIR}/Include")
set(CMSIS_DSP_SRC
BasicMathFunctions/arm_mult_f32.c
TransformFunctions/arm_rfft_fast_f32.c
TransformFunctions/arm_cfft_f32.c
TransformFunctions/arm_rfft_fast_init_f32.c
TransformFunctions/arm_cfft_radix8_f32.c
TransformFunctions/arm_bitreversal2.S
CommonTables/arm_common_tables.c
ComplexMathFunctions/arm_cmplx_mag_f32.c
StatisticsFunctions/arm_max_f32.c
)
list(TRANSFORM CMSIS_DSP_SRC PREPEND "${CMSIS_DSP_DIR}/Source/")
set(STM32_STARTUP_DIR "${MAIN_SRC_DIR}/startup")
main_sources(STM32_VCP_SRC
drivers/serial_usb_vcp.c
drivers/usb_io.c
)
main_sources(STM32_SDCARD_SRC
drivers/sdcard/sdcard.c
drivers/sdcard/sdcard_spi.c
drivers/sdcard/sdcard_sdio.c
drivers/sdcard/sdcard_standard.c
)
# XXX: This code is not STM32 specific
main_sources(STM32_ASYNCFATFS_SRC
io/asyncfatfs/asyncfatfs.c
io/asyncfatfs/fat_standard.c
)
main_sources(STM32_MSC_SRC
msc/usbd_storage.c
)
main_sources(STM32_MSC_FLASH_SRC
msc/usbd_storage_emfat.c
msc/emfat.c
msc/emfat_file.c
)
main_sources(STM32_MSC_SDCARD_SRC
msc/usbd_storage_sd_spi.c
)
set(STM32_INCLUDE_DIRS
"${CMSIS_INCLUDE_DIR}"
"${CMSIS_DSP_INCLUDE_DIR}"
"${MAIN_SRC_DIR}/target"
)
set(STM32_DEFINITIONS
)
set(STM32_DEFAULT_HSE_MHZ 8)
set(STM32_LINKER_DIR "${MAIN_SRC_DIR}/target/link")
set(STM32_COMPILE_OPTIONS
-ffunction-sections
-fdata-sections
-fno-common
)
set(STM32_LINK_LIBRARIES
-lm
-lc
)
if(SEMIHOSTING)
list(APPEND STM32_LINK_LIBRARIES --specs=rdimon.specs -lrdimon)
list(APPEND STM32_DEFINITIONS SEMIHOSTING)
else()
list(APPEND STM32_LINK_LIBRARIES -lnosys)
endif()
set(STM32_LINK_OPTIONS
-nostartfiles
--specs=nano.specs
-static
-Wl,-gc-sections
-Wl,-L${STM32_LINKER_DIR}
-Wl,--cref
-Wl,--no-wchar-size-warning
-Wl,--print-memory-usage
)
macro(get_stm32_target_features output_var dir target_name)
execute_process(COMMAND "${CMAKE_C_COMPILER}" -E -dD -D${ARGV2} "${ARGV1}/target.h"
ERROR_VARIABLE _errors
RESULT_VARIABLE _result
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE _contents)
if(NOT _result EQUAL 0)
message(FATAL_ERROR "error extracting features for stm32 target ${ARGV2}: ${_errors}")
endif()
string(REGEX MATCH "#define[\t ]+USE_VCP" HAS_VCP ${_contents})
if(HAS_VCP)
list(APPEND ${ARGV0} VCP)
endif()
string(REGEX MATCH "define[\t ]+USE_FLASHFS" HAS_FLASHFS ${_contents})
if(HAS_FLASHFS)
list(APPEND ${ARGV0} FLASHFS)
endif()
string(REGEX MATCH "define[\t ]+USE_SDCARD" HAS_SDCARD ${_contents})
if (HAS_SDCARD)
list(APPEND ${ARGV0} SDCARD)
string(REGEX MATCH "define[\t ]+USE_SDCARD_SDIO" HAS_SDIO ${_contents})
if (HAS_SDIO)
list(APPEND ${ARGV0} SDIO)
endif()
endif()
if(HAS_FLASHFS OR HAS_SDCARD)
list(APPEND ${ARGV0} MSC)
endif()
endmacro()
function(get_stm32_flash_size out size)
# 4: 16, 6: 32, 8: 64, B: 128, C: 256, D: 384, E: 512, F: 768, G: 1024, H: 1536, I: 2048 KiB
string(TOUPPER ${size} s)
if(${s} STREQUAL "4")
set(${out} 16 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "6")
set(${out} 32 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "8")
set(${out} 64 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "8")
set(${out} 64 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "B")
set(${out} 128 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "C")
set(${out} 256 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "D")
set(${out} 384 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "E")
set(${out} 512 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "F")
set(${out} 768 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "G")
set(${out} 1024 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "H")
set(${out} 1536 PARENT_SCOPE)
return()
endif()
if(${s} STREQUAL "I")
set(${out} 2048 PARENT_SCOPE)
return()
endif()
endfunction()
function(add_hex_target name exe hex)
add_custom_target(${name} ALL
cmake -E env PATH=$ENV{PATH}
# TODO: Overriding the start address with --set-start 0x08000000
# seems to be required due to some incorrect assumptions about .hex
# files in the configurator. Verify wether that's the case and fix
# the bug in configurator or delete this comment.
${CMAKE_OBJCOPY} -Oihex --set-start 0x08000000 $<TARGET_FILE:${exe}> ${hex}
BYPRODUCTS ${hex}
)
endfunction()
function(add_bin_target name exe bin)
add_custom_target(${name}
cmake -E env PATH=$ENV{PATH}
${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${exe}> ${bin}
BYPRODUCTS ${bin}
)
endfunction()
function(generate_map_file target)
if(CMAKE_VERSION VERSION_LESS 3.15)
set(map "$<TARGET_FILE:${target}>.map")
else()
set(map "$<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.map")
endif()
target_link_options(${target} PRIVATE "-Wl,-Map,${map}")
endfunction()
function(set_linker_script target script)
set(script_path ${STM32_LINKER_DIR}/${args_LINKER_SCRIPT}.ld)
if(NOT EXISTS ${script_path})
message(FATAL_ERROR "linker script ${script_path} doesn't exist")
endif()
set_target_properties(${target} PROPERTIES LINK_DEPENDS ${script_path})
target_link_options(${elf_target} PRIVATE -T${script_path})
endfunction()
function(add_stm32_executable)
cmake_parse_arguments(
args
# Boolean arguments
""
# Single value arguments
"FILENAME;NAME;OPTIMIZATION;OUTPUT_BIN_FILENAME;OUTPUT_HEX_FILENAME;OUTPUT_TARGET_NAME"
# Multi-value arguments
"COMPILE_DEFINITIONS;COMPILE_OPTIONS;INCLUDE_DIRECTORIES;LINK_OPTIONS;LINKER_SCRIPT;SOURCES"
# Start parsing after the known arguments
${ARGN}
)
set(elf_target ${args_NAME}.elf)
add_executable(${elf_target})
target_sources(${elf_target} PRIVATE ${args_SOURCES})
target_include_directories(${elf_target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${args_INCLUDE_DIRECTORIES} ${STM32_INCLUDE_DIRS})
target_compile_definitions(${elf_target} PRIVATE ${args_COMPILE_DEFINITIONS})
target_compile_options(${elf_target} PRIVATE ${STM32_COMPILE_OPTIONS} ${args_COMPILE_OPTIONS})
if(WARNINGS_AS_ERRORS)
target_compile_options(${elf_target} PRIVATE -Werror)
endif()
if (IS_RELEASE_BUILD)
target_compile_options(${elf_target} PRIVATE ${args_OPTIMIZATION})
target_link_options(${elf_target} PRIVATE ${args_OPTIMIZATION})
endif()
target_link_libraries(${elf_target} PRIVATE ${STM32_LINK_LIBRARIES})
target_link_options(${elf_target} PRIVATE ${STM32_LINK_OPTIONS} ${args_LINK_OPTIONS})
generate_map_file(${elf_target})
set_linker_script(${elf_target} ${args_LINKER_SCRIPT})
if(args_FILENAME)
set(basename ${CMAKE_BINARY_DIR}/${args_FILENAME})
set(hex_filename ${basename}.hex)
add_hex_target(${args_NAME} ${elf_target} ${hex_filename})
set(bin_filename ${basename}.bin)
add_bin_target(${args_NAME}.bin ${elf_target} ${bin_filename})
endif()
if(args_OUTPUT_BIN_FILENAME)
set(${args_OUTPUT_BIN_FILENAME} ${bin_filename} PARENT_SCOPE)
endif()
if(args_OUTPUT_TARGET_NAME)
set(${args_OUTPUT_TARGET_NAME} ${elf_target} PARENT_SCOPE)
endif()
if(args_OUTPUT_HEX_FILENAME)
set(${args_OUTPUT_HEX_FILENAME} ${hex_filename} PARENT_SCOPE)
endif()
endfunction()
function(target_stm32)
if(NOT arm-none-eabi STREQUAL TOOLCHAIN)
return()
endif()
# Parse keyword arguments
cmake_parse_arguments(
args
# Boolean arguments
"DISABLE_MSC;BOOTLOADER"
# Single value arguments
"HSE_MHZ;LINKER_SCRIPT;NAME;OPENOCD_TARGET;OPTIMIZATION;STARTUP;SVD"
# Multi-value arguments
"COMPILE_DEFINITIONS;COMPILE_OPTIONS;INCLUDE_DIRECTORIES;LINK_OPTIONS;SOURCES;MSC_SOURCES;MSC_INCLUDE_DIRECTORIES;VCP_SOURCES;VCP_INCLUDE_DIRECTORIES"
# Start parsing after the known arguments
${ARGN}
)
set(name ${args_NAME})
if (args_HSE_MHZ)
set(hse_mhz ${args_HSE_MHZ})
else()
set(hse_mhz ${STM32_DEFAULT_HSE_MHZ})
endif()
set(target_sources ${STM32_STARTUP_DIR}/${args_STARTUP})
list(APPEND target_sources ${args_SOURCES})
file(GLOB target_c_sources "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
file(GLOB target_h_sources "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
list(APPEND target_sources ${target_c_sources} ${target_h_sources})
set(target_include_directories ${args_INCLUDE_DIRECTORIES})
set(target_definitions ${STM32_DEFINITIONS} ${COMMON_COMPILE_DEFINITIONS})
get_stm32_target_features(features "${CMAKE_CURRENT_SOURCE_DIR}" ${name})
set_property(TARGET ${elf_target} PROPERTY FEATURES ${features})
if(VCP IN_LIST features)
list(APPEND target_sources ${STM32_VCP_SRC} ${args_VCP_SOURCES})
list(APPEND target_include_directories ${args_VCP_INCLUDE_DIRECTORIES})
endif()
if(SDCARD IN_LIST features)
list(APPEND target_sources ${STM32_SDCARD_SRC} ${STM32_ASYNCFATFS_SRC})
endif()
set(msc_sources)
if(NOT args_DISABLE_MSC AND MSC IN_LIST features)
list(APPEND target_include_directories ${args_MSC_INCLUDE_DIRECTORIES})
list(APPEND msc_sources ${STM32_MSC_SRC} ${args_MSC_SOURCES})
list(APPEND target_definitions USE_USB_MSC)
if(FLASHFS IN_LIST features)
list(APPEND msc_sources ${STM32_MSC_FLASH_SRC})
endif()
if (SDCARD IN_LIST features)
list(APPEND msc_sources ${STM32_MSC_SDCARD_SRC})
endif()
endif()
math(EXPR hse_value "${hse_mhz} * 1000000")
list(APPEND target_definitions "HSE_VALUE=${hse_value}")
if(args_COMPILE_DEFINITIONS)
list(APPEND target_definitions ${args_COMPILE_DEFINITIONS})
endif()
if(DEBUG_HARDFAULTS)
list(APPEND target_definitions DEBUG_HARDFAULTS)
endif()
string(TOLOWER ${PROJECT_NAME} lowercase_project_name)
set(binary_name ${lowercase_project_name}_${FIRMWARE_VERSION}_${name})
if(DEFINED BUILD_SUFFIX AND NOT "" STREQUAL "${BUILD_SUFFIX}")
set(binary_name "${binary_name}_${BUILD_SUFFIX}")
endif()
# Main firmware
add_stm32_executable(
NAME ${name}
FILENAME ${binary_name}
SOURCES ${target_sources} ${msc_sources} ${CMSIS_DSP_SRC} ${COMMON_SRC}
COMPILE_DEFINITIONS ${target_definitions}
COMPILE_OPTIONS ${args_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${target_include_directories}
LINK_OPTIONS ${args_LINK_OPTIONS}
LINKER_SCRIPT ${args_LINKER_SCRIPT}
OPTIMIZATION ${args_OPTIMIZATION}
OUTPUT_HEX_FILENAME main_hex_filename
OUTPUT_TARGET_NAME main_target_name
)
set_property(TARGET ${main_target_name} PROPERTY OPENOCD_TARGET ${args_OPENOCD_TARGET})
set_property(TARGET ${main_target_name} PROPERTY OPENOCD_DEFAULT_INTERFACE stlink)
set_property(TARGET ${main_target_name} PROPERTY SVD ${args_SVD})
setup_firmware_target(${main_target_name} ${name} ${ARGN})
if(args_BOOTLOADER)
# Bootloader for the target
set(bl_suffix _bl)
add_stm32_executable(
NAME ${name}${bl_suffix}
FILENAME ${binary_name}${bl_suffix}
SOURCES ${target_sources} ${BOOTLOADER_SOURCES}
COMPILE_DEFINITIONS ${target_definitions} BOOTLOADER MSP_FIRMWARE_UPDATE
COMPILE_OPTIONS ${args_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${target_include_directories}
LINK_OPTIONS ${args_LINK_OPTIONS}
LINKER_SCRIPT ${args_LINKER_SCRIPT}${bl_suffix}
OPTIMIZATION ${args_OPTIMIZATION}
OUTPUT_BIN_FILENAME bl_bin_filename
OUTPUT_HEX_FILENAME bl_hex_filename
OUTPUT_TARGET_NAME bl_target_name
)
setup_executable(${bl_target_name} ${name})
# Main firmware, but for running with the bootloader
set(for_bl_suffix _for_bl)
add_stm32_executable(
NAME ${name}${for_bl_suffix}
FILENAME ${binary_name}${for_bl_suffix}
SOURCES ${target_sources} ${msc_sources} ${CMSIS_DSP_SRC} ${COMMON_SRC}
COMPILE_DEFINITIONS ${target_definitions} MSP_FIRMWARE_UPDATE
COMPILE_OPTIONS ${args_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${target_include_directories}
LINK_OPTIONS ${args_LINK_OPTIONS}
LINKER_SCRIPT ${args_LINKER_SCRIPT}${for_bl_suffix}
OPTIMIZATION ${args_OPTIMIZATION}
OUTPUT_BIN_FILENAME for_bl_bin_filename
OUTPUT_HEX_FILENAME for_bl_hex_filename
OUTPUT_TARGET_NAME for_bl_target_name
)
setup_executable(${for_bl_target_name} ${name})
# Combined with bootloader and main firmware
set(with_bl_suffix _with_bl)
set(combined_hex ${CMAKE_BINARY_DIR}/${binary_name}${with_bl_suffix}.hex)
set(with_bl_target ${name}${with_bl_suffix})
add_custom_target(${with_bl_target}
${CMAKE_SOURCE_DIR}/src/utils/combine_tool ${bl_bin_filename} ${for_bl_bin_filename} ${combined_hex}
BYPRODUCTS ${combined_hex}
)
add_dependencies(${with_bl_target} ${bl_target_name} ${for_bl_target_name})
endif()
# clean_<target>
set(generator_cmd "")
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
set(generator_cmd "make")
elseif(CMAKE_GENERATOR STREQUAL "Ninja")
set(generator_cmd "ninja")
endif()
if (NOT generator_cmd STREQUAL "")
set(clean_target "clean_${name}")
add_custom_target(${clean_target}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${generator_cmd} clean
COMMENT "Removing intermediate files for ${name}")
set_property(TARGET ${clean_target} PROPERTY
EXCLUDE_FROM_ALL 1
EXCLUDE_FROM_DEFAULT_BUILD 1)
endif()
endfunction()

16
cmake/stm32f3-usb.cmake

@ -0,0 +1,16 @@
set(STM32_USBFS_DIR "${MAIN_LIB_DIR}/main/STM32_USB-FS-Device_Driver")
set(STM32_USBFS_SRC
usb_core.c
usb_init.c
usb_int.c
usb_mem.c
usb_regs.c
usb_sil.c
)
list(TRANSFORM STM32_USBFS_SRC PREPEND "${STM32_USBFS_DIR}/src/")
set(STM32F3_USB_INCLUDE_DIRS
${STM32_USBFS_DIR}/inc
)
set(STM32F3_USB_SRC ${STM32_USBFS_SRC})

95
cmake/stm32f3.cmake

@ -0,0 +1,95 @@
include(cortex-m4f)
include(stm32-stdperiph)
include(stm32f3-usb)
set(STM32F3_STDPERIPH_DIR "${MAIN_LIB_DIR}/main/STM32F3/Drivers/STM32F30x_StdPeriph_Driver")
set(STM32F3_CMSIS_DEVICE_DIR "${MAIN_LIB_DIR}/main/STM32F3/Drivers/CMSIS/Device/ST/STM32F30x")
set(STM32F3_CMSIS_DRIVERS_DIR "${MAIN_LIB_DIR}/main/STM32F3/Drivers/CMSIS")
set(STM32F3_VCP_DIR "${MAIN_SRC_DIR}/vcp")
set(STM32F3_STDPERIPH_SRC_EXCLUDES
stm32f30x_crc.c
stm32f30x_can.c
)
set(STM32F3_STDPERIPH_SRC_DIR "${STM32F3_STDPERIPH_DIR}/src")
glob_except(STM32F3_STDPERIPH_SRC "${STM32F3_STDPERIPH_SRC_DIR}/*.c" "${STM32F3_STDPERIPH_SRC_EXCLUDES}")
main_sources(STM32F3_SRC
target/system_stm32f30x.c
config/config_streamer_stm32f3.c
drivers/adc_stm32f30x.c
drivers/bus_i2c_stm32f30x.c
drivers/dma_stm32f3xx.c
drivers/serial_uart_stm32f30x.c
drivers/system_stm32f30x.c
drivers/timer_impl_stdperiph.c
drivers/timer_stm32f30x.c
)
set(STM32F3_VCP_SRC
hw_config.c
stm32_it.c
usb_desc.c
usb_endp.c
usb_istr.c
usb_prop.c
usb_pwr.c
)
list(TRANSFORM STM32F3_VCP_SRC PREPEND "${STM32F3_VCP_DIR}/")
set(STM32F3_INCLUDE_DIRS
"${CMSIS_INCLUDE_DIR}"
"${CMSIS_DSP_INCLUDE_DIR}"
"${STM32F3_STDPERIPH_DIR}/inc"
"${STM32F3_CMSIS_DEVICE_DIR}"
"${STM32F3_CMSIS_DRIVERS_DIR}"
"${STM32F3_VCP_DIR}"
)
set(STM32F3_DEFINITIONS
${CORTEX_M4F_DEFINITIONS}
STM32F3
USE_STDPERIPH_DRIVER
)
set(STM32F303CC_DEFINITIONS
STM32F303
STM32F303xC
MCU_FLASH_SIZE=256
)
function(target_stm32f3xx)
# F3 targets don't support MSC and use -Os instead of -O2 to save size
target_stm32(
SOURCES ${STM32_STDPERIPH_SRC} ${STM32F3_STDPERIPH_SRC} ${STM32F3_SRC}
COMPILE_DEFINITIONS ${STM32F3_DEFINITIONS}
COMPILE_OPTIONS ${CORTEX_M4F_COMMON_OPTIONS} ${CORTEX_M4F_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${STM32F3_INCLUDE_DIRS}
LINK_OPTIONS ${CORTEX_M4F_COMMON_OPTIONS} ${CORTEX_M4F_LINK_OPTIONS}
VCP_SOURCES ${STM32F3_USB_SRC} ${STM32F3_VCP_SRC}
VCP_INCLUDE_DIRECTORIES ${STM32F3_USB_INCLUDE_DIRS}
DISABLE_MSC
OPTIMIZATION -Os
OPENOCD_TARGET stm32f3x
${ARGN}
)
endfunction()
function(target_stm32f303xc name)
target_stm32f3xx(
NAME ${name}
STARTUP startup_stm32f30x_md_gcc.S
COMPILE_DEFINITIONS ${STM32F303CC_DEFINITIONS}
LINKER_SCRIPT stm32_flash_f303xc
SVD STM32F303
${ARGN}
)
endfunction()

59
cmake/stm32f4-usb.cmake

@ -0,0 +1,59 @@
set(STM32_USBOTG_DIR "${MAIN_LIB_DIR}/main/STM32_USB_OTG_Driver")
set(STM32_USBCORE_DIR "${MAIN_LIB_DIR}/main/STM32_USB_Device_Library/Core")
set(STM32_USBCDC_DIR "${MAIN_LIB_DIR}/main/STM32_USB_Device_Library/Class/cdc")
set(STM32_USBHID_DIR "${MAIN_LIB_DIR}/main/STM32_USB_Device_Library/Class/hid")
set(STM32_USBWRAPPER_DIR "${MAIN_LIB_DIR}/main/STM32_USB_Device_Library/Class/hid_cdc_wrapper")
set(STM32_USBMSC_DIR "${MAIN_LIB_DIR}/main/STM32_USB_Device_Library/Class/msc")
set(STM32F4_USB_INCLUDE_DIRS
"${STM32_USBOTG_DIR}/inc"
"${STM32_USBCORE_DIR}/inc"
"${STM32_USBCDC_DIR}/inc"
"${STM32_USBHID_DIR}/inc"
"${STM32_USBWRAPPER_DIR}/inc"
"${STM32_USBMSC_DIR}/inc"
)
set(STM32_USBOTG_SRC
usb_core.c
usb_dcd.c
usb_dcd_int.c
)
list(TRANSFORM STM32_USBOTG_SRC PREPEND "${STM32_USBOTG_DIR}/src/")
set(STM32_USBCORE_SRC
usbd_core.c
usbd_ioreq.c
usbd_req.c
)
list(TRANSFORM STM32_USBCORE_SRC PREPEND "${STM32_USBCORE_DIR}/src/")
set(STM32_USBCDC_SRC
"${STM32_USBCDC_DIR}/src/usbd_cdc_core.c"
)
set(STM32_USBHID_SRC
"${STM32_USBHID_DIR}/src/usbd_hid_core.c"
)
set(STM32_USBWRAPPER_SRC
"${STM32_USBWRAPPER_DIR}/src/usbd_hid_cdc_wrapper.c"
)
set(STM32F4_USBMSC_SRC
usbd_msc_bot.c
usbd_msc_core.c
usbd_msc_data.c
usbd_msc_scsi.c
)
main_sources(STM32F4_MSC_SRC
msc/usbd_msc_desc.c
)
list(TRANSFORM STM32F4_USBMSC_SRC PREPEND "${STM32_USBMSC_DIR}/src/")
list(APPEND STM32F4_USBMSC_SRC ${STM32F4_MSC_SRC})
list(APPEND STM32F4_USB_SRC ${STM32_USBOTG_SRC})
list(APPEND STM32F4_USB_SRC ${STM32_USBCORE_SRC})
list(APPEND STM32F4_USB_SRC ${STM32_USBCDC_SRC})
list(APPEND STM32F4_USB_SRC ${STM32_USBHID_SRC})
list(APPEND STM32F4_USB_SRC ${STM32_USBWRAPPER_SRC})

155
cmake/stm32f4.cmake

@ -0,0 +1,155 @@
include(cortex-m4f)
include(stm32-stdperiph)
include(stm32f4-usb)
set(STM32F4_STDPERIPH_DIR "${MAIN_LIB_DIR}/main/STM32F4/Drivers/STM32F4xx_StdPeriph_Driver")
set(STM32F4_CMSIS_DEVICE_DIR "${MAIN_LIB_DIR}/main/STM32F4/Drivers/CMSIS/Device/ST/STM32F4xx")
set(STM32F4_CMSIS_DRIVERS_DIR "${MAIN_LIB_DIR}/main/STM32F4/Drivers/CMSIS")
set(STM32F4_VCP_DIR "${MAIN_SRC_DIR}/vcpf4")
set(STM32F4_STDPERIPH_SRC_EXCLUDES
stm32f4xx_can.c
stm32f4xx_cec.c
stm32f4xx_crc.c
stm32f4xx_cryp.c
stm32f4xx_cryp_aes.c
stm32f4xx_cryp_des.c
stm32f4xx_cryp_tdes.c
stm32f4xx_dbgmcu.c
stm32f4xx_dsi.c
stm32f4xx_flash_ramfunc.c
stm32f4xx_fmpi2c.c
stm32f4xx_fmc.c
stm32f4xx_hash.c
stm32f4xx_hash_md5.c
stm32f4xx_hash_sha1.c
stm32f4xx_lptim.c
stm32f4xx_qspi.c
stm32f4xx_sai.c
stm32f4xx_spdifrx.c
)
set(STM32F4_STDPERIPH_SRC_DIR "${STM32F4_STDPERIPH_DIR}/src")
glob_except(STM32F4_STDPERIPH_SRC "${STM32F4_STDPERIPH_SRC_DIR}/*.c" "${STM32F4_STDPERIPH_SRC_EXCLUDES}")
main_sources(STM32F4_SRC
target/system_stm32f4xx.c
config/config_streamer_stm32f4.c
drivers/adc_stm32f4xx.c
drivers/adc_stm32f4xx.c
drivers/bus_i2c_stm32f40x.c
drivers/serial_uart_stm32f4xx.c
drivers/system_stm32f4xx.c
drivers/timer.c
drivers/timer_impl_stdperiph.c
drivers/timer_stm32f4xx.c
drivers/uart_inverter.c
drivers/dma_stm32f4xx.c
drivers/sdcard/sdmmc_sdio_f4xx.c
)
set(STM32F4_VCP_SRC
stm32f4xx_it.c
usb_bsp.c
usbd_desc.c
usbd_usr.c
usbd_cdc_vcp.c
)
list(TRANSFORM STM32F4_VCP_SRC PREPEND "${STM32F4_VCP_DIR}/")
main_sources(STM32F4_MSC_SRC
drivers/usb_msc_f4xx.c
)
set(STM32F4_INCLUDE_DIRS
"${CMSIS_INCLUDE_DIR}"
"${CMSIS_DSP_INCLUDE_DIR}"
"${STM32F4_STDPERIPH_DIR}/inc"
"${STM32F4_CMSIS_DEVICE_DIR}"
"${STM32F4_CMSIS_DRIVERS_DIR}"
"${STM32F4_VCP_DIR}"
)
set(STM32F4_DEFINITIONS
${CORTEX_M4F_DEFINITIONS}
STM32F4
USE_STDPERIPH_DRIVER
)
function(target_stm32f4xx)
target_stm32(
SOURCES ${STM32_STDPERIPH_SRC} ${STM32F4_SRC}
COMPILE_DEFINITIONS ${STM32F4_DEFINITIONS}
COMPILE_OPTIONS ${CORTEX_M4F_COMMON_OPTIONS} ${CORTEX_M4F_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${STM32F4_INCLUDE_DIRS}
LINK_OPTIONS ${CORTEX_M4F_COMMON_OPTIONS} ${CORTEX_M4F_LINK_OPTIONS}
MSC_SOURCES ${STM32F4_USBMSC_SRC} ${STM32F4_MSC_SRC}
VCP_SOURCES ${STM32F4_USB_SRC} ${STM32F4_VCP_SRC}
VCP_INCLUDE_DIRECTORIES ${STM32F4_USB_INCLUDE_DIRS}
OPTIMIZATION -O2
OPENOCD_TARGET stm32f4x
${ARGN}
)
endfunction()
set(STM32F405_COMPILE_DEFINITIONS
STM32F40_41xxx
STM32F405xx
MCU_FLASH_SIZE=1024
)
function(target_stm32f405xg name)
target_stm32f4xx(
NAME ${name}
STARTUP startup_stm32f40xx.s
SOURCES ${STM32F4_STDPERIPH_SRC}
COMPILE_DEFINITIONS ${STM32F405_COMPILE_DEFINITIONS}
LINKER_SCRIPT stm32_flash_f405xg
SVD STM32F405
BOOTLOADER
${ARGN}
)
endfunction()
set(STM32F411_OR_F427_STDPERIPH_SRC ${STM32F4_STDPERIPH_SRC})
set(STM32F411_OR_F427_STDPERIPH_SRC_EXCLUDES "stm32f4xx_fsmc.c")
exclude_basenames(STM32F411_OR_F427_STDPERIPH_SRC ${STM32F411_OR_F427_STDPERIPH_SRC_EXCLUDES})
set(STM32F411_COMPILE_DEFINITIONS
STM32F411xE
MCU_FLASH_SIZE=512
)
function(target_stm32f411xe name)
target_stm32f4xx(
NAME ${name}
STARTUP startup_stm32f411xe.s
SOURCES ${STM32F411_OR_F427_STDPERIPH_SRC}
COMPILE_DEFINITIONS ${STM32F411_COMPILE_DEFINITIONS}
LINKER_SCRIPT stm32_flash_f411xe
SVD STM32F411
${ARGN}
)
endfunction()
set(STM32F427_COMPILE_DEFINITIONS
STM32F427_437xx
MCU_FLASH_SIZE=1024
)
function(target_stm32f427xg name)
target_stm32f4xx(
NAME ${name}
STARTUP startup_stm32f427xx.s
SOURCES ${STM32F411_OR_F427_STDPERIPH_SRC}
COMPILE_DEFINITIONS ${STM32F427_COMPILE_DEFINITIONS}
LINKER_SCRIPT stm32_flash_f427xg
SVD STM32F411
${ARGN}
)
endfunction()

48
cmake/stm32f7-usb.cmake

@ -0,0 +1,48 @@
set(STM32F7_USBCORE_DIR "${MAIN_LIB_DIR}/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Core")
set(STM32F7_USBCORE_SRC
usbd_core.c
usbd_ctlreq.c
usbd_ioreq.c
)
list(TRANSFORM STM32F7_USBCORE_SRC PREPEND "${STM32F7_USBCORE_DIR}/Src/")
set(STM32F7_USBCDC_DIR "${MAIN_LIB_DIR}/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/CDC")
set(STM32F7_USBCDC_SRC
usbd_cdc.c
)
list(TRANSFORM STM32F7_USBCDC_SRC PREPEND "${STM32F7_USBCDC_DIR}/Src/")
set(STM32F7_USBHID_DIR "${MAIN_LIB_DIR}/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/HID")
set(STM32F7_USBHID_SRC
usbd_hid.c
)
list(TRANSFORM STM32F7_USBHID_SRC PREPEND "${STM32F7_USBHID_DIR}/Src/")
set(STM32F7_USBCDCHID_DIR "${MAIN_LIB_DIR}/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_HID")
set(STM32F7_USBCDCHID_SRC
usbd_cdc_hid.c
)
list(TRANSFORM STM32F7_USBCDCHID_SRC PREPEND "${STM32F7_USBCDCHID_DIR}/Src/")
set(STM32F7_USBMSC_DIR "${MAIN_LIB_DIR}/main/STM32F7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC")
set(STM32F7_USBMSC_SRC
usbd_msc.c
usbd_msc_bot.c
usbd_msc_data.c
usbd_msc_scsi.c
)
list(TRANSFORM STM32F7_USBMSC_SRC PREPEND "${STM32F7_USBMSC_DIR}/Src/")
set(STM32F7_USB_INCLUDE_DIRS
"${STM32F7_USBCORE_DIR}/Inc"
"${STM32F7_USBCDC_DIR}/Inc"
"${STM32F7_USBHID_DIR}/Inc"
"${STM32F7_USBCDCHID_DIR}/Inc"
"${STM32F7_USBMSC_DIR}/Inc"
)
list(APPEND STM32F7_USB_SRC ${STM32F7_USBCORE_SRC})
list(APPEND STM32F7_USB_SRC ${STM32F7_USBCDC_SRC})
list(APPEND STM32F7_USB_SRC ${STM32F7_USBHID_SRC})
list(APPEND STM32F7_USB_SRC ${STM32F7_USBCDCHID_SRC})
list(APPEND STM32F7_USB_SRC ${STM32F7_USBMSC_SRC})

140
cmake/stm32f7.cmake

@ -0,0 +1,140 @@
include(cortex-m7)
include(stm32f7-usb)
set(STM32F7_HAL_DIR "${MAIN_LIB_DIR}/main/STM32F7/Drivers/STM32F7xx_HAL_Driver")
set(STM32F7_HAL_SRC
stm32f7xx_hal.c
stm32f7xx_hal_adc.c
stm32f7xx_hal_adc_ex.c
stm32f7xx_hal_cortex.c
stm32f7xx_hal_dac.c
stm32f7xx_hal_dac_ex.c
stm32f7xx_hal_dma.c
stm32f7xx_hal_dma_ex.c
stm32f7xx_hal_flash.c
stm32f7xx_hal_flash_ex.c
stm32f7xx_hal_gpio.c
stm32f7xx_hal_i2c.c
stm32f7xx_hal_i2c_ex.c
stm32f7xx_hal_pcd.c
stm32f7xx_hal_pcd_ex.c
stm32f7xx_hal_pwr.c
stm32f7xx_hal_pwr_ex.c
stm32f7xx_hal_rcc.c
stm32f7xx_hal_rcc_ex.c
stm32f7xx_hal_rtc.c
stm32f7xx_hal_rtc_ex.c
stm32f7xx_hal_spi.c
stm32f7xx_hal_tim.c
stm32f7xx_hal_tim_ex.c
stm32f7xx_hal_uart.c
stm32f7xx_hal_usart.c
stm32f7xx_ll_dma.c
stm32f7xx_ll_dma2d.c
stm32f7xx_ll_gpio.c
stm32f7xx_ll_rcc.c
stm32f7xx_ll_spi.c
stm32f7xx_ll_tim.c
stm32f7xx_ll_usb.c
stm32f7xx_ll_utils.c
)
list(TRANSFORM STM32F7_HAL_SRC PREPEND "${STM32F7_HAL_DIR}/Src/")
set(STM32F7_CMSIS_DEVICE_DIR "${MAIN_LIB_DIR}/main/STM32F7/Drivers/CMSIS/Device/ST/STM32F7xx")
set(STM32F7_VCP_DIR "${MAIN_SRC_DIR}/vcp_hal")
set(STM32F7_VCP_SRC
usbd_desc.c
usbd_conf_stm32f7xx.c
usbd_cdc_interface.c
)
list(TRANSFORM STM32F7_VCP_SRC PREPEND "${STM32F7_VCP_DIR}/")
set(STM32F7_INCLUDE_DIRS
${STM32F7_HAL_DIR}/Inc
${STM32F7_CMSIS_DEVICE_DIR}/Include
)
main_sources(STM32F7_SRC
target/system_stm32f7xx.c
config/config_streamer_stm32f7.c
drivers/adc_stm32f7xx.c
drivers/bus_i2c_hal.c
drivers/dma_stm32f7xx.c
drivers/bus_spi_hal_ll.c
drivers/timer.c
drivers/timer_impl_hal.c
drivers/timer_stm32f7xx.c
drivers/system_stm32f7xx.c
drivers/serial_uart_stm32f7xx.c
drivers/serial_uart_hal.c
drivers/sdcard/sdmmc_sdio_f7xx.c
)
main_sources(STM32F7_MSC_SRC
drivers/usb_msc_f7xx.c
)
set(STM32F7_DEFINITIONS
${CORTEX_M7_DEFINITIONS}
USE_HAL_DRIVER
USE_FULL_LL_DRIVER
)
function(target_stm32f7xx)
target_stm32(
SOURCES ${STM32F7_HAL_SRC} ${STM32F7_SRC}
COMPILE_DEFINITIONS ${STM32F7_DEFINITIONS}
COMPILE_OPTIONS ${CORTEX_M7_COMMON_OPTIONS} ${CORTEX_M7_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${STM32F7_INCLUDE_DIRS}
LINK_OPTIONS ${CORTEX_M7_COMMON_OPTIONS} ${CORTEX_M7_LINK_OPTIONS}
MSC_SOURCES ${STM32F7_USBMSC_SRC} ${STM32F7_MSC_SRC}
VCP_SOURCES ${STM32F7_USB_SRC} ${STM32F7_VCP_SRC}
VCP_INCLUDE_DIRECTORIES ${STM32F7_USB_INCLUDE_DIRS} ${STM32F7_VCP_DIR}
OPENOCD_TARGET stm32f7x
BOOTLOADER
${ARGN}
)
endfunction()
macro(define_target_stm32f7 subfamily size)
function(target_stm32f7${subfamily}x${size} name)
set(func_ARGV ARGV)
string(TOUPPER ${size} upper_size)
get_stm32_flash_size(flash_size ${size})
if(flash_size GREATER 512)
set(opt -O2)
else()
set(opt -Os)
endif()
set(definitions
STM32F7
STM32F7${subfamily}xx
STM32F7${subfamily}x${upper_size}
MCU_FLASH_SIZE=${flash_size}
)
target_stm32f7xx(
NAME ${name}
STARTUP startup_stm32f7${subfamily}xx.s
COMPILE_DEFINITIONS ${definitions}
LINKER_SCRIPT stm32_flash_f7${subfamily}x${size}
OPTIMIZATION ${opt}
${${func_ARGV}}
)
endfunction()
endmacro()
define_target_stm32f7(22 e)
define_target_stm32f7(45 g)
define_target_stm32f7(46 g)
define_target_stm32f7(65 g)
define_target_stm32f7(65 i)

41
cmake/stm32h7-usb.cmake

@ -0,0 +1,41 @@
set(STM32H7_USBCORE_DIR "${MAIN_LIB_DIR}/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Core")
set(STM32H7_USBCORE_SRC
usbd_core.c
usbd_ctlreq.c
usbd_ioreq.c
)
list(TRANSFORM STM32H7_USBCORE_SRC PREPEND "${STM32H7_USBCORE_DIR}/Src/")
set(STM32H7_USBCDC_DIR "${MAIN_LIB_DIR}/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/CDC")
set(STM32H7_USBCDC_SRC
usbd_cdc.c
)
list(TRANSFORM STM32H7_USBCDC_SRC PREPEND "${STM32H7_USBCDC_DIR}/Src/")
set(STM32H7_USBHID_DIR "${MAIN_LIB_DIR}/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/HID")
set(STM32H7_USBHID_SRC
usbd_hid.c
)
list(TRANSFORM STM32H7_USBHID_SRC PREPEND "${STM32H7_USBHID_DIR}/Src/")
set(STM32H7_USBMSC_DIR "${MAIN_LIB_DIR}/main/STM32H7/Middlewares/ST/STM32_USB_Device_Library/Class/MSC")
set(STM32H7_USBMSC_SRC
usbd_msc.c
usbd_msc_bot.c
usbd_msc_data.c
usbd_msc_scsi.c
)
list(TRANSFORM STM32H7_USBMSC_SRC PREPEND "${STM32H7_USBMSC_DIR}/Src/")
set(STM32H7_USB_INCLUDE_DIRS
"${STM32H7_USBCORE_DIR}/Inc"
"${STM32H7_USBCDC_DIR}/Inc"
"${STM32H7_USBHID_DIR}/Inc"
"${STM32H7_USBMSC_DIR}/Inc"
)
list(APPEND STM32H7_USB_SRC ${STM32H7_USBCORE_SRC})
list(APPEND STM32H7_USB_SRC ${STM32H7_USBCDC_SRC})
list(APPEND STM32H7_USB_SRC ${STM32H7_USBHID_SRC})
#XXX: Not working yet
#list(APPEND STM32H7_USB_SRC ${STM32H7_USBMSC_SRC})

220
cmake/stm32h7.cmake

@ -0,0 +1,220 @@
include(cortex-m7)
include(stm32h7-usb)
set(STM32H7_CMSIS_DEVICE_DIR "${MAIN_LIB_DIR}/main/STM32H7/Drivers/CMSIS/Device/ST/STM32H7xx")
set(STM32H7_HAL_DIR "${MAIN_LIB_DIR}/main/STM32H7/Drivers/STM32H7xx_HAL_Driver")
set(STM32H7_HAL_SRC
stm32h7xx_hal.c
stm32h7xx_hal_adc.c
stm32h7xx_hal_adc_ex.c
# stm32h7xx_hal_cec.c
# stm32h7xx_hal_comp.c
stm32h7xx_hal_cortex.c
# stm32h7xx_hal_crc.c
# stm32h7xx_hal_crc_ex.c
# stm32h7xx_hal_cryp.c
# stm32h7xx_hal_cryp_ex.c
stm32h7xx_hal_dac.c
stm32h7xx_hal_dac_ex.c
# stm32h7xx_hal_dcmi.c
# stm32h7xx_hal_dfsdm.c
# stm32h7xx_hal_dfsdm_ex.c
stm32h7xx_hal_dma.c
# stm32h7xx_hal_dma2d.c
stm32h7xx_hal_dma_ex.c
# stm32h7xx_hal_dsi.c
stm32h7xx_hal_dts.c
# stm32h7xx_hal_eth.c
# stm32h7xx_hal_eth_ex.c
stm32h7xx_hal_exti.c
# stm32h7xx_hal_fdcan.c
stm32h7xx_hal_flash.c
stm32h7xx_hal_flash_ex.c
stm32h7xx_hal_gfxmmu.c
stm32h7xx_hal_gpio.c
# stm32h7xx_hal_hash.c
# stm32h7xx_hal_hash_ex.c
# stm32h7xx_hal_hcd.c
# stm32h7xx_hal_hrtim.c
# stm32h7xx_hal_hsem.c
stm32h7xx_hal_i2c.c
stm32h7xx_hal_i2c_ex.c
# stm32h7xx_hal_i2s.c
# stm32h7xx_hal_i2s_ex.c
# stm32h7xx_hal_irda.c
# stm32h7xx_hal_iwdg.c
# stm32h7xx_hal_jpeg.c
# stm32h7xx_hal_lptim.c
# stm32h7xx_hal_ltdc.c
# stm32h7xx_hal_ltdc_ex.c
# stm32h7xx_hal_mdios.c
# stm32h7xx_hal_mdma.c
# stm32h7xx_hal_mmc.c
# stm32h7xx_hal_mmc_ex.c
# stm32h7xx_hal_nand.c
# stm32h7xx_hal_nor.c
# stm32h7xx_hal_opamp.c
# stm32h7xx_hal_opamp_ex.c
stm32h7xx_hal_ospi.c
stm32h7xx_hal_otfdec.c
stm32h7xx_hal_pcd.c
stm32h7xx_hal_pcd_ex.c
stm32h7xx_hal_pssi.c
stm32h7xx_hal_pwr.c
stm32h7xx_hal_pwr_ex.c
stm32h7xx_hal_qspi.c
# stm32h7xx_hal_ramecc.c
stm32h7xx_hal_rcc.c
stm32h7xx_hal_rcc_ex.c
# stm32h7xx_hal_rng.c
# stm32h7xx_hal_rng_ex.c
stm32h7xx_hal_rtc.c
stm32h7xx_hal_rtc_ex.c
# stm32h7xx_hal_sai.c
# stm32h7xx_hal_sai_ex.c
stm32h7xx_hal_sd.c
stm32h7xx_hal_sd_ex.c
# stm32h7xx_hal_sdram.c
# stm32h7xx_hal_smartcard.c
# stm32h7xx_hal_smartcard_ex.c
# stm32h7xx_hal_smbus.c
# stm32h7xx_hal_spdifrx.c
stm32h7xx_hal_spi.c
stm32h7xx_hal_spi_ex.c
# stm32h7xx_hal_sram.c
# stm32h7xx_hal_swpmi.c
stm32h7xx_hal_tim.c
stm32h7xx_hal_tim_ex.c
stm32h7xx_hal_uart.c
stm32h7xx_hal_uart_ex.c
# stm32h7xx_hal_usart.c
# stm32h7xx_hal_usart_ex.c
# stm32h7xx_hal_wwdg.c
# stm32h7xx_ll_adc.c
# stm32h7xx_ll_bdma.c
# stm32h7xx_ll_comp.c
# stm32h7xx_ll_crc.c
stm32h7xx_ll_crs.c
# stm32h7xx_ll_dac.c
# stm32h7xx_ll_delayblock.c
stm32h7xx_ll_dma.c
# stm32h7xx_ll_dma2d.c
stm32h7xx_ll_exti.c
# stm32h7xx_ll_fmc.c
# stm32h7xx_ll_gpio.c
# stm32h7xx_ll_hrtim.c
stm32h7xx_ll_i2c.c
# stm32h7xx_ll_lptim.c
# stm32h7xx_ll_lpuart.c
# stm32h7xx_ll_mdma.c
# stm32h7xx_ll_opamp.c
# stm32h7xx_ll_pwr.c
# stm32h7xx_ll_rcc.c
# stm32h7xx_ll_rng.c
# stm32h7xx_ll_rtc.c
stm32h7xx_ll_sdmmc.c
# stm32h7xx_ll_spi.c
# stm32h7xx_ll_swpmi.c
stm32h7xx_ll_tim.c
# stm32h7xx_ll_usart.c
stm32h7xx_ll_usb.c
# stm32h7xx_ll_utils.c
)
list(TRANSFORM STM32H7_HAL_SRC PREPEND "${STM32H7_HAL_DIR}/Src/")
set(STM32H7_VCP_DIR "${MAIN_SRC_DIR}/vcp_hal")
set(STM32H7_VCP_SRC
usbd_desc.c
usbd_conf_stm32h7xx.c
usbd_cdc_interface.c
)
list(TRANSFORM STM32H7_VCP_SRC PREPEND "${STM32H7_VCP_DIR}/")
set(STM32H7_INCLUDE_DIRS
${STM32H7_HAL_DIR}/Inc
${STM32H7_CMSIS_DEVICE_DIR}/Include
)
main_sources(STM32H7_SRC
target/system_stm32h7xx.c
config/config_streamer_stm32h7.c
drivers/adc_stm32h7xx.c
drivers/bus_i2c_hal.c
drivers/dma_stm32h7xx.c
drivers/bus_spi_hal.c
drivers/memprot.h
drivers/memprot_hal.c
drivers/memprot_stm32h7xx.c
drivers/timer.c
drivers/timer_impl_hal.c
drivers/timer_stm32h7xx.c
drivers/system_stm32h7xx.c
drivers/serial_uart_stm32h7xx.c
drivers/serial_uart_hal.c
# drivers/sdcard/sdmmc_sdio_h7xx.c
)
main_sources(STM32H7_MSC_SRC
drivers/usb_msc_h7xx.c
)
set(STM32H7_DEFINITIONS
${CORTEX_M7_DEFINITIONS}
USE_HAL_DRIVER
USE_FULL_LL_DRIVER
MAX_MPU_REGIONS=16
)
function(target_stm32h7xx)
target_stm32(
SOURCES ${STM32H7_HAL_SRC} ${STM32H7_SRC}
COMPILE_DEFINITIONS ${STM32H7_DEFINITIONS}
COMPILE_OPTIONS ${CORTEX_M7_COMMON_OPTIONS} ${CORTEX_M7_COMPILE_OPTIONS}
INCLUDE_DIRECTORIES ${STM32H7_INCLUDE_DIRS}
LINK_OPTIONS ${CORTEX_M7_COMMON_OPTIONS} ${CORTEX_M7_LINK_OPTIONS}
MSC_SOURCES ${STM32H7_USBMSC_SRC} ${STM32H7_MSC_SRC}
VCP_SOURCES ${STM32H7_USB_SRC} ${STM32H7_VCP_SRC}
VCP_INCLUDE_DIRECTORIES ${STM32H7_USB_INCLUDE_DIRS} ${STM32H7_VCP_DIR}
OPTIMIZATION -O2
OPENOCD_TARGET stm32h7x
DISABLE_MSC # This should be temporary
# BOOTLOADER
${ARGN}
)
endfunction()
macro(define_target_stm32h7 subfamily size)
function(target_stm32h7${subfamily}x${size} name)
set(func_ARGV ARGV)
string(TOUPPER ${size} upper_size)
get_stm32_flash_size(flash_size ${size})
set(definitions
STM32H7
STM32H7${subfamily}xx
STM32H7${subfamily}x${upper_size}
# stm32h743xx.h defined FLASH_SIZE, used by HAL, but in bytes
# use MCU_FLASH_SIZE since we use KiB in our code
MCU_FLASH_SIZE=${flash_size}
)
target_stm32h7xx(
NAME ${name}
STARTUP startup_stm32h7${subfamily}xx.s
COMPILE_DEFINITIONS ${definitions}
LINKER_SCRIPT stm32_flash_h7${subfamily}x${size}
${${func_ARGV}}
)
endfunction()
endmacro()
define_target_stm32h7(43 i)

16
cmake/svd.cmake

@ -0,0 +1,16 @@
function(setup_svd target_exe target_name)
get_property(svd_name TARGET ${target_exe} PROPERTY SVD)
set(svd_target_name "svd_${target_name}")
if (svd_name AND NOT svd_name STREQUAL "")
add_custom_target(${svd_target_name}
COMMAND ${CMAKE_COMMAND} -E copy
${SVD_DIR}/${svd_name}.svd
${CMAKE_BINARY_DIR}/svd/${target_name}.svd
)
else()
add_custom_target(${svd_target_name}
${CMAKE_COMMAND} -E echo "target ${target_name} does not declare an SVD filename"
COMMAND ${CMAKE_COMMAND} -E false)
endif()
exclude_from_all(${svd_target_name})
endfunction()

40381
dev/svd/STM32F303.svd
File diff suppressed because it is too large
View File

61681
dev/svd/STM32F405.svd
File diff suppressed because it is too large
View File

27110
dev/svd/STM32F411.svd
File diff suppressed because it is too large
View File

63121
dev/svd/STM32F427.svd
File diff suppressed because it is too large
View File

57155
dev/svd/STM32F446.svd
File diff suppressed because it is too large
View File

61861
dev/svd/STM32F7x2.svd
File diff suppressed because it is too large
View File

71136
dev/svd/STM32F7x5.svd
File diff suppressed because it is too large
View File

70681
dev/svd/STM32F7x6.svd
File diff suppressed because it is too large
View File

28
dev/vscode/launch.json

@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
// ******* INAV ********
// Define the following values in settings.json
// - BUILD_DIR: Relative path to the build directory
// - TARGET: Target name that you want to launch
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "${config:BUILD_DIR}/bin/${config:TARGET}.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"device": "${config:TARGET}",
"configFiles": [
"${config:BUILD_DIR}/openocd/${config:TARGET}.cfg"
],
"preLaunchTask": "openocd-debug-prepare",
"svdFile": "${config:BUILD_DIR}/svd/${config:TARGET}.svd",
}
]
}

51
dev/vscode/tasks.json

@ -0,0 +1,51 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"options": {
"env": {
"TARGET": "${config:TARGET}",
}
},
"tasks": [
{
"label": "target",
"type": "shell",
"command": "make", "args": ["-C", "${config:BUILD_DIR}", "${config:TARGET}"],
"problemMatcher": "$gcc",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
}
},
{
"label": "flash",
"type": "shell",
"command": "make", "args": ["-C", "${config:BUILD_DIR}", "openocd_flash_${config:TARGET}"],
"dependsOn": "elf"
},
{
"label": "svd",
"type": "shell",
"command": "make", "args": ["-C", "${config:BUILD_DIR}", "svd_${config:TARGET}"],
"problemMatcher": []
},
{
"label": "openocd-cfg",
"type": "shell",
"command": "make", "args": ["-C", "${config:BUILD_DIR}", "openocd_cfg_${config:TARGET}"],
"problemMatcher": []
},
{
"label": "openocd-debug-prepare",
"type": "shell",
"dependsOn": ["svd", "openocd-cfg", "flash"],
"problemMatcher": []
}
]
}

74
docs/1wire.md

@ -0,0 +1,74 @@
# 1-wire passthrough esc programming
### ESCs must have the BlHeli Bootloader.
If your ESCs didn't come with BlHeli Bootloader, you'll need to flash them with an ArduinoISP programmer first. [Here's a guide](http://bit.ly/blheli-f20).
This is the option you need to select for the bootloader:
![Flashing BlHeli Bootloader](assets/images/blheli-bootloader.png)
Currently supported on all boards with at least 128kB of flash memory (all F3, F4 and F7).
## Usage
- Plug in the USB cable and connect to your board with the INAV configurator.
- Open the BlHeli Suite.
- Ensure you have selected the correct Atmel or SILABS "Cleanflight" option under the "Select ATMEL / SILABS Interface" menu option.
- Ensure you have port for your external USB/UART adapter selected, if you're using one, otherwise pick the same COM port that you normally use for INAV.
- Click "Connect" and wait for the connection to complete. If you get a COM error, hit connect again. It will probably work.
- Use the boxes at the bottom to select the ESCs you have connected. Note that the boxes correspond directly to the ports on your flight controller. For example if you have motors on ports 1-4, pick boxes 1-4 or in the case of a tri-copter that uses motors on ports 3, 4 and 5, select those ports in BlHeli.
- Click "Read Setup"
- Use BlHeli suite as normal.
- When you're finished with one ESC, click "Disconnect"
## Implementing and Configuring targets
The following parameters can be used to enable and configure this in the related target.h file:
USE_SERIAL_1WIRE Enables the 1wire code, defined in target.h
- For new targets
- in `target.h`
```
// Turn on serial 1wire passthrough
#define USE_SERIAL_1WIRE
// How many escs does this board support?
#define ESC_COUNT 6
// STM32F3DISCOVERY TX - PC3 connects to UART RX
#define S1W_TX_GPIO GPIOC
#define S1W_TX_PIN GPIO_Pin_3
// STM32F3DISCOVERY RX - PC1 connects to UART TX
#define S1W_RX_GPIO GPIOC
#define S1W_RX_PIN GPIO_Pin_1
```
- in `serial_1wire.c`
```
// Define your esc hardware
#if defined(STM32F3DISCOVERY)
const escHardware_t escHardware[ESC_COUNT] = {
{ GPIOD, 12 },
{ GPIOD, 13 },
{ GPIOD, 14 },
{ GPIOD, 15 },
{ GPIOA, 1 },
{ GPIOA, 2 }
};
```
## Development Notes
On the STM32F3DISCOVERY, an external pullup on the ESC line may be necessary. I needed a 3v, 4.7k pullup.

161
docs/API/MSP_extensions.md

@ -0,0 +1,161 @@
# MSP Extensions
INAV includes a number of extensions to the MultiWii Serial Protocol (MSP). This document describes
those extensions in order that 3rd party tools may identify INAV firmware and react appropriately.
Issue the MSP_API_VERSION command to find out if the firmware supports them.
## Mode Ranges
### MSP\_MODE\_RANGES
The MSP\_MODE\_RANGES returns the current auxiliary mode settings from the flight controller. It should be invoked
before any modification is made to the configuration.
The message returns a group of 4 unsigned bytes for each 'slot' available in the flight controller. The number of
slots should be calculated from the size of the returned message.
| Command | Msg Id | Direction | Notes |
|---------|--------|-----------|-------|
| MSP\_MODE\_RANGES | 34 | to FC | Following this command, the FC returns a block of 4 bytes for each auxiliary mode 'slot'|
Unassigned slots have rangeStartStep == rangeEndStep. Each element contains the following fields.
| Data | Type | Notes |
|------|------|-------|
| permanentId | uint8 | See Modes.md for a definition of the permanent ids |
| auxChannelIndex | uint8 | The Aux switch number (indexed from 0) |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
Thus, for a INAV firmware with 40 slots 160 bytes would be returned in response to MSP\_MODE\_RANGES,
### MSP\_SET\_MODE\_RANGE
The MSP\_SET\_MODE\_RANGE is used to inform the flight controller of
auxiliary mode settings. The client *must* return all auxiliary
elements, including those that have been disabled or are undefined, by
sending this message for all auxiliary slots.
| Command | Msg Id | Direction |
|---------|--------|-----------|
| MSP\_SET\_MODE\_RANGE | 35 | to FC |
| Data | Type | Notes |
|------|------|-------|
| sequence id | uint8 | A monotonically increasing ID, from 0 to the number of slots -1 |
| permanentId | uint8 | See Modes.md for a definition of the permanent ids |
| auxChannelIndex | uint8 | The Aux channel number (indexed from 0) |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
### Implementation Notes
* The client should make no assumptions about the number of slots available. Rather, the number should be computed
from the size of the MSP\_MODE\_RANGES message divided by the size of the returned data element (4 bytes);
* The client should ensure that all changed items are returned to the flight controller, including those where a
switch or range has been disabled;
* A 'null' return, with all values other than the sequence id set to 0, must be made for all unused slots, up to
the maximum number of slots calculated from the initial message.
## Adjustment Ranges
### MSP\_ADJUSTMENT\_RANGES
The MSP\_ADJUSTMENT\_RANGES returns the current adjustment range settings from
the flight controller. It should be invoked before any modification is
made to the configuration.
The message returns a group of 6 unsigned bytes for each 'slot'
available in the flight controller. The number of slots should be
calculated from the size of the returned message.
| Command | Msg Id | Direction | Notes |
|---------|--------|-----------|-------|
| MSP\_ADJUSTMENT\_RANGES | 52 | to FC | Following this command, the FC returns a block of 6 bytes for each adjustment range 'slot'|
Unassigned slots have rangeStartStep == rangeEndStep. Each element contains the following fields.
| Data | Type | Notes |
|------|------|-------|
| adjustmentStateIndex | uint8 | See below |
| auxChannelIndex | uint8 | The Aux channel number (indexed from 0) used to activate the adjustment |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| adjustmentFunction | uint8 | See below |
| auxSwitchChannelIndex | uint8 | The Aux channel number used to perform the function (indexed from 0) |
Thus, for a INAV firmware with 12 slots 72 bytes would be returned in response to MSP\_ADJUSTMENT\_RANGES,
### MSP\_SET\_ADJUSTMENT\_RANGE
The MSP\_SET\_ADJUSTMENT\_RANGE is used to inform the flight controller of
adjustment range settings. The client *must* return all adjustment range
elements, including those that have been disabled or are undefined, by
sending this message for all adjustment range slots.
| Command | Msg Id | Direction |
|---------|--------|-----------|
| MSP\_SET\_ADJUSTMENT\_RANGE | 53 | to FC |
| Data | Type | Notes |
|------|------|-------|
| sequence id | uint8 | A monotonically increasing ID, from 0 to the number of slots -1 |
| adjustmentStateIndex | uint8 | See below |
| auxChannelIndex | uint8 | The Aux channel number (indexed from 0) |
| rangeStartStep | uint8 | The start value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| rangeEndStep | uint8 | The end value for this element in 'blocks' of 25 where 0 == 900 and 48 == 2100 |
| adjustmentFunction | uint8 | See below |
| auxSwitchChannelIndex | uint8 | The Aux channel number used to perform the function (indexed from 0) |
### MSP\_SET\_1WIRE
The MSP\_SET\_1WIRE is used to enable serial1wire passthrough
note: it would be ideal to disable this when armed
| Command | Msg Id | Direction |
|---------|--------|-----------|
| MSP\_SET\_1WIRE | 243 | to FC |
| Data | Type | Notes |
|------|------|-------|
| esc id | uint8 | A monotonically increasing ID, from 0 to the number of escs -1 |
#### AdjustmentIndex
The FC maintains internal state for each adjustmentStateIndex, currently 4 simultaneous adjustment states are maintained. Multiple adjustment ranges
can be configured to use the same state but care should be taken not to send multiple adjustment ranges that when active would confict.
e.g. Configuring two identical adjustment ranges using the same slot would conflict, but configuring two adjustment ranges that used
only one half of the possible channel range each but used the same adjustmentStateIndex would not conflict.
The FC does NOT check for conflicts.
#### AdjustmentFunction
There are many adjustments that can be made, the numbers of them and their use is found in the documentation of the cli `adjrange` command in the 'Inflight Adjustents' section.
### Implementation Notes
* The client should make no assumptions about the number of slots available. Rather, the number should be computed
from the size of the MSP\_ADJUSTMENT\_RANGES message divided by the size of the returned data element (6 bytes);
* The client should ensure that all changed items are returned to the flight controller, including those where a
switch or range has been disabled;
* A 'null' return, with all values except for the sequence id set to 0, must be made for all unused slots,
up to the maximum number of slots calculated from the initial message.
## Deprecated MSP
The following MSP commands are replaced by the MSP\_MODE\_RANGES and
MSP\_SET\_MODE\_RANGE extensions, and are not recognised by
INAV.
* MSP\_BOX
* MSP\_SET\_BOX
See also
--------
Modes.md describes the user visible implementation for the INAV
modes extension.

59
docs/Autotune - fixedwing.md

@ -0,0 +1,59 @@
# Airplane Autotune instructions
Airplane PIFF autotune is inspired by ArduPilot Plane firmware.
Getting a good set of roll/pitch/yaw PIFF parameters for your aircraft is essential for stable flight. To help with this it is highly recommended that you use the AUTOTUNE system described below.
## What AUTOTUNE does
The AUTOTUNE mode is a flight mode that acts on top of normal ANGLE/HORIZON/ACRO mode and uses changes in flight attitude input by the pilot to learn the tuning values for roll, pitch and yaw tuning.
In general pilot needs to activate AUTOTUNE mode while in the air and then fly the plane for a few minutes. While flying the pilot needs to input as many sharp attitude changes as possible so that the autotune code can learn how the aircraft responds and figure out PIFF gains.
## Before flying with AUTOTUNE
Before taking off you need to set up a few parameters for your airplane:
parameter | explanation
--------- | -----------
roll_rate | Maximum roll rate limit for your ariplane. Must not exceed physical limit of your plane
pitch_rate | Maximum pitch rate limit for your ariplane. Must not exceed physical limit of your plane
yaw_rate | Maximum yaw rate limit for your ariplane. Must not exceed physical limit of your plane
fw_p_level | Self-leveling strength. Bigger value means sharper response
fw_i_level | Self-leveling filtering. Usual value for airplanes is 1-5 Hz
max_angle_inclination_rll | Maximum roll angle in [0.1 deg] units
max_angle_inclination_pit | Maximum pitch angle in [0.1 deg] units
tpa_breakpoint | Cruise throttle (expected throttle that you would be flying most of the time)
tpa_rate | Amount of TPS curve to apply (usually should be in range 50-80 for most airplanes)
For most hobby-sized airplanes roll/pitch rate limits should be in range 70-120 deg/s (7-12 for `roll_rate` and `pitch_rate` values). Small and agile flying wings can reach 180-200 deg/s.
Other things to check:
* It's highly recommended that you fly in MANUAL and trim your servo midpoints for stable flight
* Make sure you have center of gravity according to manual to your aircraft
* Check that your failsafe activates correctly (test on the ground with propeller off for safety)
## Flying in AUTOTUNE
Once you are all setup you can take off normally and switch to AUTOTUNE mode once you have gained altitude.
When you engage AUTOTUNE mode a few things will happen:
* The autotune system will immediately setup some default values for your roll, pitch and yaw P and I gains
* The autotune system will monitor requested roll and pitch rates (as determined by your transmitter stick movements). When the demanded roll or pitch rate exceeds certain threshold the autotune system will use the response of the aircraft to learn roll or pitch tuning values
* Every 5 seconds the autotune system will store the snapshot of parameters you have. When you switch out of AUTOTUNE mode the last remembered parameters are restored
* You may find the plane is quite sluggish when you first enter AUTOTUNE. You will find that as the tune progresses this will get better. Make sure your flight area has plenty of room for slow large-radius turns.
* Don't land in AUTOTUNE mode - during landing airplane doesn't reach it full performance which may be read by autotune system as insufficient gains.
The key to a successful autotune is to input rapid movements with the transmitter sticks. You should only do one of either roll or pitch at a time, and you should move the stick rapidly to the maximum deflection.
## Don't stop too early
The more you fly the better it will get. Let autotune analyze how your airplane behaves and figure decent tune for you. Once you feel that airplane is flying good in AUTOTUNE - keep flying well past that point to finalize the tune.
## Completing the tune
Once you have tuned reasonable PIFF parameters with AUTOTUNE you should complete the tune by switching out of AUTOTUNE to ANGLE or MANUAL and landing the airplane.
Note that AUTOTUNE mode doesn't automatically save parameters to EEPROM. You need to disarm and issue a [stick command](Controls.md) to save configuration parameters.

324
docs/Battery.md

@ -0,0 +1,324 @@
# Battery Monitoring
INAV has a battery monitoring feature. The voltage of the main battery can be measured by the system and used to trigger a low-battery warning [buzzer](Buzzer.md), on-board status LED flashing and LED strip patterns.
Low battery warnings can:
* Help ensure you have time to safely land the aircraft
* Help maintain the life and safety of your LiPo/LiFe batteries, which should not be discharged below manufacturer recommendations
Minimum and maximum cell voltages can be set, and these voltages are used to auto-detect the number of cells in the battery when it is first connected.
Per-cell monitoring is not supported, as we only use one ADC to read the battery voltage.
## Supported targets
All targets support battery voltage monitoring unless stated.
## Connections
When dealing with batteries **ALWAYS CHECK POLARITY!**
Measure expected voltages **first** and then connect to the flight controller. Powering the flight controller with
incorrect voltage or reversed polarity will likely fry your flight controller. Ensure your flight controller
has a voltage divider capable of measuring your particular battery voltage.
On the first battery connection is always advisable to use a current limiter device to limit damages if something is wrong in the setup.
### Sparky
See the [Sparky board chapter](Board%20-%20Sparky.md).
## Voltage measurement
Enable the `VBAT` feature to enable the measurement of the battery voltage and the use of the voltage based OSD battery gauge, voltage based and energy based battery alarms.
### Calibration
`vbat_scale` - Adjust this setting to match actual measured battery voltage to reported value. Increasing this value increases the measured voltage.
### Voltage measurement source
Two voltage sources are available: raw voltage and sag compensated voltage. The raw voltage is the voltage directly measured at the battery while the sag compensated voltage is calculated by an algorithm aiming to provide a stable voltage source for gauges, telemetry and alarms. When the current drawn from a battery varies the provided voltage also varies due to the internal resistance of the battery, it is called sag. The sag can often trigger the battery alarms before the battery is empty and if you are relying on the battery voltage to know the charge state of your battery you have to land or cut the throttle to know the real, without load, battery voltage. The sag compensation algorithm simulates a battery with zero internal resistance and provides a stable reading independent from the drawn current.
You can select the voltage source used for battery alarms and telemetry with the `bat_voltage_source` setting. It can be set to either `RAW` for using raw battery voltage or `SAG_COMP` for using the calculated sag compensated voltage.
You can see an illustration of the sag compensation algorithm in action in the following graph:
![Voltage graph](assets/images/sag_compensated_battery_voltage_plot.png)
### Voltage based OSD gauge and alarms
Up to 3 battery profiles are supported. You can select the battery profile from the GUI, OSD menu, [stick commands](Controls.md) and CLI command `battery_profile n`. Each profile stores the following voltage settings:
`bat_cells` - Specify the number of cells of your battery. Allows the automatic selection of the battery profile when set to a value greater than 0. Set to 0 (default) for auto-detecting the number of cells (see next setting)
`vbat_cell_detect_voltage` - Maximum voltage per cell, used for auto-detecting the number of cells of the battery. Should be higher than maximum cell voltage to take into account possible drift in measured voltage and keep cell count detection accurate (0.01V unit, i.e. 430 = 4.30V)
`vbat_max_cell_voltage` - Maximum voltage per cell when the battery is fully charged. Used for the OSD voltage based battery gauge (0.01V unit, i.e. 420 = 4.20V)
`vbat_warning_cell_voltage` - Cell warning voltage. A cell voltage bellow this value triggers the first (short beeps) voltage based battery alarm if used and also the blinking of the OSD voltage indicator if the battery capacity is not used instead (see bellow) (0.01V unit, i.e. 370 = 3.70V)
`vbat_min_cell_voltage` - Cell minimum voltage. A cell voltage bellow this value triggers the second (long beeps) voltage based battery alarm if used and the OSD gauge will display 0% if the battery capacity is not used instead (see bellow) (0.01V unit, i.e. 350 = 3.50V)
e.g.
```
battery_profile 1
set vbat_scale = 1100
set vbat_max_cell_voltage = 430
set vbat_warning_cell_voltage = 340
set vbat_min_cell_voltage = 330
```
# Current Monitoring
Current monitoring (amperage) is supported by connecting a current meter to the appropriate current meter ADC input (see the documentation for your particular board).
When enabled, the following values calculated and used by the telemetry and OLED display subsystems:
* Amps
* mAh used
* Capacity remaining
## Configuration
Enable current monitoring using the CLI command:
```
feature CURRENT_METER
```
Configure the current meter type using the `current_meter_type` settings here:
| Value | Sensor Type |
| ----- | ---------------------- |
| 0 | None |
| 1 | ADC/hardware sensor |
| 2 | Virtual sensor |
Configure capacity using the `battery_capacity` setting, in mAh units.
If you're using an OSD that expects the multiwii current meter output value, then set `multiwii_current_meter_output` to `1` (this multiplies amperage sent to MSP by 10).
### ADC Sensor
The current meter may need to be configured so the value read at the ADC input matches actual current draw. Just like you need a voltmeter to correctly calibrate your voltage reading you also need an ammeter to calibrate the current sensor.
Use the following settings to adjust calibration:
`current_meter_scale`
`current_meter_offset`
### Virtual Sensor
The virtual sensor uses the throttle position to calculate an estimated current value. This is useful when a real sensor is not available. The following settings adjust the virtual sensor calibration:
| Setting | Description |
| ----------------------------- | -------------------------------------------------------- |
| `current_meter_scale` | The throttle scaling factor [centiamps, i.e. 1/100th A] |
| `current_meter_offset` | The current at zero throttle (while disarmed) [centiamps, i.e. 1/100th A] |
There are two simple methods to tune these parameters: one uses a battery charger and another depends on actual current measurements.
#### Tuning Using Actual Current Measurements
If you know your craft's current draw while disarmed (Imin) and at maximum throttle while armed (Imax), calculate the scaling factors as follows:
```
current_meter_scale = (Imax - Imin) * 100000 / (Tmax + (Tmax * Tmax / 50))
current_meter_offset = Imin * 100
```
Note: Tmax is maximum throttle offset (i.e. for `max_throttle` = 1850, Tmax = 1850 - 1000 = 850)
For example, assuming a maximum current of 34.2A, a minimum current of 2.8A, and a Tmax `max_throttle` = 1850:
```
current_meter_scale = (Imax - Imin) * 100000 / (Tmax + (Tmax * Tmax / 50))
= (34.2 - 2.8) * 100000 / (850 + (850 * 850 / 50))
= 205
current_meter_offset = Imin * 100 = 280
```
#### Tuning Using Battery Charger Measurement
If you cannot measure current draw directly, you can approximate it indirectly using your battery charger.
However, note it may be difficult to adjust `current_meter_offset` using this method unless you can
measure the actual current draw with the craft disarmed.
Note:
+ This method depends on the accuracy of your battery charger; results may vary.
+ If you add or replace equipment that changes the in-flight current draw (e.g. video transmitter,
camera, gimbal, motors, prop pitch/sizes, ESCs, etc.), you should recalibrate.
The general method is:
1. Fully charge your flight battery
2. Fly your craft, using >50% of your battery pack capacity (estimated)
3. Note INAV's reported mAh draw
4. Re-charge your flight battery, noting the mAh charging data needed to restore the pack to fully charged
5. Adjust `current_meter_scale` to according to the formula given below
6. Repeat and test
Given (a) the reported mAh draw and the (b) mAh charging data, calculate a new `current_meter_scale` value as follows:
```
current_meter_scale = (reported_draw_mAh / charging_data_mAh) * old_current_meter_scale
```
For example, assuming:
+ A INAV reported current draw of 1260 mAh
+ Charging data to restore full charge of 1158 mAh
+ A existing `current_meter_scale` value of 400 (the default)
Then the updated `current_meter_scale` is:
```
current_meter_scale = (reported_draw_mAh / charging_data_mAh) * old_current_meter_scale
= (1260 / 1158) * 400
= 435
```
## Battery capacity monitoring
For the capacity monitoring to work you need a current sensor (`CURRENT_METER` feature). For monitoring energy in milliWatt hour you also need voltage measurement (`VBAT` feature). For best results the current and voltage readings have to be calibrated.
It is possible to display the remaining battery capacity in the OSD and also use the battery capacity thresholds (`battery_capacity_warning` and `battery_capacity_critical`) for battery alarms.
For the remaining battery capacity to be displayed users need to set the `battery_capacity` setting (>0) and the battery to be full when plugged in. If the `battery_capacity` setting is set to 0 the remaining battery capacity item in the OSD will display `NA` and the battery gauge will use an estimation based on the battery voltage otherwise it will display the remaining battery capacity down to the `battery_capacity_critical` setting (battery considered empty) and the battery gauge will be based on the remaining capacity. For the capacity thresholds to be used for alarms the `battery_capacity_warning` and `battery_capacity_critical` settings also needs to be set (>0) and the plugged in battery to be full when plugged in. The battery capacity settings unit can be set using the `battery_capacity_unit`. MilliAmpere hour and milliWatt hour units are supported. The value are absolute meaning that `battery_capacity_warning` is the battery capacity left when the battery is entering the `warning` state and `battery_capacity_critical` is the battery capacity left when the battery is considered empty and entering the `critical` state.
For the battery to be considered full the mean cell voltage of the battery needs to be above `vbat_max_cell_voltage - 140mV` (by default 4.1V). So a 3S battery will be considered full above 12.3V and a 4S battery above 16.24V. If the battery plugged in is not considered full the remaining battery capacity OSD item will show `NF` (Not Full).
For the remaining battery capacity and battery gauge to be the most precise (linear relative to throttle from full to empty) when using battery capacity monitoring users should use the milliWatt hour unit for the battery capacity settings.
### Example configuration
```
set battery_capacity_unit = MAH // battery capacity values are specified in milliAmpere hour
set battery_capacity = 2200 // battery capacity is 2200mAh
set battery_capacity_warning = 660 // the battery warning alarm will sound and the capacity related OSD items will blink when left capacity is less than 660 mAh (30% of battery capacity)
set battery_capacity_critical = 440 // the battery critical alarm will sound and the OSD battery gauge and remaining capacity item will be empty when left capacity is less than 440 mAh (20% of battery capacity)
```
Note that in this example even though your warning capacity (`battery_capacity_warning`) is set to 30% (660mAh), since 440mAh (`battery_capacity_critical`) is considered empty (0% left), the OSD capacity related items will only start to blink when the remaining battery percentage shown on the OSD is below 12%: (`battery_capacity_warning`-`battery_capacity_critical`)*100/(`battery_capacity`-`battery_capacity_critical`)=(660-440)*100/(2200-440)=12.5
## Battery profiles
Up to 3 battery profiles are supported. You can select the battery profile from the GUI, OSD menu, [stick commands](Controls.md) and CLI command `battery_profile n`. Battery profiles store the following settings (see above for an explanation of each setting): `bat_cells`, `vbat_cell_detect_voltage`, `vbat_max_cell_voltage`, `vbat_warning_cell_voltage`, `vbat_min_cell_voltage`, `battery_capacity_unit`, `battery_capacity`, `battery_capacity_warning`, `battery_capacity_critical`
To enable the automatic battery profile switching based on battery voltage enable the `BAT_PROF_AUTOSWITCH` feature. For a profile to be automatically selected the number of cells of the battery needs to be specified (>0).
### Battery profiles configuration examples
#### Simple example
In this example we want to use two different type of batteries for the same aircraft and switch manually between them. The first battery is a Li-Po (4.20V/cell) and the second battery is a Li-Ion (4.10V/cell).
```
battery_profile 1
set bat_cells = 0
set vbat_max_cell_voltage = 420
set vbat_warning_cell_voltage = 370
set vbat_min_cell_voltage = 340
battery_profile 2
set bat_cells = 0
set vbat_max_cell_voltage = 410
set vbat_warning_cell_voltage = 280
set vbat_min_cell_voltage = 250
```
#### Simple example with automatic profile switching
In this example we want to use two different batteries for the same aircraft and automatically switch between them when the battery is plugged in. The first battery is a Li-Po 2200mAh 3S and the second battery is a LiPo 1500mAh 4S. Since the iNav defaults for the cell detection voltage and max voltage are adequate for standard LiPo batteries they will not be modified. The warning and minimum voltage are not modified either in this example but you can set them to the value you like. Since we are using battery capacities only the warning voltage (kept at default in this example) will be used and only for triggering the battery voltage indicator blinking in the OSD.
```
feature BAT_PROF_AUTOSWITCH
battery_profile 1
set bat_cells = 3
set battery_capacity_unit = MAH
set battery_capacity = 2200
set battery_capacity_warning = 440
set battery_capacity_critical = 220
battery_profile 2
set bat_cells = 4
set battery_capacity_unit = MAH
set battery_capacity = 1500
set battery_capacity_warning = 300
set battery_capacity_critical = 150
```
#### Advanced automatic switching example
Profile 1 is for a 3S 2200mAh Li-Po pack (max 4.20V/cell), profile 2 for a 3S 4000mAh Li-Ion pack (max 4.10V/cell) and profile 3 for a 4S 1500mAh Li-Po pack (max 4.20V/cell).
With this configuration if the battery plugged in is less than 12.36V (3 x 4.12) the profile 2 will be automatically selected else if the battery voltage is less than 12.66V (3 x 4.22) the profile 1 will be automatically selected else if the battery voltage is less 17.20V (4 x 4.3) the profile 3 will be automatically selected. If a matching profile can't be found the last selected profile is used.
```
feature BAT_PROF_AUTOSWITCH
battery_profile 1
set bat_cells = 3
set vbat_cell_detect_voltage = 422
set vbat_max_cell_voltage = 420
set vbat_warning_cell_voltage = 350
set vbat_min_cell_voltage = 330
set battery_capacity = 2200
set battery_capacity_warning = 440
set battery_capacity_critical = 220
battery_profile 2
set bat_cells = 3
set vbat_cell_detect_voltage = 412
set vbat_max_cell_voltage = 410
set vbat_warning_cell_voltage = 300
set vbat_min_cell_voltage = 280
set battery_capacity = 4000
set battery_capacity_warning = 800
set battery_capacity_critical = 400
battery_profile 3
set bat_cells = 4
set vbat_cell_detect_voltage = 430
set vbat_max_cell_voltage = 420
set vbat_warning_cell_voltage = 350
set vbat_min_cell_voltage = 330
set battery_capacity = 1500
set battery_capacity_warning = 300
set battery_capacity_critical = 150
```
## Remaining flight time and flight distance estimation
The estimated remaining flight time and flight distance estimations can be displayed on the OSD (for fixed wing only for the moment). They are calculated from the GPS distance from home, remaining battery capacity and average power draw. They are taking into account the requested altitude change and heading to home change after altitude change following the switch to RTH. They are also taking into account the estimated wind if `osd_estimations_wind_compensation` is set to `ON`. When the timer and distance indicator reach 0 they will blink and you need to go home in a straight line manually or by engaging RTH. You should be left with at least `rth_energy_margin`% of battery left when arriving home if the cruise speed and power are set correctly (see bellow).
To use this feature the following conditions need to be met:
- The `VBAT`, `CURRENT_METER` and `GPS` features need to be enabled
- The battery capacity needs to be specified in mWh (`battery_capacity` setting > 0 and `battery_capacity_unit` set to `MWH`)
- The average ground speed of the aircraft without wind at cruise throttle needs to be set (`nav_fw_cruise_speed` setting in cm/s)
- The average power draw at zero throttle needs to be specified (`idle_power` setting in 0.01W unit)
- The average power draw at cruise throttle needs to be specified (`cruise_power` setting in 0.01W unit)
- The battery needs to be full when plugged in (voltage >= (`vbat_max_cell_voltage` - 100mV) * cells)
It is advised to set `nav_fw_cruise_speed` a bit lower than the real speed and `cruise_power` 10% higher than the power at cruise throttle to ensure variations in throttle during cruise won't cause the aircraft to draw more energy than estimated.
If `---` is displayed during flight instead of the remaining flight time/distance it means at least one of the above conditions aren't met. If the OSD element is blinking and the digits are replaced by the horizontal wind symbol it means that the estimated horizontal wind is too strong to be able to return home at `nav_fw_cruise_speed`.
## Automatic throttle compensation based on battery voltage
This features aims to compensate the throttle to get constant thrust with the same throttle request despite the battery voltage going down during flight. It can be used by enabling the `THR_VBAT_COMP` feature. This feature needs the sag compensated voltage which needs a current sensor (real or virtual) to be calculated.
It is working like this: `used_throttle = requested_throttle * (1 + (battery_full_voltage / sag_compensated_voltage - 1) * thr_comp_weight)`.
The default `thr_comp_weight` of 1 should be close to ideal but if you want to tune this feature you need to find the difference in throttle value to achieve the same thrust (same power) when your battery is full and when your battery is almost empty then set `thr_comp_weight` to `(empty_battery_throttle / full_battery_throttle - 1) / (battery_full_voltage / battery_empty_sag_compensated_voltage - 1)`
Example:
If the drawn power is 100W when the battery is full (12.6V) with 53% throttle and the drawn power is 100W with 58% throttle when the battery is almost empty with the sag compensated voltage being 11.0V `thr_comp_weight` needs to be set to this value to compensate the throttle automatically:
`(58 / 53 - 1) / (12.6 / 11.0 - 1) = 0.649`
Known limitation: it doesn't work in 3D mode (3D feature)

262
docs/Blackbox.md

@ -0,0 +1,262 @@
# Blackbox flight data recorder
![Rendered flight log frame](Screenshots/blackbox-screenshot-1.jpg)
## Introduction
This feature transmits your flight data information on every control loop iteration over a serial port to an external
logging device to be recorded, or to a dataflash chip which is present on some flight controllers.
After your flight, you can view the resulting logs using the interactive log viewer:
https://github.com/iNavFlight/blackbox-log-viewer
You can also use the `blackbox_decode` tool to turn the logs into CSV files for analysis, or render your flight log as a
video using the `blackbox_render` tool. Those tools can be found in this repository:
https://github.com/cleanflight/blackbox-tools
## Logged data
The blackbox records flight data on every iteration of the flight control loop. It records the current time in
microseconds, P, I and D corrections for each axis, your RC command stick positions (after applying expo curves),
gyroscope data, accelerometer data (after your configured low-pass filtering), barometer and rangefinder readings, 3-axis
magnetometer readings, raw VBAT and current measurements, RSSI, and the command being sent to each motor speed
controller. This is all stored without any approximation or loss of precision, so even quite subtle problems should be
detectable from the fight data log.
GPS data is logged whenever new GPS data is available. Although the CSV decoder will decode this data, the video
renderer does not yet show any of the GPS information (this will be added later).
## Supported configurations
The maximum data rate that can be recorded to the flight log is fairly restricted, so anything that increases the load
can cause the flight log to drop frames and contain errors.
The Blackbox is typically used on tricopters and quadcopters. Although it will work on hexacopters and octocopters,
because these craft have more motors to record, they must transmit more data to the flight log. This can increase the
number of dropped frames. Although the browser-based log viewer supports hexacopters and octocopters, the command-line
`blackbox_render` tool currently only supports tri- and quadcopters.
INAV's `looptime` setting decides how frequently an update is saved to the flight log. The default looptime on
INAV is 2000us. If you're using a looptime smaller than about 2400, you may experience some dropped frames due to
the high required data rate. In that case you will need to reduce the sampling rate in the Blackbox settings, or
increase your logger's baudrate to 250000. See the later section on configuring the Blackbox feature for details.
## Setting up logging
First, you must enable the Blackbox feature. In the [INAV Configurator][] enter the Configuration tab,
tick the "BLACKBOX" feature at the bottom of the page, and click "Save and reboot"
Now you must decide which device to store your flight logs on. You can either transmit the log data over a serial port
to an external logging device like the [OpenLog serial data logger][] to be recorded to a microSDHC card, or if you have
a compatible flight controller you can store the logs on the onboard dataflash storage instead.
### OpenLog serial data logger
The OpenLog is a small logging device which attaches to your flight controller using a serial port and logs your
flights to a MicroSD card.
The OpenLog ships from SparkFun with standard "OpenLog 3" firmware installed. Although this original OpenLog firmware
will work with the Blackbox, in order to reduce the number of dropped frames it should be reflashed with the
higher performance [OpenLog Blackbox firmware][]. The special Blackbox variant of the OpenLog firmware also ensures that
the OpenLog is using INAV compatible settings, and defaults to 115200 baud.
You can find the Blackbox version of the OpenLog firmware [here](https://github.com/cleanflight/blackbox-firmware),
along with instructions for installing it onto your OpenLog.
[OpenLog serial data logger]: https://www.sparkfun.com/products/9530
[OpenLog Blackbox firmware]: https://github.com/cleanflight/blackbox-firmware
#### microSDHC
Your choice of microSDHC card is very important to the performance of the system. The OpenLog relies on being able to
make many small writes to the card with minimal delay, which not every card is good at. A faster SD-card speed rating is
not a guarantee of better performance.
##### microSDHC cards known to have poor performance
- Generic 4GB Class 4 microSDHC card - the rate of missing frames is about 1%, and is concentrated around the most
interesting parts of the log!
- Sandisk Ultra 32GB (unlike the smaller 16GB version, this version has poor write latency)
##### microSDHC cards known to have good performance
- Transcend 16GB Class 10 UHS-I microSDHC (typical error rate < 0.1%)
- Sandisk Extreme 16GB Class 10 UHS-I microSDHC (typical error rate < 0.1%)
- Sandisk Ultra 16GB (it performs only half as well as the Extreme in theory, but still very good)
You should format any card you use with the [SD Association's special formatting tool][] , as it will give the OpenLog
the best chance of writing at high speed. You must format it with either FAT, or with FAT32 (recommended).
[SD Association's special formatting tool]: https://www.sdcard.org/downloads/formatter_4/
### Choosing a serial port for the OpenLog
First, tell the Blackbox to log using a serial port (rather than to an onboard dataflash chip). Go to the
Configurator's CLI tab, enter `set blackbox_device=SERIAL` to switch logging to serial, and
save.
You need to let INAV know which of [your serial ports][] you connect your OpenLog to (i.e. the Blackbox port),
which you can do on the Configurator's Ports tab.
You should use a hardware serial port. SoftSerial ports can be used for the Blackbox. However, because they are limited to 19200 baud, your logging
rate will need to be severely reduced to compensate. Therefore the use of SoftSerial is not recommended.
When using a hardware serial port, Blackbox should be set to at least 115200 baud on that port. When using fast
looptimes (<2500), a baud rate of 250000 should be used instead in order to reduce dropped frames.
The serial port used for Blackbox cannot be shared with any other function (e.g. GPS, telemetry) except the MSP
protocol. If MSP is used on the same port as Blackbox, then MSP will be active when the board is disarmed, and Blackbox
will be active when the board is armed. This will mean that you can't use the Configurator or any other function that
requires MSP, such as an OSD or a Bluetooth wireless configuration app, while the board is armed.
Connect the "TX" pin of the serial port you've chosen to the OpenLog's "RXI" pin. Don't connect the serial port's RX
pin to the OpenLog, as this will cause the OpenLog to interfere with any shared functions on the serial port while
disarmed.
The key criteria to choose a serial port are:
* Should be a hardware serial port rather than SoftSerial.
* Cannot be shared with any other function (GPS, telemetry) except MSP.
* If MSP is used on the same UART, MSP will stop working when the board is armed.
#### OpenLog configuration
Power up the OpenLog with a microSD card inside, wait 10 seconds or so, then power it down and plug the microSD card
into your computer. You should find a "CONFIG.TXT" file on the card, open it up in a text editor. You should see the
baud rate that the OpenLog has been configured for (usually 115200 or 9600 from the factory). Set the baud rate to match
the rate you entered for the Blackbox in the Configurator's Port tab (typically 115200 or 250000).
Save the file and put the card back into your OpenLog, it will use those settings from now on.
If your OpenLog didn't write a CONFIG.TXT file, create a CONFIG.TXT file with these contents and store it in the root
of the MicroSD card:
```
115200
baud
```
If you are using the original OpenLog firmware, use this configuration instead:
```
115200,26,0,0,1,0,1
baud,escape,esc#,mode,verb,echo,ignoreRX
```
#### OpenLog protection
The OpenLog can be wrapped in black electrical tape or heat-shrink in order to insulate it from conductive frames (like
carbon fiber), but this makes its status LEDs impossible to see. I recommend wrapping it with some clear heatshrink
tubing instead.
![OpenLog installed](Wiring/blackbox-installation-1.jpg "OpenLog installed with double-sided tape, SDCard slot pointing outward")
### Onboard dataflash storage
Some flight controllers have an onboard SPI NOR dataflash chip which can be used to store flight logs instead of using
an OpenLog.
The SPRacingF3 has a 8 megabyte dataflash chip onboard which allows for longer recording times.
These chips are also supported:
* Micron/ST M25P16 - 16 Mbit / 2 MByte
* Micron N25Q064 - 64 Mbit / 8 MByte
* Winbond W25Q64 - 64 Mbit / 8 MByte
* Micron N25Q0128 - 128 Mbit / 16 MByte
* Winbond W25Q128 - 128 Mbit / 16 MByte
#### Enable recording to dataflash
On the Configurator's CLI tab, you must enter `set blackbox_device=SPIFLASH` to switch to logging to an onboard dataflash chip,
then save.
[your serial ports]: https://github.com/iNavFlight/inav/blob/master/docs/Serial.md
[INAV Configurator]: https://chrome.google.com/webstore/detail/inav-configurator/fmaidjmgkdkpafmbnmigkpdnpdhopgel
## Configuring the Blackbox
The Blackbox currently provides two settings (`blackbox_rate_num` and `blackbox_rate_denom`) that allow you to control
the rate at which data is logged. These two together form a fraction (`blackbox_rate_num / blackbox_rate_denom`) which
decides what portion of the flight controller's control loop iterations should be logged. The default is 1/1 which logs
every iteration.
If you're using a slower MicroSD card, you may need to reduce your logging rate to reduce the number of corrupted
logged frames that `blackbox_decode` complains about. A rate of 1/2 is likely to work for most craft.
You can change the logging rate settings by entering the CLI tab in the [INAV Configurator][] and using the `set`
command, like so:
```
set blackbox_rate_num = 1
set blackbox_rate_denom = 2
```
The data rate for my quadcopter using a looptime of 2400 and a rate of 1/1 is about 10.25kB/s. This allows about 18
days of flight logs to fit on my OpenLog's 16GB MicroSD card, which ought to be enough for anybody :).
If you are logging using SoftSerial, you will almost certainly need to reduce your logging rate to 1/32. Even at that
logging rate, looptimes faster than about 1000 cannot be successfully logged.
If you're logging to an onboard dataflash chip instead of an OpenLog, be aware that the 2MB of storage space it offers
is pretty small. At the default 1/1 logging rate, and a 2400 looptime, this is only enough for about 3 minutes of
flight. This could be long enough for you to investigate some flying problem with your craft, but you may want to reduce
the logging rate in order to extend your recording time.
To maximize your recording time, you could drop the rate all the way down to 1/32 (the smallest possible rate) which
would result in a logging rate of about 10-20Hz and about 650 bytes/second of data. At that logging rate, a 2MB
dataflash chip can store around 50 minutes of flight data, though the level of detail is severely reduced and you could
not diagnose flight problems like vibration or PID setting issues.
## Usage
The Blackbox starts recording data as soon as you arm your craft, and stops when you disarm.
If your craft has a buzzer attached, you can use INAV's arming beep to synchronize your Blackbox log with your
flight video. INAV's arming beep is a "long, short" pattern. The beginning of the first long beep will be shown
as a blue line in the flight data log, which you can sync against your recorded audio track.
You should wait a few seconds after disarming your craft to allow the Blackbox to finish saving its data.
### Usage - OpenLog
Each time the OpenLog is power-cycled, it begins a fresh new log file. If you arm and disarm several times without
cycling the power (recording several flights), those logs will be combined together into one file. The command line
tools will ask you to pick which one of these flights you want to display/decode.
Don't insert or remove the SD card while the OpenLog is powered up.
### Usage - Dataflash chip
After your flights, you can use the [INAV Configurator][] to download the contents of the dataflash to your
computer. Go to the "dataflash" tab and click the "save flash to file..." button. Saving the log can take 2 or 3
minutes.
![Dataflash tab in Configurator](Screenshots/blackbox-dataflash.png)
After downloading the log, be sure to erase the chip to make it ready for reuse by clicking the "erase flash" button.
If you try to start recording a new flight when the dataflash is already full, Blackbox logging will be disabled and
nothing will be recorded.
### Usage - Logging switch
If you're recording to an onboard flash chip, you probably want to disable Blackbox recording when not required in order
to save storage space. To do this, you can add a Blackbox flight mode to one of your AUX channels on the Configurator's
modes tab. Once you've added a mode, Blackbox will only log flight data when the mode is active.
A log header will always be recorded at arming time, even if logging is paused. You can freely pause and resume logging
while in flight.
## Viewing recorded logs
After your flights, you'll have a series of flight log files with a .TXT extension.
You can view these .TXT flight log files interactively using your web browser with the INAV Blackbox Explorer:
https://github.com/iNavFlight/blackbox-log-viewer
This allows you to scroll around a graphed version of your log and examine your log in detail. You can also export a
video of your log to share it with others!
You can decode your logs with the `blackbox_decode` tool to create CSV (comma-separated values) files for analysis,
or render them into a series of PNG frames with `blackbox_render` tool, which you could then convert into a video using
another software package.
You'll find those tools along with instructions for using them in this repository:
https://github.com/iNavFlight/blackbox-log-viewer

85
docs/Board - Airbot F4 and Flip32 F4.md

@ -0,0 +1,85 @@
# Board - Airbot F4 / Flip32 F4 / Generic F4 Flight Controller from Banggood and Aliexpress
![Airbot F4](https://quadmeup.com/wp-content/uploads/2016/10/Flip32-F4-Flight-Controller-pinout.jpg)
> This target supports both MPU6000 and MPU6500 versions of this board
## Features
* STM32F405 CPU
* Integrated Accelerometer/Gyro MPU6000 or MPU6500 via SPI bus
* 6 motor outputs
* 4 UART ports (UART1, UART3, UART6, Softserial1)
* External I2C bus, pins shared with UART3, can not be used simultaneously
* Only UART1 is equipped with inverter
* Onboard 128Mbit (16MB) flash
* BLHeli Passthrough
* Integrated voltage stabilizer
* Buzzer connector
## **NOT** supported
* HC-SR04 Rangefinder
* ServoTilt
## Radio Receivers
SerialRX, PPM and MSP receivers are supported.
SerialRX and PPM receivers should be connected to dedicated _PPM SBUS_ connector above _Motor 1_. MSP receivers should be connected to one of UARTs configured as MSP.
## Motors
| Motor | pin | Shared with |
| ---- | ---- | ---- |
| 1 | PB0 | |
| 2 | PB1 | |
| 3 | PA3 | |
| 4 | PA2 | |
| 5 | PA1 | LED Strip |
| 6 | PA8 | |
## USB
This board uses STM32 VCP and _not_ utilizes UART when USB is connected. STM32 VCP drivers might be required!
Flashing requires DFU mode and STM32 DFU drivers. Use [Zadig](http://zadig.akeo.ie) tool to install WinUSB driver on Windows.
## Buzzer / Beeper
5V piezo buzzer should be connected directly to dedicated pins _BUZ +_ and _BUZ -_. No additional hardware is required.
## RSSI ADC
* Connected to pin PA0
* 3.3V tolerant, do not supply 5V
## Current Meter ADC
* Connected to pin PC1
* 3.3V tolerant, do not supply 5V
## Voltage monitoring
* Connected to pin PC2
* Connected to VBAT pins (both are the same) and integrated Voltage Stabilizer (LM7805M)
## Integrated voltage stabilizer
It is integrated with voltage monitoring and always powered when VBAT is connected to battery.
Because this is **Linear Stabilizer**, it has a tendency to overheat, especially on 4S. Because of that,
avoid powering too many devices directly to 5V pins on the board. RX receiver is (and board itself) is rather all
it can do without overeating (150mA on 4S gives 1.5W of waste heat!). OSD, LED Strip and other devices should powered from separate BEC if voltage monitoring is to be enabled.
## LED Strip
LED strip is enabled on Motor 5 pin (PA1)
## SoftwareSerial
This board allows for single **SoftwareSerial** port on small soldering pads located next to UART3 pins.
| Pad | SoftwareSerial Role |
| ---- | ---- |
| CH5 | RX |
| CH6 | TX |

71
docs/Board - AlienFlight.md

@ -0,0 +1,71 @@
# AlienFlight (ALIENFLIGHTF1, ALIENFLIGHTF3, ALIENFLIGHTF4 and ALIENFLIGHTNGF7 target)
AlienWii is now AlienFlight. This designs are released partially for public (CC BY-SA 4.0) and some for noncommercial use (CC BY-NC-SA 4.0) at:
http://www.alienflight.com
AlienFlight F3 Eagle files are available at:
https://github.com/MJ666/Flight-Controllers
AlienFlightNG (Next Generation) designs are released for noncommercial use (CC BY-NC-SA 4.0) or (CC BY-NC-ND 4.0) can be found here:
http://www.alienflightng.com
This targets supports various variants of brushed and brushless flight controllers. All published designs are flight tested by various people. The intention here is to make these flight controllers available and enable skilled users and in some cases RC vendors to build them.
Some variants of the AlienFlight controllers will be available for purchase from:
http://www.microfpv.eu
https://micro-motor-warehouse.com
Here are the general hardware specifications for this boards:
- STM32F303CCT6 MCU (ALIENFLIGHTF3)
- STM32F405RGT6 MCU (ALIENFLIGHTF4)
- STM32F711RET6 MCU (ALIENFLIGHTNGF7)
- MPU6050/6500/9250/ICM-20602 accelerometer/gyro(/mag) sensor unit
- The MPU sensor interrupt is connected to the MCU for all published designs and enabled in the firmware
- 4-8 x 4.2A to 9.5A brushed ESCs, integrated, to run the strongest micro motors (brushed variants)
- extra-wide traces on the PCB, for maximum power throughput (brushed variants)
- some new F4 boards using a 4-layer PCB for better power distribution
- USB port, integrated
- (*) serial connection for external DSM2/DSMX sat receiver (e.g. Spektrum SAT, OrangeRx R100, Lemon RX or Deltang Rx31) and SBUS
- CPPM input
- ground and 3.3V for the receiver, some boards have also the option to power an 5V receiver
- hardware bind plug for easy binding
- motor connections are at the corners for a clean look with reduced wiring
- small footprint
- direct operation from a single cell LIPO battery for brushed versions
- 3.3V LDO power regulator (older prototypes)
- 3.3V buck-boost power converter (all new versions)
- 5V buck-boost power converter for FPV (some versions)
- brushless versions are designed for 4S operation and also have an 5V power output
- battery monitoring with an LED or buzzer output (for some variants only)
- current monitoring (F4/F7 V1.1 versions)
- SDCard Reader for black box monitoring (F4/F7 V1.1 versions)
- (**) integrated OpenSky (FrSky compatible) receiver with FrSky hub telemetry (F4/F7 V2 versions)
- hardware detection of brushed and brushless versions with individual defaults
(*) Spektrum Compatible DSM2 satellites are supported out of the box. DSMX sat will work with DSM2 protocol with default settings (DSM2, 11bit, 11ms is preset). This is chosen for maximum compatibility. For optimal connection it is recommended to adjust settings to match the capabilities of your transmitter and satellite receiver. If possible it is recommended to use the DSMX protocol since it is known as more reliable. Also to make use of additional channels you should adjust the following two parameters with the Cleanflight Configurator.
set serialrx_provider = 1 (0 for 1024bit, 1 for 2048bit)
set spektrum_sat_bind = 5
(**) This receiver is based on the uSky and OpenSky projects. http://www.fishpepper.de
For more detail of the different bind modes please refer the CleanFlight Spektrum Bind document.
Deltang receivers in serial mode will work like any other Spektrum satellite compatible receiver (10bit, 22ms) only the bind process will be different.
(**) OpenSky receiver with telemetry is enabled by default if present on the board.
The AlienFlight firmware will be built as target ALIENFLIGHTF1, ALIENFLIGHTF3, ALIENFLIGHTF4 or ALIENFLIGHTNGF7. The firmware image will come with alternative default settings which will give the user a plug and play experience. There is no computer needed to get this into the air with a small Quadcopter. A preconfigured custom mixer for an Octocopter is part of the default settings to allow clean straight wiring with the AlienFlight. The mixer can be activated with "mixer custom" in the CLI. To use the AlienFlight controller in a Hexa- or Octocopter or to do some more tuning additional configuration changes can be done as usual in the CLI or the BetaFlight configurator.
## Flashing the firmware
The firmware can be updated with the BetaFlight configurator as for any other target. All AlienFlight boards have a boot jumper which need to be closed for initial flashing or for recovery from a broken firmware.
The firmware for the OpenSky receiver can be updated via serial pass-through and the embedded boot loader. The initial flashing need to be done with the ISP programming pins. The target for the embedded AlienFlight OpenSky receiver is "AFF4RX". Please refer to the OpenSky project for more details.
https://github.com/fishpepper/OpenSky/blob/master/README.md

86
docs/Board - AnyFC F7.md

@ -0,0 +1,86 @@
# AnyFC-F7
* The first F7 board flown with betaflight and inavflight, made by [@sambas](https://github.com/sambas)
* OSHW CC BY-SA 3.0
* Source: https://github.com/sambas/hw/tree/master/AnyFCF7
* 1st betaflight: https://www.youtube.com/watch?v=tv7k3A0FG80
* 1st inavflight: https://www.youtube.com/watch?v=kJvlZAzprBs
## HW info
* STM32F745VGT6 100lqfp 216MHz
* MPU6000 SPI
* MS5611 baro
* All 8 uarts available + VCP
* 10 pwm outputs + 6 inputs
* external I2C
* external SPI (shared with U4/5)
* support for CAN
* SD card logging (SPI)
* 3 AD channels, one with 10k/1k divider, two with 1k series resistor
## Pinout
![Top](https://quadmeup.com/wp-content/uploads/2017/05/AnyFC-F7-Top-Side-Pinout.jpg)
![Bottom](https://quadmeup.com/wp-content/uploads/2017/05/AnyFC-F7-Bottom-Side-Pinout.jpg)
## Outout mapping
Multirotors
-----------
| Output number | No *LED Strip* | With *LED Strip* |
|---------------|----------------|------------------|
| 1 | Motor 4 | Motor 4 |
| 2 | Motor 5 | LED Strip |
| 3 | Motor 6 | Motor 5 |
| 4 | Motor 7 | Motor 6 |
| 5 | Motor 3 | Motor 3 |
| 6 | Motor 2 | Motor 2 |
| 7 | Motor 8 | - |
| 8 | - | Motor 7 |
| 9 | Buzzer | Buzzer |
| 10 | Motor 1 | Motor 1 |
| Input | Function |
|-------|----------|
| 1 | PPM |
| 2 | - |
| 3 | Servo 1 |
| 4 | Servo 2 |
| 5 | Servo 3 |
| 6 | Servo 4 |
Airplanes
---------
| Output number | Function |
|---------------|----------|
| 1 | Motor 1 |
| 2 | Motor 2 |
| 3 | Servo 4 |
| 4 | Servo 5 |
| 5 | Servo 3 |
| 6 | Servo 2 |
| 7 | Servo 6 |
| 8 | Servo 7 |
| 9 | Servo 8 |
| 10 | Servo 1 |
## Buzzer
Buzzer is supported with additional switching MOSFET transistor when connected to PWM Output #9.
![Buzzer](assets/images/anyfcf7_buzzer_pwm9.png)
## SD Card Detection
**Any Fc F7** clones can come with different SD card slot: with inverted or _not_ inverted detection pin. If board is not able to detect SD card, try changing `sdcard_detect_inverted` CLI setting. It accepts `ON` and `OFF` values.
## Barometer
**AnyFC F7** clones comes without MS5611 barometer installed. If you want to use external barometer of any kind (BMP280, BMP085, MS5611) you have to use target `ANYFCF7_EXTERNAL_BARO`. This target enables barometer detection on external I2C bus.
# AnyFC F7 Pro from Banggood
This board is not yet officially supported. It _should_ work but INAV devs did not tested it yet. Use on your own responsibility

60
docs/Board - BeeRotor F4.md

@ -0,0 +1,60 @@
# Board - BeeRotor F4
![BeeRotor F4 front](https://raw.githubusercontent.com/wiki/betaflight/betaflight/images/boards/beerotorf4/beerotorf4_front.jpg)
![BeeRotor F4 back](https://raw.githubusercontent.com/wiki/betaflight/betaflight/images/boards/beerotorf4/beerotorf4_back.jpg)
## Features
* STM32F405 CPU
* Integrated Accelerometer/Gyro MPU6050 via SPI bus
* Barometer BMP280
* 8 motor outputs
* 3 UART ports (UART1, UART2, UART3)
* External SPI bus
* UART2 and UART3 are equipped with inverter
* SD Card slot for logging
* LED connector
* Buzzer connector
* Integrated OSD
## Currently **NOT** supported
* inverter on UART3
* IR transmitter output
## Radio Receivers
SerialRX, PPM and MSP receivers are supported.
SerialRX and PPM receivers should be connected to dedicated _PPM SBUS_ pin on the _RX_ connector. MSP receivers should be connected to one of UARTs configured as MSP.
## USB
This board uses STM32 VCP and _not_ utilizes UART when USB is connected. STM32 VCP drivers might be required!
Flashing requires DFU mode and STM32 DFU drivers. Use [Zadig](http://zadig.akeo.ie) tool to install WinUSB driver on Windows.
## Buzzer / Beeper
5V piezo buzzer should be connected directly to dedicated pins _BUZ +_ and _BUZ -_. No additional hardware is required.
## RSSI monitoring
* Use the dedicated _RSSI_ pin on the _RX_ connector.
* 3.3V tolerant, do not supply 5V
## Current monitoring
* Use the dedicated _SI_ pin on the _PDB_ connector, or the _SI_ pad on the board.
* 3.3V tolerant, do not supply 5V
## Voltage monitoring
* Use the dedicated _SI_ pin on the _PDB_ connector, or the _SV_ pad on the board.
* 3.3V tolerant, do not supply 5V
* _SV_ pin on the _PDB_ connector does not have a voltage divider. It requires a voltage divider on the PDB, or the board will be destroyed! (The _SV_ pad on the board has a voltage divider, use this if your board doesn't.)
## LED Strip
* Use the dedicated _LED_ pin on the LED / buzzer connector.

12
docs/Board - BetFPVF722.md

@ -0,0 +1,12 @@
# BetaFPVF722
## I2C bus for magnetometer
BetFPVF722 does not have I2C pads broken out. I2C is shared with UART3
* TX3 - SCL
* RX3 - SDA
> I2C and UART3 can not be used at the same time! Connect the serial receiver to a different serial port when I2C device like MAG is used.
![BetaFPVF722 I2C](assets/betafpvf722.png)

106
docs/Board - DALRCF405.md

@ -0,0 +1,106 @@
# Board - DALRCF405
The DALRCF405 described here:
http://www.dalrcmodel.com/DALRC/plus/view.php?aid=184
This board use the STM32F405RGT6 microcontroller and have the following features:
* 1024K bytes of flash memory,192K bytes RAM,168 MHz CPU/210 DMIPS
* The 16M byte SPI flash for data logging
* USB VCP and boot select button on board(for DFU)
* Stable voltage regulation,9V/2A DCDC BEC for VTX/camera etc.And could select 5v/9v
* Serial LED interface(LED_STRIP)
* VBAT/CURR/RSSI sensors input
* Suppose IRC Tramp/smart audio/FPV Camera Control/FPORT/telemetry
* Supports SBus, Spektrum1024/2048, PPM. No external inverters required (built-in).
* Supports I2C device extend(baro/compass/OLED etc)
* Supports GPS
### Uarts
| Value | Identifier | RX | TX | Notes |
| ----- | ------------ | -----| -----| ------------------------------------------------------------------------------------------- |
| 1 | USART1 | PB7 | PA9 | PB7 FOR SBUS IN(inverter build in) |
| 2 | USART2 | PA3 | PA2 | PAD USE FOR TRAMP/smart audio |
| 3 | USART3 | PB11 | PB10| USE FOR GPS |
| 4 | USART4 | PA1 | PA0 | PA0 FOR RSSI/FPORT/TEL etc |
| 5 | USART5 | PD2 | PC12| PAD |
### I2C with GPS port together.Use for BARO or compass etc
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | I2C1 | SDA | PB9 | with GPS outlet
| 2 | I2C1 | SCL | PB8 | with GPS outlet
### Buzzer/LED output
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | LED0 | LED | PC14 |
| 2 | BEEPER | BEE | PC13 |
### VBAT input with 1/10 divider ratio,Current signal input,Analog/digit RSSI input
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | ADC1 | VBAT | PC2 | DMA2_Stream0
| 2 | ADC1 | CURR | PC1 | DMA2_Stream0
| 3 | ADC1 | RSSI | PA0 | DMA2_Stream0
| 4 | ADC1 | extend | PC0 | DMA2_Stream0 extend for other senser(PAD)
### 8 Outputs, 1 PPM input
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | TIM12_CH2 | PPM | PB15 | PPM
| 2 | TIM3_CH3 | OUPUT1 | PB0 | DMA1_Stream7
| 3 | TIM8_CH1 | OUPUT2 | PC6 | DMA2_Stream2
| 4 | TIM1_CH3 | OUPUT3 | PA10 | DMA2_Stream6
| 5 | TIM1_CH1 | OUPUT4 | PA8 | DMA2_Stream1
| 6 | TIM8_CH3 | OUPUT5 | PC8 | DMA2_Stream4
| 7 | TIM3_CH4 | OUPUT6 | PB1 | DMA1_Stream2
| 8 | TIM3_CH2 | OUPUT7 | PC7 | DMA1_Stream5
| 9 | TIM8_CH4 | OUPUT8 | PC9 | DMA2_Stream7
| 10 | TIM4_CH1 | PWM | PB6 | DMA1_Stream0 LED_STRIP
| 11 | TIM2_CH1 | PWM | PA5 | FPV Camera Control(FCAM)
### Gyro & ACC ,suppose ICM20689/MPU6000
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI1 | SCK | PB3 |
| 2 | SPI1 | MISO | PA6 |
| 3 | SPI1 | MOSI | PA7 |
| 4 | SPI1 | CS | PC4 |
### OSD MAX7456
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI3 | SCK | PC10 |
| 2 | SPI3 | MISO | PC11 |
| 3 | SPI3 | MOSI | PB5 |
| 4 | SPI3 | CS | PA15 |
### 16Mbyte flash
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI2 | SCK | PB13 |
| 2 | SPI2 | MISO | PB14 |
| 3 | SPI2 | MOSI | PC3 |
| 4 | SPI2 | CS | PB12 |
### SWD
| Pin | Function | Notes |
| --- | -------------- | -------------------------------------------- |
| 1 | SWCLK | PAD |
| 2 | Ground | PAD |
| 3 | SWDIO | PAD |
| 4 | 3V3 | PAD |
### Designers
* ZhengNyway(nyway@vip.qq.com) FROM DALRC

111
docs/Board - DALRCF722DUAL.md

@ -0,0 +1,111 @@
# Board - DALRCF722DUAL
The DALRCF722DUAL described here:
http://www.dalrcmodel.com/DALRC/plus/view.php?aid=188
This board use the STM32F722RET6 microcontroller and have the following features:
* High-performance and DSP with FPU, ARM Cortex-M7 MCU with 512 Kbytes Flash
* 216 MHz CPU,462 DMIPS/2.14 DMIPS/MHz (Dhrystone 2.1) and DSP instructions, Art Accelerator, L1 cache, SDRAM
* DUAL gyro MPU6000 and ICM20602,could choose mpu6000,more stable and smooth.Or choose ICM20602,higher rate(32K/32K).Choose on CLI mode,experience different feature gyro on same board
* OSD on board
* The 16M byte SPI flash on board for data logging
* USB VCP and boot select button on board(for DFU)
* Stable voltage regulation,DUAL BEC 5v/2.5A and 10v/2A for VTX/camera etc.And could select 5v/10v with pad
* Serial LED interface(LED_STRIP)
* VBAT/CURR/RSSI sensors input
* Suppose IRC Tramp/smart audio/FPV Camera Control/FPORT/telemetry
* Supports SBus(built-in inverters), Spektrum1024/2048, PPM
* Supports I2C device extend(baro/compass/OLED etc)(socket)
* Supports GPS (socket)
### All uarts have pad on board
| Value | Identifier | RX | TX | Notes |
| ----- | ------------ | -----| -----| ------------------------------------------------------------------------------------------- |
| 1 | USART1 | PB7 | PB6 | PB7 FOR SBUS IN(inverter build in)/PPM |
| 2 | USART2 | PA3 | PA2 | PAD USE FOR TRAMP/smart audio |
| 3 | USART3 | PC11 | PC10| USE FOR GPS |
| 4 | USART4 | PA1 | PA0 | PA0 FOR RSSI/FPORT/TEL etc |
| 5 | USART5 | PD2 | PC12| PAD |
### I2C with GPS port together.Use for BARO or compass etc
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | I2C1 | SDA | PB9 |
| 2 | I2C1 | SCL | PB8 |
### Buzzer/LED output
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | LED0 | LED | PC14 |On board
| 2 | BEEPER | BEE | PC13 |Pad
### VBAT input with 1/10 divider ratio,Current signal input,Analog/digit RSSI input
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | ADC1 | VBAT | PC1 |
| 2 | ADC1 | CURR | PC0 |
| 3 | ADC1 | RSSI | PA0 |
### 8 Outputs
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | TIM4_CH2 | PPM | PB7 | PPM
| 2 | TIM8_CH1 | OUPUT1 | PC6 | DMA
| 3 | TIM8_CH2 | OUPUT2 | PC7 | DMA
| 4 | TIM8_CH3 | OUPUT3 | PC8 | DMA
| 5 | TIM8_CH4 | OUPUT4 | PC9 | DMA
| 6 | TIM1_CH1 | OUPUT5 | PA8 | DMA
| 7 | TIM1_CH2 | OUPUT6 | PA9 | DMA
| 8 | TIM1_CH3 | OUPUT7 | PA10 | DMA NO PAD
| 9 | TIM2_CH4 | OUPUT8 | PB11 | NO PAD
| 10 | TIM2_CH1 | PWM | PA15 | DMA LED_STRIP
| 11 | TIM3_CH4 | PWM | PB1 | FPV Camera Control(FCAM)
### Gyro & ACC ,support ICM20602 and MPU6000
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI1 | SCK | PA5 | MPU6000 & ICM20602
| 2 | SPI1 | MISO | PA6 | MPU6000 & ICM20602
| 3 | SPI1 | MOSI | PA7 | MPU6000 & ICM20602
| 4 | SPI1 | CS1 | PB0 | MPU6000
| 5 | SPI1 | CS2 | PA4 | ICM20602
| 6 | SPI1 | INT1 | PB10 | MPU6000
| 7 | SPI1 | INT2 | PC4 | ICM20602
### OSD MAX7456
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI2 | SCK | PB13 |
| 2 | SPI2 | MISO | PB14 |
| 3 | SPI2 | MOSI | PB15 |
| 4 | SPI2 | CS | PB12 |
### 16Mbyte flash
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI3 | SCK | PB3 |
| 2 | SPI3 | MISO | PB4 |
| 3 | SPI3 | MOSI | PB4 |
| 4 | SPI3 | CS | PB2 |
### SWD
| Pin | Function | Notes |
| --- | -------------- | -------------------------------------------- |
| 1 | SWCLK | PAD |
| 2 | Ground | PAD |
| 3 | SWDIO | PAD |
| 4 | 3V3 | PAD |
### Designers
* ZhengNyway(nyway@vip.qq.com) FROM DALRC

33
docs/Board - FLYWOOF411.md

@ -0,0 +1,33 @@
# Board - FLYWOOF411
![Banggood](https://img.staticbg.com/thumb/view/oaupload/banggood/images/A5/01/79d28a2c-ef4b-4e4f-bab6-14edf66bbb23.jpg)
![Banggood](https://img.staticbg.com/images/oaupload/banggood/images/2E/C5/c14a1e86-4e58-4bc8-85de-8e344cb382b9.jpg)
![Banggood](https://img.staticbg.com/images/oaupload/banggood/images/42/F7/45a68ade-9be1-4fff-afec-bbdd45f0331d.jpg)
*Note:* This board used to be sold as a 'NOX F4' but is now an updated version similar to a Flywoo F411
## Banggood Specification:
* Model: Upgrade Betaflight F4 Noxe V1
* Version: Acro Version / Deluxe Version
* Acro Version: Without Barometer and Blackbox
* Deluxe Version: With Barometer and Blackbox
* CPU: STM32F411C
* MPU: MPU6000
* Input Voltage: Support 2-6S Lipo Input
* Built-In Betaflight OSD
* Built-in 5V @ 2.5A BEC & 8V @ 3A BEC
* 3.3V
* 4.5V powered by USB
* DShot, Proshot ESC
* Support Spektrum 1024 /2048 , SBUS, IBUS, PPM
* Built in flash for blackbox 16MB
* Support WS2812 LED strip
* Size: 27x27mm
* Mounting Hole: 20x20mm , M2.5
* Weight: 4.3g
* DSM / IBUS/SBUS Receiver, choose UART RX2
* PPM Receiver, don't need choose UART Port
## Where to buy:
* [Banggood](https://inavflight.com/shop/s/bg/1310419)

16
docs/Board - FOXEERF405.md

@ -0,0 +1,16 @@
# Board - FOXEERF405
The FOXEERF405 described here:
This board use the STM32F405RGT6 microcontroller and have the following features:
* 1024K bytes of flash memory,192K bytes RAM,168 MHz CPU/210 DMIPS
* The 16M byte SPI flash for data logging
* USB VCP and boot select button on board(for DFU)
* Stable voltage regulation,9V/2A DCDC BEC for VTX/camera etc.And could select 5v/9v with pad
* Serial LED interface(LED_STRIP)
* VBAT/CURR/RSSI sensors input
* Suppose IRC Tramp/smart audio/FPV Camera Control/FPORT/telemetry
* Supports SBus, Spektrum1024/2048, PPM. No external inverters required (built-in).
* Supports I2C device extend(baro/compass/OLED etc)
* Supports GPS
* Supports MPU6000 or ICM20689

103
docs/Board - FOXEERF722DUAL.md

@ -0,0 +1,103 @@
# Board - FOXEERF722DUAL, Foxeer F722 V2 and Foxeer F722 Mini
The Foxeer F722 DUAL, Foxeer F722 V2 and Foxeer F722 Mini described here:
This board use the STM32F722RET6 microcontroller and have the following features:
* High-performance and DSP with FPU, ARM Cortex-M7 MCU with 512 Kbytes Flash
* 216 MHz CPU,462 DMIPS/2.14 DMIPS/MHz (Dhrystone 2.1) and DSP instructions, Art Accelerator, L1 cache, SDRAM
* DUAL gyro MPU6000 and ICM20602,could choose mpu6000,more stable and smooth.Or choose ICM20602,higher rate(32K/32K).Choose on CLI mode,experience different feature gyro on same board
* OSD on board
* The 16M byte SPI flash on board for data logging
* USB VCP and boot select button on board(for DFU)
* Stable voltage regulation,DUAL BEC 5v/2.5A and 9v/2A for VTX/camera etc.And could select 5v/9v with pad
* Serial LED interface(LED_STRIP)
* VBAT/CURR/RSSI sensors input
* Suppose IRC Tramp/smart audio/FPV Camera Control/FPORT/telemetry
* Supports SBus, Spektrum1024/2048, PPM
* Supports I2C device extend(baro/compass/OLED etc)
* Supports GPS
### All uarts have pad on board
| Value | Identifier | RX | TX | Notes |
| ----- | ------------ | -----| -----| ------------------------------------------------------------------------------------------- |
| 1 | USART1 | PB7 | PB6 | PB7 FOR SBUS IN(inverter build in)/PPM |
| 2 | USART2 | PA3 | PA2 | PAD USE FOR TRAMP/smart audio |
| 3 | USART3 | PB11 | PB10| USE FOR GPS |
| 4 | USART4 | PA1 | PA0 | PA0 FOR RSSI/FPORT/TEL etc |
| 5 | USART5 | PD2 | PC12| PAD |
### I2C with GPS port together.Use for BARO or compass etc
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | I2C1 | SDA | PB9 | outlet
| 2 | I2C1 | SCL | PB8 | outlet
### Buzzer/LED output
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | LED0 | LED | PC15 |On board
| 2 | BEEPER | BEE | PA4 |Pad
### VBAT input with 1/10 divider ratio,Current signal input,Analog/digit RSSI input
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | ADC1 | VBAT | PC0 | On board
| 2 | ADC1 | CURR | PC2 |
| 3 | ADC1 | RSSI | PA0 |
### 8 Outputs
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ----------| ------| ------------------------------------------------------------------------------------- |
| 1 | TIM4_CH2 | PPM | PB7 | PPM
| 2 | TIM1_CH2 | OUPUT1 | PA9 | DMA
| 3 | TIM1_CH1 | OUPUT2 | PA8 | DMA
| 4 | TIM8_CH4 | OUPUT3 | PC9 | DMA
| 5 | TIM8_CH3 | OUPUT4 | PC8 | DMA
| 6 | TIM8_CH1 | OUPUT5 | PC6 | DMA
| 7 | TIM8_CH2 | OUPUT6 | PC7 | DMA
| 8 | TIM2_CH1 | PWM | PA15 | DMA LED_STRIP
| 9 | TIM2_CH2 | PWM | PB3 | FPV Camera Control(FCAM)
### Gyro & ACC ,support ICM20602 and MPU6000
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI1 | SCK | PA5 | MPU6000 & ICM20602
| 2 | SPI1 | MISO | PA6 | MPU6000 & ICM20602
| 3 | SPI1 | MOSI | PA7 | MPU6000 & ICM20602
| 4 | SPI1 | CS1 | PB2 | MPU6000
| 5 | SPI1 | CS2 | PB1 | ICM20602
| 6 | SPI1 | INT1 | PC4 | MPU6000
| 7 | SPI1 | INT2 | PB0 | ICM20602
### OSD MAX7456
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI3 | SCK | PC10 |
| 2 | SPI3 | MISO | PC11 |
| 3 | SPI3 | MOSI | PB5 |
| 4 | SPI3 | CS | PC3 |
### 16Mbyte flash
| Value | Identifier | function | pin | Notes |
| ----- | ------------ | ---------| -------| ------------------------------------------------------------------------------------- |
| 1 | SPI2 | SCK | PB13 |
| 2 | SPI2 | MISO | PB14 |
| 3 | SPI2 | MOSI | PB15 |
| 4 | SPI2 | CS | PB12 |
### SWD
| Pin | Function | Notes |
| --- | -------------- | -------------------------------------------- |
| 1 | SWCLK | PAD |
| 2 | Ground | PAD |
| 3 | SWDIO | PAD |
| 4 | 3V3 | PAD |
### Designers
* NywayZheng(nyway@vip.qq.com)

13
docs/Board - FrSky Pilot.md

@ -0,0 +1,13 @@
# Board - FRSKYPILOT
## Vendor Information / specification
https://www.frsky-rc.com/product/r9rxsr-pilot/
## Firmware
Two firmware variants are available.
* `inav_x.y.z_FRSKYPILOT.hex`
* `inav_x.y.z_FRSKYPILOT_LED.hex`
The only difference is that the `_LED` variant provides WS2812 LED support on S10. S11 & S12 are used for UART3 only.

19
docs/Board - IFLIGHTF7_TWING.md

@ -0,0 +1,19 @@
### Hardware
- MCU: STM32F722RET6
- IMU1: ICM20689_A (SPI1)
- IMU2: ICM20689_B (SPI1)
- OSD: AT7456E (SPI2)
- Barometer: BMP280 (IIC)
- Blackbox: Micron M25P16VP (SPI3)
### Feature
- High-performance and DSP with FPU, ARM Cortex-M7 MCU with 512 Kbytes Flash.
- DUAL gyro ICM20689_A and ICM20689_B, they can work together to show you better performance.
- The 16M byte SPI flash for data logging
- USB VCP and boot select button on board(for DFU)
- Serial LED interface(LED_STRIP)
- VBAT/CURR/RSSI sensors input
- Suppose IRC Tramp/smart audio/FPV Camera Control/FPORT/telemetry
- Supports SBus, Spektrum1024/2048, PPM. No external inverters required (built-in).
- Supports I2C device extend(baro/compass/OLED etc)(socket)
- Supports GPS (socket)

23
docs/Board - KroozX.md

@ -0,0 +1,23 @@
# Board - KroozX
![KroozX](https://farm4.staticflickr.com/3844/33558972311_507c7d6e36_h.jpg)
## Features
* MCU: STM32F4RGT6
* IMU: MPU6000 (SPI bus), ICM20608 (I2C bus)
* BARO: MS5611
* VCP: Yes
* Hardware UARTS: 5 (RX6/RX1/TX1 with onboard inverters)
* PWM outputs: 10
* OSD: MAX7456 with a switch for 2 video channel
* Blackbox: MicroSD card slot (SD/SDHC, upto 64GB)
* PPM/SBUS: RX6 with onboard inverter
* Wireless: HC-12 onboard transceiver
* Battery Voltage Sensor: Yes, up to 6S input
* Current Sensor: Yes
* Integrated Voltage Regulator: 5V 2000mA, 10V 2000mA with LC filter
* Buttons: No (powering the board with plugged USB starts STM DFU bootloader)
* Buzzer driver: Yes
* RSSI Analog/PWM port: Yes
* SWD port: Yes (SWIO, SWCLK, RST pins)

30
docs/Board - Matek F411 Wing.md

@ -0,0 +1,30 @@
# Board - [MATEKSYS F411-Wing](https://inavflight.com/shop/p/MATEKF411WING)
![Matek F411 Wing](https://quadmeup.com/wp-content/uploads/2018/12/DSC_0004.jpg)
## Specification:
* STM32F411 CPU
* OSD
* BMP280 barometer
* Integrated PDB for 2 motors
* 2 UART ports
* 5 servos
* no SD card slot
* 3 BECs
## Details
* [Full specification](http://www.mateksys.com/?portfolio=f411-wing)
* SBUS pad has a built-in inverter and is connected to UART1 RX
## Available TARGETS
* `MATEKF411` if you want to control LEDs and have SS1 TX on ST1 pad.
* `MATEKF411_FD_SFTSRL` if you need the softserial to be full-duplex (TX = ST1 pad, RX = LED pad), at the cost of losing the LED output.
* `MATEKF411_RSSI` if you want to have analog RSSI input on ST1 pad. SS1 TX will be available on the LED pad.
* `MATEKF411_SFTSRL2`if you want to use two softserials (TX only) at the same time. Eg. Smart Audio + S. Port, Smart Audio + LTM. (SS1 TX will be on ST1 pad and SS2 TX will be on LED pad).
## Where to buy:
* [Banggood](https://inavflight.com/shop/p/MATEKF411WING)

26
docs/Board - Matek F411-WSE.md

@ -0,0 +1,26 @@
# Board - [MATEKSYS F411-WSE](http://www.mateksys.com/?portfolio=f411-wse)
![Matek F411 Wing](http://www.mateksys.com/wp-content/uploads/2019/06/F411-WSE_1-1500x600.jpg)
## Specification:
* STM32F411 CPU
* OSD
* BMP280 barometer (DSP310 with new FCs from around June 2021)
* Integrated PDB for 2 motors
* 2 UART ports
* 6 servos
* no SD card slot
* 3 BECs
## Details
* [Full specification](http://www.mateksys.com/?portfolio=f411-wse)
* SBUS pad has a built-in inverter and is connected to UART2 RX
## Available TARGETS
* `MATEKF411SE` Stock target. LED control and have SS1 on ST1 pad, SS2 on TX2 pad.
* `MATEKF411SE_PINIO` Adds USER 2 PINIO support on the LED pad.
* `MATEKF411SE_FD_SFTSRL1` Adds full duplex SS1 by putting the RX on the LED pad.
* `MATEKF411SE_SS2_CH6` SS2 moved to Ch6 pad. This keeps UART 2 as a full UART (for example, for use with Crossfire) and SS2 support.

25
docs/Board - Matek F722-STD.md

@ -0,0 +1,25 @@
# Board - [MATEKSYS F722-STD](https://inavflight.com/shop/p/MATEKF722STD)
![Matek F722-STD](https://quadmeup.com/wp-content/uploads/2018/12/DSC_0012.jpg)
## Specification:
* STM32F722 CPU
* OSD
* BMP280 barometer
* Micro SD slot
* 5 UART serial ports
* I2C
* 7 outputs
* I2C
* No BEC
## Details
* [Full specification](http://www.mateksys.com/?portfolio=f722-std)
* For Matek F722-STD use `MATEKF722` firmware.
* all serial ports are capable of running SBUS and SmartPort, no need for any additional inverters or receiver hacks
## Where to buy:
* [Banggood](https://inavflight.com/shop/p/MATEKF722STD)

25
docs/Board - MatekF405 Wing.md

@ -0,0 +1,25 @@
# Board - [MATEKSYS F405-Wing](https://inavflight.com/shop/p/MATEKF405WING)
![Matek F405 Wing](https://quadmeup.com/wp-content/uploads/2018/12/DSC_0007.jpg)
## Specification:
* STM32F405 CPU
* OSD
* BMP280 barometer
* SD slot
* 6 UART serial ports
* I2C
* PDB for 2 motors
* 7 servos
* 5A BEC for the servos
## Details
* For Matek F405-WING use `MATEKF405SE` firmware.
* SBUS pin is connected to UART2
* SmartPort telemetry can be setup with `SoftwareSerial` feature turned on, SmartPort configured in SoftwareSerial1 and receiver connected to UART2 TX pad
## Where to buy:
* [Banggood](https://inavflight.com/shop/p/MATEKF405WING)

124
docs/Board - MatekF405.md

@ -0,0 +1,124 @@
# Board - MATEKSYS F405 family
![Matek F405-AIO](http://www.mateksys.com/wp-content/uploads/2017/06/F405-AIO_2.jpg)
### [Matek F405-CTR](https://inavflight.com/shop/p/MATEKF405CTR)
### [Matek F405-STD](https://inavflight.com/shop/p/MATEKF405STD)
### [Matek F405-AIO (end-of-life)](http://www.mateksys.com/?portfolio=f405-aio)
### [Matek F405-OSD (end-of-life)](http://www.mateksys.com/?portfolio=f405-osd)
## Firmware
Due to differences on the board (I2C - see below), there are two firmware variants:
| Board | Firmware |
| ------ | -------- |
| Matek F405-AIO, STD, CTR | inav_x.y.z_MATEKF405.hex<br/>inav_x.y.z_MATEKF405_SERVOS6.hex |
| Matek F405-OSD | inav_x.y.z_MATEKF405OSD.hex |
## Hardware features
* MCU: STM32F405RGT6, 168MHz
* IMU: ICM-20602 (OSD, AIO, STD), MPU6000 (CTR)
* OSD: BetaFlight OSD w/ AT7456E chip
* Baro: BMP280 (STD, CTR)
* Compass: No
* Blackbox: MicroSD card slot
* VCP, UART1, UART2, UART3, UART4, UART5
* Built in inverter for SBUS input (UART2-RX)
* PPM/UART Shared: UART2-RX
* Battery Voltage Sensor
* I2C SDA & SCL: Yes
* LDO: 3.3V Max. 300mA
* Current Sensor: Yes (AIO, CTR), otherwise FCHUB-6S option
* Integrated Power Distribution Board: Yes (AIO, CTR), otherwise FCHUB-6S option
* Integrated Voltage Regulator: 5V 2A & 9V 2A (AIO), 5V 2A (CTR), otherwise FCHUB-6S option
* 6 PWM / DSHOT capable outputs
* WS2812 Led Strip : Yes
* Beeper: Yes
* RSSI: Yes
* Side-press button for BOOT(DFU) mode
* Anti-vibration Standoffs
### I2C
The F405-AIO, STD, CTR boards expose dedicated I2C pads.
The F405-OSD does not expose I2C. For iNav there is a software I2C provision using the USART3 pads, as:
* SDA => RX3, SCL => TX3
* Do not assign any serial function to USART3
### PWM and Servos
Due to the available hardware, please note:
#### Flying Wing
* S1 : ESC
* S2 : LEFT elevon
* S3 : RIGHT elevon
#### Tricopter
* S1 : Tail Servo
* S2 : Motor 1
* S3 : Motor 2
* S4 : Motor 3
If you need servo connected to S6 pin while keeping motors on S1..S4 pins (e.g. camera tilt on quadcopter), please flash MATEKF405_SERVOS6 firmware.
I2C requires that the WS2812 led strip is moved to S5, thus WS2812 is not usable on hexcopter and similar.
### Soft Serial
Soft serial is available as an alternative to a hardware UART on RX4/TX4 and TX2. By default this is NOT inverted. In order to use this feature:
* Enable soft serial
* Do not assign any function to hardware UART4
* Assign the desired function to the soft-serial ports
* UART4 TX/RX pads will be used as SoftSerial 1 TX/RX pads
* UART2 TX pad will be used as SoftSerial 2 TX pad
RX2 and SBUS pads can be used as normal for receiver-only UART. If you need a full duplex UART (IE: TBS Crossfire) and SoftSerial, then use UART 1, 3 or 5 for Full Duplex.
#### Common scenarios for SoftSerial on this boards:
You need to wire a FrSky receiver (SBUS and SmartPort) to the Flight controller
* Connect SBUS from Receiver to SBUS pin on the Flight Controller
* Connect SmartPort from Receiver to TX2 pad on the Flight Controller
* Enable SoftSerial and set UART2 for Serial RX and SoftSerial 2 for SmartPort Telemetry
You need to wire a SmartAudio or Trump VTX to the Flight controller
* Connect SmartAudio/Tramp from VTX to the TX4 pad on the Flight Controller
* Enable SoftSerial and set SoftSerial 1 for SmartAudio or Tramp
### USB
This board uses STM32 VCP and does _not_ use a UART when USB is connected. STM32 VCP drivers might be required on some operating systems.
Flashing requires DFU mode and STM32 DFU drivers. On Linux, the configurator or `dfu-util` work with a `udev` rule.
````
# DFU (Internal bootloader for STM32 MCUs)
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="0664", GROUP="plugdev"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_DEVICE_IGNORE}="1"
````
On Windows, it may be necessary to use the [Zadig](http://zadig.akeo.ie) tool to install the WinUSB driver.
## Manufacturer
Matek Systems: http://www.mateksys.com/
## Distributors
* [Matek F405-CTR](https://inavflight.com/shop/p/MATEKF405CTR)
* [Matek F405-STD](https://inavflight.com/shop/p/MATEKF405STD)
## FAQ & Known Issues
Rcgroups Thread Matek F405: https://www.rcgroups.com/forums/showthread.php?2889298-MATEKSYS-Flight-Controller-F405-OSD-32K-Gyro-5xUARTs-SD-Slot
Rcgroups Thread Matek F405-AIO: https://www.rcgroups.com/forums/showthread.php?2912273-Matek-Flight-Controller-F405-AIO
This board doesn't have hardware inverters for UART pins. This page explains getting SmartPort telemetry working on F4 board: https://github.com/iNavFlight/inav/blob/master/docs/Telemetry.md

92
docs/Board - MatekF722-SE.md

@ -0,0 +1,92 @@
# Board - Matek F722-SE
Full details on the MATEKSYS F722-SE can be found on the Matek Website: [mateksys.com/?portfolio=f722-se](http://www.mateksys.com/?portfolio=f722-se). INAV Target: `MATEKF722SE`
## Hardware Specs
* *Mass:* ~10g
* *PCB Size:* 36x46mm
* 30x30mm Hole pattern (M4 size, M3 size with rubber isolators)
### FC Specs
* Processors and Sensors
* *MCU:* STM32F722RET6
* *IMU:* MPU6000(Gyro1) & ICM20602(Gyro2) connected via SPI1
* *Baro:* BMP280 (connected via I2C1)
* *OSD:* BetaFlight OSD (AT7456E connected via SPI2)
* *Blackbox:* MicroSD card slot (connected via SPI3)
* 5 UARTs
* 8 PWM/Dshot outputs
* 2 PINIO definition (VTX power switcher/user1 and 2 camera switcher/user2)
### Integrated PDB Specs
* *Input:* 6-36v (2-8S LiPo) w/TVS protection
* *ESC Pads:* Rated 4x30A per ESC pad set (4x46A burst)
* Voltage Regulators:
* *5v BEC:* 2A continuous load (3A burst)
* *3.3v LDO:* max load: 200mA
* Power Sense:
* *Current Sensor:* Rated for 184A (*Suggested scale value `179`*)
* *Voltage Sensor:* 1:10 signal output ratio (*Suggested scale value `110`*)
## Status LEDs
| LED | Color | Color Codes |
|---------------:|-------|:----------------------------------------------------------------------------------------------------------|
| FC Status | Blue | **Unlit:** USB disconnected and disarmed, <br> **Lit:** USB disconnected and armed, <br> **Flashing:** USB connected and disarmed, <br> **5x Rapid Flash then Flashing:** USB connected and arming command prevented |
| Accelerometer | Green | Accelerometer status (Lit: active, Unlit: inactive) |
| 3v3 Status | Red | Red: active, Unlit: inactive |
## Pinout
Pads are organised into two large banks of pads on left and right sides of board with a couple sets of pads on the underside of the board and ESC related connections near the board corners.
```
__________
/ U U \
/-----------------------------\
|oE Eo|
|SC SC|
| |
| P P |
| A A |
| D D |
| S S |
| |
|ES ES|
|oC Co|
\------------[USB]------------/
```
| Pad Silkscreen Label | Function | Notes |
|---------------------:|---------------|:-----------------------------------------------------------------------------------------------|
| `+ / -` | Battery In | 6-30vDC LiPo Power input (*Battery +/- and 4-in-1 ESC +/- pads*) |
| `S1-S8` | ESC Out | (*1-4 near ESC power connections, 5-8 on right side*) Supports PWM, Oneshot, Multishot, DSHOT |
| `GND, S1-S4` | ESC Out | (*Rear of board*) 4-in-1 ESC Out |
| `VBT, GND` | VBT Out | VBAT power pad (*marked for VTX*), power ON/OFF can be switched via PINIO1(PC8) |
| `CURR` | Current Sense | Current Sensor I/O pin (*output from onboard sensor or input from external sensor*) |
| `5V` | | Out from internal 5v BEC (*rated 2A continuous, 3A burst*) |
| `3V3` | | Out from 3v3 regulator (*rated 200mA*) |
| `4V5` | | Out from 4v4~4v8, 0.5A (*power is also supplied when connected via USB*) |
| `G` | GND | |
| `LED` | WS2812 Signal | |
| `Bz-, 5V` | Buzzer | |
| `CL, DA` | I2C | I2C connection marked for a magnetometer but could be used for whatever |
| `VTX` | VTX | VTX: Video out |
| `C1/C2` | Camera | C1: camera-1 IN, C1: camera-2 IN, 2 camera image can be switched via PINIO2(PC9) |
| `RX1, TX1` | UART1 | |
| `TX2` | UART2-TX | |
| `RX2` | UART2-RX | RX connection for Spektrum DSMX or DSM2, FlySky iBUS, or PPM (*Disable `UART2` for PPM*) |
| `RX3, TX3` | UART3 | TX3 can be used for VTX control |
| `RX4, TX4` | UART4 | RX4 pin `PA1` can be used for camera control(PWM) |
| `TX6` | UART6-TX | |
| `RX6` | UART6-RX | (*One per board corner*) Duplicates of RX6 pad for ESC Telemetry |
| `Rssi` | RSSI | FrSky RSSI input from RX (*Rear of board*) |
| `PA4 ` | ADC/DAC | Airspeed_ADC_PIN (*Rear of board*) |
| `D+, D-. VBus` | USB pins | (*Rear of board*) |

14
docs/Board - MatekF722.md

@ -0,0 +1,14 @@
# Board - MATEKSYS F722
## Vendor Information / specification
http://www.mateksys.com/?portfolio=f722-std
## Firmware
Two firmware variants are available.
* `inav_x.y.z_MATEKF722.hex`
* `inav_x.y.z_MATEKF722_HEXSERVO.hex`
The only difference is that the `HEXSERVO` variant provides a multi-rotor servo *only* on S7 (vice S6 and S7 in the standard firmware); this facilitates the use of a single servo on a hexcopter.

28
docs/Board - MatekF765-Wing.md

@ -0,0 +1,28 @@
# Board - [MATEKSYS F765-Wing](https://inavflight.com/shop/s/bg/1557661)
![Matek F765 Wing](http://www.mateksys.com/wp-content/uploads/2019/08/F765-WING_2.jpg)
## Specification:
* STM32F765 216MHz CPU
* 2-8S LiPo support
* 132A current sensor
* OSD
* BMP280 barometer
* SD slot
* 7 UART serial ports
* 2 I2C
* PDB for 2 motors
* 12 outputs (10 DSHOT)
* 8A BEC for the servos
* 9V supply for FPV gear
* Dual camera switcher
## Details
* For Matek F765-WING use `MATEKF765` firmware.
* No need for SBUS inversion
## Where to buy:
* [Banggood](https://inavflight.com/shop/s/bg/1557661)

46
docs/Board - NOX.md

@ -0,0 +1,46 @@
# Board - [NOX](https://inavflight.com/shop/p/NOX)
![Airbot]https://youtu.be/j3zIYFYZ_SQ
![Banggood](https://img.staticbg.com/thumb/view/oaupload/banggood/images/A5/01/79d28a2c-ef4b-4e4f-bab6-14edf66bbb23.jpg)
![Banggood]https://img.staticbg.com/images/oaupload/banggood/images/2E/C5/c14a1e86-4e58-4bc8-85de-8e344cb382b9.jpg)
![Banggood]https://img.staticbg.com/images/oaupload/banggood/images/42/F7/45a68ade-9be1-4fff-afec-bbdd45f0331d.jpg)
## Airbot Specification:
* Betaflight OSD
* STM32F411 MCU
* MPU6000 Gyro - It's also replaceable
* Barometer
* 5V BEC with LC filter (500ma)
* 4000uf capacitors onboard - No Need for bulky caps
* 4in1 ESC
* BLHeli32 - The 32-bit architecture that we've come to expect
* DSHOT 1200
* 35A Per motor
* Telemetry Output functionality
* ESC upgradeable
## Banggood Specification:
* Model: F4 Nox4
* Version: Acro Version / Deluxe Version
* Acro Version: Without Barometer and Blackbox
* Deluxe Version: With Barometer and Blackbox
* CPU: STM32F411C
* MPU: MPU6000
* Input Voltage: Support 2-4S Lipo Input
* Built-In Betaflight OSD
* Built-in 5V @ 3A BEC
* 3.3V
* Built-in LC Filter
* DShot, Proshot ESC
* Support Spektrum 1024 /2048 , SBUS, IBUS, PPM
* Size: 27x27mm
* Mounting Hole: 20x20mm , M2.5
* Weight: 3.3g
* DSM / IBUS/SBUS Receiver, choose UART RX2
* PPM Receiver, don't need choose UART Port
## Where to buy:
* [Airbot](https://store.myairbot.com/noxv2.html)
* [Banggood](https:inavflight.com/shop/s/bg/1310419)

202
docs/Board - Omnibus F4.md

@ -0,0 +1,202 @@
# Board - Omnibus F4
![Omnibus F4](https://quadmeup.com/wp-content/uploads/2016/11/Omnibus-F4-Pinout-Top-Full-768x447.jpg)
* For Omnibus F4 Pro (with BMP280 baro, current sensor and SD Card) use **OMNIBUSF4PRO** target (LED strip on dedicated connection)
* For Onnibus F4 Pro clones (Banggood, AliExpress, eBay, etc.) use **OMNIBUSF4PRO_LEDSTRIPM5** target (LED strip on M5 pin)
* For Omnibus F4 Pro Corner use **OMNIBUSF4PRO** target
## Features
* STM32F405 CPU
* Integrated Accelerometer/Gyro MPU6000 or MPU6500 via SPI bus
* 6 motor outputs
* 3 UART ports (UART1, UART3, UART6)
* External I2C bus, pins shared with UART3, cannot be used simultaneously
* Inverter for SBUS
* Blackbox via SDCard or integrated 128mbit flash memory
* BLHeli Passthrough
* Integrated BEC
* Buzzer connector
* Integrated OSD
## Hardware versions
### Omnibus F4 v1 - discontinued
* Linear voltage stabilizer, tends to overheat
* SBUS inverter connected to UART1
* PPM and UART1 can be used together when S.BUS jumper is removed (close to PPM/SBUS connector)
* 128mbit flash memory for Blackbox
* Uses target **OMNIBUSF4**
### Omnibus F4 v3 - discontinued
* Switching voltage regulator - solves problem of overheating BEC
* SD Card slot instead of flash memory
* SBUS inverter connected to UART6
* PPM and UART6 can be used together when S.BUS jumper is removed (close to PPM/SBUS connector)
* Uses target **OMNIBUSF4V3**
More target options:
* OMNIBUSF4V3_S6_SS: Softserial1 on S6
* OMNIBUSF4V3_S5_S6_2SS: Softserial1 on S5 and Softserial2 on S6
* OMNIBUSF4V3_S5S6_SS: Softserial1 on S5/RX and S6/TX
### [Omnibus F4 v4/v5](https://inavflight.com/shop/p/OMNIBUSF4V5)
* Switching voltage regulator - solves problem of overheating BEC
* SD Card slot instead of flash memory
* SBUS inverter connected to UART6
* PPM and UART6 cannot be used together, there is no jumper to disconnect PPM input from UART6 RX
* Uses target **OMNIBUSF4V3**
### [Omnibus F4 Pro](https://inavflight.com/shop/p/OMNIBUSF4PRO)
* Sometimes called Omnibus F4 v2 Pro, but also exists v3, v4 & v5 versions with no functional differences
* Switching voltage regulator - solves problem of overheating BEC
* LC filter for camera and VTX
* SD Card slot instead of flash memory
* SBUS inverter connected to UART1
* PPM and UART1 can be used together when S.BUS jumper is removed (close to PPM/SBUS connector)
* Integrated current meter
* Uses target **OMNIBUSF4PRO**
* Omnibus F4 Pro clones (Banggood, AliExpress, eBay, etc.) use **OMNIBUSF4PRO_LEDSTRIPM5** target (LED strip on M5 pin instead of incorrectly wired dedicated connection)
### Omnibus F4 Pro Corner
* Switching voltage regulator - solves problem of overheating BEC
* LC filter for camera and VTX
* SD Card slot instead of flash memory
* SBUS inverter connected to UART3
* Integrated current meter
* Uses target **OMNIBUSF4PRO**
### Omnibus F4 Nano V6
* Switching voltage regulator - solves problem of overheating BEC
* SPI flash memory for blacbox
* SBUS inverter connected to UART1
* Uses target **FIREWORKSV2**
### Omnibus Corner Nano
* Configurable inverter on UART6
* Use target **OMNIBUSF4V3**
## **NOT** supported
* HC-SR04 Rangefinder
* ServoTilt
## Radio Receivers
SerialRX, PPM and MSP receivers are supported.
SerialRX and PPM receivers should be connected to dedicated _PPM SBUS_ connector above _Motor 1_. MSP receivers should be connected to one of UARTs configured as MSP.
## Motors
| Motor | pin |
| ---- | ---- |
| 1 | PB0 |
| 2 | PB1 |
| 3 | PA3 |
| 4 | PA2 |
| 5 | PA1 |
| 6 | PA8 |
## USB
This board uses STM32 VCP and _not_ utilizes UART when USB is connected. STM32 VCP drivers might be required!
Flashing requires DFU mode and STM32 DFU drivers. Two options for installing the proper driver:
* [Zadig](http://zadig.akeo.ie) tool to install WinUSB driver on Windows.
* [ImpulseRC Driver Fixer](https://impulserc.com/pages/downloads) installs the STM32 DFU driver with a single click.
## Buzzer / Beeper
5V piezo buzzer should be connected directly to dedicated pins _BUZ +_ and _BUZ -_. No additional hardware is required.
## RSSI ADC
* Connected to pin PA0
* 3.3V tolerant, do not supply 5V
## Current Meter ADC
* Connected to pin PC1
* 3.3V tolerant, do not supply 5V
## Voltage monitoring
* Connected to pin PC2
* Connected to VBAT pins (both are the same) and integrated Voltage Stabilizer (LM7805M)
## Integrated voltage stabilizer (Omnibus F4 v1 only)
It is integrated with voltage monitoring and always powered when VBAT is connected to battery.
Because this is a **Linear Stabilizer**, it has a tendency to overheat, especially on 4S. Because of that,
avoid powering too many devices directly to 5V pins on the board. RX receiver (and board itself) is rather all
it can do without overeating (150mA on 4S gives 1.5W of waste heat!). OSD, LED Strip and other devices should powered from separate BEC if voltage monitoring is to be enabled.
## LED Strip
LED strip is enabled as indicated on flight controller silkscreen or schematics.
For INAV versions before v1.8.0, LED strip was shared with Motor 5 pin (PA1).
For Omnibus F4 Pro clones (Banggood, AliExpress, eBay, etc.) use **OMNIBUSF4PRO_LEDSTRIPM5** target for LED strip on M5 pin as the dedicated LED strip connection on these devices is typically wired incorrectly.
## SoftwareSerial
### Omnibus F4 v1/v2 SoftwareSerial Connections
This board allows for single **SoftwareSerial** port on small soldering pads located on the bottom side of the board.
Please note that this is *not* the motor PWM5/PWM6 pins, but small surface mount pads CH5/CH6.
### Omnibus F4 Pro SoftwareSerial Connections
![Omnibus F4 Pro SoftwareSerial Connections](assets/images/omnibusf4pro_ss.jpg)
| Pad | SoftwareSerial Role |
| ---- | ---- |
| CH5 | RX |
| CH6 | TX |
![Omnibus F4 Pro SmartPort using SoftwareSerial](assets/images/omnibusf4pro_ss.png)
### Omnibus F4 v3/v4/v5 SoftwareSerial Connections
The SOFTSERIAL1 is an uni-directional port mapped to UART6-TX pin.
When enabled, the UART6 is still available as hardware port but it's then RX-only port (good for e.g. receiving S.BUS input). TX instead is controlled in software and can be used for transmitting one-way telemetry (e.g. LTM). Please note that UART6-TX line passes programmable inverter on those boards, so it is a pure output-only port. SmartPort/FPort telemetry requires bi-directional communication, so it is not possible on this port without hardware modification (bypassing the inverter).
## Where to buy:
* [Omnibus F4 v5](https://inavflight.com/shop/p/OMNIBUSF4V5)
* [Omnibus F4 Pro](https://inavflight.com/shop/p/OMNIBUSF4PRO)
* [Omnibus F4 Nano V6](https://inavflight.com/shop/s/bg/1320256)
# Wiring diagrams for Omnibus F4 Pro
Following diagrams applies to _Pro_ version with integrated current meter and JST connectors only
## Board layout
![Omnibus F4 Pro Board Layout](assets/images/omnibusf4pro.png)
## Flying wing motor and servos
![Omnibus F4 Pro Flying Wing Setup](assets/images/omnibusf4pro_flyingwing_setup.png)
## RX setup
![Omnibus F4 Pro RX Setup](assets/images/omnibusf4pro_rx.png)
## FPV setup
![Omnibus F4 Pro FPV Setup](assets/images/omnibusf4pro_fpv_setup.png)
## GPS setup
![Omnibus F4 Pro GPS Setup](assets/images/omnibusf4pro_gps_setup.png)
_Diagrams created by Albert Kravcov (skaman82)_

43
docs/Board - Omnibus F7.md

@ -0,0 +1,43 @@
# Board - Omnibus F7
![Omnibus F7](https://quadmeup.com/wp-content/uploads/2017/07/Omnibus-F7-flight-controller-top-view.jpg)
## Features
* STM32F745 CPU
* Integrated Accelerometer/Gyro MPU6000 and MPU6500 via SPI bus. INAV uses only MPU6000
* 4 motor outputs
* 4 UART ports (UART1, UART2 (RX only), UART3, UART6)
* External I2C bus, pins shared with UART3, can not be used simultaneously
* BLHeli Passthrough
* Integrated BEC
* Buzzer connector
* Integrated OSD
## Known issues
* LED Strips are not working
## Radio Receivers
SerialRX, PPM and MSP receivers are supported.
SerialRX and PPM receivers should be connected to dedicated _PPM SBUS_ connector. For SerialRX use UART2
## Motors
This board has only 4 motor/servo outputs. Can be used in airplanes only on Flywing Wings
## Buzzer / Beeper
5V piezo buzzer should be connected directly to dedicated pins _BUZ +_ and _BUZ -_. No additional hardware is required.
## RSSI ADC
* Connected to pin PA0
* 3.3V tolerant, do not supply 5V
## Current Meter ADC
* Connected to pin PC1
* 3.3V tolerant, do not supply 5V

94
docs/Board - PixRacer R14.md

@ -0,0 +1,94 @@
# Board - PixRacer
PinOut diagrams are only for reference. See Ports and interfaces for true locations and mappings.
## Top View PinOut
![PixRacer](https://pixhawk.org/_media/modules/pixracer_r09_top_pinouts.png?cache=)
## Bottom View PinOut
![PixRacer](https://pixhawk.org/_media/modules/pixracer_r09_bot_pinouts.png?cache=&w=900&h=660&tok=a821d6)
Schematic : https://pixhawk.org/_media/modules/pixracer-r14.pdf
## How to Flash
PixRacer comes with NuttX Bootloader installed.
To flash inav follow the steps below
* Short 3.3 V pad and GND pad located at Top(near Motor Pins)
* Plug in via USB
* Either use ziadag to get the correct the drivers for inav based firmware flashing or use Dfuse to flash the correct firmware.
If you want to revert back then PixRacer factory Loaded Bootloader Bin File for Dfuse : https://github.com/mkschreder/ardupilot/tree/master/mk/PX4/bootloader (download px4fmu4_bl.bin) or Build your own from :https://github.com/PX4/Bootloader
Then follow this : https://pixhawk.org/dev/bootloader_update
## Features
### Processor and Sensors
* 32-bit STM32F427 Cortex M4 core with FPU rev. 3 168 MHz/256 KB RAM/2 MB Flash
* ICM-20608-G 3-axis accelerometer/gyroscope
* MPU-9250 3-axis accelerometer/gyroscope/magnetometer
* MEAS MS5611 barometer
* Honeywell HMC5983 magnetometer temperature compensated
### Interface and Ports
Total UARTS Recognized by iNav -> 8
#### USART1
* Location : Top
* Use: ESP8266 for Wifi OTA updates in Arducopter and PX4 AutoPilot
* See Top View to find TX & RX
* Only 3.3 volt peripherals will work unless your provide your own 5V BEC
#### USART2
* Location : Top
* Use :Free Port
* Runcam Device/Smart Audio and any other UART Peripheral should be supported
#### USART3
* Location : Top
* Use :Free port
* Runcam Device/Smart Audio and any other UART Peripheral should be supported
#### USART 4
* Location :
* Use : I2C/GPS Port (WIP if you want to just use I2C)
* Recommended to actually leave this port as is and not modify wires
* GPS devices/ magnetometer and other I2C devices should be connected to this port
* Till I2C is made available use as Free UART
#### USART 5
* Location : Top?
* Use :CAN Bus?
* Recommendation :CAN ESC?
#### USART 6
* Location : Top
* Use : RC IN
* Has RSS IN and and supports only PPM
* RSS IN board is connected to PC1 pin of the F4 controller
* RC input has been separated
* PPM RC input is on PB0
* Serial RC input is on PC7
#### UART 7
* Location : Bottom
* Use :JTAG connector for debugging and bootloader/firmware flash
* Unless you really know what you are doing leave this port alone
* If you _really_ need another UART be aware, this port is limited to 3.3 volt
#### USART 8
* Location : Top
* Use : Native FrSky port
* Recommendation : Use for native FrSky telemetry
## Buzzer
You can connect the buzzer provide from factory to the default buzzer port
### WIP
* SD card (SDIO Bus)(Pins used are PC8, PC9, PC10, P11, PC12, PD 2)
* Voltage Sensing (Connected to PA2)
* Current Sensing (Connected to PA3)
* HMC5983 compass (DRDY : PE12 , CS : PE15) (SPI bus pins : SCK on PB10 , MISO on PB14, MOSI on PB15) shares SPI bus with FRAM
* FM25V02-G FRAM memory support (SPI bus pins : SCK on PB10 , MISO on PB14, MOSI on PB15)
* I2C support (SCL on PB8 ,SDA on PB9)

132
docs/Board - Revolution.md

@ -0,0 +1,132 @@
# Board - OpenPilot Revolution also known as CC3D Revo
## Features
* STM32F405 CPU
* Integrated Accelerometer/Gyro MPU6000 via SPI bus
* Integrated Magnetometer HMC5883
* Integrated Barometer MS5611
* Integrated 433MHz OPlink Modem -> Not supported
* 6 motor outputs
* 3 UART ports (UART1, UART3, UART6)
* External I2C bus, pins shared with UART3, can not be used simultaneously
* Only UART1 is equipped with inverter
* Onboard 128Mbit (16MB) flash
* BLHeli Passthrough
## **NOT** supported
* HC-SR04 Rangefinder
* SoftwareSerial
* ServoTilt
## USB
This board uses STM32 VCP and _not_ utilizes UART when USB is connected. STM32 VCP drivers might be required!
Flashing requires DFU mode and STM32 DFU drivers. Use [Zadig](http://zadig.akeo.ie) tool to install WinUSB driver on Windows.
## Pinout
Following section is ported from [RaceFlight](https://github.com/rs2k/raceflight/blob/master/docs/Board%20-%20Revo.md) with edits
### RC_Input connector
#### RX_PPM and RX_SERIAL
| Pin | Function | Notes |
| --- | --------- | -------------------------------- |
| 1 | Ground | |
| 2 | +5V | |
| 3 | | |
| 4 | | |
| 5 | PPM Input | Enable `feature RX_PPM` |
| 6 | | |
| 7 | UART6 TX | |
| 8 | UART6 RX | |
| 9 | | |
| 10 | | |
#### RX_PARALLEL_PWM
| Pin | Function | Notes |
| --- | ---------| ------|
| 1 | Ground | |
| 2 | +5V | |
| 3 | Unused | |
| 4 | Unused | |
| 5 | CH1 | |
| 6 | CH2 | |
| 7 | CH3 | |
| 8 | CH4 | |
| 9 | CH5 | |
| 10 | CH6 | |
### RC_Output connector
#### RX_PPM and RX_SERIAL
| Pin | Pin | Function | Notes |
| --- | ---- |---------- | ------|
| 1 | PB0 | MOTOR 1 | |
| 2 | PB1 | MOTOR 2 | |
| 3 | PA3 | MOTOR 3 | |
| 4 | PA2 | MOTOR 4 | |
| 5 | PA1 | MOTOR 5 / LED Strip | |
| 6 | PA0 | MOTOR 6 / RSSI_ADC | |
## Serial Ports
| Value | Identifier | Board Markings | Notes |
| ----- | ------------ | -------------- | ------------------------------------------|
| 1 | VCP | USB PORT | |
| 2 | UART1 | MAIN PORT | Connected to an MCU controllable inverter |
| 3 | UART3 | FLEX PORT | |
| 4 | UART6 | RC connector | |
The UART6 port is not available when RX_PARALLEL_PWM is used.
### Main Port
The main port is connected to an inverter which is automatically enabled as required. For example, if the main port is used for SBus Serial RX then an external inverter is not required.
| Pin | Signal | Notes |
| --- | ------------------ | ----------------------- |
| 1 | GND | |
| 2 | VCC unregulated | |
| 3 | UART1 TX | 3.3v level |
| 4 | UART1 RX | 3.3v level (5v tolerant)|
### Flex Port
The flex port will be enabled in I2C mode unless UART3 is used. You can connect external I2C sensors and displays to this port.
You cannot use USART3 and I2C at the same time.
| Pin | Signal | Notes |
| --- | ------------------ | ----------------------- |
| 1 | GND | |
| 2 | VCC unregulated | |
| 3 | I2C SCL / UART3 TX | 3.3v level |
| 4 | I2C SDA / UART3 RX | 3.3v level (5v tolerant) |
### Pwr sensor connector
| Pin | Signal | Notes |
| --- | ------------------ | ----------------------- |
| 1 | GND | |
| 2 | VCC unregulated | |
| 3 | Current sensor | 3.3v max input |
| 4 | Voltage sensor | 3.3v max input |
## Buzzer
External buzzer should be wired to PB4 CPU pin using a transistor circuit
## Notes
* At this moment LED Strip is not functional on this target
* Motor out put 5 and 6 needs testing
* Servo output might not be working at the moment of writing this documentation
* I2C might not be working at the moment of writing this documentation
* LED Strip might not be working at the moment of writing this documentation

12
docs/Board - WingFC.md

@ -0,0 +1,12 @@
# Board - Wing FC
This FC can be bought here: https://inavflight.com/shop/s/bg/1318626
This board use the STM32F405RGT6 microcontroller and have the following features:
* 1024K bytes of flash memory,192K bytes RAM,168 MHz CPU/210 DMIPS
* The 16M byte SPI flash for data logging
* USB VCP and boot select button on board(for DFU)
* Current sensor
* Supports I2C device (shared with UART1)
* PPM input (UART3 RX)

38
docs/Board - YuPiF4.md

@ -0,0 +1,38 @@
# YuPiF4 by RcNet
An high quality flight controller for the most demanding pilotes.
## Description
The YuPiF4 is a 36x36mm (30.5x30.5 mounting holes) board with an F4 microcontroller.
## MCU, Sensors and Features
### Hardware 
- MCU: STM32F405RTG6 
- IMU: not yet defined 
- IMU Interrupt: Yes 
- BARO: No 
- VCP: Yes 
- Hardware UARTS: 3 with an inverter for SBus and a Smart-Port Pad to solder directly your SPort wire 
- Blackbox: SD card slot 
- PPM : A specific pad is available for PPM input 
- Battery Voltage Sensor: Yes, directly connected, no wiring necessary 
- Integrated Voltage Regulator: the board can be powered by your lipo (2S to 6S) 
- Brushed Motor Mosfets: No 
- Motor outputs : can drive up to 6 motors 
- Buttons: Boot0 to enter in DFU mode### Features 
- Current Sensor: Not implemented 
- BlHeli passthrough: Yes  
- WS2811 Led Strip: Yes (on motor output Pin 5) 
- Transponder: No
### Extension Board
- An extension board with a GPS and a Baro will be available
## Designers and Maintainers
[RcNet](https://github.com/ted-rcnet) and [FaduF](https://github.com/Faduf)
## Manufacturers and Distributors
This board is currently in the prototype phase. Only small batches were manufactured for testing.Website : http://www.yupif4.com/

49
docs/Boards.md

@ -0,0 +1,49 @@
# Flight controller hardware
### Sponsored and recommended boards
These boards come from companies that support INAV development. Buying one of these boards you make your small contribution for improving INAV as well.
Also these boards are tested by INAV development team and usually flown on daily basis.
| Board name | CPU Family | Target name(s) | GPS | Compass | Barometer | Telemetry | RX | Blackbox |
|---------------------------|:----------:|:-------------------------:|:----:|:-------:|:--------------:|:---------:|:------------------------------:|:--------------------:|
| [Airbot OMNIBUS F4 PRO](https://inavflight.com/shop/p/OMNIBUSF4PRO)| F4 | OMNIBUSF4PRO | All | All | All | All | All | SERIAL, SD |
| [Airbot OMNIBUS F4](https://inavflight.com/shop/s/bg/1319176)| F4 | OMNIBUSF4 | All | All | All | All | All | SERIAL, SD |
Note: In the above and following tables, the sensor columns indicates firmware support for the sensor category; it does not necessarily mean there is an on-board sensor.
### Recommended boards
These boards are well tested with INAV and are known to be of good quality and reliability.
| Board name | CPU Family | Target name(s) | GPS | Compass | Barometer | Telemetry | RX | Blackbox |
|---------------------------|:----------:|:-------------------------:|:----:|:-------:|:--------------:|:---------:|:------------------------------:|:--------------------:|
| [Matek F405-CTR](https://inavflight.com/shop/p/MATEKF405CTR) | F4 | MATEKF405 | All | All | All | All | All | SERIAL, SD |
| [Matek F405-STD](https://inavflight.com/shop/p/MATEKF405STD) | F4 | MATEKF405 | All | All | All | All | All | SERIAL, SD |
| [Matek F405-WING](https://inavflight.com/shop/p/MATEKF405WING) | F4 | MATEKF405SE | All | All | All | All | All | SERIAL, SD |
| [Matek F722 WING](https://inavflight.com/shop/p/MATEKF722WING) | F7 | MATEKF722SE | All | All | All | All | All | SERIAL, SD |
| [Matek F722-SE](https://inavflight.com/shop/p/MATEKF722SE) | F7 | MATEKF722SE | All | All | All | All | All | SERIAL, SD |
| [Matek F722-STD](https://inavflight.com/shop/p/MATEKF722STD) | F7 | MATEKF722 | All | All | All | All | All | SERIAL, SD |
| [Matek F722-MINI](https://inavflight.com/shop/p/MATEKF722MINI) | F7 | MATEKF722SE | All | All | All | All | All | SPIFLASH |
It's possible to find more supported and tested boards [here](https://github.com/iNavFlight/inav/wiki/Welcome-to-INAV,-useful-links-and-products)
### Boards documentation
See the [docs](https://github.com/iNavFlight/inav/tree/master/docs) folder for additional information regards to many targets in INAV, to example help in finding pinout and features. _Feel free to help improve the docs._
### Boards based on F4/F7 CPUs
These boards are powerful and in general support everything INAV is capable of. Limitations are quite rare and are usually caused by hardware design issues.
### Boards based on F3 CPUs
Boards based on F3 boards will be supported for as long as practical, sometimes with reduced features due to lack of resources. No new features will be added so F3 boards are not recommended for new builds.
### Boards based on F1 CPUs
Boards based on STM32F1 CPUs are no longer supported by latest INAV version. Last release is 1.7.3
### Not recommended for new setups
F1 and F3 boards are no longer recommended. Users should choose a board from the supported F4 or F7 devices available in the latest release.

99
docs/Buzzer.md

@ -0,0 +1,99 @@
# Buzzer
INAV supports a buzzer which is used for the following purposes:
* Low and critical battery alarms (when battery monitoring enabled)
* Arm/disarm tones (and warning beeps while armed)
* Notification of calibration complete status
* TX-AUX operated beeping - useful for locating your aircraft after a crash
* Failsafe status
* Flight mode change
* Rate profile change (via TX-AUX switch)
If the arm/disarm is via the control stick, holding the stick in the disarm position will sound a repeating tone. This can be used as a lost-model locator.
Three beeps immediately after powering the board means that the gyroscope calibration has completed successfully. INAV calibrates the gyro automatically upon every power-up. It is important that the copter stay still on the ground until the three beeps sound, so that gyro calibration isn't thrown off. If you move the copter significantly during calibration, INAV will detect this, and will automatically re-start the calibration once the copter is still again. This will delay the "three beeps" tone. If you move the copter just a little bit, the gyro calibration may be incorrect, and the copter may not fly correctly. In this case, the gyro calibration can be performed manually via [stick command](Controls.md), or you may simply power cycle the board.
There is a special arming tone used if a GPS fix has been attained, and there's a "ready" tone sounded after a GPS fix has been attained (only happens once). The tone sounded via the TX-AUX-switch will count out the number of satellites (if GPS fix).
The CLI command `play_sound` is useful for demonstrating the buzzer tones. Repeatedly entering the command will play the various tones in turn. Entering the command with a numeric-index parameter (see below) will play the associated tone.
Buzzer is enabled by default on platforms that have buzzer connections.
## Tone sequences
Buzzer tone sequences (square wave generation) are made so that : 1st, 3rd, 5th, .. are the delays how long the beeper is on and 2nd, 4th, 6th, .. are the delays how long beeper is off. Delays are in milliseconds/10 (i.e., 5 => 50ms).
Sequences:
0 GYRO_CALIBRATED 20, 10, 20, 10, 20, 10 Gyro is calibrated
1 RX_LOST_LANDING 10, 10, 10, 10, 10, 40, 40, 10, 40, 10, 40, 40, 10, 10, 10, 10, 10, 70 SOS morse code
2 RX_LOST 50, 50 TX off or signal lost (repeats until TX is okay)
3 DISARMING 15, 5, 15, 5 Disarming the board
4 ARMING 30, 5, 5, 5 Arming the board
5 ARMING_GPS_FIX 5, 5, 15, 5, 5, 5, 15, 30 Arming and GPS has fix
6 BAT_CRIT_LOW 50, 2 Battery is critically low (repeats)
7 BAT_LOW 25, 50 Battery is getting low (repeats)
8 NULL multi beeps GPS status (sat count)
9 RX_SET 10, 10 RX is set (when aux channel is set for beep or beep sequence how many satellites has found if GPS enabled)
10 ACC_CALIBRATION 5, 5, 5, 5 ACC inflight calibration completed
11 ACC_CALIBRATION_FAIL 20, 15, 35, 5 ACC inflight calibration failed
12 READY_BEEP 4, 5, 4, 5, 8, 5, 15, 5, 8, 5, 4, 5, 4, 5 GPS locked and copter ready
13 NULL multi beeps Variable # of beeps (confirmation, GPS sat count, etc)
14 DISARM_REPEAT 0, 100, 10 Stick held in disarm position (after pause)
15 ARMED 0, 245, 10, 5 Board is armed (after pause ; repeats until board is disarmed or throttle is increased)
You can use [this tool](https://www.mrd-rc.com/tutorials-tools-and-testing/useful-tools/helpful-inav-buzzer-code-checker/) to hear current buzzer sequences or enter custom sequences.
## Controlling buzzer usage
The usage of the buzzer can be controlled by the CLI `beeper` command.
### List current usage
```
beeper
```
### List all buzzer setting options
```
beeper list
```
giving:
```
Available: RUNTIME_CALIBRATION HW_FAILURE RX_LOST RX_LOST_LANDING DISARMING ARMING ARMING_GPS_FIX BAT_CRIT_LOW BAT_LOW GPS_STATUS RX_SET ACTION_SUCCESS ACTION_FAIL READY_BEEP MULTI_BEEPS DISARM_REPEAT ARMED SYSTEM_INIT ON_USB LAUNCH_MODE CAM_CONNECTION_OPEN CAM_CONNECTION_CLOSED ALL PREFERED
```
The `beeper` command syntax follows that of the `feature` command; a minus (`-`) in front of a name disables that function.
So to disable the beeper / buzzer when connected to USB (may enhance domestic harmony)
```
beeper -ON_USB
```
Now the `beeper` command will show:
```
# beeper
Disabled: ON_USB
```
As with other CLI commands, the `save` command is needed to save the new settings.
## Types of buzzer supported
The buzzers are enabled/disabled by simply enabling or disabling a GPIO output pin on the board.
This means the buzzer must be able to generate its own tone simply by having power applied to it.
Buzzers that need an analog or PWM signal do not work and will make clicking noises or no sound at all.
Examples of a known-working buzzers.
* [Hcm1205x Miniature Buzzer 5v](http://www.rapidonline.com/Audio-Visual/Hcm1205x-Miniature-Buzzer-5v-35-0055)
* [5V Electromagnetic Active Buzzer Continuous Beep](https://inavflight.com/shop/s/bg/943524)
* [Radio Shack Model: 273-074 PC-BOARD 12VDC (3-16v) 70DB PIEZO BUZZER](http://www.radioshack.com/pc-board-12vdc-70db-piezo-buzzer/2730074.html#.VIAtpzHF_Si)
* [MultiComp MCKPX-G1205A-3700 TRANSDUCER, THRU-HOLE, 4V, 30MA](http://uk.farnell.com/multicomp/mckpx-g1205a-3700/transducer-thru-hole-4v-30ma/dp/2135914?CMP=i-bf9f-00001000)
* [3-24V Piezo Electronic Tone Buzzer Alarm 95DB](https://inavflight.com/shop/s/bg/919348)

15
docs/Channel forwarding.md

@ -0,0 +1,15 @@
# Channel forwarding
Starting from INAV 2.0, _channel forwarding_ feature is removed. Channel forwarding functionality can be configured using _Mixer Configurator Tab_ instead.
Channel forwarding using mixer works for all flight controllers that supports servos in either multirotor or airplane configuration. Bear in mind, that some boards might not have any servo outputs in multirotor configuration. In this case, channel forwarding will just not work. Refer to the board documentation to find out if servos are available in multirotor configuration.
## How to setup channel forwarding
![Mixer GUI](assets/images/mixer_forwarding.png)
1. Open Mixer tab
1. Add new _servo rule_ for given servo index
1. Choose source as one of _RC Roll_, _RC Pitch_, _RC Yaw_, _RC Throttle_ or _RC Channel 5_ to _RC Channel 16_
1. When required, servo direction can be modified by applying negative weight
1. It is possible to limit servo speed. Refer to [Mixer documentation](Mixer.md)

150
docs/Cli.md

@ -0,0 +1,150 @@
# Command Line Interface (CLI)
INAV has a command line interface (CLI) that can be used to change settings and configure the FC.
## Accessing the CLI.
The CLI can be accessed via the GUI tool or via a terminal emulator connected to the CLI serial port.
1. Connect your terminal emulator to the CLI serial port (which, by default, is the same as the MSP serial port)
2. Use the baudrate specified by msp_baudrate (115200 by default).
3. Send a `#` character.
To save your settings type in 'save', saving will reboot the flight controller.
To exit the CLI without saving power off the flight controller or type in 'exit'.
To see a list of other commands type in 'help' and press return.
To dump your configuration (including the current profile), use the 'dump' or 'diff' command.
See the other documentation sections for details of the cli commands and settings that are available.
## Backup via CLI
Disconnect main power, connect to cli via USB/FTDI.
dump using cli
```
profile 0
dump
```
dump profiles using cli if you use them
```
profile 1
dump profile
profile 2
dump profile
```
copy screen output to a file and save it.
Alternatively, use the `diff` command to dump only those settings that differ from their default values (those that have been changed).
## Restore via CLI.
Use the cli `defaults` command first.
When restoring from backup it's a good idea to do a dump of the latest defaults so you know what has changed - if you do this each time a firmware release is created you will be able to see the cli changes between firmware versions. If you blindly restore your backup you would not benefit from these new defaults or may even end up with completely wrong settings in case some parameters changed semantics and/or value ranges.
It may be good idea to restore settings using the `diff` output rather than complete `dump`. This way you can have more control on what is restored and the risk of mistakenly restoring bad values if the semantics changes is minimised.
To perform the restore simply paste the saved commands in the Configurator CLI tab and then type `save`.
After restoring it's always a good idea to `dump` or `diff` the settings once again and compare the output with previous one to verify if everything is set as it should be.
## CLI Command Reference
| `Command` | Description |
|------------------|------------------------------------------------|
| `1wire <esc>` | passthrough 1wire to the specified esc |
| `adjrange` | show/set adjustment ranges settings |
| `aux` | show/set aux settings |
| `beeper` | show/set beeper (buzzer) [usage](Buzzer.md) |
| `bind_rx` | Initiate binding for RX_SPI or SRXL2 receivers |
| `mmix` | design custom motor mixer |
| `smix` | design custom servo mixer |
| `color` | configure colors |
| `defaults` | reset to defaults and reboot |
| `dump` | print configurable settings in a pastable form |
| `diff` | print only settings that have been modified |
| `exit` | |
| `feature` | list or -val or val |
| `get` | get variable value |
| `gpspassthrough` | passthrough gps to serial |
| `help` | |
| `led` | configure leds |
| `map` | mapping of rc channel order |
| `motor` | get/set motor output value |
| `msc` | Enter USB Mass storage mode. See [USB MSC documentation](USB_Mass_Storage_(MSC)_mode.md) for usage information.|
| `play_sound` | index, or none for next |
| `profile` | index (0 to 2) |
| `rxrange` | configure rx channel ranges (end-points) |
| `safehome` | Define safe home locations. See the [safehome documentation](Safehomes.md) for usage information. |
| `save` | save and reboot |
| `serial` | Configure serial ports |
| `serialpassthrough <id> <baud> <mode>`| where `id` is the zero based port index, `baud` is a standard baud rate, and mode is `rx`, `tx`, or both (`rxtx`) |
| `set` | name=value or blank or * for list |
| `status` | show system status |
| `temp_sensor` | list or configure temperature sensor(s). See [temperature sensors documentation](Temperature sensors.md) for more information. |
| `wp` | list or configure waypoints. See more in the [navigation documentation](Navigation.md#cli-command-wp-to-manage-waypoints). |
| `version` | Displays version information, |
### serial
The syntax of the `serial` command is `serial <id> <function_value> <msp-baudrate> <gps-baudrate> <telemetry-baudate> <peripheral-baudrate>`.
A shorter form is also supported to enable and disable a single function using `serial <id> +n` and `serial <id> -n`, where n is the a serial function identifier. The following values are available:
| Function | Bit Identifier | Numeric value |
|-----------------------|---------------|----------------|
| MSP | 0 | 1 |
| GPS | 1 | 2 |
| TELEMETRY_FRSKY | 2 | 4 |
| TELEMETRY_HOTT | 3 | 8 |
| TELEMETRY_LTM | 4 | 16 |
| TELEMETRY_SMARTPORT | 5 | 32 |
| RX_SERIAL | 6 | 64 |
| BLACKBOX | 7 | 128 |
| TELEMETRY_MAVLINK | 8 | 256 |
| TELEMETRY_IBUS | 9 | 512 |
| RCDEVICE | 10 | 1024 |
| VTX_SMARTAUDIO | 11 | 2048 |
| VTX_TRAMP | 12 | 4096 |
| UAV_INTERCONNECT | 13 | 8192 |
| OPTICAL_FLOW | 14 | 16384 |
| LOG | 15 | 32768 |
| RANGEFINDER | 16 | 65536 |
| VTX_FFPV | 17 | 131072 |
Thus, to enable MSP and LTM on a port, one would use the function **value** of 17 (1 << 0)+(1<<4), aka 1+16, aka 17.
```
serial 0 17 57600 57600 57600 57600
```
but to remove LTM using the +/- shorthand, use the **bit Id** (4, TELEMETRY_LTM):
```
serial 0 -4
```
`serial` can also be used without any argument to print the current configuration of all the serial ports.
## Flash chip management
For targets that have a flash data chip, typically used for blackbox logs, the following additional comamnds are provided.
| Command | Effect |
| ------- | ------ |
| `flash_erase` | Erases the flash chip |
| `flash_info` | Displays flash chip information (used, free etc.) |
| `flash_read <length> <address>` | Reads `length` bytes from `address` |
| `flash_write <address> <data>` | Writes `data` to `address` |
## CLI Variable Reference
See [Settings.md](Settings.md).

35
docs/Configuration.md

@ -0,0 +1,35 @@
# Configuration
INAV is configured primarily using the INAV Configurator GUI.
Both the command line interface and GUI are accessible by connecting to a serial port on the target,
be it a USB virtual serial port, physical hardware UART port or a SoftSerial port.
See the Serial section for more information and see the Board specific sections for details of the serial ports available on the board you are using.
The GUI cannot currently configure all aspects of the system, the CLI must be used to enable or configure
some features and settings.
__Due to ongoing development, the fact that the GUI cannot yet backup all your settings and automatic chrome updates of the GUI app it is highly advisable to backup your settings (using the CLI) so that when a new version of the configurator or firmware is released you can re-apply your settings.__
## GUI
![INAV Gui](Screenshots/cleanflight-gui.png)
The GUI tool is the preferred way of configuration. The GUI tool also includes a terminal which
can be used to interact with the CLI.
[INAV Configurator on Chrome store](https://chrome.google.com/webstore/detail/inav-configurator/fmaidjmgkdkpafmbnmigkpdnpdhopgel)
If you cannot use the latest version of the GUI to access the FC due to firmware compatibility issues you can still access the FC via the CLI to backup your settings, or you can install an old version of the configurator.
Old versions of the configurator can be downloaded from the configurator releases page: https://github.com/iNavFlight/inav-configurator/releases
See the README file that comes with the configurator for installation instructions.
## CLI
INAV can also be configured by a command line interface.
See the CLI section of the documentation for more details.

97
docs/Controls.md

@ -0,0 +1,97 @@
# Controls
## Arming
When armed, the aircraft is ready to fly and the motors will spin when throttle is applied. With multirotors, the motors will spin at a slow speed when armed (this feature may be disabled by setting MOTOR_STOP, but for safety reasons, that is not recommended).
Arming and disarming is done using a switch, set up on the modes page. (NOTE: Stick arming was removed in iNav 2.2)
## Stick Positions
The three stick positions are:
|Position | Approx. Channel Input|
|----------------|----------------------|
|LOW | 1000 |
|CENTER | 1500 |
|HIGH | 2000 |
The stick positions are combined to activate different functions:
| Function | Throttle | Yaw | Pitch | Roll |
| ----------------------------- | -------- | ------- | ------ | ------ |
| Profile 1 | LOW | LOW | CENTER | LOW |
| Profile 2 | LOW | LOW | HIGH | CENTER |
| Profile 3 | LOW | LOW | CENTER | HIGH |
| Battery profile 1 | HIGH | LOW | CENTER | LOW |
| Battery profile 2 | HIGH | LOW | HIGH | CENTER |
| Battery profile 3 | HIGH | LOW | CENTER | HIGH |
| Calibrate Gyro | LOW | LOW | LOW | CENTER |
| Calibrate Acc | HIGH | LOW | LOW | CENTER |
| Calibrate Mag/Compass | HIGH | HIGH | LOW | CENTER |
| Trim Acc Left | HIGH | CENTER | CENTER | LOW |
| Trim Acc Right | HIGH | CENTER | CENTER | HIGH |
| Trim Acc Forwards | HIGH | CENTER | HIGH | CENTER |
| Trim Acc Backwards | HIGH | CENTER | LOW | CENTER |
| Save current waypoint mission | LOW | CENTER | HIGH | LOW |
| Load current waypoint mission | LOW | CENTER | HIGH | HIGH |
| Unload waypoint mission | LOW | CENTER | LOW | HIGH |
| Save setting | LOW | LOW | LOW | HIGH |
| Enter OSD Menu (CMS) | CENTER | LOW | HIGH | CENTER |
![Stick Positions](assets/images/StickPositions.png)
## Yaw control
While arming/disarming with sticks, your yaw stick will be moving to extreme values. In order to prevent your craft from trying to yaw during arming/disarming while on the ground, your yaw input will not cause the craft to yaw when the throttle is LOW (i.e. below the `min_check` setting).
For tricopters, you may want to retain the ability to yaw while on the ground, so that you can verify that your tail servo is working correctly before takeoff. You can do this by setting `tri_unarmed_servo` to `1` on the CLI (this is the default). If you are having issues with your tail rotor contacting the ground during arm/disarm, you can set this to `0` instead. Check this table to decide which setting will suit you:
<table>
<tr>
<th colspan="5">Is yaw control of the tricopter allowed?</th>
</tr>
<tr>
<th></th><th colspan="2">Disarmed</th><th colspan="2">Armed</th>
</tr>
<tr>
<th></th><th>Throttle low</th><th>Throttle normal</th><th>Throttle low</th><th>Throttle normal</th>
</tr>
<tr>
<td rowspan="2">tri_unarmed_servo = 0</td><td>No</td><td>No</td><td>No</td><td>Yes</td>
</tr>
<tr>
<td>No</td><td>No</td><td>No</td><td>Yes</td>
</tr>
<tr>
<td rowspan="2">tri_unarmed_servo = 1</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td>
</tr>
<tr>
<td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td>
</tr>
</table>
## Throttle settings and their interaction
*Terminology. After iNav 2.3, the setting `min_throttle` was replaced with `throttle_idle` which is more appropriate to modern hardware. In this document `min_throttle` may be taken as either the older `min_throttle` value, or the throttle value calculated from the modern `throttle_idle` setting. The way that `throttle_idle` generates a throttle value is described in `Cli.md`.*
`min_command` -
With motor stop enabled this is the command sent to the esc's when the throttle is below min_check or disarmed. With motor stop disabled, this is the command sent only when the copter is disarmed. This must be set well below motors spinning for safety.
`min_check` -
With switch arming mode is in use, lowering your throttle below min_check will result in motors spinning at `throttle_idle` (min_throttle). When using the default stick arming, lowering your throttle below min_check will result in motors spinning at min_throttle and yaw being disabled so that you may arm/disarm. With motor stop enabled, lowering your throttle below min_check will also result in motors off and the esc's being sent min_command. Min_check must be set to a level that is 100% reliably met by the throttle throw. A setting too low may result in a dangerous condition where the copter can’t be disarmed. It is ok to set this below `throttle_idle` (min_throttle) because the FC will automaticly scale the output to the ESCs
`throttle_idle` (previously `min_throttle)` -
Typically set to just above reliable spin up of all motors. Sometimes this is set slightly higher for prop stall prevention during advanced maneuvers or sometimes considerably higher to produce a desired result. When armed with motor stop off, your motors will spin at this command so keep that in mind from a safety stand point.
`max_check` -
Throttle positions above this level will send max_command to the ESCs.
`max_throttle` -
This is the max command to the ESCs from the flight controller.
In depth videos explaining these terms are available from Joshua Bardwell here:
https://www.youtube.com/watch?v=WFU3VewGbbA
https://www.youtube.com/watch?v=YNRl0OTKRGA

75
docs/Display.md

@ -0,0 +1,75 @@
# Display
INAV supports displays to provide information to you about your aircraft and iNav state.
When the aircraft is armed, an "Armed" message is displayed. When it is disarmed, a summary page is displayed. Page cycling has been removed and no other information is currently available
![Stick Positions](assets/images/inav_display_armed.jpg)
![Stick Positions](assets/images/inav_display_status.jpg)
There is currently no way to change the information on the display
## Supported Hardware
I2c IIC Serial Oled LCD LED Module 12864 (<a href="http://a.co/5hxXEvZ">http://a.co/5hxXEvZ</a> used in status image above)
SSD1306
UG-2864HSWEG01
## Configuration
From the CLI enable the `DASHBOARD` feature
```
feature DASHBOARD
```
### SSD1306 OLED displays
The SSD1306 display is a 128x64 OLED display that is visible in full sunlight, small and consumes very little current.
This makes it ideal for aircraft use.
There are various models of SSD1306 boards out there, they are not all equal and some require addtional modifications
before they work. Choose wisely!
Links to displays:
* [banggood.com](https://inavflight.com/shop/s/bg/958196) 0.96 Inch 4Pin White IIC I2C OLED Display Module 12864 LED For Arduino
* [banggood.com](https://inavflight.com/shop/s/bg/969147) 0.96 Inch 4Pin IIC I2C Blue OLED Display Module For Arduino
* [wide.hk](http://www.wide.hk/products.php?product=I2C-0.96%22-OLED-display-module-%28-compatible-Arduino-%29) I2C 0.96" OLED display module
* [witespyquad.gostorego.com](http://witespyquad.gostorego.com/accessories/readytofly-1-oled-128x64-pid-tuning-display-i2c.html) ReadyToFlyQuads 1" OLED Display
* [multiwiicopter.com](http://www.multiwiicopter.com/products/1-oled) PARIS 1" OLED 128x64 PID tuning screen AIR
The banggood.com display is the cheapest at the time of writing and will correctly send I2C ACK signals.
#### Crius CO-16
This display is best avoided but will work if you modify it.
Step 1
As supplied the I2C ack signal is not sent because the manufacturer did not bridge D1 and D2 together. To fix this solder
the two pins together as they enter the screen. Failure to do this will result is a screen that doesn't display anything.
Step 2
Pin 14 must be disconnected from the main board using a scalpel. Then connect a 10nF or 100nF capacitor between pins 30 and the
lifted pin 14.
Step 3
Connect a 100K resistor between Pin 9 and the lifted Pin 14.
Failure to perform steps 2 and 3 will result in a display that only works on power up some of the time any may display random dots
or other display corruption.
More can be read about this procedure here: http://www.multiwii.com/forum/viewtopic.php?f=6&t=2705&start=10
![Crius CO-16 Diagram](Wiring/Crius CO-16 OLED diagram.png)
![Crius CO-16 Modification](Wiring/Crius CO-16 OLED modifications.jpg)
## Connections
Connect +5v, Ground, I2C SDA and I2C SCL from the flight controller to the display.

26
docs/ESC and servo outputs.md

@ -0,0 +1,26 @@
# ESC and servo outputs
## ESC protocols
INAV support following ESC protocols:
* "standard" PWM with 50-400Hz update rate
* OneShot125
* OneShot42
* Multishot
* Brushed motors
ESC protocol can be selected in Configurator. No special configuration is required.
Check ESC documentation of the list of protocols that it is supporting.
## Servo outputs
By default, INAV uses 50Hz servo update rate. If you want to increase it, make sure that servos support
higher update rates. Only high end digital servos are capable of handling 200Hz and above!
## Servo output mapping
Not all outputs on a flight controller can be used for servo outputs. It is a hardware thing. Always check flight controller documentation.
While motors are usually ordered sequentially, here is no standard output layout for servos! Some boards might not be supporting servos in _Multirotor_ configuration at all!

146
docs/Failsafe.md

@ -0,0 +1,146 @@
# Failsafe
Failsafe is a state the flight controller is meant to enter when the radio receiver loses the RC link. Any of these of these conditions will trigger it:
* Any flight channel (pitch, roll, throttle or yaw) sends no pulses
* Any channel is outside the valid range between `rx_min_usec` and `rx_max_usec`
* The FAILSAFE aux mode is activated
If the failsafe happens while the flight controller is disarmed, it only prevent arming. If it happens while armed, the failsafe policy configured in `failsafe_procedure` is engaged. The available procedures are:
* __DROP:__ Just kill the motors and disarm (crash the craft).
* __SET-THR:__ Enable auto-level mode (for multirotor) or enter preconfigured roll/pitch/yaw spiral down (for airplanes) and set the throttle to a predefined value (`failsafe_throttle`) for a predefined time (`failsafe_off_delay`). This is meant to get the craft to a safe-ish landing (or more realistically, a controlled crash), it doesn't require any extra sensor other than gyros and accelerometers.
* __RTH:__ (Return To Home) One of the key features of inav, it automatically navigates the craft back to the home position and (optionally) lands it. Similarly to all other automated navigation methods, it requires GPS for any type of craft, plus compass and barometer for multicopters.
* __NONE:__ Do nothing. This is meant to let the craft perform a fully automated flight (eg. waypoint flight) outside of radio range. Highly unsafe when used with manual flight.
Note that:
* Should the failsafe disarm the flight controller (**DROP**, **SET-THR** after `failsafe_off_delay` or **RTH** with `nav_disarm_on_landing` ON), the flight controller will be disarmed and re-arming will be locked until the signal from the receiver is restored for 30 seconds AND the arming switch is in the OFF position (when an arm switch is in use).
* Prior to starting failsafe it is checked if the throttle position has been below `min_throttle` for the last `failsafe_throttle_low_delay` seconds. If it was, the craft is assumed to be on the ground and is simply disarmed. This feature can be disabled completely by setting `failsafe_throttle_low_delay` to zero, which may be necessary to do if the craft may fly long with zero throttle (eg. gliders).
## Notes about safety
* If the craft is landed but armed, the failsafe may make the motors and props spin again and even make the craft take off (in case of **RTH** failsafe). Take expecially care of this when using `MOTOR_STOP` feature. **Props will spin up without warning**. Have a look at the `failsafe_throttle_low_delay` setting explained above to learn when this could happen.
* If any required navigation sensor becomes unavailable during a Return to Home (eg. loss of GPS fix), an emergency landing similar to **SET-THR** but with barometer support will be performed after a short timeout. An emergency landing would also be performed right when the failsafe is triggered if any required sensor is reported as unavailable.
* **SET-THR** doesn't control the descend in any other way than setting a fixed throttle. Thus, appropriate testing must be performed to find the right throttle value. Consider that a constant throttle setting will yield different thrusts depending on battery voltage, so when you evaluate the throttle value do it with a loaded battery. Failure to do so may cause a flyaway.
* When the failsafe mode is aborted (RC signal restored/failsafe switch set to OFF), the current stick positions will be enforced immediately. Be ready to react quickly.
## RX configuration
In order to engage failsafe mode correctly, you must configure your receiver to do one of the following on signal loss:
* Send no signal/pulses over the channels
* Send an invalid signal over the channels (for example, send values lower than `rx_min_usec`)
* Set an aux channel to engage FAILSAFE mode.
and
* Ensure your receiver does not set any aux channel so that the craft would disarm.
## Failsafe Settings
Failsafe delays are configured in 0.1 second units. Distances are in centimeters (1/100 of a meter).
### Parameters relevant to all failsafe procedures
#### `failsafe_procedure`
Selects the failsafe procedure. Valid procedures are **DROP**, **SET-THR**, **RTH** and **NONE**. See above for a description of each one.
#### `failsafe_delay`
Guard time for failsafe activation when rx channel data is lost or invalid. This is the amount of time the flight controller waits to see if it begins receiving a valid signal again before activating failsafe. Does not apply when activating the FAILSAFE aux mode.
#### `failsafe_recovery_delay`
Guard time for failsafe de-activation after signal is recovered. This is the amount of time the flight controller waits to see if the signal is consistent before turning off failsafe procedure. Usefull to avoid swithing in and out of failsafe RTH. Does not apply when disactivating the FAILSAFE aux mode.
#### `failsafe_stick_threshold`
This parameter defines recovery from failsafe by stick motion. When set to zero failsafe procedure will be cleared as soon as RC link is recovered. When this is set to a non-zero value - failsafe won't clear immediately when if RC link is recovered, you will have to move any of Roll/Pitch/Yaw sticks more than this value to exit failsafe.
The use-case is the Return To Home failsafe: when on the edge of radio coverage you may end up entering and exiting failsafe if radio link is sporadic - happens a lot with long-range pilots. Setting `failsafe_stick_threshold` to a certain value (i.e. 100) RTH will be initiated on first signal loss and will continue as long as pilots want it to continue. When RC link is solid (based on RSSI etc) pilot will move sticks and regain control.
#### `failsafe_throttle_low_delay`
Time throttle level must have been below 'min_throttle' to _only disarm_ instead of _full failsafe procedure_. Set to zero to disable.
#### `failsafe_min_distance`
If failsafe happens when craft is closer than this distance in centimeters from home, failsafe will not execute regular failsafe_procedure, but will execute procedure specified in failsafe_min_distance_procedure instead. 0 = Normal failsafe_procedure always taken.
#### `failsafe_min_distance_procedure`
What failsafe procedure to initiate in Stage 2 when craft is closer to home than failsafe_min_distance.
#### `rx_min_usec`
The lowest channel value considered valid.
#### `rx_max_usec`
The highest channel value considered valid.
### Parameters relevant to **RTH** failsafe procedure
#### `nav_min_rth_distance`
If the failsafe happens while the craft is within this distance from the home position, the home position is considered immediately reached.
#### `nav_rth_climb_first`
If ON the craft rises to `nav_rth_altitude` before heading to home position. if OFF the craft climbs on the way to home position.
#### `nav_rth_climb_ignore_emerg`
When this option is OFF (default) and when you initiate RTH without GPS fix - aircraft will initiate emergency descent and go down. If you set this option to ON - aircraft will reach the RTH target altitude before initiating emergency descent. This is done for cases where GPS coverage is poor (i.e. in the mountains) - allowing UAV to climb up might improve GPS coverage and allow safe return instead of landing in a place where UAV might be impossible to recover.
#### `nav_rth_tail_first`
Only relevant for multirotors. If this is OFF the craft will head to home position head first, if ON it'll be tail first
#### `nav_rth_altitude`
The altitude used as reference for the RTH procedure.
#### `nav_rth_alt_mode`
How and when to reach `nav_rth_altitude`. Please read [the page on the wiki](https://github.com/iNavFlight/inav/wiki/Navigation-modes#rth-altitude-control-modes) for a description of the available modes.
#### `nav_rth_abort_threshold`
If the craft increases its distance from the point the failsafe was triggered first by this amount, RTH procedure is aborted and an emergency landing is initiated. It's meant to avoid flyaways due to navigation issues, like strong winds.
#### `nav_rth_allow_landing`
Enables landing when home position is reached. If OFF the craft will hover indefinitely over the home position.
#### `nav_disarm_on_landing`
Instructs the flight controller to disarm the craft when landing is detected
### Parameters relevant to **SET-THR** failsafe procedure
#### `failsafe_off_delay`
Delay after failsafe activates before motors finally turn off. This is the amount of time 'failsafe_throttle' is active. If you fly at higher altitudes you may need more time to descend safely. Set to zero to keep `failsafe_throttle` active indefinitely.
#### `failsafe_throttle`
Throttle level used for landing. Specify a value that causes the aircraft to descend at about 1M/sec. Default is set to 1000 which should correspond to throttle off.
#### `failsafe_fw_roll_angle`
This parameter defines amount of roll angle (in 1/10 deg units) to execute on failsafe. Negative = LEFT
#### `failsafe_fw_pitch_angle`
This parameter defines amount of pitch angle (in 1/10 deg units) to execute on `SET-THR` failsafe for an airplane. Negative = CLIMB
#### `failsafe_fw_yaw_rate`
This parameter defines amount of yaw rate (in deg per second units) to execute on `SET-THR` failsafe for an airplane. Negative = LEFT

107
docs/Getting Started.md

@ -0,0 +1,107 @@
# Getting Started
This is a step-by-step guide that can help a person that has never used INAV before set up a flight controller and the aircraft around it for flight. Basic RC knowledge is required, though. A total beginner should first familiarize themselves with concepts and techniques of RC before using this (e.g. basic controls, soldering, transmitter operation etc). One could use [RCGroups](http://www.rcgroups.com/forums/index.php) and/or [the Youtube show FliteTest](https://www.youtube.com/user/flitetest) for this.
DISCLAIMER: This documents is a work in progress. We cannot guarantee the safety or success of your project. At this point the document is only meant to be a helping guide, not an authoritative checklist of everything you should do to be safe and successful. Always exercise common sense, critical thinking and caution.
Read the [Introduction](Introduction.md) chapter for an overview of INAV and how the community works.
## Hardware
NOTE: Flight Controllers are typically equipped with accelerometers. These devices are sensitive to shocks. When the device is not yet installed to an aircraft, it has very little mass by itself. If you drop or bump the controller, a big force will be applied on its accelerometers, which could potentially damage them. Bottom line: Handle the board very carefully until it's installed on an aircraft!
For an overview of the hardware INAV (hereby CF) can run on, see [Boards.md](Boards.md). For information about specific boards, see the board specific documentation.
* Assuming that you have a flight controller board (hereby FC) in hand, you should first read through the manual that it came with. You can skip the details about software setup, as we'll cover that here.
* Decide how you'll connect your receiver by reading the [receiver](Rx.md) chapter, and how many pins you need on the outputs (to connect ESCs and servos) by reading about [Mixers](Mixer.md).
* If you're interested in monitoring your flight battery with CF, see [Battery Monitoring](Battery.md).
* You may want audible feedback from your copter so skim through [Buzzer](Buzzer.md) and mark the pins that will be used.
* Do you want your RC Receiver's RSSI to be sent to the board? [The RSSI chapter](Rssi.md) explains how. You may or may not need to make an additional connection from your Receiver to the FC.
* Would you like to try using a GPS unit to get your aircraft to Loiter or Return-To-Launch? Take a look at the [GPS](Gps.md) and [GPS Tested Hardware](Gps.md#hardware) chapters.
* You may also want to read the [Serial](Serial.md) chapter to determine what extra devices (such as Blackbox, OSD, Telemetry) you may want to use, and how they should be connected.
* Now that you know what features you are going to use, and which pins you need, you can go ahead and solder them to your board, if they are not soldered already. Soldering only the pins required for the application may save weight and contribute to a neater looking setup, but if you need to use a new feature later you may have to unmount the board from the craft and solder missing pins, so plan accordingly. Before soldering your FC please review a how-to-solder tutorial to avoid expensive mistakes, practice soldering on some scrap before soldering your FC.
* If you are going to use [Oneshot125](Oneshot.md), you may need to enable that on your ESCs using a jumper or flashing them with the latest stable firmware and enable Damped Light in their settings, if it's supported. Refer to the ESCs' documentation or online discussions to determine this.
## Software setup
Now that your board has pins on it, you are ready to connect it to your PC and flash it with CF. Install the Chromium browser or Google Chrome to your PC, if you don't have it already, add the [INAV Configurator](https://chrome.google.com/webstore/detail/inav-configurator/fmaidjmgkdkpafmbnmigkpdnpdhopgel) to it, and start it.
Then follow these instructions for [Installation](Installation.md) of the firmware to the FC.
## INAV Configuration
Your FC should now be running CF, and you should be able to connect to it using the Configurator. If that is not the case, please go back to the previous sections and follow the steps carefully.
<!--- This next paragraph should probably contain less info, as this info already exists in Configuration.md -->
Now, there are two ways to [configure CF](Configuration.md); via the Configurator's tabs (in a "graphical" way, clicking through and selecting/changing values and tickboxes) and using the [Command Line Interface (CLI)](Cli.md). Some settings may only be configurable using the CLI and some settings are best configured using the GUI (particularly the ports settings, which aren't documented for the CLI as they're not human friendly).
* It is now a good time to setup your RC Receiver and Transmitter. Set the Tx so that it outputs at least 4 channels (Aileron, Elevator, Throttle, Rudder) but preferably more. E.g. you can set channels 5 and 6 to be controlled by 3-position switches, to be used later. Maybe set up EXPO on AIL/ELE/RUD, but you should know that it can also be done in CF's software later. If using RSSI over PPM or PWM, it's now time to configure your Rx to output it on a spare channel.
* Connect the Rx to the FC, and the FC to the PC. You may need to power the Rx through a BEC (its 5V rail - observe polarity!).
* On your PC, connect to the Configurator, and go to the first tab. Check that the board animation is moving properly when you move the actual board. Do an accelerometer calibration.
* Configuration tab: Select your aircraft configuration (e.g. Quad X), and go through each option in the tab to check if relevant for you.
* E.g. you may want to enable ONESHOT125 for Oneshot-capable ESCs.
* You may need RX_PPM if you're using an RC Receiver with PPM output etc.
* If planning to use the battery measurement feature of the FC, check VBAT under Battery Voltage.
* If using analog RSSI, enable that under RSSI. Do not enable this setting if using RSSI injected into the PPM stream.
* Motors will spin by default when the FC is armed. If you don't like this, enable MOTOR_STOP.
* Also, adjust the minimum, middle and maximum throttle according to these guidelines:
* Minimum Throttle - Set this to the minimum throttle level that enables all motors to start reliably. If this is too low, some motors may not start properly after spindowns, which can cause loss of stability and control. A typical value would be 1100.
* Middle Throttle - The throttle level for middle stick position. Many radios use 1500, but some (e.g. Futaba) may use 1520 or other values.
* Maximum Throttle - The maximum throttle level that the ESCs should receive. A typical value would be 2000.
* Minimum Command - This is the "idle" signal level that will be sent to the ESCs when the craft is disarmed, which should not cause the motors to spin. A typical value would be 1000.
* Finally, click Save and Reboot.
* Receiver tab:
* Check that the channel inputs move according to your Tx inputs.
* Check that the Channel map is correct along with the RSSI Channel, if you use that.
* Verify the range of each channel goes from ~1000 to ~2000. See also [controls](Controls.md). and `rx_min_usec` and `rx_max_usec`.
* You can also set EXPO here instead of your Tx.
* Click Save!
* Modes tab: Setup the desired modes. See the [modes](Modes.md) chapter for what each mode does, but for the beginning you mainly need HORIZON, if any.
* Before finishing this section, you should calibrate the ESCs, install the FC to the frame, and connect the RSSI cable, buzzer and battery if you have chosen to use those.
## Final testing and safety
It's important that you have configured CF properly, so that your aircraft does not fly away, or even worse fly into property and people! This is an important step that you should NOT postpone until after your maiden flight. Please do this now, before you head off to the flying field.
* First, learn how to arm your FC, and about other [controls](Controls.md).
* Next up, setup [Failsafe](Failsafe.md). Take your time, do it properly.
* Now, on the bench, without props, test that failsafe works properly, according to the above doc.
* Additionally, test the effect of AIL/ELE input of your Tx. Is the aircraft responding properly? Do the same for RUD input.
* Test the direction of AIL/ELE auto correction. Raise throttle at 30% (no blades!); when you tilt the aircraft, do the motors try to compensate momentarily? This should simulate random wind forces that the FC should counteract
* Test the direction of AIL/ELE auto correction in HORIZON mode. With throttle at 30%, if you tilt the aircraft so that one motor is lowered towards the ground, does it spin up and stay at high RPM until you level it off again? This tests the auto-leveling direction.
If one of these tests fail, do not attempt to fly, but go back to the configuration phase instead. Some channel may need reversing, or the direction of the board is wrong.
## Using it (AKA: Flying)
Go to the field, turn Tx on, place aircraft on the ground, connect flight battery and wait. Arm and fly. Good luck!
## Advanced Matters
Some advanced configurations and features are documented in the following pages, but have not been touched-upon earlier:
* [Profiles](Profiles.md)
* [PID tuning](PID%20tuning.md)
* [In-flight Adjustments](Inflight%20Adjustments.md)
* [Blackbox logging](Blackbox.md)
* [Using a Sonar](Sonar.md)
* [Spektrum Bind](Spektrum%20bind.md)
* [Telemetry](Telemetry.md)
* [Using a Display](Display.md)
* [Using a LED strip](LedStrip.md)

25
docs/INAV PID Controller.md

@ -0,0 +1,25 @@
# INAV PID Controller
What you have to know about INAV PID/PIFF/PIDCD controllers:
1. INAV PID uses floating-point math
1. Rate/Angular Velocity controllers work in dps [degrees per second]
1. P, I, D and Multirotor CD gains are scaled like Betafligfht equivalents, but actual mechanics are different, and PID response might be different
1. Depending on platform type, different controllers are used
1. Fixed-wing uses **PIFF**:
1. Error is computed with a formula `const float rateError = pidState->rateTarget - pidState->gyroRate;`
1. P-term with a formula `rateError * pidState->kP`
1. Simple I-term without Iterm Relax. I-term limit based on stick position is used instead. I-term is no allowed to grow if stick (roll/pitch/yaw) is deflected above threshold defined in `fw_iterm_limit_stick_position`. `pidState->errorGyroIf += rateError * pidState->kI * dT;`
1. No D-term
1. FF-term (Feed Forward) is computed from the controller input with a formula `pidState->rateTarget * pidState->kFF`. Bear in mind, this is not a **FeedForward** from Betaflight!
1. Multirotor uses **PIDCD**:
1. Error is computed with a formula `const float rateError = pidState->rateTarget - pidState->gyroRate;`
1. P-term with a formula `rateError * pidState->kP`
1. I-term
1. Iterm Relax is used to dynamically attenuate I-term during fast stick movements
1. I-term formula `pidState->errorGyroIf += (itermErrorRate * pidState->kI * antiWindupScaler * dT) + ((newOutputLimited - newOutput) * pidState->kT * antiWindupScaler * dT);`
1. I-term can be limited when motor output is saturated
1. D-term is computed only from gyro measurement
1. There are 2 LPF filters on D-term
1. D-term can by boosted during fast maneuvers using D-Boost. D-Boost is an equivalent of Betaflight D_min
1. **Control Derivative**, CD, or CD-term is a derivative computed from the setpoint that helps to boost PIDCD controller during fast stick movements. `newCDTerm = rateTargetDeltaFiltered * (pidState->kCD / dT);` It is an equivalent of Betaflight Feed Forward

BIN
docs/INAV_Autolaunch.pdf

BIN
docs/INAV_Fixed_Wing_Setup_Guide.pdf

BIN
docs/INAV_Modes.pdf

BIN
docs/INAV_Wing_Tuning_Masterclass.pdf

266
docs/Inflight Adjustments.md

@ -0,0 +1,266 @@
# In-flight Adjustments
With INAV it's possible to make adjustments to various settings by using AUX channels from your transmitter while the aircraft is flying.
## Warning
Changing settings during flight can make your aircraft unstable and crash if you are not careful.
## Recommendations
* Always make adjustments while flying in a large open area.
* Make small adjustments and fly carefully to test your adjustment.
* Give yourself enough flying space and time to adjust to how your changes affect the behaviour of the aircraft.
* Remember to set adjustment channel switches/pots to the center position before powering on your TX and your aircraft.
* If possible configure switch warnings on your transitter for dedicated adjustment switches.
* A momentary 3 position switch is the best choice of switch for this - i.e. one that re-centers itself when you let go of it.
## Overview
Up to 4 RX channels can be used to make different adjustments at the same time.
The adjustment a channel makes can be controlled by another channel.
The following adjustments can be made in flight as well as on the ground.
* RC Rate
* RC Expo
* Throttle Expo
* Pitch, Roll, Yaw Rates
* Pitch, Roll, Yaw PIDs
* Rate profile
* Manual rates
* FW cruise_throttle, pitch2thr, min_throttle_down_pitch_angle
* Board alignment
* Level PIDs
* PosHold, AltHold PIDs
* PIDs profile
Example scenarios:
Up to 4 3-position switches or pots can be used to adjust 4 different settings at the same time.
A single 2/3/4/5/6/x position switch can be used to make one 3 position switch adjust one setting at a time.
Any combination of switches and pots can be used. So you could have 6 POS switch.
Settings are not saved automatically, connect a GUI, refresh and save or save using stick position when disarmed.
Powering off without saving will discard the adjustments.
Settings can be saved when disarmed using stick positions: Throttle Low, Yaw Left, Pitch Low, Roll Right.
## Adjustment switches
The switch can be a ON-OFF-ON, POT or momentary ON-OFF-ON switch. The latter is recommended.
When the switch is returned to the center position the value will not be increased/decreased.
Each time you can press the switch high/low and then return it to the middle the value will change at least once, you do not have to wait before pressing the switch again if you want to increase/decrease at a faster rate. While the adjustment switch held is high/low, the adjustment function applies and increases/decreases the value being adjusted twice a second and the flight controller will beep shorter/longer, respectively. The system works similar to how a keyboard repeat delay works.
Hint: With OpenTX transmitters you can combine two momentary OFF-ON switches to control a single channel. You could make it so that a momentary switch on the left of your transmitter decreases the value and a momentary switch on the right increases the value. Experiment with your mixer!
## Configuration
The CLI command `adjrange` is used to configure adjustment ranges.
12 adjustment ranges can be defined.
4 adjustments can be made at the same time, each simultaneous adjustment requires an adjustment slot.
Show the current ranges using:
`adjrange`
Configure a range using:
`adjrange <index> <slot> <range channel> <range start> <range end> <adjustment function> <adjustment channel>`
| Argument | Value | Meaning |
| -------- | ----- |-------- |
| Index | 0 - 11 | Select the adjustment range to configure |
| Slot | 0 - 3 | Select the adjustment slot to use |
| Range Channel | 0 based index, AUX1 = 0, AUX2 = 1 | The AUX channel to use to select an adjustment for a switch/pot |
| Range Start | 900 - 2100. Steps of 25, e.g. 900, 925, 950... | Start of range |
| Range End | 900 - 2100 | End of range |
| Adjustment function | 0 - 11 | See Adjustment function table |
| Adjustment channel | 0 based index, AUX1 = 0, AUX2 = 1 | The channel that is controlled by a 3 Position switch/Pot |
Range Start/End values should match the values sent by your receiver.
Normally Range Channel and Slot values are grouped together over multiple adjustment ranges.
The Range Channel and the Adjustment Channel can be the same channel. This is useful when you want a single 3 Position switch to be dedicated
to a single adjustment function regardless of other switch positions.
The adjustment function is applied to the adjustment channel when range channel is between the range values.
The adjustment is made when the adjustment channel is in the high or low position. high = mid_rc + 200, low = mid_rc - 200. by default this is 1700 and 1300 respectively.
When the Range Channel does not fall into Start/End range the assigned slot will retain it's state and will continue to apply the adjustment. For
this reason ensure that you define enough ranges to cover the range channel's usable range.
### Adjustment function
| Value | Adjustment | Notes |
| ----- | ---------- |------ |
| 0 | None |
| 1 | RC RATE |
| 2 | RC_EXPO |
| 3 | THROTTLE_EXPO |
| 4 | PITCH_ROLL_RATE |
| 5 | YAW_RATE |
| 6 | PITCH_ROLL_P |
| 7 | PITCH_ROLL_I |
| 8 | PITCH_ROLL_D |
| 9 | YAW_P |
| 10 | YAW_I |
| 11 | YAW_D_FF |
| 12 | RATE_PROFILE | Switch between 3 rate profiles using a 3 position switch. |
| 13 | PITCH_RATE |
| 14 | ROLL_RATE |
| 15 | PITCH_P |
| 16 | PITCH_I |
| 17 | PITCH_D_FF |
| 18 | ROLL_P |
| 19 | ROLL_I |
| 20 | ROLL_D_FF |
| 21 | RC_YAW_EXPO |
| 22 | MANUAL_RC_EXPO |
| 23 | MANUAL_RC_YAW_EXPO |
| 24 | MANUAL_PITCH_ROLL_RATE |
| 25 | MANUAL_ROLL_RATE |
| 26 | MANUAL_PITCH_RATE |
| 27 | MANUAL_YAW_RATE |
| 28 | NAV_FW_CRUISE_THROTTLE |
| 29 | NAV_FW_PITCH2THR |
| 30 | ROLL_BOARD_ALIGNMENT |
| 31 | PITCH_BOARD_ALIGNMENT |
| 32 | LEVEL_P |
| 33 | LEVEL_I |
| 34 | LEVEL_D |
| 35 | POS_XY_P |
| 36 | POS_XY_I |
| 37 | POS_XY_D |
| 38 | POS_Z_P |
| 39 | POS_Z_I |
| 40 | POS_Z_D |
| 41 | HEADING_P |
| 42 | VEL_XY_P |
| 43 | VEL_XY_I |
| 44 | VEL_XY_D |
| 45 | VEL_Z_P |
| 46 | VEL_Z_I |
| 47 | VEL_Z_D |
| 48 | FW_MIN_THROTTLE_DOWN_PITCH_ANGLE |
| 49 | ADJUSTMENT_VTX_POWER_LEVEL |
## Examples
### Example 1 - 3 Position switch used to adjust pitch/roll rate
```
adjrange 0 0 3 900 2100 4 3
```
explained:
* configure adjrange 0 to use adjustment slot 1 (0) so that when aux4
(3) in the range 900-2100 then use adjustment 4 (pitch/roll rate) when aux 4 (3)
is in the appropriate position.
### Example 2 - 2 Position switch used to enable adjustment of RC rate via a 3 position switch
```
adjrange 1 1 0 900 1700 0 2
adjrange 2 1 0 1700 2100 1 2
```
explained:
* configure adjrange 1 to use adjustment slot 2 (1) so that when aux1
(0) in the range 900-1700 then do nothing (0) when aux 3 (2) is in any
position.
* configure adjrange 2 to use adjustment slot 2 (1) so that when aux1
(0) in the range 1700-2100 then use adjustment rc rate (1) when aux 3
(2) is in the appropriate position.
Without the entire range of aux1 being defined there is nothing that
would stop aux 3 adjusting the pitch/roll rate once aux 1 wasn't in the higher
range.
### Example 3 - 6 Position switch used to select PID tuning adjustments via a 3 position switch
```
adjrange 3 2 1 900 1150 6 3
adjrange 4 2 1 1150 1300 7 3
adjrange 5 2 1 1300 1500 8 3
adjrange 6 2 1 1500 1700 9 3
adjrange 7 2 1 1700 1850 10 3
adjrange 8 2 1 1850 2100 11 3
```
explained:
* configure adjrange 3 to use adjustment slot 3 (2) so that when aux2
(1) in the range 900-1150 then use adjustment Pitch/Roll P (6) when aux 4
(3) is in the appropriate position.
* configure adjrange 4 to use adjustment slot 3 (2) so that when aux2
(1) in the range 1150-1300 then use adjustment Pitch/Roll I (7) when aux 4
(3) is in the appropriate position.
* configure adjrange 5 to use adjustment slot 3 (2) so that when aux2
(1) in the range 1300-1500 then use adjustment Pitch/Roll D (8) when aux 4
(3) is in the appropriate position.
* configure adjrange 6 to use adjustment slot 3 (2) so that when aux2
(1) in the range 1500-1700 then use adjustment Yaw P (9) when aux 4
(3) is in the appropriate position.
* configure adjrange 7 to use adjustment slot 3 (2) so that when aux2
(1) in the range 1700-1850 then use adjustment Yaw I (10) when aux 4
(3) is in the appropriate position.
* configure adjrange 8 to use adjustment slot 3 (2) so that when aux2
(1) in the range 1850-2100 then use adjustment Yaw D (11) when aux 4
(3) is in the appropriate position.
### Example 4 - Use a single 3 position switch to change between 3 different rate profiles
adjrange 11 3 3 900 2100 12 3
explained:
* configure adjrange 11 to use adjustment slot 4 (3) so that when aux4
(3) in the range 900-2100 then use adjustment Rate Profile (12) when aux 4
(3) is in the appropriate position.
When the switch is low, rate profile 0 is selcted.
When the switch is medium, rate profile 1 is selcted.
When the switch is high, rate profile 2 is selcted.
### Configurator examples
The following 5 images show valid configurations. In all cases the entire usable range for the Range Channel is used.
![Configurator example 1](Screenshots/adjustments-rate-profile-selection-via-3pos.png)
---
![Configurator example 2](Screenshots/adjustments-pitch-and-roll-rate-adjustment-via-3pos.png)
---
![Configurator example 3](Screenshots/adjustments-pid-via-two-3pos.png)
---
![Configurator example 4](Screenshots/adjustments-pid-via-6pos-and-3pos.png)
---
![Configurator example 5](Screenshots/adjustments-rates-via-a-2pos-and-3pos.png)
The following examples shows __incorrect__ configurations - the entire usable range for the Range Channel is not used in both cases.
![Configurator example 6](Screenshots/adjustments-incorrect-config-1.png)
![Configurator example 7](Screenshots/adjustments-incorrect-config-2.png)
In the following example, the incorrect configuraton (above) has been corrected by adding a range that makes 'No changes'.
![Configurator example 7](Screenshots/adjustments-incorrect-config-2-corrected.png)

30
docs/Installation.md

@ -0,0 +1,30 @@
# Installation
## Using the configurator
This is a generic procedure to flash a board using the configurator. The configurator does not yet support all boards, so please check the documentation corresponding to your board before proceeding.
Make sure you have the [INAV Configurator](https://github.com/iNavFlight/inav-configurator) installed, then:
* Connect the flight controller to the PC.
* Start the INAV Configurator.
* Click on "Disconnect" if the configurator connected to the board automatically.
* Click on the "Firmware Flasher" tab.
* Make sure you have internet connectivity and click on the "Load Firmware [Online]" button.
* Click on the "Choose a Firmware / Board" dropdown menu, and select the latest stable version for your flight controller.
* IMPORTANT: Read and understand the release notes that are displayed. When upgrading review all release notes since your current firmware.
* If this is the first time INAV is flashed to the board, tick the "Full Chip Erase" checkbox.
* Connect the flight controller board to the PC. Ensure the correct serial port is selected.
* Click on the "Flash Firmware" button and hold still (do not breathe, too).
* When the progress bar becomes green and reads "Programming: SUCCESSFUL" you are done!
## Manually
See the board specific flashing instructions.
# Upgrading
When upgrading be sure to backup / dump your existing settings. Some firmware releases are not backwards compatible and default settings are restored when the FC detects an out of date configuration.
## Backup/Restore process
See the CLI section of the docs for details on how to backup and restore your configuration via the CLI.

35
docs/Introduction.md

@ -0,0 +1,35 @@
# INAV
![INAV](http://static.rcgroups.net/forums/attachments/6/1/0/3/7/6/a9088858-102-inav.png)
Welcome to INAV!
INAV is an community project which attempts to deliver flight controller firmware and related tools.
## Primary Goals
* Community driven.
* Friendly project atmosphere.
* Focus on the needs of users.
* Great flight performance.
* Understandable and maintainable code.
## Hardware
See the flight controller hardware chapter for details.
## Software
There are two primary components, the firmware and the configuration tool. The firmware is the code that runs on the flight controller board. The GUI configuration tool (configurator) is used to configure the flight controller, it runs on Windows, OSX and Linux.
## Feedback & Contributing
We welcome all feedback. If you love it we want to hear from you, if you have problems please tell us how we could improve things so we can make it better for everyone.
If you want to contribute please see the notes here:
https://github.com/iNavFlight/inav#contributing
Developers should read this:
https://github.com/iNavFlight/inav/blob/master/CONTRIBUTING.md

599
docs/LedStrip.md

@ -0,0 +1,599 @@
# LED Strip
INAV supports the use of addressable LED strips. Addressable LED strips allow each LED in the strip to
be programmed with a unique and independant color. This is far more advanced than the normal RGB strips which
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.
* Indicators showing pitch/roll stick positions.
* Heading/Orientation lights.
* Flight mode specific color schemes.
* Low battery warning.
* AUX operated on/off switch.
* GPS state.
* RSSI level.
* Battery level.
Support for more than 32 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.
WS2812 LEDs require an 800khz signal and precise timings and thus requires the use of a dedicated hardware timer.
Note: Not all WS2812 ICs use the same timings, some batches use different timings.
It could be possible to be able to specify the timings required via CLI if users request it.
### Tested Hardware
* [Adafruit NeoPixel Jewel 7](https://www.adafruit.com/products/2226) (preliminary testing)
* Measured current consumption in all white mode ~ 350 mA.
* Fits well under motors on mini 250 quads.
* [Adafruit NeoPixel Stick](https://www.adafruit.com/products/1426) (works well)
* Measured current consumption in all white mode ~ 350 mA.
## Connections
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.
| Target | Pin | LED Strip | Signal |
| --------------------- | ---- | --------- | -------|
| F3Discovery | PB8 | Data In | PB8 |
| Sparky | PWM5 | Data In | PA6 |
If you have LEDs that are intermittent, flicker or show the wrong colors then drop the VIN to less than 4.7v, e.g. by using an inline
diode on the VIN to the LED strip. The problem occurs because of the difference in voltage between the data signal and the power
signal. The WS2811 LED's require the data signal (Din) to be between 0.3 * Vin (Max) and 0.7 * VIN (Min) to register valid logic
low/high signals. The LED pin on the CPU will always be between 0v to ~3.3v, so the Vin should be 4.7v (3.3v / 0.7 = 4.71v).
Some LEDs are more tolerant of this than others.
The datasheet can be found here: http://www.adafruit.com/datasheets/WS2812.pdf
## Configuration
The led strip feature can be configured via the GUI.
GUI:
Enable the Led Strip feature via the GUI under setup.
Configure the leds from the Led Strip tab in the INAV GUI.
First setup how the led's are laid out so that you can visualize it later as you configure and so the flight controller knows how many led's there are available.
There is a step by step guide on how to use the GUI to configure the Led Strip feature using the GUI http://blog.oscarliang.net/setup-rgb-led-cleanflight/ which was published early 2015 by Oscar Liang which may or may not be up-to-date by the time you read this.
CLI:
Enable the `LED_STRIP` feature via the cli:
```
feature LED_STRIP
```
If you enable LED_STRIP feature and the feature is turned off again after a reboot then check your config does not conflict with other features, as above.
Configure the LEDs using the `led` command.
The `led` command takes either zero or two arguments - an zero-based led number and a sequence which indicates pair of coordinates, direction flags and mode flags and a color.
If used with zero arguments it prints out the led configuration which can be copied for future reference.
Each led is configured using the following template: `x,y:ddd:mmm:cc`
`x` and `y` are grid coordinates of a 0 based 16x16 grid, north west is 0,0, south east is 15,15
`ddd` specifies the directions, since an led can face in any direction it can have multiple directions. Directions are:
`N` - North
`E` - East
`S` - South
`W` - West
`U` - Up
`D` - Down
For instance, an LED that faces South-east at a 45 degree downwards angle could be configured as `SED`.
Note: It is perfectly possible to configure an LED to have all directions `NESWUD` but probably doesn't make sense.
`mmm` specifies the modes that should be applied an LED.
Each LED has one base function:
* `C` - `C`olor.
* `F` - `F`light mode & Orientation
* `A` - `A`rmed state.
* `R` - `R`ing thrust state.
* `G` - `G`PS state.
* `S` - R`S`SSI level.
* `L` - Battery `L`evel.
And each LED has overlays:
* `W` - `W`warnings.
* `I` - `I`ndicator.
* `T` - `T`hrust state.
* `B` - `B`link (flash twice) mode.
* `O` - Lars`O`n Scanner (Cylon Effect).
* `N` - Blink on la`N`ding (throttle < 50%).
`cc` specifies the color number (0 based index).
Example:
```
led 0 0,15:SD:AWI:0
led 1 15,0:ND:AWI:0
led 2 0,0:ND:AWI:0
led 3 0,15:SD:AWI:0
led 4 7,7::C:1
led 5 8,8::C:2
led 6 8,9::B:1
```
To erase an led, and to mark the end of the chain, use `0,0::` as the second argument, like this:
```
led 4 0,0:::
```
It is best to erase all LEDs that you do not have connected.
### Modes
#### Warning
This mode simply uses the LEDs to flash when warnings occur.
| Warning | LED Pattern | Notes |
|---------|-------------|-------|
| Arm-lock enabled | flash between green and off | occurs calibration or when unarmed and the aircraft is tilted too much |
| Low Battery | flash red and off | battery monitoring must be enabled. May trigger temporarily under high-throttle due to voltage drop |
| Hardware Error | flash blue and off | indicates that at least one of hardware components is not working correctly |
| Failsafe | flash between light blue and yellow | Failsafe must be enabled |
Flash patterns appear in order, so that it's clear which warnings are enabled.
#### GPS state
This mode shows the GPS state and satellite count.
No fix = red LED
3D fix = green LED
The LEDs will blink as many times as the satellite count, then pause and start again.
#### RSSI level
This mode binds the LED color to RSSI level.
| Color | RSSI |
| ---------- | ---------|
| Green | 100% |
| Lime green | 80% |
| Yellow | 60% |
| Orange | 40% |
| Red | 20% |
| Deep pink | 0% |
When RSSI is below 50% is reached, LEDs will blink slowly, and they will blink fast when under 20%.
#### Battery level
This mode binds the LED color to remaining battery capacity.
| Color | Capacity |
| ---------- | ---------|
| Green | 100% |
| Lime green | 80% |
| Yellow | 60% |
| Orange | 40% |
| Red | 20% |
| Deep pink | 0% |
When Warning or Critial voltage is reached, LEDs will blink slowly or fast.
Note: this mode requires a current sensor. If you don't have the actual device you can set up a virtual current sensor (see [Battery](Battery.md)).
#### Blink
This mode blinks the current LED, alternatively from black to the current active color.
#### Blink on landing
This mode blinks the current LED, alternatively from black to the current active color, when throttle is below 50% and the craft is armed.
#### Larson Scanner (Cylon Effect)
The Larson Scanner replicates the scanning "eye" effect seen on the mechanical Cylons and on Kitt from Knight Rider.
This overlay merely varies the brightness of each LED's current color.
#### Flight Mode & Orientation
This mode shows the flight mode and orientation.
When flight modes are active then the LEDs are updated to show different colors depending on the mode, placement on the grid and direction.
LEDs are set in a specific order:
* LEDs that marked as facing up or down.
* LEDs that marked as facing west or east AND are on the west or east side of the grid.
* LEDs that marked as facing north or south AND are on the north or south side of the grid.
That is, south facing LEDs have priority.
The mapping between modes led placement and colors is currently fixed and cannot be changed.
#### Indicator
This mode flashes LEDs that correspond to roll and pitch stick positions. i.e. they indicate the direction the craft is going to turn.
| Mode | Direction | LED Color |
|------------|--------|---------------------|
|Orientation | North | WHITE |
|Orientation | East | DARK VIOLET |
|Orientation | South | RED |
|Orientation | West | DEEP PINK |
|Orientation | Up | BLUE |
|Orientation | Down | ORANGE |
| | | |
|Head Free | North | LIME GREEN |
|Head Free | East | DARK VIOLET |
|Head Free | South | ORANGE |
|Head Free | West | DEEP PINK |
|Head Free | Up | BLUE |
|Head Free | Down | ORANGE |
| | | |
|Horizon | North | BLUE |
|Horizon | East | DARK VIOLET |
|Horizon | South | YELLOW |
|Horizon | West | DEEP PINK |
|Horizon | Up | BLUE |
|Horizon | Down | ORANGE |
| | | |
|Angle | North | CYAN |
|Angle | East | DARK VIOLET |
|Angle | South | YELLOW |
|Angle | West | DEEP PINK |
|Angle | Up | BLUE |
|Angle | Down | ORANGE |
| | | |
|Mag | North | MINT GREEN |
|Mag | East | DARK VIOLET |
|Mag | South | ORANGE |
|Mag | West | DEEP PINK |
|Mag | Up | BLUE |
|Mag | Down | ORANGE |
| | | |
|Baro | North | LIGHT BLUE |
|Baro | East | DARK VIOLET |
|Baro | South | RED |
|Baro | West | DEEP PINK |
|Baro | Up | BLUE |
|Baro | Down | ORANGE |
#### Armed state
This mode toggles LEDs between green and blue when disarmed and armed, respectively.
Note: Armed State cannot be used with Flight Mode.
#### Thrust state
This mode fades the LED current LED color to the previous/next color in the HSB color space depending on throttle stick position. When the
throttle is in the middle position the color is unaffected, thus it can be mixed with orientation colors to indicate orientation and throttle at
the same time. Thrust should normally be combined with Color or Mode/Orientation.
#### Thrust ring state
This mode is allows you to use one or multiple led rings (e.g. NeoPixel ring) for an afterburner effect. The light pattern rotates clockwise as throttle increases.
A better effect is acheived when LEDs configured for thrust ring have no other functions.
LED direction and X/Y positions are irrelevant for thrust ring LED state. The order of the LEDs that have the state determines how the LED behaves.
Each LED of the ring can be a different color. The color can be selected between the 16 colors availables.
For example, led 0 is set as a `R`ing thrust state led in color 13 as follow.
```
led 0 2,2::R:13
```
LED strips and rings can be combined.
#### Solid Color
The mode allows you to set an LED to be permanently on and set to a specific color.
x,y position and directions are ignored when using this mode.
Other modes will override or combine with the color mode.
For example, to set led 0 to always use color 10 you would issue this command.
```
led 0 0,0::C:10
```
### Colors
Colors can be configured using the cli `color` command.
The `color` command takes either zero or two arguments - an zero-based color number and a sequence which indicates pair of hue, saturation and value (HSV).
See http://en.wikipedia.org/wiki/HSL_and_HSV
If used with zero arguments it prints out the color configuration which can be copied for future reference.
The default color configuration is as follows:
| Index | Color |
| ----- | ----------- |
| 0 | black |
| 1 | white |
| 2 | red |
| 3 | orange |
| 4 | yellow |
| 5 | lime green |
| 6 | green |
| 7 | mint green |
| 8 | cyan |
| 9 | light blue |
| 10 | blue |
| 11 | dark violet |
| 12 | magenta |
| 13 | deep pink |
| 14 | black |
| 15 | black |
```
color 0 0,0,0
color 1 0,255,255
color 2 0,0,255
color 3 30,0,255
color 4 60,0,255
color 5 90,0,255
color 6 120,0,255
color 7 150,0,255
color 8 180,0,255
color 9 210,0,255
color 10 240,0,255
color 11 270,0,255
color 12 300,0,255
color 13 330,0,255
color 14 0,0,0
color 15 0,0,0
```
### Mode Colors Assignement
Mode Colors can be configured using the cli `mode_color` command.
- No arguments: lists all mode colors
- arguments: mode, function, color
First 6 groups of ModeIndexes are :
| mode | name |
|------|-------------|
| 0 | orientation |
| 1 | headfree |
| 2 | horizon |
| 3 | angle |
| 4 | mag |
| 5 | baro |
| 6 | special |
Modes 0 to 5 functions:
| function | name |
|----------|-------|
| 0 | north |
| 1 | east |
| 2 | south |
| 3 | west |
| 4 | up |
| 5 | down |
Mode 6 use these functions:
| function | name |
|----------|--------------------|
| 0 | disarmed |
| 1 | armed |
| 2 | animation |
| 3 | background |
| 4 | blink background |
| 5 | gps: no satellites |
| 6 | gps: no fix |
| 7 | gps: 3D fix |
The ColorIndex is picked from the colors array ("palette").
Examples (using the default colors):
- set armed color to red: ```mode_color 6 1 2```
- set disarmed color to yellow: ```mode_color 6 0 4```
- set Headfree mode 'south' to Cyan: ```mode_color 1 2 8```
## Positioning
Cut the strip into sections as per diagrams below. When the strips are cut ensure you reconnect each output to each input with cable where the break is made.
e.g. connect 5V out to 5V in, GND to GND and Data Out to Data In.
Orientation is when viewed with the front of the aircraft facing away from you and viewed from above.
### Example 12 LED config
The default configuration is as follows
```
led 0 15,15:ES:IA:0
led 1 15,8:E:WF:0
led 2 15,7:E:WF:0
led 3 15,0:NE:IA:0
led 4 8,0:N:F:0
led 5 7,0:N:F:0
led 6 0,0:NW:IA:0
led 7 0,7:W:WF:0
led 8 0,8:W:WF:0
led 9 0,15:SW:IA:0
led 10 7,15:S:WF:0
led 11 8,15:S:WF:0
led 12 7,7:U:WF:0
led 13 8,7:U:WF:0
led 14 7,8:D:WF:0
led 15 8,8:D:WF:0
led 16 8,9::R:3
led 17 9,10::R:3
led 18 10,11::R:3
led 19 10,12::R:3
led 20 9,13::R:3
led 21 8,14::R:3
led 22 7,14::R:3
led 23 6,13::R:3
led 24 5,12::R:3
led 25 5,11::R:3
led 26 6,10::R:3
led 27 7,9::R:3
led 28 0,0:::0
led 29 0,0:::0
led 30 0,0:::0
led 31 0,0:::0
```
Which translates into the following positions:
```
6 3
\ /
\ 5-4 /
\ FRONT /
7,8 | 12-15 | 1,2
/ BACK \
/ 10,11 \
/ \
9 0
RING 16-27
```
LEDs 0,3,6 and 9 should be placed underneath the quad, facing downwards.
LEDs 1-2, 4-5, 7-8 and 10-11 should be positioned so the face east/north/west/south, respectively.
LEDs 12-13 should be placed facing down, in the middle
LEDs 14-15 should be placed facing up, in the middle
LEDs 16-17 should be placed in a ring and positioned at the rear facing south.
This is the default so that if you don't want to place LEDs top and bottom in the middle just connect the first 12 LEDs.
### Example 16 LED config
```
led 0 15,15:SD:IA:0
led 1 8,8:E:FW:0
led 2 8,7:E:FW:0
led 3 15,0:ND:IA:0
led 4 7,7:N:FW:0
led 5 8,7:N:FW:0
led 6 0,0:ND:IA:0
led 7 7,7:W:FW:0
led 8 7,8:W:FW:0
led 9 0,15:SD:IA:0
led 10 7,8:S:FW:0
led 11 8,8:S:FW:0
led 12 7,7:D:FW:0
led 13 8,7:D:FW:0
led 14 7,7:U:FW:0
led 15 8,7:U:FW:0
```
Which translates into the following positions:
```
6 3
\ /
\ 5-4 /
7 \ FRONT / 2
| 12-15 |
8 / BACK \ 1
/ 10-11 \
/ \
9 0
```
LEDs 0,3,6 and 9 should be placed underneath the quad, facing downwards.
LEDs 1-2, 4-5, 7-8 and 10-11 should be positioned so the face east/north/west/south, respectively.
LEDs 12-13 should be placed facing down, in the middle
LEDs 14-15 should be placed facing up, in the middle
### Exmple 28 LED config
```
# right rear cluster
led 0 9,9:S:FWT:0
led 1 10,10:S:FWT:0
led 2 11,11:S:IA:0
led 3 11,11:E:IA:0
led 4 10,10:E:AT:0
led 5 9,9:E:AT:0
# right front cluster
led 6 10,5:S:F:0
led 7 11,4:S:F:0
led 8 12,3:S:IA:0
led 9 12,2:N:IA:0
led 10 11,1:N:F:0
led 11 10,0:N:F:0
# center front cluster
led 12 7,0:N:FW:0
led 13 6,0:N:FW:0
led 14 5,0:N:FW:0
led 15 4,0:N:FW:0
# left front cluster
led 16 2,0:N:F:0
led 17 1,1:N:F:0
led 18 0,2:N:IA:0
led 19 0,3:W:IA:0
led 20 1,4:S:F:0
led 21 2,5:S:F:0
# left rear cluster
led 22 2,9:W:AT:0
led 23 1,10:W:AT:0
led 24 0,11:W:IA:0
led 25 0,11:S:IA:0
led 26 1,10:S:FWT:0
led 27 2,9:S:FWT:0
```
```
16-18 9-11
19-21 \ / 6-8
\ 12-15 /
\ FRONT /
/ BACK \
/ \
22-24 / \ 3-5
25-27 0-2
```
All LEDs should face outwards from the chassis in this configuration.
Note:
This configuration is specifically designed for the [Alien Spider AQ50D PRO 250mm frame](http://www.goodluckbuy.com/alien-spider-aq50d-pro-250mm-mini-quadcopter-carbon-fiber-micro-multicopter-frame.html).
## Troubleshooting
On initial power up the LEDs on the strip will be set to WHITE. This means you can attach a current meter to verify
the current draw if your measurement equipment is fast enough. Most 5050 LEDs will draw 0.3 Watts a piece.
This also means that you can make sure that each R,G and B LED in each LED module on the strip is also functioning.
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.

33
docs/Lights.md

@ -0,0 +1,33 @@
# Digital output for controlling lights
This features allows the control of generic non adressable lights with the `LIGHTS` flight mode. It also allows the FC to turn on or flash the lights in the case of a failsafe event.
## Custom firmware build
A custom build is required. The `USE_LIGHTS` macro must be defined in the `target.h` file corresponding to the FC this feature should be enabled on. Also the MCU pin to use as output for controlling the electronic power switch must be defined: `LIGHTS_PIN`.
Example:
```
#define USE_LIGHTS
#define LIGHTS_PIN PA1 // Use PA1 pin as output
```
## Run-time configuration
Once a flight controller board is flashed with a custom build including the previously decribed changes a new `LIGHTS` flight mode will be available. When this mode is enabled the output pin will switch to a high state and output 3.3V otherwise the pin is in the low state and connected to ground.
The default settings will also make the lights flash in the case of a failsafe event. By default a 100ms flash every second (1Hz).
Settings associated with this feature:
- `failsafe_lights` can be `ON` or `OFF`
- `failsafe_lights_flash_period` in milliseconds
- `failsafe_lights_on_time` duration of the flash for every period in milliseconds
If `failsafe_lights_on_time` is greater or equal to `failsafe_lights_flash_period` the lights will stay continuously on during the failsafe event.
## Power driver
The MCU output pins cannot drive loads greater than a few milliamperes. You will need an electronic power switch to drive the lights like the following example circuit (Don't forget the current limiting resistor(s) if you are using LEDs which don't have built-in current limiting, not included in this schematic).
### Example schematic of a N-FET based power switch capable of driving higher than 10A loads
![Example schematic](assets/images/lights_power_schematic.png)

106
docs/Mixer.md

@ -0,0 +1,106 @@
# Mixer and platform type
Mixing rules determine how servos and motors react to user and FC inputs. INAV supports various preset mixer configurations as well as custom mixing rules.
## Configuration
The mixer can be configured through the `Mixer` tab of the graphical user interface or using the CLI commands `mmix` and `smix`. `mmix` to define motor mixing rules and `smix` to define servo mixing rules.
To use a mixer preset first select the platform type then the mixer preset matching your aircraft and either press the `Load and apply` or `Load mixer` buttons. The `Load and apply` button will load the mixer, save it and ask to reboot the flight controller. The `Load mixer` button only loads the preset mixing rules, you can then edit them to suit your needs and when you are done you need to press the `Save and Reboot` button to save the rules.
Watch [this video](https://www.youtube.com/watch?v=0cLFu-5syi0) for a detailed description of the GUI and the documentation bellow for more details.
## Platform type
The platform type determines what features will be available to match the type of aircraft: available flight modes, flight modes behaviour, availability of flaps and displayed types of mixer presets. It can be set through the GUI's `Mixer tab` or through the CLI's `platform_type` setting.
Currently, following platform types are supported:
* MULTIROTOR
* AIRPLANE
* TRICOPTER
## Writing custom mixing rules
## Motor Mixing
A motor mixing rule is needed for each motor. Each rule defines weights that determine how the motor it applies to will change its speed relative to the requested throttle and flight dynamics: roll rate, pitch rate and yaw rate. The heigher a weight the more the input will have an impact on the speed of the motor. Refer to the following table for the meaning of each weight.
| Weight | Definition |
| ---------------------- | ---------- |
| THROTTLE | Speed of the motor relative to throttle. Range [0.0, 1.0]. A motor with a weight of 0.5 will receive a command that will half of a motor with a 1.0 weight |
| ROLL | Indicates how much roll authority this motor imparts to the roll rate of the aircraft. Range [-1.0, 1.0]. For fixed wing models this is usually set to 0. A positive value means that the motor needs to accelerate for a positive roll rate request (rolling right). A negative value means that the motor needs to decelerate. |
| PITCH | Indicates how much pitch authority this motor imparts to the pitch rate of the aircraft. Range [-1.0, 1.0]. For fixed wing models this is usually set to 0. A positive value means that the motor needs to accelerate for a positive pitch rate request (pitching down). A negative value means that the motor needs to decelerate. |
| YAW | Indicates how much yaw authority this motor imparts to the yaw rate of the aircraft. Range [-1.0, 1.0]. For fixed wing models with more than one motor this weight can be used to setup differential thrust. For fixed wing models with only one motor this is usually set to 0. A positive value means that the motor needs to accelerate for a positive yaw rate request (clockwise yaw seen from the top of the model). A negative value means that the motor needs to decelerate |
CLI commands to configure motor mixing rules:
The `mmix reset` command removes all the existing motor mixing rules.
The `mmix` command is used to list, create or modify rules. To list the currently defined rules run the `mmix` command without parameters.
To create or modify rules use the `mmix` command with the following syntax: `mmix <n> <throttle> <roll> <pitch> <yaw>`. `<n>` is representing the index of the motor output pin (integer). The other parameters are decimal weights for each of the inputs. To disable a mixing rule set the `throttle` weight to 0.
## Servo Mixing
At least one servo mixing rule is needed for each servo. Each rule defines how a servo will move relative to a specific input like a RC channel, or a requested flight dynamics rate or position from the flight controller.
Each servo mixing rule has the following parameters:
* Servo index: defines which servo the rule will apply to. The absolute value of the index is not important, what matters is only the relative difference between the used indexes. The rule with the smaller servo index will apply to the first servo, the next higher servo index to the second servo, etc. More than one rule can use the same servo index. The output of the rules with the same servo index are added together to give the final output for the specified servo.
* Input: the input for the mixing rule, see a summary of the input types table bellow.
* Weight: percentage of the input to forward to the servo. Range [-1000, 1000]. Mixing rule output = input * weight. If the output of a set of mixing rules is lower/higher than the defined servo min/max the output is clipped (the servo will never travel farther than the set min/max).
* Speed: maximum rate of change of the mixing rule output. Used to limit the servo speed. 1 corresponds to maximum 10µs/s output rate of change. Set to 0 for no speed limit. For example: 10 = full sweep (1000 to 2000) in 10s, 100 = full sweep in 1s.
| CLI input ID | Mixer input | Description |
|----|--------------------------|------------------------------------------------------------------------------|
| 0 | Stabilised ROLL | Roll command from the flight controller. Depends on the selected flight mode(s) |
| 1 | Stabilised PITCH | Pitch command from the flight controller. Depends on the selected flight mode(s) |
| 2 | Stabilised YAW | Yaw command from the flight controller. Depends on the selected flight mode(s) |
| 3 | Stabilised THROTTLE | Throttle command from the flight controller. Depends on the selected flight mode(s) |
| 4 | RC ROLL | Raw roll RC channel |
| 5 | RC PITCH | Raw pitch RC channel |
| 6 | RC YAW | Raw yaw RC channel |
| 7 | RC THROTTLE | Raw throttle RC channel |
| 8 | RC channel 5 | Raw RC channel 5 |
| 9 | RC channel 6 | Raw RC channel 6 |
| 10 | RC channel 7 | Raw RC channel 7 |
| 11 | RC channel 8 | Raw RC channel 8 |
| 12 | GIMBAL PITCH | Scaled pitch attitude of the aircraft [-90°, 90°] => [-500, 500] |
| 13 | GIMBAL ROLL | Scaled roll attitude of the aircraft [-180°, 180°] => [-500, 500] |
| 14 | FEATURE FLAPS | This input value is equal to the `flaperon_throw_offset` setting when the `FLAPERON` flight mode is enabled, 0 otherwise |
| 15 | RC channel 9 | Raw RC channel 9 |
| 16 | RC channel 10 | Raw RC channel 10 |
| 17 | RC channel 11 | Raw RC channel 11 |
| 18 | RC channel 12 | Raw RC channel 12 |
| 19 | RC channel 13 | Raw RC channel 13 |
| 20 | RC channel 14 | Raw RC channel 14 |
| 21 | RC channel 15 | Raw RC channel 15 |
| 22 | RC channel 16 | Raw RC channel 16 |
| 23 | Stabilized ROLL+ | Clipped between 0 and 1000 |
| 24 | Stabilized ROLL- | Clipped between -1000 and 0 |
| 25 | Stabilized PITCH+ | Clipped between 0 and 1000 |
| 26 | Stabilized PITCH- | Clipped between -1000 and 0 |
| 27 | Stabilized YAW+ | Clipped between 0 and 1000 |
| 28 | Stabilized YAW- | Clipped between -1000 and 0 |
| 29 | MAX | Constant value of 500 |
The `smix reset` command removes all the existing motor mixing rules.
The `smix` command is used to list, create or modify rules. To list the currently defined rules run the `smix` command without parameters.
To create or modify rules use the `smix` command with the following syntax: `smix <n> <servo_index> <input_id> <weight> <speed> <logic_condition_id>`. `<n>` is representing the index of the servo mixing rule to create or modify (integer). To disable a mixing rule set the weight to 0.
`logic_condition_id` default value is `-1` for rules that should be always executed.
### Logic Conditions
[Logic Conditions](Logic%20Conditions.md) allows to activate/deactivate `smix` rules based on user input and flight parameters. If Logic Condition evaluates as `false`, smix rule connected with with LC will not be active and used inside the Mixer.
This mechanism allows to move servos when desired conditions are met. For example, if an airplane is equipped with a pitot tube and flaps, flaps can be automatically deployed when airspeed goes below a threshold.
Other usages can be:
* automatic parachute deployment
* VTOL and especially tail-sitters that require change in mixings during flight mode transition
* crowbar airbrakes
* any kind of servo mixings that should be changed during flight

112
docs/Navigation.md

@ -0,0 +1,112 @@
# Navigation
The navigation system in INAV is responsible for assisting the pilot allowing altitude and position hold, return-to-home and waypoint flight.
## NAV ALTHOLD mode - altitude hold
Altitude hold requires a valid source of altitude - barometer, GPS or rangefinder. The best source is chosen automatically. GPS is available as an altitude source for airplanes only.
In this mode THROTTLE stick controls climb rate (vertical velocity). When pilot moves stick up - quad goes up, pilot moves stick down - quad descends, you keep stick at neutral position - quad hovers.
### CLI parameters affecting ALTHOLD mode:
* *nav_use_midthr_for_althold* - when set to "0", firmware will remember where your throttle stick was when ALTHOLD was activated - this will be considered neutral position. When set to "1" - 50% throttle will be considered neutral position.
### Related PIDs
PIDs affecting altitude hold: ALT & VEL
PID meaning:
* ALT - translates altitude error to desired climb rate and acceleration. Tune P for altitude-to-velocity regulator and I for velocity-to-acceleration regulator
* VEL - translated Z-acceleration error to throttle adjustment
## Throttle tilt compensation
Throttle tilt compensation attempts to maintain constant vertical thrust when copter is tilted giving additional throttle if tilt angle (pitch/roll) is not zero. Controlled by *throttle_tilt_comp_str* CLI variable.
## NAV POSHOLD mode - position hold
Position hold requires GPS, accelerometer and compass sensors. Flight modes that require a compass (POSHOLD, RTH) are locked until compass is properly calibrated.
When activated, this mode will attempt to keep copter where it is (based on GPS coordinates). From inav 2.0, POSHOLD is a full 3D position hold. Heading hold in this mode is assumed and activated automatically.
### CLI parameters affecting POSHOLD mode:
* *nav_user_control_mode* - can be set to "0" (GPS_ATTI) or "1" (GPS_CRUISE), controls how firmware will respond to roll/pitch stick movement. When in GPS_ATTI mode, right stick controls attitude, when it is released, new position is recorded and held. When in GPS_CRUISE mode right stick controls velocity and firmware calculates required attitude on its own.
### Related PIDs
PIDs affecting position hold: POS, POSR
PID meaning:
* POS - translated position error to desired velocity, uses P term only
* POSR - translates velocity error to desired acceleration
## NAV RTH - return to home mode
Home for RTH is the position where vehicle was armed. This position may be offset by the CLI settings `nav_rth_home_offset_distance` and `nav_rth_home_offset_direction`. RTH requires accelerometer, compass and GPS sensors.
If barometer is NOT present, RTH will fly directly to home, altitude control here is up to pilot.
If barometer is present, RTH will maintain altitude during the return and when home is reached copter will attempt automated landing.
When deciding what altitude to maintain, RTH has 4 different modes of operation (controlled by *nav_rth_alt_mode* and *nav_rth_altitude* cli variables):
* 0 (NAV_RTH_NO_ALT) - keep current altitude during whole RTH sequence (*nav_rth_altitude* is ignored)
* 1 (NAV_RTH_EXTRA_ALT) - climb to current altitude plus extra margin prior to heading home (*nav_rth_altitude* defines the extra altitude (cm))
* 2 (NAV_RTH_CONST_ALT) - climb/descend to predefined altitude before heading home (*nav_rth_altitude* defined altitude above launch point (cm))
* 3 (NAV_RTH_MAX_ALT) - track maximum altitude of the whole flight, climb to that altitude prior to the return (*nav_rth_altitude* is ignored)
* 4 (NAV_RTH_AT_LEAST_ALT) - same as 2 (NAV_RTH_CONST_ALT), but only climb, do not descend
## CLI command `wp` to manage waypoints
`wp` - List all waypoints.
`wp load` - Load list of waypoints from EEPROM to FC.
`wp <n> <action> <lat> <lon> <alt> <p1> <p2> <p3> <flag>` - Set parameters of waypoint with index `<n>`. Note that prior to inav 2.5, the `p2` and `p3` parameters were not required. From 2.5, inav will accept either version but always saves and lists the later full version.
Parameters:
* `<action>` - The action to be taken at the WP. The following are enumerations are available in inav 2.6 and later:
* 0 - Unused / Unassigned
* 1 - WAYPOINT
* 3 - POSHOLD_TIME
* 4 - RTH
* 5 - SET_POI
* 6 - JUMP
* 7 - SET_HEAD
* 8 - LAND
* `<lat>` - Latitude (WGS84), in degrees * 1E7 (for example 123456789 means 12.3456789).
* `<lon>` - Longitude.
* `<alt>` - Altitude in cm.
* `<p1>` - For a RTH waypoint, p1 > 0 enables landing. For a normal waypoint it is the speed to this waypoint (cm/s), it is taken into account only for multicopters and when > 50 and < nav_auto_speed. For POSHOLD TIME waypoint it is time to loiter in seconds. For JUMP it is the target WP **index** (not number). For SET_HEAD, it is the desired heading (0-359) or -1 to cancel a previous SET_HEAD or SET_POI.
* `<p2>` - For a POSHOLD TIME it is the speed to this waypoint (cm/s), it is taken into account only for multicopters and when > 50 and < nav_auto_speed. For JUMP it is the number of iterations of the JUMP.
* `<p3>` - Reserved for future use. If `p2` is provided, then `p3` is also required.
* `<flag>` - Last waypoint must have set `flag` to 165 (0xA5), otherwise 0.
`wp save` - Checks list of waypoints and save from FC to EEPROM (warning: it also saves all unsaved CLI settings like normal `save`).
`wp reset` - Resets the list, sets the number of waypoints to 0 and marks the list as invalid (but doesn't delete the waypoint definitions).
### `wp` example
```
# wp load
# wp
# wp 11 valid
wp 0 1 543533193 -45179273 3500 0 0 0 0
wp 1 1 543535723 -45193913 3500 0 0 0 0
wp 2 1 543544541 -45196617 5000 0 0 0 0
wp 3 1 543546578 -45186895 5000 0 0 0 0
wp 4 6 0 0 0 1 2 0 0
wp 5 1 543546688 -45176009 3500 0 0 0 0
wp 6 1 543541225 -45172673 3500 0 0 0 0
wp 7 6 0 0 0 0 1 0 0
wp 8 3 543531383 -45190405 3500 45 0 0 0
wp 9 1 543548470 -45182104 3500 0 0 0 0
wp 10 8 543540521 -45178091 6000 0 0 0 165
wp 11 0 0 0 0 0 0 0 0
...
wp 59 0 0 0 0 0 0 0 0
```
Note that the `wp` CLI command shows waypoint list indices, while the MW-XML definition used by mwp, ezgui and the configurator use WP numbers.

79
docs/PID tuning.md

@ -0,0 +1,79 @@
# PID tuning
Every aspect of flight dynamics is controlled by the selected "PID controller". This is an algorithm which is
responsible for reacting to your stick inputs and keeping the craft stable in the air by using the gyroscopes and/or
accelerometers (depending on your flight mode).
The "PIDs" are a set of tuning parameters which control the operation of the PID controller. The optimal PID settings
to use are different on every craft, so if you can't find someone with your exact setup who will share their settings
with you, some trial and error is required to find the best performing PID settings.
A video on how to recognise and correct different flight problems caused by PID settings is available here:
https://www.youtube.com/watch?v=YNzqTGEl2xQ
Basically, the goal of the PID controller is to bring the craft's rotation rate in all three axes to the rate that
you're commanding with your sticks. An error is computed which is the difference between your target rotation rate and
the actual one measured by the gyroscopes, and the controller tries to bring this error to zero.
Note that:
* For fixed wing, a PIFF controller is used. Some documentation is available in the wiki and legacy release notes.
* The iNav Configurator provides conservative example PID settings for various aircraft types. These will require tuning to a particular machine.
## PIDs
**The P term** controls the strength of the correction that is applied to bring the craft toward the target angle or
rotation rate. If the P term is too low, the craft will be difficult to control as it won't respond quickly enough to
keep itself stable. If it is set too high, the craft will rapidly oscillate/shake as it continually overshoots its
target.
**The I term** corrects small, long term errors. If it is set too low, the craft's attitude will slowly drift. If it is
set too high, the craft will oscillate (but with slower oscillations than with P being set too high).
**The D term** attempts to increase system stability by monitoring the rate of change in the error. If the error is rapidly converging to zero, the D term causes the strength of the correction to be backed off in order to avoid overshooting the target.
## TPA and TPA Breakpoint
TPA stands for Throttle PID Attenuation and according to [AlexYork.net](http://blog.alexyorke.net/what-is-tpa/):
> "TPA basically allows an aggressively tuned multi-rotor (one that feels very locked in) to reduce its PID gains when throttle is applied beyond the TPA threshold/breakpoint in order to eliminate fast oscillations.."
Note that TPA is set via CLI or on the PID TUNING tab of the GUI. tpa_breakpoint is set via CLI
Also note that TPA and tpa_breakpoint may not be used in certain PID Controllers. Check the description on the individual controller.
TPA applies a PID value reduction in relation to full Throttle. It is used to apply dampening of PID values as full throttle is reached.
**TPA** = % of dampening that will occur at full throttle.
**tpa_breakpoint** = the point in the throttle curve at which TPA will begin to be applied.
An Example: With TPA = 50 (or .5 in the GUI) and tpa_breakpoint = 1500 (assumed throttle range 1000 - 2000)
* At 1500 on the throttle channel, the PIDs will begin to be dampened.
* At 3/4 throttle (1750), PIDs are reduced by approximately 25% (half way between 1500 and 2000 the dampening will be 50% of the total TPA value of 50% in this example)
* At full throttle (2000) the full amount of dampening set in TPA is applied. (50% reduction in this example)
* TPA can lead into increase of rotation rate when more throttle applied.
![tpa example chart](https://cloud.githubusercontent.com/assets/1668170/6053290/655255dc-ac92-11e4-9491-1a58d868c131.png "TPA Example Chart")
**How and Why to use this?**
If you are getting oscillations starting at say 3/4 throttle, set tpa breakpoint = 1750 or lower (remember, this is assuming your throttle range is 1000-2000), and then slowly increase TPA until your oscillations are gone. Usually, you will want tpa breakpoint to start a little sooner then when your oscillations start so you'll want to experiment with the values to reduce/remove the oscillations.
## PID controllers
INAV has a single built-in PID controller. The PID controller scaling
means that Betaflight PIDs should be comparable.
Note that very old INAV versions had more PID controllers. These have been removed.
## RC rate, Pitch and Roll Rates (P/R rate before they were separated), and Yaw rate
### RC Rate
An overall multiplier on the RC stick inputs for pitch, rol;, and yaw.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save