Integrated EPICS version of expmag

This commit is contained in:
2026-07-07 15:40:00 +02:00
parent f77c6b54a5
commit 8220130bdd
6 changed files with 6654 additions and 44 deletions
+102 -27
View File
@@ -11,8 +11,28 @@ add_compile_options(
-Wno-unused-function
)
# Check if the required environment variables MIDASSYS, EPICSSYS and EPICS_HOST_ARCH are available
if (NOT DEFINED ENV{MIDASSYS})
message(SEND_ERROR "MIDASSYS environment variable not defined.")
endif()
if (NOT DEFINED ENV{EPICSSYS})
message(SEND_ERROR "EPICSSYS environment variable not defined.")
endif()
if (NOT DEFINED ENV{EPICS_HOST_ARCH})
message(SEND_ERROR "EPICS_HOST_ARCH environment variable not defined.")
endif()
set(MIDASSYS $ENV{MIDASSYS})
set(EPICSSYS $ENV{EPICSSYS})
# Select the correct EPICS library depending on the OS (currently Linux is available)
if (${CMAKE_SYSTEM_NAME} MATCHES Linux)
link_directories(${EPICSSYS}/lib/linux-x86_64)
set(LIBS ${LIBS} -lpthread -lutil -lrt -lbsd -ldl)
endif()
option(
BUILD_FRONTEND
BUILD_FRONTENDS
"If ON, build the default frontend executable"
OFF
)
@@ -27,11 +47,6 @@ set(
"path to tcpip driver that should be used"
)
set(
DRIVERS
$ENV{MIDASSYS}/drivers/class/generic.cxx
)
set(SYS_LIBS
pthread
util
@@ -45,7 +60,14 @@ set(MIDAS_LIBS
midas::mscb
)
set(TCPIP_DRIVER)
set(LIBS ${SYS_LIBS} ${MIDAS_LIBS})
set(EPICS_LIBS
${LIBS}
${EPICSSYS}/lib/$ENV{EPICS_HOST_ARCH}/libca.so
${EPICSSYS}/lib/$ENV{EPICS_HOST_ARCH}/libCom.so
)
add_subdirectory(midas_lan_gpib)
@@ -67,28 +89,28 @@ if(IS_DIRECTORY ${TCPIP_DRIVER_DIR})
)
else()
set(
DRIVERS
${DRIVERS}
TCPIP_DRIVER
${TCPIP_DRIVER_DIR}
)
endif()
################################################################################
## Device Library
## Device Libraries
################################################################################
add_library(
expmag
device/expmag.cxx
device/spline.cxx
${DRIVERS}
${TCPIP_DRIVER}
$ENV{MIDASSYS}/drivers/class/generic.cxx
)
set_property(
TARGET
expmag
PROPERTY
CXX_STANDARD 11
CXX_STANDARD 17
)
target_include_directories(
@@ -106,33 +128,86 @@ target_link_libraries(
${LIBS}
)
######## EPICS library
add_library(
expmag_epics
device/expmag.cxx
device/epics_ca.cxx
device/spline.cxx
${TCPIP_DRIVER}
$ENV{MIDASSYS}/drivers/class/generic.cxx
)
set_property(
TARGET
expmag_epics
PROPERTY
CXX_STANDARD 17
)
target_include_directories(
expmag_epics
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE
$ENV{MIDASSYS}/drivers
${EPICSSYS}/include
${EPICSSYS}/include/os/Linux
${EPICSSYS}/include/compiler/gcc
${EPICSSYS}/include/compiler/clang
)
target_link_libraries(
expmag_epics
PUBLIC
midas_lan_gpib
${EPICS_LIBS}
)
target_compile_definitions(
expmag_epics
PRIVATE
EPICSGFA
GFA_SPECIFIC
)
################################################################################
## Test Frontend
################################################################################
if(${BUILD_FRONTEND})
if(${BUILD_FRONTENDS})
add_executable(
expmag_fe
frontend/expmag_scfe.cxx
)
foreach(target IN ITEMS expmag_fe expmag_epics_fe)
set_property(
TARGET
expmag_fe
PROPERTY
CXX_STANDARD 11
)
add_executable(
${target}
frontend/expmag_scfe.cxx
)
target_include_directories(
expmag_fe
PRIVATE
$ENV{MIDASSYS}/drivers
)
set_property(
TARGET
${target}
PROPERTY
CXX_STANDARD 17
)
target_include_directories(
${target}
PRIVATE
$ENV{MIDASSYS}/drivers
)
endforeach()
target_link_libraries(
expmag_fe
expmag
)
target_link_libraries(
expmag_epics_fe
expmag_epics
)
endif()
+6 -9
View File
@@ -1,14 +1,11 @@
# Main experimental magnet PS
This repository contains the driver code and Midas frontend for the main
experimental magnet PS.
> **Important Note**
>
> The EPICSGFA flag is currently not used, it was created for using a prototype
> EPICS driver for MIDAS. It is not clear whether this prototype driver would
> work. If all instruments work without this flag in late 2026, it is heavily
> recommended to remove it entirely.
experimental magnet PS. There are two different versions of this driver - one
using LAN-GPIB to run the magnets and a second one which uses the EPICS
interface provided by GFA. The respective CMake targets are:
- `expmag` (LAN-GPIB)
- `expmag_epics` (EPICS interface)
## Requirements
@@ -20,7 +17,7 @@ to the built Midas artifacts and headers.
Clone this repository, enter the cloned directory, and then build via CMake.
```bash
cmake -S "$(pwd)" -B <directory-to-build-in> -DBUILD_FRONTEND=ON
cmake -S "$(pwd)" -B <directory-to-build-in> -DBUILD_FRONTENDS=ON
cmake --build <directory-to-build-in> --clean-first -- -j8
```
+6067
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
/********************************************************************\
Name: epics_ca.h
Created by: Stefan Ritt
Contents: Channel Access device driver function declarations
$Id: epics_ca.h,v 1.1.1.1 2019/02/21 10:07:20 raselli Exp $
\********************************************************************/
INT epics_ca(INT cmd, ...);
+458
View File
@@ -0,0 +1,458 @@
/********************************************************************\
Name: epics_ca_private.h
Created by: RA36 (modified part of epics_ca.c)
Contents: Channel Access device driver private function declarations
epics_ca_...() functions may also be used as sub device driver
$Id: epics_ca_private.h,v 1.5 2024/06/30 10:09:16 raselli Exp $
\********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cadef.h"
#include "epicsEvent.h"
#ifdef _MSC_VER /* collision between varargs and stdarg */
#undef va_arg
#undef va_start
#undef va_end
#endif
#include "midas.h"
#ifndef _EPICS_CA_PRIVATE_H_
#define _EPICS_CA_PRIVATE_H_
/*----------------------------------------------------------------------------*/
#define CHN_NAME_LENGTH 32 /* length of channel names */
#define CHNFLAGS_LENGTH 16 /* chan flags string size */
/*----------------------------------------------------------------------------*/
#ifdef GFA_SPECIFIC
#define DTYPE_LENGTH 40 /* epics DBR_STRING size - fixed */
#define DSEC_LENGTH 40 /* epics DBR_STRING size - fixed */
#endif
/* DD settings
* DD/Loadfile <loadfile> (size is NAME_LENGTH-1 = 31)
* loadfile location is usually /usr/local/midas for Midas 1.9.5 or
* /usr/local/midas2_32 (i686) or /usr/local/midas2_64 (x86_64) for Midas 2.1
* /usr/local/midas2n_32 (i686) or /usr/local/midas2n_64 (x86_64) for Midas 2.1N
* <loadfile> will be read and interpreted and DD entries for
* EPICS Channel name, Used, Readonly, Chn_flags, Minval, Maxval, Threshold
* and Tolerance will be created, if it they did not previously exist.
*
* DD/AlarmWhenNOTConnected <alarm>
* if not NONE, Alarm <alarm> will initially be reset in epics_ca_init() and
* in epics_ca_get() when Sum_NOT_Connected (of all C flagged channels)
* changes to 0.
* e.g.: Alarm condition for Alarm "BL connected" for the PiM3 area is
* /Equipment/eblpim3/Settings/Devices/EPICSGFA/DD/Sum_NOT_Connected > 0
*
* DD/Sum_NOT_Connected <number>
* <number> > 0 may be used as Alarm level
*
* DD/AlarmWhenNOTinTolerance <alarm>
* if not NONE, Alarm <alarm> will initially be reset in epics_ca_init() and
* when Sum_NOT_in_Tolerance changes (of all T flagged channels) changes to 0.
* e.g.: Alarm condition for Alarm "BL tolerance" for the PiM3 area is
* /Equipment/eblpim3/Settings/Devices/EPICSGFA/DD/Sum_NOT_in_Tolerance > 0
*
* DD/Sum_NOT_in_Tolerance <number>
* <number> > 0 may be used as Alarm level
* NOTE: Pending operations set Sum_NOT_in_tolerance > 0 until reliable
* checks are possible. To make sure WAIT <equipment> INRANGE in autorun
* waits until all operations are completed.
*
* DD/EPICS Channel name [] max. 32 characters
*
* DD/Used [] y/n
*
* DD/Readonly [] y/n
*
* DD/Chn_Flags []
*
* Chn_flags are evaluated when (re)connecting, reading or setting the
* respective channel
* NOTE: Only channel flag I should be used when epics_ca device driver
* routines are used as sub device driver for another device driver.
*
* - Initial values set when DD is created are "US".
* These must be changed when doing the initial setup
* U = NOT USED (Channel will not be handled)
*
* - Initialized
* I = Channel may be used and has no special flags
*
* - channel subscription may be disabled
* S = NO subscription of channel changes
* e.g. for strings
*
* - update demand value of channel when readout of demand value changes
* F = Feedback of demand channel readout to (Midas) demand value of
* channel when (Midas) demand value was not updated by epics_ca_set()
* in the last 2 seconds
* NOTE:
* when the demand value is out of range
* if #define RESET_DEMAND_VALUE_TO_RANGE is defined
* then
* *** the demand value will be reset
* to the corresponding range limit *** in epics_ca_set(),
* only, when the parameter forced_update is TRUE
* else
* ODB will be updated only and the demand value will not
* be sent to the EPICS channel by ca_put()
* else
* if the demand value readout is out of range a message will
* be logged but the demand value will not be updated.
*
* See GFA specific flag G for update of Command or Setpoint channel demand
* by the interpreted readout of a measured or status channel.
*
* - Min/Max Info for GUI or Min/Max value when sending new demand value
* to EPICS channel
* M = Write Min & Max in DD during first init of DD/MinVal and DD/MaxVal
* Change new demand value to Min or Max value when out of range
*
* NOTE: Maybe modify Min/Max of channels manually when channel is not
* available during init or Min or Max value should be different
* NOTE: any value may be set if MinVal and MaxVal are both equal to 0
* NOTE: any value may be set if M is not specified in DD/Chn_Flags
*
* Delete DD/MinVal DD/MaxVal after the first setup to regenerate
* Min/Max from LOW/HIGH when channels are connected.
*
* NOTE: For GFA device type FENTE (=SLIT) LOW/HIGH is not set. Always
* set MinVal and MaxVal to 0 as Min/Max may not be determined
* reliably by moving into either limit switch. There is also a race
* condition when the slit position is set to an out of range
* position by another application.
*
* NOTE: S and U overrule M
*
* - information when channel is not connected ....
* D = Set measured value to -1 to flag channel not found, disconnected
* or no read access
*
* - information if channel is not connected
* C = check if channel is not connected.
* NOTE: When NOT connected DD/Sum_NOT_connected is incremented.
*
* - reset demand value
* R = (Re)set Demand value on EPICS channel when channel is reconnected
* and readout of demand value and demand value differ.
* NOTE: Setpoint must always be valid.
* e.g. GFA device type FENTE must therefore always be set to
* setpoint and command MOVE_TO_SOL must be commanded (G-flag).
*
* *** GFA Specific ***
*
* . GFA specific handling of channels when compilation flag GFA_SPECIFIC
* is defined.
* . The device type of an EPICS channel is determined by reading the
* device type channel <device>:DESC:TYP of <device>.
* exceptions that do not have a :DESC:TYP channel are
* KS<number> -> BX
* SEP<number>HVN:, SEP<number>HVP: and SEP<number>HV: -> HVPS
* ROT<number>HVN:, ROT<number>HVP: and ROT<number>HV: -> HVPS
* <name>CNT:INP<number> e.g. ZMUE1CNT:INP3 -> DIAG
* The following GFA specific device types exist and are handled:
* BEND,QUAD,SEPT,STER,PS,TS,KICKER,BX,VALVE,FENTE,SOLE,DIAG and HVPS.
* . The following GFA specific device types will be treated as the basic
* device types:
* DEGR -> FENTE
* CS_DEGR -> FENTE
* CS_FENT -> FENTE
* CS_BX -> BX
* CS_PS -> PS
* MA_BEND -> BEND
* MA_QUAD -> QUAD
* MA_STER -> STER
* MA_SEXT -> SEXT
* MA_SOLE -> SOLE
* MA_SPIN -> PS
* MA_KICK -> KICKER
* MA_TR -> TS
* TR -> TS
* VA_VALVE -> VALVE
* VA_PUMP -> PUMP
* VA_GAUGE -> GAUGE
* DI_DIAG -> DIAG
* DI_MESTRA -> DIAG
* . BEND,QUAD,SEPT,STER,PS,SOLE and TS are power supplies for magnetic
* components of the beamlines.
* KICKER is a high voltage power supply using the MultIO interface.
* Digital power supplies are of type KombiPS1 and for analog power supplies
* the MultiIO interface is used. :COM:2 commands and :STA:2 status for
* both type of power supplies are identical. :SOL:2 and :IST:2 units are
* either A or kV.
* Some analog power supplies have a switch to set either 20% or 100% of
* the full range. An additional variable <name>:SCALE:2:factor may be set
* for this device.
* . BX are beam blocker channels (KV = Kanalverschluss).
* . VALVE are valve channels of the vacuum system.
* . FENTE are slit channels
* . HVPS are channels of the separator/spinrotator high voltage system
* including vacuum pressure and xray readout.
* Until now there is no feedback of the one or two :STA:2 channels to the
* (single) :COM:2 implemented.
* Setting the F flag will reset :COM:2 to -2 in the ODB. ON (0), OFF (1) or
* RESET (2) may therefore be set irrespective of the previously set value.
* . DIAG are EPICS single scalers of the beamline for Optima.
* . readout of an EPICS command channel is not reliable. After sending a
* command to a <device>:COM:2 channel the readout may not be used to update
* the demand value in the Midas ODB. If the device type of an EPICS channel
* is known the status channel <device>:STA:1 information may be used to
* update the demand value instead. (see G-flag description)
* . readout of an EPICS channel representing a measured quantity and status
* channel information may be used to set the demand value in the ODB
* . <device>:COM:2 may be set automatically when setting the demand value of
* <device> e.g. to turn power off or on.
* . The location of a device may be determined by reading the
* <device>:DESC:SEC EPICS channel of <device>.
* Exceptions are KS<>,SEP<>,ROT<>, <>CNT:INP<>, some power supplies and
* some slits. These are hardcoded.
*
* - update demand value of channel corresponding to measured or status chan
* G = Feedback from "Measured" or "Status" channel readout to corresponding
* demand channel and demand value was not updated by epics_ca_set()
* in the last 2 seconds.
*
* NOTE: ODB update only - demand value will not be put to EPICS channel
*
* NOTE: Type FENTE :SOL:2 will only be updated with IST1:2 or POSA:2
* when not moving anymore (NOT 0x0100 and NOT 0x0200) and in :STA:1
* status "stopped" (0x0004) and previous cmd was SOL=POSA(0x0004).
* Updating :SOL:2 when cmd was MOVE_TO_CW/CCW (0x0000/0x0001) and
* status is "in CW/CCW limit switch" (0x0001/0x0002) was not
* implemented as :SOL:2 may not reliably be positioned to readout
* position of IST1:2 or POSA:2.
* NOTE: POSA and SOL are mm equivalent to POSA:2 and SOL:2 in Steps.
* :COM:2 has less commands. :STA:2 is different than :STA:1
*
* See non GFA specific flag F for update of demand by demand readout
*
* - additional EPICS channel e.g. for Power ON/OFF may be set
* according to GFA device type
*
* P = Turn power ON (other channel e.g. :COM:2) when setting this channel
* e.g. :SOL:2
* N = Turn power ON (other channel e.g. :COM:2) when setting > 0
* Turn power OFF (other channel e.g. :COM:2) when setting <= 0
* Z = Turn power OFF (other channel e.g. :COM:2) when setting to zero
* Turn power ON (other channel e.g. :COM:2) when setting <> zero
* NOTE: N overrules Z and P. Z overrules P.
* NOTE: No ramping to zero - command power off will be sent to :COM:2
* channel immediately. If ramping to zero is not implemented in
* the EPICS IOC the GFA device has to be set close to zero before
* sending power off.
*
* - set command set_to_demand on other channel
* V = Set value for "Move to setpoint" MOVE_TO_SOL=0x0003
* (in other channel e.g. :COM:2 for GFA of type FENTE)
* when setting this channel e.g. :SOL:2
*
* - check tolerance of this channel
* T = check if (this) demand channel e.g. <dev>:SOL:2 and corresponding
* measured channel e.g.: <dev>:IST:2 are in tolerance
* when <tolerance> of demand is > 0.
* Does not check tolerance when demand value is negative and N flag is
* set.
* NOTE: When NOT in tolerance DD/Sum_NOT_in_Tolerance is incremented.
* NOTE: For BX and VALVE out of tolerance condition is met when NOT open.
* <dev>:COM:2 or <dev>:CSV:2 is derived from :STA:1 and therefore
* not evaluated.
*
* Examples of channel flags
*
* EPICS Channel GFA_type Channel flags Iscmd
* ------------- ---------- ------------- ------
* in Steps old slit control
* FS11-L:COM:2 FENTE I y <-| <-|
* FS11-L:STA:1 FENTE IG n G |
* FS11-L:SOL:2 FENTE IVMCF y <-F <-| V
* FS11-L:IST1:2 FENTE IG n G*
* or in steps new slit control
* FS71-L:COM:2 FENTE IF y <-F <-|
* FS71-L:STA:2 FENTE <channel is disabled> |
* FS71-L:SOL:2 FENTE IVCF y <-F V
* FS71-L:POSA:2 FENTE I n
* NOTE: Use IVCF for :SOL:2 and IF for :COM:2 and I for :STA:2 and :POSA:2
* or in mm new slit control
* FS11-L:COM:2 FENTE IF y <-|
* FS11-L:STA:2 FENTE <channel is disabled> |
* FS11-L:SOL FENTE IVMCF y <-F V
* FS11-L:POSA FENTE I n
* NOTE: Use IVCF for :SOL and IF for :COM:2, and I for :STA:2 and :POSA
*
* ASM11:COM:2 BEND I y <-| <-|
* ASM11:STA:1 BEND IG n G |
* ASM11:SOL:2 BEND IFZMCTR y <-F Z,N or P T R->
* ASM11:IST:2 BEND I n T
*
* QSK81:COM:2 QUAD I y \
* QSK81:STA:1 QUAD IG n > see ASM11
* QSK81:SOL:2 QUAD IFZMCTR y /
* QSK81:SCALE:2:factor QUAD IF y F: demand of factor
* QSK81:SCALE:2:factor QUAD I y NOT F: readout of factor
* QSK81:IST:2 QUAD I n
*
* KSD11:COM:2 BX I y <-|
* KSD11:STA:1 BX IGCT n G T
*
* VSD11:CSV:2 VALVE I y <-|
* VSD11:STA:1 VALVE IGCT n G T
*
* SEP31HVN:STA:2 HVPS I n
* SEP31HVN:ISTI:2 HVPS I n
* SEP31HVN:ISTV:2 HVPS I n T
* SEP31HVN:SOLI:2 HVPS IF y <-F |
* SEP31HVN:SOLV:2 HVPS IFCT y <-F T
* SEP31HVP:STA:2 HVPS I n
* :
* SEP31HV:COM:2 HVPS IF y <-F dummy flag!
* NOTE: NO <device>HV:STA:2! Demand <device>HV:COM:2 will be reset to -2
* SEP31HV:XRAY:2 HVPS I n
* SEP31HV:VAC:2 HVPS I n
* SEP31HV:TIME:2 HVPS I n
*
* ZMUE1CNT:INP3 DIAG I n
* MHC4:IST:2 DIAG I n
*
* DD/DESC:TYP[] GFA specific type used to handle channel according to type
* BEND, QUAD, SEPT, STER, PS, TS, KICKER, BX, VALVE, FENTE, SOLE, DIAG,
* HVPS, ...
* **CHAN_NOT_USED** DD/Used[] is N
* **TYPE_NOT_INIT**
* **TYPE_NOT_RETURNED** <device>:DESC:TYP information was not returned
* **TYPE_NOT_FOUND** EPICS channel <device>:DESC:TYP was not found
* and not assigned using <device>
*
* DD/DESC:SEC[] GFA specific section informational only
* PIM1, PIM31, PIM32, PIM33, PIE1, PIE3, MUE1, ...
* **CHAN_NOT_USED** DD/Used[] of channel is N
* **SEC_NOT_INIT**
* **SEC_NOT_RETURNED** <device>:DESC:SEC information was not returned
* **SEC_NOT_FOUND** EPICS channel <device>:DESC:SEC was not found
* and not assigned using <device>
*
* *** END GFA Specific ***
*
* DD/Minval [] [0.0]
* Minimum value from Loadfile or updated from LOW attribute of Channel
* when M flag is set and DD/Minval does not exist
*
* DD/Maxval [] [0.0]
* Maximum value from Loadfile or updated from HIGH attribute of Channel
* when M flag is set and DD/Maxval does not exist
* NOTE: if Minval[i] and Maxval[i] of EPICS channel [i] is 0.0 there will be
* no range checking when a demand value is set on channel [i]
*
* DD/Tolerance [] [0.0]
* Tolerance from Loadfile
* NOTE: Tolerance will not be checked when T flag of the channel is not set
* NOTE: Tolerance will not be checked when 0.0 is set as tolerance
* (except device type BX and VALVE where status OPEN is interpreted as
* in tolerance range and status CLOSED as out of tolerance range)
*/
/*----------------------------------------------------------------------------*/
typedef struct {
char loadfile[NAME_LENGTH]; /* file name of load file */
char AlarmWhenNOTConnected[NAME_LENGTH];
int Sum_NOT_Connected; /* sum of DOWN channels with C flag set */
char AlarmWhenNOTinTolerance[NAME_LENGTH];
int Sum_NOT_in_Tolerance; /* out of tolerance channels with T flag & tol > 0.0 */
char *channel_names; /* channel_names */
#ifdef GFA_SPECIFIC
char *dtype; /* description type (also for interpretation by GUI) */
char *dsec; /* description section (also for interpretation by GUI) */
#endif
char *chnflags; /* special flags of channel */
float *minval; /* channel minval */
float *maxval; /* channel maxval */
float *tolerance; /* channel tolerance */
BOOL *used; /* used flag */
BOOL *readonly; /* readonly flag */
} CA_SETTINGS;
typedef struct {
CA_SETTINGS settings; /* DD specific settings in ODB */
chid *pchid; /* channel ID of channels */
float *array_new; /* new channel readout */
float *array_new_m; /* new channel readout mirror */
float *array; /* channel readout */
float *array_m; /* channel readout mirror */
float *demand; /* channel demand */
float *threshold; /* channel threshold (only used when reading loadfile) */
DWORD *lastset; /* channel timestamp when last set */
DWORD *lastget; /* channel timestamp when last get */
BOOL *get; /* get flag */
BOOL *getcalled; /* get flag */
int *status_new; /* new status returned in event handler */
int *status_new_m; /* new status returned in event handler mirror */
int *status; /* status returned in event handler */
BOOL *found_new; /* channel event found flag */
BOOL *found_new_m; /* channel event found flag mirror */
BOOL *found; /* channel found flag */
BOOL *iscmd; /* iscmd flag */
BOOL *subscribed; /* subscribed flag */
BOOL *down; /* down flag */
BOOL *first; /* first flag */
BOOL *firstread; /* flag expecting first reading when UP again */
INT *nerr; /* number of errors */
INT *nmsg; /* number of messages */
#ifdef GFA_SPECIFIC
INT *tolchan; /* index of corresponding tolerance channel */
INT *gchan; /* index of corresponding channel with G-flag */
BOOL *intol; /* channel is/is not in tolerance range */
#endif
INT num_channels; /* number of channels */
DWORD flags; /* flags supplied when epics_ca(CMD_INIT, ...) is called*/
INT cmd_disabled; /* command execution in epics_ca() is initially disabled*/
INT subscribe_disabled;/* subscribe (in connection handler) is initially disabled*/
#ifdef GFA_SPECIFIC
BOOL handling_disabled; /* GFA specific handling is (currently) disabled */
#endif /* to avoid infinit loop of handling dependencies... */
char name[NAME_LENGTH]; /* equipment <name> */
HNDLE hkeyDemand; /* "/Equipment/<equi>/Variables/Demand" key handle */
HNDLE hkeyDD; /* "DD" key handle */
HNDLE hkeySNC; /* "DD/Sum_NOT_Connected" key handle */
HNDLE hkeySNT; /* "DD/Sum_NOT_in_Tolerance" key handle */
DWORD lastSNC; /* last time Sum_NOT_Connected of C flag channels */
DWORD lastSNT; /* last time Sum_NOT_in_Tolerance of T flag channels */
INT pending; /* pending operation -> increment Sum_NOT_in_Tolerance */
BOOL silentreadonly; /* do not show a readonly message when demand and */
/* newdemand differ but ODB will be updated */
} CA_INFO;
/*---- functions ---------------------------------------------------*/
INT epics_ca (INT cmd, ...);
INT epics_ca_init (HNDLE , CA_INFO **, INT);
INT epics_ca_exit (CA_INFO *);
INT epics_ca_set (CA_INFO *, INT, float, BOOL, BOOL);
INT epics_ca_set_all (CA_INFO *, INT, float);
INT epics_ca_set_label (CA_INFO *, INT, char *);
INT epics_ca_get (CA_INFO *, INT, float *);
INT epics_ca_get_demand(CA_INFO *, INT, float *);
INT epics_ca_get_all (CA_INFO *, INT, float *);
INT epics_ca_set_pending (CA_INFO *, BOOL);
INT epics_ca_get_default_name (CA_INFO *, INT, char *);
INT epics_ca_get_default_threshold(CA_INFO *, INT, float *);
#endif /* _EPICS_CA_PRIVATE_H_ */
/*--- EOF epics_ca_private.h -------------------------------------------------*/
+9 -8
View File
@@ -27,8 +27,8 @@
#include "midas.h"
#include "msystem.h"
#include "device/spline.h"
#include "midas_lan_gpib.h"
#include "bus/tcpip.h"
#include "midas_lan_gpib.h"
#ifdef EPICSGFA
#define GFA_SPECIFIC /* GFA specific handling of EPICS channels :COM: :SOL: */
@@ -1624,7 +1624,7 @@ INT epics_wait(EXPMAG_INFO *info, int ntimes, INT interval) {
/* the init function creates a ODB record which contains the
settings and initialized it variables as well as the bus driver */
INT expmag_init(HNDLE hkey, void **pinfo, INT channels, INT(*bd) (INT cmd, ...))
INT expmag_init(HNDLE hkey, EXPMAG_INFO **pinfo, INT channels, INT(*bd) (INT cmd, ...))
{
int status, size;
HNDLE hDB, hkeydd;
@@ -1753,7 +1753,7 @@ INT expmag_init(HNDLE hkey, void **pinfo, INT channels, INT(*bd) (INT cmd, ...))
if (db_find_key(hDB, info->hkey, "EPICS", &tkey) == DB_SUCCESS) {
// init EPICS channel access
status = epics_ca_init( tkey, (void **)&info->cainfo,
status = epics_ca_init( tkey, (CA_INFO **)&info->cainfo,
info->expmag_settings.epics_channels);
if (status != SUCCESS) {
cm_msg(MERROR,"expmag_init","ERROR returned from epics_ca_init() - EXIT");
@@ -3967,7 +3967,7 @@ mode_change:
timeo = ss_time()+60;
do {
#ifdef EPICSGFA
epics_wait(info,3, 333);
epics_wait((EXPMAG_INFO*)info,3, 333);
#else
ss_sleep(1000);
#endif
@@ -6965,6 +6965,7 @@ INT expmag(INT cmd, ...)
float value, *pvalue;
void *info, *bd;
char *name;
EXPMAG_INFO **pinfo;
va_start(argptr, cmd);
status = FE_SUCCESS;
@@ -6976,11 +6977,11 @@ INT expmag(INT cmd, ...)
switch (cmd) {
case CMD_INIT:
hKey = va_arg(argptr, HNDLE);
info = va_arg(argptr, void *);
pinfo = va_arg(argptr, EXPMAG_INFO **);
channel = va_arg(argptr, INT);
flags = va_arg(argptr, DWORD);
bd = va_arg(argptr, void *);
status = expmag_init(hKey, &info, channel, (INT (*)(INT, ...))bd);
status = expmag_init(hKey, pinfo, channel, (INT (*)(INT, ...))bd);
break;
case CMD_EXIT:
@@ -7012,14 +7013,14 @@ INT expmag(INT cmd, ...)
gngets++;
if (gngets > 100) {
#ifdef EPICSGFA
epics_wait(info, 3, 333);
epics_wait((EXPMAG_INFO*)info, 3, 333);
#else
ss_sleep(1000);
#endif
}
} else {
#ifdef EPICSGFA
epics_wait(info, 6, 500);
epics_wait((EXPMAG_INFO*)info, 6, 500);
#else
ss_sleep(3000);
#endif