AlcapDAQ  1
Data Structures | Macros | Typedefs | Functions | Variables
epics_ca.c File Reference
#include <errno.h>
#include "epics_ca_private.h"

Go to the source code of this file.

Data Structures

struct  _GFA_msg
 
struct  _GFA_mask
 
struct  _GFA_channel
 
struct  _GFA_type
 

Macros

#define GFA_SPECIFIC   /* include GFA_SPECIFIC code in private */
 
#define N_GFA_TYPES   (sizeof(gfatype)/sizeof(GFA_type)) -1
 

Typedefs

typedef struct _GFA_msg GFA_msg
 
typedef struct _GFA_mask GFA_mask
 
typedef struct _GFA_channel GFA_channel
 
typedef struct _GFA_type GFA_type
 

Functions

INT epics_ca (INT cmd,...)
 
INT epics_ca_init (HNDLE, void **, 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 *)
 
char * castatestr (enum channel_state)
 
void epics_ca_exception_handler (struct exception_handler_args)
 
void epics_ca_event_handler (struct event_handler_args)
 
void epics_ca_connection_handler (struct connection_handler_args)
 

Variables

static char smsg [128]
 
GFA_msg KVstamsg0003 []
 
GFA_msg KVstamsg0004 []
 
GFA_msg KVstamsg0008 []
 
GFA_mask KVsta []
 
GFA_msg KVcommsg0001 []
 
GFA_mask KVcom []
 
GFA_channel KVchan []
 
GFA_msg KPS1stamsg000f []
 
GFA_msg KPS1stamsg0010 []
 
GFA_msg KPS1stamsg0020 []
 
GFA_msg KPS1stamsg0040 []
 
GFA_msg KPS1stamsg0080 []
 
GFA_msg KPS1stamsg0400 []
 
GFA_msg KPS1stamsg0800 []
 
GFA_msg KPS1stamsg1000 []
 
GFA_msg KPS1stamsg2000 []
 
GFA_msg KPS1stamsg8000 []
 
GFA_mask KPS1sta []
 
GFA_msg KPS1cmdmsg []
 
GFA_mask KPS1cmd []
 
GFA_channel KPS1chan []
 
GFA_msg Slitstamsg307 []
 
GFA_msg Slitstamsg300 []
 
GFA_mask Slitsta []
 
GFA_msg Slitcmdmsg []
 
GFA_mask Slitcmd []
 
GFA_channel Slitchan []
 
GFA_msg HVPSstamsg []
 
GFA_mask HVPSsta []
 
GFA_channel HVPSchan []
 
GFA_type gfatype []
 

Macro Definition Documentation

#define GFA_SPECIFIC   /* include GFA_SPECIFIC code in private */

Definition at line 23 of file epics_ca.c.

Referenced by epics_ca_init().

#define N_GFA_TYPES   (sizeof(gfatype)/sizeof(GFA_type)) -1

Definition at line 334 of file epics_ca.c.

Referenced by epics_ca_event_handler(), epics_ca_init(), and epics_ca_set().

Typedef Documentation

typedef struct _GFA_channel GFA_channel
typedef struct _GFA_mask GFA_mask
typedef struct _GFA_msg GFA_msg
typedef struct _GFA_type GFA_type

Function Documentation

char * castatestr ( enum channel_state  castate)

Definition at line 362 of file epics_ca.c.

References smsg.

Referenced by epics_ca_init(), and epics_ca_set().

362  {
363 
364  switch(castate) {
365  case cs_never_conn:
366  strcpy(&smsg[0],"Server not found or unavailable");
367  break;
368 
369  case cs_prev_conn:
370  strcpy(&smsg[0],"Previously connected to server");
371  break;
372 
373  case cs_conn:
374  strcpy(&smsg[0],"Connected to server");
375  break;
376 
377  case cs_closed:
378  strcpy(&smsg[0],"Channel deleted by user");
379  break;
380 
381  default:
382  strcpy(&smsg[0],"**UNKNOWN STATE**");
383  }
384  return &smsg[0];
385 }
INT epics_ca ( INT  cmd,
  ... 
)

Definition at line 3134 of file epics_ca.c.

3134  {
3135  va_list argptr;
3136  HNDLE hKey;
3137  INT channel, status;
3138  DWORD flags;
3139  float value, *pvalue;
3140  CA_INFO *info;
3141  char *label;
3142 
3143  va_start(argptr, cmd);
3144  status = FE_SUCCESS;
3145 
3146 #ifdef MIDEBUG2
3147  cm_msg(MLOG,"","++epics_ca(CMD=%d)",cmd);
3148 #endif
3149  if (cmd == CMD_INIT) {
3150  void *pinfo;
3151 
3152  hKey = va_arg(argptr, HNDLE);
3153  pinfo = va_arg(argptr, void *);
3154  channel = va_arg(argptr, INT);
3155  flags = va_arg(argptr, DWORD);
3156  status = epics_ca_init(hKey, pinfo, channel);
3157  if (pinfo) {
3158  info = *(CA_INFO **) pinfo;
3159  if (info) info->flags = flags;
3160  }
3161  } else {
3162  info = va_arg(argptr, void *);
3163 
3164  /* only execute command if enabled */
3165  if (!info || info->cmd_disabled) {
3166  ss_sleep(100);
3167 #ifdef MIDEBUG2
3168  cm_msg(MLOG,"","ss_sleep(100)");
3169 #endif
3170  status = FE_ERR_DISABLED;
3171  } else {
3172  switch (cmd) {
3173  case CMD_INIT:
3174  break;
3175 
3176  case CMD_EXIT:
3177  status = epics_ca_exit(info);
3178  break;
3179 
3180  case CMD_SET:
3181  channel = va_arg(argptr, INT);
3182  value = (float) va_arg(argptr, double);
3183  status = epics_ca_set(info, channel, value, TRUE, FALSE);
3184  break;
3185 
3186  case CMD_SET_ALL:
3187  channel = va_arg(argptr, INT);
3188  value = (float) va_arg(argptr, double);
3189  status = epics_ca_set_all(info, channel, value);
3190  break;
3191 
3192  case CMD_SET_LABEL:
3193  channel = va_arg(argptr, INT);
3194  label = va_arg(argptr, char *);
3195  //status = epics_ca_set_label(info, channel, label);
3196  status = FE_SUCCESS;
3197  break;
3198 
3199  case CMD_GET:
3200  channel = va_arg(argptr, INT);
3201  pvalue = va_arg(argptr, float *);
3202  status = epics_ca_get(info, channel, pvalue);
3203  break;
3204 
3205  case CMD_GET_DEMAND:
3206  channel = va_arg(argptr, INT);
3207  pvalue = va_arg(argptr, float *);
3208  status = epics_ca_get_demand(info, channel, pvalue);
3209  break;
3210 
3211  case CMD_GET_ALL:
3212  channel = va_arg(argptr, INT);
3213  pvalue = va_arg(argptr, float *);
3214  status = epics_ca_get_all(info, channel, pvalue);
3215  break;
3216 
3217  case CMD_GET_DEFAULT_NAME:
3218  channel = va_arg(argptr, INT);
3219  label = va_arg(argptr, char *);
3220  status = epics_ca_get_default_name(info, channel, label);
3221  break;
3222 
3223  case CMD_GET_DEFAULT_THRESHOLD:
3224  channel = va_arg(argptr, INT);
3225  pvalue = va_arg(argptr, float *);
3226  status = epics_ca_get_default_threshold(info, channel, pvalue);
3227  break;
3228 
3229  default:
3230 #ifdef MIDEBUG
3231  cm_msg(MLOG,"","**epics_ca(CMD=%d) is not handled",cmd);
3232 #endif
3233  break;
3234  }
3235  }
3236  }
3237 
3238  va_end(argptr);
3239 
3240 #ifdef MIDEBUG2
3241  cm_msg(MLOG,"","--epics_ca()");
3242 #endif
3243  return status;
3244 }
void epics_ca_connection_handler ( struct connection_handler_args  cargs)

Definition at line 453 of file epics_ca.c.

References CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, CA_INFO::down, epics_ca_event_handler(), FALSE, CA_INFO::firstread, found, CA_INFO::found, i, CA_INFO::num_channels, CA_INFO::pchid, CA_INFO::settings, status, CA_INFO::subscribe_disabled, CA_INFO::subscribed, and TRUE.

Referenced by epics_ca_init().

453  {
454 
455 #ifdef MIDEBUGF
456  if (fp) fprintf(fp,"%u : ++epics_ca_connection_handler()\n", ss_time());
457 #endif
458 #ifdef MIDEBUG1
459  cm_msg(MLOG,"","++epics_ca_connection_handler()");
460 #endif
461 
462  if (cargs.chid) {
463  CA_INFO *pinfo;
464  int i,status;
465 
466  pinfo = (CA_INFO *) ca_puser(cargs.chid);
467  if (pinfo) {
468  BOOL found;
469 
470  /* search channel index */
471  for (found = FALSE, i = 0; i < pinfo->num_channels; i++) {
472  if (*(pinfo->pchid+i) == cargs.chid) { // matching channel ID?
473 
474  if (cargs.op == CA_OP_CONN_UP) {
475  if (*(pinfo->subscribed+i)) {
476  cm_msg(MLOG,"","Channel %d(%s) RECONNECTED",i,ca_name(cargs.chid));
477 #ifdef MIDEBUGF
478  if (fp) fprintf(fp,"%u : Channel %d(%s) RECONNECTED\n", ss_time(),
479  i,ca_name(cargs.chid));
480 #endif
481  if (!*(pinfo->found+i)) {
482  *(pinfo->found+i) = TRUE;
483  cm_msg(MLOG,"","epics_ca_connection_handler: found flag of channel %d"
484  "(%s)was not set yet",i,ca_name(cargs.chid));
485  }
486  } else {
487 #ifdef MIDEBUG1
488  cm_msg(MLOG,"","Channel %d(%s) CONNECTED",i,ca_name(cargs.chid));
489 #endif
490 #ifdef MIDEBUGF
491  if (fp) fprintf(fp,"%u : Channel %d(%s) CONNECTED\n", ss_time(),
492  i,ca_name(cargs.chid));
493 #endif
494  // chan specific: omit channels with S-flag e.g.: returning strings
495  // and :COM:2 channels
496  if ((strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'S') == NULL)&&
497  (strstr(pinfo->settings.channel_names+CHN_NAME_LENGTH*i,":COM:2")==NULL)){
498  if (!pinfo->subscribe_disabled) {
499  cm_msg(MLOG,"","Channel %d(%s) CONNECTED",i,ca_name(cargs.chid));
500  // subscribe event handler callback for this channel when not created
501  // subscribed value is converted to float
502  status = ca_create_subscription(DBR_FLOAT,1,*(pinfo->pchid+i),DBE_LOG|
503  DBE_VALUE, epics_ca_event_handler, pinfo, NULL);
504  if (!(status & ECA_NORMAL)) {
505  cm_msg(MERROR, "epics_ca_connection_handler", "Channel %d(%s): "
506  "ca_create_subscription() returned status 0x%X = \"%s\"",i,
507  pinfo->settings.channel_names+CHN_NAME_LENGTH*i,status,
508  ca_message(status));
509  } else {
510 #ifdef MIDEBUG1
511  cm_msg(MLOG,"","Channel %d(%s): CA event handler (float) will be "
512  "installed",i,
513  pinfo->settings.channel_names+CHN_NAME_LENGTH*i,status);
514 #endif
515  *(pinfo->subscribed+i) = TRUE;
516  /* NOTE: ca_pend_io(0.01); may not be called in this event handler */
517  }
518  }
519  } else {
520  if (strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'S'))
521  cm_msg(MLOG,"","Channel %d(%s): S flag: CA event handler will NOT be "
522  "installed", i, pinfo->settings.channel_names+CHN_NAME_LENGTH*i);
523 #ifdef MIDEBUG
524  else if (strstr(pinfo->settings.channel_names+CHN_NAME_LENGTH*i,":COM:2"))
525  cm_msg(MLOG,"","Channel %d(%s): COM Channel : CA event handler will NO"
526  "T be installed",i,pinfo->settings.channel_names+CHN_NAME_LENGTH*i);
527 #endif
528  *(pinfo->subscribed+i) = TRUE; // mark as handled
529  }
530  *(pinfo->found+i) = TRUE; // mark channel as found
531  }
532  //if (strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'C') != NULL)
533  *(pinfo->down+i) = FALSE; // mark channel to be NOT down
534  } else {
535  cm_msg(MLOG,"","Channel %d(%s) is DOWN",i,ca_name(cargs.chid));
536  //if (strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'C') != NULL)
537  *(pinfo->down+i) = TRUE; // mark channel to be down
538  *(pinfo->firstread+i) = TRUE; // mark channel for first read after DOWN
539  }
540  found = TRUE;
541  break;
542  }
543  } // for all channels
544 
545  if (!found)
546  cm_msg(MERROR,"epics_ca_connection_handler","Channel %s NOT found in list!",
547  ca_name(cargs.chid));
548  } else {
549  cm_msg(MERROR,"epics_ca_connection_handler","NULL pointer returned by ca_puser()");
550  }
551  } else {
552  cm_msg(MERROR,"epics_ca_connection_handler","channel id nil returned as argument");
553  }
554 
555 #ifdef MIDEBUG1
556  cm_msg(MLOG,"","--epics_ca_connection_handler()");
557 #endif
558 #ifdef MIDEBUGF
559  if (fp) fprintf(fp,"%u : --epics_ca_connection_handler()\n", ss_time());
560 #endif
561 }
void epics_ca_event_handler ( struct event_handler_args  args)

Definition at line 567 of file epics_ca.c.

References CA_INFO::array, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, CA_INFO::demand, CA_INFO::down, epics_ca_set(), FALSE, CA_INFO::firstread, found, i, if, CA_INFO::lastget, msg, N_GFA_TYPES, _GFA_type::nc, CA_INFO::num_channels, CA_INFO::pchid, CA_INFO::settings, CA_INFO::status, CA_INFO::subscribed, _GFA_type::tc, and TRUE.

Referenced by epics_ca_connection_handler(), and epics_ca_init().

567  {
568  CA_INFO *pinfo;
569  int i;
570  BOOL found;
571 
572 #ifdef MIDEBUGF
573  if (fp) fprintf(fp,"%u : ++epics_ca_event_handler()\n", ss_time());
574 #endif
575 #ifdef MIDEBUGE1
576  cm_msg(MLOG,"","++epics_ca_event_handler()");
577 #endif
578 
579  found = FALSE;
580 
581  pinfo = (CA_INFO *) args.usr;
582 
583  if (pinfo) {
584  /* find channel index */
585  for (i = 0; i < pinfo->num_channels; i++) {
586  if (*(pinfo->pchid+i) == args.chid) { // matching channel ID?
587  if (args.type == DBR_FLOAT) { // data type is pure float?
588  float tval;
589 
590  if (*(pinfo->subscribed+i) != TRUE) {
591  *(pinfo->subscribed+i) = TRUE;
592  cm_msg(MLOG,"","epics_ca_event_handler: Subscribed flag not yet set for"
593  "channel %d(%s)",i,pinfo->settings.channel_names+CHN_NAME_LENGTH*i);
594  }
595 
596  if (*(pinfo->down+i)) {
597 #ifdef MIDEBUG1
598  cm_msg(MLOG,"","epics_ca_event_handler: channel %d(%s) Marked DOWN. Now "
599  "set to NOT DOWN",i,pinfo->settings.channel_names+CHN_NAME_LENGTH*i);
600 #endif
601  //if (strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'C') != NULL)
602  *(pinfo->down+i) = FALSE; // mark channel to be NOT down
603  }
604  if (args.dbr) {
605  tval = *((float *)args.dbr);
606 #ifdef MIDEBUGE
607  cm_msg(MLOG,"","callback for channel %d(%s): value %f", i,
608  pinfo->settings.channel_names+CHN_NAME_LENGTH*i,tval);
609 #endif
610 #ifdef MIDEBUGF
611  if (fp) fprintf(fp,"%u : callback for channel %d(%s): value %f\n",
612  ss_time(),i,pinfo->settings.channel_names+CHN_NAME_LENGTH*i,tval);
613 #endif
614  if ((args.status != ECA_NORMAL) && (*(pinfo->status+i)!=args.status)) {
615  cm_msg(MLOG,"","epics_ca_event_handler: WARNING Status %d = \"%s\" for "
616  "channel %d(%s)", args.status, ca_message(args.status),
618  }
619  *(pinfo->status+i) = args.status;
620  if (pinfo->array) {
621  *(pinfo->lastget+i) = ss_time();
622  if (*(pinfo->array+i) != tval) {
623 #ifdef GFA_SPECIFIC
624  char *tpos;
625 
626  // channel has <device>:<spec>
627  if ((tpos=strchr(pinfo->settings.channel_names+CHN_NAME_LENGTH*i,':'))
628  != NULL) {
629  int j;
630 
631  for (j = 0; j < N_GFA_TYPES; j++) {
632  // find type
633  if (strcmp(gfatype[j].type,pinfo->settings.dtype+DTYPE_LENGTH*i)==0){
634  GFA_channel *tc;
635  int k;
636 #ifdef MIDEBUGE
637  cm_msg(MLOG,"","Found type %s", gfatype[j].type);
638 #endif
639  tc = gfatype[j].tc;
640  for (k=0; k < gfatype[j].nc; k++) { // channels of this type
641 
642  if (!(tc+k)) continue;
643 
644  if (strcmp(tpos,(tc+k)->spec ) == 0) { // matching :<spec>
645  int l;
646  GFA_mask *cm;
647 #ifdef MIDEBUGE
648  cm_msg(MLOG,"","Found spec %s", (tc+k)->spec);
649 #endif
650  cm = (tc+k)->cm;
651  for (l = 0; l < (tc+k)->ns; l++) { // for all masks
652  int m;
653  int ttval, tarr;
654  GFA_msg *sm;
655 
656  if (!(cm+l)) continue;
657 #ifdef MIDEBUGE
658  cm_msg(MLOG,"","Checking Mask 0x%4.4X",(cm+l)->mask);
659 #endif
660  ttval = (int)tval & (cm+l)->mask;
661  tarr = (int) *(pinfo->array+i) & (cm+l)->mask;
662  if (*(pinfo->array+i) == -2.f) tarr = 0; // hide setup flag
663  if (( ttval != tarr)||(*(pinfo->array+i) == -2.f)) {
664  char *tpost,*tposa;
665  tpost = tposa = NULL;
666 
667  sm = (cm+l)->sm;
668  for (m = 0; m < (cm+l)->nm; m++) {
669  if (!(sm+m)) continue;
670  // cm_msg(MLOG,"","check Value 0x%4.4X : \"%s\"",
671  // (sm+m)->value, (sm+m)->msg);
672  if ((sm+m)->value == ttval) {
673  if (tpost) cm_msg(MLOG,"","New value: %s overwritten"
674  " by %s", tpost, (sm+m)->msg);
675  tpost = (sm+m)->msg;
676  }
677  if ((sm+m)->value == tarr) {
678  if (tposa) cm_msg(MLOG,"","Prev value: %s overwritten"
679  " by %s", tposa, (sm+m)->msg);
680  tposa = (sm+m)->msg;
681  }
682  } // for all values
683 
684  if (tpost) {
685  if (*(pinfo->array+i) == -2.f) tposa = NULL;//hide setup
686  if (tposa) {
687  cm_msg(MLOG,"","%s: \"%s\" changed to \"%s\"",
689  tposa, tpost);
690  } else {
691  if (strstr(pinfo->settings.channel_names+
692  CHN_NAME_LENGTH*i,":STA:")) {
693  cm_msg(MLOG,"","%s: Current status is \"%s\"",
695  tpost);
696  } else if (strstr(pinfo->settings.channel_names+
697  CHN_NAME_LENGTH*i,":COM:")) {
698 #ifdef MIDEBUG
699  cm_msg(MLOG,"","%s: Current RAW command is \"%s\"",
701  tpost);
702 #else
703  // DO NOTHING
704 #endif
705  } else {
706  cm_msg(MLOG,"","%s: \"%s\" is currently set",
708  tpost);
709  }
710  }
711  } else {
712  // NIY nothing assigned to mask
713  }
714  }
715  } // for all masks
716  break;
717  }
718  } // for all channels of this type
719  break;
720  }
721  } // for all GFA types
722  }
723 #endif
724  // First reading after connection was down
725  if (*(pinfo->firstread+i)) {
726  // R-flag is set
727  if (strchr(pinfo->settings.chnflags+CHNFLAGS_LENGTH*i,'R')) {
728  // demand value and readout of this channel are different
729  // send demand again
730  if (*(pinfo->demand+i) != tval) {
731  cm_msg(MLOG,"","Channel %d(%s) UP again. Demand may not have been"
732  " set and R(eset) flag set -> Setting demand %f again",i,
734  *(pinfo->demand+i));
735  // for this channel and dependent channels when PNZV flags set
736  // force setting demand value
737  epics_ca_set(pinfo,i,*(pinfo->demand+i),FALSE,TRUE);
738  }
739  }
740  *(pinfo->firstread+i) = FALSE;
741  }
742  *(pinfo->array+i) = tval;
743  }
744  }
745  } else {
746  cm_msg(MERROR,"epics_ca_event_handler","Channel %d(%s): NULL pointer to "
747  "data returned as dbr argument!", i,
749  }
750  } else {
751 #ifdef MIDEBUG
752  cm_msg(MLOG,"","epics_ca_event_handler: channel %d(%s): Unsupported data "
753  "type %s", i, pinfo->settings.channel_names+CHN_NAME_LENGTH*i,
754  dbr_type_to_text(args.type));
755 #endif
756  }
757  found = TRUE;
758  break;
759  }
760  }
761  }
762 
763  if (!found && (args.status != ECA_NORMAL)) {
764  cm_msg(MERROR,"epics_ca_event_handler","WARNING Status %d = \"%s\"", args.status,
765  ca_message(args.status));
766  }
767 #ifdef MIDEBUGE1
768  cm_msg(MLOG,"","--epics_ca_event_handler()");
769 #endif
770 #ifdef MIDEBUGF
771  if (fp) fprintf(fp,"%u : --epics_ca_event_handler()\n", ss_time());
772 #endif
773 }
void epics_ca_exception_handler ( struct exception_handler_args  eargs)

Definition at line 421 of file epics_ca.c.

References buf, and sprintf().

Referenced by epics_ca_init().

421  {
422  char buf[512];
423  char *pname;
424 
425 #ifdef MIDEBUGF
426  if (fp) fprintf(fp,"%u : ++epics_ca_exception_handler()\n", ss_time());
427 #endif
428 #ifdef MIDEBUG1
429  cm_msg(MLOG,"","++epics_ca_exception_handler()");
430 #endif
431  if (eargs.chid) {
432  sprintf(buf,"%s - chan=%s op=%d data_type = %s count=%d",
433  eargs.ctx, ca_name(eargs.chid), eargs.op, dbr_type_to_text(eargs.type),
434  eargs.count);
435  } else {
436  sprintf(buf,"%s - op=%d", eargs.ctx, eargs.op);
437  }
438  cm_msg(MLOG,"","Status: %d EXCEPTION: %s",eargs.stat,buf);
439  ca_signal(eargs.stat, buf);
440 
441 #ifdef MIDEBUG1
442  cm_msg(MLOG,"","--epics_ca_exception_handler()");
443 #endif
444 #ifdef MIDEBUGF
445  if (fp) fprintf(fp,"%u : --epics_ca_exception_handler()\n", ss_time());
446 #endif
447 }
INT epics_ca_exit ( CA_INFO info)

Definition at line 1837 of file epics_ca.c.

Referenced by epics_ca().

1837  {
1838  int i, status;
1839 
1840 #ifdef MIDEBUGF
1841  if (fp) fprintf(fp,"%u : ++epics_ca_exit()\n", ss_time());
1842 #endif
1843 #ifdef MIDEBUG1
1844  cm_msg(MLOG,"","++epics_ca_exit()");
1845 #endif
1846 
1847  if (info) {
1848  // NOTE: not necessary to call ca_clear_subscription()
1849 
1850  // release channels and event subscription
1851  for (i = 0; i < info->num_channels; i++) {
1852  if (*(info->pchid+i)) {
1853  status = ca_clear_channel(*(info->pchid+i));
1854  if (!(status & ECA_NORMAL))
1855  cm_msg(MERROR, "epics_ca_init", "Channel %d(%s): ca_clear_channel() returned "
1856  "status 0X%x = \"%s\"",i,
1858  status, ca_message(status));
1859  }
1860  }
1861  status = ca_pend_io(1.0);
1862 #ifdef MIDEBUGP
1863  cm_msg(MLOG,"","ca_pend_io(1.0) status 0X%x = \"%s\"", status, ca_message(status));
1864 #endif
1865  status = ca_pend_event(1.0);
1866 #ifdef MIDEBUGP
1867  cm_msg(MLOG,"","ca_pend_event(1.0)");
1868 #endif
1869  }
1870 
1871  // close channel access
1872  ca_context_destroy();
1873 
1874  // free arrays
1875  if (info) {
1876  if (info->settings.channel_names) { free(info->settings.channel_names);
1877  info->settings.channel_names = NULL; }
1878 #ifdef GFA_SPECIFIC
1879  if (info->settings.dtype) { free(info->settings.dtype);
1880  info->settings.dtype = NULL; }
1881  if (info->settings.dsec) { free(info->settings.dsec);
1882  info->settings.dsec = NULL; }
1883 #endif
1884  if (info->settings.chnflags) { free(info->settings.chnflags);
1885  info->settings.chnflags = NULL; }
1886  if (info->settings.minval) { free(info->settings.minval);
1887  info->settings.minval = NULL; }
1888  if (info->settings.maxval) { free(info->settings.maxval);
1889  info->settings.maxval = NULL; }
1890  if (info->settings.tolerance) { free(info->settings.tolerance);
1891  info->settings.tolerance = NULL; }
1892  if (info->settings.used) { free(info->settings.used);
1893  info->settings.used = NULL; }
1894  if (info->settings.readonly) { free(info->settings.readonly);
1895  info->settings.readonly = NULL; }
1896 
1897  if (info->pchid) { free(info->pchid); info->pchid = NULL; }
1898  if (info->array) { free(info->array); info->array = NULL; }
1899  if (info->array_m) { free(info->array_m); info->array_m = NULL; }
1900  if (info->demand) { free(info->demand); info->demand = NULL; }
1901  if (info->lastset) { free(info->lastset); info->lastset = NULL; }
1902  if (info->lastget) { free(info->lastget); info->lastget = NULL; }
1903  if (info->status) { free(info->status); info->status = NULL; }
1904  if (info->found) { free(info->found); info->found = NULL; }
1905  if (info->iscmd) { free(info->iscmd); info->iscmd = NULL; }
1906  if (info->subscribed) { free(info->subscribed); info->subscribed = NULL; }
1907  if (info->down) { free(info->down); info->down = NULL; }
1908  if (info->firstread) { free(info->firstread); info->firstread = NULL; }
1909  if (info->nerr) { free(info->nerr); info->nerr = NULL; }
1910  if (info->nmsg) { free(info->nmsg); info->nmsg = NULL; }
1911  if (info->tolchan) { free(info->tolchan); info->tolchan = NULL; }
1912  if (info->gchan) { free(info->gchan); info->gchan = NULL; }
1913  if (info->intol) { free(info->intol); info->intol = NULL; }
1914  if (info->threshold) { free(info->threshold); info->threshold = NULL; }
1915 
1916  free(info);
1917  }
1918 
1919 #ifdef MIDEBUG1
1920  cm_msg(MLOG,"","--epics_ca_exit()");
1921 #endif
1922 
1923 #ifdef MIDEBUGF
1924  if (fp) {
1925  fprintf(fp,"%u : --epics_ca_exit()\n",ss_time());
1926  fclose(fp);
1927  fp = NULL;
1928  }
1929 #endif
1930 
1931  return FE_SUCCESS;
1932 }
INT epics_ca_get ( CA_INFO info,
INT  channel,
float *  pvalue 
)

Definition at line 2384 of file epics_ca.c.

Referenced by epics_ca(), and epics_ca_get_all().

2384  {
2385  int status;
2386 #ifdef MIDEBUGF
2387  if (fp) fprintf(fp,"%u : ++epics_ca_get(channel=%d(%s))\n", ss_time(),channel,
2389 #endif
2390 #ifdef MIDEBUG2
2391  cm_msg(MLOG,""," ++epics_ca_get(channel %d)",channel);
2392 #endif
2393 
2394  // NOTE: pending events will be handled in event handler callback
2395 
2396  if (channel == 0) {
2397  if (info->num_channels > 50) {
2398 #ifdef MIDEBUGP
2399  cm_msg(MLOG,"","ca_pend_event(0.01)");
2400 #endif
2401  ca_pend_event(0.01);
2402  } else {
2403 #ifdef MIDEBUG2
2404  cm_msg(MLOG,"","ss_sleep(50)");
2405 #endif
2406  ss_sleep(50);
2407 #ifdef MIDEBUGP
2408  cm_msg(MLOG,"","ca_pend_event(0.1)");
2409 #endif
2410  ca_pend_event(0.1);
2411  }
2412  status = ca_pend_io(0.001);
2413 #ifdef MIDEBUGP
2414  cm_msg(MLOG,"","ca_pend_io(0.001) status 0X%x =\"%s\"",status,ca_message(status));
2415 #endif
2416  } else {
2417  ca_pend_event(0.001);
2418  }
2419 
2420  // return last value
2421  if (*(info->found+channel)) {
2422  if (ca_state(*(info->pchid+channel)) == cs_conn) {
2423  if (ca_read_access(*(info->pchid+channel))) {
2424  float newdemand;
2425 
2426  newdemand = *(info->demand+channel);
2427  // process and then get demand value and also update array_m of dependent chans
2428  epics_ca_get_demand(info, channel, &newdemand);
2429  if (pvalue) *pvalue = *(info->array_m+channel);
2430 
2431  if (newdemand != *(info->demand+channel)) {
2432  // difference of DWORD not negative due to change of system time?
2433  if (ss_time() > *(info->lastset+channel)) {
2434  // if ((ss_time() - *(info->lastset+channel)) > 60) {
2435  if ((ss_time() - *(info->lastset+channel)) > 2) {
2436 
2437  if (*(info->iscmd+channel)) {
2438  if (*(info->demand+channel) != -2.f)
2439  cm_msg(MLOG, "", "Channel %d(%s): demand (%f) changed to %f", channel,
2441  *(info->demand+channel),newdemand);
2442  else
2443  cm_msg(MLOG, "", "Channel %d(%s): current demand is %f", channel,
2444  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2445  newdemand);
2446  }
2447 
2448  if ((*(info->iscmd+channel)) && ((*(info->gchan+channel) > 0) ||
2449  (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'F')!=NULL))){
2450  int size;
2451  HNDLE hDB;
2452 #ifdef GFA_SPECIFIC
2453  BOOL oldflag;
2454 #endif
2455 
2456 #ifdef GFA_SPECIFIC
2457  oldflag = info->handling_disabled;
2458  // maybe disable handling of GFA specific
2459  // info->handling_disabled = TRUE;
2460 #endif
2461  // F flag: set new demand value (limits may be checked and set)
2462  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'F')!=NULL){
2463  DWORD lastset;
2464  // NOTE: ...ca_set() sets *(info->demand+channel) to newdemand
2465  // and puts new value to "command" channel
2466  lastset = *(info->lastset+channel); // keep lastset time
2467  epics_ca_set(info,channel,newdemand,TRUE,FALSE);
2468  *(info->lastset+channel) = lastset; // restore lastset
2469  } else {
2470  // G flag: "status" feedback therefore not necessary to put newdemand
2471  // to "command" channel again
2472  *(info->demand+channel) = newdemand;
2473  }
2474 #ifdef GFA_SPECIFIC
2475  info->handling_disabled = oldflag;
2476 #endif
2477 
2478 #ifndef OMIT_ODBUPDATE
2479  // update ODB Demand
2480  size = sizeof(float);
2481  cm_get_experiment_database(&hDB, NULL);
2482  if (info->hkeyDemand != 0) {
2483  INT mstatus;
2484  mstatus = db_set_data_index(hDB,info->hkeyDemand, &newdemand,
2485  size, channel, TID_FLOAT);
2486  if (mstatus != DB_SUCCESS) ; // NIY message
2487  }
2488 #endif
2489  } else
2490  *(info->demand+channel) = newdemand;
2491  *(info->lastset+channel) = ss_time();
2492  }
2493  } else {
2494  *(info->lastset+channel) = ss_time();
2495  }
2496  }
2497  *(info->nmsg+channel) = 0;
2498  } else {
2499  if (*(info->nmsg+channel) == 0) {
2500  cm_msg(MLOG, "", "Channel %d(%s): NO read access!", channel,
2501  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2502  *(info->nmsg+channel) += 1;
2503  }
2504  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'D') && pvalue)
2505  *pvalue = -1.f;
2506  }
2507  } else {
2508  if (*(info->nmsg+channel) == 0) {
2509  cm_msg(MLOG, "", "Channel %d(%s): NOT connected!", channel,
2510  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2511  *(info->nmsg+channel) += 1;
2512  }
2513  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'D') && pvalue)
2514  *pvalue = -1.f;
2515  }
2516  } else {
2517  if (*(info->nmsg+channel) == 0) {
2518  if (*(info->settings.used+channel))
2519  cm_msg(MLOG, "", "Channel %d(%s): NOT found!", channel,
2520  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2521  *(info->nmsg+channel) += 1;
2522  }
2523  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'D') && pvalue)
2524  *pvalue = -1.f;
2525  }
2526 
2527  // after all channels were processed once
2528  if (channel == info->num_channels-1) {
2529  // check every 10 seconds
2530  if ((ss_time() > info->lastSNC) && ((ss_time() - info->lastSNC) > 10)) {
2531  int i,tSNC;
2532 #ifdef MIDEBUG1
2533  cm_msg(MLOG,"","C-flag: Checking if channels with C-flag are connected");
2534 #endif
2535  for (i=0,tSNC=0; i < info->num_channels; i++) {
2536  // if (*(info->found+i)&&*(info->settings.used+i)&&!*(info->settings.readonly+i)&&
2537  if ( *(info->settings.used+i) &&
2538  (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'C')) && *(info->down+i)){
2539 #ifdef MIDEBUG
2540  cm_msg(MLOG,"","C-flag: Channel %d (%s) is currently not connected",i,
2542 #endif
2543  tSNC++;
2544  }
2545  }
2546 
2547  if (tSNC != info->settings.Sum_NOT_Connected) {
2548  cm_msg(MLOG,"","Number of Channels (with C-flag) NOT connected changed from "
2549  "%d to %d", info->settings.Sum_NOT_Connected, tSNC);
2550  info->settings.Sum_NOT_Connected = tSNC;
2551  // update ODB when different
2552  if (info->hkeySNC) {
2553  HNDLE hDB;
2554  cm_get_experiment_database(&hDB, NULL);
2555  db_set_data(hDB, info->hkeySNC, &info->settings.Sum_NOT_Connected,
2556  sizeof(int), 1, TID_INT);
2557  }
2558  // reset alarm when sum is 0
2559  if ((tSNC==0) && (strncmp(info->settings.AlarmWhenNOTConnected,"NONE",4) != 0))
2560  al_reset_alarm(info->settings.AlarmWhenNOTConnected);
2561  }
2562 
2563  info->lastSNC = ss_time();
2564 
2565  } else if (ss_time() < info->lastSNC) {
2566  cm_msg(MLOG,"","Sum of channels NOT connected: System time was reset");
2567  info->lastSNC = ss_time();
2568  }
2569 
2570 #ifdef GFA_SPECIFIC
2571  // check every 10 seconds
2572  if ((ss_time() > info->lastSNT) && ((ss_time() - info->lastSNT) > 10)) {
2573  int i,tSNT;
2574  BOOL *handled;
2575 #ifdef MIDEBUG
2576  cm_msg(MLOG,"","T-flag: Checking if channels with T-flag are in tolerance");
2577 #endif
2578  handled = calloc(info->num_channels,sizeof(BOOL));
2579  for (i=0,tSNT=0; i < info->num_channels; i++) {
2580  // T flag set, not handled yet and tolerance > 0
2581  // if (*(info->found+i)&&*(info->settings.used+i)&&!*(info->settings.readonly+i)&&
2582  if ( *(info->settings.used+i) &&
2583  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'T') &&
2584  (!handled || !*(handled+i)) && (*(info->settings.tolerance+i)>0.f)){
2585  if (*(info->tolchan+i) == -1.f) {
2586  char tename[CHN_NAME_LENGTH];
2587  int j;
2588  BOOL findrefchan;
2589  char *ds;
2590  char *tpos;
2591 
2592  findrefchan = TRUE;
2593  strcpy(tename,info->settings.channel_names+CHN_NAME_LENGTH*i);
2594 
2595  ds = info->settings.dtype+DTYPE_LENGTH*i;
2596 #ifdef MIDEBUG2
2597  cm_msg(MLOG,"","Looking for device specific handling of Device type %s",ds);
2598 #endif
2599  if ((strcmp(ds,"BEND")==0) || (strcmp(ds,"QUAD")==0) ||
2600  (strcmp(ds,"SEPT")==0) || (strcmp(ds,"STER")==0) ||
2601  (strcmp(ds,"PS" )==0) ||
2602  (strcmp(ds,"TS" )==0) || (strcmp(ds,"KICKER")==0)) {
2603 
2604 #ifdef MIDEBUG2
2605  cm_msg(MLOG,"","T-flag: Device type %s found",ds);
2606 #endif
2607  // assign corresponding channel
2608  if ((tpos = strstr(tename,":SOL:2")) != NULL) {
2609  strcpy(tpos,":IST:2");
2610  } else if ((tpos = strstr(tename,":IST:2")) != NULL) {
2611  strcpy(tpos,":SOL:2");
2612  } else {
2613  cm_msg(MLOG,"","T-flag: Channel %d (%s) not handled for type %s", i,
2615  findrefchan = FALSE;
2616  }
2617  } else if (strcmp(ds,"FENTE")==0) {
2618  // assign corresponding channel
2619  if ((tpos = strstr(tename,":SOL:2")) != NULL) {
2620  strcpy(tpos,":IST1:2");
2621  } else if ((tpos = strstr(tename,":IST1:2")) != NULL) {
2622  strcpy(tpos,":SOL:2");
2623  } else if ((tpos = strstr(tename,":POSA:2")) != NULL) {
2624  strcpy(tpos,":SOL:2");
2625  } else {
2626  cm_msg(MLOG,"","T-flag: Channel %d (%s) not handled for type %s", i,
2628  findrefchan = FALSE;
2629  }
2630  } else if (strcmp(ds,"BX")==0) {
2631  // DO NOTHING
2632  findrefchan = FALSE;
2633  } else if (strcmp(ds,"HVPS")==0) {
2634  // assign corresponding channel NOTE: I(max) has no tolerance!
2635  if ((tpos = strstr(tename,":SOLV:2")) != NULL) {
2636  strcpy(tpos,":ISTV:2");
2637  } else if ((tpos = strstr(tename,":ISTV:2")) != NULL) {
2638  strcpy(tpos,":SOLV:2");
2639  } else {
2640  cm_msg(MLOG,"","T-flag: Channel %d (%s) not handled for type %s", i,
2642  findrefchan = FALSE;
2643  }
2644  } else {
2645  cm_msg(MLOG,"","T-flag: Channel %d (%s) type %s is not handled", i,
2647  findrefchan = FALSE;
2648  }
2649 
2650  if (findrefchan) {
2651 #ifdef MIDEBUG1
2652  cm_msg(MLOG,"","T-flag: Searching for channel %s",tename);
2653 #endif
2654  for (j=0; j < info->num_channels; j++) {
2655  if (i != j) {
2656  if (strcmp(tename,info->settings.channel_names+CHN_NAME_LENGTH*j)==0){
2657  *(info->tolchan+i) = j;
2658  // NIY if (*(info->tolchan+j) > 0) warning channel was already
2659  // assigned
2660  *(info->tolchan+j) = i;
2661  break;
2662  }
2663  }
2664  } // for all (other) channels
2665  } else {
2666  *(info->tolchan+i) = -2.f; // mark as already processed
2667  }
2668  } // search for corresponding channels
2669 
2670  if (*(info->tolchan+i) > 0) { // tolerance needs to be checked
2671  float tvali,tvalr,diff;
2672  int j;
2673  BOOL omit;
2674 
2675  omit = FALSE;
2676  j = *(info->tolchan+i);
2677  if (*(info->iscmd+i)) {
2678  tvali = *(info->demand+i);
2679  tvalr = *(info->array+j);
2680  // exceptions?
2681  // N flag: Power Off when Negative -> omit
2682  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'N')&&(tvali < 0.f))
2683  omit = TRUE;
2684  } else {
2685  tvali = *(info->array+i);
2686  tvalr = *(info->demand+j);
2687  // exceptions?
2688  // N flag: Power Off when Negative -> omit
2689  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*j,'N')&&(tvalr < 0.f))
2690  omit = TRUE;
2691  }
2692 
2693  diff = tvali - tvalr;
2694  if (diff < 0.f) diff = -diff;
2695  if (diff > *(info->settings.tolerance+i)) {
2696  if (!omit) {
2697  if (*(info->intol+i) || *(info->intol+j)) {
2698  cm_msg(MLOG,"","Channel %d (%s)=%f and Channel %d (%s)=%f : "
2699  "difference %f is out of tolerance %f",
2700  i,info->settings.channel_names+CHN_NAME_LENGTH*i,tvali,
2701  j,info->settings.channel_names+CHN_NAME_LENGTH*j,tvalr,
2702  diff, *(info->settings.tolerance+i));
2703  *(info->intol+i) = FALSE;
2704  *(info->intol+j) = FALSE;
2705  }
2706  tSNT++;
2707  }
2708  } else {
2709 #ifdef MIDEBUG1
2710  cm_msg(MLOG,"","Channel %d (%s)=%f and Channel %d (%s)=%f : "
2711  "difference %f is in tolerance %f",
2712  i,info->settings.channel_names+CHN_NAME_LENGTH*i,tvali,
2713  j,info->settings.channel_names+CHN_NAME_LENGTH*j,tvalr,
2714  diff, *(info->settings.tolerance+i));
2715 #endif
2716  *(info->intol+i) = TRUE;
2717  *(info->intol+j) = TRUE;
2718  }
2719 
2720  if (handled) {
2721  *(handled+i) = TRUE;
2722  *(handled+j) = TRUE;
2723  }
2724 
2725  }
2726  } else {
2727 #ifdef MIDEBUG
2728  if (!*(info->settings.used+i))
2729  cm_msg(MLOG,"","Channel %d (%s): not used",i,
2731  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'T') == NULL)
2732  cm_msg(MLOG,"","Channel %d (%s): T flag not set",i,
2734  if (handled && *(handled+i))
2735  cm_msg(MLOG,"","Channel %d (%s): already handled",i,
2737  if (*(info->settings.tolerance+i)<=0.f)
2738  cm_msg(MLOG,"","Channel %d (%s): invalid tolerance %f", i,
2740  *(info->settings.tolerance+i));
2741 #endif
2742  } // channel used?
2743  } // for all channels
2744 
2745  if (info->pending > 0) {
2746  tSNT += info->pending;
2747  }
2748 
2749  if (info->settings.Sum_NOT_in_Tolerance != tSNT) {
2750  // pending operations, tolerance check is not reliable
2751  if ((info->pending > 0) && (info->pending == tSNT)) {
2752  if (info->pending == 1)
2753  cm_msg(MLOG,"","Pending operation -> In Range checking blocked");
2754  else
2755  cm_msg(MLOG,"","%d Pending operations -> In Range checking blocked",
2756  info->pending);
2757 
2758  } else {
2759  if (tSNT != 0)
2760  cm_msg(MLOG,"","Number of Channels (T) NOT in Tolerance Range changed "
2761  "from %d to %d", info->settings.Sum_NOT_in_Tolerance, tSNT);
2762  else
2763  cm_msg(MLOG,"","All Channels (T) in Tolerance Range");
2764  }
2765  info->settings.Sum_NOT_in_Tolerance = tSNT;
2766  // update ODB when different
2767  if (info->hkeySNT) {
2768  HNDLE hDB;
2769  cm_get_experiment_database(&hDB, NULL);
2770  db_set_data(hDB,info->hkeySNT,&info->settings.Sum_NOT_in_Tolerance,
2771  sizeof(int),1,TID_INT);
2772  }
2773  // reset alarm when sum is 0
2774  if ((tSNT==0)&&(strncmp(info->settings.AlarmWhenNOTinTolerance,"NONE",4) != 0))
2775  al_reset_alarm(info->settings.AlarmWhenNOTinTolerance);
2776  }
2777 
2778  info->lastSNT = ss_time();
2779  if (handled) { free(handled); handled = NULL;}
2780 
2781  } else if (ss_time() < info->lastSNT) {
2782  cm_msg(MLOG,"","Sum of channels NOT in Tolerance: System time was reset");
2783  info->lastSNT = ss_time();
2784  }
2785 #endif /* #ifdef GFA_SPECIFIC */
2786  }
2787 
2788 #ifdef MIDEBUG2
2789  if (pvalue)
2790  cm_msg(MLOG,""," --epics_ca_get(value = %f)",*pvalue);
2791  else
2792  cm_msg(MLOG,""," --epics_ca_get(NULL pointer to return data)");
2793 #endif
2794 #ifdef MIDEBUGF
2795  if (fp) {
2796  if (pvalue)
2797  fprintf(fp,"%u : --epics_ca_get(channel=%d(%s), value=%f)\n", ss_time(), channel,
2798  info->settings.channel_names+CHN_NAME_LENGTH*channel, *pvalue);
2799  else
2800  fprintf(fp,"%u : --epics_ca_get(channel=%d, NULL pointer to return data)\n",
2801  ss_time(), channel);
2802  }
2803 #endif
2804  return FE_SUCCESS;
2805 }
INT epics_ca_get_all ( CA_INFO info,
INT  channels,
float *  pvalue 
)

Definition at line 3083 of file epics_ca.c.

Referenced by epics_ca().

3083  {
3084  int i;
3085 
3086 #ifdef MIDEBUG1
3087  cm_msg(MLOG,""," ++epics_ca_get_all(%d channels)", channels);
3088 #endif
3089  for (i = 0; i < MIN(info->num_channels, channels); i++)
3090  epics_ca_get(info, i, pvalue + i);
3091 
3092 #ifdef MIDEBUG1
3093  cm_msg(MLOG,""," --epics_ca_get_all()");
3094 #endif
3095  return FE_SUCCESS;
3096 }
INT epics_ca_get_default_name ( CA_INFO info,
INT  channel,
char *  name 
)

Definition at line 3099 of file epics_ca.c.

References CA_SETTINGS::channel_names, CHN_NAME_LENGTH, and CA_INFO::settings.

Referenced by epics_ca().

3099  {
3100 #ifdef MIDEBUG1
3101  cm_msg(MLOG,""," ++epics_ca_get_default_name(channel %d, name %s)", channel, name);
3102 #endif
3103  if ((name != NULL) && (channel >= 0) && (channel< info->num_channels)) {
3104  strcpy(name, info->settings.channel_names + CHN_NAME_LENGTH * channel);
3105  }
3106 #ifdef MIDEBUG1
3107  cm_msg(MLOG,""," --epics_ca_get_default_name(channel %d, name %s)", channel, name);
3108 #endif
3109  return FE_SUCCESS;
3110 }
INT epics_ca_get_default_threshold ( CA_INFO info,
INT  channel,
float *  pvalue 
)

Definition at line 3114 of file epics_ca.c.

References channel, and CA_INFO::threshold.

Referenced by epics_ca().

3114  {
3115 
3116 #ifdef MIDEBUG1
3117  cm_msg(MLOG,""," ++epics_ca_get_default_threshold(channel %d)", channel);
3118 #endif
3119  if (pvalue != NULL) {
3120  *pvalue = 0.1f;
3121  if (info->threshold && (channel >= 0) && (channel < info->num_channels))
3122  *pvalue = *(info->threshold+channel);
3123  }
3124 #ifdef MIDEBUG1
3125  if (pvalue)
3126  cm_msg(MLOG,""," --epics_ca_get_default_threshold(channel %d, threshold %f)",
3127  channel, *pvalue);
3128 #endif
3129  return FE_SUCCESS;
3130 }
INT epics_ca_get_demand ( CA_INFO info,
INT  channel,
float *  pvalue 
)

Definition at line 2812 of file epics_ca.c.

References CA_INFO::array, CA_INFO::array_m, channel, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, FALSE, CA_INFO::gchan, CA_INFO::iscmd, CA_INFO::num_channels, CA_INFO::settings, and TRUE.

Referenced by epics_ca(), epics_ca_get(), and epics_ca_init().

2812  {
2813 #ifdef MIDEBUGF
2814  if (fp) fprintf(fp,"%u : ++epics_ca_get_demand(channel=%d(%s))\n", ss_time(), channel,
2816 #endif
2817 #ifdef MIDEBUG1
2818  cm_msg(MLOG,""," ++epics_ca_get_demand(channel %d)",channel);
2819 #endif
2820 
2821  if (info) {
2822  if (channel < info->num_channels) {
2823 
2824  // channel number of dependent channel is not initialized yet
2825  // search for channel
2826  if (*(info->gchan+channel) == -1.f) {
2827  char tename[CHN_NAME_LENGTH];
2828  int j;
2829  BOOL findrefchan;
2830  char *ds;
2831  char *tpos;
2832 
2833  findrefchan = TRUE;
2834  strcpy(tename,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2835 
2836  ds = info->settings.dtype+DTYPE_LENGTH*channel;
2837 #ifdef MIDEBUG2
2838  cm_msg(MLOG,"","G-flag: search Looking for device specific handling of Device "
2839  "type %s", ds);
2840 #endif
2841  if ((strcmp(ds,"BEND")==0) || (strcmp(ds,"QUAD")==0) ||
2842  (strcmp(ds,"SEPT")==0) || (strcmp(ds,"STER")==0) ||
2843  (strcmp(ds,"PS" )==0) || (strcmp(ds,"TS" )==0) ||
2844  (strcmp(ds,"KICKER")==0) ) {
2845 
2846 #ifdef MIDEBUG2
2847  cm_msg(MLOG,"","G-flag: Device type %s found",ds);
2848 #endif
2849  // assign corresponding channel
2850  if ((tpos = strstr(tename,":COM:2")) != NULL) {
2851  strcpy(tpos,":STA:1");
2852  } else if ((tpos = strstr(tename,":STA:1")) != NULL) {
2853  strcpy(tpos,":COM:2");
2854  } else if ((tpos = strstr(tename,":SOL:2")) != NULL) {
2855  findrefchan = FALSE;
2856  } else if ((tpos = strstr(tename,":IST:2")) != NULL) {
2857  findrefchan = FALSE;
2858  } else {
2859  cm_msg(MLOG,"","G-flag: search Channel %d (%s) not handled for type %s",
2860  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel,ds);
2861  findrefchan = FALSE;
2862  }
2863 
2864  } else if (strcmp(ds,"FENTE")==0) {
2865  // assign corresponding channel
2866  if ((tpos = strstr(tename,":COM:2")) != NULL) {
2867  strcpy(tpos,":STA:1");
2868  } else if ((tpos = strstr(tename,":STA:1")) != NULL) {
2869  strcpy(tpos,":COM:2");
2870  } else if ((tpos = strstr(tename,":SOL:2")) != NULL) {
2871  strcpy(tpos,":IST1:2");
2872  } else if ((tpos = strstr(tename,":IST1:2")) != NULL) {
2873  strcpy(tpos,":SOL:2");
2874  } else if ((tpos = strstr(tename,":POSA:2")) != NULL) {
2875  strcpy(tpos,":SOL:2");
2876  } else {
2877  cm_msg(MLOG,"","G-flag: search Channel %d (%s) not handled for type %s",
2878  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel,ds);
2879  findrefchan = FALSE;
2880  }
2881 
2882  } else if (strcmp(ds,"BX")==0) {
2883  if ((tpos = strstr(tename,":COM:2")) != NULL) {
2884  strcpy(tpos,":STA:1");
2885  } else if ((tpos = strstr(tename,":STA:1")) != NULL) {
2886  strcpy(tpos,":COM:2");
2887  } else {
2888  cm_msg(MLOG,"","G-flag: search Channel %d (%s) not handled for type %s",
2889  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel,ds);
2890  findrefchan = FALSE;
2891  }
2892 
2893  } else if (strcmp(ds,"HVPS")==0) {
2894  // DO NOTHING (no G-flags)
2895  findrefchan = FALSE;
2896  } else {
2897  if (strncmp(ds,"**",2) != 0)
2898  cm_msg(MLOG,"","G-flag: search Channel %d (%s) type %s is not handled",
2899  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel,ds);
2900  findrefchan = FALSE;
2901  }
2902 
2903  if (findrefchan) {
2904 #ifdef MIDEBUG1
2905  cm_msg(MLOG,"","G-flag: search Searching for channel %s",tename);
2906 #endif
2907  for (j=0; j < info->num_channels; j++) {
2908  if (channel != j) {
2909  if (strcmp(tename,info->settings.channel_names+CHN_NAME_LENGTH*j)==0){
2910  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'G') ||
2911  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*j,'G')) {
2912  *(info->gchan+channel) = j;
2913  // NIY if (*(info->gchan+j) > 0) warning channel was already
2914  // assigned to channel ...
2915  *(info->gchan+j) = channel;
2916  break;
2917  }
2918  }
2919  }
2920  } // for all (other) channels
2921 
2922  if (*(info->gchan+channel) < 0) {
2923  cm_msg(MLOG,"","G-flag: search Channel corresponding to %d (%s) NOT found!",
2924  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel);
2925  *(info->gchan+channel) = -2.f; // mark as already processed
2926  }
2927  } else {
2928  *(info->gchan+channel) = -2.f; // mark as already processed
2929  }
2930  } // search for corresponding channels
2931 
2932  // command/setpoint channel?
2933  if (*(info->iscmd+channel)) {
2934  if (*(info->gchan+channel) > 0) {
2935  char *ds;
2936  char *tpos;
2937  int gchan;
2938 
2939  gchan = *(info->gchan+channel);
2940  ds = info->settings.dtype+DTYPE_LENGTH*channel;
2941 #ifdef MIDEBUG2
2942  cm_msg(MLOG,"","G-flag: command/setpoint channel: Looking for device "
2943  "specific handling of Device type %s",ds);
2944 #endif
2945  if ((strcmp(ds,"BEND")==0) || (strcmp(ds,"QUAD")==0) ||
2946  (strcmp(ds,"SEPT")==0) || (strcmp(ds,"STER")==0) ||
2947  (strcmp(ds,"PS" )==0) ||
2948  (strcmp(ds,"TS" )==0) || (strcmp(ds,"KICKER")==0)) {
2949 
2950  // update COM:2 reading STA:1 for KombiPS1 or MultiIO
2951  if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*channel,":COM:2")) {
2952  INT tval;
2953  tval = (int) *(info->array+gchan);
2954  // Status is ON : 0x0005 ("Soll ON" : 0x0001 and (|) "Ist ON" : 0x0004)
2955  if ((tval & 0x0005) == 0x0005) {
2956  if (*(info->array_m+channel) != 0.f) {
2957  if (*(info->array_m+channel) != -2.f)
2958  cm_msg(MLOG,"","%d(%s): Command changed to \"ON\"", channel,
2959  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2960  else
2961  cm_msg(MLOG,"","%d(%s): Current Command is \"ON\"", channel,
2962  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2963  *(info->array_m+channel) = 0.f; // command ON
2964  }
2965  } else { // everything NOT ON is OFF
2966  if (*(info->array_m+channel) != 1.f) {
2967  if (*(info->array_m+channel) != -2.f)
2968  cm_msg(MLOG,"","%d(%s): Command changed to \"OFF\"", channel,
2969  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2970  else
2971  cm_msg(MLOG,"","%d(%s): Current Command is \"OFF\"", channel,
2972  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2973  *(info->array_m+channel) = 1.f; // command OFF
2974  }
2975  }
2976  *(info->array_m+gchan) = *(info->array+gchan); // update :STA:1
2977  }
2978 
2979  } else if (strcmp(ds,"FENTE")==0) {
2980  if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*channel,":COM:2")) {
2981  int cur, prev;
2982  cur = (int) *(info->array +gchan);
2983  prev = (int) *(info->array_m+gchan);
2984  // when status changed maybe update COM:2 with info from STA:1
2985  if ((cur != prev)||(*(info->array_m+channel) == -2.f)) {
2986  // not moving anymore
2987  if (((cur & 0x0100) != 0x0100) && ((cur & 0x0200) != 0x0200)) {
2988  // stopped and NOT error
2989  if ((cur & 0x0004) && ((cur & 0x0003) != 0x0003)) {
2990  // not command STOP and not MOVE_TO_SOL?
2991  if ((*(info->array_m+channel) != (float) 0x0002) &&
2992  (*(info->array_m+channel) != (float) 0x0003)) {
2993  if (*(info->array_m+channel) != -2.f)
2994  cm_msg(MLOG,"","%d(%s): Command changed to \"STOP\"", channel,
2995  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2996  else
2997  cm_msg(MLOG,"","%d(%s): Current Command is \"STOP\"", channel,
2998  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2999  *(info->array_m+channel) = (float) 0x0002; // command STOP
3000  }
3001  }
3002  }
3003  }
3004  *(info->array_m+gchan) = *(info->array+gchan); // update :STA:1
3005  } else if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*channel,
3006  ":SOL:2")) {
3007  // NIY G-flag described in epics_ca_private.h should be handled here
3008  //
3009  // NIY SOL:2 and IST1 or POLA and :STA:1 - > maybe set SOL:2
3010  *(info->array_m+channel) = *(info->array+channel); // update :SOL:2
3011  *(info->array_m+gchan) = *(info->array+gchan); // update IST1 or POLA
3012  }
3013 
3014  } else if (strcmp(ds,"BX") == 0) {
3015  // update COM:2 reading STA:1 for BX
3016  if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*channel,":COM:2")) {
3017  INT tval;
3018  tval = (int) *(info->array+gchan);
3019  // Status is Open : 0x0001 or Closed : 0x0002
3020  if ((tval & 0x0001) == 0x0001) {
3021  if (*(info->array_m+channel) != 0.f) {
3022  if (*(info->array_m+channel) != -2.f)
3023  cm_msg(MLOG,"","%d(%s): Command changed to \"OPEN\"", channel,
3024  info->settings.channel_names+CHN_NAME_LENGTH*channel);
3025  else
3026  cm_msg(MLOG,"","%d(%s): Current Command is \"OPEN\"", channel,
3027  info->settings.channel_names+CHN_NAME_LENGTH*channel);
3028  *(info->array_m+channel) = 0.f; // command OPEN
3029  }
3030  } else { // NOT OPEN -> CLOSE
3031  if (*(info->array_m+channel) != 1.f) {
3032  if (*(info->array_m+channel) != -2.f)
3033  cm_msg(MLOG,"","%d(%s): Command changed to \"CLOSE\"", channel,
3034  info->settings.channel_names+CHN_NAME_LENGTH*channel);
3035  else
3036  cm_msg(MLOG,"","%d(%s): Current Command is \"CLOSE\"", channel,
3037  info->settings.channel_names+CHN_NAME_LENGTH*channel);
3038  *(info->array_m+channel) = 1.f; // command CLOSE
3039  }
3040  }
3041  *(info->array_m+gchan) = *(info->array+gchan); // update :STA:1
3042  }
3043  } else {
3044  cm_msg(MLOG,"","G-flag: command/setpoint Channel %d (%s) type %s is not han"
3045  "dled", channel, info->settings.channel_names+CHN_NAME_LENGTH*channel,ds);
3046  }
3047  } else {
3048  // no corresponding "status" channel -> mirror demand readout of channel
3049  *(info->array_m+channel) = *(info->array+channel);
3050  }
3051 
3052  if (pvalue) *pvalue = *(info->array_m+channel);
3053 
3054  // not a command channel
3055  } else {
3056  // and no corresponding command channel -> mirror readout of channel
3057  if (*(info->gchan+channel) < -1.f)
3058  *(info->array_m+channel) = *(info->array+channel);
3059  if (pvalue) *pvalue = 0.f; // NO demand value to return
3060  }
3061  }
3062  }
3063 #ifdef MIDEBUG1
3064  if (pvalue)
3065  cm_msg(MLOG,""," --epics_ca_get_demand(value = %f)",*pvalue);
3066  else
3067  cm_msg(MLOG,""," --epics_ca_get_demand(NULL pointer to return)");
3068 #endif
3069 #ifdef MIDEBUGF
3070  if (fp) {
3071  if (pvalue)
3072  fprintf(fp,"%u : --epics_ca_get_demand(channel=%d(%s), value=%f)\n", ss_time(),
3073  channel, info->settings.channel_names+CHN_NAME_LENGTH*channel, *pvalue);
3074  else
3075  fprintf(fp,"%u : --epics_ca_get_demand(channel=%d,NULL pointer to return demand)\n"
3076  ,ss_time(), channel);
3077  }
3078 #endif
3079  return FE_SUCCESS;
3080 }
INT epics_ca_init ( HNDLE  hKey,
void **  pinfo,
INT  channels 
)

Definition at line 777 of file epics_ca.c.

Referenced by epics_ca().

777  {
778  int status, i;
779  HNDLE hDB, subkey;
780  CA_INFO *info;
781  enum channel_state castate;
782  char tpath[MAX_ODB_PATH];
783  char *pnames;
784  BOOL loaded;
785 
786 #ifdef MIDEBUGF
787  sprintf(tpath,"EPICS_ca_%d.log",ss_time());
788  fp = fopen(tpath,"w");
789  if (fp) fprintf(fp,"%u : ++epics_ca_init(%d)\n",ss_time(),channels);
790 #endif
791 
792 #ifdef MIDEBUG1
793  cm_msg(MLOG,"","++epics_ca_init(init %d channels)",channels);
794 #ifdef MIDEBUGF
795  cm_msg(MLOG,"","ss_time()'ed Info written to %s",tpath);
796 #endif
797 #endif
798 
799  pnames = NULL;
800  loaded = FALSE;
801 
802  cm_get_experiment_database(&hDB, NULL);
803 
804  /* allocate info structure */
805  info = calloc(1, sizeof(CA_INFO));
806  *pinfo = info; // must be done first else core dump on error return
807 
808  /* check if necessary event variables are defined */
809  if (!getenv("EPICS_CA_AUTO_ADDR_LIST") || !getenv("EPICS_CA_ADDR_LIST") ||
810  !getenv("EPICS_CA_SERVER_PORT")) {
811  if (!getenv("EPICS_CA_AUTO_ADDR_LIST"))
812  cm_msg(MERROR, "epics_ca_init",
813  "Please define environment variable 'EPICS_CA_AUTO_ADDR_LIST'");
814  if (!getenv("EPICS_CA_ADDR_LIST"))
815  cm_msg(MERROR, "epics_ca_init",
816  "Please define environment variable 'EPICS_CA_ADDR_LIST'");
817  if (!getenv("EPICS_CA_SERVER_PORT"))
818  cm_msg(MERROR, "epics_ca_init",
819  "Please define environment variable 'EPICS_CA_SERVER_PORT'");
820  return FE_ERR_HW;
821  } else {
822  cm_msg(MLOG,"","EPICS_CA_AUTO_ADDR_LIST is %s",getenv("EPICS_CA_AUTO_ADDR_LIST"));
823  cm_msg(MLOG,"","EPICS_CA_ADDR_LIST is %s", getenv("EPICS_CA_ADDR_LIST"));
824  cm_msg(MLOG,"","EPICS_CA_SERVER_PORT is %s", getenv("EPICS_CA_SERVER_PORT"));
825  }
826 
827  // NIY check if caRepeater program is available
828 
829  info->num_channels = channels;
830 
831  /* initially disable all commands */
832  info->cmd_disabled = 1;
833 
834  /* initialize EPICS CA driver */
835  status = ca_context_create(ca_disable_preemptive_callback);
836  if (!(status & ECA_NORMAL)) {
837  cm_msg(MERROR, "epics_ca_init", "Unable to initialize! ca_context_create() "
838  "returned status 0X%x = \"%s\"",status,ca_message(status));
839  return FE_ERR_HW;
840  }
841 
842  status = ca_add_exception_event(epics_ca_exception_handler,0);
843  if (!(status & ECA_NORMAL))
844  cm_msg(MERROR, "epics_ca_init", "Unable to install global exception handler! "
845  "ca_add_exception_handler() returned status 0X%x = \"%s\"",
846  status,ca_message(status));
847 
848  /* allocate arrays */
850 #ifdef GFA_SPECIFIC
851  info->settings.dtype = calloc(channels, DTYPE_LENGTH);
852  info->settings.dsec = calloc(channels, DSEC_LENGTH);
853 #endif
854  info->settings.chnflags = calloc(channels, CHNFLAGS_LENGTH);
855  info->settings.minval = calloc(channels, sizeof(float));
856  info->settings.maxval = calloc(channels, sizeof(float));
857  info->settings.tolerance = calloc(channels, sizeof(float));
858  info->settings.used = calloc(channels, sizeof(BOOL));
859  info->settings.readonly = calloc(channels, sizeof(BOOL));
860 
861  info->array = calloc(channels, sizeof(float));
862  info->array_m = calloc(channels, sizeof(float));
863  info->demand = calloc(channels, sizeof(float));
864  info->threshold = NULL;
865  info->lastset = calloc(channels, sizeof(DWORD));
866  info->lastget = calloc(channels, sizeof(DWORD));
867  info->status = calloc(channels, sizeof(int));
868  info->pchid = calloc(channels, sizeof(chid));
869  info->found = calloc(channels, sizeof(BOOL));
870  info->iscmd = calloc(channels, sizeof(BOOL));
871  info->subscribed = calloc(channels, sizeof(BOOL));
872  info->down = calloc(channels, sizeof(BOOL));
873  info->firstread = calloc(channels, sizeof(BOOL));
874  info->nerr = calloc(channels, sizeof(INT));
875  info->nmsg = calloc(channels, sizeof(INT));
876  info->tolchan = calloc(channels, sizeof(INT));
877  info->gchan = calloc(channels, sizeof(INT));
878  info->intol = calloc(channels, sizeof(BOOL));
879 
880  /* init arrays */
881  for (i = 0; i < channels; i++) {
882  sprintf(info->settings.channel_names+CHN_NAME_LENGTH*i, "NONE_%d", i);
883 #ifdef GFA_SPECIFIC
884  sprintf(info->settings.dtype+DTYPE_LENGTH*i, "**TYPE_NOT_INIT**");
885  sprintf(info->settings.dsec+DSEC_LENGTH*i, "**SEC_NOT_INIT**");
886 #endif
887  sprintf(info->settings.chnflags+CHNFLAGS_LENGTH*i, "US");
888  *(info->settings.minval+i) = 0.f;
889  *(info->settings.maxval+i) = 0.f;
890  *(info->settings.tolerance+i)= 0.f;
891  /* *(info->settings.used+i) = FALSE; already init'd */
892  *(info->settings.readonly+i) = TRUE;
893 
894  *(info->array+i) = -2.f;
895  *(info->array_m+i) = -2.f;
896  *(info->demand+i) = -2.f;
897  /* *(info->found+i) = FALSE; already init'd */
898  /* *(info->iscmd+i) = FALSE; already init'd */
899  /* *(info->subscribed+i) = FALSE; already init'd */
900  *(info->down+i) = TRUE;
901  /* *(info->firstread+i) = FALSE; already init'd */
902  /* *(info->nerr+i) = 0; already init'd */
903  /* *(info->nmsg+i) = 0; already init'd */
904  *(info->tolchan+i) = -1;
905  *(info->gchan+i) = -1;
906  *(info->intol+i) = TRUE;
907  /* *(info->pchid+i) = 0; already init'd */
908  *(info->lastset+i) = ss_time();
909  /* *(info->lastget+i) = 0; already init'd */
910  *(info->status+i) = ECA_NORMAL;
911  }
912 
913  // remember if DD/Loadfile is already present
914  status = db_find_key(hDB, hKey, "DD/Loadfile", &subkey);
915 
916  strcpy(info->settings.loadfile,"NONE");
917  db_merge_data(hDB, hKey, "DD/Loadfile", info->settings.loadfile,
918  NAME_LENGTH, 1, TID_STRING);
919  // DD/Loadfile was not in ODB -> stop here user may now set loadfile name
920  if (status == DB_NO_KEY) {
921  cm_msg(MLOG,"","Created \"DD/Loadfile\" in ODB -> set name of loadfile and restart"
922  " to load initial setup from local loadfile");
923  cm_msg(MLOG,"","Or just restart and do manual setup in ODB");
924  return FE_ERR_HW;
925  }
926 
927  info->settings.Sum_NOT_Connected = 0;
928  db_merge_data(hDB, hKey, "DD/Sum_NOT_Connected",
929  &info->settings.Sum_NOT_Connected, sizeof(int), 1, TID_INT);
930  status = db_find_key(hDB, hKey, "DD/Sum_NOT_Connected", &info->hkeySNC);
931  if (status == DB_SUCCESS) {
932  if (info->settings.Sum_NOT_Connected != 0) {
933  info->settings.Sum_NOT_Connected = 0;
934  db_set_data(hDB, info->hkeySNC, &info->settings.Sum_NOT_Connected,
935  sizeof(int), 1, TID_INT);
936  }
937  } else {
938  info->hkeySNC = 0;
939  }
940 
941  info->settings.Sum_NOT_in_Tolerance = 0;
942  db_merge_data(hDB, hKey, "DD/Sum_NOT_in_Tolerance",
943  &info->settings.Sum_NOT_in_Tolerance, sizeof(int), 1, TID_INT);
944  status = db_find_key(hDB, hKey, "DD/Sum_NOT_in_Tolerance", &info->hkeySNT);
945  if (status == DB_SUCCESS) {
946  if (info->settings.Sum_NOT_in_Tolerance != 0) {
947  info->settings.Sum_NOT_in_Tolerance = 0;
948  db_set_data(hDB,info->hkeySNT,&info->settings.Sum_NOT_in_Tolerance,
949  sizeof(int),1,TID_INT);
950  }
951  } else {
952  info->hkeySNT = 0;
953  }
954 
955  strcpy(info->settings.AlarmWhenNOTConnected,"NONE");
956  db_merge_data(hDB, hKey, "DD/AlarmWhenNOTConnected",
957  info->settings.AlarmWhenNOTConnected, NAME_LENGTH, 1, TID_STRING);
958 
959  strcpy(info->settings.AlarmWhenNOTinTolerance,"NONE");
960  db_merge_data(hDB, hKey, "DD/AlarmWhenNOTinTolerance",
961  info->settings.AlarmWhenNOTinTolerance, NAME_LENGTH, 1, TID_STRING);
962 
963  // read info about EPICS Channel Name, Used, Readonly, Chn flags, Name, Min, Max,
964  // Threshold from a local file and write to DD if not created yet
965  if (strcmp(info->settings.loadfile,"NONE") != 0){
966 
967  if (db_find_key(hDB, hKey, "DD/EPICS Channel name", &subkey) == DB_NO_KEY) {
968  FILE *stream;
969 
970  i = 0;
971  if ((stream = fopen(info->settings.loadfile,"r")) != NULL) {
972  char tline[255];
973  char *p,*pn,*po;
974  int n,k;
975 
976  pnames = calloc(channels, NAME_LENGTH);
977  info->threshold = calloc(channels, sizeof(float));
978  n = 0;
979  while (!feof(stream)) {
980  // 1 2 3 4 5 6 7 8
981  // EPICSCAname[,Y/N,Y/N,flags,MidasName,Min,Max,Threshold,Toler] # comments
982  if (fgets(tline, sizeof(tline), stream) != NULL) {
983  n++;
984  if ((p = strchr(tline,'#'))) *p = '\0'; // remove comments
985 
986  if (strlen(tline) > 0) { // make sure last field on line ends with ,
987  int j;
988  for (j=strlen(tline)-1; j >= 0; j--) {
989  if (!isspace(tline[j])) { // remove trailing blanks
990  if (tline[j] != ',') {tline[j+1] = ','; tline[j+2] = '\0';}
991  break;
992  }
993  }
994  }
995  if ((strlen(tline) > 0)&&(p = strchr(tline,','))) { // EPICS channel name
996  if (i < channels) {
997  cm_msg(MLOG,"","Channel %d: Processing Line %d: %s", i, n, tline);
998  pn = p+1; *p = '\0';
999  po = &tline[0];
1000 
1001  for (k=strlen(po)-1; k >= 0; k--) // remove trailing blanks
1002  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1003  while (isspace(*po)) po++; // remove leading blanks
1004 
1005  if (strlen(po) >= CHN_NAME_LENGTH) *(po+CHN_NAME_LENGTH-1) = '\0';
1006 #ifdef GFA_SPECIFIC
1007  // NIY check GFA convention ?
1008 #endif
1009  strcpy(info->settings.channel_names+ CHN_NAME_LENGTH*i,po);
1010 
1011  // take EPICS Channel as Midas Name default (maybe overwritten below)
1012  if (strlen(po) >= NAME_LENGTH) *(po+NAME_LENGTH-1) = '\0';
1013  strcpy(pnames+NAME_LENGTH*i,po);
1014 
1015  if (info->threshold) *(info->threshold+i) = 0.1f;
1016 
1017  if (p = strchr(pn,',')) { // used
1018  po = pn; pn = p+1; *p = '\0';
1019  if (strchr(po,'y')||strchr(po,'Y')) *(info->settings.used+i) = TRUE;
1020 
1021  if (p = strchr(pn,',')) { // readonly
1022  po = pn; pn = p+1; *p = '\0';
1023  if (strchr(po,'n')||strchr(po,'N'))
1024  *(info->settings.readonly+i)=FALSE;
1025 
1026  if (p = strchr(pn,',')) { // channel flags
1027  po = pn; pn = p+1; *p = '\0';
1028  for (k=strlen(po)-1; k >= 0; k--) // remove trailing blanks
1029  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1030  if (strlen(po) >= CHNFLAGS_LENGTH) *(po+CHNFLAGS_LENGTH-1) = '\0';
1031  if (strlen(po) > 0) {
1032  int k1;
1033 
1034  // remove blanks
1035  for (k=0, k1=0; k < strlen(po); k++) {
1036  *(info->settings.chnflags+ CHNFLAGS_LENGTH*i+k) = '\0';
1037  if (!isspace(*(po+k))) {
1038 #ifdef GFA_SPECIFIC
1039  // NIY check flags also with/without GFA_SPECIFIC
1040  // NIY T should only be set for SOL, IST or POSA
1041 #else
1042 #endif
1043  // NIY R should only be set for :SOL: or maybe :COM:
1044  *(info->settings.chnflags+ CHNFLAGS_LENGTH*i+k1) = *(po+k);
1045  k1++;
1046  *(info->settings.chnflags+ CHNFLAGS_LENGTH*i+k1) = '\0';
1047  }
1048  }
1049  }
1050 
1051  if ((p = strchr(pn,','))) { // Midas Name
1052  po = pn; pn = p+1; *p = '\0';
1053  for (k=strlen(po)-1; k >= 0; k--) // remove trailing blanks
1054  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1055  while (isspace(*po)) po++; // remove leading blanks
1056  if (strlen(po) >= NAME_LENGTH) *(po+NAME_LENGTH-1) = '\0';
1057  if (strlen(po) > 0) {
1058  strcpy(pnames+NAME_LENGTH*i,po);
1059  }
1060 
1061  if ((p = strchr(pn,','))) { // Minval
1062  po = pn; pn = p+1; *p = '\0';
1063  for (k=strlen(po)-1; k >= 0; k--) // remove trailing blanks
1064  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1065  if (strlen(po) > 0) {
1066  float tval;
1067  if (sscanf(po,"%f",&tval) == 1)
1068  *(info->settings.minval+i) = tval;
1069  }
1070 
1071  if ((p = strchr(pn,','))) { // Maxval
1072  po = pn; pn = p+1; *p = '\0';
1073  for (k=strlen(po)-1; k >= 0; k--) // remove trailing blanks
1074  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1075  if (strlen(po) > 0) {
1076  float tval;
1077  if (sscanf(po,"%f",&tval) == 1)
1078  *(info->settings.maxval+i) = tval;
1079  }
1080 
1081  if ((p = strchr(pn,','))) { // threshold
1082  po = pn; pn = p+1; *p = '\0';
1083  for (k=strlen(po)-1; k >= 0; k--)// remove trailing blanks
1084  if (isspace(*(po+k))) *(po+k)='\0'; else break;
1085  if (strlen(po) > 0) {
1086  float tval;
1087  if ((sscanf(po,"%f",&tval) == 1) && info->threshold)
1088  *(info->threshold+i) = tval;
1089  }
1090 
1091  for (k=strlen(pn)-1; k >= 0; k--)// remove trailing blanks
1092  if (isspace(*(pn+k))) *(pn+k)='\0'; else break;
1093  if (strlen(pn) > 0) { // rest is tolerance
1094  float tval;
1095  if (sscanf(pn,"%f",&tval) == 1)
1096  *(info->settings.tolerance+i) = tval;
1097  }
1098  }
1099  }
1100  }
1101  }
1102  }
1103  }
1104  }
1105  // NIY check min < max
1106  // NIY check threshold > 0
1107 #ifdef GFA_SPECIFIC
1108  // NIY check tolerance >= 0 when T flag
1109 #endif
1110  } else {
1111  cm_msg(MLOG,"","Line %d not handled! %s", n, tline);
1112  }
1113  i++;
1114  }
1115  }
1116  } // while not EOF
1117 
1118  if (i < channels) {
1119  cm_msg(MLOG,"","Less channels (%d) loaded from %s than expected (%d) "
1120  "-> recompile with %d or add more channel lines", i,
1121  info->settings.loadfile, channels, i);
1122  for (; i < channels; i++) { // init rest to defaults
1123  sprintf(pnames+NAME_LENGTH*i,"NONE_%d",i);
1124  if (info->threshold) *(info->threshold+i) = 0.1f;
1125  }
1126  } else if (i > channels) {
1127  cm_msg(MLOG,"","More channels (%d) read from %s than expected (%d) "
1128  "-> recompile with %d or remove channel lines", i,
1129  info->settings.loadfile, channels, i);
1130  } else {
1131  cm_msg(MLOG,"","Expected number of channels (%d) read ", channels);
1132  }
1133  if (i > 0) loaded = TRUE;
1134  fclose(stream);
1135  } else {
1136  cm_msg(MLOG,"","ERROR %d returned when trying to open %s for read access!",
1137  errno, info->settings.loadfile);
1138  }
1139  }
1140  }
1141 
1142  /* init or get channel names, Used and Readonly DD settings */
1143  db_merge_data(hDB, hKey, "DD/EPICS Channel name", info->settings.channel_names,
1144  CHN_NAME_LENGTH * channels, channels, TID_STRING);
1145  db_merge_data(hDB, hKey, "DD/Used", info->settings.used,
1146  sizeof(BOOL)* channels, channels, TID_BOOL);
1147  db_merge_data(hDB, hKey, "DD/Readonly", info->settings.readonly,
1148  sizeof(BOOL)* channels, channels, TID_BOOL);
1149  db_merge_data(hDB, hKey, "DD/Chn_Flags", info->settings.chnflags,
1150  CHNFLAGS_LENGTH * channels, channels, TID_STRING);
1151 #ifdef GFA_SPECIFIC
1152  db_merge_data(hDB, hKey, "DD/DESC:TYP", info->settings.dtype,
1153  DTYPE_LENGTH * channels, channels, TID_STRING);
1154  db_merge_data(hDB, hKey, "DD/DESC:SEC", info->settings.dsec,
1155  DSEC_LENGTH * channels, channels, TID_STRING);
1156 #endif
1157  if (loaded) { // min and max were loaded write them now
1158  db_merge_data(hDB, hKey, "DD/Minval", info->settings.minval,
1159  sizeof(float)* channels, channels, TID_FLOAT);
1160  db_merge_data(hDB, hKey, "DD/Maxval", info->settings.maxval,
1161  sizeof(float)* channels, channels, TID_FLOAT);
1162  }
1163 
1164  db_merge_data(hDB, hKey, "DD/Tolerance", info->settings.tolerance,
1165  sizeof(float)* channels, channels, TID_FLOAT);
1166 
1167  /* -- search for channels */
1168 
1169 #ifdef GFA_SPECIFIC
1170  /* search for <gfa_device>:DESC:TYP and <gfa_device>:DESC:SEC to
1171  * get device type and section of channel */
1172  {
1173  chid *tchidt;
1174  chid *tchids;
1175  char tname[2*CHN_NAME_LENGTH];
1176  HNDLE tkey;
1177 
1178  tchidt = calloc(channels, sizeof(chid));
1179  tchids = calloc(channels, sizeof(chid));
1180 
1181  if (tchidt && tchids) {
1182  /* post channel search to IO buffer */
1183  for (i = 0; i < channels; i++) {
1184  if (*(info->settings.used+i)) {
1185  char *tpos;
1186 
1187  strcpy(tname,info->settings.channel_names+CHN_NAME_LENGTH*i);
1188  tpos = strchr(tname,':');
1189  /*
1190  * GFA specific: devices of the same type have the same channel names
1191  * channel name is <gfa_device_name>:<gfa_device_specific_channel_info>
1192  * e.g.: BMB1:COM:2 to set/read demand or BMB1:STA:1 to read status
1193  * <gfa_device>:DESC:TYP contains info about GFA device type
1194  * <gfa_device>:DESC:SEC contains info about GFA device section
1195  */
1196  if (tpos) *tpos = '\0';
1197  strcat(tname,":DESC:TYP");
1198  status = ca_create_channel(tname,NULL,NULL,0,tchidt+i);
1199  if (!(status & ECA_NORMAL))
1200  cm_msg(MERROR, "epics_ca_init", "ERROR status 0X%x = \"%s\" returned by "
1201  "ca_create_channel(%s)", status, ca_message(status), tname);
1202  }
1203  }
1204 
1205  for (i = 0; i < channels; i++) {
1206  if (*(info->settings.used+i)) {
1207  char *tpos;
1208 
1209  strcpy(tname,info->settings.channel_names+CHN_NAME_LENGTH*i);
1210  tpos = strchr(tname,':');
1211  if (tpos) *tpos = '\0';
1212  strcat(tname,":DESC:SEC");
1213  status = ca_create_channel(tname,NULL,NULL,0,tchids+i);
1214  if (!(status & ECA_NORMAL))
1215  cm_msg(MERROR, "epics_ca_init", "ERROR status 0X%x = \"%s\" returned by "
1216  "ca_create_channel(%s)", status, ca_message(status), tname);
1217  }
1218  }
1219 
1220  /* flush send buffer and block for outstanding queries */
1221  status = ca_pend_io(5.0);
1222  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1223  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1224 #ifdef MIDEBUGP
1225  cm_msg(MLOG,"","ca_pend_io(5.0) status 0X%x = \"%s\"",status,ca_message(status));
1226 #endif
1227  /* if channel is connected post get channel info to IO buffer */
1228  for (i = 0; i < channels; i++) {
1229  if (*(info->settings.used+i)) {
1230  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "**TYPE_NOT_RETURNED**");
1231  if (ca_state(*(tchidt+i)) == cs_conn) {
1232  status = ca_get(DBR_STRING,*(tchidt+i),info->settings.dtype+DTYPE_LENGTH*i);
1233  if (status != ECA_NORMAL)
1234  cm_msg(MLOG,"","ca_get(dtype of channel %d): status 0X%x = \"%s\"",i,
1235  status,ca_message(status));
1236  } else {
1237  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "**TYPE_NOT_FOUND**");
1238  }
1239  } else {
1240  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "**CHAN_NOT_USED**");
1241  }
1242  }
1243 
1244  for (i = 0; i < channels; i++) {
1245  if (*(info->settings.used+i)) {
1246  strcpy(info->settings.dsec+DSEC_LENGTH*i, "**SEC_NOT_RETURNED**");
1247  if (ca_state(*(tchids+i)) == cs_conn) {
1248  status = ca_get(DBR_STRING,*(tchids+i),info->settings.dsec+DSEC_LENGTH*i);
1249  if (status != ECA_NORMAL)
1250  cm_msg(MLOG,"","ca_get(dsec of channel %d): status 0X%x = \"%s\"",i,
1251  status,ca_message(status));
1252  } else {
1253  strcpy(info->settings.dsec+DSEC_LENGTH*i, "**SEC_NOT_FOUND**");
1254  }
1255  } else {
1256  strcpy(info->settings.dsec+DSEC_LENGTH*i, "**CHAN_NOT_USED**");
1257  }
1258  }
1259  status = ca_pend_io(1.0); /* flush buffer and block for outstanding q's */
1260  if (status == ECA_TIMEOUT) status = ca_pend_io(1.0);
1261 #ifdef MIDEBUGP
1262  cm_msg(MLOG,"","ca_pend_io(1.0) status 0X%x = \"%s\"",status,ca_message(status));
1263 #endif
1264  /* NOTE: status is not evaluated */
1265 
1266 #ifdef MIDEBUG2
1267  cm_msg(MLOG,"","ss_sleep(2000)");
1268 #endif
1269  ss_sleep(2000); /* wait some time */
1270 
1271  status = ca_pend_event(1.0); /* probably not necessary to wait again */
1272 #ifdef MIDEBUGP
1273  cm_msg(MLOG,"","ca_pend_event(1.0)");
1274 #endif
1275 
1276  // (re)set info when not connected then release channels
1277  for (i = 0; i < channels; i++) {
1278  if (*(tchidt+i)) {
1279  if (*(info->settings.used+i)) {
1280  if (ca_state(*(tchidt+i)) != cs_conn) {
1281  // some beamline channel locks (KanalverschlusS) are not fully
1282  // implemented in EPICS therefore supply TYP information from chan name
1283  if (strncmp(info->settings.channel_names+CHN_NAME_LENGTH*i,"KS",2)==0)
1284  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "BX");
1285  // separator HV and spinrotator HV are from another server
1286  else if ((strncmp(info->settings.channel_names+CHN_NAME_LENGTH*i,"SEP",3)
1287  ==0) &&
1288  (strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,"HVN:") ||
1289  strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,"HVP:") ||
1290  strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,"HV:")))
1291  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "HVPS");
1292  else
1293  strcpy(info->settings.dtype+DTYPE_LENGTH*i, "**TYPE_NOT_FOUND**");
1294  }
1295  }
1296  status = ca_clear_channel(*(tchidt+i));
1297  if (!(status & ECA_NORMAL))
1298  cm_msg(MERROR, "epics_ca_init", ":DESC:TYP of Channel %d(%s): "
1299  "ca_clear_channel() returned status 0X%x = \"%s\"",i,
1301  status, ca_message(status));
1302  }
1303  }
1304  for (i = 0; i < channels; i++) {
1305  if (*(tchids+i)) {
1306  if (*(info->settings.used+i)) {
1307  if (ca_state(*(tchids+i)) != cs_conn) {
1308  // spinrotator/separator HV is not fully implemented
1309  // in EPICS therefore supply SEC information from channel name
1310  if (strncmp(info->settings.channel_names+CHN_NAME_LENGTH*i,"sep31:",6)==0)
1311  strcpy(info->settings.dsec+DSEC_LENGTH*i, "PIM31");
1312  else
1313  strcpy(info->settings.dsec+DSEC_LENGTH*i, "**SEC_NOT_FOUND**");
1314  }
1315  }
1316  status = ca_clear_channel(*(tchids+i));
1317  if (!(status & ECA_NORMAL))
1318  cm_msg(MERROR, "epics_ca_init", ":DESC:SEC of Channel %d(%s): "
1319  "ca_clear_channel() returned status 0X%x = \"%s\"",i,
1321  status, ca_message(status));
1322  }
1323  }
1324  status = ca_pend_io(1.0); /* flush buffer */
1325  if (status == ECA_TIMEOUT) status = ca_pend_io(1.0);
1326 #ifdef MIDEBUGP
1327  cm_msg(MLOG,"","ca_pend_io(1.0) status 0X%x = \"%s\"",status,ca_message(status));
1328 #endif
1329 
1330  }
1331 
1332  if (tchidt) free(tchidt);
1333  if (tchids) free(tchids);
1334 
1335  /* update ODB */
1336  status = db_find_key(hDB, hKey, "DD/DESC:TYP", &tkey);
1337  if (status == DB_SUCCESS)
1338  db_set_data(hDB, tkey, info->settings.dtype, DTYPE_LENGTH * channels,
1339  channels, TID_STRING);
1340 
1341  status = db_find_key(hDB, hKey, "DD/DESC:SEC", &tkey);
1342  if (status == DB_SUCCESS)
1343  db_set_data(hDB, tkey, info->settings.dsec, DSEC_LENGTH * channels,
1344  channels, TID_STRING);
1345 
1346  }
1347 #endif /* #ifdef GFA_SPECIFIC */
1348 
1349  /* disable event handler callback subscription in the connection handler callback
1350  * before everything is set-up */
1351  info->subscribe_disabled = TRUE;
1352 
1353  /* post create channel connection to IO buffer */
1354  for (i = 0; i < channels; i++) {
1355  if (*(info->settings.used+i)) {
1356  /* NOTE: connection handler used -> ca_pend_io() will not block - waiting for
1357  * channel to enter connected state */
1358  status = ca_create_channel(info->settings.channel_names+CHN_NAME_LENGTH*i,
1359  epics_ca_connection_handler, info, 0, info->pchid+i);
1360  if (!(status & ECA_NORMAL))
1361  cm_msg(MERROR, "epics_ca_init", "ERROR status 0X%x = \"%s\" returned by "
1362  "ca_create_channel(%s)", status, ca_message(status),
1364  }
1365  }
1366 
1367  /* flush send buffer */
1368  status = ca_pend_io(5.0);
1369  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1370  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1371  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1372  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1373 #ifdef MIDEBUGP
1374  cm_msg(MLOG,"","ca_pend_io(5.0) status 0X%x = \"%s\"", status, ca_message(status));
1375 #endif
1376 #ifdef MIDEBUG2
1377  cm_msg(MLOG,"","ss_sleep(5000)");
1378 #endif
1379  ss_sleep(5000);
1380  ca_pend_event(4.0);
1381 #ifdef MIDEBUGP
1382  cm_msg(MLOG,"","ca_pend_event(4.0)");
1383 #endif
1384 
1385  /* timeout occured or normal (ca_pend_io,only) -> process channels */
1386  if ((status == ECA_TIMEOUT) || (status == ECA_NORMAL)){
1387 
1388  for (i = 0; i < channels; i++) {
1389  if (*(info->settings.used+i)) {
1390  if ((castate=ca_state(*(info->pchid+i))) != cs_conn) {
1391  cm_msg(MERROR, "epics_ca_init", "Not connected to EPICS Channel %d(%s). "
1392  "Channel state is %d = \"%s\"",i,
1394  castate, castatestr(castate));
1395  } else {
1396  if (!*(info->found+i)) {
1397  cm_msg(MLOG, "epics_ca_init", "Connected to EPICS Channel %d(%s)", i,
1399  *(info->found+i) = TRUE;
1400  }
1401  }
1402  }
1403  }
1404 
1405  } else {
1406  cm_msg(MLOG,"epics_ca_init","Returned status %d = \"%s\" of ca_pend_io(A) is not "
1407  "handled", status, ca_message(status));
1408  }
1409 
1410  // get MIN/MAX if not already present
1411  // NOTE: some channels may still be missing
1412  status = db_find_key(hDB, hKey, "DD/Minval", &subkey);
1413  if (status != DB_NO_KEY) status = db_find_key(hDB, hKey, "DD/Maxval", &subkey);
1414 
1415  if (status == DB_NO_KEY) {
1416  struct dbr_ctrl_float *pctrl;
1417 
1418  cm_msg(MLOG,"","Query LOW and HIGH of channels");
1419  pctrl = calloc(channels,sizeof(struct dbr_ctrl_float));
1420  if (pctrl) {
1421  int nchans;
1422  for (nchans = 0, i = 0; i < channels; i++) {
1423  if (*(info->settings.used+i)) {
1424  if ((castate=ca_state(*(info->pchid+i))) == cs_conn) {
1425  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'U') == NULL) {
1426  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'S') == NULL) {
1427  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'M') != NULL) {
1428  status = ca_get(DBR_CTRL_FLOAT,*(info->pchid+i),pctrl+i);
1429  if (status != ECA_NORMAL)
1430  cm_msg(MLOG,"","ca_get(DBR_CTRL_FLOAT of channel %d): "
1431  "status 0X%x = \"%s\"",i,status,ca_message(status));
1432  nchans++;
1433  } else {
1434  cm_msg(MLOG,"","Channel %d M flag not set", i);
1435  }
1436  } else {
1437  cm_msg(MLOG,"","Channel %d S flag set", i);
1438  }
1439  } else {
1440  cm_msg(MLOG,"","Channel %d U flag set", i);
1441  }
1442  } else {
1443  cm_msg(MLOG,"","Channel %d not connected", i);
1444  }
1445  } else {
1446  cm_msg(MLOG,"","Channel %d not used", i);
1447  }
1448  }
1449 
1450  if (nchans>0) {
1451  cm_msg(MLOG,"","Queried LOW and HIGH of %d channels",nchans);
1452  /* flush send buffer */
1453  status = ca_pend_io(5.0);
1454  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1455  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1456 #ifdef MIDEBUGP
1457  cm_msg(MLOG,"","ca_pend_io(5.0) status 0X%x =\"%s\"",status,ca_message(status));
1458 #endif
1459 #ifdef MIDEBUG2
1460  cm_msg(MLOG,"","ss_sleep(1000)");
1461 #endif
1462  ss_sleep(1000);
1463  ca_pend_event(4.0);
1464 #ifdef MIDEBUGP
1465  cm_msg(MLOG,"","ca_pend_event(1.0)");
1466 #endif
1467  for (i = 0; i < channels; i++) {
1468  if (*(info->settings.used+i)) {
1469  if ((castate=ca_state(*(info->pchid+i))) == cs_conn) {
1470  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'U') == NULL) {
1471  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'S') == NULL) {
1472  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'M') != NULL) {
1473  *(info->settings.minval+i) = (pctrl+i)->lower_ctrl_limit;
1474  cm_msg(MLOG,"","Channel %d(%s): LOW is %f",
1476  *(info->settings.minval+i));
1477  *(info->settings.maxval+i) = (pctrl+i)->upper_ctrl_limit;
1478  cm_msg(MLOG,"","Channel %d(%s): HIGH is %f",
1480  *(info->settings.maxval+i));
1481  }
1482  }
1483  }
1484  }
1485  }
1486  }
1487  }
1488  free(pctrl);
1489  } else {
1490  cm_msg(MERROR,"epics_ca_init","Memory not allocated for struct dbr_ctrl_float");
1491  }
1492  }
1493 
1494  /* create and init or read DD/Minval DD/Maxval */
1495  db_merge_data(hDB, hKey, "DD/Minval", info->settings.minval,
1496  sizeof(float)* channels, channels, TID_FLOAT);
1497  db_merge_data(hDB, hKey, "DD/Maxval", info->settings.maxval,
1498  sizeof(float)* channels, channels, TID_FLOAT);
1499 
1500  /* enable event handler callback subscription in connection handler */
1501  info->subscribe_disabled = FALSE;
1502 
1503  /* buffer add change notifications */
1504  for (i = 0; i < channels; i++) {
1505  /* only for connected channels */
1506  if (*(info->settings.used+i) && ((castate=ca_state(info->pchid[i])) == cs_conn)) {
1507  // chan specific: omit channels with S-flag e.g.: returning strings
1508  // and :COM:2 channels
1509  if ((strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'S') == NULL) &&
1510  (strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,":COM:2") == NULL)){
1511  // subscribe event handler callback for this channel converting value to float
1512  status = ca_create_subscription(DBR_FLOAT, 1, *(info->pchid+i), DBE_VALUE,
1513  epics_ca_event_handler, info, NULL);
1514  if (!(status & ECA_NORMAL)) {
1515  cm_msg(MERROR,"epics_ca_init","Channel %d(%s): ca_create_subscription() retur"
1516  "ned status 0x%X = \"%s\"",i,info->settings.channel_names+CHN_NAME_LENGTH*i,
1517  status, ca_message(status));
1518  } else {
1519 #ifdef MIDEBUG1
1520  cm_msg(MLOG,"","Channel %d(%s): CA event handler (float) will be installed",
1522 #endif
1523  *(info->subscribed+i) = TRUE;
1524  }
1525  } else {
1526  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'S'))
1527  cm_msg(MLOG,"","Channel %d(%s): S flag: CA event handler will NOT be "
1528  "installed", i,info->settings.channel_names+CHN_NAME_LENGTH*i);
1529 #ifdef MIDEBUG
1530  else if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,":COM:2"))
1531  cm_msg(MLOG,"","Channel %d(%s): COM Channel : CA event handler will NOT "
1532  "be installed",i,info->settings.channel_names+CHN_NAME_LENGTH*i);
1533 #endif
1534  *(info->subscribed+i) = TRUE; // mark as handled
1535  }
1536  //if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'C') != NULL)
1537  *(info->down+i) = FALSE; // channel is currently up
1538  } else {
1539  //if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'C') != NULL)
1540  *(info->down+i) = TRUE; // channel is currently down
1541  }
1542  }
1543 
1544  /* flush send buffer and block for outstanding queries */
1545  status = ca_pend_io(5.0);
1546  if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1547 #ifdef MIDEBUGP
1548  cm_msg(MLOG,"","ca_pend_io(5.0) status 0X%x = \"%s\"", status, ca_message(status));
1549 #endif
1550 #ifdef MIDEBUG2
1551  cm_msg(MLOG,"","ss_sleep(2000)");
1552 #endif
1553  ss_sleep(2000); // wait fixed time interval for (initial) events
1554 
1555  status = ca_pend_event(5.0); // process receive buffer to handle events
1556 #ifdef MIDEBUGP
1557  cm_msg(MLOG,"","ca_pend_event(5.0)");
1558 #endif
1559  if ((status == ECA_TIMEOUT) || (status == ECA_NORMAL)) {
1560  for (i = 0; i < channels; i++) {
1561  if (*(info->settings.used+i) && *(info->found+i)) {
1562  if (ca_state(info->pchid[i]) != cs_conn)
1563  cm_msg(MERROR, "epics_ca_init", "Not connected to %s",
1565  } else if (*(info->found+i)){
1566  if (*(info->settings.used+i)) {
1567  cm_msg(MLOG,"","Channel %d(%s): Not connected (state %d = \"%s\") -> no CA "
1568  "callback installed and channel disabled", i,
1569  info->settings.channel_names+CHN_NAME_LENGTH*i, castate,
1570  castatestr(castate));
1571  }
1572  *(info->found+i) = FALSE;
1573  }
1574  }
1575  } else if (status != ECA_NORMAL) {
1576 #ifdef MIDEBUG
1577  cm_msg(MLOG,"epics_ca_init","Returned status %d \"%s\" of ca_pend_io(B) is not "
1578  "handled", status, ca_message(status));
1579 #endif
1580  }
1581 
1582  /* log information */
1583  for (i = 0; i < channels; i++) {
1584  if (*(info->settings.used+i)) {
1585  // R only for :COM: or :SOL:
1586 #ifdef GFA_SPECIFIC
1587  if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,":COM:") ||
1588  strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,":SOL:"))
1589  sprintf(smsg,"Channel %d(%s): %s Type: %s Section: %s Chn_Flags: %s", i,
1591  *(info->settings.readonly+i)?"R":"W",
1592  info->settings.dtype+DTYPE_LENGTH *i,
1593  info->settings.dsec+DSEC_LENGTH*i,
1595  else
1596  sprintf(smsg,"Channel %d(%s): R Type: %s Section: %s Chn_Flags: %s", i,
1598  info->settings.dtype+DTYPE_LENGTH *i,
1599  info->settings.dsec+DSEC_LENGTH*i,
1601 #else
1602  sprintf(smsg,"Channel %d(%s): %s Chn_Flags: %s", i,
1604  *(info->readonly+i)?"R":"W",
1606 #endif /* #ifdef GFA_SPECIFIC */
1607 
1608  if ((strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'U'))||
1609  (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'S'))) {
1610  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'I')||
1611  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'F')||
1612  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'M')||
1613  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'C')||
1614 #ifdef GFA_SPECIFIC
1615  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'P')||
1616  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'N')||
1617  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'Z')||
1618  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'V')||
1619  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'T')||
1620  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'G')||
1621 #endif
1622  strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'R') )
1623  strcat(smsg," ** Other flag(s) overruled by U and/or S **");
1624  } else {
1625  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'M')) {
1626  sprintf(&smsg[strlen(smsg)]," Minval = %.2f, Maxval = %.2f",
1627  *(info->settings.minval+i), *(info->settings.maxval+i));
1628  }
1629 #ifdef GFA_SPECIFIC
1630  // NIY check and list additional info (tolerance when T,
1631  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*i,'T')) {
1632  if ( *(info->settings.tolerance+i) >= 0.f)
1633  sprintf(&smsg[strlen(smsg)]," Tolerance = %f",
1634  *(info->settings.tolerance+i));
1635  }
1636 #endif
1637  }
1638  cm_msg(MLOG,"",smsg);
1639  } else {
1640  sprintf(smsg,"Channel %d(%s): NOT Used", i,
1642  cm_msg(MLOG,"",smsg);
1643  }
1644  }
1645 
1646 #ifndef OMIT_ODBUPDATE
1647  // get equipment name
1648  if ((status = db_get_path(hDB, hKey, tpath, sizeof(tpath))) == DB_SUCCESS) {
1649  int i;
1650  for (i = strlen("/Equipment/"); i < strlen(tpath); i++) {
1651  if (tpath[i] == '/') {
1652  tpath[i] = '\0';
1653  strncpy(info->name, &tpath[strlen("/Equipment/")], NAME_LENGTH);
1654  info->name[NAME_LENGTH - 1] = '\0';
1655  sprintf(tpath, "/Equipment/%s/Variables/Demand",info->name);
1656  status = db_find_key(hDB, 0, tpath, &info->hkeyDemand);
1657  if (status != DB_SUCCESS) info->hkeyDemand = 0;
1658  break;
1659  }
1660  }
1661  cm_msg(MINFO, "", "epics_ca_init: Equipment name is %s", info->name);
1662  } else {
1663  cm_msg(MERROR, "epics_ca_init","ERROR %d getting key path", status);
1664  }
1665 #else
1666  info->hkeyDemand = 0;
1667 #endif
1668 
1669 #ifndef OMIT_ODBUPDATE
1670  // directly init ODB settings of Names
1671  if (pnames != NULL) {
1672  sprintf(tpath, "/Equipment/%s/Settings/Names",info->name);
1673  db_merge_data(hDB, 0, tpath, pnames, NAME_LENGTH*channels, channels, TID_STRING);
1674  free(pnames);
1675  pnames = NULL;
1676  }
1677 #endif
1678 
1679 #ifndef OMIT_ODBUPDATE
1680  // directly init ODB settings of thresholds
1681  if (info->threshold != NULL) {
1682  // NIY TODO does not work
1683  //sprintf(tpath, "/Equipment/%s/Settings/Update Threshold Measured",info->name);
1684  //db_merge_data(hDB, 0, tpath, info->threshold, sizeof(float)* channels, channels,
1685  // TID_FLOAT);
1686  //free(info->threshold);
1687  //info->threshold = NULL;
1688  }
1689 #endif
1690 
1691 #ifdef GFA_SPECIFIC
1692 
1693  /* list GFA types, their channels, channel masks, values and corresp. messages */
1694 #ifdef MIDEBUG
1695  cm_msg(MLOG, "", "List of used GFA types");
1696 
1697  for (i=0; i < N_GFA_TYPES; i++) {
1698  int n,j;
1699  BOOL found;
1700  GFA_channel *tc;
1701 
1702  for (found=FALSE,n=0; n < info->num_channels; n++) {
1703  if (strcmp(info->settings.dtype+DTYPE_LENGTH*n,gfatype[i].type) == 0) {
1704  found = TRUE;
1705  break;
1706  }
1707  }
1708 
1709  if (!found) continue;
1710 
1711  cm_msg(MLOG,"","TYPE: \"%s\" \"%s\" %d channels", gfatype[i].type, gfatype[i].desc,
1712  gfatype[i].nc);
1713  tc = gfatype[i].tc;
1714 
1715  for (j = 0; j < gfatype[i].nc; j++) {
1716  int k;
1717  GFA_mask *cm;
1718 
1719  if (!(tc+j)) continue;
1720 #ifdef MIDEBUG1
1721  cm_msg(MLOG,"","**Channel \"%s\" \"%s\" %d masks",(tc+j)->spec,(tc+j)->desc,
1722  (tc+j)->ns);
1723 #else
1724  cm_msg(MLOG,"","**Channel \"%s\" \"%s\"",(tc+j)->spec,(tc+j)->desc);
1725 #endif
1726  cm = (tc+j)->cm;
1727  for (k = 0; k < (tc+j)->ns; k++) {
1728  int l;
1729  GFA_msg *sm;
1730 
1731  if (!(cm+k)) continue;
1732  cm_msg(MLOG,"","****Mask 0x%4.4X",(cm+k)->mask);
1733  sm = (cm+k)->sm;
1734  for (l = 0; l < (cm+k)->nm; l++) {
1735  if (!(sm+l)) continue;
1736  cm_msg(MLOG,"","******Value 0x%4.4X : \"%s\"",(sm+l)->value, (sm+l)->msg);
1737  }
1738 
1739  }
1740  }
1741  }
1742 #endif
1743 
1744  // check if GFA type is in list and channel is known
1745  // when not write message NO GFA specific handling possible for TYP
1746  for (i=0; i < info->num_channels; i++) {
1747  int n;
1748  BOOL found;
1749  for (found=FALSE,n=0; n < N_GFA_TYPES; n++) {
1750  if (strcmp(info->settings.dtype+DTYPE_LENGTH*i,gfatype[n].type) == 0) {
1751  found = TRUE;
1752  break;
1753  }
1754  }
1755 
1756  if (found) {
1757  int m;
1758  char *tpos;
1759 
1760  tpos = strchr(info->settings.channel_names+CHN_NAME_LENGTH*i,':');
1761  if (tpos) {
1762  for (found = FALSE, m=0; m < gfatype[n].nc; m++) { //loop over channels of type
1763  if ((gfatype[n].tc+m) && (strcmp((gfatype[n].tc+m)->spec,tpos)==0)) {
1764  found = TRUE; // channel spec found
1765  *(info->iscmd+i) = (gfatype[n].tc+m)->iscmd; // copy iscmd flag of spec
1766  break;
1767  }
1768  }
1769  if (!found && (strcmp(info->settings.dtype+DTYPE_LENGTH*i,"HVPS")==0)) {
1770  for (found = FALSE, m=0; m < gfatype[n].nc; m++) { //loop over chans of type
1771  if ((gfatype[n].tc+m) &&
1772  strstr(info->settings.channel_names+CHN_NAME_LENGTH*i,
1773  (gfatype[n].tc+m)->spec)) {
1774  found = TRUE; // channel spec found
1775  *(info->iscmd+i) = (gfatype[n].tc+m)->iscmd; // copy iscmd flag of spec
1776  break;
1777  }
1778  }
1779  }
1780  if (!found) {
1781  cm_msg(MLOG,"","Channel %d(%s): Not found in list of handled channels for "
1782  "GFA type \"%s\"", i,
1784  info->settings.dtype+DTYPE_LENGTH*i);
1785  if (!*(info->settings.readonly+i)) // not found but write flag set
1786  *(info->iscmd+i) = TRUE; // assume command
1787  }
1788  }
1789  } else {
1790  // omit channels with unknown types
1791  if (strncmp(info->settings.dtype+DTYPE_LENGTH*i,"**",2) == 0) continue;
1792 
1793  cm_msg(MLOG,"","Channel %d(%s): GFA Type \"%s\" not found in list"
1794  " of handled GFA types!", i,
1796  info->settings.dtype+DTYPE_LENGTH*i);
1797  }
1798  }
1799 #else
1800  for (i=0; i < info->num_channels; i++) {
1801  if (!*(info->settings.readonly+i)) // write flag set -> assume command
1802  *(info->iscmd+i) = TRUE;
1803  }
1804 #endif /* #ifdef GFA_SPECIFIC */
1805 
1806  // reset alarms
1807  if (strncmp(info->settings.AlarmWhenNOTConnected,"NONE",4) != 0)
1808  al_reset_alarm(info->settings.AlarmWhenNOTConnected);
1809 
1810  if (strncmp(info->settings.AlarmWhenNOTinTolerance,"NONE",4) != 0)
1811  al_reset_alarm(info->settings.AlarmWhenNOTinTolerance);
1812 
1813 
1814  // initialize demand of channel (and array_m) from readout array
1815  // if iscmd flag is set and not down
1816  // else init mirror array_m from readout array
1817  for (i=0; i < info->num_channels; i++)
1818  if (*(info->iscmd+i) && !*(info->down+i))
1819  epics_ca_get_demand(info, i, info->demand+i);
1820  else
1821  *(info->array_m+i) = *(info->array+i);
1822 
1823  /* got here without error -> enable all commands */
1824  info->cmd_disabled = FALSE;
1825 
1826 #ifdef MIDEBUG1
1827  cm_msg(MLOG,"","--epics_ca_init()");
1828 #endif
1829 #ifdef MIDEBUGF
1830  if (fp) fprintf(fp,"%u : --epics_ca_init()\n", ss_time());
1831 #endif
1832  return FE_SUCCESS;
1833 }
INT epics_ca_set ( CA_INFO info,
INT  channel,
float  value,
BOOL  flush,
BOOL  forced_update 
)

Definition at line 1936 of file epics_ca.c.

References CA_INFO::array_m, castatestr(), channel, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, CA_INFO::demand, epics_ca_set(), FALSE, CA_INFO::found, hDB, CA_INFO::hkeyDemand, i, CA_INFO::iscmd, CA_INFO::lastset, CA_SETTINGS::maxval, CA_SETTINGS::minval, msg, N_GFA_TYPES, _GFA_type::nc, CA_INFO::num_channels, CA_INFO::pchid, CA_SETTINGS::readonly, CA_INFO::settings, status, _GFA_type::tc, TRUE, and CA_SETTINGS::used.

Referenced by epics_ca(), epics_ca_event_handler(), epics_ca_get(), epics_ca_set(), and epics_ca_set_all().

1936  {
1937 #ifdef MIDEBUGF
1938  if (fp) fprintf(fp,"%u : ++epics_ca_set(channel=%d(%s), value=%f, flush=%d, force_upd"
1939  "=%d)\n", ss_time(), channel,
1941  value, flush, forced_update);
1942 #endif
1943 #ifdef MIDEBUG1
1944  cm_msg(MLOG,""," ++epics_ca_set(channel=%d, value=%f, flush=%d,force_upd=%d)",
1945  channel,value,flush,forced_update);
1946 #endif
1947  if (info) {
1948  if (channel < info->num_channels) {
1949  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'U') == NULL) {
1950  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'S') == NULL) {
1951  if (strchr(info->settings.chnflags+CHNFLAGS_LENGTH*channel,'M') != NULL) {
1952  if ((*(info->settings.minval+channel) != 0.f) ||
1953  (*(info->settings.maxval+channel) != 0.f)) {
1954  if (*(info->found+channel) && *(info->settings.used+channel) &&
1955  !*(info->settings.readonly+channel) && *(info->iscmd+channel)) {
1956  if (value < *(info->settings.minval+channel)) {
1957  cm_msg(MLOG,"","Channel %d (%s): New demand value (%f) lower than "
1958  "min value (%f)! - Setting min value", channel,
1959  info->settings.channel_names+CHN_NAME_LENGTH*channel,
1960  value, *(info->settings.minval+channel));
1961  value = *(info->settings.minval+channel);
1962  // NOTE: demand in ODB is not (re)set!
1963  } else if (value > *(info->settings.maxval+channel)) {
1964  cm_msg(MLOG,"","Channel %d (%s): New demand value (%f) larger than "
1965  "max value (%f)! - Setting max value", channel,
1966  info->settings.channel_names+CHN_NAME_LENGTH*channel,
1967  value, *(info->settings.maxval+channel));
1968  value = *(info->settings.maxval+channel);
1969  // NOTE: demand in ODB is not (re)set!
1970  }
1971  }
1972  }
1973  }
1974  }
1975  }
1976 
1977  if ((value != *(info->demand+channel))||forced_update) {
1978  if (*(info->found+channel) && *(info->settings.used+channel) &&
1979  !*(info->settings.readonly+channel) && *(info->iscmd+channel)) {
1980  enum channel_state castate;
1981  if ((castate=ca_state(*(info->pchid+channel)))== cs_conn) {
1982  if (ca_write_access(*(info->pchid+channel))) {
1983  int status;
1984 
1985 #ifdef GFA_SPECIFIC
1986  {
1987  char *tpos;
1988 
1989  // channel has <device>:<spec>
1990  if ((tpos=strchr(info->settings.channel_names+CHN_NAME_LENGTH*channel,
1991  ':')) != NULL) {
1992  int j;
1993 
1994  for (j = 0; j < N_GFA_TYPES; j++) {
1995  // find type
1996  if (strcmp(gfatype[j].type,info->settings.dtype+DTYPE_LENGTH*channel)
1997  ==0){
1998  GFA_channel *tc;
1999  int k;
2000 #ifdef MIDEBUGE
2001  cm_msg(MLOG,"","Found type %s", gfatype[j].type);
2002 #endif
2003  tc = gfatype[j].tc;
2004  for (k=0; k < gfatype[j].nc; k++) { // channels of this type
2005 
2006  if (!(tc+k)) continue;
2007 
2008  if (strcmp(tpos,(tc+k)->spec ) == 0) { // matching :<spec>
2009  int l;
2010  GFA_mask *cm;
2011 #ifdef MIDEBUGE
2012  cm_msg(MLOG,"","Found spec %s NS=%d",(tc+k)->spec,(tc+k)->ns);
2013 #endif
2014  cm = (tc+k)->cm;
2015  for (l = 0; l < (tc+k)->ns; l++) { // for all masks
2016  int m;
2017  int ttval, tdem;
2018  GFA_msg *sm;
2019 
2020  if (!(cm+l)) continue;
2021 #ifdef MIDEBUGE
2022  cm_msg(MLOG,"","Checking Mask 0x%4.4X",(cm+l)->mask);
2023 #endif
2024  ttval = (int)value & (cm+l)->mask;
2025  tdem = (int) *(info->demand+channel) & (cm+l)->mask;
2026  if (*(info->demand+channel) == -2.f) tdem = 0; // hide setup
2027  if (( ttval != tdem)||(*(info->demand+channel) == -2.f)) {
2028  char *tpost,*tposa;
2029  tpost = tposa = NULL;
2030 
2031  sm = (cm+l)->sm;
2032  for (m = 0; m < (cm+l)->nm; m++) {
2033  if (!(sm+m)) continue;
2034  // cm_msg(MLOG,"","check Value 0x%4.4X : \"%s\"",
2035  // (sm+m)->value, (sm+m)->msg);
2036  if ((sm+m)->value == ttval) {
2037  if (tpost) cm_msg(MLOG,"","New value: %s overwritten"
2038  " by %s", tpost, (sm+m)->msg);
2039  tpost = (sm+m)->msg;
2040  }
2041  if ((sm+m)->value == tdem) {
2042  if (tposa) cm_msg(MLOG,"","Prev value: %s overwritten"
2043  " by %s", tposa, (sm+m)->msg);
2044  tposa = (sm+m)->msg;
2045  }
2046  } // for all values
2047 
2048  if (tpost) {
2049  if (*(info->demand+channel) == -2.f) tposa = NULL;//hide
2050  if (tposa) {
2051  cm_msg(MLOG,"","%s: \"%s\" changed to \"%s\"",
2052  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2053  tposa, tpost);
2054  } else {
2055  if (strstr(info->settings.channel_names+
2056  CHN_NAME_LENGTH*channel,":COM:")) {
2057 
2058  cm_msg(MLOG,"","%s: Command is \"%s\"",
2059  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2060  tpost);
2061  } else {
2062  cm_msg(MLOG,"","%s: \"%s\" is currently set",
2063  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2064  tpost);
2065  }
2066  }
2067  // nothing assigned to mask
2068  } else {
2069  if (*(info->demand+channel) != -2.f)
2070  cm_msg(MLOG,"","Channel %d(%s) %f set to %f",channel,
2071  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2072  *(info->demand+channel),value);
2073  else
2074  cm_msg(MLOG,"","Channel %d(%s) set to %f", channel,
2075  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2076  value);
2077  }
2078  }
2079  } // for all masks
2080  if ((tc+k)->ns <= 0) {
2081  if (*(info->demand+channel) != -2.f)
2082  cm_msg(MLOG,"","Channel %d(%s) %f set to %f",channel,
2083  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2084  *(info->demand+channel),value);
2085  else
2086  cm_msg(MLOG,"","Channel %d(%s) set to %f", channel,
2087  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2088  value);
2089  }
2090  break;
2091  }
2092  } // for all channels of this type
2093  if (gfatype[j].nc <= 0) {
2094  if (*(info->demand+channel) != -2.f)
2095  cm_msg(MLOG,"","Channel %d(%s) %f set to %f",channel,
2096  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2097  *(info->demand+channel),value);
2098  else
2099  cm_msg(MLOG,"","Channel %d(%s) set to %f", channel,
2100  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2101  value);
2102  }
2103  break;
2104  }
2105  } // for all GFA types
2106  }
2107  }
2108 #else
2109  if (*(info->demand+channel) != -2.f)
2110  cm_msg(MLOG,"","Channel %d(%s) %f set to %f",channel,
2111  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2112  *(info->demand+channel),value);
2113  else
2114  cm_msg(MLOG,"","Channel %d(%s) set to %f", channel,
2115  info->settings.channel_names+CHN_NAME_LENGTH*channel,
2116  value);
2117 #endif
2118 
2119  // no :COM:2 readout therefore simulate readout of :COM:2 channel
2120  if (strstr(info->settings.channel_names+CHN_NAME_LENGTH*channel,":COM:2"))
2121  *(info->array_m+channel) = value;
2122 
2123  ca_put(DBR_FLOAT, info->pchid[channel], &value);
2124 #ifdef GFA_SPECIFIC
2125  // GFA specific handling : maybe post pending command
2126  if (!info->handling_disabled) {
2127  char *ds;
2128 
2129  // disable GFA specific handling
2130  info->handling_disabled = TRUE;
2131 
2132  // type and channel specific changes of other channel(s)
2133  // when specific flags of this channel set and apply rule to new value
2134  // e.g. Z flag : Turn power off when new value is zero
2135  ds = info->settings.dtype+DTYPE_LENGTH*channel;
2136 #ifdef MIDEBUG2
2137  cm_msg(MLOG,"","Looking for device specific handling of Device type %s",ds);
2138 #endif
2139  if ((strcmp(ds,"BEND")==0) || (strcmp(ds,"QUAD")==0) ||
2140  (strcmp(ds,"SEPT")==0) || (strcmp(ds,"STER")==0) ||
2141  (strcmp(ds,"PS" )==0) ||
2142  (strcmp(ds,"TS" )==0) || (strcmp(ds,"KICKER")==0)) {
2143  char chname[CHN_NAME_LENGTH];
2144  char *tpos;
2145 
2146 #ifdef MIDEBUG2
2147  cm_msg(MLOG,"","Device type %s found",ds);
2148 #endif
2149  strcpy(chname,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2150 
2151  if ((tpos = strstr(chname,":SOL:2")) != NULL) {
2152  int i;
2153 
2154  strcpy(tpos,":COM:2");
2155 #ifdef MIDEBUG2
2156  cm_msg(MLOG,"","Looking for channel %s",chname);
2157 #endif
2158  for (i = 0; i < info->num_channels; i++) {
2159  if (i==channel) continue;
2160  if (strcmp(info->settings.channel_names+CHN_NAME_LENGTH*i,chname)
2161  == 0) {
2162  float tval;
2163  char *chflgs;
2164 
2165  tval = (*info->demand+i); // current value of other
2166  // evaluate channel flags of channel
2167  chflgs = info->settings.chnflags+CHNFLAGS_LENGTH*channel;
2168  if (strchr(chflgs,'P')) {
2169  tval = 0.f; // ON
2170  }
2171  if (strchr(chflgs,'Z')) {
2172  if (value == 0.f)
2173  tval = 1.f; // OFF
2174  else
2175  tval = 0.f; // ON
2176  }
2177  if (strchr(chflgs,'N')) {
2178  if (value > 0.f)
2179  tval = 0.f; // ON
2180  else
2181  tval = 1.f; // OFF
2182  }
2183  if (tval != *(info->demand+i)) {
2184  if (*(info->found+i) && *(info->settings.used+i) &&
2185  !*(info->settings.readonly+i)) {
2186  HNDLE hDB;
2187  epics_ca_set(info, i, tval, FALSE, forced_update);
2188 #ifndef OMIT_ODBUPDATE
2189  // update ODB
2190  cm_get_experiment_database(&hDB, NULL);
2191  if (info->hkeyDemand != 0) {
2192  INT mstatus;
2193  mstatus = db_set_data_index(hDB, info->hkeyDemand, &tval,
2194  sizeof(float), i, TID_FLOAT);
2195  if (mstatus != DB_SUCCESS) ; // NIY message
2196 
2197  }
2198 #endif
2199  }
2200  }
2201  break; // channel found
2202  }
2203  }
2204  }
2205 
2206  } else if (strcmp(ds,"FENTE")==0) {
2207  char chname[CHN_NAME_LENGTH];
2208  char *tpos;
2209 
2210 #ifdef MIDEBUG2
2211  cm_msg(MLOG,"","Device type %s found",ds);
2212 #endif
2213  strcpy(chname,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2214 
2215  if ((tpos = strstr(chname,":SOL:2")) != NULL) {
2216  int i;
2217 
2218  strcpy(tpos,":COM:2");
2219 #ifdef MIDEBUG2
2220  cm_msg(MLOG,"","Looking for channel %s",chname);
2221 #endif
2222  for (i = 0; i < info->num_channels; i++) {
2223  if (i==channel) continue;
2224  if (strcmp(info->settings.channel_names+CHN_NAME_LENGTH*i,chname)
2225  == 0) {
2226  float tval;
2227  char *chflgs;
2228 
2229  tval = (*info->demand+i); // current value of other
2230  // evaluate channel flags of channel
2231  chflgs = info->settings.chnflags+CHNFLAGS_LENGTH*channel;
2232  if (strchr(chflgs,'V')) {
2233  tval = 3.f; // 3 MOVE_TO_SOL
2234  }
2235  if (tval != *(info->demand+i)) {
2236  if (*(info->found+i) && *(info->settings.used+i) &&
2237  !*(info->settings.readonly+i)) {
2238  HNDLE hDB;
2239 
2240  epics_ca_set(info, i, tval, FALSE, forced_update);
2241  // update ODB
2242  cm_get_experiment_database(&hDB, NULL);
2243  if (info->hkeyDemand != 0) {
2244  INT mstatus;
2245  mstatus = db_set_data_index(hDB, info->hkeyDemand, &tval,
2246  sizeof(float), i, TID_FLOAT);
2247  if (mstatus != DB_SUCCESS) ; // NIY message
2248  }
2249  }
2250  }
2251  break;
2252  }
2253  }
2254  }
2255  } else if (strcmp(ds,"BX")==0) {
2256  // DO NOTHING
2257  } else if (strcmp(ds,"HVPS")==0) {
2258  // DO NOTHING (too complicated to be handled correctly)
2259  } else {
2260  cm_msg(MLOG,"","epics_ca_set: GFA type %s is currently not handled",
2261  ds);
2262  }
2263  // enable GFA specific handling
2264  info->handling_disabled = FALSE;
2265  }
2266 #endif /* #ifdef GFA_SPECIFIC */
2267  if (flush) {
2268  status = ca_pend_io(0.01);
2269 #ifdef MIDEBUGP
2270  cm_msg(MLOG,"","ca_pend_io(0.01) status 0X%x = \"%s\"", status,
2271  ca_message(status));
2272 #endif
2273  }
2274  } else {
2275  cm_msg(MLOG,"","SET: channel %d(%s) NO WRITE ACCESS!",
2276  channel,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2277  }
2278  } else {
2279  cm_msg(MLOG,"","SET: channel %d(%s) is (currently?) not connected! "
2280  "Channel state is %d = \"%s\"", channel,
2281  info->settings.channel_names+CHN_NAME_LENGTH*channel, castate,
2282  castatestr(castate));
2283  }
2284  } else if (!*(info->found+channel)){
2285  cm_msg(MLOG,"","SET: channel %d(%s) is (currently?) not enabled!",
2286  channel,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2287  } else if (!*(info->settings.used+channel)) {
2288  cm_msg(MLOG,"","SET: channel %d(%s) is not used!",
2289  channel,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2290  } else if (*(info->settings.readonly+channel)) {
2291  cm_msg(MLOG,"","SET: channel %d(%s) is set read ONLY!",
2292  channel,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2293  } else if (!*(info->iscmd+channel)){
2294  cm_msg(MLOG,"","SET: channel %d(%s) is not a channel to be set!",
2295  channel,info->settings.channel_names+CHN_NAME_LENGTH*channel);
2296  }
2297  } else {
2298 #ifdef MIDEBUG
2299  cm_msg(MLOG,"","Demand and readout (%f) did not change -> not updating channel"
2300  " %d(%s)", value, channel,
2301  info->settings.channel_names+CHN_NAME_LENGTH*channel);
2302 #endif
2303  }
2304  if (info->lastset) *(info->lastset+channel) = ss_time();
2305  if (info->demand) *(info->demand+channel) = value;
2306  }
2307  }
2308 #ifdef MIDEBUG1
2309  cm_msg(MLOG,""," --epics_ca_set()");
2310 #endif
2311 #ifdef MIDEBUGF
2312  if (fp) fprintf(fp,"%u : --epics_ca_set(channel=%d, value=%f)\n", ss_time(),
2313  channel,value);
2314 #endif
2315  return FE_SUCCESS;
2316 }
INT epics_ca_set_all ( CA_INFO info,
INT  channels,
float  value 
)

Definition at line 2320 of file epics_ca.c.

Referenced by epics_ca().

2320  {
2321  INT status,i;
2322 
2323 #ifdef MIDEBUG1
2324  cm_msg(MLOG,""," ++epics_ca_set_all(%d channels)",channels);
2325 #endif
2326  for (i = 0; i < MIN(info->num_channels, channels); i++)
2327  epics_ca_set(info, i, value, FALSE, FALSE);
2328 
2329  status = ca_pend_io(0.01);
2330 #ifdef MIDEBUGP
2331  cm_msg(MLOG,"","ca_pend_io(0.01) status 0X%x = \"%s\"", status, ca_message(status));
2332 #endif
2333 
2334 #ifdef MIDEBUG1
2335  cm_msg(MLOG,""," --epics_ca_set_all()");
2336 #endif
2337  return FE_SUCCESS;
2338 }
INT epics_ca_set_label ( CA_INFO info,
INT  channel,
char *  label 
)

Definition at line 2342 of file epics_ca.c.

Referenced by epics_ca().

2342  {
2343  int status;
2344  char str[256];
2345  chid chan_id;
2346 
2347 #ifdef MIDEBUG1
2348  cm_msg(MLOG,""," ++epics_ca_set_label(channel %d, label %s)", channel, label);
2349 #endif
2350  sprintf(str, "%s.DESC", info->settings.channel_names+CHN_NAME_LENGTH*channel);
2351  status = ca_create_channel(str, NULL, NULL, 0, &chan_id);
2352  if (status == ECA_NORMAL) {
2353  status = ca_pend_io(2.0);
2354 #ifdef MIDEBUGP
2355  cm_msg(MLOG,"","ca_pend_io(2.0) status 0X%x = \"%s\"", status, ca_message(status));
2356 #endif
2357  if (status == ECA_NORMAL) {
2358  if (ca_state(chan_id) == cs_conn) {
2359  status = ca_put(ca_field_type(chan_id), chan_id, label);
2360  status = ca_pend_io(0.01);
2361 #ifdef MIDEBUGP
2362  status = cm_msg(MLOG,"", "ca_pend_io(0.01) status 0X%x = \"%s\"", status,
2363  ca_message(status));
2364 #endif
2365  } else {
2366  cm_msg(MLOG,"","epics_ca_set_label: Channel %s is not connected", str);
2367  }
2368  } else {
2369  cm_msg(MERROR,"epics_ca_set_label","%s not found", str);
2370  }
2371  ca_clear_channel(chan_id);
2372  } else {
2373  cm_msg(MERROR,"epics_ca_set_label","ca_create_channel(%s) Returned status "
2374  "0X%x = \"%s\"",str,status,ca_message(status));
2375  }
2376 #ifdef MIDEBUG1
2377  cm_msg(MLOG,""," --epics_ca_set_label()");
2378 #endif
2379  return FE_SUCCESS;
2380 }
INT epics_ca_set_pending ( CA_INFO info,
BOOL  pending 
)

Definition at line 396 of file epics_ca.c.

References CA_INFO::pending, and status.

396  {
397  INT status;
398 
399  status = FE_SUCCESS;
400  if (info) {
401  if (pending) {
402  if (info->pending == 0) cm_msg(MLOG,"","*** Blocking Tolerance InRange checking");
403  info->pending++;
404  } else {
405  if (info->pending > 0) {
406  info->pending--;
407  if (info->pending == 0)
408  cm_msg(MLOG,"","*** Tolerance InRange checking not blocked anymore");
409  } else {
410  cm_msg(MERROR,"epics_ca_set_pending","PROGRAMMING ERROR releasing pending "
411  "AND info->pending == 0");
412  }
413  }
414  }
415  return status;
416 }

Variable Documentation

GFA_type gfatype[]
Initial value:
= {
{ "BEND", "Bending magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "QUAD", "Quadrupol magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "SEPT", "Septum magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "STER", "Steering magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "PS", "Spinrot magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "TS", "Shim magnet", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "KICKER", "Kicker HV", KPS1chan, sizeof(KPS1chan)/sizeof(GFA_channel)},
{ "BX", "Beam Blocker", KVchan, sizeof(KVchan )/sizeof(GFA_channel)},
{ "FENTE", "Slit system", Slitchan, sizeof(Slitchan)/sizeof(GFA_channel)},
{ "HVPS", "Spinrot/Sep HV", HVPSchan, sizeof(HVPSchan)/sizeof(GFA_channel)},
{ "", "Terminator", NULL, 0},
}

Definition at line 314 of file epics_ca.c.

GFA_channel HVPSchan[]
Initial value:
= {
{"HVN:STA:2", "Neg. HV Status", HVPSsta, sizeof(HVPSsta)/sizeof(GFA_mask), FALSE},
{"HVN:ISTI:2", "Neg. HV Current Measured [uA]", NULL, 0, FALSE},
{"HVN:ISTV:2", "Neg. HV Voltage Measured [kV]", NULL, 0, FALSE},
{"HVN:SOLI:2", "Neg. HV Current Demand [uA]", NULL, 0, TRUE},
{"HVN:SOLV:2", "Neg. HV Voltage Demand [kV]", NULL, 0, TRUE},
{"HVP:STA:2", "Pos. HV Status", HVPSsta, sizeof(HVPSsta)/sizeof(GFA_mask), FALSE},
{"HVP:ISTI:2", "Pos. HV Current Measured [uA]", NULL, 0, FALSE},
{"HVP:ISTV:2", "Pos. HV Voltage Measured [kV]", NULL, 0, FALSE},
{"HVP:SOLI:2", "Pos. HV Current Demand [uA]", NULL, 0, TRUE},
{"HVP:SOLV:2", "Pos. HV Voltage Demand [kV]", NULL, 0, TRUE},
{"HV:COM:2", "HV IDLE=0/ON=1/OFF=2/SET=3", NULL, 0, TRUE},
{"HV:XRAY:2", "Xray ", NULL, 0, FALSE},
{"HV:VAC:2", "Vacuum", NULL, 0, FALSE},
{"HV:TIME:2", "TimeStamp of SoftIOC", NULL, 0, FALSE}
}

Definition at line 296 of file epics_ca.c.

GFA_mask HVPSsta[]
Initial value:
= {
{ 0x0001, "Status", HVPSstamsg, sizeof(HVPSstamsg)/sizeof(GFA_msg)}
}

Definition at line 292 of file epics_ca.c.

GFA_msg HVPSstamsg[]
Initial value:
= {
{0x0000, "OFF" },
{0x0001, "ON" }
}

Definition at line 287 of file epics_ca.c.

GFA_channel KPS1chan[]
Initial value:
= {
{ ":STA:1", "Status", KPS1sta, sizeof(KPS1sta)/sizeof(GFA_mask), FALSE},
{ ":COM:2", "Command", KPS1cmd, sizeof(KPS1cmd)/sizeof(GFA_mask), TRUE },
{ ":IST:2", "Istwert", NULL, 0, FALSE},
{ ":SOL:2", "Sollwert", NULL, 0, TRUE }
}

Definition at line 233 of file epics_ca.c.

GFA_mask KPS1cmd[]
Initial value:
= {
{ 0x0003, "Command", KPS1cmdmsg, sizeof(KPS1cmdmsg)/sizeof(GFA_msg)}
}

Definition at line 228 of file epics_ca.c.

GFA_msg KPS1cmdmsg[]
Initial value:
= {
{0x0000, "ON" },
{0x0001, "OFF" },
{0x0002, "RESET"}
}

Definition at line 222 of file epics_ca.c.

GFA_mask KPS1sta[]
Initial value:
= {
{ 0x000F, "Status", KPS1stamsg000f, sizeof(KPS1stamsg000f)/sizeof(GFA_msg)},
{ 0x0010, "Status", KPS1stamsg0010, sizeof(KPS1stamsg0010)/sizeof(GFA_msg)},
{ 0x0020, "Status", KPS1stamsg0020, sizeof(KPS1stamsg0020)/sizeof(GFA_msg)},
{ 0x0040, "Status", KPS1stamsg0040, sizeof(KPS1stamsg0040)/sizeof(GFA_msg)},
{ 0x0080, "Status", KPS1stamsg0080, sizeof(KPS1stamsg0080)/sizeof(GFA_msg)},
{ 0x0400, "Status", KPS1stamsg0400, sizeof(KPS1stamsg0400)/sizeof(GFA_msg)},
{ 0x0800, "Status", KPS1stamsg0800, sizeof(KPS1stamsg0800)/sizeof(GFA_msg)},
{ 0x1000, "Status", KPS1stamsg1000, sizeof(KPS1stamsg1000)/sizeof(GFA_msg)},
{ 0x2000, "Status", KPS1stamsg2000, sizeof(KPS1stamsg2000)/sizeof(GFA_msg)},
{ 0x8000, "Status", KPS1stamsg8000, sizeof(KPS1stamsg8000)/sizeof(GFA_msg)}
}

Definition at line 205 of file epics_ca.c.

GFA_msg KPS1stamsg000f[]
Initial value:
= {
{0x0000, "Soll and Ist NOT ON and NOT OFF" },
{0x0001, "Soll ON - Ist NOT ON and NOT OFF" },
{0x0002, "Soll OFF - Ist NOT ON and NOT OFF" },
{0x0003, "Soll ON and OFF - Ist NOT ON and NOT OFF" },
{0x0004, "Soll NOT ON and NOT OFF - Ist ON" },
{0x0005, "On" },
{0x0006, "Soll OFF - Ist ON" },
{0x0007, "Soll ON and OFF, Ist ON" },
{0x0008, "Soll NOT ON and NOT OFF - Ist OFF" },
{0x0009, "Soll On - Ist OFF" },
{0x000a, "Off" },
{0x000b, "Soll ON and OFF - Ist OFF" },
{0x000c, "Soll NOT ON and NOT OFF - Ist ON and OFF" },
{0x000d, "Soll ON - Ist ON and OFF" },
{0x000e, "Soll OFF - Ist ON and OFF" },
{0x000f, "Soll ON and OFF - Ist ON and OFF" }
}

Definition at line 118 of file epics_ca.c.

GFA_msg KPS1stamsg0010[]
Initial value:
= {
{0x0010, "In Local Mode" }
}

Definition at line 141 of file epics_ca.c.

GFA_msg KPS1stamsg0020[]
Initial value:
= {
{0x0000, "SG Status NOK" }
}

Definition at line 148 of file epics_ca.c.

GFA_msg KPS1stamsg0040[]
Initial value:
= {
{0x0000, "PSC Status NOK" }
}

Definition at line 155 of file epics_ca.c.

GFA_msg KPS1stamsg0080[]
Initial value:
= {
{0x0000, "Config Error" }
}

Definition at line 162 of file epics_ca.c.

GFA_msg KPS1stamsg0400[]
Initial value:
= {
{0x0400, "IST == SOLA" },
{0x0000, "IST <> SOLA" }
}

Definition at line 170 of file epics_ca.c.

GFA_msg KPS1stamsg0800[]
Initial value:
= {
{0x0000, "IST < Low Limit" }
}

Definition at line 177 of file epics_ca.c.

GFA_msg KPS1stamsg1000[]
Initial value:
= {
{0x0000, "IST > High Limit" }
}

Definition at line 184 of file epics_ca.c.

GFA_msg KPS1stamsg2000[]
Initial value:
= {
{0x0000, "SOL<>SOLA" }
}

Definition at line 191 of file epics_ca.c.

GFA_msg KPS1stamsg8000[]
Initial value:
= {
{0x0000, "PSC Link Error" }
}

Definition at line 198 of file epics_ca.c.

GFA_channel KVchan[]
Initial value:
= {
{ ":STA:1", "Status", KVsta, sizeof(KVsta)/sizeof(GFA_mask), FALSE},
{ ":COM:2", "Commmand", KVcom, sizeof(KVcom)/sizeof(GFA_mask), TRUE },
}

Definition at line 110 of file epics_ca.c.

GFA_mask KVcom[]
Initial value:
= {
{ 0x0001, "Commands", KVcommsg0001, sizeof(KVcommsg0001)/sizeof(GFA_msg)}
}

Definition at line 106 of file epics_ca.c.

GFA_msg KVcommsg0001[]
Initial value:
= {
{0x0000, "OPEN" },
{0x0001, "CLOSE" }
}

Definition at line 101 of file epics_ca.c.

GFA_mask KVsta[]
Initial value:
= {
{ 0x0003, "Status", KVstamsg0003, sizeof(KVstamsg0003)/sizeof(GFA_msg)},
{ 0x0004, "Status", KVstamsg0004, sizeof(KVstamsg0004)/sizeof(GFA_msg)},
{ 0x0008, "Status", KVstamsg0008, sizeof(KVstamsg0008)/sizeof(GFA_msg)},
}

Definition at line 94 of file epics_ca.c.

GFA_msg KVstamsg0003[]
Initial value:
= {
{0x0000, "Moving" },
{0x0001, "Open" },
{0x0002, "Closed" },
{0x0003, "Error" }
}

Definition at line 77 of file epics_ca.c.

GFA_msg KVstamsg0004[]
Initial value:
= {
{0x0004, "Pass Bew.OK" },
{0x0000, "Pass Bew.NOK" }
}

Definition at line 84 of file epics_ca.c.

GFA_msg KVstamsg0008[]
Initial value:
= {
{0x0008, "RPS Bew.OK" },
{0x0000, "RPS Bew.NOK" }
}

Definition at line 89 of file epics_ca.c.

GFA_channel Slitchan[]
Initial value:
= {
{":STA:1", "Status", Slitsta,sizeof(Slitsta)/sizeof(GFA_mask),FALSE},
{":COM:2", "Command", Slitcmd,sizeof(Slitcmd)/sizeof(GFA_mask),TRUE },
{":IST1:2","Position ADC rohwert", NULL, 0, FALSE},
{":SOL:2", "Sollwert", NULL, 0, TRUE },
{":POSA:2","Position ADC gefiltert", NULL, 0, FALSE}
}

Definition at line 278 of file epics_ca.c.

GFA_mask Slitcmd[]
Initial value:
= {
{ 0x0007, "Command", Slitcmdmsg, sizeof(Slitcmdmsg)/sizeof(GFA_msg)}
}

Definition at line 273 of file epics_ca.c.

GFA_msg Slitcmdmsg[]
Initial value:
= {
{0x0000, "MOVE_TO_CW" },
{0x0001, "MOVE_TO_CCW" },
{0x0002, "STOP" },
{0x0003, "MOVE_TO_SOL" },
{0x0004, "SOL=POSA" },
{0x0005, "RESET_CW" },
{0x0006, "RESET_CCW" }
}

Definition at line 263 of file epics_ca.c.

GFA_mask Slitsta[]
Initial value:
= {
{ 0x0307, "Status", Slitstamsg307, sizeof(Slitstamsg307)/sizeof(GFA_msg)},
{ 0x0300, "Status", Slitstamsg300, sizeof(Slitstamsg300)/sizeof(GFA_msg)}
}

Definition at line 256 of file epics_ca.c.

GFA_msg Slitstamsg300[]
Initial value:
= {
{0x0100, "moving CW" } ,
{0x0200, "moving CCW" }
}

Definition at line 251 of file epics_ca.c.

GFA_msg Slitstamsg307[]
Initial value:
= {
{0x0001, "in CW limit switch" },
{0x0002, "in CCW limit switch" },
{0x0003, "not connected/command error" },
{0x0004, "stopped" },
{0x0005, "in CW limit switch and stopped" },
{0x0006, "in CCW limit switch and stopped" }
}

Definition at line 242 of file epics_ca.c.

char smsg[128]
static

Definition at line 43 of file epics_ca.c.

Referenced by castatestr(), and epics_ca_init().