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 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 

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