FSM simulation: Rotary-dial pulse counter
This is the interactive simulator of the rotary-dial pulse-counting state machine that runs inside the USB HID Phone firmware. It animates the FSM in sync with a live timing diagram showing in_nsa, in_nsi, the active state and pulseCount, and is meant for teaching, documentation and screencasts.
The ISR body in the simulator is a direct port of InterruptHandlerHigh() from user/user_mouse.c: same four states, same transitions, counting in_nsi falling edges only while in_nsa is high.
- One simulated tick = one real 10 ms Timer0 interrupt.
- Pulse-low / pulse-high durations in the scenarios (6 ticks / 4 ticks) are representative of a real rotary dial returning at ~10 pulses per second.
- On the last pulse,
↑in_nsiand↓in_nsacoincide;in_nsithen stays high with no further pulses.
If the embedded view is too cramped: open the simulator in a new tab.
Scenarios
| Value | Description |
|---|---|
dial1 |
Dial “1”: single pulse |
dial2 |
Dial “2”: two pulses |
dial3 |
Dial “3”: three pulses (default) |
dial4 |
Dial “4”: four pulses |
dial5 |
Dial “5”: five pulses |
dial6 |
Dial “6”: six pulses |
dial7 |
Dial “7”: seven pulses |
dial8 |
Dial “8”: eight pulses |
dial9 |
Dial “9”: nine pulses |
dial0 |
Dial “0”: ten pulses (rotary-dial encoding for zero) |
dial21 |
Dial “2” then “1” back-to-back, showing successive digits |
manual |
Drive in_nsa / in_nsi yourself via the pills below the controls |
Keyboard shortcuts
| Key | Action |
|---|---|
Space |
Play / Pause |
S or → |
Step one tick |
← |
Step back |
R |
Reset |
URL parameters
The simulator can be deep-linked, which is handy for documentation or scripted recordings:
fsm_demo.html?scenario=dial3&speed=0.1&autoplay=1
| Parameter | Values | Effect |
|---|---|---|
scenario |
dial1 … dial9, dial0, dial21, manual |
Preload a scenario |
speed |
0.01 … 1.0 |
Real-time multiplier |
autoplay |
1 |
Start playing immediately |
tick |
integer | Seek to a specific tick on load (stills) |
What you should see
- On
↑in_nsathe FSM jumps fromSTATE_INITtoSTATE_DIALand resetspulseCountto 0. - Each
↓in_nsiwhile inSTATE_DIALflips us toSTATE_PULSE_LOWand incrementspulseCount. - Each
↑in_nsiflips us back toSTATE_DIAL. - When
↓in_nsaarrives andpulseCount > 0, we go toSTATE_DONE. - The (simulated)
processIO()then computespulseCount + HID_KP_BASE, lights up the green digit N pill in the header, flashes theSTATE_DONE → STATE_INITedge, and we are armed for the next digit.
Back to the USB HID Phone project page.