feat(EL18): Add AFHDS3 receiver options (#2470)
* Get config after switching model ID * Remember set model ID and change it on the fly * Add AFHDS3 options * Fix compiler warning * Fix box sizing * Apply model config before editing options
This commit is contained in:
@@ -140,6 +140,9 @@ endif()
|
||||
|
||||
if(AFHDS2 OR AFHDS3)
|
||||
add_gui_src(flysky_settings.cpp)
|
||||
if(AFHDS3)
|
||||
add_gui_src(afhds3_options.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MULTIMODULE)
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "afhds3_options.h"
|
||||
#include "opentx.h"
|
||||
|
||||
//#include "checkbox.h"
|
||||
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define SET_DIRTY()
|
||||
|
||||
static const char* _analog_outputs[] = { "PWM", "PPM" };
|
||||
static const char* _bus_types[] = { "iBUS", "iBUS2", "SBUS" };
|
||||
static const char* _v1_bus_types[] = { "PWM", "PPM", "SBUS", "iBUS IN", "iBUS OUT" };
|
||||
|
||||
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";
|
||||
|
||||
header.setTitle(title);
|
||||
|
||||
auto form = new FormGroup(&body, rect_t{});
|
||||
form->setFlexLayout();
|
||||
form->padAll(lv_dpx(8));
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc, 2);
|
||||
|
||||
if (cfg->version == 0) {
|
||||
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));
|
||||
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, "PWM sychronized");
|
||||
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(vCfg->PWMFrequency.Synchronized));
|
||||
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, "Analog output");
|
||||
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 Choice(line, rect_t{}, _bus_types,
|
||||
afhds3::EB_BT_IBUS1, afhds3::EB_BT_SBUS1,
|
||||
GET_SET_DEFAULT(vCfg->ExternalBusType));
|
||||
|
||||
} else {
|
||||
auto vCfg = &cfg->v1;
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
for (uint8_t i = 0; i < SES_NPT_NB_MAX_PORTS; i++) {
|
||||
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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "page.h"
|
||||
#include "pulses/afhds3_config.h"
|
||||
|
||||
class AFHDS3_Options : public Page
|
||||
{
|
||||
afhds3::Config_u* cfg;
|
||||
|
||||
public:
|
||||
AFHDS3_Options(uint8_t moduleIdx);
|
||||
};
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "flysky_settings.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#if defined(AFHDS3)
|
||||
#include "afhds3_options.h"
|
||||
#endif
|
||||
|
||||
#include "pulses/flysky.h"
|
||||
#include "pulses/afhds3.h"
|
||||
|
||||
@@ -132,50 +136,23 @@ void FlySkySettings::update()
|
||||
new StaticText(line, rect_t{}, STR_TYPE, 0, COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW);
|
||||
|
||||
new Choice(box, rect_t{}, _afhds3_region, 1, afhds3::LNK_ES_FCC,
|
||||
GET_SET_DEFAULT(md->afhds3.emi));
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP);
|
||||
lv_obj_set_style_grid_cell_x_align(box->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
|
||||
new Choice(box, rect_t{}, _afhds3_phy_mode, 0, afhds3::PHYMODE_MAX,
|
||||
GET_SET_DEFAULT(md->afhds3.phyMode));
|
||||
|
||||
// // Power source
|
||||
// line = newLine(&grid);
|
||||
// new StaticText(line, rect_t{}, STR_AFHDS3_POWER_SOURCE, 0,
|
||||
// COLOR_THEME_PRIMARY1);
|
||||
// new DynamicText(line, rect_t{}, [=] {
|
||||
// char msg[64] = "";
|
||||
// getModuleSyncStatusString(moduleIdx, msg);
|
||||
// return std::string(msg);
|
||||
// });
|
||||
new Choice(box, rect_t{}, _afhds3_region,
|
||||
afhds3::LNK_ES_CE, afhds3::LNK_ES_FCC,
|
||||
GET_SET_DEFAULT(md->afhds3.emi));
|
||||
|
||||
// // RX Freq
|
||||
// line = newLine(&grid);
|
||||
// new StaticText(line, rect_t{}, STR_AFHDS3_RX_FREQ, 0, COLOR_THEME_PRIMARY1);
|
||||
// auto edit = new NumberEdit(line, rect_t{}, AFHDS3_MIN_FREQ, AFHDS3_MAX_FREQ,
|
||||
// GET_DEFAULT(md->afhds3.rxFreq()));
|
||||
// edit->setSetValueHandler(
|
||||
// [=](int32_t newValue) { md->afhds3.setRxFreq((uint16_t)newValue); });
|
||||
// edit->setSuffix(STR_HZ);
|
||||
|
||||
// // Module actual power
|
||||
// line = newLine(&grid);
|
||||
// new StaticText(line, rect_t{}, STR_AFHDS3_ACTUAL_POWER, 0,
|
||||
// COLOR_THEME_PRIMARY1);
|
||||
// new DynamicText(line, rect_t{}, [=] {
|
||||
// char msg[64] = "";
|
||||
// getStringAtIndex(msg, STR_AFHDS3_POWERS, actualAfhdsRunPower(moduleIdx));
|
||||
// return std::string(msg);
|
||||
// });
|
||||
|
||||
// // Module power
|
||||
// line = newLine(&grid);
|
||||
// new StaticText(line, rect_t{}, STR_RF_POWER, 0, COLOR_THEME_PRIMARY1);
|
||||
// new Choice(line, rect_t{}, STR_AFHDS3_POWERS,
|
||||
// afhds3::RUN_POWER::RUN_POWER_FIRST,
|
||||
// afhds3::RUN_POWER::RUN_POWER_LAST,
|
||||
// GET_SET_DEFAULT(md->afhds3.runPower));
|
||||
uint8_t module = moduleIdx;
|
||||
new TextButton(box, rect_t{}, STR_MODULE_OPTIONS,
|
||||
[=]() {
|
||||
afhds3::applyModelConfig(module);
|
||||
new AFHDS3_Options(module);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ void mixerSchedulerISRTrigger();
|
||||
#define mixerSchedulerStart()
|
||||
#define mixerSchedulerStop()
|
||||
#define mixerSchedulerResetTimer()
|
||||
#define mixerSchedulerSetPeriod(m,p)
|
||||
#define mixerSchedulerSetPeriod(m,p) ((void)(p))
|
||||
#define mixerSchedulerClearTrigger()
|
||||
|
||||
#define mixerSchedulerEnableTrigger()
|
||||
|
||||
+72
-180
@@ -21,11 +21,12 @@
|
||||
|
||||
#include "afhds3.h"
|
||||
#include "afhds3_transport.h"
|
||||
#include "afhds3_config.h"
|
||||
|
||||
#include "pulses.h"
|
||||
|
||||
#include "../debug.h"
|
||||
#include "../definitions.h"
|
||||
// #include <cstdio>
|
||||
|
||||
#include "telemetry/telemetry.h"
|
||||
#include "mixer_scheduler.h"
|
||||
@@ -62,24 +63,24 @@ static uint8_t _phyMode_channels[] = {
|
||||
12, // ROUTINE_LORA_12CH
|
||||
};
|
||||
|
||||
enum COMMAND_DIRECTION
|
||||
{
|
||||
RADIO_TO_MODULE = 0,
|
||||
MODULE_TO_RADIO = 1
|
||||
};
|
||||
// enum COMMAND_DIRECTION
|
||||
// {
|
||||
// RADIO_TO_MODULE = 0,
|
||||
// MODULE_TO_RADIO = 1
|
||||
// };
|
||||
|
||||
enum DATA_TYPE
|
||||
{
|
||||
READY_DT, // 8 bytes 0x01 Not ready 0x02 Ready
|
||||
STATE_DT, // See MODULE_STATE
|
||||
MODE_DT,
|
||||
MOD_CONFIG_DT,
|
||||
CHANNELS_DT,
|
||||
TELEMETRY_DT,
|
||||
MODULE_POWER_DT,
|
||||
MODULE_VERSION_DT,
|
||||
EMPTY_DT,
|
||||
};
|
||||
// enum DATA_TYPE
|
||||
// {
|
||||
// READY_DT, // 8 bytes 0x01 Not ready 0x02 Ready
|
||||
// STATE_DT, // See MODULE_STATE
|
||||
// MODE_DT,
|
||||
// MOD_CONFIG_DT,
|
||||
// CHANNELS_DT,
|
||||
// TELEMETRY_DT,
|
||||
// MODULE_POWER_DT,
|
||||
// MODULE_VERSION_DT,
|
||||
// EMPTY_DT,
|
||||
// };
|
||||
|
||||
//enum used by command response -> translate to ModuleState
|
||||
enum MODULE_READY_E
|
||||
@@ -122,135 +123,6 @@ enum CMD_RESULT
|
||||
SUCCESS = 0x02,
|
||||
};
|
||||
|
||||
enum BIND_POWER
|
||||
{
|
||||
MIN_16dBm = 0x00,
|
||||
BIND_POWER_FIRST = MIN_16dBm,
|
||||
MIN_5dBm = 0x01,
|
||||
MIN_0dbm = 0x02,
|
||||
PLUS_5dBm = 0x03,
|
||||
PLUS_14dBm = 0x04,
|
||||
BIND_POWER_LAST = PLUS_14dBm,
|
||||
};
|
||||
|
||||
// enum EMI_STANDARD
|
||||
// {
|
||||
// FCC = 0x00,
|
||||
// CE = 0x01
|
||||
// };
|
||||
|
||||
enum TELEMETRY
|
||||
{
|
||||
TELEMETRY_DISABLED = 0x00,
|
||||
TELEMETRY_ENABLED = 0x01
|
||||
};
|
||||
|
||||
enum PULSE_MODE
|
||||
{
|
||||
PWM_MODE = 0x00,
|
||||
PPM_MODE = 0x01,
|
||||
};
|
||||
|
||||
enum SERIAL_MODE
|
||||
{
|
||||
IBUS = 0x00,
|
||||
SBUS_MODE = 0x02
|
||||
};
|
||||
|
||||
// Old format for FRM302
|
||||
// PACK(struct Config_s {
|
||||
// uint8_t bindPower;
|
||||
// uint8_t runPower;
|
||||
// uint8_t emiStandard;
|
||||
// uint8_t telemetry;
|
||||
// uint16_t pwmFreq;
|
||||
// uint8_t pulseMode;
|
||||
// uint8_t serialMode;
|
||||
// uint8_t channelCount;
|
||||
// uint16_t failSafeTimout;
|
||||
// int16_t failSafeMode[AFHDS3_MAX_CHANNELS];
|
||||
// });
|
||||
|
||||
PACK(struct sSES_PWMFrequencyV0 {
|
||||
uint16_t Frequency : 15; // From 50 to 400Hz
|
||||
uint16_t Synchronized : 1; // 1=Synchronize the PWM output to the RF cycle
|
||||
// (lower latency but unstable frequency)
|
||||
});
|
||||
|
||||
enum eSES_PA_SetAnalogOutput {
|
||||
SES_ANALOG_OUTPUT_PWM = 0,
|
||||
SES_ANALOG_OUTPUT_PPM
|
||||
};
|
||||
|
||||
enum eEB_BusType {
|
||||
EB_BT_IBUS1=0,
|
||||
EB_BT_IBUS2,
|
||||
EB_BT_SBUS1
|
||||
};
|
||||
|
||||
// 48 bytes
|
||||
PACK(struct sDATA_ConfigV0 {
|
||||
uint8_t Version; // =0
|
||||
uint8_t EMIStandard; // eLNK_EMIStandard
|
||||
uint8_t IsTwoWay;
|
||||
uint8_t PhyMode; // eDATA_PHYMODE
|
||||
uint8_t SignalStrengthRCChannelNb; // 0xFF if not used, 0`18
|
||||
uint16_t FailsafeTimeout; // in unit of ms
|
||||
int16_t FailSafe[AFHDS3_MAX_CHANNELS];
|
||||
uint8_t FailsafeOutputMode; //TRUE Or FALSE
|
||||
sSES_PWMFrequencyV0 PWMFrequency;
|
||||
uint8_t AnalogOutput; // eSES_PA_SetAnalogOutput
|
||||
uint8_t ExternalBusType; // eEB_BusType
|
||||
});
|
||||
|
||||
#define SES_NB_MAX_CHANNELS (32)
|
||||
#define SES_NPT_NB_MAX_PORTS (4)
|
||||
|
||||
enum eSES_NewPortType {
|
||||
SES_NPT_PWM,
|
||||
SES_NPT_PPM,
|
||||
SES_NPT_SBUS,
|
||||
SES_NPT_IBUS1_IN,
|
||||
SES_NPT_IBUS1_OUT,
|
||||
SES_NPT_IBUS2,
|
||||
SES_NPT_IBUS2_HUB_PORT,
|
||||
SES_NPT_WSTX,
|
||||
SES_NPT_WSRX,
|
||||
SES_NPT_NONE=0xFF
|
||||
};
|
||||
|
||||
PACK(struct sSES_PWMFrequenciesAPPV1 {
|
||||
// One unsigned short per
|
||||
// channel, From 50 to 400Hz,
|
||||
// 1:1000Hz,2:833Hz
|
||||
uint16_t PWMFrequencies[SES_NB_MAX_CHANNELS];
|
||||
|
||||
// 1 bit per channel, 32 channels total
|
||||
uint32_t Synchronized;
|
||||
});
|
||||
|
||||
// 116 bytes
|
||||
PACK(struct sDATA_ConfigV1 {
|
||||
uint8_t Version; // =1
|
||||
uint8_t EMIStandard; // eLNK_EMIStandard
|
||||
uint8_t IsTwoWay;
|
||||
uint8_t PhyMode; // eDATA_PHYMODE
|
||||
uint8_t SignalStrengthRCChannelNb; // 0xFF if not used , 0`18
|
||||
uint16_t FailsafeTimeout; // in unit of ms
|
||||
int16_t FailSafe[AFHDS3_MAX_CHANNELS];
|
||||
uint8_t FailsafeOutputMode; // TRUE Or FALSE
|
||||
uint8_t NewPortTypes[SES_NPT_NB_MAX_PORTS]; // eSES_NewPortType
|
||||
sSES_PWMFrequenciesAPPV1 PWMFrequenciesV1;
|
||||
});
|
||||
|
||||
union Config_u
|
||||
{
|
||||
uint8_t version;
|
||||
sDATA_ConfigV0 v0;
|
||||
sDATA_ConfigV1 v1;
|
||||
uint8_t buffer[sizeof(sDATA_ConfigV1)];
|
||||
};
|
||||
|
||||
enum CHANNELS_DATA_MODE
|
||||
{
|
||||
CHANNELS = 0x01,
|
||||
@@ -349,9 +221,13 @@ class ProtoState
|
||||
*/
|
||||
void stop();
|
||||
|
||||
Config_u* getConfig() { return &cfg; }
|
||||
|
||||
void applyConfigFromModel();
|
||||
|
||||
protected:
|
||||
|
||||
void setConfigFromModel();
|
||||
void resetConfig(uint8_t version);
|
||||
|
||||
private:
|
||||
//friendship declaration - use for passing telemetry
|
||||
@@ -391,6 +267,7 @@ class ProtoState
|
||||
ModuleState state;
|
||||
|
||||
bool modelIDSet;
|
||||
uint8_t modelID;
|
||||
|
||||
/**
|
||||
* Command count used for counting actual number of commands sent in run mode
|
||||
@@ -438,7 +315,7 @@ static const char* const moduleStateText[] =
|
||||
static const COMMAND periodicRequestCommands[] =
|
||||
{
|
||||
COMMAND::MODULE_STATE,
|
||||
COMMAND::MODULE_GET_CONFIG,
|
||||
// COMMAND::MODULE_GET_CONFIG,
|
||||
COMMAND::VIRTUAL_FAILSAFE
|
||||
};
|
||||
|
||||
@@ -513,7 +390,7 @@ void ProtoState::setupFrame()
|
||||
if (moduleMode == ::ModuleSettingsMode::MODULE_MODE_BIND) {
|
||||
if (state != STATE_BINDING) {
|
||||
TRACE("AFHDS3 [BIND]");
|
||||
setConfigFromModel();
|
||||
applyConfigFromModel();
|
||||
|
||||
trsp.sendFrame(COMMAND::MODULE_SET_CONFIG,
|
||||
FRAME_TYPE::REQUEST_SET_EXPECT_DATA, cfg.buffer,
|
||||
@@ -542,10 +419,19 @@ void ProtoState::setupFrame()
|
||||
return;
|
||||
} else {
|
||||
modelIDSet = true;
|
||||
modelID = g_model.header.modelId[module_index];
|
||||
trsp.sendFrame(COMMAND::MODEL_ID, FRAME_TYPE::REQUEST_SET_EXPECT_DATA,
|
||||
&g_model.header.modelId[module_index], 1);
|
||||
|
||||
// always fetch config after setting model ID
|
||||
trsp.enqueue(COMMAND::MODULE_GET_CONFIG, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
return;
|
||||
}
|
||||
} else if (modelID != g_model.header.modelId[module_index]) {
|
||||
modelIDSet = false;
|
||||
auto mode = (uint8_t)MODULE_MODE_E::STANDBY;
|
||||
trsp.sendFrame(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &mode, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->state == ModuleState::STATE_STANDBY) {
|
||||
@@ -873,64 +759,58 @@ void ProtoState::stop()
|
||||
trsp.sendFrame(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &mode, 1);
|
||||
}
|
||||
|
||||
void ProtoState::setConfigFromModel()
|
||||
void ProtoState::resetConfig(uint8_t version)
|
||||
{
|
||||
if (moduleData->afhds3.phyMode < ROUTINE_FLCR1_18CH) {
|
||||
cfg.version = 0;
|
||||
memclear(&cfg, sizeof(cfg));
|
||||
cfg.version = version;
|
||||
|
||||
if (cfg.version == 1) {
|
||||
cfg.v1.SignalStrengthRCChannelNb = 0xFF;
|
||||
cfg.v1.FailsafeTimeout = 500;
|
||||
for (int i = 0; i < SES_NB_MAX_CHANNELS; i++)
|
||||
cfg.v1.PWMFrequenciesV1.PWMFrequencies[i] = 50;
|
||||
} else {
|
||||
cfg.version = 1;
|
||||
cfg.v0.SignalStrengthRCChannelNb = 0xFF;
|
||||
cfg.v0.FailsafeTimeout = 500;
|
||||
cfg.v0.PWMFrequency.Frequency = 50;
|
||||
}
|
||||
}
|
||||
|
||||
void ProtoState::applyConfigFromModel()
|
||||
{
|
||||
uint8_t version = 0;
|
||||
if (moduleData->afhds3.phyMode >= ROUTINE_FLCR1_18CH) {
|
||||
version = 1;
|
||||
}
|
||||
|
||||
if (version != cfg.version) {
|
||||
resetConfig(version);
|
||||
}
|
||||
|
||||
if (cfg.version == 1) {
|
||||
cfg.v1.EMIStandard = moduleData->afhds3.emi;
|
||||
cfg.v1.IsTwoWay = moduleData->afhds3.telemetry;
|
||||
cfg.v1.PhyMode = moduleData->afhds3.phyMode;
|
||||
cfg.v1.SignalStrengthRCChannelNb = 0xFF;
|
||||
|
||||
// Failsafe
|
||||
cfg.v1.FailsafeTimeout = 500;
|
||||
setFailSafe(cfg.v1.FailSafe);
|
||||
|
||||
if (moduleData->failsafeMode != FAILSAFE_NOPULSES) {
|
||||
cfg.v1.FailsafeOutputMode = true;
|
||||
} else {
|
||||
cfg.v1.FailsafeOutputMode = false;
|
||||
}
|
||||
|
||||
// Serial output
|
||||
memclear(&cfg.v1.NewPortTypes, sizeof(cfg.v1.NewPortTypes));
|
||||
|
||||
// PWM settings
|
||||
for (int i = 0; i < SES_NB_MAX_CHANNELS; i++)
|
||||
cfg.v1.PWMFrequenciesV1.PWMFrequencies[i] = 50;
|
||||
|
||||
cfg.v1.PWMFrequenciesV1.Synchronized = 0;
|
||||
|
||||
} else {
|
||||
cfg.v0.EMIStandard = moduleData->afhds3.emi;
|
||||
cfg.v0.IsTwoWay = moduleData->afhds3.telemetry;
|
||||
cfg.v0.PhyMode = moduleData->afhds3.phyMode;
|
||||
cfg.v0.SignalStrengthRCChannelNb = 0xFF;
|
||||
|
||||
// Failsafe
|
||||
cfg.v0.FailsafeTimeout = 500;
|
||||
setFailSafe(cfg.v0.FailSafe);
|
||||
|
||||
if (moduleData->failsafeMode != FAILSAFE_NOPULSES) {
|
||||
cfg.v0.FailsafeOutputMode = true;
|
||||
} else {
|
||||
cfg.v0.FailsafeOutputMode = false;
|
||||
}
|
||||
|
||||
// PWM settings
|
||||
cfg.v0.PWMFrequency.Frequency = 50;
|
||||
cfg.v0.PWMFrequency.Synchronized = 0;
|
||||
|
||||
// PWM/PPM
|
||||
cfg.v0.AnalogOutput = 0;
|
||||
|
||||
// iBUS/SBUS
|
||||
cfg.v0.ExternalBusType = EB_BT_IBUS1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,6 +849,18 @@ uint8_t ProtoState::setFailSafe(int16_t* target)
|
||||
return (uint8_t) (AFHDS3_MAX_CHANNELS);
|
||||
}
|
||||
|
||||
Config_u* getConfig(uint8_t module)
|
||||
{
|
||||
auto p_state = &protoState[module];
|
||||
return p_state->getConfig();
|
||||
}
|
||||
|
||||
void applyModelConfig(uint8_t module)
|
||||
{
|
||||
auto p_state = &protoState[module];
|
||||
p_state->applyConfigFromModel();
|
||||
}
|
||||
|
||||
static void* initExternal(uint8_t module)
|
||||
{
|
||||
#if defined(AFHDS3_EXT_UART)
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#define AFHDS3_MIN_FREQ 50
|
||||
#define AFHDS3_MAX_FREQ 400
|
||||
#define AFHDS3_MAX_CHANNELS 18
|
||||
#define AFHDS3_FAILSAFE_MIN -15000
|
||||
#define AFHDS3_FAILSAFE_MAX 15000
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define AFHDS3_MAX_CHANNELS 18
|
||||
|
||||
namespace afhds3
|
||||
{
|
||||
|
||||
PACK(struct sSES_PWMFrequencyV0 {
|
||||
uint16_t Frequency : 15; // From 50 to 400Hz
|
||||
uint16_t Synchronized : 1; // 1=Synchronize the PWM output to the RF cycle
|
||||
// (lower latency but unstable frequency)
|
||||
});
|
||||
|
||||
enum eSES_PA_SetAnalogOutput {
|
||||
SES_ANALOG_OUTPUT_PWM = 0,
|
||||
SES_ANALOG_OUTPUT_PPM
|
||||
};
|
||||
|
||||
enum eEB_BusType {
|
||||
EB_BT_IBUS1=0,
|
||||
EB_BT_IBUS2,
|
||||
EB_BT_SBUS1
|
||||
};
|
||||
|
||||
// 48 bytes
|
||||
PACK(struct sDATA_ConfigV0 {
|
||||
uint8_t Version; // =0
|
||||
uint8_t EMIStandard; // eLNK_EMIStandard
|
||||
uint8_t IsTwoWay;
|
||||
uint8_t PhyMode; // eDATA_PHYMODE
|
||||
uint8_t SignalStrengthRCChannelNb; // 0xFF if not used, 0`18
|
||||
uint16_t FailsafeTimeout; // in unit of ms
|
||||
int16_t FailSafe[AFHDS3_MAX_CHANNELS];
|
||||
uint8_t FailsafeOutputMode; //TRUE Or FALSE
|
||||
sSES_PWMFrequencyV0 PWMFrequency;
|
||||
uint8_t AnalogOutput; // eSES_PA_SetAnalogOutput
|
||||
uint8_t ExternalBusType; // eEB_BusType
|
||||
});
|
||||
|
||||
#define SES_NB_MAX_CHANNELS (32)
|
||||
#define SES_NPT_NB_MAX_PORTS (4)
|
||||
|
||||
enum eSES_NewPortType {
|
||||
SES_NPT_PWM,
|
||||
SES_NPT_PPM,
|
||||
SES_NPT_SBUS,
|
||||
SES_NPT_IBUS1_IN,
|
||||
SES_NPT_IBUS1_OUT,
|
||||
SES_NPT_IBUS2,
|
||||
SES_NPT_IBUS2_HUB_PORT,
|
||||
SES_NPT_WSTX,
|
||||
SES_NPT_WSRX,
|
||||
SES_NPT_NONE=0xFF
|
||||
};
|
||||
|
||||
PACK(struct sSES_PWMFrequenciesAPPV1 {
|
||||
// One unsigned short per
|
||||
// channel, From 50 to 400Hz,
|
||||
// 1:1000Hz,2:833Hz
|
||||
uint16_t PWMFrequencies[SES_NB_MAX_CHANNELS];
|
||||
|
||||
// 1 bit per channel, 32 channels total
|
||||
uint32_t Synchronized;
|
||||
});
|
||||
|
||||
// 116 bytes
|
||||
PACK(struct sDATA_ConfigV1 {
|
||||
uint8_t Version; // =1
|
||||
uint8_t EMIStandard; // eLNK_EMIStandard
|
||||
uint8_t IsTwoWay;
|
||||
uint8_t PhyMode; // eDATA_PHYMODE
|
||||
uint8_t SignalStrengthRCChannelNb; // 0xFF if not used , 0`18
|
||||
uint16_t FailsafeTimeout; // in unit of ms
|
||||
int16_t FailSafe[AFHDS3_MAX_CHANNELS];
|
||||
uint8_t FailsafeOutputMode; // TRUE Or FALSE
|
||||
uint8_t NewPortTypes[SES_NPT_NB_MAX_PORTS]; // eSES_NewPortType
|
||||
sSES_PWMFrequenciesAPPV1 PWMFrequenciesV1;
|
||||
});
|
||||
|
||||
union Config_u
|
||||
{
|
||||
uint8_t version;
|
||||
sDATA_ConfigV0 v0;
|
||||
sDATA_ConfigV1 v1;
|
||||
uint8_t buffer[sizeof(sDATA_ConfigV1)];
|
||||
};
|
||||
|
||||
Config_u* getConfig(uint8_t moduleIdx);
|
||||
void applyModelConfig(uint8_t moduleIdx);
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user