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 
72 /*
73  *
74  */
76 static struct vme_handle *vmic_handle;
79 
80 static BOOL vmic_enabled;
81 
82 extern INT cycle_ram();
83 
84 /*
85  *
86  */
87 void vmic_set(DWORD new_value)
88 {
89  WORD low = new_value & 0xffff;
90  WORD high = (new_value >> 16) & 0xffff;
91 
92  if(low != vmic_current_low) {
93  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT12, low);
94  vmic_current_low = low;
95  }
96 
97  if(high != vmic_current_high) {
98  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT34, high);
99  vmic_current_high = high;
100  }
101 }
102 
103 /*
104  *
105  */
106 void vmic_turn_on(DWORD new_channels)
107 {
108  WORD low = vmic_current_low | (new_channels & 0xffff);
109  WORD high = vmic_current_high | ((new_channels >> 16) & 0xffff);
110  vmic_set((high << 16) | low);
111 }
112 
114 {
115  short status, mask;
116 
117  int reg;
118 
119  // decide which port and bit we're reading
120  if ((channel >= 0) && (channel < 16)) {
121  reg = VMIC_PORT56;
122  mask = (1 << channel);
123  } else if ((channel >= 16) && (channel < 32)) {
124  reg = VMIC_PORT78;
125  mask = (1 << (channel-16));
126  } else if ((channel >= 32) && (channel < 48)) {
127  reg = VMIC_PORT12;
128  mask = (1 << (channel-32));
129  } else if ((channel >= 48) && (channel < 64)) {
130  reg = VMIC_PORT34;
131  mask = (1 << (channel-48));
132  }
133 
134  status = vme_read_d16(vmic_handle, vmic_vme_base | reg);
135 
136  if ((status & mask)==0) {
137  return 0;
138  } else {
139  return 1;
140  }
141 }
142 
143 /*
144  * vmic_ttl_init
145  *
146  */
147 INT vmic_ttl_init()
148 {
149  vmic_enabled =
150  (odb_find_key("/Equipment/Crate %d/Settings/VMIC", crate_number) != NULL);
151 
152  if(!vmic_enabled) {
153  return SUCCESS;
154  }
155 
156  vmic_vme_base =
157  odb_get_word("/Equipment/Crate %d/Settings/VMIC/vme address", crate_number);
158 
159  struct vme_mapping_ctrl mapping = {
164  };
165 
166  vmic_handle = vme_open(vmic_vme_base, mapping, 0x100, 0);
167  if(vmic_handle == NULL) {
168  diag_print(0, "Unable to open handle for VMIC TTL I/O register\n");
169  return FE_ERR_HW;
170  }
171 
172  // Set control register: port 4 as input, all others as output
173  int status =
174  vme_write_d16_checked(vmic_handle, vmic_vme_base | VMIC_CSRU, 0xefff);
175  if(status != SUCCESS) {
176  diag_print(0, "Unable to write CSRU value to VMIC TTL I/O register\n");
177  return FE_ERR_HW;
178  }
179 
180  // Wait a moment to allow this setting to take effect
181  ss_sleep(400);
182 
183  // Turn off all outputs
184  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT12, 0);
185  vme_write_d16(vmic_handle, vmic_vme_base | VMIC_PORT34, 0);
186 
187  return SUCCESS;
188 }
189 
190 /*
191  * vmic_ttl_start_block
192  *
193  */
195 {
196  if(!vmic_enabled) {
197  return SUCCESS;
198  }
199 
200  // Is crate 4 going to be part of the cycle?
201  DWORD maybe_crate4 = 0;
202  if(crate_is_participating(4)) {
203  maybe_crate4 = VMIC_OUTPUT_CRATE4;
204  }
205 
206  // First send a pulse on the latch reset line:
207  vmic_set(0);
208  vmic_set(VMIC_OUTPUT_LATCH_RESET | maybe_crate4);
209 // vmic_set(0 | maybe_crate4);
210 
211  // Now check whether the reset was effective--did it make the EndEvent
212  // signal clear?
214  diag_print(0, "END_EVENT signal not clearing with reset\n");
215  return FE_ERR_HW;
216  }
217 
218 #if 0
219  // Try another reset...going straight into the start of the cycle
220  // so that the compressor timing matches the CAENs.
221  vmic_set(VMIC_OUTPUT_LATCH_RESET | maybe_crate4);
222 #endif
223 
224  int ram = cycle_ram();
225 
226  diag_print(2, "Starting RAM %d cycle\n", ram);
227 
228  //
229  // Finally, start the cycle.
230  //
231  if(ram == 1) {
232  vmic_set(VMIC_OUTPUT_START1 | maybe_crate4);
233  vmic_set(VMIC_OUTPUT_EW1 | maybe_crate4);
234  } else {
235  vmic_set(VMIC_OUTPUT_START2 | maybe_crate4);
236  vmic_set(VMIC_OUTPUT_EW2 | maybe_crate4);
237  }
238 
239  // We don't currently have any way of testing that the cycle started
240  // correctly. Perhaps something to think about adding...
241  return SUCCESS;
242 }
243 
244 /*
245  * vmic_ttl_stop_block
246  *
247  */
249 {
250  if(!vmic_enabled) {
251  return SUCCESS;
252  }
253 
254  // set SOFTSTOP output
256 }
257 
258 /*
259  * vmic_ttl_poll_live()
260  *
261  * Called periodically while a block is active; performs active readout.
262  *
263  * Returns:
264  * - ordinarily 0,
265  * - a request for a "soft stop" end-of-block, or
266  * - an error code
267  */
268 INT vmic_ttl_poll_live()
269 {
270  if(!vmic_enabled) {
271  return SUCCESS;
272  }
273 
274  INT end_event = vmic_read_input(VMIC_INPUT_END_EVENT);
275 
276  if(end_event) {
277  vmic_set(0);
278  return FE_END_BLOCK;
279  } else {
280  return SUCCESS;
281  }
282 }
283