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/>.
21 /* Created by jflyper */
30 #if defined(USE_VTX_COMMON)
32 #include "common/time.h"
33 #include "drivers/vtx_common.h"
34 #include "drivers/vtx_table.h"
37 static vtxDevice_t
*vtxDevice
= NULL
;
38 static uint8_t selectedBand
= 0;
39 static uint8_t selectedChannel
= 0;
41 void vtxCommonInit(void)
45 void vtxCommonSetDevice(vtxDevice_t
*pDevice
)
50 vtxDevice_t
*vtxCommonDevice(void)
55 vtxDevType_e
vtxCommonGetDeviceType(const vtxDevice_t
*vtxDevice
)
58 return VTXDEV_UNKNOWN
;
60 return vtxDevice
->vTable
->getDeviceType(vtxDevice
);
63 bool vtxCommonDeviceIsReady(const vtxDevice_t
*vtxDevice
)
65 if (vtxDevice
&& vtxDevice
->vTable
->isReady
) {
66 return vtxDevice
->vTable
->isReady(vtxDevice
);
72 void vtxCommonProcess(vtxDevice_t
*vtxDevice
, timeUs_t currentTimeUs
)
75 vtxDevice
->vTable
->process(vtxDevice
, currentTimeUs
);
79 // band and channel are 1 origin
80 void vtxCommonSetBandAndChannel(vtxDevice_t
*vtxDevice
, uint8_t band
, uint8_t channel
)
82 uint16_t freq
= vtxCommonLookupFrequency(vtxDevice
, band
, channel
);
84 selectedChannel
= channel
;
86 if (vtxTableIsFactoryBand
[band
- 1]) {
87 vtxDevice
->vTable
->setBandAndChannel(vtxDevice
, band
, channel
);
89 vtxDevice
->vTable
->setFrequency(vtxDevice
, freq
);
94 // index is one origin, zero = unknown power level
95 void vtxCommonSetPowerByIndex(vtxDevice_t
*vtxDevice
, uint8_t index
)
97 if (index
<= vtxTablePowerLevels
) {
98 vtxDevice
->vTable
->setPowerByIndex(vtxDevice
, index
);
103 void vtxCommonSetPitMode(vtxDevice_t
*vtxDevice
, uint8_t onOff
)
105 vtxDevice
->vTable
->setPitMode(vtxDevice
, onOff
);
108 void vtxCommonSetFrequency(vtxDevice_t
*vtxDevice
, uint16_t frequency
)
112 vtxDevice
->vTable
->setFrequency(vtxDevice
, frequency
);
115 bool vtxCommonGetBandAndChannel(const vtxDevice_t
*vtxDevice
, uint8_t *pBand
, uint8_t *pChannel
)
117 bool result
= vtxDevice
->vTable
->getBandAndChannel(vtxDevice
, pBand
, pChannel
);
118 if ((!result
|| (*pBand
== 0 && *pChannel
== 0)) && selectedBand
!= 0 && selectedChannel
!= 0
119 && !vtxTableIsFactoryBand
[selectedBand
- 1]) {
121 result
= vtxCommonGetFrequency(vtxDevice
, &freq
);
123 vtxCommonLookupBandChan(vtxDevice
, freq
, pBand
, pChannel
);
129 bool vtxCommonGetPowerIndex(const vtxDevice_t
*vtxDevice
, uint8_t *pIndex
)
131 return vtxDevice
->vTable
->getPowerIndex(vtxDevice
, pIndex
);
134 bool vtxCommonGetFrequency(const vtxDevice_t
*vtxDevice
, uint16_t *pFrequency
)
136 return vtxDevice
->vTable
->getFrequency(vtxDevice
, pFrequency
);
139 bool vtxCommonGetStatus(const vtxDevice_t
*vtxDevice
, unsigned *status
)
141 return vtxDevice
->vTable
->getStatus(vtxDevice
, status
);
144 uint8_t vtxCommonGetVTXPowerLevels(const vtxDevice_t
*vtxDevice
, uint16_t *levels
, uint16_t *powers
)
146 return vtxDevice
->vTable
->getPowerLevels(vtxDevice
, levels
, powers
);
149 const char *vtxCommonLookupBandName(const vtxDevice_t
*vtxDevice
, int band
)
151 if (vtxDevice
&& band
> 0 && band
<= vtxTableBandCount
) {
152 return vtxTableBandNames
[band
];
158 char vtxCommonLookupBandLetter(const vtxDevice_t
*vtxDevice
, int band
)
160 if (vtxDevice
&& band
> 0 && band
<= vtxTableBandCount
) {
161 return vtxTableBandLetters
[band
];
167 const char *vtxCommonLookupChannelName(const vtxDevice_t
*vtxDevice
, int channel
)
169 if (vtxDevice
&& channel
> 0 && channel
<= vtxTableChannelCount
) {
170 return vtxTableChannelNames
[channel
];
176 //Converts frequency (in MHz) to band and channel values.
177 //If frequency not found in the vtxtable then band and channel will return 0
178 void vtxCommonLookupBandChan(const vtxDevice_t
*vtxDevice
, uint16_t freq
, uint8_t *pBand
, uint8_t *pChannel
)
183 // Use reverse lookup order so that 5880Mhz
184 // get Raceband 7 instead of Fatshark 8.
185 for (int band
= vtxTableBandCount
- 1 ; band
>= 0 ; band
--) {
186 for (int channel
= 0 ; channel
< vtxTableChannelCount
; channel
++) {
187 if (vtxTableFrequency
[band
][channel
] == freq
) {
189 *pChannel
= channel
+ 1;
197 //Converts band and channel values to a frequency (in MHz) value.
198 // band: Band value (1 to 5).
199 // channel: Channel value (1 to 8).
200 // Returns frequency value (in MHz), or 0 if band/channel out of range.
201 uint16_t vtxCommonLookupFrequency(const vtxDevice_t
*vtxDevice
, int band
, int channel
)
204 if (band
> 0 && band
<= vtxTableBandCount
&&
205 channel
> 0 && channel
<= vtxTableChannelCount
) {
206 return vtxTableFrequency
[band
- 1][channel
- 1];
213 const char *vtxCommonLookupPowerName(const vtxDevice_t
*vtxDevice
, int index
)
215 if (vtxDevice
&& index
> 0 && index
<= vtxTablePowerLevels
) {
216 return vtxTablePowerLabels
[index
];
222 bool vtxCommonLookupPowerValue(const vtxDevice_t
*vtxDevice
, int index
, uint16_t *pPowerValue
)
224 if (vtxDevice
&& index
> 0 && index
<= vtxTablePowerLevels
) {
225 *pPowerValue
= vtxTablePowerValues
[index
- 1];
232 static void vtxCommonSerializeCustomDeviceStatus(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
234 const bool customDeviceStatusAvailable
= vtxDevice
&& vtxDevice
->vTable
->serializeCustomDeviceStatus
;
236 if (customDeviceStatusAvailable
) {
237 vtxDevice
->vTable
->serializeCustomDeviceStatus(vtxDevice
, dst
);
243 static void vtxCommonSerializePowerLevels(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
245 uint16_t levels
[VTX_TABLE_MAX_POWER_LEVELS
];
246 uint16_t powers
[VTX_TABLE_MAX_POWER_LEVELS
];
248 const uint8_t powerLevelCount
= vtxCommonGetVTXPowerLevels(vtxDevice
, levels
, powers
);
250 sbufWriteU8(dst
, powerLevelCount
);
252 for (int i
= 0; i
< powerLevelCount
; i
++) {
253 sbufWriteU16(dst
, levels
[i
]);
254 sbufWriteU16(dst
, powers
[i
]);
258 void vtxCommonSerializeDeviceStatus(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
261 const vtxDevType_e vtxType
= vtxCommonGetDeviceType(vtxDevice
);
262 const bool deviceReady
= vtxCommonDeviceIsReady(vtxDevice
);
266 const bool bandAndChannelAvailable
= vtxCommonGetBandAndChannel(vtxDevice
, &band
, &channel
);
268 uint8_t powerIndex
= 0;
269 const bool powerIndexAvailable
= vtxCommonGetPowerIndex(vtxDevice
, &powerIndex
);
271 uint16_t frequency
= 0;
272 const bool frequencyAvailable
= vtxCommonGetFrequency(vtxDevice
, &frequency
);
274 unsigned vtxStatus
= 0; // pitmode and/or locked
275 const bool vtxStatusAvailable
= vtxCommonGetStatus(vtxDevice
, &vtxStatus
);
277 sbufWriteU8(dst
, vtxType
);
278 sbufWriteU8(dst
, deviceReady
);
280 sbufWriteU8(dst
, bandAndChannelAvailable
);
281 sbufWriteU8(dst
, band
);
282 sbufWriteU8(dst
, channel
);
284 sbufWriteU8(dst
, powerIndexAvailable
);
285 sbufWriteU8(dst
, powerIndex
);
287 sbufWriteU8(dst
, frequencyAvailable
);
288 sbufWriteU16(dst
, frequency
);
290 sbufWriteU8(dst
, vtxStatusAvailable
);
291 sbufWriteU32(dst
, vtxStatus
);
293 vtxCommonSerializePowerLevels(vtxDevice
, dst
);
294 vtxCommonSerializeCustomDeviceStatus(vtxDevice
, dst
);