fix: PWM gimbals initialisation and inversion (#3745)

* fix: PWM gimbals initialisation and inversion

* feat: add periph clock support in PWM stick driver
This commit is contained in:
Raphael Coeffic
2023-07-14 14:54:32 +10:00
committed by GitHub
parent c5aa250dd9
commit 1bb27e7011
17 changed files with 282 additions and 144 deletions
@@ -3,6 +3,7 @@
AddHWGenTarget(${HW_DESC_JSON} stm32_keys stm32_keys.inc)
AddHWGenTarget(${HW_DESC_JSON} stm32_switches stm32_switches.inc)
AddHWGenTarget(${HW_DESC_JSON} stm32_adc_inputs stm32_adc_inputs.inc)
AddHWGenTarget(${HW_DESC_JSON} stm32_pwm_inputs stm32_pwm_inputs.inc)
AddHWGenTarget(${HW_DESC_JSON} hal_adc_inputs hal_adc_inputs.inc)
# Dependencies common to bootloader and firmware
@@ -17,6 +18,7 @@ set(MINIMAL_BOARD_LIB_SRC
set(BOARD_LIB_SRC
${CMAKE_CURRENT_BINARY_DIR}/stm32_switches.inc
${CMAKE_CURRENT_BINARY_DIR}/stm32_adc_inputs.inc
${CMAKE_CURRENT_BINARY_DIR}/stm32_pwm_inputs.inc
${CMAKE_CURRENT_BINARY_DIR}/hal_adc_inputs.inc
boards/generic_stm32/module_ports.cpp
@@ -22,6 +22,7 @@
#include "analog_inputs.h"
#include "stm32_adc.h"
#include "stm32_spi_adc.h"
#include "sticks_pwm_driver.h"
#include "hal.h"
@@ -38,6 +39,7 @@
// generated files
#include "stm32_adc_inputs.inc"
#include "stm32_pwm_inputs.inc"
#include "hal_adc_inputs.inc"
constexpr uint8_t n_ADC = DIM(_ADC_adc);
@@ -83,3 +85,35 @@ const etx_hal_adc_driver_t _adc_driver = {
adc_wait_completion
};
#if defined(PWM_STICKS)
static const stick_pwm_timer_t _sticks_timer = {
PWM_GPIO,
PWM_GPIOA_PINS,
PWM_GPIO_AF,
PWM_TIMER,
PWM_IRQn,
};
#if !defined(PWM_IRQHandler)
#error "Missing PWM_IRQHandler"
#endif
extern "C" void PWM_IRQHandler(void)
{
sticks_pwm_isr(&_sticks_timer, _PWM_inputs, DIM(_PWM_inputs));
}
bool sticksPwmDetect()
{
return sticks_pwm_detect(&_sticks_timer, _PWM_inputs, DIM(_PWM_inputs));
}
#else
bool sticksPwmDetect()
{
return false;
}
#endif
@@ -22,3 +22,5 @@
#include "hal/adc_driver.h"
extern const etx_hal_adc_driver_t _adc_driver;
bool sticksPwmDetect();
@@ -43,6 +43,7 @@ set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC}
../common/arm/stm32/module_timer_driver.cpp
../common/arm/stm32/stm32_switch_driver.cpp
../common/arm/stm32/stm32_adc.cpp
../common/arm/stm32/stm32_timer.cpp
../common/arm/stm32/stm32_gpio_driver.cpp
../common/arm/stm32/mixer_scheduler_driver.cpp
)
@@ -19,151 +19,157 @@
* GNU General Public License for more details.
*/
#include "sticks_pwm_driver.h"
#include "stm32_gpio_driver.h"
#include "stm32_timer.h"
#include "hal/adc_driver.h"
#include "stm32_hal_ll.h"
#include "delays_driver.h"
#include "hal.h"
#include "dataconstants.h"
static volatile uint32_t pwm_interrupt_count;
static volatile uint32_t _pwm_interrupt_count;
static void sticksPwmInit()
static void sticks_pwm_init(const stick_pwm_timer_t* tim)
{
stm32_gpio_enable_clock(tim->GPIOx);
LL_GPIO_InitTypeDef pinInit;
pinInit.Pin = PWM_GPIOA_PINS;
pinInit.Pin = tim->GPIO_Pin;
pinInit.Alternate = tim->GPIO_Alternate;
pinInit.Mode = LL_GPIO_MODE_ALTERNATE;
pinInit.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
pinInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
pinInit.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(PWM_GPIO, &pinInit);
LL_GPIO_Init(tim->GPIOx, &pinInit);
PWM_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer
PWM_TIMER->PSC = 80;
PWM_TIMER->ARR = 0xffff;
PWM_TIMER->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
PWM_TIMER->CCMR2 = TIM_CCMR2_CC3S_0 | TIM_CCMR2_CC4S_0;
PWM_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
PWM_TIMER->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE;
PWM_TIMER->CR1 = TIM_CR1_CEN; // Start timer
auto TIMx = tim->TIMx;
NVIC_EnableIRQ(PWM_IRQn);
NVIC_SetPriority(PWM_IRQn, 10);
stm32_timer_enable_clock(TIMx);
TIMx->CR1 &= ~TIM_CR1_CEN; // Stop timer
TIMx->PSC = 80;
TIMx->ARR = 0xffff;
TIMx->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
TIMx->CCMR2 = TIM_CCMR2_CC3S_0 | TIM_CCMR2_CC4S_0;
TIMx->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
TIMx->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE;
TIMx->CR1 = TIM_CR1_CEN; // Start timer
NVIC_EnableIRQ(tim->TIM_IRQn);
NVIC_SetPriority(tim->TIM_IRQn, 10);
}
static void sticksPwmDeInit()
static void sticks_pwm_deinit(const stick_pwm_timer_t* tim)
{
NVIC_DisableIRQ(PWM_IRQn);
PWM_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer
NVIC_DisableIRQ(tim->TIM_IRQn);
// Stop timer
auto TIMx = tim->TIMx;
TIMx->CR1 &= ~TIM_CR1_CEN;
stm32_timer_disable_clock(TIMx);
LL_GPIO_InitTypeDef pinInit;
LL_GPIO_StructInit(&pinInit);
pinInit.Pin = PWM_GPIOA_PINS;
pinInit.Pin = tim->GPIO_Pin;
pinInit.Mode = LL_GPIO_MODE_INPUT;
LL_GPIO_Init(PWM_GPIO, &pinInit);
LL_GPIO_Init(tim->GPIOx, &pinInit);
}
bool sticksPwmDetect()
bool sticks_pwm_detect(const stick_pwm_timer_t* timer,
const stick_pwm_input_t* inputs,
uint8_t n_inputs)
{
pwm_interrupt_count = 0;
sticksPwmInit();
if (!timer || !inputs || n_inputs == 0)
return false;
_pwm_interrupt_count = 0;
sticks_pwm_init(timer);
delay_ms(20);
if (pwm_interrupt_count < 32) {
sticksPwmDeInit();
if (_pwm_interrupt_count < 32) {
sticks_pwm_deinit(timer);
return false;
}
return true;
}
static inline uint32_t TIM_GetCapture_Stick(uint8_t n)
static inline uint32_t tim_get_capture(TIM_TypeDef *TIMx, uint8_t channel)
{
switch (n) {
case 0:
return PWM_TIMER->CCR1;
case 1:
return PWM_TIMER->CCR2;
case 2:
return PWM_TIMER->CCR3;
case 3:
return PWM_TIMER->CCR4;
default:
return 0;
}
auto* base_CCRx = &(TIMx->CCR1);
return READ_REG(*(base_CCRx + channel));
}
static inline void TIM_SetPolarityRising(uint8_t n)
static inline void tim_set_polarity_rising(TIM_TypeDef *TIMx, uint8_t channel)
{
PWM_TIMER->CCER &= ~(TIM_CCER_CC1P << (n * 4));
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1P << (channel * 4));
}
static inline void TIM_SetPolarityFalling(uint8_t n)
static inline void tim_set_polarity_falling(TIM_TypeDef *TIMx, uint8_t channel)
{
PWM_TIMER->CCER |= (TIM_CCER_CC1P << (n * 4));
SET_BIT(TIMx->CCER, TIM_CCER_CC1P << (channel * 4));
}
static inline void TIM_ClearITPendingBit(uint8_t n)
static inline uint32_t tim_is_active_flag_CCx(TIM_TypeDef *TIMx, uint8_t channel)
{
PWM_TIMER->SR = ~(TIM_SR_CC1IF << n);
return READ_BIT(TIMx->SR, TIM_SR_CC1IF << channel);
}
static inline void tim_clear_flag_CCx(TIM_TypeDef *TIMx, uint8_t channel)
{
CLEAR_BIT(TIMx->SR, TIM_SR_CC1IF << channel);
}
static inline uint32_t diff_with_16bits_overflow(uint32_t a, uint32_t b)
{
if (b > a)
if (b > a) {
return b - a;
else
return b + 0xffff - a;
}
return b + 0xffff - a;
}
#if !defined(STICK_PWM_CHANNEL_0)
#define STICK_PWM_CHANNEL_0 0
#endif
#if !defined(STICK_PWM_CHANNEL_1)
#define STICK_PWM_CHANNEL_1 1
#endif
#if !defined(STICK_PWM_CHANNEL_2)
#define STICK_PWM_CHANNEL_2 2
#endif
#if !defined(STICK_PWM_CHANNEL_3)
#define STICK_PWM_CHANNEL_3 3
#endif
static const uint8_t _channel_map[] = {
STICK_PWM_CHANNEL_0,
STICK_PWM_CHANNEL_1,
STICK_PWM_CHANNEL_2,
STICK_PWM_CHANNEL_3,
};
extern "C" void PWM_IRQHandler(void)
void sticks_pwm_isr(const stick_pwm_timer_t* tim,
const stick_pwm_input_t* inputs,
uint8_t n_inputs)
{
static uint8_t timer_capture_states[MAX_STICKS];
static uint32_t timer_capture_rising_time[MAX_STICKS];
auto TIMx = tim->TIMx;
auto adcValues = getAnalogValues();
for (uint8_t i=0; i<MAX_STICKS; i++) {
if (PWM_TIMER->SR & (TIM_SR_CC1IF << i)) {
uint32_t capture = TIM_GetCapture_Stick(i);
for (uint8_t i = 0; i < n_inputs; i++) {
const auto& input = inputs[i];
auto channel = input.channel;
if (tim_is_active_flag_CCx(TIMx, channel)) {
uint32_t capture = tim_get_capture(TIMx, channel);
tim_clear_flag_CCx(TIMx, channel);
// overflow may happen but we only use this to detect PWM / ADC on radio startup
pwm_interrupt_count++;
_pwm_interrupt_count++;
if (timer_capture_states[i] != 0) {
uint32_t value = diff_with_16bits_overflow(timer_capture_rising_time[i], capture);
if (value < 10000) {
adcValues[_channel_map[i]] = (uint16_t) value;
if (value <= ADC_MAX_VALUE) {
uint16_t v16 = (uint16_t)value;
adcValues[i] = input.inverted ? ADC_INVERT_VALUE(v16) : v16;
}
TIM_SetPolarityRising(i);
tim_set_polarity_rising(TIMx, channel);
timer_capture_states[i] = 0;
}
else {
timer_capture_rising_time[i] = capture;
TIM_SetPolarityFalling(i);
tim_set_polarity_falling(TIMx, channel);
timer_capture_states[i] = 0x80;
}
TIM_ClearITPendingBit(i);
}
}
}
@@ -21,5 +21,29 @@
#pragma once
#include <stdint.h>
#include "stm32_hal_ll.h"
struct stick_pwm_input_t {
uint8_t channel;
uint8_t inverted;
};
struct stick_pwm_timer_t {
GPIO_TypeDef* GPIOx;
uint32_t GPIO_Pin;
uint32_t GPIO_Alternate;
TIM_TypeDef* TIMx;
IRQn_Type TIM_IRQn;
};
// returns 'true' if PWM sticks have been detected
bool sticksPwmDetect();
bool sticks_pwm_detect(const stick_pwm_timer_t* timer,
const stick_pwm_input_t* inputs,
uint8_t n_inputs);
void sticks_pwm_isr(const stick_pwm_timer_t* tim,
const stick_pwm_input_t* inputs,
uint8_t n_inputs);
@@ -26,7 +26,6 @@
struct stm32_adc_input_t {
const char* name;
GPIO_TypeDef* GPIOx;
uint32_t GPIO_Pin;
uint32_t ADC_Channel;
@@ -20,6 +20,7 @@
*/
#include "stm32_pulse_driver.h"
#include "stm32_timer.h"
#include "stm32_dma.h"
#include "definitions.h"
@@ -34,21 +35,6 @@
// - DMA IRQ prio configurable (now 7)
// - Timer IRQ prio configurable (now 7)
static void enable_tim_clock(TIM_TypeDef* TIMx)
{
if (TIMx == TIM1) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
} else if (TIMx == TIM2) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
} else if (TIMx == TIM3) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
} else if (TIMx == TIM4) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
} else if (TIMx == TIM8) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
}
}
void stm32_pulse_init(const stm32_pulse_timer_t* tim, uint32_t freq)
{
if (tim->DMA_TC_CallbackPtr) {
@@ -72,7 +58,7 @@ void stm32_pulse_init(const stm32_pulse_timer_t* tim, uint32_t freq)
timInit.Prescaler = __LL_TIM_CALC_PSC(tim->TIM_Freq, freq);
timInit.Autoreload = STM32_DEFAULT_TIMER_AUTORELOAD;
enable_tim_clock(tim->TIMx);
stm32_timer_enable_clock(tim->TIMx);
LL_TIM_Init(tim->TIMx, &timInit);
if (tim->DMAx) {
@@ -86,21 +72,6 @@ void stm32_pulse_init(const stm32_pulse_timer_t* tim, uint32_t freq)
NVIC_SetPriority(tim->TIM_IRQn, 7);
}
static void disable_tim_clock(TIM_TypeDef* TIMx)
{
if (TIMx == TIM1) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1);
} else if (TIMx == TIM2) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
} else if (TIMx == TIM3) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM3);
} else if (TIMx == TIM4) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM4);
} else if (TIMx == TIM8) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM8);
}
}
void stm32_pulse_deinit(const stm32_pulse_timer_t* tim)
{
// Disable IRQs
@@ -118,7 +89,7 @@ void stm32_pulse_deinit(const stm32_pulse_timer_t* tim)
}
LL_TIM_DeInit(tim->TIMx);
disable_tim_clock(tim->TIMx);
stm32_timer_disable_clock(tim->TIMx);
// Reconfigure pin as input
LL_GPIO_InitTypeDef pinInit;
@@ -0,0 +1,56 @@
/*
* 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_timer.h"
void stm32_timer_enable_clock(TIM_TypeDef *TIMx)
{
if (TIMx == TIM1) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
} else if (TIMx == TIM2) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
} else if (TIMx == TIM3) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
} else if (TIMx == TIM4) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
} else if (TIMx == TIM5) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM5);
} else if (TIMx == TIM8) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
}
}
void stm32_timer_disable_clock(TIM_TypeDef *TIMx)
{
if (TIMx == TIM1) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1);
} else if (TIMx == TIM2) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
} else if (TIMx == TIM3) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM3);
} else if (TIMx == TIM4) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM4);
} else if (TIMx == TIM5) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM5);
} else if (TIMx == TIM8) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM8);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include "stm32_hal_ll.h"
void stm32_timer_enable_clock(TIM_TypeDef *TIMx);
void stm32_timer_disable_clock(TIM_TypeDef *TIMx);
+2 -4
View File
@@ -24,6 +24,8 @@
#include "hal/switch_driver.h"
#include "hal/rotary_encoder.h"
#include "sticks_pwm_driver.h"
#include "board.h"
#include "boards/generic_stm32/module_ports.h"
#include "boards/generic_stm32/intmodule_heartbeat.h"
@@ -38,10 +40,6 @@
#include <string.h>
#if defined(PWM_STICKS)
#include "sticks_pwm_driver.h"
#endif
#if defined(RADIO_FAMILY_T16) || defined(PCBNV14)
#include "flysky_gimbal_driver.h"
#endif
+6 -2
View File
@@ -325,8 +325,8 @@
#define ADC_RCC_APB2Periph 0
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_0 // PA.00
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_1 // PA.01
#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_2 // PA.02
#define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_3 // PA.03
#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_2 // PA.02
#define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_0 // PC.00
#define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_1 // PC.01
#define ADC_GPIO_PIN_POT3 LL_GPIO_PIN_2 // PC.02 //
@@ -345,6 +345,10 @@
#define PWM_IRQHandler TIM5_IRQHandler
#define PWM_IRQn TIM5_IRQn
#define PWM_GPIOA_PINS (ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_RV)
#define STICK_PWM_CHANNEL_LH 0
#define STICK_PWM_CHANNEL_LV 1
#define STICK_PWM_CHANNEL_RV 3
#define STICK_PWM_CHANNEL_RH 2
#endif
#define ADC_GPIOA_PINS_FS (LL_GPIO_PIN_2 | LL_GPIO_PIN_3)
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_RV)
@@ -393,7 +397,7 @@
#elif defined(RADIO_TX16S)
#define ADC_DIRECTION {1,-1,1,-1, 1,1,1, -1,1,1,1, -1,1 }
#elif defined(PCBX10)
#define ADC_DIRECTION {1,-1,1,-1, -1,1,-1, 1,1,1,1, 1,-1 }
#define ADC_DIRECTION {1,-1,1,-1, -1,1,-1, 1,-1,1,1, 1,-1 }
#elif defined(PCBX12S)
#define ADC_DIRECTION {1,-1,1,-1, -1,1,-1, 1,-1, -1,-1, 0,0,0}
#else
+2 -10
View File
@@ -21,17 +21,16 @@
#include "hal/adc_driver.h"
#include "hal/switch_driver.h"
#include "hal/module_port.h"
#include "board.h"
#include "boards/generic_stm32/module_ports.h"
#include "boards/generic_stm32/intmodule_heartbeat.h"
#include "boards/generic_stm32/analog_inputs.h"
#include "debug.h"
#include "rtc.h"
#include "hal/adc_driver.h"
#include "hal/module_port.h"
#include "../common/arm/stm32/timers_driver.h"
#include "dataconstants.h"
@@ -47,10 +46,6 @@
#include "bluetooth_driver.h"
#endif
#if defined(PWM_STICKS)
#include "sticks_pwm_driver.h"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
@@ -70,9 +65,6 @@ bool UNEXPECTED_SHUTDOWN()
HardwareOptions hardwareOptions;
// adc_driver.cpp
extern const etx_hal_adc_driver_t _adc_driver;
void watchdogInit(unsigned int duration)
{
IWDG->KR = 0x5555; // Unlock registers
+15 -12
View File
@@ -1474,10 +1474,10 @@
#define ADC_RCC_AHB1Periph (RCC_AHB1Periph_DMA2)
#define ADC_RCC_APB1Periph RCC_APB1Periph_TIM5
#define ADC_RCC_APB2Periph 0
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_3 // PA.03
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_2 // PA.02
#define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_0 // PA.00
#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_1 // PA.01
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_2 // PA.02
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_3 // PA.03
#define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_1 // PC.01
#define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_2 // PC.02
#define ADC_GPIO_PIN_BATT LL_GPIO_PIN_0 // PC.00
@@ -1488,12 +1488,16 @@
#define PWM_IRQHandler TIM5_IRQHandler
#define PWM_IRQn TIM5_IRQn
#define PWM_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_LH)
#define STICK_PWM_CHANNEL_LH 3
#define STICK_PWM_CHANNEL_LV 2
#define STICK_PWM_CHANNEL_RV 0
#define STICK_PWM_CHANNEL_RH 1
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_LH)
#define ADC_GPIOC_PINS (ADC_GPIO_PIN_POT1 | ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_BATT)
#define ADC_CHANNEL_STICK_LH LL_ADC_CHANNEL_0 // ADC1_IN0
#define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_1 // ADC1_IN1
#define ADC_CHANNEL_STICK_RV LL_ADC_CHANNEL_3 // ADC1_IN3
#define ADC_CHANNEL_STICK_RH LL_ADC_CHANNEL_2 // ADC1_IN2
#define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_1 // ADC1_IN1
#define ADC_CHANNEL_STICK_LH LL_ADC_CHANNEL_0 // ADC1_IN0
#define ADC_CHANNEL_POT1 LL_ADC_CHANNEL_11 // ADC1_IN11
#define ADC_CHANNEL_POT2 LL_ADC_CHANNEL_12 // ADC1_IN12
#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_10 // ADC1_IN10
@@ -1521,10 +1525,10 @@
#define ADC_RCC_AHB1Periph (RCC_AHB1Periph_DMA2)
#define ADC_RCC_APB1Periph RCC_APB1Periph_TIM5
#define ADC_RCC_APB2Periph 0
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_1 // PA.01
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_0 // PA.00
#define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_2 // PA.02
#define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_3 // PA.03
#define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_0 // PA.00
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_1 // PA.01
#define ADC_CHANNEL_STICK_RV LL_ADC_CHANNEL_2 // ADC1_IN2
#define ADC_CHANNEL_STICK_RH LL_ADC_CHANNEL_3 // ADC1_IN3
#define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_0 // ADC1_IN0
@@ -1535,18 +1539,17 @@
#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_15
#define ADC_VREF_PREC2 320
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV)
#define PWM_IRQHandler TIM5_IRQHandler
#define PWM_STICKS
#define PWM_IRQHandler TIM5_IRQHandler
#define PWM_TIMER TIM5
#define PWM_GPIO GPIOA
#define PWM_GPIO_AF GPIO_AF_TIM5
#define PWM_IRQn TIM5_IRQn
#define PWM_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV)
#define STICK_CHANNEL_CHANGE
#define STICK_PWM_CHANNEL_0 1
#define STICK_PWM_CHANNEL_1 0
#define STICK_PWM_CHANNEL_2 2
#define STICK_PWM_CHANNEL_3 3
#define STICK_PWM_CHANNEL_LH 1
#define STICK_PWM_CHANNEL_LV 0
#define STICK_PWM_CHANNEL_RV 2
#define STICK_PWM_CHANNEL_RH 3
#elif defined(RADIO_TLITE) || defined(RADIO_LR3PRO)
#define ADC_RCC_AHB1Periph (RCC_AHB1Periph_DMA2)
#define ADC_RCC_APB1Periph 0
+6 -1
View File
@@ -224,8 +224,13 @@ class ADCInputParser:
def _add_input(self, adc_input):
if adc_input is not None:
idx = len(self.inputs)
if adc_input.type == 'STICK':
if 'PWM_STICKS' in self.hw_defs:
ch = self.hw_defs.get(f'STICK_PWM_CHANNEL_{adc_input.name}')
adc_input.pwm_channel = idx if ch is None else ch
if adc_input.type != 'VBAT' and adc_input.type != 'RTC_BAT':
d = self.dirs[len(self.inputs)]
d = self.dirs[idx]
if d < 0:
adc_input.inverted = True
if adc_input.type == 'POT':
@@ -6,7 +6,6 @@
static const stm32_adc_input_t _ADC_inputs[] = {
{% for input in adc_inputs.inputs %}
{
"{{ input.name }}",
// ADC_INPUT_{{ input.type }},
{{ input.gpio if input.gpio else 'nullptr' }},
{{ input.pin if input.gpio else '0' }},
+15
View File
@@ -0,0 +1,15 @@
//
// WARNING: DO NOT EDIT THIS FILE
// This file has been generated from the target's JSON hardware description
//
{% set pwm_inputs = adc_inputs.inputs | selectattr('pwm_channel', 'defined') | list %}
static const stick_pwm_input_t _PWM_inputs[] = {
{% for input in pwm_inputs %}
{
// ADC_INPUT_{{ input.type }}, {{ input.name }}
{{ input.pwm_channel }}, // channel
{{ '1 // inverted' if input.inverted else '0 // normal' }}
},
{% endfor %}
};