Updated INAV Remote Management, Control and Telemetry (markdown)
[inav.wiki.git] / Building-custom-firmware.md
blob14f18ef655ffee6d520a70cdf3e813871e9ef2e5
1 # Rationale
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.
7 # Prerequisite
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
13 ## Overview
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.
19 ```
20 $ cd inav/src/main/target
21 $ ls QUARKVISION
22 CMakeFiles           CMakeLists.txt  README.md  target.h
23 cmake_install.cmake  config.c        target.c
24 ```
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). 
34 ### `CMakeLists.txt` 
36 The `QUARKVISION` example contains a single line:
38 ```
39 target_stm32f405xg(QUARKVISION HSE_MHZ 16 SKIP_RELEASES)
40 ```
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:
48 ```
49 target_stm32f405xg(QUARKVISION_V2 HSE_MHZ 16 SKIP_RELEASES)
50 ```
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.
56 ## `target.h` 
58 `target.h` contains hardware definitions, a fragment is below:
60 ```
61 #pragma once
63 #define TARGET_BOARD_IDENTIFIER "QRKV"
64 #define USBD_PRODUCT_STRING "QuarkVision"
66 ...
68 #define BEEPER                  PC15
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
80 // MPU6000 interrupts
81 #define USE_EXTI
82 #define GYRO_INT_EXTI            PC0
83 #define USE_MPU_DATA_READY_SIGNAL
85 //*************** MAG *****************************
87 #define USE_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
94 ...
95 ```
97 Of note:
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"
104 #else
105 # define TARGET_BOARD_IDENTIFIER "QRKV"
106 #endif
109 This pattern is required for each variation and the features affected by the variation.
111 The file fragment then defines hardware options:
112 * Pins, Busses
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.
117 ### `target.c`
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
142 The parameters are:
144 * `TIMn`: The timer
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`.
154 ## Further reading
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.
169 ### Building
171 Build the target.
174 $ make -j  $(nproc) QUARKVISION
175 ## or (using ninja as the build manager)
176 $ ninja QUARKVISION
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%
185        MEMORY_B1:          0 GB         0 GB
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.)
198 git pull
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.