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