diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index c93116143..012fcc799 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -548,9 +548,14 @@ enum SwitchSources { SWSRC_LAST_FLIGHT_MODE = SWSRC_FIRST_FLIGHT_MODE+MAX_FLIGHT_MODES-1, SWSRC_TELEMETRY_STREAMING, + SWSRC_FIRST_SENSOR, SWSRC_LAST_SENSOR = SWSRC_FIRST_SENSOR+MAX_TELEMETRY_SENSORS-1, +#if defined(DEBUG_LATENCY) + SWSRC_LATENCY_TOGGLE, +#endif + SWSRC_COUNT, SWSRC_OFF = -SWSRC_ON, diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 6967cb984..e17aebc9e 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -530,7 +530,6 @@ void menuMainView(event_t event) #endif } else { - // Logical Switches uint8_t index = 0; uint8_t y = LCD_H-20; @@ -552,7 +551,7 @@ void menuMainView(event_t event) } // And ! in case of unexpected shutdown -#if defined(LOG_TELEMETRY) || defined(WATCHDOG_DISABLED) +#if defined(LOG_TELEMETRY) || defined(WATCHDOG_DISABLED) || defined(DEBUG_LATENCY) lcdDrawChar(REBOOT_X, 0*FH, '!', INVERS); #else if (unexpectedShutdown) { diff --git a/radio/src/gui/128x64/view_statistics.cpp b/radio/src/gui/128x64/view_statistics.cpp index 5d42c1f92..b5ff4174c 100644 --- a/radio/src/gui/128x64/view_statistics.cpp +++ b/radio/src/gui/128x64/view_statistics.cpp @@ -100,19 +100,8 @@ void menuStatisticsView(event_t event) #endif } - #define MENU_DEBUG_COL1_OFS (11*FW-3) - #define MENU_DEBUG_COL2_OFS (17*FW) - #define MENU_DEBUG_Y_CURRENT (1*FH) - #define MENU_DEBUG_ROW1 (1*FH+1) - #define MENU_DEBUG_ROW2 (2*FH+1) - #define MENU_DEBUG_Y_MAH (2*FH) - #define MENU_DEBUG_Y_CPU_TEMP (3*FH) - #define MENU_DEBUG_Y_COPROC (4*FH) - #define MENU_DEBUG_Y_MIXMAX (5*FH) - #define MENU_DEBUG_Y_RTOS (6*FH) - #define MENU_DEBUG_Y_USB (2*FH) - #define MENU_DEBUG_Y_LUA (3*FH) - #define MENU_DEBUG_Y_FREE_RAM (4*FH) +#define MENU_DEBUG_COL1_OFS (11*FW-3) +#define MENU_DEBUG_COL2_OFS (17*FW) void menuStatisticsDebug(event_t event) { @@ -134,7 +123,6 @@ void menuStatisticsDebug(event_t event) maxMixerDuration = 0; break; - case EVT_KEY_FIRST(KEY_UP): #if defined(NAVIGATION_X7) case EVT_KEY_BREAK(KEY_PAGE): @@ -157,83 +145,105 @@ void menuStatisticsDebug(event_t event) #if defined(PCBSKY9X) if ((ResetReason&RSTC_SR_RSTTYP) == (2<<8)) { - lcdDrawText(LCD_W-8*FW, 0*FH, "WATCHDOG"); + lcdDrawText(LCD_W-8*FW, 0, "WATCHDOG"); } else if (unexpectedShutdown) { - lcdDrawText(LCD_W-13*FW, 0*FH, "UNEXP.SHTDOWN"); + lcdDrawText(LCD_W-13*FW, 0, "UNEXP.SHTDOWN"); } #endif + uint8_t y = FH + 1; + #if defined(TX_CAPACITY_MEASUREMENT) // current - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT); - drawValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT); + lcdDrawTextAlignedLeft(y, STR_CPU_CURRENT); + drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, getCurrent(), UNIT_MILLIAMPS, LEFT); uint32_t current_scale = 488 + g_eeGeneral.txCurrentCalibration; - lcdDrawChar(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>'); - drawValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT); + lcdDrawChar(MENU_DEBUG_COL2_OFS, y, '>'); + drawValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, y, Current_max*10*current_scale/8192, UNIT_RAW, LEFT); + y += FH; + // consumption - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH); - drawValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1); + lcdDrawTextAlignedLeft(y, STR_CPU_MAH); + drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1); + y += FH; #endif #if defined(PCBSKY9X) - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP); - drawValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT); - lcdDrawChar(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>'); - drawValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT); + lcdDrawTextAlignedLeft(y, STR_CPU_TEMP); + drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, getTemperature(), UNIT_TEMPERATURE, LEFT); + lcdDrawChar(MENU_DEBUG_COL2_OFS, y, '>'); + drawValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, y, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT); + y += FH; #endif #if defined(COPROCESSOR) - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP); - + lcdDrawTextAlignedLeft(y, STR_COPROC_TEMP); if (Coproc_read==0) { - lcdDrawText(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, "Co Proc NACK",INVERS); + lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Co Proc NACK",INVERS); } else if (Coproc_read==0x81) { - lcdDrawText(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, "Inst.TinyApp",INVERS); + lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Inst.TinyApp",INVERS); } else if (Coproc_read<3) { - lcdDrawText(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, "Upgr.TinyApp",INVERS); + lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Upgr.TinyApp",INVERS); } else { - drawValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT); - drawValueWithUnit(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT); + drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, Coproc_temp, UNIT_TEMPERATURE, LEFT); + drawValueWithUnit(MENU_DEBUG_COL2_OFS, y, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT); } + y += FH; #endif -#if defined(PCBTARANIS) -#if !defined(SIMU) && defined(DEBUG) - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_USB, "Usb"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_USB, charsWritten, LEFT); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_USB, " "); - lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_Y_USB, APP_Rx_ptr_in, LEFT); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_USB, " "); - lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_Y_USB, APP_Rx_ptr_out, LEFT); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_USB, " "); - lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_Y_USB, usbWraps, LEFT); +#if defined(STM32) && !defined(SIMU) && defined(DEBUG) + lcdDrawTextAlignedLeft(y, "Usb"); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, charsWritten, LEFT); + lcdDrawText(lcdLastRightPos, y, " "); + lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_in, LEFT); + lcdDrawText(lcdLastRightPos, y, " "); + lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_out, LEFT); + lcdDrawText(lcdLastRightPos, y, " "); + lcdDrawNumber(lcdLastRightPos, y, usbWraps, LEFT); + y += FH; #endif - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_FREE_RAM, "Free Mem"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_FREE_RAM, availableMemory(), LEFT); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_FREE_RAM, "b"); + +#if defined(STM32) + lcdDrawTextAlignedLeft(y, "Free Mem"); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, availableMemory(), LEFT); + lcdDrawText(lcdLastRightPos, y, "b"); + y += FH; +#endif + #if defined(LUA) - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_LUA, "Lua scripts"); - lcdDrawText(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_LUA+1, "[D]", SMLSIZE); - lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_Y_LUA, 10*maxLuaDuration, LEFT); - lcdDrawText(lcdLastRightPos+2, MENU_DEBUG_Y_LUA+1, "[I]", SMLSIZE); - lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_Y_LUA, 10*maxLuaInterval, LEFT); -#endif // LUA -#endif // PCBTARANIS + lcdDrawTextAlignedLeft(y, "Lua scripts"); + lcdDrawText(MENU_DEBUG_COL1_OFS, y+1, "[D]", SMLSIZE); + lcdDrawNumber(lcdLastRightPos, y, 10*maxLuaDuration, LEFT); + lcdDrawText(lcdLastRightPos+2, y+1, "[I]", SMLSIZE); + lcdDrawNumber(lcdLastRightPos, y, 10*maxLuaInterval, LEFT); + y += FH; +#endif - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_MIXMAX, "ms"); + lcdDrawTextAlignedLeft(y, STR_TMIXMAXMS); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT); + lcdDrawText(lcdLastRightPos, y, "ms"); + y += FH; - lcdDrawTextAlignedLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, menusStack.available(), LEFT|SMLSIZE); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_RTOS, "/"); - lcdDrawNumber(lcdLastRightPos+1, MENU_DEBUG_Y_RTOS, mixerStack.available(), LEFT|SMLSIZE); - lcdDrawText(lcdLastRightPos, MENU_DEBUG_Y_RTOS, "/"); - lcdDrawNumber(lcdLastRightPos+1, MENU_DEBUG_Y_RTOS, audioStack.available(), LEFT|SMLSIZE); + lcdDrawTextAlignedLeft(y, STR_FREE_STACK); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, menusStack.available(), LEFT); + lcdDrawText(lcdLastRightPos, y, "/"); + lcdDrawNumber(lcdLastRightPos, y, mixerStack.available(), LEFT); + lcdDrawText(lcdLastRightPos, y, "/"); + lcdDrawNumber(lcdLastRightPos, y, audioStack.available(), LEFT); + y += FH; + +#if defined(DEBUG_LATENCY) + lcdDrawTextAlignedLeft(y, "Hearbeat"); + if (heartbeatCapture.valid) + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, heartbeatCapture.count, LEFT); + else + lcdDrawText(MENU_DEBUG_COL1_OFS, y, "---"); + y += FH; +#endif lcdDrawText(4*FW, 7*FH+1, STR_MENUTORESET); lcdInvertLastLine(); @@ -269,12 +279,16 @@ void menuStatisticsDebug2(event_t event) break; } - lcdDrawTextAlignedLeft(MENU_DEBUG_ROW1, "Tlm RX Err"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_ROW1, telemetryErrors, RIGHT); + uint8_t y = FH + 1; -#if defined(PCBX7) - lcdDrawTextAlignedLeft(MENU_DEBUG_ROW2, "BT status"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_ROW2, IS_BLUETOOTH_CHIP_PRESENT(), RIGHT); + lcdDrawTextAlignedLeft(y, "Tlm RX Err"); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, telemetryErrors, RIGHT); + y += FH; + +#if defined(BLUETOOTH) + lcdDrawTextAlignedLeft(y, "BT status"); + lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, IS_BLUETOOTH_CHIP_PRESENT(), RIGHT); + y += FH; #endif lcdDrawText(4*FW, 7*FH+1, STR_MENUTORESET); diff --git a/radio/src/gui/212x64/view_statistics.cpp b/radio/src/gui/212x64/view_statistics.cpp index aa7aeee4f..3b7f04a49 100644 --- a/radio/src/gui/212x64/view_statistics.cpp +++ b/radio/src/gui/212x64/view_statistics.cpp @@ -184,7 +184,7 @@ void menuStatisticsDebug(event_t event) lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_ROW4, usbWraps, LEFT); #endif - lcdDrawTextAlignedLeft(MENU_DEBUG_ROW5, STR_FREESTACKMINB); + lcdDrawTextAlignedLeft(MENU_DEBUG_ROW5, STR_FREE_STACK); lcdDrawText(MENU_DEBUG_COL1_OFS, MENU_DEBUG_ROW5+1, "[M]", SMLSIZE); lcdDrawNumber(lcdLastRightPos, MENU_DEBUG_ROW5, menusStack.available(), LEFT); lcdDrawText(lcdLastRightPos+2, MENU_DEBUG_ROW5+1, "[X]", SMLSIZE); diff --git a/radio/src/gui/480x272/view_statistics.cpp b/radio/src/gui/480x272/view_statistics.cpp index fa3d8293b..583c609fe 100644 --- a/radio/src/gui/480x272/view_statistics.cpp +++ b/radio/src/gui/480x272/view_statistics.cpp @@ -114,7 +114,7 @@ bool menuStatsDebug(event_t event) lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+FH, STR_TMIXMAXMS); lcdDrawNumber(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+FH, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT, 0, NULL, "ms"); - lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+2*FH, STR_FREESTACKMINB); + lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+2*FH, STR_FREE_STACK); lcdDrawText(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+2*FH+1, "[Menus]", HEADER_COLOR|SMLSIZE); lcdDrawNumber(lcdNextPos+5, MENU_CONTENT_TOP+2*FH, menusStack.available(), LEFT); lcdDrawText(lcdNextPos+20, MENU_CONTENT_TOP+2*FH+1, "[Mix]", HEADER_COLOR|SMLSIZE); diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index f0b1c3a9a..598a531bf 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -47,6 +47,10 @@ union ReusableBuffer reusableBuffer __DMA; uint8_t* MSC_BOT_Data = reusableBuffer.MSC_BOT_Data; #endif +#if defined(DEBUG_LATENCY) +uint8_t latencyToggleSwitch = 0; +#endif + const uint8_t bchout_ar[] = { 0x1B, 0x1E, 0x27, 0x2D, 0x36, 0x39, 0x4B, 0x4E, 0x63, 0x6C, 0x72, 0x78, @@ -1339,6 +1343,19 @@ void doMixerCalculations() static tmr10ms_t lastTMR = 0; tmr10ms_t tmr10ms = get_tmr10ms(); + +#if defined(DEBUG_LATENCY) + static tmr10ms_t lastLatencyToggle = 0; + if (tmr10ms - lastLatencyToggle >= 10) { + lastLatencyToggle = tmr10ms; + latencyToggleSwitch ^= 1; + if (latencyToggleSwitch) + sportUpdatePowerOn(); + else + sportUpdatePowerOff(); + } +#endif + uint8_t tick10ms = (tmr10ms >= lastTMR ? tmr10ms - lastTMR : 1); // handle tick10ms overrun // correct overflow handling costs a lot of code; happens only each 11 min; diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 2b15c68a1..5ec52dca5 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1386,4 +1386,8 @@ inline bool isSimu() #endif } +#if defined(DEBUG_LATENCY) +extern uint8_t latencyToggleSwitch; +#endif + #endif // _OPENTX_H_ diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index 173165fc2..8c5dfbc94 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -272,7 +272,14 @@ void setupPulsesInternalModule(uint8_t protocol) #if defined(PXX2) case PROTOCOL_CHANNELS_PXX2: intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE); - scheduleNextMixerCalculation(INTERNAL_MODULE, moduleState[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleState[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER ? PXX2_TOOLS_PERIOD : PXX2_PERIOD); + if (moduleState[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleState[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER) { + scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_TOOLS_PERIOD); + } +#if !defined(INTMDULE_HEARTBEAT) + else { + scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_PERIOD); + } +#endif break; #endif diff --git a/radio/src/pulses/pulses_common.h b/radio/src/pulses/pulses_common.h index da70a13c0..f453c5f7c 100644 --- a/radio/src/pulses/pulses_common.h +++ b/radio/src/pulses/pulses_common.h @@ -58,8 +58,12 @@ template class PulsesBuffer: public DataBuffer { public: T getLast() { - return *(DataBuffer::ptr - 1); + return *(DataBuffer::ptr - 1); }; + + void setLast(T value) { + *(DataBuffer::ptr - 1) = value; + } }; #endif diff --git a/radio/src/pulses/pxx1.h b/radio/src/pulses/pxx1.h index 822886470..3d605de75 100644 --- a/radio/src/pulses/pxx1.h +++ b/radio/src/pulses/pxx1.h @@ -23,6 +23,14 @@ #include "pxx.h" +struct HeartbeatCapture { + uint32_t timestamp; + uint32_t count; + uint8_t valid; +}; + +extern volatile HeartbeatCapture heartbeatCapture; + class Pxx1CrcMixin { protected: void initCrc() diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 6133b8bdc..ada03129f 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -60,6 +60,12 @@ void Pxx2Pulses::addChannels(uint8_t module) for (int8_t i = 0; i < count; i++, channel++) { int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); +#if defined(DEBUG_LATENCY_RF_ONLY) + if (latencyToggleSwitch) + pulseValue = 1; + else + pulseValue = 2046; +#endif if (i & 1) addPulsesValues(pulseValueLow, pulseValue); else diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index a4a787883..c9a595248 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -321,6 +321,11 @@ char * getSwitchString(char * dest, swsrc_t idx) else if (idx == SWSRC_TELEMETRY_STREAMING) { strcpy(s, "Tele"); } +#if defined(DEBUG_LATENCY) + else if (idx == SWSRC_LATENCY_TOGGLE) { + strcpy(s, "Ltc"); + } +#endif else { zchar2str(s, g_model.telemetrySensors[idx-SWSRC_FIRST_SENSOR].label, TELEM_LABEL_LEN); } diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 9012339a8..38ae149b0 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -431,6 +431,11 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) else if (cs_idx == SWSRC_ON) { result = true; } +#if defined(DEBUG_LATENCY) + else if (cs_idx == SWSRC_LATENCY_TOGGLE) { + result = latencyToggleSwitch; + } +#endif else if (cs_idx <= SWSRC_LAST_SWITCH) { #if defined(PCBTARANIS) || defined(PCBHORUS) if (flags & GETSWITCH_MIDPOS_DELAY) diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index b3756b7d6..da45e0309 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -17,6 +17,7 @@ option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger option(MULTI_SPORT "SPORT telemetry support" OFF) option(SUPPORT_D16_EU_ONLY "XJT module only supports D16-EU and LR12-EU" OFF) # TODO rename to XJT_EU_ONLY option(DEBUG_INTERRUPTS "Count interrupts" OFF) +option(DEBUG_LATENCY "Debug latency" OFF) option(DEBUG_USB_INTERRUPTS "Count individual USB interrupts" OFF) option(DEBUG_TASKS "Task switching statistics" OFF) option(DEBUG_TIMERS "Time critical parts of the code" OFF) @@ -71,6 +72,17 @@ if(DEBUG_TIMERS) set(DEBUG ON) endif() +if(DEBUG_LATENCY STREQUAL MIXER_RF) + add_definitions(-DDEBUG_LATENCY) + add_definitions(-DDEBUG_LATENCY_MIXER_RF) +endif() + +if(DEBUG_LATENCY STREQUAL RF_ONLY) + add_definitions(-DDEBUG_LATENCY) + add_definitions(-DDEBUG_LATENCY_RF_ONLY) +endif() + + if(CLI) add_definitions(-DCLI) set(FIRMWARE_SRC ${FIRMWARE_SRC} cli.cpp) diff --git a/radio/src/targets/common/arm/stm32/hearbeat_driver.cpp b/radio/src/targets/common/arm/stm32/hearbeat_driver.cpp deleted file mode 100644 index afdc581ed..000000000 --- a/radio/src/targets/common/arm/stm32/hearbeat_driver.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * 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" - -volatile uint32_t HearbeatCapture = 0; - -void init_xjt_heartbeat() -{ - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Pin = HEARTBEAT_GPIO_PIN; - GPIO_Init(HEARTBEAT_GPIO, &GPIO_InitStructure); - - SYSCFG_EXTILineConfig(HEARTBEAT_EXTI_PortSource, HEARTBEAT_EXTI_PinSource); - - EXTI_InitTypeDef EXTI_InitStructure; - EXTI_StructInit(&EXTI_InitStructure); - EXTI_InitStructure.EXTI_Line = HEARTBEAT_EXTI_LINE; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - NVIC_SetPriority(HEARTBEAT_EXTI_IRQn, 0); // Highest priority interrupt - NVIC_EnableIRQ(HEARTBEAT_EXTI_IRQn); -} - -void stop_xjt_heartbeat() -{ - NVIC_DisableIRQ(HEARTBEAT_EXTI_IRQn); -} - -extern "C" void HEARTBEAT_EXTI_IRQHandler() -{ - if (EXTI_GetITStatus(HEARTBEAT_EXTI_LINE) != RESET) { - HearbeatCapture = TIMER_2MHz_TIMER->CNT; - EXTI_ClearITPendingBit(HEARTBEAT_EXTI_LINE); - } -} diff --git a/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp new file mode 100644 index 000000000..5ab376736 --- /dev/null +++ b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * 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" + +volatile HeartbeatCapture heartbeatCapture; + +#if defined(INTMODULE_HEARTBEAT_GPIO) +void init_intmodule_heartbeat() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = INTMODULE_HEARTBEAT_GPIO_PIN; + GPIO_Init(INTMODULE_HEARTBEAT_GPIO, &GPIO_InitStructure); + + SYSCFG_EXTILineConfig(INTMODULE_HEARTBEAT_EXTI_PortSource, INTMODULE_HEARTBEAT_EXTI_PinSource); + + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = INTMODULE_HEARTBEAT_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + NVIC_SetPriority(INTMODULE_HEARTBEAT_EXTI_IRQn, 0); // Highest priority interrupt + NVIC_EnableIRQ(INTMODULE_HEARTBEAT_EXTI_IRQn); + heartbeatCapture.valid = true; +} + +void stop_intmodule_heartbeat() +{ + heartbeatCapture.valid = false; + +#if !defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER) + NVIC_DisableIRQ(INTMODULE_HEARTBEAT_EXTI_IRQn); +#endif + + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = INTMODULE_HEARTBEAT_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = INTMODULE_HEARTBEAT_TRIGGER; + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + EXTI_Init(&EXTI_InitStructure); +} + +void check_xjt_heartbeat() +{ + if (EXTI_GetITStatus(INTMODULE_HEARTBEAT_EXTI_LINE) != RESET) { + heartbeatCapture.timestamp = TIMER_2MHz_TIMER->CNT; + heartbeatCapture.count++; + EXTI_ClearITPendingBit(INTMODULE_HEARTBEAT_EXTI_LINE); + } +} +#endif + +#if defined(INTMDULE_HEARTBEAT) && !defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER) +extern "C" void INTMODULE_HEARTBEAT_EXTI_IRQHandler() +{ + check_xjt_heartbeat(); +} +#endif 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 f6a47d071..6e763f058 100644 --- a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp @@ -90,6 +90,10 @@ extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void) EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE2); } #endif + +#if !defined(BOOT) && defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER) + check_xjt_heartbeat(); +#endif } #if defined(ROTARY_ENCODER_EXTI_IRQn2) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 49fab6b59..11361676a 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -626,8 +626,9 @@ // Heartbeat (not used) #define TRAINER_MODULE_RCC_AHB1Periph RCC_AHB1Periph_GPIOD -#define HEARTBEAT_GPIO GPIOD -#define HEARTBEAT_GPIO_PIN GPIO_Pin_12 // PD.12 +#define INTMODULE_HEARTBEAT_GPIO GPIOD +#define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_12 // PD.12 +#define INTMODULE_HEARTBEAT_TRIGGER EXTI_Trigger_Falling // Trainer Port #define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA1) diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index d12997904..aca21c142 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -255,6 +255,7 @@ set(TARGET_SRC trainer_driver.cpp ../common/arm/stm32/audio_dac_driver.cpp ../common/arm/stm32/adc_driver.cpp + ../common/arm/stm32/heartbeat_driver.cpp ) if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index cb28e03f6..b8f408b3c 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -362,14 +362,15 @@ void checkTrainerSettings() stop_trainer_ppm(); break; case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: - stop_trainer_module_cppm() ; + stop_trainer_module_cppm(); break; case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: - stop_trainer_module_sbus() ; + stop_trainer_module_sbus(); break; #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: auxSerialStop(); + break; #endif } @@ -397,6 +398,11 @@ void checkTrainerSettings() init_trainer_capture(); break; } + + if (requiredTrainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE || requiredTrainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE) + stop_intmodule_heartbeat(); + else + init_intmodule_heartbeat(); } } diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index fa3b32f8b..671677dfc 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -270,6 +270,16 @@ void extmoduleSendNextFrame(); #define stop_trainer_module_sbus() #endif +#if defined(INTMODULE_HEARTBEAT_GPIO) +void init_intmodule_heartbeat(); +void stop_intmodule_heartbeat(); +void check_xjt_heartbeat(); +#else +#define init_intmodule_heartbeat() +#define stop_intmodule_heartbeat() +#define check_xjt_heartbeat() +#endif + // SBUS int sbusGetByte(uint8_t * byte); diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index e3dcb417f..fdd72ca59 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1164,36 +1164,80 @@ #define SPORT_UPDATE_RCC_AHB1Periph 0 #endif -// Heartbeat for XJT synchro -#if defined(PCBXLITE) || defined(PCBX9LITE) - #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD - #define HEARTBEAT_GPIO GPIOD - #define HEARTBEAT_GPIO_PIN GPIO_Pin_15 - #define HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOD - #define HEARTBEAT_EXTI_PinSource GPIO_PinSource15 - #define HEARTBEAT_EXTI_LINE EXTI_Line15 - #define HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn - #define HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler +#if defined(PCBXLITES) || defined(PCBX9LITE) + #define INTMODULE_HEARTBEAT_TRIGGER EXTI_Trigger_Rising #else - #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC - #define HEARTBEAT_GPIO GPIOC - #define HEARTBEAT_GPIO_PIN GPIO_Pin_7 - #define HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOC - #define HEARTBEAT_EXTI_PinSource GPIO_PinSource7 - #define HEARTBEAT_EXTI_LINE EXTI_Line7 - #define HEARTBEAT_EXTI_IRQn EXTI9_5_IRQn - #define HEARTBEAT_EXTI_IRQHandler EXTI9_5_IRQHandler + #define INTMODULE_HEARTBEAT_TRIGGER EXTI_Trigger_Falling +#endif + +// Heartbeat for iXJT / ISRM synchro +#if defined(PCBXLITE) + #define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD + #define INTMODULE_HEARTBEAT_GPIO GPIOD + #define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_15 + #define INTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOD + #define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource15 + #define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line15 + #define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI15_10_IRQn + #define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI15_10_IRQHandler +#elif defined(PCBX9LITE) + #define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC + // #define INTMODULE_HEARTBEAT_GPIO GPIOC + // #define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_9 + #define INTMODULE_HEARTBEAT_EXTI_PortSource EXTI_PortSourceGPIOC + #define INTMODULE_HEARTBEAT_EXTI_PinSource GPIO_PinSource9 + #define INTMODULE_HEARTBEAT_EXTI_LINE EXTI_Line9 + #define INTMODULE_HEARTBEAT_EXTI_IRQn EXTI9_5_IRQn + #define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI9_5_IRQHandler +#elif defined(RADIO_X7) + #define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER + #define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC + #define INTMODULE_HEARTBEAT_GPIO GPIOC + #define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_7 + #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 +#else + #define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC + #define INTMODULE_HEARTBEAT_GPIO GPIOC + #define INTMODULE_HEARTBEAT_GPIO_PIN GPIO_Pin_7 + #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 + #define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI9_5_IRQHandler +#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 // Trainer / Trainee from the module bay -#if defined(PCBXLITE) || defined(PCBX9LITE) +#if defined(PCBX9LITE) #define TRAINER_MODULE_CPPM - #define TRAINER_MODULE_RCC_AHB1Periph RCC_AHB1Periph_GPIOD + #define TRAINER_MODULE_RCC_AHB1Periph EXTMODULE_HEARTBEAT_RCC_AHB1Periph #define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM4 #define TRAINER_MODULE_RCC_APB2Periph 0 - #define TRAINER_MODULE_CPPM_GPIO HEARTBEAT_GPIO - #define TRAINER_MODULE_CPPM_GPIO_PIN HEARTBEAT_GPIO_PIN - #define TRAINER_MODULE_CPPM_GPIO_PinSource GPIO_PinSource15 + #define TRAINER_MODULE_CPPM_GPIO EXTMODULE_HEARTBEAT_GPIO + #define TRAINER_MODULE_CPPM_GPIO_PIN EXTMODULE_HEARTBEAT_GPIO_PIN + #define TRAINER_MODULE_CPPM_GPIO_PinSource EXTMODULE_HEARTBEAT_EXTI_PinSource + #define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM4 +#elif defined(PCBXLITE) + #define TRAINER_MODULE_CPPM + #define TRAINER_MODULE_RCC_AHB1Periph INTMODULE_HEARTBEAT_RCC_AHB1Periph + #define TRAINER_MODULE_RCC_APB1Periph RCC_APB1Periph_TIM4 + #define TRAINER_MODULE_RCC_APB2Periph 0 + #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_GPIO_AF GPIO_AF_TIM4 #else #define TRAINER_MODULE_CPPM @@ -1201,9 +1245,9 @@ #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_GPIO HEARTBEAT_GPIO - #define TRAINER_MODULE_CPPM_GPIO_PIN HEARTBEAT_GPIO_PIN - #define TRAINER_MODULE_CPPM_GPIO_PinSource GPIO_PinSource7 + #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_SBUS_GPIO_AF GPIO_AF_USART6 #define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3 #define TRAINER_MODULE_SBUS_USART USART6 diff --git a/radio/src/targets/taranis/intmodule_pulses_driver.cpp b/radio/src/targets/taranis/intmodule_pulses_driver.cpp index 67ba6490a..044883034 100644 --- a/radio/src/targets/taranis/intmodule_pulses_driver.cpp +++ b/radio/src/targets/taranis/intmodule_pulses_driver.cpp @@ -20,8 +20,6 @@ #include "opentx.h" -extern volatile uint32_t HeartbeatCapture; - void intmoduleStop() { INTERNAL_MODULE_OFF(); @@ -34,17 +32,27 @@ void intmoduleStop() INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; } +#if defined(DEBUG_LATENCY) +#define HEARBEAT_OFFSET unsigned(5500 + g_model.flightModeData[0].gvars[0] * 100) +#else +constexpr int HEARBEAT_OFFSET = 5500; +#endif + void intmoduleSendNextFrame() { switch (moduleState[INTERNAL_MODULE].protocol) { #if defined(PXX1) case PROTOCOL_CHANNELS_PXX1_PULSES: { -#if 0 - // TODO this will be needed if we want to use HEARTBEAT for synchro with the module - INTMODULE_TIMER->ARR = TIMER_2MHz_TIMER->CNT - HeartbeatCapture > 0x2A00 ? 17979 : 18019; -#endif - INTMODULE_TIMER->CCR2 = intmodulePulsesData.pxx.getLast() - 4000; // 2mS in advance + uint32_t last = intmodulePulsesData.pxx.getLast(); + if (heartbeatCapture.valid) { + if (TIMER_2MHz_TIMER->CNT - heartbeatCapture.timestamp > HEARBEAT_OFFSET) + last -= 21; + else + last += 19; + intmodulePulsesData.pxx.setLast(last); + } + INTMODULE_TIMER->CCR2 = last - 4000; // 2mS in advance INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA INTMODULE_DMA_STREAM->CR |= INTMODULE_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; INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR); diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index fef2cd705..e1a0f5e58 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -134,17 +134,28 @@ TASK_FUNCTION(mixerTask) uint32_t now = RTOS_GET_MS(); bool run = false; - if ((now - lastRunTime) >= 10) { // run at least every 10ms + + if ((now - lastRunTime) >= 10) { + // run at least every 10ms run = true; } - else if (now == nextMixerTime[0]) { - run = true; - } -#if NUM_MODULES >= 2 - else if (now == nextMixerTime[1]) { + +#if defined(PXX2) && defined(INTMDULE_HEARTBEAT) + if (moduleState[0].protocol == PROTOCOL_CHANNELS_PXX2 && heartbeatCapture.valid && heartbeatCapture.timestamp > lastRunTime) { run = true; } #endif + + if (now == nextMixerTime[0]) { + run = true; + } + +#if NUM_MODULES >= 2 + if (now == nextMixerTime[1]) { + run = true; + } +#endif + if (!run) { continue; // go back to sleep } diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 510784628..7b4395a4c 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -210,7 +210,7 @@ const char STR_TX[] = TR_TXnRX; const char STR_NODATA[] = TR_NODATA; const char STR_US[] = TR_US; const char STR_TMIXMAXMS[] = TR_TMIXMAXMS; -const char STR_FREESTACKMINB[] = TR_FREESTACKMINB; +const char STR_FREE_STACK[] = TR_FREE_STACK; const char STR_MENUTORESET[] = TR_MENUTORESET; const char STR_PPM_TRAINER[] = TR_PPM_TRAINER; const char STR_CH[] = TR_CH; diff --git a/radio/src/translations.h b/radio/src/translations.h index 660f67ffb..94ed6eb6e 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -333,7 +333,7 @@ extern const char STR_TX[]; extern const char STR_NODATA[]; extern const char STR_US[]; extern const char STR_TMIXMAXMS[]; -extern const char STR_FREESTACKMINB[]; +extern const char STR_FREE_STACK[]; extern const char STR_MENUTORESET[]; extern const char STR_PPM_TRAINER[]; extern const char STR_CH[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index f79d94dd6..1f19fff1f 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -639,7 +639,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER" >> Reset" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 6d1648cf4..b471bdd1a 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -648,7 +648,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Freier Stack" +#define TR_FREE_STACK "Freier Stack" #define TR_MENUTORESET CENTER TR_ENTER " für Reset" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 9e172328e..fae6870a8 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -643,7 +643,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER " to reset" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index a3523e951..86d0d786c 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -653,7 +653,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER "Resetear" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 207108140..cbf41d2b4 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -646,7 +646,7 @@ #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" - #define TR_FREESTACKMINB "Free Stack" + #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER " to reset" #define TR_PPM_TRAINER "TR" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index b7cae5c22..3a1784f20 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -657,7 +657,7 @@ #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" - #define TR_FREESTACKMINB "Free Stack" + #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER" pour reset" #define TR_PPM_TRAINER "TR" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 7ed855d65..7ef942227 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -656,7 +656,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER" x Azzerare" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index db97f53de..f1738dffb 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -642,7 +642,7 @@ TR_GYR_VSRCRAW #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER" voor Reset" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index ecf743049..f6e706992 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -656,7 +656,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "TmixMaks" -#define TR_FREESTACKMINB "Wolny stos" +#define TR_FREE_STACK "Wolny stos" #define TR_MENUTORESET CENTER TR_ENTER " >> Reset" #define TR_PPM_TRAINER "TR" #define TR_CH "KN" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index ab88e12c0..334105849 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -638,7 +638,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER" Reinicia" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 92bb9311c..f049c5326 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -655,7 +655,7 @@ #define TR_US "us" #define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" -#define TR_FREESTACKMINB "Free Stack" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET CENTER TR_ENTER " Nollar" #define TR_PPM_TRAINER "TR" #define TR_CH "KN"