[all] Timers countdown / minute beep are configurable

[stock] Port from a part of Andreas patch relative to timers. Thanks Andreas! It allowed me to implement the configurable beeps for timers at a almost 0 flash cost.
This commit is contained in:
bsongis
2013-02-26 16:07:41 +00:00
parent fbd1488b62
commit 6fc8ba804c
9 changed files with 203 additions and 159 deletions
+1 -1
View File
@@ -409,7 +409,7 @@ void eeLoadModel(uint8_t id)
memclear(lastFunctionTime, sizeof(lastFunctionTime));
for (uint8_t i=0; i<MAX_TIMERS; i++) {
if (g_model.timers[i].remanent) {
if (g_model.timers[i].persistent) {
s_timerVal[i] = g_model.timers[i].value;
}
}
+1 -1
View File
@@ -907,7 +907,7 @@ void eeLoadModel(uint8_t id)
#if !defined(PCBSTD)
for (uint8_t i=0; i<MAX_TIMERS; i++) {
if (g_model.timers[i].remanent) {
if (g_model.timers[i].persistent) {
s_timerVal[i] = g_model.timers[i].value;
}
}
+2 -2
View File
@@ -63,7 +63,7 @@ PACK(typedef struct {
}) TimerData_v212;
PACK(typedef struct {
uint16_t remanent:1;
uint16_t persistent:1;
uint16_t value:15;
}) TimerDataExtra_v212;
@@ -159,7 +159,7 @@ bool eeConvert()
for (uint8_t i=0; i<2; i++) {
g_model.timers[i].mode = oldModel.timers[i].mode;
g_model.timers[i].start = oldModel.timers[i].val;
g_model.timers[i].remanent = oldModel.timersXtra[i].remanent;
g_model.timers[i].persistent = oldModel.timersXtra[i].persistent;
g_model.timers[i].value = oldModel.timersXtra[i].value;
}
g_model.protocol = oldModel.protocol;
-10
View File
@@ -136,8 +136,6 @@ enum menuGeneralSetupItems {
IF_ROTARY_ENCODERS(ITEM_SETUP_RE_NAVIGATION)
ITEM_SETUP_THROTTLE_REVERSED,
ITEM_SETUP_BEEP_LABEL,
ITEM_SETUP_MINUTE_BEEP,
ITEM_SETUP_COUNTDOWN_BEEP,
ITEM_SETUP_BACKLIGHT_LABEL,
ITEM_SETUP_BACKLIGHT_MODE,
ITEM_SETUP_BACKLIGHT_DELAY,
@@ -402,14 +400,6 @@ void menuGeneralSetup(uint8_t event)
g_eeGeneral.throttleReversed = onoffMenuItem(g_eeGeneral.throttleReversed, RADIO_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ;
break;
case ITEM_SETUP_MINUTE_BEEP:
g_eeGeneral.minuteBeep = onoffMenuItem(g_eeGeneral.minuteBeep, RADIO_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event ) ;
break;
case ITEM_SETUP_COUNTDOWN_BEEP:
g_eeGeneral.preBeep = onoffMenuItem(g_eeGeneral.preBeep, RADIO_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event ) ;
break;
case ITEM_SETUP_BACKLIGHT_MODE:
g_eeGeneral.backlightMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBLMODE, g_eeGeneral.backlightMode, e_backlight_mode_off, e_backlight_mode_on, attr, event);
break;
+8 -6
View File
@@ -37,13 +37,15 @@
#ifndef menus_h
#define menus_h
#define NO_HI_LEN 25
#define NO_HI_LEN 25
#define RESX 1024
#define RESXu 1024u
#define RESXul 1024ul
#define RESXl 1024l
#define RESKul 100ul
// 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 1024
#define RESXu 1024u
#define RESXul 1024ul
#define RESXl 1024l
#define RESKul 100ul
#define RESX_PLUS_TRIM (RESX+128)
typedef void (*MenuFuncP)(uint8_t event);
+48 -34
View File
@@ -728,7 +728,13 @@ enum menuModelSetupItems {
ITEM_MODEL_NAME,
CASE_PCBX9D(ITEM_MODEL_BITMAP)
ITEM_MODEL_TIMER1,
IF_PERSISTENT_TIMERS(ITEM_MODEL_TIMER1_PERSISTENT)
ITEM_MODEL_TIMER1_MINUTE_BEEP,
ITEM_MODEL_TIMER1_COUNTDOWN_BEEP,
ITEM_MODEL_TIMER2,
IF_PERSISTENT_TIMERS(ITEM_MODEL_TIMER2_PERSISTENT)
ITEM_MODEL_TIMER2_MINUTE_BEEP,
ITEM_MODEL_TIMER2_COUNTDOWN_BEEP,
ITEM_MODEL_EXTENDED_LIMITS,
ITEM_MODEL_EXTENDED_TRIMS,
ITEM_MODEL_TRIM_INC,
@@ -743,12 +749,6 @@ enum menuModelSetupItems {
ITEM_MODEL_SETUP_MAX
};
#if defined(CPUARM) || defined(PCBGRUVIN9X)
#define FIELD_TIMER_MAX 3
#else
#define FIELD_TIMER_MAX 2
#endif
#if defined(PCBSKY9X)
#define FIELD_PROTOCOL_MAX 2
#else
@@ -779,7 +779,7 @@ void menuModelSetup(uint8_t event)
s_rangecheck_mode = 0;
#endif
MENU(STR_MENUSETUP, menuTabModel, e_Model, ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX), {0,0,CASE_PCBX9D(0) FIELD_TIMER_MAX,FIELD_TIMER_MAX,0,0,0,0,0,0,0,NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, IF_PCBSKY9X(1) 2 });
MENU(STR_MENUSETUP, menuTabModel, e_Model, ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX), { 0, 0, CASE_PCBX9D(0) 2, IF_PERSISTENT_TIMERS(0) 0, 0, 2, IF_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, IF_PCBSKY9X(1) 2 });
uint8_t sub = m_posVert - 1;
int8_t editMode = s_editMode;
@@ -819,39 +819,53 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_TIMER1:
case ITEM_MODEL_TIMER2:
case ITEM_MODEL_TIMER1_MINUTE_BEEP:
case ITEM_MODEL_TIMER2_MINUTE_BEEP:
case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP:
case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP:
{
TimerData *timer = &g_model.timers[k-ITEM_MODEL_TIMER1];
putsStrIdx(0*FW, y, STR_TIMER, k-ITEM_MODEL_TIMER1+1);
putsTmrMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0);
putsTime(MODEL_SETUP_2ND_COLUMN+5*FW-2, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0);
#if defined(CPUARM) || defined(PCBGRUVIN9X)
lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+10*FW-1, y, g_model.timers[k-ITEM_MODEL_TIMER1].remanent ? 'R' : '-', m_posHorz==3 ? attr : 0);
#endif
if (attr && (editMode>0 || p1valdiff)) {
div_t qr = div(timer->start, 60);
switch (m_posHorz) {
case 0:
CHECK_INCDEC_MODELVAR(event, timer->mode, -2*(MAX_PSWITCH+NUM_CSW)-1, TMR_VAROFS+2*(MAX_PSWITCH+NUM_CSW));
break;
case 1:
CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59);
timer->start = qr.rem + qr.quot*60;
break;
case 2:
qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2;
timer->start -= qr.rem ;
if ((int16_t)timer->start < 0) timer->start=0;
break;
#if defined(CPUARM) || defined(PCBGRUVIN9X)
case 3:
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.timers[k-ITEM_MODEL_TIMER1].remanent, 1);
break;
#endif
TimerData *timer = &g_model.timers[k>=ITEM_MODEL_TIMER2 ? 1 : 0];
if (k==ITEM_MODEL_TIMER1_MINUTE_BEEP || k==ITEM_MODEL_TIMER2_MINUTE_BEEP) {
timer->minuteBeep = onoffMenuItem(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event);
}
else if (k==ITEM_MODEL_TIMER1_COUNTDOWN_BEEP || k==ITEM_MODEL_TIMER2_COUNTDOWN_BEEP) {
timer->countdownBeep = onoffMenuItem(timer->countdownBeep, MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event);
}
else {
putsStrIdx(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1);
putsTmrMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0);
putsTime(MODEL_SETUP_2ND_COLUMN+5*FW-2, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0);
if (attr && (editMode>0 || p1valdiff)) {
div_t qr = div(timer->start, 60);
switch (m_posHorz) {
case 0:
CHECK_INCDEC_MODELVAR(event, timer->mode, -2*(MAX_PSWITCH+NUM_CSW)-1, TMR_VAROFS+2*(MAX_PSWITCH+NUM_CSW));
break;
case 1:
CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59);
timer->start = qr.rem + qr.quot*60;
break;
case 2:
qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2;
timer->start -= qr.rem ;
if ((int16_t)timer->start < 0) timer->start=0;
break;
}
}
}
break;
}
#if defined(CPUARM) || defined(PCBGRUVIN9X)
case ITEM_MODEL_TIMER1_PERSISTENT:
case ITEM_MODEL_TIMER2_PERSISTENT:
{
TimerData &timer = g_model.timers[k==ITEM_MODEL_TIMER2_PERSISTENT];
timer.persistent = onoffMenuItem(timer.persistent, MODEL_SETUP_2ND_COLUMN, y, PSTR(INDENT"Persist."), attr, event);
break;
}
#endif
case ITEM_MODEL_EXTENDED_LIMITS:
g_model.extendedLimits = onoffMenuItem(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, STR_ELIMITS, attr, event);
break;
+11 -6
View File
@@ -173,8 +173,7 @@ PACK(typedef struct t_EEGeneral {
uint8_t spare2:1;
uint8_t inactivityTimer;
uint8_t throttleReversed:1;
uint8_t minuteBeep:1;
uint8_t preBeep:1;
uint8_t spare3:2;
SPLASH_MODE; /* 3bits */
int8_t hapticMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all
uint8_t blOffBright:4;
@@ -992,14 +991,20 @@ enum MixSources {
#if defined(PCBGRUVIN9X) || defined(CPUARM)
PACK(typedef struct t_TimerData {
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
uint16_t start;
uint16_t remanent:1;
uint16_t value:15;
uint16_t start:12;
uint16_t countdownBeep:1;
uint16_t minuteBeep:1;
uint16_t persistent:1;
uint16_t spare:1;
uint16_t value;
}) TimerData;
#else
PACK(typedef struct t_TimerData {
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
uint16_t start;
uint16_t start:12;
uint16_t countdownBeep:1;
uint16_t minuteBeep:1;
uint16_t spare:2;
}) TimerData;
#endif
+126 -98
View File
@@ -292,7 +292,7 @@ void per10ms()
// These moved here from perOut() to improve beep trigger reliability.
#if defined(PWM_BACKLIGHT)
if (g_tmr10ms % 4 == 0)
if ((g_tmr10ms&0x03) == 0x00)
fadeBacklight(); // increment or decrement brightness until target brightness is reached
#endif
@@ -338,7 +338,7 @@ CurveInfo curveinfo(uint8_t idx)
result.crv = curveaddress(idx);
int8_t *next = curveaddress(idx+1);
uint8_t size = next - result.crv;
if (size % 2 == 0) {
if ((size & 1) == 0) {
result.points = (size / 2) + 1;
result.custom = true;
}
@@ -854,12 +854,15 @@ bool __getSwitch(int8_t swtch)
}
#endif
}
else if (cs->v1 >= MIXSRC_GVAR1) {
y = cs->v2;
}
else {
y = calc100toRESX(cs->v2);
}
#else
if (cs->v1 >= MIXSRC_FIRST_TELEM) {
y = cs->v2; // it's a timer
if (cs->v1 >= MIXSRC_GVAR1) {
y = cs->v2; // it's a GVAR or a Timer
}
else {
y = calc100toRESX(cs->v2);
@@ -1214,12 +1217,13 @@ void putsTelemetryValue(xcoord_t x, uint8_t y, lcdint_t val, uint8_t unit, uint8
}
#endif
#define INAC_DEVISOR 512 // Bypass splash screen with stick movement
#define INAC_DEVISOR 512 // bypass splash screen with stick movement
#define INAC_DEV_SHIFT 9 // shift right value for stick movement
uint16_t stickMoveValue()
{
uint16_t sum = 0;
for (uint8_t i=0; i<4; i++)
sum += anaIn(i)/INAC_DEVISOR;
for (uint8_t i=0; i<NUM_STICKS; i++)
sum += anaIn(i) >> INAC_DEV_SHIFT;
return sum;
}
@@ -1586,7 +1590,7 @@ uint8_t checkTrim(uint8_t event)
after = TRIM_MAX;
if (after < TRIM_MIN)
after = TRIM_MIN;
after /= 4;
after >>= 2;
after += 60;
#endif
@@ -1772,7 +1776,6 @@ static uint8_t lastSwPos[2] = {0, 0};
static uint16_t s_cnt[2] = {0, 0};
static uint16_t s_sum[2] = {0, 0};
static uint8_t sw_toggled[2] = {false, false};
static uint16_t s_time_cum_16[2] = {0, 0};
#if defined(THRTRACE)
uint8_t s_traceBuf[MAXTRACE];
@@ -1843,7 +1846,7 @@ BeepANACenter evalSticks(uint8_t mode)
if (g_model.swashR.value) {
uint32_t v = (int32_t(calibratedStick[ELE_STICK])*calibratedStick[ELE_STICK] +
int32_t(calibratedStick[AIL_STICK])*calibratedStick[AIL_STICK]);
uint32_t q = int32_t(RESX)*g_model.swashR.value/100;
uint32_t q = calc100toRESX(g_model.swashR.value);
q *= q;
if (v>q)
d = isqrt32(v);
@@ -1923,8 +1926,8 @@ BeepANACenter evalSticks(uint8_t mode)
}
#ifdef HELI
if(d && (ch==ELE_STICK || ch==AIL_STICK))
v = int32_t(v)*g_model.swashR.value*RESX/(int32_t(d)*100);
if (d && (ch==ELE_STICK || ch==AIL_STICK))
v = (int32_t(v)*calc100toRESX(g_model.swashR.value))/int32_t(d);
#endif
rawAnas[ch] = v;
@@ -1963,8 +1966,6 @@ PLAY_FUNCTION(playValue, uint8_t idx)
{
int16_t val = getValue(idx);
// TODO add the MIXSRC_TELEM_TM1 and so on.
switch (idx) {
case MIXSRC_FIRST_TELEM-1+TELEM_TX_VOLTAGE-1:
PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
@@ -2051,7 +2052,7 @@ PLAY_FUNCTION(playValue, uint8_t idx)
default:
{
uint8_t unit = 1;
if (idx < MIXSRC_FIRST_TELEM-1+TELEM_TM1-1)
if (idx < MIXSRC_GVAR1)
val = calcRESXto100(val);
if (idx >= MIXSRC_FIRST_TELEM-1+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM-1+TELEM_GPSALT-1)
unit = idx - (MIXSRC_FIRST_TELEM-1+TELEM_ALT-1);
@@ -2396,13 +2397,13 @@ void perOut(uint8_t mode, uint8_t tick10ms)
if(g_model.swashR.value)
{
uint32_t v = ((int32_t)anas[ELE_STICK]*anas[ELE_STICK] + (int32_t)anas[AIL_STICK]*anas[AIL_STICK]);
uint32_t q = (int32_t)RESX*g_model.swashR.value/100;
uint32_t q = calc100toRESX(g_model.swashR.value);
q *= q;
if(v>q)
{
if (v>q) {
uint16_t d = isqrt32(v);
anas[ELE_STICK] = (int32_t)anas[ELE_STICK]*g_model.swashR.value*RESX/((int32_t)d*100);
anas[AIL_STICK] = (int32_t)anas[AIL_STICK]*g_model.swashR.value*RESX/((int32_t)d*100);
int16_t tmp = calc100toRESX(g_model.swashR.value);
anas[ELE_STICK] = (int32_t) anas[ELE_STICK]*tmp/d;
anas[AIL_STICK] = (int32_t) anas[AIL_STICK]*tmp/d;
}
}
@@ -2769,7 +2770,7 @@ void doMixerCalculations()
s_perout_flight_phase = p;
perOut(e_perout_mode_normal, tick10ms);
for (uint8_t i=0; i<NUM_CHNOUT; i++)
sum_chans512[i] += (chans[i] / 16) * fp_act[p];
sum_chans512[i] += (chans[i] >> 4) * fp_act[p];
weight += fp_act[p];
}
}
@@ -2841,50 +2842,21 @@ void doMixerCalculations()
val = RESX + calibratedStick[g_model.thrTraceSrc == 0 ? THR_STICK : g_model.thrTraceSrc+NUM_STICKS-1];
}
val /= (RESX/16); // calibrate it
static tmr10ms_t s_time_tot;
static uint8_t s_cnt_1s;
static uint16_t s_sum_1s;
#if defined(THRTRACE)
static tmr10ms_t s_time_trace;
static uint16_t s_cnt_10s;
static uint16_t s_sum_10s;
#if !defined(CPUM64)
// 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
#define ACCURAT_THROTTLE_TIMER
#endif
s_cnt_1s++;
s_sum_1s += val;
if ((tmr10ms_t)(tmr10ms - s_time_tot) >= 100) { // 1sec
s_time_tot += 100;
s_timeCumTot += 1;
val = s_sum_1s / s_cnt_1s;
s_timeCum16ThrP += val / 2;
if (val) s_timeCumThr += 1;
#if defined(THRTRACE)
s_cnt_10s += s_cnt_1s;
s_sum_10s += s_sum_1s;
if ((tmr10ms_t)(tmr10ms - s_time_trace) >= 1000) { // 10s
s_time_trace += 1000;
val = s_sum_10s / s_cnt_10s;
s_sum_10s = 0;
s_cnt_10s = 0;
s_traceBuf[s_traceWr++] = val;
if (s_traceWr >= MAXTRACE) s_traceWr = 0;
if (s_traceCnt >= 0) s_traceCnt++;
}
#if defined(ACCURAT_THROTTLE_TIMER)
val >>= (RESX_SHIFT-6); // calibrate it (resolution increased by factor 4)
#else
val >>= (RESX_SHIFT-4); // calibrate it
#endif
s_cnt_1s = 0;
s_sum_1s = 0;
}
// Timers start
for (uint8_t i=0; i<2; i++) {
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;
@@ -2893,7 +2865,6 @@ void doMixerCalculations()
s_timerState[i] = TMR_RUNNING;
s_cnt[i] = 0;
s_sum[i] = 0;
s_time_cum_16[i] = 0;
}
uint8_t atm = (tm >= 0 ? tm : TMR_VAROFS-tm-1);
@@ -2914,73 +2885,127 @@ void doMixerCalculations()
if ( (s_timerVal_10ms[i] += tick10ms ) >= 100 ) {
s_timerVal_10ms[i] -= 100 ;
if (tv) s_timerVal[i] = tv - s_timerVal[i];
int16_t newTimerVal = s_timerVal[i];
if (tv) newTimerVal = tv - newTimerVal;
if (atm==TMRMODE_ABS) {
s_timerVal[i]++;
newTimerVal++;
}
else if (atm==TMRMODE_THR) {
if (val) s_timerVal[i]++;
if (val) newTimerVal++;
}
else if (atm==TMRMODE_THR_REL) {
if (s_cnt[i]) {
val = s_sum[i]/s_cnt[i];
s_sum[i] -= val*s_cnt[i]; //rest
s_cnt[i] = 0;
s_time_cum_16[i] += val/2;
if (s_time_cum_16[i] >= 16) {
s_timerVal[i] ++;
s_time_cum_16[i] -= 16;
}
// @@@ 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 ((s_sum[i]/s_cnt[i])>=128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well)
newTimerVal++; // add second used of throttle
s_sum[i]-=128*s_cnt[i];
}
#else
if ((s_sum[i]/s_cnt[i])>=32) { // throttle was normalized to 0 to 32 value (throttle/16*2 (because - range is added as well)
newTimerVal++; // add second used of throttle
s_sum[i]-=32*s_cnt[i];
}
#endif
s_cnt[i]=0;
}
else if (atm==TMRMODE_THR_TRG) {
if (val || s_timerVal[i] > 0)
s_timerVal[i]++;
if (val || newTimerVal > 0)
newTimerVal++;
}
else {
if (atm<(TMR_VAROFS+MAX_SWITCH))
sw_toggled[i] = tm>0 ? getSwitch(tm-(TMR_VAROFS-1), 0) : !getSwitch(-tm, 0); // normal switch
if (sw_toggled[i])
s_timerVal[i]++;
newTimerVal++;
}
switch(s_timerState[i])
{
case TMR_RUNNING:
if (tv && s_timerVal[i]>=(int16_t)tv) s_timerState[i]=TMR_BEEPING;
if (tv && newTimerVal>=(int16_t)tv) s_timerState[i]=TMR_BEEPING;
break;
case TMR_BEEPING:
if (s_timerVal[i] >= (int16_t)tv + MAX_ALERT_TIME) s_timerState[i]=TMR_STOPPED;
if (newTimerVal >= (int16_t)tv + MAX_ALERT_TIME) s_timerState[i]=TMR_STOPPED;
break;
}
if (tv) s_timerVal[i] = tv - s_timerVal[i]; //if counting backwards - display backwards
if (tv) newTimerVal = tv - newTimerVal; //if counting backwards - display backwards
if (newTimerVal != s_timerVal[i]) { // beep only if seconds advance
s_timerVal[i] = newTimerVal;
if (s_timerState[i] == TMR_RUNNING) {
if (g_model.timers[i].countdownBeep && g_model.timers[i].start) { // beep when 30, 15, 10, 5,4,3,2,1 seconds remaining
if (newTimerVal==30) AUDIO_TIMER_30(); //beep three times
if (newTimerVal==20) AUDIO_TIMER_20(); //beep two times
if (newTimerVal==10) AUDIO_TIMER_10();
if (newTimerVal<= 3) AUDIO_TIMER_LT3(newTimerVal);
}
if (g_model.timers[i].minuteBeep && (newTimerVal % 60)==0) { // short beep every minute
AUDIO_TIMER_MINUTE(newTimerVal);
}
}
else if (s_timerState[0] == TMR_BEEPING) {
AUDIO_WARNING1();
}
}
}
}
};
static int16_t last_tmr;
if (last_tmr != s_timerVal[0]) { // beep only if seconds advance
if (s_timerState[0] == TMR_RUNNING) {
if (g_eeGeneral.preBeep && g_model.timers[0].start) { // beep when 30, 15, 10, 5,4,3,2,1 seconds remaining
if(s_timerVal[0]==30) AUDIO_TIMER_30(); //beep three times
if(s_timerVal[0]==20) AUDIO_TIMER_20(); //beep two times
if(s_timerVal[0]==10) AUDIO_TIMER_10();
if(s_timerVal[0]<= 3) AUDIO_TIMER_LT3(s_timerVal[0]);
}
static tmr10ms_t s_time_tot;
static uint8_t s_cnt_1s;
static uint16_t s_sum_1s;
#if defined(THRTRACE)
static tmr10ms_t s_time_trace;
static uint16_t s_cnt_10s;
static uint16_t s_sum_10s;
#endif
if (g_eeGeneral.minuteBeep && (s_timerVal[0] % 60)==0) { // short beep every minute
AUDIO_TIMER_MINUTE(s_timerVal[0]);
}
s_cnt_1s++;
s_sum_1s += val;
// @@@ open.20.fsguruh: moved code here; at least val variable conflicts with caculations above, safer here?
// even reduced code size about 8 bytes, why ever?
if ((tmr10ms_t)(tmr10ms - s_time_tot) >= 100) { // 1sec
s_time_tot += 100;
s_timeCumTot += 1;
#if defined(ACCURAT_THROTTLE_TIMER)
val = s_sum_1s / s_cnt_1s;
s_timeCum16ThrP += (val>>3); // s_timeCum16ThrP would overrun if we would store throttle value with higher accuracy; therefore stay with 16 steps
if (val) s_timeCumThr += 1;
s_sum_1s>>=2; // correct better accuracy now, because trace graph can show this information; in case thrtrace is not active, the compile should remove this
#else
val = s_sum_1s / s_cnt_1s;
s_timeCum16ThrP += (val>>1);
if (val) s_timeCumThr += 1;
#endif
#if defined(THRTRACE)
// throttle trace is done every 10 seconds; Tracebuffer is adjusted to screen size.
// in case buffer runs out, it wraps around
// resolution for y axis is only 32, therefore no higher value makes sense
s_cnt_10s += s_cnt_1s;
s_sum_10s += s_sum_1s;
if ((tmr10ms_t)(tmr10ms - s_time_trace) >= 1000) { // 10s
s_time_trace += 1000;
val = s_sum_10s / s_cnt_10s;
s_sum_10s = 0;
s_cnt_10s = 0;
s_traceBuf[s_traceWr++] = val;
if (s_traceWr >= MAXTRACE) s_traceWr = 0;
if (s_traceCnt >= 0) s_traceCnt++;
}
else if(s_timerState[0] == TMR_BEEPING) {
AUDIO_WARNING1();
}
last_tmr = s_timerVal[0];
#endif
s_cnt_1s = 0;
s_sum_1s = 0;
}
// Timers end
if (s_fade_flight_phases) {
uint16_t tick_delta = delta * tick10ms;
@@ -3031,6 +3056,9 @@ void perMain()
}
nextMixerEndTime = t0 + MAX_MIXER_DELTA;
// this is a very tricky implementation; lastMixerEndTime is just like a default value not to stop mixcalculations totally;
// the real value for lastMixerEndTime is calculated inside pulses_XXX.cpp which aligns the timestamp to the pulses generated
// nextMixerEndTime is actually defined inside pulses_XXX.h
doMixerCalculations();
@@ -3455,7 +3483,7 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
void saveTimers()
{
for (uint8_t i=0; i<MAX_TIMERS; i++) {
if (g_model.timers[i].remanent) {
if (g_model.timers[i].persistent) {
if (g_model.timers[i].value != s_timerVal[i]) {
g_model.timers[i].value = s_timerVal[i];
eeDirty(EE_MODEL);
+6 -1
View File
@@ -74,6 +74,12 @@
#define IF_BATTGRAPH(x)
#endif
#if defined(CPUARM) || defined(PCBGRUVIN9X)
#define IF_PERSISTENT_TIMERS(x) x,
#else
#define IF_PERSISTENT_TIMERS(x)
#endif
#if defined(RTCLOCK)
#define IF_RTCLOCK(x) x,
#else
@@ -981,7 +987,6 @@ extern int16_t ex_chans[NUM_CHNOUT]; // Outputs (before LIMITS) of th
extern int16_t g_chans512[NUM_CHNOUT];
extern uint16_t BandGap;
extern uint16_t expou(uint16_t x, uint16_t k);
extern int16_t expo(int16_t x, int16_t k);
extern int16_t intpol(int16_t, uint8_t);
extern int16_t applyCurve(int16_t, int8_t);