AlcapDAQ  1
vmic_ttl.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <unistd.h>
5 #include <sys/io.h>
6 
7 #include "midas.h"
8 
9 #include "crate.h"
10 #include "diag.h"
11 #include "odb_wrapper.h"
12 #include "vme.h"
13 
14 INT vmic_ttl_init();
17 INT vmic_ttl_poll_live();
18 
20  vmic_ttl_init, // init
21  NULL, // exit
22  NULL, // pre_bor
23  NULL, // bor
24  NULL, // eor
25  vmic_ttl_poll_live, // poll_live
26  NULL, // poll_dead
27  vmic_ttl_start_block, // start_block
28  vmic_ttl_stop_block, // stop_block
29  NULL, // read
30 };
31 
32 /*
33  * VMIC registers.
34  */
35 #define VMIC_PORT12 0x12
36 #define VMIC_PORT34 0x10
37 #define VMIC_PORT56 0x16
38 #define VMIC_PORT78 0x14
39 #define VMIC_CSRU 0x20
40 #define VMIC_CSRL 0x21
41 
42 /*
43  * VMIC outputs
44  */
45 #define VMIC_OUTPUT_1 0x00004000
46 #define VMIC_OUTPUT_2 0x00000800
47 #define VMIC_OUTPUT_3 0x00000100
48 #define VMIC_OUTPUT_4 0x00000030
49 #define VMIC_OUTPUT_5 0x00000004
50 #define VMIC_OUTPUT_6 0x00800000
51 #define VMIC_OUTPUT_7 0x00100000
52 #define VMIC_OUTPUT_8 0x00020000
53 
54 /*
55  * ...and their aliases for muCap:
56  */
57 #define VMIC_OUTPUT_EW1 VMIC_OUTPUT_1
58 #define VMIC_OUTPUT_EW2 VMIC_OUTPUT_2
59 #define VMIC_OUTPUT_LATCH_RESET VMIC_OUTPUT_3
60 #define VMIC_OUTPUT_CAENandCOMP VMIC_OUTPUT_4
61 #define VMIC_OUTPUT_CRATE4 VMIC_OUTPUT_5
62 #define VMIC_OUTPUT_SOFTSTOP VMIC_OUTPUT_6
63 #define VMIC_OUTPUT_CLOCK_RESET VMIC_OUTPUT_7
64 #define VMIC_OUTPUT_START1 (VMIC_OUTPUT_1 | VMIC_OUTPUT_4)
65 #define VMIC_OUTPUT_START2 (VMIC_OUTPUT_2 | VMIC_OUTPUT_4)
66 
67 /*
68  * VMIC input channels.
69  */
70 #define VMIC_INPUT_END_EVENT 62
71 #define VMIC_INPUT_BLOCK 59
72 
73 /*
74  *
75  */
77 static struct vme_handle *vmic_handle;
80 
81 static BOOL vmic_enabled;
82 
83 static BOOL not_really_started;
84 
85 extern INT cycle_ram();
86 
87 /*
88  *
89  */
90 void vmic_set(DWORD new_value)
91 {
92  WORD low = new_value & 0xffff;
93  WORD high = (new_value >> 16) & 0xffff;
94 
95  if(low != vmic_current_low) {
96  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT12, low);
97  vmic_current_low = low;
98  }
99 
100  if(high != vmic_current_high) {
101  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT34, high);
102  vmic_current_high = high;
103  }
104 }
105 
106 /*
107  *
108  */
109 void vmic_turn_on(DWORD new_channels)
110 {
111  WORD low = vmic_current_low | (new_channels & 0xffff);
112  WORD high = vmic_current_high | ((new_channels >> 16) & 0xffff);
113  vmic_set((high << 16) | low);
114 }
115 
117 {
118  short status, mask;
119 
120  int reg;
121 
122  // decide which port and bit we're reading
123  if ((channel >= 0) && (channel < 16)) {
124  reg = VMIC_PORT56;
125  mask = (1 << channel);
126  } else if ((channel >= 16) && (channel < 32)) {
127  reg = VMIC_PORT78;
128  mask = (1 << (channel-16));
129  } else if ((channel >= 32) && (channel < 48)) {
130  reg = VMIC_PORT12;
131  mask = (1 << (channel-32));
132  } else if ((channel >= 48) && (channel < 64)) {
133  reg = VMIC_PORT34;
134  mask = (1 << (channel-48));
135  }
136 
137  status = vme_read_d16(vmic_handle, vmic_vme_base | reg);
138 
139  if ((status & mask)==0) {
140  return 0;
141  } else {
142  return 1;
143  }
144 }
145 
146 /*
147  * vmic_ttl_init
148  *
149  */
151 {
152  vmic_enabled =
153  (odb_find_key("/Equipment/Crate %d/Settings/VMIC", crate_number) != 0);
154 
155  if(!vmic_enabled) {
156  return SUCCESS;
157  }
158 
159  diag_print(4,"vmic_ttl_init()\n");
160 
161  vmic_vme_base =
162  odb_get_word("/Equipment/Crate %d/Settings/VMIC/vme address", crate_number);
163 
164  struct vme_mapping_ctrl mapping = {
169  };
170 
171  vmic_handle = vme_open(vmic_vme_base, mapping, 0x100, 0);
172  if(vmic_handle == NULL) {
173  diag_print(0, "Unable to open handle for VMIC TTL I/O register\n");
174  return FE_ERR_HW;
175  }
176 
177  // Set control register: port 4 as input, all others as output
178  int status =
179  vme_write_d16_checked(vmic_handle, vmic_vme_base | VMIC_CSRU, 0xefff);
180  if(status != SUCCESS) {
181  diag_print(0, "Unable to write CSRU value to VMIC TTL I/O register\n");
182  return FE_ERR_HW;
183  }
184 
185  // Wait a moment to allow this setting to take effect
186  ss_sleep(400);
187 
188  // Turn off all outputs
189 /*
190  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT12, 0);
191  vmic_current_high = 0;
192  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT34, 0);
193  vmic_current_low = 0;
194 */
195  vmic_set(0);
196 
197  not_really_started = 0;
198 
199  return SUCCESS;
200 }
201 
202 /*
203  * vmic_ttl_start_block
204  *
205  */
207 {
208  if(!vmic_enabled) {
209  return SUCCESS;
210  }
211 
212  diag_print(4,"vmic_ttl_start_block()\n");
213 
214  // Is crate 4 going to be part of the cycle?
215  DWORD maybe_crate4 = 0;
216  if(crate_is_participating(4)) {
217  maybe_crate4 = VMIC_OUTPUT_CRATE4;
218  }
219 
220  // If there is already a block in progress, refuse to start another one.
221  int block_input = vmic_read_input(VMIC_INPUT_BLOCK);
222  if(block_input != 0) {
223  diag_print(0, "BLOCK is high when it should be low!\n");
224  vmic_set(0);
225  ss_sleep(10);
227  ss_sleep(10);
228  vmic_set(0);
229  ss_sleep(100);
230  not_really_started = 1;
231  return FE_ERR_HW;
232  }
233 
234  // First send a pulse on the latch reset line:
235  vmic_set(0);
236  vmic_set(VMIC_OUTPUT_LATCH_RESET | maybe_crate4);
237 // vmic_set(0 | maybe_crate4);
238 
239 #if 1
240  // Now check whether the reset was effective--did it make the EndEvent
241  // signal clear?
243  diag_print(0, "END_EVENT signal not clearing with reset\n");
244  not_really_started = 1;
245  return FE_ERR_HW;
246  }
247 #endif
248 
249 #if 0
250  // Try another reset...going straight into the start of the cycle
251  // so that the compressor timing matches the CAENs.
252  vmic_set(VMIC_OUTPUT_LATCH_RESET | maybe_crate4);
253 #endif
254 
255  int ram = cycle_ram();
256 
257  diag_print(2, "Starting RAM %d cycle\n", ram);
258 
259  //
260  // Finally, start the cycle.
261  //
262  if(ram == 1) {
263  vmic_set(VMIC_OUTPUT_START1 | maybe_crate4);
264  vmic_set(VMIC_OUTPUT_EW1 | maybe_crate4);
265  } else {
266  vmic_set(VMIC_OUTPUT_START2 | maybe_crate4);
267  vmic_set(VMIC_OUTPUT_EW2 | maybe_crate4);
268  }
269 
270  // We don't currently have any way of testing that the cycle started
271  // correctly. Perhaps something to think about adding...
272  not_really_started = 0;
273  return SUCCESS;
274 }
275 
276 /*
277  * vmic_ttl_stop_block
278  *
279  */
281 {
282  if(!vmic_enabled) {
283  return SUCCESS;
284  }
285 
286  diag_print(4,"vmic_ttl_stop_block()\n");
287 
288  // set SOFTSTOP output
290 }
291 
292 /*
293  * vmic_ttl_poll_live()
294  *
295  * Called periodically while a block is active; performs active readout.
296  *
297  * Returns:
298  * - ordinarily 0,
299  * - a request for a "soft stop" end-of-block, or
300  * - an error code
301  */
303 {
304  if(!vmic_enabled) {
305  return SUCCESS;
306  }
307 
308  //diag_print(4,"vmic_ttl_poll_live()\n");
309 
310  INT end_event = vmic_read_input(VMIC_INPUT_END_EVENT);
311 
312  if(end_event || not_really_started) {
313  vmic_set(0);
314  return FE_END_BLOCK;
315  } else {
316  return SUCCESS;
317  }
318 }
319