[all] Mixer bugs fixed (slow / delays)

[stock] Flash saving
[stock] PWM backlight fix
[stock] NAVIGATION=STICKS pulled from er9x, thanks Mike!
[Taranis] Telemetry logs in DEBUG mode correctly opened / closed (not tested)
This commit is contained in:
bsongis@gmail.com
2013-05-31 19:33:20 +00:00
parent 7e7b1914ff
commit c9171c6d79
15 changed files with 311 additions and 169 deletions
+5 -1
View File
@@ -71,12 +71,13 @@ HELI = NO
# Values = YES, NO
TEMPLATES = YES
# Enable navigation with Pots / Rotary encoders
# Enable navigation with Pots / Sticks / Rotary encoders
# Values = NO
# POT1 (only POT1 available for fields modification),
# POT2 (menus scroll),
# POT3 (cursor down/up),
# POTS (POT1, POT2, POT3),
# STICKS
# ROTENC (Rotary encoder)
NAVIGATION = NO
@@ -710,6 +711,9 @@ endif
ifeq ($(NAVIGATION), POTS)
CPPDEFS += -DNAVIGATION_POT1 -DNAVIGATION_POT2 -DNAVIGATION_POT3
endif
ifeq ($(NAVIGATION), STICKS)
CPPDEFS += -DNAVIGATION_STICKS
endif
ifeq ($(NAVIGATION), ROTENC)
CPPDEFS += -DROTARY_ENCODER_NAVIGATION
endif
+64 -55
View File
@@ -46,7 +46,10 @@ void doMixerCalculations();
#define MIXER_RESET() \
memset(channelOutputs, 0, sizeof(channelOutputs)); \
memset(ex_chans, 0, sizeof(ex_chans))
memset(ex_chans, 0, sizeof(ex_chans)); \
memset(act, 0, sizeof(act)); \
memset(swOn, 0, sizeof(swOn)); \
int32_t lastAct = 0; lastAct = lastAct; /* to avoid a warning */
uint16_t anaInValues[NUM_STICKS+NUM_POTS] = { 0 };
uint16_t anaIn(uint8_t chan)
@@ -282,8 +285,8 @@ TEST(FrSky, dateNtime)
TEST(getSwitch, undefCSW)
{
MODEL_RESET();
EXPECT_EQ(getSwitch(MAX_PSWITCH, 0), false);
EXPECT_EQ(getSwitch(-MAX_PSWITCH, 0), true); // no good answer there!
EXPECT_EQ(getSwitch(MAX_PSWITCH), false);
EXPECT_EQ(getSwitch(-MAX_PSWITCH), true); // no good answer there!
}
TEST(getSwitch, circularCSW)
@@ -291,18 +294,16 @@ TEST(getSwitch, circularCSW)
MODEL_RESET();
g_model.customSw[0] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_OR };
g_model.customSw[1] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_AND };
EXPECT_EQ(getSwitch(MAX_SWITCH-NUM_CSW, 0), false);
EXPECT_EQ(getSwitch(-(MAX_SWITCH-NUM_CSW), 0), true);
EXPECT_EQ(getSwitch(1+MAX_SWITCH-NUM_CSW, 0), false);
EXPECT_EQ(getSwitch(-(1+MAX_SWITCH-NUM_CSW), 0), true);
EXPECT_EQ(getSwitch(MAX_SWITCH-NUM_CSW), false);
EXPECT_EQ(getSwitch(-(MAX_SWITCH-NUM_CSW)), true);
EXPECT_EQ(getSwitch(1+MAX_SWITCH-NUM_CSW), false);
EXPECT_EQ(getSwitch(-(1+MAX_SWITCH-NUM_CSW)), true);
}
TEST(getSwitch, nullSW)
{
MODEL_RESET();
EXPECT_EQ(getSwitch(0, 0), false);
EXPECT_EQ(getSwitch(0, true), true);
EXPECT_EQ(getSwitch(0, 0), false);
EXPECT_EQ(getSwitch(0), true);
}
TEST(FlightModes, nullFadeOut_posFadeIn)
@@ -465,6 +466,24 @@ TEST(Mixer, RecursiveAddChannel)
EXPECT_EQ(chans[1], 0);
}
#define CHECK_SLOW_MOVEMENT(channel, sign, duration) \
do { \
for (int i=1; i<=(duration); i++) { \
perOut(e_perout_mode_normal, 1); \
lastAct = lastAct + (sign) * (1<<19)/500; /* 100 on ARM */ \
EXPECT_EQ(chans[(channel)], 256 * (lastAct >> 8)); \
} \
} while (0)
#define CHECK_DELAY(channel, duration) \
do { \
int32_t value = chans[(channel)]; \
for (int i=1; i<=(duration); i++) { \
perOut(e_perout_mode_normal, 1); \
EXPECT_EQ(chans[(channel)], value); \
} \
} while (0)
TEST(Mixer, SlowOnSwitch)
{
MODEL_RESET();
@@ -481,19 +500,10 @@ TEST(Mixer, SlowOnSwitch)
EXPECT_EQ(chans[0], 0);
simuSetSwitch(0, 1);
int32_t lastAct = 0;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct + (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, +1, 250);
simuSetSwitch(0, 0);
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct - (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, -1, 250);
}
TEST(Mixer, SlowOnPhase)
@@ -513,19 +523,10 @@ TEST(Mixer, SlowOnPhase)
perOut(e_perout_mode_normal, 0);
EXPECT_EQ(chans[0], 0);
int32_t lastAct = 0;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct+(1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, +1, 250);
s_perout_flight_phase = 1;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct - (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, -1, 250);
}
TEST(Mixer, SlowOnSwitchAndPhase)
@@ -547,20 +548,11 @@ TEST(Mixer, SlowOnSwitchAndPhase)
simuSetSwitch(0, 1);
s_perout_flight_phase = 0;
int32_t lastAct = 0;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct+(1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, +1, 250);
simuSetSwitch(0, 0);
s_perout_flight_phase = 1;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct - (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, -1, 250);
}
TEST(Mixer, SlowOnSwitchSource)
@@ -575,21 +567,38 @@ TEST(Mixer, SlowOnSwitchSource)
g_model.mixData[0].speedDown = 10;
simuSetSwitch(0, 0);
int32_t lastAct = 0;
for (int i=1; i<=250; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct - (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, -1, 250);
EXPECT_EQ(chans[0], -CHANNEL_MAX);
simuSetSwitch(0, 1);
for (int i=1; i<=500; i++) {
perOut(e_perout_mode_normal, 1);
lastAct = lastAct + (1<<19)/500; /* 100 on ARM */
EXPECT_EQ(chans[0], 256 * (lastAct >> 8));
}
CHECK_SLOW_MOVEMENT(0, +1, 500);
}
TEST(Mixer, SlowAndDelayOnReplace3POSSource)
{
MODEL_RESET();
MIXER_RESET();
g_model.mixData[0].destCh = 0;
g_model.mixData[0].mltpx = MLTPX_REP;
g_model.mixData[0].srcRaw = MIXSRC_3POS;
g_model.mixData[0].weight = 100;
g_model.mixData[0].delayUp = 10;
g_model.mixData[0].delayUp = 10;
g_model.mixData[0].speedUp = 10;
g_model.mixData[0].speedDown = 10;
simuSetSwitch(3, -1);
CHECK_SLOW_MOVEMENT(0, -1, 250);
EXPECT_EQ(chans[0], -CHANNEL_MAX);
simuSetSwitch(3, 0);
CHECK_DELAY(0, 500);
CHECK_SLOW_MOVEMENT(0, +1, 250/*half course*/);
EXPECT_EQ(chans[0], 0);
simuSetSwitch(3, 1);
CHECK_DELAY(0, 500);
CHECK_SLOW_MOVEMENT(0, +1, 250);
}
TEST(Curves, LinearIntpol)
+3
View File
@@ -960,6 +960,8 @@ void menuGeneralDiagAna(uint8_t event)
SIMPLE_MENU(STR_MENUANA, menuTabDiag, e_Ana, ANAS_ITEMS_COUNT);
STICK_SCROLL_DISABLE();
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) {
uint8_t y = 1+FH+(i/2)*FH;
uint8_t x = i&1 ? 64+5 : 0;
@@ -1134,6 +1136,7 @@ void menuCommonCalib(uint8_t event)
case 2:
// MOVE STICKS/POTS
STICK_SCROLL_DISABLE();
lcd_putsAtt(0*FW, 2*FH, STR_MOVESTICKSPOTS, s_noScroll ? INVERS : 0);
lcd_putsLeft(3*FH, STR_MENUWHENDONE);
+4 -3
View File
@@ -3466,6 +3466,7 @@ void menuModelLimits(uint8_t event)
for (uint8_t j=0; j<ITEM_LIMITS_COUNT; j++) {
uint8_t attr = ((sub==k && m_posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ;
if (active) STICK_SCROLL_DISABLE();
switch(j)
{
#if defined(PCBTARANIS)
@@ -3728,7 +3729,7 @@ void menuModelCustomSwitchOne(uint8_t event)
CustomSwData * cs = cswaddress(s_currIdx);
uint8_t sw = SWSRC_SW1+s_currIdx;
putsSwitches(14*FW, 0, sw, (getSwitch(sw, 0) ? BOLD : 0));
putsSwitches(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0));
SIMPLE_SUBMENU_NOTITLE(CSW_FIELD_COUNT);
int8_t sub = m_posVert;
@@ -3864,7 +3865,7 @@ void menuModelCustomSwitches(uint8_t event)
// CSW name
uint8_t sw = SWSRC_SW1+k;
putsSwitches(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw, 0) ? BOLD : 0));
putsSwitches(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw) ? BOLD : 0));
if (cs->func > 0) {
// CSW func
@@ -3929,7 +3930,7 @@ void menuModelCustomSwitches(uint8_t event)
// CSW name
uint8_t sw = SWSRC_SW1+k;
putsSwitches(0, y, sw, (getSwitch(sw, 0) ? BOLD : 0) | ((sub==k && m_posHorz<0) ? INVERS : 0));
putsSwitches(0, y, sw, (getSwitch(sw) ? BOLD : 0) | ((sub==k && m_posHorz<0) ? INVERS : 0));
// CSW func
lcd_putsiAtt(CSW_1ST_COLUMN, y, STR_VCSWFUNC, cs->func, m_posHorz==0 ? attr : 0);
+21 -19
View File
@@ -39,10 +39,9 @@
#if LCD_W >= 212
#define BIGSIZE MIDSIZE
#define BOX_WIDTH 31
#define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10)
#define LBOX_CENTERX (BOX_WIDTH/2 + 17)
#define LBOX_CENTERY (LCD_H-BOX_WIDTH/2-10)
#define RBOX_CENTERX (LCD_W-LBOX_CENTERX)
#define RBOX_CENTERY LBOX_CENTERY
#define MODELNAME_X (15)
#define MODELNAME_Y (11)
#define VBATT_X (MODELNAME_X+26)
@@ -69,10 +68,9 @@
#else
#define BIGSIZE DBLSIZE
#define BOX_WIDTH 23
#define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
#define LBOX_CENTERX (LCD_W/4 + 10)
#define LBOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
#define RBOX_CENTERX (3*LCD_W/4 - 10)
#define RBOX_CENTERY LBOX_CENTERY
#define MODELNAME_X (2*FW-2)
#define MODELNAME_Y (0)
#define PHASE_X (6*FW)
@@ -128,22 +126,24 @@ void drawPotsBars()
}
}
void drawStick(uint8_t centrex, int16_t xval, int16_t yval)
{
lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
DO_CROSS(centrex, BOX_CENTERY, 3);
lcd_square(centrex + (xval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/BOX_LIMIT)) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
}
void doMainScreenGraphics()
{
lcd_square(LBOX_CENTERX-BOX_WIDTH/2, LBOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
lcd_square(RBOX_CENTERX-BOX_WIDTH/2, RBOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
DO_CROSS(LBOX_CENTERX, LBOX_CENTERY, 3)
DO_CROSS(RBOX_CENTERX, RBOX_CENTERY, 3)
int16_t calibStickVert = calibratedStick[CONVERT_MODE(1+1)-1];
if (g_model.throttleReversed && CONVERT_MODE(1+1)-1 == THR_STICK)
calibStickVert = -calibStickVert;
lcd_square(LBOX_CENTERX+(calibratedStick[CONVERT_MODE(0+1)-1]*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, LBOX_CENTERY-(calibStickVert*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
drawStick(LBOX_CENTERX, calibratedStick[CONVERT_MODE(0+1)-1], calibStickVert);
calibStickVert = calibratedStick[CONVERT_MODE(2+1)-1];
if (g_model.throttleReversed && CONVERT_MODE(2+1)-1 == THR_STICK)
calibStickVert = -calibStickVert;
lcd_square(RBOX_CENTERX+(calibratedStick[CONVERT_MODE(3+1)-1]*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, RBOX_CENTERY-(calibStickVert*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
drawStick(RBOX_CENTERX, calibratedStick[CONVERT_MODE(3+1)-1], calibStickVert);
#if !defined(PCBTARANIS)
drawPotsBars();
@@ -451,6 +451,8 @@ void onMainViewMenu(const char *result)
void menuMainView(uint8_t event)
{
STICK_SCROLL_DISABLE();
#if !defined(PCBTARANIS)
uint8_t view = g_eeGeneral.view;
uint8_t view_base = view & 0x0f;
@@ -678,7 +680,7 @@ void menuMainView(uint8_t event)
uint8_t x = LCD_W/2+7*FW+col*FW;
uint8_t y = LCD_H/2-7+line*8;
lcd_putcAtt(x, y, sw>=9 ? 'A'+sw-9 : '1'+sw, SMLSIZE);
if (getSwitch(SWSRC_SW1+sw, 0))
if (getSwitch(SWSRC_SW1+sw))
lcd_filled_rect(x-1, y-1, 6, 8);
sw++;
}
@@ -752,7 +754,7 @@ void menuMainView(uint8_t event)
x = 17*FW-1;
y -= 3*FH;
}
putsSwitches(x, y, sw, getSwitch(i, 0) ? INVERS : 0);
putsSwitches(x, y, sw, getSwitch(i) ? INVERS : 0);
}
}
else {
@@ -773,23 +775,23 @@ void menuMainView(uint8_t event)
// Custom Switches
#if defined(PCBSKY9X)
for (uint8_t i=0; i<NUM_CSW; i++) {
int8_t len = getSwitch(SWSRC_SW1+i, 0) ? BAR_HEIGHT : 1;
int8_t len = getSwitch(SWSRC_SW1+i) ? BAR_HEIGHT : 1;
uint8_t x = VSWITCH_X(i);
lcd_vline(x-1, VSWITCH_Y-len, len);
lcd_vline(x, VSWITCH_Y-len, len);
}
#elif defined(PCBGRUVIN9X) && ROTARY_ENCODERS > 2
for (uint8_t i=0; i<NUM_CSW; i++)
putsSwitches(2*FW-2 + (i/3)*(4*FW-2) + (i/3>1 ? 3*FW+6 : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i, 0) ? INVERS : 0);
putsSwitches(2*FW-2 + (i/3)*(4*FW-2) + (i/3>1 ? 3*FW+6 : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#elif defined(PCBGRUVIN9X)
for (uint8_t i=0; i<NUM_CSW; i++)
putsSwitches(2*FW-2 + (i/3)*(4*FW-2) + (i/3>1 ? 3*FW : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i, 0) ? INVERS : 0);
putsSwitches(2*FW-2 + (i/3)*(4*FW-2) + (i/3>1 ? 3*FW : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#elif !defined(PCBSTD)
for (uint8_t i=0; i<NUM_CSW; i++)
putsSwitches(2*FW-2 + (i/3)*(4*FW-1), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i, 0) ? INVERS : 0);
putsSwitches(2*FW-2 + (i/3)*(4*FW-1), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#else
for (uint8_t i=0; i<NUM_CSW; i++)
putsSwitches(2*FW-2 + (i/3)*(5*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i, 0) ? INVERS : 0);
putsSwitches(2*FW-2 + (i/3)*(5*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0);
#endif
}
}
+1 -1
View File
@@ -91,7 +91,7 @@ void Key::input(bool val, EnumKeys enuk)
//fallthrough
case KSTATE_START:
putEvent(EVT_KEY_FIRST(enuk));
inacCounter = 0;
inactivity.counter = 0;
m_state = KSTATE_RPTDELAY;
m_cnt = 0;
break;
+132 -48
View File
@@ -627,7 +627,7 @@ void applyExpos(int16_t *anas, uint8_t mode)
continue;
if (ed.phases & (1<<s_perout_flight_phase))
continue;
if (getSwitch(ed.swtch, 1)) {
if (getSwitch(ed.swtch)) {
int16_t v = anas2[ed.chn];
if((v<0 && (ed.mode&1)) || (v>=0 && (ed.mode&2))) {
#if defined(BOLD_FONT)
@@ -897,10 +897,9 @@ getvalue_t getValue(uint8_t i)
}
#if defined(CPUARM)
#define GETSWITCH_RECURSIVE_TYPE uint32_t
volatile bool s_default_switch_value;
#define GETSWITCH_RECURSIVE_TYPE uint32_t
#else
#define GETSWITCH_RECURSIVE_TYPE uint16_t
#define GETSWITCH_RECURSIVE_TYPE uint16_t
#endif
volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_used;
@@ -920,11 +919,7 @@ bool __getSwitch(int8_t swtch)
bool result;
if (swtch == 0)
#if defined(CPUARM)
return s_default_switch_value;
#else
return s_last_switch_used & ((GETSWITCH_RECURSIVE_TYPE)1<<15);
#endif
return true;
uint8_t cs_idx = abs(swtch);
@@ -1094,16 +1089,10 @@ bool __getSwitch(int8_t swtch)
return swtch > 0 ? result : !result;
}
bool getSwitch(int8_t swtch, bool nc)
bool getSwitch(int8_t swtch)
{
#if defined(CPUARM)
s_last_switch_used = 0;
s_last_switch_value = 0;
s_default_switch_value = nc;
#else
s_last_switch_used = ((GETSWITCH_RECURSIVE_TYPE)nc<<15);
s_last_switch_value = 0;
#endif
return __getSwitch(swtch);
}
@@ -1195,7 +1184,7 @@ uint8_t getFlightPhase()
{
for (uint8_t i=1; i<MAX_PHASES; i++) {
PhaseData *phase = &g_model.phaseData[i];
if (phase->swtch && getSwitch(phase->swtch, 0)) {
if (phase->swtch && getSwitch(phase->swtch)) {
return i;
}
}
@@ -1511,9 +1500,9 @@ void checkBacklight()
if (tmr10ms != x) {
tmr10ms = x;
uint16_t tsum = stickMoveValue();
if (tsum != inacSum) {
inacSum = tsum;
inacCounter = 0;
if (tsum != inactivity.sum) {
inactivity.sum = tsum;
inactivity.counter = 0;
if (g_eeGeneral.backlightMode & e_backlight_mode_sticks)
backlightOn();
}
@@ -2129,10 +2118,8 @@ int16_t rawAnas [NUM_INPUTS] = {0};
int16_t anas [NUM_INPUTS] = {0};
int16_t trims[NUM_STICKS] = {0};
int32_t chans[NUM_CHNOUT] = {0};
uint8_t inacPrescale;
uint16_t inacCounter = 0;
uint16_t inacSum = 0;
BeepANACenter bpanaCenter = 0;
struct t_inactivity inactivity = {0};
int24_t act [MAX_MIXERS] = {0};
SwOn swOn [MAX_MIXERS]; // TODO better name later...
@@ -2489,7 +2476,7 @@ void evalFunctions()
swtch += MAX_SWITCH+1;
}
bool active = getSwitch(swtch, 0);
bool active = getSwitch(swtch);
if (active) newActiveSwitches |= switch_mask;
if (momentary || short_long) {
@@ -2739,8 +2726,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
}
#if defined(HELI)
if(g_model.swashR.value)
{
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 = calc100toRESX(g_model.swashR.value);
q *= q;
@@ -2755,20 +2741,18 @@ void perOut(uint8_t mode, uint8_t tick10ms)
#define REZ_SWASH_X(x) ((x) - (x)/8 - (x)/128 - (x)/512) // 1024*sin(60) ~= 886
#define REZ_SWASH_Y(x) ((x)) // 1024 => 1024
if(g_model.swashR.type)
{
if (g_model.swashR.type) {
getvalue_t vp = anas[ELE_STICK]+trims[ELE_STICK];
getvalue_t vr = anas[AIL_STICK]+trims[AIL_STICK];
getvalue_t vc = 0;
if (g_model.swashR.collectiveSource)
vc = getValue(g_model.swashR.collectiveSource-1);
if(g_model.swashR.invertELE) vp = -vp;
if(g_model.swashR.invertAIL) vr = -vr;
if(g_model.swashR.invertCOL) vc = -vc;
if (g_model.swashR.invertELE) vp = -vp;
if (g_model.swashR.invertAIL) vr = -vr;
if (g_model.swashR.invertCOL) vc = -vc;
switch (g_model.swashR.type)
{
switch (g_model.swashR.type) {
case SWASH_TYPE_120:
vp = REZ_SWASH_Y(vp);
vr = REZ_SWASH_X(vr);
@@ -2834,7 +2818,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
//========== PHASE && SWITCH =====
bool mixCondition = (md->phases != 0 || md->swtch);
int8_t mixEnabled = !(md->phases & (1 << s_perout_flight_phase)) && getSwitch(md->swtch, 1);
int8_t mixEnabled = !(md->phases & (1 << s_perout_flight_phase)) && getSwitch(md->swtch);
//========== VALUE ===============
getvalue_t v = 0;
@@ -2848,7 +2832,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
}
else {
if (k < NUM_STICKS) {
v = md->noExpo ? rawAnas[k] : anas[k]; //Switch is on. MAX=FULL=512 or value.
v = md->noExpo ? rawAnas[k] : anas[k];
}
else {
v = getValue(k);
@@ -2859,34 +2843,32 @@ void perOut(uint8_t mode, uint8_t tick10ms)
if (dirtyChannels & ((bitfield_channels_t)1 << (k-MIXSRC_CH1+1)) & (passDirtyChannels|~(((bitfield_channels_t) 1 << md->destCh)-1)))
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] >> 8;
}
}
}
bool apply_offset_and_curve = true;
//========== DELAYS ===============
// ========== DELAYS ===============
int8_t _swOn = swOn[i].now;
int8_t _swPrev = swOn[i].prev;
bool swTog = (mixEnabled != _swOn);
// if (i==0) { printf("mixEnabled=%d swOn=%d swPrev=%d sDelay=%d mixCondition=%d\n", mixEnabled, _swOn, _swPrev, sDelay[i], mixCondition); fflush(stdout); }
if (swTog) {
if (mode==e_perout_mode_normal && swTog) {
if (!swOn[i].delay) _swPrev = _swOn;
swOn[i].delay = (mixEnabled > _swOn ? md->delayUp : md->delayDown) * (100/DELAY_STEP);
swOn[i].now = mixEnabled;
swOn[i].prev = _swPrev;
}
if (swOn[i].delay > 0) {
if (mode==e_perout_mode_normal && swOn[i].delay > 0) {
swOn[i].delay = max<int16_t>(0, (int16_t)swOn[i].delay - tick10ms);
if (!mixCondition)
v = _swPrev << 10; // TODO optim?
v = _swPrev << 10;
else if (mixEnabled)
continue;
}
else if (!mixEnabled) {
if (md->speedDown) {
if (md->mltpx == MLTPX_REP) continue;
if (mixCondition) {
v = 0;
apply_offset_and_curve = false;
@@ -3039,7 +3021,7 @@ void perOut(uint8_t mode, uint8_t tick10ms)
else {
if ((tmp.words_t.hi|0x007F)!=0x007F) tmp.words_t.hi=0x0079; // set to max nearly
}
*ptr=tmp.dword;
*ptr = tmp.dword;
// this implementation saves 18bytes flash
/* dv=*ptr>>8;
@@ -3143,7 +3125,7 @@ void doMixerCalculations()
for (uint8_t p=0; p<MAX_PHASES; p++) {
if (s_fade_flight_phases & ((ACTIVE_PHASES_TYPE)1 << p)) {
s_perout_flight_phase = p;
perOut(p==phase?e_perout_mode_normal:e_perout_mode_inactive_phase, tick10ms);
perOut(p==phase?e_perout_mode_normal:e_perout_mode_inactive_phase, p==phase?tick10ms:0);
for (uint8_t i=0; i<NUM_CHNOUT; i++)
sum_chans512[i] += (chans[i] >> 4) * fp_act[p];
weight += fp_act[p];
@@ -3260,7 +3242,7 @@ void doMixerCalculations()
if (atm>=(TMR_VAROFS+MAX_SWITCH)){ // toggeled switch
if(!(sw_toggled[i] | s_sum[i] | s_cnt[i] | lastSwPos[i])) { lastSwPos[i] = tm < 0; s_sum[i] = 1; } // if initializing then init the lastSwPos
uint8_t swPos = getSwitch(tm>0 ? tm-(TMR_VAROFS+MAX_SWITCH-1) : tm+MAX_SWITCH, 0);
uint8_t swPos = getSwitch(tm>0 ? tm-(TMR_VAROFS+MAX_SWITCH-1) : tm+MAX_SWITCH);
if (swPos && !lastSwPos[i]) sw_toggled[i] = !sw_toggled[i]; // if switch is flipped first time -> change counter state
lastSwPos[i] = swPos;
}
@@ -3298,7 +3280,7 @@ void doMixerCalculations()
}
else {
if (atm<(TMR_VAROFS+MAX_SWITCH))
sw_toggled[i] = tm>0 ? getSwitch(tm-(TMR_VAROFS-1), 0) : !getSwitch(-tm, 0); // normal switch
sw_toggled[i] = tm>0 ? getSwitch(tm-(TMR_VAROFS-1)) : !getSwitch(-tm); // normal switch
if (sw_toggled[i])
newTimerVal++;
}
@@ -3354,8 +3336,11 @@ void doMixerCalculations()
s_time_tot += 100;
s_timeCumTot += 1;
inacCounter++;
if ((((uint8_t)inacCounter)&0x07)==0x01 && g_eeGeneral.inactivityTimer && g_vbat100mV>50 && inacCounter > ((uint16_t)g_eeGeneral.inactivityTimer*60))
struct t_inactivity *ptrInactivity = &inactivity;
FORCE_INDIRECT(ptrInactivity) ;
ptrInactivity->counter++;
if ((((uint8_t)ptrInactivity->counter)&0x07)==0x01 && g_eeGeneral.inactivityTimer && g_vbat100mV>50 && ptrInactivity->counter > ((uint16_t)g_eeGeneral.inactivityTimer*60))
AUDIO_INACTIVITY();
#if defined(AUDIO)
@@ -3448,6 +3433,41 @@ void doMixerCalculations()
#endif
}
#if defined(NAVIGATION_STICKS)
uint8_t StickScrollAllowed;
uint8_t StickScrollTimer;
static const pm_uint8_t rate[] PROGMEM = { 0, 0, 100, 40, 16, 7, 3, 1 } ;
uint8_t calcStickScroll( uint8_t index )
{
uint8_t direction ;
int8_t value ;
if ( ( g_eeGeneral.stickMode & 1 ) == 0 )
{
index ^= 3 ;
}
value = calibratedStick[index] / 128 ;
direction = value > 0 ? 0x80 : 0 ;
if ( value < 0 )
{
value = -value ; // (abs)
}
if ( value > 7 )
{
value = 7 ;
}
value = pgm_read_byte(rate+(uint8_t)value) ;
if ( value )
{
StickScrollTimer = STICK_SCROLL_TIMEOUT ; // Seconds
}
return value | direction ;
}
#endif
void perMain()
{
#if defined(SIMU)
@@ -3595,6 +3615,70 @@ void perMain()
}
#endif
#if defined(NAVIGATION_STICKS)
if (StickScrollAllowed) {
if ( StickScrollTimer ) {
static uint8_t repeater;
uint8_t direction;
uint8_t value;
if ( repeater < 128 )
{
repeater += 1;
}
value = calcStickScroll( 2 );
direction = value & 0x80;
value &= 0x7F;
if ( value )
{
if ( repeater > value )
{
repeater = 0;
if ( evt == 0 )
{
if ( direction )
{
evt = EVT_KEY_FIRST(KEY_UP);
}
else
{
evt = EVT_KEY_FIRST(KEY_DOWN);
}
}
}
}
else
{
value = calcStickScroll( 3 );
direction = value & 0x80;
value &= 0x7F;
if ( value )
{
if ( repeater > value )
{
repeater = 0;
if ( evt == 0 )
{
if ( direction )
{
evt = EVT_KEY_FIRST(KEY_RIGHT);
}
else
{
evt = EVT_KEY_FIRST(KEY_LEFT);
}
}
}
}
}
}
}
else {
StickScrollTimer = 0; // Seconds
}
StickScrollAllowed = 1 ;
#endif
lcd_clear();
const char *warn = s_warning;
uint8_t menu = s_menu_count;
+22 -5
View File
@@ -414,6 +414,15 @@ enum EnumKeys {
void watchdogSetTimeout(uint32_t timeout);
#endif
#if defined(NAVIGATION_STICKS)
extern uint8_t StickScrollAllowed;
extern uint8_t StickScrollTimer;
#define STICK_SCROLL_TIMEOUT 9
#define STICK_SCROLL_DISABLE() StickScrollAllowed = 0
#else
#define STICK_SCROLL_DISABLE()
#endif
#include "eeprom_common.h"
#if defined(PCBSKY9X)
@@ -688,9 +697,12 @@ void watchdogSetTimeout(uint32_t timeout);
#define MAX_ALERT_TIME 60
extern uint8_t inacPrescale;
extern uint16_t inacCounter;
extern uint16_t inacSum;
struct t_inactivity
{
uint16_t counter;
uint16_t sum;
};
extern struct t_inactivity inactivity;
#if defined(PXX)
extern uint8_t pxxFlag[NUM_MODULES];
@@ -752,7 +764,11 @@ enum PerOutMode {
};
// Fiddle to force compiler to use a pointer
#define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr))
#if defined(CPUARM) || defined(SIMU)
#define FORCE_INDIRECT(ptr)
#else
#define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr))
#endif
extern uint8_t s_perout_flight_phase;
@@ -767,7 +783,7 @@ void perMain();
NOINLINE void per10ms();
getvalue_t getValue(uint8_t i);
bool getSwitch(int8_t swtch, bool nc);
bool getSwitch(int8_t swtch);
extern swstate_t switches_states;
int8_t getMovedSwitch();
@@ -1137,6 +1153,7 @@ PACK(typedef struct t_SwOn {
int16_t activeExpo:1;
}) SwOn;
extern SwOn swOn [MAX_MIXERS];
extern int24_t act [MAX_MIXERS];
#ifdef BOLD_FONT
inline bool isExpoActive(uint8_t expo)
+1 -1
View File
@@ -113,7 +113,7 @@ void setupPulsesDsm2(uint8_t chns)
}
if ((dsmDat[0] & BIND_BIT) && (!switchState(SW_TRN))) dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled
// TODO find a way to do that, FUNC SWITCH: if ((!(dsmDat[0] & BIND_BIT)) && getSwitch(MAX_DRSWITCH-1, 0, 0)) dsmDat[0] |= RANGECHECK_BIT; // range check function
// TODO find a way to do that, FUNC SWITCH: if ((!(dsmDat[0] & BIND_BIT)) && getSwitch(MAX_DRSWITCH-1)) dsmDat[0] |= RANGECHECK_BIT; // range check function
// else dsmDat[0] &= ~RANGECHECK_BIT;
dsmDat[1]=g_eeGeneral.currModel+1; //DSM2 Header second byte for model match
for(uint8_t i=0; i<chns; i++)
+13 -18
View File
@@ -40,27 +40,22 @@
#include "FatFs/ff.h"
#ifdef SIMU
#define ROOT_PATH "."
#define MODELS_PATH "."
#define LOGS_PATH "."
#define SOUNDS_PATH "./en"
#define SOUNDS_PATH_LNG_OFS 2
#define SYSTEM_SOUNDS_PATH SOUNDS_PATH "/SYSTEM"
#define BITMAPS_PATH "."
#define ROOT_PATH "./"
#else
#define ROOT_PATH "/"
#define MODELS_PATH "/MODELS"
#define LOGS_PATH "/LOGS" // no trailing slash = important
#define SOUNDS_PATH "/SOUNDS/en" // no trailing slash = important
#define SOUNDS_PATH_LNG_OFS 8
#define SYSTEM_SOUNDS_PATH SOUNDS_PATH "/SYSTEM" // no trailing slash = important
#define BITMAPS_PATH "/BMP"
#define ROOT_PATH "/"
#endif
#define MODELS_EXT ".bin"
#define LOGS_EXT ".csv"
#define SOUNDS_EXT ".wav"
#define BITMAPS_EXT ".bmp"
#define MODELS_PATH ROOT_PATH "MODELS"
#define LOGS_PATH ROOT_PATH "LOGS" // no trailing slash = important
#define SOUNDS_PATH ROOT_PATH "SOUNDS/en" // no trailing slash = important
#define SOUNDS_PATH_LNG_OFS (sizeof(SOUNDS_PATH)-3)
#define SYSTEM_SOUNDS_PATH SOUNDS_PATH "/SYSTEM" // no trailing slash = important
#define BITMAPS_PATH ROOT_PATH "/BMP"
#define MODELS_EXT ".bin"
#define LOGS_EXT ".csv"
#define SOUNDS_EXT ".wav"
#define BITMAPS_EXT ".bmp"
extern FATFS g_FATFS_Obj;
+4 -2
View File
@@ -247,10 +247,12 @@ long Open9xSim::onTimeout(FXObject*,FXSelector,void*)
#define SWITCH_KEY(key, swtch, states) \
static bool state##key = 0; \
static int8_t state_##swtch = 2; \
static int8_t inc_##swtch = 1; \
if (getApp()->getKeyState(KEY_##key)) { \
if (!state##key) { \
state_##swtch = (state_##swtch+1); \
if (state_##swtch == 2+states) state_##swtch = 2; \
state_##swtch = (state_##swtch+inc_##swtch); \
if (state_##swtch == 1+states) inc_##swtch = -1; \
else if (state_##swtch == 2) inc_##swtch = 1; \
state##key = true; \
} \
} \
+17 -9
View File
@@ -122,17 +122,19 @@ inline void boardInit()
#if defined(AUDIO) || defined(VOICE)
SET_TIMER_AUDIO_CTRL();
#if !defined(CPUM2561)
TIMSK |= (1<<OCIE0) | (1<<TOIE0) | (1<<TOIE2); // Enable Output-Compare and Overflow interrrupts
#endif
#elif defined(PWM_BACKLIGHT)
/** Smartieparts LED Backlight is connected to PORTB/pin7, which can be used as pwm output of timer2 **/
#if defined(SP22)
TCCR2 = (0b011 << CS20)|(1<<WGM20)|(1<<COM21)|(1<<COM20); // inv. pwm mode, clk/64
#else
TCCR2 = (0b011 << CS20)|(1<<WGM20)|(1<<COM21); // pwm mode, clk/64
#endif
#endif
#if !defined(CPUM2561)
TIMSK |= (1<<OCIE0) | (1<<TOIE0) | (1<<TOIE2); // Enable Output-Compare and Overflow interrrupts
#if defined(SP22)
TCCR2 = (0b011 << CS20)|(1<<WGM20)|(1<<COM21)|(1<<COM20); // inv. pwm mode, clk/64
#else
TCCR2 = (0b011 << CS20)|(1<<WGM20)|(1<<COM21); // pwm mode, clk/64
#endif
#if !defined(CPUM2561)
TIMSK |= (1<<OCIE0) | (1<<TOIE0); // Enable Output-Compare and Overflow interrrupts
#endif
#endif
}
#endif
@@ -268,6 +270,12 @@ void readKeysAndTrims()
#if defined(ROTARY_ENCODER_NAVIGATION)
keys[enuk].input(ROTENC_DOWN(), (EnumKeys)enuk); // Rotary Enc. Switch
#endif
#if defined(NAVIGATION_STICKS)
if (~PINB & 0x7E) {
StickScrollTimer = STICK_SCROLL_TIMEOUT ;
}
#endif
}
bool checkSlaveMode()
+1
View File
@@ -104,6 +104,7 @@ void delay_01us(uint16_t nb);
#define SD_GET_BLOCKNR() (0)
#define SD_GET_SPEED() (0)
void sdInit();
void sdDone();
void sdPoll10ms();
#define sdMountPoll()
uint32_t sdMounted();
+22 -1
View File
@@ -959,12 +959,33 @@ void sdPoll10ms()
}
}
// TODO everything here should not be in the driver layer ...
FATFS g_FATFS_Obj;
#if defined(DEBUG)
FIL g_telemetryFile = {0};
#endif
void sdInit()
{
if (f_mount(0, &g_FATFS_Obj) == FR_OK)
if (f_mount(0, &g_FATFS_Obj) == FR_OK) {
refreshSystemAudioFiles();
#if defined(DEBUG)
f_open(&g_telemetryFile, LOGS_PATH "/sport.log", FA_CREATE_ALWAYS | FA_WRITE);
#endif
}
}
void sdDone()
{
if (sdMounted()) {
audioQueue.stopSD();
closeLogs();
#if defined(DEBUG)
f_close(&g_telemetryFile);
#endif
f_mount(0, 0); // unmount SD
}
}
uint32_t sdMounted()
+1 -6
View File
@@ -107,12 +107,7 @@ void USBD_USR_DeviceResumed(void)
*/
void USBD_USR_DeviceConnected (void)
{
if (sdMounted()) {
audioQueue.stopSD();
closeLogs();
f_mount(0, 0); // unmount SD
}
sdDone();
eeCheck(true);
usbState = USB_CONNECTED;
}