Skip to content

feat: add tip profiles system with flash storage and menu UI#157

Merged
AxxAxx merged 4 commits into
AxxAxx:mainfrom
pashamray:feat/flash-profiles-write
Apr 20, 2026
Merged

feat: add tip profiles system with flash storage and menu UI#157
AxxAxx merged 4 commits into
AxxAxx:mainfrom
pashamray:feat/flash-profiles-write

Conversation

@pashamray

@pashamray pashamray commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

ATTENTION, NOT YET TESTED!

Summary

  • Add a tip profiles system allowing users to create, edit, and switch between per-handle tip configurations (calibration data, PID parameters, power limits) stored in dedicated flash sections
  • Introduce a pluggable StorageDriver abstraction with flash backend and build-time driver selection (STORAGE_PROFILES, STORAGE_SETTINGS CMake options), replacing the old monolithic flash.c/h
  • Add profiles menu UI: profile list, profile editor, character-by-character name editor, and a quick-select popup on tip change with 5-second auto-timeout
  • Refactor settings menu to use MI_ enum with step-100 ranges, delegating calibration and power limit entries to per-profile settings
  • Add PROFILES.md documentation with screenshots

Key implementation details

  • Dedicated PROFILES and SETTINGS flash sections in linker script (2 KB each) with CRC-protected reads/writes and interrupt-guarded CRC peripheral access
  • Heater is disabled (requested_power = 0) while popup blocks the main loop to prevent uncontrolled heating
  • Flash wear reduction: skip redundant writes when profile is already active or unchanged on menu exit (memcmp check)
  • Off-by-one fix in flash page erase calculation, FLASH_BANK_1 set explicitly to prevent undefined erase behavior on STM32G4

Test plan

  • Build firmware
  • Verify profiles list displays correctly, create/edit/delete profiles
  • Verify name editor allows character-by-character editing
  • Change soldering tip and confirm quick-select popup appears with 5-second timeout
  • Confirm heater is off while popup is displayed
  • Verify settings saved to flash persist across power cycles
  • Confirm SW_2 cancels the popup without changing active profile
  • Check that deprecated calibration/power limit entries in settings menu are no longer directly editable

AxxSolder.zip

20260414_141718 20260414_141740 20260414_141804 20260414_141818 20260414_141837

- Add pluggable StorageDriver abstraction (flash backend, build-time selection)
- Add dedicated PROFILES/SETTINGS flash sections in linker script (2 KB each)
- Add TipProfile CRUD with per-handle active profile tracking
- Add profiles menu UI: list, editor, name editor, quick-select popup
- Refactor settings menu: MI_ enum with step-100 ranges, remove flash.c/h
- Move calibration and power limits into per-profile settings
- Add PROFILES.md documentation with screenshots

Fixes applied:
- Fix off-by-one in flash page erase calculation (could corrupt adjacent page)
- Protect CRC peripheral access with __disable_irq in flash_read/flash_verify
- Use slot_to_handle() reverse mapping in tip_profiles_delete (decouple from enum order)
- Add bounds check in tip_profiles_set_active
- Add SW_2 cancel to profiles_popup (was an infinite loop with no exit)
- Guard enc_sel against max_items == 0
- Use designated initializers for handle_str[] (safe against enum reorder)
- Show kp/ki/kd with one decimal place in profile editor
- Replace compound literal with shared identity_cal[]
- Fix linker PROFILES/SETTINGS sections: (rx) → (rw)
- storage_flash: add erase.Banks = FLASH_BANK_1 to prevent undefined
  erase behavior on STM32G4
- storage_flash: protect CRC calculation in flash_write with
  __disable_irq/__enable_irq to match flash_read/flash_verify
- menu_profiles: disable heater (requested_power = 0) while popup
  blocks the main loop to prevent uncontrolled heating
- menu_profiles: add 5-second timeout to profiles_popup to prevent
  indefinite main loop blockage; resets on user interaction
- menu_profiles: skip redundant flash write in single-match popup
  when the profile is already active
- menu_profiles: only save profile on Back if actually modified
  (memcmp check) to reduce flash wear
- menu_settings: mark deprecated calibration and power limit entries
  in mi_table and enum with explanatory comments
- menu_settings: document count==0 sentinel for profiles group
  delegation
- Move MI_PROFILE_ON_TIP_CHG into the Mode group so the toggle is
  reachable in Settings (the Profiles group delegates to profiles_menu
  and never rendered the item).
- Suppress the profile popup during boot by gating it on startup_done,
  so the filter warm-up loop can't trigger a popup with an uninitialized
  attached_handle.
- Show the popup even when only one profile matches the handle, and
  pre-select the currently active profile for that handle.
- Repaint the main screen after the popup closes to clear overlay
  residue.
@AxxAxx

AxxAxx commented Apr 19, 2026

Copy link
Copy Markdown
Owner

It works pretty good.
Three things,

  1. What is -Set Active- meant to do? If I have a auto-detected T210 handle and I try to set T245 nothing happens. Which is good I guess. or what is the idea?

  2. It seems that you can delete the profile of T210 while still having T210 connected. what happens if the default profile is gone?

  3. I played around and deleted two of the default profiles. And now even with a "system->Load Default" They do not come back.

@pashamray

pashamray commented Apr 20, 2026

Copy link
Copy Markdown
Contributor Author
1. What is -Set Active- meant to do? If I have a auto-detected T210 handle and I try to set T245 nothing happens. Which is good I guess. or what is the idea?

Yes, the idea is that you can select a profile only for a compatible handle.

2. It seems that you can delete the profile of T210 while still having T210 connected. what happens if the default profile is gone?

Fixed this, now default profiles cannot be deleted.
If a non-default active profile is deleted, a suitable one from the standard ones will be selected.

3. I played around and deleted two of the default profiles. And now even with a "system->Load Default" They do not come back.

Fixed.

@AxxAxx AxxAxx merged commit 57a5994 into AxxAxx:main Apr 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants