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();
}
}
}
}