From bd7ab010ca8a9a71103d1a3b95c6995d9d761073 Mon Sep 17 00:00:00 2001 From: bsongis Date: Thu, 1 Mar 2012 21:10:18 +0000 Subject: [PATCH] FrSky did introduce 2us jitter since last optimization Makefile minor update Google tests fixed Momentary switches in FUNC SWITCHES screen (not finished) Trim parameter in Mixer is OFF if the source is not a stick --- src/Makefile | 26 +++++----- src/frsky.cpp | 116 +++++++++++++++++++++++--------------------- src/frsky.h | 4 +- src/gtests.cpp | 3 ++ src/lcd.cpp | 30 +++++++----- src/lcd.h | 5 +- src/main_views.cpp | 4 +- src/model_menus.cpp | 10 ++-- src/myeeprom.h | 24 +++++++++ src/open9x.cpp | 52 ++++++++++---------- src/open9x.h | 4 ++ src/templates.h | 3 -- 12 files changed, 161 insertions(+), 120 deletions(-) diff --git a/src/Makefile b/src/Makefile index 80db36daf..f45300040 100644 --- a/src/Makefile +++ b/src/Makefile @@ -529,9 +529,7 @@ MSG_FLASH = Creating load file for Flash: MSG_EEPROM = Creating load file for EEPROM: MSG_EXTENDED_LISTING = Creating Extended Listing: MSG_SYMBOL_TABLE = Creating Symbol Table: -MSG_LINKING = Linking: -MSG_COMPILING = Compiling C: -MSG_COMPILING_CPP = Compiling C++: +MSG_COMPILING = Compiling C++: MSG_ASSEMBLING = Assembling: MSG_CLEANING = Cleaning project: MSG_CREATING_LIBRARY = Creating library: @@ -539,7 +537,6 @@ MSG_CREATING_LIBRARY = Creating library: # Compiler flags to generate dependency files. GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d - # Combine all necessary flags and optional flags. # Add target processor to flags. ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(AVRGCCFLAGS) -fwhole-program @@ -554,8 +551,7 @@ BUILD_DIR = $(shell pwd | awk -F'/' '{print $$((NF-1))}') all: begin gccversion sizebefore build sizeafter end # Change the build target to build a HEX file or a library. -build: stamp_header font.lbm font_dblsize.lbm sticks.lbm s9xsplash.lbm elf hex eep lss sym - +build: stamp_header font.lbm font_dblsize.lbm sticks.lbm s9xsplash.lbm allsrc elf remallsrc hex eep lss sym elf: $(TARGET).elf hex: $(TARGET).hex @@ -566,8 +562,6 @@ sym: $(TARGET).sym # Build stamp-file stamp_header: @echo - @echo $(CPPSRC) - @echo "Generate Version-stamp:" @echo "//Automatically generated file (Makefile) - do not edit" > stamp-open9x.h @echo "#define DATE_STR \"`date +%Y-%m-%d`\"" >> stamp-open9x.h @@ -746,14 +740,19 @@ extcoff: $(TARGET).elf @echo $(MSG_SYMBOL_TABLE) $@ $(NM) -n $< > $@ -# Link: create ELF output file from object files. -%.elf: - @echo - @echo $(MSG_LINKING) $@ +# Concatenate all sources files in one big file to optimize size +allsrc: $(CPPSRC) cat $(CPPSRC) > allsrc.cpp + +remallsrc: + $(REMOVE) allsrc.cpp + +# Link: create ELF output file from object files. +%.elf: allsrc @echo + @echo $(MSG_COMPILING) $@ $(CC) $(ALL_CPPFLAGS) allsrc.cpp --output $@ $(LDFLAGS) - + # Target: clean project. clean: begin clean_list end @@ -775,6 +774,7 @@ clean_list : $(REMOVE) $(SRC:.c=.s) $(REMOVE) *.o $(REMOVE) *.d + $(REMOVE) allsrc.cpp $(REMOVEDIR) .dep # Include the dependency files. diff --git a/src/frsky.cpp b/src/frsky.cpp index d52726469..e2706ffd0 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -343,17 +343,75 @@ void processFrskyPacket(uint8_t *packet) */ #ifndef SIMU + +NOINLINE void processSerialData(uint8_t stat, uint8_t data) +{ + static uint8_t numPktBytes = 0; + static uint8_t dataState = frskyDataIdle; + + if (stat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) + { // discard buffer and start fresh on any comms error + FrskyRxBufferReady = 0; + numPktBytes = 0; + } + else + { + if (FrskyRxBufferReady == 0) // can't get more data if the buffer hasn't been cleared + { + switch (dataState) + { + case frskyDataStart: + if (data == START_STOP) break; // Remain in userDataStart if possible 0x7e,0x7e doublet found. + + if (numPktBytes < FRSKY_RX_PACKET_SIZE) + frskyRxBuffer[numPktBytes++] = data; + dataState = frskyDataInFrame; + break; + + case frskyDataInFrame: + if (data == BYTESTUFF) + { + dataState = frskyDataXOR; // XOR next byte + break; + } + if (data == START_STOP) // end of frame detected + { + processFrskyPacket(frskyRxBuffer); // FrskyRxBufferReady = 1; + dataState = frskyDataIdle; + break; + } + if (numPktBytes < FRSKY_RX_PACKET_SIZE) + frskyRxBuffer[numPktBytes++] = data; + break; + + case frskyDataXOR: + if (numPktBytes < FRSKY_RX_PACKET_SIZE) + frskyRxBuffer[numPktBytes++] = data ^ STUFF_MASK; + dataState = frskyDataInFrame; + break; + + case frskyDataIdle: + if (data == START_STOP) + { + numPktBytes = 0; + dataState = frskyDataStart; + } + break; + + } // switch + } // if (FrskyRxBufferReady == 0) + } +} + ISR(USART0_RX_vect) { uint8_t stat; uint8_t data; - static uint8_t numPktBytes = 0; - static uint8_t dataState = frskyDataIdle; - UCSR0B &= ~(1 << RXCIE0); // disable Interrupt sei() ; + stat = UCSR0A; // USART control and Status Register 0 A /* @@ -387,58 +445,8 @@ ISR(USART0_RX_vect) data = UDR0; // USART data register 0 - if (stat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) - { // discard buffer and start fresh on any comms error - FrskyRxBufferReady = 0; - numPktBytes = 0; - } - else - { - if (FrskyRxBufferReady == 0) // can't get more data if the buffer hasn't been cleared - { - switch (dataState) - { - case frskyDataStart: - if (data == START_STOP) break; // Remain in userDataStart if possible 0x7e,0x7e doublet found. + processSerialData(stat, data); - if (numPktBytes < FRSKY_RX_PACKET_SIZE) - frskyRxBuffer[numPktBytes++] = data; - dataState = frskyDataInFrame; - break; - - case frskyDataInFrame: - if (data == BYTESTUFF) - { - dataState = frskyDataXOR; // XOR next byte - break; - } - if (data == START_STOP) // end of frame detected - { - processFrskyPacket(frskyRxBuffer); // FrskyRxBufferReady = 1; - dataState = frskyDataIdle; - break; - } - if (numPktBytes < FRSKY_RX_PACKET_SIZE) - frskyRxBuffer[numPktBytes++] = data; - break; - - case frskyDataXOR: - if (numPktBytes < FRSKY_RX_PACKET_SIZE) - frskyRxBuffer[numPktBytes++] = data ^ STUFF_MASK; - dataState = frskyDataInFrame; - break; - - case frskyDataIdle: - if (data == START_STOP) - { - numPktBytes = 0; - dataState = frskyDataStart; - } - break; - - } // switch - } // if (FrskyRxBufferReady == 0) - } cli() ; UCSR0B |= (1 << RXCIE0); // enable Interrupt } diff --git a/src/frsky.h b/src/frsky.h index 261b616d6..474427775 100644 --- a/src/frsky.h +++ b/src/frsky.h @@ -70,7 +70,7 @@ class FrskyData: public FrskyRSSI { #define EARTH_RADIUS ((uint32_t)111194) #if defined(FRSKY_HUB) -struct FrskyHubData { +PACK(struct FrskyHubData { int16_t baroAltitudeOffset;// spare reused int16_t gpsAltitude_bp; // 0x01 before punct int16_t temperature1; // 0x02 -20 .. 250 deg. celcius @@ -116,7 +116,7 @@ struct FrskyHubData { // end of FrSky Hub data uint16_t gpsDistance; uint16_t maxGpsSpeed; -}; +}); #elif defined(WS_HOW_HIGH) diff --git a/src/gtests.cpp b/src/gtests.cpp index 6b5387a4f..469e15404 100644 --- a/src/gtests.cpp +++ b/src/gtests.cpp @@ -207,6 +207,9 @@ TEST(EEPROM, rm) { extern void processFrskyPacket(uint8_t *packet); TEST(FrSky, gpsNfuel) { + g_model.frsky.usrProto = 1; + frskyHubData.gpsFix = 1; + uint8_t pkt1[] = { 0xfd, 0x07, 0x00, 0x5e, 0x14, 0x2c, 0x00, 0x5e, 0x1c, 0x03 }; uint8_t pkt2[] = { 0xfd, 0x07, 0x00, 0x00, 0x5e, 0x13, 0x38, 0x0c, 0x5e, 0x1b }; uint8_t pkt3[] = { 0xfd, 0x07, 0x00, 0xc9, 0x06, 0x5e, 0x23, 0x4e, 0x00, 0x5e }; diff --git a/src/lcd.cpp b/src/lcd.cpp index 1ab9ccade..219ed7431 100644 --- a/src/lcd.cpp +++ b/src/lcd.cpp @@ -494,13 +494,23 @@ void putsModelName(uint8_t x, uint8_t y, char *name, uint8_t id, uint8_t att) void putsSwitches(uint8_t x, uint8_t y, int8_t idx, uint8_t att) { - switch(idx){ - case 0: lcd_putsiAtt(x, y, STR_MMMINV, 0, att);return; - case MAX_SWITCH: lcd_putsiAtt(x, y, STR_OFFON, 1, att);return; - case -MAX_SWITCH: lcd_putsiAtt(x, y, STR_OFFON, 0, att);return; + if (idx == 0) + return lcd_putsiAtt(x, y, STR_MMMINV, 0, att); + if (~att & SWONLY) { + if (idx == MAX_SWITCH) + return lcd_putsiAtt(x, y, STR_OFFON, 1, att); + if (idx == -MAX_SWITCH) + return lcd_putsiAtt(x, y, STR_OFFON, 0, att); } - if (idx<0) lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/); - lcd_putsiAtt(x, y, STR_VSWITCHES, abs(idx)-1, att); + if (idx<0) { + lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/); + idx = -idx; + } + if (idx >= MAX_SWITCH) { + idx -= ((att & SWONLY) ? MAX_SWITCH-1 : MAX_SWITCH); + if (~att & SWCONDENSED) lcd_putcAtt(x+3*FW, y, 'm', att); + } + lcd_putsiAtt(x, y, STR_VSWITCHES, idx-1, att); } void putsFlightPhase(uint8_t x, uint8_t y, int8_t idx, uint8_t att) @@ -529,13 +539,7 @@ void putsTmrMode(uint8_t x, uint8_t y, int8_t mode, uint8_t att) return; } - if (mode < TMR_VAROFS+MAX_SWITCH-1) { // normal on-off - putsSwitches(x, y, mode-(TMR_VAROFS-1), att); - } - else { - putsSwitches(x, y, mode-(TMR_VAROFS+MAX_SWITCH-2), att); // momentary on-off - if (~att & SHRT_TM_MODE) lcd_putcAtt(x+3*FW, y, 'm', att); - } + putsSwitches(x, y, mode-(TMR_VAROFS-1), att|SWONLY); } #ifdef FRSKY diff --git a/src/lcd.h b/src/lcd.h index ebf3cf5bf..a4b398439 100644 --- a/src/lcd.h +++ b/src/lcd.h @@ -68,9 +68,12 @@ #define WHITE 0x04 #define ROUND 0x08 +/* switches flags */ +#define SWONLY 0x40 /* means no ON OFF, only switches */ +#define SWCONDENSED 0x80 /* means that THRm will be displayed as THR */ + /* other flags */ #define NO_UNIT UNSIGN -#define SHRT_TM_MODE LEFT #define TWO_DOTS LEFT extern uint8_t displayBuf[DISPLAY_W*DISPLAY_H/8]; diff --git a/src/main_views.cpp b/src/main_views.cpp index 33382d459..840c2e7a9 100644 --- a/src/main_views.cpp +++ b/src/main_views.cpp @@ -188,7 +188,7 @@ void menuMainView(uint8_t event) if (g_model.timer1.mode) { uint8_t att = DBLSIZE | (s_timerState[0]==TMR_BEEPING ? BLINK : 0); putsTime(12*FW+3, FH*2, s_timerVal[0], att, att); - putsTmrMode(s_timerVal[0] >= 0 ? 9*FW-FW/2+5 : 9*FW-FW/2-2, FH*3, g_model.timer1.mode, SHRT_TM_MODE); + putsTmrMode(s_timerVal[0] >= 0 ? 9*FW-FW/2+5 : 9*FW-FW/2-2, FH*3, g_model.timer1.mode, SWCONDENSED); } // trim sliders @@ -298,7 +298,7 @@ void menuMainView(uint8_t event) } else { // timer2 putsTime(33+FW+2, FH*5, s_timerVal[1], DBLSIZE, DBLSIZE); - putsTmrMode(s_timerVal[1] >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timer2.mode, SHRT_TM_MODE); + putsTmrMode(s_timerVal[1] >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timer2.mode, SWCONDENSED); // lcd_outdezNAtt(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s } diff --git a/src/model_menus.cpp b/src/model_menus.cpp index a9276cefa..8d0ace278 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -1206,11 +1206,9 @@ void menuProcMixOne(uint8_t event) if (attr) CHECK_INFLIGHT_INCDEC_MODELVAR(event, md2->sOffset, -125, 125, 0, STR_MIXEROFFSET); break; case 3: - // TODO hidden when src is not a STICK as it has no sense lcd_puts(2*FW, y, STR_TRIM); - // lcd_putsnAtt(FW*10, y, STR_OFFON+LEN_OFFON*(1-md2->carryTrim), LEN_OFFON, attr); - lcd_putsiAtt(FW*10, y, STR_VMIXTRIMS, md2->carryTrim, attr); // TODO perhaps could be optimized by reusing STR_OFFON - if (attr) CHECK_INCDEC_MODELVAR( event, md2->carryTrim, 0, 2); + lcd_putsiAtt(FW*10, y, STR_VMIXTRIMS, (md2->srcRaw <= 4) ? md2->carryTrim : 1, attr); + if (attr) CHECK_INCDEC_MODELVAR( event, md2->carryTrim, TRIM_ON, TRIM_OFFSET); break; case 4: lcd_puts(2*FW, y, STR_CURVES); @@ -1760,9 +1758,9 @@ void menuProcFunctionSwitches(uint8_t event) uint8_t active = (attr && (s_editMode>0 || p1valdiff)); switch (j) { case 0: - putsSwitches(1*FW, y, sd->swtch, attr); + putsSwitches(3, y, sd->swtch, attr); if (active) { - CHECK_INCDEC_MODELVAR( event, sd->swtch, -MAX_SWITCH, MAX_SWITCH); + CHECK_INCDEC_MODELVAR( event, sd->swtch, -MAX_SWITCH-MAX_PSWITCH-NUM_CSW, MAX_SWITCH+MAX_PSWITCH+NUM_CSW); } break; case 1: diff --git a/src/myeeprom.h b/src/myeeprom.h index de81e048d..2673a95a4 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -151,10 +151,34 @@ PACK(typedef struct t_LimitData { #define MIX_CYC2 11 #define MIX_CYC3 12 +#define TRIM_ON 0 +#define TRIM_OFF 1 +#define TRIM_OFFSET 2 + #define MLTPX_ADD 0 #define MLTPX_MUL 1 #define MLTPX_REP 2 +/* +PACK(typedef struct t_MixData { + uint8_t destCh:5; // 0, 1..NUM_CHNOUT + uint16_t differential:7; + int16_t phase:4; // -5=!FP4, 0=normal, 5=FP4 + int8_t weight; + int8_t swtch:6; + uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := + int8_t curve:6; + uint8_t mixWarn:2; // mixer warning + uint8_t delayUp:4; + uint8_t delayDown:4; + uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle) + uint8_t speedDown:4; // 0 nichts + uint8_t carryTrim:2; + uint8_t srcRaw:6; // + int8_t sOffset; +}) MixData; +*/ + PACK(typedef struct t_MixData { uint8_t destCh:5; // 0, 1..NUM_CHNOUT uint8_t mixWarn:3; // mixer warning diff --git a/src/open9x.cpp b/src/open9x.cpp index b87bfad54..fdb400224 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -294,7 +294,6 @@ void applyExpos(int16_t *anas, uint8_t phase) } /*TODO evaluate impact FORCEINLINE */ -bool s_noStickInputs = false; int16_t getValue(uint8_t i) { if(i throttle trim if applicable + int16_t v = anas[i]; + int32_t vv = 2*RESX; + int16_t trim = getTrimValue(getTrimFlightPhase(i, phase), i); + if (i==THR_STICK && g_model.thrTrim) { + if (g_eeGeneral.throttleReversed) + trim = -trim; + vv = ((int32_t)trim-TRIM_MIN)*(RESX-v)/(2*RESX); + } + else if (trimsCheckTimer > 0) { + trim = 0; } - else { - // do trim -> throttle trim if applicable - int16_t v = anas[i]; - int32_t vv = 2*RESX; - int16_t trim = getTrimValue(getTrimFlightPhase(i, phase), i); - if (i==THR_STICK && g_model.thrTrim) { - if (g_eeGeneral.throttleReversed) - trim = -trim; - vv = ((int32_t)trim-TRIM_MIN)*(RESX-v)/(2*RESX); - } - else if (trimsCheckTimer > 0) { - trim = 0; - } - trims[i] = (vv==2*RESX) ? trim*2 : (int16_t)vv*2; // if throttle trim -> trim low end - } + trims[i] = (vv==2*RESX) ? trim*2 : (int16_t)vv*2; // if throttle trim -> trim low end } } +bool s_noTrainerInput = false; uint8_t evalSticks(uint8_t phase) { #ifdef HELI @@ -1047,7 +1042,7 @@ uint8_t evalSticks(uint8_t phase) if (tmp <= 1) anaCenter |= (tmp==0 ? 1<mode) { @@ -1244,9 +1239,6 @@ void perOut(int16_t *chanOut, uint8_t phase) v = anas[k]; //Switch is on. MAX=FULL=512 or value. if (k>=CHOUT_BASE && (kmixWarn) mixWarning |= 1<<(md->mixWarn-1); // Mix warning - if (md->carryTrim == 2/*TODO constant*/ && md->srcRaw <= NUM_STICKS) { - s_trimPtr[md->srcRaw-1] = &md->sOffset; // use the value stored here for the trim - } } //========== INPUT OFFSET =============== @@ -1305,8 +1297,16 @@ void perOut(int16_t *chanOut, uint8_t phase) if (md->curve) v = applyCurve(v, md->curve, md->srcRaw); - //========== TRIM =============== - if((md->carryTrim==0) && (md->srcRaw>0) && (md->srcRaw<=4)) v += trims[md->srcRaw-1]; // 0 = Trim ON = Default + //========== TRIMS =============== + if (md->srcRaw>0 && md->srcRaw<=NUM_STICKS) { + if (md->carryTrim == TRIM_ON) { + v += trims[md->srcRaw-1]; + } + if (md->carryTrim == TRIM_OFFSET) { + v = md->sOffset; + s_trimPtr[md->srcRaw-1] = &md->sOffset; // use the value stored here for the trim + } + } //========== MULTIPLEX =============== int32_t dv = (int32_t)v*md->weight; @@ -2019,9 +2019,9 @@ void instantTrim() if (i!=THR_STICK) { // don't instant trim the throttle stick uint8_t trim_phase = getTrimFlightPhase(i, phase); - s_noStickInputs = true; + s_noTrainerInput = true; evalSticks(phase); - s_noStickInputs = false; + s_noTrainerInput = false; int16_t trim = (anas[i] + trims[i]) / 2; if (trim < TRIM_EXTENDED_MIN) { trim = TRIM_EXTENDED_MIN; diff --git a/src/open9x.h b/src/open9x.h index 1c51ea3a7..338a69b0e 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -546,6 +546,10 @@ extern uint8_t s_eeDirtyMsk; #define FORCEINLINE inline __attribute__ ((always_inline)) #endif +#ifndef NOINLINE +#define NOINLINE __attribute__ ((noinline)) +#endif + /// liefert Betrag des Arguments template FORCEINLINE t abs(t a) { return a>0?a:-a; } /// liefert das Minimum der Argumente diff --git a/src/templates.h b/src/templates.h index 1e9db9753..9e1492865 100644 --- a/src/templates.h +++ b/src/templates.h @@ -69,9 +69,6 @@ #define STK_P2 6 #define STK_P3 7 -#define TRIM_ON 0 -#define TRIM_OFF 1 - #define CH(x) (CHOUT_BASE+(x)) #define CV(x) (CURVE_BASE+(x)-1) #define CC(x) (channel_order(x)) //need to invert this to work with dest