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