source: drsdaq/VME/struck/sis1100/V2.02/test/readout_v729.c@ 23

Last change on this file since 23 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 10.1 KB
Line 
1#ifdef __linux__
2#define _LARGEFILE_SOURCE
3#define _LARGEFILE64_SOURCE
4#define _FILE_OFFSET_BITS 64
5#define LINUX_LARGEFILE O_LARGEFILE
6#else
7#define LINUX_LARGEFILE 0
8#endif
9
10#define _GNU_SOURCE
11#include <stdio.h>
12#include <errno.h>
13#include <string.h>
14#include <sys/types.h>
15#include <unistd.h>
16#include <stdlib.h>
17#include <fcntl.h>
18#include <sys/ioctl.h>
19
20#include "dev/pci/sis1100_var.h"
21
22struct caen_type {
23 int typ;
24 char* name;
25 char* descr;
26};
27
28struct caen_type caen_types[]={
29 {0x34, "V550", "C-RAMS"}, /* 64k */
30 {0x3c, "V551B", "C-RAMS Sequencer"},
31 {0x48, "V729A", "40 MHz ADC"},
32 {0x12e, "V693", "Multihit TDC"},
33 {0x311, "V785", "Peak Sensing ADC"},
34 {0, 0, 0}
35};
36
37const int M=16, N=32;
38
39/****************************************************************************/
40static int find_caen_name(int typ)
41{
42 int i;
43 for (i=0; caen_types[i].name && caen_types[i].typ!=typ; i++);
44 if (caen_types[i].typ==typ)
45 return i;
46 else
47 return -1;
48}
49/****************************************************************************/
50static void
51fill_pipeent(struct sis1100_pipelist* ent, int am, int size, u_int32_t addr)
52{
53 ent->head=((0x00f00000<<size)&0x0f000000)<<(addr&3)|0x00010000;
54 ent->am=am;
55 ent->addr=addr;
56}
57/****************************************************************************/
58static int check_caen_rom(int p, u_int32_t addr)
59{
60 struct sis1100_pipelist list[10];
61 struct sis1100_pipe pipe;
62 u_int16_t ver;
63 u_int16_t rev;
64 u_int32_t manu, board_id, serial;
65 int idx, i;
66 u_int32_t data[10];
67 static const u_int32_t offs[10]={
68 0x8026, /*oui_msb*/
69 0x802a, /*oui*/
70 0x802e, /*oui_lsb*/
71 0x8032, /*ver*/
72 0x8036, /*id_msb*/
73 0x803a, /*id*/
74 0x803e, /*id_lsb*/
75 0x804e, /*rev*/
76 0x8f02, /*ser_msb*/
77 0x8f06 /*ser_lsb*/};
78
79
80 for (i=0; i<10; i++) fill_pipeent(list+i, 9, 2, addr+offs[i]);
81 pipe.num=10;
82 pipe.list=list;
83 pipe.data=data;
84
85 if (ioctl(p, SIS1100_PIPE, &pipe)<0) {
86 printf("ioctl(SIS1100_PIPE): %s\n", strerror(errno));
87 return -1;
88 }
89 if (pipe.error) return 0;
90
91 manu=((data[0]&0xff)<<12)|((data[1]&0xff)<<8)|(data[2]&0xff);
92 if (manu!=0x40e6) return 0;
93
94 board_id=((data[4]&0xff)<<12)|((data[5]&0xff)<<8)|(data[6]&0xff);
95 serial=((data[8]&0xff)<<8)|(data[9]&0xff);
96 ver=data[3];
97 rev=data[7];
98 idx=find_caen_name(board_id);
99 if (idx>=0)
100 printf("0x%08x: CAEN %-6s; version=%d; serial=%d; revision=%d (%s)\n",
101 addr, caen_types[idx].name, ver, serial, rev, caen_types[idx].descr);
102 else
103 printf("0x%08x: CAEN unknown type 0x%x; version=%d; serial=%d; revision=%d\n",
104 addr, board_id, ver, serial, rev);
105 return board_id;
106}
107/****************************************************************************/
108static int check_caen(int p, u_int32_t addr)
109{
110 u_int16_t v[3];
111 int res;
112 struct vmespace space;
113
114 if ((res=check_caen_rom(p, addr))>0) return res;
115
116 space.am=9;
117 space.datasize=2;
118 space.swap=1;
119 space.mapit=0;
120 space.mindmalen=-1;
121
122 if (ioctl(p, SIS1100_SETVMESPACE, &space)<0) {
123 perror("SETVMESPACE");
124 return -1;
125 }
126
127 res=pread(p, v, 6, addr+0xfa);
128 if (res!=6) {
129 /*fprintf(stderr, "read 0x%x+0xfa: %s\n", addr, strerror(errno));*/
130 return 0;
131 }
132
133 if (v[0]==0xfaf5) {
134 int typ, manf, ser, ver, idx;
135
136 typ=v[1]&0x3ff;
137 manf=(v[1]>>10)&0x3f;
138 ser=v[2]&0xfff;
139 ver=(v[2])>12&0xf;
140 idx=find_caen_name(typ);
141 if (idx>=0)
142 printf("0x%08x: CAEN %-6s; version=%d; serial=%d (%s)\n",
143 addr, caen_types[idx].name, ver, ser, caen_types[idx].descr);
144 else
145 printf("0x%08x: CAEN; unknown type 0x%x; version=%d; serial=%d\n",
146 addr, typ, ver, ser);
147 return typ;
148 }
149 return 0;
150}
151/****************************************************************************/
152static u_int32_t find_caen(int p, int code)
153{
154 u_int32_t addr;
155 int idx, res;
156
157 for (addr=0, idx=0; idx<65536; idx++, addr+=0x10000) {
158 res=check_caen(p, addr);
159 if (res<0) return 0xffffffffU;
160 if (res==code) return addr;
161 }
162 return 0xffffffffU;
163}
164/****************************************************************************/
165static int
166write_16(int p, u_int32_t addr, u_int16_t val)
167{
168 struct sis1100_vme_req req;
169 req.size=2;
170 req.am=9;
171 req.addr=addr;
172 req.data=val;
173 req.error=0;
174 if (ioctl(p, SIS3100_VME_WRITE, &req)<0) {
175 fprintf(stderr, "VME_WRITE(0x%08x, 0x%x)\n", addr, val);
176 return -1;
177 }
178 if (req.error){
179 fprintf(stderr, "VME_WRITE(0x%08x, 0x%x): error=0x%x\n",
180 addr, val, req.error);
181 return -1;
182 }
183 return 0;
184}
185/****************************************************************************/
186static u_int16_t
187read_16(int p, u_int32_t addr)
188{
189 struct sis1100_vme_req req;
190 req.size=2;
191 req.am=9;
192 req.addr=addr;
193 req.data=0;
194 req.error=0;
195 if (ioctl(p, SIS3100_VME_READ, &req)<0) {
196 fprintf(stderr, "VME_READ(0x%08x): %s\n", addr, strerror(errno));
197 return -1;
198 }
199 if (req.error){
200 fprintf(stderr, "VME_READ(0x%08x): error=0x%x\n",
201 addr, req.error);
202 return -1;
203 }
204 return req.data&0xffff;
205}
206/****************************************************************************/
207static u_int32_t
208read_32(int p, u_int32_t addr)
209{
210 struct sis1100_vme_req req;
211 req.size=4;
212 req.am=9;
213 req.addr=addr;
214 req.data=0;
215 req.error=0;
216 if (ioctl(p, SIS3100_VME_READ, &req)<0) {
217 fprintf(stderr, "VME_READ(0x%08x): %s\n", addr, strerror(errno));
218 return -1;
219 }
220 if (req.error){
221 fprintf(stderr, "VME_READ(0x%08x): error=0x%x\n",
222 addr, req.error);
223 return -1;
224 }
225 return req.data;
226}
227/****************************************************************************/
228static int
229reset_v729(int p, u_int32_t addr)
230{
231 write_16(p, addr+0x14, 0);
232 return 0;
233}
234/****************************************************************************/
235static int
236setup_v729(int p, u_int32_t addr)
237{
238 int i;
239 u_int16_t cbl, obae, obaf;
240 u_int16_t w[4];
241
242 reset_v729(p, addr);
243
244 /* fifo settings */
245 cbl=4096+12-M;
246 obae=0;
247 obaf=N;
248 w[0]=(obae<<8)&0xff00;
249 w[1]=obae&0x0f00;
250 w[2]=((obaf<<8)&0xff00)|(cbl&0xff);
251 w[3]=(obae&0x0f00)|((cbl>>8)&0xf);
252 for (i=0; i<4; i++) {
253 write_16(p, addr+0x10, w[i]);
254 write_16(p, addr+0x12, 0);
255 }
256
257 /* number of samples */
258 write_16(p, addr+0x8, N);
259
260 /* ofsets */
261 for (i=0; i<4; i++) {
262 write_16(p, addr+0x18+4*i, 0x733); /* DAC+ */
263 write_16(p, addr+0x1a+4*i, 0x733); /* DAC- */
264 }
265
266 write_16(p, addr+0xe, 0); /* control */
267 return 0;
268}
269/****************************************************************************/
270static int
271trigger_v729(int p, u_int32_t addr)
272{
273 write_16(p, addr+0x16, 1);
274 write_16(p, addr+0x16, 0);
275 return 0;
276}
277/****************************************************************************/
278static void print_data(u_int32_t v, int fifo)
279{
280 u_int32_t v0, v1, tc;
281 int e0, e1;
282
283 e0=!(v&0x20000000);
284 e1=!(v&0x40000000);
285 if (v&0x80000000) {
286 tc=v&0xffffff;
287 printf("%c%c time=%d", e0?'-':'X', e1?'-':'X', tc);
288 } else {
289 v0=v&0xfff;
290 v1=(v>>12)&0xfff;
291 printf("%c%c %d %d", e0?'-':'X', e1?'-':'X', v1, v0);
292 }
293}
294/****************************************************************************/
295static int
296read_v729(int p, u_int32_t addr)
297{
298 int count, i;
299 u_int32_t d0[N+1];
300 u_int32_t d1[N+1];
301 struct sis1100_vme_block_req req;
302
303 req.size=4;
304 req.fifo=1;
305 req.num=N+1;
306 req.am=0x9;
307 req.error=0;
308
309 count=read_16(p, addr+0x8);
310 printf("count=%d\n", count);
311 req.addr=addr+0x0;
312 req.data=d0;
313 if (ioctl(p, SIS3100_VME_BLOCK_READ, &req)<0) {
314 printf("VME_BLOCK_READ buffer_0: %s\n", strerror(errno));
315 }
316 if (req.error) {
317 printf("VME_BLOCK_READ buffer_0: error=0x%x\n", req.error);
318 }
319 req.addr=addr+0x4;
320 req.data=d1;
321 if (ioctl(p, SIS3100_VME_BLOCK_READ, &req)<0) {
322 printf("VME_BLOCK_READ buffer_1: %s\n", strerror(errno));
323 }
324 if (req.error) {
325 printf("VME_BLOCK_READ buffer_1: error=0x%x\n", req.error);
326 }
327
328 for (i=0; i<N+1; i++) {
329 printf("d0[%2d]: ", i); print_data(d0[i], 0); printf("\n");
330 }
331 for (i=0; i<N+1; i++) {
332 printf("d1[%2d]: ", i); print_data(d1[i], 1); printf("\n");
333 }
334 return 0;
335}
336/****************************************************************************/
337static int
338stat_v729(int p, u_int32_t addr, char* text)
339{
340 u_int16_t stat, a_events, r_events;
341 a_events=read_16(p, addr+0xa);
342 r_events=read_16(p, addr+0xc);
343 stat=read_16(p, addr+0xe);
344 printf("status 729 %s\n", text);
345 printf(" stat=0x%04x, a_events=%d, r_events=%d\n",
346 stat, a_events, r_events);
347 return 0;
348}
349/****************************************************************************/
350int main(int argc, char* argv[])
351{
352 u_int32_t addr_729;
353 int p;
354
355 if (argc<2) {
356 fprintf(stderr, "usage: %s path\n", argv[0]);
357 return 1;
358 }
359
360 if ((p=open(argv[1], O_RDWR, 0))<0) {
361 fprintf(stderr, "open %s: %s\n", argv[1], strerror(errno));
362 return 1;
363 }
364
365 if (argc>2) {
366 addr_729=strtoul(argv[2], 0, 0);
367 printf("using addr 0x%08x\n", addr_729);
368 } else {
369 addr_729=find_caen(p, 0x48);
370 if (addr_729==0xffffffff) {
371 printf("no V729 found\n");
372 return 1;
373 } else {
374 printf("found V729 at 0x%08x\n", addr_729);
375 }
376 }
377
378 reset_v729(p, addr_729);
379 stat_v729(p, addr_729, "after reset");
380 setup_v729(p, addr_729);
381 stat_v729(p, addr_729, "after setup");
382
383 trigger_v729(p, addr_729);
384 stat_v729(p, addr_729, "after trigger");
385
386 read_v729(p, addr_729);
387
388 stat_v729(p, addr_729, "after read");
389
390 close(p);
391 return 0;
392}
393/****************************************************************************/
394/****************************************************************************/
Note: See TracBrowser for help on using the repository browser.