// =====================================================================
//  $Id: TVmeRpv130Module.cc,v 1.4 2004/03/07 10:30:31 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TVmeRpv130Module.cc,v $
//  Revision 1.4  2004/03/07 10:30:31  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.3  2003/10/06 17:02:40  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:19:12  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TVmeRpv130Module.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"

TVmeRpv130Module::TVmeRpv130Module( Toff_t offset, Tint mapsize, Tint nch )
  : TVmeModule( nch, offset, mapsize, tA16D16 ),
    theReadoutMode( tReadoutWithThrough ), theLevelStatus( 0x0000 )
{
  LevelDown();
}

TVmeRpv130Module::TVmeRpv130Module( const TVmeRpv130Module& right )
  : TVmeModule( right ), 
    theReadoutMode( right.theReadoutMode ),
    theLevelStatus( right.theLevelStatus )
{;}

TVmeRpv130Module::~TVmeRpv130Module()
{;}

const TVmeRpv130Module& TVmeRpv130Module::operator=( const TVmeRpv130Module& right )
{
  *( (TVmeModule*)this ) = *( (TVmeModule*)(&right) );
  theReadoutMode = right.theReadoutMode;
  theLevelStatus = right.theLevelStatus;
  return *this;
}

Tbool TVmeRpv130Module::operator==( const TVmeRpv130Module& right ) const
{
  Tbool ret = Ttrue;
  ret &= ( *( (TVmeModule*)this ) == *( (TVmeModule*)(&right) ) );
  ret &= ( theReadoutMode == right.theReadoutMode );
  ret &= ( theLevelStatus == right.theLevelStatus );
  return ret;
}

Tbool TVmeRpv130Module::operator!=( const TVmeRpv130Module& right ) const
{
  Tbool ret = Tfalse;
  ret |= ( *( (TVmeModule*)this ) != *( (TVmeModule*)(&right) ) );
  ret |= ( theReadoutMode != right.theReadoutMode );
  ret |= ( theLevelStatus != right.theLevelStatus );
  return ret;
}

Tint TVmeRpv130Module::Clear()
{
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 0, 1 );
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 1, 1 );

  setBit( (TUshort*)( theBaseAddress + CSR2 ), 0, 1 );
  setBit( (TUshort*)( theBaseAddress + CSR2 ), 1, 1 );
  return theStatus = tStatusSuccess;
}

Tint TVmeRpv130Module::Update()
{
  return Clear();
}

Tint TVmeRpv130Module::Initialize()
{
  Clear();
  Disable();
  return theStatus = tStatusSuccess;
}

Tvoid TVmeRpv130Module::FillData( TDataElement& element, Tint channel )
{
  if ( channel < 0 || channel >= theNumberOfChannels ) {
    Tcerr << "TVmeRpv130Module::FillData: invalid ID " << channel << Tendl;
    theStatus = -EFAULT;
    element.FillData( &theStatus, tTypeInt, 1 );
  } else {
    TUshort data = Read();
    element.FillData( &data, tTypeUnsignedShort, 1 );
  }
  return;
}

Tvoid TVmeRpv130Module::Pulse()
{
  *( (TUshort*)( theBaseAddress + PULSE ) ) = 0x000ff;
  return;
}

Tvoid TVmeRpv130Module::Pulse( Tint pattern )
{
  *( (TUshort*)( theBaseAddress + PULSE ) ) = (TUshort)pattern;
  return;
}

Tvoid TVmeRpv130Module::Level()
{
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = 0x000ff;
  theLevelStatus = 0x00ff;
  return;
}

Tvoid TVmeRpv130Module::Level( Tint pattern )
{
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = (TUshort)pattern;
  theLevelStatus = pattern & 0x00ff;
  return;
}

Tvoid TVmeRpv130Module::LevelDown()
{
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = 0x00000;
  theLevelStatus = 0x0000;
  return;
}

Tvoid TVmeRpv130Module::LevelDown( Tint channel )
{
  setBit( (TUshort*)(&theLevelStatus), channel, 0 );
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = theLevelStatus;

  return;
}

Tvoid TVmeRpv130Module::LevelUp()
{
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = 0x000ff;
  theLevelStatus = 0x00ff;
  return;
}

Tvoid TVmeRpv130Module::LevelUp( int channel )
{
  setBit( (TUshort*)(&theLevelStatus), channel, 1 );
  *( (TUshort*)( theBaseAddress + LEVEL ) ) = theLevelStatus;
  return;
}

Tvoid TVmeRpv130Module::Enable()
{
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 4, 1 );
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 6, 1 );

  setBit( (TUshort*)( theBaseAddress + CSR2 ), 4, 1 );
  setBit( (TUshort*)( theBaseAddress + CSR2 ), 6, 1 );
  return;
}

Tvoid TVmeRpv130Module::Disable()
{
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 4, 0 );
  setBit( (TUshort*)( theBaseAddress + CSR1 ), 6, 0 );

  setBit( (TUshort*)( theBaseAddress + CSR2 ), 4, 0 );
  setBit( (TUshort*)( theBaseAddress + CSR2 ), 6, 0 );
  return;
}

TUshort TVmeRpv130Module::Read()
{
  TUshort data;
  switch ( theReadoutMode ) {
    case tReadoutWithLatch1:
      data = *( (TUshort*)( theBaseAddress + LATCH1 ) );
    case tReadoutWithLatch2:
      data = *( (TUshort*)( theBaseAddress + LATCH2 ) );
    case tReadoutWithRSFF:
      data = *( (TUshort*)( theBaseAddress + RSFF ) );
    case tReadoutWithThrough:
      data = *( (TUshort*)( theBaseAddress + THROUGH ) );
    default:
      data = *( (TUshort*)( theBaseAddress + RSFF ) );
  }
  data &= 0x00ff;
  return data;
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TVmeRpv130Module)
#endif
