diff --git a/docs/src/man/man9/opto_ac5.9.adoc b/docs/src/man/man9/opto_ac5.9.adoc
deleted file mode 100644
index 0461756caf2..00000000000
--- a/docs/src/man/man9/opto_ac5.9.adoc
+++ /dev/null
@@ -1,73 +0,0 @@
-= opto_ac5(9)
-
-== NAME
-
-opto_ac5 - Realtime driver for opto22 PCI-AC5 cards
-
-== SYNOPSIS
-
-*loadrt opto_ac5* [**portconfig0=0x**_N_] [**portconfig1=0x**_N_]
-
-== DESCRIPTION
-
-These pins and parameters are created by the realtime *opto_ac5* module.
-The portconfig0 and portconfig1 variables are used to configure the two
-ports of each card. The first 24 bits of a 32 bit number represent the
-24 i/o points of each port. The lowest (rightmost) bit would be HAL pin
-0 which is header connector pin 47. Then next bit to the left would be
-HAL pin 1, header connector pin 45 and so on, until bit 24 would be HAL
-pin 23, header connector pin 1. "1" bits represent output points. So
-channel 0..11 as inputs and 12..23 as outputs would be represented by
-(in binary) 111111111111000000000000 which is 0xfff000 in hexadecimal.
-That is the number you would use, e.g.
-
-[source,hal]
-----
-loadrt opto_ac5 portconfig0=0xfff000
-----
-
-If no portconfig variable is specified the default configuration is 12
-inputs then 12 outputs.
-
-Up to 4 boards are supported. Boards are numbered starting at 0.
-
-Portnumber can be 0 or 1. Port 0 is closest to the card bracket.
-
-== PINS
-
-**opto_ac5.**_BOARDNUMBER_**.port.**_PORTNUMBER_**.in-**_PINNUMBER_ OUT bit::
- +
-
-**opto_ac5.**_BOARDNUMBER_**.port.**_PORTNUMBER_**.in-**_PINNUMBER_**-not** OUT bit::
- Connect a HAL bit signal to this pin to read an i/o point from the card.
- The PINNUMBER represents the position in the relay rack. E.g., PINNUMBER 0 is
- position 0 in a opto22 relay rack and would be pin 47 on the 50 pin header connector.
- The *-not* pin is inverted so that LOW gives TRUE and HIGH gives FALSE.
-**opto_ac5.**_BOARDNUMBER_**.port.**_PORTNUMBER_**.out-**_PINNUMBER_ IN bit::
- Connect a HAL bit signal to this pin to write to an i/o point of the
- card. The PINNUMBER represents the position in the relay rack. E.g.,
- PINNUMBER 23 is position 23 in a opto22 relay rack and would be pin 1
- on the 50 pin header connector.
-**opto_ac5.**_BOARDNUMBER_**.led.**_NUMBER_ OUT bit::
- Turns one of the on board LEDS on/off. LEDS are numbered 0 to 3.
-
-== PARAMETERS
-
-**opto_ac5.**_BOARDNUMBER_**.port.**_PORTNUMBER_**.out-**_PINNUMBER_**-invert** W bit::
- When TRUE, invert the meaning of the corresponding *-out* pin so that
- TRUE gives LOW and FALSE gives HIGH.
-
-== FUNCTIONS
-
-*opto_ac5.0.digital-read*::
- Add this to a thread to read all the input points.
-*opto_ac5.0.digital-write*::
- Add this to a thread to write all the output points and LEDS.
-
-== BUGS
-
-All boards are loaded with the same port configurations as the first board.
-
-== SEE ALSO
-
-https://wiki.linuxcnc.org/cgi-bin/wiki.pl?OptoPciAc5
diff --git a/src/Makefile b/src/Makefile
index ce0192abd38..22973911e77 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -543,7 +543,7 @@ genclean:
-rm -rf objects
-rm -f $(TARGETS)
-rm -f ../lib/*.so.[0-9]*
- -rm -f $(GENERATED_MANPAGES)
+ -rm -rf ../docs/build/man
-rm -f ../rtlib/*.$(MODULE_EXT)
-rm -f hal/components/conv_*.comp
@@ -987,26 +987,6 @@ ifeq ($(X86ARCH),true)
obj-$(CONFIG_HAL_SPEAKER) += hal_speaker.o
hal_speaker-objs := hal/drivers/hal_speaker.o $(MATHSTUB)
endif
-ifneq ($(BUILD_SYS),uspace)
-obj-$(CONFIG_PCI_8255) += pci_8255.o
-pci_8255-objs := hal/drivers/pci_8255.o
-obj-$(CONFIG_HAL_TIRO) += hal_tiro.o
-hal_tiro-objs := hal/drivers/hal_tiro.o $(MATHSTUB)
-obj-$(CONFIG_HAL_STG) += hal_stg.o
-hal_stg-objs := hal/drivers/hal_stg.o $(MATHSTUB)
-obj-$(CONFIG_HAL_VTI) += hal_vti.o
-hal_vti-objs := hal/drivers/hal_vti.o $(MATHSTUB)
-obj-$(CONFIG_HAL_EVOREG) += hal_evoreg.o
-hal_evoreg-objs := hal/drivers/hal_evoreg.o $(MATHSTUB)
-obj-$(CONFIG_HAL_MOTENC) += hal_motenc.o
-hal_motenc-objs := hal/drivers/hal_motenc.o $(MATHSTUB)
-obj-$(CONFIG_HAL_AX521H) += hal_ax5214h.o
-hal_ax5214h-objs := hal/drivers/hal_ax5214h.o $(MATHSTUB)
-obj-$(CONFIG_HAL_SKELETON) += hal_skeleton.o
-hal_skeleton-objs := hal/drivers/hal_skeleton.o $(MATHSTUB)
-obj-$(CONFIG_OPTO_AC5) += opto_ac5.o
-opto_ac5-objs := hal/drivers/opto_ac5.o $(MATHSTUB)
-endif
obj-$(CONFIG_HAL_GM) += hal_gm.o
hal_gm-objs := hal/drivers/hal_gm.o $(MATHSTUB)
obj-$(CONFIG_HAL_PPMC) += hal_ppmc.o
@@ -1399,17 +1379,6 @@ endif
../rtlib/sampler$(MODULE_EXT): $(addprefix objects/rt,$(sampler-objs))
../rtlib/hal_parport$(MODULE_EXT): $(addprefix objects/rt,$(hal_parport-objs))
#../rtlib/uparport$(MODULE_EXT): $(addprefix objects/rt,$(uparport-objs))
-ifneq ($(BUILD_SYS),uspace)
-../rtlib/pci_8255$(MODULE_EXT): $(addprefix objects/rt,$(pci_8255-objs))
-../rtlib/hal_tiro$(MODULE_EXT): $(addprefix objects/rt,$(hal_tiro-objs))
-../rtlib/hal_stg$(MODULE_EXT): $(addprefix objects/rt,$(hal_stg-objs))
-../rtlib/hal_vti$(MODULE_EXT): $(addprefix objects/rt,$(hal_vti-objs))
-../rtlib/hal_evoreg$(MODULE_EXT): $(addprefix objects/rt,$(hal_evoreg-objs))
-../rtlib/hal_motenc$(MODULE_EXT): $(addprefix objects/rt,$(hal_motenc-objs))
-../rtlib/hal_ax5214h$(MODULE_EXT): $(addprefix objects/rt,$(hal_ax5214h-objs))
-../rtlib/hal_skeleton$(MODULE_EXT): $(addprefix objects/rt,$(hal_skeleton-objs))
-../rtlib/opto_ac5$(MODULE_EXT): $(addprefix objects/rt,$(opto_ac5-objs))
-endif
../rtlib/hal_ppmc$(MODULE_EXT): $(addprefix objects/rt,$(hal_ppmc-objs))
ifeq ($(X86ARCH),true)
../rtlib/hal_speaker$(MODULE_EXT): $(addprefix objects/rt,$(hal_speaker-objs))
diff --git a/src/Makefile.inc.in b/src/Makefile.inc.in
index c0ab1ceb631..ffaaa804292 100644
--- a/src/Makefile.inc.in
+++ b/src/Makefile.inc.in
@@ -211,18 +211,9 @@ CONFIG_SAMPLER=m
CONFIG_UPARPORT=m
CONFIG_HAL_PARPORT=m
CONFIG_PROBE_PARPORT=m
-CONFIG_HAL_TIRO=m
-CONFIG_HAL_EVOREG=m
-CONFIG_HAL_MOTENC=m
-CONFIG_HAL_SKELETON=m
CONFIG_HAL_SPEAKER=m
-CONFIG_HAL_STG=m
-CONFIG_HAL_VTI=m
-CONFIG_HAL_AX521H=m
CONFIG_HAL_PPMC=m
-CONFIG_PCI_8255=m
CONFIG_HOSTMOT2=m
-CONFIG_OPTO_AC5=m
CONFIG_HAL_GM=m
CONFIG_HAL_BB_GPIO=m
CONFIG_HAL_PI_GPIO=m
diff --git a/src/hal/drivers/Submakefile b/src/hal/drivers/Submakefile
deleted file mode 100644
index b4ff16113ef..00000000000
--- a/src/hal/drivers/Submakefile
+++ /dev/null
@@ -1,41 +0,0 @@
-hal/drivers/pluto_servo_rbf.h: hal/drivers/pluto_servo_firmware/pluto_servo.rbf hal/drivers/rbf2h.py
- $(PYTHON) hal/drivers/rbf2h.py -g \
- -c "This is a component of pluto_servo, a PWM servo driver and" \
- -c "quadrature counter for emc2" \
- -c "Copyright (C) 2006, 2007 Jeff Epler" \
- $< > $@
-
-hal/drivers/pluto_step_rbf.h: hal/drivers/pluto_step_firmware/pluto_step.rbf hal/drivers/rbf2h.py
- $(PYTHON) hal/drivers/rbf2h.py -g \
- -c "This is a component of pluto_step, a hardware step generator for emc2" \
- -c "Copyright (C) 2006, 2007 Jeff Epler" \
- $< > $@
-
-clean: pluto_clean
-pluto_clean:
- rm -rf \
- pluto_servo_firmware/db \
- pluto_servo_firmware/pluto_servo.asm.rpt \
- pluto_servo_firmware/pluto_servo.done \
- pluto_servo_firmware/pluto_servo.fit.rpt \
- pluto_servo_firmware/pluto_servo.fit.summary \
- pluto_servo_firmware/pluto_servo.flow.rpt \
- pluto_servo_firmware/pluto_servo.map.rpt \
- pluto_servo_firmware/pluto_servo.map.summary \
- pluto_servo_firmware/pluto_servo.pin \
- pluto_servo_firmware/pluto_servo.pof \
- pluto_servo_firmware/pluto_servo.qws \
- pluto_servo_firmware/pluto_servo.rbf \
- pluto_servo_firmware/pluto_servo.sof \
- pluto_servo_firmware/pluto_servo.tan.rpt \
- pluto_servo_firmware/pluto_servo.tan.summary \
- pluto_servo_firmware/undo_redo.txt
-
-# The kernel's build system won't know how to rebuild generated files
-# so modules must depend on them explicitly
-ifneq ($(BUILD_SYS),uspace)
-modules: \
- hal/drivers/pluto_servo_rbf.h \
- hal/drivers/pluto_step_rbf.h
-endif
-
diff --git a/src/hal/drivers/hal_ax5214h.c b/src/hal/drivers/hal_ax5214h.c
deleted file mode 100644
index 84dd3781d51..00000000000
--- a/src/hal/drivers/hal_ax5214h.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/********************************************************************
-* Description: AX5214H.c
-* This file, 'AX5214H.c', is a HAL component that
-* provides a driver for the Axiom Measurement & Control
-* AX5241H 48 channel digital I/O board.
-*
-* Author: John Kasunich
-* License: GPL Version 2
-*
-* Copyright (c) 2005 All rights reserved.
-*
-* Last change:
-********************************************************************/
-/** This file, 'AX5214H.c', is a HAL component that provides a
- driver for the Axiom Measurement & Control AX5241H 48 channel
- digital I/O board.
-
- The configuration is determined by a config string passed to
- insmod when loading the module. The format consists of a base
- address, followed by a eight character string that sets the
- direction of each group of pins, repeated for each card (if
- more than one card is used). Each character of the direction
- string is either "I" or "O". The first character sets the
- direction of port A on channel 1 (Port 1A), the next sets
- port B on channel 1 (port 1B), the next sets the low nibble
- of port C on channel 1 (port 1CL), and the fourth sets the
- high nibble of port C on channel 1 (port 1CH). The next four
- characters do the same thing for channel 2 (ports 2A, 2B,
- 2CL, and 2CH).
-
- example: insmod AX5214.o cfg="0x220 IIIOIIOO"
-
- The example above is for one card, with its base address
- set to hex 220, and with 36 channels of input (Ports 1A,
- 1B, 1CL, 2A, and 2B) and 12 channels of output (Ports 1CH,
- 2CL, and 2CH).
-
- The driver creates HAL pins and parameters for each port pin
- as follows:
- Each physical output has a corresponding HAL pin, named
- 'ax5214.
.out-', and a HAL parameter
- 'ax5214..out--invert'.
- Each physical input has two corresponding HAL pins, named
- 'ax5214..in-' and
- 'ax5214..in--not'.
-
- is the board number, starting from zero.
- is the pin number, from 0 to 47.
-
- Note that the driver assumes active LOW signals. This
- is so that modules such as OPTO-22 will work correctly
- (TRUE means output ON, or input energized). If the
- signals are being used directly without buffering or
- isolation the inversion needs to be accounted for.
-
- The driver exports two HAL functions for each board,
- 'ax5214..read' and 'ax5214..write'.
-
-*/
-
-/** Copyright (C) 2005 John Kasunich
-
-*/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include /* isspace() */
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-#include /* HAL public API decls */
-
-/* If FASTIO is defined, uses outb() and inb() from ,
- instead of rtapi_outb() and rtapi_inb() - the ones
- are inlined, and save a microsecond or two (on my 233MHz box)
-*/
-#define FASTIO
-
-#ifdef FASTIO
-#define rtapi_inb inb
-#define rtapi_outb outb
-#include
-#endif
-
-/* module information */
-MODULE_AUTHOR("John Kasunich");
-MODULE_DESCRIPTION("Axiom AX5214H Driver for HAL");
-MODULE_LICENSE("GPL");
-static char *cfg = ""; /* config string, default no boards */
-RTAPI_MP_STRING(cfg, "config string");
-
-/***********************************************************************
-* STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-/* this structure contains the runtime data needed by the
- driver for a single board
-*/
-
-typedef struct {
- hal_bool_t data; /* basic pin for input or output */
- union {
- hal_bool_t not; /* pin for inverted data (input only) */
- hal_bool_t invert; /* param for inversion (output only) */
- } io;
-} io_pin_t;
-
-
-typedef struct {
- unsigned short base_addr; /* base I/O address (0x220, etc.) */
- unsigned char dir_bits; /* LSB is port 1A, MSB is port 2CH, */
- /* 1 means output, 0 means input */
- unsigned char port1config; /* config register value for port 1 */
- unsigned char port2config; /* config register value for port 1 */
- io_pin_t port_1A[8];
- io_pin_t port_1B[8];
- io_pin_t port_1CL[4];
- io_pin_t port_1CH[4];
- io_pin_t port_2A[8];
- io_pin_t port_2B[8];
- io_pin_t port_2CL[4];
- io_pin_t port_2CH[4];
-} board_t;
-
-/* pointer to array of board_t structs in shared memory, 1 per board */
-static board_t *board_array;
-
-/* other globals */
-static int comp_id; /* component ID */
-static int num_boards; /* number of ports configured */
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-
-/* These are the functions that actually do the I/O
- everything else is just init code
-*/
-
-static void read_board(void *arg, long period);
-static void write_board(void *arg, long period);
-
-/* 'pins_and_params()' does most of the work involved in setting up
- the driver. It parses the command line (argv[]), then if the
- command line is OK, it calls hal_init(), allocates shared memory
- for the parport_t data structure(s), and exports pins and parameters
- It does not set up functions, since that is handled differently in
- realtime and user space.
-*/
-static int pins_and_params(char *argv[]);
-
-static unsigned short parse_board_addr(char *cp);
-
-static int export_board(int boardnum, board_t * board);
-static int export_port(int boardnum, int pin_num, io_pin_t *pin, int num_pins, int dir);
-static int export_input_pin(int boardnum, int pinnum, io_pin_t *pin);
-static int export_output_pin(int boardnum, int pinnum, io_pin_t *pin);
-
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_BOARDS 8
-
-#define MAX_TOK ((MAX_BOARDS*2)+3)
-
-int rtapi_app_main(void)
-{
- char *cp;
- char *argv[MAX_TOK];
- int n, retval;
-
- /* test for config string */
- if ((cfg == 0) || (cfg[0] == '\0')) {
- rtapi_print_msg(RTAPI_MSG_ERR, "AX5214H: ERROR: no config string\n");
- return -1;
- }
- /* as a RT module, we don't get a nice argc/argv command line, we only
- get a single string... so we need to tokenize it ourselves */
- /* and to make things worse, it seems that insmod under kernel 2.6
- ends the config string at the first space, so I added the ability
- to use '_' as a token separator. What an ugly hack... HAL needs
- a better way to handle insmod time config data */
- cp = cfg;
- for (n = 0; n < MAX_TOK; n++) {
- /* strip leading whitespace or token separators */
- while ((*cp != '\0') && ( isspace(*cp) || ( *cp == '_') ))
- cp++;
- /* mark beginning of token */
- argv[n] = cp;
- /* find end of token */
- while ((*cp != '\0') && !( isspace(*cp) || ( *cp == '_') ))
- cp++;
- /* mark end of this token, prepare to search for next one */
- if (*cp != '\0') {
- *cp = '\0';
- cp++;
- }
- }
- for (n = 0; n < MAX_TOK; n++) {
- /* is token empty? */
- if (argv[n][0] == '\0') {
- /* yes - make pointer NULL */
- argv[n] = NULL;
- }
- }
- /* parse "command line", set up pins and parameters */
- retval = pins_and_params(argv);
- if (retval != 0) {
- return retval;
- }
- /* export functions for each board */
- for (n = 0; n < num_boards; n++) {
- /* export read function */
- retval = hal_export_functf(read_board, &(board_array[n]),
- 0, 0, comp_id, "ax5214h.%d.read", n);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5214H: ERROR: port %d read funct export failed\n", n);
- hal_exit(comp_id);
- return -1;
- }
- /* export write function */
- retval = hal_export_functf(write_board, &(board_array[n]),
- 0, 0, comp_id, "ax5214h.%d.write", n);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5214H: ERROR: port %d write funct export failed\n", n);
- hal_exit(comp_id);
- return -1;
- }
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "AX5214H: installed driver for %d boards\n", num_boards);
- hal_ready(comp_id);
- return 0;
-}
-
-void rtapi_app_exit(void)
-{
- int n;
- board_t *board;
-
- for ( n = 0 ; n < num_boards ; n++ ) {
- board = &(board_array[n]);
- /* reset all outputs to high/off */
- outb(0xff, board->base_addr+0);
- outb(0xff, board->base_addr+1);
- outb(0xff, board->base_addr+2);
- outb(0xff, board->base_addr+3);
- outb(0xff, board->base_addr+4);
- outb(0xff, board->base_addr+5);
- outb(0xff, board->base_addr+6);
- outb(0xff, board->base_addr+7);
- }
- hal_exit(comp_id);
-}
-
-
-/***********************************************************************
-* REALTIME PORT READ AND WRITE FUNCTIONS *
-************************************************************************/
-
-
-static void split_input(unsigned char data, io_pin_t *dest, int num)
-{
- int b;
- unsigned char mask;
-
- /* splits a byte into 'num' HAL pins (and their NOTs) */
- mask = 0x01;
- for (b = 0 ; b < num ; b++ ) {
- if ( data & mask ) {
- /* input high, which means FALSE (active low) */
- hal_set_bool(dest->data, 0);
- hal_set_bool(dest->io.not, 1);
- } else {
- /* input low, which means TRUE */
- hal_set_bool(dest->data, 1);
- hal_set_bool(dest->io.not, 0);
- }
- mask <<= 1;
- dest++;
- }
-}
-
-static void read_board(void *arg, long period)
-{
- board_t *board;
- unsigned char indata;
-
- board = arg;
- if ( (board->dir_bits & 0x01) == 0 ) {
- indata = rtapi_inb(board->base_addr+0);
- split_input(indata, &(board->port_1A[0]), 8);
- }
- if ( (board->dir_bits & 0x02) == 0 ) {
- indata = rtapi_inb(board->base_addr+1);
- split_input(indata, &(board->port_1B[0]), 8);
- }
- if ( (board->dir_bits & 0x0A) != 0x0A ) {
- indata = rtapi_inb(board->base_addr+2);
- if ( (board->dir_bits & 0x04) == 0 ) {
- split_input(indata, &(board->port_1CL[0]), 4);
- }
- indata >>= 4;
- if ( (board->dir_bits & 0x08) == 0 ) {
- split_input(indata, &(board->port_1CH[0]), 4);
- }
- }
- if ( (board->dir_bits & 0x10) == 0 ) {
- indata = rtapi_inb(board->base_addr+4);
- split_input(indata, &(board->port_2A[0]), 8);
- }
- if ( (board->dir_bits & 0x20) == 0 ) {
- indata = rtapi_inb(board->base_addr+5);
- split_input(indata, &(board->port_2B[0]), 8);
- }
- if ( (board->dir_bits & 0xA0) != 0xA0 ) {
- indata = rtapi_inb(board->base_addr+6);
- if ( (board->dir_bits & 0x40) == 0 ) {
- split_input(indata, &(board->port_2CL[0]), 4);
- }
- indata >>= 4;
- if ( (board->dir_bits & 0x80) == 0 ) {
- split_input(indata, &(board->port_2CH[0]), 4);
- }
- }
-}
-
-unsigned char build_output(io_pin_t *src, int num)
-{
- int b;
- unsigned char data, mask;
-
- data = 0x00;
- mask = 0x01;
- /* assemble output byte for data port from 'num' source variables */
- for (b = 0; b < num; b++) {
- /* get the data, add to output byte */
- if ( hal_get_bool(src->data) ) {
- if ( !hal_get_bool(src->io.invert) ) {
- data |= mask;
- }
- } else {
- if ( hal_get_bool(src->io.invert) ) {
- data |= mask;
- }
- }
- mask <<= 1;
- src++;
- }
- return data;
-}
-
-static void write_board(void *arg, long period)
-{
- board_t *board;
- unsigned char outdata, tmp;
-
- board = arg;
- if ( (board->dir_bits & 0x01) == 0x01 ) {
- outdata = build_output(&(board->port_1A[0]), 8);
- rtapi_outb(~outdata, board->base_addr+0);
- }
- if ( (board->dir_bits & 0x02) == 0x02 ) {
- outdata = build_output(&(board->port_1B[0]), 8);
- rtapi_outb(~outdata, board->base_addr+1);
- }
- if ( (board->dir_bits & 0x0A) != 0x00 ) {
- outdata = 0;
- if ( (board->dir_bits & 0x04) == 0x04 ) {
- tmp = build_output(&(board->port_1CL[0]), 4);
- outdata = tmp;
- }
- if ( (board->dir_bits & 0x08) == 0x08 ) {
- tmp = build_output(&(board->port_1CH[0]), 4);
- outdata = outdata | (tmp << 4);
- }
- rtapi_outb(~outdata, board->base_addr+2);
- }
- if ( (board->dir_bits & 0x10) == 0x10 ) {
- outdata = build_output(&(board->port_2A[0]), 8);
- rtapi_outb(~outdata, board->base_addr+4);
- }
- if ( (board->dir_bits & 0x20) == 0x20 ) {
- outdata = build_output(&(board->port_2B[0]), 8);
- rtapi_outb(~outdata, board->base_addr+5);
- }
- if ( (board->dir_bits & 0xA0) != 0x00 ) {
- outdata = 0;
- if ( (board->dir_bits & 0x40) == 0x40 ) {
- tmp = build_output(&(board->port_2CL[0]), 4);
- outdata = tmp;
- }
- if ( (board->dir_bits & 0x80) == 0x80 ) {
- tmp = build_output(&(board->port_2CH[0]), 4);
- outdata = outdata | (tmp << 4);
- }
- rtapi_outb(~outdata, board->base_addr+6);
- }
-}
-
-/***********************************************************************
-* LOCAL FUNCTION DEFINITIONS *
-************************************************************************/
-
-static int pins_and_params(char *argv[])
-{
- unsigned short board_addr[MAX_BOARDS];
- unsigned char dir_bits[MAX_BOARDS], mask;
- int n, m, retval;
-
- /* clear port_addr and dir_bits arrays */
- for (n = 0; n < MAX_BOARDS; n++) {
- board_addr[n] = 0;
- dir_bits[n] = 0;
- }
- /* parse config string, results in port_addr[] and data_dir[] arrays */
- num_boards = 0;
- n = 0;
- while ((num_boards < MAX_BOARDS) && (argv[n] != 0)) {
- board_addr[num_boards] = parse_board_addr(argv[n]);
- if (board_addr[num_boards] == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5124H: ERROR: bad port address '%s'\n", argv[n]);
- return -1;
- }
- n++;
- if (argv[n] == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5124H: ERROR: no config info for port %s\n", argv[n-1]);
- return -1;
- }
- /* should be a string of 8 'I" or "O" characters */
- dir_bits[num_boards] = 0;
- mask = 0x01;
- for ( m = 0 ; m < 8 ; m++ ) {
- /* test character and set/clear bit */
- if ((argv[n][m] == 'i') || (argv[n][m] == 'I')) {
- /* input, set mask bit to zero */
- dir_bits[num_boards] &= ~mask;
- } else if ((argv[n][m] == 'o') || (argv[n][m] == 'O')) {
- /* output, set mask bit to one */
- dir_bits[num_boards] |= mask;
- } else {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5124H: ERROR: bad config info for port %s: '%s'\n", argv[n-1], argv[n]);
- return -1;
- }
- /* shift mask for next but */
- mask <<= 1;
- }
- n++;
- num_boards++;
- }
- /* OK, now we've parsed everything */
- if (num_boards == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5214H: ERROR: no ports configured\n");
- return -1;
- }
- /* have good config info, connect to the HAL */
- comp_id = hal_init("hal_ax5214h");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "AX5214H: ERROR: hal_init() failed\n");
- return -1;
- }
- /* allocate shared memory for board data */
- board_array = hal_malloc(num_boards * sizeof(board_t));
- if (board_array == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5214H: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
- /* export all the pins and params for each board */
- for (n = 0; n < num_boards; n++) {
- /* config addr and direction */
- board_array[n].base_addr = board_addr[n];
- board_array[n].dir_bits = dir_bits[n];
- /* export all vars */
- retval = export_board(n, &(board_array[n]));
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "AX5214H: ERROR: board %d (%04X) var export failed\n", n, board_addr[n]);
- hal_exit(comp_id);
- return -1;
- }
- }
- return 0;
-}
-
-static unsigned short parse_board_addr(char *cp)
-{
- unsigned short result;
-
- /* initial value */
- result = 0;
- /* test for leading '0x' */
- if (cp[0] == '0') {
- if ((cp[1] == 'X') || (cp[1] == 'x')) {
- /* leading '0x', skip it */
- cp += 2;
- }
- }
- /* ok, now parse digits */
- while (*cp != '\0') {
- /* if char is a hex digit, add it to result */
- if ((*cp >= '0') && (*cp <= '9')) {
- result <<= 4;
- result += *cp - '0';
- } else if ((*cp >= 'A') && (*cp <= 'F')) {
- result <<= 4;
- result += (*cp - 'A') + 10;
- } else if ((*cp >= 'a') && (*cp <= 'f')) {
- result <<= 4;
- result += (*cp - 'a') + 10;
- } else {
- /* not a valid hex digit */
- return 0;
- }
- /* next char */
- cp++;
- }
- return result;
-}
-
-static int export_board(int boardnum, board_t * board)
-{
- int retval, msg, dir;
- unsigned char config;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
-
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
- retval = 0;
- config = 0x80;
- dir = board->dir_bits & 0x01;
- retval += export_port ( boardnum, 0, &(board->port_1A[0]), 8, dir );
- if ( dir == 0 ) {
- config |= 0x10;
- }
- dir = board->dir_bits & 0x02;
- retval += export_port ( boardnum, 8, &(board->port_1B[0]), 8, dir );
- if ( dir == 0 ) {
- config |= 0x02;
- }
- dir = board->dir_bits & 0x04;
- retval += export_port ( boardnum, 16, &(board->port_1CL[0]), 4, dir );
- if ( dir == 0 ) {
- config |= 0x01;
- }
- dir = board->dir_bits & 0x08;
- retval += export_port ( boardnum, 20, &(board->port_1CH[0]), 4, dir );
- if ( dir == 0 ) {
- config |= 0x08;
- }
- board->port1config = config;
- config = 0x80;
-
- dir = board->dir_bits & 0x10;
- retval += export_port ( boardnum, 24, &(board->port_2A[0]), 8, dir );
- if ( dir == 0 ) {
- config |= 0x10;
- }
- dir = board->dir_bits & 0x20;
- retval += export_port ( boardnum, 32, &(board->port_2B[0]), 8, dir );
- if ( dir == 0 ) {
- config |= 0x02;
- }
- dir = board->dir_bits & 0x40;
- retval += export_port ( boardnum, 40, &(board->port_2CL[0]), 4, dir );
- if ( dir == 0 ) {
- config |= 0x01;
- }
- dir = board->dir_bits & 0x80;
- retval += export_port ( boardnum, 44, &(board->port_2CH[0]), 4, dir );
- if ( dir == 0 ) {
- config |= 0x08;
- }
- board->port2config = config;
- /* initialize hardware - all outputs high
- (since outputs are active low) */
- outb(board->port1config, board->base_addr+3);
- outb(0xff, board->base_addr+0);
- outb(0xff, board->base_addr+1);
- outb(0xff, board->base_addr+2);
- outb(board->port2config, board->base_addr+7);
- outb(0xff, board->base_addr+4);
- outb(0xff, board->base_addr+5);
- outb(0xff, board->base_addr+6);
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return retval;
-}
-
-static int export_port(int boardnum, int pin_num, io_pin_t *pin, int num_pins, int dir)
-{
- int n, retval;
-
- retval = 0;
- for ( n = 0 ; n < num_pins ; n++ ) {
- if ( dir == 0 ) {
- retval += export_input_pin(boardnum, pin_num, pin );
- } else {
- retval += export_output_pin(boardnum, pin_num, pin );
- }
- pin_num++;
- pin++;
- }
- return retval;
-}
-
-static int export_input_pin(int boardnum, int pinnum, io_pin_t *pin)
-{
- int retval;
-
- /* export read only HAL pin for input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->data), 0,
- "ax5214h.%d.in-%02d", boardnum, pinnum);
- if (retval != 0) {
- return retval;
- }
- /* export additional pin for inverted input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->io.not), 1,
- "ax5214h.%d.in-%02d-not", boardnum, pinnum);
- return retval;
-}
-
-static int export_output_pin(int boardnum, int pinnum, io_pin_t *pin)
-{
- int retval;
-
- /* export read only HAL pin for output data */
- retval = hal_pin_new_bool(comp_id, HAL_IN, &(pin->data), 0,
- "ax5214h.%d.out-%02d", boardnum, pinnum);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for polarity */
- retval = hal_param_new_bool(comp_id, HAL_RW, &(pin->io.invert), 0,
- "ax5214h.%d.out-%02d-invert", boardnum, pinnum);
- return retval;
-}
diff --git a/src/hal/drivers/hal_evoreg.c b/src/hal/drivers/hal_evoreg.c
deleted file mode 100644
index 01c82f992d5..00000000000
--- a/src/hal/drivers/hal_evoreg.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/********************************************************************
-* Description: hal_evoreg.c
-* This file, 'hal_evoreg.c', is a HAL component that
-* provides a driver for the Siemens EVOREG motion
-* control board.
-*
-* Author: Martin Kuhnle, John Kasunich
-* License: GPL Version 2
-*
-* Copyright (c) 2003 All rights reserved.
-*
-* Last change:
-********************************************************************/
-
-/** This file, 'hal_evoreg.c', is a HAL component that provides a
- driver for the Siemens EVOREG motion control board.
- This board provides three 16bit DAC's, three encoder inputs,
- 46 digital inputs and 21 digital outputs
-
- Fixme: error messages are not proper up to now
- ToDo: better error messages
- make inverted bits available
- possibility to read back outputs
- check dac values for limits
- scale for every dacs
- scale for every encoder
- check if the dacs are updated all at the same time
- enable Interrupts
- check for wire break
- watchdog
-
-
-
- Copyright (C) 2003 Martin Kuhnle
-
- John Kasunich
-
-
-*/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include /* isspace() */
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-#include /* rtapi_inb(), rtapi_outb() */
-#include /* HAL public API decls */
-
-/* module information */
-MODULE_AUTHOR("Martin Kuhnle");
-MODULE_DESCRIPTION("SIEMENS-EVOREG Driver for EMC HAL");
-MODULE_LICENSE("GPL");
-/* static char *cfg = 0; */
-/* config string
-RTAPI_MP_STRING(cfg, "config string"); */
-
-/***********************************************************************
-* STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-/* this structure contains the runtime data needed by the
- driver for a single port/channel
-*/
-
-typedef struct {
- void *io_base;
- hal_real_t dac_out[3]; /* ptrs for dac output */
- hal_real_t position[3]; /* ptrs for encoder input */
- hal_bool_t digital_in[47]; /* ptrs for digital input pins 0 - 45 */
- hal_bool_t digital_out[25]; /* ptrs for digital output pins 0 - 20 */
- rtapi_u16 raw_counts_old[3];
- rtapi_s32 counts[3];
- hal_real_t pos_scale; /*! \todo scale for position command FIXME should be one per axis */
-} evoreg_t;
-
-/* pointer to array of evoreg_t structs in shared memory, 1 per port */
-static evoreg_t *port_data_array;
-
-/* other globals */
-static int comp_id; /* component ID */
-static int num_ports; /* number of ports configured */
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-/* These is the functions that actually do the I/O
- everything else is just init code
-*/
-static void update_port(void *arg, long period);
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_PORTS 8
-#define MAX_DAC 3 /* number of DACs per card */
-#define MAX_ENC 3 /* number of Encoders per card */
-
-#define MAX_TOK ((MAX_PORTS*2)+3)
-
-int rtapi_app_main(void)
-{
- int n,i , retval, num_dac, num_enc;
-
- unsigned int base=0x300;
-
- /* only one port at the moment */
- num_ports = 1;
- n = 0;
-
- #define ISA_BASE 0xC9000
- #define ISA_MAX 0x100000 /* allgemeiner Speicherzugriff */
-
-
- /* STEP 1: initialise the driver */
- comp_id = hal_init("hal_evoreg");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: hal_init() failed\n");
- return -1;
- }
-
- /* STEP 2: allocate shared memory for EVOREG data */
- port_data_array = hal_malloc(num_ports * sizeof(evoreg_t));
- if (port_data_array == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- /*! \todo FIXME: Test memory area and setup the card */
- port_data_array->io_base = ioremap(ISA_BASE, ISA_MAX - ISA_BASE);
- rtapi_print_msg(RTAPI_MSG_ERR,"EVOREG: io_base: %p \n", port_data_array->io_base);
- outw(0x82c9,base); /* set indexregister */
-
- /* Set all outputs to zero */
- writew(0, (char *)port_data_array->io_base + 0x20); /* digital out 0-15 */
- writew(0, (char *)port_data_array->io_base + 0x40); /* digital out 16-23 */
- writew(0, (char *)port_data_array->io_base + 0x60); /* DAC 1 */
- writew(0, (char *)port_data_array->io_base + 0x80); /* DAC 2 */
- writew(0, (char *)port_data_array->io_base + 0xa0); /* DAC 3 */
- /* Reset Encoder's */
- writew(0, (char *)port_data_array->io_base + 0x02); /* ENCODER 1 */
- writew(0, (char *)port_data_array->io_base + 0x0a); /* ENCODER 2 */
- writew(0, (char *)port_data_array->io_base + 0x12); /* ENCODER 3 */
-
- /* STEP 3: export the pin(s) */
-
- /* Export DAC pin's */
- for ( num_dac=1; num_dac<=MAX_DAC; num_dac++) {
- retval = hal_pin_new_real(comp_id, HAL_IN, &(port_data_array->dac_out[num_dac-1]),
- 0.0, "evoreg.%d.dac-%02d-out", 1, num_dac);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
- retval);
- hal_exit(comp_id);
- return -1;
- }
- }
-
- /* Export Encoder pin's */
- for ( num_enc=1; num_enc<=MAX_ENC; num_enc++) {
- retval = hal_pin_new_real(comp_id, HAL_OUT, &(port_data_array->position[num_enc - 1]),
- 0.0, "evoreg.%d.position-%02d-in", 1, num_enc);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
- retval);
- hal_exit(comp_id);
- return -1;
- }
- }
-
- /* Export IO pin's */
-
- /* export write only HAL pin's for the input bit */
- for ( i=0; i<=45;i++) {
- retval += hal_pin_new_bool(comp_id, HAL_OUT, &(port_data_array->digital_in[i]),
- 0, "evoreg.%d.pin-%02d-in", 1, i);
-
- /* export another write only HAL pin for the same bit inverted */
- /*
- retval += hal_pin_bit_newf(HAL_OUT, &(port_data_array->digital_in[(2*i)+1]),
- comp_id, "evoreg.%d.pin-%02d-in-not", 1, i); */
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
- retval);
- hal_exit(comp_id);
- return -1;
- }
- }
-
- /* export read only HAL pin's for the output bit */
- for ( i=0; i<=23;i++) {
- retval += hal_pin_new_bool(comp_id, HAL_IN, &(port_data_array->digital_out[i]),
- 0, "evoreg.%d.pin-%02d-out", 1, i);
-
- /* export another read only HAL pin for the same bit inverted */
- /*
- retval += hal_pin_bit_newf(HAL_IN, &(port_data_array->digital_out[(2*i)+1]),
- comp_id, "evoreg.%d.pin-%02d-out-not", 1, i)); */
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: port %d var export failed with err=%i\n", n + 1,
- retval);
- hal_exit(comp_id);
- return -1;
- }
- }
-
- /* export parameter for scaling */
- retval = hal_param_new_real(comp_id, HAL_RW, &(port_data_array->pos_scale),
- 0.0, "evoreg.%d.position-scale", 1);
- if (retval != 0) {
- return retval;
- }
-
-
- /* STEP 4: export function */
- retval = hal_export_functf(update_port, &(port_data_array[n]), 1, 0,
- comp_id, "evoreg.%d.update", n + 1);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "EVOREG: ERROR: port %d write funct export failed\n", n + 1);
- hal_exit(comp_id);
- return -1;
- }
-
- rtapi_print_msg(RTAPI_MSG_INFO,
- "EVOREG: installed driver for %d card(s)\n", num_ports);
- hal_ready(comp_id);
- return 0;
-}
-
-void rtapi_app_exit(void)
-{
- outw(0x0,0x300);
- hal_exit(comp_id);
-}
-
-/**************************************************************
-* REALTIME PORT WRITE FUNCTION *
-**************************************************************/
-
-static void update_port(void *arg, long period)
-{
- evoreg_t *port;
- int pin;
- unsigned char tmp, mask;
- __u16 raw_counts[3];
-
- port = arg;
-
-/* write DAC's */
- writew((hal_get_real(port->dac_out[0])/10 * 0x7fff), (char *)port->io_base + 0x60);
- writew((hal_get_real(port->dac_out[1])/10 * 0x7fff), (char *)port->io_base + 0x80);
- writew((hal_get_real(port->dac_out[2])/10 * 0x7fff), (char *)port->io_base + 0xa0);
-
-/* Read Encoders, improve the 16bit hardware counters to 32bit and scale the values */
- raw_counts[0] = (__u16) readw(port->io_base);
- raw_counts[1] = (__u16) readw((char *)port->io_base + 0x08 );
- raw_counts[2] = (__u16) readw((char *)port->io_base + 0x10 );
-
- port->counts[0] += (__s16) (raw_counts[0] - port->raw_counts_old[0]);
- port->raw_counts_old[0] = raw_counts[0];
-
- port->counts[1] += (__s16) (raw_counts[1] - port->raw_counts_old[1]);
- port->raw_counts_old[1] = raw_counts[1];
-
- port->counts[2] += (__s16) (raw_counts[2] - port->raw_counts_old[2]);
- port->raw_counts_old[2] = raw_counts[2];
-
- rtapi_real pos_scale = hal_get_real(port->pos_scale);
- hal_set_real(port->position[0], port->counts[0] * pos_scale);
- hal_set_real(port->position[1], port->counts[1] * pos_scale);
- hal_set_real(port->position[2], port->counts[2] * pos_scale);
-
-
-/* read digital inputs */
- tmp = readw((char *)port->io_base + 0x20); /* digital input 0-15 */
- mask = 0x01;
- for (pin=0 ; pin < 16 ; pin++) {
- hal_set_bool(port->digital_in[pin], (tmp & mask) ? 1:0);
- mask <<= 1;
- }
- tmp = readw((char *)port->io_base + 0x40); /* digital input 16-31 */
- mask = 0x01;
- for (pin=16 ; pin < 32 ; pin++) {
- hal_set_bool(port->digital_in[pin], (tmp & mask) ? 1:0);
- mask <<= 1;
- }
-
- tmp = readw((char *)port->io_base + 0x60); /* digital input 32-45 */
- mask = 0x01;
- for (pin=32 ; pin < 46 ; pin++) {
- hal_set_bool(port->digital_in[pin], (tmp & mask) ? 1:0);
- mask <<= 1;
- }
-
-
-/* write digital outputs */
- tmp = 0x0;
- mask = 0x01;
- for (pin=0; pin < 16; pin++) {
- if (hal_get_bool(port->digital_out[pin])) {
- tmp |= mask;
- }
- mask <<= 1;
- }
- writew( tmp, (char *)port->io_base + 0x20); /* digital output 0-15 */
-
-
- tmp = 0x0;
- mask = 0x01;
- for (pin=16; pin < 24; pin++) {
- if (hal_get_bool(port->digital_out[pin])) {
- tmp |= mask;
- }
- mask <<= 1;
- }
- writew( tmp, (char *)port->io_base + 0x40); /* digital output 16-23 */
-
-}
diff --git a/src/hal/drivers/hal_motenc.c b/src/hal/drivers/hal_motenc.c
deleted file mode 100644
index 01471f7c679..00000000000
--- a/src/hal/drivers/hal_motenc.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2005 Peter G. Vavaroutsos
- * License: GPL Version 2
- *
- *
- * This is the driver for the Vital Systems MOTENC-100 board.
- * The board includes 8 quadrature decoders, 8 analog inputs,
- * 8 analog outputs, 68 digital inputs, 32 digital outputs,
- * programmable timer interrupts, a watch dog timer, and a hardware
- * E-STOP circuit.
- *
- * Installation of the driver (realtime only):
- *
- * insmod hal_motenc
- *
- *
- * The following items are exported to the HAL. is read
- * from the jumper settings on the MOTENC-100 board and is formatted
- * as "%d". is formatted as "%02d".
- *
- * Encoders:
- * Parameters:
- * float motenc..enc--scale
- *
- * Pins:
- * s32 motenc..enc--count
- * float motenc..enc--position
- * bit motenc..enc--index
- * bit motenc..enc--index-enable
- * bit motenc..enc--reset
- *
- * Functions:
- * void motenc..encoder-read
- *
- *
- * DACs:
- * Parameters:
- * float motenc..dac--offset
- * float motenc..dac--gain
- *
- * Pins:
- * float motenc..dac--value
- *
- * Functions:
- * void motenc..dac-write
- *
- *
- * ADC:
- * Parameters:
- * float motenc..adc--offset
- * float motenc..adc--gain
- *
- * Pins:
- * float motenc..adc--value
- *
- * Functions:
- * void motenc..adc-read
- *
- *
- * Digital In:
- * Pins:
- * bit motenc..pin--in
- * bit motenc..pin--in-not
- *
- * Functions:
- * void motenc..digital-in-read
- *
- *
- * Digital Out:
- * Parameters:
- * bit motenc..pin--out-invert
- *
- * Pins:
- * bit motenc..pin--out
- *
- * Functions:
- * void motenc..digital-out-write
- *
- *
- * Miscellaneous:
- * Parameters:
- * u32 motenc..watchdog-control
- * MOTENC_WATCHDOG_CTL_8MS 0x00000000
- * MOTENC_WATCHDOG_CTL_16MS 0x00000001
- * MOTENC_WATCHDOG_CTL_ENABLE 0x00000004
- * MOTENC_WATCHDOG_CTL_AUTO_RESET 0x00000010 // Reset by DAC writes.
- *
- * Pins:
- * bit motenc..estop-in
- * bit motenc..estop-in-not
- * bit motenc..watchdog-reset
- *
- * Functions:
- * void motenc..misc-update
- *
- ******************************************************************************
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General
- * Public License as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- * ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- * TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- * harming persons must have provisions for completely removing power
- * from all motors, etc, before persons enter any danger area. All
- * machinery must be designed to comply with local and national safety
- * codes, and the authors of this software can not, and do not, take
- * any responsibility for such compliance.
- *
- * This code was written as part of the EMC HAL project. For more
- * information, go to www.linuxcnc.org.
- *
- ******************************************************************************/
-
-#include
-
-#include // RTAPI realtime OS API.
-#include // RTAPI realtime module decls.
-#include // HAL public API decls.
-#include "motenc.h" // Hardware dependent defines.
-
-// Module information.
-MODULE_AUTHOR("Pete Vavaroutsos");
-MODULE_DESCRIPTION("Driver for Vital Systems MOTENC-100 for EMC HAL");
-MODULE_LICENSE("GPL");
-
-
-/******************************************************************************
- * DEVICE OBJECT
- *
- * This object contains all the data for one card. A device object is
- * dynamically allocated in shmem for each card during initialization.
- *
- ******************************************************************************/
-
-
-typedef struct {
- // Pins.
- hal_sint_t pCount; // Captured binary count value.
- hal_real_t pPosition; // Scaled position (floating point).
- hal_bool_t pIndex; // Current state of index.
- hal_bool_t pIndexEnable; // Setting this pin causes the count
- // to be cleared on the next index pulse.
- // Use this feature at your own risk as the PID loop
- // may get upset. This pin is self clearing.
- hal_bool_t pReset; // Setting this pin causes Count to be reset.
-
- // Parameters.
- hal_real_t scale; // Scaling factor for position.
-
- // Private data.
- double oldScale; // Stored scale value.
- double scaleRecip; // Reciprocal value used for scaling.
-} EncoderPinsParams;
-
-typedef struct {
- // Pins.
- hal_real_t pValue; // Desired value.
-
- // Parameters.
- hal_real_t offset;
- hal_real_t gain;
-} DacPinsParams;
-
-typedef struct {
- // Pins.
- hal_real_t pValue; // Converted value.
-
- // Parameters.
- hal_real_t offset;
- hal_real_t gain;
-} AdcPinsParams;
-
-typedef struct {
- // Pins.
- hal_bool_t pValue;
- hal_bool_t pValueNot;
-} DigitalInPinsParams;
-
-typedef struct {
- // Pins.
- hal_bool_t pValue;
-
- // Parameters.
- hal_bool_t invert;
-} DigitalOutPinsParams;
-
-typedef struct {
- // Pins.
- hal_bool_t pEstopIn;
- hal_bool_t pEstopInNot;
- hal_bool_t pWatchdogReset;// This pin is self clearing.
-
- // Parameters.
- hal_uint_t watchdogControl;
-} MiscPinsParams;
-
-typedef struct {
- // Private data.
- MotencRegMap *pCard;
- int boardType;
- char *pTypeName;
- int boardID;
- int numFpga;
- int adcState;
- rtapi_u32 watchdogControl;// Shadow HW register.
-
- // Exported to HAL.
- EncoderPinsParams encoder[MOTENC_NUM_ENCODER_CHANNELS];
- DacPinsParams dac[MOTENC_NUM_DAC_CHANNELS];
- AdcPinsParams adc[MOTENC_NUM_ADC_CHANNELS];
- DigitalInPinsParams in[MOTENC_NUM_DIGITAL_INPUTS];
- DigitalOutPinsParams out[MOTENC_NUM_DIGITAL_OUTPUTS];
- MiscPinsParams misc;
-} Device;
-
-
-// These methods are used for initialization.
-static int Device_Init(Device *this, MotencRegMap *pCard);
-static int Device_ExportPinsParametersFunctions(Device *this, int componentId);
-static int Device_ExportEncoderPinsParametersFunctions(Device *this, int componentId, int boardId);
-static int Device_ExportDacPinsParametersFunctions(Device *this, int componentId, int boardId);
-static int Device_ExportAdcPinsParametersFunctions(Device *this, int componentId, int boardId);
-static int Device_ExportDigitalInPinsParametersFunctions(Device *this, int componentId, int boardId);
-static int Device_ExportDigitalOutPinsParametersFunctions(Device *this, int componentId, int boardId);
-static int Device_ExportMiscPinsParametersFunctions(Device *this, int componentId, int boardId);
-
-// These methods are exported to the HAL.
-static void Device_EncoderRead(void *this, long period);
-static void Device_DacWrite(void *this, long period);
-static void Device_AdcRead(void *this, long period);
-static void Device_DigitalInRead(void *this, long period);
-static void Device_DigitalOutWrite(void *this, long period);
-static void Device_MiscUpdate(void *this, long period);
-
-// Private helper methods.
-static int Device_AdcRead4(Device *this, int startChannel);
-
-
-/******************************************************************************
- * DRIVER OBJECT
- *
- * This object contains all the data for this HAL component.
- *
- ******************************************************************************/
-
-#define MAX_DEVICES 4 // Since there are 2 board id bits.
-
-typedef struct {
- int componentId; // HAL component ID.
- Device *deviceTable[MAX_DEVICES];
- unsigned char idPresent[MAX_DEVICES];
-} Driver;
-
-static Driver driver;
-
-
-/******************************************************************************
- * INIT AND EXIT CODE
- ******************************************************************************/
-
-int
-rtapi_app_main(void)
-{
- int i, j;
- struct pci_dev *pDev = NULL;
- MotencRegMap *pCard = NULL;
- Device *pDevice;
-
- // Connect to the HAL.
- driver.componentId = hal_init("hal_motenc");
- if (driver.componentId < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: hal_init() failed\n");
- return(-EINVAL);
- }
-
- for(i = 0; i < MAX_DEVICES; i++){
- driver.deviceTable[i] = NULL;
- driver.idPresent[i] = 0;
- }
-
- i = 0;
- // Find a MOTENC card.
- while((i < MAX_DEVICES) && ((pDev = pci_get_device(MOTENC_VENDOR_ID, MOTENC_DEVICE_ID, pDev)) != NULL)){
-
- // Allocate memory for device object.
- pDevice = hal_malloc(sizeof(Device));
-
- if (pDevice == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: hal_malloc() failed\n");
- hal_exit(driver.componentId);
- return(-ENOMEM);
- }
-
- // Save pointer to device object.
- driver.deviceTable[i++] = pDevice;
-
- // Map card into memory.
- pCard = (MotencRegMap *)ioremap_nocache(pci_resource_start(pDev, 2), pci_resource_len(pDev, 2));
- rtapi_print_msg(RTAPI_MSG_INFO, "MOTENC: Card detected in slot %2x\n", PCI_SLOT(pDev->devfn));
- rtapi_print_msg(RTAPI_MSG_INFO, "MOTENC: Card address @ %p, Len = %d\n", pCard, (int)pci_resource_len(pDev, 2));
-
- // Initialize device.
- Device_Init(pDevice, pCard);
- rtapi_print_msg(RTAPI_MSG_INFO, "MOTENC: Card is %s, ID: %d\n", pDevice->pTypeName, pDevice->boardID);
- if ( pDevice->boardType == 0 ) {
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR, unknown card detected\n");
- hal_exit(driver.componentId);
- return(-ENODEV);
- }
-
-
- if ( driver.idPresent[pDevice->boardID] != 0 ) {
- // duplicate ID... a strict driver would bail out, but
- // we are nice, we try to find an unused ID
- j = 0;
- while ( driver.idPresent[j] != 0 ) {
- j++;
- if ( j >= MAX_DEVICES ) {
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR, duplicate ID, can't remap\n");
- hal_exit(driver.componentId);
- return(-EINVAL);
- }
- }
- pDevice->boardID = j;
- rtapi_print_msg(RTAPI_MSG_WARN, "MOTENC: WARNING, duplicate ID, remapped to %d\n", j);
- }
- driver.idPresent[pDevice->boardID] = 1;
-
- // Export pins, parameters, and functions.
- if(Device_ExportPinsParametersFunctions(pDevice, driver.componentId)){
- hal_exit(driver.componentId);
- return(-EINVAL);
- }
- }
-
- if(pCard == NULL){
- // No card present.
- rtapi_print_msg(RTAPI_MSG_WARN, "MOTENC: **** No MOTENC card detected ****\n");
- hal_exit(driver.componentId);
- return -ENODEV;
- }
-
- hal_ready(driver.componentId);
- return(0);
-}
-
-
-void
-rtapi_app_exit(void)
-{
- int i, j;
- Device *pDevice;
-
- hal_exit(driver.componentId);
-
- for(i = 0; i < MAX_DEVICES; i++){
- if((pDevice = driver.deviceTable[i]) != NULL){
- // turn off digital outputs
- for(j = 0; j < pDevice->numFpga; j++){
- pDevice->pCard->fpga[j].digitalIo = MOTENC_DIGITAL_OUT;
- }
- // set DAC outputs to zero volts
- for(j = 0; j < MOTENC_NUM_DAC_CHANNELS; j++){
- pDevice->pCard->dac[j] = MOTENC_DAC_COUNT_ZERO;
- }
-
- // Unmap card.
- iounmap((void *)(pDevice->pCard));
-
- // TODO: Free device object when HAL supports free.
-// hal_free(pDevice);
- }
- }
-}
-
-
-/******************************************************************************
- * DEVICE OBJECT FUNCTION DEFINITIONS
- ******************************************************************************/
-
-/*
- * LOCAL FUNCTIONS
- */
-
-static int
-Device_Init(Device *this, MotencRegMap *pCard)
-{
- int i, status;
-
- this->pCard = pCard;
- this->adcState = 0;
- this->watchdogControl = 0;
-
- // Identify type of board.
- status = pCard->fpga[0].boardVersion;
- if ( status == 0 ) {
- // MOTENC-100.
- this->boardType = 1;
- this->pTypeName = "MOTENC-100";
- this->numFpga = 2;
- } else if ( status == 1 ) {
- // MOTENC-Lite.
- this->boardType = 2;
- this->pTypeName = "MOTENC-Lite";
- this->numFpga = 1;
- } else {
- // No idea what it is.
- this->boardType = 2;
- this->pTypeName = "unknown";
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: unknown board type - %i\n", status);
- this->numFpga = 0;
- //return -1;
- }
-
- // Extract board id from first FPGA. The user sets this via jumpers on the card.
- status = pCard->fpga[0].statusControl;
- this->boardID = (status & MOTENC_STATUS_BOARD_ID) >> MOTENC_STATUS_BOARD_ID_SHFT;
-
- // Initialize hardware.
- for(i = 0; i < this->numFpga; i++){
- pCard->fpga[i].digitalIo = MOTENC_DIGITAL_OUT;
- pCard->fpga[i].statusControl = MOTENC_CONTROL_ENCODER_RESET;
- }
-
- for(i = 0; i < MOTENC_NUM_DAC_CHANNELS; i++){
- pCard->dac[i] = MOTENC_DAC_COUNT_ZERO;
- }
-
- pCard->timerIrqDisable = 1;
- pCard->watchdogControl = this->watchdogControl;
-
- return(0);
-}
-
-
-static int
-Device_ExportPinsParametersFunctions(Device *this, int componentId)
-{
- int msgLevel, boardId, error;
-
- // This function exports a lot of stuff, which results in a lot of
- // logging if msg_level is at INFO or ALL. So we save the current value
- // of msg_level and restore it later. If you actually need to log this
- // function's actions, change the second line below.
- msgLevel = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
-
- boardId = this->boardID;
-
- // Export encoders.
- error = Device_ExportEncoderPinsParametersFunctions(this, componentId, boardId);
-
- // Export DACs.
- if(!error) error = Device_ExportDacPinsParametersFunctions(this, componentId, boardId);
-
- // Export ADCs.
- if(!error) error = Device_ExportAdcPinsParametersFunctions(this, componentId, boardId);
-
- // Export digital I/O.
- if(!error) error = Device_ExportDigitalInPinsParametersFunctions(this, componentId, boardId);
- if(!error) error = Device_ExportDigitalOutPinsParametersFunctions(this, componentId, boardId);
-
- // Export miscellaneous.
- if(!error) error = Device_ExportMiscPinsParametersFunctions(this, componentId, boardId);
-
- // Restore saved message level.
- rtapi_set_msg_level(msgLevel);
-
- return(error);
-}
-
-
-static int
-Device_ExportEncoderPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError, channel;
-
- // Export pins and parameters.
- halError = 0;
- for(channel = 0; channel < this->numFpga * MOTENC_FPGA_NUM_ENCODER_CHANNELS; channel++){
- // Pins.
- if((halError = hal_pin_new_si32(componentId, HAL_OUT, &(this->encoder[channel].pCount),
- 0, "motenc.%d.enc-%02d-count", boardId, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_real(componentId, HAL_OUT, &(this->encoder[channel].pPosition),
- 0.0, "motenc.%d.enc-%02d-position", boardId, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(componentId, HAL_OUT, &(this->encoder[channel].pIndex),
- 0, "motenc.%d.enc-%02d-index", boardId, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(componentId, HAL_IO, &(this->encoder[channel].pIndexEnable),
- 0, "motenc.%d.enc-%02d-index-enable", boardId, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(componentId, HAL_IN, &(this->encoder[channel].pReset),
- 0, "motenc.%d.enc-%02d-reset", boardId, channel)) != 0)
- break;
-
- // Parameters.
- if((halError = hal_param_new_real(componentId, HAL_RW, &(this->encoder[channel].scale),
- 1.0, "motenc.%d.enc-%02d-scale", boardId, channel)) != 0)
- break;
-
- // Init encoder.
- this->encoder[channel].oldScale = 1.0;
- this->encoder[channel].scaleRecip = 1.0 / hal_get_real(this->encoder[channel].scale);
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_EncoderRead, this, 1, 0, componentId, "motenc.%d.encoder-read", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export encoder failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-static int
-Device_ExportDacPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError, channel;
-
- // Export pins and parameters.
- halError = 0;
- for(channel = 0; channel < MOTENC_NUM_DAC_CHANNELS; channel++){
- // Pins.
- if((halError = hal_pin_new_real(componentId, HAL_IN, &(this->dac[channel].pValue),
- 0.0, "motenc.%d.dac-%02d-value", boardId, channel)) != 0)
- break;
-
- // Parameters.
- if((halError = hal_param_new_real(componentId, HAL_RW, &(this->dac[channel].offset),
- 0.0, "motenc.%d.dac-%02d-offset", boardId, channel)) != 0)
- break;
-
- if((halError = hal_param_new_real(componentId, HAL_RW, &(this->dac[channel].gain),
- 1.0, "motenc.%d.dac-%02d-gain", boardId, channel)) != 0)
- break;
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_DacWrite, this, 1, 0, componentId, "motenc.%d.dac-write", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export DAC failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-static int
-Device_ExportAdcPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError, channel;
-
- // Export pins and parameters.
- halError = 0;
- for(channel = 0; channel < MOTENC_NUM_ADC_CHANNELS; channel++){
- // Pins.
- if((halError = hal_pin_new_real(componentId, HAL_OUT, &(this->adc[channel].pValue),
- 0.0, "motenc.%d.adc-%02d-value", boardId, channel)) != 0)
- break;
-
- // Parameters.
- if((halError = hal_param_new_real(componentId, HAL_RW, &(this->adc[channel].offset),
- 0.0, "motenc.%d.adc-%02d-offset", boardId, channel)) != 0)
- break;
-
- if((halError = hal_param_new_real(componentId, HAL_RW, &(this->adc[channel].gain),
- 1.0, "motenc.%d.adc-%02d-gain", boardId, channel)) != 0)
- break;
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_AdcRead, this, 1, 0, componentId, "motenc.%d.adc-read", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export ADC failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-static int
-Device_ExportDigitalInPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError, channel;
-
- // Export pins and parameters.
- halError = 0;
- for(channel = 0; channel < (this->numFpga * MOTENC_FPGA_NUM_DIGITAL_INPUTS - 4); channel++){
- // Pins.
- if((halError = hal_pin_new_bool(componentId, HAL_OUT, &(this->in[channel].pValue),
- 0, "motenc.%d.in-%02d", boardId, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(componentId, HAL_OUT, &(this->in[channel].pValueNot),
- 1, "motenc.%d.in-%02d-not", boardId, channel)) != 0)
- break;
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_DigitalInRead, this, 0, 0, componentId, "motenc.%d.digital-in-read", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export digital in failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-static int
-Device_ExportDigitalOutPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError, channel;
-
- // Export pins and parameters.
- halError = 0;
- for(channel = 0; channel < this->numFpga * MOTENC_FPGA_NUM_DIGITAL_OUTPUTS; channel++){
- // Pins.
- if((halError = hal_pin_new_bool(componentId, HAL_IN, &(this->out[channel].pValue),
- 0, "motenc.%d.out-%02d", boardId, channel)) != 0)
- break;
-
- // Parameters.
- if((halError = hal_param_new_bool(componentId, HAL_RW, &(this->out[channel].invert),
- 0, "motenc.%d.out-%02d-invert", boardId, channel)) != 0)
- break;
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_DigitalOutWrite, this, 0, 0, componentId, "motenc.%d.digital-out-write", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export digital out failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-static int
-Device_ExportMiscPinsParametersFunctions(Device *this, int componentId, int boardId)
-{
- int halError;
-
- // Export Pins.
- halError = hal_pin_new_bool(componentId, HAL_OUT, &(this->misc.pEstopIn), 0,
- "motenc.%d.estop-in", boardId);
-
- if(!halError){
- halError = hal_pin_new_bool(componentId, HAL_OUT, &(this->misc.pEstopInNot), 1,
- "motenc.%d.estop-in-not", boardId);
- }
-
- if(!halError){
- halError = hal_pin_new_bool(componentId, HAL_IO, &(this->misc.pWatchdogReset), 0,
- "motenc.%d.watchdog-reset", boardId);
- }
-
- // Export Parameters.
- if(!halError){
- halError = hal_param_new_ui32(componentId, HAL_RW, &(this->misc.watchdogControl), this->watchdogControl,
- "motenc.%d.watchdog-control", boardId);
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_MiscUpdate, this, 0, 0, componentId, "motenc.%d.misc-update", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "MOTENC: ERROR: export miscellaneous failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-/*
- * HAL EXPORTED FUNCTIONS
- */
-
-static void
-Device_EncoderRead(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
- EncoderPinsParams *pEncoder;
- int i, j;
- rtapi_u32 status;
-
- pEncoder = &this->encoder[0];
-
- // For each FPGA.
- for(i = 0; i < this->numFpga; i++){
-
- // read status register just once, before writing anything to the card
- status = pCard->fpga[i].statusControl;
-
- // For each encoder.
- for(j = 0; j < MOTENC_FPGA_NUM_ENCODER_CHANNELS; j++, pEncoder++){
-
- // Check reset pin.
- if(hal_get_bool(pEncoder->pReset)){
- // Reset encoder.
- pCard->fpga[i].statusControl = 1 << (MOTENC_CONTROL_ENCODER_RESET_SHFT + j);
- }
-
- // check state of hardware index pin
- hal_set_bool(pEncoder->pIndex, (status >> (MOTENC_STATUS_INDEX_SHFT + j)) & 1);
-
- // check for index pulse detected
- if((status >> (MOTENC_STATUS_INDEX_LATCH_SHFT + j)) & 1){
- // cancel index-enable
- hal_set_bool(pEncoder->pIndexEnable, 0);
- }
-
- // Check for index enable request from HAL
- if(hal_get_bool(pEncoder->pIndexEnable)){
- // tell hardware to latch on index
- pCard->fpga[i].encoderCount[j] = 1;
- } else {
- // cancel hardware latch on index
- pCard->fpga[i].encoderCount[j] = 0;
- }
-
- // Read encoder counts.
- hal_set_si32(pEncoder->pCount, pCard->fpga[i].encoderCount[j]);
-
- // Check for change in scale value.
- if ( hal_get_real(pEncoder->scale) != pEncoder->oldScale ) {
- // Get ready to detect future scale changes.
- pEncoder->oldScale = hal_get_real(pEncoder->scale);
-
- // Validate the new scale value.
- if ((hal_get_real(pEncoder->scale) < 1e-20) && (hal_get_real(pEncoder->scale) > -1e-20)) {
- // Value too small, divide by zero is a bad thing.
- hal_set_real(pEncoder->scale, 1.0);
- }
-
- // We will need the reciprocal.
- pEncoder->scaleRecip = 1.0 / hal_get_real(pEncoder->scale);
- }
-
- // Scale count to make floating point position.
- hal_set_real(pEncoder->pPosition, hal_get_si32(pEncoder->pCount) * pEncoder->scaleRecip);
- }
- }
-}
-
-
-static void
-Device_DacWrite(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
- DacPinsParams *pDac;
- int i;
- rtapi_real volts;
- rtapi_u32 dacCount;
-
- pDac = &this->dac[0];
-
- // For each DAC.
- for(i = 0; i < MOTENC_NUM_DAC_CHANNELS; i++, pDac++){
-
- // Calculate hardware register value.
- volts = (hal_get_real(pDac->pValue) - hal_get_real(pDac->offset)) * hal_get_real(pDac->gain);
-
- // Truncate volts to DAC limits.
- if(volts > MOTENC_DAC_VOLTS_MAX){
- volts = MOTENC_DAC_VOLTS_MAX;
- }else if(volts < MOTENC_DAC_VOLTS_MIN){
- volts = MOTENC_DAC_VOLTS_MIN;
- }
-
- // Transform volts to counts.
- dacCount = (rtapi_u32)(volts * MOTENC_DAC_SCALE_MULTIPLY /
- MOTENC_DAC_SCALE_DIVIDE + MOTENC_DAC_COUNT_ZERO);
-
- // Write DAC.
- pCard->dac[i] = dacCount;
- }
-}
-
-
-static void
-Device_AdcRead(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
-
- switch(this->adcState){
- // Start conversion on first 4 channels.
- case 0:
- this->adcState++;
- pCard->adcDataCommand = MOTENC_ADC_COMMAND_CHN_0_1_2_3;
- pCard->adcStartConversion = 1;
- break;
-
- // Wait for first conversion, start conversion on second 4 channels.
- case 1:
- if(Device_AdcRead4(this, 0)){
- this->adcState++;
-
- // Start next conversion.
- pCard->adcDataCommand = MOTENC_ADC_COMMAND_CHN_4_5_6_7;
- pCard->adcStartConversion = 1;
- }
- break;
-
- // Wait for second conversion, start conversion on first 4 channels.
- case 2:
- if(Device_AdcRead4(this, 4)){
- this->adcState = 1;
-
- // Start next conversion.
- pCard->adcDataCommand = MOTENC_ADC_COMMAND_CHN_0_1_2_3;
- pCard->adcStartConversion = 1;
- }
- break;
-
- default:
- this->adcState = 0;
- }
-}
-
-
-static int
-Device_AdcRead4(Device *this, int startChannel)
-{
- MotencRegMap *pCard = this->pCard;
- AdcPinsParams *pAdc;
- int i;
- rtapi_s32 adcCount;
- rtapi_real volts;
-
- if(pCard->fpga[0].statusControl & MOTENC_STATUS_ADC_DONE)
- return(0);
-
- pAdc = &this->adc[startChannel];
-
- // Get conversion results.
- for(i = 0; i < 4; i++, pAdc++){
- adcCount = pCard->adcDataCommand;
-
- // Sign extend result.
- if(adcCount & MOTENC_ADC_SIGN_BIT){
- adcCount |= MOTENC_ADC_SIGN_EXTEND;
- }
-
- // Transform count to volts.
- volts = adcCount * MOTENC_ADC_SCALE_MULTIPLY / MOTENC_ADC_SCALE_DIVIDE;
-
- // Scale and offset volts.
- volts = volts * hal_get_real(pAdc->gain) - hal_get_real(pAdc->offset);
-
- // Update pin.
- hal_set_real(pAdc->pValue, volts);
- }
-
- return(1);
-}
-
-
-static void
-Device_DigitalInRead(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
- DigitalInPinsParams *pDigitalIn;
- int i, j, n;
- rtapi_u32 pins;
-
- pDigitalIn = &this->in[0];
-
- // For each FPGA.
- for(i = 0; i < this->numFpga; i++){
-
- // Read digital I/O register.
- pins = ~pCard->fpga[i].digitalIo >> MOTENC_DIGITAL_IN_SHFT;
-
- // For each pin.
- for(j = 0; j < 16; j++, pDigitalIn++){
-
- // Update pins.
- rtapi_bool b = hal_set_bool(pDigitalIn->pValue, pins & 1);
- hal_set_bool(pDigitalIn->pValueNot, !b);
-
- pins >>= 1;
- }
-
- // Read status register.
- pins = ~pCard->fpga[i].statusControl >> MOTENC_STATUS_DIGITAL_IN_SHFT;
-
- // First FPGA only has 16 inputs in the status register. The other 4 are
- // used for special purpose inputs like board id, ADC done, and E-STOP.
- n = (i)? 20: 16;
-
- // For each pin.
- for(j = 0; j < n; j++, pDigitalIn++){
-
- // Update pins.
- rtapi_bool b = hal_set_bool(pDigitalIn->pValue, pins & 1);
- hal_set_bool(pDigitalIn->pValueNot, !b);
-
- pins >>= 1;
- }
- }
-}
-
-
-static void
-Device_DigitalOutWrite(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
- DigitalOutPinsParams *pDigitalOut;
- int i, j;
- rtapi_u32 pins, mask;
-
- pDigitalOut = &this->out[0];
-
- // For each FPGA.
- for(i = 0; i < this->numFpga; i++){
-
- pins = 0;
- mask = 1;
-
- // For each pin.
- for(j = 0; j < MOTENC_FPGA_NUM_DIGITAL_OUTPUTS; j++, pDigitalOut++){
-
- // Build hardware register value.
- if(hal_get_bool(pDigitalOut->pValue) != hal_get_bool(pDigitalOut->invert)){
- pins |= mask;
- }
-
- mask <<=1;
- }
-
- // Write digital I/O register.
- // invert for active low OPTO-22 modules
- pCard->fpga[i].digitalIo = ~pins << MOTENC_DIGITAL_OUT_SHFT;
- }
-}
-
-
-static void
-Device_MiscUpdate(void *arg, long period)
-{
- Device *this = (Device *)arg;
- MotencRegMap *pCard = this->pCard;
-
- // Check watchdog control parameter.
- if(this->watchdogControl != hal_get_ui32(this->misc.watchdogControl)){
- // Update shadow register.
- this->watchdogControl = hal_get_ui32(this->misc.watchdogControl);
-
- // Write hardware.
- pCard->watchdogControl = this->watchdogControl;
- }
-
- // Check watchdog reset pin.
- if(hal_get_bool(this->misc.pWatchdogReset)){
- // Clear pin.
- hal_set_bool(this->misc.pWatchdogReset, 0);
-
- // Reset the watchdog timer.
- pCard->watchdogReset = MOTENC_WATCHDOG_RESET_VALUE;
- }
-
- // Update E-STOP pin.
- rtapi_bool b = hal_set_bool(this->misc.pEstopIn, (pCard->fpga[0].statusControl & MOTENC_STATUS_ESTOP)? 1: 0);
- hal_set_bool(this->misc.pEstopInNot, !b);
-}
diff --git a/src/hal/drivers/hal_skeleton.c b/src/hal/drivers/hal_skeleton.c
deleted file mode 100644
index 2496f066152..00000000000
--- a/src/hal/drivers/hal_skeleton.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/********************************************************************
-* Description: hal_skeleton.c
-* This file, 'hal_skeleton.c', is a example that shows
-* how drivers for HAL components will work and serve as
-* a skeleton for new hardware drivers.
-*
-* Author: John Kasunich
-* License: GPL Version 2
-*
-* Copyright (c) 2003 All rights reserved.
-*
-* Last change:
-********************************************************************/
-
-/** This file, 'hal_skeleton.c', is a example that shows how
- drivers for HAL components will work and serve as a skeleton
- for new hardware drivers.
-
- Most of this code is taken from the hal_parport driver from John Kasunich,
- which is also a good starting point for new drivers.
-
- This driver supports only for demonstration how to write a byte (char)
- to a hardware address, here we use the parallel port (0x378).
-
- This driver support no configuration strings so installing is easy:
- realtime: halcmd loadrt hal_skeleton
-
- The driver creates a HAL pin and if it run in realtime a function
- as follows:
-
- Pin: 'skeleton..pin--out'
- Function: 'skeleton..write'
-
- This skeleton driver also doesn't use arguments you can pass to the driver
- at startup. Please look at the parport driver how to implement this if you need
- this for your driver.
-
- (added 17 Nov 2006)
- The approach used for writing HAL drivers has evolved quite a bit over the
- three years since this was written. Driver writers should consult the HAL
- User Manual for information about canonical device interfaces, and should
- examine some of the more complex drivers, before using this as a basis for
- a new driver.
-
-*/
-
-/** Copyright (C) 2003 John Kasunich
-
- Martin Kuhnle
-
-*/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-
-#include /* HAL public API decls */
-
-/* If FASTIO is defined, uses outb() and inb() from ,
- instead of rtapi_outb() and rtapi_inb() - the ones
- are inlined, and save a microsecond or two (on my 233MHz box)
-*/
-#define FASTIO
-
-#ifdef FASTIO
-#define rtapi_inb inb
-#define rtapi_outb outb
-#include
-#endif
-
-/* module information */
-MODULE_AUTHOR("Martin Kuhnle");
-MODULE_DESCRIPTION("Test Driver for ISA-LED Board for EMC HAL");
-MODULE_LICENSE("GPL");
-/* static char *cfg = 0; */
-/* config string
-RTAPI_MP_STRING(cfg, "config string"); */
-
-/***********************************************************************
-* STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-/* this structure contains the runtime data needed by the
- driver for a single port/channel
-*/
-
-typedef struct {
- hal_uint_t data_out; /* ptrs for output */
-} skeleton_t;
-
-/* pointer to array of skeleton_t structs in shared memory, 1 per port */
-static skeleton_t *port_data_array;
-
-/* other globals */
-static int comp_id; /* component ID */
-static int num_ports; /* number of ports configured */
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-/* These is the functions that actually do the I/O
- everything else is just init code
-*/
-static void write_port(void *arg, long period);
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_PORTS 8
-
-#define MAX_TOK ((MAX_PORTS*2)+3)
-
-int rtapi_app_main(void)
-{
- int n, retval;
-
- /* only one port at the moment */
- num_ports = 1;
- n = 0; /* port number */
-
- /* STEP 1: initialise the driver */
- comp_id = hal_init("hal_skeleton");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "SKELETON: ERROR: hal_init() failed\n");
- return -1;
- }
-
- /* STEP 2: allocate shared memory for skeleton data */
- port_data_array = hal_malloc(num_ports * sizeof(skeleton_t));
- if (port_data_array == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "SKELETON: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- /* STEP 3: export the pin(s) */
- retval = hal_pin_new_ui32(comp_id, HAL_IN, &(port_data_array->data_out),
- 0, "skeleton.%d.pin-%02d-out", n, 1);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "SKELETON: ERROR: port %d var export failed with err=%i\n", n,
- retval);
- hal_exit(comp_id);
- return -1;
- }
-
- /* STEP 4: export write function */
- retval = hal_export_functf(write_port, &(port_data_array[n]), 0, 0,
- comp_id, "skeleton.%d.write", n);
- if (retval < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "SKELETON: ERROR: port %d write funct export failed\n", n);
- hal_exit(comp_id);
- return -1;
- }
-
- rtapi_print_msg(RTAPI_MSG_INFO,
- "SKELETON: installed driver for %d ports\n", num_ports);
- hal_ready(comp_id);
- return 0;
-}
-
-void rtapi_app_exit(void)
-{
- hal_exit(comp_id);
-}
-
-/**************************************************************
-* REALTIME PORT WRITE FUNCTION *
-**************************************************************/
-
-static void write_port(void *arg, long period)
-{
- skeleton_t *port;
- unsigned char outdata;
- port = arg;
-
- outdata = hal_get_ui32(port->data_out) & 0xFF;
- /* write it to the hardware */
- rtapi_outb(outdata, 0x378);
-}
diff --git a/src/hal/drivers/hal_stg.c b/src/hal/drivers/hal_stg.c
deleted file mode 100644
index 95d2c5c1766..00000000000
--- a/src/hal/drivers/hal_stg.c
+++ /dev/null
@@ -1,1645 +0,0 @@
-/********************************************************************
-* Description: hal_stg.c
-* This is the driver for Servo-To-Go Model I & II board.
-*
-* Author: Alex Joni
-* License: GPL Version 2
-*
-* Copyright (c) 2004 All rights reserved.
-* see below for additional notes
-*
-* Last change:
-********************************************************************/
-
-/** This is the driver for Servo-To-Go Model I & II board.
- The board includes 8 channels of quadrature encoder input,
- 8 channels of analog input and output, 32 bits digital I/O,
- and an interval timer with interrupt.
-
- Installation of the driver only realtime:
-
- insmod hal_stg num_chan=8 dio="IIOO"
- - autodetects the address
- or
-
- insmod hal_stg base=0x200 num_chan=8 dio="IIOO"
-
- Check your Hardware manual for your base address.
-
- The digital inputs/outputs configuration is determined by a
- config string passed to insmod when loading the module.
- The format consists by a four character string that sets the
- direction of each group of pins. Each character of the direction
- string is either "I" or "O". The first character sets the
- direction of port A (Port A - DIO.0-7), the next sets
- port B (Port B - DIO.8-15), the next sets port C (Port C - DIO.16-23),
- and the fourth sets port D (Port D - DIO.24-31).
-
- The following items are exported to the HAL.
-
- Encoders:
- Parameters:
- float stg..position-scale (counts per unit)
-
- Pins:
- s32 stg..counts
- float stg..position
-
-/todo bit stg..index-enable
-/todo bit stg..enc-reset-count
-
- Functions:
- void stg..capture_position
-
-
- DACs:
- Parameters:
- float stg..dac-offset
- float stg..dac-gain
-
- Pins:
- float stg..dac-value
-
- Functions:
- void stg..dac-write
-
-
- ADC:
- Parameters:
- float stg..adc-offset
- float stg..adc-gain
-
- Pins:
- float stg..adc-value
-
- Functions:
- void stg..adc-read
-
-
- Digital In:
- Pins:
- bit stg.in-
- bit stg.in--not
-
- Functions:
- void stg.digital-in-read
-
-
- Digital Out:
- Parameters:
- bit stg.out--invert
-
- Pins:
- bit stg.out-
-
- Functions:
- void stg.digital-out-write
-
-*/
-
-/** Copyright (C) 2004 Alex Joni
-
-*/
-
-/** Copyright (C) 2003 John Kasunich
-
-*/
-
-/* Based on STGMEMBS.CPP from the Servo To Go Windows drivers
- - Copyright (c) 1996 Servo To Go Inc and released under GPL Version 2 */
-/* Also relates to the EMC1 code (very similar to STGMEMBS.CPP)
- work done by Fred Proctor, Will Shackleford */
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-#include /* HAL public API decls */
-#include "hal_stg.h" /* STG related defines */
-
-/* module information */
-MODULE_AUTHOR("Alex Joni");
-MODULE_DESCRIPTION("Driver for Servo-to-Go Model I & II for EMC HAL");
-MODULE_LICENSE("GPL");
-static int base = 0x00; /* board base address, 0 means autodetect */
-RTAPI_MP_INT(base, "board base address, don't use for autodetect");
-static int model = 0; /* board model, leave empty and autodetect */
-RTAPI_MP_INT(model, "board model, use with caution. it overrides the detected model");
-static int num_chan = MAX_CHANS; /* number of channels - default = 8 */
-RTAPI_MP_INT(num_chan, "number of channels");
-static char *dio = "IIOO"; /* dio config - default = port A&B inputs, port C&D outputs */
-RTAPI_MP_STRING(dio, "dio config string - expects something like IIOO");
-
-#define EPSILON 1e-20
-
-/***********************************************************************
-* STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-typedef struct {
- hal_bool_t data; /* basic pin for input or output */
- union {
- hal_bool_t not; /* pin for inverted data (input only) */
- hal_bool_t invert; /* param for inversion (output only) */
- } io;
-} io_pin;
-
-typedef struct {
-/* counter data */
- hal_sint_t count[MAX_CHANS]; /* captured binary count value */
- rtapi_s32 offset[MAX_CHANS]; /* offset to hold latched position from index pulse */
- hal_real_t pos[MAX_CHANS]; /* scaled position (floating point) */
- hal_real_t pos_scale[MAX_CHANS]; /* parameter: scaling factor for pos */
- hal_bool_t index_enable[MAX_CHANS]; /* pins for index homing */
- hal_bool_t index_latch[MAX_CHANS]; /* value of the index latch for the axis */
-// hal_s32_t check_index[MAX_CHANS]; /* internal marker for two stage index pulse check */
- hal_bool_t index_polarity[MAX_CHANS]; /* Polarity of index pulse */
-
-/* dac data */
- hal_real_t dac_value[MAX_CHANS]; /* value to be written to dac */
- hal_real_t dac_offset[MAX_CHANS]; /* offset value for DAC */
- hal_real_t dac_gain[MAX_CHANS]; /* gain to be applied */
-
-/* adc data */
- hal_real_t adc_value[MAX_CHANS]; /* value to be read from adc */
- hal_real_t adc_offset[MAX_CHANS]; /* offset value for ADC */
- hal_real_t adc_gain[MAX_CHANS]; /* gain to be applied */
- int adc_current_chan; /* holds the currently converting channel */
-
-/* dio data */
- io_pin port[4][8]; /* holds 4 ports each 8 pins, either input or output */
- unsigned char dir_bits; /* remembers config (which port is input which is output) */
-
- unsigned char model;
-
-} stg_struct;
-
-static stg_struct *stg_driver;
-
-/* other globals */
-static int comp_id; /* component ID */
-static int outpinnum=0, inputpinnum=0;
-//const int STG_MSG_LEVEL = RTAPI_MSG_ALL;
-const int STG_MSG_LEVEL = RTAPI_MSG_INFO;
-
-#define DATA(x) (base + (2 * x) - (x % 2)) /* Address of Data register 0 */
-#define CTRL(x) (base + (2 * (x+1)) - (x % 2)) /* Address of Control register 0 */
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-/* helper functions, to export HAL pins & co. */
-static int export_counter(int num, stg_struct * addr);
-static int export_dac(int num, stg_struct * addr);
-static int export_adc(int num, stg_struct * addr);
-static int export_pins(int num, int dir, stg_struct * addr);
-static int export_input_pin(int pinnum, io_pin * pin);
-static int export_output_pin(int pinnum, io_pin * pin);
-
-/* Board specific functions */
-
-/* initializes the STG, takes care of autodetection, all initialisations */
-static int stg_init_card(void);
-/* sets up interrupt to be used */
-static int stg_set_interrupt(short interrupt);
-/* scans possible addresses for STG cards */
-static unsigned short stg_autodetect(void);
-
-/* counter related functions */
-static int stg_counter_init(int ch);
-static long stg_counter_read(int i);
-static void stg_counter_latch(int i);
-static void stg1_select_index_axis(void *arg, unsigned int chan);
-static void stg1_reset_index_latch(void *arg, unsigned int chan);
-static unsigned short stg1_get_index_pulse_latch(void *arg, unsigned int chan);
-
-static void stg2_reset_all_index_latches( void *arg );
-static void stg2_select_index_axes( void *arg, unsigned char mask );
-static unsigned char stg2_get_all_index_pulse_latches( void *arg );
-
-/* dac related functions */
-static int stg_dac_init(int ch);
-static int stg_dac_write(int ch, short value);
-
-/* adc related functions */
-static int stg_adc_init(int ch);
-static int stg_adc_start(void *arg, unsigned short wAxis);
-static short stg_adc_read(void *arg, int ch);
-
-/* dio related functions */
-static int stg_dio_init(void);
-
-/* periodic functions registered to HAL */
-static void stg_adcs_read(void *arg, long period); //reads adc data from the board, check long description at the beginning of the function
-static void stg_dacs_write(void *arg, long period); //writes dac's to the STG
-static void stg_counter_capture(void *arg, long period); //captures encoder counters
-static void stg_di_read(void *arg, long period); //reads digital inputs from the STG
-static void stg_do_write(void *arg, long period); //writes digital outputs to the STG
-//static void stg_debug_print( void *, long );
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_CHAN 8
-
-int rtapi_app_main(void)
-{
- int n, retval, mask, m;
- unsigned char dir_bits;
- int msg;
-
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* test for number of channels */
- if ((num_chan <= 0) || (num_chan > MAX_CHAN)) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: invalid num_chan: %d\n", num_chan);
- return -1;
- }
-
- /* test for config string */
- if ((dio == 0) || (dio[0] == '\0')) {
- rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: no dio config string\n");
- return -1;
- }
-
- /* have good config info, connect to the HAL */
- comp_id = hal_init("hal_stg");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: hal_init() failed\n");
- return -1;
- }
-
- /* allocate shared memory for stg data */
- stg_driver = hal_malloc(num_chan * sizeof(stg_struct));
- if (stg_driver == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- /* takes care of all initialisations, also autodetection and model if necessary */
- if ((retval=stg_init_card()) != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg_init_card() failed\n");
- hal_exit(comp_id);
- return retval;
- }
-
- /* dio should be a string of 4 'I" or "O" characters */
- dir_bits = 0;
- mask = 0x01;
- for ( m = 0 ; m < 4 ; m++ ) {
- /* test character and set/clear bit */
- if ((dio[m] == 'i') || (dio[m] == 'I')) {
- /* input, set mask bit to zero */
- dir_bits &= ~mask;
- } else if ((dio[m] == 'o') || (dio[m] == 'O')) {
- /* output, set mask bit to one */
- dir_bits |= mask;
- } else {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: bad config info for port %d\n", m);
- return -1;
- }
- /* shift mask for next bit */
- mask <<= 1;
- }
-
- /* we now should have directions figured out, next is exporting the pins based on that */
- mask = 0x01;
- for ( m = 0 ; m < 4 ; m++ ) {
-
- /* port, direction, driver */
- export_pins(m, (dir_bits & mask), stg_driver);
-
- /* shift mask for next bit */
- mask <<= 1;
- }
- stg_driver->dir_bits = dir_bits; /* remember direction of each port, will be used in the write / read functions */
-
- stg_dio_init();
-
- /* export all the variables for each counter, dac */
- for (n = 0; n < num_chan; n++) {
- /* export all vars */
- retval = export_counter(n, stg_driver);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: counter %d var export failed\n", n + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_si32(stg_driver->count[n], 0);
- stg_driver->offset[n] = 0;
- hal_set_real(stg_driver->pos[n], 0.0);
-
- /* By default the index pulse is not processed/used */
- hal_set_bool(stg_driver->index_enable[n], 0);
-
- /* Default polarity for the index pulse is active high */
- if( stg_driver->model == 1 )
- {
- hal_set_bool(stg_driver->index_polarity[n], 1);
- }
-
- /* Default value for the index latch output is false */
- hal_set_bool(stg_driver->index_latch[n], 0);
-
- hal_set_real(stg_driver->pos_scale[n], 1.0);
-
- /* init counter chip */
- stg_counter_init(n);
-
- retval = export_dac(n, stg_driver);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: dac %d var export failed\n", n + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_real(stg_driver->dac_value[n], 0);
- hal_set_real(stg_driver->dac_offset[n], 0.0);
- hal_set_real(stg_driver->dac_gain[n], 1.0);
-
- /* init dac chip */
- stg_dac_init(n);
-
- retval = export_adc(n, stg_driver);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: adc %d var export failed\n", n + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_real(stg_driver->adc_value[n], 0);
- hal_set_real(stg_driver->adc_offset[n], 0.0);
- hal_set_real(stg_driver->adc_gain[n], 1.0);
-
- stg_driver->adc_current_chan = -1; /* notify that no conversion has been started yet */
-
- /* init adc chip */
- stg_adc_init(n);
- }
-
- /* export functions */
- retval = hal_export_funct("stg.capture-position", stg_counter_capture,
- stg_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.counter-capture funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed %d encoder counters\n", num_chan);
-
- retval = hal_export_funct("stg.write-dacs", stg_dacs_write,
- stg_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.write-dacs funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed %d dacs\n", num_chan);
-
- retval = hal_export_funct("stg.read-adcs", stg_adcs_read,
- stg_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.read-adcs funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed %d adcs\n", num_chan);
-
- retval = hal_export_funct("stg.di-read", stg_di_read,
- stg_driver, 0, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.di-read funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed %d digital inputs\n", inputpinnum);
-
- retval = hal_export_funct("stg.do-write", stg_do_write,
- stg_driver, 0, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.do-write funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed %d digital outputs\n", outpinnum);
-
- /*
- retval = hal_export_funct("stg.debug_print", stg_debug_print, stg_driver, 0, 0, comp_id);
- if (retval != 0)
- {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: ERROR: stg.debug_print funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: installed periodic debug print\n");
- */
- hal_ready(comp_id);
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- return 0;
-}
-
-void rtapi_app_exit(void)
-{
- hal_exit(comp_id);
- // FIXME, check for return code ?
- return;
-}
-
-/***********************************************************************
-* REALTIME ENCODER COUNTING AND UPDATE FUNCTIONS *
-************************************************************************/
-
-static void stg_counter_capture(void *arg, long period)
-{
- stg_struct *stg = arg;
- int n;
-// int msg;
- unsigned char mask;
- unsigned char index_pulse_latches;
-
- if( stg->model == 1 )
- {
- /*
- * STG Model 1, stg1
- */
- for( n = 0; n < num_chan; n++ )
- {
- /* reset and then select current axes pair to be reset by index
- * Because they index polarity is configurable for the stg2 card be select
- * even for the odd axes */
- stg1_select_index_axis(arg, n);
-
- if (stg1_get_index_pulse_latch(arg, n))
- {
- hal_set_bool(stg->index_latch[n], 1);
-
- if (hal_get_bool(stg->index_enable[n]))
- {
- // read the value without latching, latching was done on index
- // remember this as an offset, it will be substracted from nominal
- stg->offset[n] = stg_counter_read(n);
- /* set index-enable false, so outside knows we found the index, and reset the position */
- hal_set_bool(stg->index_enable[n], 0);
-
- /*
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: Index pulse detected on channel %1d\n", n );
- rtapi_set_msg_level(msg);
- */
- } else {
- /* NOP, no action needed, since the selection of an index pair is just valid until the next
- * pair is selected */
- }
- } else {
- hal_set_bool(stg->index_latch[n], 0);
- }
-
- }
- } else if( stg->model == 2 )
- {
- /*
- * STG Model 2, stg2
- */
-
- // Set IDLEN
- for( mask = 0, n = 0; n < num_chan; n++ )
- {
- if(hal_get_bool(stg->index_enable[n]))
- {
- mask |= ( 1<index_latch[n], 1);
-
- if (hal_get_bool(stg->index_enable[n]))
- {
- // read the value without latching, latching was done on index
- // remember this as an offset, it will be substracted from nominal
- stg->offset[n] = stg_counter_read(n);
- /* set index-enable false, so outside knows we found the index, and reset the position */
- hal_set_bool(stg->index_enable[n], 0);
-
- /*
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: Index pulse detected on channel %1d\n", n );
- rtapi_set_msg_level(msg);
- */
- } else {
- /* NOP, no action needed, since all index latches will be clearer for the next iteration anyway */
- }
- } else {
- hal_set_bool(stg->index_latch[n], 0);
- }
- }
- // Reset all latches
- stg2_reset_all_index_latches( arg );
-
- } else {
- // NOP, only models stg1 and stg2, thus should never be reached */
- }
-
- for (n = 0; n < num_chan; n++)
- {
- /* capture raw counts to latches */
- stg_counter_latch(n);
- /* read raw count, and substract the offset (determined by indexed homing) */
- hal_set_si32(stg->count[n], stg_counter_read(n) - stg->offset[n]);
- /* make sure scale isn't zero or tiny to avoid divide error */
- if (hal_get_real(stg->pos_scale[n]) < 0.0) {
- if (hal_get_real(stg->pos_scale[n]) > -EPSILON)
- hal_set_real(stg->pos_scale[n], -1.0);
- } else {
- if (hal_get_real(stg->pos_scale[n]) < EPSILON)
- hal_set_real(stg->pos_scale[n], 1.0);
- }
- /* scale count to make floating point position */
- hal_set_real(stg->pos[n], hal_get_si32(stg->count[n]) / hal_get_real(stg->pos_scale[n]));
- }
- /* done */
- return;
-}
-
-/* stg_debug_print
- * run this function from a very slow,
- * e.g. 1sec thread and it will give some information
- */
-/*
-static void stg_debug_print( void *arg, long period )
-{
- stg_struct *stg=arg;
- int msg;
- static int counter;
-
- // model 2 encoder index registers
- unsigned char idlen_reg;
- unsigned char seldi_reg;
-
- //model 1 encoder index registers
- unsigned char intc_reg;
-
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- if( stg->model == 1 )
- {
- intc_reg = inb(base + INTC);
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: %04d: IXS1 is %s\n", counter, ( intc_reg & IXS1 ) ? "TRUE" : "FALSE" );
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: %04d: IXS0 is %s\n", counter, ( intc_reg & IXS0 ) ? "TRUE" : "FALSE" );
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: %04d: IXLVL is active %s\n", counter, ( intc_reg & IXLVL ) ? "TRUE" : "FALSE" );
-
- } else if (stg->model == 2 )
- {
- idlen_reg = inb( base + IDLEN );
- seldi_reg = inb( base + SELDI );
-
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: %04d: IDLEN is 0x%02x\n", counter, idlen_reg );
- rtapi_print_msg(RTAPI_MSG_DBG, "STG: %04d: SELDI is 0x%02x\n", counter, seldi_reg );
-
- } else {
- // NOP, should never be reached
- }
-
- // restore saved message level
- rtapi_set_msg_level(msg);
-
- counter++;
-
- return;
-}
-*/
-
-/* stg_dacs_write() - writes all dac's to the board
- - calls stg_dac_write() */
-static void stg_dacs_write(void *arg, long period)
-{
- stg_struct *stg;
- double volts;
- short ncounts, i;
-
- stg=arg;
- for (i=0;i < num_chan; i++) {
- /* scale the voltage to be written based on offset and gain */
- volts = (hal_get_real(stg->dac_value[i]) - hal_get_real(stg->dac_offset[i])) * hal_get_real(stg->dac_gain[i]);
- /* clamp the scaled voltage value to the -10V to 10V output range of the STG */
- if (volts < -10.0)
- volts = -10.0;
- if (volts > 10.0)
- volts = 10.0;
- /* compute the value for the DAC, the extra - in there is STG specific */
- ncounts = (short) ((((-10.0 - volts) * 0x1FFF) / 20.0) - 1 );
- /* write it to the card */
- stg_dac_write(i, ncounts);
- }
- return;
-}
-
-/* stg_adcs_read() - reads one adc at a time from the board to hal
- - calls stg_adc_read() */
-
-/* long description :
-
- Because the conversion takes a while (first mux to the right channel ~5usecs,
- then start the conversion, and wait for it to finish ~16-20 usecs) for all the
- 8 channels, it would be too much to start the conversion, wait for the result
- for all the 8 axes.
- Instead a different approach is chosen:
- - on the beginning of the function the conversion should already be done
- - it gets read and sent to HAL
- - the new channel gets mux'ed
- - and at the end of the function the new conversion is started, so that the data
- will be available at the next run.
- This way 8 periods are needed to read 8 ADC's. It is possible to set the board
- to do faster conversions (AZ bit on INTC off), but that would make it less
- reliable (autozero takes care of temp. errors).*/
-/*! \todo STG_ADC_Improvement (if any user requests it).
- Another improvement might be to let the user chose what channels he would like
- for ADC (having only 2 channels might speed things up considerably).
-*/
-static void stg_adcs_read(void *arg, long period)
-{
- stg_struct *stg;
- double volts;
- short ncounts;
- int i;
-
- stg = arg;
- i = stg->adc_current_chan;
- if ((i >= 0) && (i < num_chan)) {
- /* we should have the conversion done for adc_num_chan */
- ncounts = stg_adc_read(stg,i);
- volts = ncounts * 10.0 / 4096;
- hal_set_real(stg->adc_value[i], volts * hal_get_real(stg->adc_gain[i]) - hal_get_real(stg->adc_offset[i]));
- }
- /* if adc_num_chan < 0, it's the first time this routine runs
- thus we don't have any ready data, we simply start the next conversion */
- if (stg->adc_current_chan++ >= num_chan)
- stg->adc_current_chan=0; //increase the channel, and roll back to 0 after all chans are done
-
- /* select the current channel with the mux, and start the conversion */
- stg_adc_start(stg,stg->adc_current_chan);
- /* the next time this function runs, the result should be available */
- return;
-}
-
-
-// helper function to extract the data out of a char and place it into HAL data
-// written by JMK
-static void split_input(unsigned char data, io_pin *dest, int num)
-{
- int b;
- unsigned char mask;
-
- /* splits a byte into 'num' HAL pins (and their NOTs) */
- mask = 0x01;
- for (b = 0 ; b < num ; b++ ) {
- if ( data & mask ) {
- /* input high, which means FALSE (active low) */
- hal_set_bool(dest->data, 0);
- hal_set_bool(dest->io.not, 1);
- } else {
- /* input low, which means TRUE */
- hal_set_bool(dest->data, 1);
- hal_set_bool(dest->io.not, 0);
- }
- mask <<= 1;
- dest++;
- }
- return;
-}
-
-// helper function to extract the data out of HAL and place it into a char
-// written by JMK
-unsigned char build_output(io_pin *src, int num)
-{
- int b;
- unsigned char data, mask;
-
- data = 0x00;
- mask = 0x01;
- /* assemble output byte for data port from 'num' source variables */
- for (b = 0; b < num; b++) {
- /* get the data, add to output byte */
- if ( hal_get_bool(src->data) ) {
- if ( !hal_get_bool(src->io.invert) ) {
- data |= mask;
- }
- } else {
- if ( hal_get_bool(src->io.invert) ) {
- data |= mask;
- }
- }
- mask <<= 1;
- src++;
- }
- return data;
-}
-
-
-static void stg_di_read(void *arg, long period) //reads digital inputs from the STG
-{
- stg_struct *stg;
- unsigned char val;
- stg=arg;
-
- if ( (stg->dir_bits & 0x01) == 0) { // if port A is set as input, read the bits
- if (stg->model == 1)
- val = inb(base + DIO_A);
- else
- val = inb(base + PORT_A);
- split_input(val, &(stg->port[0][0]), 8);
- }
- if ( (stg->dir_bits & 0x02) == 0) { // if port B is set as input, read the bits
- if (stg->model == 1)
- val = inb(base + DIO_B);
- else
- val = inb(base + PORT_B);
- split_input(val, &(stg->port[1][0]), 8);
- }
- if ( (stg->dir_bits & 0x04) == 0) { // if port C is set as input, read the bits
- if (stg->model == 1)
- val = inb(base + DIO_C);
- else
- val = inb(base + PORT_C);
- split_input(val, &(stg->port[2][0]), 8);
- }
- if ( (stg->dir_bits & 0x08) == 0) { // if port D is set as input, read the bits
- if (stg->model == 1)
- val = inb(base + DIO_D);
- else
- val = inb(base + PORT_D);
- split_input(val, &(stg->port[3][0]), 8);
- }
-}
-
-static void stg_do_write(void *arg, long period) //writes digital outputs to the STG
-{
- stg_struct *stg;
- unsigned char val;
- stg=arg;
-
- if ( (stg->dir_bits & 0x01) != 0) { // if port A is set as output, write the bits
- val = build_output(&(stg->port[0][0]), 8);
- if (stg->model == 1)
- outb(val, base + DIO_A);
- else
- outb(val, base + PORT_A);
- }
- if ( (stg->dir_bits & 0x02) != 0) { // if port B is set as output, write the bits
- val = build_output(&(stg->port[1][0]), 8);
- if (stg->model == 1)
- outb(val, base + DIO_B);
- else
- outb(val, base + PORT_B);
- }
- if ( (stg->dir_bits & 0x04) != 0) { // if port C is set as output, write the bits
- val = build_output(&(stg->port[2][0]), 8);
- if (stg->model == 1)
- outb(val, base + DIO_C);
- else
- outb(val, base + PORT_C);
- }
- if ( (stg->dir_bits & 0x08) != 0) { // if port D is set as output, write the bits
- val = build_output(&(stg->port[3][0]), 8);
- if (stg->model == 1)
- outb(val, base + DIO_D);
- else
- outb(val, base + PORT_D);
- }
-}
-
-/***********************************************************************
-* BOARD SPECIFIC FUNCTIONS *
-* execute board related things (write/read to/from the stg) *
-************************************************************************/
-
-
-/***********************************************************************
-* INIT FUNCTIONS *
-************************************************************************/
-
-/*
- stg_counter_init() - Initializes the channel
-
- works the same for both cards (STG & STG2)
-*/
-static int stg_counter_init(int ch)
-{
- /* Set Counter Command Register - Master Control, Master Reset (MRST), */
- /* and Reset address pointer (RADR). */
- outb(0x23, CTRL(ch));
-
- /* Set Counter Command Register - Input Control, OL Load (P3), */
- /* and Enable Inputs A and B (INA/B). */
- outb(0x68, CTRL(ch));
-
- /* Set Counter Command Register - Output Control */
- outb(0x80, CTRL(ch));
-
- /* Set Counter Command Register - Quadrature */
- outb(0xC3, CTRL(ch));
- return 0;
-}
-
-/*
- stg_dac_init() - Initializes the dac channel
-
- works the same for both cards (STG & STG2)
-*/
-static int stg_dac_init(int ch)
-{
- int i;
-
- /* set all DAC's to 0 on startup */
- for (i=0; i < num_chan; i++) {
- stg_dac_write(i, 0x1000); //by Xuecheng, 0x1000 corresponds to 0V
- }
- return 0;
-}
-
-
-/*
- stg_adc_init() - Initializes the adc channel
-*/
-static int stg_adc_init(int ch)
-{
-
- /* not much to setup for the ADC's */
- /* only select the mode of operation we will work with AutoZero */
- if (stg_driver->model == 1)
- outb(0x0f, base + MIO_2); // the second 82C55 is already configured (by running stg_dio_init)
- // we only set bit 8 (AZ) to 1 to enable it
- return 0;
-}
-
-
-/*
- stg_dio_init() - Initializes the dio's
-*/
-static int stg_dio_init(void)
-{
- /* we will select the directions of each port */
- unsigned char control, tempINTC, tempIMR, tempCtrl0, tempCtrl1;
-
- control = 0x80; //set up |1|0|0|A|CH|0|B|CL|
- if ( (stg_driver->dir_bits & 0x01) == 0) // if port A is set as input, set bit accordingly
- control |= 0x10;
- if ( (stg_driver->dir_bits & 0x02) == 0) // if port B is set as input, set bit accordingly
- control |= 0x02;
- if ( (stg_driver->dir_bits & 0x04) == 0) // if port C is set as input, set bits accordingly
- control |= 0x09;
-
- if (stg_driver->model == 1) {
- // write the computed control to MIO_1
- outb(control, base+MIO_1);
- } else { //model STG2
- // write port A,B,C direction to ABC_DIR
- outb(control, base+ABC_DIR);
- }
-
- tempINTC = inb(base + INTC);
-
- if (stg_driver->model == 1) {
- // next compute the directions for port D, located on the second 82C55
- control = 0x82;
-
- if ( (stg_driver->dir_bits & 0x08) == 0)// if port D is set as input, set bits accordingly
- control = 0x92;
-
- tempIMR = inb(base + IMR); // get the current interrupt mask
-
- outb(0xff, base + OCW1); //mask off all interrupts
-
- // write the computed control to MIO_2
- outb(control, base+MIO_2);
-
- outb(tempINTC, base + INTC); //restore interrupt control reg.
-
- outb(tempIMR, base+ OCW1); //restore int mask
-
- } else { //model STG2
-
- // save contents of CNTRL0, it will get reinitialized
- tempCtrl0 = inb(base+CNTRL0);
- tempCtrl1 = inb(base+CNTRL1);
-
- // CNTRL0 output, BRDTST input, D output
- control = 0x82;
-
- if ( (stg_driver->dir_bits & 0x08) == 0)// if port D is set as input, set bits accordingly
- control = 0x8b;
-
- outb(0xff, base + CNTRL1); // disable interrupts
-
- outb(control, base + D_DIR); // set port D direction, also resets CNTRL0
-
- outb(tempCtrl0, base + CNTRL0);
- outb( (tempCtrl1 & 0x0f) | 0xf0, base + CNTRL1);
- }
-
- return 0;
-}
-
-
-/***********************************************************************
-* ACTION FUNCTIONS *
-* these do the actual data exchange with the board *
-************************************************************************/
-
-static void stg_counter_latch(int i)
-{
- outb(0x03, CTRL(i));
-}
-
-
-/*
- stg_counter_read() - reads one channel
- FIXME - todo, extend to 32 bits in software
-
- works the same for both cards (STG & STG2)
-*/
-static long stg_counter_read(int i)
-{
- union pos_tag {
- long l;
- struct byte_tag {
- char b0;
- char b1;
- char b2;
- char b3;
- } byte;
- } pos;
-
- pos.byte.b0 = inb(DATA(i));
- pos.byte.b1 = inb(DATA(i));
- pos.byte.b2 = inb(DATA(i));
- if (pos.byte.b2 < 0) {
- pos.byte.b3 = -1;
- } else {
- pos.byte.b3 = 0;
- }
- return pos.l;
-}
-
-static void stg1_select_index_axis(void *arg, unsigned int channel)
-{
- stg_struct *stg = arg;
- unsigned char byIntc,byAxis;
- unsigned char byPol = 1;
-
- if (stg->model == 1)
- {
- /*
- * Set polarity to low active if that is requested
- */
- if( hal_get_bool(stg->index_polarity[channel]) == 0 )
- {
- byPol = 0;
- }
-
- /* Stg manual p. 21: "The bits are level triggered and cannot be reset if they are active"
- * So it is save to reset them and only those which are really active will remain */
- stg1_reset_index_latch(arg, channel);
-
- // routine for Model 1
- // initialize stuff to poll index pulse
- byAxis = channel;
-
- byAxis &= 0x6; // ignore low bit, we check 2 axes at a time
- byAxis <<= 3; // shift into position for IXS1, IXS0
- byIntc = inb(base + INTC); // get a copy of INTC, we'll change
- // some bits in it, not all
- byIntc &= ~(IXLVL | IXS1 | IXS0); // zero bits for axis and polarity
- byIntc |= byAxis; // put axes address in INTC
- if (byPol != 0) // is index pulse active high?
- byIntc |= IXLVL;
- outb(byIntc, base + INTC);
- }
-}
-
-static void stg2_select_index_axes( void *arg, unsigned char mask )
-{
- /* stg2 manual, p.21
- * writing 0 to the corresponding bit disables the index pulse
- * writing 1 enables it
- */
- outb( mask, base + IDLEN );
- return;
-}
-
-/* Note that for stg1 cards this function will clear the index pulse latches for the two selected axes,
- */
-static void stg1_reset_index_latch(void *arg, unsigned int channel)
-{
- stg_struct *stg = arg;
-
- if (stg->model == 1)
- { // routine for Model 1
- inb(base + ODDRST); //reset index pulse latch for ODD axis
- inb(base + BRDTST); //reset index pulse latch for EVEN axis
- }
- return;
-}
-
-static void stg2_reset_all_index_latches( void *arg )
-{
- stg_struct *stg = arg;
- if( stg->model == 2 )
- {
- /*
- * stg2 manual p.22,
- * writing 0 to IDL resets the index latch,
- * writing 1 has no effect
- */
- outb( 0x00, base + IDL);
- }
- return;
-}
-
-unsigned char stg1_get_current_IRR(void)
-{
- outb(base + OCW3, 0x0a); // IRR on next read
- return inb(base + IRR);
-}
-
-static unsigned short stg1_get_index_pulse_latch(void *arg, unsigned int chan)
-{
- // routine for Model 1 board
-
- stg_struct *stg = arg;
- unsigned char byIRR, byAxisMask;
-
- if (stg->model == 1){ // routine for Model 1
- byIRR = stg1_get_current_IRR();
- byAxisMask = (chan & 1) ? LIXODD : LIXEVN; // even or odd axis?
- if (byIRR & byAxisMask) // check latched index pulse
- return 1;
- return 0;
- } else if (stg->model == 2) {
- //FIXME: return if latched index pulse is there
- return 0;
- }
- return 0;
-}
-
-static unsigned char stg2_get_all_index_pulse_latches( void *arg )
-{
- stg_struct *stg = arg;
- unsigned char indexRegister = 0;
-
- if( stg-> model == 2 )
- indexRegister = inb( base + IDL );
- return indexRegister;
-}
-
-
-/*
- stg_dac_write() - writes a dac channel
-
- works the same for both cards (STG & STG2)
-*/
-static int stg_dac_write(int ch, short value)
-{
- /* write the DAC */
- outw(value, base + DAC_0 + (ch << 1));
-
- return 0;
-}
-
-
-
-int stg_adc_start(void *arg, unsigned short wAxis)
-{
- stg_struct *stg;
- unsigned char tempCtrl0;
-
- stg = arg;
-
- if (stg->model == 1) {
- /* do a dummy read from the ADC, just to set the input multiplexer to
- the right channel */
- inw(base + ADC_0 + (wAxis << 1));
-
- /* wait 4 uS for settling time on the multiplexer and ADC. You probably
- shouldn't really have a delay in a driver */
- outb(0, 0x80);
- outb(0, 0x80);
- outb(0, 0x80);
- outb(0, 0x80);
-
- /* now start conversion */
- outw(0, base + ADC_0 + (wAxis << 1));
- } else { //model STG2
-
- tempCtrl0 = inb(base+CNTRL0) & 0x07; // save IRQ
- tempCtrl0 |= (wAxis << 4) | 0x88; //autozero & cal cycle
- outb(tempCtrl0, base + CNTRL0); // select channel
-
- /* wait 4 uS for settling time on the multiplexer and ADC. You probably
- shouldn't really have a delay in a driver */
- outb(0, 0x80);
- outb(0, 0x80);
- outb(0, 0x80);
- outb(0, 0x80);
-
- /* now start conversion */
- outw(0, base + ADC_0);
- }
- return 0;
-};
-
-static short stg_adc_read(void *arg, int axis)
-{
- short j;
- stg_struct *stg;
-
- stg = arg;
-
- /*
- there must have been a delay between stg_adc_start() and
- stg_adc_read(), of 19 usec if autozeroing (we are), 4 usecs
- otherwise. In code that calls this, make sure you split these
- calls up with some intervening code
- */
-
-
- if (stg->model == 1) {
-
- /* make sure conversion is done, assume polling delay is done.
- EOC (End Of Conversion) is bit 0x08 in IIR (Interrupt Request
- Register) of Interrupt Controller. Don't wait forever though
- bail out eventually. */
-
- for (j = 0; !(inb(base + IRR) & 0x08) && (j < 1000); j++);
-
- j = inw(base + ADC_0 + (axis << 1));
-
- } else { //model 2
-
- for (j = 0; (inb(base + BRDTST) & 0x08) && (j < 1000); j++);
-
- j = inw(base + ADC_0 + (axis << 1));
-
- }
-
-
- if (j & 0x1000) /* is sign bit negative? */
- j |= 0xf000; /* sign extend */
- else
- j &= 0xfff; /* make sure high order bits are zero. */
-
- return j;
-};
-
-/***********************************************************************
-* BOARD INIT FUNCTIONS *
-* functions for autodetec, irq init *
-************************************************************************/
-
-static int stg_set_interrupt(short interrupt)
-{
- unsigned char tempINTC;
-
- if (stg_driver->model == 1)
- tempINTC=0x80;
- else
- tempINTC=0x88;//also CAL low, don|t want ADC to calibrate
-
- switch (interrupt) {
- case 3: break;
- case 5: tempINTC |= 4;break;
- case 7: tempINTC |= 2;break;
- case 9: tempINTC |= 6;break;
- case 10: tempINTC |= 5;break;
- case 11: tempINTC |= 7;break;
- case 12: tempINTC |= 3;break;
- case 15: tempINTC |= 1;break;
- default: tempINTC |= 4;break;
- }
- if (stg_driver->model == 1)
- outb(tempINTC, base + INTC);
- else
- outb(tempINTC, base + CNTRL0);
-
- return 0;
-}
-
-static int stg_init_card()
-{
- int msg;
-
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /*
- * If both stg card model and base address are set
- * then no autodetecting is necessary.
- * Else we need to autodetect
- */
- if ( (model != 0) && (base != 0) )
- {
- stg_driver->model = model;
- } else {
- base = stg_autodetect();
- }
-
- /*
- * Now check if the settings for a card a ok
- */
- if ( (base == 0x00) || (stg_driver->model == 0) )
- {
- rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: no stg1 or stg2 card could be initialised\n");
- return -ENODEV;
- }
-
- if (stg_driver->model == 1) {
- /*
- * STG1
- */
- // initialize INTC as output
- outb(0x92, base + MIO_2);
-
- stg_set_interrupt(5); // initialize it to smthg, we won't use it anyways
-
- outb(0x1a, base + ICW1); // initialize the 82C59 as single chip (STG docs say so:)
- outb(0x00, base + ICW2); // ICW2 not used, must init it to 0
- outb(0xff, base + OCW1); // mask off all interrupts
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: Initialised stg%1d card at address %x\n", stg_driver->model, base);
- } else if (stg_driver->model == 2 ) {
- /*
- * STG2
- */
- outb(0x8b, base + D_DIR); // initialize CONTRL0 output, BRDTST input
-
- /* stg2 manual, p.21
- * writing 0 to the corresponding bit disables the index pulse
- * writing 1 enables it
- */
- outb( 0x00, base + IDLEN );
-
- /* stg2 manual, p.21
- * writing 0 to the corresponding bit selects the index pulse to latch the counter
- * writing 1 to the corresponding bit selects EXLATCH to latch the counter
- */
- outb( 0x00, base + SELDI );
-
- stg_set_interrupt(5); // initialize it to something, we won't use it anyways
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: Initialised stg%1d card at address %x\n", stg_driver->model, base);
- } else {
- rtapi_print_msg(RTAPI_MSG_ERR, "STG: ERROR: The model stg%1d is not correct\n", stg_driver->model );
- return -ENODEV;
- }
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- // all ok
- return 0;
-}
-
-/* scans possible addresses for STG cards */
-unsigned short stg_autodetect()
-{
-
- short i, j, k, ofs;
- unsigned short address;
- unsigned short retval = 0;
- int msg;
-
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* search all possible addresses */
- for (i = 15; i >= 0; i--) {
- address = i * 0x20 + 0x200;
-
- /* does jumper = i? */
- //if ((inb(address + BRDTST) & 0x0f) == i) { // by Xuecheng, not necessary
- k = 0; // var for getting the serial
- for (j = 0; j < 8; j++) {
- ofs = (inb(address + BRDTST) >> 4);
-
- if (ofs & 8) { /* is SER set? */
- ofs = ofs & 7; /* mask for Q2,Q1,Q0 */
- k += (1 << ofs); /* shift bit into position specified
- by Q2, Q1, Q0 */
- }
- }
-
- if (k == 0x75) {
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: Autodetected stg1 card at address %x\n", address);
- stg_driver->model=1;
- retval = address; /* SER sequence is 01110101 */
- break;
- }
-
- if (k == 0x74) {
- rtapi_print_msg(RTAPI_MSG_INFO,
- "STG: Autodetected stg2 card at address %x\n", address);
- stg_driver->model=2;
- retval = address;
- break;
- }
- //}
- }
-
- if ( ( retval == 0 ) || ( stg_driver->model == 0 ) )
- {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "STG: stg_autodetect() did not find any stg1 or stg2 card\n");
- }
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- return retval;
-}
-
-/***********************************************************************
-* LOCAL FUNCTION DEFINITIONS *
-* these are functions used for exporting various HAL pins/prams *
-************************************************************************/
-static int export_counter(int num, stg_struct *addr)
-{
- int retval, msg;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* export pin for counts captured by update() */
- retval = hal_pin_new_si32(comp_id, HAL_OUT, &addr->count[num],
- 0, "stg.%d.counts", num);
- if (retval != 0) {
- return retval;
- }
- /* export pin for scaled position captured by update() */
- retval = hal_pin_new_real(comp_id, HAL_OUT, &addr->pos[num],
- 0.0, "stg.%d.position", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for scaling */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->pos_scale[num],
- 1.0, "stg.%d.position-scale", num);
- if (retval != 0) {
- return retval;
- }
-
- /* export pin for index homing */
- retval = hal_pin_new_bool(comp_id, HAL_IO, &addr->index_enable[num],
- 0, "stg.%d.index-enable", num);
- if (retval != 0) {
- return retval;
- }
-
- /* export pin for reading the index latch */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &addr->index_latch[num],
- 0, "stg.%d.index-latch", num);
- if (retval != 0) {
- return retval;
- }
-
-
- /*
- * The index polarity is configurable for the stg1 cards only,
- * but not for the stg2 cards
- */
- if( addr->model == 1 )
- {
- /* export read only HAL pin for index pulse polarity */
- retval = hal_pin_new_bool(comp_id, HAL_IN, &addr->index_polarity[num],
- 0, "stg.%d.index-polarity", num);
- if (retval != 0)
- {
- return retval;
- }
- }
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- return 0;
-}
-
-static int export_dac(int num, stg_struct *addr)
-{
- int retval, msg;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* export pin for voltage received by the board() */
- retval = hal_pin_new_real(comp_id, HAL_IN, &addr->dac_value[num],
- 0.0, "stg.%d.dac-value", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for offset */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->dac_offset[num],
- 0.0, "stg.%d.dac-offset", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for gain */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->dac_gain[num],
- 1.0, "stg.%d.dac-gain", num);
- if (retval != 0) {
- return retval;
- }
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
-
-static int export_adc(int num, stg_struct *addr)
-{
- int retval, msg;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* export pin for voltage received by the board() */
- retval = hal_pin_new_real(comp_id, HAL_OUT, &addr->adc_value[num],
- 0.0, "stg.%d.adc-value", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for offset */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->adc_offset[num],
- 0.0, "stg.%d.adc-offset", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for gain */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->adc_gain[num],
- 1.0, "stg.%d.adc-gain", num);
- if (retval != 0) {
- return retval;
- }
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
-
-static int export_pins(int num, int dir, stg_struct *addr)
-{
- int retval, msg, i;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- for (i=0; i<8; i++) {
-
- if (dir != 0)
- retval=export_output_pin(outpinnum++, &(addr->port[num][i]) );
- else
- retval=export_input_pin(inputpinnum++, &(addr->port[num][i]) );
-
- if (retval != 0) {
- return retval;
- }
- }
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
-
-static int export_input_pin(int pinnum, io_pin * pin)
-{
- int retval;
- int msg;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* export read only HAL pin for input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->data), 0,
- "stg.in-%02d", pinnum);
- if (retval != 0) {
- return retval;
- }
- /* export additional pin for inverted input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->io.not), 1,
- "stg.in-%02d-not", pinnum);
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- return retval;
-}
-
-static int export_output_pin(int pinnum, io_pin * pin)
-{
- int retval;
- int msg;
-
- /*
- * This function exports a lot of stuff, which results in a lot of
- * logging if msg_level is at INFO or ALL. So we save the current value
- * of msg_level and restore it later. If you actually need to log this
- * function's actions, change the second line below
- */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level( STG_MSG_LEVEL );
-
- /* export read only HAL pin for output data */
- retval = hal_pin_new_bool(comp_id, HAL_IN, &(pin->data),
- 0, "stg.out-%02d", pinnum);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for polarity */
- retval = hal_param_new_bool(comp_id, HAL_RW, &(pin->io.invert),
- 0, "stg.out-%02d-invert", pinnum);
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
-
- return retval;
-}
diff --git a/src/hal/drivers/hal_stg.h b/src/hal/drivers/hal_stg.h
deleted file mode 100644
index 196c841ade4..00000000000
--- a/src/hal/drivers/hal_stg.h
+++ /dev/null
@@ -1,138 +0,0 @@
-#ifndef STG_H
-#define STG_H
-
-/** This is the driver for an Servo-To-Go Model I board.
- The board includes 8 channels of quadrature encoder input,
- 8 channels of analog input and output, 32 bits digital I/O,
- and an interval timer with interrupt.
-**/
-
-/** Copyright (C) 2005 Alex Joni
-
-**/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-**/
-
-/*
- Servo To Go board decls
-*/
-#define MAX_CHANS 8
-
-#define CNT0_D 0x00
-#define CNT1_D 0x01
-#define CNT0_C 0x02
-#define CNT1_C 0x03
-#define CNT2_D 0x04
-#define CNT3_D 0x05
-#define CNT2_C 0x06
-#define CNT3_C 0x07
-#define CNT4_D 0x08
-#define CNT5_D 0x09
-#define CNT4_C 0x0a
-#define CNT5_C 0x0b
-#define CNT6_D 0x0c
-#define CNT7_D 0x0d
-#define CNT6_C 0x0e
-#define CNT7_C 0x0f
-
-#define DAC_0 0x10
-#define DAC_1 0x12
-#define DAC_2 0x14
-#define DAC_3 0x16
-#define DAC_4 0x18
-#define DAC_5 0x1a
-#define DAC_6 0x1c
-#define DAC_7 0x1e
-
-#define ADC_0 0x410
-#define ADC_1 0x412
-#define ADC_2 0x414
-#define ADC_3 0x416
-#define ADC_4 0x418
-#define ADC_5 0x41a
-#define ADC_6 0x41c
-#define ADC_7 0x41e
-
-#define BRDTST 0x403
-
-#define DIO_A 0x400 /* Model 1 */
-#define DIO_B 0x402 /* Model 1 */
-#define DIO_C 0x404 /* Model 1 */
-#define DIO_D 0x401 /* Model 1 */
-#define PORT_A 0x400 /* Model 2, same function as DIO_A */
-#define PORT_B 0x402 /* Model 2, same function as DIO_B */
-#define PORT_C 0x404 /* Model 2, same function as DIO_C */
-#define PORT_D 0x405 /* Model 2, same function as DIO_D */
-
-#define CNTRL0 0x401 /* Model 2 */
-#define CNTRL1 0x40f /* Model 2 */
-#define ABC_DIR 0x406 /* Model 2 */
-#define D_DIR 0x407 /* Model 2 */
-
-#define MIO_1 0x406
-#define INTC 0x405
-#define MIO_2 0x407
-#define ODDRST 0x407
-#define TIMER_0 0x408
-#define TIMER_1 0x40a
-#define TIMER_2 0x40c
-#define TMRCMD 0x40e
-#define ICW1 0x409
-#define ICW2 0x40b
-#define OCW1 0x40b
-#define OCW2 0x409
-#define OCW3 0x409
-#define IRR 0x409
-#define ISR 0x409
-#define IMR 0x40b
-
-#define IDLEN 0x409
-#define SELDI 0x40B
-#define IDL 0x40D
-
-/*
- * Some bit masks for various registers for Model 1
- */
-// for IRR, ISR, and IMR
-#define IXEVN 0x80
-#define IXODD 0x40
-#define LIXEVN 0x20
-#define LIXODD 0x10
-#define EOC 0x08
-#define TP0 0x04
-#define USR_INT 0x02
-#define TP2 0x01
-// for INTC
-#define AUTOZERO 0x80
-#define IXLVL 0x40
-#define IXS1 0x20
-#define IXS0 0x10
-#define USRINT 0x08
-#define IA2 0x04
-#define IA1 0x02
-#define IA0 0x01
-
-#endif
diff --git a/src/hal/drivers/hal_tiro.c b/src/hal/drivers/hal_tiro.c
deleted file mode 100644
index eba33782d3a..00000000000
--- a/src/hal/drivers/hal_tiro.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/********************************************************************
-* Description: hal_tiro.c
-* This is the driver for an ISA (PC104) encoder reading
-* board.
-*
-* Author: Alex Joni
-* License: GPL Version 2
-*
-* Copyright (c) 2003 All rights reserved.
-*
-* Last change:
-********************************************************************/
-
-/** This is the driver for an ISA (PC104) encoder reading board.
- The board includes up to 4 channels of LS7166 chips for counting
- quadrature encoders. Schematics of the board will be included on
- my webpage www.juve.ro.
-
- Installation of the driver only realtime:
-
- insmod hal_tiro base=0x300 num_chan=4
-
- This code can to some extent be used for the DRO board (with minor
- adjustments). If it is required a DRO driver will follow.
-*/
-
-/** Copyright (C) 2004 Alex Joni
-
-*/
-
-/** Copyright (C) 2003 John Kasunich
-
-*/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-#include /* HAL public API decls */
-
-#define FASTIO
-
-#ifdef FASTIO
-#define rtapi_inb inb
-#define rtapi_outb outb
-#include
-#endif
-
-/* module information */
-MODULE_AUTHOR("Alex Joni");
-MODULE_DESCRIPTION("Driver for Tiro-PC104 board for EMC HAL");
-MODULE_LICENSE("GPL");
-static int base = 0x300; /* board base address */
-RTAPI_MP_INT(base, "board base address");
-static int num_chan = 4; /* number of channels - default = 4 */
-RTAPI_MP_INT(num_chan, "number of channels");
-
-/***********************************************************************
-* STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-/* this structure contains the runtime data for a single counter */
-
-typedef struct {
- hal_sint_t count; /* captured binary count value */
- hal_real_t pos; /* scaled position (floating point) */
- hal_real_t pos_scale; /* parameter: scaling factor for pos */
-} counter_t;
-
-/* pointer to array of counter_t structs in shmem, 1 per counter */
-static counter_t *counter_array;
-
-/* other globals */
-static int comp_id; /* component ID */
-
-#define DATA(x) (base + (2 * x)) /* Address of Data register */
-#define CTRL(x) (base + (2 * x) + 1) /* Address of Control register */
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-
-static int export_counter(int num, counter_t * addr);
-static void capture(void *arg, long period);
-static int LS7166Init(int ch);
-static long LS7166Read(int i);
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_CHAN 4
-
-int rtapi_app_main(void)
-{
- int n, retval;
-
- /* test for number of channels */
- if ((num_chan <= 0) || (num_chan > MAX_CHAN)) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "TIRO: ERROR: invalid num_chan: %d\n", num_chan);
- return -1;
- }
- /* have good config info, connect to the HAL */
- comp_id = hal_init("hal_tiro");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "TIRO: ERROR: hal_init() failed\n");
- return -1;
- }
- /* allocate shared memory for counter data */
- counter_array = hal_malloc(num_chan * sizeof(counter_t));
- if (counter_array == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "TIRO: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
- /* export all the variables for each counter */
- for (n = 0; n < num_chan; n++) {
- /* export all vars */
- retval = export_counter(n, &(counter_array[n]));
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "TIRO: ERROR: counter %d var export failed\n", n + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_si32(counter_array[n].count, 0);
- hal_set_real(counter_array[n].pos, 0.0);
- hal_set_real(counter_array[n].pos_scale, 1.0);
-
- /* init counter chip */
- LS7166Init(n);
- }
- /* export functions */
- retval = hal_export_funct("tiro.capture-position", capture,
- counter_array, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "TIRO: ERROR: capture funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "TIRO: installed %d encoder counters\n", num_chan);
- hal_ready(comp_id);
- return 0;
-}
-
-void rtapi_app_exit(void)
-{
- hal_exit(comp_id);
-}
-
-/***********************************************************************
-* REALTIME ENCODER COUNTING AND UPDATE FUNCTIONS *
-************************************************************************/
-
-static void capture(void *arg, long period)
-{
- counter_t *cntr;
- int n;
-
- cntr = arg;
- for (n = 0; n < num_chan; n++) {
-
- /* capture raw counts to latches */
- hal_set_si32(cntr->count, LS7166Read(n));
- /* scale count to make floating point position */
- hal_set_real(cntr->pos, hal_get_si32(cntr->count) * hal_get_real(cntr->pos_scale));
- /* move on to next channel */
- cntr++;
- }
- /* done */
-}
-
-
-/***********************************************************************
-* BOARD SPECIFIC FUNCTIONS *
-************************************************************************/
-/*
- LS7166Init() - Initializes the channel
-*/
-
-int LS7166Init(int ch)
-{
- rtapi_outb(CTRL(ch), 0x49);
- rtapi_outb(CTRL(ch), 0xC3);
- rtapi_outb(CTRL(ch), 0x80);
- return 0;
-}
-
-
-/*
- LS7166Read() - reads one channel
-*/
-long LS7166Read(int i)
-{
- union pos_tag {
- long l;
- struct byte_tag { char b0; char b1; char b2; char b3;} byte;
- } pos;
-
- rtapi_outb(CTRL(i), 0x03);
- pos.byte.b0=rtapi_inb(DATA(i));
- pos.byte.b1=rtapi_inb(DATA(i));
- pos.byte.b2=rtapi_inb(DATA(i));
- if (pos.byte.b2 < 0) {
- pos.byte.b3 = -1;
- }
- else {
- pos.byte.b3 = 0;
- }
- return pos.l;
-}
-
-/***********************************************************************
-* LOCAL FUNCTION DEFINITIONS *
-************************************************************************/
-
-static int export_counter(int num, counter_t * addr)
-{
- int retval, msg;
-
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
-
- /* export pin for counts captured by update() */
- retval = hal_pin_new_si32(comp_id, HAL_OUT, &(addr->count), 0,
- "tiro.%d.counts", num);
- if (retval != 0) {
- return retval;
- }
- /* export pin for scaled position captured by update() */
- retval = hal_pin_new_real(comp_id, HAL_OUT, &(addr->pos), 0.0,
- "tiro.%d.position", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for scaling */
- retval = hal_param_new_real(comp_id, HAL_RW, &(addr->pos_scale), 1.0,
- "tiro.%d.position-scale", num);
- if (retval != 0) {
- return retval;
- }
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
diff --git a/src/hal/drivers/hal_vti.c b/src/hal/drivers/hal_vti.c
deleted file mode 100644
index 7f5cb7c7ce8..00000000000
--- a/src/hal/drivers/hal_vti.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/********************************************************************
-* Description: hal_vti.c
-* This is the driver for the Vigilant Technologies
-* PCI-ENCDAC 4 channel controller.
-*
-* Author: Eric H. Johnson from template by Alex Joni and EMC1 driver
-* by Paul C.
-* License: GPL Version 2
-*
-* Copyright (c) 2006 All rights reserved.
-* see below for additional notes
-*
-* Last change:
-********************************************************************/
-
-/** This is the driver for Vigilant Technologies (VTI) ENCDAC controller.
- The board includes 4 channels of quadrature encoder input,
- 4 channels of analog input and output, 8 bits digital I/O plus up to
- 128 bits digital I/O on digital expander module, and three
- timers with interrupt.
-
- Installation of the driver only realtime:
-
- insmod hal_vti num_chan=4 dio="IOiooi"
- BNF -> dio="*nI|O|ii|io|oi|oo"
- where n=number of enabled I/O ports
- - autodetects the address
- or
-
- insmod hal_vti base=0x200 num_chan=4 dio="I|O|ii|io|oi|oo..."
-
- Check your Hardware manual for your base address (ISA bus only).
-
- The digital inputs/outputs configuration is determined by a
- config string passed to insmod when loading the module.
- The format consists of a character string that sets the
- direction of each group of pins. Each character or character pair
- of the direction string is one of "I", "O", "ii", "io", "oi" or "oo".
- The individual and character pair formats may be used interchangeably in
- the same string, however the lower case format must always appear in
- pairs. The representatiom of each character or character pair is as follows:
-
- I: 8 (0..7) Inputs
- O: 8 (0..7) Outputs
- ii: 4 (0..3) Inputs / 4 (4..7) Inputs
- io: 4 (0..3) Inputs / 4 (4..7) Outputs
- oi: 4 (0..3) Outputs / 4 (4..7) Inputs
- oo: 4 (0..3) Outputs / 4 (4..7) Outputs
-
- There are characters or character pairs equal to the number of I/O
- ports (sets of 8 DIO) configured on the ENCDAC board and the expanded
- I/O module, where the first port is for the I/O on the ENCDAC board
- itself.
-
- The following items are exported to the HAL.
-
- Encoders:
- Parameters:
- float vti..position-scale
-
- Pins:
- s32 vti..counts
- float vti..position
-
-/todo bit vti..enc-index
-/todo bit vti..enc-idx-latch
-/todo bit vti..enc-latch-index
-/todo bit vti..enc-reset-count
-
- Functions:
- void vti..capture_position
-
- DACs:
- Parameters:
- float vti..dac-offset
- float vti..dac-gain
-
- Pins:
- float vti..dac-value
-
- Functions:
- void vti..dac-write
-
- ADC:
- Parameters:
-/totest float vti..adc-offset
-/totest float vti..adc-gain
-
- Pins:
-/totest float vti..adc-value
-
- Functions:
-/totest void vti..adc-read
-
- Digital In:
- Pins:
- bit vti.in-
- bit vti.in--not
-
- Functions:
- void vti.digital-in-read
-
- Digital Out:
- Parameters:
- bit vti.out--invert
-
- Pins:
- bit vti.out-
-
- Functions:
- void vti.digital-out-write
-
-*/
-
-/** Copyright (C) 2006 Eric Johnson
-
-*/
-
-/** Copyright (C) 2004 Alex Joni
-
-*/
-
-/** Copyright (C) 2003 John Kasunich
-
-*/
-
-/* Also relates to the EMC1 code (very similar to STGMEMBS.CPP)
- work done by Fred Proctor, Will Shackleford */
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-*/
-
-#include
-#include /* RTAPI realtime OS API */
-#include /* RTAPI realtime module decls */
-#include
-#include /* HAL public API decls */
-#include "hal_vti.h" /* VTI related defines */
-
-/* module information */
-MODULE_AUTHOR("Eric Johnson");
-MODULE_DESCRIPTION
- ("Driver for Vigilant Technologies ENCDAC 4 channel controller");
-MODULE_LICENSE("GPL");
-static int num_chan = MAX_CHANS; /* number of channels - default = 4 */
-RTAPI_MP_INT(num_chan, "number of channels");
-static char *dio = "ii"; /* dio config - default = port A&B inputs, port C&D outputs */
-RTAPI_MP_STRING(dio, "dio config string - expects something like IOiooi");
-
-/***********************************************************************
- * STRUCTURES AND GLOBAL VARIABLES *
-************************************************************************/
-
-typedef struct {
- hal_bool_t data; /* basic pin for input or output */
- union {
- hal_bool_t not; /* pin for inverted data (input only) */
- hal_bool_t invert; /* param for inversion (output only) */
- } io;
-} io_pin;
-
-typedef struct {
-/* counter data */
- hal_sint_t count[MAX_CHANS]; /* captured binary count value */
- hal_real_t pos[MAX_CHANS]; /* scaled position (floating point) */
- hal_real_t pos_scale[MAX_CHANS]; /* parameter: scaling factor for pos */
-
-/* dac data */
- hal_real_t dac_value[MAX_CHANS]; /* value to be written to dac */
- hal_real_t dac_offset[MAX_CHANS]; /* offset value for DAC */
- hal_real_t dac_gain[MAX_CHANS]; /* gain to be applied */
-
-/* adc data */
- // These adc thingies are apparently unused...
- hal_real_t adc_value[MAX_CHANS]; /* value to be read from adc */
- hal_real_t adc_offset[MAX_CHANS]; /* offset value for ADC */
- hal_real_t adc_gain[MAX_CHANS]; /* gain to be applied */
- int adc_current_chan; /* holds the currently converting channel */
-
-/* dio data */
- io_pin port[MAX_IO_PORTS][PINS_PER_PORT]; /* Holds MAX_IO_PORTS X PINS_PER_PORT
- number of discrete I/O points */
- unsigned char dir_bits[MAX_IO_PORTS * 2]; /* remembers config (which port is input which is output) */
-
- unsigned char model;
-
-} vti_struct;
-
-static vti_struct *vti_driver;
-struct pci_dev *dev = NULL;
-struct pci_access *device;
-volatile struct encoder *encoder = NULL;
-volatile struct timer *timer = NULL;
-volatile struct dac *dac = NULL;
-volatile struct ip *ip = NULL;
-
-/* other globals */
-static int comp_id; /* component ID */
-static int outpinnum = 0, inputpinnum = 0;
-static int diocount = 0;
-static rtapi_s32 enc_counts[MAX_CHANS];
-
-/***********************************************************************
-* LOCAL FUNCTION DECLARATIONS *
-************************************************************************/
-/* helper functions, to export HAL pins & co. */
-static int export_counter(int num, vti_struct * addr);
-static int export_dac(int num, vti_struct * addr);
-// static int export_adc(int num, vti_struct * addr);
-static int export_dio_pins(int io_points);
-static int export_pin(int num, int dir, vti_struct * addr);
-static int export_input_pin(int pinnum, io_pin * pin);
-static int export_output_pin(int pinnum, io_pin * pin);
-
-/* Board specific functions */
-
-/* initializes the vti, takes care of autodetection, all initialisations */
-static int vti_init_card(void);
-/* sets up interrupt to be used - unused for now*/
-/*static int vti_set_interrupt(short interrupt);*/
-/* scans possible addresses for vti cards */
-static int vti_autodetect(void);
-
-/* counter related functions */
-static int vti_counter_init(int channels);
-static long vti_counter_read(int i);
-
-/* dac related functions */
-static int vti_dac_init(int channels);
-static int vti_dac_write(int ch, short value);
-
-/* adc related functions */
-static int vti_adc_init(int channels);
-// static int vti_adc_start(void *arg, unsigned short wAxis);
-// static short vti_adc_read(void *arg, int ch);
-
-/* dio related functions */
-static int vti_dio_init(int nibbles);
-static int vti_parse_dio(void);
-
-/* periodic functions registered to HAL */
-static void vti_adcs_read(void *arg, long period); //reads adc data from the board, check long description at the beginning of the function
-static void vti_dacs_write(void *arg, long period); //writes dac's to the vti
-static void vti_counter_capture(void *arg, long period); //captures encoder counters
-static void vti_di_read(void *arg, long period); //reads digital inputs from the vti
-static void vti_do_write(void *arg, long period); //writes digital outputs to the vti
-
-/***********************************************************************
-* INIT AND EXIT CODE *
-************************************************************************/
-
-#define MAX_CHAN 8
-
-int rtapi_app_main(void)
-{
- int retval;
-
- /* test for number of channels */
- if ((num_chan <= 0) || (num_chan > MAX_CHAN)) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: invalid num_chan: %d\n", num_chan);
- return -1;
- }
-
- /* test for config string */
- if ((dio == 0) || (dio[0] == '\0')) {
- rtapi_print_msg(RTAPI_MSG_ERR, "VTI: ERROR: no dio config string\n");
- return -1;
- }
-
- /* have good config info, connect to the HAL */
- comp_id = hal_init("hal_vti");
- if (comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "VTI: ERROR: hal_init() failed\n");
- return -1;
- }
-
- /* allocate shared memory for vti data */
- vti_driver = hal_malloc(num_chan * sizeof(vti_struct));
- if (vti_driver == 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, "VTI: ERROR: hal_malloc() failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- /* takes care of all initialisations, also autodetection and model if necessary */
- if ((retval=vti_init_card()) != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti_init_card() failed\n");
- hal_exit(comp_id);
- return retval;
- }
-
- diocount = vti_parse_dio();
- if (diocount == -1) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: bad config info for port.\n");
- return -1;
- }
- export_dio_pins(diocount);
-
- vti_dio_init(diocount / 4);
-
- /* init counter chip */
- if (vti_counter_init(num_chan) == -1) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: bad config info counter.\n");
- return -1;
- }
-
- /* init dac chip */
- vti_dac_init(num_chan);
-
- /* init adc chip */
- vti_adc_init(0); // VTI controller has no ADCs
-
- /* export functions */
- retval = hal_export_funct("vti.capture-position", vti_counter_capture,
- vti_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti.counter-capture funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "VTI: installed %d encoder counters\n", num_chan);
-
- retval = hal_export_funct("vti.write-dacs", vti_dacs_write,
- vti_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti.write-dacs funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: installed %d dacs\n", num_chan);
-
- retval = hal_export_funct("vti.read-adcs", vti_adcs_read,
- vti_driver, 1, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti.read-adcs funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: installed %d adcs\n", 0);
-
- retval = hal_export_funct("vti.di-read", vti_di_read,
- vti_driver, 0, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti.di-read funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
-
- rtapi_print_msg(RTAPI_MSG_INFO,
- "VTI: installed %d digital inputs\n", inputpinnum);
-
- retval = hal_export_funct("vti.do-write", vti_do_write,
- vti_driver, 0, 0, comp_id);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: vti.do-write funct export failed\n");
- hal_exit(comp_id);
- return -1;
- }
- rtapi_print_msg(RTAPI_MSG_INFO,
- "VTI: installed %d digital outputs\n", outpinnum);
-
- hal_ready(comp_id);
- return 0;
-}
-
-static int vti_parse_dio(void)
-{
- int i = 0, nibble = 0;
-
- if (strlen(dio) == 0)
- return 0;
- while (i < strlen(dio)) {
- switch (dio[i]) {
- case 'I':
- vti_driver->dir_bits[nibble] = 0;
- vti_driver->dir_bits[nibble + 1] = 0;
- break;
- case 'O':
- vti_driver->dir_bits[nibble] = 1;
- vti_driver->dir_bits[nibble + 1] = 1;
- break;
- case 'i':
- vti_driver->dir_bits[nibble] = 0;
- i++;
- if (dio[i] == 'i')
- vti_driver->dir_bits[nibble + 1] = 0;
- else if (dio[i] == 'o')
- vti_driver->dir_bits[nibble + 1] = 1;
- else
- return -1;
- break;
- case 'o':
- vti_driver->dir_bits[nibble] = 1;
- i++;
- if (dio[i] == 'i')
- vti_driver->dir_bits[nibble + 1] = 0;
- else if (dio[i] == 'o')
- vti_driver->dir_bits[nibble + 1] = 1;
- else
- return -1;
- break;
- default:
- return -1;
- }
- nibble += 2;
- i++;
- }
- return nibble * 4; // Number of IO points defined
-}
-
-void rtapi_app_exit(void)
-{
- hal_exit(comp_id);
-}
-
-/***********************************************************************
-* REALTIME ENCODER COUNTING AND UPDATE FUNCTIONS *
-************************************************************************/
-
-static void vti_counter_capture(void *arg, long period)
-{
- vti_struct *vti;
- int i;
-
- vti = arg;
- for (i = 0; i < num_chan; i++) {
- /* capture raw counts to latches */
- hal_set_si32(vti->count[i], vti_counter_read(i));
- /* scale count to make floating point position */
- if (hal_get_real(vti->pos_scale[i]) < 0.0) {
- if (hal_get_real(vti->pos_scale[i]) > -EPSILON)
- hal_set_real(vti->pos_scale[i], -1.0);}
- else {
- if (hal_get_real(vti->pos_scale[i]) < EPSILON)
- hal_set_real(vti->pos_scale[i], 1.0); }
- hal_set_real(vti->pos[i], hal_get_si32(vti->count[i]) / hal_get_real(vti->pos_scale[i]));
- }
- /* done */
-}
-
-/* vti_dacs_write() - writes all dac's to the board
- - calls vti_dac_write() */
-static void vti_dacs_write(void *arg, long period)
-{
- vti_struct *vti;
- double volts;
- unsigned short ncounts, i;
-
- vti = arg;
- for (i = 0; i < num_chan; i++) {
- /* scale the voltage to be written based on offset and gain */
- volts =
- (hal_get_real(vti->dac_value[i]) - hal_get_real(vti->dac_offset[i])) * hal_get_real(vti->dac_gain[i]);
- /* compute the value for the DAC, the extra - in there is vti specific */
- ncounts = ((volts / 10) * 0x7fff) + 0x8000;
-
- /* write it to the card */
- vti_dac_write(i, ncounts);
- }
-}
-
-/* The VTI board has no ADCs. Procedure is retained only as a stub, should it be called from
- elsewhere in the application. */
-
-static void vti_adcs_read(void *arg, long period)
-{
- return;
-}
-
-// helper function to extract the data out of a char and place it into HAL data
-// written by JMK
-static void split_input(unsigned char data, io_pin * dest, int num)
-{
- int b;
- unsigned char mask;
-
- /* splits a byte into 'num' HAL pins (and their NOTs) */
- mask = 0x01;
- for (b = 0; b < num; b++) {
- if (data & mask) {
- /* input high, which means FALSE (active low) */
- hal_set_bool(dest->data, 0);
- hal_set_bool(dest->io.not, 1);
- } else {
- /* input low, which means TRUE */
- hal_set_bool(dest->data, 1);
- hal_set_bool(dest->io.not, 0);
- }
- mask <<= 1;
- dest++;
- }
-}
-
-// helper function to extract the data out of HAL and place it into a char
-// written by JMK
-unsigned char build_output(io_pin * src, int num)
-{
- int b;
- unsigned char data, mask;
-
- data = 0x00;
- mask = 0x01;
- /* assemble output byte for data port from 'num' source variables */
- for (b = 0; b < num; b++) {
- /* get the data, add to output byte */
- if (hal_get_bool(src->data)) {
- if (!hal_get_bool(src->io.invert)) {
- data |= mask;
- }
- } else {
- if (hal_get_bool(src->io.invert)) {
- data |= mask;
- }
- }
- mask <<= 1;
- src++;
- }
- return data;
-}
-
-static void vti_di_read(void *arg, long period) //reads digital inputs from the vti
-{
- vti_struct *vti;
- int i;
- char latchedVal;
-
- vti = arg;
- if (diocount == 0) return; // No DIO enabled
- /* Get ENCDAC onboard inputs */
- latchedVal = encoder->DIO;
- if (vti->dir_bits[0] == 0)
- split_input(latchedVal, &(vti->port[0][0]), 4);
- if (vti->dir_bits[1] == 0)
- split_input(latchedVal, &(vti->port[0][4]), 4);
-
- /* Get Extended I/O inputs */
- if (diocount <= 8) return; // No extended I/O enabled
- for (i = 1; i < (diocount / 8); i++) {
- latchedVal = dac->DIO[i - 1];
- if (vti->dir_bits[i * 2] == 0)
- split_input(latchedVal, &(vti->port[i][0]), 4);
- if (vti->dir_bits[i * 2 + 1] == 0)
- split_input(latchedVal, &(vti->port[i][4]), 4);
- }
-}
-
-static void vti_do_write(void *arg, long period) //writes digital outputs to the vti
-{
- vti_struct *vti;
- int i;
-
- vti = arg;
- /* Write ENCDAC onboard outputs */
- if (diocount == 0) return; // No DIO
- encoder->DIO = build_output(&(vti->port[0][0]), 8);
- if (diocount <= 8) return; // No extended I/O
-
- /* Write Extended I/O outputs */
- for (i = 1; i < diocount / 8; i++) {
- dac->DIO[i - 1] = build_output(&(vti->port[i][0]), 8);
- }
-
-}
-
-/***********************************************************************
-* BOARD SPECIFIC FUNCTIONS *
-* execute board related things (write/read to/from the vti) *
-************************************************************************/
-
-/***********************************************************************
-* INIT FUNCTIONS *
-************************************************************************/
-
-/*
- vti_counter_init() - Initializes the channel
-
- works the same for both cards (vti & STG2)
-*/
-static int vti_counter_init(int counters)
-{
-
- int i, retval=0;
- /* export all the variables for each counter, dac */
- for (i = 0; i < counters; i++) {
- /* export all vars */
- retval = export_counter(i, vti_driver);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: counter %d var export failed\n", i + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_si32(vti_driver->count[i], 0);
- hal_set_real(vti_driver->pos[i], 0.0);
- hal_set_real(vti_driver->pos_scale[i], 1.0);
- }
- return 0;
-}
-
-/*
- vti_dac_init() - Initializes the dac channel
-
- works the same for both cards (vti & STG2)
-*/
-static int vti_dac_init(int channels)
-{
- int retval, i;
-
- encoder->DAC = DAC_IND_MODE; // Enable DACs for output independent of watchdog
- for (i = 0; i < channels; i++) {
- retval = export_dac(i, vti_driver);
- if (retval != 0) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "VTI: ERROR: dac %d var export failed\n", i + 1);
- hal_exit(comp_id);
- return -1;
- }
- /* init counter */
- hal_set_real(vti_driver->dac_value[i], 0);
- hal_set_real(vti_driver->dac_offset[i], 0.0);
- hal_set_real(vti_driver->dac_gain[i], 1.0);
- vti_dac_write(i, DAC_ZERO_VOLTS);
- }
- return 0;
-}
-
-/* vti_adc_init() - Initializes the adc channel */
-/* VTI card has no ADCs. */
-
-static int vti_adc_init(int channels)
-{
- return 0;
-}
-
-static int vti_dio_init(int nibbles)
-{
- unsigned int mask;
- int i;
-
- /* we will select the directions of each port */
- /* First initialize the 8 on board I/O points */
- if (diocount == 0) return 0; // No DIO
- encoder->DIO = 0; // Turn all inputs / outputs off
- mask = encoder->Interrupt;
- mask &= 0xfffffcff; // Mask off direction bits
- if (vti_driver->dir_bits[0] == 1)
- mask |= 0x00000100; // Set mask for bits 0-3
- if (vti_driver->dir_bits[1] == 1)
- mask |= 0x00000200; // Set mask for bits 4-7
- encoder->Interrupt = mask;
- /* Now initialize all extended I/O */
- if (diocount <= 8) return 0; // No extended I/O
- for (i = 0; i < (diocount - 8) / 8; i++) {
- dac->DIO[i] = 0; // Turn all extended I/O off
- }
-
- mask = 0;
- for (i = 0; i < 8; i++) { // Set direction for extended I/O points 0..63
- if (vti_driver->dir_bits[(i * 2) + 2] == 1)
- mask |= (1 << i);
- }
- dac->config0 = mask;
- mask = 0;
- for (i = 0; i < 8; i++) { // Set direction for extended I/O points 64..127
- if (vti_driver->dir_bits[(i * 2) + 18] == 1)
- mask |= (1 << i);
- }
- dac->config1 = mask;
- return 0;
-}
-
-/***********************************************************************
-* ACTION FUNCTIONS *
-* these do the actual data exchange with the board *
-************************************************************************/
-
-/*
- vti_counter_read() - reads one channel
- FIXME - todo, extend to 32 bits in software
-
- works the same for both cards (vti & STG2)
-*/
-static long vti_counter_read(int axis)
-{
- unsigned int status;
- unsigned int count;
- Longword EncData;
- static long int lastCount;
-// static unsigned short lastdac;
-
- if ((axis >= MAX_CHANS) || (axis < 0)) {
- return 0x80000000; // Return encoder error value
- }
- lastCount = enc_counts[axis];
- status = encoder->Status; // latch status from vti board
- count = encoder->Counter[axis]; // latch count from vti board
-
- EncData.Long = (long int)enc_counts[axis];
- if (status & (1 << axis)) {
- if (status & (1 << (axis + 4))) {
- EncData.Word[1] += 1;
- }
- else {
- EncData.Word[1] -= 1;
- }
- }
-
-
- EncData.Word[0] = count;
-// Filter out spurious roll overs / roll unders
- if ((EncData.Long - lastCount) > 0x7fff)
- EncData.Word[1] -= 1;
- else
- if ((lastCount - EncData.Long) > 0x7fff)
- EncData.Word[1] += 1;
- enc_counts[axis] = EncData.Long;
-
- return EncData.Long;
-}
-
-/*
- vti_dac_write() - writes a dac channel
-*/
-static int vti_dac_write(int axis, short value)
-{
- short junk;
- /* write the DAC */
- if ((axis >= MAX_CHANS) || (axis < 0)) {
- return -1;
- }
-
- junk = dac->mode; // Read from mode to trigger update dac immediately
- dac->dac[axis] = value; // Write dac value
-
- return 0;
-}
-
-/* int vti_adc_start(void *arg, unsigned short wAxis)
-{
- return 0; // VTI card has do ADCs
-} */
-
-/* static short vti_adc_read(void *arg, int axis)
-{
-
- return 0; // VTI card has no ADCs
-} */
-
-/***********************************************************************
-* BOARD INIT FUNCTIONS *
-* functions for autodetec, irq init *
-************************************************************************/
-/*
-static int vti_set_interrupt(short interrupt)
-{
- return 0; // No interrupts necessary for VTI board
-}*/
-
-static int vti_init_card()
-{
- int retval=vti_autodetect();
- if (retval == 0) {
- encoder = (volatile struct encoder *)
- ioremap(pci_resource_start(dev, 2), sizeof(encoder));
- dac =
- (volatile struct dac *) ioremap(pci_resource_start(dev,
- 4), sizeof(dac));
- timer =
- (volatile struct timer *) ioremap(pci_resource_start(dev,
- 3), sizeof(timer));
- ip = (volatile struct ip *) ioremap(pci_resource_start(dev, 5),
- sizeof(ip));
- } else {
- return (retval);
- }
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Encoders mapped to : %p\n",
- encoder);
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: DACs mapped to : %p\n",
- dac);
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Timers mapped to : %p\n",
- timer);
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Industry pack mapped to : %p\n",
- ip);
- encoder->Status = 0;
- encoder->Reset = 0;
- // all ok
- return 0;
-}
-
-/* scans possible addresses for vti cards */
-static int vti_autodetect()
-{
- dev = pci_get_device(VENDOR, DEVICE, dev);
- if (dev) {
- pci_dev_put(dev);
- rtapi_print_msg(RTAPI_MSG_INFO,
- "VTI: Card detected in slot: %2x\n", PCI_SLOT(dev->devfn));
- return (0);
- } else {
- rtapi_print_msg(RTAPI_MSG_INFO, "VTI: Exiting with auto detect failed\n");
- return (-ENODEV);
- }
-}
-
-/***********************************************************************
-* LOCAL FUNCTION DEFINITIONS *
-* these are functions used for exporting various HAL pins/prams *
-************************************************************************/
-static int export_counter(int num, vti_struct * addr)
-{
- int retval, msg;
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
- /* export pin for counts captured by update() */
- retval = hal_pin_new_si32(comp_id, HAL_OUT, &addr->count[num],
- 0, "vti.%d.counts", num);
- if (retval != 0) {
- return retval;
- }
- /* export pin for scaled position captured by update() */
- retval = hal_pin_new_real(comp_id, HAL_OUT, &addr->pos[num],
- 0.0, "vti.%d.position", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for scaling */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->pos_scale[num],
- 1.0, "vti.%d.position-scale", num);
- if (retval != 0) {
- return retval;
- }
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
-
-static int export_dac(int num, vti_struct * addr)
-{
- int retval, msg;
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
- /* export pin for voltage received by the board() */
- retval = hal_pin_new_real(comp_id, HAL_IN, &addr->dac_value[num],
- 0.0, "vti.%d.dac-value", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for offset */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->dac_offset[num],
- 0.0, "vti.%d.dac-offset", num);
- if (retval != 0) {
- return retval;
- }
- /* export parameter for gain */
- retval = hal_param_new_real(comp_id, HAL_RW, &addr->dac_gain[num],
- 1.0, "vti.%d.dac-gain", num);
- if (retval != 0) {
- return retval;
- }
-
- /* restore saved message level */
- rtapi_set_msg_level(msg);
- return 0;
-}
-
-/* static int export_adc(int num, vti_struct * addr)
-{
- return 0; // No ADCs to export
-} */
-
-static int export_dio_pins(int io_points)
-{
- int i, msg, retval=0;
- /* This function exports a lot of stuff, which results in a lot of
- logging if msg_level is at INFO or ALL. So we save the current value
- of msg_level and restore it later. If you actually need to log this
- function's actions, change the second line below */
- if (io_points == 0) return 0;
- msg = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
- for (i = 0; i < io_points; i++) {
- /* point, direction, driver */
- retval |= export_pin(i, vti_driver->dir_bits[i / 4], vti_driver);
- }
- /* restore saved message level */ rtapi_set_msg_level(msg);
- return retval;
-}
-
-static int export_pin(int num, int dir, vti_struct * addr)
-{
- int retval;
- if (dir != 0)
- retval =
- export_output_pin(outpinnum++, &(addr->port[num / 8][num % 8]));
- else
- retval =
- export_input_pin(inputpinnum++, &(addr->port[num / 8][num % 8]));
- if (retval != 0)
- return retval;
- return 0;
-}
-static int export_input_pin(int pinnum, io_pin * pin)
-{
- int retval;
- /* export read only HAL pin for input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->data),
- 0, "vti.in-%02d", pinnum);
- if (retval != 0)
- return retval;
- /* export additional pin for inverted input data */
- retval = hal_pin_new_bool(comp_id, HAL_OUT, &(pin->io.not),
- 1, "vti.in-%02d-not", pinnum);
- return retval;
-}
-static int export_output_pin(int pinnum, io_pin * pin)
-{
- int retval;
- /* export read only HAL pin for output data */
- retval = hal_pin_new_bool(comp_id, HAL_IN, &(pin->data),
- 0, "vti.out-%02d", pinnum);
- if (retval != 0)
- return retval;
- /* export parameter for polarity */
- retval = hal_param_new_bool(comp_id, HAL_RW, &(pin->io.invert),
- 0, "vti.out-%02d-invert", pinnum);
- return retval;
-}
diff --git a/src/hal/drivers/hal_vti.h b/src/hal/drivers/hal_vti.h
deleted file mode 100644
index 30b72024fed..00000000000
--- a/src/hal/drivers/hal_vti.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef VTI_H
-#define VTI_H
-
-/** This is the driver for a Vigilant technologies ENCDAC board.
- The board includes 4 channels of quadrature encoder input,
- 4 channels of analog output, 8 on board digital I/O, and up
- to 128 digital I/O on the expanded I/O module, 3 timers
- with interrupt.
-
- A further 4 quadrature encoder inputs, 4 channels of DAC
- output and 8 additional channels of digital I/O are
- available through the Industry Pack interface. While some
- of the hooks are in place, the IP interface is not
- currently supported, nor is the ISA version of the board.
-
- To Do: Add full support for the Industray pack
- Add support for the ISA version of the board.
- Add support for timers
-**/
-
-/** Copyright (C) 2006 Eric H. Johnson
-
-**/
-
-/** This program is free software; you can redistribute it and/or
- modify it under the terms of version 2 of the GNU General
- Public License as published by the Free Software Foundation.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- harming persons must have provisions for completely removing power
- from all motors, etc, before persons enter any danger area. All
- machinery must be designed to comply with local and national safety
- codes, and the authors of this software can not, and do not, take
- any responsibility for such compliance.
-
- This code was written as part of the EMC HAL project. For more
- information, go to www.linuxcnc.org.
-**/
-
-/*
- Vigilant Technologies' board decls
-*/
-#define VENDOR 0x10b5
-#define DEVICE 0x9050
-
-#define MAX_CHANS 4
-#define MAX_IO_PORTS 17
-#define PINS_PER_PORT 8
-
-#define DAC_DISABLE 0x00a5
-#define DAC_IND_MODE 0x005a
-#define DAC_WATCHDOG_MODE 0x000f
-#define DAC_ZERO_VOLTS 0x8000
-
-#define EPSILON 1e-20
-
-/* Structures used by the PCI card */
-struct encoder {
- u16 Counter[4];
- u8 Status; // 0x08
- u8 dummy; // dummy space
- u16 Reset; // 0x0a
- u8 reserved[3]; // dummy space 0x0c - 0x0f
- u16 Interrupt; // 0x10
- u16 DAC; // 0x12
- u16 DIO; // 0x14
- };
-
-struct timer {
- u8 reserved[0x2c];
- u8 ctc0; // 8254 Counter 0
- u8 ctc1; // 8254 Counter 1
- u8 ctc2; // 8254 Counter 2
- u8 control; // 8254 command register
- };
-
-struct dac {
- u8 reserved1[0x13f]; // dummy space
- u16 dac[4];
- u16 dac_adj[4];
- u16 mode;
- u16 update;
- u16 reset;
- u8 dummy[0x2a]; // dummy space
- u8 DIO[0x10]; // Digital IO channels
- u16 config0; // Direction configs for channels 00-63
- u16 config1; // Direction configs for channels 64-127
- u16 status;
- };
-
-/* IndustryPack mappings - Need to check IF u8 or u16, also check boundary address*/
-struct ip {
- u8 ID[0x40]; // IndustryPack ID - The first (12*2) addresses used for ID info
- // consult P20 of vip-4encdac.pdf for more info.
- u16 IP_int; // Interrupt status
- u8 reserved[0x3e]; // dummy space
- u16 IO[0x30]; // IndustryPack IO - Only need the first 0x30 address.
- // Again, consult manual - Might it be better to use another struct here ??
- // and also for the ID stuff....
- };
-
-typedef union
-{
- signed long int Long;
- signed short int Word[2];
-} Longword;
-
-
-#endif
diff --git a/src/hal/drivers/motenc.h b/src/hal/drivers/motenc.h
deleted file mode 100644
index efdd4f5f8c7..00000000000
--- a/src/hal/drivers/motenc.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2005 Peter G. Vavaroutsos
- *
- *
- * Hardware register defines for Vital Systems MOTENC-100 board.
- * The board includes an 8 channel quadrature decoder, 8 analog inputs,
- * 8 analog outputs, 68 digital inputs, 32 digital outputs, programmable
- * timer interrupts, a watch dog timer, and a hardware E-STOP circuit.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General
- * Public License as published by the Free Software Foundation.
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR
- * ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE
- * TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of
- * harming persons must have provisions for completely removing power
- * from all motors, etc, before persons enter any danger area. All
- * machinery must be designed to comply with local and national safety
- * codes, and the authors of this software can not, and do not, take
- * any responsibility for such compliance.
- *
- * This code was written as part of the EMC HAL project. For more
- * information, go to www.linuxcnc.org.
- *
- ******************************************************************************/
-
-#ifndef _MOTENC_H_
-#define _MOTENC_H_
-
-
-#include
-
-
-// Vendor and device ID.
-#define MOTENC_VENDOR_ID 0x10B5 // PLX.
-#define MOTENC_DEVICE_ID 0x3001 // MOTENC-100.
-#define MOTENC_SUB_SYS_VENDOR_ID 0x10B5 // PLX.
-#define MOTENC_SUB_SYS_DEVICE_ID 0x9030 // 9030 SMARTarget I/O Accelerator.
-
-#define MOTENC_PCI_MEM_LEN 512
-
-#define MOTENC_NUM_ADC_CHANNELS 8
-#define MOTENC_NUM_DAC_CHANNELS 8
-
-#define MOTENC_FPGA_NUM_ENCODER_CHANNELS 4
-#define MOTENC_FPGA_NUM_DIGITAL_INPUTS 36
-#define MOTENC_FPGA_NUM_DIGITAL_OUTPUTS 16
-
-#define MOTENC_NUM_FPGA 2
-#define MOTENC_NUM_ENCODER_CHANNELS (MOTENC_NUM_FPGA * MOTENC_FPGA_NUM_ENCODER_CHANNELS)
-#define MOTENC_NUM_DIGITAL_INPUTS (MOTENC_NUM_FPGA * MOTENC_FPGA_NUM_DIGITAL_INPUTS - 4)
-#define MOTENC_NUM_DIGITAL_OUTPUTS (MOTENC_NUM_FPGA * MOTENC_FPGA_NUM_DIGITAL_OUTPUTS)
-
-
-
-typedef struct {
- volatile rtapi_s32 encoderCount[MOTENC_FPGA_NUM_ENCODER_CHANNELS];
- volatile rtapi_u32 digitalIo;
- volatile rtapi_u32 statusControl;
- volatile rtapi_u32 reserved;
- volatile rtapi_u32 boardVersion;
-} volatile MotencFpgaRegMap;
-
-// For use with digitalIo reg.
-#define MOTENC_DIGITAL_OUT 0x0000FFFF
-#define MOTENC_DIGITAL_OUT_SHFT 0
-#define MOTENC_DIGITAL_IN 0xFFFF0000
-#define MOTENC_DIGITAL_IN_SHFT 16
-
-// For use with statusControl reg.
-#define MOTENC_CONTROL_ENCODER_RESET 0x0000000F
-#define MOTENC_CONTROL_ENCODER_RESET_SHFT 0
-
-#define MOTENC_STATUS_DIGITAL_IN 0x0000FFFF
-#define MOTENC_STATUS_DIGITAL_IN_SHFT 0
-#define MOTENC_STATUS_BOARD_ID 0x00030000 // FPGA 0.
-#define MOTENC_STATUS_BOARD_ID_SHFT 16
-#define MOTENC_STATUS_ADC_DONE 0x00040000
-#define MOTENC_STATUS_ESTOP 0x00080000
-#define MOTENC_STATUS_DIGITAL_IN2 0x000F0000 // FPGA 1.
-#define MOTENC_STATUS_DIGITAL_IN2_SHFT 16
-#define MOTENC_STATUS_INDEX 0x00F00000
-#define MOTENC_STATUS_INDEX_SHFT 20
-#define MOTENC_STATUS_INDEX_LATCH 0x0F000000
-#define MOTENC_STATUS_INDEX_LATCH_SHFT 24
-
-typedef struct {
- MotencFpgaRegMap fpga[MOTENC_NUM_FPGA];
- volatile rtapi_u32 timerCompare;
- volatile rtapi_u32 timerIrqDisable;
- volatile rtapi_u32 timerIrqEnable;
- volatile rtapi_u32 watchdogControl;
- volatile rtapi_u32 watchdogReset;
- volatile rtapi_u32 reserved1[3];
- volatile rtapi_u32 dac[MOTENC_NUM_DAC_CHANNELS];
- volatile rtapi_u32 adcDataCommand;
- volatile rtapi_u32 reserved2[7];
- volatile rtapi_u32 adcStartConversion;
-} volatile MotencRegMap;
-
-// For use with watchdogControl reg.
-#define MOTENC_WATCHDOG_CTL_TIMEBASE 0x00000001
-#define MOTENC_WATCHDOG_CTL_8MS 0x00000000
-#define MOTENC_WATCHDOG_CTL_16MS 0x00000001
-#define MOTENC_WATCHDOG_CTL_ENABLE 0x00000004
-#define MOTENC_WATCHDOG_CTL_AUTO_RESET 0x00000010 // Reset by DAC writes.
-
-// For use with watchdogReset reg.
-#define MOTENC_WATCHDOG_RESET_VALUE 0x0000005A
-
-// For use with dac reg.
-#define MOTENC_DAC_COUNT_ZERO 0x00001000 // 0 volts.
-#define MOTENC_DAC_VOLTS_MIN -10.0 // For converting volts to counts.
-#define MOTENC_DAC_VOLTS_MAX 10.0
-#define MOTENC_DAC_SCALE_MULTIPLY -8191.0 // Higher counts are lower voltage.
-#define MOTENC_DAC_SCALE_DIVIDE (MOTENC_DAC_VOLTS_MAX - MOTENC_DAC_VOLTS_MIN)
-
-// For use with adcDataCommand reg.
-#define MOTENC_ADC_COMMAND_CHN_0 0
-#define MOTENC_ADC_COMMAND_CHN_0_1 1
-#define MOTENC_ADC_COMMAND_CHN_0_1_2 2
-#define MOTENC_ADC_COMMAND_CHN_0_1_2_3 3
-#define MOTENC_ADC_COMMAND_CHN_4 4
-#define MOTENC_ADC_COMMAND_CHN_4_5 5
-#define MOTENC_ADC_COMMAND_CHN_4_5_6 6
-#define MOTENC_ADC_COMMAND_CHN_4_5_6_7 7
-#define MOTENC_ADC_COMMAND_POWER_DOWN 8
-#define MOTENC_ADC_SIGN_BIT 0x00002000
-#define MOTENC_ADC_SIGN_EXTEND 0xFFFFC000
-#define MOTENC_ADC_VOLTS_MIN -5.0 // For converting counts to volts.
-#define MOTENC_ADC_VOLTS_MAX 5.0
-#define MOTENC_ADC_SCALE_MULTIPLY (MOTENC_ADC_VOLTS_MAX - MOTENC_ADC_VOLTS_MIN)
-#define MOTENC_ADC_SCALE_DIVIDE 16384.0
-
-
-#endif
diff --git a/src/hal/drivers/opto_ac5.c b/src/hal/drivers/opto_ac5.c
deleted file mode 100644
index cb90507bf1b..00000000000
--- a/src/hal/drivers/opto_ac5.c
+++ /dev/null
@@ -1,432 +0,0 @@
-#include
-#include // RTAPI realtime OS API.
-#include // RTAPI realtime module decls.
-#include // HAL public API decls.
-#include "opto_ac5.h" // Hardware dependent defines.
-
-#ifndef MODULE
-#define MODULE
-#endif
-
-#ifdef MODULE
-// Module information.
-MODULE_AUTHOR("Chris Morley");
-MODULE_DESCRIPTION("Driver for opto22 pci AC5 for EMC HAL");
-MODULE_LICENSE("GPL");
-#endif // MODULE
-
-
-/*************************************************************************
- typedefs and defines
-*************************************************************************/
-
-
-// Vendor and device ID. "magic numbers"
-#define opto22_VENDOR_ID 0x148a // opto22 corp
-#define opto22_pci_AC5_DEVICE_ID 0xac05 // AC5 relay board interface
-#define MAX_BOARDS 4 // could be higher uses more memory
-
-// OFFSETS FROM BASE ADDRESS FOR COMMANDS TO OPTO CARD
-// for port 0
-#define CONFIG_WRITE_OFFSET_0 0x00000004
-#define CONFIG_READ_OFFSET_0 0x00000100
-#define DATA_WRITE_OFFSET_0 0X00000008
-#define DATA_READ_OFFSET_0 0X00000300
-
-// for port 1
-#define CONFIG_WRITE_OFFSET_1 0x00000014
-#define CONFIG_READ_OFFSET_1 0x00000500
-#define DATA_WRITE_OFFSET_1 0X00000018
-#define DATA_READ_OFFSET_1 0X00000700
-
-// These methods are used for initialization.
-static int Device_Init(board_data_t *pboard);
-static int Device_ExportPinsParametersFunctions(board_data_t *pboard, int comp_id, int boardId);
-static int Device_ExportDigitalInPinsParametersFunctions(board_data_t *pboard, int comp_id, int boardId);
-static int Device_ExportDigitalOutPinsParametersFunctions(board_data_t *pboard, int comp_id, int boardId);
-// These methods are exported to the HAL.
-static void Device_DigitalInRead(void *this, long period);
-static void Device_DigitalOutWrite(void *this, long period);
-/*************************************************************************
- Globals
-*************************************************************************/
-
-
-typedef struct {
- int comp_id; /* HAL component ID */
- board_data_t *boards[MAX_BOARDS];
- int num_of_boards;
-} Driver_t;
-
-static Driver_t driver;
-
-// in case no portconfig is given when loading driver
-// sets 12 inputs then 12 outputs per port and sets leds (bit 31,32) for output
-// could define more variables so the ports of extra cards could be configured differently but
-// I doubt if anyone will use more then one card
-
-static unsigned long portconfig0 = 0Xc0fff000;
-RTAPI_MP_LONG(portconfig0, "port 0 i/o configuration number");
-static unsigned long portconfig1 = 0Xc0fff000;
-RTAPI_MP_LONG(portconfig1, "port 1 i/o configuration number");
-
-/******************************************************************************
- Init and exit code
- ******************************************************************************/
-
-int rtapi_app_main(void)
-{
- int n;
- board_data_t *pboard;
- struct pci_dev *pDev;
-
- // Connect to the HAL.
- driver.comp_id = hal_init("opto_ac5");
- if (driver.comp_id < 0) {
- rtapi_print_msg(RTAPI_MSG_ERR, " ERROR OPTO_AC5--- hal_init() failed\n");
- return(-1);
- }
- for ( n = 0 ; n < MAX_BOARDS ; n++ ) {
- driver.boards[n] = NULL;
- }
- pDev = NULL;
- for ( n = 0 ; n < MAX_BOARDS ; n++ )
- {
- // Find a M5I20 card.
- pDev = pci_get_device(opto22_VENDOR_ID, opto22_pci_AC5_DEVICE_ID, pDev);
- if ( pDev == NULL ) { /* no more boards */break;}
-
-
- /* Allocate HAL memory for the board */
- pboard = (board_data_t *)(hal_malloc(sizeof(board_data_t)));
- if ( pboard == NULL ) {
- rtapi_print_msg(RTAPI_MSG_ERR, "ERROR OPTO_AC5--- hal_malloc() failed\n");
- rtapi_app_exit();
- return -1;
- }
- // save pointer
- driver.boards[n] = pboard;
-
- /* gather info about the board and save it */
- pboard->pci_dev = pDev;
- pboard->slot = PCI_SLOT(pDev->devfn);
- pboard->num = n;
- rtapi_print("INFO OPTO_AC5--- Board %d detected in PCI Slot: %2x\n", pboard->num, pboard->slot);
- /* region 0 is the 32 bit memory mapped I/O region */
- pboard->len = pci_resource_len(pDev, 0);
- pboard->base = ioremap_nocache(pci_resource_start(pDev, 0), pboard->len);
- if ( pboard->base == NULL ) {
- rtapi_print_msg(RTAPI_MSG_ERR,
- "ERROR OPTO_AC5--- could not find board %d PCI base address\n", pboard->num );
- rtapi_app_exit();
- return -1;
- } else {
- rtapi_print(
- "INFO OPTO_AC5--- board %d mapped to %08lx, Len = %ld\n",
- pboard->num, (long)pboard->base,(long)pboard->len);
- }
- // Initialize device.
- if(Device_Init(pboard)){
- hal_exit(driver.comp_id);
- return(-1);
- }
-
- // Export pins, parameters, and functions.
- if(Device_ExportPinsParametersFunctions(pboard, driver.comp_id, n)){
- hal_exit(driver.comp_id);
- return(-1);
- }
-
- }
-
- if(n == 0){
- /* No cards detected */
- rtapi_print ("ERROR OPTO_AC5--- No opto PCI-AC5 card(s) detected\n");
- rtapi_app_exit();
- return(-1);
- }
-
- hal_ready(driver.comp_id);
- return(0);
-}
-
-// here we turn the leds and outputs off and unmap the pci driver
-void rtapi_app_exit(void)
-{
- int n;
- board_data_t *pDevice;
-
- pDevice = driver.boards[0];
-
-
- hal_exit(driver.comp_id);
- for ( n = 0; n < MAX_BOARDS; n++ )
- {
- if ( driver.boards[n] != NULL)
- {
- rtapi_print ("INFO OPTO_AC5--- board %i driver removed.\n",n);
- writel(0XC0FFFFFF, driver.boards[n]->base + (DATA_WRITE_OFFSET_0));
- writel(0XC0FFFFFF, driver.boards[n]->base + (DATA_WRITE_OFFSET_1));
- // Unmap board memory
- if ( driver.boards[n]->base != NULL )
- {
- iounmap(driver.boards[n]->base);
- }
- }
- }
-}
-
-/******************************************************************************
- * DEVICE OBJECT FUNCTION DEFINITIONS
- ******************************************************************************/
-
-/*
- * LOCAL FUNCTIONS
- */
-static int Device_Init(board_data_t *pboard)
-{
-
- // Initialize hardware.
-// portconfig[0 or 1] are either the default number from global or mapped from the command line
-// make sure last two bits are set for output so leds will work
-
- if ((portconfig0 & 0x80000000) ==0) { portconfig0 |=0x80000000; }
- if ((portconfig0 & 0x40000000) ==0) { portconfig0 |=0x40000000; }
- if ((portconfig1 & 0x80000000) ==0) { portconfig1 |=0x80000000; }
- if ((portconfig1 & 0x40000000) ==0) { portconfig1 |=0x40000000; }
- writel(portconfig0, pboard->base + (CONFIG_WRITE_OFFSET_0));
- writel(portconfig1, pboard->base + (CONFIG_WRITE_OFFSET_1));
-
- // Initialize digital I/O structure mask.
-
- pboard->port[0].mask = portconfig0;
- pboard->port[1].mask = portconfig1;
-
- return(0);
-}
-
-static int Device_ExportPinsParametersFunctions(board_data_t *this, int componentId, int boardId)
-{
- int msgLevel, error=0;
-
-// This function exports a lot of stuff, which results in a lot of
-// logging if msg_level is at INFO or ALL. So we save the current value
-// of msg_level and restore it later. If you actually need to log this
-// function's actions, change the second line below.
-
- msgLevel = rtapi_get_msg_level();
- rtapi_set_msg_level(RTAPI_MSG_WARN);
-
-// Export digital I/O.
-
- if(!error) error = Device_ExportDigitalInPinsParametersFunctions(this, componentId, boardId);
- if(!error) error = Device_ExportDigitalOutPinsParametersFunctions(this, componentId, boardId);
-
-// Restore saved message level.
-
- rtapi_set_msg_level(msgLevel);
-
- return(error);
-}
-
-// we check each ports mask (port[portnum].mask) against a mask bit to see which of the 24 points of i/o are inputs (a false bit is an input)
-// then export HAL pins mapped to the proper io structure
-// HAL pin numbers represent position in an opto22 relay rack (eg. pin 00 is position 0)
-// this way you can configure the i/o in any way for all the 24 points of each port
-
-static int Device_ExportDigitalInPinsParametersFunctions(board_data_t *this, int comp_id, int boardId)
-{
- int halError=0, channel,mask,portnum=0;
-
- // Export pins and parameters.
- while (portnum<2)
- {
- mask=1;
- for(channel = 0; channel < 24; channel++)
- {
- if ((this->port[portnum].mask & mask)==0)//physical input?
- {
- // Pins.
- if((halError = hal_pin_new_bool(comp_id, HAL_OUT, &(this->port[portnum].io[channel].pValue),
- 0, "opto-ac5.%d.port%d.in-%02d", boardId, portnum, channel)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(comp_id, HAL_OUT, &(this->port[portnum].io[channel].pValueNot),
- 1, "opto-ac5.%d.port%d.in-%02d-not", boardId, portnum, channel)) != 0)
- break;
- }
- mask <<=1;
- }
-
- portnum ++;
- }
-
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_DigitalInRead, this, 0, 0, comp_id, "opto-ac5.%d.digital-read", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "ERROR OPTO22_AC5---exporting digital inputs to HAL failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-
-// we check each ports mask (port[portnum].mask) against a mask bit to see which of the 24 points of i/o are outputs (a true bit is an output)
-// then export HAL pins mapped to the proper io structure
-// this way you can configure the i/o in any way for all the 24 points of each port
-// HAL pin numbers represent position in an opto22 relay rack (eg. pin 00 is position 0)
-// the LEDS are bits 31 and 32 of the portmask but are mapped to 24 and 25 of the i0 structure
-
-static int Device_ExportDigitalOutPinsParametersFunctions(board_data_t *this, int comp_id, int boardId)
-{
- int halError=0, channel,mask,portnum=0;
-
- // Export pins and parameters.
-
- while (portnum<2)
- {
- mask=1;
- for(channel = 0; channel < 24; channel++)
- {
- if ((this->port[portnum].mask & mask)!=0)//phyical output?
- {
- // Pins.
- if((halError = hal_pin_new_bool(comp_id, HAL_IN, &(this->port[portnum].io[channel].pValue),
- 0, "opto-ac5.%d.port%d.out-%02d", boardId, portnum, channel)) != 0)
- break;
-
- // Parameters.
- if((halError = hal_param_new_bool(comp_id, HAL_RW, &(this->port[portnum].io[channel].invert),
- 0, "opto-ac5.%d.port%d.out-%02d-invert", boardId, portnum, channel)) != 0)
- break;
- }
- mask <<=1;
- }
- portnum++;
- }
- // led Pins.
- portnum=0;
- for(channel = 0; channel < 2; channel++)
- {
- if((halError = hal_pin_new_bool(comp_id, HAL_IN, &(this->port[portnum].io[24].pValue),
- 0, "opto-ac5.%d.led%d", boardId, channel+portnum)) != 0)
- break;
-
- if((halError = hal_pin_new_bool(comp_id, HAL_IN, &(this->port[portnum].io[25].pValue),
- 0, "opto-ac5.%d.led%d", boardId, channel+portnum+1)) != 0)
- break;
- portnum++;
- }
- // Export functions.
- if(!halError){
- halError = hal_export_functf(Device_DigitalOutWrite, this, 0, 0, comp_id, "opto-ac5.%d.digital-write", boardId);
- }
-
- if(halError){
- rtapi_print_msg(RTAPI_MSG_ERR, "ERROR OPTO_AC5---exporting digital outputs to HAL failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-// here we read inputs from board
-// we read the current data (variable 'pins') of the first port. Then for each of the 24 points
-// we compare to the mask of the first port to see which of the 24 io points are inputs (the bits that are false)
-// if it is an input then check 'pins' against the mask to see if input bit is true
-// update the HAL pin and not-pin accordingly. shift the mask then do the next point (of 24 io points)
-// after all pins done-increase 'portnum' to 1 set offset to the offset for port1
-// then do it all again on the second port
-
-static void
-Device_DigitalInRead(void *arg, long period)
-{
- board_data_t *pboard = (board_data_t *)arg;
- DigitalPinsParams *pDigital;
- int i, portnum=0;
- unsigned long pins, offset=DATA_READ_OFFSET_0, mask;
-
- // For each port.
- while (portnum<2)
- {
- mask=1;
- pDigital = &pboard->port[portnum].io[0];
-
- // Read digital I/O register.
- pins= readl (pboard->base + (offset));
- for(i = 0; i < 24; i++,pDigital++)
- {
- if ((pboard->port[portnum].mask & mask) ==0) // is it an input bit ?
- {
- if ((pins & mask) !=0){ hal_set_bool(pDigital->pValue, 0);
- }else{ hal_set_bool(pDigital->pValue, 1); }
- // Update not pin.
- hal_set_bool(pDigital->pValueNot, !hal_get_bool(pDigital->pValue));
- }
- mask <<=1;// shift mask
- }
- portnum++;
- offset=DATA_READ_OFFSET_1;// change to offset for port1
- }
-}
-
-// here we output data and update LEDS
-// we look at the mask of the first port to see which of the 24 io points are outputs (the bits that are true)
-// then check the OUT HAL pins to see if output should be on and if it should - OR the bit (using 'mask') to the variable 'pins'
-// then set 'mask' to the last bit (32) and check the HAL led pin to see if true- OR the bit to 'pins' if it is
-// set 'mask to second to second to last bit (31) do the same
-// have to remember that a 1 sent to the hardware turns an output OFF
-// finally write the variable 'pins' to the boards first port
-// reset offset to the next port offset, increase portnum for port 1
-// then do it all again on the second port
-
-static void
-Device_DigitalOutWrite(void *arg, long period)
-{
- board_data_t *pboard = (board_data_t *)arg;
- DigitalPinsParams *pDigital;
- int portnum=0;
- unsigned int i,j;
- unsigned long pins, offset=DATA_WRITE_OFFSET_0,mask;
-
- // For each port.
- while (portnum<2)
- {
- pDigital = &pboard->port[portnum].io[0];
- mask=1;
- pins=0;
-
- // For each pin.
- for(j = 0; j < 24; j++, pDigital++)
- {
- if ((pboard->port[portnum].mask & mask) !=0) //is it an output?
- {
- // add mask to pins if HAL pin + invert =true.
- if( (!hal_get_bool(pDigital->pValue) && !hal_get_bool(pDigital->invert) ) ||
- ( hal_get_bool(pDigital->pValue) && hal_get_bool(pDigital->invert) ))
- { pins |= mask; }
- }
- mask <<=1; // shift mask
-
- }
-
- // CHECK LED PINS
- pDigital = &pboard->port[portnum].io[23];//one before what we want to check
- for (i = 0; i < 2; i++)
- {
- mask = (unsigned int) 1 << (31-i);
- pDigital++;
-
- if ( hal_get_bool(pDigital->pValue) == 0 ) { pins |= mask; }
- }
- // Write digital I/O register.
- writel(pins,pboard->base + (offset));
- portnum++;
- offset=DATA_WRITE_OFFSET_1; // set to port1 offset
- }
-}
-
diff --git a/src/hal/drivers/opto_ac5.h b/src/hal/drivers/opto_ac5.h
deleted file mode 100644
index eab07dac2a9..00000000000
--- a/src/hal/drivers/opto_ac5.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2005-2008, various authors
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-/*************************************************************************
-
-Header for opto22 pci AC5 board driver
-
-Copyright (C) 2008 Chris Morley
-
-*************************************************************************/
-
-#include
-
-/* code assumes that PINS_PER_PORT is <= 24 */
-//there are 2 ports on a opto22 pci AC5 card
-//number of i/o per board = 48 + 4 LEDS
-#define OPTO_NUM_DIGITAL 52
-
-/*************************************************************************
- Data Structures
-*************************************************************************/
-typedef struct DigitalPinsParams {
- // Pins.
- hal_bool_t pValue;
- hal_bool_t pValueNot;
- // Parameters.
- hal_bool_t invert;
-} DigitalPinsParams;
-
-
-
-typedef struct port_t {
- __u32 mask;
- struct DigitalPinsParams io[OPTO_NUM_DIGITAL/2];
-} port_t;
-
-
-
-
-/* master board structure */
-typedef struct board_data_t {
- struct pci_dev *pci_dev; /* PCI bus info */
- int slot; /* PCI slot number */
- int num; /* HAL board number */
- void __iomem *base; /* base address */
- int len; /* length of address space*/
- struct port_t port[2];
-
-
-} board_data_t;
-
-/*************************************************************************
- Globals
-*************************************************************************/
-
-//extern int comp_id; /* HAL component ID */
-
-
-/*************************************************************************
- Functions
-*************************************************************************/
-
-
-
diff --git a/src/hal/drivers/pci_8255.c b/src/hal/drivers/pci_8255.c
deleted file mode 100644
index 682a9e09cf9..00000000000
--- a/src/hal/drivers/pci_8255.c
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright (C) 2008 Jeff Epler
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#include
-#include
-#include
-#include
-
-#define MAX 16
-
-MODULE_LICENSE("GPL");
-int io[MAX] = {0,};
-int dir[MAX] = {0,};
-RTAPI_MP_ARRAY_INT(io, MAX, "I/O addresses of 8255s");
-RTAPI_MP_ARRAY_INT(dir, MAX, "I/O direction of 8255s");
-
-static int comp_id;
-
-union inv { hal_bool_t not_; hal_bool_t invert; };
-
-struct port {
- hal_bool_t a[8];
- hal_bool_t b[8];
- hal_bool_t c[8];
- union inv ai[8];
- union inv bi[8];
- union inv ci[8];
- hal_uint_t dir_;
- hal_uint_t ioaddr;
-};
-
-struct state {
- struct port ports[3];
- hal_bool_t relay;
- hal_bool_t relay_invert;
- hal_uint_t ioaddr;
-};
-
-static void read(struct port *inst, long period);
-static void write(struct port *inst, long period);
-static void write_relay(struct state *inst, long period);
-static void write_all(struct state *inst, long period);
-static void read_all(struct state *inst, long period);
-
-static void extra_cleanup(void);
-
-#include
-#define SHIFT 4
-static inline void pci_8255_outb(int value, rtapi_u32 base, int offset) {
- // int *mem = (int*) base;
- outb(value, base + SHIFT*offset);
- // mem[offset] = value;
-}
-
-static inline int pci_8255_inb(rtapi_u32 base, int offset) {
- return inb(base + SHIFT*offset);
- // int *mem = (int*) base;
- // return mem[offset];
-}
-
-
-static int export(char *prefix, struct port *inst, int ioaddr, int dir) {
- int r = 0;
- int i;
- hal_pin_dir_t direction;
- int sz = sizeof(struct port);
- memset(inst, 0, sz);
- if(0 != (r = hal_param_new_fake(comp_id, (hal_refs_u *)&inst->ioaddr)))
- return r;
- hal_set_ui32(inst->ioaddr, ioaddr);
-
- if(dir & 8) direction = HAL_OUT; else direction = HAL_IN;
- for(i=0; i<8; i++) {
- r = hal_pin_new_bool(comp_id, direction, &(inst->a[i]), 0,
- "%s.a%d", prefix, i);
- if(r != 0) return r;
- if(direction == HAL_OUT) {
- r = hal_pin_new_bool(comp_id, direction, &(inst->ai[i].not_), 0,
- "%s.a%d-not", prefix, i);
- } else {
- r = hal_param_new_bool(comp_id, HAL_RW, &(inst->ai[i].invert), 0,
- "%s.a%d-invert", prefix, i);
- }
- if(r != 0) return r;
- }
- if(dir & 2) direction = HAL_OUT; else direction = HAL_IN;
- for(i=0; i<8; i++) {
- r = hal_pin_new_bool(comp_id, direction, &(inst->b[i]), 0,
- "%s.b%d", prefix, i);
- if(r != 0) return r;
- if(direction == HAL_OUT) {
- r = hal_pin_new_bool(comp_id, direction, &(inst->bi[i].not_), 0,
- "%s.b%d-not", prefix, i);
- } else {
- r = hal_param_new_bool(comp_id, HAL_RW, &(inst->bi[i].invert), 0,
- "%s.b%d-invert", prefix, i);
- }
- if(r != 0) return r;
- }
- for(i=0; i<8; i++) {
- if(i < 4) {
- if(dir & 1) direction = HAL_OUT;
- else direction = HAL_IN;
- } else {
- if(dir & 4) direction = HAL_OUT;
- else direction = HAL_IN;
- }
- r = hal_pin_new_bool(comp_id, direction, &(inst->c[i]), 0,
- "%s.c%d", prefix, i);
- if(r != 0) return r;
- if(direction == HAL_OUT) {
- r = hal_pin_new_bool(comp_id, direction, &(inst->ci[i].not_), 0,
- "%s.c%d-not", prefix, i);
- } else {
- r = hal_param_new_bool(comp_id, HAL_RW, &(inst->ci[i].invert), 0,
- "%s.c%d-invert", prefix, i);
- }
- if(r != 0) return r;
- }
- r = hal_param_new_ui32(comp_id, HAL_RO, &(inst->dir_), dir,
- "%s.dir", prefix);
- if(r != 0) return r;
- r = hal_export_functf((void(*)(void *inst, long))read, inst, 0, 0, comp_id, "%s.read", prefix);
- if(r != 0) return r;
- r = hal_export_functf((void(*)(void *inst, long))write, inst, 0, 0, comp_id, "%s.write", prefix);
- if(r != 0) return r;
-
- rtapi_print_msg(RTAPI_MSG_DBG, "registering %s ... %x %x\n", prefix,
- (dir&3) | ((dir & 0xc) << 1) | 0x80, ioaddr);
-
- pci_8255_outb((dir&3) | ((dir & 0xc) << 1) | 0x80, ioaddr, 3);
-
- return 0;
-}
-
-static struct state *inst = 0;
-static int count = 0;
-
-static void write_relay(struct state *inst, long period) {
- int val = (!hal_get_bool(inst->relay)) ^ (!hal_get_bool(inst->relay_invert));
- // relay is active low
- if(val) {
- pci_8255_outb(0, hal_get_ui32(inst->ioaddr), 3);
- } else {
- pci_8255_outb(0x10, hal_get_ui32(inst->ioaddr), 3);
- }
-}
-
-static void write_all(struct state *inst, long period) {
- int i;
- for(i=0; i> (4*j)) & 0xf);
- if(r != 0) goto out_error;
- }
- hal_pin_new_bool(comp_id, HAL_IN, &(inst[i].relay), 0, "pci8255.%d.relay", i);
- hal_param_new_bool(comp_id, HAL_RW, &(inst[i].relay_invert), 0,
- "pci8255.%d.relay-invert", i);
- r = hal_export_functf((void(*)(void *inst, long))write_relay, &inst[i], 0, 0, comp_id, "pci8255.%d.write-relay", i);
- if(r != 0) return r;
- }
- r = hal_export_funct("pci8255.read-all", (void(*)(void *inst, long))read_all, inst, 0, 0, comp_id);
- r = hal_export_funct("pci8255.write-all", (void(*)(void *inst, long))write_all, inst, 0, 0, comp_id);
-out_error:
- if(r) {
- extra_cleanup();
- hal_exit(comp_id);
- } else {
- hal_ready(comp_id);
- }
- return r;
-}
-
-void rtapi_app_exit(void) {
- extra_cleanup();
- hal_exit(comp_id);
-}
-
-#define FUNCTION(name) static void name(struct state *inst, long period)
-#define EXTRA_CLEANUP() static void extra_cleanup(void)
-#define fperiod (period * 1e-9)
-#define a(i) (hal_get_bool(inst->a[(i)]))
-#define b(i) (hal_get_bool(inst->b[(i)]))
-#define c(i) (hal_get_bool(inst->c[(i)]))
-#define a_set(i,v) (hal_set_bool(inst->a[(i)], (v)))
-#define b_set(i,v) (hal_set_bool(inst->b[(i)], (v)))
-#define c_set(i,v) (hal_set_bool(inst->c[(i)], (v)))
-#define ai_invert(i) (hal_get_bool(inst->ai[i].invert))
-#define bi_invert(i) (hal_get_bool(inst->bi[i].invert))
-#define ci_invert(i) (hal_get_bool(inst->ci[i].invert))
-#define ai_not_set(i,v) (hal_set_bool(inst->ai[(i)].not_, (v)))
-#define bi_not_set(i,v) (hal_set_bool(inst->bi[(i)].not_, (v)))
-#define ci_not_set(i,v) (hal_set_bool(inst->ci[(i)].not_, (v)))
-#define ioaddr (inst->ioaddr)
-#define dir_ (inst->dir_)
-
-#include