AlcapDAQ
1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
crate9
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
csr, sis->
odb_name
);
94
sis->
enabled
=
false
;
95
return
FE_ERR_HW;
96
}
97
98
// Continue setup
99
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_CSR
, 0x08010000);
100
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_KA_CLEAR
, 0x1);
101
vme_write_d32
(handle, sis->
vme_base
|
SIS3600_KA_ENABLENEXT
, 0x1);
102
103
// Again check the status register value
104
csr =
vme_read_d32
(handle, sis->
vme_base
|
SIS3600_CSR
);
105
if
(csr != 0x00018300) {
106
diag_print
(0,
"Unexpected status 0x%08x on %s after setup, disabling\n"
,
107
csr, sis->
odb_name
);
108
sis->
enabled
=
false
;
109
return
FE_ERR_HW;
110
}
111
112
// Determine whether we're supposed to do active readout
113
sis->
do_active_readout
=
114
odb_get_bool
(
"/Equipment/Crate %d/Settings/%s/Active Readout mode"
,
115
crate_number
, sis->
odb_name
);
116
117
return
SUCCESS
;
118
}
119
120
/*
121
* sis3600_bor
122
*
123
* Called at the beginning of the run to discover SIS3600 modules
124
* and initialize them.
125
*/
126
INT
sis3600_bor
()
127
{
128
// Use the ODB to find any SIS3600 modules
129
for
(
int
j = 0; j <
MAX_SIS3600
; j++) {
130
131
bool
enabled
=
false
;
132
133
if
(
odb_find_key
(
"/Equipment/Crate %d/Settings/COMP %d"
,
crate_number
, j)) {
134
diag_print
(1,
"ODB says COMP %d is present, "
, j);
135
enabled =
136
odb_get_bool
(
"/Equipment/Crate %d/Settings/COMP %d/enabled status"
,
137
crate_number
, j);
138
if
(enabled) {
139
diag_print
(1,
"and is enabled. Initializing...\n"
);
140
}
else
{
141
diag_print
(1,
"but is disabled.\n"
);
142
}
143
}
144
145
sis3600
[j].
enabled
=
enabled
;
146
147
// Set up the name of the MIDAS bank associated with the module
148
sprintf
(
sis3600
[j].
bank_name
,
"CMP%d"
, j);
149
sprintf
(
sis3600
[j].odb_name,
"COMP %d"
, j);
150
151
if
(enabled) {
152
sis3600_bor1
(&
sis3600
[j]);
153
}
154
}
155
156
return
SUCCESS
;
157
}
158
159
INT
sis3600_eor1
(
struct
sis3600
*sis)
160
{
161
vme_close
(sis->
vme_handle
);
162
return
SUCCESS
;
163
}
164
165
/*
166
* sis3600_eor
167
*
168
* Called at the end of the run to release any resources that may have
169
* been allocated.
170
*/
171
INT
sis3600_eor
()
172
{
173
174
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
175
if
(
sis3600
[
i
].enabled) {
176
int
status
=
sis3600_eor1
(&
sis3600
[
i
]);
177
if
(status !=
SUCCESS
) {
178
return
status
;
179
}
180
}
181
}
182
183
return
SUCCESS
;
184
}
185
186
INT
sis3600_fifo_read
(
struct
sis3600
*sis,
unsigned
char
*buffer,
187
int
max_size,
bool
in_active_readout)
188
{
189
// If we're not in the active readout phase, then we simply do a big DMA.
190
// There is a 50% chance of losing one word at the end of the block.
191
if
(!in_active_readout) {
192
int
status
=
vme_dma_read
(sis->
vme_handle
,
193
sis->
vme_base
|
SIS3600_OUTBUF
,
194
buffer,
195
max_size);
196
return
status
;
197
}
198
199
// If we are in the active readout phase, then we have to be more careful.
200
// Before initiating a block transfer, we check whether the CSR
201
// indicates "almost empty." If it does not, a 256 byte (64 word)
202
// block transfer is safe. If it does, then we return nothing; we'll
203
// be back when there is enough data to bother with.
204
int
size
= 0;
205
while
(size < max_size) {
206
207
DWORD
csr =
vme_read_d32
(sis->
vme_handle
, sis->
vme_base
|
SIS3600_CSR
);
208
if
(csr &
SIS3600_CSR_FIFO_ALMOST_EMPTY_MASK
) {
209
return
size
;
210
}
211
212
int
size_this_time =
MIN
(max_size - size, 256);
213
214
int
status
=
vme_dma_read
(sis->
vme_handle
,
215
sis->
vme_base
|
SIS3600_OUTBUF
,
216
buffer + size,
217
size_this_time);
218
219
if
(status >= 0) {
220
size +=
status
;
221
}
222
223
if
(status != size_this_time) {
224
diag_print
(0,
"Retrieved only %d bytes from %s"
, status, sis->
odb_name
);
225
}
226
}
227
228
return
size
;
229
}
230
231
/*
232
* sis3600_poll1
233
*
234
* Performs active readout for a single SIS3600 FIFO.
235
*/
236
INT
sis3600_poll1
(
struct
sis3600
*sis)
237
{
238
// If active readout is not enabled, skip it.
239
if
(!sis->
do_active_readout
) {
240
return
SUCCESS
;
241
}
242
243
// First check how much space we have available in the active
244
// readout buffer.
245
int
size_left =
ACTIVE_READOUT_BUFFER_SIZE
- sis->
active_readout_size
;
246
int
size
=
MIN
(
ACTIVE_READOUT_MAX_PER_POLL
, size_left);
247
248
// Now try to read up to that amount.
249
int
status
=
sis3600_fifo_read
(sis,
250
sis->
active_readout_buffer
+ sis->
active_readout_size
,
251
size,
TRUE
);
252
253
// Check the status
254
if
(status >= 0) {
255
sis->
active_readout_size
+=
status
;
256
}
else
{
257
diag_print
(0,
"Status from sis3600_fifo_read is %d for %s.\n"
, status,
258
sis->
odb_name
);
259
return
FE_ERR_HW;
260
}
261
262
if
(sis->
active_readout_size
==
ACTIVE_READOUT_BUFFER_SIZE
) {
263
return
FE_NEED_STOP
;
264
}
else
{
265
return
SUCCESS
;
266
}
267
}
268
269
/*
270
* sis3600_poll_live
271
*
272
* Called periodically while a block is active; performs active readout.
273
*
274
* Returns:
275
* - ordinarily 0,
276
* - a request for a "soft stop" end-of-block, or
277
* - an error code
278
*/
279
INT
sis3600_poll_live
()
280
{
281
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
282
if
(
sis3600
[
i
].enabled) {
283
int
status
=
sis3600_poll1
(&
sis3600
[
i
]);
284
if
(status !=
SUCCESS
) {
285
return
status
;
286
}
287
}
288
}
289
290
return
SUCCESS
;
291
}
292
293
/*
294
* sis3600_read1
295
*
296
* Constructs the MIDAS bank for a single SIS3600.
297
*/
298
INT
sis3600_read1
(
struct
sis3600
*sis,
char
*pevent)
299
{
300
// Create the MIDAS bank
301
DWORD
*pdata;
302
bk_create(pevent, sis->
bank_name
, TID_DWORD, &pdata);
303
304
// Copy data that was read during the active readout
305
int
active_size = sis->
active_readout_size
;
306
memcpy(pdata, sis->
active_readout_buffer
, active_size);
307
308
// Read any data remaining in the module
309
int
status
=
310
sis3600_fifo_read
(sis, ((
unsigned
char
*) pdata) + active_size,
311
SIS3600_MAX_SIZE
,
FALSE
);
312
313
// Check the status
314
int
final_size = 0;
315
if
(status >= 0) {
316
final_size =
status
;
317
}
else
{
318
// handle the error
319
}
320
321
// Close the bank
322
bk_close(pevent, pdata + (active_size + final_size)/
sizeof
(
DWORD
));
323
324
// Clear for the next block
325
sis->
active_readout_size
= 0;
326
327
// Clear FIFO
328
vme_write_d32
(sis->
vme_handle
, sis->
vme_base
|
SIS3600_KA_CLEAR
, 0x1);
329
330
return
SUCCESS
;
331
}
332
333
/*
334
* sis3600_read
335
*
336
* Called at the end of a block to assemble data from that block into a
337
* MIDAS event.
338
*/
339
INT
sis3600_read
(
char
*pevent)
340
{
341
for
(
int
i
= 0;
i
<
MAX_SIS3600
;
i
++) {
342
if
(
sis3600
[
i
].enabled) {
343
int
status
=
sis3600_read1
(&
sis3600
[
i
], pevent);
344
if
(status !=
SUCCESS
) {
345
return
status
;
346
}
347
}
348
}
349
350
return
SUCCESS
;
351
}
Generated by
1.8.4