esone.c

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

Midas DOC Version 1.9.5 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk