From: <ro...@us...> - 2008-05-17 21:02:40
|
Revision: 1840 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1840&view=rev Author: ron-fox Date: 2008-05-17 14:02:48 -0700 (Sat, 17 May 2008) Log Message: ----------- Good compilation on the device support for the MADC 32 (Mesytec 32 channel adc). In the process added some support for additional convenience parameter decoding functions to CConfigurableObject. Modified Paths: -------------- trunk/llnlReadout/devices/C785.cpp trunk/llnlReadout/devices/CConfigurableObject.cpp trunk/llnlReadout/devices/CConfigurableObject.h trunk/llnlReadout/devices/Makefile.am Added Paths: ----------- trunk/llnlReadout/devices/CMADC32.cpp trunk/llnlReadout/devices/CMADC32.h Modified: trunk/llnlReadout/devices/C785.cpp =================================================================== --- trunk/llnlReadout/devices/C785.cpp 2008-05-16 17:17:18 UTC (rev 1839) +++ trunk/llnlReadout/devices/C785.cpp 2008-05-17 21:02:48 UTC (rev 1840) @@ -355,7 +355,7 @@ (type != 862)) { // 775 for testing!!. char message[100]; string name = m_pConfiguration->getName(); - sprintf(message, "Module %s at base 0x%x is not a supported module but a %d", + sprintf(message, "Module %s at base 0x%x is not a CAEN 32 channel digitizer but a %d", name.c_str(), base, type); throw string(message); } Modified: trunk/llnlReadout/devices/CConfigurableObject.cpp =================================================================== --- trunk/llnlReadout/devices/CConfigurableObject.cpp 2008-05-16 17:17:18 UTC (rev 1839) +++ trunk/llnlReadout/devices/CConfigurableObject.cpp 2008-05-17 21:02:48 UTC (rev 1840) @@ -21,6 +21,7 @@ #include <errno.h> #include <tcl.h> #include <math.h> +#include <tcl.h> using namespace std; @@ -248,6 +249,30 @@ return atof(name.c_str()); } +/*! + Return a parameter that is a list of integers. + \param name - name of the parameter. + \return vector<int> + \retval Vector containing the integers in the list. + +*/ +vector<int> +CConfigurableObject::getIntegerList(string name) +{ + string value = cget(name); + int argc; + const char** argv; + vector<int> result; + + Tcl_SplitList(NULL, value.c_str(), &argc, &argv); + + for (int i =0; i < argc; i++) { + result.push_back(static_cast<int>(strtol(argv[i], NULL, 0))); + } + Tcl_Free((char*)argv); + return result; + +} /////////////////////////////////////////////////////////////////////////// /////////////////////// Establishing he configuration ///////////////////// /////////////////////////////////////////////////////////////////////////// Modified: trunk/llnlReadout/devices/CConfigurableObject.h =================================================================== --- trunk/llnlReadout/devices/CConfigurableObject.h 2008-05-16 17:17:18 UTC (rev 1839) +++ trunk/llnlReadout/devices/CConfigurableObject.h 2008-05-17 21:02:48 UTC (rev 1840) @@ -159,9 +159,10 @@ // Convenience functions that get common conversions: - int getIntegerParameter (std::string name); - bool getBoolParameter (std::string name); - double getFloatParameter (std::string name); + int getIntegerParameter (std::string name); + bool getBoolParameter (std::string name); + double getFloatParameter (std::string name); + std::vector<int> getIntegerList (std::string name); // Operations: Added: trunk/llnlReadout/devices/CMADC32.cpp =================================================================== --- trunk/llnlReadout/devices/CMADC32.cpp (rev 0) +++ trunk/llnlReadout/devices/CMADC32.cpp 2008-05-17 21:02:48 UTC (rev 1840) @@ -0,0 +1,440 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CMADC32.h" +#include "CReadoutModule.h" +#include <CVMUSB.h> +#include <CVMUSBReadoutList.h> + +#include <tcl.h> + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> + +#include <string> +#include <vector> +#include <set> + +using namespace std; + +////////////////////////////////////////////////////////////////////// +// Local constants. + +#define Const(name) static const int name = + +// The address modifiers that will be used to access the module: + +Const(initamod) CVMUSBReadoutList::a32UserData; // setup using user data access. +Const(readamod) CVMUSBReadoutList::a32UserBlock; // Read in block mode. + +// Module address map; for the most part I'm only defining the registers +// we'll actually use. + +Const(eventBuffer) 0; + +Const(Thresholds) 0x4000; + +Const(AddressSource) 0x6000; +Const(Address) 0x6002; +Const(ModuleId) 0x6004; +Const(Reset) 0x6008; // write anything here to reset the module. + +Const(Ipl) 0x6010; +Const(Vector) 0x6012; + +Const(DataFormat) 0x6032; +Const(ReadoutReset) 0x6034; +Const(MarkType) 0x6038; +Const(StartAcq) 0x603A; +Const(InitFifo) 0x603c; + +Const(BankOperation) 0x6040; +Const(Resolution) 0x6042; +Const(OutputFormat) 0x6044; + +Const(HoldDelay0) 0x6050; +Const(HoldDelay1) 0x6052; +Const(HoldWidth0) 0x6054; +Const(HoldWidth1) 0x6056; +Const(EnableGDG) 0x6058; + +Const(InputRange) 0x6060; +Const(ECLTermination) 0x6062; +Const(ECLGate1OrTiming) 0x6064; +Const(ECLFCOrTimeReset) 0x6066; +Const(NIMGate1OrTiming) 0x606a; +Const(NIMFCOrTimeReset) 0x606c; +Const(NIMBusyFunction) 0x606e; + +Const(TimingSource) 0x6096; + +Const(TestPulser) 0x6070; // In order to ensure it's off ! + +Const(EventCounterReset) 0x6090; + +///////////////////////////////////////////////////////////////////////////////// +// Data that drives parameter validity checks. + +static CConfigurableObject::limit Zero(0); // Useful for many of the integer limits. +static CConfigurableObject::limit Byte(0xff); +// Module id: + +static CConfigurableObject::limit IdMax(255); +static CConfigurableObject::Limits IdLimits(Zero, IdMax); + +// Interrupt priority level: + +static CConfigurableObject::limit IPLMax(7); +static CConfigurableObject::Limits IPLLimit(Zero, IPLMax); + +// Interrupt vector: + +static CConfigurableObject::limit VectorMax(255); +static CConfigurableObject::Limits VectorLimit(Zero, IPLMax); + +// List parameters have constraints on their sizes (HoldListSize), +// Value types, and parameters to the type checker (e.g. range limitations). +// These are encapsulated in isListParameter struct. +// +// Thresholds, are 32 element lists with values [0,0xfff]. + +static CConfigurableObject::limit ThresholdMax(0xfff); +static CConfigurableObject::Limits ThresholdLimits(Zero, ThresholdMax); +static CConfigurableObject::ListSizeConstraint ThresholdListSize = {32, 32}; +static CConfigurableObject::TypeCheckInfo ThresholdValuesOk(CConfigurableObject::isInteger, + &ThresholdLimits); +static CConfigurableObject::isListParameter ThresholdValidity = + {ThresholdListSize, + ThresholdValuesOk}; + + +// hold delays are a two element integer array, with no limits. + + +static CConfigurableObject::ListSizeConstraint HoldListSize = {2, 2}; +static CConfigurableObject::Limits HoldLimits(Zero, Byte); +static CConfigurableObject::TypeCheckInfo HoldValueOk(CConfigurableObject::isInteger, + &HoldLimits); +static CConfigurableObject::isListParameter HoldValidity = + {HoldListSize, + HoldValueOk}; + + +// Note for all enums, the first item in the list is the default. + + +// Legal gatemode values for the enumerator: + +const char* GateModeValues[2] = {"common", "separate"}; +const int GateModeNumValues = sizeof(GateModeValues)/sizeof(char*); + +// Legal values for the adc input range: + +const char* InputRangeValues[3] = {"4v", "8v", "10v"}; +const int InputRangeNumValues = sizeof(InputRangeValues)/sizeof(char*); + +// Legal values for the timing source. + +const char* TimingSourceValues[2] = {"vme", "external"}; +const int TimingSourceNumValues = sizeof(TimingSourceValues)/sizeof(char*); + + +//////////////////////////////////////////////////////////////////////////////// +// Constructors and implemented canonical operations: + +/* These are largely trivial in nature: */ + +CMADC32::CMADC32() : + m_pConfiguration(0) +{} + + +/*! Copy construction involves a deep copy */ + +CMADC32::CMADC32(const CMADC32& rhs) : + m_pConfiguration(0) +{ + if (rhs.m_pConfiguration) { + m_pConfiguration = new CReadoutModule(*(rhs.m_pConfiguration)); + } +} + +CMADC32::~CMADC32() {} + +CMADC32& +CMADC32::operator=(const CMADC32& rhs) +{ + return *this; +} +///////////////////////////////////////////////////////////////////////////////// +// Object operations: +// + +/*! + Attach the module to its configuration. + This is called when the object has been created by the configuration software. + we will register our configuration parameters, validators and limits. + A pointer to the configuration object is retained so that The module configuration + can be gotten when we need it. + + \param configuration - The Readout module that will hold our configuration. + +*/ +void +CMADC32::onAttach(CReadoutModule& configuration) +{ + + m_pConfiguration = &configuration; + + // Create the configuration parameters. + + m_pConfiguration->addParameter("-base", CConfigurableObject::isInteger, + NULL, "0"); + m_pConfiguration->addParameter("-id", CConfigurableObject::isInteger, + &IdLimits, "0"); + m_pConfiguration->addParameter("-ipl", CConfigurableObject::isInteger, + &IPLLimit, "0"); + m_pConfiguration->addParameter("-vector", CConfigurableObject::isInteger, + &VectorLimit, "0"); + m_pConfiguration->addParameter("-timestamp", CConfigurableObject::isBool, + NULL, "false"); + + // Create the enumeration and register the -gatemode parameter. + + static CConfigurableObject::isEnumParameter ValidGateMode; + for (int i=0; i < GateModeNumValues; i++) { + ValidGateMode.insert(GateModeValues[i]); + } + m_pConfiguration->addParameter("-gatemode", CConfigurableObject::isEnum, + &ValidGateMode, GateModeValues[0]); + + // the hold delays and widths have the same list constraints. + // just different default values. + + m_pConfiguration->addParameter("-holddelays", CConfigurableObject::isIntList, + &HoldValidity, "15"); + m_pConfiguration->addParameter("-holdwidths", CConfigurableObject::isIntList, + &HoldValidity, "20"); + + m_pConfiguration->addParameter("-gategenerator", CConfigurableObject::isBool, + NULL, "false"); + // Input range: + + static CConfigurableObject::isEnumParameter ValidInputRange; + for (int i = 0; i < InputRangeNumValues; i++) { + ValidInputRange.insert(InputRangeValues[i]); + } + m_pConfiguration->addParameter("-inputrange", CConfigurableObject::isEnum, + &ValidInputRange, InputRangeValues[0]); + + + m_pConfiguration->addParameter("-ecltermination", CConfigurableObject::isBool, + NULL, "true"); + m_pConfiguration->addParameter("-ecltiming", CConfigurableObject::isBool, + NULL, "false"); + m_pConfiguration->addParameter("-nimtiming", CConfigurableObject::isBool, + NULL, "false"); + // The timing source enum.. + + static CConfigurableObject::isEnumParameter ValidTimingSource; + for (int i = 0; i < TimingSourceNumValues; i++) { + ValidTimingSource.insert(TimingSourceValues[i]); + } + m_pConfiguration->addParameter("-timingsource", CConfigurableObject::isEnum, + &ValidTimingSource, TimingSourceValues[0]); + + + m_pConfiguration->addParameter("-thresholds", CConfigurableObject::isIntList, + &ThresholdValidity, "0"); + + +} +/*! + Initialize the module prior to data taking. We will get the initialization + data from the configuration. Unfortunately, there's no way to verify the + base address we were given actually points to a module. + + \param CVMUSB&controller References a VMSUB controller that will be used + to initilize the module (the module is in a VME crate connected to that + VMUSB object. +*/ + + +void +CMADC32::Initialize(CVMUSB& controller) +{ + // Locate the module and reset it and the fifo. + // These operations are the only individual operations and are done + // in case time is needed between reset and the next operations on the module. + // The remaining operations on the module will be done in + // a list so that they don't take so damned much time. + + + uint32_t base = m_pConfiguration->getIntegerParameter("-base"); + controller.vmeWrite16(base + Reset, initamod, 0); + controller.vmeWrite16(base + InitFifo, initamod, 0); + + CVMUSBReadoutList list; // Initialization instructions will be added to this. + + // First disable the interrupts so that we can't get any spurious ones during init. + + list.addWrite16(base + Ipl, initamod, 0); + + // Now retrieve the configuration parameters: + + uint16_t id = m_pConfiguration->getIntegerParameter("-id"); + uint8_t ipl = m_pConfiguration->getIntegerParameter("-ipl"); + uint8_t ivector = m_pConfiguration->getIntegerParameter("-vector"); + bool timestamp = m_pConfiguration->getBoolParameter("-timestamp"); + string gatemode = m_pConfiguration->cget("-gatemode"); + vector<int> holddelays = m_pConfiguration->getIntegerList("-holddelays"); + vector<int> holdwidths = m_pConfiguration->getIntegerList("-holdwidths"); + bool gdg = m_pConfiguration->getBoolParameter("-gategenerator"); + string inputrange = m_pConfiguration->cget("-inputrange"); + bool termination = m_pConfiguration->getBoolParameter("-ecltermination"); + bool ecltimeinput= m_pConfiguration->getBoolParameter("-ecltiming"); + bool nimtimeinput= m_pConfiguration->getBoolParameter("-nimtiming"); + string timesource = m_pConfiguration->cget("-timingsource"); + vector<int> thresholds = m_pConfiguration->getIntegerList("-thresholds"); + + // Write the thresholds. + + for (int i =0; i < 32; i++) { + list.addWrite16(base + Thresholds + i*sizeof(uint16_t), initamod, thresholds[i]); + } + + list.addWrite16(base + ModuleId, initamod, id); // Module id. + list.addWrite16(base + Vector, initamod, ivector); + + list.addWrite16(base + MarkType, initamod, timestamp ? 1 : 0); + + if (gatemode == string("separate")) { + list.addWrite16(base + BankOperation, initamod, 1); + } + else { + list.addWrite16(base + BankOperation, initamod, 0); + } + // If the gate generator is on, we need to program the hold delays and widths + // as well as enable it. + + if(gdg) { + list.addWrite16(base + HoldDelay0, initamod, holddelays[0]); + list.addWrite16(base + HoldDelay1, initamod, holddelays[1]); + + list.addWrite16(base + HoldWidth0, initamod, holdwidths[0]); + list.addWrite16(base + HoldWidth1, initamod, holdwidths[1]); + + list.addWrite16(base + EnableGDG, initamod, 1); + } else { + list.addWrite16(base + EnableGDG, initamod, 0); + } + + // Set the input range: + + if (inputrange == string("4v")) { + list.addWrite16(base + InputRange, initamod, 0); + } + else if (inputrange == string("8v")) { + list.addWrite16(base + InputRange, initamod, 1); + } + else { // 10V + list.addWrite16(base + InputRange, initamod, 2); + } + // Turn on or off ECL termination. In fact the module provides much more control + // over this featuer.. but for now we're all or nothing. + + if(termination) { + list.addWrite16(base + ECLTermination, initamod, 0xf); + } + else { + list.addWrite16(base + ECLTermination, initamod, 0); + } + + // Control which external sources can provide the timebase for the timestamp: + + if (ecltimeinput) { + list.addWrite16(base + ECLGate1OrTiming, initamod, 1); + list.addWrite16(base + ECLFCOrTimeReset, initamod, 1); + } + else { + list.addWrite16(base + ECLGate1OrTiming, initamod, 0); + list.addWrite16(base + ECLFCOrTimeReset, initamod, 0); + } + + if (nimtimeinput) { + list.addWrite16(base + NIMGate1OrTiming, initamod, 1); + list.addWrite16(base + NIMFCOrTimeReset, initamod, 1); + } + else { + list.addWrite16(base + NIMGate1OrTiming, initamod, 0); + list.addWrite16(base + NIMFCOrTimeReset, initamod, 0); + } + + // Source of the timebase: + + if(timesource == string("vme") ) { + list.addWrite16(base + TimingSource, initamod, 0); + } + else { + list.addWrite16(base + TimingSource, initamod, 1); + } + + + // Finally clear the converter and set the IPL which enables interrupts if + // the IPL is non-zero, and does no harm if it is zero. + + list.addWrite16(base + ReadoutReset, initamod, 0); + list.addWrite16(base + InitFifo, initamod, 0); + + list.addWrite16(base + Ipl, initamod, ipl); + + // Execute the list to initialize the module: + + + char readBuffer[100]; // really a dummy as these are all write... + size_t bytesRead; + int status = controller.executeList(list, readBuffer, sizeof(readBuffer), &bytesRead); + if (status != 0) { + throw string("List excecution to initialize an MADC32 failed"); + } + +} +/*! + Add instructions to read out the ADC for a event. Since we're only working in + single even tmode, we'll just read 'too many' words and let the + BERR terminate for us. This ensures that we'll have that 0xfff at the end of + the data. + \param list - The VMUSB read9out list that's being built for this stack. +*/ +void +CMADC32::addReadoutList(CVMUSBReadoutList& list) +{ + // Need the base: + + int base = m_pConfiguration->getIntegerParameter("-base"); + + list.addBlockRead32(base + eventBuffer, readamod, 40); +} + +// Cloning supports a virtual copy constructor. + +CReadoutHardware* +CMADC32::clone() const +{ + return new CMADC32(*this); +} Added: trunk/llnlReadout/devices/CMADC32.h =================================================================== --- trunk/llnlReadout/devices/CMADC32.h (rev 0) +++ trunk/llnlReadout/devices/CMADC32.h 2008-05-17 21:02:48 UTC (rev 1840) @@ -0,0 +1,107 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CMADC32_H +#define __CMADC32_h + +#ifndef __CREADOUTHARDWARE_H +#include "CReadoutHardware.h" +#endif + +#ifndef __CRT_STDINT_H +#include <stdint.h> +#ifndef __CRT_STDINT_H +#define __CRT_STDINT_H +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + + +// Forward class definitions: + +class CReadoutModule; +class CVMUSB; +class CVMUSBReadoutList; + + +/*! + The MADC32 is a 32 channel ADC module produced by Mesytec. + This module will be used in single event mode. + The following configuration parameters can be sued to tailor + the module: + +\verbatim + Name Value type Description + -base integer Base address of the module in VME space. + -id integer [0-255] Module id (part of the module header). + -ipl integer [0-7] Interrupt priority level 0 means disabled. + -vector integer [0-255] Interrupt vector. + -timestamp bool (false) If true enables the module timestamp. + -gatemode enum (separate,common) Determines if the bank gates are + independent or common. + -holddelays int[2] Delay between trigger and gate for each bank. + -holdwidths int[2] Lengths of generated gates. + -gategenerator bool Enable gate generator (hold stuff) + -inputrange enum (4v,8v,10v) ADC input range. + -ecltermination bool Enable termination of the ECL inputs. + -ecltming bool Enables ECL timestamp inputs + (oscillator and reset). + -nimtiming bool Enables NIM input for timestamp inputs + (oscillator & rset). + -timingsource enum (vme,external) Determines where timestamp source is. + -thresholds int[32] [0-4095] Threshold settings (0 means unused). +\endverbatim +*/ +class CMADC32 : public CReadoutHardware +{ +private: + CReadoutModule* m_pConfiguration; +public: + CMADC32(); + CMADC32(const CMADC32& rhs); + virtual ~CMADC32(); + CMADC32& operator=(const CMADC32& rhs); +private: + int operator==(CMADC32& rhs) const; + int operator!=(CMADC32& rhs) const; + + // The interface for CReadoutHardware: + +public: + virtual void onAttach(CReadoutModule& configuration); + virtual void Initialize(CVMUSB& controller); + virtual void addReadoutList(CVMUSBReadoutList& list); + virtual CReadoutHardware* clone() const; + + +}; + + + +#endif Modified: trunk/llnlReadout/devices/Makefile.am =================================================================== --- trunk/llnlReadout/devices/Makefile.am 2008-05-16 17:17:18 UTC (rev 1839) +++ trunk/llnlReadout/devices/Makefile.am 2008-05-17 21:02:48 UTC (rev 1840) @@ -8,7 +8,8 @@ C830.cpp \ CMarker.cpp \ C3804.cpp \ - CNADC2530.cpp + CNADC2530.cpp \ + CMADC32.cpp INCLUDES = -I$(top_builddir)/vmusb \ @@ -30,7 +31,8 @@ C830.h \ CMarker.h \ C3804.h \ - CNADC2530.h + CNADC2530.h \ + CMADC32.h This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |