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:
@@ -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);
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' }},
|
||||
|
||||
@@ -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 %}
|
||||
};
|
||||
Reference in New Issue
Block a user