From 02e804f55c164bd82061d51a3ca82b4eb50724e2 Mon Sep 17 00:00:00 2001 From: Xy2019 <46518305+Xy2019@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:36:43 +0800 Subject: [PATCH] fix(afhds3): Unable to set SBUS, IBUS display issue, indiv channel PWM freq (#3443) * Fix the BUG of V0 receiver setting IBUS SBUS; add the setting item of INRM301. * Fix check failure; remove some unused characters. * Fix typos and rename variables as well as fix compilation errors. * add language --- radio/src/gui/colorlcd/afhds3_options.cpp | 210 +++++++++++++++--- radio/src/gui/colorlcd/afhds3_options.h | 9 + radio/src/pulses/afhds3.cpp | 247 +++++++++++++++------- radio/src/pulses/afhds3_config.h | 12 ++ radio/src/pulses/afhds3_transport.h | 8 + radio/src/translations.cpp | 7 + radio/src/translations.h | 7 + radio/src/translations/cn.h | 6 + radio/src/translations/cz.h | 6 + radio/src/translations/da.h | 6 + radio/src/translations/de.h | 6 + radio/src/translations/en.h | 6 + radio/src/translations/es.h | 6 + radio/src/translations/fi.h | 6 + radio/src/translations/fr.h | 6 + radio/src/translations/it.h | 6 + radio/src/translations/jp.h | 12 +- radio/src/translations/nl.h | 6 + radio/src/translations/pl.h | 6 + radio/src/translations/pt.h | 6 + radio/src/translations/se.h | 16 +- radio/src/translations/tw.h | 12 +- 22 files changed, 495 insertions(+), 117 deletions(-) diff --git a/radio/src/gui/colorlcd/afhds3_options.cpp b/radio/src/gui/colorlcd/afhds3_options.cpp index c2199135e..02b9438d9 100644 --- a/radio/src/gui/colorlcd/afhds3_options.cpp +++ b/radio/src/gui/colorlcd/afhds3_options.cpp @@ -32,17 +32,128 @@ static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, #define SET_DIRTY() static const char* _analog_outputs[] = { "PWM", "PPM" }; -static const char* _bus_types[] = { "iBUS", "iBUS2", "SBUS" }; +static const char* _bus_types[] = { "iBUS OUT", "iBUS IN", "SBUS" }; static const char* _v1_bus_types[] = { "PWM", "PPM", "SBUS", "iBUS IN", "iBUS OUT" }; +static const char* _v1_pwmfreq_types[] = { STR_ANALOG_SERVO, STR_DIGITAL_SERVO, "SR833HZ", "SFR1000HZ", STR_MULTI_CUSTOM }; +static const char* _v0_pwmfreq_types[] = { STR_ANALOG_SERVO, STR_DIGITAL_SERVO, STR_MULTI_CUSTOM }; + +static const uint16_t _v1_index2pwmvalue[] = {50, 333, 2, 1, 50}; +static const uint16_t _v0_index2pwmvalue[] = {50, 333, 50}; +static uint16_t _v1_pwmvalue_type[2][32] = {0xff}; +static uint8_t channel_num[]={18, 10, 18, 8, 12}; + + + +static void pwmfreq_changed(lv_event_t* e) +{ + auto obj = lv_event_get_target(e); + auto dat = (Choice*)lv_obj_get_user_data(obj); + if (!dat) return; + + auto num_edit_obj = (lv_obj_t*)lv_event_get_user_data(e); + if (!num_edit_obj) return; + + if (dat->getIntValue() == 4) { + lv_obj_clear_flag(num_edit_obj, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_add_flag(num_edit_obj, LV_OBJ_FLAG_HIDDEN); + } +} +static void pwmfreq_changedV0(lv_event_t* e) +{ + auto obj = lv_event_get_target(e); + auto dat = (Choice*)lv_obj_get_user_data(obj); + if (!dat) return; + + auto num_edit_obj = (lv_obj_t*)lv_event_get_user_data(e); + if (!num_edit_obj) return; + + if (dat->getIntValue() == 2) { + lv_obj_clear_flag(num_edit_obj, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_add_flag(num_edit_obj, LV_OBJ_FLAG_HIDDEN); + } +} +PWMfrequencyChoice::PWMfrequencyChoice(Window* parent, uint8_t moduleIdx, uint8_t channelIdx) : + FormGroup(parent, rect_t{}) +{ + setFlexLayout(LV_FLEX_FLOW_ROW); + lv_obj_set_width(lvobj, LV_SIZE_CONTENT); + uint16_t &pwmvalue_type = _v1_pwmvalue_type[moduleIdx][channelIdx]; + auto vCfg = &afhds3::getConfig(moduleIdx)->v1; + if( 0xff ==pwmvalue_type ) + { + if ( 50 == vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] ) pwmvalue_type = 0; + else if ( 333 == vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] ) pwmvalue_type = 1; + else if ( 2 == vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] ) pwmvalue_type = 2; + else if ( 1 == vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] ) pwmvalue_type = 3; + else pwmvalue_type = 4; + } + auto choice = new Choice(this, rect_t{}, _v1_pwmfreq_types, 0, 4, + [=,&pwmvalue_type]{ + return pwmvalue_type; + }, + [=,&pwmvalue_type](int32_t newValue) { + pwmvalue_type=newValue; + vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] = _v1_index2pwmvalue[newValue]; + }); + auto num_edit = new NumberEdit(this, rect_t{}, 50, 400, + [=,&pwmvalue_type] { return (pwmvalue_type==4?vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx]:50); }, + [=](int16_t newVal) { + vCfg->PWMFrequenciesV1.PWMFrequencies[channelIdx] = newVal; + }); + c_obj = choice->getLvObj(); + auto btn_obj = num_edit->getLvObj(); + lv_obj_add_event_cb(c_obj, pwmfreq_changed, LV_EVENT_VALUE_CHANGED, btn_obj); + lv_event_send(c_obj, LV_EVENT_VALUE_CHANGED, nullptr); +} + +PWMfrequencyChoice::PWMfrequencyChoice(Window* parent, uint8_t moduleIdx ) : + FormGroup(parent, rect_t{}) +{ + setFlexLayout(LV_FLEX_FLOW_ROW); + lv_obj_set_width(lvobj, LV_SIZE_CONTENT); + uint16_t &pwmvalue_type = _v1_pwmvalue_type[moduleIdx][0]; + auto vCfg = &afhds3::getConfig(moduleIdx)->v0; + if( 0xff ==pwmvalue_type ) + { + if ( 50 == (vCfg->PWMFrequency.Frequency&0x7fff) ) pwmvalue_type = 0; + else if ( 333 == (vCfg->PWMFrequency.Frequency&0x7fff) ) pwmvalue_type = 1; + else pwmvalue_type = 2; + } + auto choice = new Choice(this, rect_t{}, _v0_pwmfreq_types, 0, 2, + [=,&pwmvalue_type]{ + return pwmvalue_type; + }, + [=,&pwmvalue_type](int32_t newValue) { + pwmvalue_type=newValue; + vCfg->PWMFrequency.Frequency = _v0_index2pwmvalue[newValue]; + }); + auto num_edit = new NumberEdit(this, rect_t{}, 50, 400, + [=,&pwmvalue_type] { return (pwmvalue_type==2?vCfg->PWMFrequency.Frequency&0x7fff:50); }, + [=](int16_t newVal) { + vCfg->PWMFrequency.Frequency = newVal; + }); + c_obj = choice->getLvObj(); + auto btn_obj = num_edit->getLvObj(); + lv_obj_add_event_cb(c_obj, pwmfreq_changedV0, LV_EVENT_VALUE_CHANGED, btn_obj); + lv_event_send(c_obj, LV_EVENT_VALUE_CHANGED, nullptr); +} + +void PWMfrequencyChoice::update() const +{ + lv_event_send(c_obj, LV_EVENT_VALUE_CHANGED, nullptr); +} + + AFHDS3_Options::AFHDS3_Options(uint8_t moduleIdx) : Page(ICON_MODEL_SETUP) { cfg = afhds3::getConfig(moduleIdx); - std::string title = moduleIdx == INTERNAL_MODULE ? STR_INTERNALRF : STR_EXTERNALRF; - title += "\nAFHDS3"; - + title += "AFHDS3"; + title += moduleIdx == INTERNAL_MODULE ?"\nINRM301":"\nFRM303"; header.setTitle(title); auto form = new FormGroup(&body, rect_t{}); @@ -55,56 +166,87 @@ AFHDS3_Options::AFHDS3_Options(uint8_t moduleIdx) : Page(ICON_MODEL_SETUP) auto vCfg = &cfg->v0; auto line = form->newLine(&grid); - new StaticText(line, rect_t{}, "PWM frequency"); - new NumberEdit(line, rect_t{}, 50, 400, GET_SET_DEFAULT(vCfg->PWMFrequency.Frequency)); - + std::string temp_str ="PWM"; + temp_str += TR_POWERMETER_FREQ; + new StaticText(line, rect_t{}, temp_str); + new PWMfrequencyChoice(line, moduleIdx ); + //new NumberEdit(line, rect_t{}, 50, 400, GET_SET_DEFAULT(vCfg->PWMFrequency.Frequency)); + temp_str ="PWM"; + temp_str +=STR_SYNC; line = form->newLine(&grid); - new StaticText(line, rect_t{}, "PWM sychronized"); + new StaticText(line, rect_t{}, temp_str); new CheckBox(line, rect_t{}, GET_SET_DEFAULT(vCfg->PWMFrequency.Synchronized)); + line = form->newLine(&grid); - new StaticText(line, rect_t{}, "Analog output"); + temp_str = TR_CHANS; + temp_str += "1"; + new StaticText(line, rect_t{}, temp_str ); new Choice(line, rect_t{}, _analog_outputs, afhds3::SES_ANALOG_OUTPUT_PWM, afhds3::SES_ANALOG_OUTPUT_PPM, GET_SET_DEFAULT(vCfg->AnalogOutput)); line = form->newLine(&grid); - new StaticText(line, rect_t{}, "External bus type"); + new StaticText(line, rect_t{}, STR_SERIAL_BUS); new Choice(line, rect_t{}, _bus_types, - afhds3::EB_BT_IBUS1, afhds3::EB_BT_SBUS1, - GET_SET_DEFAULT(vCfg->ExternalBusType)); - + 0, 2, + GET_SET_DEFAULT(cfg->BusType.ExternalBusType)); + } else { auto vCfg = &cfg->v1; + for (uint8_t i = 0; i < channel_num[vCfg->PhyMode]; i++) { + std::string temp_str=TR_CHANS; + temp_str += std::to_string(i+1); + auto line = form->newLine(&grid); + new StaticText(line, rect_t{}, temp_str); + new PWMfrequencyChoice(line, moduleIdx, i); - auto line = form->newLine(&grid); - new StaticText(line, rect_t{}, "PWM frequency"); - new NumberEdit(line, rect_t{}, 50, 400, - GET_DEFAULT(vCfg->PWMFrequenciesV1.PWMFrequencies[0]), - [=](int16_t newVal) { - for (uint8_t i = 0; i < SES_NB_MAX_CHANNELS; i++) { - vCfg->PWMFrequenciesV1.PWMFrequencies[i] = newVal; - } - }); - - line = form->newLine(&grid); - new StaticText(line, rect_t{}, "PWM sychronized"); - new CheckBox( - line, rect_t{}, GET_DEFAULT(vCfg->PWMFrequenciesV1.Synchronized), - [=](uint8_t newVal) { - vCfg->PWMFrequenciesV1.Synchronized = newVal ? 0xFFFFFFFF : 0; - }); + temp_str ="PWM"; + temp_str +=STR_SYNC; + line = form->newLine(&grid); + new StaticText(line, rect_t{}, temp_str); + new CheckBox( + line, rect_t{}, GET_DEFAULT((vCfg->PWMFrequenciesV1.Synchronized&1<>i), + [=](uint8_t newVal) { + vCfg->PWMFrequenciesV1.Synchronized &= ~(1<PWMFrequenciesV1.Synchronized |= (newVal?1:0)<newLine(&grid); - + auto line = form->newLine(&grid); std::string portName = "NP"; portName += 'A' + i; - new StaticText(line, rect_t{}, portName.c_str()); new Choice(line, rect_t{}, _v1_bus_types, afhds3::SES_NPT_PWM, afhds3::SES_NPT_IBUS1_OUT, - GET_SET_DEFAULT(vCfg->NewPortTypes[i])); + GET_DEFAULT(vCfg->NewPortTypes[i]), + [=](int32_t newValue) { + if(!newValue) + vCfg->NewPortTypes[i] = newValue; + else { + uint8_t j = 0; + for ( j = 0; j < SES_NPT_NB_MAX_PORTS; j++) { + if ( vCfg->NewPortTypes[j]== newValue && i != j ) + break; + } + //The RX does not support two or more ports to output IBUS (the same is true for PPM and SBUS). + if(j==SES_NPT_NB_MAX_PORTS ) vCfg->NewPortTypes[i] = newValue; + } + }); } } + auto line = form->newLine(&grid); + new StaticText(line, rect_t{}, STR_SIGNAL_OUTPUT); + std::vector signed_strength_ch; + signed_strength_ch.emplace_back(STR_OFF); + for(int i=0; iv1.PhyMode]; i++ ){ + std::string temstr = TR_CHANS; + temstr += std::to_string(i+1); + signed_strength_ch.emplace_back(temstr); + } + new Choice(line, rect_t{}, signed_strength_ch, + 0, channel_num[cfg->v1.PhyMode], + [=] { return cfg->v1.SignalStrengthRCChannelNb==0xff?0:cfg->v1.SignalStrengthRCChannelNb+1; }, + [=](int32_t newValue) { newValue?cfg->v1.SignalStrengthRCChannelNb = newValue-1:cfg->v1.SignalStrengthRCChannelNb=0xff;}); } diff --git a/radio/src/gui/colorlcd/afhds3_options.h b/radio/src/gui/colorlcd/afhds3_options.h index 3a7497b59..09386ebf7 100644 --- a/radio/src/gui/colorlcd/afhds3_options.h +++ b/radio/src/gui/colorlcd/afhds3_options.h @@ -24,6 +24,15 @@ #include "page.h" #include "pulses/afhds3_config.h" +struct PWMfrequencyChoice : public FormGroup { + PWMfrequencyChoice(Window* parent, uint8_t moduleIdx, uint8_t channelIdx); + PWMfrequencyChoice(Window* parent, uint8_t moduleIdx); + void update() const; + + private: + lv_obj_t* c_obj; +}; + class AFHDS3_Options : public Page { afhds3::Config_u* cfg; diff --git a/radio/src/pulses/afhds3.cpp b/radio/src/pulses/afhds3.cpp index cc2339806..11d693c32 100644 --- a/radio/src/pulses/afhds3.cpp +++ b/radio/src/pulses/afhds3.cpp @@ -73,6 +73,37 @@ static uint8_t _phyMode_channels[] = { // EMPTY_DT, // }; +//Product number +#define PN_FRM301 ( (0x1234<<16) | 0x0003 ) +#define PN_FRM004 ( (0x1234<<16) | 0x0007 ) +#define PN_FRM005 ( (0x1234<<16) | 0x0009 ) + +#define PN_FTR10 ( (0x1234<<16) | 0x0002 ) +#define PN_FGR4 ( (0x1234<<16) | 0x0004 ) + +#define PN_FTR4 ( (0x1234<<16) | 0x0006 ) +#define PN_FGR4S ( (0x1234<<16) | 0x0006 ) +#define PN_FGR4P ( (0x1234<<16) | 0x0006 ) + +#define PN_FTR16S ( (0x0001<<16) | 0x0103 ) +//#define PN_MINIZ ( (0x0001<<16) | 0x0104 ) + +#define PN_FTR8B ( (0x0001<<16) | 0x0105 ) +#define PN_FTR12B ( (0x0001<<16) | 0x0106 ) +#define PN_FGR8B ( (0x0001<<16) | 0x0107 ) +#define PN_FGR12B ( (0x0001<<16) | 0x0108 ) +#define PN_GMR ( (0x0001<<16) | 0x0109 ) +#define PN_TMR ( (0x0001<<16) | 0x010A ) +#define PN_INR4_GYB ( (0x0001<<16) | 0x010B ) +#define PN_INR6_HS ( (0x0001<<16) | 0x010C ) +#define PN_FTR4B ( (0x0001<<16) | 0x010D ) +#define PN_FGR4B ( (0x0001<<16) | 0x010E ) +#define PN_FBR12 ( (0x0001<<16) | 0x010F ) +#define PN_INR6_FC ( (0x0001<<16) | 0x0110 ) +#define PN_TR8B ( (0x0001<<16) | 0x0111 ) +#define PN_FBR8 ( (0x0001<<16) | 0x0112 ) +#define PN_FBR4 ( (0x0001<<16) | 0x0113 ) + // enum used by command response -> translate to ModuleState enum MODULE_READY_E { MODULE_STATUS_UNKNOWN = 0x00, @@ -146,14 +177,29 @@ enum DeviceAddress { IRM301 = 0x05, }; -PACK(struct ModuleVersion { +PACK(struct ModuleVersion +{ + uint16_t companyNumber; + uint32_t txID; + uint32_t rxID; uint32_t productNumber; - uint32_t hardwereVersion; + uint32_t hardwareVersion; uint32_t bootloaderVersion; uint32_t firmwareVersion; uint32_t rfVersion; }); + +PACK(struct ReceiverVersion +{ +uint32_t ProductNumber; +uint16_t MainboardVersion; +uint16_t RFModuleVersion; +uint16_t BootloaderVersion; +uint16_t FirmwareVersion; +uint16_t RFLibraryVersion; +} ); + PACK(struct CommandResult_s { uint16_t command; uint8_t result; @@ -171,6 +217,7 @@ union AfhdsFrameData { #define FRM302_STATUS 0x56 +uint8_t receiver_type( unsigned long productnumber ); class ProtoState { public: @@ -251,6 +298,7 @@ class ProtoState bool modelIDSet; bool modelcfgGet; uint8_t modelID; + uint32_t cmd_flg; /** * Command count used for counting actual number of commands sent in run mode */ @@ -275,6 +323,7 @@ class ProtoState * Actual module version - must be requested from module */ ModuleVersion version; + ReceiverVersion rx_version; }; static const char* const moduleStateText[] = @@ -559,16 +608,29 @@ void ProtoState::parseData(uint8_t* rxBuffer, uint8_t rxBufferCount) moduleData->afhds3.emi = cfg.v0.EMIStandard; moduleData->afhds3.telemetry = cfg.v0.IsTwoWay; moduleData->afhds3.phyMode = cfg.v0.PhyMode; + cfg.BusType.ExternalBusType = cfg.v0.ExternalBusType; } break; case COMMAND::MODULE_VERSION: std::memcpy((void*) &version, &responseFrame->value, sizeof(version)); TRACE("AFHDS3 [MODULE_VERSION] Product %d, HW %d, BOOT %d, FW %d", - version.productNumber, version.hardwereVersion, + version.productNumber, version.hardwareVersion, version.bootloaderVersion, version.firmwareVersion); break; case COMMAND::MODULE_STATE: TRACE("AFHDS3 [MODULE_STATE] %02X", responseFrame->value); setState((ModuleState)responseFrame->value); + if(STATE_SYNC_DONE == (ModuleState)responseFrame->value){ + if(this->cmd_flg & 0x04) + { + this->cmd_flg &= ~0x04; + this->cmd_flg |= 0x02; + trsp.enqueue(COMMAND::MODULE_VERSION, FRAME_TYPE::REQUEST_GET_DATA); + } + } + else + { + this->cmd_flg |= 0x04; + } break; case COMMAND::MODULE_MODE: TRACE("AFHDS3 [MODULE_MODE] %02X", responseFrame->value); @@ -630,10 +692,38 @@ void ProtoState::parseData(uint8_t* rxBuffer, uint8_t rxBufferCount) } break; case COMMAND::COMMAND_RESULT: { - // AfhdsFrameData* respData = responseFrame->GetData(); - // TRACE("COMMAND RESULT %02X result %d datalen %d", - // respData->CommandResult.command, respData->CommandResult.result, - // respData->CommandResult.respLen); + uint8_t *data = &responseFrame->value; + uint16_t cmd_code = *data++; + cmd_code |= (*data++)<<8; + uint8_t result = *data++; + switch (cmd_code) + { + case RX_CMD_GET_VERSION : + if(RX_CMDRESULT::RXSUCCESS==result) + { + if(14==*data++) + { + this->cmd_flg &= ~0x02; + std::memcpy((void*) &rx_version, data, sizeof(rx_version)); + this->cmd_flg |= 0x08; + } + }break; + case RX_CMD_BUS_TYPE_V0: + if(RX_CMDRESULT::RXSUCCESS==result) + { + this->cmd_flg &= ~0x28; + }break; + case RX_CMD_IBUS_DIRECTION: + if(RX_CMDRESULT::RXSUCCESS==*data++) + { + this->cmd_flg &= ~0x10; + auto *cfg = this->getConfig(); + if( 0==cfg->version && 2==cfg->v0.ExternalBusType) + this->cmd_flg |= 0x20; + }break; + default: + break; + } } break; } } @@ -656,70 +746,63 @@ inline bool isPWM(uint8_t mode) bool ProtoState::syncSettings() { - // RUN_POWER targetPower = getRunPower(); - - // /*not sure if we need to prevent them in bind mode*/ - // if (getModuleMode(module_index) != ::ModuleSettingsMode::MODULE_MODE_BIND && - // targetPower != cfg.config.runPower) { - // cfg.config.runPower = moduleData->afhds3.runPower; - // uint8_t data[] = {0x13, 0x20, 0x02, moduleData->afhds3.runPower, 0}; - // TRACE("AFHDS3 SET TX POWER %d", moduleData->afhds3.runPower); - // trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, - // sizeof(data)); - // return true; - // } - - // // other settings only in 2 way mode (state must be synchronized) - // if (this->state != ModuleState::STATE_SYNC_DONE) { - // return false; - // } - - // if (moduleData->afhds3.rxFreq() != cfg.config.pwmFreq) { - // cfg.config.pwmFreq = moduleData->afhds3.rxFreq(); - // uint8_t data[] = {0x17, 0x70, 0x02, - // (uint8_t)(moduleData->afhds3.rxFreq() & 0xFF), - // (uint8_t)(moduleData->afhds3.rxFreq() >> 8)}; - // TRACE("AFHDS3 SET RX FREQ"); - // trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, - // sizeof(data)); - // return true; - // } - - // PULSE_MODE modelPulseMode = isPWM(moduleData->afhds3.mode) - // ? PULSE_MODE::PWM_MODE - // : PULSE_MODE::PPM_MODE; - // if (modelPulseMode != cfg.config.pulseMode) { - // cfg.config.pulseMode = modelPulseMode; - // TRACE("AFHDS3 PWM/PPM %d", modelPulseMode); - // uint8_t data[] = {0x16, 0x70, 0x01, (uint8_t)(modelPulseMode)}; - // trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, - // sizeof(data)); - // return true; - // } - - // SERIAL_MODE modelSerialMode = isSbus(moduleData->afhds3.mode) - // ? SERIAL_MODE::SBUS_MODE - // : SERIAL_MODE::IBUS; - // if (modelSerialMode != cfg.config.serialMode) { - // cfg.config.serialMode = modelSerialMode; - // TRACE("AFHDS3 IBUS/SBUS %d", modelSerialMode); - // uint8_t data[] = {0x18, 0x70, 0x01, (uint8_t)(modelSerialMode)}; - // trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, - // sizeof(data)); - // return true; - // } - - // if (moduleData->afhds3.failsafeTimeout != cfg.config.failSafeTimout) { - // moduleData->afhds3.failsafeTimeout = cfg.config.failSafeTimout; - // uint8_t data[] = {0x12, 0x60, 0x02, - // (uint8_t)(moduleData->afhds3.failsafeTimeout & 0xFF), - // (uint8_t)(moduleData->afhds3.failsafeTimeout >> 8)}; - // trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, - // sizeof(data)); - // TRACE("AFHDS3 FAILSAFE TMEOUT, %d", moduleData->afhds3.failsafeTimeout); - // return true; - // } - +if (this->state != ModuleState::STATE_SYNC_DONE) { + return false; + } + if(this->cmd_flg&0x02) + { + uint8_t data[] = { (uint8_t)(RX_CMD_GET_VERSION&0xFF), (uint8_t)((RX_CMD_GET_VERSION>>8)&0xFF), 0x00 }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data)); + return true; + } + auto *cfg = this->getConfig(); + if((this->cmd_flg&0x38) && (!cfg->version) ) + { + uint8_t bustype = cfg->BusType.ExternalBusType<=1?0:2; + uint8_t busdir = cfg->BusType.ExternalBusType; + if( 1==receiver_type(rx_version.ProductNumber) ) + { + if(this->cmd_flg&0x08) + { + uint8_t data[] = { (uint8_t)(RX_CMD_BUS_TYPE_V0&0xFF), (uint8_t)((RX_CMD_BUS_TYPE_V0>>8)&0xFF), 0x1, bustype }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data)); + if(busdir<2) + this->cmd_flg |= 0x10; + return true; + } + if((this->cmd_flg&0x10) && busdir<2) + { + cfg->BusType.ExternalBusType = IBUS1_OUT; + busdir = IBUS1_OUT; + uint8_t data1[] = { (uint8_t)(RX_CMD_IBUS_DIRECTION&0xFF), (uint8_t)((RX_CMD_IBUS_DIRECTION>>8)&0xFF), 0x1, busdir }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data1, sizeof(data1)); + return true; + } + } + else if( 2==receiver_type(rx_version.ProductNumber) ) + { + if(this->cmd_flg&0x08) + { + uint8_t data[] = { (uint8_t)(RX_CMD_BUS_TYPE_V0&0xFF), (uint8_t)((RX_CMD_BUS_TYPE_V0>>8)&0xFF), 0x1, 0 }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data)); + this->cmd_flg |= 0x10; + return true; + } + else if((this->cmd_flg&0x10)) + { + if(busdir>=2) busdir = 0; //IBUSOUT + uint8_t data1[] = { (uint8_t)(RX_CMD_IBUS_DIRECTION&0xFF), (uint8_t)((RX_CMD_IBUS_DIRECTION>>8)&0xFF), 0x1, busdir }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data1, sizeof(data1)); + return true; + } + else if((this->cmd_flg&0x20)) + { + uint8_t data[] = { (uint8_t)(RX_CMD_BUS_TYPE_V0&0xFF), (uint8_t)((RX_CMD_BUS_TYPE_V0>>8)&0xFF), 0x1, 2 }; + trsp.sendFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data)); + return true; + } + } + } return false; } @@ -798,7 +881,7 @@ void ProtoState::applyConfigFromModel() cfg.v0.EMIStandard = moduleData->afhds3.emi; cfg.v0.IsTwoWay = moduleData->afhds3.telemetry; cfg.v0.PhyMode = moduleData->afhds3.phyMode; - + cfg.v0.ExternalBusType = cfg.BusType.ExternalBusType==1?0:cfg.BusType.ExternalBusType; // Failsafe setFailSafe(cfg.v0.FailSafe); if (moduleData->failsafeMode != FAILSAFE_NOPULSES) { @@ -809,6 +892,26 @@ void ProtoState::applyConfigFromModel() } } +uint8_t receiver_type( unsigned long productnumber ) +{ + if(PN_FTR10 == productnumber || PN_FGR4 == productnumber || PN_FTR16S == productnumber) + { + return 1; // This type of RX can be set to IBUS-OUT/SBUS + } + else if(PN_FTR4 == productnumber) + { + return 2; // This type of RX can be set to IBUS-IN/IBUS-OUT/SBUS + } + else if( (PN_FTR8B&0xFFFF) <= productnumber) + { + return 3; //V1 RX + } + else + { + return 0; + } +} + inline int16_t ProtoState::convert(int channelValue) { //pulseValue = limit(0, 988 + ((channelValue + 1024) / 2), 0xfff); diff --git a/radio/src/pulses/afhds3_config.h b/radio/src/pulses/afhds3_config.h index 2bcad0003..e7fb04d1d 100644 --- a/radio/src/pulses/afhds3_config.h +++ b/radio/src/pulses/afhds3_config.h @@ -43,6 +43,12 @@ enum eEB_BusType { EB_BT_SBUS1 }; +typedef enum +{ + IBUS1_OUT, + IBUS1_IN, //Not yet supported +} eIBUS1_DIR; + // 48 bytes PACK(struct sDATA_ConfigV0 { uint8_t Version; // =0 @@ -98,12 +104,18 @@ PACK(struct sDATA_ConfigV1 { sSES_PWMFrequenciesAPPV1 PWMFrequenciesV1; }); +PACK(struct sDATA_BusType { + uint8_t buffer[sizeof(sDATA_ConfigV1)]; + uint8_t ExternalBusType; // eEB_BusType +}); + union Config_u { uint8_t version; sDATA_ConfigV0 v0; sDATA_ConfigV1 v1; uint8_t buffer[sizeof(sDATA_ConfigV1)]; + sDATA_BusType BusType; }; Config_u* getConfig(uint8_t moduleIdx); diff --git a/radio/src/pulses/afhds3_transport.h b/radio/src/pulses/afhds3_transport.h index 2f28fb149..3a02aef22 100644 --- a/radio/src/pulses/afhds3_transport.h +++ b/radio/src/pulses/afhds3_transport.h @@ -70,6 +70,14 @@ enum COMMAND : uint8_t { #define RX_CMD_BUS_FAILSAFE ( 0x702A ) #define RX_CMD_GET_VERSION ( 0x701F ) +enum RX_CMDRESULT: uint8_t +{ + RXSUCCESS=0, + RXTIMEOUT=1, + RXERROR=2, //not support + RXINVALID=3, +}; + // one byte frames for request queue struct Frame { enum COMMAND command; diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 8847aea94..88d85a2ae 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -990,3 +990,10 @@ const char STR_USBJOYSTICK_CIRC_COUTOUT[] = TR_USBJOYSTICK_CIRC_COUTOUT; ISTR(VUSBJOYSTICK_CIRC_COUTOUT); const char STR_USBJOYSTICK_APPLY_CHANGES[] = TR_USBJOYSTICK_APPLY_CHANGES; #endif + +const char STR_DIGITAL_SERVO[] = TR_DIGITAL_SERVO; +const char STR_ANALOG_SERVO[] = TR_ANALOG_SERVO; +const char STR_SIGNAL_OUTPUT[] = TR_SIGNAL_OUTPUT; +const char STR_SERIAL_BUS[] = TR_SERIAL_BUS; +const char STR_SYNC[] = TR_SYNC; + diff --git a/radio/src/translations.h b/radio/src/translations.h index d52ec1d9e..dc33c8b69 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -816,6 +816,13 @@ extern const char STR_CONFIRMRESET[]; extern const char STR_TOO_MANY_LUA_SCRIPTS[]; extern const char STR_BLCOLOR[]; +extern const char STR_DIGITAL_SERVO[]; +extern const char STR_ANALOG_SERVO[]; +extern const char STR_SIGNAL_OUTPUT[]; +extern const char STR_SERIAL_BUS[]; +extern const char STR_SYNC[]; + + struct LanguagePack { const char * id; const char * name; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index 2fc145a84..fc2c3c768 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -1279,3 +1279,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "数字舵机333HZ" +#define TR_ANALOG_SERVO "模拟舵机50HZ" +#define TR_SIGNAL_OUTPUT "信号强度输出" +#define TR_SERIAL_BUS "串行总线" +#define TR_SYNC "同步" diff --git a/radio/src/translations/cz.h b/radio/src/translations/cz.h index d92c05075..3324fe046 100644 --- a/radio/src/translations/cz.h +++ b/radio/src/translations/cz.h @@ -1281,3 +1281,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index c9fa43417..df050e5b0 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -1294,3 +1294,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Cirk. klip", "Cikulær klip") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "Ingen","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Gem ændringer" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index 3b1a690d0..a327c2c0b 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -1280,3 +1280,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index 7630ba0a9..1f4c6a7ae 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -1273,3 +1273,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/es.h b/radio/src/translations/es.h index 2557844f9..1cad4eb1f 100644 --- a/radio/src/translations/es.h +++ b/radio/src/translations/es.h @@ -1284,3 +1284,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/fi.h b/radio/src/translations/fi.h index 40516e3a5..b68a73ab0 100644 --- a/radio/src/translations/fi.h +++ b/radio/src/translations/fi.h @@ -1297,3 +1297,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/fr.h b/radio/src/translations/fr.h index 688f66454..a8c4098a9 100644 --- a/radio/src/translations/fr.h +++ b/radio/src/translations/fr.h @@ -1302,3 +1302,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Appliquer changements" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" \ No newline at end of file diff --git a/radio/src/translations/it.h b/radio/src/translations/it.h index a1578ab0e..d1cc958b1 100644 --- a/radio/src/translations/it.h +++ b/radio/src/translations/it.h @@ -1289,3 +1289,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/jp.h b/radio/src/translations/jp.h index 69971da7a..57f76306e 100644 --- a/radio/src/translations/jp.h +++ b/radio/src/translations/jp.h @@ -808,7 +808,7 @@ #define TR_PATH_TOO_LONG "パスが長すぎます" #define TR_VIEW_TEXT "テキストビュー" #define TR_FLASH_BOOTLOADER "Bootloader書き込み" -#define TR_FLASH_DEVICE TR("Flash device","デバイスに書き込み") +#define TR_FLASH_DEVICE TR("Flash device","デバイスに書き込み") #define TR_FLASH_EXTERNAL_DEVICE TR("Flash S.Port", "S.Portデバイスに書き込み") #define TR_FLASH_RECEIVER_OTA "OTAにて受信機に書き込み" #define TR_FLASH_RECEIVER_BY_EXTERNAL_MODULE_OTA "OTAにて外部受信機に書き込み" @@ -1198,9 +1198,9 @@ #define TR_ADD_ALL_TRIMS_TO_SUBTRIMS "サブトリムにすべてのトリムを追加" #if LCD_W > LCD_H - #define TR_OPEN_CHANNEL_MONITORS "チャンネルモニター起動" + #define TR_OPEN_CHANNEL_MONITORS "チャンネルモニター起動" #else - #define TR_OPEN_CHANNEL_MONITORS "Open Channel Mon." + #define TR_OPEN_CHANNEL_MONITORS "Open Channel Mon." #endif #define TR_DUPLICATE "複製" #define TR_ACTIVATE "設定の有効" @@ -1274,3 +1274,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/nl.h b/radio/src/translations/nl.h index ba1caa5e6..41b30e34b 100644 --- a/radio/src/translations/nl.h +++ b/radio/src/translations/nl.h @@ -1294,3 +1294,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/pl.h b/radio/src/translations/pl.h index 198ac1d9c..dec34898c 100644 --- a/radio/src/translations/pl.h +++ b/radio/src/translations/pl.h @@ -1278,3 +1278,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/pt.h b/radio/src/translations/pt.h index ef6d53d6f..56e5a3072 100644 --- a/radio/src/translations/pt.h +++ b/radio/src/translations/pt.h @@ -1287,3 +1287,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/se.h b/radio/src/translations/se.h index fa52145a2..9f99abc14 100644 --- a/radio/src/translations/se.h +++ b/radio/src/translations/se.h @@ -91,7 +91,7 @@ #define TR_RETA123 "R","H","G","S","1","2","3" #endif -#define TR_VCURVETYPE "Diff","Expo","Funk","Egen" +#define TR_VCURVETYPE "Diff","Expo","Funk","Egen" #define TR_VCURVEFUNC "---","x>0","x<0","|x|","f>0","f<0","|f|" #define TR_VMLTPX "Addera","Multiplicera","Ersätt" #define TR_VMLTPX2 "+=","*=",":=" @@ -377,7 +377,7 @@ #define TR_CHECKTRIMS "Kolla FL-trimmar" #else #define TR_CHECKTRIMS CENTER "\006Kolla\012trimmar" -#endif +#endif #define OFS_CHECKTRIMS CENTER_OFS+(9*FW) #define TR_SWASHTYPE "Swashtyp" #define TR_COLLECTIVE "Kollektiv" @@ -964,7 +964,7 @@ #define TR_ENABLE "Aktivera" #define TR_TOPLCDTIMER "Översta LCD timer" #define TR_UNIT "Enhet" -#define TR_TELEMETRY_NEWSENSOR INDENT "Lägg till..." +#define TR_TELEMETRY_NEWSENSOR INDENT "Lägg till..." #define TR_CHANNELRANGE TR(INDENT "Kanalomr.", INDENT "Kanalområde") #define TR_RXFREQUENCY TR("Rx frekv.", "Rx frekvens") #define TR_AFHDS3_RX_FREQ TR("Rx frekv", "Rx frekvens") @@ -1241,9 +1241,9 @@ #define TR_ADD_ALL_TRIMS_TO_SUBTRIMS "Addera alla trimmar till subtrimmar" #if LCD_W > LCD_H - #define TR_OPEN_CHANNEL_MONITORS "Öppna kanalmonitorn" + #define TR_OPEN_CHANNEL_MONITORS "Öppna kanalmonitorn" #else - #define TR_OPEN_CHANNEL_MONITORS "Öppna kanalmon." + #define TR_OPEN_CHANNEL_MONITORS "Öppna kanalmon." #endif #define TR_DUPLICATE "Duplicera" @@ -1318,3 +1318,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Cirk. klipp", "Cirkulärt klipp") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "Ingen","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Tillämpa ändringar" + +#define TR_DIGITAL_SERVO "Servo333HZ" +#define TR_ANALOG_SERVO "Servo 50HZ" +#define TR_SIGNAL_OUTPUT "Signal output" +#define TR_SERIAL_BUS "Serial bus" +#define TR_SYNC "Sync" diff --git a/radio/src/translations/tw.h b/radio/src/translations/tw.h index 6d1f05c01..e11a22253 100644 --- a/radio/src/translations/tw.h +++ b/radio/src/translations/tw.h @@ -786,7 +786,7 @@ #define TR_BLUETOOTH_MODES "---","啟用" #else #define TR_BLUETOOTH_MODES "---","回傳","教練" -#endif +#endif #define TR_SD_INFO_TITLE "存儲卡詳情" #define TR_SD_TYPE "類型:" @@ -1198,9 +1198,9 @@ #define TR_ADD_ALL_TRIMS_TO_SUBTRIMS "將所有微調導入中點偏移值" #if LCD_W > LCD_H - #define TR_OPEN_CHANNEL_MONITORS "打開通道監視器" + #define TR_OPEN_CHANNEL_MONITORS "打開通道監視器" #else - #define TR_OPEN_CHANNEL_MONITORS "通道監視" + #define TR_OPEN_CHANNEL_MONITORS "通道監視" #endif #define TR_DUPLICATE "複製" #define TR_ACTIVATE "啟用" @@ -1277,3 +1277,9 @@ #define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout") #define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY" #define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes" + +#define TR_DIGITAL_SERVO "數字舵機333HZ" +#define TR_ANALOG_SERVO "模擬舵機50HZ" +#define TR_SIGNAL_OUTPUT "信號強度輸出" +#define TR_SERIAL_BUS "串行總線" +#define TR_SYNC "同步"