3 Prebuilt targets may not include the features you wish to use. If a target already exists, it is relatively simple to build your own custom firmware.
5 This guide provides a high level overview. It is **not** a detailed development guide.
9 You need a working development environment. There is [developer / build environment documentation](https://github.com/iNavFlight/inav/tree/master/docs/development) for the major platforms (Linux, MacOS, Windows).
11 # Target Specific Files
15 For basic configuration changes, the files are found under `src/main/targets/NAME`. At the top level this includes a separate directory for each target.
17 This article considers a prototype flight controller `QUARKVISION` that was never put into production.
20 $ cd inav/src/main/target
22 CMakeFiles CMakeLists.txt README.md target.h
23 cmake_install.cmake config.c target.c
26 The `CMakefles` directory and `cmake_install.cmake` are generated by the build system; the other files are:
28 * `CMakeLists.txt` : Mandatory, defines the target name and variants
29 * `README.md` : Optional, information about the target
30 * `target.h` : Mandatory, defines capabilities and definitions (e.g. sensors, pin definitions)
31 * `target.c` : Mandatory, defines timers and usage (e.g. for motors and servos)
32 * `config.c` : Mandatory, defines configuration defaults (RX type etc).
36 The `QUARKVISION` example contains a single line:
39 target_stm32f405xg(QUARKVISION HSE_MHZ 16 SKIP_RELEASES)
41 Here is the definition for:
42 * The processor class `stm32f405xg`
43 * The target name `QUARKVISION`
44 * Additional parameters `HSE_MHZ 16` (an optional parameter defining a non-default high-speed external (HSE) oscillator clock required by this board) and `SKIP_RELEASES` as this is not an official target.
46 If we had other variants, for example a V2 variant with different sensors, we could add another line, for example:
49 target_stm32f405xg(QUARKVISION_V2 HSE_MHZ 16 SKIP_RELEASES)
52 We can then reference the `QUARKVISION_V2` in `target.c` or `target.h` to handle the different capabilities of each variation.
54 See [the developer documentation](https://github.com/iNavFlight/inav/blob/master/docs/development/Cmake%20usage.md) for more information, including a more detailed `CMakeLists.txt` and a list of processor options.
58 `target.h` contains hardware definitions, a fragment is below:
63 #define TARGET_BOARD_IDENTIFIER "QRKV"
64 #define USBD_PRODUCT_STRING "QuarkVision"
69 #define BEEPER_INVERTED
70 #define USE_UART_INVERTER
71 #define INVERTER_PIN_UART2 PB2 // PB2 used as inverter select GPIO
72 #define INVERTER_PIN_UART2_RX PB2 // PB2 used as inverter select GPIO
74 #define MPU6000_CS_PIN PC1
75 #define MPU6000_SPI_BUS BUS_SPI2
77 #define USE_IMU_MPU6000
78 #define IMU_MPU6000_ALIGN CW270_DEG
82 #define GYRO_INT_EXTI PC0
83 #define USE_MPU_DATA_READY_SIGNAL
85 //*************** MAG *****************************
88 #define MAG_I2C_BUS BUS_I2C3
89 #define USE_MAG_HMC5883
90 #define USE_MAG_MAG3110
91 #define USE_MAG_QMC5883
92 #define USE_MAG_AK8963
93 #define USE_MAG_AK8975
99 * `TARGET_BOARD_IDENTIFIER` this should be unique in the first **4 bytes**. If the mythical `QUARKVISION_V2` existed, it would need a separate ID. For example:
102 #if defined(QUARKVISION_V2)
103 # define TARGET_BOARD_IDENTIFIER "QVV2"
105 # define TARGET_BOARD_IDENTIFIER "QRKV"
109 This pattern is required for each variation and the features affected by the variation.
111 The file fragment then defines hardware options:
113 * Sensors, for example the `#define USE_MAG` stanza which defines the `MAG_I2C_BUS` I2C bus for the compass, and the different compass types supported on this board.
115 There will similar stanzas for all the available sensor components.
119 `target.c` defines the timer and channel usage. The association between timers and channels is provided by the vendor MCU documentation. This defines an array of `timerHardware_t`, in turn defined by the `DEF_TIM` (define timer) macro.
123 timerHardware_t timerHardware[] = {
124 DEF_TIM(TIM1, CH3, PA10, TIM_USE_PPM, 0, 0), // S1_IN_PPM A01
125 DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0), // SSERIAL1 RX c07
126 DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0), // SSERIAL1 TX
127 DEF_TIM(TIM2, CH1, PA15, 0, 0, 0), // LED A15
128 DEF_TIM(TIM3, CH3, PB0, TIM_USE_OUTPUT_AUTO, 0, 0), // S1_OUT
129 DEF_TIM(TIM3, CH4, PB1, TIM_USE_OUTPUT_AUTO, 0, 0), // S2_OUT
130 DEF_TIM(TIM12, CH1, PB14, TIM_USE_OUTPUT_AUTO, 0, 0), // S3_OUT
131 DEF_TIM(TIM12, CH2, PB15, TIM_USE_OUTPUT_AUTO, 0, 0), // S4_OUT
132 DEF_TIM(TIM11, CH1, PB9, TIM_USE_OUTPUT_AUTO, 0, 0), // S5_OUT
133 DEF_TIM(TIM10, CH1, PB8, TIM_USE_OUTPUT_AUTO, 0, 0), // S6_OUT
134 DEF_TIM(TIM3, CH2, PB5, TIM_USE_OUTPUT_AUTO, 0, 0), // S7_OUT
135 DEF_TIM(TIM3, CH1, PB4, TIM_USE_OUTPUT_AUTO, 0, 0), // S8_OUT
136 DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S9_OUT
137 DEF_TIM(TIM2, CH2, PB3, TIM_USE_OUTPUT_AUTO, 0, 0), // S10_OUT
145 * `CHn` : The channel
146 * `Pxy` : The hardware (MCU) pin
147 * The usage function(s) available in this pin. Note that each timer is assigned a rate defined by function, so it is inadvisable to have both `MOTOR` and `SERVO` definition on the same timer. `TIM_USE_OUTPUT_AUTO` will let INAV assign the output to either `MOTOR` or `SERVO` automatically.
148 * The final two parameters (`flags`, `dmavar` are hardware specific / required for DMA (e.g. DSHOT), which is turn is defined by `#define USE_DSHOT` in `target.h`. See vendor's technical definitions perhaps compared to comparable targets. The example target here does not define `USE_DSHOT` and the values are 0. These parameters provide a DMA descriptor table compatible with Betaflight.
150 ## Adding a new source file
152 If a new source file is added **outside of the `target/NAME` directory**, it must be added to the top level `src/main/CMakeLists.txt`.
156 * Read the fine source, base your target / changes on a **supported target** with similar characteristics
157 * Read the [developer / build environment documentation](https://github.com/iNavFlight/inav/tree/master/docs/development)
159 ## Other recommendations
161 ### Use a separate branch
164 $ git checkout -b my_super_special_branch
167 This will isolate your work from the base repo and facilitate making a pull request if you decide to contribute your changes back to the project.
174 $ make -j $(nproc) QUARKVISION
175 ## or (using ninja as the build manager)
178 [365/366] Linking C executable bin/QUARKVISION.elf
179 Memory region Used Size Region Size %age Used
180 FLASH: 519160 B 896 KB 56.58%
181 FLASH_CONFIG: 0 GB 128 KB 0.00%
182 RAM: 76476 B 128 KB 58.35%
183 CCM: 13852 B 64 KB 21.14%
184 BACKUP_SRAM: 0 GB 4 KB 0.00%
186 [366/366] cd /home/jrh/Projects/fc/ina.../inav/build/inav_6.0.0_QUARKVISION.hex
189 ## Fix any errors / warnings
191 If you changes introduce compiler warnings, please fix them. Submissions (pull requests) with compiler errors / warnings will not be accepted. If your changes overflow the flash size, consider removing unwanted features in `target.h`. Your `target.h` can always `#undef` generic features from `src/main/target/common.h` (e.g. unwanted RX or telemetry options).
193 ## Commit your changes
195 You can now commit the changes to your branch, e.g. `git commit -a -m "my descriptive commit message"` ; otherwise if one wanted to update to the upstream the source tree (e.g.)
201 git will complain that there are uncommitted changes and won't perform the update.
202 * Commit to your private branch as above ; or
203 * `$ git reset --hard` before pulling ; or
204 * Stash away the original files and restore them after pulling.
206 The developer documentation has more information on synchronising a custom branch with upstream Github.
208 ## Other tools and resources
210 ### Migrate Betaflight Targets
212 There is a [script in the repo](https://github.com/iNavFlight/inav/blob/mosca-target-converter/src/utils/bf2inav.py) that can help automate conversion of Betaflight targets to INAV. The developer, @mosca, will be grateful for any reports of success (or failure).
214 Paweł Spychalski has also made YouTube videos on the subject.