HAL/LL: Generic EXTI & trainer driver

Changes:
- generic EXTI driver
- generic trainer driver
- relocated rotary encoder timer (simple 100us delay) from TIM4 to TIM12
- taranis & horus use now TIM4 for trainer pulses
- serial driver handles periph clocks for UARTs

TODO:
- SBUS on heartbeat pin (USART or soft-serial)
This commit is contained in:
Raphael Coeffic
2022-12-10 13:37:31 +01:00
committed by Raphael Coeffic
parent d4cd3d0ddf
commit 042d5091f2
32 changed files with 896 additions and 1082 deletions
+2 -1
View File
@@ -20,6 +20,7 @@
*/
#include "opentx.h"
#include "hal/trainer_driver.h"
#define BIGSIZE MIDSIZE
#define LBOX_CENTERX (BOX_WIDTH/2 + 16)
@@ -262,7 +263,7 @@ void displayTopBar()
}
if (SLAVE_MODE()) {
if (TRAINER_CONNECTED()) {
if (is_trainer_connected()) {
LCD_NOTIF_ICON(x, ICON_TRAINEE);
x -= 12;
}
+47
View File
@@ -0,0 +1,47 @@
/*
* 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
// Startup init
void init_trainer();
// Output mode
void init_trainer_ppm();
void stop_trainer_ppm();
// Input mode
void init_trainer_capture();
void stop_trainer_capture();
// Cable inserted?
bool is_trainer_connected();
#if defined(TRAINER_MODULE_CPPM)
void init_trainer_module_cppm();
void stop_trainer_module_cppm();
#endif
#if defined(TRAINER_MODULE_SBUS)
void init_trainer_module_sbus();
void stop_trainer_module_sbus();
int trainerModuleSbusGetByte(uint8_t* byte);
#endif
-6
View File
@@ -2076,12 +2076,6 @@ uint32_t pwrCheck()
return e_power_usb;
}
#if defined(TRAINER_PWR)
if (TRAINER_CONNECTED()) {
return e_power_trainer;
}
#endif
if (!g_eeGeneral.disableRssiPoweroffAlarm) {
if (TELEMETRY_STREAMING()) {
RAISE_ALERT(STR_MODEL, STR_MODEL_STILL_POWERED, STR_PRESS_ENTER_TO_CONFIRM, AU_MODEL_STILL_POWERED);
@@ -84,6 +84,7 @@ set(BOOTLOADER_SRC
../usb_bsp.c
../usb_driver.cpp
../flash_driver.cpp
../stm32_exti_driver.cpp
init.c
boot.cpp
bin_files.cpp
@@ -217,15 +217,12 @@ void bootloaderInitApp()
RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph | LCD_RCC_APB1Periph |
BACKLIGHT_RCC_APB1Periph |
INTERRUPT_xMS_RCC_APB1Periph |
AUX_SERIAL_RCC_APB1Periph |
AUX2_SERIAL_RCC_APB1Periph | SD_RCC_APB1Periph,
INTERRUPT_xMS_RCC_APB1Periph | SD_RCC_APB1Periph,
ENABLE);
RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph |
RCC_APB2Periph_SYSCFG | AUX_SERIAL_RCC_APB2Periph |
AUX2_SERIAL_RCC_APB2Periph,
ENABLE);
RCC_APB2PeriphClockCmd(
LCD_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph | RCC_APB2Periph_SYSCFG,
ENABLE);
#if defined(HAVE_BOARD_BOOTLOADER_INIT)
boardBootloaderInit();
@@ -19,6 +19,7 @@
* GNU General Public License for more details.
*/
#include "stm32_exti_driver.h"
#include "mixer_scheduler.h"
#include "board.h"
#include "debug.h"
@@ -32,6 +33,17 @@
volatile HeartbeatCapture heartbeatCapture;
static void trigger_intmodule_heartbeat()
{
heartbeatCapture.timestamp = getTmr2MHz();
#if defined(DEBUG_LATENCY)
heartbeatCapture.count++;
#endif
mixerSchedulerResetTimer();
mixerSchedulerISRTrigger();
}
void init_intmodule_heartbeat()
{
TRACE("init_intmodule_heartbeat");
@@ -54,11 +66,7 @@ void init_intmodule_heartbeat()
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_SetPriority(INTMODULE_HEARTBEAT_EXTI_IRQn,
// Highest priority interrupt
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(INTMODULE_HEARTBEAT_EXTI_IRQn);
stm32_exti_enable(INTMODULE_HEARTBEAT_EXTI_LINE, trigger_intmodule_heartbeat);
heartbeatCapture.valid = true;
}
@@ -67,9 +75,7 @@ void stop_intmodule_heartbeat()
TRACE("stop_intmodule_heartbeat");
heartbeatCapture.valid = false;
#if !defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER)
NVIC_DisableIRQ(INTMODULE_HEARTBEAT_EXTI_IRQn);
#endif
stm32_exti_disable(INTMODULE_HEARTBEAT_EXTI_LINE);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
@@ -80,27 +86,4 @@ void stop_intmodule_heartbeat()
EXTI_Init(&EXTI_InitStructure);
}
void check_intmodule_heartbeat()
{
if (EXTI_GetITStatus(INTMODULE_HEARTBEAT_EXTI_LINE) != RESET) {
heartbeatCapture.timestamp = getTmr2MHz();
#if defined(DEBUG_LATENCY)
heartbeatCapture.count++;
#endif
EXTI_ClearITPendingBit(INTMODULE_HEARTBEAT_EXTI_LINE);
mixerSchedulerResetTimer();
mixerSchedulerISRTrigger();
}
}
#endif
#if defined(INTMODULE_HEARTBEAT) && !defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER)
extern "C" void INTMODULE_HEARTBEAT_EXTI_IRQHandler()
{
check_intmodule_heartbeat();
#if defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
check_telemetry_exti();
#endif
}
#endif
@@ -70,22 +70,11 @@ void pwrInit()
hardwareOptions.pcbrev = PCBREV_VALUE();
#endif
#if defined(TRAINER_DETECT_GPIO_PIN)
GPIO_InitStructure.GPIO_Pin = TRAINER_DETECT_GPIO_PIN;
GPIO_Init(TRAINER_DETECT_GPIO, &GPIO_InitStructure);
#endif
#if defined(SD_PRESENT_GPIO_PIN)
GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = SD_PRESENT_GPIO_PIN;
GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure);
#endif
#if defined(INTMODULE_USART) && defined(TRAINER_MODULE_CPPM)
GPIO_SetBits(TRAINER_MODULE_CPPM_GPIO, TRAINER_MODULE_CPPM_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = TRAINER_MODULE_CPPM_GPIO_PIN;
GPIO_Init(TRAINER_MODULE_CPPM_GPIO, &GPIO_InitStructure);
#endif
}
void pwrOn()
@@ -19,10 +19,11 @@
* GNU General Public License for more details.
*/
#include "stm32_exti_driver.h"
#include "board.h"
#include "hal.h"
#include "board_common.h"
#include "heartbeat_driver.h"
#if !defined(BOOT)
#include "opentx.h"
@@ -31,51 +32,6 @@
volatile rotenc_t rotencValue = 0;
volatile uint32_t rotencDt = 0;
void rotaryEncoderInit()
{
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;
SYSCFG_EXTILineConfig(ROTARY_ENCODER_EXTI_PortSource, ROTARY_ENCODER_EXTI_PinSource1);
#if defined(ROTARY_ENCODER_EXTI_LINE2)
SYSCFG_EXTILineConfig(ROTARY_ENCODER_EXTI_PortSource, ROTARY_ENCODER_EXTI_PinSource2);
#endif
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = ROTARY_ENCODER_EXTI_LINE1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
#if defined(ROTARY_ENCODER_EXTI_LINE2)
EXTI_InitStructure.EXTI_Line = ROTARY_ENCODER_EXTI_LINE2;
EXTI_Init(&EXTI_InitStructure);
#endif
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ROTARY_ENCODER_EXTI_IRQn1;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if defined(ROTARY_ENCODER_EXTI_IRQn2)
NVIC_InitStructure.NVIC_IRQChannel = ROTARY_ENCODER_EXTI_IRQn2;
NVIC_Init(&NVIC_InitStructure);
#endif
NVIC_EnableIRQ(ROTARY_ENCODER_TIMER_IRQn);
NVIC_SetPriority(ROTARY_ENCODER_TIMER_IRQn, 7);
}
#if defined(BOOT)
#define INC_ROT 1
#define INC_ROT_2 2
@@ -147,39 +103,39 @@ void rotaryEncoderStartDelay()
ROTARY_ENCODER_TIMER->CR1 = TIM_CR1_CEN | TIM_CR1_URS;
}
extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void)
void rotaryEncoderInit()
{
#if !defined(BOOT) && defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER)
check_telemetry_exti();
#endif
rotencPosition = ROTARY_ENCODER_POSITION();
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE1) != RESET) {
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE1);
}
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(ROTARY_ENCODER_EXTI_IRQn2)
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE2) != RESET) {
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE2);
}
#endif
SYSCFG_EXTILineConfig(ROTARY_ENCODER_EXTI_PortSource, ROTARY_ENCODER_EXTI_PinSource1);
SYSCFG_EXTILineConfig(ROTARY_ENCODER_EXTI_PortSource, ROTARY_ENCODER_EXTI_PinSource2);
#if !defined(BOOT) && defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER)
check_intmodule_heartbeat();
#endif
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = ROTARY_ENCODER_EXTI_LINE1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = ROTARY_ENCODER_EXTI_LINE2;
EXTI_Init(&EXTI_InitStructure);
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE1, rotaryEncoderStartDelay);
stm32_exti_enable(ROTARY_ENCODER_EXTI_LINE2, rotaryEncoderStartDelay);
NVIC_EnableIRQ(ROTARY_ENCODER_TIMER_IRQn);
NVIC_SetPriority(ROTARY_ENCODER_TIMER_IRQn, 7);
}
#if defined(ROTARY_ENCODER_EXTI_IRQn2)
extern "C" void ROTARY_ENCODER_EXTI_IRQHandler2(void)
{
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE2) != RESET) {
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE2);
}
}
#endif
extern "C" void ROTARY_ENCODER_TIMER_IRQHandler(void)
{
ROTARY_ENCODER_TIMER->SR &= ~TIM_SR_UIF;
@@ -0,0 +1,117 @@
/*
* 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_exti_driver.h"
#include "hal.h"
#define _EXTI_HANDLERS(irq_name) _handlers_ ## irq_name
#define _PR_MASK(first, last) (((1 << (last - first + 1))-1))
#define _DEFINE_EXTI_IRQ_HANDLER(irq_name, first, last) \
static stm32_exti_handler_t _EXTI_HANDLERS(irq_name) [last - first + 1] = { 0 }; \
extern "C" void irq_name ## Handler() \
{ \
/* Read Pending register */ \
/* (shifted by start line) */ \
uint32_t pr = LL_EXTI_ReadReg(PR) >> first; \
pr &= _PR_MASK(first,last); \
while (pr) { \
uint32_t i = POSITION_VAL(pr); \
/* Clear Pending Flag */ \
LL_EXTI_ClearFlag_0_31(1 << (first + i)); \
pr &= ~(1 << i); \
/* ... and trigger handler */ \
stm32_exti_handler_t h_fct = _EXTI_HANDLERS(irq_name) [i]; \
if (h_fct) h_fct(); \
} \
}
#define _SET_EXTI_IRQ_HANDLER(irq_name, first, last, line_pos, cb) \
if (line_pos >= first && line_pos <= last) { \
_EXTI_HANDLERS(irq_name)[line_pos - first] = cb; \
NVIC_SetPriority(irq_name ## n, irq_name ## _Priority); \
NVIC_EnableIRQ(irq_name ## n); \
return; \
}
#define _CLEAR_EXTI_IRQ_HANDLER(irq_name, first, last, line_pos) \
if (line_pos >= first && line_pos <= last) { \
_EXTI_HANDLERS(irq_name)[line_pos - first] = nullptr; \
if (!_has_handler(_EXTI_HANDLERS(irq_name), last - first + 1)) { \
NVIC_DisableIRQ(irq_name ## n); \
} \
return; \
}
#if defined(USE_EXTI1_IRQ)
_DEFINE_EXTI_IRQ_HANDLER(EXTI1_IRQ, 1, 1);
#endif
#if defined(USE_EXTI9_5_IRQ)
_DEFINE_EXTI_IRQ_HANDLER(EXTI9_5_IRQ, 5, 9);
#endif
#if defined(USE_EXTI15_10_IRQ)
_DEFINE_EXTI_IRQ_HANDLER(EXTI15_10_IRQ, 10, 15);
#endif
static bool _has_handler(stm32_exti_handler_t* _handlers, uint8_t len)
{
for (uint8_t i = 0; i < len; i++)
if (_handlers[i]) return true;
return false;
}
void stm32_exti_enable(uint32_t line, stm32_exti_handler_t cb)
{
uint32_t line_pos = POSITION_VAL(line);
#if defined(USE_EXTI1_IRQ)
_SET_EXTI_IRQ_HANDLER(EXTI1_IRQ, 1, 1, line_pos, cb);
#endif
#if defined(USE_EXTI9_5_IRQ)
_SET_EXTI_IRQ_HANDLER(EXTI9_5_IRQ, 5, 9, line_pos, cb);
#endif
#if defined(USE_EXTI15_10_IRQ)
_SET_EXTI_IRQ_HANDLER(EXTI15_10_IRQ, 10, 15, line_pos, cb);
#endif
}
void stm32_exti_disable(uint32_t line)
{
uint32_t line_pos = POSITION_VAL(line);
#if defined(USE_EXTI1_IRQ)
_CLEAR_EXTI_IRQ_HANDLER(EXTI1_IRQ, 1, 1, line_pos);
#endif
#if defined(USE_EXTI9_5_IRQ)
_CLEAR_EXTI_IRQ_HANDLER(EXTI9_5_IRQ, 5, 9, line_pos);
#endif
#if defined(USE_EXTI15_10_IRQ)
_CLEAR_EXTI_IRQ_HANDLER(EXTI15_10_IRQ, 10, 15, line_pos);
#endif
}
@@ -0,0 +1,40 @@
/*
* 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 <stdint.h>
// Prior to use this driver, please make sure the proper macros are defined in hal.h:
//
// - If 'USE_EXTIm_n_IRQ' is defined,
// 'EXTIm_n_IRQHandler' will be handled by this driver.
//
// - If 'USE_EXTIn_IRQ' is defined,
// 'EXTIn_IRQHandler' will be handled by this driver.
typedef void (*stm32_exti_handler_t)();
// Set callback and enable IRQ
void stm32_exti_enable(uint32_t line, stm32_exti_handler_t cb);
// Reset callback and disable IRQ if no more handlers
void stm32_exti_disable(uint32_t line);
@@ -22,6 +22,21 @@
#include "stm32_pulse_driver.h"
#include "definitions.h"
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)
{
LL_GPIO_InitTypeDef pinInit;
@@ -37,33 +52,56 @@ void stm32_pulse_init(const stm32_pulse_timer_t* tim)
// 0.5uS (2Mhz)
timInit.Prescaler = tim->TIM_Prescaler;
timInit.Autoreload = 65535;
enable_tim_clock(tim->TIMx);
LL_TIM_Init(tim->TIMx, &timInit);
// Enable DMA IRQ
NVIC_EnableIRQ(tim->DMA_IRQn);
NVIC_SetPriority(tim->DMA_IRQn, 7);
if (tim->DMAx) {
// Enable DMA IRQ
NVIC_EnableIRQ(tim->DMA_IRQn);
NVIC_SetPriority(tim->DMA_IRQn, 7);
}
// Enable timer IRQ
NVIC_EnableIRQ(tim->TIM_IRQn);
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
NVIC_DisableIRQ(tim->DMA_IRQn);
if (tim->DMAx) {
NVIC_DisableIRQ(tim->DMA_IRQn);
}
NVIC_DisableIRQ(tim->TIM_IRQn);
// De-init DMA & timer
LL_DMA_DeInit(tim->DMAx, tim->DMA_Stream);
LL_TIM_DeInit(tim->TIMx);
// Reconfigure pin as output
if (tim->DMAx) {
LL_DMA_DeInit(tim->DMAx, tim->DMA_Stream);
}
LL_TIM_DeInit(tim->TIMx);
disable_tim_clock(tim->TIMx);
// Reconfigure pin as input
LL_GPIO_InitTypeDef pinInit;
LL_GPIO_StructInit(&pinInit);
pinInit.Pin = tim->GPIO_Pin;
pinInit.Mode = LL_GPIO_MODE_OUTPUT;
pinInit.Mode = LL_GPIO_MODE_INPUT;
LL_GPIO_Init(tim->GPIOx, &pinInit);
}
@@ -140,9 +178,15 @@ static void set_compare_reg(const stm32_pulse_timer_t* tim, uint32_t val)
case LL_TIM_CHANNEL_CH1N:
LL_TIM_OC_SetCompareCH1(tim->TIMx, val);
break;
case LL_TIM_CHANNEL_CH2:
LL_TIM_OC_SetCompareCH2(tim->TIMx, val);
break;
case LL_TIM_CHANNEL_CH3:
LL_TIM_OC_SetCompareCH3(tim->TIMx, val);
break;
case LL_TIM_CHANNEL_CH4:
LL_TIM_OC_SetCompareCH4(tim->TIMx, val);
break;
}
}
@@ -267,3 +311,13 @@ void stm32_pulse_tim_update_isr(const stm32_pulse_timer_t* tim)
// Halt pulses by forcing to inactive level
set_oc_mode(tim, LL_TIM_OCMODE_FORCED_INACTIVE);
}
// input mode
void stm32_pulse_config_input(const stm32_pulse_timer_t* tim)
{
LL_TIM_IC_InitTypeDef icInit;
LL_TIM_IC_StructInit(&icInit);
icInit.ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
icInit.ICFilter = LL_TIM_IC_FILTER_FDIV1_N8;
LL_TIM_IC_Init(tim->TIMx, tim->TIM_Channel, &icInit);
}
@@ -44,6 +44,8 @@ struct stm32_pulse_timer_t {
void stm32_pulse_init(const stm32_pulse_timer_t* tim);
void stm32_pulse_deinit(const stm32_pulse_timer_t* tim);
void stm32_pulse_config_input(const stm32_pulse_timer_t* tim);
void stm32_pulse_config_output(const stm32_pulse_timer_t* tim, bool polarity,
uint32_t ocmode, uint32_t cmp_val);
@@ -64,7 +66,8 @@ void stm32_pulse_tim_update_isr(const stm32_pulse_timer_t* tim);
#define __STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(ch) \
((ch) == LL_TIM_CHANNEL_CH1 || (ch) == LL_TIM_CHANNEL_CH1N || \
(ch) == LL_TIM_CHANNEL_CH3)
(ch) == LL_TIM_CHANNEL_CH2 || (ch) == LL_TIM_CHANNEL_CH3 || \
(ch) == LL_TIM_CHANNEL_CH4)
#define __STM32_PULSE_IS_DMA_STREAM_SUPPORTED(stream) \
((stream) == LL_DMA_STREAM_1 || (stream) == LL_DMA_STREAM_5 || \
@@ -22,6 +22,46 @@
#include "stm32_usart_driver.h"
#include <string.h>
static void enable_usart_clock(USART_TypeDef* USARTx)
{
if (USARTx == USART1) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
} else if (USARTx == USART2) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
} else if (USARTx == USART3) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);
} else if (USARTx == UART4) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART4);
} else if (USARTx == USART6) {
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART6);
}
#if defined(UART7) // does not exist on F2
else if (USARTx == UART7) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART7);
}
#endif
}
static void disable_usart_clock(USART_TypeDef* USARTx)
{
if (USARTx == USART1) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_USART1);
} else if (USARTx == USART2) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_USART2);
} else if (USARTx == USART3) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_USART3);
} else if (USARTx == UART4) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_UART4);
} else if (USARTx == USART6) {
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_USART6);
}
#if defined(UART7) // does not exist on F2
else if (USARTx == UART7) {
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_UART7);
}
#endif
}
void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length)
{
if (!usart->rxDMA) return;
@@ -67,6 +107,7 @@ void stm32_usart_deinit_rx_dma(const stm32_usart_t* usart)
void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params)
{
enable_usart_clock(usart->USARTx);
LL_USART_DeInit(usart->USARTx);
LL_GPIO_Init(usart->GPIOx, (LL_GPIO_InitTypeDef*)usart->pinInit);
@@ -142,6 +183,7 @@ void stm32_usart_deinit(const stm32_usart_t* usart)
}
NVIC_DisableIRQ(usart->IRQn);
LL_USART_DeInit(usart->USARTx);
disable_usart_clock(usart->USARTx);
// Reconfigure pin as output
LL_GPIO_InitTypeDef pinInit;
@@ -0,0 +1,340 @@
/*
* 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_pulse_driver.h"
#include "hal/trainer_driver.h"
#include "hal.h"
#include "opentx.h"
#define __IS_TRAINER_TIMER_OUT_CHANNEL_SUPPORTED(ch) \
(((ch) == LL_TIM_CHANNEL_CH1 || (ch) == LL_TIM_CHANNEL_CH2 || \
(ch) == LL_TIM_CHANNEL_CH3 || (ch) == LL_TIM_CHANNEL_CH4) && \
__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(ch))
#define __IS_TRAINER_TIMER_IN_CHANNEL_SUPPORTED(ch) \
((ch) == LL_TIM_CHANNEL_CH1 || (ch) == LL_TIM_CHANNEL_CH2 || \
(ch) == LL_TIM_CHANNEL_CH3 || (ch) == LL_TIM_CHANNEL_CH4)
#if defined(TRAINER_GPIO)
static_assert(__IS_TRAINER_TIMER_OUT_CHANNEL_SUPPORTED(TRAINER_OUT_TIMER_Channel),
"Unsupported trainer timer output channel");
static_assert(__IS_TRAINER_TIMER_IN_CHANNEL_SUPPORTED(TRAINER_IN_TIMER_Channel),
"Unsupported trainer timer input channel");
#else
void init_trainer_ppm() {}
void stop_trainer_ppm() {}
void init_trainer_capture() {}
void stop_trainer_capture() {}
#endif
static void (*_trainer_timer_isr)();
static const stm32_pulse_timer_t* _trainer_timer;
void init_trainer()
{
#if defined(TRAINER_DETECT_GPIO_PIN)
LL_GPIO_InitTypeDef pinInit;
LL_GPIO_StructInit(&pinInit);
pinInit.Pin = TRAINER_DETECT_GPIO_PIN;
pinInit.Mode = LL_GPIO_MODE_INPUT;
pinInit.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(TRAINER_DETECT_GPIO, &pinInit);
#endif
_trainer_timer = nullptr;
_trainer_timer_isr = nullptr;
}
static inline bool trainer_check_isr_flag(const stm32_pulse_timer_t* tim)
{
switch (tim->TIM_Channel) {
case LL_TIM_CHANNEL_CH1:
if (LL_TIM_IsEnabledIT_CC1(tim->TIMx) &&
LL_TIM_IsActiveFlag_CC1(tim->TIMx)) {
LL_TIM_ClearFlag_CC1(tim->TIMx);
return true;
}
break;
case LL_TIM_CHANNEL_CH2:
if (LL_TIM_IsEnabledIT_CC2(tim->TIMx) &&
LL_TIM_IsActiveFlag_CC2(tim->TIMx)) {
LL_TIM_ClearFlag_CC2(tim->TIMx);
return true;
}
break;
case LL_TIM_CHANNEL_CH3:
if (LL_TIM_IsEnabledIT_CC3(tim->TIMx) &&
LL_TIM_IsActiveFlag_CC3(tim->TIMx)) {
LL_TIM_ClearFlag_CC3(tim->TIMx);
return true;
}
break;
case LL_TIM_CHANNEL_CH4:
if (LL_TIM_IsEnabledIT_CC4(tim->TIMx) &&
LL_TIM_IsActiveFlag_CC4(tim->TIMx)) {
LL_TIM_ClearFlag_CC4(tim->TIMx);
return true;
}
break;
}
return false;
}
static void trainer_in_isr()
{
// proceed only if the channel flag was set
// and the IRQ was enabled
if (!trainer_check_isr_flag(_trainer_timer))
return;
uint16_t capture = 0;
switch(_trainer_timer->TIM_Channel) {
case LL_TIM_CHANNEL_CH1:
capture = LL_TIM_IC_GetCaptureCH1(_trainer_timer->TIMx);
break;
case LL_TIM_CHANNEL_CH2:
capture = LL_TIM_IC_GetCaptureCH2(_trainer_timer->TIMx);
break;
case LL_TIM_CHANNEL_CH3:
capture = LL_TIM_IC_GetCaptureCH3(_trainer_timer->TIMx);
break;
case LL_TIM_CHANNEL_CH4:
capture = LL_TIM_IC_GetCaptureCH4(_trainer_timer->TIMx);
break;
default:
return;
}
captureTrainerPulses(capture);
}
static void _stop_trainer(const stm32_pulse_timer_t* tim)
{
stm32_pulse_deinit(tim);
_trainer_timer_isr = nullptr;
_trainer_timer = nullptr;
}
static void _init_trainer_capture(const stm32_pulse_timer_t* tim)
{
// set proper ISR handler first
_trainer_timer = tim;
_trainer_timer_isr = trainer_in_isr;
stm32_pulse_init(tim);
stm32_pulse_config_input(tim);
switch (tim->TIM_Channel) {
case LL_TIM_CHANNEL_CH1:
LL_TIM_EnableIT_CC1(tim->TIMx);
break;
case LL_TIM_CHANNEL_CH2:
LL_TIM_EnableIT_CC2(tim->TIMx);
break;
case LL_TIM_CHANNEL_CH3:
LL_TIM_EnableIT_CC1(tim->TIMx);
break;
case LL_TIM_CHANNEL_CH4:
LL_TIM_EnableIT_CC2(tim->TIMx);
break;
}
LL_TIM_EnableCounter(tim->TIMx);
}
#if defined(TRAINER_GPIO)
static const stm32_pulse_timer_t trainerOutputTimer = {
.GPIOx = TRAINER_GPIO,
.GPIO_Pin = TRAINER_OUT_GPIO_PIN,
.GPIO_Alternate = TRAINER_GPIO_AF,
.TIMx = TRAINER_TIMER,
.TIM_Prescaler = __LL_TIM_CALC_PSC(TRAINER_TIMER_FREQ, 2000000),
.TIM_Channel = TRAINER_OUT_TIMER_Channel,
.TIM_IRQn = TRAINER_TIMER_IRQn,
.DMAx = nullptr,
.DMA_Stream = 0,
.DMA_Channel = 0,
.DMA_IRQn = (IRQn_Type)0,
};
static void trainerSendNextFrame()
{
stm32_pulse_set_polarity(&trainerOutputTimer, GET_TRAINER_PPM_POLARITY());
// load the first period: next reload when CC compare event triggers
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->ARR = *(trainerPulsesData.ppm.ptr++);
switch (trainerOutputTimer.TIM_Channel) {
case LL_TIM_CHANNEL_CH1:
LL_TIM_EnableIT_CC1(trainerOutputTimer.TIMx);
break;
case LL_TIM_CHANNEL_CH2:
LL_TIM_EnableIT_CC2(trainerOutputTimer.TIMx);
break;
case LL_TIM_CHANNEL_CH3:
LL_TIM_EnableIT_CC3(trainerOutputTimer.TIMx);
break;
case LL_TIM_CHANNEL_CH4:
LL_TIM_EnableIT_CC4(trainerOutputTimer.TIMx);
break;
}
}
static void trainer_out_isr()
{
// proceed only if the channel flag was set
// and the IRQ was enabled
if (!trainer_check_isr_flag(_trainer_timer))
return;
if (*trainerPulsesData.ppm.ptr) {
// load next period
LL_TIM_SetAutoReload(_trainer_timer->TIMx,
*(trainerPulsesData.ppm.ptr++));
} else {
setupPulsesPPMTrainer();
trainerSendNextFrame();
}
}
void init_trainer_ppm()
{
// set proper ISR handler first
_trainer_timer = &trainerOutputTimer;
_trainer_timer_isr = trainer_out_isr;
stm32_pulse_init(&trainerOutputTimer);
stm32_pulse_config_output(&trainerOutputTimer, GET_TRAINER_PPM_POLARITY(),
LL_TIM_OCMODE_PWM1, GET_TRAINER_PPM_DELAY() * 2);
setupPulsesPPMTrainer();
trainerSendNextFrame();
LL_TIM_EnableCounter(trainerOutputTimer.TIMx);
}
void stop_trainer_ppm()
{
_stop_trainer(&trainerOutputTimer);
}
static const stm32_pulse_timer_t trainerInputTimer = {
.GPIOx = TRAINER_GPIO,
.GPIO_Pin = TRAINER_IN_GPIO_PIN,
.GPIO_Alternate = TRAINER_GPIO_AF,
.TIMx = TRAINER_TIMER,
.TIM_Prescaler = __LL_TIM_CALC_PSC(TRAINER_TIMER_FREQ, 2000000),
.TIM_Channel = TRAINER_IN_TIMER_Channel,
.TIM_IRQn = TRAINER_TIMER_IRQn,
.DMAx = nullptr,
.DMA_Stream = 0,
.DMA_Channel = 0,
.DMA_IRQn = (IRQn_Type)0,
};
void init_trainer_capture()
{
_init_trainer_capture(&trainerInputTimer);
}
void stop_trainer_capture()
{
_stop_trainer(&trainerInputTimer);
}
#endif // TRAINER_GPIO
bool is_trainer_connected()
{
#if defined(TRAINER_DETECT_GPIO_PIN)
bool set = LL_GPIO_IsInputPinSet(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN);
#if defined(TRAINER_DETECT_INVERTED)
return !set;
#else
return set;
#endif
#else // TRAINER_DETECT_GPIO_PIN
return true;
#endif
}
#if defined(TRAINER_GPIO) || (defined(TRAINER_MODULE_CPPM) && \
!defined(TRAINER_MODULE_CPPM_TIMER_IRQHandler))
#if !defined(TRAINER_TIMER_IRQHandler)
#error "Missing TRAINER_TIMER_IRQHandler definition"
#endif
extern "C" void TRAINER_TIMER_IRQHandler()
{
DEBUG_INTERRUPT(INT_TRAINER);
if (_trainer_timer && _trainer_timer_isr)
_trainer_timer_isr();
}
#endif
#if defined(TRAINER_MODULE_CPPM)
static_assert(__IS_TRAINER_TIMER_IN_CHANNEL_SUPPORTED(TRAINER_MODULE_CPPM_TIMER_Channel),
"Unsupported trainer timer input channel");
static const stm32_pulse_timer_t trainerModuleTimer = {
.GPIOx = TRAINER_MODULE_CPPM_GPIO,
.GPIO_Pin = TRAINER_MODULE_CPPM_GPIO_PIN,
.GPIO_Alternate = TRAINER_MODULE_CPPM_GPIO_AF,
.TIMx = TRAINER_MODULE_CPPM_TIMER,
.TIM_Prescaler = __LL_TIM_CALC_PSC(TRAINER_MODULE_CCPM_FREQ, 2000000),
.TIM_Channel = TRAINER_MODULE_CPPM_TIMER_Channel,
.TIM_IRQn = TRAINER_MODULE_CPPM_TIMER_IRQn,
.DMAx = nullptr,
.DMA_Stream = 0,
.DMA_Channel = 0,
.DMA_IRQn = (IRQn_Type)0,
};
void init_trainer_module_cppm()
{
_init_trainer_capture(&trainerModuleTimer);
}
void stop_trainer_module_cppm()
{
_stop_trainer(&trainerModuleTimer);
}
#if defined(TRAINER_MODULE_CPPM_TIMER_IRQHandler)
extern "C" void TRAINER_MODULE_CPPM_TIMER_IRQHandler()
{
DEBUG_INTERRUPT(INT_TRAINER);
if (_trainer_timer && _trainer_timer_isr)
_trainer_timer_isr();
}
#endif
#endif // TRAINER_MODULE_CPPM
+2 -1
View File
@@ -288,7 +288,6 @@ set(FIRMWARE_TARGET_SRC
board.cpp
backlight_driver.cpp
led_driver.cpp
trainer_driver.cpp
sdram_driver.c
startup_stm32f42_43xxx.s
)
@@ -296,6 +295,7 @@ set(FIRMWARE_TARGET_SRC
set(FIRMWARE_SRC
${FIRMWARE_SRC}
hal/adc_driver.cpp
targets/common/arm/stm32/stm32_exti_driver.cpp
targets/common/arm/stm32/mixer_scheduler_driver.cpp
targets/common/arm/stm32/timers_driver.cpp
targets/common/arm/stm32/intmodule_serial_driver.cpp
@@ -306,6 +306,7 @@ set(FIRMWARE_SRC
targets/common/arm/stm32/rotary_encoder_driver.cpp
targets/common/arm/stm32/pwr_driver.cpp
targets/common/arm/stm32/heartbeat_driver.cpp
targets/common/arm/stm32/trainer_driver.cpp
targets/common/arm/stm32/sdio_sd.c
)
+2 -9
View File
@@ -23,6 +23,7 @@
#include "hal/adc_driver.h"
#include "hal/serial_driver.h"
#include "hal/serial_port.h"
#include "hal/trainer_driver.h"
#include "board.h"
#include "timers_driver.h"
@@ -133,13 +134,8 @@ void boardInit()
#if defined(RADIO_FAMILY_T16)
FLYSKY_HALL_RCC_APB1Periph |
#endif
AUX_SERIAL_RCC_APB1Periph |
AUX2_SERIAL_RCC_APB1Periph |
TELEMETRY_RCC_APB1Periph |
TRAINER_RCC_APB1Periph |
AUDIO_RCC_APB1Periph |
INTMODULE_RCC_APB1Periph |
EXTMODULE_RCC_APB1Periph |
MIXER_SCHEDULER_TIMER_RCC_APB1Periph |
BACKLIGHT_RCC_APB1Periph,
ENABLE);
@@ -148,12 +144,8 @@ void boardInit()
LCD_RCC_APB2Periph |
ADC_RCC_APB2Periph |
HAPTIC_RCC_APB2Periph |
INTMODULE_RCC_APB2Periph |
EXTMODULE_RCC_APB2Periph |
TELEMETRY_RCC_APB2Periph |
BT_RCC_APB2Periph |
AUX_SERIAL_RCC_APB2Periph |
AUX2_SERIAL_RCC_APB2Periph |
BACKLIGHT_RCC_APB2Periph,
ENABLE);
@@ -168,6 +160,7 @@ void boardInit()
#endif
pwrInit();
init_trainer();
pwrOn();
delaysInit();
-12
View File
@@ -67,12 +67,6 @@ extern uint16_t sessionTimer;
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
#if defined(PCBX10) && !defined(RADIO_FAMILY_T16)
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET)
#else
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET)
#endif
// Board driver
void boardInit();
void boardOff();
@@ -189,12 +183,6 @@ void SDRAM_Init();
#define IS_PXX1_INTERNAL_ENABLED() (true)
#endif
// Trainer driver
void init_trainer_ppm();
void stop_trainer_ppm();
void init_trainer_capture();
void stop_trainer_capture();
// Keys driver
enum EnumKeys
{
+39 -36
View File
@@ -76,21 +76,23 @@
#endif
// Rotary Encoder
#define ROTARY_ENCODER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define ROTARY_ENCODER_RCC_APB1Periph RCC_APB1Periph_TIM12
#define ROTARY_ENCODER_GPIO GPIOH
#define ROTARY_ENCODER_GPIO_PIN_A GPIO_Pin_11 // PH.11
#define ROTARY_ENCODER_GPIO_PIN_B GPIO_Pin_10 // PH.10
#define ROTARY_ENCODER_POSITION() ((ROTARY_ENCODER_GPIO->IDR >> 10) & 0x03)
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line11
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line10
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI15_10_IRQHandler
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOH
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource11
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource10
#define ROTARY_ENCODER_TIMER TIM4
#define ROTARY_ENCODER_TIMER_IRQn TIM4_IRQn
#define ROTARY_ENCODER_TIMER_IRQHandler TIM4_IRQHandler
#define ROTARY_ENCODER_TIMER TIM12
#define ROTARY_ENCODER_TIMER_IRQn TIM8_BRK_TIM12_IRQn
#define ROTARY_ENCODER_TIMER_IRQHandler TIM8_BRK_TIM12_IRQHandler
#if defined(RADIO_FAMILY_T16) && !defined(RADIO_T18)
#define ROTARY_ENCODER_SUPPORT_BUGGY_WIRING
@@ -422,8 +424,6 @@
// Serial Port (DEBUG)
#if defined(AUX_SERIAL)
#define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3
#define AUX_SERIAL_RCC_APB2Periph 0
#define AUX_SERIAL_GPIO GPIOB
#define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10
#define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11
@@ -444,15 +444,11 @@
#endif
#else
#define AUX_SERIAL_RCC_AHB1Periph 0
#define AUX_SERIAL_RCC_APB1Periph 0
#define AUX_SERIAL_RCC_APB2Periph 0
#endif
#if defined(AUX2_SERIAL)
#if defined(PCBX12S)
#define AUX2_SERIAL_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
#define AUX2_SERIAL_RCC_APB1Periph RCC_APB1Periph_UART4
#define AUX2_SERIAL_RCC_APB2Periph 0
#define AUX2_SERIAL_USART UART4
#define AUX2_SERIAL_GPIO_AF GPIO_AF_UART4
#define AUX2_SERIAL_GPIO_AF_LL LL_GPIO_AF_8
@@ -469,8 +465,6 @@
#define AUX2_SERIAL_DMA_Stream_RX_LL LL_DMA_STREAM_2
#else
#define AUX2_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_DMA2)
#define AUX2_SERIAL_RCC_APB1Periph 0
#define AUX2_SERIAL_RCC_APB2Periph RCC_APB2Periph_USART6
#define AUX2_SERIAL_USART USART6
#define AUX2_SERIAL_GPIO_AF GPIO_AF_USART6
#define AUX2_SERIAL_GPIO_AF_LL LL_GPIO_AF_8
@@ -490,8 +484,6 @@
#endif
#else // AUX2_SERIAL
#define AUX2_SERIAL_RCC_AHB1Periph 0
#define AUX2_SERIAL_RCC_APB1Periph 0
#define AUX2_SERIAL_RCC_APB2Periph 0
#endif
// Telemetry
@@ -845,8 +837,6 @@
#define INTMODULE_BOOTCMD_GPIO_PIN GPIO_Pin_9 // PI.09
#endif
#define INIT_INTMODULE_BOOTCMD_PIN() GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN);
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1
// External Module
#define EXTMODULE_PWR_GPIO GPIOB
@@ -854,8 +844,6 @@
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#if (defined(PCBX10) && defined(PCBREV_EXPRESS)) || defined(HARDWARE_EXTERNAL_ACCESS_MOD)
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define EXTMODULE_RCC_APB1Periph (RCC_APB1Periph_TIM2 | RCC_APB1Periph_USART3)
#define EXTMODULE_RCC_APB2Periph 0
#define EXTMODULE_TX_GPIO GPIOB
#define EXTMODULE_USART_GPIO EXTMODULE_TX_GPIO
#define EXTMODULE_TX_GPIO_PIN LL_GPIO_PIN_10 // PB.10 (TIM2_CH3)
@@ -889,8 +877,6 @@
#define EXTMODULE_USART_RX_DMA_STREAM DMA1_Stream1
#elif defined(PCBX10) || PCBREV >= 13
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define EXTMODULE_RCC_APB1Periph 0
#define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1
#define EXTMODULE_TX_GPIO GPIOA
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_10 // PA.10 (TIM1_CH3)
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource10
@@ -910,8 +896,6 @@
#define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF5
#else
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2
#define EXTMODULE_RCC_APB2Periph 0
#define EXTMODULE_TX_GPIO GPIOA
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_15 // PA.15 (TIM2_CH1)
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource15
@@ -936,12 +920,15 @@
#define INTMODULE_HEARTBEAT
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define INTMODULE_HEARTBEAT_GPIO GPIOD
#define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_12 // PD.12
#define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_12 // PD.12 / TIM4_CH1
#define INTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOD
#define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource12
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line12
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn
#define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER
#if defined(INTERNAL_MODULE_PXX2)
#define INTMODULE_HEARTBEAT_TRIGGER EXTI_Trigger_Falling
@@ -951,22 +938,38 @@
// Trainer Port
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA1)
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_GPIO GPIOC
#define TRAINER_IN_GPIO_PIN GPIO_Pin_6 // PC.06
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource6
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_7 // PC.07
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource7
#define TRAINER_IN_GPIO_PIN LL_GPIO_PIN_6 // PC.06
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH1
#define TRAINER_OUT_GPIO_PIN LL_GPIO_PIN_7 // PC.07
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_DETECT_GPIO GPIOB
#define TRAINER_DETECT_GPIO_PIN GPIO_Pin_4 // PB.04
#define TRAINER_DETECT_GPIO_PIN LL_GPIO_PIN_4 // PB.04
#if !defined(PCBX10) || defined(RADIO_FAMILY_T16)
#define TRAINER_DETECT_INVERTED
#endif
#define TRAINER_TIMER TIM3
#define TRAINER_TIMER_IRQn TIM3_IRQn
#define TRAINER_TIMER_IRQHandler TIM3_IRQHandler
#define TRAINER_GPIO_AF GPIO_AF_TIM3
#define TRAINER_DMA DMA1
#define TRAINER_DMA_CHANNEL DMA_Channel_5
#define TRAINER_GPIO_AF LL_GPIO_AF_2
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
// Trainer CPPM input on heartbeat pin
#define TRAINER_MODULE_CPPM
#define TRAINER_MODULE_CPPM_TIMER TIM4
#define TRAINER_MODULE_CCPM_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_MODULE_CPPM_GPIO INTMODULE_HEARTBEAT_GPIO
#define TRAINER_MODULE_CPPM_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN
#define TRAINER_MODULE_CPPM_TIMER_Channel LL_TIM_CHANNEL_CH1
#define TRAINER_MODULE_CPPM_TIMER_IRQn TIM4_IRQn
#define TRAINER_MODULE_CPPM_TIMER_IRQHandler TIM4_IRQHandler
#define TRAINER_MODULE_CPPM_GPIO_AF LL_GPIO_AF_2
// Xms Interrupt
#define INTERRUPT_xMS_RCC_APB1Periph RCC_APB1Periph_TIM14
#define INTERRUPT_xMS_TIMER TIM14
-144
View File
@@ -1,144 +0,0 @@
/*
* 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 "opentx.h"
#include "aux_serial_driver.h"
void trainerSendNextFrame();
void init_trainer_ppm()
{
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_OUT_GPIO_PinSource, TRAINER_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_OUT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->ARR = 45000;
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_0; // Force O/P high
TRAINER_TIMER->BDTR = TIM_BDTR_MOE;
TRAINER_TIMER->EGR = 1;
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
TRAINER_TIMER->CR1 |= TIM_CR1_CEN;
setupPulsesPPMTrainer();
trainerSendNextFrame();
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_ppm()
{
NVIC_DisableIRQ(TRAINER_TIMER_IRQn);
TRAINER_TIMER->DIER = 0; // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
}
void init_trainer_capture()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_IN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF);
TRAINER_TIMER->ARR = 0xFFFF;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->CR2 = 0;
TRAINER_TIMER->CCMR1 = TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_CC1S_0;
TRAINER_TIMER->CCER = TIM_CCER_CC1E;
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE;
TRAINER_TIMER->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_capture()
{
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
TRAINER_TIMER->DIER = 0; // Stop Interrupt
}
void trainerSendNextFrame()
{
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
// load the first period: next reload when CCR2 compare event triggers
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->ARR = *(trainerPulsesData.ppm.ptr++);
TRAINER_TIMER->DIER |= TIM_DIER_CC2IE;
}
extern "C" void TRAINER_TIMER_IRQHandler()
{
DEBUG_INTERRUPT(INT_TRAINER);
uint16_t capture = 0;
bool doCapture = false;
// What mode? in or out?
if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) {
// capture mode on trainer jack
capture = TRAINER_TIMER->CCR1;
if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) {
doCapture = true;
}
}
if (doCapture) {
captureTrainerPulses(capture);
}
// PPM out compare interrupt
if ((TRAINER_TIMER->DIER & TIM_DIER_CC2IE) && (TRAINER_TIMER->SR & TIM_SR_CC2IF)) {
// compare interrupt
TRAINER_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
if (*trainerPulsesData.ppm.ptr) {
// load next period
TRAINER_TIMER->ARR = *(trainerPulsesData.ppm.ptr++);
} else {
setupPulsesPPMTrainer();
trainerSendNextFrame();
}
}
}
+1 -1
View File
@@ -139,7 +139,6 @@ set(FIRMWARE_TARGET_SRC
${LCD_DRIVER}
${TOUCH_DRIVER}
sdram_driver.c
trainer_driver.cpp
battery_driver.cpp
audio_spi_driver.cpp
backlight_driver.cpp
@@ -158,6 +157,7 @@ set(FIRMWARE_SRC
targets/common/arm/stm32/extmodule_serial_driver.cpp
targets/common/arm/stm32/intmodule_serial_driver.cpp
targets/common/arm/stm32/stm32_usart_driver.cpp
targets/common/arm/stm32/trainer_driver.cpp
targets/common/arm/stm32/pwr_driver.cpp
targets/common/arm/stm32/sdio_sd.c
)
+3 -8
View File
@@ -26,6 +26,7 @@
#include "debug.h"
#include "hal/adc_driver.h"
#include "hal/trainer_driver.h"
#include "stm32_hal_adc.h"
#include "timers_driver.h"
@@ -95,21 +96,14 @@ void delay_self(int count)
)
#define RCC_APB1PeriphOther (TELEMETRY_RCC_APB1Periph |\
TRAINER_RCC_APB1Periph |\
INTMODULE_RCC_APB1Periph |\
FLYSKY_HALL_RCC_APB1Periph |\
EXTMODULE_RCC_APB1Periph |\
INTMODULE_RCC_APB1Periph |\
AUX_SERIAL_RCC_APB1Periph |\
MIXER_SCHEDULER_TIMER_RCC_APB1Periph \
)
#define RCC_APB2PeriphMinimum (LCD_RCC_APB2Periph)
#define RCC_APB2PeriphOther (ADC_RCC_APB2Periph |\
HAPTIC_RCC_APB2Periph |\
AUX_SERIAL_RCC_APB2Periph |\
AUDIO_RCC_APB2Periph |\
EXTMODULE_RCC_APB2Periph \
AUDIO_RCC_APB2Periph \
)
static uint8_t boardGetPcbRev()
@@ -180,6 +174,7 @@ void boardInit()
TRACE("RCC->CSR = %08x", RCC->CSR);
pwrInit();
init_trainer();
extModuleInit();
battery_charge_init();
globalData.flyskygimbals = true;
-7
View File
@@ -51,7 +51,6 @@
extern uint16_t sessionTimer;
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
#define TRAINER_CONNECTED() (true)
// initilizes the board for the bootloader
#define HAVE_BOARD_BOOTLOADER_INIT 1
@@ -161,12 +160,6 @@ void EXTERNAL_MODULE_OFF();
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
#define IS_PXX2_INTERNAL_ENABLED() (false)
// Trainer driver
void init_trainer_ppm();
void stop_trainer_ppm();
void init_trainer_capture();
void stop_trainer_capture();
// Keys driver
enum EnumKeys
{
+7 -26
View File
@@ -182,8 +182,6 @@
// Serial Port (DEBUG)
// We will temporarily used the PPM and the HEARTBEAT PINS
#define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE)
#define AUX_SERIAL_RCC_APB1Periph 0
#define AUX_SERIAL_RCC_APB2Periph RCC_APB2Periph_USART6
#define AUX_SERIAL_GPIO GPIOC
#define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_6 // PC.06
#define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_7 // PC.07
@@ -426,8 +424,6 @@
// #define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream3_IRQn
// #define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream_IRQHandler
#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_UART7 | RCC_APB1Periph_TIM3)
#define INTMODULE_RCC_APB2Periph 0
#define INTMODULE_TIMER TIM3
#define INTMODULE_TIMER_IRQn TIM3_IRQn
#define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler
@@ -444,8 +440,6 @@
#define EXTMODULE_RCC_AHB1Periph \
(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOC | \
RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA2)
#define EXTMODULE_RCC_APB1Periph 0
#define EXTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM8 | RCC_APB2Periph_USART6)
#define EXTMODULE_TX_GPIO GPIOC
#define EXTMODULE_TX_GPIO_PIN LL_GPIO_PIN_6 // PC.06
#define EXTMODULE_TX_GPIO_AF LL_GPIO_AF_3 // TIM8_CH1
@@ -507,34 +501,21 @@
#define HEARTBEAT_GPIO_PIN GPIO_Pin_12 // PD.12
// Trainer Port
#define TRAINERMODULE
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD)
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define TRAINER_GPIO GPIOD
#define TRAINER_IN_GPIO_PIN GPIO_Pin_12 // PD.12
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource12
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_13 // PD.13
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource13
#define TRAINER_IN_GPIO_PIN LL_GPIO_PIN_12 // PD.12
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH1
#define TRAINER_OUT_GPIO_PIN LL_GPIO_PIN_13 // PD.13
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_TIMER TIM4
#define TRAINER_GPIO_AF GPIO_AF_TIM4 // TIM4_CH1 (in) + TIM4_CH2 (out)
#define TRAINER_TIMER_IRQn TIM4_IRQn
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
#define TRAINER_GPIO_AF LL_GPIO_AF_2
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_OUT_CCMR1 TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE;
#define TRAINER_IN_CCMR1 TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_CC1S_0;
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR2
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR1
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR3
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC1IF
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC1IE
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC1IE
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC1IF
#define TRAINER_OUT_CCER TIM_CCER_CC2E
#define TRAINER_CCER_POLARYTY TIM_CCER_CC2P
#define TRAINER_IN_CCER TIM_CCER_CC1E
//BLUETOOTH
#define BLUETOOTH_ON_RCC_AHB1Periph RCC_AHB1Periph_GPIOI
-142
View File
@@ -1,142 +0,0 @@
/*
* 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 "opentx.h"
void trainerSendNextFrame();
void init_trainer_ppm()
{
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_OUT_GPIO_PinSource, TRAINER_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_OUT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->ARR = 45000;
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY()*2;
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_0; // Force O/P high
TRAINER_TIMER->BDTR = TIM_BDTR_MOE;
TRAINER_TIMER->EGR = 1;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
TRAINER_TIMER->CR1 |= TIM_CR1_CEN;
trainerSendNextFrame();
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_ppm()
{
TRAINER_TIMER->DIER = 0; // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
}
void init_trainer_capture()
{
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_IN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
TRAINER_TIMER->ARR = 0xFFFF;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->CR2 = 0;
TRAINER_TIMER->CCMR1 = TRAINER_IN_CCMR1;
TRAINER_TIMER->CCER = TRAINER_IN_CCER;
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE;
TRAINER_TIMER->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_capture()
{
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
TRAINER_TIMER->DIER = 0; // Stop Interrupt
}
short unsigned int* lastPulse = 0;
void trainerSendNextFrame()
{
setupPulsesPPMTrainer();
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
lastPulse = trainerPulsesData.ppm.ptr;
TRAINER_TIMER->CCR3 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag
TRAINER_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt
}
extern "C" void TRAINER_TIMER_IRQHandler()
{
DEBUG_INTERRUPT(INT_TRAINER);
uint16_t capture = 0;
bool doCapture = false;
if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) {
// capture mode on trainer jack
capture = TRAINER_IN_COUNTER_REGISTER;
if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) {
doCapture = true;
}
}
if (doCapture) {
captureTrainerPulses(capture);
}
// PPM out compare interrupt
if ((TRAINER_TIMER->DIER & TIM_DIER_CC3IE) && (TRAINER_TIMER->SR & TIM_SR_CC3IF)) {
// compare interrupt
TRAINER_TIMER->DIER &= ~TIM_DIER_CC3IE; // stop this interrupt
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF; // Clear flag
trainerSendNextFrame();
}
if ((TRAINER_TIMER->DIER & TIM_DIER_UIE) && (TRAINER_TIMER->SR & TIM_SR_UIF)) {
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++;
if (trainerPulsesData.ppm.ptr == lastPulse) {
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF; // Clear flag
TRAINER_TIMER->DIER |= TIM_DIER_CC3IE; // Enable this interrupt
}
}
}
+2 -2
View File
@@ -44,12 +44,12 @@ void extmoduleSendNextFramePxx1(void const*, unsigned short) {}
void extmoduleSendNextFrameSoftSerial(void const*, unsigned short, bool) {}
void extmoduleSendNextFramePpm(void*, unsigned short, unsigned short, bool) {}
#if defined(TRAINER_GPIO)
void init_trainer_ppm() {}
void stop_trainer_ppm() {}
void init_trainer_capture() {}
void stop_trainer_capture() {}
#endif
bool is_trainer_connected() { return false; }
void init_trainer_module_cppm() {}
void stop_trainer_module_cppm() {}
+3 -2
View File
@@ -498,7 +498,6 @@ if(HARDWARE_EXTERNAL_MODULE)
set(FIRMWARE_SRC
${FIRMWARE_SRC}
targets/common/arm/stm32/extmodule_driver.cpp
targets/common/arm/stm32/stm32_pulse_driver.cpp
targets/common/arm/stm32/extmodule_serial_driver.cpp
targets/common/arm/stm32/stm32_usart_driver.cpp
)
@@ -599,7 +598,6 @@ set(FIRMWARE_TARGET_SRC
volume_i2c.cpp
eeprom_driver.cpp
backlight_driver.cpp
trainer_driver.cpp
)
if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCBREV STREQUAL COMMANDO8)
@@ -618,6 +616,9 @@ set(FIRMWARE_SRC
targets/common/arm/stm32/timers_driver.cpp
targets/common/arm/stm32/audio_dac_driver.cpp
targets/common/arm/stm32/pwr_driver.cpp
targets/common/arm/stm32/stm32_exti_driver.cpp
targets/common/arm/stm32/stm32_pulse_driver.cpp
targets/common/arm/stm32/trainer_driver.cpp
)
if(LCD_DUAL_BUFFER)
-7
View File
@@ -127,11 +127,7 @@ void boardInit()
INTERRUPT_xMS_RCC_APB1Periph |
TIMER_2MHz_RCC_APB1Periph |
SD_RCC_APB1Periph |
TRAINER_RCC_APB1Periph |
TELEMETRY_RCC_APB1Periph |
AUX_SERIAL_RCC_APB1Periph |
INTMODULE_RCC_APB1Periph |
TRAINER_MODULE_RCC_APB1Periph |
MIXER_SCHEDULER_TIMER_RCC_APB1Periph |
BT_RCC_APB1Periph,
ENABLE);
@@ -140,9 +136,6 @@ void boardInit()
BACKLIGHT_RCC_APB2Periph |
ADC_RCC_APB2Periph |
HAPTIC_RCC_APB2Periph |
INTMODULE_RCC_APB2Periph |
EXTMODULE_RCC_APB2Periph |
TRAINER_MODULE_RCC_APB2Periph |
BT_RCC_APB2Periph |
TELEMETRY_RCC_APB2Periph,
ENABLE);
-23
View File
@@ -139,29 +139,6 @@ uint32_t isBootloaderStart(const uint8_t * buffer);
#define TRAINER_CONNECTED() true
#endif
#if defined(TRAINER_GPIO)
void init_trainer_ppm();
void stop_trainer_ppm();
void init_trainer_capture();
void stop_trainer_capture();
#else
#define init_trainer_ppm()
#define stop_trainer_ppm()
#define init_trainer_capture()
#define stop_trainer_capture()
#endif
#if defined(TRAINER_MODULE_CPPM)
void init_trainer_module_cppm();
void stop_trainer_module_cppm();
#endif
#if defined(TRAINER_MODULE_SBUS)
void init_trainer_module_sbus();
void stop_trainer_module_sbus();
int trainerModuleSbusGetByte(uint8_t* byte);
#endif
void check_telemetry_exti();
// Keys driver
+115 -147
View File
@@ -188,11 +188,14 @@
#define ROTARY_ENCODER_POSITION() (ROTARY_ENCODER_GPIO->IDR >> 12) & 0x03
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line12
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line13
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI15_10_IRQHandler
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOD
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource12
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource13
// ROTARY_ENCODER_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#elif defined(RADIO_X9DP2019)
#define ROTARY_ENCODER_NAVIGATION
#define ROTARY_ENCODER_GPIO GPIOE
@@ -201,11 +204,14 @@
#define ROTARY_ENCODER_POSITION() (((ROTARY_ENCODER_GPIO->IDR >> 9) & 0x02) + ((ROTARY_ENCODER_GPIO->IDR >> 11) & 0x01))
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line10
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line11
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI15_10_IRQHandler
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOE
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource10
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource11
// ROTARY_ENCODER_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#elif defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TPRO)
#define ROTARY_ENCODER_NAVIGATION
#define ROTARY_ENCODER_GPIO GPIOE
@@ -214,10 +220,16 @@
#define ROTARY_ENCODER_POSITION() (((ROTARY_ENCODER_GPIO->IDR >> 10) & 0x02) + ((ROTARY_ENCODER_GPIO->IDR >> 9) & 0x01))
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line9
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line11
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI9_5_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI9_5_IRQHandler
#define ROTARY_ENCODER_EXTI_IRQn2 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler2 EXTI15_10_IRQHandler
// ROTARY_ENCODER_EXTI_LINE1 IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
// ROTARY_ENCODER_EXTI_LINE2 IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOE
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource9
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource11
@@ -229,11 +241,14 @@
#define ROTARY_ENCODER_POSITION() (((ROTARY_ENCODER_GPIO->IDR >> 12) & 0x01) + ((ROTARY_ENCODER_GPIO->IDR >> 9) & 0x02))
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line10
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line12
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI15_10_IRQHandler
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOE
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource10
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource12
// ROTARY_ENCODER_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#elif defined(RADIO_TX12) || defined(RADIO_TX12MK2) || defined(RADIO_ZORRO)
#define ROTARY_ENCODER_NAVIGATION
#define ROTARY_ENCODER_GPIO GPIOE
@@ -242,13 +257,19 @@
#define ROTARY_ENCODER_POSITION() ((ROTARY_ENCODER_GPIO->IDR >> 9) & 0x03)
#define ROTARY_ENCODER_EXTI_LINE1 EXTI_Line9
#define ROTARY_ENCODER_EXTI_LINE2 EXTI_Line10
#define ROTARY_ENCODER_EXTI_IRQn1 EXTI9_5_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler1 EXTI9_5_IRQHandler
#define ROTARY_ENCODER_EXTI_IRQn2 EXTI15_10_IRQn
#define ROTARY_ENCODER_EXTI_IRQHandler2 EXTI15_10_IRQHandler
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOE
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource9
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource10
// ROTARY_ENCODER_EXTI_LINE1 IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
// ROTARY_ENCODER_EXTI_LINE2 IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#if defined(RADIO_TX12)
#define ROTARY_ENCODER_SUPPORT_BUGGY_WIRING
#endif
@@ -1535,8 +1556,6 @@
#define EXTERNAL_ANTENNA
#endif
#if defined(PCBXLITE) || defined(PCBX9LITE)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1
#if defined(PCBXLITES) || defined(PCBX9LITE)
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define INTMODULE_PWR_GPIO GPIOA
@@ -1567,8 +1586,6 @@
#define INIT_INTMODULE_BOOTCMD_PIN() GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN);
#endif
#elif defined(RADIO_X9DP2019)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define INTMODULE_PWR_GPIO GPIOA
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_7 // PA.07
@@ -1588,8 +1605,6 @@
#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF7
#define INTMODULE_DMA_CHANNEL DMA_Channel_4
#elif defined(RADIO_X7ACCESS)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define INTMODULE_PWR_GPIO GPIOC
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_5 // PC.05
@@ -1609,8 +1624,6 @@
#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF7
#define INTMODULE_DMA_CHANNEL DMA_Channel_4
#elif defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define INTMODULE_PWR_GPIO GPIOC
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_4 // PC.04
@@ -1638,8 +1651,6 @@
#elif defined(PCBX9E) || defined(PCBX9DP) || defined(RADIO_X7)
#define INTMODULE_PULSES
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1
#define INTMODULE_PWR_GPIO GPIOC
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_6 // PC.06
#define INTMODULE_TX_GPIO GPIOA
@@ -1657,8 +1668,6 @@
#define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
#elif (defined(RADIO_FAMILY_JUMPER_T12) && defined(HARDWARE_INTERNAL_MODULE)) || defined(RADIO_TX12) || defined(RADIO_T8) || defined(RADIO_TPRO)
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA1)
#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_USART3 | RCC_APB1Periph_TIM2)
#define INTMODULE_RCC_APB2Periph 0
#define INTMODULE_PWR_GPIO GPIOC
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_6 // PC.06
#define INTMODULE_GPIO GPIOB
@@ -1712,8 +1721,6 @@
#else
#define INTMODULE_PULSES
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
#define INTMODULE_RCC_APB1Periph 0
#define INTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM1
#define INTMODULE_PWR_GPIO GPIOD
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_15 // PD.15
#define INTMODULE_TX_GPIO GPIOA
@@ -1733,7 +1740,6 @@
// External Module
#if defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019) || defined(PCBX7ACCESS) || defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#define EXTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM8 | RCC_APB2Periph_USART6)
#if defined(RADIO_X9DP2019) || defined(RADIO_X7ACCESS) || defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
#define EXTMODULE_PWR_GPIO GPIOD
@@ -1785,20 +1791,19 @@
#define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream1
#else
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
#define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM8
#if defined(RADIO_COMMANDO8)
#define EXTMODULE_RF_SWITCH_GPIO GPIOE //Antenna switching port
#define EXTMODULE_RF_SWITCH_GPIO_PIN GPIO_Pin_7 //Antenna switching pin //PE.07
#define EXTMODULE_PWR_GPIO GPIOE //External tuner power port //PE.02
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_2 //External tuner power pin
#define EXTERNAL_MODULE_PWR_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN|EXTMODULE_RF_SWITCH_GPIO_PIN)
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN|EXTMODULE_RF_SWITCH_GPIO_PIN)
#else
#define EXTMODULE_PWR_GPIO GPIOD
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PD.08
#define EXTERNAL_MODULE_PWR_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#endif
#if defined(RADIO_COMMANDO8)
#define EXTMODULE_RF_SWITCH_GPIO GPIOE //Antenna switching port
#define EXTMODULE_RF_SWITCH_GPIO_PIN GPIO_Pin_7 //Antenna switching pin //PE.07
#define EXTMODULE_PWR_GPIO GPIOE //External tuner power port //PE.02
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_2 //External tuner power pin
#define EXTERNAL_MODULE_PWR_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN|EXTMODULE_RF_SWITCH_GPIO_PIN)
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN|EXTMODULE_RF_SWITCH_GPIO_PIN)
#else
#define EXTMODULE_PWR_GPIO GPIOD
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PD.08
#define EXTERNAL_MODULE_PWR_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#endif
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define EXTMODULE_TX_GPIO GPIOA
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_7
@@ -1822,91 +1827,57 @@
#if defined(PCBXLITES) || defined(PCBX9LITE)
// on these 2 radios the trainer port already uses DMA1_Stream6, we won't use the DMA
#define TRAINER_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define TRAINER_GPIO GPIOD
#define TRAINER_IN_GPIO_PIN GPIO_Pin_13 // PD.13
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource13
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_12 // PD.12
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource12
#define TRAINER_IN_GPIO_PIN LL_GPIO_PIN_13 // PD.13
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_OUT_GPIO_PIN LL_GPIO_PIN_12 // PD.12
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH1
#if defined(PCBX9LITE)
#define TRAINER_DETECT_GPIO GPIOD
#define TRAINER_DETECT_GPIO_PIN GPIO_Pin_11 // PD.11
#define TRAINER_DETECT_GPIO_PIN_VALUE Bit_SET
#define TRAINER_DETECT_GPIO_PIN LL_GPIO_PIN_11 // PD.11
#endif
#define TRAINER_TIMER TIM4
#define TRAINER_GPIO_AF GPIO_AF_TIM4 // TIM4_CH1 (Out) + TIM4_CH2 (In)
#define TRAINER_TIMER_IRQn TIM4_IRQn
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_OUT_CCMR1 TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
#define TRAINER_IN_CCMR1 TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0;
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR1
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR2
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR3
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC3IF
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC3IE
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC2IE
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC2IF
#define TRAINER_OUT_CCER TIM_CCER_CC1E
#define TRAINER_CCER_POLARYTY TIM_CCER_CC1P
#define TRAINER_IN_CCER TIM_CCER_CC2E
#elif defined(PCBXLITE)
#define TRAINER_TIMER TIM4
#define TRAINER_RCC_AHB1Periph 0
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define TRAINER_TIMER_IRQn TIM4_IRQn
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
#else
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA1)
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_GPIO GPIOC
#define TRAINER_IN_GPIO_PIN GPIO_Pin_8 // PC.08
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource8
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_9 // PC.09
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource9
#define TRAINER_IN_GPIO_PIN LL_GPIO_PIN_8 // PC.08
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH3
#define TRAINER_OUT_GPIO_PIN LL_GPIO_PIN_9 // PC.09
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH4
#define TRAINER_DETECT_GPIO GPIOA
#define TRAINER_DETECT_GPIO_PIN GPIO_Pin_8 // PA.08
#if defined(RADIO_X9DP2019) || defined(RADIO_X7ACCESS)
#define TRAINER_DETECT_GPIO_PIN_VALUE Bit_SET
#else
#define TRAINER_DETECT_GPIO_PIN_VALUE Bit_RESET
#define TRAINER_DETECT_GPIO_PIN LL_GPIO_PIN_8 // PA.08
#if !defined(RADIO_X9DP2019) && !defined(RADIO_X7ACCESS)
#define TRAINER_DETECT_INVERTED
#endif
#define TRAINER_TIMER TIM3
#define TRAINER_TIMER_IRQn TIM3_IRQn
#define TRAINER_GPIO_AF GPIO_AF_TIM3
#define TRAINER_DMA DMA1
#define TRAINER_DMA_CHANNEL DMA_Channel_5
#define TRAINER_DMA_STREAM DMA1_Stream2
#define TRAINER_DMA_IRQn DMA1_Stream2_IRQn
#define TRAINER_DMA_IRQHandler DMA1_Stream2_IRQHandler
#define TRAINER_DMA_FLAG_TC DMA_IT_TCIF2
#define TRAINER_GPIO_AF LL_GPIO_AF_2
// #define TRAINER_DMA DMA1
// #define TRAINER_DMA_CHANNEL DMA_Channel_5
// #define TRAINER_DMA_STREAM DMA1_Stream2
// #define TRAINER_DMA_IRQn DMA1_Stream2_IRQn
// #define TRAINER_DMA_IRQHandler DMA1_Stream2_IRQHandler
// #define TRAINER_DMA_FLAG_TC DMA_IT_TCIF2
#define TRAINER_TIMER_IRQn TIM3_IRQn
#define TRAINER_TIMER_IRQHandler TIM3_IRQHandler
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_OUT_CCMR2 TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE;
#define TRAINER_IN_CCMR2 TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0;
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR4
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR3
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR1
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC1IF
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC1IE
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC3IE
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC3IF
#define TRAINER_OUT_CCER TIM_CCER_CC4E
#define TRAINER_IN_CCER TIM_CCER_CC3E
#define TRAINER_CCER_POLARYTY TIM_CCER_CC4P
#endif
// Serial Port
#if (defined(PCBX7) && !defined(RADIO_ZORRO) && !defined(RADIO_TX12MK2)) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019)
#define AUX_SERIAL_RCC_AHB1Periph 0
#define AUX_SERIAL_RCC_APB1Periph 0
#define AUX_SERIAL_RCC_APB2Periph 0
#else
#define HARDWARE_TRAINER_AUX_SERIAL
#define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3
#define AUX_SERIAL_RCC_APB2Periph 0
#define AUX_SERIAL_GPIO GPIOB
#define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10
#define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11
@@ -1958,15 +1929,11 @@
#define TELEMETRY_EXTI_PortSource EXTI_PortSourceGPIOD
#define TELEMETRY_EXTI_PinSource EXTI_PinSource6
#define TELEMETRY_EXTI_LINE EXTI_Line6
#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn
#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising
#if defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TX12) || defined(RADIO_TX12MK2) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_COMMANDO8) || defined(RADIO_TPRO)
#define TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER
#elif defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019)
#define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler
#else
#define TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT
// TELEMETRY_EXTI IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
#define TELEMETRY_TIMER TIM11
@@ -2049,18 +2016,26 @@
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line15
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn
#define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
#define EXTI15_10_IRQ_Priority 5
#endif
#elif defined(PCBX9LITE)
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph 0
#elif defined(RADIO_X7ACCESS)
#define INTMODULE_HEARTBEAT
#define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
#define INTMODULE_HEARTBEAT_GPIO GPIOA
#define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_7 // PA.07
#define INTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOA
#define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource7
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line7
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI9_5_IRQn
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
#elif defined(RADIO_X9DP2019)
#define INTMODULE_HEARTBEAT
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOB
@@ -2071,6 +2046,11 @@
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line1
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI1_IRQn
#define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI1_IRQHandler
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI1_IRQ)
#define USE_EXTI1_IRQ
#define EXTI1_IRQ_Priority 5
#endif
#elif defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#define INTMODULE_HEARTBEAT_RCC_AHB1Periph 0
#else
@@ -2081,46 +2061,41 @@
#define INTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOC
#define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource7
#define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line7
#define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI9_5_IRQn
#if defined(RADIO_X7) || defined(RADIO_TX12) || defined(RADIO_TPRO)
#define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER
#else
#define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI9_5_IRQHandler
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
#endif
#if defined(PCBX9LITE)
#define EXTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define EXTMODULE_HEARTBEAT_GPIO GPIOD
#define EXTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_15
#define EXTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOD
#define EXTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource15
#define EXTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line15
#define EXTMODULE_HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn
#define EXTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler
#endif
// Unused
// #if defined(PCBX9LITE)
// #define EXTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
// #define EXTMODULE_HEARTBEAT_GPIO GPIOD
// #define EXTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_15
// #define EXTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOD
// #define EXTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource15
// #define EXTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line15
// #define EXTMODULE_HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn
// #define EXTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler
// #endif
// Trainer / Trainee from the module bay
#if defined(PCBX9LITE) || defined(PCBXLITE) || defined(RADIO_X9DP2019) || defined(PCBX7ACCESS) || defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#if defined(PCBX9LITE) || defined(PCBXLITE) || defined(RADIO_X9DP2019) || \
defined(PCBX7ACCESS) || defined(RADIO_ZORRO) || defined(RADIO_TX12MK2)
#define TRAINER_MODULE_CPPM
#define TRAINER_MODULE_SBUS
#define TRAINER_MODULE_RCC_AHB1Periph 0
#define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_MODULE_RCC_APB2Periph 0
#define TRAINER_MODULE_CPPM_GPIO EXTMODULE_USART_GPIO
#define TRAINER_MODULE_CPPM_GPIO_PIN GPIO_Pin_7
#define TRAINER_MODULE_CPPM_GPIO_PinSource GPIO_PinSource7
#define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3
#define TRAINER_MODULE_CPPM_TIMER TIM3
#define TRAINER_MODULE_CPPM_COUNTER_REGISTER TRAINER_MODULE_CPPM_TIMER->CCR2
#define TRAINER_MODULE_CPPM_INTERRUPT_ENABLE TIM_DIER_CC2IE
#define TRAINER_MODULE_CPPM_INTERRUPT_FLAG TIM_SR_CC2IF
#define TRAINER_MODULE_CPPM_CCMR1 (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0)
#define TRAINER_MODULE_CPPM_CCER TIM_CCER_CC2E
#define TRAINER_MODULE_RCC_AHB1Periph 0
#define TRAINER_MODULE_CPPM_TIMER TIM3
#define TRAINER_MODULE_CCPM_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_MODULE_CPPM_GPIO EXTMODULE_USART_GPIO
#define TRAINER_MODULE_CPPM_GPIO_PIN EXTMODULE_RX_GPIO_PIN
#define TRAINER_MODULE_CPPM_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_MODULE_CPPM_TIMER_IRQn TIM3_IRQn
#define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3
#if defined(PCBX9LITE) || defined(PCBXLITE)
#define TRAINER_MODULE_CPPM_TIMER_IRQHandler TIM3_IRQHandler
#endif
// #define TRAINER_MODULE_SBUS -> use ext module serial buffers?
#define TRAINER_MODULE_SBUS_GPIO EXTMODULE_USART_GPIO
#define TRAINER_MODULE_SBUS_GPIO_PIN TRAINER_MODULE_CPPM_GPIO_PIN
#define TRAINER_MODULE_SBUS_GPIO_AF EXTMODULE_USART_GPIO_AF
@@ -2133,21 +2108,16 @@
// Trainer CPPM input on heartbeat pin
#define TRAINER_MODULE_CPPM
#define TRAINER_MODULE_RCC_AHB1Periph RCC_AHB1Periph_GPIOC
#define TRAINER_MODULE_RCC_APB2Periph RCC_APB2Periph_USART6
#define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_MODULE_CPPM_TIMER TRAINER_TIMER
#define TRAINER_MODULE_CCPM_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_MODULE_CPPM_GPIO INTMODULE_HEARTBEAT_GPIO
#define TRAINER_MODULE_CPPM_GPIO_PIN INTMODULE_HEARTBEAT_GPIO_PIN
#define TRAINER_MODULE_CPPM_GPIO_PinSource INTMODULE_HEARTBEAT_EXTI_PinSource
#define TRAINER_MODULE_CPPM_INTERRUPT_ENABLE TIM_DIER_CC2IE
#define TRAINER_MODULE_CPPM_INTERRUPT_FLAG TIM_SR_CC2IF
#define TRAINER_MODULE_CPPM_CCMR1 (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0)
#define TRAINER_MODULE_CPPM_CCER TIM_CCER_CC2E
#define TRAINER_MODULE_CPPM_COUNTER_REGISTER TRAINER_TIMER->CCR2
#define TRAINER_MODULE_CPPM_TIMER_Channel LL_TIM_CHANNEL_CH2
#define TRAINER_MODULE_CPPM_TIMER_IRQn TRAINER_TIMER_IRQn
#define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3
// Trainer SBUS input on heartbeat pin
#define TRAINER_MODULE_SBUS
// #define TRAINER_MODULE_SBUS -> use ext module serial buffers?
// -> these targets have no external serial module
#define TRAINER_MODULE_SBUS_GPIO_AF GPIO_AF_USART6
#define TRAINER_MODULE_SBUS_USART USART6
#define TRAINER_MODULE_SBUS_GPIO INTMODULE_HEARTBEAT_GPIO
@@ -2158,8 +2128,6 @@
#else
// TODO: replace SBUS trainer with S.PORT pin
#define TRAINER_MODULE_RCC_AHB1Periph 0
#define TRAINER_MODULE_RCC_APB2Periph 0
#define TRAINER_MODULE_RCC_APB1Periph 0
#endif
#endif
+17 -39
View File
@@ -19,7 +19,9 @@
* GNU General Public License for more details.
*/
#include "board.h"
#include "stm32_exti_driver.h"
#include "aux_serial_driver.h"
#include "opentx.h"
#if defined(GHOST)
@@ -104,17 +106,23 @@ static uint8_t rxByte;
static uint16_t bitLength;
static uint16_t probeTimeFromStartBit;
static void do_telemetry_exti()
{
if (rxBitCount == 0) {
TELEMETRY_TIMER->ARR = probeTimeFromStartBit; // 1,5 cycle from start at 57600bps
TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN;
// disable start bit interrupt
EXTI->IMR &= ~EXTI_IMR_MR6;
}
}
void telemetryPortInvertedInit(uint32_t baudrate)
{
if (baudrate == 0) {
//TODO:
// - handle conflict with HEARTBEAT disabled for trainer input...
// - probably need to stop trainer input/output and restore after this is closed
#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && \
!defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
NVIC_DisableIRQ(TELEMETRY_EXTI_IRQn);
#endif
stm32_exti_disable(TELEMETRY_EXTI_LINE);
NVIC_DisableIRQ(TELEMETRY_TIMER_IRQn);
EXTI_InitTypeDef EXTI_InitStructure;
@@ -176,13 +184,7 @@ void telemetryPortInvertedInit(uint32_t baudrate)
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//TODO:
// - handle conflict with HEARTBEAT disabled for trainer input...
// - probably need to stop trainer input/output and restore after this is closed
#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
NVIC_SetPriority(TELEMETRY_EXTI_IRQn, 0);
NVIC_EnableIRQ(TELEMETRY_EXTI_IRQn);
#endif
stm32_exti_enable(TELEMETRY_EXTI_LINE, do_telemetry_exti);
}
void telemetryPortInvertedRxBit()
@@ -368,30 +370,6 @@ extern "C" void TELEMETRY_USART_IRQHandler(void)
}
}
void check_telemetry_exti()
{
if (EXTI_GetITStatus(TELEMETRY_EXTI_LINE) != RESET) {
if (rxBitCount == 0) {
TELEMETRY_TIMER->ARR = probeTimeFromStartBit; // 1,5 cycle from start at 57600bps
TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN;
// disable start bit interrupt
EXTI->IMR &= ~EXTI_IMR_MR6;
}
EXTI_ClearITPendingBit(TELEMETRY_EXTI_LINE);
}
}
#if defined(TELEMETRY_EXTI_IRQHandler)
extern "C" void TELEMETRY_EXTI_IRQHandler(void)
{
check_telemetry_exti();
}
#endif
extern "C" void TELEMETRY_TIMER_IRQHandler()
{
TELEMETRY_TIMER->SR &= ~TIM_SR_UIF;
@@ -1,336 +0,0 @@
/*
* 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 "opentx.h"
void trainerSendNextFrame();
#if defined(TRAINER_GPIO)
void init_trainer_ppm()
{
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_OUT_GPIO_PinSource, TRAINER_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_OUT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->ARR = 45000;
#if defined(TRAINER_OUT_CCMR1)
TRAINER_TIMER->CCMR1 = TRAINER_OUT_CCMR1;
#elif defined(TRAINER_OUT_CCMR2)
TRAINER_TIMER->CCMR2 = TRAINER_OUT_CCMR2;
#endif
TRAINER_TIMER->BDTR = TIM_BDTR_MOE;
TRAINER_TIMER->EGR = 1;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
TRAINER_TIMER->CR1 |= TIM_CR1_CEN;
setupPulsesPPMTrainer();
trainerSendNextFrame();
#if defined(TRAINER_DMA_STREAM)
NVIC_EnableIRQ(TRAINER_DMA_IRQn);
NVIC_SetPriority(TRAINER_DMA_IRQn, 7);
#endif
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_ppm()
{
#if defined(TRAINER_DMA_STREAM)
NVIC_DisableIRQ(TRAINER_DMA_IRQn);
TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#endif
NVIC_DisableIRQ(TRAINER_TIMER_IRQn);
TRAINER_TIMER->DIER = 0;
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
}
void init_trainer_capture()
{
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_IN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
TRAINER_TIMER->ARR = 0xFFFF;
TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS
TRAINER_TIMER->CR2 = 0;
#if defined(TRAINER_IN_CCMR1)
TRAINER_TIMER->CCMR1 = TRAINER_IN_CCMR1;
#elif defined(TRAINER_IN_CCMR2)
TRAINER_TIMER->CCMR2 = TRAINER_IN_CCMR2;
#endif
TRAINER_TIMER->CCER = TRAINER_IN_CCER;
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
TRAINER_TIMER->DIER |= TRAINER_IN_INTERRUPT_ENABLE;
TRAINER_TIMER->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_capture()
{
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
TRAINER_TIMER->DIER = 0; // Stop Interrupt
}
void trainerSendNextFrame()
{
TRAINER_OUT_COUNTER_REGISTER = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TRAINER_OUT_CCER | (GET_TRAINER_PPM_POLARITY() ? 0 : TRAINER_CCER_POLARYTY);
TRAINER_SETUP_REGISTER = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
#if defined(TRAINER_DMA_STREAM)
TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
TRAINER_DMA_STREAM->CR |= TRAINER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
TRAINER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&TRAINER_TIMER->ARR);
TRAINER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(trainerPulsesData.ppm.pulses);
TRAINER_DMA_STREAM->NDTR = trainerPulsesData.ppm.ptr - trainerPulsesData.ppm.pulses;
TRAINER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
#else
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag
TRAINER_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt
#endif
}
#endif
#if defined(TRAINER_DMA_STREAM)
extern "C" void TRAINER_DMA_IRQHandler()
{
if (!DMA_GetITStatus(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC))
return;
DMA_ClearITPendingBit(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC);
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag
TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt
}
#endif
extern "C" void TRAINER_TIMER_IRQHandler()
{
DEBUG_INTERRUPT(INT_TRAINER);
uint16_t capture = 0;
bool doCapture = false;
#if defined(TRAINER_GPIO)
// What mode? in or out?
if ((TRAINER_TIMER->DIER & TRAINER_IN_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_IN_INTERRUPT_FLAG)) {
// capture mode on trainer jack
capture = TRAINER_IN_COUNTER_REGISTER;
if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) {
doCapture = true;
}
}
#endif
#if defined(TRAINER_MODULE_CPPM) && !defined(TRAINER_MODULE_CPPM_TIMER_IRQHandler)
if ((TRAINER_TIMER->DIER & TRAINER_MODULE_CPPM_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_MODULE_CPPM_INTERRUPT_FLAG)) {
// capture mode on heartbeat pin (external module)
capture = TRAINER_MODULE_CPPM_COUNTER_REGISTER;
if (currentTrainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) {
doCapture = true;
}
}
#endif
if (doCapture) {
captureTrainerPulses(capture);
}
#if defined(TRAINER_GPIO)
// PPM out compare interrupt
if ((TRAINER_TIMER->DIER & TRAINER_OUT_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_OUT_INTERRUPT_FLAG)) {
// compare interrupt
TRAINER_TIMER->DIER &= ~TRAINER_OUT_INTERRUPT_ENABLE; // stop this interrupt
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag
setupPulsesPPMTrainer();
trainerSendNextFrame();
}
#endif
#if defined(TRAINER_GPIO) && !defined(TRAINER_DMA_STREAM) // PPM out update interrupt
if ((TRAINER_TIMER->DIER & TIM_DIER_UIE) && (TRAINER_TIMER->SR & TIM_SR_UIF)) {
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++;
if (*trainerPulsesData.ppm.ptr == 0) {
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear this flag
TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt
}
}
#endif
}
#if defined(TRAINER_MODULE_CPPM_TIMER_IRQHandler)
extern "C" void TRAINER_MODULE_CPPM_TIMER_IRQHandler()
{
uint16_t capture = 0;
bool doCapture = false;
if ((TRAINER_MODULE_CPPM_TIMER->DIER & TRAINER_MODULE_CPPM_INTERRUPT_ENABLE) && (TRAINER_MODULE_CPPM_TIMER->SR & TRAINER_MODULE_CPPM_INTERRUPT_FLAG)) {
// capture mode on external module
capture = TRAINER_MODULE_CPPM_COUNTER_REGISTER;
if (currentTrainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) {
doCapture = true;
}
}
if (doCapture) {
captureTrainerPulses(capture);
}
}
#endif
#if defined(TRAINER_MODULE_CPPM)
void init_trainer_module_cppm()
{
EXTERNAL_MODULE_ON();
GPIO_PinAFConfig(TRAINER_MODULE_CPPM_GPIO, TRAINER_MODULE_CPPM_GPIO_PinSource, TRAINER_MODULE_CPPM_GPIO_AF);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TRAINER_MODULE_CPPM_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TRAINER_MODULE_CPPM_GPIO, &GPIO_InitStructure);
TRAINER_MODULE_CPPM_TIMER->ARR = 0xFFFF;
TRAINER_MODULE_CPPM_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS
TRAINER_MODULE_CPPM_TIMER->CR2 = 0;
#if defined(TRAINER_MODULE_CPPM_CCMR1)
TRAINER_MODULE_CPPM_TIMER->CCMR1 = TRAINER_MODULE_CPPM_CCMR1;
#elif defined(TRAINER_MODULE_CPPM_CCMR2)
TRAINER_MODULE_CPPM_TIMER->CCMR2 = TRAINER_MODULE_CPPM_CCMR2;
#endif
TRAINER_MODULE_CPPM_TIMER->CCER = TRAINER_MODULE_CPPM_CCER;
TRAINER_MODULE_CPPM_TIMER->SR &= ~TRAINER_MODULE_CPPM_INTERRUPT_FLAG; // Clear flag
TRAINER_MODULE_CPPM_TIMER->DIER |= TRAINER_MODULE_CPPM_INTERRUPT_ENABLE;
TRAINER_MODULE_CPPM_TIMER->CR1 = TIM_CR1_CEN;
NVIC_SetPriority(TRAINER_MODULE_CPPM_TIMER_IRQn, 7);
NVIC_EnableIRQ(TRAINER_MODULE_CPPM_TIMER_IRQn);
}
void stop_trainer_module_cppm()
{
TRAINER_MODULE_CPPM_TIMER->DIER = 0;
TRAINER_MODULE_CPPM_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
NVIC_DisableIRQ(TRAINER_MODULE_CPPM_TIMER_IRQn); // Stop Interrupt
if (!IS_EXTERNAL_MODULE_ENABLED()) {
EXTERNAL_MODULE_OFF();
}
}
#endif
// TODO: use external module serial driver
#if defined(TRAINER_MODULE_SBUS)
static DMAFifo<32> trainerSbusFifo __DMA (TRAINER_MODULE_SBUS_DMA_STREAM);
void init_trainer_module_sbus()
{
EXTERNAL_MODULE_ON();
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig(TRAINER_MODULE_SBUS_GPIO, TRAINER_MODULE_SBUS_GPIO_PinSource, TRAINER_MODULE_SBUS_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = TRAINER_MODULE_SBUS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(TRAINER_MODULE_SBUS_GPIO, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 100000;
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_Init(TRAINER_MODULE_SBUS_USART, &USART_InitStructure);
DMA_InitTypeDef DMA_InitStructure;
trainerSbusFifo.clear();
USART_ITConfig(TRAINER_MODULE_SBUS_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(TRAINER_MODULE_SBUS_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = TRAINER_MODULE_SBUS_DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TRAINER_MODULE_SBUS_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(trainerSbusFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = trainerSbusFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(TRAINER_MODULE_SBUS_DMA_STREAM, &DMA_InitStructure);
USART_DMACmd(TRAINER_MODULE_SBUS_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(TRAINER_MODULE_SBUS_USART, ENABLE);
DMA_Cmd(TRAINER_MODULE_SBUS_DMA_STREAM, ENABLE);
}
void stop_trainer_module_sbus()
{
DMA_Cmd(TRAINER_MODULE_SBUS_DMA_STREAM, DISABLE);
USART_Cmd(TRAINER_MODULE_SBUS_USART, DISABLE);
USART_DMACmd(TRAINER_MODULE_SBUS_USART, USART_DMAReq_Rx, DISABLE);
DMA_DeInit(TRAINER_MODULE_SBUS_DMA_STREAM);
if (!IS_EXTERNAL_MODULE_ENABLED()) {
EXTERNAL_MODULE_OFF();
}
}
int trainerModuleSbusGetByte(uint8_t* byte)
{
return trainerSbusFifo.pop(*byte);
}
#endif
+1
View File
@@ -20,6 +20,7 @@
*/
#include "opentx.h"
#include "hal/trainer_driver.h"
#include "heartbeat_driver.h"
#include "aux_serial_driver.h"