2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
23 #include <drivers/vtx_table.h>
27 #if defined(USE_VTX_CONTROL) && defined(USE_VTX_COMMON)
29 #include "common/maths.h"
31 #include "config/config_eeprom.h"
33 #include "drivers/buttons.h"
34 #include "drivers/light_led.h"
35 #include "drivers/time.h"
36 #include "drivers/vtx_common.h"
38 #include "config/config.h"
39 #include "fc/runtime_config.h"
41 #include "io/spektrum_vtx_control.h"
43 #include "io/vtx_control.h"
48 #include "pg/pg_ids.h"
51 PG_REGISTER_WITH_RESET_TEMPLATE(vtxConfig_t
, vtxConfig
, PG_VTX_CONFIG
, 1);
53 PG_RESET_TEMPLATE(vtxConfig_t
, vtxConfig
,
54 // .vtxChannelActivationConditions = { 0 },
58 static uint8_t locked
= 0;
61 void vtxControlInit(void)
66 void vtxControlInputPoll(void)
68 // Check variuos input sources for VTX config updates
69 #if defined(USE_SPEKTRUM_VTX_CONTROL)
75 static void vtxUpdateBandAndChannel(uint8_t bandStep
, uint8_t channelStep
)
77 if (ARMING_FLAG(ARMED
)) {
81 if (!locked
&& vtxCommonDevice()) {
82 vtxSettingsConfigMutable()->band
+= bandStep
;
83 vtxSettingsConfigMutable()->channel
+= channelStep
;
87 void vtxIncrementBand(void)
89 vtxUpdateBandAndChannel(+1, 0);
92 void vtxDecrementBand(void)
94 vtxUpdateBandAndChannel(-1, 0);
97 void vtxIncrementChannel(void)
99 vtxUpdateBandAndChannel(0, +1);
102 void vtxDecrementChannel(void)
104 vtxUpdateBandAndChannel(0, -1);
107 void vtxUpdateActivatedChannel(void)
109 if (ARMING_FLAG(ARMED
)) {
113 if (vtxCommonDevice()) {
114 static uint8_t lastIndex
= -1;
116 for (uint8_t index
= 0; index
< MAX_CHANNEL_ACTIVATION_CONDITION_COUNT
; index
++) {
117 const vtxChannelActivationCondition_t
*vtxChannelActivationCondition
= &vtxConfig()->vtxChannelActivationConditions
[index
];
119 if (isRangeActive(vtxChannelActivationCondition
->auxChannelIndex
, &vtxChannelActivationCondition
->range
)
120 && index
!= lastIndex
) {
124 if (vtxChannelActivationCondition
->band
> 0) {
125 vtxSettingsConfigMutable()->band
= vtxChannelActivationCondition
->band
;
127 if (vtxChannelActivationCondition
->channel
> 0) {
128 vtxSettingsConfigMutable()->channel
= vtxChannelActivationCondition
->channel
;
132 if (vtxChannelActivationCondition
->power
> 0) {
133 vtxSettingsConfigMutable()->power
= vtxChannelActivationCondition
->power
;
141 void vtxCycleBandOrChannel(const uint8_t bandStep
, const uint8_t channelStep
)
143 const vtxDevice_t
*vtxDevice
= vtxCommonDevice();
145 uint8_t band
= 0, channel
= 0;
147 const bool haveAllNeededInfo
= vtxCommonGetBandAndChannel(vtxDevice
, &band
, &channel
);
148 if (!haveAllNeededInfo
) {
152 int newChannel
= channel
+ channelStep
;
153 if (newChannel
> vtxTableChannelCount
) {
155 } else if (newChannel
< 1) {
156 newChannel
= vtxTableChannelCount
;
159 int newBand
= band
+ bandStep
;
160 if (newBand
> vtxTableBandCount
) {
162 } else if (newBand
< 1) {
163 newBand
= vtxTableBandCount
;
166 vtxSettingsConfigMutable()->band
= newBand
;
167 vtxSettingsConfigMutable()->channel
= newChannel
;
171 void vtxCyclePower(const uint8_t powerStep
)
173 const vtxDevice_t
*vtxDevice
= vtxCommonDevice();
176 const bool haveAllNeededInfo
= vtxCommonGetPowerIndex(vtxDevice
, &power
);
177 if (!haveAllNeededInfo
) {
181 int newPower
= power
+ powerStep
;
182 if (newPower
>= vtxTablePowerLevels
) {
184 } else if (newPower
< 0) {
185 newPower
= vtxTablePowerLevels
;
188 vtxSettingsConfigMutable()->power
= newPower
;
193 * Allow VTX channel/band/rf power/on-off and save via a single button.
195 * The LED1 flashes a set number of times, followed by a short pause, one per second. The amount of flashes decreases over time while
196 * the button is held to indicate the action that will be performed upon release.
197 * The actions are ordered by most-frequently used action. i.e. you change channel more frequently than band.
199 * The vtx settings can be changed while the VTX is OFF.
200 * If the VTX is OFF when the settings are saved the VTX will be OFF on the next boot, likewise
201 * If the VTX is ON when the settings are saved the VTX will be ON on the next boot.
203 * Future: It would be nice to re-use the code in statusindicator.c and blink-codes but target a different LED instead of the simple timed
204 * behaviour of the LED1 here.
206 * Future: Blink out the state after changing it.
208 void handleVTXControlButton(void)
210 #if defined(USE_VTX_RTC6705) && defined(BUTTON_A_PIN)
211 bool buttonWasPressed
= false;
212 const timeMs_t start
= millis();
213 timeMs_t ledToggleAt
= start
;
214 bool ledEnabled
= false;
215 uint8_t flashesDone
= 0;
217 uint8_t actionCounter
= 0;
219 while ((buttonHeld
= buttonAPressed())) {
220 const timeMs_t end
= millis();
222 int32_t diff
= cmp32(end
, start
);
223 if (diff
> 25 && diff
<= 1000) {
225 } else if (diff
> 1000 && diff
<= 3000) {
227 } else if (diff
> 3000 && diff
<= 5000) {
229 } else if (diff
> 5000) {
235 diff
= cmp32(ledToggleAt
, end
);
238 ledEnabled
= !ledEnabled
;
240 const uint8_t updateDuration
= 60;
242 ledToggleAt
= end
+ updateDuration
;
251 if (flashesDone
== actionCounter
) {
252 ledToggleAt
+= (1000 - ((flashesDone
* updateDuration
) * 2));
256 buttonWasPressed
= true;
260 if (!buttonWasPressed
) {
266 switch (actionCounter
) {
268 vtxCycleBandOrChannel(0, +1);
271 vtxCycleBandOrChannel(+1, 0);
277 saveConfigAndNotify();