mirror of
https://github.com/opentx/opentx.git
synced 2025-07-23 16:25:16 +03:00
Fixes #2009: Timer Voice minute call not working for persistent timers
Timers moved to timer.cpp Added timer overflow protection Added timer gtests THt mode now triggers on THR>10%
This commit is contained in:
parent
76937ea566
commit
afc41f082e
25 changed files with 4001 additions and 3563 deletions
|
@ -15,13 +15,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "inttypes.h"
|
#include <inttypes.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
#include "file.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "eeprominterface.h"
|
#include "eeprominterface.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
RleFile::RleFile():
|
RleFile::RleFile():
|
||||||
eeprom(NULL),
|
eeprom(NULL),
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace Open9xGruvin9x {
|
||||||
#include "radio/src/functions.cpp"
|
#include "radio/src/functions.cpp"
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/pulses/pulses_avr.cpp"
|
#include "radio/src/pulses/pulses_avr.cpp"
|
||||||
#include "radio/src/stamp.cpp"
|
#include "radio/src/stamp.cpp"
|
||||||
#include "radio/src/maths.cpp"
|
#include "radio/src/maths.cpp"
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace OpenTxM128 {
|
||||||
#include "radio/src/functions.cpp"
|
#include "radio/src/functions.cpp"
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/pulses/pulses_avr.cpp"
|
#include "radio/src/pulses/pulses_avr.cpp"
|
||||||
#include "radio/src/stamp.cpp"
|
#include "radio/src/stamp.cpp"
|
||||||
#include "radio/src/maths.cpp"
|
#include "radio/src/maths.cpp"
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace OpenTxM64 {
|
||||||
#include "radio/src/functions.cpp"
|
#include "radio/src/functions.cpp"
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/pulses/pulses_avr.cpp"
|
#include "radio/src/pulses/pulses_avr.cpp"
|
||||||
#include "radio/src/stamp.cpp"
|
#include "radio/src/stamp.cpp"
|
||||||
#include "radio/src/maths.cpp"
|
#include "radio/src/maths.cpp"
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace Open9xSky9x {
|
||||||
#include "radio/src/switches.cpp"
|
#include "radio/src/switches.cpp"
|
||||||
#include "radio/src/functions.cpp"
|
#include "radio/src/functions.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/targets/sky9x/pulses_driver.cpp"
|
#include "radio/src/targets/sky9x/pulses_driver.cpp"
|
||||||
#include "radio/src/pulses/pulses_arm.cpp"
|
#include "radio/src/pulses/pulses_arm.cpp"
|
||||||
|
|
|
@ -87,6 +87,7 @@ inline int geteepromsize() {
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
#include "radio/src/sdcard.cpp"
|
#include "radio/src/sdcard.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/targets/taranis/pulses_driver.cpp"
|
#include "radio/src/targets/taranis/pulses_driver.cpp"
|
||||||
#include "radio/src/targets/taranis/rtc_driver.cpp"
|
#include "radio/src/targets/taranis/rtc_driver.cpp"
|
||||||
#include "radio/src/targets/taranis/trainer_driver.cpp"
|
#include "radio/src/targets/taranis/trainer_driver.cpp"
|
||||||
|
|
|
@ -88,6 +88,7 @@ inline int geteepromsize() {
|
||||||
#include "radio/src/curves.cpp"
|
#include "radio/src/curves.cpp"
|
||||||
#include "radio/src/mixer.cpp"
|
#include "radio/src/mixer.cpp"
|
||||||
#include "radio/src/sdcard.cpp"
|
#include "radio/src/sdcard.cpp"
|
||||||
|
#include "radio/src/timers.cpp"
|
||||||
#include "radio/src/targets/taranis/pulses_driver.cpp"
|
#include "radio/src/targets/taranis/pulses_driver.cpp"
|
||||||
#include "radio/src/targets/taranis/rtc_driver.cpp"
|
#include "radio/src/targets/taranis/rtc_driver.cpp"
|
||||||
#include "radio/src/targets/taranis/rotenc_driver.cpp"
|
#include "radio/src/targets/taranis/rotenc_driver.cpp"
|
||||||
|
|
|
@ -954,7 +954,7 @@ ifeq ($(GUI), YES)
|
||||||
CPPDEFS += -DGUI
|
CPPDEFS += -DGUI
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC)
|
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC) timers.cpp
|
||||||
|
|
||||||
ifeq ($(GUI), YES)
|
ifeq ($(GUI), YES)
|
||||||
GUISRC += gui/$(GUIDIRECTORY)/lcd.cpp gui/$(GUIDIRECTORY)/splash.cpp gui/$(GUIDIRECTORY)/fonts.cpp
|
GUISRC += gui/$(GUIDIRECTORY)/lcd.cpp gui/$(GUIDIRECTORY)/splash.cpp gui/$(GUIDIRECTORY)/fonts.cpp
|
||||||
|
|
|
@ -285,7 +285,7 @@ const struct TraceElement * getTraceElement(uint16_t idx)
|
||||||
|
|
||||||
void dumpTraceBuffer()
|
void dumpTraceBuffer()
|
||||||
{
|
{
|
||||||
TRACE("Dump of Trace Buffer ("VERS_STR " " DATE_STR " " TIME_STR "):");
|
TRACE("Dump of Trace Buffer (" VERS_STR " " DATE_STR " " TIME_STR "):");
|
||||||
TRACE("# Time Event Data");
|
TRACE("# Time Event Data");
|
||||||
for(int n = 0; n < TRACE_BUFFER_LEN; ++n) {
|
for(int n = 0; n < TRACE_BUFFER_LEN; ++n) {
|
||||||
struct gtm tp;
|
struct gtm tp;
|
||||||
|
|
|
@ -35,9 +35,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "inttypes.h"
|
#include "timers.h"
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
uint8_t s_eeDirtyMsk;
|
uint8_t s_eeDirtyMsk;
|
||||||
tmr10ms_t s_eeDirtyTime10ms;
|
tmr10ms_t s_eeDirtyTime10ms;
|
||||||
|
|
|
@ -35,9 +35,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "inttypes.h"
|
#include "timers.h"
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
volatile uint32_t Spi_complete; // TODO in the driver ?
|
volatile uint32_t Spi_complete; // TODO in the driver ?
|
||||||
|
|
||||||
|
@ -396,11 +397,7 @@ void eeLoadModel(uint8_t id)
|
||||||
|
|
||||||
customFunctionsReset();
|
customFunctionsReset();
|
||||||
|
|
||||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
restoreTimers();
|
||||||
if (g_model.timers[i].persistent) {
|
|
||||||
timersStates[i].val = g_model.timers[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resumeMixerCalculations();
|
resumeMixerCalculations();
|
||||||
// TODO pulses should be started after mixer calculations ...
|
// TODO pulses should be started after mixer calculations ...
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "inttypes.h"
|
#include "timers.h"
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
uint8_t s_write_err = 0; // error reasons
|
uint8_t s_write_err = 0; // error reasons
|
||||||
RlcFile theFile; //used for any file operation
|
RlcFile theFile; //used for any file operation
|
||||||
|
@ -985,13 +986,7 @@ void eeLoadModel(uint8_t id)
|
||||||
|
|
||||||
customFunctionsReset();
|
customFunctionsReset();
|
||||||
|
|
||||||
#if !defined(PCBSTD)
|
restoreTimers();
|
||||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
|
||||||
if (g_model.timers[i].persistent) {
|
|
||||||
timersStates[i].val = g_model.timers[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CPUARM)
|
#if defined(CPUARM)
|
||||||
for (int i=0; i<TELEM_VALUES_MAX; i++) {
|
for (int i=0; i<TELEM_VALUES_MAX; i++) {
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
CustomFunctionsContext modelFunctionsContext = { 0 };
|
CustomFunctionsContext modelFunctionsContext = { 0 };
|
||||||
|
|
||||||
|
@ -359,10 +360,7 @@ void evalFunctions()
|
||||||
#if defined(CPUARM)
|
#if defined(CPUARM)
|
||||||
case FUNC_SET_TIMER:
|
case FUNC_SET_TIMER:
|
||||||
{
|
{
|
||||||
TimerState & timerState = timersStates[CFN_TIMER_INDEX(cfn)];
|
timerSet(CFN_TIMER_INDEX(cfn), CFN_PARAM(cfn));
|
||||||
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
|
||||||
timerState.val = CFN_PARAM(cfn);
|
|
||||||
timerState.val_10ms = 0 ;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,224 +1,225 @@
|
||||||
/*
|
/*
|
||||||
* Authors (alphabetical order)
|
* Authors (alphabetical order)
|
||||||
* - Andre Bernet <bernet.andre@gmail.com>
|
* - Andre Bernet <bernet.andre@gmail.com>
|
||||||
* - Andreas Weitl
|
* - Andreas Weitl
|
||||||
* - Bertrand Songis <bsongis@gmail.com>
|
* - Bertrand Songis <bsongis@gmail.com>
|
||||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||||
* - Cameron Weeks <th9xer@gmail.com>
|
* - Cameron Weeks <th9xer@gmail.com>
|
||||||
* - Erez Raviv
|
* - Erez Raviv
|
||||||
* - Gabriel Birkus
|
* - Gabriel Birkus
|
||||||
* - Jean-Pierre Parisy
|
* - Jean-Pierre Parisy
|
||||||
* - Karl Szmutny
|
* - Karl Szmutny
|
||||||
* - Michael Blandford
|
* - Michael Blandford
|
||||||
* - Michal Hlavinka
|
* - Michal Hlavinka
|
||||||
* - Pat Mackenzie
|
* - Pat Mackenzie
|
||||||
* - Philip Moss
|
* - Philip Moss
|
||||||
* - Rob Thomson
|
* - Rob Thomson
|
||||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||||
* - Thomas Husterer
|
* - Thomas Husterer
|
||||||
*
|
*
|
||||||
* opentx is based on code named
|
* opentx is based on code named
|
||||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||||
* and the original (and ongoing) project by
|
* and the original (and ongoing) project by
|
||||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../opentx.h"
|
#include "../../opentx.h"
|
||||||
|
#include "../../timers.h"
|
||||||
void menuStatisticsView(uint8_t event)
|
|
||||||
{
|
void menuStatisticsView(uint8_t event)
|
||||||
TITLE(STR_MENUSTAT);
|
{
|
||||||
|
TITLE(STR_MENUSTAT);
|
||||||
switch(event)
|
|
||||||
{
|
switch(event)
|
||||||
case EVT_KEY_FIRST(KEY_UP):
|
{
|
||||||
chainMenu(menuStatisticsDebug);
|
case EVT_KEY_FIRST(KEY_UP):
|
||||||
break;
|
chainMenu(menuStatisticsDebug);
|
||||||
|
break;
|
||||||
#if defined(CPUARM)
|
|
||||||
case EVT_KEY_LONG(KEY_MENU):
|
#if defined(CPUARM)
|
||||||
g_eeGeneral.globalTimer = 0;
|
case EVT_KEY_LONG(KEY_MENU):
|
||||||
eeDirty(EE_GENERAL);
|
g_eeGeneral.globalTimer = 0;
|
||||||
sessionTimer = 0;
|
eeDirty(EE_GENERAL);
|
||||||
break;
|
sessionTimer = 0;
|
||||||
#endif
|
break;
|
||||||
case EVT_KEY_FIRST(KEY_EXIT):
|
#endif
|
||||||
chainMenu(menuMainView);
|
case EVT_KEY_FIRST(KEY_EXIT):
|
||||||
break;
|
chainMenu(menuMainView);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP);
|
|
||||||
putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0);
|
lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP);
|
||||||
putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0);
|
putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0);
|
||||||
|
putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0);
|
||||||
putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0);
|
|
||||||
putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0);
|
putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0);
|
||||||
|
putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0);
|
||||||
putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0);
|
|
||||||
|
putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0);
|
||||||
#if defined(CPUARM)
|
|
||||||
putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0);
|
#if defined(CPUARM)
|
||||||
#endif
|
putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0);
|
||||||
|
#endif
|
||||||
#if defined(THRTRACE)
|
|
||||||
coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0);
|
#if defined(THRTRACE)
|
||||||
const coord_t x = 5;
|
coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0);
|
||||||
const coord_t y = 60;
|
const coord_t x = 5;
|
||||||
lcd_hline(x-3, y, MAXTRACE+3+3);
|
const coord_t y = 60;
|
||||||
lcd_vline(x, y-32, 32+3);
|
lcd_hline(x-3, y, MAXTRACE+3+3);
|
||||||
|
lcd_vline(x, y-32, 32+3);
|
||||||
for (coord_t i=0; i<MAXTRACE; i+=6) {
|
|
||||||
lcd_vline(x+i+6, y-1, 3);
|
for (coord_t i=0; i<MAXTRACE; i+=6) {
|
||||||
}
|
lcd_vline(x+i+6, y-1, 3);
|
||||||
for (coord_t i=1; i<=MAXTRACE; i++) {
|
}
|
||||||
lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]);
|
for (coord_t i=1; i<=MAXTRACE; i++) {
|
||||||
traceRd++;
|
lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]);
|
||||||
if (traceRd>=MAXTRACE) traceRd = 0;
|
traceRd++;
|
||||||
if (traceRd==s_traceWr) break;
|
if (traceRd>=MAXTRACE) traceRd = 0;
|
||||||
}
|
if (traceRd==s_traceWr) break;
|
||||||
#endif
|
}
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
#if defined(PCBSKY9X)
|
|
||||||
#define MENU_DEBUG_COL1_OFS (11*FW-3)
|
#if defined(PCBSKY9X)
|
||||||
#define MENU_DEBUG_COL2_OFS (17*FW)
|
#define MENU_DEBUG_COL1_OFS (11*FW-3)
|
||||||
#define MENU_DEBUG_Y_CURRENT (1*FH)
|
#define MENU_DEBUG_COL2_OFS (17*FW)
|
||||||
#define MENU_DEBUG_Y_MAH (2*FH)
|
#define MENU_DEBUG_Y_CURRENT (1*FH)
|
||||||
#define MENU_DEBUG_Y_CPU_TEMP (3*FH)
|
#define MENU_DEBUG_Y_MAH (2*FH)
|
||||||
#define MENU_DEBUG_Y_COPROC (4*FH)
|
#define MENU_DEBUG_Y_CPU_TEMP (3*FH)
|
||||||
#define MENU_DEBUG_Y_MIXMAX (5*FH)
|
#define MENU_DEBUG_Y_COPROC (4*FH)
|
||||||
#define MENU_DEBUG_Y_RTOS (6*FH)
|
#define MENU_DEBUG_Y_MIXMAX (5*FH)
|
||||||
#else
|
#define MENU_DEBUG_Y_RTOS (6*FH)
|
||||||
#define MENU_DEBUG_COL1_OFS (14*FW)
|
#else
|
||||||
#endif
|
#define MENU_DEBUG_COL1_OFS (14*FW)
|
||||||
|
#endif
|
||||||
void menuStatisticsDebug(uint8_t event)
|
|
||||||
{
|
void menuStatisticsDebug(uint8_t event)
|
||||||
TITLE(STR_MENUDEBUG);
|
{
|
||||||
|
TITLE(STR_MENUDEBUG);
|
||||||
switch(event)
|
|
||||||
{
|
switch(event)
|
||||||
#if defined(CPUARM)
|
{
|
||||||
case EVT_KEY_LONG(KEY_ENTER):
|
#if defined(CPUARM)
|
||||||
g_eeGeneral.mAhUsed = 0;
|
case EVT_KEY_LONG(KEY_ENTER):
|
||||||
g_eeGeneral.globalTimer = 0;
|
g_eeGeneral.mAhUsed = 0;
|
||||||
eeDirty(EE_GENERAL);
|
g_eeGeneral.globalTimer = 0;
|
||||||
#if defined(PCBSKY9X)
|
eeDirty(EE_GENERAL);
|
||||||
Current_used = 0;
|
#if defined(PCBSKY9X)
|
||||||
#endif
|
Current_used = 0;
|
||||||
sessionTimer = 0;
|
#endif
|
||||||
killEvents(event);
|
sessionTimer = 0;
|
||||||
AUDIO_KEYPAD_UP();
|
killEvents(event);
|
||||||
break;
|
AUDIO_KEYPAD_UP();
|
||||||
#endif
|
break;
|
||||||
case EVT_KEY_FIRST(KEY_ENTER):
|
#endif
|
||||||
#if !defined(CPUARM)
|
case EVT_KEY_FIRST(KEY_ENTER):
|
||||||
g_tmr1Latency_min = 0xff;
|
#if !defined(CPUARM)
|
||||||
g_tmr1Latency_max = 0;
|
g_tmr1Latency_min = 0xff;
|
||||||
#endif
|
g_tmr1Latency_max = 0;
|
||||||
maxMixerDuration = 0;
|
#endif
|
||||||
AUDIO_KEYPAD_UP();
|
maxMixerDuration = 0;
|
||||||
break;
|
AUDIO_KEYPAD_UP();
|
||||||
|
break;
|
||||||
#if defined(DEBUG_TRACE_BUFFER)
|
|
||||||
case EVT_KEY_FIRST(KEY_UP):
|
#if defined(DEBUG_TRACE_BUFFER)
|
||||||
pushMenu(menuTraceBuffer);
|
case EVT_KEY_FIRST(KEY_UP):
|
||||||
return;
|
pushMenu(menuTraceBuffer);
|
||||||
#endif
|
return;
|
||||||
|
#endif
|
||||||
case EVT_KEY_FIRST(KEY_DOWN):
|
|
||||||
chainMenu(menuStatisticsView);
|
case EVT_KEY_FIRST(KEY_DOWN):
|
||||||
break;
|
chainMenu(menuStatisticsView);
|
||||||
case EVT_KEY_FIRST(KEY_EXIT):
|
break;
|
||||||
chainMenu(menuMainView);
|
case EVT_KEY_FIRST(KEY_EXIT):
|
||||||
break;
|
chainMenu(menuMainView);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
#if defined(PCBSKY9X)
|
|
||||||
if ((ResetReason&RSTC_SR_RSTTYP) == (2<<8)) {
|
#if defined(PCBSKY9X)
|
||||||
lcd_puts(LCD_W-8*FW, 0*FH, "WATCHDOG");
|
if ((ResetReason&RSTC_SR_RSTTYP) == (2<<8)) {
|
||||||
}
|
lcd_puts(LCD_W-8*FW, 0*FH, "WATCHDOG");
|
||||||
else if (unexpectedShutdown) {
|
}
|
||||||
lcd_puts(LCD_W-13*FW, 0*FH, "UNEXP.SHTDOWN");
|
else if (unexpectedShutdown) {
|
||||||
}
|
lcd_puts(LCD_W-13*FW, 0*FH, "UNEXP.SHTDOWN");
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#if defined(PCBSKY9X) && !defined(REVA)
|
|
||||||
// current
|
#if defined(PCBSKY9X) && !defined(REVA)
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT);
|
// current
|
||||||
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT);
|
lcd_putsLeft(MENU_DEBUG_Y_CURRENT, STR_CPU_CURRENT);
|
||||||
uint32_t current_scale = 488 + g_eeGeneral.currentCalib;
|
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CURRENT, getCurrent(), UNIT_MILLIAMPS, LEFT);
|
||||||
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>');
|
uint32_t current_scale = 488 + g_eeGeneral.currentCalib;
|
||||||
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
|
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CURRENT, '>');
|
||||||
// consumption
|
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CURRENT, Current_max*10*current_scale/8192, UNIT_RAW, LEFT);
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH);
|
// consumption
|
||||||
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
|
lcd_putsLeft(MENU_DEBUG_Y_MAH, STR_CPU_MAH);
|
||||||
#endif
|
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MAH, g_eeGeneral.mAhUsed + Current_used*current_scale/8192/36, UNIT_MAH, LEFT|PREC1);
|
||||||
|
#endif
|
||||||
#if defined(PCBSKY9X)
|
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP);
|
#if defined(PCBSKY9X)
|
||||||
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT);
|
lcd_putsLeft(MENU_DEBUG_Y_CPU_TEMP, STR_CPU_TEMP);
|
||||||
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>');
|
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_CPU_TEMP, getTemperature(), UNIT_TEMPERATURE, LEFT);
|
||||||
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
|
lcd_putc(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_CPU_TEMP, '>');
|
||||||
#endif
|
putsValueWithUnit(MENU_DEBUG_COL2_OFS+FW+1, MENU_DEBUG_Y_CPU_TEMP, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, LEFT);
|
||||||
|
#endif
|
||||||
#if defined(COPROCESSOR)
|
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP);
|
#if defined(COPROCESSOR)
|
||||||
|
lcd_putsLeft(MENU_DEBUG_Y_COPROC, STR_COPROC_TEMP);
|
||||||
if (Coproc_read==0) {
|
|
||||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Co Proc NACK"),INVERS);
|
if (Coproc_read==0) {
|
||||||
}
|
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Co Proc NACK"),INVERS);
|
||||||
else if (Coproc_read==0x81) {
|
}
|
||||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Inst.TinyApp"),INVERS);
|
else if (Coproc_read==0x81) {
|
||||||
}
|
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Inst.TinyApp"),INVERS);
|
||||||
else if (Coproc_read<3) {
|
}
|
||||||
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Upgr.TinyApp"),INVERS);
|
else if (Coproc_read<3) {
|
||||||
}
|
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, PSTR("Upgr.TinyApp"),INVERS);
|
||||||
else {
|
}
|
||||||
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT);
|
else {
|
||||||
putsValueWithUnit(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
|
putsValueWithUnit(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_COPROC, Coproc_temp, UNIT_TEMPERATURE, LEFT);
|
||||||
}
|
putsValueWithUnit(MENU_DEBUG_COL2_OFS, MENU_DEBUG_Y_COPROC, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT);
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#if defined(CPUARM)
|
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
|
#if defined(CPUARM)
|
||||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
|
lcd_putsLeft(MENU_DEBUG_Y_MIXMAX, STR_TMIXMAXMS);
|
||||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
|
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
|
||||||
#endif
|
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
|
||||||
|
#endif
|
||||||
#if defined(PCBSKY9X)
|
|
||||||
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
|
#if defined(PCBSKY9X)
|
||||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
|
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
|
||||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
|
||||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
|
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
||||||
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(1), UNSIGN|LEFT);
|
||||||
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
|
lcd_puts(lcdLastPos, MENU_DEBUG_Y_RTOS, "/");
|
||||||
#endif
|
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(2), UNSIGN|LEFT);
|
||||||
|
#endif
|
||||||
#if !defined(CPUARM)
|
|
||||||
lcd_putsLeft(1*FH, STR_TMR1LATMAXUS);
|
#if !defined(CPUARM)
|
||||||
lcd_outdez8(MENU_DEBUG_COL1_OFS , 1*FH, g_tmr1Latency_max/2 );
|
lcd_putsLeft(1*FH, STR_TMR1LATMAXUS);
|
||||||
lcd_putsLeft(2*FH, STR_TMR1LATMINUS);
|
lcd_outdez8(MENU_DEBUG_COL1_OFS , 1*FH, g_tmr1Latency_max/2 );
|
||||||
lcd_outdez8(MENU_DEBUG_COL1_OFS , 2*FH, g_tmr1Latency_min/2 );
|
lcd_putsLeft(2*FH, STR_TMR1LATMINUS);
|
||||||
lcd_putsLeft(3*FH, STR_TMR1JITTERUS);
|
lcd_outdez8(MENU_DEBUG_COL1_OFS , 2*FH, g_tmr1Latency_min/2 );
|
||||||
lcd_outdez8(MENU_DEBUG_COL1_OFS , 3*FH, (g_tmr1Latency_max - g_tmr1Latency_min) /2 );
|
lcd_putsLeft(3*FH, STR_TMR1JITTERUS);
|
||||||
lcd_putsLeft(4*FH, STR_TMIXMAXMS);
|
lcd_outdez8(MENU_DEBUG_COL1_OFS , 3*FH, (g_tmr1Latency_max - g_tmr1Latency_min) /2 );
|
||||||
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 4*FH, DURATION_MS_PREC2(maxMixerDuration), PREC2);
|
lcd_putsLeft(4*FH, STR_TMIXMAXMS);
|
||||||
lcd_putsLeft(5*FH, STR_FREESTACKMINB);
|
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, 4*FH, DURATION_MS_PREC2(maxMixerDuration), PREC2);
|
||||||
lcd_outdezAtt(14*FW, 5*FH, stack_free(), UNSIGN) ;
|
lcd_putsLeft(5*FH, STR_FREESTACKMINB);
|
||||||
#endif
|
lcd_outdezAtt(14*FW, 5*FH, stack_free(), UNSIGN) ;
|
||||||
|
#endif
|
||||||
lcd_puts(3*FW, 7*FH+1, STR_MENUTORESET);
|
|
||||||
lcd_status_line();
|
lcd_puts(3*FW, 7*FH+1, STR_MENUTORESET);
|
||||||
}
|
lcd_status_line();
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
#if defined(REVPLUS) && defined(LCD_DUAL_BUFFER)
|
#if defined(REVPLUS) && defined(LCD_DUAL_BUFFER)
|
||||||
display_t displayBuf1[DISPLAY_BUF_SIZE];
|
display_t displayBuf1[DISPLAY_BUF_SIZE];
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../opentx.h"
|
#include "../../opentx.h"
|
||||||
|
#include "../../timers.h"
|
||||||
|
|
||||||
#define BIGSIZE MIDSIZE
|
#define BIGSIZE MIDSIZE
|
||||||
#define LBOX_CENTERX (BOX_WIDTH/2 + 17)
|
#define LBOX_CENTERX (BOX_WIDTH/2 + 17)
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../opentx.h"
|
#include "../../opentx.h"
|
||||||
|
#include "../../timers.h"
|
||||||
|
|
||||||
void menuStatisticsView(uint8_t event)
|
void menuStatisticsView(uint8_t event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "stamp-opentx.h"
|
#include "stamp-opentx.h"
|
||||||
#include "bin_allocator.h"
|
#include "bin_allocator.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
#if !defined(SIMU)
|
#if !defined(SIMU)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
#if defined(PCBTARANIS)
|
#if defined(PCBTARANIS)
|
||||||
int8_t virtualInputsTrims[NUM_INPUTS];
|
int8_t virtualInputsTrims[NUM_INPUTS];
|
||||||
|
|
5310
radio/src/opentx.cpp
5310
radio/src/opentx.cpp
File diff suppressed because it is too large
Load diff
|
@ -270,6 +270,15 @@
|
||||||
#define convertSimuPath(x) (x)
|
#define convertSimuPath(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CPUM64) && !defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
// code cost is about 16 bytes for higher throttle accuracy for timer
|
||||||
|
// would not be noticable anyway, because all version up to this change had only 16 steps;
|
||||||
|
// now it has already 32 steps; this define would increase to 128 steps
|
||||||
|
#if !defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
#define ACCURAT_THROTTLE_TIMER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// RESX range is used for internal calculation; The menu says -100.0 to 100.0; internally it is -1024 to 1024 to allow some optimizations
|
// RESX range is used for internal calculation; The menu says -100.0 to 100.0; internally it is -1024 to 1024 to allow some optimizations
|
||||||
#define RESX_SHIFT 10
|
#define RESX_SHIFT 10
|
||||||
#define RESX 1024
|
#define RESX 1024
|
||||||
|
@ -867,16 +876,6 @@ extern uint16_t sessionTimer;
|
||||||
extern uint16_t s_timeCumThr;
|
extern uint16_t s_timeCumThr;
|
||||||
extern uint16_t s_timeCum16ThrP;
|
extern uint16_t s_timeCum16ThrP;
|
||||||
|
|
||||||
struct TimerState {
|
|
||||||
uint16_t cnt;
|
|
||||||
uint16_t sum;
|
|
||||||
uint8_t state;
|
|
||||||
int16_t val;
|
|
||||||
uint8_t val_10ms;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern TimerState timersStates[MAX_TIMERS];
|
|
||||||
|
|
||||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||||
#if defined(CPUARM)
|
#if defined(CPUARM)
|
||||||
typedef int16_t safetych_t;
|
typedef int16_t safetych_t;
|
||||||
|
@ -895,12 +894,6 @@ extern uint8_t trimsDisplayTimer;
|
||||||
extern uint8_t trimsDisplayMask;
|
extern uint8_t trimsDisplayMask;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TMR_OFF 0
|
|
||||||
#define TMR_RUNNING 1
|
|
||||||
#define TMR_NEGATIVE 2
|
|
||||||
#define TMR_STOPPED 3
|
|
||||||
#define TMR_TRIGGED 4
|
|
||||||
void timerReset(uint8_t idx);
|
|
||||||
void flightReset();
|
void flightReset();
|
||||||
|
|
||||||
extern uint8_t unexpectedShutdown;
|
extern uint8_t unexpectedShutdown;
|
||||||
|
@ -1068,12 +1061,6 @@ inline void resumeMixerCalculations()
|
||||||
#define resumeMixerCalculations()
|
#define resumeMixerCalculations()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CPUARM) || defined(CPUM2560)
|
|
||||||
void saveTimers();
|
|
||||||
#else
|
|
||||||
#define saveTimers()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void generalDefault();
|
void generalDefault();
|
||||||
void modelDefault(uint8_t id);
|
void modelDefault(uint8_t id);
|
||||||
|
|
||||||
|
|
284
radio/src/tests/timers.cpp
Normal file
284
radio/src/tests/timers.cpp
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* 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 "gtests.h"
|
||||||
|
#include "opentx.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct TimerState {
|
||||||
|
uint16_t cnt;
|
||||||
|
uint16_t sum;
|
||||||
|
uint8_t state;
|
||||||
|
int16_t val;
|
||||||
|
uint8_t val_10ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
PACK(typedef struct t_TimerData {
|
||||||
|
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||||
|
uint16_t start;
|
||||||
|
uint8_t countdownBeep:2;
|
||||||
|
uint8_t minuteBeep:1;
|
||||||
|
uint8_t persistent:2; // 0 off, 1 flight, 2 manual reset
|
||||||
|
uint8_t spare:3;
|
||||||
|
uint16_t value;
|
||||||
|
}) TimerData;
|
||||||
|
|
||||||
|
enum TimerModes {
|
||||||
|
TMRMODE_NONE,
|
||||||
|
TMRMODE_ABS,
|
||||||
|
TMRMODE_THR,
|
||||||
|
TMRMODE_THR_REL,
|
||||||
|
TMRMODE_THR_TRG,
|
||||||
|
TMRMODE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CountDownModes {
|
||||||
|
COUNTDOWN_SILENT,
|
||||||
|
COUNTDOWN_BEEPS,
|
||||||
|
COUNTDOWN_VOICE
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(CPUARM)
|
||||||
|
#undef timerSet
|
||||||
|
void timerSet(int idx, int16_t val)
|
||||||
|
{
|
||||||
|
TimerState & timerState = timersStates[idx];
|
||||||
|
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
||||||
|
timerState.val = val;
|
||||||
|
timerState.val_10ms = 0 ;
|
||||||
|
}
|
||||||
|
#endif // #if !defined(CPUARM)
|
||||||
|
|
||||||
|
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
#define THR_100 128 // approximately 10% full throttle
|
||||||
|
#define THR_50 64 // approximately 10% full throttle
|
||||||
|
#define THR_10 13 // approximately 10% full throttle
|
||||||
|
#else
|
||||||
|
#define THR_100 32 // approximately 10% full throttle
|
||||||
|
#define THR_50 16 // approximately 10% full throttle
|
||||||
|
#define THR_10 3 // approximately 10% full throttle
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_AB_EQUAL(a, b) if (a != b) { return ::testing::AssertionFailure() << \
|
||||||
|
#a "= " << (uint32_t)a << ", " << #b "= " << (uint32_t)b; };
|
||||||
|
|
||||||
|
void initModelTimer(uint32_t idx, uint8_t mode, int16_t start = 0)
|
||||||
|
{
|
||||||
|
g_model.timers[0].mode = mode;
|
||||||
|
g_model.timers[0].start = start;
|
||||||
|
g_model.timers[0].countdownBeep = COUNTDOWN_SILENT;
|
||||||
|
g_model.timers[0].minuteBeep = 0;
|
||||||
|
g_model.timers[0].spare = 0;
|
||||||
|
#if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
g_model.timers[0].persistent = 0;
|
||||||
|
g_model.timers[0].value = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Run timers for n seconds and test the end state
|
||||||
|
*/
|
||||||
|
::testing::AssertionResult evalTimersForNSecondsAndTest(unsigned int n, uint8_t throttle, uint32_t idx, uint8_t state, int16_t value)
|
||||||
|
{
|
||||||
|
unsigned int noLoops = n * 100;
|
||||||
|
while(noLoops--)
|
||||||
|
{
|
||||||
|
evalTimers(throttle, 1);
|
||||||
|
}
|
||||||
|
TEST_AB_EQUAL(timersStates[idx].state, state);
|
||||||
|
TEST_AB_EQUAL(timersStates[idx].val, value);
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Timers, timerReset)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_THR_REL, 200);
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 200));
|
||||||
|
|
||||||
|
initModelTimer(1, TMRMODE_THR_REL, 0);
|
||||||
|
timerReset(1);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CPUARM)
|
||||||
|
TEST(Timers, timerSet)
|
||||||
|
{
|
||||||
|
timerSet(0, 500);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
|
||||||
|
|
||||||
|
timerSet(1, 300);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 300));
|
||||||
|
}
|
||||||
|
#endif // #if defined(CPUARM)
|
||||||
|
|
||||||
|
#if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
TEST(Timers, saveRestoreTimers)
|
||||||
|
{
|
||||||
|
g_model.timers[0].persistent = 1;
|
||||||
|
g_model.timers[1].persistent = 1;
|
||||||
|
timerSet(0, 500);
|
||||||
|
timerSet(1, 1500);
|
||||||
|
saveTimers();
|
||||||
|
EXPECT_EQ(g_model.timers[0].value, 500);
|
||||||
|
EXPECT_EQ(g_model.timers[1].value, 1500);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
|
||||||
|
|
||||||
|
timerReset(0);
|
||||||
|
timerReset(1);
|
||||||
|
restoreTimers();
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST(Timers, timerOff)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_NONE, 0);
|
||||||
|
timerReset(0);
|
||||||
|
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 0));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, THR_100, 0, TMR_OFF, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Timers, timerAbsolute)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_ABS, 0);
|
||||||
|
timerReset(0);
|
||||||
|
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 1));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 101));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 201));
|
||||||
|
|
||||||
|
// max timer value test
|
||||||
|
timerSet(0, TIMER_MAX-10);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MAX-9));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MAX));
|
||||||
|
|
||||||
|
// test down-running
|
||||||
|
g_model.timers[0].start = 200;
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_NEGATIVE, -1));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED, -101));
|
||||||
|
|
||||||
|
// min timer value test
|
||||||
|
timerSet(0, TIMER_MIN+10);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MIN+9));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Timers, timerThrottle)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_THR, 0);
|
||||||
|
timerReset(0);
|
||||||
|
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 200));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 200));
|
||||||
|
|
||||||
|
// test down-running
|
||||||
|
g_model.timers[0].start = 200;
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_NEGATIVE, -1));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-101));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(Timers, timerThrottleRelative)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_THR_REL, 0);
|
||||||
|
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 150)); // 50% throttle == 50s
|
||||||
|
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 160)); // 10% throttle == 10s
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 160));
|
||||||
|
#else
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 159)); // 10% throttle == 10s
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 159));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// test down-running
|
||||||
|
initModelTimer(0, TMRMODE_THR_REL, 200);
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(200, THR_50, 0, TMR_NEGATIVE, -1)); // 50% throttle == 100s
|
||||||
|
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-11)); // 10% throttle == 10s
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-111));
|
||||||
|
#else
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-10)); // 10% throttle == 10s
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-110));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Timers, timerThrottleTriggered)
|
||||||
|
{
|
||||||
|
initModelTimer(0, TMRMODE_THR_TRG, 0);
|
||||||
|
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 0));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 0)); // below threshold
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 100));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 200));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 300));
|
||||||
|
|
||||||
|
// test down-running
|
||||||
|
initModelTimer(0, TMRMODE_THR_TRG, 200);
|
||||||
|
timerReset(0);
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 200));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 200)); // below threshold
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(101, THR_50, 0, TMR_NEGATIVE, -1));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, 0, 0, TMR_NEGATIVE,-11));
|
||||||
|
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_STOPPED,-111));
|
||||||
|
}
|
209
radio/src/timers.cpp
Normal file
209
radio/src/timers.cpp
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* 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 "opentx.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
TimerState timersStates[MAX_TIMERS] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
void timerReset(uint8_t idx)
|
||||||
|
{
|
||||||
|
TimerState & timerState = timersStates[idx];
|
||||||
|
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
||||||
|
timerState.val = g_model.timers[idx].start;
|
||||||
|
timerState.val_10ms = 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CPUARM)
|
||||||
|
void timerSet(int idx, int16_t val)
|
||||||
|
{
|
||||||
|
TimerState & timerState = timersStates[idx];
|
||||||
|
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
||||||
|
timerState.val = val;
|
||||||
|
timerState.val_10ms = 0 ;
|
||||||
|
}
|
||||||
|
#endif // #if defined(CPUARM)
|
||||||
|
|
||||||
|
#if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
void restoreTimers()
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||||
|
if (g_model.timers[i].persistent) {
|
||||||
|
timersStates[i].val = g_model.timers[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveTimers()
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||||
|
if (g_model.timers[i].persistent) {
|
||||||
|
TimerState *timerState = &timersStates[i];
|
||||||
|
if (g_model.timers[i].value != (uint16_t)timerState->val) {
|
||||||
|
g_model.timers[i].value = timerState->val;
|
||||||
|
eeDirty(EE_MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CPUARM) && !defined(REVA)
|
||||||
|
if (sessionTimer > 0) {
|
||||||
|
g_eeGeneral.globalTimer += sessionTimer;
|
||||||
|
eeDirty(EE_GENERAL);
|
||||||
|
sessionTimer = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // #if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
|
||||||
|
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
#define THR_TRG_TRESHOLD 13 // approximately 10% full throttle
|
||||||
|
#else
|
||||||
|
#define THR_TRG_TRESHOLD 3 // approximately 10% full throttle
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void evalTimers(int16_t throttle, uint8_t tick10ms)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||||
|
int8_t tm = g_model.timers[i].mode;
|
||||||
|
uint16_t tv = g_model.timers[i].start;
|
||||||
|
TimerState * timerState = &timersStates[i];
|
||||||
|
|
||||||
|
if (tm) {
|
||||||
|
if ((timerState->state == TMR_OFF) && (tm != TMRMODE_THR_TRG)) {
|
||||||
|
timerState->state = TMR_RUNNING;
|
||||||
|
timerState->cnt = 0;
|
||||||
|
timerState->sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tm == TMRMODE_THR_REL) {
|
||||||
|
timerState->cnt++;
|
||||||
|
timerState->sum += throttle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((timerState->val_10ms += tick10ms) >= 100) {
|
||||||
|
if (timerState->val == TIMER_MAX) break;
|
||||||
|
if (timerState->val == TIMER_MIN) break;
|
||||||
|
|
||||||
|
timerState->val_10ms -= 100 ;
|
||||||
|
int16_t newTimerVal = timerState->val;
|
||||||
|
if (tv) newTimerVal = tv - newTimerVal;
|
||||||
|
|
||||||
|
if (tm == TMRMODE_ABS) {
|
||||||
|
newTimerVal++;
|
||||||
|
}
|
||||||
|
else if (tm == TMRMODE_THR) {
|
||||||
|
if (throttle) newTimerVal++;
|
||||||
|
}
|
||||||
|
else if (tm == TMRMODE_THR_REL) {
|
||||||
|
// @@@ open.20.fsguruh: why so complicated? we have already a s_sum field; use it for the half seconds (not showable) as well
|
||||||
|
// check for s_cnt[i]==0 is not needed because we are shure it is at least 1
|
||||||
|
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||||
|
if ((timerState->sum/timerState->cnt) >= 128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well)
|
||||||
|
newTimerVal++; // add second used of throttle
|
||||||
|
timerState->sum -= 128*timerState->cnt;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ((timerState->sum/timerState->cnt) >= 32) { // throttle was normalized to 0 to 32 value (throttle/16*2 (because - range is added as well)
|
||||||
|
newTimerVal++; // add second used of throttle
|
||||||
|
timerState->sum -= 32*timerState->cnt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
timerState->cnt=0;
|
||||||
|
}
|
||||||
|
else if (tm == TMRMODE_THR_TRG) {
|
||||||
|
// we can't rely on (throttle || newTimerVal > 0) as a detection if timer should be running
|
||||||
|
// because having persistent timer brakes this rule
|
||||||
|
if ((throttle > THR_TRG_TRESHOLD) && timerState->state == TMR_OFF) {
|
||||||
|
timerState->state = TMR_RUNNING; // start timer running
|
||||||
|
timerState->cnt = 0;
|
||||||
|
timerState->sum = 0;
|
||||||
|
TRACE("Timer[%d] THr triggered", i);
|
||||||
|
}
|
||||||
|
if (timerState->state != TMR_OFF) newTimerVal++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (tm > 0) tm -= (TMRMODE_COUNT-1);
|
||||||
|
if (getSwitch(tm))
|
||||||
|
newTimerVal++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (timerState->state) {
|
||||||
|
case TMR_RUNNING:
|
||||||
|
if (tv && newTimerVal>=(int16_t)tv) {
|
||||||
|
AUDIO_TIMER_00(g_model.timers[i].countdownBeep);
|
||||||
|
timerState->state = TMR_NEGATIVE;
|
||||||
|
TRACE("Timer[%d] negative", i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TMR_NEGATIVE:
|
||||||
|
if (newTimerVal >= (int16_t)tv + MAX_ALERT_TIME) {
|
||||||
|
timerState->state = TMR_STOPPED;
|
||||||
|
TRACE("Timer[%d] stopped state at %d", i, newTimerVal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tv) newTimerVal = tv - newTimerVal; // if counting backwards - display backwards
|
||||||
|
|
||||||
|
if (newTimerVal != timerState->val) {
|
||||||
|
timerState->val = newTimerVal;
|
||||||
|
if (timerState->state == TMR_RUNNING) {
|
||||||
|
if (g_model.timers[i].countdownBeep && g_model.timers[i].start) {
|
||||||
|
if (newTimerVal==30) {
|
||||||
|
AUDIO_TIMER_30();
|
||||||
|
TRACE("Timer[%d] 30s announcement", i);
|
||||||
|
}
|
||||||
|
if (newTimerVal==20) {
|
||||||
|
AUDIO_TIMER_20();
|
||||||
|
TRACE("Timer[%d] 20s announcement", i);
|
||||||
|
}
|
||||||
|
if (newTimerVal<=10) {
|
||||||
|
AUDIO_TIMER_LT10(g_model.timers[i].countdownBeep, newTimerVal);
|
||||||
|
TRACE("Timer[%d] %ds announcement", i, newTimerVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g_model.timers[i].minuteBeep && (newTimerVal % 60)==0) {
|
||||||
|
AUDIO_TIMER_MINUTE(newTimerVal);
|
||||||
|
TRACE("Timer[%d] %d minute announcement", i, newTimerVal/60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
radio/src/timers.h
Normal file
74
radio/src/timers.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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 timers_h
|
||||||
|
#define timers_h
|
||||||
|
|
||||||
|
#define TMR_OFF 0
|
||||||
|
#define TMR_RUNNING 1
|
||||||
|
#define TMR_NEGATIVE 2
|
||||||
|
#define TMR_STOPPED 3
|
||||||
|
|
||||||
|
#define TIMER_MAX (32767)
|
||||||
|
#define TIMER_MIN (-32767-1)
|
||||||
|
|
||||||
|
struct TimerState {
|
||||||
|
uint16_t cnt;
|
||||||
|
uint16_t sum;
|
||||||
|
uint8_t state;
|
||||||
|
int16_t val;
|
||||||
|
uint8_t val_10ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TimerState timersStates[MAX_TIMERS];
|
||||||
|
|
||||||
|
void timerReset(uint8_t idx);
|
||||||
|
|
||||||
|
#if defined(CPUARM)
|
||||||
|
void timerSet(int idx, int16_t val);
|
||||||
|
#endif // #if defined(CPUARM)
|
||||||
|
|
||||||
|
#if defined(CPUARM) || defined(CPUM2560)
|
||||||
|
void saveTimers();
|
||||||
|
void restoreTimers();
|
||||||
|
#else
|
||||||
|
#define saveTimers()
|
||||||
|
#define restoreTimers()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void evalTimers(int16_t throttle, uint8_t tick10ms);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue