mirror of
https://github.com/opentx/opentx.git
synced 2025-07-19 14:25:11 +03:00
Ghost support (#7900)
This commit is contained in:
parent
1cfe0edeb6
commit
205ac7a21d
48 changed files with 776 additions and 54 deletions
|
@ -160,7 +160,8 @@ QString ModuleData::protocolToString(unsigned protocol)
|
|||
"FrSky ACCESS R9M Lite",
|
||||
"FrSky ACCESS R9M Lite Pro",
|
||||
"FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)",
|
||||
"AFHDS3"
|
||||
"AFHDS3",
|
||||
"ImmersionRC Ghost"
|
||||
};
|
||||
|
||||
return CHECK_IN_ARRAY(strings, protocol);
|
||||
|
@ -221,6 +222,7 @@ int ModuleData::getMaxChannelCount()
|
|||
case PULSES_XJT_LITE_X16:
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_GHOST:
|
||||
case PULSES_SBUS:
|
||||
case PULSES_PPM:
|
||||
return 16;
|
||||
|
|
|
@ -59,6 +59,7 @@ enum PulsesProtocol {
|
|||
PULSES_XJT_LITE_D8,
|
||||
PULSES_XJT_LITE_LR12,
|
||||
PULSES_AFHDS3,
|
||||
PULSES_GHOST,
|
||||
PULSES_PROTOCOL_LAST
|
||||
};
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ class ProtocolsConversionTable: public ConversionTable
|
|||
addConversion(PULSES_ACCESS_R9M, val++);
|
||||
addConversion(PULSES_PXX_R9M_LITE, val++);
|
||||
addConversion(PULSES_ACCESS_R9M_LITE, val++);
|
||||
addConversion(PULSES_PXX_R9M_LITE_PRO, val++);
|
||||
addConversion(PULSES_GHOST, val++);
|
||||
addConversion(PULSES_ACCESS_R9M_LITE_PRO, val++);
|
||||
|
||||
addConversion(PULSES_SBUS, val++);
|
||||
|
@ -104,6 +104,7 @@ class ProtocolsConversionTable: public ConversionTable
|
|||
addConversion(PULSES_XJT_LITE_X16, val);
|
||||
addConversion(PULSES_XJT_LITE_D8, val);
|
||||
addConversion(PULSES_XJT_LITE_LR12, val++);
|
||||
|
||||
if (version >= 219) {
|
||||
addConversion(PULSES_AFHDS3, val++);
|
||||
}
|
||||
|
|
|
@ -760,6 +760,7 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
|
|||
case PULSES_MULTIMODULE:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_AFHDS3:
|
||||
case PULSES_GHOST:
|
||||
return true;
|
||||
case PULSES_ACCESS_R9M:
|
||||
return IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_FAMILY_HORUS_OR_T16(board) && id.contains("internalaccess"));
|
||||
|
|
|
@ -84,6 +84,12 @@ QString SensorData::unitString() const
|
|||
return tr("V");
|
||||
case UNIT_MILLILITERS_PER_MINUTE:
|
||||
return tr("ml/minute");
|
||||
case UNIT_HERZ:
|
||||
return tr("Hertz");
|
||||
case UNIT_MS:
|
||||
return tr("mS");
|
||||
case UNIT_US:
|
||||
return tr("uS");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -94,10 +94,10 @@ class SensorData {
|
|||
UNIT_MILLILITERS,
|
||||
UNIT_FLOZ,
|
||||
UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_MAX = UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_SPARE1,
|
||||
UNIT_SPARE2,
|
||||
UNIT_SPARE3,
|
||||
UNIT_HERZ,
|
||||
UNIT_MS,
|
||||
UNIT_US,
|
||||
UNIT_MAX = UNIT_US,
|
||||
UNIT_SPARE4,
|
||||
UNIT_SPARE5,
|
||||
UNIT_SPARE6,
|
||||
|
|
|
@ -424,6 +424,7 @@ void ModulePanel::update()
|
|||
max_rx_num = 20;
|
||||
break;
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_GHOST:
|
||||
mask |= MASK_CHANNELS_RANGE;
|
||||
module.channelsCount = 16;
|
||||
break;
|
||||
|
|
|
@ -212,7 +212,7 @@ QString ModelPrinter::printModule(int idx)
|
|||
str << printLabelValue(tr("Delay"), QString("%1us").arg(module.ppm.delay));
|
||||
}
|
||||
else {
|
||||
if (!(module.protocol == PULSES_PXX_XJT_D8 || module.protocol == PULSES_CROSSFIRE || module.protocol == PULSES_SBUS)) {
|
||||
if (!(module.protocol == PULSES_PXX_XJT_D8 || module.protocol == PULSES_CROSSFIRE || module.protocol == PULSES_GHOST || module.protocol == PULSES_SBUS)) {
|
||||
str << printLabelValue(tr("Receiver"), QString::number(module.modelId));
|
||||
}
|
||||
if (module.protocol == PULSES_MULTIMODULE) {
|
||||
|
|
BIN
radio/sdcard/horus/WIDGETS/Ghost/img/background.png
Normal file
BIN
radio/sdcard/horus/WIDGETS/Ghost/img/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
88
radio/sdcard/horus/WIDGETS/Ghost/main.lua
Normal file
88
radio/sdcard/horus/WIDGETS/Ghost/main.lua
Normal file
|
@ -0,0 +1,88 @@
|
|||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
|
||||
---- # #
|
||||
---- # This program is free software; you can redistribute it and/or modify #
|
||||
---- # it under the terms of the GNU General Public License version 2 as #
|
||||
---- # published by the Free Software Foundation. #
|
||||
---- # #
|
||||
---- # This program is distributed in the hope that it will be useful #
|
||||
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
---- # GNU General Public License for more details. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
local backgroundBitmap
|
||||
local offsetX
|
||||
local offsetY
|
||||
local sensors = {}
|
||||
|
||||
local options = {
|
||||
{ "VTX", BOOL, 0 },
|
||||
}
|
||||
|
||||
local function getValues(wgt)
|
||||
if wgt.options.VTX == 0 then
|
||||
sensors[1] = string.format("%s", getValue("RFMD"))
|
||||
sensors[2] = string.format("%d Hz", getValue("FRat"))
|
||||
sensors[3] = string.format("%d %%", getValue("RQly"))
|
||||
if (getValue("TPWR") == 0) then
|
||||
sensors[4] = "Range"
|
||||
else
|
||||
sensors[4] = string.format("%d mW", getValue("TPWR"))
|
||||
end
|
||||
else
|
||||
sensors[1] = string.format("%s", getValue("VBan"))
|
||||
sensors[2] = string.format("%dMHz", getValue("VFrq"))
|
||||
sensors[3] = string.format("CH: %d", getValue("VChn"))
|
||||
sensors[4] = string.format("%d mW", getValue("VPwr"))
|
||||
end
|
||||
end
|
||||
|
||||
local function create(zone, options)
|
||||
local wgt = { zone=zone, options=options}
|
||||
backgroundBitmap = Bitmap.open("/WIDGETS/Ghost/img/background.png")
|
||||
offsetX = (wgt.zone.w - 178) / 2
|
||||
offsetY = (wgt.zone.h - 148) / 2
|
||||
return wgt
|
||||
end
|
||||
|
||||
local function update(wgt, options)
|
||||
wgt.options = options
|
||||
end
|
||||
|
||||
local function background(wgt)
|
||||
end
|
||||
|
||||
function refresh(wgt)
|
||||
-- runs onty on large enough zone
|
||||
if wgt.zone.w < 180 or wgt.zone.h < 145 then
|
||||
return
|
||||
end
|
||||
|
||||
if backgroundBitmap ~= nil then
|
||||
lcd.drawBitmap(backgroundBitmap, wgt.zone.x + offsetX, wgt.zone.y + offsetY)
|
||||
end
|
||||
|
||||
if getRSSI() ~= 0 then
|
||||
getValues(wgt)
|
||||
|
||||
-- RF Mode/Band
|
||||
lcd.drawText(wgt.zone.x + offsetX + 75, wgt.zone.y + offsetY + 2, sensors[1], CENTER + DBLSIZE)
|
||||
|
||||
-- Frame rate / Frequency
|
||||
lcd.drawText(wgt.zone.x + offsetX + 85, wgt.zone.y + offsetY + 35, sensors[2], CENTER + DBLSIZE)
|
||||
|
||||
-- RSSI / Channel
|
||||
lcd.drawText(wgt.zone.x + offsetX + 85, wgt.zone.y + offsetY + 70, sensors[3], CENTER + DBLSIZE)
|
||||
|
||||
-- Transmit power
|
||||
lcd.drawText(wgt.zone.x + offsetX + 85, wgt.zone.y + offsetY + 105, sensors[4], CENTER + DBLSIZE)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return { name="Ghost", options=options, create=create, update=update, refresh=refresh, background=background }
|
|
@ -54,6 +54,7 @@ option(MODULE_PROTOCOL_FLEX "Add support for non certified FLEX modules" OFF)
|
|||
option(MODULE_PROTOCOL_D8 "Add support for D8 modules" ON)
|
||||
option(FRSKY_RELEASE "Used to build FrSky released firmware" OFF)
|
||||
option(TBS_RELEASE "Used to build TBS released firmware" OFF)
|
||||
option(IMRC_RELEASE "Used to build IMRC released firmware" OFF)
|
||||
option(ALLOW_TRAINER_MULTI "Allow multi trainer" OFF)
|
||||
|
||||
# since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags.
|
||||
|
@ -348,6 +349,10 @@ if(TBS_RELEASE)
|
|||
add_definitions(-DTBS_RELEASE)
|
||||
endif()
|
||||
|
||||
if(IMRC_RELEASE)
|
||||
add_definitions(-DIMRC_RELEASE)
|
||||
endif()
|
||||
|
||||
if(FRSKY_RELEASE)
|
||||
add_definitions(-DFRSKY_RELEASE)
|
||||
set(POPUP_LEVEL 3)
|
||||
|
|
|
@ -158,9 +158,9 @@ const char * const unitsFilenames[] = {
|
|||
"ml",
|
||||
"founce",
|
||||
"mlpm",
|
||||
"spare1",
|
||||
"spare2",
|
||||
"spare3",
|
||||
"hertz",
|
||||
"ms",
|
||||
"us",
|
||||
"spare4",
|
||||
"spare5",
|
||||
"spare6",
|
||||
|
|
|
@ -270,7 +270,8 @@ enum TelemetryProtocol
|
|||
PROTOCOL_TELEMETRY_HOTT,
|
||||
PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||
PROTOCOL_TELEMETRY_AFHDS3,
|
||||
PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_AFHDS3,
|
||||
PROTOCOL_TELEMETRY_GHOST,
|
||||
PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_GHOST,
|
||||
PROTOCOL_TELEMETRY_LUA
|
||||
};
|
||||
|
||||
|
@ -304,10 +305,10 @@ enum TelemetryUnit {
|
|||
UNIT_MILLILITERS,
|
||||
UNIT_FLOZ,
|
||||
UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_MAX = UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_SPARE1,
|
||||
UNIT_SPARE2,
|
||||
UNIT_SPARE3,
|
||||
UNIT_HERTZ,
|
||||
UNIT_MS,
|
||||
UNIT_US,
|
||||
UNIT_MAX = UNIT_US,
|
||||
UNIT_SPARE4,
|
||||
UNIT_SPARE5,
|
||||
UNIT_SPARE6,
|
||||
|
|
|
@ -126,7 +126,7 @@ void onHardwareAntennaSwitchConfirm(const char * result)
|
|||
#define EXTERNAL_ANTENNA_ROW
|
||||
#endif
|
||||
|
||||
#if defined(CROSSFIRE)
|
||||
#if (defined(CROSSFIRE) || defined(GHOST))
|
||||
#define MAX_BAUDRATE_ROW 0
|
||||
#else
|
||||
#define MAX_BAUDRATE_ROW HIDDEN_ROW
|
||||
|
|
|
@ -162,7 +162,7 @@ enum {
|
|||
ITEM_RADIO_HARDWARE_CAPACITY_CALIB,
|
||||
#endif
|
||||
|
||||
#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000
|
||||
#if (defined(CROSSFIRE) || defined(GHOST)) && SPORT_MAX_BAUDRATE < 400000
|
||||
ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE,
|
||||
#endif
|
||||
|
||||
|
@ -278,7 +278,7 @@ void onHardwareAntennaSwitchConfirm(const char * result)
|
|||
#define TX_CAPACITY_MEASUREMENT_ROWS
|
||||
#endif
|
||||
|
||||
#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000
|
||||
#if (defined(CROSSFIRE) || defined(GHOST)) && SPORT_MAX_BAUDRATE < 400000
|
||||
#define MAX_BAUD_ROWS 0,
|
||||
#else
|
||||
#define MAX_BAUD_ROWS
|
||||
|
@ -544,7 +544,7 @@ void menuRadioHardware(event_t event)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000
|
||||
#if (defined(CROSSFIRE) || defined(GHOST)) && SPORT_MAX_BAUDRATE < 400000
|
||||
case ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE:
|
||||
lcdDrawTextAlignedLeft(y, STR_MAXBAUDRATE);
|
||||
lcdDrawNumber(HW_SETTINGS_COLUMN2, y, CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate], attr|LEFT);
|
||||
|
|
|
@ -584,6 +584,14 @@ bool isModuleUsingSport(uint8_t moduleBay, uint8_t moduleType)
|
|||
}
|
||||
}
|
||||
|
||||
bool areModulesConflicting(int intModuleType, int extModuleType)
|
||||
{
|
||||
if (intModuleType == MODULE_TYPE_ISRM_PXX2)
|
||||
return (extModuleType == MODULE_TYPE_GHOST);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
bool isInternalModuleAvailable(int moduleType)
|
||||
{
|
||||
|
@ -605,7 +613,7 @@ bool isInternalModuleAvailable(int moduleType)
|
|||
|
||||
if (moduleType == MODULE_TYPE_ISRM_PXX2) {
|
||||
#if defined(PXX2) && defined(INTERNAL_MODULE_PXX2)
|
||||
return true;
|
||||
return !areModulesConflicting(moduleType, g_model.moduleData[EXTERNAL_MODULE].type);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -620,9 +628,6 @@ bool isInternalModuleAvailable(int moduleType)
|
|||
|
||||
bool isExternalModuleAvailable(int moduleType)
|
||||
{
|
||||
if (moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX1)
|
||||
return false;
|
||||
|
||||
#if !defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
||||
if (isModuleTypeR9MLite(moduleType) || moduleType == MODULE_TYPE_XJT_LITE_PXX2)
|
||||
return false;
|
||||
|
@ -657,6 +662,11 @@ bool isExternalModuleAvailable(int moduleType)
|
|||
return false;
|
||||
#endif
|
||||
|
||||
#if !defined(GHOST)
|
||||
if (moduleType == MODULE_TYPE_GHOST)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if !defined(DSM2)
|
||||
if (moduleType == MODULE_TYPE_DSM2)
|
||||
return false;
|
||||
|
@ -673,6 +683,9 @@ bool isExternalModuleAvailable(int moduleType)
|
|||
#endif
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
if (areModulesConflicting(g_model.moduleData[INTERNAL_MODULE].type, moduleType))
|
||||
return false;
|
||||
|
||||
if (isTrainerUsingModuleBay() || (isModuleUsingSport(EXTERNAL_MODULE, moduleType) && isModuleUsingSport(INTERNAL_MODULE, g_model.moduleData[INTERNAL_MODULE].type)))
|
||||
return false;
|
||||
#endif
|
||||
|
@ -697,6 +710,11 @@ bool isRfProtocolAvailable(int protocol)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
#if defined(GHOST)
|
||||
if (protocol != MODULE_SUBTYPE_PXX1_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_GHOST) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if !defined(MODULE_PROTOCOL_D8)
|
||||
if (protocol == MODULE_SUBTYPE_PXX1_ACCST_D8) {
|
||||
return false;
|
||||
|
@ -726,6 +744,10 @@ bool isTelemetryProtocolAvailable(int protocol)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( protocol== PROTOCOL_TELEMETRY_GHOST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(MULTIMODULE)
|
||||
if (protocol == PROTOCOL_TELEMETRY_SPEKTRUM || protocol == PROTOCOL_TELEMETRY_FLYSKY_IBUS || protocol == PROTOCOL_TELEMETRY_MULTIMODULE) {
|
||||
return false;
|
||||
|
|
|
@ -175,7 +175,7 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx)
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
else if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx)) {
|
||||
else if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleGhost(moduleIdx) || isModuleSBUS(moduleIdx)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1981,6 +1981,9 @@ const luaR_value_entry opentxConstants[] = {
|
|||
{"UNIT_MILLILITERS", UNIT_MILLILITERS },
|
||||
{"UNIT_FLOZ", UNIT_FLOZ },
|
||||
{"UNIT_MILLILITERS_PER_MINUTE", UNIT_MILLILITERS_PER_MINUTE },
|
||||
{"UNIT_HERTZ", UNIT_HERTZ },
|
||||
{"UNIT_MS", UNIT_MS },
|
||||
{"UNIT_US", UNIT_US },
|
||||
{"UNIT_HOURS", UNIT_HOURS },
|
||||
{"UNIT_MINUTES", UNIT_MINUTES },
|
||||
{"UNIT_SECONDS", UNIT_SECONDS },
|
||||
|
|
|
@ -29,6 +29,9 @@ static const char * const options[] = {
|
|||
#if defined(CROSSFIRE)
|
||||
"crossfire",
|
||||
#endif
|
||||
#if defined(GHOST)
|
||||
"ghost",
|
||||
#endif
|
||||
#if !defined(MODULE_PROTOCOL_D8)
|
||||
"eu",
|
||||
#endif
|
||||
|
|
89
radio/src/pulses/ghost.cpp
Executable file
89
radio/src/pulses/ghost.cpp
Executable file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
// Range for pulses (channels output) is [-1024:+1024]
|
||||
uint8_t createGhostChannelsFrame(uint8_t * frame, int16_t * pulses)
|
||||
{
|
||||
static uint8_t lastGhostFrameId = GHST_UL_RC_CHANS_HS4_5TO8;
|
||||
uint8_t ghostUpper4Offset = 0;
|
||||
|
||||
switch (lastGhostFrameId) {
|
||||
case GHST_UL_RC_CHANS_HS4_5TO8:
|
||||
ghostUpper4Offset = 0;
|
||||
break;
|
||||
case GHST_UL_RC_CHANS_HS4_9TO12:
|
||||
ghostUpper4Offset = 4;
|
||||
break;
|
||||
case GHST_UL_RC_CHANS_HS4_13TO16:
|
||||
ghostUpper4Offset = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t * buf = frame;
|
||||
*buf++ = GHST_ADDR_MODULE;
|
||||
*buf++ = GHST_UL_RC_CHANS_SIZE;
|
||||
uint8_t * crc_start = buf;
|
||||
*buf++ = lastGhostFrameId;
|
||||
|
||||
// first 4 high speed, 12 bit channels (11 relevant bits with openTx)
|
||||
uint32_t bits = 0;
|
||||
uint8_t bitsavailable = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint32_t value = limit(0, GHST_RC_CTR_VAL_12BIT + (((pulses[i]) << 3) / 5), 2 * GHST_RC_CTR_VAL_12BIT);
|
||||
bits |= value << bitsavailable;
|
||||
bitsavailable += GHST_CH_BITS_12;
|
||||
while (bitsavailable >= 8) {
|
||||
*buf++ = bits;
|
||||
bits >>= 8;
|
||||
bitsavailable -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// second 4 lower speed, 8 bit channels
|
||||
for (int i = 4; i < 8; ++i) {
|
||||
*buf++ = limit(0, GHST_RC_CTR_VAL_8BIT + (((pulses[i + ghostUpper4Offset]) >> 1) / 5), 2 * GHST_RC_CTR_VAL_8BIT);
|
||||
}
|
||||
|
||||
*buf++ = crc8(crc_start, GHST_UL_RC_CHANS_SIZE - 1);
|
||||
|
||||
switch (lastGhostFrameId) {
|
||||
case GHST_UL_RC_CHANS_HS4_5TO8:
|
||||
lastGhostFrameId = GHST_UL_RC_CHANS_HS4_9TO12;
|
||||
break;
|
||||
case GHST_UL_RC_CHANS_HS4_9TO12:
|
||||
lastGhostFrameId = GHST_UL_RC_CHANS_HS4_13TO16;
|
||||
break;
|
||||
case GHST_UL_RC_CHANS_HS4_13TO16:
|
||||
lastGhostFrameId = GHST_UL_RC_CHANS_HS4_5TO8;
|
||||
break;
|
||||
}
|
||||
|
||||
return buf - frame;
|
||||
}
|
||||
|
||||
void setupPulsesGhost()
|
||||
{
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_GHOST) {
|
||||
uint8_t * pulses = extmodulePulsesData.ghost.pulses;
|
||||
extmodulePulsesData.ghost.length = createGhostChannelsFrame(pulses, &channelOutputs[g_model.moduleData[EXTERNAL_MODULE].channelsStart]);
|
||||
}
|
||||
}
|
|
@ -29,11 +29,11 @@ enum ModuleType {
|
|||
MODULE_TYPE_DSM2,
|
||||
MODULE_TYPE_CROSSFIRE,
|
||||
MODULE_TYPE_MULTIMODULE,
|
||||
MODULE_TYPE_R9M_PXX1,
|
||||
MODULE_TYPE_R9M_PXX2,
|
||||
MODULE_TYPE_R9M_LITE_PXX1,
|
||||
MODULE_TYPE_R9M_LITE_PXX2,
|
||||
MODULE_TYPE_R9M_LITE_PRO_PXX1, // Doesn't exist
|
||||
MODULE_TYPE_R9M_PXX1, // R9M
|
||||
MODULE_TYPE_R9M_PXX2, // R9M ACCESS
|
||||
MODULE_TYPE_R9M_LITE_PXX1, //R9MLite
|
||||
MODULE_TYPE_R9M_LITE_PXX2, //R9MLP
|
||||
MODULE_TYPE_GHOST, // Replaces MODULE_TYPE_R9M_LITE_PRO_PXX1 which doesn't exist
|
||||
MODULE_TYPE_R9M_LITE_PRO_PXX2,
|
||||
MODULE_TYPE_SBUS,
|
||||
MODULE_TYPE_XJT_LITE_PXX2,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#endif
|
||||
|
||||
#define CROSSFIRE_CHANNELS_COUNT 16
|
||||
#define GHOST_CHANNELS_COUNT 12
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
// When using packed, the pointer in here end up not being aligned, which clang and gcc complain about
|
||||
|
@ -150,6 +151,18 @@ inline bool isModuleCrossfire(uint8_t idx)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
inline bool isModuleGhost(uint8_t idx)
|
||||
{
|
||||
return idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_GHOST;
|
||||
}
|
||||
#else
|
||||
inline bool isModuleGhost(uint8_t idx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PCBSKY9X)
|
||||
inline bool isExtraModule(uint8_t idx)
|
||||
{
|
||||
|
@ -178,7 +191,7 @@ inline bool isModulePPM(uint8_t moduleIdx)
|
|||
|
||||
inline bool isModuleTypeR9MNonAccess(uint8_t type)
|
||||
{
|
||||
return type == MODULE_TYPE_R9M_PXX1 || type == MODULE_TYPE_R9M_LITE_PXX1 || type == MODULE_TYPE_R9M_LITE_PRO_PXX1;
|
||||
return type == MODULE_TYPE_R9M_PXX1 || type == MODULE_TYPE_R9M_LITE_PXX1;
|
||||
}
|
||||
|
||||
inline bool isModuleR9MNonAccess(uint8_t idx)
|
||||
|
@ -218,7 +231,7 @@ inline bool isModuleR9MLiteNonPro(uint8_t idx)
|
|||
|
||||
inline bool isModuleTypeR9MLitePro(uint8_t type)
|
||||
{
|
||||
return type == MODULE_TYPE_R9M_LITE_PRO_PXX1 || type == MODULE_TYPE_R9M_LITE_PRO_PXX2;
|
||||
return type == MODULE_TYPE_R9M_LITE_PRO_PXX2;
|
||||
}
|
||||
|
||||
inline bool isModuleTypeR9MLite(uint8_t type)
|
||||
|
@ -384,6 +397,8 @@ inline int8_t sentModuleChannels(uint8_t idx)
|
|||
{
|
||||
if (isModuleCrossfire(idx))
|
||||
return CROSSFIRE_CHANNELS_COUNT;
|
||||
else if (isModuleGhost(idx))
|
||||
return GHOST_CHANNELS_COUNT;
|
||||
else if (isModuleMultimodule(idx) && !isModuleMultimoduleDSM2(idx))
|
||||
return 16;
|
||||
else if (isModuleSBUS(idx))
|
||||
|
@ -528,7 +543,7 @@ inline bool isTelemAllowedOnBind(uint8_t moduleIndex)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M_PXX1 || g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M_LITE_PRO_PXX1) {
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_R9M_PXX1) {
|
||||
if (isModuleR9M_LBT(EXTERNAL_MODULE))
|
||||
return g_model.moduleData[EXTERNAL_MODULE].pxx.power < R9M_LBT_POWER_200_16CH_NOTELEM;
|
||||
else
|
||||
|
|
|
@ -133,7 +133,6 @@ uint8_t getRequiredProtocol(uint8_t module)
|
|||
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML)
|
||||
case MODULE_TYPE_R9M_LITE_PXX1:
|
||||
case MODULE_TYPE_R9M_LITE_PRO_PXX1:
|
||||
protocol = PROTOCOL_CHANNELS_PXX1_SERIAL;
|
||||
break;
|
||||
|
||||
|
@ -193,6 +192,12 @@ uint8_t getRequiredProtocol(uint8_t module)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
case MODULE_TYPE_GHOST:
|
||||
protocol = PROTOCOL_CHANNELS_GHOST;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
protocol = PROTOCOL_CHANNELS_NONE;
|
||||
break;
|
||||
|
@ -243,6 +248,12 @@ void enablePulsesExternalModule(uint8_t protocol)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
case PROTOCOL_CHANNELS_GHOST:
|
||||
EXTERNAL_MODULE_ON();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(PXX2) && defined(EXTMODULE_USART)
|
||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||
extmoduleInvertedSerialStart(PXX2_HIGHSPEED_BAUDRATE);
|
||||
|
@ -332,6 +343,13 @@ bool setupPulsesExternalModule(uint8_t protocol)
|
|||
return true;
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
case PROTOCOL_CHANNELS_GHOST:
|
||||
setupPulsesGhost();
|
||||
scheduleNextMixerCalculation(EXTERNAL_MODULE, GHOST_PERIOD);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||
setupPulsesMultiExternalModule();
|
||||
|
|
|
@ -237,6 +237,12 @@ PACK(struct CrossfirePulsesData {
|
|||
uint8_t length;
|
||||
});
|
||||
|
||||
#define GHOST_FRAME_MAXLEN 16
|
||||
PACK(struct GhostPulsesData {
|
||||
uint8_t pulses[GHOST_FRAME_MAXLEN];
|
||||
uint8_t length;
|
||||
});
|
||||
|
||||
union InternalModulePulsesData {
|
||||
#if defined(PXX1)
|
||||
#if defined(INTMODULE_USART)
|
||||
|
@ -286,6 +292,8 @@ union ExternalModulePulsesData {
|
|||
PpmPulsesData<pulse_duration_t> ppm;
|
||||
|
||||
CrossfirePulsesData crossfire;
|
||||
|
||||
GhostPulsesData ghost;
|
||||
} __ALIGNED(4);
|
||||
|
||||
/* The __ALIGNED keyword is required to align the struct inside the modulePulsesData below,
|
||||
|
@ -310,6 +318,7 @@ bool setupPulsesInternalModule();
|
|||
bool setupPulsesExternalModule();
|
||||
void setupPulsesDSM2();
|
||||
void setupPulsesCrossfire();
|
||||
void setupPulsesGhost();
|
||||
void setupPulsesMultiExternalModule();
|
||||
void setupPulsesMultiInternalModule();
|
||||
void setupPulsesSbus();
|
||||
|
@ -364,7 +373,8 @@ enum ChannelsProtocols {
|
|||
PROTOCOL_CHANNELS_SBUS,
|
||||
PROTOCOL_CHANNELS_PXX2_LOWSPEED,
|
||||
PROTOCOL_CHANNELS_PXX2_HIGHSPEED,
|
||||
PROTOCOL_CHANNELS_AFHDS3
|
||||
PROTOCOL_CHANNELS_AFHDS3,
|
||||
PROTOCOL_CHANNELS_GHOST
|
||||
};
|
||||
|
||||
inline void stopPulses()
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#define DISPLAY_VERSION "-radiomaster"
|
||||
#elif defined(TBS_RELEASE)
|
||||
#define DISPLAY_VERSION "-tbs"
|
||||
#elif defined(IMRC_RELEASE)
|
||||
#define DISPLAY_VERSION "-imrc"
|
||||
#else
|
||||
#define DISPLAY_VERSION
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@ option(PPM "PPM TX Module" ON)
|
|||
option(DSM2 "DSM2 TX Module" ON)
|
||||
option(SBUS "SBUS TX Module" ON)
|
||||
option(CROSSFIRE "Crossfire TX Module" ON)
|
||||
option(GHOST "Ghost TX Module" ON)
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
option(DEBUG_INTERRUPTS "Count interrupts" OFF)
|
||||
option(DEBUG_LATENCY "Debug latency" OFF)
|
||||
|
@ -175,6 +176,18 @@ if(MULTIMODULE OR AFHDS3)
|
|||
set(SRC ${SRC} telemetry/flysky_ibus.cpp )
|
||||
endif()
|
||||
|
||||
if(GHOST)
|
||||
add_definitions(-DGHOST)
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
ghost.cpp
|
||||
)
|
||||
set(SRC
|
||||
${SRC}
|
||||
telemetry/ghost.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(-DCPUARM)
|
||||
add_definitions(-DGPS)
|
||||
add_definitions(-DBOLD_FONT -DBATTGRAPH -DTHRTRACE)
|
||||
|
|
|
@ -48,6 +48,7 @@ if (PCB STREQUAL X10)
|
|||
option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON)
|
||||
set(BLUETOOTH ON)
|
||||
add_definitions(-DHARDWARE_POWER_MANAGEMENT_UNIT)
|
||||
add_definitions(-DRADIO_X10E)
|
||||
elseif (PCBREV STREQUAL T16)
|
||||
set(FLAVOUR t16)
|
||||
set(LUA_EXPORT lua_export_t16)
|
||||
|
|
|
@ -368,6 +368,12 @@ void extmoduleSendNextFrame()
|
|||
break;
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
case PROTOCOL_CHANNELS_GHOST:
|
||||
sportSendBuffer(extmodulePulsesData.ghost.pulses, extmodulePulsesData.ghost.length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
break;
|
||||
|
|
|
@ -321,6 +321,12 @@ void extmoduleSendNextFrame()
|
|||
break;
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
case PROTOCOL_CHANNELS_GHOST:
|
||||
sportSendBuffer(extmodulePulsesData.ghost.pulses, extmodulePulsesData.ghost.length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
break;
|
||||
|
|
|
@ -76,7 +76,7 @@ bool isForcePowerOffRequested()
|
|||
bool isModuleSynchronous(uint8_t moduleIdx)
|
||||
{
|
||||
uint8_t protocol = moduleState[moduleIdx].protocol;
|
||||
if (protocol == PROTOCOL_CHANNELS_PXX2_HIGHSPEED || protocol == PROTOCOL_CHANNELS_PXX2_LOWSPEED || protocol == PROTOCOL_CHANNELS_CROSSFIRE || protocol == PROTOCOL_CHANNELS_NONE)
|
||||
if (protocol == PROTOCOL_CHANNELS_PXX2_HIGHSPEED || protocol == PROTOCOL_CHANNELS_PXX2_LOWSPEED || protocol == PROTOCOL_CHANNELS_CROSSFIRE || protocol == PROTOCOL_CHANNELS_GHOST || protocol == PROTOCOL_CHANNELS_NONE)
|
||||
return true;
|
||||
#if defined(INTMODULE_USART) || defined(EXTMODULE_USART)
|
||||
if (protocol == PROTOCOL_CHANNELS_PXX1_SERIAL)
|
||||
|
|
216
radio/src/telemetry/ghost.cpp
Executable file
216
radio/src/telemetry/ghost.cpp
Executable file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
const char * const ghstRfProfileValue[GHST_RF_PROFILE_COUNT] = { "Auto", "Norm", "Race", "Pure", "Long" };
|
||||
const char * const ghstVtxBandName[GHST_VTX_BAND_COUNT] = { "- - -" , "IRC", "Race", "BandE", "BandB", "BandA" };
|
||||
|
||||
struct GhostSensor
|
||||
{
|
||||
const uint16_t id;
|
||||
const char * name;
|
||||
const TelemetryUnit unit;
|
||||
const uint8_t precision;
|
||||
};
|
||||
|
||||
// telemetry sensors ID
|
||||
enum
|
||||
{
|
||||
GHOST_ID_RX_RSSI = 0x0001, // Rx-side RSSI
|
||||
GHOST_ID_RX_LQ = 0x0002, // Rx-side link quality
|
||||
GHOST_ID_RX_SNR = 0x0003, // Rx-side signal to noise
|
||||
GHOST_ID_FRAME_RATE = 0x0004, // Tx-side frame rate
|
||||
GHOST_ID_TX_POWER = 0x0005, // Tx-side power output
|
||||
GHOST_ID_RF_MODE = 0x0006, // Tx-side frame rate
|
||||
GHOST_ID_TOTAL_LATENCY = 0x0007, // Tx-side total latency
|
||||
GHOST_ID_VTX_FREQ = 0x0008, // Vtx Frequency (in MHz)
|
||||
GHOST_ID_VTX_POWER = 0x0009, // Vtx Power (in mW)
|
||||
GHOST_ID_VTX_CHAN = 0x000a, // Vtx Channel
|
||||
GHOST_ID_VTX_BAND = 0x000b, // Vtx Band
|
||||
|
||||
};
|
||||
|
||||
const GhostSensor ghostSensors[] = {
|
||||
{GHOST_ID_RX_RSSI, ZSTR_RSSI, UNIT_DB, 0},
|
||||
{GHOST_ID_RX_LQ, ZSTR_RX_QUALITY, UNIT_PERCENT, 0},
|
||||
{GHOST_ID_RX_SNR, ZSTR_RX_SNR, UNIT_DB, 0},
|
||||
|
||||
{GHOST_ID_FRAME_RATE, ZSTR_FRAME_RATE, UNIT_RAW, 0},
|
||||
{GHOST_ID_TX_POWER, ZSTR_TX_POWER, UNIT_MILLIWATTS, 0},
|
||||
{GHOST_ID_RF_MODE, ZSTR_RF_MODE, UNIT_TEXT, 0},
|
||||
{GHOST_ID_TOTAL_LATENCY, ZSTR_TOTAL_LATENCY, UNIT_RAW, 0},
|
||||
|
||||
{GHOST_ID_VTX_FREQ, ZSTR_VTX_FREQ, UNIT_RAW, 0},
|
||||
{GHOST_ID_VTX_POWER, ZSTR_VTX_PWR, UNIT_RAW, 0},
|
||||
{GHOST_ID_VTX_CHAN, ZSTR_VTX_CHAN, UNIT_RAW, 0},
|
||||
{GHOST_ID_VTX_BAND, ZSTR_VTX_BAND, UNIT_TEXT, 0},
|
||||
|
||||
{0x00, NULL, UNIT_RAW, 0},
|
||||
};
|
||||
|
||||
const GhostSensor *getGhostSensor(uint8_t id)
|
||||
{
|
||||
for (const GhostSensor * sensor = ghostSensors; sensor->id; sensor++) {
|
||||
if (id == sensor->id)
|
||||
return sensor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void processGhostTelemetryValue(uint8_t index, int32_t value)
|
||||
{
|
||||
if (!TELEMETRY_STREAMING())
|
||||
return;
|
||||
|
||||
const GhostSensor * sensor = getGhostSensor(index);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_GHOST, sensor->id, 0, 0, value, sensor->unit, sensor->precision);
|
||||
}
|
||||
|
||||
void processGhostTelemetryValueString(const GhostSensor * sensor, const char * str)
|
||||
{
|
||||
int i = 0;
|
||||
if (TELEMETRY_STREAMING()) {
|
||||
do {
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_GHOST, sensor->id, 0, 0, str[i], UNIT_TEXT, i);
|
||||
} while (str[i++] != 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool checkGhostTelemetryFrameCRC()
|
||||
{
|
||||
uint8_t len = telemetryRxBuffer[1];
|
||||
uint8_t crc = crc8(&telemetryRxBuffer[2], len - 1);
|
||||
return (crc == telemetryRxBuffer[len + 1]);
|
||||
}
|
||||
|
||||
uint16_t getTelemetryValue_u16(uint8_t index)
|
||||
{
|
||||
return (telemetryRxBuffer[index] << 8) | telemetryRxBuffer[index + 1];
|
||||
}
|
||||
|
||||
uint32_t getTelemetryValue_s32(uint8_t index)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
val <<= 8, val |= telemetryRxBuffer[index + i];
|
||||
return val;
|
||||
}
|
||||
|
||||
void processGhostTelemetryFrame()
|
||||
{
|
||||
if (!checkGhostTelemetryFrameCRC()) {
|
||||
TRACE("[GS] CRC error");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t id = telemetryRxBuffer[2];
|
||||
switch(id) {
|
||||
case GHST_DL_LINK_STAT:
|
||||
{
|
||||
uint8_t rssiVal = min<uint8_t>(telemetryRxBuffer[3], 100);
|
||||
uint8_t lqVal = min<uint8_t>(telemetryRxBuffer[4], 100);
|
||||
uint8_t snrVal = min<uint8_t>(telemetryRxBuffer[5], 100);
|
||||
|
||||
processGhostTelemetryValue(GHOST_ID_RX_RSSI, rssiVal);
|
||||
processGhostTelemetryValue(GHOST_ID_RX_LQ, lqVal);
|
||||
processGhostTelemetryValue(GHOST_ID_RX_SNR, snrVal);
|
||||
|
||||
// give OpenTx the LQ value, not RSSI
|
||||
if (lqVal) {
|
||||
telemetryData.rssi.set(lqVal);
|
||||
telemetryStreaming = TELEMETRY_TIMEOUT10ms;
|
||||
}
|
||||
else {
|
||||
telemetryData.rssi.reset();
|
||||
telemetryStreaming = 0;
|
||||
}
|
||||
|
||||
processGhostTelemetryValue(GHOST_ID_TX_POWER, getTelemetryValue_u16(6));
|
||||
processGhostTelemetryValue(GHOST_ID_FRAME_RATE, getTelemetryValue_u16(8));
|
||||
processGhostTelemetryValue(GHOST_ID_TOTAL_LATENCY, getTelemetryValue_u16(10));
|
||||
uint8_t rfModeEnum = min<uint8_t>(telemetryRxBuffer[12], GHST_RF_PROFILE_MAX);
|
||||
|
||||
// RF mode string, one char at a time
|
||||
const GhostSensor * sensor = getGhostSensor(GHOST_ID_RF_MODE);
|
||||
const char * rfModeString = ghstRfProfileValue[rfModeEnum];
|
||||
processGhostTelemetryValueString(sensor, rfModeString);
|
||||
break;
|
||||
}
|
||||
|
||||
case GHST_DL_VTX_STAT:
|
||||
{
|
||||
uint8_t vtxBandEnum = min<uint8_t>(telemetryRxBuffer[8], GHST_VTX_BAND_MAX);
|
||||
|
||||
const GhostSensor * sensor = getGhostSensor(GHOST_ID_VTX_BAND);
|
||||
const char * vtxBandString = ghstVtxBandName[vtxBandEnum];
|
||||
|
||||
processGhostTelemetryValue(GHOST_ID_VTX_FREQ, getTelemetryValue_u16(4));
|
||||
processGhostTelemetryValue(GHOST_ID_VTX_POWER, getTelemetryValue_u16(6));
|
||||
processGhostTelemetryValue(GHOST_ID_VTX_CHAN, min<uint8_t>(telemetryRxBuffer[9], 8));
|
||||
processGhostTelemetryValueString(sensor, vtxBandString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processGhostTelemetryData(uint8_t data)
|
||||
{
|
||||
if (telemetryRxBufferCount == 0 && data != GHST_ADDR_RADIO) {
|
||||
TRACE("[GH] address 0x%02X error", data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) {
|
||||
telemetryRxBuffer[telemetryRxBufferCount++] = data;
|
||||
}
|
||||
else {
|
||||
TRACE("[GH] array size %d error", telemetryRxBufferCount);
|
||||
telemetryRxBufferCount = 0;
|
||||
}
|
||||
|
||||
if (telemetryRxBufferCount > 4) {
|
||||
uint8_t length = telemetryRxBuffer[1];
|
||||
if (length + 2 == telemetryRxBufferCount) {
|
||||
processGhostTelemetryFrame();
|
||||
telemetryRxBufferCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ghostSetDefault(int index, uint8_t id, uint8_t subId)
|
||||
{
|
||||
TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index];
|
||||
|
||||
telemetrySensor.id = id;
|
||||
telemetrySensor.instance = subId;
|
||||
|
||||
const GhostSensor * sensor = getGhostSensor(id);
|
||||
if (sensor) {
|
||||
TelemetryUnit unit = sensor->unit;
|
||||
uint8_t prec = min<uint8_t>(2, sensor->precision);
|
||||
telemetrySensor.init(sensor->name, unit, prec);
|
||||
}
|
||||
else
|
||||
telemetrySensor.init(id);
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
114
radio/src/telemetry/ghost.h
Executable file
114
radio/src/telemetry/ghost.h
Executable file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_H_
|
||||
#define _GHOST_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "dataconstants.h"
|
||||
|
||||
// Device (destination) address
|
||||
#define GHST_ADDR_RADIO 0x80 // phase 1
|
||||
#define GHST_ADDR_MODULE 0x81
|
||||
#define GHST_ADDR_FC 0x82
|
||||
#define GHST_ADDR_GOGGLES 0x83 // phase 2
|
||||
#define GHST_ADDR_5G_TXCTRL 0x84 // phase 3
|
||||
#define GHST_ADDR_5G_TWRSCAN 0x85
|
||||
#define GHST_ADDR_5G_RLY 0x86
|
||||
|
||||
#define GHST_UL_RC_CHANS_HS4_5TO8 0x10 // High Speed 4 channel (12 bits), plus CH5-8 (8 bits)
|
||||
#define GHST_UL_RC_CHANS_HS4_9TO12 0x11 // High Speed 4 channel (12 bits), plus CH9-12 (8 bits)
|
||||
#define GHST_UL_RC_CHANS_HS4_13TO16 0x12 // High Speed 4 channel (12 bits), plus CH13-16 (8 bits)
|
||||
#define GHST_UL_RC_CHANS_SIZE 12 // 1 (type) + 10 (data) + 1 (crc)
|
||||
|
||||
#define GHST_DL_OPENTX_SYNC 0x20
|
||||
#define GHST_DL_LINK_STAT 0x21
|
||||
#define GHST_DL_VTX_STAT 0x22
|
||||
|
||||
#define GHST_RC_CTR_VAL_12BIT 0x7C0 // 0x3e0 << 1
|
||||
#define GHST_RC_CTR_VAL_8BIT 0x7C
|
||||
|
||||
#define GHST_CH_BITS_12 12
|
||||
#define GHST_CH_BITS_8 8
|
||||
|
||||
enum GhstPowerMode
|
||||
{
|
||||
GHST_PWR_16UW = 0,
|
||||
GHST_PWR_100UW = 1,
|
||||
GHST_PWR_1MW = 2,
|
||||
GHST_PWR_25MW = 3,
|
||||
GHST_PWR_100MW = 4,
|
||||
GHST_PWR_200MW = 5,
|
||||
GHST_PWR_350MW = 6,
|
||||
GHST_PWR_500MW = 7,
|
||||
GHST_PWR_600MW = 8,
|
||||
GHST_PWR_1W = 9,
|
||||
GHST_PWR_1_5W = 10,
|
||||
GHST_PWR_2W = 11,
|
||||
GHST_PWR_3W = 12,
|
||||
GHST_PWR_4W = 13,
|
||||
GHST_PWR_COUNT
|
||||
};
|
||||
|
||||
enum GhstRFProfile
|
||||
{
|
||||
GHST_RF_PROFILE_Auto = 0,
|
||||
GHST_RF_PROFILE_Normal = 1,
|
||||
GHST_RF_PROFILE_Race = 2,
|
||||
GHST_RF_PROFILE_PureRace = 3,
|
||||
GHST_RF_PROFILE_LongRange = 4,
|
||||
GHST_RF_PROFILE_MAX = GHST_RF_PROFILE_LongRange,
|
||||
GHST_RF_PROFILE_COUNT
|
||||
};
|
||||
|
||||
enum GhstVtxBand
|
||||
{
|
||||
GHST_VTX_BAND_Unknown = 0,
|
||||
GHST_VTX_BAND_Irc = 1,
|
||||
GHST_VTX_BAND_Race = 2,
|
||||
GHST_VTX_BAND_BandE = 3,
|
||||
GHST_VTX_BAND_BandB = 4,
|
||||
GHST_VTX_BAND_BandA = 5,
|
||||
GHST_VTX_BAND_MAX = GHST_VTX_BAND_BandA,
|
||||
GHST_VTX_BAND_COUNT
|
||||
};
|
||||
|
||||
void processGhostTelemetryData(uint8_t data);
|
||||
void ghostSetDefault(int index, uint8_t id, uint8_t subId);
|
||||
|
||||
#if SPORT_MAX_BAUDRATE < 400000
|
||||
// For radios which can't support telemetry at high rates, offer baud rate choices
|
||||
// (modified vs. unmodified radios)
|
||||
const uint32_t GHOST_BAUDRATES[] = {
|
||||
400000,
|
||||
115200,
|
||||
};
|
||||
const uint8_t GHOST_PERIODS[] = {
|
||||
4,
|
||||
16,
|
||||
};
|
||||
#define GHOST_BAUDRATE GHOST_BAUDRATES[g_eeGeneral.telemetryBaudrate]
|
||||
#define GHOST_PERIOD GHOST_PERIODS[g_eeGeneral.telemetryBaudrate]
|
||||
#else
|
||||
#define GHOST_BAUDRATE 400000
|
||||
#define GHOST_PERIOD 4
|
||||
#endif
|
||||
|
||||
#endif // _GHOST_H_
|
|
@ -45,6 +45,13 @@ void processTelemetryData(uint8_t data)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_GHOST) {
|
||||
processGhostTelemetryData(data);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_SPEKTRUM) {
|
||||
processSpektrumTelemetryData(EXTERNAL_MODULE, data, telemetryRxBuffer, telemetryRxBufferCount);
|
||||
|
@ -295,6 +302,16 @@ void telemetryInit(uint8_t protocol)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
else if (protocol == PROTOCOL_TELEMETRY_GHOST) {
|
||||
telemetryPortInit(GHOST_BAUDRATE, TELEMETRY_SERIAL_DEFAULT);
|
||||
#if defined(LUA)
|
||||
outputTelemetryBuffer.reset();
|
||||
#endif
|
||||
telemetryPortSetDirectionOutput();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AUX_SERIAL) || defined(PCBSKY9X)
|
||||
else if (protocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) {
|
||||
telemetryPortInit(0, TELEMETRY_SERIAL_DEFAULT);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "frsky.h"
|
||||
#include "crossfire.h"
|
||||
#include "ghost.h"
|
||||
#include "myeeprom.h"
|
||||
#include "io/frsky_sport.h"
|
||||
|
||||
|
@ -153,6 +154,12 @@ inline uint8_t modelTelemetryProtocol()
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_GHOST) {
|
||||
return PROTOCOL_TELEMETRY_GHOST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sportUsed && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) {
|
||||
return g_model.telemetryProtocol;
|
||||
}
|
||||
|
|
|
@ -526,6 +526,11 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui
|
|||
crossfireSetDefault(index, id, instance);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GHOST)
|
||||
case PROTOCOL_TELEMETRY_GHOST:
|
||||
ghostSetDefault(index, id, instance);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MULTIMODULE) || defined(AFHDS3)
|
||||
case PROTOCOL_TELEMETRY_FLYSKY_IBUS:
|
||||
flySkySetDefault(index,id, subId, instance);
|
||||
|
|
|
@ -260,7 +260,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metr.\0""Imper.", "Metrické""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1350,3 +1350,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -263,7 +263,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\012")
|
||||
#define TR_VUNITSSYSTEM TR("Metrik""Imper.", "Metrisch\0 ""Imperial\0 ")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1357,3 +1357,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -263,7 +263,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1354,3 +1354,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -260,7 +260,7 @@
|
|||
#define LEN_VUNITSSYSTEM "\010"
|
||||
#define TR_VUNITSSYSTEM "Métrico\0""Imperial"
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1353,3 +1353,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -281,7 +281,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1361,3 +1361,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -283,7 +283,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\012")
|
||||
#define TR_VUNITSSYSTEM TR("Métr.\0""Impér.", "Métriques\0""Impériales")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1378,3 +1378,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -284,7 +284,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\011")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metriche\0""Imperiali")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1371,3 +1371,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -264,7 +264,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Mtrsch""Engels", "Metrisch\0 ""Engels\0 ")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1363,3 +1363,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -281,7 +281,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010") /*8 decimal*/
|
||||
#define TR_VUNITSSYSTEM TR("Metr. ""Imper.", "Metryczn""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1370,3 +1370,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -277,7 +277,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1359,3 +1359,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -278,7 +278,7 @@
|
|||
#define LEN_VUNITSSYSTEM TR("\006", "\010")
|
||||
#define TR_VUNITSSYSTEM TR("Metri.""Imper.", "Metriska""Imperial")
|
||||
#define LEN_VTELEMUNIT "\003"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz"
|
||||
#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0"
|
||||
|
||||
#define STR_V (STR_VTELEMUNIT+1)
|
||||
#define STR_A (STR_VTELEMUNIT+4)
|
||||
|
@ -1370,3 +1370,9 @@
|
|||
#define ZSTR_CL16 "Cl16"
|
||||
#define ZSTR_CL17 "Cl17"
|
||||
#define ZSTR_CL18 "Cl18"
|
||||
#define ZSTR_FRAME_RATE "FRat"
|
||||
#define ZSTR_TOTAL_LATENCY "TLat"
|
||||
#define ZSTR_VTX_FREQ "VFrq"
|
||||
#define ZSTR_VTX_PWR "VPwr"
|
||||
#define ZSTR_VTX_CHAN "VChn"
|
||||
#define ZSTR_VTX_BAND "VBan"
|
|
@ -87,7 +87,7 @@
|
|||
#endif
|
||||
|
||||
#define LEN_EXTERNAL_MODULE_PROTOCOLS "\014"
|
||||
#define TR_EXTERNAL_MODULE_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""ISRM\0 ""DSM2\0 ""CRSF\0 ""MULTI\0 ""R9M\0 ""R9M ACCESS\0 " TR_MODULE_R9M_LITE "R9ML ACCESS\0""R9MLP\0 ""R9MLP ACCESS""SBUS\0 ""XJT Lite\0 ""AFHDS3"
|
||||
#define TR_EXTERNAL_MODULE_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""ISRM\0 ""DSM2\0 ""CRSF\0 ""MULTI\0 ""R9M\0 ""R9M ACCESS\0 " TR_MODULE_R9M_LITE "R9ML ACCESS\0""GHST\0 ""R9MLP ACCESS""SBUS\0 ""XJT Lite\0 ""AFHDS3\0 "
|
||||
|
||||
#define LEN_INTERNAL_MODULE_PROTOCOLS LEN_EXTERNAL_MODULE_PROTOCOLS
|
||||
#define TR_INTERNAL_MODULE_PROTOCOLS TR_EXTERNAL_MODULE_PROTOCOLS
|
||||
|
|
|
@ -38,6 +38,9 @@ for i, (s, f) in enumerate([("volt", "volt0"), ("volts", "volt1"),
|
|||
("milliliter", "ml0"), ("milliliters", "ml1"),
|
||||
("fluid ounce", "founce0"), ("fluid ounces", "founce1"),
|
||||
("milliliter per minute", "mlpm0"), ("milliliters per minute", "mlpm1"),
|
||||
("hertz", "hertz0"), ("hertz", "hertz1"),
|
||||
("milisecond", "ms0"), ("miliseconds", "ms1"),
|
||||
("microsecond", "us0"), ("microseconds", "us1"),
|
||||
("hour", "hour0"), ("hours", "hour1"),
|
||||
("minute", "minute0"), ("minutes", "minute1"),
|
||||
("second", "second0"), ("seconds", "second1"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue