781 enum channel_state castate;
782 char tpath[MAX_ODB_PATH];
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);
793 cm_msg(MLOG,
"",
"++epics_ca_init(init %d channels)",
channels);
795 cm_msg(MLOG,
"",
"ss_time()'ed Info written to %s",tpath);
802 cm_get_experiment_database(&hDB, NULL);
805 info = calloc(1,
sizeof(
CA_INFO));
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'");
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"));
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));
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));
910 *(info->
status+
i) = ECA_NORMAL;
914 status = db_find_key(hDB,
hKey,
"DD/Loadfile", &subkey);
918 NAME_LENGTH, 1, TID_STRING);
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");
928 db_merge_data(hDB,
hKey,
"DD/Sum_NOT_Connected",
930 status = db_find_key(hDB,
hKey,
"DD/Sum_NOT_Connected", &info->
hkeySNC);
931 if (status == DB_SUCCESS) {
935 sizeof(
int), 1, TID_INT);
942 db_merge_data(hDB,
hKey,
"DD/Sum_NOT_in_Tolerance",
944 status = db_find_key(hDB,
hKey,
"DD/Sum_NOT_in_Tolerance", &info->
hkeySNT);
945 if (status == DB_SUCCESS) {
949 sizeof(
int),1,TID_INT);
956 db_merge_data(hDB,
hKey,
"DD/AlarmWhenNOTConnected",
960 db_merge_data(hDB,
hKey,
"DD/AlarmWhenNOTinTolerance",
967 if (db_find_key(hDB,
hKey,
"DD/EPICS Channel name", &subkey) == DB_NO_KEY) {
976 pnames = calloc(channels, NAME_LENGTH);
977 info->
threshold = calloc(channels,
sizeof(
float));
979 while (!feof(stream)) {
982 if (fgets(tline,
sizeof(tline), stream) != NULL) {
984 if ((p = strchr(tline,
'#'))) *p =
'\0';
986 if (strlen(tline) > 0) {
988 for (j=strlen(tline)-1; j >= 0; j--) {
989 if (!isspace(tline[j])) {
990 if (tline[j] !=
',') {tline[j+1] =
','; tline[j+2] =
'\0';}
995 if ((strlen(tline) > 0)&&(p = strchr(tline,
','))) {
997 cm_msg(MLOG,
"",
"Channel %d: Processing Line %d: %s", i, n, tline);
1001 for (k=strlen(po)-1; k >= 0; k--)
1002 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1003 while (isspace(*po)) po++;
1012 if (strlen(po) >= NAME_LENGTH) *(po+NAME_LENGTH-1) =
'\0';
1013 strcpy(pnames+NAME_LENGTH*i,po);
1017 if (p = strchr(pn,
',')) {
1018 po = pn; pn = p+1; *p =
'\0';
1021 if (p = strchr(pn,
',')) {
1022 po = pn; pn = p+1; *p =
'\0';
1023 if (strchr(po,
'n')||strchr(po,
'N'))
1026 if (p = strchr(pn,
',')) {
1027 po = pn; pn = p+1; *p =
'\0';
1028 for (k=strlen(po)-1; k >= 0; k--)
1029 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1031 if (strlen(po) > 0) {
1035 for (k=0, k1=0; k < strlen(po); k++) {
1037 if (!isspace(*(po+k))) {
1051 if ((p = strchr(pn,
','))) {
1052 po = pn; pn = p+1; *p =
'\0';
1053 for (k=strlen(po)-1; k >= 0; k--)
1054 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1055 while (isspace(*po)) po++;
1056 if (strlen(po) >= NAME_LENGTH) *(po+NAME_LENGTH-1) =
'\0';
1057 if (strlen(po) > 0) {
1058 strcpy(pnames+NAME_LENGTH*i,po);
1061 if ((p = strchr(pn,
','))) {
1062 po = pn; pn = p+1; *p =
'\0';
1063 for (k=strlen(po)-1; k >= 0; k--)
1064 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1065 if (strlen(po) > 0) {
1067 if (sscanf(po,
"%f",&tval) == 1)
1071 if ((p = strchr(pn,
','))) {
1072 po = pn; pn = p+1; *p =
'\0';
1073 for (k=strlen(po)-1; k >= 0; k--)
1074 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1075 if (strlen(po) > 0) {
1077 if (sscanf(po,
"%f",&tval) == 1)
1081 if ((p = strchr(pn,
','))) {
1082 po = pn; pn = p+1; *p =
'\0';
1083 for (k=strlen(po)-1; k >= 0; k--)
1084 if (isspace(*(po+k))) *(po+k)=
'\0';
else break;
1085 if (strlen(po) > 0) {
1087 if ((sscanf(po,
"%f",&tval) == 1) && info->
threshold)
1091 for (k=strlen(pn)-1; k >= 0; k--)
1092 if (isspace(*(pn+k))) *(pn+k)=
'\0';
else break;
1093 if (strlen(pn) > 0) {
1095 if (sscanf(pn,
"%f",&tval) == 1)
1111 cm_msg(MLOG,
"",
"Line %d not handled! %s", n, tline);
1119 cm_msg(MLOG,
"",
"Less channels (%d) loaded from %s than expected (%d) "
1120 "-> recompile with %d or add more channel lines", i,
1123 sprintf(pnames+NAME_LENGTH*i,
"NONE_%d",i);
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,
1131 cm_msg(MLOG,
"",
"Expected number of channels (%d) read ", channels);
1133 if (i > 0) loaded =
TRUE;
1136 cm_msg(MLOG,
"",
"ERROR %d returned when trying to open %s for read access!",
1146 sizeof(BOOL)* channels, channels, TID_BOOL);
1148 sizeof(BOOL)* channels, channels, TID_BOOL);
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);
1159 sizeof(
float)* channels, channels, TID_FLOAT);
1161 sizeof(
float)* channels, channels, TID_FLOAT);
1165 sizeof(
float)* channels, channels, TID_FLOAT);
1178 tchidt = calloc(channels,
sizeof(chid));
1179 tchids = calloc(channels,
sizeof(chid));
1181 if (tchidt && tchids) {
1188 tpos = strchr(tname,
':');
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);
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);
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);
1225 cm_msg(MLOG,
"",
"ca_pend_io(5.0) status 0X%x = \"%s\"",status,ca_message(status));
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));
1237 strcpy(info->
settings.dtype+DTYPE_LENGTH*i,
"**TYPE_NOT_FOUND**");
1240 strcpy(info->
settings.dtype+DTYPE_LENGTH*i,
"**CHAN_NOT_USED**");
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));
1253 strcpy(info->
settings.dsec+DSEC_LENGTH*i,
"**SEC_NOT_FOUND**");
1256 strcpy(info->
settings.dsec+DSEC_LENGTH*i,
"**CHAN_NOT_USED**");
1259 status = ca_pend_io(1.0);
1260 if (status == ECA_TIMEOUT) status = ca_pend_io(1.0);
1262 cm_msg(MLOG,
"",
"ca_pend_io(1.0) status 0X%x = \"%s\"",status,ca_message(status));
1267 cm_msg(MLOG,
"",
"ss_sleep(2000)");
1271 status = ca_pend_event(1.0);
1273 cm_msg(MLOG,
"",
"ca_pend_event(1.0)");
1280 if (ca_state(*(tchidt+i)) != cs_conn) {
1284 strcpy(info->
settings.dtype+DTYPE_LENGTH*i,
"BX");
1291 strcpy(info->
settings.dtype+DTYPE_LENGTH*i,
"HVPS");
1293 strcpy(info->
settings.dtype+DTYPE_LENGTH*i,
"**TYPE_NOT_FOUND**");
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));
1307 if (ca_state(*(tchids+i)) != cs_conn) {
1311 strcpy(info->
settings.dsec+DSEC_LENGTH*i,
"PIM31");
1313 strcpy(info->
settings.dsec+DSEC_LENGTH*i,
"**SEC_NOT_FOUND**");
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));
1324 status = ca_pend_io(1.0);
1325 if (status == ECA_TIMEOUT) status = ca_pend_io(1.0);
1327 cm_msg(MLOG,
"",
"ca_pend_io(1.0) status 0X%x = \"%s\"",status,ca_message(status));
1332 if (tchidt) free(tchidt);
1333 if (tchids) free(tchids);
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);
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);
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),
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);
1374 cm_msg(MLOG,
"",
"ca_pend_io(5.0) status 0X%x = \"%s\"", status, ca_message(status));
1377 cm_msg(MLOG,
"",
"ss_sleep(5000)");
1382 cm_msg(MLOG,
"",
"ca_pend_event(4.0)");
1386 if ((status == ECA_TIMEOUT) || (status == ECA_NORMAL)){
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,
1396 if (!*(info->
found+i)) {
1397 cm_msg(MLOG,
"epics_ca_init",
"Connected to EPICS Channel %d(%s)", i,
1406 cm_msg(MLOG,
"epics_ca_init",
"Returned status %d = \"%s\" of ca_pend_io(A) is not "
1407 "handled", status, ca_message(status));
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);
1415 if (status == DB_NO_KEY) {
1416 struct dbr_ctrl_float *pctrl;
1418 cm_msg(MLOG,
"",
"Query LOW and HIGH of channels");
1419 pctrl = calloc(channels,
sizeof(
struct dbr_ctrl_float));
1422 for (nchans = 0, i = 0; i <
channels; i++) {
1424 if ((castate=ca_state(*(info->
pchid+i))) == cs_conn) {
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));
1434 cm_msg(MLOG,
"",
"Channel %d M flag not set", i);
1437 cm_msg(MLOG,
"",
"Channel %d S flag set", i);
1440 cm_msg(MLOG,
"",
"Channel %d U flag set", i);
1443 cm_msg(MLOG,
"",
"Channel %d not connected", i);
1446 cm_msg(MLOG,
"",
"Channel %d not used", i);
1451 cm_msg(MLOG,
"",
"Queried LOW and HIGH of %d channels",nchans);
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);
1457 cm_msg(MLOG,
"",
"ca_pend_io(5.0) status 0X%x =\"%s\"",status,ca_message(status));
1460 cm_msg(MLOG,
"",
"ss_sleep(1000)");
1465 cm_msg(MLOG,
"",
"ca_pend_event(1.0)");
1469 if ((castate=ca_state(*(info->
pchid+i))) == cs_conn) {
1474 cm_msg(MLOG,
"",
"Channel %d(%s): LOW is %f",
1478 cm_msg(MLOG,
"",
"Channel %d(%s): HIGH is %f",
1490 cm_msg(MERROR,
"epics_ca_init",
"Memory not allocated for struct dbr_ctrl_float");
1496 sizeof(
float)* channels, channels, TID_FLOAT);
1498 sizeof(
float)* channels, channels, TID_FLOAT);
1506 if (*(info->
settings.
used+i) && ((castate=ca_state(info->
pchid[i])) == cs_conn)) {
1512 status = ca_create_subscription(DBR_FLOAT, 1, *(info->
pchid+i), DBE_VALUE,
1514 if (!(status & ECA_NORMAL)) {
1515 cm_msg(MERROR,
"epics_ca_init",
"Channel %d(%s): ca_create_subscription() retur"
1517 status, ca_message(status));
1520 cm_msg(MLOG,
"",
"Channel %d(%s): CA event handler (float) will be installed",
1527 cm_msg(MLOG,
"",
"Channel %d(%s): S flag: CA event handler will NOT be "
1531 cm_msg(MLOG,
"",
"Channel %d(%s): COM Channel : CA event handler will NOT "
1545 status = ca_pend_io(5.0);
1546 if (status == ECA_TIMEOUT) status = ca_pend_io(5.0);
1548 cm_msg(MLOG,
"",
"ca_pend_io(5.0) status 0X%x = \"%s\"", status, ca_message(status));
1551 cm_msg(MLOG,
"",
"ss_sleep(2000)");
1555 status = ca_pend_event(5.0);
1557 cm_msg(MLOG,
"",
"ca_pend_event(5.0)");
1559 if ((status == ECA_TIMEOUT) || (status == ECA_NORMAL)) {
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)){
1567 cm_msg(MLOG,
"",
"Channel %d(%s): Not connected (state %d = \"%s\") -> no CA "
1568 "callback installed and channel disabled", i,
1575 }
else if (status != ECA_NORMAL) {
1577 cm_msg(MLOG,
"epics_ca_init",
"Returned status %d \"%s\" of ca_pend_io(B) is not "
1578 "handled", status, ca_message(status));
1589 sprintf(
smsg,
"Channel %d(%s): %s Type: %s Section: %s Chn_Flags: %s", i,
1592 info->
settings.dtype+DTYPE_LENGTH *i,
1596 sprintf(
smsg,
"Channel %d(%s): R Type: %s Section: %s Chn_Flags: %s", i,
1598 info->
settings.dtype+DTYPE_LENGTH *i,
1602 sprintf(
smsg,
"Channel %d(%s): %s Chn_Flags: %s", i,
1604 *(info->readonly+i)?
"R":
"W",
1623 strcat(
smsg,
" ** Other flag(s) overruled by U and/or S **");
1638 cm_msg(MLOG,
"",
smsg);
1642 cm_msg(MLOG,
"",
smsg);
1646 #ifndef OMIT_ODBUPDATE
1648 if ((status = db_get_path(hDB,
hKey, tpath,
sizeof(tpath))) == DB_SUCCESS) {
1650 for (i = strlen(
"/Equipment/"); i < strlen(tpath); i++) {
1651 if (tpath[i] ==
'/') {
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;
1661 cm_msg(MINFO,
"",
"epics_ca_init: Equipment name is %s", info->
name);
1663 cm_msg(MERROR,
"epics_ca_init",
"ERROR %d getting key path", status);
1669 #ifndef OMIT_ODBUPDATE
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);
1679 #ifndef OMIT_ODBUPDATE
1695 cm_msg(MLOG,
"",
"List of used GFA types");
1709 if (!found)
continue;
1711 cm_msg(MLOG,
"",
"TYPE: \"%s\" \"%s\" %d channels",
gfatype[i].type,
gfatype[i].desc,
1719 if (!(tc+j))
continue;
1721 cm_msg(MLOG,
"",
"**Channel \"%s\" \"%s\" %d masks",(tc+j)->spec,(tc+j)->desc,
1724 cm_msg(MLOG,
"",
"**Channel \"%s\" \"%s\"",(tc+j)->spec,(tc+j)->desc);
1727 for (k = 0; k < (tc+j)->ns; k++) {
1731 if (!(cm+k))
continue;
1732 cm_msg(MLOG,
"",
"****Mask 0x%4.4X",(cm+k)->mask);
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);
1763 if ((
gfatype[n].tc+m) && (strcmp((
gfatype[n].tc+m)->spec,tpos)==0)) {
1769 if (!found && (strcmp(info->
settings.dtype+DTYPE_LENGTH*i,
"HVPS")==0)) {
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);
1791 if (strncmp(info->
settings.dtype+DTYPE_LENGTH*i,
"**",2) == 0)
continue;
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);
1827 cm_msg(MLOG,
"",
"--epics_ca_init()");
1830 if (fp) fprintf(fp,
"%u : --epics_ca_init()\n", ss_time());