summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDewey Garrett <dgarrett@panix.com>2014-01-31 16:57:30 -0700
committerDewey Garrett <dgarrett@panix.com>2014-02-01 19:11:23 -0700
commit3f5702a20c99f0f5e5fa8281499a91b1eb1ebe70 (patch)
tree459bb74455996878e65fc57b204ee90f622ba6c5
parentd91abc0dc107b18497cae05296fd717f5eac3a88 (diff)
downloadlinuxcnc-3f5702a20c99f0f5e5fa8281499a91b1eb1ebe70.tar.gz
linuxcnc-3f5702a20c99f0f5e5fa8281499a91b1eb1ebe70.zip
xhc-hb04 (usb wireless mpg) sim configs
Use Frederick Rible's xhc-hb04 component to make simulator configs for two known button layouts. A new halfile (xhc-hb04.tcl) and component (xhc_hb04_util.comp) make it possible to add the pendant with minor edits to a user ini file since no glue-logic hal components are involved. It is assumed/required that a thread named servo-thread exists. Ini file entries: [XHC_HB04_BUTTONS]name=pin define button connections for the buttons defined in the layout cfg file [XHC_HB04_CONFIG]layout=2 (required: 1|2 2 is most common) [XHC_HB04_CONFIG]coords= x y z a (optional, default = x y z a) [XHC_HB04_CONFIG]coefs= 1 1 1 1 (optional filter coefs, not usually required) [XHC_HB04_CONFIG]scales= 1 1 1 1 (optional) layout specifies one of two button layouts. coords specifies the axes for the jogwheel selector. coefs specifies filter coeficient terms to slow response. scales specifies plus/minus scale factors for each axis. Two additional jogwheel selections provide spindle and feedrate control.
-rwxr-xr-xconfigs/sim/axis/xhc-hb04/README40
l---------configs/sim/axis/xhc-hb04/axis_manualtoolchange.hal1
l---------configs/sim/axis/xhc-hb04/core_sim9.hal1
l---------configs/sim/axis/xhc-hb04/sim.tbl1
l---------configs/sim/axis/xhc-hb04/sim_spindle_encoder.hal1
l---------configs/sim/axis/xhc-hb04/simulated_home.hal1
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout1.cfg17
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini304
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt35
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout2.cfg19
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini306
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt35
-rw-r--r--configs/sim/axis/xhc-hb04/xhc-hb04.tcl295
-rw-r--r--src/hal/components/xhc_hb04_util.comp71
14 files changed, 1127 insertions, 0 deletions
diff --git a/configs/sim/axis/xhc-hb04/README b/configs/sim/axis/xhc-hb04/README
new file mode 100755
index 000000000..97b75445c
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/README
@@ -0,0 +1,40 @@
+These sim configurations demonstrate use of an XHC-HB04 wireless MPG pendant in LinuxCNC using a HAL module created by Frederic Rible (frible@teaser.fr) (Copyright (C) 2013). Ref:
+
+http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Using_A_XHC-HB04_Wireless_MPG_Pendant
+
+The HAL module is designed for the XHC-HB04 V3.0 identified as USB device 10CE:EB70.
+Most of the pendant features are handled:
+- buttons converted to hal pins
+- jog wheel with variable scale (use STEP button to select scale)
+- LCD screen
+
+Sim configurations are provided for several know button configurations:
+
+layout1 -- 16 buttons
+layout2 -- 18 buttons (more common)
+
+A working and connected xhc-hb04 device is required for the demonstration. If not connected, the sim configs will start anyway.
+
+A udev rules file:
+ /etc/udev/rules.d/90-xhc.rules
+must be added to the system:
+SYSFS{idProduct}=="eb70", SYSFS{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+
+Or for later operating systems (like ubuntu12.x):
+ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+
+The sim configurations use a single halfile: xhc-hb04.tcl. This halfile uses a custom comp file (xhc_hb04_util.comp) and can be added to existing configurations by adding an ini file entry for:
+ [HAL]HALFILE=xhc-hb04.tcl
+
+Typically, this HALFILE entry should follow other entries. A thread named servo-thread is assumed and required.
+
+Other ini file entries used are:
+[XHC_HB04_CONFIG]layout=2 (1|2)
+[XHC_HB04_CONFIG]coords= x y z a (typ)
+[XHC_HB04_CONFIG]coefs= 1 1 1 1 (optional, not usually needed since xhc-hb04 smooths)
+[XHC_HB04_CONFIG]scales= 1 1 1 1 (optional, rotaries may require bigger scale)
+
+[XHC_HB04_BUTTONS]name=pin define button connections for the buttons defined in the layout file
+[HALUI]MDI_COMMAND=... define pins useful for connection to the buttons
+
+See the ini files for more detailed examples.
diff --git a/configs/sim/axis/xhc-hb04/axis_manualtoolchange.hal b/configs/sim/axis/xhc-hb04/axis_manualtoolchange.hal
new file mode 120000
index 000000000..397c8934a
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/axis_manualtoolchange.hal
@@ -0,0 +1 @@
+../../axis_manualtoolchange.hal \ No newline at end of file
diff --git a/configs/sim/axis/xhc-hb04/core_sim9.hal b/configs/sim/axis/xhc-hb04/core_sim9.hal
new file mode 120000
index 000000000..32979d06f
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/core_sim9.hal
@@ -0,0 +1 @@
+../../core_sim9.hal \ No newline at end of file
diff --git a/configs/sim/axis/xhc-hb04/sim.tbl b/configs/sim/axis/xhc-hb04/sim.tbl
new file mode 120000
index 000000000..1dccf4afb
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/sim.tbl
@@ -0,0 +1 @@
+../../sim.tbl \ No newline at end of file
diff --git a/configs/sim/axis/xhc-hb04/sim_spindle_encoder.hal b/configs/sim/axis/xhc-hb04/sim_spindle_encoder.hal
new file mode 120000
index 000000000..e83032b1e
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/sim_spindle_encoder.hal
@@ -0,0 +1 @@
+../../sim_spindle_encoder.hal \ No newline at end of file
diff --git a/configs/sim/axis/xhc-hb04/simulated_home.hal b/configs/sim/axis/xhc-hb04/simulated_home.hal
new file mode 120000
index 000000000..a0e8e5601
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/simulated_home.hal
@@ -0,0 +1 @@
+../../simulated_home.hal \ No newline at end of file
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.cfg b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.cfg
new file mode 100644
index 000000000..6a7741576
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.cfg
@@ -0,0 +1,17 @@
+[XHC-HB04]
+BUTTON=01:button-stop
+BUTTON=02:button-start-pause
+BUTTON=03:button-rewind
+BUTTON=04:button-safe-z
+BUTTON=05:button-home
+BUTTON=06:button-x2
+BUTTON=07:button-y2
+BUTTON=08:button-probe-z
+BUTTON=09:button-x0
+BUTTON=0A:button-y0
+BUTTON=0B:button-z0
+BUTTON=0C:button-goto-zero
+BUTTON=0D:button-step
+BUTTON=0E:button-mode
+BUTTON=0F:button-spindle
+BUTTON=17:button-reset
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini
new file mode 100644
index 000000000..7f7201d1a
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.ini
@@ -0,0 +1,304 @@
+# adapted from axis_9axis.ini for xhc-hb04 demo
+
+[XHC_HB04_CONFIG]
+# specify layout = n for xhc-hb04-layout{n}.cfg files
+layout = 1
+# coords: specify 4 letters
+# coords: switch labels are xyza but any unique 4 letters
+# from the set {xyxabcuvw) can be used (if the coord exists)
+coords = x y z c
+# lowpass settings:
+# coef: slows rate of change of output, range: 0 < coef < 1
+coefs = 1 1 1 1
+# scale plus or minus, rotaries may require larger scale factor:
+scales = 1 -1 1 1
+
+[XHC_HB04_BUTTONS]
+# use button names according to layout file xhc-hb04-layout{n}.cfg
+# note: "start-pause" is reserved because it is connected for
+# controlling halui.pause/halui.resume/halui.run
+# note: "step" is used by xhc-hb04.cc to change the wheel scale but
+# can also connected to a pin
+# these are examples, edit as required:
+stop = halui.program.stop
+start-pause = RESERVED
+rewind = halui.program.step
+safe-z = halui.mdi-command-01
+# in this sim, home-all only works first time, hold down till finished:
+home = halui.home-all
+x2 = halui.mdi-command-02
+y2 = halui.mdi-command-03
+# probe-input for simulating a probe:
+probe-z = motion.probe-input
+x0 = halui.mdi-command-04
+y0 = halui.mdi-command-05
+z0 = halui.mdi-command-06
+goto-zero = halui.mdi-command-00
+step = CAUTION
+mode = ""
+spindle = ""
+reset = halui.estop.activate
+
+[HALUI]
+# these are examples, edit as required:
+# a halui hal pin is created for each MDI_COMMAND below
+# halui.mdi-command-00, halui.mdi-command-01,... etc
+MDI_COMMAND=G0 X0 Y0 Z0
+MDI_COMMAND=(debug, example: mdi-01)
+MDI_COMMAND=(debug, example: mdi-02)
+#03 M110: clears notifications
+MDI_COMMAND=M110
+MDI_COMMAND=(debug, example: mdi-04)
+MDI_COMMAND=(debug, example: mdi-05)
+MDI_COMMAND=(debug, example: mdi-06)
+#07 M101: example print to stdout
+MDI_COMMAND=M101
+MDI_COMMAND=(debug, example: mdi-08)
+MDI_COMMAND=(debug, example: mdi-09)
+MDI_COMMAND=(debug, example: mdi-10)
+MDI_COMMAND=(debug, example: mdi-11)
+MDI_COMMAND=(debug, example: mdi-12)
+MDI_COMMAND=(debug, example: mdi-13)
+MDI_COMMAND=(debug, example: mdi-14)
+MDI_COMMAND=(debug, example: mdi-15)
+
+[EMC]
+MACHINE = xhc-hb04 layout1 demo
+DEBUG = 0
+
+[DISPLAY]
+DISPLAY = axis
+CYCLE_TIME = 0.100
+POSITION_OFFSET = RELATIVE
+POSITION_FEEDBACK = ACTUAL
+MAX_FEED_OVERRIDE = 1.2
+MAX_SPINDLE_OVERRIDE = 1.0
+PROGRAM_PREFIX = ../../nc_files/
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+EDITOR = gedit
+GEOMETRY = XYZABCUVW
+INCREMENTS = 1 mm, .01 in, .1mm, 1 mil, .1 mil, 1/8000 in
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python
+
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+[RS274NGC]
+PARAMETER_FILE = sim-9axis.var
+SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+# for demo of M110:
+USER_M_PATH = ../../nc_files/ngcgui_lib/mfiles
+
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+COMM_WAIT = 0.010
+SERVO_PERIOD = 1000000
+
+[HAL]
+HALFILE = core_sim9.hal
+HALFILE = sim_spindle_encoder.hal
+HALFILE = axis_manualtoolchange.hal
+HALFILE = simulated_home.hal
+HALFILE = xhc-hb04.tcl
+HALUI = halui
+
+[TRAJ]
+NO_FORCE_HOMING = 1
+AXES = 9
+COORDINATES = X Y Z A B C U V W
+HOME = 0 0 0 0 0 0 0 0 0
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+CYCLE_TIME = 0.010
+DEFAULT_VELOCITY = 1.0
+DEFAULT_ANGULAR_VELOCITY = 45.0
+POSITION_FILE = position9.txt
+MAX_LINEAR_VELOCITY = 1.2
+MAX_ANGULAR_VELOCITY = 90.0
+
+[AXIS_0]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+[AXIS_1]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_2]
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -2.0
+MAX_LIMIT = 4.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+[AXIS_3]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_4]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 45.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_5]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_6]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[AXIS_7]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[AXIS_8]
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -2.0
+MAX_LIMIT = 4.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+TOOL_TABLE = sim.tbl
+TOOL_CHANGE_POSITION = 0 0 2
+
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt
new file mode 100644
index 000000000..c2fb63ef5
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1.txt
@@ -0,0 +1,35 @@
+xhc-hb04-layout1
+
+16 buttons:
+
+---------------------------------------
+|RESET | |
+---------------------------------------
+|Stop |Start/Pause|Rewind |Probe-Z |
+---------------------------------------
+|GotoZero| X2 | Y2 |Safe-Z |
+---------------------------------------
+| X=0 | Y=0 | Z=0 | Home |
+---------------------------------------
+|STEP | Mode |Spindle| |
+---------------------------------------
+| Off |
+| X |
+| Y |
+| Rotary -------> Z |
+| Switch A |
+| Spindle |
+| Feed |
+---------------------------------------
+
+Button codes defined in xhc-hb04-layout1.cfg
+
+The STEP button isused to change the wheel multiplier and can also be connected to a pin.
+
+The Start/Pause button is reserved to control halui.program.run,pause,resume.
+
+The other buttons can be connected to hal pins -- typically halui provided pins. MDI commands can be executed using halui.mdi-command-nn pins defined in the ini file with [HALUI]MDI_COMMAND= entries.
+
+The rotary switch selects the axis, spindle, or feedoverride for control by the jogwheel.
+
+The switch positions (xyza) can be defined to any available axis (xyzc for instance).
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.cfg b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.cfg
new file mode 100644
index 000000000..d84465856
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.cfg
@@ -0,0 +1,19 @@
+[XHC-HB04]
+BUTTON=01:button-goto-zero
+BUTTON=02:button-start-pause
+BUTTON=03:button-rewind
+BUTTON=04:button-probe-z
+BUTTON=05:button-macro-3
+BUTTON=06:button-half
+BUTTON=07:button-zero
+BUTTON=08:button-safe-z
+BUTTON=09:button-home
+BUTTON=0A:button-macro-1
+BUTTON=0B:button-macro-2
+BUTTON=0C:button-spindle
+BUTTON=0D:button-step
+BUTTON=0E:button-mode
+BUTTON=0F:button-macro-6
+BUTTON=10:button-macro-7
+BUTTON=16:button-stop
+BUTTON=17:button-reset
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini
new file mode 100644
index 000000000..f65780303
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.ini
@@ -0,0 +1,306 @@
+# adapted from axis_9axis.ini for xhc-hb04 demo
+
+[XHC_HB04_CONFIG]
+# specify layout = n for xhc-hb04-layout{n}.cfg files
+layout = 2
+# coords: specify 4 letters
+# coords: switch labels are xyza but any unique 4 letters
+# from the set {xyxabcuvw) can be used (if the coord exists)
+coords = x y z c
+# lowpass settings:
+# coef: slows rate of change of output, range: 0 < coef < 1
+coefs = 1 1 1 1
+# scale plus or minus, rotaries may require larger scale factor:
+scales = 1 -1 1 1
+
+[XHC_HB04_BUTTONS]
+# use button names according to layout file xhc-hb04-layout{n}.cfg
+# note: "start-pause" is reserved because it is connected for
+# controlling halui.pause/halui.resume/halui.run
+# note: "step" is used by xhc-hb04.cc to change the wheel scale but
+# can also connected to a pin
+# these are examples, edit as required:
+goto-zero = halui.mdi-command-00
+start-pause = RESERVED
+rewind = halui.program.step
+# probe-input for simulating a probe:
+probe-z = motion.probe-input
+macro-3 = halui.mdi-command-03
+half = halui.spindle.stop
+zero = ""
+safe-z = halui.mdi-command-10
+# in this sim, home-all only works first time, hold down till finished:
+home = halui.home-all
+macro-1 = halui.mdi-command-01
+macro-2 = halui.mdi-command-02
+spindle = halui.spindle.start
+step = CAUTION
+mode = ""
+macro-6 = halui.mdi-command-06
+macro-7 = halui.mdi-command-07
+stop = halui.program.stop
+reset = halui.estop.activate
+
+[HALUI]
+# these are examples, edit as required:
+# a halui hal pin is created for each MDI_COMMAND below
+# halui.mdi-command-00, halui.mdi-command-01,... etc
+MDI_COMMAND=G0 X0 Y0 Z0
+MDI_COMMAND=(debug, example: mdi-01)
+MDI_COMMAND=(debug, example: mdi-02)
+#03 M110: clears notifications
+MDI_COMMAND=M110
+MDI_COMMAND=(debug, example: mdi-04)
+MDI_COMMAND=(debug, example: mdi-05)
+MDI_COMMAND=(debug, example: mdi-06)
+#07 M101: example print to stdout
+MDI_COMMAND=M101
+MDI_COMMAND=(debug, example: mdi-08)
+MDI_COMMAND=(debug, example: mdi-09)
+MDI_COMMAND=(debug, example: mdi-10)
+MDI_COMMAND=(debug, example: mdi-11)
+MDI_COMMAND=(debug, example: mdi-12)
+MDI_COMMAND=(debug, example: mdi-13)
+MDI_COMMAND=(debug, example: mdi-14)
+MDI_COMMAND=(debug, example: mdi-15)
+
+[EMC]
+MACHINE = xhc-hb04 layout2 demo
+DEBUG = 0
+
+[DISPLAY]
+DISPLAY = axis
+CYCLE_TIME = 0.100
+POSITION_OFFSET = RELATIVE
+POSITION_FEEDBACK = ACTUAL
+MAX_FEED_OVERRIDE = 1.2
+MAX_SPINDLE_OVERRIDE = 1.0
+PROGRAM_PREFIX = ../../nc_files/
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+EDITOR = gedit
+GEOMETRY = XYZABCUVW
+INCREMENTS = 1 mm, .01 in, .1mm, 1 mil, .1 mil, 1/8000 in
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python
+
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+[RS274NGC]
+PARAMETER_FILE = sim-9axis.var
+SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+# for demo of M110:
+USER_M_PATH = ../../nc_files/ngcgui_lib/mfiles
+
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+COMM_WAIT = 0.010
+SERVO_PERIOD = 1000000
+
+[HAL]
+HALFILE = core_sim9.hal
+HALFILE = sim_spindle_encoder.hal
+HALFILE = axis_manualtoolchange.hal
+HALFILE = simulated_home.hal
+HALFILE = xhc-hb04.tcl
+HALUI = halui
+
+[TRAJ]
+NO_FORCE_HOMING = 1
+AXES = 9
+COORDINATES = X Y Z A B C U V W
+HOME = 0 0 0 0 0 0 0 0 0
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+CYCLE_TIME = 0.010
+DEFAULT_VELOCITY = 1.0
+DEFAULT_ANGULAR_VELOCITY = 45.0
+POSITION_FILE = position9.txt
+MAX_LINEAR_VELOCITY = 1.2
+MAX_ANGULAR_VELOCITY = 90.0
+
+[AXIS_0]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+[AXIS_1]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_2]
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -2.0
+MAX_LIMIT = 4.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME_SEARCH_VEL = 5.0
+HOME_LATCH_VEL = 1.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+[AXIS_3]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_4]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 45.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_5]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+[AXIS_6]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[AXIS_7]
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -10.0
+MAX_LIMIT = 10.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[AXIS_8]
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 1.2
+MAX_ACCELERATION = 20.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -2.0
+MAX_LIMIT = 4.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 0
+
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+TOOL_TABLE = sim.tbl
+TOOL_CHANGE_POSITION = 0 0 2
+
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt
new file mode 100644
index 000000000..8aba3bad8
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2.txt
@@ -0,0 +1,35 @@
+xhc-hb04-layout2
+
+18 buttons:
+
+---------------------------------------
+|RESET |Stop | |
+---------------------------------------
+|GotoZero|Start/Pause|Rewind |Probe-Z |
+---------------------------------------
+|Spindle | =1/2 | =0 |Safe-Z |
+---------------------------------------
+|GotoHome|Macro-1 |Macro-2|Macro-3 |
+---------------------------------------
+|STEP |Mode |Macro-6|Macro-7 |
+---------------------------------------
+| Off |
+| X |
+| Y |
+| Rotary -------> Z |
+| Switch A |
+| Spindle |
+| Feed |
+---------------------------------------
+
+Button codes defined in xhc-hb04-layout2.cfg
+
+The STEP button is used to change the wheel multiplier and can also be connected to a pin.
+
+The Start/Pause button is reserved to control halui.program.run,pause,resume.
+
+The other buttons can be connected to hal pins -- typically halui provided pins. MDI commands can be executed using halui.mdi-command-nn pins defined in the ini file with [HALUI]MDI_COMMAND= entries.
+
+The rotary switch selects the axis, spindle, or feedoverride for control by the jogwheel.
+
+The switch positions (xyza) can be defined to any available axis (xyzc for instance).
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04.tcl b/configs/sim/axis/xhc-hb04/xhc-hb04.tcl
new file mode 100644
index 000000000..3685047aa
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04.tcl
@@ -0,0 +1,295 @@
+# xhc-hb04.tcl: HALFILE for xhc-hb04 pendant
+
+# Usage:
+# In ini file, include:
+# [HAL]
+# HALFILE = existing halfiles
+# ...
+# HALFILE = xhc-hb04.tcl
+#
+# [XHC-HB04_CONFIG]
+# layout = 2 (required: 1|2 are supported)
+# coords = x y z a (any unique four of xyzabcuvw)
+# coefs = 1 1 1 1 (optional, filter coefs, 0 < coef < 1, not usually reqd)
+# scales = 1 1 1 1 (optional)
+
+# [XHC-HB04_BUTTONS]
+# name = pin (connect button to hal pin)
+# name = "" (no connect button)
+# (see ini files for more exanples)
+
+# Notes:
+# 1) presumes an existing thread named servo-thread
+# 2) the 'start-pause' pin is RESERVED since it is connected herein
+# 3) the 'step' pin is used by xhc-hb04.cc to manage the jogwheel
+# step sizes so use caution in connecting it for other purposes
+# 2) non-root access to the usb device requires an additional
+# udev rule. Typically, create /etc/udev/rules.d/90-xhc.rules:
+# SYSFS{idProduct}=="eb70", SYSFS{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+# or (for ubuntu12 and up):
+# ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+
+#-----------------------------------------------------------------------
+# Copyright: 2014
+# Author: Dewey Garrett <dgarrett@panix.com>
+#
+# 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
+#-----------------------------------------------------------------------
+
+proc is_uniq {list_name} { ;# make list unique
+ set tmp(xxxxxxxx) "" ;# make an array first
+ foreach item $list_name {
+ if {[array names tmp $item] == $item} {
+ return 0 ;# not unique
+ }
+ set tmp($item) $item
+ }
+ return 1 ;# unique
+} ;# is_uniq
+
+proc pin_exists {name} {
+ set line [lindex [split [show pin $name] \n] 2]
+ if {"$line" == ""} {
+ return 0 ;# fail
+ }
+ if [catch {scan $line "%d %s %s %s%s" owner type dir value pinname} msg] {
+ return 0 ;# fail
+ } else {
+ #puts stderr "OK:$owner $type $dir $value $pinname"
+ return 1 ;# ok
+ }
+} ;# pin_exists
+
+proc connect_pins {} {
+ foreach bname [lsort [array names ::XHC_HB04_BUTTONS]] {
+ set thepin $::XHC_HB04_BUTTONS($bname)
+ set thepin [lindex $thepin 0]
+
+ if {"$thepin" == "\"\""} {
+ #puts stderr "$::progname: no pin defined for <$bname>"
+ continue
+ }
+ # this pin is reserved for use with xhc-hb04-util
+ if {[string tolower $bname] == "start-pause"} {
+ puts stderr "$::progname: skipping button start-pause <$thepin>"
+ puts stderr "$::progname: the start-pause pin usage is builtin"
+ continue
+ }
+ # these are used in the ini file examples but aren't real pins
+ if { [string tolower "$thepin"] == "reserved"
+ || [string tolower "$thepin"] == "caution"
+ } {
+ puts stderr "$::progname: skipping button $bname marked <$thepin>"
+ continue
+ }
+ set fullbname xhc-hb04.button-$bname
+ if ![pin_exists $fullbname] {
+ puts stderr "$::progname: !!! <$fullbname> pin does not exist, continuing"
+ continue
+ }
+ if ![pin_exists $thepin] {
+ puts stderr "$::progname: !!! <$thepin> target pin does not exist, continuing"
+ continue
+ }
+
+ net pendant:$bname $fullbname => $thepin
+ }
+} ;# connect_pins
+
+proc wheel_setup {} {
+ # defaults if not in inifile:
+ set ::XHC_HB04_CONFIG(coef,0) 1.0
+ set ::XHC_HB04_CONFIG(coef,1) 1.0
+ set ::XHC_HB04_CONFIG(coef,2) 1.0
+ set ::XHC_HB04_CONFIG(coef,3) 1.0
+ if [info exists ::XHC_HB04_CONFIG(coefs)] {
+ set ::XHC_HB04_CONFIG(coefs) [string trim $::XHC_HB04_CONFIG(coefs) "{}"]
+ set idx 0
+ foreach g $::XHC_HB04_CONFIG(coefs) {
+ set g1 $g
+ if {$g < 0} {
+ set g [expr -1 * $g]
+ puts stderr "$::progname: coef #$idx must be positive was:$g1, is:$g"
+ }
+ if {$g > 1} {
+ set g .5
+ puts stderr "$::progname: coef #$idx must < 1 coef was:$g1, is:$g"
+ }
+ set ::XHC_HB04_CONFIG(coef,$idx) $g
+ incr idx
+ }
+ }
+ # defaults if not in inifile:
+ set ::XHC_HB04_CONFIG(scale,0) 1.0
+ set ::XHC_HB04_CONFIG(scale,1) 1.0
+ set ::XHC_HB04_CONFIG(scale,2) 1.0
+ set ::XHC_HB04_CONFIG(scale,3) 1.0
+ if [info exists ::XHC_HB04_CONFIG(scales)] {
+ set ::XHC_HB04_CONFIG(scales) [string trim $::XHC_HB04_CONFIG(scales) "{}"]
+ set idx 0
+ foreach g $::XHC_HB04_CONFIG(scales) {
+ set ::XHC_HB04_CONFIG(scale,$idx) $g
+ incr idx
+ }
+ }
+
+ net pendant:jog-scale <= xhc-hb04.jog.scale
+ net pendant:jog-counts <= xhc-hb04.jog.counts
+ net pendant:jog-counts-neg <= xhc-hb04.jog.counts-neg
+
+ set anames {x y z a}
+ # xhc-hb04.cc hardcodes pin names as: x y z a
+ # herein: Use names in order of the [XHC_HB04_CONFIG]coords
+ # specification in the inifile.
+ # These pin names will be a little confusing when
+ # using alternate axis sequences but the signal
+ # names will align correctly.
+ # With this method, any coord (xyzabcuvw) can be
+ # controlled by the wheel (providing it exists)
+ #
+ set idx 0
+ foreach coord $::XHC_HB04_CONFIG(coords) {
+ set coord [string trim [string tolower $coord] -] ;# strip -
+ set axno $::XHC_HB04_CONFIG($coord,axno)
+
+ setp pendant_util.coef$idx $::XHC_HB04_CONFIG(coef,$idx)
+ setp pendant_util.scale$idx $::XHC_HB04_CONFIG(scale,$idx)
+
+ set acoord [lindex $anames $idx]
+ net pendant:pos-$coord halui.axis.$axno.pos-feedback \
+ => xhc-hb04.$acoord.pos-absolute
+ net pendant:pos-rel-$coord halui.axis.$axno.pos-relative \
+ => xhc-hb04.$acoord.pos-relative
+
+ net pendant:jog-$coord xhc-hb04.jog.enable-$acoord \
+ => axis.$axno.jog-enable
+ net pendant:jog-scale => axis.$axno.jog-scale
+
+ net pendant:jog-counts => pendant_util.in$idx
+ net pendant:jog-counts-$coord-filtered <= pendant_util.out$idx \
+ => axis.$axno.jog-counts
+ incr idx
+ }
+
+ setp halui.feed-override.scale 0.01
+ net pendant:jog-counts => halui.feed-override.counts
+
+ setp halui.spindle-override.scale 0.01
+ net pendant:jog-counts => halui.spindle-override.counts
+
+ net pendant:jog-speed halui.jog-speed <= halui.max-velocity.value
+
+ net pendant:jog-feed halui.feed-override.count-enable \
+ <= xhc-hb04.jog.enable-feed-override
+ net pendant:jog-feed2 halui.feed-override.value \
+ => xhc-hb04.feed-override
+
+ net pendant:jog-spindle halui.spindle-override.count-enable
+ net pendant:jog-spindle <= xhc-hb04.jog.enable-spindle-override
+ net pendant:jog-spindle2 halui.spindle-override.value \
+ => xhc-hb04.spindle-override
+ net pendant:spindle-rps motion.spindle-speed-cmd-rps \
+ => xhc-hb04.spindle-rps
+} ;# wheel_setup
+
+proc start_pause_button {} {
+ # hardcoded setup for button-start-pause
+ loadrt xhc_hb04_util names=pendant_util
+ addf pendant_util servo-thread ;# hardcoded thread name
+ net pendant:start-or-pause <= xhc-hb04.button-start-pause \
+ => pendant_util.start-or-pause
+
+ net pendant:is-idle <= halui.program.is-idle \
+ => pendant_util.is-idle
+ net pendant:is-paused <= halui.program.is-paused \
+ => pendant_util.is-paused
+ net pendant:is-running <= halui.program.is-running \
+ => pendant_util.is-running
+
+ net pendant:program-resume pendant_util.resume => halui.program.resume
+ net pendant:program-pause pendant_util.pause => halui.program.pause
+ net pendant:program-run pendant_util.run => halui.program.run
+} ;# start_pause_button
+
+proc popup_msg {msg} {
+ puts stderr "$msg"
+ if [catch {package require Tk
+ wm withdraw .
+ tk_messageBox \
+ -title "$::progname: loadusr fail" \
+ -type ok \
+ -message "$msg"
+ destroy .
+ } msg] {
+ puts stderr "$msg"
+ }
+} ;# popup_msg
+
+proc err_exit {msg} {
+ puts stderr "\n$::progname: $msg\n"
+ exit 1
+} ;# err_exit
+
+# begin------------------------------------------------------------------------
+set ::progname "xhc-hb04.tcl"
+set cfg xhc-hb04-layout2.cfg ;# default
+
+if [info exists ::XHC_HB04_CONFIG(layout)] {
+ switch ${::XHC_HB04_CONFIG(layout)} {
+ 1 {set cfg xhc-hb04-layout1.cfg}
+ 2 {set cfg xhc-hb04-layout2.cfg}
+ default {
+ set msg "Unknown layout:<$::XHC_HB04_CONFIG(layout)>"
+ set msg "$msg\ntrying: $cfg"
+ popup_msg "$msg"
+ # keep going
+ }
+ }
+}
+
+if ![file exists $cfg] {
+ set msg "Cannot find file: <$cfg>\nCannot configure pendant\n"
+ set msg "$msg\nContinuing without xhc-hb04"
+ popup_msg "$msg"
+ return ;# not an exit
+}
+
+if [catch {loadusr -W xhc-hb04 -I $cfg -H} msg] {
+ set msg "\n$::progname: loadusr xhc-hb04:\n<$msg>\n\n"
+ set msg "$msg Is it plugged in?\n\n"
+ set msg "$msg Are permissions correct?\n\n"
+ set msg "$msg Continuing without xhc-hb04\n"
+ popup_msg "$msg"
+ return ;# not an exit
+}
+
+set ct 0; foreach coord {x y z a b c u v w} {
+ set ::XHC_HB04_CONFIG($coord,axno) $ct; incr ct
+}
+
+if [info exists ::XHC_HB04_CONFIG(coords)] {
+ set ::XHC_HB04_CONFIG(coords) [string trim $::XHC_HB04_CONFIG(coords) "{}"]
+ if ![is_uniq $::XHC_HB04_CONFIG(coords)] {
+ err_exit "coords must be unique, not: <$::XHC_HB04_CONFIG(coords)>"
+ }
+} else {
+ set ::XHC_HB04_CONFIG(coords) {x y z a} ;# default
+}
+
+start_pause_button ;# special handling for this button
+connect_pins ;# per ini file items: [XHC_HB04_BUTTONS]buttonname=pin
+wheel_setup ;# jog wheel per ini file items:
+ # [XHC_HB04_CONFIG]coords,coefs,scales
+#parray ::XHC_HB04_CONFIG
diff --git a/src/hal/components/xhc_hb04_util.comp b/src/hal/components/xhc_hb04_util.comp
new file mode 100644
index 000000000..8f749beb4
--- /dev/null
+++ b/src/hal/components/xhc_hb04_util.comp
@@ -0,0 +1,71 @@
+component xhc_hb04_util "xhc-hb04 convenience utility";
+description """Provides logic for a start/pause button and an interface
+to halui.program.is_paused,is_idle,is_running to generate outputs for
+halui.program.pause,resume,run.
+
+Includes 4 simple lowpass filters with coef and scale pins. The coef value should
+be 0 <= coef <=1, smaller coef values slow response. Note: the xhc_hb04
+component includes smoothing so these values can usually be left at 1.0
+""";
+
+pin in bit start_or_pause;
+pin in bit is_paused;
+pin in bit is_idle;
+pin in bit is_running;
+pin out bit pause;
+pin out bit resume;
+pin out bit run;
+
+// integer low pass filters (see ilowpass.comp)
+pin in s32 in0;
+pin in s32 in1;
+pin in s32 in2;
+pin in s32 in3;
+pin out s32 out0;
+pin out s32 out1;
+pin out s32 out2;
+pin out s32 out3;
+pin in float scale0 = 1.0;
+pin in float scale1 = 1.0;
+pin in float scale2 = 1.0;
+pin in float scale3 = 1.0;
+pin in float coef0 = 1.0;
+pin in float coef1 = 1.0;
+pin in float coef2 = 1.0;
+pin in float coef3 = 1.0;
+
+option data xhc_data;
+
+variable double value0;
+variable double value1;
+variable double value2;
+variable double value3;
+
+function _;
+license "GPL";
+;;
+
+typedef struct { int old_start_or_pause; } xhc_data;
+
+FUNCTION(_) {
+ // protect so that 0 <= coef <= 1
+ value0 += (in0 - value0) * (fabs(coef0) < 1 ? fabs(coef0) : 1);
+ value1 += (in1 - value1) * (fabs(coef1) < 1 ? fabs(coef1) : 1);
+ value2 += (in2 - value2) * (fabs(coef2) < 1 ? fabs(coef2) : 1);
+ value3 += (in3 - value3) * (fabs(coef3) < 1 ? fabs(coef3) : 1);
+
+ out0 = ceil(value0 - .5) * scale0;
+ out1 = ceil(value1 - .5) * scale1;
+ out2 = ceil(value2 - .5) * scale2;
+ out3 = ceil(value3 - .5) * scale3;
+
+ if (data.old_start_or_pause == start_or_pause) return;
+ data.old_start_or_pause = start_or_pause;
+ if (!start_or_pause) {
+ pause = run = resume = 0;
+ return;
+ }
+ if (is_paused) {pause = 0; run = 0; resume = 1; }
+ if (is_running) {pause = 1; run = 0; resume = 0; }
+ if (is_idle) {pause = 0; run = 1; resume = 0; }
+}