AlcapDAQ  1
frontend.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <time.h>
3 #include "midas.h"
4 
5 
6 /* make frontend functions callable from the C framework */
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 INT crate_number=11;
12 
13 HNDLE hDB;
14 
15 INT ge_ln2_read(char *pevent, INT off);
16 
17 /*-- Globals -------------------------------------------------------*/
18 
19 /* The frontend name (client name) as seen by other MIDAS clients */
20 char *frontend_name = "Germanium";
21 /* The frontend file name, don't change it */
22 char *frontend_file_name = __FILE__;
23 
24 /* frontend_loop is called periodically if this variable is TRUE */
26 
27 /* a frontend status page is displayed with this frequency in ms */
28 INT display_period = 1000;
29 
30 /* maximum event size produced by this frontend */
31 INT max_event_size = 10000;
32 
33 /* maximum event size for fragmented events (EQ_FRAGMENTED) */
34 INT max_event_size_frag = 5 * 1024 * 1024;
35 
36 /* buffer size to hold events */
37 INT event_buffer_size = 10 * 10000;
38 
39 // Globals to this file only
40 static char* sLastFilled = "/Equipment/Germanium/Settings/AlarmCheck/LastFilled";
41 static char* sJustFilled = "/Equipment/Germanium/Settings/AlarmCheck/JustFilled";
42 static char* sTimeLimit = "/Equipment/Germanium/Settings/AlarmCheck/TimeLimit";
43 static char* sAlarmName = "Germanium";
44 static HNDLE kLastFilled;
45 static HNDLE kJustFilled;
46 static HNDLE kTimeLimit;
47 static HNDLE kAlarm;
48 
49 /*-- Equipment list ------------------------------------------------*/
50 
51 BANK_LIST ge_ln2_bank_list[] = {
52  { "LN2F", TID_DWORD, 1, NULL },
53  { "" },
54 };
55 
56 #undef USE_INT
57 
58 EQUIPMENT equipment[] = {
59  {"Germanium", /* equipment name */
60  { 24, 0, /* event ID, trigger mask */
61  "SYSTEM", /* event buffer */
62  EQ_PERIODIC, /* equipment type */
63  0, /* event source */
64  "MIDAS", /* format */
65  TRUE, /* enabled */
66  RO_ALWAYS | RO_ODB, /* read all the time */
67  1000, /* reads spaced by this many ms */
68  0, /* stop run after this event limit */
69  0, /* number of sub events */
70  0, /* log history every event */
71  "", "", "", },
72  ge_ln2_read, /* readout routine */
73  NULL, NULL,
75  },
76 
77  {""}
78 };
79 
80 
81 
82 #ifdef __cplusplus
83 }
84 #endif
85 
86 /*-- Dummy routines ------------------------------------------------*/
87 
89 {
90  return CM_SUCCESS;
91 }
92 
94 {
95  return CM_SUCCESS;
96 }
97 
98 INT poll_event(INT source[], INT count, BOOL test)
99 {
100  return 1;
101 };
102 INT interrupt_configure(INT cmd, INT source[], PTYPE adr)
103 {
104  return 1;
105 };
106 
107 /*-- Frontend Init -------------------------------------------------*/
108 
110 
111  INT status;
112  BOOL default_justfilled = FALSE; // Assuming the worst
113  DWORD default_lastfilled = 0; // Assuming the worst
114  DWORD default_timelimit = 28000; // 8 hours between fills
115  // Get handles to database keys if they exist,
116  // and create otherwise with default worst-case-scenario values
117  status = cm_get_experiment_database(&hDB, NULL);
118  if (status != CM_SUCCESS) {
119  printf("Warning: Could not connect to ODB database!\n");
120  return FE_ERR_HW;
121  }
122 
123  status = db_find_key(hDB, 0, sLastFilled, &kLastFilled);
124  if (status == DB_NO_KEY) {
125  db_create_key(hDB, 0, sLastFilled, TID_DWORD);
126  db_find_key(hDB, 0, sLastFilled, &kLastFilled);
127  status = db_set_value(hDB, 0, sLastFilled, &default_lastfilled, sizeof(default_lastfilled), 1, TID_DWORD);
128  }
129  if (status != DB_SUCCESS) {
130  printf("Warning: Could not access key %s!\n", sLastFilled);
131  return FE_ERR_HW;
132  }
133 
134  status = db_find_key(hDB, 0, sJustFilled, &kJustFilled);
135  if (status == DB_NO_KEY) {
136  db_create_key(hDB, 0, sJustFilled, TID_BOOL);
137  db_find_key(hDB, 0, sJustFilled, &kJustFilled);
138  status = db_set_value(hDB, 0, sJustFilled, &default_justfilled, sizeof(default_justfilled), 1, TID_BOOL);
139  }
140  if (status != DB_SUCCESS) {
141  printf("Warning: Could not access key %s!\n", sJustFilled);
142  return FE_ERR_HW;
143  }
144 
145  status = db_find_key(hDB, 0, sTimeLimit, &kTimeLimit);
146  if (status == DB_NO_KEY) {
147  db_create_key(hDB, 0, sTimeLimit, TID_DWORD);
148  db_find_key(hDB, 0, sTimeLimit, &kTimeLimit);
149  status = db_set_value(hDB, 0, sTimeLimit, &default_timelimit, sizeof(default_timelimit), 1, TID_DWORD);
150  }
151  if (status != DB_SUCCESS) {
152  printf("Warning: Could not access key %s!\n", sTimeLimit);
153  return FE_ERR_HW;
154  }
155 
156  /*
157  // Check if alarm exists and, if not,create it
158  // Copied from midas.c which should take care of this, but doesn't
159  char str[256];
160  sprintf(str, "/Alarms/Alarms/%s", sAlarmName);
161  db_find_key(hDB, 0, str, &kAlarm);
162  if (!kAlarm) {
163  ALARM_ODB_STR(alarm_odb_str); // The initial "run number too large" settings for a default alarm
164  status = db_create_record(hDB, 0, str, strcomb(alarm_odb_str));
165  db_find_key(hDB, 0, str, &kAlarm);
166  if (!kAlarm) {
167  cm_msg(MERROR, "ge_ln2_init", "Cannot create alarm record");
168  return FE_ERR_HW;
169  }
170  BOOL al_active = TRUE; // Alarm should be on
171  INT al_type = AT_EVALUATED; // Alarm type is evaluated; it looks for a certain ODB value to be too large
172  char al_cond[256] = ""; // Not a "conditional" alarm in the MIDAS sense
173  char al_class[32] = "Alarm"; // When triggered, the alarm will have black letters on red background
174  char al_msg[80] = "Germanium must be filled!"; // Message on banner
175  db_set_value(hDB, kAlarm, "Active", &al_active, sizeof(al_active), 1, TID_BOOL);
176  db_set_value(hDB, kAlarm, "Type", &al_type, sizeof(al_type), 1, TID_INT);
177  db_set_value(hDB, kAlarm, "Condition", al_cond, sizeof(al_cond), 1, TID_STRING);
178  db_set_value(hDB, kAlarm, "Alarm Class", al_class, sizeof(al_class), 1, TID_STRING);
179  db_set_value(hDB, kAlarm, "Alarm Message", al_msg, sizeof(al_msg), 1, TID_STRING);
180 
181  }
182  */
183  return CM_SUCCESS;
184 }
185 
186 /*-- Frontend Exit -------------------------------------------------*/
187 
189 {
190  return CM_SUCCESS;
191 }
192 
193 /*-- Frontend Loop -------------------------------------------------*/
194 
196 {
197  return CM_SUCCESS;
198 }
199 
200 /*-- Begin of Run --------------------------------------------------*/
201 
202 INT begin_of_run(INT run_number, char *error)
203 {
204  return CM_SUCCESS;
205 }
206 
207 /*-- End of Run ----------------------------------------------------*/
208 
209 INT end_of_run(INT run_number, char *error)
210 {
211  return CM_SUCCESS;
212 }
213 
214 /*-- Pause Run -----------------------------------------------------*/
215 
216 INT pause_run(INT run_number, char *error)
217 {
218  return CM_SUCCESS;
219 }
220 
221 /*-- Resuem Run ----------------------------------------------------*/
222 
223 INT resume_run(INT run_number, char *error)
224 {
225  return CM_SUCCESS;
226 }
227 
228 /*------------------------------------------------------------------*/
229 
230 INT ge_ln2_read(char *pevent, INT off) {
231 
232  static INT status, size;
233  static DWORD lastfilled, now, timelimit;
234  static BOOL justfilled;
235  static DWORD *timesincefill;
236 
237  bk_init(pevent);
238  timesincefill = NULL;
239 
240  // Get recent values
241  size = sizeof(lastfilled);
242  status = db_get_value(hDB, 0, sLastFilled, &lastfilled, &size, TID_DWORD, FALSE);
243  if (status != DB_SUCCESS) {
244  cm_msg(MERROR, "ge_ln2_read", "Error getting last filled time");
245  return 0;
246  }
247 
248  size = sizeof(justfilled);
249  status = db_get_value(hDB, 0, sJustFilled, &justfilled, &size, TID_BOOL, FALSE);
250  if (status != DB_SUCCESS) {
251  cm_msg(MERROR, "ge_ln2_read", "Error getting just filled status");
252  return 0;
253  }
254 
255  size = sizeof(timelimit);
256  status = db_get_value(hDB, 0, sTimeLimit, &timelimit, &size, TID_DWORD, FALSE);
257  if (status != DB_SUCCESS) {
258  cm_msg(MERROR, "ge_ln2_read", "Error getting time limit between fills");
259  return 0;
260  }
261 
262  // If just filled, write time to ODB
263  if (justfilled == TRUE) {
264  lastfilled = (DWORD)time(NULL);
265  status = db_set_value(hDB, 0, sLastFilled, &lastfilled, sizeof(lastfilled), 1, TID_DWORD);
266  if (status != DB_SUCCESS) {
267  cm_msg(MERROR, "gn_ln2_read", "Error setting last filled time");
268  return 0;
269  }
270  justfilled = FALSE;
271  status = db_set_value(hDB, 0, sJustFilled, &justfilled, sizeof(justfilled), 1, TID_BOOL);
272  if (status != DB_SUCCESS) {
273  cm_msg(MERROR, "gn_ln2_read", "Error setting just filled status");
274  return 0;
275  }
276 
277  al_reset_alarm(sAlarmName);
278 
279  bk_create(pevent, "LN2F", TID_DWORD, &timesincefill);
280  *timesincefill = 0;
281  bk_close(pevent, ++timesincefill);
282 
283  return bk_size(pevent);
284  }
285 
286  // Check the status
287  bk_create(pevent, "LN2F", TID_DWORD, &timesincefill);
288  now = (DWORD) time(NULL);
289  *timesincefill = now - lastfilled;
290  if (*timesincefill > timelimit) {
291  al_trigger_alarm(sAlarmName, "Germanium must be filled!", "Alarm", "", AT_INTERNAL);
292  printf("Alarm!\n");
293  }
294  bk_close(pevent, ++timesincefill);
295 
296  return bk_size(pevent);
297 }