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

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 - Konstantin Olchanski - Renee Poutissou - Andreas Suter - Piotr Adam Zolnierczuk