Rotary-dial FSM animator user_mouse.c — InterruptHandlerHigh

t0 ms
tick0 / 0
stateSTATE_INIT
pulseCount0
in_nsa0
in_nsi1
Mental model: in_nsa=1 means "dial active". Each falling edge of in_nsi increments pulseCount. A rising edge of in_nsi re-arms the next count. When in_nsa falls, the digit is complete (STATE_DONE), then ProcessIO() sends the HID key and returns to STATE_INIT.

State chart

RotaryDialFSM Rotary-dial pulse counter FSM     user_mouse.c - sampled every 10 ms (Timer0 ISR) cluster_legend Legend __start__ STATE_INIT STATE_INIT wait for dial to start __start__->STATE_INIT  power-up   STATE_DIAL STATE_DIAL armed, wait for pulse low STATE_INIT->STATE_DIAL ↑in_nsa / pulseCount = 0 STATE_PULSE_LOW STATE_PULSE_LOW in_nsi low, wait for in_nsi high STATE_DIAL->STATE_PULSE_LOW ↓in_nsi / pulseCount++ STATE_DONE STATE_DONE digit finalized, awaiting HID TX STATE_DIAL->STATE_DONE ↓in_nsa [pulseCount > 0] ______padding______ STATE_PULSE_LOW->STATE_DIAL ↑in_nsi STATE_PULSE_LOW->STATE_DONE ↓in_nsa [pulseCount > 0] ______padding______ STATE_DONE->STATE_INIT ProcessIO sends HID report buffer1[3] = pulseCount + HID_KP_BASE HIDTxReport(buffer1, KBD_REPORT_SIZE) default_note default: any unexpected state value resets to STATE_INIT default_note->STATE_INIT legend_inputs Signal / Symbol Meaning in_nsa (RB6) dial-active contact (high while dialing) in_nsi (RB7) pulse contact (low during pulse) pulseCount pulse count (= dialed digit; 10 = "0") ↑sig rising edge  (0 → 1) ↓sig falling edge (1 → 0) [guard] UML guard condition

Timing diagram

Press ▶ Play to start.
FeTAp 611 rotary-dial Schaltplan (nsa / nsi contact wiring)
FeTAp 611 dial wiring — nsa (off-normal) and nsi (pulse) contacts, the same signals shown above as in_nsa / in_nsi.