diff --git a/radio/src/gui/128x64/model_custom_scripts.cpp b/radio/src/gui/128x64/model_custom_scripts.cpp index f1063e9a8..4ff56e735 100644 --- a/radio/src/gui/128x64/model_custom_scripts.cpp +++ b/radio/src/gui/128x64/model_custom_scripts.cpp @@ -37,7 +37,7 @@ void onModelCustomScriptMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a lua file in the list copySelection(sd.file, result, sizeof(sd.file)); memset(sd.inputs, 0, sizeof(sd.inputs)); diff --git a/radio/src/gui/128x64/model_display.cpp b/radio/src/gui/128x64/model_display.cpp index dc740822b..03cd4c094 100644 --- a/radio/src/gui/128x64/model_display.cpp +++ b/radio/src/gui/128x64/model_display.cpp @@ -73,7 +73,7 @@ void onTelemetryScriptFileSelectionMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file)); storageDirty(EE_MODEL); diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp index 479a0b544..8b7aa6b33 100644 --- a/radio/src/gui/128x64/model_select.cpp +++ b/radio/src/gui/128x64/model_select.cpp @@ -56,7 +56,7 @@ void onModelSelectMenu(const char * result) SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); } #if defined(SDCARD) - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); POPUP_WARNING(eeRestoreModel(sub, (char *)result)); diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index a972a83a6..e8fbd9643 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -276,7 +276,7 @@ enum MenuModelSetupItems { void onPXX2BindMenu(const char * result) { - if (result) { + if (result != STR_EXIT) { reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex = (result - reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]) / sizeof(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]); reusableBuffer.moduleSetup.pxx2.bindStep = BIND_RX_NAME_SELECTED; } diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index f266afffa..46f1b5d53 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -57,12 +57,12 @@ void onCustomFunctionsFileSelectionMenu(const char * result) strcpy(directory, SOUNDS_PATH); strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); } - if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), NULL)) { + if (!sdListFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), nullptr)) { POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); POPUP_MENU_UNSET_BSS_FLAG(); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cfn->play.name, result, sizeof(cfn->play.name)); storageDirty(eeFlags); @@ -96,7 +96,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else if (result) { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } diff --git a/radio/src/gui/212x64/model_custom_scripts.cpp b/radio/src/gui/212x64/model_custom_scripts.cpp index bd9f81969..c78c06d8e 100644 --- a/radio/src/gui/212x64/model_custom_scripts.cpp +++ b/radio/src/gui/212x64/model_custom_scripts.cpp @@ -29,7 +29,7 @@ void onModelCustomScriptMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a lua file in the list copySelection(sd.file, result, sizeof(sd.file)); memset(sd.inputs, 0, sizeof(sd.inputs)); diff --git a/radio/src/gui/212x64/model_display.cpp b/radio/src/gui/212x64/model_display.cpp index 72191bfbe..0f17b6b1b 100644 --- a/radio/src/gui/212x64/model_display.cpp +++ b/radio/src/gui/212x64/model_display.cpp @@ -72,7 +72,7 @@ void onTelemetryScriptFileSelectionMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file)); storageDirty(EE_MODEL); diff --git a/radio/src/gui/212x64/model_select.cpp b/radio/src/gui/212x64/model_select.cpp index d4bf5d37d..758abc31b 100644 --- a/radio/src/gui/212x64/model_select.cpp +++ b/radio/src/gui/212x64/model_select.cpp @@ -55,7 +55,7 @@ void onModelSelectMenu(const char * result) POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(nametmp, sizeof(g_model.header.name), 0); } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); POPUP_WARNING(eeRestoreModel(sub, (char *)result)); diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 1425787ae..ef98e47a2 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -148,7 +148,7 @@ void onModelSetupBitmapMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a bmp file in the list copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index 50ffa5869..3bdbfbc74 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -56,7 +56,7 @@ void onCustomFunctionsFileSelectionMenu(const char * result) POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cfn->play.name, result, sizeof(cfn->play.name)); storageDirty(eeFlags); @@ -129,7 +129,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else if (result) { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } diff --git a/radio/src/gui/480x272/model_custom_scripts.cpp b/radio/src/gui/480x272/model_custom_scripts.cpp index 9a5fba277..96ab0b6ca 100644 --- a/radio/src/gui/480x272/model_custom_scripts.cpp +++ b/radio/src/gui/480x272/model_custom_scripts.cpp @@ -29,7 +29,7 @@ void onModelCustomScriptMenu(const char *result) POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a lua file in the list copySelection(sd.file, result, sizeof(sd.file)); memset(sd.inputs, 0, sizeof(sd.inputs)); diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index fd9930933..5ac81e2e8 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -151,7 +151,7 @@ void onModelSetupBitmapMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a bmp file in the list copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); storageDirty(EE_MODEL); diff --git a/radio/src/gui/480x272/model_special_functions.cpp b/radio/src/gui/480x272/model_special_functions.cpp index 9e9695645..7d4d6c46c 100644 --- a/radio/src/gui/480x272/model_special_functions.cpp +++ b/radio/src/gui/480x272/model_special_functions.cpp @@ -56,7 +56,7 @@ void onCustomFunctionsFileSelectionMenu(const char * result) POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { // The user choosed a file in the list memcpy(cf->play.name, result, sizeof(cf->play.name)); storageDirty(eeFlags); @@ -128,7 +128,7 @@ void onAdjustGvarSourceLongEnterPress(const char * result) CFN_PARAM(cfn) = 0; storageDirty(EE_MODEL); } - else if (result) { + else if (result != STR_EXIT) { onSourceLongEnterPress(result); } } diff --git a/radio/src/gui/480x272/screens_setup.cpp b/radio/src/gui/480x272/screens_setup.cpp index 800e584fb..749bd50c2 100644 --- a/radio/src/gui/480x272/screens_setup.cpp +++ b/radio/src/gui/480x272/screens_setup.cpp @@ -53,7 +53,7 @@ void onZoneOptionFileSelectionMenu(const char * result) POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } - else if (result) { + else if (result != STR_EXIT) { fileSelectionDone = true; memcpy(fileSelection, result, sizeof(fileSelection)); } diff --git a/radio/src/gui/common/stdlcd/popups.cpp b/radio/src/gui/common/stdlcd/popups.cpp index f0e1881d8..e4dfe0e5f 100644 --- a/radio/src/gui/common/stdlcd/popups.cpp +++ b/radio/src/gui/common/stdlcd/popups.cpp @@ -65,7 +65,7 @@ void showMessageBox(const char * title) const char * runPopupMenu(event_t event) { - const char * result = NULL; + const char * result = nullptr; uint8_t display_count = min(popupMenuItemsCount, MENU_MAX_DISPLAY_LINES); uint8_t y = LCD_H / 2 - (popupMenuTitle ? 0 : 3) - (display_count * FH / 2); @@ -149,7 +149,11 @@ const char * runPopupMenu(event_t event) #endif case EVT_KEY_BREAK(KEY_ENTER): result = popupMenuItems[s_menu_item + (popupMenuOffsetType == MENU_OFFSET_INTERNAL ? popupMenuOffset : 0)]; - // no break + popupMenuItemsCount = 0; + s_menu_item = 0; + popupMenuOffset = 0; + popupMenuTitle = nullptr; + break; #if defined(CASE_EVT_ROTARY_LONG) CASE_EVT_ROTARY_LONG @@ -158,6 +162,7 @@ const char * runPopupMenu(event_t event) #endif case EVT_KEY_BREAK(KEY_EXIT): + result = STR_EXIT; popupMenuItemsCount = 0; s_menu_item = 0; popupMenuOffset = 0; diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 32be237c9..7a088558e 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -400,8 +400,6 @@ void handleGui(event_t event) { } } -bool inPopupMenu = false; - void guiMain(event_t evt) { #if defined(LUA) @@ -446,22 +444,14 @@ void guiMain(event_t evt) else if (popupMenuItemsCount > 0) { // popup menu is active display it on top of normal menus handleGui(0); // suppress events, they are handled by the popup - if (!inPopupMenu) { - TRACE("Popup Menu started"); - inPopupMenu = true; - } const char * result = runPopupMenu(evt); - if (popupMenuItemsCount == 0) { + if (result) { TRACE("popupMenuHandler(%s)", result); popupMenuHandler(result); } } else { // normal menus - if (inPopupMenu) { - TRACE("Popup Menu ended"); - inPopupMenu = false; - } handleGui(evt); } diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 07fe6d96f..1e22e9245 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -36,53 +36,69 @@ uint8_t Pxx2Pulses::addFlag0(uint8_t module) return flag0; } -void Pxx2Pulses::addFlag1(uint8_t module) +void Pxx2Pulses::addFlag1() { uint8_t flag1 = 0; Pxx2Transport::addByte(flag1); } -void Pxx2Pulses::addChannels(uint8_t module, uint8_t sendFailsafe, uint8_t firstChannel) +void Pxx2Pulses::addPulsesValues(uint16_t low, uint16_t high) +{ + Pxx2Transport::addByte(low); // Low byte of channel + Pxx2Transport::addByte(((low >> 8) & 0x0F) | (high << 4)); // 4 bits each from 2 channels + Pxx2Transport::addByte(high >> 4); // High byte of channel +} + +void Pxx2Pulses::addChannels(uint8_t module) { uint16_t pulseValue = 0; uint16_t pulseValueLow = 0; - for (int8_t i=0; i<8; i++) { - uint8_t channel = firstChannel + i; - if (sendFailsafe) { - if (g_model.moduleData[module].failsafeMode == FAILSAFE_HOLD) { + uint8_t channel = g_model.moduleData[module].channelsStart; + uint8_t count = sentModuleChannels(module); + + for (int8_t i = 0; i < count; i++, channel++) { + int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); + if (i & 1) + addPulsesValues(pulseValueLow, pulseValue); + else + pulseValueLow = pulseValue; + } +} + +void Pxx2Pulses::addFailsafe(uint8_t module) +{ + uint16_t pulseValue = 0; + uint16_t pulseValueLow = 0; + + uint8_t channel = g_model.moduleData[module].channelsStart; + uint8_t count = sentModuleChannels(module); + + for (int8_t i = 0; i < count; i++, channel++) { + if (g_model.moduleData[module].failsafeMode == FAILSAFE_HOLD) { + pulseValue = 2047; + } + else if (g_model.moduleData[module].failsafeMode == FAILSAFE_NOPULSES) { + pulseValue = 0; + } + else { + int16_t failsafeValue = g_model.failsafeChannels[channel]; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { pulseValue = 2047; } - else if (g_model.moduleData[module].failsafeMode == FAILSAFE_NOPULSES) { + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { pulseValue = 0; } else { - int16_t failsafeValue = g_model.failsafeChannels[channel]; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - pulseValue = 2047; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - pulseValue = 0; - } - else { - failsafeValue += 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; - pulseValue = limit(1, (failsafeValue * 512 / 682) + 1024, 2046); - } + failsafeValue += 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; + pulseValue = limit(1, (failsafeValue * 512 / 682) + 1024, 2046); } } - else { - int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER; - pulseValue = limit(1, (value * 512 / 682) + 1024, 2046); - } - - if (i & 1) { - Pxx2Transport::addByte(pulseValueLow); // Low byte of channel - Pxx2Transport::addByte(((pulseValueLow >> 8) & 0x0F) | (pulseValue << 4)); // 4 bits each from 2 channels - Pxx2Transport::addByte(pulseValue >> 4); // High byte of channel - } - else { + if (i & 1) + addPulsesValues(pulseValueLow, pulseValue); + else pulseValueLow = pulseValue; - } } } @@ -90,21 +106,17 @@ void Pxx2Pulses::setupChannelsFrame(uint8_t module) { addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_CHANNELS); - // FLAG0 + // Flag0 uint8_t flag0 = addFlag0(module); - // FLAG1 - addFlag1(module); + // Flag1 + addFlag1(); - // Channels - uint8_t channelsCount = sentModuleChannels(module); - addChannels(module, flag0 & PXX2_CHANNELS_FLAG0_FAILSAFE, g_model.moduleData[module].channelsStart); - if (channelsCount > 8) { - addChannels(module, flag0 & PXX2_CHANNELS_FLAG0_FAILSAFE, g_model.moduleData[module].channelsStart + 8); - if (channelsCount > 16) { - addChannels(module, flag0 & PXX2_CHANNELS_FLAG0_FAILSAFE, g_model.moduleData[module].channelsStart + 16); - } - } + // Failsafe / Channels + if (flag0 & PXX2_CHANNELS_FLAG0_FAILSAFE) + addFailsafe(module); + else + addChannels(module); } void Pxx2Pulses::setupTelemetryFrame(uint8_t module) diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 31e5f3a36..627233d2f 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -158,9 +158,13 @@ class Pxx2Pulses: public PxxPulses { uint8_t addFlag0(uint8_t module); - void addFlag1(uint8_t module); + void addFlag1(); - void addChannels(uint8_t module, uint8_t sendFailsafe, uint8_t firstChannel); + void addPulsesValues(uint16_t low, uint16_t high); + + void addChannels(uint8_t module); + + void addFailsafe(uint8_t module); void addCrc() { diff --git a/radio/src/targets/taranis/i2c2_driver.cpp b/radio/src/targets/taranis/i2c2_driver.cpp new file mode 100644 index 000000000..fe7f3a2fb --- /dev/null +++ b/radio/src/targets/taranis/i2c2_driver.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "board.h" + +void i2c2Init() +{ + I2C_DeInit(I2CX); + + I2C_InitTypeDef I2C_InitStructure; + I2C_InitStructure.I2C_ClockSpeed = I2CX_SPEED; + I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_Init(I2CX, &I2C_InitStructure); + I2C_Cmd(I2CX, ENABLE); + + GPIO_PinAFConfig(I2CX_SCL_GPIO, I2CX_SCL_GPIO_PinSource, I2CX_GPIO_AF); + GPIO_PinAFConfig(I2CX_SDA_GPIO, I2CX_SDA_GPIO_PinSource, I2CX_GPIO_AF); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = I2CX_SCL_GPIO_PIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(I2CX_SCL_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = I2CX_SDA_GPIO_PIN; + GPIO_Init(I2CX_SDA_GPIO, &GPIO_InitStructure); +} + +#define I2C_TIMEOUT_MAX 1000 +bool I2C_WaitEvent(uint32_t event) +{ + uint32_t timeout = I2C_TIMEOUT_MAX; + while (!I2C_CheckEvent(I2CX, event)) { + if ((timeout--) == 0) return false; + } + return true; +} + +bool I2C2_WaitEventCleared(uint32_t event) +{ + uint32_t timeout = I2C_TIMEOUT_MAX; + while (I2C_CheckEvent(I2CX, event)) { + if ((timeout--) == 0) return false; + } + return true; +} + +void setVolume(uint8_t volume) +{ + if (!I2C2_WaitEventCleared(I2C_FLAG_BUSY)) + return; + + I2C_GenerateSTART(I2CX, ENABLE); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT)) + return; + + I2C_Send7bitAddress(I2C, I2C_ADDRESS_VOLUME, I2C_Direction_Transmitter); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + return; + + I2C_SendData(I2CX, 0); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING)) + return; + I2C_SendData(I2CX, volume); + if (!I2C2_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) + return; + + I2C_GenerateSTOP(I2CX, ENABLE); +} + +int32_t getVolume() +{ + return -1; // TODO +} +#endif