From fe027c440c5bfd65ee1bcb5c142fc35b7c58815a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Izzo?= Date: Sun, 10 Sep 2023 13:04:38 +0200 Subject: [PATCH] ttwrplus: enable volume control Replaced KEY_F7 and KEY_F8 with KEY_VOLUP and KEY_VOLDOWN. Remapped the T-TWR Plus volume up and down keys to those, fixing a bug in the pmu key detection where the wrong active edge was selected. Adapt soft volume code for the UV3x0 to control code in the T-TWR Plus by acting on the AT1846s Rx gain. For target T-TWR Plus bound long press of KEY_VOLDOWN to macro menu open. Unbound KNOB_LEFT and KNOB_RIGHT to squelch control and bound instead KEY_VOLUP and KEY_VOLDOWN. TG-553 --- openrtx/include/interfaces/keyboard.h | 58 +++++++++---------- openrtx/src/rtx/OpMode_FM.cpp | 13 ++++- openrtx/src/ui/default/ui.c | 38 +++++++----- platform/drivers/keyboard/keyboard_ttwrplus.c | 20 ++++++- platform/targets/linux/emulator/emulator.c | 2 +- platform/targets/ttwrplus/platform.c | 5 +- platform/targets/ttwrplus/pmu.cpp | 4 +- 7 files changed, 87 insertions(+), 53 deletions(-) diff --git a/openrtx/include/interfaces/keyboard.h b/openrtx/include/interfaces/keyboard.h index 8ab7f456..47adb7b5 100644 --- a/openrtx/include/interfaces/keyboard.h +++ b/openrtx/include/interfaces/keyboard.h @@ -29,35 +29,35 @@ */ enum key { - KEY_0 = (1 << 0), /* Keypad digit "0" */ - KEY_1 = (1 << 1), /* Keypad digit "1" */ - KEY_2 = (1 << 2), /* Keypad digit "2" */ - KEY_3 = (1 << 3), /* Keypad digit "3" */ - KEY_4 = (1 << 4), /* Keypad digit "4" */ - KEY_5 = (1 << 5), /* Keypad digit "5" */ - KEY_6 = (1 << 6), /* Keypad digit "6" */ - KEY_7 = (1 << 7), /* Keypad digit "7" */ - KEY_8 = (1 << 8), /* Keypad digit "8" */ - KEY_9 = (1 << 9), /* Keypad digit "9" */ - KEY_STAR = (1 << 10), /* Keypad digit "*" */ - KEY_HASH = (1 << 11), /* Keypad digit "#" */ - KEY_ENTER = (1 << 12), /* Keypad green button/enter */ - KEY_ESC = (1 << 13), /* Keypad red button/esc */ - KEY_UP = (1 << 14), /* Keypad upward arrow */ - KEY_DOWN = (1 << 15), /* Keypad downward arrow */ - KEY_LEFT = (1 << 16), /* Keypad leftward arrow */ - KEY_RIGHT = (1 << 17), /* Keypad rightward arrow */ - KEY_MONI = (1 << 18), /* Monitor button */ - KEY_F1 = (1 << 19), /* Function button */ - KEY_F2 = (1 << 20), /* Function button (device specific) */ - KEY_F3 = (1 << 21), /* Function button (device specific) */ - KEY_F4 = (1 << 22), /* Function button (device specific) */ - KEY_F5 = (1 << 23), /* Function button (device specific) */ - KEY_F6 = (1 << 24), /* Function button (device specific) */ - KEY_F7 = (1 << 25), /* Function button (device specific) */ - KEY_F8 = (1 << 26), /* Function button (device specific) */ - KNOB_LEFT = (1 << 27), /* Knob rotated counter clockwise */ - KNOB_RIGHT = (1 << 28), /* Knob rotated clockwise */ + KEY_0 = (1 << 0), /* Keypad digit "0" */ + KEY_1 = (1 << 1), /* Keypad digit "1" */ + KEY_2 = (1 << 2), /* Keypad digit "2" */ + KEY_3 = (1 << 3), /* Keypad digit "3" */ + KEY_4 = (1 << 4), /* Keypad digit "4" */ + KEY_5 = (1 << 5), /* Keypad digit "5" */ + KEY_6 = (1 << 6), /* Keypad digit "6" */ + KEY_7 = (1 << 7), /* Keypad digit "7" */ + KEY_8 = (1 << 8), /* Keypad digit "8" */ + KEY_9 = (1 << 9), /* Keypad digit "9" */ + KEY_STAR = (1 << 10), /* Keypad digit "*" */ + KEY_HASH = (1 << 11), /* Keypad digit "#" */ + KEY_ENTER = (1 << 12), /* Keypad green button/enter */ + KEY_ESC = (1 << 13), /* Keypad red button/esc */ + KEY_UP = (1 << 14), /* Keypad upward arrow */ + KEY_DOWN = (1 << 15), /* Keypad downward arrow */ + KEY_LEFT = (1 << 16), /* Keypad leftward arrow */ + KEY_RIGHT = (1 << 17), /* Keypad rightward arrow */ + KEY_MONI = (1 << 18), /* Monitor button */ + KEY_F1 = (1 << 19), /* Function button */ + KEY_F2 = (1 << 20), /* Function button (device specific) */ + KEY_F3 = (1 << 21), /* Function button (device specific) */ + KEY_F4 = (1 << 22), /* Function button (device specific) */ + KEY_F5 = (1 << 23), /* Function button (device specific) */ + KEY_F6 = (1 << 24), /* Function button (device specific) */ + KEY_VOLUP = (1 << 25), /* Volume increase button */ + KEY_VOLDOWN = (1 << 26), /* Volume decrease button */ + KNOB_LEFT = (1 << 27), /* Knob rotated counter clockwise */ + KNOB_RIGHT = (1 << 28), /* Knob rotated clockwise */ }; /** diff --git a/openrtx/src/rtx/OpMode_FM.cpp b/openrtx/src/rtx/OpMode_FM.cpp index 7612093f..823eeea4 100644 --- a/openrtx/src/rtx/OpMode_FM.cpp +++ b/openrtx/src/rtx/OpMode_FM.cpp @@ -24,8 +24,10 @@ #include #include -#ifdef PLATFORM_MDUV3x0 +#if defined(PLATFORM_MDUV3x0) #include "../../../drivers/baseband/HR_C6000.h" +#elif defined(PLATFORM_TTWRPLUS) +#include "AT1846S.h" #endif /** @@ -36,7 +38,7 @@ * provide the helper function below to keep the real volume level consistent * with the knob position. */ -#ifdef PLATFORM_MDUV3x0 +#if defined(PLATFORM_MDUV3x0) || defined(PLATFORM_TTWRPLUS) void _setVolume() { static uint8_t oldVolume = 0xFF; @@ -45,9 +47,14 @@ void _setVolume() if(volume == oldVolume) return; +#if defined(PLATFORM_MDUV3x0) // Apply new volume level, map 0 - 255 range into -31 to 31 int8_t gain = ((int8_t) (volume / 4)) - 31; HR_C6000::instance().setDacGain(gain); +#elif defined(PLATFORM_TTWRPLUS) + // AT1846S volume control is 4 bit + AT1846S::instance().setRxAudioGain(volume / 16, volume / 16); +#endif oldVolume = volume; } @@ -86,7 +93,7 @@ void OpMode_FM::update(rtxStatus_t *const status, const bool newCfg) { (void) newCfg; - #ifdef PLATFORM_MDUV3x0 + #if defined(PLATFORM_MDUV3x0) || defined(PLATFORM_TTWRPLUS) // Set output volume by changing the HR_C6000 DAC gain _setVolume(); #endif diff --git a/openrtx/src/ui/default/ui.c b/openrtx/src/ui/default/ui.c index 3428c414..3f415620 100644 --- a/openrtx/src/ui/default/ui.c +++ b/openrtx/src/ui/default/ui.c @@ -991,19 +991,15 @@ static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) #endif } -#ifdef HAS_ABSOLUTE_KNOB // If the radio has an absolute position knob - if(msg.keys & KNOB_LEFT || msg.keys & KNOB_RIGHT) { - state.settings.sqlLevel = platform_getChSelector() - 1; - *sync_rtx = true; - vp_announceSquelch(state.settings.sqlLevel, queueFlags); - } - - if(msg.keys & KEY_LEFT || msg.keys & KEY_DOWN) -#else // Use left and right buttons or relative position knob - // NOTE: Use up and down for UV380 which has not yet a functional knob +#if defined(PLATFORM_TTWRPLUS) + if(msg.keys & KEY_VOLDOWN) +#else if(msg.keys & KEY_LEFT || msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT) -#endif +#endif // PLATFORM_TTWRPLUS { +#ifdef HAS_ABSOLUTE_KNOB // If the radio has an absolute position knob + state.settings.sqlLevel = platform_getChSelector() - 1; +#endif // HAS_ABSOLUTE_KNOB if(state.settings.sqlLevel > 0) { state.settings.sqlLevel -= 1; @@ -1012,12 +1008,15 @@ static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) } } -#ifdef HAS_ABSOLUTE_KNOB - else if(msg.keys & KEY_RIGHT || msg.keys & KEY_UP) +#if defined(PLATFORM_TTWRPLUS) + else if(msg.keys & KEY_VOLUP) #else else if(msg.keys & KEY_RIGHT || msg.keys & KEY_UP || msg.keys & KNOB_RIGHT) -#endif +#endif // PLATFORM_TTWRPLUS { +#ifdef HAS_ABSOLUTE_KNOB + state.settings.sqlLevel = platform_getChSelector() - 1; +#endif if(state.settings.sqlLevel < 15) { state.settings.sqlLevel += 1; @@ -1288,9 +1287,8 @@ void ui_updateFSM(bool *sync_rtx) // unless is the MONI key for the MACRO functions if (_ui_exitStandby(now) && !(msg.keys & KEY_MONI)) return; - // If MONI is pressed, activate MACRO functions - bool moniPressed = (msg.keys & KEY_MONI) ? true : false; + bool moniPressed = msg.keys & KEY_MONI; if(moniPressed || macro_latched) { macro_menu = true; @@ -1312,6 +1310,14 @@ void ui_updateFSM(bool *sync_rtx) { macro_menu = false; } +#if defined(PLATFORM_TTWRPLUS) + // T-TWR Plus has no KEY_MONI, using KEY_VOLDOWN long press instead + if ((msg.keys & KEY_VOLDOWN) && msg.long_press) + { + macro_menu = true; + macro_latched = true; + } +#endif // PLA%FORM_TTWRPLUS int priorUIScreen = state.ui_screen; switch(state.ui_screen) diff --git a/platform/drivers/keyboard/keyboard_ttwrplus.c b/platform/drivers/keyboard/keyboard_ttwrplus.c index df5bccb5..7636380e 100644 --- a/platform/drivers/keyboard/keyboard_ttwrplus.c +++ b/platform/drivers/keyboard/keyboard_ttwrplus.c @@ -29,6 +29,8 @@ static const struct device *const buttons_dev = DEVICE_DT_GET(DT_NODELABEL(butto static int8_t old_pos = 0; static keyboard_t keys = 0; +// Defined in ttwrplus/platform.c to implement volume control +extern uint8_t volume_level; static void gpio_keys_cb_handler(struct input_event *evt) { @@ -38,7 +40,9 @@ static void gpio_keys_cb_handler(struct input_event *evt) switch(evt->code) { case INPUT_KEY_VOLUMEDOWN: - keyCode = KEY_MONI; + keyCode = KEY_VOLDOWN; + if(evt->value != 0 && volume_level > 9) + volume_level -= 10; break; case INPUT_BTN_START: @@ -105,5 +109,19 @@ keyboard_t kbd_getKeys() old_pos = new_pos; } + /* + * The power key is only connected to the PMU and its state is detected through + * the PMU interrupts. + */ + if (pmu_pwrOnBtnStatus()) + { + // Update the volume only once when key is pressed + if (!(keys & KEY_VOLUP) && volume_level < 246) + volume_level += 10; + keys |= KEY_VOLUP; + } + else + keys &= ~KEY_VOLUP; + return keys; } diff --git a/platform/targets/linux/emulator/emulator.c b/platform/targets/linux/emulator/emulator.c index d4d16c61..17234a76 100644 --- a/platform/targets/linux/emulator/emulator.c +++ b/platform/targets/linux/emulator/emulator.c @@ -141,7 +141,7 @@ static keyboard_t keyname2keyboard(char *name) "KEY_0", "KEY_1", "KEY_2", "KEY_3", "KEY_4", "KEY_5", "KEY_6", "KEY_7", "KEY_8", "KEY_9", "KEY_STAR", "KEY_HASH", "KEY_ENTER", "KEY_ESC", "KEY_UP","KEY_DOWN", "KEY_LEFT", "KEY_RIGHT", "KEY_MONI", "KEY_F1", - "KEY_F2", "KEY_F3", "KEY_F4", "KEY_F5", "KEY_F6", "KEY_F7", "KEY_F8", + "KEY_F2", "KEY_F3", "KEY_F4", "KEY_F5", "KEY_F6", "KEY_VOLUP", "KEY_VOLDOWN", "KNOB_LEFT", "KNOB_RIGHT", }; diff --git a/platform/targets/ttwrplus/platform.c b/platform/targets/ttwrplus/platform.c index fc576f07..9dec316c 100644 --- a/platform/targets/ttwrplus/platform.c +++ b/platform/targets/ttwrplus/platform.c @@ -34,6 +34,9 @@ static const struct gpio_dt_spec button_ptt = GPIO_DT_SPEC_GET_OR(BUTTON_PTT_NOD static const struct device *const qdec_dev = DEVICE_DT_GET(DT_ALIAS(qdec0)); static const struct device *const led_dev = DEVICE_DT_GET(DT_ALIAS(led0)); +// This is cross-references in keyboard_ttwrplus.c to implement volume control +uint8_t volume_level = 125; + static hwInfo_t hwInfo = { .name = "ttwrplus", @@ -118,7 +121,7 @@ uint8_t platform_getMicLevel() uint8_t platform_getVolumeLevel() { - return 0; + return volume_level; } int8_t platform_getChSelector() diff --git a/platform/targets/ttwrplus/pmu.cpp b/platform/targets/ttwrplus/pmu.cpp index 812595fa..ec3e7c62 100644 --- a/platform/targets/ttwrplus/pmu.cpp +++ b/platform/targets/ttwrplus/pmu.cpp @@ -345,11 +345,11 @@ void pmu_handleIRQ() // Power on key rising edge if((irqStatus & XPOWERS_AXP2101_PKEY_POSITIVE_IRQ) != 0) - pwrOnPressed = true; + pwrOnPressed = false; // Power on key falling edge if((irqStatus & XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ) != 0) - pwrOnPressed = false; + pwrOnPressed = true; // Power key long press if ((irqStatus & XPOWERS_AXP2101_PKEY_LONG_IRQ) != 0)