feat: Radiomaster TX15 support (#6484)
Co-authored-by: Malte Langermann <54738901+gagarinlg@users.noreply.github.com> Co-authored-by: 3djc <3djc@gh.com> Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com> Co-authored-by: philmoz <phil.a.mitchell@gmail.com> Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
This commit is contained in:
co-authored by
Malte Langermann
3djc
raphaelcoeffic
philmoz
Peter Feerick
parent
3a00c0812b
commit
324b2c7761
@@ -43,6 +43,7 @@ jobs:
|
||||
matrix:
|
||||
target:
|
||||
- x9dp2019
|
||||
- tx15
|
||||
- tx16s
|
||||
- nv14
|
||||
- el18
|
||||
@@ -99,6 +100,7 @@ jobs:
|
||||
- tprov2;tpros;bumblebee
|
||||
- t20;t20v2;t14
|
||||
- tx12mk2;boxer;gx12
|
||||
- tx15
|
||||
- tx16s
|
||||
- f16
|
||||
- v12;v14;v16
|
||||
|
||||
@@ -36,6 +36,7 @@ jobs:
|
||||
- mt12
|
||||
- nb4p
|
||||
- st16
|
||||
- tx15
|
||||
container:
|
||||
image: ghcr.io/edgetx/edgetx-dev:latest
|
||||
volumes:
|
||||
|
||||
@@ -135,6 +135,8 @@ uint32_t Boards::getFourCC(Type board)
|
||||
return 0x4078746F;
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return 0x3878746F;
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
return 0x4978746F;
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
return 0x4178746F;
|
||||
case BOARD_RADIOMASTER_TX12_MK2:
|
||||
@@ -210,6 +212,7 @@ int Boards::getEEpromSize(Board::Type board)
|
||||
case BOARD_JUMPER_T16:
|
||||
case BOARD_JUMPER_T18:
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
case BOARD_FLYSKY_NV14:
|
||||
case BOARD_FLYSKY_EL18:
|
||||
case BOARD_FLYSKY_PA01:
|
||||
@@ -269,6 +272,7 @@ int Boards::getFlashSize(Type board)
|
||||
case BOARD_JUMPER_T16:
|
||||
case BOARD_JUMPER_T18:
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
case BOARD_FLYSKY_NV14:
|
||||
case BOARD_FLYSKY_EL18:
|
||||
case BOARD_FLYSKY_PA01: // 8MB SDRAM
|
||||
@@ -380,7 +384,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
case LcdHeight:
|
||||
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board))
|
||||
return 480;
|
||||
else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_FLYSKY_ST16(board))
|
||||
else if (IS_FAMILY_PL18(board) || IS_JUMPER_T15(board) || IS_FLYSKY_ST16(board) || IS_RADIOMASTER_TX15(board))
|
||||
return 320;
|
||||
else if (IS_FLYSKY_PA01(board))
|
||||
return 240;
|
||||
@@ -390,11 +394,11 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
return 64;
|
||||
|
||||
case LcdWidth:
|
||||
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PA01(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;
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board) || IS_RADIOMASTER_TX15(board))
|
||||
return 480;
|
||||
else if (IS_TARANIS_SMALL(board))
|
||||
return 128;
|
||||
@@ -418,7 +422,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) || IS_FLYSKY_PA01(board);
|
||||
return IS_RADIOMASTER_GX12(board) || IS_FLYSKY_ST16(board) || IS_FLYSKY_PA01(board) || IS_RADIOMASTER_TX15(board);
|
||||
|
||||
default:
|
||||
return getBoardJson(board)->getCapability(capability);
|
||||
@@ -648,6 +652,8 @@ QString Boards::getBoardName(Board::Type board)
|
||||
return "Radiomaster TX12 Mark II";
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return "Radiomaster TX16S";
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
return "Radiomaster TX15";
|
||||
case BOARD_RADIOMASTER_ZORRO:
|
||||
return "Radiomaster Zorro";
|
||||
case BOARD_RADIOMASTER_GX12:
|
||||
@@ -782,6 +788,7 @@ int Boards::getDefaultInternalModules(Board::Type board)
|
||||
case BOARD_FATFISH_F16:
|
||||
case BOARD_HELLORADIOSKY_V14:
|
||||
case BOARD_HELLORADIOSKY_V16:
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
case BOARD_IFLIGHT_COMMANDO8:
|
||||
case BOARD_JUMPER_BUMBLEBEE:
|
||||
case BOARD_JUMPER_T12MAX:
|
||||
@@ -848,6 +855,7 @@ void Boards::getBattRange(Board::Type board, int& vmin, int& vmax, unsigned int&
|
||||
case BOARD_X10:
|
||||
case BOARD_X10_EXPRESS:
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
case BOARD_RADIOMASTER_TX15:
|
||||
case BOARD_JUMPER_T16:
|
||||
case BOARD_JUMPER_T18:
|
||||
case BOARD_JUMPER_T20:
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace Board {
|
||||
BOARD_JUMPER_T15,
|
||||
BOARD_JUMPER_T16,
|
||||
BOARD_RADIOMASTER_TX16S,
|
||||
BOARD_RADIOMASTER_TX15,
|
||||
BOARD_JUMPER_T18,
|
||||
BOARD_JUMPER_T20,
|
||||
BOARD_RADIOMASTER_TX12,
|
||||
@@ -561,6 +562,11 @@ inline bool IS_RADIOMASTER_TX16S(Board::Type board)
|
||||
return board == Board::BOARD_RADIOMASTER_TX16S;
|
||||
}
|
||||
|
||||
inline bool IS_RADIOMASTER_TX15(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_RADIOMASTER_TX15;
|
||||
}
|
||||
|
||||
inline bool IS_RADIOMASTER_TX12(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_RADIOMASTER_TX12;
|
||||
@@ -618,12 +624,13 @@ inline bool IS_HELLORADIOSKY_V16(Board::Type board)
|
||||
|
||||
inline bool IS_FAMILY_T16(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_JUMPER_T15 ||
|
||||
return board == Board::BOARD_JUMPER_T15 ||
|
||||
board == Board::BOARD_JUMPER_T16 ||
|
||||
board == Board::BOARD_JUMPER_T18 ||
|
||||
board == Board::BOARD_RADIOMASTER_TX16S ||
|
||||
board == Board::BOARD_FATFISH_F16 ||
|
||||
board == Board::BOARD_HELLORADIOSKY_V16;
|
||||
board == Board::BOARD_HELLORADIOSKY_V16 ||
|
||||
board == Board::BOARD_RADIOMASTER_TX15;
|
||||
}
|
||||
|
||||
inline bool IS_FAMILY_T12(Board::Type board)
|
||||
|
||||
@@ -233,6 +233,8 @@ void GeneralSettings::init()
|
||||
strcpy(bluetoothName, "pl18u");
|
||||
else if (IS_FLYSKY_ST16(board))
|
||||
strcpy(bluetoothName, "st16");
|
||||
else if (IS_RADIOMASTER_TX15(board))
|
||||
strcpy(bluetoothName, "tx15");
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
strcpy(bluetoothName, "horus");
|
||||
else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board))
|
||||
|
||||
@@ -326,7 +326,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
IS_JUMPER_T15(board) || IS_JUMPER_T18(board) || IS_JUMPER_T20(board) || IS_JUMPER_TPRO(board) ||
|
||||
IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_GX12(board) || IS_RADIOMASTER_MT12(board) ||
|
||||
IS_RADIOMASTER_POCKET(board) || IS_RADIOMASTER_TX12(board) || IS_RADIOMASTER_TX12_MK2(board) ||
|
||||
IS_RADIOMASTER_TX16S(board) || IS_RADIOMASTER_ZORRO(board));
|
||||
IS_RADIOMASTER_TX16S(board) || IS_RADIOMASTER_ZORRO(board) || IS_RADIOMASTER_TX15(board));
|
||||
case HasSoftwareSerialPower:
|
||||
return IS_RADIOMASTER_TX16S(board);
|
||||
case HasIntModuleMulti:
|
||||
@@ -818,6 +818,13 @@ void registerOpenTxFirmwares()
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* Radiomaster TX15 board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("tx15"), Firmware::tr("Radiomaster TX15"), BOARD_RADIOMASTER_TX15);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
firmware->addOptionsGroup({opt_bt, opt_internal_gps});
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* Radiomaster TX16S board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("tx16s"), Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
["Jumper T-Pro V2", "tprov2-"],
|
||||
["Jumper T-Pro S", "tpros-"],
|
||||
["RadioMaster Boxer", "boxer-"],
|
||||
["RadioMaster GX12", "gx12-"]
|
||||
["RadioMaster MT12","mt12-"],
|
||||
["RadioMaster Pocket", "pocket-"],
|
||||
["RadioMaster TX12MK2", "tx12mk2-"],
|
||||
["RadioMaster TX15", "tx15s-"],
|
||||
["RadioMaster TX16S", "tx16s-"],
|
||||
["RadioMaster Zorro","zorro-"],
|
||||
["RadioMaster GX12", "gx12-"]
|
||||
],
|
||||
"changelog": "- Major initial bug fixes"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include(CMakeForceCompiler)
|
||||
include(Bitmaps)
|
||||
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 ST16 PA01)
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18 ST16 PA01 TX15)
|
||||
set(RADIO_LANGUAGES CN CZ DA DE EN ES FI FR HE HU IT JP KO NL PL PT RU SE SK TW UA)
|
||||
set(TTS_LANGUAGES CN CZ DA DE EN ES FR HE HU IT JP KO NL PL PT RU SE SK UA)
|
||||
|
||||
@@ -90,6 +90,8 @@ elseif(PCB STREQUAL ST16)
|
||||
include(targets/st16/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL PA01)
|
||||
include(targets/pa01/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL TX15)
|
||||
include(targets/tx15/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)
|
||||
@@ -626,6 +628,12 @@ if (DEFINED TARGET_EXTRAM_SIZE)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DEFINED TARGET_PSRAM_START)
|
||||
target_link_options(firmware PRIVATE
|
||||
-Wl,--defsym=__PSRAM_START__=${TARGET_PSRAM_START}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LUA)
|
||||
# Lua needs %g and %f
|
||||
target_link_options(firmware PRIVATE
|
||||
|
||||
@@ -79,7 +79,9 @@ static void rgbLedStart()
|
||||
LED_STRIP_REFRESH_PERIOD, true);
|
||||
}
|
||||
|
||||
timer_start(&_refresh_timer);
|
||||
if (timer_start(&_refresh_timer) != 0) {
|
||||
TRACE("Failed to start RGB LED refresh timer");
|
||||
};
|
||||
}
|
||||
|
||||
void rgbLedStop()
|
||||
|
||||
@@ -83,6 +83,12 @@ if (DEFINED TARGET_EXTRAM_SIZE)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DEFINED TARGET_PSRAM_START)
|
||||
target_link_options(bootloader PRIVATE
|
||||
-Wl,--defsym=__PSRAM_START__=${TARGET_PSRAM_START}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (ENABLE_BOOTLOADER_DEBUG)
|
||||
target_compile_definitions(board_bl PRIVATE -DDEBUG)
|
||||
target_compile_definitions(bootloader PRIVATE -DDEBUG)
|
||||
|
||||
@@ -114,10 +114,6 @@ void bootloaderInitApp()
|
||||
rotaryEncoderInit();
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
initSerialPorts();
|
||||
#endif
|
||||
|
||||
__enable_irq();
|
||||
|
||||
TRACE("\nBootloader started :)");
|
||||
|
||||
@@ -88,7 +88,7 @@ static inline void check_struct()
|
||||
|
||||
#if defined(PCBXLITES)
|
||||
CHKSIZE(RadioData, 945);
|
||||
#elif defined(RADIO_ST16) || defined(PCBPA01)
|
||||
#elif defined(RADIO_ST16) || defined(PCBPA01) || defined(RADIO_TX15)
|
||||
CHKSIZE(RadioData, 1159);
|
||||
#elif defined(COLORLCD)
|
||||
CHKSIZE(RadioData, 1039);
|
||||
@@ -126,6 +126,8 @@ static inline void check_struct()
|
||||
CHKSIZE(ModelData, 27522);
|
||||
#elif defined(RADIO_T15)
|
||||
CHKSIZE(ModelData, 27683);
|
||||
#elif defined(RADIO_TX15)
|
||||
CHKSIZE(ModelData, 27761);
|
||||
#elif defined(RADIO_H7RS)
|
||||
// CHKSIZE()
|
||||
#elif defined(PCBHORUS)
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
WARNING: while this ICM42607C belong to the ICM426xx familly, it is NOT compatible
|
||||
with code for generic ICM4267XX. All register have different addresses
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal/i2c_driver.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "icm42607C.h"
|
||||
#include "imu_filter.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "inactivity_timer.h"
|
||||
#include "hal.h"
|
||||
|
||||
int16_t getGyroTemperature()
|
||||
{
|
||||
uint8_t reg = TEMP_DATA_X0_REG;
|
||||
uint8_t buf[2] = {0};
|
||||
|
||||
if (stm32_i2c_read(IMU_I2C_BUS, ICM426xx_I2C_ADDR, reg, 1, buf, 2, 1000) < 0) {
|
||||
TRACE("ICM426xx ERROR: TEMP_DATA_X0_REG i2c read error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (((buf[0] << 8) | buf[1]) / 128) + 25;
|
||||
}
|
||||
|
||||
int write_cmd(uint8_t reg, uint8_t val)
|
||||
{
|
||||
return i2c_write(IMU_I2C_BUS, ICM426xx_I2C_ADDR, reg, 1, &val, 1);
|
||||
}
|
||||
|
||||
#if defined(IMU_INT_GPIO)
|
||||
static void imu_exti_isr(void)
|
||||
{
|
||||
inactivityTimerReset(ActivitySource::MainControls);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int write_mreg1(uint8_t reg, uint8_t val) {
|
||||
if (write_cmd(BLK_SEL_W_REG, 0x00) < 0) return -1;
|
||||
if (write_cmd(MADDR_W_REG, reg) < 0) return -1;
|
||||
if (write_cmd(M_W_REG, val) < 0) return -1;
|
||||
delay_us(10); //42627-pdf p12“Accessing MREG1, MREG2 And MREG3 Registers
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gyroInit(void)
|
||||
{
|
||||
TRACE("ICM426xx I2C Init");
|
||||
|
||||
if (i2c_init(IMU_I2C_BUS) < 0) {
|
||||
TRACE("ICM426xx ERROR: i2c_init bus error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_dev_ready(IMU_I2C_BUS, ICM426xx_I2C_ADDR) < 0) {
|
||||
TRACE("ICM426xx device init error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t data = 0;
|
||||
if (stm32_i2c_read(IMU_I2C_BUS, ICM426xx_I2C_ADDR, 0x75, 1, &data, 1, 1000) < 0) {
|
||||
TRACE("ICM426xx ERROR: i2c read error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data != 0x61) {
|
||||
TRACE("ICM426xx ERROR: this code only works on ICM42607C");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(write_cmd(SIGNAL_PATH_RESET, SOFT_RESET_CMD) < 0) {
|
||||
TRACE("ICM426xx ERROR: SOFT_RESET_CMD error");
|
||||
return -1;
|
||||
}
|
||||
delay_ms(100);
|
||||
|
||||
if(write_cmd(PWR_MGMT0_REG, PWR_MGMT0_ENABLE) < 0) {
|
||||
TRACE("ICM426xx ERROR: PWR_MGMT0_REG error");
|
||||
return -1;
|
||||
}
|
||||
delay_ms(10);
|
||||
|
||||
// Set gyro to 2000 dps, 1kHz ODR
|
||||
if(write_cmd(GYRO_CONFIG0_REG, GYRO_ODR_1KHZ) < 0) {
|
||||
TRACE("ICM426xx ERROR: GYRO_CONFIG0_REG error");
|
||||
return -1;
|
||||
}
|
||||
delay_ms(1);
|
||||
|
||||
// Set accel to ±4g, 1kHz ODR
|
||||
if (write_cmd(ACCEL_CONFIG0_REG, ACCEL_ODR_1KHZ) < 0) {
|
||||
TRACE("ICM426xx ERROR: ACCEL_CONFIG0_REG error");
|
||||
return -1;
|
||||
}
|
||||
delay_ms(1);
|
||||
|
||||
|
||||
if (write_cmd(INT_CONFIG_REG, 0x00) < 0) {
|
||||
TRACE("ICM426xx ERROR: INT_CONFIG_REG error");
|
||||
return -1;
|
||||
}
|
||||
delay_ms(1);
|
||||
|
||||
#if defined(IMU_INT_GPIO)
|
||||
// CCEL_WOM_X_THR:0-255(0-1g),0x10--16mg
|
||||
if (write_mreg1(ACCEL_WOM_X_THR_REG, 0xFE) < 0) return -1;
|
||||
if (write_mreg1(ACCEL_WOM_Y_THR_REG, 0xFE) < 0) return -1;
|
||||
if (write_mreg1(ACCEL_WOM_Z_THR_REG, 0xFE) < 0) return -1;
|
||||
|
||||
delay_ms(1);
|
||||
// config WoM
|
||||
if (write_cmd(WOM_CONFIG_REG, 0x03) < 0) return -1; // OR mode
|
||||
delay_ms(1);
|
||||
// enable INT1
|
||||
if (write_cmd(INT_SOURCE1_REG, 0x07) < 0) return -1; // XYZ interrupt
|
||||
delay_ms(1);
|
||||
// config INT1 pin
|
||||
if (write_cmd(INT_CONFIG_REG, 0x00) < 0) return -1;
|
||||
|
||||
gpio_init_int(IMU_INT_GPIO, GPIO_IN_PU, GPIO_FALLING, imu_exti_isr);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gyroRead(uint8_t buffer[IMU_BUFFER_LENGTH])
|
||||
{
|
||||
IMU_RawData_t imu_raw;
|
||||
IMU_FilteredData_t *filtered;
|
||||
|
||||
uint8_t buf[6];
|
||||
uint8_t reg = GYRO_DATA_X0_REG;
|
||||
if (stm32_i2c_read(IMU_I2C_BUS, ICM426xx_I2C_ADDR, reg, 1, buf, 6, 1000) < 0) {
|
||||
TRACE("ICM426xx ERROR: i2c read error");
|
||||
return -1;
|
||||
}
|
||||
imu_raw.gyro_x = -((int16_t)(buf[0] << 8) | buf[1]); // x
|
||||
imu_raw.gyro_y = -((int16_t)(buf[2] << 8) | buf[3]); // y
|
||||
imu_raw.gyro_z = ((int16_t)(buf[4] << 8) | buf[5]); // z
|
||||
|
||||
reg = ACCEL_DATA_X0_REG;
|
||||
if (stm32_i2c_read(IMU_I2C_BUS, ICM426xx_I2C_ADDR, reg, 1, buf, 6, 1000) < 0) {
|
||||
TRACE("ICM426xx ERROR: i2c read error");
|
||||
return -1;
|
||||
}
|
||||
imu_raw.accel_x = ((int16_t)(buf[0] << 8) | buf[1]); // x
|
||||
imu_raw.accel_y = ((int16_t)(buf[2] << 8) | buf[3]); // y
|
||||
imu_raw.accel_z = ((int16_t)(buf[4] << 8) | buf[5]); // z
|
||||
|
||||
// Process through filters
|
||||
process_imu_data(&imu_raw);
|
||||
filtered = get_filtered_imu_data();
|
||||
|
||||
*(int16_t*)&buffer[6] = -(int16_t)filtered->accel_x; // x
|
||||
*(int16_t*)&buffer[8] = -(int16_t)filtered->accel_y; // y
|
||||
*(int16_t*)&buffer[10] = (int16_t)filtered->accel_z; // z
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
WARNING: while this ICM42607C belong to the ICM426xx familly, it is NOT compatible
|
||||
with code for generic ICM4267XX. All register have different addresses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ICM426xx_I2C_ADDR 0x68
|
||||
|
||||
// Register addresses
|
||||
#define WHO_AM_I_REG 0x75
|
||||
#define PWR_MGMT0_REG 0x1F
|
||||
#define SIGNAL_PATH_RESET 0x02
|
||||
#define ACCEL_CONFIG0_REG 0x21
|
||||
#define GYRO_CONFIG0_REG 0x20
|
||||
#define INT_CONFIG_REG 0x06
|
||||
#define TEMP_DATA_X0_REG 0x09
|
||||
|
||||
// Config values
|
||||
#define SOFT_RESET_CMD 0x10
|
||||
|
||||
#define PWR_MGMT0_ENABLE 0x0F // ACCEL_LNM + GYRO_LNM
|
||||
#define ACCEL_ODR_1KHZ 0x45 // Accel 1 kHz ±4g
|
||||
#define GYRO_ODR_1KHZ 0x05 // Gyro 1 kHz ±2000 dps
|
||||
|
||||
#define GYRO_DATA_X0_REG 0x11
|
||||
#define ACCEL_DATA_X0_REG 0x0B
|
||||
|
||||
#define BLK_SEL_W_REG 0x79
|
||||
#define MADDR_W_REG 0x7A
|
||||
#define M_W_REG 0x7B
|
||||
#define ACCEL_WOM_X_THR_REG 0x4B
|
||||
#define ACCEL_WOM_Y_THR_REG 0x4C
|
||||
#define ACCEL_WOM_Z_THR_REG 0x4D
|
||||
#define WOM_CONFIG_REG 0x27
|
||||
#define INT_SOURCE1_REG 0x2C
|
||||
#define INT_CONFIG_REG 0x06
|
||||
#define INT_STATUS2_REG 0x3B
|
||||
|
||||
typedef struct {
|
||||
float fTemperatureDegC; //°C
|
||||
float fAccX, fAccY, fAccZ; // m/s^2
|
||||
float fGyroXradps, fGyroYradps, fGyroZradps; // rad/s
|
||||
} sIMUoutput;
|
||||
|
||||
extern sIMUoutput IMUoutput;
|
||||
|
||||
int gyroInit(void);
|
||||
int gyroRead(unsigned char*);
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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 "imu_filter.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
// Filter parameters
|
||||
#define COMPLEMENTARY_ALPHA 0.92f // Complementary filter coefficient
|
||||
#define LP_FILTER_ALPHA 0.9f // Low-pass filter coefficient
|
||||
#define SAMPLE_TIME_S 0.005f // Gyro is read every 5ms as part of execMixerFrequentActions()
|
||||
#define RAD_TO_DEG 57.2958f
|
||||
#define DEG_TO_RAD 0.0174533f
|
||||
|
||||
// Filter state variables
|
||||
static IMU_FilteredData_t filtered_data = {0};
|
||||
static float prev_accel[3] = {0};
|
||||
static float prev_gyro[3] = {0};
|
||||
static uint8_t filter_initialized = 0;
|
||||
|
||||
// Low-pass filter implementation
|
||||
float low_pass_filter(float new_value, float prev_value, float alpha) {
|
||||
return alpha * prev_value + (1.0f - alpha) * new_value;
|
||||
}
|
||||
|
||||
// Calculate roll and pitch from accelerometer data
|
||||
void calculate_accel_angles(float ax, float ay, float az, float *roll, float *pitch) {
|
||||
// Normalize accelerometer data
|
||||
float norm = sqrtf(ax*ax + ay*ay + az*az);
|
||||
if (norm == 0.0f) return;
|
||||
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
az /= norm;
|
||||
|
||||
// Calculate angles
|
||||
*roll = atan2f(ay, sqrtf(ax*ax + az*az));
|
||||
*pitch = atan2f(-ax, sqrtf(ay*ay + az*az));
|
||||
}
|
||||
|
||||
// Complementary filter for attitude estimation
|
||||
void complementary_filter(IMU_RawData_t *raw_data, float dt) {
|
||||
float accel_roll, accel_pitch;
|
||||
|
||||
// Calculate angles from accelerometer
|
||||
calculate_accel_angles(raw_data->accel_x, raw_data->accel_y, raw_data->accel_z,
|
||||
&accel_roll, &accel_pitch);
|
||||
|
||||
if (!filter_initialized) {
|
||||
// Initialize filter with accelerometer angles
|
||||
filtered_data.roll = accel_roll;
|
||||
filtered_data.pitch = accel_pitch;
|
||||
filtered_data.yaw = 0.0f;
|
||||
filter_initialized = 1;
|
||||
} else {
|
||||
// Integrate gyroscope data
|
||||
float gyro_roll = filtered_data.roll + raw_data->gyro_x * dt;
|
||||
float gyro_pitch = filtered_data.pitch + raw_data->gyro_y * dt;
|
||||
float gyro_yaw = filtered_data.yaw + raw_data->gyro_z * dt;
|
||||
|
||||
// Apply complementary filter
|
||||
filtered_data.roll = COMPLEMENTARY_ALPHA * gyro_roll +
|
||||
(1.0f - COMPLEMENTARY_ALPHA) * accel_roll;
|
||||
filtered_data.pitch = COMPLEMENTARY_ALPHA * gyro_pitch +
|
||||
(1.0f - COMPLEMENTARY_ALPHA) * accel_pitch;
|
||||
filtered_data.yaw = gyro_yaw; // No magnetometer correction in this example
|
||||
|
||||
// Keep yaw within -π to π range
|
||||
while (filtered_data.yaw > M_PI) filtered_data.yaw -= 2.0f * M_PI;
|
||||
while (filtered_data.yaw < -M_PI) filtered_data.yaw += 2.0f * M_PI;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply low-pass filter to raw sensor data
|
||||
void apply_lowpass_filter(IMU_RawData_t *raw_data) {
|
||||
// Filter accelerometer data
|
||||
filtered_data.accel_x = low_pass_filter(raw_data->accel_x, prev_accel[0], LP_FILTER_ALPHA);
|
||||
filtered_data.accel_y = low_pass_filter(raw_data->accel_y, prev_accel[1], LP_FILTER_ALPHA);
|
||||
filtered_data.accel_z = low_pass_filter(raw_data->accel_z, prev_accel[2], LP_FILTER_ALPHA);
|
||||
|
||||
// Filter gyroscope data
|
||||
filtered_data.gyro_x = low_pass_filter(raw_data->gyro_x, prev_gyro[0], LP_FILTER_ALPHA);
|
||||
filtered_data.gyro_y = low_pass_filter(raw_data->gyro_y, prev_gyro[1], LP_FILTER_ALPHA);
|
||||
filtered_data.gyro_z = low_pass_filter(raw_data->gyro_z, prev_gyro[2], LP_FILTER_ALPHA);
|
||||
|
||||
// Update previous values
|
||||
prev_accel[0] = filtered_data.accel_x;
|
||||
prev_accel[1] = filtered_data.accel_y;
|
||||
prev_accel[2] = filtered_data.accel_z;
|
||||
|
||||
prev_gyro[0] = filtered_data.gyro_x;
|
||||
prev_gyro[1] = filtered_data.gyro_y;
|
||||
prev_gyro[2] = filtered_data.gyro_z;
|
||||
}
|
||||
|
||||
// Main IMU filter processing function
|
||||
void process_imu_data(IMU_RawData_t *raw_data) {
|
||||
// Apply low-pass filtering to raw data
|
||||
apply_lowpass_filter(raw_data);
|
||||
|
||||
// Apply complementary filter for attitude estimation
|
||||
complementary_filter(raw_data, SAMPLE_TIME_S);
|
||||
}
|
||||
|
||||
// Get filtered IMU data
|
||||
IMU_FilteredData_t* get_filtered_imu_data(void) {
|
||||
return &filtered_data;
|
||||
}
|
||||
|
||||
// Reset filter state
|
||||
void reset_imu_filter(void) {
|
||||
memset(&filtered_data, 0, sizeof(filtered_data));
|
||||
memset(prev_accel, 0, sizeof(prev_accel));
|
||||
memset(prev_gyro, 0, sizeof(prev_gyro));
|
||||
filter_initialized = 0;
|
||||
}
|
||||
|
||||
// Advanced Kalman filter structure (optional implementation)
|
||||
typedef struct {
|
||||
float Q_angle; // Process noise variance for accelerometer
|
||||
float Q_bias; // Process noise variance for gyro bias
|
||||
float R_measure; // Measurement noise variance
|
||||
float angle; // Estimated angle
|
||||
float bias; // Estimated bias
|
||||
float rate; // Unbiased rate
|
||||
float P[2][2]; // Error covariance matrix
|
||||
} kalman_state_t;
|
||||
|
||||
// Kalman filter implementation (more advanced option)
|
||||
float kalman_filter(kalman_state_t *state, float new_angle, float new_rate, float dt) {
|
||||
// Prediction step
|
||||
state->rate = new_rate - state->bias;
|
||||
state->angle += dt * state->rate;
|
||||
|
||||
// Update error covariance
|
||||
state->P[0][0] += dt * (dt * state->P[1][1] - state->P[0][1] - state->P[1][0] + state->Q_angle);
|
||||
state->P[0][1] -= dt * state->P[1][1];
|
||||
state->P[1][0] -= dt * state->P[1][1];
|
||||
state->P[1][1] += state->Q_bias * dt;
|
||||
|
||||
// Innovation
|
||||
float S = state->P[0][0] + state->R_measure;
|
||||
float K[2] = {state->P[0][0] / S, state->P[1][0] / S};
|
||||
|
||||
float y = new_angle - state->angle;
|
||||
|
||||
// Update step
|
||||
state->angle += K[0] * y;
|
||||
state->bias += K[1] * y;
|
||||
|
||||
// Update error covariance
|
||||
float P00_temp = state->P[0][0];
|
||||
float P01_temp = state->P[0][1];
|
||||
|
||||
state->P[0][0] -= K[0] * P00_temp;
|
||||
state->P[0][1] -= K[0] * P01_temp;
|
||||
state->P[1][0] -= K[1] * P00_temp;
|
||||
state->P[1][1] -= K[1] * P01_temp;
|
||||
|
||||
return state->angle;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// IMU data structure
|
||||
typedef struct {
|
||||
float accel_x, accel_y, accel_z; // Accelerometer data (m/s²)
|
||||
float gyro_x, gyro_y, gyro_z; // Gyroscope data (rad/s)
|
||||
float mag_x, mag_y, mag_z; // Magnetometer data (optional)
|
||||
} IMU_RawData_t;
|
||||
|
||||
typedef struct {
|
||||
float roll, pitch, yaw; // Filtered attitude (radians)
|
||||
float accel_x, accel_y, accel_z; // Filtered acceleration
|
||||
float gyro_x, gyro_y, gyro_z; // Filtered gyroscope
|
||||
} IMU_FilteredData_t;
|
||||
|
||||
void process_imu_data(IMU_RawData_t *raw_data);
|
||||
IMU_FilteredData_t* get_filtered_imu_data(void);
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "pca95xx.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define REG_INPUT 0x00
|
||||
#define REG_OUTPUT 0x02
|
||||
@@ -46,10 +47,12 @@ int pca95xx_init(pca95xx_t* dev, etx_i2c_bus_t bus, uint16_t addr)
|
||||
dev->output = 0;
|
||||
|
||||
if (i2c_init(bus) < 0) {
|
||||
TRACE("PCA95 bus init error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_dev_ready(bus, addr) < 0) {
|
||||
TRACE("PCA95 device init error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
#include "hal/i2c_driver.h"
|
||||
|
||||
/* WARNING
|
||||
Ti PCA95 chip do NOT number pin sequentially, it goes PIN0 to PIN7 then PIN10 to PIN17.
|
||||
So when schematic indicate P10, it is PIN_8 in the following table
|
||||
*/
|
||||
|
||||
#define PCA95XX_PIN_0 (1 << 0)
|
||||
#define PCA95XX_PIN_1 (1 << 1)
|
||||
#define PCA95XX_PIN_2 (1 << 2)
|
||||
@@ -40,6 +45,23 @@
|
||||
#define PCA95XX_PIN_14 (1 << 14)
|
||||
#define PCA95XX_PIN_15 (1 << 15)
|
||||
|
||||
#define PCA95XX_P0 PCA95XX_PIN_0
|
||||
#define PCA95XX_P1 PCA95XX_PIN_1
|
||||
#define PCA95XX_P2 PCA95XX_PIN_2
|
||||
#define PCA95XX_P3 PCA95XX_PIN_3
|
||||
#define PCA95XX_P4 PCA95XX_PIN_4
|
||||
#define PCA95XX_P5 PCA95XX_PIN_5
|
||||
#define PCA95XX_P6 PCA95XX_PIN_6
|
||||
#define PCA95XX_P7 PCA95XX_PIN_7
|
||||
#define PCA95XX_P10 PCA95XX_PIN_8
|
||||
#define PCA95XX_P11 PCA95XX_PIN_9
|
||||
#define PCA95XX_P12 PCA95XX_PIN_10
|
||||
#define PCA95XX_P13 PCA95XX_PIN_11
|
||||
#define PCA95XX_P14 PCA95XX_PIN_12
|
||||
#define PCA95XX_P15 PCA95XX_PIN_13
|
||||
#define PCA95XX_P16 PCA95XX_PIN_14
|
||||
#define PCA95XX_P17 PCA95XX_PIN_15
|
||||
|
||||
typedef struct {
|
||||
etx_i2c_bus_t bus;
|
||||
uint16_t addr;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "tas2505.h"
|
||||
#include "stm32_i2s.h"
|
||||
#include "timers_driver.h"
|
||||
#include "hal/audio_driver.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@@ -126,3 +127,25 @@ int tas2505_init(tas2505_t* dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// adjust this value for a volume level just above the silence
|
||||
// values is attenuation in dB, higher value - less volume
|
||||
// max value is 126
|
||||
#define VOLUME_MIN_DB 60
|
||||
|
||||
void tas2505_set_volume(tas2505_t* dev, uint8_t volume)
|
||||
{
|
||||
if (volume > VOLUME_LEVEL_MAX) {
|
||||
volume = VOLUME_LEVEL_MAX;
|
||||
}
|
||||
// maximum volume is 0x00 and total silence is 0xFE
|
||||
if (volume == 0) {
|
||||
tas2505_write_reg(dev, TAS2505_SPKVOL1, 0xFE);
|
||||
tas2505_write_reg(dev, TAS2505_HP_VOL, 0xFE);
|
||||
} else {
|
||||
uint32_t vol = (VOLUME_MIN_DB * 2) -
|
||||
((uint32_t)volume * (VOLUME_MIN_DB * 2)) / VOLUME_LEVEL_MAX;
|
||||
tas2505_write_reg(dev, TAS2505_SPKVOL1, vol);
|
||||
tas2505_write_reg(dev, TAS2505_HP_VOL, vol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,3 +94,4 @@ typedef struct {
|
||||
|
||||
int tas2505_probe(tas2505_t* dev, etx_i2c_bus_t bus, uint16_t addr);
|
||||
int tas2505_init(tas2505_t* dev);
|
||||
void tas2505_set_volume(tas2505_t* dev, uint8_t volume);
|
||||
|
||||
@@ -477,7 +477,7 @@ int uf2_fat_write_block(uint32_t block_no, uint8_t *data)
|
||||
wr_st->written_mask[pos] |= mask;
|
||||
wr_st->num_written++;
|
||||
TRACE_DEBUG("[UF2] wr #%d (%d / %d)\n", bl->blockNo,
|
||||
state->num_written, bl->numBlocks);
|
||||
wr_st->num_written, bl->numBlocks);
|
||||
}
|
||||
if (wr_st->num_written >= wr_st->num_blocks) {
|
||||
TRACE_DEBUG("[UF2] done: reboot\n");
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/audio_driver.h"
|
||||
#include "hal/rgbleds.h"
|
||||
|
||||
#include "timers_driver.h"
|
||||
|
||||
@@ -401,6 +402,9 @@ void generalDefault()
|
||||
|
||||
#if defined(MANUFACTURER_RADIOMASTER)
|
||||
g_eeGeneral.audioMuteEnable = 1;
|
||||
#if defined(RADIO_TX15)
|
||||
g_eeGeneral.backlightBright = 50; // Screen looks off if not set high enough
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// disable Custom Script
|
||||
@@ -1123,6 +1127,10 @@ void edgeTxClose(uint8_t shutdown)
|
||||
#endif
|
||||
|
||||
sdDone();
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
turnOffRGBLeds();
|
||||
#endif
|
||||
}
|
||||
|
||||
void edgeTxResume()
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#if LANDSCAPE
|
||||
|
||||
static const lv_coord_t col_dsc[] = {
|
||||
LV_GRID_FR(32), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_FR(32), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_FR(34), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_FR(34), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_TEMPLATE_LAST
|
||||
};
|
||||
|
||||
@@ -91,16 +91,15 @@ class AnaViewWindow : public Window
|
||||
|
||||
new StaticText(line, rect_t{}, s);
|
||||
|
||||
auto lbl = new DynamicText(
|
||||
line, rect_t{},
|
||||
auto lbl = new DynamicText(line, rect_t{},
|
||||
[=]() {
|
||||
return std::to_string((int16_t)calibratedAnalogs[i] * 25 / 256);
|
||||
});
|
||||
etx_obj_add_style(lbl->getLvObj(), styles->text_align_right, LV_PART_MAIN);
|
||||
}, COLOR_THEME_PRIMARY1_INDEX, RIGHT);
|
||||
|
||||
lbl = new DynamicText(
|
||||
line, rect_t{}, [=]() { return std::to_string((int16_t)column3(i)); });
|
||||
etx_obj_add_style(lbl->getLvObj(), styles->text_align_right, LV_PART_MAIN);
|
||||
lbl = new DynamicText(line, rect_t{},
|
||||
[=]() {
|
||||
return std::to_string((int16_t)column3(i));
|
||||
}, COLOR_THEME_PRIMARY1_INDEX, RIGHT);
|
||||
|
||||
if (column4size() > 0) {
|
||||
lbl = new DynamicText(
|
||||
@@ -108,8 +107,7 @@ class AnaViewWindow : public Window
|
||||
[=]() {
|
||||
return std::string(column4prefix()) +
|
||||
std::to_string((int16_t)column4(i));
|
||||
});
|
||||
etx_obj_add_style(lbl->getLvObj(), (column4size() == 2) ? styles->text_align_left : styles->text_align_right, LV_PART_MAIN);
|
||||
}, COLOR_THEME_PRIMARY1_INDEX, (column4size() == 2) ? 0 : RIGHT);
|
||||
#if LANDSCAPE
|
||||
lv_obj_set_grid_cell(lbl->getLvObj(), LV_GRID_ALIGN_STRETCH,
|
||||
3 + (i & 1) * 5, column4size(),
|
||||
@@ -126,11 +124,31 @@ class AnaViewWindow : public Window
|
||||
lbl = new DynamicText(
|
||||
line, rect_t{},
|
||||
[=]() { return std::to_string((int16_t)column5(i)); });
|
||||
etx_obj_add_style(lbl->getLvObj(), styles->text_align_left, LV_PART_MAIN);
|
||||
} else {
|
||||
grid.nextCell();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(IMU_ICM4207C) && LANDSCAPE
|
||||
line = newLine(grid);
|
||||
lv_obj_set_style_pad_column(line->getLvObj(), PAD_SMALL, LV_PART_MAIN);
|
||||
|
||||
new StaticText(line, rect_t{}, "Tilt X");
|
||||
new DynamicText(
|
||||
line, rect_t{},
|
||||
[=]() {
|
||||
return std::to_string((int16_t) gyro.scaledX());
|
||||
}, COLOR_THEME_PRIMARY1_INDEX, RIGHT);
|
||||
|
||||
for (int i = 0; i < 3; i++) {grid.nextCell();}
|
||||
|
||||
new StaticText(line, rect_t{}, "Tilt Y");
|
||||
new DynamicText(
|
||||
line, rect_t{},
|
||||
[=]() {
|
||||
return std::to_string((int16_t) gyro.scaledY());
|
||||
}, COLOR_THEME_PRIMARY1_INDEX, RIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkEvents() override { Window::checkEvents(); }
|
||||
|
||||
+30
-3
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal.h"
|
||||
#include "debug.h"
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
@@ -59,14 +61,24 @@ void Gyro::wakeup()
|
||||
// stopping the sensor forever
|
||||
errors = 0;
|
||||
|
||||
int16_t gx = values[0];
|
||||
int16_t gy = values[1];
|
||||
// int16_t gz = values[2];
|
||||
#if defined(IMU_ICM4207C)
|
||||
raw_ax = values[3];
|
||||
raw_ay = values[4];
|
||||
int16_t ax = raw_ax - offset_x;
|
||||
int16_t ay = raw_ay - offset_y;
|
||||
|
||||
// Use only ACC value, they are really reliable
|
||||
outputs[0] = (ax * float(RESX)) / range_x;
|
||||
outputs[1] = (ay * float(RESX)) / range_y;
|
||||
#else
|
||||
int16_t ax = values[3];
|
||||
int16_t ay = values[4];
|
||||
int16_t az = values[5];
|
||||
|
||||
int16_t gx = values[0];
|
||||
int16_t gy = values[1];
|
||||
int16_t gz = values[2];
|
||||
|
||||
// integrate gyro
|
||||
roll -= gx * SCALE_FACT_GYRO * DT;
|
||||
pitch += gy * SCALE_FACT_GYRO * DT;
|
||||
@@ -85,6 +97,7 @@ void Gyro::wakeup()
|
||||
|
||||
outputs[0] = deg2RESX(roll);
|
||||
outputs[1] = deg2RESX(pitch);
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t Gyro::scaledX()
|
||||
@@ -103,3 +116,17 @@ int16_t Gyro::scaledY()
|
||||
// RESX);
|
||||
return limit<int16_t>(-RESX, outputs[1], RESX);
|
||||
}
|
||||
|
||||
void Gyro::setIMU_X(int16_t offset, int16_t range)
|
||||
{
|
||||
if (offset == -1) offset_x = raw_ax;
|
||||
else offset_x = offset;
|
||||
range_x = range * 8192 / 180;
|
||||
}
|
||||
|
||||
void Gyro::setIMU_Y(int16_t offset, int16_t range)
|
||||
{
|
||||
if (offset == -1) offset_y = raw_ay;
|
||||
else offset_y = offset;
|
||||
range_y = range * 8192 / 180;
|
||||
}
|
||||
@@ -39,11 +39,19 @@ class Gyro
|
||||
uint8_t errors = 0;
|
||||
float roll = 0.0;
|
||||
float pitch = 0.0;
|
||||
int16_t offset_x = 0;
|
||||
int16_t offset_y = 0;
|
||||
int16_t range_x = 8192;
|
||||
int16_t range_y = 8192;
|
||||
int16_t raw_ax = 0;
|
||||
int16_t raw_ay = 0;
|
||||
|
||||
public:
|
||||
int16_t outputs[2];
|
||||
|
||||
void wakeup();
|
||||
void setIMU_X(int16_t, int16_t);
|
||||
void setIMU_Y(int16_t, int16_t);
|
||||
|
||||
int16_t scaledX();
|
||||
int16_t scaledY();
|
||||
|
||||
@@ -63,7 +63,7 @@ bool getFSLedState(uint8_t index) {
|
||||
|
||||
uint32_t getFSLedRGBColor(uint8_t index)
|
||||
{
|
||||
return fsGetLedRGB(index);
|
||||
return fsGetLedRGB(index);
|
||||
}
|
||||
#else
|
||||
void setFSLedOFF(uint8_t index) {
|
||||
@@ -81,3 +81,8 @@ bool getFSLedState(uint8_t index) {
|
||||
return fsLedState(index);
|
||||
}
|
||||
#endif
|
||||
|
||||
void turnOffRGBLeds()
|
||||
{
|
||||
rgbLedClearAll();
|
||||
}
|
||||
|
||||
@@ -30,3 +30,4 @@ void setFSLedOFF(uint8_t index);
|
||||
void setFSLedON(uint8_t index);
|
||||
bool getFSLedState(uint8_t index);
|
||||
uint32_t getFSLedRGBColor(uint8_t index);
|
||||
void turnOffRGBLeds();
|
||||
|
||||
@@ -150,6 +150,7 @@ static uint8_t* skipUF2Extensions(uint8_t* data) {
|
||||
#if defined(STM32) && !defined(SIMU)
|
||||
void writeUF2FirmwareVersion(void* block)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
UF2_Block* uf2 = (UF2_Block*)block;
|
||||
uint8_t* end_data = skipUF2Extensions(uf2->data + uf2->payloadSize);
|
||||
|
||||
@@ -189,10 +190,12 @@ void writeUF2FirmwareVersion(void* block)
|
||||
memcpy(end_data, version, version_len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeUF2RebootBlock(void* block)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
extern uint32_t _reboot_cmd;
|
||||
|
||||
UF2_Block* uf2 = (UF2_Block*)block;
|
||||
@@ -209,5 +212,6 @@ void writeUF2RebootBlock(void* block)
|
||||
|
||||
uint32_t reboot_addr = BOOTLOADER_ADDRESS;
|
||||
memcpy(end_data, &reboot_addr, sizeof(reboot_addr));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -66,6 +66,7 @@ void UF2FirmwareUpdate::flashFirmware(const char* filename,
|
||||
uint32_t sect_len = drv->get_sector_size(sector);
|
||||
if (drv->erase_sector(addr) < 0) break;
|
||||
last_erased = block.targetAddr + sect_len - 1;
|
||||
TRACE("[UF2] erased %dKB @ 0x%08X", sect_len / 1024, addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +93,9 @@ void UF2FirmwareUpdate::flashFirmware(const char* filename,
|
||||
if (drv) {
|
||||
uint32_t len = block.payloadSize;
|
||||
uint8_t* data = (uint8_t*)block.data;
|
||||
drv->program(addr, data, len);
|
||||
if (drv->program(addr, data, len) < 0) break;
|
||||
TRACE("[UF2] written %d bytes @ 0x%08X (%d of %d)", len, addr,
|
||||
block.blockNo + 1, block.numBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2989,6 +2989,69 @@ static int luaGetStickMode(lua_State* const L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*luadoc
|
||||
@function setIMU_X(offset, range)
|
||||
|
||||
@param offset: integer, offset in angular degree. -1 to offset to current X position
|
||||
|
||||
@param range: integer, range in angular degree. 180° max.90 means min/max value will be reached at 45° from offset position
|
||||
|
||||
@status current Introduced in 3.0
|
||||
*/
|
||||
|
||||
static int luaSetIMU_X(lua_State* const L)
|
||||
{
|
||||
#if defined(IMU)
|
||||
int16_t offset = luaL_checkinteger(L, 1);
|
||||
int16_t range = luaL_checkinteger(L, 2);
|
||||
|
||||
if (offset < -180 || offset > 180) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
if (range < 0 || range > 180) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gyro.setIMU_X(offset, range);
|
||||
#endif
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*luadoc
|
||||
@function setIMU_Y(offset, range)
|
||||
|
||||
@param offset: integer, offset in angular degree. -1 to offset to current Y position
|
||||
|
||||
@param range: integer, range in angular degree, 180° max. 90 means min/max value will be reached at 45° from offset position
|
||||
|
||||
@status current Introduced in 3.0
|
||||
*/
|
||||
|
||||
static int luaSetIMU_Y(lua_State* const L)
|
||||
{
|
||||
#if defined(IMU)
|
||||
int16_t offset = luaL_checkinteger(L, 1);
|
||||
int16_t range = luaL_checkinteger(L, 2);
|
||||
|
||||
if (offset < -180 || offset > 180) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
if (range < 0 || range > 180) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gyro.setIMU_Y(offset, range);
|
||||
#endif
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#define KEY_EVENTS(xxx, yyy) \
|
||||
{ "EVT_"#xxx"_FIRST", LRO_NUMVAL(EVT_KEY_FIRST(yyy)) }, \
|
||||
{ "EVT_"#xxx"_BREAK", LRO_NUMVAL(EVT_KEY_BREAK(yyy)) }, \
|
||||
@@ -3084,6 +3147,8 @@ LROT_BEGIN(etxlib, NULL, 0)
|
||||
LROT_FUNCENTRY( setCFSLedColor, luaSetCFSLedColor )
|
||||
#endif
|
||||
LROT_FUNCENTRY( getStickMode, luaGetStickMode )
|
||||
LROT_FUNCENTRY( setIMU_X, luaSetIMU_X )
|
||||
LROT_FUNCENTRY( setIMU_Y, luaSetIMU_Y )
|
||||
LROT_END(etxlib, NULL, 0)
|
||||
|
||||
LROT_BEGIN(etxcst, NULL, 0)
|
||||
|
||||
@@ -38,6 +38,8 @@ elseif(PCB STREQUAL ST16)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_st16.cpp)
|
||||
elseif(PCB STREQUAL PA01)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pa01.cpp)
|
||||
elseif(PCB STREQUAL TX15)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tx15.cpp)
|
||||
elseif(PCB STREQUAL X7)
|
||||
if(PCBREV STREQUAL TPRO)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp)
|
||||
|
||||
@@ -36,10 +36,12 @@
|
||||
#else
|
||||
#include "yaml_datastructs_x10.cpp"
|
||||
#endif
|
||||
#elif defined(PCBTX15)
|
||||
#include "yaml_datastructs_tx15.cpp"
|
||||
#elif defined(PCBPL18)
|
||||
#if defined(RADIO_NB4P)
|
||||
#include "yaml_datastructs_nb4p.cpp"
|
||||
#elif defined(RADIO_NV14_FAMILY)
|
||||
#elif defined(RADIO_NV14_FAMILY)
|
||||
#include "yaml_datastructs_nv14_family.cpp"
|
||||
#elif defined(RADIO_PL18U)
|
||||
#include "yaml_datastructs_pl18u.cpp"
|
||||
|
||||
@@ -0,0 +1,985 @@
|
||||
// generated by generate_yaml.py
|
||||
|
||||
//
|
||||
// Enums first
|
||||
//
|
||||
|
||||
const struct YamlIdStr enum_BacklightMode[] = {
|
||||
{ e_backlight_mode_off, "backlight_mode_off" },
|
||||
{ e_backlight_mode_keys, "backlight_mode_keys" },
|
||||
{ e_backlight_mode_sticks, "backlight_mode_sticks" },
|
||||
{ e_backlight_mode_all, "backlight_mode_all" },
|
||||
{ e_backlight_mode_on, "backlight_mode_on" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_AntennaModes[] = {
|
||||
{ ANTENNA_MODE_INTERNAL, "MODE_INTERNAL" },
|
||||
{ ANTENNA_MODE_ASK, "MODE_ASK" },
|
||||
{ ANTENNA_MODE_PER_MODEL, "MODE_PER_MODEL" },
|
||||
{ ANTENNA_MODE_EXTERNAL, "MODE_EXTERNAL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ModuleType[] = {
|
||||
{ MODULE_TYPE_NONE, "TYPE_NONE" },
|
||||
{ MODULE_TYPE_PPM, "TYPE_PPM" },
|
||||
{ MODULE_TYPE_XJT_PXX1, "TYPE_XJT_PXX1" },
|
||||
{ MODULE_TYPE_ISRM_PXX2, "TYPE_ISRM_PXX2" },
|
||||
{ MODULE_TYPE_DSM2, "TYPE_DSM2" },
|
||||
{ MODULE_TYPE_CROSSFIRE, "TYPE_CROSSFIRE" },
|
||||
{ MODULE_TYPE_MULTIMODULE, "TYPE_MULTIMODULE" },
|
||||
{ MODULE_TYPE_R9M_PXX1, "TYPE_R9M_PXX1" },
|
||||
{ MODULE_TYPE_R9M_PXX2, "TYPE_R9M_PXX2" },
|
||||
{ MODULE_TYPE_R9M_LITE_PXX1, "TYPE_R9M_LITE_PXX1" },
|
||||
{ MODULE_TYPE_R9M_LITE_PXX2, "TYPE_R9M_LITE_PXX2" },
|
||||
{ MODULE_TYPE_GHOST, "TYPE_GHOST" },
|
||||
{ MODULE_TYPE_R9M_LITE_PRO_PXX2, "TYPE_R9M_LITE_PRO_PXX2" },
|
||||
{ MODULE_TYPE_SBUS, "TYPE_SBUS" },
|
||||
{ MODULE_TYPE_XJT_LITE_PXX2, "TYPE_XJT_LITE_PXX2" },
|
||||
{ MODULE_TYPE_FLYSKY_AFHDS2A, "TYPE_FLYSKY_AFHDS2A" },
|
||||
{ MODULE_TYPE_FLYSKY_AFHDS3, "TYPE_FLYSKY_AFHDS3" },
|
||||
{ MODULE_TYPE_LEMON_DSMP, "TYPE_LEMON_DSMP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TrainerMultiplex[] = {
|
||||
{ TRAINER_OFF, "OFF" },
|
||||
{ TRAINER_ADD, "ADD" },
|
||||
{ TRAINER_REPL, "REPL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_BeeperMode[] = {
|
||||
{ e_mode_quiet, "mode_quiet" },
|
||||
{ e_mode_alarms, "mode_alarms" },
|
||||
{ e_mode_nokeys, "mode_nokeys" },
|
||||
{ e_mode_all, "mode_all" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_BluetoothModes[] = {
|
||||
{ BLUETOOTH_OFF, "OFF" },
|
||||
{ BLUETOOTH_TELEMETRY, "TELEMETRY" },
|
||||
{ BLUETOOTH_TRAINER, "TRAINER" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_Functions[] = {
|
||||
{ FUNC_OVERRIDE_CHANNEL, "OVERRIDE_CHANNEL" },
|
||||
{ FUNC_TRAINER, "TRAINER" },
|
||||
{ FUNC_INSTANT_TRIM, "INSTANT_TRIM" },
|
||||
{ FUNC_RESET, "RESET" },
|
||||
{ FUNC_SET_TIMER, "SET_TIMER" },
|
||||
{ FUNC_ADJUST_GVAR, "ADJUST_GVAR" },
|
||||
{ FUNC_VOLUME, "VOLUME" },
|
||||
{ FUNC_SET_FAILSAFE, "SET_FAILSAFE" },
|
||||
{ FUNC_RANGECHECK, "RANGECHECK" },
|
||||
{ FUNC_BIND, "BIND" },
|
||||
{ FUNC_PLAY_SOUND, "PLAY_SOUND" },
|
||||
{ FUNC_PLAY_TRACK, "PLAY_TRACK" },
|
||||
{ FUNC_PLAY_VALUE, "PLAY_VALUE" },
|
||||
{ FUNC_PLAY_SCRIPT, "PLAY_SCRIPT" },
|
||||
{ FUNC_BACKGND_MUSIC, "BACKGND_MUSIC" },
|
||||
{ FUNC_BACKGND_MUSIC_PAUSE, "BACKGND_MUSIC_PAUSE" },
|
||||
{ FUNC_VARIO, "VARIO" },
|
||||
{ FUNC_HAPTIC, "HAPTIC" },
|
||||
{ FUNC_LOGS, "LOGS" },
|
||||
{ FUNC_BACKLIGHT, "BACKLIGHT" },
|
||||
{ FUNC_SCREENSHOT, "SCREENSHOT" },
|
||||
{ FUNC_RACING_MODE, "RACING_MODE" },
|
||||
{ FUNC_DISABLE_TOUCH, "DISABLE_TOUCH" },
|
||||
{ FUNC_SET_SCREEN, "SET_SCREEN" },
|
||||
{ FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" },
|
||||
{ FUNC_RGB_LED, "RGB_LED" },
|
||||
{ FUNC_PUSH_CUST_SWITCH, "PUSH_CUST_SWITCH" },
|
||||
{ FUNC_TEST, "TEST" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_SwitchConfig[] = {
|
||||
{ SWITCH_NONE, "NONE" },
|
||||
{ SWITCH_TOGGLE, "TOGGLE" },
|
||||
{ SWITCH_2POS, "2POS" },
|
||||
{ SWITCH_3POS, "3POS" },
|
||||
{ SWITCH_GLOBAL, "GLOBAL" },
|
||||
{ SWITCH_none, "none" },
|
||||
{ SWITCH_toggle, "toggle" },
|
||||
{ SWITCH_2pos, "2pos" },
|
||||
{ SWITCH_3pos, "3pos" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_fsStartPositionType[] = {
|
||||
{ FS_START_OFF, "START_OFF" },
|
||||
{ FS_START_ON, "START_ON" },
|
||||
{ FS_START_PREVIOUS, "START_PREVIOUS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_booleanEnum[] = {
|
||||
{ BOOL_OFF, "OFF" },
|
||||
{ BOOL_ON, "ON" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
{ TMRMODE_OFF, "OFF" },
|
||||
{ TMRMODE_ON, "ON" },
|
||||
{ TMRMODE_START, "START" },
|
||||
{ TMRMODE_THR, "THR" },
|
||||
{ TMRMODE_THR_REL, "THR_REL" },
|
||||
{ TMRMODE_THR_START, "THR_START" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_MixerMultiplex[] = {
|
||||
{ MLTPX_ADD, "ADD" },
|
||||
{ MLTPX_MUL, "MUL" },
|
||||
{ MLTPX_REPL, "REPL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_MixSources[] = {
|
||||
{ MIXSRC_NONE, "NONE" },
|
||||
{ MIXSRC_TILT_X, "TILT_X" },
|
||||
{ MIXSRC_TILT_Y, "TILT_Y" },
|
||||
{ MIXSRC_SPACEMOUSE_A, "SPACEMOUSE_A" },
|
||||
{ MIXSRC_SPACEMOUSE_B, "SPACEMOUSE_B" },
|
||||
{ MIXSRC_SPACEMOUSE_C, "SPACEMOUSE_C" },
|
||||
{ MIXSRC_SPACEMOUSE_D, "SPACEMOUSE_D" },
|
||||
{ MIXSRC_SPACEMOUSE_E, "SPACEMOUSE_E" },
|
||||
{ MIXSRC_SPACEMOUSE_F, "SPACEMOUSE_F" },
|
||||
{ MIXSRC_MIN, "MIN" },
|
||||
{ MIXSRC_MAX, "MAX" },
|
||||
{ MIXSRC_TX_VOLTAGE, "TX_VOLTAGE" },
|
||||
{ MIXSRC_TX_TIME, "TX_TIME" },
|
||||
{ MIXSRC_TX_GPS, "TX_GPS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_LogicalSwitchesFunctions[] = {
|
||||
{ LS_FUNC_NONE, "FUNC_NONE" },
|
||||
{ LS_FUNC_VEQUAL, "FUNC_VEQUAL" },
|
||||
{ LS_FUNC_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL" },
|
||||
{ LS_FUNC_VPOS, "FUNC_VPOS" },
|
||||
{ LS_FUNC_VNEG, "FUNC_VNEG" },
|
||||
{ LS_FUNC_APOS, "FUNC_APOS" },
|
||||
{ LS_FUNC_ANEG, "FUNC_ANEG" },
|
||||
{ LS_FUNC_AND, "FUNC_AND" },
|
||||
{ LS_FUNC_OR, "FUNC_OR" },
|
||||
{ LS_FUNC_XOR, "FUNC_XOR" },
|
||||
{ LS_FUNC_EDGE, "FUNC_EDGE" },
|
||||
{ LS_FUNC_EQUAL, "FUNC_EQUAL" },
|
||||
{ LS_FUNC_GREATER, "FUNC_GREATER" },
|
||||
{ LS_FUNC_LESS, "FUNC_LESS" },
|
||||
{ LS_FUNC_DIFFEGREATER, "FUNC_DIFFEGREATER" },
|
||||
{ LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" },
|
||||
{ LS_FUNC_TIMER, "FUNC_TIMER" },
|
||||
{ LS_FUNC_STICKY, "FUNC_STICKY" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_SwashType[] = {
|
||||
{ SWASH_TYPE_NONE, "TYPE_NONE" },
|
||||
{ SWASH_TYPE_120, "TYPE_120" },
|
||||
{ SWASH_TYPE_120X, "TYPE_120X" },
|
||||
{ SWASH_TYPE_140, "TYPE_140" },
|
||||
{ SWASH_TYPE_90, "TYPE_90" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_SwitchSources[] = {
|
||||
{ SWSRC_NONE, "NONE" },
|
||||
{ SWSRC_ON, "ON" },
|
||||
{ SWSRC_ONE, "ONE" },
|
||||
{ SWSRC_TELEMETRY_STREAMING, "TELEMETRY_STREAMING" },
|
||||
{ SWSRC_RADIO_ACTIVITY, "RADIO_ACTIVITY" },
|
||||
{ SWSRC_TRAINER_CONNECTED, "TRAINER_CONNECTED" },
|
||||
{ SWSRC_OFF, "OFF" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_PotsWarnMode[] = {
|
||||
{ POTS_WARN_OFF, "WARN_OFF" },
|
||||
{ POTS_WARN_MANUAL, "WARN_MANUAL" },
|
||||
{ POTS_WARN_AUTO, "WARN_AUTO" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ModelOverridableEnable[] = {
|
||||
{ OVERRIDE_GLOBAL, "GLOBAL" },
|
||||
{ OVERRIDE_OFF, "OFF" },
|
||||
{ OVERRIDE_ON, "ON" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_FailsafeModes[] = {
|
||||
{ FAILSAFE_NOT_SET, "NOT_SET" },
|
||||
{ FAILSAFE_HOLD, "HOLD" },
|
||||
{ FAILSAFE_CUSTOM, "CUSTOM" },
|
||||
{ FAILSAFE_NOPULSES, "NOPULSES" },
|
||||
{ FAILSAFE_RECEIVER, "RECEIVER" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TelemetrySensorFormula[] = {
|
||||
{ TELEM_FORMULA_ADD, "FORMULA_ADD" },
|
||||
{ TELEM_FORMULA_AVERAGE, "FORMULA_AVERAGE" },
|
||||
{ TELEM_FORMULA_MIN, "FORMULA_MIN" },
|
||||
{ TELEM_FORMULA_MAX, "FORMULA_MAX" },
|
||||
{ TELEM_FORMULA_MULTIPLY, "FORMULA_MULTIPLY" },
|
||||
{ TELEM_FORMULA_TOTALIZE, "FORMULA_TOTALIZE" },
|
||||
{ TELEM_FORMULA_CELL, "FORMULA_CELL" },
|
||||
{ TELEM_FORMULA_CONSUMPTION, "FORMULA_CONSUMPTION" },
|
||||
{ TELEM_FORMULA_DIST, "FORMULA_DIST" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CUSTOM, "TYPE_CUSTOM" },
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
//
|
||||
|
||||
static const struct YamlNode struct_CalibData[] = {
|
||||
YAML_IDX_CUST("calib",r_calib,w_calib),
|
||||
YAML_SIGNED( "mid", 16 ),
|
||||
YAML_SIGNED( "spanNeg", 16 ),
|
||||
YAML_SIGNED( "spanPos", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_signed_16[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "val", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerMix[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "srcChn", 6 ),
|
||||
YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL),
|
||||
YAML_SIGNED( "studWeight", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerData[] = {
|
||||
YAML_ARRAY("calib", 16, 4, struct_signed_16, NULL),
|
||||
YAML_ARRAY("mix", 16, 4, struct_TrainerMix, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_1[] = {
|
||||
YAML_STRING("name", 8),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_2[] = {
|
||||
YAML_SIGNED( "val", 16 ),
|
||||
YAML_UNSIGNED( "mode", 8 ),
|
||||
YAML_UNSIGNED( "param", 8 ),
|
||||
YAML_SIGNED( "val2", 32 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_3[] = {
|
||||
YAML_SIGNED( "val1", 32 ),
|
||||
YAML_SIGNED( "val2", 32 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_0_elmts[] = {
|
||||
YAML_STRUCT("play", 64, struct_anonymous_1, NULL),
|
||||
YAML_STRUCT("all", 64, struct_anonymous_2, NULL),
|
||||
YAML_STRUCT("clear", 64, struct_anonymous_3, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_ENUM("func", 6, enum_Functions, NULL),
|
||||
YAML_CUSTOM("def",r_customFn,w_customFn),
|
||||
YAML_PADDING( 64 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RGBLedColor[] = {
|
||||
YAML_UNSIGNED( "r", 8 ),
|
||||
YAML_UNSIGNED( "g", 8 ),
|
||||
YAML_UNSIGNED( "b", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write),
|
||||
YAML_STRING("name", 3),
|
||||
YAML_ENUM("type", 3, enum_SwitchConfig, NULL),
|
||||
YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs),
|
||||
YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs),
|
||||
YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_STRUCT("onColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_UNSIGNED( "ppmunit", 2 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_UNSIGNED( "vBatWarn", 8 ),
|
||||
YAML_SIGNED( "txVoltageCalibration", 8 ),
|
||||
YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL),
|
||||
YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL),
|
||||
YAML_UNSIGNED( "disableRtcWarning", 1 ),
|
||||
YAML_UNSIGNED( "keysBacklight", 1 ),
|
||||
YAML_UNSIGNED( "dontPlayHello", 1 ),
|
||||
YAML_ENUM("internalModule", 8, enum_ModuleType, NULL),
|
||||
YAML_STRUCT("trainer", 128, struct_TrainerData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_UNSIGNED( "fai", 1 ),
|
||||
YAML_SIGNED_CUST( "beepMode", 2, r_beeperMode, w_beeperMode ),
|
||||
YAML_UNSIGNED( "alarmsFlash", 1 ),
|
||||
YAML_UNSIGNED( "disableMemoryWarning", 1 ),
|
||||
YAML_UNSIGNED( "disableAlarmWarning", 1 ),
|
||||
YAML_UNSIGNED( "stickMode", 2 ),
|
||||
YAML_SIGNED( "timezone", 5 ),
|
||||
YAML_UNSIGNED( "adjustRTC", 1 ),
|
||||
YAML_UNSIGNED( "inactivityTimer", 8 ),
|
||||
YAML_CUSTOM("telemetryBaudrate",r_telemetryBaudrate,nullptr),
|
||||
YAML_UNSIGNED( "internalModuleBaudrate", 3 ),
|
||||
YAML_SIGNED( "splashMode", 3 ),
|
||||
YAML_SIGNED_CUST( "hapticMode", 2, r_beeperMode, w_beeperMode ),
|
||||
YAML_SIGNED( "switchesDelay", 8 ),
|
||||
YAML_UNSIGNED( "lightAutoOff", 8 ),
|
||||
YAML_UNSIGNED( "templateSetup", 8 ),
|
||||
YAML_SIGNED( "PPM_Multiplier", 8 ),
|
||||
YAML_SIGNED_CUST( "hapticLength", 8, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "beepLength", 3, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "hapticStrength", 3, r_5pos, w_5pos ),
|
||||
YAML_UNSIGNED( "gpsFormat", 1 ),
|
||||
YAML_UNSIGNED( "audioMuteEnable", 1 ),
|
||||
YAML_UNSIGNED_CUST( "speakerPitch", 8, r_spPitch, w_spPitch ),
|
||||
YAML_SIGNED_CUST( "speakerVolume", 8, r_vol, w_vol ),
|
||||
YAML_SIGNED_CUST( "vBatMin", 8, r_vbat_min, w_vbat_min ),
|
||||
YAML_SIGNED_CUST( "vBatMax", 8, r_vbat_max, w_vbat_max ),
|
||||
YAML_UNSIGNED( "backlightBright", 8 ),
|
||||
YAML_UNSIGNED( "globalTimer", 32 ),
|
||||
YAML_UNSIGNED( "bluetoothBaudrate", 4 ),
|
||||
YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL),
|
||||
YAML_UNSIGNED( "countryCode", 2 ),
|
||||
YAML_SIGNED( "pwrOnSpeed", 3 ),
|
||||
YAML_SIGNED( "pwrOffSpeed", 3 ),
|
||||
YAML_CUSTOM("jitterFilter",r_jitterFilter,nullptr),
|
||||
YAML_UNSIGNED( "noJitterFilter", 1 ),
|
||||
YAML_UNSIGNED( "imperial", 1 ),
|
||||
YAML_UNSIGNED( "disableRssiPoweroffAlarm", 1 ),
|
||||
YAML_UNSIGNED( "USBMode", 2 ),
|
||||
YAML_UNSIGNED( "jackMode", 2 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_STRING("ttsLanguage", 2),
|
||||
YAML_SIGNED_CUST( "beepVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "wavVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "varioVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "backgroundVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ),
|
||||
YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ),
|
||||
YAML_SIGNED( "varioRepeat", 8 ),
|
||||
YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active),
|
||||
YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr),
|
||||
YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr),
|
||||
YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr),
|
||||
YAML_ARRAY("sticksConfig", 0, MAX_STICKS, struct_stickConfig, stick_name_valid),
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 80, 20, struct_switchDef, switchIsActive),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_STRING("currModelFilename", 17),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 3 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_UNSIGNED( "stickDeadZone", 3 ),
|
||||
YAML_SIGNED( "imuMax", 8 ),
|
||||
YAML_SIGNED( "imuOffset", 8 ),
|
||||
YAML_STRING("selectedTheme", 26),
|
||||
YAML_UNSIGNED( "labelSingleSelect", 1 ),
|
||||
YAML_UNSIGNED( "labelMultiMode", 1 ),
|
||||
YAML_UNSIGNED( "favMultiMode", 1 ),
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "radioGFDisabled", 1 ),
|
||||
YAML_UNSIGNED( "radioTrainerDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelHeliDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelFMDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelCurvesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelGVDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelLSDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelSFDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelTelemetryDisabled", 1 ),
|
||||
YAML_UNSIGNED( "disableTrainerPoweroffAlarm", 1 ),
|
||||
YAML_UNSIGNED( "disablePwrOnOffHaptic", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "val", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelHeader[] = {
|
||||
YAML_STRING("name", 15),
|
||||
YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL),
|
||||
YAML_STRING("bitmap", 14),
|
||||
YAML_STRING("labels", 100),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TimerData[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "start", 22 ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_SIGNED( "value", 22 ),
|
||||
YAML_ENUM("mode", 3, enum_TimerModes, NULL),
|
||||
YAML_UNSIGNED( "countdownBeep", 2 ),
|
||||
YAML_UNSIGNED( "minuteBeep", 1 ),
|
||||
YAML_UNSIGNED( "persistent", 2 ),
|
||||
YAML_SIGNED( "countdownStart", 2 ),
|
||||
YAML_UNSIGNED( "showElapsed", 1 ),
|
||||
YAML_UNSIGNED( "extraHaptic", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_STRING("name", 8),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CurveRef[] = {
|
||||
YAML_UNSIGNED( "type", 5 ),
|
||||
YAML_UNSIGNED_CUST( "value", 11, r_sourceNumVal, w_sourceNumVal ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_MixData[] = {
|
||||
YAML_UNSIGNED( "destCh", 5 ),
|
||||
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
|
||||
YAML_UNSIGNED( "carryTrim", 1 ),
|
||||
YAML_UNSIGNED( "mixWarn", 2 ),
|
||||
YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL),
|
||||
YAML_UNSIGNED( "delayPrec", 1 ),
|
||||
YAML_UNSIGNED( "speedPrec", 1 ),
|
||||
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
|
||||
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
|
||||
YAML_UNSIGNED( "delayUp", 8 ),
|
||||
YAML_UNSIGNED( "delayDown", 8 ),
|
||||
YAML_UNSIGNED( "speedUp", 8 ),
|
||||
YAML_UNSIGNED( "speedDown", 8 ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LimitData[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED_CUST( "min", 11, in_read_weight, in_write_weight ),
|
||||
YAML_SIGNED_CUST( "max", 11, in_read_weight, in_write_weight ),
|
||||
YAML_SIGNED( "ppmCenter", 10 ),
|
||||
YAML_SIGNED_CUST( "offset", 11, in_read_weight, in_write_weight ),
|
||||
YAML_UNSIGNED( "symetrical", 1 ),
|
||||
YAML_UNSIGNED( "revert", 1 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_SIGNED( "curve", 8 ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ExpoData[] = {
|
||||
YAML_UNSIGNED( "mode", 2 ),
|
||||
YAML_UNSIGNED( "scale", 14 ),
|
||||
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
|
||||
YAML_SIGNED( "trimSource", 6 ),
|
||||
YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ),
|
||||
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
|
||||
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
|
||||
YAML_UNSIGNED( "chn", 5 ),
|
||||
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CurveHeader[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "type", 1 ),
|
||||
YAML_UNSIGNED( "smooth", 1 ),
|
||||
YAML_SIGNED( "points", 6 ),
|
||||
YAML_STRING("name", 3),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_signed_8[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "val", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LogicalSwitchData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL),
|
||||
YAML_CUSTOM("def",r_logicSw,w_logicSw),
|
||||
YAML_PADDING( 10 ),
|
||||
YAML_PADDING( 10 ),
|
||||
YAML_SIGNED_CUST( "andsw", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_UNSIGNED( "lsPersist", 1 ),
|
||||
YAML_UNSIGNED( "lsState", 1 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_UNSIGNED( "delay", 8 ),
|
||||
YAML_UNSIGNED( "duration", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_SwashRingData[] = {
|
||||
YAML_ENUM("type", 8, enum_SwashType, NULL),
|
||||
YAML_UNSIGNED( "value", 8 ),
|
||||
YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED_CUST( "elevatorSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_SIGNED( "collectiveWeight", 8 ),
|
||||
YAML_SIGNED( "aileronWeight", 8 ),
|
||||
YAML_SIGNED( "elevatorWeight", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_trim_t[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "value", 11 ),
|
||||
YAML_UNSIGNED( "mode", 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_FlightModeData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ARRAY("trim", 16, 8, struct_trim_t, NULL),
|
||||
YAML_STRING("name", 10),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "fadeIn", 8 ),
|
||||
YAML_UNSIGNED( "fadeOut", 8 ),
|
||||
YAML_ARRAY("gvars", 16, 9, struct_signed_16, gvar_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_GVarData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("name", 3),
|
||||
YAML_UNSIGNED( "min", 12 ),
|
||||
YAML_UNSIGNED( "max", 12 ),
|
||||
YAML_UNSIGNED( "popup", 1 ),
|
||||
YAML_UNSIGNED( "prec", 1 ),
|
||||
YAML_UNSIGNED( "unit", 2 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_VarioData[] = {
|
||||
YAML_UNSIGNED_CUST( "source", 7, r_tele_sensor, w_tele_sensor ),
|
||||
YAML_UNSIGNED( "centerSilent", 1 ),
|
||||
YAML_SIGNED( "centerMax", 8 ),
|
||||
YAML_SIGNED( "centerMin", 8 ),
|
||||
YAML_SIGNED( "min", 8 ),
|
||||
YAML_SIGNED( "max", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RssiAlarmData[] = {
|
||||
YAML_CUSTOM("disabled",r_rssiDisabled,nullptr),
|
||||
YAML_CUSTOM("warning",r_rssiWarning,nullptr),
|
||||
YAML_CUSTOM("critical",r_rssiCritical,nullptr),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RFAlarmData[] = {
|
||||
YAML_SIGNED( "warning", 8 ),
|
||||
YAML_SIGNED( "critical", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PpmModule[] = {
|
||||
YAML_SIGNED( "delay", 6 ),
|
||||
YAML_UNSIGNED( "pulsePol", 1 ),
|
||||
YAML_UNSIGNED( "outputType", 1 ),
|
||||
YAML_SIGNED( "frameLength", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_5[] = {
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_UNSIGNED( "disableTelemetry", 1 ),
|
||||
YAML_UNSIGNED( "disableMapping", 1 ),
|
||||
YAML_UNSIGNED( "autoBindMode", 1 ),
|
||||
YAML_UNSIGNED( "lowPowerMode", 1 ),
|
||||
YAML_UNSIGNED( "receiverTelemetryOff", 1 ),
|
||||
YAML_UNSIGNED( "receiverHigherChannels", 1 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_SIGNED( "optionValue", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_6[] = {
|
||||
YAML_UNSIGNED( "power", 2 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_UNSIGNED( "receiverTelemetryOff", 1 ),
|
||||
YAML_UNSIGNED( "receiverHigherChannels", 1 ),
|
||||
YAML_SIGNED( "antennaMode", 2 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_7[] = {
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "noninverted", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_SIGNED( "refreshRate", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_string_64[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("val", 8),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_8[] = {
|
||||
YAML_UNSIGNED( "receivers", 7 ),
|
||||
YAML_UNSIGNED( "racingMode", 1 ),
|
||||
YAML_ARRAY("receiverName", 64, 3, struct_string_64, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_9[] = {
|
||||
YAML_ARRAY("rx_id", 8, 4, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "mode", 3 ),
|
||||
YAML_UNSIGNED( "rfPower", 1 ),
|
||||
YAML_UNSIGNED( "reserved", 4 ),
|
||||
YAML_ARRAY("rx_freq", 8, 2, struct_unsigned_8, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_10[] = {
|
||||
YAML_UNSIGNED( "emi", 2 ),
|
||||
YAML_UNSIGNED( "telemetry", 1 ),
|
||||
YAML_UNSIGNED( "phyMode", 3 ),
|
||||
YAML_UNSIGNED( "reserved", 2 ),
|
||||
YAML_UNSIGNED( "rfPower", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_11[] = {
|
||||
YAML_UNSIGNED( "raw12bits", 1 ),
|
||||
YAML_UNSIGNED( "telemetryBaudrate", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_12[] = {
|
||||
YAML_UNSIGNED( "telemetryBaudrate", 3 ),
|
||||
YAML_UNSIGNED( "crsfArmingMode", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_SIGNED_CUST( "crsfArmingTrigger", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_SIGNED( "spare3", 6 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_ARRAY("raw", 8, 25, struct_unsigned_8, NULL),
|
||||
YAML_STRUCT("ppm", 16, struct_PpmModule, NULL),
|
||||
YAML_STRUCT("multi", 24, struct_anonymous_5, NULL),
|
||||
YAML_STRUCT("pxx", 16, struct_anonymous_6, NULL),
|
||||
YAML_STRUCT("sbus", 16, struct_anonymous_7, NULL),
|
||||
YAML_STRUCT("pxx2", 200, struct_anonymous_8, NULL),
|
||||
YAML_STRUCT("flysky", 56, struct_anonymous_9, NULL),
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED_CUST( "type", 8, r_moduleType, w_moduleType ),
|
||||
YAML_CUSTOM("subType",r_modSubtype,w_modSubtype),
|
||||
YAML_UNSIGNED( "channelsStart", 8 ),
|
||||
YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ),
|
||||
YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerModuleData[] = {
|
||||
YAML_UNSIGNED_CUST( "mode", 8, r_trainerMode, w_trainerMode ),
|
||||
YAML_UNSIGNED( "channelsStart", 8 ),
|
||||
YAML_SIGNED( "channelsCount", 8 ),
|
||||
YAML_SIGNED( "frameLength", 8 ),
|
||||
YAML_SIGNED( "delay", 6 ),
|
||||
YAML_UNSIGNED( "pulsePol", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ScriptDataInput_elmts[] = {
|
||||
YAML_SIGNED( "value", 16 ),
|
||||
YAML_UNSIGNED_CUST( "source", 16, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ScriptDataInput[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNION("u", 16, union_ScriptDataInput_elmts, select_script_input),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ScriptData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("file", 6),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_ARRAY("inputs", 16, 6, union_ScriptDataInput, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_string_32[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("val", 4),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_14_elmts[] = {
|
||||
YAML_UNSIGNED( "id", 16 ),
|
||||
YAML_UNSIGNED( "persistentValue", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_16[] = {
|
||||
YAML_UNSIGNED( "physID", 5 ),
|
||||
YAML_UNSIGNED( "rxIndex", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_15_elmts[] = {
|
||||
YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL),
|
||||
YAML_UNSIGNED( "instance", 8 ),
|
||||
YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_18[] = {
|
||||
YAML_UNSIGNED( "ratio", 16 ),
|
||||
YAML_SIGNED( "offset", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_19[] = {
|
||||
YAML_UNSIGNED( "source", 8 ),
|
||||
YAML_UNSIGNED( "index", 8 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_20[] = {
|
||||
YAML_ARRAY("sources", 8, 4, struct_signed_8, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_21[] = {
|
||||
YAML_UNSIGNED( "source", 8 ),
|
||||
YAML_PADDING( 24 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_22[] = {
|
||||
YAML_UNSIGNED( "gps", 8 ),
|
||||
YAML_UNSIGNED( "alt", 8 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_17_elmts[] = {
|
||||
YAML_STRUCT("custom", 32, struct_anonymous_18, NULL),
|
||||
YAML_STRUCT("cell", 32, struct_anonymous_19, NULL),
|
||||
YAML_STRUCT("calc", 32, struct_anonymous_20, NULL),
|
||||
YAML_STRUCT("consumption", 32, struct_anonymous_21, NULL),
|
||||
YAML_STRUCT("dist", 32, struct_anonymous_22, NULL),
|
||||
YAML_UNSIGNED( "param", 32 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNION("id1", 16, union_anonymous_14_elmts, select_id1),
|
||||
YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2),
|
||||
YAML_STRING("label", 4),
|
||||
YAML_UNSIGNED( "subId", 8 ),
|
||||
YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "unit", 6 ),
|
||||
YAML_UNSIGNED( "prec", 2 ),
|
||||
YAML_UNSIGNED( "autoOffset", 1 ),
|
||||
YAML_UNSIGNED( "filter", 1 ),
|
||||
YAML_UNSIGNED( "logs", 1 ),
|
||||
YAML_UNSIGNED( "persistent", 1 ),
|
||||
YAML_UNSIGNED( "onlyPositive", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write),
|
||||
YAML_STRING("name", 3),
|
||||
YAML_ENUM("type", 3, enum_SwitchConfig, NULL),
|
||||
YAML_UNSIGNED( "group", 2 ),
|
||||
YAML_ENUM("start", 2, enum_fsStartPositionType, NULL),
|
||||
YAML_UNSIGNED( "state", 1 ),
|
||||
YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, NULL),
|
||||
YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, NULL),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_STRUCT("onColor", 24, struct_RGBLedColor, isAlwaysActive),
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
|
||||
YAML_UNSIGNED( "telemetryProtocol", 3 ),
|
||||
YAML_UNSIGNED( "thrTrim", 1 ),
|
||||
YAML_UNSIGNED( "noGlobalFunctions", 1 ),
|
||||
YAML_UNSIGNED( "displayTrims", 2 ),
|
||||
YAML_UNSIGNED( "ignoreSensorIds", 1 ),
|
||||
YAML_SIGNED( "trimInc", 3 ),
|
||||
YAML_UNSIGNED( "disableThrottleWarning", 1 ),
|
||||
YAML_UNSIGNED( "displayChecklist", 1 ),
|
||||
YAML_UNSIGNED( "extendedLimits", 1 ),
|
||||
YAML_UNSIGNED( "extendedTrims", 1 ),
|
||||
YAML_UNSIGNED( "throttleReversed", 1 ),
|
||||
YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ),
|
||||
YAML_UNSIGNED( "disableTelemetryWarning", 1 ),
|
||||
YAML_UNSIGNED( "showInstanceIds", 1 ),
|
||||
YAML_UNSIGNED( "checklistInteractive", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_SIGNED( "customThrottleWarningPosition", 8 ),
|
||||
YAML_UNSIGNED( "beepANACenter", 16 ),
|
||||
YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL),
|
||||
YAML_ARRAY("limitData", 104, 32, struct_LimitData, NULL),
|
||||
YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL),
|
||||
YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL),
|
||||
YAML_ARRAY("points", 8, 512, struct_signed_8, NULL),
|
||||
YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL),
|
||||
YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active),
|
||||
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
|
||||
YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active),
|
||||
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
|
||||
YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr),
|
||||
YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr),
|
||||
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
|
||||
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
|
||||
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
|
||||
YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL),
|
||||
YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL),
|
||||
YAML_UNSIGNED( "thrTrimSw", 3 ),
|
||||
YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL),
|
||||
YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL),
|
||||
YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL),
|
||||
YAML_STRUCT("trainerData", 40, struct_TrainerModuleData, NULL),
|
||||
YAML_ARRAY("scriptsData", 192, 9, struct_ScriptData, NULL),
|
||||
YAML_ARRAY("inputNames", 32, 32, struct_string_32, NULL),
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr),
|
||||
YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr),
|
||||
YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr),
|
||||
YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr),
|
||||
YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr),
|
||||
YAML_ARRAY("functionSwitchLedONColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOnColorConfig, nullptr),
|
||||
YAML_ARRAY("functionSwitchLedOFFColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOffColorConfig, nullptr),
|
||||
YAML_ARRAY("customSwitches", 88, 6, struct_customSwitch, isAlwaysActive),
|
||||
YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
#define MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN 29
|
||||
|
||||
static const struct YamlNode __RadioData_root_node = YAML_ROOT( struct_RadioData );
|
||||
|
||||
const YamlNode* get_radiodata_nodes()
|
||||
{
|
||||
return &__RadioData_root_node;
|
||||
}
|
||||
static const struct YamlNode __ModelData_root_node = YAML_ROOT( struct_ModelData );
|
||||
|
||||
const YamlNode* get_modeldata_nodes()
|
||||
{
|
||||
return &__ModelData_root_node;
|
||||
}
|
||||
static const struct YamlNode __PartialModel_root_node = YAML_ROOT( struct_PartialModel );
|
||||
|
||||
const YamlNode* get_partialmodel_nodes()
|
||||
{
|
||||
return &__PartialModel_root_node;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,11 @@ uint8_t potsPos[MAX_POTS];
|
||||
|
||||
uint16_t fsPreviousState = 0;
|
||||
|
||||
uint8_t isSwitch3Pos(uint8_t idx)
|
||||
{
|
||||
return IS_CONFIG_3POS(idx);
|
||||
}
|
||||
|
||||
void setFSStartupPosition()
|
||||
{
|
||||
for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
||||
|
||||
@@ -90,18 +90,15 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SDMMC1) && defined(SD_SDIO)
|
||||
# if !defined(SD_SDIO_IRQHandler)
|
||||
# define SD_SDIO_IRQHandler SDMMC1_IRQHandler
|
||||
# define SD_SDIO_IRQn SDMMC1_IRQn
|
||||
# endif
|
||||
#if defined(SDMMC1)
|
||||
# define SD_SDIO_TypeDef SDMMC_TypeDef
|
||||
# define SD_SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
|
||||
# define SD_SDIO_CLOCK_POWER_SAVE_DISABLE SDMMC_CLOCK_POWER_SAVE_DISABLE
|
||||
# define SD_SDIO_BUS_WIDE_1B SDMMC_BUS_WIDE_1B
|
||||
# define SD_SDIO_BUS_WIDE_4B SDMMC_BUS_WIDE_4B
|
||||
# define SD_SDIO_HARDWARE_FLOW_CONTROL_DISABLE SDMMC_HARDWARE_FLOW_CONTROL_DISABLE
|
||||
#elif !defined(SDMMC1)
|
||||
# define SD_SDIO_IRQn SDMMC1_IRQn
|
||||
#else
|
||||
# if !defined(SD_SDIO)
|
||||
# define SD_SDIO SDIO
|
||||
# endif
|
||||
@@ -118,6 +115,24 @@
|
||||
# define SD_SDIO_HARDWARE_FLOW_CONTROL_DISABLE SDIO_HARDWARE_FLOW_CONTROL_DISABLE
|
||||
#endif
|
||||
|
||||
struct {
|
||||
SD_SDIO_TypeDef* periph = SD_SDIO;
|
||||
gpio_t D0 = SD_SDIO_PIN_D0;
|
||||
gpio_t D1 = SD_SDIO_PIN_D1;
|
||||
gpio_t D2 = SD_SDIO_PIN_D2;
|
||||
gpio_t D3 = SD_SDIO_PIN_D3;
|
||||
gpio_t CMD = SD_SDIO_PIN_CMD;
|
||||
gpio_t CLK = SD_SDIO_PIN_CLK;
|
||||
gpio_af_t AF_D0 = SD_SDIO_AF_D0;
|
||||
gpio_af_t AF_D1 = SD_SDIO_AF_D1;
|
||||
gpio_af_t AF_D2 = SD_SDIO_AF_D2;
|
||||
gpio_af_t AF_D3 = SD_SDIO_AF_D3;
|
||||
gpio_af_t AF_CMD = SD_SDIO_AF_CMD;
|
||||
gpio_af_t AF_CLK = SD_SDIO_AF_CLK;
|
||||
IRQn_Type IRQn = SD_SDIO_IRQn;
|
||||
uint32_t SD_CLK_DIV = SD_SDIO_TRANSFER_CLK_DIV;
|
||||
} currentSD;
|
||||
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
#error "Variable sector size is not supported"
|
||||
#endif
|
||||
@@ -156,8 +171,12 @@ extern uint32_t _heap_start;
|
||||
// HAL state
|
||||
static SD_HandleTypeDef sdio;
|
||||
#if defined(SD_SDIO_DMA)
|
||||
#if defined(STM32H7) || defined(STM32H7RS) || defined(STM32H5)
|
||||
static_assert(false,"H7/H5 use dedicated DMA controler");
|
||||
#else
|
||||
static DMA_HandleTypeDef sdioTxDma;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Disk status
|
||||
static volatile uint32_t WriteStatus;
|
||||
@@ -179,26 +198,26 @@ static void _sd_sdio_clk_enable(SD_SDIO_TypeDef* periph)
|
||||
|
||||
static void sdio_low_level_init(void)
|
||||
{
|
||||
_sd_sdio_clk_enable(SD_SDIO);
|
||||
_sd_sdio_clk_enable(currentSD.periph);
|
||||
|
||||
// data pins
|
||||
gpio_init(SD_SDIO_PIN_D0, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_D0, SD_SDIO_AF_D0);
|
||||
gpio_init(currentSD.D0, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.D0, currentSD.AF_D0);
|
||||
|
||||
gpio_init(SD_SDIO_PIN_D1, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_D1, SD_SDIO_AF_D1);
|
||||
|
||||
gpio_init(SD_SDIO_PIN_D2, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_D2, SD_SDIO_AF_D2);
|
||||
gpio_init(currentSD.D1, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.D1, currentSD.AF_D1);
|
||||
|
||||
gpio_init(SD_SDIO_PIN_D3, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_D3, SD_SDIO_AF_D3);
|
||||
gpio_init(currentSD.D2, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.D2, currentSD.AF_D2);
|
||||
|
||||
gpio_init(SD_SDIO_PIN_CMD, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_CMD, SD_SDIO_AF_CMD);
|
||||
|
||||
gpio_init(SD_SDIO_PIN_CLK, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(SD_SDIO_PIN_CLK, SD_SDIO_AF_CLK);
|
||||
gpio_init(currentSD.D3, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.D3, currentSD.AF_D3);
|
||||
|
||||
gpio_init(currentSD.CMD, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.CMD, currentSD.AF_CMD);
|
||||
|
||||
gpio_init(currentSD.CLK, GPIO_IN_PU, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_set_af(currentSD.CLK, currentSD.AF_CLK);
|
||||
|
||||
#if defined(SD_SDIO_HAS_TRANSCEIVER)
|
||||
gpio_init_af(SD_SDIO_PIN_CKIN, SD_SDIO_AF_CKIN, GPIO_PIN_SPEED_HIGH);
|
||||
@@ -208,8 +227,8 @@ static void sdio_low_level_init(void)
|
||||
#endif
|
||||
|
||||
// SDIO Interrupt ENABLE
|
||||
NVIC_SetPriority(SD_SDIO_IRQn, 0);
|
||||
NVIC_EnableIRQ(SD_SDIO_IRQn);
|
||||
NVIC_SetPriority(currentSD.IRQn, 0);
|
||||
NVIC_EnableIRQ(currentSD.IRQn);
|
||||
|
||||
#if defined(SD_SDIO_DMA)
|
||||
// Init SDIO DMA instance
|
||||
@@ -231,7 +250,7 @@ static void sdio_low_level_init(void)
|
||||
|
||||
__HAL_LINKDMA(&sdio, hdmatx, sdioTxDma);
|
||||
__HAL_LINKDMA(&sdio, hdmarx, sdioTxDma);
|
||||
|
||||
|
||||
// DMA2 STREAMx Interrupt ENABLE
|
||||
NVIC_SetPriority(SD_SDIO_DMA_IRQn, 0);
|
||||
NVIC_EnableIRQ(SD_SDIO_DMA_IRQn);
|
||||
@@ -241,6 +260,27 @@ static void sdio_low_level_init(void)
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
static DSTATUS sdio_initialize(BYTE lun)
|
||||
{
|
||||
#if defined(SD2_PRESENT_GPIO)
|
||||
/* Define active SD */
|
||||
if (gpio_read(SD2_PRESENT_GPIO) == 0) {
|
||||
currentSD.periph = SDMMC2;
|
||||
currentSD.D0 = SD2_SDIO_PIN_D0;
|
||||
currentSD.AF_D0 = SD2_SDIO_AF_D0;
|
||||
currentSD.D1 = SD2_SDIO_PIN_D1;
|
||||
currentSD.AF_D1 = SD2_SDIO_AF_D1;
|
||||
currentSD.D2 = SD2_SDIO_PIN_D2;
|
||||
currentSD.AF_D2 = SD2_SDIO_AF_D2;
|
||||
currentSD.D3 = SD2_SDIO_PIN_D3;
|
||||
currentSD.AF_D3 = SD2_SDIO_AF_D3;
|
||||
currentSD.CMD = SD2_SDIO_PIN_CMD;
|
||||
currentSD.AF_CMD = SD2_SDIO_AF_CMD;
|
||||
currentSD.CLK = SD2_SDIO_PIN_CLK;
|
||||
currentSD.AF_CLK = SD2_SDIO_AF_CLK;
|
||||
currentSD.IRQn = SDMMC2_IRQn;
|
||||
currentSD.SD_CLK_DIV = SD2_SDIO_TRANSFER_CLK_DIV;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SDIO Peripheral Low Level Init */
|
||||
sdio_low_level_init();
|
||||
|
||||
@@ -248,7 +288,7 @@ static DSTATUS sdio_initialize(BYTE lun)
|
||||
/*!< SDIO_CK = SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2) */
|
||||
/*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */
|
||||
|
||||
sdio.Instance = SD_SDIO;
|
||||
sdio.Instance = currentSD.periph;
|
||||
sdio.Init.ClockEdge = SD_SDIO_CLOCK_EDGE_RISING;
|
||||
sdio.Init.ClockPowerSave = SD_SDIO_CLOCK_POWER_SAVE_DISABLE;
|
||||
sdio.Init.BusWide = SD_SDIO_BUS_WIDE_1B;
|
||||
@@ -259,7 +299,7 @@ static DSTATUS sdio_initialize(BYTE lun)
|
||||
#if defined(SD_SDIO_CLOCK_BYPASS_DISABLE)
|
||||
sdio.Init.ClockBypass = SD_SDIO_CLOCK_BYPASS_DISABLE;
|
||||
#endif
|
||||
sdio.Init.ClockDiv = SD_SDIO_TRANSFER_CLK_DIV;
|
||||
sdio.Init.ClockDiv = currentSD.SD_CLK_DIV;
|
||||
|
||||
HAL_StatusTypeDef halStatus = HAL_SD_Init(&sdio);
|
||||
if (halStatus != HAL_OK) {
|
||||
@@ -311,7 +351,7 @@ static SDTransferState sdio_check_card_state()
|
||||
else if (cardstate == HAL_SD_CARD_ERROR) {
|
||||
return SD_TRANSFER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
return SD_TRANSFER_BUSY;
|
||||
}
|
||||
|
||||
@@ -333,7 +373,11 @@ static DSTATUS sdio_status(BYTE lun)
|
||||
{
|
||||
DSTATUS stat = RES_OK;
|
||||
|
||||
#if defined(SD_PRESENT_GPIO)
|
||||
#if defined(SD2_PRESENT_GPIO)
|
||||
if (currentSD.periph == SDMMC2 && gpio_read(SD2_PRESENT_GPIO)) {
|
||||
stat |= STA_NODISK;
|
||||
}
|
||||
#elif defined(SD_PRESENT_GPIO)
|
||||
if (gpio_read(SD_PRESENT_GPIO)) {
|
||||
stat |= STA_NODISK;
|
||||
}
|
||||
@@ -551,12 +595,28 @@ extern "C" void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
|
||||
ReadStatus = 1;
|
||||
}
|
||||
|
||||
#if defined(SDMMC1)
|
||||
#if defined(SDMMC1)
|
||||
extern "C" void SDMMC1_IRQHandler(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_SDIO);
|
||||
HAL_SD_IRQHandler(&sdio);
|
||||
}
|
||||
#endif
|
||||
#if defined(SDMMC2) && defined(SD2_PRESENT_GPIO)
|
||||
extern "C" void SDMMC2_IRQHandler(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_SDIO);
|
||||
HAL_SD_IRQHandler(&sdio);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
extern "C" void SD_SDIO_IRQHandler(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_SDIO);
|
||||
HAL_SD_IRQHandler(&sdio);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(SD_SDIO_DMA)
|
||||
extern "C" void SD_SDIO_DMA_IRQHANDLER(void)
|
||||
{
|
||||
|
||||
@@ -48,8 +48,10 @@ static const stm32_usart_t fsUSART = {
|
||||
.IRQn = FLYSKY_HALL_SERIAL_USART_IRQn,
|
||||
.IRQ_Prio = 4,
|
||||
.txDMA = FLYSKY_HALL_SERIAL_DMA,
|
||||
#if defined(FLYSKY_HALL_DMA_Stream_TX)
|
||||
.txDMA_Stream = FLYSKY_HALL_DMA_Stream_TX,
|
||||
.txDMA_Channel = FLYSKY_HALL_DMA_Channel,
|
||||
#endif
|
||||
.rxDMA = FLYSKY_HALL_SERIAL_DMA,
|
||||
.rxDMA_Stream = FLYSKY_HALL_DMA_Stream_RX,
|
||||
.rxDMA_Channel = FLYSKY_HALL_DMA_Channel,
|
||||
@@ -263,12 +265,17 @@ bool flysky_gimbal_init()
|
||||
{
|
||||
if (flysky_gimbal_init_uart() != 0) return false;
|
||||
|
||||
// Wait 70ms for FlySky gimbals to respond. According to LA trace, minimally
|
||||
// 23ms is required
|
||||
_fs_gimbal_detected = false;
|
||||
|
||||
for (uint8_t i = 0; i < 70; i++) {
|
||||
// Wait 70ms for serial gimbals to respond
|
||||
for (uint16_t i = 0; i < 70; i++) {
|
||||
#if defined(HALL_SYNC) && !defined(SIMU)
|
||||
gpio_set(HALL_SYNC);
|
||||
#endif
|
||||
delay_ms(1);
|
||||
#if defined(HALL_SYNC) && !defined(SIMU)
|
||||
gpio_clear(HALL_SYNC);
|
||||
#endif
|
||||
if (_fs_gimbal_detected) {
|
||||
// Try to obtain the version of gimbal for operation mode selection
|
||||
_fs_cmd_get_version();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define __INIT_HOOK __attribute__((section(".init_hook")))
|
||||
|
||||
#define __CCMRAM __attribute__((section(".ccm"), aligned(4)))
|
||||
#define __DMA __attribute__((section(".ram"), aligned(4)))
|
||||
#define __DMA __attribute__((section(".ram"), aligned(32)))
|
||||
#define __DMA_NO_CACHE __attribute__((section(".dram"), aligned(4)))
|
||||
#define __IRAM __attribute__((section(".iram")))
|
||||
#define __SDRAM __attribute__((section(".sdram"), aligned(4)))
|
||||
|
||||
@@ -32,6 +32,10 @@ void pwrInit()
|
||||
gpio_init(SD_PRESENT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
#if defined(SD2_PRESENT_GPIO)
|
||||
gpio_init(SD2_PRESENT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
#if defined(INTMODULE_BOOTCMD_GPIO)
|
||||
gpio_init(INTMODULE_BOOTCMD_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_write(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_DEFAULT);
|
||||
|
||||
@@ -154,6 +154,7 @@ void rotaryEncoderStartDelay()
|
||||
|
||||
void rotaryEncoderInit()
|
||||
{
|
||||
#if defined(ROTARY_ENCODER_GPIO)
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
LL_GPIO_StructInit(&pinInit);
|
||||
pinInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
@@ -186,6 +187,44 @@ void rotaryEncoderInit()
|
||||
uint32_t trigger = LL_EXTI_TRIGGER_RISING_FALLING;
|
||||
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE1, trigger, rotaryEncoderStartDelay);
|
||||
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE2, trigger, rotaryEncoderStartDelay);
|
||||
#else
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
LL_GPIO_StructInit(&pinInit);
|
||||
pinInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
pinInit.Pull = LL_GPIO_PULL_UP;
|
||||
pinInit.Pin = ROTARY_ENCODER_GPIO_PIN_A;
|
||||
|
||||
stm32_gpio_enable_clock(ROTARY_ENCODER_GPIO_A);
|
||||
stm32_gpio_enable_clock(ROTARY_ENCODER_GPIO_B);
|
||||
LL_GPIO_Init(ROTARY_ENCODER_GPIO_A, &pinInit);
|
||||
pinInit.Pin = ROTARY_ENCODER_GPIO_PIN_B;
|
||||
LL_GPIO_Init(ROTARY_ENCODER_GPIO_B, &pinInit);
|
||||
|
||||
stm32_timer_enable_clock(ROTARY_ENCODER_TIMER);
|
||||
ROTARY_ENCODER_TIMER->ARR = 99; // 100uS
|
||||
ROTARY_ENCODER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS
|
||||
ROTARY_ENCODER_TIMER->CCER = 0;
|
||||
ROTARY_ENCODER_TIMER->CCMR1 = 0;
|
||||
ROTARY_ENCODER_TIMER->EGR = 0;
|
||||
ROTARY_ENCODER_TIMER->CR1 = 0;
|
||||
ROTARY_ENCODER_TIMER->DIER |= TIM_DIER_UIE;
|
||||
|
||||
#if defined(LL_APB4_GRP1_PERIPH_SYSCFG)
|
||||
LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
|
||||
#elif defined(LL_APB2_GRP1_PERIPH_SYSCFG)
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
|
||||
#else
|
||||
#error "Unsupported SYSCFG clock"
|
||||
#endif
|
||||
|
||||
LL_SYSCFG_SetEXTISource(ROTARY_ENCODER_EXTI_PORT_A, ROTARY_ENCODER_EXTI_SYS_LINE1);
|
||||
LL_SYSCFG_SetEXTISource(ROTARY_ENCODER_EXTI_PORT_B, ROTARY_ENCODER_EXTI_SYS_LINE2);
|
||||
|
||||
uint32_t trigger = LL_EXTI_TRIGGER_RISING_FALLING;
|
||||
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE1, trigger, rotaryEncoderStartDelay);
|
||||
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE2, trigger, rotaryEncoderStartDelay);
|
||||
#endif
|
||||
|
||||
|
||||
NVIC_EnableIRQ(ROTARY_ENCODER_TIMER_IRQn);
|
||||
NVIC_SetPriority(ROTARY_ENCODER_TIMER_IRQn, 7);
|
||||
|
||||
@@ -67,8 +67,14 @@ void rtcInit()
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
#endif
|
||||
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
#if defined(LSE_DRIVE_STRENGTH)
|
||||
__HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
|
||||
__HAL_RCC_LSEDRIVE_CONFIG(LSE_DRIVE_STRENGTH);
|
||||
#endif
|
||||
|
||||
// Enable LSE Oscillator
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {};
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
|
||||
#if !defined(STM32H7RS) && !defined(STM32H5)
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||
|
||||
@@ -33,8 +33,12 @@
|
||||
#include <string.h>
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
|
||||
#define OVERSAMPLING 4
|
||||
#if defined(STM32H7) || defined(STM32H7RS) || defined(STM32H5)
|
||||
// Disable software oversampling as HW one is used
|
||||
#define OVERSAMPLING 1
|
||||
#else
|
||||
#define OVERSAMPLING 4
|
||||
#endif
|
||||
|
||||
#define SAMPLING_TIMEOUT_US 500
|
||||
|
||||
@@ -78,6 +82,9 @@ static uint8_t _adc_run;
|
||||
static uint8_t _adc_oversampling_disabled;
|
||||
static uint16_t _adc_oversampling[MAX_ADC_INPUTS];
|
||||
|
||||
// Indicates ADC timeout has occured
|
||||
static bool _adc_timeout_error;
|
||||
|
||||
void stm32_hal_set_inputs_mask(uint32_t inputs)
|
||||
{
|
||||
_adc_input_inhibt_mask |= inputs;
|
||||
@@ -232,6 +239,12 @@ static void adc_setup_scan_mode(ADC_TypeDef* ADCx, uint8_t nconv)
|
||||
wait_loop_index--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start ADC calibration in mode single-ended or differential */
|
||||
LL_ADC_StartCalibration(ADCx, LL_ADC_CALIB_OFFSET_LINEARITY, LL_ADC_SINGLE_ENDED);
|
||||
|
||||
/* Wait for calibration completion */
|
||||
while (LL_ADC_IsCalibrationOnGoing(ADCx) != 0UL);
|
||||
#endif
|
||||
|
||||
#if defined(LL_ADC_RESOLUTION_12B_OPT)
|
||||
@@ -253,6 +266,17 @@ static void adc_setup_scan_mode(ADC_TypeDef* ADCx, uint8_t nconv)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(STM32H7RS) || defined(STM32H7) || defined(STM32H5)
|
||||
// set hardware oversampling
|
||||
if (!_adc_oversampling_disabled && ADCx != ADC3) {
|
||||
// LL_ADC_OVS_RATIO_x in stm32h7xx_ll_adc.h is broken
|
||||
// so actual oversampling count need to be used
|
||||
// ADC3 oversampling is disabled because of issues in LL libs
|
||||
LL_ADC_ConfigOverSamplingRatioShift(ADCx, 16, LL_ADC_OVS_SHIFT_RIGHT_4);
|
||||
LL_ADC_SetOverSamplingScope(ADCx, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
|
||||
}
|
||||
#endif
|
||||
|
||||
LL_ADC_REG_Init(ADCx, &adcRegInit);
|
||||
|
||||
// Enable ADC
|
||||
@@ -756,10 +780,12 @@ void stm32_hal_adc_wait_completion(const stm32_adc_t* ADCs, uint8_t n_ADC,
|
||||
// busy wait
|
||||
if ((uint32_t)(timersGetUsTick() - timeout) >= SAMPLING_TIMEOUT_US) {
|
||||
TRACE("ADC timeout");
|
||||
_adc_timeout_error = true;
|
||||
_adc_started_mask = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_adc_timeout_error = false;
|
||||
}
|
||||
|
||||
void stm32_hal_adc_disable_oversampling()
|
||||
@@ -787,7 +813,7 @@ static void _adc_chain_conversions(const stm32_adc_t* adc)
|
||||
for (uint8_t i = 0; i < _adc_n_inputs; i++) {
|
||||
if (~_adc_input_mask & (1 << i)) continue;
|
||||
if (_adc_inhibit_mask & (1 << i)) continue;
|
||||
adcValues[i] = _adc_oversampling[i] / OVERSAMPLING;
|
||||
if (!_adc_timeout_error) adcValues[i] = _adc_oversampling[i] / OVERSAMPLING;
|
||||
}
|
||||
|
||||
// we're done!
|
||||
|
||||
@@ -360,7 +360,14 @@ static int i2c_init_clock_source(I2C_TypeDef* instance)
|
||||
#endif
|
||||
|
||||
#if defined(LL_RCC_I2C123_CLKSOURCE)
|
||||
LL_RCC_SetClockSource(LL_RCC_I2C123_CLKSOURCE_PCLK1);
|
||||
# if defined(LL_RCC_I2C4_CLKSOURCE)
|
||||
if (instance == I2C4) {
|
||||
LL_RCC_SetClockSource(LL_RCC_I2C4_CLKSOURCE_PCLK4);
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
LL_RCC_SetClockSource(LL_RCC_I2C123_CLKSOURCE_PCLK1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -371,15 +378,17 @@ static int i2c_init_clock_source(I2C_TypeDef* instance)
|
||||
static int i2c_enable_clock(I2C_TypeDef* instance)
|
||||
{
|
||||
/* Peripheral clock enable */
|
||||
if (instance == I2C1) {
|
||||
if (instance == I2C1)
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
} else if (instance == I2C2) {
|
||||
else if (instance == I2C2)
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2);
|
||||
} else if (instance == I2C3) {
|
||||
else if (instance == I2C3)
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
#if defined(I2C4)
|
||||
else if (instance == I2C4)
|
||||
LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_I2C4);
|
||||
#endif
|
||||
else return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -393,6 +402,10 @@ static int i2c_disable_clock(I2C_TypeDef* instance)
|
||||
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C2);
|
||||
else if (instance == I2C3)
|
||||
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
#if defined(I2C4)
|
||||
else if (instance == I2C4)
|
||||
LL_APB4_GRP1_DisableClock(LL_APB4_GRP1_PERIPH_I2C4);
|
||||
#endif
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -472,17 +485,17 @@ int stm32_i2c_init(uint8_t bus, uint32_t clock_rate, const stm32_i2c_hw_def_t* h
|
||||
|
||||
if (i2c_gpio_init(hw_def) < 0) {
|
||||
TRACE("I2C ERROR: HAL_I2C_MspInit() I2C_GPIO misconfiguration");
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (i2c_enable_clock(hw_def->I2Cx) < 0) {
|
||||
TRACE("I2C ERROR: HAL_I2C_MspInit() I2C misconfiguration");
|
||||
return -1;
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (HAL_I2C_Init(h) != HAL_OK) {
|
||||
TRACE("I2C ERROR: HAL_I2C_Init() failed");
|
||||
return -1;
|
||||
return -4;
|
||||
}
|
||||
|
||||
#if defined(I2C_FLTR_ANOFF) && defined(I2C_FLTR_DNF) || defined(STM32H7) || \
|
||||
|
||||
@@ -480,6 +480,7 @@ bool stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params)
|
||||
if (params->direction & ETX_Dir_TX)
|
||||
usartInit.TransferDirection |= LL_USART_DIRECTION_TX;
|
||||
|
||||
|
||||
LL_USART_Init(usart->USARTx, &usartInit);
|
||||
LL_USART_Enable(usart->USARTx);
|
||||
|
||||
|
||||
@@ -380,6 +380,11 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
|
||||
hpcd_USB_OTG.Init.speed = PCD_SPEED_FULL;
|
||||
hpcd_USB_OTG.Init.dma_enable = DISABLE;
|
||||
hpcd_USB_OTG.Init.phy_itface = PCD_PHY_EMBEDDED;
|
||||
#if defined(STM32H7)
|
||||
hpcd_USB_OTG.Init.battery_charging_enable = DISABLE;
|
||||
hpcd_USB_OTG.Init.use_external_vbus = ENABLE;
|
||||
#endif
|
||||
|
||||
hpcd_USB_OTG.Init.Sof_enable = ENABLE;
|
||||
hpcd_USB_OTG.Init.low_power_enable = DISABLE;
|
||||
hpcd_USB_OTG.Init.lpm_enable = DISABLE;
|
||||
|
||||
@@ -864,7 +864,6 @@
|
||||
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
|
||||
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
|
||||
#define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2)
|
||||
#define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000)
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000)
|
||||
|
||||
// Uncomment only one line below to select which storage to use
|
||||
|
||||
@@ -269,7 +269,6 @@
|
||||
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
|
||||
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
|
||||
#define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2)
|
||||
#define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000)
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000)
|
||||
#define STORAGE_USE_SDIO
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ void ledGreen() {}
|
||||
void ledBlue() {}
|
||||
void ledOff() {}
|
||||
void rgbLedColorApply() {}
|
||||
void rgbLedClearAll() {}
|
||||
|
||||
bool fsLedState(uint8_t i)
|
||||
{
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
#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_SAMPTIME LL_ADC_SAMPLINGTIME_8CYCLES_5
|
||||
|
||||
#define ADC_EXT ADC3
|
||||
#define ADC_EXT_CHANNELS \
|
||||
|
||||
@@ -366,7 +366,7 @@ void setTopBatteryValue(uint32_t volts);
|
||||
#define BATTERY_DIVIDER 39500
|
||||
#else
|
||||
#define BATTERY_DIVIDER 26214
|
||||
#endif
|
||||
#endif
|
||||
#define VOLTAGE_DROP 20
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON)
|
||||
option(PXX1 "PXX1 protocol support" ON)
|
||||
option(PXX2 "PXX2 protocol support" OFF)
|
||||
option(AFHDS3 "AFHDS3 TX Module" ON)
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
option(GHOST "Ghost TX Module" ON)
|
||||
option(MODULE_SIZE_STD "Standard size TX Module" ON)
|
||||
option(LUA_MIXER "Enable LUA mixer/model scripts support" ON)
|
||||
option(DISK_CACHE "Enable SD card disk cache" ON)
|
||||
|
||||
set(FIRMWARE_QSPI YES)
|
||||
set(FIRMWARE_FORMAT_UF2 YES)
|
||||
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
|
||||
set(CPU_TYPE STM32H7)
|
||||
set(HSE_VALUE 48000000)
|
||||
set(SDCARD YES)
|
||||
set(STORAGE_MODELSLIST YES)
|
||||
set(HAPTIC YES)
|
||||
set(GUI_DIR colorlcd)
|
||||
set(BITMAPS_DIR 480x272)
|
||||
set(TARGET_DIR tx15)
|
||||
set(RTC_BACKUP_RAM YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)")
|
||||
set(HARDWARE_EXTERNAL_MODULE YES)
|
||||
set(INTERNAL_MODULE_AFHDS3 NO)
|
||||
set(ROTARY_ENCODER YES)
|
||||
set(FUNCTION_SWITCHES_WITH_RGB YES)
|
||||
|
||||
#option(STICKS_DEAD_ZONE "Enable sticks dead zone" YES)
|
||||
|
||||
# IMU support
|
||||
set(IMU ON)
|
||||
add_definitions(-DIMU_ICM4207C)
|
||||
|
||||
# for size report script
|
||||
set(CPU_TYPE_FULL STM32H750xB)
|
||||
set(TARGET_LINKER_DIR stm32h750_sdram)
|
||||
set(TARGET_EXTRAM_START 0xD0000000)
|
||||
set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192")
|
||||
set(FIRMWARE_STRIP_BOOTLOADER YES)
|
||||
|
||||
add_definitions(-DPCBTX15 -DPCBHORUS)
|
||||
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)
|
||||
add_definitions(-DUSB_CHARGER)
|
||||
|
||||
set(FLAVOUR tx15)
|
||||
add_definitions(-DRADIO_TX15)
|
||||
add_definitions(-DMANUFACTURER_RADIOMASTER)
|
||||
|
||||
# defines existing internal modules
|
||||
set(INTERNAL_MODULES CRSF CACHE STRING "Internal modules")
|
||||
set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module")
|
||||
|
||||
set(BITMAPS_TARGET bm480_bitmaps)
|
||||
set(FONTS_TARGET x12_fonts)
|
||||
set(LCD_DRIVER lcd_driver.cpp)
|
||||
set(HARDWARE_TOUCH YES)
|
||||
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
|
||||
set(FIRMWARE_DEPENDENCIES datacopy)
|
||||
set(SOFTWARE_KEYBOARD ON)
|
||||
set(FLYSKY_GIMBAL ON)
|
||||
set(FUNCTION_SWITCHES ON)
|
||||
set(USB_CHARGER YES)
|
||||
set(AUX_SERIAL YES)
|
||||
set(AUX2_SERIAL YES)
|
||||
|
||||
add_definitions(
|
||||
-DSTM32H750XBTx -DSTM32H750xx
|
||||
-DSDRAM -DCCMRAM
|
||||
-DCOLORLCD -DLIBOPENUI
|
||||
-DHARDWARE_TOUCH -DHARDWARE_KEYS -DSOFTWARE_KEYBOARD
|
||||
-DWS2812_MAX_LEDS=26
|
||||
)
|
||||
|
||||
set(SDRAM ON)
|
||||
|
||||
add_definitions(-DAUDIO -DVOICE -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
|
||||
${TARGET_SRC_DIR}/usb_charger_driver.cpp
|
||||
targets/common/arm/stm32/abnormal_reboot.cpp
|
||||
targets/common/arm/stm32/delays_driver.cpp
|
||||
targets/common/arm/stm32/dma2d.cpp
|
||||
targets/common/arm/stm32/flash_driver.cpp
|
||||
targets/common/arm/stm32/pwr_driver.cpp
|
||||
targets/common/arm/stm32/rotary_encoder_driver.cpp
|
||||
targets/common/arm/stm32/rtc_driver.cpp
|
||||
targets/common/arm/stm32/watchdog_driver.cpp
|
||||
drivers/pca95xx.cpp
|
||||
)
|
||||
|
||||
# Bootloader board library
|
||||
add_library(board_bl OBJECT EXCLUDE_FROM_ALL
|
||||
${BOARD_COMMON_SRC}
|
||||
${TARGET_SRC_DIR}/system_clock.c
|
||||
${TARGET_SRC_DIR}/sdram_driver.cpp
|
||||
${TARGET_SRC_DIR}/usb_charger_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}/tp_gt911.cpp
|
||||
${TARGET_SRC_DIR}/audio_driver.cpp
|
||||
drivers/icm42607C.cpp
|
||||
drivers/imu_filter.cpp
|
||||
drivers/tas2505.cpp
|
||||
targets/common/arm/stm32/heartbeat_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_i2s.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,156 @@
|
||||
#include "drivers/tas2505.h"
|
||||
|
||||
#include "stm32_dma.h"
|
||||
#include "stm32_i2s.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define DEFAULT_DAC_VOL -15 // -7dB
|
||||
#define DEFAULT_HP_VOL 20
|
||||
#define DEFAULT_SPK_VOL 40
|
||||
|
||||
static tas2505_t _tas2505 = {
|
||||
.ndac = 2,
|
||||
.mdac = 1,
|
||||
.dosr = 256,
|
||||
.dac_vol = DEFAULT_DAC_VOL,
|
||||
.hp_drv = 0,
|
||||
.hp_vol = DEFAULT_HP_VOL,
|
||||
.spk_drv = TAS2505_SPK_DRV_32_DB,
|
||||
.spk_vol = DEFAULT_SPK_VOL,
|
||||
};
|
||||
|
||||
//
|
||||
// TX15 pinout
|
||||
//
|
||||
// Pin MCU TAS2505
|
||||
// ---------------------------------
|
||||
// PC6 (I2S2_MCK): MCLK <-> MCLK
|
||||
// PI0 (I2S2_WS): WCLK <-> WCLK
|
||||
// PI1 (I2S2_CK): BCLK <-> BCLK
|
||||
// PI3 (I2S2_SDO): DOUT <-> DIN
|
||||
// PC2 (I2S2_SDI): DIN <-> DOUT
|
||||
|
||||
|
||||
const stm32_i2s_t _i2s_dev = {
|
||||
.SPIx = AUDIO_SPI,
|
||||
.MCK = {GPIO_PIN(GPIOC, 6), GPIO_AF5},
|
||||
.WS = {GPIO_PIN(GPIOI, 0), GPIO_AF5},
|
||||
.CK = {GPIO_PIN(GPIOI, 1), GPIO_AF5},
|
||||
.SDO = {GPIO_PIN(GPIOI, 3), GPIO_AF5},
|
||||
.SDI = {GPIO_PIN(GPIOI, 2), GPIO_AF5},
|
||||
|
||||
.DMA = I2S_DMA,
|
||||
.DMA_Stream = I2S_DMA_Stream,
|
||||
.DMA_PeriphRequest = I2S_DMA_Stream_Request,
|
||||
};
|
||||
|
||||
// 16 bit, 2 channels
|
||||
#define DMA_BUFFER_HALF_LEN AUDIO_BUFFER_SIZE
|
||||
|
||||
// 2 buffers
|
||||
#define DMA_BUFFER_LEN (DMA_BUFFER_HALF_LEN * 2)
|
||||
|
||||
static int32_t _dma_buffer[DMA_BUFFER_LEN] __DMA_NO_CACHE;
|
||||
|
||||
static void enable_dma_irqs()
|
||||
{
|
||||
LL_DMA_EnableIT_HT(I2S_DMA, I2S_DMA_Stream);
|
||||
LL_DMA_EnableIT_TC(I2S_DMA, I2S_DMA_Stream);
|
||||
|
||||
NVIC_SetPriority(I2S_DMA_Stream_IRQn, 7);
|
||||
NVIC_EnableIRQ(I2S_DMA_Stream_IRQn);
|
||||
}
|
||||
|
||||
int audioInit()
|
||||
{
|
||||
gpio_init(AUDIO_HP_DETECT_PIN, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
|
||||
memset(_dma_buffer, 0, sizeof(_dma_buffer));
|
||||
|
||||
if (tas2505_probe(&_tas2505, 0, 0x30 >> 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stm32_i2s_init(&_i2s_dev)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enable_dma_irqs();
|
||||
return tas2505_init(&_tas2505);
|
||||
}
|
||||
|
||||
static volatile uint32_t _dma_buffer_offset = 0;
|
||||
|
||||
void audioConsumeCurrentBuffer()
|
||||
{
|
||||
if (!stm32_i2s_is_xfer_started(&_i2s_dev)) {
|
||||
|
||||
auto buffer = audioQueue.buffersFifo.getNextFilledBuffer();
|
||||
if (!buffer) return;
|
||||
|
||||
unsigned idx = 0;
|
||||
for (; idx < buffer->size; idx++) {
|
||||
uint32_t offset = _dma_buffer_offset + idx;
|
||||
_dma_buffer[offset] = (uint32_t)buffer->data[idx];
|
||||
}
|
||||
for (; idx < DMA_BUFFER_HALF_LEN; idx++) {
|
||||
uint32_t offset = _dma_buffer_offset + idx;
|
||||
_dma_buffer[offset] = 0;
|
||||
}
|
||||
audioQueue.buffersFifo.freeNextFilledBuffer();
|
||||
stm32_i2s_config_dma_stream(&_i2s_dev, _dma_buffer, DMA_BUFFER_LEN * 2);
|
||||
stm32_i2s_start_dma_stream(&_i2s_dev);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t _calc_offset(uint8_t tc)
|
||||
{
|
||||
return tc * DMA_BUFFER_HALF_LEN;
|
||||
}
|
||||
|
||||
static void audio_update_dma_buffer(uint8_t tc)
|
||||
{
|
||||
_dma_buffer_offset = _calc_offset(tc);
|
||||
|
||||
auto buffer = audioQueue.buffersFifo.getNextFilledBuffer();
|
||||
if (!buffer) {
|
||||
unsigned idx = 0;
|
||||
for (; idx < DMA_BUFFER_HALF_LEN; idx++) {
|
||||
uint32_t offset = _dma_buffer_offset + idx;
|
||||
_dma_buffer[offset] = 0;
|
||||
}
|
||||
} else {
|
||||
unsigned idx = 0;
|
||||
for (; idx < buffer->size; idx++) {
|
||||
uint32_t offset = _dma_buffer_offset + idx;
|
||||
_dma_buffer[offset] = (uint16_t)buffer->data[idx];
|
||||
}
|
||||
for (; idx < DMA_BUFFER_HALF_LEN; idx++) {
|
||||
uint32_t offset = _dma_buffer_offset + idx;
|
||||
_dma_buffer[offset] = 0;
|
||||
}
|
||||
audioQueue.buffersFifo.freeNextFilledBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void audioSetVolume(uint8_t volume)
|
||||
{
|
||||
tas2505_set_volume(&_tas2505, volume * 9 / 10); // TX15 HP cannot handle the full power of TAS2505
|
||||
}
|
||||
|
||||
extern "C" void DMA1_Stream4_IRQHandler(void)
|
||||
{
|
||||
if (stm32_dma_check_ht_flag(I2S_DMA, I2S_DMA_Stream)) {
|
||||
audio_update_dma_buffer(0);
|
||||
}
|
||||
|
||||
if (stm32_dma_check_tc_flag(I2S_DMA, I2S_DMA_Stream)) {
|
||||
audio_update_dma_buffer(1);
|
||||
}
|
||||
}
|
||||
@@ -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 = BACKLIGHT_TIMER_CHANNEL,
|
||||
.TIM_IRQn = (IRQn_Type)-1,
|
||||
.DMAx = nullptr,
|
||||
.DMA_Stream = 0,
|
||||
.DMA_Channel = 0,
|
||||
.DMA_IRQn = (IRQn_Type)-1,
|
||||
.DMA_TC_CallbackPtr = nullptr,
|
||||
};
|
||||
|
||||
void backlightLowInit()
|
||||
{
|
||||
gpio_init(BACKLIGHT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_clear(BACKLIGHT_GPIO);
|
||||
}
|
||||
|
||||
void backlightInit()
|
||||
{
|
||||
stm32_pulse_init(&_bl_timer, 1000000);
|
||||
stm32_pulse_config_output(&_bl_timer, true, LL_TIM_OCMODE_PWM1, 100);
|
||||
LL_TIM_SetAutoReload(_bl_timer.TIMx, 100);
|
||||
LL_TIM_EnableCounter(_bl_timer.TIMx);
|
||||
}
|
||||
|
||||
uint8_t lastDutyCycle = 0;
|
||||
|
||||
void backlightEnable(uint8_t dutyCycle)
|
||||
{
|
||||
stm32_pulse_set_cmp_val(&_bl_timer, dutyCycle);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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/flash_driver.h"
|
||||
#include "hal/trainer_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/gpio.h"
|
||||
#include "hal/rgbleds.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "sdcard.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "flysky_gimbal_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#include "bitmapbuffer.h"
|
||||
#include "colors.h"
|
||||
|
||||
#include "touch_driver.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// common ADC driver
|
||||
extern const etx_hal_adc_driver_t _adc_driver;
|
||||
|
||||
// RGB LED timer
|
||||
extern const stm32_pulse_timer_t _led_timer;
|
||||
|
||||
static void led_strip_off()
|
||||
{
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
ws2812_set_color(i, 0, 0, 0);
|
||||
}
|
||||
ws2812_update(&_led_timer);
|
||||
}
|
||||
|
||||
void INTERNAL_MODULE_ON()
|
||||
{
|
||||
gpio_set(INTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void INTERNAL_MODULE_OFF()
|
||||
{
|
||||
gpio_clear(INTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_ON()
|
||||
{
|
||||
gpio_set(EXTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_OFF()
|
||||
{
|
||||
gpio_clear(EXTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void boardBLEarlyInit()
|
||||
{
|
||||
// TAS2505 requires reset pin to be low on power on
|
||||
gpio_init(AUDIO_RESET_PIN, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_clear(AUDIO_RESET_PIN);
|
||||
|
||||
timersInit();
|
||||
bsp_io_init();
|
||||
usbChargerInit();
|
||||
}
|
||||
|
||||
void boardBLPreJump()
|
||||
{
|
||||
// TAS2505 requires reset pin to be high only after power on
|
||||
// https://www.ti.com/lit/ug/slau472c/slau472c.pd fig 4.2
|
||||
gpio_set(AUDIO_RESET_PIN);
|
||||
ExtFLASH_Init();
|
||||
SDRAM_Init();
|
||||
|
||||
// Stop 1ms timer
|
||||
MS_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void boardBLInit()
|
||||
{
|
||||
ExtFLASH_Init();
|
||||
SDRAM_Init();
|
||||
|
||||
// register external FLASH for DFU
|
||||
usbRegisterDFUMedia((void*)extflash_dfu_media);
|
||||
|
||||
// register internal & external FLASH for UF2
|
||||
flashRegisterDriver(FLASH_BANK1_BASE, BOOTLOADER_SIZE, &stm32_flash_driver);
|
||||
flashRegisterDriver(QSPI_BASE, 8 * 1024 * 1024, &extflash_driver);
|
||||
}
|
||||
|
||||
void boardInit()
|
||||
{
|
||||
// enable interrupts
|
||||
__enable_irq();
|
||||
|
||||
ledInit();
|
||||
boardInitModulePorts();
|
||||
|
||||
pwrInit();
|
||||
delaysInit();
|
||||
timersInit();
|
||||
|
||||
bsp_io_init();
|
||||
usbChargerInit();
|
||||
gpio_set(LED_BLUE_GPIO);
|
||||
gpio_init(HALL_SYNC, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
|
||||
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);
|
||||
|
||||
// init_trainer();
|
||||
auto inittime = flysky_gimbal_init();
|
||||
if (inittime)
|
||||
TRACE("Serial gimbal detected in %d ms", inittime);
|
||||
else
|
||||
TRACE("No serial gimbal detected");
|
||||
|
||||
usbInit();
|
||||
|
||||
rgbLedInit();
|
||||
led_strip_off();
|
||||
|
||||
keysInit();
|
||||
switchInit();
|
||||
rotaryEncoderInit();
|
||||
touchPanelInit();
|
||||
audioInit();
|
||||
adcInit(&_adc_driver);
|
||||
hapticInit();
|
||||
|
||||
// RTC must be initialized before rambackupRestore() is called
|
||||
rtcInit();
|
||||
}
|
||||
|
||||
extern void rtcDisableBackupReg();
|
||||
|
||||
void boardOff()
|
||||
{
|
||||
lcdOff();
|
||||
|
||||
while (pwrPressed()) {
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
SysTick->CTRL = 0; // turn off systick
|
||||
|
||||
// Shutdown the Haptic
|
||||
hapticDone();
|
||||
|
||||
rtcDisableBackupReg();
|
||||
|
||||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include "definitions.h"
|
||||
#include "edgetx_constants.h"
|
||||
|
||||
#include "board_common.h"
|
||||
#include "hal.h"
|
||||
#include "hal/serial_port.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#define BOOTLOADER_SIZE 0x10000
|
||||
#define BOOTLOADER_ADDRESS 0x08000000
|
||||
#define FIRMWARE_ADDRESS 0x90000000
|
||||
#define FIRMWARE_LEN(fsize) (fsize)
|
||||
#define FIRMWARE_MAX_LEN FLASHSIZE
|
||||
#define APP_START_ADDRESS (uint32_t)(FIRMWARE_ADDRESS)
|
||||
|
||||
#define BOOTLOADER_KEYS 0x42
|
||||
|
||||
#define MB *1024*1024
|
||||
#define LUA_MEM_EXTRA_MAX (2 MB) // max allowed memory usage for Lua bitmaps (in bytes)
|
||||
#define LUA_MEM_MAX (6 MB) // max allowed memory usage for complete Lua (in bytes), 0 means unlimited
|
||||
|
||||
extern uint16_t sessionTimer;
|
||||
|
||||
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
|
||||
|
||||
// Board driver
|
||||
void boardInit();
|
||||
void boardOff();
|
||||
|
||||
// CPU Unique ID
|
||||
#define LEN_CPU_UID (3*8+2)
|
||||
void getCPUUniqueID(char * s);
|
||||
|
||||
// Flash Write driver
|
||||
#define FLASH_PAGESIZE 256
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
// SDRAM driver
|
||||
extern "C" void SDRAM_Init();
|
||||
|
||||
// Pulses driver
|
||||
#if !defined(SIMU)
|
||||
|
||||
void INTERNAL_MODULE_ON();
|
||||
void INTERNAL_MODULE_OFF();
|
||||
void EXTERNAL_MODULE_ON();
|
||||
void EXTERNAL_MODULE_OFF();
|
||||
#define EXTERNAL_MODULE_PWR_OFF EXTERNAL_MODULE_OFF
|
||||
#define BLUETOOTH_MODULE_ON() gpio_clear(BLUETOOTH_ON_GPIO)
|
||||
#define BLUETOOTH_MODULE_OFF() gpio_set(BLUETOOTH_ON_GPIO)
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (gpio_read(EXTMODULE_PWR_GPIO) ? 1 : 0)
|
||||
|
||||
#else
|
||||
|
||||
#define INTERNAL_MODULE_OFF()
|
||||
#define INTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_OFF()
|
||||
#define BLUETOOTH_MODULE_ON()
|
||||
#define BLUETOOTH_MODULE_OFF()
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (false)
|
||||
|
||||
#endif // defined(SIMU)
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
#define NUM_FUNCTIONS_SWITCHES 6
|
||||
#define NUM_FUNCTIONS_GROUPS 3
|
||||
#define DEFAULT_FS_CONFIG \
|
||||
(SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \
|
||||
(SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0)
|
||||
|
||||
#define DEFAULT_FS_GROUPS \
|
||||
(1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \
|
||||
(1 << 0) // Set all FS to group 1 to act like a 6pos
|
||||
|
||||
#define DEFAULT_FS_STARTUP_CONFIG \
|
||||
((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \
|
||||
(FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \
|
||||
(FS_START_PREVIOUS << 2) + \
|
||||
(FS_START_PREVIOUS << 0)) // keep last state by default
|
||||
|
||||
#else
|
||||
#define NUM_FUNCTIONS_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#define NUM_TRIMS 8
|
||||
#define DEFAULT_STICK_DEADZONE 2
|
||||
|
||||
#define BATTERY_WARN 74 // 7.4V
|
||||
#define BATTERY_MIN 70 // 6.8V
|
||||
#define BATTERY_MAX 86 // 8.6V
|
||||
|
||||
// --- MOSFET ---- R1 --- MCU
|
||||
// |__ R2 --- GND
|
||||
//
|
||||
#define VBAT_DIV_R1 100 // kOhms
|
||||
#define VBAT_DIV_R2 32 // kOhms
|
||||
#define VBAT_MOSFET_DROP 0 // * 10mV
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Power driver
|
||||
#define SOFT_PWR_CTRL
|
||||
#define POWER_ON_DELAY 10 // 1s
|
||||
void pwrInit();
|
||||
void extModuleInit();
|
||||
uint32_t pwrCheck();
|
||||
uint32_t lowPowerCheck();
|
||||
|
||||
void pwrOn();
|
||||
void pwrSoftReboot();
|
||||
void pwrOff();
|
||||
void pwrResetHandler();
|
||||
bool pwrPressed();
|
||||
bool pwrOffPressed();
|
||||
#if defined(PWR_EXTRA_SWITCH_GPIO)
|
||||
bool pwrForcePressed();
|
||||
#else
|
||||
#define pwrForcePressed() false
|
||||
#endif
|
||||
uint32_t pwrPressedDuration();;
|
||||
|
||||
const etx_serial_port_t* auxSerialGetPort(int port_nr);
|
||||
#define AUX_SERIAL_POWER_ON()
|
||||
#define AUX_SERIAL_POWER_OFF()
|
||||
|
||||
// LED driver
|
||||
void ledInit();
|
||||
void ledOff();
|
||||
void ledRed();
|
||||
void ledBlue();
|
||||
void ledGreen();
|
||||
|
||||
// LCD driver
|
||||
void lcdSetInitalFrameBuffer(void* fbAddress);
|
||||
void lcdInit();
|
||||
void lcdCopy(void * dest, void * src);
|
||||
|
||||
void lcdOff();
|
||||
void lcdOn();
|
||||
|
||||
#define lcdRefreshWait(...)
|
||||
|
||||
// Backlight driver
|
||||
#define BACKLIGHT_LEVEL_MAX 100
|
||||
#define BACKLIGHT_FORCED_ON BACKLIGHT_LEVEL_MAX + 1
|
||||
#define BACKLIGHT_LEVEL_MIN 1
|
||||
|
||||
extern bool boardBacklightOn;
|
||||
void backlightLowInit( void );
|
||||
void backlightInit();
|
||||
void backlightEnable(uint8_t dutyCycle);
|
||||
void backlightFullOn();
|
||||
bool isBacklightEnabled();
|
||||
|
||||
#define BACKLIGHT_ENABLE() \
|
||||
{ \
|
||||
boardBacklightOn = true; \
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX - currentBacklightBright); \
|
||||
}
|
||||
|
||||
#define BACKLIGHT_DISABLE() \
|
||||
{ \
|
||||
boardBacklightOn = false; \
|
||||
backlightEnable(((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && \
|
||||
(g_eeGeneral.backlightMode != e_backlight_mode_off)) \
|
||||
? 0 \
|
||||
: g_eeGeneral.blOffBright); \
|
||||
}
|
||||
|
||||
#define USB_NAME "TX15"
|
||||
#define USB_MANUFACTURER 'R', 'M', ' ', ' ', ' ', ' ', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'T', 'X', '1', '5', ' ', ' ', ' ', ' ' /* 8 Bytes */
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
}
|
||||
#endif
|
||||
|
||||
int audioInit();
|
||||
void audioConsumeCurrentBuffer();
|
||||
|
||||
// Telemetry driver
|
||||
#define INTMODULE_FIFO_SIZE 512
|
||||
#define TELEMETRY_FIFO_SIZE 512
|
||||
|
||||
// Haptic driver
|
||||
void hapticInit();
|
||||
void hapticDone();
|
||||
void hapticOff();
|
||||
void hapticOn(uint32_t pwmPercent);
|
||||
|
||||
// Second serial port driver
|
||||
//#define AUX_SERIAL
|
||||
#define DEBUG_BAUDRATE 115200
|
||||
#define LUA_DEFAULT_BAUDRATE 115200
|
||||
|
||||
extern uint8_t currentTrainerMode;
|
||||
void checkTrainerSettings();
|
||||
|
||||
// Touch panel driver
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState touchPanelRead();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
// USB Charger
|
||||
#if defined(USB_CHARGER)
|
||||
void usbChargerInit();
|
||||
bool usbChargerLed();
|
||||
#endif
|
||||
|
||||
#endif // _BOARD_H_
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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 "stm32_ws2812.h"
|
||||
#include "stm32_switch_driver.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "drivers/pca95xx.h"
|
||||
#include "timers_driver.h"
|
||||
#include "delays_driver.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if !defined(BOOT)
|
||||
#include "os/async.h"
|
||||
#include "os/timer.h"
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
extern const stm32_switch_t* boardGetSwitchDef(uint8_t idx);
|
||||
|
||||
struct bsp_io_expander {
|
||||
pca95xx_t exp;
|
||||
uint32_t mask;
|
||||
uint32_t state;
|
||||
};
|
||||
|
||||
static volatile bool _poll_switches_in_queue = false;
|
||||
|
||||
static bsp_io_expander _io_switches;
|
||||
static bsp_io_expander _io_fs_switches;
|
||||
|
||||
#if !defined(BOOT)
|
||||
static timer_handle_t _poll_timer = TIMER_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static void _init_io_expander(bsp_io_expander* io, uint32_t mask)
|
||||
{
|
||||
io->mask = mask;
|
||||
io->state = 0;
|
||||
}
|
||||
|
||||
static volatile uint8_t pca95xx_errors = 0;
|
||||
|
||||
static uint32_t _read_io_expander(bsp_io_expander* io)
|
||||
{
|
||||
uint16_t value = 0;
|
||||
if (pca95xx_read(&io->exp, io->mask, &value) == 0) {
|
||||
io->state = value;
|
||||
} else {
|
||||
if (pca95xx_errors++ > 5) {
|
||||
gpio_clear(IO_RESET_GPIO);
|
||||
pca95xx_errors = 0;
|
||||
delay_us(1); // Only 6ns are needed according to PCA datasheet, but lets be safe
|
||||
gpio_set(IO_RESET_GPIO);
|
||||
}
|
||||
}
|
||||
|
||||
return io->state;
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
typedef enum {
|
||||
TRIGGERED_BY_TIMER = 0,
|
||||
TRIGGERED_BY_IRQ,
|
||||
} trigger_source_t;
|
||||
|
||||
static void _poll_switches(void *param1, uint32_t trigger_source)
|
||||
{
|
||||
if (trigger_source == TRIGGERED_BY_IRQ) {
|
||||
_poll_switches_in_queue = false;
|
||||
timer_reset(&_poll_timer);
|
||||
}
|
||||
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
}
|
||||
|
||||
static void _io_int_handler()
|
||||
{
|
||||
async_call_isr(_poll_switches, &_poll_switches_in_queue, nullptr,
|
||||
TRIGGERED_BY_IRQ);
|
||||
}
|
||||
|
||||
static void _poll_cb(timer_handle_t* timer)
|
||||
{
|
||||
(void)timer;
|
||||
_poll_switches(nullptr, TRIGGERED_BY_TIMER);
|
||||
}
|
||||
|
||||
static void start_poll_timer()
|
||||
{
|
||||
timer_create(&_poll_timer, _poll_cb, "portex", 100, true);
|
||||
timer_start(&_poll_timer);
|
||||
}
|
||||
#endif
|
||||
|
||||
int bsp_io_init()
|
||||
{
|
||||
int i2cError = i2c_init(I2C_Bus_1);
|
||||
if (i2cError < 0) {
|
||||
TRACE("I2C INIT ERROR: %d", i2cError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// setup expanders reset pin
|
||||
gpio_init(IO_RESET_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_clear(IO_RESET_GPIO);
|
||||
gpio_set(IO_RESET_GPIO);
|
||||
|
||||
// configure expander 1
|
||||
_init_io_expander(&_io_fs_switches, 0xFF3F);
|
||||
if (pca95xx_init(&_io_fs_switches.exp, I2C_Bus_1, 0x74) < 0) {
|
||||
TRACE("EXP1 INIT ERROR");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// configure expander 2
|
||||
_init_io_expander(&_io_switches, 0xFFF8);
|
||||
if (pca95xx_init(&_io_switches.exp, I2C_Bus_1, 0x75) < 0) {
|
||||
TRACE("EXP2 INIT ERROR");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
// setup expanders pin change interrupt
|
||||
gpio_init_int(IO_INT_GPIO, GPIO_IN, GPIO_FALLING, _io_int_handler);
|
||||
#endif
|
||||
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
|
||||
#if !defined(BOOT)
|
||||
start_poll_timer();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t bsp_get_fs_switches()
|
||||
{
|
||||
return _io_fs_switches.state;
|
||||
}
|
||||
|
||||
void boardInitSwitches()
|
||||
{
|
||||
bsp_io_init();
|
||||
}
|
||||
|
||||
static SwitchHwPos _get_switch_pos(uint8_t idx)
|
||||
{
|
||||
SwitchHwPos pos = SWITCH_HW_UP;
|
||||
|
||||
const stm32_switch_t* def = boardGetSwitchDef(idx);
|
||||
uint32_t state = _io_switches.state;
|
||||
|
||||
if (def->isCustomSwitch) {
|
||||
if ((state & def->Pin_high) == 0) {
|
||||
return SWITCH_HW_DOWN;
|
||||
} else {
|
||||
return SWITCH_HW_UP;
|
||||
}
|
||||
}
|
||||
else if (!def->Pin_low) {
|
||||
// 2POS switch
|
||||
if ((state & def->Pin_high) == 0) {
|
||||
pos = SWITCH_HW_DOWN;
|
||||
}
|
||||
} else {
|
||||
bool hi = state & def->Pin_high;
|
||||
bool lo = state & def->Pin_low;
|
||||
|
||||
if (hi && lo) {
|
||||
pos = SWITCH_HW_MID;
|
||||
} else if (!hi && lo) {
|
||||
pos = SWITCH_HW_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static SwitchHwPos _get_fs_switch_pos(uint8_t idx)
|
||||
{
|
||||
const stm32_switch_t* def = boardGetSwitchDef(idx);
|
||||
uint32_t state = _io_fs_switches.state;
|
||||
if ((state & def->Pin_high) == 0) {
|
||||
return SWITCH_HW_DOWN;
|
||||
} else {
|
||||
return SWITCH_HW_UP;
|
||||
}
|
||||
}
|
||||
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t idx)
|
||||
{
|
||||
if (idx < 6)
|
||||
return _get_switch_pos(idx);
|
||||
return _get_fs_switch_pos(idx);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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/pca95xx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
// Port expander 1 (0x74)
|
||||
#define SWITCH_A_L PCA95XX_P14
|
||||
#define SWITCH_A_H PCA95XX_P15
|
||||
#define SWITCH_B_L PCA95XX_P12
|
||||
#define SWITCH_B_H PCA95XX_P13
|
||||
#define SWITCH_C_L PCA95XX_P10
|
||||
#define SWITCH_C_H PCA95XX_P11
|
||||
#define SWITCH_D_L PCA95XX_P6
|
||||
#define SWITCH_D_H PCA95XX_P7
|
||||
#define SWITCH_E_L PCA95XX_P16
|
||||
#define SWITCH_E_H PCA95XX_P17
|
||||
#define SWITCH_F_H PCA95XX_P4
|
||||
#define SWITCH_F_L PCA95XX_P5
|
||||
|
||||
// Port expander 2 (0x75)
|
||||
#define BSP_TR1U PCA95XX_PIN_13
|
||||
#define BSP_TR1D PCA95XX_PIN_12
|
||||
|
||||
#define BSP_TR2U PCA95XX_PIN_11
|
||||
#define BSP_TR2D PCA95XX_PIN_10
|
||||
|
||||
#define BSP_TR3L PCA95XX_PIN_15
|
||||
#define BSP_TR3R PCA95XX_PIN_14
|
||||
|
||||
#define BSP_TR4L PCA95XX_PIN_9
|
||||
#define BSP_TR4R PCA95XX_PIN_8
|
||||
|
||||
#define FSSWITCH_1 PCA95XX_P0
|
||||
#define FSSWITCH_2 PCA95XX_P1
|
||||
#define FSSWITCH_3 PCA95XX_P2
|
||||
#define FSSWITCH_4 PCA95XX_P3
|
||||
#define FSSWITCH_5 PCA95XX_P4
|
||||
#define FSSWITCH_6 PCA95XX_P5
|
||||
|
||||
extern uint8_t isSwitch3Pos(uint8_t idx);
|
||||
|
||||
int bsp_io_init();
|
||||
uint32_t bsp_io_read_switches();
|
||||
uint32_t bsp_io_read_fs_switches();
|
||||
uint32_t bsp_get_fs_switches();
|
||||
|
||||
uint16_t bsp_input_get();
|
||||
struct stm32_switch_t;
|
||||
@@ -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
|
||||
@@ -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,593 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
STM32H750
|
||||
|
||||
SDMMC uses own DMA controler
|
||||
|
||||
DMA1
|
||||
Stream0: LED_STRIP_TIMER_DMA_STREAM
|
||||
Stream1: INTMODULE_DMA_STREAM
|
||||
Stream2: FLYSKY_HALL_DMA_Stream_RX
|
||||
Stream3: TELEMETRY_DMA_Stream_RX
|
||||
Stream4: I2S_DMA_Stream
|
||||
Stream5: INTMODULE_RX_DMA_STREAM
|
||||
Stream6: AUX2_SERIAL_DMA_RX_STREAM
|
||||
Stream7: TELEMETRY_DMA_Stream_TX
|
||||
|
||||
DMA2
|
||||
Stream0: ADC_EXT_DMA_STREAM (do not move)
|
||||
Stream1: AUX_SERIAL_DMA_TX_STREAM
|
||||
Stream2: AUX_SERIAL_DMA_RX_STREAM
|
||||
Stream3: EXTMODULE_TIMER_DMA_STREAM
|
||||
Stream4: ADC_DMA_STREAM (do not move)
|
||||
Stream5: EXTMODULE_USART_RX_DMA_STREAM
|
||||
Stream6: EXTMODULE_USART_TX_DMA_STREAM
|
||||
Stream7: AUX2_SERIAL_DMA_TX_STREAM
|
||||
|
||||
TIM1: BACKLIGHT_TIMER
|
||||
TIM2: LED_STRIP_TIMER
|
||||
TIM3: HAPTIC_GPIO_TIMER
|
||||
TIM4:
|
||||
TIM5: EXTMODULE_TIMER
|
||||
TIM7:
|
||||
TIM8: TRAINER_TIMER
|
||||
TIM12: MIXER_SCHEDULER_TIMER
|
||||
TIM14: MS_TIMER
|
||||
TIM15: PDM
|
||||
TIM16:
|
||||
TIM17: ROTARY_ENCODER_TIMER
|
||||
*/
|
||||
|
||||
#ifndef _HAL_H_
|
||||
#define _HAL_H_
|
||||
|
||||
#define CPU_FREQ 480000000
|
||||
|
||||
#define PERI1_FREQUENCY 120000000
|
||||
#define PERI2_FREQUENCY 120000000
|
||||
#define TIMER_MULT_APB1 2
|
||||
#define TIMER_MULT_APB2 2
|
||||
|
||||
// Keys
|
||||
#define KEYS_GPIO_REG_PAGEDN GPIOA
|
||||
#define KEYS_GPIO_PIN_PAGEDN LL_GPIO_PIN_8 // PA.08
|
||||
#define KEYS_GPIO_REG_PAGEUP GPIOG
|
||||
#define KEYS_GPIO_PIN_PAGEUP LL_GPIO_PIN_7 // PG.07
|
||||
#define KEYS_GPIO_REG_SYS GPIOB
|
||||
#define KEYS_GPIO_PIN_SYS LL_GPIO_PIN_2 // PB.02
|
||||
#define KEYS_GPIO_REG_ENTER GPIOG
|
||||
#define KEYS_GPIO_PIN_ENTER LL_GPIO_PIN_12 // PG.12
|
||||
#define KEYS_GPIO_REG_MDL GPIOE
|
||||
#define KEYS_GPIO_PIN_MDL LL_GPIO_PIN_3 // PE.03
|
||||
#define KEYS_GPIO_REG_EXIT GPIOG
|
||||
#define KEYS_GPIO_PIN_EXIT LL_GPIO_PIN_3 // PG.03
|
||||
#define KEYS_GPIO_REG_TELE GPIOG
|
||||
#define KEYS_GPIO_PIN_TELE LL_GPIO_PIN_2 // PG.02
|
||||
|
||||
// Trims
|
||||
#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
|
||||
//SW1
|
||||
#define SWITCHES_GPIO_REG_G
|
||||
#define SWITCHES_GPIO_PIN_G PCA95XX_P0
|
||||
#define SWITCHES_G_CFS_IDX 0
|
||||
#define FUNCTION_SWITCH_1 SG
|
||||
//SW2
|
||||
#define SWITCHES_GPIO_REG_H
|
||||
#define SWITCHES_GPIO_PIN_H PCA95XX_P1
|
||||
#define SWITCHES_H_CFS_IDX 1
|
||||
#define FUNCTION_SWITCH_2 SH
|
||||
//SW3
|
||||
#define SWITCHES_GPIO_REG_I
|
||||
#define SWITCHES_GPIO_PIN_I PCA95XX_P2
|
||||
#define SWITCHES_I_CFS_IDX 2
|
||||
#define FUNCTION_SWITCH_3 SI
|
||||
//SW4
|
||||
#define SWITCHES_GPIO_REG_J
|
||||
#define SWITCHES_GPIO_PIN_J PCA95XX_P3
|
||||
#define SWITCHES_J_CFS_IDX 3
|
||||
#define FUNCTION_SWITCH_4 SJ
|
||||
//SW5
|
||||
#define SWITCHES_GPIO_REG_K
|
||||
#define SWITCHES_GPIO_PIN_K PCA95XX_P4
|
||||
#define SWITCHES_K_CFS_IDX 4
|
||||
#define FUNCTION_SWITCH_5 SK
|
||||
//SW6
|
||||
#define SWITCHES_GPIO_REG_L
|
||||
#define SWITCHES_GPIO_PIN_L PCA95XX_P5
|
||||
#define SWITCHES_L_CFS_IDX 5
|
||||
#define FUNCTION_SWITCH_6 SL
|
||||
|
||||
// Extender Switches
|
||||
#define SWITCHES_A_3POS
|
||||
#define SWITCHES_GPIO_REG_A_H
|
||||
#define SWITCHES_GPIO_PIN_A_H PCA95XX_P15
|
||||
#define SWITCHES_GPIO_REG_A_L
|
||||
#define SWITCHES_GPIO_PIN_A_L PCA95XX_P14
|
||||
#define SWITCHES_B_3POS
|
||||
#define SWITCHES_GPIO_REG_B_H
|
||||
#define SWITCHES_GPIO_PIN_B_H PCA95XX_P13
|
||||
#define SWITCHES_GPIO_REG_B_L
|
||||
#define SWITCHES_GPIO_PIN_B_L PCA95XX_P12
|
||||
#define SWITCHES_C_3POS
|
||||
#define SWITCHES_GPIO_REG_C_H
|
||||
#define SWITCHES_GPIO_PIN_C_H PCA95XX_P11
|
||||
#define SWITCHES_GPIO_REG_C_L
|
||||
#define SWITCHES_GPIO_PIN_C_L PCA95XX_P10
|
||||
#define SWITCHES_D_3POS
|
||||
#define SWITCHES_GPIO_REG_D_H
|
||||
#define SWITCHES_GPIO_PIN_D_H PCA95XX_P7
|
||||
#define SWITCHES_GPIO_REG_D_L
|
||||
#define SWITCHES_GPIO_PIN_D_L PCA95XX_P6
|
||||
#define SWITCHES_E_2POS
|
||||
#define SWITCHES_GPIO_REG_E
|
||||
#define SWITCHES_GPIO_PIN_E PCA95XX_P16
|
||||
#define SWITCHES_F_2POS
|
||||
#define SWITCHES_GPIO_REG_F
|
||||
#define SWITCHES_GPIO_PIN_F PCA95XX_P4
|
||||
|
||||
|
||||
// Expanders
|
||||
#define IO_INT_GPIO GPIO_PIN(GPIOD, 3)
|
||||
#define IO_RESET_GPIO GPIO_PIN(GPIOG, 10)
|
||||
#if !defined(USE_EXTI3_IRQ)
|
||||
#define USE_EXTI3_IRQ
|
||||
#define EXTI3_IRQ_Priority 9
|
||||
#endif
|
||||
|
||||
// ADC
|
||||
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_6 // PA.06
|
||||
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_3 // PC.03
|
||||
#define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_4 // PC.04
|
||||
#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_5 // PC.05
|
||||
|
||||
#define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_1 // PC.01 POT1
|
||||
#define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_1 // PB.01 POT2
|
||||
#define ADC_GPIO_PIN_BATT LL_GPIO_PIN_3 // PH.03
|
||||
|
||||
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_LH)
|
||||
#define ADC_GPIOB_PINS (ADC_GPIO_PIN_POT2)
|
||||
#define ADC_GPIOC_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_POT1)
|
||||
#define ADC_GPIOH_PINS (ADC_GPIO_PIN_BATT)
|
||||
|
||||
|
||||
#define ADC_CHANNEL_STICK_LH LL_ADC_CHANNEL_3 // ADC12_INP3
|
||||
#define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_13 // ADC12_INP13
|
||||
#define ADC_CHANNEL_STICK_RV LL_ADC_CHANNEL_4 // ADC12_INP4
|
||||
#define ADC_CHANNEL_STICK_RH LL_ADC_CHANNEL_8 // ADC12_INP8
|
||||
|
||||
// Each ADC cannot map more than 8 channels, otherwise it will cause problems
|
||||
#define ADC_CHANNEL_POT1 LL_ADC_CHANNEL_11 // ADC12_INP11
|
||||
#define ADC_CHANNEL_POT2 LL_ADC_CHANNEL_5 // ADC12_INP5
|
||||
#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_14 // ADC3_INP14
|
||||
#define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC3_INP17
|
||||
|
||||
#define ADC_MAIN ADC1
|
||||
#define ADC_DMA DMA2
|
||||
#define ADC_DMA_CHANNEL LL_DMAMUX1_REQ_ADC1
|
||||
#define ADC_DMA_STREAM LL_DMA_STREAM_4
|
||||
#define ADC_DMA_STREAM_IRQ DMA2_Stream4_IRQn
|
||||
#define ADC_DMA_STREAM_IRQHandler DMA2_Stream4_IRQHandler
|
||||
#define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_8CYCLES_5
|
||||
|
||||
#define ADC_EXT ADC3
|
||||
#define ADC_EXT_CHANNELS { ADC_CHANNEL_BATT , ADC_CHANNEL_RTC_BAT }
|
||||
#define ADC_EXT_DMA DMA2
|
||||
#define ADC_EXT_DMA_CHANNEL LL_DMAMUX1_REQ_ADC3
|
||||
#define ADC_EXT_DMA_STREAM LL_DMA_STREAM_0
|
||||
#define ADC_EXT_DMA_STREAM_IRQ DMA2_Stream0_IRQn
|
||||
#define ADC_EXT_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler
|
||||
#define ADC_EXT_SAMPTIME LL_ADC_SAMPLINGTIME_64CYCLES_5 // No hardware oversampling on ADC3
|
||||
|
||||
#define ADC_VREF_PREC2 330
|
||||
|
||||
#define ADC_DIRECTION { \
|
||||
0,-1,0,-1, /* gimbals */ \
|
||||
-1,-1, /* pots */ \
|
||||
0,0, /* sliders */ \
|
||||
0, /* vbat */ \
|
||||
0, /* rtc_bat */ \
|
||||
0, /* SWA */ \
|
||||
0, /* SWB */ \
|
||||
0, /* SWC */ \
|
||||
0, /* SWD */ \
|
||||
0, /* SWE */ \
|
||||
0 /* SWF */ \
|
||||
}
|
||||
|
||||
// Serial gimbal sync port
|
||||
#define HALL_SYNC GPIO_PIN(GPIOH, 11)
|
||||
|
||||
#define USE_EXTI9_5_IRQ // used for I2C port extender interrupt
|
||||
#define EXTI9_5_IRQ_Priority 5
|
||||
|
||||
// Power
|
||||
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOA, 4)
|
||||
#define PWR_ON_GPIO GPIO_PIN(GPIOH, 12)
|
||||
|
||||
// Chargers (USB and wireless)
|
||||
#define UCHARGER_GPIO GPIO_PIN(GPIOD, 11)
|
||||
#define UCHARGER_EN_GPIO GPIO_PIN(GPIOB, 12)
|
||||
|
||||
// TODO! Check IOLL1 to PI.01 connectivity!
|
||||
|
||||
// S.Port update connector
|
||||
#define HAS_SPORT_UPDATE_CONNECTOR() (false)
|
||||
|
||||
// Telemetry
|
||||
#define TELEMETRY_SET_INPUT 0
|
||||
#define TELEMETRY_TX_GPIO GPIO_PIN(GPIOA, 9)
|
||||
#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 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 TELEMETRY_RX_FRAME_EXTI_LINE CUSTOM_EXTI_IRQ_LINE
|
||||
|
||||
// USB
|
||||
#define USB_GPIO GPIOA
|
||||
#define USB_GPIO_VBUS GPIO_PIN(GPIOH, 5)
|
||||
#define USB_GPIO_DM GPIO_PIN(GPIOA, 11)
|
||||
#define USB_GPIO_DP GPIO_PIN(GPIOA, 12)
|
||||
#define USB_GPIO_AF GPIO_AF10
|
||||
|
||||
// LCD
|
||||
#define LCD_SPI_CS_GPIO GPIOA
|
||||
#define LCD_SPI_CS_GPIO_PIN LL_GPIO_PIN_7
|
||||
#define LCD_SPI_SCK_GPIO GPIOB
|
||||
#define LCD_SPI_SCK_GPIO_PIN LL_GPIO_PIN_0
|
||||
#define LCD_SPI_MOSI_GPIO GPIOI
|
||||
#define LCD_SPI_MOSI_GPIO_PIN LL_GPIO_PIN_9
|
||||
|
||||
#define LTDC_IRQ_PRIO 4
|
||||
#define DMA_SCREEN_IRQ_PRIO 6
|
||||
|
||||
#define LCD_RESET_GPIO GPIOJ
|
||||
#define LCD_RESET_GPIO_PIN LL_GPIO_PIN_12
|
||||
|
||||
#define LCD_TE_GPIO GPIOI
|
||||
#define LCD_TE_GPIO_PIN LL_GPIO_PIN_4
|
||||
|
||||
// Backlight
|
||||
#define BACKLIGHT_GPIO GPIO_PIN(GPIOA, 10) // TIM1_CH3
|
||||
#define BACKLIGHT_TIMER TIM1
|
||||
#define BACKLIGHT_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
|
||||
#define BACKLIGHT_GPIO_AF GPIO_AF1
|
||||
#define BACKLIGHT_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
// QSPI Flash
|
||||
#define QSPI_CLK_GPIO GPIO_PIN(GPIOF, 10)
|
||||
#define QSPI_CLK_GPIO_AF GPIO_AF9
|
||||
#define QSPI_CS_GPIO GPIO_PIN(GPIOG, 6)
|
||||
#define QSPI_CS_GPIO_AF GPIO_AF10
|
||||
#define QSPI_MISO_GPIO GPIO_PIN(GPIOF, 9)
|
||||
#define QSPI_MISO_GPIO_AF GPIO_AF10
|
||||
#define QSPI_MOSI_GPIO GPIO_PIN(GPIOF, 8)
|
||||
#define QSPI_MOSI_GPIO_AF GPIO_AF10
|
||||
#define QSPI_WP_GPIO GPIO_PIN(GPIOF, 7)
|
||||
#define QSPI_WP_GPIO_AF GPIO_AF9
|
||||
#define QSPI_HOLD_GPIO GPIO_PIN(GPIOF, 6)
|
||||
#define QSPI_HOLD_GPIO_AF GPIO_AF9
|
||||
#define QSPI_FLASH_SIZE 0x1000000
|
||||
|
||||
|
||||
// SD
|
||||
#define SD_SDIO SDMMC1
|
||||
#define SD_SDIO_CLK_DIV(fq) (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC) / (2 * fq))
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) // Hz
|
||||
|
||||
#define SD2_PRESENT_GPIO GPIO_PIN(GPIOH, 8) // PH.08
|
||||
#define SD2_SDIO SDMMC2
|
||||
#define SD2_SDIO_PIN_D0 GPIO_PIN(GPIOB, 14)
|
||||
#define SD2_SDIO_AF_D0 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_D1 GPIO_PIN(GPIOB, 15)
|
||||
#define SD2_SDIO_AF_D1 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_D2 GPIO_PIN(GPIOG, 11)
|
||||
#define SD2_SDIO_AF_D2 GPIO_AF10
|
||||
#define SD2_SDIO_PIN_D3 GPIO_PIN(GPIOB, 4)
|
||||
#define SD2_SDIO_AF_D3 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_CLK GPIO_PIN(GPIOD, 6)
|
||||
#define SD2_SDIO_AF_CLK GPIO_AF11
|
||||
#define SD2_SDIO_PIN_CMD GPIO_PIN(GPIOD, 7)
|
||||
#define SD2_SDIO_AF_CMD GPIO_AF11
|
||||
#define SD2_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) // Hz
|
||||
|
||||
#define STORAGE_USE_SDIO
|
||||
|
||||
|
||||
// AUDIO
|
||||
#define AUDIO_SPI SPI2
|
||||
#define AUDIO_RESET_PIN GPIO_PIN(GPIOH, 10)
|
||||
#define AUDIO_HP_DETECT_PIN GPIO_PIN(GPIOA, 5)
|
||||
#define I2S_DMA DMA1
|
||||
#define I2S_DMA_Stream LL_DMA_STREAM_4
|
||||
#define I2S_DMA_Stream_Request LL_DMAMUX1_REQ_SPI2_TX
|
||||
#define I2S_DMA_Stream_IRQn DMA1_Stream4_IRQn
|
||||
#define I2S_DMA_Stream_IRQHandler DMA1_Stream4_IRQHandler
|
||||
|
||||
|
||||
// I2C Bus
|
||||
#define I2C_B1 I2C4
|
||||
#define I2C_B1_SDA_GPIO GPIO_PIN(GPIOD, 13) // PD.13
|
||||
#define I2C_B1_SCL_GPIO GPIO_PIN(GPIOD, 12) // PD.12
|
||||
#define I2C_B1_GPIO_AF LL_GPIO_AF_4
|
||||
#define I2C_B1_CLK_RATE 400000
|
||||
|
||||
// Haptic: TIM3_CH2
|
||||
#define HAPTIC_PWM
|
||||
#define HAPTIC_GPIO GPIO_PIN(GPIOC, 7)
|
||||
#define HAPTIC_GPIO_TIMER TIM3
|
||||
#define HAPTIC_GPIO_AF GPIO_AF2
|
||||
#define HAPTIC_TIMER_OUTPUT_ENABLE TIM_CCER_CC2E | TIM_CCER_CC2NE;
|
||||
#define HAPTIC_TIMER_MODE TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE
|
||||
#define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR2
|
||||
|
||||
// Flysky Hall Stick
|
||||
#define FLYSKY_HALL_SERIAL_USART UART4
|
||||
#define FLYSKY_HALL_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 9)
|
||||
#define FLYSKY_HALL_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 8)
|
||||
#define FLYSKY_HALL_SERIAL_USART_IRQn UART4_IRQn
|
||||
|
||||
#define FLYSKY_HALL_SERIAL_DMA DMA1
|
||||
#define FLYSKY_HALL_DMA_Stream_RX LL_DMA_STREAM_2
|
||||
#define FLYSKY_HALL_DMA_Channel LL_DMAMUX1_REQ_UART4_RX
|
||||
|
||||
// LED Strip
|
||||
#define LED_STRIP_LENGTH 26 // 6POS + 2 rings of 10
|
||||
#define BLING_LED_STRIP_START 6
|
||||
#define BLING_LED_STRIP_LENGTH 20
|
||||
#define CFS_LED_STRIP_START 0
|
||||
#define CFS_LED_STRIP_LENGTH 6
|
||||
#define CFS_LEDS_PER_SWITCH 1
|
||||
#define LED_STRIP_GPIO GPIO_PIN(GPIOA, 0) // PA.00 / TIM2_CH1
|
||||
#define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1/2/16/17
|
||||
#define LED_STRIP_TIMER TIM2
|
||||
#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_TIM2_UP
|
||||
#define LED_STRIP_TIMER_DMA_STREAM LL_DMA_STREAM_0
|
||||
#define LED_STRIP_TIMER_DMA_IRQn DMA1_Stream0_IRQn
|
||||
#define LED_STRIP_TIMER_DMA_IRQHandler DMA1_Stream0_IRQHandler
|
||||
#define LED_STRIP_REFRESH_PERIOD 50 //ms
|
||||
|
||||
#define STATUS_LEDS
|
||||
#define GPIO_LED_GPIO_ON gpio_clear
|
||||
#define GPIO_LED_GPIO_OFF gpio_set
|
||||
#define LED_RED_GPIO GPIO_PIN(GPIOI, 8) // PI.08
|
||||
#define LED_GREEN_GPIO GPIO_PIN(GPIOI, 11) // PI.11
|
||||
#define LED_BLUE_GPIO GPIO_PIN(GPIOI, 10) // PI.10
|
||||
|
||||
// Internal Module
|
||||
#define INTMODULE_PWR_GPIO GPIO_PIN(GPIOB, 13) // PB.13
|
||||
#define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOH, 9) // PH.09
|
||||
#define INTMODULE_BOOTCMD_DEFAULT 0
|
||||
#define INTMODULE_TX_GPIO GPIO_PIN(GPIOG, 14)
|
||||
#define INTMODULE_RX_GPIO GPIO_PIN(GPIOG, 9)
|
||||
#define INTMODULE_USART USART6
|
||||
#define INTMODULE_GPIO_AF LL_GPIO_AF_7
|
||||
#define INTMODULE_USART_IRQn USART6_IRQn
|
||||
#define INTMODULE_USART_IRQHandler USART6_IRQHandler
|
||||
#define INTMODULE_DMA DMA1
|
||||
#define INTMODULE_DMA_STREAM LL_DMA_STREAM_1
|
||||
#define INTMODULE_DMA_STREAM_IRQ DMA1_Stream1_IRQn
|
||||
#define INTMODULE_DMA_FLAG_TC DMA_FLAG_TCIF1
|
||||
#define INTMODULE_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_TX
|
||||
#define INTMODULE_RX_DMA DMA1
|
||||
#define INTMODULE_RX_DMA_STREAM LL_DMA_STREAM_5
|
||||
#define INTMODULE_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_RX
|
||||
#define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream5_IRQn
|
||||
#define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE
|
||||
#define EXTMODULE_PULSES
|
||||
#define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOD, 4) // PD.04
|
||||
#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOA, 2) // TIM2_CH3, TIM5_CH3,TIM15_CH1,
|
||||
#define EXTMODULE_RX_GPIO GPIO_PIN(GPIOA, 3)
|
||||
#define EXTMODULE_TX_GPIO_AF LL_GPIO_AF_3 // TIM5_CH3
|
||||
#define EXTMODULE_TIMER TIM5
|
||||
#define EXTMODULE_TIMER_32BITS
|
||||
#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH3
|
||||
#define EXTMODULE_TIMER_IRQn TIM5_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM5_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
#define EXTMODULE_TIMER_TX_GPIO_AF LL_GPIO_AF_2
|
||||
|
||||
|
||||
//USART
|
||||
#define EXTMODULE_USART USART2
|
||||
#define EXTMODULE_USART_TX_DMA DMA2
|
||||
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMAMUX1_REQ_USART2_TX
|
||||
#define EXTMODULE_USART_TX_DMA_STREAM LL_DMA_STREAM_6
|
||||
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART2_RX
|
||||
#define EXTMODULE_USART_RX_DMA_STREAM LL_DMA_STREAM_5
|
||||
#define EXTMODULE_USART_IRQHandler USART2_IRQHandler
|
||||
#define EXTMODULE_USART_IRQn USART2_IRQn
|
||||
|
||||
//TIMER
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM5_UP
|
||||
#define EXTMODULE_TIMER_DMA DMA2
|
||||
#define EXTMODULE_TIMER_DMA_STREAM LL_DMA_STREAM_6
|
||||
#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream6_IRQn
|
||||
#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream6_IRQHandler
|
||||
|
||||
// Trainer Port
|
||||
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA)
|
||||
|
||||
#define TRAINER_IN_GPIO GPIO_PIN(GPIOI, 6)
|
||||
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH2
|
||||
|
||||
#define TRAINER_OUT_GPIO GPIO_PIN(GPIOI, 5)
|
||||
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH1
|
||||
|
||||
#define TRAINER_TIMER TIM8
|
||||
#define TRAINER_TIMER_IRQn TIM8_CC_IRQn
|
||||
#define TRAINER_TIMER_IRQHandler TIM8_CC_IRQHandler
|
||||
#define TRAINER_GPIO_AF LL_GPIO_AF_3
|
||||
#define TRAINER_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
|
||||
#define TRAINER_DETECT_GPIO GPIO_PIN(GPIOH, 4)
|
||||
|
||||
// AUX ports
|
||||
#define AUX_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 6) // PB.06
|
||||
#define AUX_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 5) // PB.05
|
||||
#define AUX_SERIAL_USART UART5
|
||||
#define AUX_SERIAL_USART_IRQHandler UART5_IRQHandler
|
||||
#define AUX_SERIAL_USART_IRQn UART5_IRQn
|
||||
#define AUX_SERIAL_DMA_TX DMA2
|
||||
#define AUX_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_1
|
||||
#define AUX_SERIAL_DMA_TX_CHANNEL LL_DMAMUX1_REQ_UART5_TX
|
||||
#define AUX_SERIAL_DMA_RX DMA2
|
||||
#define AUX_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_2
|
||||
#define AUX_SERIAL_DMA_RX_CHANNEL LL_DMAMUX1_REQ_UART5_RX
|
||||
#define AUX_SERIAL_PWR_GPIO GPIO_PIN(GPIOB, 7) // PB.07
|
||||
|
||||
#define AUX2_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 10) // PB.10
|
||||
#define AUX2_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 11) // PB.11
|
||||
#define AUX2_SERIAL_USART USART3
|
||||
#define AUX2_SERIAL_USART_IRQHandler USART3_IRQHandler
|
||||
#define AUX2_SERIAL_USART_IRQn USART3_IRQn
|
||||
#define AUX2_SERIAL_DMA_TX DMA2
|
||||
#define AUX2_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_7
|
||||
#define AUX2_SERIAL_DMA_TX_CHANNEL LL_DMAMUX1_REQ_USART3_TX
|
||||
#define AUX2_SERIAL_DMA_RX DMA1
|
||||
#define AUX2_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_6
|
||||
#define AUX2_SERIAL_DMA_RX_CHANNEL LL_DMAMUX1_REQ_USART3_RX
|
||||
#define AUX2_SERIAL_PWR_GPIO GPIO_PIN(GPIOC, 13) // PC.13
|
||||
|
||||
// Touch
|
||||
#define TOUCH_I2C_BUS I2C_Bus_1
|
||||
#define TOUCH_INT_GPIO GPIO_PIN(GPIOE, 2) // PE.02
|
||||
#define TOUCH_RST_GPIO GPIO_PIN(GPIOJ, 13) // PJ.13
|
||||
|
||||
// TOUCH_INT_EXTI IRQ
|
||||
#if !defined(USE_EXTI2_IRQ)
|
||||
#define USE_EXTI2_IRQ
|
||||
#define EXTI2_IRQ_Priority 9
|
||||
#endif
|
||||
|
||||
// IMU
|
||||
#define IMU_I2C_BUS I2C_Bus_1
|
||||
#define IMU_I2C_ADDRESS 0x6A
|
||||
#define IMU_INT_GPIO GPIO_PIN(GPIOG, 13) // PG.13
|
||||
// IMU_INT_EXTI IRQ
|
||||
#if !defined(USE_EXTI15_10_IRQ)
|
||||
#define USE_EXTI15_10_IRQ
|
||||
#define EXTI15_10_IRQ_Priority 6
|
||||
#endif
|
||||
|
||||
|
||||
//ROTARY emulation for trims as buttons
|
||||
#define ROTARY_ENCODER_NAVIGATION
|
||||
// Rotary Encoder
|
||||
#define ROTARY_ENCODER_INVERTED
|
||||
#define ROTARY_ENCODER_GPIO_A GPIOI
|
||||
#define ROTARY_ENCODER_GPIO_PIN_A LL_GPIO_PIN_7
|
||||
#define ROTARY_ENCODER_GPIO_B GPIOJ
|
||||
#define ROTARY_ENCODER_GPIO_PIN_B LL_GPIO_PIN_8
|
||||
#define ROTARY_ENCODER_POSITION() (((ROTARY_ENCODER_GPIO_A->IDR >> 7) & 0x01)|((ROTARY_ENCODER_GPIO_B->IDR >> 7) & 0x02))
|
||||
#define ROTARY_ENCODER_EXTI_LINE1 LL_EXTI_LINE_7
|
||||
#define ROTARY_ENCODER_EXTI_LINE2 LL_EXTI_LINE_8
|
||||
#if !defined(USE_EXTI7_IRQ)
|
||||
#define USE_EXTI7_IRQ
|
||||
#define EXTI7_IRQ_Priority 5
|
||||
#endif
|
||||
#if !defined(USE_EXTI8_IRQ)
|
||||
#define USE_EXTI8_IRQ
|
||||
#define EXTI8_IRQ_Priority 5
|
||||
#endif
|
||||
#define ROTARY_ENCODER_EXTI_PORT_A LL_SYSCFG_EXTI_PORTI
|
||||
#define ROTARY_ENCODER_EXTI_PORT_B LL_SYSCFG_EXTI_PORTJ
|
||||
#define ROTARY_ENCODER_EXTI_SYS_LINE1 LL_SYSCFG_EXTI_LINE7
|
||||
#define ROTARY_ENCODER_EXTI_SYS_LINE2 LL_SYSCFG_EXTI_LINE8
|
||||
#define ROTARY_ENCODER_TIMER TIM17
|
||||
#define ROTARY_ENCODER_TIMER_IRQn TIM17_IRQn
|
||||
#define ROTARY_ENCODER_TIMER_IRQHandler TIM17_IRQHandler
|
||||
|
||||
// Millisecond timer
|
||||
#define MS_TIMER TIM14
|
||||
#define MS_TIMER_IRQn TIM8_TRG_COM_TIM14_IRQn
|
||||
#define MS_TIMER_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler
|
||||
|
||||
// Mixer scheduler timer
|
||||
#define MIXER_SCHEDULER_TIMER TIM12
|
||||
#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define MIXER_SCHEDULER_TIMER_IRQn TIM8_BRK_TIM12_IRQn
|
||||
#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_BRK_TIM12_IRQHandler
|
||||
|
||||
#define LANDSCAPE_LCD true
|
||||
#define PORTRAIT_LCD false
|
||||
#define LANDSCAPE_LCD_SML false
|
||||
#define LANDSCAPE_LCD_STD true
|
||||
#define LANDSCAPE_LCD_LRG false
|
||||
|
||||
#define LCD_W 480
|
||||
#define LCD_H 320
|
||||
|
||||
#define LCD_PHYS_W LCD_H
|
||||
#define LCD_PHYS_H LCD_W
|
||||
|
||||
#define LCD_DEPTH 16
|
||||
|
||||
#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH
|
||||
|
||||
#endif // _HAL_H_
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_timer.h"
|
||||
#include "stm32_pulse_driver.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define HAPTIC_TIMER_FREQ 200000000
|
||||
|
||||
static const stm32_pulse_timer_t _haptic_timer = {
|
||||
.GPIO = (gpio_t)HAPTIC_GPIO,
|
||||
.GPIO_Alternate = HAPTIC_GPIO_AF,
|
||||
.TIMx = HAPTIC_GPIO_TIMER,
|
||||
.TIM_Freq = HAPTIC_TIMER_FREQ,
|
||||
.TIM_Channel = LL_TIM_CHANNEL_CH2,
|
||||
.TIM_IRQn = (IRQn_Type)-1,
|
||||
.DMAx = nullptr,
|
||||
.DMA_Stream = 0,
|
||||
.DMA_Channel = 0,
|
||||
.DMA_IRQn = (IRQn_Type)-1,
|
||||
.DMA_TC_CallbackPtr = nullptr,
|
||||
};
|
||||
|
||||
void hapticInit(void)
|
||||
{
|
||||
stm32_pulse_init(&_haptic_timer, 10000);
|
||||
stm32_pulse_config_output(&_haptic_timer, true, LL_TIM_OCMODE_PWM1, 0);
|
||||
LL_TIM_SetAutoReload(_haptic_timer.TIMx, 100);
|
||||
LL_TIM_EnableCounter(_haptic_timer.TIMx);
|
||||
}
|
||||
|
||||
void hapticOn(uint32_t pwmPercent)
|
||||
{
|
||||
if (pwmPercent > 100) pwmPercent = 100;
|
||||
stm32_pulse_set_cmp_val(&_haptic_timer, pwmPercent);
|
||||
}
|
||||
|
||||
void hapticOff(void) { hapticOn(0); }
|
||||
void hapticDone(void) { hapticOff(); }
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include "stm32_keys.inc"
|
||||
#include "debug.h"
|
||||
|
||||
void keysInit() { _init_keys(); }
|
||||
|
||||
uint32_t readKeys() { return _read_keys(); }
|
||||
|
||||
/* 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 PhysicalTrims {
|
||||
TR3L = 0,
|
||||
TR3R,
|
||||
TR1D = 2,
|
||||
TR1U,
|
||||
TR2D = 4,
|
||||
TR2U,
|
||||
TR4L = 6,
|
||||
TR4R
|
||||
};
|
||||
|
||||
uint32_t readTrims()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
uint32_t keys = bsp_get_fs_switches();
|
||||
|
||||
#define _TRIM(t) \
|
||||
if ((keys & BSP_##t) == 0) result |= 1 << t;
|
||||
|
||||
_TRIM(TR1U);
|
||||
_TRIM(TR1D);
|
||||
_TRIM(TR3L);
|
||||
_TRIM(TR3R);
|
||||
_TRIM(TR2U);
|
||||
_TRIM(TR2D);
|
||||
_TRIM(TR4L);
|
||||
_TRIM(TR4R);
|
||||
|
||||
#undef _TRIM
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "dma2d.h"
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_driver.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_qspi.h"
|
||||
|
||||
uint8_t TouchControllerType = 0; // 0: other; 1: CST836U
|
||||
static volatile uint16_t lcd_phys_w = LCD_PHYS_W;
|
||||
static volatile uint16_t lcd_phys_h = LCD_PHYS_H;
|
||||
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
(void)disp_drv;
|
||||
(void)copy_area;
|
||||
|
||||
// given the data cache size, this is probably
|
||||
// faster than cleaning by address
|
||||
SCB_CleanDCache();
|
||||
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
lcdSpiInitFucPtr lcdOffFunction;
|
||||
lcdSpiInitFucPtr lcdOnFunction;
|
||||
uint32_t lcdPixelClock;
|
||||
|
||||
volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 };
|
||||
|
||||
static void LCD_Delay(void) {
|
||||
volatile unsigned int i;
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
gpio_t _lcd_af_gpios[] = {
|
||||
GPIO_PIN(GPIOI, 12), GPIO_PIN(GPIOI, 13), GPIO_PIN(GPIOI, 14),
|
||||
|
||||
GPIO_PIN(GPIOJ, 1), GPIO_PIN(GPIOJ, 2), GPIO_PIN(GPIOJ, 3),
|
||||
GPIO_PIN(GPIOJ, 4), GPIO_PIN(GPIOJ, 5), GPIO_PIN(GPIOJ, 6),
|
||||
GPIO_PIN(GPIOJ, 9), GPIO_PIN(GPIOJ, 10), GPIO_PIN(GPIOJ, 11),
|
||||
GPIO_PIN(GPIOJ, 14), GPIO_PIN(GPIOJ, 15),
|
||||
|
||||
GPIO_PIN(GPIOK, 0), GPIO_PIN(GPIOK, 1), GPIO_PIN(GPIOK, 2),
|
||||
GPIO_PIN(GPIOK, 3), GPIO_PIN(GPIOK, 4), GPIO_PIN(GPIOK, 5),
|
||||
GPIO_PIN(GPIOK, 6), GPIO_PIN(GPIOK, 7),
|
||||
};
|
||||
|
||||
static void LCD_AF_GPIOConfig(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(_lcd_af_gpios) / sizeof(_lcd_af_gpios[0]); i++) {
|
||||
gpio_init_af(_lcd_af_gpios[i], GPIO_AF14, GPIO_SPEED_FREQ_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
static void lcdSpiConfig(void)
|
||||
{
|
||||
LL_GPIO_InitTypeDef GPIO_InitStructure;
|
||||
LL_GPIO_StructInit(&GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = LCD_SPI_MOSI_GPIO_PIN;
|
||||
GPIO_InitStructure.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStructure.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(LCD_SPI_MOSI_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = LCD_SPI_SCK_GPIO_PIN;
|
||||
LL_GPIO_Init(LCD_SPI_SCK_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = LCD_SPI_CS_GPIO_PIN;
|
||||
LL_GPIO_Init(LCD_SPI_CS_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = LCD_RESET_GPIO_PIN;
|
||||
LL_GPIO_Init(LCD_RESET_GPIO, &GPIO_InitStructure);
|
||||
|
||||
LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
void lcdDelay() {
|
||||
delay_01us(1);
|
||||
}
|
||||
|
||||
static void lcdReset() {
|
||||
LCD_CS_HIGH();
|
||||
|
||||
LCD_NRST_HIGH();
|
||||
delay_ms(1);
|
||||
|
||||
LCD_NRST_LOW(); // RESET();
|
||||
delay_ms(10);
|
||||
|
||||
LCD_NRST_HIGH();
|
||||
delay_ms(100);
|
||||
}
|
||||
|
||||
unsigned char LCD_ReadByteOnFallingEdge(void) {
|
||||
unsigned int i;
|
||||
unsigned char ReceiveData = 0;
|
||||
|
||||
LCD_MOSI_HIGH();
|
||||
LCD_MOSI_AS_INPUT();
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
LCD_DELAY();
|
||||
LCD_SCK_HIGH();
|
||||
LCD_DELAY();
|
||||
LCD_DELAY();
|
||||
ReceiveData <<= 1;
|
||||
|
||||
LCD_SCK_LOW();
|
||||
LCD_DELAY();
|
||||
LCD_DELAY();
|
||||
if (LCD_READ_DATA_PIN()) {
|
||||
ReceiveData |= 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
LCD_MOSI_AS_OUTPUT();
|
||||
|
||||
return (ReceiveData);
|
||||
}
|
||||
|
||||
static void lcdWriteByte(uint8_t data_enable, uint8_t byte) {
|
||||
|
||||
LCD_SCK_LOW();
|
||||
lcdDelay();
|
||||
|
||||
if (data_enable) {
|
||||
LCD_MOSI_HIGH();
|
||||
} else {
|
||||
LCD_MOSI_LOW();
|
||||
}
|
||||
|
||||
LCD_SCK_HIGH();
|
||||
lcdDelay();
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
LCD_SCK_LOW();
|
||||
lcdDelay();
|
||||
|
||||
if (byte & 0x80) {
|
||||
LCD_MOSI_HIGH();
|
||||
} else {
|
||||
LCD_MOSI_LOW();
|
||||
}
|
||||
|
||||
LCD_SCK_HIGH();
|
||||
byte <<= 1;
|
||||
|
||||
lcdDelay();
|
||||
}
|
||||
|
||||
LCD_SCK_LOW();
|
||||
}
|
||||
|
||||
unsigned char LCD_ReadByte(void) {
|
||||
unsigned int i;
|
||||
unsigned char ReceiveData = 0;
|
||||
|
||||
LCD_MOSI_HIGH();
|
||||
LCD_MOSI_AS_INPUT();
|
||||
for (i = 0; i < 8; i++) {
|
||||
LCD_SCK_LOW();
|
||||
lcdDelay();
|
||||
ReceiveData <<= 1;
|
||||
LCD_SCK_HIGH();
|
||||
lcdDelay();
|
||||
if (LCD_READ_DATA_PIN()) {
|
||||
ReceiveData |= 0x01;
|
||||
}
|
||||
}
|
||||
LCD_SCK_LOW();
|
||||
LCD_MOSI_AS_OUTPUT();
|
||||
return (ReceiveData);
|
||||
}
|
||||
|
||||
unsigned char LCD_ReadRegister(unsigned char Register) {
|
||||
unsigned char ReadData = 0;
|
||||
LCD_CS_LOW();
|
||||
lcdDelay();
|
||||
|
||||
lcdWriteByte(0, Register);
|
||||
lcdDelay();
|
||||
lcdDelay();
|
||||
ReadData = LCD_ReadByte();
|
||||
LCD_CS_HIGH();
|
||||
return (ReadData);
|
||||
}
|
||||
|
||||
void lcdWriteCommand(uint8_t command) {
|
||||
lcdWriteByte(0, command);
|
||||
}
|
||||
|
||||
void lcdWriteData(uint8_t data) {
|
||||
lcdWriteByte(1, data);
|
||||
}
|
||||
|
||||
void LCD_ST7365_On(void) {
|
||||
LCD_CS_LOW();
|
||||
delay_ms(1);
|
||||
lcdWriteCommand(0x29);
|
||||
LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
void LCD_ST7365_Init(void) {
|
||||
|
||||
LCD_CS_LOW();
|
||||
delay_ms(1);
|
||||
lcdWriteCommand( 0x11 );
|
||||
delay_ms(120);
|
||||
|
||||
lcdWriteCommand( 0xF0 );
|
||||
lcdWriteData( 0xC3 );
|
||||
|
||||
lcdWriteCommand( 0xF0 );
|
||||
lcdWriteData( 0x96 );
|
||||
|
||||
|
||||
lcdWriteCommand(0x11);
|
||||
|
||||
delay_ms(120);
|
||||
|
||||
lcdWriteCommand(0xF0); // Command Set Control
|
||||
lcdWriteData(0xC3);
|
||||
|
||||
lcdWriteCommand(0xF0);
|
||||
lcdWriteData(0x96);
|
||||
|
||||
lcdWriteCommand(0x36); // Memory Data Access Control MY,MX~~
|
||||
lcdWriteData(0xE8);
|
||||
|
||||
lcdWriteCommand(0x2A);//480-1
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x01);
|
||||
lcdWriteData(0xDF);
|
||||
|
||||
lcdWriteCommand(0x2B);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x01);
|
||||
lcdWriteData(0x3F); //320-1
|
||||
|
||||
|
||||
lcdWriteCommand(0x3A);
|
||||
lcdWriteData(0x66); //55:RGB565 66:RGB666 77:RGB888
|
||||
|
||||
lcdWriteCommand(0xB4);
|
||||
lcdWriteData(0x01);
|
||||
|
||||
lcdWriteCommand(0xB6); //RGB
|
||||
lcdWriteData(0x20);
|
||||
lcdWriteData(0x02); //02
|
||||
lcdWriteData(0x3B);
|
||||
|
||||
lcdWriteCommand(0xB7);
|
||||
lcdWriteData(0xC6);
|
||||
|
||||
lcdWriteCommand(0xC0);
|
||||
lcdWriteData(0x80);
|
||||
lcdWriteData(0x45);
|
||||
|
||||
lcdWriteCommand(0xC1);
|
||||
lcdWriteData(0x0F ); //18 //00
|
||||
|
||||
lcdWriteCommand(0xC2);
|
||||
lcdWriteData(0xA7); //A7
|
||||
|
||||
lcdWriteCommand(0xC5);
|
||||
lcdWriteData(0x0A);
|
||||
|
||||
lcdWriteCommand(0xE8);
|
||||
lcdWriteData(0x40);
|
||||
lcdWriteData(0x8A);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x00);
|
||||
lcdWriteData(0x29);
|
||||
lcdWriteData(0x19);
|
||||
lcdWriteData(0xA5);
|
||||
lcdWriteData(0x33);
|
||||
|
||||
lcdWriteCommand(0xE0);
|
||||
lcdWriteData(0xD0);
|
||||
lcdWriteData(0x08);
|
||||
lcdWriteData(0x0F);
|
||||
lcdWriteData(0x06);
|
||||
lcdWriteData(0x06);
|
||||
lcdWriteData(0x33);
|
||||
lcdWriteData(0x30);
|
||||
lcdWriteData(0x33);
|
||||
lcdWriteData(0x47);
|
||||
lcdWriteData(0x17);
|
||||
lcdWriteData(0x13);
|
||||
lcdWriteData(0x13);
|
||||
lcdWriteData(0x2B);
|
||||
lcdWriteData(0x31);
|
||||
|
||||
lcdWriteCommand(0xE1);
|
||||
lcdWriteData(0xD0);
|
||||
lcdWriteData(0x0A);
|
||||
lcdWriteData(0x11);
|
||||
lcdWriteData(0x0B);
|
||||
lcdWriteData(0x09);
|
||||
lcdWriteData(0x07);
|
||||
lcdWriteData(0x2F);
|
||||
lcdWriteData(0x33);
|
||||
lcdWriteData(0x47);
|
||||
lcdWriteData(0x38);
|
||||
lcdWriteData(0x15);
|
||||
lcdWriteData(0x16);
|
||||
lcdWriteData(0x2C);
|
||||
lcdWriteData(0x32);
|
||||
|
||||
|
||||
lcdWriteCommand(0xF0);
|
||||
lcdWriteData(0x3C);
|
||||
|
||||
lcdWriteCommand(0xF0);
|
||||
lcdWriteData(0x69);
|
||||
|
||||
delay_ms(120);
|
||||
|
||||
lcdWriteCommand(0x21);
|
||||
LCD_CS_HIGH();
|
||||
delay_ms(1);
|
||||
LCD_ST7365_On();
|
||||
}
|
||||
|
||||
void LCD_ST7365_Off(void) {
|
||||
LCD_CS_LOW();
|
||||
delay_ms(1);
|
||||
lcdWriteCommand(0x28);
|
||||
LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
void LCD_Init_LTDC() {
|
||||
hltdc.Instance = LTDC;
|
||||
|
||||
/* Configure PLLSAI prescalers for LCD */
|
||||
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
|
||||
/* PLLSAI_VCO Output = PLLSAI_VCO Input * lcdPixelclock * 16 = XX Mhz */
|
||||
/* PLLLCDCLK = PLLSAI_VCO Output/PLL_LTDC = PLLSAI_VCO/4 = YY Mhz */
|
||||
/* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = YY/4 = lcdPixelClock Mhz */
|
||||
// uint32_t clock = (lcdPixelClock*16) / 1000000; // clock*16 in MHz
|
||||
// RCC_PeriphCLKInitTypeDef clkConfig;
|
||||
// clkConfig.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||
// clkConfig.PLLI2S
|
||||
// clkConfig.PLLSAI.PLLSAIN = clock;
|
||||
// clkConfig.PLLSAI.PLLSAIR = 4;
|
||||
// clkConfig.PLLSAIDivQ = 6;
|
||||
// clkConfig.PLLSAIDivR = RCC_PLLSAIDIVR_4;
|
||||
// HAL_RCCEx_PeriphCLKConfig(&clkConfig);
|
||||
|
||||
/* LTDC Configuration *********************************************************/
|
||||
/* Polarity configuration */
|
||||
/* Initialize the horizontal synchronization polarity as active low */
|
||||
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
|
||||
/* Initialize the vertical synchronization polarity as active low */
|
||||
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
|
||||
/* Initialize the data enable polarity as active low */
|
||||
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
|
||||
/* Initialize the pixel clock polarity as input pixel clock */
|
||||
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IIPC;
|
||||
|
||||
/* Configure R,G,B component values for LCD background color */
|
||||
hltdc.Init.Backcolor.Red = 0;
|
||||
hltdc.Init.Backcolor.Green = 0;
|
||||
hltdc.Init.Backcolor.Blue = 0;
|
||||
|
||||
/* Configure horizontal synchronization width */
|
||||
hltdc.Init.HorizontalSync = HSW-1;
|
||||
/* Configure vertical synchronization height */
|
||||
hltdc.Init.VerticalSync = VSH-1;
|
||||
/* Configure accumulated horizontal back porch */
|
||||
hltdc.Init.AccumulatedHBP = HSW+HBP-1;
|
||||
/* Configure accumulated vertical back porch */
|
||||
hltdc.Init.AccumulatedVBP = VSH+VBP-1;
|
||||
/* Configure accumulated active width */
|
||||
hltdc.Init.AccumulatedActiveW = lcd_phys_w + HBP+HSW-1;
|
||||
/* Configure accumulated active height */
|
||||
hltdc.Init.AccumulatedActiveH = lcd_phys_h + VBP+VSH-1;
|
||||
/* Configure total width */
|
||||
hltdc.Init.TotalWidth = lcd_phys_w + HBP + HFP + HSW -1;
|
||||
/* Configure total height */
|
||||
hltdc.Init.TotalHeigh = lcd_phys_h + VBP + VFP+VSH-1;
|
||||
|
||||
HAL_LTDC_Init(&hltdc);
|
||||
|
||||
// Configure IRQ (line)
|
||||
NVIC_SetPriority(LTDC_IRQn, LTDC_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(LTDC_IRQn);
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
auto& layer = hltdc.LayerCfg[0];
|
||||
|
||||
/* Windowing configuration */
|
||||
layer.WindowX0 = 0;
|
||||
layer.WindowX1 = lcd_phys_w;
|
||||
layer.WindowY0 = 0;
|
||||
layer.WindowY1 = lcd_phys_h;
|
||||
|
||||
/* Pixel Format configuration*/
|
||||
layer.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
|
||||
/* Alpha constant (255 totally opaque) */
|
||||
layer.Alpha = 255;
|
||||
|
||||
/* Default Color configuration (configure A,R,G,B component values) */
|
||||
layer.Backcolor.Blue = 0;
|
||||
layer.Backcolor.Green = 0;
|
||||
layer.Backcolor.Red = 0;
|
||||
layer.Alpha0 = 0;
|
||||
|
||||
/* Configure blending factors */
|
||||
layer.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
|
||||
layer.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
|
||||
|
||||
layer.ImageWidth = lcd_phys_w;
|
||||
layer.ImageHeight = lcd_phys_h;
|
||||
|
||||
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
|
||||
layer.FBStartAdress = (intptr_t)initialFrameBuffer;
|
||||
|
||||
/* Initialize LTDC layer 1 */
|
||||
HAL_LTDC_ConfigLayer(&hltdc, &hltdc.LayerCfg[0], 0);
|
||||
|
||||
/* dithering activation */
|
||||
HAL_LTDC_EnableDither(&hltdc);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void lcdSetInitalFrameBuffer(void* fbAddress)
|
||||
{
|
||||
initialFrameBuffer = fbAddress;
|
||||
}
|
||||
|
||||
const char* boardLcdType = "";
|
||||
|
||||
extern "C"
|
||||
void lcdInit(void)
|
||||
{
|
||||
#if defined(LCD_SPI_CONFLICTS_WITH_QSPI)
|
||||
stm32_qspi_nor_deinit();
|
||||
#endif
|
||||
|
||||
/* Configure the LCD SPI+RESET pins */
|
||||
lcdSpiConfig();
|
||||
|
||||
/* Reset the LCD --------------------------------------------------------*/
|
||||
lcdReset();
|
||||
|
||||
/* Configure the LCD Control pins */
|
||||
LCD_AF_GPIOConfig();
|
||||
|
||||
/* Send LCD initialization commands */
|
||||
TRACE("LCD INIT (default): ST7365");
|
||||
boardLcdType = "ST7365 (Default)";
|
||||
lcdInitFunction = LCD_ST7365_Init;
|
||||
lcdOffFunction = LCD_ST7365_Off;
|
||||
lcdOnFunction = LCD_ST7365_On;
|
||||
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
lcdInitFunction();
|
||||
|
||||
LCD_Init_LTDC();
|
||||
LCD_LayerInit();
|
||||
|
||||
// Enable LCD display
|
||||
__HAL_LTDC_ENABLE(&hltdc);
|
||||
|
||||
lcdSetFlushCb(startLcdRefresh);
|
||||
|
||||
#if defined(LCD_SPI_CONFLICTS_WITH_QSPI)
|
||||
stm32_qspi_nor_init();
|
||||
stm32_qspi_nor_memory_mapped();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
#include "bsp_io.h"
|
||||
|
||||
#define HBP ( 20 )
|
||||
#define VBP ( 10 )
|
||||
|
||||
#define HSW ( 6 )
|
||||
#define VSH ( 2 )
|
||||
|
||||
#define HFP ( 40 )
|
||||
#define VFP ( 10 )
|
||||
|
||||
#define LCD_DELAY() LCD_Delay()
|
||||
|
||||
typedef void (*lcdSpiInitFucPtr)(void);
|
||||
typedef unsigned int LcdReadIDFucPtr( void );
|
||||
|
||||
extern lcdSpiInitFucPtr lcdInitFunction;
|
||||
extern lcdSpiInitFucPtr lcdOffFunction;
|
||||
extern lcdSpiInitFucPtr lcdOnFunction;
|
||||
|
||||
#define SET_IO_INPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_INPUT )
|
||||
#define SET_IO_OUTPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_OUTPUT )
|
||||
|
||||
#define LCD_NRST_HIGH() LL_GPIO_SetOutputPin(LCD_RESET_GPIO, LCD_RESET_GPIO_PIN)
|
||||
#define LCD_NRST_LOW() LL_GPIO_ResetOutputPin(LCD_RESET_GPIO, LCD_RESET_GPIO_PIN)
|
||||
|
||||
#define LCD_CS_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_CS_GPIO, LCD_SPI_CS_GPIO_PIN)
|
||||
#define LCD_CS_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_CS_GPIO, LCD_SPI_CS_GPIO_PIN)
|
||||
|
||||
#define LCD_SCK_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_SCK_GPIO, LCD_SPI_SCK_GPIO_PIN)
|
||||
#define LCD_SCK_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_SCK_GPIO, LCD_SPI_SCK_GPIO_PIN)
|
||||
|
||||
#define LCD_MOSI_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
#define LCD_MOSI_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
#define LCD_MOSI_AS_INPUT() SET_IO_INPUT( LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN )
|
||||
#define LCD_MOSI_AS_OUTPUT() SET_IO_OUTPUT( LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN )
|
||||
|
||||
#define LCD_READ_DATA_PIN() LL_GPIO_IsInputPinSet(LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#define GET_RED(color) (((color) & 0xFF0000) >>16)
|
||||
#define GET_GREEN(color) (((color) & 0x00FF00) >> 8)
|
||||
#define GET_BLUE(color) ((color) & 0x0000FF)
|
||||
|
||||
#if defined(FUNCTION_SWITCHES) && !defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
static const uint32_t fsLeds[] = {FSLED_GPIO_PIN_1, FSLED_GPIO_PIN_2,
|
||||
FSLED_GPIO_PIN_3, FSLED_GPIO_PIN_4,
|
||||
FSLED_GPIO_PIN_5, FSLED_GPIO_PIN_6};
|
||||
#endif
|
||||
|
||||
void ledInit()
|
||||
{
|
||||
#if defined(LED_GREEN_GPIO)
|
||||
gpio_init(LED_GREEN_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
#if defined(LED_RED_GPIO)
|
||||
gpio_init(LED_RED_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
#if defined(LED_BLUE_GPIO)
|
||||
gpio_init(LED_BLUE_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
#endif
|
||||
|
||||
#if defined(FUNCTION_SWITCHES) && !defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
for (size_t i = 0; i < DIM(fsLeds); i++) {
|
||||
gpio_init(fsLeds[i], GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
void fsLedRGB(uint8_t index, uint32_t color)
|
||||
{
|
||||
ws2812_set_color(index + CFS_LED_STRIP_START, GET_RED(color), GET_GREEN(color),
|
||||
GET_BLUE(color));
|
||||
}
|
||||
|
||||
uint32_t fsGetLedRGB(uint8_t index)
|
||||
{
|
||||
return rgbGetLedColor(index + CFS_LED_STRIP_START);
|
||||
}
|
||||
|
||||
uint8_t getRGBColorIndex(uint32_t color)
|
||||
{
|
||||
for (uint8_t i = 0; i < DIM(colorTable); i++) {
|
||||
if (color == colorTable[i])
|
||||
return(i + 1);
|
||||
}
|
||||
return 0; // Custom value set with Companion
|
||||
}
|
||||
#elif defined(FUNCTION_SWITCHES)
|
||||
void fsLedOff(uint8_t index)
|
||||
{
|
||||
gpio_clear(fsLeds[index]);
|
||||
}
|
||||
|
||||
void fsLedOn(uint8_t index)
|
||||
{
|
||||
gpio_set(fsLeds[index]);
|
||||
}
|
||||
|
||||
bool fsLedState(uint8_t index)
|
||||
{
|
||||
return gpio_read(fsLeds[index]) ? true : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ledOff()
|
||||
{
|
||||
#if defined(LED_RED_GPIO)
|
||||
GPIO_LED_GPIO_OFF(LED_RED_GPIO);
|
||||
#endif
|
||||
#if defined(LED_BLUE_GPIO)
|
||||
GPIO_LED_GPIO_OFF(LED_BLUE_GPIO);
|
||||
#endif
|
||||
#if defined(LED_GREEN_GPIO)
|
||||
GPIO_LED_GPIO_OFF(LED_GREEN_GPIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ledRed()
|
||||
{
|
||||
#if defined(LED_RED_GPIO)
|
||||
GPIO_LED_GPIO_ON(LED_RED_GPIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ledGreen()
|
||||
{
|
||||
#if defined(LED_GREEN_GPIO)
|
||||
GPIO_LED_GPIO_ON(LED_GREEN_GPIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ledBlue()
|
||||
{
|
||||
#if defined(LED_BLUE_GPIO)
|
||||
GPIO_LED_GPIO_ON(LED_BLUE_GPIO);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
|
||||
|
||||
#define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_3
|
||||
|
||||
#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
|
||||
|
||||
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
|
||||
|
||||
#define SDRAM_READBURST FMC_SDRAM_RBURST_DISABLE
|
||||
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
|
||||
#define SDRAM_MODEREG_BURST_FULL_PAGE ((uint16_t)0x0007)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_1 ((uint16_t)0x0010)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
|
||||
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
|
||||
|
||||
#define GPIO_AF_FMC GPIO_AF12
|
||||
|
||||
extern "C" void SDRAM_GPIOConfig(void)
|
||||
{
|
||||
/*-- GPIOs Configuration -----------------------------------------------------*/
|
||||
/*
|
||||
*/
|
||||
|
||||
/* GPIOC configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOC, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
/* GPIOD configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOE configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOF configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 2), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 3), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOG configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
|
||||
gpio_init_af(GPIO_PIN(GPIOH, 6), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOH, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
}
|
||||
|
||||
extern "C" void SDRAM_InitSequence(void)
|
||||
{
|
||||
FMC_SDRAM_CommandTypeDef FMC_SDRAMCommandStructure;
|
||||
uint32_t tmpr = 0;
|
||||
|
||||
/* Step 3 --------------------------------------------------------------------*/
|
||||
/* Configure a clock configuration enable command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 4 --------------------------------------------------------------------*/
|
||||
/* Insert 1 ms delay */
|
||||
delay_ms(100);
|
||||
|
||||
/* Step 5 --------------------------------------------------------------------*/
|
||||
/* Configure a PALL (precharge all) command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_PALL;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 6 --------------------------------------------------------------------*/
|
||||
/* Configure a Auto-Refresh command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 8;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 7 --------------------------------------------------------------------*/
|
||||
/* Program the external memory mode register */
|
||||
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
|
||||
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
|
||||
SDRAM_MODEREG_CAS_LATENCY_3 |
|
||||
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
|
||||
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
|
||||
|
||||
/* Configure a load Mode register command*/
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = tmpr;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 8 --------------------------------------------------------------------*/
|
||||
/* Set the refresh rate counter */
|
||||
/* (15.62 us x Freq) - 20 */
|
||||
/* Set the device refresh counter */
|
||||
FMC_SDRAM_SetAutoRefreshNumber(FMC_Bank5_6_R, 15);
|
||||
FMC_SDRAM_ProgramRefreshRate(FMC_Bank5_6_R, 1855);
|
||||
}
|
||||
|
||||
extern "C" void SDRAM_Init(void)
|
||||
{
|
||||
//delay funcion needed
|
||||
delaysInit();
|
||||
|
||||
/* GPIO configuration for FMC SDRAM bank */
|
||||
SDRAM_GPIOConfig();
|
||||
|
||||
/* Enable FMC clock */
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FMC);
|
||||
|
||||
/* FMC Configuration ---------------------------------------------------------*/
|
||||
FMC_SDRAM_InitTypeDef FMC_SDRAMInitStructure;
|
||||
FMC_SDRAM_TimingTypeDef FMC_SDRAMTimingInitStructure;
|
||||
|
||||
/* FMC SDRAM Bank configuration */
|
||||
/* Timing configuration for 80 Mhz of SD clock */
|
||||
FMC_SDRAMTimingInitStructure.LoadToActiveDelay = 2;
|
||||
FMC_SDRAMTimingInitStructure.ExitSelfRefreshDelay = 7;
|
||||
FMC_SDRAMTimingInitStructure.SelfRefreshTime = 4;
|
||||
FMC_SDRAMTimingInitStructure.RowCycleDelay = 7;
|
||||
FMC_SDRAMTimingInitStructure.WriteRecoveryTime = 3;
|
||||
FMC_SDRAMTimingInitStructure.RPDelay = 2;
|
||||
FMC_SDRAMTimingInitStructure.RCDDelay = 2;
|
||||
|
||||
/* FMC SDRAM control configuration */
|
||||
FMC_SDRAMInitStructure.SDBank = FMC_SDRAM_BANK2;
|
||||
FMC_SDRAMInitStructure.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
|
||||
FMC_SDRAMInitStructure.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
|
||||
FMC_SDRAMInitStructure.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
|
||||
FMC_SDRAMInitStructure.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
|
||||
FMC_SDRAMInitStructure.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
|
||||
FMC_SDRAMInitStructure.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
|
||||
FMC_SDRAMInitStructure.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
|
||||
FMC_SDRAMInitStructure.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
|
||||
FMC_SDRAMInitStructure.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
|
||||
|
||||
/* FMC SDRAM bank initialization */
|
||||
FMC_SDRAM_Init(FMC_Bank5_6_R, &FMC_SDRAMInitStructure);
|
||||
FMC_SDRAM_Timing_Init(FMC_Bank5_6_R, &FMC_SDRAMTimingInitStructure, FMC_SDRAM_BANK2);
|
||||
|
||||
__FMC_ENABLE();
|
||||
|
||||
/* FMC SDRAM device initialization sequence */
|
||||
SDRAM_InitSequence();
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "stm32h7xx_ll_pwr.h"
|
||||
#include "stm32h7xx_ll_rcc.h"
|
||||
#include "stm32h7xx_ll_system.h"
|
||||
#include "stm32h7xx_ll_bus.h"
|
||||
|
||||
#define BOOTSTRAP __attribute__((section(".bootstrap")))
|
||||
|
||||
BOOTSTRAP void SystemClock_Config(void)
|
||||
{
|
||||
/* Power Configuration */
|
||||
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
|
||||
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
|
||||
while (LL_PWR_IsActiveFlag_VOS() == 0){
|
||||
}
|
||||
|
||||
/* Enable HSE oscillator */
|
||||
LL_RCC_HSE_Enable();
|
||||
while (LL_RCC_HSE_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Set FLASH latency */
|
||||
LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
|
||||
|
||||
/* Main PLL configuration and activation */
|
||||
LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
|
||||
LL_RCC_PLL1P_Enable();
|
||||
LL_RCC_PLL1Q_Enable();
|
||||
LL_RCC_PLL1R_Enable();
|
||||
LL_RCC_PLL1FRACN_Disable();
|
||||
LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
LL_RCC_PLL1_SetM(3);
|
||||
LL_RCC_PLL1_SetN(60);
|
||||
LL_RCC_PLL1_SetP(2);
|
||||
LL_RCC_PLL1_SetQ(20);
|
||||
LL_RCC_PLL1_SetR(2);
|
||||
LL_RCC_PLL1_Enable();
|
||||
while (LL_RCC_PLL1_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Set Sys & AHB & APB1 & APB2 & APB4 prescaler */
|
||||
LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
|
||||
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
|
||||
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
|
||||
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
|
||||
LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
|
||||
|
||||
/* Set PLL1 as System Clock Source */
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
|
||||
}
|
||||
|
||||
/* Config & activate PLL2 */
|
||||
LL_RCC_PLL2P_Enable();
|
||||
LL_RCC_PLL2FRACN_Disable();
|
||||
LL_RCC_PLL2_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL2_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
LL_RCC_PLL2_SetM(24);
|
||||
LL_RCC_PLL2_SetN(96);
|
||||
LL_RCC_PLL2_SetP(17); // 11.294 MHz
|
||||
LL_RCC_PLL2_Enable();
|
||||
while (LL_RCC_PLL2_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Config & activate PLL3 */
|
||||
LL_RCC_PLL3P_Enable();
|
||||
LL_RCC_PLL3Q_Enable();
|
||||
LL_RCC_PLL3R_Enable();
|
||||
LL_RCC_PLL3FRACN_Disable();
|
||||
LL_RCC_PLL3_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL3_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
LL_RCC_PLL3_SetM(1);
|
||||
LL_RCC_PLL3_SetN(4);
|
||||
LL_RCC_PLL3_SetP(2);
|
||||
LL_RCC_PLL3_SetQ(2);
|
||||
LL_RCC_PLL3_SetR(18);
|
||||
LL_RCC_PLL3_Enable();
|
||||
while (LL_RCC_PLL3_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Enable SRAM1, SRAM2 & SRAM3 */
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_D2SRAM1 |
|
||||
LL_AHB2_GRP1_PERIPH_D2SRAM2 |
|
||||
LL_AHB2_GRP1_PERIPH_D2SRAM3);
|
||||
|
||||
/* Set periph clock sources */
|
||||
LL_RCC_SetSPIClockSource(LL_RCC_SPI123_CLKSOURCE_PLL1Q);
|
||||
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL1Q);
|
||||
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_CLKP);
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 "touch.h"
|
||||
|
||||
extern void touchPanelDeInit();
|
||||
extern bool touchPanelInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState getInternalTouchState();
|
||||
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* 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/i2c_driver.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_exti_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tp_gt911.h"
|
||||
#include "delays_driver.h"
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TP_GT911_ID "911"
|
||||
|
||||
|
||||
bool touchGT911Flag = false;
|
||||
volatile static bool touchEventOccured = false;
|
||||
struct TouchData touchData;
|
||||
uint16_t touchGT911fwver = 0;
|
||||
uint32_t touchGT911hiccups = 0;
|
||||
|
||||
static tmr10ms_t downTime = 0;
|
||||
static tmr10ms_t tapTime = 0;
|
||||
static short tapCount = 0;
|
||||
|
||||
static TouchState internalTouchState = {};
|
||||
|
||||
static void _gt911_exti_isr(void)
|
||||
{
|
||||
touchEventOccured = true;
|
||||
}
|
||||
|
||||
void I2C_Init_Radio(void)
|
||||
{
|
||||
TRACE("GT911 I2C Init");
|
||||
|
||||
if (i2c_init(TOUCH_I2C_BUS) < 0) {
|
||||
TRACE("GT911 ERROR: i2c_init failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool I2C_GT911_WriteRegister(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t uAddrAndBuf[258];
|
||||
uAddrAndBuf[0] = (uint8_t)((reg & 0xFF00) >> 8);
|
||||
uAddrAndBuf[1] = (uint8_t)(reg & 0x00FF);
|
||||
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
uAddrAndBuf[i + 2] = buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (stm32_i2c_master_tx(TOUCH_I2C_BUS, GT911_I2C_ADDR, uAddrAndBuf, len + 2,
|
||||
100) < 0) {
|
||||
TRACE("I2C B1 ERROR: WriteRegister failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2C_GT911_ReadRegister(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t uRegAddr[2];
|
||||
uRegAddr[0] = (uint8_t)((reg & 0xFF00) >> 8);
|
||||
uRegAddr[1] = (uint8_t)(reg & 0x00FF);
|
||||
|
||||
if (stm32_i2c_master_tx(TOUCH_I2C_BUS, GT911_I2C_ADDR, uRegAddr, 2, 10) < 0) {
|
||||
TRACE("I2C B1 ERROR: ReadRegister write reg address failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stm32_i2c_master_rx(TOUCH_I2C_BUS, GT911_I2C_ADDR, buf, len, 100) < 0) {
|
||||
TRACE("I2C B1 ERROR: ReadRegister read reg address failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void touchPanelDeInit(void)
|
||||
{
|
||||
gpio_int_disable(TOUCH_INT_GPIO);
|
||||
touchGT911Flag = false;
|
||||
}
|
||||
|
||||
uint8_t tp_gt911_cfgVer = GT911_CFG_NUMBER;
|
||||
|
||||
bool touchPanelInit(void)
|
||||
{
|
||||
uint8_t tmp[4] = {0};
|
||||
|
||||
if (touchGT911Flag) {
|
||||
gpio_init_int(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_RISING, _gt911_exti_isr);
|
||||
return true;
|
||||
} else {
|
||||
TRACE("Touchpanel init start ...");
|
||||
|
||||
gpio_init(TOUCH_RST_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(TOUCH_INT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
I2C_Init_Radio();
|
||||
|
||||
gpio_clear(TOUCH_RST_GPIO);
|
||||
gpio_set(TOUCH_INT_GPIO);
|
||||
delay_us(200);
|
||||
|
||||
gpio_set(TOUCH_RST_GPIO);
|
||||
delay_ms(6);
|
||||
|
||||
gpio_clear(TOUCH_INT_GPIO);
|
||||
delay_ms(55);
|
||||
|
||||
gpio_init(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
|
||||
delay_ms(50);
|
||||
|
||||
TRACE("Reading Touch registry");
|
||||
if (!I2C_GT911_ReadRegister(GT911_PRODUCT_ID_REG, tmp, 4)) {
|
||||
TRACE("GT911 ERROR: Product ID read failed");
|
||||
}
|
||||
|
||||
if (strcmp((char *)tmp, TP_GT911_ID) == 0) {
|
||||
TRACE("GT911 chip detected");
|
||||
tmp[0] = 0X02;
|
||||
if (!I2C_GT911_WriteRegister(GT911_COMMAND_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: write to control register failed");
|
||||
}
|
||||
if (!I2C_GT911_ReadRegister(GT911_CONFIG_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: configuration register read failed");
|
||||
}
|
||||
|
||||
TRACE("Chip config Ver:%x", tmp[0]);
|
||||
if ((tp_gt911_cfgVer == 0) || (tmp[0] < tp_gt911_cfgVer)) { // Config ver
|
||||
TRACE("Sending new config %d", GT911_CFG_NUMBER);
|
||||
if (!I2C_GT911_ReadRegister(GT911_CONFIG_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: configuration register read failed");
|
||||
}
|
||||
tp_gt911_cfgVer = tmp[0];
|
||||
}
|
||||
|
||||
if (!I2C_GT911_ReadRegister(GT911_FIRMWARE_VERSION_REG, tmp, 2)) {
|
||||
TRACE("GT911 ERROR: reading firmware version failed");
|
||||
} else {
|
||||
touchGT911fwver = (tmp[1] << 8) + tmp[0];
|
||||
TRACE("GT911 FW version: %u", touchGT911fwver);
|
||||
}
|
||||
|
||||
delay_ms(10);
|
||||
tmp[0] = 0X00;
|
||||
if (!I2C_GT911_WriteRegister(GT911_COMMAND_REG, tmp, 1)) { // end reset
|
||||
TRACE("GT911 ERROR: write to command register failed");
|
||||
}
|
||||
touchGT911Flag = true;
|
||||
|
||||
gpio_init_int(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_RISING, _gt911_exti_isr);
|
||||
|
||||
return true;
|
||||
}
|
||||
TRACE("GT911 chip NOT FOUND");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool I2C_ReInit(void)
|
||||
{
|
||||
TRACE("I2C B1 ReInit");
|
||||
touchPanelDeInit();
|
||||
if (stm32_i2c_deinit(TOUCH_I2C_BUS) < 0)
|
||||
TRACE("I2C B1 ReInit - I2C DeInit failed");
|
||||
|
||||
// If DeInit fails, try to re-init anyway
|
||||
if (!touchPanelInit()) {
|
||||
TRACE("I2C B1 ReInit - touchPanelInit failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(SIMU) || defined(SEMIHOSTING) || defined(DEBUG)
|
||||
static const char *event2str(uint8_t ev)
|
||||
{
|
||||
switch (ev) {
|
||||
case TE_NONE:
|
||||
return "NONE";
|
||||
case TE_UP:
|
||||
return "UP";
|
||||
case TE_DOWN:
|
||||
return "DOWN";
|
||||
case TE_SLIDE_END:
|
||||
return "SLIDE_END";
|
||||
case TE_SLIDE:
|
||||
return "SLIDE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct TouchState touchPanelRead()
|
||||
{
|
||||
uint8_t state = 0;
|
||||
|
||||
if (!touchEventOccured) return internalTouchState;
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
uint32_t startReadStatus = timersGetMsTick();
|
||||
do {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1)) {
|
||||
// ledRed();
|
||||
touchGT911hiccups++;
|
||||
TRACE("GT911 I2C read XY error");
|
||||
if (!I2C_ReInit()) TRACE("I2C B1 ReInit failed");
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
if (state & 0x80u) {
|
||||
// ready
|
||||
break;
|
||||
}
|
||||
sleep_ms(1);
|
||||
} while (timersGetMsTick() - startReadStatus < GT911_TIMEOUT);
|
||||
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
TRACE("touch state = 0x%x", state);
|
||||
if (state & 0x80u) {
|
||||
uint8_t pointsCount = (state & 0x0Fu);
|
||||
uint32_t now = timersGetMsTick();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (pointsCount > 0 && pointsCount <= GT911_MAX_TP) {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG + 1, touchData.data,
|
||||
pointsCount * sizeof(TouchPoint))) {
|
||||
// ledRed();
|
||||
touchGT911hiccups++;
|
||||
TRACE("GT911 I2C data read error");
|
||||
if (!I2C_ReInit()) TRACE("I2C B1 ReInit failed");
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
if (internalTouchState.event == TE_NONE ||
|
||||
internalTouchState.event == TE_UP ||
|
||||
internalTouchState.event == TE_SLIDE_END) {
|
||||
internalTouchState.event = TE_DOWN;
|
||||
internalTouchState.startX = internalTouchState.x =
|
||||
touchData.points[0].x;
|
||||
internalTouchState.startY = internalTouchState.y =
|
||||
touchData.points[0].y;
|
||||
downTime = now;
|
||||
} else {
|
||||
internalTouchState.deltaX =
|
||||
touchData.points[0].x - internalTouchState.x;
|
||||
internalTouchState.deltaY =
|
||||
touchData.points[0].y - internalTouchState.y;
|
||||
if (internalTouchState.event == TE_SLIDE ||
|
||||
abs(internalTouchState.deltaX) >= SLIDE_RANGE ||
|
||||
abs(internalTouchState.deltaY) >= SLIDE_RANGE) {
|
||||
internalTouchState.event = TE_SLIDE;
|
||||
internalTouchState.x = touchData.points[0].x;
|
||||
internalTouchState.y = touchData.points[0].y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (internalTouchState.event == TE_SLIDE) {
|
||||
internalTouchState.event = TE_SLIDE_END;
|
||||
} else if (internalTouchState.event == TE_DOWN) {
|
||||
internalTouchState.event = TE_UP;
|
||||
if (now - downTime <= GT911_TAP_TIME) {
|
||||
if (now - tapTime > GT911_TAP_TIME)
|
||||
tapCount = 1;
|
||||
else
|
||||
tapCount++;
|
||||
internalTouchState.tapCount = tapCount;
|
||||
tapTime = now;
|
||||
}
|
||||
} else {
|
||||
internalTouchState.event = TE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t zero = 0;
|
||||
if (!I2C_GT911_WriteRegister(GT911_READ_XY_REG, &zero, 1)) {
|
||||
TRACE("GT911 ERROR: clearing XY register failed");
|
||||
}
|
||||
|
||||
TRACE("touch event = %s", event2str(internalTouchState.event));
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
bool touchPanelEventOccured()
|
||||
{
|
||||
return touchEventOccured;
|
||||
}
|
||||
|
||||
TouchState getInternalTouchState()
|
||||
{
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 "touch.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#define HAS_TOUCH_PANEL() (touchGT911Flag == true)
|
||||
|
||||
extern bool touchGT911Flag;
|
||||
extern uint16_t touchGT911fwver;
|
||||
extern uint32_t touchGT911hiccups;
|
||||
|
||||
extern void touchPanelDeInit();
|
||||
extern bool touchPanelInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
#define GT911_TIMEOUT 3 // 3ms
|
||||
#define GT911_TAP_TIME 250 // 250 ms
|
||||
|
||||
#define GT911_MAX_TP 5
|
||||
|
||||
#define GT911_CFG_NUMBER 0x6D
|
||||
|
||||
//I2C
|
||||
#define GT911_I2C_ADDR 0x14
|
||||
|
||||
//#define GT_CMD_WR 0x28
|
||||
//#define GT_CMD_RD 0x29
|
||||
//#define I2C_TIMEOUT_MAX 1000
|
||||
|
||||
#define GT911_COMMAND_REG 0x8040
|
||||
#define GT911_CONFIG_REG 0x8047
|
||||
#define GT911_COORDINATE_REG 0x804D
|
||||
#define GT911_CONFIG_CHECKSUM_REG 0x80FF
|
||||
|
||||
#define GT911_PRODUCT_ID_REG 0x8140
|
||||
#define GT911_FIRMWARE_VERSION_REG 0x8144
|
||||
#define GT911_VENDOR_ID_REG 0x814A
|
||||
#define GT911_READ_XY_REG 0x814E
|
||||
#define GT911_TP1_REG 0x8150
|
||||
#define GT911_TP2_REG 0x8158
|
||||
#define GT911_TP3_REG 0x8160
|
||||
#define GT911_TP4_REG 0x8168
|
||||
#define GT911_TP5_REG 0x8170
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t track;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t size;
|
||||
uint8_t reserved;
|
||||
}) TouchPoint;
|
||||
|
||||
PACK(struct TouchData {
|
||||
union
|
||||
{
|
||||
TouchPoint points[GT911_MAX_TP];
|
||||
uint8_t data[GT911_MAX_TP * sizeof(TouchPoint)];
|
||||
};
|
||||
});
|
||||
+12
-21
@@ -19,31 +19,22 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "hal/usb_driver.h"
|
||||
|
||||
void EXTERNAL_MODULE_ON()
|
||||
//TODO: charger enable control
|
||||
|
||||
void usbChargerInit()
|
||||
{
|
||||
GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
gpio_init(UCHARGER_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(UCHARGER_EN_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_clear(UCHARGER_EN_GPIO);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_OFF()
|
||||
bool usbChargerLed()
|
||||
{
|
||||
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();
|
||||
return (gpio_read(UCHARGER_GPIO) && usbPlugged());
|
||||
}
|
||||
@@ -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 "TX15"
|
||||
#define USB_MANUFACTURER 'R', 'M', ' ', ' ', ' ', ' ', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'T', 'X', '1', '5', ' ', ' ', ' ', ' ' /* 8 Bytes */
|
||||
|
||||
#endif // _USB_DESCRIPTOR_H_
|
||||
+88
-88
@@ -125,33 +125,33 @@ TEST_F(TrimsTest, throttleTrim)
|
||||
{
|
||||
g_model.thrTrim = 1;
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(512));
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(256));
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS);
|
||||
#if defined(SURFACE_RADIO)
|
||||
// stick bellow 0 + trim max :no trim in reverse
|
||||
anaSetFiltered(THR_STICK, -512);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -512);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -512);
|
||||
@@ -159,27 +159,27 @@ TEST_F(TrimsTest, throttleTrim)
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(2048));
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(1024));
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS);
|
||||
@@ -190,12 +190,12 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrim)
|
||||
g_model.throttleReversed = 1;
|
||||
g_model.thrTrim = 1;
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024);
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -204,7 +204,7 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrim)
|
||||
EXPECT_EQ(channelOutputs[2], -1024+256);
|
||||
#endif
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -213,7 +213,7 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrim)
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024+512);
|
||||
#endif
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -222,12 +222,12 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrim)
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024+512);
|
||||
#endif
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
@@ -235,40 +235,40 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrim)
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max : no effect since we are in reverse mode
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024);
|
||||
#if defined(SURFACE_RADIO)
|
||||
// stick max + trim mid: no effect since we are in reverse mode
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024);
|
||||
#else
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024+1024);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024+2048);
|
||||
#endif
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
@@ -281,32 +281,32 @@ TEST_F(TrimsTest, throttleTrimWithZeroWeightOnThrottle)
|
||||
ExpoData *expo = expoAddress(THR_STICK);
|
||||
expo->weight = makeSourceNumVal(0);
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 256);
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[THR_CHAN] - 128), 1); //can't use precise comparison here because of lower precision math on 9X
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 256);
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[THR_CHAN] - 128), 1);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
@@ -315,31 +315,31 @@ TEST_F(TrimsTest, throttleTrimWithZeroWeightOnThrottle)
|
||||
g_model.extendedTrims = 1;
|
||||
// trim min + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, -300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, +300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
|
||||
// trim max + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, -300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, +300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
}
|
||||
@@ -352,32 +352,32 @@ TEST_F(TrimsTest, invertedThrottlePlusthrottleTrimWithZeroWeightOnThrottle)
|
||||
ExpoData *expo = expoAddress(THR_STICK);
|
||||
expo->weight = makeSourceNumVal(0);
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[THR_CHAN] - 128), 1);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 256);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_LE(abs(channelOutputs[THR_CHAN] - 128), 1);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, THR_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 256);
|
||||
@@ -386,38 +386,38 @@ TEST_F(TrimsTest, invertedThrottlePlusthrottleTrimWithZeroWeightOnThrottle)
|
||||
g_model.extendedTrims = 1;
|
||||
// trim min + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MIN);
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, -300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, +300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
|
||||
// trim max + various stick positions = should always be same value
|
||||
setTrimValue(0, THR_STICK, TRIM_EXTENDED_MAX);
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, -300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, +300);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +300);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 0);
|
||||
}
|
||||
|
||||
TEST_F(TrimsTest, CopyTrimsToOffset)
|
||||
{
|
||||
setTrimValue(0, ELE_STICK, -100); // -100 on elevator/steering
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, -100); // -100 on elevator/steering
|
||||
evalFunctions(g_model.customFn, modelFunctionsContext); // it disables all safety channels
|
||||
copyTrimsToOffset(ELE_CHAN);
|
||||
EXPECT_EQ(getTrimValue(0, ELE_STICK), -100); // unchanged
|
||||
@@ -426,7 +426,7 @@ TEST_F(TrimsTest, CopyTrimsToOffset)
|
||||
|
||||
TEST_F(TrimsTest, CopySticksToOffset)
|
||||
{
|
||||
anaSetFiltered(ELE_STICK, -100);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), -100);
|
||||
evalMixes(1);
|
||||
copySticksToOffset(ELE_CHAN);
|
||||
#if defined(STICK_DEAD_ZONE)
|
||||
@@ -440,7 +440,7 @@ TEST_F(TrimsTest, MoveTrimsToOffsets)
|
||||
{
|
||||
// No trim idle only
|
||||
g_model.thrTrim = 0;
|
||||
anaSetFiltered(THR_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), 0);
|
||||
setTrimValue(0, MIXSRC_TRIMTHR - MIXSRC_FIRST_TRIM, 100);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, -100);
|
||||
evalMixes(1);
|
||||
@@ -462,7 +462,7 @@ TEST_F(TrimsTest, MoveTrimsToOffsetsWithTrimIdle)
|
||||
{
|
||||
// Trim idle only
|
||||
g_model.thrTrim = 1;
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS); // Min stick
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS); // Min stick
|
||||
g_model.limitData[THR_CHAN].offset = 0;
|
||||
g_model.limitData[ELE_CHAN].offset = 0;
|
||||
setTrimValue(0, MIXSRC_TRIMTHR - MIXSRC_FIRST_TRIM, 100);
|
||||
@@ -505,8 +505,8 @@ TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrossTrims)
|
||||
expo = expoAddress(ELE_CHAN);
|
||||
expo->trimSource = THR_TRIM_SOURCE;
|
||||
|
||||
anaSetFiltered(THR_STICK, 0);
|
||||
anaSetFiltered(ELE_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), 0);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), 0);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 100);
|
||||
setTrimValue(0, MIXSRC_TRIMTHR - MIXSRC_FIRST_TRIM, -100);
|
||||
evalMixes(1);
|
||||
@@ -537,7 +537,7 @@ TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrosstrimsAndTrimIdle)
|
||||
expo->trimSource = ELE_TRIM_SOURCE;
|
||||
expo = expoAddress(ELE_CHAN);
|
||||
expo->trimSource = THR_TRIM_SOURCE;
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS); // Min throttle
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS); // Min throttle
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 100);
|
||||
setTrimValue(0, MIXSRC_TRIMTHR - MIXSRC_FIRST_TRIM, -100);
|
||||
evalMixes(1);
|
||||
@@ -927,7 +927,7 @@ TEST_F(TrimsTest, throttleTrimEle) {
|
||||
g_model.thrTrim = 1;
|
||||
// checks ELE sticks are not affected by throttleTrim
|
||||
// stick max + trim min
|
||||
anaSetFiltered(ELE_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), +1024);
|
||||
setTrimValue(0, ELE_STICK, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024 - 256);
|
||||
@@ -965,9 +965,9 @@ TEST(Heli, BasicTest)
|
||||
g_model.mixData[2].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[2].srcRaw = MIXSRC_CYC3;
|
||||
g_model.mixData[2].weight = makeSourceNumVal(100);
|
||||
anaSetFiltered(THR_STICK, 0);
|
||||
anaSetFiltered(ELE_STICK, 1024);
|
||||
anaSetFiltered(AIL_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), 0);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), 1024);
|
||||
anaSetFiltered(inputMappingConvertMode(AIL_STICK), 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], -CHANNEL_MAX);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX/2);
|
||||
@@ -1001,9 +1001,9 @@ TEST(Heli, Mode2Test)
|
||||
g_model.mixData[2].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[2].srcRaw = MIXSRC_CYC3;
|
||||
g_model.mixData[2].weight = makeSourceNumVal(100);
|
||||
anaSetFiltered(THR_STICK, 0);
|
||||
anaSetFiltered(ELE_STICK, 1024);
|
||||
anaSetFiltered(AIL_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), 0);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), 1024);
|
||||
anaSetFiltered(inputMappingConvertMode(AIL_STICK), 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], -CHANNEL_MAX);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX/2);
|
||||
@@ -1093,32 +1093,32 @@ TEST_F(TrimsTest, throttleTrimWithCrossTrims)
|
||||
expo->trimSource = THR_TRIM_SOURCE;
|
||||
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(ELE_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), 0);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(512));
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(256));
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS);
|
||||
@@ -1127,31 +1127,31 @@ TEST_F(TrimsTest, throttleTrimWithCrossTrims)
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], 1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024+2048);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim mid
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 0);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS + TRIM_SCALE(1024));
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, THR_STICK_MIN_THR_POS);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), THR_STICK_MIN_THR_POS);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], THR_STICK_MIN_THR_POS);
|
||||
@@ -1169,14 +1169,14 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
expo->trimSource = THR_TRIM_SOURCE;
|
||||
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(ELE_STICK, 0);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(ELE_STICK), 0);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 0);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -1186,7 +1186,7 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
#endif
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -1196,13 +1196,13 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
#endif
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
@@ -1211,13 +1211,13 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
// now the same tests with extended Trims
|
||||
g_model.extendedTrims = 1;
|
||||
// stick max + trim max
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], -1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim mid
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, 0);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -1227,7 +1227,7 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
#endif
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick max + trim min
|
||||
anaSetFiltered(THR_STICK, +1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), +1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
#if defined(SURFACE_RADIO)
|
||||
@@ -1237,13 +1237,13 @@ TEST_F(TrimsTest, invertedThrottlePlusThrottleTrimWithCrossTrims)
|
||||
#endif
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim max
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MAX);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
EXPECT_EQ(channelOutputs[ELE_CHAN], 0);
|
||||
// stick min + trim min
|
||||
anaSetFiltered(THR_STICK, -1024);
|
||||
anaSetFiltered(inputMappingConvertMode(THR_STICK), -1024);
|
||||
setTrimValue(0, MIXSRC_TRIMELE - MIXSRC_FIRST_TRIM, TRIM_EXTENDED_MIN);
|
||||
evalMixes(1);
|
||||
EXPECT_EQ(channelOutputs[THR_CHAN], +1024);
|
||||
|
||||
@@ -90,7 +90,7 @@ LEGACY_NAMES = [
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": {"t15"},
|
||||
"targets": {"t15", "tx15"},
|
||||
"inputs": {
|
||||
"LH": {
|
||||
"yaml": "Rud",
|
||||
|
||||
@@ -142,6 +142,10 @@ POT_CONFIG = {
|
||||
"SL1": {"default": "SLIDER"},
|
||||
"SL2": {"default": "SLIDER"}
|
||||
},
|
||||
"tx15": {
|
||||
"P1": {"default": "POT"},
|
||||
"P2": {"default": "POT"},
|
||||
},
|
||||
"tx16s": {
|
||||
"P1": {"default": "POT_CENTER"},
|
||||
"P2": {"default": "MULTIPOS"},
|
||||
|
||||
@@ -382,6 +382,21 @@ SWITCH_CONFIG = {
|
||||
"SF": {"default": "3POS", "display": [1, 2]},
|
||||
"SH": {"default": "NONE", "display": [1, 3]}
|
||||
},
|
||||
"tx15": {
|
||||
"SA": {"default": "3POS"},
|
||||
"SB": {"default": "3POS"},
|
||||
"SC": {"default": "3POS"},
|
||||
"SD": {"default": "3POS"},
|
||||
"SE": {"default": "2POS"},
|
||||
"SF": {"default": "TOGGLE"},
|
||||
# custom switches
|
||||
"SG": {"default": "2POS"},
|
||||
"SH": {"default": "2POS"},
|
||||
"SI": {"default": "2POS"},
|
||||
"SJ": {"default": "2POS"},
|
||||
"SK": {"default": "2POS"},
|
||||
"SL": {"default": "2POS"},
|
||||
},
|
||||
"tx16s": {
|
||||
"SA": {"default": "3POS"},
|
||||
"SB": {"default": "3POS"},
|
||||
|
||||
@@ -116,6 +116,9 @@ get_target_build_options() {
|
||||
t18)
|
||||
BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T18"
|
||||
;;
|
||||
tx15)
|
||||
BUILD_OPTIONS+="-DPCB=TX15 -DNANO=NO"
|
||||
;;
|
||||
tx16s)
|
||||
BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=TX16S"
|
||||
;;
|
||||
|
||||
@@ -208,7 +208,7 @@ declare -a simulator_plugins=(
|
||||
t8 t12 t12max tx12 tx12mk2 t15 t16 t18 t20 t20v2
|
||||
xlite xlites
|
||||
x10 x10express x12s
|
||||
zorro tx16s
|
||||
zorro tx16s tx15
|
||||
commando8 boxer pocket mt12 gx12
|
||||
tlite tpro tprov2 tpros bumblebee lr3pro t14
|
||||
nv14 el18 pl18 pl18ev pl18u st16 pa01
|
||||
|
||||
+1
-2
@@ -86,8 +86,7 @@ do
|
||||
|
||||
rm -f CMakeCache.txt arm-none-eabi/CMakeCache.txt
|
||||
|
||||
#if [ -f arm-none-eabi/firmware.uf2 ]; then
|
||||
if [ "$target_name" = "st16" ]; then
|
||||
if [ -f "arm-none-eabi/firmware.uf2" ]; then
|
||||
mv arm-none-eabi/firmware.uf2 "../${fw_name}.uf2"
|
||||
else
|
||||
mv arm-none-eabi/firmware.bin "../${fw_name}.bin"
|
||||
|
||||
@@ -9,7 +9,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
: "${SRCDIR:=$(dirname "$(pwd)/$0")/..}"
|
||||
|
||||
: ${FLAVOR:="nv14;el18;pl18;pl18ev;nb4p;st16;t12;t12max;t15;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v14;v12"}
|
||||
: ${FLAVOR:="nv14;el18;pl18;pl18ev;nb4p;st16;t12;t12max;t15;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v14;v12;tx15"}
|
||||
: ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -Wno-dev -DCMAKE_MESSAGE_LOG_LEVEL=WARNING"}
|
||||
|
||||
# wipe build directory clean
|
||||
|
||||
@@ -11,7 +11,7 @@ if [[ -n ${GCC_ARM} ]] ; then
|
||||
export PATH=${GCC_ARM}:$PATH
|
||||
fi
|
||||
|
||||
: ${FLAVOR:="t15;tx16s;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;pa01"}
|
||||
: ${FLAVOR:="t15;tx16s;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;pa01;tx15"}
|
||||
: ${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"}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
export BRANCH_NAME="main" # main|2.9|...
|
||||
export RADIO_TYPE="tx16s" # tx16s|x10|x10express|x12s|x9d|x9dp|x9lite|x9lites|x7|x7access|t12|t12max|tx12|tx12mk2|mt12|gx12|boxer|t8|zorro|pocket|tlite|tpro|t20|t20v2|t14|lr3pro|xlite|xlites|x9dp2019|x9e|x9e-hall|t15|t16|t18|nv14|commando8
|
||||
export RADIO_TYPE="tx16s" # tx16s|x10|x10express|x12s|x9d|x9dp|x9lite|x9lites|x7|x7access|t12|t12max|tx12|tx12mk2|mt12|gx12|boxer|t8|zorro|pocket|tlite|tpro|t20|t20v2|t14|lr3pro|xlite|xlites|x9dp2019|x9e|x9e-hall|t15|t16|t18|nv14|commando8|tx15
|
||||
|
||||
export BUILD_OPTIONS="-DDEFAULT_MODE=2 -DGVARS=YES"
|
||||
|
||||
@@ -114,6 +114,9 @@ case $RADIO_TYPE in
|
||||
t18)
|
||||
BUILD_OPTIONS+=" -DPCB=X10 -DPCBREV=T18"
|
||||
;;
|
||||
tx15)
|
||||
BUILD_OPTIONS+=" -DPCB=TX15"
|
||||
;;
|
||||
tx16s)
|
||||
BUILD_OPTIONS+=" -DPCB=X10 -DPCBREV=TX16S"
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user