Merged dbd2html branch
This commit is contained in:
@@ -13,6 +13,8 @@ SUBST_SUFFIX ?= .substitutions
|
||||
|
||||
##################################################### vpath
|
||||
|
||||
vpath %.pm $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.pod $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.dbd $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD))
|
||||
vpath %.db $(USR_VPATH) $(SRC_DIRS) $(dir $(DB))
|
||||
vpath %.vdb $(USR_VPATH) $(SRC_DIRS) $(dir $(DB))
|
||||
@@ -231,9 +233,9 @@ menu%.h$(DEP): menu%.dbd
|
||||
@$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
menu%.h$(DEP): ../menu%.dbd
|
||||
%.dbd$(DEP): %.dbd.pod
|
||||
@$(RM) $@
|
||||
@$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
%.dbd$(DEP): %Include.dbd
|
||||
@@ -361,14 +363,14 @@ $(COMMON_DIR)/menu%.h: ../menu%.dbd
|
||||
|
||||
##################################################### DBD files
|
||||
|
||||
$(COMMON_DIR)/bpt%.dbd: bpt%.data
|
||||
$(COMMON_DIR)/bpt%.dbd: bpt%.data
|
||||
@$(RM) $(notdir $@)
|
||||
$(MAKEBPT) $< $(notdir $@)
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/bpt%.dbd: ../bpt%.data
|
||||
$(COMMON_DIR)/%.dbd: %.dbd.pod
|
||||
@$(RM) $(notdir $@)
|
||||
$(MAKEBPT) $< $(notdir $@)
|
||||
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.dbd: %Include.dbd
|
||||
@@ -422,6 +424,30 @@ $(foreach file, $(DBD_INSTALLS), $(eval $(call DBD_INSTALLS_template, $(file))))
|
||||
|
||||
.PRECIOUS: $(COMMON_DBDS) $(COMMON_DIR)/%Include.dbd
|
||||
|
||||
##################################################### HTML files
|
||||
|
||||
$(COMMON_DIR)/%.html: %.dbd.pod $(TOOLS)/dbdToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/dbdToHtml.pl $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: %.pod $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: %.pm $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.html: ../%.pm $(TOOLS)/podToHtml.pl
|
||||
@$(RM) $(notdir $@)
|
||||
$(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.html %.html
|
||||
|
||||
##################################################### DB files
|
||||
|
||||
$(COMMON_DIR)/%.db$(RAW): $(COMMON_DIR)/%.edf
|
||||
|
||||
@@ -68,6 +68,8 @@ else
|
||||
INSTALL_TEMPLATES_SUBDIR = $(INSTALL_TEMPLATES)
|
||||
endif
|
||||
|
||||
HTMLS_DIR ?= .
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# First target
|
||||
|
||||
@@ -480,6 +482,10 @@ $(INSTALL_HTML)/$(HTMLS_DIR)/%: ../%
|
||||
$(ECHO) "Installing html $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_HTML)/$(HTMLS_DIR)/%: $(COMMON_DIR)/%
|
||||
$(ECHO) "Installing generated html $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_TEMPLATES_SUBDIR)/%: ../%
|
||||
$(ECHO) "Installing $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
@@ -61,10 +61,6 @@ ifdef T_A
|
||||
$(RM) $@ $@_new
|
||||
$(PERL) $(EXTUTILS)/xsubpp -typemap $(EXTUTILS)/typemap $< > $@_new && $(MV) $@_new $@
|
||||
|
||||
%.html: ../%.pm
|
||||
$(RM) $@
|
||||
podchecker $< && pod2html --infile=$< --outfile=$@
|
||||
|
||||
$(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)/%: %
|
||||
$(ECHO) "Installing loadable shared library $@"
|
||||
@$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)
|
||||
|
||||
@@ -25,3 +25,5 @@ PROD_HOST += makeBpt
|
||||
|
||||
makeBpt_SRCS = makeBpt
|
||||
|
||||
HTMLS += menuConvert.html
|
||||
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuConvert
|
||||
|
||||
This menu defines the standard analog conversions which are included with Base.
|
||||
IOC applications may add choices or replace the later choices in this menu,
|
||||
although the first three choices must not be renamed or moved to different
|
||||
positions. The breakpoint table name must exactly match the choice string
|
||||
listed here.
|
||||
|
||||
=menu menuConvert
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuConvert) {
|
||||
choice(menuConvertNO_CONVERSION,"NO CONVERSION")
|
||||
choice(menuConvertSLOPE,"SLOPE")
|
||||
@@ -58,6 +58,7 @@ menuGlobal_DBD += menuSimm.dbd
|
||||
DBDINC += $(basename $(menuGlobal_DBD))
|
||||
DBDINC += dbCommon
|
||||
|
||||
HTMLS += $(patsubst %.dbd.pod,%.html,$(notdir $(wildcard ../db/menu*.dbd.pod)))
|
||||
|
||||
dbCore_SRCS += dbLock.c
|
||||
dbCore_SRCS += dbAccess.c
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
# This is a Makefile fragment, see src/ioc/Makefile.
|
||||
|
||||
dbCommon.h$(DEP): $(IOCDIR)/db/dbCommonRecord.dbd
|
||||
dbCommon.h$(DEP): $(IOCDIR)/db/dbCommonRecord.dbd $(IOCDIR)/db/RULES
|
||||
@$(RM) $@
|
||||
@$(DBTORECORDTYPEH) -D -I ../db -o $(COMMONDEP_TARGET) $< > $@
|
||||
@echo "$(COMMONDEP_TARGET): ../Makefile" >> $@
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuAlarmSevr
|
||||
|
||||
This menu defines the four possible alarm severities that EPICS records can
|
||||
exhibit. Note that it is not possible to add or remove severities just by
|
||||
changing the choices defined here.
|
||||
|
||||
=menu menuAlarmSevr
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuAlarmSevr) {
|
||||
choice(menuAlarmSevrNO_ALARM,"NO_ALARM")
|
||||
choice(menuAlarmSevrMINOR,"MINOR")
|
||||
@@ -1,12 +1,21 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuSimm
|
||||
|
||||
This menu is used for Simulation Mode (SIMM) fields of input record types that
|
||||
can fetch either raw or engineering values through their SIOL link.
|
||||
|
||||
=menu menuSimm
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuSimm) {
|
||||
choice(menuSimmNO,"NO")
|
||||
choice(menuSimmYES,"YES")
|
||||
@@ -9,10 +9,12 @@
|
||||
|
||||
SRC_DIRS += $(STDDIR)/filters
|
||||
|
||||
DBD_INSTALLS += filters.dbd
|
||||
DBD += filters.dbd
|
||||
|
||||
dbRecStd_SRCS += ts.c
|
||||
dbRecStd_SRCS += dbnd.c
|
||||
dbRecStd_SRCS += arr.c
|
||||
dbRecStd_SRCS += sync.c
|
||||
|
||||
HTMLS += filters.html
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
registrar(tsInitialize)
|
||||
registrar(dbndInitialize)
|
||||
registrar(arrInitialize)
|
||||
registrar(syncInitialize)
|
||||
244
src/std/filters/filters.dbd.pod
Normal file
244
src/std/filters/filters.dbd.pod
Normal file
@@ -0,0 +1,244 @@
|
||||
=head1 Channel Filters
|
||||
|
||||
Channel Filters can be applied to Channel Access channels by a client, using
|
||||
a JSON Field Modifier to select the filter and any parameters.
|
||||
The following filters are available in this release:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<TimeStamp|/"TimeStamp Filter "ts"">
|
||||
|
||||
=item * L<Deadband|/"Deadband Filter "dbnd"">
|
||||
|
||||
=item * L<Array|/"Array Filter "arr"">
|
||||
|
||||
=item * L<Synchronize|/"Synchronize Filter "sync"">
|
||||
|
||||
=back
|
||||
|
||||
=head2 Using Filters
|
||||
|
||||
Channel filters can be added to any Channel Access channel name.
|
||||
There can be more than one filter applied to the same channel, in which case the
|
||||
order that they are specified will control the order in which they are applied
|
||||
to the resulting data-stream.
|
||||
The filter specification must appear after the field name, or if the default
|
||||
(VAL) field is used after a dot C<.> appended to the record name.
|
||||
With the exception of the array short-hand which is described below, all filters
|
||||
must appear inside a pair of braces C< {} > after the dot expressed as a JSON
|
||||
(L<JavaScript Object Notation|http://www.json.org/>) object, which allows filter
|
||||
parameters to be included as needed.
|
||||
|
||||
Each filter is given as a name/value pair. The filter name (given in parentheses
|
||||
in the titles below) is a string, and must be enclosed inside double-quotes C<">
|
||||
characters as per the JSON specification.
|
||||
Parameters to that filter are provided as the value part of the name/value pair,
|
||||
and will normally appear as a child JSON object consisting of name/value pairs
|
||||
inside a nested pair of braces C< {} >.
|
||||
|
||||
=head4 Example Filter
|
||||
|
||||
Given a record called C<test:channel> the following would apply a filter C<f> to
|
||||
the VAL field of that record, giving the filter two numeric parameters named
|
||||
C<lo> and C<hi>:
|
||||
|
||||
test:channel.{"f":{"lo":0,"hi":10}}
|
||||
|
||||
Note that due to the required presence of the double-quote characters in the
|
||||
JSON strings in the name string, it will usually be necessary to enclose a
|
||||
filtered name within single-quotes C<< ' ... ' >> when typing it as an
|
||||
argument to a Unix shell command.
|
||||
|
||||
=head2 Filter Reference
|
||||
|
||||
=cut
|
||||
|
||||
registrar(tsInitialize)
|
||||
|
||||
=head3 TimeStamp Filter C<"ts">
|
||||
|
||||
This filter is used to set the timestamp of the value fetched through
|
||||
the channel to the time the value was fetched (or an update was sent),
|
||||
rather than the time the record last
|
||||
processed which could have been days or even weeks ago for some records, or set
|
||||
to the EPICS epoch if the record has never processed.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
None, use an empty pair of braces.
|
||||
|
||||
=head4 Example
|
||||
|
||||
Hal$ caget -a 'test:channel.{"ts":{}}'
|
||||
test:channel.{"ts":{}} 2012-08-28 22:10:31.192547 0 UDF INVALID
|
||||
Hal$ caget -a 'test:channel'
|
||||
test:channel <undefined> 0 UDF INVALID
|
||||
|
||||
=cut
|
||||
|
||||
registrar(dbndInitialize)
|
||||
|
||||
=head3 Deadband Filter C<"dbnd">
|
||||
|
||||
This filter implements a channel-specific monitor deadband, which is applied
|
||||
after any deadbands implemented by the record itself (it can only drop updates
|
||||
that the unfiltered channel generates, never add additional updates).
|
||||
|
||||
The deadband can be specified as an absolute value change, or as a relative
|
||||
percentage.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
=over
|
||||
|
||||
=item Mode+Deadband C<"abs">/C<"rel"> (shorthand)
|
||||
|
||||
Mode and deadband can be specified in one definition (shorthand).
|
||||
The desired mode is given as parameter name (C<"abs"> or C<"rel">), with the
|
||||
numeric size of the deadband (absolute value or numeric percentage) as value.
|
||||
|
||||
=item Deadband C<"d">
|
||||
|
||||
The size of the deadband to use.
|
||||
Relative deadband values are given as a numeric percentage, but without any
|
||||
trailing percent character.
|
||||
|
||||
=item Mode C<"m"> (optional)
|
||||
|
||||
A string (enclosed in double-quotes C<">), which should contain either
|
||||
C<abs> or C<rel>.
|
||||
The default mode is C<abs> if no mode parameter is included.
|
||||
|
||||
=back
|
||||
|
||||
=head4 Example
|
||||
|
||||
Hal$ camonitor 'test:channel'
|
||||
test:channel 2012-09-01 22:10:19.600595 1 LOLO MAJOR
|
||||
test:channel 2012-09-01 22:10:20.600661 2 LOLO MAJOR
|
||||
test:channel 2012-09-01 22:10:21.600819 3 LOW MINOR
|
||||
test:channel 2012-09-01 22:10:22.600905 4 LOW MINOR
|
||||
test:channel 2012-09-01 22:10:23.601023 5
|
||||
test:channel 2012-09-01 22:10:24.601136 6 HIGH MINOR
|
||||
^C
|
||||
Hal$ camonitor 'test:channel.{"dbnd":{"abs":1.5}}'
|
||||
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:49.613341 1 LOLO MAJOR
|
||||
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:51.613615 3 LOW MINOR
|
||||
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:53.613804 5
|
||||
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:55.614074 7 HIGH MINOR
|
||||
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:57.614305 9 HIHI MAJOR
|
||||
^C
|
||||
|
||||
=cut
|
||||
|
||||
registrar(arrInitialize)
|
||||
|
||||
=head3 Array Filter C<"arr">
|
||||
|
||||
This filter is used to retrieve parts of an array (subarrays and strided
|
||||
subarrays).
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
Note: Negative index numbers address from the end of the array, with C<-1> being the last element.
|
||||
|
||||
=over
|
||||
|
||||
=item Square bracket notation C<[s:i:e]> (shorthand)
|
||||
|
||||
The familiar C<[s:i:e]> notation with square brackets can be used (shorthand).
|
||||
|
||||
=item Start index C<"s">
|
||||
|
||||
Index of the first original array element to retrieve.
|
||||
|
||||
=item Increment C<"i">
|
||||
|
||||
Index increment between retrieved elements of the original array; must be
|
||||
a positive number.
|
||||
|
||||
=item End index C<"e">
|
||||
|
||||
Index of the last original array element to retrieve.
|
||||
|
||||
=back
|
||||
|
||||
Defaults (when parameters are omitted) are:
|
||||
C<s=0> (first element), C<i=1> (fetch all elements), C<e=-1>
|
||||
(last element)
|
||||
|
||||
=head4 Example
|
||||
|
||||
Hal$ caget test:channel 'test:channel.{"arr":{"s":2,"i":2,"e":8}}' test:channel.[3:5] test:channel.[3:2:-3]
|
||||
test:channel 10 0 1 2 3 4 5 6 7 8 9
|
||||
test:channel.{"arr":{"s":2,"i":2,"e":8}} 4 2 4 6 8
|
||||
test:channel.[3:5] 3 3 4 5
|
||||
test:channel.[3:2:-3] 3 3 5 7
|
||||
|
||||
=cut
|
||||
|
||||
registrar(syncInitialize)
|
||||
|
||||
=head3 Synchronize Filter C<"sync">
|
||||
|
||||
This filter is used to dynamically enable or disable monitors according
|
||||
to a condition and a state variable declared by the IOC.
|
||||
|
||||
State variables have a boolean value and can be set by a binary output
|
||||
record, an iocsh command or by other software running in the IOC calling
|
||||
C<dbStateSet()>.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
=over
|
||||
|
||||
=item Mode+State
|
||||
|
||||
Mode and state can be specified in one definition (shorthand).
|
||||
The desired mode is given as parameter name (C<"before"> / C<"first"> /
|
||||
C<"while"> / C<"last"> / C<"after"> / C<"unless">), with the state name
|
||||
(enclosed in double quotes C<">) as value.
|
||||
|
||||
=item Mode C<"m">
|
||||
|
||||
A single word from the list below, enclosed in double quotes C<">.
|
||||
This controls how the state value should affect the monitor stream.
|
||||
|
||||
=over
|
||||
|
||||
=item C<"before"> E<mdash> only the last value received before the state
|
||||
changes from false to true is forwarded to the client.
|
||||
|
||||
=item C<"first"> E<mdash> only the first value received after the state
|
||||
changes from true to false is forwarded to the client.
|
||||
|
||||
=item C<"while"> E<mdash> values are forwarded to the client as long as
|
||||
the state is true.
|
||||
|
||||
=item C<"last"> E<mdash> only the last value received before the state
|
||||
changes from true to false is forwarded to the client.
|
||||
|
||||
=item C<"after"> E<mdash> only the first value received after the state
|
||||
changes from true to false is forwarded to the client.
|
||||
|
||||
=item C<"unless"> E<mdash> values are forwarded to the client as long
|
||||
as the state is false.
|
||||
|
||||
=back
|
||||
|
||||
=item State C<"s">
|
||||
|
||||
The name of a state variable, enclosed in double quotes C<">.
|
||||
|
||||
=back
|
||||
|
||||
=head4 Example
|
||||
|
||||
Assuming there is a system state called "blue", that is being controlled by
|
||||
some other facility such as a timing system, updates could be restricted to
|
||||
periods only when "blue" is true by using
|
||||
|
||||
Hal$ camonitor 'test:channel' 'test:channel.{"while":"blue"}'
|
||||
...
|
||||
|
||||
=cut
|
||||
@@ -21,11 +21,6 @@
|
||||
|
||||
#define STATE_NAME_LENGTH 20
|
||||
|
||||
static const
|
||||
chfPluginEnumType modeEnum[] = { {"before", 0}, {"first", 1},
|
||||
{"last", 2}, {"after", 3},
|
||||
{"while", 4}, {"unless", 5},
|
||||
{NULL,0} };
|
||||
typedef enum syncMode {
|
||||
syncModeBefore=0,
|
||||
syncModeFirst=1,
|
||||
@@ -35,6 +30,17 @@ typedef enum syncMode {
|
||||
syncModeUnless=5
|
||||
} syncMode;
|
||||
|
||||
static const
|
||||
chfPluginEnumType modeEnum[] = {
|
||||
{"before", syncModeBefore},
|
||||
{"first", syncModeFirst},
|
||||
{"last", syncModeLast},
|
||||
{"after", syncModeAfter},
|
||||
{"while", syncModeWhile},
|
||||
{"unless", syncModeUnless},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
typedef struct myStruct {
|
||||
syncMode mode;
|
||||
char state[STATE_NAME_LENGTH];
|
||||
|
||||
@@ -51,3 +51,4 @@ stdRecords_DBD = $(patsubst %,%.dbd,$(stdRecords))
|
||||
|
||||
dbRecStd_SRCS += $(patsubst %,%.c,$(stdRecords))
|
||||
|
||||
HTMLS += $(patsubst %.dbd.pod,%.html,$(notdir $(wildcard ../rec/*Record.dbd.pod)))
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2012 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Array Subroutine Record (aSub)
|
||||
|
||||
...
|
||||
|
||||
=head2 Record-specific Menus
|
||||
|
||||
=head3 Menu aSubLFLG
|
||||
|
||||
The LFLG field uses this menu to ...
|
||||
|
||||
=menu aSubLFLG
|
||||
|
||||
=head3 Menu aSubEFLG
|
||||
|
||||
The EFLG field uses this menu to ...
|
||||
|
||||
=menu aSubEFLG
|
||||
|
||||
...
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype aSub
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
menu(aSubLFLG) {
|
||||
choice(aSubLFLG_IGNORE,"IGNORE")
|
||||
choice(aSubLFLG_READ,"READ")
|
||||
@@ -191,12 +230,24 @@ recordtype(aSub) {
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
|
||||
=head3 Input Fields
|
||||
|
||||
...
|
||||
|
||||
=fields A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U
|
||||
|
||||
=cut
|
||||
|
||||
field(A,DBF_NOACCESS) {
|
||||
prompt("Input value A")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *a")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTA
|
||||
}
|
||||
field(B,DBF_NOACCESS) {
|
||||
prompt("Input value B")
|
||||
@@ -204,6 +255,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *b")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTB
|
||||
}
|
||||
field(C,DBF_NOACCESS) {
|
||||
prompt("Input value C")
|
||||
@@ -211,6 +265,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *c")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTC
|
||||
}
|
||||
field(D,DBF_NOACCESS) {
|
||||
prompt("Input value D")
|
||||
@@ -218,6 +275,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *d")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTD
|
||||
}
|
||||
field(E,DBF_NOACCESS) {
|
||||
prompt("Input value E")
|
||||
@@ -225,6 +285,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *e")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTE
|
||||
}
|
||||
field(F,DBF_NOACCESS) {
|
||||
prompt("Input value F")
|
||||
@@ -232,6 +295,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *f")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTF
|
||||
}
|
||||
field(G,DBF_NOACCESS) {
|
||||
prompt("Input value G")
|
||||
@@ -239,6 +305,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *g")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTG
|
||||
}
|
||||
field(H,DBF_NOACCESS) {
|
||||
prompt("Input value H")
|
||||
@@ -246,6 +315,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *h")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTH
|
||||
}
|
||||
field(I,DBF_NOACCESS) {
|
||||
prompt("Input value I")
|
||||
@@ -253,6 +325,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *i")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTI
|
||||
}
|
||||
field(J,DBF_NOACCESS) {
|
||||
prompt("Input value J")
|
||||
@@ -260,6 +335,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *j")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTJ
|
||||
}
|
||||
field(K,DBF_NOACCESS) {
|
||||
prompt("Input value K")
|
||||
@@ -267,6 +345,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *k")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTK
|
||||
}
|
||||
field(L,DBF_NOACCESS) {
|
||||
prompt("Input value L")
|
||||
@@ -274,6 +355,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *l")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTL
|
||||
}
|
||||
field(M,DBF_NOACCESS) {
|
||||
prompt("Input value M")
|
||||
@@ -281,6 +365,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *m")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTM
|
||||
}
|
||||
field(N,DBF_NOACCESS) {
|
||||
prompt("Input value N")
|
||||
@@ -288,6 +375,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *n")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTN
|
||||
}
|
||||
field(O,DBF_NOACCESS) {
|
||||
prompt("Input value O")
|
||||
@@ -295,6 +385,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *o")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTO
|
||||
}
|
||||
field(P,DBF_NOACCESS) {
|
||||
prompt("Input value P")
|
||||
@@ -302,6 +395,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *p")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTP
|
||||
}
|
||||
field(Q,DBF_NOACCESS) {
|
||||
prompt("Input value Q")
|
||||
@@ -309,6 +405,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *q")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTQ
|
||||
}
|
||||
field(R,DBF_NOACCESS) {
|
||||
prompt("Input value R")
|
||||
@@ -316,6 +415,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *r")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTR
|
||||
}
|
||||
field(S,DBF_NOACCESS) {
|
||||
prompt("Input value S")
|
||||
@@ -323,6 +425,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *s")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTS
|
||||
}
|
||||
field(T,DBF_NOACCESS) {
|
||||
prompt("Input value T")
|
||||
@@ -330,6 +435,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *t")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTT
|
||||
}
|
||||
field(U,DBF_NOACCESS) {
|
||||
prompt("Input value U")
|
||||
@@ -337,6 +445,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *u")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTU
|
||||
}
|
||||
field(FTA,DBF_MENU) {
|
||||
prompt("Type of A")
|
||||
@@ -905,12 +1016,24 @@ recordtype(aSub) {
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
|
||||
=head3 Value Fields
|
||||
|
||||
...
|
||||
|
||||
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
|
||||
|
||||
=cut
|
||||
|
||||
field(VALA,DBF_NOACCESS) {
|
||||
prompt("Output value A")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vala")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVA
|
||||
}
|
||||
field(VALB,DBF_NOACCESS) {
|
||||
prompt("Output value B")
|
||||
@@ -918,6 +1041,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valb")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVB
|
||||
}
|
||||
field(VALC,DBF_NOACCESS) {
|
||||
prompt("Output value C")
|
||||
@@ -925,6 +1051,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valc")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVC
|
||||
}
|
||||
field(VALD,DBF_NOACCESS) {
|
||||
prompt("Output value D")
|
||||
@@ -932,6 +1061,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vald")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVD
|
||||
}
|
||||
field(VALE,DBF_NOACCESS) {
|
||||
prompt("Output value E")
|
||||
@@ -939,6 +1071,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vale")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVE
|
||||
}
|
||||
field(VALF,DBF_NOACCESS) {
|
||||
prompt("Output value F")
|
||||
@@ -946,6 +1081,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valf")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVF
|
||||
}
|
||||
field(VALG,DBF_NOACCESS) {
|
||||
prompt("Output value G")
|
||||
@@ -953,6 +1091,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valg")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVG
|
||||
}
|
||||
field(VALH,DBF_NOACCESS) {
|
||||
prompt("Output value H")
|
||||
@@ -960,6 +1101,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valh")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVH
|
||||
}
|
||||
field(VALI,DBF_NOACCESS) {
|
||||
prompt("Output value I")
|
||||
@@ -967,6 +1111,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vali")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVI
|
||||
}
|
||||
field(VALJ,DBF_NOACCESS) {
|
||||
prompt("Output value J")
|
||||
@@ -974,6 +1121,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valj")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVJ
|
||||
}
|
||||
field(VALK,DBF_NOACCESS) {
|
||||
prompt("Output value K")
|
||||
@@ -981,6 +1131,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valk")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVK
|
||||
}
|
||||
field(VALL,DBF_NOACCESS) {
|
||||
prompt("Output value L")
|
||||
@@ -988,6 +1141,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vall")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVL
|
||||
}
|
||||
field(VALM,DBF_NOACCESS) {
|
||||
prompt("Output value M")
|
||||
@@ -995,6 +1151,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valm")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVM
|
||||
}
|
||||
field(VALN,DBF_NOACCESS) {
|
||||
prompt("Output value N")
|
||||
@@ -1002,6 +1161,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valn")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVN
|
||||
}
|
||||
field(VALO,DBF_NOACCESS) {
|
||||
prompt("Output value O")
|
||||
@@ -1009,6 +1171,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valo")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVO
|
||||
}
|
||||
field(VALP,DBF_NOACCESS) {
|
||||
prompt("Output value P")
|
||||
@@ -1016,6 +1181,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valp")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVP
|
||||
}
|
||||
field(VALQ,DBF_NOACCESS) {
|
||||
prompt("Output value Q")
|
||||
@@ -1023,6 +1191,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valq")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVQ
|
||||
}
|
||||
field(VALR,DBF_NOACCESS) {
|
||||
prompt("Output value R")
|
||||
@@ -1030,6 +1201,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valr")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVR
|
||||
}
|
||||
field(VALS,DBF_NOACCESS) {
|
||||
prompt("Output value S")
|
||||
@@ -1037,6 +1211,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *vals")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVS
|
||||
}
|
||||
field(VALT,DBF_NOACCESS) {
|
||||
prompt("Output value T")
|
||||
@@ -1044,6 +1221,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valt")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVT
|
||||
}
|
||||
field(VALU,DBF_NOACCESS) {
|
||||
prompt("Output value U")
|
||||
@@ -1051,6 +1231,9 @@ recordtype(aSub) {
|
||||
special(SPC_DBADDR)
|
||||
interest(2)
|
||||
extra("void *valu")
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
#=type Set by FTVU
|
||||
}
|
||||
field(OVLA,DBF_NOACCESS) {
|
||||
prompt("Old Output A")
|
||||
@@ -19,6 +19,9 @@ recordtype(aai) {
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
|
||||
@@ -19,6 +19,9 @@ recordtype(aao) {
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
recordtype(ai) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Current EGU Value")
|
||||
promptgroup(GUI_INPUTS)
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuConvert)
|
||||
}
|
||||
field(EGUF,DBF_DOUBLE) {
|
||||
prompt("Engineer Units Full")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGUL,DBF_DOUBLE) {
|
||||
prompt("Engineer Units Low")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(ASLO,DBF_DOUBLE) {
|
||||
prompt("Adjustment Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(SMOO,DBF_DOUBLE) {
|
||||
prompt("Smoothing")
|
||||
promptgroup(GUI_CONVERT)
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(AFTC,DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Time Constant")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(AFVL,DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ESLO,DBF_DOUBLE) {
|
||||
prompt("Raw to EGU Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
initial("1")
|
||||
}
|
||||
field(EOFF,DBF_DOUBLE) {
|
||||
prompt("Raw to EGU Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(ROFF,DBF_LONG) {
|
||||
prompt("Raw Offset, obsolete")
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(PBRK,DBF_NOACCESS) {
|
||||
prompt("Ptrto brkTable")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * pbrk")
|
||||
}
|
||||
field(INIT,DBF_SHORT) {
|
||||
prompt("Initialized?")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LBRK,DBF_SHORT) {
|
||||
prompt("LastBreak Point")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RVAL,DBF_LONG) {
|
||||
prompt("Current Raw Value")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_LONG) {
|
||||
prompt("Previous Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_DOUBLE) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
}
|
||||
631
src/std/rec/aiRecord.dbd.pod
Normal file
631
src/std/rec/aiRecord.dbd.pod
Normal file
@@ -0,0 +1,631 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Analog Input Record (ai)
|
||||
|
||||
This record type is normally used to obtain an analog value from a hardware
|
||||
input and convert it to engineering units.
|
||||
The record supports linear and break-point conversion to engineering units,
|
||||
smoothing, alarm limits, alarm filtering, and graphics and control limits.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype ai
|
||||
|
||||
=cut
|
||||
|
||||
recordtype(ai) {
|
||||
|
||||
=head3 Input Specification
|
||||
|
||||
These fields control where the record will read data from when it is processed:
|
||||
|
||||
=fields DTYP, INP
|
||||
|
||||
The DTYP field selects which device support layer should be responsible for
|
||||
providing input data to the record.
|
||||
The ai device support layers provided by EPICS Base are documented in the
|
||||
L<Device Support|devSoft> section.
|
||||
External support modules may provide additional device support for this record
|
||||
type.
|
||||
If not set explicitly, the DTYP value defaults to the first device support that
|
||||
is loaded for the record type, which will usually be the C<Soft Channel> support
|
||||
that comes with Base.
|
||||
|
||||
The INP link field contains a database or channel access link or provides
|
||||
hardware address information that the device support uses to determine where the
|
||||
input data should come from.
|
||||
The format for the INP field value depends on the device support layer that is
|
||||
selected by the DTYP field.
|
||||
See L<Address Specification|...> for a description of the various hardware
|
||||
address formats supported.
|
||||
|
||||
=head3 Units Conversion
|
||||
|
||||
These fields control if and how the raw input value gets converted into
|
||||
engineering units:
|
||||
|
||||
=fields RVAL, ROFF, ASLO, AOFF, LINR, ESLO, EOFF, EGUL, EGUF
|
||||
|
||||
These fields are not used if the device support layer reads its value in
|
||||
engineering units and puts it directly into the VAL field.
|
||||
This applies to Soft Channel and Async Soft Channel device support, and is also
|
||||
fairly common for GPIB and similar high-level device interfaces.
|
||||
|
||||
If the device support sets the RVAL field, the LINR field controls how this gets
|
||||
converted into engineering units and placed in the VAL field as follows:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
RVAL is converted to a double and ROFF is added to it.
|
||||
|
||||
=item 2.
|
||||
If ASLO is non-zero the value is multiplied by ASLO.
|
||||
|
||||
=item 3.
|
||||
AOFF is added.
|
||||
|
||||
=item 4.
|
||||
If LINR is C<NO CONVERSION> the units conversion is finished after the above
|
||||
steps.
|
||||
|
||||
=item 5.
|
||||
If LINR is C<LINEAR> or C<SLOPE>, the value from step 3 above is multiplied by
|
||||
ESLO and EOFF is added to complete the units conversion process.
|
||||
|
||||
=item 6.
|
||||
Any other value for LINR selects a particular breakpoint table to be used on the
|
||||
value from step 3 above.
|
||||
|
||||
=back
|
||||
|
||||
The distinction between the C<LINEAR> and C<SLOPE> settings for the LINR field
|
||||
are in how the conversion parameters are calculated:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
With C<LINEAR> conversion the user must set EGUL and EGUF to the lowest and
|
||||
highest possible engineering units values respectively that can be converted by
|
||||
the hardware.
|
||||
The device support knows the range of the raw data and calculates ESLO and EOFF
|
||||
from them.
|
||||
|
||||
=item *
|
||||
C<SLOPE> conversion requires the user to calculate the appropriate scaling and
|
||||
offset factors and put them directly in ESLO and EOFF.
|
||||
|
||||
=back
|
||||
|
||||
=head3 Smoothing Filter
|
||||
|
||||
This filter is usually only used if the device support sets the RVAL field and
|
||||
the Units Conversion process is used.
|
||||
Device support that directly sets the VAL field may implement the filter if
|
||||
desired.
|
||||
|
||||
The filter is controlled with a single parameter field:
|
||||
|
||||
=fields SMOO
|
||||
|
||||
The SMOO field should be set to a number between 0 and 1.
|
||||
If set to zero the filter is not used (no smoothing), while if set to one the
|
||||
result is infinite smoothing (the VAL field will never change).
|
||||
The calculation performed is:
|
||||
|
||||
=over
|
||||
|
||||
VAL = VAL * SMOO + (1 - SMOO) * New Data
|
||||
|
||||
=back
|
||||
|
||||
where C<New Data> was the result from the Units Conversion above.
|
||||
This implements a first-order infinite impulse response (IIR) digital filter
|
||||
with z-plane pole at SMOO.
|
||||
The equivalent continuous-time filter time constant E<tau> is given by
|
||||
|
||||
=over
|
||||
|
||||
E<tau> = E<minus>T / ln(SMOO)
|
||||
|
||||
=back
|
||||
|
||||
where T is the time between record processing.
|
||||
|
||||
=head3 Undefined Check
|
||||
|
||||
If after applying the smoothing filter the VAL field contains a NaN
|
||||
(Not-a-Number) value, the UDF field is set to a non-zero value, indicating that
|
||||
the record value is undefined, which will trigger a C<UDF_ALARM> with severity
|
||||
C<INVALID_ALARM>.
|
||||
|
||||
=fields UDF
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator.
|
||||
They do not affect the functioning of the record at all.
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
DESC is a string that is usually used to briefly describe the record.
|
||||
|
||||
=item *
|
||||
EGU is a string of up to 16 characters naming the engineering units that the VAL
|
||||
field represents.
|
||||
|
||||
=item *
|
||||
The HOPR and LOPR fields set the upper and lower display limits for the VAL,
|
||||
HIHI, HIGH, LOW, and LOLO fields.
|
||||
|
||||
=item *
|
||||
The PREC field determines the floating point precision (i.e. the number of
|
||||
digits to show after the decimal point) with which to display VAL and the other
|
||||
DOUBLE fields.
|
||||
|
||||
=back
|
||||
|
||||
=fields DESC, EGU, HOPR, LOPR, PREC
|
||||
|
||||
=head3 Alarm Limits
|
||||
|
||||
The user configures limit alarms by putting numerical values into the HIHI,
|
||||
HIGH, LOW and LOLO fields, and by setting the associated alarm severity in the
|
||||
corresponding HHSV, HSV, LSV and LLSV menu fields.
|
||||
|
||||
The HYST field controls hysteresis to prevent alarm chattering from an input
|
||||
signal that is close to one of the limits and suffers from significant readout
|
||||
noise.
|
||||
|
||||
The AFTC field sets the time constant on a low-pass filter that delays the
|
||||
reporting of limit alarms until the signal has been within the alarm range for
|
||||
that number of seconds (the default AFTC value of zero retains the previous
|
||||
behavior).
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, AFTC, LALM
|
||||
|
||||
=head3 Monitor Parameters
|
||||
|
||||
These parameters are used to determine when to send monitors placed on the VAL
|
||||
field.
|
||||
The monitors are sent when the current value exceeds the last transmitted value
|
||||
by the appropriate deadband.
|
||||
If these fields are set to zero, a monitor will be triggered every time the
|
||||
value changes; if set to -1, a monitor will be sent every time the record is
|
||||
processed.
|
||||
|
||||
The ADEL field sets the deadband for archive monitors (C<DBE_LOG> events), while
|
||||
the MDEL field controls value monitors (C<DBE_VALUE> events).
|
||||
|
||||
The remaining fields are used by the record at run-time to implement the record
|
||||
monitoring functionality.
|
||||
|
||||
=fields ADEL, MDEL, ALST, MLST, ORAW
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Current EGU Value")
|
||||
promptgroup(GUI_INPUTS)
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuConvert)
|
||||
}
|
||||
field(EGUF,DBF_DOUBLE) {
|
||||
prompt("Engineer Units Full")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGUL,DBF_DOUBLE) {
|
||||
prompt("Engineer Units Low")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(ASLO,DBF_DOUBLE) {
|
||||
prompt("Adjustment Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(SMOO,DBF_DOUBLE) {
|
||||
prompt("Smoothing")
|
||||
promptgroup(GUI_CONVERT)
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(AFTC,DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Time Constant")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(AFVL,DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ESLO,DBF_DOUBLE) {
|
||||
prompt("Raw to EGU Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
initial("1")
|
||||
}
|
||||
field(EOFF,DBF_DOUBLE) {
|
||||
prompt("Raw to EGU Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(ROFF,DBF_LONG) {
|
||||
prompt("Raw Offset, obsolete")
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(PBRK,DBF_NOACCESS) {
|
||||
prompt("Ptrto brkTable")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * pbrk")
|
||||
}
|
||||
field(INIT,DBF_SHORT) {
|
||||
prompt("Initialized?")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LBRK,DBF_SHORT) {
|
||||
prompt("LastBreak Point")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RVAL,DBF_LONG) {
|
||||
prompt("Current Raw Value")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_LONG) {
|
||||
prompt("Previous Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode
|
||||
|
||||
The record provides several fields to support simulation of absent hardware.
|
||||
If the SIML field is set it is used to read a value into the SIMM field, which
|
||||
controls whether simulation is used or not:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
SIMM must be zero (C<NO>) for the record to request a value from the device
|
||||
support.
|
||||
|
||||
=item *
|
||||
If SIMM is C<YES> and the SIOL link field is set, a simlated value in
|
||||
engineering units is read using the link into the SVAL field, from where it will
|
||||
subsequently be copied into the VAL field.
|
||||
|
||||
=item *
|
||||
If SIMM is C<RAW> the SIOL link is still read into SVAL, but is then truncated
|
||||
and copied into the RVAL field.
|
||||
The L</Units Conversion> process described above is then followed to transform
|
||||
the simulated raw value into engineering units.
|
||||
|
||||
=back
|
||||
|
||||
The SIMS field can be set to give the record an alarm severity while it is in
|
||||
simulation mode.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS
|
||||
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim. Input Specification")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_DOUBLE) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim. Mode Location")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
}
|
||||
|
||||
=head2 Device Support Interface
|
||||
|
||||
The record requires device support to provide an entry table (dset) which
|
||||
defines the following members:
|
||||
|
||||
typedef struct {
|
||||
long number;
|
||||
long (*report)(int level);
|
||||
long (*init)(int after);
|
||||
long (*init_record)(aiRecord *prec);
|
||||
long (*get_ioint_info)(int cmd, aiRecord *prec, IOSCANPVT *piosl);
|
||||
long (*read_ai)(aiRecord *prec);
|
||||
long (*special_linconv)(aiRecord *prec, int after);
|
||||
} aidset;
|
||||
|
||||
The module must set C<number> to at least 6, and provide a pointer to its
|
||||
C<read_ai()> routine; the other function pointers may be C<NULL> if their
|
||||
associated functionality is not required for this support layer.
|
||||
Most device supports also provide an C<init_record()> routine to configure the
|
||||
record instance and connect it to the hardware or driver support layer, and if
|
||||
using the record's L</Units Conversion> features they set C<special_linconv()>
|
||||
as well.
|
||||
|
||||
The individual routines are described below.
|
||||
|
||||
=head3 Device Support Routines
|
||||
|
||||
=head4 long report(int level)
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=head4 long init(int after)
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=head4 long init_record(aiRecord *prec)
|
||||
|
||||
This optional routine is called by the record initialization code for each ai
|
||||
record instance that has its DTYP field set to use this device support.
|
||||
It is normally used to check that the INP address is the expected type and that
|
||||
it points to a valid device; to allocate any record-specific buffer space and
|
||||
other memory; and to connect any communication channels needed for the
|
||||
C<read_ai()> routine to work properly.
|
||||
|
||||
If the record type's unit conversion features are used, the C<init_record()>
|
||||
routine should calculate appropriate values for the ESLO and EOFF fields from
|
||||
the EGUL and EGUF field values.
|
||||
This calculation only has to be performed if the record's LINR field is set to
|
||||
C<LINEAR>, but it is not necessary to check that condition first.
|
||||
This same calculation takes place in the C<special_linconv()> routine, so the
|
||||
implementation can usually just call that routine to perform the task.
|
||||
|
||||
=head4 long get_ioint_info(int cmd, aiRecord *prec, IOSCANPVT *piosl)
|
||||
|
||||
This optional routine is called whenever the record's SCAN field is being
|
||||
changed to or from the value C<I/O Intr> to find out which I/O Interrupt Scan
|
||||
list the record should be added to or deleted from.
|
||||
If this routine is not provided, it will not be possible to set the SCAN field
|
||||
to the value C<I/O Intr> at all.
|
||||
|
||||
The C<cmd> parameter is zero when the record is being added to the scan list,
|
||||
and one when it is being removed from the list.
|
||||
The routine must determine which interrupt source the record should be connected
|
||||
to, which it indicates by the scan list that it points the location at C<*piosl>
|
||||
to before returning.
|
||||
It can prevent the SCAN field from being changed at all by returning a non-zero
|
||||
value to its caller.
|
||||
|
||||
In most cases the device support will create the I/O Interrupt Scan lists that
|
||||
it returns for itself, by calling C<void scanIoInit(IOSCANPVT *piosl)> once for
|
||||
each separate interrupt source.
|
||||
That routine allocates memory and inializes the list, then passes back a pointer
|
||||
to the new list in the location at C<*piosl>.
|
||||
|
||||
When the device support receives notification that the interrupt has occurred,
|
||||
it announces that to the IOC by calling C<void scanIoRequest(IOSCANPVT iosl)>
|
||||
which will arrange for the appropriate records to be processed in a suitable
|
||||
thread.
|
||||
The C<scanIoRequest()> routine is safe to call from an interrupt service routine
|
||||
on embedded architectures (vxWorks and RTEMS).
|
||||
|
||||
=head4 long read_ai(aiRecord *prec)
|
||||
|
||||
This essential routine is called when the record wants a new value from the
|
||||
addressed device.
|
||||
It is responsible for performing (or at least initiating) a read operation, and
|
||||
(eventually) returning its value to the record.
|
||||
|
||||
... PACT and asynchronous processing ...
|
||||
|
||||
... return value ...
|
||||
|
||||
=head4 long special_linconv(aiRecord *prec, int after)
|
||||
|
||||
This optional routine should be provided if the record type's unit conversion
|
||||
features are used by the device support's C<read_ai()> routine returning a
|
||||
status value of zero.
|
||||
It is called by the record code whenever any of the the fields LINR, EGUL or
|
||||
EGUF are modified and LINR has the value C<LINEAR>.
|
||||
The routine must calculate and set the fields EOFF and ESLO appropriately based
|
||||
on the new values of EGUL and EGUF.
|
||||
|
||||
These calculations can be expressed in terms of the minimum and maximum raw
|
||||
values that the C<read_ai()> routine can put in the RVAL field.
|
||||
When RVAL is set to I<RVAL_max> the VAL field will be set to EGUF, and when RVAL
|
||||
is set to I<RVAL_min> the VAL field will become EGUL.
|
||||
|
||||
The fomulae to use are:
|
||||
|
||||
=over
|
||||
|
||||
EOFF = (I<RVAL_max> * EGUL E<minus> I<RVAL_min> * EGUF) /
|
||||
(I<RVAL_max> E<minus> I<RVAL_min>)
|
||||
|
||||
ESLO = (EGUF E<minus> EGUL) / (I<RVAL_max> E<minus> I<RVAL_min>)
|
||||
|
||||
=back
|
||||
|
||||
Note that the record support sets EOFF to EGUL before calling this routine,
|
||||
which is a very common case (when I<RVAL_min> is zero).
|
||||
|
||||
=head3 Extended Device Support
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
@@ -1,308 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
menu(aoOIF) {
|
||||
choice(aoOIF_Full,"Full")
|
||||
choice(aoOIF_Incremental,"Incremental")
|
||||
}
|
||||
recordtype(ao) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Desired Output")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(OVAL,DBF_DOUBLE) {
|
||||
prompt("Output Value")
|
||||
}
|
||||
field(OUT,DBF_OUTLINK) {
|
||||
prompt("Output Specification")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(OROC,DBF_DOUBLE) {
|
||||
prompt("Output Rate of Chang")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(DOL,DBF_INLINK) {
|
||||
prompt("Desired Output Loc")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(OMSL,DBF_MENU) {
|
||||
prompt("Output Mode Select")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
menu(menuOmsl)
|
||||
}
|
||||
field(OIF,DBF_MENU) {
|
||||
prompt("Out Full/Incremental")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
menu(aoOIF)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuConvert)
|
||||
}
|
||||
field(EGUF,DBF_DOUBLE) {
|
||||
prompt("Eng Units Full")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGUL,DBF_DOUBLE) {
|
||||
prompt("Eng Units Low")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(ROFF,DBF_LONG) {
|
||||
prompt("Raw Offset, obsolete")
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(EOFF,DBF_DOUBLE) {
|
||||
prompt("EGU to Raw Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(ESLO,DBF_DOUBLE) {
|
||||
prompt("EGU to Raw Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
initial("1")
|
||||
}
|
||||
field(DRVH,DBF_DOUBLE) {
|
||||
prompt("Drive High Limit")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(DRVL,DBF_DOUBLE) {
|
||||
prompt("Drive Low Limit")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(ASLO,DBF_DOUBLE) {
|
||||
prompt("Adjustment Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(RVAL,DBF_LONG) {
|
||||
prompt("Current Raw Value")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_LONG) {
|
||||
prompt("Previous Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RBV,DBF_LONG) {
|
||||
prompt("Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(ORBV,DBF_LONG) {
|
||||
prompt("Prev Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(PVAL,DBF_DOUBLE) {
|
||||
prompt("Previous value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(PBRK,DBF_NOACCESS) {
|
||||
prompt("Ptrto brkTable")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * pbrk")
|
||||
}
|
||||
field(INIT,DBF_SHORT) {
|
||||
prompt("Initialized?")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LBRK,DBF_SHORT) {
|
||||
prompt("LastBreak Point")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(2)
|
||||
menu(menuIvoa)
|
||||
}
|
||||
field(IVOV,DBF_DOUBLE) {
|
||||
prompt("INVALID output value")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(2)
|
||||
}
|
||||
field(OMOD,DBF_UCHAR) {
|
||||
prompt("Was OVAL modified?")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
}
|
||||
917
src/std/rec/aoRecord.dbd.pod
Normal file
917
src/std/rec/aoRecord.dbd.pod
Normal file
@@ -0,0 +1,917 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Analog Output Record (ao)
|
||||
|
||||
This record type is normally used to send an analog value to an output device,
|
||||
converting it from engineering units into an integer value if necessary.
|
||||
The record supports alarm and drive limits, rate-of-change limiting, output
|
||||
value integration, linear and break-point conversion from engineering units, and
|
||||
graphics and control limits.
|
||||
|
||||
=head2 Record-specific Menus
|
||||
|
||||
=head3 Menu aoOIF
|
||||
|
||||
The OIF field which uses this menu controls whether the record acts as an
|
||||
integrator (C<Incremental>) or not (C<Full>).
|
||||
|
||||
=menu aoOIF
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype ao
|
||||
|
||||
=cut
|
||||
|
||||
menu(aoOIF) {
|
||||
choice(aoOIF_Full,"Full")
|
||||
choice(aoOIF_Incremental,"Incremental")
|
||||
}
|
||||
|
||||
recordtype(ao) {
|
||||
|
||||
=head3 Output Value Determination
|
||||
|
||||
These fields control how the record determines the value to be output when it
|
||||
gets processed:
|
||||
|
||||
=fields OMSL, DOL, OIF, PVAL, DRVH, DRVL, VAL, OROC, OVAL
|
||||
|
||||
The following steps are performed in order during record processing.
|
||||
|
||||
=head4 Fetch Value, Integrate
|
||||
|
||||
The OMSL menu field is used to determine whether the DOL link and OIF menu
|
||||
fields should be used during processing or not:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
If OMSL is C<supervisory> the DOL and OIF fields are not used.
|
||||
The new output value is taken from the VAL field, which may have been set from
|
||||
elsewhere.
|
||||
|
||||
=item *
|
||||
If OMSL is C<closed_loop> the DOL link field is read to obtain a value; if OIF
|
||||
is C<Incremental> and the DOL link was read successfully, the record's previous
|
||||
output value PVAL is added to it.
|
||||
|
||||
=back
|
||||
|
||||
=head4 Drive Limits
|
||||
|
||||
The output value is now clipped to the range DRVL to DRVH inclusive, provided
|
||||
that DRVH > DRVL.
|
||||
The result is copied into both the VAL and PVAL fields.
|
||||
|
||||
=head4 Limit Rate of Change
|
||||
|
||||
If the OROC field is not zero, the VAL field is now adjusted so it is no more
|
||||
than OROC different to the previous output value given in OVAL.
|
||||
OROC thus determines the maximum change in the output value that can occur each
|
||||
time the record gets processed.
|
||||
The result is copied into the OVAL field, which is used as the input to the
|
||||
following Units Conversion processing stage.
|
||||
|
||||
=head3 Units Conversion
|
||||
|
||||
...
|
||||
|
||||
|
||||
For analog output records that do not use the Soft Channel device support
|
||||
routine, the specified conversions (if any) are performed on the OVAL field and
|
||||
the resulting value in the RVAL field is sent to the address contained in the
|
||||
output link after it is adjusted by the values in the AOFF and ASLO fields.
|
||||
|
||||
=fields LINR, RVAL, ROFF, EGUF, EGUL, AOFF, ASLO, ESLO, EOFF
|
||||
|
||||
=head4 Conversion Related Fields and the Conversion Process
|
||||
|
||||
Except for analog outputs that use Soft Channel device support, the LINR field
|
||||
determines if a conversion is performed and which conversion algorithm is used
|
||||
to convert OVAL to RVAL.
|
||||
|
||||
The LINR field can specify C<LINEAR> or C<SLOPE> for linear conversions,
|
||||
C<NO CONVERSION> for no conversions at all, or the name of a breakpoint table
|
||||
such as C<typeKdegC> for breakpoint conversions.
|
||||
|
||||
Note that the ESLO, EOFF, EGUF, and EGUL fields are only used for linear
|
||||
conversions.
|
||||
Also note that none of these fields have any significance for records that use
|
||||
the Soft Channel device support module.
|
||||
|
||||
=over
|
||||
|
||||
=item EGUF, EGUF
|
||||
|
||||
The user must calculate these fields when configuring the database for records
|
||||
that use C<LINEAR> conversions.
|
||||
They are used to calculate the values for ESLO and EOFF.
|
||||
See Conversion Specification for more information on how to calculate these
|
||||
fields.
|
||||
|
||||
=item AOFF, ASLO
|
||||
|
||||
These fields are adjustment parameters for the raw output values.
|
||||
They are applied to the raw output value after conversion from engineering
|
||||
units.
|
||||
|
||||
=item ESLO, EOFF
|
||||
|
||||
Computed by device support using EGUF and EGUL when LINR specifies C<LINEAR>.
|
||||
These values must be supplied by the user when LINR specifies C<SLOPE>.
|
||||
Used only when LINR is C<LINEAR> or C<SLOPE>.
|
||||
|
||||
=item ROFF
|
||||
|
||||
This field can be used to offset the raw value generated by the conversion
|
||||
process, which is needed for some kinds of hardware.
|
||||
|
||||
=back
|
||||
|
||||
Conversion proceeds as follows:
|
||||
|
||||
=over
|
||||
|
||||
=item 1. If LINR==LINEAR or LINR==SLOPE, then X = (VAL - EOFF) / ESLO,
|
||||
else if LINR==NO_CONVERSION, then X = VAL,
|
||||
else X is obtained via breakpoint table.
|
||||
|
||||
=item 2. X = (X - AOFF) / ASLO
|
||||
|
||||
=item 3. RVAL = round(X) - ROFF
|
||||
|
||||
=back
|
||||
|
||||
To see how the Raw Soft Channel device support routine uses these
|
||||
fields, see L</Device Support For Soft Records> below for more
|
||||
information.
|
||||
|
||||
=head3 Output Specification
|
||||
|
||||
The analog output record sends its desired output to the address in the
|
||||
OUT field. For analog outputs that write their values to devices, the
|
||||
OUT field must specify the address of the I/O card. In addition, the
|
||||
DTYP field must contain the name of the device support module. Be aware
|
||||
that the address format differs according to the I/O bus used. See
|
||||
Address Specification for information on the format of hardware
|
||||
addresses. The user can see a list of the device support modules
|
||||
currently supported at the user's local site by using the dbst utility
|
||||
in R3.13.
|
||||
|
||||
For soft records the output link can be a database link, a channel
|
||||
access link, or a constant value. If the link is a constant, no output
|
||||
is sent. See Address Specification for information on the format of
|
||||
database and channel access addresses.
|
||||
|
||||
=fields DTYP, OUT
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator.
|
||||
They display the value and other parameters of the analog output either
|
||||
textually or graphically.
|
||||
|
||||
EGU is a string of up to 16 characters describing the units that the
|
||||
analog output measures. It is retrieved by the get_units record support
|
||||
routine.
|
||||
|
||||
The HOPR and LOPR fields set the upper and lower display limits for the
|
||||
VAL, OVAL, PVAL, HIHI, HIGH, LOW, and LOLO fields. Both the
|
||||
get_graphic_double and get_control_double record support routines
|
||||
retrieve these fields. If these values are defined, they must be in the
|
||||
range: DRVL E<lt>= LOPR E<lt>= HOPR E<lt>= DRVH.
|
||||
|
||||
The PREC field determines the floating point precision with which to
|
||||
display VAL, OVAL and PVAL. It is used whenever the get_precision
|
||||
record support routine is called.
|
||||
|
||||
See Fields Common to All Record Types for more on the record name
|
||||
(NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, HOPR, LOPR, PREC, NAME, DESC
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The possible alarm conditions for analog outputs are the SCAN, READ,
|
||||
INVALID and limit alarms. The SCAN, READ, and INVALID alarms are called
|
||||
by the record or device support routines.
|
||||
|
||||
The limit alarms are configured by the user in the HIHI, LOLO, HIGH,
|
||||
and LOW fields, which must be floating-point values. For each of these
|
||||
fields, there is a corresponding severity field which can be either
|
||||
NO_ALARM, MINOR, or MAJOR.
|
||||
|
||||
See Alarm Specification for a complete explanation of alarms and these
|
||||
fields. See Invalid Alarm Output Action for more information on the
|
||||
IVOA and IVOV fields. Alarm Fields lists other fields related to a
|
||||
alarms that are common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, IVOA, IVOV
|
||||
|
||||
=head3 Monitor Parameters
|
||||
|
||||
These parameters are used to specify deadbands for monitors on the VAL
|
||||
field. The monitors are sent when the value field exceeds the last
|
||||
monitored field by the specified deadband. If these fields have a value
|
||||
of zero, everytime the value changes, a monitor will be triggered; if
|
||||
they have a value of -1, everytime the record is processed, monitors
|
||||
are triggered. ADEL is the deadband for archive monitors, and MDEL the
|
||||
deadband for all other types of monitors. See Monitor Specification for
|
||||
a complete explanation of monitors.
|
||||
|
||||
=fields ADEL, MDEL
|
||||
|
||||
=head3 Run-time and Simulation Mode Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the
|
||||
analog output. They are not configurable. They represent the current
|
||||
state of the record. The record support routines use some of them for
|
||||
more efficient processing.
|
||||
|
||||
The ORAW field is used to decide if monitors should be triggered for
|
||||
RVAL when monitors are triggered for VAL. The RBV field is the actual
|
||||
read back value obtained from the hardware itself or from the
|
||||
associated device driver. It is the responsibility of the device
|
||||
support routine to give this field a value.
|
||||
|
||||
ORBV is used to decide if monitors should be triggered for RBV at the
|
||||
same time monitors are triggered for changes in VAL.
|
||||
|
||||
The LALM, MLST, and ALST fields are used to implement the hysteresis
|
||||
factors for monitor callbacks.
|
||||
|
||||
The INIT field is used to initialize the LBRK field and for smoothing.
|
||||
|
||||
The PBRK field contains a pointer to the current breakpoint table (if
|
||||
any), and LBRK contains a pointer to the last breakpoint table used.
|
||||
|
||||
The OMOD field indicates whether OVAL differs from VAL. It will be
|
||||
different if VAL or OVAL have changed since the last time the record
|
||||
was processed, or if VAL has been adjusted by OROC during the current
|
||||
processing.
|
||||
|
||||
=fields ORAW, RBV, ORBV, LALM, ALST, MLST, INIT, PBRK, LBRK, PVAL, OMOD
|
||||
|
||||
The following fields are used to operate the analog output in the
|
||||
simulation mode. See Fields Common to Many Record Types for more
|
||||
information on these fields.
|
||||
|
||||
=fields SIOL, SIML, SIMM, SIMS
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Desired Output")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(OVAL,DBF_DOUBLE) {
|
||||
prompt("Output Value")
|
||||
}
|
||||
field(OUT,DBF_OUTLINK) {
|
||||
prompt("Output Specification")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(OROC,DBF_DOUBLE) {
|
||||
prompt("Output Rate of Change")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(DOL,DBF_INLINK) {
|
||||
prompt("Desired Output Loc")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
}
|
||||
field(OMSL,DBF_MENU) {
|
||||
prompt("Output Mode Select")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
menu(menuOmsl)
|
||||
}
|
||||
field(OIF,DBF_MENU) {
|
||||
prompt("Out Full/Incremental")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(1)
|
||||
menu(aoOIF)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuConvert)
|
||||
}
|
||||
field(EGUF,DBF_DOUBLE) {
|
||||
prompt("Eng Units Full")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGUL,DBF_DOUBLE) {
|
||||
prompt("Eng Units Low")
|
||||
promptgroup(GUI_CONVERT)
|
||||
special(SPC_LINCONV)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(ROFF,DBF_LONG) {
|
||||
prompt("Raw Offset, obsolete")
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(EOFF,DBF_DOUBLE) {
|
||||
prompt("EGU to Raw Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
}
|
||||
field(ESLO,DBF_DOUBLE) {
|
||||
prompt("EGU to Raw Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(2)
|
||||
initial("1")
|
||||
}
|
||||
field(DRVH,DBF_DOUBLE) {
|
||||
prompt("Drive High Limit")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(DRVL,DBF_DOUBLE) {
|
||||
prompt("Drive Low Limit")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(ASLO,DBF_DOUBLE) {
|
||||
prompt("Adjustment Slope")
|
||||
promptgroup(GUI_CONVERT)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup(GUI_ALARMS)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup(GUI_ALARMS)
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup(GUI_DISPLAY)
|
||||
interest(1)
|
||||
}
|
||||
field(RVAL,DBF_LONG) {
|
||||
prompt("Current Raw Value")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_LONG) {
|
||||
prompt("Previous Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RBV,DBF_LONG) {
|
||||
prompt("Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(ORBV,DBF_LONG) {
|
||||
prompt("Prev Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(PVAL,DBF_DOUBLE) {
|
||||
prompt("Previous value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(PBRK,DBF_NOACCESS) {
|
||||
prompt("Ptrto brkTable")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * pbrk")
|
||||
}
|
||||
field(INIT,DBF_SHORT) {
|
||||
prompt("Initialized?")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LBRK,DBF_SHORT) {
|
||||
prompt("LastBreak Point")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
promptgroup(GUI_INPUTS)
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(2)
|
||||
menu(menuIvoa)
|
||||
}
|
||||
field(IVOV,DBF_DOUBLE) {
|
||||
prompt("INVALID output value")
|
||||
promptgroup(GUI_OUTPUT)
|
||||
interest(2)
|
||||
}
|
||||
field(OMOD,DBF_UCHAR) {
|
||||
prompt("Was OVAL modified?")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
}
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
=head3 Record Support Routines
|
||||
|
||||
The following are the record support routines that would be of interest
|
||||
to an application developer. Other routines are the get_units,
|
||||
get_precision, get_graphic_double, and get_control_double routines.
|
||||
|
||||
=over
|
||||
|
||||
=item init_record
|
||||
|
||||
This routine initializes SIMM if SIML is a constant or creates a
|
||||
channel access link if SIML is PV_LINK. If SIOL is PV_LINK a channel
|
||||
access link is created.
|
||||
|
||||
This routine next checks to see that device support is available. If
|
||||
DOL is a constant, then VAL is initialized with its value and UDF is
|
||||
set to FALSE.
|
||||
|
||||
The routine next checks to see if the device support write routine is
|
||||
defined. If either device support or the device support write routine
|
||||
does not exist, an error message is issued and processing is
|
||||
terminated.
|
||||
|
||||
For compatibility with old device supports that don't know EOFF, if
|
||||
both EOFF and ESLO have their default value, EOFF is set to EGUL.
|
||||
|
||||
If device support includes init_record, it is called.
|
||||
|
||||
INIT is set TRUE. This causes PBRK, LBRK, and smoothing to be
|
||||
re-initialized. If "backwards" linear conversion is requested, then VAL
|
||||
is computed from RVAL using the algorithm:
|
||||
|
||||
VAL = ((RVAL+ROFF) * ASLO + AOFF) * ESLO + EOFF
|
||||
|
||||
and UDF is set to FALSE.
|
||||
|
||||
For breakpoint conversion, a call is made to cvtEngToRawBpt and UDF is
|
||||
then set to FALSE. PVAL is set to VAL.
|
||||
|
||||
=item process
|
||||
|
||||
See next section.
|
||||
|
||||
=item special
|
||||
|
||||
The only special processing for analog output records is SPC_LINCONV
|
||||
which is invoked whenever either of the fields LINR, EGUF, EGUL or ROFF
|
||||
is changed If the device support routine special_linconv exists it is
|
||||
called.
|
||||
|
||||
INIT is set TRUE. This causes PBRK, LBRK, and smoothing to be
|
||||
re-initialized.
|
||||
|
||||
=item get_value
|
||||
|
||||
Fills in the values of struct valueDes so that they refer to VAL.
|
||||
|
||||
=item get_alarm_double
|
||||
|
||||
Sets the following values:
|
||||
|
||||
upper_alarm_limit = HIHI
|
||||
upper_warning_limit = HIGH
|
||||
lower_warning_limit = LOW
|
||||
lower_alarm_limit = LOLO
|
||||
|
||||
=back
|
||||
|
||||
=head3 Record Processing
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1. Check to see that the appropriate device support module
|
||||
exists. If it doesn't, an error message is issued and processing is
|
||||
terminated with the PACT field set to TRUE. This ensures that processes
|
||||
will no longer be called for this record. Thus error storms will not
|
||||
occur.
|
||||
|
||||
=item 2. Check PACT: If PACT is FALSE call fetch_values and convert
|
||||
which perform the following steps:
|
||||
|
||||
=over
|
||||
|
||||
=item * fetch_values:
|
||||
|
||||
=over
|
||||
|
||||
=item * if DOL is DB_LINK and OMSL is CLOSED_LOOP then get value from
|
||||
DOL
|
||||
|
||||
=item * if OIF is INCREMENTAL then set value = value + VAL else value =
|
||||
VAL
|
||||
|
||||
=back
|
||||
|
||||
=item * convert:
|
||||
|
||||
=over
|
||||
|
||||
=item * If Drive limits are defined force value to be within limits
|
||||
|
||||
=item * Set VAL equal to value
|
||||
|
||||
=item * Set UDF to FALSE.
|
||||
|
||||
=item * If OVAL is undefined set it equal to value
|
||||
|
||||
=item * If OROC is defined and not 0 make |value-OVAL| E<lt>=OROC
|
||||
|
||||
=item * Set OVAL equal to value
|
||||
|
||||
=item * Compute RVAL from OVAL. using linear or break point table
|
||||
conversion. For linear conversions the algorithm is RVAL =
|
||||
(OVAL-EOFF)/ESLO.
|
||||
|
||||
=item * For break point table conversion a call is made to
|
||||
cvtEngToRawBpt.
|
||||
|
||||
=item * After that, for all conversion types AOFF, ASLO, and ROFF are
|
||||
calculated in, using the formula RVAL = (RVAL -AOFF) / ASLO - ROFF.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=item 3. Check alarms: This routine checks to see if the new VAL causes
|
||||
the alarm status and severity to change. If so, NSEV, NSTA and y are
|
||||
set. It also honors the alarm hysteresis factor (HYST). Thus the value
|
||||
must change by at least HYST before the alarm status and severity is
|
||||
reduced.
|
||||
|
||||
=item 4. Check severity and write the new value. See Invalid Alarm
|
||||
Output Action for details on how invalid alarms affect output records.
|
||||
|
||||
=item 5. If PACT has been changed to TRUE, the device support write
|
||||
output routine has started but has not completed writing the new value.
|
||||
In this case, the processing routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 6. Check to see if monitors should be invoked:
|
||||
|
||||
=over
|
||||
|
||||
=item * Alarm monitors are invoked if the alarm status or severity has
|
||||
changed.
|
||||
|
||||
=item * Archive and value change monitors are invoked if ADEL and MDEL
|
||||
conditions are met.
|
||||
|
||||
=item * Monitors for RVAL and for RBV are checked whenever other
|
||||
monitors are invoked.
|
||||
|
||||
=item * NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=item 7. Scan forward link if necessary, set PACT and INIT FALSE, and
|
||||
return.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Device Support
|
||||
|
||||
=head3 Fields Of Interest To Device Support
|
||||
|
||||
Each analog output record must have an associated set of device support
|
||||
routines. The primary responsibility of the device support routines is
|
||||
to output a new value whenever write_ao is called. The device support
|
||||
routines are primarily interested in the following fields:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
PACT E<mdash> Process Active, used to indicate asynchronous completion
|
||||
|
||||
=item *
|
||||
DPVT E<mdash> Device Private, reserved for device support to use
|
||||
|
||||
=item *
|
||||
OUT E<mdash> Output Link, provides addressing information
|
||||
|
||||
=item *
|
||||
EGUF E<mdash> Engineering Units Full
|
||||
|
||||
=item *
|
||||
EGUL E<mdash> Engineering Units Low
|
||||
|
||||
=item *
|
||||
ESLO E<mdash> Engineering Unit Slope
|
||||
|
||||
=item *
|
||||
EOFF E<mdash> Engineering Unit Offset
|
||||
|
||||
=item *
|
||||
OVAL E<mdash> Output Value, in Engineering units
|
||||
|
||||
=item *
|
||||
RVAL E<mdash> Raw Output Value, after conversion
|
||||
|
||||
=back
|
||||
|
||||
=head3 Device Support routines
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=over
|
||||
|
||||
=item C<long report(int level)>
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=item C<long init(int after)>
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=item C<long init_record(aoRecord *prec)>
|
||||
|
||||
This optional routine is called by the record initialization code for each ao
|
||||
record instance that has its DTYP field set to use this device support.
|
||||
It is normally used to check that the OUT address has the expected type and
|
||||
points to a valid device; to allocate any record-specific buffer space and
|
||||
other memory; and to connect any communication channels needed for the
|
||||
C<write_ao()> routine to work properly.
|
||||
|
||||
If the record type's unit conversion features are used, the C<init_record()>
|
||||
routine should calculate appropriate values for the ESLO and EOFF fields from
|
||||
the EGUL and EGUF field values.
|
||||
This calculation only has to be performed if the record's LINR field is set to
|
||||
C<LINEAR>, but it is not necessary to check that condition first.
|
||||
This same calculation takes place in the C<special_linconv()> routine, so the
|
||||
implementation can usually just call that routine to perform the task.
|
||||
|
||||
If the the last output value can be read back from the hardware, this routine
|
||||
should also fetch that value and put it into the record's RVAL or VAL field. The
|
||||
return value should be zero if the RVAL field has been set, or 2 if either the
|
||||
VAL field has been set or if the last output value cannot be retrieved.
|
||||
|
||||
=item C<long get_ioint_info(int cmd, aoRecord *prec, IOSCANPVT *piosl)>
|
||||
|
||||
This optional routine is called whenever the record's SCAN field is being
|
||||
changed to or from the value C<I/O Intr> to find out which I/O Interrupt Scan
|
||||
list the record should be added to or deleted from.
|
||||
If this routine is not provided, it will not be possible to set the SCAN field
|
||||
to the value C<I/O Intr> at all.
|
||||
|
||||
The C<cmd> parameter is zero when the record is being added to the scan list,
|
||||
and one when it is being removed from the list.
|
||||
The routine must determine which interrupt source the record should be connected
|
||||
to, which it indicates by the scan list that it points the location at C<*piosl>
|
||||
to before returning.
|
||||
It can prevent the SCAN field from being changed at all by returning a non-zero
|
||||
value to its caller.
|
||||
|
||||
In most cases the device support will create the I/O Interrupt Scan lists that
|
||||
it returns for itself, by calling C<void scanIoInit(IOSCANPVT *piosl)> once for
|
||||
each separate interrupt source.
|
||||
That API allocates memory and inializes the list, then passes back a pointer to
|
||||
the new list in the location at C<*piosl>.
|
||||
When the device support receives notification that the interrupt has occurred,
|
||||
it announces that to the IOC by calling C<void scanIoRequest(IOSCANPVT iosl)>
|
||||
which will arrange for the appropriate records to be processed in a suitable
|
||||
thread.
|
||||
The C<scanIoRequest()> routine is safe to call from an interrupt service routine
|
||||
on embedded architectures (vxWorks and RTEMS).
|
||||
|
||||
=item C<long write_ao(aoRecord *prec)>
|
||||
|
||||
This essential routine is called whenever the record has a new output value to
|
||||
send to the device. It is responsible for performing the write operation, using
|
||||
either the engineering units value found in the record's OVAL field, or the raw
|
||||
value from the record's RVAL field if the record type's unit conversion
|
||||
facilities are used. A return value of zero indicates success, any other value
|
||||
indicates that an error occurred.
|
||||
|
||||
This routine must not block (busy-wait) if the device takes more than a few
|
||||
microseconds to accept the new value. In that case the routine must use
|
||||
asynchronous completion to tell the record when the write operation eventually
|
||||
completes. It signals that this is an asynchronous operation by setting the
|
||||
record's PACT field to TRUE before it returns, having arranged for the record's
|
||||
C<process()> routine to be called later once the write operation is over. When
|
||||
that happens the C<write_ao()> routine will be called again with PACT still set
|
||||
to TRUE; it should then set it to FALSE to indicate the write has completed, and
|
||||
return.
|
||||
|
||||
=item C<long special_linconv(aoRecord *prec, int after)>
|
||||
|
||||
This optional routine should be provided if the record type's unit conversion
|
||||
features are used by the device support's C<write_ao()> routine utilizing the
|
||||
RVAL field rather than OVAL or VAL.
|
||||
It is called by the record code whenever any of the the fields LINR, EGUL or
|
||||
EGUF are modified and LINR has the value C<LINEAR>.
|
||||
The routine must calculate and set the fields EOFF and ESLO appropriately based
|
||||
on the new values of EGUL and EGUF.
|
||||
|
||||
These calculations can be expressed in terms of the minimum and maximum raw
|
||||
values that the C<write_ao()> routine can accept in the RVAL field.
|
||||
When VAL is EGUF the RVAL field will be set to I<RVAL_max>, and when VAL is
|
||||
EGUL the RVAL field will become I<RVAL_min>.
|
||||
The fomulae to use are:
|
||||
|
||||
=over
|
||||
|
||||
EOFF = (I<RVAL_max> * EGUL E<minus> I<RVAL_min> * EGUF) /
|
||||
(I<RVAL_max> E<minus> I<RVAL_min>)
|
||||
|
||||
ESLO = (EGUF E<minus> EGUL) / (I<RVAL_max> E<minus> I<RVAL_min>)
|
||||
|
||||
=back
|
||||
|
||||
Note that the record support sets EOFF to EGUL before calling this routine,
|
||||
which is a very common case (I<RVAL_min> is zero).
|
||||
|
||||
=back
|
||||
|
||||
=head2 Device Support For Soft Records
|
||||
|
||||
Two soft device support modules Soft Channel and Raw Soft Channel are
|
||||
provided for output records not related to actual hardware devices. The
|
||||
OUT link type must be either a CONSTANT, DB_LINK, or CA_LINK.
|
||||
|
||||
=head3 Soft Channel
|
||||
|
||||
This module writes the current value of OVAL.
|
||||
|
||||
If the OUT link type is PV_LINK, then dbCaAddInlink is called by
|
||||
init_record. init_record always returns a value of 2, which means that
|
||||
no conversion will ever be attempted.
|
||||
|
||||
write_ao calls recGblPutLinkValue to write the current value of VAL.
|
||||
See Soft Output for details.
|
||||
|
||||
=head3 Raw Soft Channel
|
||||
|
||||
This module is like the previous except that it writes the current
|
||||
value of RVAL.
|
||||
|
||||
=cut
|
||||
@@ -3,10 +3,36 @@
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE Versions 3.13.7
|
||||
# and higher are distributed subject to a Software License Agreement found
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Compress Record (compress)
|
||||
|
||||
...
|
||||
|
||||
=head2 Record-specific Menus
|
||||
|
||||
=head3 Menu compressALG
|
||||
|
||||
The ALG field which uses this menu controls the compression algorithm used.
|
||||
|
||||
...
|
||||
|
||||
=menu compressALG
|
||||
|
||||
...
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype compress
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
menu(compressALG) {
|
||||
choice(compressALG_N_to_1_Low_Value,"N to 1 Low Value")
|
||||
choice(compressALG_N_to_1_High_Value,"N to 1 High Value")
|
||||
@@ -16,6 +42,11 @@ menu(compressALG) {
|
||||
choice(compressALG_N_to_1_Median,"N to 1 Median")
|
||||
}
|
||||
recordtype(compress) {
|
||||
|
||||
=fields VAL
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
@@ -23,6 +54,9 @@ recordtype(compress) {
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
@@ -20,6 +20,9 @@ recordtype(histogram) {
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
extra("void * val")
|
||||
#=type ULONG[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(NELM,DBF_USHORT) {
|
||||
prompt("Num of Array Elements")
|
||||
|
||||
@@ -15,6 +15,8 @@ recordtype(mbbo) {
|
||||
special(SPC_DBADDR)
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(DOL,DBF_INLINK) {
|
||||
prompt("Desired Output Loc")
|
||||
|
||||
@@ -15,6 +15,9 @@ recordtype(subArray) {
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type Set by FTVL
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
|
||||
@@ -6,11 +6,43 @@
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Waveform Record (waveform)
|
||||
|
||||
...
|
||||
|
||||
=head2 Record-specific Menus
|
||||
|
||||
=head3 Menu waveformPOST
|
||||
|
||||
The MPST and APST fields use this menu to determine when to post new value
|
||||
and archive monitors respectively.
|
||||
|
||||
=menu waveformPOST
|
||||
|
||||
...
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype waveform
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
menu(waveformPOST) {
|
||||
choice(waveformPOST_Always,"Always")
|
||||
choice(waveformPOST_OnChange,"On Change")
|
||||
choice(waveformPOST_Always,"Always")
|
||||
choice(waveformPOST_OnChange,"On Change")
|
||||
}
|
||||
|
||||
recordtype(waveform) {
|
||||
|
||||
=fields VAL, FTVL, MPST, APST
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
@@ -18,6 +50,9 @@ recordtype(waveform) {
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type Set by FTVL
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(RARM,DBF_SHORT) {
|
||||
prompt("Rearm the waveform")
|
||||
@@ -8,7 +8,9 @@
|
||||
# This is a Makefile fragment, see src/ioc/Makefile.
|
||||
|
||||
softIoc.dbd$(DEP): $(COMMON_DIR)/stdRecords.dbd
|
||||
softIoc.dbd$(DEP): $(COMMON_DIR)/filters.dbd
|
||||
$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/stdRecords.dbd
|
||||
$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/filters.dbd
|
||||
$(COMMON_DIR)/softIoc.dbd: $(STDDIR)/softIoc/Makefile
|
||||
|
||||
softMain$(DEP): epicsInstallDir.h
|
||||
|
||||
@@ -21,7 +21,9 @@ sub new {
|
||||
'DBD::Menu' => {},
|
||||
'DBD::Recordtype' => {},
|
||||
'DBD::Registrar' => {},
|
||||
'DBD::Variable' => {}
|
||||
'DBD::Variable' => {},
|
||||
'COMMENTS' => [],
|
||||
'POD' => []
|
||||
};
|
||||
bless $this, $class;
|
||||
return $this;
|
||||
@@ -43,6 +45,24 @@ sub add {
|
||||
}
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my $this = shift;
|
||||
push @{$this->{COMMENTS}}, @_;
|
||||
}
|
||||
|
||||
sub comments {
|
||||
return @{shift->{COMMENTS}};
|
||||
}
|
||||
|
||||
sub add_pod {
|
||||
my $this = shift;
|
||||
push @{$this->{POD}}, @_;
|
||||
}
|
||||
|
||||
sub pod {
|
||||
return @{shift->{POD}};
|
||||
}
|
||||
|
||||
sub breaktables {
|
||||
return shift->{'DBD::Breaktable'};
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ sub escapeCstring {
|
||||
}
|
||||
|
||||
|
||||
# Base class routines for the DBD component objects
|
||||
# Base methods for the DBD component objects
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
@@ -128,6 +128,17 @@ sub what {
|
||||
return shift->{WHAT};
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my $this = shift;
|
||||
confess "add_comment() not supported by $this->{WHAT} ($this)\n",
|
||||
"Context: ", join(' in ', @context), "\n";
|
||||
}
|
||||
|
||||
sub add_pod {
|
||||
my $this = shift;
|
||||
warnContext "Warning: Pod text inside $this->{WHAT} will be ignored";
|
||||
}
|
||||
|
||||
sub equals {
|
||||
my ($a, $b) = @_;
|
||||
return $a->{NAME} eq $b->{NAME}
|
||||
|
||||
@@ -8,6 +8,7 @@ sub init {
|
||||
my ($this, $name) = @_;
|
||||
$this->SUPER::init($name, "breakpoint table");
|
||||
$this->{POINT_LIST} = [];
|
||||
$this->{COMMENTS} = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -31,6 +32,15 @@ sub point {
|
||||
return $this->{POINT_LIST}[$idx];
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my $this = shift;
|
||||
push @{$this->{COMMENTS}}, @_;
|
||||
}
|
||||
|
||||
sub comments {
|
||||
return @{shift->{COMMENTS}};
|
||||
}
|
||||
|
||||
sub equals {
|
||||
my ($a, $b) = @_;
|
||||
return $a->SUPER::equals($b)
|
||||
|
||||
@@ -7,6 +7,7 @@ sub init {
|
||||
$this->SUPER::init($name, "menu");
|
||||
$this->{CHOICE_LIST} = [];
|
||||
$this->{CHOICE_INDEX} = {};
|
||||
$this->{COMMENTS} = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -39,6 +40,15 @@ sub legal_choice {
|
||||
return exists $this->{CHOICE_INDEX}->{$value};
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my $this = shift;
|
||||
push @{$this->{COMMENTS}}, @_;
|
||||
}
|
||||
|
||||
sub comments {
|
||||
return @{shift->{COMMENTS}};
|
||||
}
|
||||
|
||||
sub equals {
|
||||
my ($a, $b) = @_;
|
||||
return $a->SUPER::equals($b)
|
||||
|
||||
@@ -19,10 +19,9 @@ use DBD::Variable;
|
||||
our $debug=0;
|
||||
|
||||
sub ParseDBD {
|
||||
my $dbd = shift;
|
||||
$_ = shift;
|
||||
(my $dbd, $_) = @_;
|
||||
while (1) {
|
||||
parseCommon();
|
||||
parseCommon($dbd);
|
||||
if (m/\G menu \s* \( \s* $RXstr \s* \) \s* \{/oxgc) {
|
||||
print "Menu: $1\n" if $debug;
|
||||
parse_menu($dbd, $1);
|
||||
@@ -59,12 +58,12 @@ sub ParseDBD {
|
||||
\s* $RXstr \s* , \s*$RXstr \s* \)/oxgc) {
|
||||
print "Device: $1, $2, $3, $4\n" if $debug;
|
||||
my $rtyp = $dbd->recordtype($1);
|
||||
if (!defined $rtyp) {
|
||||
$rtyp = DBD::Recordtype->new($1);
|
||||
warn "Device using undefined record type '$1', place-holder created\n";
|
||||
$dbd->add($rtyp);
|
||||
if (!defined $rtyp) {
|
||||
$rtyp = DBD::Recordtype->new($1);
|
||||
warn "Device using undefined record type '$1', place-holder created\n";
|
||||
$dbd->add($rtyp);
|
||||
}
|
||||
$rtyp->add_device(DBD::Device->new($2, $3, $4));
|
||||
$rtyp->add_device(DBD::Device->new($2, $3, $4));
|
||||
} else {
|
||||
last unless m/\G (.*) $/moxgc;
|
||||
dieContext("Syntax error in '$1'");
|
||||
@@ -73,21 +72,27 @@ sub ParseDBD {
|
||||
}
|
||||
|
||||
sub parseCommon {
|
||||
my ($obj) = @_;
|
||||
while (1) {
|
||||
# Skip leading whitespace
|
||||
m/\G \s* /oxgc;
|
||||
|
||||
if (m/\G \# /oxgc) {
|
||||
if (m/\G \#!BEGIN\{ ( [^}]* ) \}!\#\# \n/oxgc) {
|
||||
# Extract POD
|
||||
if (m/\G ( = [a-zA-Z] .* ) \n/oxgc) {
|
||||
$obj->add_pod($1, &parsePod);
|
||||
}
|
||||
elsif (m/\G \# /oxgc) {
|
||||
if (m/\G \# ! BEGIN \{ ( [^}]* ) \} ! \# \# \n/oxgc) {
|
||||
print "File-Begin: $1\n" if $debug;
|
||||
pushContext("file '$1'");
|
||||
}
|
||||
elsif (m/\G \#!END\{ ( [^}]* ) \}!\#\# \n?/oxgc) {
|
||||
elsif (m/\G \# ! END \{ ( [^}]* ) \} ! \# \# \n?/oxgc) {
|
||||
print "File-End: $1\n" if $debug;
|
||||
popContext("file '$1'");
|
||||
}
|
||||
else {
|
||||
m/\G (.*) \n/oxgc;
|
||||
$obj->add_comment($1);
|
||||
print "Comment: $1\n" if $debug;
|
||||
}
|
||||
} else {
|
||||
@@ -96,12 +101,29 @@ sub parseCommon {
|
||||
}
|
||||
}
|
||||
|
||||
sub parsePod {
|
||||
pushContext("Pod markup");
|
||||
my @pod;
|
||||
while (1) {
|
||||
if (m/\G ( =cut .* ) \n?/oxgc) {
|
||||
popContext("Pod markup");
|
||||
return @pod;
|
||||
}
|
||||
elsif (m/\G ( .* ) $/oxgc) {
|
||||
dieContext("Unexpected end of input file, Pod block not closed");
|
||||
}
|
||||
elsif (m/\G ( .* ) \n/oxgc) {
|
||||
push @pod, $1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_menu {
|
||||
my ($dbd, $name) = @_;
|
||||
pushContext("menu($name)");
|
||||
my $menu = DBD::Menu->new($name);
|
||||
while(1) {
|
||||
parseCommon();
|
||||
parseCommon($menu);
|
||||
if (m/\G choice \s* \( \s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) {
|
||||
print " Menu-Choice: $1, $2\n" if $debug;
|
||||
$menu->add_choice($1, $2);
|
||||
@@ -123,7 +145,7 @@ sub parse_breaktable {
|
||||
pushContext("breaktable($name)");
|
||||
my $bt = DBD::Breaktable->new($name);
|
||||
while(1) {
|
||||
parseCommon();
|
||||
parseCommon($bt);
|
||||
if (m/\G point\s* \(\s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) {
|
||||
print " Breaktable-Point: $1, $2\n" if $debug;
|
||||
$bt->add_point($1, $2);
|
||||
@@ -149,7 +171,7 @@ sub parse_recordtype {
|
||||
pushContext("recordtype($name)");
|
||||
my $rtyp = DBD::Recordtype->new($name);
|
||||
while(1) {
|
||||
parseCommon();
|
||||
parseCommon($rtyp);
|
||||
if (m/\G field \s* \( \s* $RXstr \s* , \s* $RXstr \s* \) \s* \{/oxgc) {
|
||||
print " Recordtype-Field: $1, $2\n" if $debug;
|
||||
parse_field($rtyp, $1, $2);
|
||||
@@ -175,7 +197,7 @@ sub parse_field {
|
||||
my $fld = DBD::Recfield->new($name, $field_type);
|
||||
pushContext("field($name, $field_type)");
|
||||
while(1) {
|
||||
parseCommon();
|
||||
parseCommon($fld);
|
||||
if (m/\G (\w+) \s* \( \s* $RXstr \s* \)/oxgc) {
|
||||
print " Field-Attribute: $1, $2\n" if $debug;
|
||||
$fld->add_attribute($1, $2);
|
||||
|
||||
@@ -56,6 +56,7 @@ sub init {
|
||||
sort keys %field_types) unless exists $field_types{$type};
|
||||
$this->{DBF_TYPE} = $type;
|
||||
$this->{ATTR_INDEX} = {};
|
||||
$this->{COMMENTS} = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -109,6 +110,16 @@ sub check_valid {
|
||||
if (defined($default) and !$this->legal_value($default));
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my $this = shift;
|
||||
push @{$this->{COMMENTS}}, @_;
|
||||
}
|
||||
|
||||
sub comments {
|
||||
return @{shift->{COMMENTS}};
|
||||
}
|
||||
|
||||
|
||||
# The C structure member name is usually the field name converted to
|
||||
# lower-case. However if that is a reserved word, use the original.
|
||||
sub C_name {
|
||||
|
||||
@@ -12,6 +12,8 @@ sub init {
|
||||
$this->{DEVICE_LIST} = [];
|
||||
$this->{DEVICE_INDEX} = {};
|
||||
$this->{CDEFS} = [];
|
||||
$this->{COMMENTS} = [];
|
||||
$this->{POD} = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -69,6 +71,15 @@ sub device {
|
||||
return $this->{DEVICE_INDEX}->{$choice};
|
||||
}
|
||||
|
||||
sub add_comment {
|
||||
my ($this, $comment) = @_;
|
||||
push @{$this->{COMMENTS}}, $comment;
|
||||
}
|
||||
|
||||
sub comments {
|
||||
return @{shift->{COMMENTS}};
|
||||
}
|
||||
|
||||
sub add_cdef {
|
||||
my ($this, $cdef) = @_;
|
||||
push @{$this->{CDEFS}}, $cdef;
|
||||
@@ -82,6 +93,15 @@ sub toCdefs {
|
||||
return join("\n", shift->cdefs) . "\n\n";
|
||||
}
|
||||
|
||||
sub add_pod {
|
||||
my $this = shift;
|
||||
push @{$this->{POD}}, @_;
|
||||
}
|
||||
|
||||
sub pod {
|
||||
return @{shift->{POD}};
|
||||
}
|
||||
|
||||
sub equals {
|
||||
my ($new, $known) = @_;
|
||||
return 0 if ! $known->fields;
|
||||
|
||||
@@ -49,8 +49,11 @@ PERL_SCRIPTS += dbdToMenuH.pl
|
||||
PERL_SCRIPTS += dbdToRecordtypeH.pl
|
||||
PERL_SCRIPTS += dbdExpand.pl
|
||||
PERL_SCRIPTS += dbdToHtml.pl
|
||||
PERL_SCRIPTS += podToHtml.pl
|
||||
PERL_SCRIPTS += registerRecordDeviceDriver.pl
|
||||
|
||||
HTMLS = style.css
|
||||
|
||||
# Build Package Config Files
|
||||
|
||||
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
@@ -9,6 +8,8 @@
|
||||
|
||||
# $Id$
|
||||
|
||||
use strict;
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
@@ -17,20 +18,35 @@ use DBD::Parser;
|
||||
use EPICS::Getopts;
|
||||
use EPICS::macLib;
|
||||
use EPICS::Readfile;
|
||||
use HTML::Entities;
|
||||
|
||||
BEGIN {
|
||||
$::XHTML = eval "require Pod::Simple::XHTML; 1";
|
||||
if (!$::XHTML) {
|
||||
require Pod::Simple::HTML;
|
||||
}
|
||||
}
|
||||
|
||||
my $tool = 'dbdToHtml';
|
||||
getopts('DI@o:') or
|
||||
die "Usage: $tool [-D] [-I dir] [-o xRecord.html] xRecord.dbd\n";
|
||||
|
||||
my @path = map { split /[:;]/ } @opt_I;
|
||||
use vars qw($opt_D @opt_I $opt_o);
|
||||
getopts('DI@o:') or
|
||||
die "Usage: $tool [-D] [-I dir] [-o file.html] file.dbd.pod\n";
|
||||
|
||||
my $dbd = DBD->new();
|
||||
|
||||
my $infile = shift @ARGV;
|
||||
$infile =~ m/\.dbd$/ or
|
||||
die "$tool: Input file '$infile' must have '.dbd' extension\n";
|
||||
$infile =~ m/\.dbd.pod$/ or
|
||||
die "$tool: Input file '$infile' must have '.dbd.pod' extension\n";
|
||||
|
||||
&ParseDBD($dbd, &Readfile($infile, 0, \@opt_I));
|
||||
|
||||
if (!$opt_o) {
|
||||
($opt_o = $infile) =~ s/\.dbd\.pod$/.html/;
|
||||
$opt_o =~ s/^.*\///;
|
||||
$opt_o =~ s/dbCommonRecord/dbCommon/;
|
||||
}
|
||||
|
||||
if ($opt_D) { # Output dependencies only
|
||||
my %filecount;
|
||||
my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles;
|
||||
@@ -39,214 +55,175 @@ if ($opt_D) { # Output dependencies only
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $out;
|
||||
if ($opt_o) {
|
||||
$out = $opt_o;
|
||||
} else {
|
||||
($out = $infile) =~ s/\.dbd$/.html/;
|
||||
$out =~ s/^.*\///;
|
||||
$out =~ s/dbCommonRecord/dbCommon/;
|
||||
}
|
||||
open $out, '>', $opt_o or die "Can't create $opt_o: $!\n";
|
||||
(my $title = $opt_o) =~ s/\.html$//;
|
||||
|
||||
print $out "<h1>$infile</h1>\n";
|
||||
open my $out, '>', $opt_o or
|
||||
die "Can't create $opt_o: $!\n";
|
||||
|
||||
my $rtypes = $dbd->recordtypes;
|
||||
|
||||
my ($rn, $rtyp) = each %{$rtypes};
|
||||
print $out "<h2>Record Name $rn</h2>\n";
|
||||
|
||||
my @fields = $rtyp->fields;
|
||||
|
||||
#create a Hash to store the table of field information for each GUI type
|
||||
%dbdTables = (
|
||||
"GUI_COMMON" => "",
|
||||
"GUI_COMMON" => "",
|
||||
"GUI_ALARMS" => "",
|
||||
"GUI_BITS1" => "",
|
||||
"GUI_BITS2" => "",
|
||||
"GUI_CALC" => "",
|
||||
"GUI_CLOCK" => "",
|
||||
"GUI_COMPRESS" => "",
|
||||
"GUI_CONVERT" => "",
|
||||
"GUI_DISPLAY" => "",
|
||||
"GUI_HIST" => "",
|
||||
"GUI_INPUTS" => "",
|
||||
"GUI_LINKS" => "",
|
||||
"GUI_MBB" => "",
|
||||
"GUI_MOTOR" => "",
|
||||
"GUI_OUTPUT" => "",
|
||||
"GUI_PID" => "",
|
||||
"GUI_PULSE" => "",
|
||||
"GUI_SELECT" => "",
|
||||
"GUI_SEQ1" => "",
|
||||
"GUI_SEQ2" => "",
|
||||
"GUI_SEQ3" => "",
|
||||
"GUI_SUB" => "",
|
||||
"GUI_TIMER" => "",
|
||||
"GUI_WAVE" => "",
|
||||
"GUI_SCAN" => "",
|
||||
"GUI_NONE" => ""
|
||||
);
|
||||
|
||||
|
||||
#Loop over all of the fields. Build a string that contains the table body
|
||||
#for each of the GUI Types based on which fields go with which GUI type.
|
||||
foreach $fVal (@fields) {
|
||||
my $pg = $fVal->attribute('promptgroup');
|
||||
while ( ($typ1, $content) = each %dbdTables) {
|
||||
if ( $pg eq $typ1 or ($pg eq "" and $typ1 eq "GUI_NONE")) {
|
||||
buildTableRow($fVal, $dbdTables{$typ1} );
|
||||
# Parse the Pod text from the root DBD object
|
||||
my $pod = join "\n", '=for html <div class="pod">', '',
|
||||
map {
|
||||
# Handle a 'recordtype' Pod directive
|
||||
if (m/^ =recordtype \s+ (.*)/x) {
|
||||
my $rn = $1;
|
||||
my $rtyp = $dbd->recordtype($rn);
|
||||
die "Unknown recordtype '$rn' in $infile POD directive\n"
|
||||
unless $rtyp;
|
||||
rtypeToPod($rtyp, $dbd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Write out each table
|
||||
while ( ($typ2, $content) = each %dbdTables) {
|
||||
printHtmlTable($typ2, $content);
|
||||
}
|
||||
|
||||
|
||||
#add a field to a table body. The specified field and table body are passed
|
||||
#in as parameters
|
||||
sub buildTableRow {
|
||||
my ( $fld, $outStr) = @_;
|
||||
$longDesc = " ";
|
||||
%htmlCellFmt = (
|
||||
rowStart => "<tr><td rowspan = \"2\">",
|
||||
nextCell => "</td><td>",
|
||||
endRow => "</td></tr>",
|
||||
nextRow => "<tr><td colspan = \"7\" align=left>"
|
||||
);
|
||||
my %cellFmt = %htmlCellFmt;
|
||||
my $rowStart = $cellFmt{rowStart};
|
||||
my $nextCell = $cellFmt{nextCell};
|
||||
my $endRow = $cellFmt{endRow};
|
||||
my $nextRow = $cellFmt{nextRow};
|
||||
$outStr = $outStr . $rowStart;
|
||||
$outStr = $outStr . $fld->name;
|
||||
$outStr = $outStr . $nextCell;
|
||||
$outStr = $outStr . $fld->attribute('prompt');
|
||||
$outStr = $outStr . $nextCell;
|
||||
my $recType = $fld->dbf_type;
|
||||
$typStr = $recType;
|
||||
if ($recType eq "DBF_STRING") {
|
||||
$typStr = $recType . " [" . $fld->attribute('size') . "]";
|
||||
}
|
||||
|
||||
$outStr = $outStr . $typStr;
|
||||
$outStr = $outStr . $nextCell;
|
||||
$outStr = $outStr . design($fld);
|
||||
$outStr = $outStr . $nextCell;
|
||||
my $initial = $fld->attribute('initial');
|
||||
if ( $initial eq '' ) {$initial = " ";}
|
||||
$outStr = $outStr . $initial;
|
||||
$outStr = $outStr . $nextCell;
|
||||
$outStr = $outStr . readable($fld);
|
||||
$outStr = $outStr . $nextCell;
|
||||
$outStr = $outStr . writable($fld);
|
||||
$outStr = $outStr . $nextCell;
|
||||
$outStr = $outStr . processPassive($fld);
|
||||
$outStr = $outStr . $endRow;
|
||||
$outStr = $outStr . "\n";
|
||||
$outStr = $outStr . $nextRow;
|
||||
$outStr = $outStr . $longDesc;
|
||||
$outStr = $outStr . $endRow;
|
||||
$outStr = $outStr . "\n";
|
||||
$_[1] = $outStr;
|
||||
}
|
||||
|
||||
#Check if the prompt group is defined so that this can be used by clients
|
||||
sub design {
|
||||
my $fld = $_[0];
|
||||
my $pg = $fld->attribute('promptgroup');
|
||||
if ( $pg eq '' ) {
|
||||
my $result = 'No';
|
||||
}
|
||||
else {
|
||||
my $result = 'Yes';
|
||||
}
|
||||
}
|
||||
|
||||
#Check if this field is readable by clients
|
||||
sub readable {
|
||||
my $fld = $_[0];
|
||||
if ( $fld->attribute('special') eq "SPC_DBADDR") {
|
||||
$return = "Probably";
|
||||
}
|
||||
else{
|
||||
if ( $fld->dbf_type eq "DBF_NOACCESS" ) {
|
||||
$return = "No";
|
||||
# Handle a 'menu' Pod directive
|
||||
elsif (m/^ =menu \s+ (.*)/x) {
|
||||
my $mn = $1;
|
||||
my $menu = $dbd->menu($mn);
|
||||
die "Unknown menu '$mn' in $infile POD directive\n"
|
||||
unless $menu;
|
||||
menuToPod($menu);
|
||||
}
|
||||
elsif (m/^ =title \s+ (.*)/x) {
|
||||
$title = $1;
|
||||
"=head1 $title";
|
||||
}
|
||||
else {
|
||||
$return = "Yes"
|
||||
$_;
|
||||
}
|
||||
}
|
||||
} $dbd->pod,
|
||||
'=for html </div>', '';
|
||||
|
||||
my $podHtml;
|
||||
|
||||
if ($::XHTML) {
|
||||
$podHtml = Pod::Simple::XHTML->new();
|
||||
$podHtml->html_doctype(<< '__END_DOCTYPE');
|
||||
<?xml version='1.0' encoding='iso-8859-1'?>
|
||||
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
|
||||
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
|
||||
__END_DOCTYPE
|
||||
} else { # Fall back to HTML
|
||||
$podHtml = Pod::Simple::HTML->new();
|
||||
}
|
||||
|
||||
#Check if this field is writable by clients
|
||||
sub writable {
|
||||
my $fld = $_[0];
|
||||
my $spec = $fld->attribute('special');
|
||||
if ( $spec eq "SPC_NOMOD" ) {
|
||||
$return = "No";
|
||||
}
|
||||
else {
|
||||
if ( $spec ne "SPC_DBADDR") {
|
||||
if ( $fld->dbf_type eq "DBF_NOACCESS" ) {
|
||||
$return = "No";
|
||||
}
|
||||
else {
|
||||
$return = "Yes";
|
||||
}
|
||||
$podHtml->html_css('style.css');
|
||||
$podHtml->force_title(encode_entities($title));
|
||||
$podHtml->perldoc_url_prefix('');
|
||||
$podHtml->perldoc_url_postfix('.html');
|
||||
$podHtml->output_fh($out);
|
||||
$podHtml->parse_string_document($pod);
|
||||
close $out;
|
||||
|
||||
|
||||
sub menuToPod {
|
||||
my ($menu) = @_;
|
||||
my $index = 0;
|
||||
return '=begin html', '', '<blockquote><table border="1"><tr>',
|
||||
'<th>Index</th><th>Identifier</th><th>Choice String</th></tr>',
|
||||
map({choiceTableRow($_, $index++)} $menu->choices),
|
||||
'</table></blockquote>', '', '=end html';
|
||||
}
|
||||
|
||||
sub choiceTableRow {
|
||||
my ($ch, $index) = @_;
|
||||
my ($id, $name) = @{$ch};
|
||||
return '<tr>',
|
||||
"<td class='cell DBD_Menu index'>$index</td>",
|
||||
"<td class='cell DBD_Menu identifier'>$id</td>",
|
||||
"<td class='cell DBD_Menu choice'>$name</td>",
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
sub rtypeToPod {
|
||||
my ($rtyp, $dbd) = @_;
|
||||
return map {
|
||||
# Handle a 'fields' Pod directive
|
||||
if (m/^ =fields \s+ (.*)/x) {
|
||||
my @names = split /\s*,\s*/, $1;
|
||||
# Look up the named fields
|
||||
my @fields = map {
|
||||
my $field = $rtyp->field($_);
|
||||
die "Unknown field name '$_' in $infile POD\n"
|
||||
unless $field;
|
||||
$field;
|
||||
} @names;
|
||||
# Generate Pod for the table
|
||||
'=begin html', '', '<blockquote><table border="1"><tr>',
|
||||
'<th>Field</th><th>Summary</th><th>Type</th><th>DCT</th>',
|
||||
'<th>Default</th><th>Read</th><th>Write</th><th>CA PP</th>',
|
||||
'</tr>',
|
||||
map({fieldTableRow($_, $dbd)} @fields),
|
||||
'</table></blockquote>', '', '=end html';
|
||||
}
|
||||
# Handle a 'menu' Pod directive
|
||||
elsif (m/^ =menu \s+ (.*)/x) {
|
||||
my $mn = $1;
|
||||
my $menu = $dbd->menu($mn);
|
||||
die "Unknown menu '$mn' in $infile POD directive\n"
|
||||
unless $menu;
|
||||
menuToPod($menu);
|
||||
}
|
||||
else {
|
||||
$return = "Maybe";
|
||||
# Raw text line
|
||||
$_;
|
||||
}
|
||||
} $rtyp->pod;
|
||||
}
|
||||
|
||||
sub fieldTableRow {
|
||||
my ($fld, $dbd) = @_;
|
||||
my $html = '<tr><td class="cell">';
|
||||
$html .= $fld->name;
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->attribute('prompt');
|
||||
$html .= '</td><td class="cell">';
|
||||
my $type = $fld->public_type;
|
||||
$html .= $type;
|
||||
$html .= ' [' . $fld->attribute('size') . ']'
|
||||
if $type eq 'STRING';
|
||||
if ($type eq 'MENU') {
|
||||
my $mn = $fld->attribute('menu');
|
||||
my $menu = $dbd->menu($mn);
|
||||
my $url = $menu ? "#Menu_$mn" : "${mn}.html";
|
||||
$html .= " (<a href='$url'>$mn</a>)";
|
||||
}
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->attribute('promptgroup') ? 'Yes' : 'No';
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->attribute('initial') || ' ';
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->readable;
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->writable;
|
||||
$html .= '</td><td class="cell">';
|
||||
$html .= $fld->attribute('pp') eq 'TRUE' ? 'Yes' : 'No';
|
||||
$html .= "</td></tr>\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
#Check to see if the field is process passive on caput
|
||||
sub processPassive {
|
||||
my $fld = $_[0];
|
||||
$pp = $fld->attribute('pp');
|
||||
if ( $pp eq "YES" or $pp eq "TRUE" ) {
|
||||
$result = "Yes";
|
||||
}
|
||||
elsif ( $PP eq "NO" or $pp eq "FALSE" or $pp eq "" ) {
|
||||
$result = "No";
|
||||
}
|
||||
# Native type presented to dbAccess users
|
||||
sub DBD::Recfield::public_type {
|
||||
my $fld = shift;
|
||||
m/^=type (.+)$/i && return $1 for $fld->comments;
|
||||
my $type = $fld->dbf_type;
|
||||
$type =~ s/^DBF_//;
|
||||
return $type;
|
||||
}
|
||||
|
||||
#print the start row to define a table
|
||||
sub printTableStart {
|
||||
print $out "<table border =\"1\"> \n";
|
||||
print $out "<caption><em>$_[0]</em></caption>";
|
||||
print $out "<th>Field</th>\n";
|
||||
print $out "<th>Summary</th>\n";
|
||||
print $out "<th>Type</th>\n";
|
||||
print $out "<th>DCT</th>\n";
|
||||
print $out "<th>Default</th>\n";
|
||||
print $out "<th>Read</th>\n";
|
||||
print $out "<th>Write</th>\n";
|
||||
print $out "<th>caPut=PP</th></tr>\n";
|
||||
|
||||
# Check if this field is readable
|
||||
sub DBD::Recfield::readable {
|
||||
my $fld = shift;
|
||||
m/^=read (Yes|No)$/i && return $1 for $fld->comments;
|
||||
return 'Probably'
|
||||
if $fld->attribute('special') eq "SPC_DBADDR";
|
||||
return $fld->dbf_type eq 'DBF_NOACCESS' ? 'No' : 'Yes';
|
||||
}
|
||||
|
||||
#print the tail end of the table
|
||||
sub printTableEnd {
|
||||
print $out "</table>\n";
|
||||
# Check if this field is writable
|
||||
sub DBD::Recfield::writable {
|
||||
my $fld = shift;
|
||||
m/^=write (Yes|No)$/i && return $1 for $fld->comments;
|
||||
my $special = $fld->attribute('special');
|
||||
return 'No'
|
||||
if $special eq "SPC_NOMOD";
|
||||
return 'Maybe'
|
||||
if $special eq "SPC_DBADDR";
|
||||
return $fld->dbf_type eq "DBF_NOACCESS" ? 'No' : 'Yes';
|
||||
}
|
||||
|
||||
# Print the table for a GUI type. The name of the GUI type and the Table body
|
||||
# for this type are fed in as parameters
|
||||
sub printHtmlTable {
|
||||
my ($typ2, $content) = $_;
|
||||
if ( (length $_[1]) gt 0) {
|
||||
printTableStart($_[0]);
|
||||
print $out "$_[1]\n";
|
||||
printTableEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
47
src/tools/podToHtml.pl
Normal file
47
src/tools/podToHtml.pl
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env perl
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# $Id$
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Getopt::Std;
|
||||
use Pod::Simple::HTML;
|
||||
|
||||
our ($opt_o);
|
||||
|
||||
$Getopt::Std::OUTPUT_HELP_VERSION = 1;
|
||||
&HELP_MESSAGE if !getopts('o:') || @ARGV != 1;
|
||||
|
||||
my $infile = shift @ARGV;
|
||||
|
||||
if (!$opt_o) {
|
||||
($opt_o = $infile) =~ s/\. \w+ $/.html/x;
|
||||
$opt_o =~ s/^.*\///;
|
||||
}
|
||||
|
||||
open my $out, '>', $opt_o or
|
||||
die "Can't create $opt_o: $!\n";
|
||||
|
||||
my $podHtml = Pod::Simple::HTML->new();
|
||||
|
||||
$podHtml->html_css('style.css');
|
||||
$podHtml->perldoc_url_prefix('');
|
||||
$podHtml->perldoc_url_postfix('.html');
|
||||
$podHtml->set_source($infile);
|
||||
$podHtml->output_string(\my $html);
|
||||
$podHtml->run;
|
||||
|
||||
print $out $html;
|
||||
close $out;
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "Usage: podToHtml.pl [-o file.html] file.pod\n";
|
||||
exit 2;
|
||||
}
|
||||
442
src/tools/style.css
Normal file
442
src/tools/style.css
Normal file
@@ -0,0 +1,442 @@
|
||||
BODY, .logo { background: white; }
|
||||
|
||||
BODY {
|
||||
color: black;
|
||||
font-family: arial,sans-serif;
|
||||
margin: 0;
|
||||
padding: 1ex;
|
||||
}
|
||||
|
||||
TABLE {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border-width: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
IMG { border: 0; }
|
||||
FORM { margin: 0; }
|
||||
input { margin: 2px; }
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
width: 264px;
|
||||
height: 77px;
|
||||
}
|
||||
|
||||
.front .logo {
|
||||
float: none;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.front .searchbox {
|
||||
margin: 2ex auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.front .menubar {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.menubar {
|
||||
background: #006699;
|
||||
margin: 1ex 0;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.menubar A {
|
||||
padding: 0.8ex;
|
||||
font: bold 10pt Arial,Helvetica,sans-serif;
|
||||
}
|
||||
|
||||
.menubar A:link, .menubar A:visited {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menubar A:hover {
|
||||
color: #ff6600;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
A:link, A:visited {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
}
|
||||
|
||||
A[href="#POD_ERRORS"] {
|
||||
background: transparent;
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
TD {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
DIV {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
DT {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.credits TD {
|
||||
padding: 0.5ex 2ex;
|
||||
}
|
||||
|
||||
.huge {
|
||||
font-size: 32pt;
|
||||
}
|
||||
|
||||
.s {
|
||||
background: #dddddd;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.s TD, .r TD {
|
||||
padding: 0.2ex 1ex;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
TH {
|
||||
background: #bbbbbb;
|
||||
color: inherit;
|
||||
padding: 0.4ex 1ex;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
TH A:link, TH A:visited {
|
||||
background: transparent;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.box {
|
||||
border: 1px solid #006699;
|
||||
margin: 1ex 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.distfiles TD {
|
||||
padding: 0 2ex 0 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.manifest TD {
|
||||
padding: 0 1ex;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.l1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.l2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.t1, .t2, .t3, .t4, .t5 {
|
||||
background: #006699;
|
||||
color: white;
|
||||
}
|
||||
.t4 {
|
||||
padding: 0.2ex 0.4ex;
|
||||
}
|
||||
.t1, .t2, .t3 {
|
||||
padding: 0.5ex 1ex;
|
||||
}
|
||||
|
||||
/* IE does not support .box>.t1 Grrr */
|
||||
.box .t1, .box .t2, .box .t3, .box .t5 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.t1 {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.t2 {
|
||||
font-size: 1.0em;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.t3 {
|
||||
font-size: 1.0em;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.t5 {
|
||||
font-size: 0.8em;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* width: 100%; border: 0.1px solid #FFFFFF; */ /* NN4 hack */
|
||||
|
||||
.datecell {
|
||||
text-align: center;
|
||||
width: 17em;
|
||||
}
|
||||
|
||||
.cell {
|
||||
padding: 0.2ex 1ex;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.DBD_Menu.index {
|
||||
padding: 0.2ex 2ex;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.DBD_Menu.choice {
|
||||
font: 1.0em monospace;
|
||||
}
|
||||
|
||||
.label {
|
||||
background: #aaaaaa;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
padding: 0.2ex 1ex;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.categories {
|
||||
border-bottom: 3px double #006699;
|
||||
margin-bottom: 1ex;
|
||||
padding-bottom: 3ex;
|
||||
padding-top: 2ex;
|
||||
}
|
||||
|
||||
.categories TABLE {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.categories TD {
|
||||
padding: 0.5ex 1ex;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.path A {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pages {
|
||||
background: #dddddd;
|
||||
color: #006699;
|
||||
padding: 0.2ex 0.4ex;
|
||||
}
|
||||
|
||||
.path {
|
||||
background: #dddddd;
|
||||
border-bottom: 1px solid #006699;
|
||||
color: #006699;
|
||||
/* font-size: 1.4em;*/
|
||||
margin: 1ex 0;
|
||||
padding: 0.5ex 1ex;
|
||||
}
|
||||
|
||||
.menubar TD {
|
||||
background: #006699;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.menubar {
|
||||
background: #006699;
|
||||
color: white;
|
||||
margin: 1ex 0;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.menubar .links {
|
||||
background: transparent;
|
||||
color: white;
|
||||
padding: 0.2ex;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.menubar .searchbar {
|
||||
background: black;
|
||||
color: black;
|
||||
margin: 0px;
|
||||
padding: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
A.m:link, A.m:visited {
|
||||
background: #006699;
|
||||
color: white;
|
||||
font: bold 10pt Arial,Helvetica,sans-serif;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
A.o:link, A.o:visited {
|
||||
background: #006699;
|
||||
color: #ccffcc;
|
||||
font: bold 10pt Arial,Helvetica,sans-serif;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
A.o:hover {
|
||||
background: transparent;
|
||||
color: #ff6600;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
A.m:hover {
|
||||
background: transparent;
|
||||
color: #ff6600;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
table.dlsip {
|
||||
background: #dddddd;
|
||||
border: 0.4ex solid #dddddd;
|
||||
}
|
||||
|
||||
.pod, .manifest { margin-right: 0; }
|
||||
|
||||
.pod PRE {
|
||||
background: #eeeeee;
|
||||
border: 1px solid #888888;
|
||||
color: black;
|
||||
padding: 1em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.pod H1 {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.pod H1 A { text-decoration: none; }
|
||||
.pod H2 A { text-decoration: none; }
|
||||
.pod H3 A { text-decoration: none; }
|
||||
.pod H4 A { text-decoration: none; }
|
||||
|
||||
.pod H2 {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.pod H3 {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.pod H4 {
|
||||
background: transparent;
|
||||
color: #006699;
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.pod IMG {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.pod .toc A {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.pod .toc LI {
|
||||
line-height: 1.2em;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.faq DT {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.chmenu {
|
||||
background: black;
|
||||
color: red;
|
||||
font: bold 1.1em Arial,Helvetica,sans-serif;
|
||||
margin: 1ex auto;
|
||||
padding: 0.5ex;
|
||||
}
|
||||
|
||||
.chmenu TD {
|
||||
padding: 0.2ex 1ex;
|
||||
}
|
||||
|
||||
.chmenu A:link, .chmenu A:visited {
|
||||
background: transparent;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.chmenu A:hover {
|
||||
background: transparent;
|
||||
color: #ff6600;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.column {
|
||||
padding: 0.5ex 1ex;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.datebar {
|
||||
margin: auto;
|
||||
width: 14em;
|
||||
}
|
||||
|
||||
.date {
|
||||
background: transparent;
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 1ex;
|
||||
text-align: right;
|
||||
color: #006699;
|
||||
font-size: x-small;
|
||||
border-top: 1px solid #006699;
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
.front .footer {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
#permalink {
|
||||
float: right
|
||||
}
|
||||
|
||||
#permalink A {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.sr {
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cpanstats {
|
||||
float: left;
|
||||
text-align: left;
|
||||
color: #bbb;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
form.tool {
|
||||
margin: 1ex;
|
||||
}
|
||||
|
||||
.styleswitch {
|
||||
text-align: right;
|
||||
}
|
||||
Reference in New Issue
Block a user