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