chore: store more hardware settings in hwdef JSON files (#7031)

This commit is contained in:
philmoz
2026-01-29 11:54:14 +10:00
committed by GitHub
parent 71305d502c
commit 2579bc6132
11 changed files with 290 additions and 134 deletions
+88 -3
View File
@@ -69,10 +69,12 @@ BoardJson::BoardJson(Board::Type board, QString hwdefn) :
m_switches(new SwitchesTable),
m_trims(new TrimsTable),
m_keys(new KeysTable),
m_display({0, 0, 0, 0, 0, 0, 0, 0}),
m_cfs({0, 0}),
m_hardware({0, 0, 0}),
m_inputCnt({0, 0, 0, 0, 0, 0, 0, 0, 0}),
m_switchCnt({0, 0, 0})
{
}
BoardJson::~BoardJson()
@@ -151,6 +153,9 @@ void BoardJson::afterLoadFixups(Board::Type board, InputsTable * inputs, Switche
const int BoardJson::getCapability(const Board::Capability capability) const
{
switch (capability) {
case Board::Air:
return !m_hardware.surface;
case Board::FlexInputs:
return (m_inputCnt.flexGyroAxes +
m_inputCnt.flexJoystickAxes +
@@ -161,18 +166,45 @@ const int BoardJson::getCapability(const Board::Capability capability) const
case Board::FlexSwitches:
return m_switchCnt.flex;
case Board::FunctionSwitchColors:
return m_cfs.rgb_led;
case Board::FunctionSwitches:
return m_switchCnt.func;
case Board::FunctionSwitchGroups:
return m_cfs.groups;
case Board::GyroAxes:
return m_inputCnt.flexGyroAxes;
case Board::Gyros:
return getCapability(Board::GyroAxes) / 2;
case Board::HasAudioMuteGPIO:
return m_hardware.has_audio_mute;
case Board::HasBacklightColor:
return m_display.backlight_color;
case Board::HasBlingLEDS:
return m_hardware.has_bling_leds;
case Board::HasColorLcd:
return m_display.color;
case Board::HasExternalModuleSupport:
return m_hardware.has_ext_module_support;
case Board::HasInternalModuleSupport:
return m_hardware.has_int_module_support;
case Board::HasRTC:
return m_inputCnt.rtcbat;
case Board::HasSDCard:
return true;
case Board::HasVBat:
return m_inputCnt.vbat;
@@ -182,9 +214,24 @@ const int BoardJson::getCapability(const Board::Capability capability) const
case Board::InputSwitches:
return m_inputCnt.switches;
case Board::JoystickAxes:
return m_inputCnt.flexJoystickAxes;
case Board::Keys:
return m_keys->size();
case Board::LcdDepth:
return m_display.depth;
case Board::LcdHeight:
return m_display.h;
case Board::LcdOLED:
return m_display.oled;
case Board::LcdWidth:
return m_display.w;
case Board::MultiposPots:
// assumes every input has potential to be one
// index used for mapping 6 pos switches back to input
@@ -208,12 +255,18 @@ const int BoardJson::getCapability(const Board::Capability capability) const
case Board::Sliders:
return m_inputCnt.flexSliders;
case Board::SportMaxBaudRate:
return m_hardware.sport_max_baudrate;
case Board::StandardSwitches:
return m_switchCnt.std;
case Board::Sticks:
return m_inputCnt.sticks;
case Board::Surface:
return m_hardware.surface;
case Board::Switches:
return (m_switchCnt.std +
m_switchCnt.flex +
@@ -920,7 +973,7 @@ bool BoardJson::loadDefinition()
if (m_board == Board::BOARD_UNKNOWN)
return true;
if (!loadFile(m_board, m_hwdefn, m_inputs, m_switches, m_keys, m_trims))
if (!loadFile(m_board, m_hwdefn, m_inputs, m_switches, m_keys, m_trims, m_display, m_cfs, m_hardware))
return false;
afterLoadFixups(m_board, m_inputs, m_switches, m_keys, m_trims);
@@ -956,7 +1009,8 @@ bool BoardJson::loadDefinition()
// static
bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches,
KeysTable * keys, TrimsTable * trims)
KeysTable * keys, TrimsTable * trims, DisplayDefn & display, CustomSwitchesDefn & cfs,
HardwareDefn & hardware)
{
if (board == Board::BOARD_UNKNOWN) {
return false;
@@ -1164,6 +1218,37 @@ bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs
}
}
if (obj.value("display").isObject()) {
const QJsonObject &o = obj.value("display").toObject();
display.w = o.value("w").toInt();
display.h = o.value("h").toInt();
display.phys_w = o.value("phys_w").toInt();
display.phys_h = o.value("phys_h").toInt();
display.depth = o.value("depth").toInt();
display.color = o.value("color").toInt();
display.oled = o.value("oled").toInt();
display.backlight_color = o.value("backlight_color").toInt();
}
if (obj.value("custom_switches").isObject()) {
const QJsonObject &o = obj.value("custom_switches").toObject();
cfs.rgb_led = o.value("rgb_led").toInt();
cfs.groups = o.value("groups").toInt();
}
if (obj.value("hardware").isObject()) {
const QJsonObject &o = obj.value("hardware").toObject();
hardware.has_audio_mute = o.value("has_audio_mute").toInt();
hardware.has_bling_leds = o.value("has_bling_leds").toInt();
hardware.has_ext_module_support = o.value("has_ext_module_support").toInt();
hardware.has_int_module_support = o.value("has_int_module_support").toInt();
hardware.sport_max_baudrate = o.value("sport_max_baudrate").toInt();
hardware.surface = o.value("surface").toInt();
}
delete json;
return true;
}
+30 -1
View File
@@ -100,6 +100,31 @@ class BoardJson
TrimDefn() = default;
};
struct DisplayDefn {
int w = 0;
int h = 0;
int phys_w = 0;
int phys_h = 0;
int depth = 0;
int color = 0;
int oled = 0;
int backlight_color = 0;
};
struct CustomSwitchesDefn {
int rgb_led = 0;
int groups = 0;
};
struct HardwareDefn {
int has_audio_mute = 0;
int has_bling_leds = 0;
int has_ext_module_support = 0;
int has_int_module_support = 0;
int sport_max_baudrate = 0;
int surface = 0;
};
typedef std::vector<TrimDefn> TrimsTable;
explicit BoardJson(Board::Type board, QString hwdefn);
@@ -170,6 +195,9 @@ private:
SwitchesTable *m_switches;
TrimsTable *m_trims;
KeysTable *m_keys;
DisplayDefn m_display;
CustomSwitchesDefn m_cfs;
HardwareDefn m_hardware;
struct InputCounts {
unsigned int flexGyroAxes;
@@ -194,7 +222,8 @@ private:
SwitchCounts m_switchCnt;
static bool loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches,
KeysTable * keys, TrimsTable * trims);
KeysTable * keys, TrimsTable * trims, DisplayDefn & lcd, CustomSwitchesDefn & cfs,
HardwareDefn & hardware);
static void afterLoadFixups(Board::Type board, InputsTable * inputs, SwitchesTable * switches,
KeysTable * keys, TrimsTable * trims);
-112
View File
@@ -305,66 +305,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
// TODO investigate usage of any that should be covered in BoardJson::getCapability or are no longer required
// some could be used when importing pre v2.10 configurations
switch (capability) {
case Air:
return !getCapability(board, Surface);
case FactoryInstalledPots:
if (IS_TARANIS_X9(board))
return 2;
else
return getCapability(board, Pots);
case FactoryInstalledSwitches:
if (IS_TARANIS_X9E(board))
return 8;
else if (IS_JUMPER_TPROV2(board))
return 6;
else if (IS_JUMPER_TLITE(board) || IS_JUMPER_TPROV1(board) || IS_BETAFPV_LR3PRO(board) || IS_IFLIGHT_COMMANDO8(board) || IS_JUMPER_BUMBLEBEE(board))
return 4;
else if(IS_RADIOMASTER_ZORRO(board))
return 8;
else if (IS_RADIOMASTER_POCKET(board))
return 5;
else if (IS_FAMILY_T12(board))
return 6;
else if (IS_HORUS_X12S(board))
return 8;
else
return getCapability(board, Board::Switches);
case FunctionSwitchGroups:
if (getCapability(board, FunctionSwitches)) {
return IS_RADIOMASTER_GX12(board) ? CPN_MAX_CUSTOMSWITCH_GROUPS : 3;
}
return 0;
case HasAudioMuteGPIO:
// All color lcd (including NV14 and EL18) except Horus X12S
// TX12, TX12MK2, ZORRO, BOXER, T8, TLITE, TPRO, LR3PRO, COMMANDO8
return (IS_FAMILY_HORUS_OR_T16(board) && !IS_HORUS_X12S(board)) || IS_FAMILY_T12(board);
case HasBacklightColor:
return IS_TARANIS_PLUS(board) || IS_TARANIS_X9DP_2019(board);
case HasColorLcd:
return IS_FAMILY_HORUS_OR_T16(board);
case HasExternalModuleSupport:
return (IS_STM32(board) && !IS_RADIOMASTER_T8(board));
case HasIMU:
return (IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS(board) || IS_RADIOMASTER_TX15(board));
case HasInternalModuleSupport:
return (IS_STM32(board) && !IS_TARANIS_X9(board));
case HasLedStripGPIO:
return (IS_RADIOMASTER_MT12(board) || IS_FAMILY_PL18(board) ||
IS_HELLORADIOSKY_V16(board));
case HasSDCard:
return true;
case HasTrainerModuleCPPM:
return (getCapability(board, HasTrainerModuleSBUS) || IS_FAMILY_HORUS_OR_T16(board));
@@ -376,61 +319,6 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
IS_JUMPER_BUMBLEBEE(board)) || IS_FAMILY_T16(board) || IS_FAMILY_HORUS(board) ||
(getCapability(board, HasExternalModuleSupport) && (IS_TARANIS(board) && !IS_FAMILY_T12(board))));
case LcdOLED:
return IS_BETAFPV_LR3PRO(board) || IS_JUMPER_TPROV2(board) || IS_JUMPER_TPROS(board) || IS_JUMPER_T20(board) ||
IS_JUMPER_T14(board) || IS_JUMPER_BUMBLEBEE(board) || IS_RADIOMASTER_GX12(board);
case LcdDepth:
if (IS_FAMILY_HORUS_OR_T16(board))
return 16;
else if (IS_TARANIS_SMALL(board))
return 1;
else if (IS_TARANIS(board))
return 4;
else
return 1;
case LcdHeight:
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_RADIOMASTER_TX16SMK3(board))
return 480;
else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_JUMPER_T15PRO(board) || IS_FLYSKY_ST16(board) || IS_RADIOMASTER_TX15(board))
return 320;
else if (IS_FLYSKY_PA01(board))
return 240;
else if (IS_FAMILY_HORUS_OR_T16(board))
return 272;
else
return 64;
case LcdWidth:
if (IS_RADIOMASTER_TX16SMK3(board))
return 800;
else if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PA01(board))
return 320;
else if (IS_FAMILY_HORUS_OR_T16(board) || IS_RADIOMASTER_TX15(board) || IS_FAMILY_PL18(board) || IS_FLYSKY_ST16(board))
return 480;
else if (IS_TARANIS(board) && !IS_TARANIS_SMALL(board))
return 212;
else
return 128;
case MaxAnalogs:
return getCapability(board, Board::Sticks) + getCapability(board, Board::Pots) + getCapability(board, Board::Sliders) +
getCapability(board, Board::JoystickAxes) + getCapability(board, Board::GyroAxes);
case SportMaxBaudRate:
if (IS_FAMILY_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_TARANIS_X7_ACCESS(board) ||
(IS_TARANIS(board) && !IS_TARANIS_XLITE(board) && !IS_TARANIS_X7(board) && !IS_TARANIS_X9LITE(board)))
return 400000; // 400K and higher
else
return 250000; // less than 400K
case Surface:
return IS_RADIOMASTER_MT12(board);
case FunctionSwitchColors:
return IS_RADIOMASTER_GX12(board) || IS_FLYSKY_ST16(board) || IS_FLYSKY_PA01(board) || IS_RADIOMASTER_TX15(board) || IS_RADIOMASTER_TX16SMK3(board);
default:
return getBoardJson(board)->getCapability(capability);
}
+8 -11
View File
@@ -212,15 +212,13 @@ namespace Board {
enum Capability {
Air,
FactoryInstalledPots,
FactoryInstalledSwitches,
FlexInputs,
FlexSwitches,
FunctionSwitches,
FunctionSwitchColors,
FunctionSwitches,
FunctionSwitchGroups,
Gyros,
GyroAxes,
Gyros,
HasAudioMuteGPIO,
HasBacklightColor,
HasColorLcd,
@@ -228,22 +226,21 @@ namespace Board {
HasIMU,
HasInternalModuleSupport,
HasIntModuleHeartbeatGPIO,
HasLedStripGPIO,
HasBlingLEDS,
HasRTC,
HasSDCard,
HasTrainerModuleCPPM,
HasTrainerModuleSBUS,
HasVBat,
LcdOLED,
LcdDepth,
LcdHeight,
LcdWidth,
MaxAnalogs,
Inputs,
InputSwitches,
Joysticks,
JoystickAxes,
Joysticks,
Keys,
LcdDepth,
LcdHeight,
LcdOLED,
LcdWidth,
MultiposPots,
MultiposPotsPositions,
NumFunctionSwitchesPositions,
@@ -265,7 +265,7 @@ bool CustomFunctionData::isFuncAvailable(const int index, const ModelData * mode
((index >= FuncAdjustGV1 && index <= FuncAdjustGVLast) && ((index - FuncAdjustGV1) >= fw->getCapability(Gvars))) ||
((index == FuncDisableTouch) && !IS_HORUS_OR_TARANIS(fw->getBoard())) ||
((index == FuncDisableAudioAmp && !Boards::getCapability(fw->getBoard(), Board::HasAudioMuteGPIO))) ||
((index == FuncRGBLed && !(Boards::getCapability(fw->getBoard(), Board::HasLedStripGPIO) || Boards::getCapability(fw->getBoard(), Board::FunctionSwitchColors)))) ||
((index == FuncRGBLed && !(Boards::getCapability(fw->getBoard(), Board::HasBlingLEDS) || Boards::getCapability(fw->getBoard(), Board::FunctionSwitchColors)))) ||
((index == FuncLCDtoVideo && !IS_FATFISH_F16(fw->getBoard()))) ||
((index >= FuncPushCustomSwitch1 && index <= FuncPushCustomSwitchLast) && !Boards::getCapability(fw->getBoard(), Board::FunctionSwitches))
);
-6
View File
@@ -254,16 +254,10 @@ void ledBlue();
// LCD driver
#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E)
#define LCD_W 212
#define LCD_H 64
#define LCD_DEPTH 4
#define LCD_CONTRAST_MIN 0
#define LCD_CONTRAST_MAX 45
#define LCD_CONTRAST_DEFAULT 25
#else
#define LCD_W 128
#define LCD_H 64
#define LCD_DEPTH 1
#define IS_LCD_RESET_NEEDED() true
#if defined(OLED_SCREEN)
#define LCD_CONTRAST_MIN 2
+15
View File
@@ -2961,3 +2961,18 @@
#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define MIXER_SCHEDULER_TIMER_IRQn TIM8_BRK_TIM12_IRQn
#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_BRK_TIM12_IRQHandler
// LCD driver
#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E)
#define LCD_W 212
#define LCD_H 64
#define LCD_DEPTH 4
#else
#define LCD_W 128
#define LCD_H 64
#define LCD_DEPTH 1
#endif
#if defined(PCBX9DP) || defined(PCBX9E)
#define HAS_BACKLIGHT_COLOR
#endif
+26
View File
@@ -0,0 +1,26 @@
class CFS:
def __init__(self, cfs_rgb_led, cfs_groups):
self.rgb_led = cfs_rgb_led
self.groups = cfs_groups
def parse_cfs(hw_defs):
cfs_rgb_led = 0
cfs_groups = 0
fcfs = f'FUNCTION_SWITCHES'
frgb = f'FUNCTION_SWITCHES_RGB_LEDS'
if fcfs in hw_defs:
if frgb in hw_defs:
cfs_rgb_led = 1
if f'RADIO_GX12' in hw_defs:
cfs_groups = 4
elif f'RADIO_PA01' in hw_defs:
cfs_groups = 2
else:
cfs_groups = 3
return CFS(cfs_rgb_led, cfs_groups)
+18
View File
@@ -6,6 +6,9 @@ import json
from hal_switches import Switch, parse_switches
from hal_adc import ADCInput, SPI_ADCInput, ADC, ADCInputParser
from hal_keys import Key, Trim, parse_trims, parse_keys
from hal_lcd import Display, parse_lcd
from hal_cfs import CFS, parse_cfs
from hal_misc import Misc, parse_misc
import legacy_names
@@ -62,6 +65,12 @@ class DictEncoder(json.JSONEncoder):
return prune_dict(obj.__dict__)
if isinstance(obj, Key):
return prune_dict(obj.__dict__)
if isinstance(obj, Display):
return prune_dict(obj.__dict__)
if isinstance(obj, CFS):
return prune_dict(obj.__dict__)
if isinstance(obj, Misc):
return prune_dict(obj.__dict__)
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, obj)
@@ -89,5 +98,14 @@ def parse_defines(filename, target):
trims = parse_trims(hw_defs)
out_defs["trims"] = trims
display = parse_lcd(hw_defs)
out_defs["display"] = display
cfs = parse_cfs(hw_defs)
out_defs["custom_switches"] = cfs
misc = parse_misc(hw_defs)
out_defs["hardware"] = misc
print(json.dumps(out_defs, cls=DictEncoder, indent=2))
+60
View File
@@ -0,0 +1,60 @@
class Display:
def __init__(self, w, h, phys_w, phys_h, depth, color, oled, bl_color):
self.w = w
self.h = h
self.phys_w = phys_w
self.phys_h = phys_h
self.depth = depth
self.color = color
self.oled = oled
self.backlight_color = bl_color
def parse_lcd(hw_defs):
fw = f'LCD_W'
fh = f'LCD_H'
fphys_w = f'LCD_PHYS_W'
fphys_h = f'LCD_PHYS_H'
fdepth = f'LCD_DEPTH'
foled = f'OLED_SCREEN'
fbl_color = f'HAS_BACKLIGHT_COLOR'
w = hw_defs[fw]
h = hw_defs[fh]
if fphys_w in hw_defs:
phys_w = hw_defs[fphys_w]
else:
phys_w = w
if fphys_h in hw_defs:
phys_h = hw_defs[fphys_h]
else:
phys_h = h
depth = hw_defs[fdepth]
if phys_w == fw:
phys_w = w
if phys_w == fh:
phys_w = h
if phys_h == fh:
phys_h = h
if phys_h == fw:
phys_h = w
if foled in hw_defs:
oled = 1
else:
oled = 0
if depth < 16:
color = 0
else:
color = 1
if fbl_color in hw_defs:
bl_color = 1
else:
bl_color = 0
return Display(w, h, phys_w, phys_h, depth, color, oled, bl_color)
+44
View File
@@ -0,0 +1,44 @@
class Misc:
def __init__(self, has_audio_mute, has_bling_leds, has_ext_module_support, has_int_module_support, sport_max_baudrate, surface):
self.has_audio_mute = has_audio_mute
self.has_bling_leds = has_bling_leds
self.has_ext_module_support = has_ext_module_support
self.has_int_module_support = has_int_module_support
self.sport_max_baudrate = sport_max_baudrate
self.surface = surface
def parse_misc(hw_defs):
if f'RADIO_MT12' in hw_defs:
surface = 1
else:
surface = 0
if f'SPORT_MAX_BAUDRATE' in hw_defs:
sport_max_baudrate = hw_defs[f'SPORT_MAX_BAUDRATE']
else:
sport_max_baudrate = 400000
if f'AUDIO_MUTE_GPIO' in hw_defs:
has_audio_mute = 1
else:
has_audio_mute = 0
if f'BLING_LED_STRIP_LENGTH' in hw_defs:
has_bling_leds = hw_defs[f'BLING_LED_STRIP_LENGTH']
else:
has_bling_leds = 0
if f'RADIO_T8' in hw_defs:
has_ext_module_support = 0
else:
has_ext_module_support = 1
if f'PCBX9D' in hw_defs or f'PCBX9DP' in hw_defs or f'PCBX9E' in hw_defs:
has_int_module_support = 0
else:
has_int_module_support = 1
return Misc(has_audio_mute, has_bling_leds, has_ext_module_support, has_int_module_support, sport_max_baudrate, surface)