source: drsdaq/VME/struck/sis1100/V2.02/test/camac.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: 15.2 KB
Line 
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/time.h>
6#include <unistd.h>
7#include <stdlib.h>
8#include <string.h>
9#include <fcntl.h>
10#include <sys/mman.h>
11#include <sys/ioctl.h>
12#include "devopen.h"
13
14#include "dev/pci/sis1100_var.h"
15#include "dev/pci/sis5100_map.h"
16
17typedef int (*camacproc)(struct devinfo* dev, u_int32_t N, u_int32_t A,
18 u_int32_t F, u_int32_t* data);
19
20#define CAMAC(base, N, A, F) \
21 ((base)+(((F)<<9)|((N)<<4)|(A)))
22
23static int
24camac_mapped(struct devinfo* dev, u_int32_t N,
25 u_int32_t A, u_int32_t F, u_int32_t* data)
26{
27 volatile u_int32_t* camaddr=CAMAC(dev->base_remote, N, A, F);
28 if ((F&0x18)==0x10) {
29 u_int32_t err;
30 *camaddr=*data;
31 err=*(dev->base_ctrl+0x2B);
32 *data=(~err<<24)&0xc0000000;
33 if (err && !(err&0xc0)) {
34 printf("camac_mapped: err=0x%x\n", err);
35 return -1;
36 }
37 } else { /* read or control */
38 *data=*camaddr^0xc0000000;
39 }
40 return 0;
41}
42
43static int
44camac_mapped_w(struct devinfo* dev, u_int32_t N,
45 u_int32_t A, u_int32_t F, u_int32_t* data)
46{
47 volatile u_int32_t* camaddr=CAMAC(dev->base_remote, N, A, F);
48 u_int32_t err;
49
50 *camaddr=*data;
51 err=*(dev->base_ctrl+0x2B);
52 *data=(~err<<24)&0xc0000000;
53 if (err && !(err&0xc0)) {
54 printf("camac_mapped: err=0x%x\n", err);
55 return -1;
56 }
57 return 0;
58}
59
60static int
61camac_mapped_r(struct devinfo* dev, u_int32_t N,
62 u_int32_t A, u_int32_t F, u_int32_t* data)
63{
64 *data=(*CAMAC(dev->base_remote, N, A, F))^0xc0000000;
65 return 0;
66}
67
68static int
69camac_driver_vme(struct devinfo* dev, u_int32_t N,
70 u_int32_t A, u_int32_t F, u_int32_t* data)
71{
72 struct sis1100_vme_req req;
73 unsigned int camac_addr;
74 int res;
75
76 camac_addr=((F&0x1f)<<11)+((N&0x1f)<<6)+((A&0xf)<<2);
77
78 req.size=4;
79 req.am=-1;
80 req.addr=camac_addr;
81 req.data=*data;
82 req.error=0;
83
84 if ((F&0x18)==0x10) {
85 res=ioctl(dev->p_remote, SIS3100_VME_WRITE, &req);
86 *data=(~req.error<<24)&0xc0000000;
87 } else {
88 res=ioctl(dev->p_remote, SIS3100_VME_READ, &req);
89 *data=req.data^0xc0000000;
90 }
91 if (res) {
92 printf("driver_vme: res=%d\n", res);
93 return -1;
94 }
95 if (req.error&~0x2c0) {
96 printf("driver_vme: error=0x%x\n", req.error);
97 return -1;
98 }
99 return 0;
100}
101
102static __inline int
103camac_driver(struct devinfo* dev, u_int32_t N, u_int32_t A, u_int32_t F,
104 u_int32_t* data)
105{
106 struct sis1100_camac_req req;
107 int res;
108
109 req.N=N;
110 req.A=A;
111 req.F=F;
112 req.data=*data;
113 req.error=0;
114
115 res=ioctl(dev->p_remote, SIS5100_CNAF, &req);
116 if (res) {
117 printf("driver_camac: res=%d\n", res);
118 return -1;
119 }
120 if (req.error) {
121 printf("driver_camac: error=0x%x\n", req.error);
122 return -1;
123 }
124 *data=req.data;
125 return 0;
126}
127#if 0
128static void
129test_inhibit(int p)
130{
131 struct sis1100_ctrl_reg reg;
132
133 while (1) {
134 reg.offset=0x100;
135 reg.val=0xffff;
136 reg.error=0;
137 if (ioctl(p, SIS1100_CTRL_WRITE, &reg)<0) {
138 fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): %s\n",
139 strerror(errno));
140 return;
141 }
142 if (reg.error!=0) {
143 fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): error=0x%x\n",
144 reg.error);
145 return;
146 }
147 sleep(1);
148
149 reg.offset=0x100;
150 reg.val=0xffff0000;
151 reg.error=0;
152 if (ioctl(p, SIS1100_CTRL_WRITE, &reg)<0) {
153 fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): %s\n",
154 strerror(errno));
155 return;
156 }
157 if (reg.error!=0) {
158 fprintf(stderr, "ioctl(SIS1100_CTRL_WRITE, 0x100): error=0x%x\n",
159 reg.error);
160 return;
161 }
162 sleep(1);
163 }
164}
165#else
166static void
167test_inhibit(int p)
168{
169 int d=1;
170
171 while (1) {
172 if (ioctl(p, SIS5100_CCCI, &d)<0) {
173 fprintf(stderr, "ioctl(SIS5100_CCCI, %d): %s\n",
174 d, strerror(errno));
175 return;
176 }
177 d=1-d;
178 sleep(1);
179 }
180}
181#endif
182
183static int
184camac_count_driver_vme(struct devinfo* dev, int num)
185{
186 struct sis1100_vme_req req;
187 unsigned int camac_addr;
188 int N=20;
189 int A=0;
190 int F=16;
191 int p;
192
193 p=dev->p_ctrl;
194 if (p<0) p=dev->p_remote;
195 if (p<0) return -1;
196
197 camac_addr=((F&0x1f)<<11)+((N&0x1f)<<6)+((A&0xf)<<2);
198
199 req.size=4;
200 req.am=-1;
201 req.addr=camac_addr;
202
203 for (; num; num--) {
204 int res;
205
206 req.data=num;
207
208 res=ioctl(p, SIS3100_VME_WRITE, &req);
209 if (res) {
210 printf("camac_write: res=%d\n", res);
211 return -1;
212 }
213 if (req.error&0x3f) {
214 printf("camac_write: error=0x%x\n", req.error);
215 return -1;
216 }
217 }
218 return 0;
219}
220
221static int
222camac_count_driver_camac(struct devinfo* dev, int num)
223{
224 struct sis1100_camac_req req;
225 int p;
226
227 p=dev->p_ctrl;
228 if (p<0) p=dev->p_remote;
229 if (p<0) return -1;
230
231 req.N=20;
232 req.A=0;
233 req.F=16;
234
235 for (; num; num--) {
236 int res;
237 req.data=num;
238
239 res=ioctl(p, SIS5100_CNAF, &req);
240 if (res) {
241 printf("camac_write: res=%d\n", res);
242 return -1;
243 }
244 if (req.error) {
245 printf("camac_write: error=0x%x\n", req.error);
246 return -1;
247 }
248 }
249 return 0;
250}
251
252static int
253camac_count_mapped(struct devinfo* dev, int num)
254{
255 int F=16;
256 int N=20;
257 int A=0;
258 volatile u_int32_t *addr;
259
260 if (!dev->base_remote) return -1;
261 addr=CAMAC(dev->base_remote, N, A, F);
262
263 for (; num; num--) {
264 *addr=num;
265 }
266 return 0;
267}
268
269typedef int (*countproc)(struct devinfo* dev, int num);
270
271static void
272camac_count(struct devinfo* dev, countproc proc, const char* text, int num)
273{
274 struct timeval tv0, tv1;
275 float tdiff, tcycle;
276 int res;
277
278 gettimeofday(&tv0, 0);
279 res=proc(dev, num);
280 gettimeofday(&tv1, 0);
281 if (res) return;
282 tdiff=tv1.tv_sec-tv0.tv_sec;
283 tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.;
284 tcycle=(tdiff*1000000.)/num;
285 printf("%s: %f us\n", text, tcycle);
286}
287
288static void
289fill_4302(struct devinfo* dev, camacproc proc, const char* text, int N,
290 int num)
291{
292 u_int32_t d, i, x;
293 struct timeval tv0, tv1;
294 float tdiff, tcycle;
295
296 d=1;
297 proc(dev, N, 1, 17, &d); /* set MODE to CAMAC */
298 camac_mapped(dev, N, 1, 1, &d); printf("mode: %x\n", d&3);
299 gettimeofday(&tv0, 0);
300 for (x=100; x; x--) {
301 d=0;
302 proc(dev, N, 0, 17, &d); /* set ADDR */
303 for (i=0; i<num; i++) {
304 d=i;
305 proc(dev, N, 0, 16, &d); /* write data */
306 if (!(d&0xc0000000)) {
307 printf("fill_4302: QX: 0x%08x\n", d);
308 break;
309 }
310 }
311 }
312 gettimeofday(&tv1, 0);
313 camac_mapped(dev, N, 0, 1, &d); printf("addr after write: 0x%x; i=%d\n", d, i);
314 tdiff=tv1.tv_sec-tv0.tv_sec;
315 tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.;
316 tcycle=(tdiff*1000000.)/i/100.;
317 printf("%s: %f us\n", text, tcycle);
318}
319
320static void
321fill_4302_mapped(struct devinfo* dev, const char* text, int N,
322 int num)
323{
324 struct timeval tv0, tv1;
325 float tdiff, tcycle;
326 u_int32_t d, i=0, x;
327 volatile u_int32_t err;
328 volatile u_int32_t* addr;
329 volatile u_int32_t* base=dev->base_remote;
330
331 err=*(dev->base_ctrl+0x2B);
332 d=*(dev->base_ctrl+0x2A);
333 printf("(b) initial err: 0x%x, balance=%d\n", err, d);
334
335 *CAMAC(base, N, 1, 17)=1; /* set MODE to CAMAC */
336 err=*(dev->base_ctrl+0x2B);
337 d=*(dev->base_ctrl+0x2A);
338 printf("(set mode) err: 0x%x, balance=%d\n", err, d);
339
340 /* read mode */
341 d=*CAMAC(base, N, 1, 1); printf("mode: %x\n", d&3);
342 err=*(dev->base_ctrl+0x2B);
343 d=*(dev->base_ctrl+0x2A);
344 printf("(read mode) err: 0x%x, balance=%d\n", err, d);
345
346 gettimeofday(&tv0, 0);
347 for (x=100; x; x--) {
348 addr=CAMAC(base, N, 0, 17);
349 *addr=0; /* set ADDR */
350 err=*(dev->base_ctrl+0x2B);
351 if (err) {
352 d=*(dev->base_ctrl+0x2A);
353 printf("(set addr) err: 0x%x, balance=%d\n", err, d);
354 goto raus;
355 }
356 addr=CAMAC(base, N, 0, 16);
357 for (i=0; i<num; i++) {
358 *addr=i;
359 /*err=*(dev->base_ctrl+0x2B);*/
360/*
361 * if (err&0xc0) {
362 * printf("fill_4302_mapped: QX: 0x%x\n", err);
363 * goto raus;
364 * }
365 */
366 }
367 do {
368 err=*(dev->base_ctrl+0x2B);
369 d=*(dev->base_ctrl+0x2A);
370 } while (err==0x107);
371 if (err) {
372 printf("(after write) err: 0x%x, balance=%d\n", err, d);
373 goto raus;
374 }
375 }
376raus:
377 gettimeofday(&tv1, 0);
378 addr=CAMAC(base, N, 0, 1);
379 d=*addr; printf("addr after write: 0x%x; i=%d\n", d, i);
380 tdiff=tv1.tv_sec-tv0.tv_sec;
381 tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.;
382 tcycle=(tdiff*1000000.)/i/100.;
383 printf("%s: %f us\n", text, tcycle);
384}
385
386static void
387read_4302(struct devinfo* dev, camacproc proc, const char* text, int N, int num)
388{
389 struct timeval tv0, tv1;
390 float tdiff, tcycle;
391 u_int32_t d, i=0, x;
392
393 gettimeofday(&tv0, 0);
394 for (x=100; x; x--) {
395 d=0;
396 camac_mapped(dev, N, 0, 17, &d); /* set ADDR */
397 for (i=0; i<num; i++) {
398 proc(dev, N, 0, 0, &d); /* read data */
399 if (!(d&0xc0000000)) {
400 printf("read_4302: QX: 0x%08x\n", d);
401 goto raus;
402 }
403 if ((d&~0xc0000000)!=(i&0xffefff)) {
404 printf("read_4302[0x%04x]: 0x%x\n", i, d);
405 goto raus;
406 }
407 }
408 }
409raus:
410 gettimeofday(&tv1, 0);
411 proc(dev, N, 0, 1, &d); printf("addr after read: 0x%x, i=%d\n", d, i);
412 tdiff=tv1.tv_sec-tv0.tv_sec;
413 tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.;
414 tcycle=(tdiff*1000000.)/i/100.;
415 printf("%s: %f us\n", text, tcycle);
416}
417
418static void
419read_4302_mapped(struct devinfo* dev, const char* text, int N, int num)
420{
421 struct timeval tv0, tv1;
422 float tdiff, tcycle;
423 u_int32_t d, i=0, x;
424 volatile u_int32_t err;
425 volatile u_int32_t* addr;
426 volatile u_int32_t* base=dev->base_remote;
427
428 addr=CAMAC((u_int32_t*)0, N, 0, 17); /* set ADDR */
429 printf("offset=%p\n", addr);
430
431 gettimeofday(&tv0, 0);
432 for (x=1; x; x--) {
433 addr=CAMAC(base, N, 0, 17); /* set ADDR */
434 *addr=0;
435 err=*(dev->base_ctrl+0x2B);
436 if (err) {
437 d=*(dev->base_ctrl+0x2A);
438 printf("(set addr) err: 0x%x, balance=%d\n", err, d);
439 goto raus;
440 }
441 addr=CAMAC(base, N, 0, 0); /* read data */
442 for (i=0; i<num; i++) {
443 d=*addr;
444 if (d&0xc0000000) {
445 printf("read_4302_mapped: QX: 0x%08x\n", d);
446 goto raus;
447 }
448 if (d!=(i&0xffefff)) {
449 printf("read_4302_mapped[0x%04x]: 0x%x\n", i, d);
450 goto raus;
451 }
452 }
453 }
454raus:
455 gettimeofday(&tv1, 0);
456 addr=CAMAC(base, N, 0, 1);
457 d=*addr; printf("addr after read: 0x%x; i=%d\n", d, i);
458 tdiff=tv1.tv_sec-tv0.tv_sec;
459 tdiff+=(tv1.tv_usec-tv0.tv_usec)/1000000.;
460 tcycle=(tdiff*1000000.)/i/100.;
461 printf("%s: %f us\n", text, tcycle);
462}
463
464int main(int argc, char* argv[])
465{
466 struct devinfo devinfo;
467 struct sis1100_ident ident;
468
469 if (argc<2)
470 {
471 fprintf(stderr, "usage: %s path_1 path_2 ...\n", argv[0]);
472 return 1;
473 }
474
475 if (open_dev(argv+1, &devinfo)<0) return 2;
476
477 {
478 int p;
479
480 p=devinfo.p_ctrl;
481 if (p<0) p=devinfo.p_remote;
482 if (p<0) {
483 printf("neither ctrl nor remote device open.\n");
484 return 3;
485 }
486 if (ioctl(p, SIS1100_IDENT, &ident)<0) {
487 fprintf(stderr, "ioctl(SIS1100_IDENT): %s\n", strerror(errno));
488 return 4;
489 }
490 printf("local:\n");
491 printf(" hw_type : %d\n", ident.local.hw_type);
492 printf(" hw_version: %d\n", ident.local.hw_version);
493 printf(" fw_type : %d\n", ident.local.fw_type);
494 printf(" fw_version: %d\n\n", ident.local.fw_version);
495 printf("remote:\n");
496 printf(" hw_type : %d\n", ident.remote.hw_type);
497 printf(" hw_version: %d\n", ident.remote.hw_version);
498 printf(" fw_type : %d\n", ident.remote.fw_type);
499 printf(" fw_version: %d\n\n", ident.remote.fw_version);
500
501 printf(" remote side is %s and %svalid\n",
502 ident.remote_online?"online":"offline",
503 ident.remote_ok?"":"not ");
504
505 if ((ident.local.hw_type!=1)||(ident.local.hw_version!=1)||
506 (ident.local.fw_type!=1)) {
507 fprintf(stderr, "unsupported bord version\n");
508 return 4;
509 }
510 }
511
512 if (devinfo.base_ctrl!=MAP_FAILED) {
513 printf("size of mapped ctrl space : %d\n", devinfo.size_ctrl);
514 }
515 if (devinfo.base_remote!=MAP_FAILED) {
516 struct sis1100_ctrl_reg reg;
517 const int mapidx=0;
518 u_int32_t offs=0x400+16*mapidx;
519 u_int32_t header=0x0f010000; /* 4 byte; remote space 1; no AM */
520 int res=0;
521 int p=devinfo.p_ctrl;
522
523 printf("size of mapped remote space: %d\n", devinfo.size_remote);
524
525 reg.offset=offs+0;
526 reg.val=header;
527 res|=ioctl(p, SIS1100_CTRL_WRITE, &reg);
528
529 reg.offset=offs+4;
530 reg.val=0; /* address modifier */
531 res|=ioctl(p, SIS1100_CTRL_WRITE, &reg);
532
533 reg.offset=offs+8;
534 reg.val=0; /* address base */
535 res|=ioctl(p, SIS1100_CTRL_WRITE, &reg);
536
537 reg.offset=offs+12;
538 reg.val=0; /* high part of 64 bit address */
539 res|=ioctl(p, SIS1100_CTRL_WRITE, &reg);
540 if (res) {
541 printf("mapping of CAMAC space failed.\n");
542 }
543 }
544
545#if 0
546 if (devinfo.p_remote>=0) {
547 test_inhibit(devinfo.p_ctrl);
548 } else {
549 printf("remote path not open.\n");
550 }
551#endif
552
553#if 0
554 camac_count(&devinfo, camac_count_driver_vme, "vme ", 1000000);
555 camac_count(&devinfo, camac_count_driver_camac, "camac ", 1000000);
556 camac_count(&devinfo, camac_count_mapped, "mapped", 1000000);
557#endif
558
559#if 0
560 {
561 int p;
562 p=devinfo.p_ctrl;
563 if (p<0) p=devinfo.p_remote;
564 if (p>=0) {
565 camac_count_driver_vme(p);
566 } else {
567 printf("neither ctrl nor remote device open.\n");
568 }
569 }
570 {
571 int p;
572 p=devinfo.p_ctrl;
573 if (p<0) p=devinfo.p_remote;
574 if (p>=0) {
575 camac_count_driver_camac(p);
576 } else {
577 printf("neither ctrl nor remote device open.\n");
578 }
579 }
580 {
581 if (devinfo.base_remote!=MAP_FAILED) {
582 camac_count_mapped(devinfo);
583 } else {
584 printf("CAMAC space not mapped.\n");
585 }
586 }
587#endif
588
589#if 0
590 fill_4302(&devinfo, camac_driver_vme, "vme", 21, 16384);
591 read_4302(&devinfo, camac_driver_vme, "vme", 21, 16384);
592 fill_4302(&devinfo, camac_driver, "camac", 21, 16384);
593 read_4302(&devinfo, camac_driver, "camac", 21, 16384);
594 fill_4302_mapped(&devinfo, "fill_mapped_m", 21, 1000);
595 fill_4302(&devinfo, camac_mapped_w, "fill_mapped_w", 21, 1000);
596 read_4302(&devinfo, camac_mapped_r, "read_mapped_r", 21, 1000);
597 read_4302(&devinfo, camac_mapped, "read_mapped", 21, 1000);
598#endif
599 read_4302_mapped(&devinfo, "read_mapped_m", 21, 1000);
600
601 return 0;
602}
Note: See TracBrowser for help on using the repository browser.