From 2a9160fcab696de4dcac3bd56d4eb52d99e5abe3 Mon Sep 17 00:00:00 2001 From: "open.20.fsguruh@xoxy.net" Date: Thu, 21 Feb 2013 22:11:33 +0000 Subject: [PATCH] weight and offset range extension change (flash code cost 22bytes) This change makes both weight and offset range bigger for all 32 possible mixers. Instead of -125 to 125 now -245 to 245 is allowed for weight and offset in mixer. No additional EEPROM is needed. Conversion of EEPROM follow soon... --- src/menus.cpp | 4 +-- src/menus.h | 2 +- src/model_menus.cpp | 32 +++++++----------- src/myeeprom.h | 47 ++++++++++++++++++++++++-- src/open9x.cpp | 80 +++++++++++++++++++-------------------------- src/open9x.h | 9 ++++- 6 files changed, 100 insertions(+), 74 deletions(-) diff --git a/src/menus.cpp b/src/menus.cpp index f9348f9ce..a062cc6b9 100644 --- a/src/menus.cpp +++ b/src/menus.cpp @@ -677,7 +677,7 @@ int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t } #if defined(GVARS) -int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event) +int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) // @@@ open.20.fsguruh { uint8_t delta = (max <= 100 ? GV1_SMALL-1 : GV1_LARGE-1); bool invers = (attr & INVERS); @@ -701,7 +701,7 @@ int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int8_t min, int8_t max } else { lcd_outdezAtt(x, y, value, attr); - if (invers) CHECK_INCDEC_MODELVAR(event, value, min, max); + if (invers) value = checkIncDec(event, value, min, max,EE_MODEL); // as proposed, no change to makro, but directly call this function } return value; } diff --git a/src/menus.h b/src/menus.h index 2f2005e62..da178a29d 100644 --- a/src/menus.h +++ b/src/menus.h @@ -211,7 +211,7 @@ uint8_t onoffMenuItem(uint8_t value, uint8_t x, uint8_t y, const pm_char *label, int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t event); #if defined(GVARS) -int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event); +int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event); // @@@ open.20.fsguruh #define displayGVar(x, y, v, min, max) gvarMenuItem(x, y, v, min, max, 0, 0) #else int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event); diff --git a/src/model_menus.cpp b/src/model_menus.cpp index 7e5b02a91..12a60cb3d 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -1904,16 +1904,11 @@ void gvarWeightItem(xcoord_t x, uint8_t y, MixData *md, uint8_t attr, uint8_t ev #if defined(CPUARM) || !defined(GVARS) md->weight = gvarMenuItem(x, y, md->weight, -125, 125, attr, event); #else - int16_t weight = (md->weightMode ? (int16_t)GV1_LARGE + md->weight : md->weight); - weight = gvarMenuItem(x, y, weight, -125, 125, attr, event); - if (weight <= 125) { - md->weightMode = 0; - md->weight = weight; - } - else { - md->weightMode = 1; - md->weight = weight - GV1_LARGE; - } + // @@@ open.20.fsguruh + u_int8int16_t weight; + MD_GETWEIGHT(weight,md); + weight.word = gvarMenuItem(x, y, weight.word, -245, 245, attr, event); + MD_SETWEIGHT(weight,md); #endif } @@ -1990,18 +1985,13 @@ void menuModelMixOne(uint8_t event) { lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET)); #if defined(GVARS) - int16_t offset = (md2->offsetMode ? (int16_t)GV1_LARGE + md2->offset : md2->offset); - offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, offset, -125, 125, attr|LEFT, event); - if (offset <= 125) { - md2->offsetMode = 0; - md2->offset = offset; - } - else { - md2->offsetMode = 1; - md2->offset = offset - GV1_LARGE; - } + // @@@ open.20.fsguruh + u_int8int16_t offset; + MD_GETOFFSET(offset,md2); + offset.word = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, offset.word, -245, 245, attr|LEFT, event); + MD_SETOFFSET(offset,md2); #else - md2->offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->offset, -125, 125, attr|LEFT, event); + md2->offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->offset, -125, 125, attr|LEFT, event); #endif break; } diff --git a/src/myeeprom.h b/src/myeeprom.h index 6608fc7e7..6a688ff8b 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -311,14 +311,57 @@ PACK(typedef struct t_MixData { int8_t offset; }) MixData; #if defined(GVARS) - #define MD_WEIGHT(md) (md->weightMode ? (int16_t)GV1_LARGE+md->weight : md->weight) + // @@@ open.20.fsguruh + PACK( union u_gvarint_t { + struct { + int8_t lo; + uint8_t hi; + } bytes_t; + int16_t word; + + u_gvarint_t(int8_t l, uint8_t h) {bytes_t.lo=l; bytes_t.hi=h?255:0;} // hi bit is negativ sign + + private: + // prevent unwanted constructors, also saves program + u_gvarint_t() {} + u_gvarint_t(const u_gvarint_t&) {} + }); + #define MD_WEIGHT(md) (u_gvarint_t(md->weight,md->weightMode).word) + + PACK( union u_int8int16_t { + struct { + int8_t lo; + uint8_t hi; + } bytes_t; + int16_t word; + }); + #define MD_GETWEIGHT(var,md) var.bytes_t.lo=md->weight; var.bytes_t.hi=md->weightMode?255:0 + #define MD_SETWEIGHT(var,md) md->weight = var.bytes_t.lo; \ + if (var.word<0) md->weightMode=1; else md->weightMode=0 // set negative sign + + #define MD_OFFSET(md) (u_gvarint_t(md->offset,md->offsetMode).word) + #define MD_GETOFFSET(var,md) var.bytes_t.lo=md->offset; var.bytes_t.hi=md->offsetMode?255:0 + #define MD_SETOFFSET(var,md) md->offset = var.bytes_t.lo; \ + if (var.word<0) md->offsetMode=1; else md->offsetMode=0 // set negative sign #else #define MD_WEIGHT(md) (md->weight) #endif #endif #if defined(GVARS) -#define MD_OFFSET(md) (md->offsetMode ? (int16_t)GV1_LARGE+md->offset : md->offset) +// @@@ open.20.fsguruh +#ifndef MD_OFFSET + PACK( union u_int8int16_t { + struct { + int8_t lo; + uint8_t hi; + } bytes_t; + int16_t word; + }); + #define MD_OFFSET(md) (md->offsetMode ? (int16_t)GV1_LARGE+md->offset : md->offset) + #define MD_GETOFFSET(var,md) var.word=md->offset + #define MD_SETOFFSET(var,md) md->offset=var.word +#endif #else #define MD_OFFSET(md) (md->offset) #endif diff --git a/src/open9x.cpp b/src/open9x.cpp index 6560ca6fa..071ecdbcd 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -657,7 +657,6 @@ void applyExpos(int16_t *anas) #if !defined(CPUARM) - // #define CORRECT_NEGATIVE_SHIFTS // open.20.fsguruh; shift right operations do the rounding different for negative values compared to positive values // so all negative divisions round always further down, which give absolute values bigger compared to a usual division @@ -665,11 +664,10 @@ void applyExpos(int16_t *anas) // difference this is more a mental thing. Maybe people are distracted, because the easy calculations are obviously wrong // this define would correct this, but costs 34 bytes code for stock version -int16_t calc100to256(int8_t x) // return x*2.56 +int16_t calc100to256_16Bits(int16_t x) // return x*2.56 { // y = 2*x + x/2 +x/16-x/512-x/2048 // 512 and 2048 are out of scope from int8 input --> forget it - #ifdef CORRECT_NEGATIVE_SHIFTS int16_t res=(int16_t)x<<1; //int8_t sign=(uint8_t) x>>7; @@ -684,22 +682,14 @@ int16_t calc100to256(int8_t x) // return x*2.56 #else return ((int16_t)x<<1)+(x>>1)+(x>>4); #endif - // in case of negative values the routine above always generates a too small value, this could be corrected with this - // I think it is not needed anyway - // if (x<0) return -calc100to256(-x); - // else return ((int16_t)x<<1)+(x>>1)+(x>>4); } - -// return x*10.24 -int16_t calc100toRESX_16Bits(int16_t x) // @@@ open.20.fsguruh +int16_t calc100to256(int8_t x) // return x*2.56 { - // return (int16_t)x*10 + x/4 - x/64; - return ((x*41)>>2) - (x>>6); // this implementation saves a add but reduces valid range by factor 4!!! by carefull - // return (x*10)+(x>>2)-(x>>6); // this would be the saver implementation -} + return calc100to256_16Bits(x); +} -int16_t calc100toRESX(int8_t x) // return x*10.24 +int16_t calc100toRESX_16Bits(int16_t x) // return x*10.24 { #ifdef CORRECT_NEGATIVE_SHIFTS int16_t res= ((int16_t)x*41)>>2; @@ -715,6 +705,11 @@ int16_t calc100toRESX(int8_t x) // return x*10.24 #endif } +int16_t calc100toRESX(int8_t x) // return x*10.24 +{ + return calc100toRESX_16Bits(x); +} + // return x*1.024 int16_t calc1000toRESX(int16_t x) // improve calc time by Pat MacKenzie { @@ -745,9 +740,7 @@ int16_t applyLimits(uint8_t channel, int32_t value) int16_t ofs = calc1000toRESX(limit->offset); // multiply to 1.24 to get range (-1024..1024) int16_t lim_p = calc100toRESX(limit->max + 100); int16_t lim_n = calc100toRESX(limit->min - 100); //multiply by 10.24 to get same range (-1024..1024) - // int16_t ofs = limit->offset; - // int16_t lim_p = 10 * (limit->max + 100); - // int16_t lim_n = 10 * (limit->min - 100); //multiply by 10 to get same range as ofs (-1000..1000) + if (ofs > lim_p) ofs = lim_p; if (ofs < lim_n) ofs = lim_n; @@ -759,47 +752,40 @@ int16_t applyLimits(uint8_t channel, int32_t value) else tmp = (value > 0) ? (lim_p - ofs) : (-lim_n + ofs); value = (int32_t) value * tmp; // div by 1024*256 -> output = -1024..1024 +#ifdef CORRECT_NEGATIVE_SHIFTS + int8_t sign=(value<0?1:0); + value-=sign; tmp=value>>16; // that's quite tricky: the shiftright 16 operation is assmbled just with addressmove; just forget the two least significant bytes; tmp>>=2; // now one simple shift right for two bytes does the rest -// too pedantic or really useful? -// if ((tmp==-1) && (value&0x00020000)) tmp+=1; // check if negativ and least significant bit was set - // if we are pedantic; a -1 result is wrong if we devide with 262144)) (-0x40000) That's why a +1 is needed + tmp+=sign; +#else + tmp=value>>16; // that's quite tricky: the shiftright 16 operation is assmbled just with addressmove; just forget the two least significant bytes; + tmp>>=2; // now one simple shift right for two bytes does the rest +#endif + ofs+=tmp; // ofs can to added directly because already recalculated, - -/* int32_t tmp; - if (limit->symetrical) - tmp = (value > 0) ? ((int32_t) lim_p) : ((int32_t) -lim_n); - else - tmp = (value > 0) ? ((int32_t) lim_p - ofs) : ((int32_t) -lim_n + ofs); - value = (value * tmp) / 100000; */ } #else if (value) { int16_t tmp = (value > 0) ? (lim_p - ofs) : (-lim_n + ofs); value = (int32_t) value * tmp; // div by 1024*256 -> output = -1024..1024 +#ifdef CORRECT_NEGATIVE_SHIFTS + int8_t sign=(value<0?1:0); + value-=sign; tmp=value>>16; // that's quite tricky: the shiftright 16 operation is assmbled just with addressmove; just forget the two least significant bytes; tmp>>=2; // now one simple shift right for two bytes does the rest -// too pedantic or really useful? -// if ((tmp==-1) && (value&0x00020000)) tmp+=1; // check if negativ and least significant bit was set - // if we are pedantic; a -1 result is wrong if we devide with 262144)) (-0x40000) That's why a +1 is needed + tmp+=sign; +#else + tmp=value>>16; // that's quite tricky: the shiftright 16 operation is assmbled just with addressmove; just forget the two least significant bytes; + tmp>>=2; // now one simple shift right for two bytes does the rest +#endif ofs+=tmp; // ofs can to added directly because already recalculated, - - // int32_t tmp = (value > 0) ? ((int32_t) lim_p - ofs) : ((int32_t) -lim_n + ofs); - // value = (value * tmp) / 100000; //div by 100000 -> output = -1024..1024 } #endif - // ofs+=value; // already done above - // lim_p, lim_n already recalculated + if (ofs > lim_p) ofs = lim_p; if (ofs < lim_n) ofs = lim_n; - // value += calc1000toRESX(ofs); - // lim_p = calc1000toRESX(lim_p); - // lim_n = calc1000toRESX(lim_n); - // if (value > lim_p) value = lim_p; - // if (value < lim_n) value = lim_n; - // ofs = value; // we convert value to a 16bit value and reuse ofs - if (limit->revert) ofs = -ofs; // finally do the reverse. if (safetyCh[channel] != -128) // if safety channel available for channel check @@ -1255,7 +1241,7 @@ uint8_t s_gvar_last = 0; #if defined(CPUM64) int16_t getGVarValue(int16_t x, int16_t min, int16_t max) { - if (x > max) { + if (x > (GV1_LARGE-6)) { // @@@ open.20.fsguruh int8_t idx = (max <= 100 ? x - GV1_SMALL : x - GV1_LARGE); int8_t mul = 1; @@ -2705,8 +2691,8 @@ void perOut(uint8_t mode, uint8_t tick10ms) //========== OFFSET =============== if (apply_offset_and_curve) { - int8_t offset = GET_GVAR(MD_OFFSET(md), -125, 125, s_perout_flight_phase); - if (offset) v += calc100toRESX(offset); + int16_t offset = GET_GVAR(MD_OFFSET(md), -245, 245, s_perout_flight_phase); // open.20.fsguruh + if (offset) v+=calc100toRESX_16Bits(offset); // @@@ open.20.fsguruh } //========== TRIMS =============== @@ -2730,7 +2716,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) //========== WEIGHT =============== // @@@2 recalculate weight to a 256 basis which ease the calculation later a lot - int32_t dv = (int32_t) v * calc100to256(weight); + int32_t dv = (int32_t) v * calc100to256_16Bits(weight); //========== SPEED =============== if (mode == e_perout_mode_normal && (md->speedUp || md->speedDown)) { // there are delay values diff --git a/src/open9x.h b/src/open9x.h index fabfb7caf..491fd49e5 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -820,7 +820,8 @@ void incRotaryEncoder(uint8_t idx, int8_t inc); #define SET_GVAR(idx, val, p) setGVarValue(idx, val, p) #endif #define GV1_SMALL 123 - #define GV1_LARGE 1024 + // @@@ open.20.fsguruh + #define GV1_LARGE 251 #define GVAR_DISPLAY_TIME 100 /*1 second*/; extern uint8_t s_gvar_timer; extern uint8_t s_gvar_last; @@ -1003,6 +1004,11 @@ void generalDefault(); void modelDefault(uint8_t id); #if defined(CPUARM) +inline int16_t calc100to256_16Bits(register int16_t x) // @@@2 open.20.fsguruh: return x*2.56 +{ + return ((int16_t) x * 256) / 100; +} + inline int16_t calc100to256(register int8_t x) // @@@2 open.20.fsguruh: return x*2.56 { return ((int16_t) x * 256) / 100; @@ -1034,6 +1040,7 @@ inline int16_t calcRESXto100(register int32_t x) } #else +extern int16_t calc100to256_16Bits(int16_t x); // @@@2 open.20.fsguruh: return x*2.56 extern int16_t calc100to256(int8_t x); // @@@2 open.20.fsguruh: return x*2.56 extern int16_t calc100toRESX_16Bits(int16_t x); // @@@ open.20.fsguruh extern int16_t calc100toRESX(int8_t x);