feat: More flexible ADC inputs (#3870)
Co-authored-by: 3djc <lesitewebdejc@hotmail.com> Co-authored-by: Peter Feerick <peter.feerick@gmail.com> Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
This commit is contained in:
co-authored by
3djc
Peter Feerick
philmoz
parent
f5593c44e8
commit
b48e07026d
@@ -32,80 +32,35 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void switchInit()
|
||||
void boardInitSwitches()
|
||||
{
|
||||
_init_switches();
|
||||
}
|
||||
|
||||
swconfig_t switchGetDefaultConfig()
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
return _switch_default_config;
|
||||
return stm32_switch_get_position(&_switch_offsets[cat][idx]);
|
||||
}
|
||||
|
||||
const char* boardSwitchGetName(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
return _switch_offsets[cat][idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType boardSwitchGetType(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
return _switch_offsets[cat][idx].type;
|
||||
}
|
||||
|
||||
uint8_t boardGetMaxSwitches() { return n_switches; }
|
||||
uint8_t boardGetMaxFctSwitches() { return n_fct_switches; }
|
||||
|
||||
swconfig_t boardSwitchGetDefaultConfig() { return _switch_default_config; }
|
||||
|
||||
switch_display_pos_t switchGetDisplayPosition(uint8_t idx)
|
||||
{
|
||||
if (idx >= DIM(_switch_display))
|
||||
return {0, 0};
|
||||
// TODO: find a solution for FLEX switches so they can be displayed on main view
|
||||
if (idx >= DIM(_switch_display)) return {0, 0};
|
||||
|
||||
return _switch_display[idx];
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxSwitches()
|
||||
{
|
||||
return n_switches;
|
||||
}
|
||||
|
||||
uint8_t getSwitchCount()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxRow(uint8_t col)
|
||||
{
|
||||
uint8_t lastrow = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.col == col)
|
||||
lastrow = switch_display.row > lastrow ? switch_display.row : lastrow;
|
||||
}
|
||||
}
|
||||
return lastrow;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxFctSwitches()
|
||||
{
|
||||
return n_fct_switches;
|
||||
}
|
||||
|
||||
// returns state (0 / 1) of a specific switch position
|
||||
uint32_t switchState(uint8_t pos_idx)
|
||||
{
|
||||
auto d = div(pos_idx, 3);
|
||||
if (d.quot >= n_total_switches) return 0;
|
||||
return stm32_switch_get_state(&_switch_defs[d.quot], (SwitchHwPos)d.rem);
|
||||
}
|
||||
|
||||
SwitchHwPos switchGetPosition(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return SWITCH_HW_UP;
|
||||
return stm32_switch_get_position(&_switch_defs[idx]);
|
||||
}
|
||||
|
||||
const char* switchGetName(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return "";
|
||||
return _switch_defs[idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType switchGetHwType(uint8_t idx)
|
||||
{
|
||||
if (idx >= n_total_switches) return SWITCH_HW_2POS;
|
||||
return _switch_defs[idx].type;
|
||||
}
|
||||
|
||||
@@ -392,19 +392,22 @@ enum PotsWarnMode {
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#define MAX_POTS 16
|
||||
#define MAX_AXIS 2
|
||||
#else
|
||||
#define MAX_POTS 8
|
||||
#define MAX_AXIS 0
|
||||
#endif
|
||||
|
||||
#define MAX_VBAT 1
|
||||
#define MAX_RTC_BAT 1
|
||||
|
||||
#define MAX_ANALOG_INPUTS (MAX_STICKS + MAX_POTS + MAX_AXIS + MAX_VBAT + MAX_RTC_BAT)
|
||||
#define MAX_CALIB_ANALOG_INPUTS (MAX_STICKS + MAX_POTS + MAX_AXIS)
|
||||
#define MAX_ANALOG_INPUTS (MAX_STICKS + MAX_POTS + MAX_VBAT + MAX_RTC_BAT)
|
||||
#define MAX_CALIB_ANALOG_INPUTS (MAX_STICKS + MAX_POTS)
|
||||
|
||||
#define MAX_SWITCHES 20
|
||||
|
||||
#if !defined(MAX_FLEX_SWITCHES)
|
||||
#define MAX_FLEX_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#if defined(RADIO_T20)
|
||||
#define MAX_TRIMS 8
|
||||
#else
|
||||
@@ -482,11 +485,6 @@ enum MixSources {
|
||||
MIXSRC_FIRST_POT SKIP,
|
||||
MIXSRC_LAST_POT SKIP = MIXSRC_FIRST_POT + MAX_POTS - 1,
|
||||
|
||||
#if MAX_AXIS > 0
|
||||
MIXSRC_FIRST_AXIS SKIP,
|
||||
MIXSRC_LAST_AXIS SKIP = MIXSRC_FIRST_AXIS + MAX_AXIS - 1,
|
||||
#endif
|
||||
|
||||
#if defined(IMU)
|
||||
MIXSRC_TILT_X,
|
||||
MIXSRC_TILT_Y,
|
||||
|
||||
@@ -147,14 +147,14 @@ static inline void check_struct()
|
||||
CHKSIZE(ModelData, 6706);
|
||||
#elif defined(PCBHORUS)
|
||||
#if defined(PCBX10)
|
||||
CHKSIZE(RadioData, 848);
|
||||
CHKSIZE(RadioData, 836);
|
||||
CHKSIZE(ModelData, 15607);
|
||||
#else
|
||||
CHKSIZE(RadioData, 848);
|
||||
CHKSIZE(RadioData, 836);
|
||||
CHKSIZE(ModelData, 15607);
|
||||
#endif
|
||||
#elif defined(PCBNV14)
|
||||
CHKSIZE(RadioData, 848);
|
||||
CHKSIZE(RadioData, 836);
|
||||
CHKSIZE(ModelData, 15463);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -923,6 +923,7 @@ PACK(struct RadioData {
|
||||
CUST_ARRAY(slidersConfig, struct_sliderConfig, MAX_POTS, nullptr);
|
||||
potconfig_t potsConfig ARRAY(4,struct_potConfig,nullptr);
|
||||
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr);
|
||||
CUST_ARRAY(flexSwitches, struct_flexSwitch, MAX_FLEX_SWITCHES, flex_sw_valid);
|
||||
|
||||
EXTRA_GENERAL_FIELDS
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ inline uint8_t TIMER_ROW(uint8_t timer, uint8_t value)
|
||||
return HIDDEN_ROW;
|
||||
}
|
||||
|
||||
#define POT_WARN_ROWS PREFLIGHT_ROW(((g_model.potsWarnMode) ? adcGetMaxInputs(ADC_INPUT_POT) : (uint8_t)0))
|
||||
#define POT_WARN_ROWS PREFLIGHT_ROW(((g_model.potsWarnMode) ? adcGetMaxInputs(ADC_INPUT_FLEX) : (uint8_t)0))
|
||||
|
||||
#define TIMER_ROWS(x) \
|
||||
1, TIMER_ROW(x,0), \
|
||||
@@ -592,7 +592,7 @@ void menuModelSetup(event_t event)
|
||||
PREFLIGHT_ROW(0), // Custom position for throttle warning value
|
||||
WARN_ROWS
|
||||
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_POT + 1) - 1)), // Center beeps
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_FLEX + 1) - 1)), // Center beeps
|
||||
|
||||
0, // ADC Jitter filter
|
||||
|
||||
@@ -899,7 +899,7 @@ void menuModelSetup(event_t event)
|
||||
if (attr)
|
||||
CHECK_INCDEC_MODELVAR_ZERO_CHECK(
|
||||
event, g_model.thrTraceSrc,
|
||||
adcGetMaxInputs(ADC_INPUT_POT) + MAX_OUTPUT_CHANNELS,
|
||||
adcGetMaxInputs(ADC_INPUT_FLEX) + MAX_OUTPUT_CHANNELS,
|
||||
isThrottleSourceAvailable);
|
||||
|
||||
uint8_t idx = throttleSource2Source(g_model.thrTraceSrc);
|
||||
@@ -1078,7 +1078,7 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
if (g_model.potsWarnMode) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN+28;
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (int i = 0; i < max_pots; ++i) {
|
||||
|
||||
if (!IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
@@ -1092,7 +1092,7 @@ void menuModelSetup(event_t event)
|
||||
flags |= INVERS;
|
||||
}
|
||||
if (max_pots > 3) {
|
||||
lcdDrawText(x, y, getAnalogShortLabel(adcGetInputOffset(ADC_INPUT_POT) + i), flags);
|
||||
lcdDrawText(x, y, getAnalogShortLabel(adcGetInputOffset(ADC_INPUT_FLEX) + i), flags);
|
||||
x = lcdNextPos + 1;
|
||||
}
|
||||
else {
|
||||
@@ -1106,7 +1106,7 @@ void menuModelSetup(event_t event)
|
||||
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER: {
|
||||
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
|
||||
uint8_t input_max = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t input_max = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (uint8_t i = 0; i < input_max; i++) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN + i*FW;
|
||||
LcdFlags flags = 0;
|
||||
|
||||
@@ -81,8 +81,8 @@ void drawExternalAntennaAndRSSI()
|
||||
|
||||
void drawPotsBars()
|
||||
{
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
uint8_t configured_pots = 0;
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
@@ -567,14 +567,14 @@ void menuMainView(event_t event)
|
||||
uint8_t configured_switches = 0;
|
||||
|
||||
for (uint8_t i = 0; i < switches; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
if (SWITCH_EXISTS(i) && !switchIsFlex(i)) {
|
||||
configured_switches ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (configured_switches < 9) {
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
if (SWITCH_EXISTS(i) && !switchIsFlex(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.row >= 3) {
|
||||
drawSmallSwitch(switch_display.col == 0 ? 28 : 16 * FW + 1,
|
||||
@@ -594,7 +594,7 @@ void menuMainView(event_t event)
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
if (SWITCH_EXISTS(i) && !switchIsFlex(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
coord_t x = (switch_display.col == 0 ? 8 : 96) + switch_display.row * 5;
|
||||
drawSmallSwitch(x, 5 * FH + 1, 4, i);
|
||||
|
||||
@@ -538,7 +538,7 @@ void menuModelSetup(event_t event)
|
||||
SW_WARN_ROWS, // ITEM_MODEL_SETUP_SWITCHES_WARNING1
|
||||
POT_WARN_ROWS, // ITEM_MODEL_SETUP_POTS_WARNING
|
||||
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_POT + 1) - 1)), // ITEM_MODEL_SETUP_BEEP_CENTER
|
||||
uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_FLEX + 1) - 1)), // ITEM_MODEL_SETUP_BEEP_CENTER
|
||||
|
||||
0, // ITEM_MODEL_SETUP_USE_JITTER_FILTER
|
||||
|
||||
@@ -977,7 +977,7 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
if (g_model.potsWarnMode) {
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN+28;
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (int i = 0; i < max_pots; ++i) {
|
||||
|
||||
if (!IS_POT_SLIDER_AVAILABLE(i)) {
|
||||
@@ -1011,8 +1011,8 @@ void menuModelSetup(event_t event)
|
||||
|
||||
case ITEM_MODEL_SETUP_BEEP_CENTER: {
|
||||
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
uint8_t max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN) + adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
coord_t x = MODEL_SETUP_2ND_COLUMN;
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
if ( i >= pot_offset && IS_POT_MULTIPOS(i - pot_offset) ) {
|
||||
@@ -1024,7 +1024,7 @@ void menuModelSetup(event_t event)
|
||||
flags = BLINK | INVERS;
|
||||
else if (ANALOG_CENTER_BEEP(i) || (attr && CURSOR_ON_LINE()))
|
||||
flags = INVERS;
|
||||
if (adcGetMaxInputs(ADC_INPUT_POT) > 4 || i < pot_offset) {
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) > 4 || i < pot_offset) {
|
||||
lcdDrawText(x, y, getAnalogShortLabel(i), flags);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
void drawPotsBars()
|
||||
{
|
||||
// Optimization by Mike Blandford
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t x = LCD_W / 2 - max_pots / 2 * BAR_SPACING + BAR_SPACING / 2,
|
||||
i = 0;
|
||||
|
||||
@@ -183,8 +183,8 @@ static const coord_t _pot_slots[] = {
|
||||
void drawSliders()
|
||||
{
|
||||
uint8_t slot_idx = 0;
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
uint8_t offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
|
||||
@@ -534,7 +534,7 @@ void menuMainView(event_t event)
|
||||
uint8_t switches = switchGetMaxSwitches();
|
||||
if (getSwitchCount() > 16) { // beware, there is a desired col/row swap in this special mode
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
if (SWITCH_EXISTS(i) && !switchIsFlex(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (g_model.view == VIEW_INPUTS) {
|
||||
coord_t x = 50 + (switch_display.row % 5) * 4 +
|
||||
@@ -552,7 +552,7 @@ void menuMainView(event_t event)
|
||||
else {
|
||||
coord_t shiftright = switchGetMaxRow(1) < 4 ? 20 : 0;
|
||||
for (int i = 0; i < switches; ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
if (SWITCH_EXISTS(i) && !switchIsFlex(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (g_model.view == VIEW_INPUTS) {
|
||||
coord_t x = (switch_display.col == 0 ? 50 : 125) +
|
||||
|
||||
@@ -39,8 +39,16 @@ struct HWInputEdit : public RadioTextEdit {
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t col_three_dsc[] = {
|
||||
LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t col_three_dsc[] = {LV_GRID_FR(8), LV_GRID_FR(12), LV_GRID_FR(20),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(2), LV_GRID_FR(5),
|
||||
LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(22), LV_GRID_FR(48), LV_GRID_FR(16),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#endif
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
@@ -71,7 +79,7 @@ HWSticks::HWSticks(Window* parent) : FormWindow(parent, rect_t{})
|
||||
|
||||
HWPots::HWPots(Window* parent) : FormWindow(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_three_dsc, row_dsc, 2);
|
||||
FlexGridLayout grid(pots_col_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
potsChanged = false;
|
||||
@@ -83,7 +91,7 @@ HWPots::HWPots(Window* parent) : FormWindow(parent, rect_t{})
|
||||
}
|
||||
});
|
||||
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (int i = 0; i < max_pots; i++) {
|
||||
// TODO: check initialised ADC inputs instead!
|
||||
|
||||
@@ -93,29 +101,32 @@ HWPots::HWPots(Window* parent) : FormWindow(parent, rect_t{})
|
||||
// if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
// #endif
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, adcGetInputLabel(ADC_INPUT_POT, i), 0,
|
||||
new StaticText(line, rect_t{}, adcGetInputLabel(ADC_INPUT_FLEX, i), 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormWindow(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
#if LCD_H > LCD_W
|
||||
line = newLine(&grid);
|
||||
#endif
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, (char*)analogGetCustomLabel(ADC_INPUT_POT, i),
|
||||
new HWInputEdit(line, (char*)analogGetCustomLabel(ADC_INPUT_FLEX, i),
|
||||
LEN_ANA_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_POTTYPES, POT_NONE, POT_SLIDER_WITH_DETENT,
|
||||
[=]() -> int {
|
||||
return bfGet<potconfig_t>(g_eeGeneral.potsConfig, POT_CFG_BITS * i,
|
||||
POT_CFG_BITS);
|
||||
},
|
||||
auto pot = new Choice(
|
||||
line, rect_t{}, STR_POTTYPES, FLEX_NONE, FLEX_SWITCH,
|
||||
[=]() -> int { return getPotType(i); },
|
||||
[=](int newValue) {
|
||||
g_eeGeneral.potsConfig = bfSet<potconfig_t>(
|
||||
g_eeGeneral.potsConfig, newValue, POT_CFG_BITS * i, POT_CFG_BITS);
|
||||
setPotType(i, newValue);
|
||||
switchFixFlexConfig();
|
||||
potsChanged = true;
|
||||
SET_DIRTY();
|
||||
});
|
||||
pot->setAvailableHandler([=](int val) { return isPotTypeAvailable(val); });
|
||||
|
||||
new ToggleSwitch(
|
||||
line, rect_t{}, [=]() -> uint8_t { return (uint8_t)getPotInversion(i); },
|
||||
[=](int8_t newValue) {
|
||||
setPotInversion(i, newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +141,7 @@ class SwitchDynamicLabel : public StaticText
|
||||
|
||||
std::string label()
|
||||
{
|
||||
std::string str(switchGetName(index));
|
||||
std::string str(switchGetCanonicalName(index));
|
||||
return str + getSwitchPositionSymbol(lastpos);
|
||||
}
|
||||
|
||||
@@ -159,18 +170,53 @@ class SwitchDynamicLabel : public StaticText
|
||||
uint8_t lastpos = 0xff;
|
||||
};
|
||||
|
||||
static void flex_channel_changed(lv_event_t* e)
|
||||
{
|
||||
auto target = lv_event_get_target(e);
|
||||
auto channel = (Choice*)lv_obj_get_user_data(target);
|
||||
|
||||
auto sw_cfg = (Choice*)lv_event_get_user_data(e);
|
||||
lv_obj_t* sw_cfg_obj = sw_cfg->getLvObj();
|
||||
|
||||
if (channel->getIntValue() < 0) {
|
||||
lv_obj_add_flag(sw_cfg_obj, LV_OBJ_FLAG_HIDDEN);
|
||||
sw_cfg->setValue(0);
|
||||
} else {
|
||||
lv_obj_clear_flag(sw_cfg_obj, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
HWSwitches::HWSwitches(Window* parent) : FormWindow(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_three_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
auto max_switches = switchGetMaxSwitches();
|
||||
for (int i = 0; i < max_switches; i++) {
|
||||
auto line = newLine(&grid);
|
||||
new SwitchDynamicLabel(line, i);
|
||||
|
||||
new HWInputEdit(line, (char*)switchGetCustomName(i), LEN_SWITCH_NAME);
|
||||
new Choice(
|
||||
line, rect_t{}, STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
|
||||
|
||||
auto box = new FormWindow(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
box->setWidth(lv_pct(45));
|
||||
|
||||
Choice* channel = nullptr;
|
||||
if (switchIsFlex(i)) {
|
||||
channel = new Choice(
|
||||
box, rect_t{}, -1, adcGetMaxInputs(ADC_INPUT_FLEX) - 1,
|
||||
[=]() -> int { return switchGetFlexConfig(i); },
|
||||
[=](int newValue) { switchConfigFlex(i, newValue); });
|
||||
channel->setAvailableHandler(
|
||||
[=](int val) { return val < 0 || switchIsFlexInputAvailable(i, val); });
|
||||
channel->setTextHandler([=](int val) -> std::string {
|
||||
if (val < 0) return STR_NONE;
|
||||
return adcGetInputLabel(ADC_INPUT_FLEX, val);
|
||||
});
|
||||
}
|
||||
|
||||
auto sw_cfg = new Choice(
|
||||
box, rect_t{}, STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
|
||||
[=]() -> int { return SWITCH_CONFIG(i); },
|
||||
[=](int newValue) {
|
||||
swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(i);
|
||||
@@ -179,6 +225,12 @@ HWSwitches::HWSwitches(Window* parent) : FormWindow(parent, rect_t{})
|
||||
((swconfig_t(newValue) & SW_CFG_MASK) << (SW_CFG_BITS * i));
|
||||
SET_DIRTY();
|
||||
});
|
||||
|
||||
if (channel) {
|
||||
lv_obj_t* obj = channel->getLvObj();
|
||||
lv_obj_add_event_cb(obj, flex_channel_changed, LV_EVENT_VALUE_CHANGED, sw_cfg);
|
||||
lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +241,11 @@ HWInputDialog<T>::HWInputDialog(const char* title) :
|
||||
setCloseWhenClickOutside(true);
|
||||
if (title) content->setTitle(title);
|
||||
new T(&content->form);
|
||||
#if LCD_W > LCD_H
|
||||
content->setWidth(LCD_W * 0.8);
|
||||
#else
|
||||
content->setWidth(LCD_W * 0.95);
|
||||
#endif
|
||||
content->updateSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect,
|
||||
void MainViewSlider::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
auto pot_idx = adcGetInputOffset(ADC_INPUT_POT) + idx;
|
||||
auto pot_idx = adcGetInputOffset(ADC_INPUT_FLEX) + idx;
|
||||
int16_t newValue = calibratedAnalogs[pot_idx];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
|
||||
@@ -163,7 +163,7 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
||||
new SwitchWarnMatrix(line, rect_t{});
|
||||
|
||||
// Pots and sliders warning
|
||||
if (adcGetMaxInputs(ADC_INPUT_POT) > 0) {
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) > 0) {
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_POTWARNINGSTATE, 0, COLOR_THEME_PRIMARY1);
|
||||
auto pots_wm = new Choice(line, rect_t{}, STR_PREFLIGHT_POTSLIDER_CHECK, 0, 2,
|
||||
@@ -218,7 +218,7 @@ SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) :
|
||||
uint8_t btn_id = 0;
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
setTextAndState(i);
|
||||
setTextAndState(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
@@ -332,7 +332,7 @@ CenterBeepsMatrix::CenterBeepsMatrix(Window* parent, const rect_t& r) :
|
||||
uint8_t btn_cnt = 0;
|
||||
|
||||
auto max_sticks = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
max_analogs = max_sticks + max_pots;
|
||||
|
||||
for (uint8_t i = 0; i < max_analogs; i++) {
|
||||
@@ -373,7 +373,7 @@ void CenterBeepsMatrix::setTextAndState(uint8_t btn_id)
|
||||
if (ana_idx[btn_id] < max_sticks)
|
||||
setText(btn_id, getAnalogShortLabel(ana_idx[btn_id]));
|
||||
else
|
||||
setText(btn_id, getAnalogLabel(ADC_INPUT_POT, ana_idx[btn_id] - max_sticks));
|
||||
setText(btn_id, getAnalogLabel(ADC_INPUT_FLEX, ana_idx[btn_id] - max_sticks));
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,11 +70,14 @@ class AnaViewWindow: public FormWindow {
|
||||
{
|
||||
char s[10];
|
||||
|
||||
auto pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
+ adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
if (i > adcGetMaxInputs(ADC_INPUT_MAIN) && !IS_POT_AVAILABLE(i - adcGetMaxInputs(ADC_INPUT_MAIN))) continue;
|
||||
if (i >= pot_offset && (POT_CONFIG(i - pot_offset) == FLEX_NONE))
|
||||
continue;
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
if ((i & 1) == 0)
|
||||
line = newLine(grid);
|
||||
@@ -316,7 +319,7 @@ class AnaFilteredDevViewWindow: public AnaViewWindow {
|
||||
AnaViewWindow(parent)
|
||||
{
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
+ adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++)
|
||||
stats[i].clear();
|
||||
@@ -325,7 +328,7 @@ class AnaFilteredDevViewWindow: public AnaViewWindow {
|
||||
void checkEvents() override
|
||||
{
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
+ adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
stats[i].write(getAnalogValue(i));
|
||||
@@ -419,7 +422,7 @@ class AnaMinMaxViewWindow: public AnaViewWindow {
|
||||
AnaViewWindow(parent)
|
||||
{
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
+ adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++)
|
||||
minmax[i].clear();
|
||||
@@ -437,7 +440,7 @@ class AnaMinMaxViewWindow: public AnaViewWindow {
|
||||
void checkEvents() override
|
||||
{
|
||||
auto max_inputs = adcGetMaxInputs(ADC_INPUT_MAIN)
|
||||
+ adcGetMaxInputs(ADC_INPUT_POT);
|
||||
+ adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
minmax[i].write(getAnalogValue(i));
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
static const uint8_t _trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, 0, 1, 8, 9, 10, 11};
|
||||
|
||||
#if !defined(PCBNV14)
|
||||
static EnumKeys get_ith_key(uint8_t i)
|
||||
{
|
||||
auto supported_keys = keysGetSupported();
|
||||
@@ -41,7 +40,6 @@ static EnumKeys get_ith_key(uint8_t i)
|
||||
// we assume: i < keysGetMaxKeys()
|
||||
return (EnumKeys)0;
|
||||
}
|
||||
#endif
|
||||
|
||||
class RadioKeyDiagsWindow : public Window
|
||||
{
|
||||
@@ -96,38 +94,27 @@ class RadioKeyDiagsWindow : public Window
|
||||
dc->drawText(TRIM_MINUS_COLUMN, 1, "-", COLOR_THEME_PRIMARY1);
|
||||
dc->drawText(TRIM_PLUS_COLUMN, 1, "+", COLOR_THEME_PRIMARY1);
|
||||
|
||||
#if !defined(PCBNV14)
|
||||
// KEYS
|
||||
coord_t y = 1;
|
||||
for (uint8_t i = 0; i < keysGetMaxKeys(); i++) {
|
||||
auto k = get_ith_key(i);
|
||||
y += FH;
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(k), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, k);
|
||||
y += FH;
|
||||
}
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
y += FH;
|
||||
dc->drawText(KEY_COLUMN, y, STR_ROTARY_ENCODER, COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(70, y, rotaryEncoderGetValue(), COLOR_THEME_PRIMARY1);
|
||||
#endif
|
||||
#else // defined(PCBNV14)
|
||||
// KEYS
|
||||
{
|
||||
coord_t y = 1;
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(KEY_ENTER), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, KEY_ENTER);
|
||||
y += FH;
|
||||
dc->drawText(KEY_COLUMN, y, keysGetLabel(KEY_EXIT), COLOR_THEME_PRIMARY1);
|
||||
displayKeyState(dc, 70, y, KEY_EXIT);
|
||||
}
|
||||
#endif
|
||||
// SWITCHES
|
||||
y = 1;
|
||||
for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
coord_t y = 1 + FH * i;
|
||||
getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i);
|
||||
getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3));
|
||||
drawSwitch(dc, SWITCHES_COLUMN, y, sw, COLOR_THEME_PRIMARY1);
|
||||
y +=FH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Windo
|
||||
sliders[2] = new MainViewHorizontalSlider(br, 2);
|
||||
|
||||
// TODO: check how many pots are configured instead
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
if (max_pots > 3) {
|
||||
// create containers for the sliders, so that they are at the borders of the display
|
||||
// on top of each other, when there are two sliders to display per side
|
||||
|
||||
@@ -143,16 +143,16 @@ static void _init_menu_tab_array(uint8_t* tab, size_t len)
|
||||
tab[i] = idx < max_sticks ? 0 : HIDDEN_ROW;
|
||||
}
|
||||
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (int i = ITEM_RADIO_HARDWARE_POT; i <= ITEM_RADIO_HARDWARE_POT_END; i++) {
|
||||
uint8_t idx = i - ITEM_RADIO_HARDWARE_POT;
|
||||
tab[i] = idx < max_pots ? 1 : HIDDEN_ROW;
|
||||
tab[i] = idx < max_pots ? 2 : HIDDEN_ROW;
|
||||
}
|
||||
|
||||
auto max_switches = switchGetMaxSwitches();
|
||||
for (int i = ITEM_RADIO_HARDWARE_SWITCH; i <= ITEM_RADIO_HARDWARE_SWITCH_END; i++) {
|
||||
uint8_t idx = i - ITEM_RADIO_HARDWARE_SWITCH;
|
||||
tab[i] = idx < max_switches ? 1 : HIDDEN_ROW;
|
||||
tab[i] = (idx < max_switches && idx < max_switches + MAX_FLEX_SWITCHES) ? 2 : idx < max_switches ? 1 : HIDDEN_ROW;
|
||||
}
|
||||
|
||||
tab[ITEM_RADIO_HARDWARE_BATTERY_CALIB] = 0;
|
||||
@@ -479,33 +479,38 @@ void menuRadioHardware(event_t event)
|
||||
} else if (k <= ITEM_RADIO_HARDWARE_POT_END) {
|
||||
// Pots & sliders
|
||||
int idx = k - ITEM_RADIO_HARDWARE_POT;
|
||||
uint8_t shift = (POT_CFG_BITS * idx);
|
||||
potconfig_t mask = POT_CONFIG_MASK(idx);
|
||||
|
||||
// draw hw name
|
||||
LcdFlags flags = menuHorizontalPosition < 0 ? attr : 0;
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_CHAR_POT, flags);
|
||||
lcdDrawText(lcdNextPos, y, adcGetInputLabel(ADC_INPUT_POT, idx), flags);
|
||||
lcdDrawText(lcdNextPos, y, adcGetInputLabel(ADC_INPUT_FLEX, idx), flags);
|
||||
|
||||
// draw custom name
|
||||
if (analogHasCustomLabel(ADC_INPUT_POT, idx) ||
|
||||
if (analogHasCustomLabel(ADC_INPUT_FLEX, idx) ||
|
||||
(attr && s_editMode > 0 && menuHorizontalPosition == 0)) {
|
||||
editName(HW_SETTINGS_COLUMN1, y,
|
||||
(char*)analogGetCustomLabel(ADC_INPUT_POT, idx), LEN_ANA_NAME, event,
|
||||
(char*)analogGetCustomLabel(ADC_INPUT_FLEX, idx), LEN_ANA_NAME, event,
|
||||
attr && menuHorizontalPosition == 0, 0, old_editMode);
|
||||
} else {
|
||||
lcdDrawMMM(HW_SETTINGS_COLUMN1, y, menuHorizontalPosition==0 ? attr : 0);
|
||||
}
|
||||
|
||||
// pot config
|
||||
uint8_t potType = (g_eeGeneral.potsConfig & mask) >> shift;
|
||||
uint8_t potType = getPotType(idx);
|
||||
potType = editChoice(HW_SETTINGS_COLUMN2, y, "", STR_POTTYPES, potType,
|
||||
POT_NONE, POT_SLIDER_WITH_DETENT,
|
||||
FLEX_NONE, FLEX_SWITCH,
|
||||
menuHorizontalPosition == 1 ? attr : 0, event);
|
||||
g_eeGeneral.potsConfig &= ~mask;
|
||||
g_eeGeneral.potsConfig |= (potType << shift);
|
||||
if (checkIncDec_Ret) switchFixFlexConfig();
|
||||
setPotType(idx, potType);
|
||||
|
||||
} else if (k <= ITEM_RADIO_HARDWARE_SWITCH_END) {
|
||||
// ADC inversion
|
||||
flags = menuHorizontalPosition == 2 ? attr : 0;
|
||||
bool potinversion = getPotInversion(idx);
|
||||
lcdDrawChar(LCD_W - 8, y, potinversion ? 127 : 126, flags);
|
||||
if (flags & (~RIGHT)) potinversion = checkIncDec(event, potinversion, 0, 1, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL);
|
||||
setPotInversion(idx, potinversion);
|
||||
}
|
||||
else if (k <= ITEM_RADIO_HARDWARE_SWITCH_END) {
|
||||
// Switches
|
||||
int index = k - ITEM_RADIO_HARDWARE_SWITCH;
|
||||
int config = SWITCH_CONFIG(index);
|
||||
@@ -514,24 +519,59 @@ void menuRadioHardware(event_t event)
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_CHAR_SWITCH, flags);
|
||||
lcdDrawText(lcdNextPos, y, switchGetName(index), flags);
|
||||
|
||||
flags = menuHorizontalPosition == 0 ? attr : 0;
|
||||
if (switchHasCustomName(index) ||
|
||||
(attr && s_editMode > 0 && menuHorizontalPosition == 0)) {
|
||||
editName(HW_SETTINGS_COLUMN1, y, (char*)switchGetCustomName(index),
|
||||
LEN_SWITCH_NAME, event, flags, 0, old_editMode);
|
||||
} else {
|
||||
lcdDrawMMM(HW_SETTINGS_COLUMN1, y, flags);
|
||||
if (switchIsFlex(index)) {
|
||||
// flexSwitch source
|
||||
flags = menuHorizontalPosition == 0 ? attr : 0;
|
||||
auto source = switchGetFlexConfig(index);
|
||||
lcdDrawText(HW_SETTINGS_COLUMN1, y, (source < 0) ? STR_NONE : adcGetInputLabel(ADC_INPUT_FLEX, source), flags);
|
||||
if (flags & (~RIGHT)) source = checkIncDec(event, source, -1, adcGetMaxInputs(ADC_INPUT_FLEX) - 1, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isFlexSwitchSourceValid);
|
||||
switchConfigFlex(index, source);
|
||||
|
||||
//Name
|
||||
flags = menuHorizontalPosition == 1 ? attr : 0;
|
||||
if (switchHasCustomName(index) ||
|
||||
(attr && s_editMode > 0 && menuHorizontalPosition == 1)) {
|
||||
editName(HW_SETTINGS_COLUMN2, y,
|
||||
(char*)switchGetCustomName(index), LEN_SWITCH_NAME,
|
||||
event, flags, 0, old_editMode);
|
||||
} else {
|
||||
lcdDrawMMM(HW_SETTINGS_COLUMN2, y, flags);
|
||||
}
|
||||
|
||||
// Switch type
|
||||
flags = menuHorizontalPosition == 2 ? attr : 0;
|
||||
config = editChoice(HW_SETTINGS_COLUMN2 + 25, y, "", STR_SWTYPES, config,
|
||||
SWITCH_NONE, switchGetMaxType(index), flags, event);
|
||||
|
||||
if (attr && checkIncDec_Ret) {
|
||||
swconfig_t mask = SWITCH_CONFIG_MASK(index);
|
||||
g_eeGeneral.switchConfig =
|
||||
(g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(config) & SW_CFG_MASK) << (SW_CFG_BITS * index));
|
||||
}
|
||||
}
|
||||
else {
|
||||
flags = menuHorizontalPosition == 0 ? attr : 0;
|
||||
if (switchHasCustomName(index) ||
|
||||
(attr && s_editMode > 0 && menuHorizontalPosition == 0)) {
|
||||
editName(HW_SETTINGS_COLUMN1, y,
|
||||
(char*)switchGetCustomName(index), LEN_SWITCH_NAME,
|
||||
event, flags, 0, old_editMode);
|
||||
} else {
|
||||
lcdDrawMMM(HW_SETTINGS_COLUMN1, y, flags);
|
||||
}
|
||||
|
||||
flags = menuHorizontalPosition == 1 ? attr : 0;
|
||||
config = editChoice(HW_SETTINGS_COLUMN2, y, "", STR_SWTYPES, config,
|
||||
SWITCH_NONE, switchGetMaxType(index), flags, event);
|
||||
flags = menuHorizontalPosition == 1 ? attr : 0;
|
||||
config =
|
||||
editChoice(HW_SETTINGS_COLUMN2, y, "", STR_SWTYPES, config,
|
||||
SWITCH_NONE, switchGetMaxType(index), flags, event);
|
||||
|
||||
if (attr && checkIncDec_Ret) {
|
||||
swconfig_t mask = SWITCH_CONFIG_MASK(index);
|
||||
g_eeGeneral.switchConfig =
|
||||
(g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(config) & SW_CFG_MASK) << (SW_CFG_BITS * index));
|
||||
if (attr && checkIncDec_Ret) {
|
||||
swconfig_t mask = SWITCH_CONFIG_MASK(index);
|
||||
g_eeGeneral.switchConfig =
|
||||
(g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(config) & SW_CFG_MASK) << (SW_CFG_BITS * index));
|
||||
}
|
||||
}
|
||||
} else if (k <= ITEM_RADIO_HARDWARE_SERIAL_PORT_END) {
|
||||
auto port_nr = k - ITEM_RADIO_HARDWARE_SERIAL_PORT;
|
||||
|
||||
@@ -198,11 +198,6 @@ bool isSourceAvailable(int source)
|
||||
return IS_POT_SLIDER_AVAILABLE(source - MIXSRC_FIRST_POT);
|
||||
}
|
||||
|
||||
#if MAX_AXIS > 0
|
||||
if (source >= MIXSRC_FIRST_AXIS && source <= MIXSRC_LAST_AXIS)
|
||||
return source - MIXSRC_FIRST_AXIS < adcGetMaxInputs(ADC_INPUT_AXIS);
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS) && !defined(SPACEMOUSE)
|
||||
if (source >= MIXSRC_FIRST_SPACEMOUSE && source <= MIXSRC_LAST_SPACEMOUSE)
|
||||
return false;
|
||||
@@ -298,13 +293,6 @@ bool isSourceAvailableInInputs(int source)
|
||||
if (source >= MIXSRC_FIRST_POT && source <= MIXSRC_LAST_POT)
|
||||
return IS_POT_SLIDER_AVAILABLE(source - MIXSRC_FIRST_POT);
|
||||
|
||||
#if MAX_AXIS > 0
|
||||
if (source >= MIXSRC_FIRST_AXIS && source <= MIXSRC_LAST_AXIS) {
|
||||
auto idx = source - MIXSRC_FIRST_AXIS;
|
||||
return idx < adcGetMaxInputs(ADC_INPUT_AXIS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(IMU)
|
||||
if (source == MIXSRC_TILT_X || source == MIXSRC_TILT_Y)
|
||||
return true;
|
||||
@@ -391,7 +379,7 @@ bool isSwitchAvailable(int swtch, SwitchContext context)
|
||||
|
||||
if (swtch >= SWSRC_FIRST_MULTIPOS_SWITCH && swtch <= SWSRC_LAST_MULTIPOS_SWITCH) {
|
||||
int index = (swtch - SWSRC_FIRST_MULTIPOS_SWITCH) / XPOTS_MULTIPOS_COUNT;
|
||||
return (index < adcGetMaxInputs(ADC_INPUT_POT)) ? IS_POT_MULTIPOS(index) : false;
|
||||
return (index < adcGetMaxInputs(ADC_INPUT_FLEX)) ? IS_POT_MULTIPOS(index) : false;
|
||||
}
|
||||
|
||||
if (swtch >= SWSRC_FIRST_TRIM && swtch <= SWSRC_LAST_TRIM) {
|
||||
@@ -1209,3 +1197,57 @@ uint8_t expandableSection(coord_t y, const char* title, uint8_t value, uint8_t a
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isPotTypeAvailable(uint8_t type)
|
||||
{
|
||||
if (type == FLEX_SWITCH) {
|
||||
if (MAX_FLEX_SWITCHES == 0)
|
||||
return false;
|
||||
|
||||
auto availableFlexSwitch = MAX_FLEX_SWITCHES;
|
||||
for (uint8_t i = 0; i < adcGetMaxInputs(ADC_INPUT_FLEX); i++) {
|
||||
if (POT_CONFIG(i) == FLEX_SWITCH) availableFlexSwitch--;
|
||||
if (availableFlexSwitch == 0) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isFlexSwitchSourceValid(int source)
|
||||
{
|
||||
if (MAX_FLEX_SWITCHES == 0) return false;
|
||||
|
||||
// Allow NONE
|
||||
if (source < 0) return true;
|
||||
|
||||
// already assigned ?
|
||||
for (int i=0; i < MAX_FLEX_SWITCHES;i++) {
|
||||
if (source == switchGetFlexConfig_raw(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (POT_CONFIG(source) != FLEX_SWITCH) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getPotInversion(int index)
|
||||
{
|
||||
return bfGet<potconfig_t>(g_eeGeneral.potsConfig, (POT_CFG_BITS * index) + POT_CFG_TYPE_BITS, POT_CFG_INV_BITS);
|
||||
}
|
||||
|
||||
void setPotInversion(int index, bool value)
|
||||
{
|
||||
g_eeGeneral.potsConfig = bfSet<potconfig_t>(g_eeGeneral.potsConfig, value, (POT_CFG_BITS * index) + POT_CFG_TYPE_BITS, POT_CFG_INV_BITS);
|
||||
}
|
||||
|
||||
uint8_t getPotType(int index)
|
||||
{
|
||||
return bfGet<potconfig_t>(g_eeGeneral.potsConfig, POT_CFG_BITS * index, POT_CFG_TYPE_BITS);
|
||||
}
|
||||
|
||||
void setPotType(int index, int value)
|
||||
{
|
||||
g_eeGeneral.potsConfig = bfSet<potconfig_t>(g_eeGeneral.potsConfig, value, (POT_CFG_BITS * index), POT_CFG_TYPE_BITS);
|
||||
}
|
||||
@@ -99,6 +99,12 @@ bool isInternalModuleSupported(int moduleType);
|
||||
bool isRfProtocolAvailable(int protocol);
|
||||
bool isTrainerModeAvailable(int mode);
|
||||
bool isAssignableFunctionAvailable(int function, CustomFunctionData * functions);
|
||||
bool isPotTypeAvailable(uint8_t type);
|
||||
bool isFlexSwitchSourceValid(int source);
|
||||
bool getPotInversion(int index);
|
||||
void setPotInversion(int index, bool value);
|
||||
uint8_t getPotType(int index);
|
||||
void setPotType(int index, int value);
|
||||
|
||||
bool isSensorUnit(int sensor, uint8_t unit);
|
||||
bool isCellsSensor(int sensor);
|
||||
|
||||
@@ -7,8 +7,14 @@ set(SRC ${SRC}
|
||||
hal/module_port.cpp
|
||||
hal/adc_driver.cpp
|
||||
hal/key_driver.cpp
|
||||
hal/switch_driver.cpp
|
||||
)
|
||||
|
||||
if (FLEXSW)
|
||||
# define the number of allowed flexible adc entries used as switch
|
||||
add_definitions(-DMAX_FLEX_SWITCHES=${FLEXSW})
|
||||
endif()
|
||||
|
||||
include_directories(${FATFS_DIR} ${FATFS_DIR}/option)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
|
||||
+158
-92
@@ -22,10 +22,8 @@
|
||||
#include "adc_driver.h"
|
||||
#include "board.h"
|
||||
|
||||
// IS_POT_SLIDER_AVAILABLE()
|
||||
#include "opentx.h"
|
||||
|
||||
|
||||
const etx_hal_adc_driver_t* _hal_adc_driver = nullptr;
|
||||
const etx_hal_adc_inputs_t* _hal_adc_inputs = nullptr;
|
||||
|
||||
@@ -71,10 +69,20 @@ bool adcRead()
|
||||
return true;
|
||||
}
|
||||
|
||||
void adcCalibDefaults()
|
||||
{
|
||||
for (int i = 0; i < adcGetMaxCalibratedInputs(); i++) {
|
||||
CalibData* calib = &g_eeGeneral.calib[i];
|
||||
calib->mid = 1023;
|
||||
calib->spanNeg = 1024 - (1024 / STICK_TOLERANCE);
|
||||
calib->spanPos = 1024 - (1024 / STICK_TOLERANCE);
|
||||
}
|
||||
}
|
||||
|
||||
void adcCalibSetMidPoint()
|
||||
{
|
||||
uint8_t max_inputs = adcGetMaxCalibratedInputs();
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_inputs; i++) {
|
||||
|
||||
@@ -124,32 +132,32 @@ void adcCalibSetMinMax()
|
||||
{
|
||||
// get low and high vals for sticks and pots
|
||||
uint8_t max_input = adcGetMaxCalibratedInputs();
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_input; i++) {
|
||||
|
||||
auto& calib = reusableBuffer.calib.inputs[i];
|
||||
int16_t vt = getAnalogValue(i) >> 1;
|
||||
|
||||
if (i < pot_offset || !IS_POT_MULTIPOS(i - pot_offset)) {
|
||||
int16_t vt = anaIn(i);
|
||||
calib.input.loVal = min(vt, calib.input.loVal);
|
||||
calib.input.hiVal = max(vt, calib.input.hiVal);
|
||||
|
||||
if (i >= pot_offset && IS_POT_WITHOUT_DETENT(i - pot_offset)) {
|
||||
calib.input.midVal = (calib.input.hiVal + calib.input.loVal) / 2;
|
||||
if (i >= pot_offset) {
|
||||
auto pot_cfg = POT_CONFIG(i - pot_offset);
|
||||
if (pot_cfg == FLEX_POT || pot_cfg == FLEX_SWITCH || pot_cfg == FLEX_NONE) {
|
||||
calib.input.midVal = (calib.input.hiVal + calib.input.loVal) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// in case we enough input movement, store the result
|
||||
if (abs(calib.input.loVal - calib.input.hiVal) > 50) {
|
||||
writeAnalogCalib(i, calib.input.loVal, calib.input.midVal, calib.input.hiVal);
|
||||
writeAnalogCalib(i, calib.input.loVal, calib.input.midVal, calib.input.hiVal);
|
||||
}
|
||||
} else {
|
||||
auto& xpot = calib.xpot;
|
||||
int count = xpot.stepsCount;
|
||||
if (count <= XPOTS_MULTIPOS_COUNT) {
|
||||
// use raw analog value for multipos calibraton,
|
||||
// anaIn() already has multipos decoded value
|
||||
int16_t vt = getAnalogValue(i) >> 1;
|
||||
if (xpot.lastCount == 0 || vt < xpot.lastPosition - XPOT_DELTA ||
|
||||
vt > xpot.lastPosition + XPOT_DELTA) {
|
||||
xpot.lastPosition = vt;
|
||||
@@ -192,8 +200,8 @@ void adcCalibSetMinMax()
|
||||
|
||||
static void disableUncalibratedXPots()
|
||||
{
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
uint8_t max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_pots; i++) {
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
@@ -252,8 +260,8 @@ uint16_t* getAnalogValues()
|
||||
// used by diaganas
|
||||
uint32_t s_anaFilt[MAX_ANALOG_INPUTS];
|
||||
|
||||
#define ANALOG_MULTIPLIER (1<<ANALOG_SCALE)
|
||||
#define ANA_FILT(chan) (s_anaFilt[chan] / (JITTER_ALPHA * ANALOG_MULTIPLIER))
|
||||
#define ANALOG_MULTIPLIER (1 << ANALOG_SCALE)
|
||||
#define ANA_FILT(chan) (s_anaFilt[chan] / (JITTER_ALPHA * ANALOG_MULTIPLIER))
|
||||
#if (JITTER_ALPHA * ANALOG_MULTIPLIER > 32)
|
||||
#error "JITTER_FILTER_STRENGTH and ANALOG_SCALE are too big, their summ should be <= 5 !!!"
|
||||
#endif
|
||||
@@ -308,10 +316,121 @@ uint16_t getBatteryVoltage()
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t apply_low_pass_filter(uint32_t v, uint32_t v_prev,
|
||||
bool is_main_input)
|
||||
{
|
||||
// Jitter filter:
|
||||
// * pass trough any big change directly
|
||||
// * for small change use Modified moving average (MMA) filter
|
||||
//
|
||||
// Explanation:
|
||||
//
|
||||
// Normal MMA filter has this formula:
|
||||
// <out> = ((ALPHA-1)*<out> + <in>)/ALPHA
|
||||
//
|
||||
// If calculation is done this way with integer arithmetics, then any small
|
||||
// change in input signal is lost. One way to combat that, is to rearrange the
|
||||
// formula somewhat, to store a more precise (larger) number between
|
||||
// iterations. The basic idea is to store undivided value between iterations.
|
||||
// Therefore an new variable <filtered> is used. The new formula becomes:
|
||||
// <filtered> = <filtered> - <filtered>/ALPHA + <in>
|
||||
// <out> = <filtered>/ALPHA (use only when out is needed)
|
||||
//
|
||||
// The above formula with a maximum allowed ALPHA value (we are limited by
|
||||
// the 16 bit s_anaFilt[]) was tested on the radio. The resulting signal still
|
||||
// had some jitter (a value of 1 was observed). The jitter might be bigger on
|
||||
// other radios.
|
||||
//
|
||||
// So another idea is to use larger input values for filtering. So instead of
|
||||
// using input in a range from 0 to 2047, we use twice larger number (temp[x]
|
||||
// is divided less)
|
||||
//
|
||||
// This also means that ALPHA must be lowered (remember 16 bit limit), but
|
||||
// test results have proved that this kind of filtering gives better results.
|
||||
// So the recommended values for filter are:
|
||||
// JITTER_FILTER_STRENGTH 4
|
||||
// ANALOG_SCALE 1
|
||||
//
|
||||
uint32_t previous = v_prev / JITTER_ALPHA;
|
||||
uint32_t diff = (v > previous) ? (v - previous) : (previous - v);
|
||||
|
||||
// Combine ADC jitter filter setting form radio and model.
|
||||
// Model can override (on or off) or use setting from radio setup.
|
||||
// Model setting is active when 1, radio setting is active when 0
|
||||
// Please note: these settings only apply to main controls.
|
||||
bool useJitterFilter = true;
|
||||
if (is_main_input) {
|
||||
if (g_model.jitterFilter == OVERRIDE_GLOBAL) {
|
||||
// Use radio setting - which is inverted
|
||||
useJitterFilter = !g_eeGeneral.noJitterFilter;
|
||||
} else {
|
||||
// Enable if value is "On", disable if "Off"
|
||||
useJitterFilter = (g_model.jitterFilter == OVERRIDE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t out;
|
||||
if (useJitterFilter && diff < (10 * ANALOG_MULTIPLIER)) {
|
||||
// apply jitter filter
|
||||
out = (v_prev - previous) + v;
|
||||
} else {
|
||||
// use unfiltered value
|
||||
out = v * JITTER_ALPHA;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static uint32_t apply_calibration(const CalibData* calib, uint32_t v)
|
||||
{
|
||||
// Simu uses normed inputs
|
||||
#if !defined(SIMU)
|
||||
// Apply calibration relative to mid-point
|
||||
int32_t s = v - 2 * calib->mid;
|
||||
s = s * (int32_t)RESX /
|
||||
(max((int16_t)100, (s > 0 ? calib->spanPos : calib->spanNeg)));
|
||||
|
||||
// Translate back in range
|
||||
s += 2 * RESX;
|
||||
|
||||
// Limit values to supported range
|
||||
if (s < 0) {
|
||||
s = 0;
|
||||
} else if (s > 4 * RESX) {
|
||||
s = 4 * RESX;
|
||||
}
|
||||
|
||||
v = s;
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint32_t apply_multipos(const StepsCalibData* calib, uint32_t v)
|
||||
{
|
||||
constexpr uint32_t ALPHA_MULT = JITTER_ALPHA * ANALOG_MULTIPLIER;
|
||||
constexpr uint32_t ANAFILT_MAX = 2 * RESX * ALPHA_MULT;
|
||||
|
||||
// TODO: consider adding another low pass filter to eliminate multipos
|
||||
// switching glitches
|
||||
uint8_t vShifted = (v / ALPHA_MULT) >> 4;
|
||||
|
||||
for (uint32_t i = 0; i < calib->count; i++) {
|
||||
if (vShifted < calib->steps[i]) {
|
||||
return (i * (ANAFILT_MAX + ALPHA_MULT)) / calib->count;
|
||||
}
|
||||
}
|
||||
|
||||
return ANAFILT_MAX;
|
||||
}
|
||||
|
||||
void getADC()
|
||||
{
|
||||
uint8_t max_analogs = adcGetMaxInputs(ADC_INPUT_ALL);
|
||||
uint8_t pot_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
auto max_analogs = adcGetMaxInputs(ADC_INPUT_ALL);
|
||||
auto max_mains = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
auto pot_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
auto max_calib_analogs = adcGetMaxCalibratedInputs();
|
||||
|
||||
#if defined(JITTER_MEASURE)
|
||||
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
|
||||
@@ -320,78 +439,39 @@ void getADC()
|
||||
rawJitter[x].reset();
|
||||
avgJitter[x].reset();
|
||||
}
|
||||
jitterResetTime = get_tmr10ms() + 100; //every second
|
||||
jitterResetTime = get_tmr10ms() + 100; // every second
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_TIMER_START(debugTimerAdcRead);
|
||||
if (!adcRead())
|
||||
TRACE("adcRead failed");
|
||||
if (!adcRead()) TRACE("adcRead failed");
|
||||
DEBUG_TIMER_STOP(debugTimerAdcRead);
|
||||
|
||||
// TODO: jitter filter should probably still be applied
|
||||
// to VBAT and RTC_BAT, no matter what is configured
|
||||
//
|
||||
for (uint8_t x = 0; x < max_analogs; x++) {
|
||||
|
||||
uint32_t v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
|
||||
bool is_flex_input = (x >= pot_offset) && (x < pot_offset + max_pots);
|
||||
bool is_multipos = is_flex_input && IS_POT_MULTIPOS(x - pot_offset);
|
||||
|
||||
// Jitter filter:
|
||||
// * pass trough any big change directly
|
||||
// * for small change use Modified moving average (MMA) filter
|
||||
//
|
||||
// Explanation:
|
||||
//
|
||||
// Normal MMA filter has this formula:
|
||||
// <out> = ((ALPHA-1)*<out> + <in>)/ALPHA
|
||||
//
|
||||
// If calculation is done this way with integer arithmetics, then any small change in
|
||||
// input signal is lost. One way to combat that, is to rearrange the formula somewhat,
|
||||
// to store a more precise (larger) number between iterations. The basic idea is to
|
||||
// store undivided value between iterations. Therefore an new variable <filtered> is
|
||||
// used. The new formula becomes:
|
||||
// <filtered> = <filtered> - <filtered>/ALPHA + <in>
|
||||
// <out> = <filtered>/ALPHA (use only when out is needed)
|
||||
//
|
||||
// The above formula with a maximum allowed ALPHA value (we are limited by
|
||||
// the 16 bit s_anaFilt[]) was tested on the radio. The resulting signal still had
|
||||
// some jitter (a value of 1 was observed). The jitter might be bigger on other
|
||||
// radios.
|
||||
//
|
||||
// So another idea is to use larger input values for filtering. So instead of using
|
||||
// input in a range from 0 to 2047, we use twice larger number (temp[x] is divided less)
|
||||
//
|
||||
// This also means that ALPHA must be lowered (remember 16 bit limit), but test results
|
||||
// have proved that this kind of filtering gives better results. So the recommended values
|
||||
// for filter are:
|
||||
// JITTER_FILTER_STRENGTH 4
|
||||
// ANALOG_SCALE 1
|
||||
//
|
||||
// Variables mapping:
|
||||
// * <in> = v
|
||||
// * <out> = s_anaFilt[x]
|
||||
uint32_t previous = s_anaFilt[x] / JITTER_ALPHA;
|
||||
uint32_t diff = (v > previous) ? (v - previous) : (previous - v);
|
||||
// 1st: apply calibration
|
||||
uint32_t v = getAnalogValue(x);
|
||||
|
||||
// Combine ADC jitter filter setting form radio and model.
|
||||
// Model can override (on or off) or use setting from radio setup.
|
||||
// Model setting is active when 1, radio setting is active when 0
|
||||
uint8_t useJitterFilter = 0;
|
||||
if (g_model.jitterFilter == OVERRIDE_GLOBAL) {
|
||||
// Use radio setting - which is inverted
|
||||
useJitterFilter = !g_eeGeneral.noJitterFilter;
|
||||
} else {
|
||||
// Enable if value is "On", disable if "Off"
|
||||
useJitterFilter = (g_model.jitterFilter == OVERRIDE_ON)?1:0;
|
||||
if (x < max_calib_analogs && !is_multipos) {
|
||||
v = apply_calibration(&g_eeGeneral.calib[x], v);
|
||||
}
|
||||
|
||||
if (useJitterFilter && diff < (10*ANALOG_MULTIPLIER)) {
|
||||
// apply jitter filter
|
||||
s_anaFilt[x] = (s_anaFilt[x] - previous) + v;
|
||||
// 2nd: apply inversion
|
||||
if (is_flex_input && getPotInversion(x - pot_offset)) {
|
||||
v = 4 * RESX - v;
|
||||
}
|
||||
else {
|
||||
// use unfiltered value
|
||||
s_anaFilt[x] = v * JITTER_ALPHA;
|
||||
|
||||
// 3rd: apply filtering
|
||||
s_anaFilt[x] = apply_low_pass_filter(v, s_anaFilt[x], x < max_mains);
|
||||
|
||||
if (is_multipos) {
|
||||
const auto* calib = (const StepsCalibData*)&g_eeGeneral.calib[x];
|
||||
if (IS_MULTIPOS_CALIBRATED(calib)) {
|
||||
s_anaFilt[x] = apply_multipos(calib, s_anaFilt[x]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(JITTER_MEASURE)
|
||||
@@ -399,20 +479,6 @@ void getADC()
|
||||
avgJitter[x].measure(ANA_FILT(x));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ANAFILT_MAX (2 * RESX * JITTER_ALPHA * ANALOG_MULTIPLIER)
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[x];
|
||||
if (IS_POT_MULTIPOS(x - pot_offset) && IS_MULTIPOS_CALIBRATED(calib)) {
|
||||
// TODO: consider adding another low pass filter to eliminate multipos switching glitches
|
||||
uint8_t vShifted = ANA_FILT(x) >> 4;
|
||||
s_anaFilt[x] = ANAFILT_MAX;
|
||||
for (uint32_t i = 0; i < calib->count; i++) {
|
||||
if (vShifted < calib->steps[i]) {
|
||||
s_anaFilt[x] = (i * (ANAFILT_MAX + JITTER_ALPHA * ANALOG_MULTIPLIER)) / calib->count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +502,7 @@ uint8_t adcGetInputOffset(uint8_t type)
|
||||
|
||||
uint8_t adcGetMaxCalibratedInputs()
|
||||
{
|
||||
// ADC_INPUT_MAIN + ADC_INPUT_POT + ADC_INPUT_AXIS
|
||||
// ADC_INPUT_MAIN + ADC_INPUT_FLEX + ADC_INPUT_AXIS
|
||||
return adcGetInputOffset(ADC_INPUT_VBAT);
|
||||
}
|
||||
|
||||
@@ -467,7 +533,7 @@ const char* adcGetInputName(uint8_t idx)
|
||||
|
||||
// find the proper input type
|
||||
while (_hal_adc_inputs[type].offset + _hal_adc_inputs[type].n_inputs <= idx) {
|
||||
if (++type > ADC_INPUT_AXIS) return nullptr;
|
||||
if (++type > ADC_INPUT_FLEX) return nullptr;
|
||||
}
|
||||
|
||||
idx -= _hal_adc_inputs[type].offset;
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
|
||||
enum {
|
||||
ADC_INPUT_MAIN=0, // gimbals / wheel + throttle
|
||||
ADC_INPUT_POT,
|
||||
ADC_INPUT_AXIS,
|
||||
ADC_INPUT_FLEX,
|
||||
ADC_INPUT_VBAT,
|
||||
ADC_INPUT_RTC_BAT,
|
||||
ADC_INPUT_ALL,
|
||||
@@ -92,6 +91,9 @@ uint16_t* getAnalogValues();
|
||||
|
||||
// Run calibration steps:
|
||||
|
||||
// Set default values before loading radio settings
|
||||
void adcCalibDefaults();
|
||||
|
||||
// Set mid-points and reset min/max in temporary buffer
|
||||
void adcCalibSetMidPoint();
|
||||
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* 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 "switch_driver.h"
|
||||
|
||||
#include "definitions.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#include "dataconstants.h"
|
||||
#include "opentx_helpers.h"
|
||||
#include "opentx.h"
|
||||
|
||||
// Board API
|
||||
void boardInitSwitches();
|
||||
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx);
|
||||
|
||||
const char* boardSwitchGetName(uint8_t cat, uint8_t idx);
|
||||
SwitchHwType boardSwitchGetType(uint8_t cat, uint8_t idx);
|
||||
|
||||
uint8_t boardGetMaxSwitches();
|
||||
uint8_t boardGetMaxFctSwitches();
|
||||
|
||||
swconfig_t boardSwitchGetDefaultConfig();
|
||||
|
||||
constexpr uint8_t _INVALID_ADC_CH = 0xFF;
|
||||
|
||||
static uint8_t _flex_switches[MAX_FLEX_SWITCHES];
|
||||
|
||||
void switchInit()
|
||||
{
|
||||
memset(_flex_switches, _INVALID_ADC_CH, sizeof(_flex_switches));
|
||||
boardInitSwitches();
|
||||
}
|
||||
|
||||
swconfig_t switchGetDefaultConfig() { return boardSwitchGetDefaultConfig(); }
|
||||
|
||||
uint8_t switchGetMaxSwitches()
|
||||
{
|
||||
return boardGetMaxSwitches() + MAX_FLEX_SWITCHES;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxFctSwitches() { return boardGetMaxFctSwitches(); }
|
||||
|
||||
uint32_t switchState(uint8_t pos_idx)
|
||||
{
|
||||
auto d = div(pos_idx, 3);
|
||||
auto idx = (uint8_t)d.quot;
|
||||
auto pos = (SwitchHwPos)d.rem;
|
||||
|
||||
return switchGetPosition(idx) == pos;
|
||||
}
|
||||
|
||||
SwitchHwPos switchGetPosition(uint8_t sw_idx)
|
||||
{
|
||||
auto idx = (int)sw_idx;
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) {
|
||||
return boardSwitchGetPosition(SWITCH_PHYSICAL, idx);
|
||||
}
|
||||
|
||||
idx -= max_switches;
|
||||
if (MAX_FLEX_SWITCHES > 0) {
|
||||
if (idx < MAX_FLEX_SWITCHES) {
|
||||
auto channel = _flex_switches[idx];
|
||||
SwitchHwPos ret = SWITCH_HW_UP;
|
||||
|
||||
if (channel != _INVALID_ADC_CH) {
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
uint16_t value = anaIn(channel + offset);
|
||||
if (value > 3 * 512) {
|
||||
ret = SWITCH_HW_DOWN;
|
||||
} else if (value >= 512) {
|
||||
ret = SWITCH_HW_MID;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
idx -= MAX_FLEX_SWITCHES;
|
||||
}
|
||||
|
||||
if (idx < boardGetMaxFctSwitches()) {
|
||||
return boardSwitchGetPosition(SWITCH_FUNCTION, idx);
|
||||
}
|
||||
|
||||
return SWITCH_HW_UP;
|
||||
}
|
||||
|
||||
static const char * const _flex_sw_canon_names[] = {
|
||||
"FL1", "FL2", "FL3", "FL4"
|
||||
};
|
||||
|
||||
static_assert(DIM(_flex_sw_canon_names) >= MAX_FLEX_SWITCHES,
|
||||
"Missing canonical name for flex switches");
|
||||
|
||||
const char* switchGetName(uint8_t sw_idx)
|
||||
{
|
||||
auto idx = (int)sw_idx;
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) {
|
||||
return boardSwitchGetName(SWITCH_PHYSICAL, idx);
|
||||
}
|
||||
|
||||
idx -= max_switches;
|
||||
if (MAX_FLEX_SWITCHES > 0) {
|
||||
if (idx < MAX_FLEX_SWITCHES) {
|
||||
return _flex_sw_canon_names[idx];
|
||||
}
|
||||
|
||||
idx -= MAX_FLEX_SWITCHES;
|
||||
}
|
||||
|
||||
if (idx < boardGetMaxFctSwitches()) {
|
||||
return boardSwitchGetName(SWITCH_FUNCTION, idx);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SwitchHwType switchGetHwType(uint8_t sw_idx)
|
||||
{
|
||||
auto idx = (int)sw_idx;
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) {
|
||||
return boardSwitchGetType(SWITCH_PHYSICAL, idx);
|
||||
}
|
||||
|
||||
idx -= max_switches;
|
||||
if (idx < MAX_FLEX_SWITCHES) {
|
||||
return SWITCH_HW_3POS;
|
||||
}
|
||||
|
||||
return SWITCH_HW_2POS;
|
||||
}
|
||||
|
||||
bool switchIsFlex(uint8_t idx)
|
||||
{
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
return idx >= max_switches && idx < max_switches + MAX_FLEX_SWITCHES;
|
||||
}
|
||||
|
||||
void switchConfigFlex_raw(uint8_t idx, int8_t channel)
|
||||
{
|
||||
if (!MAX_FLEX_SWITCHES || idx > MAX_FLEX_SWITCHES) return;
|
||||
if ((int)channel >= (int)adcGetMaxInputs(ADC_INPUT_FLEX)) return;
|
||||
|
||||
auto& sw_channel = _flex_switches[idx];
|
||||
if (channel < 0) {
|
||||
sw_channel = _INVALID_ADC_CH;
|
||||
} else if (POT_CONFIG((uint8_t)channel) == FLEX_SWITCH) {
|
||||
sw_channel = (uint8_t)channel;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t switchGetFlexChannel(uint8_t idx)
|
||||
{
|
||||
return _flex_switches[idx];
|
||||
}
|
||||
|
||||
void switchConfigFlex(uint8_t idx, int8_t channel)
|
||||
{
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) return;
|
||||
idx -= max_switches;
|
||||
switchConfigFlex_raw(idx, channel);
|
||||
}
|
||||
|
||||
int8_t switchGetFlexConfig_raw(uint8_t idx)
|
||||
{
|
||||
if (!MAX_FLEX_SWITCHES || idx > MAX_FLEX_SWITCHES) return _INVALID_ADC_CH;
|
||||
return (int8_t)_flex_switches[idx];
|
||||
}
|
||||
|
||||
int8_t switchGetFlexConfig(uint8_t idx)
|
||||
{
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) return _INVALID_ADC_CH;
|
||||
idx -= max_switches;
|
||||
return switchGetFlexConfig_raw(idx);
|
||||
}
|
||||
|
||||
bool switchIsFlexValid_raw(uint8_t sw_idx)
|
||||
{
|
||||
auto idx = (int)sw_idx;
|
||||
return MAX_FLEX_SWITCHES > 0 && idx < MAX_FLEX_SWITCHES &&
|
||||
_flex_switches[idx] != _INVALID_ADC_CH;
|
||||
}
|
||||
|
||||
bool switchIsFlexValid(uint8_t idx)
|
||||
{
|
||||
auto max_switches = boardGetMaxSwitches();
|
||||
if (idx < max_switches) return false;
|
||||
idx -= max_switches;
|
||||
return switchIsFlexValid_raw(idx);
|
||||
}
|
||||
|
||||
static bool is_flex_input_available(uint8_t flex_idx, uint8_t channel)
|
||||
{
|
||||
for (int i = 0; i < MAX_FLEX_SWITCHES; i++) {
|
||||
if (_flex_switches[i] == channel && (int)flex_idx != i)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool switchIsFlexInputAvailable(uint8_t idx, uint8_t channel)
|
||||
{
|
||||
if (MAX_FLEX_SWITCHES == 0) return false;
|
||||
if (POT_CONFIG(channel) != FLEX_SWITCH) return false;
|
||||
|
||||
auto phy_switches = boardGetMaxSwitches();
|
||||
if (idx < phy_switches) return false;
|
||||
|
||||
return is_flex_input_available(idx - phy_switches, channel);
|
||||
}
|
||||
|
||||
static void invalidate_flex_config(uint8_t flex_idx)
|
||||
{
|
||||
auto sw_idx = flex_idx + boardGetMaxSwitches();
|
||||
swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(sw_idx);
|
||||
g_eeGeneral.switchConfig &= ~mask;
|
||||
|
||||
_flex_switches[flex_idx] = _INVALID_ADC_CH;
|
||||
}
|
||||
|
||||
void switchFixFlexConfig()
|
||||
{
|
||||
for (int i = 0; i < MAX_FLEX_SWITCHES; i++) {
|
||||
auto channel = _flex_switches[i];
|
||||
if (channel != _INVALID_ADC_CH && POT_CONFIG(channel) != FLEX_SWITCH) {
|
||||
invalidate_flex_config(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,11 @@ enum SwitchHwPos {
|
||||
SWITCH_HW_DOWN,
|
||||
};
|
||||
|
||||
enum SwitchCategory {
|
||||
SWITCH_PHYSICAL=0,
|
||||
SWITCH_FUNCTION,
|
||||
};
|
||||
|
||||
#define SWITCH_HW_INVERTED 1
|
||||
|
||||
// init hardware for switches
|
||||
@@ -44,7 +49,7 @@ void switchInit();
|
||||
// returns the factory configuration for all switches
|
||||
swconfig_t switchGetDefaultConfig();
|
||||
|
||||
// returns the maximum number of regular switches supported in hardware
|
||||
// returns the maximum number of regular switches supported in hardware (customizable switches NOT included)
|
||||
uint8_t switchGetMaxSwitches();
|
||||
|
||||
// returns the number of configured switches
|
||||
@@ -63,6 +68,21 @@ struct switch_display_pos_t {
|
||||
|
||||
switch_display_pos_t switchGetDisplayPosition(uint8_t idx);
|
||||
|
||||
// Configure Flex switch (using unified switch index)
|
||||
void switchConfigFlex(uint8_t idx, int8_t channel);
|
||||
int8_t switchGetFlexConfig(uint8_t idx);
|
||||
|
||||
bool switchIsFlex(uint8_t idx);
|
||||
bool switchIsFlexValid(uint8_t idx);
|
||||
bool switchIsFlexInputAvailable(uint8_t idx, uint8_t channel);
|
||||
|
||||
void switchFixFlexConfig();
|
||||
|
||||
// "Raw" variants indexing only flex switches (used for storage)
|
||||
void switchConfigFlex_raw(uint8_t idx, int8_t channel);
|
||||
int8_t switchGetFlexConfig_raw(uint8_t idx);
|
||||
bool switchIsFlexValid_raw(uint8_t idx);
|
||||
|
||||
// The functions bellow support regular as well as customizable switches.
|
||||
//
|
||||
// Regular switches are indexed from `0` to `switchGetMaxSwitches() - 1`
|
||||
|
||||
+4
-4
@@ -227,10 +227,10 @@ void writeHeader()
|
||||
f_putc(',', &g_oLogFile);
|
||||
}
|
||||
|
||||
n_inputs = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
n_inputs = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
for (uint8_t i = 0; i < n_inputs; i++) {
|
||||
if (!IS_POT_AVAILABLE(i)) continue;
|
||||
const char* p = analogGetCanonicalName(ADC_INPUT_POT, i);
|
||||
const char* p = analogGetCanonicalName(ADC_INPUT_FLEX, i);
|
||||
while (*p) { f_putc(*(p++), &g_oLogFile); }
|
||||
f_putc(',', &g_oLogFile);
|
||||
}
|
||||
@@ -367,8 +367,8 @@ void logsWrite()
|
||||
f_printf(&g_oLogFile, "%d,", calibratedAnalogs[inputMappingConvertMode(offset + i)]);
|
||||
}
|
||||
|
||||
n_inputs = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
n_inputs = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < n_inputs; i++) {
|
||||
if (IS_POT_AVAILABLE(i))
|
||||
|
||||
@@ -466,6 +466,7 @@ bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags)
|
||||
return true;
|
||||
|
||||
// check switches from 'sa' to 'sz'
|
||||
// TODO: does not work with function switches!
|
||||
if (len == 2 && name[0] == 's' && name[1] >= 'a' && name[1] <= 'z') {
|
||||
auto c = name[1] - 'a' + 'A';
|
||||
auto sw_idx = switchLookupIdx(c);
|
||||
|
||||
+35
-51
@@ -296,6 +296,18 @@ int16_t applyLimits(uint8_t channel, int32_t value)
|
||||
return ofs;
|
||||
}
|
||||
|
||||
static const getvalue_t _switch_2pos_lookup[] = {
|
||||
-1024, // SWITCH_HW_UP
|
||||
+1024, // SWITCH_HW_MID
|
||||
+1024, // SWITCH_HW_DOWN
|
||||
};
|
||||
|
||||
static const getvalue_t _switch_3pos_lookup[] = {
|
||||
-1024, // SWITCH_HW_UP
|
||||
0, // SWITCH_HW_MID
|
||||
+1024, // SWITCH_HW_DOWN
|
||||
};
|
||||
|
||||
// TODO same naming convention than the drawSource
|
||||
// *valid added to return status to Lua for invalid sources
|
||||
getvalue_t getValue(mixsrc_t i, bool* valid)
|
||||
@@ -329,24 +341,13 @@ getvalue_t getValue(mixsrc_t i, bool* valid)
|
||||
}
|
||||
else if (i <= MIXSRC_LAST_POT) {
|
||||
i -= MIXSRC_FIRST_POT;
|
||||
if (i >= adcGetMaxInputs(ADC_INPUT_POT)) {
|
||||
if (i >= adcGetMaxInputs(ADC_INPUT_FLEX)) {
|
||||
if (valid != nullptr) *valid = false;
|
||||
return 0;
|
||||
}
|
||||
return calibratedAnalogs[i + adcGetInputOffset(ADC_INPUT_POT)];
|
||||
return calibratedAnalogs[i + adcGetInputOffset(ADC_INPUT_FLEX)];
|
||||
}
|
||||
|
||||
#if MAX_AXIS > 0
|
||||
else if (i <= MIXSRC_LAST_AXIS) {
|
||||
i -= MIXSRC_FIRST_AXIS;
|
||||
if (i >= adcGetMaxInputs(ADC_INPUT_AXIS)) {
|
||||
if (valid != nullptr) *valid = false;
|
||||
return 0;
|
||||
}
|
||||
return calibratedAnalogs[i + adcGetInputOffset(ADC_INPUT_AXIS)];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(IMU)
|
||||
else if (i == MIXSRC_TILT_X) {
|
||||
return gyro.scaledX();
|
||||
@@ -383,31 +384,30 @@ getvalue_t getValue(mixsrc_t i, bool* valid)
|
||||
auto trim_value = getTrimValue(mixerCurrentFlightMode, i);
|
||||
return calc1000toRESX((int16_t)8 * trim_value);
|
||||
}
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_REGULAR_SWITCH) {
|
||||
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
|
||||
if (SWITCH_EXISTS(sw)) {
|
||||
return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024));
|
||||
}
|
||||
else {
|
||||
if (valid != nullptr) *valid = false;
|
||||
return 0;
|
||||
}
|
||||
} else if (i >= MIXSRC_FIRST_FS_SWITCH && i <= MIXSRC_LAST_SWITCH) {
|
||||
return getFSLogicalState(i - MIXSRC_FIRST_SWITCH - switchGetMaxSwitches()) ? +1024 : -1024;
|
||||
}
|
||||
#else
|
||||
else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_SWITCH) {
|
||||
mixsrc_t sw = i - MIXSRC_FIRST_SWITCH;
|
||||
if (SWITCH_EXISTS(sw)) {
|
||||
return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024));
|
||||
auto sw_idx = (uint8_t)(i - MIXSRC_FIRST_SWITCH);
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
auto max_reg_switches = switchGetMaxSwitches();
|
||||
if (sw_idx >= max_reg_switches) {
|
||||
auto fct_idx = sw_idx - max_reg_switches;
|
||||
auto max_fct_switches = switchGetMaxFctSwitches();
|
||||
if (fct_idx < max_fct_switches) {
|
||||
return _switch_2pos_lookup[getFSLogicalState(fct_idx)];
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
auto sw_cfg = (SwitchConfig)SWITCH_CONFIG(sw_idx);
|
||||
switch(sw_cfg) {
|
||||
case SWITCH_NONE:
|
||||
if (valid != nullptr) *valid = false;
|
||||
return 0;
|
||||
case SWITCH_TOGGLE:
|
||||
case SWITCH_2POS:
|
||||
return _switch_2pos_lookup[switchGetPosition(sw_idx)];
|
||||
case SWITCH_3POS:
|
||||
return _switch_3pos_lookup[switchGetPosition(sw_idx)];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (i <= MIXSRC_LAST_LOGICAL_SWITCH) {
|
||||
return getSwitch(SWSRC_FIRST_LOGICAL_SWITCH + i - MIXSRC_FIRST_LOGICAL_SWITCH) ? 1024 : -1024;
|
||||
@@ -503,30 +503,14 @@ void evalInputs(uint8_t mode)
|
||||
#endif
|
||||
|
||||
auto max_calib_analogs = adcGetInputOffset(ADC_INPUT_VBAT);
|
||||
auto pots_offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
auto pots_offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (uint8_t i = 0; i < max_calib_analogs; i++) {
|
||||
// normalization [0..2048] -> [-1024..1024]
|
||||
int16_t v = anaIn(i);
|
||||
uint8_t ch = (i < pots_offset ? inputMappingConvertMode(i) : i);
|
||||
|
||||
if (i >= pots_offset && IS_POT_MULTIPOS(i - pots_offset)) {
|
||||
v -= RESX;
|
||||
}
|
||||
else {
|
||||
#if defined(SIMU)
|
||||
// Simu uses normed inputs
|
||||
v -= RESX;
|
||||
#else
|
||||
CalibData * calib = &g_eeGeneral.calib[i];
|
||||
v -= calib->mid;
|
||||
v = v * (int32_t) RESX / (max((int16_t) 100, (v > 0 ? calib->spanPos : calib->spanNeg)));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Limit values to supported range
|
||||
if (v < -RESX) v = -RESX;
|
||||
if (v > RESX) v = RESX;
|
||||
// [0..2048] -> [-1024..1024]
|
||||
v -= RESX;
|
||||
|
||||
#if defined(STICK_DEAD_ZONE)
|
||||
// dead zone invented by FlySky in my opinion it should goes into ADC
|
||||
|
||||
@@ -86,7 +86,9 @@
|
||||
#define MODEL_GVAR_MAX(idx) (CFN_GVAR_CST_MAX - g_model.gvars[idx].max)
|
||||
|
||||
// pots config
|
||||
#define POT_CFG_BITS 4 // 4 bits per pot
|
||||
#define POT_CFG_TYPE_BITS 3
|
||||
#define POT_CFG_INV_BITS 1
|
||||
#define POT_CFG_BITS (POT_CFG_TYPE_BITS + POT_CFG_INV_BITS)
|
||||
#define POT_CFG_MASK ((1 << POT_CFG_BITS) - 1)
|
||||
#define POT_CONFIG_POS(x) (POT_CFG_BITS * (x))
|
||||
#define POT_CONFIG_MASK(x) (POT_CFG_MASK << POT_CONFIG_POS(x))
|
||||
|
||||
+10
-10
@@ -277,6 +277,8 @@ void generalDefault()
|
||||
g_eeGeneral.internalModule = DEFAULT_INTERNAL_MODULE;
|
||||
#endif
|
||||
|
||||
adcCalibDefaults();
|
||||
|
||||
g_eeGeneral.potsConfig = adcGetDefaultPotsConfig();
|
||||
g_eeGeneral.switchConfig = switchGetDefaultConfig();
|
||||
|
||||
@@ -359,9 +361,12 @@ void generalDefault()
|
||||
uint16_t evalChkSum()
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
const int16_t * calibValues = (const int16_t *) &g_eeGeneral.calib[0];
|
||||
for (int i=0; i<12; i++)
|
||||
auto main_calib_bytes = adcGetMaxInputs(ADC_INPUT_MAIN) * sizeof(CalibData);
|
||||
|
||||
const uint8_t *calibValues = (const uint8_t *)&g_eeGeneral.calib[0];
|
||||
for (unsigned i = 0; i < main_calib_bytes; i++) {
|
||||
sum += calibValues[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@@ -403,18 +408,11 @@ int8_t getMovedSource(uint8_t min)
|
||||
if (result == 0) {
|
||||
for (uint8_t i = 0; i < MAX_ANALOG_INPUTS; i++) {
|
||||
if (abs(calibratedAnalogs[i] - sourcesStates[i]) > MULTIPOS_STEP_SIZE) {
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
if (i >= offset) {
|
||||
result = MIXSRC_FIRST_POT + i - offset;
|
||||
break;
|
||||
}
|
||||
#if MAX_AXIS > 0
|
||||
offset = adcGetInputOffset(ADC_INPUT_AXIS);
|
||||
if (i >= offset) {
|
||||
result = MIXSRC_FIRST_AXIS + i - offset;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
result = MIXSRC_FIRST_STICK + inputMappingConvertMode(i);
|
||||
break;
|
||||
}
|
||||
@@ -1402,6 +1400,8 @@ void opentxInit()
|
||||
menuHandlers[1] = menuModelSelect;
|
||||
#endif
|
||||
|
||||
switchInit();
|
||||
|
||||
#if defined(STARTUP_ANIMATION)
|
||||
lcdRefreshWait();
|
||||
lcdClear();
|
||||
|
||||
+14
-8
@@ -256,15 +256,21 @@ enum RotaryEncoderMode {
|
||||
void memswap(void * a, void * b, uint8_t size);
|
||||
|
||||
// TODO: move these config check macros somewhere else
|
||||
#define POT_CONFIG(x) \
|
||||
((g_eeGeneral.potsConfig >> POT_CONFIG_POS(x)) & POT_CFG_MASK)
|
||||
#define POT_CONFIG(x) (getPotType(x))
|
||||
|
||||
#define IS_POT_MULTIPOS(x) (POT_CONFIG(x) == POT_MULTIPOS_SWITCH)
|
||||
#define IS_POT_WITHOUT_DETENT(x) (POT_CONFIG(x) == POT_WITHOUT_DETENT)
|
||||
#define IS_SLIDER(x) (POT_CONFIG(x) == POT_SLIDER_WITH_DETENT)
|
||||
#define IS_POT_AVAILABLE(x) (POT_CONFIG(x) != POT_NONE)
|
||||
#define IS_POT_SLIDER_AVAILABLE(x) (IS_POT_AVAILABLE(x))
|
||||
#define IS_MULTIPOS_CALIBRATED(cal) (cal->count > 0 && cal->count < XPOTS_MULTIPOS_COUNT)
|
||||
#define IS_POT_MULTIPOS(x) (POT_CONFIG(x) == FLEX_MULTIPOS)
|
||||
|
||||
#define IS_POT_WITHOUT_DETENT(x) (POT_CONFIG(x) == FLEX_POT)
|
||||
|
||||
#define IS_SLIDER(x) (POT_CONFIG(x) == FLEX_SLIDER)
|
||||
|
||||
#define IS_POT_AVAILABLE(x) \
|
||||
(POT_CONFIG(x) != FLEX_NONE && POT_CONFIG(x) <= FLEX_MULTIPOS)
|
||||
|
||||
#define IS_POT_SLIDER_AVAILABLE(x) (IS_POT_AVAILABLE(x))
|
||||
|
||||
#define IS_MULTIPOS_CALIBRATED(cal) \
|
||||
(cal->count > 0 && cal->count < XPOTS_MULTIPOS_COUNT)
|
||||
|
||||
#define IS_SWITCH_MULTIPOS(x) \
|
||||
(SWSRC_FIRST_MULTIPOS_SWITCH <= (x) && (x) <= SWSRC_LAST_MULTIPOS_SWITCH)
|
||||
|
||||
@@ -29,12 +29,15 @@ enum SwitchConfig {
|
||||
SWITCH_3POS,
|
||||
};
|
||||
|
||||
enum PotConfig {
|
||||
POT_NONE=0,
|
||||
POT_WITH_DETENT,
|
||||
POT_MULTIPOS_SWITCH,
|
||||
POT_WITHOUT_DETENT,
|
||||
POT_SLIDER_WITH_DETENT,
|
||||
enum FlexAnalogConfig {
|
||||
FLEX_NONE=0,
|
||||
FLEX_POT, // without detent
|
||||
FLEX_POT_CENTER, // with detent
|
||||
FLEX_SLIDER,
|
||||
FLEX_MULTIPOS,
|
||||
FLEX_AXIS_X,
|
||||
FLEX_AXIS_Y,
|
||||
FLEX_SWITCH,
|
||||
};
|
||||
|
||||
enum fsStartPositionType {
|
||||
|
||||
+2
-7
@@ -134,7 +134,7 @@ OpenTxSim::OpenTxSim(FXApp* a):
|
||||
sliders[i]->setValue(2047);
|
||||
}
|
||||
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
memset(knobs, 0, sizeof(knobs));
|
||||
|
||||
for (int i = 0; i < max_pots; i++) {
|
||||
@@ -673,15 +673,10 @@ uint16_t simu_get_analog(uint8_t idx)
|
||||
|
||||
idx -= max_sticks;
|
||||
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
if (idx < max_pots)
|
||||
return opentxSim->knobs[idx]->getValue();
|
||||
|
||||
idx -= max_pots;
|
||||
|
||||
auto max_axes = adcGetMaxInputs(ADC_INPUT_AXIS);
|
||||
if (idx < max_axes) return 0;
|
||||
|
||||
// probably RTC_BAT
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "myeeprom.h"
|
||||
#include "opentx.h"
|
||||
#include "opentx_helpers.h"
|
||||
#include "storage.h"
|
||||
@@ -185,6 +187,8 @@ const char * loadRadioSettings()
|
||||
g_eeGeneral.internalModule = DEFAULT_INTERNAL_MODULE;
|
||||
#endif
|
||||
|
||||
adcCalibDefaults();
|
||||
|
||||
const char* error = loadRadioSettingsYaml(true);
|
||||
if (!error) {
|
||||
g_eeGeneral.chkSum = evalChkSum();
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "opentx_constants.h"
|
||||
#include "yaml_bits.h"
|
||||
#include "yaml_node.h"
|
||||
#include "yaml_tree_walker.h"
|
||||
|
||||
#include "pulses/multi.h"
|
||||
@@ -254,14 +256,9 @@ static uint32_t r_mixSrcRaw(const YamlNode* node, const char* val, uint8_t val_l
|
||||
auto idx = analogLookupCanonicalIdx(ADC_INPUT_MAIN, val, val_len);
|
||||
if (idx >= 0) return idx + MIXSRC_FIRST_STICK;
|
||||
|
||||
idx = analogLookupCanonicalIdx(ADC_INPUT_POT, val, val_len);
|
||||
idx = analogLookupCanonicalIdx(ADC_INPUT_FLEX, val, val_len);
|
||||
if (idx >= 0) return idx + MIXSRC_FIRST_POT;
|
||||
|
||||
#if MAX_AXIS > 0
|
||||
idx = analogLookupCanonicalIdx(ADC_INPUT_AXIS, val, val_len);
|
||||
if (idx >= 0) return idx + MIXSRC_FIRST_POT;
|
||||
#endif
|
||||
|
||||
idx = switchLookupIdx(val, val_len);
|
||||
if (idx >= 0) return idx + MIXSRC_FIRST_SWITCH;
|
||||
|
||||
@@ -318,13 +315,8 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf,
|
||||
str = analogGetCanonicalName(ADC_INPUT_MAIN, val - MIXSRC_FIRST_STICK);
|
||||
}
|
||||
else if (val <= MIXSRC_LAST_POT) {
|
||||
str = analogGetCanonicalName(ADC_INPUT_POT, val - MIXSRC_FIRST_POT);
|
||||
str = analogGetCanonicalName(ADC_INPUT_FLEX, val - MIXSRC_FIRST_POT);
|
||||
}
|
||||
#if MAX_AXIS > 0
|
||||
else if (val <= MIXSRC_LAST_AXIS) {
|
||||
str = analogGetCanonicalName(ADC_INPUT_AXIS, val - MIXSRC_FIRST_AXIS);
|
||||
}
|
||||
#endif
|
||||
else if (val >= MIXSRC_FIRST_HELI
|
||||
&& val <= MIXSRC_LAST_HELI) {
|
||||
if (!wf(opaque, "CYC", 3)) return false;
|
||||
@@ -682,8 +674,8 @@ static uint32_t slider_read(void* user, const char* val, uint8_t val_len)
|
||||
}
|
||||
|
||||
static const struct YamlIdStr enum_SliderConfig[] = {
|
||||
{ POT_NONE, "none" },
|
||||
{ POT_SLIDER_WITH_DETENT, "with_detent" },
|
||||
{ FLEX_NONE, "none" },
|
||||
{ FLEX_SLIDER, "with_detent" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -704,7 +696,7 @@ static void sl_type_read(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
static void sl_name_read(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
_read_analog_name(ADC_INPUT_POT, user, data, bitoffs, val, val_len);
|
||||
_read_analog_name(ADC_INPUT_FLEX, user, data, bitoffs, val, val_len);
|
||||
}
|
||||
|
||||
static const struct YamlNode struct_sliderConfig[] = {
|
||||
@@ -768,10 +760,63 @@ static const struct YamlNode struct_switchConfig[] = {
|
||||
YAML_END
|
||||
};
|
||||
|
||||
static bool flex_sw_valid(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
uint16_t idx = tw->getElmts();
|
||||
return switchIsFlexValid_raw(idx);
|
||||
}
|
||||
|
||||
uint8_t boardGetMaxSwitches();
|
||||
|
||||
static uint32_t flex_sw_read(void* user, const char* val, uint8_t val_len)
|
||||
{
|
||||
(void)user;
|
||||
auto idx = switchLookupIdx(val, val_len);
|
||||
return idx - boardGetMaxSwitches();
|
||||
}
|
||||
|
||||
bool flex_sw_write(void* user, yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
uint16_t idx = tw->getElmts();
|
||||
|
||||
auto sw_offset = boardGetMaxSwitches();
|
||||
const char* str = switchGetCanonicalName(idx + sw_offset);
|
||||
return str ? wf(opaque, str, strlen(str)) : true;
|
||||
}
|
||||
|
||||
static void r_flex_sw_channel(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
uint16_t idx = tw->getElmts(1);
|
||||
|
||||
auto channel = analogLookupPhysicalIdx(ADC_INPUT_FLEX, val, val_len);
|
||||
switchConfigFlex_raw(idx, channel);
|
||||
}
|
||||
|
||||
static bool w_flex_sw_channel(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
uint16_t idx = tw->getElmts(1);
|
||||
|
||||
auto channel = switchGetFlexConfig_raw(idx);
|
||||
const char* s = analogGetPhysicalName(ADC_INPUT_FLEX, channel);
|
||||
return s ? wf(opaque, s, strlen(s)) : true;
|
||||
}
|
||||
|
||||
static const struct YamlNode struct_flexSwitch[] = {
|
||||
YAML_IDX_CUST( "sw", flex_sw_read, flex_sw_write),
|
||||
YAML_CUSTOM( "channel", r_flex_sw_channel, w_flex_sw_channel),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
static uint32_t pot_read(void* user, const char* val, uint8_t val_len)
|
||||
{
|
||||
(void)user;
|
||||
auto idx = analogLookupPhysicalIdx(ADC_INPUT_POT, val, val_len);
|
||||
auto idx = analogLookupPhysicalIdx(ADC_INPUT_FLEX, val, val_len);
|
||||
if (idx >= 0) return idx;
|
||||
|
||||
idx = _legacy_mix_src(val, val_len);
|
||||
@@ -786,35 +831,39 @@ static bool pot_write(void* user, yaml_writer_func wf, void* opaque)
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
uint16_t idx = tw->getElmts();
|
||||
|
||||
const char* str = analogGetPhysicalName(ADC_INPUT_POT, idx);
|
||||
const char* str = analogGetPhysicalName(ADC_INPUT_FLEX, idx);
|
||||
return str ? wf(opaque, str, strlen(str)) : true;
|
||||
}
|
||||
|
||||
static void pot_name_read(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
_read_analog_name(ADC_INPUT_POT, user, data, bitoffs, val, val_len);
|
||||
_read_analog_name(ADC_INPUT_FLEX, user, data, bitoffs, val, val_len);
|
||||
}
|
||||
|
||||
static bool pot_name_write(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
return _write_analog_name(ADC_INPUT_POT, user, data, bitoffs, wf, opaque);
|
||||
return _write_analog_name(ADC_INPUT_FLEX, user, data, bitoffs, wf, opaque);
|
||||
}
|
||||
|
||||
static const struct YamlIdStr enum_PotConfig[] = {
|
||||
{ POT_NONE, "none" },
|
||||
{ POT_WITH_DETENT, "with_detent" },
|
||||
{ POT_MULTIPOS_SWITCH, "multipos_switch" },
|
||||
{ POT_WITHOUT_DETENT, "without_detent" },
|
||||
{ POT_SLIDER_WITH_DETENT, "slider" },
|
||||
{ FLEX_NONE, "none" },
|
||||
{ FLEX_POT, "without_detent" },
|
||||
{ FLEX_POT_CENTER, "with_detent" },
|
||||
{ FLEX_SLIDER, "slider" },
|
||||
{ FLEX_MULTIPOS, "multipos_switch" },
|
||||
{ FLEX_AXIS_X, "axis_x" },
|
||||
{ FLEX_AXIS_Y, "axis_y" },
|
||||
{ FLEX_SWITCH, "switch" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct YamlNode struct_potConfig[] = {
|
||||
YAML_IDX_CUST( "pot", pot_read, pot_write ),
|
||||
YAML_ENUM( "type", POT_CFG_BITS, enum_PotConfig),
|
||||
YAML_CUSTOM( "name", pot_name_read, pot_name_write),
|
||||
YAML_IDX_CUST("pot", pot_read, pot_write ),
|
||||
YAML_ENUM("type", POT_CFG_TYPE_BITS, enum_PotConfig),
|
||||
YAML_UNSIGNED("inv", POT_CFG_INV_BITS),
|
||||
YAML_CUSTOM("name", pot_name_read, pot_name_write),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -840,7 +889,9 @@ static uint32_t r_swtchSrc(const YamlNode* node, const char* val, uint8_t val_le
|
||||
val_len--;
|
||||
}
|
||||
|
||||
if (val_len > 3 && val[0] == 'S' && val[1] >= 'W'
|
||||
if (val_len > 3
|
||||
&& ((val[0] == 'S' && val[1] >= 'W')
|
||||
|| (val[0] == 'F' && val[1] >= 'L'))
|
||||
&& val[2] >= '0' && val[2] <= '9'
|
||||
&& val[3] >= '0' && val[3] <= '2') {
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "ppmunit", 2 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_SIGNED( "currModel", 8 ),
|
||||
YAML_UNSIGNED( "contrast", 8 ),
|
||||
@@ -364,6 +364,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_STRING("currModelFilename", 17),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
|
||||
@@ -301,7 +301,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "ppmunit", 2 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_UNSIGNED( "vBatWarn", 8 ),
|
||||
YAML_SIGNED( "txVoltageCalibration", 8 ),
|
||||
@@ -370,6 +370,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_STRING("currModelFilename", 17),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
|
||||
@@ -301,7 +301,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "ppmunit", 2 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_UNSIGNED( "vBatWarn", 8 ),
|
||||
YAML_SIGNED( "txVoltageCalibration", 8 ),
|
||||
@@ -370,6 +370,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_STRING("currModelFilename", 17),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
|
||||
@@ -353,6 +353,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
|
||||
@@ -355,6 +355,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_UNSIGNED( "backlightColor", 8 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
|
||||
@@ -538,7 +538,7 @@ const char* getAnalogLabel(uint8_t type, uint8_t idx)
|
||||
return adcGetInputShortLabel(type, idx);
|
||||
}
|
||||
|
||||
if (type == ADC_INPUT_POT) {
|
||||
if (type == ADC_INPUT_FLEX) {
|
||||
return adcGetInputLabel(type, idx);
|
||||
}
|
||||
|
||||
@@ -562,10 +562,10 @@ const char* getAnalogShortLabel(uint8_t idx)
|
||||
}
|
||||
|
||||
idx -= max;
|
||||
max = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
max = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
|
||||
if (idx < max) {
|
||||
return adcGetInputShortLabel(ADC_INPUT_POT, idx);
|
||||
return adcGetInputShortLabel(ADC_INPUT_FLEX, idx);
|
||||
}
|
||||
|
||||
// we only support short labels
|
||||
@@ -604,7 +604,7 @@ const char* getTrimSourceLabel(uint16_t src_raw, int8_t trim_src)
|
||||
|
||||
const char* getPotLabel(uint8_t idx)
|
||||
{
|
||||
return getAnalogLabel(ADC_INPUT_POT, idx);
|
||||
return getAnalogLabel(ADC_INPUT_FLEX, idx);
|
||||
}
|
||||
|
||||
// this should be declared in header, but it used so much foreign symbols that
|
||||
@@ -676,19 +676,12 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx)
|
||||
pos = strAppend(pos, STR_CHAR_POT, sizeof(STR_CHAR_POT) - 1);
|
||||
dest_len -= sizeof(STR_CHAR_POT) - 1;
|
||||
}
|
||||
// TODO: AXIS / SWITCH ???
|
||||
name = getPotLabel(idx);
|
||||
}
|
||||
strncpy(pos, name, dest_len - 1);
|
||||
pos[dest_len - 1] = '\0';
|
||||
}
|
||||
#if MAX_AXIS > 0
|
||||
else if (idx <= MIXSRC_LAST_AXIS) {
|
||||
idx -= MIXSRC_FIRST_AXIS;
|
||||
auto name = adcGetInputName(ADC_INPUT_AXIS, idx);
|
||||
strncpy(dest, name, dest_len - 1);
|
||||
dest[dest_len - 1] = '\0';
|
||||
}
|
||||
#endif
|
||||
#if defined(IMU)
|
||||
else if (idx <= MIXSRC_TILT_Y) {
|
||||
idx -= MIXSRC_TILT_X;
|
||||
|
||||
+43
-26
@@ -171,6 +171,8 @@ void evalFunctionSwitches()
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
uint8_t getFSLogicalState(uint8_t) { return false; }
|
||||
#endif // FUNCTION_SWITCHES
|
||||
|
||||
div_t switchInfo(int switchPosition)
|
||||
@@ -196,15 +198,12 @@ int switchLookupIdx(char c)
|
||||
|
||||
int switchLookupIdx(const char* name, size_t len)
|
||||
{
|
||||
if (len < 2 || name[0] != 'S') return -1;
|
||||
|
||||
uint8_t idx = 1; // Sx
|
||||
if (len > 2) idx = 2; // SWx
|
||||
if (len < 2 || (name[0] != 'S' && name[0] != 'F')) return -1;
|
||||
|
||||
auto max_switches = switchGetMaxSwitches() + switchGetMaxFctSwitches();
|
||||
for (int i = 0; i < max_switches; i++) {
|
||||
const char *sw_name = switchGetName(i);
|
||||
if (sw_name[idx] == name[idx]) return i;
|
||||
const char *sw_name = switchGetCanonicalName(i);
|
||||
if (strncmp(sw_name, name, len) == 0) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -244,9 +243,6 @@ bool switchHasCustomName(uint8_t idx)
|
||||
|
||||
const char* switchGetCanonicalName(uint8_t idx)
|
||||
{
|
||||
if (idx >= switchGetMaxSwitches() + switchGetMaxFctSwitches())
|
||||
return nullptr;
|
||||
|
||||
return switchGetName(idx);
|
||||
}
|
||||
|
||||
@@ -314,8 +310,8 @@ void getSwitchesPosition(bool startup)
|
||||
|
||||
switchesPos = newPos;
|
||||
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_POT);
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_POT);
|
||||
auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX);
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
|
||||
for (int i = 0; i < max_pots; i++) {
|
||||
if (IS_POT_MULTIPOS(i)) {
|
||||
@@ -345,6 +341,30 @@ void getSwitchesPosition(bool startup)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getSwitchCount()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxRow(uint8_t col)
|
||||
{
|
||||
uint8_t lastrow = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.col == col)
|
||||
lastrow = switch_display.row > lastrow ? switch_display.row : lastrow;
|
||||
}
|
||||
}
|
||||
return lastrow;
|
||||
}
|
||||
|
||||
getvalue_t getValueForLogicalSwitch(mixsrc_t i)
|
||||
{
|
||||
getvalue_t result = getValue(i);
|
||||
@@ -567,11 +587,19 @@ bool getSwitch(swsrc_t swtch, uint8_t flags)
|
||||
#endif
|
||||
else if (cs_idx <= SWSRC_LAST_SWITCH) {
|
||||
cs_idx -= SWSRC_FIRST_SWITCH;
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
auto max_reg_pos = switchGetMaxSwitches() * 3;
|
||||
if (cs_idx < max_reg_pos) {
|
||||
if (flags & GETSWITCH_MIDPOS_DELAY)
|
||||
if (cs_idx >= max_reg_pos && cs_idx - max_reg_pos < switchGetMaxFctSwitches() * 3) {
|
||||
cs_idx -= max_reg_pos;
|
||||
div_t qr = div(cs_idx, 3);
|
||||
auto value = getFSLogicalState(qr.quot);
|
||||
result = qr.rem == 0 ? !value : (qr.rem == 2 ? value : false);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (flags & GETSWITCH_MIDPOS_DELAY) {
|
||||
result = SWITCH_POSITION(cs_idx);
|
||||
else {
|
||||
} else {
|
||||
div_t qr = div(cs_idx, 3);
|
||||
if (SWITCH_EXISTS(qr.quot)) {
|
||||
result = switchState(cs_idx);
|
||||
@@ -580,17 +608,6 @@ bool getSwitch(swsrc_t swtch, uint8_t flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
else if (cs_idx - max_reg_pos < switchGetMaxFctSwitches() * 3) {
|
||||
cs_idx -= max_reg_pos;
|
||||
div_t qr = div(cs_idx, 3);
|
||||
auto value = getFSLogicalState(qr.quot);
|
||||
result = qr.rem == 0 ? !value : (qr.rem == 2 ? value : false);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (cs_idx <= SWSRC_LAST_MULTIPOS_SWITCH) {
|
||||
result = POT_POSITION(cs_idx - SWSRC_FIRST_MULTIPOS_SWITCH);
|
||||
@@ -753,7 +770,7 @@ bool isSwitchWarningRequired(uint16_t &bad_pots)
|
||||
if (g_model.potsWarnMode) {
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
bad_pots = 0;
|
||||
for (int i = 0; i < adcGetMaxInputs(ADC_INPUT_POT); i++) {
|
||||
for (int i = 0; i < adcGetMaxInputs(ADC_INPUT_FLEX); i++) {
|
||||
if (!IS_POT_SLIDER_AVAILABLE(i)) continue;
|
||||
if ((g_model.potsWarnEnabled & (1 << i)) &&
|
||||
(abs(g_model.potsWarnPosition[i] - GET_LOWRES_POT_POSITION(i)) > 1)) {
|
||||
|
||||
@@ -50,6 +50,10 @@ bool isSwitchWarningRequired(uint16_t &bad_pots);
|
||||
|
||||
void getSwitchesPosition(bool startup);
|
||||
|
||||
uint8_t getSwitchCount();
|
||||
|
||||
uint8_t switchGetMaxRow(uint8_t col);
|
||||
|
||||
extern swarnstate_t switches_states;
|
||||
swsrc_t getMovedSwitch();
|
||||
|
||||
|
||||
@@ -22,72 +22,6 @@
|
||||
#include "stm32_switch_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
bool stm32_switch_get_state(const stm32_switch_t* sw, SwitchHwPos pos)
|
||||
{
|
||||
switch (sw->type) {
|
||||
case SWITCH_HW_2POS:
|
||||
switch (pos) {
|
||||
case SWITCH_HW_UP:
|
||||
if (sw->flags & SWITCH_HW_INVERTED)
|
||||
return !LL_GPIO_IsInputPinSet(sw->GPIOx_high, sw->Pin_high);
|
||||
else
|
||||
return LL_GPIO_IsInputPinSet(sw->GPIOx_high, sw->Pin_high);
|
||||
|
||||
case SWITCH_HW_DOWN:
|
||||
if (sw->flags & SWITCH_HW_INVERTED)
|
||||
return LL_GPIO_IsInputPinSet(sw->GPIOx_high, sw->Pin_high);
|
||||
else
|
||||
return !LL_GPIO_IsInputPinSet(sw->GPIOx_high, sw->Pin_high);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_HW_3POS: {
|
||||
auto hi = LL_GPIO_IsInputPinSet(sw->GPIOx_high, sw->Pin_high);
|
||||
auto lo = LL_GPIO_IsInputPinSet(sw->GPIOx_low, sw->Pin_low);
|
||||
|
||||
switch (pos) {
|
||||
case SWITCH_HW_UP:
|
||||
if (sw->flags & SWITCH_HW_INVERTED)
|
||||
return !hi && lo;
|
||||
else
|
||||
return hi && !lo;
|
||||
|
||||
case SWITCH_HW_DOWN:
|
||||
if (sw->flags & SWITCH_HW_INVERTED)
|
||||
return hi && !lo;
|
||||
else
|
||||
return !hi && lo;
|
||||
|
||||
case SWITCH_HW_MID:
|
||||
return hi && lo;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case SWITCH_HW_ADC: {
|
||||
uint16_t value = getAnalogValue(sw->Pin_high);
|
||||
switch (pos) {
|
||||
case SWITCH_HW_UP:
|
||||
return value < 1024;
|
||||
case SWITCH_HW_DOWN:
|
||||
return value > 3 * 1024;
|
||||
case SWITCH_HW_MID:
|
||||
return (value >= 1024) && (value <= 3 * 1024);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SwitchHwPos stm32_switch_get_position(const stm32_switch_t* sw)
|
||||
{
|
||||
bool inv = sw->flags & SWITCH_HW_INVERTED;
|
||||
|
||||
@@ -37,18 +37,5 @@ struct stm32_switch_t
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
#define SWITCH_HW_DEF_3POS(x, flags) \
|
||||
{ \
|
||||
SWITCHES_GPIO_REG_##x##_H, SWITCHES_GPIO_PIN_##x##_H, \
|
||||
SWITCHES_GPIO_REG_##x##_L, SWITCHES_GPIO_PIN_##x##_L, \
|
||||
SWITCH_HW_3POS, (flags) \
|
||||
}
|
||||
|
||||
#define SWITCH_HW_DEF_2POS(x, flags) \
|
||||
{ \
|
||||
SWITCHES_GPIO_REG_##x, SWITCHES_GPIO_PIN_##x, \
|
||||
nullptr, 0, SWITCH_HW_2POS, (flags) \
|
||||
}
|
||||
|
||||
SwitchHwPos stm32_switch_get_position(const stm32_switch_t* sw);
|
||||
bool stm32_switch_get_state(const stm32_switch_t* sw, SwitchHwPos pos);
|
||||
|
||||
@@ -110,6 +110,7 @@ if (PCB STREQUAL X10)
|
||||
endif()
|
||||
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
|
||||
set(FLYSKY_GIMBAL ON)
|
||||
set(FLEXSW "2" CACHE STRING "Max flex inputs usable as switches")
|
||||
elseif (PCBREV STREQUAL T18)
|
||||
set(FLAVOUR t18)
|
||||
add_definitions(-DRADIO_T18)
|
||||
|
||||
@@ -51,7 +51,7 @@ QVector<QIODevice *> OpenTxSimulator::tracebackDevices;
|
||||
uint16_t simu_get_analog(uint8_t idx)
|
||||
{
|
||||
// 6POS simu mechanism use a different scale, so needs specific offset
|
||||
if (IS_POT_MULTIPOS(idx - adcGetInputOffset(ADC_INPUT_POT))) {
|
||||
if (IS_POT_MULTIPOS(idx - adcGetInputOffset(ADC_INPUT_FLEX))) {
|
||||
// Use radio calibration data to determine conversion factor
|
||||
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[idx];
|
||||
int range6POS = 2048; // Default if calibration is not valid
|
||||
@@ -256,11 +256,11 @@ void OpenTxSimulator::setInputValue(int type, uint8_t index, int16_t value)
|
||||
setAnalogValue(index, value);
|
||||
break;
|
||||
case INPUT_SRC_KNOB :
|
||||
setAnalogValue(index + adcGetInputOffset(ADC_INPUT_POT), value);
|
||||
setAnalogValue(index + adcGetInputOffset(ADC_INPUT_FLEX), value);
|
||||
break;
|
||||
case INPUT_SRC_SLIDER :
|
||||
// TODO redo this when Companion refactored to use radio json adc files
|
||||
//setAnalogValue(index + adcGetInputOffset(ADC_INPUT_POT), value);
|
||||
//setAnalogValue(index + adcGetInputOffset(ADC_INPUT_FLEX), value);
|
||||
static const int slideroffset = adcGetInputIdx("SL1", 3);
|
||||
//qDebug() << "SL1:" << slideroffset;
|
||||
if (slideroffset >= 0)
|
||||
|
||||
@@ -33,92 +33,36 @@ struct hw_switch_def {
|
||||
|
||||
#include "simu_switches.inc"
|
||||
|
||||
int8_t switchesStates[n_total_switches] = { -1 };
|
||||
int8_t switchesStates[MAX_SWITCHES] = { -1 };
|
||||
|
||||
void simuSetSwitch(uint8_t swtch, int8_t state)
|
||||
{
|
||||
assert(swtch < n_total_switches);
|
||||
assert(swtch < switchGetMaxSwitches() + switchGetMaxFctSwitches());
|
||||
switchesStates[swtch] = state;
|
||||
}
|
||||
|
||||
swconfig_t switchGetDefaultConfig()
|
||||
void boardInitSwitches() {}
|
||||
|
||||
static uint8_t get_switch_index(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
return _switch_default_config;
|
||||
switch(cat) {
|
||||
case SWITCH_PHYSICAL:
|
||||
assert(idx < n_switches);
|
||||
return idx;
|
||||
|
||||
case SWITCH_FUNCTION:
|
||||
assert(idx < n_fct_switches);
|
||||
return idx + n_switches;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch_display_pos_t switchGetDisplayPosition(uint8_t idx)
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
if (idx >= DIM(_switch_display))
|
||||
return {0, 0};
|
||||
|
||||
return _switch_display[idx];
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxSwitches()
|
||||
{
|
||||
return n_switches;
|
||||
}
|
||||
|
||||
uint8_t getSwitchCount()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxRow(uint8_t col)
|
||||
{
|
||||
uint8_t lastrow = 0;
|
||||
for (int i = 0; i < switchGetMaxSwitches(); ++i) {
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto switch_display = switchGetDisplayPosition(i);
|
||||
if (switch_display.col == col)
|
||||
lastrow = switch_display.row > lastrow ? switch_display.row : lastrow;
|
||||
}
|
||||
}
|
||||
return lastrow;
|
||||
}
|
||||
|
||||
uint8_t switchGetMaxFctSwitches()
|
||||
{
|
||||
return n_fct_switches;
|
||||
}
|
||||
|
||||
const char* switchGetName(uint8_t idx)
|
||||
{
|
||||
assert(idx < n_total_switches);
|
||||
return _hw_switch_defs[idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType switchGetHwType(uint8_t idx)
|
||||
{
|
||||
assert(idx < n_total_switches);
|
||||
return _hw_switch_defs[idx].type;
|
||||
}
|
||||
|
||||
uint32_t switchState(uint8_t pos)
|
||||
{
|
||||
assert(pos < n_total_switches * 3);
|
||||
|
||||
div_t qr = div(pos, 3);
|
||||
int state = switchesStates[qr.quot];
|
||||
switch (qr.rem) {
|
||||
case SWITCH_HW_UP:
|
||||
return state < 0;
|
||||
case SWITCH_HW_DOWN:
|
||||
return state > 0;
|
||||
default:
|
||||
return state == 0;
|
||||
}
|
||||
}
|
||||
|
||||
SwitchHwPos switchGetPosition(uint8_t idx)
|
||||
{
|
||||
assert(idx < n_total_switches);
|
||||
idx = get_switch_index(cat, idx);
|
||||
|
||||
if (switchesStates[idx] < 0)
|
||||
return SWITCH_HW_UP;
|
||||
@@ -127,3 +71,27 @@ SwitchHwPos switchGetPosition(uint8_t idx)
|
||||
else
|
||||
return SWITCH_HW_DOWN;
|
||||
}
|
||||
|
||||
const char* boardSwitchGetName(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
idx = get_switch_index(cat, idx);
|
||||
return _switch_defs[idx].name;
|
||||
}
|
||||
|
||||
SwitchHwType boardSwitchGetType(uint8_t cat, uint8_t idx)
|
||||
{
|
||||
idx = get_switch_index(cat, idx);
|
||||
return _switch_defs[idx].type;
|
||||
}
|
||||
|
||||
uint8_t boardGetMaxSwitches() { return n_switches; }
|
||||
uint8_t boardGetMaxFctSwitches() { return n_fct_switches; }
|
||||
|
||||
swconfig_t boardSwitchGetDefaultConfig() { return _switch_default_config; }
|
||||
|
||||
switch_display_pos_t switchGetDisplayPosition(uint8_t idx)
|
||||
{
|
||||
if (idx >= DIM(_switch_display)) return {0, 0};
|
||||
|
||||
return _switch_display[idx];
|
||||
}
|
||||
|
||||
@@ -44,13 +44,17 @@ TEST_F(SpecialFunctionsTest, FlightReset)
|
||||
g_model.customFn[0].all.val = FUNC_RESET_FLIGHT;
|
||||
g_model.customFn[0].active = true;
|
||||
|
||||
|
||||
mainRequestFlags = 0;
|
||||
simuSetSwitch(0, 0);
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH));
|
||||
|
||||
evalFunctions(g_model.customFn, modelFunctionsContext);
|
||||
EXPECT_EQ((bool)(mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)), false);
|
||||
|
||||
// now trigger SA0
|
||||
simuSetSwitch(0, -1);
|
||||
EXPECT_EQ(true, getSwitch(SWSRC_FIRST_SWITCH));
|
||||
|
||||
// flightReset() should be called
|
||||
evalFunctions(g_model.customFn, modelFunctionsContext);
|
||||
|
||||
@@ -74,7 +74,7 @@ TEST(ModelAudio, switches)
|
||||
EXPECT_FALSE(matchSwitchAudioFile("SX-mid.wav", sw_pos));
|
||||
EXPECT_FALSE(matchSwitchAudioFile("AS-mid.wav", sw_pos));
|
||||
|
||||
g_eeGeneral.potsConfig = POT_MULTIPOS_SWITCH << (POT_CFG_BITS * 2);
|
||||
g_eeGeneral.potsConfig = FLEX_MULTIPOS << (POT_CFG_BITS * 2);
|
||||
EXPECT_TRUE(matchSwitchAudioFile("S34.wav", sw_pos));
|
||||
EXPECT_EQ(MAX_SWITCHES * 3 + 2 * XPOTS_MULTIPOS_COUNT + 3, sw_pos);
|
||||
|
||||
|
||||
+133
-31
@@ -19,7 +19,12 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "dataconstants.h"
|
||||
#include "gtests.h"
|
||||
#include "myeeprom.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
void setLogicalSwitch(int index, uint16_t _func, int16_t _v1, int16_t _v2, int16_t _v3 = 0, uint8_t _delay = 0, uint8_t _duration = 0, int8_t _andsw = 0)
|
||||
{
|
||||
@@ -137,7 +142,7 @@ TEST(evalLogicalSwitches, playFile)
|
||||
#endif
|
||||
|
||||
#define SWSRC_SA2 (SWSRC_FIRST_SWITCH + 2)
|
||||
#define SWSRC_SF2 (SWSRC_FIRST_SWITCH + 5 * 3 + 2)
|
||||
#define SWSRC_SD2 (SWSRC_FIRST_SWITCH + 3 * 3 + 2)
|
||||
|
||||
TEST(getSwitch, edgeInstant)
|
||||
{
|
||||
@@ -145,29 +150,29 @@ TEST(getSwitch, edgeInstant)
|
||||
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
// LS1 setup: EDGE SFup (0:instant)
|
||||
// LS2 setup: (EDGE SFup (0:instant)) AND SAup
|
||||
setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SF2, -129, -1);
|
||||
setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SF2, -129, -1, 0, 0, SWSRC_SA2);
|
||||
// LS1 setup: EDGE SDup (0:instant)
|
||||
// LS2 setup: (EDGE SDup (0:instant)) AND SAup
|
||||
setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SD2, -129, -1);
|
||||
setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SD2, -129, -1, 0, 0, SWSRC_SA2);
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), false);
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SD2), false);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now trigger SFup, LS1 should become true
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), true);
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SD2), true);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now release SA0 and SW2 should stay true
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
@@ -184,23 +189,23 @@ TEST(getSwitch, edgeInstant)
|
||||
// second part with SAup
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), false);
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SD2), false);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now trigger SFup, LS1 should become true
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SF2), true);
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
// EXPECT_EQ(getSwitch(SWSRC_SD2), true);
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), true);
|
||||
|
||||
// now release SA0 and SW2 should stay true
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
@@ -214,23 +219,23 @@ TEST(getSwitch, edgeInstant)
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
// now bug #2939
|
||||
// SF is kept up and SA is toggled
|
||||
// SD is kept up and SA is toggled
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
@@ -240,7 +245,7 @@ TEST(getSwitch, edgeInstant)
|
||||
//logical switches are reset - the switch should fire again
|
||||
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false); //switch will not trigger, because SF was already up
|
||||
@@ -265,25 +270,25 @@ TEST(getSwitch, edgeRelease)
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
// test for issue #2728
|
||||
// LS1 setup: EDGE SFup (0:release)
|
||||
// LS2 setup: (EDGE SFup (0:release)) AND SAup
|
||||
setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SF2, -129, 0);
|
||||
setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SF2, -129, 0, 0, 0, SWSRC_SA2 );
|
||||
// LS1 setup: EDGE SDup (0:release)
|
||||
// LS2 setup: (EDGE SDup (0:release)) AND SAup
|
||||
setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SD2, -129, 0);
|
||||
setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SD2, -129, 0, 0, 0, SWSRC_SA2 );
|
||||
|
||||
simuSetSwitch(0, -1); //SA down
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
@@ -292,19 +297,19 @@ TEST(getSwitch, edgeRelease)
|
||||
|
||||
// second part with SAup
|
||||
simuSetSwitch(0, 1); //SA up
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 1); //SF up
|
||||
simuSetSwitch(3, 1); //SD up
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), false);
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
simuSetSwitch(5, 0); //SF down
|
||||
simuSetSwitch(3, 0); //SD down
|
||||
logicalSwitchesTimerTick();
|
||||
evalLogicalSwitches();
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW1), true);
|
||||
@@ -318,3 +323,100 @@ TEST(getSwitch, edgeRelease)
|
||||
EXPECT_EQ(getSwitch(SWSRC_SW2), false);
|
||||
|
||||
}
|
||||
|
||||
uint8_t boardGetMaxSwitches();
|
||||
|
||||
TEST(FlexSwitches, switchGetPosition)
|
||||
{
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
||||
if (MAX_FLEX_SWITCHES == 0) return;
|
||||
switchInit();
|
||||
|
||||
auto sw_idx = boardGetMaxSwitches();
|
||||
auto sw_name = switchGetName(sw_idx);
|
||||
EXPECT_STREQ("FL1", sw_name);
|
||||
EXPECT_FALSE(switchIsFlexValid(sw_idx));
|
||||
|
||||
// Configure 1st FLEX input as switch
|
||||
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
||||
switchConfigFlex(sw_idx, 0);
|
||||
EXPECT_TRUE(switchIsFlexValid(sw_idx));
|
||||
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
anaSetFiltered(offset, -1024);
|
||||
EXPECT_EQ(SWITCH_HW_UP, switchGetPosition(sw_idx));
|
||||
|
||||
anaSetFiltered(offset, 0);
|
||||
EXPECT_EQ(SWITCH_HW_MID, switchGetPosition(sw_idx));
|
||||
|
||||
anaSetFiltered(offset, +1024);
|
||||
EXPECT_EQ(SWITCH_HW_DOWN, switchGetPosition(sw_idx));
|
||||
}
|
||||
|
||||
TEST(FlexSwitches, getValue)
|
||||
{
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
||||
if (MAX_FLEX_SWITCHES == 0) return;
|
||||
switchInit();
|
||||
|
||||
// Configure 1st FLEX input as switch
|
||||
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
||||
auto sw_idx = boardGetMaxSwitches();
|
||||
switchConfigFlex(sw_idx, 0);
|
||||
|
||||
g_eeGeneral.switchConfig = (swconfig_t)SWITCH_3POS << (sw_idx * SW_CFG_BITS);
|
||||
EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(sw_idx));
|
||||
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
anaSetFiltered(offset, -1024);
|
||||
EXPECT_EQ(-1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
|
||||
anaSetFiltered(offset, 0);
|
||||
EXPECT_EQ(0, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
|
||||
anaSetFiltered(offset, +1024);
|
||||
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
|
||||
g_eeGeneral.switchConfig = (swconfig_t)SWITCH_2POS << (sw_idx * SW_CFG_BITS);
|
||||
EXPECT_EQ(SWITCH_2POS, SWITCH_CONFIG(sw_idx));
|
||||
|
||||
anaSetFiltered(offset, -1024);
|
||||
EXPECT_EQ(-1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
|
||||
anaSetFiltered(offset, 0);
|
||||
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
|
||||
anaSetFiltered(offset, +1024);
|
||||
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
||||
}
|
||||
|
||||
TEST(FlexSwitches, getSwitch)
|
||||
{
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
||||
if (MAX_FLEX_SWITCHES == 0) return;
|
||||
switchInit();
|
||||
|
||||
// Configure 1st FLEX input as switch
|
||||
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
||||
auto sw_idx = boardGetMaxSwitches();
|
||||
switchConfigFlex(sw_idx, 0);
|
||||
|
||||
g_eeGeneral.switchConfig = (swconfig_t)SWITCH_3POS << (sw_idx * SW_CFG_BITS);
|
||||
EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(sw_idx));
|
||||
|
||||
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
||||
anaSetFiltered(offset, -1024);
|
||||
EXPECT_EQ(true, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
||||
|
||||
anaSetFiltered(offset, 0);
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
||||
EXPECT_EQ(true, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
||||
|
||||
anaSetFiltered(offset, +1024);
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
||||
EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
||||
EXPECT_EQ(true, getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "调试","回传镜像","回传输入","SBUS教练","LUA脚本","CLI","GPS","Debug","SpaceMouse","外置发射"
|
||||
#define TR_SWTYPES "无","回弹","2段","3段"
|
||||
#define TR_POTTYPES "无","有中点旋钮","多段旋钮","无中点旋钮","侧滑块"
|
||||
#define TR_POTTYPES "无","无中点旋钮","有中点旋钮","侧滑块","多段旋钮","Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "禁用","随飞行记录复位","随手动复位"
|
||||
#define TR_COUNTRY_CODES "美国","日本","欧洲"
|
||||
#define TR_USBMODES "询问","游戏柄","U盘","串行"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define TR_TRNCHN "CH1","CH2","CH3","CH4"
|
||||
#define TR_AUX_SERIAL_MODES "VYP","Telemetrie zrcadlení","Telemetrie vstup","SBUS Trenér","LUA","CLI","GPS","Debug","SpaceMouse","Externí modul"
|
||||
#define TR_SWTYPES "Žádný","Bez aretace","2-polohový","3-polohový"
|
||||
#define TR_POTTYPES "Žádný",TR("Pot s aret.","Pot s aretací"),TR("Vícepol př.","Vícepol. přep."),TR("Pot","Potenciometr"),"Slider"
|
||||
#define TR_POTTYPES "Žádný",TR("Pot","Potenciometr"),TR("Pot s aret.","Pot s aretací"),"Slider",TR("Vícepol př.","Vícepol. přep."),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "Ne","V rámci letu","Reset ručně"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japonsko"),TR("EU","Evropa")
|
||||
#define TR_USBMODES TR("Zeptat","Zeptat se"),TR("Joyst","Joystick"),TR("SDkarta","Úložiště"),"Serial"
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#define TR_SWTYPES "Ingen","Skift","2POS","3POS"
|
||||
#endif
|
||||
|
||||
#define TR_POTTYPES "Ingen",TR("Drejek./klik","Drejekontakt med klik"),TR("Multipos","Multipos kontakt"),TR("Drejek.", "Drejekontakt"),"Skyder"
|
||||
#define TR_POTTYPES "Ingen",TR("Drejek.", "Drejekontakt"),TR("Drejek./klik","Drejekontakt med klik"),"Skyder",TR("Multipos","Multipos kontakt"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "FRA","Flyv","Manuel nulstil"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa")
|
||||
#define TR_USBMODES "Spørg",TR("Joyst","Joystik"),TR("Lager","USB lager"),TR("Data", "USB data")
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define TR_TRNCHN "CH1","CH2","CH3","CH4"
|
||||
#define TR_AUX_SERIAL_MODES "AUS","Telem weiterl.","Telemetrie In","SBUS Eingang","LUA","CLI","GPS","Debug","SpaceMouse","Externes Modul"
|
||||
#define TR_SWTYPES "Kein","Taster","2POS","3POS"
|
||||
#define TR_POTTYPES "Kein",TR("Poti m.Ras","Poti mit Raste"),TR("Stufens.","Stufen-Schalter"),TR("Pot","Poti ohne Raste"), "Schieber"
|
||||
#define TR_POTTYPES "Kein",TR("Pot","Poti ohne Raste"),TR("Poti m.Ras","Poti mit Raste"),"Schieber",TR("Stufens.","Stufen-Schalter"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "AUS","Flugzeit","Manuell Rück"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa")
|
||||
#define TR_USBMODES "Fragen",TR("Joyst","Joystick"),TR("SDCard","Speicher"),TR("Serial","Seriell")
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module"
|
||||
#define TR_SWTYPES "None","Toggle","2POS","3POS"
|
||||
#define TR_POTTYPES "None",TR("Pot w. det","Pot with detent"),TR("Multipos","Multipos Switch"),"Pot", "Slider"
|
||||
#define TR_POTTYPES "None","Pot",TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Multipos Switch"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "OFF","Flight","Manual Reset"
|
||||
#define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europe")
|
||||
#define TR_USBMODES "Ask",TR("Joyst","Joystick"),TR("SDCard","Storage"),"Serial"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "UIT","Telem Mirror","Telemetría","Entrenador SBUS","LUA","CLI","GPS","Debug","SpaceMouse","Módulo externo"
|
||||
#define TR_SWTYPES "Nada","Palanca","2POS","3POS"
|
||||
#define TR_POTTYPES "Nada",TR("Pot con fij","Pot con fijador"),TR("Multipos","Switch multipos"),"Pot","Slider"
|
||||
#define TR_POTTYPES "Nada","Pot",TR("Pot con fij","Pot con fijador"),"Slider",TR("Multipos","Switch multipos"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "OFF","Vuelo","Reset manual"
|
||||
#define TR_COUNTRY_CODES TR("US","América"),TR("JP","Japón"),TR("EU", "Europa")
|
||||
#define TR_USBMODES "Pregunta","Joystick","SDCard","Serie"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "POIS","S-Port Pelik","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module"
|
||||
#define TR_SWTYPES "None","Toggle","2POS","3POS"
|
||||
#define TR_POTTYPES "None", TR("Pot w. det","Pot with detent"),TR("Multipos","Monias. Kytkin"),TR("Pot","Potikka"),"Slider"
|
||||
#define TR_POTTYPES "None",TR("Pot","Potikka"),TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Monias. Kytkin"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "OFF","Flight","Manual Reset"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerikk"),TR("JP","Japani"),TR("EU","Euroopp")
|
||||
#define TR_USBMODES "Kysy",TR("Joyst","Joystick"),TR("SDCard","Storage"),"Serial"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define TR_AUX_SERIAL_MODES "OFF","Recopie Télém.","Télémétrie In","Écolage SBUS","LUA","CLI","GPS","Débug","SpaceMouse","Module externe"
|
||||
|
||||
#define TR_SWTYPES "Rien","Monostable","2-POS","3-POS"
|
||||
#define TR_POTTYPES "Rien",TR("Pots av. ctr","Pots avec centre"),TR("Multipos.","Inter multi-pos""Potentiomètre"),TR("Pots","Potentiomètre"),"Curseurs"
|
||||
#define TR_POTTYPES "Rien",TR("Pots","Potentiomètre"),TR("Pots av. ctr","Pots avec centre"),"Curseurs",TR("Multipos.","Inter multi-pos""Potentiomètre"),"Axis X","Axis Y","Switch"
|
||||
|
||||
#define TR_VPERSISTENT "OFF","Vol","Reset Manuel"
|
||||
#define TR_COUNTRY_CODES TR("US","USA"),TR("JP","Japon"),TR("Europe","EU")
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module"
|
||||
#define TR_SWTYPES "None","Toggle","2POS","3POS"
|
||||
#define TR_POTTYPES "None",TR("Pot w. det","Pot with detent"),TR("Multipos","Multipos Switch"),"Pot"
|
||||
#define TR_POTTYPES "None","Pot",TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Multipos Switch"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "OFF","Flight","Manual Reset"
|
||||
#define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europe")
|
||||
#define TR_USBMODES "הצג לי אופציות",TR("Joyst","חיבור משחק קבוע"),TR("SDCard","העברת נתונים קבוע"),"חיבור סיריילי קבוע"
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "OFF","Replica Telem","Telemetria In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","Modulo esterno"
|
||||
#define TR_SWTYPES "Disab.","Toggle","2POS","3POS"
|
||||
#define TR_POTTYPES "Disab.",TR("Pot c. fer","Pot. con centro"),TR("Multipos","Inter. Multipos"),TR("Pot","Potenziometro"),"Slider"
|
||||
#define TR_POTTYPES "Disab.",TR("Pot","Potenziometro"),TR("Pot c. fer","Pot. con centro"),"Slider",TR("Multipos","Inter. Multipos"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "NO","Volo","Reset Manuale"
|
||||
#define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europa")
|
||||
#define TR_USBMODES TR("Chied","Chiedi"),TR("Joyst","Joystick"),TR("SDCard","Storage"),TR("Serial","Seriale")
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "OFF","テレメトリーミラー","テレメトリーIN","SBUSトレーナー","LUAスクリプト","CLI","GPS","デバッグ","外部モジュール"
|
||||
#define TR_SWTYPES "なし","トグル","2POS","3POS"
|
||||
#define TR_POTTYPES "なし",TR("Pot w. det","ダイヤル(ノッチ有)"),TR("Multipos","マルチPOSスイッチ"),"ダイヤル","スライダー"
|
||||
#define TR_POTTYPES "なし","ダイヤル",TR("Pot w. det","ダイヤル(ノッチ有)"),"スライダー",TR("Multipos","マルチPOSスイッチ"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "無効","飛行時","手動リセット"
|
||||
#define TR_COUNTRY_CODES TR("US","アメリカ"),TR("JP","日本"),TR("EU","ヨーロッパ")
|
||||
#define TR_USBMODES "確認",TR("Joyst","JoyStick"),TR("SDカード","ストレージ"),"シリアル"
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "UIT","Telem Mirror","Telemetry In","SBUS Leerling","LUA","CLI","GPS","Debug","SpaceMouse","External module"
|
||||
#define TR_SWTYPES "Geen","Wissel","2POS","3POS"
|
||||
#define TR_POTTYPES "Geen",TR("Pot w. det","Pot met Klik"),TR("Multipos","Standenschakelaar"),TR("Pot", "Pot zonder Klik"),"Schuif"
|
||||
#define TR_POTTYPES "Geen",TR("Pot", "Pot zonder Klik"),TR("Pot w. det","Pot met Klik"),"Schuif",TR("Multipos","Standenschakelaar"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "UIT","Vliegtijd","Handmatige Reset"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa")
|
||||
#define TR_USBMODES "Ask",TR("Joyst","Joystick"),TR("SDCard","Storage"),"Serial"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#define TR_TRNCHN "KN1","KN2","KN3","KN4"
|
||||
#define TR_AUX_SERIAL_MODES "Wyłącz","S-Port Kopia","Telemetria","Trener SBUS","LUA","CLI","GPS","Debug","SpaceMouse","Moduł zewnętrzny"
|
||||
#define TR_SWTYPES "Brak","Chwil.","2POZ","3POZ"
|
||||
#define TR_POTTYPES "Brak",TR("Pot w. det","Poten z zapadką"),TR("Multipos","Przeł.Wielopoz."),TR("Pot","Potencjometr"),"Suwak"
|
||||
#define TR_POTTYPES "Brak",TR("Pot","Potencjometr"),TR("Pot w. det","Poten z zapadką"),"Suwak",TR("Multipos","Przeł.Wielopoz."),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "Wyłącz","Lot","Ręczny Reset"
|
||||
#define TR_COUNTRY_CODES TR("US","Ameryka"),TR("JP","Japonia"),TR("EU", "Europa")
|
||||
#define TR_USBMODES "Ask",TR("Joyst","Joystick"),TR("SDCard","Storage"),"Serial"
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#define TR_TRNCHN "CH1","CH2","CH3","CH4"
|
||||
#define TR_AUX_SERIAL_MODES "OFF","Espelhar Telem","Entr Telem","Trainer SBUS","LUA","CLI","GPS","Debug","SpaceMouse","External module"
|
||||
#define TR_SWTYPES "Nenhum","Tatil","2POS","3POS"
|
||||
#define TR_POTTYPES "Nenhum",TR("Pot c. det","Pot com detentor"),TR("Multipos","Chave Multipos"),"Pot","Slider"
|
||||
#define TR_POTTYPES "Nenhum","Pot",TR("Pot c. det","Pot com detentor"),"Slider",TR("Multipos","Chave Multipos"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "OFF","Voo","Reset Manual"
|
||||
#define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japao"),TR("EU","Europa")
|
||||
#define TR_USBMODES "Pergunta",TR("Joyst","Joystick"),TR("SDCard","Storage"),"Serial"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#define TR_SWTYPES "Ingen","Flipp","2 pos","3 pos"
|
||||
#endif
|
||||
|
||||
#define TR_POTTYPES "Ingen",TR("Vred m. mitt","Vred med mittläge"),TR("Multipos","Flerlägesväljare"),"Vred","Reglage"
|
||||
#define TR_POTTYPES "Ingen","Vred",TR("Vred m. mitt","Vred med mittläge"),"Reglage",TR("Multipos","Flerlägesväljare"),"Axis X","Axis Y","Switch"
|
||||
#define TR_VPERSISTENT "Av","Flygning","Nolla själv"
|
||||
#define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa")
|
||||
#define TR_USBMODES "Fråga","Joystick",TR("SD-kort","SD-kortlagring"),"Seriell"
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#define TR_AUX_SERIAL_MODES "禁用","回傳鏡像","回傳輸入","SBUS教練","LUA腳本","CLI","GPS","調試","SpaceMouse","外置發射"
|
||||
#define TR_SWTYPES "無","回彈","2段","3段"
|
||||
#define TR_POTTYPES "無","有中點旋鈕","多段旋鈕","無中點旋鈕","側滑塊"
|
||||
#define TR_POTTYPES "無","無中點旋鈕","有中點旋鈕","側滑塊","多段旋鈕"
|
||||
#define TR_VPERSISTENT "禁用","隨飛行記錄重啟","隨手動重啟"
|
||||
#define TR_COUNTRY_CODES "美國","日本","歐洲"
|
||||
#define TR_USBMODES "詢問","遊戲柄","U盤","串行"
|
||||
|
||||
@@ -43,6 +43,22 @@ KEYS_LUT = [
|
||||
"KEY_BIND",
|
||||
]
|
||||
|
||||
# def eprint(*args, **kwargs):
|
||||
# from sys import stderr
|
||||
# print(*args, file=stderr, **kwargs)
|
||||
|
||||
def is_ext_input(input):
|
||||
|
||||
if input.get('type') != 'FLEX':
|
||||
return False
|
||||
|
||||
name = input.get('name')
|
||||
if name and name.startswith('EXT'):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def generate_from_template(json_filename, template_filename, target):
|
||||
|
||||
with open(json_filename) as json_file:
|
||||
@@ -70,6 +86,8 @@ def generate_from_template(json_filename, template_filename, target):
|
||||
trim_blocks=True
|
||||
)
|
||||
|
||||
env.tests['ext_input'] = is_ext_input
|
||||
|
||||
template_str = template_file.read()
|
||||
template = env.from_string(template_str)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ def eprint(*args, **kwargs):
|
||||
class ADCInput:
|
||||
|
||||
TYPE_STICK = 'STICK'
|
||||
TYPE_POT = 'POT'
|
||||
TYPE_FLEX = 'FLEX'
|
||||
TYPE_SWITCH = 'SWITCH'
|
||||
# TYPE_BATT = 'BATT'
|
||||
|
||||
@@ -60,25 +60,25 @@ class ADCInputParser:
|
||||
},
|
||||
{
|
||||
'range': range(1, MAX_POTS + 1),
|
||||
'type': ADCInput.TYPE_POT,
|
||||
'type': ADCInput.TYPE_FLEX,
|
||||
'suffix': 'POT{}',
|
||||
'name': 'P{}',
|
||||
},
|
||||
{
|
||||
'range': range(1, MAX_SLIDERS + 1),
|
||||
'type': ADCInput.TYPE_POT,
|
||||
'type': ADCInput.TYPE_FLEX,
|
||||
'suffix': 'SLIDER{}',
|
||||
'name': 'SL{}',
|
||||
},
|
||||
{
|
||||
'range': range(1, MAX_EXTS + 1),
|
||||
'type': ADCInput.TYPE_POT,
|
||||
'type': ADCInput.TYPE_FLEX,
|
||||
'suffix': 'EXT{}',
|
||||
'name': 'EXT{}',
|
||||
},
|
||||
{
|
||||
'range': range(1, 2 + 1),
|
||||
'type': 'AXIS',
|
||||
'type': ADCInput.TYPE_FLEX,
|
||||
'suffix': 'MOUSE{}',
|
||||
'name': MouseName(),
|
||||
},
|
||||
@@ -232,10 +232,10 @@ class ADCInputParser:
|
||||
d = self.dirs[idx]
|
||||
if d < 0:
|
||||
adc_input.inverted = True
|
||||
if adc_input.type == 'POT':
|
||||
if adc_input.type == 'FLEX':
|
||||
input_labels = self.labels[adc_input.name]
|
||||
adc_input.label = input_labels['label']
|
||||
adc_input.short_label = input_labels['short_label']
|
||||
adc_input.label = input_labels.get('label')
|
||||
adc_input.short_label = input_labels.get('short_label')
|
||||
cfg = pot_cfg_by_target(self.target,adc_input.name)
|
||||
if cfg:
|
||||
adc_input.default = cfg.get('default')
|
||||
|
||||
@@ -12,25 +12,16 @@ static const etx_hal_adc_input_t _main_inputs[] = {
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
{% set pot_offset = n_mains %}
|
||||
{% set pot_inputs = adc_inputs.inputs | selectattr('type', '==', 'POT') | list %}
|
||||
{% set n_pots = pot_inputs | count %}
|
||||
static const etx_hal_adc_input_t _pot_inputs[] = {
|
||||
{% for input in pot_inputs %}
|
||||
{% set flex_offset = n_mains %}
|
||||
{% set flex_inputs = adc_inputs.inputs | selectattr('type', '==', 'FLEX') | list %}
|
||||
{% set n_flex = flex_inputs | count %}
|
||||
static etx_hal_adc_input_t _flex_inputs[] = {
|
||||
{% for input in flex_inputs %}
|
||||
{ "{{ input.name }}", "{{ input.label }}", "{{ input.short_label }}" },
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
{% set axis_offset = pot_offset + n_pots %}
|
||||
{% set axis_inputs = adc_inputs.inputs | selectattr('type', '==', 'AXIS') | list %}
|
||||
{% set n_axis = axis_inputs | count %}
|
||||
static const etx_hal_adc_input_t _axis_inputs[] = {
|
||||
{% for input in axis_inputs %}
|
||||
{ "{{ input.name }}", "{{ input.label }}", nullptr },
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
{% set vbat_offset = axis_offset + n_axis %}
|
||||
{% set vbat_offset = flex_offset + n_flex %}
|
||||
{% set vbat_inputs = adc_inputs.inputs | selectattr('type', '==', 'VBAT') | list %}
|
||||
{% set n_vbat = vbat_inputs | count %}
|
||||
static const etx_hal_adc_input_t _vbat_inputs[] = {
|
||||
@@ -51,17 +42,16 @@ static const etx_hal_adc_input_t _rtc_bat_inputs[] = {
|
||||
{% set n_inputs = rtc_bat_offset + n_rtc_bat %}
|
||||
static const etx_hal_adc_inputs_t _hal_inputs[] = {
|
||||
{ {{ n_mains }}, 0, _main_inputs },
|
||||
{ {{ n_pots }}, {{ pot_offset }}, _pot_inputs },
|
||||
{ {{ n_axis }}, {{ axis_offset }}, _axis_inputs },
|
||||
{ {{ n_flex }}, {{ flex_offset }}, _flex_inputs },
|
||||
{ {{ n_vbat }}, {{ vbat_offset }}, _vbat_inputs },
|
||||
{ {{ n_rtc_bat }}, {{ rtc_bat_offset }}, _rtc_bat_inputs },
|
||||
{ {{ n_inputs }}, 0, nullptr },
|
||||
};
|
||||
|
||||
constexpr potconfig_t _pot_default_config = (0)
|
||||
{% for pot in pot_inputs %}
|
||||
{% if pot.default %}
|
||||
| (POT_{{ pot.default }} << ({{ loop.index0 }} * POT_CFG_BITS))
|
||||
{% for flex in flex_inputs %}
|
||||
{% if flex.default %}
|
||||
| ((potconfig_t)FLEX_{{ flex.default }} << ({{ loop.index0 }} * POT_CFG_BITS))
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
;
|
||||
|
||||
@@ -148,11 +148,15 @@ LEGACY_NAMES = [
|
||||
"JSx": {
|
||||
"yaml": "MOUSE1",
|
||||
"lua": "jsx",
|
||||
"label": "JSx",
|
||||
"short_label": "X",
|
||||
"description": "Joystick X"
|
||||
},
|
||||
"JSy": {
|
||||
"yaml": "MOUSE2",
|
||||
"lua": "jsy",
|
||||
"label": "JSy",
|
||||
"short_label": "Y",
|
||||
"description": "Joystick Y"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,144 +2,146 @@
|
||||
|
||||
POT_CONFIG = {
|
||||
"boxer": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"P3": {"default": "MULTIPOS_SWITCH"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"P3": {"default": "MULTIPOS"}
|
||||
},
|
||||
"el18": {
|
||||
"P1": { "default": "WITHOUT_DETENT"},
|
||||
"P2": { "default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"nv14": {
|
||||
"P1": { "default": "WITHOUT_DETENT"},
|
||||
"P2": { "default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"tpro": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"tprov2": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"t20": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL3": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL4": {"default": "SLIDER_WITH_DETENT"},
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"},
|
||||
"SL3": {"default": "SLIDER"},
|
||||
"SL4": {"default": "SLIDER"},
|
||||
},
|
||||
"t12": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT"}
|
||||
},
|
||||
"tx12": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"tx12mk2": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"t16": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"t18": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"tx16s": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x7": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"x7access": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT_CENTER"}
|
||||
},
|
||||
"x9d": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x9dp": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x9dp2019": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x9e": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P2": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL3": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL4": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"},
|
||||
"SL3": {"default": "SLIDER"},
|
||||
"SL4": {"default": "SLIDER"}
|
||||
},
|
||||
"x10": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x10express": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"x12s": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "MULTIPOS_SWITCH"},
|
||||
"P3": {"default": "WITH_DETENT"},
|
||||
"SL1": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL2": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL3": {"default": "SLIDER_WITH_DETENT"},
|
||||
"SL4": {"default": "SLIDER_WITH_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
"P3": {"default": "POT_CENTER"},
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"},
|
||||
"SL3": {"default": "SLIDER"},
|
||||
"SL4": {"default": "SLIDER"},
|
||||
"JSx": {"default": "AXIS_X"},
|
||||
"JSy": {"default": "AXIS_Y"}
|
||||
},
|
||||
"xlite": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT"}
|
||||
},
|
||||
"xlites": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT"}
|
||||
},
|
||||
"x9lite": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
},
|
||||
"x9lites": {
|
||||
"P1": {"default": "WITH_DETENT"},
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
},
|
||||
"zorro": {
|
||||
"P1": {"default": "WITHOUT_DETENT"},
|
||||
"P2": {"default": "WITHOUT_DETENT"}
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT"}
|
||||
},
|
||||
"pocket": {
|
||||
"P1": { "default": "WITHOUT_DETENT" }
|
||||
"P1": {"default": "POT"}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% set regular_switches = switches | selectattr('type','!=','FSWITCH') | list %}
|
||||
{% set function_switches = switches | selectattr('type','==','FSWITCH') | list %}
|
||||
|
||||
const hw_switch_def _hw_switch_defs[] = {
|
||||
const hw_switch_def _switch_defs[] = {
|
||||
{% for switch in regular_switches %}
|
||||
{ "{{ switch.name }}", SWITCH_HW_{{ switch.type }} },
|
||||
{% endfor %}
|
||||
|
||||
@@ -41,6 +41,13 @@ static const stm32_switch_t _switch_defs[] = {
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
static const stm32_switch_t* const _switch_offsets[] = {
|
||||
_switch_defs,
|
||||
{% if function_switches %}
|
||||
_switch_defs + {{ regular_switches | count }},
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
static inline void _init_switches()
|
||||
{
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
@@ -56,7 +63,6 @@ static inline void _init_switches()
|
||||
|
||||
constexpr uint8_t n_switches = {{ regular_switches | count }};
|
||||
constexpr uint8_t n_fct_switches = {{ function_switches | count }};
|
||||
constexpr uint8_t n_total_switches = {{ switches | count }};
|
||||
|
||||
constexpr swconfig_t _switch_default_config = (swconfig_t)0
|
||||
{% for sw in regular_switches %}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
//
|
||||
|
||||
{% set main_inputs = adc_inputs.inputs | selectattr('type', '==', 'STICK') | list %}
|
||||
{% set pot_inputs = adc_inputs.inputs | selectattr('type', '==', 'POT') | list %}
|
||||
{% set axis_inputs = adc_inputs.inputs | selectattr('type', '==', 'AXIS') | list %}
|
||||
{% set flex_inputs = adc_inputs.inputs | selectattr('type', '==', 'FLEX') | list %}
|
||||
|
||||
struct legacy_input_t {
|
||||
const char* legacy;
|
||||
@@ -17,12 +16,8 @@ static const legacy_input_t _legacy_inputs[] = {
|
||||
{% set li = legacy_inputs[input.name] %}
|
||||
{ "{{ li.yaml }}", MIXSRC_FIRST_STICK + {{ loop.index0 }} },
|
||||
{% endfor %}
|
||||
{% for input in pot_inputs %}
|
||||
{% for input in flex_inputs %}
|
||||
{% set li = legacy_inputs[input.name] %}
|
||||
{ "{{ li.yaml }}", MIXSRC_FIRST_POT + {{ loop.index0 }} },
|
||||
{% endfor %}
|
||||
{% for input in axis_inputs %}
|
||||
{% set li = legacy_inputs[input.name] %}
|
||||
{ "{{ li.yaml }}", MIXSRC_FIRST_AXIS + {{ loop.index0 }} },
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user