SGM_CTRL was turned on at the very start of LCD_Init(), before the
ST7789V register sequence and first frame ran, showing garbage/blank
content briefly on every boot. GPIO_Init() now forces backlight off at
power-on, LCD_Init() no longer touches it, and main() only turns it on
right before entering the main loop (after HomeApp's first frame is
drawn). Wakeup_Restore()'s existing on-then-reinit sequence is
untouched since it sets the level itself before calling LCD_Init().
Splits the ad-hoc menu_level state machine into standalone Apps with a
uniform parent/child exit convention (long-press CONFIRM -> parent):
clock_app renamed to home_app (boot-default), new set_clock_app
extracted from home_app's time-edit mode, new ipc_bind_app extracted
from menu_app's old level-2 screen, and the sensor-type selection step
merged into pair_app as its new initial state. menu_app now only holds
the 4-item top-level list (language toggle inline). Also makes both
menu_app and pair_app's up/down navigation cyclic (wraps at both ends).
Root cause found via datasheet: PxIM0/PxIM1 has no dual-edge mode, only
falling/rising/low-level/high-level. (IM1=1,IM0=1) was actually
high-level interrupt, refiring continuously for the whole high-pulse
duration (confirmed by scope: no real HF noise, and edge_count=0 when
P3.6 grounded). Fix: start in rising-edge mode, software-toggle to the
opposite edge on every trigger (ping-pong) to emulate true dual-edge
triggering, feeding exact edge direction into the incremental decode
state machine (no glitch filter needed). Also switch P3.6 idle bias
from pull-up to pull-down, since floating-high under the old high-level
mode caused the interrupt-storm boot issue; removed the now-conflicting
pull-up restore in Wakeup_Restore().
Diagnostic experiment: restore the commit d8df5d4 polling decode
algorithm/thresholds unchanged, while P3.6 ISR now only increments an
edge counter (no decode state machine). Successful decodes print the
edge-count delta over the decode window to compare against the
EV1527 theoretical 50-edges-per-frame, to validate/refute the
edge-interrupt glitch-noise hypothesis.
App/isr_jump.asm was never added to wristband.uvproj, so the Port0/Port2/Port3
hardware vector redirects it defines were never assembled. Port3_Isr (declared
as interrupt 16) never actually ran on real P3 port events, causing the
edge-interrupt-driven RF decode to silently never fire. Adds the missing
CSEG/LJMP redirect for vector 40 and registers the file as FileType=2.