From 7ec8392c81efe1c6cbb7f45a172823e94815b863 Mon Sep 17 00:00:00 2001 From: openfsguruh Date: Wed, 2 Apr 2014 13:13:22 +0200 Subject: [PATCH 1/2] This should solve issue #888; You have to specify the compile option if you are on a Atmel based CPU like Turnigy9x: ACCURAT_THROTTLE_STATS=YES The reason why this fix is not always activated: - It costs about 18bytes additional flash - There are rare cases you will notice the rounding issue at all. Don't bother on Taranis, the fix is activated on this automatically. --- radio/src/Makefile | 11 +++++++++++ radio/src/opentx.cpp | 30 +++++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index c80161774..c27ae747c 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -126,6 +126,14 @@ CORRECT_NEGATIVE_VALUES = YES # Values = YES, NO ARITHMETIC_OVERFLOW_CHECK = NO +# increases resolution for throttle statistics and throttle counting, in very rare cases. +# most important effect is, it prevents throttle counting faster than actual time for 100%. +# this will be only true if an output channel is used for throttle calculation, and this chanenel has changed limits, e.g. -90% to +80% +# if you use standard limits for throttle or directly the throttle stick you do not bother about this option +# not valid for ARM based transmitters like Taranis, They do not have this rounding issue at all +# Values = YES, NO +ACCURAT_THROTTLE_STATS = NO + # HAPTIC Mods # Values = YES, NO HAPTIC = NO @@ -857,6 +865,9 @@ ifeq ($(ARITHMETIC_OVERFLOW_CHECK), YES) CPPDEFS += -DPREVENT_ARITHMETIC_OVERFLOW endif +ifeq ($(ACCURAT_THROTTLE_STATS), YES) + CPPDEFS += -DACCURAT_THROTTLE_TIMER +endif # EXTENSIONS (for Telemetry protocols) ifneq ($(EXT), $(filter $(EXT), STD FRSKY ARDUPILOT NMEA JETI MAVLINK TELEMETREZ)) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index ae54e4f4e..6c8f55490 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -4171,6 +4171,13 @@ void doMixerCalculations() if (!tick10ms) return; //make sure the rest happen only every 10ms. #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 + #define ACCURAT_THROTTLE_TIMER +#endif + /* Throttle trace */ int16_t val; @@ -4191,18 +4198,22 @@ void doMixerCalculations() if (lim->symetrical) val -= calc1000toRESX(lim->offset); #endif - // @@@ open.20.fsguruh optimized calculation; now *8 /8 instead of 10 base; (*16/16 already cause a overrun; unsigned calculation also not possible, because v may be negative) + + gModelMax -= gModelMin; // we compare difference between Max and Mix for recaling needed; Max and Min are shifted to 0 by default - // usually max is 1024 min is -1024 --> max-min = 2048 full range / 128 = max 16 steps - + // usually max is 1024 min is -1024 --> max-min = 2048 full range + +#ifdef ACCURAT_THROTTLE_TIMER + if (gModelMax!=0 && gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // recaling only needed if Min, Max differs +#else + // @@@ open.20.fsguruh optimized calculation; now *8 /8 instead of 10 base; (*16/16 already cause a overrun; unsigned calculation also not possible, because v may be negative) gModelMax >>= (10-2); - if (gModelMax != 0 && gModelMax != 8) { + if (gModelMax!=0 && gModelMax!=8) { val = (val << 3) / gModelMax; // rescaling only needed if Min, Max differs } +#endif - // if (gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // recaling only needed if Min, Max differs - // val = val * 10 / (10+(lim->max-lim->min)/20); if (val<0) val=0; // prevent val be negative, which would corrupt throttle trace and timers; could occur if safetyswitch is smaller than limits } else { @@ -4213,13 +4224,6 @@ void doMixerCalculations() #endif } -#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 - #if defined(ACCURAT_THROTTLE_TIMER) val >>= (RESX_SHIFT-6); // calibrate it (resolution increased by factor 4) #else From 30099dc5cd2f64e9cbcbb4ac8c7a2179ce37ba9d Mon Sep 17 00:00:00 2001 From: openfsguruh Date: Wed, 2 Apr 2014 21:29:00 +0200 Subject: [PATCH 2/2] changed rounding for gModelMax. This should prevent counting THROTTLE faster than 100%, if ACCURAT_THROTTLE_STATS is set to NO and ATMEL based Transmitters are used. --- radio/src/Makefile | 3 +-- radio/src/opentx.cpp | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index c27ae747c..e21c42da3 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -127,9 +127,8 @@ CORRECT_NEGATIVE_VALUES = YES ARITHMETIC_OVERFLOW_CHECK = NO # increases resolution for throttle statistics and throttle counting, in very rare cases. -# most important effect is, it prevents throttle counting faster than actual time for 100%. # this will be only true if an output channel is used for throttle calculation, and this chanenel has changed limits, e.g. -90% to +80% -# if you use standard limits for throttle or directly the throttle stick you do not bother about this option +# if you use standard limits for throttle or directly the throttle stick you do not need to bother about this option # not valid for ARM based transmitters like Taranis, They do not have this rounding issue at all # Values = YES, NO ACCURAT_THROTTLE_STATS = NO diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 6c8f55490..6a6ee4a6a 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -4204,9 +4204,10 @@ void doMixerCalculations() // usually max is 1024 min is -1024 --> max-min = 2048 full range #ifdef ACCURAT_THROTTLE_TIMER - if (gModelMax!=0 && gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // recaling only needed if Min, Max differs + if (gModelMax!=0 && gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // rescaling only needed if Min, Max differs #else // @@@ open.20.fsguruh optimized calculation; now *8 /8 instead of 10 base; (*16/16 already cause a overrun; unsigned calculation also not possible, because v may be negative) + gModelMax+=255; // force rounding up --> gModelMax is bigger --> val is smaller gModelMax >>= (10-2); if (gModelMax!=0 && gModelMax!=8) {