Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b7fa3ee
Add lock on mode functionality in Helios
livingkurt Aug 14, 2025
778f198
Refine lock on mode handling in Helios
livingkurt Aug 14, 2025
63267fc
Refine LED indication for locked state in Helios
livingkurt Aug 14, 2025
4457116
Enhance lock on mode handling in Helios
livingkurt Aug 14, 2025
8012d34
Refactor test files to standardize color codes and enhance clarity
livingkurt Aug 14, 2025
e62685e
Refine condition for locked state handling in Helios
livingkurt Aug 15, 2025
f007802
Update global flag handling in Helios to include FLAG_LOCK_ON
livingkurt Aug 15, 2025
5378cdd
Refactor test file for color code consistency and clarity
livingkurt Aug 15, 2025
5b651b7
Merge branch 'aeos' into kurt/aeos/lock-on
livingkurt Aug 15, 2025
39ac701
Fix indentation in Helios state handling logic for improved readability
livingkurt Aug 15, 2025
4a1e2a7
Add comment to clarify Lock On mode behavior in Helios
livingkurt Aug 15, 2025
7a98ea9
Refactor autoplay condition in Helios state handling
livingkurt Aug 15, 2025
ce04e06
Merge branch 'aeos' into kurt/aeos/lock-on
livingkurt Aug 15, 2025
0894f44
Refactor global flag handling in Helios
livingkurt Aug 18, 2025
3b77463
Fix formatting in Helios state handling condition
livingkurt Aug 18, 2025
3cb55a7
Update flag checking method in Helios global flags
livingkurt Aug 18, 2025
b4bd2f7
Update flag type casting in Helios global flags and state handling
livingkurt Aug 18, 2025
dca8900
Refactor autoplay toggle handling in Helios state management
livingkurt Aug 18, 2025
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
66 changes: 50 additions & 16 deletions Helios/Helios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,9 @@ void Helios::load_global_flags()
factory_reset();
return;
}
if (has_flag(FLAG_CONJURE)) {
// if conjure is enabled then load the current mode index from storage
if (has_any_flags((Flags)(FLAG_CONJURE | FLAG_LOCK_ON))) {
// if conjure or lock on is enabled then load the current mode index from storage
// For Lock On this will prevent the cur mode from changing back to the first mode when reset
cur_mode = Storage::read_current_mode();
}
}
Expand Down Expand Up @@ -272,6 +273,9 @@ void Helios::handle_state()
case STATE_TOGGLE_LOCK:
handle_state_toggle_flag(FLAG_LOCKED);
break;
case STATE_TOGGLE_LOCK_ON:
handle_state_toggle_flag(FLAG_LOCK_ON);
break;
case STATE_SET_DEFAULTS:
handle_state_set_defaults();
break;
Expand All @@ -292,8 +296,11 @@ void Helios::handle_state_modes()
bool hasReleased = (Button::releaseCount() > 0);

if (Button::releaseCount() > 1 && Button::onShortClick()) {
if (has_flag(FLAG_CONJURE)) {
if (has_flags(FLAG_CONJURE)) {
enter_sleep();
} else if (has_flags(FLAG_LOCK_ON)) {
// when lock on is enabled, short clicks do nothing
return;
} else {
load_next_mode();
}
Expand All @@ -303,7 +310,7 @@ void Helios::handle_state_modes()
// This handles iterating the mode forward when the autoplay feature is
// enabled. The modes automatically cycle forward every AUTOPLAY_DURATION ticks
// but only if the button isn't pressed to avoid iterating while opening menus
if (has_flag(FLAG_AUTOPLAY) && !Button::isPressed()) {
if (has_flags(FLAG_AUTOPLAY) && !Button::isPressed()) {
uint32_t current_time = Time::getCurtime();
if (current_time - last_mode_switch_time >= AUTOPLAY_DURATION) {
// If a pattern has a single cycle that is longer than the autoplay duration,
Expand All @@ -315,13 +322,24 @@ void Helios::handle_state_modes()
}

// check for lock and go back to sleep
if (has_flag(FLAG_LOCKED) && hasReleased && !Button::onRelease()) {
if (has_flags(FLAG_LOCKED) && hasReleased && !Button::onRelease()) {
enter_sleep();
// ALWAYS RETURN AFTER SLEEP! WE WILL WAKE HERE!
return;
}

if (!has_flag(FLAG_LOCKED) && hasReleased) {
// check for lock on - device stays on but locked
if (has_flags(FLAG_LOCK_ON) && hasReleased && !Button::onRelease()) {
// For lock on mode, always play the pattern unless we're in a long hold (menu access)
uint32_t holdDur = Button::holdDuration();
bool heldPast = (holdDur > SHORT_CLICK_THRESHOLD);
if (!Button::isPressed() || !heldPast) {
pat.play();
return;
}
}

if (!has_any_flags((Flags)(FLAG_LOCKED | FLAG_LOCK_ON)) && hasReleased) {
// just play the current mode
pat.play();
}
Expand All @@ -333,8 +351,8 @@ void Helios::handle_state_modes()
// whether the user has held the button longer than a short click
bool heldPast = (holdDur > SHORT_CLICK_THRESHOLD);

// flash red briefly when locked and short clicked
if (has_flag(FLAG_LOCKED) && holdDur < SHORT_CLICK_THRESHOLD) {
// flash red briefly when locked and short clicked (only for glow lock, not lock on)
if (has_flags(FLAG_LOCKED) && holdDur < SHORT_CLICK_THRESHOLD) {
Led::set(RGB_RED_BRI_LOW);
}
// if the button is held for at least 1 second
Expand All @@ -347,9 +365,10 @@ void Helios::handle_state_modes()
case 1: Led::set(RGB_TURQUOISE_BRI_LOW); break; // Color Selection
case 2: Led::set(RGB_MAGENTA_BRI_LOW); break; // Pattern Selection
case 3: Led::set(RGB_YELLOW_BRI_LOW); break; // Conjure Mode
case 4: Led::set(RGB_WHITE_BRI_LOW); break; // Lock On Mode
}
} else {
if (has_flag(FLAG_LOCKED)) {
if (has_flags(FLAG_LOCKED)) {
switch (magnitude) {
default:
case 0: Led::clear(); break;
Expand All @@ -361,7 +380,7 @@ void Helios::handle_state_modes()
case 0: Led::clear(); break; // nothing
case 1: Led::set(RGB_RED_BRI_LOW); break; // Enter Glow Lock
case 2: Led::set(RGB_BLUE_BRI_LOW); break; // Master Reset
case 3: Led::set(has_flag(FLAG_AUTOPLAY) ? RGB_ORANGE_BRI_LOW : RGB_PINK_BRI_LOW); break; // Autoplay Toggle
case 3: Led::set(has_flags(FLAG_AUTOPLAY) ? RGB_ORANGE_BRI_LOW : RGB_PINK_BRI_LOW); break; // Autoplay Toggle
}
}
}
Expand All @@ -382,7 +401,7 @@ void Helios::handle_state_modes()
void Helios::handle_off_menu(uint8_t mag, bool past)
{
// if still locked then handle the unlocking menu which is just if mag == 5
if (has_flag(FLAG_LOCKED)) {
if (has_flags(FLAG_LOCKED)) {
switch (mag) {
case TIME_TILL_GLOW_LOCK_UNLOCK: // red lock
cur_state = STATE_TOGGLE_LOCK;
Expand All @@ -396,6 +415,20 @@ void Helios::handle_off_menu(uint8_t mag, bool past)
return;
}

// if lock on is enabled, handle the unlocking menu
if (has_flags(FLAG_LOCK_ON)) {
switch (mag) {
case TIME_TILL_GLOW_LOCK_UNLOCK: // red unlock
cur_state = STATE_TOGGLE_LOCK_ON;
break;
default:
// stay on but locked - do not sleep
return;
}
// in this case we return either way, since we're locked on
return;
}

// otherwise if not locked handle the off menu
switch (mag) {
case 1: // red lock
Expand All @@ -406,10 +439,7 @@ void Helios::handle_off_menu(uint8_t mag, bool past)
cur_state = STATE_SET_DEFAULTS;
return; //RETURN HERE
case 3: // autoplay toggle
toggle_flag(FLAG_AUTOPLAY);
save_global_flags();
last_mode_switch_time = Time::getCurtime(); // Reset the timer when enabling autoplay
cur_state = STATE_MODES;
handle_state_toggle_flag(FLAG_AUTOPLAY);
return; //RETURN HERE
default:
// just go back to sleep in hold-past off menu
Expand Down Expand Up @@ -453,6 +483,10 @@ void Helios::handle_on_menu(uint8_t mag, bool past)
cur_state = STATE_TOGGLE_CONJURE;
Led::clear();
break;
case 4: // lock on mode
cur_state = STATE_TOGGLE_LOCK_ON;
Led::clear();
break;
default: // hold past
break;
}
Expand Down Expand Up @@ -690,7 +724,7 @@ void Helios::handle_state_pat_select()
void Helios::handle_state_toggle_flag(Flags flag)
{
// toggle the conjure flag
toggle_flag(flag);
toggle_flags(flag);
// write out the new global flags and the current mode
save_global_flags();
// switch back to modes
Expand Down
12 changes: 8 additions & 4 deletions Helios/Helios.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class Helios
FLAG_CONJURE = (1 << 1),
// Autoplay is enabled, modes will automatically cycle
FLAG_AUTOPLAY = (1 << 2),
// Lock on mode is enabled, device stays on and locked
FLAG_LOCK_ON = (1 << 3),
// Add new flags here, max 8 flags

// ==============================================
Expand All @@ -49,10 +51,11 @@ class Helios
};

// get/set global flags
static void set_flag(Flags flag) { global_flags = (Flags)(global_flags | flag); }
static bool has_flag(Flags flag) { return (global_flags & flag) == flag; }
static void clear_flag(Flags flag) { global_flags = (Flags)(global_flags & ~flag); }
static void toggle_flag(Flags flag) { global_flags = (Flags)(global_flags ^ flag); }
static void set_flags(Flags flag) { global_flags = (Flags)(global_flags | flag); }
static bool has_flags(Flags flag) { return (global_flags & flag) == flag; }
static bool has_any_flags(Flags flag) { return (global_flags & flag) != FLAG_NONE; }
static void clear_flags(Flags flag) { global_flags = (Flags)(global_flags & ~flag); }
static void toggle_flags(Flags flag) { global_flags = (Flags)(global_flags ^ flag); }

private:
// initialize the various components of helios
Expand Down Expand Up @@ -90,6 +93,7 @@ class Helios
STATE_PATTERN_SELECT,
STATE_TOGGLE_CONJURE,
STATE_TOGGLE_LOCK,
STATE_TOGGLE_LOCK_ON,
STATE_SET_DEFAULTS,
#ifdef HELIOS_CLI
STATE_SLEEP,
Expand Down
Loading