// Author: Thomas Hadig (Group EB SLAC Stanford CA USA)
// Last update: $Date: 2003/08/22 22:31:11 $
// Copyright: Thomas Hadig, hadig@slac.stanford.edu

#ifndef __CRTGPIB3988CAMACCRATE_CXX
#define __CRTGPIB3988CAMACCRATE_CXX

////////////////////////////////////////////////////////////////////////////////
//
// Cosmic Ray Telescope Data Aquisition Software
//
// Generic driver for a CAMAC crate.
// Connection from a PC to the crate is done via the Kinetics GPIB 3988 
// crate controller
//
////////////////////////////////////////////////////////////////////////////////

#include <gendriver/gpib3988crate.hh>
#include <gendriver/gpib3988board.hh>
                     
namespace CRT
 { 
  //{{{}}}
  //{{{  constructor
   CrtGpib3988CamacCrate::CrtGpib3988CamacCrate() : CrtCamacCrate()
   {
    // default constructor
    fOk=-1;
   }
  //}}}
  //{{{  constructor CrtGpib3988CamacCrate(const Char_t *inName, CrtGpib3988Board *inBoard)
   CrtGpib3988CamacCrate::CrtGpib3988CamacCrate(const Char_t *inName, CrtGpib3988Board *inBoard)
     : CrtCamacCrate(inName), fOk(0), fBoard(inBoard)
   {
    // constructor
   }
  //}}}
  //{{{  destructor
   CrtGpib3988CamacCrate::~CrtGpib3988CamacCrate()
   {
    // destructor
    fOk=-1;
   }
  //}}}

  //{{{  GetIdentity
   Int_t CrtGpib3988CamacCrate::GetIdentity(Int_t inBoardNumber, Int_t inSubAdress) const
   {
    // calculates identity number for a crate/board/subadress number
    if (fOk==-1) return -1;
    if ((inSubAdress<0)||(inSubAdress>16)) return -1;
    if ((inBoardNumber<0)||(inBoardNumber>23)) return -1;
    return inBoardNumber *256 + inSubAdress;
   }
  //}}}
  //{{{  Initialize
   void CrtGpib3988CamacCrate::Initialize()
   {
    if (fOk<0) return;

    Char_t buffer[10];
    // send initialize
    buffer[0]=30;
    buffer[1]=0;
    buffer[2]=17;
    buffer[3]=0;
    buffer[4]=0x04; // 24 bits for all commands, status byte enabled, single transfer
    buffer[5]=0xd0; // initialize
    fBoard->Send(buffer,6);
    fOk=1;
   }
  //}}}
  //{{{  Send
   Int_t CrtGpib3988CamacCrate::Send(Int_t inIdent, Int_t inFunction, Int_t inValue) const
   {
    // executes a function on a specific card in the crate. It passes the
    // inValue to this function
    // return code is the Q response

    if (fOk!=1) return -1;
    Char_t buffer[10];
    buffer[0]=inIdent/256;
    buffer[1]=inIdent%256;
    buffer[2]=inFunction;
    if ((inFunction>=16)&&(inFunction<24))
     { 
      buffer[3]= inValue/256/256;
      buffer[4]=(inValue/256)%256;
      buffer[5]= inValue%256;
      fBoard->Send(buffer,6);
     }
    else
      fBoard->Send(buffer,3);
    return 1;
   }
  //}}}
  //{{{  Read
   Int_t CrtGpib3988CamacCrate::Read(Int_t inIdent, Int_t inFunction, Int_t *outValue) const
   {
    // executes a function on a specific card in the crate. It passes the
    // function return value to outValue.
    // return code is the Q response

    if (fOk!=1) return -1;
    Char_t buffer[10];
    buffer[0]=inIdent/256;
    buffer[1]=inIdent%256;
    buffer[2]=inFunction;
    fBoard->Send(buffer,3);
    if (inFunction>=8)
      return 1;

    fBoard->Read(buffer,4);
    *outValue = (UChar_t)buffer[0]*256*256+(UChar_t)buffer[1]*256+(UChar_t)buffer[2];
    return !(buffer[3] & 0x01);
   }
  //}}}
  //{{{  Test
   Int_t CrtGpib3988CamacCrate::Test(Int_t inIdent, Int_t inFunction) const
   {
    // executes a test function on a specific card in the crate. 
    // return code is the Q response

    if (fOk!=1) return -1;
    Char_t buffer[10];
    buffer[0]=inIdent/256;
    buffer[1]=inIdent%256;
    buffer[2]=inFunction;
    fBoard->Send(buffer,3);
    return 1;
   }
  //}}}
  //{{{  BlockSend
   Int_t CrtGpib3988CamacCrate::BlockSend(Int_t inIdent, Int_t inFunction, Int_t inCount, Int_t *inValue) const
   {
    // same as send, but repeats the same function with increasing sub-addresses.
    // inCount defines the number of executions.
    // The return value will be the number of executions.
    // Please note: The inValue array has to have a length of at least the number
    // of channels

    Int_t count=0;

    do
     {
      Send(inIdent+count, inFunction, inValue[count]);
      count++;
     } while (count<inCount);
    return count;
   }
  //}}}
  //{{{  BlockRead
   Int_t CrtGpib3988CamacCrate::BlockRead(Int_t inIdent, Int_t inFunction, Int_t inCount, Int_t *outValue) const
   {
    // same as read, but repeats the same function with increasing sub-addresses
    // as long as the Q response is 1 or increments the slot if the Q response is
    // 0. inCount defines the number of executions.
    // The return value will be the number of executions.
    // Please note: The outValue array has to have a length of at least the number
    // of channels

    Int_t count=0;
    Int_t q;
    Int_t ident=inIdent;

    do
     {
      q=Read(ident, inFunction, &outValue[count]);
      if (q==1)
        ident++;  // next subadress
      else
        ident=inIdent+256*256; // next slot
      count++;
     } while (count<inCount);
    return count;
   }
  //}}}
  //{{{  GetStatus
   void CrtGpib3988CamacCrate::GetStatus(Char_t *outBuffer) const
   { 
    if (fOk!=1) return;
    outBuffer[0]=30;
    outBuffer[1]=0;
    outBuffer[2]=1;
    fBoard->Send(outBuffer,3);
    fBoard->Read(outBuffer,3);
   }
  //}}}
  //{{{  SetInhibit
   void CrtGpib3988CamacCrate::SetInhibit() const
   {
    // sets crate inhibit
    Char_t buffer[10];
    GetStatus(buffer+3);
    buffer[0]=30;
    buffer[1]=0;
    buffer[2]=17;
    buffer[5] |= 0x20;
    fBoard->Send(buffer,6);
   }
  //}}}
  //{{{  ClearInhibit
   void CrtGpib3988CamacCrate::ClearInhibit() const
   {
    // clears crate inhibit
    Char_t buffer[10];
    GetStatus(buffer+3);
    buffer[0]=30;
    buffer[1]=0;
    buffer[2]=17;
    buffer[5] &= 0xdf;
    fBoard->Send(buffer,6);
   }
  //}}}
 }
 
ClassImp(CRT::CrtGpib3988CamacCrate) //generic driver for a CAMAC crate with a Kinectic GPIB3988 controler

#endif



ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.