diff --git a/radio/src/debug.cpp b/radio/src/debug.cpp index af883134e..f97bc8b48 100644 --- a/radio/src/debug.cpp +++ b/radio/src/debug.cpp @@ -145,6 +145,7 @@ void dumpTraceBuffer() "Audio", // INT_AUDIO, "BlueT", // INT_BLUETOOTH, "Lcd ", // INT_LCD, + "D2S7 ", // INT_DMA2S7, "T1CC ", // INT_TIM1CC, "Tim1 ", // INT_TIM1, "Tim8 ", // INT_TIM8, @@ -152,6 +153,7 @@ void dumpTraceBuffer() "TelDm", // INT_TELEM_DMA, "TelUs", // INT_TELEM_USART, "Train", // INT_TRAINER, + "Hbeat", // INT_HEARTBEAT, "Usb ", // INT_OTG_FS, #if defined(DEBUG_USB_INTERRUPTS) " spur", // INT_OTG_FS_SPURIOUS, diff --git a/radio/src/debug.h b/radio/src/debug.h index e951eea65..eb5520bb7 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -255,6 +255,7 @@ enum InterruptNames { INT_AUDIO, INT_BLUETOOTH, INT_LCD, + INT_DMA2S7, INT_TIM1CC, INT_TIM1, INT_TIM8, @@ -262,6 +263,7 @@ enum InterruptNames { INT_TELEM_DMA, INT_TELEM_USART, INT_TRAINER, + INT_HEARTBEAT, INT_OTG_FS, #if defined(DEBUG_USB_INTERRUPTS) INT_OTG_FS_SPURIOUS, diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index d1b3bb9fa..7c98907e3 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -110,19 +110,16 @@ enum MenuModelSetupItems { ITEM_MODEL_PPM1_PROTOCOL, ITEM_MODEL_PPM1_PARAMS, #endif -#if defined(PCBX7) +#if defined(PCBTARANIS) ITEM_MODEL_TRAINER_LABEL, ITEM_MODEL_TRAINER_MODE, #if defined(BLUETOOTH) ITEM_MODEL_TRAINER_BLUETOOTH, #endif ITEM_MODEL_TRAINER_CHANNELS, +#if !defined(PCBXLITE) ITEM_MODEL_TRAINER_PARAMS, -#elif defined(PCBXLITE) - ITEM_MODEL_TRAINER_LABEL, - ITEM_MODEL_TRAINER_MODE, - ITEM_MODEL_TRAINER_BLUETOOTH, - ITEM_MODEL_TRAINER_CHANNELS, +#endif #endif ITEM_MODEL_SETUP_MAX }; @@ -193,12 +190,11 @@ enum MenuModelSetupItems { #define TRAINER_PARAMS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)2 : HIDDEN_ROW) #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW TRAINER_CHANNELS_ROW, TRAINER_PARAMS_ROW #elif defined(PCBXLITE) - #define IF_BT_TRAINER_ON(x) (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER ? (uint8_t)(x) : HIDDEN_ROW) #define TRAINER_BLUETOOTH_M_ROW ((bluetoothDistantAddr[0] == '\0' || bluetoothState == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) #define TRAINER_BLUETOOTH_S_ROW (bluetoothDistantAddr[0] == '\0' ? HIDDEN_ROW : LABEL()) #define TRAINER_BLUETOOTH_ROW (g_model.trainerMode == TRAINER_MODE_MASTER_BLUETOOTH ? TRAINER_BLUETOOTH_M_ROW : (g_model.trainerMode == TRAINER_MODE_SLAVE_BLUETOOTH ? TRAINER_BLUETOOTH_S_ROW : HIDDEN_ROW)) #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) - #define TRAINER_ROWS IF_BT_TRAINER_ON(LABEL(Trainer)), IF_BT_TRAINER_ON(0), IF_BT_TRAINER_ON(TRAINER_BLUETOOTH_ROW), IF_BT_TRAINER_ON(TRAINER_CHANNELS_ROW) + #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_BLUETOOTH_ROW, TRAINER_CHANNELS_ROW #else #define TRAINER_ROWS #endif diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index e99831680..b3026e352 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -597,7 +597,7 @@ bool isTrainerModeAvailable(int mode) #elif defined(PCBXLITE) bool isTrainerModeAvailable(int mode) { - if (g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH)) + if ((g_eeGeneral.bluetoothMode == BLUETOOTH_TRAINER && (mode == TRAINER_MODE_MASTER_BLUETOOTH || mode == TRAINER_MODE_SLAVE_BLUETOOTH)) || mode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) return true; else return false; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index e04e492b9..388f2176a 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -469,7 +469,7 @@ void modelDefault(uint8_t id) #endif #if defined(PCBXLITE) - g_model.trainerMode = TRAINER_MODE_MASTER_BLUETOOTH; + g_model.trainerMode = TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE; #endif #if defined(CPUARM) && defined(EEPROM) diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index a2b99744b..165229b71 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -110,7 +110,6 @@ else() set(TARGET_SRC ${TARGET_SRC} intmodule_pulses_driver.cpp - trainer_driver.cpp ) add_definitions(-DSBUS) set(PULSES_SRC @@ -168,6 +167,7 @@ set(TARGET_SRC ${LED_DRIVER} backlight_driver.cpp extmodule_driver.cpp + trainer_driver.cpp ../common/arm/stm32/audio_dac_driver.cpp ../common/arm/stm32/analog_adc_driver.cpp ) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 48cbc7bc8..71b0032d5 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -155,7 +155,7 @@ void boardInit() BACKLIGHT_RCC_APB1Periph | HAPTIC_RCC_APB1Periph | INTERRUPT_xMS_RCC_APB1Periph | TIMER_2MHz_RCC_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | - TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph | + TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph | HEARTBEAT_RCC_APB1Periph | INTMODULE_RCC_APB1Periph | BT_RCC_APB1Periph, ENABLE); RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph | ADC_RCC_APB2Periph | diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 4ac194fb5..6aa221c85 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -205,25 +205,31 @@ void disable_crossfire( uint32_t module_index ); #else #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET) #endif -#if defined(TRAINER_GPIO) +#if defined(TRAINER_OUT_GPIO_PIN) void init_trainer_ppm(void); void stop_trainer_ppm(void); - void init_trainer_capture(void); - void stop_trainer_capture(void); #else #define init_trainer_ppm() #define stop_trainer_ppm() +#endif +#if defined(TRAINER_IN_GPIO_PIN) + void init_trainer_capture(void); + void stop_trainer_capture(void); +#else #define init_trainer_capture() #define stop_trainer_capture() #endif -#if defined(TRAINER_MODULE_HEARTBEAT) +#if defined(HEARTBEAT_GPIO_AF_CAPTURE) void init_cppm_on_heartbeat_capture(void); void stop_cppm_on_heartbeat_capture(void); - void init_sbus_on_heartbeat_capture(void); - void stop_sbus_on_heartbeat_capture(void); #else #define init_cppm_on_heartbeat_capture() #define stop_cppm_on_heartbeat_capture() +#endif +#if defined(HEARTBEAT_GPIO_AF_SBUS) + void init_sbus_on_heartbeat_capture(void); + void stop_sbus_on_heartbeat_capture(void); +#else #define init_sbus_on_heartbeat_capture() #define stop_sbus_on_heartbeat_capture() #endif diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index e27f8e084..b87e37284 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -799,20 +799,41 @@ #endif // Heartbeat -#if defined(PCBXLITE) +#if defined(PCBXLITE) // TIM4_CH4 #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD + #define HEARTBEAT_RCC_APB1Periph RCC_APB1Periph_TIM4 #define HEARTBEAT_RCC_APB2Periph 0 #define HEARTBEAT_GPIO GPIOD #define HEARTBEAT_GPIO_PIN GPIO_Pin_15 // PD.15 -#else - #define TRAINER_MODULE_HEARTBEAT + #define HEARTBEAT_GPIO_PinSource GPIO_PinSource15 + #define HEARTBEAT_GPIO_AF_CAPTURE GPIO_AF_TIM4 + #define HEARTBEAT_TIMER_CCMR_REG CCMR2 + #define HEARTBEAT_TIMER_CCMR_CFG TIM_CCMR2_IC4F_0 | TIM_CCMR2_IC4F_1 | TIM_CCMR2_CC4S_0 + #define HEARTBEAT_TIMER_CCER_CFG TIM_CCER_CC4E + #define HEARTBEAT_TIMER_IF TIM_SR_CC4IF + #define HEARTBEAT_TIMER_IE TIM_DIER_CC4IE + #define HEARTBEAT_TIMER_CCR CCR4 + #define HEARTBEAT_TIMER TIM4 + #define HEARTBEAT_TIMER_IRQn TIM4_IRQn + #define HEARTBEAT_TIMER_IRQHandler TIM4_IRQHandler +#else // TIM3_CH2 #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC + #define HEARTBEAT_RCC_APB1Periph 0 #define HEARTBEAT_RCC_APB2Periph RCC_APB2Periph_USART6 #define HEARTBEAT_GPIO GPIOC #define HEARTBEAT_GPIO_PIN GPIO_Pin_7 // PC.07 #define HEARTBEAT_GPIO_PinSource GPIO_PinSource7 #define HEARTBEAT_GPIO_AF_SBUS GPIO_AF_USART6 #define HEARTBEAT_GPIO_AF_CAPTURE GPIO_AF_TIM3 + #define HEARTBEAT_TIMER_CCMR_REG CCMR1 + #define HEARTBEAT_TIMER_CCMR_CFG TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0 + #define HEARTBEAT_TIMER_CCER TIM_CCER_CC2E + #define HEARTBEAT_TIMER_CCER_CFG TIM_CCER_CC2E + #define HEARTBEAT_TIMER_IF TIM_SR_CC2IF + #define HEARTBEAT_TIMER_IE TIM_DIER_CC2IE + #define HEARTBEAT_TIMER_CCR CCR2 + #define HEARTBEAT_TIMER TIM3 + #define HEARTBEAT_TIMER_IRQn TIM3_IRQn #define HEARTBEAT_USART USART6 #define HEARTBEAT_USART_IRQHandler USART6_IRQHandler #define HEARTBEAT_USART_IRQn USART6_IRQn diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp index 1992d635e..e41926297 100644 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ b/radio/src/targets/taranis/trainer_driver.cpp @@ -20,9 +20,24 @@ #include "opentx.h" +#if defined(HEARTBEAT_DMA_Stream) DMAFifo<32> heartbeatFifo __DMA (HEARTBEAT_DMA_Stream); +#endif -void trainerSendNextFrame(); +#if defined(TRAINER_OUT_GPIO_PIN) +void trainerSendNextFrame() +{ + TRAINER_TIMER->CCR4 = GET_PPM_DELAY(TRAINER_MODULE)*2; + TRAINER_TIMER->CCER = TIM_CCER_CC4E | (GET_PPM_POLARITY(TRAINER_MODULE) ? 0 : TIM_CCER_CC4P); + TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance + + 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 +} void init_trainer_ppm() { @@ -63,7 +78,9 @@ void stop_trainer_ppm() TRAINER_TIMER->DIER = 0; TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter } +#endif +#if defined(TRAINER_IN_GPIO_PIN) void init_trainer_capture() { GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF); @@ -95,21 +112,9 @@ void stop_trainer_capture() TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter TRAINER_TIMER->DIER = 0; // Stop Interrupt } +#endif -void trainerSendNextFrame() -{ - TRAINER_TIMER->CCR4 = GET_PPM_DELAY(TRAINER_MODULE)*2; - TRAINER_TIMER->CCER = TIM_CCER_CC4E | (GET_PPM_POLARITY(TRAINER_MODULE) ? 0 : TIM_CCER_CC4P); - TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance - - 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 -} - +#if defined(TRAINER_DMA_STREAM) extern "C" void TRAINER_DMA_IRQHandler() { if (!DMA_GetITStatus(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC)) @@ -120,7 +125,9 @@ extern "C" void TRAINER_DMA_IRQHandler() TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag TRAINER_TIMER->DIER |= TIM_DIER_CC1IE; // Enable this interrupt } +#endif +#if defined(TRAINER_TIMER) extern "C" void TRAINER_TIMER_IRQHandler() { DEBUG_INTERRUPT(INT_TRAINER); @@ -158,7 +165,26 @@ extern "C" void TRAINER_TIMER_IRQHandler() trainerSendNextFrame(); } } +#endif +#if defined(HEARTBEAT_TIMER_IRQHandler) +extern "C" void HEARTBEAT_TIMER_IRQHandler() +{ + DEBUG_INTERRUPT(INT_TRAINER); + + uint16_t capture = 0; + + if ((HEARTBEAT_TIMER->DIER & HEARTBEAT_TIMER_IE) && (HEARTBEAT_TIMER->SR & HEARTBEAT_TIMER_IF)) { + // capture mode on heartbeat pin (external module) + capture = HEARTBEAT_TIMER->HEARTBEAT_TIMER_CCR; + if (currentTrainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) { + captureTrainerPulses(capture); + } + } +} +#endif + +#if defined(HEARTBEAT_GPIO_AF_CAPTURE) void init_cppm_on_heartbeat_capture(void) { EXTERNAL_MODULE_ON(); @@ -173,30 +199,32 @@ void init_cppm_on_heartbeat_capture(void) GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(HEARTBEAT_GPIO, &GPIO_InitStructure); - TRAINER_TIMER->ARR = 0xFFFF; - TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS - TRAINER_TIMER->CR2 = 0; - TRAINER_TIMER->CCMR1 = TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0; - TRAINER_TIMER->CCER = TIM_CCER_CC2E; - TRAINER_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag - TRAINER_TIMER->DIER |= TIM_DIER_CC2IE; - TRAINER_TIMER->CR1 = TIM_CR1_CEN; + HEARTBEAT_TIMER->ARR = 0xFFFF; + HEARTBEAT_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS + HEARTBEAT_TIMER->CR2 = 0; + HEARTBEAT_TIMER->HEARTBEAT_TIMER_CCMR_REG = HEARTBEAT_TIMER_CCMR_CFG; + HEARTBEAT_TIMER->CCER = HEARTBEAT_TIMER_CCER_CFG; + HEARTBEAT_TIMER->SR &= ~HEARTBEAT_TIMER_IF; // Clear flag + HEARTBEAT_TIMER->DIER |= HEARTBEAT_TIMER_IE; + HEARTBEAT_TIMER->CR1 = TIM_CR1_CEN; - NVIC_SetPriority(TRAINER_TIMER_IRQn, 7); - NVIC_EnableIRQ(TRAINER_TIMER_IRQn); + NVIC_SetPriority(HEARTBEAT_TIMER_IRQn, 7); + NVIC_EnableIRQ(HEARTBEAT_TIMER_IRQn); } void stop_cppm_on_heartbeat_capture() { - TRAINER_TIMER->DIER = 0; - TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter - NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt + HEARTBEAT_TIMER->DIER = 0; + HEARTBEAT_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter + NVIC_DisableIRQ(HEARTBEAT_TIMER_IRQn); // Stop Interrupt if (!IS_EXTERNAL_MODULE_ENABLED()) { EXTERNAL_MODULE_OFF(); } } +#endif +#if defined(HEARTBEAT_GPIO_AF_SBUS) void init_sbus_on_heartbeat_capture() { EXTERNAL_MODULE_ON(); @@ -272,3 +300,4 @@ int sbusGetByte(uint8_t * byte) return false; } } +#endif