feat: Flysky gimbal support for RM Boxer (#3139)

* Adds Flysky digital hall gimbal support for RadioMaster Boxer.

---------

Co-authored-by: rotorman <risto.koiva@web.de>
This commit is contained in:
richardclli
2023-02-26 13:27:37 +01:00
committed by GitHub
co-authored by rotorman
parent 4ea77ee749
commit 9216570d6c
14 changed files with 125 additions and 42 deletions
+29 -12
View File
@@ -27,7 +27,7 @@
void menuCommonCalib(event_t event)
{
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high vals for sticks and trims
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS+NUM_SLIDERS; i++) { // get low and high values for sticks, pots and sliders
int16_t vt = anaIn(i);
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
@@ -41,12 +41,15 @@ void menuCommonCalib(event_t event)
if (IS_POT_MULTIPOS(i) && count <= XPOTS_MULTIPOS_COUNT) {
// use raw analog value for multipos calibraton, anaIn() already has multipos decoded value
vt = getAnalogValue(i) >> 1;
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 || vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA || vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == 0 ||
vt < reusableBuffer.calib.xpotsCalib[idx].lastPosition - XPOT_DELTA ||
vt > reusableBuffer.calib.xpotsCalib[idx].lastPosition + XPOT_DELTA) {
reusableBuffer.calib.xpotsCalib[idx].lastPosition = vt;
reusableBuffer.calib.xpotsCalib[idx].lastCount = 1;
}
else {
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255) reusableBuffer.calib.xpotsCalib[idx].lastCount++;
if (reusableBuffer.calib.xpotsCalib[idx].lastCount < 255)
reusableBuffer.calib.xpotsCalib[idx].lastCount++;
}
if (reusableBuffer.calib.xpotsCalib[idx].lastCount == XPOT_DELAY) {
int16_t position = reusableBuffer.calib.xpotsCalib[idx].lastPosition;
@@ -99,7 +102,16 @@ void menuCommonCalib(event_t event)
reusableBuffer.calib.loVals[i] = 15000;
reusableBuffer.calib.hiVals[i] = -15000;
#if defined(PCBTARANIS)
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals && (i < FIRST_ANALOG_ADC_FS) )
{
reusableBuffer.calib.midVals[i] = anaIn(i);
}
else
#endif
{
reusableBuffer.calib.midVals[i] = getAnalogValue(i) >> 1;
}
if (i<NUM_XPOTS) {
reusableBuffer.calib.xpotsCalib[i].stepsCount = 0;
reusableBuffer.calib.xpotsCalib[i].lastCount = 0;
@@ -123,9 +135,6 @@ void menuCommonCalib(event_t event)
g_eeGeneral.calib[i].spanPos = v - v/STICK_TOLERANCE;
}
}
break;
case CALIB_STORE:
#if defined(PCBTARANIS)
for (uint8_t i=POT1; i<=POT_LAST; i++) {
int idx = i - POT1;
@@ -145,18 +154,26 @@ void menuCommonCalib(event_t event)
calib->steps[j] = (reusableBuffer.calib.xpotsCalib[idx].steps[j+1] + reusableBuffer.calib.xpotsCalib[idx].steps[j]) >> 5;
}
}
else {
}
}
#endif
break;
case CALIB_STORE:
#if defined(RADIO_BOXER)
// load 6pos calib with factory data if 6 pos was not manually calibrated
for (uint8_t i=POT1; i<=POT_LAST; i++) {
int idx = i - POT1;
if (IS_POT_MULTIPOS(i)) {
int count = reusableBuffer.calib.xpotsCalib[idx].stepsCount;
if (count < XPOTS_MULTIPOS_COUNT)
{
// load 6-pos calib with factory data if 6-pos was not manually calibrated
constexpr int16_t factoryValues[]= {0x5,0xd,0x16,0x1f,0x28};
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[POT3];
calib->count = 5;
for (int j=0; j<calib->count ; j++) {
calib->steps[j] = factoryValues[j];
}
#else
g_eeGeneral.potsConfig &= ~(0x03<<(2*idx));
#endif
}
}
}
+14 -2
View File
@@ -22,12 +22,16 @@
#include "opentx.h"
#include "../../hal/adc_driver.h"
#if defined(FLYSKY_GIMBAL)
#include "flysky_gimbal_driver.h"
#endif
#define HOLDANAVALUEFRAMES 4 /* 4* 50ms = 200 ms update rate */
void menuRadioDiagAnalogs(event_t event)
{
static int8_t entryCount = 0;
static uint16_t lastShownAnalogValue[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
static int16_t lastShownAnalogValue[NUM_STICKS+NUM_POTS+NUM_SLIDERS];
enum ANAVIEWS{
ANAVIEW_FIRST,
@@ -106,7 +110,15 @@ void menuRadioDiagAnalogs(event_t event)
switch (viewpage) {
case (ANAVIEW_RAWLOWFPS):
if (entryCount == 0) {
lastShownAnalogValue[i] = getAnalogValue(i); // Update value
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals && i < FIRST_ANALOG_ADC_FS)
{
lastShownAnalogValue[i] = hall_raw_values[i];
} else
#endif
{
lastShownAnalogValue[i] = getAnalogValue(i); // Update value
}
}
lcdDrawNumber(x+3*FW-1, y, lastShownAnalogValue[i],
LEADING0|LEFT, 4);
+1 -1
View File
@@ -66,7 +66,7 @@ HWPots::HWPots(Window* parent) : FormGroup(parent, rect_t{})
for (int i = 0; i < NUM_POTS; i++) {
// Display EX3 & EX4 (= last two pots) only when FlySky gimbals are present
#if !defined(SIMU) && defined(RADIO_FAMILY_T16)
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
#endif
auto line = newLine(&grid);
+4 -4
View File
@@ -64,7 +64,7 @@ class AnaCalibratedViewWindow: public Window {
void paint(BitmapBuffer * dc) override
{
#if !defined(SIMU) && (defined(RADIO_FAMILY_T16) || defined(PCBNV14))
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
for (uint8_t i = 0; i < FLYSKY_HALL_CHANNEL_COUNT; i++) {
@@ -258,7 +258,7 @@ class AnaFilteredDevViewWindow: public Window {
ClearStats = false;
}
#if !defined(SIMU) && (defined(RADIO_FAMILY_T16) || defined(PCBNV14))
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
for (uint8_t i = 0; i < FLYSKY_HALL_CHANNEL_COUNT; i++) {
@@ -337,7 +337,7 @@ class AnaUnfilteredRawViewWindow: public Window {
void paint(BitmapBuffer * dc) override
{
#if !defined(SIMU) && (defined(RADIO_FAMILY_T16) || defined(PCBNV14))
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
for (uint8_t i = 0; i < FLYSKY_HALL_CHANNEL_COUNT; i++) {
@@ -460,7 +460,7 @@ class AnaMinMaxViewWindow: public Window {
}
dc->drawText(10, 1, STR_ANADIAGS_MOVE, COLOR_THEME_PRIMARY1);
#if !defined(SIMU) && (defined(RADIO_FAMILY_T16) || defined(PCBNV14))
#if !defined(SIMU) && defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
for (uint8_t i = 0; i < FLYSKY_HALL_CHANNEL_COUNT; i++) {
+3 -3
View File
@@ -134,7 +134,8 @@ bool adcRead()
uint16_t temp[NUM_ANALOGS] = { 0 };
uint8_t first_analog_adc;
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
first_analog_adc = FIRST_ANALOG_ADC_FS;
@@ -146,7 +147,6 @@ bool adcRead()
first_analog_adc = FIRST_ANALOG_ADC;
#endif
for (int i=0; i<4; i++) {
if (!adcSingleRead())
return false;
@@ -267,7 +267,7 @@ void getADC()
for (uint8_t x=0; x<NUM_ANALOGS; x++) {
uint32_t v;
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
if (x < 4) {
+4
View File
@@ -33,8 +33,12 @@
#define NUM_ANALOGS_ADC_EXT (NUM_ANALOGS - NUM_ANALOGS_ADC)
#else
#define FIRST_ANALOG_ADC_FS 4
#if defined (RADIO_BOXER)
#define NUM_ANALOGS_ADC_FS 5
#else
#define NUM_ANALOGS_ADC_FS 10
#define NUM_ANALOGS_ADC_EXT 2
#endif
#define FIRST_ANALOG_ADC 0
#define NUM_ANALOGS_ADC NUM_ANALOGS
#endif
@@ -63,6 +63,13 @@ if(AUX_SERIAL OR AUX2_SERIAL)
endif()
endif()
if(FLYSKY_GIMBAL)
set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC}
../common/arm/stm32/flysky_gimbal_driver.cpp
)
add_definitions(-DFLYSKY_GIMBAL)
endif()
if(DEBUG OR CLI OR USB_SERIAL)
set(STM32USB_SRC ${STM32USB_SRC}
STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
@@ -35,14 +35,16 @@ static void adc_init_pins()
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#if defined(ADC_GPIOA_PINS)
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
GPIO_InitStructure.GPIO_Pin = ADC_GPIOA_PINS_FS;
}
else
#endif
#endif
{
GPIO_InitStructure.GPIO_Pin = ADC_GPIOA_PINS;
}
GPIO_Init(GPIOA, &GPIO_InitStructure);
#endif
@@ -144,7 +146,7 @@ static const stm32_hal_adc_channel* ADC_MAIN_get_channels()
if (STICKS_PWM_ENABLED())
return ADC_MAIN_channels + 4;
#endif
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
return ADC_MAIN_channels + FIRST_ANALOG_ADC_FS;
@@ -158,12 +160,16 @@ static const stm32_hal_adc_channel* ADC_MAIN_get_channels()
static uint8_t ADC_MAIN_get_nconv()
{
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
if (globalData.flyskygimbals)
return NUM_ANALOGS_ADC_FS;
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
return NUM_ANALOGS_ADC_FS;
}
else
#endif
return NUM_ANALOGS_ADC; // based on STICKS_PWM_ENABLED()
{
return NUM_ANALOGS_ADC; // based on STICKS_PWM_ENABLED()
}
}
#if defined(ADC_EXT)
@@ -205,7 +211,7 @@ static const stm32_hal_adc_channel* ADC_EXT_get_channels()
static uint16_t* ADC_MAIN_get_dma_buffer()
{
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
return &adcValues[FIRST_ANALOG_ADC_FS];
@@ -220,14 +226,16 @@ static uint16_t* ADC_MAIN_get_dma_buffer()
#if defined(ADC_EXT) && defined(ADC_EXT_DMA_Stream)
static uint16_t* ADC_EXT_get_dma_buffer()
{
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
if (globalData.flyskygimbals)
{
return adcValues + NUM_ANALOGS_ADC_FS + FIRST_ANALOG_ADC_FS;
}
else
#endif
return adcValues + NUM_ANALOGS_ADC + FIRST_ANALOG_ADC;
{
return adcValues + NUM_ANALOGS_ADC + FIRST_ANALOG_ADC;
}
}
#endif
+3 -5
View File
@@ -93,6 +93,7 @@ if (PCB STREQUAL X10)
set(AUX2_SERIAL ON)
endif()
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
set(FLYSKY_GIMBAL ON)
elseif (PCBREV STREQUAL TX16S)
set(FLAVOUR tx16s)
set(LUA_EXPORT lua_export_t16)
@@ -110,6 +111,7 @@ if (PCB STREQUAL X10)
set(AUX2_SERIAL ON)
endif()
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
set(FLYSKY_GIMBAL ON)
elseif (PCBREV STREQUAL T18)
set(FLAVOUR t18)
set(LUA_EXPORT lua_export_t16)
@@ -124,6 +126,7 @@ if (PCB STREQUAL X10)
set(AUX2_SERIAL ON)
endif()
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
set(FLYSKY_GIMBAL ON)
else()
set(FLAVOUR x10)
set(DEFAULT_INTERNAL_MODULE XJT_PXX1 CACHE STRING "Default internal module")
@@ -192,10 +195,6 @@ if(HARDWARE_EXTERNAL_ACCESS_MOD)
add_definitions(-DHARDWARE_EXTERNAL_ACCESS_MOD)
endif()
if(PCB STREQUAL X10)
set(FLYSKY_HALL_STICKS_DRIVER targets/common/arm/stm32/flysky_gimbal_driver.cpp)
endif()
if(IMU_LSM6DS33)
add_definitions(-DIMU_LSM6DS33)
set(AUX_SERIAL OFF)
@@ -288,7 +287,6 @@ set(FIRMWARE_SRC
targets/common/arm/stm32/heartbeat_driver.cpp
targets/common/arm/stm32/trainer_driver.cpp
targets/common/arm/stm32/sdio_sd.c
${FLYSKY_HALL_STICKS_DRIVER}
)
if(BOOTLOADER)
+4 -4
View File
@@ -43,7 +43,7 @@
#define ADC_DRIVER x12s_adc_driver
#endif
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
#include "flysky_gimbal_driver.h"
#endif
@@ -75,7 +75,7 @@ void boardInit()
AUDIO_RCC_AHB1Periph |
KEYS_RCC_AHB1Periph |
ADC_RCC_AHB1Periph |
#if defined(RADIO_FAMILY_T16)
#if defined(FLYSKY_GIMBAL)
FLYSKY_HALL_RCC_AHB1Periph |
#endif
AUX_SERIAL_RCC_AHB1Periph |
@@ -95,7 +95,7 @@ void boardInit()
ADC_RCC_APB1Periph |
TIMER_2MHz_RCC_APB1Periph |
AUDIO_RCC_APB1Periph |
#if defined(RADIO_FAMILY_T16)
#if defined(FLYSKY_GIMBAL)
FLYSKY_HALL_RCC_APB1Periph |
#endif
TELEMETRY_RCC_APB1Periph |
@@ -158,7 +158,7 @@ void boardInit()
}
#endif
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#if defined(FLYSKY_GIMBAL)
globalData.flyskygimbals = flysky_gimbal_init();
#else
globalData.flyskygimbals = false;
+1 -1
View File
@@ -60,6 +60,7 @@ set(HARDWARE_TOUCH YES)
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
set(HARDWARE_TOUCH ON)
set(FLYSKY_GIMBAL ON)
add_definitions(
-DSTM32F429_439xx -DSTM32F429xx
@@ -156,7 +157,6 @@ set(FIRMWARE_SRC
targets/common/arm/stm32/trainer_driver.cpp
targets/common/arm/stm32/pwr_driver.cpp
targets/common/arm/stm32/sdio_sd.c
targets/common/arm/stm32/flysky_gimbal_driver.cpp
)
# Make malloc() thread-safe
+1
View File
@@ -242,6 +242,7 @@ elseif(PCB STREQUAL X7)
set(PXX2 ON)
set(ENABLE_SERIAL_PASSTHROUGH ON CACHE BOOL "Enable serial passthrough")
set(CLI ON CACHE BOOL "Enable CLI")
set(FLYSKY_GIMBAL ON)
elseif(PCBREV STREQUAL ZORRO)
set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module")
set(INTERNAL_MODULE_SERIAL YES)
+16
View File
@@ -54,6 +54,10 @@ extern "C" {
}
#endif
#if defined(FLYSKY_GIMBAL)
#include "flysky_gimbal_driver.h"
#endif
HardwareOptions hardwareOptions;
void watchdogInit(unsigned int duration)
@@ -81,6 +85,9 @@ void boardInit()
AUDIO_RCC_AHB1Periph |
BACKLIGHT_RCC_AHB1Periph |
ADC_RCC_AHB1Periph |
#if defined(FLYSKY_GIMBAL)
FLYSKY_HALL_RCC_AHB1Periph |
#endif
SD_RCC_AHB1Periph |
HAPTIC_RCC_AHB1Periph |
INTMODULE_RCC_AHB1Periph |
@@ -97,6 +104,9 @@ void boardInit()
LCD_RCC_APB1Periph |
AUDIO_RCC_APB1Periph |
ADC_RCC_APB1Periph |
#if defined(FLYSKY_GIMBAL)
FLYSKY_HALL_RCC_APB1Periph |
#endif
BACKLIGHT_RCC_APB1Periph |
HAPTIC_RCC_APB1Periph |
INTERRUPT_xMS_RCC_APB1Periph |
@@ -213,6 +223,12 @@ void boardInit()
}
#endif
#if defined(FLYSKY_GIMBAL)
globalData.flyskygimbals = flysky_gimbal_init();
#else
globalData.flyskygimbals = false;
#endif
if (!adcInit(&stm32_hal_adc_driver))
TRACE("adcInit failed");
lcdInit(); // delaysInit() must be called before
+20
View File
@@ -1367,6 +1367,7 @@
#define ADC_GPIO_PIN_POT3 GPIO_Pin_5 // PA.05
#define ADC_CHANNEL_POT3 ADC_Channel_5
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_POT3)
#define ADC_GPIOA_PINS_FS (ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_POT3)
#else
#define ADC_CHANNEL_POT3 0
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_POT2)
@@ -2509,6 +2510,25 @@
#define HAPTIC_GPIO_PIN GPIO_Pin_12
#endif
#if defined(RADIO_BOXER)
// Flysky Hall Stick
#define FLYSKY_HALL_SERIAL_USART UART4
#define FLYSKY_HALL_SERIAL_GPIO GPIOA
#define FLYSKY_HALL_DMA_Channel LL_DMA_CHANNEL_4
#define FLYSKY_HALL_SERIAL_TX_GPIO_PIN LL_GPIO_PIN_0 // PA.00
#define FLYSKY_HALL_SERIAL_RX_GPIO_PIN LL_GPIO_PIN_1 // PA.01
#define FLYSKY_HALL_SERIAL_GPIO_AF LL_GPIO_AF_8
#define FLYSKY_HALL_RCC_AHB1Periph RCC_AHB1Periph_DMA1
#define FLYSKY_HALL_RCC_APB1Periph RCC_APB1Periph_UART4
#define FLYSKY_HALL_SERIAL_USART_IRQHandler UART4_IRQHandler
#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_Stream_TX LL_DMA_STREAM_4
#endif
// Top LCD on X9E
#if defined(PCBX9E)
#define TOPLCD_RCC_AHB1Periph RCC_AHB1Periph_GPIOG