diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 7f2047cb0..fb2a41605 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -109,7 +109,8 @@ body: - HelloRadioSky V16 - Jumper T12 - Jumper T14 - - Jumper T15 + - Jumper T15 + - Jumper T15Pro - Jumper T16 - Jumper T18 - Jumper T20/T20S diff --git a/.github/workflows/build_fw.yml b/.github/workflows/build_fw.yml index 5d52656ae..257a589e4 100644 --- a/.github/workflows/build_fw.yml +++ b/.github/workflows/build_fw.yml @@ -55,6 +55,7 @@ jobs: - gx12 - nb4p - st16 + - t15pro container: image: ghcr.io/edgetx/edgetx-dev:latest volumes: @@ -102,6 +103,7 @@ jobs: - mt12;gx12 - nb4p - st16 + - t15pro container: image: ghcr.io/edgetx/edgetx-dev:latest volumes: diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 78e0902f8..309ec87e2 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -209,6 +209,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_X10: case BOARD_X10_EXPRESS: case BOARD_JUMPER_T15: + case BOARD_JUMPER_T15PRO: case BOARD_JUMPER_T16: case BOARD_JUMPER_T18: case BOARD_RADIOMASTER_TX16S: @@ -269,6 +270,7 @@ int Boards::getFlashSize(Type board) case BOARD_X10: case BOARD_X10_EXPRESS: case BOARD_JUMPER_T15: + case BOARD_JUMPER_T15PRO: case BOARD_JUMPER_T16: case BOARD_JUMPER_T18: case BOARD_RADIOMASTER_TX16S: @@ -384,7 +386,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case LcdHeight: if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board)) return 480; - else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_FLYSKY_ST16(board) || IS_RADIOMASTER_TX15(board)) + else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_JUMPER_T15PRO(board) || IS_FLYSKY_ST16(board) || IS_RADIOMASTER_TX15(board)) return 320; else if (IS_FLYSKY_PA01(board)) return 240; @@ -630,6 +632,8 @@ QString Boards::getBoardName(Board::Type board) return "Jumper T14"; case BOARD_JUMPER_T15: return "Jumper T15"; + case BOARD_JUMPER_T15PRO: + return "Jumper T15Pro"; case BOARD_JUMPER_T16: return "Jumper T16"; case BOARD_JUMPER_T18: @@ -794,6 +798,7 @@ int Boards::getDefaultInternalModules(Board::Type board) case BOARD_JUMPER_T12MAX: case BOARD_JUMPER_T14: case BOARD_JUMPER_T15: + case BOARD_JUMPER_T15PRO: case BOARD_JUMPER_T20: case BOARD_JUMPER_TPROS: case BOARD_JUMPER_T20V2: diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 48c478051..1507e8137 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -62,6 +62,7 @@ namespace Board { BOARD_JUMPER_T12MAX, BOARD_JUMPER_T14, BOARD_JUMPER_T15, + BOARD_JUMPER_T15PRO, BOARD_JUMPER_T16, BOARD_RADIOMASTER_TX16S, BOARD_RADIOMASTER_TX15, @@ -534,6 +535,11 @@ inline bool IS_JUMPER_T15(Board::Type board) return board == Board::BOARD_JUMPER_T15; } +inline bool IS_JUMPER_T15PRO(Board::Type board) +{ + return board == Board::BOARD_JUMPER_T15PRO; +} + inline bool IS_JUMPER_T16(Board::Type board) { return board == Board::BOARD_JUMPER_T16; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 47a7c62e7..0086bd6f1 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -326,7 +326,7 @@ int OpenTxFirmware::getCapability(::Capability capability) IS_JUMPER_T15(board) || IS_JUMPER_T18(board) || IS_JUMPER_T20(board) || IS_JUMPER_TPRO(board) || IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_GX12(board) || IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_POCKET(board) || IS_RADIOMASTER_TX12(board) || IS_RADIOMASTER_TX12_MK2(board) || - IS_RADIOMASTER_TX16S(board) || IS_RADIOMASTER_ZORRO(board) || IS_RADIOMASTER_TX15(board)); + IS_RADIOMASTER_TX16S(board) || IS_RADIOMASTER_ZORRO(board) || IS_RADIOMASTER_TX15(board) || IS_JUMPER_T15PRO(board)); case HasSoftwareSerialPower: return IS_RADIOMASTER_TX16S(board); case HasIntModuleMulti: @@ -342,7 +342,7 @@ int OpenTxFirmware::getCapability(::Capability capability) return id.contains("internalelrs") || IS_RADIOMASTER_TX12_MK2(board) || IS_IFLIGHT_COMMANDO8(board) || IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_POCKET(board) || IS_JUMPER_T20(board) || - IS_RADIOMASTER_MT12(board); + IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_TX15(board) || IS_JUMPER_T15PRO(board); case HasIntModuleFlySky: return id.contains("afhds2a") || id.contains("afhds3") || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FAMILY_PL18(board); @@ -722,6 +722,12 @@ void registerOpenTxFirmwares() addOpenTxRfOptions(firmware, FLEX); registerOpenTxFirmware(firmware); + /* Jumper T15Pro board */ + firmware = new OpenTxFirmware(FIRMWAREID("t15pro"), Firmware::tr("Jumper T15Pro"), BOARD_JUMPER_T15PRO); + addOpenTxFrskyOptions(firmware); + addOpenTxRfOptions(firmware, FLEX); + registerOpenTxFirmware(firmware); + /* Jumper T16 board */ firmware = new OpenTxFirmware(FIRMWAREID("t16"), Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); addOpenTxFrskyOptions(firmware); diff --git a/fw.json b/fw.json index d4a74c149..57b586d08 100644 --- a/fw.json +++ b/fw.json @@ -26,6 +26,7 @@ ["Jumper T12 MAX", "t12max-"], ["Jumper T14", "t14-"], ["Jumper T15", "t15-"], + ["Jumper T15Pro", "t15pro-"], ["Jumper T16", "t16-"], ["Jumper T18", "t18-"], ["Jumper T20", "t20-"], diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index f63a00225..ca57b7c90 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -1,7 +1,7 @@ include(CMakeForceCompiler) include(Bitmaps) -set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 ST16 PA01 TX15) +set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 T15PRO ST16 PA01 TX15) set(RADIO_LANGUAGES CN CZ DA DE EN ES FI FR HE HU IT JP KO NL PL PT RU SE SK TW UA) set(TTS_LANGUAGES CN CZ DA DE EN ES FR HE HU IT JP KO NL PL PT RU SE SK UA) @@ -86,6 +86,8 @@ elseif(PCB STREQUAL NV14) include(targets/nv14/CMakeLists.txt) elseif(PCB STREQUAL PL18) include(targets/pl18/CMakeLists.txt) +elseif(PCB STREQUAL T15PRO) + include(targets/t15pro/CMakeLists.txt) elseif(PCB STREQUAL ST16) include(targets/st16/CMakeLists.txt) elseif(PCB STREQUAL PA01) @@ -398,7 +400,7 @@ endif() add_definitions(-DPOPUP_LEVEL=${POPUP_LEVEL}) -if(INTERNAL_MODULE_MULTI) +if(INTERNAL_MODULE_MULTI OR INTERNAL_MODULE_CRSF) set(DEFAULT_TEMPLATE_SETUP 21 CACHE STRING "") else() set(DEFAULT_TEMPLATE_SETUP 0 CACHE STRING "") diff --git a/radio/src/boards/jumper-h750/backlight_driver.cpp b/radio/src/boards/jumper-h750/backlight_driver.cpp new file mode 100644 index 000000000..b87dc4a26 --- /dev/null +++ b/radio/src/boards/jumper-h750/backlight_driver.cpp @@ -0,0 +1,94 @@ +/* + * 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/gpio.h" +#include "stm32_gpio.h" +#include "stm32_timer.h" +#include "stm32_pulse_driver.h" + +#include "edgetx_types.h" +#include "board.h" + +#include "globals.h" + +static const stm32_pulse_timer_t _bl_timer = { + .GPIO = (gpio_t)BACKLIGHT_GPIO, + .GPIO_Alternate = BACKLIGHT_GPIO_AF, + .TIMx = BACKLIGHT_TIMER, + .TIM_Freq = BACKLIGHT_TIMER_FREQ, + .TIM_Channel = BACKLIGHT_TIMER_CHANNEL, + .TIM_IRQn = (IRQn_Type)-1, + .DMAx = nullptr, + .DMA_Stream = 0, + .DMA_Channel = 0, + .DMA_IRQn = (IRQn_Type)-1, + .DMA_TC_CallbackPtr = nullptr, +}; + +void backlightLowInit() +{ + gpio_init(BACKLIGHT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); + gpio_clear(BACKLIGHT_GPIO); +} + +void backlightInit() +{ + stm32_pulse_init(&_bl_timer, 10000); + stm32_pulse_config_output(&_bl_timer, true, LL_TIM_OCMODE_PWM1, 100); + LL_TIM_SetAutoReload(_bl_timer.TIMx, 100); + LL_TIM_EnableCounter(_bl_timer.TIMx); +} + +uint8_t lastDutyCycle = 0; + +void backlightEnable(uint8_t dutyCycle) +{ + stm32_pulse_set_cmp_val(&_bl_timer, dutyCycle); + + // TODO: removed until QSPI & LCD SPI are split + // if(!dutyCycle) { + // //experimental to turn off LCD when no backlight + // // if(lcdOffFunction) lcdOffFunction(); + // } + // else if(!lastDutyCycle) { + // // if(lcdOnFunction) lcdOnFunction(); + // // else lcdInit(); + // } + + // lastDutyCycle = dutyCycle; +} + +void lcdOff() { + backlightEnable(0); +} + +void lcdOn(){ + // if(lcdOnFunction) lcdOnFunction(); + // else lcdInit(); + backlightEnable(BACKLIGHT_LEVEL_MAX); +} + +bool boardBacklightOn; + +bool isBacklightEnabled() +{ + return boardBacklightOn; +} diff --git a/radio/src/boards/jumper-h750/board.cpp b/radio/src/boards/jumper-h750/board.cpp new file mode 100644 index 000000000..4e2d68d4e --- /dev/null +++ b/radio/src/boards/jumper-h750/board.cpp @@ -0,0 +1,225 @@ +/* + * 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 "stm32_adc.h" +#include "stm32_gpio.h" +#include "stm32_i2c_driver.h" +#include "stm32_hal.h" +#include "stm32_ws2812.h" +#include "stm32_spi.h" + +#include "flash_driver.h" +#include "extflash_driver.h" + +#include "board.h" +#include "boards/generic_stm32/module_ports.h" +#include "boards/generic_stm32/rgb_leds.h" + +#include "hal/adc_driver.h" +#include "hal/flash_driver.h" +#include "hal/trainer_driver.h" +#include "hal/rotary_encoder.h" +#include "hal/switch_driver.h" +#include "hal/abnormal_reboot.h" +#include "hal/watchdog_driver.h" +#include "hal/usb_driver.h" +#include "hal/gpio.h" + +#include "globals.h" +#include "sdcard.h" +#include "debug.h" + +#include "flysky_gimbal_driver.h" +#include "timers_driver.h" + +#include "bitmapbuffer.h" +#include "colors.h" + + +#include "touch_driver.h" + +#include + +// common ADC driver +extern const etx_hal_adc_driver_t _adc_driver; + +// RGB LED timer +extern const stm32_pulse_timer_t _led_timer; + + +static void led_strip_off() +{ + for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { + ws2812_set_color(i, 0, 0, 0); + } + ws2812_update(&_led_timer); + } + +void INTERNAL_MODULE_ON() +{ + gpio_set(INTMODULE_PWR_GPIO); +} + +void INTERNAL_MODULE_OFF() +{ + gpio_clear(INTMODULE_PWR_GPIO); +} + +void EXTERNAL_MODULE_ON() +{ + gpio_set(EXTMODULE_PWR_GPIO); +} + +void EXTERNAL_MODULE_OFF() +{ + gpio_clear(EXTMODULE_PWR_GPIO); +} + +void boardBLEarlyInit() +{ + timersInit(); + usbChargerInit(); +} + +void boardBLPreJump() +{ + ExtFLASH_Init(); + SDRAM_Init(); + + // Stop 1ms timer + MS_TIMER->CR1 &= ~TIM_CR1_CEN; +} + +void boardBLInit() +{ + ExtFLASH_Init(); + SDRAM_Init(); + + // register external FLASH for DFU + usbRegisterDFUMedia((void*)extflash_dfu_media); + + // register internal & external FLASH for UF2 + flashRegisterDriver(FLASH_BANK1_BASE, BOOTLOADER_SIZE, &stm32_flash_driver); + flashRegisterDriver(QSPI_BASE, 8 * 1024 * 1024, &extflash_driver); +} + +void boardInit() +{ + // enable interrupts + __enable_irq(); + + ledInit(); + boardInitModulePorts(); + + pwrInit(); + delaysInit(); + timersInit(); + + gpio_set(LED_BLUE_GPIO); + + ExtFLASH_InitRuntime(); + + // register internal & external FLASH for UF2 + flashRegisterDriver(FLASH_BANK1_BASE, BOOTLOADER_SIZE, &stm32_flash_driver); + flashRegisterDriver(QSPI_BASE, QSPI_FLASH_SIZE, &extflash_driver); + +#if defined(FLYSKY_GIMBAL) + // TODO remove the next 2 lines they are ony for test with current proto board + gpio_init(GPIO_PIN(GPIOB, 10), GPIO_OUT, GPIO_PIN_SPEED_LOW); + gpio_set(GPIO_PIN(GPIOB, 10)); + auto inittime = flysky_gimbal_init(); + if (inittime) + TRACE("Serial gimbal detected in %d ms", inittime); + else + TRACE("No serial gimbal detected"); +#endif + + usbInit(); + +#if !defined(DEBUG_SEGGER_RTT) + // This is needed to prevent radio from starting when usb is plugged to charge + if (usbPlugged()) { + while (usbPlugged() && !pwrPressed()) { + delay_ms(1000); + } + if (!pwrPressed()) { + pwrOff(); + // Wait power to drain + while (true) { + } + } + } +#endif + + rgbLedInit(); + led_strip_off(); + + keysInit(); + switchInit(); + rotaryEncoderInit(); + touchPanelInit(); + audioInit(); + adcInit(&_adc_driver); + hapticInit(); + + rtcInit(); // RTC must be initialized before rambackupRestore() is called +} + +extern void rtcDisableBackupReg(); + +void boardOff() +{ + lcdOff(); + + while (pwrPressed()) { + WDG_RESET(); + } + + SysTick->CTRL = 0; // turn off systick + + // Shutdown the Haptic + hapticDone(); + + rtcDisableBackupReg(); + +// RTC->BKP0R = SHUTDOWN_REQUEST; + pwrOff(); + + // We reach here only in forced power situations, such as hw-debugging with external power + // Enter STM32 stop mode / deep-sleep + // Code snippet from ST Nucleo PWR_EnterStopMode example +#define PDMode 0x00000000U +#if defined(PWR_CR1_MRUDS) && defined(PWR_CR1_LPUDS) && defined(PWR_CR1_FPDS) + MODIFY_REG(PWR->CR1, (PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_FPDS | PWR_CR1_LPUDS | PWR_CR1_MRUDS), PDMode); +#elif defined(PWR_CR_MRLVDS) && defined(PWR_CR_LPLVDS) && defined(PWR_CR_FPDS) + MODIFY_REG(PWR->CR1, (PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_FPDS | PWR_CR1_LPLVDS | PWR_CR1_MRLVDS), PDMode); +#else +// MODIFY_REG(PWR->CR1, (PWR_CR1_P_PDDS| PWR_CR1_LPDS), PDMode); +#endif /* PWR_CR_MRUDS && PWR_CR_LPUDS && PWR_CR_FPDS */ + +/* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + // To avoid HardFault at return address, end in an endless loop + while (1) { + + } +} diff --git a/radio/src/boards/jumper-h750/board.h b/radio/src/boards/jumper-h750/board.h new file mode 100644 index 000000000..dd02337f4 --- /dev/null +++ b/radio/src/boards/jumper-h750/board.h @@ -0,0 +1,260 @@ +/* + * 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. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "definitions.h" +#include "edgetx_constants.h" + +#include "board_common.h" +#include "hal.h" +#include "hal/serial_port.h" +#include "hal/watchdog_driver.h" + +#define BOOTLOADER_SIZE 0x10000 +#define BOOTLOADER_ADDRESS 0x08000000 +#define FIRMWARE_ADDRESS 0x90000000 +#define FIRMWARE_LEN(fsize) (fsize) +#define FIRMWARE_MAX_LEN FLASHSIZE +#define APP_START_ADDRESS (uint32_t)(FIRMWARE_ADDRESS) + +#define BOOTLOADER_KEYS 0x42 + +#define MB *1024*1024 +#define LUA_MEM_EXTRA_MAX (2 MB) // max allowed memory usage for Lua bitmaps (in bytes) +#define LUA_MEM_MAX (6 MB) // max allowed memory usage for complete Lua (in bytes), 0 means unlimited + +extern uint16_t sessionTimer; + +#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) + +// Board driver +void boardInit(); +void boardOff(); + +// CPU Unique ID +#define LEN_CPU_UID (3*8+2) +void getCPUUniqueID(char * s); + +// Flash Write driver +#define FLASH_PAGESIZE 256 +void unlockFlash(); +void lockFlash(); +void flashWrite(uint32_t * address, const uint32_t * buffer); +uint32_t isFirmwareStart(const uint8_t * buffer); +uint32_t isBootloaderStart(const uint8_t * buffer); + +// SDRAM driver +extern "C" void SDRAM_Init(); + +// Pulses driver +#if !defined(SIMU) + +void INTERNAL_MODULE_ON(); +void INTERNAL_MODULE_OFF(); +void EXTERNAL_MODULE_ON(); +void EXTERNAL_MODULE_OFF(); +#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) + +#else + +#define INTERNAL_MODULE_OFF() +#define INTERNAL_MODULE_ON() +#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) + +#endif // defined(SIMU) + +#if defined(FUNCTION_SWITCHES) +#define NUM_FUNCTIONS_SWITCHES 6 +#define NUM_FUNCTIONS_GROUPS 3 +#define DEFAULT_FS_CONFIG \ + (SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \ + (SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0) + +#define DEFAULT_FS_GROUPS \ + (1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \ + (1 << 0) // Set all FS to group 1 to act like a 6pos + +#define DEFAULT_FS_STARTUP_CONFIG \ + ((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \ + (FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \ + (FS_START_PREVIOUS << 2) + \ + (FS_START_PREVIOUS << 0)) // keep last state by default + +#else +#define NUM_FUNCTIONS_SWITCHES 0 +#endif + +#define NUM_TRIMS 8 +#define DEFAULT_STICK_DEADZONE 2 + +#define BATTERY_WARN 74 // 7.4V +#define BATTERY_MIN 70 // 6.8V +#define BATTERY_MAX 86 // 8.6V + +// --- MOSFET ---- R1 --- MCU +// |__ R2 --- GND +// +#define VBAT_DIV_R1 680 // kOhms +#define VBAT_DIV_R2 158 // kOhms +#define VBAT_MOSFET_DROP 0 // * 10mV + +// #define BATTERY_DIVIDER 1211 // = 2047 * 165k / (165k + 680k) * 10 / 3.3V + +#if defined(__cplusplus) && !defined(SIMU) +extern "C" { +#endif + +// Power driver +#define SOFT_PWR_CTRL +#define POWER_ON_DELAY 10 // 1s +void pwrInit(); +void extModuleInit(); +uint32_t pwrCheck(); +uint32_t lowPowerCheck(); + +void pwrOn(); +void pwrSoftReboot(); +void pwrOff(); +void pwrResetHandler(); +bool pwrPressed(); +bool pwrOffPressed(); +#if defined(PWR_EXTRA_SWITCH_GPIO) + bool pwrForcePressed(); +#else + #define pwrForcePressed() false +#endif +uint32_t pwrPressedDuration();; + +const etx_serial_port_t* auxSerialGetPort(int port_nr); +#define AUX_SERIAL_POWER_ON() +#define AUX_SERIAL_POWER_OFF() + +// LED driver +void ledInit(); +void ledOff(); +void ledRed(); +void ledBlue(); +void ledGreen(); + +// LCD driver +void lcdSetInitalFrameBuffer(void* fbAddress); +void lcdInit(); +void lcdCopy(void * dest, void * src); + +void lcdOff(); +void lcdOn(); + +#define lcdRefreshWait(...) + +// Backlight driver +#define BACKLIGHT_LEVEL_MAX 100 +#define BACKLIGHT_FORCED_ON BACKLIGHT_LEVEL_MAX + 1 +#define BACKLIGHT_LEVEL_MIN 1 + +extern bool boardBacklightOn; +void backlightLowInit( void ); +void backlightInit(); +void backlightEnable(uint8_t dutyCycle); +void backlightFullOn(); +bool isBacklightEnabled(); + +#define BACKLIGHT_ENABLE() \ + { \ + boardBacklightOn = true; \ + backlightEnable(BACKLIGHT_LEVEL_MAX - currentBacklightBright); \ + } + +#define BACKLIGHT_DISABLE() \ + { \ + boardBacklightOn = false; \ + backlightEnable(((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && \ + (g_eeGeneral.backlightMode != e_backlight_mode_off)) \ + ? 0 \ + : g_eeGeneral.blOffBright); \ + } + +#if defined(__cplusplus) && !defined(SIMU) +} +#endif + +// Audio driver +class stm32_spi_t; +struct AudioConfig_t +{ + stm32_spi_t* spi; + void (*setMuteHigh)(); + void (*setMuteLow)(); + void (*setResetHigh)(); + void (*setResetLow)(); +}; +void audioInit(); +void audioConsumeCurrentBuffer(); + +#define audioDisableIrq() // interrupts must stay enabled on Horus +#define audioEnableIrq() // interrupts must stay enabled on Horus +#define setSampleRate(freq) +void setScaledVolume(uint8_t volume); +void setVolume(uint8_t volume); +int32_t getVolume(); +#define VOLUME_LEVEL_MAX 23 +#define VOLUME_LEVEL_DEF 12 + +// Telemetry driver +#define INTMODULE_FIFO_SIZE 512 +#define TELEMETRY_FIFO_SIZE 512 + +// Haptic driver +void hapticInit(); +void hapticDone(); +void hapticOff(); +void hapticOn(uint32_t pwmPercent); + +// Second serial port driver +//#define AUX_SERIAL +#define DEBUG_BAUDRATE 115200 +#define LUA_DEFAULT_BAUDRATE 115200 + +extern uint8_t currentTrainerMode; +void checkTrainerSettings(); + +// Touch panel driver +bool touchPanelEventOccured(); +struct TouchState touchPanelRead(); +struct TouchState getInternalTouchState(); + +// USB Charger +#if defined(USB_CHARGER) +void usbChargerInit(); +bool usbChargerLed(); +#endif + +#endif // _BOARD_H_ diff --git a/radio/src/boards/jumper-h750/extflash_driver.cpp b/radio/src/boards/jumper-h750/extflash_driver.cpp new file mode 100644 index 000000000..2354db468 --- /dev/null +++ b/radio/src/boards/jumper-h750/extflash_driver.cpp @@ -0,0 +1,154 @@ +#include "extflash_driver.h" + +#include "stm32_hal.h" +#include "stm32_qspi.h" + +#include "board.h" + +#define QSPI_NOR_PAGE_SIZE 256 + +int32_t ExtFLASH_Init() +{ + if (stm32_qspi_nor_init() != 0) { + return -1; + } + + return stm32_qspi_nor_memory_mapped(); +} + +void ExtFLASH_InitRuntime() { stm32_qspi_no_init_runtime(); } + +// +// ETX HAL flash interface +// + +static uint32_t extflash_get_size_kb() +{ + return QSPI_FLASH_SIZE / 1024; +} + +static uint32_t extflash_get_sector(uint32_t address) +{ + address -= QSPI_BASE; + return address / (64 * 1024); +} + +static uint32_t extflash_get_sector_size(uint32_t sector) +{ + (void)sector; + return (64 * 1024); +} + +static int extflash_erase_sector(uint32_t address) +{ + address -= QSPI_BASE; + return stm32_qspi_nor_erase_sector(address); +} + +static int extflash_program(uint32_t address, void* data, uint32_t len) +{ + address -= QSPI_BASE; + + int ret = 0; + while (len > 0) { + uint32_t size = (len > QSPI_NOR_PAGE_SIZE) ? QSPI_NOR_PAGE_SIZE : len; + ret = stm32_qspi_nor_program(address, data, size); + if (ret != 0) break; + len -= size; + address += size; + data = (uint8_t*)data + size; + } + + return ret; +} + +static int extflash_read(uint32_t address, void* data, uint32_t len) +{ + address -= QSPI_BASE; + return stm32_qspi_nor_read(address, data, len); +} + +const etx_flash_driver_t extflash_driver = { + .get_size_kb = extflash_get_size_kb, + .get_sector = extflash_get_sector, + .get_sector_size = extflash_get_sector_size, + .erase_sector = extflash_erase_sector, + .program = extflash_program, + .read = extflash_read, +}; + +#if defined(BOOT) +// +// USB DFU interface +// +#include "usbd_dfu.h" + +#define MEDIA_DESC_STR "@External Flash /0x90000000/128*064Kg" + +static uint16_t extflash_dfu_init() +{ + return USBD_OK; +} + +static uint16_t extflash_dfu_deinit() +{ + return USBD_OK; +} + +static uint16_t extflash_dfu_erase(uint32_t address) +{ + if (extflash_erase_sector(address) < 0) { + return USBD_FAIL; + } + return USBD_OK; +} + +static uint16_t extflash_dfu_write(uint8_t* src, uint8_t* dest, uint32_t len) +{ + if (extflash_program((intptr_t)dest, (void*)src, len) < 0) { + return USBD_FAIL; + } + return USBD_OK; +} + +static uint8_t* extflash_dfu_read(uint8_t* src, uint8_t* dest, uint32_t len) +{ + if (extflash_read((intptr_t)src, (void*)dest, len) < 0) { + return nullptr; + } + return dest; +} + +static uint16_t extflash_dfu_get_status(uint32_t address, uint8_t cmd, uint8_t *buffer) +{ + switch (cmd) { + case DFU_MEDIA_PROGRAM: + buffer[1] = 1; + buffer[2] = 0; + buffer[3] = 0; + break; + + case DFU_MEDIA_ERASE: + default: + buffer[1] = 20; + buffer[2] = 0; + buffer[3] = 0; + break; + } + + return USBD_OK; +} + +const USBD_DFU_MediaTypeDef _extflash_dfu_media = { + .pStrDesc = (uint8_t*)MEDIA_DESC_STR, + .Init = extflash_dfu_init, + .DeInit = extflash_dfu_deinit, + .Erase = extflash_dfu_erase, + .Write = extflash_dfu_write, + .Read = extflash_dfu_read, + .GetStatus = extflash_dfu_get_status, +}; + +const void* extflash_dfu_media = &_extflash_dfu_media; + +#endif // BOOT diff --git a/radio/src/boards/jumper-h750/extflash_driver.h b/radio/src/boards/jumper-h750/extflash_driver.h new file mode 100644 index 000000000..22a8b3b77 --- /dev/null +++ b/radio/src/boards/jumper-h750/extflash_driver.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) EdgeTX + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "hal/flash_driver.h" + +extern const etx_flash_driver_t extflash_driver; +extern const void* extflash_dfu_media; + +// init external FLASH hardware +int32_t ExtFLASH_Init(); + +// init only runtime structures +void ExtFLASH_InitRuntime(); diff --git a/radio/src/boards/jumper-h750/haptic_driver.cpp b/radio/src/boards/jumper-h750/haptic_driver.cpp new file mode 100644 index 000000000..148312717 --- /dev/null +++ b/radio/src/boards/jumper-h750/haptic_driver.cpp @@ -0,0 +1,60 @@ +/* + * 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/gpio.h" +#include "stm32_gpio.h" +#include "stm32_timer.h" +#include "stm32_pulse_driver.h" + +#include "board.h" + +#define HAPTIC_TIMER_FREQ 200000000 + +static const stm32_pulse_timer_t _haptic_timer = { + .GPIO = (gpio_t)HAPTIC_GPIO, + .GPIO_Alternate = HAPTIC_GPIO_AF, + .TIMx = HAPTIC_GPIO_TIMER, + .TIM_Freq = HAPTIC_TIMER_FREQ, + .TIM_Channel = LL_TIM_CHANNEL_CH2, + .TIM_IRQn = (IRQn_Type)-1, + .DMAx = nullptr, + .DMA_Stream = 0, + .DMA_Channel = 0, + .DMA_IRQn = (IRQn_Type)-1, + .DMA_TC_CallbackPtr = nullptr, +}; + +void hapticInit(void) +{ + stm32_pulse_init(&_haptic_timer, 10000); + stm32_pulse_config_output(&_haptic_timer, true, LL_TIM_OCMODE_PWM1, 0); + LL_TIM_SetAutoReload(_haptic_timer.TIMx, 100); + LL_TIM_EnableCounter(_haptic_timer.TIMx); +} + +void hapticOn(uint32_t pwmPercent) +{ + if (pwmPercent > 100) pwmPercent = 100; + stm32_pulse_set_cmp_val(&_haptic_timer, pwmPercent); +} + +void hapticOff(void) { hapticOn(0); } +void hapticDone(void) { hapticOff(); } diff --git a/radio/src/boards/jumper-h750/key_driver.cpp b/radio/src/boards/jumper-h750/key_driver.cpp new file mode 100644 index 000000000..3577ebb10 --- /dev/null +++ b/radio/src/boards/jumper-h750/key_driver.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "hal/key_driver.h" + +#include "stm32_hal_ll.h" +#include "stm32_gpio_driver.h" +#include "stm32_i2c_driver.h" + +#include "hal.h" +#include "delays_driver.h" +#include "keys.h" + +#include "stm32_keys.inc" +#include "debug.h" diff --git a/radio/src/boards/jumper-h750/lcd_driver.cpp b/radio/src/boards/jumper-h750/lcd_driver.cpp new file mode 100644 index 000000000..013e91ff6 --- /dev/null +++ b/radio/src/boards/jumper-h750/lcd_driver.cpp @@ -0,0 +1,2013 @@ +/* + * 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 "stm32_hal_ll.h" +#include "stm32_hal.h" +#include "stm32_gpio_driver.h" +#include "edgetx_types.h" +#include "dma2d.h" +#include "hal.h" +#include "delays_driver.h" +#include "debug.h" +#include "lcd.h" +#include "lcd_driver.h" +#include "board.h" + +#include "stm32_gpio.h" +#include "hal/gpio.h" + +uint8_t TouchControllerType = 0; // 0: other; 1: CST836U +static volatile uint16_t lcd_phys_w = LCD_H; +static volatile uint16_t lcd_phys_h = LCD_W; + +static LTDC_HandleTypeDef hltdc; +static void* initialFrameBuffer = nullptr; + +static volatile uint8_t _frame_addr_reloaded = 0; + +static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer, + const rect_t ©_area) +{ + (void)disp_drv; + (void)copy_area; + + // given the data cache size, this is probably + // faster than cleaning by address + SCB_CleanDCache(); + +// LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD); + LTDC_Layer1->CFBAR = (uint32_t)buffer; + // reload shadow registers on vertical blank + _frame_addr_reloaded = 0; + LTDC->SRCR = LTDC_SRCR_VBR; + __HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI); + + // wait for reload + // TODO: replace through some smarter mechanism without busy wait + while(_frame_addr_reloaded == 0); +} + +lcdSpiInitFucPtr lcdInitFunction; +lcdSpiInitFucPtr lcdOffFunction; +lcdSpiInitFucPtr lcdOnFunction; +uint32_t lcdPixelClock; + +volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 }; + +static void LCD_Delay(void) { + volatile unsigned int i; + + for (i = 0; i < 20; i++) { + ; + } +} + +#define LTDC_HSYNC GPIO_PIN(GPIOI, 12) +#define LTDC_VSYNC GPIO_PIN(GPIOI, 13) +#define LTDC_CLK GPIO_PIN(GPIOI, 14) +#define LTDC_DE GPIO_PIN(GPIOK, 7) + +#define LTDC_R3 GPIO_PIN(GPIOJ, 2) +#define LTDC_R4 GPIO_PIN(GPIOJ, 3) +#define LTDC_R5 GPIO_PIN(GPIOJ, 4) +#define LTDC_R6 GPIO_PIN(GPIOJ, 5) +#define LTDC_R7 GPIO_PIN(GPIOJ, 6) + +#define LTDC_G2 GPIO_PIN(GPIOJ, 9) +#define LTDC_G3 GPIO_PIN(GPIOJ, 10) +#define LTDC_G4 GPIO_PIN(GPIOJ, 11) +#define LTDC_G5 GPIO_PIN(GPIOK, 0) +#define LTDC_G6 GPIO_PIN(GPIOK, 1) +#define LTDC_G7 GPIO_PIN(GPIOK, 2) + +#define LTDC_B3 GPIO_PIN(GPIOJ, 15) +#define LTDC_B4 GPIO_PIN(GPIOK, 3) +#define LTDC_B5 GPIO_PIN(GPIOK, 4) +#define LTDC_B6 GPIO_PIN(GPIOK, 5) +#define LTDC_B7 GPIO_PIN(GPIOK, 6) + +static void LCD_AF_GPIOConfig(void) { + gpio_init_af(LTDC_HSYNC, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_VSYNC, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_CLK, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_DE, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + + gpio_init_af(LTDC_R3, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_R4, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_R5, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_R6, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_R7, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + + gpio_init_af(LTDC_G2, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_G3, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_G4, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_G5, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_G6, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_G7, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + + gpio_init_af(LTDC_B3, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_B4, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_B5, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_B6, GPIO_AF14, GPIO_SPEED_FREQ_LOW); + gpio_init_af(LTDC_B7, GPIO_AF14, GPIO_SPEED_FREQ_LOW); +} + +static void lcdSpiConfig(void) { + stm32_gpio_enable_clock(LCD_SPI_GPIO); + stm32_gpio_enable_clock(LCD_NRST_GPIO); + stm32_gpio_enable_clock(LCD_SPI_CS_GPIO); + + LL_GPIO_InitTypeDef GPIO_InitStructure; + LL_GPIO_StructInit(&GPIO_InitStructure); + + GPIO_InitStructure.Pin = LCD_SPI_SCK_GPIO_PIN | LCD_SPI_MOSI_GPIO_PIN | LCD_SPI_MISO_GPIO_PIN; + GPIO_InitStructure.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStructure.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(LCD_SPI_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = LCD_NRST_GPIO_PIN; + LL_GPIO_Init(LCD_NRST_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = LCD_SPI_CS_GPIO_PIN; + LL_GPIO_Init(LCD_SPI_CS_GPIO, &GPIO_InitStructure); + + /* Set the chip select pin always low */ + LCD_CS_LOW(); +} + +void lcdDelay() { + delay_01us(1); +} + +static void lcdReset() { + LCD_NRST_HIGH(); + delay_ms(1); + + LCD_NRST_LOW(); // RESET(); + delay_ms(100); + + LCD_NRST_HIGH(); + delay_ms(100); +} + +unsigned char LCD_ReadByteOnFallingEdge(void) { + unsigned int i; + unsigned char ReceiveData = 0; + + LCD_MOSI_HIGH(); + LCD_MOSI_AS_INPUT(); + + for (i = 0; i < 8; i++) { + LCD_DELAY(); + LCD_SCK_HIGH(); + LCD_DELAY(); + LCD_DELAY(); + ReceiveData <<= 1; + + LCD_SCK_LOW(); + LCD_DELAY(); + LCD_DELAY(); + if (LCD_READ_DATA_PIN()) { + ReceiveData |= 0x01; + } + } + + LCD_MOSI_AS_OUTPUT(); + + return (ReceiveData); +} + +static void lcdWriteByte(uint8_t data_enable, uint8_t byte) { + + LCD_SCK_LOW(); + lcdDelay(); + + if (data_enable) { + LCD_MOSI_HIGH(); + } else { + LCD_MOSI_LOW(); + } + + LCD_SCK_HIGH(); + lcdDelay(); + + for (int i = 0; i < 8; i++) { + LCD_SCK_LOW(); + lcdDelay(); + + if (byte & 0x80) { + LCD_MOSI_HIGH(); + } else { + LCD_MOSI_LOW(); + } + + LCD_SCK_HIGH(); + byte <<= 1; + + lcdDelay(); + } + + LCD_SCK_LOW(); +} + +unsigned char LCD_ReadByte(void) { + unsigned int i; + unsigned char ReceiveData = 0; + + LCD_MOSI_HIGH(); + LCD_MOSI_AS_INPUT(); + for (i = 0; i < 8; i++) { + LCD_SCK_LOW(); + lcdDelay(); + ReceiveData <<= 1; + LCD_SCK_HIGH(); + lcdDelay(); + if (LCD_READ_DATA_PIN()) { + ReceiveData |= 0x01; + } + } + LCD_SCK_LOW(); + LCD_MOSI_AS_OUTPUT(); + return (ReceiveData); +} + +unsigned char LCD_ReadRegister(unsigned char Register) { + unsigned char ReadData = 0; + + lcdWriteByte(0, Register); + lcdDelay(); + lcdDelay(); + ReadData = LCD_ReadByte(); + return (ReadData); +} + +void lcdWriteCommand(uint8_t command) { + lcdWriteByte(0, command); +} + +void lcdWriteData(uint8_t data) { + lcdWriteByte(1, data); +} + +void LCD_ST7796S_On(void) { + lcdWriteCommand(0x29); +} + +void LCD_ST7796S_Init(void) { + delay_ms(120); + + lcdWriteCommand(0x11); + delay_ms(120); + + lcdWriteCommand(0xF0); + lcdWriteData(0xC3); + + lcdWriteCommand(0xF0); + lcdWriteData(0x96); + + lcdWriteCommand(0x36); + lcdWriteData(0x28); + + lcdWriteCommand(0x2A); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0xDF); + lcdWriteCommand(0x2B); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0x3F); + + lcdWriteCommand(0x3A); + lcdWriteData(0x55); + lcdWriteCommand(0x34); + + // SET RGB STRAT + lcdWriteCommand(0xB0); // SET HS VS DE CLK 上升还是下降有效 + lcdWriteData(0x80); + + lcdWriteCommand(0xB4); + lcdWriteData(0x01); + + lcdWriteCommand(0xB6); + // lcdWriteData( 0x20 ); + // lcdWriteData( 0x02 ); + // lcdWriteData( 0x3B ); + lcdWriteData(0x20); + lcdWriteData(0x02); + lcdWriteData(0x3B); + // SET RGB END + + lcdWriteCommand(0xB7); + lcdWriteData(0xC6); + + lcdWriteCommand(0xB9); + lcdWriteData(0x02); + lcdWriteData(0xE0); + + lcdWriteCommand(0xC0); + lcdWriteData(0x80); + lcdWriteData(0x65); + + lcdWriteCommand(0xC1); + lcdWriteData(0x0D); + + lcdWriteCommand(0xC2); + lcdWriteData(0xA7); + + lcdWriteCommand(0xC5); + lcdWriteData(0x14); + + lcdWriteCommand(0xE8); + lcdWriteData(0x40); + lcdWriteData(0x8A); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x29); + lcdWriteData(0x19); + lcdWriteData(0xA5); + lcdWriteData(0x33); + + lcdWriteCommand(0xE0); + lcdWriteData(0xD0); + lcdWriteData(0x00); + lcdWriteData(0x04); + lcdWriteData(0x05); + lcdWriteData(0x04); + lcdWriteData(0x21); + lcdWriteData(0x25); + lcdWriteData(0x43); + lcdWriteData(0x3F); + lcdWriteData(0x37); + lcdWriteData(0x13); + lcdWriteData(0x13); + lcdWriteData(0x29); + lcdWriteData(0x32); + + lcdWriteCommand(0xE1); + lcdWriteData(0xD0); + lcdWriteData(0x04); + lcdWriteData(0x06); + lcdWriteData(0x09); + lcdWriteData(0x06); + lcdWriteData(0x03); + lcdWriteData(0x25); + lcdWriteData(0x32); + lcdWriteData(0x3E); + lcdWriteData(0x18); + lcdWriteData(0x15); + lcdWriteData(0x15); + lcdWriteData(0x2B); + lcdWriteData(0x30); + + lcdWriteCommand(0xF0); + lcdWriteData(0x3C); + + lcdWriteCommand(0xF0); + lcdWriteData(0x69); + + delay_ms(120); + + lcdWriteCommand(0x21); + + LCD_ST7796S_On(); +} + +void LCD_ST7796S_Off(void) { + lcdWriteCommand(0x28); +} + +unsigned int LCD_ST7796S_ReadID(void) { + lcdReset(); + unsigned int ID = 0; + + lcdWriteCommand( 0XF0 ); + lcdWriteData( 0XC3 ); + lcdWriteCommand( 0XF0 ); + lcdWriteData( 0X96 ); + + lcdWriteCommand( 0XB0 ); + lcdWriteData( 0X80 ); + + lcdWriteCommand( 0XD3 ); + + LCD_MOSI_AS_INPUT(); + LCD_SCK_LOW(); + lcdDelay(); + lcdDelay(); + LCD_SCK_HIGH(); + lcdDelay(); + lcdDelay(); + + LCD_ReadByte(); + ID += (uint16_t)(LCD_ReadByte())<<8; + ID += LCD_ReadByte(); + + return (ID); + } + + +unsigned int LCD_NT35310_ReadID( void ) +{ + unsigned int ID = 0x3531; + + return( ID ); + +} + +void LCD_NT35310_Init( void ) +{ +#if 1 + lcdWriteCommand(0xED); + lcdWriteData(0x01); + lcdWriteData(0xFE); + + lcdWriteCommand(0xEE); + lcdWriteData(0xDE); + lcdWriteData(0x21); + + lcdWriteCommand(0x11); + delay_ms(120); + lcdWriteCommand(0xB3); + lcdWriteData(0x21); + + + + lcdWriteCommand(0xC0); + lcdWriteData(0x33); + lcdWriteData(0x33); + lcdWriteData(0x10); + lcdWriteData(0x10); + + + lcdWriteCommand(0xC4); + lcdWriteData(0x56); //3a + + lcdWriteCommand(0xBF); + lcdWriteData(0xAA); + + lcdWriteCommand(0xB0); + lcdWriteData(0x0D); + lcdWriteData(0x00); + lcdWriteData(0x0D); + lcdWriteData(0x00); + lcdWriteData(0x11); + lcdWriteData(0x00); + lcdWriteData(0x19); + lcdWriteData(0x00); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x2D); + lcdWriteData(0x00); + lcdWriteData(0x3D); + lcdWriteData(0x00); + lcdWriteData(0x5D); + lcdWriteData(0x00); + lcdWriteData(0x5D); + lcdWriteData(0x00); + + lcdWriteCommand(0xB1); + lcdWriteData(0x80); + lcdWriteData(0x00); + lcdWriteData(0x8B); + lcdWriteData(0x00); + lcdWriteData(0x96); + lcdWriteData(0x00); + + lcdWriteCommand(0xB2); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x03); + lcdWriteData(0x00); + + lcdWriteCommand(0xB3); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xB4); + lcdWriteData(0x8B); + lcdWriteData(0x00); + lcdWriteData(0x96); + lcdWriteData(0x00); + lcdWriteData(0xA1); + lcdWriteData(0x00); + + lcdWriteCommand(0xB5); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x03); + lcdWriteData(0x00); + lcdWriteData(0x04); + lcdWriteData(0x00); + lcdWriteCommand(0xB6); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xB7); + lcdWriteData(0x3E); + lcdWriteData(0x00); + lcdWriteData(0x5E); + lcdWriteData(0x00); + lcdWriteData(0x9E); + lcdWriteData(0x00); + lcdWriteData(0x74); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0xAC); + lcdWriteData(0x00); + lcdWriteData(0xDC); + lcdWriteData(0x00); + lcdWriteData(0x70); + lcdWriteData(0x00); + lcdWriteData(0xB9); + lcdWriteData(0x00); + lcdWriteData(0xEC); + lcdWriteData(0x00); + lcdWriteData(0xDC); + lcdWriteData(0x00); + + lcdWriteCommand(0xB8); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xBA); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC1); + lcdWriteData(0x20); + lcdWriteData(0x00); + lcdWriteData(0x54); + lcdWriteData(0x00); + lcdWriteData(0xFF); + lcdWriteData(0x00); + + lcdWriteCommand(0xC2); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x04); + lcdWriteData(0x00); + + lcdWriteCommand(0xC3); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x3A); + lcdWriteData(0x00); + lcdWriteData(0x39); + lcdWriteData(0x00); + lcdWriteData(0x37); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x2F); + lcdWriteData(0x00); + lcdWriteData(0x2C); + lcdWriteData(0x00); + lcdWriteData(0x29); + lcdWriteData(0x00); + lcdWriteData(0x26); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x2F); + lcdWriteData(0x00); + lcdWriteData(0x2C); + lcdWriteData(0x00); + lcdWriteData(0x29); + lcdWriteData(0x00); + lcdWriteData(0x26); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + + lcdWriteCommand(0xC4); + lcdWriteData(0x62); + lcdWriteData(0x00); + lcdWriteData(0x05); + lcdWriteData(0x00); + lcdWriteData(0x84); + lcdWriteData(0x00); + lcdWriteData(0xF0); + lcdWriteData(0x00); + lcdWriteData(0x18); + lcdWriteData(0x00); + lcdWriteData(0xA4); + lcdWriteData(0x00); + lcdWriteData(0x18); + lcdWriteData(0x00); + lcdWriteData(0x50); + lcdWriteData(0x00); + lcdWriteData(0x0C); + lcdWriteData(0x00); + lcdWriteData(0x17); + lcdWriteData(0x00); + lcdWriteData(0x95); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + lcdWriteData(0xE6); + lcdWriteData(0x00); + + lcdWriteCommand(0xC5); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + lcdWriteData(0x76); + lcdWriteData(0x00); + lcdWriteData(0x88); + lcdWriteData(0x00); + + lcdWriteCommand(0xC6); + lcdWriteData(0x20); + lcdWriteData(0x00); + lcdWriteData(0x17); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0x00); + + lcdWriteCommand(0xC7); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC8); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC9); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xE0); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE1); + lcdWriteData(0x01); + lcdWriteData(0x00); + lcdWriteData(0x05); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE2); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE3); + lcdWriteData(0x01); + lcdWriteData(0x00); + lcdWriteData(0x05); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE4); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE5); + lcdWriteData(0x01); + lcdWriteData(0x00); + lcdWriteData(0x05); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x25); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x6F); + lcdWriteData(0x00); + lcdWriteData(0x7F); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0x98); + lcdWriteData(0x00); + lcdWriteData(0xA6); + lcdWriteData(0x00); + lcdWriteData(0xAE); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBB); + lcdWriteData(0x00); + lcdWriteData(0xC0); + lcdWriteData(0x00); + lcdWriteData(0xC9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE6); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE7); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE8); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE9); + lcdWriteData(0xAA); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0x00); + lcdWriteData(0xAA); + + lcdWriteCommand(0xCF); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xF0); + lcdWriteData(0x00); + lcdWriteData(0x50); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xF1); + lcdWriteData(0x01); + + lcdWriteCommand(0xF9); + lcdWriteData(0x06); + lcdWriteData(0x10); + lcdWriteData(0x29); + lcdWriteData(0x00); + + lcdWriteCommand(0xDF); + lcdWriteData(0x10); + delay_ms(20); + lcdWriteCommand(0x36); +// if( IsHorizontal ) +// lcdWriteData(0x00);//需修改 +// else + lcdWriteData(0x14); + + lcdWriteCommand(0x3A); + lcdWriteData(0x66); + + lcdWriteCommand(0x21); + + lcdWriteCommand(0x35); + lcdWriteData(0x00); + + lcdWriteCommand(0x29); +#else + lcdWriteCommand(0xED); + lcdWriteData(0x01); + lcdWriteData(0xFE); + + lcdWriteCommand(0xEE); + lcdWriteData(0xDE); + lcdWriteData(0x21); + + lcdWriteCommand(0x11); + SYSTEM_DelayMS(120); + lcdWriteCommand(0xB3); + lcdWriteData(0x21); + + + lcdWriteCommand(0xc0); + lcdWriteData(0x56); + lcdWriteData(0x56); + lcdWriteData(0x24); + lcdWriteData(0x24); + + lcdWriteCommand(0xC4); + lcdWriteData(0x30); //3a + + lcdWriteCommand(0xBF); + lcdWriteData(0xAA); + + lcdWriteCommand(0xB0); + lcdWriteData(0x0D); + lcdWriteData(0x00); + lcdWriteData(0x0D); + lcdWriteData(0x00); + lcdWriteData(0x11); + lcdWriteData(0x00); + lcdWriteData(0x19); + lcdWriteData(0x00); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x2D); + lcdWriteData(0x00); + lcdWriteData(0x3D); + lcdWriteData(0x00); + lcdWriteData(0x5D); + lcdWriteData(0x00); + lcdWriteData(0x5D); + lcdWriteData(0x00); + + lcdWriteCommand(0xB1); + lcdWriteData(0x80); + lcdWriteData(0x00); + lcdWriteData(0x8B); + lcdWriteData(0x00); + lcdWriteData(0x96); + lcdWriteData(0x00); + + lcdWriteCommand(0xB2); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x03); + lcdWriteData(0x00); + + lcdWriteCommand(0xB3); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xB4); + lcdWriteData(0x8B); + lcdWriteData(0x00); + lcdWriteData(0x96); + lcdWriteData(0x00); + lcdWriteData(0xA1); + lcdWriteData(0x00); + + lcdWriteCommand(0xB5); + lcdWriteData(0x02); + lcdWriteData(0x00); + lcdWriteData(0x03); + lcdWriteData(0x00); + lcdWriteData(0x04); + lcdWriteData(0x00); + lcdWriteCommand(0xB6); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xB7); + lcdWriteData(0x3E); + lcdWriteData(0x00); + lcdWriteData(0x5E); + lcdWriteData(0x00); + lcdWriteData(0x9E); + lcdWriteData(0x00); + lcdWriteData(0x74); + lcdWriteData(0x00); + lcdWriteData(0x8C); + lcdWriteData(0x00); + lcdWriteData(0xAC); + lcdWriteData(0x00); + lcdWriteData(0xDC); + lcdWriteData(0x00); + lcdWriteData(0x70); + lcdWriteData(0x00); + lcdWriteData(0xB9); + lcdWriteData(0x00); + lcdWriteData(0xEC); + lcdWriteData(0x00); + lcdWriteData(0xDC); + lcdWriteData(0x00); + + lcdWriteCommand(0xB8); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xBA); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC1); + lcdWriteData(0x20); + lcdWriteData(0x00); + lcdWriteData(0x54); + lcdWriteData(0x00); + lcdWriteData(0xFF); + lcdWriteData(0x00); + + lcdWriteCommand(0xC2); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x04); + lcdWriteData(0x00); + + lcdWriteCommand(0xC3); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x3A); + lcdWriteData(0x00); + lcdWriteData(0x39); + lcdWriteData(0x00); + lcdWriteData(0x37); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x2F); + lcdWriteData(0x00); + lcdWriteData(0x2C); + lcdWriteData(0x00); + lcdWriteData(0x29); + lcdWriteData(0x00); + lcdWriteData(0x26); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x36); + lcdWriteData(0x00); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x2F); + lcdWriteData(0x00); + lcdWriteData(0x2C); + lcdWriteData(0x00); + lcdWriteData(0x29); + lcdWriteData(0x00); + lcdWriteData(0x26); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + + lcdWriteCommand(0xC4); + lcdWriteData(0x62); + lcdWriteData(0x00); + lcdWriteData(0x05); + lcdWriteData(0x00); + lcdWriteData(0x84); + lcdWriteData(0x00); + lcdWriteData(0xF0); + lcdWriteData(0x00); + lcdWriteData(0x18); + lcdWriteData(0x00); + lcdWriteData(0xA4); + lcdWriteData(0x00); + lcdWriteData(0x18); + lcdWriteData(0x00); + lcdWriteData(0x50); + lcdWriteData(0x00); + lcdWriteData(0x0C); + lcdWriteData(0x00); + lcdWriteData(0x17); + lcdWriteData(0x00); + lcdWriteData(0x95); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + lcdWriteData(0xE6); + lcdWriteData(0x00); + + lcdWriteCommand(0xC5); + lcdWriteData(0x32); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + lcdWriteData(0x76); + lcdWriteData(0x00); + lcdWriteData(0x88); + lcdWriteData(0x00); + + lcdWriteCommand(0xC6); + lcdWriteData(0x20); + lcdWriteData(0x00); + lcdWriteData(0x17); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0x00); + + lcdWriteCommand(0xC7); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC8); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xC9); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xE0); + lcdWriteData(0x01); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xCF); + lcdWriteData(0x00); + lcdWriteData(0xD3); + lcdWriteData(0x00); + lcdWriteData(0xDA); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE1); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xD0); + lcdWriteData(0x00); + lcdWriteData(0xD4); + lcdWriteData(0x00); + lcdWriteData(0xD9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE2); + lcdWriteData(0x10); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xCF); + lcdWriteData(0x00); + lcdWriteData(0xD3); + lcdWriteData(0x00); + lcdWriteData(0xDA); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE3); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xD0); + lcdWriteData(0x00); + lcdWriteData(0xD4); + lcdWriteData(0x00); + lcdWriteData(0xD9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE4); + lcdWriteData(0x01); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xCF); + lcdWriteData(0x00); + lcdWriteData(0xD3); + lcdWriteData(0x00); + lcdWriteData(0xDA); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE5); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x1F); + lcdWriteData(0x00); + lcdWriteData(0x3C); + lcdWriteData(0x00); + lcdWriteData(0x59); + lcdWriteData(0x00); + lcdWriteData(0x67); + lcdWriteData(0x00); + lcdWriteData(0x72); + lcdWriteData(0x00); + lcdWriteData(0x82); + lcdWriteData(0x00); + lcdWriteData(0x93); + lcdWriteData(0x00); + lcdWriteData(0xA0); + lcdWriteData(0x00); + lcdWriteData(0xAB); + lcdWriteData(0x00); + lcdWriteData(0xB4); + lcdWriteData(0x00); + lcdWriteData(0xBF); + lcdWriteData(0x00); + lcdWriteData(0xC6); + lcdWriteData(0x00); + lcdWriteData(0xCA); + lcdWriteData(0x00); + lcdWriteData(0xD0); + lcdWriteData(0x00); + lcdWriteData(0xD4); + lcdWriteData(0x00); + lcdWriteData(0xD9); + lcdWriteData(0x00); + lcdWriteData(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xE6); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE7); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE8); + lcdWriteData(0x55); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x56); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x57); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x77); + lcdWriteData(0x00); + lcdWriteData(0x66); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x44); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x33); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x23); + lcdWriteData(0x00); + lcdWriteData(0x65); + lcdWriteData(0x00); + + lcdWriteCommand(0xE9); + lcdWriteData(0xAA); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0x00); + lcdWriteData(0xAA); + + lcdWriteCommand(0xCF); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xF0); + lcdWriteData(0x00); + lcdWriteData(0x50); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x00); + + lcdWriteCommand(0xF1); + lcdWriteData(0x01); + + lcdWriteCommand(0xee); + lcdWriteData(0xde); + lcdWriteData(0x21); + + lcdWriteCommand(0xF3); + lcdWriteData(0x00); + + lcdWriteCommand(0xF9); + lcdWriteData(0x06); + lcdWriteData(0x10); + lcdWriteData(0x29); + lcdWriteData(0x00); + + lcdWriteCommand(0xDF); + lcdWriteData(0x10); + SYSTEM_DelayMS(20); + lcdWriteCommand(0x36); + if( IsHorizontal ) + lcdWriteData(0x14);//需修改 + else + lcdWriteData(0x14); + + lcdWriteCommand(0x3A); + lcdWriteData(0x66); + + lcdWriteCommand(0x21); + + lcdWriteCommand(0x35); + lcdWriteData(0x00); + + lcdWriteCommand(0x28); +#endif +} + +void LCD_NT35310_On( void ) +{ + lcdWriteCommand( 0x29 ); +} + +void LCD_NT35310_Off( void ) +{ + lcdWriteCommand( 0x28 ); +} + +void LCD_Init_LTDC() { + hltdc.Instance = LTDC; + + /* Configure PLLSAI prescalers for LCD */ + /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ + /* PLLSAI_VCO Output = PLLSAI_VCO Input * lcdPixelclock * 16 = XX Mhz */ + /* PLLLCDCLK = PLLSAI_VCO Output/PLL_LTDC = PLLSAI_VCO/4 = YY Mhz */ + /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = YY/4 = lcdPixelClock Mhz */ +// uint32_t clock = (lcdPixelClock*16) / 1000000; // clock*16 in MHz +// RCC_PeriphCLKInitTypeDef clkConfig; +// clkConfig.PeriphClockSelection = RCC_PERIPHCLK_LTDC; +// clkConfig.PLLI2S +// clkConfig.PLLSAI.PLLSAIN = clock; +// clkConfig.PLLSAI.PLLSAIR = 4; +// clkConfig.PLLSAIDivQ = 6; +// clkConfig.PLLSAIDivR = RCC_PLLSAIDIVR_4; +// HAL_RCCEx_PeriphCLKConfig(&clkConfig); + + /* LTDC Configuration *********************************************************/ + /* Polarity configuration */ + /* Initialize the horizontal synchronization polarity as active low */ + hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL; + /* Initialize the vertical synchronization polarity as active low */ + hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL; + /* Initialize the data enable polarity as active low */ + hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL; + /* Initialize the pixel clock polarity as input pixel clock */ + hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IIPC; + + /* Configure R,G,B component values for LCD background color */ + hltdc.Init.Backcolor.Red = 0; + hltdc.Init.Backcolor.Green = 0; + hltdc.Init.Backcolor.Blue = 0; + + /* Configure horizontal synchronization width */ + hltdc.Init.HorizontalSync = HSW; + /* Configure vertical synchronization height */ + hltdc.Init.VerticalSync = VSH; + /* Configure accumulated horizontal back porch */ + hltdc.Init.AccumulatedHBP = HBP; + /* Configure accumulated vertical back porch */ + hltdc.Init.AccumulatedVBP = VBP; + /* Configure accumulated active width */ + hltdc.Init.AccumulatedActiveW = lcd_phys_w + HBP; + /* Configure accumulated active height */ + hltdc.Init.AccumulatedActiveH = lcd_phys_h + VBP; + /* Configure total width */ + hltdc.Init.TotalWidth = lcd_phys_w + HBP + HFP; + /* Configure total height */ + hltdc.Init.TotalHeigh = lcd_phys_h + VBP + VFP; + + HAL_LTDC_Init(&hltdc); + + // Configure IRQ (line) + NVIC_SetPriority(LTDC_IRQn, LTDC_IRQ_PRIO); + NVIC_EnableIRQ(LTDC_IRQn); + + // Trigger on last line + HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h); + __HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI); +} + +void LCD_LayerInit() { + auto& layer = hltdc.LayerCfg[0]; + + /* Windowing configuration */ + layer.WindowX0 = 0; + layer.WindowX1 = lcd_phys_w; + layer.WindowY0 = 0; + layer.WindowY1 = lcd_phys_h; + + /* Pixel Format configuration*/ + layer.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; + + /* Alpha constant (255 totally opaque) */ + layer.Alpha = 255; + + /* Default Color configuration (configure A,R,G,B component values) */ + layer.Backcolor.Blue = 0; + layer.Backcolor.Green = 0; + layer.Backcolor.Red = 0; + layer.Alpha0 = 0; + + /* Configure blending factors */ + layer.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA; + layer.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA; + + layer.ImageWidth = lcd_phys_w; + layer.ImageHeight = lcd_phys_h; + + /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ + layer.FBStartAdress = (intptr_t)initialFrameBuffer; + + /* Initialize LTDC layer 1 */ + HAL_LTDC_ConfigLayer(&hltdc, &hltdc.LayerCfg[0], 0); + + /* dithering activation */ + HAL_LTDC_EnableDither(&hltdc); +} + +extern "C" +void lcdSetInitalFrameBuffer(void* fbAddress) +{ + initialFrameBuffer = fbAddress; +} + +const char* boardLcdType = ""; + +extern "C" +void lcdInit(void) +{ + /* Configure the LCD SPI+RESET pins */ + lcdSpiConfig(); + + /* Reset the LCD --------------------------------------------------------*/ + lcdReset(); + + /* Configure the LCD Control pins */ + LCD_AF_GPIOConfig(); + + /* Send LCD initialization commands */ +// if (LCD_ILI9481_ReadID() == LCD_ILI9481_ID) { +// TRACE("LCD INIT: ILI9481"); +// boardLcdType = "ILI9481"; +// lcdInitFunction = LCD_ILI9481_Init; +// lcdOffFunction = LCD_ILI9481_Off; +// lcdOnFunction = LCD_ILI9481_On; +// lcdPixelClock = 12000000; +// } else if (LCD_ILI9486_ReadID() == LCD_ILI9486_ID) { +// TRACE("LCD INIT: ILI9486"); +// boardLcdType = "ILI9486"; +// lcdInitFunction = LCD_ILI9486_Init; +// lcdOffFunction = LCD_ILI9486_Off; +// lcdOnFunction = LCD_ILI9486_On; +// lcdPixelClock = 12000000; +// } else if (LCD_ILI9488_ReadID() == LCD_ILI9488_ID) { +// TRACE("LCD INIT: ILI9488"); +// boardLcdType = "ILI9488"; +// lcdInitFunction = LCD_ILI9488_Init; +// lcdOffFunction = LCD_ILI9488_Off; +// lcdOnFunction = LCD_ILI9488_On; +// lcdPixelClock = 12000000; +// lcd_phys_w = LCD_PHYS_H; +// lcd_phys_h = LCD_PHYS_W; +// } else if (LCD_HX8357D_ReadID() == LCD_HX8357D_ID) { +// TRACE("LCD INIT: HX8357D"); +// boardLcdType = "HX8357D"; +// lcdInitFunction = LCD_HX8357D_Init; +// lcdOffFunction = LCD_HX8357D_Off; +// lcdOnFunction = LCD_HX8357D_On; +// lcdPixelClock = 12000000; +// } else if (LCD_ST7796S_ReadID() == LCD_ST7796S_ID ) { +// TRACE("LCD INIT: ST7796S"); +// boardLcdType = "ST7796S"; +// lcdInitFunction = LCD_ST7796S_Init; +// lcdOffFunction = LCD_ST7796S_Off; +// lcdOnFunction = LCD_ST7796S_On; +// lcdPixelClock = 14500000; +// } +// else{ + TRACE("LCD INIT (default): ST7796S"); + boardLcdType = "ST7796S (Default)"; + lcdInitFunction = LCD_ST7796S_Init; + lcdOffFunction = LCD_ST7796S_Off; + lcdOnFunction = LCD_ST7796S_On; + lcdPixelClock = 12000000; +// } + + __HAL_RCC_LTDC_CLK_ENABLE(); + lcdInitFunction(); + + LCD_Init_LTDC(); + LCD_LayerInit(); + + // Enable LCD display + __HAL_LTDC_ENABLE(&hltdc); + + lcdSetFlushCb(startLcdRefresh); +} + +extern "C" void LTDC_IRQHandler(void) +{ + __HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI); + __HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI); + _frame_addr_reloaded = 1; +} \ No newline at end of file diff --git a/radio/src/boards/jumper-h750/lcd_driver.h b/radio/src/boards/jumper-h750/lcd_driver.h new file mode 100644 index 000000000..6ffeb1e9c --- /dev/null +++ b/radio/src/boards/jumper-h750/lcd_driver.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#ifndef __LCD_DRIVER_H__ +#define __LCD_DRIVER_H__ + +#define HBP ( 24 ) // TODO use names from FlySky +#define VBP ( 10 ) + +#define HSW ( 4 ) +#define VSH ( 2 ) + +#define HFP ( 140 - HBP ) +#define VFP ( 22 - VBP ) + +#define LCD_ST7796S_ID ( 0x7796 ) +#define LCD_ILI9481_ID ( 0x9481 ) +#define LCD_ILI9486_ID ( 0x9486 ) +#define LCD_ILI9488_ID ( 0x9488 ) +#define LCD_HX8357D_ID ( 0x99 ) + +#define LCD_DELAY() LCD_Delay() + +typedef void (*lcdSpiInitFucPtr)(void); +typedef unsigned int LcdReadIDFucPtr( void ); + +extern lcdSpiInitFucPtr lcdInitFunction; +extern lcdSpiInitFucPtr lcdOffFunction; +extern lcdSpiInitFucPtr lcdOnFunction; + +#define SET_IO_INPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_INPUT ) +#define SET_IO_OUTPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_OUTPUT ) + +#define LCD_NRST_HIGH() LL_GPIO_SetOutputPin(LCD_NRST_GPIO, LCD_NRST_GPIO_PIN) +#define LCD_NRST_LOW() LL_GPIO_ResetOutputPin(LCD_NRST_GPIO, LCD_NRST_GPIO_PIN) + +#define LCD_CS_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_CS_GPIO, LCD_SPI_CS_GPIO_PIN) +#define LCD_CS_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_CS_GPIO, LCD_SPI_CS_GPIO_PIN) + +#define LCD_SCK_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_GPIO, LCD_SPI_SCK_GPIO_PIN) +#define LCD_SCK_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_GPIO, LCD_SPI_SCK_GPIO_PIN) + +#define LCD_MOSI_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN) +#define LCD_MOSI_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN) + +#define LCD_MOSI_AS_INPUT() SET_IO_INPUT( LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN ) +#define LCD_MOSI_AS_OUTPUT() SET_IO_OUTPUT( LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN ) + +#define LCD_READ_DATA_PIN() LL_GPIO_IsInputPinSet(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN) + + +#define HORIZONTAL_SYNC_WIDTH ( 4 ) +#define HORIZONTAL_BACK_PORCH ( 24 ) +#define HORIZONTAL_FRONT_PORCH ( 140 - HORIZONTAL_BACK_PORCH ) +#define VERTICAL_SYNC_HEIGHT ( 2 ) +#define VERTICAL_BACK_PORCH ( 10 ) +#define VERTICAL_FRONT_PORCH ( 22 - VERTICAL_BACK_PORCH ) + +#endif \ No newline at end of file diff --git a/radio/src/boards/jumper-h750/led_driver.cpp b/radio/src/boards/jumper-h750/led_driver.cpp new file mode 100644 index 000000000..3eb16a009 --- /dev/null +++ b/radio/src/boards/jumper-h750/led_driver.cpp @@ -0,0 +1,134 @@ +/* + * 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/gpio.h" +#include "hal/rgbleds.h" +#include "stm32_gpio.h" +#include "boards/generic_stm32/rgb_leds.h" +#include "board.h" +#if defined(LED_STRIP_GPIO) +#include "stm32_ws2812.h" +#endif + +#define GET_RED(color) (((color) & 0xFF0000) >>16) +#define GET_GREEN(color) (((color) & 0x00FF00) >> 8) +#define GET_BLUE(color) ((color) & 0x0000FF) + +#if defined(FUNCTION_SWITCHES) && !defined(FUNCTION_SWITCHES_RGB_LEDS) +static const uint32_t fsLeds[] = {FSLED_GPIO_PIN_1, FSLED_GPIO_PIN_2, + FSLED_GPIO_PIN_3, FSLED_GPIO_PIN_4, + FSLED_GPIO_PIN_5, FSLED_GPIO_PIN_6}; +#endif + +void ledInit() +{ +#if defined(LED_GREEN_GPIO) + gpio_init(LED_GREEN_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); +#endif + +#if defined(LED_RED_GPIO) + gpio_init(LED_RED_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); +#endif + +#if defined(LED_BLUE_GPIO) + gpio_init(LED_BLUE_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); +#endif + +#if defined(FUNCTION_SWITCHES) && !defined(FUNCTION_SWITCHES_RGB_LEDS) + for (size_t i = 0; i < DIM(fsLeds); i++) { + gpio_init(fsLeds[i], GPIO_OUT, GPIO_PIN_SPEED_LOW); + } +#endif +} + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +void fsLedRGB(uint8_t index, uint32_t color) +{ + ws2812_set_color(index, GET_RED(color), \ + GET_GREEN(color),GET_BLUE(color)); +} + +uint8_t getRGBColorIndex(uint32_t color) +{ + for (uint8_t i = 0; i < (sizeof(colorTable) / sizeof(colorTable[0])); i++) { + if (color == colorTable[i]) + return(i); + } + return 5; // Custom value set with Companion +} +#elif defined(FUNCTION_SWITCHES) +void fsLedOff(uint8_t index) +{ + gpio_clear(fsLeds[index]); +} + +void fsLedOn(uint8_t index) +{ + gpio_set(fsLeds[index]); +} + +bool fsLedState(uint8_t index) +{ + return gpio_read(fsLeds[index]) ? true : false; +} +#endif + +void ledOff() +{ +#if defined(LED_RED_GPIO) + GPIO_LED_GPIO_OFF(LED_RED_GPIO); +#endif +#if defined(LED_BLUE_GPIO) + GPIO_LED_GPIO_OFF(LED_BLUE_GPIO); +#endif +#if defined(LED_GREEN_GPIO) + GPIO_LED_GPIO_OFF(LED_GREEN_GPIO); +#endif +} + +void ledRed() +{ + ledOff(); +#if defined(LED_RED_GPIO) + GPIO_LED_GPIO_ON(LED_RED_GPIO); +#endif +} + +void ledGreen() +{ + ledOff(); +#if defined(LED_GREEN_GPIO) + GPIO_LED_GPIO_ON(LED_GREEN_GPIO); +#endif +} + +void ledBlue() +{ + ledOff(); +#if defined(LED_BLUE_GPIO) + GPIO_LED_GPIO_ON(LED_BLUE_GPIO); +#endif +} + +uint32_t fsGetLedRGB(uint8_t index) +{ + return rgbGetLedColor(index + CFS_LED_STRIP_START); +} \ No newline at end of file diff --git a/radio/src/boards/jumper-h750/sdram_driver.cpp b/radio/src/boards/jumper-h750/sdram_driver.cpp new file mode 100644 index 000000000..bf56f468e --- /dev/null +++ b/radio/src/boards/jumper-h750/sdram_driver.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * 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/gpio.h" +#include "stm32_gpio.h" +#include "stm32_hal_ll.h" + +#include "board.h" + +#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 + +#define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_3 + +#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2 + +#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) + +#define SDRAM_READBURST FMC_SDRAM_RBURST_DISABLE + +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODEREG_BURST_FULL_PAGE ((uint16_t)0x0007) +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODEREG_CAS_LATENCY_1 ((uint16_t)0x0010) +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +#define GPIO_AF_FMC GPIO_AF12 + +extern "C" void SDRAM_GPIOConfig(void) +{ + /*-- GPIOs Configuration -----------------------------------------------------*/ + /* + */ + + /* GPIOC configuration */ + + /* GPIOD configuration */ + gpio_init_af(GPIO_PIN(GPIOD, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOD, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + + /* GPIOE configuration */ + gpio_init_af(GPIO_PIN(GPIOE, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOE, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + + /* GPIOF configuration */ + gpio_init_af(GPIO_PIN(GPIOF, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 2), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 3), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOF, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + + /* GPIOG configuration */ + gpio_init_af(GPIO_PIN(GPIOG, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOG, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOG, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + 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); + + gpio_init_af(GPIO_PIN(GPIOH, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOH, 6), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + gpio_init_af(GPIO_PIN(GPIOH, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); + +} + +extern "C" void SDRAM_InitSequence(void) +{ + FMC_SDRAM_CommandTypeDef FMC_SDRAMCommandStructure; + uint32_t tmpr = 0; + + /* Step 3 --------------------------------------------------------------------*/ + /* Configure a clock configuration enable command */ + FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; + FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + FMC_SDRAMCommandStructure.AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0; + /* Send the command */ + FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10); + + /* Step 4 --------------------------------------------------------------------*/ + /* Insert 1 ms delay */ + delay_ms(100); + + /* Step 5 --------------------------------------------------------------------*/ + /* Configure a PALL (precharge all) command */ + FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_PALL; + FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + FMC_SDRAMCommandStructure.AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0; + /* Send the command */ + FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10); + + /* Step 6 --------------------------------------------------------------------*/ + /* Configure a Auto-Refresh command */ + FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; + FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + FMC_SDRAMCommandStructure.AutoRefreshNumber = 8; + FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0; + /* Send the command */ + FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10); + + /* Step 7 --------------------------------------------------------------------*/ + /* Program the external memory mode register */ + tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + /* Configure a load Mode register command*/ + FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; + FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + FMC_SDRAMCommandStructure.AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.ModeRegisterDefinition = tmpr; + /* Send the command */ + FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10); + + /* Step 8 --------------------------------------------------------------------*/ + /* Set the refresh rate counter */ + /* (15.62 us x Freq) - 20 */ + /* Set the device refresh counter */ + FMC_SDRAM_SetAutoRefreshNumber(FMC_Bank5_6_R, 15); + FMC_SDRAM_ProgramRefreshRate(FMC_Bank5_6_R, 1855); +} + +extern "C" void SDRAM_Init(void) +{ + //delay funcion needed + delaysInit(); + + /* GPIO configuration for FMC SDRAM bank */ + SDRAM_GPIOConfig(); + + /* Enable FMC clock */ + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FMC); + + /* FMC Configuration ---------------------------------------------------------*/ + FMC_SDRAM_InitTypeDef FMC_SDRAMInitStructure; + FMC_SDRAM_TimingTypeDef FMC_SDRAMTimingInitStructure; + + /* FMC SDRAM Bank configuration */ + /* Timing configuration for 80 Mhz of SD clock */ + FMC_SDRAMTimingInitStructure.LoadToActiveDelay = 2; + FMC_SDRAMTimingInitStructure.ExitSelfRefreshDelay = 7; + FMC_SDRAMTimingInitStructure.SelfRefreshTime = 4; + FMC_SDRAMTimingInitStructure.RowCycleDelay = 7; + FMC_SDRAMTimingInitStructure.WriteRecoveryTime = 3; + FMC_SDRAMTimingInitStructure.RPDelay = 2; + FMC_SDRAMTimingInitStructure.RCDDelay = 2; + + /* FMC SDRAM control configuration */ + FMC_SDRAMInitStructure.SDBank = FMC_SDRAM_BANK2; + FMC_SDRAMInitStructure.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; + FMC_SDRAMInitStructure.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; + FMC_SDRAMInitStructure.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; + FMC_SDRAMInitStructure.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; + FMC_SDRAMInitStructure.CASLatency = FMC_SDRAM_CAS_LATENCY_3; + FMC_SDRAMInitStructure.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; + FMC_SDRAMInitStructure.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3; + FMC_SDRAMInitStructure.ReadBurst = FMC_SDRAM_RBURST_ENABLE; + FMC_SDRAMInitStructure.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; + + /* FMC SDRAM bank initialization */ + FMC_SDRAM_Init(FMC_Bank5_6_R, &FMC_SDRAMInitStructure); + FMC_SDRAM_Timing_Init(FMC_Bank5_6_R, &FMC_SDRAMTimingInitStructure, FMC_SDRAM_BANK2); + + __FMC_ENABLE(); + + /* FMC SDRAM device initialization sequence */ + SDRAM_InitSequence(); +} diff --git a/radio/src/boards/jumper-h750/system_clock.c b/radio/src/boards/jumper-h750/system_clock.c new file mode 100644 index 000000000..2c32220da --- /dev/null +++ b/radio/src/boards/jumper-h750/system_clock.c @@ -0,0 +1,111 @@ +/* + * 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 "stm32h7xx_ll_pwr.h" +#include "stm32h7xx_ll_rcc.h" +#include "stm32h7xx_ll_system.h" +#include "stm32h7xx_ll_bus.h" + +#define BOOTSTRAP __attribute__((section(".bootstrap"))) + +BOOTSTRAP void SystemClock_Config(void) +{ + /* Power Configuration */ + LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY); + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); + while (LL_PWR_IsActiveFlag_VOS() == 0){ + } + + /* Enable HSE oscillator */ + LL_RCC_HSE_Enable(); + while (LL_RCC_HSE_IsReady() != 1) { + } + + /* Set FLASH latency */ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_5); + + /* Main PLL configuration and activation */ + LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE); + LL_RCC_PLL1P_Enable(); + LL_RCC_PLL1Q_Enable(); + LL_RCC_PLL1R_Enable(); + LL_RCC_PLL1FRACN_Disable(); + LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4); + LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); + LL_RCC_PLL1_SetM(3); + LL_RCC_PLL1_SetN(60); + LL_RCC_PLL1_SetP(2); + LL_RCC_PLL1_SetQ(20); + LL_RCC_PLL1_SetR(2); + LL_RCC_PLL1_Enable(); + while (LL_RCC_PLL1_IsReady() != 1) { + } + + /* Set Sys & AHB & APB1 & APB2 & APB4 prescaler */ + LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2); + LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2); + + /* Set PLL1 as System Clock Source */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) { + } + + /* Config & activate PLL2 */ + LL_RCC_PLL2P_Enable(); + LL_RCC_PLL2FRACN_Disable(); + LL_RCC_PLL2_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4); + LL_RCC_PLL2_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); + LL_RCC_PLL2_SetM(24); + LL_RCC_PLL2_SetN(96); + LL_RCC_PLL2_SetP(17); // 11.294 MHz + LL_RCC_PLL2_Enable(); + while (LL_RCC_PLL2_IsReady() != 1) { + } + + /* Config & activate PLL3 */ + LL_RCC_PLL3P_Enable(); + LL_RCC_PLL3Q_Enable(); + LL_RCC_PLL3R_Enable(); + LL_RCC_PLL3FRACN_Disable(); + LL_RCC_PLL3_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4); + LL_RCC_PLL3_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); + LL_RCC_PLL3_SetM(1); + LL_RCC_PLL3_SetN(4); + LL_RCC_PLL3_SetP(2); + LL_RCC_PLL3_SetQ(2); + LL_RCC_PLL3_SetR(18); + LL_RCC_PLL3_Enable(); + while (LL_RCC_PLL3_IsReady() != 1) { + } + + /* Enable SRAM1, SRAM2 & SRAM3 */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_D2SRAM1 | + LL_AHB2_GRP1_PERIPH_D2SRAM2 | + LL_AHB2_GRP1_PERIPH_D2SRAM3); + + /* Set periph clock sources */ + LL_RCC_SetSPIClockSource(LL_RCC_SPI123_CLKSOURCE_PLL1Q); + LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL1Q); + LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_CLKP); +} diff --git a/radio/src/boards/jumper-h750/system_clock.h b/radio/src/boards/jumper-h750/system_clock.h new file mode 100644 index 000000000..10b69a118 --- /dev/null +++ b/radio/src/boards/jumper-h750/system_clock.h @@ -0,0 +1,23 @@ +/* + * 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. + */ + +void SystemClock_Config(); + diff --git a/radio/src/boards/jumper-h750/touch_driver.cpp b/radio/src/boards/jumper-h750/touch_driver.cpp new file mode 100644 index 000000000..96ed51480 --- /dev/null +++ b/radio/src/boards/jumper-h750/touch_driver.cpp @@ -0,0 +1,291 @@ +/* + * 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 "touch_driver.h" +#include "stm32_hal.h" +#include "stm32_hal_ll.h" + +#include "stm32_exti_driver.h" +#include "stm32_gpio.h" +#include "stm32_gpio_driver.h" +#include "stm32_i2c_driver.h" +#include "timers_driver.h" + +#include "debug.h" +#include "delays_driver.h" +#include "hal.h" +#include "hal/gpio.h" +#include "hal/i2c_driver.h" +#include "rtos.h" + +volatile static bool touchEventOccured; + +#define TOUCH_CST836U_I2C_ADDRESS (0x15) + +static tc_handle_TypeDef tc_handle = {0, 0}; + +tmr10ms_t downTime = 0; +tmr10ms_t tapTime = 0; +short tapCount = 0; +#define TAP_TIME 250 // ms + +static TouchState internalTouchState = {}; + +static void _cst836u_exti_isr(void) { + touchEventOccured = true; +} + +static void TouchAFExtiConfig(void) +{ + TRACE("TOUCH_AF_EXTI_CONFIG"); + gpio_init_int(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_FALLING, _cst836u_exti_isr); +} + +void initTouchI2C(void) +{ + TRACE("CST836U I2C Init"); + + if (i2c_init(TOUCH_I2C_BUS) < 0) { + TRACE("CST836U ERROR: i2c_init failed"); + return; + } +} + +#define I2C_TIMEOUT_MAX 5 // 5 ms + +bool touch_i2c_read(uint8_t addr, uint8_t reg, uint8_t* data, uint8_t len) +{ + if (stm32_i2c_master_tx(TOUCH_I2C_BUS, addr, ®, 1, 3) < 0) return false; + delay_us(5); + if (stm32_i2c_master_rx(TOUCH_I2C_BUS, addr, data, len, I2C_TIMEOUT_MAX) < 0) + return false; + + return true; +} + +static uint8_t TS_IO_Read(uint8_t addr, uint8_t reg) +{ + uint8_t result; + uint8_t tryCount = 3; + while (!touch_i2c_read(addr, reg, &result, 1)) { + if (--tryCount == 0) break; + initTouchI2C(); + } + return result; +} + +static uint16_t TS_IO_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t* buffer, + uint16_t length) +{ + uint8_t tryCount = 3; + while (!touch_i2c_read(addr, reg, buffer, length)) { + if (--tryCount == 0) break; + initTouchI2C(); + } + return 1; +} + +static void touch_cst836u_debug_info(void) +{ +#if defined(DEBUG) + TRACE("cst836u: fw ver 0x%02X %02X", + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_H_REG), + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_L_REG)); + TRACE("cst836u: module version 0x%02X", + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_MODULE_VERSION_REG)); + TRACE("cst836u: project name 0x%02X", + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_PROJECT_NAME_REG)); + TRACE("cst836u: chip type 0x%02X 0x%02X", + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_H_REG), + TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_L_REG)); +#endif +} + +/** + * @brief Get the touch screen X and Y positions values + * Manage multi touch thanks to touch Index global + * variable 'tc_handle.currActiveTouchIdx'. + * @param DeviceAddr: Device address on communication Bus. + * @param X: Pointer to X position value + * @param Y: Pointer to Y position value + * @retval None. + */ +static void cst836u_TS_GetXY(uint16_t* X, uint16_t* Y, uint32_t* event) +{ + uint8_t regAddress = 0; + uint8_t dataxy[4]; + + if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) { + switch (tc_handle.currActiveTouchIdx) { + case 0: + regAddress = CST836U_TOUCH1_XH_REG; + break; + case 1: + regAddress = CST836U_TOUCH2_XH_REG; + break; + default: + break; + } + + /* Read X and Y positions */ + TS_IO_ReadMultiple(TOUCH_CST836U_I2C_ADDRESS, regAddress, dataxy, + sizeof(dataxy)); + /* Send back ready X position to caller */ + *X = ((dataxy[0] & CST836U_MSB_MASK) << 8) | dataxy[1]; + /* Send back ready Y position to caller */ + *Y = ((dataxy[2] & CST836U_MSB_MASK) << 8) | dataxy[3]; + + *event = (dataxy[0] & CST836U_TOUCH_EVT_FLAG_MASK) >> + CST836U_TOUCH_EVT_FLAG_SHIFT; + /* + uint32_t weight; + uint32_t area; + */ + tc_handle.currActiveTouchIdx++; + } +} + +/** + * @brief Return if there is touches detected or not. + * Try to detect new touches and forget the old ones (reset internal + * global variables). + * @param DeviceAddr: Device address on communication Bus. + * @retval : Number of active touches detected (can be 0, 1 or 2). + */ +static uint8_t cst836u_TS_DetectTouch() +{ + volatile uint8_t nbTouch = 0; + + /* Read register CST836U_TOUCH_NUM_REG to check number of touches detection */ + nbTouch = TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_TOUCH_NUM_REG); + if (nbTouch > CST836U_MAX_DETECTABLE_TOUCH) { + /* If invalid number of touch detected, set it to zero */ + nbTouch = 0; + } + tc_handle.currActiveTouchNb = nbTouch; + + tc_handle.currActiveTouchIdx = 0; + return (nbTouch); +} + +void TouchReset() +{ + gpio_clear(TOUCH_RST_GPIO); + delay_ms(10); + gpio_set(TOUCH_RST_GPIO); + delay_ms(300); +} + +void touchPanelInit(void) +{ + gpio_init(TOUCH_RST_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); + initTouchI2C(); + TouchReset(); + TouchAFExtiConfig(); + touch_cst836u_debug_info(); +} + +void handleTouch() +{ + unsigned short touchX; + unsigned short touchY; + uint32_t tEvent = 0; + cst836u_TS_GetXY(&touchX, &touchY, &tEvent); + + if (tEvent == CST836U_TOUCH_EVT_FLAG_CONTACT) { + int dx = touchX - internalTouchState.x; + int dy = touchY - internalTouchState.y; + + internalTouchState.x = touchX; + internalTouchState.y = touchY; + + if (internalTouchState.event == TE_NONE || + internalTouchState.event == TE_UP || + internalTouchState.event == TE_SLIDE_END) { + internalTouchState.startX = internalTouchState.x; + internalTouchState.startY = internalTouchState.y; + internalTouchState.event = TE_DOWN; + } else if (internalTouchState.event == TE_DOWN) { + if (dx >= SLIDE_RANGE || dx <= -SLIDE_RANGE || dy >= SLIDE_RANGE || + dy <= -SLIDE_RANGE) { + internalTouchState.event = TE_SLIDE; + internalTouchState.deltaX = (short)dx; + internalTouchState.deltaY = (short)dy; + } else { + internalTouchState.event = TE_DOWN; + internalTouchState.deltaX = 0; + internalTouchState.deltaY = 0; + } + } else if (internalTouchState.event == TE_SLIDE) { + internalTouchState.event = TE_SLIDE; // no change + internalTouchState.deltaX = (short)dx; + internalTouchState.deltaY = (short)dy; + } + } +} + +bool touchPanelEventOccured() { return touchEventOccured; } + +TouchState touchPanelRead() +{ + if (!touchEventOccured) return internalTouchState; + + touchEventOccured = false; + + tmr10ms_t now = timersGetMsTick(); + internalTouchState.tapCount = 0; + + if (cst836u_TS_DetectTouch()) { + handleTouch(); + if (internalTouchState.event == TE_DOWN && downTime == 0) { + downTime = now; + } + } else { + if (internalTouchState.event == TE_DOWN) { + internalTouchState.event = TE_UP; + if (now - downTime <= TAP_TIME) { + if (now - tapTime > TAP_TIME) { + tapCount = 1; + } else { + tapCount++; + } + internalTouchState.tapCount = tapCount; + tapTime = now; + } else { + internalTouchState.tapCount = 0; // not a tap + } + downTime = 0; + } else { + tapCount = 0; + internalTouchState.tapCount = 0; + internalTouchState.event = TE_SLIDE_END; + } + } + TouchState ret = internalTouchState; + internalTouchState.deltaX = 0; + internalTouchState.deltaY = 0; + if (internalTouchState.event == TE_UP || + internalTouchState.event == TE_SLIDE_END) + internalTouchState.event = TE_NONE; + return ret; +} + +TouchState getInternalTouchState() { return internalTouchState; } diff --git a/radio/src/boards/jumper-h750/touch_driver.h b/radio/src/boards/jumper-h750/touch_driver.h new file mode 100644 index 000000000..b4c8eb6b9 --- /dev/null +++ b/radio/src/boards/jumper-h750/touch_driver.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + Copyright 2016 fishpepper gmail.com + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + 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. + You should have received a copy of the GNU General Public License + along with this program. If not, see . + author: fishpepper gmail.com +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Set Multi-touch as non supported */ +#ifndef TS_MULTI_TOUCH_SUPPORTED +#define TS_MULTI_TOUCH_SUPPORTED 0 +#endif + +/* Set Auto-calibration as non supported */ +#ifndef TS_AUTO_CALIBRATION_SUPPORTED +#define TS_AUTO_CALIBRATION_SUPPORTED 0 +#endif + +/* Macros --------------------------------------------------------------------*/ + +/** @typedef ft6x06_handle_TypeDef + * ft6x06 Handle definition. + */ +typedef struct { + /* field holding the current number of simultaneous active touches */ + uint8_t currActiveTouchNb; + + /* field holding the touch index currently managed */ + uint8_t currActiveTouchIdx; + +} tc_handle_TypeDef; +/* clang-format off */ +#define CST836U_WORK_MODE_REG 0x00 +#define CST836U_PROXIMITY_ID_REG 0x01 +#define CST836U_TOUCH_NUM_REG 0x02 +#define CST836U_TOUCH1_XH_REG 0x03 +#define CST836U_TOUCH1_XL_REG 0x04 +#define CST836U_TOUCH1_YH_REG 0x05 +#define CST836U_TOUCH1_YL_REG 0x06 + +#define CST836U_TOUCH2_XH_REG 0x09 +#define CST836U_TOUCH2_XL_REG 0x0A +#define CST836U_TOUCH2_YH_REG 0x0B +#define CST836U_TOUCH2_YL_REG 0x0C + +#define CST836U_FW_VERSION_L_REG 0xA6 +#define CST836U_FW_VERSION_H_REG 0xA7 +#define CST836U_MODULE_VERSION_REG 0xA8 +#define CST836U_PROJECT_NAME_REG 0xA9 +#define CST836U_CHIP_TYPE_L_REG 0xAA +#define CST836U_CHIP_TYPE_H_REG 0xAB +#define CST836U_CHECKSUM_L_REG 0xAC +#define CST836U_CHECKSUM_H_REG 0xAD + +#define CST836U_PROX_STATE_REG 0xB0 +#define CST836U_GES_STATE_REG 0xD0 +#define CST836U_GES_ID_REG_REG 0xD3 + +#define CST836U_MAX_DETECTABLE_TOUCH 2 + +#define CST836U_MSB_MASK 0x0F + +#define CST836U_TOUCH_EVT_FLAG_SHIFT 6 +#define CST836U_TOUCH_EVT_FLAG_MASK (3 << CST836U_TOUCH_EVT_FLAG_SHIFT) +#define CST836U_TOUCH_EVT_FLAG_CONTACT 0x02 +/* clang-format on */ + +extern void touchPanelInit(void); +extern void TouchDriver(void); + +#ifdef __cplusplus +} +#endif diff --git a/radio/src/boards/jumper-h750/usb_charger_driver.cpp b/radio/src/boards/jumper-h750/usb_charger_driver.cpp new file mode 100644 index 000000000..1e319b9e8 --- /dev/null +++ b/radio/src/boards/jumper-h750/usb_charger_driver.cpp @@ -0,0 +1,36 @@ +/* + * 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/gpio.h" +#include "stm32_gpio.h" + +#include "board.h" +#include "hal/usb_driver.h" + +void usbChargerInit() +{ + gpio_init(UCHARGER_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW); +} + +bool usbChargerLed() +{ + return (gpio_read(UCHARGER_GPIO) && usbPlugged()); +} diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index f85c8ee12..63fb695a4 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -88,7 +88,7 @@ static inline void check_struct() #if defined(PCBXLITES) CHKSIZE(RadioData, 945); -#elif defined(RADIO_ST16) || defined(PCBPA01) || defined(RADIO_TX15) +#elif defined(RADIO_ST16) || defined(PCBPA01) || defined(RADIO_TX15) || defined(RADIO_T15PRO) CHKSIZE(RadioData, 1159); #elif defined(COLORLCD) CHKSIZE(RadioData, 1039); @@ -126,6 +126,8 @@ static inline void check_struct() CHKSIZE(ModelData, 27522); #elif defined(RADIO_T15) CHKSIZE(ModelData, 27683); +#elif defined(RADIO_T15PRO) + CHKSIZE(ModelData, 27761); #elif defined(RADIO_TX15) CHKSIZE(ModelData, 27761); #elif defined(RADIO_H7RS) diff --git a/radio/src/drivers/pca95xx.h b/radio/src/drivers/pca95xx.h index 9c6df92ea..e401a6729 100644 --- a/radio/src/drivers/pca95xx.h +++ b/radio/src/drivers/pca95xx.h @@ -44,6 +44,8 @@ #define PCA95XX_PIN_13 (1 << 13) #define PCA95XX_PIN_14 (1 << 14) #define PCA95XX_PIN_15 (1 << 15) +#define PCA95XX_PIN_16 (1 << 16) +#define PCA95XX_PIN_17 (1 << 17) #define PCA95XX_P0 PCA95XX_PIN_0 #define PCA95XX_P1 PCA95XX_PIN_1 diff --git a/radio/src/hal/rotary_encoder.h b/radio/src/hal/rotary_encoder.h index 93f4679c1..0e6246f50 100644 --- a/radio/src/hal/rotary_encoder.h +++ b/radio/src/hal/rotary_encoder.h @@ -27,7 +27,7 @@ #define ROTENC_MIDSPEED 5 #define ROTENC_HIGHSPEED 50 -#if defined(RADIO_FAMILY_T20) || defined(RADIO_T14) || defined(RADIO_T12MAX) || defined(RADIO_T15) || defined(RADIO_BUMBLEBEE) +#if defined(RADIO_FAMILY_T20) || defined(RADIO_T14) || defined(RADIO_T12MAX) || defined(RADIO_T15) || defined(RADIO_T15PRO) || defined(RADIO_BUMBLEBEE) #define ROTARY_ENCODER_GRANULARITY 4 #else #define ROTARY_ENCODER_GRANULARITY 2 diff --git a/radio/src/storage/yaml/CMakeLists.txt b/radio/src/storage/yaml/CMakeLists.txt index 69c75cabb..e36480c18 100644 --- a/radio/src/storage/yaml/CMakeLists.txt +++ b/radio/src/storage/yaml/CMakeLists.txt @@ -34,12 +34,14 @@ elseif(PCB STREQUAL PL18) else() set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pl18.cpp) endif() +elseif(PCB STREQUAL T15PRO) + set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_t15pro.cpp) elseif(PCB STREQUAL ST16) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_st16.cpp) elseif(PCB STREQUAL PA01) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pa01.cpp) elseif(PCB STREQUAL TX15) - set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tx15.cpp) + set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tx15.cpp) elseif(PCB STREQUAL X7) if(PCBREV STREQUAL TPRO) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp) diff --git a/radio/src/storage/yaml/yaml_datastructs.cpp b/radio/src/storage/yaml/yaml_datastructs.cpp index 3bf47a0ee..23cb98450 100644 --- a/radio/src/storage/yaml/yaml_datastructs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs.cpp @@ -38,6 +38,8 @@ #endif #elif defined(PCBTX15) #include "yaml_datastructs_tx15.cpp" +#elif defined(PCBT15) + #include "yaml_datastructs_t15pro.cpp" #elif defined(PCBPL18) #if defined(RADIO_NB4P) #include "yaml_datastructs_nb4p.cpp" diff --git a/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp b/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp new file mode 100644 index 000000000..01d8a3f61 --- /dev/null +++ b/radio/src/storage/yaml/yaml_datastructs_t15pro.cpp @@ -0,0 +1,985 @@ +// 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_PUSH_CUST_SWITCH, "PUSH_CUST_SWITCH" }, + { FUNC_TEST, "TEST" }, + { 0, NULL } +}; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; +const struct YamlIdStr enum_booleanEnum[] = { + { BOOL_OFF, "OFF" }, + { BOOL_ON, "ON" }, + { 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_TILT_X, "TILT_X" }, + { MIXSRC_TILT_Y, "TILT_Y" }, + { MIXSRC_SPACEMOUSE_A, "SPACEMOUSE_A" }, + { MIXSRC_SPACEMOUSE_B, "SPACEMOUSE_B" }, + { MIXSRC_SPACEMOUSE_C, "SPACEMOUSE_C" }, + { MIXSRC_SPACEMOUSE_D, "SPACEMOUSE_D" }, + { MIXSRC_SPACEMOUSE_E, "SPACEMOUSE_E" }, + { MIXSRC_SPACEMOUSE_F, "SPACEMOUSE_F" }, + { 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, NULL), + 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, NULL), + YAML_CUSTOM("def",r_customFn,w_customFn), + YAML_PADDING( 64 ), + YAML_PADDING( 1 ), + YAML_PADDING( 7 ), + YAML_END +}; +static const struct YamlNode struct_RGBLedColor[] = { + YAML_UNSIGNED( "r", 8 ), + YAML_UNSIGNED( "g", 8 ), + YAML_UNSIGNED( "b", 8 ), + YAML_END +}; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_PADDING( 1 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, switch_is_cfs), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), + 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_UNSIGNED( "vBatWarn", 8 ), + YAML_SIGNED( "txVoltageCalibration", 8 ), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), + YAML_UNSIGNED( "disableRtcWarning", 1 ), + YAML_UNSIGNED( "keysBacklight", 1 ), + YAML_UNSIGNED( "dontPlayHello", 1 ), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), + 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, NULL), + 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_PADDING( 8 ), + YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), + YAML_ARRAY("switchConfig", 80, 20, struct_switchDef, switchIsActive), + 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_SIGNED( "imuMax", 8 ), + YAML_SIGNED( "imuOffset", 8 ), + 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, NULL), + 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_UNSIGNED_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, NULL), + 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, NULL), + 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, NULL), + 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, NULL), + 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, NULL), + 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, NULL), + 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, NULL), + 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_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 2 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_PADDING( 6 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, isAlwaysActive), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, isAlwaysActive), + YAML_END +}; +static const struct YamlNode struct_USBJoystickChData[] = { + YAML_IDX, + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), + 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", 2, 32, struct_swtchWarn, nullptr), + 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, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), + 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_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("functionSwitchLedONColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOnColorConfig, nullptr), + YAML_ARRAY("functionSwitchLedOFFColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOffColorConfig, nullptr), + YAML_ARRAY("customSwitches", 88, 6, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), + YAML_UNSIGNED( "usbJoystickExtMode", 1 ), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), + YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), + YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), + 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/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp b/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp index 5e41b7518..f25933cb0 100644 --- a/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp +++ b/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp @@ -263,7 +263,7 @@ static void dac_close_dma_xfer() DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5; // Disable DMA stream - AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN; + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN; } static void dac_start_dma_request(const audio_data_t* data, uint16_t length) @@ -279,7 +279,7 @@ static void dac_start_dma_request(const audio_data_t* data, uint16_t length) AUDIO_DAC->SR = DAC_SR_DMAUDR1; // enable DAC - AUDIO_DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1; + AUDIO_DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1; } void audioConsumeCurrentBuffer() @@ -370,7 +370,7 @@ static void dac_periph_init() // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function // So maybe it is automatically done void dacInit() -{ +{ #if defined(AUDIO_MUTE_GPIO) // Mute before init anything gpio_init(AUDIO_MUTE_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); diff --git a/radio/src/targets/t15pro/CMakeLists.txt b/radio/src/targets/t15pro/CMakeLists.txt new file mode 100644 index 000000000..c1cb35b2c --- /dev/null +++ b/radio/src/targets/t15pro/CMakeLists.txt @@ -0,0 +1,191 @@ +option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON) +option(PXX1 "PXX1 protocol support" ON) +option(PXX2 "PXX2 protocol support" OFF) +option(AFHDS3 "AFHDS3 TX Module" ON) +option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON) +option(GHOST "Ghost TX Module" ON) +option(MODULE_SIZE_STD "Standard size TX Module" ON) +option(LUA_MIXER "Enable LUA mixer/model scripts support" ON) +option(DISK_CACHE "Enable SD card disk cache" ON) + +set(FIRMWARE_QSPI YES) +set(FIRMWARE_FORMAT_UF2 YES) +set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") +set(CPU_TYPE STM32H7) +set(HSE_VALUE 48000000) +set(SDCARD YES) +set(STORAGE_MODELSLIST YES) +set(HAPTIC YES) +set(GUI_DIR colorlcd) +set(BITMAPS_DIR 480x272) +set(TARGET_DIR t15pro) +set(RTC_BACKUP_RAM YES) +set(PPM_LIMITS_SYMETRICAL YES) +set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)") +set(HARDWARE_EXTERNAL_MODULE YES) +set(INTERNAL_MODULE_AFHDS3 NO) +set(ROTARY_ENCODER YES) +set(FUNCTION_SWITCHES_WITH_RGB YES) + +#option(STICKS_DEAD_ZONE "Enable sticks dead zone" YES) + +# IMU support +set(IMU ON) + +# for size report script +set(CPU_TYPE_FULL STM32H750xB) +set(TARGET_LINKER_DIR stm32h750_sdram) +set(TARGET_EXTRAM_START 0xD0000000) +set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192") +set(FIRMWARE_STRIP_BOOTLOADER YES) + +add_definitions(-DPCBT15 -DPCBHORUS) +add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS) +add_definitions(-DFIRMWARE_QSPI) +add_definitions(-DFIRMWARE_FORMAT_UF2) +add_definitions(-DUSE_CUSTOM_EXTI_IRQ) +add_definitions(-DUSB_CHARGER) + +set(FLAVOUR t15pro) +add_definitions(-DRADIO_T15PRO) + +# defines existing internal modules +set(INTERNAL_MODULES CRSF CACHE STRING "Internal modules") +set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module") + +set(BITMAPS_TARGET bm480_bitmaps) +set(FONTS_TARGET x12_fonts) +set(LCD_DRIVER lcd_driver.cpp) +set(HARDWARE_TOUCH YES) +set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET}) +set(FIRMWARE_DEPENDENCIES datacopy) +set(SOFTWARE_KEYBOARD ON) +set(FLYSKY_GIMBAL OFF) +set(FUNCTION_SWITCHES_WITH_RGB YES) + +add_definitions( + -DSTM32H750XBTx -DSTM32H750xx + -DSDRAM -DCCMRAM + -DCOLORLCD -DLIBOPENUI + -DHARDWARE_TOUCH -DHARDWARE_KEYS -DSOFTWARE_KEYBOARD +) + +set(SDRAM ON) + +add_definitions(-DAUDIO -DVOICE) +add_definitions(-DSOFTWARE_VOLUME) +add_definitions(-DRTCLOCK) +add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE}) +add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) + +if(STICKS_DEAD_ZONE) + add_definitions(-DSTICK_DEAD_ZONE) +endif() + +if(NOT UNEXPECTED_SHUTDOWN) + add_definitions(-DNO_UNEXPECTED_SHUTDOWN) +endif() + +if(DISK_CACHE) + set(SRC ${SRC} disk_cache.cpp) + add_definitions(-DDISK_CACHE) +endif() + +if(FUNCTION_SWITCHES_WITH_RGB) + set(FUNCTION_SWITCHES YES) + add_definitions(-DFUNCTION_SWITCHES) + add_definitions(-DFUNCTION_SWITCHES_RGB_LEDS) +endif() + +if(FUNCTION_SWITCHES) +add_definitions(-DFUNCTION_SWITCHES) +endif() + +set(AFHDS3 ON) + +# VCP CLI +set(ENABLE_SERIAL_PASSTHROUGH ON CACHE BOOL "Enable serial passthrough") +set(CLI ON CACHE BOOL "Enable CLI") + +set(BOARD jumper-h750) +set(BOARD_SRC_DIR boards/${BOARD}) +include_directories(boards/${BOARD}) + +set(TARGET_SRC_DIR targets/${TARGET_DIR}) + +set(BOARD_COMMON_SRC + ${BOARD_SRC_DIR}/board.cpp + ${BOARD_SRC_DIR}/key_driver.cpp + ${BOARD_SRC_DIR}/lcd_driver.cpp + ${BOARD_SRC_DIR}/backlight_driver.cpp + ${BOARD_SRC_DIR}/haptic_driver.cpp + ${BOARD_SRC_DIR}/extflash_driver.cpp + ${BOARD_SRC_DIR}/usb_charger_driver.cpp + targets/common/arm/stm32/abnormal_reboot.cpp + targets/common/arm/stm32/delays_driver.cpp + targets/common/arm/stm32/dma2d.cpp + targets/common/arm/stm32/flash_driver.cpp + targets/common/arm/stm32/pwr_driver.cpp + targets/common/arm/stm32/rotary_encoder_driver.cpp + targets/common/arm/stm32/rtc_driver.cpp + targets/common/arm/stm32/watchdog_driver.cpp + drivers/pca95xx.cpp +) + +# Bootloader board library +add_library(board_bl OBJECT EXCLUDE_FROM_ALL + ${BOARD_COMMON_SRC} + ${BOARD_SRC_DIR}/sdram_driver.cpp + ${RADIO_SRC_DIR}/gui/colorlcd/boot_menu.cpp + targets/common/arm/stm32/stm32_qspi.cpp + targets/common/arm/stm32/stm32_pulse_driver.cpp +) +add_dependencies(board_bl minimal_board_lib) +set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $) + +set(CMSIS_SRC ${BOARD_SRC_DIR}/system_clock.c) + +# Firmware board library +add_library(board OBJECT EXCLUDE_FROM_ALL + ${BOARD_COMMON_SRC} + ${BOARD_SRC_DIR}/led_driver.cpp + ${BOARD_SRC_DIR}/touch_driver.cpp + targets/common/arm/stm32/audio_dac_driver.cpp + targets/common/arm/stm32/heartbeat_driver.cpp + targets/common/arm/stm32/lsm6ds_driver.cpp + targets/common/arm/stm32/mixer_scheduler_driver.cpp + targets/common/arm/stm32/module_timer_driver.cpp + targets/common/arm/stm32/stm32_pulse_driver.cpp + targets/common/arm/stm32/stm32_softserial_driver.cpp + targets/common/arm/stm32/stm32_qspi.cpp + targets/common/arm/stm32/stm32_switch_driver.cpp + targets/common/arm/stm32/stm32_ws2812.cpp + targets/common/arm/stm32/trainer_driver.cpp +) +add_dependencies(board board_lib) +set(FIRMWARE_SRC ${FIRMWARE_SRC} $) + +include_directories(${RADIO_SRC_DIR}/fonts/colorlcd gui/${GUI_DIR} gui/${GUI_DIR}/layouts) + +if(BOOTLOADER) + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + ../../bootloader/loadboot.cpp + ) +endif() + +set(SRC + ${SRC} + io/frsky_firmware_update.cpp + io/multi_firmware_update.cpp + ) + +if (MULTIMODULE) + add_definitions(-DMULTI_PROTOLIST) + set(SRC ${SRC} + io/multi_protolist.cpp + ) +endif() + +# Make malloc() thread-safe +add_definitions(-DTHREADSAFE_MALLOC) diff --git a/radio/src/targets/t15pro/hal.h b/radio/src/targets/t15pro/hal.h new file mode 100644 index 000000000..ab445c9f2 --- /dev/null +++ b/radio/src/targets/t15pro/hal.h @@ -0,0 +1,509 @@ +/* + * 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. + */ + +/* +STM32H750 +DMA1 +Stream0: LED_STRIP_TIMER_DMA_STREAM +Stream1: INTMODULE_DMA_STREAM +Stream2: FLYSKY_HALL_DMA_Stream_RX +Stream3: TELEMETRY_DMA_Stream_RX +Stream4: ADC_DMA_STREAM +Stream5: INTMODULE_RX_DMA_STREAM +Stream6: +Stream7: TELEMETRY_DMA_Stream_TX + +DMA2 +Stream0: +Stream1: AUDIO_DMA_Stream +Stream2: +Stream3: EXTMODULE_TIMER_DMA_STREAM +Stream4: ADC_DMA_STREAM +Stream5: EXTMODULE_USART_RX_DMA_STREAM +Stream6: EXTMODULE_USART_TX_DMA_STREAM + +TIM1: LED_STRIP_TIMER +TIM2: BACKLIGHT_TIMER +TIM3: EXTMODULE_TIMER +TIM4: (no pins) +TIM5: TRAINER_TIMER +TIM6: AUDIO_TIMER +TIM7: (no pins) +TIM8: TRAINER_TIMER +TIM12: MIXER_SCHEDULER_TIMER +TIM13: +TIM14: MS_TIMER +TIM15: HAPTIC_GPIO_TIMER +TIM16: +TIM17: ROTARY_ENCODER_TIMER + +USARTS +USART1: INTMODULE_USART +USART2: TELEMETRY_USART +USART3: DGONE +USART4: BT MODULE +USART6: EXTMODULE_USART +*/ + +#ifndef _HAL_H_ +#define _HAL_H_ + +#define CPU_FREQ 480000000 + +#define PERI1_FREQUENCY 120000000 +#define PERI2_FREQUENCY 120000000 +#define TIMER_MULT_APB1 2 +#define TIMER_MULT_APB2 2 + +// Keys +#define KEYS_GPIO_REG_PAGEDN GPIOI +#define KEYS_GPIO_PIN_PAGEDN LL_GPIO_PIN_4 +#define KEYS_GPIO_REG_SYS GPIOI +#define KEYS_GPIO_PIN_SYS LL_GPIO_PIN_5 +#define KEYS_GPIO_REG_ENTER GPIOI +#define KEYS_GPIO_PIN_ENTER LL_GPIO_PIN_2 +#define KEYS_GPIO_REG_MDL GPIOE +#define KEYS_GPIO_PIN_MDL LL_GPIO_PIN_3 +#define KEYS_GPIO_REG_EXIT GPIOI +#define KEYS_GPIO_PIN_EXIT LL_GPIO_PIN_8 +#define KEYS_GPIO_REG_TELE GPIOE +#define KEYS_GPIO_PIN_TELE LL_GPIO_PIN_4 + +// Trims +#define TRIMS_GPIO_REG_LHL GPIOI +#define TRIMS_GPIO_PIN_LHL LL_GPIO_PIN_10 + +#define TRIMS_GPIO_REG_LHR GPIOI +#define TRIMS_GPIO_PIN_LHR LL_GPIO_PIN_9 + +#define TRIMS_GPIO_REG_LVD GPIOB +#define TRIMS_GPIO_PIN_LVD LL_GPIO_PIN_13 + +#define TRIMS_GPIO_REG_LVU GPIOB +#define TRIMS_GPIO_PIN_LVU LL_GPIO_PIN_14 + +#define TRIMS_GPIO_REG_RHL GPIOG +#define TRIMS_GPIO_PIN_RHL LL_GPIO_PIN_2 + +#define TRIMS_GPIO_REG_RHR GPIOG +#define TRIMS_GPIO_PIN_RHR LL_GPIO_PIN_3 + +#define TRIMS_GPIO_REG_RVD GPIOB +#define TRIMS_GPIO_PIN_RVD LL_GPIO_PIN_12 + +#define TRIMS_GPIO_REG_RVU GPIOB +#define TRIMS_GPIO_PIN_RVU LL_GPIO_PIN_15 + +// Switches +#define SWITCHES_GPIO_REG_A_H GPIOB +#define SWITCHES_GPIO_PIN_A_H LL_GPIO_PIN_0 // PB.00 +#define SWITCHES_GPIO_REG_A_L GPIOC +#define SWITCHES_GPIO_PIN_A_L LL_GPIO_PIN_4 // PC.04 +#define SWITCHES_A_INVERTED + +#define SWITCHES_GPIO_REG_B_H GPIOD +#define SWITCHES_GPIO_PIN_B_H LL_GPIO_PIN_4 // PD.04 +#define SWITCHES_GPIO_REG_B_L GPIOJ +#define SWITCHES_GPIO_PIN_B_L LL_GPIO_PIN_7 // PJ.07 +#define SWITCHES_B_INVERTED + +#define SWITCHES_GPIO_REG_C_H GPIOH +#define SWITCHES_GPIO_PIN_C_H LL_GPIO_PIN_3 // PH.03 +#define SWITCHES_GPIO_REG_C_L GPIOJ +#define SWITCHES_GPIO_PIN_C_L LL_GPIO_PIN_0 // PJ.00 +#define SWITCHES_C_INVERTED + +#define SWITCHES_GPIO_REG_D_H GPIOJ +#define SWITCHES_GPIO_PIN_D_H LL_GPIO_PIN_14 // PJ.14 +#define SWITCHES_GPIO_REG_D_L GPIOH +#define SWITCHES_GPIO_PIN_D_L LL_GPIO_PIN_15 // PH.15 +#define SWITCHES_D_INVERTED + +#define SWITCHES_GPIO_REG_E GPIOE +#define SWITCHES_GPIO_PIN_E LL_GPIO_PIN_5 // PE.05 + +#define SWITCHES_GPIO_REG_F GPIOA +#define SWITCHES_GPIO_PIN_F LL_GPIO_PIN_15 // PA.15 + +// function switches +//SW1 +#define FUNCTION_SWITCH_1 SG +#define SWITCHES_GPIO_REG_G GPIOH +#define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_11 // PH.11 +#define SWITCHES_G_CFS_IDX 0 +//SW2 +#define FUNCTION_SWITCH_2 SH +#define SWITCHES_GPIO_REG_H GPIOH +#define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_9 // PH.09 +#define SWITCHES_H_CFS_IDX 1 +//SW3 +#define FUNCTION_SWITCH_3 SI +#define SWITCHES_GPIO_REG_I GPIOH +#define SWITCHES_GPIO_PIN_I LL_GPIO_PIN_10 // PH.10 +#define SWITCHES_I_CFS_IDX 2 +//SW4 +#define FUNCTION_SWITCH_4 SJ +#define SWITCHES_GPIO_REG_J GPIOH +#define SWITCHES_GPIO_PIN_J LL_GPIO_PIN_13 // PH.123 +#define SWITCHES_J_CFS_IDX 3 +//SW5 +#define FUNCTION_SWITCH_5 SK +#define SWITCHES_GPIO_REG_K GPIOH +#define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_14 // PH.14 +#define SWITCHES_K_CFS_IDX 4 +//SW6 +#define FUNCTION_SWITCH_6 SL +#define SWITCHES_GPIO_REG_L GPIOH +#define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_12 // PH.12 +#define SWITCHES_L_CFS_IDX 5 + +// ADC +#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_0 // PA.00 ADC1_INP16 +#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_3 // PA.03 ADC12_INP15 +#define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_1 // PA.01 ADC1_INP17 +#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_2 // PA.02 ADC12_INP14 + +#define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_3 // PC.03 POT2 ADC12_INP13 +#define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_2 // PC.02 POT1 ADC123_INP12 +#define ADC_GPIO_PIN_BATT LL_GPIO_PIN_5 // PC.05 ADC12_INP8 + +#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV, ADC_GPIO_PIN_STICK_RH, ADC_GPIO_PIN_STICK_RV) +#define ADC_GPIOC_PINS (ADC_GPIO_PIN_POT1 | ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_BATT ) + +#define ADC_CHANNEL_STICK_LH LL_ADC_CHANNEL_16 +#define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_15 +#define ADC_CHANNEL_STICK_RV LL_ADC_CHANNEL_17 +#define ADC_CHANNEL_STICK_RH LL_ADC_CHANNEL_14 + +#define ADC_CHANNEL_POT1 LL_ADC_CHANNEL_13 +#define ADC_CHANNEL_POT2 LL_ADC_CHANNEL_12 +#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_8 +#define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC3 IMP17 + +#define ADC_MAIN ADC1 +#define ADC_DMA DMA2 +#define ADC_DMA_CHANNEL LL_DMAMUX1_REQ_ADC1 +#define ADC_DMA_STREAM LL_DMA_STREAM_4 +#define ADC_DMA_STREAM_IRQ DMA2_Stream4_IRQn +#define ADC_DMA_STREAM_IRQHandler DMA2_Stream4_IRQHandler +#define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_8CYCLES_5 + +#define ADC_EXT ADC3 +#define ADC_EXT_CHANNELS { ADC_CHANNEL_RTC_BAT } +#define ADC_EXT_DMA DMA2 +#define ADC_EXT_DMA_CHANNEL LL_DMAMUX1_REQ_ADC3 +#define ADC_EXT_DMA_STREAM LL_DMA_STREAM_0 +#define ADC_EXT_DMA_STREAM_IRQ DMA2_Stream0_IRQn +#define ADC_EXT_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler +#define ADC_EXT_SAMPTIME LL_ADC_SAMPLINGTIME_8CYCLES_5 + +#define ADC_VREF_PREC2 330 + +#define ADC_DIRECTION { \ +0,-1,0,-1, /* gimbals */ \ +1,1, /* pots */ \ +0,0, /* sliders */ \ +0, /* vbat */ \ +0, /* rtc_bat */ \ +0, /* SWA */ \ +0, /* SWB */ \ +0, /* SWC */ \ +0, /* SWD */ \ +0, /* SWE */ \ +0 /* SWF */ \ +} + + +// Power +#define PWR_SWITCH_GPIO GPIO_PIN(GPIOI, 3) +#define PWR_ON_GPIO GPIO_PIN(GPIOD, 3) + +// S.Port update connector +#define HAS_SPORT_UPDATE_CONNECTOR() (false) + + +// Telemetry +#define TELEMETRY_SET_INPUT 0 +#define TELEMETRY_TX_GPIO GPIO_PIN(GPIOD, 5) +#define TELEMETRY_RX_GPIO GPIO_UNDEF +#define TELEMETRY_USART USART2 +#define TELEMETRY_USART_IRQn USART2_IRQn +#define TELEMETRY_DMA DMA1 +#define TELEMETRY_DMA_Stream_TX LL_DMA_STREAM_7 +#define TELEMETRY_DMA_Channel_TX LL_DMAMUX1_REQ_USART2_TX +#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream7_IRQn +#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler +#define TELEMETRY_DMA_Stream_RX LL_DMA_STREAM_3 +#define TELEMETRY_DMA_Channel_RX LL_DMAMUX1_REQ_USART2_RX +#define TELEMETRY_USART_IRQHandler USART2_IRQHandler + +// Software IRQ (Prio 5 -> FreeRTOS compatible) +//#define USE_CUSTOM_EXTI_IRQ +#define TELEMETRY_USE_CUSTOM_EXTI +#define CUSTOM_EXTI_IRQ_NAME ETH_WKUP_IRQ +#define ETH_WKUP_IRQ_Priority 5 +#define CUSTOM_EXTI_IRQ_LINE 86 +//#define USE_EXTI15_10_IRQ +//#define CUSTOM_EXTI_IRQ_Priority 5 +#define TELEMETRY_RX_FRAME_EXTI_LINE CUSTOM_EXTI_IRQ_LINE + +// USB +#define USB_GPIO GPIOA +#define USB_GPIO_VBUS GPIO_PIN(GPIOA, 9) +#define USB_GPIO_DM GPIO_PIN(GPIOA, 11) +#define USB_GPIO_DP GPIO_PIN(GPIOA, 12) +#define USB_GPIO_AF GPIO_AF10 + +// LCD SPI1 +#define LCD_SPI_CS_GPIO GPIOG +#define LCD_SPI_CS_GPIO_PIN LL_GPIO_PIN_10 +#define LCD_SPI_GPIO GPIOB +#define LCD_SPI_SCK_GPIO_PIN LL_GPIO_PIN_3 +#define LCD_SPI_MISO_GPIO_PIN LL_GPIO_PIN_4 +#define LCD_SPI_MOSI_GPIO_PIN LL_GPIO_PIN_5 +#define LTDC_IRQ_PRIO 4 +#define DMA_SCREEN_IRQ_PRIO 6 + +#define LCD_NRST_GPIO GPIOI +#define LCD_NRST_GPIO_PIN LL_GPIO_PIN_15 + +// Backlight +#define BACKLIGHT_GPIO GPIO_PIN(GPIOA, 5) // TIM2_CH1 +#define BACKLIGHT_TIMER TIM2 +#define BACKLIGHT_TIMER_CHANNEL LL_TIM_CHANNEL_CH1 +#define BACKLIGHT_GPIO_AF GPIO_AF1 +#define BACKLIGHT_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + +// QSPI Flash +#define QSPI_CLK_GPIO GPIO_PIN(GPIOF, 10) +#define QSPI_CLK_GPIO_AF GPIO_AF9 +#define QSPI_CS_GPIO GPIO_PIN(GPIOG, 6) +#define QSPI_CS_GPIO_AF GPIO_AF10 +#define QSPI_MISO_GPIO GPIO_PIN(GPIOF, 9) +#define QSPI_MISO_GPIO_AF GPIO_AF10 +#define QSPI_MOSI_GPIO GPIO_PIN(GPIOF, 8) +#define QSPI_MOSI_GPIO_AF GPIO_AF10 +#define QSPI_WP_GPIO GPIO_PIN(GPIOF, 7) +#define QSPI_WP_GPIO_AF GPIO_AF9 +#define QSPI_HOLD_GPIO GPIO_PIN(GPIOF, 6) +#define QSPI_HOLD_GPIO_AF GPIO_AF9 +#define QSPI_FLASH_SIZE 0x1000000 + +#define SD_SDIO SDMMC1 +#define SD_SDIO_CLK_DIV(fq) (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC) / (2 * fq)) +#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) +#define STORAGE_USE_SDIO + +// Chargers (USB and wireless) +#define UCHARGER_GPIO GPIO_PIN(GPIOD, 6) + +// Audio +#define AUDIO_MUTE_GPIO GPIO_PIN(GPIOH, 4) +#define AUDIO_OUTPUT_GPIO GPIO_PIN(GPIOA, 4) +#define AUDIO_DAC DAC1 +#define AUDIO_DMA_Stream LL_DMA_STREAM_1 +#define AUDIO_DMA_Channel LL_DMAMUX1_REQ_DAC1_CH1 +#define AUDIO_TIM_IRQn TIM6_DAC_IRQn +#define AUDIO_TIM_IRQHandler TIM6_DAC_IRQHandler +#define AUDIO_DMA_Stream_IRQn DMA2_Stream1_IRQn +#define AUDIO_DMA_Stream_IRQHandler DMA2_Stream1_IRQHandler +#define AUDIO_TIMER TIM6 +#define AUDIO_DMA DMA2 + +// I2C Bus +#define I2C_B1 I2C1 +#define I2C_B1_SDA_GPIO GPIO_PIN(GPIOB, 9) +#define I2C_B1_SCL_GPIO GPIO_PIN(GPIOB, 8) +#define I2C_B1_GPIO_AF LL_GPIO_AF_4 +#define I2C_B1_CLK_RATE 400000 + +#define I2C_B2 I2C4 +#define I2C_B2_SDA_GPIO GPIO_PIN(GPIOD, 13) +#define I2C_B2_SCL_GPIO GPIO_PIN(GPIOD, 12) +#define I2C_B2_GPIO_AF LL_GPIO_AF_4 +#define I2C_B2_CLK_RATE 400000 + +// Haptic +#define HAPTIC_PWM +#define HAPTIC_GPIO GPIO_PIN(GPIOE, 6) // TIM15_CH2 +#define HAPTIC_GPIO_TIMER TIM15 +#define HAPTIC_GPIO_AF GPIO_AF4 +#define HAPTIC_TIMER_OUTPUT_ENABLE TIM_CCER_CC2E | TIM_CCER_CC2NE; +#define HAPTIC_TIMER_MODE TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE +#define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR2 + +// LED Strip +#define LED_STRIP_LENGTH 7 // 6POS + 1 common (many leds in //) +#define BLING_LED_STRIP_START 6 +#define BLING_LED_STRIP_LENGTH 1 +#define CFS_LED_STRIP_START 0 +#define CFS_LED_STRIP_LENGTH 6 +#define CFS_LEDS_PER_SWITCH 1 +#define LED_STRIP_GPIO GPIO_PIN(GPIOA, 10) // PA.00 / TIM1_CH3 +#define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1_CH3 +#define LED_STRIP_TIMER TIM1 +#define LED_STRIP_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) +#define LED_STRIP_TIMER_CHANNEL LL_TIM_CHANNEL_CH3 +#define LED_STRIP_TIMER_DMA DMA1 +#define LED_STRIP_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM1_UP +#define LED_STRIP_TIMER_DMA_STREAM LL_DMA_STREAM_0 +#define LED_STRIP_TIMER_DMA_IRQn DMA1_Stream0_IRQn +#define LED_STRIP_TIMER_DMA_IRQHandler DMA1_Stream0_IRQHandler +#define LED_STRIP_REFRESH_PERIOD 50 //ms + +#define STATUS_LEDS +#define GPIO_LED_GPIO_ON gpio_set +#define GPIO_LED_GPIO_OFF gpio_clear +#define LED_RED_GPIO GPIO_PIN(GPIOA, 8) +#define LED_GREEN_GPIO GPIO_PIN(GPIOJ, 13) +#define LED_BLUE_GPIO GPIO_PIN(GPIOG, 7) + +// Internal Module +#define INTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 1) +#define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOD, 7) +#define INTMODULE_BOOTCMD_DEFAULT 0 +#define INTMODULE_TX_GPIO GPIO_PIN(GPIOB, 6) +#define INTMODULE_RX_GPIO GPIO_PIN(GPIOB, 7) +#define INTMODULE_USART USART1 +#define INTMODULE_GPIO_AF LL_GPIO_AF_7 +#define INTMODULE_USART_IRQn USART1_IRQn +#define INTMODULE_USART_IRQHandler USART1_IRQHandler +#define INTMODULE_DMA DMA1 +#define INTMODULE_DMA_STREAM LL_DMA_STREAM_1 +#define INTMODULE_DMA_STREAM_IRQ DMA1_Stream1_IRQn +#define INTMODULE_DMA_FLAG_TC DMA_FLAG_TCIF1 +#define INTMODULE_DMA_CHANNEL LL_DMAMUX1_REQ_USART1_TX +#define INTMODULE_RX_DMA DMA1 +#define INTMODULE_RX_DMA_STREAM LL_DMA_STREAM_5 +#define INTMODULE_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART1_RX +#define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream5_IRQn +#define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler + +// External Module +#define EXTMODULE +#define EXTMODULE_PULSES +#define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOI, 0) +#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOC, 6) // TIM3_CH1 +#define EXTMODULE_RX_GPIO GPIO_PIN(GPIOC, 7) + +#define EXTMODULE_TIMER TIM3 +#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH1 +#define EXTMODULE_TIMER_IRQn TIM3_IRQn +#define EXTMODULE_TIMER_IRQHandler TIM3_IRQHandler +#define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) +#define EXTMODULE_TIMER_TX_GPIO_AF LL_GPIO_AF_2 + +//USART +#define EXTMODULE_USART USART6 +#define EXTMODULE_USART_TX_DMA DMA2 +#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_TX +#define EXTMODULE_USART_TX_DMA_STREAM LL_DMA_STREAM_6 +#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_RX +#define EXTMODULE_USART_RX_DMA_STREAM LL_DMA_STREAM_5 +#define EXTMODULE_USART_IRQHandler USART6_IRQHandler +#define EXTMODULE_USART_IRQn USART6_IRQn + +//TIMER +// TODO +#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM3_UP +#define EXTMODULE_TIMER_DMA DMA2 +#define EXTMODULE_TIMER_DMA_STREAM LL_DMA_STREAM_3 +#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream3_IRQn +#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream3_IRQHandler + +// Trainer Port +#define TRAINER_IN_GPIO GPIO_PIN(GPIOI, 6) // TIM8_CH2 +#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH2 + +#define TRAINER_OUT_GPIO GPIO_PIN(GPIOI, 7) // TIM8_CH3 +#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH3 + +#define TRAINER_TIMER TIM8 +#define TRAINER_TIMER_IRQn TIM8_CC_IRQn +#define TRAINER_TIMER_IRQHandler TIM8_CC_IRQHandler +#define TRAINER_GPIO_AF LL_GPIO_AF_3 +#define TRAINER_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) + +// Touch +#define TOUCH_I2C_BUS I2C_Bus_2 +#define TOUCH_RST_GPIO GPIO_PIN(GPIOJ, 1) // PJ.01 +#define TOUCH_INT_GPIO GPIO_PIN(GPIOD, 11) // PD.11 + +#define TOUCH_INT_EXTI_Line LL_EXTI_LINE_11 +#define TOUCH_INT_EXTI_Port LL_SYSCFG_EXTI_PORTD +#define TOUCH_INT_EXTI_SysCfgLine LL_SYSCFG_EXTI_LINE11 + +// TOUCH_INT_EXTI IRQ +#if !defined(USE_EXTI15_10_IRQ) +#define USE_EXTI15_10_IRQ +#define EXTI15_10_IRQ_Priority 9 +#endif + +//ROTARY emulation for trims as buttons +#define ROTARY_ENCODER_NAVIGATION +// Rotary Encoder +#define ROTARY_ENCODER_GPIO_A GPIOA +#define ROTARY_ENCODER_GPIO_PIN_A LL_GPIO_PIN_6 +#define ROTARY_ENCODER_GPIO_B GPIOA +#define ROTARY_ENCODER_GPIO_PIN_B LL_GPIO_PIN_7 +#define ROTARY_ENCODER_POSITION() (((ROTARY_ENCODER_GPIO_A->IDR >> 6) & 0x01)|((ROTARY_ENCODER_GPIO_B->IDR >> 6) & 0x02)) +#define ROTARY_ENCODER_EXTI_LINE1 LL_EXTI_LINE_6 +#define ROTARY_ENCODER_EXTI_LINE2 LL_EXTI_LINE_7 +#if !defined(USE_EXTI9_5_IRQ) + #define USE_EXTI9_5_IRQ + #define EXTI9_5_IRQ_Priority 9 +#endif +#define ROTARY_ENCODER_EXTI_PORT_A LL_SYSCFG_EXTI_PORTA +#define ROTARY_ENCODER_EXTI_PORT_B LL_SYSCFG_EXTI_PORTA +#define ROTARY_ENCODER_EXTI_SYS_LINE1 LL_SYSCFG_EXTI_LINE6 +#define ROTARY_ENCODER_EXTI_SYS_LINE2 LL_SYSCFG_EXTI_LINE7 +#define ROTARY_ENCODER_TIMER TIM17 +#define ROTARY_ENCODER_TIMER_IRQn TIM17_IRQn +#define ROTARY_ENCODER_TIMER_IRQHandler TIM17_IRQHandler + +// Millisecond timer +#define MS_TIMER TIM14 +#define MS_TIMER_IRQn TIM8_TRG_COM_TIM14_IRQn +#define MS_TIMER_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler + +// Mixer scheduler timer +#define MIXER_SCHEDULER_TIMER TIM12 +#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) +#define MIXER_SCHEDULER_TIMER_IRQn TIM8_BRK_TIM12_IRQn +#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_BRK_TIM12_IRQHandler + +#define LANDSCAPE_LCD true +#define PORTRAIT_LCD false +#define LANDSCAPE_LCD_SML false +#define LANDSCAPE_LCD_STD true +#define LANDSCAPE_LCD_LRG false + +#define LCD_W 480 +#define LCD_H 320 + +#define LCD_PHYS_W LCD_W +#define LCD_PHYS_H LCD_H + +#define LCD_DEPTH 16 + +#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH + +#endif // _HAL_H_ diff --git a/radio/src/targets/t15pro/usb_descriptor.h b/radio/src/targets/t15pro/usb_descriptor.h new file mode 100644 index 000000000..c5998f008 --- /dev/null +++ b/radio/src/targets/t15pro/usb_descriptor.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#define USB_NAME "T15PRO" +#define USB_MANUFACTURER 'J', 'U', 'M', 'P', 'E', 'R', ' ', ' ' /* 8 bytes */ +#define USB_PRODUCT 'T', '1', '5', ' ', 'P', 'R', 'O', ' ' /* 8 Bytes */ diff --git a/radio/util/hw_defs/legacy_names.py b/radio/util/hw_defs/legacy_names.py index d9ee464da..d0101f382 100644 --- a/radio/util/hw_defs/legacy_names.py +++ b/radio/util/hw_defs/legacy_names.py @@ -90,7 +90,7 @@ LEGACY_NAMES = [ } }, { - "targets": {"t15", "tx15"}, + "targets": {"t15", "t15pro", "tx15"}, "inputs": { "LH": { "yaml": "Rud", diff --git a/radio/util/hw_defs/pot_config.py b/radio/util/hw_defs/pot_config.py index 174a9f7cf..8f5dcbfcd 100644 --- a/radio/util/hw_defs/pot_config.py +++ b/radio/util/hw_defs/pot_config.py @@ -146,6 +146,10 @@ POT_CONFIG = { "P1": {"default": "POT"}, "P2": {"default": "POT"}, }, + "t15pro": { + "P1": {"default": "POT_CENTER"}, + "P2": {"default": "POT_CENTER"}, + }, "tx16s": { "P1": {"default": "POT_CENTER"}, "P2": {"default": "MULTIPOS"}, diff --git a/radio/util/hw_defs/switch_config.py b/radio/util/hw_defs/switch_config.py index f12011f91..2c3c514fa 100644 --- a/radio/util/hw_defs/switch_config.py +++ b/radio/util/hw_defs/switch_config.py @@ -382,6 +382,21 @@ SWITCH_CONFIG = { "SF": {"default": "3POS", "display": [1, 2]}, "SH": {"default": "NONE", "display": [1, 3]} }, + "t15pro": { + "SA": {"default": "3POS"}, + "SB": {"default": "3POS"}, + "SC": {"default": "3POS"}, + "SD": {"default": "3POS"}, + "SE": {"default": "2POS"}, + "SF": {"default": "2POS"}, + # custom switches + "SG": {"default": "2POS"}, + "SH": {"default": "2POS"}, + "SI": {"default": "2POS"}, + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + }, "tx15": { "SA": {"default": "3POS"}, "SB": {"default": "3POS"}, diff --git a/tools/build-common.sh b/tools/build-common.sh index 40d2d088e..d5616dd21 100644 --- a/tools/build-common.sh +++ b/tools/build-common.sh @@ -116,6 +116,9 @@ get_target_build_options() { t18) BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T18" ;; + t15pro) + BUILD_OPTIONS+="-DPCB=T15PRO" + ;; tx15) BUILD_OPTIONS+="-DPCB=TX15 -DNANO=NO" ;; diff --git a/tools/build-companion.sh b/tools/build-companion.sh index 10bb1892d..938978aa8 100755 --- a/tools/build-companion.sh +++ b/tools/build-companion.sh @@ -55,7 +55,7 @@ rm -rf build && mkdir build && cd build output_error_log() { local log_file="$1" local context="$2" - + if [[ -f "$log_file" ]]; then echo "------------------------------------------" echo " Full error output from $log_file:" @@ -66,12 +66,12 @@ output_error_log() { fi } -# Function to show last N lines of a log file for warnings +# Function to show last N lines of a log file for warnings show_log_summary() { local log_file="$1" local lines="${2:-50}" local context="$3" - + if [[ -f "$log_file" ]]; then echo "------------------------------------------" echo "Last $lines lines from $log_file:" @@ -86,7 +86,7 @@ run_pipeline() { local context="$3" local show_details="${4:-false}" local cmake_opts="--parallel ${MAX_JOBS} ${QUIET_FLAGS}" - + case "$pipeline_type" in "plugin") clean_build @@ -118,20 +118,20 @@ run_pipeline() { fi ;; esac - + return 0 } execute_with_output() { local description="$1" - local command="$2" + local command="$2" local log_file="$3" local show_output="${4:-false}" - + if [[ "$show_output" == "true" && "$log_file" != "/dev/null" ]]; then - echo " $description..." + echo " $description..." fi - + eval "$command" >> "$log_file" 2>&1 } @@ -144,14 +144,14 @@ get_platform_config() { case "$platform" in "Darwin") PACKAGE_TARGET="package" - PACKAGE_FILES="*.dmg" + PACKAGE_FILES="*.dmg" PACKAGE_NAME="macOS DMG" PACKAGE_EMOJI="🍎" ;; "Linux") PACKAGE_TARGET="package" PACKAGE_FILES="*.AppImage" - PACKAGE_NAME="Linux AppImage" + PACKAGE_NAME="Linux AppImage" PACKAGE_EMOJI="🐧" ;; *) @@ -168,9 +168,9 @@ build_plugin() { local plugin="$1" local log_file="build_${plugin}.log" local verbose="${2:-false}" - + BUILD_OPTIONS="${COMMON_OPTIONS} " - + if ! get_target_build_options "$plugin" >> "$log_file" 2>&1; then if [[ -n "$GITHUB_ACTIONS" ]]; then echo "::error::Failed to get build options for $plugin" @@ -178,17 +178,17 @@ build_plugin() { output_error_log "$log_file" "$plugin (Build Options)" return 1 fi - + # Only show detailed output in GitHub Actions or if verbose is requested local show_details="false" if [[ -n "$GITHUB_ACTIONS" || "$verbose" == "true" ]]; then show_details="true" fi - + if ! run_pipeline "plugin" "$log_file" "$plugin" "$show_details"; then return 1 fi - + # Check for warnings and show summary if found if grep -q -i "warning" "$log_file"; then echo " ⚠️ $plugin completed with warnings" @@ -205,7 +205,7 @@ build_plugin() { declare -a simulator_plugins=( x9lite x9lites x9d x9dp x9dp2019 x9e x7 x7access - t8 t12 t12max tx12 tx12mk2 t15 t16 t18 t20 t20v2 + t8 t12 t12max tx12 tx12mk2 t15 t15pro t16 t18 t20 t20v2 xlite xlites x10 x10express x12s zorro tx16s tx15 @@ -233,7 +233,7 @@ for i in "${!simulator_plugins[@]}"; do echo "🔨 [$current/$TOTAL] ($percent%) Building $plugin..." fi - error_status=0 + error_status=0 if ! build_plugin "$plugin"; then FAILED_PLUGINS+=("$plugin") error_status=1 @@ -257,12 +257,12 @@ if [ ${#FAILED_PLUGINS[@]} -gt 0 ]; then echo "❌ Build Failures Summary" echo "==========================================" fi - + echo "The following plugins failed to build:" for failed_plugin in "${FAILED_PLUGINS[@]}"; do echo " ❌ $failed_plugin" done - + if [[ -n "$GITHUB_ACTIONS" ]]; then echo "::endgroup::" else @@ -287,7 +287,7 @@ if run_pipeline "final" "final.log" "companion" "true"; then echo " ❌ Failed to copy package files to output directory" echo " 📁 Directory Contents:" echo " ----------------------" - + echo "Contents of native/ directory:" ls -la native/ || echo "native/ directory not found" echo "Looking for files matching: $PACKAGE_FILES" diff --git a/tools/generate-hw-defs.sh b/tools/generate-hw-defs.sh index 9fc027acf..811c97454 100755 --- a/tools/generate-hw-defs.sh +++ b/tools/generate-hw-defs.sh @@ -9,7 +9,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" : "${SRCDIR:=$(dirname "$(pwd)/$0")/..}" -: ${FLAVOR:="nv14;el18;pl18;pl18ev;nb4p;st16;t12;t12max;t15;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v14;v12;tx15"} +: ${FLAVOR:="nv14;el18;pl18;pl18ev;nb4p;st16;t12;t12max;t15;t15pro;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v14;v12;tx15"} : ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -Wno-dev -DCMAKE_MESSAGE_LOG_LEVEL=WARNING"} # wipe build directory clean diff --git a/tools/generate-yaml.sh b/tools/generate-yaml.sh index f9ddbb72d..bc37f1af9 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;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;pa01;tx15"} +: ${FLAVOR:="t15;tx16s;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;pa01;tx15;t15pro"} : ${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"} diff --git a/tools/msys2_fetch_and_build_all.sh b/tools/msys2_fetch_and_build_all.sh index e11d2c1e0..576d5d551 100644 --- a/tools/msys2_fetch_and_build_all.sh +++ b/tools/msys2_fetch_and_build_all.sh @@ -9,7 +9,7 @@ # ----------------------------------------------------------------------------- export BRANCH_NAME="main" # main|2.9|... -export RADIO_TYPE="tx16s" # tx16s|x10|x10express|x12s|x9d|x9dp|x9lite|x9lites|x7|x7access|t12|t12max|tx12|tx12mk2|mt12|gx12|boxer|t8|zorro|pocket|tlite|tpro|t20|t20v2|t14|lr3pro|xlite|xlites|x9dp2019|x9e|x9e-hall|t15|t16|t18|nv14|commando8|tx15 +export RADIO_TYPE="tx16s" # tx16s|x10|x10express|x12s|x9d|x9dp|x9lite|x9lites|x7|x7access|t12|t12max|tx12|tx12mk2|mt12|gx12|boxer|t8|zorro|pocket|tlite|tpro|t20|t20v2|t14|lr3pro|xlite|xlites|x9dp2019|x9e|x9e-hall|t15|t15pro|t16|t18|nv14|commando8|tx15 export BUILD_OPTIONS="-DDEFAULT_MODE=2 -DGVARS=YES" @@ -108,6 +108,9 @@ case $RADIO_TYPE in t15) BUILD_OPTIONS+=" -DPCB=X10 -DPCBREV=T15 -DINTERNAL_MODULE_CRSF=ON" ;; + t15pro) + BUILD_OPTIONS+=" -DPCB=T15PRO -DINTERNAL_MODULE_CRSF=ON" + ;; t16) BUILD_OPTIONS+=" -DPCB=X10 -DPCBREV=T16 -DINTERNAL_MODULE_MULTI=ON" ;;