Skip to content

Fix/aura sleep and reassert - #15

Open
alsocat wants to merge 61 commits into
ZimengXiong:mainfrom
alsocat:fix/aura-sleep-and-reassert
Open

alsocat wants to merge 61 commits into
ZimengXiong:mainfrom
alsocat:fix/aura-sleep-and-reassert

Conversation

@alsocat

@alsocat alsocat commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

ZimengXiong and others added 29 commits July 9, 2026 06:22
…ware

Add unified firmware and setup tooling
Updated the link to tinytouch.dev to use HTTPS.
serve_port() treated whatever readline() returned at its 0.2 s timeout as a
complete line, so an event split across two reads was HMAC-verified as a
fragment and rejected. In a captured log this silently discarded 2 of 20
touches, visible only as "bad event mac" on stderr.

A USB suspend can also cut a write off mid-event. Those bytes are lost rather
than delayed, so the remains arrive concatenated with the next event and parse
as too many fields -- dropping a second, valid touch as well, and this time
with no log line at all because the field count is checked before the MAC.

Buffer until a newline arrives, and resynchronise on the last "EV " marker so a
truncated leading fragment cannot take the intact event behind it down with it.
The discarded fragment is now reported instead of failing silently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
set_aura() cached the requested colour even when the sensor had not
acknowledged the command, and skipped sending anything when the cache already
matched. A single dropped command therefore desynchronised the cache from the
hardware permanently: every later request for that colour became a no-op, so
the aura stayed on whatever it had been doing.

show_result() made that reachable in ordinary use. It started a two-cycle flash
program on the sensor, then sent a steady colour only 350 ms later while that
program was still running, so the sensor discarded it.

Cache the colour only when the command is acknowledged, and build the result
blink out of steady commands so no program is left running for a later command
to fight with.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
usb_ccid_start() configures TinyUSB with TINYUSB_DEFAULT_CONFIG(), which in
esp_tinyusb 2.2.1 populates .task -- so tinyusb_driver_install() starts its own
task whose entire job is calling tud_task(). app_main() then called it again in
a 1 ms loop, leaving two contexts racing the same event queue.

app_main() now returns once the subsystems are started. config_console and
touch_hid already run as their own tasks, so nothing depended on the main task
staying alive, and usb_ccid_task() had no other caller.

This is not a fix for the device becoming unreachable after the host suspends.
That fault persists with this change applied and its cause is not yet known.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The wiring section named pins 6 and 7 for TX/RX and pin 1 for the interrupt.
Both firmwares use GPIO43 (TX), GPIO44 (RX) and GPIO2 (INT) -- and the CLI's
own sensor error message already directs users to check GPIO44/43, so the
README contradicted the tool.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The installer runs as a child process, so it cannot change PATH in the
terminal that started it. It only wrote ~/.zprofile and told the user to
open a new Terminal, so `tinytouch setup` failed with command not found
in the shell they had just used.

Write ~/.zshrc as well. Login shells read .zprofile, but shells started
without -l only read .zshrc, so those never picked up the change even in
a new window. Guard the exported line so sourcing both files is harmless.

Point at `exec zsh -l`, which reloads the current shell in place, instead
of asking for a new window.

Vendor the installer as packaging/install.sh. It was only ever served
from the website, so it was unreviewed, unversioned, and free to drift
from the CLI it installs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The HID poll ran fingerprint_match_captured(quiet=true), and every branch
that paints a result is guarded by !quiet. A normal touch is the only path
that path takes, so the firmware never drove the LED at all and the sensor's
own animation owned it. Run the poll non-quiet: quiet only suppressed the
logging of a touch that genuinely happened, and the guard silenced the
result colours with it.

set_aura alone cannot recover from that. The sensor repaints its aura while
it captures, so afterwards the cache still claims BLUE and the equality
guard discards the correction as redundant. force_aura clears the cache
first, and the poll re-asserts through it once a capture has run.

Fade out and sleep the aura after FP_SLEEP_AFTER_MS without a finger, waking
on the detect pin. The pin is debounced over two ticks; a single stray read
otherwise walks the aura through wake and sleep on its own.

The fade has to be the sensor's own ramp. Dimming in firmware costs a UART
round trip per step, which caps the duty cycle near 12 Hz and reads as
flashing. But this sensor ignores the cycle-count parameter -- the original
flash-mode blink passed times=2 and still ran forever -- so every program it
accepts runs until another command replaces it, and while one runs it
discards commands. So: start the ramp, wait for it to bottom out, then retry
a steady blackout until one is acknowledged. FP_FADE_MS is the measured ramp
length at speed 60; landing early clips the fade visibly.

Verified on hardware: red and green results, fade to dark on idle, no
stranding after a failed match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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