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

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