feat: ELRS bind command support (#4907)
This commit is contained in:
@@ -1837,7 +1837,10 @@ void menuModelSetup(event_t event)
|
||||
l_posHorz += 1;
|
||||
}
|
||||
if (isModuleBindRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (TELEMETRY_STREAMING() && isModuleELRS(moduleIdx))
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_UNBIND, l_posHorz == 1 ? attr : 0);
|
||||
else
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (isModuleRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(lcdNextPos + 2, y, STR_MODULE_RANGE, l_posHorz == 2 ? attr : 0);
|
||||
}
|
||||
@@ -1881,6 +1884,8 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
else {
|
||||
newFlag = MODULE_MODE_BIND;
|
||||
if (isModuleELRS(moduleIdx))
|
||||
AUDIO_PLAY(AU_SPECIAL_SOUND_CHEEP); // Since ELRS bind is just one frame, we need to play the sound manually
|
||||
}
|
||||
|
||||
if (!event && (oldFlag != newFlag) &&
|
||||
|
||||
@@ -1562,7 +1562,10 @@ void menuModelSetup(event_t event)
|
||||
l_posHorz += 1;
|
||||
}
|
||||
if (isModuleBindRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (TELEMETRY_STREAMING() && isModuleCrossfire(moduleIdx))
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_UNBIND, l_posHorz == 1 ? attr : 0);
|
||||
else
|
||||
lcdDrawText(bindButtonPos, y, STR_MODULE_BIND, l_posHorz == 1 ? attr : 0);
|
||||
if (isModuleRangeAvailable(moduleIdx)) {
|
||||
lcdDrawText(lcdNextPos + FW, y, STR_MODULE_RANGE, l_posHorz == 2 ? attr : 0);
|
||||
}
|
||||
@@ -1600,6 +1603,8 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
else {
|
||||
newFlag = MODULE_MODE_BIND;
|
||||
if (isModuleCrossfire(moduleIdx))
|
||||
AUDIO_PLAY(AU_SPECIAL_SOUND_CHEEP); // Since ELRS bind is just one frame, we need to play the sound manually
|
||||
}
|
||||
|
||||
if (!event && (oldFlag != newFlag) &&
|
||||
|
||||
@@ -102,6 +102,8 @@ class ModuleWindow : public Window
|
||||
void startRSSIDialog(std::function<void()> closeHandler = nullptr);
|
||||
|
||||
void updateIDStaticText(int mdIdx);
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
struct FailsafeChoice : public Window {
|
||||
@@ -156,6 +158,19 @@ ModuleWindow::ModuleWindow(Window* parent, uint8_t moduleIdx) :
|
||||
lv_obj_add_event_cb(lvobj, mw_refresh_cb, LV_EVENT_REFRESH, this);
|
||||
}
|
||||
|
||||
void ModuleWindow::checkEvents()
|
||||
{
|
||||
if (bindButton != nullptr) {
|
||||
if (TELEMETRY_STREAMING() && isModuleELRS(moduleIdx))
|
||||
bindButton->setText(STR_MODULE_UNBIND);
|
||||
else if (isModuleELRS(moduleIdx))
|
||||
bindButton->setText(STR_MODULE_BIND);
|
||||
|
||||
bindButton->show(isModuleBindRangeAvailable(moduleIdx));
|
||||
}
|
||||
Window::checkEvents();
|
||||
}
|
||||
|
||||
void ModuleWindow::updateIDStaticText(int mdIdx)
|
||||
{
|
||||
if (idUnique == nullptr) return;
|
||||
@@ -280,7 +295,7 @@ void ModuleWindow::updateModule()
|
||||
}
|
||||
});
|
||||
|
||||
if (isModuleBindRangeAvailable(moduleIdx)) {
|
||||
if (isModuleBindRangeAvailable(moduleIdx) || isModuleCrossfire(moduleIdx)) {
|
||||
bindButton = new TextButton(box, rect_t{}, STR_MODULE_BIND);
|
||||
bindButton->setPressHandler([=]() -> uint8_t {
|
||||
if (moduleState[moduleIdx].mode == MODULE_MODE_RANGECHECK) {
|
||||
@@ -312,6 +327,8 @@ void ModuleWindow::updateModule()
|
||||
}
|
||||
#endif
|
||||
moduleState[moduleIdx].mode = MODULE_MODE_BIND;
|
||||
if (isModuleELRS(moduleIdx))
|
||||
AUDIO_PLAY(AU_SPECIAL_SOUND_CHEEP); // Since ELRS bind is just one frame, we need to play the sound manually
|
||||
#if defined(AFHDS2)
|
||||
if (isModuleAFHDS2A(moduleIdx)) {
|
||||
resetPulsesAFHDS2();
|
||||
|
||||
@@ -126,7 +126,7 @@ class VersionDialog : public BaseDialog
|
||||
new StaticText(int_rx_name_w, rect_t{}, "");
|
||||
int_rx_name_w->hide();
|
||||
|
||||
// internal reciever status
|
||||
// internal receiver status
|
||||
int_rx_status_w = form->newLine(grid);
|
||||
new StaticText(int_rx_status_w, rect_t{}, STR_STATUS);
|
||||
int_rx_status =
|
||||
@@ -195,6 +195,8 @@ class VersionDialog : public BaseDialog
|
||||
// snprintf(statusText, 64, "%d Hz %" PRIu32 " Err", hz, telemetryErrors);
|
||||
snprintf(statusText, 64, "%d Hz", hz);
|
||||
status->setText(statusText);
|
||||
snprintf(statusText, 64, "%s V%u.%u.%u", crossfireModuleStatus[module].name, crossfireModuleStatus[module].major, crossfireModuleStatus[module].minor, crossfireModuleStatus[module].revision);
|
||||
name->setText(statusText);
|
||||
module_status_w->show();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define MENU_BODY_TOP (FH + 1)
|
||||
#define MENU_BODY_BOTTOM (LCD_H)
|
||||
|
||||
#if defined(PXX2)
|
||||
#if defined(PXX2) || defined(CROSSFIRE)
|
||||
constexpr uint8_t COLUMN2_X = 10 * FW;
|
||||
#endif
|
||||
|
||||
@@ -84,7 +84,8 @@ void drawPXX2FullVersion(coord_t x, coord_t y, PXX2Version hwVersion, PXX2Versio
|
||||
lcdDrawText(lcdNextPos, y, "/");
|
||||
drawPXX2Version(lcdNextPos, y, swVersion);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(PXX2) || defined(CROSSFIRE)
|
||||
void menuRadioModulesVersion(event_t event)
|
||||
{
|
||||
if (menuEvent) {
|
||||
@@ -95,8 +96,8 @@ void menuRadioModulesVersion(event_t event)
|
||||
}
|
||||
|
||||
title(STR_MENU_MODULES_RX_VERSION);
|
||||
|
||||
if (event == EVT_ENTRY) {
|
||||
#if defined(PXX2)
|
||||
if (event == EVT_ENTRY) {
|
||||
memclear(&reusableBuffer.hardwareAndSettings.modules, sizeof(reusableBuffer.hardwareAndSettings.modules));
|
||||
}
|
||||
|
||||
@@ -116,6 +117,7 @@ void menuRadioModulesVersion(event_t event)
|
||||
|
||||
reusableBuffer.hardwareAndSettings.updateTime = get_tmr10ms() + 1000 /* 10s*/;
|
||||
}
|
||||
#endif
|
||||
|
||||
coord_t y = (FH + 1) - menuVerticalOffset * FH;
|
||||
|
||||
@@ -166,6 +168,14 @@ void menuRadioModulesVersion(event_t event)
|
||||
1000000 / getMixerSchedulerPeriod()/*, UINT32_C(telemetryErrors)*/);
|
||||
lcdDrawText(COLUMN2_X, y, statusText);
|
||||
y += FH;
|
||||
lcdDrawText(INDENT_WIDTH, y, crossfireModuleStatus[module].name);
|
||||
lcdDrawChar(lcdNextPos + 5, y, 'V');
|
||||
lcdDrawNumber(lcdNextPos, y, crossfireModuleStatus[module].major);
|
||||
lcdDrawChar(lcdNextPos, y, '.');
|
||||
lcdDrawNumber(lcdNextPos, y, crossfireModuleStatus[module].minor);
|
||||
lcdDrawChar(lcdNextPos, y, '.');
|
||||
lcdDrawNumber(lcdNextPos, y, crossfireModuleStatus[module].revision);
|
||||
y += FH;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -174,12 +184,14 @@ void menuRadioModulesVersion(event_t event)
|
||||
y += FH;
|
||||
continue;
|
||||
}
|
||||
#if defined(PXX2)
|
||||
uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module]
|
||||
.information.modelID;
|
||||
lcdDrawText(COLUMN2_X, y, getPXX2ModuleName(modelId));
|
||||
#endif
|
||||
}
|
||||
y += FH;
|
||||
|
||||
#if defined(PXX2)
|
||||
// Module version
|
||||
if (y >= MENU_BODY_TOP && y < MENU_BODY_BOTTOM) {
|
||||
if (reusableBuffer.hardwareAndSettings.modules[module].information.modelID) {
|
||||
@@ -211,6 +223,7 @@ void menuRadioModulesVersion(event_t event)
|
||||
y += FH;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t lines = (y - (FH + 1)) / FH + menuVerticalOffset;
|
||||
@@ -243,7 +256,7 @@ enum MenuRadioVersionItems
|
||||
#if defined(PCBTARANIS)
|
||||
ITEM_RADIO_FIRMWARE_OPTIONS,
|
||||
#endif
|
||||
#if defined(PXX2)
|
||||
#if defined(PXX2) || defined(CROSSFIRE)
|
||||
ITEM_RADIO_MODULES_VERSION,
|
||||
#endif
|
||||
ITEM_RADIO_VERSION_COUNT
|
||||
@@ -266,7 +279,7 @@ void menuRadioVersion(event_t event)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PXX2)
|
||||
#if defined(PXX2) || defined(CROSSFIRE)
|
||||
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_MODULES_RX_VERSION), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0);
|
||||
y += FH;
|
||||
if (menuVerticalPosition == ITEM_RADIO_MODULES_VERSION && event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
|
||||
@@ -1261,6 +1261,9 @@ uint8_t MENU_FIRST_LINE_EDIT(const uint8_t * horTab, uint8_t horTabMax)
|
||||
|
||||
uint8_t MODULE_BIND_ROWS(int moduleIdx)
|
||||
{
|
||||
if (isModuleELRS(moduleIdx) && (crossfireModuleStatus[moduleIdx].major >= 4 || (crossfireModuleStatus[moduleIdx].major == 3 && crossfireModuleStatus[moduleIdx].minor >= 4)))
|
||||
return 1;
|
||||
|
||||
if (isModuleCrossfire(moduleIdx))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -42,6 +42,36 @@
|
||||
|
||||
#define MIN_FRAME_LEN 3
|
||||
|
||||
uint8_t createCrossfireBindFrame(uint8_t moduleIdx, uint8_t * frame)
|
||||
{
|
||||
uint8_t * buf = frame;
|
||||
*buf++ = UART_SYNC; /* device address */
|
||||
*buf++ = 7; /* frame length */
|
||||
*buf++ = COMMAND_ID; /* cmd type */
|
||||
if (TELEMETRY_STREAMING())
|
||||
*buf++ = RECEIVER_ADDRESS; /* Destination is receiver (unbind) */
|
||||
else
|
||||
*buf++ = MODULE_ADDRESS; /* Destination is module */
|
||||
*buf++ = RADIO_ADDRESS; /* Origin Address */
|
||||
*buf++ = SUBCOMMAND_CRSF; /* sub command */
|
||||
*buf++ = SUBCOMMAND_CRSF_BIND; /* initiate bind */
|
||||
*buf++ = crc8_BA(frame + 2, 5);
|
||||
*buf++ = crc8(frame + 2, 6);
|
||||
return buf - frame;
|
||||
}
|
||||
|
||||
uint8_t createCrossfirePingFrame(uint8_t moduleIdx, uint8_t * frame)
|
||||
{
|
||||
uint8_t * buf = frame;
|
||||
*buf++ = UART_SYNC; /* device address */
|
||||
*buf++ = 4; /* frame length */
|
||||
*buf++ = PING_DEVICES_ID; /* cmd type */
|
||||
*buf++ = BROADCAST_ADDRESS; /* Destination Address */
|
||||
*buf++ = RADIO_ADDRESS; /* Origin Address */
|
||||
*buf++ = crc8(frame + 2, 3);
|
||||
return buf - frame;
|
||||
}
|
||||
|
||||
uint8_t createCrossfireModelIDFrame(uint8_t moduleIdx, uint8_t * frame)
|
||||
{
|
||||
uint8_t * buf = frame;
|
||||
@@ -98,6 +128,11 @@ static void setupPulsesCrossfire(uint8_t module, uint8_t*& p_buf,
|
||||
if (moduleState[module].counter == CRSF_FRAME_MODELID) {
|
||||
p_buf += createCrossfireModelIDFrame(module, p_buf);
|
||||
moduleState[module].counter = CRSF_FRAME_MODELID_SENT;
|
||||
} else if (moduleState[module].counter == CRSF_FRAME_MODELID_SENT && crossfireModuleStatus[module].queryCompleted == false) {
|
||||
p_buf += createCrossfirePingFrame(module, p_buf);
|
||||
} else if (moduleState[module].mode == MODULE_MODE_BIND) {
|
||||
p_buf += createCrossfireBindFrame(module, p_buf);
|
||||
moduleState[module].mode = MODULE_MODE_NORMAL;
|
||||
} else {
|
||||
/* TODO: nChannels */
|
||||
p_buf += createCrossfireChannelsFrame(p_buf, channels);
|
||||
@@ -307,6 +342,8 @@ static void* crossfireInit(uint8_t module)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
memset(&crossfireModuleStatus[module], 0, sizeof(crossfireModuleStatus[module]));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -321,6 +358,8 @@ static void crossfireDeInit(void* ctx)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
|
||||
memset(&crossfireModuleStatus[modulePortGetModule(mod_st)], 0, sizeof(crossfireModuleStatus[modulePortGetModule(mod_st)]));
|
||||
|
||||
#if !defined(SIMU)
|
||||
if (mod_st && (modulePortGetModule(mod_st) == EXTERNAL_MODULE)) {
|
||||
auto drv = modulePortGetSerialDrv(mod_st->rx);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "globals.h"
|
||||
#include "MultiProtoDefs.h"
|
||||
#include "hal/module_port.h"
|
||||
#include "telemetry/crossfire.h"
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
#include "telemetry/multi.h"
|
||||
@@ -227,6 +228,11 @@ inline bool isModuleCrossfire(uint8_t idx)
|
||||
return g_model.moduleData[idx].type == MODULE_TYPE_CROSSFIRE;
|
||||
}
|
||||
|
||||
inline bool isModuleELRS(uint8_t idx)
|
||||
{
|
||||
return crossfireModuleStatus[idx].isELRS;
|
||||
}
|
||||
|
||||
inline bool isInternalModuleCrossfire()
|
||||
{
|
||||
return g_eeGeneral.internalModule == MODULE_TYPE_CROSSFIRE;
|
||||
@@ -237,6 +243,11 @@ inline bool isModuleCrossfire(uint8_t idx)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isModuleELRS(uint8_t idx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isInternalModuleCrossfire()
|
||||
{
|
||||
return false;
|
||||
@@ -607,7 +618,8 @@ inline bool isModuleBindRangeAvailable(uint8_t moduleIdx)
|
||||
{
|
||||
return isModulePXX2(moduleIdx) || isModulePXX1(moduleIdx) ||
|
||||
isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx) ||
|
||||
isModuleFlySky(moduleIdx) || isModuleDSMP(moduleIdx);
|
||||
isModuleFlySky(moduleIdx) || isModuleDSMP(moduleIdx) ||
|
||||
(isModuleELRS(moduleIdx) && (crossfireModuleStatus[moduleIdx].major >= 4 || (crossfireModuleStatus[moduleIdx].major == 3 && crossfireModuleStatus[moduleIdx].minor >= 4)));
|
||||
}
|
||||
|
||||
inline uint32_t getNV14RfFwVersion()
|
||||
@@ -621,7 +633,7 @@ inline uint32_t getNV14RfFwVersion()
|
||||
|
||||
inline bool isModuleRangeAvailable(uint8_t moduleIdx)
|
||||
{
|
||||
bool ret = isModuleBindRangeAvailable(moduleIdx) && !IS_RX_MULTI(moduleIdx);
|
||||
bool ret = isModuleBindRangeAvailable(moduleIdx) && !IS_RX_MULTI(moduleIdx) && !isModuleCrossfire(moduleIdx);
|
||||
#if defined(PCBNV14) && defined(AFHDS2)
|
||||
ret = ret &&
|
||||
(!isModuleAFHDS2A(moduleIdx) || NV14internalModuleFwVersion >= 0x1000E);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "crossfire.h"
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
// clang-format off
|
||||
@@ -62,6 +61,8 @@ const CrossfireSensor crossfireSensors[] = {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
CrossfireModuleStatus crossfireModuleStatus[2] = {0};
|
||||
|
||||
const CrossfireSensor & getCrossfireSensor(uint8_t id, uint8_t subId)
|
||||
{
|
||||
if (id == LINK_ID)
|
||||
@@ -260,6 +261,18 @@ void processCrossfireTelemetryFrame(uint8_t module, uint8_t* rxBuffer,
|
||||
|
||||
#if defined(LUA)
|
||||
default:
|
||||
if (id == DEVICE_INFO_ID && rxBuffer[4]== MODULE_ADDRESS) {
|
||||
uint8_t nameSize = rxBuffer[1] - 18;
|
||||
strncpy((char *)&crossfireModuleStatus[module].name, (const char *)&rxBuffer[5], CRSF_NAME_MAXSIZE);
|
||||
crossfireModuleStatus[module].name[CRSF_NAME_MAXSIZE -1] = 0; // For some reason, GH din't like strlcpy
|
||||
if (strncmp((const char *) &rxBuffer[5 + nameSize], "ELRS", 4) == 0)
|
||||
crossfireModuleStatus[module].isELRS = true;
|
||||
crossfireModuleStatus[module].major = rxBuffer[14 + nameSize];
|
||||
crossfireModuleStatus[module].minor = rxBuffer[15 + nameSize];
|
||||
crossfireModuleStatus[module].revision = rxBuffer[16 + nameSize];
|
||||
crossfireModuleStatus[module].queryCompleted = true;
|
||||
}
|
||||
|
||||
if (luaInputTelemetryFifo && luaInputTelemetryFifo->hasSpace(rxBufferCount - 2)) {
|
||||
for (uint8_t i = 1; i < rxBufferCount - 1; i++) {
|
||||
// destination address and CRC are skipped
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define BROADCAST_ADDRESS 0x00
|
||||
#define RADIO_ADDRESS 0xEA
|
||||
#define MODULE_ADDRESS 0xEE
|
||||
#define RECEIVER_ADDRESS 0xEC
|
||||
|
||||
// Frame id
|
||||
#define GPS_ID 0x02
|
||||
@@ -50,6 +51,9 @@
|
||||
#define UART_SYNC 0xC8
|
||||
#define SUBCOMMAND_CRSF 0x10
|
||||
#define COMMAND_MODEL_SELECT_ID 0x05
|
||||
#define SUBCOMMAND_CRSF_BIND 0x01
|
||||
|
||||
constexpr uint8_t CRSF_NAME_MAXSIZE = 16;
|
||||
|
||||
struct CrossfireSensor {
|
||||
const uint8_t id;
|
||||
@@ -100,6 +104,18 @@ enum CrossfireFrames{
|
||||
CRSF_FRAME_MODELID_SENT
|
||||
};
|
||||
|
||||
struct CrossfireModuleStatus
|
||||
{
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t revision;
|
||||
char name[CRSF_NAME_MAXSIZE];
|
||||
bool queryCompleted;
|
||||
bool isELRS;
|
||||
};
|
||||
|
||||
extern CrossfireModuleStatus crossfireModuleStatus[2];
|
||||
|
||||
void processCrossfireTelemetryFrame(uint8_t module, uint8_t* rxBuffer,
|
||||
uint8_t rxBufferCount);
|
||||
void crossfireSetDefault(int index, uint8_t id, uint8_t subId);
|
||||
|
||||
@@ -586,6 +586,7 @@ const char STR_EXPONAME[] = TR_EXPONAME;
|
||||
const char STR_TRAINER[] = TR_TRAINER;
|
||||
const char STR_CHANS[] = TR_CHANS;
|
||||
const char STR_MODULE_BIND[] = TR_MODULE_BIND;
|
||||
const char STR_MODULE_UNBIND[] = TR_MODULE_UNBIND;
|
||||
const char STR_POWERMETER_ATTN_NEEDED[] = TR_POWERMETER_ATTN_NEEDED;
|
||||
const char STR_PXX2_SELECT_RX[] = TR_PXX2_SELECT_RX;
|
||||
const char STR_PXX2_DEFAULT[] = TR_PXX2_DEFAULT;
|
||||
|
||||
@@ -986,6 +986,7 @@ extern const char STR_EXPONAME[];
|
||||
extern const char STR_TRAINER[];
|
||||
extern const char STR_CHANS[];
|
||||
extern const char STR_MODULE_BIND[];
|
||||
extern const char STR_MODULE_UNBIND[];
|
||||
extern const char STR_POWERMETER_ATTN_NEEDED[];
|
||||
extern const char STR_PXX2_SELECT_RX[];
|
||||
extern const char STR_PXX2_DEFAULT[];
|
||||
|
||||
@@ -853,7 +853,8 @@
|
||||
#define TR_BUZZER "蜂鸣器"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("对频", "对频"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "需要串联衰减器"
|
||||
#define TR_MODULE_UNBIND BUTTON("解绑")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "需要串联衰减器"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "选择设备"
|
||||
|
||||
@@ -864,7 +864,8 @@
|
||||
#define TR_BUZZER "Pípák"
|
||||
#define TR_BYTES "[B]"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Útlumový člen nutný!"
|
||||
#define TR_MODULE_UNBIND BUTTON("Odpárovat")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Útlumový člen nutný!"
|
||||
#define TR_PXX2_SELECT_RX "Vyber RX..."
|
||||
#define TR_PXX2_DEFAULT "<výchozí>"
|
||||
#define TR_BT_SELECT_DEVICE "Vyberte zařízení"
|
||||
|
||||
@@ -858,7 +858,8 @@
|
||||
#define TR_BUZZER "Biper"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Tils", "Tilslut"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attestering nødvendig"
|
||||
#define TR_MODULE_UNBIND BUTTON("Afkobl")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attestering nødvendig"
|
||||
#define TR_PXX2_SELECT_RX "Vælg RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Vælg enhed"
|
||||
|
||||
@@ -852,6 +852,7 @@
|
||||
#define TR_BUZZER "Summer"
|
||||
#define TR_BYTES "Bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd","Binden")) //9XR-Pro
|
||||
#define TR_MODULE_UNBIND BUTTON("Trennen")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Dämpfungsgl. nötig"
|
||||
#define TR_PXX2_SELECT_RX "Wähle RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
|
||||
@@ -858,7 +858,8 @@
|
||||
#define TR_BUZZER "Buzzer"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Select device"
|
||||
|
||||
@@ -848,7 +848,8 @@
|
||||
#define TR_BUZZER "Zumbador"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND "[Enl.]"
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Necesita atenuador"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Necesita atenuador"
|
||||
#define TR_PXX2_SELECT_RX "Selecciona RX..."
|
||||
#define TR_PXX2_DEFAULT "<defecto>"
|
||||
#define TR_BT_SELECT_DEVICE "Selecciona dispositivo"
|
||||
|
||||
@@ -863,7 +863,8 @@
|
||||
#define TR_BUZZER "Buzzer"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND "[Bind]"
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Tarvitaan vaimennin"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Tarvitaan vaimennin"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Select device"
|
||||
|
||||
@@ -854,6 +854,7 @@
|
||||
#define TR_BUZZER "Bipeur"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_MODULE_UNBIND BUTTON("Délier")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Atténuateur requis"
|
||||
#define TR_PXX2_SELECT_RX "Sélection RX..."
|
||||
#define TR_PXX2_DEFAULT "<défaut>"
|
||||
|
||||
@@ -857,7 +857,8 @@
|
||||
#define TR_BUZZER "זמזם"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "צימוד"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "בחר מכשיר"
|
||||
|
||||
@@ -852,6 +852,7 @@
|
||||
#define TR_BUZZER "Buzzer"
|
||||
#define TR_BYTES "Bytes"
|
||||
#define TR_MODULE_BIND TR("[Bnd]","[Bind]")
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuatore necessario"
|
||||
#define TR_PXX2_SELECT_RX "Seleziona RX..."
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
|
||||
@@ -857,7 +857,8 @@
|
||||
#define TR_BUZZER "ブザー"
|
||||
#define TR_BYTES "バイト"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "減衰器が必要です"
|
||||
#define TR_MODULE_UNBIND BUTTON("バインド解除")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "減衰器が必要です"
|
||||
#define TR_PXX2_SELECT_RX "受信機選択"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "デバイス選択"
|
||||
|
||||
@@ -849,7 +849,8 @@
|
||||
#define TR_BUZZER "Zoemer"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND TR("[Bnd]", "[Bind]")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Select device"
|
||||
|
||||
@@ -850,7 +850,8 @@
|
||||
#define TR_BUZZER "Brzęczyk"
|
||||
#define TR_BYTES "bajty"
|
||||
#define TR_MODULE_BIND TR("[BND]","[Bind]")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Wybierz urządzenie"
|
||||
|
||||
@@ -861,7 +861,8 @@
|
||||
#define TR_BUZZER "Buzzer"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Select device"
|
||||
|
||||
@@ -860,7 +860,8 @@
|
||||
#define TR_BUZZER "Звук сигнал"
|
||||
#define TR_BYTES "Байты"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Требуется аттенюатор"
|
||||
#define TR_MODULE_UNBIND BUTTON("Unbind")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Требуется аттенюатор"
|
||||
#define TR_PXX2_SELECT_RX "Выбор RX"
|
||||
#define TR_PXX2_DEFAULT "<По умолчанию>"
|
||||
#define TR_BT_SELECT_DEVICE "Выбор устройства"
|
||||
|
||||
@@ -872,7 +872,8 @@
|
||||
#define TR_BUZZER "Summer"
|
||||
#define TR_BYTES "byte"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator behövs"
|
||||
#define TR_MODULE_UNBIND BUTTON("Glöm")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Attenuator behövs"
|
||||
#define TR_PXX2_SELECT_RX "Välj Rx"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "Välj enhet"
|
||||
|
||||
@@ -858,7 +858,8 @@
|
||||
#define TR_BUZZER "蜂鳴器"
|
||||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("對頻", "對頻"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "需要串聯衰減器"
|
||||
#define TR_MODULE_UNBIND BUTTON("解綁")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "需要串聯衰減器"
|
||||
#define TR_PXX2_SELECT_RX "Select RX"
|
||||
#define TR_PXX2_DEFAULT "<default>"
|
||||
#define TR_BT_SELECT_DEVICE "選擇設備"
|
||||
|
||||
@@ -860,7 +860,8 @@
|
||||
#define TR_BUZZER "Дзвоник"
|
||||
#define TR_BYTES "байти"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Прив.", "Прив'язати"))
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Потрібен атенюатор"
|
||||
#define TR_MODULE_UNBIND BUTTON("Відв'язати")
|
||||
#define TR_POWERMETER_ATTN_NEEDED "Потрібен атенюатор"
|
||||
#define TR_PXX2_SELECT_RX "Оберіть RX"
|
||||
#define TR_PXX2_DEFAULT "<замовч>"
|
||||
#define TR_BT_SELECT_DEVICE "Оберіть пристрій"
|
||||
|
||||
Reference in New Issue
Block a user