feat: Flysky PA01 support (#6392)

Co-authored-by: Malte Langermann <malte@langermann.net>
Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
Co-authored-by: 3djc <3djc@gh.com>
Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com>
Co-authored-by: xlong <984929678@qq.com>
Co-authored-by: Peter Feerick <pfeerick@users.noreply.github.com>
This commit is contained in:
richardclli
2025-08-17 20:13:43 +10:00
committed by GitHub
co-authored by Malte Langermann philmoz 3djc raphaelcoeffic xlong Peter Feerick
parent 89e57df285
commit e89a4414ac
45 changed files with 5067 additions and 17 deletions
+1
View File
@@ -92,6 +92,7 @@ jobs:
target:
- nv14;el18
- pl18;pl18ev;pl18u
- pa01
- t12max
- t15;t16;t18
- zorro;pocket;mt12;commando8
+1
View File
@@ -18,6 +18,7 @@ jobs:
target:
- nv14;el18
- pl18;pl18ev;pl18u
- pa01
- t12max
- t15;t16;t18
- zorro;pocket;mt12;commando8
+15 -5
View File
@@ -152,6 +152,8 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_FLYSKY_PL18EV:
case BOARD_FLYSKY_PL18U:
return 0x4878746F;
case BOARD_FLYSKY_PA01:
return 0x4A78746F;
case BOARD_FLYSKY_ST16:
return 0x4C78746F;
case BOARD_HELLORADIOSKY_V14:
@@ -210,6 +212,7 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_RADIOMASTER_TX16S:
case BOARD_FLYSKY_NV14:
case BOARD_FLYSKY_EL18:
case BOARD_FLYSKY_PA01:
case BOARD_FLYSKY_PL18:
case BOARD_FLYSKY_PL18EV:
case BOARD_FLYSKY_PL18U:
@@ -268,10 +271,11 @@ int Boards::getFlashSize(Type board)
case BOARD_RADIOMASTER_TX16S:
case BOARD_FLYSKY_NV14:
case BOARD_FLYSKY_EL18:
case BOARD_FLYSKY_PA01: // 8MB SDRAM
case BOARD_FLYSKY_PL18:
case BOARD_FLYSKY_PL18EV:
case BOARD_FLYSKY_PL18U:
case BOARD_FLYSKY_ST16:
case BOARD_FLYSKY_ST16: // 8MB SDRAM
case BOARD_FATFISH_F16:
case BOARD_HELLORADIOSKY_V16:
return FSIZE_2MB;
@@ -378,13 +382,15 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return 480;
else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_FLYSKY_ST16(board))
return 320;
else if (IS_FLYSKY_PA01(board))
return 240;
else if (IS_FAMILY_HORUS_OR_T16(board))
return 272;
else
return 64;
case LcdWidth:
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board))
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PA01(board))
return 320;
else if (IS_FAMILY_PL18(board) || IS_FLYSKY_ST16(board))
return 480;
@@ -412,7 +418,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return IS_RADIOMASTER_MT12(board);
case FunctionSwitchColors:
return IS_RADIOMASTER_GX12(board) || IS_FLYSKY_ST16(board);
return IS_RADIOMASTER_GX12(board) || IS_FLYSKY_ST16(board) || IS_FLYSKY_PA01(board);
default:
return getBoardJson(board)->getCapability(capability);
@@ -650,6 +656,8 @@ QString Boards::getBoardName(Board::Type board)
return "FlySky NV14";
case BOARD_FLYSKY_EL18:
return "FlySky EL18";
case BOARD_FLYSKY_PA01:
return "FlySky PA01";
case BOARD_FLYSKY_PL18:
return "FlySky PL18";
case BOARD_FLYSKY_PL18EV:
@@ -768,7 +776,6 @@ int Boards::getDefaultInternalModules(Board::Type board)
case BOARD_JUMPER_TPROV2:
case BOARD_FLYSKY_PL18:
case BOARD_FLYSKY_PL18EV:
case BOARD_FLYSKY_ST16:
return (int)MODULE_TYPE_MULTIMODULE;
case BOARD_BETAFPV_LR3PRO:
@@ -796,6 +803,8 @@ int Boards::getDefaultInternalModules(Board::Type board)
case BOARD_FLYSKY_EL18:
case BOARD_FLYSKY_PL18U:
case BOARD_FLYSKY_PA01: // ANT
case BOARD_FLYSKY_ST16: // ANT
return (int)MODULE_TYPE_FLYSKY_AFHDS3;
default:
@@ -861,7 +870,8 @@ void Boards::getBattRange(Board::Type board, int& vmin, int& vmax, unsigned int&
BR(35, 43, 37)
break;
case BOARD_FLYSKY_ST16:
BR(70, 86,80)
case BOARD_FLYSKY_PA01:
BR(70, 86, 80)
break;
case BOARD_IFLIGHT_COMMANDO8:
BR(30, 42, 32)
+7 -1
View File
@@ -74,6 +74,7 @@ namespace Board {
BOARD_JUMPER_TLITE,
BOARD_JUMPER_TLITE_F4,
BOARD_FLYSKY_NV14,
BOARD_FLYSKY_PA01,
BOARD_FLYSKY_PL18,
BOARD_FLYSKY_PL18EV,
BOARD_FLYSKY_PL18U,
@@ -661,6 +662,11 @@ inline bool IS_FLYSKY_EL18(Board::Type board)
return (board == Board::BOARD_FLYSKY_EL18);
}
inline bool IS_FLYSKY_PA01(Board::Type board)
{
return (board == Board::BOARD_FLYSKY_PA01);
}
inline bool IS_FLYSKY_PL18(Board::Type board)
{
return (board == Board::BOARD_FLYSKY_PL18);
@@ -765,7 +771,7 @@ inline bool IS_FAMILY_HORUS_OR_T16(Board::Type board)
{
return IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board) ||
IS_FLYSKY_NV14(board)/*generally*/ || IS_FLYSKY_EL18(board)/*generally*/
|| IS_FAMILY_PL18(board) || IS_FLYSKY_ST16(board)/*generally*/;
|| IS_FAMILY_PL18(board) || IS_FLYSKY_ST16(board)/*generally*/ || IS_FLYSKY_PA01(board)/*generally*/;
}
inline bool IS_HORUS_OR_TARANIS(Board::Type board)
@@ -496,6 +496,12 @@ void registerOpenTxFirmwares()
addOpenTxRfOptions(firmware, FLEX + AFHDS2A + AFHDS3);
registerOpenTxFirmware(firmware);
/* FlySky PA01 board */
firmware = new OpenTxFirmware(FIRMWAREID("pa01"), Firmware::tr("FlySky PA01"), BOARD_FLYSKY_PA01);
addOpenTxFrskyOptions(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
registerOpenTxFirmware(firmware);
/* FlySky PL18 board */
firmware = new OpenTxFirmware(FIRMWAREID("pl18"), Firmware::tr("FlySky PL18"), BOARD_FLYSKY_PL18);
addOpenTxFrskyOptions(firmware);
+1
View File
@@ -3,6 +3,7 @@
["Fatfish F16","f16-"],
["Flysky EL18", "el18-"],
["Flysky NV14", "nv14-"],
["Flysky PA01", "pa01-"],
["Flysky PL18", "pl18-"],
["Flysky PL18EV", "pl18ev-"],
["Flysky PL18U", "pl18u-"],
+3 -1
View File
@@ -1,7 +1,7 @@
include(CMakeForceCompiler)
include(Bitmaps)
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 ST16)
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 ST16 PA01)
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)
@@ -88,6 +88,8 @@ elseif(PCB STREQUAL PL18)
include(targets/pl18/CMakeLists.txt)
elseif(PCB STREQUAL ST16)
include(targets/st16/CMakeLists.txt)
elseif(PCB STREQUAL PA01)
include(targets/pa01/CMakeLists.txt)
elseif(PCB STREQUAL STM32H7S78_DK)
include(targets/stm32h7s78-dk/CMakeLists.txt)
elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES)
@@ -393,15 +393,19 @@ static void _internal_module_set_pwr(uint8_t enable)
}
}
#if defined(INTMODULE_BOOTCMD_GPIO)
#if defined(INTMODULE_BOOTCMD_GPIO) || defined(INTMODULE_BOOTCMD_BSP)
static void _internal_module_set_bootcmd(uint8_t enable)
{
#if defined(INTMODULE_BOOTCMD_BSP)
INTERNAL_MODULE_BOOTCMD(enable);
#else
// If default state is SET, invert the logic
if (INTMODULE_BOOTCMD_DEFAULT) {
enable = !enable;
}
gpio_write(INTMODULE_BOOTCMD_GPIO, enable);
#endif
}
#endif
@@ -437,7 +441,7 @@ static const etx_module_port_t _internal_ports[] = {
static const etx_module_t _internal_module = {
.ports = _internal_ports,
.set_pwr = _internal_module_set_pwr,
#if defined(INTMODULE_BOOTCMD_GPIO)
#if defined(INTMODULE_BOOTCMD_GPIO) || defined(INTMODULE_BOOTCMD_BSP)
.set_bootcmd = _internal_module_set_bootcmd,
#else
.set_bootcmd = nullptr,
@@ -24,6 +24,7 @@
#include "stm32_gpio_driver.h"
#include "drivers/pca95xx.h"
#include "drivers/aw9523b.h"
#include "definitions.h"
#include "myeeprom.h"
+5 -3
View File
@@ -75,6 +75,8 @@ static inline void check_struct()
CHKSIZE(CustomScreenData, 1972);
#if defined(PCBNV14) || defined(RADIO_NB4P) || defined(RADIO_NV14_FAMILY)
CHKTYPE(TopBarPersistentData, 736);
#elif defined(PCBPA01)
CHKTYPE(TopBarPersistentData, 916);
#elif defined(RADIO_H7RS)
// TODO
#else
@@ -86,14 +88,12 @@ static inline void check_struct()
#if defined(PCBXLITES)
CHKSIZE(RadioData, 945);
#elif defined(RADIO_ST16)
#elif defined(RADIO_ST16) || defined(PCBPA01)
CHKSIZE(RadioData, 1159);
#elif defined(COLORLCD)
CHKSIZE(RadioData, 1039);
#elif defined(RADIO_GX12)
CHKSIZE(RadioData, 1063);
#elif defined(RADIO_GX12)
CHKSIZE(RadioData, 1062);
#else
CHKSIZE(RadioData, 943);
#endif
@@ -122,6 +122,8 @@ static inline void check_struct()
CHKSIZE(ModelData, 27295);
#elif defined(PCBST16)
CHKSIZE(ModelData, 27761);
#elif defined(PCBPA01)
CHKSIZE(ModelData, 27522);
#elif defined(RADIO_T15)
CHKSIZE(ModelData, 27683);
#elif defined(RADIO_H7RS)
+124
View File
@@ -0,0 +1,124 @@
/*
* 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 "aw9523b.h"
#define REG_INPUT 0x00
#define REG_OUTPUT 0x02
#define REG_DIRECTION 0x04
#define REG_INTERRUPT 0x06
#define REG_CONTROL 0x11
#define REG_LED_MODE 0x12
#define CTL_P0_DRIVE_MODE_OD 0
#define CTL_P0_DRIVE_MODE_PP (1<<4)
static int aw9523b_i2c_write16(aw9523b_t* dev, uint16_t reg, uint16_t value)
{
if (!dev->addr) return -1;
uint8_t val8 = value&0xFF;
if (i2c_write(dev->bus, dev->addr, reg, 1, (uint8_t*)&val8, 1) < 0) {
return -1;
}
val8 = (value>>8)&0xFF;
if (i2c_write(dev->bus, dev->addr, reg+1, 1, (uint8_t*)&val8, 1) < 0) {
return -1;
}
return 0;
}
int aw9523b_init(aw9523b_t* dev, etx_i2c_bus_t bus, uint16_t addr)
{
dev->bus = 0;
dev->addr = 0;
//dev->interrupt = 0;
dev->direction = 0xFFFF;
dev->output = 0;
if (i2c_init(bus) < 0) {
return -1;
}
if (i2c_dev_ready(bus, addr) < 0) {
return -1;
}
dev->bus = bus;
dev->addr = addr;
volatile uint8_t test = 0;
uint8_t tmp = CTL_P0_DRIVE_MODE_PP;
i2c_read(dev->bus, dev->addr, REG_CONTROL, 1, (uint8_t*)&test, 1);
i2c_write(dev->bus, dev->addr, REG_CONTROL, 1, (uint8_t*)&tmp, 1);
i2c_read(dev->bus, dev->addr, REG_CONTROL, 1, (uint8_t*)&test, 1);
aw9523b_i2c_write16(dev, REG_LED_MODE, 0xFFFF); // set all pins to GPIO mode not LED mode
aw9523b_i2c_write16(dev, REG_INTERRUPT, 0); // enable interrupts for all pins
return 0;
}
int aw9523b_set_direction(aw9523b_t* dev, uint16_t mask, uint16_t dir)
{
uint16_t tmp = dev->direction;
tmp &= ~mask;
tmp |= dir & mask;
if (aw9523b_i2c_write16(dev, REG_DIRECTION, tmp) < 0) {
return -1;
}
dev->direction = tmp;
return 0;
}
int aw9523b_write(aw9523b_t* dev, uint16_t mask, uint16_t value)
{
uint16_t tmp = dev->output;
tmp &= ~mask;
tmp |= value & mask;
if (aw9523b_i2c_write16(dev, REG_OUTPUT, tmp) < 0) {
return -1;
}
dev->output = tmp;
return 0;
}
int aw9523b_read(aw9523b_t* dev, uint16_t mask, uint16_t* value)
{
if (!dev->addr) return -1;
uint16_t tmp;
uint8_t tmp8;
if (i2c_read(dev->bus, dev->addr, REG_INPUT, 1, (uint8_t*)&tmp8, 1) < 0) {
return -1;
}
tmp = tmp8;
if (i2c_read(dev->bus, dev->addr, REG_INPUT+1, 1, (uint8_t*)&tmp8, 1) < 0) {
return -1;
}
tmp |= ((uint16_t)tmp)<<8;
*value = tmp & mask;
return 0;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) EdgeTx
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include "hal/i2c_driver.h"
#define AW9523B_PIN_0 (1 << 0)
#define AW9523B_PIN_1 (1 << 1)
#define AW9523B_PIN_2 (1 << 2)
#define AW9523B_PIN_3 (1 << 3)
#define AW9523B_PIN_4 (1 << 4)
#define AW9523B_PIN_5 (1 << 5)
#define AW9523B_PIN_6 (1 << 6)
#define AW9523B_PIN_7 (1 << 7)
#define AW9523B_PIN_8 (1 << 8)
#define AW9523B_PIN_9 (1 << 9)
#define AW9523B_PIN_10 (1 << 10)
#define AW9523B_PIN_11 (1 << 11)
#define AW9523B_PIN_12 (1 << 12)
#define AW9523B_PIN_13 (1 << 13)
#define AW9523B_PIN_14 (1 << 14)
#define AW9523B_PIN_15 (1 << 15)
typedef struct {
etx_i2c_bus_t bus;
uint16_t addr;
// uint16_t interrupt; // unused, the direction config is used to enable interrupts for all input pins
uint16_t direction;
uint16_t output;
} aw9523b_t;
int aw9523b_init(aw9523b_t* dev, etx_i2c_bus_t bus, uint16_t addr);
int aw9523b_set_direction(aw9523b_t* dev, uint16_t mask, uint16_t dir);
int aw9523b_set_polarity(aw9523b_t* dev, uint16_t mask, uint16_t dir);
int aw9523b_write(aw9523b_t* dev, uint16_t mask, uint16_t value);
int aw9523b_read(aw9523b_t* dev, uint16_t mask, uint16_t* value);
+1
View File
@@ -20,3 +20,4 @@ set(LVGL_FONT_SOURCES_MINIMAL
fonts/lvgl/${FONT_DIR}/lv_font_bl.c
PARENT_SCOPE
)
@@ -25,10 +25,7 @@
#include "etx_lv_theme.h"
#include "view_main.h"
#include "topbar_impl.h"
#if defined(HARDWARE_TOUCH)
#include "keyboard_base.h"
#endif
#if defined(DEBUG)
static uint32_t dsms, dems, end_ms, start_ms;
+2
View File
@@ -36,6 +36,8 @@ elseif(PCB STREQUAL PL18)
endif()
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 X7)
if(PCBREV STREQUAL TPRO)
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp)
@@ -50,6 +50,8 @@
#include "yaml_datastructs_nv14.cpp"
#elif defined(PCBST16)
#include "yaml_datastructs_st16.cpp"
#elif defined(PCBPA01)
#include "yaml_datastructs_pa01.cpp"
#elif defined(PCBX7)
#if defined(RADIO_TPRO) || defined(RADIO_TPROV2) || defined(RADIO_BUMBLEBEE)
#include "yaml_datastructs_tpro.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, 6, 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, 5, 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", 352, 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", 7328, struct_TopBarPersistentData, NULL),
YAML_ARRAY("topbarWidgetWidth", 8, 5, 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, 4, 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;
}
+188
View File
@@ -0,0 +1,188 @@
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 12000000)
set(SDCARD YES)
set(STORAGE_MODELSLIST YES)
set(HAPTIC YES)
set(GUI_DIR colorlcd)
set(BITMAPS_DIR 320x240)
set(TARGET_DIR pa01)
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 YES)
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 0xC0000000)
set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192")
set(FIRMWARE_STRIP_BOOTLOADER YES)
add_definitions(-DPCBPA01 -DPCBHORUS -DPCBFLYSKY)
add_definitions(-DBATTERY_CHARGE)
add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS)
add_definitions(-DFIRMWARE_QSPI)
add_definitions(-DFIRMWARE_FORMAT_UF2)
add_definitions(-DUSE_CUSTOM_EXTI_IRQ)
set(FLAVOUR pa01)
add_definitions(-DRADIO_PA01)
# Defines internal modules for PL18 via UART7
set(INTERNAL_MODULES AFHDS3;CRSF CACHE STRING "Internal modules")
set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module")
set(BITMAPS_TARGET bm320_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 ON)
set(FUNCTION_SWITCHES ON)
add_definitions(
-DSTM32H750ZBTx -DSTM32H750xx
-DSDRAM -DCCMRAM
-DCOLORLCD -DLIBOPENUI
-DHARDWARE_KEYS -DSOFTWARE_KEYBOARD
-DWS2812_MAX_LEDS=24
)
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(TARGET_SRC_DIR targets/${TARGET_DIR})
set(BOARD_COMMON_SRC
${TARGET_SRC_DIR}/board.cpp
${TARGET_SRC_DIR}/bsp_io.cpp
${TARGET_SRC_DIR}/key_driver.cpp
${TARGET_SRC_DIR}/lcd_driver.cpp
${TARGET_SRC_DIR}/backlight_driver.cpp
${TARGET_SRC_DIR}/haptic_driver.cpp
${TARGET_SRC_DIR}/extflash_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/aw9523b.cpp
)
# Bootloader board library
add_library(board_bl OBJECT EXCLUDE_FROM_ALL
${BOARD_COMMON_SRC}
${TARGET_SRC_DIR}/system_clock.c
${TARGET_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} $<TARGET_OBJECTS:board_bl>)
# Firmware board library
add_library(board OBJECT EXCLUDE_FROM_ALL
${BOARD_COMMON_SRC}
${TARGET_SRC_DIR}/led_driver.cpp
${TARGET_SRC_DIR}/battery_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} $<TARGET_OBJECTS:board>)
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)
@@ -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"
#include "lcd_driver.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 = 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 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, 0);
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);
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;
}
+677
View File
@@ -0,0 +1,677 @@
/*
* 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 "edgetx.h"
#include "battery_driver.h"
#include "boards/generic_stm32/rgb_leds.h"
#include "bsp_io.h"
#include "stm32_ws2812.h"
#define __BATTERY_DRIVER_C__
#define BATTERY_W 140
#define BATTERY_H (LCD_H - 120)
#define BATTERY_TOP ((LCD_H - BATTERY_H)/2)
#define BATTERY_CONNECTOR_W 32
#define BATTERY_CONNECTOR_H 10
#define BATTERY_BORDER 4
#define BATTERY_W_INNER (BATTERY_W - 2*BATTERY_BORDER)
#define BATTERY_H_INNER (BATTERY_H - 2*BATTERY_BORDER)
#define BATTERY_TOP_INNER (BATTERY_TOP + BATTERY_BORDER)
#define UCHARGER_SAMPLING_CNT 10
#define UCHARGER_CHARGING_SAMPLING_CNT 10
typedef struct
{
bool hasCharger : 1;
bool isChargeEnd : 1;
bool isChargerDetectionReady : 1;
bool isChargingDetectionReady : 1;
bool isHighCurrent : 1;
uint8_t chargerSamplingCount;
uint8_t chargingSamplingCount;
uint8_t chargeEndSamplingCount;
} STRUCT_BATTERY_CHARGER;
STRUCT_BATTERY_CHARGER uCharger; // USB charger
void chargerDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargerPinActive, uint8_t samplingCountThreshold)
{
if ((charger->hasCharger && chargerPinActive) || (!charger->hasCharger && !chargerPinActive))
{
charger->chargerSamplingCount = 0;
}
else
{
charger->chargerSamplingCount++;
if (charger->chargerSamplingCount >= samplingCountThreshold)
{
charger->chargerSamplingCount = 0;
charger->hasCharger = !charger->hasCharger;
charger->isChargerDetectionReady = true;
}
}
}
void resetChargeEndDetection(STRUCT_BATTERY_CHARGER* charger)
{
charger->isChargeEnd = false;
charger->isChargingDetectionReady = false;
charger->chargingSamplingCount = 0;
charger->isHighCurrent = false;
}
void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinActive, uint8_t samplingCountThreshold)
{
if (charger->isChargeEnd)
{
if (chargeEndPinActive)
{
charger->chargingSamplingCount = 0;
if (charger->isChargingDetectionReady)
{
charger->chargeEndSamplingCount = 0;
}
else
{
charger->chargeEndSamplingCount++;
if (charger->chargeEndSamplingCount >= samplingCountThreshold)
{
charger->chargeEndSamplingCount = 0;
charger->isChargingDetectionReady = true;
}
}
}
else
{
charger->chargeEndSamplingCount = 0;
charger->chargingSamplingCount++;
if (charger->chargingSamplingCount >= samplingCountThreshold)
{
charger->chargingSamplingCount = 0;
charger->isChargeEnd = false;
charger->isChargingDetectionReady = true;
}
}
}
else
{
if (!chargeEndPinActive)
{
charger->chargeEndSamplingCount = 0;
if (charger->isChargingDetectionReady)
{
charger->chargingSamplingCount = 0;
}
else
{
charger->chargingSamplingCount++;
if (charger->chargingSamplingCount >= samplingCountThreshold)
{
charger->chargingSamplingCount = 0;
charger->isChargingDetectionReady = true;
}
}
}
else
{
charger->chargingSamplingCount = 0;
charger->chargeEndSamplingCount++;
if (charger->chargeEndSamplingCount >= samplingCountThreshold)
{
charger->chargeEndSamplingCount = 0;
charger->isChargeEnd = true;
charger->isChargingDetectionReady = true;
}
}
}
}
uint16_t get_battery_charge_state()
{
uint16_t state = CHARGE_UNKNOWN;
chargerDetection(&uCharger, IS_UCHARGER_ACTIVE(), UCHARGER_SAMPLING_CNT);
if (uCharger.isChargerDetectionReady)
{
if (uCharger.hasCharger) // USB charger can be detected properly no matter it is enabled or not
{
ENABLE_UCHARGER();
chargeEndDetection(&uCharger, IS_UCHARGER_CHARGE_END_ACTIVE(), UCHARGER_CHARGING_SAMPLING_CNT);
if (uCharger.isChargingDetectionReady)
{
if (uCharger.isChargeEnd)
{
state = CHARGE_FINISHED;
}
else
{
state = CHARGE_STARTED;
}
}
}
else
{
resetChargeEndDetection(&uCharger);
// Disable USB charger if it is not present, so that wireless charger can be detected properly
DISABLE_UCHARGER();
}
}
return state;
}
bool isChargerActive()
{
if (uCharger.isChargerDetectionReady) {
// Detect the removal of the charger.
get_battery_charge_state();
} else {
while (!uCharger.isChargerDetectionReady)
{
get_battery_charge_state();
delay_ms(10);
}
}
return uCharger.hasCharger;
}
void battery_charge_init()
{
// USB charger status pins
gpio_init(UCHARGER_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW);
gpio_init(UCHARGER_CHARGE_END_GPIO, GPIO_IN_PD, GPIO_PIN_SPEED_LOW);
// USB charger state init
ENABLE_UCHARGER();
uCharger.hasCharger = !IS_UCHARGER_ACTIVE(); // Init for sampling count works
uCharger.isChargerDetectionReady = false;
resetChargeEndDetection(&uCharger);
}
void ledChargingInfo(uint16_t chargeState) {
#if defined(LED_STRIP_GPIO)
static int ledIdx = LED_CHARGING_END;
if (ledIdx == LED_CHARGING_END)
ledIdx = LED_CHARGING_START;
else
ledIdx += LED_CHARGING_START > LED_CHARGING_END ? -1 : 1;
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
uint8_t green = 0;
if (CHARGE_FINISHED == chargeState) {
if (LED_CHARGING_START > LED_CHARGING_END && i <= LED_CHARGING_START && i >= LED_CHARGING_END)
{
green = 20;
}
if (LED_CHARGING_START <= LED_CHARGING_END && i >= LED_CHARGING_START && i <= LED_CHARGING_END)
{
green = 20;
}
} else if (ledIdx == i) {
green = 20;
}
rgbSetLedColor(i, 0, green, 0);
}
rgbLedColorApply();
#endif
}
static Window* chargeWindow = nullptr;
void drawChargingInfo(uint16_t chargeState) {
static int progress = -1;
static StaticText* stateText = nullptr;
static lv_obj_t* battBox = nullptr;
const char* text;
int h;
LcdColorIndex color = COLOR_THEME_EDIT_INDEX;
switch (chargeState) {
case CHARGE_STARTED:
progress += 1;
if (progress > 4) progress = 0;
text = STR_BATTERYCHARGING;
h = ((BATTERY_H_INNER * progress) / 4);
break;
case CHARGE_FINISHED:
text = STR_BATTERYFULL;
h = BATTERY_H_INNER;
break;
default:
text = STR_BATTERYNONE;
h = BATTERY_H_INNER;
color = COLOR_THEME_PRIMARY1_INDEX;
break;
}
if (chargeWindow == nullptr) {
chargeWindow = new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
etx_solid_bg(chargeWindow->getLvObj(), COLOR_THEME_PRIMARY1_INDEX);
stateText = new StaticText(chargeWindow, {0, LCD_H - 50, LCD_W, 50}, "", COLOR_THEME_PRIMARY2_INDEX, CENTERED);
lv_obj_t* box = lv_obj_create(chargeWindow->getLvObj());
lv_obj_set_pos(box, (LCD_W - BATTERY_W) / 2, BATTERY_TOP);
lv_obj_set_size(box, BATTERY_W, BATTERY_H);
lv_obj_set_style_border_opa(box, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_width(box, 2, LV_PART_MAIN);
etx_border_color(box, COLOR_THEME_PRIMARY2_INDEX);
box = lv_obj_create(chargeWindow->getLvObj());
lv_obj_set_pos(box, (LCD_W - BATTERY_CONNECTOR_W) / 2, BATTERY_TOP - BATTERY_CONNECTOR_H);
lv_obj_set_size(box, BATTERY_CONNECTOR_W, BATTERY_CONNECTOR_H);
etx_solid_bg(box, COLOR_THEME_PRIMARY2_INDEX);
battBox = lv_obj_create(chargeWindow->getLvObj());
}
stateText->setText(text);
lv_obj_set_pos(battBox, (LCD_W - BATTERY_W_INNER) / 2, BATTERY_TOP_INNER + BATTERY_H_INNER - h);
lv_obj_set_size(battBox, BATTERY_W_INNER, h);
etx_solid_bg(battBox, color);
LvglWrapper::instance()->run();
lv_refr_now(nullptr);
BACKLIGHT_ENABLE();
}
void battery_charge_end()
{
chargeWindow->clear();
delete chargeWindow;
chargeWindow = nullptr;
}
#define CHARGE_INFO_DURATION 5000 // ms
//this method should be called by timer interrupt or by GPIO interrupt
void handle_battery_charge(uint32_t last_press_time)
{
#if !defined(SIMU)
static uint32_t updateTime = 0;
static uint16_t lastState = CHARGE_UNKNOWN;
static uint32_t info_until = 0;
static bool lcdInited = false;
uint32_t now = timersGetMsTick();
uint16_t chargeState = get_battery_charge_state();
if (chargeState != CHARGE_UNKNOWN) {
if (lastState != chargeState) {
//avoid positive check when none and unknown
if (lastState + chargeState > 1) {
//charge state changed - last state known
info_until = now + (CHARGE_INFO_DURATION);
}
}
//power buttons pressed
else if (now - last_press_time < POWER_ON_DELAY) {
info_until = now + CHARGE_INFO_DURATION;
}
lastState = chargeState;
}
if (!lcdInited) {
lcdInited = true;
backlightInit();
lcdInitDisplayDriver();
}
if (updateTime == 0 || ((timersGetMsTick() - updateTime) >= 500))
{
updateTime = timersGetMsTick();
ledChargingInfo(chargeState);
if(now > info_until) {
info_until = 0;
BACKLIGHT_DISABLE();
if(lcdInited) {
lcdOff();
}
} else {
if (lcdInited) {
lcdOn();
}
drawChargingInfo(chargeState);
// DEBUG INFO - TODO delete or replace with LVGL objects
#if 0
char buffer[1024];
sprintf(buffer, "%d,%d,%d,%d", uCharger.isChargerDetectionReady, uCharger.hasCharger, IS_UCHARGER_ACTIVE(), uCharger.chargerSamplingCount);
lcd->drawSizedText(100, 10, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
sprintf(buffer, "%d,%d,%d,%d,%d,", uCharger.isChargingDetectionReady, uCharger.isChargeEnd, IS_UCHARGER_CHARGE_END_ACTIVE(), uCharger.chargingSamplingCount, uCharger.chargeEndSamplingCount);
lcd->drawSizedText(100, 40, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
sprintf(buffer, "%d", isChargerActive());
lcd->drawSizedText(100, 130, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
#endif
}
}
#endif
}
#define BRIGHTNESS_MAX 255
void rgbPowerOn(uint8_t color) {
// Sequential RGB On
static uint8_t power_on_step = RGB_STEP_POWER_AROUND;
switch (power_on_step)
{
case RGB_STEP_POWER_AROUND:
setLedGroupColor(4, color, BRIGHTNESS_MAX);
setLedGroupColor(5, color, BRIGHTNESS_MAX);
setLedGroupColor(6, color, BRIGHTNESS_MAX);
break;
case RGB_STEP_FUNC1:
setLedGroupColor(0, color, BRIGHTNESS_MAX);
break;
case RGB_STEP_FUNC2:
setLedGroupColor(1, color, BRIGHTNESS_MAX);
break;
case RGB_STEP_FUNC3:
setLedGroupColor(2, color, BRIGHTNESS_MAX);
break;
case RGB_STEP_FUNC4:
setLedGroupColor(3, color, BRIGHTNESS_MAX);
break;
default:
break;
}
power_on_step++;
}
void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
uint8_t color = 0;
uint8_t breath_index = 0;
switch (power_level)
{
case POWER_LEVEL_CRITICAL:
color = RGB_COLOR_NONE;
if (rgb_state == RGB_STATE_CHARGE) {
color = RGB_COLOR_RED;
breath_index |= RGB_GROUP_MASK_FUNC_1;
setLedGroupColor(1, color, 0);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
}
break;
case POWER_LEVEL_LOW:
color = RGB_COLOR_RED;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_1;
setLedGroupColor(1, color, 0);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
}
break;
case POWER_LEVEL_MEDIUM:
color = RGB_COLOR_PURPLE;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_2;
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
}
break;
case POWER_LEVEL_HIGH:
color = RGB_COLOR_YELLOW;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_3;
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(3, color, 0);
}
break;
case POWER_LEVEL_NEAR_FULL:
color = RGB_COLOR_GREEN;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_4;
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, BRIGHTNESS_MAX);
}
break;
case POWER_LEVEL_FULL:
color = RGB_COLOR_GREEN;
if (rgb_state == RGB_STATE_CHARGE) {
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, BRIGHTNESS_MAX);
setLedGroupColor(3, color, BRIGHTNESS_MAX);
}
break;
default:
break;
}
switch (rgb_state)
{
case RGB_STATE_BREATH:
ledSetGroup(RGB_GROUP_MASK_ALL);
break;
case RGB_STATE_CHARGE:
breath_index |= RGB_GROUP_MASK_AROUND_L | RGB_GROUP_MASK_AROUND_R | RGB_GROUP_MASK_POWER;
ledSetGroup(breath_index);
break;
case RGB_STATE_POWER_ON:
rgbPowerOn(color);
break;
default:
break;
}
ledSetState(rgb_state);
ledSetColor(color);
}
#define BREATH_INTERVAL 7
#define GAMMA 6
#define PI 3.14159265358979323846f
#define BREATH_STEP 0.0089759771428571 // PI / 350.0f; // step size
typedef struct
{
uint8_t led_color;
uint8_t led_state;
uint8_t led_group;
} ledInfo_t;
// used to map all led number in the rgbled chain
// function 1~4 power right left
uint8_t rgbMapping[] = {4, 6, 0, 2, 8, 12, 10};
ledInfo_t led_info = {0};
void ledSetColor(uint8_t color) {
led_info.led_color = color;
}
void ledSetState(uint8_t state) {
led_info.led_state = state;
}
void ledSetGroup(uint8_t group) {
led_info.led_group = group;
}
void setLedGroupColor(uint8_t index, uint8_t color, uint8_t brightness) {
uint8_t scaled_r = 0;
uint8_t scaled_g = 0;
uint8_t scaled_b = 0;
if (color & RGB_COLOR_RED) {
scaled_r = brightness;
}
if (color & RGB_COLOR_GREEN) {
scaled_g = brightness;
}
if (color & RGB_COLOR_BLUE) {
scaled_b = brightness;
}
ws2812_set_color(rgbMapping[index], scaled_r, scaled_g, scaled_b);
ws2812_set_color(rgbMapping[index] + 1, scaled_r, scaled_g, scaled_b);
}
uint8_t ledBreathBright(float angle) {
float brightness = sin(angle) * 0.5 + 0.5; // map range 0-1
brightness = pow(brightness, GAMMA); // gamma correction
uint8_t bright = (uint8_t)(brightness * 255);
return bright;
}
void ledBreathUpdate(uint8_t state, uint8_t color, uint8_t group) {
static uint32_t breath_tick = 0;
if (timersGetMsTick() - breath_tick < BREATH_INTERVAL && breath_tick != 0) {
if (state == RGB_STATE_BREATH || state == RGB_STATE_CHARGE) {
return;
}
}
breath_tick = timersGetMsTick();
uint8_t bright = 0;
static float breath_angle = 0;
bright = ledBreathBright(breath_angle);
breath_angle += BREATH_STEP;
if (breath_angle > PI) breath_angle = 0; // reset angle
if (group & RGB_GROUP_MASK_FUNC_1) setLedGroupColor(0, color, bright);
if (group & RGB_GROUP_MASK_FUNC_2) setLedGroupColor(1, color, bright);
if (group & RGB_GROUP_MASK_FUNC_3) setLedGroupColor(2, color, bright);
if (group & RGB_GROUP_MASK_FUNC_4) setLedGroupColor(3, color, bright);
if (group & RGB_GROUP_MASK_POWER) setLedGroupColor(4, color, bright);
if (group & RGB_GROUP_MASK_AROUND_L) setLedGroupColor(5, color, bright);
if (group & RGB_GROUP_MASK_AROUND_R) setLedGroupColor(6, color, bright);
rgbLedColorApply();
}
void ledLoop(void) {
if (led_info.led_state == RGB_STATE_OFF) {
led_info.led_state = RGB_STATE_NONE;
rgbLedClearAll();
return;
} else if (led_info.led_state == RGB_STATE_POWER_ON) {
rgbLedColorApply();
return;
} else if (led_info.led_state == RGB_STATE_NONE) {
return;
}
ledBreathUpdate(led_info.led_state, led_info.led_color, led_info.led_group);
}
extern const stm32_pulse_timer_t _led_timer;
static uint8_t _led_charge_colors[WS2812_BYTES_PER_LED * LED_STRIP_LENGTH];
void rgbChargeInit(void) {
ws2812_init(&_led_timer, _led_charge_colors, LED_STRIP_LENGTH, WS2812_GRB);
rgbLedClearAll();
}
constexpr uint16_t vbatLedTable[] = {660, 720, 760, 800, 823};
constexpr uint16_t HYSTERESIS = 5;
void updateBatteryState(uint8_t rgb_state) {
uint16_t bat_v = getBatteryVoltage();
uint8_t power_level = POWER_LEVEL_NONE;
static uint8_t last_power_level = POWER_LEVEL_NONE;
uint16_t current_level_min = 0;
uint16_t current_level_max = 0;
bool need_update = true;
if (last_power_level != POWER_LEVEL_NONE) {
switch (last_power_level) {
case POWER_LEVEL_CRITICAL:
current_level_min = 0;
current_level_max = vbatLedTable[0] + HYSTERESIS;
break;
case POWER_LEVEL_LOW:
current_level_min = vbatLedTable[0] - HYSTERESIS;
current_level_max = vbatLedTable[1] + HYSTERESIS;
break;
case POWER_LEVEL_MEDIUM:
current_level_min = vbatLedTable[1] - HYSTERESIS;
current_level_max = vbatLedTable[2] + HYSTERESIS;
break;
case POWER_LEVEL_HIGH:
current_level_min = vbatLedTable[2] - HYSTERESIS;
current_level_max = vbatLedTable[3] + HYSTERESIS;
break;
case POWER_LEVEL_NEAR_FULL:
current_level_min = vbatLedTable[3] - HYSTERESIS;
current_level_max = vbatLedTable[4] + HYSTERESIS;
break;
case POWER_LEVEL_FULL:
current_level_min = vbatLedTable[4] - HYSTERESIS;
current_level_max = UINT16_MAX;
break;
default:
need_update = true;
}
if (bat_v >= current_level_min && bat_v <= current_level_max) {
need_update = false;
power_level = last_power_level;
}
}
if (need_update) {
if (bat_v < vbatLedTable[0]) {
power_level = POWER_LEVEL_CRITICAL;
} else if (bat_v < vbatLedTable[1]) {
power_level = POWER_LEVEL_LOW;
} else if (bat_v < vbatLedTable[2]) {
power_level = POWER_LEVEL_MEDIUM;
} else if (bat_v < vbatLedTable[3]) {
power_level = POWER_LEVEL_HIGH;
} else if (bat_v < vbatLedTable[4]){
power_level = POWER_LEVEL_NEAR_FULL;
} else {
power_level = POWER_LEVEL_FULL;
}
}
rgbBatteryLevelInfo(power_level, rgb_state);
ledLoop();
last_power_level = power_level;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include "board.h"
#include "hal.h"
#include "hal/gpio.h"
#include "stm32_gpio.h"
enum ChargeState
{
CHARGE_UNKNOWN,
CHARGE_NONE,
CHARGE_STARTED,
CHARGE_FINISHED
};
enum PowerLevel {
POWER_LEVEL_NONE,
POWER_LEVEL_CRITICAL,
POWER_LEVEL_LOW,
POWER_LEVEL_MEDIUM,
POWER_LEVEL_HIGH,
POWER_LEVEL_NEAR_FULL,
POWER_LEVEL_FULL,
};
extern void battery_charge_init();
extern void handle_battery_charge(uint32_t last_press_time);
extern uint16_t get_battery_charge_state();
extern uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
extern bool isChargerActive();
extern void battery_charge_end();
void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state);
void updateBatteryState(uint8_t rgb_state);
+379
View File
@@ -0,0 +1,379 @@
/*
* 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 "bsp_io.h"
#include "hal/adc_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 "battery_driver.h"
#include "bitmapbuffer.h"
#include "colors.h"
#include <string.h>
// common ADC driver
extern const etx_hal_adc_driver_t _adc_driver;
#if defined(SEMIHOSTING)
extern "C" void initialise_monitor_handles();
#endif
#if defined(SPI_FLASH)
extern "C" void flushFTL();
#endif
constexpr uint8_t ledMapping[] = {4, 6, 0, 2};
void INTERNAL_MODULE_BOOTCMD(uint8_t enable)
{
if (enable)
bsp_output_set(BSP_INTMOD_BOOTCMD);
else
bsp_output_clear(BSP_INTMOD_BOOTCMD);
}
void INTERNAL_MODULE_ON()
{
bsp_output_set(BSP_INTMOD_PWR_EN);
}
void INTERNAL_MODULE_OFF()
{
bsp_output_clear(BSP_INTMOD_PWR_EN);
}
void EXTERNAL_MODULE_ON()
{
bsp_output_set(BSP_EXTMOD_PWR_EN);
}
void EXTERNAL_MODULE_OFF()
{
bsp_output_clear(BSP_EXTMOD_PWR_EN);
}
void boardBLEarlyInit()
{
timersInit();
bsp_io_init();
gpio_init(UCHARGER_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW);
}
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();
#if defined(DEBUG)
serialSetMode(SP_AUX1, UART_MODE_DEBUG); // indicate AUX1 is used
serialInit(SP_AUX1, UART_MODE_DEBUG); // early AUX1 init
#endif
boardInitModulePorts();
pwrInit();
delaysInit();
timersInit();
bsp_io_init();
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);
board_trainer_init();
battery_charge_init();
adcInit(&_adc_driver);
getADC();
flysky_gimbal_init();
usbInit();
rgbChargeInit(); // RTOS was not running, timer_create will prevent the ADC from reading.
rotaryEncoderInit();
#if !defined(DEBUG_SEGGER_RTT)
#if defined(SHORT_LONG_PRESS)
uint32_t short_press = 0;
uint32_t first_short_press = 0;
uint32_t long_press = 0;
uint32_t last_pulse = 0;
uint32_t now = 0;
pwrOn();
// Handle charging state if charger is active
if (isChargerActive()) {
static uint32_t adc_sample_time = 0; // Hardware ADC sample tick
bool is_charging = true;
while (1)
{
now = timersGetMsTick();
while (now - adc_sample_time > 10)
{
adc_sample_time = now;
getADC();
is_charging = isChargerActive();
}
// Exit conditions: button pressed or charger disconnected
if (!pwrPressed() && is_charging) {
updateBatteryState(RGB_STATE_CHARGE);
} else {
rgbLedClearAll();
if (!is_charging) {
boardOff();
}
break;
}
}
}
// First stage: Detect initial button press and handle press duration
first_short_press = timersGetMsTick();
while (pwrPressed()) {
now = timersGetMsTick();
short_press = now;
last_pulse = now;
updateBatteryState(RGB_STATE_BREATH);
// Shutdown after 10s continuous press
if (now - first_short_press > FRIST_PRESS_TIMEOUT) {
rgbLedClearAll();
boardOff();
}
}
// Second stage: Detect secondary long-press sequence
while (1)
{
now = timersGetMsTick();
if (pwrPressed()) {
if (long_press == 0) {
updateBatteryState(RGB_STATE_OFF);
long_press = now;
}
// Successful long-press completion
if (now - long_press > POWER_ON_DELAY) {
// updateBatteryState(RGB_STATE_OFF);
break;
}
// Pulsing effect during long-press
if (now - last_pulse > POWER_ON_STEP) {
last_pulse = now;
updateBatteryState(RGB_STATE_POWER_ON);
}
} else {
// Breathing effect between press sequences
updateBatteryState(RGB_STATE_BREATH);
// Shutdown conditions:
// 1. Incomplete secondary press (released too soon)
// 2. Timeout between press sequences
if ((long_press != 0) || (now - short_press > INTER_PRESS_TIMEOUT)) {
boardOff();
}
}
}
#else
uint32_t press_start = 0;
uint32_t press_end = 0;
rotenc_t lastEncoderValue = 0;
if (UNEXPECTED_SHUTDOWN()) {
pwrOn();
} else if (isChargerActive()) {
while (true) {
pwrOn();
uint32_t now = timersGetMsTick();
if (pwrPressed()) {
press_end = now;
if (press_start == 0) press_start = now;
if ((now - press_start) > POWER_ON_DELAY) {
break;
}
} else if (!isChargerActive()) {
boardOff();
} else {
uint32_t press_end_touch = press_end;
extern void rotaryEncoderCheck();
rotaryEncoderCheck();
rotenc_t value = rotaryEncoderGetValue();
if (value != lastEncoderValue) {
lastEncoderValue = value;
press_end_touch = timersGetMsTick();
}
press_start = 0;
handle_battery_charge(press_end_touch);
delay_ms(10);
press_end = 0;
}
}
battery_charge_end();
}
#endif
#endif
rgbLedInit();
rgbLedClearAll();
keysInit();
switchInit();
audioInit();
hapticInit();
#if defined(RTCLOCK)
rtcInit(); // RTC must be initialized before rambackupRestore() is called
#endif
}
extern void rtcDisableBackupReg();
void boardOff()
{
lcdOff();
while (pwrPressed()) {
WDG_RESET();
}
SysTick->CTRL = 0; // turn off systick
// Shutdown the Haptic
hapticDone();
rtcDisableBackupReg();
#if !defined(BOOT)
rgbLedClearAll();
if (IS_UCHARGER_ACTIVE())
{
// RTC->BKP0R = SOFTRESET_REQUEST;
NVIC_SystemReset();
}
else
#endif
// 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) {
}
}
/*
int usbPlugged()
{
static uint8_t debouncedState = 0;
static uint8_t lastState = 0;
uint8_t state = IS_UCHARGER_ACTIVE();
if (state == lastState)
debouncedState = state;
else
lastState = state;
return debouncedState;
}
*/
// extern "C" void * memcpy(void* dst, const void*src, size_t count)
// {
// uint8_t* d = (uint8_t*)dst;
// const uint8_t* s = (const uint8_t*)src;
// while(count--)
// *d++ = *s++;
// return dst;
// }
+295
View File
@@ -0,0 +1,295 @@
/*
* 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 FLASHSIZE 0x800000
#define FLASH_PAGESIZE 256
#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(); /*gpio_set(INTMODULE_PWR_GPIO)*/
void INTERNAL_MODULE_OFF(); /*gpio_clear(INTMODULE_PWR_GPIO);*/
void INTERNAL_MODULE_BOOTCMD(uint8_t enable);
void EXTERNAL_MODULE_ON(); /*gpio_set(EXTMODULE_PWR_GPIO)*/
void EXTERNAL_MODULE_OFF(); /*gpio_clear(EXTMODULE_PWR_GPIO)*/
#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_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#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 4
#define NUM_FUNCTIONS_GROUPS 2
#define DEFAULT_FS_CONFIG \
(SWITCH_2POS << 6) + \
(SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0)
#define DEFAULT_FS_GROUPS \
(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 << 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 4
#define DEFAULT_STICK_DEADZONE 2
#define BATTERY_WARN 74 // 7.4V
#define BATTERY_MIN 70 // 6.8V
#define BATTERY_MAX 86 // 8.6V
#define BATTERY_DIVIDER 2323
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
// Power driver
#define SOFT_PWR_CTRL
#define POWER_ON_DELAY 1500 // 1.5s
#define POWER_ON_STEP 250 // 300ms
#define INTER_PRESS_TIMEOUT 5000 // 5s
#define FRIST_PRESS_TIMEOUT 10000 // 10s
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
#define IS_UCHARGER_ACTIVE() gpio_read(UCHARGER_GPIO) ? 1 : 0
#define IS_UCHARGER_CHARGE_END_ACTIVE() gpio_read(UCHARGER_CHARGE_END_GPIO) ? 0 : 1
#define ENABLE_UCHARGER() bsp_output_set(BSP_CHARGE_EN);
#define DISABLE_UCHARGER() bsp_output_clear(BSP_CHARGE_EN)
// Audio driver
void audioInit();
void audioConsumeCurrentBuffer();
void setSampleRate(uint32_t frequency);
#define audioWaitReady()
#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();
enum rgb_state_e {
RGB_STATE_NONE,
RGB_STATE_BREATH,
RGB_STATE_CHARGE,
RGB_STATE_ON,
RGB_STATE_OFF,
RGB_STATE_POWER_ON,
RGB_STATE_POWER_OFF,
};
enum rgb_color_e {
RGB_COLOR_NONE = 0,
RGB_COLOR_RED = (1 << 0), // 00000001
RGB_COLOR_GREEN = (1 << 1), // 00000010
RGB_COLOR_BLUE = (1 << 2), // 00000100
RGB_COLOR_YELLOW = RGB_COLOR_RED | RGB_COLOR_GREEN,
RGB_COLOR_PURPLE = RGB_COLOR_RED | RGB_COLOR_BLUE,
RGB_COLOR_WHITE = RGB_COLOR_RED | RGB_COLOR_GREEN | RGB_COLOR_BLUE,
};
enum rgb_group_e {
RGB_GROUP_MASK_NONE = 0,
RGB_GROUP_MASK_FUNC_1 = (1 << 0),
RGB_GROUP_MASK_FUNC_2 = (1 << 1),
RGB_GROUP_MASK_FUNC_3 = (1 << 2),
RGB_GROUP_MASK_FUNC_4 = (1 << 3),
RGB_GROUP_MASK_POWER = (1 << 4),
RGB_GROUP_MASK_AROUND_L = (1 << 5),
RGB_GROUP_MASK_AROUND_R = (1 << 6),
RGB_GROUP_MASK_ALL = 0x7f, // 0111 1111
};
enum rgb_power_step_e {
RGB_STEP_POWER_AROUND,
RGB_STEP_FUNC1,
RGB_STEP_FUNC2,
RGB_STEP_FUNC3,
RGB_STEP_FUNC4,
};
void rgbChargeInit(void);
void ledLoop(void);
void ledSetColor(uint8_t color);
void ledSetState(uint8_t state);
void ledSetGroup(uint8_t group);
void setLedGroupColor(uint8_t index, uint8_t color, uint8_t brightness);
#endif // _BOARD_H_
+90
View File
@@ -0,0 +1,90 @@
/*
* 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 "bsp_io.h"
#include "hal.h"
#include "drivers/aw9523b.h"
#include "stm32_i2c_driver.h"
#include "stm32_switch_driver.h"
#define BSP_I2C_BUS I2C_Bus_1
#define BSP_I2C_ADDR 0x5b
#define BSP_IN_MASK \
(AW9523B_PIN_0 | AW9523B_PIN_1 | AW9523B_PIN_2 | AW9523B_PIN_3)
#define BSP_OUT_MASK \
(AW9523B_PIN_7 | AW9523B_PIN_8 | AW9523B_PIN_9 | AW9523B_PIN_10 | \
AW9523B_PIN_11 | AW9523B_PIN_12 | AW9523B_PIN_13 | AW9523B_PIN_14 | \
AW9523B_PIN_15)
#define BSP_CHECK(x) if ((x) < 0) return -1
static aw9523b_t i2c_exp;
static uint16_t inputState = 0;
static bool shouldReadKeys = false;
static void _io_int_handler()
{
shouldReadKeys = true;
}
bool bsp_get_shouldReadKeys()
{
bool tmp = shouldReadKeys;
shouldReadKeys = false;
return tmp;
}
static void bsp_input_read()
{
uint16_t value;
if (aw9523b_read(&i2c_exp, BSP_IN_MASK, &value) < 0) return;
inputState = value;
}
int bsp_io_init()
{
// init outputs
BSP_CHECK(aw9523b_init(&i2c_exp, BSP_I2C_BUS, BSP_I2C_ADDR));
BSP_CHECK(aw9523b_write(&i2c_exp, BSP_OUT_MASK,
BSP_KEY_OUT1 | BSP_KEY_OUT2 | BSP_KEY_OUT3 | BSP_KEY_OUT4));
BSP_CHECK(aw9523b_set_direction(&i2c_exp, 0xFFFF, BSP_IN_MASK));
// setup expanders pin change interrupt
gpio_init_int(IO_INT_GPIO, GPIO_IN, GPIO_FALLING, _io_int_handler);
bsp_output_clear(BSP_U6_SELECT);
return 0;
}
void bsp_output_set(uint16_t pin) { aw9523b_write(&i2c_exp, pin, pin); }
void bsp_output_set(uint16_t mask, uint16_t pin) { aw9523b_write(&i2c_exp, mask, pin); }
void bsp_output_clear(uint16_t pin) { aw9523b_write(&i2c_exp, pin, 0); }
uint16_t bsp_input_get()
{
bsp_input_read();
return inputState;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) EdgeTx
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include "drivers/aw9523b.h"
#include "stm32_switch_driver.h"
#include "hal/switch_driver.h"
bool getFctKeyState(int index);
// Input port expander
#define BSP_KEY_IN1 AW9523B_PIN_0
#define BSP_KEY_IN2 AW9523B_PIN_1
#define BSP_KEY_IN3 AW9523B_PIN_2
#define BSP_KEY_IN4 AW9523B_PIN_3
// Output port expander
#define BSP_INTMOD_PWR_EN AW9523B_PIN_7
#define BSP_CHARGE_EN AW9523B_PIN_8
#define BSP_INTMOD_BOOTCMD AW9523B_PIN_9
#define BSP_KEY_OUT1 AW9523B_PIN_10
#define BSP_KEY_OUT2 AW9523B_PIN_11
#define BSP_KEY_OUT3 AW9523B_PIN_12
#define BSP_KEY_OUT4 AW9523B_PIN_13
#define BSP_U6_SELECT AW9523B_PIN_14
#define BSP_EXTMOD_PWR_EN AW9523B_PIN_15
int bsp_io_init();
bool bsp_get_shouldReadKeys();
void bsp_output_set(uint16_t pin);
void bsp_output_set(uint16_t mask, uint16_t pin);
void bsp_output_clear(uint16_t pin);
uint16_t bsp_input_get();
+154
View File
@@ -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
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include "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();
@@ -0,0 +1,49 @@
/*
* 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 "board.h"
void EXTERNAL_MODULE_ON()
{
GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
}
void EXTERNAL_MODULE_OFF()
{
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
}
void extModuleInit()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_INVERT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(EXTMODULE_TX_INVERT_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_RX_INVERT_GPIO_PIN;
GPIO_Init(EXTMODULE_RX_INVERT_GPIO, &GPIO_InitStructure);
EXTMODULE_TX_INVERTED();
EXTMODULE_RX_INVERTED();
}
+498
View File
@@ -0,0 +1,498 @@
/*
* 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 _HAL_H_
#define _HAL_H_
#define CPU_FREQ 400000000
#define PERI1_FREQUENCY 100000000
#define PERI2_FREQUENCY 100000000
#define TIMER_MULT_APB1 2
#define TIMER_MULT_APB2 2
/* Timers Allocation:
* TIM3 = Haptic / Backlight
* TIM15 = Trainer
*
* TIM14 = 5 ms counter
*/
/* DMA Allocation:
*/
// Keys
#define KEYS_GPIO_REG_ENTER
#define KEYS_GPIO_PIN_ENTER
#define KEYS_GPIO_ENTER GPIO_PIN(GPIOG, 13) // PG.13
// Keys in bsp matrix
#define KEYS_GPIO_REG_PAGEUP
#define KEYS_GPIO_PIN_PAGEUP
#define KEYS_GPIO_REG_PAGEDN
#define KEYS_GPIO_PIN_PAGEDN
#define KEYS_GPIO_REG_SYS
#define KEYS_GPIO_PIN_SYS
#define KEYS_GPIO_REG_EXIT
#define KEYS_GPIO_PIN_EXIT
// Trims in bsp matrix
#define TRIMS_GPIO_REG_LHL
#define TRIMS_GPIO_PIN_LHL
#define TRIMS_GPIO_REG_LHR
#define TRIMS_GPIO_PIN_LHR
#define TRIMS_GPIO_REG_LVD
#define TRIMS_GPIO_PIN_LVD
#define TRIMS_GPIO_REG_LVU
#define TRIMS_GPIO_PIN_LVU
#define TRIMS_GPIO_REG_RHL
#define TRIMS_GPIO_PIN_RHL
#define TRIMS_GPIO_REG_RHR
#define TRIMS_GPIO_PIN_RHR
#define TRIMS_GPIO_REG_RVD
#define TRIMS_GPIO_PIN_RVD
#define TRIMS_GPIO_REG_RVU
#define TRIMS_GPIO_PIN_RVU
// function switches
#define FUNCTION_SWITCH_1 SK
#define SWITCHES_GPIO_REG_K
#define SWITCHES_GPIO_PIN_K AW9523B_PIN_0
#define SWITCHES_K_CFS_IDX 0
#define FUNCTION_SWITCH_2 SL
#define SWITCHES_GPIO_REG_L
#define SWITCHES_GPIO_PIN_L AW9523B_PIN_1
#define SWITCHES_L_CFS_IDX 1
#define FUNCTION_SWITCH_3 SM
#define SWITCHES_GPIO_REG_M
#define SWITCHES_GPIO_PIN_M AW9523B_PIN_2
#define SWITCHES_M_CFS_IDX 2
#define FUNCTION_SWITCH_4 SN
#define SWITCHES_GPIO_REG_N
#define SWITCHES_GPIO_PIN_N AW9523B_PIN_3
#define SWITCHES_N_CFS_IDX 3
// Direct switches
// SWA
#define STORAGE_SWITCH_A
#define HARDWARE_SWITCH_A
#define SWITCHES_GPIO_REG_A GPIOA
#define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_2 // PA.02
// SWD
#define STORAGE_SWITCH_D
#define HARDWARE_SWITCH_D
#define SWITCHES_GPIO_REG_D GPIOF
#define SWITCHES_GPIO_PIN_D LL_GPIO_PIN_8 // PF.08
// SWE
#define STORAGE_SWITCH_E
#define HARDWARE_SWITCH_E
#define SWITCHES_GPIO_REG_E GPIOG
#define SWITCHES_GPIO_PIN_E LL_GPIO_PIN_3 // PG.03
// SWF
#define STORAGE_SWITCH_F
#define HARDWARE_SWITCH_F
#define SWITCHES_GPIO_REG_F GPIOG
#define SWITCHES_GPIO_PIN_F LL_GPIO_PIN_2 // PG.02
#define KEYS_GPIOB_PINS (LL_GPIO_PIN_15)
// PC8 allocated to SDIO D0, is not required to sample SWA !
#define KEYS_GPIOC_PINS (LL_GPIO_PIN_13)
#define KEYS_GPIOD_PINS ()
#define KEYS_GPIOH_PINS \
(LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11)
#define KEYS_GPIOJ_PINS (LL_GPIO_PIN_12)
#define KEYS_OUT_GPIOG_PINS (LL_GPIO_PIN_2 )
#define KEYS_OUT_GPIOH_PINS (LL_GPIO_PIN_7)
// ADC
#define ADC_GPIO_PIN_STICK_LH
#define ADC_GPIO_PIN_STICK_LV
#define ADC_GPIO_PIN_STICK_RV
#define ADC_GPIO_PIN_STICK_RH
#define ADC_GPIO_PIN_SLIDER1 LL_GPIO_PIN_3 // PA.03 S1
#define ADC_GPIO_PIN_SLIDER2 LL_GPIO_PIN_5 // PA.05 S2
#define ADC_GPIO_PIN_SWB LL_GPIO_PIN_5 // PC.05
#define ADC_GPIO_PIN_SWC LL_GPIO_PIN_7 // PF.07
#define ADC_GPIO_PIN_BATT LL_GPIO_PIN_1 // PC.01
#define ADC_GPIOA_PINS ( ADC_GPIO_PIN_SLIDER1 | ADC_GPIO_PIN_SLIDER2 )
#define ADC_GPIOC_PINS ( ADC_GPIO_PIN_BATT | ADC_GPIO_PIN_SWB )
#define ADC_GPIOF_PINS ( ADC_GPIO_PIN_SWC )
#define ADC_CHANNEL_STICK_LH
#define ADC_CHANNEL_STICK_LV
#define ADC_CHANNEL_STICK_RV
#define ADC_CHANNEL_STICK_RH
// Sliders
#define ADC_CHANNEL_SLIDER1 LL_ADC_CHANNEL_15 // ADC12_INP15
#define ADC_CHANNEL_SLIDER2 LL_ADC_CHANNEL_19 // ADC12_INP19
// Analog switches
#define ADC_CHANNEL_SWB LL_ADC_CHANNEL_8 // ADC12_INP8
#define ADC_CHANNEL_SWC LL_ADC_CHANNEL_3 // ADC3_INP3
#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_11 // ADC123_INP11
#define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC12_IN16
#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_64CYCLES_5
#define ADC_EXT ADC3
#define ADC_EXT_CHANNELS \
{ ADC_CHANNEL_SWC, ADC_CHANNEL_SWD }
#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_64CYCLES_5
#define ADC_VREF_PREC2 329
#define ADC_DIRECTION { \
0,0,0,0, /* gimbals */ \
0,0, /* sliders */ \
0, /* vbat */ \
0, /* rtc_bat */ \
-1, /* SWB */ \
-1, /* SWC */ \
0, /* SWE */ \
0 /* SWF */ \
}
// Power
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOE, 6) // PE.06
#define PWR_ON_GPIO GPIO_PIN(GPIOE, 3) // PE.03
#define SHORT_LONG_PRESS
// USB Chargers
#define UCHARGER_GPIO GPIO_PIN(GPIOB, 0) // PB.00
#define UCHARGER_CHARGE_END_GPIO GPIO_PIN(GPIOG, 14) // PG.14
#define IO_INT_GPIO GPIO_PIN(GPIOB, 4) // PB.04
#if !defined(USE_EXTI4_IRQ)
#define USE_EXTI4_IRQ
#define EXTI4_IRQ_Priority 5
#endif
// S.Port update connector
#define HAS_SPORT_UPDATE_CONNECTOR() (false)
// Telemetry
#define TELEMETRY_TX_GPIO GPIO_PIN(GPIOB, 14)
#define TELEMETRY_RX_GPIO GPIO_UNDEF
#define TELEMETRY_USART USART1
#define TELEMETRY_USART_IRQn USART1_IRQn
#define TELEMETRY_DMA DMA1
#define TELEMETRY_DMA_Stream_TX LL_DMA_STREAM_7
#define TELEMETRY_DMA_Channel_TX LL_DMAMUX1_REQ_USART1_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_USART1_RX
#define TELEMETRY_USART_IRQHandler USART1_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(GPIOB, 0) // PB.00
#define USB_GPIO_DM GPIO_PIN(GPIOA, 11) // PA.11
#define USB_GPIO_DP GPIO_PIN(GPIOA, 12) // PA.12
#define USB_GPIO_AF GPIO_AF10
// LCD
#define LCD_SPI SPI1
#define LCD_SPI_DMA DMA1
#define LCD_SPI_TX_DMA LL_DMAMUX1_REQ_SPI1_TX
#define LCD_SPI_RX_DMA LL_DMAMUX1_REQ_SPI1_RX
#define LCD_SPI_TX_DMA_STREAM LL_DMA_STREAM_4
#define LCD_SPI_RX_DMA_STREAM LL_DMA_STREAM_5
#define LCD_FMARK GPIO_PIN(GPIOB, 7)
#define LCD_NRST GPIO_PIN(GPIOD, 7)
#define LCD_SPI_RS GPIO_PIN(GPIOG, 12)
#define LCD_SPI_CS GPIO_PIN(GPIOG, 10)
#define LCD_SPI_CLK GPIO_PIN(GPIOG, 11)
#define LCD_SPI_MOSI GPIO_PIN(GPIOB, 5)
#define LCD_SPI_MISO GPIO_PIN(GPIOG, 9)
#define LCD_SPI_BAUD 100000000
// Backlight
#define BACKLIGHT_GPIO GPIO_PIN(GPIOB, 03) // TIM2_CH2
#define BACKLIGHT_TIMER TIM2
#define BACKLIGHT_GPIO_AF GPIO_AF1
#define BACKLIGHT_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
// QSPI Flash
#define QSPI_MAX_FREQ 80000000U // 80 MHz
#define QSPI_CLK_GPIO GPIO_PIN(GPIOB, 2)
#define QSPI_CLK_GPIO_AF GPIO_AF9
#define QSPI_CS_GPIO GPIO_PIN(GPIOB, 6)
#define QSPI_CS_GPIO_AF GPIO_AF10
#define QSPI_MISO_GPIO GPIO_PIN(GPIOD, 12)
#define QSPI_MISO_GPIO_AF GPIO_AF9
#define QSPI_MOSI_GPIO GPIO_PIN(GPIOD, 11)
#define QSPI_MOSI_GPIO_AF GPIO_AF9
#define QSPI_WP_GPIO GPIO_PIN(GPIOE, 2)
#define QSPI_WP_GPIO_AF GPIO_AF9
#define QSPI_HOLD_GPIO GPIO_PIN(GPIOD, 13)
#define QSPI_HOLD_GPIO_AF GPIO_AF9
#define QSPI_FLASH_SIZE 0x800000
#define QSPI_QE_REG 1
#define QSPI_QE_BIT (1 << 6)
// Storage
#define STORAGE_USE_SDIO
/*
* SDIO pins:
* - SDMMC1_D0-D3 (PC.08-11)
* - SDMMC1_CK (PC.12)
* - SDMMC1_CMD (PD.02)
*/
#define SD_SDIO SDMMC1
#define SD_SDIO_TRANSFER_CLK_DIV SDMMC_HSPEED_CLK_DIV
// Audio
#define AUDIO_MUTE_GPIO GPIO_PIN(GPIOE, 4) // PE.04
#define AUDIO_OUTPUT_GPIO GPIO_PIN(GPIOA, 4) // PA.04
#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 DMA1_Stream1_IRQn
#define AUDIO_DMA_Stream_IRQHandler DMA1_Stream1_IRQHandler
#define AUDIO_TIMER TIM6
#define AUDIO_DMA DMA1
#define AUDIO_UNMUTE_DELAY 100 // ms
#define AUDIO_MUTE_DELAY 100 // ms
#define INVERTED_MUTE_PIN
// I2C Bus
#define I2C_B1 I2C1
#define I2C_B1_SDA_GPIO GPIO_PIN(GPIOB, 9) // PB.09
#define I2C_B1_SCL_GPIO GPIO_PIN(GPIOB, 8) // PB.08
#define I2C_B1_GPIO_AF LL_GPIO_AF_4
#define I2C_B1_CLK_RATE 400000
#define I2C_B2 I2C2
#define I2C_B2_SDA_GPIO GPIO_PIN(GPIOB, 10) // PB.10
#define I2C_B2_SCL_GPIO GPIO_PIN(GPIOB, 11) // PB.11
#define I2C_B2_GPIO_AF LL_GPIO_AF_4
#define I2C_B2_CLK_RATE 400000
// Haptic: TIM3_CH2
#define HAPTIC_PWM
#define HAPTIC_GPIO GPIO_PIN(GPIOA, 15) // PA.15
#define HAPTIC_GPIO_TIMER TIM2
#define HAPTIC_GPIO_AF GPIO_AF1
// Flysky Hall Stick
#define FLYSKY_HALL_SERIAL_USART USART2
#define FLYSKY_HALL_SERIAL_TX_GPIO GPIO_PIN(GPIOD, 5) // PD.05
#define FLYSKY_HALL_SERIAL_RX_GPIO GPIO_PIN(GPIOD, 6) // PD.06
#define FLYSKY_HALL_SERIAL_USART_IRQn USART2_IRQn
#define FLYSKY_HALL_SERIAL_DMA DMA1
#define FLYSKY_HALL_DMA_Stream_RX LL_DMA_STREAM_2
#define FLYSKY_HALL_DMA_Stream_TX LL_DMA_STREAM_4
#define FLYSKY_HALL_DMA_Channel LL_DMAMUX1_REQ_USART2_RX
// TODO LED Strip PF.06
// LED Strip
#define LED_STRIP_LENGTH 14
#define BLING_LED_STRIP_START 0
#define BLING_LED_STRIP_LENGTH 10
#define CFS_LED_STRIP_START 10
#define CFS_LED_STRIP_LENGTH 4
#define CFS_LEDS_PER_SWITCH 1
#define LED_STRIP_GPIO GPIO_PIN(GPIOF, 06) // PF.06 / TIM16_CH1
#define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1/2/16/17
#define LED_STRIP_TIMER TIM16
#define LED_STRIP_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define LED_STRIP_TIMER_CHANNEL LL_TIM_CHANNEL_CH1
#define LED_STRIP_TIMER_DMA DMA1
#define LED_STRIP_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM16_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 RGB_LED_OFFSET 10
#define STATUS_LEDS
#define LED_CHARGING_START 0
#define LED_CHARGING_END 13
// Internal Module
#define INTMODULE_TX_GPIO GPIO_PIN(GPIOA, 0) // PA.00
#define INTMODULE_RX_GPIO GPIO_PIN(GPIOA, 1) // PA.01
#define INTMODULE_USART UART4
#define INTMODULE_GPIO_AF LL_GPIO_AF_8
#define INTMODULE_USART_IRQn UART4_IRQn
#define INTMODULE_USART_IRQHandler UART4_IRQHandler
#define INTMODULE_DMA DMA2
#define INTMODULE_DMA_STREAM LL_DMA_STREAM_6
#define INTMODULE_DMA_CHANNEL LL_DMAMUX1_REQ_UART4_TX
#define INTMODULE_RX_DMA DMA2
#define INTMODULE_RX_DMA_STREAM LL_DMA_STREAM_5
#define INTMODULE_RX_DMA_CHANNEL LL_DMAMUX1_REQ_UART4_RX
#define INTMODULE_BOOTCMD_BSP
// External Module
#define EXTMODULE
#define EXTMODULE_PULSES
#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOC, 6) // PC.06
#define EXTMODULE_RX_GPIO GPIO_PIN(GPIOC, 7) // PC.07
#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_RX_GPIO GPIO_PIN(GPIOC, 7) // PC.07
#define EXTMODULE_USART_TX_GPIO GPIO_PIN(GPIOC, 6) // PC.06
#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_1
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_RX
#define EXTMODULE_USART_RX_DMA_STREAM LL_DMA_STREAM_3
#define EXTMODULE_USART_IRQHandler USART6_IRQHandler
#define EXTMODULE_USART_IRQn USART6_IRQn
//TIMER
#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM3_UP
#define EXTMODULE_TIMER_DMA DMA2
#define EXTMODULE_TIMER_DMA_STREAM LL_DMA_STREAM_1
#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream1_IRQn
#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream1_IRQHandler
// Trainer Port
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD)
#define TRAINER_IN_GPIO GPIO_PIN(GPIOA, 10) // PA.10
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH3
#define TRAINER_OUT_GPIO GPIO_PIN(GPIOA, 9) // PA.09
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_TIMER TIM1
#define TRAINER_TIMER_IRQn TIM1_CC_IRQn
#define TRAINER_TIMER_IRQHandler TIM1_CC_IRQHandler
#define TRAINER_GPIO_AF LL_GPIO_AF_1
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TOUCH_I2C_BUS I2C_Bus_1
#define TOUCH_I2C_CLK_RATE 100000
// Rotary Encoder
#define ROTARY_ENCODER_NAVIGATION
#define ROTARY_ENCODER_GPIO GPIOA
#define ROTARY_ENCODER_GPIO_PIN_A LL_GPIO_PIN_6 // PA.06
#define ROTARY_ENCODER_GPIO_PIN_B LL_GPIO_PIN_7 // PA.07
#define ROTARY_ENCODER_POSITION() ((ROTARY_ENCODER_GPIO->IDR >> 6) & 0x03)
#define ROTARY_ENCODER_EXTI_LINE1 LL_EXTI_LINE_6
#define ROTARY_ENCODER_EXTI_LINE2 LL_EXTI_LINE_7
// port extender interrupt
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
#define ROTARY_ENCODER_EXTI_PORT 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
// IMU / Gyro
#define IMU_I2C_BUS I2C_Bus_2
#define IMU_I2C_ADDRESS 0x6A
#define LCD_W 320
#define LCD_H 240
#define LCD_PHYS_W LCD_W
#define LCD_PHYS_H LCD_H
#define LCD_DEPTH 16
#endif // _HAL_H_
+60
View File
@@ -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_CH1,
.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(); }
+204
View File
@@ -0,0 +1,204 @@
/*
* 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 "bsp_io.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"
#define BSP_READ_AFTER_WRITE_DELAY 10 // us
#define BSP_KEY_OUT_MASK \
(BSP_KEY_OUT1 | BSP_KEY_OUT2 | BSP_KEY_OUT3 | BSP_KEY_OUT4)
/* The output bit-order has to be:
0 LHL TR3L (Left equals down)
1 LHR TR3R
2 LVD TR1D
3 LVU TR1U
4 RVD TR2D
5 RVU TR2U
6 RHL TR4L
7 RHR TR4R
*/
enum PhysicalKeys
{
// Trims
TR3L = 0,
TR3R,
TR1D = 2,
TR1U,
TR2D = 4,
TR2U,
TR4L = 6,
TR4R,
// Keys
PGUP = 8,
PGDN,
RTN = 10,
MODEL,
KEY1 = 12,
KEY2,
KEY3 = 14,
KEY4,
ENT = 16
};
static bool fct_state[4] = {false, false, false, false};
static uint32_t keyState = 0;
static uint32_t nonReadCount = 0;
static uint32_t _readKeyMatrix()
{
#if !defined(BOOT)
if(!bsp_get_shouldReadKeys() && nonReadCount < 10)
{
if (gpio_read(KEYS_GPIO_ENTER) == 0)
keyState |= 1<<ENT;
nonReadCount++;
return keyState;
}
nonReadCount = 0;
#endif
// This function avoids concurrent matrix agitation
uint32_t result = 0;
uint16_t bsp_input = 0;
volatile static struct
{
uint32_t oldResult = 0;
uint8_t ui8ReadInProgress = 0;
} syncelem;
if (syncelem.ui8ReadInProgress != 0) return syncelem.oldResult;
// ui8ReadInProgress was 0, increment it
syncelem.ui8ReadInProgress++;
// Double check before continuing, as non-atomic, non-blocking so far
// If ui8ReadInProgress is above 1, then there was concurrent task calling it, exit
if (syncelem.ui8ReadInProgress > 1) return syncelem.oldResult;
// If we land here, we have exclusive access to Matrix
bsp_output_set(BSP_KEY_OUT_MASK, ~BSP_KEY_OUT1);
delay_us(BSP_READ_AFTER_WRITE_DELAY);
bsp_input = bsp_input_get();
if ((bsp_input & BSP_KEY_IN1) == 0)
result |= 1<<TR1U;
if ((bsp_input & BSP_KEY_IN2) == 0)
result |= 1<<TR1D;
if ((bsp_input & BSP_KEY_IN3) == 0)
result |= 1<<TR2U;
if ((bsp_input & BSP_KEY_IN4) == 0)
result |= 1<<TR2D;
bsp_output_set(BSP_KEY_OUT_MASK, ~BSP_KEY_OUT2);
delay_us(BSP_READ_AFTER_WRITE_DELAY);
bsp_input = bsp_input_get();
if ((bsp_input & BSP_KEY_IN1) == 0)
result |= 1<<TR3L;
if ((bsp_input & BSP_KEY_IN2) == 0)
result |= 1<<TR3R;
if ((bsp_input & BSP_KEY_IN3) == 0)
result |= 1<<TR4L;
if ((bsp_input & BSP_KEY_IN4) == 0)
result |= 1<<TR4R;
bsp_output_set(BSP_KEY_OUT_MASK, ~BSP_KEY_OUT3);
delay_us(BSP_READ_AFTER_WRITE_DELAY);
bsp_input = bsp_input_get();
if ((bsp_input & BSP_KEY_IN1) == 0)
result |= 1<<PGDN;
if ((bsp_input & BSP_KEY_IN2) == 0)
result |= 1<<PGUP;
if ((bsp_input & BSP_KEY_IN3) == 0)
result |= 1<<RTN;
if ((bsp_input & BSP_KEY_IN4) == 0)
result |= 1<<MODEL;
bsp_output_set(BSP_KEY_OUT_MASK, ~BSP_KEY_OUT4);
delay_us(BSP_READ_AFTER_WRITE_DELAY);
bsp_input = bsp_input_get();
if ((bsp_input & BSP_KEY_IN1) == 0)
result |= 1<<KEY1;
if ((bsp_input & BSP_KEY_IN2) == 0)
result |= 1<<KEY2;
if ((bsp_input & BSP_KEY_IN3) == 0)
result |= 1<<KEY3;
if ((bsp_input & BSP_KEY_IN4) == 0)
result |= 1<<KEY4;
if (gpio_read(KEYS_GPIO_ENTER) == 0)
result |= 1<<ENT;
syncelem.oldResult = result;
syncelem.ui8ReadInProgress = 0;
bsp_output_set(BSP_KEY_OUT_MASK, 0);
bsp_get_shouldReadKeys();
fct_state[0] = (result & 1<<KEY1)?true:false;
fct_state[1] = (result & 1<<KEY2)?true:false;
fct_state[2] = (result & 1<<KEY3)?true:false;
fct_state[3] = (result & 1<<KEY4)?true:false;
keyState = result;
return result;
}
void keysInit()
{
gpio_init(KEYS_GPIO_ENTER, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
}
uint32_t readKeys()
{
uint32_t result = 0;
uint32_t mkeys = _readKeyMatrix();
if (mkeys & (1 << PGUP)) result |= 1 << KEY_PAGEUP;
if (mkeys & (1 << PGDN)) result |= 1 << KEY_PAGEDN;
if (mkeys & (1 << RTN)) result |= 1 << KEY_EXIT;
if (mkeys & (1 << MODEL)) result |= 1 << KEY_MODEL;
if (mkeys & (1 << ENT)) result |= 1 << KEY_ENTER;
return result;
}
uint32_t readTrims()
{
uint32_t mkeys = _readKeyMatrix();
return mkeys & 0xff; // Mask only the trims output
}
bool getFctKeyState(int index)
{
return fct_state[index];
}
+333
View File
@@ -0,0 +1,333 @@
/*
* 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 "lcd_driver.h"
#include "stm32_gpio.h"
#include "stm32_spi.h"
#include "delays_driver.h"
#include "hal/gpio.h"
#include "lcd.h"
#include "hal.h"
#include "board.h"
#define LCD_NRST_HIGH() gpio_set(LCD_NRST)
#define LCD_NRST_LOW() gpio_clear(LCD_NRST)
#define LCD_COMMAND_MODE() gpio_clear(LCD_SPI_RS)
#define LCD_DATA_MODE() gpio_set(LCD_SPI_RS)
#define CASET 0x2A
#define RASET 0x2B
#define RAMWR 0x2C
static const stm32_spi_t lcdSpi = {
.SPIx = LCD_SPI,
.SCK = LCD_SPI_CLK,
.MISO = LCD_SPI_MISO,
.MOSI = LCD_SPI_MOSI,
.CS = LCD_SPI_CS,
.DMA = LCD_SPI_DMA,
.txDMA_PeriphRequest = LCD_SPI_TX_DMA,
.rxDMA_PeriphRequest = LCD_SPI_RX_DMA,
.txDMA_Stream = LCD_SPI_TX_DMA_STREAM,
.rxDMA_Stream = LCD_SPI_RX_DMA_STREAM,
};
static void* initialFrameBuffer = nullptr;
static void write_start_end(uint8_t cmd, uint16_t start, uint16_t end)
{
// big endian format
uint8_t buf[4] = {
(uint8_t)(start >> 8),
(uint8_t)(start & 0xFF),
(uint8_t)(end >> 8),
(uint8_t)(end & 0xFF),
};
stm32_spi_select(&lcdSpi);
LCD_COMMAND_MODE();
stm32_spi_transfer_byte(&lcdSpi, cmd);
LCD_DATA_MODE();
stm32_spi_transfer_bytes(&lcdSpi, (uint8_t *)buf, nullptr, sizeof(buf));
stm32_spi_unselect(&lcdSpi);
}
static inline void set_column_addr(uint16_t xs, uint16_t xe)
{
write_start_end(CASET, xs, xe);
}
static inline void set_row_addr(uint16_t ys, uint16_t ye)
{
write_start_end(RASET, ys, ye);
}
static void memory_write(const uint16_t* data, uint32_t length)
{
stm32_spi_select(&lcdSpi);
LCD_COMMAND_MODE();
stm32_spi_transfer_byte(&lcdSpi, RAMWR);
LCD_DATA_MODE();
stm32_spi_set_data_width(&lcdSpi, LL_SPI_DATAWIDTH_16BIT);
SCB_CleanDCache_by_Addr((void *)data, length * sizeof(uint16_t));
stm32_spi_dma_transmit_words(&lcdSpi, data, length);
stm32_spi_unselect(&lcdSpi);
stm32_spi_set_data_width(&lcdSpi, LL_SPI_DATAWIDTH_8BIT);
}
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
const rect_t &copy_area)
{
(void)disp_drv;
// TODO: replace through some smarter mechanism without busy wait
while (!gpio_read(LCD_FMARK));
coord_t x1 = copy_area.x;
coord_t x2 = x1 + copy_area.w - 1;
set_column_addr(x1, x2);
coord_t y1 = copy_area.y;
coord_t y2 = y1 + copy_area.h - 1;
set_row_addr(y1, y2);
memory_write(buffer, copy_area.w * copy_area.h);
}
lcdSpiInitFucPtr lcdInitFunction;
lcdSpiInitFucPtr lcdOffFunction;
lcdSpiInitFucPtr lcdOnFunction;
uint32_t lcdPixelClock;
static void lcdSpiConfig(void)
{
stm32_spi_init(&lcdSpi, LL_SPI_DATAWIDTH_8BIT);
stm32_spi_set_max_baudrate(&lcdSpi, LCD_SPI_BAUD);
gpio_init(LCD_FMARK, GPIO_IN, GPIO_PIN_SPEED_HIGH);
gpio_init(LCD_NRST, GPIO_OUT, GPIO_PIN_SPEED_HIGH);
gpio_init(LCD_SPI_RS, GPIO_OUT, GPIO_PIN_SPEED_HIGH);
}
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(120);
}
static void lcdWriteCommand(uint8_t cmd)
{
LCD_COMMAND_MODE();
stm32_spi_select(&lcdSpi);
stm32_spi_transfer_byte(&lcdSpi, cmd);
stm32_spi_unselect(&lcdSpi);
}
// static void lcdWriteReg(uint8_t reg, uint8_t data)
// {
// LCD_COMMAND_MODE();
// stm32_spi_select(&lcdSpi);
// stm32_spi_transfer_byte(&lcdSpi, reg);
// LCD_DATA_MODE();
// stm32_spi_transfer_byte(&lcdSpi, data);
// stm32_spi_unselect(&lcdSpi);
// }
static void lcdWriteData(uint8_t data)
{
LCD_DATA_MODE();
stm32_spi_select(&lcdSpi);
stm32_spi_transfer_byte(&lcdSpi, data);
stm32_spi_unselect(&lcdSpi);
}
// static uint8_t lcdReadReg(uint8_t reg)
// {
// uint8_t data = 0;
// LCD_COMMAND_MODE();
// stm32_spi_select(&lcdSpi);
// stm32_spi_transfer_byte(&lcdSpi, reg);
// LCD_DATA_MODE();
// data = stm32_spi_transfer_byte(&lcdSpi, 0xFF);
// stm32_spi_unselect(&lcdSpi);
// return data;
// }
extern "C" void lcdSetInitalFrameBuffer(void *fbAddress)
{
initialFrameBuffer = fbAddress;
}
static void lcdSetOn(void) { lcdWriteCommand(0x29); }
static void lcdSetOff(void) { lcdWriteCommand(0x28); }
extern "C" void lcdInit()
{
// Configure the LCD SPI + RESET pins
lcdSpiConfig();
stm32_spi_unselect(&lcdSpi);
// hard reset
lcdReset();
// Init command start
lcdWriteCommand( 0xFE );
lcdWriteCommand( 0xEF );
// Display orientation
lcdWriteCommand( 0x36 );
lcdWriteData( 0xE8 );
// Color mode
lcdWriteCommand( 0x3A );
lcdWriteData( 0x05 ); // 16-bit color
// Display control
lcdWriteCommand( 0x86 );
lcdWriteData( 0x98 );
lcdWriteCommand( 0x89 );
lcdWriteData( 0x33 );
lcdWriteCommand( 0x8B );
lcdWriteData( 0x80 );
lcdWriteCommand( 0x8D );
lcdWriteData( 0x33 );
lcdWriteCommand( 0x3A );
lcdWriteData( 0x05 );
lcdWriteCommand( 0x8E );
lcdWriteData( 0x0F );
lcdWriteCommand( 0xEC );
lcdWriteData( 0x33 );
lcdWriteData( 0x07 );
lcdWriteData( 0x00 );
lcdWriteCommand( 0xED );
lcdWriteData( 0x18 );
lcdWriteData( 0x08 );
lcdWriteCommand( 0xE8 );
lcdWriteData( 0x12 );
lcdWriteData( 0x00 );
// Init command ends
lcdWriteCommand( 0xFF );
lcdWriteCommand( 0x62 );
// Display control
lcdWriteCommand( 0x99 );
lcdWriteData( 0x3E );
lcdWriteCommand( 0x9D );
lcdWriteData( 0x4B );
lcdWriteCommand( 0x98 );
lcdWriteData( 0x3E );
lcdWriteCommand( 0x9C );
lcdWriteData( 0x4B );
lcdWriteCommand( 0xC3 );
lcdWriteData( 0x39 );
lcdWriteCommand( 0xC4 );
lcdWriteData( 0x29 );
lcdWriteCommand( 0xC9 );
lcdWriteData( 0x09 );
// Gamma Control
lcdWriteCommand( 0xF0 );
lcdWriteData( 0x0B );
lcdWriteData( 0x0C );
lcdWriteData( 0x07 );
lcdWriteData( 0x07 );
lcdWriteData( 0x05 );
lcdWriteData( 0x22 );
lcdWriteCommand( 0xF1);
lcdWriteData( 0x42 );
lcdWriteData( 0x78 );
lcdWriteData( 0x56 );
lcdWriteData( 0x1E );
lcdWriteData( 0x1A );
lcdWriteData( 0x95 );
lcdWriteCommand( 0xF2 );
lcdWriteData( 0x0B );
lcdWriteData( 0x0C );
lcdWriteData( 0x07 );
lcdWriteData( 0x07 );
lcdWriteData( 0x05 );
lcdWriteData( 0x44 );
lcdWriteCommand( 0xF3 );
lcdWriteData( 0x56 );
lcdWriteData( 0x92 );
lcdWriteData( 0x30 );
lcdWriteData( 0x31 );
lcdWriteData( 0x35 );
lcdWriteData( 0x7F );
// Display orientation
lcdWriteCommand( 0x36 );
lcdWriteData( 0xA0 );
// Display size
lcdWriteCommand( 0x2A );
lcdWriteData( 0x00 );
lcdWriteData( 0x00 );
lcdWriteData( 0x01 );
lcdWriteData( 0x40 );
lcdWriteCommand( 0x2B );
lcdWriteData( 0x00 );
lcdWriteData( 0x00 );
lcdWriteData( 0x00 );
lcdWriteData( 0xF0 );
// No, invert color
lcdWriteCommand( 0x20 );
// Tear on
lcdWriteCommand( 0x35 );
// Exit sleep
lcdWriteCommand( 0x11 );
// Init LCD RAM
memory_write((const uint16_t*)initialFrameBuffer, LCD_W * LCD_H);
lcdSetOn();
lcdOnFunction = lcdSetOn;
lcdOffFunction = lcdSetOff;
lcdSetFlushCb(startLcdRefresh);
}
+42
View File
@@ -0,0 +1,42 @@
/*
* 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 LCD_DELAY() LCD_Delay()
typedef void (*lcdSpiInitFucPtr)(void);
extern lcdSpiInitFucPtr lcdInitFunction;
extern lcdSpiInitFucPtr lcdOffFunction;
extern lcdSpiInitFucPtr lcdOnFunction;
#define LCD_NRST_HIGH() gpio_set(LCD_NRST)
#define LCD_NRST_LOW() gpio_clear(LCD_NRST)
#define LCD_COMMAND_MODE() gpio_clear(LCD_SPI_RS)
#define LCD_DATA_MODE() gpio_set(LCD_SPI_RS)
#endif
+127
View File
@@ -0,0 +1,127 @@
/*
* 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 "stm32_ws2812.h"
#include "boards/generic_stm32/rgb_leds.h"
#include "board.h"
#if defined(LED_STRIP_GPIO)
#include "boards/generic_stm32/rgb_leds.h"
#endif
#define GET_RED(color) (((color) & 0xF80000) >>16)
#define GET_GREEN(color) (((color) & 0x000F800) >> 8)
#define GET_BLUE(color) (((color) & 0xF8))
#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)
// used to map switch number to led number in the rgbled chain
uint8_t ledMapping[] = {4, 6, 0, 2};
void fsLedRGB(uint8_t index, uint32_t color)
{
ws2812_set_color(ledMapping[index], GET_RED(color),
GET_GREEN(color),GET_BLUE(color));
ws2812_set_color(ledMapping[index]+1, GET_RED(color),
GET_GREEN(color),GET_BLUE(color));
}
uint32_t fsGetLedRGB(uint8_t index)
{
return rgbGetLedColor(ledMapping[index]);
}
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()
{
ws2812_set_color(8, 0, 0, 0);
ws2812_set_color(9, 0, 0, 0);
}
void ledRed()
{
ws2812_set_color(8, 20, 0, 0);
ws2812_set_color(9, 20, 0, 0);
}
void ledGreen()
{
ws2812_set_color(8, 0, 20, 0);
ws2812_set_color(9, 0, 20, 0);
}
void ledBlue()
{
ws2812_set_color(8, 0, 0, 20);
ws2812_set_color(9, 0, 0, 20);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* 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
constexpr coord_t INPUT_EDIT_CURVE_WIDTH = 132;
constexpr coord_t INPUT_EDIT_CURVE_HEIGHT = INPUT_EDIT_CURVE_WIDTH;
constexpr coord_t MENUS_MAX_HEIGHT = (MENUS_LINE_HEIGHT * 8) + 8;
+279
View File
@@ -0,0 +1,279 @@
/*
* 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_3
#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)
{
// __HAL_RCC_SYSCFG_CLK_ENABLE(); // needed for syscfg register, to route P2C and P3C pins to the AF
/*-- GPIOs 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(GPIOC, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
gpio_init_af(GPIO_PIN(GPIOC, 2), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
gpio_init_af(GPIO_PIN(GPIOC, 3), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
}
extern "C" void SDRAM_InitSequence(void)
{
FMC_SDRAM_CommandTypeDef FMC_SDRAMCommandStructure;
uint32_t tmpr = 0;
uint32_t timeout = SDRAM_TIMEOUT;
/* Step 3 --------------------------------------------------------------------*/
/* Configure a clock configuration enable command */
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
// while((__FMC_SDRAM_GET_FLAG(FMC_Bank5_6_R, FMC_SDRAM_FLAG_BUSY) != 0) &&
// (timeout > 0))
// {
// timeout--;
// }
/* 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_BANK1;
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
// timeout = SDRAM_TIMEOUT;
// while((__FMC_SDRAM_GET_FLAG(FMC_Bank5_6_R, FMC_SDRAM_FLAG_BUSY) != 0) && (timeout > 0))
// {
// timeout--;
// }
/* Send the command */
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
// delay_ms(1);
/* Step 6 --------------------------------------------------------------------*/
/* Configure a Auto-Refresh command */
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
FMC_SDRAMCommandStructure.AutoRefreshNumber = 8;
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
/* Wait until the SDRAM controller is ready */
// timeout = SDRAM_TIMEOUT;
// while((__FMC_SDRAM_GET_FLAG(FMC_Bank5_6_R, FMC_SDRAM_FLAG_BUSY) != 0) &&
// (timeout > 0))
// {
// timeout--;
// }
/* Send the command */
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
// delay_ms(1);
/* 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_BANK1;
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.ModeRegisterDefinition = tmpr;
/* Wait until the SDRAM controller is ready */
// timeout = SDRAM_TIMEOUT;
// while((__FMC_SDRAM_GET_FLAG(FMC_Bank5_6_R, FMC_SDRAM_FLAG_BUSY) != 0) && (timeout > 0))
// {
// timeout--;
// }
/* Send the command */
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
// delay_ms(1);
/* 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);
/* Wait until the SDRAM controller is ready */
// timeout = SDRAM_TIMEOUT;
// while((__FMC_SDRAM_GET_FLAG(FMC_Bank5_6_R, FMC_SDRAM_FLAG_BUSY) != 0) && (timeout > 0))
// {
// timeout--;
// }
// delay_ms(1);
}
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_BANK1;
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_BANK1);
__FMC_ENABLE();
/* FMC SDRAM device initialization sequence */
SDRAM_InitSequence();
uint32_t data = 0x12345678;
uint32_t* base = (uint32_t*)0xc0000000;
while(true&&0)
{
uint32_t dataStart = data;
uint32_t buf=dataStart;
for(int i=0; i<(8*1024*1024)/4; ++i)
{
base[i] = buf;
__asm__ ("ror %0, %1, %2" : "=r" (buf) : "r" (buf), "M" (1));
}
buf=dataStart;
SCB_CleanDCache();
delay_ms(100);
SCB_InvalidateDCache();
for(int i=0; i<(8*1024*1024)/4; ++i)
{
if(base[i] != buf)
asm("bkpt");
__asm__ ("ror %0, %1, %2" : "=r" (buf) : "r" (buf), "M" (1));
}
__asm__ ("ror %0, %1, %2" : "=r" (data) : "r" (data), "M" (1));
}
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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_EXTERNAL_SOURCE_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(200);
LL_RCC_PLL1_SetP(2);
LL_RCC_PLL1_SetQ(4);
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_PLL2Q_Enable();
LL_RCC_PLL2R_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(3);
LL_RCC_PLL2_SetN(240);
LL_RCC_PLL2_SetP(12);
LL_RCC_PLL2_SetQ(2);
LL_RCC_PLL2_SetR(4);
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(3);
LL_RCC_PLL3_SetN(240);
LL_RCC_PLL3_SetP(5);
LL_RCC_PLL3_SetQ(20);
LL_RCC_PLL3_SetR(80);
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_SetFMCClockSource(LL_RCC_FMC_CLKSOURCE_HCLK);
LL_RCC_SetSPIClockSource(LL_RCC_SPI123_CLKSOURCE_PLL3P);
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL3Q);
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_CLKP);
}
+23
View File
@@ -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();
+29
View File
@@ -0,0 +1,29 @@
/*
* 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 _USB_DESCRIPTOR_H_
#define _USB_DESCRIPTOR_H_
#define USB_NAME "PA01"
#define USB_MANUFACTURER 'F', 'l', 'y', 'S', 'k', 'y', ' ', ' ' /* 8 bytes */
#define USB_PRODUCT 'P', 'A', '0', '1', ' ', ' ', ' ', ' ' /* 8 Bytes */
#endif // _USB_DESCRIPTOR_H_
+23
View File
@@ -982,6 +982,29 @@ LEGACY_NAMES = [
},
},
},
{
"targets": {"pa01"},
"inputs": {
"LH": {"yaml": "Rud", "lua": "rud", "description": "Rudder"},
"LV": {"yaml": "Ele", "lua": "ele", "description": "Elevator"},
"RV": {"yaml": "Thr", "lua": "thr", "description": "Throttle"},
"RH": {"yaml": "Ail", "lua": "ail", "description": "Aileron"},
"SL1": {
"yaml": "SLIDER1",
"lua": "ls",
"label": "LS",
"short_label": "L",
"description": "Left slider"
},
"SL2": {
"yaml": "SLIDER2",
"lua": "rs",
"label": "RS",
"short_label": "R",
"description": "Right slider",
},
},
},
{
"targets": {"h747", "h7rs"},
"inputs": {
+4
View File
@@ -244,6 +244,10 @@ POT_CONFIG = {
"SL1": {"default": "SLIDER"},
"SL2": {"default": "SLIDER"},
},
"pa01": {
"SL1": {"default": "SLIDER"},
"SL2": {"default": "SLIDER"},
},
}
+13
View File
@@ -105,6 +105,19 @@ SWITCH_CONFIG = {
"SO": {"default": "2POS"},
"SP": {"default": "2POS"},
},
"pa01": {
"SA": { "default": "2POS" },
"SB": { "default": "3POS" },
"SC": { "default": "3POS" },
"SD": { "default": "TOGGLE" },
"SE": { "default": "TOGGLE" },
"SF": { "default": "TOGGLE" },
# custom switches
"SK": {"default": "2POS"},
"SL": {"default": "2POS"},
"SM": {"default": "2POS"},
"SN": {"default": "2POS"},
},
"lr3pro": {
# left side
"SA": {"default": "3POS", "display": [0, 0]},
+3
View File
@@ -158,6 +158,9 @@ get_target_build_options() {
st16)
BUILD_OPTIONS+="-DPCB=ST16 -DNANO=NO"
;;
pa01)
BUILD_OPTIONS+="-DPCB=PA01 -DNANO=NO"
;;
*)
echo "Unknown target: $target_name"
return 1
+1 -1
View File
@@ -211,7 +211,7 @@ declare -a simulator_plugins=(
zorro tx16s
commando8 boxer pocket mt12 gx12
tlite tpro tprov2 tpros bumblebee lr3pro t14
nv14 el18 pl18 pl18ev pl18u st16
nv14 el18 pl18 pl18ev pl18u st16 pa01
f16 v14 v16
)
+1 -1
View File
@@ -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"}
: ${FLAVOR:="t15;tx16s;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;pa01"}
: ${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"}