From 042d5091f235e7871e3df1551f76738117d01cbd Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 28 Mar 2022 12:50:43 +0200 Subject: [PATCH] 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) --- radio/src/gui/212x64/view_main.cpp | 3 +- radio/src/hal/trainer_driver.h | 47 +++ radio/src/opentx.cpp | 6 - .../arm/stm32/bootloader/CMakeLists.txt | 1 + .../common/arm/stm32/bootloader/boot.cpp | 11 +- .../common/arm/stm32/heartbeat_driver.cpp | 45 +-- .../targets/common/arm/stm32/pwr_driver.cpp | 11 - .../arm/stm32/rotary_encoder_driver.cpp | 102 ++---- .../common/arm/stm32/stm32_exti_driver.cpp | 117 ++++++ .../common/arm/stm32/stm32_exti_driver.h | 40 +++ .../common/arm/stm32/stm32_pulse_driver.cpp | 74 +++- .../common/arm/stm32/stm32_pulse_driver.h | 5 +- .../common/arm/stm32/stm32_usart_driver.cpp | 42 +++ .../common/arm/stm32/trainer_driver.cpp | 340 ++++++++++++++++++ radio/src/targets/horus/CMakeLists.txt | 3 +- radio/src/targets/horus/board.cpp | 11 +- radio/src/targets/horus/board.h | 12 - radio/src/targets/horus/hal.h | 75 ++-- radio/src/targets/horus/trainer_driver.cpp | 144 -------- radio/src/targets/nv14/CMakeLists.txt | 2 +- radio/src/targets/nv14/board.cpp | 11 +- radio/src/targets/nv14/board.h | 7 - radio/src/targets/nv14/hal.h | 33 +- radio/src/targets/nv14/trainer_driver.cpp | 142 -------- radio/src/targets/simu/module_drivers.cpp | 4 +- radio/src/targets/taranis/CMakeLists.txt | 5 +- radio/src/targets/taranis/board.cpp | 7 - radio/src/targets/taranis/board.h | 23 -- radio/src/targets/taranis/hal.h | 262 ++++++-------- .../src/targets/taranis/telemetry_driver.cpp | 56 +-- radio/src/targets/taranis/trainer_driver.cpp | 336 ----------------- radio/src/trainer.cpp | 1 + 32 files changed, 896 insertions(+), 1082 deletions(-) create mode 100644 radio/src/hal/trainer_driver.h create mode 100644 radio/src/targets/common/arm/stm32/stm32_exti_driver.cpp create mode 100644 radio/src/targets/common/arm/stm32/stm32_exti_driver.h create mode 100644 radio/src/targets/common/arm/stm32/trainer_driver.cpp delete mode 100644 radio/src/targets/horus/trainer_driver.cpp delete mode 100644 radio/src/targets/nv14/trainer_driver.cpp delete mode 100644 radio/src/targets/taranis/trainer_driver.cpp diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index e9502c837..f1b05f157 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -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; } diff --git a/radio/src/hal/trainer_driver.h b/radio/src/hal/trainer_driver.h new file mode 100644 index 000000000..185e8cbcf --- /dev/null +++ b/radio/src/hal/trainer_driver.h @@ -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 diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 897da4f0c..d5965b1c7 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -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); diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index bd06a8e36..f903cb84e 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -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 diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 875a8b2ae..0e744553c 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.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(); diff --git a/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp index e06db23af..068ac0cff 100644 --- a/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp +++ b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp @@ -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 diff --git a/radio/src/targets/common/arm/stm32/pwr_driver.cpp b/radio/src/targets/common/arm/stm32/pwr_driver.cpp index 3d197caab..2f758c94c 100644 --- a/radio/src/targets/common/arm/stm32/pwr_driver.cpp +++ b/radio/src/targets/common/arm/stm32/pwr_driver.cpp @@ -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() diff --git a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp index 271a24a37..cd51193ca 100644 --- a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp @@ -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; diff --git a/radio/src/targets/common/arm/stm32/stm32_exti_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_exti_driver.cpp new file mode 100644 index 000000000..024524ebd --- /dev/null +++ b/radio/src/targets/common/arm/stm32/stm32_exti_driver.cpp @@ -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 +} diff --git a/radio/src/targets/common/arm/stm32/stm32_exti_driver.h b/radio/src/targets/common/arm/stm32/stm32_exti_driver.h new file mode 100644 index 000000000..6c15f10cc --- /dev/null +++ b/radio/src/targets/common/arm/stm32/stm32_exti_driver.h @@ -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 + +// 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); diff --git a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp index 2274e1ab3..456c35536 100644 --- a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.cpp @@ -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); +} diff --git a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.h b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.h index 299ee6fec..04cf8ace6 100644 --- a/radio/src/targets/common/arm/stm32/stm32_pulse_driver.h +++ b/radio/src/targets/common/arm/stm32/stm32_pulse_driver.h @@ -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 || \ diff --git a/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp index ae5829db9..fbc14556b 100644 --- a/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_usart_driver.cpp @@ -22,6 +22,46 @@ #include "stm32_usart_driver.h" #include +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; diff --git a/radio/src/targets/common/arm/stm32/trainer_driver.cpp b/radio/src/targets/common/arm/stm32/trainer_driver.cpp new file mode 100644 index 000000000..ea79f3a46 --- /dev/null +++ b/radio/src/targets/common/arm/stm32/trainer_driver.cpp @@ -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 diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index f06a43fc0..016a7924a 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -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 ) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index a280cd72f..53c879fe1 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -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(); diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 8b09861dc..b83fa553c 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -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 { diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 1ac60da8e..25d325cbf 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -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 diff --git a/radio/src/targets/horus/trainer_driver.cpp b/radio/src/targets/horus/trainer_driver.cpp deleted file mode 100644 index 6f49e02e7..000000000 --- a/radio/src/targets/horus/trainer_driver.cpp +++ /dev/null @@ -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(); - } - } -} diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index 35a493a83..ee6bd04bf 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -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 ) diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index ff4f97301..004da2815 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -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; diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 4951412ea..26ec38dab 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -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 { diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index f2f5bdd28..4f569df5a 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -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 diff --git a/radio/src/targets/nv14/trainer_driver.cpp b/radio/src/targets/nv14/trainer_driver.cpp deleted file mode 100644 index 55282d500..000000000 --- a/radio/src/targets/nv14/trainer_driver.cpp +++ /dev/null @@ -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 - } - } -} diff --git a/radio/src/targets/simu/module_drivers.cpp b/radio/src/targets/simu/module_drivers.cpp index 9ebd13eca..48f59aa72 100644 --- a/radio/src/targets/simu/module_drivers.cpp +++ b/radio/src/targets/simu/module_drivers.cpp @@ -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() {} diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 97ff660df..3b16bffe3 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -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) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 2e79aba65..856805d64 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -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); diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index e09f09355..e1f322ad7 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -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 diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index f8a6f4fd8..06116895c 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -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 diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index 1fbace107..4fd643f27 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -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; diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp deleted file mode 100644 index 919c38240..000000000 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ /dev/null @@ -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 diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index 0730dab8c..a6acac4fe 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -20,6 +20,7 @@ */ #include "opentx.h" +#include "hal/trainer_driver.h" #include "heartbeat_driver.h" #include "aux_serial_driver.h"