mirror of
https://github.com/opentx/opentx.git
synced 2025-07-13 19:40:20 +03:00
Fixes #2579: Added support for Trainer signal alarm
- added alarm “Trainer signal lost” & “Trainer signal recovered”. - moved PPM capture code to trainer_input.{h,cpp}
This commit is contained in:
parent
3d461b771f
commit
f6bff9683d
12 changed files with 185 additions and 78 deletions
|
@ -1058,7 +1058,7 @@ ifeq ($(GUI), YES)
|
|||
CPPDEFS += -DGUI
|
||||
endif
|
||||
|
||||
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC) timers.cpp
|
||||
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC) timers.cpp trainer_input.cpp
|
||||
|
||||
ifeq ($(GUI), YES)
|
||||
GUISRC += gui/$(GUIDIRECTORY)/lcd.cpp gui/$(GUIDIRECTORY)/splash.cpp gui/$(GUIDIRECTORY)/fonts.cpp
|
||||
|
|
|
@ -169,6 +169,8 @@ const char * const audioFilenames[] = {
|
|||
"swr_red",
|
||||
"telemko",
|
||||
"telemok",
|
||||
"trainko",
|
||||
"trainok",
|
||||
#if defined(PCBSKY9X)
|
||||
"highmah",
|
||||
"hightemp",
|
||||
|
|
|
@ -331,6 +331,8 @@ void audioStart();
|
|||
#define AUDIO_RXBATT_RED() audioEvent(AU_RXBATT_RED)
|
||||
#define AUDIO_TELEMETRY_LOST() audioEvent(AU_TELEMETRY_LOST)
|
||||
#define AUDIO_TELEMETRY_BACK() audioEvent(AU_TELEMETRY_BACK)
|
||||
#define AUDIO_TRAINER_LOST() audioEvent(AU_TRAINER_LOST)
|
||||
#define AUDIO_TRAINER_BACK() audioEvent(AU_TRAINER_BACK)
|
||||
|
||||
#define AUDIO_HEARTBEAT()
|
||||
|
||||
|
|
|
@ -455,7 +455,7 @@ void evalInputs(uint8_t mode)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (mode <= e_perout_mode_inactive_flight_mode && isFunctionActive(FUNCTION_TRAINER+ch) && ppmInValid) {
|
||||
if (mode <= e_perout_mode_inactive_flight_mode && isFunctionActive(FUNCTION_TRAINER+ch) && IS_TRAINER_INPUT_VALID()) {
|
||||
// trainer mode
|
||||
TrainerMix* td = &g_eeGeneral.trainer.mix[ch];
|
||||
if (td->mode) {
|
||||
|
@ -662,7 +662,7 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
|
|||
|
||||
#define MIXER_LINE_DISABLE() (mixCondition = true, mixEnabled = 0)
|
||||
|
||||
if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_TRAINER && md->srcRaw <= MIXSRC_LAST_TRAINER && !ppmInValid) {
|
||||
if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_TRAINER && md->srcRaw <= MIXSRC_LAST_TRAINER && !IS_TRAINER_INPUT_VALID()) {
|
||||
MIXER_LINE_DISABLE();
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ void per10ms()
|
|||
#endif
|
||||
|
||||
if (trimsCheckTimer) trimsCheckTimer--;
|
||||
if (ppmInValid) ppmInValid--;
|
||||
if (g_ppmInputValidityTimer) g_ppmInputValidityTimer--;
|
||||
|
||||
#if defined(CPUARM)
|
||||
if (trimsDisplayTimer)
|
||||
|
@ -1714,6 +1714,7 @@ void doMixerCalculations()
|
|||
s_cnt_1s += 1;
|
||||
|
||||
logicalSwitchesTimerTick();
|
||||
checkTrainerSignalWarning();
|
||||
|
||||
if (s_cnt_1s >= 10) { // 1sec
|
||||
s_cnt_1s -= 10;
|
||||
|
@ -2068,10 +2069,6 @@ void checkBattery()
|
|||
}
|
||||
}
|
||||
|
||||
int16_t g_ppmIns[NUM_TRAINER];
|
||||
uint8_t ppmInState = 0; // 0=unsync 1..8= wait for value i-1
|
||||
uint8_t ppmInValid = 0;
|
||||
|
||||
#if !defined(SIMU) && !defined(CPUARM)
|
||||
|
||||
volatile uint8_t g_tmr16KHz; //continuous timer 16ms (16MHz/1024/256) -- 8-bit counter overflow
|
||||
|
@ -2153,26 +2150,7 @@ ISR(TIMER3_CAPT_vect) // G: High frequency noise can cause stack overflo with IS
|
|||
PAUSE_PPMIN_INTERRUPT();
|
||||
sei(); // enable other interrupts
|
||||
|
||||
uint16_t val = (capture - lastCapt) / 2;
|
||||
|
||||
// G: We process g_ppmIns immediately here, to make servo movement as smooth as possible
|
||||
// while under trainee control
|
||||
if (val>4000 && val < 16000) { // G: Prioritize reset pulse. (Needed when less than 8 incoming pulses)
|
||||
ppmInState = 1; // triggered
|
||||
}
|
||||
else {
|
||||
if (ppmInState>0 && ppmInState<=8) {
|
||||
if (val>800 && val<2200) { // if valid pulse-width range
|
||||
ppmInValid = PPM_IN_VALID_TIMEOUT;
|
||||
g_ppmIns[ppmInState++ - 1] = (int16_t)(val - 1500) * (uint8_t)(g_eeGeneral.PPM_Multiplier+10)/10; //+-500 != 512, but close enough.
|
||||
}
|
||||
else {
|
||||
ppmInState = 0; // not triggered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastCapt = capture;
|
||||
captureTrainerPulses(capture);
|
||||
|
||||
cli(); // disable other interrupts for stack pops before this function's RETI
|
||||
RESUME_PPMIN_INTERRUPT();
|
||||
|
|
|
@ -1127,10 +1127,8 @@ extern uint8_t g_vbat100mV;
|
|||
extern uint8_t g_beepCnt;
|
||||
extern uint8_t g_beepVal[5];
|
||||
|
||||
extern uint8_t ppmInState; //0=unsync 1..8= wait for value i-1
|
||||
extern uint8_t ppmInValid;
|
||||
#define PPM_IN_VALID_TIMEOUT 100
|
||||
extern int16_t g_ppmIns[NUM_TRAINER];
|
||||
#include "trainer_input.h"
|
||||
|
||||
extern int32_t chans[NUM_CHNOUT];
|
||||
extern int16_t ex_chans[NUM_CHNOUT]; // Outputs (before LIMITS) of the last perMain
|
||||
extern int16_t channelOutputs[NUM_CHNOUT];
|
||||
|
@ -1392,6 +1390,8 @@ enum AUDIO_SOUNDS {
|
|||
AU_SWR_RED,
|
||||
AU_TELEMETRY_LOST,
|
||||
AU_TELEMETRY_BACK,
|
||||
AU_TRAINER_LOST,
|
||||
AU_TRAINER_BACK,
|
||||
#endif
|
||||
#if defined(PCBSKY9X)
|
||||
AU_TX_MAH_HIGH,
|
||||
|
|
|
@ -87,7 +87,7 @@ void processSbusFrame(uint8_t *sbus, int16_t *pulses, uint32_t size)
|
|||
inputbits >>= SBUS_CH_BITS;
|
||||
}
|
||||
|
||||
ppmInValid = PPM_IN_VALID_TIMEOUT;
|
||||
g_ppmInputValidityTimer = PPM_IN_VALID_TIMEOUT;
|
||||
}
|
||||
|
||||
void processSbusInput()
|
||||
|
|
|
@ -248,31 +248,10 @@ void start_timer4()
|
|||
|
||||
extern "C" void TC3_IRQHandler() //capture ppm in at 2MHz
|
||||
{
|
||||
static uint16_t lastCapt ;
|
||||
|
||||
uint16_t capture = TC1->TC_CHANNEL[0].TC_RA ;
|
||||
(void) TC1->TC_CHANNEL[0].TC_SR ; // Acknowledge the interrupt
|
||||
|
||||
uint16_t val = ((uint16_t)(capture - lastCapt)) / 2;
|
||||
|
||||
// G: We process g_ppmIns immediately here, to make servo movement as smooth as possible
|
||||
// while under trainee control
|
||||
if (val>4000 && val<19000) { // G: Prioritize reset pulse. (Needed when less than 16 incoming pulses)
|
||||
ppmInState = 1; // triggered
|
||||
}
|
||||
else {
|
||||
if (ppmInState>0 && ppmInState<=16) {
|
||||
if (val>800 && val<2200) { // if valid pulse-width range
|
||||
ppmInValid = PPM_IN_VALID_TIMEOUT;
|
||||
g_ppmIns[ppmInState++ - 1] = (int16_t)(val - 1500)*(g_eeGeneral.PPM_Multiplier+10)/10; //+-500 != 512, but close enough.
|
||||
}
|
||||
else {
|
||||
ppmInState = 0; // not triggered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastCapt = capture;
|
||||
captureTrainerPulses(capture);
|
||||
}
|
||||
|
||||
void init_trainer_capture()
|
||||
|
|
|
@ -121,8 +121,6 @@ void stop_trainer_capture()
|
|||
extern "C" void TIM3_IRQHandler()
|
||||
{
|
||||
uint16_t capture = 0;
|
||||
static uint16_t lastCapt ;
|
||||
uint16_t val ;
|
||||
bool doCapture = false ;
|
||||
|
||||
// What mode? in or out?
|
||||
|
@ -139,25 +137,7 @@ extern "C" void TIM3_IRQHandler()
|
|||
}
|
||||
|
||||
if (doCapture) {
|
||||
val = (uint16_t)(capture - lastCapt) / 2 ;
|
||||
lastCapt = capture;
|
||||
|
||||
// We process g_ppmInsright here to make servo movement as smooth as possible
|
||||
// while under trainee control
|
||||
if (val>4000 && val<19000) { // G: Prioritize reset pulse. (Needed when less than 16 incoming pulses)
|
||||
ppmInState = 1; // triggered
|
||||
}
|
||||
else {
|
||||
if (ppmInState>0 && ppmInState<=16) {
|
||||
if (val>800 && val<2200) {
|
||||
ppmInValid = PPM_IN_VALID_TIMEOUT;
|
||||
g_ppmIns[ppmInState++ - 1] = (int16_t)(val - 1500)*(g_eeGeneral.PPM_Multiplier+10)/10; //+-500 != 512, but close enough.
|
||||
}
|
||||
else {
|
||||
ppmInState = 0; // not triggered
|
||||
}
|
||||
}
|
||||
}
|
||||
captureTrainerPulses(capture);
|
||||
}
|
||||
|
||||
// PPM out compare interrupt
|
||||
|
|
69
radio/src/trainer_input.cpp
Normal file
69
radio/src/trainer_input.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* 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 "trainer_input.h"
|
||||
|
||||
int16_t g_ppmIns[NUM_TRAINER];
|
||||
uint8_t g_ppmInputValidityTimer;
|
||||
|
||||
|
||||
#if defined(CPUARM)
|
||||
#include "audio_arm.h"
|
||||
|
||||
void checkTrainerSignalWarning()
|
||||
{
|
||||
enum PpmInValidState_t {
|
||||
PPM_IN_IS_NOT_USED=0,
|
||||
PPM_IN_IS_VALID,
|
||||
PPM_IN_INVALID
|
||||
};
|
||||
|
||||
static uint8_t ppmInputValidState = PPM_IN_IS_NOT_USED;
|
||||
|
||||
if(g_ppmInputValidityTimer && (ppmInputValidState == PPM_IN_IS_NOT_USED)) {
|
||||
ppmInputValidState = PPM_IN_IS_VALID;
|
||||
}
|
||||
else if (!g_ppmInputValidityTimer && (ppmInputValidState == PPM_IN_IS_VALID)) {
|
||||
ppmInputValidState = PPM_IN_INVALID;
|
||||
AUDIO_TRAINER_LOST();
|
||||
}
|
||||
else if (g_ppmInputValidityTimer && (ppmInputValidState == PPM_IN_INVALID)) {
|
||||
ppmInputValidState = PPM_IN_IS_VALID;
|
||||
AUDIO_TRAINER_BACK();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
89
radio/src/trainer_input.h
Normal file
89
radio/src/trainer_input.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef trainer_input_h
|
||||
#define trainer_input_h
|
||||
|
||||
#include "myeeprom.h"
|
||||
|
||||
// Trainer input channels
|
||||
extern int16_t g_ppmIns[NUM_TRAINER];
|
||||
|
||||
// Timer gets decremented in per10ms()
|
||||
#define PPM_IN_VALID_TIMEOUT 100 // 1s
|
||||
extern uint8_t g_ppmInputValidityTimer;
|
||||
|
||||
#define IS_TRAINER_INPUT_VALID() (g_ppmInputValidityTimer != 0)
|
||||
|
||||
#if defined(CPUARM)
|
||||
void checkTrainerSignalWarning();
|
||||
#else
|
||||
#define checkTrainerSignalWarning()
|
||||
#endif
|
||||
|
||||
// Needs to be inlined to avoid slow function calls in ISR routines
|
||||
inline void captureTrainerPulses(uint16_t capture)
|
||||
{
|
||||
static uint16_t lastCapt=0;
|
||||
static uint8_t channelNumber=0;
|
||||
|
||||
uint16_t val = (uint16_t)(capture - lastCapt) / 2;
|
||||
lastCapt = capture;
|
||||
|
||||
// We process g_ppmInsright here to make servo movement as smooth as possible
|
||||
// while under trainee control
|
||||
//
|
||||
// G: Prioritize reset pulse. (Needed when less than 16 incoming pulses)
|
||||
//
|
||||
if (val>4000 && val<19000) {
|
||||
channelNumber = 1; // triggered
|
||||
}
|
||||
else {
|
||||
if ((channelNumber > 0) && (channelNumber <= NUM_TRAINER)) {
|
||||
if (val>800 && val<2200) {
|
||||
g_ppmInputValidityTimer = PPM_IN_VALID_TIMEOUT;
|
||||
g_ppmIns[channelNumber++ - 1] =
|
||||
//+-500 != 512, but close enough.
|
||||
(int16_t)(val - 1500)*(g_eeGeneral.PPM_Multiplier+10)/10;
|
||||
}
|
||||
else {
|
||||
channelNumber = 0; // not triggered
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -186,6 +186,8 @@ def ttsEn():
|
|||
(u"radio antenna defective", "swr_red", NO_ALTERNATE),
|
||||
(u"telemetry lost", "telemko", NO_ALTERNATE),
|
||||
(u"telemetry recovered", "telemok", NO_ALTERNATE),
|
||||
(u"trainer signal lost", "trainko", NO_ALTERNATE),
|
||||
(u"trainer signal recovered", "trainok", NO_ALTERNATE),
|
||||
]:
|
||||
systemSounds.append((s, filename(f, a)))
|
||||
for i, (s, f) in enumerate([
|
||||
|
@ -282,6 +284,8 @@ def ttsFr():
|
|||
(u"Antenne défectueuse", "swr_red", NO_ALTERNATE),
|
||||
(u"Plus de télémétrie", "telemko", NO_ALTERNATE),
|
||||
(u"Télémétrie retrouvée", "telemok", NO_ALTERNATE),
|
||||
(u"Signal écolage perdu", "trainko", NO_ALTERNATE),
|
||||
(u"Signal écolage retrouvé", "trainok", NO_ALTERNATE),
|
||||
]:
|
||||
systemSounds.append((s, filename(f, a)))
|
||||
for i, (s, f) in enumerate([
|
||||
|
@ -599,6 +603,10 @@ def ttsDe():
|
|||
(u"Funksignal schlecht!", "rssi_org", NO_ALTERNATE),
|
||||
(u"Funksignal kritisch!", "rssi_red", NO_ALTERNATE),
|
||||
(u"Problem mit der sender Antenna", "swr_red", NO_ALTERNATE),
|
||||
(u"Telemetrie verloren", "telemko", NO_ALTERNATE),
|
||||
(u"Telemetrie wiederhergestellt", "telemok", NO_ALTERNATE),
|
||||
(u"Schülersignal verloren", "trainko", NO_ALTERNATE),
|
||||
(u"Schülersignal wiederhergestellt", "trainok", NO_ALTERNATE),
|
||||
]:
|
||||
systemSounds.append((s, filename(f, a)))
|
||||
for i, s in enumerate(["Timer", "Timer", "Sendung", "Empfang", "A1", "A2", "Hoehe", "Motor",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue