Now extended range for weight, offset also without GVARS, GVARS fix, overruns fix
This version holds mainly bugfixes and prepares this branch for merge. Please test and report. - gvars didn't work for value ranges usually from -100 to 100 (e.g. diff function) - gvars shown wrong also in models menu (same in trunk as well) - gbirkus tested ranges with speed optimizations, overruns occured at half range of trunk version. Now this is fixed and a much bigger range can be used. Still overruns possible. Please test. - ISR 10msec now safe and code optimized.
This commit is contained in:
+2
-2
@@ -706,10 +706,10 @@ int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t m
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event)
|
||||
int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event)
|
||||
{
|
||||
lcd_outdezAtt(x, y, value, attr);
|
||||
if (attr&INVERS) CHECK_INCDEC_MODELVAR(event, value, min, max);
|
||||
if (attr&INVERS) value = checkIncDec(event, value, min, max,EE_MODEL);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t
|
||||
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);
|
||||
int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event);
|
||||
#define displayGVar(x, y, v, min, max) lcd_outdez8(x, y, v)
|
||||
#endif
|
||||
|
||||
|
||||
+10
-9
@@ -1901,15 +1901,15 @@ enum MixFields {
|
||||
|
||||
void gvarWeightItem(xcoord_t x, uint8_t y, MixData *md, uint8_t attr, uint8_t event)
|
||||
{
|
||||
#if defined(CPUARM) || !defined(GVARS)
|
||||
md->weight = gvarMenuItem(x, y, md->weight, -125, 125, attr, event);
|
||||
#else
|
||||
// #if defined(CPUARM) || !defined(GVARS)
|
||||
// md->weight = gvarMenuItem(x, y, md->weight, -125, 125, attr, event);
|
||||
// #else
|
||||
// @@@ 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
|
||||
//#endif
|
||||
}
|
||||
|
||||
void menuModelMixOne(uint8_t event)
|
||||
@@ -1984,15 +1984,15 @@ void menuModelMixOne(uint8_t event)
|
||||
case MIX_FIELD_OFFSET:
|
||||
{
|
||||
lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET));
|
||||
#if defined(GVARS)
|
||||
// #if defined(GVARS)
|
||||
// @@@ 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);
|
||||
#endif
|
||||
// #else
|
||||
// md2->offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->offset, -125, 125, attr|LEFT, event);
|
||||
// #endif
|
||||
break;
|
||||
}
|
||||
case MIX_FIELD_TRIM:
|
||||
@@ -2305,7 +2305,8 @@ void menuModelExpoMix(uint8_t expo, uint8_t event)
|
||||
if (md->curveMode == MODE_CURVE)
|
||||
putsCurve(12*FW+2, y, md->curveParam);
|
||||
else
|
||||
displayGVar(15*FW+2, y, md->curveParam, -125, 125);
|
||||
displayGVar(15*FW+2, y, md->curveParam, -100, 100); // open.20.fsguruh
|
||||
// displayGVar(15*FW+2, y, md->curveParam, -125, 125); // only -100 to +100 is allowed now
|
||||
}
|
||||
if (md->swtch) putsSwitches(16*FW, y, md->swtch);
|
||||
|
||||
|
||||
+60
-48
@@ -284,7 +284,39 @@ PACK(typedef struct t_MixData {
|
||||
int8_t offset;
|
||||
char name[LEN_EXPOMIX_NAME];
|
||||
}) MixData;
|
||||
|
||||
#define MD_WEIGHT(md) (md->weight)
|
||||
#define MD_GETWEIGHT(var,md) var.word=md->weight
|
||||
#define MD_SETWEIGHT(var,md) md->weight= var.word
|
||||
|
||||
PACK( union u_int8int16_t {
|
||||
struct {
|
||||
int8_t lo;
|
||||
uint8_t hi;
|
||||
} bytes_t;
|
||||
int16_t word;
|
||||
});
|
||||
|
||||
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_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 DELAY_STEP 2
|
||||
#define SLOW_STEP 2
|
||||
@@ -310,60 +342,40 @@ PACK(typedef struct t_MixData {
|
||||
int8_t curveParam;
|
||||
int8_t offset;
|
||||
}) MixData;
|
||||
#if defined(GVARS)
|
||||
// @@@ 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)
|
||||
// @@@ 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; \
|
||||
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; \
|
||||
#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)
|
||||
// @@@ 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
|
||||
|
||||
#if defined(CPUARM)
|
||||
|
||||
+74
-69
@@ -733,7 +733,7 @@ int16_t calcRESXto1000(int16_t x) // return x/1.024
|
||||
// channel = channelnumber -1;
|
||||
// value = outputvalue with 100 mulitplied usual range -102400 to 102400; output -1024 to 1024
|
||||
// changed rescaling from *100 to *256 to optimize performance
|
||||
// rescaled to -262144)) to 262144))
|
||||
// rescaled from -262144 to 262144
|
||||
int16_t applyLimits(uint8_t channel, int32_t value)
|
||||
{
|
||||
LimitData * limit = limitaddress(channel);
|
||||
@@ -744,6 +744,12 @@ int16_t applyLimits(uint8_t channel, int32_t value)
|
||||
if (ofs > lim_p) ofs = lim_p;
|
||||
if (ofs < lim_n) ofs = lim_n;
|
||||
|
||||
// thanks to gbirkus, he motivated this change, which greatly reduces overruns
|
||||
// unfortunately the constants and 32bit compares generates about 52 bytes codes; didn't find a way to get it down.
|
||||
// But I think it is worth
|
||||
if (value>RESXl*256) value = RESXl*256; // no bigger values allowed, prevent early overruns
|
||||
if (value<-RESXl*256) value = -RESXl*256; // no smaller values allowed, prevent early overruns
|
||||
|
||||
#if defined(PPM_LIMITS_SYMETRICAL)
|
||||
if (value) {
|
||||
int16_t tmp;
|
||||
@@ -1241,7 +1247,7 @@ uint8_t s_gvar_last = 0;
|
||||
#if defined(CPUM64)
|
||||
int16_t getGVarValue(int16_t x, int16_t min, int16_t max)
|
||||
{
|
||||
if (x > (GV1_LARGE-6)) { // @@@ open.20.fsguruh
|
||||
if ((x > (GV1_LARGE-6)) || (x>max)) { // @@@ open.20.fsguruh
|
||||
int8_t idx = (max <= 100 ? x - GV1_SMALL : x - GV1_LARGE);
|
||||
int8_t mul = 1;
|
||||
|
||||
@@ -1715,7 +1721,7 @@ uint8_t checkTrim(uint8_t event)
|
||||
after = TRIM_MAX;
|
||||
if (after < TRIM_MIN)
|
||||
after = TRIM_MIN;
|
||||
after /= 4;
|
||||
after>>=2; // open.20.fsguruh after/=4;
|
||||
after += 60;
|
||||
#endif
|
||||
|
||||
@@ -2631,7 +2637,6 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
passDirtyChannels |= (bitfield_channels_t) 1 << md->destCh;
|
||||
if (k-MIXSRC_CH1+1 < md->destCh || pass > 0)
|
||||
v = chans[k-MIXSRC_CH1+1] >> 8; // remove factor 256 from old mix loop; was 100 before
|
||||
// v = chans[k-MIXSRC_CH1+1] / 100;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -2646,7 +2651,6 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
passDirtyChannels |= (bitfield_channels_t) 1 << md->destCh;
|
||||
if (k-MIXSRC_CH1+1 < md->destCh || pass > 0)
|
||||
v = chans[k-MIXSRC_CH1+1] >> 8; // remove factor 256 from old mix loop; was 100 before
|
||||
// v = chans[k-MIXSRC_CH1+1] / 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2737,6 +2741,8 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
|
||||
|
||||
//========== SPEED ===============
|
||||
// now its on input side, but without weight compensation. More like other remote controls
|
||||
// lower weight causes slower movement
|
||||
if (mode == e_perout_mode_normal && (md->speedUp || md->speedDown)) { // there are delay values
|
||||
|
||||
#define DEL_MULT_SHIFT 8
|
||||
@@ -2750,14 +2756,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
// the value in md->speedXXX gives the time it should take to do a full movement from -100 to 100 therefore 200%. This equals 2048 in recalculated internal range
|
||||
if (tick10ms) {
|
||||
// only if already time is passed add or substract a value according the speed configured
|
||||
// codesaving 44 bytes
|
||||
#ifndef WEIGHTSPEEDCORRECTION
|
||||
int32_t rate = (int32_t) tick10ms << (DEL_MULT_SHIFT+11); // = DEL_MULT*2048*tick10ms
|
||||
#else
|
||||
// codecost 82 bytes
|
||||
int32_t rate = (int32_t) tick10ms << (DEL_MULT_SHIFT+19); // = DEL_MULT*2048*tick10ms
|
||||
rate/=abs(weight);
|
||||
#endif
|
||||
// rate equals a full range for one second; if less time is passed rate is accordingly smaller
|
||||
// if one second passed, rate would be 2048 (full motion)*256(recalculated weight)*100(100 ticks needed for one second)
|
||||
|
||||
@@ -2795,6 +2794,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
int32_t dv = (int32_t) v * weight;
|
||||
|
||||
#ifdef SPEED_AFTER_WEIGHT
|
||||
// todo remove is there is no need anymore...
|
||||
//========== SPEED ===============
|
||||
if (mode == e_perout_mode_normal && (md->speedUp || md->speedDown)) { // there are delay values
|
||||
|
||||
@@ -2840,12 +2840,6 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
|
||||
//========== DIFFERENTIAL =========
|
||||
if (md->curveMode == MODE_DIFFERENTIAL) {
|
||||
/* int8_t curveParam = GET_GVAR(md->curveParam, -100, 100, s_perout_flight_phase);
|
||||
if (curveParam > 0 && dv < 0)
|
||||
dv = (dv * (100 - curveParam)) / 100;
|
||||
else if (curveParam < 0 && dv > 0)
|
||||
dv = (dv * (100 + curveParam)) / 100; */
|
||||
|
||||
// @@@2 also recalculate curveParam to a 256 basis which ease the calculation later a lot
|
||||
int16_t curveParam=calc100to256(GET_GVAR(md->curveParam, -100, 100, s_perout_flight_phase));
|
||||
if (curveParam > 0 && dv < 0)
|
||||
@@ -3049,10 +3043,10 @@ void doMixerCalculations()
|
||||
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
|
||||
|
||||
// gModelMax>>=(10-2);
|
||||
// if (gModelMax!=8) val = (val << 3) / (gModelMax); // recaling only needed if Min, Max differs
|
||||
gModelMax>>=(10-2);
|
||||
if (gModelMax!=8) val = (val << 3) / (gModelMax); // recaling only needed if Min, Max differs
|
||||
|
||||
if (gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // recaling only needed if Min, Max differs
|
||||
// if (gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // recaling only needed if Min, Max differs
|
||||
// val = val * 10 / (10+(g_model.limitData[ch].max-g_model.limitData[ch].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
|
||||
}
|
||||
@@ -3493,51 +3487,21 @@ uint16_t getTmr16KHz()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// ISR(TIMER_10MS_VECT, ISR_NOBLOCK) // 10ms timer
|
||||
ISR(TIMER_10MS_VECT)
|
||||
|
||||
|
||||
|
||||
|
||||
ISR(TIMER_10MS_VECT, ISR_NOBLOCK)
|
||||
// 10ms timer
|
||||
{
|
||||
static uint8_t accuracyWarble;
|
||||
|
||||
#if defined(PCBGRUVIN9X)
|
||||
// static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; not start value needed
|
||||
uint8_t bump = (!(++accuracyWarble & 0x03)) ? 157 : 156;
|
||||
OCR2A += bump;
|
||||
#elif defined(AUDIO) || defined(VOICE)
|
||||
|
||||
// static uint8_t accuracyWarble;
|
||||
// because in this compile option the ISR is called each 128usec we prevent reentrant calls with a check to highest bit if accuracyWarble
|
||||
// this is not necessary for the other builds, because we expect there would not be a reentrant call in 10msec time
|
||||
OCR0 += 2; // interrupt every 128us
|
||||
// warble is done later for AUDIO or VOICE don't do it here because it will destroy audio
|
||||
// cli();
|
||||
// PAUSE_10MS_INTERRUPT();
|
||||
// sei();
|
||||
|
||||
static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; no start value needed
|
||||
|
||||
static int8_t cnt10ms; // no initialization needed here; execute 10ms code once every 78 ISRs; takes 16.38msec to overrun for first round --> no problem
|
||||
|
||||
cnt10ms--;
|
||||
|
||||
if (accuracyWarble&0x80) return; // is we are already in ISR leave it as soon as possible to free CPU, at least we had the ISR counted
|
||||
accuracyWarble|=0x80; // sign we are currently in ISR
|
||||
|
||||
bool doPer10msCall=false;
|
||||
|
||||
if (cnt10ms<=0) { // also allow smaller values
|
||||
cnt10ms += (!(++accuracyWarble &0x07)) ? 79 : 78; // instead of assigning we add to take missed ISRs into account
|
||||
accuracyWarble|=0x80; // reset sign bit, because ++accuracyWarble may deleted it because of overrun
|
||||
doPer10msCall=true;
|
||||
}
|
||||
|
||||
#else
|
||||
static uint8_t accuracyWarble;
|
||||
// static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; not start value needed
|
||||
// each tick we are 0,016msec too fast
|
||||
// one tick more means 0,048 msec too slow = 3*0,016msec --> in sum we are correct!!!
|
||||
// therefore every 4 round we need to slow down one tick
|
||||
uint8_t bump = (!(++accuracyWarble & 0x03)) ? 157 : 156;
|
||||
OCR0 += bump;
|
||||
#endif
|
||||
sei();
|
||||
|
||||
#if defined(PCBSTD) && (defined(AUDIO) || defined(VOICE))
|
||||
|
||||
#if defined(AUDIO)
|
||||
@@ -3548,6 +3512,8 @@ ISR(TIMER_10MS_VECT)
|
||||
VOICE_DRIVER();
|
||||
#endif
|
||||
|
||||
static uint8_t cnt10ms; // no initialization needed here; execute 10ms code once every 78 ISRs; takes 16.38msec to overrun for first round --> no problem
|
||||
|
||||
#if defined(FRSKY) || defined(MAVLINK) || defined(JETI)
|
||||
if (cnt10ms == 30) {
|
||||
if (!IS_DSM2_SERIAL_PROTOCOL(s_current_protocol))
|
||||
@@ -3555,8 +3521,14 @@ ISR(TIMER_10MS_VECT)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (doPer10msCall) { // BEGIN { ... every 10ms ... }
|
||||
if (--cnt10ms == 0) { // BEGIN { ... every 10ms ... }
|
||||
// Begin 10ms event
|
||||
// cnt10ms = 78;
|
||||
cnt10ms = (!(++accuracyWarble &0x07)) ? 79 : 78; // instead of assigning we add to take missed ISRs into account
|
||||
// each per10ms() we are 0,016msec too fast
|
||||
// one tick more means 0,112 msec too slow = 7*0,016msec --> in sum we are correct!!!
|
||||
// therefore every 8. round we need to slow down one tick
|
||||
|
||||
#endif
|
||||
|
||||
AUDIO_HEARTBEAT();
|
||||
@@ -3570,14 +3542,45 @@ ISR(TIMER_10MS_VECT)
|
||||
#if defined(PCBSTD) && (defined(AUDIO) || defined(VOICE))
|
||||
} // end 10ms event
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
accuracyWarble&=0x7F;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// without correction we are 0,16% too fast; that mean in one hour we are 5,76Sek too fast; we do not like that
|
||||
#if defined(PCBGRUVIN9X)
|
||||
// static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; not start value needed
|
||||
uint8_t bump = (!(++accuracyWarble & 0x03)) ? 157 : 156;
|
||||
OCR2A += bump;
|
||||
#elif defined(AUDIO) || defined(VOICE)
|
||||
// simple solution; if ISR tooks longer this round is just ignored; The problem in this case is, it takes 16msec for the next ISR --> big gap in AUDIO, VOICE and a big fault in time calculaiton if it happens
|
||||
// cnt10ms--;
|
||||
OCR0 += 2; // interrupt every 128us
|
||||
/*
|
||||
// needs to change cnt10ms to int instead uint to allow cnt10ms to be negative
|
||||
// code oost: 34 bytes
|
||||
// this solutions all missed ISRs are counted and next ISR is in about 128usec (exception is wrap around)
|
||||
cli();
|
||||
do {
|
||||
cnt10ms--;
|
||||
OCR0 += 2; // interrupt every 128us
|
||||
} while ((OCR0<TCNT0) && (OCR0>=2)); // loop in case ISR tooks too long; If it laps around, ignore additional calcuation and stop anyway
|
||||
// sei(); will be done anyway if ISR is left
|
||||
*/
|
||||
#else
|
||||
// static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; not start value needed
|
||||
// each tick we are 0,016msec too fast
|
||||
// one tick more means 0,048 msec too slow = 3*0,016msec --> in sum we are correct!!!
|
||||
// therefore every 4 round we need to slow down one tick
|
||||
uint8_t bump = (!(++accuracyWarble & 0x03)) ? 157 : 156;
|
||||
OCR0 += bump;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// #define OLD_VERSION
|
||||
|
||||
#ifdef OLD_VERSION
|
||||
|
||||
ISR(TIMER_10MS_VECT, ISR_NOBLOCK) // 10ms timer
|
||||
{
|
||||
@@ -3650,6 +3653,8 @@ ISR(TIMER_10MS_VECT, ISR_NOBLOCK) // 10ms timer
|
||||
// sei();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Timer3 used for PPM_IN pulse width capture. Counter running at 16MHz / 8 = 2MHz
|
||||
// equating to one count every half millisecond. (2 counts = 1ms). Control channel
|
||||
// count delta values thus can range from about 1600 to 4400 counts (800us to 2200us),
|
||||
|
||||
Reference in New Issue
Block a user