// Author: Thomas Hadig (Group EB SLAC Stanford CA USA)
// Last update: $Date: 2003/08/27 19:51:12 $
// Copyright: Thomas Hadig, hadig@slac.stanford.edu

#ifndef __CRTCC32CAMACCRATE_CXX
#define __CRTCC32CAMACCRATE_CXX

//#define __CC32_DEBUG

////////////////////////////////////////////////////////////////////////////////
//
// Cosmic Ray Telescope Data Aquisition Software
//
// Generic driver for a CAMAC crate.
// Connection from a PC to the crate is done via the Wiener CC32 crate controller
// and the corresponding PCI PC board
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <sstream>

#include <gendriver/cc32camaccrate.hh>

extern "C"
 { 
# include <cc32/libcc32.h>
 }

namespace CRT
 { 
  //{{{}}}
  //{{{  constructor
   CrtCc32CamacCrate::CrtCc32CamacCrate() : CrtCamacCrate()
   {
    // default constructor
    fOk=-1;
   }
  //}}}
  //{{{  constructor CrtCc32CamacCrate(const Char_t *inName, Int_t inCrateNumber)
   CrtCc32CamacCrate::CrtCc32CamacCrate(const Char_t *inName, Int_t inCrateNumber)
     : CrtCamacCrate(inName)
   {
    // constructor
    fOk=0;
    fCrateNumber=inCrateNumber;
   }
  //}}}
  //{{{  destructor
   CrtCc32CamacCrate::~CrtCc32CamacCrate()
   {
    // destructor
    if (fOk==1) 
      cc32_close(fFile);
    fOk=-1;
   }
  //}}}
  //{{{  GetIdentity
   Int_t CrtCc32CamacCrate::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 CrtCc32CamacCrate::Initialize()
   {
    if (fOk!=0) return;
    std::stringstream s;
    s<<fCrateNumber+1;
    std::string buffer = "/dev/cc32_"+s.str();
    Int_t error;
    if ((error = cc32_open(buffer.c_str(),&fFile))!=0)
     {
      fOk=-1;
      std::cout<<"ERROR: could not open connection to cc32 controller : "<<error<<std::endl;
      exit(1);
     }
    fOk=1;
    cc32_write_word(fFile, 31, 0, 0, 0); // reset CC32
    cc32_write_word(fFile, 30, 2, 0, 0); // cycle tune to CAMAC standard
    cc32_write_word(fFile, 30, 1, 0, 0); //    for high, mid and low
    cc32_write_word(fFile, 30, 0, 0, 0); //    stations
    cc32_write_word(fFile, 27, 0, 0, 0); // inhibit on
    cc32_write_word(fFile, 27, 3, 0, 0); // read double word off
    cc32_write_word(fFile, 0, 1, 0, 0); // CAMAC initialize
    cc32_interrupt_disable(fFile);
    //cc32_autoread_off(fFile);
    ClearInhibit();
   }
  //}}}

  //{{{  Send
   Int_t CrtCc32CamacCrate::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;
    cc32_write_long(fFile, inIdent/256, inIdent%256, inFunction, inValue);
#  ifdef __CC32_DEBUG
    std::cout<<"CC32W : "<<inIdent/256<<" "<<inIdent%256<<" "<<inFunction<<" "<<
        inValue<<std::endl;
#  endif
    return 1;
   }
  //}}}
  //{{{  Read
   Int_t CrtCc32CamacCrate::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;
    Int_t q,x;
    *outValue = cc32_read_long(fFile, inIdent/256, inIdent%256, inFunction, &q, &x);
#  ifdef __CC32_DEBUG
    std::cout<<"CC32R : "<<inIdent/256<<" "<<inIdent%256<<" "<<inFunction<<" "<<q
        <<" "<<x<<" "<<hex<<*outValue<<dec<<std::endl;
#  endif
    return q;
   }
  //}}}
  //{{{  Test
   Int_t CrtCc32CamacCrate::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;
    Int_t q,x;
    cc32_read_long(fFile, inIdent/256, inIdent%256, inFunction, &q, &x);
#  ifdef __CC32_DEBUG
    std::cout<<"CC32T : "<<inIdent/256<<" "<<inIdent%256<<" "<<inFunction<<" "<<q
        <<" "<<x<<std::endl;
#  endif
    return q;
   }
  //}}}
  //{{{  BlockSend
   Int_t CrtCc32CamacCrate::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 CrtCc32CamacCrate::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;
   }
  //}}}
  //{{{  SetInhibit
   void CrtCc32CamacCrate::SetInhibit() const
   {
    // sets crate inhibit 
    cc32_write_long(fFile, 27, 0, 0, 0);
   }
  //}}}
  //{{{  ClearInhibit
   void CrtCc32CamacCrate::ClearInhibit() const
   { 
    // clears crate inhibit 
    cc32_write_long(fFile, 27, 1, 0, 0);
   }
  //}}}
  //{{{  PrintStatus
   void CrtCc32CamacCrate::PrintStatus() const
   {
    // read the CC32 status and prints the result 
    Int_t status;
    Read(GetIdentity(0,0),0,&status);
    std::cout<<"CC32 status :"<<std::hex<<status<<std::dec<<'n';

    if (status&0xf000==0x8000) std::cout<<"  Module type : CC32n";
    else if (status&0xf000==0x1000) std::cout<<"  Module type : VMEMMn";
    else std::cout<<"  Module type : "<<(status&0xf000)/0x1000<<"n";

    std::cout<<"  FPGA version : "<<(status&0x0f00)/0x0100<<"n";
    std::cout<<"  Module number : "<<(status&0x00f0)/0x0010<<"n";
    std::cout<<"  Last Q response : "<<(status&0x0008)/0x0008<<"n";
    std::cout<<"  Last X response : "<<(status&0x0004)/0x0004<<"n";
    std::cout<<"  Inhibit status  : "<<(status&0x0002)/0x0002<<"n";
    std::cout<<"  LAM status      : "<<(status&0x0001)/0x0001<<std::endl;
   }
  //}}}
 }
 
ClassImp(CRT::CrtCc32CamacCrate) //generic driver for a CAMAC crate with a Wiener CC32 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.