// =====================================================================
/*!
//
//  \file TCamacModule.hh
//  \brief This file contains the TCamacModule class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TCamacModule.hh,v 1.7 2004/03/07 10:30:31 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TCamacModule.hh,v $
//  Revision 1.7  2004/03/07 10:30:31  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.6  2004/01/19 21:09:41  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.5  2003/11/04 07:40:13  goiwai
//  CAMACドライバへインターフェース部分である CamacDriverInterface の名前
//  を TCamacDriverInterface に変更しました.
//  またこの型をTCamacModuleクラス内部に閉じ込めました.
//  その他,文法的に無意味な部分を修整しました.手元にハードがないので,動作
//  確認していませんが,もし動かなくなるようならこの部分が原因です.
//
//  Revision 1.4  2003/11/03 08:35:13  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.3  2003/10/06 17:02:40  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:19:10  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TCAMACMODULE_HH
#define CLDAQ__TCAMACMODULE_HH

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

class TCamacCrateController;

/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TCamacModule
// \brief This is the TCamacModule class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TCamacModule class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup ModulesCategory
*/
class TCamacModule
  : public TModule
{

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

  public:
    //! ドライバへのインターフェース
    /*!
    // 今のところこれは坂本さんのCAMACドライバのみを想定しています.
    // ドライバへのアクセスはカプセル化されているので,
    // この部分の内部仕様を知る必要はありません.
    */
    typedef struct TCamacDriverInterface {
      TUint _naf;
      Tshort _q;
      Tshort _x;
      union {
        TUshort _d16;
        TUint _d24;
      } _data;
    };

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

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TCamacModule,0)
#endif

};

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

inline TCamacModule::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
