diff --git a/src/Makefile b/src/Makefile index 7de8d7881..cdc0d3a96 100644 --- a/src/Makefile +++ b/src/Makefile @@ -89,6 +89,14 @@ TRANSLATIONS = YES # Values = YES, NO DISPLAY_USER_DATA = NO +# FrSky Hub +# Values = YES, NO +FRSKY_HUB = YES + +# WS HowHigh +# Values = YES, NO +WS_HOW_HIGH = YES + # PXX (FrSky PCM) protocol PXX = NO @@ -101,6 +109,9 @@ SILVER = NO # CTP-1009 protocol CTP1009 = NO +# SOMO-14D module +SOMO = NO + #------- END BUILD OPTIONS --------------------------- # MCU name @@ -207,79 +218,88 @@ endif ifeq ($(PCB), STD) -# STD PCB, so ... + # STD PCB, so ... CPPDEFS += -DPCBSTD -# If Hardware PPM mode ( PB0<->BP7) switch the Backlight output with the original PPM to use hardware facility to generate precise PPM (hardware mods) -# G: TODO This prevents HARDPPM being used with FRSKY. HARDPPM needs its own option XXX + # If Hardware PPM mode ( PB0<->BP7) switch the Backlight output with the original PPM to use hardware facility to generate precise PPM (hardware mods) + # G: TODO This prevents HARDPPM being used with FRSKY. HARDPPM needs its own option XXX ifeq ($(EXT), HARDPPM) CPPDEFS += -DPPMPB7_HARDWARE endif -# If JETI-Support is enabled + # If JETI-Support is enabled ifeq ($(EXT), JETI) + MODS += J CPPDEFS += -DJETI endif -# If FRSKY-Support is enabled + # If FRSKY-Support is enabled ifeq ($(EXT), FRSKY) - CPPDEFS += -DFRSKY -DFRSKY_HUB - CPPSRC += frsky.cpp - endif - -# If FRSKY-Support is enabled - ifeq ($(EXT), FRSKY_NOHUB) + MODS += F CPPDEFS += -DFRSKY CPPSRC += frsky.cpp + # If FRSKY-Hub is enabled + ifeq ($(FRSKY_HUB), YES) + CPPDEFS += -DFRSKY_HUB + endif + # If WS HowHigh is enabled + ifeq ($(WS_HOW_HIGH), YES) + CPPDEFS += -DWS_HOW_HIGH + endif endif -# gruvin: If buzzer speaker replacment supported + # gruvin: If buzzer speaker replacment supported ifeq ($(BEEPER), SPEAKER) CPPDEFS += -DBEEPSPKR endif -# If buzzer modified (no interference with PPM jack) + # If buzzer modified (no interference with PPM jack) ifeq ($(BEEPER), BUZZER_MOD) CPPDEFS += -DBUZZER_MOD endif -# If BandGap is not rock solid + # If BandGap is not rock solid ifeq ($(BATT), UNSTABLE_BANDGAP) CPPDEFS += -DBATT_UNSTABLE_BANDGAP endif -# gruvin: Legacy support for hardware mod freeing USART1 [DEPRECATED] + # gruvin: Legacy support for hardware mod freeing USART1 [DEPRECATED] ifeq ($(USART1), FREED) CPPDEFS += -DUSART1FREED endif -# gruvin: PCM-in circuit mod for JR/Spektrum (and others) compatability + # gruvin: PCM-in circuit mod for JR/Spektrum (and others) compatability ifeq ($(PPMIN), MOD1) CPPDEFS += -DPPMIN_MOD1 endif else + # not PCB=STD, so ... ifeq ($(NAVIGATION), RE1) CPPDEFS += -DNAVIGATION_RE1 endif -# not PCB=STD, so ... CPPSRC += frsky.cpp - CPPDEFS += -DPCBV3 -DFRSKY -DFRSKY_HUB + CPPDEFS += -DPCBV3 -DFRSKY -DFRSKY_HUB -DWS_HOW_HIGH ifeq ($(PCB), V3) CPPDEFS += -DBEEPSPKR endif ifeq ($(PCB), V4) CPPDEFS += -DPCBV4 -# Temporary hack to get stock beeper working for testing, etc ... make BEEPER=BUZZER_MOD + # Temporary hack to get stock beeper working for testing, etc ... make BEEPER=BUZZER_MOD + # TODO should not be needed / tested here in V4 ifeq ($(BEEPER), BUZZER_MOD) CPPDEFS += -DBUZZER_MOD else CPPDEFS += -DBEEPSPKR endif endif + ifeq ($(SOMO), YES) + CPPSRC += somo14d.cpp + CPPDEFS += -DSOMO + endif endif @@ -294,6 +314,7 @@ ifeq ($(TRANSLATIONS), YES) endif ifeq ($(HELI), YES) + MODS += H CPPDEFS += -DHELI endif @@ -618,6 +639,7 @@ stamp: @echo "#define TIME_STR \"`date +%H:%I:%S`\"" >> stamp-gruvin9x.h @echo "#define TAG_VERS $(SUB_VER)-$(THEUSER)" >> stamp-gruvin9x.h @echo "#define SVN_VERS \"$(BUILD_DIR)-r$(REV)\"" >> stamp-gruvin9x.h + @echo "#define MOD_VERS \"$(MODS)\"" >> stamp-gruvin9x.h @echo "#define BUILD_NUM $(BUILD_NUM)" >> stamp-gruvin9x.h @cat stamp-gruvin9x.h diff --git a/src/drivers.cpp b/src/drivers.cpp index 552afa45d..2c8487ffe 100644 --- a/src/drivers.cpp +++ b/src/drivers.cpp @@ -302,8 +302,8 @@ void per10ms() # if defined (PCBV4) - keys[BTN_RE1].input(~PIND & 0b00100000, BTN_RE1); - keys[BTN_RE2].input(~PIND & 0b00010000, BTN_RE2); + keys[BTN_RE1].input(~PIND & 0x20, BTN_RE1); + keys[BTN_RE2].input(~PIND & 0x10, BTN_RE2); uint8_t tin = ~PINL; uint8_t in; @@ -437,6 +437,8 @@ void per10ms() } #ifndef SIMU + if (frskyUsrStreaming > 0) + frskyUsrStreaming--; if (frskyStreaming > 0) { frskyStreaming--; } diff --git a/src/frsky.cpp b/src/frsky.cpp index 188cb27b7..bbec40c1a 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -21,7 +21,6 @@ #include "gruvin9x.h" #include "frsky.h" #include "ff.h" // TODO -// #include // TODO // Enumerate FrSky packet codes #define LINKPKT 0xfe @@ -38,14 +37,12 @@ #define BYTESTUFF 0x7d #define STUFF_MASK 0x20 -#define FRSKY_RX_PACKET_SIZE 19 -#define FRSKY_TX_PACKET_SIZE 12 - uint8_t frskyRxBuffer[FRSKY_RX_PACKET_SIZE]; // Receive buffer. 9 bytes (full packet), worst case 18 bytes with byte-stuffing (+1) uint8_t frskyTxBuffer[FRSKY_TX_PACKET_SIZE]; // Ditto for transmit buffer uint8_t frskyTxBufferCount = 0; uint8_t FrskyRxBufferReady = 0; uint8_t frskyStreaming = 0; +uint8_t frskyUsrStreaming = 0; FrskyData frskyTelemetry[2]; FrskyData frskyRSSI[2]; @@ -58,8 +55,8 @@ struct FrskyAlarm { struct FrskyAlarm frskyAlarms[4]; -#ifdef FRSKY_HUB -struct FrskyHubData frskyHubData; +#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) +FrskyHubData frskyHubData; #endif void frskyPushValue(uint8_t *&ptr, uint8_t value) @@ -152,6 +149,17 @@ void parseTelemHubByte(uint8_t byte) ((uint8_t*)&frskyHubData)[structPos+1] = byte; state = TS_IDLE; } +#endif + +#ifdef WS_HOW_HIGH +void parseTelemWSHowHighByte(uint8_t byte) +{ + if (frskyUsrStreaming < (FRSKY_TIMEOUT10ms*3 - 10)) // At least 100mS passed since last data received + ((uint8_t*)&frskyHubData)[offsetof(FrskyHubData, baroAltitude)] = byte; + else + ((uint8_t*)&frskyHubData)[offsetof(FrskyHubData, baroAltitude)+1] = byte; + frskyUsrStreaming = FRSKY_TIMEOUT10ms*3; // reset counter +} #endif /* @@ -191,15 +199,21 @@ void processFrskyPacket(uint8_t *packet) frskyRSSI[1].set(packet[4] / 2); break; +#if defined(FRSKY_HUB) || defined (WS_HOW_HIGH) case USRPKT: // User Data packet -#ifdef FRSKY_HUB uint8_t numBytes = 3 + (packet[1] & 0x07); // sanitize in case of data corruption leading to buffer overflow for (uint8_t i=3; i + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) * - * frsky.cpp original authors - Bryan J.Rentoul (Gruvin) and Philip Moss Adapted from jeti.cpp code by Karl - * Szmutny * + * Original contributors + * - Philip Moss Adapted first frsky functions from jeti.cpp code by + * - Karl Szmutny * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -18,6 +21,9 @@ #ifndef FRSKY_H #define FRSKY_H +#define FRSKY_RX_PACKET_SIZE 19 +#define FRSKY_TX_PACKET_SIZE 12 + #include // .20 seconds @@ -40,7 +46,7 @@ struct FrskyData { void set(uint8_t value); }; -#ifdef FRSKY_HUB +#if defined(FRSKY_HUB) struct FrskyHubData { int16_t gpsAltitude_bp; // before punct int16_t temperature1; // -20 .. 250 deg. celcius @@ -70,12 +76,17 @@ struct FrskyHubData { int16_t accelY; // 1/256th gram (-8g ~ +8g) int16_t accelZ; // 1/256th gram (-8g ~ +8g) }; - -extern struct FrskyHubData frskyHubData; +extern FrskyHubData frskyHubData; +#elif defined(WS_HOW_HIGH) +struct FrskyHubData { + uint16_t baroAltitude; // 0..9,999 meters +}; +extern FrskyHubData frskyHubData; #endif // Global Fr-Sky telemetry data variables extern uint8_t frskyStreaming; // >0 (true) == data is streaming in. 0 = nodata detected for some time +extern uint8_t frskyUsrStreaming; #define SEND_MODEL_ALARMS 4 #define SEND_RSSI_ALARMS (SEND_MODEL_ALARMS + 2) diff --git a/src/main_views.cpp b/src/main_views.cpp index 4b942dacb..352e016dc 100644 --- a/src/main_views.cpp +++ b/src/main_views.cpp @@ -41,6 +41,8 @@ uint8_t tabViews[] = { 1, /*e_timer2*/ #if defined(FRSKY_HUB) 4, /*e_telemetry*/ +#elif defined(WS_HOW_HIGH) + 3, /*e_telemetry*/ #elif defined(FRSKY) 2, /*e_telemetry*/ #endif @@ -110,6 +112,15 @@ void menuMainView(uint8_t event) case EVT_KEY_BREAK(KEY_RIGHT): case EVT_KEY_BREAK(KEY_LEFT): if (switchView != 255) break; +#if defined(FRSKY) +#if defined(FRSKY_HUB) && defined(WS_HOW_HIGH) + tabViews[e_telemetry] = (g_model.frsky.usrProto == 0 ? 2 : (g_model.frsky.usrProto == 1 ? 4 : 3)); +#elif defined(FRSKY_HUB) + tabViews[e_telemetry] = (g_model.frsky.usrProto == 1 ? 4 : 2); +#elif defined(WS_HOW_HIGH) + tabViews[e_telemetry] = (g_model.frsky.usrProto == 2 ? 3 : 2); +#endif +#endif g_eeGeneral.view = (view + (event == EVT_KEY_BREAK(KEY_RIGHT) ? ALTERNATE_VIEW : tabViews[view_base]*ALTERNATE_VIEW-ALTERNATE_VIEW)) % (tabViews[view_base]*ALTERNATE_VIEW); eeDirty(EE_GENERAL); beepKey(); @@ -196,7 +207,7 @@ void menuMainView(uint8_t event) trim2OfsSwLock = trimSw; #ifdef FRSKY - if (view_base == e_telemetry && view > ALTERNATE_VIEW) { + if (view_base == e_telemetry && frskyStreaming && view > ALTERNATE_VIEW) { putsModelName(0, 0, g_model.name, g_eeGeneral.currModel, 0); uint8_t att = (g_vbat100mV < g_eeGeneral.vBatWarn ? BLINK : 0); putsVBat(14*FW,0,att); @@ -272,7 +283,7 @@ void menuMainView(uint8_t event) uint8_t x0,y0; int16_t val = g_chans512[i]; //val += g_model.limitData[i].revert ? g_model.limitData[i].offset : -g_model.limitData[i].offset; - switch(view_base) + switch(view_base) // TODO optim with if (view_base == e_e_outputValues) ... else ... { case e_outputValues: x0 = (i%4*9+3)*FW/2; @@ -306,8 +317,31 @@ void menuMainView(uint8_t event) } } } -#ifdef FRSKY - else if(view_base == e_telemetry) { + else if (view_base == e_inputs) { + if (view == e_inputs) { + // hardware inputs + doMainScreenGrphics(); + for (uint8_t i=0; i<6; i++) { + int8_t sw1 = (i<3 ? 1+i : 4+i); + int8_t sw2 = (sw1 == 9 ? (getSwitch(4, 0) ? 4 : (getSwitch(5, 0) ? 5 : 6)) : sw1); + putsSwitches(i<3 ? 2*FW-2: 17*FW-1, (i%3)*FH+4*FH, sw2, getSwitch(sw1, 0) ? INVERS : 0); + } + } + else { + // virtual inputs + for (uint8_t i=0; i<8; i++) { + int16_t val = g_chans512[8+i]; + int8_t len = limit((int16_t)0, (int16_t)(((val+1024) * BAR_HEIGHT) / 2048), (int16_t)BAR_HEIGHT); + V_BAR(SCREEN_WIDTH/2-5*4+2+i*5, SCREEN_HEIGHT-8, len) + } + for (uint8_t i=0; i<12; i++) { + if ((i%6) < 3) lcd_puts_P(i<6 ? 2*FW-2 : 16*FW-2, (i%3)*FH+4*FH, PSTR("SW")); + lcd_putcAtt((i<6 ? 2*FW-2 : 16*FW-2) + 2 * FW + ((i%6) < 3 ? 0 : FW), (i%3)*FH+4*FH, i<9 ? '1'+i : 'A'+i-9, getSwitch(10+i, 0) ? INVERS : 0); + } + } + } +#if defined(FRSKY) + else if (view_base == e_telemetry) { static uint8_t displayCount = 0; static uint8_t staticTelemetry[2]; static uint8_t staticRSSI[2]; @@ -329,7 +363,7 @@ void menuMainView(uint8_t event) for (int i=0; i<2; i++) { if (g_model.frsky.channels[i].ratio) { blink = (alarmRaised[i] ? INVERS : 0); - lcd_puts_P(x0, 3*FH, PSTR("A =")); + lcd_puts_P(x0, 3*FH, PSTR("A :")); lcd_putc(x0+FW, 3*FH, '1'+i); x0 += 3*FW; val = ((uint16_t)staticTelemetry[i]+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255; @@ -378,17 +412,25 @@ void menuMainView(uint8_t event) } #endif - lcd_puts_P(0, 6*FH, PSTR("Rx=")); + lcd_puts_P(0, 6*FH, PSTR("Rx:")); lcd_outdezAtt(3 * FW, 5*FH+2, staticRSSI[0], DBLSIZE|LEFT); lcd_outdezAtt(4 * FW, 7*FH, frskyRSSI[0].min, 0); lcd_outdezAtt(6 * FW, 7*FH, frskyRSSI[0].max, LEFT); - lcd_puts_P(11 * FW - 2, 6*FH, PSTR("Tx=")); + lcd_puts_P(11 * FW - 2, 6*FH, PSTR("Tx:")); lcd_outdezAtt(14 * FW - 2, 5*FH+2, staticRSSI[1], DBLSIZE|LEFT); lcd_outdezAtt(15 * FW - 2, 7*FH, frskyRSSI[1].min, 0); lcd_outdezAtt(17 * FW - 2, 7*FH, frskyRSSI[1].max, LEFT); } +#ifdef WS_HOW_HIGH + else if (g_model.frsky.usrProto == PROTO_WS_HOW_HIGH && view == e_telemetry+2*ALTERNATE_VIEW) { + lcd_puts_P(0, 4*FH, PSTR("Alt:")); + uint16_t value = frskyHubData.baroAltitude; + lcd_outdezAtt(4*FW, 3*FH, (value * 32) / 105, DBLSIZE|LEFT); + lcd_putc(lcd_lastPos, 4*FH, 'm') ; + } +#endif #ifdef FRSKY_HUB - else if (g_eeGeneral.view == e_telemetry+2*ALTERNATE_VIEW) { // if on second alternate telemetry view + else if (g_model.frsky.usrProto == PROTO_FRSKY_HUB && view == e_telemetry+2*ALTERNATE_VIEW) { // Date lcd_outdezNAtt(1*FW, 1*FH, frskyHubData.year+2000, LEFT, 4); lcd_putc(lcd_lastPos, 1*FH, '-'); @@ -441,8 +483,7 @@ void menuMainView(uint8_t event) lcd_outdezAtt(lcd_lastPos+2, 7*FH, frskyHubData.gpsAltitude_ap, LEFT|UNSIGN); // after '.' lcd_putc(lcd_lastPos, 7*FH, 'm'); } - else if (g_eeGeneral.view == e_telemetry+3*ALTERNATE_VIEW) { // if on second alternate telemetry view - + else if (g_model.frsky.usrProto == PROTO_FRSKY_HUB && view == e_telemetry+3*ALTERNATE_VIEW) { uint8_t y = 2*FH; // Temperature 1 @@ -485,15 +526,15 @@ void menuMainView(uint8_t event) // Acceleromter lcd_puts_P(11*FW, y, PSTR("Accel")); y += FH; - lcd_puts_P(11*FW, y, PSTR("x=")); + lcd_puts_P(11*FW, y, PSTR("x:")); lcd_outdezNAtt(FW*17, y, (int32_t)frskyHubData.accelX * 100 / 256, PREC2); lcd_putc(lcd_lastPos, y, 'g'); y += FH; - lcd_puts_P(11*FW, y, PSTR("y=")); + lcd_puts_P(11*FW, y, PSTR("y:")); lcd_outdezNAtt(FW*17, y, (int32_t)frskyHubData.accelY * 100 / 256, PREC2); lcd_putc(lcd_lastPos, y, 'g'); y += FH; - lcd_puts_P(11*FW, y, PSTR("z=")); + lcd_puts_P(11*FW, y, PSTR("z:")); lcd_outdezNAtt(FW*17, y, (int32_t)frskyHubData.accelZ * 100 / 256, PREC2); lcd_putc(lcd_lastPos, y, 'g'); } @@ -505,7 +546,7 @@ void menuMainView(uint8_t event) for (int i=0; i<2; i++) { if (g_model.frsky.channels[i].ratio) { blink = (alarmRaised[i] ? INVERS+BLINK : 0)|LEFT; - lcd_puts_P(x0, y0, PSTR("A =")); + lcd_puts_P(x0, y0, PSTR("A :")); lcd_putc(x0+FW, y0, '1'+i); val = ((int16_t)staticTelemetry[i]+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255; putsTelemetry(x0+3*FW, y0, val, g_model.frsky.channels[i].type, blink); @@ -514,9 +555,9 @@ void menuMainView(uint8_t event) } y0+=FH; //lcd_puts_P(2*FW-3, y0, PSTR("RSSI:")); - lcd_puts_P(4*FW-3, y0, PSTR("Rx=")); + lcd_puts_P(4*FW-3, y0, PSTR("Rx:")); lcd_outdezAtt(7*FW-3, y0, staticRSSI[0], LEFT); - lcd_puts_P(13*FW-3, y0, PSTR("Tx=")); + lcd_puts_P(13*FW-3, y0, PSTR("Tx:")); lcd_outdezAtt(16*FW-3, y0, staticRSSI[1], LEFT); } } @@ -525,29 +566,6 @@ void menuMainView(uint8_t event) } } #endif - else if (view_base == e_inputs) { - if (view == e_inputs) { - // hardware inputs - doMainScreenGrphics(); - for (uint8_t i=0; i<6; i++) { - int8_t sw1 = (i<3 ? 1+i : 4+i); - int8_t sw2 = (sw1 == 9 ? (getSwitch(4, 0) ? 4 : (getSwitch(5, 0) ? 5 : 6)) : sw1); - putsSwitches(i<3 ? 2*FW-2: 17*FW-1, (i%3)*FH+4*FH, sw2, getSwitch(sw1, 0) ? INVERS : 0); - } - } - else { - // virtual inputs - for (uint8_t i=0; i<8; i++) { - int16_t val = g_chans512[8+i]; - int8_t len = limit((int16_t)0, (int16_t)(((val+1024) * BAR_HEIGHT) / 2048), (int16_t)BAR_HEIGHT); - V_BAR(SCREEN_WIDTH/2-5*4+2+i*5, SCREEN_HEIGHT-8, len) - } - for (uint8_t i=0; i<12; i++) { - if ((i%6) < 3) lcd_puts_P(i<6 ? 2*FW-2 : 16*FW-2, (i%3)*FH+4*FH, PSTR("SW")); - lcd_putcAtt((i<6 ? 2*FW-2 : 16*FW-2) + 2 * FW + ((i%6) < 3 ? 0 : FW), (i%3)*FH+4*FH, i<9 ? '1'+i : 'A'+i-9, getSwitch(10+i, 0) ? INVERS : 0); - } - } - } else { // timer2 putsTime(33+FW+2, FH*5, timer2, DBLSIZE, DBLSIZE); } diff --git a/src/model_menus.cpp b/src/model_menus.cpp index 8ebb9af26..e29af2cdb 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -1727,7 +1727,11 @@ void menuProcSafetySwitches(uint8_t event) #ifdef FRSKY void menuProcTelemetry(uint8_t event) { - MENU("TELEMETRY", menuTabModel, e_Telemetry, 13, {0, -1, 1, 0, 1, 2, 2, -1, 1, 0, 1, 2/*, 2*/}); +#if defined FRSKY_HUB || defined WS_HOW_HIGH + MENU("TELEMETRY", menuTabModel, e_Telemetry, 14, {0, -1, 1, 0, 1, 2, 2, -1, 1, 0, 1, 2, 2, 0}); +#else + MENU("TELEMETRY", menuTabModel, e_Telemetry, 13, {0, -1, 1, 0, 1, 2, 2, -1, 1, 0, 1, 2, 2}); +#endif int8_t sub = m_posVert; uint8_t blink; @@ -1820,6 +1824,23 @@ void menuProcTelemetry(uint8_t event) subN++; } } + +#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) + if(s_pgOfs