AlcapDAQ
1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
crate6_CAEN_TDC
sis3600.cpp
Go to the documentation of this file.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#include "midas.h"
6
7
#include "
crate.h
"
8
#include "
vme.h
"
9
#include "
odb_wrapper.h
"
10
#include "
diag.h
"
11
12
INT
sis3600_bor
();
13
INT
sis3600_eor
();
14
INT
sis3600_poll_live
();
15
INT
sis3600_read
(
char
*pevent);
16
17
struct
readout_module
sis3600_module
= {
18
NULL,
// init
19
NULL,
// exit
20
NULL,
// pre_bor
21
sis3600_bor
,
// bor
22
sis3600_eor
,
// eor
23
sis3600_poll_live
,
// poll_live
24
NULL,
// poll_dead
25
NULL,
// start_cycle
26
NULL,
// stop_cycle
27
sis3600_read
,
// read
28
};
29
30
31
32
#define SIS3600_MAX_DMA_SIZE 256
33
#define SIS3600_MAX_SIZE (32*1024*4)
34
#define ACTIVE_READOUT_BUFFER_SIZE (32*1024*4)
35
#define ACTIVE_READOUT_MAX_PER_POLL (2*1024)
36
37
struct
sis3600
{
38
bool
enabled
;
39
bool
do_active_readout
;
40
struct
vme_handle
*
vme_handle
;
41
unsigned
long
vme_base
;
42
char
odb_name
[20];
43
char
bank_name
[20];
44
int
active_readout_size
;
45
unsigned
char
active_readout_buffer
[
ACTIVE_READOUT_BUFFER_SIZE
];
46
};
47
48
#define MAX_SIS3600 4
49
struct
sis3600
sis3600
[
MAX_SIS3600
];
50
51
#define SIS3600_CSR 0x000
52
#define SIS3600_KA_CLEAR 0x020
53
#define SIS3600_KA_ENABLENEXT 0x028
54
#define SIS3600_KA_RESET 0x060
55
#define SIS3600_OUTBUF 0x100
56
57
#define SIS3600_CSR_FIFO_EMPTY_MASK 0x00000100
58
#define SIS3600_CSR_FIFO_ALMOST_EMPTY_MASK 0x00000200
59
60
/*
61
* sis3600_bor1
62
*
63
* Initialize one SIS3600 module.
64
*/
65
INT
sis3600_bor1
(
struct
sis3600
*sis)
66
{
67
// Get the VME base address of the module
68
sis->
vme_base
=
odb_get_dword
(
"/Equipment/Crate %d/Settings/%s/vme address"
,
69
crate_number
, sis->
odb_name
);
70
71
// Open a VME handle for memory-mapped access
72
struct
vme_mapping_ctrl
mapping = {
73
VMEMAP_DWIDTH_32
,
74
VMEMAP_ASPACE_A32
,
75
VMEMAP_SUPUSERAM_SUPER
,
76
VMEMAP_PRGDATAAM_DATA
77
};
78
79
struct
vme_handle
*
handle
=
80
vme_open
(sis->
vme_base
, mapping, 0x200,
SIS3600_MAX_DMA_SIZE
);
81
sis->
vme_handle
=
handle
;
82
83
// Reset
84
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_KA_RESET
, 0x1);
85
86
// Clear for the next block
87
sis->
active_readout_size
= 0;
88
89
// Read back current status register and check it
90
DWORD
csr =
vme_read_d32
(handle, sis->
vme_base
|
SIS3600_CSR
);
91
if
(csr != 0x00000300) {
92
// diag_print(0, "Unexpected status 0x%08x on %s after reset, disabling\n",
93
printf
(
"Unexpected status 0x%08x on %s after reset, disabling\n"
,
94
csr, sis->
odb_name
);
95
sis->
enabled
=
false
;
96
return
FE_ERR_HW;
97
}
98
99
// Continue setup
100
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_CSR
, 0x08010000);
101
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_KA_CLEAR
, 0x1);
102
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_KA_ENABLENEXT
, 0x1);
103
104
// Again check the status register value
105
csr =
vme_read_d32
(handle, sis->
vme_base
|
SIS3600_CSR
);
106
if
(csr != 0x00018300) {
107
// diag_print(0, "Unexpected status 0x%08x on %s after setup, disabling\n",
108
printf
(
"Unexpected status 0x%08x on %s after setup, disabling\n"
,
109
csr, sis->
odb_name
);
110
sis->
enabled
=
false
;
111
return
FE_ERR_HW;
112
}
113
114
printf
(
"Enabled %s successfully\n"
, sis->
odb_name
);
115
116
// Determine whether we're supposed to do active readout
117
sis->
do_active_readout
=
118
odb_get_bool
(
"/Equipment/Crate %d/Settings/%s/Active Readout mode"
,
119
crate_number
, sis->
odb_name
);
120
121
return
SUCCESS
;
122
}
123
124
/*
125
* sis3600_bor
126
*
127
* Called at the beginning of the run to discover SIS3600 modules
128
* and initialize them.
129
*/
130
INT
sis3600_bor
()
131
{
132
// Use the ODB to find any SIS3600 modules
133
for
(
int
j = 0; j <
MAX_SIS3600
; j++) {
134
135
bool
enabled
=
false
;
136
137
if
(
odb_find_key
(
"/Equipment/Crate %d/Settings/COMP %d"
,
crate_number
, j)) {
138
diag_print
(1,
"ODB says COMP %d is present, "
, j);
139
enabled =
140
odb_get_bool
(
"/Equipment/Crate %d/Settings/COMP %d/enabled status"
,
141
crate_number
, j);
142
if
(enabled) {
143
diag_print
(1,
"and is enabled. Initializing...\n"
);
144
}
else
{
145
diag_print
(1,
"but is disabled.\n"
);
146
}
147
}
148
149
sis3600
[j].
enabled
=
enabled
;
150
151
// Set up the name of the MIDAS bank associated with the module
152
sprintf
(
sis3600
[j].
bank_name
,
"CMP%d"
, j);
153
sprintf
(
sis3600
[j].odb_name,
"COMP %d"
, j);
154
155
if
(enabled) {
156
sis3600_bor1
(&
sis3600
[j]);
157
}
158
}
159
160
return
SUCCESS
;
161
}
162
163
INT
sis3600_eor1
(
struct
sis3600
*sis)
164
{
165
vme_close
(sis->
vme_handle
);
166
return
SUCCESS
;
167
}
168
169
/*
170
* sis3600_eor
171
*
172
* Called at the end of the run to release any resources that may have
173
* been allocated.
174
*/
175
INT
sis3600_eor
()
176
{
177
178
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
179
if
(
sis3600
[
i
].
enabled
) {
180
int
status
=
sis3600_eor1
(&
sis3600
[
i
]);
181
if
(status !=
SUCCESS
) {
182
return
status
;
183
}
184
}
185
}
186
187
return
SUCCESS
;
188
}
189
190
INT
sis3600_fifo_read
(
struct
sis3600
*sis,
unsigned
char
*buffer,
191
int
max_size,
bool
in_active_readout)
192
{
193
// If we're not in the active readout phase, then we simply do a big DMA.
194
// There is a 50% chance of losing one word at the end of the block.
195
if
(!in_active_readout) {
196
int
status
=
vme_dma_read
(sis->
vme_handle
,
197
sis->
vme_base
|
SIS3600_OUTBUF
,
198
buffer,
199
max_size);
200
return
status
;
201
}
202
203
// If we are in the active readout phase, then we have to be more careful.
204
// Before initiating a block transfer, we check whether the CSR
205
// indicates "almost empty." If it does not, a 256 byte (64 word)
206
// block transfer is safe. If it does, then we return nothing; we'll
207
// be back when there is enough data to bother with.
208
int
size
= 0;
209
while
(size < max_size) {
210
211
DWORD
csr =
vme_read_d32
(sis->
vme_handle
, sis->
vme_base
|
SIS3600_CSR
);
212
if
(csr &
SIS3600_CSR_FIFO_ALMOST_EMPTY_MASK
) {
213
return
size
;
214
}
215
216
int
size_this_time =
MIN
(max_size - size, 256);
217
218
int
status
=
vme_dma_read
(sis->
vme_handle
,
219
sis->
vme_base
|
SIS3600_OUTBUF
,
220
buffer + size,
221
size_this_time);
222
223
if
(status >= 0) {
224
size +=
status
;
225
}
226
227
if
(status != size_this_time) {
228
diag_print
(0,
"Retrieved only %d bytes from %s"
, status, sis->
odb_name
);
229
}
230
}
231
232
return
size
;
233
}
234
235
/*
236
* sis3600_poll1
237
*
238
* Performs active readout for a single SIS3600 FIFO.
239
*/
240
INT
sis3600_poll1
(
struct
sis3600
*sis)
241
{
242
// If active readout is not enabled, skip it.
243
if
(!sis->
do_active_readout
) {
244
return
SUCCESS
;
245
}
246
247
// First check how much space we have available in the active
248
// readout buffer.
249
int
size_left =
ACTIVE_READOUT_BUFFER_SIZE
- sis->
active_readout_size
;
250
int
size
=
MIN
(
ACTIVE_READOUT_MAX_PER_POLL
, size_left);
251
252
// Now try to read up to that amount.
253
int
status
=
sis3600_fifo_read
(sis,
254
sis->
active_readout_buffer
+ sis->
active_readout_size
,
255
size,
TRUE
);
256
257
// Check the status
258
if
(status >= 0) {
259
sis->
active_readout_size
+=
status
;
260
}
else
{
261
diag_print
(0,
"Status from sis3600_fifo_read is %d for %s.\n"
, status,
262
sis->
odb_name
);
263
return
FE_ERR_HW;
264
}
265
266
if
(sis->
active_readout_size
==
ACTIVE_READOUT_BUFFER_SIZE
) {
267
return
FE_NEED_STOP
;
268
}
else
{
269
return
SUCCESS
;
270
}
271
}
272
273
/*
274
* sis3600_poll_live
275
*
276
* Called periodically while a block is active; performs active readout.
277
*
278
* Returns:
279
* - ordinarily 0,
280
* - a request for a "soft stop" end-of-block, or
281
* - an error code
282
*/
283
INT
sis3600_poll_live
()
284
{
285
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
286
if
(
sis3600
[
i
].
enabled
) {
287
int
status
=
sis3600_poll1
(&
sis3600
[
i
]);
288
if
(status !=
SUCCESS
) {
289
return
status
;
290
}
291
}
292
}
293
294
return
SUCCESS
;
295
}
296
297
/*
298
* sis3600_read1
299
*
300
* Constructs the MIDAS bank for a single SIS3600.
301
*/
302
INT
sis3600_read1
(
struct
sis3600
*sis,
char
*pevent)
303
{
304
// Create the MIDAS bank
305
DWORD
*pdata;
306
bk_create(pevent, sis->
bank_name
, TID_DWORD, &pdata);
307
308
// Copy data that was read during the active readout
309
int
active_size = sis->
active_readout_size
;
310
memcpy(pdata, sis->
active_readout_buffer
, active_size);
311
312
// Read any data remaining in the module
313
int
status
=
314
sis3600_fifo_read
(sis, ((
unsigned
char
*) pdata) + active_size,
315
SIS3600_MAX_SIZE
,
FALSE
);
316
317
// Check the status
318
int
final_size = 0;
319
if
(status >= 0) {
320
final_size =
status
;
321
}
else
{
322
// handle the error
323
}
324
325
// Close the bank
326
// Modified by VT on Oct-29-2010
327
//bk_close(pevent, pdata + (active_size + final_size)/sizeof(DWORD));
328
int
total_size = active_size + final_size;
329
if
( total_size > 500000 ) {
330
printf
(
"ERROR! Event size is too big (%i). The event will be rejected\n"
);
331
bk_close(pevent, pdata + 0);
332
}
else
{
333
bk_close(pevent, pdata + (active_size + final_size)/
sizeof
(
DWORD
));
334
}
335
336
// Clear for the next block
337
sis->
active_readout_size
= 0;
338
339
// Clear FIFO
340
vme_write_d32
(sis->
vme_handle
, sis->
vme_base
|
SIS3600_KA_CLEAR
, 0x1);
341
342
return
SUCCESS
;
343
}
344
345
/*
346
* sis3600_read
347
*
348
* Called at the end of a block to assemble data from that block into a
349
* MIDAS event.
350
*/
351
INT
sis3600_read
(
char
*pevent)
352
{
353
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
354
if
(
sis3600
[
i
].
enabled
) {
355
int
status
=
sis3600_read1
(&
sis3600
[
i
], pevent);
356
if
(status !=
SUCCESS
) {
357
return
status
;
358
}
359
}
360
}
361
362
return
SUCCESS
;
363
}
Generated by
1.8.4