00001 /******************************************************************** 00002 00003 Name: esone.c 00004 Created by: Pierre-Andre Amaudruz & Stefan Ritt 00005 00006 Contents: CAMAC interface for ESONE standard using 00007 MCSTD (Midas Camac Standard) 00008 00009 $Log: esone.c,v $ 00010 Revision 1.8 2004/01/08 06:51:40 pierre 00011 Doxygen the file 00012 00013 Revision 1.7 2002/02/01 19:11:33 pierre 00014 doc++ cleanup 00015 00016 Revision 1.6 2001/12/17 18:25:05 pierre 00017 include cclnk, cculk, ccrgl from khy1331 00018 00019 Revision 1.5 2001/08/14 10:27:40 midas 00020 Restore signal handler on error 00021 00022 Revision 1.3 2001/08/14 09:43:30 midas 00023 Initial revision 00024 00025 \********************************************************************/ 00026 00027 /**dox***************************************************************/ 00028 /** @file esone.c 00029 The ESONE CAMAC standard call file 00030 */ 00031 00032 /**dox***************************************************************/ 00033 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00034 00035 #include <stdio.h> 00036 #include "mcstd.h" 00037 #include "esone.h" 00038 00039 #ifndef INLINE 00040 #if defined( _MSC_VER ) 00041 #define INLINE __inline 00042 #elif defined(__GNUC__) 00043 #define INLINE __inline__ 00044 #else 00045 #define INLINE 00046 #endif 00047 #endif 00048 00049 /*-- external representation added to MCSTD ------------------------*/ 00050 00051 INLINE void came_cn(int *ext, const int b, const int c, const int n, const int a) 00052 { 00053 *ext = (b << 24 | (c << 16) | (n << 8) | a); 00054 } 00055 00056 /*------------------------------------------------------------------*/ 00057 INLINE void came_ext(const int ext, int *b, int *c, int *n, int *a) 00058 { 00059 *b = (ext >> 24) & 0x7; 00060 *c = (ext >> 16) & 0x7; 00061 *n = (ext >> 8) & 0x1f; 00062 *a = (ext >> 0) & 0xf; 00063 } 00064 00065 /********************************************************************* 00066 * ESONE functions * 00067 *********************************************************************/ 00068 00069 /**dox***************************************************************/ 00070 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00071 00072 /********************************************************************/ 00073 /** 00074 CAMAC initialization 00075 00076 CAMAC initialization must be called before any other ESONE 00077 subroutine call. 00078 00079 @return void 00080 */ 00081 INLINE void ccinit(void) 00082 { 00083 cam_init(); 00084 } 00085 00086 /********************************************************************/ 00087 /** 00088 CAMAC initialization with return status 00089 00090 fccinit can be called instead of ccinit to determine if the 00091 initialization was successful 00092 00093 @return 1 for success, 0 for failure 00094 */ 00095 INLINE int fccinit(void) 00096 { 00097 if (cam_init() == SUCCESS) 00098 return 1; 00099 00100 return 0; 00101 } 00102 00103 /********************************************************************/ 00104 /** 00105 Control Declaration REGister. 00106 00107 Compose an external address from BCNA for later use. 00108 Accessing CAMAC through ext could be faster if the external address is 00109 memory mapped to the processor (hardware dependent). Some CAMAC controller 00110 do not have this option see @ref AppendixB. 00111 @param ext external address 00112 @param b branch number (0..7) 00113 @param c crate number (0..) 00114 @param n station number (0..30) 00115 @param a sub-address (0..15) 00116 @return void 00117 */ 00118 INLINE void cdreg(int *ext, const int b, const int c, const int n, const int a) 00119 { 00120 came_cn(ext, b, c, n, a); 00121 } 00122 00123 /********************************************************************/ 00124 /** 00125 Control Short Operation. 00126 00127 16 bit operation on a given external CAMAC address. 00128 00129 The range of the f is hardware dependent. The number indicated below are for 00130 standard ANSI/IEEE Std (758-1979) 00131 Execute cam16i for f<8, cam16o for f>15, camc_q for (f>7 or f>23) 00132 00133 @param f function code (0..31) 00134 @param ext external address 00135 @param d data word 00136 @param q Q response 00137 @return void 00138 */ 00139 INLINE void cssa(const int f, int ext, unsigned short *d, int *q) 00140 { 00141 int b, c, n, a, x; 00142 00143 if (f < 8) { 00144 /* read */ 00145 came_ext(ext, &b, &c, &n, &a); 00146 cam16i_q(c, n, a, f, d, &x, q); 00147 } else if (f > 15) { 00148 /* write */ 00149 came_ext(ext, &b, &c, &n, &a); 00150 cam16o_q(c, n, a, f, *d, &x, q); 00151 } else if ((f > 7) || (f > 23)) { 00152 /* command */ 00153 came_ext(ext, &b, &c, &n, &a); 00154 camc_q(c, n, a, f, q); 00155 } 00156 } 00157 00158 /********************************************************************/ 00159 /** 00160 Control Full Operation. 00161 00162 24 bit operation on a given external CAMAC address. 00163 00164 The range of the f is hardware dependent. The number indicated below are for 00165 standard ANSI/IEEE Std (758-1979) 00166 Execute cam24i for f<8, cam24o for f>15, camc_q for (f>7 or f>23) 00167 00168 @param f function code (0..31) 00169 @param ext external address 00170 @param d data long word 00171 @param q Q response 00172 @return void 00173 */ 00174 INLINE void cfsa(const int f, const int ext, unsigned long *d, int *q) 00175 { 00176 int b, c, n, a, x; 00177 00178 if (f < 8) { 00179 /* read */ 00180 came_ext(ext, &b, &c, &n, &a); 00181 cam24i_q(c, n, a, f, d, &x, q); 00182 } else if (f > 15) { 00183 /* write */ 00184 came_ext(ext, &b, &c, &n, &a); 00185 cam24o_q(c, n, a, f, *d, &x, q); 00186 } else if ((f > 7) || (f > 23)) { 00187 /* command */ 00188 came_ext(ext, &b, &c, &n, &a); 00189 camc_q(c, n, a, f, q); 00190 } 00191 } 00192 00193 /********************************************************************/ 00194 /** 00195 Control Crate Clear. 00196 00197 Generate Crate Clear function. Execute cam_crate_clear() 00198 00199 @param ext external address 00200 @return void 00201 */ 00202 INLINE void cccc(const int ext) 00203 { 00204 int b, c, n, a; 00205 00206 came_ext(ext, &b, &c, &n, &a); 00207 cam_crate_clear(c); 00208 } 00209 00210 /********************************************************************/ 00211 /** 00212 Control Crate Z. 00213 00214 Generate Dataway Initialize. Execute cam_crate_zinit() 00215 00216 @param ext external address 00217 @return void 00218 */ 00219 INLINE void cccz(const int ext) 00220 { 00221 int b, c, n, a; 00222 00223 came_ext(ext, &b, &c, &n, &a); 00224 cam_crate_zinit(c); 00225 } 00226 00227 /********************************************************************/ 00228 /** 00229 Control Crate I. 00230 00231 Set or Clear Dataway Inhibit, Execute cam_inhinit_set() /clear() 00232 00233 @param ext external address 00234 @param l action l=0 -> Clear I, l=1 -> Set I 00235 @return void 00236 */ 00237 INLINE void ccci(const int ext, int l) 00238 { 00239 int b, c, n, a; 00240 00241 came_ext(ext, &b, &c, &n, &a); 00242 if (l) 00243 cam_inhibit_set(c); 00244 else 00245 cam_inhibit_clear(c); 00246 } 00247 00248 /********************************************************************/ 00249 /** 00250 Test Crate I. 00251 00252 Test Crate Inhibit, Execute cam_inhibit_test() 00253 00254 @param ext external address 00255 @param l action l=0 -> Clear I, l=1 -> Set I 00256 @return void 00257 */ 00258 INLINE void ctci(const int ext, int *l) 00259 { 00260 int b, c, n, a; 00261 00262 came_ext(ext, &b, &c, &n, &a); 00263 *l = cam_inhibit_test(c); 00264 } 00265 00266 /********************************************************************/ 00267 /** 00268 Control Crate D. 00269 00270 Enable or Disable Crate Demand. 00271 00272 @param ext external address 00273 @param l action l=0 -> Clear D, l=1 -> Set D 00274 @return void 00275 */ 00276 INLINE void cccd(const int ext, int l) 00277 { 00278 int b, c, n, a; 00279 00280 came_ext(ext, &b, &c, &n, &a); 00281 00282 if (l) 00283 cam_interrupt_enable(c); 00284 else 00285 cam_interrupt_disable(c); 00286 } 00287 00288 /********************************************************************/ 00289 /** 00290 Control Test Crate D. 00291 00292 Test Crate Demand. 00293 00294 @param ext external address 00295 @param l D cleared -> l=0, D set -> l=1 00296 @return void 00297 */ 00298 INLINE void ctcd(const int ext, int *l) 00299 { 00300 int b, c, n, a; 00301 00302 came_ext(ext, &b, &c, &n, &a); 00303 *l = cam_interrupt_test(c); 00304 } 00305 00306 /********************************************************************/ 00307 /** 00308 Control Declare LAM. 00309 00310 Declare LAM, Identical to cdreg. 00311 00312 @param lam external LAM address 00313 @param b branch number (0..7) 00314 @param c crate number (0..) 00315 @param n station number (0..30) 00316 @param a sub-address (0..15) 00317 @param inta implementation dependent 00318 @return void 00319 */ 00320 INLINE void cdlam(int *lam, const int b, const int c, const int n, 00321 const int a, const int inta[2]) 00322 { 00323 /* inta[2] ignored */ 00324 cdreg(lam, b, c, n, a); 00325 } 00326 00327 /********************************************************************/ 00328 /** 00329 Control Test Demand Present. 00330 00331 Test the LAM register. 00332 00333 @param ext external LAM register address 00334 @param l l !=0 if any LAM is set. 00335 @return void 00336 */ 00337 INLINE void ctgl(const int ext, int *l) 00338 { 00339 int b, c, n, a; 00340 unsigned long lam; 00341 00342 came_ext(ext, &b, &c, &n, &a); 00343 cam_lam_read(c, &lam); 00344 *l = (lam > 0); 00345 } 00346 00347 /********************************************************************/ 00348 /** 00349 Control Crate LAM. 00350 00351 Enable or Disable LAM. Execute F24 for disable, F26 for enable. 00352 00353 @param lam external address 00354 @param l action l=0 -> disable LAM , l=1 -> enable LAM 00355 @return void 00356 */ 00357 INLINE void cclm(const int lam, int l) 00358 { 00359 int b, c, n, a; 00360 00361 came_ext(lam, &b, &c, &n, &a); 00362 00363 if (l) 00364 camc(c, n, 0, 26); 00365 else 00366 camc(c, n, 0, 24); 00367 } 00368 00369 /********************************************************************/ 00370 /** 00371 Link LAM to service procedure 00372 00373 Link a specific service routine to a LAM. Since this routine 00374 is executed asynchronously, care must be taken on re-entrancy. 00375 00376 @param lam external address 00377 @param isr name of service procedure 00378 @return void 00379 */ 00380 INLINE void cclnk(const int lam, void (*isr) (void)) 00381 { 00382 int b, c, n, a; 00383 00384 came_ext(lam, &b, &c, &n, &a); 00385 00386 cam_interrupt_attach(c, n, isr); 00387 cam_lam_enable(c, n); 00388 cam_lam_clear(c, n); 00389 } 00390 00391 /********************************************************************/ 00392 /** 00393 Unlink LAM from service procedure 00394 00395 Performs complementary operation to cclnk. 00396 00397 @param lam external address 00398 @return void 00399 */ 00400 INLINE void cculk(const int lam) 00401 { 00402 int b, c, n, a; 00403 00404 came_ext(lam, &b, &c, &n, &a); 00405 cam_interrupt_detach(c, n); 00406 } 00407 00408 /********************************************************************/ 00409 /** 00410 Relink LAM 00411 00412 Re-enable LAM in the controller 00413 00414 @param lam external address 00415 @return void 00416 */ 00417 INLINE void ccrgl(const int lam) 00418 { 00419 int b, c, n, a; 00420 00421 came_ext(lam, &b, &c, &n, &a); 00422 00423 cam_lam_enable(c, n); 00424 cam_lam_clear(c, n); 00425 cam_interrupt_enable(c); 00426 } 00427 00428 /********************************************************************/ 00429 /** 00430 Control Clear LAM. 00431 00432 Clear the LAM of the station pointer by the lam address. 00433 00434 @param lam external address 00435 @return void 00436 */ 00437 INLINE void cclc(const int lam) 00438 { 00439 int b, c, n, a; 00440 00441 came_ext(lam, &b, &c, &n, &a); 00442 camc(c, n, 0, 10); 00443 } 00444 00445 /********************************************************************/ 00446 /** 00447 Test LAM. 00448 00449 Test the LAM of the station pointed by lam. Performs an F8 00450 00451 @param lam external address 00452 @param l No LAM-> l=0, LAM present-> l=1 00453 @return void 00454 */ 00455 INLINE void ctlm(const int lam, int *l) 00456 { 00457 int b, c, n, a; 00458 00459 came_ext(lam, &b, &c, &n, &a); 00460 camc_q(c, n, a, 8, l); 00461 } 00462 00463 /********************************************************************/ 00464 /** 00465 Control Full (24bit) word General Action. 00466 00467 @param f function code 00468 @param exta[] external address array 00469 @param intc[] data array 00470 @param qa[] Q response array 00471 @param cb[] control block array<br> 00472 cb[0] : number of function to perform<br> 00473 cb[1] : returned number of function performed 00474 @return void 00475 */ 00476 INLINE void cfga(int f[], int exta[], int intc[], int qa[], int cb[]) 00477 { 00478 int i; 00479 00480 for (i = 0; i < cb[0]; i++) 00481 cfsa(f[i], exta[i], (unsigned long *) (&(intc[i])), &(qa[i])); 00482 00483 cb[1] = cb[0]; 00484 } 00485 00486 /********************************************************************/ 00487 /** 00488 Control (16bit) word General Action. 00489 00490 @param f function code 00491 @param exta[] external address array 00492 @param intc[] data array 00493 @param qa[] Q response array 00494 @param cb[] control block array <br> 00495 cb[0] : number of function to perform<br> 00496 cb[1] : returned number of function performed 00497 @return void 00498 */ 00499 INLINE void csga(int f[], int exta[], int intc[], int qa[], int cb[]) 00500 { 00501 int i; 00502 00503 for (i = 0; i < cb[0]; i++) 00504 cssa(f[i], exta[i], (unsigned short *) (&(intc[i])), &(qa[i])); 00505 00506 cb[1] = cb[0]; 00507 } 00508 00509 /********************************************************************/ 00510 /** 00511 Control Full (24bit) Address Q scan. 00512 00513 Scan all sub-address while Q=1 from a0..a15 max from address extb[0] and store 00514 corresponding data in intc[]. If Q=0 while A<15 or A=15 then cross station boundary is applied 00515 (n-> n+1) and sub-address is reset (a=0). Perform action until either cb[0] action are performed 00516 or current external address exceeds extb[1]. 00517 00518 <b>implementation of cb[2] for LAM recognition is not implemented.</b> 00519 00520 @param f function code 00521 @param extb[] external address array<br> 00522 extb[0] : first valid external address <br> 00523 extb[1] : last valid external address 00524 @param intc[] data array 00525 @param cb[] control block array <br> 00526 cb[0] : number of function to perform <br> 00527 cb[1] : returned number of function performed 00528 @return void 00529 */ 00530 INLINE void cfmad(int f, int extb[], int intc[], int cb[]) 00531 { 00532 int j, count; 00533 int x, q, b, c, n, a; 00534 unsigned long exts, extc, exte; 00535 00536 exts = extb[0]; 00537 exte = extb[1]; 00538 count = cb[0]; 00539 j = 0; 00540 came_ext(exts, &b, &c, &n, &a); 00541 do { 00542 cam24i_q(c, n, a, f, (unsigned long *) &intc[j], &x, &q); 00543 if (q == 0) { 00544 a = 0; /* set subaddress to zero */ 00545 n++; /* select next slot */ 00546 j++; 00547 } else { 00548 a++; /* increment address */ 00549 ++cb[1]; /* increment tally count */ 00550 ++intc; /* next data array */ 00551 --count; 00552 } 00553 came_cn((int *) &extc, b, c, n, a); 00554 00555 if (extc > exte) 00556 count = 0; /* force exit */ 00557 00558 } while (count); 00559 } 00560 00561 /********************************************************************/ 00562 /** 00563 Control (16bit) Address Q scan. 00564 00565 Scan all sub-address while Q=1 from a0..a15 max from address extb[0] and store 00566 corresponding data in intc[]. If Q=0 while A<15 or A=15 then cross station boundary is applied 00567 (n-> n+1) and sub-address is reset (a=0). Perform action until either cb[0] action are performed 00568 or current external address exceeds extb[1]. 00569 00570 <b>implementation of cb[2] for LAM recognition is not implemented.</b> 00571 00572 @param f function code 00573 @param extb[] external address array<br> 00574 extb[0] : first valid external address <br> 00575 extb[1] : last valid external address 00576 @param intc[] data array 00577 @param cb[] control block array <br> 00578 cb[0] : number of function to perform <br> 00579 cb[1] : returned number of function performed 00580 @return void 00581 */ 00582 INLINE void csmad(int f, int extb[], int intc[], int cb[]) 00583 { 00584 int j, count; 00585 int x, q, b, c, n, a; 00586 unsigned long exts, extc, exte; 00587 00588 exts = extb[0]; 00589 exte = extb[1]; 00590 count = cb[0]; 00591 j = 0; 00592 came_ext(exts, &b, &c, &n, &a); 00593 do { 00594 cam16i_q(c, n, a, f, (unsigned short *) &intc[j], &x, &q); 00595 if (q == 0) { 00596 a = 0; /* set subaddress to zero */ 00597 n++; /* select next slot */ 00598 j++; 00599 } else { 00600 a++; /* increment address */ 00601 ++cb[1]; /* increment tally count */ 00602 ++intc; /* next data array */ 00603 --count; 00604 } 00605 came_cn((int *) &extc, b, c, n, a); 00606 00607 if (extc > exte) 00608 count = 0; /* force exit */ 00609 00610 } while (count); 00611 } 00612 00613 /********************************************************************/ 00614 /** 00615 Control Full (24bit) Block Repeat with Q-stop. 00616 00617 Execute function f on address ext with data intc[] while Q. 00618 00619 @param f function code 00620 @param ext external address array 00621 @param intc[] data array 00622 @param cb[] control block array <br> 00623 cb[0] : number of function to perform <br> 00624 cb[1] : returned number of function performed 00625 @return void 00626 */ 00627 INLINE void cfubc(const int f, int ext, int intc[], int cb[]) 00628 { 00629 int count, q; 00630 00631 count = cb[0]; 00632 do { 00633 cfsa(f, ext, (unsigned long *) intc, &q); 00634 if (q == 0) 00635 count = 0; /* stop on no q */ 00636 else { 00637 ++cb[1]; /* increment tally count */ 00638 ++intc; /* next data array */ 00639 --count; 00640 } 00641 } while (count); 00642 } 00643 00644 /********************************************************************/ 00645 /** 00646 Control (16bit) Block Repeat with Q-stop. 00647 00648 Execute function f on address ext with data intc[] while Q. 00649 00650 @param f function code 00651 @param ext external address array 00652 @param intc[] data array 00653 @param cb[] control block array <br> 00654 cb[0] : number of function to perform <br> 00655 cb[1] : returned number of function performed 00656 @return void 00657 */ 00658 INLINE void csubc(const int f, int ext, int intc[], int cb[]) 00659 { 00660 int count, q; 00661 00662 count = cb[0]; 00663 do { 00664 cssa(f, ext, (unsigned short *) intc, &q); 00665 if (q == 0) 00666 count = 0; /* stop on no q */ 00667 else { 00668 ++cb[1]; /* increment tally count */ 00669 ++intc; /* next data array */ 00670 --count; 00671 } 00672 } while (count); 00673 } 00674 00675 /********************************************************************/ 00676 /** 00677 Repeat Mode Block Transfer (24bit). 00678 00679 Execute function f on address ext with data intc[] if Q. 00680 If noQ keep current intc[] data. Repeat cb[0] times. 00681 00682 @param f function code 00683 @param ext external address array 00684 @param intc[] data array 00685 @param cb[] control block array <br> 00686 cb[0] : number of function to perform <br> 00687 cb[1] : returned number of function performed 00688 @return void 00689 */ 00690 INLINE void cfubr(const int f, int ext, int intc[], int cb[]) 00691 { 00692 int q, count; 00693 00694 count = cb[0]; 00695 do { 00696 do { 00697 cfsa(f, ext, (unsigned long *) intc, &q); 00698 } while (q == 0); 00699 00700 ++cb[1]; /* increment tally count */ 00701 ++intc; /* next data array */ 00702 --count; 00703 } while (count); 00704 } 00705 00706 /********************************************************************/ 00707 /** 00708 Repeat Mode Block Transfer (16bit). 00709 00710 Execute function f on address ext with data intc[] if Q. 00711 If noQ keep current intc[] data. Repeat cb[0] times. 00712 00713 @param f function code 00714 @param ext external address array 00715 @param intc[] data array 00716 @param cb[] control block array <br> 00717 cb[0] : number of function to perform <br> 00718 cb[1] : returned number of function performed 00719 @return void 00720 */ 00721 INLINE void csubr(const int f, int ext, int intc[], int cb[]) 00722 { 00723 int q, count; 00724 00725 count = cb[0]; 00726 do { 00727 do { 00728 cssa(f, ext, (unsigned short *) intc, &q); 00729 } while (q == 0); 00730 00731 ++cb[1]; /* increment tally count */ 00732 ++intc; /* next data array */ 00733 --count; 00734 } while (count); 00735 }