Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions source/Core/BSP/BSP.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample);
// !! Returns 1 if held down, 0 if released
uint8_t getButtonA();
uint8_t getButtonB();
// Optional dedicated OK button for 3-button devices (e.g. Fnirsi HS-02).
// Weakly defined to return 0 in Buttons.cpp; devices with a third button override it.
uint8_t getButtonOK();

// This is a work around that will be called if I2C starts to bug out
// This should toggle the SCL line until SDA goes high to end the current transaction
Expand Down
4 changes: 4 additions & 0 deletions source/Core/BSP/Fnirsi/BSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@ void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) {
pendingPWM = scaledPWM;
}

// The HS-02 has three physical buttons; IronOS's two logical buttons map to UP/DOWN,
// and the dedicated OK button is exposed via getButtonOK() so each UI screen can give
// it a context-appropriate action (see the BUTTON_OK_SHORT handlers in the UI logic).
uint8_t getButtonA() { return GPIO_ReadInputDataBit(BUTTON_Port, BUTTON_DOWN_Pin) == Bit_RESET ? 1 : 0; }
uint8_t getButtonB() { return GPIO_ReadInputDataBit(BUTTON_Port, BUTTON_UP_Pin) == Bit_RESET ? 1 : 0; }
uint8_t getButtonOK() { return GPIO_ReadInputDataBit(BUTTON_Port, BUTTON_OK_Pin) == Bit_RESET ? 1 : 0; }

void BSPInit(void) { switchToFastPWM(); }

Expand Down
16 changes: 16 additions & 0 deletions source/Core/Drivers/Buttons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <Buttons.hpp>
TickType_t lastButtonTime = 0;

// Devices without a dedicated OK button fall back to this (no third button).
__attribute__((weak)) uint8_t getButtonOK() { return 0; }

ButtonState getButtonState() {
/*
* Read in the buttons and then determine if a state change needs to occur
Expand All @@ -25,11 +28,13 @@ ButtonState getButtonState() {
*/
static uint8_t previousState = 0;
static bool longPressed = false;
static bool okLongFired = false; // OK long-press is one-shot (back = single level)
static TickType_t previousStateChange = 0;
const TickType_t timeout = TICKS_100MS * 4;
uint8_t currentState;
currentState = (getButtonA()) << 0;
currentState |= (getButtonB()) << 1;
currentState |= (getButtonOK()) << 2; // Dedicated OK button (0 on 2-button devices)

if (currentState) {
lastButtonTime = xTaskGetTickCount();
Expand All @@ -46,6 +51,14 @@ ButtonState getButtonState() {
return BUTTON_F_LONG;
} else if (currentState == 0x02) {
return BUTTON_B_LONG;
} else if (currentState == 0x04) {
// Dedicated OK button held: emit BUTTON_OK_LONG only once per hold so a
// "back one level" action doesn't cascade up multiple levels while held.
if (okLongFired) {
return BUTTON_NONE;
}
okLongFired = true;
return BUTTON_OK_LONG;
} else {
return BUTTON_BOTH_LONG; // Both being held case
}
Expand Down Expand Up @@ -73,12 +86,15 @@ ButtonState getButtonState() {
retVal = BUTTON_F_SHORT;
} else if (previousState == 0x02) {
retVal = BUTTON_B_SHORT;
} else if (previousState == 0x04) {
retVal = BUTTON_OK_SHORT; // Dedicated OK button pressed
} else {
retVal = BUTTON_BOTH; // Both being held case
}
}
previousState = 0;
longPressed = false;
okLongFired = false; // reset one-shot latch on release
}
previousStateChange = xTaskGetTickCount();
return retVal;
Expand Down
2 changes: 2 additions & 0 deletions source/Core/Drivers/Buttons.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ enum ButtonState {
BUTTON_B_LONG = 8, /* User is holding the back button*/
BUTTON_BOTH = 16, /* User has pressed both buttons*/
BUTTON_BOTH_LONG = 32, /* User is holding both buttons*/
BUTTON_OK_SHORT = 64, /* User has pressed a dedicated OK button (3-button devices only)*/
BUTTON_OK_LONG = 128,/* User is holding a dedicated OK button (3-button devices only)*/

/*
* Note:
Expand Down
1 change: 1 addition & 0 deletions source/Core/Threads/UI/logic/HomeScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ OperatingMode handleHomeButtons(const ButtonState buttons, guiContext *cxt) {
return OperatingMode::TemperatureAdjust;
#endif
break;
case BUTTON_OK_SHORT: // Dedicated OK button enters soldering (same as front-press)
case BUTTON_F_SHORT:
if (!isTipDisconnected()) {
bool detailedView = getSettingValue(SettingsOptions::DetailedIDLE) && getSettingValue(SettingsOptions::DetailedSoldering);
Expand Down
6 changes: 6 additions & 0 deletions source/Core/Threads/UI/logic/SettingsMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt) {
case BUTTON_B_SHORT:
buttonPress = swapButtonSettings ? BUTTON_F_SHORT : BUTTON_B_SHORT;
break;
case BUTTON_OK_SHORT:
buttonPress = BUTTON_F_SHORT; // Dedicated OK button selects/enters, ignoring button swap
break;
case BUTTON_OK_LONG:
buttonPress = BUTTON_BOTH; // OK long-press goes back one level (submenu -> root -> home)
break;
default:
buttonPress = buttons;
break;
Expand Down
3 changes: 3 additions & 0 deletions source/Core/Threads/UI/logic/Soldering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ OperatingMode handleSolderingButtons(const ButtonState buttons, guiContext *cxt)
cxt->scratch_state.state2 = 0;
cxt->scratch_state.state1 = 0;
break;
case BUTTON_OK_LONG: // Dedicated OK long-press returns to the home screen
/*Fall through*/
case BUTTON_BOTH:
/*Fall through*/
case BUTTON_B_LONG:
Expand All @@ -67,6 +69,7 @@ OperatingMode handleSolderingButtons(const ButtonState buttons, guiContext *cxt)
cxt->scratch_state.state2 = 1;
}
break;
case BUTTON_OK_SHORT: // Dedicated OK button opens temperature adjust
case BUTTON_F_SHORT:
case BUTTON_B_SHORT:
cxt->transitionMode = TransitionAnimation::Left;
Expand Down
2 changes: 2 additions & 0 deletions source/Core/Threads/UI/logic/TemperatureAdjust.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ OperatingMode gui_solderingTempAdjust(const ButtonState buttonIn, guiContext *cx
// stay
(*autoRepeatAcceleration) = 0;
break;
case BUTTON_OK_SHORT: // Dedicated OK button confirms & exits (same as both-press)
case BUTTON_OK_LONG: // OK long-press also exits (back to previous screen)
case BUTTON_BOTH:
// exit
saveSettings();
Expand Down