├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── TODO ├── configure.mk ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── rules └── source │ └── format ├── examples ├── Makefile ├── fsoe │ ├── TwinSAFE-Project.xml │ ├── TwinSAFE.tsm │ └── ethercat-conf.xml ├── generic-complex │ ├── CPD17 │ │ ├── cpd17_x.hal │ │ ├── cpd17_x.ini │ │ └── ethercat-conf_X.xml │ ├── README │ └── ethercat-conf.xml ├── initcmds │ ├── AM8121-xFx0-000x_MDP.xml │ ├── AX5206-AM8032-async.xml │ └── ethercat-conf.xml ├── omrg5 │ └── omrg5.xml └── swm-fm45a │ ├── ethercat-conf.xml │ ├── swm-fm45a-axis.hal │ ├── swm-fm45a-io.hal │ ├── swm-fm45a-spindle.hal │ ├── swm-fm45a.hal │ ├── swm-fm45a.ini │ └── tool.tbl ├── patches ├── add-task-pll-functions-2.7.patch └── add-task-pll-functions-2.8.patch └── src ├── Kbuild ├── Makefile ├── lcec.h ├── lcec_ax5100.c ├── lcec_ax5100.h ├── lcec_ax5200.c ├── lcec_ax5200.h ├── lcec_ax5805.c ├── lcec_ax5805.h ├── lcec_class_ax5.c ├── lcec_class_ax5.h ├── lcec_class_enc.c ├── lcec_class_enc.h ├── lcec_conf.c ├── lcec_conf.h ├── lcec_conf_icmds.c ├── lcec_conf_priv.h ├── lcec_conf_util.c ├── lcec_deasda.c ├── lcec_deasda.h ├── lcec_dems300.c ├── lcec_dems300.h ├── lcec_ek1100.h ├── lcec_el1252.c ├── lcec_el1252.h ├── lcec_el1859.c ├── lcec_el1859.h ├── lcec_el1904.c ├── lcec_el1904.h ├── lcec_el1918_logic.c ├── lcec_el1918_logic.h ├── lcec_el1xxx.c ├── lcec_el1xxx.h ├── lcec_el2202.c ├── lcec_el2202.h ├── lcec_el2521.c ├── lcec_el2521.h ├── lcec_el2904.c ├── lcec_el2904.h ├── lcec_el2xxx.c ├── lcec_el2xxx.h ├── lcec_el31x2.c ├── lcec_el31x2.h ├── lcec_el31x4.c ├── lcec_el31x4.h ├── lcec_el3255.c ├── lcec_el3255.h ├── lcec_el32x4.c ├── lcec_el32x4.h ├── lcec_el40x1.c ├── lcec_el40x1.h ├── lcec_el40x2.c ├── lcec_el40x2.h ├── lcec_el40x8.c ├── lcec_el40x8.h ├── lcec_el41x2.c ├── lcec_el41x2.h ├── lcec_el41x4.c ├── lcec_el41x4.h ├── lcec_el5002.c ├── lcec_el5002.h ├── lcec_el5021.c ├── lcec_el5021.h ├── lcec_el5032.c ├── lcec_el5032.h ├── lcec_el5101.c ├── lcec_el5101.h ├── lcec_el5122.c ├── lcec_el5122.h ├── lcec_el5151.c ├── lcec_el5151.h ├── lcec_el5152.c ├── lcec_el5152.h ├── lcec_el6900.c ├── lcec_el6900.h ├── lcec_el7041_1000.c ├── lcec_el7041_1000.h ├── lcec_el70x1.c ├── lcec_el70x1.h ├── lcec_el7211.c ├── lcec_el7211.h ├── lcec_el7342.c ├── lcec_el7342.h ├── lcec_el7411.c ├── lcec_el7411.h ├── lcec_el95xx.c ├── lcec_el95xx.h ├── lcec_em7004.c ├── lcec_em7004.h ├── lcec_generic.c ├── lcec_generic.h ├── lcec_main.c ├── lcec_omrg5.c ├── lcec_omrg5.h ├── lcec_ph3lm2rm.c ├── lcec_ph3lm2rm.h ├── lcec_rtapi.h ├── lcec_rtapi_kmod.h ├── lcec_rtapi_user.h ├── lcec_stmds5k.c ├── lcec_stmds5k.h ├── realtime.mk └── user.mk /.gitignore: -------------------------------------------------------------------------------- 1 | # generc file-types 2 | **.ko 3 | **.so 4 | **.ko.cmd 5 | **.mod.c 6 | **.o 7 | **.o.cmd 8 | **.swp 9 | **.sym 10 | **.ver 11 | **.tmp 12 | 13 | # generic files 14 | **/.tmp_versions/ 15 | **/modules.order 16 | config.mk 17 | src/lcec_conf 18 | src/Module.symvers 19 | 20 | # debian pkgbuild files 21 | debian/.debhelper/ 22 | debian/files 23 | debian/*.log 24 | debian/*.substvars 25 | debian/linuxcnc-ethercat/ 26 | debian/debhelper-build-stamp 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all configure install clean 2 | 3 | all: configure 4 | @$(MAKE) -C src all 5 | 6 | clean: 7 | @$(MAKE) -C src clean 8 | rm -f config.mk config.mk.tmp 9 | 10 | install: configure 11 | @$(MAKE) -C src install 12 | @$(MAKE) -C examples install-examples 13 | 14 | configure: config.mk 15 | 16 | config.mk: configure.mk 17 | @$(MAKE) -s -f configure.mk > config.mk.tmp 18 | @mv config.mk.tmp config.mk 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # linuxcnc-ethercat 2 | LinuxCNC EtherCAT HAL driver 3 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - (Re-)testing/Documentation of all devices 2 | - option --enable-ethercat for configure script 3 | - DOC: don't use EL9010 4 | - Debug EL5151/EL5152/EL2521 Subindex does not exist 5 | - DOC: Parameter A60/A61 Stoeber 6 | -------------------------------------------------------------------------------- /configure.mk: -------------------------------------------------------------------------------- 1 | ifeq (, $(COMP)) 2 | COMP = $(shell which halcompile) 3 | endif 4 | ifeq (, $(COMP)) 5 | COMP = $(shell which comp) 6 | endif 7 | ifeq (, $(COMP)) 8 | $(error halcompile/comp executable not found or set) 9 | endif 10 | 11 | .PHONY: configure 12 | configure: 13 | @echo "COMP = $(COMP)" 14 | @echo "MODINC = $(MODINC)" 15 | @echo "BUILDSYS = $(BUILDSYS)" 16 | @echo "KERNELDIR = $(KERNELDIR)" 17 | @echo "CC = $(CC)" 18 | @echo "RTAI = $(RTAI)" 19 | @echo "RTFLAGS = $(RTFLAGS)" 20 | @echo "KERNELRELEASE = $(KERNELRELEASE)" 21 | @echo "EXTRA_CFLAGS = $(EXTRA_CFLAGS)" 22 | @echo "USE_RTLIBM = $(USE_RTLIBM)" 23 | @echo "EMC2_HOME = $(EMC2_HOME)" 24 | @echo "RUN_IN_PLACE = $(RUN_IN_PLACE)" 25 | @echo "RTLIBDIR = $(RTLIBDIR)" 26 | @echo "LIBDIR = $(LIBDIR)" 27 | @echo "prefix = $(prefix)" 28 | @echo "MODINC_HAS_EXTRA_LDFLAGS = $(MODINC_HAS_EXTRA_LDFLAGS)" 29 | 30 | # include modinc 31 | MODINC=$(shell $(COMP) --print-modinc) 32 | ifeq (, $(MODINC)) 33 | $(error Unable to get modinc path) 34 | endif 35 | 36 | MODINC_HAS_EXTRA_LDFLAGS = $(shell fgrep -q EXTRA_LDFLAGS $(MODINC) && echo 'y') 37 | 38 | include $(MODINC) 39 | 40 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | linuxcnc-ethercat (0.9.4) unstable; urgency=low 2 | 3 | * added EL7211 debug pins 4 | * route digital input to HAL for EL7201-9014 5 | * added ramp function with at-speed pin to el7211/el7411 for use as spindle 6 | * Add support for all Omron G5 drives 7 | * added EP2809, EP2008, EK1120 8 | * added EL7411 (HALL velocity mode) 9 | * added EL7201-9014 10 | * added EL7031 and EL7041_0052 support 11 | * added EL1859 12 | * added EL2634 13 | * added EL3164 14 | * added EL1819 15 | * add SK1110 support 16 | * add linuxcnc 2.8 support 17 | * add 3lm2rm support 18 | * add el4134 support 19 | * moved from PI to BANG-BANG controller for task PLL. 20 | * add EL7221 support 21 | * added EL40x8 support 22 | * add support for EL2612 23 | * fixed fsoe command read data type 24 | * allow IP trsition on SDO initialization 25 | * added external encoder supoort for MDS5000 26 | * support for complete write on SDO init commads 27 | * added support for ax5203 28 | * add fsoe support 29 | * fixed a problem that could not read an unordered property 30 | * fix segfault during `lcec_update_slave_state_hal()` on Machinekit HAL 31 | * fixed el2521 sdo 8000:07 read size 32 | 33 | -- Sascha Ittner Wed, 21 Jul 2021 11:47:50 +0200 34 | 35 | linuxcnc-ethercat (0.9.3) unstable; urgency=low 36 | 37 | * NEW: support to sync master's task to the EC refclock (sittner) 38 | enabled via refSyncCycle="1", needs supplied patch against linuxcnc 39 | * NEW: support for EL2798 (frankbrossette) 40 | * NEW: support for EL41x4 (frankbrossette) 41 | * NEW: support for EL3255 5 Ch Potentiometer input device (sittner) 42 | * NEW: support EP2028 (sittner) 43 | * NEW: support for EL7211 (sittner) 44 | * NEW: support for AX5206 (sittner) 45 | * NEW: added SoE setup function for ethercat-config.xml (sittner) 46 | * NEW: added support to include external CoE/SoE init commands for ethercat-config.xml (sittner) 47 | * NEW: new module specific parameter support (narogon, sittner) 48 | * NEW: stmds5k, deasda, ax5206 and el7211 uses same encoder class for position feedback (sittner) 49 | ATTENTION: this may need some changes to existing configs, as some pins have changed 50 | * FIX: Fixed conceptual bug in intermediate config buffer handling (sittner) 51 | * FIX: sync refclock to masterclock now respects local jitter (sittner) 52 | * FIX: use master's synchronous ecrt_master_sdo_upload to read SDOs on init (sittner) 53 | * FIX: build script uses Makefile.modinc (sirop, sittner) 54 | * DEPRECATE: RTAI is not tested anymore (sittner) 55 | * CLEANUP: reworked pin export method (sittner) 56 | * CLEANUP: introduced function class concept (sittner) 57 | 58 | -- Sascha Ittner Fri, 23 Mar 2018 14:38:41 +0200 59 | 60 | linuxcnc-ethercat (0.9.2) unstable; urgency=low 61 | 62 | * added autoreset fault retry option for delta asda driver (sittner) 63 | * add driver support for EL2622 (koppi) 64 | * EL7342: fix counter underflow, counter overflow PDOs (koppi) 65 | * add device driver for EL7041-1000 (koppi) 66 | * fixed scale/offset config parsing (sittner) 67 | * GENERIC: support for complex pins (frankbrossette, sittner) 68 | * support for EL2202 and EL1252 added (claudiolorini) 69 | 70 | -- Sascha Ittner Sun, 04 Oct 2015 21:51:14 +0200 71 | 72 | linuxcnc-ethercat (0.9.1) unstable; urgency=low 73 | 74 | * Stoeber MDS5000 tourque calculation fixed 75 | * Support for simulation mode 76 | * Rework of build system 77 | 78 | -- Sascha Ittner Wed, 11 Mar 2015 00:00:00 +0100 79 | 80 | linuxcnc-ethercat (0.9.0-2) unstable; urgency=low 81 | 82 | * added example files 83 | 84 | -- Sascha Ittner Tue, 28 Jan 2015 16:26:32 +0100 85 | 86 | linuxcnc-ethercat (0.9.0-1) unstable; urgency=low 87 | 88 | * Initial release 89 | 90 | -- Sascha Ittner Mon, 12 Jan 2015 10:19:04 +0100 91 | 92 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: linuxcnc-ethercat 2 | Section: unknown 3 | Priority: extra 4 | Maintainer: Sascha Ittner 5 | Build-Depends: debhelper (>= 8.0.0), libexpat1-dev, linuxcnc-dev | linuxcnc-sim-dev | linuxcnc-uspace-dev | machinekit-dev, etherlabmaster-dev 6 | Standards-Version: 3.9.3 7 | 8 | Package: linuxcnc-ethercat 9 | Architecture: any 10 | Depends: ${shlibs:Depends}, ${misc:Depends}, linuxcnc | linuxcnc-sim | linuxcnc-uspace | machinekit, etherlabmaster 11 | Description: LinuxCNC EtherCAT HAL driver 12 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: linuxcnc-ethercat 3 | Source: 4 | 5 | Files: * 6 | Copyright: 2015 Sascha Ittner 7 | License: GPL-2.0+ 8 | 9 | Files: debian/* 10 | Copyright: 2015 Sascha Ittner 11 | License: GPL-2.0+ 12 | 13 | License: GPL-2.0+ 14 | This package is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation; either version 2 of the License, or 17 | (at your option) any later version. 18 | . 19 | This package is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | . 24 | You should have received a copy of the GNU General Public License 25 | along with this program. If not, see 26 | . 27 | On Debian systems, the complete text of the GNU General 28 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 29 | 30 | # Please also look if there are files or directories which have a 31 | # different copyright/license attached and list them here. 32 | # Please avoid to pick license terms that are more restrictive than the 33 | # packaged work, as it may make Debian's contributions unacceptable upstream. 34 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | TODO 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | SUBDIRS = generic-complex swm-fm45a 4 | 5 | install-examples: 6 | mkdir -p $(DESTDIR)$(EMC2_HOME)/share/linuxcnc-ethercat/examples 7 | cp -R $(SUBDIRS) $(DESTDIR)$(EMC2_HOME)/share/linuxcnc-ethercat/examples 8 | 9 | -------------------------------------------------------------------------------- /examples/fsoe/TwinSAFE-Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 1204112TwinSAFE Gruppe 11RUN/STOP11ERR Ack21FB ERR31COM ERR41OUT ERR513TwinSAFE VerbindungslisteTwinSAFE Funktion Block Liste2OR (FB 1)4Fehler160OrIn121One channel break10OrIn230One channel break10OrIn341One channel break10OrIn450One channel break10OrIn560One channel break10OrIn670One channel break10OrIn780One channel break10OrIn890One channel break10OrOut201140OR0MAIN.run_stopStandard2Out111MAIN.run_stopMAIN.err_ackStandard2Out012MAIN.err_ackMAIN.fb_errStandard2In013MAIN.fb_errMAIN.com_errStandard2In114MAIN.com_errMAIN.out_errStandard2In215MAIN.out_errKlemme 5 (EL1904).InputChannel1IO connection1In51420Klemme 6 (EL1904).InputChannel1IO connection1In61440Klemme 7 (EL2904).OutputChannel1IO connection1Out714200Klemme 7 (EL2904)7ERR Ack11Master141002378060000000000000002290Klemme 5 (EL1904)5ERR Ack11Master121002158000f00000000000002190Klemme 6 (EL1904)6ERR Ack11Master131002268000f00000000000002190 3 | -------------------------------------------------------------------------------- /examples/fsoe/TwinSAFE.tsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sittner/linuxcnc-ethercat/938387ded92a3c61b2654b7e2f6177909f803f91/examples/fsoe/TwinSAFE.tsm -------------------------------------------------------------------------------- /examples/fsoe/ethercat-conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/generic-complex/CPD17/cpd17_x.hal: -------------------------------------------------------------------------------- 1 | loadusr -W lcec_conf /home/frank/linuxcnc/configs/ethercat/ethercat-conf_X.xml 2 | loadrt lcec 3 | loadrt trivkins 4 | loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES 5 | loadrt not count=1 6 | 7 | #----------------------------------------------------------- 8 | 9 | addf lcec.read-all servo-thread 10 | addf motion-command-handler servo-thread 11 | addf motion-controller servo-thread 12 | addf not.0 servo-thread 13 | addf lcec.write-all servo-thread 14 | 15 | #----------------------------------------------------------- 16 | 17 | net bus_up lcec.state-op => iocontrol.0.emc-enable-in 18 | 19 | net tool-change iocontrol.0.tool-change iocontrol.0.tool-changed 20 | net tool-prepare iocontrol.0.tool-prepare iocontrol.0.tool-prepared 21 | #----------------------------------------------------------- 22 | 23 | net Spindel_enable motion.spindle-on => lcec.0.2.dout-0 24 | net Spindel_dir motion.spindle-reverse => lcec.0.2.dout-1 25 | 26 | # Test Homefahrt 27 | net RefX halui.spindle.is-on => axis.0.home-sw-in 28 | 29 | #----------------------------------------------------------- 30 | 31 | # ChangeSetImmediatly: true -> neuer Zielwert sofort aktivieren 32 | setp lcec.0.3.X-cmd-ChangeSetImmediatly true 33 | 34 | # NewSetpoint in jedem Zyklus ändern 35 | net NewSetpoint not.0.out => not.0.in 36 | 37 | #----------------------------------------------------------- 38 | # X-Achse 39 | #----------------------------------------------------------- 40 | net EnableAmpX axis.0.amp-enable-out => lcec.0.3.X-cmd-SwitchOn 41 | net EnableAmpX lcec.0.3.X-cmd-EnableVoltage 42 | net EnableAmpX lcec.0.3.X-cmd-/QuickStop 43 | net EnableAmpX lcec.0.3.X-cmd-EnableOperation 44 | #----------------------------------------------------------- 45 | # Istposition vom Motor an axis übergeben 46 | net Xachse_fb lcec.0.3.X-Pos => axis.0.motor-pos-fb 47 | #----------------------------------------------------------- 48 | # Sollposition von axis an den Motor übergeben 49 | net Xachse_cmd axis.0.motor-pos-cmd => lcec.0.3.X-TargetPos 50 | #----------------------------------------------------------- 51 | # NewSetpoint an den Motor übergeben 52 | net NewSetpoint => lcec.0.3.X-cmd-NewSetpoint 53 | 54 | #----------------------------------------------------------- 55 | # Y+Z-Achse simulieren 56 | #----------------------------------------------------------- 57 | net Ypos axis.1.motor-pos-cmd => axis.1.motor-pos-fb 58 | net Zpos axis.2.motor-pos-cmd => axis.2.motor-pos-fb 59 | 60 | -------------------------------------------------------------------------------- /examples/generic-complex/CPD17/cpd17_x.ini: -------------------------------------------------------------------------------- 1 | [EMC] 2 | MACHINE = CPD17_X 3 | DEBUG = 1 4 | 5 | [DISPLAY] 6 | DISPLAY = axis 7 | EDITOR = gedit 8 | POSITION_OFFSET = RELATIVE 9 | POSITION_FEEDBACK = ACTUAL 10 | MAX_FEED_OVERRIDE = 5.0 11 | INTRO_GRAPHIC = linuxcnc.gif 12 | INTRO_TIME = 0 13 | PROGRAM_PREFIX = /root/linuxcnc/nc_files 14 | INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm 15 | # EMBED_TAB_NAME = Camera 16 | # EMBED_TAB_COMMAND = camview-emc -w {XID} 17 | 18 | [FILTER] 19 | PROGRAM_EXTENSION = .png,.gif,.jpg Greyscale Depth Image 20 | PROGRAM_EXTENSION = .py Python Script 21 | png = image-to-gcode 22 | gif = image-to-gcode 23 | jpg = image-to-gcode 24 | py = python 25 | 26 | [TASK] 27 | TASK = milltask 28 | CYCLE_TIME = 0.001 29 | # the Python plugins serves interpreter and task 30 | 31 | [PYTHON] 32 | # where to find Python code 33 | # code specific for this configuration 34 | PATH_PREPEND=./python 35 | # generic support code 36 | PATH_APPEND=../../nc_files/remap_lib/python-stdglue 37 | 38 | # import the following Python module 39 | TOPLEVEL=python/toplevel.py 40 | 41 | # the higher the more verbose tracing of the Python plugin 42 | LOG_LEVEL = 0 43 | 44 | [RS274NGC] 45 | PARAMETER_FILE = linuxcnc.var 46 | SUBROUTINE_PATH = nc_subroutines:/home/frank/linuxcnc/configs/ethercat 47 | LOG_LEVEL = 9 48 | 49 | # optional features - a bit mask to selectively turn on experimental/dubious features 50 | # see 51 | # RETAIN_G43 0x00000001 52 | # OWORD_N_ARGS 0x00000002 53 | # INI_VARS 0x00000004 54 | # HAL_PIN_VARS 0x00000008 55 | # NO_DOWNCASE_OWORD 0x00000010 56 | # turn on all optional features 57 | 58 | # turn on all optional features except RETAIN_G43 59 | FEATURES=30 60 | 61 | 62 | ON_ABORT_COMMAND=O call 63 | 64 | # ------ remapping toolchange - related codes ---------------------- 65 | # 66 | # see python/remap.py for the prolog and epilog handlers 67 | 68 | REMAP=M6 modalgroup=6 prolog=change_prolog ngc=wz_rack epilog=change_epilog 69 | 70 | # vor dem Halter oben 71 | [CHANGE_POSITION_1] 72 | X = 20 73 | Y = 650 74 | Z = 80 75 | 76 | # vor dem Halter 77 | [CHANGE_POSITION_2] 78 | X = 20 79 | Y = 650 80 | Z = 40 81 | 82 | # im Halter 83 | [CHANGE_POSITION_3] 84 | X = 20 85 | Y = 680 86 | Z = 40 87 | 88 | # über dem Halter 89 | [CHANGE_POSITION_4] 90 | X = 20 91 | Y = 680 92 | Z = 80 93 | 94 | # Abstand zwischen den Haltern 95 | [TOOL_SLOT_DELTA] 96 | X = 80 97 | Y = 0 98 | Z = 0 99 | 100 | [TIMER] 101 | PRE_LOCK_TIME = 0.5 102 | POST_LOCK_TIME = 0.2 103 | UNLOCK_TIME = 1.0 104 | COVER_OPEN = 1.0 105 | 106 | # motion.digital-out-NN pins 107 | [OUT_PINS] 108 | LOCK = 0 109 | COVER_OPEN = 1 110 | COVER_CLOSE = 2 111 | 112 | # motion.digital-in-NN pins 113 | [IN_PINS] 114 | COVER_OPEN = 0 115 | 116 | [EMCMOT] 117 | EMCMOT = motmod 118 | COMM_TIMEOUT = 1.0 119 | COMM_WAIT = 0.010 120 | BASE_PERIOD = 0 121 | SERVO_PERIOD = 5000000 122 | 123 | [HAL] 124 | HALUI = halui 125 | HALFILE = cpd17_x.hal 126 | 127 | [HALUI] 128 | # HalUI-MDI-Befehle hier einfügen (max. 64) 129 | 130 | [EMCIO] 131 | EMCIO = io 132 | CYCLE_TIME = 0.100 133 | TOOL_TABLE = tool.tbl 134 | 135 | 136 | [TRAJ] 137 | AXES = 3 138 | COORDINATES = X Y Z 139 | LINEAR_UNITS = mm 140 | ANGULAR_UNITS = degree 141 | CYCLE_TIME = 0.01 142 | DEFAULT_VELOCITY = 10.0 143 | MAX_LINEAR_VELOCITY = 20.0 144 | # neuer TP 145 | ARC_BLEND_ENABLE = 1 146 | ARC_BLEND_FALLBACK_ENABLE = 0 147 | ARC_BLEND_OPTIMIZATION_DEPTH = 50 148 | ARC_BLEND_GAP_CYCLES = 4 149 | ARC_BLEND_RAMP_FREQ = 100 150 | 151 | 152 | [AXIS_0] 153 | TYPE = LINEAR 154 | MAX_VELOCITY = 20.0 155 | MAX_ACCELERATION = 6000.0 156 | SCALE = 1 157 | FERROR = 1 158 | MIN_FERROR = 20 159 | MIN_LIMIT = -20 160 | MAX_LIMIT = 700 161 | HOME = 0.0 162 | HOME_VEL = 10.0 163 | HOME_OFFSET = 10.0 164 | HOME_SEARCH_VEL = -1.0 165 | HOME_LATCH_VEL = -0.1 166 | HOME_USE_INDEX = NO 167 | HOME_IGNORE_LIMITS = NO 168 | HOME_SEQUENCE = 0 169 | 170 | 171 | [AXIS_1] 172 | TYPE = LINEAR 173 | MAX_VELOCITY = 33.33333333 174 | MAX_ACCELERATION = 600.0 175 | SCALE = 1 176 | FERROR = 1 177 | MIN_FERROR = 20 178 | MIN_LIMIT = -20 179 | MAX_LIMIT = 700 180 | HOME = 0.0 181 | HOME_VEL = 0.0 182 | HOME_OFFSET = 10.0 183 | HOME_SEARCH_VEL = 0.0 184 | HOME_LATCH_VEL = 0.0 185 | HOME_USE_INDEX = NO 186 | HOME_IGNORE_LIMITS = NO 187 | HOME_SEQUENCE = 1 188 | 189 | [AXIS_2] 190 | TYPE = LINEAR 191 | MAX_VELOCITY = 33.33333333 192 | MAX_ACCELERATION = 600.0 193 | SCALE = 1 194 | FERROR = 1 195 | MIN_FERROR = 200 196 | MIN_LIMIT = -5 197 | MAX_LIMIT = 100 198 | HOME = 0.0 199 | HOME_VEL = 0.0 200 | HOME_OFFSET = 10.0 201 | HOME_SEARCH_VEL = 0.0 202 | HOME_LATCH_VEL = 0.0 203 | HOME_USE_INDEX = NO 204 | HOME_IGNORE_LIMITS = NO 205 | HOME_SEQUENCE = 2 206 | 207 | -------------------------------------------------------------------------------- /examples/generic-complex/README: -------------------------------------------------------------------------------- 1 | Please Note: 2 | 3 | to get the sdoConfig data (which is needed to configure the 4 | EL6751 in this case) is generated by TwinCAT by Beckhoff. 5 | 6 | -------------------------------------------------------------------------------- /examples/initcmds/AM8121-xFx0-000x_MDP.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PS 5 | 6 | 0 7 | 1 8 | 32785 9 | 17 10 | 10270000 11 | 12 | 13 | PS 14 | 15 | 0 16 | 1 17 | 32785 18 | 18 19 | a00f0000 20 | 21 | 22 | PS 23 | 24 | 0 25 | 1 26 | 32785 27 | 45 28 | c800 29 | 30 | 31 | PS 32 | 33 | 0 34 | 1 35 | 32785 36 | 19 37 | 03 38 | 39 | 40 | PS 41 | 42 | 0 43 | 1 44 | 32785 45 | 21 46 | a6ff 47 | 48 | 49 | PS 50 | 51 | 0 52 | 1 53 | 32785 54 | 22 55 | 82000000 56 | 57 | 58 | PS 59 | 60 | 0 61 | 1 62 | 32785 63 | 24 64 | 86000000 65 | 66 | 67 | PS 68 | 69 | 0 70 | 1 71 | 32785 72 | 25 73 | 1e00 74 | 75 | 76 | PS 77 | 78 | 0 79 | 1 80 | 32785 81 | 27 82 | b80b0000 83 | 84 | 85 | PS 86 | 87 | 0 88 | 1 89 | 32784 90 | 19 91 | 6401 92 | 93 | 94 | PS 95 | 96 | 0 97 | 1 98 | 32784 99 | 18 100 | 0500 101 | 102 | 103 | PS 104 | 105 | 0 106 | 1 107 | 32784 108 | 21 109 | 70000000 110 | 111 | 112 | PS 113 | 114 | 0 115 | 1 116 | 32784 117 | 20 118 | 96000000 119 | 120 | 121 | PS 122 | 123 | 0 124 | 1 125 | 32786 126 | 17 127 | 0000 128 | 129 | 130 | PS 131 | 132 | 0 133 | 1 134 | 32786 135 | 18 136 | 0000 137 | 138 | 139 | PS 140 | 141 | 0 142 | 1 143 | 32786 144 | 19 145 | 0000 146 | 147 | 148 | PS 149 | 150 | 0 151 | 1 152 | 32786 153 | 20 154 | 0000 155 | 156 | 157 | PS 158 | 159 | 0 160 | 1 161 | 32784 162 | 51 163 | 0a00 164 | 165 | 166 | PS 167 | 168 | 0 169 | 1 170 | 32784 171 | 25 172 | 80bb0000 173 | 174 | 175 | -------------------------------------------------------------------------------- /examples/initcmds/ethercat-conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/omrg5/omrg5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/swm-fm45a/ethercat-conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/swm-fm45a/swm-fm45a-axis.hal: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # 3 | # Axis Controller HAL file for SWM FM45A DRO Profi 4 | # 5 | # Created 2014/10/21 by Sascha Ittner 6 | # 7 | # Axis interface for Joints 8 | # 9 | # This File contains the Position-Controler for each 10 | # joint plus the interface to the LCNC motion controller. 11 | # The motion controller delivers the position command 12 | # and receives the current position from position 13 | # feedback (motor encoder or external messurement system). 14 | # Position command and feedback even feeds into position 15 | # controller, which generates the velocity command for 16 | # the external motor drivers. 17 | # 18 | # The scale for poosition is mm, for velocity mm/s sould 19 | # be used (Please ensure that SCALE in the corresponding 20 | # [AXIS] section in the ini file is set correctly). 21 | # 22 | # If the external motor driver has has velocity controll 23 | # loop, FF1 sould be set accordingly (1.0 in case of 24 | # a velocity scale in mm/s) 25 | # 26 | # Parameters for the position controller are set in 27 | # the ini file. Please refer to 28 | # http://linuxcnc.org/docs/html/man/man9/pid.9.html 29 | # for the descrpition of the parameters 30 | # 31 | ########################################################### 32 | 33 | ########################################################### 34 | # X axis 35 | ########################################################### 36 | 37 | # position controler 38 | setp x-pid.Pgain [AXIS_0]P 39 | setp x-pid.Igain [AXIS_0]I 40 | setp x-pid.Dgain [AXIS_0]D 41 | setp x-pid.FF0 [AXIS_0]FF0 42 | setp x-pid.FF1 [AXIS_0]FF1 43 | setp x-pid.FF2 [AXIS_0]FF2 44 | setp x-pid.deadband [AXIS_0]DEADBAND 45 | setp x-pid.maxoutput [AXIS_0]MAX_OUTPUT 46 | net x-enable => x-pid.enable 47 | net x-pos-cmd => x-pid.command 48 | net x-pos-fb => x-pid.feedback 49 | net x-vel-cmd <= x-pid.output 50 | 51 | # axis interface 52 | net x-neg-lim-in => axis.0.home-sw-in 53 | net x-enable <= axis.0.amp-enable-out 54 | net x-amp-fault => axis.0.amp-fault-in 55 | net x-pos-cmd <= axis.0.motor-pos-cmd 56 | net x-pos-fb => axis.0.motor-pos-fb 57 | net x-pos-joint <= axis.0.joint-pos-fb 58 | net x-homed <= axis.0.homed 59 | net x-homing <= axis.0.homing 60 | net x-neg-lim-in => axis.0.neg-lim-sw-in 61 | net x-pos-lim-in => axis.0.pos-lim-sw-in 62 | 63 | ########################################################### 64 | # Y axis 65 | ########################################################### 66 | 67 | # position controler 68 | setp y-pid.Pgain [AXIS_1]P 69 | setp y-pid.Igain [AXIS_1]I 70 | setp y-pid.Dgain [AXIS_1]D 71 | setp y-pid.FF0 [AXIS_1]FF0 72 | setp y-pid.FF1 [AXIS_1]FF1 73 | setp y-pid.FF2 [AXIS_1]FF2 74 | setp y-pid.deadband [AXIS_1]DEADBAND 75 | setp y-pid.maxoutput [AXIS_1]MAX_OUTPUT 76 | net y-enable => y-pid.enable 77 | net y-pos-cmd => y-pid.command 78 | net y-pos-fb => y-pid.feedback 79 | net y-vel-cmd <= y-pid.output 80 | 81 | # axis interface 82 | net y-pos-lim-in => axis.1.home-sw-in 83 | net y-enable <= axis.1.amp-enable-out 84 | net y-amp-fault => axis.1.amp-fault-in 85 | net y-pos-cmd <= axis.1.motor-pos-cmd 86 | net y-pos-fb => axis.1.motor-pos-fb 87 | net y-pos-joint <= axis.1.joint-pos-fb 88 | net y-homed <= axis.1.homed 89 | net y-homing <= axis.1.homing 90 | net y-neg-lim-in => axis.1.neg-lim-sw-in 91 | net y-pos-lim-in => axis.1.pos-lim-sw-in 92 | 93 | ########################################################### 94 | # Z axis 95 | ########################################################### 96 | 97 | # position controler 98 | setp z-pid.Pgain [AXIS_2]P 99 | setp z-pid.Igain [AXIS_2]I 100 | setp z-pid.Dgain [AXIS_2]D 101 | setp z-pid.FF0 [AXIS_2]FF0 102 | setp z-pid.FF1 [AXIS_2]FF1 103 | setp z-pid.FF2 [AXIS_2]FF2 104 | setp z-pid.deadband [AXIS_2]DEADBAND 105 | setp z-pid.maxoutput [AXIS_2]MAX_OUTPUT 106 | net z-enable => z-pid.enable 107 | net z-pos-cmd => z-pid.command 108 | net z-pos-fb => z-pid.feedback 109 | net z-vel-cmd <= z-pid.output 110 | 111 | # axis interface 112 | net z-pos-lim-in => axis.2.home-sw-in 113 | net z-enable <= axis.2.amp-enable-out 114 | net z-amp-fault => axis.2.amp-fault-in 115 | net z-pos-cmd <= axis.2.motor-pos-cmd 116 | net z-pos-fb => axis.2.motor-pos-fb 117 | net z-pos-joint <= axis.2.joint-pos-fb 118 | net z-homed <= axis.2.homed 119 | net z-homing <= axis.2.homing 120 | net z-neg-lim-in => axis.2.neg-lim-sw-in 121 | net z-pos-lim-in => axis.2.pos-lim-sw-in 122 | 123 | -------------------------------------------------------------------------------- /examples/swm-fm45a/swm-fm45a-io.hal: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # 3 | # IO HAL file for SWM FM45A DRO Profi 4 | # 5 | # Created 2014/10/21 by Sascha Ittner 6 | # 7 | # This file connects internal LCNC HAL signals with 8 | # external Haldware on the ethercat bus. 9 | # 10 | ########################################################### 11 | 12 | ########################################################### 13 | # Signals for monitorting of the connection state 14 | # and slave state 15 | ########################################################### 16 | net ec-slaves-responding <= lcec.slaves-responding 17 | net ec-link-up <= lcec.link-up 18 | net ec-all-op <= lcec.all-op 19 | 20 | ########################################################### 21 | # digital inputs 22 | ########################################################### 23 | 24 | net voltage-on <= lcec.0.D2.din-0 25 | net x-pos-lim-in <= lcec.0.D2.din-1-not 26 | net x-neg-lim-in <= lcec.0.D2.din-2-not 27 | net y-pos-lim-in <= lcec.0.D2.din-3-not 28 | net y-neg-lim-in <= lcec.0.D2.din-4-not 29 | net z-pos-lim-in <= lcec.0.D2.din-5-not 30 | net z-neg-lim-in <= lcec.0.D2.din-6-not 31 | 32 | ########################################################### 33 | # digital outputs 34 | ########################################################### 35 | 36 | net coolant-on => lcec.0.D6.dout-0 37 | net spindle-cw <= lcec.0.D6.dout-1 38 | net spindle-ccw <= lcec.0.D6.dout-2 39 | net z-brake => lcec.0.D6.dout-6 40 | 41 | ########################################################### 42 | # servo controlers 43 | ########################################################### 44 | 45 | # X axis 46 | # HINT: Please refer to lcec_deasda.h for a complete 47 | # description off all delta driver pins/parameters. 48 | # 49 | # voltage is statically enabled as soon as LCNC is running 50 | setp lcec.0.3A1.srv-enable-volt 1 51 | # set motor position scale (default 1 motor revolution) 52 | setp lcec.0.3A1.srv-pos-scale [AXIS_0]SCALE 53 | setp lcec.0.3A1.srv-extenc-scale [AXIS_0]ENC_SCALE 54 | # switch on if joint is enables 55 | # this signal is used for the fault autoreset feature, too 56 | net x-enable => lcec.0.3A1.srv-switch-on 57 | # enable operation if joint is enabled 58 | # The delta driver internally delay this signal 59 | # till switched-on feedback is set to 1 60 | net x-enable => lcec.0.3A1.srv-enable 61 | # check driver fault status 62 | net x-amp-fault <= lcec.0.3A1.srv-fault 63 | # output velocity command from position control 64 | # the scale of this value respects the setting 65 | # of srv-pos-scale. if scale is set to 1.0 this 66 | # means 1 motor revolution per second. 67 | net x-vel-cmd => lcec.0.3A1.srv-vel-cmd 68 | # motor encoder position is used as joint 69 | # position feedback 70 | net x-pos-fb <= lcec.0.3A1.srv-pos-extenc 71 | 72 | # Y axis 73 | # same logic as X axis 74 | setp lcec.0.3A2.srv-enable-volt 1 75 | setp lcec.0.3A2.srv-pos-scale [AXIS_1]SCALE 76 | setp lcec.0.3A2.srv-extenc-scale [AXIS_1]ENC_SCALE 77 | net y-enable => lcec.0.3A2.srv-switch-on 78 | net y-enable => lcec.0.3A2.srv-enable 79 | net y-amp-fault <= lcec.0.3A2.srv-fault 80 | net y-vel-cmd => lcec.0.3A2.srv-vel-cmd 81 | net y-pos-fb <= lcec.0.3A2.srv-pos-extenc 82 | 83 | # Z axis 84 | # same logic as X axis 85 | setp lcec.0.4A3.srv-enable-volt 1 86 | setp lcec.0.4A3.srv-pos-scale [AXIS_2]SCALE 87 | setp lcec.0.4A3.srv-extenc-scale [AXIS_2]ENC_SCALE 88 | net z-enable => lcec.0.4A3.srv-switch-on 89 | net z-enable => lcec.0.4A3.srv-enable 90 | net z-amp-fault <= lcec.0.4A3.srv-fault 91 | net z-vel-cmd => lcec.0.4A3.srv-vel-cmd 92 | net z-pos-fb <= lcec.0.4A3.srv-pos-extenc 93 | net z-brake <= lcec.0.4A3.srv-oper-enabled 94 | 95 | -------------------------------------------------------------------------------- /examples/swm-fm45a/swm-fm45a-spindle.hal: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # 3 | # Spindle HAL file for SWM FM45A DRO Profi 4 | # 5 | # Created 2014/10/21 by Sascha Ittner 6 | # 7 | # Spindle Interface 8 | # 9 | ########################################################### 10 | 11 | ########################################################### 12 | # motion interface 13 | ########################################################### 14 | 15 | net spindle-on <= motion.spindle-on 16 | net spindle-cw <= motion.spindle-forward 17 | net spindle-ccw <= motion.spindle-reverse 18 | 19 | # coolant 20 | net coolant-on <= iocontrol.0.coolant-flood 21 | 22 | -------------------------------------------------------------------------------- /examples/swm-fm45a/swm-fm45a.hal: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # 3 | # Master HAL file for SWM FM45A DRO Profi 4 | # 5 | # Created 2014/10/21 by Sascha Ittner 6 | # 7 | # Global HAL configuration file 8 | # 9 | ########################################################### 10 | 11 | ########################################################### 12 | # Setup 13 | ########################################################### 14 | 15 | # load kinematiks and motion controller (realtime) 16 | loadrt trivkins 17 | loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES 18 | 19 | # load ethercat config parser 20 | loadusr -W lcec_conf ethercat-conf.xml 21 | # load ethercat realtime module 22 | loadrt lcec 23 | 24 | # load position controller PID instances 25 | loadrt pid names=x-pid,y-pid,z-pid 26 | 27 | ########################################################### 28 | # Functions 29 | # 30 | # specify the thead and the order where component functions 31 | # will be called. Since we need no high speed pulse generation 32 | # like soft pwm and stepper generator, only the servo thread 33 | # is used (wich allows floating point calculations and runs 34 | # at 1ms cycle time per default). Functions be called in the 35 | # order of definition. 36 | # 37 | # Base thread could be used in simple systems for high speed 38 | # tasks like mentioned above. Base thread only supports 39 | # integer arithmetics. 40 | # 41 | ########################################################### 42 | 43 | addf lcec.read-all servo-thread 44 | 45 | addf motion-command-handler servo-thread 46 | addf motion-controller servo-thread 47 | 48 | addf x-pid.do-pid-calcs servo-thread 49 | addf y-pid.do-pid-calcs servo-thread 50 | addf z-pid.do-pid-calcs servo-thread 51 | 52 | addf lcec.write-all servo-thread 53 | 54 | ########################################################### 55 | # E-Stop 56 | ########################################################### 57 | 58 | net voltage-on => iocontrol.0.emc-enable-in 59 | 60 | ########################################################### 61 | # Toolchange 62 | # 63 | # Manual tool change window 64 | # 65 | ########################################################### 66 | 67 | loadusr -W hal_manualtoolchange 68 | net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change 69 | net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed 70 | net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number 71 | net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared 72 | 73 | -------------------------------------------------------------------------------- /examples/swm-fm45a/swm-fm45a.ini: -------------------------------------------------------------------------------- 1 | # Erstellt von stepconf am Tue Oct 21 11:55:16 2014 2 | # Änderungen an dieser Datei werden beim nächsten 3 | # Aufruf von stepconf überschrieben. 4 | 5 | [EMC] 6 | MACHINE = swm-fm45a 7 | DEBUG = 0 8 | 9 | [DISPLAY] 10 | DISPLAY = axis 11 | EDITOR = gedit 12 | POSITION_OFFSET = RELATIVE 13 | POSITION_FEEDBACK = ACTUAL 14 | MAX_FEED_OVERRIDE = 2.0 15 | INTRO_GRAPHIC = linuxcnc.gif 16 | INTRO_TIME = 5 17 | PROGRAM_PREFIX = /home/linuxcnc/linuxcnc/nc_files 18 | INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm 19 | MIN_SPINDLE_OVERRIDE = 0.5 20 | MAX_SPINDLE_OVERRIDE = 1.5 21 | 22 | [FILTER] 23 | PROGRAM_EXTENSION = .png,.gif,.jpg Greyscale Depth Image 24 | PROGRAM_EXTENSION = .py Python Script 25 | png = image-to-gcode 26 | gif = image-to-gcode 27 | jpg = image-to-gcode 28 | py = python 29 | 30 | [TASK] 31 | TASK = milltask 32 | CYCLE_TIME = 0.010 33 | 34 | [RS274NGC] 35 | PARAMETER_FILE = linuxcnc.var 36 | 37 | [EMCMOT] 38 | EMCMOT = motmod 39 | COMM_TIMEOUT = 1.0 40 | COMM_WAIT = 0.010 41 | SERVO_PERIOD = 1000000 42 | 43 | [HAL] 44 | HALFILE = swm-fm45a.hal 45 | HALFILE = swm-fm45a-axis.hal 46 | HALFILE = swm-fm45a-spindle.hal 47 | HALFILE = swm-fm45a-io.hal 48 | 49 | [HALUI] 50 | 51 | [TRAJ] 52 | AXES = 3 53 | COORDINATES = X Y Z 54 | LINEAR_UNITS = mm 55 | ANGULAR_UNITS = degree 56 | CYCLE_TIME = 0.010 57 | DEFAULT_VELOCITY = 20.00 58 | MAX_LINEAR_VELOCITY = 60.00 59 | 60 | [EMCIO] 61 | EMCIO = io 62 | CYCLE_TIME = 0.100 63 | TOOL_TABLE = tool.tbl 64 | 65 | [AXIS_0] 66 | TYPE = LINEAR 67 | HOME = 0.0 68 | HOME_OFFSET = -5.0 69 | HOME_SEQUENCE = 1 70 | HOME_SEARCH_VEL = -20.0 71 | HOME_LATCH_VEL = 1.0 72 | HOME_IGNORE_LIMITS = yes 73 | MAX_VELOCITY = 65.0 74 | MAX_ACCELERATION = 500.0 75 | SCALE = -5.0 76 | ENC_SCALE = -0.001 77 | FERROR = 1 78 | MIN_FERROR = .5 79 | MIN_LIMIT = -1.00 80 | MAX_LIMIT = 414.0 81 | 82 | # Position controller parameters 83 | P = 30.0 84 | I = 0.000 85 | D = 0.000 86 | FF0 = 0.0 87 | FF1 = 1.0 88 | FF2 = 0.0 89 | DEADBAND = 0.01 90 | MAX_OUTPUT = 200.0 91 | 92 | [AXIS_1] 93 | TYPE = LINEAR 94 | HOME = 0.0 95 | HOME_OFFSET = 5.0 96 | HOME_SEQUENCE = 1 97 | HOME_SEARCH_VEL = 20.0 98 | HOME_LATCH_VEL = -1.0 99 | HOME_IGNORE_LIMITS = yes 100 | MAX_VELOCITY = 65.0 101 | MAX_ACCELERATION = 500.0 102 | SCALE = 5.0 103 | ENC_SCALE = -0.001 104 | FERROR = 1 105 | MIN_FERROR = .5 106 | MIN_LIMIT = -160.00 107 | MAX_LIMIT = 1.0 108 | 109 | # Position controller parameters 110 | P = 30.0 111 | I = 0.000 112 | D = 0.000 113 | FF0 = 0.0 114 | FF1 = 1.0 115 | FF2 = 0.0 116 | DEADBAND = 0.01 117 | MAX_OUTPUT = 200.0 118 | 119 | [AXIS_2] 120 | TYPE = LINEAR 121 | HOME = 0.0 122 | HOME_OFFSET = 5.0 123 | HOME_SEQUENCE = 0 124 | HOME_SEARCH_VEL = 20.0 125 | HOME_LATCH_VEL = -1.0 126 | HOME_IGNORE_LIMITS = yes 127 | MAX_VELOCITY = 65.0 128 | MAX_ACCELERATION = 300.0 129 | SCALE = -2.5 130 | ENC_SCALE = 0.001 131 | FERROR = 1 132 | MIN_FERROR = .25 133 | MIN_LIMIT = -316.0 134 | MAX_LIMIT = 1.0 135 | 136 | # Position controller parameters 137 | P = 30.0 138 | I = 0.000 139 | D = 0.000 140 | FF0 = 0.0 141 | FF1 = 1.0 142 | FF2 = 0.0 143 | DEADBAND = 0.01 144 | MAX_OUTPUT = 200.0 145 | 146 | -------------------------------------------------------------------------------- /examples/swm-fm45a/tool.tbl: -------------------------------------------------------------------------------- 1 | T1 P1 D0.125000 Z+0.511000 ;1/8 end mill 2 | T2 P2 D0.062500 Z+0.100000 ;1/16 end mill 3 | T3 P3 D0.201000 Z+1.273000 ;#7 tap drill 4 | T99999 P99999 Z+0.100000 ;big tool number 5 | -------------------------------------------------------------------------------- /patches/add-task-pll-functions-2.7.patch: -------------------------------------------------------------------------------- 1 | diff -Naur linuxcnc.orig/src/rtapi/rtapi.h linuxcnc/src/rtapi/rtapi.h 2 | --- linuxcnc.orig/src/rtapi/rtapi.h 2018-06-18 20:25:19.000000000 +0200 3 | +++ linuxcnc/src/rtapi/rtapi.h 2018-06-29 17:04:15.169661593 +0200 4 | @@ -473,6 +473,26 @@ 5 | */ 6 | extern int rtapi_task_self(void); 7 | 8 | +#if defined(RTAPI_USPACE) || defined(USPACE) 9 | + 10 | +#define RTAPI_TASK_PLL_SUPPORT 11 | + 12 | +/** 'rtapi_task_pll_get_reference()' gets the reference timestamp 13 | + for the start of the current cycle. 14 | + Returns 0 if not called from within task context or on 15 | + platforms that do not support this. 16 | +*/ 17 | + extern long long rtapi_task_pll_get_reference(void); 18 | + 19 | +/** 'rtapi_task_pll_set_correction()' sets the correction value for 20 | + the next scheduling cycle of the current task. This could be 21 | + used to synchronize the task cycle to external sources. 22 | + Returns -EINVAL if not called from within task context or on 23 | + platforms that do not support this. 24 | +*/ 25 | + extern int rtapi_task_pll_set_correction(long value); 26 | +#endif /* USPACE */ 27 | + 28 | #endif /* RTAPI */ 29 | 30 | /*********************************************************************** 31 | diff -Naur linuxcnc.orig/src/rtapi/rtapi_uspace.hh linuxcnc/src/rtapi/rtapi_uspace.hh 32 | --- linuxcnc.orig/src/rtapi/rtapi_uspace.hh 2018-06-18 20:25:19.000000000 +0200 33 | +++ linuxcnc/src/rtapi/rtapi_uspace.hh 2018-06-29 17:04:15.169661593 +0200 34 | @@ -47,6 +47,8 @@ 35 | virtual int task_pause(int task_id) = 0; 36 | virtual int task_resume(int task_id) = 0; 37 | virtual int task_self() = 0; 38 | + virtual long long task_pll_get_reference(void) = 0; 39 | + virtual int task_pll_set_correction(long value) = 0; 40 | virtual void wait() = 0; 41 | virtual unsigned char do_inb(unsigned int port) = 0; 42 | virtual void do_outb(unsigned char value, unsigned int port) = 0; 43 | @@ -71,6 +73,8 @@ 44 | long period; 45 | struct timespec nextstart; 46 | unsigned ratio; 47 | + long pll_correction; 48 | + long pll_correction_limit; 49 | void *arg; 50 | void (*taskcode) (void*); /* pointer to task function */ 51 | }; 52 | diff -Naur linuxcnc.orig/src/rtapi/uspace_rtapi_app.cc linuxcnc/src/rtapi/uspace_rtapi_app.cc 53 | --- linuxcnc.orig/src/rtapi/uspace_rtapi_app.cc 2018-06-18 20:25:19.000000000 +0200 54 | +++ linuxcnc/src/rtapi/uspace_rtapi_app.cc 2018-06-29 17:04:15.169661593 +0200 55 | @@ -519,6 +519,8 @@ 56 | int task_pause(int task_id); 57 | int task_resume(int task_id); 58 | int task_self(); 59 | + long long task_pll_get_reference(void); 60 | + int task_pll_set_correction(long value); 61 | void wait(); 62 | unsigned char do_inb(unsigned int port); 63 | void do_outb(unsigned char value, unsigned int port); 64 | @@ -841,6 +843,10 @@ 65 | task->period = period_nsec; 66 | task->ratio = period_nsec / period; 67 | 68 | + // limit PLL correction values to +/-1% of cycle time 69 | + task->pll_correction_limit = period_nsec / 100; 70 | + task->pll_correction = 0; 71 | + 72 | struct sched_param param; 73 | memset(¶m, 0, sizeof(param)); 74 | param.sched_priority = task->prio; 75 | @@ -917,7 +923,7 @@ 76 | 77 | struct timespec now; 78 | clock_gettime(RTAPI_CLOCK, &now); 79 | - advance_clock(task->nextstart, now, task->period); 80 | + advance_clock(task->nextstart, now, task->period + task->pll_correction); 81 | 82 | /* call the task function with the task argument */ 83 | (task->taskcode) (task->arg); 84 | @@ -940,6 +946,21 @@ 85 | return task - task_array; 86 | } 87 | 88 | +long long Posix::task_pll_get_reference(void) { 89 | + struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 90 | + if(!task) return 0; 91 | + return task->nextstart.tv_sec * 1000000000LL + task->nextstart.tv_nsec; 92 | +} 93 | + 94 | +int Posix::task_pll_set_correction(long value) { 95 | + struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 96 | + if(!task) return -EINVAL; 97 | + if (value > task->pll_correction_limit) value = task->pll_correction_limit; 98 | + if (value < -(task->pll_correction_limit)) value = -(task->pll_correction_limit); 99 | + task->pll_correction = value; 100 | + return 0; 101 | +} 102 | + 103 | static bool ts_less(const struct timespec &ta, const struct timespec &tb) { 104 | if(ta.tv_sec < tb.tv_sec) return 1; 105 | if(ta.tv_sec > tb.tv_sec) return 0; 106 | @@ -951,7 +972,7 @@ 107 | pthread_mutex_unlock(&thread_lock); 108 | pthread_testcancel(); 109 | struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 110 | - advance_clock(task->nextstart, task->nextstart, task->period); 111 | + advance_clock(task->nextstart, task->nextstart, task->period + task->pll_correction); 112 | struct timespec now; 113 | clock_gettime(RTAPI_CLOCK, &now); 114 | if(ts_less(task->nextstart, now)) 115 | @@ -1051,6 +1072,16 @@ 116 | return App().task_self(); 117 | } 118 | 119 | +long long rtapi_task_pll_get_reference(void) 120 | +{ 121 | + return App().task_pll_get_reference(); 122 | +} 123 | + 124 | +int rtapi_task_pll_set_correction(long value) 125 | +{ 126 | + return App().task_pll_set_correction(value); 127 | +} 128 | + 129 | void rtapi_wait(void) 130 | { 131 | App().wait(); 132 | -------------------------------------------------------------------------------- /patches/add-task-pll-functions-2.8.patch: -------------------------------------------------------------------------------- 1 | From 55fae4b21f7bc37f6edc488aca08d7d57521ac8b Mon Sep 17 00:00:00 2001 2 | From: Sascha Ittner 3 | Date: Wed, 20 Nov 2019 11:54:23 +0100 4 | Subject: [PATCH] add task PLL functions 5 | 6 | --- 7 | src/rtapi/rtapi.h | 20 ++++++++++++++++++++ 8 | src/rtapi/rtapi_uspace.hh | 4 ++++ 9 | src/rtapi/uspace_rtapi_app.cc | 35 +++++++++++++++++++++++++++++++++-- 10 | 3 files changed, 57 insertions(+), 2 deletions(-) 11 | 12 | diff --git a/src/rtapi/rtapi.h b/src/rtapi/rtapi.h 13 | index c931542bc..6cf910bdd 100644 14 | --- a/src/rtapi/rtapi.h 15 | +++ b/src/rtapi/rtapi.h 16 | @@ -419,6 +419,26 @@ RTAPI_BEGIN_DECLS 17 | */ 18 | extern int rtapi_task_self(void); 19 | 20 | +#if defined(RTAPI_USPACE) || defined(USPACE) 21 | + 22 | +#define RTAPI_TASK_PLL_SUPPORT 23 | + 24 | +/** 'rtapi_task_pll_get_reference()' gets the reference timestamp 25 | + for the start of the current cycle. 26 | + Returns 0 if not called from within task context or on 27 | + platforms that do not support this. 28 | +*/ 29 | + extern long long rtapi_task_pll_get_reference(void); 30 | + 31 | +/** 'rtapi_task_pll_set_correction()' sets the correction value for 32 | + the next scheduling cycle of the current task. This could be 33 | + used to synchronize the task cycle to external sources. 34 | + Returns -EINVAL if not called from within task context or on 35 | + platforms that do not support this. 36 | +*/ 37 | + extern int rtapi_task_pll_set_correction(long value); 38 | +#endif /* USPACE */ 39 | + 40 | #endif /* RTAPI */ 41 | 42 | /*********************************************************************** 43 | diff --git a/src/rtapi/rtapi_uspace.hh b/src/rtapi/rtapi_uspace.hh 44 | index 0fd4d983c..5e76d03f9 100644 45 | --- a/src/rtapi/rtapi_uspace.hh 46 | +++ b/src/rtapi/rtapi_uspace.hh 47 | @@ -60,6 +60,8 @@ struct rtapi_task { 48 | long period; 49 | struct timespec nextstart; 50 | unsigned ratio; 51 | + long pll_correction; 52 | + long pll_correction_limit; 53 | void *arg; 54 | void (*taskcode) (void*); /* pointer to task function */ 55 | }; 56 | @@ -85,6 +87,8 @@ struct RtapiApp 57 | virtual int task_pause(int task_id) = 0; 58 | virtual int task_resume(int task_id) = 0; 59 | virtual int task_self() = 0; 60 | + virtual long long task_pll_get_reference(void) = 0; 61 | + virtual int task_pll_set_correction(long value) = 0; 62 | virtual void wait() = 0; 63 | virtual unsigned char do_inb(unsigned int port) = 0; 64 | virtual void do_outb(unsigned char value, unsigned int port) = 0; 65 | diff --git a/src/rtapi/uspace_rtapi_app.cc b/src/rtapi/uspace_rtapi_app.cc 66 | index 7d503e20d..2ba2c8df1 100644 67 | --- a/src/rtapi/uspace_rtapi_app.cc 68 | +++ b/src/rtapi/uspace_rtapi_app.cc 69 | @@ -608,6 +608,8 @@ struct Posix : RtapiApp 70 | int task_pause(int task_id); 71 | int task_resume(int task_id); 72 | int task_self(); 73 | + long long task_pll_get_reference(void); 74 | + int task_pll_set_correction(long value); 75 | void wait(); 76 | struct rtapi_task *do_task_new() { 77 | return new PosixTask; 78 | @@ -979,6 +981,10 @@ int Posix::task_start(int task_id, unsigned long int period_nsec) 79 | task->period = period_nsec; 80 | task->ratio = period_nsec / period; 81 | 82 | + // limit PLL correction values to +/-1% of cycle time 83 | + task->pll_correction_limit = period_nsec / 100; 84 | + task->pll_correction = 0; 85 | + 86 | struct sched_param param; 87 | memset(¶m, 0, sizeof(param)); 88 | param.sched_priority = task->prio; 89 | @@ -1042,7 +1048,7 @@ void *Posix::wrapper(void *arg) 90 | 91 | struct timespec now; 92 | clock_gettime(RTAPI_CLOCK, &now); 93 | - rtapi_timespec_advance(task->nextstart, now, task->period); 94 | + rtapi_timespec_advance(task->nextstart, now, task->period + task->pll_correction); 95 | 96 | /* call the task function with the task argument */ 97 | (task->taskcode) (task->arg); 98 | @@ -1051,6 +1057,21 @@ void *Posix::wrapper(void *arg) 99 | return NULL; 100 | } 101 | 102 | +long long Posix::task_pll_get_reference(void) { 103 | + struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 104 | + if(!task) return 0; 105 | + return task->nextstart.tv_sec * 1000000000LL + task->nextstart.tv_nsec; 106 | +} 107 | + 108 | +int Posix::task_pll_set_correction(long value) { 109 | + struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 110 | + if(!task) return -EINVAL; 111 | + if (value > task->pll_correction_limit) value = task->pll_correction_limit; 112 | + if (value < -(task->pll_correction_limit)) value = -(task->pll_correction_limit); 113 | + task->pll_correction = value; 114 | + return 0; 115 | +} 116 | + 117 | int Posix::task_pause(int) { 118 | return -ENOSYS; 119 | } 120 | @@ -1070,7 +1091,7 @@ void Posix::wait() { 121 | pthread_mutex_unlock(&thread_lock); 122 | pthread_testcancel(); 123 | struct rtapi_task *task = reinterpret_cast(pthread_getspecific(key)); 124 | - rtapi_timespec_advance(task->nextstart, task->nextstart, task->period); 125 | + rtapi_timespec_advance(task->nextstart, task->nextstart, task->period + task->pll_correction); 126 | struct timespec now; 127 | clock_gettime(RTAPI_CLOCK, &now); 128 | if(rtapi_timespec_less(task->nextstart, now)) 129 | @@ -1173,6 +1194,16 @@ int rtapi_task_self() 130 | return App().task_self(); 131 | } 132 | 133 | +long long rtapi_task_pll_get_reference(void) 134 | +{ 135 | + return App().task_pll_get_reference(); 136 | +} 137 | + 138 | +int rtapi_task_pll_set_correction(long value) 139 | +{ 140 | + return App().task_pll_set_correction(value); 141 | +} 142 | + 143 | void rtapi_wait(void) 144 | { 145 | App().wait(); 146 | -- 147 | 2.20.1 148 | 149 | -------------------------------------------------------------------------------- /src/Kbuild: -------------------------------------------------------------------------------- 1 | obj-m += lcec.o 2 | lcec-objs := \ 3 | lcec_main.o \ 4 | lcec_class_enc.o \ 5 | lcec_class_ax5.o \ 6 | lcec_generic.o \ 7 | lcec_ax5100.o \ 8 | lcec_ax5200.o \ 9 | lcec_el1xxx.o \ 10 | lcec_el1252.o \ 11 | lcec_el1859.o \ 12 | lcec_el2521.o \ 13 | lcec_el2xxx.o \ 14 | lcec_el2202.o \ 15 | lcec_el31x2.o \ 16 | lcec_el31x4.o \ 17 | lcec_el32x4.o \ 18 | lcec_el3255.o \ 19 | lcec_el40x1.o \ 20 | lcec_el40x2.o \ 21 | lcec_el40x8.o \ 22 | lcec_el41x2.o \ 23 | lcec_el41x4.o \ 24 | lcec_el5002.o \ 25 | lcec_el5021.o \ 26 | lcec_el5032.o \ 27 | lcec_el5101.o \ 28 | lcec_el5151.o \ 29 | lcec_el5122.o \ 30 | lcec_el5152.o \ 31 | lcec_el6900.o \ 32 | lcec_el1918_logic.o \ 33 | lcec_el1904.o \ 34 | lcec_el2904.o \ 35 | lcec_ax5805.o \ 36 | lcec_el7041_1000.o \ 37 | lcec_el70x1.o \ 38 | lcec_el7211.o \ 39 | lcec_el7342.o \ 40 | lcec_el7411.o \ 41 | lcec_el95xx.o \ 42 | lcec_em7004.o \ 43 | lcec_stmds5k.o \ 44 | lcec_deasda.o \ 45 | lcec_dems300.o \ 46 | lcec_omrg5.o \ 47 | lcec_ph3lm2rm.o 48 | 49 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | -include ../config.mk 2 | 3 | .PHONY: all install clean 4 | 5 | all: 6 | @$(MAKE) -f user.mk all 7 | @$(MAKE) -f realtime.mk all 8 | 9 | install: ../config.mk 10 | mkdir -p $(DESTDIR)$(RTLIBDIR) 11 | @$(MAKE) -f user.mk install 12 | @$(MAKE) -f realtime.mk install 13 | 14 | clean: 15 | rm -f *.so *.ko *.o 16 | rm -f *.sym *.tmp *.ver 17 | rm -f *.mod.c .*.cmd 18 | rm -f modules.order Module.symvers 19 | rm -rf .tmp_versions 20 | rm -f lcec_conf 21 | 22 | -------------------------------------------------------------------------------- /src/lcec_ax5100.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_ax5100.h" 21 | 22 | typedef struct { 23 | lcec_syncs_t syncs; 24 | lcec_class_ax5_chan_t chan; 25 | } lcec_ax5100_data_t; 26 | 27 | static const LCEC_CONF_FSOE_T fsoe_conf = { 28 | .slave_data_len = 2, 29 | .master_data_len = 2, 30 | .data_channels = 1 31 | }; 32 | 33 | void lcec_ax5100_read(struct lcec_slave *slave, long period); 34 | void lcec_ax5100_write(struct lcec_slave *slave, long period); 35 | 36 | int lcec_ax5100_preinit(struct lcec_slave *slave) { 37 | // check if already initialized 38 | if (slave->fsoeConf != NULL) { 39 | return 0; 40 | } 41 | 42 | // set FSOE conf (this will be used by the corresponding AX5805 43 | slave->fsoeConf = &fsoe_conf; 44 | 45 | // set pdo count 46 | slave->pdo_entry_count = lcec_class_ax5_pdos(slave); 47 | 48 | return 0; 49 | } 50 | 51 | int lcec_ax5100_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 52 | lcec_master_t *master = slave->master; 53 | lcec_ax5100_data_t *hal_data; 54 | int err; 55 | 56 | // initialize callbacks 57 | slave->proc_read = lcec_ax5100_read; 58 | slave->proc_write = lcec_ax5100_write; 59 | 60 | // alloc hal memory 61 | if ((hal_data = hal_malloc(sizeof(lcec_ax5100_data_t))) == NULL) { 62 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 63 | return -EIO; 64 | } 65 | memset(hal_data, 0, sizeof(lcec_ax5100_data_t)); 66 | slave->hal_data = hal_data; 67 | 68 | // init subclasses 69 | if ((err = lcec_class_ax5_init(slave, pdo_entry_regs, &hal_data->chan, 0, "")) != 0) { 70 | return err; 71 | } 72 | 73 | // initialize sync info 74 | lcec_syncs_init(&hal_data->syncs); 75 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_OUTPUT, EC_WD_DEFAULT); 76 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_INPUT, EC_WD_DEFAULT); 77 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_OUTPUT, EC_WD_DEFAULT); 78 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x0018); 79 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0086, 0x01, 16); // control-word 80 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0018, 0x01, 32); // velo-command 81 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_INPUT, EC_WD_DEFAULT); 82 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x0010); 83 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0087, 0x01, 16); // status word 84 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0033, 0x01, 32); // position feedback 85 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0054, 0x01, 16); // torque feedback 86 | if (hal_data->chan.fb2_enabled) { 87 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0035, 0x01, 32); // position feedback 2 88 | } 89 | if (hal_data->chan.diag_enabled) { 90 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0186, 0x01, 32); // diagnostic number 91 | } 92 | slave->sync_info = &hal_data->syncs.syncs[0]; 93 | 94 | return 0; 95 | } 96 | 97 | void lcec_ax5100_read(struct lcec_slave *slave, long period) { 98 | lcec_ax5100_data_t *hal_data = (lcec_ax5100_data_t *) slave->hal_data; 99 | 100 | // check inputs 101 | lcec_class_ax5_read(slave, &hal_data->chan); 102 | } 103 | 104 | void lcec_ax5100_write(struct lcec_slave *slave, long period) { 105 | lcec_ax5100_data_t *hal_data = (lcec_ax5100_data_t *) slave->hal_data; 106 | 107 | // write outputs 108 | lcec_class_ax5_write(slave, &hal_data->chan); 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/lcec_ax5100.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_AX5100_H_ 19 | #define _LCEC_AX5100_H_ 20 | 21 | #include "lcec.h" 22 | #include "lcec_class_ax5.h" 23 | 24 | #define LCEC_AX5100_VID LCEC_BECKHOFF_VID 25 | #define LCEC_AX5101_PID 0x13ed6012 26 | #define LCEC_AX5103_PID 0x13ef6012 27 | #define LCEC_AX5106_PID 0x13f26012 28 | #define LCEC_AX5112_PID 0x13f86012 29 | #define LCEC_AX5118_PID 0x13fe6012 30 | 31 | int lcec_ax5100_preinit(struct lcec_slave *slave); 32 | int lcec_ax5100_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/lcec_ax5200.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_ax5200.h" 21 | 22 | typedef struct { 23 | lcec_syncs_t syncs; 24 | lcec_class_ax5_chan_t chans[LCEC_AX5200_CHANS]; 25 | } lcec_ax5200_data_t; 26 | 27 | static const LCEC_CONF_FSOE_T fsoe_conf = { 28 | .slave_data_len = 2, 29 | .master_data_len = 2, 30 | .data_channels = 2 31 | }; 32 | 33 | void lcec_ax5200_read(struct lcec_slave *slave, long period); 34 | void lcec_ax5200_write(struct lcec_slave *slave, long period); 35 | 36 | int lcec_ax5200_preinit(struct lcec_slave *slave) { 37 | // check if already initialized 38 | if (slave->fsoeConf != NULL) { 39 | return 0; 40 | } 41 | 42 | // set FSOE conf (this will be used by the corresponding AX5805 43 | slave->fsoeConf = &fsoe_conf; 44 | 45 | // set pdo count 46 | slave->pdo_entry_count = lcec_class_ax5_pdos(slave) * LCEC_AX5200_CHANS; 47 | 48 | return 0; 49 | } 50 | 51 | int lcec_ax5200_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 52 | lcec_master_t *master = slave->master; 53 | lcec_ax5200_data_t *hal_data; 54 | int i; 55 | lcec_class_ax5_chan_t *chan; 56 | int err; 57 | char pfx[HAL_NAME_LEN]; 58 | 59 | // initialize callbacks 60 | slave->proc_read = lcec_ax5200_read; 61 | slave->proc_write = lcec_ax5200_write; 62 | 63 | // alloc hal memory 64 | if ((hal_data = hal_malloc(sizeof(lcec_ax5200_data_t))) == NULL) { 65 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 66 | return -EIO; 67 | } 68 | memset(hal_data, 0, sizeof(lcec_ax5200_data_t)); 69 | slave->hal_data = hal_data; 70 | 71 | // initialize pins 72 | for (i=0; ichans[i]; 74 | 75 | // init subclasses 76 | rtapi_snprintf(pfx, HAL_NAME_LEN, "ch%d.", i); 77 | if ((err = lcec_class_ax5_init(slave, pdo_entry_regs, chan, i, pfx)) != 0) { 78 | return err; 79 | } 80 | } 81 | 82 | // initialize sync info 83 | lcec_syncs_init(&hal_data->syncs); 84 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_OUTPUT, EC_WD_DEFAULT); 85 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_INPUT, EC_WD_DEFAULT); 86 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_OUTPUT, EC_WD_DEFAULT); 87 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x0018); 88 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0086, 0x01, 16); // control-word 89 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0018, 0x01, 32); // velo-command 90 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x1018); 91 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0086, 0x02, 16); // control-word 92 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0018, 0x02, 32); // velo-command 93 | lcec_syncs_add_sync(&hal_data->syncs, EC_DIR_INPUT, EC_WD_DEFAULT); 94 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x0010); 95 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0087, 0x01, 16); // status word 96 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0033, 0x01, 32); // position feedback 97 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0054, 0x01, 16); // torque feedback 98 | if (hal_data->chans[0].fb2_enabled) { 99 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0035, 0x01, 32); // position feedback 2 100 | } 101 | if (hal_data->chans[0].diag_enabled) { 102 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0186, 0x01, 32); // diagnostic number 103 | } 104 | lcec_syncs_add_pdo_info(&hal_data->syncs, 0x1010); 105 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0087, 0x02, 16); // status word 106 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0033, 0x02, 32); // position feedback 107 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0054, 0x02, 16); // torque feedback 108 | if (hal_data->chans[1].fb2_enabled) { 109 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0035, 0x02, 32); // position feedback 2 110 | } 111 | if (hal_data->chans[1].diag_enabled) { 112 | lcec_syncs_add_pdo_entry(&hal_data->syncs, 0x0186, 0x02, 32); // diagnostic number 113 | } 114 | slave->sync_info = &hal_data->syncs.syncs[0]; 115 | 116 | return 0; 117 | } 118 | 119 | void lcec_ax5200_read(struct lcec_slave *slave, long period) { 120 | lcec_ax5200_data_t *hal_data = (lcec_ax5200_data_t *) slave->hal_data; 121 | int i; 122 | lcec_class_ax5_chan_t *chan; 123 | 124 | // check inputs 125 | for (i=0; ichans[i]; 127 | lcec_class_ax5_read(slave, chan); 128 | } 129 | } 130 | 131 | void lcec_ax5200_write(struct lcec_slave *slave, long period) { 132 | lcec_ax5200_data_t *hal_data = (lcec_ax5200_data_t *) slave->hal_data; 133 | int i; 134 | lcec_class_ax5_chan_t *chan; 135 | 136 | // write outputs 137 | for (i=0; ichans[i]; 139 | lcec_class_ax5_write(slave, chan); 140 | } 141 | } 142 | 143 | -------------------------------------------------------------------------------- /src/lcec_ax5200.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_AX5200_H_ 19 | #define _LCEC_AX5200_H_ 20 | 21 | #include "lcec.h" 22 | #include "lcec_class_ax5.h" 23 | 24 | #define LCEC_AX5200_VID LCEC_BECKHOFF_VID 25 | #define LCEC_AX5203_PID 0x14536012 26 | #define LCEC_AX5206_PID 0x14566012 27 | 28 | #define LCEC_AX5200_CHANS 2 29 | #define LCEC_AX5200_PDOS (LCEC_AX5200_CHANS * LCEC_CLASS_AX5_PDOS) 30 | 31 | int lcec_ax5200_preinit(struct lcec_slave *slave); 32 | int lcec_ax5200_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/lcec_ax5805.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_AX5805_H_ 19 | #define _LCEC_AX5805_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_AX5805_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_AX5805_PID 0x16AD6012 26 | 27 | int lcec_ax5805_preinit(struct lcec_slave *slave); 28 | int lcec_ax5805_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /src/lcec_class_ax5.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_CLASS_AX5_H_ 19 | #define _LCEC_CLASS_AX5_H_ 20 | 21 | #include "lcec.h" 22 | #include "lcec_class_enc.h" 23 | 24 | #define LCEC_AX5_PARAM_ENABLE_FB2 1 25 | #define LCEC_AX5_PARAM_ENABLE_DIAG 2 26 | 27 | typedef struct { 28 | hal_bit_t *drive_on; 29 | 30 | hal_bit_t *enable; 31 | hal_bit_t *enabled; 32 | hal_bit_t *halted; 33 | hal_bit_t *fault; 34 | 35 | hal_bit_t *halt; 36 | 37 | hal_float_t *velo_cmd; 38 | 39 | int fb2_enabled; 40 | int diag_enabled; 41 | 42 | hal_u32_t *status; 43 | hal_float_t *torque_fb_pct; 44 | hal_u32_t *diag; 45 | 46 | unsigned int status_pdo_os; 47 | unsigned int pos_fb_pdo_os; 48 | unsigned int pos_fb2_pdo_os; 49 | unsigned int torque_fb_pdo_os; 50 | unsigned int diag_pdo_os; 51 | unsigned int ctrl_pdo_os; 52 | unsigned int vel_cmd_pdo_os; 53 | 54 | hal_float_t scale; 55 | hal_float_t scale_fb2; 56 | hal_float_t vel_scale; 57 | hal_u32_t pos_resolution; 58 | 59 | lcec_class_enc_data_t enc; 60 | lcec_class_enc_data_t enc_fb2; 61 | 62 | double scale_old; 63 | double scale_rcpt; 64 | double scale_fb2_old; 65 | double scale_fb2_rcpt; 66 | 67 | double vel_output_scale; 68 | 69 | int toggle; 70 | 71 | } lcec_class_ax5_chan_t; 72 | 73 | int lcec_class_ax5_pdos(struct lcec_slave *slave); 74 | int lcec_class_ax5_init(struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs, lcec_class_ax5_chan_t *chan, int index, const char *pfx); 75 | void lcec_class_ax5_read(struct lcec_slave *slave, lcec_class_ax5_chan_t *chan); 76 | void lcec_class_ax5_write(struct lcec_slave *slave, lcec_class_ax5_chan_t *chan); 77 | 78 | #endif 79 | 80 | -------------------------------------------------------------------------------- /src/lcec_class_enc.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_class_enc.h" 21 | 22 | static const lcec_pindesc_t slave_pins[] = { 23 | { HAL_S32, HAL_OUT, offsetof(lcec_class_enc_data_t, raw), "%s.%s.%s.%s-raw" }, 24 | { HAL_U32, HAL_IO, offsetof(lcec_class_enc_data_t, ext_lo), "%s.%s.%s.%s-ext-lo" }, 25 | { HAL_U32, HAL_IO, offsetof(lcec_class_enc_data_t, ext_hi), "%s.%s.%s.%s-ext-hi" }, 26 | { HAL_U32, HAL_OUT, offsetof(lcec_class_enc_data_t, ref_lo), "%s.%s.%s.%s-ref-lo" }, 27 | { HAL_U32, HAL_OUT, offsetof(lcec_class_enc_data_t, ref_hi), "%s.%s.%s.%s-ref-hi" }, 28 | { HAL_BIT, HAL_IO, offsetof(lcec_class_enc_data_t, index_ena), "%s.%s.%s.%s-index-ena" }, 29 | { HAL_BIT, HAL_IN, offsetof(lcec_class_enc_data_t, pos_reset), "%s.%s.%s.%s-pos-reset" }, 30 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_class_enc_data_t, pos_enc), "%s.%s.%s.%s-pos-enc" }, 31 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_class_enc_data_t, pos_abs), "%s.%s.%s.%s-pos-abs" }, 32 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_class_enc_data_t, pos), "%s.%s.%s.%s-pos" }, 33 | { HAL_BIT, HAL_OUT, offsetof(lcec_class_enc_data_t, on_home_neg), "%s.%s.%s.%s-on-home-neg" }, 34 | { HAL_BIT, HAL_OUT, offsetof(lcec_class_enc_data_t, on_home_pos), "%s.%s.%s.%s-on-home-pos" }, 35 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 36 | }; 37 | 38 | static const lcec_pindesc_t slave_params[] = { 39 | { HAL_U32, HAL_RW, offsetof(lcec_class_enc_data_t, raw_home), "%s.%s.%s.%s-raw-home" }, 40 | { HAL_U32, HAL_RO, offsetof(lcec_class_enc_data_t, raw_bits), "%s.%s.%s.%s-raw-bits" }, 41 | { HAL_FLOAT, HAL_RO, offsetof(lcec_class_enc_data_t, pprev_scale), "%s.%s.%s.%s-pprev-scale" }, 42 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 43 | }; 44 | 45 | static int32_t raw_diff(int shift, uint32_t raw_a, uint32_t raw_b); 46 | static void set_ref(lcec_class_enc_data_t *hal_data, long long ref); 47 | static long long signed_mod_64(long long val, unsigned long div); 48 | 49 | int class_enc_init(struct lcec_slave *slave, lcec_class_enc_data_t *hal_data, int raw_bits, const char *pfx) { 50 | lcec_master_t *master = slave->master; 51 | int err; 52 | 53 | // export pins 54 | if ((err = lcec_pin_newf_list(hal_data, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, pfx)) != 0) { 55 | return err; 56 | } 57 | 58 | // export parameters 59 | if ((err = lcec_param_newf_list(hal_data, slave_params, LCEC_MODULE_NAME, master->name, slave->name, pfx)) != 0) { 60 | return err; 61 | } 62 | 63 | hal_data->do_init = 1; 64 | hal_data->index_sign = 0; 65 | 66 | hal_data->pprev_last = 0; 67 | hal_data->pprev_scale = 1.0; 68 | 69 | hal_data->raw_bits = raw_bits; 70 | hal_data->raw_shift = 32 - hal_data->raw_bits; 71 | hal_data->raw_mask = (1LL << hal_data->raw_bits) - 1; 72 | 73 | return 0; 74 | } 75 | 76 | void class_enc_update(lcec_class_enc_data_t *hal_data, uint64_t pprev, double scale, uint32_t raw, uint32_t ext_latch_raw, int ext_latch_ena) { 77 | long long pos, mod; 78 | uint32_t ovfl_win; 79 | int sign; 80 | double pos_scale; 81 | 82 | // calculate pos scale 83 | if (pprev > 0) { 84 | if (hal_data->do_init || hal_data->pprev_last != pprev) { 85 | hal_data->pprev_scale = 1.0 / ((double) pprev); 86 | hal_data->index_sign = 0; 87 | } 88 | pos_scale = hal_data->pprev_scale * scale; 89 | } else { 90 | pos_scale = scale; 91 | } 92 | hal_data->pprev_last = pprev; 93 | 94 | // init last encoder value to last known position 95 | // this could be used to retain extrapolated multiturn tracking 96 | // IMPORTANT: hi/lo values need to be stored atomic 97 | if (hal_data->do_init) { 98 | *(hal_data->raw) = *(hal_data->ext_lo) & hal_data->raw_mask; 99 | } 100 | 101 | // extrapolate to 64 bits 102 | pos = ((long long) *(hal_data->ext_hi) << 32) | *(hal_data->ext_lo); 103 | pos += raw_diff(hal_data->raw_shift, raw, *(hal_data->raw)); 104 | *(hal_data->raw) = raw; 105 | *(hal_data->ext_hi) = (uint32_t) (pos >> 32); 106 | *(hal_data->ext_lo) = (uint32_t) pos; 107 | 108 | // set raw encoder pos 109 | *(hal_data->pos_enc) = ((double) pos) * pos_scale; 110 | 111 | // calculate home based abs pos 112 | pos += raw_diff(hal_data->raw_shift, 0, hal_data->raw_home); 113 | *(hal_data->pos_abs) = ((double) pos) * pos_scale; 114 | *(hal_data->on_home_neg) = (pos <= 0); 115 | *(hal_data->on_home_pos) = (pos >= 0); 116 | 117 | // handle index 118 | if (*(hal_data->index_ena)) { 119 | // get overflow detection window (pprev / 4) 120 | ovfl_win = pprev >> 2; 121 | if (ovfl_win == 0 || pprev > 0xffffffff) { 122 | // no useable singleturn bits -> just reset the position 123 | *(hal_data->index_ena) = 0; 124 | set_ref(hal_data, pos); 125 | } else { 126 | mod = signed_mod_64(pos, pprev); 127 | sign = (mod >= 0) ? 1 : -1; 128 | if (hal_data->index_sign != 0 && sign != hal_data->index_sign && mod <= ovfl_win) { 129 | *(hal_data->index_ena) = 0; 130 | set_ref(hal_data, pos - mod); 131 | } 132 | hal_data->index_sign = sign; 133 | } 134 | } else { 135 | hal_data->index_sign = 0; 136 | } 137 | 138 | // handle external latch 139 | if (ext_latch_ena) { 140 | set_ref(hal_data, pos + raw_diff(hal_data->raw_shift, ext_latch_raw, raw)); 141 | } 142 | 143 | // handle rel position init 144 | if (hal_data->do_init || *(hal_data->pos_reset)) { 145 | set_ref(hal_data, pos); 146 | } 147 | 148 | // calculate rel pos 149 | pos -= ((long long) *(hal_data->ref_hi) << 32) | *(hal_data->ref_lo); 150 | *(hal_data->pos) = ((double) pos) * pos_scale; 151 | 152 | hal_data->do_init = 0; 153 | } 154 | 155 | static int32_t raw_diff(int shift, uint32_t a, uint32_t b) { 156 | return ((int32_t) (a << shift) - (int32_t) (b << shift)) >> shift; 157 | } 158 | 159 | static void set_ref(lcec_class_enc_data_t *hal_data, long long ref) { 160 | *(hal_data->ref_hi) = (uint32_t) (ref >> 32); 161 | *(hal_data->ref_lo) = (uint32_t) ref; 162 | } 163 | 164 | static long long signed_mod_64(long long val, unsigned long div) { 165 | long long rem = lcec_mod_64(val, div); 166 | 167 | if (rem < 0) { 168 | rem += div; 169 | } 170 | 171 | if (rem > (div >> 1)) { 172 | rem -= div; 173 | } 174 | 175 | return rem; 176 | } 177 | 178 | 179 | -------------------------------------------------------------------------------- /src/lcec_class_enc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_CLASS_ENC_H_ 19 | #define _LCEC_CLASS_ENC_H_ 20 | 21 | #include "lcec.h" 22 | 23 | typedef struct { 24 | hal_s32_t raw_home; 25 | hal_u32_t raw_bits; 26 | hal_float_t pprev_scale; 27 | 28 | hal_s32_t *raw; 29 | hal_u32_t *ext_lo; 30 | hal_u32_t *ext_hi; 31 | hal_u32_t *ref_lo; 32 | hal_u32_t *ref_hi; 33 | 34 | hal_bit_t *index_ena; 35 | hal_bit_t *pos_reset; 36 | 37 | hal_float_t *pos_enc; 38 | hal_float_t *pos_abs; 39 | hal_float_t *pos; 40 | 41 | hal_bit_t *on_home_neg; 42 | hal_bit_t *on_home_pos; 43 | 44 | int do_init; 45 | 46 | int raw_shift; 47 | uint32_t raw_mask; 48 | 49 | uint64_t pprev_last; 50 | 51 | int index_sign; 52 | 53 | } lcec_class_enc_data_t; 54 | 55 | int class_enc_init(struct lcec_slave *slave, lcec_class_enc_data_t *hal_data, int raw_bits, const char *pfx); 56 | void class_enc_update(lcec_class_enc_data_t *hal_data, uint64_t pprev, double scale, uint32_t raw, uint32_t ext_latch_raw, int ext_latch_ena); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/lcec_conf_priv.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_CONF_PRIV_H_ 19 | #define _LCEC_CONF_PRIV_H_ 20 | 21 | #include 22 | 23 | #define BUFFSIZE 8192 24 | 25 | struct LCEC_CONF_XML_HANLDER; 26 | 27 | typedef struct LCEC_CONF_XML_INST { 28 | XML_Parser parser; 29 | const struct LCEC_CONF_XML_HANLDER *states; 30 | int state; 31 | } LCEC_CONF_XML_INST_T; 32 | 33 | typedef struct LCEC_CONF_XML_HANLDER { 34 | const char *el; 35 | int state_from; 36 | int state_to; 37 | void (*start_handler)(struct LCEC_CONF_XML_INST *inst, int next, const char **attr); 38 | void (*end_handler)(struct LCEC_CONF_XML_INST *inst, int next); 39 | } LCEC_CONF_XML_HANLDER_T; 40 | 41 | typedef struct LCEC_CONF_OUTBUF_ITEM { 42 | size_t len; 43 | struct LCEC_CONF_OUTBUF_ITEM *next; 44 | } LCEC_CONF_OUTBUF_ITEM_T; 45 | 46 | typedef struct { 47 | LCEC_CONF_OUTBUF_ITEM_T *head; 48 | LCEC_CONF_OUTBUF_ITEM_T *tail; 49 | size_t len; 50 | } LCEC_CONF_OUTBUF_T; 51 | 52 | extern char *modname; 53 | 54 | void initOutputBuffer(LCEC_CONF_OUTBUF_T *buf); 55 | void *addOutputBuffer(LCEC_CONF_OUTBUF_T *buf, size_t len); 56 | void copyFreeOutputBuffer(LCEC_CONF_OUTBUF_T *buf, void *dest); 57 | 58 | int parseIcmds(LCEC_CONF_SLAVE_T *slave, LCEC_CONF_OUTBUF_T *outputBuf, const char *filename); 59 | 60 | int initXmlInst(LCEC_CONF_XML_INST_T *inst, const LCEC_CONF_XML_HANLDER_T *states); 61 | 62 | int parseHex(const char *s, int slen, uint8_t *buf); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/lcec_conf_util.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "lcec_conf.h" 26 | #include "lcec_conf_priv.h" 27 | 28 | char *modname = "lcec_conf"; 29 | 30 | static void xml_start_handler(void *data, const char *el, const char **attr); 31 | static void xml_end_handler(void *data, const char *el); 32 | 33 | void initOutputBuffer(LCEC_CONF_OUTBUF_T *buf) { 34 | buf->head = NULL; 35 | buf->tail = NULL; 36 | buf->len = 0; 37 | } 38 | 39 | void *addOutputBuffer(LCEC_CONF_OUTBUF_T *buf, size_t len) { 40 | 41 | void *p = calloc(1, sizeof(LCEC_CONF_OUTBUF_ITEM_T) + len); 42 | if (p == NULL) { 43 | fprintf(stderr, "%s: ERROR: Couldn't allocate memory for config token\n", modname); 44 | return NULL; 45 | } 46 | 47 | // setup header 48 | LCEC_CONF_OUTBUF_ITEM_T *header = p; 49 | p += sizeof(LCEC_CONF_OUTBUF_ITEM_T); 50 | header->len = len; 51 | buf->len += len; 52 | 53 | // update list 54 | if (buf->head == NULL) { 55 | buf->head = header; 56 | } 57 | if (buf->tail != NULL) { 58 | buf->tail->next = header; 59 | } 60 | buf->tail = header; 61 | 62 | return p; 63 | } 64 | 65 | void copyFreeOutputBuffer(LCEC_CONF_OUTBUF_T *buf, void *dest) { 66 | void *p; 67 | 68 | while (buf->head != NULL) { 69 | p = buf->head; 70 | if (dest != NULL) { 71 | memcpy(dest, p + sizeof(LCEC_CONF_OUTBUF_ITEM_T), buf->head->len); 72 | dest += buf->head->len; 73 | } 74 | buf->head = buf->head->next; 75 | free(p); 76 | } 77 | } 78 | 79 | int initXmlInst(LCEC_CONF_XML_INST_T *inst, const LCEC_CONF_XML_HANLDER_T *states) { 80 | // create xml parser 81 | inst->parser = XML_ParserCreate(NULL); 82 | if (inst->parser == NULL) { 83 | return 1; 84 | } 85 | 86 | // setup data 87 | inst->states = states; 88 | inst->state = 0; 89 | XML_SetUserData(inst->parser, inst); 90 | 91 | // setup handlers 92 | XML_SetElementHandler(inst->parser, xml_start_handler, xml_end_handler); 93 | 94 | return 0; 95 | } 96 | 97 | static void xml_start_handler(void *data, const char *el, const char **attr) { 98 | LCEC_CONF_XML_INST_T *inst = (LCEC_CONF_XML_INST_T *) data; 99 | const LCEC_CONF_XML_HANLDER_T *state; 100 | 101 | for (state = inst->states; state->el != NULL; state++) { 102 | if (inst->state == state->state_from && (strcmp(el, state->el) == 0)) { 103 | if (state->start_handler != NULL) { 104 | state->start_handler(inst, state->state_to, attr); 105 | } 106 | inst->state = state->state_to; 107 | return; 108 | } 109 | } 110 | 111 | fprintf(stderr, "%s: ERROR: unexpected node %s found\n", modname, el); 112 | XML_StopParser(inst->parser, 0); 113 | } 114 | 115 | static void xml_end_handler(void *data, const char *el) { 116 | LCEC_CONF_XML_INST_T *inst = (LCEC_CONF_XML_INST_T *) data; 117 | const LCEC_CONF_XML_HANLDER_T *state; 118 | 119 | for (state = inst->states; state->el != NULL; state++) { 120 | if (inst->state == state->state_to && (strcmp(el, state->el) == 0)) { 121 | if (state->end_handler != NULL) { 122 | state->end_handler(inst, state->state_from); 123 | } 124 | inst->state = state->state_from; 125 | return; 126 | } 127 | } 128 | 129 | fprintf(stderr, "%s: ERROR: unexpected close tag %s found\n", modname, el); 130 | XML_StopParser(inst->parser, 0); 131 | } 132 | 133 | int parseHex(const char *s, int slen, uint8_t *buf) { 134 | char c; 135 | int len; 136 | int nib; 137 | uint8_t tmp; 138 | 139 | for (len = 0, nib = 0, tmp = 0; (slen == -1 || slen > 0) && (c = *s) != 0; s++) { 140 | // update remaining length 141 | if (slen > 0) { 142 | slen --; 143 | } 144 | 145 | // skip blanks if no current nibble 146 | if (!nib && strchr(" \t\r\n", c)) { 147 | continue; 148 | } 149 | 150 | // get nibble value 151 | if (c >= '0' && c <= '9') { 152 | c = c - '0'; 153 | } else if (c >= 'a' && c <= 'f') { 154 | c = c - 'a' + 10; 155 | } else if (c >= 'A' && c <= 'F') { 156 | c = c - 'A' + 10; 157 | } else { 158 | return -1; 159 | } 160 | 161 | // store nibble 162 | if (nib) { 163 | tmp |= c & 0x0f; 164 | if (buf) { 165 | *(buf++) = tmp; 166 | } 167 | len++; 168 | } else { 169 | tmp = c << 4; 170 | } 171 | nib = !nib; 172 | } 173 | 174 | // nibble must not be active 175 | if (nib) { 176 | return -1; 177 | } 178 | 179 | return len; 180 | } 181 | 182 | -------------------------------------------------------------------------------- /src/lcec_deasda.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | /*############################################################################# 20 | 21 | Description of Pins/Parameters: 22 | 23 | Pins: 24 | FLOAT OUT srv-vel-fb 25 | Actual velocity feddback in scale units per second. 26 | 27 | FLOAT OUT srv-vel-fb-rpm 28 | Actual velocity feddback in revolutions per minute. 29 | 30 | FLOAT OUT srv-vel-fb-rpm-abs 31 | Actual absolute value of velocity feddback in 32 | revolutions per minute. 33 | 34 | FLOAT OUT srv-vel-rpm 35 | Current velocity command send to motor driver in 36 | revolutions per minute. 37 | 38 | BIT OUT srv-ready 39 | ready status flag from motor driver 40 | 41 | BIT OUT srv-switched-on 42 | switched-on status flag from motor driver 43 | 44 | BIT OUT srv-oper-enabled 45 | operation-enabled status flag from motor driver 46 | 47 | BIT OUT srv-fault 48 | fault status flag from motor driver 49 | 50 | BIT OUT srv-volt-enabled 51 | voltage-enabled status flag from motor driver 52 | 53 | BIT OUT srv-quick-stoped 54 | quick-stoped status flag from motor driver 55 | 56 | BIT OUT srv-on-disabled 57 | on-disabled status flag from motor driver 58 | 59 | BIT OUT srv-warning 60 | warning status flag from motor driver 61 | 62 | BIT OUT srv-remote 63 | motor driver is remote controlled 64 | 65 | BIT OUT srv-at-speed 66 | motor has reached requested velocity 67 | 68 | BIT OUT srv-limit-active 69 | motor driver has reached some limit. 70 | 71 | BIT OUT srv-zero-speed 72 | motor has stopped 73 | 74 | S32 OUT srv-enc-raw 75 | raw value from motor encoder without offset calculation. This 76 | value is the unmodified one ad repoted by the motor driver. 77 | 78 | U32 OUT srv-pos-raw-hi 79 | Upper 32 bits of range extended 64 bit encoder value. This is a relative 80 | value wich is reset on restart/reset pin trigger. 81 | 82 | U32 OUT srv-pos-raw-lo 83 | Lower 32 bits of range extended 64 bit encoder value. This is a relative 84 | value wich is reset on restart/reset pin trigger. 85 | 86 | FLOAT OUT srv-pos-fb 87 | Actual encoder position 88 | 89 | BIT OUT srv-on-home-neg 90 | Motor encoder is below virtual home switch position. (See parameter 91 | srv-home-raw) 92 | 93 | BIT OUT srv-on-home-pos 94 | Motor encoder is above virtual home switch position. (See parameter 95 | srv-home-raw) 96 | 97 | BIT IN srv-pos-reset 98 | Reset relative position counter (srv-pos-raw-hi/srv-pos-raw-lo) 99 | 100 | BIT IN srv-switch-on 101 | Switch motor driver on 102 | 103 | BIT IN srv-enable-volt 104 | Enable motor driver voltage 105 | 106 | BIT IN srv-quick-stop 107 | Enable motor quick stop 108 | 109 | BIT IN srv-enable 110 | Enable motor driver operation. This signal is internaly delayed 111 | until driver reports switched-on. 112 | 113 | BIT IN srv-fault-reset 114 | Reset motor driver error 115 | 116 | BIT IN srv-fault-autoreset 117 | If set to 1 errors get automatically reset if drive is disabled (enable = 0) 118 | 119 | BIT IN srv-halt 120 | Set motor driver halt flag 121 | 122 | FLOAT IN srv-vel-cmd 123 | Velocity command input in scale units per second. 124 | 125 | Parameters: 126 | RW FLOAT srv-pos-scale 127 | Scale for position/velocity values (1.0 -> 1 revolution per second) 128 | 129 | RW S32 srv-home-raw 130 | Absolute position of virtual home switch. This could be used to implement 131 | a home switch on motors with abolute encoders without a hardware switch. 132 | 133 | #############################################################################*/ 134 | 135 | #ifndef _LCEC_DEASDA_H_ 136 | #define _LCEC_DEASDA_H_ 137 | 138 | #include "lcec.h" 139 | 140 | #define LCEC_DEASDA_VID LCEC_DELTA_VID 141 | #define LCEC_DEASDA_PID 0x10305070 142 | 143 | #define LCEC_DEASDA_PDOS 6 144 | 145 | int lcec_deasda_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 146 | 147 | #endif 148 | 149 | -------------------------------------------------------------------------------- /src/lcec_dems300.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2021 Dominik Braun 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | /*############################################################################# 20 | 21 | Description of Pins/Parameters: 22 | 23 | Pins: 24 | FLOAT OUT vel-fb-rpm 25 | Actual velocity feddback in revolutions per minute. 26 | 27 | FLOAT OUT vel-fb-rpm-abs 28 | Actual absolute value of velocity feddback in 29 | revolutions per minute. 30 | 31 | FLOAT IN vel-rpm-cmd 32 | Current velocity command send to motor driver in 33 | revolutions per minute. 34 | 35 | BIT OUT stat-switch-on-ready 36 | ready statusword flag from motor driver 37 | 38 | BIT OUT stat-switched-on 39 | switched-on statusword flag from motor driver 40 | 41 | BIT OUT stat-op-enabled 42 | operation-enabled statusword flag from motor driver 43 | 44 | BIT OUT stat-fault 45 | fault statusword flag from motor driver 46 | 47 | BIT OUT stat-volt-enabled 48 | voltage-enabled statusword flag from motor driver 49 | 50 | BIT OUT stat-quick-stoped 51 | quick-stoped statusword flag from motor driver 52 | 53 | BIT OUT stat-switch-on-disabled 54 | switch-on-disabled statusword flag from motor driver 55 | 56 | BIT OUT stat-warning 57 | warning statusword flag from motor driver 58 | 59 | BIT OUT stat-remote 60 | motor driver is remote controlled statusword flag 61 | 62 | BIT OUT stat-at-speed 63 | motor has reached requested velocity 64 | 65 | 66 | BIT IN enable 67 | Switch motor driver on 68 | 69 | BIT IN quick-stop 70 | Enable controlword motor quick stop 71 | 72 | BIT IN fault-reset 73 | Reset motor driver error 74 | 75 | BIT IN halt 76 | Set controlword driver halt flag 77 | 78 | 79 | Parameters: 80 | BIT IN auto-fault-reset 81 | If set to 1 errors get automatically reset if drive is enabled again (enable = 0 -> 1) 82 | 83 | 84 | #############################################################################*/ 85 | 86 | #ifndef _LCEC_DEMS300_H_ 87 | #define _LCEC_DEMS300_H_ 88 | 89 | #include "lcec.h" 90 | 91 | #define LCEC_DEMS300_VID LCEC_DELTA_VID 92 | #define LCEC_DEMS300_PID 0x10400200 93 | 94 | #define LCEC_DEMS300_PDOS 11 95 | 96 | int lcec_dems300_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /src/lcec_ek1100.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EK1100_H_ 19 | #define _LCEC_EK1100_H_ 20 | 21 | #define LCEC_EK1100_VID LCEC_BECKHOFF_VID 22 | #define LCEC_EK1100_PID 0x044C2C52 23 | #define LCEC_EK1100_PDOS 0 24 | 25 | #define LCEC_EK1101_VID LCEC_BECKHOFF_VID 26 | #define LCEC_EK1101_PID 0x044D2C52 27 | #define LCEC_EK1101_PDOS 0 28 | 29 | #define LCEC_EK1110_VID LCEC_BECKHOFF_VID 30 | #define LCEC_EK1110_PID 0x04562C52 31 | #define LCEC_EK1110_PDOS 0 32 | 33 | #define LCEC_EK1122_VID LCEC_BECKHOFF_VID 34 | #define LCEC_EK1122_PID 0x04622C52 35 | #define LCEC_EK1122_PDOS 0 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /src/lcec_el1252.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Claudio lorini 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | #ifndef _LCEC_EL1252_H_ 20 | #define _LCEC_EL1252_H_ 21 | 22 | /** \brief Product Code */ 23 | #define LCEC_EL1252_PID 0x04E43052 24 | 25 | /** \brief Number of channels */ 26 | #define LCEC_EL1252_CHANS 2 27 | 28 | /** \brief Number of PDO */ 29 | #define LCEC_EL1252_PDOS (4 * LCEC_EL1252_CHANS ) 30 | 31 | /** \brief Vendor ID */ 32 | #define LCEC_EL1252_VID LCEC_BECKHOFF_VID 33 | 34 | int lcec_el1252_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_el1859.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el1859.h" 21 | 22 | typedef struct { 23 | hal_bit_t *in; 24 | hal_bit_t *in_not; 25 | hal_bit_t *out; 26 | hal_bit_t invert; 27 | unsigned int pdo_in_os; 28 | unsigned int pdo_in_bp; 29 | unsigned int pdo_out_os; 30 | unsigned int pdo_out_bp; 31 | 32 | } lcec_el1859_pin_t; 33 | 34 | static const lcec_pindesc_t slave_pins[] = { 35 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1859_pin_t, in), "%s.%s.%s.din-%d" }, 36 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1859_pin_t, in_not), "%s.%s.%s.din-%d-not" }, 37 | { HAL_BIT, HAL_IN, offsetof(lcec_el1859_pin_t, out), "%s.%s.%s.dout-%d" }, 38 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 39 | }; 40 | 41 | static const lcec_pindesc_t slave_params[] = { 42 | { HAL_BIT, HAL_RW, offsetof(lcec_el1859_pin_t, invert), "%s.%s.%s.dout-%d-invert" }, 43 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 44 | }; 45 | 46 | 47 | void lcec_el1859_read(struct lcec_slave *slave, long period); 48 | void lcec_el1859_write(struct lcec_slave *slave, long period); 49 | 50 | int lcec_el1859_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 51 | lcec_master_t *master = slave->master; 52 | lcec_el1859_pin_t *hal_data; 53 | lcec_el1859_pin_t *pin; 54 | int i; 55 | int err; 56 | 57 | // initialize callbacks 58 | slave->proc_read = lcec_el1859_read; 59 | slave->proc_write = lcec_el1859_write; 60 | 61 | // alloc hal memory 62 | if ((hal_data = hal_malloc(sizeof(lcec_el1859_pin_t) * LCEC_EL1859_PINS)) == NULL) { 63 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 64 | return -EIO; 65 | } 66 | memset(hal_data, 0, sizeof(lcec_el1859_pin_t) * LCEC_EL1859_PINS); 67 | slave->hal_data = hal_data; 68 | 69 | // initialize pins 70 | for (i=0, pin=hal_data; iindex, slave->vid, slave->pid, 0x6000 + (i << 4), 0x01, &pin->pdo_in_os, &pin->pdo_in_bp); 73 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7080 + (i << 4), 0x01, &pin->pdo_out_os, &pin->pdo_out_bp); 74 | 75 | // export pins 76 | if ((err = lcec_pin_newf_list(pin, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 77 | return err; 78 | } 79 | 80 | // export parameters 81 | if ((err = lcec_param_newf_list(pin, slave_params, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 82 | return err; 83 | } 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | void lcec_el1859_read(struct lcec_slave *slave, long period) { 90 | lcec_master_t *master = slave->master; 91 | lcec_el1859_pin_t *hal_data = (lcec_el1859_pin_t *) slave->hal_data; 92 | uint8_t *pd = master->process_data; 93 | lcec_el1859_pin_t *pin; 94 | int i, s; 95 | 96 | // wait for slave to be operational 97 | if (!slave->state.operational) { 98 | return; 99 | } 100 | 101 | // check inputs 102 | for (i=0, pin=hal_data; ipdo_in_os], pin->pdo_in_bp); 104 | *(pin->in) = s; 105 | *(pin->in_not) = !s; 106 | } 107 | } 108 | 109 | void lcec_el1859_write(struct lcec_slave *slave, long period) { 110 | lcec_master_t *master = slave->master; 111 | lcec_el1859_pin_t *hal_data = (lcec_el1859_pin_t *) slave->hal_data; 112 | uint8_t *pd = master->process_data; 113 | lcec_el1859_pin_t *pin; 114 | int i, s; 115 | 116 | // set outputs 117 | for (i=0, pin=hal_data; iout); 119 | if (pin->invert) { 120 | s = !s; 121 | } 122 | EC_WRITE_BIT(&pd[pin->pdo_out_os], pin->pdo_out_bp, s); 123 | } 124 | } 125 | 126 | -------------------------------------------------------------------------------- /src/lcec_el1859.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL1859_H_ 19 | #define _LCEC_EL1859_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL1859_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL1859_PID 0x07433052 26 | 27 | #define LCEC_EL1859_PINS 8 28 | #define LCEC_EL1859_PDOS (2 * LCEC_EL1859_PINS) 29 | 30 | int lcec_el1859_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /src/lcec_el1904.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el1904.h" 21 | 22 | typedef struct { 23 | hal_bit_t *fsoe_in; 24 | hal_bit_t *fsoe_in_not; 25 | 26 | unsigned int fsoe_in_os; 27 | unsigned int fsoe_in_bp; 28 | } lcec_el1904_data_in_t; 29 | 30 | typedef struct { 31 | hal_u32_t *fsoe_master_cmd; 32 | hal_u32_t *fsoe_master_crc; 33 | hal_u32_t *fsoe_master_connid; 34 | 35 | hal_u32_t *fsoe_slave_cmd; 36 | hal_u32_t *fsoe_slave_crc; 37 | hal_u32_t *fsoe_slave_connid; 38 | 39 | lcec_el1904_data_in_t inputs[LCEC_EL1904_INPUT_COUNT]; 40 | 41 | unsigned int fsoe_master_cmd_os; 42 | unsigned int fsoe_master_crc_os; 43 | unsigned int fsoe_master_connid_os; 44 | 45 | unsigned int fsoe_slave_cmd_os; 46 | unsigned int fsoe_slave_crc_os; 47 | unsigned int fsoe_slave_connid_os; 48 | 49 | } lcec_el1904_data_t; 50 | 51 | static const lcec_pindesc_t slave_pins[] = { 52 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_master_cmd), "%s.%s.%s.fsoe-master-cmd" }, 53 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_master_crc), "%s.%s.%s.fsoe-master-crc" }, 54 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_master_connid), "%s.%s.%s.fsoe-master-connid" }, 55 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_slave_cmd), "%s.%s.%s.fsoe-slave-cmd" }, 56 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_slave_crc), "%s.%s.%s.fsoe-slave-crc" }, 57 | { HAL_U32, HAL_OUT, offsetof(lcec_el1904_data_t, fsoe_slave_connid), "%s.%s.%s.fsoe-slave-connid" }, 58 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 59 | }; 60 | 61 | static const lcec_pindesc_t slave_in_pins[] = { 62 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1904_data_in_t, fsoe_in), "%s.%s.%s.fsoe-in-%d" }, 63 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1904_data_in_t, fsoe_in_not), "%s.%s.%s.fsoe-in-%d-not" }, 64 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 65 | }; 66 | 67 | static const LCEC_CONF_FSOE_T fsoe_conf = { 68 | .slave_data_len = 1, 69 | .master_data_len = 1, 70 | .data_channels = 1 71 | }; 72 | 73 | void lcec_el1904_read(struct lcec_slave *slave, long period); 74 | 75 | int lcec_el1904_preinit(struct lcec_slave *slave) { 76 | // set fsoe config 77 | slave->fsoeConf = &fsoe_conf; 78 | 79 | return 0; 80 | } 81 | 82 | int lcec_el1904_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 83 | lcec_master_t *master = slave->master; 84 | lcec_el1904_data_t *hal_data; 85 | int i, err; 86 | lcec_el1904_data_in_t *in; 87 | 88 | // initialize callbacks 89 | slave->proc_read = lcec_el1904_read; 90 | 91 | // alloc hal memory 92 | if ((hal_data = hal_malloc(sizeof(lcec_el1904_data_t))) == NULL) { 93 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 94 | return -EIO; 95 | } 96 | memset(hal_data, 0, sizeof(lcec_el1904_data_t)); 97 | slave->hal_data = hal_data; 98 | 99 | // initialize POD entries 100 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000, 0x01, &hal_data->fsoe_master_cmd_os, NULL); 101 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000, 0x02, &hal_data->fsoe_master_crc_os, NULL); 102 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000, 0x03, &hal_data->fsoe_master_connid_os, NULL); 103 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000, 0x01, &hal_data->fsoe_slave_cmd_os, NULL); 104 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000, 0x03, &hal_data->fsoe_slave_crc_os, NULL); 105 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000, 0x04, &hal_data->fsoe_slave_connid_os, NULL); 106 | for (i = 0, in = hal_data->inputs; i < LCEC_EL1904_INPUT_COUNT; i++, in++) { 107 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6001, 0x01 + i, &in->fsoe_in_os, &in->fsoe_in_bp); 108 | } 109 | 110 | // export pins 111 | if ((err = lcec_pin_newf_list(hal_data, slave_pins, LCEC_MODULE_NAME, master->name, slave->name)) != 0) { 112 | return err; 113 | } 114 | for (i = 0, in = hal_data->inputs; i < LCEC_EL1904_INPUT_COUNT; i++, in++) { 115 | if ((err = lcec_pin_newf_list(in, slave_in_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 116 | return err; 117 | } 118 | } 119 | 120 | return 0; 121 | } 122 | 123 | void lcec_el1904_read(struct lcec_slave *slave, long period) { 124 | lcec_master_t *master = slave->master; 125 | lcec_el1904_data_t *hal_data = (lcec_el1904_data_t *) slave->hal_data; 126 | uint8_t *pd = master->process_data; 127 | int i; 128 | lcec_el1904_data_in_t *in; 129 | 130 | copy_fsoe_data(slave, hal_data->fsoe_slave_cmd_os, hal_data->fsoe_master_cmd_os); 131 | 132 | *(hal_data->fsoe_slave_cmd) = EC_READ_U8(&pd[hal_data->fsoe_slave_cmd_os]); 133 | *(hal_data->fsoe_slave_crc) = EC_READ_U16(&pd[hal_data->fsoe_slave_crc_os]); 134 | *(hal_data->fsoe_slave_connid) = EC_READ_U16(&pd[hal_data->fsoe_slave_connid_os]); 135 | 136 | *(hal_data->fsoe_master_cmd) = EC_READ_U8(&pd[hal_data->fsoe_master_cmd_os]); 137 | *(hal_data->fsoe_master_crc) = EC_READ_U16(&pd[hal_data->fsoe_master_crc_os]); 138 | *(hal_data->fsoe_master_connid) = EC_READ_U16(&pd[hal_data->fsoe_master_connid_os]); 139 | 140 | for (i = 0, in = hal_data->inputs; i < LCEC_EL1904_INPUT_COUNT; i++, in++) { 141 | *(in->fsoe_in) = EC_READ_BIT(&pd[in->fsoe_in_os], in->fsoe_in_bp); 142 | *(in->fsoe_in_not) = ! *(in->fsoe_in); 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /src/lcec_el1904.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL1904_H_ 19 | #define _LCEC_EL1904_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL1904_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL1904_PID 0x07703052 26 | 27 | #define LCEC_EL1904_INPUT_COUNT 4 28 | 29 | #define LCEC_EL1904_PDOS (6 + LCEC_EL1904_INPUT_COUNT * 1) 30 | 31 | int lcec_el1904_preinit(struct lcec_slave *slave); 32 | int lcec_el1904_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/lcec_el1918_logic.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2021 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL1918_LOGIC_H_ 19 | #define _LCEC_EL1918_LOGIC_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL1918_LOGIC_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL1918_LOGIC_PID 0x077e3052 25 | 26 | #define LCEC_EL1918_LOGIC_PDOS 2 27 | #define LCEC_EL1918_LOGIC_STDIN_PDOS 1 28 | #define LCEC_EL1918_LOGIC_STDOUT_PDOS 1 29 | 30 | #define LCEC_EL1918_LOGIC_PARAM_SLAVEID 1 31 | #define LCEC_EL1918_LOGIC_PARAM_STDIN_NAME 2 32 | #define LCEC_EL1918_LOGIC_PARAM_STDOUT_NAME 3 33 | 34 | #define LCEC_EL1918_LOGIC_PARAM_SLAVE_PDOS 4 35 | #define LCEC_EL1918_LOGIC_PARAM_SLAVE_CH_PDOS 2 36 | 37 | #define LCEC_EL1918_LOGIC_DIO_MAX_COUNT 8 38 | 39 | int lcec_el1918_logic_preinit(struct lcec_slave *slave); 40 | int lcec_el1918_logic_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /src/lcec_el1xxx.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el1xxx.h" 21 | 22 | typedef struct { 23 | hal_bit_t *in; 24 | hal_bit_t *in_not; 25 | unsigned int pdo_os; 26 | unsigned int pdo_bp; 27 | } lcec_el1xxx_pin_t; 28 | 29 | static const lcec_pindesc_t slave_pins[] = { 30 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1xxx_pin_t, in), "%s.%s.%s.din-%d" }, 31 | { HAL_BIT, HAL_OUT, offsetof(lcec_el1xxx_pin_t, in_not), "%s.%s.%s.din-%d-not" }, 32 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 33 | }; 34 | 35 | void lcec_el1xxx_read(struct lcec_slave *slave, long period); 36 | 37 | int lcec_el1xxx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 38 | lcec_master_t *master = slave->master; 39 | lcec_el1xxx_pin_t *hal_data; 40 | lcec_el1xxx_pin_t *pin; 41 | int i; 42 | int err; 43 | 44 | // initialize callbacks 45 | slave->proc_read = lcec_el1xxx_read; 46 | 47 | // alloc hal memory 48 | if ((hal_data = hal_malloc(sizeof(lcec_el1xxx_pin_t) * slave->pdo_entry_count)) == NULL) { 49 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 50 | return -EIO; 51 | } 52 | memset(hal_data, 0, sizeof(lcec_el1xxx_pin_t) * slave->pdo_entry_count); 53 | slave->hal_data = hal_data; 54 | 55 | // initialize pins 56 | for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { 57 | // initialize POD entry 58 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x01, &pin->pdo_os, &pin->pdo_bp); 59 | 60 | // export pins 61 | if ((err = lcec_pin_newf_list(pin, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 62 | return err; 63 | } 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | void lcec_el1xxx_read(struct lcec_slave *slave, long period) { 70 | lcec_master_t *master = slave->master; 71 | lcec_el1xxx_pin_t *hal_data = (lcec_el1xxx_pin_t *) slave->hal_data; 72 | uint8_t *pd = master->process_data; 73 | lcec_el1xxx_pin_t *pin; 74 | int i, s; 75 | 76 | // wait for slave to be operational 77 | if (!slave->state.operational) { 78 | return; 79 | } 80 | 81 | // check inputs 82 | for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { 83 | s = EC_READ_BIT(&pd[pin->pdo_os], pin->pdo_bp); 84 | *(pin->in) = s; 85 | *(pin->in_not) = !s; 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/lcec_el1xxx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL1XXX_H_ 19 | #define _LCEC_EL1XXX_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL1xxx_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL1002_PID 0x03EA3052 26 | #define LCEC_EL1004_PID 0x03EC3052 27 | #define LCEC_EL1008_PID 0x03F03052 28 | #define LCEC_EL1012_PID 0x03F43052 29 | #define LCEC_EL1014_PID 0x03F63052 30 | #define LCEC_EL1018_PID 0x03FA3052 31 | #define LCEC_EL1024_PID 0x04003052 32 | #define LCEC_EL1034_PID 0x040A3052 33 | #define LCEC_EL1084_PID 0x043C3052 34 | #define LCEC_EL1088_PID 0x04403052 35 | #define LCEC_EL1094_PID 0x04463052 36 | #define LCEC_EL1098_PID 0x044A3052 37 | #define LCEC_EL1104_PID 0x04503052 38 | #define LCEC_EL1114_PID 0x045A3052 39 | #define LCEC_EL1124_PID 0x04643052 40 | #define LCEC_EL1134_PID 0x046E3052 41 | #define LCEC_EL1144_PID 0x04783052 42 | #define LCEC_EL1808_PID 0x07103052 43 | #define LCEC_EL1809_PID 0x07113052 44 | #define LCEC_EL1819_PID 0x071B3052 45 | 46 | #define LCEC_EL1002_PDOS 2 47 | #define LCEC_EL1004_PDOS 4 48 | #define LCEC_EL1008_PDOS 8 49 | #define LCEC_EL1012_PDOS 2 50 | #define LCEC_EL1014_PDOS 4 51 | #define LCEC_EL1018_PDOS 8 52 | #define LCEC_EL1024_PDOS 4 53 | #define LCEC_EL1034_PDOS 4 54 | #define LCEC_EL1084_PDOS 4 55 | #define LCEC_EL1088_PDOS 8 56 | #define LCEC_EL1094_PDOS 4 57 | #define LCEC_EL1098_PDOS 8 58 | #define LCEC_EL1104_PDOS 4 59 | #define LCEC_EL1114_PDOS 4 60 | #define LCEC_EL1124_PDOS 4 61 | #define LCEC_EL1134_PDOS 4 62 | #define LCEC_EL1144_PDOS 4 63 | #define LCEC_EL1808_PDOS 8 64 | #define LCEC_EL1809_PDOS 16 65 | #define LCEC_EL1819_PDOS 16 66 | 67 | int lcec_el1xxx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /src/lcec_el2202.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Claudio lorini 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | 20 | /** \brief Linuxcnc and Machinekit HAL driver for Beckhoff EL2202 21 | 2-channel fast digital output terminal with tri-state. 22 | \details Voltage on Output terminal is controlled by the Output hal pin, 23 | if the Tristate hal pin is activated the output value is placed in high 24 | impedence status. 25 | http://www.beckhoff.com/english.asp?EtherCAT/el2202.htm%20 */ 26 | 27 | #include "lcec.h" 28 | #include "lcec_el2202.h" 29 | 30 | /* Master 0, Slave 2, "EL2202" 31 | * Vendor ID: 0x00000002 32 | * Product code: 0x089a3052 33 | * Revision number: 0x00100000 34 | */ 35 | 36 | /** \brief channels PDOs Index, SubIndex, size in bit */ 37 | ec_pdo_entry_info_t lcec_el2202_ch1_out[] = { 38 | {0x7000, 0x01, 1}, /* Output */ 39 | {0x7000, 0x02, 1}, /* TriState */ 40 | }; 41 | ec_pdo_entry_info_t lcec_el2202_ch2_out[] = { 42 | {0x7010, 0x01, 1}, /* Output */ 43 | {0x7010, 0x02, 1}, /* TriState */ 44 | }; 45 | 46 | /** \brief PDOs of the EL2202 */ 47 | ec_pdo_info_t lcec_el2202_pdos[] = { 48 | {0x1600, 2, lcec_el2202_ch1_out}, /* Channel 1 */ 49 | {0x1601, 2, lcec_el2202_ch2_out}, /* Channel 2 */ 50 | }; 51 | 52 | ec_sync_info_t lcec_el2202_syncs[] = { 53 | {0, EC_DIR_OUTPUT, 2, lcec_el2202_pdos, EC_WD_ENABLE}, 54 | {0xff} 55 | }; 56 | 57 | /** \brief data structure of each channel */ 58 | typedef struct { 59 | // data exposed as PIN to Linuxcnc/Machinekit 60 | hal_bit_t *out; 61 | hal_bit_t *tristate; 62 | // OffSets and BitPositions used to access data in EC PDOs 63 | unsigned int out_offs; 64 | unsigned int out_bitp; 65 | unsigned int tristate_offs; 66 | unsigned int tristate_bitp; 67 | } lcec_el2202_chan_t; 68 | 69 | /** \brief complete data structure for EL2202 */ 70 | typedef struct { 71 | lcec_el2202_chan_t chans[LCEC_EL2202_CHANS]; 72 | } lcec_el2202_data_t; 73 | 74 | static const lcec_pindesc_t slave_pins[] = { 75 | { HAL_BIT, HAL_IN, offsetof(lcec_el2202_chan_t, out), "%s.%s.%s.dout-%d" }, 76 | { HAL_BIT, HAL_IN, offsetof(lcec_el2202_chan_t, tristate), "%s.%s.%s.tristate-%d" }, 77 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 78 | }; 79 | 80 | /** \brief callback for periodic IO data access*/ 81 | void lcec_el2202_write(struct lcec_slave *slave, long period); 82 | 83 | int lcec_el2202_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 84 | lcec_master_t *master = slave->master; 85 | 86 | lcec_el2202_data_t *hal_data; 87 | lcec_el2202_chan_t *chan; 88 | 89 | int i; 90 | int err; 91 | 92 | // initialize callbacks 93 | slave->proc_write = lcec_el2202_write; 94 | 95 | // alloc hal memory 96 | if ((hal_data = hal_malloc(sizeof(lcec_el2202_data_t))) == NULL) { 97 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 98 | return -EIO; 99 | } 100 | memset(hal_data, 0, sizeof(lcec_el2202_data_t)); 101 | slave->hal_data = hal_data; 102 | 103 | // initializer sync info 104 | slave->sync_info = lcec_el2202_syncs; 105 | 106 | // initialize pins 107 | for (i=0; ichans[i]; 109 | 110 | // initialize PDO entries position vend.id prod.code index sindx offset bit pos 111 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000 + (i << 4), 0x01, &chan->out_offs, &chan->out_bitp); 112 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000 + (i << 4), 0x02, &chan->tristate_offs, &chan->tristate_bitp); 113 | 114 | // export pins 115 | if ((err = lcec_pin_newf_list(chan, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 116 | return err; 117 | } 118 | } 119 | 120 | return 0; 121 | } 122 | 123 | void lcec_el2202_write(struct lcec_slave *slave, long period) { 124 | lcec_master_t *master = slave->master; 125 | uint8_t *pd = master->process_data; 126 | 127 | lcec_el2202_data_t *hal_data = (lcec_el2202_data_t *) slave->hal_data; 128 | lcec_el2202_chan_t *chan; 129 | 130 | int i; 131 | 132 | for (i=0; ichans[i]; 134 | 135 | // set output 136 | EC_WRITE_BIT(&pd[chan->out_offs], chan->out_bitp, *(chan->out)); 137 | // set tristate 138 | EC_WRITE_BIT(&pd[chan->tristate_offs], chan->tristate_bitp, *(chan->tristate)); 139 | } 140 | } 141 | 142 | -------------------------------------------------------------------------------- /src/lcec_el2202.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Claudio lorini 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | #ifndef _LCEC_EL2202_H_ 20 | #define _LCEC_EL2202_H_ 21 | 22 | /** \brief Product Code */ 23 | #define LCEC_EL2202_PID 0x089A3052 24 | 25 | /** \brief Number of channels */ 26 | #define LCEC_EL2202_CHANS 2 27 | 28 | /** \brief Number of PDO */ 29 | #define LCEC_EL2202_PDOS (2 * LCEC_EL2202_CHANS) 30 | 31 | /** \brief Vendor ID */ 32 | #define LCEC_EL2202_VID LCEC_BECKHOFF_VID 33 | 34 | int lcec_el2202_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_el2521.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL2521_H_ 19 | #define _LCEC_EL2521_H_ 20 | 21 | // **************************************************************************** 22 | // CONFIG ISSUES: 23 | // - sign/amount representation (8000:04) must be FALSE (0x00, default) 24 | // - ramp function (8000:06) need to be active (0x01, default), can be disabled by hal pin 25 | // - direct input mode (8000:08) must be FALSE (0x00, default) 26 | // - travel distance control active (8000:0A) must be FALSE (0x00, default) 27 | // **************************************************************************** 28 | 29 | #include "lcec.h" 30 | 31 | #define LCEC_EL2521_VID LCEC_BECKHOFF_VID 32 | #define LCEC_EL2521_PID 0x09d93052 33 | 34 | #define LCEC_EL2521_PDOS 4 35 | 36 | int lcec_el2521_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /src/lcec_el2904.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL2904_H_ 19 | #define _LCEC_EL2904_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL2904_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL2904_PID 0x0B583052 26 | 27 | #define LCEC_EL2904_PDOS 14 28 | 29 | int lcec_el2904_preinit(struct lcec_slave *slave); 30 | int lcec_el2904_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /src/lcec_el2xxx.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el2xxx.h" 21 | 22 | typedef struct { 23 | hal_bit_t *out; 24 | hal_bit_t invert; 25 | unsigned int pdo_os; 26 | unsigned int pdo_bp; 27 | } lcec_el2xxx_pin_t; 28 | 29 | void lcec_el2xxx_write(struct lcec_slave *slave, long period); 30 | 31 | int lcec_el2xxx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 32 | lcec_master_t *master = slave->master; 33 | lcec_el2xxx_pin_t *hal_data; 34 | lcec_el2xxx_pin_t *pin; 35 | int i; 36 | int err; 37 | 38 | // initialize callbacks 39 | slave->proc_write = lcec_el2xxx_write; 40 | 41 | // alloc hal memory 42 | if ((hal_data = hal_malloc(sizeof(lcec_el2xxx_pin_t) * slave->pdo_entry_count)) == NULL) { 43 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 44 | return -EIO; 45 | } 46 | memset(hal_data, 0, sizeof(lcec_el2xxx_pin_t) * slave->pdo_entry_count); 47 | slave->hal_data = hal_data; 48 | 49 | // initialize pins 50 | for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { 51 | // initialize POD entry 52 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000 + (i << 4), 0x01, &pin->pdo_os, &pin->pdo_bp); 53 | 54 | // export pins 55 | if ((err = lcec_pin_newf(HAL_BIT, HAL_IN, (void **) &(pin->out), "%s.%s.%s.dout-%d", LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 56 | return err; 57 | } 58 | if ((err = lcec_param_newf(HAL_BIT, HAL_RW, (void *) &(pin->invert), "%s.%s.%s.dout-%d-invert", LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 59 | return err; 60 | } 61 | 62 | // initialize pins 63 | *(pin->out) = 0; 64 | pin->invert = 0; 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | void lcec_el2xxx_write(struct lcec_slave *slave, long period) { 71 | lcec_master_t *master = slave->master; 72 | lcec_el2xxx_pin_t *hal_data = (lcec_el2xxx_pin_t *) slave->hal_data; 73 | uint8_t *pd = master->process_data; 74 | lcec_el2xxx_pin_t *pin; 75 | int i, s; 76 | 77 | // set outputs 78 | for (i=0, pin=hal_data; ipdo_entry_count; i++, pin++) { 79 | s = *(pin->out); 80 | if (pin->invert) { 81 | s = !s; 82 | } 83 | EC_WRITE_BIT(&pd[pin->pdo_os], pin->pdo_bp, s); 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/lcec_el2xxx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL2XXX_H_ 19 | #define _LCEC_EL2XXX_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL2xxx_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL2002_PID 0x07D23052 26 | #define LCEC_EL2004_PID 0x07D43052 27 | #define LCEC_EL2008_PID 0x07D83052 28 | #define LCEC_EL2022_PID 0x07E63052 29 | #define LCEC_EL2024_PID 0x07E83052 30 | #define LCEC_EL2032_PID 0x07F03052 31 | #define LCEC_EL2034_PID 0x07F23052 32 | #define LCEC_EL2042_PID 0x07FA3052 33 | #define LCEC_EL2084_PID 0x08243052 34 | #define LCEC_EL2088_PID 0x08283052 35 | #define LCEC_EL2124_PID 0x084C3052 36 | #define LCEC_EL2612_PID 0x0A343052 37 | #define LCEC_EL2622_PID 0x0A3E3052 38 | #define LCEC_EL2634_PID 0x0A4A3052 39 | #define LCEC_EL2652_PID 0x0A5C3052 40 | #define LCEC_EL2808_PID 0x0AF83052 41 | #define LCEC_EL2798_PID 0x0AEE3052 42 | #define LCEC_EL2809_PID 0x0AF93052 43 | #define LCEC_EP2008_PID 0x07D84052 44 | #define LCEC_EP2028_PID 0x07EC4052 45 | #define LCEC_EP2809_PID 0x0AF94052 46 | 47 | #define LCEC_EL2002_PDOS 2 48 | #define LCEC_EL2004_PDOS 4 49 | #define LCEC_EL2008_PDOS 8 50 | #define LCEC_EL2022_PDOS 2 51 | #define LCEC_EL2024_PDOS 4 52 | #define LCEC_EL2032_PDOS 2 53 | #define LCEC_EL2034_PDOS 4 54 | #define LCEC_EL2042_PDOS 2 55 | #define LCEC_EL2084_PDOS 4 56 | #define LCEC_EL2088_PDOS 8 57 | #define LCEC_EL2124_PDOS 4 58 | #define LCEC_EL2612_PDOS 2 59 | #define LCEC_EL2622_PDOS 2 60 | #define LCEC_EL2634_PDOS 4 61 | #define LCEC_EL2652_PDOS 2 62 | #define LCEC_EL2808_PDOS 8 63 | #define LCEC_EL2798_PDOS 8 64 | #define LCEC_EL2809_PDOS 16 65 | #define LCEC_EP2008_PDOS 8 66 | #define LCEC_EP2028_PDOS 8 67 | #define LCEC_EP2809_PDOS 16 68 | 69 | int lcec_el2xxx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /src/lcec_el31x2.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el31x2.h" 21 | 22 | typedef struct { 23 | hal_bit_t *error; 24 | hal_bit_t *overrange; 25 | hal_bit_t *underrange; 26 | hal_s32_t *raw_val; 27 | hal_float_t *scale; 28 | hal_float_t *bias; 29 | hal_float_t *val; 30 | unsigned int state_pdo_os; 31 | unsigned int val_pdo_os; 32 | } lcec_el31x2_chan_t; 33 | 34 | static const lcec_pindesc_t slave_pins[] = { 35 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x2_chan_t ,error), "%s.%s.%s.ain-%d-error" }, 36 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x2_chan_t ,overrange), "%s.%s.%s.ain-%d-overrange" }, 37 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x2_chan_t ,underrange), "%s.%s.%s.ain-%d-underrange" }, 38 | { HAL_S32, HAL_OUT, offsetof(lcec_el31x2_chan_t ,raw_val), "%s.%s.%s.ain-%d-raw" }, 39 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_el31x2_chan_t ,val), "%s.%s.%s.ain-%d-val" }, 40 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el31x2_chan_t ,scale), "%s.%s.%s.ain-%d-scale" }, 41 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el31x2_chan_t ,bias), "%s.%s.%s.ain-%d-bias" }, 42 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 43 | }; 44 | 45 | typedef struct { 46 | lcec_el31x2_chan_t chans[LCEC_EL31x2_CHANS]; 47 | } lcec_el31x2_data_t; 48 | 49 | static ec_pdo_entry_info_t lcec_el31x2_channel1[] = { 50 | {0x3101, 1, 8}, // status 51 | {0x3101, 2, 16} // value 52 | }; 53 | 54 | static ec_pdo_entry_info_t lcec_el31x2_channel2[] = { 55 | {0x3102, 1, 8}, // status 56 | {0x3102, 2, 16} // value 57 | }; 58 | 59 | static ec_pdo_info_t lcec_el31x2_pdos_in[] = { 60 | {0x1A00, 2, lcec_el31x2_channel1}, 61 | {0x1A01, 2, lcec_el31x2_channel2} 62 | }; 63 | 64 | static ec_sync_info_t lcec_el31x2_syncs[] = { 65 | {0, EC_DIR_OUTPUT, 0, NULL}, 66 | {1, EC_DIR_INPUT, 0, NULL}, 67 | {2, EC_DIR_OUTPUT, 0, NULL}, 68 | {3, EC_DIR_INPUT, 2, lcec_el31x2_pdos_in}, 69 | {0xff} 70 | }; 71 | 72 | void lcec_el31x2_read(struct lcec_slave *slave, long period); 73 | 74 | int lcec_el31x2_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 75 | lcec_master_t *master = slave->master; 76 | lcec_el31x2_data_t *hal_data; 77 | lcec_el31x2_chan_t *chan; 78 | int i; 79 | int err; 80 | 81 | // initialize callbacks 82 | slave->proc_read = lcec_el31x2_read; 83 | 84 | // alloc hal memory 85 | if ((hal_data = hal_malloc(sizeof(lcec_el31x2_data_t))) == NULL) { 86 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 87 | return -EIO; 88 | } 89 | memset(hal_data, 0, sizeof(lcec_el31x2_data_t)); 90 | slave->hal_data = hal_data; 91 | 92 | // initializer sync info 93 | slave->sync_info = lcec_el31x2_syncs; 94 | 95 | // initialize pins 96 | for (i=0; ichans[i]; 98 | 99 | // initialize POD entries 100 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x3101 + i, 0x01, &chan->state_pdo_os, NULL); 101 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x3101 + i, 0x02, &chan->val_pdo_os, NULL); 102 | 103 | // export pins 104 | if ((err = lcec_pin_newf_list(chan, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 105 | return err; 106 | } 107 | 108 | // initialize pins 109 | *(chan->scale) = 1.0; 110 | } 111 | 112 | return 0; 113 | } 114 | 115 | void lcec_el31x2_read(struct lcec_slave *slave, long period) { 116 | lcec_master_t *master = slave->master; 117 | lcec_el31x2_data_t *hal_data = (lcec_el31x2_data_t *) slave->hal_data; 118 | uint8_t *pd = master->process_data; 119 | int i; 120 | lcec_el31x2_chan_t *chan; 121 | uint8_t state; 122 | int16_t value; 123 | 124 | // wait for slave to be operational 125 | if (!slave->state.operational) { 126 | return; 127 | } 128 | 129 | // check inputs 130 | for (i=0; ichans[i]; 132 | 133 | // update state 134 | state = pd[chan->state_pdo_os]; 135 | *(chan->error) = (state >> 6) & 0x01; 136 | *(chan->overrange) = (state >> 1) & 0x01; 137 | *(chan->underrange) = (state >> 0) & 0x01; 138 | 139 | // update value 140 | value = EC_READ_S16(&pd[chan->val_pdo_os]); 141 | *(chan->raw_val) = value; 142 | *(chan->val) = *(chan->bias) + *(chan->scale) * (double)value * ((double)1/(double)0x7fff); 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /src/lcec_el31x2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL31X2_H_ 19 | #define _LCEC_EL31X2_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL31x2_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL3102_PID 0x0C1E3052 26 | #define LCEC_EL3112_PID 0x0C283052 27 | #define LCEC_EL3122_PID 0x0C323052 28 | #define LCEC_EL3142_PID 0x0C463052 29 | #define LCEC_EL3152_PID 0x0C503052 30 | #define LCEC_EL3162_PID 0x0C5A3052 31 | 32 | #define LCEC_EL31x2_PDOS 4 33 | 34 | #define LCEC_EL31x2_CHANS 2 35 | 36 | int lcec_el31x2_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /src/lcec_el31x4.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el31x4.h" 21 | 22 | typedef struct { 23 | hal_bit_t *overrange; 24 | hal_bit_t *underrange; 25 | hal_bit_t *error; 26 | hal_bit_t *sync_err; 27 | hal_s32_t *raw_val; 28 | hal_float_t *scale; 29 | hal_float_t *bias; 30 | hal_float_t *val; 31 | unsigned int ovr_pdo_os; 32 | unsigned int ovr_pdo_bp; 33 | unsigned int udr_pdo_os; 34 | unsigned int udr_pdo_bp; 35 | unsigned int error_pdo_os; 36 | unsigned int error_pdo_bp; 37 | unsigned int sync_err_pdo_os; 38 | unsigned int sync_err_pdo_bp; 39 | unsigned int val_pdo_os; 40 | } lcec_el31x4_chan_t; 41 | 42 | static const lcec_pindesc_t slave_pins[] = { 43 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x4_chan_t ,error), "%s.%s.%s.ain-%d-error" }, 44 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x4_chan_t ,sync_err), "%s.%s.%s.ain-%d-sync-err" }, 45 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x4_chan_t ,overrange), "%s.%s.%s.ain-%d-overrange" }, 46 | { HAL_BIT, HAL_OUT, offsetof(lcec_el31x4_chan_t ,underrange), "%s.%s.%s.ain-%d-underrange" }, 47 | { HAL_S32, HAL_OUT, offsetof(lcec_el31x4_chan_t ,raw_val), "%s.%s.%s.ain-%d-raw" }, 48 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_el31x4_chan_t ,val), "%s.%s.%s.ain-%d-val" }, 49 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el31x4_chan_t ,scale), "%s.%s.%s.ain-%d-scale" }, 50 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el31x4_chan_t ,bias), "%s.%s.%s.ain-%d-bias" }, 51 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 52 | }; 53 | 54 | typedef struct { 55 | lcec_el31x4_chan_t chans[LCEC_EL31x4_CHANS]; 56 | } lcec_el31x4_data_t; 57 | 58 | void lcec_el31x4_read(struct lcec_slave *slave, long period); 59 | 60 | int lcec_el31x4_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 61 | lcec_master_t *master = slave->master; 62 | lcec_el31x4_data_t *hal_data; 63 | lcec_el31x4_chan_t *chan; 64 | int i; 65 | int err; 66 | 67 | // initialize callbacks 68 | slave->proc_read = lcec_el31x4_read; 69 | 70 | // alloc hal memory 71 | if ((hal_data = hal_malloc(sizeof(lcec_el31x4_data_t))) == NULL) { 72 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 73 | return -EIO; 74 | } 75 | memset(hal_data, 0, sizeof(lcec_el31x4_data_t)); 76 | slave->hal_data = hal_data; 77 | 78 | // initialize pins 79 | for (i=0; ichans[i]; 81 | 82 | // initialize POD entries 83 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x01, &chan->udr_pdo_os, &chan->udr_pdo_bp); 84 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x02, &chan->ovr_pdo_os, &chan->ovr_pdo_bp); 85 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x07, &chan->error_pdo_os, &chan->error_pdo_bp); 86 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x0E, &chan->sync_err_pdo_os, &chan->sync_err_pdo_bp); 87 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x11, &chan->val_pdo_os, NULL); 88 | 89 | // export pins 90 | if ((err = lcec_pin_newf_list(chan, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 91 | return err; 92 | } 93 | 94 | // initialize pins 95 | *(chan->scale) = 1.0; 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | void lcec_el31x4_read(struct lcec_slave *slave, long period) { 102 | lcec_master_t *master = slave->master; 103 | lcec_el31x4_data_t *hal_data = (lcec_el31x4_data_t *) slave->hal_data; 104 | uint8_t *pd = master->process_data; 105 | int i; 106 | lcec_el31x4_chan_t *chan; 107 | int16_t value; 108 | 109 | // wait for slave to be operational 110 | if (!slave->state.operational) { 111 | return; 112 | } 113 | 114 | // check inputs 115 | for (i=0; ichans[i]; 117 | 118 | // update state 119 | // update state 120 | *(chan->overrange) = EC_READ_BIT(&pd[chan->ovr_pdo_os], chan->ovr_pdo_bp); 121 | *(chan->underrange) = EC_READ_BIT(&pd[chan->udr_pdo_os], chan->udr_pdo_bp); 122 | *(chan->error) = EC_READ_BIT(&pd[chan->error_pdo_os], chan->error_pdo_bp); 123 | *(chan->sync_err) = EC_READ_BIT(&pd[chan->sync_err_pdo_os], chan->sync_err_pdo_bp); 124 | 125 | // update value 126 | value = EC_READ_S16(&pd[chan->val_pdo_os]); 127 | *(chan->raw_val) = value; 128 | *(chan->val) = *(chan->bias) + *(chan->scale) * (double)value * ((double)1/(double)0x7fff); 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/lcec_el31x4.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL31X4_H_ 19 | #define _LCEC_EL31X4_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL31x4_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL3164_PID 0x0C5C3052 26 | 27 | #define LCEC_EL31x4_CHANS 4 28 | 29 | #define LCEC_EL31x4_PDOS (5 * LCEC_EL31x4_CHANS) 30 | 31 | int lcec_el31x4_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /src/lcec_el3255.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2016 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL3255_H_ 19 | #define _LCEC_EL3255_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL3255_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL3255_PID 0x0CB73052 25 | 26 | #define LCEC_EL3255_CHANS 5 27 | #define LCEC_EL3255_PDOS (LCEC_EL3255_CHANS * 5) 28 | 29 | int lcec_el3255_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/lcec_el32x4.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2024 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el32x4.h" 21 | 22 | typedef struct { 23 | hal_bit_t *overrange; 24 | hal_bit_t *underrange; 25 | hal_bit_t *error; 26 | hal_bit_t *tx_state; 27 | hal_bit_t *tx_toggle; 28 | hal_s32_t *raw_val; 29 | hal_float_t *scale; 30 | hal_float_t *bias; 31 | hal_float_t *val; 32 | unsigned int ovr_pdo_os; 33 | unsigned int ovr_pdo_bp; 34 | unsigned int udr_pdo_os; 35 | unsigned int udr_pdo_bp; 36 | unsigned int error_pdo_os; 37 | unsigned int error_pdo_bp; 38 | unsigned int tx_state_pdo_os; 39 | unsigned int tx_state_pdo_bp; 40 | unsigned int tx_toggle_pdo_os; 41 | unsigned int tx_toggle_pdo_bp; 42 | unsigned int val_pdo_os; 43 | } lcec_el32x4_chan_t; 44 | 45 | static const lcec_pindesc_t slave_pins[] = { 46 | { HAL_BIT, HAL_OUT, offsetof(lcec_el32x4_chan_t, error), "%s.%s.%s.ain-%d-error" }, 47 | { HAL_BIT, HAL_OUT, offsetof(lcec_el32x4_chan_t, overrange), "%s.%s.%s.ain-%d-overrange" }, 48 | { HAL_BIT, HAL_OUT, offsetof(lcec_el32x4_chan_t, underrange), "%s.%s.%s.ain-%d-underrange" }, 49 | { HAL_BIT, HAL_OUT, offsetof(lcec_el32x4_chan_t, tx_state), "%s.%s.%s.ain-%d-tx-state" }, 50 | { HAL_BIT, HAL_OUT, offsetof(lcec_el32x4_chan_t, tx_toggle), "%s.%s.%s.ain-%d-tx-toggle" }, 51 | { HAL_S32, HAL_OUT, offsetof(lcec_el32x4_chan_t, raw_val), "%s.%s.%s.ain-%d-raw" }, 52 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_el32x4_chan_t, val), "%s.%s.%s.ain-%d-val" }, 53 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el32x4_chan_t, scale), "%s.%s.%s.ain-%d-scale" }, 54 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el32x4_chan_t, bias), "%s.%s.%s.ain-%d-bias" }, 55 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 56 | }; 57 | 58 | typedef struct { 59 | lcec_el32x4_chan_t chans[LCEC_EL32x4_CHANS]; 60 | } lcec_el32x4_data_t; 61 | 62 | void lcec_el32x4_read(struct lcec_slave *slave, long period); 63 | 64 | int lcec_el32x4_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 65 | lcec_master_t *master = slave->master; 66 | lcec_el32x4_data_t *hal_data; 67 | lcec_el32x4_chan_t *chan; 68 | int i; 69 | int err; 70 | 71 | // initialize callbacks 72 | slave->proc_read = lcec_el32x4_read; 73 | 74 | // alloc hal memory 75 | if ((hal_data = hal_malloc(sizeof(lcec_el32x4_data_t))) == NULL) { 76 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 77 | return -EIO; 78 | } 79 | memset(hal_data, 0, sizeof(lcec_el32x4_data_t)); 80 | slave->hal_data = hal_data; 81 | 82 | // initialize pins 83 | for (i=0; ichans[i]; 85 | 86 | // initialize POD entries 87 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x01, &chan->udr_pdo_os, &chan->udr_pdo_bp); 88 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x02, &chan->ovr_pdo_os, &chan->ovr_pdo_bp); 89 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x07, &chan->error_pdo_os, &chan->error_pdo_bp); 90 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x0f, &chan->tx_state_pdo_os, &chan->tx_state_pdo_bp); 91 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x10, &chan->tx_toggle_pdo_os, &chan->tx_toggle_pdo_bp); 92 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000 + (i << 4), 0x11, &chan->val_pdo_os, NULL); 93 | 94 | // export pins 95 | if ((err = lcec_pin_newf_list(chan, slave_pins, LCEC_MODULE_NAME, master->name, slave->name, i)) != 0) { 96 | return err; 97 | } 98 | 99 | // initialize pins 100 | *(chan->scale) = 1.0; 101 | } 102 | 103 | return 0; 104 | } 105 | 106 | void lcec_el32x4_read(struct lcec_slave *slave, long period) { 107 | lcec_master_t *master = slave->master; 108 | lcec_el32x4_data_t *hal_data = (lcec_el32x4_data_t *) slave->hal_data; 109 | uint8_t *pd = master->process_data; 110 | int i; 111 | lcec_el32x4_chan_t *chan; 112 | int16_t value; 113 | 114 | // wait for slave to be operational 115 | if (!slave->state.operational) { 116 | return; 117 | } 118 | 119 | // check inputs 120 | for (i=0; ichans[i]; 122 | 123 | // update state 124 | // update state 125 | *(chan->overrange) = EC_READ_BIT(&pd[chan->ovr_pdo_os], chan->ovr_pdo_bp); 126 | *(chan->underrange) = EC_READ_BIT(&pd[chan->udr_pdo_os], chan->udr_pdo_bp); 127 | *(chan->error) = EC_READ_BIT(&pd[chan->error_pdo_os], chan->error_pdo_bp); 128 | *(chan->tx_state) = EC_READ_BIT(&pd[chan->tx_state_pdo_os], chan->tx_state_pdo_bp); 129 | *(chan->tx_toggle) = EC_READ_BIT(&pd[chan->tx_toggle_pdo_os], chan->tx_toggle_pdo_bp); 130 | 131 | // update value 132 | value = EC_READ_S16(&pd[chan->val_pdo_os]); 133 | *(chan->raw_val) = value; 134 | *(chan->val) = *(chan->bias) + *(chan->scale) * (double)value * 0.1; 135 | } 136 | } 137 | 138 | -------------------------------------------------------------------------------- /src/lcec_el32x4.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2024 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL32X4_H_ 19 | #define _LCEC_EL32X4_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL32x4_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL3204_PID 0x0C843052 26 | 27 | #define LCEC_EL32x4_CHANS 4 28 | 29 | #define LCEC_EL32x4_PDOS (6 * LCEC_EL32x4_CHANS) 30 | 31 | int lcec_el32x4_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /src/lcec_el40x1.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el40x1.h" 21 | 22 | typedef struct { 23 | hal_bit_t *pos; 24 | hal_bit_t *neg; 25 | hal_bit_t *enable; 26 | hal_bit_t *absmode; 27 | hal_float_t *value; 28 | hal_float_t *scale; 29 | hal_float_t *offset; 30 | double old_scale; 31 | double scale_recip; 32 | hal_float_t *min_dc; 33 | hal_float_t *max_dc; 34 | hal_float_t *curr_dc; 35 | hal_s32_t *raw_val; 36 | unsigned int val_pdo_os; 37 | } lcec_el40x1_data_t; 38 | 39 | static const lcec_pindesc_t slave_pins[] = { 40 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el40x1_data_t, scale), "%s.%s.%s.aout-scale" }, 41 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el40x1_data_t, offset), "%s.%s.%s.aout-offset" }, 42 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el40x1_data_t, min_dc), "%s.%s.%s.aout-min-dc" }, 43 | { HAL_FLOAT, HAL_IO, offsetof(lcec_el40x1_data_t, max_dc), "%s.%s.%s.aout-max-dc" }, 44 | { HAL_FLOAT, HAL_OUT, offsetof(lcec_el40x1_data_t, curr_dc), "%s.%s.%s.aout-curr-dc" }, 45 | { HAL_BIT, HAL_IN, offsetof(lcec_el40x1_data_t, enable), "%s.%s.%s.aout-enable" }, 46 | { HAL_BIT, HAL_IN, offsetof(lcec_el40x1_data_t, absmode), "%s.%s.%s.aout-absmode" }, 47 | { HAL_FLOAT, HAL_IN, offsetof(lcec_el40x1_data_t, value), "%s.%s.%s.aout-value" }, 48 | { HAL_S32, HAL_OUT, offsetof(lcec_el40x1_data_t, raw_val), "%s.%s.%s.aout-raw" }, 49 | { HAL_BIT, HAL_OUT, offsetof(lcec_el40x1_data_t, pos), "%s.%s.%s.aout-pos" }, 50 | { HAL_BIT, HAL_OUT, offsetof(lcec_el40x1_data_t, neg), "%s.%s.%s.aout-neg" }, 51 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 52 | }; 53 | 54 | 55 | static ec_pdo_entry_info_t lcec_el40x1_channel[] = { 56 | {0x7000, 1, 16} // output 57 | }; 58 | 59 | static ec_pdo_info_t lcec_el40x1_pdos_in[] = { 60 | {0x1600, 1, lcec_el40x1_channel}, 61 | }; 62 | 63 | static ec_sync_info_t lcec_el40x1_syncs[] = { 64 | {0, EC_DIR_OUTPUT, 0, NULL}, 65 | {1, EC_DIR_INPUT, 0, NULL}, 66 | {2, EC_DIR_OUTPUT, 1, lcec_el40x1_pdos_in}, 67 | {0xff} 68 | }; 69 | 70 | void lcec_el40x1_write(struct lcec_slave *slave, long period); 71 | 72 | int lcec_el40x1_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 73 | lcec_master_t *master = slave->master; 74 | lcec_el40x1_data_t *hal_data; 75 | int err; 76 | 77 | // initialize callbacks 78 | slave->proc_write = lcec_el40x1_write; 79 | 80 | // alloc hal memory 81 | if ((hal_data = hal_malloc(sizeof(lcec_el40x1_data_t))) == NULL) { 82 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 83 | return -EIO; 84 | } 85 | memset(hal_data, 0, sizeof(lcec_el40x1_data_t)); 86 | slave->hal_data = hal_data; 87 | 88 | // initializer sync info 89 | slave->sync_info = lcec_el40x1_syncs; 90 | 91 | // initialize POD entries 92 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x7000, 0x01, &hal_data->val_pdo_os, NULL); 93 | 94 | // export pins 95 | if ((err = lcec_pin_newf_list(hal_data, slave_pins, LCEC_MODULE_NAME, master->name, slave->name)) != 0) { 96 | return err; 97 | } 98 | 99 | // set default pin values 100 | *(hal_data->scale) = 1.0; 101 | *(hal_data->min_dc) = -1.0; 102 | *(hal_data->max_dc) = 1.0; 103 | 104 | // init other fields 105 | hal_data->old_scale = *(hal_data->scale) + 1.0; 106 | hal_data->scale_recip = 1.0; 107 | 108 | return 0; 109 | } 110 | 111 | void lcec_el40x1_write(struct lcec_slave *slave, long period) { 112 | lcec_master_t *master = slave->master; 113 | lcec_el40x1_data_t *hal_data = (lcec_el40x1_data_t *) slave->hal_data; 114 | uint8_t *pd = master->process_data; 115 | double tmpval, tmpdc, raw_val; 116 | 117 | // validate duty cycle limits, both limits must be between 118 | // 0.0 and 1.0 (inclusive) and max must be greater then min 119 | if (*(hal_data->max_dc) > 1.0) { 120 | *(hal_data->max_dc) = 1.0; 121 | } 122 | if (*(hal_data->min_dc) > *(hal_data->max_dc)) { 123 | *(hal_data->min_dc) = *(hal_data->max_dc); 124 | } 125 | if (*(hal_data->min_dc) < -1.0) { 126 | *(hal_data->min_dc) = -1.0; 127 | } 128 | if (*(hal_data->max_dc) < *(hal_data->min_dc)) { 129 | *(hal_data->max_dc) = *(hal_data->min_dc); 130 | } 131 | 132 | // do scale calcs only when scale changes 133 | if (*(hal_data->scale) != hal_data->old_scale) { 134 | // validate the new scale value 135 | if ((*(hal_data->scale) < 1e-20) && (*(hal_data->scale) > -1e-20)) { 136 | // value too small, divide by zero is a bad thing 137 | *(hal_data->scale) = 1.0; 138 | } 139 | // get ready to detect future scale changes 140 | hal_data->old_scale = *(hal_data->scale); 141 | // we will need the reciprocal 142 | hal_data->scale_recip = 1.0 / *(hal_data->scale); 143 | } 144 | 145 | // get command 146 | tmpval = *(hal_data->value); 147 | if (*(hal_data->absmode) && (tmpval < 0)) { 148 | tmpval = -tmpval; 149 | } 150 | 151 | // convert value command to duty cycle 152 | tmpdc = tmpval * hal_data->scale_recip + *(hal_data->offset); 153 | if (tmpdc < *(hal_data->min_dc)) { 154 | tmpdc = *(hal_data->min_dc); 155 | } 156 | if (tmpdc > *(hal_data->max_dc)) { 157 | tmpdc = *(hal_data->max_dc); 158 | } 159 | 160 | // set output values 161 | if (*(hal_data->enable) == 0) { 162 | raw_val = 0; 163 | *(hal_data->pos) = 0; 164 | *(hal_data->neg) = 0; 165 | *(hal_data->curr_dc) = 0; 166 | } else { 167 | raw_val = (double)0x7fff * tmpdc; 168 | if (raw_val > (double)0x7fff) { 169 | raw_val = (double)0x7fff; 170 | } 171 | if (raw_val < (double)-0x7fff) { 172 | raw_val = (double)-0x7fff; 173 | } 174 | *(hal_data->pos) = (*(hal_data->value) > 0); 175 | *(hal_data->neg) = (*(hal_data->value) < 0); 176 | *(hal_data->curr_dc) = tmpdc; 177 | } 178 | 179 | // update value 180 | EC_WRITE_S16(&pd[hal_data->val_pdo_os], (int16_t)raw_val); 181 | *(hal_data->raw_val) = (int32_t)raw_val; 182 | } 183 | 184 | -------------------------------------------------------------------------------- /src/lcec_el40x1.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL40X1_H_ 19 | #define _LCEC_EL40X1_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL40x1_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL4001_PID 0x0fa13052 26 | #define LCEC_EL4011_PID 0x0fab3052 27 | #define LCEC_EL4021_PID 0x0fb53052 28 | #define LCEC_EL4031_PID 0x0fbf3052 29 | 30 | #define LCEC_EL40x1_PDOS 1 31 | 32 | int lcec_el40x1_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/lcec_el40x2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL40X2_H_ 19 | #define _LCEC_EL40X2_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL40x2_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL4002_PID 0x0fa23052 26 | #define LCEC_EL4012_PID 0x0fac3052 27 | #define LCEC_EL4022_PID 0x0fb63052 28 | #define LCEC_EL4032_PID 0x0fc03052 29 | 30 | #define LCEC_EL40x2_PDOS 2 31 | 32 | #define LCEC_EL40x2_CHANS 2 33 | 34 | int lcec_el40x2_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_el40x8.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL40X8_H_ 19 | #define _LCEC_EL40X8_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL40x8_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL4008_PID 0x0fa83052 26 | #define LCEC_EL4018_PID 0x0fb23052 27 | #define LCEC_EL4028_PID 0x0fbc3052 28 | #define LCEC_EL4038_PID 0x0fc63052 29 | 30 | #define LCEC_EL40x8_PDOS 8 31 | 32 | #define LCEC_EL40x8_CHANS 8 33 | 34 | int lcec_el40x8_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_el41x2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL41X2_H_ 19 | #define _LCEC_EL41X2_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL41x2_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL4102_PID 0x10063052 26 | #define LCEC_EL4112_PID 0x10103052 27 | #define LCEC_EL4122_PID 0x101A3052 28 | #define LCEC_EL4132_PID 0x10243052 29 | 30 | #define LCEC_EL41x2_PDOS 2 31 | 32 | #define LCEC_EL41x2_CHANS 2 33 | 34 | int lcec_el41x2_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_el41x4.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2016 Frank Brossette 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | #ifndef _LCEC_EL41X4_H_ 20 | #define _LCEC_EL41X4_H_ 21 | 22 | #include "lcec.h" 23 | 24 | #define LCEC_EL41x4_VID LCEC_BECKHOFF_VID 25 | 26 | #define LCEC_EL4104_PID 0x10083052 27 | #define LCEC_EL4134_PID 0x10263052 28 | 29 | #define LCEC_EL41x4_PDOS 4 30 | 31 | #define LCEC_EL41x4_CHANS 4 32 | 33 | int lcec_el41x4_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/lcec_el5002.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2023 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5002_H_ 19 | #define _LCEC_EL5002_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5002_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5002_PID 0x138a3052 25 | 26 | #define LCEC_EL5002_CHANS 2 27 | #define LCEC_EL5002_PDOS (7 * LCEC_EL5002_CHANS) 28 | 29 | #define LCEC_EL5002_PARAM_CH_MASK 0x000f 30 | #define LCEC_EL5002_PARAM_FNK_MASK 0xfff0 31 | 32 | #define LCEC_EL5002_PARAM_CH_0 0x0000 33 | #define LCEC_EL5002_PARAM_CH_1 0x0001 34 | 35 | #define LCEC_EL5002_PARAM_DIS_FRAME_ERR 0x0010 36 | #define LCEC_EL5002_PARAM_EN_PWR_FAIL_CHK 0x0020 37 | #define LCEC_EL5002_PARAM_EN_INHIBIT_TIME 0x0030 38 | #define LCEC_EL5002_PARAM_CODING 0x0040 39 | #define LCEC_EL5002_PARAM_BAUDRATE 0x0050 40 | #define LCEC_EL5002_PARAM_CLK_JIT_COMP 0x0060 41 | #define LCEC_EL5002_PARAM_FRAME_TYPE 0x0070 42 | #define LCEC_EL5002_PARAM_FRAME_SIZE 0x0080 43 | #define LCEC_EL5002_PARAM_DATA_LEN 0x0090 44 | #define LCEC_EL5002_PARAM_MIN_INHIBIT_TIME 0x00a0 45 | #define LCEC_EL5002_PARAM_NO_CLK_BURSTS 0x00b0 46 | 47 | int lcec_el5002_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /src/lcec_el5021.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2024 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5021_H_ 19 | #define _LCEC_EL5021_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5021_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5021_PID 0x139d3052 25 | 26 | #define LCEC_EL5021_PDOS 12 27 | 28 | int lcec_el5021_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /src/lcec_el5032.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2023 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5032_H_ 19 | #define _LCEC_EL5032_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5032_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5032_PID 0x13a83052 25 | 26 | #define LCEC_EL5032_CHANS 2 27 | #define LCEC_EL5032_PDOS (7 * LCEC_EL5032_CHANS) 28 | 29 | int lcec_el5032_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/lcec_el5101.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5101_H_ 19 | #define _LCEC_EL5101_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5101_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5101_PID 0x13ed3052 25 | 26 | #define LCEC_EL5101_PDOS 8 27 | 28 | #define LCEC_EL5101_PERIOD_SCALE 500e-9 29 | #define LCEC_EL5101_FREQUENCY_SCALE 0.01 30 | 31 | int lcec_el5101_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /src/lcec_el5122.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5122_H_ 19 | #define _LCEC_EL5122_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5122_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5122_PID 0x14023052 25 | 26 | #define LCEC_EL5122_CHANS 2 27 | #define LCEC_EL5122_PDOS (13 * LCEC_EL5122_CHANS) 28 | 29 | int lcec_el5122_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/lcec_el5151.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5151_H_ 19 | #define _LCEC_EL5151_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5151_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5151_PID 0x141f3052 25 | 26 | #define LCEC_EL5151_PDOS 18 27 | 28 | #define LCEC_EL5151_PERIOD_SCALE 1e-7 29 | 30 | int lcec_el5151_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /src/lcec_el5152.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL5152_H_ 19 | #define _LCEC_EL5152_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL5152_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL5152_PID 0x14203052 25 | 26 | #define LCEC_EL5152_CHANS 2 27 | #define LCEC_EL5152_PDOS (9 * LCEC_EL5152_CHANS) 28 | 29 | #define LCEC_EL5152_PERIOD_SCALE 1e-7 30 | 31 | int lcec_el5152_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /src/lcec_el6900.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL6900_H_ 19 | #define _LCEC_EL6900_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL6900_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL6900_PID 0x1AF43052 25 | 26 | #define LCEC_EL6900_PDOS 5 27 | 28 | #define LCEC_EL6900_PARAM_SLAVEID 1 29 | #define LCEC_EL6900_PARAM_STDIN_NAME 2 30 | #define LCEC_EL6900_PARAM_STDOUT_NAME 3 31 | 32 | #define LCEC_EL6900_PARAM_SLAVE_PDOS 4 33 | #define LCEC_EL6900_PARAM_SLAVE_CH_PDOS 2 34 | 35 | #define LCEC_EL6900_DIO_MAX_COUNT 32 36 | 37 | int lcec_el6900_preinit(struct lcec_slave *slave); 38 | int lcec_el6900_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /src/lcec_el7041_1000.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Jakob Flierl 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | #ifndef _LCEC_EL7041_1000_H_ 20 | #define _LCEC_EL7041_1000_H_ 21 | 22 | #include "lcec.h" 23 | 24 | #define LCEC_EL7041_1000_VID LCEC_BECKHOFF_VID 25 | #define LCEC_EL7041_1000_PID 0x1B813052 26 | 27 | #define LCEC_EL7041_1000_PDOS 34 28 | 29 | int lcec_el7041_1000_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/lcec_el70x1.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Jakob Flierl 3 | // Copyright (C) 2011 Sascha Ittner 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | // 19 | #ifndef _LCEC_EL70x1_H_ 20 | #define _LCEC_EL70x1_H_ 21 | 22 | #include "lcec.h" 23 | 24 | #define LCEC_EL70x1_VID LCEC_BECKHOFF_VID 25 | #define LCEC_EL7031_PID 0x1B773052 26 | #define LCEC_EL7041_0052_PID 0x1B813052 27 | 28 | #define LCEC_EL70x1_PDOS 15 29 | 30 | #define LCEC_EL70x1_PARAM_MAX_CURR 1 31 | #define LCEC_EL70x1_PARAM_RED_CURR 2 32 | #define LCEC_EL70x1_PARAM_NOM_VOLT 3 33 | #define LCEC_EL70x1_PARAM_COIL_RES 4 34 | #define LCEC_EL70x1_PARAM_MOTOR_EMF 5 35 | 36 | int lcec_el7031_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 37 | int lcec_el7041_0052_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/lcec_el7211.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL7211_H_ 19 | #define _LCEC_EL7211_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL7211_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL7211_PID 0x1C2B3052 25 | #define LCEC_EL7221_PID 0x1C353052 26 | #define LCEC_EL7201_9014_PID 0x1C213052 27 | 28 | #define LCEC_EL7211_PDOS 5 29 | #define LCEC_EL7201_9014_PDOS 7 30 | 31 | int lcec_el7211_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 32 | int lcec_el7201_9014_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/lcec_el7342.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL7342_H_ 19 | #define _LCEC_EL7342_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL7342_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EL7342_PID 0x1cae3052 25 | 26 | #define LCEC_EL7342_CHANS 2 27 | #define LCEC_EL7342_PDOS (33 * LCEC_EL7342_CHANS) 28 | 29 | int lcec_el7342_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/lcec_el7411.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL7411_H_ 19 | #define _LCEC_EL7411_H_ 20 | 21 | #include "lcec.h" 22 | #include "lcec_el7211.h" 23 | 24 | #define LCEC_EL7411_VID LCEC_BECKHOFF_VID 25 | #define LCEC_EL7411_PID 0x1Cf33052 26 | 27 | #define LCEC_EL7411_PDOS LCEC_EL7211_PDOS 28 | 29 | #define LCEC_EL7411_PARAM_DCLINK_NOM 1 30 | #define LCEC_EL7411_PARAM_DCLINK_MIN 2 31 | #define LCEC_EL7411_PARAM_DCLINK_MAX 3 32 | #define LCEC_EL7411_PARAM_MAX_CURR 4 33 | #define LCEC_EL7411_PARAM_RATED_CURR 5 34 | #define LCEC_EL7411_PARAM_RATED_VOLT 6 35 | #define LCEC_EL7411_PARAM_POLE_PAIRS 7 36 | #define LCEC_EL7411_PARAM_RESISTANCE 8 37 | #define LCEC_EL7411_PARAM_INDUCTANCE 9 38 | #define LCEC_EL7411_PARAM_TOURQUE_CONST 10 39 | #define LCEC_EL7411_PARAM_VOLTAGE_CONST 11 40 | #define LCEC_EL7411_PARAM_ROTOR_INERTIA 12 41 | #define LCEC_EL7411_PARAM_MAX_SPEED 13 42 | #define LCEC_EL7411_PARAM_RATED_SPEED 14 43 | #define LCEC_EL7411_PARAM_TH_TIME_CONST 15 44 | #define LCEC_EL7411_PARAM_HALL_VOLT 16 45 | #define LCEC_EL7411_PARAM_HALL_ADJUST 17 46 | 47 | int lcec_el7411_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /src/lcec_el95xx.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #include "lcec.h" 20 | #include "lcec_el95xx.h" 21 | 22 | typedef struct { 23 | hal_bit_t *power_ok; 24 | hal_bit_t *overload; 25 | unsigned int power_ok_pdo_os; 26 | unsigned int power_ok_pdo_bp; 27 | unsigned int overload_pdo_os; 28 | unsigned int overload_pdo_bp; 29 | } lcec_el95xx_data_t; 30 | 31 | static const lcec_pindesc_t slave_pins[] = { 32 | { HAL_BIT, HAL_OUT, offsetof(lcec_el95xx_data_t, power_ok), "%s.%s.%s.power-ok" }, 33 | { HAL_BIT, HAL_OUT, offsetof(lcec_el95xx_data_t, overload), "%s.%s.%s.overload" }, 34 | { HAL_TYPE_UNSPECIFIED, HAL_DIR_UNSPECIFIED, -1, NULL } 35 | }; 36 | 37 | void lcec_el95xx_read(struct lcec_slave *slave, long period); 38 | 39 | int lcec_el95xx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs) { 40 | lcec_master_t *master = slave->master; 41 | lcec_el95xx_data_t *hal_data; 42 | int err; 43 | 44 | // initialize callbacks 45 | slave->proc_read = lcec_el95xx_read; 46 | 47 | // alloc hal memory 48 | if ((hal_data = hal_malloc(sizeof(lcec_el95xx_data_t))) == NULL) { 49 | rtapi_print_msg(RTAPI_MSG_ERR, LCEC_MSG_PFX "hal_malloc() for slave %s.%s failed\n", master->name, slave->name); 50 | return -EIO; 51 | } 52 | memset(hal_data, 0, sizeof(lcec_el95xx_data_t)); 53 | slave->hal_data = hal_data; 54 | 55 | // initialize POD entries 56 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000, 0x01, &hal_data->power_ok_pdo_os, &hal_data->power_ok_pdo_bp); 57 | LCEC_PDO_INIT(pdo_entry_regs, slave->index, slave->vid, slave->pid, 0x6000, 0x02, &hal_data->overload_pdo_os, &hal_data->overload_pdo_bp); 58 | 59 | // export pins 60 | if ((err = lcec_pin_newf_list(hal_data, slave_pins, LCEC_MODULE_NAME, master->name, slave->name)) != 0) { 61 | return err; 62 | } 63 | 64 | return 0; 65 | } 66 | 67 | void lcec_el95xx_read(struct lcec_slave *slave, long period) { 68 | lcec_master_t *master = slave->master; 69 | lcec_el95xx_data_t *hal_data = (lcec_el95xx_data_t *) slave->hal_data; 70 | uint8_t *pd = master->process_data; 71 | 72 | // wait for slave to be operational 73 | if (!slave->state.operational) { 74 | return; 75 | } 76 | 77 | // check inputs 78 | *(hal_data->power_ok) = EC_READ_BIT(&pd[hal_data->power_ok_pdo_os], hal_data->power_ok_pdo_bp); 79 | *(hal_data->overload) = EC_READ_BIT(&pd[hal_data->overload_pdo_os], hal_data->overload_pdo_bp); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/lcec_el95xx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EL95XX_H_ 19 | #define _LCEC_EL95XX_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EL95xx_VID LCEC_BECKHOFF_VID 24 | 25 | #define LCEC_EL9505_PID 0x25213052 26 | #define LCEC_EL9508_PID 0x25243052 27 | #define LCEC_EL9510_PID 0x25263052 28 | #define LCEC_EL9512_PID 0x25283052 29 | #define LCEC_EL9515_PID 0x252b3052 30 | #define LCEC_EL9576_PID 0x25683052 31 | 32 | #define LCEC_EL95xx_PDOS 2 33 | 34 | int lcec_el95xx_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_em7004.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_EM7004_H_ 19 | #define _LCEC_EM7004_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_EM7004_VID LCEC_BECKHOFF_VID 24 | #define LCEC_EM7004_PID 0x1B5C3452 25 | 26 | #define LCEC_EM7004_DIN_COUNT 16 27 | #define LCEC_EM7004_DOUT_COUNT 16 28 | #define LCEC_EM7004_AOUT_COUNT 4 29 | #define LCEC_EM7004_ENC_COUNT 4 30 | 31 | #define LCEC_EM7004_PDOS (LCEC_EM7004_DIN_COUNT + LCEC_EM7004_DOUT_COUNT + LCEC_EM7004_AOUT_COUNT + (LCEC_EM7004_ENC_COUNT * 12)) 32 | 33 | int lcec_em7004_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /src/lcec_generic.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_GENERIC_H_ 19 | #define _LCEC_GENERIC_H_ 20 | 21 | #include "lcec.h" 22 | #include "lcec_conf.h" 23 | 24 | typedef struct { 25 | char name[LCEC_CONF_STR_MAXLEN]; 26 | hal_type_t type; 27 | LCEC_PDOENT_TYPE_T subType; 28 | hal_float_t floatScale; 29 | hal_float_t floatOffset; 30 | uint8_t bitOffset; 31 | uint8_t bitLength; 32 | hal_pin_dir_t dir; 33 | void *pin[LCEC_CONF_GENERIC_MAX_SUBPINS]; 34 | uint16_t pdo_idx; 35 | uint8_t pdo_sidx; 36 | unsigned int pdo_os; 37 | unsigned int pdo_bp; 38 | } lcec_generic_pin_t; 39 | 40 | int lcec_generic_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /src/lcec_omrg5.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2019 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #ifndef _LCEC_OMRG5_H_ 20 | #define _LCEC_OMRG5_H_ 21 | 22 | #include "lcec.h" 23 | 24 | #define LCEC_OMRG5_VID LCEC_OMRON_VID 25 | #define LCEC_OMRG5_R88D_KNA5L_ECT_PID 0x00000001 26 | #define LCEC_OMRG5_R88D_KN01L_ECT_PID 0x00000002 27 | #define LCEC_OMRG5_R88D_KN02L_ECT_PID 0x00000003 28 | #define LCEC_OMRG5_R88D_KN04L_ECT_PID 0x00000004 29 | #define LCEC_OMRG5_R88D_KN01H_ECT_PID 0x00000005 30 | #define LCEC_OMRG5_R88D_KN02H_ECT_PID 0x00000006 31 | #define LCEC_OMRG5_R88D_KN04H_ECT_PID 0x00000007 32 | #define LCEC_OMRG5_R88D_KN08H_ECT_PID 0x00000008 33 | #define LCEC_OMRG5_R88D_KN10H_ECT_PID 0x00000009 34 | #define LCEC_OMRG5_R88D_KN15H_ECT_PID 0x0000000A 35 | #define LCEC_OMRG5_R88D_KN20H_ECT_PID 0x00000056 36 | #define LCEC_OMRG5_R88D_KN30H_ECT_PID 0x00000057 37 | #define LCEC_OMRG5_R88D_KN50H_ECT_PID 0x00000058 38 | #define LCEC_OMRG5_R88D_KN75H_ECT_PID 0x00000059 39 | #define LCEC_OMRG5_R88D_KN150H_ECT_PID 0x0000005A 40 | #define LCEC_OMRG5_R88D_KN06F_ECT_PID 0x0000000B 41 | #define LCEC_OMRG5_R88D_KN10F_ECT_PID 0x0000000C 42 | #define LCEC_OMRG5_R88D_KN15F_ECT_PID 0x0000000D 43 | #define LCEC_OMRG5_R88D_KN20F_ECT_PID 0x0000005B 44 | #define LCEC_OMRG5_R88D_KN30F_ECT_PID 0x0000005C 45 | #define LCEC_OMRG5_R88D_KN50F_ECT_PID 0x0000005D 46 | #define LCEC_OMRG5_R88D_KN75F_ECT_PID 0x0000005E 47 | #define LCEC_OMRG5_R88D_KN150F_ECT_PID 0x0000005F 48 | 49 | #define LCEC_OMRG5_PDOS 13 50 | 51 | int lcec_omrg5_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /src/lcec_ph3lm2rm.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_PH3LM2RM_H_ 19 | #define _LCEC_PH3LM2RM_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_PH3LM2RM_VID LCEC_MODUSOFT_VID 24 | #define LCEC_PH3LM2RM_PID 0x10000001 25 | 26 | #define LCEC_PH3LM2RM_RM_COUNT 2 27 | #define LCEC_PH3LM2RM_LM_COUNT 3 28 | 29 | #define LCEC_PH3LM2RM_RM_PDOS 8 30 | #define LCEC_PH3LM2RM_LM_PDOS 8 31 | 32 | #define LCEC_PH3LM2RM_PDOS (2 + (LCEC_PH3LM2RM_RM_PDOS * LCEC_PH3LM2RM_RM_COUNT) + (LCEC_PH3LM2RM_LM_PDOS * LCEC_PH3LM2RM_LM_COUNT)) 33 | 34 | int lcec_ph3lm2rm_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/lcec_rtapi.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #ifndef _LCEC_RTAPI_H_ 20 | #define _LCEC_RTAPI_H_ 21 | 22 | #include 23 | #include 24 | 25 | // hack to identify LinuxCNC >= 2.8 26 | #ifdef RTAPI_UINT64_MAX 27 | #include 28 | #endif 29 | 30 | #ifdef __KERNEL__ 31 | #include "lcec_rtapi_kmod.h" 32 | #else 33 | #include "lcec_rtapi_user.h" 34 | #endif 35 | 36 | #if defined RTAPI_SERIAL && RTAPI_SERIAL >= 2 37 | #define lcec_rtapi_shmem_getptr(id, ptr) rtapi_shmem_getptr(id, ptr, NULL) 38 | #else 39 | #define lcec_rtapi_shmem_getptr(id, ptr) rtapi_shmem_getptr(id, ptr) 40 | #endif 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /src/lcec_rtapi_kmod.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #ifndef _LCEC_RTAPI_KMOD_H_ 20 | #define _LCEC_RTAPI_KMOD_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #define lcec_zalloc(size) kzalloc(size, GFP_KERNEL) 29 | #define lcec_free(ptr) kfree(ptr) 30 | 31 | #define lcec_gettimeofday(x) do_gettimeofday(x) 32 | 33 | #define LCEC_MS_TO_TICKS(x) (HZ * x / 1000) 34 | #define lcec_get_ticks() ((long) jiffies) 35 | 36 | #define lcec_schedule() schedule() 37 | 38 | static inline long long lcec_mod_64(long long val, unsigned long div) { 39 | s32 rem; 40 | div_s64_rem(val, div, &rem); 41 | return rem; 42 | } 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/lcec_rtapi_user.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2015 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | 19 | #ifndef _LCEC_RTAPI_USER_H_ 20 | #define _LCEC_RTAPI_USER_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | static inline void *lcec_zalloc(size_t size) { 29 | void *p = malloc(size); 30 | if (p) memset(p, 0, size); 31 | return p; 32 | } 33 | #define lcec_free(ptr) free(ptr) 34 | 35 | #define lcec_gettimeofday(x) gettimeofday(x, NULL) 36 | 37 | #define LCEC_MS_TO_TICKS(x) (x / 10) 38 | static inline long lcec_get_ticks(void) { 39 | struct timespec tp; 40 | clock_gettime(CLOCK_MONOTONIC, &tp); 41 | return ((long)(tp.tv_sec * 100LL)) + (tp.tv_nsec / 10000000L); 42 | } 43 | 44 | #define lcec_schedule() sched_yield() 45 | 46 | static inline long long lcec_mod_64(long long val, unsigned long div) { 47 | return val % div; 48 | } 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /src/lcec_stmds5k.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2011 Sascha Ittner 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | // 18 | #ifndef _LCEC_STMDS5K_H_ 19 | #define _LCEC_STMDS5K_H_ 20 | 21 | #include "lcec.h" 22 | 23 | #define LCEC_STMDS5K_VID LCEC_STOEBER_VID 24 | #define LCEC_STMDS5K_PID 0x00001388 25 | 26 | #define LCEC_STMDS5K_PDOS 8 27 | #define LCEC_STMDS5K_EXTINC_PDOS 1 28 | 29 | #define LCEC_STMDS5K_PARAM_MULTITURN 1 30 | #define LCEC_STMDS5K_PARAM_EXTENC 2 31 | 32 | int lcec_stmds5k_preinit(struct lcec_slave *slave); 33 | int lcec_stmds5k_init(int comp_id, struct lcec_slave *slave, ec_pdo_entry_reg_t *pdo_entry_regs); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /src/realtime.mk: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | include Kbuild 3 | 4 | include $(MODINC) 5 | 6 | ifeq ($(BUILDSYS),kbuild) 7 | 8 | # dirty workaround to get the RTAI directory 9 | RTAIINCDIR = $(subst /rtai.h,,$(firstword $(wildcard $(foreach i,$(subst -I,,$(filter -I%,$(RTFLAGS))), $(i)/rtai.h)))) 10 | ifneq ($(RTAIINCDIR),) 11 | RTAIDIR = $(realpath $(RTAIINCDIR)/..) 12 | endif 13 | 14 | all: 15 | $(MAKE) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(RTLIBDIR)/Module.symvers $(RTAIDIR)/modules/ethercat/Module.symvers" -C $(KERNELDIR) SUBDIRS=`pwd` CC=$(CC) V=0 modules 16 | 17 | else 18 | 19 | ifeq ($(MODINC_HAS_EXTRA_LDFLAGS),y) 20 | LDFLAGS += -Wl,-rpath,$(LIBDIR) 21 | EXTRA_LDFLAGS += -L$(LIBDIR) -llinuxcnchal -lethercat -lrt 22 | else 23 | LDFLAGS += -Wl,-rpath,$(LIBDIR) -L$(LIBDIR) -llinuxcnchal -lethercat 24 | endif 25 | 26 | all: modules 27 | 28 | endif 29 | 30 | -------------------------------------------------------------------------------- /src/user.mk: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | EXTRA_CFLAGS := $(filter-out -Wframe-larger-than=%,$(EXTRA_CFLAGS)) 4 | 5 | LCEC_CONF_OBJS = \ 6 | lcec_conf.o \ 7 | lcec_conf_util.o \ 8 | lcec_conf_icmds.o \ 9 | 10 | .PHONY: all clean install 11 | 12 | all: lcec_conf 13 | 14 | install: lcec_conf 15 | mkdir -p $(DESTDIR)$(EMC2_HOME)/bin 16 | cp lcec_conf $(DESTDIR)$(EMC2_HOME)/bin/ 17 | 18 | lcec_conf: $(LCEC_CONF_OBJS) 19 | $(CC) -o $@ $(LCEC_CONF_OBJS) -Wl,-rpath,$(LIBDIR) -L$(LIBDIR) -llinuxcnchal -lexpat 20 | 21 | %.o: %.c 22 | $(CC) -o $@ $(EXTRA_CFLAGS) -URTAPI -U__MODULE__ -DULAPI -Os -c $< 23 | 24 | --------------------------------------------------------------------------------