From a307a69fc19df523668f191f21061f9d5457fef9 Mon Sep 17 00:00:00 2001 From: Sebastian Kuzminsky Date: Fri, 16 Mar 2012 10:16:53 -0600 Subject: [PATCH] add a component to detect clicks, double-clicks, etc This one goes up to quadruple clicks. I find it useful for overloading the functionality of the hard buttons on the control panel of my mill. For example, in my config, multi-clicks on the Z+ jog button are detected and routed to halui, where they trigger MDI commands: Double-clicking runs "quill up". Triple-clicking runs my "present work" subroutine: quill up and bring the table to the front and center for operator access. Quadruple-clicking runs my "stow" subroutine: quill up and bring the table to the back and center for out-of-the way storage at the end of the night. A debounce component may be advisable between the input signal and the multiclick component. --- docs/man/man9/.gitignore | 1 + src/hal/components/multiclick.comp | 387 +++++++++++++++++++++++++++++ tests/multiclick/README | 1 + tests/multiclick/expected | 105 ++++++++ tests/multiclick/input-signals | 119 +++++++++ tests/multiclick/test.hal | 59 +++++ 6 files changed, 672 insertions(+) create mode 100644 src/hal/components/multiclick.comp create mode 100644 tests/multiclick/README create mode 100644 tests/multiclick/expected create mode 100644 tests/multiclick/input-signals create mode 100644 tests/multiclick/test.hal diff --git a/docs/man/man9/.gitignore b/docs/man/man9/.gitignore index 514a7bd0060..0dcbaff2154 100644 --- a/docs/man/man9/.gitignore +++ b/docs/man/man9/.gitignore @@ -69,6 +69,7 @@ mesa_7i65.9 message.9 minmax.9 mult2.9 +multiclick.9 multiswitch.9 mux2.9 mux4.9 diff --git a/src/hal/components/multiclick.comp b/src/hal/components/multiclick.comp new file mode 100644 index 00000000000..92d27c13e14 --- /dev/null +++ b/src/hal/components/multiclick.comp @@ -0,0 +1,387 @@ + +// +// This is a single-, double-, triple-, and quadruple-click detector +// component for LinuxCNC. +// +// Copyright 2012 Sebastian Kuzminsky +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +component multiclick "Single-, double-, triple-, and quadruple-click detector"; +license "GPL"; + +pin in bit in "The input line, this is where we look for clicks."; + +pin out bit single_click +"Goes high briefly when a single-click is detected on the 'in' pin."; + +pin out bit single_click_only +"""Goes high briefly when a single-click is detected on the 'in' pin +and no second click followed it."""; + +pin out bit double_click +"Goes high briefly when a double-click is detected on the 'in' pin."; + +pin out bit double_click_only +"""Goes high briefly when a double-click is detected on the 'in' pin +and no third click followed it."""; + +pin out bit triple_click +"Goes high briefly when a triple-click is detected on the 'in' pin."; + +pin out bit triple_click_only +"""Goes high briefly when a triple-click is detected on the 'in' pin +and no fourth click followed it."""; + +pin out bit quadruple_click +"Goes high briefly when a quadruple-click is detected on the 'in' pin."; + +pin out bit quadruple_click_only +"""Goes high briefly when a quadruple-click is detected on the 'in' +pin and no fifth click followed it."""; + + +// for debugging +pin out s32 state; + + +param rw bit invert_input = FALSE +"""If FALSE (the default), clicks start with rising edges. If TRUE, +clicks start with falling edges."""; + +param rw u32 max_hold_ns = 250000000 +"""If the input is held down longer than this, it's not part of a +multi-click. (Default 250,000,000 ns, 250 ms.)"""; + +param rw u32 max_space_ns = 250000000 +"""If the input is released longer than this, it's not part of a +multi-click. (Default 250,000,000 ns, 250 ms.)"""; + +param rw u32 output_hold_ns = 100000000 +"""Positive pulses on the output pins last this long. (Default +100,000,000 ns, 100 ms.)"""; + + +variable int click_state = 0; // wish i could have an enum type here + + +// +// When entering a new non-IDLE state in the state machine, timer is set to +// 0 and timeout is set to the timeout for the new state. +// +// Each time the component's function runs and the state machine is not +// IDLE, the timer is incremented by the thread period. When the timer +// exceeds the timeout, the state machine resets. +// + +variable unsigned timer; +variable unsigned timeout; + + +// +// When an "X"-click (for X={single,double,triple,quadruple}) is detected, +// the X-click pin goes high and the X_click_hold_timer is set to the +// output_hold_ns param. Each invocation of the function, the +// X_click_hold_timer is decremented by the thread period, and when the +// timer falls below 0, the X-click output pin goes back to low again. +// +// Similarly for the X_click_only_hold_timer, but it doesnt start until +// max_space_ns after the click is detected (to ensure that this is not an +// X+1 click). +// + +variable unsigned single_click_hold_timer; +variable unsigned single_click_only_hold_timer; + +variable unsigned double_click_hold_timer; +variable unsigned double_click_only_hold_timer; + +variable unsigned triple_click_hold_timer; +variable unsigned triple_click_only_hold_timer; + +variable unsigned quadruple_click_hold_timer; +variable unsigned quadruple_click_only_hold_timer; + + +description """A click is defined as a rising edge on the 'in' pin, +followed by the 'in' pin being True for at most 'max-hold-ns' nanoseconds, +followed by a falling edge. + +A double-click is defined as two clicks, separated by at +most 'max-space-ns' nanoseconds with the 'in' pin in the False state. + +I bet you can guess the definition of triple- and quadruple-click. + +You probably want to run the input signal through a debounce component +before feeding it to the multiclick detector, if the input is at all +noisy. + +The '*-click' pins go high as soon as the input detects the correct +number of clicks. + +The '*-click-only' pins go high a short while after the click, after +the click separator space timeout has expired to show that no further +click is coming. This is useful for triggering halui MDI commands."""; + + +function _ nofp "Detect single-, double-, triple-, and quadruple-clicks"; + +;; + +typedef enum { + IDLE = 0, + SAW_FIRST_RISING_EDGE, + SAW_FIRST_CLICK, + SAW_SECOND_RISING_EDGE, + SAW_SECOND_CLICK, + SAW_THIRD_RISING_EDGE, + SAW_THIRD_CLICK, + SAW_FOURTH_RISING_EDGE, + SAW_FOURTH_CLICK, + HELD_TOO_LONG +} state_t; + +FUNCTION(_) { + int new_in = in; + + if (1 == invert_input) { + new_in = !new_in; + } + + if (click_state != IDLE) { + timer += period; + } + + + // + // update the output pins + // + + if (single_click_hold_timer > 0) { + if (single_click_hold_timer > period) { + single_click_hold_timer -= period; + } else { + single_click_hold_timer = 0; + single_click = 0; + } + } + + if (single_click_only_hold_timer > 0) { + if (single_click_only_hold_timer > period) { + single_click_only_hold_timer -= period; + } else { + single_click_only_hold_timer = 0; + single_click_only = 0; + } + } + + if (double_click_hold_timer > 0) { + if (double_click_hold_timer > period) { + double_click_hold_timer -= period; + } else { + double_click_hold_timer = 0; + double_click = 0; + } + } + + if (double_click_only_hold_timer > 0) { + if (double_click_only_hold_timer > period) { + double_click_only_hold_timer -= period; + } else { + double_click_only_hold_timer = 0; + double_click_only = 0; + } + } + + if (triple_click_hold_timer > 0) { + if (triple_click_hold_timer > period) { + triple_click_hold_timer -= period; + } else { + triple_click_hold_timer = 0; + triple_click = 0; + } + } + + if (triple_click_only_hold_timer > 0) { + if (triple_click_only_hold_timer > period) { + triple_click_only_hold_timer -= period; + } else { + triple_click_only_hold_timer = 0; + triple_click_only = 0; + } + } + + if (quadruple_click_hold_timer > 0) { + if (quadruple_click_hold_timer > period) { + quadruple_click_hold_timer -= period; + } else { + quadruple_click_hold_timer = 0; + quadruple_click = 0; + } + } + + if (quadruple_click_only_hold_timer > 0) { + if (quadruple_click_only_hold_timer > period) { + quadruple_click_only_hold_timer -= period; + } else { + quadruple_click_only_hold_timer = 0; + quadruple_click_only = 0; + } + } + + + // + // update state, if needed + // + + switch (click_state) { + case IDLE: { + if (1 == new_in) { + click_state = SAW_FIRST_RISING_EDGE; + timer = 0; + timeout = max_hold_ns; + } + break; + } + + case SAW_FIRST_RISING_EDGE: { + if (0 == new_in) { + click_state = SAW_FIRST_CLICK; + timer = 0; + timeout = max_space_ns; + single_click = 1; + single_click_hold_timer = output_hold_ns; + } + break; + } + + case SAW_FIRST_CLICK: { + if (1 == new_in) { + click_state = SAW_SECOND_RISING_EDGE; + timer = 0; + timeout = max_hold_ns; + } + break; + } + + case SAW_SECOND_RISING_EDGE: { + if (0 == new_in) { + click_state = SAW_SECOND_CLICK; + timer = 0; + timeout = max_space_ns; + double_click = 1; + double_click_hold_timer = output_hold_ns; + } + break; + } + + case SAW_SECOND_CLICK: { + if (1 == new_in) { + click_state = SAW_THIRD_RISING_EDGE; + timer = 0; + timeout = max_hold_ns; + } + break; + } + + case SAW_THIRD_RISING_EDGE: { + if (0 == new_in) { + click_state = SAW_THIRD_CLICK; + timer = 0; + timeout = max_space_ns; + triple_click = 1; + triple_click_hold_timer = output_hold_ns; + } + break; + } + + case SAW_THIRD_CLICK: { + if (1 == new_in) { + click_state = SAW_FOURTH_RISING_EDGE; + timer = 0; + timeout = max_hold_ns; + } + break; + } + + case SAW_FOURTH_RISING_EDGE: { + if (0 == new_in) { + // four clicks is the most we look for, and we just saw it, + // so we're done now + click_state = SAW_FOURTH_CLICK; + timer = 0; + timeout = max_space_ns; + quadruple_click = 1; + quadruple_click_hold_timer = output_hold_ns; + } + break; + } + + case SAW_FOURTH_CLICK: { + if (1 == new_in) { + click_state = HELD_TOO_LONG; + } + break; + } + + case HELD_TOO_LONG: { + if (0 == new_in) { + click_state = IDLE; + } + break; + } + + default: { + // invalid click_state! + click_state = IDLE; + } + } + + if ((click_state != IDLE) && (click_state != HELD_TOO_LONG) && (timer > timeout)) { + if (1 == new_in) { + click_state = HELD_TOO_LONG; + } else { + // timeout after some activity on the input line, trigger one + // of the "only" outputs if appropriate + switch (click_state) { + case SAW_FIRST_CLICK: { + single_click_only = 1; + single_click_only_hold_timer = output_hold_ns; + break; + } + case SAW_SECOND_CLICK: { + double_click_only = 1; + double_click_only_hold_timer = output_hold_ns; + break; + } + case SAW_THIRD_CLICK: { + triple_click_only = 1; + triple_click_only_hold_timer = output_hold_ns; + break; + } + case SAW_FOURTH_CLICK: { + quadruple_click_only = 1; + quadruple_click_only_hold_timer = output_hold_ns; + break; + } + } + click_state = IDLE; + } + } + + state = click_state; +} + diff --git a/tests/multiclick/README b/tests/multiclick/README new file mode 100644 index 00000000000..2fab595bd42 --- /dev/null +++ b/tests/multiclick/README @@ -0,0 +1 @@ +regression test for multi-click component diff --git a/tests/multiclick/expected b/tests/multiclick/expected new file mode 100644 index 00000000000..0271c88624a --- /dev/null +++ b/tests/multiclick/expected @@ -0,0 +1,105 @@ +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 +0 1 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 9 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 9 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 9 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +0 1 0 0 0 0 0 0 0 2 1 1 0 0 0 0 0 0 0 2 +0 0 0 0 0 0 0 0 0 2 1 1 0 0 0 0 0 0 0 2 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 2 +0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 2 +0 0 0 0 0 0 0 0 0 2 1 0 1 0 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 2 +0 1 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 3 +0 0 0 0 0 0 0 0 0 2 1 0 0 1 0 0 0 0 0 4 +1 0 0 0 0 0 0 0 0 3 0 0 0 1 0 0 0 0 0 5 +1 0 0 0 0 0 0 0 0 3 1 0 0 0 0 1 0 0 0 6 +1 0 0 0 0 0 0 0 0 3 1 0 0 0 0 1 0 0 0 6 +0 0 0 1 0 0 0 0 0 4 1 0 0 0 0 0 0 0 0 6 +0 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 0 0 0 6 +0 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 1 0 0 0 +0 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 1 0 0 0 +0 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +0 1 0 0 0 0 0 0 0 2 1 1 0 0 0 0 0 0 0 2 +1 0 0 0 0 0 0 0 0 3 0 1 0 0 0 0 0 0 0 3 +0 0 0 1 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 3 +1 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 3 +0 0 0 0 0 1 0 0 0 6 0 0 0 0 0 0 0 0 0 3 +0 0 0 0 0 0 0 0 0 6 1 0 0 1 0 0 0 0 0 4 +0 0 0 0 0 0 0 0 0 6 1 0 0 1 0 0 0 0 0 4 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 0 4 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 0 4 +0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 0 9 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 2 +1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 3 +0 1 0 0 0 0 0 0 0 2 1 0 0 1 0 0 0 0 0 4 +1 0 0 0 0 0 0 0 0 3 0 0 0 1 0 0 0 0 0 5 +1 0 0 0 0 0 0 0 0 3 1 0 0 0 0 1 0 0 0 6 +1 0 0 0 0 0 0 0 0 3 0 0 0 0 0 1 0 0 0 7 +0 0 0 1 0 0 0 0 0 4 1 0 0 0 0 0 0 1 0 8 +1 0 0 0 0 0 0 0 0 5 1 0 0 0 0 0 0 1 0 8 +1 0 0 0 0 0 0 0 0 5 1 0 0 0 0 0 0 0 0 8 +0 0 0 0 0 1 0 0 0 6 1 0 0 0 0 0 0 0 0 8 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 6 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 0 0 0 0 3 1 1 0 0 0 0 0 0 0 2 +0 0 0 1 0 0 0 0 0 4 1 1 0 0 0 0 0 0 0 2 +1 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 3 +0 0 0 0 0 1 0 0 0 6 0 0 0 0 0 0 0 0 0 3 +1 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 3 +0 0 0 0 0 0 0 1 0 8 1 0 0 1 0 0 0 0 0 4 +0 0 0 0 0 0 0 0 0 8 1 0 0 1 0 0 0 0 0 4 +0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 5 +0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 5 +0 0 0 0 0 0 0 0 0 8 1 0 0 0 0 1 0 0 0 6 +0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 7 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 8 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 8 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 8 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 8 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 diff --git a/tests/multiclick/input-signals b/tests/multiclick/input-signals new file mode 100644 index 00000000000..c30b758b850 --- /dev/null +++ b/tests/multiclick/input-signals @@ -0,0 +1,119 @@ +# one quick click on instance 0 +# .single-click goes high on the falling edge +# then release the button and leave it up for 5 ms to clear the state +0 1 +1 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 + +# chan 0: push and hold too long, then release and quick click +# chan 1: single click +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +0 1 +1 1 +1 0 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 + +# chan 0: double click +# chan 1: triple click +1 0 +1 1 +0 0 +0 1 +1 0 +1 1 +1 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 + +# chan 0: quick triple click +# chan 1: one click then hold too long +1 0 +0 1 +1 0 +0 0 +1 0 +0 0 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 + +# push both buttons, make sure they expire at the right time +1 0 +1 0 +1 0 +1 0 +1 0 +0 0 +0 0 +0 1 +0 1 +0 1 +0 1 + +# slow clicks on button 0, fast clicks on button 1 +1 0 +1 1 +1 0 +0 1 +1 0 +1 1 +1 0 +0 1 +1 1 +1 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 +0 1 + +# quad click on both buttons +1 0 +0 0 +1 1 +0 1 +1 0 +0 0 +1 0 +0 1 +0 1 +0 0 +0 0 +0 1 +0 0 +0 0 +0 1 +0 1 +0 1 +0 1 +0 1 + diff --git a/tests/multiclick/test.hal b/tests/multiclick/test.hal new file mode 100644 index 00000000000..9e4d8558fc9 --- /dev/null +++ b/tests/multiclick/test.hal @@ -0,0 +1,59 @@ + +loadrt threads name1=millisecond period1=1000000 + +loadrt multiclick count=2 +loadrt sampler depth=100 cfg=bbbbbbbbbsbbbbbbbbbs +loadrt streamer depth=100 cfg=bb + + +net in0 streamer.0.pin.0 => multiclick.0.in sampler.0.pin.0 + +net out0.single multiclick.0.single-click => sampler.0.pin.1 +net out0.single-only multiclick.0.single-click-only => sampler.0.pin.2 +net out0.double multiclick.0.double-click => sampler.0.pin.3 +net out0.double-only multiclick.0.double-click-only => sampler.0.pin.4 +net out0.triple multiclick.0.triple-click => sampler.0.pin.5 +net out0.triple-only multiclick.0.triple-click-only => sampler.0.pin.6 +net out0.quadruple multiclick.0.quadruple-click => sampler.0.pin.7 +net out0.quadruple-only multiclick.0.quadruple-click-only => sampler.0.pin.8 + +net state.0 multiclick.0.state => sampler.0.pin.9 + + +net in1 streamer.0.pin.1 => multiclick.1.in sampler.0.pin.10 + +net out1.single multiclick.1.single-click => sampler.0.pin.11 +net out1.single-only multiclick.1.single-click-only => sampler.0.pin.12 +net out1.double multiclick.1.double-click => sampler.0.pin.13 +net out1.double-only multiclick.1.double-click-only => sampler.0.pin.14 +net out1.triple multiclick.1.triple-click => sampler.0.pin.15 +net out1.triple-only multiclick.1.triple-click-only => sampler.0.pin.16 +net out1.quadruple multiclick.1.quadruple-click => sampler.0.pin.17 +net out1.quadruple-only multiclick.1.quadruple-click-only => sampler.0.pin.18 + +net state.1 multiclick.1.state => sampler.0.pin.19 + + +addf streamer.0 millisecond +addf multiclick.0 millisecond +addf multiclick.1 millisecond +addf sampler.0 millisecond + + +setp multiclick.0.max-hold-ns 2500000 +setp multiclick.0.max-space-ns 4500000 +setp multiclick.0.output-hold-ns 500000 + +setp multiclick.1.max-hold-ns 3500000 +setp multiclick.1.max-space-ns 3500000 +setp multiclick.1.output-hold-ns 1500000 +setp multiclick.1.invert-input True + + +# run halstreamer and let it pre-load the fifo +loadusr halstreamer input-signals +loadusr -w sleep 0.5 + +start +loadusr -w halsampler -n 105 +