Compare commits
252 Commits
R3.12.0-be
...
R3.12.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef12c444d8 | ||
|
|
cded07df78 | ||
|
|
81fb796c8d | ||
|
|
b3af9b389a | ||
|
|
9b76f9d9c0 | ||
|
|
302f4ef6c8 | ||
|
|
64b7a679a0 | ||
|
|
e9624769cb | ||
|
|
5ccee17d09 | ||
|
|
5e67b97e89 | ||
|
|
7cd16f8ad6 | ||
|
|
b5aa0e300c | ||
|
|
c27c38d531 | ||
|
|
b46166314f | ||
|
|
593df59742 | ||
|
|
561e2e9fb9 | ||
|
|
18b173eeb6 | ||
|
|
47b3da99a0 | ||
|
|
dd0ce8918a | ||
|
|
a655930baf | ||
|
|
84773e71a0 | ||
|
|
214b9ae5c1 | ||
|
|
420249caac | ||
|
|
17a0f487a8 | ||
|
|
bbfcd9ff78 | ||
|
|
b9dc0dad91 | ||
|
|
50be068a02 | ||
|
|
a90bdf0098 | ||
|
|
a58a2439cd | ||
|
|
962b520be8 | ||
|
|
6747d4e0e9 | ||
|
|
043eeb6a7c | ||
|
|
6b50908dd6 | ||
|
|
2d9514e8ad | ||
|
|
2e7e1416d3 | ||
|
|
ed2f5648b2 | ||
|
|
96da4b1121 | ||
|
|
3c6191cccd | ||
|
|
60a488940c | ||
|
|
1c1d8228c7 | ||
|
|
b2ee2f2347 | ||
|
|
2c2673dcea | ||
|
|
0e760bfc70 | ||
|
|
f0234af637 | ||
|
|
96f58790c4 | ||
|
|
2c1004fb41 | ||
|
|
f6025d2a1f | ||
|
|
4d046c8424 | ||
|
|
e7e17f07af | ||
|
|
8a23d381c4 | ||
|
|
46b9bb6e6a | ||
|
|
9ab85124d3 | ||
|
|
b8f07e873d | ||
|
|
0cfd58942f | ||
|
|
b75d3964d7 | ||
|
|
b9c8cd50e0 | ||
|
|
e7b8b42452 | ||
|
|
4cc62a1fce | ||
|
|
333c985399 | ||
|
|
f513681bc0 | ||
|
|
ddb459d08a | ||
|
|
6aa5ecfa0e | ||
|
|
9bdea89b06 | ||
|
|
3c8b4bf8c0 | ||
|
|
a912205614 | ||
|
|
3b094ac9ae | ||
|
|
13a7380a47 | ||
|
|
f1bc683bd4 | ||
|
|
5d3ded4397 | ||
|
|
4a5cb2a6e5 | ||
|
|
9300dded40 | ||
|
|
cb86cd03a7 | ||
|
|
cee91cb578 | ||
|
|
679e1b8a56 | ||
|
|
f6d91b8876 | ||
|
|
a86c813415 | ||
|
|
be2491bc51 | ||
|
|
1634c70c06 | ||
|
|
df876abf50 | ||
|
|
d5873d5e8a | ||
|
|
b6c87ce10e | ||
|
|
00d40d3e73 | ||
|
|
410e6d9c00 | ||
|
|
03944c94e3 | ||
|
|
b5f31b4b13 | ||
|
|
7bb7e8a884 | ||
|
|
d153387372 | ||
|
|
d4a4b23a55 | ||
|
|
14a152ba72 | ||
|
|
20b6539144 | ||
|
|
93b6da9b3c | ||
|
|
542c0115c5 | ||
|
|
15440b9b6c | ||
|
|
4cb9699c03 | ||
|
|
6460c2fc1d | ||
|
|
9b858b8a5f | ||
|
|
ed30327d93 | ||
|
|
35aba51c7f | ||
|
|
12fd359a3c | ||
|
|
e0b6ce3867 | ||
|
|
c5fce1bd6c | ||
|
|
2dfbf28c1b | ||
|
|
32add4c78f | ||
|
|
9ea5c86ab5 | ||
|
|
48efca8456 | ||
|
|
382c496b24 | ||
|
|
13173544a9 | ||
|
|
19bf9ec448 | ||
|
|
a08656090e | ||
|
|
7b03f77e30 | ||
|
|
80dbdf6814 | ||
|
|
103bd7492a | ||
|
|
e55693525c | ||
|
|
64bd8e03dc | ||
|
|
49b77d096f | ||
|
|
ae720e75af | ||
|
|
bca7b39ab6 | ||
|
|
3600bb9513 | ||
|
|
339d08b71d | ||
|
|
687e1a2c16 | ||
|
|
a53bffb128 | ||
|
|
4a7c1b1715 | ||
|
|
e75c3729b8 | ||
|
|
7cc6c1993d | ||
|
|
63a3b6827c | ||
|
|
b1f570f66d | ||
|
|
239e6cfa2e | ||
|
|
e783ec0de9 | ||
|
|
23f970b821 | ||
|
|
7ff04ea451 | ||
|
|
fd9d79f445 | ||
|
|
a12e94cffb | ||
|
|
d38eaf82cd | ||
|
|
b1382c3f19 | ||
|
|
7eaeac2075 | ||
|
|
96defa3afa | ||
|
|
4b2f0c1d74 | ||
|
|
53bfe9888a | ||
|
|
2c82e2976c | ||
|
|
ea2efa0e47 | ||
|
|
bd5b7b61a0 | ||
|
|
6d2eafd2ca | ||
|
|
67b4dc7064 | ||
|
|
f3ad1f4d4e | ||
|
|
0eb9331f88 | ||
|
|
35b0e4aaba | ||
|
|
1ea57db276 | ||
|
|
062e3d6d32 | ||
|
|
6937834dee | ||
|
|
f9793ec277 | ||
|
|
a93e2e8b26 | ||
|
|
d7275641dc | ||
|
|
9dc64d0063 | ||
|
|
afd124a431 | ||
|
|
a2952bdd75 | ||
|
|
5003f11977 | ||
|
|
8e12035e4a | ||
|
|
294c6778ec | ||
|
|
3178294f08 | ||
|
|
aa9222e276 | ||
|
|
fc18b7d4fb | ||
|
|
d4c7e14fd5 | ||
|
|
76dfa54089 | ||
|
|
24bc06d5ff | ||
|
|
e19085e380 | ||
|
|
69fc84d4a6 | ||
|
|
415ac1f797 | ||
|
|
e4c383cfb5 | ||
|
|
c89e742e67 | ||
|
|
ab11ca0407 | ||
|
|
78f3b493ea | ||
|
|
cdf7a99013 | ||
|
|
47e4ce63b1 | ||
|
|
48cfc5ee15 | ||
|
|
8746390dda | ||
|
|
cbe1a0b970 | ||
|
|
273f7aa5e3 | ||
|
|
e74acbc234 | ||
|
|
b30c979b0b | ||
|
|
68a0f7a00b | ||
|
|
0c9de2c129 | ||
|
|
e3f3d9c87b | ||
|
|
45c5f93950 | ||
|
|
c0e1c071bb | ||
|
|
e95156d29b | ||
|
|
a437b010b3 | ||
|
|
7d3ed265a5 | ||
|
|
85e899484d | ||
|
|
8bb3067b90 | ||
|
|
1b5d92daf1 | ||
|
|
22336dce1b | ||
|
|
1ecdaff1b5 | ||
|
|
de878747c6 | ||
|
|
3cc8bec710 | ||
|
|
2a87278529 | ||
|
|
9bbf6fe17e | ||
|
|
1c4adbf2ce | ||
|
|
0170e0c88a | ||
|
|
7b1c33aa63 | ||
|
|
faf07df760 | ||
|
|
9594f7d245 | ||
|
|
61d8593e66 | ||
|
|
363bf2a47c | ||
|
|
ba5d364469 | ||
|
|
1ea888e720 | ||
|
|
2f4992ceb7 | ||
|
|
3186db5576 | ||
|
|
e7e77e415f | ||
|
|
8bbe24525b | ||
|
|
33074d31f4 | ||
|
|
16c09ec67c | ||
|
|
a79e478a32 | ||
|
|
3941fb3ead | ||
|
|
1eb71e24b6 | ||
|
|
dacd2a6cc5 | ||
|
|
e5dae1d675 | ||
|
|
5f24768671 | ||
|
|
d4f720482b | ||
|
|
8f3b1cce16 | ||
|
|
a94db92c29 | ||
|
|
b6a46820e9 | ||
|
|
cf7307f399 | ||
|
|
fb0a164de1 | ||
|
|
8d9d7a126a | ||
|
|
67378ebaa1 | ||
|
|
0859173047 | ||
|
|
0f1c9c357a | ||
|
|
a4cfb43ba1 | ||
|
|
6c620894f5 | ||
|
|
b7451c7a5d | ||
|
|
a2331c9d0e | ||
|
|
f44ce3dbb0 | ||
|
|
d9066673ef | ||
|
|
82867f0684 | ||
|
|
6fb928ea9d | ||
|
|
ad41921414 | ||
|
|
17c54db7f7 | ||
|
|
a60cba8671 | ||
|
|
1066acd60c | ||
|
|
4c546a0299 | ||
|
|
d6fe343a88 | ||
|
|
94c6314dc9 | ||
|
|
1657a97783 | ||
|
|
36fb04f13a | ||
|
|
2ea3005498 | ||
|
|
885e9e829f | ||
|
|
5f53ebb4c2 | ||
|
|
6bc97431bc | ||
|
|
0b50562f67 | ||
|
|
523c0c37c6 | ||
|
|
52eba44ac4 | ||
|
|
d6aa5a4dac |
5
Makefile
5
Makefile
@@ -12,6 +12,9 @@
|
||||
# install because the release.% syntax is illegal.
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.22 1994/11/14 23:12:17 tang
|
||||
# Replace ARCH_TYPE with .
|
||||
#
|
||||
# Revision 1.1.1.1 1994/11/09 01:08:53 epics
|
||||
# Import of R3.12.0Beta
|
||||
#
|
||||
@@ -46,7 +49,7 @@
|
||||
#
|
||||
|
||||
EPICS=..
|
||||
include $(EPICS)/config/CONFIG_SITE
|
||||
include $(EPICS)/config/CONFIG
|
||||
|
||||
all: install
|
||||
|
||||
|
||||
71
README
71
README
@@ -10,20 +10,20 @@ Notes:
|
||||
1. Before you can build or really use EPICS, you must set your
|
||||
path properly:
|
||||
|
||||
set path = ( $path EPICS/base/tools EPICS/base/bin/HOST_ARCH )
|
||||
set path = ( $path EPICS/base/tools EPICS/base/bin/HOST_ARCH \
|
||||
EPICS/extensions/bin HOST_ARCH )
|
||||
|
||||
e.g.:
|
||||
|
||||
set path = ( $path /home/epics/base/tools /home/epics/base/bin/sun4 )
|
||||
set path = ( $path /home/epics/base/tools /home/epics/base/bin/sun4 \
|
||||
/home/epics/extensions/bin/sun4 )
|
||||
|
||||
2. If you are using GNU make (which is now THE supported make utility
|
||||
for the build), you probably want to invoke it with the
|
||||
--no-print-directory option when you are building at the TOP level:
|
||||
2. You must use GNU make (which is now THE supported make utility) for
|
||||
the build. A script, gmake, exists in the base/tools directory to invoke
|
||||
it with the --no-print-directory option. This option will turn off the
|
||||
annoying messages GNU make produces upon entering a directory.
|
||||
|
||||
make --no-print-directory
|
||||
|
||||
This is to turn off the annoying messages GNU make produces upon
|
||||
entering a directory.
|
||||
gmake
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Part 1 - Configuring and Building EPICS Base
|
||||
@@ -31,13 +31,13 @@ This is to turn off the annoying messages GNU make produces upon
|
||||
|
||||
1.1 To configure EPICS, edit the following files:
|
||||
|
||||
base/config/CONFIG_SITE - Build choices/HOST_ARCH/Vx location.
|
||||
base/config/CONFIG_SITE.* - Location of X, etc.
|
||||
base/config/CONFIG - For overriding specific variables.
|
||||
config/CONFIG_SITE - Build choices/HOST_ARCH/Vx location.
|
||||
config/CONFIG_SITE.* - Location of X, etc.
|
||||
config/CONFIG - For overriding specific variables.
|
||||
|
||||
1.2 To add a target architecture to EPICS:
|
||||
|
||||
cd epics/base/config
|
||||
cd epics/config
|
||||
cp CONFIG_ARCH.mv167 CONFIG_ARCH.YOUR_ARCH
|
||||
edit CONFIG_ARCH.YOUR_ARCH - For compiler flags / etc.
|
||||
|
||||
@@ -50,25 +50,27 @@ This is to turn off the annoying messages GNU make produces upon
|
||||
|
||||
1.3 To build EPICS:
|
||||
|
||||
make - To build and install EPICS.
|
||||
make clean - To clean temporary object files. Clean will
|
||||
remove files from ALL O.ARCH dirs, not
|
||||
only those specified in BUILD_ARCHS.
|
||||
cd epics/base
|
||||
gmake - To build and install EPICS.
|
||||
gmake clean - To clean temporary object files. Clean will
|
||||
remove files from ALL O.ARCH dirs, not
|
||||
only those specified in BUILD_ARCHS.
|
||||
|
||||
1.4 To create an EPICS release:
|
||||
|
||||
edit include/version.h - ONLY IF you need to change the EPICS
|
||||
edit base/include/version.h - ONLY IF you need to change the EPICS
|
||||
version number.
|
||||
|
||||
make release - Will create Tar file, but only after
|
||||
generating dependencies.
|
||||
make built_release - Same as above, but INCLUDING BINARIES.
|
||||
gmake release - Will create Tar file
|
||||
|
||||
gmake built_release - Will create Tar file, after generating
|
||||
dependencies, INCLUDING BINARIES.
|
||||
|
||||
1.5 "Partial" build commands:
|
||||
|
||||
make clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
|
||||
make install.sun4 - Builds sun4 only.
|
||||
make install.mv167 - Builds mv167 only (a HOST_ARCH build must
|
||||
gmake clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
|
||||
gmake install.sun4 - Builds sun4 only.
|
||||
gmake install.mv167 - Builds mv167 only (a HOST_ARCH build must
|
||||
be complete before this can be issued).
|
||||
|
||||
NOTES:
|
||||
@@ -81,8 +83,8 @@ NOTES:
|
||||
|
||||
3. During a normal build (a "make" or "make install"), the "depends"
|
||||
dependency will NOT be invoked. Only if "make depends" is run
|
||||
explicitly, or a "make release" is performed will dependencies be
|
||||
generated automatically.
|
||||
explicitly, or a "make built_release" is performed will dependencies
|
||||
be generated automatically.
|
||||
|
||||
4. Temporary objects are stored in src/DIR/O.ARCH, This allows objects
|
||||
for multiple architectures to be maintained at the same time.
|
||||
@@ -130,11 +132,16 @@ define compile and link flags.
|
||||
----------------------------------------------------------------------------
|
||||
CONFIG_COMMON - Contains definitions describing the layout of base.
|
||||
----------------------------------------------------------------------------
|
||||
HRULES - Rules for traversing hierarchical directories.
|
||||
CONFIG_BASE
|
||||
CONFIG_EXTENSIONS - Defines what subdirectories get built by default under
|
||||
base and extensions.
|
||||
----------------------------------------------------------------------------
|
||||
RULES.Vx - Rules for building with VxWorks makefiles.
|
||||
----------------------------------------------------------------------------
|
||||
RULES.Unix - Rules for building with Unix makefiles.
|
||||
----------------------------------------------------------------------------
|
||||
RULES_ARCHS
|
||||
RULES_DIRS - Allows top-level type command syntax in low-level directories.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Table of files to change when building and adding architectures.
|
||||
@@ -149,10 +156,13 @@ CONFIG_SITE.Unix.ARCH_CLASS m - c* -
|
||||
CONFIG_SITE.Vx.ARCH_CLASS m c* - -
|
||||
CONFIG.Unix.ARCH_CLASS - - c* -
|
||||
CONFIG.Vx.ARCH_CLASS - c* - -
|
||||
CONFIG_COMMON - - - -
|
||||
HRULES - - - -
|
||||
RULES.Vx - - - -
|
||||
RULES.Unix - - - -
|
||||
CONFIG_BASE - - - -
|
||||
CONFIG_EXTENSIONS - - - -
|
||||
CONFIG_COMMON - - - -
|
||||
RULES_ARCHS - - - -
|
||||
RULES_DIRS - - - -
|
||||
|
||||
m - Modify an existing file.
|
||||
c - Create a new file.
|
||||
@@ -229,9 +239,6 @@ RULES.Unix - - - -
|
||||
Dependencies supported by lower level Makefiles:
|
||||
|
||||
depends - Generate include dependencies
|
||||
pre_build - Build e_flex / antelope
|
||||
build_libs - Builds libraries for use in "build"
|
||||
install_libs - Installs these libraries in lib/ARCH
|
||||
build - Builds objects, using libraries from "build_libs"
|
||||
install - Installs executables in bin/ARCH
|
||||
clean - Cleans objects
|
||||
|
||||
29
README.solaris
Normal file
29
README.solaris
Normal file
@@ -0,0 +1,29 @@
|
||||
----------------------------------------------------------------------------
|
||||
EPICS R3.12 Notes for Solaris 2.3
|
||||
- By Andrew Johnson
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Notes:
|
||||
|
||||
1. In order to build and use EPICS under Solaris 2, you must include
|
||||
various directories in your path in the order given below, in addition
|
||||
to those named in base/README. Some of these directories may already be
|
||||
included in your path from your .login script or .cshrc file, so be
|
||||
careful that the ordering is correct.
|
||||
|
||||
setenv PATH /usr/ucb:/usr/bin:/usr/ccs/bin:$PATH
|
||||
|
||||
2. It is not possible to compile the whole of EPICS under Solaris 2
|
||||
using only the GNU gcc compiler - some routines which are needed (for
|
||||
example quiet_nan()) have been unbundled by Sun and are provided with
|
||||
their ANSI C compiler. The path to the Sun compiler is explicitly set
|
||||
using the SPARCWORKS definition in the file CONFIG_SITE.Unix.solaris
|
||||
|
||||
3. EPICS must be compiled and linked using the UCB compatability
|
||||
libraries. The definitions UCB_LIB and UCB_INCLUDE are used here to
|
||||
refer to these libraries and their header files, and the tools provided
|
||||
within /usr/ucb must be used in preference to the System V ones, hence
|
||||
the above path ordering.
|
||||
|
||||
--
|
||||
anj@mail.ast.cam.ac.uk
|
||||
@@ -3,7 +3,7 @@ include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -D_NO_PROTO
|
||||
USR_LDLIBS = -lAs -lCom -lDb -lCom -s
|
||||
USR_LDLIBS = -lAs -lCom -lDb -lCom -lm -s
|
||||
USR_LDFLAGS = -L.
|
||||
|
||||
DEPLIBS_BASE = $(EPICS_BASE_LIB)
|
||||
|
||||
@@ -52,6 +52,10 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
* .01 10-15-93 mrk Initial Implementation
|
||||
*/
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#endif
|
||||
#include <dbDefs.h>
|
||||
#include <asLib.h>
|
||||
#include <string.h>
|
||||
@@ -60,9 +64,6 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
#include <stdio.h>
|
||||
#include <gpHash.h>
|
||||
#include <freeList.h>
|
||||
#ifdef vxWorks
|
||||
#include <taskLib.h>
|
||||
#endif
|
||||
|
||||
/*Declare storage for Global Variables */
|
||||
ASBASE *pasbase=NULL;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
integer [0-9]
|
||||
name [a-zA-Z0-9_\.]
|
||||
pvname [a-zA-Z0-9_:\.\[\]<>]
|
||||
pvname [a-zA-Z0-9_:\.\[\]<>;]
|
||||
string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$]
|
||||
|
||||
%{
|
||||
|
||||
@@ -15,13 +15,31 @@ $! - You are using Multinet for TCP/IP access. If not, the logical
|
||||
$! name definitions below will need to be changed
|
||||
$!
|
||||
$!
|
||||
$! Arguments : None
|
||||
$! Arguments : optional source file name
|
||||
$!
|
||||
$! Created 16-NOV-1993 Mark L. Rivers
|
||||
$! 05-MAY-1994 Jeff O. Hill Updated for EPICS 3.12
|
||||
$! 07-MAR-1995 Jeff O. Hill Added FTP script
|
||||
$!
|
||||
$!========================================================================
|
||||
$!
|
||||
$! Example FTP script moves sources from UNIX to VMS
|
||||
$! (remove "$!" comment delimeters)
|
||||
$!
|
||||
$! user XXXXXXX
|
||||
$! cd [.ca]
|
||||
$! prompt
|
||||
$! lcd ~/epics/base/src/ca
|
||||
$! mput *.c
|
||||
$! mput *.h
|
||||
$! put BUILD_VMS.COM
|
||||
$! lcd ../libCom
|
||||
$! mput *.c
|
||||
$! mput *.h
|
||||
$! lcd ../../include
|
||||
$! mput *.h
|
||||
$!========================================================================
|
||||
$!
|
||||
$ define /nolog sys multinet_root:[multinet.include.sys]
|
||||
$ define /nolog vms multinet_root:[multinet.include.vms]
|
||||
$ define /nolog net multinet_root:[multinet.include.net]
|
||||
@@ -30,11 +48,13 @@ $ define /nolog arpa multinet_root:[multinet.include.arpa]
|
||||
$ define /nolog tcp multinet_root:[multinet.include]
|
||||
$!
|
||||
$! Compile the functions and test programs
|
||||
$! Define symbol for the CC command
|
||||
$ call set_cc_command
|
||||
$ if (p1 .nes. "")
|
||||
$ then
|
||||
$ cc /defines=(__STDC__)/include=([]) 'p1'
|
||||
$ cc_command 'p1'
|
||||
$ else
|
||||
$ cc /defines=(__STDC__)/include=([]) -
|
||||
$ cc_command -
|
||||
ACCESS, -
|
||||
CONN, -
|
||||
CONVERT, -
|
||||
@@ -51,6 +71,9 @@ VMS_DEPEN, -
|
||||
ELLLIB, -
|
||||
BUCKETLIB, -
|
||||
ENVSUBR, -
|
||||
TSSUBR, -
|
||||
NEXTFIELDSUBR, -
|
||||
ASSERTUNIX, -
|
||||
CATIME, -
|
||||
ACCTST
|
||||
$ endif
|
||||
@@ -71,7 +94,10 @@ IF_DEPEN, -
|
||||
VMS_DEPEN, -
|
||||
BSD_DEPEN, -
|
||||
BUCKETLIB, -
|
||||
TSSUBR, -
|
||||
ENVSUBR, -
|
||||
NEXTFIELDSUBR, -
|
||||
ASSERTUNIX, -
|
||||
ELLLIB
|
||||
$! Link the test programs
|
||||
$ call link acctst
|
||||
@@ -84,10 +110,32 @@ $ catime == "$ EPICS_EXE:catime.exe"
|
||||
$
|
||||
$!
|
||||
$ link: subroutine
|
||||
$ link 'p1', sys$input/options
|
||||
channel_access/lib
|
||||
multinet_socket_library/share
|
||||
sys$share:vaxcrtl/share
|
||||
$! Link differently for VAX and AXP
|
||||
$ if f$getsyi("HW_MODEL") .ge. 1024
|
||||
$ then
|
||||
$ link 'p1', sys$input/options
|
||||
channel_access/lib
|
||||
multinet_socket_library/share
|
||||
$ else
|
||||
$ link 'p1', sys$input/options
|
||||
channel_access/lib
|
||||
multinet_socket_library/share
|
||||
sys$share:vaxcrtl/share
|
||||
$ endif
|
||||
$ endsubroutine
|
||||
$
|
||||
$
|
||||
$! This subroutine sets up "cc_command" to use different switches for
|
||||
$! VAX (assumes VAX C compiler) and AXP (DEC C compiler).
|
||||
$ set_cc_command : subroutine
|
||||
$ if f$getsyi("HW_MODEL") .ge. 1024
|
||||
$ then
|
||||
$! turn of no prototype messages because MULTINET does not
|
||||
$! supply prototypes.
|
||||
$ cc_command:== cc /warn=(disable=IMPLICITFUNC)/float=d_float /include=([], [-.include], [-.libcom])
|
||||
$ else
|
||||
$ cc_command:== cc /include=([], [-.include], [-.libcom])
|
||||
$ endif
|
||||
$ endsubroutine
|
||||
$! ************************************************************
|
||||
|
||||
|
||||
@@ -2,26 +2,27 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
|
||||
USR_LDLIBS = -lca -lCom
|
||||
USR_LDLIBS = -lca -lCom -lm
|
||||
USR_LDFLAGS = -L.
|
||||
|
||||
DEPLIBS_BASE = $(EPICS_BASE_LIB)
|
||||
DEPLIBS = ./libca.a\
|
||||
$(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
|
||||
SRCS.c = \
|
||||
../iocinf.c ../access.c ../test_event.c ../service.c \
|
||||
../flow_control.c ../repeater.c ../conn.c ../acctst.c \
|
||||
../flow_control.c ../repeater.c ../conn.c \
|
||||
../syncgrp.c ../if_depen.c ../netdb_depen.c ../bsd_depen.c \
|
||||
../posix_depen.c ../caRepeater.c ../acctst.c
|
||||
../posix_depen.c ../caRepeater.c ../acctst.c ../catime.c \
|
||||
../convert.c
|
||||
|
||||
OBJS = caRepeater.o
|
||||
|
||||
LIBOBJS = \
|
||||
iocinf.o access.o test_event.o service.o flow_control.o repeater.o \
|
||||
conn.o syncgrp.o if_depen.o netdb_depen.o \
|
||||
bsd_depen.o posix_depen.o
|
||||
bsd_depen.o posix_depen.o convert.o
|
||||
|
||||
LIBNAME = libca.a
|
||||
|
||||
@@ -30,8 +31,16 @@ PROD = caRepeater
|
||||
|
||||
include $(EPICS)/config/RULES.Unix
|
||||
|
||||
acctst: acctst.o $(DEPLIBS_BASE)/libCom.a libca.a
|
||||
acctst: acctst.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
acctst.o: ../acctst.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
catime: catime.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
catime.o: ../catime.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
|
||||
|
||||
SRCS.c = \
|
||||
../iocinf.c ../access.c ../test_event.c ../service.c \
|
||||
../flow_control.c ../repeater.c ../conn.c ../syncgrp.c \
|
||||
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c
|
||||
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c \
|
||||
../catime.c
|
||||
|
||||
OBJS = \
|
||||
iocinf.o access.o test_event.o service.o flow_control.o \
|
||||
@@ -20,3 +19,10 @@ include $(EPICS)/config/RULES.Vx
|
||||
caLib: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
acctst.o: ../acctst.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
catime.o: ../catime.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
|
||||
659
src/ca/access.c
659
src/ca/access.c
File diff suppressed because it is too large
Load Diff
@@ -9,13 +9,18 @@ static char *sccsId = "@(#) $Id$";
|
||||
#include <LIB$ROUTINES.H>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
/*
|
||||
* ANSI
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "os_depen.h"
|
||||
|
||||
#include <cadef.h>
|
||||
#include "os_depen.h"
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <cadef.h>
|
||||
|
||||
#define EVENT_ROUTINE null_event
|
||||
#define CONN_ROUTINE conn
|
||||
@@ -75,18 +80,20 @@ int doacctst(char *pname)
|
||||
chid chix2;
|
||||
chid chix3;
|
||||
chid chix4;
|
||||
struct dbr_gr_float *ptr;
|
||||
struct dbr_gr_float *pgrfloat;
|
||||
struct dbr_gr_float *ptr = NULL;
|
||||
struct dbr_gr_float *pgrfloat = NULL;
|
||||
float *pfloat = NULL;
|
||||
double *pdouble = NULL;
|
||||
long status;
|
||||
long i, j;
|
||||
evid monix;
|
||||
float *pfloat;
|
||||
double *pdouble;
|
||||
char pstring[NUM][MAX_STRING_SIZE];
|
||||
|
||||
|
||||
SEVCHK(ca_task_initialize(), "Unable to initialize");
|
||||
|
||||
conn_get_cb_count = 0;
|
||||
|
||||
printf("begin\n");
|
||||
#ifdef VMS
|
||||
lib$init_timer();
|
||||
@@ -198,8 +205,6 @@ int doacctst(char *pname)
|
||||
lib$show_timer();
|
||||
#endif /*VMS*/
|
||||
|
||||
pfloat = &ptr->value;
|
||||
|
||||
#ifdef VMS
|
||||
lib$init_timer();
|
||||
#endif /*VMS*/
|
||||
@@ -219,22 +224,22 @@ int doacctst(char *pname)
|
||||
|
||||
double dval = 3.3;
|
||||
float fval = -8893.3;
|
||||
double dret;
|
||||
float fret;
|
||||
double dret = DBL_MAX;
|
||||
float fret = FLT_MAX;
|
||||
|
||||
status = ca_put(DBR_DOUBLE, chix1, &dval);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_get(DBR_DOUBLE, chix1, &dret);
|
||||
SEVCHK(status, NULL);
|
||||
ca_pend_io(30.0);
|
||||
assert(dval - dret < .000001);
|
||||
assert( fabs(dval-dret) < DBL_EPSILON*4);
|
||||
|
||||
status = ca_put(DBR_FLOAT, chix1, &fval);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_get(DBR_FLOAT, chix1, &fret);
|
||||
SEVCHK(status, NULL);
|
||||
ca_pend_io(30.0);
|
||||
assert(fval - fret < .0001);
|
||||
assert( fabs(fval-fret) < FLT_EPSILON*4);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -298,7 +303,6 @@ int doacctst(char *pname)
|
||||
printf("Skipped multiple get cb test - no read access\n");
|
||||
}
|
||||
|
||||
|
||||
if(ca_v42_ok(chix1)){
|
||||
test_sync_groups(chix1);
|
||||
}
|
||||
@@ -413,10 +417,10 @@ int doacctst(char *pname)
|
||||
&monix);
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
pfloat = (float *) malloc(sizeof(float) * NUM);
|
||||
pdouble = (double *) malloc(sizeof(double) * NUM);
|
||||
pgrfloat = (struct dbr_gr_float *) malloc(sizeof(*pgrfloat) * NUM);
|
||||
|
||||
pfloat = (float *) calloc(sizeof(float),NUM);
|
||||
pdouble = (double *) calloc(sizeof(double),NUM);
|
||||
pgrfloat = (struct dbr_gr_float *) calloc(sizeof(*pgrfloat),NUM);
|
||||
|
||||
if (VALID_DB_REQ(chix1->type))
|
||||
if (pfloat)
|
||||
@@ -482,10 +486,18 @@ int doacctst(char *pname)
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
free(pfloat);
|
||||
free(pdouble);
|
||||
free(pgrfloat);
|
||||
if (ptr){
|
||||
free (ptr);
|
||||
}
|
||||
if (pfloat) {
|
||||
free(pfloat);
|
||||
}
|
||||
if (pdouble) {
|
||||
free(pdouble);
|
||||
}
|
||||
if (pgrfloat) {
|
||||
free(pgrfloat);
|
||||
}
|
||||
|
||||
status = ca_task_exit();
|
||||
SEVCHK(status,NULL);
|
||||
@@ -550,8 +562,8 @@ void conn_cb(struct event_handler_args args)
|
||||
void test_sync_groups(chid chix)
|
||||
{
|
||||
int status;
|
||||
CA_SYNC_GID gid1;
|
||||
CA_SYNC_GID gid2;
|
||||
CA_SYNC_GID gid1=0;
|
||||
CA_SYNC_GID gid2=0;
|
||||
|
||||
printf("Performing sync group test...");
|
||||
fflush(stdout);
|
||||
|
||||
@@ -18,8 +18,8 @@ void caAddConfiguredAddr(
|
||||
SOCKET socket,
|
||||
int port);
|
||||
|
||||
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
|
||||
|
||||
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
|
||||
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort);
|
||||
|
||||
union caAddr{
|
||||
struct sockaddr_in inetAddr;
|
||||
|
||||
@@ -42,10 +42,15 @@
|
||||
*/
|
||||
int cac_select_io(struct timeval *ptimeout, int flags)
|
||||
{
|
||||
/*
|
||||
* Use auto timeout so there is no chance of
|
||||
* recursive reuse of ptimeout
|
||||
*/
|
||||
struct timeval autoTimeOut = *ptimeout;
|
||||
long status;
|
||||
IIU *piiu;
|
||||
unsigned long freespace;
|
||||
int maxfd;
|
||||
SOCKET maxfd;
|
||||
caFDInfo *pfdi;
|
||||
|
||||
LOCK;
|
||||
@@ -60,7 +65,6 @@ int cac_select_io(struct timeval *ptimeout, int flags)
|
||||
}
|
||||
}
|
||||
ellAdd (&ca_static->fdInfoList, &pfdi->node);
|
||||
UNLOCK;
|
||||
|
||||
FD_ZERO (&pfdi->readMask);
|
||||
FD_ZERO (&pfdi->writeMask);
|
||||
@@ -87,32 +91,32 @@ int cac_select_io(struct timeval *ptimeout, int flags)
|
||||
}
|
||||
|
||||
if (flags&CA_DO_SENDS) {
|
||||
if (cacRingBufferReadSize(&piiu->send, FALSE)>0) {
|
||||
if (cacRingBufferReadSize(&piiu->send, FALSE)>0) {
|
||||
maxfd = max (maxfd,piiu->sock_chan);
|
||||
FD_SET (piiu->sock_chan, &pfdi->writeMask);
|
||||
}
|
||||
FD_SET (piiu->sock_chan, &pfdi->writeMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
pfdi->writeSave = pfdi->writeMask;
|
||||
pfdi->readSave = pfdi->readMask;
|
||||
# if defined(__hpux)
|
||||
status = select(
|
||||
maxfd+1,
|
||||
(int *)&pfdi->readMask,
|
||||
(int *)&pfdi->writeMask,
|
||||
(int *)NULL,
|
||||
&autoTimeOut);
|
||||
# else
|
||||
status = select(
|
||||
maxfd+1,
|
||||
&pfdi->readMask,
|
||||
&pfdi->writeMask,
|
||||
NULL,
|
||||
&autoTimeOut);
|
||||
# endif
|
||||
|
||||
#if 0
|
||||
printf( "max fd=%d tv_usec=%d tv_sec=%d\n",
|
||||
maxfd,
|
||||
ptimeout->tv_usec,
|
||||
ptimeout->tv_sec);
|
||||
#endif
|
||||
status = select(
|
||||
maxfd+1,
|
||||
&pfdi->readMask,
|
||||
&pfdi->writeMask,
|
||||
NULL,
|
||||
ptimeout);
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
|
||||
#if 0
|
||||
printf("leaving select stat=%d errno=%d \n", status, MYERRNO);
|
||||
#endif
|
||||
if (status<0) {
|
||||
if (MYERRNO == EINTR) {
|
||||
}
|
||||
@@ -138,25 +142,13 @@ printf("leaving select stat=%d errno=%d \n", status, MYERRNO);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(piiu->sock_chan,&pfdi->writeMask)) {
|
||||
(*piiu->sendBytes)(piiu);
|
||||
}
|
||||
#if 0
|
||||
else{
|
||||
if (FD_ISSET(piiu->sock_chan, &pfdi->writeSave)) {
|
||||
if(FD_ISSET(piiu->sock_chan, &pfdi->readSave) &&
|
||||
!FD_ISSET(piiu->sock_chan,&pfdi->readMask)) {
|
||||
printf("Still waiting to send on %d with recv empty\n", piiu->sock_chan);
|
||||
}
|
||||
if(!FD_ISSET(piiu->sock_chan, &pfdi->readSave)){
|
||||
printf("Still waiting to send on %d with no recv wait?\n", piiu->sock_chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (FD_ISSET(piiu->sock_chan,&pfdi->readMask)) {
|
||||
(*piiu->recvBytes)(piiu);
|
||||
}
|
||||
|
||||
if (FD_ISSET(piiu->sock_chan,&pfdi->writeMask)) {
|
||||
(*piiu->sendBytes)(piiu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <iocinf.h>
|
||||
|
||||
main()
|
||||
{
|
||||
ca_repeater();
|
||||
assert(0);
|
||||
ca_repeater ();
|
||||
assert (0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -52,12 +52,7 @@ static char *sccsId = "@(#) $Id$";
|
||||
* Dump error messages to the appropriate place
|
||||
*
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
int ca_printf(char *pformat, ...)
|
||||
#else
|
||||
int ca_printf(va_alist)
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
int status;
|
||||
@@ -65,29 +60,9 @@ va_dcl
|
||||
va_start(args, pformat);
|
||||
|
||||
#if defined(vxWorks)
|
||||
{
|
||||
int logMsgArgs[6];
|
||||
int i;
|
||||
|
||||
for(i=0; i< NELEMENTS(logMsgArgs); i++){
|
||||
logMsgArgs[i] = va_arg(args, int);
|
||||
}
|
||||
|
||||
status = logMsg(
|
||||
pformat,
|
||||
logMsgArgs[0],
|
||||
logMsgArgs[1],
|
||||
logMsgArgs[2],
|
||||
logMsgArgs[3],
|
||||
logMsgArgs[4],
|
||||
logMsgArgs[5]);
|
||||
|
||||
}
|
||||
status = mprintf(pformat, args);
|
||||
#else
|
||||
status = vfprintf(
|
||||
stderr,
|
||||
pformat,
|
||||
args);
|
||||
status = vfprintf(stderr, pformat, args);
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
|
||||
507
src/ca/catime.c
507
src/ca/catime.c
@@ -1,30 +1,25 @@
|
||||
/*
|
||||
*
|
||||
* CA performance test
|
||||
*
|
||||
* History
|
||||
* joh 09-12-89 Initial release
|
||||
* joh 12-20-94 portability
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
CA performance test
|
||||
#include <epicsAssert.h>
|
||||
#include <cadef.h>
|
||||
|
||||
History
|
||||
joh 09-12-89 Initial release
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#include <LIB$ROUTINES.H>
|
||||
#ifndef LOCAL
|
||||
#define LOCAL static
|
||||
#endif
|
||||
|
||||
|
||||
/* System includes */
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#endif
|
||||
|
||||
#include <cadef.h>
|
||||
#include <caerr.h>
|
||||
#include <db_access.h>
|
||||
|
||||
#ifndef OK
|
||||
#define OK 0
|
||||
#endif
|
||||
@@ -41,17 +36,44 @@
|
||||
#define NELEMENTS(A) (sizeof (A) / sizeof ((A) [0]))
|
||||
#endif
|
||||
|
||||
#define NUM 1
|
||||
#define ITERATION_COUNT 10000
|
||||
#define ITERATION_COUNT 1000
|
||||
|
||||
#define WAIT_FOR_ACK
|
||||
|
||||
chid chan_list[min(10000,ITERATION_COUNT)];
|
||||
typedef struct testItem {
|
||||
chid chix;
|
||||
char name[40];
|
||||
int type;
|
||||
int count;
|
||||
union db_access_val val;
|
||||
}ti;
|
||||
|
||||
ti itemList[ITERATION_COUNT];
|
||||
|
||||
int catime (char *channelName);
|
||||
|
||||
typedef void tf (ti *pItems, unsigned iterations, unsigned *pInlineIter);
|
||||
|
||||
LOCAL void test (
|
||||
ti *pItems,
|
||||
unsigned iterations
|
||||
);
|
||||
|
||||
LOCAL tf test_search;
|
||||
LOCAL tf test_free;
|
||||
LOCAL tf test_wait;
|
||||
LOCAL tf test_put;
|
||||
LOCAL tf test_wait;
|
||||
LOCAL tf test_get;
|
||||
|
||||
void timeIt(
|
||||
tf *pfunc,
|
||||
ti *pItem,
|
||||
unsigned iterations
|
||||
);
|
||||
|
||||
#ifndef vxWorks
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *pname;
|
||||
|
||||
@@ -61,167 +83,358 @@ char **argv;
|
||||
}
|
||||
else{
|
||||
printf("usage: %s <channel name>", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
catime(channelName)
|
||||
char *channelName;
|
||||
|
||||
/*
|
||||
* catime ()
|
||||
*/
|
||||
int catime (char *channelName)
|
||||
{
|
||||
chid ai_1;
|
||||
long i;
|
||||
unsigned strsize;
|
||||
|
||||
long status;
|
||||
long i,j;
|
||||
void *ptr;
|
||||
int test_search(), test_free();
|
||||
SEVCHK (ca_task_initialize(),"Unable to initialize");
|
||||
|
||||
SEVCHK(ca_task_initialize(),"Unable to initialize");
|
||||
strsize = sizeof(itemList[i].name)-1;
|
||||
for (i=0; i<NELEMENTS(itemList); i++) {
|
||||
strncpy (
|
||||
itemList[i].name,
|
||||
channelName,
|
||||
strsize);
|
||||
itemList[i].name[strsize]= '\0';
|
||||
itemList[i].count = 1;
|
||||
}
|
||||
|
||||
printf ("search test\n");
|
||||
timeIt (test_search, itemList, NELEMENTS(itemList));
|
||||
|
||||
SEVCHK(ca_search(channelName,&ai_1),NULL);
|
||||
status = ca_pend_io(5.0);
|
||||
SEVCHK(status,NULL);
|
||||
if(status == ECA_TIMEOUT)
|
||||
exit(OK);
|
||||
printf (
|
||||
"channel name=%s, native type=%d, native count=%d\n",
|
||||
ca_name(itemList[0].chix),
|
||||
ca_field_type(itemList[0].chix),
|
||||
ca_element_count(itemList[0].chix));
|
||||
|
||||
ptr = (void *) malloc(NUM*sizeof(union db_access_val)+NUM*MAX_STRING_SIZE);
|
||||
if(!ptr)
|
||||
exit(OK);
|
||||
for (i=0; i<NELEMENTS(itemList); i++) {
|
||||
itemList[i].val.fltval = 0.0;
|
||||
itemList[i].type = DBR_FLOAT;
|
||||
}
|
||||
printf ("float test\n");
|
||||
test (itemList, NELEMENTS(itemList));
|
||||
|
||||
printf("channel name %s native type %d native count %d\n",ai_1+1,ai_1->type,ai_1->count);
|
||||
printf("search test\n");
|
||||
timex(test_search,channelName);
|
||||
printf("free test\n");
|
||||
timex(test_free,ai_1);
|
||||
for (i=0; i<NELEMENTS(itemList); i++) {
|
||||
strcpy(itemList[i].val.strval, "0.0");
|
||||
itemList[i].type = DBR_STRING;
|
||||
}
|
||||
printf ("string test\n");
|
||||
test (itemList, NELEMENTS(itemList));
|
||||
|
||||
for (i=0; i<NELEMENTS(itemList); i++) {
|
||||
itemList[i].val.intval = 0;
|
||||
itemList[i].type = DBR_INT;
|
||||
}
|
||||
printf ("interger test\n");
|
||||
test (itemList, NELEMENTS(itemList));
|
||||
|
||||
for(i=0;i<NUM;i++)
|
||||
((float *)ptr)[i] = 0.0;
|
||||
test(ai_1, "DBR_FLOAT", DBR_FLOAT, NUM, ptr);
|
||||
printf ("free test\n");
|
||||
timeIt (test_free, itemList, NELEMENTS(itemList));
|
||||
|
||||
for(i=0;i<NUM;i++)
|
||||
strcpy((char *)ptr+(MAX_STRING_SIZE*i),"0.0");
|
||||
test(ai_1, "DBR_STRING", DBR_STRING, NUM, ptr);
|
||||
SEVCHK (ca_task_exit (), "Unable to free resources at exit");
|
||||
|
||||
for(i=0;i<NUM;i++)
|
||||
((int *)ptr)[i]=0;
|
||||
test(ai_1, "DBR_INT", DBR_INT, NUM, ptr);
|
||||
|
||||
free(ptr);
|
||||
|
||||
exit(OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
test(chix, name, type, count, ptr)
|
||||
chid chix;
|
||||
char *name;
|
||||
int type,count;
|
||||
void *ptr;
|
||||
|
||||
/*
|
||||
* test ()
|
||||
*/
|
||||
LOCAL void test (
|
||||
ti *pItems,
|
||||
unsigned iterations
|
||||
)
|
||||
{
|
||||
int test_put(), test_get(), test_wait();
|
||||
|
||||
printf("%s\n",name);
|
||||
timex(test_put,chix, name, type, count, ptr);
|
||||
timex(test_get,chix, name, type, count, ptr);
|
||||
timex(test_wait,chix, name, type, count, ptr);
|
||||
printf ("\tasync put test\n");
|
||||
timeIt (test_put, pItems, iterations);
|
||||
printf ("\tasync get test\n");
|
||||
timeIt (test_get, pItems, iterations);
|
||||
printf ("\tsynch get test\n");
|
||||
timeIt (test_wait, pItems, iterations);
|
||||
}
|
||||
|
||||
#ifndef vxWorks
|
||||
timex(pfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
void (*pfunc)();
|
||||
int arg1;
|
||||
int arg2;
|
||||
int arg3;
|
||||
int arg4;
|
||||
int arg5;
|
||||
int arg6;
|
||||
int arg7;
|
||||
|
||||
/*
|
||||
* timeIt ()
|
||||
*/
|
||||
void timeIt(
|
||||
tf *pfunc,
|
||||
ti *pItems,
|
||||
unsigned iterations
|
||||
)
|
||||
{
|
||||
(*pfunc)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
TS_STAMP end_time;
|
||||
TS_STAMP start_time;
|
||||
double delay;
|
||||
int status;
|
||||
unsigned inlineIter;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
test_search(name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i< NELEMENTS(chan_list);i++){
|
||||
SEVCHK(ca_search(name,&chan_list[i]),NULL);
|
||||
}
|
||||
SEVCHK(ca_pend_io(0.0),NULL);
|
||||
status = tsLocalTime(&start_time);
|
||||
assert (status == S_ts_OK);
|
||||
(*pfunc) (pItems, iterations, &inlineIter);
|
||||
status = tsLocalTime(&end_time);
|
||||
assert (status == S_ts_OK);
|
||||
TsDiffAsDouble(&delay,&end_time,&start_time);
|
||||
printf ("Elapsed Per Item = %f\n", delay/(iterations*inlineIter));
|
||||
}
|
||||
|
||||
test_free(chix)
|
||||
chid chix;
|
||||
|
||||
/*
|
||||
* test_search ()
|
||||
*/
|
||||
LOCAL void test_search(
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
int i;
|
||||
union db_access_val ival;
|
||||
ti *pi;
|
||||
int status;
|
||||
|
||||
for(i=0; i< NELEMENTS(chan_list);i++){
|
||||
SEVCHK(ca_clear_channel(chan_list[i]),NULL);
|
||||
}
|
||||
#ifdef WAIT_FOR_ACK
|
||||
SEVCHK(ca_array_get(DBR_INT,1,chix,&ival),NULL);
|
||||
SEVCHK(ca_pend_io(0.0),NULL);
|
||||
#else
|
||||
SEVCHK(ca_flush_io(),NULL);
|
||||
#endif
|
||||
for (pi=pItems; pi<&pItems[iterations]; pi++) {
|
||||
status = ca_search (
|
||||
pi->name,
|
||||
&pi->chix);
|
||||
SEVCHK (status, NULL);
|
||||
}
|
||||
status = ca_pend_io(0.0);
|
||||
SEVCHK (status, NULL);
|
||||
|
||||
*pInlineIter = 1;
|
||||
}
|
||||
|
||||
test_put(chix, name, type, count, ptr)
|
||||
chid chix;
|
||||
char *name;
|
||||
int type,count;
|
||||
void *ptr;
|
||||
|
||||
/*
|
||||
* test_free ()
|
||||
*/
|
||||
LOCAL void test_free(
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
int i;
|
||||
ti *pi;
|
||||
int status;
|
||||
|
||||
for (pi=pItems; pi<&pItems[iterations]; pi++) {
|
||||
status = ca_clear_channel (pi->chix);
|
||||
SEVCHK (status, NULL);
|
||||
}
|
||||
*pInlineIter = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* test_put ()
|
||||
*/
|
||||
LOCAL void test_put(
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
ti *pi;
|
||||
int status;
|
||||
dbr_int_t val;
|
||||
|
||||
for(i=0; i< ITERATION_COUNT;i++){
|
||||
SEVCHK(ca_array_put(type,count,chix,ptr),NULL);
|
||||
#if 0
|
||||
ca_flush_io();
|
||||
#endif
|
||||
}
|
||||
for (pi=pItems; pi<&pItems[iterations]; pi++) {
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_put(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
}
|
||||
#ifdef WAIT_FOR_ACK
|
||||
SEVCHK(ca_array_get(type,count,chix,ptr),NULL);
|
||||
SEVCHK(ca_pend_io(0.0),NULL);
|
||||
#else
|
||||
SEVCHK(ca_flush_io(),NULL);
|
||||
status = ca_array_get (DBR_INT, 1, pItems[0].chix, &val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_pend_io(100.0);
|
||||
#endif
|
||||
status = ca_array_put(
|
||||
pItems[0].type,
|
||||
pItems[0].count,
|
||||
pItems[0].chix,
|
||||
&pItems[0].val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_flush_io();
|
||||
SEVCHK (status, NULL);
|
||||
|
||||
*pInlineIter = 10;
|
||||
}
|
||||
|
||||
test_get(chix, name, type, count, ptr)
|
||||
chid chix;
|
||||
char *name;
|
||||
int type,count;
|
||||
void *ptr;
|
||||
|
||||
/*
|
||||
* test_get ()
|
||||
*/
|
||||
LOCAL void test_get(
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
int i;
|
||||
ti *pi;
|
||||
int status;
|
||||
|
||||
for (pi=pItems; pi<&pItems[iterations]; pi++) {
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
}
|
||||
status = ca_pend_io(100.0);
|
||||
SEVCHK (status, NULL);
|
||||
|
||||
for(i=0; i< ITERATION_COUNT;i++){
|
||||
SEVCHK(ca_array_get(type,count,chix,ptr),NULL);
|
||||
#if 0
|
||||
ca_flush_io();
|
||||
#endif
|
||||
}
|
||||
SEVCHK(ca_pend_io(0.0),NULL);
|
||||
*pInlineIter = 10;
|
||||
}
|
||||
|
||||
|
||||
test_wait(chix, name, type, count, ptr)
|
||||
chid chix;
|
||||
char *name;
|
||||
int type,count;
|
||||
void *ptr;
|
||||
|
||||
/*
|
||||
* test_wait ()
|
||||
*/
|
||||
LOCAL void test_wait (
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
int i;
|
||||
ti *pi;
|
||||
int status;
|
||||
|
||||
for (pi=pItems; pi<&pItems[iterations]; pi++) {
|
||||
status = ca_array_get(
|
||||
pi->type,
|
||||
pi->count,
|
||||
pi->chix,
|
||||
&pi->val);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_pend_io(100.0);
|
||||
SEVCHK (status, NULL);
|
||||
}
|
||||
|
||||
for(i=0; i< ITERATION_COUNT;i++){
|
||||
SEVCHK(ca_array_get(type,count,chix,ptr),NULL);
|
||||
SEVCHK(ca_pend_io(0.0),NULL);
|
||||
}
|
||||
*pInlineIter = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,11 +47,11 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGRETRYINTERVAL logRetryInterval(__FILE__, __LINE__);
|
||||
LOCAL void logRetryInterval(char *pFN, unsigned lineno);
|
||||
#else
|
||||
#define LOGRETRYINTERVAL
|
||||
#endif
|
||||
|
||||
LOCAL void logRetryInterval(char *pFN, unsigned lineno);
|
||||
LOCAL void retrySearchRequest(int silent);
|
||||
|
||||
|
||||
@@ -66,9 +66,8 @@ LOCAL void retrySearchRequest(int silent);
|
||||
void manage_conn(int silent)
|
||||
{
|
||||
IIU *piiu;
|
||||
ca_time current;
|
||||
ca_real delay;
|
||||
unsigned long idelay;
|
||||
long idelay;
|
||||
|
||||
/*
|
||||
* prevent recursion
|
||||
@@ -79,8 +78,6 @@ void manage_conn(int silent)
|
||||
|
||||
ca_static->ca_manage_conn_active = TRUE;
|
||||
|
||||
cac_gettimeval(¤t);
|
||||
|
||||
/*
|
||||
* issue connection heartbeat
|
||||
* (if we dont see a beacon)
|
||||
@@ -100,7 +97,7 @@ void manage_conn(int silent)
|
||||
*/
|
||||
if (piiu->sendPending) {
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&piiu->timeAtSendBlock);
|
||||
if (delay>ca_static->ca_connectTMO) {
|
||||
TAG_CONN_DOWN(piiu);
|
||||
@@ -117,15 +114,15 @@ void manage_conn(int silent)
|
||||
int rtmo;
|
||||
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&piiu->timeAtEchoRequest);
|
||||
stmo = delay > CA_RETRY_PERIOD;
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&piiu->timeAtLastRecv);
|
||||
rtmo = delay > CA_RETRY_PERIOD;
|
||||
if(stmo && rtmo && !piiu->sendPending){
|
||||
piiu->timeAtEchoRequest = current;
|
||||
piiu->timeAtEchoRequest = ca_static->currentTime;
|
||||
noop_msg(piiu);
|
||||
}
|
||||
continue;
|
||||
@@ -133,7 +130,7 @@ void manage_conn(int silent)
|
||||
|
||||
if(piiu->echoPending){
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&piiu->timeAtEchoRequest);
|
||||
if (delay > CA_ECHO_TIMEOUT) {
|
||||
/*
|
||||
@@ -144,10 +141,10 @@ void manage_conn(int silent)
|
||||
}
|
||||
else{
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&piiu->timeAtLastRecv);
|
||||
if (delay>ca_static->ca_connectTMO) {
|
||||
echo_request(piiu, ¤t);
|
||||
echo_request(piiu, &ca_static->currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,10 +156,10 @@ void manage_conn(int silent)
|
||||
*/
|
||||
if (!ca_static->ca_repeater_contacted) {
|
||||
delay = cac_time_diff (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&ca_static->ca_last_repeater_try);
|
||||
if (delay > REPEATER_TRY_PERIOD) {
|
||||
ca_static->ca_last_repeater_try = current;
|
||||
ca_static->ca_last_repeater_try = ca_static->currentTime;
|
||||
notify_ca_repeater();
|
||||
}
|
||||
}
|
||||
@@ -181,13 +178,13 @@ void manage_conn(int silent)
|
||||
|
||||
if(ca_static->ca_conn_next_retry.tv_sec == CA_CURRENT_TIME.tv_sec &&
|
||||
ca_static->ca_conn_next_retry.tv_usec == CA_CURRENT_TIME.tv_usec){
|
||||
ca_static->ca_conn_next_retry = current;
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
LOGRETRYINTERVAL
|
||||
}
|
||||
|
||||
delay = cac_time_diff (
|
||||
&ca_static->ca_conn_next_retry,
|
||||
¤t);
|
||||
&ca_static->currentTime);
|
||||
|
||||
if (delay > 0.0) {
|
||||
ca_static->ca_manage_conn_active = FALSE;
|
||||
@@ -214,13 +211,13 @@ void manage_conn(int silent)
|
||||
idelay = idelay << ca_static->ca_search_retry;
|
||||
delay = idelay * CA_RECAST_DELAY; /* sec */
|
||||
delay = min (CA_RECAST_PERIOD, delay);
|
||||
idelay = delay;
|
||||
idelay = (long) delay;
|
||||
ca_static->ca_conn_retry_delay.tv_sec = idelay;
|
||||
ca_static->ca_conn_retry_delay.tv_usec =
|
||||
(delay-idelay)*USEC_PER_SEC;
|
||||
(long) ((delay-idelay)*USEC_PER_SEC);
|
||||
ca_static->ca_conn_next_retry =
|
||||
cac_time_sum (
|
||||
¤t,
|
||||
&ca_static->currentTime,
|
||||
&ca_static->ca_conn_retry_delay);
|
||||
LOGRETRYINTERVAL
|
||||
|
||||
@@ -278,8 +275,10 @@ LOCAL void retrySearchRequest (int silent)
|
||||
if (chix==NULL) {
|
||||
/*
|
||||
* increment the retry sequence number
|
||||
* (only if we get no responses during a sequence)
|
||||
*/
|
||||
if (ca_static->ca_search_retry<MAXCONNTRIES) {
|
||||
if (ca_static->ca_search_retry<MAXCONNTRIES
|
||||
&& ca_static->ca_search_responses==0) {
|
||||
ca_static->ca_search_retry++;
|
||||
}
|
||||
|
||||
@@ -288,6 +287,7 @@ LOCAL void retrySearchRequest (int silent)
|
||||
*/
|
||||
if (ca_static->ca_search_retry<min_retry_num) {
|
||||
ca_static->ca_search_retry = min_retry_num;
|
||||
ca_static->ca_search_responses = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,18 +347,12 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* MARK_SERVER_AVAILABLE
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
void mark_server_available(struct in_addr *pnet_addr)
|
||||
{
|
||||
chid chan;
|
||||
ca_real currentPeriod;
|
||||
ca_time currentTime;
|
||||
bhe *pBHE;
|
||||
unsigned port;
|
||||
int netChange = FALSE;
|
||||
@@ -373,8 +367,6 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
return;
|
||||
}
|
||||
|
||||
cac_gettimeval(¤tTime);
|
||||
|
||||
LOCK;
|
||||
/*
|
||||
* look for it in the hash table
|
||||
@@ -391,14 +383,14 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
* update time stamp and average period
|
||||
*/
|
||||
currentPeriod = cac_time_diff (
|
||||
¤tTime,
|
||||
&ca_static->currentTime,
|
||||
&pBHE->timeStamp);
|
||||
/*
|
||||
* update the average
|
||||
*/
|
||||
pBHE->averagePeriod += currentPeriod;
|
||||
pBHE->averagePeriod /= 2.0;
|
||||
pBHE->timeStamp = currentTime;
|
||||
pBHE->timeStamp = ca_static->currentTime;
|
||||
|
||||
if ((currentPeriod/4.0)>=pBHE->averagePeriod) {
|
||||
#ifdef DEBUG
|
||||
@@ -422,7 +414,7 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
netChange = TRUE;
|
||||
}
|
||||
if(pBHE->piiu){
|
||||
pBHE->piiu->timeAtLastRecv = currentTime;
|
||||
pBHE->piiu->timeAtLastRecv = ca_static->currentTime;
|
||||
}
|
||||
if(!netChange){
|
||||
UNLOCK;
|
||||
@@ -465,17 +457,17 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
{
|
||||
ca_real diff;
|
||||
ca_real delay;
|
||||
unsigned idelay;
|
||||
long idelay;
|
||||
ca_time ca_delay;
|
||||
ca_time next;
|
||||
|
||||
delay = (port&CA_RECAST_PORT_MASK);
|
||||
delay /= MSEC_PER_SEC;
|
||||
delay += CA_RECAST_DELAY;
|
||||
idelay = delay;
|
||||
idelay = (long) delay;
|
||||
ca_delay.tv_sec = idelay;
|
||||
ca_delay.tv_usec = (delay-idelay) * USEC_PER_SEC;
|
||||
next = cac_time_sum(¤tTime, &ca_delay);
|
||||
ca_delay.tv_usec = (long) ((delay-idelay) * USEC_PER_SEC);
|
||||
next = cac_time_sum(&ca_static->currentTime, &ca_delay);
|
||||
|
||||
diff = cac_time_diff(
|
||||
&ca_static->ca_conn_next_retry,
|
||||
@@ -484,10 +476,10 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
ca_static->ca_conn_next_retry = next;
|
||||
LOGRETRYINTERVAL
|
||||
}
|
||||
idelay = CA_RECAST_DELAY;
|
||||
idelay = (long) CA_RECAST_DELAY;
|
||||
ca_static->ca_conn_retry_delay.tv_sec = idelay;
|
||||
ca_static->ca_conn_retry_delay.tv_usec =
|
||||
(CA_RECAST_DELAY-idelay) * USEC_PER_SEC;
|
||||
(long) ((CA_RECAST_DELAY-idelay) * USEC_PER_SEC);
|
||||
ca_static->ca_search_retry = 0;
|
||||
}
|
||||
|
||||
|
||||
343
src/ca/convert.c
343
src/ca/convert.c
@@ -35,11 +35,6 @@ static char *sccsId = "@(#) $Id$";
|
||||
#include "iocinf.h"
|
||||
#include "net_convert.h"
|
||||
|
||||
void htond(double *pHost, double *pNet);
|
||||
void ntohd(double *pNet, double *pHost);
|
||||
void htonf(float *pHost, float *pNet);
|
||||
void ntohf(float *pNet, float *pHost);
|
||||
|
||||
/*
|
||||
* if hton is true then it is a host to network conversion
|
||||
* otherwise vise-versa
|
||||
@@ -136,20 +131,11 @@ CACVRTFUNC *cac_dbr_cvrt[]
|
||||
cvrt_ctrl_double
|
||||
};
|
||||
|
||||
/*
|
||||
* Native types may not match EPICS types
|
||||
*/
|
||||
typedef short ca_short_tt;
|
||||
typedef float ca_float_tt;
|
||||
typedef short ca_enum_tt;
|
||||
typedef char ca_char_tt;
|
||||
typedef int ca_long_tt;
|
||||
typedef double ca_double_tt;
|
||||
|
||||
#define dbr_ntohs(A) ntohs(A)
|
||||
#define dbr_ntohl(A) ntohl(A)
|
||||
#define dbr_htons(A) htons(A)
|
||||
#define dbr_htonl(A) htonl(A)
|
||||
#define dbr_ntohs(A) (ntohs(A))
|
||||
#define dbr_ntohl(A) (ntohl(A))
|
||||
#define dbr_htons(A) (htons(A))
|
||||
#define dbr_htonl(A) (htonl(A))
|
||||
|
||||
|
||||
|
||||
@@ -167,8 +153,8 @@ int encode, /* cvrt HOST to NET if T */
|
||||
unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
ca_char_tt *pSrc = s;
|
||||
ca_char_tt *pDest = d;
|
||||
char *pSrc = s;
|
||||
char *pDest = d;
|
||||
|
||||
if(num == 1){
|
||||
strcpy(pDest, pSrc);
|
||||
@@ -193,8 +179,8 @@ int encode, /* cvrt HOST to NET if T */
|
||||
unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
ca_short_tt *pSrc = s;
|
||||
ca_short_tt *pDest = d;
|
||||
dbr_short_t *pSrc = s;
|
||||
dbr_short_t *pDest = d;
|
||||
unsigned long i;
|
||||
|
||||
for(i=0; i<num; i++){
|
||||
@@ -223,8 +209,8 @@ unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
unsigned long i;
|
||||
ca_char_tt *pSrc = s;
|
||||
ca_char_tt *pDest = d;
|
||||
dbr_char_t *pSrc = s;
|
||||
dbr_char_t *pDest = d;
|
||||
|
||||
for(i=0; i<num; i++){
|
||||
*pDest++ = *pSrc++;
|
||||
@@ -247,8 +233,8 @@ unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
unsigned long i;
|
||||
ca_long_tt *pSrc = s;
|
||||
ca_long_tt *pDest = d;
|
||||
dbr_long_t *pSrc = s;
|
||||
dbr_long_t *pDest = d;
|
||||
|
||||
for(i=0; i<num; i++){
|
||||
*pDest = dbr_ntohl( *pSrc );
|
||||
@@ -276,8 +262,8 @@ unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
unsigned long i;
|
||||
ca_enum_tt *pSrc;
|
||||
ca_enum_tt *pDest;
|
||||
dbr_enum_t *pSrc;
|
||||
dbr_enum_t *pDest;
|
||||
|
||||
pSrc = s;
|
||||
pDest = d;
|
||||
@@ -309,15 +295,15 @@ unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
unsigned long i;
|
||||
ca_float_tt *pSrc = s;
|
||||
ca_float_tt *pDest = d;
|
||||
dbr_float_t *pSrc = s;
|
||||
dbr_float_t *pDest = d;
|
||||
|
||||
for(i=0; i<num; i++){
|
||||
if(encode){
|
||||
htonf(pSrc, pDest);
|
||||
dbr_htonf(pSrc, pDest);
|
||||
}
|
||||
else{
|
||||
ntohf(pSrc, pDest);
|
||||
dbr_ntohf(pSrc, pDest);
|
||||
}
|
||||
/*
|
||||
* dont increment these inside the MACRO
|
||||
@@ -343,15 +329,15 @@ unsigned long num /* number of values */
|
||||
)
|
||||
{
|
||||
unsigned long i;
|
||||
ca_double_tt *pSrc = s;
|
||||
ca_double_tt *pDest = d;
|
||||
dbr_double_t *pSrc = s;
|
||||
dbr_double_t *pDest = d;
|
||||
|
||||
for(i=0; i<num; i++){
|
||||
if(encode){
|
||||
htond(pSrc,pDest);
|
||||
dbr_htond(pSrc,pDest);
|
||||
}
|
||||
else{
|
||||
ntohd(pSrc,pDest);
|
||||
dbr_ntohd(pSrc,pDest);
|
||||
}
|
||||
/*
|
||||
* dont increment these inside the MACRO
|
||||
@@ -702,32 +688,32 @@ unsigned long num /* number of values */
|
||||
if (encode) /* vax to ieee convert */
|
||||
{
|
||||
if (num == 1){
|
||||
htond(&pSrc->value, &pDest->value);
|
||||
dbr_htond(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_double(&pSrc->value, &pDest->value, encode,num);
|
||||
}
|
||||
htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
}
|
||||
else /* ieee to vax convert */
|
||||
{
|
||||
if (num == 1){
|
||||
ntohd(&pSrc->value, &pDest->value);
|
||||
dbr_ntohd(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_double(&pSrc->value, &pDest->value, encode,num);
|
||||
}
|
||||
ntohd(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_ntohd(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,32 +751,32 @@ unsigned long num /* number of values */
|
||||
if (encode) /* vax to ieee convert */
|
||||
{
|
||||
if (num == 1){
|
||||
htonf(&pSrc->value, &pDest->value);
|
||||
dbr_htonf(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_float(&pSrc->value, &pDest->value, encode,num);
|
||||
}
|
||||
htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
}
|
||||
else /* ieee to vax convert */
|
||||
{
|
||||
if (num == 1){
|
||||
ntohf(&pSrc->value, &pDest->value);
|
||||
dbr_ntohf(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_float(&pSrc->value, &pDest->value, encode,num);
|
||||
}
|
||||
ntohf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_ntohf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,7 +925,7 @@ unsigned long num /* number of values */
|
||||
struct dbr_ctrl_double *pSrc = s;
|
||||
struct dbr_ctrl_double *pDest = d;
|
||||
|
||||
/* these are the same for ieee to vaax or vax to ieee */
|
||||
/* these are the same for ieee to vax or vax to ieee */
|
||||
pDest->status = dbr_ntohs(pSrc->status);
|
||||
pDest->severity = dbr_ntohs(pSrc->severity);
|
||||
pDest->precision = dbr_ntohs(pSrc->precision);
|
||||
@@ -947,35 +933,36 @@ unsigned long num /* number of values */
|
||||
if (encode) /* vax to ieee convert */
|
||||
{
|
||||
if (num == 1){
|
||||
htond(&pSrc->value, &pDest->value);
|
||||
dbr_htond(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_double(&pSrc->value, &pDest->value, encode, num);
|
||||
}
|
||||
htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
htond(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
htond(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
dbr_htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_htond(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
dbr_htond(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
}
|
||||
else /* ieee to vax convert */
|
||||
{
|
||||
if (num == 1){
|
||||
ntohd(&pSrc->value, &pDest->value);
|
||||
dbr_ntohd(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_double(&pSrc->value, &pDest->value, encode, num);
|
||||
}
|
||||
ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
ntohd(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
ntohd(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
dbr_ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_ntohd(&pSrc->upper_disp_limit, &pDest->upper_disp_limit);
|
||||
dbr_ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_ntohd(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
dbr_ntohd(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1011,35 +998,36 @@ unsigned long num /* number of values */
|
||||
if (encode) /* vax to ieee convert */
|
||||
{
|
||||
if (num == 1){
|
||||
htonf(&pSrc->value, &pDest->value);
|
||||
dbr_htonf(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_float(&pSrc->value, &pDest->value, encode, num);
|
||||
}
|
||||
htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
htonf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
htonf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
dbr_htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit);
|
||||
dbr_htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_htonf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
dbr_htonf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
}
|
||||
else /* ieee to vax convert */
|
||||
{
|
||||
if (num == 1){
|
||||
ntohf(&pSrc->value, &pDest->value);
|
||||
dbr_ntohf(&pSrc->value, &pDest->value);
|
||||
}
|
||||
else {
|
||||
cvrt_float(&pSrc->value, &pDest->value, encode, num);
|
||||
}
|
||||
ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
ntohf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
ntohf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
dbr_ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit);
|
||||
dbr_ntohf(&pSrc->upper_disp_limit, &pDest->upper_disp_limit);
|
||||
dbr_ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit);
|
||||
dbr_ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit);
|
||||
dbr_ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit);
|
||||
dbr_ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit);
|
||||
dbr_ntohf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit);
|
||||
dbr_ntohf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1374,7 +1362,7 @@ unsigned long num /* number of values */
|
||||
}
|
||||
|
||||
|
||||
#ifdef CA_FLOAT_MIT
|
||||
#if defined(CA_FLOAT_MIT)
|
||||
/************************************************************************/
|
||||
/* double convert */
|
||||
/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */
|
||||
@@ -1383,7 +1371,7 @@ unsigned long num /* number of values */
|
||||
/* (this includes mapping of fringe reals to zero or infinity) */
|
||||
/* (byte swaps included in conversion */
|
||||
|
||||
struct ieeedbl{
|
||||
struct ieeedbl {
|
||||
unsigned int mant2 : 32;
|
||||
unsigned int mant1 : 20;
|
||||
unsigned int exp : 11;
|
||||
@@ -1396,7 +1384,7 @@ struct ieeedbl{
|
||||
/* -1022<exp<1024 with mantissa of form 1.mant */
|
||||
#define DBLEXPMINIEEE -1022 /* min for norm # IEEE exponent */
|
||||
|
||||
struct mitdbl{
|
||||
struct mitdbl {
|
||||
unsigned int mant1 : 7;
|
||||
unsigned int exp : 8;
|
||||
unsigned int sign : 1;
|
||||
@@ -1413,18 +1401,25 @@ struct mitdbl{
|
||||
#define DBLEXPMAXMIT 126 /* max MIT exponent */
|
||||
#define DBLEXPMINMIT -128 /* min MIT exponent */
|
||||
|
||||
|
||||
void htond(double *pHost, double *pNet)
|
||||
/*
|
||||
* Converts VAX D floating point to IEEE double precision
|
||||
* (D floating is the VAX C default)
|
||||
*/
|
||||
void dbr_htond(dbr_double_t *pHost, dbr_double_t *pNet)
|
||||
{
|
||||
double copyin;
|
||||
dbr_double_t copyin;
|
||||
struct mitdbl *pMIT;
|
||||
struct ieeedbl *pIEEE;
|
||||
ca_uint32_t *ptmp;
|
||||
ca_uint32_t tmp;
|
||||
|
||||
/*
|
||||
* Use internal buffer so the src and dest ptr
|
||||
* can be identical
|
||||
*/
|
||||
copyin = *pHost;
|
||||
pMIT = (struct mitdbl *)©in;
|
||||
pIEEE = (struct ieeedbl *)pNet;
|
||||
pMIT = (struct mitdbl *) ©in;
|
||||
pIEEE = (struct ieeedbl *) pNet;
|
||||
|
||||
if( ((int)pMIT->exp) < (DBLEXPMINMIT+MIT_DBL_SB) ){
|
||||
pIEEE->mant1 = 0;
|
||||
@@ -1444,34 +1439,43 @@ void htond(double *pHost, double *pNet)
|
||||
* byte swap to net order
|
||||
*/
|
||||
ptmp = (ca_uint32_t *) pNet;
|
||||
tmp = htonl(ptmp[0]);
|
||||
ptmp[0] = htonl(ptmp[1]);
|
||||
tmp = dbr_htonl(ptmp[0]);
|
||||
ptmp[0] = dbr_htonl(ptmp[1]);
|
||||
ptmp[1] = tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Converts IEEE double precision to VAX D floating point
|
||||
* (D floating is the VAX default)
|
||||
*
|
||||
* sign must be forced to zero if the exponent is zero to prevent a reserved
|
||||
* operand fault- joh 9-13-90
|
||||
*/
|
||||
void ntohd(double *pNet, double *pHost)
|
||||
void dbr_ntohd(dbr_double_t *pNet, dbr_double_t *pHost)
|
||||
{
|
||||
double copyin;
|
||||
struct ieeedbl copyin;
|
||||
struct mitdbl *pMIT;
|
||||
struct ieeedbl *pIEEE;
|
||||
ca_uint32_t *ptmp;
|
||||
ca_uint32_t tmp;
|
||||
|
||||
copyin = *pNet;
|
||||
pIEEE = (struct ieeedbl *)pNet;
|
||||
pMIT = (struct mitdbl *)pHost;
|
||||
pIEEE = (struct ieeedbl *)©in;
|
||||
|
||||
/*
|
||||
* Use internal buffer so the src and dest ptr
|
||||
* can be identical
|
||||
*/
|
||||
copyin = *pIEEE;
|
||||
pIEEE = ©in;
|
||||
|
||||
/*
|
||||
* Byte swap from net order to host order
|
||||
*/
|
||||
ptmp = (ca_uint32_t *) pIEEE;
|
||||
tmp = htonl(ptmp[0]);
|
||||
ptmp[0] = htonl(ptmp[1]);
|
||||
tmp = dbr_htonl(ptmp[0]);
|
||||
ptmp[0] = dbr_htonl(ptmp[1]);
|
||||
ptmp[1] = tmp;
|
||||
|
||||
if( ((int)pIEEE->exp) > (DBLEXPMAXMIT + IEEE_DBL_SB) ){
|
||||
@@ -1533,45 +1537,52 @@ struct mitflt{
|
||||
# define EXPMAXMIT 126 /* max MIT exponent */
|
||||
# define EXPMINMIT -128 /* min MIT exponent */
|
||||
|
||||
/* (this includes mapping of fringe reals to zero or infinity) */
|
||||
/* (byte swaps included in conversion */
|
||||
|
||||
void htonf(float *pHost, float *pNet)
|
||||
/*
|
||||
* (this includes mapping of fringe reals to zero or infinity)
|
||||
* (byte swaps included in conversion
|
||||
*
|
||||
* Uses internal buffer so the src and dest ptr
|
||||
* can be identical
|
||||
*/
|
||||
void dbr_htonf(dbr_float_t *pHost, dbr_float_t *pNet)
|
||||
{
|
||||
struct mitflt *pMIT = pHost;
|
||||
struct ieeeflt *pIEEE = pNet;
|
||||
struct mitflt *pMIT = (struct mitflt *) pHost;
|
||||
struct ieeeflt *pIEEE = (struct ieeeflt *) pNet;
|
||||
long exp,mant,sign;
|
||||
|
||||
sign = pHost->sign;
|
||||
sign = pMIT->sign;
|
||||
|
||||
if( (short)(pMIT->exp < EXPMINIEEE + MIT_SB){
|
||||
if( ((int)pMIT->exp) < EXPMINIEEE + MIT_SB){
|
||||
exp = 0;
|
||||
mant = 0;
|
||||
sign = 0;
|
||||
}
|
||||
else{
|
||||
exp = (short)pMIT->exp-MIT_SB+IEEE_SB;
|
||||
exp = ((int)pMIT->exp)-MIT_SB+IEEE_SB;
|
||||
mant = (pMIT->mant1<<16) | pMIT->mant2;
|
||||
}
|
||||
pIEEE->mant = mant;
|
||||
pIEEE->exp = exp;
|
||||
pIEEE->sign = sign;
|
||||
*(ca_uint32_t *)pIEEE = ntohl(*(ca_uint32_t *)pIEEE);
|
||||
*(ca_uint32_t *)pIEEE = dbr_htonl(*(ca_uint32_t *)pIEEE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sign must be forced to zero if the exponent is zero to prevent a reserved
|
||||
* operand fault- joh 9-13-90
|
||||
*
|
||||
* Uses internal buffer so the src and dest ptr
|
||||
* can be identical
|
||||
*/
|
||||
void ntohf(float *pNet, float *pHost)
|
||||
void dbr_ntohf(dbr_float_t *pNet, dbr_float_t *pHost)
|
||||
{
|
||||
struct mitflt *pMIT = pHost;
|
||||
struct ieeeflt *pIEEE = pNet;
|
||||
struct mitflt *pMIT = (struct mitflt *) pHost;
|
||||
struct ieeeflt *pIEEE = (struct ieeeflt *) pNet;
|
||||
long exp,mant2,mant1,sign;
|
||||
|
||||
*(ca_uint32_t *)pIEEE = htonl(*(ca_uint32_t *)pIEEE);
|
||||
if( (short) pIEEE->exp > EXPMAXMIT + IEEE_SB){
|
||||
*(ca_uint32_t *)pIEEE = dbr_ntohl(*(ca_uint32_t *)pIEEE);
|
||||
if( ((int)pIEEE->exp) > EXPMAXMIT + IEEE_SB){
|
||||
sign = pIEEE->sign;
|
||||
exp = EXPMAXMIT + MIT_SB;
|
||||
mant2 = ~0;
|
||||
@@ -1598,29 +1609,81 @@ void ntohf(float *pNet, float *pHost)
|
||||
|
||||
#endif /*CA_FLOAT_MIT*/
|
||||
|
||||
#ifndef CA_FLOAT_MIT
|
||||
#if defined(CA_FLOAT_IEEE) && 0
|
||||
|
||||
void htond(double *IEEEhost, double *IEEEnet)
|
||||
/*
|
||||
* dbr_htond ()
|
||||
* performs only byte swapping
|
||||
*/
|
||||
void dbr_htond (dbr_double_t *IEEEhost, dbr_double_t *IEEEnet)
|
||||
{
|
||||
*IEEEnet = *IEEEhost;
|
||||
#ifdef CA_LITTLE_ENDIAN
|
||||
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
|
||||
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
|
||||
ca_uint32_t tmp;
|
||||
|
||||
/*
|
||||
* byte swap to net order
|
||||
* (assume that src and dest ptrs
|
||||
* may be identical)
|
||||
*/
|
||||
tmp = pHost[0];
|
||||
pNet[0] = dbr_htonl (pHost[1]);
|
||||
pNet[1] = dbr_htonl (tmp);
|
||||
#else
|
||||
*IEEEnet = *IEEEhost;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ntohd(double *IEEEnet, double *IEEEhost)
|
||||
/*
|
||||
* dbr_ntohd ()
|
||||
* performs only byte swapping
|
||||
*/
|
||||
void dbr_ntohd (dbr_double_t *IEEEnet, dbr_double_t *IEEEhost)
|
||||
{
|
||||
*IEEEhost = *IEEEnet;
|
||||
#ifdef CA_LITTLE_ENDIAN
|
||||
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
|
||||
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
|
||||
ca_uint32_t tmp;
|
||||
|
||||
/*
|
||||
* byte swap to net order
|
||||
* (assume that src and dest ptrs
|
||||
* may be identical)
|
||||
*/
|
||||
tmp = pNet[0];
|
||||
pHost[0] = dbr_ntohl (pNet[1]);
|
||||
pHost[1] = dbr_htonl (tmp);
|
||||
#else
|
||||
*IEEEhost = *IEEEnet;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ntohf(float *IEEEnet, float *IEEEhost)
|
||||
/*
|
||||
* dbr_ntohf ()
|
||||
* performs only byte swapping
|
||||
*/
|
||||
void dbr_ntohf (dbr_float_t *IEEEnet, dbr_float_t *IEEEhost)
|
||||
{
|
||||
*IEEEhost = *IEEEnet;
|
||||
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
|
||||
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
|
||||
|
||||
*pHost = dbr_ntohl (*pNet);
|
||||
}
|
||||
|
||||
void htonf(float *IEEEhost, float *IEEEnet)
|
||||
/*
|
||||
* dbr_htonf ()
|
||||
* performs only byte swapping
|
||||
*/
|
||||
void dbr_htonf (dbr_float_t *IEEEhost, dbr_float_t *IEEEnet)
|
||||
{
|
||||
*IEEEnet = *IEEEhost;
|
||||
ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost;
|
||||
ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet;
|
||||
|
||||
*pNet = dbr_htonl (*pHost);
|
||||
}
|
||||
|
||||
#endif /* not CA_MIT_FLOAT*/
|
||||
#endif /* IEEE float and little endian */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ static char *sccsId = "@(#) $Id$";
|
||||
void flow_control(struct ioc_in_use *piiu)
|
||||
{
|
||||
unsigned nbytes;
|
||||
register int status;
|
||||
register int busy = piiu->client_busy;
|
||||
int status;
|
||||
int busy = piiu->client_busy;
|
||||
|
||||
LOCK;
|
||||
|
||||
@@ -95,6 +95,5 @@ void flow_control(struct ioc_in_use *piiu)
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ static char *sccsId = "@(#) $Id$";
|
||||
*
|
||||
* Perhaps it is sufficient for this to return 127.0.0.1
|
||||
* (the loop back address)
|
||||
* See Below
|
||||
*/
|
||||
int local_addr(int s, struct sockaddr_in *plcladdr)
|
||||
{
|
||||
@@ -78,7 +79,9 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
|
||||
ifconf.ifc_req = ifreq;
|
||||
status = socket_ioctl(s, SIOCGIFCONF, &ifconf);
|
||||
if (status < 0 || ifconf.ifc_len == 0) {
|
||||
ca_printf("CAC: ioctl failed %s\n", strerror(MYERRNO));
|
||||
ca_printf(
|
||||
"CAC: ioctl failed because \"%s\"\n",
|
||||
strerror(MYERRNO));
|
||||
ifconf.ifc_len = 0;
|
||||
}
|
||||
|
||||
@@ -141,16 +144,46 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* An alternate solution
|
||||
* for os without the if routines
|
||||
*/
|
||||
/*
|
||||
* local_addr()
|
||||
*
|
||||
* return 127.0.0.1
|
||||
* (the loop back address)
|
||||
*/
|
||||
int local_addr (int s, struct sockaddr_in *plcladdr)
|
||||
{
|
||||
ca_uint32_t loopBackAddress = 0x7f000001;
|
||||
|
||||
plcladdr->sa_family = AF_INET;
|
||||
plcladdr->sin_port = 0;
|
||||
plcladdr->sin_addr.s_addr = ntohl (loopBackAddress);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* caDiscoverInterfaces()
|
||||
* caDiscoverInterfaces()
|
||||
*
|
||||
* Load the list with the broadcast address for all
|
||||
* interfaces found that support broadcast.
|
||||
* This routine is provided with the address of an ELLLIST a socket
|
||||
* and a destination port number. When the routine returns there
|
||||
* will be one additional inet address (a caAddrNode) in the list
|
||||
* for each inet interface found that is up and isnt a loop back
|
||||
* interface. If the interface supports broadcast then I add its
|
||||
* broadcast address to the list. If the interface is a point to
|
||||
* point link then I add the destination address of the point to
|
||||
* point link to the list. In either case I set the port number
|
||||
* in the address node to the port supplied in the argument
|
||||
* list.
|
||||
*
|
||||
* LOCK should be applied here for (pList)
|
||||
* (this is also called from the server)
|
||||
* LOCK should be applied here for (pList)
|
||||
* (this is also called from the server)
|
||||
*/
|
||||
void caDiscoverInterfaces(ELLLIST *pList, int socket, int port)
|
||||
{
|
||||
|
||||
400
src/ca/iocinf.c
400
src/ca/iocinf.c
@@ -73,7 +73,6 @@ static char *sccsId = "@(#) $Id$";
|
||||
#define CA_GLBLSOURCE
|
||||
#include "iocinf.h"
|
||||
#include "net_convert.h"
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
LOCAL void tcp_recv_msg(struct ioc_in_use *piiu);
|
||||
LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu);
|
||||
@@ -188,6 +187,7 @@ int net_proto
|
||||
UNLOCK;
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
|
||||
pNode->destAddr.inetAddr.sin_family = AF_INET;
|
||||
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
|
||||
pNode->destAddr.inetAddr.sin_port =
|
||||
@@ -219,7 +219,7 @@ int net_proto
|
||||
IPPROTO_TCP,
|
||||
TCP_NODELAY,
|
||||
(char *)&true,
|
||||
sizeof true);
|
||||
sizeof(true));
|
||||
if(status < 0){
|
||||
free(piiu);
|
||||
status = socket_close(sock);
|
||||
@@ -270,57 +270,53 @@ int net_proto
|
||||
#endif
|
||||
|
||||
#ifdef CA_SET_TCP_BUFFER_SIZES
|
||||
/* set TCP buffer sizes */
|
||||
i = MAX_MSG_SIZE;
|
||||
status = setsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
&i,
|
||||
sizeof(i));
|
||||
if(status < 0){
|
||||
free(piiu);
|
||||
status = socket_close(sock);
|
||||
if(status<0){
|
||||
SEVCHK(ECA_INTERNAL,NULL);
|
||||
}
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
i = MAX_MSG_SIZE;
|
||||
status = setsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_RCVBUF,
|
||||
&i,
|
||||
sizeof(i));
|
||||
if(status < 0){
|
||||
free(piiu);
|
||||
status = socket_close(sock);
|
||||
if(status<0){
|
||||
SEVCHK(ECA_INTERNAL,NULL);
|
||||
}
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
|
||||
/* fetch the TCP send buffer size */
|
||||
i = sizeof(piiu->tcp_send_buff_size);
|
||||
status = getsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
(char *)&piiu->tcp_send_buff_size,
|
||||
&i);
|
||||
if(status < 0 || i != sizeof(piiu->tcp_send_buff_size)){
|
||||
free(piiu);
|
||||
status = socket_close(sock);
|
||||
if(status<0){
|
||||
SEVCHK(ECA_INTERNAL,NULL);
|
||||
/* set TCP buffer sizes */
|
||||
i = MAX_MSG_SIZE;
|
||||
status = setsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
&i,
|
||||
sizeof(i));
|
||||
if(status < 0){
|
||||
free(piiu);
|
||||
socket_close(sock);
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
i = MAX_MSG_SIZE;
|
||||
status = setsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_RCVBUF,
|
||||
&i,
|
||||
sizeof(i));
|
||||
if(status < 0){
|
||||
free(piiu);
|
||||
socket_close(sock);
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
|
||||
/* fetch the TCP send buffer size */
|
||||
i = sizeof(size);
|
||||
status = getsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
(char *)&size,
|
||||
&i);
|
||||
if(status < 0 || i != sizeof(size)){
|
||||
free(piiu);
|
||||
socket_close(sock);
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* connect */
|
||||
@@ -342,20 +338,6 @@ int net_proto
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->send.buf));
|
||||
cacRingBufferInit(&piiu->send, sizeof(piiu->send.buf));
|
||||
|
||||
/*
|
||||
* Set non blocking IO
|
||||
* to prevent dead locks
|
||||
*/
|
||||
status = socket_ioctl(
|
||||
piiu->sock_chan,
|
||||
FIONBIO,
|
||||
&true);
|
||||
if(status<0){
|
||||
ca_printf(
|
||||
"Error setting non-blocking io: %s\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the Host name for efficient access in the
|
||||
* future.
|
||||
@@ -435,6 +417,7 @@ int net_proto
|
||||
sock,
|
||||
ca_static->ca_server_port);
|
||||
|
||||
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->send.buf));
|
||||
cacRingBufferInit(&piiu->send, min(MAX_UDP,
|
||||
sizeof(piiu->send.buf)));
|
||||
@@ -443,7 +426,6 @@ int net_proto
|
||||
piiu->host_name_str,
|
||||
"<<unknown host>>",
|
||||
sizeof(piiu->host_name_str)-1);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -456,6 +438,20 @@ int net_proto
|
||||
return ECA_INTERNAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set non blocking IO
|
||||
* to prevent dead locks
|
||||
*/
|
||||
status = socket_ioctl(
|
||||
piiu->sock_chan,
|
||||
FIONBIO,
|
||||
&true);
|
||||
if(status<0){
|
||||
ca_printf(
|
||||
"Error setting non-blocking io: %s\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
|
||||
if(fd_register_func){
|
||||
LOCKEVENTS;
|
||||
(*fd_register_func)(fd_register_arg, sock, TRUE);
|
||||
@@ -571,21 +567,34 @@ void notify_ca_repeater()
|
||||
LOCK; /*MULTINET TCP/IP routines are not reentrant*/
|
||||
status = local_addr(piiuCast->sock_chan, &saddr);
|
||||
if (status == OK) {
|
||||
int len;
|
||||
|
||||
memset((char *)&msg, 0, sizeof(msg));
|
||||
msg.m_cmmd = htons(REPEATER_REGISTER);
|
||||
msg.m_available = saddr.sin_addr.s_addr;
|
||||
saddr.sin_port = htons(ca_static->ca_repeater_port);
|
||||
|
||||
/*
|
||||
* Intentionally sending a zero length message here
|
||||
* until most CA repeater daemons have been restarted
|
||||
* (and only then will accept the above protocol)
|
||||
* (repeaters began accepting this protocol
|
||||
* starting with EPICS 3.12)
|
||||
*
|
||||
* SOLARIS will not accept a zero length message
|
||||
* and we are just porting there for 3.12 so
|
||||
* we will use the new protocol for 3.12
|
||||
*/
|
||||
# ifdef SOLARIS
|
||||
len = sizeof(msg);
|
||||
# else /* SOLARIS */
|
||||
len = 0;
|
||||
# endif /* SOLARIS */
|
||||
|
||||
status = sendto(
|
||||
piiuCast->sock_chan,
|
||||
(char *)&msg, /* UCX requires a valid address here */
|
||||
0, /* <= sizeof(msg) ! see comment above ! */
|
||||
len,
|
||||
0,
|
||||
(struct sockaddr *)&saddr,
|
||||
sizeof(saddr));
|
||||
@@ -641,6 +650,8 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
while(pNode){
|
||||
unsigned long actualSendCnt;
|
||||
|
||||
status = sendto(
|
||||
piiu->sock_chan,
|
||||
&piiu->send.buf[piiu->send.rdix],
|
||||
@@ -649,18 +660,27 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
&pNode->destAddr.sockAddr,
|
||||
sizeof(pNode->destAddr.sockAddr));
|
||||
if(status<0){
|
||||
if( MYERRNO != EWOULDBLOCK &&
|
||||
MYERRNO != ENOBUFS &&
|
||||
MYERRNO != EINTR){
|
||||
int localErrno;
|
||||
|
||||
localErrno = MYERRNO;
|
||||
|
||||
if( localErrno == EWOULDBLOCK &&
|
||||
localErrno == ENOBUFS &&
|
||||
localErrno == EINTR){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ca_printf(
|
||||
"CAC: error on socket send() %s\n",
|
||||
strerror(MYERRNO));
|
||||
strerror(localErrno));
|
||||
}
|
||||
|
||||
TAG_CONN_DOWN(piiu);
|
||||
break;
|
||||
}
|
||||
assert(status == sendCnt);
|
||||
actualSendCnt = (unsigned long) status;
|
||||
assert (actualSendCnt == sendCnt);
|
||||
pNode = (caAddrNode *) pNode->node.next;
|
||||
}
|
||||
|
||||
@@ -687,6 +707,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
{
|
||||
unsigned long sendCnt;
|
||||
int status;
|
||||
int localError;
|
||||
|
||||
/*
|
||||
* check for shutdown in progress
|
||||
@@ -697,55 +718,64 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
|
||||
LOCK;
|
||||
|
||||
sendCnt = cacRingBufferReadSize(&piiu->send, TRUE);
|
||||
|
||||
assert(sendCnt<=piiu->send.max_msg);
|
||||
|
||||
/*
|
||||
* return if nothing to send
|
||||
* Check at least twice to see if there is anything
|
||||
* in the ring buffer (in case the block of messages
|
||||
* isnt continuous). Always return if the send was
|
||||
* less bytes than requested.
|
||||
*/
|
||||
if(sendCnt == 0){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
while (TRUE) {
|
||||
sendCnt = cacRingBufferReadSize(&piiu->send, TRUE);
|
||||
assert(sendCnt<=piiu->send.max_msg);
|
||||
|
||||
status = send(
|
||||
piiu->sock_chan,
|
||||
&piiu->send.buf[piiu->send.rdix],
|
||||
sendCnt,
|
||||
0);
|
||||
if(status>=0){
|
||||
assert(status<=sendCnt);
|
||||
|
||||
piiu->sendPending = FALSE;
|
||||
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
|
||||
|
||||
sendCnt = cacRingBufferReadSize(&piiu->send, FALSE);
|
||||
if(sendCnt==0){
|
||||
/*
|
||||
* return if nothing to send
|
||||
*/
|
||||
if(sendCnt == 0){
|
||||
piiu->sendPending = FALSE;
|
||||
piiu->send_needed = FALSE;
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
return;
|
||||
status = send(
|
||||
piiu->sock_chan,
|
||||
&piiu->send.buf[piiu->send.rdix],
|
||||
sendCnt,
|
||||
0);
|
||||
if (status<0) {
|
||||
break;
|
||||
}
|
||||
else if (status==0) {
|
||||
TAG_CONN_DOWN(piiu);
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
|
||||
|
||||
if (status != sendCnt) {
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( MYERRNO == EWOULDBLOCK ||
|
||||
MYERRNO == ENOBUFS ||
|
||||
MYERRNO == EINTR){
|
||||
localError = MYERRNO;
|
||||
|
||||
if( localError == EWOULDBLOCK ||
|
||||
localError == ENOBUFS ||
|
||||
localError == EINTR){
|
||||
UNLOCK;
|
||||
if(!piiu->sendPending){
|
||||
cac_gettimeval(&piiu->timeAtSendBlock);
|
||||
piiu->sendPending = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( MYERRNO != EPIPE &&
|
||||
MYERRNO != ECONNRESET &&
|
||||
MYERRNO != ETIMEDOUT){
|
||||
if( localError != EPIPE &&
|
||||
localError != ECONNRESET &&
|
||||
localError != ETIMEDOUT){
|
||||
ca_printf(
|
||||
"CAC: error on socket send() %s\n",
|
||||
strerror(MYERRNO));
|
||||
strerror(localError));
|
||||
}
|
||||
|
||||
TAG_CONN_DOWN(piiu);
|
||||
@@ -781,7 +811,6 @@ void cac_flush_internal()
|
||||
UNLOCK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* cac_clean_iiu_list()
|
||||
@@ -816,14 +845,16 @@ void ca_process_input_queue()
|
||||
{
|
||||
struct ioc_in_use *piiu;
|
||||
|
||||
LOCK;
|
||||
|
||||
/*
|
||||
* dont allow recursion
|
||||
* dont allow recursion
|
||||
*/
|
||||
if(post_msg_active){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK;
|
||||
for( piiu=(IIU *)iiuList.node.next;
|
||||
piiu;
|
||||
piiu=(IIU *)piiu->node.next){
|
||||
@@ -834,6 +865,7 @@ void ca_process_input_queue()
|
||||
|
||||
(*piiu->procInput)(piiu);
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
|
||||
cac_flush_internal();
|
||||
@@ -856,56 +888,59 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
|
||||
|
||||
LOCK;
|
||||
|
||||
writeSpace = cacRingBufferWriteSize(&piiu->recv, TRUE);
|
||||
if(writeSpace == 0){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Check at least twice to see if there is ana space left
|
||||
* in the ring buffer (in case the messages block
|
||||
* isnt continuous). Always return if the send was
|
||||
* less bytes than requested.
|
||||
*/
|
||||
while (TRUE) {
|
||||
|
||||
status = recv( piiu->sock_chan,
|
||||
&piiu->recv.buf[piiu->recv.wtix],
|
||||
writeSpace,
|
||||
0);
|
||||
if(status == 0){
|
||||
TAG_CONN_DOWN(piiu);
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
else if(status <0){
|
||||
/* try again on status of -1 and no luck this time */
|
||||
if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR){
|
||||
UNLOCK;
|
||||
return;
|
||||
writeSpace = cacRingBufferWriteSize(&piiu->recv, TRUE);
|
||||
if(writeSpace == 0){
|
||||
break;
|
||||
}
|
||||
|
||||
if( MYERRNO != EPIPE &&
|
||||
MYERRNO != ECONNRESET &&
|
||||
MYERRNO != ETIMEDOUT){
|
||||
ca_printf(
|
||||
"CAC: unexpected recv error (err=%s)\n",
|
||||
strerror(MYERRNO));
|
||||
status = recv( piiu->sock_chan,
|
||||
&piiu->recv.buf[piiu->recv.wtix],
|
||||
writeSpace,
|
||||
0);
|
||||
if(status == 0){
|
||||
TAG_CONN_DOWN(piiu);
|
||||
break;
|
||||
}
|
||||
TAG_CONN_DOWN(piiu);
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
else if(status <0){
|
||||
/* try again on status of -1 and no luck this time */
|
||||
if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR){
|
||||
break;
|
||||
}
|
||||
|
||||
if( MYERRNO != EPIPE &&
|
||||
MYERRNO != ECONNRESET &&
|
||||
MYERRNO != ETIMEDOUT){
|
||||
ca_printf(
|
||||
"CAC: unexpected recv error (err=%s)\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
TAG_CONN_DOWN(piiu);
|
||||
break;
|
||||
}
|
||||
|
||||
if(status>MAX_MSG_SIZE){
|
||||
ca_printf( "CAC: recv_msg(): message overflow %l\n",
|
||||
status-MAX_MSG_SIZE);
|
||||
TAG_CONN_DOWN(piiu);
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
assert (status<=writeSpace);
|
||||
|
||||
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, status);
|
||||
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, status);
|
||||
|
||||
/*
|
||||
* Record the time whenever we receive a message
|
||||
* from this IOC
|
||||
*/
|
||||
piiu->timeAtLastRecv = ca_static->currentTime;
|
||||
|
||||
if (status != writeSpace) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Record the time whenever we receive a message
|
||||
* from this IOC
|
||||
*/
|
||||
cac_gettimeval(&piiu->timeAtLastRecv);
|
||||
|
||||
UNLOCK;
|
||||
return;
|
||||
@@ -922,18 +957,20 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
|
||||
int status;
|
||||
long bytesToProcess;
|
||||
|
||||
LOCK;
|
||||
|
||||
/*
|
||||
* dont allow recursion
|
||||
*/
|
||||
if(post_msg_active){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
|
||||
post_msg_active = TRUE;
|
||||
|
||||
LOCK;
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
|
||||
while(TRUE){
|
||||
bytesToProcess = cacRingBufferReadSize(&piiu->recv, TRUE);
|
||||
if(bytesToProcess == 0){
|
||||
@@ -956,9 +993,9 @@ LOCAL void ca_process_tcp(struct ioc_in_use *piiu)
|
||||
&piiu->recv,
|
||||
bytesToProcess);
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
post_msg_active = FALSE;
|
||||
UNLOCK;
|
||||
|
||||
flow_control(piiu);
|
||||
|
||||
@@ -1059,17 +1096,18 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
|
||||
char *pBuf;
|
||||
unsigned long bytesAvailable;
|
||||
|
||||
LOCK;
|
||||
|
||||
/*
|
||||
* dont allow recursion
|
||||
*/
|
||||
if(post_msg_active){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
post_msg_active = TRUE;
|
||||
|
||||
LOCK;
|
||||
while(TRUE){
|
||||
|
||||
bytesAvailable = cacRingBufferReadSize(&piiu->recv, TRUE);
|
||||
@@ -1117,9 +1155,8 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu)
|
||||
bytesAvailable);
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
|
||||
post_msg_active = FALSE;
|
||||
UNLOCK;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1174,21 +1211,31 @@ void close_ioc (struct ioc_in_use *piiu)
|
||||
chix = (chid) &piiu->chidlist.node.next;
|
||||
while (chix = (chid) chix->node.next) {
|
||||
chix->type = TYPENOTCONN;
|
||||
chix->count = 0;
|
||||
chix->count = 0U;
|
||||
chix->state = cs_prev_conn;
|
||||
chix->id.sid = ~0L;
|
||||
chix->id.sid = ~0U;
|
||||
chix->ar.read_access = FALSE;
|
||||
chix->ar.write_access = FALSE;
|
||||
/*
|
||||
* try to reconnect
|
||||
*/
|
||||
chix->retry = 0;
|
||||
chix->retry = 0U;
|
||||
}
|
||||
|
||||
if (piiu->chidlist.count) {
|
||||
ca_signal (ECA_DISCONN,piiu->host_name_str);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear outstanding get call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_read_list, chix, TRUE, ECA_DISCONN);
|
||||
|
||||
/*
|
||||
* clear outstanding put call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_write_list, chix, TRUE, ECA_DISCONN);
|
||||
|
||||
/*
|
||||
* call their connection handler as required
|
||||
*/
|
||||
@@ -1507,6 +1554,8 @@ unsigned long cacRingBufferWriteSize(struct ca_buffer *pBuf, int contiguous)
|
||||
* vxWorks user will need to configure a DNS format name for the
|
||||
* host name if they wish to be cnsistent with UNIX and VMS hosts.
|
||||
*
|
||||
* this needs to attempt to determine if the process is a remote
|
||||
* login - hard to do under UNIX
|
||||
*/
|
||||
char *localHostName()
|
||||
{
|
||||
@@ -1564,6 +1613,7 @@ void caAddConfiguredAddr(ELLLIST *pList, ENV_PARAM *pEnv,
|
||||
}
|
||||
|
||||
while(pToken = getToken(&pStr)){
|
||||
memset((char *)&addr,0,sizeof(addr));
|
||||
addr.inetAddr.sin_family = AF_INET;
|
||||
addr.inetAddr.sin_port = htons(port);
|
||||
addr.inetAddr.sin_addr.s_addr = inet_addr(pToken);
|
||||
@@ -1654,32 +1704,38 @@ void caPrintAddrList(ELLLIST *pList)
|
||||
/*
|
||||
* caFetchPortConfig()
|
||||
*/
|
||||
unsigned caFetchPortConfig(ENV_PARAM *pEnv, unsigned defaultPort)
|
||||
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
|
||||
{
|
||||
long longStatus;
|
||||
long port;
|
||||
long epicsParam;
|
||||
int port;
|
||||
|
||||
longStatus = envGetLongConfigParam(pEnv, &port);
|
||||
longStatus = envGetLongConfigParam(pEnv, &epicsParam);
|
||||
if (longStatus!=0) {
|
||||
port = defaultPort;
|
||||
epicsParam = defaultPort;
|
||||
ca_printf ("EPICS \"%s\" integer fetch failed\n", pEnv->name);
|
||||
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, port);
|
||||
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thus must be a server port that will fit in a signed
|
||||
* This must be a server port that will fit in a signed
|
||||
* short
|
||||
*/
|
||||
if (port <= IPPORT_USERRESERVED || port>SHRT_MAX) {
|
||||
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>SHRT_MAX) {
|
||||
ca_printf ("EPICS \"%s\" out of range\n", pEnv->name);
|
||||
/*
|
||||
* Quit if the port is wrong due CA coding error
|
||||
*/
|
||||
assert (port != defaultPort);
|
||||
port = defaultPort;
|
||||
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, port);
|
||||
assert (epicsParam != defaultPort);
|
||||
epicsParam = defaultPort;
|
||||
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* ok to clip to int here because we checked the range
|
||||
*/
|
||||
port = (int) epicsParam;
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,11 @@ HDRVERSIONID(iocinfh, "$Id$")
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
/*
|
||||
@@ -95,10 +95,12 @@ HDRVERSIONID(iocinfh, "$Id$")
|
||||
/*
|
||||
* EPICS includes
|
||||
*/
|
||||
#include <epicsAssert.h>
|
||||
#include <cadef.h>
|
||||
#include <bucketLib.h>
|
||||
#include <ellLib.h>
|
||||
#include <envDefs.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
/*
|
||||
* CA private includes
|
||||
@@ -118,8 +120,8 @@ HDRVERSIONID(iocinfh, "$Id$")
|
||||
# define NBBY 8 /* number of bits per byte */
|
||||
#endif
|
||||
|
||||
#define MSEC_PER_SEC 1000
|
||||
#define USEC_PER_SEC 1000000
|
||||
#define MSEC_PER_SEC 1000L
|
||||
#define USEC_PER_SEC 1000000L
|
||||
|
||||
/*
|
||||
* catch when they use really large strings
|
||||
@@ -168,8 +170,8 @@ struct pending_io_event{
|
||||
typedef struct timeval ca_time;
|
||||
|
||||
#define LD_CA_TIME(FLOAT_TIME,PCATIME) \
|
||||
((PCATIME)->tv_sec = (FLOAT_TIME), \
|
||||
(PCATIME)->tv_usec = ((FLOAT_TIME)-(PCATIME)->tv_sec)*USEC_PER_SEC)
|
||||
((PCATIME)->tv_sec = (long) (FLOAT_TIME), \
|
||||
(PCATIME)->tv_usec = (long) ( ((FLOAT_TIME)-(PCATIME)->tv_sec)*USEC_PER_SEC ))
|
||||
|
||||
/*
|
||||
* dont adjust
|
||||
@@ -188,8 +190,8 @@ extern const ca_time CA_CURRENT_TIME;
|
||||
*/
|
||||
#define MAXCONNTRIES 30 /* N conn retries on unchanged net */
|
||||
|
||||
#define SELECT_POLL (0.1) /* units sec - polls into recast */
|
||||
#define CA_RECAST_DELAY (0.1) /* initial delay to next recast (sec) */
|
||||
#define SELECT_POLL (0.05) /* units sec - polls into recast */
|
||||
#define CA_RECAST_DELAY (0.1) /* initial delay to next recast (sec) */
|
||||
#define CA_RECAST_PORT_MASK 0xff /* random retry interval off port */
|
||||
#define CA_RECAST_PERIOD (5.0) /* ul on retry period long term (sec) */
|
||||
|
||||
@@ -212,7 +214,7 @@ extern const ca_time CA_CURRENT_TIME;
|
||||
#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */
|
||||
|
||||
#define N_REPEATER_TRIES_PRIOR_TO_MSG 50
|
||||
#define REPEATER_TRY_PERIOD (0.1)
|
||||
#define REPEATER_TRY_PERIOD (1.0)
|
||||
|
||||
#ifdef vxWorks
|
||||
typedef struct caclient_put_notify{
|
||||
@@ -316,7 +318,7 @@ struct ca_buffer{
|
||||
|
||||
#define TAG_CONN_DOWN(PIIU) \
|
||||
( \
|
||||
/*ca_printf("Tagging connection down at %d in %s\n", __LINE__, __FILE__),*/ \
|
||||
/* ca_printf("Tagging connection down at %d in %s\n", __LINE__, __FILE__), */ \
|
||||
(PIIU)->conn_up = FALSE \
|
||||
)
|
||||
|
||||
@@ -380,8 +382,6 @@ typedef struct {
|
||||
ELLNODE node;
|
||||
fd_set readMask;
|
||||
fd_set writeMask;
|
||||
fd_set writeSave;
|
||||
fd_set readSave;
|
||||
}caFDInfo;
|
||||
|
||||
struct ca_static{
|
||||
@@ -397,6 +397,7 @@ struct ca_static{
|
||||
ELLLIST putCvrtBuf;
|
||||
ELLLIST fdInfoFreeList;
|
||||
ELLLIST fdInfoList;
|
||||
ca_time currentTime;
|
||||
ca_time ca_conn_next_retry;
|
||||
ca_time ca_conn_retry_delay;
|
||||
ca_time ca_last_repeater_try;
|
||||
@@ -411,6 +412,7 @@ struct ca_static{
|
||||
void (*ca_connection_func)
|
||||
(struct connection_handler_args);
|
||||
void *ca_connection_arg;
|
||||
int (*ca_printf_func)(const char *pformat, va_list args);
|
||||
void (*ca_fd_register_func)
|
||||
(void *, SOCKET, int);
|
||||
void *ca_fd_register_arg;
|
||||
@@ -421,6 +423,7 @@ struct ca_static{
|
||||
bhe *ca_beaconHash[BHT_INET_ADDR_MASK+1];
|
||||
unsigned ca_repeater_tries;
|
||||
unsigned ca_search_retry; /* search retry seq number */
|
||||
unsigned ca_search_responses; /* num search resp within seq # */
|
||||
unsigned short ca_server_port;
|
||||
unsigned short ca_repeater_port;
|
||||
char ca_sprintf_buf[256];
|
||||
@@ -550,6 +553,12 @@ unsigned long cacRingBufferReadSize(
|
||||
struct ca_buffer *pBuf,
|
||||
int contiguous);
|
||||
|
||||
void caIOBlockListFree(
|
||||
ELLLIST *pList,
|
||||
chid chan,
|
||||
int cbRequired,
|
||||
int status);
|
||||
|
||||
char *localUserName(void);
|
||||
|
||||
char *localHostName(void);
|
||||
@@ -593,6 +602,7 @@ ca_real cac_time_diff(ca_time *pTVA, ca_time *pTVB);
|
||||
ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB);
|
||||
void caIOBlockFree(evid pIOBlock);
|
||||
void clearChannelResources(unsigned id);
|
||||
void caSetDefaultPrintfHandler ();
|
||||
|
||||
/*
|
||||
* !!KLUDGE!!
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef float ca_float32_t;
|
||||
#define IOC_WRITE 4 /* write a channel value */
|
||||
#define IOC_SNAPSHOT 5 /* snapshot of the system */
|
||||
#define IOC_SEARCH 6 /* IOC channel search */
|
||||
/* 7 */
|
||||
#define IOC_BUILD 7 /* build - obsolete */
|
||||
#define IOC_EVENTS_OFF 8 /* flow control */
|
||||
#define IOC_EVENTS_ON 9 /* flow control */
|
||||
#define IOC_READ_SYNC 10 /* purge old reads */
|
||||
@@ -91,7 +91,7 @@ typedef float ca_float32_t;
|
||||
#define IOC_RSRV_IS_UP 13 /* CA server has joined the net */
|
||||
#define IOC_NOT_FOUND 14 /* channel not found */
|
||||
#define IOC_READ_NOTIFY 15 /* add a one shot event */
|
||||
/* 16 */
|
||||
#define IOC_READ_BUILD 16 /* read and build - obsolete */
|
||||
#define REPEATER_CONFIRM 17 /* registration confirmation */
|
||||
#define IOC_CLAIM_CIU 18 /* client claims resource in server */
|
||||
#define IOC_WRITE_NOTIFY 19 /* notify after write chan value */
|
||||
@@ -134,7 +134,8 @@ typedef float ca_float32_t;
|
||||
* fields aligned on natural boundaries.
|
||||
*
|
||||
* NOTE: all structures declared in this file must have a
|
||||
* byte count which is evenly divisible by 8 for the SPARC.
|
||||
* byte count which is evenly divisible by 8 matching
|
||||
* the largest atomic data type in db_access.h.
|
||||
*/
|
||||
#define CA_MESSAGE_ALIGN(A) (OCT_ROUND(A)<<3)
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <db_access.h>
|
||||
|
||||
#ifdef CA_LITTLE_ENDIAN
|
||||
# ifndef ntohs
|
||||
# define ntohs(SHORT)\
|
||||
@@ -63,9 +65,30 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MIT_FLOAT
|
||||
#define htond(IEEEhost, IEEEnet) (*(IEEEnet) = *(IEEEhost))
|
||||
#define ntohd(IEEEnet, IEEEhost) (*(IEEEhost) = *(IEEEnet))
|
||||
#define htonf(IEEEhost, IEEEnet) (*(IEEEnet) = *(IEEEhost))
|
||||
#define ntohf(IEEEnet, IEEEhost) (*(IEEEhost) = *(IEEEnet))
|
||||
#if defined(CA_FLOAT_IEEE) && !defined(CA_LITTLE_ENDIAN)
|
||||
# define dbr_htond(IEEEhost, IEEEnet) \
|
||||
(*(dbr_double_t *)(IEEEnet) = *(dbr_double_t *)(IEEEhost))
|
||||
# define dbr_ntohd(IEEEnet, IEEEhost) \
|
||||
(*(dbr_double_t *)(IEEEhost) = *(dbr_double_t *)(IEEEnet))
|
||||
# define dbr_htonf(IEEEhost, IEEEnet) \
|
||||
(*(dbr_float_t *)(IEEEnet) = *(dbr_float_t *)(IEEEhost))
|
||||
# define dbr_ntohf(IEEEnet, IEEEhost) \
|
||||
(*(dbr_float_t *)(IEEEhost) = *(dbr_float_t *)(IEEEnet))
|
||||
#elif defined(CA_FLOAT_IEEE) && defined(CA_LITTLE_ENDIAN)
|
||||
# define dbr_ntohf(NET,HOST) \
|
||||
{*((dbr_long_t *)(HOST)) = ntohl(*((dbr_long_t *)(NET )));}
|
||||
# define dbr_htonf(HOST,NET) \
|
||||
{*((dbr_long_t *)(NET) ) = htonl(*((dbr_long_t *)(HOST)));}
|
||||
# define dbr_ntohd(NET,HOST) \
|
||||
{ ((dbr_long_t *)(HOST))[1] = ntohl(((dbr_long_t *)(NET))[0]) ; \
|
||||
((dbr_long_t *)(HOST))[0] = ntohl(((dbr_long_t *)(NET))[1]) ;}
|
||||
# define dbr_htond(HOST,NET) \
|
||||
{ ((dbr_long_t *)(NET))[1] = htonl(((dbr_long_t *)(HOST))[0]) ; \
|
||||
((dbr_long_t *)(NET))[0] = htonl(((dbr_long_t *)(HOST))[1]) ;}
|
||||
#else
|
||||
void dbr_htond(dbr_double_t *pHost, dbr_double_t *pNet);
|
||||
void dbr_ntohd(dbr_double_t *pNet, dbr_double_t *pHost);
|
||||
void dbr_htonf(dbr_float_t *pHost, dbr_float_t *pNet);
|
||||
void dbr_ntohf(dbr_float_t *pNet, dbr_float_t *pHost);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,13 +37,18 @@ static char *sccsId = "@(#) $Id$";
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#ifdef _WINDOWS
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <epicsAssert.h>
|
||||
|
||||
|
||||
/*
|
||||
@@ -55,7 +60,7 @@ void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
|
||||
struct hostent *ent;
|
||||
|
||||
ent = gethostbyaddr(
|
||||
pnet_addr,
|
||||
(char *) pnet_addr,
|
||||
sizeof(*pnet_addr),
|
||||
AF_INET);
|
||||
if(ent){
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* pairs reside at the same C bracket level
|
||||
* .11 GeG 120992 support VMS/UCX
|
||||
* .12 CJM 130794 define MYERRNO properly for UCX
|
||||
* .13 CJM 311094 mods to support DEC C compiler
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -39,6 +40,7 @@ static char *os_depenhSccsId = "$Id$";
|
||||
* each socket library
|
||||
*/
|
||||
#ifdef UNIX
|
||||
# include <unistd.h>
|
||||
# include <errno.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/time.h>
|
||||
@@ -46,7 +48,9 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# include <sys/param.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <net/if.h>
|
||||
# include <arpa/inet.h>
|
||||
# define CA_OS_CONFIGURED
|
||||
#endif
|
||||
|
||||
@@ -57,6 +61,7 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/tcp.h>
|
||||
# include <net/if.h>
|
||||
|
||||
# include <systime.h>
|
||||
@@ -93,9 +98,13 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# define __TIME_LOADED /* dont include VMS CC time.h under MULTINET */
|
||||
# include <netinet/tcp.h>
|
||||
#if !defined(UCX)
|
||||
# include <sys/time.h>
|
||||
# include <tcp/errno.h>
|
||||
# include <tcp/errno.h>
|
||||
#else
|
||||
# include <errno>
|
||||
#endif
|
||||
# include <ssdef>
|
||||
# include <stsdef>
|
||||
# include <iodef.h>
|
||||
@@ -104,12 +113,12 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# include <descrip.h>
|
||||
# define MAXHOSTNAMELEN 75
|
||||
#ifdef UCX /* GeG 09-DEC-1992 */
|
||||
# include <sys/ucx$inetdef.h>
|
||||
# include <ucx.h>
|
||||
# include <sys/ucx$inetdef.h>
|
||||
# include <ucx.h>
|
||||
#else
|
||||
# include <net/if.h>
|
||||
# include <vms/inetiodef.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <net/if.h>
|
||||
# include <vms/inetiodef.h>
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
# define CA_OS_CONFIGURED
|
||||
#endif /*VMS*/
|
||||
@@ -123,15 +132,12 @@ static char *os_depenhSccsId = "$Id$";
|
||||
#endif /*_WINDOWS*/
|
||||
|
||||
#ifndef CA_OS_CONFIGURED
|
||||
#error Please define one of vxWorks, UNIX or VMS
|
||||
#error Please define one of vxWorks, UNIX VMS, or _WINDOWS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Big endin architecture is assumed. Otherwise set "CA_LITTLE_ENDIAN".
|
||||
*
|
||||
* IEEE floating point architecture assumed. Set "CA_FLOAT_MIT" if
|
||||
* appropriate. No other floating point formats currently
|
||||
* supported.
|
||||
* Here are the definitions for architecture dependent byte ordering
|
||||
* and floating point format
|
||||
*/
|
||||
#if defined(VAX)
|
||||
# define CA_FLOAT_MIT
|
||||
@@ -139,10 +145,10 @@ static char *os_depenhSccsId = "$Id$";
|
||||
#elif defined(_X86_)
|
||||
# define CA_FLOAT_IEEE
|
||||
# define CA_LITTLE_ENDIAN
|
||||
#elif (defined(__ALPHA) || defined(__alpha)) && defined(VMS)
|
||||
#elif (defined(__ALPHA) && defined(VMS) || defined(__alpha)) && defined(VMS)
|
||||
# define CA_FLOAT_MIT
|
||||
# define CA_LITTLE_ENDIAN
|
||||
#elif (defined(__ALPHA) || defined(__alpha)) && defined(UNIX)
|
||||
#elif (defined(__ALPHA) && defined(UNIX) || defined(__alpha)) && defined(UNIX)
|
||||
# define CA_FLOAT_IEEE
|
||||
# define CA_LITTLE_ENDIAN
|
||||
#else
|
||||
@@ -269,7 +275,6 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# else
|
||||
# ifdef UCX
|
||||
# define MYERRNO errno
|
||||
extern volatile int noshare errno ;
|
||||
# else
|
||||
# define MYERRNO socket_errno
|
||||
# endif
|
||||
@@ -286,6 +291,12 @@ static char *os_depenhSccsId = "$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
# define LOCKEVENTS
|
||||
# define UNLOCKEVENTS
|
||||
# define EVENTLOCKTEST (post_msg_active)
|
||||
# define MAXHOSTNAMELEN 75
|
||||
# define IPPORT_USERRESERVED 5000
|
||||
# define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
# define ENOBUFS WSAENOBUFS
|
||||
|
||||
@@ -31,14 +31,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI includes
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/param.h>
|
||||
@@ -74,52 +66,27 @@ void cac_gettimeval(struct timeval *pt)
|
||||
void cac_mux_io(struct timeval *ptimeout)
|
||||
{
|
||||
int count;
|
||||
int newInput;
|
||||
struct timeval timeout;
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
newInput = FALSE;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
if(count>0){
|
||||
newInput = TRUE;
|
||||
}
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
}
|
||||
while(count>0);
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
while(newInput);
|
||||
|
||||
}
|
||||
|
||||
log_time(char *pStr)
|
||||
{
|
||||
static struct timeval time;
|
||||
struct timeval newtime;
|
||||
struct timezone tz;
|
||||
ca_real diff;
|
||||
int status;
|
||||
|
||||
status = gettimeofday(&newtime, &tz);
|
||||
assert(status==0);
|
||||
|
||||
diff = cac_time_diff(&newtime, &time);
|
||||
printf("Expired %f - %s\n", diff, pStr);
|
||||
time = newtime;
|
||||
while(count>0);
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +187,7 @@ char *localUserName()
|
||||
if(!pName){
|
||||
pName = getpwuid(getuid())->pw_name;
|
||||
if(!pName){
|
||||
return NULL;
|
||||
pName = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +223,7 @@ void ca_spawn_repeater()
|
||||
|
||||
/*
|
||||
* return to the caller
|
||||
* if its the in the initiating process
|
||||
* if its in the initiating process
|
||||
*/
|
||||
if (status){
|
||||
return;
|
||||
@@ -270,7 +237,8 @@ void ca_spawn_repeater()
|
||||
status = execlp(pImageName, NULL);
|
||||
if(status<0){
|
||||
ca_printf("!!WARNING!!\n");
|
||||
ca_printf("The executable \"%s\" couldnt be located.\n", pImageName);
|
||||
ca_printf("The executable \"%s\" couldnt be located\n", pImageName);
|
||||
ca_printf("because - %s\n", strerror(MYERRNO));
|
||||
ca_printf("You may need to modify your PATH environment variable.\n");
|
||||
ca_printf("Creating CA repeater with fork() system call.\n");
|
||||
ca_printf("Repeater will inherit parents process name and resources.\n");
|
||||
@@ -281,25 +249,14 @@ void ca_spawn_repeater()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ca_printf()
|
||||
* caSetDefaultPrintfHandler ()
|
||||
* use the normal default here
|
||||
* ( see access.c )
|
||||
*/
|
||||
int ca_printf(char *pformat, ...)
|
||||
void caSetDefaultPrintfHandler ()
|
||||
{
|
||||
va_list args;
|
||||
int status;
|
||||
|
||||
va_start(args, pformat);
|
||||
|
||||
status = vfprintf(
|
||||
stderr,
|
||||
pformat,
|
||||
args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return status;
|
||||
ca_static->ca_printf_func = epicsVprintf;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Direct inqueries to:
|
||||
* Andy Kozubal, AT-8, Mail Stop H820
|
||||
* Jeff HIll, AT-8, Mail Stop H820
|
||||
* Los Alamos National Laboratory
|
||||
* Los Alamos, New Mexico 87545
|
||||
* Phone: (505) 667-6508
|
||||
* E-mail: kozubal@k2.lanl.gov
|
||||
* Phone: (505) 665-1831
|
||||
* E-mail: johill@lanl.gov
|
||||
*
|
||||
* PURPOSE:
|
||||
* Broadcasts fan out over the LAN, but UDP does not allow
|
||||
@@ -141,8 +141,9 @@ void ca_repeater()
|
||||
|
||||
status = local_addr(sock, &local);
|
||||
if(status != OK){
|
||||
ca_printf("CA Repeater: no inet interfaces online?\n");
|
||||
assert(0);
|
||||
ca_printf(
|
||||
"CA Repeater: failed during initialization - no local IP address\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -241,7 +242,7 @@ void ca_repeater()
|
||||
/*
|
||||
* register_new_client()
|
||||
*/
|
||||
void register_new_client(
|
||||
LOCAL void register_new_client(
|
||||
SOCKET sock,
|
||||
struct sockaddr_in *pLocal,
|
||||
struct sockaddr_in *pFrom)
|
||||
|
||||
@@ -119,8 +119,8 @@ unsigned long blockSize
|
||||
if(piiu->curMsgBytes < sizeof(piiu->curMsg)){
|
||||
char *pHdr;
|
||||
|
||||
size = sizeof(piiu->curMsg) - piiu->curMsgBytes;
|
||||
size = min(size, blockSize);
|
||||
size = sizeof (piiu->curMsg) - piiu->curMsgBytes;
|
||||
size = min (size, blockSize);
|
||||
|
||||
pHdr = (char *) &piiu->curMsg;
|
||||
memcpy( pHdr + piiu->curMsgBytes,
|
||||
@@ -129,6 +129,10 @@ unsigned long blockSize
|
||||
|
||||
piiu->curMsgBytes += size;
|
||||
if(piiu->curMsgBytes < sizeof(piiu->curMsg)){
|
||||
#if 0
|
||||
printf ("waiting for %d msg hdr bytes\n",
|
||||
sizeof(piiu->curMsg)-piiu->curMsgBytes);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -170,14 +174,14 @@ unsigned long blockSize
|
||||
/*
|
||||
* make sure we have a large enough message body cache
|
||||
*/
|
||||
if(piiu->curMsg.m_postsize>piiu->curDataMax){
|
||||
if (piiu->curMsg.m_postsize>piiu->curDataMax) {
|
||||
if(piiu->pCurData){
|
||||
free(piiu->pCurData);
|
||||
}
|
||||
piiu->curDataMax = 0;
|
||||
piiu->pCurData = (void *)
|
||||
malloc(piiu->curMsg.m_postsize);
|
||||
if(!piiu->pCurData){
|
||||
piiu->curDataMax = 0;
|
||||
piiu->curMsgBytes = 0;
|
||||
piiu->curDataBytes = 0;
|
||||
return ERROR;
|
||||
@@ -188,6 +192,8 @@ unsigned long blockSize
|
||||
|
||||
/*
|
||||
* Fetch a complete message body
|
||||
* (allows for arrays larger than than the
|
||||
* ring buffer size)
|
||||
*/
|
||||
if(piiu->curMsg.m_postsize>piiu->curDataBytes){
|
||||
char *pBdy;
|
||||
@@ -200,6 +206,10 @@ unsigned long blockSize
|
||||
size);
|
||||
piiu->curDataBytes += size;
|
||||
if(piiu->curDataBytes < piiu->curMsg.m_postsize){
|
||||
#if 0
|
||||
printf ("waiting for %d msg bdy bytes\n",
|
||||
piiu->curMsg.m_postsize-piiu->curDataBytes);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
pInBuf += size;
|
||||
@@ -466,7 +476,6 @@ struct in_addr *pnet_addr
|
||||
* read seq
|
||||
*/
|
||||
if (VALID_MSG(piiu)){
|
||||
|
||||
/*
|
||||
* convert the data buffer from net
|
||||
* format to host format
|
||||
@@ -478,11 +487,19 @@ struct in_addr *pnet_addr
|
||||
FALSE,
|
||||
piiu->curMsg.m_count);
|
||||
# else
|
||||
memcpy(
|
||||
(char *)pIOBlock->usr_arg,
|
||||
piiu->pCurData,
|
||||
dbr_size_n(piiu->curMsg.m_type,
|
||||
piiu->curMsg.m_count));
|
||||
if (piiu->curMsg.m_type == DBR_STRING) {
|
||||
strcpy ((char *)pIOBlock->usr_arg,
|
||||
piiu->pCurData);
|
||||
}
|
||||
else {
|
||||
memcpy(
|
||||
(char *)pIOBlock->usr_arg,
|
||||
piiu->pCurData,
|
||||
dbr_size_n (
|
||||
piiu->curMsg.m_type,
|
||||
piiu->curMsg.m_count)
|
||||
);
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
@@ -688,7 +705,7 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
|
||||
if (CA_V44(CA_PROTOCOL_VERSION,piiu->minor_version_number)) {
|
||||
chan->id.sid = ntohl (piiu->curMsg.m_available);
|
||||
chan->id.sid = piiu->curMsg.m_available;
|
||||
}
|
||||
reconnect_channel(piiu, chan);
|
||||
break;
|
||||
@@ -817,6 +834,7 @@ struct in_addr *pnet_addr
|
||||
ellDelete(&chpiiu->chidlist, &chan->node);
|
||||
chan->piiu = allocpiiu;
|
||||
ellAdd(&allocpiiu->chidlist, &chan->node);
|
||||
ca_static->ca_search_responses++;
|
||||
|
||||
/*
|
||||
* If this is the first channel to be
|
||||
|
||||
@@ -61,6 +61,7 @@ void ca_sg_init(void)
|
||||
void ca_sg_shutdown(struct ca_static *ca_temp)
|
||||
{
|
||||
CASG *pcasg;
|
||||
CASG *pnextcasg;
|
||||
int status;
|
||||
|
||||
/*
|
||||
@@ -69,16 +70,25 @@ void ca_sg_shutdown(struct ca_static *ca_temp)
|
||||
LOCK;
|
||||
pcasg = (CASG *) ellFirst (&ca_temp->activeCASG);
|
||||
while (pcasg) {
|
||||
status = bucketRemoveItemUnsignedId (
|
||||
ca_temp->ca_pSlowBucket, &pcasg->id);
|
||||
assert (status == BUCKET_SUCCESS);
|
||||
pcasg = (CASG *) ellNext(&pcasg->node);
|
||||
pnextcasg = (CASG *) ellNext (&pcasg->node);
|
||||
status = ca_sg_delete (pcasg->id);
|
||||
assert (status==ECA_NORMAL);
|
||||
pcasg = pnextcasg;
|
||||
}
|
||||
ellFree(&ca_temp->activeCASG);
|
||||
ellFree(&ca_temp->freeCASG);
|
||||
assert (ellCount(&ca_temp->activeCASG)==0);
|
||||
|
||||
/*
|
||||
* per sync group
|
||||
*/
|
||||
ellFree (&ca_temp->freeCASG);
|
||||
|
||||
/*
|
||||
* per sync group op
|
||||
*/
|
||||
ellFree (&ca_temp->activeCASGOP);
|
||||
ellFree (&ca_temp->freeCASGOP);
|
||||
|
||||
UNLOCK;
|
||||
ellInit(&ca_temp->activeCASGOP);
|
||||
ellInit(&ca_temp->freeCASGOP);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -87,7 +97,7 @@ void ca_sg_shutdown(struct ca_static *ca_temp)
|
||||
/*
|
||||
* ca_sg_create()
|
||||
*/
|
||||
int ca_sg_create(CA_SYNC_GID *pgid)
|
||||
int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
|
||||
{
|
||||
int status;
|
||||
CASG *pcasg;
|
||||
@@ -152,7 +162,7 @@ int ca_sg_create(CA_SYNC_GID *pgid)
|
||||
/*
|
||||
* ca_sg_delete()
|
||||
*/
|
||||
int ca_sg_delete(CA_SYNC_GID gid)
|
||||
int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
|
||||
{
|
||||
int status;
|
||||
CASG *pcasg;
|
||||
@@ -190,10 +200,9 @@ int ca_sg_delete(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_block()
|
||||
*/
|
||||
int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
{
|
||||
struct timeval beg_time;
|
||||
struct timeval cur_time;
|
||||
ca_real delay;
|
||||
int status;
|
||||
CASG *pcasg;
|
||||
@@ -234,7 +243,12 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
*/
|
||||
ca_flush_io();
|
||||
|
||||
cac_gettimeval(&beg_time);
|
||||
/*
|
||||
* the current time set within ca_flush_io()
|
||||
* above.
|
||||
*/
|
||||
beg_time = ca_static->currentTime;
|
||||
delay = 0.0;
|
||||
|
||||
status = ECA_NORMAL;
|
||||
while(pcasg->opPendCount){
|
||||
@@ -244,8 +258,6 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
/*
|
||||
* Exit if the timeout has expired
|
||||
*/
|
||||
cac_gettimeval (&cur_time);
|
||||
delay = cac_time_diff (&cur_time, &beg_time);
|
||||
remaining = timeout-delay;
|
||||
if (remaining<=0.0) {
|
||||
status = ECA_TIMEOUT;
|
||||
@@ -260,9 +272,15 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
/*
|
||||
* wait for asynch notification
|
||||
*/
|
||||
tmo.tv_sec = remaining;
|
||||
tmo.tv_usec = (remaining-tmo.tv_sec)*USEC_PER_SEC;
|
||||
tmo.tv_sec = (long) remaining;
|
||||
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
|
||||
cac_block_for_sg_completion (pcasg, &tmo);
|
||||
|
||||
/*
|
||||
* the current time set within cac_block_for_sg_completion()
|
||||
* above.
|
||||
*/
|
||||
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
|
||||
}
|
||||
pcasg->opPendCount = 0;
|
||||
pcasg->seqNo++;
|
||||
@@ -273,7 +291,7 @@ int ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
/*
|
||||
* ca_sg_reset
|
||||
*/
|
||||
int ca_sg_reset(CA_SYNC_GID gid)
|
||||
int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
|
||||
{
|
||||
CASG *pcasg;
|
||||
|
||||
@@ -295,7 +313,7 @@ int ca_sg_reset(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_test
|
||||
*/
|
||||
int ca_sg_test(CA_SYNC_GID gid)
|
||||
int APIENTRY ca_sg_test(CA_SYNC_GID gid)
|
||||
{
|
||||
CASG *pcasg;
|
||||
|
||||
@@ -321,7 +339,7 @@ int ca_sg_test(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_array_put()
|
||||
*/
|
||||
int ca_sg_array_put(
|
||||
int APIENTRY ca_sg_array_put(
|
||||
CA_SYNC_GID gid,
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -386,7 +404,7 @@ void *pvalue)
|
||||
/*
|
||||
* ca_sg_array_get()
|
||||
*/
|
||||
int ca_sg_array_get(
|
||||
int APIENTRY ca_sg_array_get(
|
||||
CA_SYNC_GID gid,
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
|
||||
@@ -19,7 +19,7 @@ static char *sccsId = "$Id$";
|
||||
#include "iocinf.h"
|
||||
|
||||
|
||||
void ca_test_event(struct event_handler_args args)
|
||||
void APIENTRY ca_test_event(struct event_handler_args args)
|
||||
{
|
||||
ca_printf("CAC: ~~~### in test event for [%s] ###~~~\n",args.chid+1);
|
||||
ca_printf("CAC: User argument\t%x\n", args.usr);
|
||||
|
||||
15
src/ca/ucx.h
15
src/ca/ucx.h
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* GeG 09-DEC-1992 initial edit
|
||||
* CJM 13-Jul-1994 add fd_set etc for R3.12
|
||||
* CJM 09-Dec-1994 define fd_set etc. so it will compile for
|
||||
* both DEC C and Vax C
|
||||
*
|
||||
*/
|
||||
#ifndef _UCX_H_
|
||||
@@ -70,13 +72,14 @@ typedef long fd_mask ;
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
|
||||
typedef struct fd_set {
|
||||
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)] ;
|
||||
} fd_set ;
|
||||
/*
|
||||
* Both DEC C and VAX C only allow 32 fd's at once
|
||||
*/
|
||||
typedef int fd_set ;
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
|
||||
#define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS)))
|
||||
#define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS)))
|
||||
#define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS)))
|
||||
#define FD_ZERO(p) bzero((char *)(p), sizeof (*(p)))
|
||||
|
||||
#include <iodef.h>
|
||||
|
||||
@@ -31,15 +31,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdLib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* VMS includes
|
||||
*/
|
||||
@@ -77,35 +68,27 @@ void cac_gettimeval(struct timeval *pt)
|
||||
void cac_mux_io(struct timeval *ptimeout)
|
||||
{
|
||||
int count;
|
||||
int newInput;
|
||||
struct timeval timeout;
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
newInput = FALSE;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
if(count>0){
|
||||
newInput = TRUE;
|
||||
}
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
}
|
||||
while(count>0);
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
while(newInput);
|
||||
while(count>0);
|
||||
|
||||
}
|
||||
|
||||
@@ -147,7 +130,7 @@ void os_specific_sg_io_complete(CASG *pcasg)
|
||||
/*
|
||||
* cac_block_for_sg_completion()
|
||||
*/
|
||||
void cac_block_for_sg_completion(pTV)
|
||||
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
{
|
||||
cac_mux_io(pTV);
|
||||
}
|
||||
@@ -183,11 +166,7 @@ void cac_os_depen_exit (struct ca_static *pcas)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* localUserName() - for VMS
|
||||
*
|
||||
* o Indicates failure by setting ptr to nill
|
||||
*
|
||||
*/
|
||||
char *localUserName()
|
||||
{
|
||||
@@ -230,24 +209,13 @@ char *localUserName()
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if(status != SS$_NORMAL){
|
||||
return NULL;
|
||||
strcpy (pName, "");
|
||||
}
|
||||
|
||||
/*
|
||||
* test for remote login
|
||||
*/
|
||||
if(jobTypeSize != sizeof(jobType)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not appear to change when it is
|
||||
* a remote login ??
|
||||
*/
|
||||
if(jobType != JPI$K_LOCAL && jobType != JPI$K_DETACHED){
|
||||
pTmp = "REMOTE";
|
||||
return pTmp;
|
||||
strcpy (pName, "");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -335,19 +303,12 @@ void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
|
||||
|
||||
|
||||
/*
|
||||
* ca_printf()
|
||||
* caSetDefaultPrintfHandler ()
|
||||
* use the normal default here
|
||||
* ( see access.c )
|
||||
*/
|
||||
int ca_printf(char *pformat, ...)
|
||||
void caSetDefaultPrintfHandler ()
|
||||
{
|
||||
va_list args;
|
||||
int status;
|
||||
|
||||
va_start(args, pformat);
|
||||
|
||||
status = vfprintf(stderr, pformat, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return status;
|
||||
ca_static->ca_printf_func = epicsVprintf;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <callback.h>
|
||||
#include "iocinf.h"
|
||||
#include "remLib.h"
|
||||
@@ -44,8 +42,6 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid);
|
||||
LOCAL int cac_add_task_variable (struct ca_static *ca_temp);
|
||||
LOCAL void deleteCallBack(CALLBACK *pcb);
|
||||
|
||||
#define USEC_PER_SEC 1000000
|
||||
|
||||
|
||||
/*
|
||||
* cac_gettimeval()
|
||||
@@ -104,6 +100,9 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
int count;
|
||||
struct timeval timeout;
|
||||
|
||||
#if NOASYNCRECV
|
||||
cac_clean_iiu_list();
|
||||
#endif
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
@@ -113,6 +112,11 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
timeout.tv_sec = 0;
|
||||
}
|
||||
while(count>0);
|
||||
|
||||
#if NOASYNCRECV
|
||||
ca_process_input_queue();
|
||||
manage_conn(TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +129,9 @@ void cac_block_for_io_completion(struct timeval *pTV)
|
||||
unsigned long ticks;
|
||||
unsigned long rate = sysClkRateGet();
|
||||
|
||||
#if NOASYNCRECV
|
||||
cac_mux_io(pTV);
|
||||
#else
|
||||
/*
|
||||
* flush outputs
|
||||
* (recv occurs in another thread)
|
||||
@@ -137,6 +144,7 @@ void cac_block_for_io_completion(struct timeval *pTV)
|
||||
ticks = min(LOCALTICKS, ticks);
|
||||
|
||||
semTake(io_done_sem, ticks);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +154,7 @@ void cac_block_for_io_completion(struct timeval *pTV)
|
||||
void os_specific_sg_create(CASG *pcasg)
|
||||
{
|
||||
pcasg->sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
assert(pcasg->sem);
|
||||
assert (pcasg->sem);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +166,7 @@ void os_specific_sg_delete(CASG *pcasg)
|
||||
int status;
|
||||
|
||||
status = semDelete(pcasg->sem);
|
||||
assert(status == OK);
|
||||
assert (status == OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +178,7 @@ void os_specific_sg_io_complete(CASG *pcasg)
|
||||
int status;
|
||||
|
||||
status = semGive(pcasg->sem);
|
||||
assert(status == OK);
|
||||
assert (status == OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -183,6 +191,9 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
unsigned long ticks;
|
||||
unsigned long rate = sysClkRateGet();
|
||||
|
||||
#if NOASYNCRECV
|
||||
cac_mux_io(pTV);
|
||||
#else
|
||||
/*
|
||||
* flush outputs
|
||||
* (recv occurs in another thread)
|
||||
@@ -194,7 +205,8 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
ticks = pTV->tv_sec*rate + (pTV->tv_usec*rate)/USEC_PER_SEC;
|
||||
ticks = min(LOCALTICKS, ticks);
|
||||
|
||||
semTake(pcasg->sem, ticks);
|
||||
semTake (pcasg->sem, ticks);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +375,7 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
evuser = (void *) db_init_events();
|
||||
assert(evuser);
|
||||
|
||||
@@ -440,14 +453,17 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid)
|
||||
* Cancel all local events
|
||||
* (and put call backs)
|
||||
*
|
||||
* !! temp release lock so that the event task
|
||||
* can finish !!
|
||||
*/
|
||||
UNLOCK;
|
||||
chix = (chid) & pcas->ca_local_chidlist.node;
|
||||
while (chix = (chid) chix->node.next) {
|
||||
while (monix = (evid) ellGet(&chix->eventq)) {
|
||||
/*
|
||||
* temp release lock so that the event task
|
||||
* can finish
|
||||
*/
|
||||
UNLOCK;
|
||||
status = db_cancel_event(monix + 1);
|
||||
LOCK;
|
||||
assert(status == OK);
|
||||
free(monix);
|
||||
}
|
||||
@@ -461,7 +477,6 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid)
|
||||
free (ppn);
|
||||
}
|
||||
}
|
||||
LOCK;
|
||||
|
||||
/*
|
||||
* set ca_static for access.c
|
||||
@@ -739,7 +754,7 @@ void ca_spawn_repeater()
|
||||
/*
|
||||
* ca_repeater_task()
|
||||
*/
|
||||
void ca_repeater_task()
|
||||
LOCAL void ca_repeater_task()
|
||||
{
|
||||
taskwdInsert((int)taskIdCurrent, NULL, NULL);
|
||||
ca_repeater();
|
||||
@@ -830,6 +845,7 @@ void cac_recv_task(int tid)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int status;
|
||||
int count;
|
||||
|
||||
taskwdInsert((int) taskIdCurrent, NULL, NULL);
|
||||
|
||||
@@ -841,58 +857,37 @@ void cac_recv_task(int tid)
|
||||
* ca_task_exit() is called.
|
||||
*/
|
||||
while(TRUE){
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 1;
|
||||
|
||||
#if NOASYNCRECV
|
||||
taskDelay(60);
|
||||
#else
|
||||
cac_clean_iiu_list();
|
||||
|
||||
cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS);
|
||||
timeout.tv_usec = 50000;
|
||||
timeout.tv_sec = 0;
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_SENDS | CA_DO_RECVS);
|
||||
|
||||
ca_process_input_queue();
|
||||
ca_process_input_queue();
|
||||
manage_conn(TRUE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* caSetDefaultPrintfHandler()
|
||||
*
|
||||
* replace the default printf handler with a
|
||||
* vxWorks specific one that calls logMsg ()
|
||||
* so that:
|
||||
*
|
||||
* ca_printf()
|
||||
*
|
||||
*
|
||||
* o messages go to the log file
|
||||
* o messages dont get intermixed
|
||||
*/
|
||||
int ca_printf(char *pformat, ...)
|
||||
void caSetDefaultPrintfHandler ()
|
||||
{
|
||||
va_list args;
|
||||
int status;
|
||||
|
||||
va_start(args, pformat);
|
||||
|
||||
{
|
||||
int logMsgArgs[6];
|
||||
int i;
|
||||
|
||||
for(i=0; i< NELEMENTS(logMsgArgs); i++){
|
||||
logMsgArgs[i] = va_arg(args, int);
|
||||
}
|
||||
|
||||
status = logMsg(
|
||||
pformat,
|
||||
logMsgArgs[0],
|
||||
logMsgArgs[1],
|
||||
logMsgArgs[2],
|
||||
logMsgArgs[3],
|
||||
logMsgArgs[4],
|
||||
logMsgArgs[5]);
|
||||
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
return status;
|
||||
ca_static->ca_printf_func = epicsVprintf;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* $Id$
|
||||
* Author: Jeffrey O. Hill
|
||||
* Author: Jeffrey O. Hill, Chris Timossi
|
||||
* hill@luke.lanl.gov
|
||||
* CATimossi@lbl.gov
|
||||
* (505) 665 1831
|
||||
* Date: 9-93
|
||||
*
|
||||
@@ -32,12 +33,9 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI includes
|
||||
* Windows includes
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
@@ -45,6 +43,11 @@
|
||||
#error This source is specific to DOS/WINDOS
|
||||
#endif
|
||||
|
||||
static int get_subnet_mask ( char SubNetMaskStr[256]);
|
||||
static int RegTcpParams (char IpAddr[256], char SubNetMask[256]);
|
||||
static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
|
||||
LPDWORD lpdwType, LPBYTE lpbData, LPDWORD lpcbData );
|
||||
|
||||
|
||||
/*
|
||||
* cac_gettimeval
|
||||
@@ -72,35 +75,27 @@ void cac_gettimeval(struct timeval *pt)
|
||||
void cac_mux_io(struct timeval *ptimeout)
|
||||
{
|
||||
int count;
|
||||
int newInput;
|
||||
struct timeval timeout;
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE); newInput = FALSE;
|
||||
|
||||
do{
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
if(count>0){
|
||||
newInput = TRUE;
|
||||
}
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
}
|
||||
while(count>0);
|
||||
count = cac_select_io(
|
||||
&timeout,
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
}
|
||||
while(newInput);
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
while(count>0);
|
||||
}
|
||||
|
||||
|
||||
@@ -143,9 +138,10 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
*/
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
{
|
||||
int status;
|
||||
int status;
|
||||
WSADATA WsaData;
|
||||
|
||||
ca_static = ca_temp;
|
||||
ca_static = pcas;
|
||||
|
||||
/*
|
||||
* dont allow disconnect to terminate process
|
||||
@@ -154,16 +150,17 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
* allow error to be returned to sendto()
|
||||
* instead of handling disconnect at interrupt
|
||||
*/
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
|
||||
/* signal(SIGPIPE,SIG_IGN); */
|
||||
|
||||
# ifdef _WINSOCKAPI_
|
||||
status = WSAStartup(MAKEWORD(1,1), &WsaData));
|
||||
status = WSAStartup(MAKEWORD(1,1), &WsaData);
|
||||
assert (status==0);
|
||||
# endif
|
||||
|
||||
status = ca_os_independent_init ();
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,12 +185,16 @@ void cac_os_depen_exit (struct ca_static *pcas)
|
||||
*/
|
||||
char *localUserName()
|
||||
{
|
||||
int length;
|
||||
char *pName;
|
||||
char *pTmp;
|
||||
int length;
|
||||
char *pName;
|
||||
char *pTmp;
|
||||
char Uname[] = "";
|
||||
|
||||
pName = "Joe PC";
|
||||
length = strlen(pName)+1;
|
||||
pName = getenv("USERNAME");
|
||||
if (!pName) {
|
||||
pName = Uname;
|
||||
}
|
||||
length = strlen(pName)+1;
|
||||
|
||||
pTmp = malloc(length);
|
||||
if(!pTmp){
|
||||
@@ -219,8 +220,13 @@ void ca_spawn_repeater()
|
||||
* running in the repeater process
|
||||
* if here
|
||||
*/
|
||||
pImageName = "caRepeater";
|
||||
status = system(pImageName);
|
||||
pImageName = "caRepeater.exe";
|
||||
//status = system(pImageName);
|
||||
//Need to check if repeater is already loaded
|
||||
//For now, start Repeater from a command line, not here
|
||||
status = 0;
|
||||
//status = _spawnlp(_P_DETACH,pImageName,"");
|
||||
|
||||
if(status<0){
|
||||
ca_printf("!!WARNING!!\n");
|
||||
ca_printf("Unable to locate the executable \"%s\".\n",
|
||||
@@ -229,26 +235,241 @@ void ca_spawn_repeater()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caSetDefaultPrintfHandler ()
|
||||
* use the normal default here
|
||||
* ( see access.c )
|
||||
*/
|
||||
void caSetDefaultPrintfHandler ()
|
||||
{
|
||||
ca_static->ca_printf_func = epicsVprintf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ca_printf()
|
||||
*
|
||||
* Network interface routines
|
||||
*
|
||||
*/
|
||||
int ca_printf(char *pformat, ...)
|
||||
|
||||
/*
|
||||
* local_addr()
|
||||
*
|
||||
* return 127.0.0.1
|
||||
* (the loop back address)
|
||||
*/
|
||||
int local_addr (SOCKET s, struct sockaddr_in *plcladdr)
|
||||
{
|
||||
va_list args;
|
||||
int status;
|
||||
ca_uint32_t loopBackAddress = 0x7f000001;
|
||||
|
||||
va_start(args, pformat);
|
||||
|
||||
status = vfprintf(
|
||||
stderr,
|
||||
pformat,
|
||||
args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return status;
|
||||
plcladdr->sin_family = AF_INET;
|
||||
plcladdr->sin_port = 0;
|
||||
plcladdr->sin_addr.s_addr = ntohl (loopBackAddress);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caDiscoverInterfaces()
|
||||
*
|
||||
* This routine is provided with the address of an ELLLIST a socket
|
||||
* and a destination port number. When the routine returns there
|
||||
* will be one additional inet address (a caAddrNode) in the list
|
||||
* for each inet interface found that is up and isnt a loop back
|
||||
* interface. If the interface supports broadcast then I add its
|
||||
* broadcast address to the list. If the interface is a point to
|
||||
* point link then I add the destination address of the point to
|
||||
* point link to the list. In either case I set the port number
|
||||
* in the address node to the port supplied in the argument
|
||||
* list.
|
||||
*
|
||||
* LOCK should be applied here for (pList)
|
||||
* (this is also called from the server)
|
||||
*/
|
||||
void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port)
|
||||
{
|
||||
struct sockaddr_in localAddr;
|
||||
struct sockaddr_in InetAddr;
|
||||
struct in_addr bcast_addr;
|
||||
caAddrNode *pNode;
|
||||
int status;
|
||||
|
||||
pNode = (caAddrNode *) calloc(1,sizeof(*pNode));
|
||||
if(!pNode){
|
||||
return;
|
||||
}
|
||||
broadcast_addr(&bcast_addr);
|
||||
pNode->destAddr.inetAddr.sin_addr.s_addr = bcast_addr.s_addr; //broadcast addr
|
||||
pNode->destAddr.inetAddr.sin_port = htons(port);
|
||||
pNode->destAddr.inetAddr.sin_family = AF_INET;
|
||||
//pNode->srcAddr.inetAddr = 0 ;//localAddr;
|
||||
|
||||
/*
|
||||
* LOCK applied externally
|
||||
*/
|
||||
ellAdd(pList, &pNode->node);
|
||||
}
|
||||
|
||||
int
|
||||
broadcast_addr( struct in_addr *pcastaddr )
|
||||
{
|
||||
char netmask[256], lhostname[80];
|
||||
static struct in_addr castaddr;
|
||||
int status;
|
||||
static char init = FALSE;
|
||||
struct hostent *phostent;
|
||||
unsigned long laddr;
|
||||
|
||||
if (init) {
|
||||
*pcastaddr = castaddr;
|
||||
return OK;
|
||||
}
|
||||
gethostname(lhostname,sizeof(lhostname));
|
||||
phostent = gethostbyname(lhostname);
|
||||
if (!phostent) {
|
||||
return MYERRNO;
|
||||
}
|
||||
|
||||
if (status = get_subnet_mask(netmask))
|
||||
return ERROR;
|
||||
|
||||
laddr = *( (unsigned long *) phostent->h_addr_list[0]);
|
||||
castaddr.s_addr = (laddr & inet_addr(netmask)) | ~inet_addr(netmask);
|
||||
|
||||
if (!init){
|
||||
init = TRUE;
|
||||
*pcastaddr = castaddr;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int get_subnet_mask ( char SubNetMaskStr[256])
|
||||
{
|
||||
char localadr[256];
|
||||
|
||||
return RegTcpParams (localadr, SubNetMaskStr);
|
||||
}
|
||||
|
||||
static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
|
||||
{
|
||||
#define MAX_VALUE_NAME 128
|
||||
static CHAR ValueName[MAX_VALUE_NAME];
|
||||
static CHAR RegPath[256];
|
||||
DWORD cbDataLen;
|
||||
CHAR cbData[256];
|
||||
DWORD dwType;
|
||||
int status;
|
||||
static char IpAddr[256], SubNetMask[256];
|
||||
|
||||
cbDataLen = sizeof(cbData);
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\1");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
|
||||
if (status) {
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\01");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
|
||||
strcat(RegPath,cbData);
|
||||
strcat(RegPath,"\\Parameters\\Tcpip");
|
||||
|
||||
cbDataLen = sizeof(IpAddr);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType, IpAddr, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
strcpy(IpAddrStr,IpAddr);
|
||||
|
||||
cbDataLen = sizeof(SubNetMask);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask", &dwType, SubNetMask, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
strcpy(SubNetMaskStr,SubNetMask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
|
||||
LPDWORD lpdwType, LPBYTE lpbData, LPDWORD lpcbData )
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD retCode;
|
||||
|
||||
DWORD dwcClassLen = MAX_PATH;
|
||||
|
||||
// OPEN THE KEY.
|
||||
|
||||
retCode = RegOpenKeyEx (hKeyRoot, // Key handle at root level.
|
||||
RegPath, // Path name of child key.
|
||||
0, // Reserved.
|
||||
KEY_QUERY_VALUE, // Requesting read access.
|
||||
&hKey); // Address of key to be returned.
|
||||
|
||||
if (retCode)
|
||||
{
|
||||
//wsprintf (Buf, "Error: RegOpenKeyEx = %d", retCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
retCode = RegQueryValueEx (hKey, // Key handle returned from RegOpenKeyEx.
|
||||
lpzValueName, // Name of value.
|
||||
NULL, // Reserved, dword = NULL.
|
||||
lpdwType, // Type of data.
|
||||
lpbData, // Data buffer.
|
||||
lpcbData); // Size of data buffer.
|
||||
|
||||
if (retCode)
|
||||
{
|
||||
//wsprintf (Buf, "Error: RegQIK = %d, %d", retCode, __LINE__);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
int status;
|
||||
WSADATA WsaData;
|
||||
|
||||
switch (dwReason) {
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
|
||||
if ((status = WSAStartup(MAKEWORD(1,1), &WsaData)) != 0)
|
||||
return FALSE;
|
||||
if (AllocConsole()) {
|
||||
SetConsoleTitle("Channel Access Status");
|
||||
freopen( "CONOUT$", "a", stderr );
|
||||
fprintf(stderr, "Process attached to ca.dll R12\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
||||
if ((status = WSACleanup()) !=0)
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
fprintf(stderr, "Thread attached to ca.dll R12\n");
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
fprintf(stderr, "Thread detached from ca.dll R12\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_LDLIBS = -lDb -lCom
|
||||
USR_LDLIBS = -lDb -lCom -lm
|
||||
USR_LDFLAGS = -L.
|
||||
|
||||
LEX = $(ELEX)
|
||||
|
||||
@@ -4,16 +4,16 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c = \
|
||||
../dbAccess.c ../dbBkpt.c ../dbFastLinkConv.c ../dbLink.c \
|
||||
../dbStaticLib.c ../iocInit.c ../drvTS.c ../dbScan.c \
|
||||
../dbNotify.c ../dbStaticLib.c ../iocInit.c ../drvTS.c ../dbScan.c \
|
||||
../dbEvent.c ../dbTest.c ../dbls.c ../db_access.c \
|
||||
../db_test.c ../recGbl.c ../callback.c ../taskwd.c \
|
||||
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c
|
||||
|
||||
OBJSdbLib = \
|
||||
dbAccess.o dbBkpt.o dbFastLinkConv.o dbLink.o dbStaticLib.o \
|
||||
iocInit.o drvTS.o dbScan.o dbEvent.o dbTest.o dbls.o db_access.o \
|
||||
db_test.o recGbl.o callback.o taskwd.o dbCaLink.o dbCaDblink.o \
|
||||
devLib.o
|
||||
dbAccess.o dbBkpt.o dbFastLinkConv.o dbLink.o dbNotify.o \
|
||||
dbStaticLib.o iocInit.o drvTS.o dbScan.o dbEvent.o dbTest.o dbls.o \
|
||||
db_access.o db_test.o recGbl.o callback.o taskwd.o dbCaLink.o \
|
||||
dbCaDblink.o devLib.o
|
||||
|
||||
|
||||
PROD = initHooks.o dbLib
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
b [a-zA-Z0-9_]
|
||||
a [ \t]
|
||||
d [a-zA-Z0-9_\,\./\*#\[\]%:;!|\'\-&\(\)@\?\+<>=$]
|
||||
d [a-zA-Z0-9_\,\./\*#\[\]%:;!|\'\-&\(\)@\?\+<>=$\^\~]
|
||||
|
||||
%{
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ junko: WORD
|
||||
yyerror(str)
|
||||
char *str;
|
||||
{
|
||||
sprintf(message,"Error line %d : %s\n",line_num, yytext);
|
||||
sprintf(message,"Error line %d : %s %s\n",line_num, yytext,str);
|
||||
errMessage(-1,message);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <callback.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <taskwd.h>
|
||||
#include <errMdef.h>
|
||||
#include <task_params.h>
|
||||
@@ -164,3 +166,22 @@ static void wdCallback(long ind)
|
||||
rngDelete(callbackQ[ind]);
|
||||
start(ind);
|
||||
}
|
||||
|
||||
static void ProcessCallback(CALLBACK *pCallback)
|
||||
{
|
||||
struct dbCommon *pRec;
|
||||
|
||||
callbackGetUser(pRec, pCallback);
|
||||
dbScanLock(pRec);
|
||||
((struct rset*)(pRec->rset))->process(pRec);
|
||||
dbScanUnlock(pRec);
|
||||
}
|
||||
void callbackRequestProcessCallback(CALLBACK *pCallback, int Priority, void *pRec)
|
||||
{
|
||||
callbackSetCallback(ProcessCallback, pCallback);
|
||||
callbackSetPriority(Priority, pCallback);
|
||||
callbackSetUser(pRec, pCallback);
|
||||
callbackRequest(pCallback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -117,12 +117,10 @@ long dbCommonInit();
|
||||
|
||||
/*
|
||||
* The lock structure for each database lock set. A lockset is the
|
||||
* connected graph of all adjacent nodes to a record. A record
|
||||
* is considered adjacent if the link connecting it to the lock
|
||||
* set causes that record to process. In other words, a record
|
||||
* is considered part of the lock set if the action of getting
|
||||
* or putting a value to that record (with a link) causes that
|
||||
* record to process.
|
||||
* connected graph of all adjacent nodes to a record (with one
|
||||
* exception, single-valued NPP NMS gets), where adjacent is defined
|
||||
* as a record connected by a get, put, or forward link to the current
|
||||
* record.
|
||||
*/
|
||||
struct scanLock {
|
||||
FAST_LOCK lock;
|
||||
@@ -190,8 +188,8 @@ void dbScanLock(struct dbCommon *precord)
|
||||
|
||||
/* Move range check to iocInit */
|
||||
if(lset < 0 || lset >= dbScanPvt.nset) {
|
||||
errMessage(S_db_badLset, "Lock Set out of range");
|
||||
exit(1);
|
||||
errMessage(S_db_badLset, "Lock Set out of range:dbScanLock");
|
||||
taskSuspend(taskIdSelf());
|
||||
}
|
||||
pscanLock = dbScanPvt.pscanLock + lset;
|
||||
FASTLOCK(&pscanLock->lock);
|
||||
@@ -212,10 +210,9 @@ void dbScanUnlock(struct dbCommon *precord)
|
||||
|
||||
/* Put check in iocInit() */
|
||||
if(lset<0 || lset>=dbScanPvt.nset) {
|
||||
errMessage(S_db_badLset,"Lock Set out of range");
|
||||
return;
|
||||
errMessage(S_db_badLset,"Lock Set out of range:dbScanUnlock");
|
||||
taskSuspend(taskIdSelf());
|
||||
}
|
||||
|
||||
pscanLock = dbScanPvt.pscanLock + lset;
|
||||
pscanLock->precord = NULL;
|
||||
FASTUNLOCK(&pscanLock->lock);
|
||||
@@ -264,64 +261,20 @@ long dbScanPassive(struct dbCommon *pfrom, struct dbCommon *pto)
|
||||
long status;
|
||||
|
||||
/* if not passive just return success */
|
||||
if (pto->scan != 0) return(0);
|
||||
if(pto->scan != 0) return(0);
|
||||
|
||||
if (pfrom && pfrom->ppn) {
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
|
||||
if (pto->ppn) { /*already being used. Abandon request*/
|
||||
ppn->status = S_db_Blocked;
|
||||
dbNotifyCompletion(ppn);
|
||||
} else {
|
||||
ppn->nwaiting++;
|
||||
pto->ppn = pfrom->ppn;
|
||||
/*If already active must redo*/
|
||||
if(pto->pact) ppn->rescan = TRUE;
|
||||
}
|
||||
}
|
||||
if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto);
|
||||
status = dbProcess(pto);
|
||||
if (pfrom && pfrom->ppn) {
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
|
||||
if (!pto->pact) {
|
||||
pto->ppn = NULL;
|
||||
} else { /*add to list of records for which to wait*/
|
||||
pto->ppnn = ppn->list;
|
||||
ppn->list = pto;
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
/*KLUDGE: Following needed so that dbPutLink to PROC field works correctly*/
|
||||
long dbScanLink(struct dbCommon *pfrom, struct dbCommon *pto)
|
||||
{
|
||||
long status;
|
||||
|
||||
if(pfrom && pfrom->ppn) {
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
|
||||
if(pto->ppn) { /*already being used. Abandon request*/
|
||||
ppn->status = S_db_Blocked;
|
||||
dbNotifyCompletion(ppn);
|
||||
} else {
|
||||
ppn->nwaiting++;
|
||||
pto->ppn = pfrom->ppn;
|
||||
/*If already active must redo*/
|
||||
if(pto->pact) ppn->rescan = TRUE;
|
||||
}
|
||||
}
|
||||
if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto);
|
||||
status = dbProcess(pto);
|
||||
if(pfrom && pfrom->ppn) {
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
|
||||
if(!pto->pact) {
|
||||
pto->ppn = NULL;
|
||||
} else { /*add to list of records for which to wait*/
|
||||
pto->ppnn = ppn->list;
|
||||
ppn->list = pto;
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -64,7 +65,7 @@
|
||||
#include <vxLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
|
||||
|
||||
#include <fast_lock.h>
|
||||
#include <alarm.h>
|
||||
#include <choice.h>
|
||||
@@ -681,7 +682,15 @@ int dbBkpt(struct dbCommon *precord)
|
||||
* breakpoint handler will not work as expected.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Take and give a semaphore to check for breakpoints
|
||||
* every time a record is processed. Slow. Thank
|
||||
* goodness breakpoint checking is turned off during
|
||||
* normal operation.
|
||||
*/
|
||||
semTake(bkpt_stack_sem, WAIT_FOREVER);
|
||||
FIND_LOCKSET(precord, pnode);
|
||||
semGive(bkpt_stack_sem);
|
||||
|
||||
if (pnode == NULL) {
|
||||
/* no breakpoints in precord's lockset */
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
* joh 21 080393 added task watch dog
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <epicsAssert.h>
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <types.h>
|
||||
@@ -591,12 +591,12 @@ int db_post_single_event(struct event_block *pevent)
|
||||
ev_que->valque[putix].sevr = sevr;
|
||||
ev_que->valque[putix].time = precord->time;
|
||||
/*
|
||||
* use bcopy to avoid a bus error on
|
||||
* use memcpy to avoid a bus error on
|
||||
* union copy of char in the db at an odd
|
||||
* address
|
||||
*/
|
||||
bcopy( pevent->paddr->pfield,
|
||||
(char *)&ev_que->valque[putix].field,
|
||||
memcpy( (char *)&ev_que->valque[putix].field,
|
||||
pevent->paddr->pfield,
|
||||
dbr_size[pevent->paddr->field_type]);
|
||||
}
|
||||
/* notify the event handler */
|
||||
@@ -669,12 +669,12 @@ unsigned int select
|
||||
ev_que->valque[putix].time = precord->time;
|
||||
|
||||
/*
|
||||
* use bcopy to avoid a bus error on
|
||||
* use memcpy to avoid a bus error on
|
||||
* union copy of char in the db at an odd
|
||||
* address
|
||||
*/
|
||||
bcopy( (char *)event->paddr->pfield,
|
||||
(char *)&ev_que->valque[putix].field,
|
||||
memcpy( (char *)&ev_que->valque[putix].field,
|
||||
(char *)event->paddr->pfield,
|
||||
dbr_size[event->paddr->field_type]);
|
||||
|
||||
}
|
||||
|
||||
248
src/db/dbLink.c
248
src/db/dbLink.c
@@ -182,7 +182,6 @@ long dbPutField(
|
||||
}
|
||||
dbScanLock(precord);
|
||||
status=dbPut(paddr,dbrType,pbuffer,nRequest);
|
||||
if(status) recGblDbaddrError(status,paddr,"dbPutField");
|
||||
if(status==0){
|
||||
if((paddr->pfield==(void *)&precord->proc)
|
||||
||(pfldDes->process_passive && precord->scan==0 && dbrType<DBR_PUT_ACKT)) {
|
||||
@@ -199,145 +198,6 @@ long dbPutField(
|
||||
return(status);
|
||||
}
|
||||
|
||||
static void notifyCallback(CALLBACK *pcallback)
|
||||
{
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
long status;
|
||||
|
||||
callbackGetUser(ppn,pcallback);
|
||||
if(ppn->cmd==notifyCmdRepeat) {
|
||||
status = dbPutNotify(ppn);
|
||||
} else if(ppn->cmd==notifyCmdCallUser) {
|
||||
(ppn->userCallback)(ppn);
|
||||
} else {/*illegal request*/
|
||||
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: illegal callback request");
|
||||
}
|
||||
}
|
||||
|
||||
static void notifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
while(precord) {
|
||||
void *pnext;
|
||||
|
||||
if(precord->rpro) {
|
||||
precord->rpro = FALSE;
|
||||
scanOnce(precord);
|
||||
}
|
||||
precord->ppn = NULL;
|
||||
pnext = precord->ppnn;
|
||||
precord->ppnn = NULL;
|
||||
precord = pnext;
|
||||
}
|
||||
ppn->list = NULL;
|
||||
}
|
||||
|
||||
void dbNotifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
dbScanLock(precord);
|
||||
notifyCancel(ppn);
|
||||
dbScanUnlock(precord);
|
||||
}
|
||||
|
||||
long dbPutNotify(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbAddr *paddr = ppn->paddr;
|
||||
short dbrType = ppn->dbrType;
|
||||
void *pbuffer = ppn->pbuffer;
|
||||
long nRequest = ppn->nRequest;
|
||||
long status=0;
|
||||
struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes);
|
||||
struct dbCommon *precord = (struct dbCommon *)(paddr->precord);
|
||||
|
||||
callbackSetCallback(notifyCallback,&ppn->callback);
|
||||
callbackSetUser(ppn,&ppn->callback);
|
||||
callbackSetPriority(priorityLow,&ppn->callback);
|
||||
/*check for putField disabled*/
|
||||
if(precord->disp) {
|
||||
if((void *)(&precord->disp) != paddr->pfield) {
|
||||
ppn->cmd = notifyCmdCallUser;
|
||||
ppn->status = S_db_putDisabled;
|
||||
notifyCallback(&ppn->callback);
|
||||
return(S_db_putDisabled);
|
||||
}
|
||||
}
|
||||
dbScanLock(precord);
|
||||
status=dbPut(paddr,dbrType,pbuffer,nRequest);
|
||||
if(status) recGblDbaddrError(status,paddr,"dbPutField");
|
||||
ppn->status = status;
|
||||
if(status==0){
|
||||
if((paddr->pfield==(void *)&precord->proc)
|
||||
||(pfldDes->process_passive && precord->scan==0)) {
|
||||
if(precord->ppn) {
|
||||
/*record already has attached ppn. Blocked*/
|
||||
|
||||
ppn->status = status = S_db_Blocked;
|
||||
return(status);
|
||||
}
|
||||
ppn->nwaiting = 1;
|
||||
ppn->rescan = FALSE;
|
||||
ppn->list = NULL;
|
||||
precord->ppn = ppn;
|
||||
precord->ppnn = NULL;
|
||||
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
|
||||
ppn->rescan = TRUE;
|
||||
ppn->status = status = S_db_Pending;
|
||||
return(status);
|
||||
}
|
||||
status=dbProcess(precord);
|
||||
if(status==0) {
|
||||
if(!precord->pact) {
|
||||
precord->ppn = NULL;
|
||||
} else {
|
||||
precord->ppnn = ppn->list;
|
||||
ppn->list = precord;
|
||||
}
|
||||
ppn->status = status = ((ppn->nwaiting == 0) ? 0 : S_db_Pending);
|
||||
} else {
|
||||
ppn->status = status;
|
||||
notifyCancel(ppn);
|
||||
}
|
||||
} else { /*Make callback immediately*/
|
||||
ppn->cmd = notifyCmdCallUser;
|
||||
ppn->status = 0;
|
||||
notifyCallback(&ppn->callback);
|
||||
}
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
return(status);
|
||||
}
|
||||
|
||||
void dbNotifyCompletion(PUTNOTIFY *ppn)
|
||||
{
|
||||
|
||||
if(ppn->status!=0 && ppn->status!=S_db_Pending) {
|
||||
ppn->cmd = notifyCmdCallUser;
|
||||
notifyCancel(ppn);
|
||||
callbackRequest(&ppn->callback);
|
||||
return;
|
||||
}
|
||||
/*decrement number of records being waited on*/
|
||||
if(ppn->nwaiting<=0) {
|
||||
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: nwaiting<-0 LOGIC");
|
||||
return;
|
||||
}
|
||||
if(--ppn->nwaiting == 0) {/*original request completed*/
|
||||
notifyCancel(ppn);
|
||||
if(ppn->rescan) {
|
||||
ppn->cmd = notifyCmdRepeat;
|
||||
callbackRequest(&ppn->callback);
|
||||
} else {
|
||||
/*issue completion callback*/
|
||||
ppn->cmd = notifyCmdCallUser;
|
||||
if(ppn->status==S_db_Pending) ppn->status = 0;
|
||||
callbackRequest(&ppn->callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long dbValueSize(
|
||||
short dbr_type
|
||||
)
|
||||
@@ -3530,7 +3390,7 @@ long offset;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static long putStringEnum(paddr,pbuffer,nRequest,no_elements,offset)
|
||||
struct dbAddr *paddr;
|
||||
char *pbuffer;
|
||||
@@ -3538,15 +3398,41 @@ long nRequest;
|
||||
long no_elements;
|
||||
long offset;
|
||||
{
|
||||
struct rset *prset;
|
||||
short record_type=(paddr->record_type);
|
||||
long status;
|
||||
struct rset *prset;
|
||||
short record_type=(paddr->record_type);
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
long status;
|
||||
unsigned int nchoices,ind;
|
||||
int nargs,nchars;
|
||||
struct dbr_enumStrs enumStrs;
|
||||
|
||||
if((prset=GET_PRSET(pdbBase->precSup,record_type)) && (prset->put_enum_str))
|
||||
return( (*prset->put_enum_str)(paddr,pbuffer) );
|
||||
status=S_db_noRSET;
|
||||
recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
|
||||
return(S_db_badDbrtype);
|
||||
if((prset=GET_PRSET(pdbBase->precSup,record_type))
|
||||
&& (prset->put_enum_str)) {
|
||||
status = (*prset->put_enum_str)(paddr,pbuffer);
|
||||
if(!status) return(0);
|
||||
if(prset->get_enum_strs) {
|
||||
status = (*prset->get_enum_strs)(paddr,&enumStrs);
|
||||
if(!status) {
|
||||
nchoices = enumStrs.no_str;
|
||||
nargs = sscanf(pbuffer," %u %n",&ind,&nchars);
|
||||
if(nargs==1 && nchars==strlen(pbuffer) && ind<nchoices) {
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
status = S_db_badChoice;
|
||||
}
|
||||
}else {
|
||||
status=S_db_noRSET;
|
||||
}
|
||||
} else {
|
||||
status=S_db_noRSET;
|
||||
}
|
||||
if(status == S_db_noRSET) {
|
||||
recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
|
||||
} else {
|
||||
recGblDbaddrError(status,paddr,"dbPut(putStringEnum)");
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putStringGchoice(paddr,pbuffer,nRequest,no_elements,offset)
|
||||
@@ -3560,20 +3446,27 @@ long offset;
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
char *pchoice;
|
||||
struct choiceSet *pchoiceSet;
|
||||
unsigned short i;
|
||||
unsigned int nchoices,ind;
|
||||
int nargs,nchars;
|
||||
|
||||
if(no_elements!=1){
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringGchoice)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if(pchoiceSet=GET_PCHOICE_SET(pdbBase->pchoiceGbl,choice_set)) {
|
||||
for(i=0; i<pchoiceSet->number; i++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[i])) continue;
|
||||
nchoices = pchoiceSet->number;
|
||||
for(ind=0; ind<nchoices; ind++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[ind])) continue;
|
||||
if(strcmp(pchoice,pbuffer)==0) {
|
||||
*pfield=i;
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
nargs = sscanf(pbuffer," %u %n",&ind,&nchars);
|
||||
if(nargs==1 && nchars==strlen(pbuffer) && ind<nchoices) {
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbPut(putStringGchoice)");
|
||||
return(S_db_badChoice);
|
||||
@@ -3589,20 +3482,27 @@ long offset;
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
char *pchoice;
|
||||
struct choiceSet *pchoiceSet;
|
||||
unsigned short i;
|
||||
unsigned int nchoices,ind;
|
||||
int nargs,nchars;
|
||||
|
||||
if(no_elements!=1){
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringCchoice)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if(pchoiceSet=pdbBase->pchoiceCvt) {
|
||||
for(i=0; i<pchoiceSet->number; i++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[i])) continue;
|
||||
nchoices = pchoiceSet->number;
|
||||
for(ind=0; ind<nchoices; ind++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[ind])) continue;
|
||||
if(strcmp(pchoice,pbuffer)==0) {
|
||||
*pfield=i;
|
||||
*pfield=ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
nargs = sscanf(pbuffer," %u %n",&ind,&nchars);
|
||||
if(nargs==1 && nchars==strlen(pbuffer) && ind<nchoices) {
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbPut(putStringCchoice)");
|
||||
return(S_db_badChoice);
|
||||
@@ -3620,7 +3520,8 @@ long offset;
|
||||
char *pchoice;
|
||||
struct choiceSet *pchoiceSet;
|
||||
struct arrChoiceSet *parrChoiceSet;
|
||||
unsigned short i;
|
||||
unsigned int nchoices,ind;
|
||||
int nargs,nchars;
|
||||
|
||||
if(no_elements!=1){
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringRchoice)");
|
||||
@@ -3628,13 +3529,19 @@ long offset;
|
||||
}
|
||||
if((parrChoiceSet=GET_PARR_CHOICE_SET(pdbBase->pchoiceRec,(paddr->record_type)))
|
||||
&& (pchoiceSet=GET_PCHOICE_SET(parrChoiceSet,choice_set))) {
|
||||
for(i=0; i<pchoiceSet->number; i++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[i])) continue;
|
||||
nchoices = pchoiceSet->number;
|
||||
for(ind=0; ind<nchoices; ind++) {
|
||||
if(!(pchoice=pchoiceSet->papChoice[ind])) continue;
|
||||
if(strcmp(pchoice,pbuffer)==0) {
|
||||
*pfield=i;
|
||||
*pfield=ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
nargs = sscanf(pbuffer," %u %n",&ind,&nchars);
|
||||
if(nargs==1 && nchars==strlen(pbuffer) && ind<nchoices) {
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbPut(putStringRchoice)");
|
||||
return(S_db_badChoice);
|
||||
@@ -3650,20 +3557,27 @@ long offset;
|
||||
unsigned short *pfield= (unsigned short*)(paddr->pfield);
|
||||
struct devChoiceSet *pdevChoiceSet;
|
||||
char *pchoice;
|
||||
unsigned short i;
|
||||
unsigned int nchoices,ind;
|
||||
int nargs,nchars;
|
||||
|
||||
if(no_elements!=1){
|
||||
recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringDchoice)");
|
||||
return(S_db_onlyOne);
|
||||
}
|
||||
if(pdevChoiceSet=GET_PDEV_CHOICE_SET(pdbBase->pchoiceDev,paddr->record_type)) {
|
||||
for(i=0; i<pdevChoiceSet->number; i++) {
|
||||
if(!(pchoice=pdevChoiceSet->papDevChoice[i]->pchoice)) continue;
|
||||
nchoices = pdevChoiceSet->number;
|
||||
for(ind=0; ind<nchoices; ind++) {
|
||||
if(!(pchoice=pdevChoiceSet->papDevChoice[ind]->pchoice)) continue;
|
||||
if(strcmp(pchoice,pbuffer)==0) {
|
||||
*pfield=i;
|
||||
*pfield=ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
nargs = sscanf(pbuffer," %u %n",&ind,&nchars);
|
||||
if(nargs==1 && nchars==strlen(pbuffer) && ind<nchoices) {
|
||||
*pfield = ind;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbPut(putStringDchoice)");
|
||||
return(S_db_badChoice);
|
||||
@@ -5875,7 +5789,9 @@ long dbPut(
|
||||
if(special) {
|
||||
if(special<100) { /*global processing*/
|
||||
if(special==SPC_NOMOD) {
|
||||
return(S_db_noMod);
|
||||
status = S_db_noMod;
|
||||
recGblDbaddrError(status,paddr,"dbPut");
|
||||
return(status);
|
||||
}else if(special==SPC_SCAN){
|
||||
scanDelete(precord);
|
||||
}
|
||||
|
||||
229
src/db/dbNotify.c
Normal file
229
src/db/dbNotify.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/* dbNotify.c */
|
||||
/* base/src/db $Id$ */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 03-30-95
|
||||
* Extracted from dbLink.c
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 03-30-95 mrk Extracted from dbLink.c
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <fast_lock.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <dbScan.h>
|
||||
#include <dbCommon.h>
|
||||
#include <errMdef.h>
|
||||
|
||||
static void notifyCallback(CALLBACK *pcallback)
|
||||
{
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
long status;
|
||||
|
||||
callbackGetUser(ppn,pcallback);
|
||||
if(ppn->cmd==notifyCmdRepeat) {
|
||||
status = dbPutNotify(ppn);
|
||||
} else if(ppn->cmd==notifyCmdCallUser) {
|
||||
ppn->cmd = notifyUserCalled;
|
||||
(ppn->userCallback)(ppn);
|
||||
} else {/*illegal request*/
|
||||
recGblRecordError(-1,ppn->paddr->precord,
|
||||
"dbNotifyCompletion: illegal callback request");
|
||||
}
|
||||
}
|
||||
|
||||
static void notifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
while(precord) {
|
||||
void *pnext;
|
||||
|
||||
if(precord->rpro) {
|
||||
precord->rpro = FALSE;
|
||||
scanOnce(precord);
|
||||
}
|
||||
precord->ppn = NULL;
|
||||
pnext = precord->ppnn;
|
||||
precord->ppnn = NULL;
|
||||
precord = pnext;
|
||||
}
|
||||
ppn->list = NULL;
|
||||
}
|
||||
|
||||
void dbNotifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
if(!precord) return;
|
||||
dbScanLock(precord);
|
||||
notifyCancel(ppn);
|
||||
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
|
||||
/*Bad lets try one time to wait*/
|
||||
dbScanUnlock(precord);
|
||||
taskDelay(10);
|
||||
dbScanLock(precord);
|
||||
}
|
||||
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
|
||||
epicsPrintf("dbNotifyCancel called while callback requested"
|
||||
" but not called\n");
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
}
|
||||
|
||||
static void issueCallback(PUTNOTIFY *ppn, notifyCmd cmd)
|
||||
{
|
||||
if(ppn->cmd!=notifyCmdNull) return;
|
||||
ppn->cmd = cmd;
|
||||
notifyCancel(ppn);
|
||||
callbackRequest(&ppn->callback);
|
||||
}
|
||||
|
||||
long dbPutNotify(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbAddr *paddr = ppn->paddr;
|
||||
short dbrType = ppn->dbrType;
|
||||
void *pbuffer = ppn->pbuffer;
|
||||
long nRequest = ppn->nRequest;
|
||||
long status=0;
|
||||
struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes);
|
||||
struct dbCommon *precord = (struct dbCommon *)(paddr->precord);
|
||||
|
||||
callbackSetCallback(notifyCallback,&ppn->callback);
|
||||
callbackSetUser(ppn,&ppn->callback);
|
||||
callbackSetPriority(priorityLow,&ppn->callback);
|
||||
/*check for putField disabled*/
|
||||
if(precord->disp) {
|
||||
if((void *)(&precord->disp) != paddr->pfield) {
|
||||
ppn->status = S_db_putDisabled;
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
return(S_db_putDisabled);
|
||||
}
|
||||
}
|
||||
ppn->status = 0;
|
||||
ppn->cmd = notifyCmdNull;
|
||||
ppn->nwaiting = 1;
|
||||
ppn->rescan = FALSE;
|
||||
dbScanLock(precord);
|
||||
status=dbPut(paddr,dbrType,pbuffer,nRequest);
|
||||
ppn->status = status;
|
||||
if(status==0){
|
||||
if((paddr->pfield==(void *)&precord->proc)
|
||||
||(pfldDes->process_passive && precord->scan==0)) {
|
||||
if(precord->ppn) {
|
||||
/*record already has attached ppn. Blocked*/
|
||||
|
||||
ppn->status = status = S_db_Blocked;
|
||||
dbScanUnlock(precord);
|
||||
return(status);
|
||||
}
|
||||
precord->ppn = ppn;
|
||||
precord->ppnn = NULL;
|
||||
ppn->list = precord;
|
||||
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
|
||||
ppn->rescan = TRUE;
|
||||
dbScanUnlock(precord);
|
||||
return(S_db_Pending);
|
||||
}
|
||||
status=dbProcess(precord);
|
||||
if(status!=0) {
|
||||
ppn->status = status;
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
}
|
||||
} else { /*Make callback immediately*/
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
}
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
return(S_db_Pending);
|
||||
}
|
||||
|
||||
void dbNotifyCompletion(PUTNOTIFY *ppn)
|
||||
{
|
||||
|
||||
if(ppn->status!=0) {
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
return;
|
||||
}
|
||||
/*decrement number of records being waited on*/
|
||||
if(ppn->nwaiting<=0) {
|
||||
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: nwaiting<-0 LOGIC");
|
||||
return;
|
||||
}
|
||||
if(--ppn->nwaiting == 0) {/*original request completed*/
|
||||
if(ppn->rescan) {
|
||||
issueCallback(ppn,notifyCmdRepeat);
|
||||
} else {
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Remove all nonactive records from put notify list*/
|
||||
void cleanPpList(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
struct dbCommon *pnext;
|
||||
struct dbCommon *pprev=NULL;
|
||||
|
||||
while(precord) {
|
||||
pnext = precord->ppnn;
|
||||
if(!precord->pact) {
|
||||
if(!pprev) ppn->list = pnext; else pprev->ppnn = pnext;
|
||||
precord->ppn = NULL;
|
||||
precord->ppnn = NULL;
|
||||
} else {
|
||||
pprev = precord;
|
||||
}
|
||||
precord = pnext;
|
||||
}
|
||||
}
|
||||
|
||||
void dbNotifyAdd(struct dbCommon *pfrom, struct dbCommon *pto)
|
||||
{
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
|
||||
if(pto->ppn) cleanPpList(pto->ppn); /* clean list before giving up*/
|
||||
if (pto->ppn) { /*already being used. Abandon request*/
|
||||
ppn->status = S_db_Blocked;
|
||||
dbNotifyCompletion(ppn);
|
||||
} else {
|
||||
ppn->nwaiting++;
|
||||
pto->ppn = pfrom->ppn;
|
||||
pto->ppnn = ppn->list;
|
||||
ppn->list = pto;
|
||||
/*If already active must redo*/
|
||||
if(pto->pact) ppn->rescan = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -486,7 +486,7 @@ got_record:
|
||||
recGblDbaddrError(status,&dbAddr,"initPeriodic");
|
||||
exit(1);
|
||||
}
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(struct scan_list));
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(struct scan_list*));
|
||||
periodicTaskId = dbCalloc(nPeriodic,sizeof(int));
|
||||
for(i=0; i<nPeriodic; i++) {
|
||||
psl = dbCalloc(1,sizeof(struct scan_list));
|
||||
|
||||
@@ -97,6 +97,11 @@ static char *promptCAMAC_IO[] = {
|
||||
"subaddress:",
|
||||
" function:",
|
||||
" parameter:"};
|
||||
static char *promptRF_IO[] = {
|
||||
" cryo:",
|
||||
" micro:",
|
||||
" dataset:",
|
||||
" element:"};
|
||||
static char *promptAB_IO[] = {
|
||||
" link:",
|
||||
" adapter:",
|
||||
@@ -149,6 +154,7 @@ static void initForms()
|
||||
promptAddr[PV_LINK] = promptPV_LINK; formlines[PV_LINK] = 4;
|
||||
promptAddr[VME_IO] = promptVME_IO; formlines[VME_IO] = 3;
|
||||
promptAddr[CAMAC_IO] = promptCAMAC_IO; formlines[CAMAC_IO] = 6;
|
||||
promptAddr[RF_IO] = promptRF_IO; formlines[RF_IO] = 4;
|
||||
promptAddr[AB_IO] = promptAB_IO; formlines[AB_IO] = 6;
|
||||
promptAddr[GPIB_IO] = promptGPIB_IO; formlines[GPIB_IO] = 3;
|
||||
promptAddr[BITBUS_IO]= promptBITBUS_IO;formlines[BITBUS_IO]= 5;
|
||||
@@ -1338,6 +1344,13 @@ DBENTRY *pdbentry;
|
||||
plink->value.camacio.n,plink->value.camacio.a,
|
||||
plink->value.camacio.f,plink->value.camacio.parm);
|
||||
break;
|
||||
case RF_IO:
|
||||
sprintf(message,"#R%d M%d D%d E%d",
|
||||
plink->value.rfio.cryo,
|
||||
plink->value.rfio.micro,
|
||||
plink->value.rfio.dataset,
|
||||
plink->value.rfio.element);
|
||||
break;
|
||||
case AB_IO:
|
||||
sprintf(message,"#L%d A%d C%d S%d F%d @%s",
|
||||
plink->value.abio.link,plink->value.abio.adapter,
|
||||
@@ -1595,6 +1608,7 @@ char *pstring;
|
||||
DBLINK *plink=(DBLINK *)pfield;
|
||||
char string[80];
|
||||
char *pstr=&string[0];
|
||||
int ind;
|
||||
|
||||
if(strlen(pstring)>=sizeof(string)) {
|
||||
status = S_dbLib_badField;
|
||||
@@ -1604,6 +1618,11 @@ char *pstring;
|
||||
strcpy(pstr,pstring);
|
||||
/*strip off leading blanks and tabs*/
|
||||
while(*pstr && (*pstr==' ' || *pstr=='\t')) pstr++;
|
||||
/*strip off trailing blanks and tabs*/
|
||||
if(pstr) for(ind = strlen(pstr)-1; ind>=0; ind--) {
|
||||
if(pstr[ind]!=' ' && pstr[ind]!='\t') break;
|
||||
pstr[ind] = '\0';
|
||||
}
|
||||
if(!pstr || strlen(pstr)<=0 ) {
|
||||
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
|
||||
if(plink->type!=CONSTANT) return(S_dbLib_badField);
|
||||
@@ -1615,14 +1634,15 @@ char *pstring;
|
||||
int pp=0;
|
||||
int ms=0;
|
||||
char *end;
|
||||
char chr;
|
||||
double tempval;
|
||||
|
||||
/* Check first to see if string is a constant*/
|
||||
chr = pstr[0];
|
||||
if(isdigit(chr) || chr=='.' || chr=='-' || chr=='+') {
|
||||
/*It is a double if strtod eats entire string*/
|
||||
/*Note that leading and trailing blanks have already been stripped*/
|
||||
tempval = strtod(pstr,&end);
|
||||
if(*end == 0) {
|
||||
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
|
||||
plink->value.value = strtod(pstr,&end);
|
||||
if(*end!=0) return(S_dbLib_badField);
|
||||
plink->value.value = tempval;
|
||||
return(0);
|
||||
}
|
||||
if(plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry);
|
||||
@@ -1682,6 +1702,25 @@ char *pstring;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RF_IO: {
|
||||
char *end;
|
||||
|
||||
if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
if(!(end = strchr(pstr,'R'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.rfio.cryo);
|
||||
if(!(end = strchr(pstr,'M'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.rfio.micro);
|
||||
if(!(end = strchr(pstr,'D'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.rfio.dataset);
|
||||
if(!(end = strchr(pstr,'E'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.rfio.element);
|
||||
}
|
||||
break;
|
||||
case AB_IO: {
|
||||
char *end;
|
||||
|
||||
@@ -2459,6 +2498,15 @@ DBENTRY *pdbentry;
|
||||
value++;
|
||||
strcpy(*value,plink->value.camacio.parm);
|
||||
break;
|
||||
case RF_IO:
|
||||
cvtShortToString(plink->value.rfio.cryo,*value);
|
||||
value++;
|
||||
cvtShortToString(plink->value.rfio.micro,*value);
|
||||
value++;
|
||||
cvtShortToString(plink->value.rfio.dataset,*value);
|
||||
value++;
|
||||
cvtShortToString(plink->value.rfio.element,*value);
|
||||
break;
|
||||
case AB_IO:
|
||||
cvtShortToString(plink->value.abio.link,*value);
|
||||
value++;
|
||||
@@ -2627,6 +2675,35 @@ char **value;
|
||||
value++; verify++;
|
||||
strncpy(plink->value.camacio.parm,*value,CAMAC_PARAM_SZ-1);
|
||||
break;
|
||||
case RF_IO:
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
if(*endp==0) {
|
||||
plink->value.rfio.cryo = lvalue; **verify = 0;
|
||||
} else {
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
if(*endp==0) {
|
||||
plink->value.rfio.micro = lvalue; **verify = 0;
|
||||
} else {
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
if(*endp==0) {
|
||||
plink->value.rfio.dataset = lvalue; **verify = 0;
|
||||
} else {
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
value++; verify++;
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
if(*endp==0) {
|
||||
plink->value.rfio.element = lvalue; **verify = 0;
|
||||
} else {
|
||||
strcpy(*verify,"Illegal. Must be number");
|
||||
}
|
||||
break;
|
||||
case AB_IO:
|
||||
lvalue = strtol(*value,&endp,0);
|
||||
if(*endp==0) {
|
||||
|
||||
@@ -813,6 +813,7 @@ int dbhcr(void)
|
||||
return(0);
|
||||
}
|
||||
dbReportDeviceConfig(pdbBase,stdout);
|
||||
fflush(stdout);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ char *filename;
|
||||
|
||||
/* load data base record name to pvName */
|
||||
str = pvName[0];
|
||||
bzero(str,1000*31);
|
||||
memset(str,0,1000*31);
|
||||
|
||||
pdbbase=dbAllocBase();
|
||||
pdbentry=dbAllocEntry(pdbbase);
|
||||
|
||||
169
src/db/devLib.c
169
src/db/devLib.c
@@ -1,5 +1,5 @@
|
||||
/* devLib.c - support for allocation of common device resources */
|
||||
/* @(#)devLib.c 1.2 3/30/94 */
|
||||
/* @(#)$Id$*/
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
@@ -45,12 +45,13 @@
|
||||
* .08 05-28-93 joh Added an argument to devRegisterAddress()
|
||||
* .09 05-28-93 joh Added devAddressMap()
|
||||
* .10 06-14-93 joh Added devAllocAddress()
|
||||
* .11 02-21-95 joh Fixed warning messages
|
||||
*
|
||||
* NOTES:
|
||||
* .01 06-14-93 joh needs devAllocInterruptVector() routine
|
||||
*/
|
||||
|
||||
static char *sccsID = "@(#)devLib.c 1.2\t3/30/94";
|
||||
static char *sccsID = "@(#) $Id$";
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
@@ -91,8 +92,8 @@ LOCAL char addrListInit;
|
||||
typedef struct{
|
||||
NODE node;
|
||||
const char *pOwnerName;
|
||||
void *pFirst;
|
||||
void *pLast;
|
||||
char *pFirst;
|
||||
char *pLast;
|
||||
}rangeItem;
|
||||
|
||||
/*
|
||||
@@ -103,7 +104,8 @@ LOCAL char *defaultHandlerNames[] = {
|
||||
"_excStub",
|
||||
"_excIntStub",
|
||||
"_unsolicitedHandlerEPICS"};
|
||||
LOCAL void *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)];
|
||||
typedef void myISR (void *pParam);
|
||||
LOCAL myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)];
|
||||
|
||||
/*
|
||||
* These routines are not exported
|
||||
@@ -112,21 +114,21 @@ LOCAL void initHandlerAddrList(void);
|
||||
LOCAL int vectorInUse(unsigned vectorNumber);
|
||||
LOCAL long initAddrList(void);
|
||||
LOCAL long addrVerify(epicsAddressType addrType, void *address);
|
||||
LOCAL void (*isrFetch(unsigned vectorNumber))();
|
||||
LOCAL myISR *isrFetch(unsigned vectorNumber);
|
||||
LOCAL long blockFind(
|
||||
epicsAddressType addrType,
|
||||
void *pBlockFirst,
|
||||
void *pBlockLast,
|
||||
char *pBlockFirst,
|
||||
char *pBlockLast,
|
||||
/* size needed */
|
||||
unsigned long size,
|
||||
/* n ls bits zero in base addr */
|
||||
unsigned alignment,
|
||||
/* base address found */
|
||||
void **ppBase);
|
||||
char **ppBase);
|
||||
LOCAL long report_conflict(
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast,
|
||||
char *pFirst,
|
||||
char *pLast,
|
||||
const char *pOwnerName);
|
||||
LOCAL long devInsertAddress(
|
||||
LIST *pRangeList,
|
||||
@@ -140,25 +142,25 @@ LOCAL long devInstallAddr(
|
||||
rangeItem *pRange,
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast,
|
||||
char *pFirst,
|
||||
char *pLast,
|
||||
void **pLocalAddress);
|
||||
LOCAL long blockDivide(
|
||||
epicsAddressType addrType,
|
||||
void *pBlockFirst,
|
||||
void *pBlockLast,
|
||||
char *pBlockFirst,
|
||||
char *pBlockLast,
|
||||
/* base address found */
|
||||
void **ppBase,
|
||||
char **ppBase,
|
||||
unsigned long requestSize
|
||||
);
|
||||
LOCAL long blockProbe(
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast
|
||||
char *pFirst,
|
||||
char *pLast
|
||||
);
|
||||
long locationProbe(
|
||||
epicsAddressType addrType,
|
||||
void *pLocation
|
||||
char *pLocation
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -336,8 +338,8 @@ void *baseAddress,
|
||||
unsigned long size,
|
||||
void **pLocalAddress)
|
||||
{
|
||||
void *pFirst;
|
||||
void *pLast;
|
||||
char *pFirst;
|
||||
char *pLast;
|
||||
rangeItem *pRange;
|
||||
long s;
|
||||
|
||||
@@ -357,7 +359,7 @@ void **pLocalAddress)
|
||||
return S_dev_lowValue;
|
||||
}
|
||||
|
||||
pFirst = baseAddress;
|
||||
pFirst = (char *) baseAddress;
|
||||
pLast = pFirst + size - 1;
|
||||
|
||||
FASTLOCK(&addrListLock);
|
||||
@@ -407,25 +409,26 @@ LOCAL long devInstallAddr(
|
||||
rangeItem *pRange, /* item on the free list to be split */
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast,
|
||||
void **pLocalAddress)
|
||||
char *pFirst,
|
||||
char *pLast,
|
||||
void **ppLocalAddress)
|
||||
{
|
||||
rangeItem *pNewRange;
|
||||
int s;
|
||||
|
||||
if(pLocalAddress){
|
||||
int s1;
|
||||
int s2;
|
||||
if(ppLocalAddress){
|
||||
char *pAddr;
|
||||
int s1;
|
||||
int s2;
|
||||
|
||||
s1 = sysBusToLocalAdrs(
|
||||
EPICStovxWorksAddrType[addrType],
|
||||
pLast,
|
||||
(char **)pLocalAddress);
|
||||
&pAddr);
|
||||
s2 = sysBusToLocalAdrs(
|
||||
EPICStovxWorksAddrType[addrType],
|
||||
pFirst,
|
||||
(char **)pLocalAddress);
|
||||
&pAddr);
|
||||
if(s1 || s2){
|
||||
errPrintf(
|
||||
S_dev_vxWorksAddrMapFail,
|
||||
@@ -437,6 +440,8 @@ void **pLocalAddress)
|
||||
pLast-pFirst+1);
|
||||
return S_dev_vxWorksAddrMapFail;
|
||||
}
|
||||
|
||||
*ppLocalAddress = (void *) pAddr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -505,8 +510,8 @@ void **pLocalAddress)
|
||||
*/
|
||||
LOCAL long report_conflict(
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast,
|
||||
char *pFirst,
|
||||
char *pLast,
|
||||
const char *pOwnerName
|
||||
)
|
||||
{
|
||||
@@ -567,6 +572,7 @@ epicsAddressType addrType,
|
||||
void *baseAddress,
|
||||
const char *pOwnerName)
|
||||
{
|
||||
char *charAddress = (char *) baseAddress;
|
||||
rangeItem *pRange;
|
||||
int s;
|
||||
|
||||
@@ -577,7 +583,7 @@ const char *pOwnerName)
|
||||
}
|
||||
}
|
||||
|
||||
s = addrVerify(addrType, baseAddress);
|
||||
s = addrVerify(addrType, charAddress);
|
||||
if(s != SUCCESS){
|
||||
return s;
|
||||
}
|
||||
@@ -585,10 +591,10 @@ const char *pOwnerName)
|
||||
FASTLOCK(&addrListLock);
|
||||
pRange = (rangeItem *) addrAlloc[addrType].node.next;
|
||||
while(pRange){
|
||||
if(pRange->pFirst == baseAddress){
|
||||
if(pRange->pFirst == charAddress){
|
||||
break;
|
||||
}
|
||||
if(pRange->pFirst > baseAddress){
|
||||
if(pRange->pFirst > charAddress){
|
||||
pRange = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -608,7 +614,7 @@ const char *pOwnerName)
|
||||
__LINE__,
|
||||
"unregister address for %s at 0X %X failed because %s owns it",
|
||||
pOwnerName,
|
||||
baseAddress,
|
||||
charAddress,
|
||||
pRange->pOwnerName);
|
||||
return s;
|
||||
}
|
||||
@@ -730,7 +736,7 @@ void **pLocalAddress)
|
||||
{
|
||||
int s;
|
||||
rangeItem *pRange;
|
||||
void *pBase;
|
||||
char *pBase;
|
||||
|
||||
s = addrVerify(addrType, (void *)size);
|
||||
if(s){
|
||||
@@ -745,9 +751,6 @@ void **pLocalAddress)
|
||||
pRange = (rangeItem *) addrFree[addrType].node.next;
|
||||
while(pRange){
|
||||
if(pRange->pLast-pRange->pFirst>=size-1){
|
||||
void *pF;
|
||||
void *pL;
|
||||
|
||||
s = blockFind(
|
||||
addrType,
|
||||
pRange->pFirst,
|
||||
@@ -875,9 +878,11 @@ LOCAL long devListAddressMap(LIST *pRangeList)
|
||||
printf("%s Address Map\n", epicsAddressTypeName[i]);
|
||||
}
|
||||
while(pri){
|
||||
printf("0X %08X - %08X %s\n",
|
||||
pri->pFirst,
|
||||
pri->pLast,
|
||||
printf("0X %0*lX - %0*lX %s\n",
|
||||
(int) (sizeof (pri->pFirst) * 2U),
|
||||
(unsigned long) pri->pFirst,
|
||||
(int) (sizeof (pri->pFirst) * 2U),
|
||||
(unsigned long) pri->pLast,
|
||||
pri->pOwnerName);
|
||||
pri = (rangeItem *) lstNext(&pri->node);
|
||||
}
|
||||
@@ -923,9 +928,9 @@ void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
LOCAL
|
||||
void initHandlerAddrList(void)
|
||||
{
|
||||
int i;
|
||||
UINT8 type;
|
||||
int status;
|
||||
int i;
|
||||
SYM_TYPE type;
|
||||
int status;
|
||||
|
||||
for(i=0; i<NELEMENTS(defaultHandlerNames); i++){
|
||||
status =
|
||||
@@ -951,18 +956,17 @@ void initHandlerAddrList(void)
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void (*isrFetch(unsigned vectorNumber))()
|
||||
LOCAL myISR *isrFetch(unsigned vectorNumber)
|
||||
{
|
||||
void (*psub)();
|
||||
void (*pCISR)();
|
||||
myISR *psub;
|
||||
myISR *pCISR;
|
||||
void *pParam;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* fetch the handler or C stub attached at this vector
|
||||
*/
|
||||
psub = (void (*)()) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber));
|
||||
psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber));
|
||||
|
||||
/*
|
||||
* from libvxWorks/veclist.c
|
||||
@@ -993,7 +997,7 @@ unsigned vectorNumber
|
||||
{
|
||||
static int init;
|
||||
int i;
|
||||
void (*psub)();
|
||||
myISR *psub;
|
||||
|
||||
if(!init){
|
||||
initHandlerAddrList();
|
||||
@@ -1026,11 +1030,11 @@ unsigned vectorNumber
|
||||
*/
|
||||
LOCAL long blockFind(
|
||||
epicsAddressType addrType,
|
||||
void *pBlockFirst,
|
||||
void *pBlockLast,
|
||||
char *pBlockFirst,
|
||||
char *pBlockLast,
|
||||
unsigned long size, /* size needed */
|
||||
unsigned alignment, /* n ls bits zero in base addr */
|
||||
void **ppBase /* base address found */
|
||||
char **ppBase /* base address found */
|
||||
)
|
||||
{
|
||||
int s;
|
||||
@@ -1041,7 +1045,7 @@ void **ppBase /* base address found */
|
||||
*/
|
||||
mask = devCreateMask(alignment);
|
||||
if(mask&(long)pBlockFirst){
|
||||
pBlockFirst = (void *) (mask | (unsigned long) pBlockFirst);
|
||||
pBlockFirst = (char *) (mask | (unsigned long) pBlockFirst);
|
||||
pBlockFirst++;
|
||||
}
|
||||
|
||||
@@ -1088,17 +1092,17 @@ void **ppBase /* base address found */
|
||||
*/
|
||||
LOCAL long blockDivide(
|
||||
epicsAddressType addrType,
|
||||
void *pBlockFirst,
|
||||
void *pBlockLast,
|
||||
void **ppBase, /* base address found */
|
||||
char *pBlockFirst,
|
||||
char *pBlockLast,
|
||||
char **ppBase, /* base address found */
|
||||
unsigned long requestSize
|
||||
)
|
||||
{
|
||||
void *pBlock;
|
||||
char *pBlock;
|
||||
unsigned long bs;
|
||||
int s;
|
||||
|
||||
s = blockProbe(addrType,pBlockFirst, pBlockFirst+(requestSize-1));
|
||||
s = blockProbe(addrType, pBlockFirst, pBlockFirst+(requestSize-1));
|
||||
if(!s){
|
||||
*ppBase = pBlockFirst;
|
||||
return SUCCESS;
|
||||
@@ -1137,11 +1141,11 @@ unsigned long requestSize
|
||||
*/
|
||||
LOCAL long blockProbe(
|
||||
epicsAddressType addrType,
|
||||
void *pFirst,
|
||||
void *pLast
|
||||
char *pFirst,
|
||||
char *pLast
|
||||
)
|
||||
{
|
||||
void *pProbe;
|
||||
char *pProbe;
|
||||
int s;
|
||||
|
||||
pProbe = pFirst;
|
||||
@@ -1161,10 +1165,10 @@ void *pLast
|
||||
*/
|
||||
long locationProbe(
|
||||
epicsAddressType addrType,
|
||||
void *pLocation
|
||||
char *pLocation
|
||||
)
|
||||
{
|
||||
void *pPhysical;
|
||||
char *pPhysical;
|
||||
int s;
|
||||
|
||||
/*
|
||||
@@ -1174,33 +1178,33 @@ void *pLocation
|
||||
s = sysBusToLocalAdrs(
|
||||
EPICStovxWorksAddrType[addrType],
|
||||
pLocation,
|
||||
(char **)&pPhysical);
|
||||
&pPhysical);
|
||||
if(s<0){
|
||||
return S_dev_vxWorksAddrMapFail;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
char *pChar;
|
||||
char byte;
|
||||
int8_t *pChar;
|
||||
int8_t byte;
|
||||
|
||||
pChar = pPhysical;
|
||||
pChar = (int8_t *) pPhysical;
|
||||
if(devPtrAlignTest(pChar)){
|
||||
s = vxMemProbe(
|
||||
pChar,
|
||||
(char *) pChar,
|
||||
READ,
|
||||
sizeof(byte),
|
||||
&byte);
|
||||
(char *) &byte);
|
||||
if(s!=ERROR){
|
||||
return S_dev_addressOverlap;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
short *pWord;
|
||||
short word;
|
||||
int16_t *pWord;
|
||||
int16_t word;
|
||||
|
||||
pWord = pPhysical;
|
||||
pWord = (int16_t *)pPhysical;
|
||||
if(devPtrAlignTest(pWord)){
|
||||
s = vxMemProbe(
|
||||
(char *)pWord,
|
||||
@@ -1213,10 +1217,10 @@ void *pLocation
|
||||
}
|
||||
}
|
||||
{
|
||||
long *pLongWord;
|
||||
long longWord;
|
||||
int32_t *pLongWord;
|
||||
int32_t longWord;
|
||||
|
||||
pLongWord = pPhysical;
|
||||
pLongWord = (int32_t *) pPhysical;
|
||||
if(devPtrAlignTest(pLongWord)){
|
||||
s = vxMemProbe(
|
||||
(char *)pLongWord,
|
||||
@@ -1270,13 +1274,15 @@ void *devLibA24Malloc(size_t size)
|
||||
void *ret;
|
||||
|
||||
if (devLibA24Debug)
|
||||
printf("devLibA24Malloc(%d) entered\n", size);
|
||||
logMsg("devLibA24Malloc(%d) entered\n", size, 0,0,0,0,0);
|
||||
|
||||
if (A24MallocFunc == NULL)
|
||||
{
|
||||
/* See if the sysA24Malloc() function is present. */
|
||||
if(symFindByName(sysSymTbl,"_sysA24Malloc", (char**)&A24MallocFunc,&stype)==ERROR)
|
||||
{ /* Could not find sysA24Malloc... use the malloc one and hope we are OK */
|
||||
if (devLibA24Debug)
|
||||
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
|
||||
A24MallocFunc = malloc;
|
||||
A24FreeFunc = free;
|
||||
}
|
||||
@@ -1284,6 +1290,8 @@ void *devLibA24Malloc(size_t size)
|
||||
{
|
||||
if(symFindByName(sysSymTbl,"_sysA24Free", (char**)&A24FreeFunc, &stype) == ERROR)
|
||||
{ /* That's strange... we have malloc, but no free! */
|
||||
if (devLibA24Debug)
|
||||
logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0);
|
||||
A24MallocFunc = malloc;
|
||||
A24FreeFunc = free;
|
||||
}
|
||||
@@ -1301,5 +1309,8 @@ void *devLibA24Malloc(size_t size)
|
||||
|
||||
void devLibA24Free(void *pBlock)
|
||||
{
|
||||
if (devLibA24Debug)
|
||||
logMsg("devLibA24Free(%p) entered\n", (unsigned long)pBlock,0,0,0,0,0);
|
||||
|
||||
A24FreeFunc(pBlock);
|
||||
}
|
||||
|
||||
132
src/db/drvTS.c
132
src/db/drvTS.c
@@ -1,6 +1,21 @@
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.7 1995/02/02 17:15:55 jbk
|
||||
* Removed the stinking message "Cannot contact master timing IOC ".
|
||||
*
|
||||
* Revision 1.6 1995/02/01 15:29:54 winans
|
||||
* Added a type field to the configure command to disable the use of the event
|
||||
* system hardware if desired.
|
||||
*
|
||||
* Revision 1.5 1994/12/16 15:51:21 winans
|
||||
* Changed error message in the event system error handler & added a conditional
|
||||
* based on a debug flag to print it... defaults to off. (Per request from MRK.)
|
||||
*
|
||||
* Revision 1.4 1994/10/28 20:15:10 jbk
|
||||
* increased the USP packet time-out to 250ms, added a parm to the configure()
|
||||
* routine to let user specify it.
|
||||
*
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
@@ -62,7 +77,12 @@ LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define NODEBUG
|
||||
#define MAKE_DEBUG 0
|
||||
#else
|
||||
#define MAKE_DEBUG TSdriverDebug
|
||||
#endif
|
||||
#define TS_DRIVER
|
||||
|
||||
#include <vxWorks.h>
|
||||
@@ -99,8 +119,12 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
#include <drvTS.h>
|
||||
|
||||
/* #define FL M_drvSup,__FILE__,__LINE__ */
|
||||
#if 0
|
||||
#define FL stderr
|
||||
#define errPrintf fprintf
|
||||
#else
|
||||
#define FL M_drvSup,__FILE__,__LINE__
|
||||
#endif
|
||||
|
||||
/* functions used by this driver */
|
||||
static long TSgetUnixTime(struct timespec*);
|
||||
@@ -173,7 +197,7 @@ TSinfo TSdata = { TS_master_dead, TS_async_slave, TS_async_none,
|
||||
0,NULL,
|
||||
TS_SYNC_RATE_SEC,TS_CLOCK_RATE_HZ,0,TS_TIME_OUT_MS,0,
|
||||
TS_MASTER_PORT,TS_SLAVE_PORT,1,0,0,
|
||||
NULL, NULL,NULL };
|
||||
NULL, NULL,NULL, 0 };
|
||||
|
||||
extern char* sysBootLine;
|
||||
|
||||
@@ -244,9 +268,12 @@ long TSreport()
|
||||
TSconfigure() - This is the configuration routine which is meant to
|
||||
be called from the vxWorks startup.cmd script before iocInit.
|
||||
It's job is to set operating parameters for the time stamp support code.
|
||||
|
||||
JRW -- if type = 0, then try to config using event system
|
||||
if type = 1, then permanantly inhibit use of the event system
|
||||
*/
|
||||
void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz,
|
||||
int master_port, int slave_port, unsigned long time_out)
|
||||
int master_port, int slave_port, unsigned long time_out, int type)
|
||||
{
|
||||
if(master) TSdata.master_timing_IOC=1;
|
||||
else TSdata.master_timing_IOC=0;
|
||||
@@ -268,6 +295,8 @@ void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz,
|
||||
if(time_out) TSdata.time_out=time_out;
|
||||
else TSdata.time_out=TS_TIME_OUT_MS;
|
||||
|
||||
TSdata.UserRequestedType = type;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -342,39 +371,56 @@ long TSinit()
|
||||
SYM_TYPE stype;
|
||||
|
||||
Debug(5,"In TSinit()\n",0);
|
||||
/* ------------------------------------------------------------- */
|
||||
/* find the lower level event system functions */
|
||||
if(symFindByName(sysSymTbl,"_ErHaveReceiver",
|
||||
(char**)&TShaveReceiver,&stype)==ERROR)
|
||||
TShaveReceiver = TShaveReceiverError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErGetTicks",
|
||||
(char**)&TSgetTicks,&stype)==ERROR)
|
||||
TSgetTicks = TSgetTicksError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErRegisterEventHandler",
|
||||
(char**)&TSregisterEventHandler,&stype)==ERROR)
|
||||
TSregisterEventHandler = TSregisterEventHandlerError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErRegisterErrorHandler",
|
||||
(char**)&TSregisterErrorHandler,&stype)==ERROR)
|
||||
TSregisterErrorHandler = TSregisterErrorHandlerError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErForceSync",
|
||||
(char**)&TSforceSync,&stype)==ERROR)
|
||||
TSforceSync = TSforceSoftSync;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErGetTime",
|
||||
(char**)&TSgetTime,&stype)==ERROR)
|
||||
TSgetTime = TSgetCurrentTime;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErSyncEvent",
|
||||
(char**)&TSsyncEvent,&stype)==ERROR)
|
||||
TSdata.sync_event=ER_EVENT_RESET_TICK;
|
||||
if (TSdata.UserRequestedType == 0)
|
||||
{ /* default configuration probe */
|
||||
/* ------------------------------------------------------------- */
|
||||
/* find the lower level event system functions */
|
||||
if(symFindByName(sysSymTbl,"_ErHaveReceiver",
|
||||
(char**)&TShaveReceiver,&stype)==ERROR)
|
||||
TShaveReceiver = TShaveReceiverError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErGetTicks",
|
||||
(char**)&TSgetTicks,&stype)==ERROR)
|
||||
TSgetTicks = TSgetTicksError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErRegisterEventHandler",
|
||||
(char**)&TSregisterEventHandler,&stype)==ERROR)
|
||||
TSregisterEventHandler = TSregisterEventHandlerError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErRegisterErrorHandler",
|
||||
(char**)&TSregisterErrorHandler,&stype)==ERROR)
|
||||
TSregisterErrorHandler = TSregisterErrorHandlerError;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErForceSync",
|
||||
(char**)&TSforceSync,&stype)==ERROR)
|
||||
TSforceSync = TSforceSoftSync;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErGetTime",
|
||||
(char**)&TSgetTime,&stype)==ERROR)
|
||||
TSgetTime = TSgetCurrentTime;
|
||||
|
||||
if(symFindByName(sysSymTbl,"_ErSyncEvent",
|
||||
(char**)&TSsyncEvent,&stype)==ERROR)
|
||||
TSdata.sync_event=ER_EVENT_RESET_TICK;
|
||||
else
|
||||
TSdata.sync_event=TSsyncEvent();
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
}
|
||||
else
|
||||
TSdata.sync_event=TSsyncEvent();
|
||||
{ /* inhibit probe and use of the event system */
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
printf("WARNING: drvTS event hardware probe inhibited by user\n");
|
||||
|
||||
TShaveReceiver = TShaveReceiverError;
|
||||
TSgetTicks = TSgetTicksError;
|
||||
TSregisterEventHandler = TSregisterEventHandlerError;
|
||||
TSregisterErrorHandler = TSregisterErrorHandlerError;
|
||||
TSforceSync = TSforceSoftSync;
|
||||
TSgetTime = TSgetCurrentTime;
|
||||
TSdata.sync_event=ER_EVENT_RESET_TICK;
|
||||
}
|
||||
|
||||
/* set all the known information about the system */
|
||||
TSdata.event_table=NULL;
|
||||
@@ -484,12 +530,14 @@ long TSinit()
|
||||
{
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_REALTIME,&tp);
|
||||
/* this should work */
|
||||
errPrintf(FL,"Failed to set time from Unix server\n");
|
||||
}
|
||||
|
||||
if( TSsetClockFromMaster()<0 )
|
||||
{
|
||||
errPrintf(FL,"Could not contact a master timing IOC\n");
|
||||
/* do nothing here */
|
||||
/* errPrintf(FL,"Could not contact a master timing IOC\n"); */
|
||||
}
|
||||
else
|
||||
TSdata.state = TS_master_alive;
|
||||
@@ -653,7 +701,23 @@ static void TSerrorHandler(int Card, int ErrorNum)
|
||||
Could put the slave on the vxworks timer until next sync
|
||||
*/
|
||||
|
||||
logMsg("***TSerrorHandler: error number %d=n",ErrorNum,0,0,0,0,0);
|
||||
if(MAKE_DEBUG)
|
||||
{
|
||||
switch(ErrorNum)
|
||||
{
|
||||
case 1:
|
||||
logMsg("***TSerrorHandler: event system error: TAXI violation",0,0,0,0,0,0);
|
||||
break;
|
||||
case 2:
|
||||
logMsg("***TSerrorHandler: event system error: lost heartbeat",0,0,0,0,0,0);
|
||||
break;
|
||||
case 3:
|
||||
logMsg("***TSerrorHandler: event system error: lost events",0,0,0,0,0,0);
|
||||
break;
|
||||
default:
|
||||
logMsg("***TSerrorHandler: unknown error %d from event system", ErrorNum,0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
545
src/db/iocInit.c
545
src/db/iocInit.c
@@ -53,11 +53,12 @@
|
||||
* .23 09-10-92 rcz changed funcptr pinitHooks from ret long to void
|
||||
* .24 09-11-92 rcz moved setMasterTimeToSelf to a seperate C file
|
||||
* .25 07-15-93 mrk Changed dbLoad for new dbStaticLib support
|
||||
<<<<<<< iocInit.c
|
||||
* .26 02-09-94 jbk changed to new time stamp support software ts_init()
|
||||
* .27 03-18-94 mcn added comments
|
||||
* .28 03-23-94 mrk Added asInit
|
||||
* .29 04-04-94 mcn added code for uninitialized conversions (link conversion field)
|
||||
* .30 01-10-95 joh Fixed no quoted strings in resource.def problem
|
||||
* .31 02-10-95 joh static => LOCAL
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
@@ -65,13 +66,17 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ellLib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sysLib.h>
|
||||
#include <symLib.h>
|
||||
#include <sysSymTbl.h> /* for sysSymTbl*/
|
||||
#include <logLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <envLib.h>
|
||||
#include <errnoLib.h>
|
||||
|
||||
#include <ellLib.h>
|
||||
#include <sdrHeader.h>
|
||||
#include <fast_lock.h>
|
||||
#include <choice.h>
|
||||
@@ -98,7 +103,7 @@
|
||||
#define MODULE_TYPES_INIT 1
|
||||
#include <module_types.h>
|
||||
|
||||
static initialized=FALSE;
|
||||
LOCAL int initialized=FALSE;
|
||||
|
||||
/* The following is for use by interrupt routines */
|
||||
int interruptAccept=FALSE;
|
||||
@@ -109,15 +114,18 @@ struct dbBase *pdbBase=NULL;
|
||||
long dbCommonInit();
|
||||
|
||||
/* define forward references*/
|
||||
static long initDrvSup(void);
|
||||
static long initRecSup(void);
|
||||
static long initDevSup(void);
|
||||
static long finishDevSup(void);
|
||||
static long initDatabase(void);
|
||||
static void createLockSets(void);
|
||||
static short makeSameSet(struct dbAddr *paddr,short set);
|
||||
static long initialProcess(void);
|
||||
static long getResources(char *fname);
|
||||
LOCAL long initDrvSup(void);
|
||||
LOCAL long initRecSup(void);
|
||||
LOCAL long initDevSup(void);
|
||||
LOCAL long finishDevSup(void);
|
||||
LOCAL long initDatabase(void);
|
||||
LOCAL void createLockSets(void);
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr,short set);
|
||||
LOCAL long initialProcess(void);
|
||||
LOCAL long getResources(char *fname);
|
||||
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
|
||||
LOCAL int getResourceTokenInternal(FILE *fp, char *pToken, unsigned maxToken);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize EPICS on the IOC.
|
||||
@@ -140,13 +148,7 @@ int iocInit(char * pResourceFilename)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the data structure for error reporting
|
||||
*/
|
||||
if ((errSymBld()) != 0) {
|
||||
logMsg("iocInit aborting because errSymBld failed to initialize \n",0,0,0,0,0,0);
|
||||
return(-1);
|
||||
}
|
||||
errInit(); /*Initialize errPrintf task*/
|
||||
|
||||
/*
|
||||
* Setup initialization hooks, but only if an initHooks routine has been defined.
|
||||
@@ -176,11 +178,6 @@ int iocInit(char * pResourceFilename)
|
||||
* Read EPICS resources.
|
||||
*/
|
||||
status = getResources(pResourceFilename);
|
||||
if (status != 0) {
|
||||
logMsg("iocInit aborting because getResources failed\n",0,0,0,0,0,0);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Call hook for after resources are read. */
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterGetResources);
|
||||
|
||||
@@ -322,7 +319,7 @@ int iocInit(char * pResourceFilename)
|
||||
* Call the initialization routine (init) for each
|
||||
* driver type.
|
||||
*/
|
||||
static long initDrvSup(void) /* Locate all driver support entry tables */
|
||||
LOCAL long initDrvSup(void) /* Locate all driver support entry tables */
|
||||
{
|
||||
char *pname;
|
||||
char name[40];
|
||||
@@ -341,7 +338,7 @@ static long initDrvSup(void) /* Locate all driver support entry tables */
|
||||
|
||||
if (!(pdrvSup=pdbBase->pdrvSup)) {
|
||||
status = S_drv_noDrvSup;
|
||||
errMessage(status,"No device drivers are defined");
|
||||
errMessage(status,"");
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -360,7 +357,7 @@ static long initDrvSup(void) /* Locate all driver support entry tables */
|
||||
vxstatus = symFindByName(sysSymTbl, name, (void *) &(pdrvSup->papDrvet[i]), &type);
|
||||
|
||||
if (vxstatus != OK) {
|
||||
strcpy(message,"driver entry table not found for ");
|
||||
strcpy(message,": ");
|
||||
strcat(message,pname);
|
||||
status = S_drv_noDrvet;
|
||||
errMessage(status,message);
|
||||
@@ -389,7 +386,7 @@ static long initDrvSup(void) /* Locate all driver support entry tables */
|
||||
* Call the initialization routine (init) for each
|
||||
* record type.
|
||||
*/
|
||||
static long initRecSup(void)
|
||||
LOCAL long initRecSup(void)
|
||||
{
|
||||
char name[40];
|
||||
int i;
|
||||
@@ -404,7 +401,7 @@ static long initRecSup(void)
|
||||
|
||||
if(!(precType=pdbBase->precType)) {
|
||||
status = S_rectype_noRecs;
|
||||
errMessage(status,"No record types defined");
|
||||
errMessage(status,"");
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -450,7 +447,7 @@ static long initRecSup(void)
|
||||
(void *) (&precSup->papRset[i]), &type);
|
||||
|
||||
if (vxstatus != OK) {
|
||||
strcpy(message,"record support entry table not found for ");
|
||||
strcpy(message,": ");
|
||||
strcat(message,name);
|
||||
status = S_rec_noRSET;
|
||||
errMessage(status,message);
|
||||
@@ -476,7 +473,7 @@ static long initRecSup(void)
|
||||
* Call the initialization routine (init) for each
|
||||
* device type (First Pass).
|
||||
*/
|
||||
static long initDevSup(void)
|
||||
LOCAL long initDevSup(void)
|
||||
{
|
||||
char *pname;
|
||||
char name[40];
|
||||
@@ -491,7 +488,7 @@ static long initDevSup(void)
|
||||
|
||||
if (!(precDevSup = pdbBase->precDevSup)) {
|
||||
status = S_dev_noDevSup;
|
||||
errMessage(status,"No device support is defined");
|
||||
errMessage(status,"");
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -523,7 +520,7 @@ static long initDevSup(void)
|
||||
|
||||
if (vxstatus != OK) {
|
||||
pdevSup->papDset[j]=NULL;
|
||||
strcpy(message, "device support entry table not found for ");
|
||||
strcpy(message, ": ");
|
||||
strcat(message, pname);
|
||||
status = S_dev_noDSET;
|
||||
errMessage(status, message);
|
||||
@@ -549,7 +546,7 @@ static long initDevSup(void)
|
||||
* after the database records have been initialized and
|
||||
* placed into lock sets.
|
||||
*/
|
||||
static long finishDevSup(void)
|
||||
LOCAL long finishDevSup(void)
|
||||
{
|
||||
int i,j;
|
||||
struct recDevSup *precDevSup;
|
||||
@@ -581,7 +578,7 @@ static long finishDevSup(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long initDatabase(void)
|
||||
LOCAL long initDatabase(void)
|
||||
{
|
||||
char name[PVNAME_SZ+FLDNAME_SZ+2];
|
||||
short i,j;
|
||||
@@ -615,7 +612,7 @@ static long initDatabase(void)
|
||||
*/
|
||||
if (!(precHeader = pdbBase->precHeader)) {
|
||||
status = S_record_noRecords;
|
||||
errMessage(status,"No database records are defined");
|
||||
errMessage(status,"");
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -660,7 +657,7 @@ static long initDatabase(void)
|
||||
if (!prset) {
|
||||
strcpy(name,precType->papName[i]);
|
||||
strcat(name,"RSET");
|
||||
strcpy(message,"record support entry table not found for ");
|
||||
strcpy(message,": ");
|
||||
strcat(message,name);
|
||||
status = S_rec_noRSET;
|
||||
errMessage(status,message);
|
||||
@@ -778,9 +775,10 @@ static long initDatabase(void)
|
||||
* Severity/No Maximize Severity(MS/NMS), and output NMS
|
||||
* links ... The following code checks for this.
|
||||
*/
|
||||
if (plink->value.db_link.process_passive
|
||||
if (errVerbose &&
|
||||
(plink->value.db_link.process_passive
|
||||
|| (pfldDes->field_type == DBF_OUTLINK
|
||||
&& plink->value.db_link.maximize_sevr))
|
||||
&& plink->value.db_link.maximize_sevr)))
|
||||
{
|
||||
/*
|
||||
* Link PP and/or Outlink MS ...
|
||||
@@ -795,7 +793,7 @@ static long initDatabase(void)
|
||||
strcat(message," PP and/or MS illegal");
|
||||
status = S_db_badField;
|
||||
errMessage(status,message);
|
||||
if(rtnval==OK) rtnval=status;
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -842,7 +840,7 @@ static long initDatabase(void)
|
||||
* lock set. Records connected by forward links are
|
||||
* definately considered part of the same lockset.
|
||||
*/
|
||||
static void createLockSets(void)
|
||||
LOCAL void createLockSets(void)
|
||||
{
|
||||
int i,link;
|
||||
struct recLoc *precLoc;
|
||||
@@ -935,7 +933,7 @@ static void createLockSets(void)
|
||||
dbScanLockInit(nset);
|
||||
}
|
||||
|
||||
static short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
{
|
||||
struct dbCommon *precord = paddr->precord;
|
||||
short link;
|
||||
@@ -1006,7 +1004,7 @@ static short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
* Process database records at initialization if
|
||||
* their pini (process at init) field is set.
|
||||
*/
|
||||
static long initialProcess(void)
|
||||
LOCAL long initialProcess(void)
|
||||
{
|
||||
short i;
|
||||
struct recHeader *precHeader;
|
||||
@@ -1030,199 +1028,362 @@ static long initialProcess(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define MAX 128
|
||||
#define MAX 256
|
||||
#define SAME 0
|
||||
static char *cvt_str[] = {
|
||||
|
||||
enum resType {
|
||||
resDBF_STRING,
|
||||
resDBF_SHORT,
|
||||
resDBF_LONG,
|
||||
resDBF_FLOAT,
|
||||
resDBF_DOUBLE,
|
||||
resInvalid};
|
||||
LOCAL char *cvt_str[] = {
|
||||
"DBF_STRING",
|
||||
"DBF_SHORT",
|
||||
"DBF_LONG",
|
||||
"DBF_FLOAT",
|
||||
"DBF_DOUBLE"
|
||||
"DBF_DOUBLE",
|
||||
"Invalid",
|
||||
};
|
||||
#define CVT_COUNT (sizeof(cvt_str) / sizeof(char*))
|
||||
static long getResources(char *fname)
|
||||
|
||||
#define EPICS_ENV_PREFIX "EPICS_"
|
||||
|
||||
long getResources(char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
int len;
|
||||
int len2;
|
||||
int lineNum = 0;
|
||||
int i = 0;
|
||||
int found = 0;
|
||||
int cvType = 0;
|
||||
int epicsFlag;
|
||||
char buff[MAX + 1];
|
||||
char name[40];
|
||||
char s1[MAX];
|
||||
char s2[MAX];
|
||||
char s3[MAX];
|
||||
char message[100];
|
||||
long rtnval = 0;
|
||||
char name[40];
|
||||
FILE *fp;
|
||||
enum resType cvType = resInvalid;
|
||||
int epicsFlag;
|
||||
SYM_TYPE type;
|
||||
char *pSymAddr;
|
||||
char *pSymAddr;
|
||||
short n_short;
|
||||
long n_long;
|
||||
float n_float;
|
||||
double n_double;
|
||||
int status;
|
||||
|
||||
if (!fname) return (0);
|
||||
|
||||
if ((fp = fopen(fname, "r")) == 0) {
|
||||
errMessage(-1L, "getResources: No such Resource file");
|
||||
errPrintf(
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"No such Resource file - %s",
|
||||
fname);
|
||||
return (-1);
|
||||
}
|
||||
while ( fgets( buff, MAX, fp) != NULL) {
|
||||
len = strlen(buff);
|
||||
lineNum++;
|
||||
if (len < 2)
|
||||
goto CLEAR;
|
||||
if (len >= MAX) {
|
||||
sprintf(message,
|
||||
"getResources: Line too long - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (buff[i] == '!') {
|
||||
goto CLEAR;
|
||||
}
|
||||
}
|
||||
/* extract the 3 fields as strings */
|
||||
if ((sscanf(buff, "%s %s %s", s1, s2, s3)) != 3) {
|
||||
sprintf(message,
|
||||
"getResources: Not enough fields - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
}
|
||||
found = 0;
|
||||
len2 = strlen(s2);
|
||||
for (i = 0; i < CVT_COUNT; i++) {
|
||||
|
||||
while (TRUE) {
|
||||
status = getResourceToken (fp, s1, sizeof(s1));
|
||||
if (status<0) {
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
break;
|
||||
}
|
||||
status = getResourceToken (fp, s2, sizeof(s2));
|
||||
if (status<0) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Missing resource data type field for resource=%s in file=%s",
|
||||
s1,
|
||||
fname);
|
||||
break;
|
||||
}
|
||||
status = getResourceToken (fp, s3, sizeof(s3));
|
||||
if (status<0) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Missing resource value field for resource=%s data type=%s file=%s",
|
||||
s1,
|
||||
s2,
|
||||
fname);
|
||||
break; /* EOF */
|
||||
}
|
||||
|
||||
if ((strncmp(s2, cvt_str[i], len2)) == SAME) {
|
||||
found = 1;
|
||||
cvType = i;
|
||||
for (cvType = 0; cvType < resInvalid; cvType++) {
|
||||
if (strcmp(s2, cvt_str[cvType]) == SAME) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
sprintf(message,
|
||||
"getResources: Field 2 not defined - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
strcpy(name, "_");
|
||||
strcat(name, s1);
|
||||
rtnval = symFindByName(sysSymTbl, name, &pSymAddr, &type);
|
||||
if (rtnval != OK) {
|
||||
sprintf(message,
|
||||
"getResources: Symbol name not found - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
status = symFindByName(sysSymTbl, name, &pSymAddr, &type);
|
||||
if (status!= OK) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Matching Symbol name not found for resource=%s",
|
||||
s1);
|
||||
continue;
|
||||
}
|
||||
|
||||
status = strncmp (
|
||||
s1,
|
||||
EPICS_ENV_PREFIX,
|
||||
strlen (EPICS_ENV_PREFIX));
|
||||
if (status == SAME) {
|
||||
epicsFlag = 1;
|
||||
if (cvType != resDBF_STRING) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"%s should be set with type DBF_STRING not type %s",
|
||||
s1,
|
||||
s2);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
epicsFlag = 0;
|
||||
}
|
||||
if ( (strncmp(s1,"EPICS_",6)) == SAME)
|
||||
epicsFlag = 1;
|
||||
else
|
||||
epicsFlag = 0;
|
||||
|
||||
switch (cvType) {
|
||||
case 0: /* DBF_STRING */
|
||||
len = strlen(s3);
|
||||
len2 = 20;
|
||||
if (len >= len2) {
|
||||
sprintf(message,
|
||||
"getResources: Warning, string might exceed previous reserved space - line=%d",
|
||||
lineNum);
|
||||
errMessage(-1L, message);
|
||||
}
|
||||
if ( epicsFlag )
|
||||
strncpy(pSymAddr+sizeof(void *), s3, len + 1);
|
||||
else
|
||||
strncpy(pSymAddr, s3, len + 1);
|
||||
break;
|
||||
case 1: /* DBF_SHORT */
|
||||
if ((sscanf(s3, "%hd", &n_short)) != 1) {
|
||||
sprintf(message,
|
||||
"getResources: conversion failed - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
}
|
||||
case resDBF_STRING:
|
||||
if ( epicsFlag ) {
|
||||
sprintf(message,
|
||||
"getResources: %s is of type DBF_STRING - line =%d",
|
||||
name,lineNum);
|
||||
errMessage(-1L, message);
|
||||
}
|
||||
else
|
||||
*(short *) pSymAddr = n_short;
|
||||
char *pEnv;
|
||||
|
||||
break;
|
||||
case 2: /* DBF_LONG */
|
||||
if ((sscanf(s3, "%ld", &n_long)) != 1) {
|
||||
sprintf(message,
|
||||
"getResources: conversion failed - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
/*
|
||||
* space for two strings, an '=' character,
|
||||
* and a null termination
|
||||
*/
|
||||
pEnv = malloc (strlen (s3) + strlen (s1) + 2);
|
||||
if (!pEnv) {
|
||||
errPrintf(
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Failed to set environment parameter \"%s\" to \"%s\" because \"%s\"\n",
|
||||
s1,
|
||||
s3,
|
||||
strerror (errnoGet()));
|
||||
break;
|
||||
}
|
||||
strcpy (pEnv, s1);
|
||||
strcat (pEnv, "=");
|
||||
strcat (pEnv, s3);
|
||||
status = putenv (pEnv);
|
||||
if (status<0) {
|
||||
errPrintf(
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Failed to set environment parameter \"%s\" to \"%s\" because \"%s\"\n",
|
||||
s1,
|
||||
s3,
|
||||
strerror (errnoGet()));
|
||||
}
|
||||
/*
|
||||
* vxWorks copies into a private buffer
|
||||
* (this does not match UNIX behavior)
|
||||
*/
|
||||
free (pEnv);
|
||||
}
|
||||
if ( epicsFlag ) {
|
||||
sprintf(message,
|
||||
"getResources: %s is of type DBF_STRING - line =%d",
|
||||
name,lineNum);
|
||||
errMessage(-1L, message);
|
||||
}
|
||||
else
|
||||
*(long *) pSymAddr = n_long;
|
||||
break;
|
||||
case 3: /* DBF_FLOAT */
|
||||
if ((sscanf(s3, "%e", &n_float)) != 1) {
|
||||
sprintf(message,
|
||||
"getResources: conversion failed - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
else{
|
||||
strcpy(pSymAddr, s3);
|
||||
}
|
||||
if ( epicsFlag ) {
|
||||
sprintf(message,
|
||||
"getResources: %s is of type DBF_STRING - line =%d",
|
||||
name,lineNum);
|
||||
errMessage(-1L, message);
|
||||
}
|
||||
else
|
||||
*(float *) pSymAddr = n_float;
|
||||
break;
|
||||
|
||||
break;
|
||||
case 4: /* DBF_DOUBLE */
|
||||
if ((sscanf(s3, "%le", &n_double)) != 1) {
|
||||
sprintf(message,
|
||||
"getResources: conversion failed - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
case resDBF_SHORT:
|
||||
if (sscanf(s3, "%hd", &n_short) != 1) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Resource=%s value=%s conversion to %s failed",
|
||||
s1,
|
||||
s3,
|
||||
cvt_str[cvType]);
|
||||
continue;
|
||||
}
|
||||
if ( epicsFlag ) {
|
||||
sprintf(message,
|
||||
"getResources: %s is of type DBF_STRING - line =%d",
|
||||
name,lineNum);
|
||||
errMessage(-1L, message);
|
||||
}
|
||||
else
|
||||
*(double *) pSymAddr = n_double;
|
||||
|
||||
*(short *) pSymAddr = n_short;
|
||||
break;
|
||||
|
||||
case resDBF_LONG:
|
||||
if (sscanf(s3, "%ld", &n_long) != 1) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Resource=%s value=%s conversion to %s failed",
|
||||
s1,
|
||||
s3,
|
||||
cvt_str[cvType]);
|
||||
continue;
|
||||
}
|
||||
*(long *) pSymAddr = n_long;
|
||||
break;
|
||||
|
||||
case resDBF_FLOAT:
|
||||
if (sscanf(s3, "%e", &n_float) != 1) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Resource=%s value=%s conversion to %s failed",
|
||||
s1,
|
||||
s3,
|
||||
cvt_str[cvType]);
|
||||
continue;
|
||||
}
|
||||
*(float *) pSymAddr = n_float;
|
||||
break;
|
||||
|
||||
case resDBF_DOUBLE:
|
||||
if (sscanf(s3, "%le", &n_double) != 1) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Resource=%s value=%s conversion to %s failed",
|
||||
s1,
|
||||
s3,
|
||||
cvt_str[cvType]);
|
||||
continue;
|
||||
}
|
||||
*(double *) pSymAddr = n_double;
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(message,
|
||||
"getResources: switch default reached - line=%d", lineNum);
|
||||
errMessage(-1L, message);
|
||||
return (-1);
|
||||
break;
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Invalid data type field=%s for resource=%s",
|
||||
s2,
|
||||
s1);
|
||||
continue;
|
||||
}
|
||||
CLEAR: memset(buff, '\0', MAX);
|
||||
memset(s1, '\0', MAX);
|
||||
memset(s2, '\0', MAX);
|
||||
memset(s3, '\0', MAX);
|
||||
}
|
||||
fclose(fp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gotSdrSum=FALSE;
|
||||
static struct sdrSum sdrSum;
|
||||
/*
|
||||
* getResourceToken
|
||||
*/
|
||||
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
* keep reading until we get a token
|
||||
* (and comments have been stripped)
|
||||
*/
|
||||
while (TRUE) {
|
||||
status = getResourceTokenInternal (fp, pToken, maxToken);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (pToken[0] != '\0') {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getResourceTokenInternal
|
||||
*/
|
||||
LOCAL int getResourceTokenInternal(FILE *fp, char *pToken, unsigned maxToken)
|
||||
{
|
||||
char formatString[32];
|
||||
char quoteCharString[2];
|
||||
int status;
|
||||
|
||||
quoteCharString[0] = '\0';
|
||||
status = fscanf (fp, " %1[\"`'!]", quoteCharString);
|
||||
if (status<0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (quoteCharString[0]) {
|
||||
/*
|
||||
* its a comment
|
||||
* (consume everything up to the next new line)
|
||||
*/
|
||||
case '!':
|
||||
{
|
||||
char tmp[MAX];
|
||||
|
||||
sprintf(formatString, "%%%d[^\n\r\v\f]", sizeof(tmp)-1);
|
||||
status = fscanf (fp, "%[^\n\r\v\f]",tmp);
|
||||
pToken[0] = '\0';
|
||||
if (status<0) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* its a plain token
|
||||
*/
|
||||
case '\0':
|
||||
sprintf(formatString, " %%%ds", maxToken-1);
|
||||
|
||||
status = fscanf (fp, formatString, pToken);
|
||||
if (status!=1) {
|
||||
if (status < 0){
|
||||
pToken[0] = '\0';
|
||||
return status;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* it was a quoted string
|
||||
*/
|
||||
default:
|
||||
sprintf(
|
||||
formatString,
|
||||
"%%%d[^%c]",
|
||||
maxToken-1,
|
||||
quoteCharString[0]);
|
||||
status = fscanf (fp, formatString, pToken);
|
||||
if (status!=1) {
|
||||
if (status < 0){
|
||||
pToken[0] = '\0';
|
||||
return status;
|
||||
}
|
||||
}
|
||||
sprintf(formatString, "%%1[%c]", quoteCharString[0]);
|
||||
status = fscanf (fp, formatString, quoteCharString);
|
||||
if (status!=1) {
|
||||
errPrintf (
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Resource file syntax error: unterminated string \"%s\"",
|
||||
pToken);
|
||||
pToken[0] = '\0';
|
||||
if (status < 0){
|
||||
return status;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
LOCAL int gotSdrSum=FALSE;
|
||||
LOCAL struct sdrSum sdrSum;
|
||||
int dbLoad(char * pfilename)
|
||||
{
|
||||
long status;
|
||||
|
||||
@@ -109,7 +109,6 @@ void recGblRecordError(long status,void *pdbc,char *pcaller_name)
|
||||
strcat(buffer," ");
|
||||
}
|
||||
if(pcaller_name) {
|
||||
strcat(buffer,"error detected in routine: ");
|
||||
strcat(buffer,pcaller_name);
|
||||
}
|
||||
errMessage(status,buffer);
|
||||
|
||||
@@ -79,45 +79,14 @@ extern struct dbBase *pdbBase;
|
||||
%%
|
||||
|
||||
database: DATABASE d_head d_body
|
||||
{
|
||||
#ifdef vxWorks
|
||||
dbFreeEntry(pdbentry);
|
||||
#endif
|
||||
}
|
||||
| DATABASE d_head /* jbk added for graphical thing */
|
||||
{
|
||||
#ifdef vxWorks
|
||||
dbFreeEntry(pdbentry);
|
||||
#endif
|
||||
}
|
||||
| db_components
|
||||
;
|
||||
|
||||
d_head: O_PAREN WORD C_PAREN
|
||||
{
|
||||
#ifdef vxWorks
|
||||
/*
|
||||
fprintf(stderr,"Warning: No EPICS version information in db file\n");
|
||||
*/
|
||||
pdbentry=dbAllocEntry(pdbBase);
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
{ free($2); }
|
||||
| O_PAREN WORD COMMA VALUE C_PAREN
|
||||
{
|
||||
#ifdef vxWorks
|
||||
int version,revision;
|
||||
char* v;
|
||||
|
||||
v=strtok($4," ."); sscanf(v,"%d",&version);
|
||||
v=strtok(NULL," ."); sscanf(v,"%d",&revision);
|
||||
|
||||
if(version!=EPICS_VERSION || revision!=EPICS_REVISION)
|
||||
fprintf(stderr,"Warning: Database not created with same version\n");
|
||||
|
||||
pdbentry=dbAllocEntry(pdbBase);
|
||||
free($2); free($4);
|
||||
#endif
|
||||
}
|
||||
{ free($2); free($4); }
|
||||
;
|
||||
|
||||
d_body: O_BRACE nowhere_records db_components C_BRACE
|
||||
@@ -144,9 +113,7 @@ container: CONTAINER c_head c_body
|
||||
;
|
||||
|
||||
c_head: O_PAREN WORD C_PAREN
|
||||
{
|
||||
free($2);
|
||||
}
|
||||
{ free($2); }
|
||||
;
|
||||
|
||||
c_body: O_BRACE db_components C_BRACE
|
||||
@@ -159,7 +126,7 @@ records: /* null */
|
||||
record: RECORD r_head r_body
|
||||
{
|
||||
#ifndef vxWorks
|
||||
printf(" }\n");
|
||||
printf("}\n");
|
||||
#endif
|
||||
}
|
||||
;
|
||||
@@ -253,10 +220,6 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef vxWorks
|
||||
/* if(container) printf(" %s {\n",container); */
|
||||
#endif
|
||||
|
||||
if(is_not_inited)
|
||||
{
|
||||
yyin=fp;
|
||||
@@ -266,10 +229,15 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
{
|
||||
yyrestart(fp);
|
||||
}
|
||||
|
||||
#ifdef vxWorks
|
||||
pdbentry=dbAllocEntry(pdbBase);
|
||||
#endif
|
||||
|
||||
yyparse();
|
||||
|
||||
#ifndef vxWorks
|
||||
/* if(container) printf(" }\n"); */
|
||||
#ifdef vxWorks
|
||||
dbFreeEntry(pdbentry);
|
||||
#endif
|
||||
|
||||
if(subst_used) dbFreeSubst();
|
||||
@@ -294,7 +262,7 @@ static void sub_pvname(char* type, char* name)
|
||||
if( dbCreateRecord(pdbentry,subst_buffer) )
|
||||
fprintf(stderr,"Cannot create record %s\n",subst_buffer);
|
||||
#else
|
||||
printf("\trecord(%s, \"%s\") {",type,subst_buffer);
|
||||
printf("record(%s,\"%s\") {",type,subst_buffer);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -303,7 +271,7 @@ static void sub_pvname(char* type, char* name)
|
||||
if( dbCreateRecord(pdbentry,name) )
|
||||
fprintf(stderr,"Cannot create record %s\n",name);
|
||||
#else
|
||||
printf("\trecord(%s, \"%s\") {",type,name);
|
||||
printf("record(%s,\"%s\") {",type,name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>]
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
|
||||
value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
|
||||
%{
|
||||
@@ -7,7 +7,10 @@ value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
|
||||
%%
|
||||
|
||||
\#.*\n ;
|
||||
|
||||
"field" { return(FIELD); }
|
||||
"grecord" { return(RECORD); }
|
||||
"record" { return(RECORD); }
|
||||
"container" { return(CONTAINER); }
|
||||
"database" { return(DATABASE); }
|
||||
|
||||
@@ -89,6 +89,17 @@ templs: templs templ
|
||||
;
|
||||
|
||||
templ: templ_head O_BRACE subst C_BRACE
|
||||
| templ_head
|
||||
{
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,NULL,NULL);
|
||||
else
|
||||
fprintf(stderr,"Error: no db file name given\n");
|
||||
#else
|
||||
sub_it();
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
templ_head: DBFILE WORD
|
||||
@@ -105,11 +116,11 @@ subst: PATTERN pattern subs
|
||||
|
||||
pattern: O_BRACE vars C_BRACE
|
||||
{
|
||||
/*
|
||||
#ifdef ERROR_STUFF
|
||||
int i;
|
||||
for(i=0;i<var_count;i++) fprintf(stderr,"variable=(%s)\n",vars[i]);
|
||||
fprintf(stderr,"var_count=%d\n",var_count);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
@@ -118,9 +129,7 @@ vars: vars var
|
||||
;
|
||||
|
||||
var: WORD
|
||||
{
|
||||
vars[var_count++]=$1;
|
||||
}
|
||||
{ vars[var_count++]=$1; }
|
||||
;
|
||||
|
||||
subs: subs sub
|
||||
@@ -130,7 +139,9 @@ subs: subs sub
|
||||
sub: WORD O_BRACE vals C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect);
|
||||
#endif
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,$1);
|
||||
@@ -147,7 +158,9 @@ sub: WORD O_BRACE vals C_BRACE
|
||||
| O_BRACE vals C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect);
|
||||
#endif
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,NULL);
|
||||
@@ -199,7 +212,9 @@ var_subs: var_subs var_sub
|
||||
var_sub: WORD O_BRACE sub_pats C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect);
|
||||
#endif
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,$1);
|
||||
@@ -216,7 +231,9 @@ var_sub: WORD O_BRACE sub_pats C_BRACE
|
||||
| O_BRACE sub_pats C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect);
|
||||
#endif
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,NULL);
|
||||
@@ -292,7 +309,10 @@ int dbLoadTemplate(char* sub_file)
|
||||
yyin=fp;
|
||||
is_not_inited=0;
|
||||
}
|
||||
else yyrestart(fp);
|
||||
else
|
||||
{
|
||||
yyrestart(fp);
|
||||
}
|
||||
|
||||
yyparse();
|
||||
|
||||
@@ -324,12 +344,22 @@ main(int argc, char** argv)
|
||||
}
|
||||
|
||||
/* use sub_collect and db_file_name to do work */
|
||||
int sub_it()
|
||||
static int sub_it()
|
||||
{
|
||||
FILE* fp;
|
||||
char var_buff[500];
|
||||
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"In sub_it()\n");
|
||||
#endif
|
||||
|
||||
if( *sub_collect )
|
||||
{
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr," dbInitSubst() calling\n");
|
||||
#endif
|
||||
dbInitSubst(sub_collect);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"No valid substitutions found in table\n");
|
||||
@@ -345,10 +375,16 @@ int sub_it()
|
||||
/* do the work here */
|
||||
while( fgets(var_buff,200,fp)!=(char*)NULL )
|
||||
{
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr," calling dbDoSubst()\n");
|
||||
#endif
|
||||
dbDoSubst(var_buff,500,NULL);
|
||||
fputs(var_buff,stdout);
|
||||
}
|
||||
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr," calling dbFreeSubst()\n");
|
||||
#endif
|
||||
dbFreeSubst();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
@@ -388,9 +424,7 @@ main(int argc, char** argv)
|
||||
|
||||
if(!name) name = "Composite";
|
||||
|
||||
printf("database(name,\"%d.%d\") {\n",EPICS_VERSION,EPICS_REVISION,name);
|
||||
dbLoadTemplate(argv[1]);
|
||||
printf("}\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,8 @@ par [\"\']
|
||||
|
||||
%%
|
||||
|
||||
\#.*\n ;
|
||||
|
||||
"pattern" { return(PATTERN); }
|
||||
"file" { return(DBFILE); }
|
||||
"=" { return(EQUALS); }
|
||||
@@ -16,8 +18,6 @@ par [\"\']
|
||||
|
||||
{word}+ { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext); return(WORD); }
|
||||
|
||||
"(" { return(O_PAREN); }
|
||||
")" { return(C_PAREN); }
|
||||
"{" { return(O_BRACE); }
|
||||
"}" { return(C_BRACE); }
|
||||
|
||||
|
||||
@@ -191,13 +191,18 @@ long dbInitSubst(char* parm_pattern)
|
||||
/* find vars and subs */
|
||||
switch(*pp)
|
||||
{
|
||||
case '\\': pp++; break;
|
||||
case '\\': pp++; break; /* skip the next character */
|
||||
case '=': subst_total++; break;
|
||||
case '\"': for(++pp;*pp!='\"';pp++) if(*pp=='\\') pp++; pp++; break;
|
||||
case '\"':
|
||||
for(++pp;*pp && *pp!='\"';pp++)
|
||||
if(*pp=='\\') pp++;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
/* fprintf(stderr,"total = %d\n",subst_total); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"total = %d\n",subst_total);
|
||||
#endif
|
||||
|
||||
/* allocate the substitution table */
|
||||
subst = (struct var_sub*)malloc( sizeof(struct var_sub)*subst_total );
|
||||
@@ -235,12 +240,12 @@ long dbInitSubst(char* parm_pattern)
|
||||
}
|
||||
|
||||
/* debug code */
|
||||
/*
|
||||
#ifdef ERROR_STUFF
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
{
|
||||
printf("table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
fprintf(stderr,"table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* resolve the multiple substitutions now */
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
@@ -253,12 +258,12 @@ long dbInitSubst(char* parm_pattern)
|
||||
}
|
||||
|
||||
/* more debug code */
|
||||
/*
|
||||
#ifdef ERROR_STUFF
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
{
|
||||
printf("table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
fprintf(stderr,"table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -276,7 +281,9 @@ static char* get_var(char** to, char* from)
|
||||
pp = strpbrk(from," \t=");
|
||||
*pp = '\0';
|
||||
pp++;
|
||||
/* fprintf(stderr,"get_var: (%s)\n",from); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"get_var: (%s)\n",from);
|
||||
#endif
|
||||
*to=from;
|
||||
return pp;
|
||||
}
|
||||
@@ -297,7 +304,9 @@ static char* get_sub(char* to, char* from)
|
||||
else *cp++ = *pp;
|
||||
}
|
||||
*cp='\0';
|
||||
/* fprintf(stderr,"get_sub: quote (%s)\n",to); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"get_sub: quote (%s)\n",to);
|
||||
#endif
|
||||
pp++;
|
||||
}
|
||||
else
|
||||
@@ -307,7 +316,9 @@ static char* get_sub(char* to, char* from)
|
||||
{
|
||||
*hold = '\0';
|
||||
hold++;
|
||||
/* fprintf(stderr,"get_sub: regular (%s)\n",pp); */
|
||||
#ifdef ERROR_STUFF
|
||||
fprintf(stderr,"get_sub: regular (%s)\n",pp);
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy(to,pp);
|
||||
|
||||
@@ -2,195 +2,210 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_INCLUDES = -I../../drv
|
||||
USR_INCLUDES = -I../../drv/ansi -I../../drv/old
|
||||
|
||||
SRCS.c = \
|
||||
../devAiDvx2502.c\
|
||||
../devAiSoft.c\
|
||||
../devAiSoftRaw.c\
|
||||
../devAiSymb.c\
|
||||
../devAiTestAsyn.c\
|
||||
../devAiXy566Di.c\
|
||||
../devAiXy566DiL.c\
|
||||
../devAiXy566Se.c\
|
||||
../devAoSoft.c\
|
||||
../devApsEg.c\
|
||||
../devApsEr.c\
|
||||
../devAoSoftRaw.c\
|
||||
../devAoSymb.c\
|
||||
../devAoTestAsyn.c\
|
||||
../devAoVmiVme4100.c\
|
||||
../devBiMpv910.c\
|
||||
../devBiSoft.c\
|
||||
../devBiSoftRaw.c\
|
||||
../devBiTestAsyn.c\
|
||||
../devBiXVme210.c\
|
||||
../devBoMpv902.c\
|
||||
../devBoSoft.c\
|
||||
../devBoSoftRaw.c\
|
||||
../devBoTestAsyn.c\
|
||||
../devBoXVme220.c\
|
||||
../devCommonGpib.c\
|
||||
../devEventSoft.c\
|
||||
../devEventTestIoEvent.c\
|
||||
../devHistogramSoft.c\
|
||||
../devHistogramTestAsyn.c\
|
||||
../devLiSoft.c\
|
||||
../devLiSymb.c\
|
||||
../devLoSoft.c\
|
||||
../devLoSymb.c\
|
||||
../devMbbiMpv910.c\
|
||||
../devMbbiSoft.c\
|
||||
../devMbbiSoftRaw.c\
|
||||
../devMbbiTestAsyn.c\
|
||||
../devMbbiXVme210.c\
|
||||
../devMbboMpv902.c\
|
||||
../devMbboSoft.c\
|
||||
../devMbboSoftRaw.c\
|
||||
../devMbboTestAsyn.c\
|
||||
../devMbboXVme220.c\
|
||||
../devMbbiDirectMpv910.c\
|
||||
../devMbbiDirectSoft.c\
|
||||
../devMbbiDirectSoftRaw.c\
|
||||
../devMbbiDirectXVme210.c\
|
||||
../devMbboDirectMpv902.c\
|
||||
../devMbboDirectSoft.c\
|
||||
../devMbboDirectSoftRaw.c\
|
||||
../devMbboDirectXVme220.c\
|
||||
../devPtSoft.c\
|
||||
../devSmCompumotor1830.c\
|
||||
../devSmOms6Axis.c\
|
||||
../devSiSoft.c\
|
||||
../devSiSymb.c\
|
||||
../devSiTestAsyn.c\
|
||||
../devSoSoft.c\
|
||||
../devSASoft.c\
|
||||
../devSoSymb.c\
|
||||
../devSoTestAsyn.c\
|
||||
../devWfSoft.c\
|
||||
../devWfTestAsyn.c\
|
||||
../devWfXy566Sc.c\
|
||||
../devAllenBradley.c\
|
||||
../devAt5Vxi.c\
|
||||
../devMz8310.c\
|
||||
../devTimerMz8310.c\
|
||||
../devVxiTDM.c\
|
||||
../devAiKscV215.c\
|
||||
../devXy240.c\
|
||||
../devHpe1368a.c\
|
||||
../devAt8Fp.c\
|
||||
../devWfComet.c\
|
||||
../devWfDvx2502.c\
|
||||
../devWfJoergerVtr1.c\
|
||||
../devAvme9440.c\
|
||||
../devSysmon.c
|
||||
# ../devAiCamac.c\
|
||||
# ../devAaiCamac.c\
|
||||
# ../devBiCamac.c\
|
||||
# ../devLiCamac.c\
|
||||
# ../devMbbiCamac.c\
|
||||
# ../devMbbiDirectCamac.c\
|
||||
# ../devWfCamac.c\
|
||||
# ../devAoCamac.c\
|
||||
# ../devAaoCamac.c\
|
||||
# ../devBoCamac.c\
|
||||
# ../devLoCamac.c\
|
||||
# ../devMbboCamac.c\
|
||||
# ../devMbboDirectCamac.c
|
||||
# SRCS.c += ../devAaiCamac.c
|
||||
# SRCS.c += ../devAiCamac.c
|
||||
SRCS.c += ../devAiDvx2502.c
|
||||
SRCS.c += ../devAiKscV215.c
|
||||
SRCS.c += ../devAiSoft.c
|
||||
SRCS.c += ../devAiSoftRaw.c
|
||||
SRCS.c += ../devAiSymb.c
|
||||
SRCS.c += ../devAiTestAsyn.c
|
||||
SRCS.c += ../devAiXy566Di.c
|
||||
SRCS.c += ../devAiXy566DiL.c
|
||||
SRCS.c += ../devAiXy566Se.c
|
||||
# SRCS.c += ../devAaoCamac.c
|
||||
# SRCS.c += ../devAoCamac.c
|
||||
SRCS.c += ../devAoSoft.c
|
||||
SRCS.c += ../devAoSoftRaw.c
|
||||
SRCS.c += ../devAoSymb.c
|
||||
SRCS.c += ../devAoTestAsyn.c
|
||||
SRCS.c += ../devAoVmiVme4100.c
|
||||
SRCS.c += ../devApsEg.c
|
||||
SRCS.c += ../devApsEr.c
|
||||
SRCS.c += ../devAt5Vxi.c
|
||||
SRCS.c += ../devAt8Fp.c
|
||||
SRCS.c += ../devAvme9440.c
|
||||
# SRCS.c += ../devBiCamac.c
|
||||
SRCS.c += ../devBiMpv910.c
|
||||
SRCS.c += ../devBiSoft.c
|
||||
SRCS.c += ../devBiSoftRaw.c
|
||||
SRCS.c += ../devBiTestAsyn.c
|
||||
SRCS.c += ../devBiXVme210.c
|
||||
# SRCS.c += ../devBoCamac.c
|
||||
SRCS.c += ../devBoMpv902.c
|
||||
SRCS.c += ../devBoSoft.c
|
||||
SRCS.c += ../devBoSoftRaw.c
|
||||
SRCS.c += ../devBoTestAsyn.c
|
||||
SRCS.c += ../devBoXVme220.c
|
||||
SRCS.c += ../devCommonGpib.c
|
||||
SRCS.c += ../devEventSoft.c
|
||||
SRCS.c += ../devEventTestIoEvent.c
|
||||
SRCS.c += ../devHistogramSoft.c
|
||||
SRCS.c += ../devHistogramTestAsyn.c
|
||||
SRCS.c += ../devHpe1368a.c
|
||||
# OBJS += devLiCamac.c
|
||||
SRCS.c += ../devLiSoft.c
|
||||
SRCS.c += ../devLiSymb.c
|
||||
# OBJS += devLoCamac.c
|
||||
SRCS.c += ../devLoSoft.c
|
||||
SRCS.c += ../devLoSymb.c
|
||||
# SRCS.c += ../devMbbiCamac.c
|
||||
# SRCS.c += ../devMbbiDirectCamac.c
|
||||
SRCS.c += ../devMbbiDirectMpv910.c
|
||||
SRCS.c += ../devMbbiDirectSoft.c
|
||||
SRCS.c += ../devMbbiDirectSoftRaw.c
|
||||
SRCS.c += ../devMbbiDirectXVme210.c
|
||||
SRCS.c += ../devMbbiMpv910.c
|
||||
SRCS.c += ../devMbbiSoft.c
|
||||
SRCS.c += ../devMbbiSoftRaw.c
|
||||
SRCS.c += ../devMbbiTestAsyn.c
|
||||
SRCS.c += ../devMbbiXVme210.c
|
||||
# SRCS.c += ../devMbboCamac.c
|
||||
# SRCS.c += ../devMbboDirectCamac.c
|
||||
SRCS.c += ../devMbboDirectMpv902.c
|
||||
SRCS.c += ../devMbboDirectSoft.c
|
||||
SRCS.c += ../devMbboDirectSoftRaw.c
|
||||
SRCS.c += ../devMbboDirectXVme220.c
|
||||
SRCS.c += ../devMbboMpv902.c
|
||||
SRCS.c += ../devMbboSoft.c
|
||||
SRCS.c += ../devMbboSoftRaw.c
|
||||
SRCS.c += ../devMbboTestAsyn.c
|
||||
SRCS.c += ../devMbboXVme220.c
|
||||
SRCS.c += ../devMz8310.c
|
||||
SRCS.c += ../devPtSoft.c
|
||||
SRCS.c += ../devSASoft.c
|
||||
SRCS.c += ../devSiSoft.c
|
||||
SRCS.c += ../devSiSymb.c
|
||||
SRCS.c += ../devSiTestAsyn.c
|
||||
SRCS.c += ../devSmCompumotor1830.c
|
||||
SRCS.c += ../devSmOms6Axis.c
|
||||
SRCS.c += ../devSoSoft.c
|
||||
SRCS.c += ../devSoSymb.c
|
||||
SRCS.c += ../devSoTestAsyn.c
|
||||
SRCS.c += ../devSysmon.c
|
||||
SRCS.c += ../devTimerMz8310.c
|
||||
SRCS.c += ../devVxiTDM.c
|
||||
# SRCS.c += ../devWfCamac.c
|
||||
SRCS.c += ../devWfComet.c
|
||||
SRCS.c += ../devWfDvx2502.c
|
||||
SRCS.c += ../devWfJoergerVtr1.c
|
||||
SRCS.c += ../devWfSoft.c
|
||||
SRCS.c += ../devWfTestAsyn.c
|
||||
SRCS.c += ../devWfXy566Sc.c
|
||||
SRCS.c += ../devWfPentek4261.c
|
||||
SRCS.c += ../devXy240.c
|
||||
|
||||
OBJS = \
|
||||
devAiDvx2502.o\
|
||||
devAiSoft.o\
|
||||
devAiSoftRaw.o\
|
||||
devAiSymb.o\
|
||||
devAiTestAsyn.o\
|
||||
devAiXy566Di.o\
|
||||
devAiXy566DiL.o\
|
||||
devAiXy566Se.o\
|
||||
devAoSoft.o\
|
||||
devAoSoftRaw.o\
|
||||
devAoSymb.o\
|
||||
devAoTestAsyn.o\
|
||||
devAoVmiVme4100.o\
|
||||
devBiMpv910.o\
|
||||
devApsEg.o\
|
||||
devApsEr.o\
|
||||
devBiSoft.o\
|
||||
devBiSoftRaw.o\
|
||||
devBiTestAsyn.o\
|
||||
devBiXVme210.o\
|
||||
devBoMpv902.o\
|
||||
devBoSoft.o\
|
||||
devBoSoftRaw.o\
|
||||
devBoTestAsyn.o\
|
||||
devBoXVme220.o\
|
||||
devCommonGpib.o\
|
||||
devEventSoft.o\
|
||||
devEventTestIoEvent.o\
|
||||
devHistogramSoft.o\
|
||||
devHistogramTestAsyn.o\
|
||||
devLiSoft.o\
|
||||
devLiSymb.o\
|
||||
devLoSoft.o\
|
||||
devLoSymb.o\
|
||||
devMbbiMpv910.o\
|
||||
devMbbiSoft.o\
|
||||
devMbbiSoftRaw.o\
|
||||
devMbbiTestAsyn.o\
|
||||
devMbbiXVme210.o\
|
||||
devMbboMpv902.o\
|
||||
devMbboSoft.o\
|
||||
devMbboSoftRaw.o\
|
||||
devMbboTestAsyn.o\
|
||||
devMbboXVme220.o\
|
||||
devMbbiDirectMpv910.o\
|
||||
devMbbiDirectSoft.o\
|
||||
devMbbiDirectSoftRaw.o\
|
||||
devMbbiDirectXVme210.o\
|
||||
devMbboDirectMpv902.o\
|
||||
devMbboDirectSoft.o\
|
||||
devMbboDirectSoftRaw.o\
|
||||
devMbboDirectXVme220.o\
|
||||
devPtSoft.o\
|
||||
devSmCompumotor1830.o\
|
||||
devSmOms6Axis.o\
|
||||
devSASoft.o\
|
||||
devSiSoft.o\
|
||||
devSiSymb.o\
|
||||
devSiTestAsyn.o\
|
||||
devSoSoft.o\
|
||||
devSoSymb.o\
|
||||
devSoTestAsyn.o\
|
||||
devWfSoft.o\
|
||||
devWfTestAsyn.o\
|
||||
devWfXy566Sc.o\
|
||||
devAllenBradley.o\
|
||||
devAt5Vxi.o\
|
||||
devMz8310.o\
|
||||
devTimerMz8310.o\
|
||||
devVxiTDM.o\
|
||||
devAiKscV215.o\
|
||||
devXy240.o\
|
||||
devHpe1368a.o\
|
||||
devAt8Fp.o\
|
||||
devWfComet.o\
|
||||
devWfDvx2502.o\
|
||||
devWfJoergerVtr1.o\
|
||||
devAvme9440.o\
|
||||
devSysmon.o
|
||||
# devAiCamac.o\
|
||||
# devAaiCamac.o\
|
||||
# devBiCamac.o\
|
||||
# devLiCamac.o\
|
||||
# devMbbiCamac.o\
|
||||
# devMbbiDirectCamac.o\
|
||||
# devWfCamac.o\
|
||||
# devAoCamac.o\
|
||||
# devAaoCamac.o\
|
||||
# devBoCamac.o\
|
||||
# devLoCamac.o\
|
||||
# devMbboCamac.o\
|
||||
# devMbboDirectCamac.o
|
||||
SRCS.c += ../devAB1771IFE.c
|
||||
SRCS.c += ../devAB1771IL.c
|
||||
SRCS.c += ../devAB1771IR.c
|
||||
SRCS.c += ../devAB1771IXE.c
|
||||
SRCS.c += ../devAB1771OFE.c
|
||||
SRCS.c += ../devABBINARY.c
|
||||
SRCS.c += ../devABStatus.c
|
||||
SRCS.c += ../devMpc.c
|
||||
|
||||
# OBJS += devAaiCamac.o
|
||||
# OBJS += devAiCamac.o
|
||||
OBJS += devAiDvx2502.o
|
||||
OBJS += devAiKscV215.o
|
||||
OBJS += devAiSoft.o
|
||||
OBJS += devAiSoftRaw.o
|
||||
OBJS += devAiSymb.o
|
||||
OBJS += devAiTestAsyn.o
|
||||
OBJS += devAiXy566Di.o
|
||||
OBJS += devAiXy566DiL.o
|
||||
OBJS += devAiXy566Se.o
|
||||
# OBJS += devAaoCamac.o
|
||||
# OBJS += devAoCamac.o
|
||||
OBJS += devAoSoft.o
|
||||
OBJS += devAoSoftRaw.o
|
||||
OBJS += devAoSymb.o
|
||||
OBJS += devAoTestAsyn.o
|
||||
OBJS += devAoVmiVme4100.o
|
||||
OBJS += devApsEg.o
|
||||
OBJS += devApsEr.o
|
||||
OBJS += devAt5Vxi.o
|
||||
OBJS += devAt8Fp.o
|
||||
OBJS += devAvme9440.o
|
||||
# OBJS += devBiCamac.o
|
||||
OBJS += devBiMpv910.o
|
||||
OBJS += devBiSoft.o
|
||||
OBJS += devBiSoftRaw.o
|
||||
OBJS += devBiTestAsyn.o
|
||||
OBJS += devBiXVme210.o
|
||||
# OBJS += devBoCamac.o
|
||||
OBJS += devBoMpv902.o
|
||||
OBJS += devBoSoft.o
|
||||
OBJS += devBoSoftRaw.o
|
||||
OBJS += devBoTestAsyn.o
|
||||
OBJS += devBoXVme220.o
|
||||
OBJS += devCommonGpib.o
|
||||
OBJS += devEventSoft.o
|
||||
OBJS += devEventTestIoEvent.o
|
||||
OBJS += devHistogramSoft.o
|
||||
OBJS += devHistogramTestAsyn.o
|
||||
OBJS += devHpe1368a.o
|
||||
# OBJS += devLiCamac.o
|
||||
OBJS += devLiSoft.o
|
||||
OBJS += devLiSymb.o
|
||||
# OBJS += devLoCamac.o
|
||||
OBJS += devLoSoft.o
|
||||
OBJS += devLoSymb.o
|
||||
# OBJS += devMbbiCamac.o
|
||||
# OBJS += devMbbiDirectCamac.o
|
||||
OBJS += devMbbiDirectMpv910.o
|
||||
OBJS += devMbbiDirectSoft.o
|
||||
OBJS += devMbbiDirectSoftRaw.o
|
||||
OBJS += devMbbiDirectXVme210.o
|
||||
OBJS += devMbbiMpv910.o
|
||||
OBJS += devMbbiSoft.o
|
||||
OBJS += devMbbiSoftRaw.o
|
||||
OBJS += devMbbiTestAsyn.o
|
||||
OBJS += devMbbiXVme210.o
|
||||
# OBJS += devMbboCamac.o
|
||||
# OBJS += devMbboDirectCamac.o
|
||||
OBJS += devMbboDirectMpv902.o
|
||||
OBJS += devMbboDirectSoft.o
|
||||
OBJS += devMbboDirectSoftRaw.o
|
||||
OBJS += devMbboDirectXVme220.o
|
||||
OBJS += devMbboMpv902.o
|
||||
OBJS += devMbboSoft.o
|
||||
OBJS += devMbboSoftRaw.o
|
||||
OBJS += devMbboTestAsyn.o
|
||||
OBJS += devMbboXVme220.o
|
||||
OBJS += devMz8310.o
|
||||
OBJS += devPtSoft.o
|
||||
OBJS += devSASoft.o
|
||||
OBJS += devSiSoft.o
|
||||
OBJS += devSiSymb.o
|
||||
OBJS += devSiTestAsyn.o
|
||||
OBJS += devSmCompumotor1830.o
|
||||
OBJS += devSmOms6Axis.o
|
||||
OBJS += devSoSoft.o
|
||||
OBJS += devSoSymb.o
|
||||
OBJS += devSoTestAsyn.o
|
||||
OBJS += devSysmon.o
|
||||
OBJS += devTimerMz8310.o
|
||||
OBJS += devVxiTDM.o
|
||||
# OBJS += devWfCamac.o
|
||||
OBJS += devWfComet.o
|
||||
OBJS += devWfDvx2502.o
|
||||
OBJS += devWfJoergerVtr1.o
|
||||
OBJS += devWfSoft.o
|
||||
OBJS += devWfTestAsyn.o
|
||||
OBJS += devWfXy566Sc.o
|
||||
OBJS += devWfPentek4261.o
|
||||
OBJS += devXy240.o
|
||||
OBJS += devAB1771IFE.o
|
||||
OBJS += devAB1771IL.o
|
||||
OBJS += devAB1771IR.o
|
||||
OBJS += devAB1771IXE.o
|
||||
OBJS += devAB1771OFE.o
|
||||
OBJS += devABBINARY.o
|
||||
OBJS += devABStatus.o
|
||||
OBJS += devMpc.o
|
||||
|
||||
PROD = devSup
|
||||
|
||||
@@ -200,3 +215,4 @@ $(PROD): $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
|
||||
267
src/dev/devAB1771IFE.c
Normal file
267
src/dev/devAB1771IFE.c
Normal file
@@ -0,0 +1,267 @@
|
||||
/* devAB1771IFE.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident
|
||||
* in the driver and device support to
|
||||
significantly reduce the amount of code
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <aiRecord.h>
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt);
|
||||
LOCAL long init_1771IfeDiff(struct aiRecord *prec);
|
||||
LOCAL long init_1771Ife0to5V(struct aiRecord *prec);
|
||||
LOCAL long init_1771IfeMa(struct aiRecord *prec);
|
||||
LOCAL long init_1771IfeSe(struct aiRecord *prec);
|
||||
LOCAL long linconv_1771Ife(struct aiRecord *prec, int after);
|
||||
LOCAL long read_1771Ife(struct aiRecord *prec);
|
||||
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;} ABAIDSET;
|
||||
|
||||
ABAIDSET devAiAb1771Ife={6, 0, 0, init_1771IfeDiff,
|
||||
ioinfo_ai, read_1771Ife, linconv_1771Ife};
|
||||
ABAIDSET devAiAb1771Ife0to5V={6, 0, 0, init_1771Ife0to5V,
|
||||
ioinfo_ai, read_1771Ife, linconv_1771Ife};
|
||||
ABAIDSET devAiAb1771IfeMa={6, 0, 0, init_1771IfeMa,
|
||||
ioinfo_ai, read_1771Ife, linconv_1771Ife};
|
||||
ABAIDSET devAiAb1771IfeSe={6, 0, 0, init_1771IfeSe,
|
||||
ioinfo_ai, read_1771Ife, linconv_1771Ife};
|
||||
|
||||
#define IFE_SCAN_RATE 1
|
||||
#define IFE_INITMSG_LENGTH 37
|
||||
#define IFE_DIFF_READMSG_LENGTH 12
|
||||
#define IFE_SE_READMSG_LENGTH 20
|
||||
|
||||
struct ab1771Ife_read {
|
||||
unsigned short diag; /* diagnostic word */
|
||||
unsigned short urange; /* low byte - under range channels */
|
||||
unsigned short orange; /* low byte - over range channels */
|
||||
unsigned short sign; /* low byte - polarity 1 = negative */
|
||||
short data[16]; /* 16 data values (can be signed) */
|
||||
};
|
||||
|
||||
/* IFE Differential Initialization Message - from the IFE Manual */
|
||||
LOCAL short ab1771IfeDiff_initmsg[IFE_INITMSG_LENGTH] = {
|
||||
0xffff, 0xffff, /* -10 to 10 volts (signals 0 - 15) */
|
||||
0x0700, /* signed magnitude - differential */
|
||||
0xffff, 0x0000, /* scaled 0 - 4095 (12 bits) */
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095
|
||||
};
|
||||
/* 1771 - IFE 0 to 5 Volt */
|
||||
LOCAL short ab1771Ife0to5v_initmsg[IFE_INITMSG_LENGTH] = {
|
||||
0x5555, 0x5555, /* 0 to 5 volts (signals 0 - 15) */
|
||||
0x0700, /* signed magnitude - differential */
|
||||
0x0000, 0x0000, /* scaled 0 - 4095 (12 bits) */
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095
|
||||
};
|
||||
/* 1771 - IFE MilliAmp */
|
||||
LOCAL short ab1771IfeMa_initmsg[IFE_INITMSG_LENGTH] = {
|
||||
0x0000, 0x0000, /* 4 - 20 Ma (signals 0 - 15) */
|
||||
0x0700, /* signed magnitude - differential */
|
||||
0x0000, 0x0000, /* scaled 0 - 4095 (12 bits) */
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095
|
||||
};
|
||||
/* 1771 - IFE Single Ended (-10 to 10 Volts) */
|
||||
LOCAL short ab1771IfeSe_initmsg[IFE_INITMSG_LENGTH] = {
|
||||
0xffff, 0xffff, /* 0 to 5 volts (signals 0 - 15) */
|
||||
0x0600, /* signed magnitude - differential */
|
||||
0xffff, 0x0000, /* scaled 0 - 4095 (12 bits) */
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
unsigned short read_msg_len;
|
||||
unsigned short *pread_msg;
|
||||
} devPvt;
|
||||
|
||||
LOCAL void devCallback(void * drvPvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
if(!pdevPvt) return;
|
||||
scanIoRequest(pdevPvt->ioscanpvt);
|
||||
}
|
||||
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)prec->dpvt;
|
||||
if(!pdevPvt) return(0);
|
||||
*ppvt = pdevPvt->ioscanpvt;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long read_1771Ife(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt= (devPvt *)prec->dpvt;
|
||||
abStatus drvStatus;
|
||||
struct ab1771Ife_read *pdata;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt);
|
||||
pdata = (struct ab1771Ife_read *)pdevPvt->pread_msg;
|
||||
if(drvStatus != abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
prec->rval = pdata->data[pabio->signal];
|
||||
if( (pdata->orange & (1 << pabio->signal))
|
||||
|| (pdata->urange & (1 << pabio->signal)) )
|
||||
recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM);
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long linconv_1771Ife(struct aiRecord *prec, int after)
|
||||
{
|
||||
|
||||
if(!after) return(0);
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long init_1771Ife(struct aiRecord *prec, const char *card_type,
|
||||
unsigned short *pinit_msg, unsigned short read_size)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
/* ai.inp must be an AB_IO */
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
/* pointer to the data addess structure */
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeAi,card_type,devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
pdevPvt->read_msg_len = read_size;
|
||||
pdevPvt->pread_msg = calloc(read_size,sizeof(unsigned short));
|
||||
drvStatus = (*pabDrv->startScan)(drvPvt,IFE_SCAN_RATE,
|
||||
pinit_msg,IFE_INITMSG_LENGTH,pdevPvt->pread_msg ,read_size);
|
||||
if(drvStatus!=abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) startScan");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long init_1771IfeDiff(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ife(prec,"IFEDIFF",&ab1771IfeDiff_initmsg[0],
|
||||
IFE_DIFF_READMSG_LENGTH));
|
||||
}
|
||||
|
||||
LOCAL long init_1771Ife0to5V(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ife(prec,"IFE0to5V",&ab1771Ife0to5v_initmsg[0],
|
||||
IFE_DIFF_READMSG_LENGTH));
|
||||
}
|
||||
|
||||
LOCAL long init_1771IfeMa(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ife(prec,"IFEMA",&ab1771IfeMa_initmsg[0],
|
||||
IFE_DIFF_READMSG_LENGTH));
|
||||
}
|
||||
|
||||
LOCAL long init_1771IfeSe(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ife(prec,"IFESE",&ab1771IfeSe_initmsg[0],
|
||||
IFE_SE_READMSG_LENGTH));
|
||||
}
|
||||
195
src/dev/devAB1771IL.c
Normal file
195
src/dev/devAB1771IL.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/* devAB1771IL.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident
|
||||
* in the driver and device support to
|
||||
significantly reduce the amount of code
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <aiRecord.h>
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt);
|
||||
LOCAL long init_1771Il(struct aiRecord *prec);
|
||||
LOCAL long linconv_1771Il(struct aiRecord *prec, int after);
|
||||
LOCAL long read_1771Il(struct aiRecord *prec);
|
||||
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;} ABAIDSET;
|
||||
|
||||
ABAIDSET devAiAb1771Il={6, 0, 0, init_1771Il,
|
||||
ioinfo_ai, read_1771Il, linconv_1771Il};
|
||||
|
||||
#define IL_SCAN_RATE 4
|
||||
#define IL_INITMSG_LENGTH 19
|
||||
#define IL_READMSG_LENGTH 12
|
||||
|
||||
#define IL_RANGE 0xffff /* volt inp for all channels -10 - 10V */
|
||||
#define IL_DATA_FORMAT 0x600 /* signed magnitude binary */
|
||||
struct ab1771il_read {
|
||||
unsigned short diag; /* diagnostic word */
|
||||
unsigned short urange; /* low byte - under range channels */
|
||||
unsigned short orange; /* low byte - over range channels */
|
||||
unsigned short sign; /* low byte - polarity 1 = negative */
|
||||
short data[8]; /* 8 data values (can be signed) */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
unsigned short read_msg[IL_READMSG_LENGTH];
|
||||
unsigned short *pinit_msg;
|
||||
} devPvt;
|
||||
|
||||
LOCAL unsigned short initMsg[IL_INITMSG_LENGTH] = {
|
||||
IL_RANGE,IL_DATA_FORMAT,0x0ff,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095,
|
||||
0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095
|
||||
};
|
||||
|
||||
LOCAL void devCallback(void * drvPvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
if(!pdevPvt) return;
|
||||
scanIoRequest(pdevPvt->ioscanpvt);
|
||||
}
|
||||
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)prec->dpvt;
|
||||
if(!pdevPvt) return(0);
|
||||
*ppvt = pdevPvt->ioscanpvt;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long read_1771Il(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt= (devPvt *)prec->dpvt;
|
||||
abStatus drvStatus;
|
||||
struct ab1771il_read *pdata;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt);
|
||||
pdata = (struct ab1771il_read *)&pdevPvt->read_msg[0];
|
||||
if(drvStatus != abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
prec->rval = pdata->data[pabio->signal];
|
||||
if((pdata->urange&(1<<pabio->signal))
|
||||
|| (pdata->orange&(1<<pabio->signal)) )
|
||||
recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long linconv_1771Il(struct aiRecord *prec, int after)
|
||||
{
|
||||
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long init_1771Il(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
/* ai.inp must be an AB_IO */
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Il (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
/* pointer to the data addess structure */
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeAi,"IL",devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
pdevPvt->pinit_msg = initMsg;
|
||||
drvStatus = (*pabDrv->startScan)(drvPvt,IL_SCAN_RATE,
|
||||
pdevPvt->pinit_msg,IL_INITMSG_LENGTH,
|
||||
&pdevPvt->read_msg[0],IL_READMSG_LENGTH);
|
||||
if(drvStatus != abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Il (init_record) startScan");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Il (init_record) registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
216
src/dev/devAB1771IR.c
Normal file
216
src/dev/devAB1771IR.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/* devAB1771IR.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident
|
||||
* in the driver and device support to
|
||||
significantly reduce the amount of code
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <aiRecord.h>
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long init_1771Ir(struct aiRecord *prec, const char *card_type,
|
||||
unsigned short config);
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt);
|
||||
LOCAL long init_1771IrPlatinum(struct aiRecord *prec);
|
||||
LOCAL long init_1771IrCopper(struct aiRecord *prec);
|
||||
LOCAL long read_1771Ir(struct aiRecord *prec);
|
||||
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;} ABAIDSET;
|
||||
|
||||
ABAIDSET devAiAb1771IrPlatinum={6, 0, 0, init_1771IrPlatinum,
|
||||
ioinfo_ai, read_1771Ir, 0};
|
||||
ABAIDSET devAiAb1771IrCopper={6, 0, 0, init_1771IrCopper,
|
||||
ioinfo_ai, read_1771Ir, 0};
|
||||
|
||||
#define IR_SCAN_RATE 5
|
||||
#define IR_INITMSG_LENGTH 1
|
||||
#define IR_READMSG_LENGTH 8
|
||||
|
||||
/*Register definitions*/
|
||||
#define IR_UNITS_DEGF 0x40
|
||||
#define IR_UNITS_OHMS 0x80
|
||||
#define IR_COPPER 0x100
|
||||
#define IR_SIGNED 0x400
|
||||
|
||||
|
||||
struct ab1771Ir_read {
|
||||
unsigned short status; /* status and over/under range */
|
||||
unsigned short pol_over; /* polarity and overflow */
|
||||
short data[6]; /* current values */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
unsigned short read_msg[IR_READMSG_LENGTH];
|
||||
unsigned short write_msg;
|
||||
} devPvt;
|
||||
|
||||
LOCAL void devCallback(void * drvPvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
if(!pdevPvt) return;
|
||||
scanIoRequest(pdevPvt->ioscanpvt);
|
||||
}
|
||||
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)prec->dpvt;
|
||||
if(!pdevPvt) return(0);
|
||||
*ppvt = pdevPvt->ioscanpvt;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long read_1771Ir(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt= (devPvt *)prec->dpvt;
|
||||
abStatus drvStatus;
|
||||
struct ab1771Ir_read *pdata;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt);
|
||||
pdata = (struct ab1771Ir_read *)&pdevPvt->read_msg;
|
||||
if(drvStatus != abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}else{
|
||||
unsigned short mask;
|
||||
short value;
|
||||
unsigned short signal = pabio->signal;
|
||||
|
||||
value = (short)pdata->data[signal];
|
||||
if(pdata->pol_over& (0x100<<signal)) value = - value;
|
||||
prec->rval = value;
|
||||
mask = (1 << pabio->signal);
|
||||
if((pdata->status & (1<<signal))
|
||||
||(pdata->status & (0x100<<signal))){
|
||||
recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL long init_1771Ir(struct aiRecord *prec, const char *card_type,
|
||||
unsigned short config)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Ir (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
prec->linr = 0;
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeAi,card_type,devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
if(pabio->parm[0]=='C') {
|
||||
strcpy(prec->egu,"degC");
|
||||
} else if(pabio->parm[0]=='O') {
|
||||
config |= IR_UNITS_OHMS;
|
||||
strcpy(prec->egu,"ohms");
|
||||
} else {
|
||||
config |= IR_UNITS_DEGF;
|
||||
strcpy(prec->egu,"degF");
|
||||
}
|
||||
config |= IR_SIGNED;
|
||||
pdevPvt->write_msg = config;
|
||||
drvStatus = (*pabDrv->startScan)(drvPvt,IR_SCAN_RATE,
|
||||
&pdevPvt->write_msg,IR_INITMSG_LENGTH,
|
||||
pdevPvt->read_msg,IR_READMSG_LENGTH);
|
||||
if(drvStatus != abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ir (init_record) startScan");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ir (init_record) registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long init_1771IrPlatinum(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ir(prec,"IRPLATINUM",0));
|
||||
}
|
||||
|
||||
LOCAL long init_1771IrCopper(struct aiRecord *prec)
|
||||
{
|
||||
return(init_1771Ir(prec,"IRCOPPER",IR_COPPER));
|
||||
}
|
||||
268
src/dev/devAB1771IXE.c
Normal file
268
src/dev/devAB1771IXE.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/* devAB1771IXE.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident
|
||||
* in the driver and device support to
|
||||
significantly reduce the amount of code
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <aiRecord.h>
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt);
|
||||
LOCAL long init_1771Ixe(struct aiRecord *prec);
|
||||
LOCAL long linconv_1771Ixe(struct aiRecord *prec, int after);
|
||||
LOCAL long read_1771Ixe(struct aiRecord *prec);
|
||||
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;} ABAIDSET;
|
||||
|
||||
ABAIDSET devAiAb1771Ixe={6, 0, 0, init_1771Ixe,
|
||||
ioinfo_ai, read_1771Ixe, linconv_1771Ixe};
|
||||
|
||||
#define IXE_HALFSEC_RATE 5
|
||||
#define IXE_1SEC_RATE 10
|
||||
#define IXE_INITMSG_LENGTH 19
|
||||
#define IXE_READMSG_LENGTH 12
|
||||
#define IXE_NUM_CVTTYPES 14
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
unsigned short init_msg[IXE_INITMSG_LENGTH];
|
||||
unsigned short read_msg[IXE_READMSG_LENGTH];
|
||||
unsigned short indCvt;
|
||||
} devPvt;
|
||||
|
||||
/* xxxxxxxxxxxxxTTT - Thermocouple Types */
|
||||
#define IXE_MILLI 0x0000 /* Millivolt input */
|
||||
#define IXE_E 0x0001 /* "E" Thermocouple */
|
||||
#define IXE_J 0x0002 /* "J" Thermocouple */
|
||||
#define IXE_K 0x0003 /* "K" Thermocouple */
|
||||
#define IXE_T 0x0004 /* "T" Thermocouple */
|
||||
#define IXE_R 0x0005 /* "R" Thermocouple */
|
||||
#define IXE_S 0x0006 /* "S" Thermocouple */
|
||||
/* xxxxxxxCxxxxxxxx - Conversion into degrees F or C */
|
||||
#define IXE_DEGC 0x0000
|
||||
#define IXE_DEGF 0x0100
|
||||
/* xxxxxFFxxxxxxxxx - Data Format */
|
||||
#define IXE_SIGNED 0x0400 /* signed magnitude " " */
|
||||
/* SSSSSxxxxxxxxxxx - Scan Rate */
|
||||
#define IXE_HALFSEC 0x2800 /* sample time = 0.5 seconds */
|
||||
#define IXE_1SEC 0x5000 /* sample time = 1.0 seconds */
|
||||
#define IXE_2SECS 0xa000 /* sample time = 2.0 seconds */
|
||||
#define IXE_3SECS 0xf000 /* sample time = 3.0 seconds */
|
||||
|
||||
#define IXE_STATUS 0xff
|
||||
struct ab1771Ixe_read {
|
||||
unsigned short pol_stat; /* status - polarity word */
|
||||
unsigned short out_of_range; /* under - over range channels */
|
||||
unsigned short alarms; /* inputs outside alarm limits */
|
||||
short data[8]; /* current values */
|
||||
unsigned short cjcw; /* cold junction cal word */
|
||||
};
|
||||
|
||||
/*NOTE: The following degfinitions assumes that the allowed convert types
|
||||
are defined as follows:
|
||||
K_DGF=2, K_DGC=3, J_DGF=4, J_DGC=5, E_DGF=6, E_DGC=7, T_DGF=8,
|
||||
T_DGC=9, R_DGF=10, R_DGC=11, S_DGF=12, S_DGC=13,
|
||||
THIS IS A REAL KLUDGE. WE SHOULD FIND A BETTER WAY */
|
||||
LOCAL unsigned short ixe_cvt[IXE_NUM_CVTTYPES] = {
|
||||
IXE_MILLI | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_MILLI | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_K | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_K | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_J | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_J | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_E | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_E | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_T | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_T | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_R | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_R | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_S | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC,
|
||||
IXE_S | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC
|
||||
};
|
||||
LOCAL const char* cardName[IXE_NUM_CVTTYPES] = {
|
||||
"IXE_MV","IXE_MV","IXE_KDEGF","IXE_KDEGC",
|
||||
"IXE_JDEGF","IXE_JDEGC","IXE_EDEGF","IXE_EDEGC",
|
||||
"IXE_TDEGF","IXE_TDEGC","IXE_RDEGF","IXE_RDEGC",
|
||||
"IXS_TDEGF","IXE_SDEGC"
|
||||
};
|
||||
LOCAL unsigned short scanRate[IXE_NUM_CVTTYPES] = {
|
||||
IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,
|
||||
IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,
|
||||
IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,
|
||||
IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE
|
||||
};
|
||||
|
||||
LOCAL void devCallback(void * drvPvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
if(!pdevPvt) return;
|
||||
scanIoRequest(pdevPvt->ioscanpvt);
|
||||
}
|
||||
|
||||
LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)prec->dpvt;
|
||||
if(!pdevPvt) return(0);
|
||||
*ppvt = pdevPvt->ioscanpvt;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long read_1771Ixe(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt= (devPvt *)prec->dpvt;
|
||||
abStatus drvStatus;
|
||||
struct ab1771Ixe_read *pdata;
|
||||
long status;
|
||||
unsigned short indCvt;
|
||||
short rval;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
indCvt = pdevPvt->indCvt;
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt);
|
||||
pdata = (struct ab1771Ixe_read *)&pdevPvt->read_msg[0];
|
||||
if(drvStatus != abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
rval = pdata->data[pabio->signal];
|
||||
if((pdata->pol_stat&(0x100<<pabio->signal))) rval = -rval;
|
||||
if((pdata->out_of_range&(1<<pabio->signal))
|
||||
|| (pdata->out_of_range&(0x100<<pabio->signal)) ) {
|
||||
recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM);
|
||||
}
|
||||
if(indCvt!=0) {
|
||||
prec->val = prec->rval = rval;
|
||||
prec->udf = FALSE;
|
||||
status=2; /*don't convert*/
|
||||
} else {
|
||||
prec->rval = rval + 10000;
|
||||
status = 0;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long linconv_1771Ixe(struct aiRecord *prec, int after)
|
||||
{
|
||||
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/20000.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long init_1771Ixe(struct aiRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
unsigned short indCvt;
|
||||
|
||||
/* ai.inp must be an AB_IO */
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Ixe (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
/*If conversion type is 2,...,IXE_NUM_CVTTYPES Ixe performs the conversion*/
|
||||
/* THIS SHOULD BE CHANGED */
|
||||
if(prec->linr>=2 && prec->linr <IXE_NUM_CVTTYPES) {
|
||||
indCvt = prec->linr;
|
||||
prec->linr = 0;
|
||||
} else {
|
||||
indCvt = 0;
|
||||
}
|
||||
prec->eslo = (prec->eguf -prec->egul)/20000.0;
|
||||
/* pointer to the data addess structure */
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeAi,cardName[indCvt],devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
pdevPvt->indCvt = indCvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
pdevPvt->init_msg[0] = ixe_cvt[indCvt];
|
||||
drvStatus = (*pabDrv->startScan)(drvPvt,scanRate[indCvt],
|
||||
&pdevPvt->init_msg[0],IXE_INITMSG_LENGTH,
|
||||
&pdevPvt->read_msg[0],IXE_READMSG_LENGTH);
|
||||
if(drvStatus != abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ixe (init_record) startScan");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ixe (init_record) registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
196
src/dev/devAB1771OFE.c
Normal file
196
src/dev/devAB1771OFE.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/* devAB1771OFE.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident in the driver and
|
||||
* device support to significantly reduce the amount of code
|
||||
* ...
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <aoRecord.h>
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long init_1771Ofe(struct aoRecord *pao);
|
||||
LOCAL long write_1771Ofe(struct aoRecord *pao);
|
||||
LOCAL long linconv_1771Ofe(struct aoRecord *pao, int after);
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_ao;
|
||||
DEVSUPFUN special_linconv;
|
||||
}ABAODSET;
|
||||
|
||||
ABAODSET devAoAb1771Ofe={ 6, NULL, NULL, init_1771Ofe, NULL,
|
||||
write_1771Ofe, linconv_1771Ofe};
|
||||
|
||||
#define UPDATE_RATE 100
|
||||
#define READ_MSG_LEN 5
|
||||
#define WRITE_MSG_LEN 5
|
||||
|
||||
|
||||
/* defines and structures for analog outputs */
|
||||
/* configuration word 5 for the OFE module */
|
||||
/* FxxxHHHHLLLLPPPP */
|
||||
/* F - Data Format */
|
||||
/* 0x0 specifies BCD */
|
||||
/* 0x1 specifies Binary */
|
||||
/* HHHH - Max Scaling Polarity */
|
||||
/* LLLL - Min Scaling Polarity */
|
||||
/* PPPP - Value Polarity */
|
||||
#define OFE_BINARY 0x8000 /* talk binary instead of BCD */
|
||||
#define OFE_SCALING 0x0000 /* all positive */
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
unsigned short read_msg[READ_MSG_LEN];
|
||||
unsigned short write_msg[WRITE_MSG_LEN];
|
||||
}devPvt;
|
||||
|
||||
LOCAL long init_1771Ofe(struct aoRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
int failed;
|
||||
int i;
|
||||
|
||||
if (prec->out.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
/* pointer to the data addess structure */
|
||||
pabio = (struct abio *)&(prec->out.value);
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeAo,"OFE",NULL,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
drvStatus = (*pabDrv->getStatus)(drvPvt);
|
||||
if(drvStatus==abSuccess) {
|
||||
prec->rval = (unsigned short)pdevPvt->read_msg[pabio->signal];
|
||||
} else {
|
||||
status = 2;
|
||||
}
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
pdevPvt->write_msg[4] = OFE_BINARY | OFE_SCALING;
|
||||
drvStatus = (*pabDrv->startScan)(drvPvt,UPDATE_RATE,
|
||||
pdevPvt->write_msg,WRITE_MSG_LEN,
|
||||
pdevPvt->read_msg ,READ_MSG_LEN);
|
||||
if(drvStatus!=abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) startScan");
|
||||
break;
|
||||
}
|
||||
/*wait for up to 1 seconds*/
|
||||
for(failed=0; failed<10; failed++) {
|
||||
taskDelay(vxTicksPerSecond/10);
|
||||
drvStatus = (*pabDrv->getStatus)(drvPvt);
|
||||
if(drvStatus==abSuccess) {
|
||||
prec->rval=(unsigned short)pdevPvt->read_msg[pabio->signal];
|
||||
for(i=0;i<4;i++) {
|
||||
pdevPvt->write_msg[i] = pdevPvt->read_msg[i];
|
||||
}
|
||||
write_1771Ofe(prec);
|
||||
status = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
status = 0;
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiAb1771Ife (init_record) registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long write_1771Ofe(struct aoRecord *prec)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
abStatus drvStatus;
|
||||
void *drvPvt;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2); /*dont convert*/
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
pabio = (struct abio *)&(prec->out.value);
|
||||
pdevPvt->write_msg[pabio->signal] = prec->rval;
|
||||
drvStatus = (*pabDrv->updateAo)(drvPvt);
|
||||
if(drvStatus!=abSuccess) {
|
||||
if(recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM) && errVerbose
|
||||
&& (prec->stat!=WRITE_ALARM || prec->sevr!=INVALID_ALARM))
|
||||
recGblRecordError(-1,(void *)prec,"abDrv(updateAo)");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
LOCAL long linconv_1771Ofe(struct aoRecord *prec, int after)
|
||||
{
|
||||
|
||||
if(!after) return(0);
|
||||
/* set linear conversion slope*/
|
||||
prec->eslo = (prec->eguf -prec->egul)/4095.0;
|
||||
return(0);
|
||||
}
|
||||
617
src/dev/devABBINARY.c
Normal file
617
src/dev/devABBINARY.c
Normal file
@@ -0,0 +1,617 @@
|
||||
/* devABBINARY.c */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Bob Dalesio, Marty Kraimer
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 12-01-94 lrd combine the device support that was resident in the driver and
|
||||
* device support to significantly reduce the amount of code
|
||||
* ...
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <dbCommon.h>
|
||||
#include <biRecord.h>
|
||||
#include <boRecord.h>
|
||||
#include <mbbiRecord.h>
|
||||
#include <mbboRecord.h>
|
||||
#include <mbbiDirectRecord.h>
|
||||
#include <mbboDirectRecord.h>
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
}devPvt;
|
||||
|
||||
|
||||
/* Create the dsets*/
|
||||
LOCAL long ioinfo(int cmd, struct dbCommon *prec, IOSCANPVT *ppvt);
|
||||
LOCAL long read_bi(struct biRecord *prec);
|
||||
LOCAL long init_bi08(struct biRecord *prec);
|
||||
LOCAL long init_bi16(struct biRecord *prec);
|
||||
LOCAL long init_bi32(struct biRecord *prec);
|
||||
LOCAL long init_bi(struct biRecord *prec,abNumBits nBits);
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;} ABBIDSET;
|
||||
|
||||
ABBIDSET devBiAb= { 5, 0, 0, init_bi08, ioinfo, read_bi};
|
||||
ABBIDSET devBiAb16= { 5, 0, 0, init_bi16, ioinfo, read_bi};
|
||||
ABBIDSET devBiAb32= { 5, 0, 0, init_bi32, ioinfo, read_bi};
|
||||
|
||||
LOCAL long read_mbbi(struct mbbiRecord *prec);
|
||||
LOCAL long init_mbbi08(struct mbbiRecord *prec);
|
||||
LOCAL long init_mbbi16(struct mbbiRecord *prec);
|
||||
LOCAL long init_mbbi32(struct mbbiRecord *prec);
|
||||
LOCAL long init_mbbi(struct mbbiRecord *prec,abNumBits nBits);
|
||||
ABBIDSET devMbbiAb= { 5, 0, 0, init_mbbi08, ioinfo, read_mbbi};
|
||||
ABBIDSET devMbbiAb16={ 5, 0, 0, init_mbbi16, ioinfo, read_mbbi};
|
||||
ABBIDSET devMbbiAb32={ 5, 0, 0, init_mbbi32, ioinfo, read_mbbi};
|
||||
|
||||
LOCAL long read_mbbiDirect(struct mbbiDirectRecord *prec);
|
||||
LOCAL long init_mbbiDirect08(struct mbbiDirectRecord *prec);
|
||||
LOCAL long init_mbbiDirect16(struct mbbiDirectRecord *prec);
|
||||
LOCAL long init_mbbiDirect32(struct mbbiDirectRecord *prec);
|
||||
LOCAL long init_mbbiDirect(struct mbbiDirectRecord *prec,abNumBits nBits);
|
||||
ABBIDSET devMbbiDirectAb= { 5,0,0, init_mbbiDirect08,ioinfo, read_mbbiDirect};
|
||||
ABBIDSET devMbbiDirectAb16={ 5,0,0, init_mbbiDirect16,ioinfo, read_mbbiDirect};
|
||||
ABBIDSET devMbbiDirectAb32={ 5,0,0, init_mbbiDirect32,ioinfo, read_mbbiDirect};
|
||||
|
||||
LOCAL long write_bo(struct boRecord *prec);
|
||||
LOCAL long init_bo08(struct boRecord *prec);
|
||||
LOCAL long init_bo16(struct boRecord *prec);
|
||||
LOCAL long init_bo32(struct boRecord *prec);
|
||||
LOCAL long init_bo(struct boRecord *prec,abNumBits nBits);
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;
|
||||
} ABBODSET;
|
||||
|
||||
ABBODSET devBoAb= { 5, 0, 0, init_bo08, 0, write_bo};
|
||||
ABBODSET devBoAb16= { 5, 0, 0, init_bo16, 0, write_bo};
|
||||
ABBODSET devBoAb32= { 5, 0, 0, init_bo32, 0, write_bo};
|
||||
|
||||
LOCAL long write_mbbo(struct mbboRecord *prec);
|
||||
LOCAL long init_mbbo08(struct mbboRecord *prec);
|
||||
LOCAL long init_mbbo16(struct mbboRecord *prec);
|
||||
LOCAL long init_mbbo32(struct mbboRecord *prec);
|
||||
LOCAL long init_mbbo(struct mbboRecord *prec,abNumBits nBits);
|
||||
ABBODSET devMbboAb= { 5, 0, 0, init_mbbo08, 0, write_mbbo};
|
||||
ABBODSET devMbboAb16={ 5, 0, 0, init_mbbo16, 0, write_mbbo};
|
||||
ABBODSET devMbboAb32={ 5, 0, 0, init_mbbo32, 0, write_mbbo};
|
||||
|
||||
LOCAL long write_mbboDirect(struct mbboDirectRecord *prec);
|
||||
LOCAL long init_mbboDirect08(struct mbboDirectRecord *prec);
|
||||
LOCAL long init_mbboDirect16(struct mbboDirectRecord *prec);
|
||||
LOCAL long init_mbboDirect32(struct mbboDirectRecord *prec);
|
||||
LOCAL long init_mbboDirect(struct mbboDirectRecord *prec,abNumBits nBits);
|
||||
ABBODSET devMbboDirectAb= { 5, 0, 0, init_mbboDirect08, 0, write_mbboDirect};
|
||||
ABBODSET devMbboDirectAb16={ 5, 0, 0, init_mbboDirect16, 0, write_mbboDirect};
|
||||
ABBODSET devMbboDirectAb32={ 5, 0, 0, init_mbboDirect32, 0, write_mbboDirect};
|
||||
|
||||
LOCAL void devCallback(void * drvPvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
if(!pdevPvt) return;
|
||||
if(!pdevPvt->ioscanpvt) return;
|
||||
scanIoRequest(pdevPvt->ioscanpvt);
|
||||
}
|
||||
|
||||
LOCAL long ioinfo(int cmd, struct dbCommon *prec, IOSCANPVT *ppvt)
|
||||
{
|
||||
devPvt *pdevPvt;
|
||||
|
||||
pdevPvt = prec->dpvt;
|
||||
if(!pdevPvt) return(0);
|
||||
*ppvt = pdevPvt->ioscanpvt;
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_bi08(struct biRecord *prec)
|
||||
{
|
||||
return(init_bi(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_bi16(struct biRecord *prec)
|
||||
{
|
||||
return(init_bi(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_bi32(struct biRecord *prec)
|
||||
{
|
||||
return(init_bi(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long init_mbbi08(struct mbbiRecord *prec)
|
||||
{
|
||||
return(init_mbbi(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_mbbi16(struct mbbiRecord *prec)
|
||||
{
|
||||
return(init_mbbi(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_mbbi32(struct mbbiRecord *prec)
|
||||
{
|
||||
return(init_mbbi(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long init_mbbiDirect08(struct mbbiDirectRecord *prec)
|
||||
{
|
||||
return(init_mbbiDirect(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_mbbiDirect16(struct mbbiDirectRecord *prec)
|
||||
{
|
||||
return(init_mbbiDirect(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_mbbiDirect32(struct mbbiDirectRecord *prec)
|
||||
{
|
||||
return(init_mbbiDirect(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long init_bo08(struct boRecord *prec)
|
||||
{
|
||||
return(init_bo(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_bo16(struct boRecord *prec)
|
||||
{
|
||||
return(init_bo(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_bo32(struct boRecord *prec)
|
||||
{
|
||||
return(init_bo(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long init_mbbo08(struct mbboRecord *prec)
|
||||
{
|
||||
return(init_mbbo(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_mbbo16(struct mbboRecord *prec)
|
||||
{
|
||||
return(init_mbbo(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_mbbo32(struct mbboRecord *prec)
|
||||
{
|
||||
return(init_mbbo(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long init_mbboDirect08(struct mbboDirectRecord *prec)
|
||||
{
|
||||
return(init_mbboDirect(prec, abBit8));
|
||||
}
|
||||
LOCAL long init_mbboDirect16(struct mbboDirectRecord *prec)
|
||||
{
|
||||
return(init_mbboDirect(prec, abBit16));
|
||||
}
|
||||
LOCAL long init_mbboDirect32(struct mbboDirectRecord *prec)
|
||||
{
|
||||
return(init_mbboDirect(prec, abBit32));
|
||||
}
|
||||
|
||||
LOCAL long read_bi(struct biRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
unsigned long value;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->rval = value;
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_bi(struct biRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"init_record: bad INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
prec->mask=1;
|
||||
prec->mask <<= pabio->signal;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBi,"BINARY",devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long read_mbbi(struct mbbiRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
unsigned long value;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->rval = value;
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_mbbi(struct mbbiRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
prec->shft = prec->inp.value.abio.signal;
|
||||
prec->mask <<= prec->shft;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBi,"BINARY",devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long read_mbbiDirect(struct mbbiDirectRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
unsigned long value;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->rval = value;
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_mbbiDirect(struct mbbiDirectRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
|
||||
if (prec->inp.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
prec->shft = prec->inp.value.abio.signal;
|
||||
prec->mask <<= prec->shft;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBi,"BINARY",devCallback,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
scanIoInit(&pdevPvt->ioscanpvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
break;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long write_bo(struct boRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
return(0);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->updateBo)(drvPvt,prec->rval,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_bo(struct boRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
unsigned long value;
|
||||
|
||||
if (prec->out.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->out.value);
|
||||
prec->mask = 1;
|
||||
prec->mask <<= pabio->signal;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBo,"BINARY",NULL,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
return(status);
|
||||
}
|
||||
drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus==abSuccess) {
|
||||
prec->rval = value;
|
||||
status = 0;
|
||||
} else {
|
||||
status = 2;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long write_mbbo(struct mbboRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
return(0);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->updateBo)(drvPvt,prec->rval,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_mbbo(struct mbboRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
unsigned long value;
|
||||
|
||||
if (prec->out.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->out.value);
|
||||
prec->shft = prec->out.value.abio.signal;
|
||||
prec->mask <<= prec->shft;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBo,"BINARY",NULL,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
return(status);
|
||||
}
|
||||
drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus==abSuccess) {
|
||||
prec->rval = value;
|
||||
status = 0;
|
||||
} else {
|
||||
status = 2;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
LOCAL long write_mbboDirect(struct mbboDirectRecord *prec)
|
||||
{
|
||||
devPvt *pdevPvt = (devPvt *)prec->dpvt;
|
||||
void *drvPvt;
|
||||
abStatus drvStatus;
|
||||
unsigned long value = prec->rval;
|
||||
|
||||
if(!pdevPvt) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
return(0);
|
||||
}
|
||||
drvPvt = pdevPvt->drvPvt;
|
||||
drvStatus = (*pabDrv->updateBo)(drvPvt,value,prec->mask);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
LOCAL long init_mbboDirect(struct mbboDirectRecord *prec,abNumBits nBits)
|
||||
{
|
||||
struct abio *pabio;
|
||||
devPvt *pdevPvt;
|
||||
abStatus drvStatus;
|
||||
long status=0;
|
||||
void *drvPvt;
|
||||
unsigned long value;
|
||||
|
||||
if (prec->out.type != AB_IO){
|
||||
recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
pabio = (struct abio *)&(prec->out.value);
|
||||
prec->shft = prec->out.value.abio.signal;
|
||||
prec->mask <<= prec->shft;
|
||||
drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter,
|
||||
pabio->card,typeBo,"BINARY",NULL,&drvPvt);
|
||||
switch(drvStatus) {
|
||||
case abSuccess :
|
||||
pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
|
||||
prec->dpvt = pdevPvt;
|
||||
break;
|
||||
case abNewCard :
|
||||
pdevPvt = calloc(1,sizeof(devPvt));
|
||||
pdevPvt->drvPvt = drvPvt;
|
||||
prec->dpvt = pdevPvt;
|
||||
(*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt);
|
||||
drvStatus = (*pabDrv->setNbits)(drvPvt,nBits);
|
||||
if(drvStatus!=abSuccess) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"init_record setNbits");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_db_badField;
|
||||
recGblRecordError(status,(void *)prec,"init_record registerCard");
|
||||
return(status);
|
||||
}
|
||||
drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask);
|
||||
if(drvStatus==abSuccess) {
|
||||
prec->rval = value;
|
||||
status = 0;
|
||||
} else {
|
||||
status = 2;
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
114
src/dev/devABStatus.c
Normal file
114
src/dev/devABStatus.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* devABStatus.c */
|
||||
/*
|
||||
* Original Authors: Marty Kraimer (nagging by Ned Arnold,Bob dalesio)
|
||||
* Date: 3/6/91
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 04-20-95 mrk Initial version
|
||||
* ...
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <alarm.h>
|
||||
#include <cvtTable.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <link.h>
|
||||
#include <drvAb.h>
|
||||
#include <mbbiRecord.h>
|
||||
|
||||
typedef struct {
|
||||
void *drvPvt;
|
||||
IOSCANPVT ioscanpvt;
|
||||
}devPvt;
|
||||
|
||||
|
||||
/* Create the dsets*/
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;} ABBIDSET;
|
||||
|
||||
LOCAL long init_common(struct mbbiRecord *prec);
|
||||
LOCAL long read_adapter_status(struct mbbiRecord *prec);
|
||||
LOCAL long read_card_status(struct mbbiRecord *prec);
|
||||
ABBIDSET devMbbiAbAdapterStat= { 5, 0, 0, init_common, 0, read_adapter_status};
|
||||
ABBIDSET devMbbiAbCardStat= { 5, 0, 0, init_common, 0, read_card_status};
|
||||
|
||||
LOCAL long init_common(struct mbbiRecord *prec)
|
||||
{
|
||||
unsigned long *pstate_values;
|
||||
char *pstate_string;
|
||||
unsigned short *palarm_sevr;
|
||||
short i;
|
||||
|
||||
if(abFailure>=16) {
|
||||
epicsPrintf("devMbbiAbLinkStat. > 16 error status values\n");
|
||||
taskSuspend(0);
|
||||
return(0);
|
||||
}
|
||||
pstate_values = &(prec->zrvl);
|
||||
pstate_string = prec->zrst;
|
||||
palarm_sevr = &prec->zrsv;
|
||||
/*Following code assumes that abFailure is last status value*/
|
||||
for(i=0; i<=abFailure; i++ ,pstate_string += sizeof(prec->zrst)){
|
||||
pstate_values[i] = 1<<i;
|
||||
if(pstate_string[0]=='\0')
|
||||
strncpy(pstate_string,abStatusMessage[i],sizeof(prec->zrst)-1);
|
||||
if(i>0) palarm_sevr[i] = MAJOR_ALARM;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL long read_adapter_status(struct mbbiRecord *prec)
|
||||
{
|
||||
abStatus status;
|
||||
struct abio *pabio;
|
||||
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
status = (*pabDrv->adapterStatus)(pabio->link,pabio->adapter);
|
||||
prec->rval = 1 << status;;
|
||||
return(0);
|
||||
}
|
||||
LOCAL long read_card_status(struct mbbiRecord *prec)
|
||||
{
|
||||
abStatus status;
|
||||
struct abio *pabio;
|
||||
|
||||
pabio = (struct abio *)&(prec->inp.value);
|
||||
status = (*pabDrv->cardStatus)(pabio->link,pabio->adapter,pabio->card);
|
||||
prec->rval = 1 << status;;
|
||||
return(0);
|
||||
}
|
||||
1377
src/dev/devAllenBradleyOLD.c
Normal file
1377
src/dev/devAllenBradleyOLD.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -774,6 +774,9 @@ STATIC int ErResetAll(ApsErStruct *pParm)
|
||||
*
|
||||
* Receive a hardware IRQ from an ER board.
|
||||
*
|
||||
* BUG -- should add errMessage calls for problem events & include storm
|
||||
* control on them.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC void ErIrqHandler(ErLinkStruct *pLink)
|
||||
{
|
||||
|
||||
@@ -127,12 +127,14 @@ AT5VXIDSET_TM devTmAt5Vxi={6, NULL, NULL, NULL, NULL, read_timer, write_timer};
|
||||
* Values are converted to seconds.
|
||||
*/
|
||||
static double constants[] = {1e3,1e6,1e9,1e12};
|
||||
|
||||
static void localPostEvent (void *pParam);
|
||||
|
||||
static long read_timer(struct timerRecord *ptimer)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
int source;
|
||||
int ptst;
|
||||
unsigned source;
|
||||
unsigned ptst;
|
||||
double time_pulse[2]; /* delay and width */
|
||||
double constant;
|
||||
|
||||
@@ -164,22 +166,40 @@ static long read_timer(struct timerRecord *ptimer)
|
||||
|
||||
static long write_timer(struct timerRecord *ptimer)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
struct vmeio *pvmeio;
|
||||
void (*pCB)(void *);
|
||||
|
||||
pvmeio = (struct vmeio *)(&ptimer->out.value);
|
||||
|
||||
if (ptimer->tevt) {
|
||||
pCB = localPostEvent;
|
||||
}
|
||||
else {
|
||||
pCB = NULL;
|
||||
}
|
||||
|
||||
/* put the value to the ao driver */
|
||||
return at5vxi_one_shot(
|
||||
(int)ptimer->ptst, /* pre-trigger state */
|
||||
ptimer->t1dl, /* pulse offset */
|
||||
ptimer->t1wd, /* pulse width */
|
||||
(int)pvmeio->card, /* card number */
|
||||
(int)pvmeio->signal, /* signal number */
|
||||
(int)ptimer->tsrc, /* trigger source */
|
||||
((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */
|
||||
(int)ptimer->tevt); /* event to post on trigger */
|
||||
ptimer->ptst, /* pre-trigger state */
|
||||
ptimer->t1dl, /* pulse offset */
|
||||
ptimer->t1wd, /* pulse width */
|
||||
pvmeio->card, /* card number */
|
||||
pvmeio->signal, /* signal number */
|
||||
ptimer->tsrc, /* trigger source */
|
||||
pCB, /* addr of event post routine */
|
||||
ptimer); /* event to post on trigger */
|
||||
}
|
||||
|
||||
|
||||
static void localPostEvent (void *pParam)
|
||||
{
|
||||
struct timerRecord *ptimer = pParam;
|
||||
|
||||
if (ptimer->tevt) {
|
||||
post_event(ptimer->tevt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static long init_ai( struct aiRecord *pai)
|
||||
{
|
||||
@@ -342,7 +362,7 @@ static long read_bi(struct biRecord *pbi)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
long status;
|
||||
long value;
|
||||
unsigned long value;
|
||||
|
||||
|
||||
pvmeio = (struct vmeio *)&(pbi->inp.value);
|
||||
@@ -357,9 +377,9 @@ static long read_bi(struct biRecord *pbi)
|
||||
|
||||
static long init_bo(struct boRecord *pbo)
|
||||
{
|
||||
unsigned int value;
|
||||
long status=0;
|
||||
struct vmeio *pvmeio;
|
||||
unsigned long value;
|
||||
long status=0;
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
/* bo.out must be an VME_IO */
|
||||
switch (pbo->out.type) {
|
||||
|
||||
@@ -181,6 +181,8 @@ struct ioCard {
|
||||
#define CONST_NUM_LINKS 6
|
||||
#define STATIC
|
||||
|
||||
STATIC int devAvme9440Report();
|
||||
|
||||
static unsigned short BASEADD;
|
||||
#define LED_INIT 0x02
|
||||
#define LED_OKRUN 0x03
|
||||
@@ -206,7 +208,7 @@ struct {
|
||||
DEVSUPFUN write_bo; /* output command goes here */
|
||||
}devBoAvme9440={
|
||||
5,
|
||||
NULL,
|
||||
(DEVSUPFUN) devAvme9440Report,
|
||||
init,
|
||||
init_bo_record,
|
||||
NULL,
|
||||
@@ -263,7 +265,36 @@ struct {
|
||||
NULL,
|
||||
read_mbbi
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Ultra groovy and useful reporting function called from 'dbior'.
|
||||
*
|
||||
**************************************************************************/
|
||||
STATIC int devAvme9440Report()
|
||||
{
|
||||
int LinkNum = 0;
|
||||
int CardBase = BASEADD;
|
||||
int IntVec = INT_VEC_BASE;
|
||||
|
||||
while (LinkNum < avme9440_num_links)
|
||||
{
|
||||
if (cards[LinkNum].card != NULL)
|
||||
{
|
||||
printf(" Link %02.2d at 0x%4.4X, IRQ 0x%2.2X, input 0x%04.4X, output 0x%04.4X\n",
|
||||
LinkNum,
|
||||
CardBase,
|
||||
IntVec,
|
||||
cards[LinkNum].card->inputData,
|
||||
cards[LinkNum].card->outputData);
|
||||
|
||||
}
|
||||
LinkNum++;
|
||||
CardBase += sizeof(struct avme9440);
|
||||
IntVec++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
|
||||
@@ -77,10 +77,7 @@ struct boRecord *pbo;
|
||||
long status;
|
||||
|
||||
status = recGblInitFastOutLink(&(pbo->out), (void *) pbo, DBR_LONG, "RVAL");
|
||||
|
||||
if (pbo->out.type != CA_LINK)
|
||||
status = 2;
|
||||
|
||||
status = 2;
|
||||
return status;
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
/* base/src/dev $Id$ */
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.23 1995/01/06 16:55:52 winans
|
||||
* Added the log parameter to the doc
|
||||
*
|
||||
*
|
||||
* Author: John Winans
|
||||
* Origional Author: Ned D. Arnold
|
||||
* Date: 11-20-91
|
||||
@@ -172,6 +177,15 @@ gDset *dset; /* pointer to dset used to reference the init function */
|
||||
|
||||
return(OK);
|
||||
}
|
||||
|
||||
static void RegisterProcessCallback(CALLBACK *pCallback, int Priority, void *Parm)
|
||||
{
|
||||
callbackSetCallback(devGpibLib_processCallback, pCallback);
|
||||
callbackSetPriority(Priority, pCallback);
|
||||
callbackSetUser(Parm, pCallback);
|
||||
callbackRequest(pCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@@ -1288,9 +1302,13 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1335,9 +1353,13 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_aiGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1382,9 +1404,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1426,9 +1452,14 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -1458,9 +1489,13 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1505,9 +1540,13 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_liGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1551,9 +1590,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1595,9 +1638,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -1624,9 +1671,13 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else /* interpret response that came back */
|
||||
{
|
||||
@@ -1669,9 +1720,13 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_biGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1718,9 +1773,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback); /* jrw */
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1763,9 +1822,14 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -1792,9 +1856,13 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1839,9 +1907,13 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_mbbiGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1888,9 +1960,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1934,9 +2010,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback); /* jrw */
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -1966,9 +2046,13 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback); /* jrw */
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2013,9 +2097,13 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_stringinGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -2051,9 +2139,13 @@ struct gpibDpvt *pdpvt;
|
||||
psi->val[40] = '\0';
|
||||
psi->udf = FALSE;
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback); /* jrw */
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -2094,9 +2186,13 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback); /* jrw */
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -2279,14 +2375,16 @@ unsigned short val; /* used for EFAST operations only */
|
||||
*
|
||||
* The reason it is done this way is because the process() call may
|
||||
* recursively call itself when records are chained and the callback
|
||||
* task's stack is larger... just for this purpose.
|
||||
* task's stack is larger... just for that reason.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
devGpibLib_processCallback(pDpvt)
|
||||
struct gpibDpvt *pDpvt;
|
||||
devGpibLib_processCallback(CALLBACK *pCallback)
|
||||
{
|
||||
struct gpibDpvt *pDpvt;
|
||||
callbackGetUser(pDpvt, pCallback);
|
||||
|
||||
dbScanLock(pDpvt->precord);
|
||||
(*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord);
|
||||
dbScanUnlock(pDpvt->precord);
|
||||
@@ -2369,6 +2467,7 @@ void (*process)();
|
||||
/* make sure the command type makes sendse for the record type */
|
||||
|
||||
if (parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBREAD &&
|
||||
parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBWRITE &&
|
||||
parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBSOFT &&
|
||||
parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBREADW)
|
||||
{
|
||||
@@ -2445,9 +2544,11 @@ int
|
||||
devGpibLib_wfGpibWork(pdpvt)
|
||||
struct gpibDpvt *pdpvt;
|
||||
{
|
||||
int OperationStatus;
|
||||
struct waveformRecord *pwf= ((struct waveformRecord *)(pdpvt->precord));
|
||||
struct gpibCmd *pCmd;
|
||||
struct devGpibParmBlock *parmBlock;
|
||||
short ibnode = pdpvt->head.device;
|
||||
|
||||
parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]);
|
||||
|
||||
@@ -2458,27 +2559,60 @@ struct gpibDpvt *pdpvt;
|
||||
if(*(parmBlock->debugFlag))
|
||||
printf("devGpibLib_wfGpibWork: starting ...command type = %d\n",pCmd->type);
|
||||
|
||||
if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR)
|
||||
{
|
||||
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest((void *)pdpvt);
|
||||
/**** Handle writes internally... the generic routine will not work ****/
|
||||
if (pCmd->type == GPIBWRITE)
|
||||
{
|
||||
/*
|
||||
* check to see if this node has timed out within last 10 sec
|
||||
*/
|
||||
if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) )
|
||||
{
|
||||
if (*parmBlock->debugFlag)
|
||||
printf("devGpibLib_xxGpibWork(): timeout flush\n");
|
||||
|
||||
OperationStatus = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
OperationStatus = (*(drvGpib.writeIb))(pdpvt->head.pibLink,
|
||||
ibnode, pdpvt->msg, pCmd->msgLen, pdpvt->head.dmaTimeout);
|
||||
|
||||
if(*parmBlock->debugFlag)
|
||||
printf("devGpibLib_xxGpibWork : done, status = %d\n",OperationStatus);
|
||||
|
||||
/* if error occurrs then mark it with time */
|
||||
if(OperationStatus == ERROR)
|
||||
{
|
||||
(pdpvt->phwpvt->tmoCount)++; /* count timeouts */
|
||||
pdpvt->phwpvt->tmoVal = tickGet(); /* set last timeout time */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OperationStatus = devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1);
|
||||
}
|
||||
|
||||
if (OperationStatus == ERROR)
|
||||
{
|
||||
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pCmd->type != GPIBREADW)
|
||||
devGpibLib_wfGpibFinish(pdpvt); /* If not waiting on SRQ, finish */
|
||||
else
|
||||
{
|
||||
if (*(parmBlock->debugFlag) || ibSrqDebug)
|
||||
printf("%s: marking srq Handler for READW operation\n", parmBlock->name);
|
||||
pdpvt->phwpvt->srqCallback = (int (*)())(((gDset*)(pwf->dset))->funPtr[pwf->dset->number + 2]);
|
||||
pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */
|
||||
return(BUSY); /* indicate device still in use */
|
||||
else
|
||||
{
|
||||
if (*(parmBlock->debugFlag) || ibSrqDebug)
|
||||
printf("%s: marking srq Handler for READW operation\n", parmBlock->name);
|
||||
pdpvt->phwpvt->srqCallback = (int (*)())(((gDset*)(pwf->dset))->funPtr[pwf->dset->number + 2]);
|
||||
pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */
|
||||
return(BUSY); /* indicate device still in use */
|
||||
}
|
||||
}
|
||||
}
|
||||
return(IDLE); /* indicate device is now idle */
|
||||
}
|
||||
|
||||
@@ -2509,9 +2643,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
|
||||
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest((void *)pdpvt);
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
}
|
||||
|
||||
devGpibLib_wfGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -2547,9 +2679,8 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest((void *)pdpvt);
|
||||
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -115,9 +115,9 @@ static long bi_ioinfo(
|
||||
|
||||
static long read_bi(struct biRecord *pbi)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
struct vmeio *pvmeio;
|
||||
long status;
|
||||
long value;
|
||||
unsigned value;
|
||||
|
||||
|
||||
pvmeio = (struct vmeio *)&(pbi->inp.value);
|
||||
@@ -198,7 +198,7 @@ static long read_mbbi(struct mbbiRecord *pmbbi)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
long status;
|
||||
unsigned long value;
|
||||
unsigned value;
|
||||
|
||||
|
||||
pvmeio = (struct vmeio *)&(pmbbi->inp.value);
|
||||
@@ -213,9 +213,9 @@ static long read_mbbi(struct mbbiRecord *pmbbi)
|
||||
|
||||
static long init_mbbo(struct mbboRecord *pmbbo)
|
||||
{
|
||||
unsigned long value;
|
||||
struct vmeio *pvmeio;
|
||||
long status = 0;
|
||||
unsigned value;
|
||||
struct vmeio *pvmeio;
|
||||
long status = 0;
|
||||
|
||||
/* mbbo.out must be an VME_IO */
|
||||
switch (pmbbo->out.type) {
|
||||
@@ -238,9 +238,9 @@ static long init_mbbo(struct mbboRecord *pmbbo)
|
||||
|
||||
static long write_mbbo(struct mbboRecord *pmbbo)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
struct vmeio *pvmeio;
|
||||
long status;
|
||||
unsigned long value;
|
||||
unsigned value;
|
||||
|
||||
|
||||
pvmeio = &(pmbbo->out.value.vmeio);
|
||||
|
||||
@@ -81,7 +81,7 @@ static long init_record(pmbbo)
|
||||
case (VME_IO) :
|
||||
pvmeio = &(pmbbo->out.value.vmeio);
|
||||
pmbbo->shft = pvmeio->signal;
|
||||
pmbbo->mask = pmbbo->shft;
|
||||
pmbbo->mask <<= pmbbo->shft;
|
||||
status = xy220_read(pvmeio->card,pmbbo->mask,&value);
|
||||
if(status==0) pmbbo->rbv = pmbbo->rval = value;
|
||||
else status = 2;
|
||||
|
||||
@@ -77,10 +77,7 @@ struct mbboRecord *pmbbo;
|
||||
long status;
|
||||
|
||||
status = recGblInitFastOutLink(&(pmbbo->out), (void *) pmbbo, DBR_ULONG, "RVAL");
|
||||
|
||||
if (pmbbo->out.type == CA_LINK)
|
||||
status = 2;
|
||||
|
||||
status = 2;
|
||||
return status;
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
@@ -83,7 +83,7 @@ static long init_record(pmbbo)
|
||||
case (VME_IO) :
|
||||
pvmeio = &(pmbbo->out.value.vmeio);
|
||||
pmbbo->shft = pvmeio->signal;
|
||||
pmbbo->mask = pmbbo->shft;
|
||||
pmbbo->mask <<= pmbbo->shft;
|
||||
status = xy220_read(pvmeio->card,pmbbo->mask,&value);
|
||||
if(status==0) pmbbo->rbv = pmbbo->rval = value;
|
||||
else status = 2;
|
||||
|
||||
1121
src/dev/devMpc.c
Normal file
1121
src/dev/devMpc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -74,6 +74,8 @@
|
||||
#include <choicePulseDelay.h>
|
||||
#include <pulseTrainRecord.h>
|
||||
#include <choicePulseTrain.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
/* Create the dsets for devMz8310 */
|
||||
static long report();
|
||||
static long init();
|
||||
@@ -303,7 +305,7 @@ static long init(after)
|
||||
|
||||
if(after)return(0);
|
||||
if(sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, 0, (void *)&shortaddr)) {
|
||||
logMsg("devMz8310: sysBusToLocalAdrs failed\n",0);
|
||||
epicsPrintf ("devMz8310: sysBusToLocalAdrs failed\n",0);
|
||||
exit(1);
|
||||
}
|
||||
memset((char *)&mz8310_info[0],0,MAXCARDS*sizeof(struct mz8310_info));
|
||||
@@ -344,7 +346,7 @@ static long init(after)
|
||||
}
|
||||
|
||||
if(rebootHookAdd(Mz8310_shutdown)<0)
|
||||
logMsg("Mz8310_shutdown: reboot hook add failed\n");
|
||||
epicsPrintf ("Mz8310_shutdown: reboot hook add failed\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
1035
src/dev/devSysmon.c
1035
src/dev/devSysmon.c
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,8 @@
|
||||
static long read_timer();
|
||||
static long write_timer();
|
||||
|
||||
static void localPostEvent (void *pParam);
|
||||
|
||||
struct tmdset {
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
@@ -83,22 +85,22 @@ static double constants[] = {1e3,1e6,1e9,1e12};
|
||||
|
||||
static long read_timer(struct timerRecord *ptimer)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
int source;
|
||||
int ptst;
|
||||
double time_pulse[2]; /* delay and width */
|
||||
double constant;
|
||||
struct vmeio *pvmeio;
|
||||
unsigned source;
|
||||
unsigned ptst;
|
||||
double time_pulse[2]; /* delay and width */
|
||||
double constant;
|
||||
|
||||
/* only supports a one channel VME timer module !!!! */
|
||||
pvmeio = (struct vmeio *)(&ptimer->out.value);
|
||||
|
||||
if (mz8310_one_shot_read(
|
||||
&ptst, /* pre-trigger state */
|
||||
&(time_pulse[0]), /* offset of pulse */
|
||||
&(time_pulse[1]), /* width of pulse */
|
||||
(int)pvmeio->card, /* card number */
|
||||
(int)pvmeio->signal, /* signal number */
|
||||
&source) != 0) { /* trigger source */
|
||||
&ptst, /* pre-trigger state */
|
||||
&(time_pulse[0]), /* offset of pulse */
|
||||
&(time_pulse[1]), /* width of pulse */
|
||||
pvmeio->card, /* card number */
|
||||
pvmeio->signal, /* signal number */
|
||||
&source) != 0) { /* trigger source */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -117,19 +119,36 @@ static long read_timer(struct timerRecord *ptimer)
|
||||
static long write_timer(struct timerRecord *ptimer)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
void (*pCB)(void *);
|
||||
|
||||
/* put the value to the ao driver */
|
||||
pvmeio = (struct vmeio *)(&ptimer->out.value);
|
||||
|
||||
if (ptimer->tevt) {
|
||||
pCB = localPostEvent;
|
||||
}
|
||||
else {
|
||||
pCB = NULL;
|
||||
}
|
||||
|
||||
/* put the value to the ao driver */
|
||||
return mz8310_one_shot(
|
||||
(int)ptimer->ptst, /* pre-trigger state */
|
||||
ptimer->t1dl, /* pulse offset */
|
||||
ptimer->t1wd, /* pulse width */
|
||||
(int)pvmeio->card, /* card number */
|
||||
(int)pvmeio->signal, /* signal number */
|
||||
(int)ptimer->tsrc, /* trigger source */
|
||||
((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */
|
||||
(int)ptimer->tevt); /* event to post on trigger */
|
||||
ptimer->ptst, /* pre-trigger state */
|
||||
ptimer->t1dl, /* pulse offset */
|
||||
ptimer->t1wd, /* pulse width */
|
||||
pvmeio->card, /* card number */
|
||||
pvmeio->signal, /* signal number */
|
||||
ptimer->tsrc, /* trigger source */
|
||||
pCB, /* addr of event post routine */
|
||||
ptimer); /* event to post on trigger */
|
||||
}
|
||||
|
||||
static void localPostEvent (void *pParam)
|
||||
{
|
||||
struct timerRecord *ptimer = pParam;
|
||||
|
||||
if (ptimer->tevt) {
|
||||
post_event (ptimer->tevt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
758
src/dev/devWfPentek4261.c
Normal file
758
src/dev/devWfPentek4261.c
Normal file
@@ -0,0 +1,758 @@
|
||||
|
||||
/*
|
||||
*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <vme.h>
|
||||
#include <iv.h>
|
||||
#include <vxLib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <module_types.h>
|
||||
|
||||
#include <alarm.h>
|
||||
#include <dbDefs.h>
|
||||
#include <recSup.h>
|
||||
#include <devSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <callback.h>
|
||||
#include <waveformRecord.h>
|
||||
|
||||
/*
|
||||
This is waveform record support for the Pentek 4261A 10MHz 12 bit ADC.
|
||||
All scan types are supported, including I/O interrupt scan. The ADC
|
||||
currently supports the edge trigger mode for starting the sampling
|
||||
operation. The ADC is programmed to record an array of samples the
|
||||
same size as the waveform record. The internal or an external clock
|
||||
may be used as the sampling clock. The sampling can be triggered by
|
||||
an external signal, or automatically by record support.
|
||||
|
||||
Using I/O interrupt scanning, the record is processed and the waveform
|
||||
record array is updated each time an external trigger signal is present.
|
||||
With the other scan types, the waveform array is updated each time the
|
||||
record is processed.
|
||||
|
||||
I could not get the continuous bank swapping feature to work with the
|
||||
trigger, I got a glitch in the data approximately 1 us into the sampling.
|
||||
After each round of sampling is done, the buffers are reset.
|
||||
|
||||
The function ConfigurePentekADC() must be run in the
|
||||
vxWorks startup.cmd file for every ADC board present. This function
|
||||
makes it easy to configure jumpers on the ADC and inform EPICS of them.
|
||||
|
||||
parameters:
|
||||
|
||||
ConfigurePentekADC(
|
||||
int card, - the ADC card number in the crate (0=first)
|
||||
unsigned long a16_base, - where the card exists in A16
|
||||
unsigned long a32_base, - where the card exists in A32 (not used)
|
||||
int irq_vector, - interrupt request vector number
|
||||
int irq_level, - interrupt request level number
|
||||
int word_clock, - the ADC word clock (see 4261 documentation)
|
||||
unsigned long clock_freq - clock frequency (see notes below)
|
||||
)
|
||||
|
||||
Good values to use for configuring the module:
|
||||
A16 base address = 0x0200
|
||||
A32 base address = 0xc0200000 (A32 not used in the support)
|
||||
IRQ vector = 121
|
||||
IRQ level = 3
|
||||
word clock = 32
|
||||
|
||||
The number of samples programed (size of waveform record) must be
|
||||
divisible by the word clock.
|
||||
|
||||
The operating mode the ADC is selected using the input field parm area.
|
||||
The user must supply two option, the clock type and the trigger type,
|
||||
in that order. Here are all the valid parm field entry and what they
|
||||
represent (all are entered as strings without the quotes):
|
||||
|
||||
"x_clock,x_trigger" = external clock and external trigger inputs.
|
||||
"i_clock,x_trigger" = internal clock and external trigger input.
|
||||
"x_clock,i_trigger" = external clock and internal trigger input.
|
||||
"i_clock,i_trigger" = internal clock and internal trigger input.
|
||||
|
||||
If external trigger is selected and scan type is not I/O interrupt scan,
|
||||
then sampling will start on the next external trigger input after device
|
||||
support completes.
|
||||
|
||||
If internal trigger is selected, the sampling will be started by software
|
||||
at the end of device support. Internal trigger only applied to scan
|
||||
types that are not I/O interrupt scanned.
|
||||
|
||||
Configuration function clock frequency note:
|
||||
The clock frequency specified in the configuration function is only
|
||||
applicable to the internal clock. When the external clock is used,
|
||||
the clock frequency parameter is meaningless, the sampling clock
|
||||
will be the external clock frequency. When the internal clock is
|
||||
used (10MHz), the clock frequency parameter will be the sampling
|
||||
frequency. The 10Mhz internal clock must be divisible by the clock
|
||||
frequency value.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Modify devSup.ascii and do a makesdr. Add devPentekADC
|
||||
device support to the waveform record.
|
||||
|
||||
Running ReportPentekADC() will print a report of configuration for
|
||||
the ADC.
|
||||
|
||||
Waveform data types of long, short, unsigned short, double, and float are
|
||||
supported.
|
||||
*/
|
||||
|
||||
long devWfPentek4261Debug=0;
|
||||
|
||||
#define CMD_ADDED 0
|
||||
#define CMD_DELETED 1
|
||||
|
||||
#define A16_SIZE 256
|
||||
#define A32_SIZE 256
|
||||
#define MAX_CARDS 4
|
||||
#define MAX_FILES_ALLOWED 20
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
/* IMPORTANT, LOOK HERE: test areas - good ones to use for jumpers */
|
||||
/* They are good setting for the jumpers for the first ADC card,
|
||||
none of these defines are actually used, are they parameters come
|
||||
from the ConfigurePentekADC().
|
||||
*/
|
||||
|
||||
#define A16_BASE 0xffff0200
|
||||
#define A32_BASE 0xc0200000 /* not really used currently */
|
||||
#define IRQ_VECTOR ((unsigned char)121)
|
||||
#define IRQ_LEVEL 3
|
||||
#define WORD_CLOCK 32 /* my default */
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
#define INTERNAL_CLOCK 10000000 /* 10MHz */
|
||||
|
||||
#define SAMPLE_CLOCK_SELECT 0x08
|
||||
#define EXT_TRIGGER_ENABLE 0x04
|
||||
#define RESET_RUN_FF 0x02
|
||||
#define SET_RUN_FF 0x01
|
||||
|
||||
#define START_MODE 0x20
|
||||
|
||||
#define EXTERNAL 0
|
||||
#define INTERNAL 1
|
||||
|
||||
struct card {
|
||||
int in_use;
|
||||
unsigned long a16_base;
|
||||
unsigned long a32_base;
|
||||
int irq_vector;
|
||||
int irq_level;
|
||||
int word_clock;
|
||||
unsigned long clock_freq;
|
||||
int soc;
|
||||
};
|
||||
typedef struct card CARD;
|
||||
|
||||
/* careful here: horrid looking structure -offset and access (rw=read/write) */
|
||||
struct adc {
|
||||
unsigned short ctc0_bs_a; /* 0x00 rw */
|
||||
unsigned short ctc1_bs_b; /* 0x02 rw */
|
||||
unsigned short ctc2_clock_div; /* 0x04 rw */
|
||||
unsigned short ctc_control; /*c0x06 rw */ /*char a;*/ short junk1[0x04];
|
||||
unsigned short int_id_status; /*c0x10 rw */ /*char b;*/
|
||||
unsigned short int_mask; /*c0x12 rw */ /*char c;*/
|
||||
unsigned short command; /*c0x14 rw */ /*char d;*/
|
||||
unsigned short trigger; /*c0x16 rw */ /*char e;*/
|
||||
unsigned short reserved; /* 0x18 -- */
|
||||
unsigned short tag_cmd; /*c0x1a rw */ /*char f;*/
|
||||
unsigned short tag_data; /* 0x1c rw */
|
||||
unsigned short int_status; /*c0x1e r- */ /*char g;*/ char junk2[0x10];
|
||||
unsigned short vme_fifo; /* 0x30 rw */
|
||||
};
|
||||
typedef struct adc ADC;
|
||||
|
||||
struct pvt_area {
|
||||
CALLBACK callback;
|
||||
int clock_mode;
|
||||
int trigger_mode;
|
||||
int last_int_status;
|
||||
int last_status;
|
||||
volatile ADC* adc_regs;
|
||||
unsigned short div;
|
||||
int card;
|
||||
int file_count;
|
||||
unsigned long total_count;
|
||||
};
|
||||
typedef struct pvt_area PVT_AREA;
|
||||
|
||||
static long dev_report(int level);
|
||||
static long dev_init(int after);
|
||||
static long dev_init_rec(struct waveformRecord* pr);
|
||||
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt);
|
||||
static long dev_read(struct waveformRecord* pr);
|
||||
static long dev_complete_read(struct waveformRecord* pr);
|
||||
static long dev_other_read(struct waveformRecord* pr);
|
||||
static void irq_func(void*);
|
||||
static int full_reset(PVT_AREA* pvt);
|
||||
static int buffer_reset(PVT_AREA* pvt);
|
||||
static long setup(PVT_AREA* pvt);
|
||||
|
||||
void ConfigurePentekADC(int,unsigned long,unsigned long,int,int,int,unsigned long);
|
||||
|
||||
/* generic structure for device support */
|
||||
typedef struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_write;
|
||||
DEVSUPFUN conv;
|
||||
} ADC_DSET;
|
||||
|
||||
ADC_DSET devWfPentek4261=
|
||||
{6,dev_report,dev_init,dev_init_rec,dev_ioint_info,dev_read,NULL};
|
||||
|
||||
static IOSCANPVT ioscanpvt;
|
||||
static CARD** cards=0;
|
||||
|
||||
static void callback(CALLBACK* cback)
|
||||
{
|
||||
struct dbCommon* pc;
|
||||
struct rset *prset;
|
||||
|
||||
callbackGetUser(pc,cback);
|
||||
prset=(struct rset *)(pc->rset);
|
||||
|
||||
/* process the record */
|
||||
dbScanLock(pc);
|
||||
(*prset->process)(pc);
|
||||
dbScanUnlock(pc);
|
||||
}
|
||||
|
||||
static long dev_report(int level)
|
||||
{
|
||||
int i;
|
||||
volatile ADC* adc_regs;
|
||||
|
||||
if(cards==0)
|
||||
printf("No Pentek ADC cards configured in system\n");
|
||||
else
|
||||
{
|
||||
for(i=0;i<MAX_CARDS;i++)
|
||||
{
|
||||
if(cards[i]!=0)
|
||||
{
|
||||
adc_regs=(ADC*)(i*A16_SIZE+cards[i]->a16_base);
|
||||
|
||||
printf("Pentek 4261A ADC card %d information:\n",i);
|
||||
printf(" a16 base=%8.8x",cards[i]->a16_base);
|
||||
printf(" a32 base=%8.8x\n",cards[i]->a32_base);
|
||||
printf(" irq vector=%d",cards[i]->irq_vector);
|
||||
printf(" irq level=%d\n",cards[i]->irq_level);
|
||||
printf(" word clock=%d",cards[i]->word_clock);
|
||||
printf(" clock frequency=%ld\n",cards[i]->clock_freq);
|
||||
|
||||
printf(" status=%4.4x\n", adc_regs->int_id_status);
|
||||
printf(" int mask=%4.4x\n", adc_regs->int_mask);
|
||||
printf(" command=%4.4x\n", adc_regs->command);
|
||||
printf(" trigger=%4.4x\n", adc_regs->trigger);
|
||||
printf(" int status=%4.4x\n", adc_regs->int_status);
|
||||
}
|
||||
else
|
||||
printf("Pentek 4261A ADC card %d not installed\n",i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_init(int after)
|
||||
{
|
||||
if(after) return(0);
|
||||
scanIoInit(&ioscanpvt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_init_rec(struct waveformRecord* pr)
|
||||
{
|
||||
volatile ADC* adc_regs;
|
||||
PVT_AREA* pvt;
|
||||
struct vmeio *pvmeio = (struct vmeio *)&(pr->inp.value);
|
||||
char *clock_type,*trigger_type;
|
||||
char parm[40];
|
||||
char** save_area=NULL;
|
||||
|
||||
if(pr->inp.type != VME_IO)
|
||||
{
|
||||
recGblRecordError(S_db_badField,(void *)pr,
|
||||
"devPentekADC (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
if(cards[pvmeio->card]==0)
|
||||
{
|
||||
recGblRecordError(S_dev_badCard,(void *)pr,
|
||||
"devPentekADC (init_record) Card not Configured!");
|
||||
return(S_dev_badCard);
|
||||
}
|
||||
if(cards[pvmeio->card]->in_use==1)
|
||||
{
|
||||
recGblRecordError(S_dev_badCard,(void *)pr,
|
||||
"devPentekADC (init_record) Card already in use");
|
||||
return(S_dev_badCard);
|
||||
}
|
||||
if(pr->nelm%cards[pvmeio->card]->word_clock!=0)
|
||||
{
|
||||
recGblRecordError(S_db_badField, (void *)pr,
|
||||
"devPentekADC (init_record) num of elements must be divisible by the word clock");
|
||||
return(S_db_badField);
|
||||
}
|
||||
|
||||
pvt=(PVT_AREA*)malloc(sizeof(PVT_AREA));
|
||||
cards[pvmeio->card]->in_use=1;
|
||||
strcpy(parm,pvmeio->parm);
|
||||
|
||||
if((clock_type=strtok_r(parm,",",save_area))==NULL)
|
||||
{
|
||||
printf("Clock type parameter missing from parm field\n");
|
||||
printf(" Defaulting to i_clock,i_trigger (internal clock/trigger)\n");
|
||||
clock_type="i_clock";
|
||||
trigger_type="i_trigger";
|
||||
}
|
||||
else if((trigger_type=strtok_r(NULL,",",save_area))==NULL)
|
||||
{
|
||||
printf("Triggert type parameter missing from parm field\n");
|
||||
printf(" Defaulting to i_trigger (internal trigger)\n");
|
||||
trigger_type="i_trigger";
|
||||
}
|
||||
|
||||
if( strcmp(clock_type,"i_clock")==0 )
|
||||
pvt->clock_mode=INTERNAL;
|
||||
else if( strcmp(clock_type,"x_clock")==0 )
|
||||
pvt->clock_mode=EXTERNAL;
|
||||
else
|
||||
{
|
||||
printf("Invalid parm for clock type, must be i_clock or x_clock\n");
|
||||
pvt->clock_mode=INTERNAL;
|
||||
}
|
||||
|
||||
if( strcmp(trigger_type,"i_trigger")==0 )
|
||||
pvt->trigger_mode=INTERNAL;
|
||||
else if( strcmp(trigger_type,"x_trigger")==0 )
|
||||
pvt->trigger_mode=EXTERNAL;
|
||||
else
|
||||
{
|
||||
printf("Invalid parm for clock type, must be i_trigger or x_trigger\n");
|
||||
pvt->trigger_mode=INTERNAL;
|
||||
}
|
||||
|
||||
adc_regs=(ADC*)(pvmeio->card*A16_SIZE+cards[pvmeio->card]->a16_base);
|
||||
|
||||
callbackSetCallback(callback,&pvt->callback);
|
||||
callbackSetPriority(pr->prio,&pvt->callback);
|
||||
callbackSetUser(pr,&pvt->callback);
|
||||
|
||||
pvt->adc_regs=adc_regs;
|
||||
pvt->card=pvmeio->card;
|
||||
pvt->file_count=0;
|
||||
pr->dpvt=(void*)pvt;
|
||||
|
||||
/* program number of samples and sample clock */
|
||||
pvt->div=pr->nelm/cards[pvmeio->card]->word_clock;
|
||||
|
||||
/* install the interrupt handler */
|
||||
if(intConnect(INUM_TO_IVEC(cards[pvmeio->card]->irq_vector),
|
||||
(VOIDFUNCPTR)irq_func, (int)pr)!=OK)
|
||||
{ printf("intConnect failed\n"); return -1; }
|
||||
|
||||
sysIntEnable(cards[pvmeio->card]->irq_level);
|
||||
full_reset(pvt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_reset(PVT_AREA* pvt)
|
||||
{
|
||||
pvt->adc_regs->command=0x00; /* reset the card */
|
||||
pvt->adc_regs->command=0x90; /* vme enable, no reset mode */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int full_reset(PVT_AREA* pvt)
|
||||
{
|
||||
unsigned long clock_div,clock_freq,sample_freq;
|
||||
unsigned short clock_div_short;
|
||||
unsigned char trig;
|
||||
|
||||
buffer_reset(pvt);
|
||||
|
||||
/* auto arm mode not enabled */
|
||||
trig=0x20; /* positive going edge */
|
||||
|
||||
if(pvt->clock_mode==EXTERNAL) trig|=0x08; /* ext clock */
|
||||
|
||||
pvt->adc_regs->trigger=trig; /* set the trigger reg */
|
||||
pvt->adc_regs->int_id_status=cards[pvt->card]->irq_vector;
|
||||
|
||||
/* program counter for bank A */
|
||||
pvt->adc_regs->ctc_control=0x00|0x30|0x04; /* CTC-0,LSB-MSB,mode */
|
||||
pvt->adc_regs->ctc0_bs_a=(unsigned short)(pvt->div&0x00ff);
|
||||
pvt->adc_regs->ctc0_bs_a=(unsigned short)(pvt->div>>8);
|
||||
/* program counter for bank B */
|
||||
pvt->adc_regs->ctc_control=0x40|0x30|0x04; /* CTC-1,LSB-MSB,mode */
|
||||
pvt->adc_regs->ctc1_bs_b=(unsigned short)(pvt->div&0x00ff);
|
||||
pvt->adc_regs->ctc1_bs_b=(unsigned short)(pvt->div>>8);
|
||||
|
||||
/* printf("bank div=%4.4x\n",pvt->div); */
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/*
|
||||
careful here, if changing code to use internal clock, use the
|
||||
code below to program the sample clock divisor, remember that if
|
||||
sample clock divisor is one, then the else portion of the code must
|
||||
be used.
|
||||
|
||||
SampleClock = InputClock / N
|
||||
|
||||
where:
|
||||
N is programmed divisor and 1<=N<=65535
|
||||
InputClock is 10MHz for internal clock or the external clock
|
||||
SampleClock if the effective sampling clock
|
||||
|
||||
We are given SampleClock, and need N, so
|
||||
|
||||
N = InputClock / SampleClock
|
||||
*/
|
||||
|
||||
/* internal clock type uses clock_freq from config as sample clock,
|
||||
external clock does not use clock divisor */
|
||||
|
||||
if(pvt->clock_mode==INTERNAL) /* internal clock */
|
||||
{
|
||||
clock_freq=INTERNAL_CLOCK;
|
||||
sample_freq=cards[pvt->card]->clock_freq;
|
||||
}
|
||||
else
|
||||
{
|
||||
clock_freq = cards[pvt->card]->clock_freq;
|
||||
sample_freq = clock_freq;
|
||||
}
|
||||
|
||||
if(clock_freq==sample_freq)
|
||||
{
|
||||
/* if clock divisor of one is to be used (10MHz) */
|
||||
pvt->adc_regs->ctc_control=0x80|0x10; /* CTC-2, LSB, mode 0 */
|
||||
}
|
||||
else
|
||||
{
|
||||
clock_div=clock_freq/sample_freq;
|
||||
/* printf("clock div=%8.8x\n",clock_div); */
|
||||
|
||||
if(clock_div>=1 && clock_div<=65535)
|
||||
{
|
||||
clock_div_short = clock_div;
|
||||
/* if clock divisor used, sample rate */
|
||||
pvt->adc_regs->ctc_control=0x80|0x30|0x04; /* CTC-2,LSB-MSB,mode */
|
||||
pvt->adc_regs->ctc2_clock_div=(clock_div_short&0x00ff);
|
||||
pvt->adc_regs->ctc2_clock_div=(clock_div_short>>8);
|
||||
}
|
||||
else
|
||||
{
|
||||
pvt->adc_regs->ctc_control=0x80|0x10; /* CTC-2, LSB, mode 0 */
|
||||
printf("Invalid clock/sample frequency: %ld/%ld\n",
|
||||
clock_freq,sample_freq);
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------------------------- */
|
||||
|
||||
/* start mode = off at this point */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt)
|
||||
{
|
||||
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
|
||||
|
||||
pr->pact=0;
|
||||
|
||||
if(cmd==CMD_ADDED)
|
||||
setup(pvt);
|
||||
else /* CMD_DELETED */
|
||||
buffer_reset(pvt); /* ensure that we are in a good state */
|
||||
|
||||
*iopvt=ioscanpvt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_read(struct waveformRecord* pr)
|
||||
{
|
||||
long rc;
|
||||
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
|
||||
|
||||
if(pr->scan==SCAN_IO_EVENT)
|
||||
{
|
||||
pvt->adc_regs->command|=0x20; /* start mode */
|
||||
rc=dev_complete_read(pr);
|
||||
setup(pvt);
|
||||
}
|
||||
else
|
||||
rc=dev_other_read(pr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long setup(PVT_AREA* pvt)
|
||||
{
|
||||
unsigned char trig;
|
||||
volatile unsigned char istat;
|
||||
|
||||
buffer_reset(pvt);
|
||||
trig=pvt->adc_regs->trigger&0xf8; /* clear run FF,trigger */
|
||||
trig|=0x44; /* external trigger on, auto arm mode */
|
||||
istat=pvt->adc_regs->int_status; /* read int status */
|
||||
pvt->adc_regs->int_mask=0x10; /* bank swap interrupt */
|
||||
pvt->adc_regs->trigger=trig|0x02; /* trigger mode + reset run FF */
|
||||
pvt->adc_regs->command|=0x20; /* start mode */
|
||||
pvt->adc_regs->trigger=trig; /* trigger mode */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_other_read(struct waveformRecord* pr)
|
||||
{
|
||||
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
|
||||
long rc=0;
|
||||
|
||||
if(pr->pact==TRUE)
|
||||
{
|
||||
/* i/o complete */
|
||||
|
||||
/* interrupt handler shut down everything already */
|
||||
pvt->adc_regs->command|=0x20; /* start mode on */
|
||||
rc=dev_complete_read(pr); /* process data in buffer */
|
||||
pvt->adc_regs->command&=~0x20; /* start mode off */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start the i/o */
|
||||
|
||||
/* this sucks, with internal mode trigger, the board glitch
|
||||
every so often, I cannot get it to work correctly, so do full reset */
|
||||
if(pvt->trigger_mode==INTERNAL) full_reset(pvt);
|
||||
|
||||
callbackSetPriority(pr->prio,&pvt->callback);
|
||||
setup(pvt);
|
||||
pr->pact=TRUE;
|
||||
|
||||
if(pvt->trigger_mode==INTERNAL)
|
||||
pvt->adc_regs->trigger|=0x01; /* set run FF */
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long dev_complete_read(struct waveformRecord* pr)
|
||||
{
|
||||
int i;
|
||||
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
|
||||
volatile unsigned short* source;
|
||||
volatile unsigned short samples;
|
||||
|
||||
source=&(pvt->adc_regs->vme_fifo);
|
||||
i=0;
|
||||
|
||||
switch(pr->ftvl)
|
||||
{
|
||||
case DBF_FLOAT:
|
||||
{
|
||||
float* f_thing = (float*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
f_thing[i]=(float)(((short)samples)>>4);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
case DBF_DOUBLE:
|
||||
{
|
||||
double* d_thing = (double*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
d_thing[i]=(double)(((short)samples)>>4);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
{
|
||||
unsigned long* ul_thing = (unsigned long*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
ul_thing[i]=(unsigned long)((samples>>4)&0x0fff);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
case DBF_LONG:
|
||||
{
|
||||
long* l_thing = (long*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
l_thing[i]=(long)(((long)samples)>>4);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
case DBF_USHORT:
|
||||
{
|
||||
unsigned short* s_thing = (unsigned short*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
s_thing[i]=(unsigned short)((samples>>4)&0x0fff);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("devPentek4261: Invalid data type\n");
|
||||
case DBF_SHORT:
|
||||
{
|
||||
short* ss_thing = (unsigned short*)pr->bptr;
|
||||
|
||||
for(i=0;i<pr->nelm;i++)
|
||||
{
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
ss_thing[i]=(short)(((short)(samples))>>4);
|
||||
}
|
||||
pr->nord=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear remaining samples if any */
|
||||
while(pvt->adc_regs->int_id_status&0x80)
|
||||
samples=pvt->adc_regs->vme_fifo;
|
||||
|
||||
/* pr->nelm, pr->bptr, &(pr->nord) */ /* three important fields */
|
||||
pr->udf=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IRQ under vxWorks */
|
||||
static void irq_func(void* v)
|
||||
{
|
||||
struct waveformRecord* pr = (struct waveformRecord*)v;
|
||||
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
|
||||
CALLBACK* cb = (CALLBACK*)pvt;
|
||||
unsigned char trig;
|
||||
|
||||
pvt->last_int_status=pvt->adc_regs->int_status; /* read status */
|
||||
|
||||
/* logMsg("in irq_func\n"); */
|
||||
/* if(pvt->last_int_status&0x02) logMsg("Overrun error\n"); */
|
||||
|
||||
pvt->adc_regs->command&=~0x20; /* start mode off - freeze all */
|
||||
pvt->adc_regs->int_mask=0x00; /* interrupts off */
|
||||
trig=pvt->adc_regs->trigger&0xfc; /* clear run FF bits */
|
||||
pvt->adc_regs->trigger=trig; /* clear run FF bits */
|
||||
pvt->adc_regs->trigger=trig|0x02; /* force reset run FF */
|
||||
|
||||
if(pr->scan==SCAN_IO_EVENT)
|
||||
scanIoRequest(ioscanpvt); /* scan EPICS record */
|
||||
else
|
||||
callbackRequest(cb);
|
||||
}
|
||||
|
||||
void ReportPentekADC() { dev_report(0); }
|
||||
|
||||
void ConfigurePentekADC( int card,
|
||||
unsigned long a16_base, unsigned long a32_base,
|
||||
int irq_vector, int irq_level,
|
||||
int word_clock, unsigned long clock_freq)
|
||||
{
|
||||
unsigned short dummy;
|
||||
|
||||
if(cards==0)
|
||||
{
|
||||
cards=(CARD**)malloc(sizeof(CARD*)*MAX_CARDS);
|
||||
memset((char*)cards,0,sizeof(CARD*)*MAX_CARDS);
|
||||
}
|
||||
|
||||
if(cards[card]!=0) printf("Overriding previous configuration\n");
|
||||
else cards[card]=(CARD*)malloc(sizeof(CARD));
|
||||
|
||||
cards[card]->in_use=0;
|
||||
if( sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,(char*)a16_base,(char**)&(cards[card]->a16_base))!=OK)
|
||||
{
|
||||
printf(" a16 base could not be converted\n");
|
||||
}
|
||||
if( sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char*)a32_base,(char**)&(cards[card]->a32_base))!=OK)
|
||||
{
|
||||
printf(" a32 base could not be converted\n");
|
||||
}
|
||||
cards[card]->irq_vector=irq_vector;
|
||||
cards[card]->irq_level=irq_level;
|
||||
cards[card]->word_clock=word_clock;
|
||||
cards[card]->clock_freq=clock_freq;
|
||||
|
||||
if(vxMemProbe((char*)cards[card]->a16_base,READ,
|
||||
sizeof(unsigned short),(char*)&dummy)!=OK)
|
||||
{
|
||||
/* card not really present */
|
||||
cards[card]->in_use=1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,33 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_INCLUDES = -I../../drv
|
||||
|
||||
SRCS.c = \
|
||||
../devAnalytekGpib.c ../devXxDg535Gpib.c ../devBBInteract.c \
|
||||
../devGpibInteract.c ../devXxSr620Gpib.c ../devK486Gpib.c \
|
||||
../devXxK196Gpib.c ../devXxDc5009Gpib.c ../devXxK263Gpib.c
|
||||
SRCS.c += ../devAnalytekGpib.c
|
||||
SRCS.c += ../devXxDg535Gpib.c
|
||||
SRCS.c += ../devBBInteract.c
|
||||
SRCS.c += ../devGpibInteract.c
|
||||
SRCS.c += ../devXxSr620Gpib.c
|
||||
SRCS.c += ../devK486Gpib.c
|
||||
SRCS.c += ../devXxK196Gpib.c
|
||||
SRCS.c += ../devXxDc5009Gpib.c
|
||||
SRCS.c += ../devXxK263Gpib.c
|
||||
SRCS.c += ../devXxSkeletonGpib.c
|
||||
|
||||
OBJS = \
|
||||
devAnalytekGpib.o devXxDg535Gpib.o devBBInteract.o \
|
||||
devGpibInteract.o devXxSr620Gpib.o devK486Gpib.o \
|
||||
devXxK196Gpib.o devXxDc5009Gpib.o devXxK263Gpib.o
|
||||
OBJS += devAnalytekGpib.o
|
||||
OBJS += devXxDg535Gpib.o
|
||||
OBJS += devBBInteract.o
|
||||
OBJS += devGpibInteract.o
|
||||
OBJS += devXxSr620Gpib.o
|
||||
OBJS += devK486Gpib.o
|
||||
OBJS += devXxK196Gpib.o
|
||||
OBJS += devXxDc5009Gpib.o
|
||||
OBJS += devXxK263Gpib.o
|
||||
OBJS += devXxSkeletonGpib.o
|
||||
|
||||
PROD = devLibOpt
|
||||
PROD = devLibOpt $(OBJS)
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
devLibOpt: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -139,8 +139,10 @@ int GI(void)
|
||||
for (cnt=0; cnt < LIST_SIZE; cnt++)
|
||||
{ /* init the elements of the command table */
|
||||
|
||||
#if 0
|
||||
gpibIntCmds[cnt].head.header.list.list1 = NULL;
|
||||
gpibIntCmds[cnt].head.header.list.list2 = NULL;
|
||||
#endif
|
||||
gpibIntCmds[cnt].head.workStart = gpibWork;
|
||||
gpibIntCmds[cnt].head.link = 0;
|
||||
gpibIntCmds[cnt].head.device = 0;
|
||||
@@ -155,7 +157,7 @@ int GI(void)
|
||||
}
|
||||
|
||||
ans = 0; /* set loop not to exit */
|
||||
printf("\n\n");
|
||||
logMsg("\n\n");
|
||||
|
||||
while ((ans != 'q') && (ans != 'Q'))
|
||||
{
|
||||
@@ -244,16 +246,20 @@ static int timingStudy(void)
|
||||
pCmd[i]->busy = 0; /* mark message 'not in queue' */
|
||||
pCmd[i]->count = 0;
|
||||
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE)
|
||||
{
|
||||
#endif
|
||||
(*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGENLINK, 0, NULL);
|
||||
(*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGETLINK, 0, &(pCmd[i]->head.pibLink));
|
||||
#ifdef USE_162_STUFF
|
||||
}
|
||||
else
|
||||
{
|
||||
drv162IB_InitLink(pCmd[i]->linkId);
|
||||
drv162IB_GetLink(pCmd[i]->linkId, &(pCmd[i]->head.pibLink));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -289,11 +295,14 @@ static int timingStudy(void)
|
||||
pCmd[i]->count++;
|
||||
pCmd[i]->busy = 1; /* mark the xact as busy */
|
||||
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE)
|
||||
#endif
|
||||
(*(drvGpib.qGpibReq))(pCmd[i], IB_Q_LOW);
|
||||
#ifdef USE_162_STUFF
|
||||
else
|
||||
drv162IB_QueueReq(pCmd[i], IB_Q_LOW);
|
||||
|
||||
#endif
|
||||
reps--;
|
||||
if (reps%10000 == 0)
|
||||
{
|
||||
@@ -359,11 +368,16 @@ static int sendMsg(void)
|
||||
replyIsBack = FALSE;
|
||||
ticks = 0;
|
||||
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
|
||||
{
|
||||
#endif
|
||||
|
||||
(*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGENLINK, 0, NULL);
|
||||
(*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGETLINK, 0, &(pCmd->head.pibLink));
|
||||
(*(drvGpib.qGpibReq))(pCmd, IB_Q_LOW); /* queue the msg */
|
||||
|
||||
#ifdef USE_162_STUFF
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -371,6 +385,7 @@ static int sendMsg(void)
|
||||
drv162IB_GetLink(pCmd->linkId, &(pCmd->head.pibLink));
|
||||
drv162IB_QueueReq(pCmd, IB_Q_LOW);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (!replyIsBack && (ticks < maxTicks)) /* wait for reply msg */
|
||||
{
|
||||
@@ -380,6 +395,8 @@ static int sendMsg(void)
|
||||
|
||||
if (replyIsBack)
|
||||
{
|
||||
if (ibDebug)
|
||||
taskDelay(60); /* Allow debug printing to complete */
|
||||
showGpibMsg(msgNum);
|
||||
}
|
||||
else
|
||||
@@ -399,10 +416,15 @@ static int gpibWork(struct gpibIntCmd *pCmd)
|
||||
switch (pCmd->type) {
|
||||
case 'w':
|
||||
case 'W': /* write the message to the GPIB listen adrs */
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
|
||||
#endif
|
||||
status =(*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
|
||||
|
||||
#ifdef USE_162_STUFF
|
||||
else
|
||||
status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
|
||||
#endif
|
||||
|
||||
if (status == ERROR)
|
||||
strcpy(pCmd->resp, "GPIB TIMEOUT (while talking)");
|
||||
@@ -411,10 +433,14 @@ static int gpibWork(struct gpibIntCmd *pCmd)
|
||||
break;
|
||||
case 'r':
|
||||
case 'R': /* write the command string */
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
|
||||
#endif
|
||||
status = (*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
|
||||
#ifdef USE_162_STUFF
|
||||
else
|
||||
status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
|
||||
#endif
|
||||
|
||||
if (status == ERROR)
|
||||
{
|
||||
@@ -426,10 +452,14 @@ static int gpibWork(struct gpibIntCmd *pCmd)
|
||||
case 'i':
|
||||
/* read the instrument */
|
||||
pCmd->resp[0] = 0; /* clear response string */
|
||||
#ifdef USE_162_STUFF
|
||||
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
|
||||
#endif
|
||||
status = (*(drvGpib.readIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime);
|
||||
#ifdef USE_162_STUFF
|
||||
else
|
||||
status = drv162IB_read(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime);
|
||||
#endif
|
||||
|
||||
if (status == ERROR)
|
||||
{
|
||||
@@ -438,7 +468,7 @@ static int gpibWork(struct gpibIntCmd *pCmd)
|
||||
}
|
||||
else if (status > (MAX_MSG_LENGTH - 1)) /* check length of resp */
|
||||
{
|
||||
printf("GPIB Response length equaled allocated space !!!\n");
|
||||
logMsg("GPIB Response length equaled allocated space !!!\n");
|
||||
pCmd->resp[(MAX_MSG_LENGTH)] = '\0'; /* place \0 at end */
|
||||
}
|
||||
else
|
||||
|
||||
@@ -391,8 +391,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
|
||||
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
|
||||
phwpvt->link, phwpvt->device, srqStatus);
|
||||
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -404,9 +404,9 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
|
||||
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
|
||||
phwpvt->link, phwpvt->device, srqStatus);
|
||||
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
callbackRequest(phwpvt->unsolicitedDpvt);
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -282,8 +282,8 @@ STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
|
||||
logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
|
||||
phwpvt->link, phwpvt->device, srqStatus);
|
||||
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.header.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.header.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
|
||||
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
|
||||
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Lowest Level Directroy Makefile
|
||||
# by Janet Anderson
|
||||
#
|
||||
# $Log$
|
||||
#
|
||||
|
||||
EPICS=../../..
|
||||
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
include $(EPICS)/config/RULES_ARCHS
|
||||
DIRS = ansi old combine
|
||||
|
||||
include $(EPICS)/config/RULES_DIRS
|
||||
|
||||
|
||||
@@ -4,73 +4,74 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield -traditional
|
||||
|
||||
SRCS.c = \
|
||||
../module_types.c\
|
||||
../drvXy010.c\
|
||||
../drvAb.c\
|
||||
../drvBb902.c\
|
||||
../drvBb910.c\
|
||||
../drvCompuSm.c\
|
||||
../drvDvx.c\
|
||||
../drvMz8310.c\
|
||||
../drvOms.c\
|
||||
../drvStc.c\
|
||||
../drvTime.c\
|
||||
../drvVmi4100.c\
|
||||
../drvXy210.c\
|
||||
../drvXy220.c\
|
||||
../drvXy240.c\
|
||||
../drvXy566.c\
|
||||
../drvAt5Vxi.c\
|
||||
../drvHp1404a.c\
|
||||
../drvEpvxi.c\
|
||||
../drvEpvxiMsg.c\
|
||||
../drvBitBus.c\
|
||||
../drvGpib.c\
|
||||
../drvMsg.c\
|
||||
../drvBB232.c\
|
||||
../drvHpe1368a.c\
|
||||
../drvHpe1445a.c\
|
||||
../drvKscV215.c\
|
||||
../drvComet.c\
|
||||
../drvJgvtr1.c\
|
||||
../drvFp.c\
|
||||
../drvMvme162.c\
|
||||
../drvFpm.c
|
||||
SRCS.c += ../module_types.c
|
||||
SRCS.c += ../drvAb.c
|
||||
SRCS.c += ../drvAt5Vxi.c
|
||||
SRCS.c += ../drvBB232.c
|
||||
SRCS.c += ../drvBb902.c
|
||||
SRCS.c += ../drvBb910.c
|
||||
SRCS.c += ../drvBitBus.c
|
||||
# SRCS.c += ../drvCaenV265.c
|
||||
SRCS.c += ../drvComet.c
|
||||
SRCS.c += ../drvCompuSm.c
|
||||
SRCS.c += ../drvDvx.c
|
||||
SRCS.c += ../drvEpvxi.c
|
||||
SRCS.c += ../drvEpvxiMsg.c
|
||||
SRCS.c += ../drvFp.c
|
||||
SRCS.c += ../drvFpm.c
|
||||
SRCS.c += ../drvGpib.c
|
||||
SRCS.c += ../drvHp1404a.c
|
||||
SRCS.c += ../drvHpe1368a.c
|
||||
SRCS.c += ../drvHpe1445a.c
|
||||
SRCS.c += ../drvJgvtr1.c
|
||||
SRCS.c += ../drvKscV215.c
|
||||
SRCS.c += ../drvMsg.c
|
||||
SRCS.c += ../drvMz8310.c
|
||||
SRCS.c += ../drvOms.c
|
||||
SRCS.c += ../drvStc.c
|
||||
SRCS.c += ../drvTime.c
|
||||
# SRCS.c += ../drvTranServ.c
|
||||
SRCS.c += ../drvVmi4100.c
|
||||
SRCS.c += ../drvXy010.c
|
||||
SRCS.c += ../drvXy210.c
|
||||
SRCS.c += ../drvXy220.c
|
||||
SRCS.c += ../drvXy240.c
|
||||
SRCS.c += ../drvXy566.c
|
||||
|
||||
OBJS += module_types.o
|
||||
OBJS += drvAb.o
|
||||
OBJS += drvAt5Vxi.o
|
||||
OBJS += drvBB232.o
|
||||
OBJS += drvBb902.o
|
||||
OBJS += drvBb910.o
|
||||
OBJS += drvBitBus.o
|
||||
# OBJS += drvCaenV265.o
|
||||
OBJS += drvComet.o
|
||||
OBJS += drvCompuSm.o
|
||||
OBJS += drvDvx.o
|
||||
OBJS += drvEpvxi.o
|
||||
OBJS += drvEpvxiMsg.o
|
||||
OBJS += drvFp.o
|
||||
OBJS += drvFpm.o
|
||||
OBJS += drvGpib.o
|
||||
OBJS += drvHp1404a.o
|
||||
OBJS += drvHpe1368a.o
|
||||
OBJS += drvHpe1445a.o
|
||||
OBJS += drvJgvtr1.o
|
||||
OBJS += drvKscV215.o
|
||||
OBJS += drvMsg.o
|
||||
OBJS += drvMz8310.o
|
||||
OBJS += drvOms.o
|
||||
OBJS += drvStc.o
|
||||
OBJS += drvTime.o
|
||||
# OBJS += drvTranServ.o
|
||||
OBJS += drvVmi4100.o
|
||||
OBJS += drvXy010.o
|
||||
OBJS += drvXy210.o
|
||||
OBJS += drvXy220.o
|
||||
OBJS += drvXy240.o
|
||||
OBJS += drvXy566.o
|
||||
|
||||
OBJS = \
|
||||
module_types.o\
|
||||
drvXy010.o\
|
||||
drvAb.o\
|
||||
drvBb902.o\
|
||||
drvBb910.o\
|
||||
drvCompuSm.o\
|
||||
drvDvx.o\
|
||||
drvMz8310.o\
|
||||
drvOms.o\
|
||||
drvStc.o\
|
||||
drvTime.o\
|
||||
drvVmi4100.o\
|
||||
drvXy210.o\
|
||||
drvXy220.o\
|
||||
drvXy240.o\
|
||||
drvXy566.o\
|
||||
drvAt5Vxi.o\
|
||||
drvHp1404a.o\
|
||||
drvEpvxi.o\
|
||||
drvEpvxiMsg.o\
|
||||
drvBitBus.o\
|
||||
drvGpib.o\
|
||||
drvMsg.o\
|
||||
drvBB232.o\
|
||||
drvHpe1368a.o\
|
||||
drvHpe1445a.o\
|
||||
drvKscV215.o\
|
||||
drvComet.o\
|
||||
drvJgvtr1.o\
|
||||
drvFp.o\
|
||||
drvMvme162.o\
|
||||
drvFpm.o
|
||||
|
||||
PROD = drvSup
|
||||
|
||||
@@ -81,5 +82,4 @@ $(PROD): $(OBJS)
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
# ../drvCaenV265.c\
|
||||
# drvCaenV265.o\
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
The CPU030 may need to have the nivxi path set correctly:
|
||||
From the vxWorks shell type vxitedit
|
||||
From the vxWorks shell type "vxitedit"
|
||||
take option 2
|
||||
take option 3
|
||||
type list
|
||||
@@ -8,6 +9,7 @@ The CPU030 may need to have the nivxi path set correctly:
|
||||
(the path should end in nivxi
|
||||
and should traverse the niCpu030
|
||||
directories shipped with the 030
|
||||
ie somethin of the form "???/config/niCPU030/nivxi"
|
||||
type save
|
||||
type exit
|
||||
.
|
||||
|
||||
12
src/drv/ansi/Makefile
Normal file
12
src/drv/ansi/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
EPICS=../../../..
|
||||
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
include $(EPICS)/config/RULES_ARCHS
|
||||
|
||||
40
src/drv/ansi/Makefile.Vx
Normal file
40
src/drv/ansi/Makefile.Vx
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
EPICS = ../../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -ansi
|
||||
|
||||
VX_WARN_YES = -Wall -pedantic
|
||||
|
||||
SRCS.c += ../drvAb.c
|
||||
SRCS.c += ../drvAt5Vxi.c
|
||||
SRCS.c += ../drvEpvxi.c
|
||||
SRCS.c += ../drvEpvxiMsg.c
|
||||
SRCS.c += ../drvHp1404a.c
|
||||
SRCS.c += ../drvHpe1368a.c
|
||||
SRCS.c += ../drvHpe1445a.c
|
||||
SRCS.c += ../drvKscV215.c
|
||||
SRCS.c += ../drvMz8310.c
|
||||
SRCS.c += ../drvStc.c
|
||||
SRCS.c += ../drvTime.c
|
||||
# SRCS.c += ../drvCaenV265.c
|
||||
|
||||
TARGETS += drvAb.o
|
||||
TARGETS += drvAt5Vxi.o
|
||||
TARGETS += drvEpvxi.o
|
||||
TARGETS += drvEpvxiMsg.o
|
||||
TARGETS += drvHp1404a.o
|
||||
TARGETS += drvHpe1368a.o
|
||||
TARGETS += drvHpe1445a.o
|
||||
TARGETS += drvKscV215.o
|
||||
TARGETS += drvMz8310.o
|
||||
TARGETS += drvStc.o
|
||||
TARGETS += drvTime.o
|
||||
# TARGETS += drvCaenV265.o
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
30
src/drv/ansi/VXI_SETUP_README
Normal file
30
src/drv/ansi/VXI_SETUP_README
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
The CPU030 may need to have the nivxi path set correctly:
|
||||
From the vxWorks shell type "vxitedit"
|
||||
take option 2
|
||||
take option 3
|
||||
type list
|
||||
type modify 0
|
||||
type in the correct path when promped
|
||||
(the path should end in nivxi
|
||||
and should traverse the niCpu030
|
||||
directories shipped with the 030
|
||||
ie somethin of the form "???/config/niCPU030/nivxi"
|
||||
type save
|
||||
type exit
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
|
||||
You may may need to setup front panel to backplane trigger
|
||||
routing:
|
||||
|
||||
To take a TTL input and map it to VXI backplane ECL trigger 0
|
||||
type in (to the vxWorks shell):
|
||||
|
||||
epvxiRouteTriggerECL(<logical address>, 1, 0)
|
||||
|
||||
where <logical address> specifies the card with the
|
||||
front panel trigger connection.
|
||||
|
||||
1751
src/drv/ansi/drvAb.c
Normal file
1751
src/drv/ansi/drvAb.c
Normal file
File diff suppressed because it is too large
Load Diff
91
src/drv/ansi/drvAb.h
Normal file
91
src/drv/ansi/drvAb.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* drvAb.h */
|
||||
/* header file for the Allen-Bradley Remote Serial IO
|
||||
* This defines interface between driver and device support
|
||||
*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 03-06-95
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* 01 03-06-95 mrk Moved all driver specific code to drvAb.c
|
||||
*/
|
||||
|
||||
#ifndef INCdrvAbh
|
||||
#define INCdrvAbh 1
|
||||
#include "dbScan.h"
|
||||
|
||||
|
||||
/* interface types */
|
||||
typedef enum {typeNotAssigned,typeBi,typeBo,typeBiBo,typeAi,typeAo,typeBt}
|
||||
cardType;
|
||||
/* status values*/
|
||||
typedef enum{abSuccess,abNewCard,abCardConflict,abNoCard,abNotInitialized,
|
||||
abBtqueued,abBusy,abTimeout,abAdapterDown,abFailure} abStatus;
|
||||
extern char **abStatusMessage;
|
||||
|
||||
typedef enum{abBitNotdefined,abBit8,abBit16,abBit32} abNumBits;
|
||||
extern char **abNumBitsMessage;
|
||||
|
||||
/*entry table for dev to drv routines*/
|
||||
typedef struct {
|
||||
abStatus (*registerCard)
|
||||
(unsigned short link,unsigned short adapter, unsigned short card,
|
||||
cardType type, const char *card_name,
|
||||
void (*callback)(void *drvPvt),
|
||||
void **drvPvt);
|
||||
void (*getLocation)
|
||||
(void *drvPvt,
|
||||
unsigned short *link, unsigned short *adapter,unsigned short *card);
|
||||
abStatus (*setNbits)(void *drvPvt, abNumBits nbits);
|
||||
void (*setUserPvt)(void *drvPvt, void *userPvt);
|
||||
void *(*getUserPvt)(void *drvPvt);
|
||||
abStatus (*getStatus)(void *drvPvt);
|
||||
abStatus(*startScan)
|
||||
(void *drvPvt, unsigned short update_rate,
|
||||
unsigned short *pwrite_msg, unsigned short write_msg_len,
|
||||
unsigned short *pread_msg, unsigned short read_msg_len);
|
||||
abStatus(*updateAo)(void *drvPvt);
|
||||
abStatus(*updateBo) (void *drvPvt,unsigned long value,unsigned long mask);
|
||||
abStatus(*readBo) (void *drvPvt,unsigned long *value,unsigned long mask);
|
||||
abStatus(*readBi) (void *drvPvt,unsigned long *value,unsigned long mask);
|
||||
abStatus(*btRead)(void *drvPvt,unsigned short *pread_msg,
|
||||
unsigned short read_msg_len);
|
||||
abStatus(*btWrite)(void *drvPvt,unsigned short *pwrite_msg,
|
||||
unsigned short write_msg_len);
|
||||
abStatus (*adapterStatus)
|
||||
(unsigned short link,unsigned short adapter);
|
||||
abStatus (*cardStatus)
|
||||
(unsigned short link,unsigned short adapter, unsigned short card);
|
||||
}abDrv;
|
||||
|
||||
extern abDrv *pabDrv;
|
||||
|
||||
int ab_reset(void);
|
||||
int ab_reset_link(int link);
|
||||
int abConfigNlinks(int nlinks);
|
||||
int abConfigVme(int link, int base, int vector, int level);
|
||||
int abConfigBaud(int link, int baud);
|
||||
int abConfigScanList(int link, int scan_list_len, char *scan_list);
|
||||
|
||||
#endif /*INCdrvAbh*/
|
||||
1410
src/drv/ansi/drvAt5Vxi.c
Normal file
1410
src/drv/ansi/drvAt5Vxi.c
Normal file
File diff suppressed because it is too large
Load Diff
94
src/drv/ansi/drvAt5Vxi.h
Normal file
94
src/drv/ansi/drvAt5Vxi.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
*
|
||||
* driver for at5 designed VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 11-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <dbScan.h>
|
||||
|
||||
typedef long at5VxiStatus;
|
||||
|
||||
at5VxiStatus at5vxi_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param/* parameter to pass to above routine */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ai_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval,
|
||||
unsigned short *prbval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_read(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *pval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bi_driver(
|
||||
unsigned card,
|
||||
unsigned long mask,
|
||||
unsigned long *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bo_driver(
|
||||
unsigned card,
|
||||
unsigned long val,
|
||||
unsigned long mask
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_getioscanpvt(
|
||||
unsigned card,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
808
src/drv/ansi/drvCaenV265.c
Normal file
808
src/drv/ansi/drvCaenV265.c
Normal file
@@ -0,0 +1,808 @@
|
||||
/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */
|
||||
/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265
|
||||
*
|
||||
* Author: Jeff Hill (johill@lanl.gov)
|
||||
* Date: 8-11-94
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* MIT Bates Lab
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI C Includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* vxWorks includes
|
||||
*/
|
||||
#include <vme.h>
|
||||
#include <iv.h>
|
||||
#include <sysLib.h>
|
||||
#include <intLib.h>
|
||||
#include <logLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <rebootLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <wdLib.h>
|
||||
|
||||
/*
|
||||
* EPICS include
|
||||
*/
|
||||
#include <dbDefs.h>
|
||||
#include <dbScan.h>
|
||||
#include <drvSup.h>
|
||||
#include <devSup.h>
|
||||
#include <recSup.h>
|
||||
#include <devLib.h>
|
||||
#include <aiRecord.h>
|
||||
#include <errMdef.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
|
||||
/*
|
||||
* base address, base interrupt vector,
|
||||
* number of cards, & interrupt level
|
||||
*/
|
||||
#define CAIN_V265_A24_BASE (0x000000)
|
||||
#define CAIN_V265_INTVEC_BASE (0xA0)
|
||||
#define CAIN_V265_MAX_CARD_COUNT (8)
|
||||
#define CAIN_V265_INT_LEVEL (6)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* all device registers declared
|
||||
* ANSI C volatile so we dont need to
|
||||
* use the -fvolatile flag (and dont
|
||||
* limit the optimizer)
|
||||
*/
|
||||
typedef volatile int16_t devReg;
|
||||
|
||||
struct caenV265 {
|
||||
devReg csr;
|
||||
devReg clear;
|
||||
devReg DAC;
|
||||
devReg gate;
|
||||
const devReg data;
|
||||
const devReg pad1[(0xf8-0x8)/2];
|
||||
const devReg fixed;
|
||||
const devReg identifier;
|
||||
const devReg version;
|
||||
};
|
||||
#define CAENV265ID 0x0812
|
||||
|
||||
/*
|
||||
* Insert or extract a bit field using the standard
|
||||
* masks and shifts defined below
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
#define INSERT(FIELD,VALUE)\
|
||||
(((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S))
|
||||
#define EXTRACT(FIELD,VALUE)\
|
||||
( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M))
|
||||
#else /*__STDC__*/
|
||||
#define INSERT(FIELD,VALUE)\
|
||||
(((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S))
|
||||
#define EXTRACT(FIELD,VALUE)\
|
||||
( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M))
|
||||
#endif /*__STDC__*/
|
||||
|
||||
/*
|
||||
* in the constants below _M is a right justified mask
|
||||
* and _S is a shift required to right justify the field
|
||||
*/
|
||||
|
||||
/*
|
||||
* csr register
|
||||
*/
|
||||
#define FD_FULL_M (0x1)
|
||||
#define FD_FULL_S (14)
|
||||
#define FD_READY_M (0x1)
|
||||
#define FD_READY_S (15)
|
||||
#define FD_BUSY_FULL_M (0x3)
|
||||
#define FD_BUSY_FULL_S (14)
|
||||
#define FD_IVEC_M (0xff)
|
||||
#define FD_IVEC_S (0)
|
||||
#define FD_ILEVEL_M (0x7)
|
||||
#define FD_ILEVEL_S (8)
|
||||
|
||||
/*
|
||||
* series/version register
|
||||
*/
|
||||
#define FD_SERIES_M (0xfff)
|
||||
#define FD_SERIES_S (0)
|
||||
#define FD_VERSION_M (0xf)
|
||||
#define FD_VERSION_S (12)
|
||||
|
||||
/*
|
||||
* data register
|
||||
*/
|
||||
#define FD_CHANNEL_M (0x7)
|
||||
#define FD_CHANNEL_S (13)
|
||||
#define FD_RANGE_M (1)
|
||||
#define FD_RANGE_S (12)
|
||||
#define FD_DATA_M (0xfff)
|
||||
#define FD_DATA_S (0)
|
||||
|
||||
struct channel{
|
||||
int16_t signal;
|
||||
char newData;
|
||||
};
|
||||
|
||||
enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES};
|
||||
#define NUMBER_OF_SIGNALS 8
|
||||
#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES)
|
||||
LOCAL struct caenV265Config{
|
||||
struct caenV265 *pCaenV265; /* pointer to the card */
|
||||
struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES];
|
||||
IOSCANPVT scanpvt;
|
||||
WDOG_ID wdid;
|
||||
}caenV265Info[CAIN_V265_MAX_CARD_COUNT];
|
||||
|
||||
#ifdef __STDC__
|
||||
#define SHOW_OFFSET(STRUCT,FIELD) \
|
||||
printf( "%s.%s is at 0x%X\n", \
|
||||
#STRUCT, \
|
||||
#FIELD, \
|
||||
offsetof(struct STRUCT, FIELD))
|
||||
#endif
|
||||
|
||||
LOCAL void caenV265ISR(unsigned card);
|
||||
LOCAL int caenV265Shutdown(void);
|
||||
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265);
|
||||
int caenV265Test(unsigned card);
|
||||
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config);
|
||||
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal);
|
||||
LOCAL int caenV265IntEnable(unsigned card);
|
||||
|
||||
/*
|
||||
* device support entry table
|
||||
*/
|
||||
LOCAL long caenV265InitRecord(struct aiRecord *pai);
|
||||
LOCAL long caenV265AiRead(struct aiRecord *pai);
|
||||
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after);
|
||||
LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devCaenV265 ={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
caenV265InitRecord,
|
||||
caenV265GetIoIntInfo,
|
||||
caenV265AiRead,
|
||||
caenV265SpecialLinconv};
|
||||
|
||||
/*
|
||||
* driver support entry table
|
||||
*/
|
||||
LOCAL long caenV265Init(void);
|
||||
LOCAL long caenV265IOReport(int level);
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvCaenV265 ={
|
||||
2,
|
||||
caenV265IOReport,
|
||||
caenV265Init};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* verify that register
|
||||
* offsets match the doc.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
void offsettest()
|
||||
{
|
||||
SHOW_OFFSET(caenV265, version);
|
||||
SHOW_OFFSET(caenV265, identifier);
|
||||
SHOW_OFFSET(caenV265, fixed);
|
||||
SHOW_OFFSET(caenV265, data);
|
||||
SHOW_OFFSET(caenV265, gate);
|
||||
SHOW_OFFSET(caenV265, DAC);
|
||||
SHOW_OFFSET(caenV265, clear);
|
||||
SHOW_OFFSET(caenV265, csr);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* caenV265InitRecord()
|
||||
*/
|
||||
LOCAL long caenV265InitRecord(struct aiRecord *pai)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
/* ai.inp must be an VME_IO */
|
||||
switch (pai->inp.type) {
|
||||
case (VME_IO):
|
||||
break;
|
||||
default :
|
||||
recGblRecordError(S_db_badField,(void *)pai,
|
||||
"devAiXy566Se (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad signal or card number
|
||||
*/
|
||||
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
|
||||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 bad card or signal number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!caenV265Info[pvmeio->card].pCaenV265){
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 card does not exist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set linear conversion slope*/
|
||||
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265AiRead()
|
||||
*/
|
||||
LOCAL long caenV265AiRead(struct aiRecord *pai)
|
||||
{
|
||||
int16_t value;
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad signal or card number
|
||||
*/
|
||||
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
|
||||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
|
||||
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* uninitialized data?
|
||||
*/
|
||||
if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) {
|
||||
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal;
|
||||
pai->rval = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265SpecialLinconv()
|
||||
*/
|
||||
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after)
|
||||
{
|
||||
if(!after) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set linear conversion slope*/
|
||||
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265GetIoIntInfo()
|
||||
*/
|
||||
LOCAL long caenV265GetIoIntInfo(
|
||||
int cmd,
|
||||
struct aiRecord *pai,
|
||||
IOSCANPVT *ppvt)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad card number
|
||||
*/
|
||||
if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
epicsPrintf (
|
||||
"%s.%d:devCaenV265 bad card number %d %s\n",
|
||||
(int)__FILE__,
|
||||
__LINE__,
|
||||
pvmeio->card,
|
||||
(int)pai->name);
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 bad card number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppvt = &caenV265Info[pvmeio->card].scanpvt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Init()
|
||||
*/
|
||||
LOCAL long caenV265Init(void)
|
||||
{
|
||||
unsigned card;
|
||||
struct caenV265 *pCaenV265;
|
||||
int status;
|
||||
|
||||
status = rebootHookAdd(caenV265Shutdown);
|
||||
if(status){
|
||||
errMessage(S_dev_internal,"reboot hook add failed");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
status = sysBusToLocalAdrs(
|
||||
VME_AM_STD_SUP_DATA,
|
||||
CAIN_V265_A24_BASE,
|
||||
(char **)&pCaenV265);
|
||||
if(status!=OK){
|
||||
errPrintf(
|
||||
S_dev_badA24,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"caenV265Init");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++, pCaenV265++){
|
||||
unsigned vec;
|
||||
|
||||
if(!caenV265IdTest(pCaenV265)){
|
||||
continue;
|
||||
}
|
||||
|
||||
caenV265Info[card].wdid = wdCreate();
|
||||
if(!caenV265Info[card].wdid){
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* flag that we have found a caen V265
|
||||
*/
|
||||
caenV265Info[card].pCaenV265 = pCaenV265;
|
||||
|
||||
/*
|
||||
* init the EPICS db int event scan block
|
||||
*/
|
||||
scanIoInit(&caenV265Info[card].scanpvt);
|
||||
|
||||
/*
|
||||
* reset the device
|
||||
*/
|
||||
pCaenV265->clear = 0; /* any rw op resets the device */
|
||||
pCaenV265->DAC = 0; /* set test-signal "offset" to zero */
|
||||
|
||||
/*
|
||||
* attach ISR
|
||||
*/
|
||||
vec = CAIN_V265_INTVEC_BASE+card;
|
||||
status = intConnect(
|
||||
INUM_TO_IVEC(vec),
|
||||
caenV265ISR,
|
||||
card);
|
||||
assert(status>=0);
|
||||
|
||||
/*
|
||||
* Enable interrupts
|
||||
*/
|
||||
caenV265IntEnable(card);
|
||||
}
|
||||
status = sysIntEnable(CAIN_V265_INT_LEVEL);
|
||||
assert(status>=0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265ISR()
|
||||
*/
|
||||
LOCAL void caenV265ISR(unsigned card)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned signal;
|
||||
int16_t csr;
|
||||
static unsigned ticks;
|
||||
unsigned newTicks;
|
||||
|
||||
/*
|
||||
* If its full then its more efficient
|
||||
* to read it out without checking
|
||||
* in between each read
|
||||
*/
|
||||
csr = pCaenV265->csr;
|
||||
if (EXTRACT(FULL,csr)) {
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_FIFO_ENTRIES;
|
||||
signal++){
|
||||
|
||||
caenV265ReadData(pCaenV256Config);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not full so check to see if its ready before
|
||||
* reading
|
||||
*/
|
||||
while (EXTRACT(READY, csr)) {
|
||||
caenV265ReadData(pCaenV256Config);
|
||||
csr = pCaenV265->csr;
|
||||
}
|
||||
|
||||
/*
|
||||
* limit the EPICS scan rate
|
||||
*/
|
||||
newTicks = tickGet();
|
||||
if(newTicks == ticks){
|
||||
/*
|
||||
* Disable Interrupts
|
||||
*/
|
||||
pCaenV265->csr = 0;
|
||||
|
||||
/*
|
||||
* start a watch dog after one tick
|
||||
* so that we limit the int rate to
|
||||
* the system tick rate.
|
||||
*/
|
||||
wdStart(pCaenV256Config->wdid,
|
||||
1,
|
||||
caenV265IntEnable,
|
||||
card);
|
||||
|
||||
return;
|
||||
}
|
||||
else{
|
||||
ticks = newTicks;
|
||||
}
|
||||
|
||||
/*
|
||||
* tell EPICS to scan on int
|
||||
*/
|
||||
scanIoRequest(&caenV265Info[card].scanpvt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IntEnable
|
||||
*/
|
||||
LOCAL int caenV265IntEnable(unsigned card)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned vec;
|
||||
int16_t newcsr;
|
||||
|
||||
|
||||
vec = CAIN_V265_INTVEC_BASE+card;
|
||||
newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL);
|
||||
pCaenV265->csr = newcsr;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265ReadData()
|
||||
*/
|
||||
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config)
|
||||
{
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
int16_t val = pCaenV265->data;
|
||||
int16_t data = EXTRACT(DATA, val);
|
||||
unsigned range = EXTRACT(RANGE, val);
|
||||
unsigned signal = EXTRACT(CHANNEL, val);
|
||||
|
||||
if(range>=NUMBER_OF_ADC_RANGES){
|
||||
epicsPrintf ("caenV265ReadData: bad range number\n");
|
||||
return;
|
||||
}
|
||||
if(signal>=NUMBER_OF_SIGNALS){
|
||||
epicsPrintf ("caenV265ReadData: bad signal number\n");
|
||||
return;
|
||||
}
|
||||
pCaenV256Config->chan[signal][range].signal=data;
|
||||
pCaenV256Config->chan[signal][range].newData=TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IdTest()
|
||||
*/
|
||||
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265)
|
||||
{
|
||||
int status;
|
||||
int16_t id;
|
||||
|
||||
/*
|
||||
* Is a card present
|
||||
*/
|
||||
status = vxMemProbe(
|
||||
(char *)&pCaenV265->identifier,
|
||||
READ,
|
||||
sizeof(id),
|
||||
(char *)&id);
|
||||
if(status!=OK){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the correct type of card present
|
||||
*/
|
||||
if(id!=CAENV265ID){
|
||||
errPrintf(
|
||||
S_dev_wrongDevice,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"caenV265IdTest");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Shutdown()
|
||||
* turns off interrupts so that dont foul up the boot
|
||||
*/
|
||||
LOCAL int caenV265Shutdown(void)
|
||||
{
|
||||
struct caenV265 *pCaenV265;
|
||||
unsigned card;
|
||||
|
||||
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++){
|
||||
pCaenV265 = caenV265Info[card].pCaenV265;
|
||||
if(!pCaenV265){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(caenV265IdTest(pCaenV265)){
|
||||
/*
|
||||
* disable interrupts
|
||||
*/
|
||||
pCaenV265->csr=0;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Test()
|
||||
*/
|
||||
int caenV265Test(unsigned card)
|
||||
{
|
||||
unsigned dacVal;
|
||||
struct caenV265Config cofigCpy;
|
||||
unsigned range;
|
||||
unsigned signal;
|
||||
|
||||
|
||||
dacVal=0;
|
||||
caenV265TestVal(card, dacVal);
|
||||
while(dacVal<FD_DATA_M){
|
||||
|
||||
cofigCpy = caenV265Info[card];
|
||||
dacVal = dacVal+32;
|
||||
caenV265TestVal(card, dacVal);
|
||||
|
||||
for( range=0;
|
||||
range<NUMBER_OF_ADC_RANGES;
|
||||
range++){
|
||||
char *pRangeName[] = { "12 bit signal",
|
||||
"15 bit signal"};
|
||||
|
||||
printf( "\t%s with DAC = 0x%X\n",
|
||||
pRangeName[range],
|
||||
dacVal);
|
||||
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
unsigned newdata;
|
||||
unsigned olddata;
|
||||
|
||||
olddata = cofigCpy.chan[signal][range].signal;
|
||||
newdata = caenV265Info[card].
|
||||
chan[signal][range].signal;
|
||||
|
||||
printf( "\t\tchan=0x%1X diff = 0x%03X\n",
|
||||
signal,
|
||||
newdata-olddata);
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265TestVal()
|
||||
*/
|
||||
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned signal;
|
||||
|
||||
if(!pCaenV265){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(!caenV265IdTest(pCaenV265)){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the module
|
||||
*/
|
||||
pCaenV265->clear=0;
|
||||
|
||||
/*
|
||||
* generate a test signal
|
||||
*/
|
||||
pCaenV265->DAC=dacVal;
|
||||
|
||||
/*
|
||||
* generate a test gate
|
||||
*/
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
caenV265Info[card].chan[signal][adc_12].newData=FALSE;
|
||||
caenV265Info[card].chan[signal][adc_15].newData=FALSE;
|
||||
while(!caenV265Info[card].chan[signal][adc_15].newData){
|
||||
pCaenV265->gate=0;
|
||||
taskDelay(1);
|
||||
}
|
||||
while(!caenV265Info[card].chan[signal][adc_12].newData){
|
||||
pCaenV265->gate=0;
|
||||
taskDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* turn off test signal
|
||||
*/
|
||||
pCaenV265->clear=0;
|
||||
pCaenV265->DAC=0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IOReport()
|
||||
*/
|
||||
LOCAL long caenV265IOReport(int level)
|
||||
{
|
||||
struct caenV265 *pCaenV265;
|
||||
unsigned card;
|
||||
unsigned signal;
|
||||
unsigned range;
|
||||
char *pVersion[] = {"NIM","ECL"};
|
||||
char *pState[] = {
|
||||
"FIFO empty",
|
||||
"FIFO full",
|
||||
"FIFO partially filled",
|
||||
"FIFO full"};
|
||||
|
||||
for (card=0; card<CAIN_V265_MAX_CARD_COUNT; card++) {
|
||||
pCaenV265 = caenV265Info[card].pCaenV265;
|
||||
if (!pCaenV265) {
|
||||
continue;
|
||||
}
|
||||
if (!caenV265IdTest(pCaenV265)) {
|
||||
continue;
|
||||
}
|
||||
printf("AI: caen V265:\tcard %d\n", card);
|
||||
if (level == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tversion = %s\n",
|
||||
pVersion[EXTRACT(VERSION, pCaenV265->version)]);
|
||||
printf("\tseries = %d\n",
|
||||
EXTRACT(SERIES, pCaenV265->version));
|
||||
printf("\tstate = %s\n",
|
||||
pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]);
|
||||
printf("\tint level = %d\n",
|
||||
EXTRACT(ILEVEL,pCaenV265->csr));
|
||||
printf("\tint vec = 0x%02X\n",
|
||||
EXTRACT(IVEC,pCaenV265->csr));
|
||||
printf( "\tbase addr= 0x%X on the %s\n",
|
||||
(unsigned)caenV265Info[card].pCaenV265,
|
||||
sysModel());
|
||||
|
||||
for( range=0;
|
||||
range<NUMBER_OF_ADC_RANGES;
|
||||
range++){
|
||||
char *pRangeName[] = { "12 bit signal",
|
||||
"15 bit signal"};
|
||||
|
||||
printf("\t%s\n", pRangeName[range]);
|
||||
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
int16_t data;
|
||||
|
||||
data = caenV265Info[card].
|
||||
chan[signal][range].signal;
|
||||
|
||||
if(caenV265Info[card].chan[signal][range].newData){
|
||||
printf( "\t\tchan=0x%1X val = 0x%03X\n",
|
||||
signal,
|
||||
data);
|
||||
}
|
||||
else{
|
||||
printf( "\t\tchan=0x%1X <NO GATE>\n",
|
||||
signal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
4620
src/drv/ansi/drvEpvxi.c
Normal file
4620
src/drv/ansi/drvEpvxi.c
Normal file
File diff suppressed because it is too large
Load Diff
1537
src/drv/ansi/drvEpvxiMsg.c
Normal file
1537
src/drv/ansi/drvEpvxiMsg.c
Normal file
File diff suppressed because it is too large
Load Diff
408
src/drv/ansi/drvHp1404a.c
Normal file
408
src/drv/ansi/drvHp1404a.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
*
|
||||
* HP E1404A VXI bus slot zero translator
|
||||
* device dependent routines
|
||||
*
|
||||
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* Date 030692
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 joh 073092 Added msg device support & interrupt shutdown for
|
||||
* soft reboots
|
||||
* .02 joh 082792 converted to ANSI C
|
||||
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <intLib.h>
|
||||
#include <rebootLib.h>
|
||||
|
||||
#include <devLib.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <drvHp1404a.h>
|
||||
|
||||
LOCAL unsigned long hpE1404DriverID;
|
||||
|
||||
struct hpE1404_config{
|
||||
void (*pSignalCallback)(int16_t signal);
|
||||
};
|
||||
|
||||
#define TLTRIG(N) (1<<(N))
|
||||
#define ECLTRIG(N) (1<<((N)+8))
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
#define HP1404A_INT_ENABLE 0x0008
|
||||
#define HP1404A_INT_DISABLE 0x0000
|
||||
|
||||
/*
|
||||
*
|
||||
* tag the device dependent registers
|
||||
*/
|
||||
#define IRQ_enable dir.w.dd.reg.ddx1a
|
||||
#define MSG_status dir.w.dd.reg.ddx1e
|
||||
#define fp_trig_drive dir.w.dd.reg.ddx2a
|
||||
#define bp_trig_drive dir.w.dd.reg.ddx22
|
||||
#define signal_read dir.r.dd.reg.ddx10
|
||||
|
||||
#define hpE1404PConfig(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
|
||||
|
||||
LOCAL void hpE1404InitLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL int hpE1404ShutDown(
|
||||
void
|
||||
);
|
||||
|
||||
LOCAL void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
);
|
||||
|
||||
LOCAL void hpE1404Int(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Init
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404Init(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
|
||||
status = rebootHookAdd(hpE1404ShutDown);
|
||||
if(status<0){
|
||||
status = S_dev_internal;
|
||||
errMessage(status, "rebootHookAdd() failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
hpE1404DriverID = epvxiUniqueDriverID();
|
||||
|
||||
status = epvxiRegisterMakeName(
|
||||
VXI_MAKE_HP,
|
||||
"Hewlett-Packard");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG_SLOT0,
|
||||
"Slot Zero Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG,
|
||||
"Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_MSG,
|
||||
"Translator (msg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDown()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL int hpE1404ShutDown(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDownLA()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404InitLA()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404InitLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct hpE1404_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
hpE1404Stat status;
|
||||
|
||||
status = epvxiOpen(
|
||||
la,
|
||||
hpE1404DriverID,
|
||||
sizeof(*pc),
|
||||
hpE1404IOReport);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
status = hpE1404PConfig(la, pc);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
epvxiClose(la, hpE1404DriverID);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the self test status to passed for
|
||||
* the message based device
|
||||
*/
|
||||
pcsr->MSG_status = VXIPASS<<2;
|
||||
|
||||
intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpE1404Int,
|
||||
la);
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404SignalConnect()
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404SignalConnect(
|
||||
unsigned la,
|
||||
void (*pSignalCallback)(int16_t signal)
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
return s;
|
||||
}
|
||||
|
||||
pc->pSignalCallback = pSignalCallback;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Int()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404Int(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned short signal;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* vector is only D8 so we cant check the cause of the int
|
||||
* (signal cause is assumed since that was all that was enabled)
|
||||
*/
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
signal = pcsr->signal_read;
|
||||
|
||||
if(pc->pSignalCallback){
|
||||
(*pc->pSignalCallback)(signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404RouteTriggerECL
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerECL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
|
||||
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* hpE1404RouteTriggerTTL
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = io_map&enable_map;
|
||||
pcsr->bp_trig_drive = (~io_map)&enable_map;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404IOReport()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user