diff --git a/docs/VTX.md b/docs/VTX.md index e8a082727..700663d2a 100644 --- a/docs/VTX.md +++ b/docs/VTX.md @@ -138,13 +138,22 @@ vtxtable powerlabels 25 200 500 800 #### SmartAudio V2.1 devices vary depending on their model. Check the manufacturers website. For these devices the `powervalues` are the output power in dBm. +To query the available power levels from a SmartAudio 2.1 VTX enter the `vtx_info` command with no parameters. This will report the available power settings thus: + +``` +# vtx_info +level 14 dBm, power 25 mW +level 20 dBm, power 100 mW +level 26 dBm, power 400 mW +``` + For example the [TBS Unify Pro32 Nano 5G8](https://www.team-blacksheep.com/products/prod:unifypro32_nano): ``` vtxtable powerlevels 3 -vtxtable powervalues 14 20 26 +vtxtable powervalues 14 20 26 vtxtable powerlabels 25 100 400 ``` @@ -152,7 +161,7 @@ vtxtable powerlabels 25 100 400 ``` vtxtable powerlevels 3 -vtxtable powervalues 13 20 26 +vtxtable powervalues 13 20 26 vtxtable powerlabels 25 100 400 ``` @@ -168,7 +177,7 @@ vtxtable powerlabels 25 100 400 1W ``` vtxtable powerlevels 4 -vtxtable powervalues 14 20 26 29 +vtxtable powervalues 14 20 26 29 vtxtable powerlabels 25 100 400 800 ``` @@ -178,7 +187,7 @@ For example a TBS Unify EVO will also work the this config: ``` vtxtable powerlevels 2 -vtxtable powervalues 20 26 +vtxtable powervalues 20 26 vtxtable powerlabels .1W .4W ``` diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 8fa0b888d..dc4a960c6 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -1598,8 +1598,8 @@ static void cliAdjustmentRange(char *cmdline) ptr = nextArg(ptr); if (ptr) { val = atoi(ptr); - // Was: slot - // Keeping the parameter to retain backwards compatibility for the command format. + // Was: slot + // Keeping the parameter to retain backwards compatibility for the command format. validArgumentCount++; } ptr = nextArg(ptr); @@ -2993,6 +2993,29 @@ static void cliVtxTable(char *cmdline) cliPrintErrorLinef("INVALID SUBCOMMAND %s", tok); } } + +static void cliVtxInfo(char *cmdline) +{ + UNUSED(cmdline); + + // Display the available power levels + uint16_t levels[VTX_TABLE_MAX_POWER_LEVELS]; + uint16_t powers[VTX_TABLE_MAX_POWER_LEVELS]; + vtxDevice_t *vtxDevice = vtxCommonDevice(); + if (vtxDevice) { + uint8_t level_count = vtxCommonGetVTXPowerLevels(vtxDevice, levels, powers); + + if (level_count) { + for (int i = 0; i < level_count; i++) { + cliPrintLinef("level %d dBm, power %d mW", levels[i], powers[i]); + } + } else { + cliPrintErrorLinef("NO POWER VALUES DEFINED"); + } + } else { + cliPrintErrorLinef("NO VTX"); + } +} #endif // USE_VTX_TABLE static void printName(dumpFlags_t dumpMask, const pilotConfig_t *pilotConfig) @@ -5832,7 +5855,7 @@ static void cliResource(char *cmdline) return; } - const char * resourceName = ownerNames[resourceTable[resourceIndex].owner]; + const char * resourceName = ownerNames[resourceTable[resourceIndex].owner]; if (strncasecmp(pch, resourceName, strlen(resourceName)) == 0) { break; } @@ -6370,6 +6393,7 @@ const clicmd_t cmdTable[] = { #endif #endif #ifdef USE_VTX_TABLE + CLI_COMMAND_DEF("vtx_info", "vtx power config dump", NULL, cliVtxInfo), CLI_COMMAND_DEF("vtxtable", "vtx frequency table", " [FACTORY|CUSTOM] ... \r\n", cliVtxTable), #endif }; diff --git a/src/main/drivers/vtx_common.c b/src/main/drivers/vtx_common.c index 77da4084e..055dcb6fe 100644 --- a/src/main/drivers/vtx_common.c +++ b/src/main/drivers/vtx_common.c @@ -141,6 +141,11 @@ bool vtxCommonGetStatus(const vtxDevice_t *vtxDevice, unsigned *status) return vtxDevice->vTable->getStatus(vtxDevice, status); } +uint8_t vtxCommonGetVTXPowerLevels(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers) +{ + return vtxDevice->vTable->getPowerLevels(vtxDevice, levels, powers); +} + const char *vtxCommonLookupBandName(const vtxDevice_t *vtxDevice, int band) { if (vtxDevice && band > 0 && band <= vtxTableBandCount) { diff --git a/src/main/drivers/vtx_common.h b/src/main/drivers/vtx_common.h index 6c474c220..baddf3035 100644 --- a/src/main/drivers/vtx_common.h +++ b/src/main/drivers/vtx_common.h @@ -112,6 +112,7 @@ typedef struct vtxVTable_s { bool (*getPowerIndex)(const vtxDevice_t *vtxDevice, uint8_t *pIndex); bool (*getFrequency)(const vtxDevice_t *vtxDevice, uint16_t *pFreq); bool (*getStatus)(const vtxDevice_t *vtxDevice, unsigned *status); + uint8_t (*getPowerLevels)(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers); } vtxVTable_t; // 3.1.0 @@ -135,6 +136,7 @@ bool vtxCommonGetBandAndChannel(const vtxDevice_t *vtxDevice, uint8_t *pBand, ui bool vtxCommonGetPowerIndex(const vtxDevice_t *vtxDevice, uint8_t *pIndex); bool vtxCommonGetFrequency(const vtxDevice_t *vtxDevice, uint16_t *pFreq); bool vtxCommonGetStatus(const vtxDevice_t *vtxDevice, unsigned *status); +uint8_t vtxCommonGetVTXPowerLevels(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers); const char *vtxCommonLookupBandName(const vtxDevice_t *vtxDevice, int band); char vtxCommonLookupBandLetter(const vtxDevice_t *vtxDevice, int band); char vtxCommonGetBandLetter(const vtxDevice_t *vtxDevice, int band); diff --git a/src/main/io/vtx_rtc6705.c b/src/main/io/vtx_rtc6705.c index 9c88968c0..c887ed20b 100644 --- a/src/main/io/vtx_rtc6705.c +++ b/src/main/io/vtx_rtc6705.c @@ -226,6 +226,15 @@ static bool vtxRTC6705GetStatus(const vtxDevice_t *vtxDevice, unsigned *status) return false; } +static uint8_t vtxRTC6705GetPowerLevels(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers) +{ + UNUSED(vtxDevice); + UNUSED(levels); + UNUSED(powers); + + return 0; +} + static vtxVTable_t rtc6705VTable = { .process = vtxRTC6705Process, .getDeviceType = vtxRTC6705GetDeviceType, @@ -238,6 +247,7 @@ static vtxVTable_t rtc6705VTable = { .getPowerIndex = vtxRTC6705GetPowerIndex, .getFrequency = vtxRTC6705GetFreq, .getStatus = vtxRTC6705GetStatus, + .getPowerLevels = vtxRTC6705GetPowerLevels, }; #endif // VTX_COMMON diff --git a/src/main/io/vtx_smartaudio.c b/src/main/io/vtx_smartaudio.c index 6a89b0ca7..8b7f2faf5 100644 --- a/src/main/io/vtx_smartaudio.c +++ b/src/main/io/vtx_smartaudio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "platform.h" @@ -127,12 +128,15 @@ static smartAudioDevice_t saDevicePrev = { // XXX Possible compliance problem here. Need LOCK/UNLOCK menu? static uint8_t saLockMode = SA_MODE_SET_UNLOCK; // saCms variable? +#ifdef USE_VTX_TABLE +#define VTX_SMARTAUDIO_POWER_COUNT VTX_TABLE_MAX_POWER_LEVELS static uint8_t saSupportedNumPowerLevels = VTX_SMARTAUDIO_POWER_COUNT; static uint16_t saSupportedPowerValues[VTX_SMARTAUDIO_POWER_COUNT]; -#if !defined(USE_VTX_TABLE) +#else // USE_VTX_TABLE +#define VTX_SMARTAUDIO_POWER_COUNT 4 static char saSupportedPowerLabels[VTX_SMARTAUDIO_POWER_COUNT + 1][4] = {"---", "25 ", "200", "500", "800"}; static char *saSupportedPowerLabelPointerArray[VTX_SMARTAUDIO_POWER_COUNT + 1]; -#endif +#endif // USE_VTX_TABLE // XXX Should be configurable by user? bool saDeferred = true; // saCms variable? @@ -1022,6 +1026,27 @@ static bool vtxSAGetStatus(const vtxDevice_t *vtxDevice, unsigned *status) return true; } +static uint8_t vtxSAGetPowerLevels(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers) +{ + if (!vtxSAIsReady(vtxDevice) || saDevice.version < 2) { + return 0; + } + + for (uint8_t i = 0; i < saSupportedNumPowerLevels; i++) { + levels[i] = saSupportedPowerValues[i]; + uint16_t power = (uint16_t)pow(10.0,levels[i]/10.0); + + if (levels[i] > 14) { + // For powers greater than 25mW round up to a multiple of 50 to match expectations + power = 50 * ((power + 25) / 50); + } + + powers[i] = power; + } + + return saSupportedNumPowerLevels; +} + static const vtxVTable_t saVTable = { .process = vtxSAProcess, .getDeviceType = vtxSAGetDeviceType, @@ -1034,6 +1059,7 @@ static const vtxVTable_t saVTable = { .getPowerIndex = vtxSAGetPowerIndex, .getFrequency = vtxSAGetFreq, .getStatus = vtxSAGetStatus, + .getPowerLevels = vtxSAGetPowerLevels, }; #endif // VTX_COMMON diff --git a/src/main/io/vtx_smartaudio.h b/src/main/io/vtx_smartaudio.h index f89755c3b..e04a9dbf6 100644 --- a/src/main/io/vtx_smartaudio.h +++ b/src/main/io/vtx_smartaudio.h @@ -35,8 +35,6 @@ #define VTX_SMARTAUDIO_MIN_CHANNEL 1 -#define VTX_SMARTAUDIO_POWER_COUNT 4 - #define VTX_SMARTAUDIO_MIN_FREQUENCY_MHZ 5000 //min freq in MHz #define VTX_SMARTAUDIO_MAX_FREQUENCY_MHZ 5999 //max freq in MHz diff --git a/src/main/io/vtx_tramp.c b/src/main/io/vtx_tramp.c index 393833735..dfe49c17a 100644 --- a/src/main/io/vtx_tramp.c +++ b/src/main/io/vtx_tramp.c @@ -593,6 +593,15 @@ static bool vtxTrampGetStatus(const vtxDevice_t *vtxDevice, unsigned *status) return true; } +static uint8_t vtxTrampGetPowerLevels(const vtxDevice_t *vtxDevice, uint16_t *levels, uint16_t *powers) +{ + UNUSED(vtxDevice); + UNUSED(levels); + UNUSED(powers); + + return 0; +} + static const vtxVTable_t trampVTable = { .process = vtxTrampProcess, .getDeviceType = vtxTrampGetDeviceType, @@ -605,6 +614,7 @@ static const vtxVTable_t trampVTable = { .getPowerIndex = vtxTrampGetPowerIndex, .getFrequency = vtxTrampGetFreq, .getStatus = vtxTrampGetStatus, + .getPowerLevels = vtxTrampGetPowerLevels, }; #endif