// =====================================================================
//  $Id: TCamacModule.hh,v 1.1.1.1 2003/06/27 02:56:41 goiwai Exp $
//  $Name: CLDAQ-1-06-02 $
// =====================================================================
#ifndef __TCAMACMODULE_HH
#define __TCAMACMODULE_HH

#include "Tglobals.h"
#include "TModule.hh"

// interface to use only yasu driver
typedef struct CamacDriverInterface
{
  TUint _naf;
  Tshort _q;
  Tshort _x;
  union DataPartOfCamacData
  {
    TUshort _d16;
    TUint _d24;
  } _data;
};

enum Tdata_t { 
  t16bitModule = 16, 
  t24bitModule = 24, 
  tNumberOfDataType
};

class TCamacCrateController;

class TCamacModule
  : public TModule
{

  protected:
    enum {
      tCamacRead = 0,
      tCamacWrite = 16,
      tCamacClear = 9,
      tCamacTestInterrupt = 8,
      tCamacClearInterrupt = 10,
      tCamacEnableInterrupt = 26,
      tCamacDisableInterrupt = 24
    };

  protected:
    TCamacCrateController* theCrateController;
    Tdata_t theDataLength;
    Tint theSlotNumber;
    Tint theQ;
    Tint theX;
    TUint theCamacData;

  public:
    TCamacModule( TCamacCrateController* cc7x00, Tint slot, Tint nch, Tdata_t datalen );
    TCamacModule( const TCamacModule& right );

  protected:
    virtual ~TCamacModule();

  public:
    virtual const TCamacModule& operator=( const TCamacModule& right );
    virtual Tbool operator==( const TCamacModule& right ) const;
    virtual Tbool operator!=( const TCamacModule& right ) const;

  public:
    virtual Tint WaitInterrupt( Tint msec );
    virtual Tint ReadInterrupt();
    virtual Tint Clear();
    virtual Tint Update();
    virtual Tint Initialize();

  public:
    // generic CAMAC functions
    virtual Tint TestInterrupt();
    virtual Tint ClearInterrupt();
    virtual Tint EnableInterrupt();
    virtual Tint DisableInterrupt();
    virtual Tint Read();
    virtual Tint Read( Tint subaddress );
    virtual Tint Write( Tint data );

  public:
    TCamacCrateController* GetCrateController() const;
    Tdata_t GetDataLength() const;
    Tint GetSlotNumber() const;
    Tint GetQ() const;
    Tint GetX() const;
    TUint GetCamacData() const;
    Tvoid SetDataLength( Tdata_t datalen );
    Tvoid SetSlotNumber( Tint slot );
    Tvoid SetQ( Tint q );
    Tvoid SetX( Tint x );
    Tvoid SetCamacData( TUint data );

  protected:
    Tint execute( Tint subaddress, Tint function );

  private:
    TUint generateNAF( Tint n, Tint a, Tint f );
    Tint execute16bit( TUint naf );
    Tint execute24bit( TUint naf );

};

inline TCamacCrateController* TCamacModule::GetCrateController() const
{
  return( theCrateController );
}

inline Tdata_t TCamacModule::GetDataLength() const
{
  return( theDataLength );
}

inline Tint TCamacModule::GetSlotNumber() const
{
  return( theSlotNumber );
}

inline Tint TCamacModule::GetQ() const
{
  return( theQ );
}

inline Tint TCamacModule::GetX() const
{
  return( theX );
}

inline TUint TCamacModule::GetCamacData() const
{
  return( theCamacData );
}

inline Tvoid TCamacModule::SetDataLength( Tdata_t datalen )
{
  theDataLength = datalen;
  return;
}

inline Tvoid TCamacModule::SetSlotNumber( Tint slot )
{
  theSlotNumber = slot;
  return;
}

inline Tvoid TCamacModule::SetQ( Tint q )
{
  theQ = q;
  return;
}

inline Tvoid TCamacModule::SetX( Tint x )
{
  theX = x;
  return;
}

inline Tvoid TCamacModule::SetCamacData( TUint data )
{
  theCamacData = data;
  return;
}

#endif
