From d7f1fcef9caf9607d16ce8f046cbf77f8e00992b Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 8 Aug 2024 11:55:35 +0800 Subject: [PATCH 01/13] Initial PL18U support --- fw.json | 1 + .../targets/common/arm/stm32/sdram_driver.cpp | 32 +++- radio/src/targets/pl18/CMakeLists.txt | 22 ++- radio/src/targets/pl18/battery_driver.cpp | 2 + radio/src/targets/pl18/battery_driver.h | 10 +- radio/src/targets/pl18/board.h | 14 +- radio/src/targets/pl18/hal.h | 160 +++++++++++++----- radio/src/targets/pl18/key_driver.cpp | 157 +++++++++++------ radio/src/targets/pl18/usb_descriptor.h | 6 +- radio/util/hw_defs/legacy_names.py | 4 +- radio/util/hw_defs/pot_config.py | 7 + radio/util/hw_defs/switch_config.py | 10 ++ tools/build-common.sh | 3 + tools/build-companion.sh | 2 +- tools/build-flysky.py | 1 + 15 files changed, 311 insertions(+), 120 deletions(-) diff --git a/fw.json b/fw.json index 76022a0ed08..b21ca7276c5 100644 --- a/fw.json +++ b/fw.json @@ -5,6 +5,7 @@ ["Flysky NV14", "nv14-"], ["Flysky PL18", "pl18-"], ["Flysky PL18EV", "pl18ev-"], + ["Flysky PL18U", "pl18u-"], ["Flysky NB4+", "nb4p-"], ["Flysky ST16", "st16-"], ["FrSky Horus X10", "x10-"], diff --git a/radio/src/targets/common/arm/stm32/sdram_driver.cpp b/radio/src/targets/common/arm/stm32/sdram_driver.cpp index d011ef8a15c..31d6057e527 100644 --- a/radio/src/targets/common/arm/stm32/sdram_driver.cpp +++ b/radio/src/targets/common/arm/stm32/sdram_driver.cpp @@ -66,10 +66,10 @@ extern "C" void SDRAM_GPIOConfig(void) +-------------------+--------------------+--------------------+--------------------+ | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | - | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG8 <-> FMC_SDCLK | - | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS | - | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 |--------------------+ - | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | + | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG2 <-> FMC_A12 | + | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG8 <-> FMC_SDCLK | + | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 | PG15 <-> FMC_NCAS | + | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 |--------------------+ | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS | +-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 | | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 | @@ -140,6 +140,10 @@ extern "C" void SDRAM_GPIOConfig(void) gpio_init_af(GPIO_PIN(GPIOG, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); gpio_init_af(GPIO_PIN(GPIOG, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); gpio_init_af(GPIO_PIN(GPIOG, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + +#if defined(SDRAM_32MB) + gpio_init_af(GPIO_PIN(GPIOG, 2), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); +#endif } void SDRAM_InitSequence(void) @@ -209,10 +213,17 @@ void SDRAM_InitSequence(void) FMC_SDRAM_SendCommand(FMC_SDRAM_DEVICE, &FMC_SDRAMCommandStructure, 10); /* Step 8: Set the refresh rate counter - refer to section SDRAM refresh timer register in RM0455 */ +#if defined(SDRAM_32MB) + /* Set the device refresh rate + * COUNT = [(SDRAM self refresh time / number of row) x SDRAM CLK] - 20 + = [(64ms/8192) * 84MHz] - 20 = 656 - 20 ~ 636 */ + FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_DEVICE, 636); +#else /* Set the device refresh rate - * COUNT = [(SDRAM self refresh time / number of row) x SDRAM CLK] – 20 + * COUNT = [(SDRAM self refresh time / number of row) x SDRAM CLK] - 20 = [(64ms/4096) * 84MHz] - 20 = 1312 - 20 ~ 1292 */ FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_DEVICE, 1292); +#endif /* Wait until the SDRAM controller is ready */ while((__FMC_SDRAM_GET_FLAG(FMC_SDRAM_DEVICE, FMC_SDRAM_FLAG_BUSY) != 0)); } @@ -251,10 +262,17 @@ extern "C" void SDRAM_Init(void) /* FMC SDRAM control configuration */ FMC_SDRAMInitStructure.SDBank = SDRAM_BANK; - /* Row addressing: [7:0] */ +#if defined(SDRAM_32MB) + /* Column addressing: [8:0] */ + FMC_SDRAMInitStructure.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; + /* Row addressing: [12:0] */ + FMC_SDRAMInitStructure.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; +#else + /* Column addressing: [7:0] */ FMC_SDRAMInitStructure.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; - /* Column addressing: [11:0] */ + /* Row addressing: [11:0] */ FMC_SDRAMInitStructure.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; +#endif FMC_SDRAMInitStructure.MemoryDataWidth = SDRAM_MEMORY_WIDTH; FMC_SDRAMInitStructure.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; FMC_SDRAMInitStructure.CASLatency = SDRAM_CAS_LATENCY; diff --git a/radio/src/targets/pl18/CMakeLists.txt b/radio/src/targets/pl18/CMakeLists.txt index ad02c18eac4..77298d67c02 100644 --- a/radio/src/targets/pl18/CMakeLists.txt +++ b/radio/src/targets/pl18/CMakeLists.txt @@ -27,7 +27,12 @@ set(CPU_TYPE_FULL STM32F429xI) set(TARGET_LINKER_DIR stm32f429_sdram) set(TARGET_EXTRAM_START 0xC0000000) -set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192") +if(PCBREV STREQUAL PL18U) + set(TARGET_SDRAM_SIZE 32768K) + set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=32768") +else() + set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192") +endif() set(RF_BAUD_RATE 921600 230400 115200 57600 38400 19200 9600 4800 2400 1200) set(PCB_RF_BAUD 921600 CACHE STRING "INTERNAL_MODULE_BAUDRATE: ${RF_BAUD_RATE}") @@ -37,7 +42,20 @@ add_definitions(-DPCBPL18 -DPCBFLYSKY) add_definitions(-DBATTERY_CHARGE) add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS) -if (PCBREV STREQUAL EL18) +if(PCBREV STREQUAL PL18U) + set(FLAVOUR pl18u) + add_definitions(-DRADIO_PL18U -DUSE_HATS_AS_KEYS) + set(DISK_CACHE ON) + set(WIRELESS_CHARGER YES) + set(FLYSKY_GIMBAL ON) + set(LED_STRIP ON) + set(USE_VS1053B ON) + set(KEY_DRIVER key_driver.cpp) + + # Defines internal module for PL18U + set(INTERNAL_MODULES AFHDS3;CRSF CACHE STRING "Internal modules") + set(DEFAULT_INTERNAL_MODULE FLYSKY_AFHDS3 CACHE STRING "Default internal module") +elseif (PCBREV STREQUAL EL18) set(FLAVOUR el18) add_definitions(-DRADIO_EL18 -DRADIO_NV14_FAMILY -DPCBNV14 -DUSE_HATS_AS_KEYS) set(DISK_CACHE ON) diff --git a/radio/src/targets/pl18/battery_driver.cpp b/radio/src/targets/pl18/battery_driver.cpp index 399f2c0eddb..a59aca0196a 100644 --- a/radio/src/targets/pl18/battery_driver.cpp +++ b/radio/src/targets/pl18/battery_driver.cpp @@ -286,7 +286,9 @@ void battery_charge_init() #if defined(WIRELESS_CHARGER) // Wireless charger control pins gpio_init(WCHARGER_EN_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); +#if defined(WCHARGER_I_CONTROL_GPIO) gpio_init(WCHARGER_I_CONTROL_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); +#endif // defined(WCHARGER_I_CONTROL_GPIO) // Wireless charger state init ENABLE_WCHARGER(); diff --git a/radio/src/targets/pl18/battery_driver.h b/radio/src/targets/pl18/battery_driver.h index a03ac70d6e6..1a4310c37a8 100644 --- a/radio/src/targets/pl18/battery_driver.h +++ b/radio/src/targets/pl18/battery_driver.h @@ -46,8 +46,14 @@ enum ChargeState #define IS_WCHARGER_CHARGE_END_ACTIVE() gpio_read(WCHARGER_CHARGE_END_GPIO) ? 1 : 0 #define ENABLE_WCHARGER() gpio_set(WCHARGER_EN_GPIO) #define DISABLE_WCHARGER() gpio_clear(WCHARGER_EN_GPIO) -#define WCHARGER_CURRENT_LOW() gpio_set(WCHARGER_I_CONTROL_GPIO) -#define WCHARGER_CURRENT_HIGH() gpio_clear(WCHARGER_I_CONTROL_GPIO) + +#if defined(WCHARGER_I_CONTROL_GPIO) + #define WCHARGER_CURRENT_LOW() gpio_set(WCHARGER_I_CONTROL_GPIO) + #define WCHARGER_CURRENT_HIGH() gpio_clear(WCHARGER_I_CONTROL_GPIO) +#else + #define WCHARGER_CURRENT_LOW() + #define WCHARGER_CURRENT_HIGH() +#endif extern void battery_charge_init(); extern void handle_battery_charge(uint32_t last_press_time); diff --git a/radio/src/targets/pl18/board.h b/radio/src/targets/pl18/board.h index d940caafe8c..64a216b7859 100644 --- a/radio/src/targets/pl18/board.h +++ b/radio/src/targets/pl18/board.h @@ -96,12 +96,12 @@ extern "C" void SDRAM_Init(); else \ gpio_set(INTMODULE_PWR_GPIO); \ } while (0) -#elif defined(RADIO_NB4P) +#elif defined(RADIO_NB4P) || defined(RADIO_PL18U) #define INTERNAL_MODULE_ON() gpio_clear(INTMODULE_PWR_GPIO) #define INTERNAL_MODULE_OFF() gpio_set(INTMODULE_PWR_GPIO); #else #define INTERNAL_MODULE_ON() gpio_set(INTMODULE_PWR_GPIO) - #define INTERNAL_MODULE_OFF() gpio_clear(INTMODULE_PWR_GPIO); + #define INTERNAL_MODULE_OFF() gpio_clear(INTMODULE_PWR_GPIO) #endif #define EXTERNAL_MODULE_ON() gpio_set(EXTMODULE_PWR_GPIO) @@ -109,19 +109,19 @@ extern "C" void SDRAM_Init(); #define EXTERNAL_MODULE_PWR_OFF EXTERNAL_MODULE_OFF #define BLUETOOTH_MODULE_ON() gpio_clear(BLUETOOTH_ON_GPIO) #define BLUETOOTH_MODULE_OFF() gpio_set(BLUETOOTH_ON_GPIO) -#define IS_INTERNAL_MODULE_ON() (false) -#define IS_EXTERNAL_MODULE_ON() (gpio_read(EXTMODULE_PWR_GPIO) ? 1 : 0) +//#define IS_INTERNAL_MODULE_ON() (false) +//#define IS_EXTERNAL_MODULE_ON() (gpio_read(EXTMODULE_PWR_GPIO) ? 1 : 0) #else // defined(SIMU) -#define INTERNAL_MODULE_OFF() #define INTERNAL_MODULE_ON() +#define INTERNAL_MODULE_OFF() #define EXTERNAL_MODULE_ON() #define EXTERNAL_MODULE_OFF() #define BLUETOOTH_MODULE_ON() #define BLUETOOTH_MODULE_OFF() -#define IS_INTERNAL_MODULE_ON() (false) -#define IS_EXTERNAL_MODULE_ON() (false) +//#define IS_INTERNAL_MODULE_ON() (false) +//#define IS_EXTERNAL_MODULE_ON() (false) #endif // defined(SIMU) diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index 88f4f42674a..a0b74d69c84 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -284,25 +284,39 @@ #define TRIMS_GPIO_REG_T8U #define TRIMS_GPIO_PIN_T8U -#define TRIMS_GPIO_REG_TR1U GPIOH->IDR -#define TRIMS_GPIO_PIN_TR1U LL_GPIO_PIN_8 // PH.08 -#define TRIMS_GPIO_REG_TR1D GPIOH->IDR -#define TRIMS_GPIO_PIN_TR1D LL_GPIO_PIN_9 // PH.09 -#define TRIMS_GPIO_REG_TR2U GPIOH->IDR -#define TRIMS_GPIO_PIN_TR2U LL_GPIO_PIN_10 // PH.10 -#define TRIMS_GPIO_REG_TR2D GPIOH->IDR -#define TRIMS_GPIO_PIN_TR2D LL_GPIO_PIN_11 // PH.11 +#if !defined(RADIO_PL18U) + #define TRIMS_GPIO_REG_TR1U GPIOH->IDR + #define TRIMS_GPIO_PIN_TR1U LL_GPIO_PIN_8 // PH.08 + #define TRIMS_GPIO_REG_TR1D GPIOH->IDR + #define TRIMS_GPIO_PIN_TR1D LL_GPIO_PIN_9 // PH.09 + #define TRIMS_GPIO_REG_TR2U GPIOH->IDR + #define TRIMS_GPIO_PIN_TR2U LL_GPIO_PIN_10 // PH.10 + #define TRIMS_GPIO_REG_TR2D GPIOH->IDR + #define TRIMS_GPIO_PIN_TR2D LL_GPIO_PIN_11 // PH.11 +#endif // active 4x4 column/row based key-matrix to support up to 16 buttons with only 8 GPIOs -#define TRIMS_GPIO_OUT1 GPIOG -#define TRIMS_GPIO_OUT1_PIN LL_GPIO_PIN_2 // PG.02 +#if defined(RADIO_PL18U) + #define TRIMS_GPIO_OUT1 GPIOI + #define TRIMS_GPIO_OUT1_PIN LL_GPIO_PIN_2 // PI.02 +#else + #define TRIMS_GPIO_OUT1 GPIOG + #define TRIMS_GPIO_OUT1_PIN LL_GPIO_PIN_2 // PG.02 +#endif + #define TRIMS_GPIO_OUT2 GPIOG #define TRIMS_GPIO_OUT2_PIN LL_GPIO_PIN_10 // PG.10 #define TRIMS_GPIO_OUT3 GPIOG #define TRIMS_GPIO_OUT3_PIN LL_GPIO_PIN_11 // PG.11 + +#if defined(RADIO_PL18U) + #define TRIMS_GPIO_OUT4 GPIOH + #define TRIMS_GPIO_OUT4_PIN LL_GPIO_PIN_10 // PH.10 +#endif + // OUT4 routed on MCU PCB, but not attached to any physical buttons, free to use for extensions -#define TRIMS_GPIO_OUT4 GPIOH -#define TRIMS_GPIO_OUT4_PIN LL_GPIO_PIN_7 // PH.07 +//#define TRIMS_GPIO_OUT4 GPIOH +//#define TRIMS_GPIO_OUT4_PIN LL_GPIO_PIN_7 // PH.07 #define TRIMS_GPIO_REG_IN1 GPIOB->IDR #define TRIMS_GPIO_PIN_IN1 LL_GPIO_PIN_15 // PB.15 @@ -322,15 +336,21 @@ #define KEYS_GPIOD_PINS (LL_GPIO_PIN_7) -#define KEYS_GPIOH_PINS \ - (LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11) +#if !defined(RADIO_PL18U) + #define KEYS_GPIOH_PINS \ + (LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11) +#endif #define KEYS_GPIOJ_PINS (LL_GPIO_PIN_12) -#define KEYS_OUT_GPIOG_PINS (LL_GPIO_PIN_2 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11) - -#define KEYS_OUT_GPIOH_PINS (LL_GPIO_PIN_7) - +#if defined(RADIO_PL18U) + #define KEYS_OUT_GPIOG_PINS (LL_GPIO_PIN_10 | LL_GPIO_PIN_11) + #define KEYS_OUT_GPIOH_PINS (LL_GPIO_PIN_10) + #define KEYS_OUT_GPIOI_PINS (LL_GPIO_PIN_2) +#else + #define KEYS_OUT_GPIOG_PINS (LL_GPIO_PIN_2 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11) + #define KEYS_OUT_GPIOH_PINS (LL_GPIO_PIN_7) +#endif // Monitor pin // #define MONITOR_RCC_AHB1Periph (RCC_AHB1Periph_GPIOJ) @@ -344,13 +364,15 @@ // Especially, as on current dev. state, using PC8 for SDIO D0. // (happy coincidence ;) // -// #define SWITCHES_GPIO_REG_A_H GPIOC -// #define SWITCHES_GPIO_PIN_A_H LL_GPIO_PIN_8 // PC.08 -// #define SWITCHES_GPIO_REG_A_L GPIOC -// #define SWITCHES_GPIO_PIN_A_L LL_GPIO_PIN_9 // PC.09 - -#define SWITCHES_GPIO_REG_A GPIOC -#define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_9 // PC.09 +#if defined(RADIO_PL18U) + #define SWITCHES_GPIO_REG_A_H GPIOD + #define SWITCHES_GPIO_PIN_A_H LL_GPIO_PIN_3 // PD.03 + #define SWITCHES_GPIO_REG_A_L GPIOB + #define SWITCHES_GPIO_PIN_A_L LL_GPIO_PIN_6 // PB.06 +#else + #define SWITCHES_GPIO_REG_A GPIOC + #define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_9 // PC.09 +#endif // High rail of Switch C is not required and thus PC10 is free to use for // customizations. @@ -360,8 +382,15 @@ // #define SWITCHES_GPIO_REG_C_L GPIOC // #define SWITCHES_GPIO_PIN_C_L LL_GPIO_PIN_11 // PC.11 -#define SWITCHES_GPIO_REG_C GPIOC -#define SWITCHES_GPIO_PIN_C LL_GPIO_PIN_11 // PC.11 +#if defined(RADIO_PL18U) + #define SWITCHES_GPIO_REG_C_H GPIOJ + #define SWITCHES_GPIO_PIN_C_H LL_GPIO_PIN_14 // PJ.14 + #define SWITCHES_GPIO_REG_C_L GPIOH + #define SWITCHES_GPIO_PIN_C_L LL_GPIO_PIN_2 // PH.02 +#else + #define SWITCHES_GPIO_REG_C GPIOC + #define SWITCHES_GPIO_PIN_C LL_GPIO_PIN_11 // PC.11 +#endif // ADC @@ -471,6 +500,20 @@ 0, /* SWG */ \ 0 /* SWH */ \ } +#elif defined(RADIO_PL18U) +#define ADC_DIRECTION { \ + 0,0,0,0, /* gimbals */ \ + 0,0,0, /* pots */ \ + -1,-1, /* sliders */ \ + 0, /* vbat */ \ + 0, /* rtc_bat */ \ + -1, /* SWB */ \ + 0, /* SWD */ \ + -1, /* SWE */ \ + 0, /* SWF */ \ + -1, /* SWG */ \ + 0 /* SWH */ \ + } #else #define ADC_DIRECTION { \ 0,0,0,0, /* gimbals */ \ @@ -497,7 +540,7 @@ #define UCHARGER_GPIO GPIO_PIN(GPIOB, 14) // PB.14 input #define UCHARGER_CHARGE_END_GPIO GPIO_PIN(GPIOB, 13) // PB.13 input -#if defined(RADIO_PL18) || defined(RADIO_PL18EV) +#if defined(RADIO_PL18) || defined(RADIO_PL18EV) || defined(RADIO_PL18U) #define UCHARGER_EN_GPIO GPIO_PIN(GPIOG, 3) // PG.03 output #elif defined(RADIO_NV14_FAMILY) #define UCHARGER_EN_GPIO GPIO_PIN(GPIOH, 11) // PH.11 output @@ -505,11 +548,17 @@ #endif #if defined (WIRELESS_CHARGER) - #define WCHARGER_GPIO GPIO_PIN(GPIOI, 9) // PI.09 input - #define WCHARGER_CHARGE_END_GPIO GPIO_PIN(GPIOI, 10) // PI.10 input - #define WCHARGER_EN_GPIO GPIO_PIN(GPIOH, 4) // PH.04 output - #define WCHARGER_I_CONTROL_GPIO GPIO_PIN(GPIOH, 13) // PH.13 output -#endif + #define WCHARGER_GPIO GPIO_PIN(GPIOI, 9) // PI.09 input + #if defined(RADIO_PL18U) + #define WCHARGER_CHARGE_END_GPIO GPIO_PIN(GPIOB, 13) // PB.13 input + #else + #define WCHARGER_CHARGE_END_GPIO GPIO_PIN(GPIOI, 10) // PI.10 input + #endif + #define WCHARGER_EN_GPIO GPIO_PIN(GPIOH, 4) // PH.04 output + #if defined(RADIO_PL18) || defined(RADIO_PL18EV) + #define WCHARGER_I_CONTROL_GPIO GPIO_PIN(GPIOH, 13) // PH.13 output + #endif +#endif // defined(WIRELESS_CHARGER) // TODO! Check IOLL1 to PI.01 connectivity! @@ -586,12 +635,14 @@ #define USB_GPIO_AF GPIO_AF10 #if defined(RADIO_NV14_FAMILY) -#define USB_GPIO_VBUS GPIO_PIN(GPIOA, 9) // PA.09 -#define USB_SW_GPIO GPIO_PIN(GPIOI, 10) // PI.10 + #define USB_GPIO_VBUS GPIO_PIN(GPIOA, 9) // PA.09 + #define USB_SW_GPIO GPIO_PIN(GPIOI, 10) // PI.10 +#elif defined(RADIO_PL18U) + #define USB_SW_GPIO GPIO_PIN(GPIOI, 5) // PI.05 #endif // LCD -#define LCD_NRST_GPIO GPIO_PIN(GPIOG, 9) // PG.09 +#define LCD_NRST_GPIO GPIO_PIN(GPIOG, 9) // PG.09 #define LCD_SPI_CS_GPIO GPIO_PIN(GPIOE, 4) // PE.04 #define LCD_SPI_SCK_GPIO GPIO_PIN(GPIOE, 2) // PE.02 #define LCD_SPI_MISO_GPIO GPIO_PIN(GPIOE, 5) // PE.05 @@ -631,9 +682,13 @@ #define ROTARY_ENCODER_TIMER_IRQHandler TIM8_UP_TIM13_IRQHandler #endif -#if defined(RADIO_NV14_FAMILY) +#if defined(RADIO_NV14_FAMILY) || defined(RADIO_PL18U) // SD card - #define SD_PRESENT_GPIO GPIO_PIN(GPIOH, 10) // PH.10 + #if defined(RADIO_PL18U) + #define SD_PRESENT_GPIO GPIO_PIN(GPIOH, 11) // PH.11 + #else + #define SD_PRESENT_GPIO GPIO_PIN(GPIOH, 10) // PH.10 + #endif #define SD_SDIO_DMA DMA2 #define SD_SDIO_DMA_STREAM DMA2_Stream3 #define SD_SDIO_DMA_CHANNEL LL_DMA_CHANNEL_4 @@ -655,7 +710,7 @@ #define FLASH_SPI_DMA_TX_STREAM LL_DMA_STREAM_5 #define FLASH_SPI_DMA_RX_STREAM LL_DMA_STREAM_6 -#if defined(RADIO_NV14_FAMILY) +#if defined(RADIO_NV14_FAMILY) || defined(RADIO_PL18U) #define STORAGE_USE_SDIO #else #define STORAGE_USE_SPI_FLASH @@ -666,7 +721,7 @@ #define SDRAM_RCC_AHB3Periph RCC_AHB3Periph_FMC // Audio -#if defined(RADIO_NV14_FAMILY) +#if defined(RADIO_NV14_FAMILY) || defined(RADIO_PL18U) #define AUDIO_XDCS_GPIO GPIO_PIN(GPIOH, 14) // PH.14 #define AUDIO_CS_GPIO GPIO_PIN(GPIOH, 13) // PH.13 #define AUDIO_DREQ_GPIO GPIO_PIN(GPIOH, 15) // PH.15 @@ -685,7 +740,12 @@ #define AUDIO_DMA DMA1 #endif -#if defined(RADIO_NV14_FAMILY) +#if defined(RADIO_PL18U) + #define AUDIO_MUTE_GPIO GPIO_PIN(GPIOI, 10) // PI.10 audio amp control pin + #define AUDIO_UNMUTE_DELAY 120 // ms + #define AUDIO_MUTE_DELAY 500 // ms + #define INVERTED_MUTE_PIN +#elif defined(RADIO_NV14_FAMILY) #define AUDIO_MUTE_GPIO GPIO_PIN(GPIOH, 8) // PH.08 audio amp control pin #define AUDIO_UNMUTE_DELAY 120 // ms #define AUDIO_MUTE_DELAY 500 // ms @@ -774,8 +834,12 @@ #endif // Internal Module -#if defined(RADIO_PL18) - #define INTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 0) // PI.00 +#if defined(RADIO_PL18) || defined(RADIO_PL18U) + #if defined(RADIO_PL18U) + #define INTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 3) // PI.03 + #else + #define INTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 0) // PI.00 + #endif #define INTMODULE_TX_GPIO GPIO_PIN(GPIOF, 7) // PF.07 #define INTMODULE_RX_GPIO GPIO_PIN(GPIOF, 6) // PF.06 #define INTMODULE_USART UART7 @@ -844,7 +908,11 @@ // External Module #define EXTMODULE #define EXTMODULE_PULSES -#define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOD, 11) // PD.11 +#if defined(RADIO_PL18U) + #define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 1) // PI.01 +#else + #define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOD, 11) // PD.11 +#endif #if defined(RADIO_NV14_FAMILY) #define EXTMODULE_PWR_FIX_GPIO GPIO_PIN(GPIOA, 2) // PA.02 #endif @@ -937,7 +1005,11 @@ // SDRAM #define SDRAM_BANK1 +#if defined(RADIO_PL18U) + #define SDRAM_32MB +#endif +// LCD Settings #if defined(RADIO_NB4P) || defined(RADIO_NV14_FAMILY) #define LCD_W 320 #define LCD_H 480 diff --git a/radio/src/targets/pl18/key_driver.cpp b/radio/src/targets/pl18/key_driver.cpp index 89f39913692..f86a4992781 100644 --- a/radio/src/targets/pl18/key_driver.cpp +++ b/radio/src/targets/pl18/key_driver.cpp @@ -28,43 +28,65 @@ #include "delays_driver.h" #include "keys.h" -/* The output bit-order has to be: - 0 LHL TR7L (Left equals down) - 1 LHR TR7R - 2 LVD TR5D - 3 LVU TR5U - 4 RVD TR6D - 5 RVU TR6U - 6 RHL TR8L - 7 RHR TR8R - 8 LSD TR1D - 9 LSU TR1U - 10 RSD TR2D - 11 RSU TR2U - 12 EX1D TR3D - 13 EX1U TR3U - 14 EX2D TR4D - 15 EX2U TR4U + + +/* The output bit-order has to be (D = L, U = R): + PL18 PL18U + 0 LHL TR7D(L) TR5D(L) + 1 LHR TR7U(R) TR5U(R) + 2 LVD TR5D TR3D + 3 LVU TR5U TR3U + 4 RVD TR6D TR4D + 5 RVU TR6U TR4U + 6 RHL TR8D(L) TR6D(L) + 7 RHR TR8U(R) TR6U(R) + 8 LSD TR1D TR1D + 9 LSU TR1U TR1U + 10 RSD TR2D TR2D + 11 RSU TR2U TR2U + 12 EX1D TR3D TR7D + 13 EX1U TR3U TR7U + 14 EX2D TR4D TR8D + 15 EX2U TR4U TR8U */ enum PhysicalTrims { - TR7L = 0, - TR7R, - TR5D = 2, - TR5U, - TR6D = 4, - TR6U, - TR8L = 6, - TR8R, - TR1D = 8, - TR1U, - TR2D = 10, - TR2U, - TR3D = 12, - TR3U, - TR4D = 14, - TR4U, +#if defined(RADIO_PL18U) + TR5D = 0, + TR5U, + TR3D = 2, + TR3U, + TR4D = 4, + TR4U, + TR6D = 6, + TR6U, + TR1D = 8, + TR1U, + TR2D = 10, + TR2U, + TR7D = 12, + TR7U, + TR8D = 14, + TR8U, +#else + TR7D = 0, + TR7U, + TR5D = 2, + TR5U, + TR6D = 4, + TR6U, + TR8D = 6, + TR8U, + TR1D = 8, + TR1U, + TR2D = 10, + TR2U, + TR3D = 12, + TR3U, + TR4D = 14, + TR4U, +#endif }; void keysInit() @@ -74,12 +96,15 @@ void keysInit() stm32_gpio_enable_clock(GPIOD); stm32_gpio_enable_clock(GPIOG); stm32_gpio_enable_clock(GPIOH); +#if defined(RADIO_PL18U) + stm32_gpio_enable_clock(GPIOI); +#endif stm32_gpio_enable_clock(GPIOJ); LL_GPIO_InitTypeDef pinInit; LL_GPIO_StructInit(&pinInit); pinInit.Mode = LL_GPIO_MODE_INPUT; - pinInit.Pull = LL_GPIO_PULL_DOWN; + pinInit.Pull = LL_GPIO_PULL_NO; pinInit.Pin = KEYS_GPIOB_PINS; LL_GPIO_Init(GPIOB, &pinInit); @@ -90,21 +115,30 @@ void keysInit() pinInit.Pin = KEYS_GPIOD_PINS; LL_GPIO_Init(GPIOD, &pinInit); +#if defined(KEYS_GPIOH_PINS) pinInit.Pin = KEYS_GPIOH_PINS; LL_GPIO_Init(GPIOH, &pinInit); +#endif pinInit.Pin = KEYS_GPIOJ_PINS; LL_GPIO_Init(GPIOJ, &pinInit); // Matrix outputs pinInit.Mode = LL_GPIO_MODE_OUTPUT; - pinInit.Pull = LL_GPIO_PULL_NO; + pinInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL; pinInit.Pin = KEYS_OUT_GPIOG_PINS; LL_GPIO_Init(GPIOG, &pinInit); +#if defined(KEYS_OUT_GPIOH_PINS) pinInit.Pin = KEYS_OUT_GPIOH_PINS; LL_GPIO_Init(GPIOH, &pinInit); +#endif + +#if defined(KEYS_OUT_GPIOI_PINS) + pinInit.Pin = KEYS_OUT_GPIOI_PINS; + LL_GPIO_Init(GPIOI, &pinInit); +#endif } static uint32_t _readKeyMatrix() @@ -112,19 +146,6 @@ static uint32_t _readKeyMatrix() // This function avoids concurrent matrix agitation uint32_t result = 0; - /* Bit 0 - TR3 down - * Bit 1 - TR3 up - * Bit 2 - TR4 down - * Bit 3 - TR4 up - * Bit 4 - TR5 down - * Bit 5 - TR5 up - * Bit 6 - TR6 down - * Bit 7 - TR6 up - * Bit 8 - TR7 left - * Bit 9 - TR7 right - * Bit 10 - TR8 left - * Bit 11 - TR8 right - */ volatile static struct { @@ -144,12 +165,16 @@ static uint32_t _readKeyMatrix() LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN); LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN); LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); + +#if defined(TRIMS_GPIO_OUT4) LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); +#endif + delay_us(10); if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) - result |= 1 << TR7L; + result |= 1 << TR7D; if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) - result |= 1 << TR7R; + result |= 1 << TR7U; if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) result |= 1 << TR5D; if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) @@ -175,12 +200,26 @@ static uint32_t _readKeyMatrix() if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) result |= 1 << TR6D; if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) - result |= 1 << TR8L; + result |= 1 << TR8D; if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) - result |= 1 << TR8R; + result |= 1 << TR8U; LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); +#if defined(TRIMS_GPIO_OUT4) + LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); + delay_us(10); + if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) + result |= 1 << TR1U; + if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) + result |= 1 << TR1D; + if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) + result |= 1 << TR2D; + if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) + result |= 1 << TR2U; + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); +#endif + syncelem.oldResult = result; syncelem.ui8ReadInProgress = 0; @@ -193,8 +232,13 @@ uint32_t readKeys() if (getHatsAsKeys()) { uint32_t mkeys = _readKeyMatrix(); +#if defined(RADIO_PL18U) + if (mkeys & (1 << TR2D)) result |= 1 << KEY_ENTER; + if (mkeys & (1 << TR2U)) result |= 1 << KEY_EXIT; +#else if (mkeys & (1 << TR4D)) result |= 1 << KEY_ENTER; if (mkeys & (1 << TR4U)) result |= 1 << KEY_EXIT; +#endif } return result; @@ -206,15 +250,22 @@ uint32_t readTrims() result |= _readKeyMatrix(); +#if defined(TRIMS_GPIO_REG_TR1U) if (~TRIMS_GPIO_REG_TR1U & TRIMS_GPIO_PIN_TR1U) result |= 1 << (TR1U); +#endif +#if defined(TRIMS_GPIO_REG_TR1D) if (~TRIMS_GPIO_REG_TR1D & TRIMS_GPIO_PIN_TR1D) result |= 1 << (TR1D); - +#endif +#if defined(TRIMS_GPIO_REG_TR2U) if (~TRIMS_GPIO_REG_TR2U & TRIMS_GPIO_PIN_TR2U) result |= 1 << (TR2U); +#endif +#if defined(TRIMS_GPIO_REG_TR2D) if (~TRIMS_GPIO_REG_TR2D & TRIMS_GPIO_PIN_TR2D) result |= 1 << (TR2D); +#endif return result; } diff --git a/radio/src/targets/pl18/usb_descriptor.h b/radio/src/targets/pl18/usb_descriptor.h index 43e3fe62542..71fa32dd2d2 100644 --- a/radio/src/targets/pl18/usb_descriptor.h +++ b/radio/src/targets/pl18/usb_descriptor.h @@ -21,7 +21,11 @@ #pragma once -#if defined(RADIO_EL18) +#if defined(RADIO_PL18U) + #define USB_NAME "FlySky PL18Ultra" + #define USB_MANUFACTURER 'F', 'l', 'y', 'S', 'k', 'y', ' ', ' ' /* 8 bytes */ + #define USB_PRODUCT 'P', 'L', '1', '8', 'U', ' ', ' ', ' ' /* 8 Bytes */ +#elif defined(RADIO_EL18) #define USB_NAME "Flysky EL18" #define USB_MANUFACTURER 'F', 'l', 'y', 's', 'k', 'y', ' ', ' ' /* 8 bytes */ #define USB_PRODUCT 'E', 'L', '1', '8', ' ', ' ', ' ', ' ' /* 8 Bytes */ diff --git a/radio/util/hw_defs/legacy_names.py b/radio/util/hw_defs/legacy_names.py index d462a8864c4..484b06420c6 100644 --- a/radio/util/hw_defs/legacy_names.py +++ b/radio/util/hw_defs/legacy_names.py @@ -528,9 +528,7 @@ } }, { - "targets": { - "pl18" - }, + "targets": {"pl18", "pl18u"}, "inputs": { "LH": { "yaml": "Rud", diff --git a/radio/util/hw_defs/pot_config.py b/radio/util/hw_defs/pot_config.py index 0cd3bd22a8b..53c7a2df53c 100644 --- a/radio/util/hw_defs/pot_config.py +++ b/radio/util/hw_defs/pot_config.py @@ -38,6 +38,13 @@ "EXT3": {"default": "MULTIPOS"}, "EXT4": {"default": "MULTIPOS"} }, + "pl18u": { + "P1": {"default": "POT"}, + "P2": {"default": "POT"}, + "P3": {"default": "POT_CENTER"}, + "SL1": {"default": "SLIDER"}, + "SL2": {"default": "SLIDER"} + }, "nb4p": { "P1": {"default": "POT"}, "P2": {"default": "POT"} diff --git a/radio/util/hw_defs/switch_config.py b/radio/util/hw_defs/switch_config.py index b39616f09e7..c82e0e5633c 100644 --- a/radio/util/hw_defs/switch_config.py +++ b/radio/util/hw_defs/switch_config.py @@ -65,6 +65,16 @@ "SI": { "default": "3POS" }, "SJ": { "default": "3POS" } }, + "pl18u": { + "SA": { "default": "3POS" }, + "SB": { "default": "3POS" }, + "SC": { "default": "3POS" }, + "SD": { "default": "3POS" }, + "SE": { "default": "3POS" }, + "SF": { "default": "3POS" }, + "SG": { "default": "3POS" }, + "SH": { "default": "TOGGLE" } + }, "nb4p": { "SA" : { "default": "TOGGLE" }, "SB" : { "default": "TOGGLE" } diff --git a/tools/build-common.sh b/tools/build-common.sh index 49fc2d71641..3613f3d31ec 100644 --- a/tools/build-common.sh +++ b/tools/build-common.sh @@ -149,6 +149,9 @@ get_target_build_options() { pl18ev) BUILD_OPTIONS+="-DPCB=PL18 -DPCBREV=PL18EV" ;; + pl18u) + BUILD_OPTIONS+="-DPCB=PL18 -DPCBREV=PL18U" + ;; nb4p) BUILD_OPTIONS+="-DPCB=PL18 -DPCBREV=NB4P" ;; diff --git a/tools/build-companion.sh b/tools/build-companion.sh index 97e7f5fd7f9..a6c9147ee49 100755 --- a/tools/build-companion.sh +++ b/tools/build-companion.sh @@ -73,7 +73,7 @@ declare -a simulator_plugins=(x9lite x9lites tlite tpro tprov2 tpros bumblebee lr3pro t14 x9d x9dp x9dp2019 x9e xlite xlites - nv14 el18 pl18 pl18ev st16 + nv14 el18 pl18 pl18ev pl18u st16 x10 x10express x12s t15 t16 t18 t20 t20v2 tx16s f16 v16) diff --git a/tools/build-flysky.py b/tools/build-flysky.py index 832fd070e00..a8943398e06 100755 --- a/tools/build-flysky.py +++ b/tools/build-flysky.py @@ -13,6 +13,7 @@ "EL18": { "PCB": "PL18", "PCBREV": "EL18" }, "PL18": { "PCB": "PL18" }, "PL18EV": { "PCB": "PL18", "PCBREV": "PL18EV" }, + "PL18U": { "PCB": "PL18", "PCBREV": "PL18U" }, "ST16": { "PCB": "ST16" , "NANO": "NO" }, } From bfc36215eedad7b4ace3ab3ed11d7457f46cfca9 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 8 Aug 2024 13:23:23 +0800 Subject: [PATCH 02/13] Added touch keys event handling --- radio/src/targets/pl18/touch_driver.cpp | 43 ++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/radio/src/targets/pl18/touch_driver.cpp b/radio/src/targets/pl18/touch_driver.cpp index 52f5026e875..dcaa9abeb14 100644 --- a/radio/src/targets/pl18/touch_driver.cpp +++ b/radio/src/targets/pl18/touch_driver.cpp @@ -32,6 +32,7 @@ #include "timers_driver.h" #include "delays_driver.h" #include "touch_driver.h" +#include "keys.h" #include "debug.h" @@ -87,6 +88,20 @@ typedef enum {TC_NONE, TC_FT6236, TC_CST836U, TC_CST340, TC_CHSC5448} TouchContr const char TOUCH_CONTROLLER_STR[][10] = {"", "FT6236", "CST836U", "CST340", "CHSC5448"}; #endif +static uint8_t lastTouchKey = 0; +static bool eventFired = false; + +static const event_t TOUCHKEY_EVENTS[8] = { + KEY_EXIT | _MSK_KEY_BREAK, + KEY_MODEL | _MSK_KEY_BREAK, + KEY_MODEL | _MSK_KEY_LONG, + KEY_PAGEUP | _MSK_KEY_FIRST, + KEY_TELE | _MSK_KEY_BREAK, + KEY_PAGEDN | _MSK_KEY_FIRST, + KEY_SYS | _MSK_KEY_LONG, + KEY_ENTER | _MSK_KEY_BREAK, +}; + TouchController touchController = TC_NONE; enum TouchRotate @@ -320,8 +335,34 @@ static bool chsc5448TouchRead(uint16_t * X, uint16_t * Y) *X = ((ppt->rp.x_h4 & 0x0f) << 8) | ppt->rp.x_l8; *Y = ((ppt->rp.y_h4 & 0x0f) << 8) | ppt->rp.y_l8; uint8_t event = ppt->rp.event; + bool hasEvent = ptCnt > 0 && event == TOUCH_CHSC5448_EVT_CONTACT; + + // Touch keys returns X = 2600, Y = 1 to 8 (total 8 keys) + uint8_t currTouchKey = 0; + if (hasEvent && *X >= 2000) { + // Touch key event + currTouchKey = *Y; + if (currTouchKey > 8) { + currTouchKey = 8; + } + hasEvent = false; + } + +#if defined(DEBUG) + TRACE("%s: lastTouchKey=%d, currTouchKey=%d", TOUCH_CONTROLLER_STR[touchController], lastTouchKey, currTouchKey); +#endif + + if (currTouchKey != lastTouchKey) { + lastTouchKey = currTouchKey; + eventFired = false; + } else { + if (currTouchKey > 0 && !eventFired) { + pushEvent(TOUCHKEY_EVENTS[currTouchKey - 1]); + eventFired = true; + } + } - return ptCnt > 0 && event == TOUCH_CHSC5448_EVT_CONTACT; + return hasEvent; } static void chsc5448PrintDebugInfo() From 18306c1c7d940eda75d6349d7d04923b7045790b Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 8 Aug 2024 13:32:21 +0800 Subject: [PATCH 03/13] PL18U battery charging logic --- radio/src/targets/pl18/battery_driver.cpp | 67 ++++++++++++++++------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/radio/src/targets/pl18/battery_driver.cpp b/radio/src/targets/pl18/battery_driver.cpp index a59aca0196a..4772f4108ca 100644 --- a/radio/src/targets/pl18/battery_driver.cpp +++ b/radio/src/targets/pl18/battery_driver.cpp @@ -35,12 +35,25 @@ #define BATTERY_H_INNER (BATTERY_H - 2*BATTERY_BORDER) #define BATTERY_TOP_INNER (BATTERY_TOP + BATTERY_BORDER) -#define UCHARGER_SAMPLING_CNT 10 -#define UCHARGER_CHARGING_SAMPLING_CNT 10 -#define WCHARGER_SAMPLING_CNT 30 -#define WCHARGER_CHARGING_SAMPLING_CNT 10 -#define WCHARGER_LOW_CURRENT_DELAY_CNT 6000 -#define WCHARGER_HIGH_CURRENT_DELAY_CNT 24000 +#define UCHARGER_SAMPLING_CNT 10 +#if defined(RADIO_PL18U) + #define UCHARGER_CHARGING_SAMPLING_CNT 1 + #define UCHARGER_CHARGE_END_SAMPLING_CNT 250 +#else + #define UCHARGER_CHARGING_SAMPLING_CNT 10 + #define UCHARGER_CHARGE_END_SAMPLING_CNT 10 +#endif + +#define WCHARGER_SAMPLING_CNT 30 +#if defined(RADIO_PL18U) + #define WCHARGER_CHARGING_SAMPLING_CNT 1 + #define WCHARGER_CHARGE_END_SAMPLING_CNT 250 +#else + #define WCHARGER_CHARGING_SAMPLING_CNT 10 + #define WCHARGER_CHARGE_END_SAMPLING_CNT 10 +#endif +#define WCHARGER_LOW_CURRENT_DELAY_CNT 6000 +#define WCHARGER_HIGH_CURRENT_DELAY_CNT 24000 typedef struct { @@ -54,11 +67,12 @@ typedef struct uint8_t chargeEndSamplingCount; } STRUCT_BATTERY_CHARGER; -STRUCT_BATTERY_CHARGER uCharger; // USB charger +static STRUCT_BATTERY_CHARGER uCharger; // USB charger + #if defined(WIRELESS_CHARGER) -STRUCT_BATTERY_CHARGER wCharger; // Wireless charger -uint16_t wirelessLowCurrentDelay = 0; -uint16_t wirelessHighCurrentDelay = 0; + static STRUCT_BATTERY_CHARGER wCharger; // Wireless charger + static uint16_t wirelessLowCurrentDelay = 0; + static uint16_t wirelessHighCurrentDelay = 0; #endif void chargerDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargerPinActive, uint8_t samplingCountThreshold) @@ -87,7 +101,8 @@ void resetChargeEndDetection(STRUCT_BATTERY_CHARGER* charger) charger->isHighCurrent = false; } -void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinActive, uint8_t samplingCountThreshold) +void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinActive, + uint8_t chargingSamplingCountThreshold, uint8_t chargeEndSamplingCountThreshold) { if (charger->isChargeEnd) { @@ -101,7 +116,7 @@ void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinAct else { charger->chargeEndSamplingCount++; - if (charger->chargeEndSamplingCount >= samplingCountThreshold) + if (charger->chargeEndSamplingCount >= chargeEndSamplingCountThreshold) { charger->chargeEndSamplingCount = 0; charger->isChargingDetectionReady = true; @@ -112,7 +127,7 @@ void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinAct { charger->chargeEndSamplingCount = 0; charger->chargingSamplingCount++; - if (charger->chargingSamplingCount >= samplingCountThreshold) + if (charger->chargingSamplingCount >= chargingSamplingCountThreshold) { charger->chargingSamplingCount = 0; charger->isChargeEnd = false; @@ -132,7 +147,7 @@ void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinAct else { charger->chargingSamplingCount++; - if (charger->chargingSamplingCount >= samplingCountThreshold) + if (charger->chargingSamplingCount >= chargingSamplingCountThreshold) { charger->chargingSamplingCount = 0; charger->isChargingDetectionReady = true; @@ -143,7 +158,7 @@ void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinAct { charger->chargingSamplingCount = 0; charger->chargeEndSamplingCount++; - if (charger->chargeEndSamplingCount >= samplingCountThreshold) + if (charger->chargeEndSamplingCount >= chargeEndSamplingCountThreshold) { charger->chargeEndSamplingCount = 0; charger->isChargeEnd = true; @@ -162,8 +177,11 @@ uint16_t get_battery_charge_state() { if (uCharger.hasCharger) // USB charger can be detected properly no matter it is enabled or not { +#if defined(RADIO_PL18U) && defined(WIRELESS_CHARGER) + DISABLE_WCHARGER(); +#endif ENABLE_UCHARGER(); - chargeEndDetection(&uCharger, IS_UCHARGER_CHARGE_END_ACTIVE(), UCHARGER_CHARGING_SAMPLING_CNT); + chargeEndDetection(&uCharger, IS_UCHARGER_CHARGE_END_ACTIVE(), UCHARGER_CHARGING_SAMPLING_CNT, UCHARGER_CHARGE_END_SAMPLING_CNT); if (uCharger.isChargingDetectionReady) { if (uCharger.isChargeEnd) @@ -182,6 +200,9 @@ uint16_t get_battery_charge_state() // Disable USB charger if it is not present, so that wireless charger can be detected properly DISABLE_UCHARGER(); +#if defined(RADIO_PL18U) && defined(WIRELESS_CHARGER) + ENABLE_WCHARGER(); +#endif } } @@ -191,7 +212,7 @@ uint16_t get_battery_charge_state() { if (wCharger.hasCharger) // Wireless charger can only be detected when USB charger is disabled { - chargeEndDetection(&wCharger, IS_WCHARGER_CHARGE_END_ACTIVE(), WCHARGER_CHARGING_SAMPLING_CNT); + chargeEndDetection(&wCharger, IS_WCHARGER_CHARGE_END_ACTIVE(), WCHARGER_CHARGING_SAMPLING_CNT, WCHARGER_CHARGE_END_SAMPLING_CNT); if (wCharger.isChargingDetectionReady) { if (wCharger.isChargeEnd) @@ -234,7 +255,7 @@ uint16_t get_battery_charge_state() } } -#endif +#endif // defined(WIRELESS_CHARGER) return state; } @@ -268,8 +289,7 @@ void battery_charge_init() // Wireless charger status pins gpio_init(WCHARGER_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW); gpio_init(WCHARGER_CHARGE_END_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW); - -#endif +#endif // defined(WIRELESS_CHARGER) // USB charger control pins @@ -278,7 +298,11 @@ void battery_charge_init() #endif // USB charger state init +#if defined(RADIO_PL18U) + DISABLE_UCHARGER(); +#else ENABLE_UCHARGER(); +#endif // defined(RADIO_PL18U) uCharger.hasCharger = !IS_UCHARGER_ACTIVE(); // Init for sampling count works uCharger.isChargerDetectionReady = false; resetChargeEndDetection(&uCharger); @@ -286,6 +310,7 @@ void battery_charge_init() #if defined(WIRELESS_CHARGER) // Wireless charger control pins gpio_init(WCHARGER_EN_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); + #if defined(WCHARGER_I_CONTROL_GPIO) gpio_init(WCHARGER_I_CONTROL_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); #endif // defined(WCHARGER_I_CONTROL_GPIO) @@ -296,7 +321,7 @@ void battery_charge_init() wCharger.hasCharger = !IS_WCHARGER_ACTIVE(); // Init for sampling count works wCharger.isChargerDetectionReady = false; resetChargeEndDetection(&wCharger); -#endif +#endif // defined(WIRELESS_CHARGER) } void ledChargingInfo(uint16_t chargeState) { From 620fee0ca59e0f02f8331a961f029e1a31302d13 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 8 Aug 2024 13:41:26 +0800 Subject: [PATCH 04/13] Updated trims mapping in diagnostic screen --- radio/src/gui/colorlcd/radio/radio_diagkeys.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp index 18985c4e3e0..49b3a7b6614 100644 --- a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp +++ b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp @@ -25,15 +25,18 @@ #include "libopenui.h" #include "edgetx.h" -#if defined(RADIO_NB4P) -static const uint8_t _trimMap[MAX_TRIMS * 2] = {0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15}; +#if defined(RADIO_PL18U) + static const uint8_t _trimMap[MAX_TRIMS * 2] = {8, 9, 10, 11, 2, 3, 4, 5, + 0, 1, 6, 7, 12, 13, 14, 15}; +#elif defined(RADIO_NB4P) + static const uint8_t _trimMap[MAX_TRIMS * 2] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15}; #elif defined(PCBPL18) -static const uint8_t _trimMap[MAX_TRIMS * 2] = {8, 9, 10, 11, 12, 13, 14, 15, - 2, 3, 4, 5, 0, 1, 6, 7}; + static const uint8_t _trimMap[MAX_TRIMS * 2] = {8, 9, 10, 11, 12, 13, 14, 15, + 2, 3, 4, 5, 0, 1, 6, 7}; #else -static const uint8_t _trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, - 0, 1, 8, 9, 10, 11}; + static const uint8_t _trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, + 0, 1, 8, 9, 10, 11}; #endif static EnumKeys get_ith_key(uint8_t i) From fa3b5b97f14a47e95d2c12029043b21b7a9a8960 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 8 Aug 2024 13:34:06 +0800 Subject: [PATCH 05/13] PL18U need slower SDIO clock --- radio/src/targets/pl18/hal.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index a0b74d69c84..beaa27d9c22 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -696,7 +696,11 @@ #define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler #define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2) #define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000) - #define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) + #if defined(RADIO_PL18U) + #define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(12000000) + #else + #define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) + #endif #endif // SPI NOR Flash From c04942c89a62861f990757afbbb4b8a4453855a9 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 26 Dec 2024 14:03:55 +0800 Subject: [PATCH 06/13] Customize sliders location VRC is in the middle --- radio/src/gui/colorlcd/mainview/sliders.h | 2 +- .../gui/colorlcd/mainview/view_main_decoration.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/radio/src/gui/colorlcd/mainview/sliders.h b/radio/src/gui/colorlcd/mainview/sliders.h index 85465eb4995..8786a6eeb5d 100644 --- a/radio/src/gui/colorlcd/mainview/sliders.h +++ b/radio/src/gui/colorlcd/mainview/sliders.h @@ -38,7 +38,7 @@ class MainViewSlider : public Window MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx, bool isVertical); -#if defined(RADIO_PL18) || defined(RADIO_PL18EV) +#if defined(RADIO_PL18) || defined(RADIO_PL18EV) || defined(RADIO_PL18U) static constexpr coord_t SLIDER_SIZE = 136; // to fit 3 across bottom row #else static LAYOUT_SIZE_SCALED_EVEN(SLIDER_SIZE, 160, 120) diff --git a/radio/src/gui/colorlcd/mainview/view_main_decoration.cpp b/radio/src/gui/colorlcd/mainview/view_main_decoration.cpp index 4afab55d2cc..60b381bfb14 100644 --- a/radio/src/gui/colorlcd/mainview/view_main_decoration.cpp +++ b/radio/src/gui/colorlcd/mainview/view_main_decoration.cpp @@ -117,11 +117,15 @@ void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Windo if (IS_POT_AVAILABLE(pot)) { sliders[pot] = new MainViewHorizontalSlider(bl, pot); } +#if defined(RADIO_PL18U) + pot += 2; +#else pot += 1; +#endif // Bottom center 6POS if (IS_POT_AVAILABLE(pot)) { -#if defined(RADIO_PL18) || defined(RADIO_PL18EV) +#if defined(RADIO_PL18) || defined(RADIO_PL18EV) || defined(RADIO_PL18U) sliders[pot] = new MainViewHorizontalSlider(bc, pot); pot += 1; #else @@ -136,10 +140,18 @@ void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Windo } // Bottom right horizontal slider + +#if defined(RADIO_PL18U) + pot -= 2; +#endif if (IS_POT_AVAILABLE(pot)) { sliders[pot] = new MainViewHorizontalSlider(br, pot); } +#if defined(RADIO_PL18U) + pot += 2; +#else pot += 1; +#endif auto max_pots = adcGetMaxInputs(ADC_INPUT_FLEX); if (max_pots > pot) { From 3cd311f36318205477a05e4186552892ba648cd9 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 26 Dec 2024 14:04:30 +0800 Subject: [PATCH 07/13] Speed up power on hold --- radio/src/targets/pl18/board.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/radio/src/targets/pl18/board.cpp b/radio/src/targets/pl18/board.cpp index f8f6fccb604..866ed744a92 100644 --- a/radio/src/targets/pl18/board.cpp +++ b/radio/src/targets/pl18/board.cpp @@ -160,6 +160,9 @@ void disableVoiceChip() void boardBLEarlyInit() { +#if defined(RADIO_PL18U) + pwrOn(); +#endif // USB charger status pins gpio_init(UCHARGER_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW); From 5a65c7ccda5d5ad5965a39bfc991bf866392860c Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 26 Dec 2024 15:02:14 +0800 Subject: [PATCH 08/13] Updated trims naming --- radio/src/gui/colorlcd/radio/radio_diagkeys.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp index 49b3a7b6614..db4007eac74 100644 --- a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp +++ b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp @@ -26,8 +26,8 @@ #include "edgetx.h" #if defined(RADIO_PL18U) - static const uint8_t _trimMap[MAX_TRIMS * 2] = {8, 9, 10, 11, 2, 3, 4, 5, - 0, 1, 6, 7, 12, 13, 14, 15}; + static const uint8_t _trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, 0, 1, + 10, 11, 8, 9, 12, 13, 14, 15}; #elif defined(RADIO_NB4P) static const uint8_t _trimMap[MAX_TRIMS * 2] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; From 5369e1125045eaabaf0189e88a548755023f2bee Mon Sep 17 00:00:00 2001 From: Richard Li Date: Thu, 26 Dec 2024 15:09:16 +0800 Subject: [PATCH 09/13] Fixed sliders direction --- radio/src/targets/pl18/hal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index beaa27d9c22..f4f6fe3b2b1 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -504,7 +504,7 @@ #define ADC_DIRECTION { \ 0,0,0,0, /* gimbals */ \ 0,0,0, /* pots */ \ - -1,-1, /* sliders */ \ + -1,1, /* sliders */ \ 0, /* vbat */ \ 0, /* rtc_bat */ \ -1, /* SWB */ \ From bb7cf4d1f555ed0fc95775050e97a9334b10dba3 Mon Sep 17 00:00:00 2001 From: Richard Li Date: Tue, 31 Dec 2024 15:27:21 +0800 Subject: [PATCH 10/13] Updated charging logic due to hardware changes --- radio/src/targets/pl18/battery_driver.cpp | 62 ++++++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/radio/src/targets/pl18/battery_driver.cpp b/radio/src/targets/pl18/battery_driver.cpp index 4772f4108ca..68f422a456b 100644 --- a/radio/src/targets/pl18/battery_driver.cpp +++ b/radio/src/targets/pl18/battery_driver.cpp @@ -25,6 +25,9 @@ #define __BATTERY_DRIVER_C__ +// Debug driver +//#define BATTERY_DRIVER_DEBUG + #define BATTERY_W 140 #define BATTERY_H (LCD_H - 120) #define BATTERY_TOP ((LCD_H - BATTERY_H)/2) @@ -168,19 +171,17 @@ void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinAct } } -uint16_t get_battery_charge_state() +uint16_t get_uCharger_state(uint16_t state) { - uint16_t state = CHARGE_UNKNOWN; - chargerDetection(&uCharger, IS_UCHARGER_ACTIVE(), UCHARGER_SAMPLING_CNT); if (uCharger.isChargerDetectionReady) { if (uCharger.hasCharger) // USB charger can be detected properly no matter it is enabled or not { -#if defined(RADIO_PL18U) && defined(WIRELESS_CHARGER) - DISABLE_WCHARGER(); -#endif +#if !defined(RADIO_PL18U) + // Enable USB charger when USB power is detected ENABLE_UCHARGER(); +#endif chargeEndDetection(&uCharger, IS_UCHARGER_CHARGE_END_ACTIVE(), UCHARGER_CHARGING_SAMPLING_CNT, UCHARGER_CHARGE_END_SAMPLING_CNT); if (uCharger.isChargingDetectionReady) { @@ -198,20 +199,29 @@ uint16_t get_battery_charge_state() { resetChargeEndDetection(&uCharger); +#if !defined(RADIO_PL18U) // Disable USB charger if it is not present, so that wireless charger can be detected properly DISABLE_UCHARGER(); -#if defined(RADIO_PL18U) && defined(WIRELESS_CHARGER) - ENABLE_WCHARGER(); #endif } } + return state; +} + +uint16_t get_wCharger_state(uint16_t state) +{ #if defined(WIRELESS_CHARGER) chargerDetection(&wCharger, IS_WCHARGER_ACTIVE(), WCHARGER_SAMPLING_CNT); if (wCharger.isChargerDetectionReady) { if (wCharger.hasCharger) // Wireless charger can only be detected when USB charger is disabled { +#if defined(RADIO_PL18U) + // Disable USB charger when wireless charger is present, otherwise USB charger detection will be wrong + DISABLE_UCHARGER(); + ENABLE_WCHARGER(); +#endif chargeEndDetection(&wCharger, IS_WCHARGER_CHARGE_END_ACTIVE(), WCHARGER_CHARGING_SAMPLING_CNT, WCHARGER_CHARGE_END_SAMPLING_CNT); if (wCharger.isChargingDetectionReady) { @@ -240,6 +250,11 @@ uint16_t get_battery_charge_state() else { resetChargeEndDetection(&wCharger); +#if defined(RADIO_PL18U) + // Enable USB charger only if wireless charger is not present + DISABLE_WCHARGER(); + ENABLE_UCHARGER(); +#endif // Charge current control wirelessHighCurrentDelay = 0; @@ -260,6 +275,22 @@ uint16_t get_battery_charge_state() return state; } +uint16_t get_battery_charge_state() +{ + uint16_t state = CHARGE_UNKNOWN; + +#if defined(RADIO_PL18U) + // PL18U wireless charger takes precedence + state = get_wCharger_state(state); + state = get_uCharger_state(state); +#else + state = get_uCharger_state(state); + state = get_wCharger_state(state); +#endif + + return state; +} + bool isChargerActive() { #if defined(WIRELESS_CHARGER) @@ -385,7 +416,7 @@ void drawChargingInfo(uint16_t chargeState) { } #define CHARGE_INFO_DURATION 5000 // ms -//this method should be called by timer interrupt or by GPIO interrupt +// This method should be called by timer interrupt or by GPIO interrupt void handle_battery_charge(uint32_t last_press_time) { #if !defined(SIMU) @@ -399,13 +430,13 @@ void handle_battery_charge(uint32_t last_press_time) if (chargeState != CHARGE_UNKNOWN) { if (lastState != chargeState) { - //avoid positive check when none and unknown + // Avoid positive check when none and unknown if (lastState + chargeState > 1) { - //charge state changed - last state known + // Charge state changed - last state known info_until = now + (CHARGE_INFO_DURATION); } } - //power buttons pressed + // Power buttons pressed else if (now - last_press_time < POWER_ON_DELAY) { info_until = now + CHARGE_INFO_DURATION; } @@ -417,6 +448,7 @@ void handle_battery_charge(uint32_t last_press_time) updateTime = timersGetMsTick(); ledChargingInfo(chargeState); +#if !defined(BATTERY_DRIVER_DEBUG) if(now > info_until) { info_until = 0; lcd->clear(); @@ -425,6 +457,7 @@ void handle_battery_charge(uint32_t last_press_time) lcdOff(); } } else { +#endif if (!lcdInited) { backlightInit(); lcdInit(); @@ -438,7 +471,7 @@ void handle_battery_charge(uint32_t last_press_time) drawChargingInfo(chargeState); // DEBUG INFO -#if 0 +#if defined(BATTERY_DRIVER_DEBUG) char buffer[1024]; sprintf(buffer, "%d,%d,%d,%d", uCharger.isChargerDetectionReady, uCharger.hasCharger, IS_UCHARGER_ACTIVE(), uCharger.chargerSamplingCount); @@ -460,8 +493,9 @@ void handle_battery_charge(uint32_t last_press_time) #endif lcdRefresh(); +#if !defined(BATTERY_DRIVER_DEBUG) } - +#endif } #endif } From 22f05c0b711cddb7bb418ef1c2ba65cfd75d8eec Mon Sep 17 00:00:00 2001 From: Richard Li Date: Mon, 10 Feb 2025 11:16:45 +0800 Subject: [PATCH 11/13] Re-work pl18u keys trims mapping with KL and KR --- radio/src/targets/pl18/CMakeLists.txt | 4 +- radio/src/targets/pl18/hal.h | 26 +- radio/src/targets/pl18/key_driver.cpp | 116 ++------- radio/src/targets/pl18/pl18u_key_driver.cpp | 248 ++++++++++++++++++++ 4 files changed, 293 insertions(+), 101 deletions(-) create mode 100644 radio/src/targets/pl18/pl18u_key_driver.cpp diff --git a/radio/src/targets/pl18/CMakeLists.txt b/radio/src/targets/pl18/CMakeLists.txt index 77298d67c02..36fd15f2f34 100644 --- a/radio/src/targets/pl18/CMakeLists.txt +++ b/radio/src/targets/pl18/CMakeLists.txt @@ -44,13 +44,13 @@ add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS) if(PCBREV STREQUAL PL18U) set(FLAVOUR pl18u) - add_definitions(-DRADIO_PL18U -DUSE_HATS_AS_KEYS) + add_definitions(-DRADIO_PL18U) set(DISK_CACHE ON) set(WIRELESS_CHARGER YES) set(FLYSKY_GIMBAL ON) set(LED_STRIP ON) set(USE_VS1053B ON) - set(KEY_DRIVER key_driver.cpp) + set(KEY_DRIVER pl18u_key_driver.cpp) # Defines internal module for PL18U set(INTERNAL_MODULES AFHDS3;CRSF CACHE STRING "Internal modules") diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index f4f6fe3b2b1..626b9c53091 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -235,6 +235,14 @@ #else // !defined(RADIO_NB4P) && !defined(RADIO_NV14_FAMILY) +// Keys +#if defined(RADIO_PL18U) +#define KEYS_GPIO_PIN_ENTER +#define KEYS_GPIO_REG_ENTER +#define KEYS_GPIO_PIN_EXIT +#define KEYS_GPIO_REG_EXIT +#endif + // Trims #define TRIMS_GPIO_REG_LHL #define TRIMS_GPIO_PIN_LHL @@ -272,19 +280,19 @@ #define TRIMS_GPIO_REG_RSU #define TRIMS_GPIO_PIN_RSU -#define TRIMS_GPIO_REG_T7L -#define TRIMS_GPIO_PIN_T7L +#if !defined(RADIO_PL18U) + #define TRIMS_GPIO_REG_T7L + #define TRIMS_GPIO_PIN_T7L -#define TRIMS_GPIO_REG_T7R -#define TRIMS_GPIO_PIN_T7R + #define TRIMS_GPIO_REG_T7R + #define TRIMS_GPIO_PIN_T7R -#define TRIMS_GPIO_REG_T8D -#define TRIMS_GPIO_PIN_T8D + #define TRIMS_GPIO_REG_T8D + #define TRIMS_GPIO_PIN_T8D -#define TRIMS_GPIO_REG_T8U -#define TRIMS_GPIO_PIN_T8U + #define TRIMS_GPIO_REG_T8U + #define TRIMS_GPIO_PIN_T8U -#if !defined(RADIO_PL18U) #define TRIMS_GPIO_REG_TR1U GPIOH->IDR #define TRIMS_GPIO_PIN_TR1U LL_GPIO_PIN_8 // PH.08 #define TRIMS_GPIO_REG_TR1D GPIOH->IDR diff --git a/radio/src/targets/pl18/key_driver.cpp b/radio/src/targets/pl18/key_driver.cpp index f86a4992781..10dd0c4181e 100644 --- a/radio/src/targets/pl18/key_driver.cpp +++ b/radio/src/targets/pl18/key_driver.cpp @@ -28,56 +28,36 @@ #include "delays_driver.h" #include "keys.h" - - /* The output bit-order has to be (D = L, U = R): - PL18 PL18U - 0 LHL TR7D(L) TR5D(L) - 1 LHR TR7U(R) TR5U(R) - 2 LVD TR5D TR3D - 3 LVU TR5U TR3U - 4 RVD TR6D TR4D - 5 RVU TR6U TR4U - 6 RHL TR8D(L) TR6D(L) - 7 RHR TR8U(R) TR6U(R) - 8 LSD TR1D TR1D - 9 LSU TR1U TR1U - 10 RSD TR2D TR2D - 11 RSU TR2U TR2U - 12 EX1D TR3D TR7D - 13 EX1U TR3U TR7U - 14 EX2D TR4D TR8D - 15 EX2U TR4U TR8U + PL18/PL18EV + 0 LHL TR7L + 1 LHR TR7R + 2 LVD TR5D + 3 LVU TR5U + 4 RVD TR6D + 5 RVU TR6U + 6 RHL TR8L + 7 RHR TR8R + 8 LSD TR1D + 9 LSU TR1U + 10 RSD TR2D + 11 RSU TR2U + 12 EX1D TR3D + 13 EX1U TR3U + 14 EX2D TR4D + 15 EX2U TR4U */ enum PhysicalTrims { -#if defined(RADIO_PL18U) - TR5D = 0, - TR5U, - TR3D = 2, - TR3U, - TR4D = 4, - TR4U, - TR6D = 6, - TR6U, - TR1D = 8, - TR1U, - TR2D = 10, - TR2U, - TR7D = 12, - TR7U, - TR8D = 14, - TR8U, -#else - TR7D = 0, - TR7U, + TR7L = 0, + TR7R, TR5D = 2, TR5U, TR6D = 4, TR6U, - TR8D = 6, - TR8U, + TR8L = 6, + TR8R, TR1D = 8, TR1U, TR2D = 10, @@ -86,7 +66,6 @@ enum PhysicalTrims TR3U, TR4D = 14, TR4U, -#endif }; void keysInit() @@ -96,9 +75,6 @@ void keysInit() stm32_gpio_enable_clock(GPIOD); stm32_gpio_enable_clock(GPIOG); stm32_gpio_enable_clock(GPIOH); -#if defined(RADIO_PL18U) - stm32_gpio_enable_clock(GPIOI); -#endif stm32_gpio_enable_clock(GPIOJ); LL_GPIO_InitTypeDef pinInit; @@ -115,10 +91,8 @@ void keysInit() pinInit.Pin = KEYS_GPIOD_PINS; LL_GPIO_Init(GPIOD, &pinInit); -#if defined(KEYS_GPIOH_PINS) pinInit.Pin = KEYS_GPIOH_PINS; LL_GPIO_Init(GPIOH, &pinInit); -#endif pinInit.Pin = KEYS_GPIOJ_PINS; LL_GPIO_Init(GPIOJ, &pinInit); @@ -130,15 +104,8 @@ void keysInit() pinInit.Pin = KEYS_OUT_GPIOG_PINS; LL_GPIO_Init(GPIOG, &pinInit); -#if defined(KEYS_OUT_GPIOH_PINS) pinInit.Pin = KEYS_OUT_GPIOH_PINS; LL_GPIO_Init(GPIOH, &pinInit); -#endif - -#if defined(KEYS_OUT_GPIOI_PINS) - pinInit.Pin = KEYS_OUT_GPIOI_PINS; - LL_GPIO_Init(GPIOI, &pinInit); -#endif } static uint32_t _readKeyMatrix() @@ -165,16 +132,11 @@ static uint32_t _readKeyMatrix() LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN); LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN); LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); - -#if defined(TRIMS_GPIO_OUT4) - LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); -#endif - delay_us(10); if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) - result |= 1 << TR7D; + result |= 1 << TR7L; if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) - result |= 1 << TR7U; + result |= 1 << TR7R; if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) result |= 1 << TR5D; if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) @@ -200,26 +162,12 @@ static uint32_t _readKeyMatrix() if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) result |= 1 << TR6D; if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) - result |= 1 << TR8D; + result |= 1 << TR8L; if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) - result |= 1 << TR8U; + result |= 1 << TR8R; LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); -#if defined(TRIMS_GPIO_OUT4) - LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); - delay_us(10); - if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) - result |= 1 << TR1U; - if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) - result |= 1 << TR1D; - if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) - result |= 1 << TR2D; - if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) - result |= 1 << TR2U; - LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); -#endif - syncelem.oldResult = result; syncelem.ui8ReadInProgress = 0; @@ -232,13 +180,8 @@ uint32_t readKeys() if (getHatsAsKeys()) { uint32_t mkeys = _readKeyMatrix(); -#if defined(RADIO_PL18U) - if (mkeys & (1 << TR2D)) result |= 1 << KEY_ENTER; - if (mkeys & (1 << TR2U)) result |= 1 << KEY_EXIT; -#else if (mkeys & (1 << TR4D)) result |= 1 << KEY_ENTER; if (mkeys & (1 << TR4U)) result |= 1 << KEY_EXIT; -#endif } return result; @@ -250,22 +193,15 @@ uint32_t readTrims() result |= _readKeyMatrix(); -#if defined(TRIMS_GPIO_REG_TR1U) if (~TRIMS_GPIO_REG_TR1U & TRIMS_GPIO_PIN_TR1U) result |= 1 << (TR1U); -#endif -#if defined(TRIMS_GPIO_REG_TR1D) if (~TRIMS_GPIO_REG_TR1D & TRIMS_GPIO_PIN_TR1D) result |= 1 << (TR1D); -#endif -#if defined(TRIMS_GPIO_REG_TR2U) + if (~TRIMS_GPIO_REG_TR2U & TRIMS_GPIO_PIN_TR2U) result |= 1 << (TR2U); -#endif -#if defined(TRIMS_GPIO_REG_TR2D) if (~TRIMS_GPIO_REG_TR2D & TRIMS_GPIO_PIN_TR2D) result |= 1 << (TR2D); -#endif return result; } diff --git a/radio/src/targets/pl18/pl18u_key_driver.cpp b/radio/src/targets/pl18/pl18u_key_driver.cpp new file mode 100644 index 00000000000..44a856b522c --- /dev/null +++ b/radio/src/targets/pl18/pl18u_key_driver.cpp @@ -0,0 +1,248 @@ +/* + * 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 "hal/key_driver.h" + +#include "stm32_hal_ll.h" +#include "stm32_gpio_driver.h" + +#include "hal.h" +#include "delays_driver.h" +#include "keys.h" + +#define REPEAT_DELAY 20 + +/* The output bit-order has to be (D = L, U = R): + PL18U + 0 LHL TR4L + 1 LHR TR4R + 2 LVD TR3D + 3 LVU TR3U + 4 RVD TR2D + 5 RVU TR2U + 6 RHL TR1L + 7 RHR TR1R + 8 LSD TR6D + 9 LSU TR6U + 10 RSD TR5D + 11 RSU TR5U + + 12 EX1D KLD + 13 EX1U KLU + 14 EX2D KRD + 15 EX2U KRU +*/ + +enum PhysicalTrims +{ + TR4L = 0, + TR4R, + TR3D = 2, + TR3U, + TR2D = 4, + TR2U, + TR1L = 6, + TR1R, + TR6D = 8, + TR6U, + TR5D = 10, + TR5U, + KLD = 12, + KLU, + KRD = 14, + KRU, +}; + +volatile uint32_t rotencDt = 0; +static rotenc_t rotencValue = 0; +static uint8_t lastRotState = 0; +static uint8_t stateCount = 0; + +void keysInit() +{ + stm32_gpio_enable_clock(GPIOB); + stm32_gpio_enable_clock(GPIOC); + stm32_gpio_enable_clock(GPIOD); + stm32_gpio_enable_clock(GPIOG); + stm32_gpio_enable_clock(GPIOH); + stm32_gpio_enable_clock(GPIOI); + stm32_gpio_enable_clock(GPIOJ); + + LL_GPIO_InitTypeDef pinInit; + LL_GPIO_StructInit(&pinInit); + pinInit.Mode = LL_GPIO_MODE_INPUT; + pinInit.Pull = LL_GPIO_PULL_NO; + + pinInit.Pin = KEYS_GPIOB_PINS; + LL_GPIO_Init(GPIOB, &pinInit); + + pinInit.Pin = KEYS_GPIOC_PINS; + LL_GPIO_Init(GPIOC, &pinInit); + + pinInit.Pin = KEYS_GPIOD_PINS; + LL_GPIO_Init(GPIOD, &pinInit); + + pinInit.Pin = KEYS_GPIOJ_PINS; + LL_GPIO_Init(GPIOJ, &pinInit); + + // Matrix outputs + pinInit.Mode = LL_GPIO_MODE_OUTPUT; + pinInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + + pinInit.Pin = KEYS_OUT_GPIOG_PINS; + LL_GPIO_Init(GPIOG, &pinInit); + + pinInit.Pin = KEYS_OUT_GPIOH_PINS; + LL_GPIO_Init(GPIOH, &pinInit); + + pinInit.Pin = KEYS_OUT_GPIOI_PINS; + LL_GPIO_Init(GPIOI, &pinInit); +} + +static uint32_t _readKeyMatrix() +{ + // This function avoids concurrent matrix agitation + + uint32_t result = 0; + + volatile static struct + { + uint32_t oldResult = 0; + uint8_t ui8ReadInProgress = 0; + } syncelem; + + if (syncelem.ui8ReadInProgress != 0) return syncelem.oldResult; + + // ui8ReadInProgress was 0, increment it + syncelem.ui8ReadInProgress++; + // Double check before continuing, as non-atomic, non-blocking so far + // If ui8ReadInProgress is above 1, then there was concurrent task calling it, exit + if (syncelem.ui8ReadInProgress > 1) return syncelem.oldResult; + + // If we land here, we have exclusive access to Matrix + LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN); + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN); + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); + + delay_us(10); + if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) + result |= 1 << KLD; + if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) + result |= 1 << KLU; + if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) + result |= 1 << TR4L; + if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) + result |= 1 << TR4R; + + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN); + LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN); + delay_us(10); + if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) + result |= 1 << TR3D; + if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) + result |= 1 << TR3U; + if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) + result |= 1 << TR2U; + if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) + result |= 1 << TR2D; + + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN); + LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); + delay_us(10); + if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) + result |= 1 << TR1R; + if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) + result |= 1 << TR1L; + if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) + result |= 1 << KRD; + if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) + result |= 1 << KRU; + + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN); + + LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); + delay_us(10); + if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1) + result |= 1 << TR6U; + if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2) + result |= 1 << TR6D; + if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3) + result |= 1 << TR5D; + if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4) + result |= 1 << TR5U; + LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN); + + syncelem.oldResult = result; + syncelem.ui8ReadInProgress = 0; + + return result; +} + +uint32_t readKeys() +{ + uint32_t result = 0; + + uint32_t mkeys = _readKeyMatrix(); + if (mkeys & (1 << KRD)) result |= 1 << KEY_ENTER; + if (mkeys & (1 << KRU)) result |= 1 << KEY_EXIT; + + uint8_t rotState = 0; + if (mkeys & (1 << KLD)) rotState |= 1; + if (mkeys & (1 << KLU)) rotState |= 2; + + if (rotState != lastRotState) { + lastRotState = rotState; + stateCount = 0; + } else { + stateCount++; + if (stateCount == 3) { + if (rotState == 1) + rotencValue++; + else if (rotState == 2) + rotencValue--; + } else if (stateCount >= REPEAT_DELAY) { + stateCount = 0; + } + } + + return result; +} + +uint32_t readTrims() +{ + uint32_t result = 0; + + result |= _readKeyMatrix(); + result &= 0xfff; // Only 12 bits for 6 trims + + return result; +} + +rotenc_t rotaryEncoderGetValue() +{ + return rotencValue; +} + +void rotaryEncoderInit() +{ +} + From 02cb18b30b49d0d5a37c7bf7cc18ba2c465e2cbc Mon Sep 17 00:00:00 2001 From: Richard Li Date: Wed, 23 Apr 2025 13:14:34 +0800 Subject: [PATCH 12/13] PL18U requires specialized datastruct --- radio/src/storage/yaml/CMakeLists.txt | 2 + radio/src/storage/yaml/yaml_datastructs.cpp | 2 + .../storage/yaml/yaml_datastructs_pl18u.cpp | 911 ++++++++++++++++++ tools/generate-yaml.sh | 2 +- 4 files changed, 916 insertions(+), 1 deletion(-) create mode 100644 radio/src/storage/yaml/yaml_datastructs_pl18u.cpp diff --git a/radio/src/storage/yaml/CMakeLists.txt b/radio/src/storage/yaml/CMakeLists.txt index 81d79ecc6c4..123186e9267 100644 --- a/radio/src/storage/yaml/CMakeLists.txt +++ b/radio/src/storage/yaml/CMakeLists.txt @@ -29,6 +29,8 @@ elseif(PCB STREQUAL PL18) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_nb4p.cpp) elseif(PCBREV STREQUAL NV14) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_nv14_family.cpp) + elseif(PCBREV STREQUAL PL18U) + set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pl18u.cpp) else() set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pl18.cpp) endif() diff --git a/radio/src/storage/yaml/yaml_datastructs.cpp b/radio/src/storage/yaml/yaml_datastructs.cpp index e2e3ca8ab9b..26861341311 100644 --- a/radio/src/storage/yaml/yaml_datastructs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs.cpp @@ -41,6 +41,8 @@ #include "yaml_datastructs_nb4p.cpp" #elif defined(RADIO_NV14_FAMILY) #include "yaml_datastructs_nv14_family.cpp" + #elif defined(RADIO_PL18U) + #include "yaml_datastructs_pl18u.cpp" #else #include "yaml_datastructs_pl18.cpp" #endif diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp new file mode 100644 index 00000000000..c52bbb4d47f --- /dev/null +++ b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp @@ -0,0 +1,911 @@ +// generated by generate_yaml.py + +// +// Enums first +// + +const struct YamlIdStr enum_BacklightMode[] = { + { e_backlight_mode_off, "backlight_mode_off" }, + { e_backlight_mode_keys, "backlight_mode_keys" }, + { e_backlight_mode_sticks, "backlight_mode_sticks" }, + { e_backlight_mode_all, "backlight_mode_all" }, + { e_backlight_mode_on, "backlight_mode_on" }, + { 0, NULL } +}; +const struct YamlIdStr enum_AntennaModes[] = { + { ANTENNA_MODE_INTERNAL, "MODE_INTERNAL" }, + { ANTENNA_MODE_ASK, "MODE_ASK" }, + { ANTENNA_MODE_PER_MODEL, "MODE_PER_MODEL" }, + { ANTENNA_MODE_EXTERNAL, "MODE_EXTERNAL" }, + { 0, NULL } +}; +const struct YamlIdStr enum_ModuleType[] = { + { MODULE_TYPE_NONE, "TYPE_NONE" }, + { MODULE_TYPE_PPM, "TYPE_PPM" }, + { MODULE_TYPE_XJT_PXX1, "TYPE_XJT_PXX1" }, + { MODULE_TYPE_ISRM_PXX2, "TYPE_ISRM_PXX2" }, + { MODULE_TYPE_DSM2, "TYPE_DSM2" }, + { MODULE_TYPE_CROSSFIRE, "TYPE_CROSSFIRE" }, + { MODULE_TYPE_MULTIMODULE, "TYPE_MULTIMODULE" }, + { MODULE_TYPE_R9M_PXX1, "TYPE_R9M_PXX1" }, + { MODULE_TYPE_R9M_PXX2, "TYPE_R9M_PXX2" }, + { MODULE_TYPE_R9M_LITE_PXX1, "TYPE_R9M_LITE_PXX1" }, + { MODULE_TYPE_R9M_LITE_PXX2, "TYPE_R9M_LITE_PXX2" }, + { MODULE_TYPE_GHOST, "TYPE_GHOST" }, + { MODULE_TYPE_R9M_LITE_PRO_PXX2, "TYPE_R9M_LITE_PRO_PXX2" }, + { MODULE_TYPE_SBUS, "TYPE_SBUS" }, + { MODULE_TYPE_XJT_LITE_PXX2, "TYPE_XJT_LITE_PXX2" }, + { MODULE_TYPE_FLYSKY_AFHDS2A, "TYPE_FLYSKY_AFHDS2A" }, + { MODULE_TYPE_FLYSKY_AFHDS3, "TYPE_FLYSKY_AFHDS3" }, + { MODULE_TYPE_LEMON_DSMP, "TYPE_LEMON_DSMP" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TrainerMultiplex[] = { + { TRAINER_OFF, "OFF" }, + { TRAINER_ADD, "ADD" }, + { TRAINER_REPL, "REPL" }, + { 0, NULL } +}; +const struct YamlIdStr enum_BeeperMode[] = { + { e_mode_quiet, "mode_quiet" }, + { e_mode_alarms, "mode_alarms" }, + { e_mode_nokeys, "mode_nokeys" }, + { e_mode_all, "mode_all" }, + { 0, NULL } +}; +const struct YamlIdStr enum_BluetoothModes[] = { + { BLUETOOTH_OFF, "OFF" }, + { BLUETOOTH_TELEMETRY, "TELEMETRY" }, + { BLUETOOTH_TRAINER, "TRAINER" }, + { 0, NULL } +}; +const struct YamlIdStr enum_Functions[] = { + { FUNC_OVERRIDE_CHANNEL, "OVERRIDE_CHANNEL" }, + { FUNC_TRAINER, "TRAINER" }, + { FUNC_INSTANT_TRIM, "INSTANT_TRIM" }, + { FUNC_RESET, "RESET" }, + { FUNC_SET_TIMER, "SET_TIMER" }, + { FUNC_ADJUST_GVAR, "ADJUST_GVAR" }, + { FUNC_VOLUME, "VOLUME" }, + { FUNC_SET_FAILSAFE, "SET_FAILSAFE" }, + { FUNC_RANGECHECK, "RANGECHECK" }, + { FUNC_BIND, "BIND" }, + { FUNC_PLAY_SOUND, "PLAY_SOUND" }, + { FUNC_PLAY_TRACK, "PLAY_TRACK" }, + { FUNC_PLAY_VALUE, "PLAY_VALUE" }, + { FUNC_PLAY_SCRIPT, "PLAY_SCRIPT" }, + { FUNC_BACKGND_MUSIC, "BACKGND_MUSIC" }, + { FUNC_BACKGND_MUSIC_PAUSE, "BACKGND_MUSIC_PAUSE" }, + { FUNC_VARIO, "VARIO" }, + { FUNC_HAPTIC, "HAPTIC" }, + { FUNC_LOGS, "LOGS" }, + { FUNC_BACKLIGHT, "BACKLIGHT" }, + { FUNC_SCREENSHOT, "SCREENSHOT" }, + { FUNC_RACING_MODE, "RACING_MODE" }, + { FUNC_DISABLE_TOUCH, "DISABLE_TOUCH" }, + { FUNC_SET_SCREEN, "SET_SCREEN" }, + { FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" }, + { FUNC_RGB_LED, "RGB_LED" }, + { FUNC_TEST, "TEST" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TimerModes[] = { + { TMRMODE_OFF, "OFF" }, + { TMRMODE_ON, "ON" }, + { TMRMODE_START, "START" }, + { TMRMODE_THR, "THR" }, + { TMRMODE_THR_REL, "THR_REL" }, + { TMRMODE_THR_START, "THR_START" }, + { 0, NULL } +}; +const struct YamlIdStr enum_MixerMultiplex[] = { + { MLTPX_ADD, "ADD" }, + { MLTPX_MUL, "MUL" }, + { MLTPX_REPL, "REPL" }, + { 0, NULL } +}; +const struct YamlIdStr enum_MixSources[] = { + { MIXSRC_NONE, "NONE" }, + { MIXSRC_MIN, "MIN" }, + { MIXSRC_MAX, "MAX" }, + { MIXSRC_TX_VOLTAGE, "TX_VOLTAGE" }, + { MIXSRC_TX_TIME, "TX_TIME" }, + { MIXSRC_TX_GPS, "TX_GPS" }, + { 0, NULL } +}; +const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { + { LS_FUNC_NONE, "FUNC_NONE" }, + { LS_FUNC_VEQUAL, "FUNC_VEQUAL" }, + { LS_FUNC_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL" }, + { LS_FUNC_VPOS, "FUNC_VPOS" }, + { LS_FUNC_VNEG, "FUNC_VNEG" }, + { LS_FUNC_APOS, "FUNC_APOS" }, + { LS_FUNC_ANEG, "FUNC_ANEG" }, + { LS_FUNC_AND, "FUNC_AND" }, + { LS_FUNC_OR, "FUNC_OR" }, + { LS_FUNC_XOR, "FUNC_XOR" }, + { LS_FUNC_EDGE, "FUNC_EDGE" }, + { LS_FUNC_EQUAL, "FUNC_EQUAL" }, + { LS_FUNC_GREATER, "FUNC_GREATER" }, + { LS_FUNC_LESS, "FUNC_LESS" }, + { LS_FUNC_DIFFEGREATER, "FUNC_DIFFEGREATER" }, + { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, + { LS_FUNC_TIMER, "FUNC_TIMER" }, + { LS_FUNC_STICKY, "FUNC_STICKY" }, + { 0, NULL } +}; +const struct YamlIdStr enum_SwashType[] = { + { SWASH_TYPE_NONE, "TYPE_NONE" }, + { SWASH_TYPE_120, "TYPE_120" }, + { SWASH_TYPE_120X, "TYPE_120X" }, + { SWASH_TYPE_140, "TYPE_140" }, + { SWASH_TYPE_90, "TYPE_90" }, + { 0, NULL } +}; +const struct YamlIdStr enum_SwitchSources[] = { + { SWSRC_NONE, "NONE" }, + { SWSRC_ON, "ON" }, + { SWSRC_ONE, "ONE" }, + { SWSRC_TELEMETRY_STREAMING, "TELEMETRY_STREAMING" }, + { SWSRC_RADIO_ACTIVITY, "RADIO_ACTIVITY" }, + { SWSRC_TRAINER_CONNECTED, "TRAINER_CONNECTED" }, + { SWSRC_OFF, "OFF" }, + { 0, NULL } +}; +const struct YamlIdStr enum_PotsWarnMode[] = { + { POTS_WARN_OFF, "WARN_OFF" }, + { POTS_WARN_MANUAL, "WARN_MANUAL" }, + { POTS_WARN_AUTO, "WARN_AUTO" }, + { 0, NULL } +}; +const struct YamlIdStr enum_ModelOverridableEnable[] = { + { OVERRIDE_GLOBAL, "GLOBAL" }, + { OVERRIDE_OFF, "OFF" }, + { OVERRIDE_ON, "ON" }, + { 0, NULL } +}; +const struct YamlIdStr enum_FailsafeModes[] = { + { FAILSAFE_NOT_SET, "NOT_SET" }, + { FAILSAFE_HOLD, "HOLD" }, + { FAILSAFE_CUSTOM, "CUSTOM" }, + { FAILSAFE_NOPULSES, "NOPULSES" }, + { FAILSAFE_RECEIVER, "RECEIVER" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TelemetrySensorFormula[] = { + { TELEM_FORMULA_ADD, "FORMULA_ADD" }, + { TELEM_FORMULA_AVERAGE, "FORMULA_AVERAGE" }, + { TELEM_FORMULA_MIN, "FORMULA_MIN" }, + { TELEM_FORMULA_MAX, "FORMULA_MAX" }, + { TELEM_FORMULA_MULTIPLY, "FORMULA_MULTIPLY" }, + { TELEM_FORMULA_TOTALIZE, "FORMULA_TOTALIZE" }, + { TELEM_FORMULA_CELL, "FORMULA_CELL" }, + { TELEM_FORMULA_CONSUMPTION, "FORMULA_CONSUMPTION" }, + { TELEM_FORMULA_DIST, "FORMULA_DIST" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TelemetrySensorType[] = { + { TELEM_TYPE_CUSTOM, "TYPE_CUSTOM" }, + { TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" }, + { 0, NULL } +}; +const struct YamlIdStr enum_ZoneOptionValueEnum[] = { + { ZOV_Unsigned, "Unsigned" }, + { ZOV_Signed, "Signed" }, + { ZOV_Bool, "Bool" }, + { ZOV_String, "String" }, + { ZOV_Source, "Source" }, + { ZOV_Color, "Color" }, + { 0, NULL } +}; +const struct YamlIdStr enum_USBJoystickIfMode[] = { + { USBJOYS_JOYSTICK, "JOYSTICK" }, + { USBJOYS_GAMEPAD, "GAMEPAD" }, + { USBJOYS_MULTIAXIS, "MULTIAXIS" }, + { 0, NULL } +}; +const struct YamlIdStr enum_USBJoystickCh[] = { + { USBJOYS_CH_NONE, "CH_NONE" }, + { USBJOYS_CH_BUTTON, "CH_BUTTON" }, + { USBJOYS_CH_AXIS, "CH_AXIS" }, + { USBJOYS_CH_SIM, "CH_SIM" }, + { 0, NULL } +}; + +// +// Structs last +// + +static const struct YamlNode struct_CalibData[] = { + YAML_IDX_CUST("calib",r_calib,w_calib), + YAML_SIGNED( "mid", 16 ), + YAML_SIGNED( "spanNeg", 16 ), + YAML_SIGNED( "spanPos", 16 ), + YAML_END +}; +static const struct YamlNode struct_signed_16[] = { + YAML_IDX, + YAML_SIGNED( "val", 16 ), + YAML_END +}; +static const struct YamlNode struct_TrainerMix[] = { + YAML_IDX, + YAML_UNSIGNED( "srcChn", 6 ), + YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_SIGNED( "studWeight", 8 ), + YAML_END +}; +static const struct YamlNode struct_TrainerData[] = { + YAML_ARRAY("calib", 16, 4, struct_signed_16, NULL), + YAML_ARRAY("mix", 16, 4, struct_TrainerMix, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_1[] = { + YAML_STRING("name", 8), + YAML_END +}; +static const struct YamlNode struct_anonymous_2[] = { + YAML_SIGNED( "val", 16 ), + YAML_UNSIGNED( "mode", 8 ), + YAML_UNSIGNED( "param", 8 ), + YAML_SIGNED( "val2", 32 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_3[] = { + YAML_SIGNED( "val1", 32 ), + YAML_SIGNED( "val2", 32 ), + YAML_END +}; +static const struct YamlNode union_anonymous_0_elmts[] = { + YAML_STRUCT("play", 64, struct_anonymous_1, NULL), + YAML_STRUCT("all", 64, struct_anonymous_2, NULL), + YAML_STRUCT("clear", 64, struct_anonymous_3, NULL), + YAML_END +}; +static const struct YamlNode struct_CustomFunctionData[] = { + YAML_IDX, + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_ENUM("func", 6, enum_Functions), + YAML_CUSTOM("def",r_customFn,w_customFn), + YAML_PADDING( 64 ), + YAML_PADDING( 1 ), + YAML_PADDING( 7 ), + YAML_END +}; +static const struct YamlNode struct_RadioData[] = { + YAML_UNSIGNED( "manuallyEdited", 1 ), + YAML_SIGNED( "timezoneMinutes", 3 ), + YAML_UNSIGNED( "ppmunit", 2 ), + YAML_PADDING( 2 ), + YAML_CUSTOM("semver",nullptr,w_semver), + YAML_CUSTOM("board",nullptr,w_board), + YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL), + YAML_PADDING( 16 ), + YAML_SIGNED( "currModel", 8 ), + YAML_UNSIGNED( "contrast", 8 ), + YAML_UNSIGNED( "vBatWarn", 8 ), + YAML_SIGNED( "txVoltageCalibration", 8 ), + YAML_ENUM("backlightMode", 3, enum_BacklightMode), + YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_UNSIGNED( "disableRtcWarning", 1 ), + YAML_UNSIGNED( "keysBacklight", 1 ), + YAML_UNSIGNED( "dontPlayHello", 1 ), + YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), + YAML_UNSIGNED( "view", 8 ), + YAML_PADDING( 2 ), + YAML_UNSIGNED( "fai", 1 ), + YAML_SIGNED_CUST( "beepMode", 2, r_beeperMode, w_beeperMode ), + YAML_UNSIGNED( "alarmsFlash", 1 ), + YAML_UNSIGNED( "disableMemoryWarning", 1 ), + YAML_UNSIGNED( "disableAlarmWarning", 1 ), + YAML_UNSIGNED( "stickMode", 2 ), + YAML_SIGNED( "timezone", 5 ), + YAML_UNSIGNED( "adjustRTC", 1 ), + YAML_UNSIGNED( "inactivityTimer", 8 ), + YAML_CUSTOM("telemetryBaudrate",r_telemetryBaudrate,nullptr), + YAML_UNSIGNED( "internalModuleBaudrate", 3 ), + YAML_SIGNED( "splashMode", 3 ), + YAML_SIGNED_CUST( "hapticMode", 2, r_beeperMode, w_beeperMode ), + YAML_SIGNED( "switchesDelay", 8 ), + YAML_UNSIGNED( "lightAutoOff", 8 ), + YAML_UNSIGNED( "templateSetup", 8 ), + YAML_SIGNED( "PPM_Multiplier", 8 ), + YAML_SIGNED_CUST( "hapticLength", 8, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "beepLength", 3, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "hapticStrength", 3, r_5pos, w_5pos ), + YAML_UNSIGNED( "gpsFormat", 1 ), + YAML_UNSIGNED( "audioMuteEnable", 1 ), + YAML_UNSIGNED_CUST( "speakerPitch", 8, r_spPitch, w_spPitch ), + YAML_SIGNED_CUST( "speakerVolume", 8, r_vol, w_vol ), + YAML_SIGNED_CUST( "vBatMin", 8, r_vbat_min, w_vbat_min ), + YAML_SIGNED_CUST( "vBatMax", 8, r_vbat_max, w_vbat_max ), + YAML_UNSIGNED( "backlightBright", 8 ), + YAML_UNSIGNED( "globalTimer", 32 ), + YAML_UNSIGNED( "bluetoothBaudrate", 4 ), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_UNSIGNED( "countryCode", 2 ), + YAML_SIGNED( "pwrOnSpeed", 3 ), + YAML_SIGNED( "pwrOffSpeed", 3 ), + YAML_CUSTOM("jitterFilter",r_jitterFilter,nullptr), + YAML_UNSIGNED( "noJitterFilter", 1 ), + YAML_UNSIGNED( "imperial", 1 ), + YAML_UNSIGNED( "disableRssiPoweroffAlarm", 1 ), + YAML_UNSIGNED( "USBMode", 2 ), + YAML_UNSIGNED( "jackMode", 2 ), + YAML_PADDING( 1 ), + YAML_STRING("ttsLanguage", 2), + YAML_SIGNED_CUST( "beepVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "wavVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "varioVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "backgroundVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), + YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), + YAML_SIGNED( "varioRepeat", 8 ), + YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), + YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), + YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), + YAML_ARRAY("sticksConfig", 0, MAX_STICKS, struct_stickConfig, stick_name_valid), + 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 ), + YAML_STRING("bluetoothName", 10), + YAML_STRING("ownerRegistrationID", 8), + YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr), + YAML_UNSIGNED( "rotEncMode", 3 ), + YAML_SIGNED( "uartSampleMode", 2 ), + YAML_UNSIGNED( "stickDeadZone", 3 ), + YAML_STRING("selectedTheme", 26), + YAML_UNSIGNED( "labelSingleSelect", 1 ), + YAML_UNSIGNED( "labelMultiMode", 1 ), + YAML_UNSIGNED( "favMultiMode", 1 ), + YAML_UNSIGNED( "modelSelectLayout", 2 ), + YAML_UNSIGNED( "radioThemesDisabled", 1 ), + YAML_UNSIGNED( "radioGFDisabled", 1 ), + YAML_UNSIGNED( "radioTrainerDisabled", 1 ), + YAML_UNSIGNED( "modelHeliDisabled", 1 ), + YAML_UNSIGNED( "modelFMDisabled", 1 ), + YAML_UNSIGNED( "modelCurvesDisabled", 1 ), + YAML_UNSIGNED( "modelGVDisabled", 1 ), + YAML_UNSIGNED( "modelLSDisabled", 1 ), + YAML_UNSIGNED( "modelSFDisabled", 1 ), + YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ), + YAML_UNSIGNED( "modelTelemetryDisabled", 1 ), + YAML_UNSIGNED( "disableTrainerPoweroffAlarm", 1 ), + YAML_UNSIGNED( "disablePwrOnOffHaptic", 1 ), + YAML_PADDING( 6 ), + YAML_UNSIGNED( "pwrOffIfInactive", 8 ), + YAML_END +}; +static const struct YamlNode struct_unsigned_8[] = { + YAML_IDX, + YAML_UNSIGNED( "val", 8 ), + YAML_END +}; +static const struct YamlNode struct_ModelHeader[] = { + YAML_STRING("name", 15), + YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL), + YAML_STRING("bitmap", 14), + YAML_STRING("labels", 100), + YAML_END +}; +static const struct YamlNode struct_TimerData[] = { + YAML_IDX, + YAML_UNSIGNED( "start", 22 ), + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_SIGNED( "value", 22 ), + YAML_ENUM("mode", 3, enum_TimerModes), + YAML_UNSIGNED( "countdownBeep", 2 ), + YAML_UNSIGNED( "minuteBeep", 1 ), + YAML_UNSIGNED( "persistent", 2 ), + YAML_SIGNED( "countdownStart", 2 ), + YAML_UNSIGNED( "showElapsed", 1 ), + YAML_UNSIGNED( "extraHaptic", 1 ), + YAML_PADDING( 6 ), + YAML_STRING("name", 8), + YAML_END +}; +static const struct YamlNode struct_CurveRef[] = { + YAML_UNSIGNED( "type", 5 ), + YAML_SIGNED_CUST( "value", 11, r_sourceNumVal, w_sourceNumVal ), + YAML_END +}; +static const struct YamlNode struct_MixData[] = { + YAML_UNSIGNED( "destCh", 5 ), + YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), + YAML_UNSIGNED( "carryTrim", 1 ), + YAML_UNSIGNED( "mixWarn", 2 ), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_UNSIGNED( "delayPrec", 1 ), + YAML_UNSIGNED( "speedPrec", 1 ), + YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), + YAML_PADDING( 1 ), + YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ), + YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ), + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_STRUCT("curve", 16, struct_CurveRef, NULL), + YAML_UNSIGNED( "delayUp", 8 ), + YAML_UNSIGNED( "delayDown", 8 ), + YAML_UNSIGNED( "speedUp", 8 ), + YAML_UNSIGNED( "speedDown", 8 ), + YAML_STRING("name", 6), + YAML_END +}; +static const struct YamlNode struct_LimitData[] = { + YAML_IDX, + YAML_SIGNED_CUST( "min", 11, in_read_weight, in_write_weight ), + YAML_SIGNED_CUST( "max", 11, in_read_weight, in_write_weight ), + YAML_SIGNED( "ppmCenter", 10 ), + YAML_SIGNED_CUST( "offset", 11, in_read_weight, in_write_weight ), + YAML_UNSIGNED( "symetrical", 1 ), + YAML_UNSIGNED( "revert", 1 ), + YAML_PADDING( 3 ), + YAML_SIGNED( "curve", 8 ), + YAML_STRING("name", 6), + YAML_END +}; +static const struct YamlNode struct_ExpoData[] = { + YAML_UNSIGNED( "mode", 2 ), + YAML_UNSIGNED( "scale", 14 ), + YAML_CUSTOM("carryTrim",r_carryTrim,nullptr), + YAML_SIGNED( "trimSource", 6 ), + YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), + YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ), + YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ), + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_STRUCT("curve", 16, struct_CurveRef, NULL), + YAML_UNSIGNED( "chn", 5 ), + YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), + YAML_PADDING( 2 ), + YAML_STRING("name", 6), + YAML_END +}; +static const struct YamlNode struct_CurveHeader[] = { + YAML_IDX, + YAML_UNSIGNED( "type", 1 ), + YAML_UNSIGNED( "smooth", 1 ), + YAML_SIGNED( "points", 6 ), + YAML_STRING("name", 3), + YAML_END +}; +static const struct YamlNode struct_signed_8[] = { + YAML_IDX, + YAML_SIGNED( "val", 8 ), + YAML_END +}; +static const struct YamlNode struct_LogicalSwitchData[] = { + YAML_IDX, + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_CUSTOM("def",r_logicSw,w_logicSw), + YAML_PADDING( 10 ), + YAML_PADDING( 10 ), + YAML_SIGNED_CUST( "andsw", 10, r_swtchSrc, w_swtchSrc ), + YAML_UNSIGNED( "lsPersist", 1 ), + YAML_UNSIGNED( "lsState", 1 ), + YAML_PADDING( 16 ), + YAML_UNSIGNED( "delay", 8 ), + YAML_UNSIGNED( "duration", 8 ), + YAML_END +}; +static const struct YamlNode struct_SwashRingData[] = { + YAML_ENUM("type", 8, enum_SwashType), + YAML_UNSIGNED( "value", 8 ), + YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_UNSIGNED_CUST( "elevatorSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_SIGNED( "collectiveWeight", 8 ), + YAML_SIGNED( "aileronWeight", 8 ), + YAML_SIGNED( "elevatorWeight", 8 ), + YAML_END +}; +static const struct YamlNode struct_trim_t[] = { + YAML_IDX, + YAML_SIGNED( "value", 11 ), + YAML_UNSIGNED( "mode", 5 ), + YAML_END +}; +static const struct YamlNode struct_FlightModeData[] = { + YAML_IDX, + YAML_ARRAY("trim", 16, 8, struct_trim_t, NULL), + YAML_STRING("name", 10), + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_PADDING( 6 ), + YAML_UNSIGNED( "fadeIn", 8 ), + YAML_UNSIGNED( "fadeOut", 8 ), + YAML_ARRAY("gvars", 16, 9, struct_signed_16, gvar_is_active), + YAML_END +}; +static const struct YamlNode struct_GVarData[] = { + YAML_IDX, + YAML_STRING("name", 3), + YAML_UNSIGNED( "min", 12 ), + YAML_UNSIGNED( "max", 12 ), + YAML_UNSIGNED( "popup", 1 ), + YAML_UNSIGNED( "prec", 1 ), + YAML_UNSIGNED( "unit", 2 ), + YAML_PADDING( 4 ), + YAML_END +}; +static const struct YamlNode struct_VarioData[] = { + YAML_UNSIGNED_CUST( "source", 7, r_tele_sensor, w_tele_sensor ), + YAML_UNSIGNED( "centerSilent", 1 ), + YAML_SIGNED( "centerMax", 8 ), + YAML_SIGNED( "centerMin", 8 ), + YAML_SIGNED( "min", 8 ), + YAML_SIGNED( "max", 8 ), + YAML_END +}; +static const struct YamlNode struct_RssiAlarmData[] = { + YAML_CUSTOM("disabled",r_rssiDisabled,nullptr), + YAML_CUSTOM("warning",r_rssiWarning,nullptr), + YAML_CUSTOM("critical",r_rssiCritical,nullptr), + YAML_END +}; +static const struct YamlNode struct_RFAlarmData[] = { + YAML_SIGNED( "warning", 8 ), + YAML_SIGNED( "critical", 8 ), + YAML_END +}; +static const struct YamlNode struct_PpmModule[] = { + YAML_SIGNED( "delay", 6 ), + YAML_UNSIGNED( "pulsePol", 1 ), + YAML_UNSIGNED( "outputType", 1 ), + YAML_SIGNED( "frameLength", 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_5[] = { + YAML_PADDING( 8 ), + YAML_UNSIGNED( "disableTelemetry", 1 ), + YAML_UNSIGNED( "disableMapping", 1 ), + YAML_UNSIGNED( "autoBindMode", 1 ), + YAML_UNSIGNED( "lowPowerMode", 1 ), + YAML_UNSIGNED( "receiverTelemetryOff", 1 ), + YAML_UNSIGNED( "receiverHigherChannels", 1 ), + YAML_PADDING( 2 ), + YAML_SIGNED( "optionValue", 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_6[] = { + YAML_UNSIGNED( "power", 2 ), + YAML_PADDING( 2 ), + YAML_UNSIGNED( "receiverTelemetryOff", 1 ), + YAML_UNSIGNED( "receiverHigherChannels", 1 ), + YAML_SIGNED( "antennaMode", 2 ), + YAML_PADDING( 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_7[] = { + YAML_PADDING( 6 ), + YAML_UNSIGNED( "noninverted", 1 ), + YAML_PADDING( 1 ), + YAML_SIGNED( "refreshRate", 8 ), + YAML_END +}; +static const struct YamlNode struct_string_64[] = { + YAML_IDX, + YAML_STRING("val", 8), + YAML_END +}; +static const struct YamlNode struct_anonymous_8[] = { + YAML_UNSIGNED( "receivers", 7 ), + YAML_UNSIGNED( "racingMode", 1 ), + YAML_ARRAY("receiverName", 64, 3, struct_string_64, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_9[] = { + YAML_ARRAY("rx_id", 8, 4, struct_unsigned_8, NULL), + YAML_UNSIGNED( "mode", 3 ), + YAML_UNSIGNED( "rfPower", 1 ), + YAML_UNSIGNED( "reserved", 4 ), + YAML_ARRAY("rx_freq", 8, 2, struct_unsigned_8, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_10[] = { + YAML_UNSIGNED( "emi", 2 ), + YAML_UNSIGNED( "telemetry", 1 ), + YAML_UNSIGNED( "phyMode", 3 ), + YAML_UNSIGNED( "reserved", 2 ), + YAML_UNSIGNED( "rfPower", 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_11[] = { + YAML_UNSIGNED( "raw12bits", 1 ), + YAML_UNSIGNED( "telemetryBaudrate", 3 ), + YAML_PADDING( 4 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_12[] = { + YAML_UNSIGNED( "telemetryBaudrate", 3 ), + YAML_UNSIGNED( "crsfArmingMode", 1 ), + YAML_PADDING( 4 ), + YAML_SIGNED_CUST( "crsfArmingTrigger", 10, r_swtchSrc, w_swtchSrc ), + YAML_SIGNED( "spare3", 6 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_13[] = { + YAML_UNSIGNED( "flags", 8 ), + YAML_END +}; +static const struct YamlNode union_anonymous_4_elmts[] = { + YAML_ARRAY("raw", 8, 25, struct_unsigned_8, NULL), + YAML_STRUCT("ppm", 16, struct_PpmModule, NULL), + YAML_STRUCT("multi", 24, struct_anonymous_5, NULL), + YAML_STRUCT("pxx", 16, struct_anonymous_6, NULL), + YAML_STRUCT("sbus", 16, struct_anonymous_7, NULL), + YAML_STRUCT("pxx2", 200, struct_anonymous_8, NULL), + YAML_STRUCT("flysky", 56, struct_anonymous_9, NULL), + YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL), + YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL), + YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL), + YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL), + YAML_END +}; +static const struct YamlNode struct_ModuleData[] = { + YAML_IDX, + YAML_UNSIGNED_CUST( "type", 8, r_moduleType, w_moduleType ), + YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), + YAML_UNSIGNED( "channelsStart", 8 ), + YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_PADDING( 4 ), + YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), + YAML_END +}; +static const struct YamlNode struct_TrainerModuleData[] = { + YAML_UNSIGNED_CUST( "mode", 8, r_trainerMode, w_trainerMode ), + YAML_UNSIGNED( "channelsStart", 8 ), + YAML_SIGNED( "channelsCount", 8 ), + YAML_SIGNED( "frameLength", 8 ), + YAML_SIGNED( "delay", 6 ), + YAML_UNSIGNED( "pulsePol", 1 ), + YAML_PADDING( 1 ), + YAML_END +}; +static const struct YamlNode union_ScriptDataInput_elmts[] = { + YAML_SIGNED( "value", 16 ), + YAML_UNSIGNED_CUST( "source", 16, r_mixSrcRaw, w_mixSrcRaw ), + YAML_END +}; +static const struct YamlNode union_ScriptDataInput[] = { + YAML_IDX, + YAML_UNION("u", 16, union_ScriptDataInput_elmts, select_script_input), + YAML_END +}; +static const struct YamlNode struct_ScriptData[] = { + YAML_IDX, + YAML_STRING("file", 6), + YAML_STRING("name", 6), + YAML_ARRAY("inputs", 16, 6, union_ScriptDataInput, NULL), + YAML_END +}; +static const struct YamlNode struct_string_32[] = { + YAML_IDX, + YAML_STRING("val", 4), + YAML_END +}; +static const struct YamlNode union_anonymous_14_elmts[] = { + YAML_UNSIGNED( "id", 16 ), + YAML_UNSIGNED( "persistentValue", 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_16[] = { + YAML_UNSIGNED( "physID", 5 ), + YAML_UNSIGNED( "rxIndex", 3 ), + YAML_END +}; +static const struct YamlNode union_anonymous_15_elmts[] = { + YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), + YAML_UNSIGNED( "instance", 8 ), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_END +}; +static const struct YamlNode struct_anonymous_18[] = { + YAML_UNSIGNED( "ratio", 16 ), + YAML_SIGNED( "offset", 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_19[] = { + YAML_UNSIGNED( "source", 8 ), + YAML_UNSIGNED( "index", 8 ), + YAML_PADDING( 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_20[] = { + YAML_ARRAY("sources", 8, 4, struct_signed_8, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_21[] = { + YAML_UNSIGNED( "source", 8 ), + YAML_PADDING( 24 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_22[] = { + YAML_UNSIGNED( "gps", 8 ), + YAML_UNSIGNED( "alt", 8 ), + YAML_PADDING( 16 ), + YAML_END +}; +static const struct YamlNode union_anonymous_17_elmts[] = { + YAML_STRUCT("custom", 32, struct_anonymous_18, NULL), + YAML_STRUCT("cell", 32, struct_anonymous_19, NULL), + YAML_STRUCT("calc", 32, struct_anonymous_20, NULL), + YAML_STRUCT("consumption", 32, struct_anonymous_21, NULL), + YAML_STRUCT("dist", 32, struct_anonymous_22, NULL), + YAML_UNSIGNED( "param", 32 ), + YAML_END +}; +static const struct YamlNode struct_TelemetrySensor[] = { + YAML_IDX, + YAML_UNION("id1", 16, union_anonymous_14_elmts, select_id1), + YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), + YAML_STRING("label", 4), + YAML_UNSIGNED( "subId", 8 ), + YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_PADDING( 1 ), + YAML_UNSIGNED( "unit", 6 ), + YAML_UNSIGNED( "prec", 2 ), + YAML_UNSIGNED( "autoOffset", 1 ), + YAML_UNSIGNED( "filter", 1 ), + YAML_UNSIGNED( "logs", 1 ), + YAML_UNSIGNED( "persistent", 1 ), + YAML_UNSIGNED( "onlyPositive", 1 ), + YAML_PADDING( 1 ), + YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg), + YAML_END +}; +static const struct YamlNode union_ZoneOptionValue_elmts[] = { + YAML_UNSIGNED( "unsignedValue", 32 ), + YAML_SIGNED( "signedValue", 32 ), + YAML_UNSIGNED( "boolValue", 32 ), + YAML_STRING("stringValue", 12), + YAML_CUSTOM("source",r_zov_source,w_zov_source), + YAML_CUSTOM("color",r_zov_color,w_zov_color), + YAML_END +}; +static const struct YamlNode struct_ZoneOptionValueTyped[] = { + YAML_IDX, + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), + YAML_END +}; +static const struct YamlNode struct_WidgetPersistentData[] = { + YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL), + YAML_END +}; +static const struct YamlNode struct_ZonePersistentData[] = { + YAML_IDX, + YAML_STRING("widgetName", 20), + YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL), + YAML_END +}; +static const struct YamlNode struct_LayoutPersistentData[] = { + YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL), + YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL), + YAML_END +}; +static const struct YamlNode struct_CustomScreenData[] = { + YAML_IDX, + YAML_STRING("LayoutId", 12), + YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL), + YAML_END +}; +static const struct YamlNode struct_TopBarPersistentData[] = { + YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL), + YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL), + YAML_END +}; +static const struct YamlNode struct_USBJoystickChData[] = { + YAML_IDX, + YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_UNSIGNED( "inversion", 1 ), + YAML_UNSIGNED( "param", 4 ), + YAML_UNSIGNED( "btn_num", 5 ), + YAML_UNSIGNED( "switch_npos", 3 ), + YAML_END +}; +static const struct YamlNode struct_ModelData[] = { + YAML_CUSTOM("semver",nullptr,w_semver), + YAML_STRUCT("header", 1048, struct_ModelHeader, NULL), + YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL), + YAML_UNSIGNED( "telemetryProtocol", 3 ), + YAML_UNSIGNED( "thrTrim", 1 ), + YAML_UNSIGNED( "noGlobalFunctions", 1 ), + YAML_UNSIGNED( "displayTrims", 2 ), + YAML_UNSIGNED( "ignoreSensorIds", 1 ), + YAML_SIGNED( "trimInc", 3 ), + YAML_UNSIGNED( "disableThrottleWarning", 1 ), + YAML_UNSIGNED( "displayChecklist", 1 ), + YAML_UNSIGNED( "extendedLimits", 1 ), + YAML_UNSIGNED( "extendedTrims", 1 ), + YAML_UNSIGNED( "throttleReversed", 1 ), + YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), + YAML_UNSIGNED( "disableTelemetryWarning", 1 ), + YAML_UNSIGNED( "showInstanceIds", 1 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), + YAML_SIGNED( "customThrottleWarningPosition", 8 ), + YAML_UNSIGNED( "beepANACenter", 16 ), + YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), + YAML_ARRAY("limitData", 104, 32, struct_LimitData, NULL), + YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), + YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), + YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), + YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), + YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), + YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), + YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), + YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), + YAML_PADDING(1), + YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), + YAML_STRUCT("varioData", 40, struct_VarioData, NULL), + YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), + YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), + YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), + YAML_UNSIGNED( "thrTrimSw", 3 ), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_PADDING( 1 ), + YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), + YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), + YAML_STRUCT("trainerData", 40, struct_TrainerModuleData, NULL), + YAML_ARRAY("scriptsData", 192, 9, struct_ScriptData, NULL), + YAML_ARRAY("inputNames", 32, 32, struct_string_32, NULL), + YAML_UNSIGNED( "potsWarnEnabled", 16 ), + YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL), + YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL), + YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL), + YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL), + YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL), + YAML_UNSIGNED( "view", 8 ), + YAML_STRING("modelRegistrationID", 8), + YAML_UNSIGNED( "usbJoystickExtMode", 1 ), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), + YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_END +}; +static const struct YamlNode struct_PartialModel[] = { + YAML_STRUCT("header", 1048, struct_ModelHeader, NULL), + YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL), + YAML_END +}; + +#define MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN 29 + +static const struct YamlNode __RadioData_root_node = YAML_ROOT( struct_RadioData ); + +const YamlNode* get_radiodata_nodes() +{ + return &__RadioData_root_node; +} +static const struct YamlNode __ModelData_root_node = YAML_ROOT( struct_ModelData ); + +const YamlNode* get_modeldata_nodes() +{ + return &__ModelData_root_node; +} +static const struct YamlNode __PartialModel_root_node = YAML_ROOT( struct_PartialModel ); + +const YamlNode* get_partialmodel_nodes() +{ + return &__PartialModel_root_node; +} + diff --git a/tools/generate-yaml.sh b/tools/generate-yaml.sh index 665f3f1904d..ef569312ab8 100755 --- a/tools/generate-yaml.sh +++ b/tools/generate-yaml.sh @@ -11,7 +11,7 @@ if [[ -n ${GCC_ARM} ]] ; then export PATH=${GCC_ARM}:$PATH fi -: ${FLAVOR:="t15;tx16s;pl18;nv14;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16"} +: ${FLAVOR:="t15;tx16s;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16"} : ${SRCDIR:=$(dirname "$(pwd)/$0")/..} : ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -Wno-dev -DDISABLE_COMPANION=YES -DCMAKE_MESSAGE_LOG_LEVEL=WARNING"} From cc06d12bd3565690e7b09e72bc46e4e41f796e8d Mon Sep 17 00:00:00 2001 From: Peter Feerick Date: Sun, 1 Jun 2025 10:25:49 +0000 Subject: [PATCH 13/13] chore: Initial Companion support --- companion/src/CMakeLists.txt | 2 ++ companion/src/firmwares/boards.cpp | 9 ++++++++- companion/src/firmwares/boards.h | 8 +++++++- companion/src/firmwares/opentx/opentxinterface.cpp | 7 +++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 57f3c816252..506c4670576 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -356,6 +356,8 @@ elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL EL18) set(FLAVOUR el18) elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL PL18EV) set(FLAVOUR pl18ev) +elseif(PCB STREQUAL PL18 AND PCBREV STREQUAL PL18U) + set(FLAVOUR pl18u) elseif(PCB STREQUAL PL18) set(FLAVOUR pl18) elseif(PCB STREQUAL ST16) diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 60ec9fad771..0adc9f974a7 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -157,6 +157,7 @@ uint32_t Boards::getFourCC(Type board) return 0x3A78746F; case BOARD_FLYSKY_PL18: case BOARD_FLYSKY_PL18EV: + case BOARD_FLYSKY_PL18U: return 0x4878746F; case BOARD_FLYSKY_ST16: return 0x4C78746F; @@ -218,6 +219,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_FLYSKY_EL18: case BOARD_FLYSKY_PL18: case BOARD_FLYSKY_PL18EV: + case BOARD_FLYSKY_PL18U: case BOARD_FLYSKY_ST16: case BOARD_FATFISH_F16: case BOARD_HELLORADIOSKY_V16: @@ -278,6 +280,7 @@ int Boards::getFlashSize(Type board) case BOARD_FLYSKY_EL18: case BOARD_FLYSKY_PL18: case BOARD_FLYSKY_PL18EV: + case BOARD_FLYSKY_PL18U: case BOARD_FLYSKY_ST16: case BOARD_FATFISH_F16: case BOARD_HELLORADIOSKY_V16: @@ -516,7 +519,7 @@ StringTagMappingTable Boards::getLegacyAnalogsLookupTable(Board::Type board) {tr("SL1").toStdString(), "LS"}, {tr("SL2").toStdString(), "RS"}, }); - } else if (IS_FLYSKY_PL18(board)) { + } else if (IS_FLYSKY_PL18(board) || IS_FLYSKY_PL18U(board)) { tbl.insert(tbl.end(), { {tr("P1").toStdString(), "POT1"}, {tr("P2").toStdString(), "POT2"}, @@ -661,6 +664,8 @@ QString Boards::getBoardName(Board::Type board) return "FlySky PL18"; case BOARD_FLYSKY_PL18EV: return "FlySky PL18EV"; + case BOARD_FLYSKY_PL18U: + return "FlySky PL18U"; case BOARD_FLYSKY_ST16: return "FlySky ST16"; case BOARD_BETAFPV_LR3PRO: @@ -801,6 +806,7 @@ int Boards::getDefaultInternalModules(Board::Type board) return (int)MODULE_TYPE_FLYSKY_AFHDS2A; case BOARD_FLYSKY_EL18: + case BOARD_FLYSKY_PL18U: return (int)MODULE_TYPE_FLYSKY_AFHDS3; default: @@ -861,6 +867,7 @@ void Boards::getBattRange(Board::Type board, int& vmin, int& vmax, unsigned int& break; case BOARD_FLYSKY_PL18: case BOARD_FLYSKY_PL18EV: + case BOARD_FLYSKY_PL18U: BR(35, 43, 37) break; case BOARD_FLYSKY_ST16: diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index a787c294fdc..3efa007b17d 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -79,6 +79,7 @@ namespace Board { BOARD_FLYSKY_NV14, BOARD_FLYSKY_PL18, BOARD_FLYSKY_PL18EV, + BOARD_FLYSKY_PL18U, BOARD_FLYSKY_ST16, BOARD_RADIOMASTER_ZORRO, BOARD_JUMPER_TPRO, @@ -667,6 +668,11 @@ inline bool IS_FLYSKY_PL18EV(Board::Type board) return (board == Board::BOARD_FLYSKY_PL18EV); } +inline bool IS_FLYSKY_PL18U(Board::Type board) +{ + return (board == Board::BOARD_FLYSKY_PL18U); +} + inline bool IS_FLYSKY_ST16(Board::Type board) { return (board == Board::BOARD_FLYSKY_ST16); @@ -674,7 +680,7 @@ inline bool IS_FLYSKY_ST16(Board::Type board) inline bool IS_FAMILY_PL18(Board::Type board) { - return IS_FLYSKY_PL18(board) || IS_FLYSKY_PL18EV(board); + return IS_FLYSKY_PL18(board) || IS_FLYSKY_PL18EV(board) || IS_FLYSKY_PL18U(board); } inline bool IS_TARANIS_XLITE(Board::Type board) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index dc1d24ecdb9..cd337035e4e 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -512,6 +512,13 @@ void registerOpenTxFirmwares() addOpenTxRfOptions(firmware, FLEX + AFHDS3); registerOpenTxFirmware(firmware); + /* FlySky PL18U board */ + firmware = new OpenTxFirmware(FIRMWAREID("pl18u"), Firmware::tr("FlySky PL18U"), BOARD_FLYSKY_PL18U); + addOpenTxFrskyOptions(firmware); + firmware->addOption(opt_bt); + addOpenTxRfOptions(firmware, FLEX + AFHDS3); + registerOpenTxFirmware(firmware); + /* FlySky ST16 board */ firmware = new OpenTxFirmware(FIRMWAREID("st16"), Firmware::tr("FlySky ST16"), BOARD_FLYSKY_ST16); addOpenTxFrskyOptions(firmware);