diff --git a/src/Makefile b/src/Makefile index de5c5e8d1..061f0462e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -103,6 +103,10 @@ HAPTIC = NO # Values = YES, NO SP22 = NO +# Fade Backlight using PWM +# Values = YES, NO +PWM_BACKLIGHT = NO + # SPLASH on START # Values = YES, NO, FIXED SPLASH = YES @@ -611,6 +615,13 @@ ifeq ($(PCB), STD128) CPPDEFS += -DAUDIO CPPSRC += audio_avr.cpp else + ifeq ($(PWM_BACKLIGHT), YES) + ifeq ($(VOICE), YES) + $(error Sorry, PWM_BACKLIGHT doesnt work on Mainboards with VOICE mod.) + else + CPPDEFS += -DPWM_BACKLIGHT + endif + endif CPPSRC += beeper.cpp endif @@ -638,19 +649,26 @@ ifeq ($(PCB), STD) EXTRABOARDSRC += stock/lcd_driver.cpp EEPROMSRC = eeprom_avr.cpp PULSESSRC = pulses_avr.cpp - + ifeq ($(AUDIO), YES) CPPDEFS += -DAUDIO CPPSRC += audio_avr.cpp else + ifeq ($(PWM_BACKLIGHT), YES) + ifeq ($(VOICE), YES) + $(error Sorry, PWM_BACKLIGHT doesnt work on Mainboards with VOICE mod.) + else + CPPDEFS += -DPWM_BACKLIGHT + endif + endif CPPSRC += beeper.cpp endif - + ifeq ($(VOICE), YES) CPPSRC += stock/voice.cpp CPPDEFS += -DVOICE endif - + ifeq ($(HAPTIC), YES) CPPDEFS += -DHAPTIC CPPSRC += haptic.cpp diff --git a/src/audio_arm.cpp b/src/audio_arm.cpp index 4e6627809..5b950923d 100644 --- a/src/audio_arm.cpp +++ b/src/audio_arm.cpp @@ -137,16 +137,15 @@ void refreshModelAudioFiles() info.lfsize = sizeof(lfn); #endif - char filename[64] = SOUNDS_PATH "/"; + char filename[AUDIO_FILENAME_MAXLEN+1] = SOUNDS_PATH "/"; if (sdMounted()) { char *buf = strcat_modelname(&filename[sizeof(SOUNDS_PATH)], g_eeGeneral.currModel); *buf++ = '/'; for (uint32_t i=0; i> 24); + uint8_t index = (i >> 16) & 0xFF; + uint8_t event = i & 0xFF; #if 0 printf("isAudioFileAvailable(%08x)\n", i); fflush(stdout); #endif if (category == SYSTEM_AUDIO_CATEGORY) { - if (sdAvailableSystemAudioFiles & ((uint32_t)1 << i)) { + if (sdAvailableSystemAudioFiles & ((uint32_t)1 << event)) { strcpy(filename, SYSTEM_SOUNDS_PATH "/"); strcpy(filename+sizeof(SYSTEM_SOUNDS_PATH), audioFilenames[i]); strcat(filename+sizeof(SYSTEM_SOUNDS_PATH), SOUNDS_EXT); @@ -173,24 +174,11 @@ bool isAudioFileAvailable(uint32_t i, char * filename) } } else if (category == PHASE_AUDIO_CATEGORY) { - uint8_t index = (i >> 16) & 0xFF; - uint8_t event = i & 0xFF; - if (sdAvailablePhaseAudioFiles[index] & (1 << event)) { + if (sdAvailablePhaseAudioFiles[index] & ((uint32_t)1 << event)) { strcpy(filename, SOUNDS_PATH "/"); char *str = strcat_modelname(filename+sizeof(SOUNDS_PATH), g_eeGeneral.currModel); *str++ = '/'; - char * tmp = strcat_phasename_nodefault(str, index); - if (tmp != str) { - strcpy(tmp, suffixes[event]); - strcat(tmp, SOUNDS_EXT); - return true; - } - } - else if ((sdAvailablePhaseAudioFiles[index] >> 4) & (1 << event)) { - strcpy(filename, SOUNDS_PATH "/"); - char *str = strcat_modelname(filename+sizeof(SOUNDS_PATH), g_eeGeneral.currModel); - *str++ = '/'; - char * tmp = strcat_phasename_default(str, index); + char * tmp = strcat_phasename(str, index); if (tmp != str) { strcpy(tmp, suffixes[event]); strcat(tmp, SOUNDS_EXT); @@ -199,13 +187,11 @@ bool isAudioFileAvailable(uint32_t i, char * filename) } } else if (category == MIXER_AUDIO_CATEGORY) { - uint8_t index = (i >> 16) & 0xFF; - uint8_t event = i & 0xFF; - if (sdAvailableMixerAudioFiles[index] & (1 << event)) { + if (sdAvailableMixerAudioFiles[index] & ((uint32_t)1 << event)) { strcpy(filename, SOUNDS_PATH "/"); char *str = strcat_modelname(filename+sizeof(SOUNDS_PATH), g_eeGeneral.currModel); *str++ = '/'; - char * tmp = strcat_mixername_nodefault(str, index); + char * tmp = strcat_mixername(str, index); if (tmp != str) { strcpy(tmp, suffixes[event]); strcat(tmp, SOUNDS_EXT); @@ -290,9 +276,11 @@ void audioTimerHandle(void) void audioTask(void* pdata) { #if defined(SDCARD) - codecsInit(); - sdInit(); - AUDIO_TADA(); + if (!unexpectedShutdown) { + codecsInit(); + sdInit(); + AUDIO_TADA(); + } #endif while (1) { @@ -635,7 +623,7 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id) if (flags & PLAY_BACKGROUND) { memset(&backgroundContext.fragment, 0, sizeof(AudioFragment)); - strcpy(backgroundContext.fragment.file, filename); // TODO strncpy + strncpy(backgroundContext.fragment.file, filename, 32); backgroundContext.fragment.id = id; if (!busy()) { state = AUDIO_RESUMING; @@ -692,11 +680,11 @@ void AudioQueue::reset() void audioEvent(uint8_t e, uint8_t f) { -#ifdef SDCARD - char filename[32]; +#if defined(SDCARD) + char filename[AUDIO_FILENAME_MAXLEN+1]; #endif -#ifdef HAPTIC +#if defined(HAPTIC) haptic.event(e); //do this before audio to help sync timings #endif @@ -706,7 +694,7 @@ void audioEvent(uint8_t e, uint8_t f) } if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) { -#ifdef SDCARD +#if defined(SDCARD) if (e < AU_FRSKY_FIRST && isAudioFileAvailable(e, filename)) { audioQueue.playFile(filename); } diff --git a/src/audio_arm.h b/src/audio_arm.h index e583d6970..feca95f5a 100644 --- a/src/audio_arm.h +++ b/src/audio_arm.h @@ -37,11 +37,12 @@ #include "FatFs/ff.h" -#define AUDIO_QUEUE_LENGTH (20) -#define BEEP_DEFAULT_FREQ (70) -#define BEEP_OFFSET (10) -#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5) -#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5) +#define AUDIO_FILENAME_MAXLEN (40) +#define AUDIO_QUEUE_LENGTH (20) +#define BEEP_DEFAULT_FREQ (70) +#define BEEP_OFFSET (10) +#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5) +#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5) extern uint16_t Sine_values[]; @@ -57,7 +58,7 @@ class ToneFragment { class AudioFragment : public ToneFragment { public: - char file[32+1]; + char file[AUDIO_FILENAME_MAXLEN+1]; }; extern "C" void DAC_IRQHandler(); @@ -195,8 +196,8 @@ extern void pushPrompt(uint16_t prompt, uint8_t id=0); #define STOP_PLAY(id) audioQueue.stopPlay((id)) #define AUDIO_RESET() audioQueue.reset() #if defined(SDCARD) -#define PLAY_PHASE_OFF(phase) do { char filename[64]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_OFF, filename)) audioQueue.playFile(filename); } while (0) -#define PLAY_PHASE_ON(phase) do { char filename[64]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_ON, filename)) audioQueue.playFile(filename); } while (0) +#define PLAY_PHASE_OFF(phase) do { char filename[AUDIO_FILENAME_MAXLEN+1]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_OFF, filename)) audioQueue.playFile(filename); } while (0) +#define PLAY_PHASE_ON(phase) do { char filename[AUDIO_FILENAME_MAXLEN+1]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_ON, filename)) audioQueue.playFile(filename); } while (0) #else #define PLAY_PHASE_OFF(phase) #define PLAY_PHASE_ON(phase) diff --git a/src/frsky.cpp b/src/frsky.cpp index 09fa586a3..c935ef3ea 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -90,6 +90,23 @@ void checkMinMaxAltitude() if (frskyData.hub.baroAltitude_bp < frskyData.hub.minAltitude) frskyData.hub.minAltitude = frskyData.hub.baroAltitude_bp; } + +#if defined(VARIO) +void evalVario(int16_t altitude_bp, uint16_t altitude_ap) +{ + int32_t varioAltitude_cm = (int32_t)altitude_bp * 100 + (altitude_bp > 0 ? altitude_ap : -altitude_ap); + uint8_t varioAltitudeQueuePointer = frskyData.hub.varioAltitudeQueuePointer + 1; + if (varioAltitudeQueuePointer == VARIO_QUEUE_LENGTH) + varioAltitudeQueuePointer = 0; + frskyData.hub.varioAltitudeQueuePointer = varioAltitudeQueuePointer; + frskyData.hub.varioSpeed -= frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] ; + frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] = varioAltitude_cm - frskyData.hub.varioAltitude_cm; + frskyData.hub.varioAltitude_cm = varioAltitude_cm; + frskyData.hub.varioSpeed += frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] ; +} +#else +#define evalVario(...) +#endif #endif #if defined(FRSKY_HUB) @@ -144,21 +161,6 @@ typedef enum { TS_XOR = 0x80 // decode stuffed byte } TS_STATE; -void evalVario(int16_t altitude_bp, uint16_t altitude_ap) -{ -#if defined(VARIO) - int32_t varioAltitude_cm = (int32_t)altitude_bp * 100 + (altitude_bp > 0 ? altitude_ap : -altitude_ap); - uint8_t varioAltitudeQueuePointer = frskyData.hub.varioAltitudeQueuePointer + 1; - if (varioAltitudeQueuePointer == VARIO_QUEUE_LENGTH) - varioAltitudeQueuePointer = 0; - frskyData.hub.varioAltitudeQueuePointer = varioAltitudeQueuePointer; - frskyData.hub.varioSpeed -= frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] ; - frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] = varioAltitude_cm - frskyData.hub.varioAltitude_cm; - frskyData.hub.varioAltitude_cm = varioAltitude_cm; - frskyData.hub.varioSpeed += frskyData.hub.varioAltitudeQueue[varioAltitudeQueuePointer] ; -#endif -} - void parseTelemHubByte(uint8_t byte) { static int8_t structPos; @@ -361,9 +363,11 @@ void processFrskyPacket(uint8_t *packet) frskyData.rssi[0].set(packet[3]); frskyData.rssi[1].set(packet[4] / 2); frskyStreaming = FRSKY_TIMEOUT10ms; // reset counter only if valid frsky packets are being detected +#if defined(VARIO) uint8_t varioSource = g_model.frsky.varioSource - VARIO_SOURCE_A1; if (varioSource < 2) frskyData.hub.varioSpeed = applyChannelRatio(varioSource, frskyData.analog[varioSource].value); +#endif break; } #if defined(FRSKY_HUB) || defined (WS_HOW_HIGH) diff --git a/src/frsky.h b/src/frsky.h index 5bc1ec6c3..ab3562e0a 100644 --- a/src/frsky.h +++ b/src/frsky.h @@ -141,24 +141,39 @@ PACK(struct FrskyHubData { // TODO later uint16_t minVfas; }); - +#define FRSKY_HUB_DATA FrskyHubData hub; #elif defined(WS_HOW_HIGH) - -PACK(struct FrskyHubData { +PACK(struct WSHowHighData { int16_t baroAltitude_bp; // 0..9,999 meters int16_t baroAltitudeOffset; int16_t minAltitude; int16_t maxAltitude; +#if defined(VARIO) + int16_t varioAltitudeQueue[VARIO_QUEUE_LENGTH]; //circular buffer + uint8_t varioAltitudeQueuePointer; // circular-buffer pointer + int32_t varioAltitude_cm; + int16_t varioSpeed; // Vertical speed in cm/s +#endif }); - +#define FRSKY_HUB_DATA WSHowHighData hub; +#elif defined(VARIO) +PACK(struct VarioData { + int16_t varioAltitudeQueue[VARIO_QUEUE_LENGTH]; //circular buffer + uint8_t varioAltitudeQueuePointer; // circular-buffer pointer + int32_t varioAltitude_cm; + int16_t varioSpeed; // Vertical speed in cm/s +}); +#define FRSKY_HUB_DATA VarioData hub; +#else +#define FRSKY_HUB_DATA #endif struct FrskyData { FrskyValueWithMinMax analog[2]; FrskyValueWithMin rssi[2]; -#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) - FrskyHubData hub; -#endif + + FRSKY_HUB_DATA + uint16_t currentConsumption; uint16_t currentPrescale; uint16_t power; diff --git a/src/general_menus.cpp b/src/general_menus.cpp index 5d4e3e0b8..e0f1220e6 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -138,6 +138,8 @@ enum menuGeneralSetupItems { ITEM_SETUP_BACKLIGHT_LABEL, ITEM_SETUP_BACKLIGHT_MODE, ITEM_SETUP_BACKLIGHT_DELAY, + CASE_PWM_BACKLIGHT(ITEM_SETUP_BACKLIGHT_BRIGHTNESS_OFF) + CASE_PWM_BACKLIGHT(ITEM_SETUP_BACKLIGHT_BRIGHTNESS_ON) ITEM_SETUP_FLASH_BEEP, #if defined(SPLASH) && !defined(FSPLASH) ITEM_SETUP_DISABLE_SPLASH, @@ -162,7 +164,7 @@ void menuGeneralSetup(uint8_t event) } #endif - MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+1, {0, IF_RTCLOCK(2) IF_RTCLOCK(2) LABEL(SOUND), 0, 0, IF_AUDIO(0) IF_VOICE(0) IF_HAPTIC(LABEL(HAPTIC)) IF_HAPTIC(0) IF_HAPTIC(0) IF_HAPTIC(0) IF_PCBSKY9X(0) IF_9X(0) LABEL(ALARMS), 0, IF_PCBSKY9X(0) IF_CPUARM(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) 0, LABEL(TIMER_EVENTS), 0, 0, LABEL(BACKLIGHT), 0, 0, 0, IF_SPLASH(0) IF_FRSKY(0) IF_FRSKY(0) 0, LABEL(TX_MODE), CASE_PCBX9D(0) 1/*to force edit mode*/}); + MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+1, {0, IF_RTCLOCK(2) IF_RTCLOCK(2) LABEL(SOUND), 0, 0, IF_AUDIO(0) IF_VOICE(0) IF_HAPTIC(LABEL(HAPTIC)) IF_HAPTIC(0) IF_HAPTIC(0) IF_HAPTIC(0) IF_PCBSKY9X(0) IF_9X(0) LABEL(ALARMS), 0, IF_PCBSKY9X(0) IF_CPUARM(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) 0, LABEL(TIMER_EVENTS), 0, 0, LABEL(BACKLIGHT), 0, 0, CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, IF_SPLASH(0) IF_FRSKY(0) IF_FRSKY(0) 0, LABEL(TX_MODE), CASE_PCBX9D(0) 1/*to force edit mode*/}); uint8_t sub = m_posVert - 1; @@ -382,15 +384,15 @@ void menuGeneralSetup(uint8_t event) break; case ITEM_SETUP_THROTTLE_REVERSED: - g_eeGeneral.throttleReversed = onoffMenuItem( g_eeGeneral.throttleReversed, RADIO_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ; + g_eeGeneral.throttleReversed = onoffMenuItem(g_eeGeneral.throttleReversed, RADIO_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ; break; case ITEM_SETUP_MINUTE_BEEP: - g_eeGeneral.minuteBeep = onoffMenuItem( g_eeGeneral.minuteBeep, RADIO_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event ) ; + g_eeGeneral.minuteBeep = onoffMenuItem(g_eeGeneral.minuteBeep, RADIO_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event ) ; break; case ITEM_SETUP_COUNTDOWN_BEEP: - g_eeGeneral.preBeep = onoffMenuItem( g_eeGeneral.preBeep, RADIO_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event ) ; + g_eeGeneral.preBeep = onoffMenuItem(g_eeGeneral.preBeep, RADIO_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, attr, event ) ; break; case ITEM_SETUP_BACKLIGHT_MODE: @@ -402,16 +404,30 @@ void menuGeneralSetup(uint8_t event) break; case ITEM_SETUP_FLASH_BEEP: - g_eeGeneral.flashBeep = onoffMenuItem( g_eeGeneral.flashBeep, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ; + g_eeGeneral.flashBeep = onoffMenuItem(g_eeGeneral.flashBeep, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ; break; case ITEM_SETUP_BACKLIGHT_DELAY: - lcd_putsLeft( y, STR_BLDELAY); + lcd_putsLeft(y, STR_BLDELAY); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT); lcd_putc(lcdLastPos, y, 's'); - if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5); + if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5); break; +#if defined(PWM_BACKLIGHT) + case ITEM_SETUP_BACKLIGHT_BRIGHTNESS_OFF: + lcd_putsLeft(y, STR_BLOFFBRIGHTNESS); + lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.blOffBright, attr|LEFT); + if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.blOffBright, 0, 15); + break; + + case ITEM_SETUP_BACKLIGHT_BRIGHTNESS_ON: + lcd_putsLeft(y, STR_BLONBRIGHTNESS); + lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 15-g_eeGeneral.blOnBright, attr|LEFT); + if (attr) g_eeGeneral.blOnBright = 15 - checkIncDecGen(event, 15-g_eeGeneral.blOnBright, 0, 15); + break; +#endif + #if defined(SPLASH) && !defined(FSPLASH) case ITEM_SETUP_DISABLE_SPLASH: { diff --git a/src/logs.cpp b/src/logs.cpp index e932eb8ed..3269b4dd5 100644 --- a/src/logs.cpp +++ b/src/logs.cpp @@ -44,7 +44,7 @@ const pm_char * openLogs() // Determine and set log file filename FRESULT result; DIR folder; - char filename[24]; + char filename[32]; if (!sdMounted()) return STR_NO_SDCARD; diff --git a/src/menus.cpp b/src/menus.cpp index cbc772c3b..86a003196 100644 --- a/src/menus.cpp +++ b/src/menus.cpp @@ -718,23 +718,27 @@ int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t } #if defined(GVARS) -int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event) +int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event) { - bool invers = attr&INVERS; + uint8_t delta = (max <= 100 ? GV1_SMALL-1 : GV1_LARGE-1); + bool invers = (attr & INVERS); if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { s_editMode = !s_editMode; - value = ((value >= 126 || value <= -126) ? GET_GVAR(value, min, max, s_perout_flight_phase) : 126); + value = (value > max ? GET_GVAR(value, min, max, s_perout_flight_phase) : delta+1); eeDirty(EE_MODEL); } - if (value >= 126 || value <= -126 || (max <= 120 && value >= 121)) { + if (value > max) { if (attr & LEFT) attr -= LEFT; /* because of ZCHAR */ else x -= 2*FW+FWNUM; - int8_t idx = value - 125; + int8_t idx = value - delta; + if (invers) { + CHECK_INCDEC_MODELVAR(event, idx, -4, +5); + value = (int16_t)idx + delta; + } if (idx <= 0) { idx = 1-idx; lcd_putcAtt(x-6, y, '-', attr); } putsStrIdx(x, y, STR_GV, idx, attr); - if (invers) value = checkIncDec(event, (uint8_t)value, max <= 120 ? 121 : 126, 130, EE_MODEL); } else { lcd_outdezAtt(x, y, value, attr); diff --git a/src/menus.h b/src/menus.h index db316539c..5f15615bb 100644 --- a/src/menus.h +++ b/src/menus.h @@ -231,10 +231,12 @@ TITLE(title) int8_t selectMenuItem(uint8_t x, uint8_t y, const pm_char *label, const pm_char *values, int8_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event); uint8_t onoffMenuItem(uint8_t value, uint8_t x, uint8_t y, const pm_char *label, LcdFlags attr, uint8_t event ); int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t event); -int8_t gvarMenuItem(uint8_t x, uint8_t y, int8_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event); + #if defined(GVARS) +int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int8_t min, int8_t max, LcdFlags attr, uint8_t event); #define displayGVar(x, y, v) gvarMenuItem(x, y, v, 0, 0, 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); #define displayGVar(x, y, v) lcd_outdez8(x, y, v) #endif diff --git a/src/model_menus.cpp b/src/model_menus.cpp index f90a1b44c..7250ba0db 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -1771,7 +1771,7 @@ bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up) enum ExposFields { IF_CPUARM(EXPO_FIELD_NAME) - EXPO_FIELD_WIDTH, + EXPO_FIELD_WEIGHT, EXPO_FIELD_EXPO, IF_CURVES(EXPO_FIELD_CURVE) IF_FLIGHT_PHASES(EXPO_FIELD_FLIGHT_PHASE) @@ -1800,7 +1800,7 @@ void menuModelExpoOne(uint8_t event) editSingleName(EXPO_ONE_2ND_COLUMN+3*FW-sizeof(ed->name)*FW, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr); break; #endif - case EXPO_FIELD_WIDTH: + case EXPO_FIELD_WEIGHT: lcd_putsLeft(y, STR_WEIGHT); ed->weight = gvarMenuItem(EXPO_ONE_2ND_COLUMN+3*FW, y, ed->weight, 0, 100, attr, event); break; @@ -1881,6 +1881,24 @@ enum MixFields { MIX_FIELD_COUNT }; +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 + int16_t weight = (md->weightMode ? (int16_t)GV1_LARGE + md->weight : md->weight); + weight = gvarMenuItem(x, y, weight, -125, 125, attr, event); + if (weight <= 125) { + md->weightMode = 0; + md->weight = weight; + } + else { + md->weightMode = 1; + md->weight = weight - GV1_LARGE; + } +#endif +} + void menuModelMixOne(uint8_t event) { #if defined(PCBX9D) @@ -1948,12 +1966,27 @@ void menuModelMixOne(uint8_t event) break; case MIX_FIELD_WEIGHT: lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT); - md2->weight = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->weight, -125, 125, attr|LEFT, event); + gvarWeightItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2, attr|LEFT, event); break; case MIX_FIELD_OFFSET: + { lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET)); - md2->offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->offset, -125, 125, attr|LEFT, event); +#if defined(GVARS) + int16_t offset = (md2->offsetMode ? (int16_t)GV1_LARGE + md2->offset : md2->offset); + offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, offset, -125, 125, attr|LEFT, event); + if (offset <= 125) { + md2->offsetMode = 0; + md2->offset = offset; + } + else { + md2->offsetMode = 1; + md2->offset = offset - GV1_LARGE; + } +#else + md2->offset = gvarMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->offset, -125, 125, attr|LEFT, event); +#endif break; + } case MIX_FIELD_TRIM: { uint8_t not_stick = (md2->srcRaw > NUM_STICKS); @@ -2258,7 +2291,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) putsMixerSource(4*FW+0, y, md->srcRaw, isMixActive(i) ? BOLD : 0); - md->weight = gvarMenuItem(11*FW+3, y, md->weight, -125, 125, attr, event); + gvarWeightItem(11*FW+3, y, md, attr, event); #if defined(CPUARM) if (md->name[0]) { @@ -3425,7 +3458,7 @@ void menuModelTelemetry(uint8_t event) CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMin, -7, 7); break; case 1: - CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMin, -15, 5+min(0, g_model.frsky.varioCenterMax+5)); + CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMin, -15, 5+min(10, g_model.frsky.varioCenterMax+5)); break; case 2: CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMax, -5+max(-10, g_model.frsky.varioCenterMin-5), +15); diff --git a/src/myeeprom.h b/src/myeeprom.h index 514d0c3bb..2eb16e455 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -174,7 +174,8 @@ PACK(typedef struct t_EEGeneral { uint8_t preBeep:1; SPLASH_MODE; /* 3bits */ int8_t hapticMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all - uint8_t spare3; + uint8_t blOffBright:4; + uint8_t blOnBright:4; uint8_t lightAutoOff; uint8_t templateSetup; //RETA order according to chout_ar array int8_t PPM_Multiplier; @@ -263,23 +264,24 @@ PACK(typedef struct t_LimitData { PACK(typedef struct t_MixData { uint8_t destCh; uint16_t phases; - uint8_t curveMode:1; // O=curve, 1=differential - uint8_t noExpo:1; - int8_t carryTrim:3; - uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := - uint8_t spare:1; - int16_t weight; - int8_t swtch; - int8_t curveParam; - uint8_t mixWarn; // mixer warning - uint8_t delayUp; - uint8_t delayDown; - uint8_t speedUp; - uint8_t speedDown; - uint8_t srcRaw; - int8_t offset; - char name[LEN_EXPOMIX_NAME]; + uint8_t curveMode:1; // O=curve, 1=differential + uint8_t noExpo:1; + int8_t carryTrim:3; + uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := + uint8_t offsetMode:1; // TODO change offset to 16bits in future EEPROM + int16_t weight; + int8_t swtch; + int8_t curveParam; + uint8_t mixWarn; // mixer warning + uint8_t delayUp; + uint8_t delayDown; + uint8_t speedUp; + uint8_t speedDown; + uint8_t srcRaw; + int8_t offset; + char name[LEN_EXPOMIX_NAME]; }) MixData; +#define MD_WEIGHT(md) (md->weight) #else #define DELAY_STEP 2 #define SLOW_STEP 2 @@ -289,7 +291,8 @@ PACK(typedef struct t_MixData { uint8_t destCh:4; // 0, 1..NUM_CHNOUT uint8_t curveMode:1; // O=curve, 1=differential uint8_t noExpo:1; - uint8_t spare:2; + uint8_t weightMode:1; + uint8_t offsetMode:1; int8_t weight; int8_t swtch:6; uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := @@ -304,6 +307,17 @@ PACK(typedef struct t_MixData { int8_t curveParam; int8_t offset; }) MixData; +#if defined(GVARS) + #define MD_WEIGHT(md) (md->weightMode ? (int16_t)GV1_LARGE+md->weight : md->weight) +#else + #define MD_WEIGHT(md) (md->weight) +#endif +#endif + +#if defined(GVARS) +#define MD_OFFSET(md) (md->offsetMode ? (int16_t)GV1_LARGE+md->offset : md->offset) +#else +#define MD_OFFSET(md) (md->offset) #endif #if defined(CPUARM) diff --git a/src/open9x.cpp b/src/open9x.cpp index 8323a3de4..9b4fcc6ad 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -188,8 +188,6 @@ uint8_t zlen(const char *str, uint8_t size) char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx) { - // TODO review if all if are needed - int8_t len = 0; if (name) { @@ -278,6 +276,11 @@ void per10ms() #endif // These moved here from perOut() to improve beep trigger reliability. +#if defined(PWM_BACKLIGHT) + if (g_tmr10ms % 4 == 0) + fadeBacklight(); // increment or decrement brightness until target brightness is reached +#endif + if(mixWarning & 1) if(((g_tmr10ms&0xFF)== 0)) AUDIO_MIX_WARNING_1(); if(mixWarning & 2) if(((g_tmr10ms&0xFF)== 64) || ((g_tmr10ms&0xFF)== 72)) AUDIO_MIX_WARNING_2(); if(mixWarning & 4) if(((g_tmr10ms&0xFF)==128) || ((g_tmr10ms&0xFF)==136) || ((g_tmr10ms&0xFF)==144)) AUDIO_MIX_WARNING_3(); @@ -1070,20 +1073,21 @@ uint8_t s_gvar_timer = 0; uint8_t s_gvar_last = 0; #if defined(CPUM64) -int16_t getGVarValue(int8_t x, int16_t min, int16_t max) +int16_t getGVarValue(int16_t x, int16_t min, int16_t max) { - if (x >= -125 && x <= (max <= 120 ? 120 : 125)) - return x; + if (x > max) { + int8_t idx = (max <= 100 ? x - GV1_SMALL : x - GV1_LARGE); + int8_t mul = 1; - int8_t idx = (uint8_t)x - 126; - int8_t mul = 1; + if (idx < 0) { + idx = 1-idx; + mul = -1; + } - if (idx < 0) { - idx = 1-idx; - mul = -1; + x = GVAR_VALUE(idx, -1) * mul; } - return limit(min, GVAR_VALUE(idx, -1), max) * mul; + return limit(min, x, max); } void setGVarValue(uint8_t idx, int8_t value) @@ -1109,20 +1113,21 @@ uint8_t getGVarFlightPhase(uint8_t phase, uint8_t idx) return 0; } -int16_t getGVarValue(int8_t x, int16_t min, int16_t max, int8_t phase) +int16_t getGVarValue(int16_t x, int16_t min, int16_t max, int8_t phase) { - if (x >= -125 && x <= (max <= 120 ? 120 : 125)) - return x; + if (x > max) { + int8_t idx = (max <= 100 ? x - GV1_SMALL : x - GV1_LARGE); + int8_t mul = 1; - int8_t idx = (uint8_t)x - 126; - int8_t mul = 1; + if (idx < 0) { + idx = 1-idx; + mul = -1; + } - if (idx < 0) { - idx = 1-idx; - mul = -1; + x = GVAR_VALUE(idx, getGVarFlightPhase(phase, idx)) * mul; } - return limit(min, GVAR_VALUE(idx, getGVarFlightPhase(phase, idx)), max) * mul; + return limit(min, x, max); } void setGVarValue(uint8_t idx, int8_t value, int8_t phase) @@ -2486,7 +2491,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) //========== OFFSET =============== if (apply_offset_and_curve) { - int8_t offset = GET_GVAR(md->offset, -125, 125, s_perout_flight_phase); + int8_t offset = GET_GVAR(MD_OFFSET(md), -125, 125, s_perout_flight_phase); if (offset) v += calc100toRESX(offset); } @@ -2507,7 +2512,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) v = applyCurve(v, md->curveParam); } - int16_t weight = GET_GVAR(md->weight, -500, 500, s_perout_flight_phase); + int16_t weight = GET_GVAR(MD_WEIGHT(md), -500, 500, s_perout_flight_phase); //========== SPEED =============== if (mode == e_perout_mode_normal && (md->speedUp || md->speedDown)) { // there are delay values diff --git a/src/open9x.h b/src/open9x.h index 44c368059..36decdc15 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -84,6 +84,12 @@ #define IF_VOICE(x) #endif +#if defined(PWM_BACKLIGHT) +#define CASE_PWM_BACKLIGHT(x) x, +#else +#define CASE_PWM_BACKLIGHT(x) +#endif + #if defined(VARIO) #define IF_VARIO(x) x, #else @@ -725,17 +731,19 @@ inline bool navigationRotaryEncoder(uint8_t event) #if defined(GVARS) #if defined(CPUM64) - int16_t getGVarValue(int8_t x, int16_t min, int16_t max); + int16_t getGVarValue(int16_t x, int16_t min, int16_t max); void setGVarValue(uint8_t x, int8_t value); #define GET_GVAR(x, min, max, p) getGVarValue(x, min, max) #define SET_GVAR(idx, val, p) setGVarValue(idx, val) #else uint8_t getGVarFlightPhase(uint8_t phase, uint8_t idx); - int16_t getGVarValue(int8_t x, int16_t min, int16_t max, int8_t phase); + int16_t getGVarValue(int16_t x, int16_t min, int16_t max, int8_t phase); void setGVarValue(uint8_t x, int8_t value, int8_t phase); #define GET_GVAR(x, min, max, p) getGVarValue(x, min, max, p) #define SET_GVAR(idx, val, p) setGVarValue(idx, val, p) #endif + #define GV1_SMALL 123 + #define GV1_LARGE 1024 #define GVAR_DISPLAY_TIME 100 /*1 second*/; extern uint8_t s_gvar_timer; extern uint8_t s_gvar_last; @@ -1229,9 +1237,8 @@ void putsTelemetryValue(xcoord_t x, uint8_t y, lcdint_t val, uint8_t unit, uint8 uint8_t zlen(const char *str, uint8_t size); char * strcat_zchar(char * dest, char * name, uint8_t size, const char *defaultName, uint8_t defaultNameSize, uint8_t defaultIdx); #define strcat_modelname(dest, idx) strcat_zchar(dest, modelNames[idx], LEN_MODEL_NAME, STR_MODEL, PSIZE(TR_MODEL), idx+1) -#define strcat_phasename_default(dest, idx) strcat_zchar(dest, NULL, 0, STR_FP, PSIZE(TR_FP), idx) -#define strcat_phasename_nodefault(dest, idx) strcat_zchar(dest, g_model.phaseData[idx].name, LEN_FP_NAME, NULL, 0, 0) -#define strcat_mixername_nodefault(dest, idx) strcat_zchar(dest, g_model.mixData[idx].name, LEN_EXPOMIX_NAME, NULL, 0, 0) +#define strcat_phasename(dest, idx) strcat_zchar(dest, g_model.phaseData[idx].name, LEN_FP_NAME, NULL, 0, 0) +#define strcat_mixername(dest, idx) strcat_zchar(dest, g_model.mixData[idx].name, LEN_EXPOMIX_NAME, NULL, 0, 0) #define ZLEN(s) zlen(s, sizeof(s)) #endif diff --git a/src/stock/board_stock.cpp b/src/stock/board_stock.cpp index 581385e10..df7d91f04 100644 --- a/src/stock/board_stock.cpp +++ b/src/stock/board_stock.cpp @@ -64,6 +64,15 @@ inline void boardInit() OCR0 = 156; #endif +#if 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< bl_current) + OCR2 = pgm_read_word(&pwmtable[++bl_current]); + else + OCR2 = pgm_read_word(&pwmtable[--bl_current]); + } +} + +#endif diff --git a/src/stock/board_stock.h b/src/stock/board_stock.h index b195f71d3..8505c2309 100644 --- a/src/stock/board_stock.h +++ b/src/stock/board_stock.h @@ -83,6 +83,16 @@ bool checkSlaveMode(); #define JACK_PPM_OUT() PORTG &= ~(1<