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"
36 static vtxDevice_t
*vtxDevice
= NULL
;
37 static uint8_t selectedBand
= 0;
38 static uint8_t selectedChannel
= 0;
40 void vtxCommonInit(void)
44 void vtxCommonSetDevice(vtxDevice_t
*pDevice
)
49 vtxDevice_t
*vtxCommonDevice(void)
54 vtxDevType_e
vtxCommonGetDeviceType(const vtxDevice_t
*vtxDevice
)
57 return VTXDEV_UNKNOWN
;
59 return vtxDevice
->vTable
->getDeviceType(vtxDevice
);
62 bool vtxCommonDeviceIsReady(const vtxDevice_t
*vtxDevice
)
64 if (vtxDevice
&& vtxDevice
->vTable
->isReady
) {
65 return vtxDevice
->vTable
->isReady(vtxDevice
);
71 void vtxCommonProcess(vtxDevice_t
*vtxDevice
, timeUs_t currentTimeUs
)
74 vtxDevice
->vTable
->process(vtxDevice
, currentTimeUs
);
78 // band and channel are 1 origin
79 void vtxCommonSetBandAndChannel(vtxDevice_t
*vtxDevice
, uint8_t band
, uint8_t channel
)
81 uint16_t freq
= vtxCommonLookupFrequency(vtxDevice
, band
, channel
);
83 selectedChannel
= channel
;
85 if (vtxTableIsFactoryBand
[band
- 1]) {
86 vtxDevice
->vTable
->setBandAndChannel(vtxDevice
, band
, channel
);
88 vtxDevice
->vTable
->setFrequency(vtxDevice
, freq
);
93 // index is one origin, zero = unknown power level
94 void vtxCommonSetPowerByIndex(vtxDevice_t
*vtxDevice
, uint8_t index
)
96 if (index
<= vtxTablePowerLevels
) {
97 vtxDevice
->vTable
->setPowerByIndex(vtxDevice
, index
);
102 void vtxCommonSetPitMode(vtxDevice_t
*vtxDevice
, uint8_t onOff
)
104 vtxDevice
->vTable
->setPitMode(vtxDevice
, onOff
);
107 void vtxCommonSetFrequency(vtxDevice_t
*vtxDevice
, uint16_t frequency
)
111 vtxDevice
->vTable
->setFrequency(vtxDevice
, frequency
);
114 bool vtxCommonGetBandAndChannel(const vtxDevice_t
*vtxDevice
, uint8_t *pBand
, uint8_t *pChannel
)
116 bool result
= vtxDevice
->vTable
->getBandAndChannel(vtxDevice
, pBand
, pChannel
);
117 if ((!result
|| (*pBand
== 0 && *pChannel
== 0)) && selectedBand
!= 0 && selectedChannel
!= 0
118 && !vtxTableIsFactoryBand
[selectedBand
- 1]) {
120 result
= vtxCommonGetFrequency(vtxDevice
, &freq
);
122 vtxCommonLookupBandChan(vtxDevice
, freq
, pBand
, pChannel
);
128 bool vtxCommonGetPowerIndex(const vtxDevice_t
*vtxDevice
, uint8_t *pIndex
)
130 return vtxDevice
->vTable
->getPowerIndex(vtxDevice
, pIndex
);
133 bool vtxCommonGetFrequency(const vtxDevice_t
*vtxDevice
, uint16_t *pFrequency
)
135 return vtxDevice
->vTable
->getFrequency(vtxDevice
, pFrequency
);
138 bool vtxCommonGetStatus(const vtxDevice_t
*vtxDevice
, unsigned *status
)
140 return vtxDevice
->vTable
->getStatus(vtxDevice
, status
);
143 uint8_t vtxCommonGetVTXPowerLevels(const vtxDevice_t
*vtxDevice
, uint16_t *levels
, uint16_t *powers
)
145 return vtxDevice
->vTable
->getPowerLevels(vtxDevice
, levels
, powers
);
148 const char *vtxCommonLookupBandName(const vtxDevice_t
*vtxDevice
, int band
)
150 if (vtxDevice
&& band
> 0 && band
<= vtxTableBandCount
) {
151 return vtxTableBandNames
[band
];
157 char vtxCommonLookupBandLetter(const vtxDevice_t
*vtxDevice
, int band
)
159 if (vtxDevice
&& band
> 0 && band
<= vtxTableBandCount
) {
160 return vtxTableBandLetters
[band
];
166 const char *vtxCommonLookupChannelName(const vtxDevice_t
*vtxDevice
, int channel
)
168 if (vtxDevice
&& channel
> 0 && channel
<= vtxTableChannelCount
) {
169 return vtxTableChannelNames
[channel
];
175 //Converts frequency (in MHz) to band and channel values.
176 //If frequency not found in the vtxtable then band and channel will return 0
177 void vtxCommonLookupBandChan(const vtxDevice_t
*vtxDevice
, uint16_t freq
, uint8_t *pBand
, uint8_t *pChannel
)
182 // Use reverse lookup order so that 5880Mhz
183 // get Raceband 7 instead of Fatshark 8.
184 for (int band
= vtxTableBandCount
- 1 ; band
>= 0 ; band
--) {
185 for (int channel
= 0 ; channel
< vtxTableChannelCount
; channel
++) {
186 if (vtxTableFrequency
[band
][channel
] == freq
) {
188 *pChannel
= channel
+ 1;
196 //Converts band and channel values to a frequency (in MHz) value.
197 // band: Band value (1 to 5).
198 // channel: Channel value (1 to 8).
199 // Returns frequency value (in MHz), or 0 if band/channel out of range.
200 uint16_t vtxCommonLookupFrequency(const vtxDevice_t
*vtxDevice
, int band
, int channel
)
203 if (band
> 0 && band
<= vtxTableBandCount
&&
204 channel
> 0 && channel
<= vtxTableChannelCount
) {
205 return vtxTableFrequency
[band
- 1][channel
- 1];
212 const char *vtxCommonLookupPowerName(const vtxDevice_t
*vtxDevice
, int index
)
214 if (vtxDevice
&& index
> 0 && index
<= vtxTablePowerLevels
) {
215 return vtxTablePowerLabels
[index
];
221 bool vtxCommonLookupPowerValue(const vtxDevice_t
*vtxDevice
, int index
, uint16_t *pPowerValue
)
223 if (vtxDevice
&& index
> 0 && index
<= vtxTablePowerLevels
) {
224 *pPowerValue
= vtxTablePowerValues
[index
- 1];
231 static void vtxCommonSerializeCustomDeviceStatus(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
233 const bool customDeviceStatusAvailable
= vtxDevice
&& vtxDevice
->vTable
->serializeCustomDeviceStatus
;
235 if (customDeviceStatusAvailable
) {
236 vtxDevice
->vTable
->serializeCustomDeviceStatus(vtxDevice
, dst
);
242 static void vtxCommonSerializePowerLevels(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
244 uint16_t levels
[VTX_TABLE_MAX_POWER_LEVELS
];
245 uint16_t powers
[VTX_TABLE_MAX_POWER_LEVELS
];
247 const uint8_t powerLevelCount
= vtxCommonGetVTXPowerLevels(vtxDevice
, levels
, powers
);
249 sbufWriteU8(dst
, powerLevelCount
);
251 for (int i
= 0; i
< powerLevelCount
; i
++) {
252 sbufWriteU16(dst
, levels
[i
]);
253 sbufWriteU16(dst
, powers
[i
]);
257 void vtxCommonSerializeDeviceStatus(const vtxDevice_t
*vtxDevice
, sbuf_t
*dst
)
260 const vtxDevType_e vtxType
= vtxCommonGetDeviceType(vtxDevice
);
261 const bool deviceReady
= vtxCommonDeviceIsReady(vtxDevice
);
265 const bool bandAndChannelAvailable
= vtxCommonGetBandAndChannel(vtxDevice
, &band
, &channel
);
267 uint8_t powerIndex
= 0;
268 const bool powerIndexAvailable
= vtxCommonGetPowerIndex(vtxDevice
, &powerIndex
);
270 uint16_t frequency
= 0;
271 const bool frequencyAvailable
= vtxCommonGetFrequency(vtxDevice
, &frequency
);
273 unsigned vtxStatus
= 0; // pitmode and/or locked
274 const bool vtxStatusAvailable
= vtxCommonGetStatus(vtxDevice
, &vtxStatus
);
276 sbufWriteU8(dst
, vtxType
);
277 sbufWriteU8(dst
, deviceReady
);
279 sbufWriteU8(dst
, bandAndChannelAvailable
);
280 sbufWriteU8(dst
, band
);
281 sbufWriteU8(dst
, channel
);
283 sbufWriteU8(dst
, powerIndexAvailable
);
284 sbufWriteU8(dst
, powerIndex
);
286 sbufWriteU8(dst
, frequencyAvailable
);
287 sbufWriteU16(dst
, frequency
);
289 sbufWriteU8(dst
, vtxStatusAvailable
);
290 sbufWriteU32(dst
, vtxStatus
);
292 vtxCommonSerializePowerLevels(vtxDevice
, dst
);
293 vtxCommonSerializeCustomDeviceStatus(vtxDevice
, dst
);