package inp.camac; /** * @author Maxim V. Kollegov * @version 1.00, 02/04/2001 */ import java.io.*; import java.util.*; /** * CamacDriver is a basic abstract class to extend by real * implementations of CAMAC hardware. Implemntations must have * default constructor without parameters. This implementation of * CamacDriver initialize instantiated by name class calling it's init() * method. * Application software must use the following code to load driver by class * name * *
* CamacDriver driver = CamacDriver.loadDriver("inp.camac.cc232.DriverCC232"); * Crate crate = driver.getCrate(0); * Module module = new Module(); * crate.addModule(module,2); * crate.Z(); * crate.C(); * crate.I(true); * module.addLAMlistener(new myLAMlistener()); * **/ public abstract class CamacDriver { private static Hashtable drivers = new Hashtable(); final int MAXCRATES = 256; Crate[] crates = new Crate[MAXCRATES]; int[] LAMmasks = new int[MAXCRATES]; /** * Get driver by class name * @return existing instance of driver by class name or * load and initialize new driver if no instance exists. * Default implementation call CamacDriver.init() after * creating new instance. * @param className driver class name to load and/or instantiate, */ public static CamacDriver loadDriver(String className) throws Exception { CamacDriver driver = (CamacDriver) drivers.get(className); if(driver==null) { driver = (CamacDriver)(ClassLoader.getSystemClassLoader().loadClass(className).newInstance()); driver.init(); drivers.put(className,driver); } return driver; } /** * Execute NAF in Crate * @param crateN Crate number from 0 to MAXCRATES * @param N Camac module position (1..24) * @param A Camac subaddress * @param F Camac function * @param data Array of data, NAF will be executed as many times as data.length is. * If data is null than NAF will be executed once without data transfer. * In case of write operation, data from this array must be written * in target module. In case of read operation data read from module * must be placed in this array. * @param bits Number of significant bits in data transfer. For some sort of * hardware this parameter might be usefull to reduce data transfer * time. Implementation might return either all 24 bits either only * required number of bits * @param Module module reference, Usefull in particular implementations to check * module.mustHaveX() and module.mustHaveQ() for correct exceptions * handling. */ public abstract void executeNAF(int crateN, int N, int A, int F, int[] data, int bits, Module module ) throws IOException; /** * Execute C cycle in specified crate * @param crateN crate Number */ public abstract void C(int crateN) throws IOException; /** * Execute Z cycle in specified crate * @param crateN crate Number */ public abstract void Z(int crateN) throws IOException; /** * set I (inhibit) bus state * @param crateN crate Number * @param inhibit */ public abstract void I(int crateN, boolean inhibit) throws IOException; /** * Implement here whatever needed to initialize connection with crate * controller. Called by default implementation of CamacDriver.getCrate * on first attempt to get crate. */ public abstract void initCrate(int crateN) throws IOException; /** * Implement here whatever needed to initialize camac driver * called by loadDriver when new driver loaded. */ public abstract void init() throws IOException; /** * Implement here whatever needed to unload camac driver */ public void release() throws IOException {}; /** * set LAM bit mask to filter out LAM events only from given positions. * * @param crateN crate number * @param mask LAM mask. 1 enables LAM, 0 disables LAM. * LSB bit 0 of mask corresponds to position 1 */ public abstract void setLAMMask(int crateN, int mask) throws IOException; /** * Close crate connectection and release all allocated resources for this crate * @param crateN crate number to release. */ public abstract void close(int crateN); /** * @return Crate object. In case object already was created once * it return existing instance, if this is first attempt to get * crate with this number it create new Crate and initialize it * with calling CamacDriver.initCrate(in crateN) */ public Crate getCrate(int crateN) throws IOException{ if( (crateN<0) || (crateN >= crates.length) ) { throw new IOException("Invalid Crate N="+crateN); } if(crates[crateN]==null) { crates[crateN] = new Crate(this, crateN); LAMmasks[crateN] = 0; initCrate(crateN); } return crates[crateN]; } /** * Enable/disable LAM from given position in given Crate */ void enableLAM(int crateN, int N, boolean enable) throws IOException{ if(crateN<0 || crateN >= crates.length ) throw new IllegalArgumentException("Invalid Crate N="+crateN); if(N<1 || N > 24 ) throw new IllegalArgumentException("Invalid N="+N); int mask = 1 << (N-1); if(enable) LAMmasks[crateN] |= mask; else LAMmasks[crateN] &= ~mask; setLAMMask(crateN,LAMmasks[crateN]); } /** * Callback. Must be called by implementation when LAM occures in module * @param crateN crate number * @param N module position must be from 1 to 24. */ public void onLAM( int crateN, int N ) { if(crateN<0 || crateN > crates.length ) return; if(crates[crateN] !=null){ int mask = 1 << (N-1); if( (LAMmasks[crateN] & mask) != 0) { crates[crateN].getModule(N).fireLAM(); } } } }