From: <ro...@us...> - 2012-05-01 17:55:49
|
Revision: 2713 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2713&view=rev Author: ron-fox Date: 2012-05-01 17:55:39 +0000 (Tue, 01 May 2012) Log Message: ----------- Commit after merge to 10.1-003 (first shot) Modified Paths: -------------- trunk/nextgen/base/dataflow/Makefile.am trunk/nextgen/base/tclplus/Makefile.am trunk/nextgen/configure.ac trunk/nextgen/daq/format/Makefile.am trunk/nextgen/docconfig/config trunk/nextgen/epics/controlpush/Makefile.am trunk/nextgen/usb/Makefile.am trunk/nextgen/usb/ccusb/ccusb/Makefile.am trunk/nextgen/usb/ccusb/ccusb.xml trunk/nextgen/usb/ccusb/commands/CBeginRun.cpp trunk/nextgen/usb/ccusb/driverkit/drivertemplate.cpp trunk/nextgen/usb/ccusb/rdothread/CAcquisitionThread.cpp trunk/nextgen/usb/vmusb/Makefile.am trunk/nextgen/usb/vmusb/commands/CBeginRun.cpp trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.cpp trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.h trunk/nextgen/usb/vmusb/daqconfig/Makefile.am trunk/nextgen/usb/vmusb/devices/C3820.cpp trunk/nextgen/usb/vmusb/devices/C785.cpp trunk/nextgen/usb/vmusb/devices/C830.cpp trunk/nextgen/usb/vmusb/devices/CCAENChain.cpp trunk/nextgen/usb/vmusb/devices/CConfigurableObject.cpp trunk/nextgen/usb/vmusb/devices/CConfigurableObject.h trunk/nextgen/usb/vmusb/devices/CHINP.cpp trunk/nextgen/usb/vmusb/devices/CMADC32.cpp trunk/nextgen/usb/vmusb/devices/CMADCChain.cpp trunk/nextgen/usb/vmusb/devices/CMADCScaler.cpp trunk/nextgen/usb/vmusb/devices/CMASE.cpp trunk/nextgen/usb/vmusb/devices/CNADC2530.cpp trunk/nextgen/usb/vmusb/devices/CPSD.cpp trunk/nextgen/usb/vmusb/devices/CV1729.cpp trunk/nextgen/usb/vmusb/devices/CV1x90.cpp trunk/nextgen/usb/vmusb/devices/CV977.cpp trunk/nextgen/usb/vmusb/devices/CXLM.cpp trunk/nextgen/usb/vmusb/devices/MADC32Registers.h trunk/nextgen/usb/vmusb/devices/Makefile.am trunk/nextgen/usb/vmusb/rdothread/CAcquisitionThread.cpp trunk/nextgen/usb/vmusb/rdothread/CAcquisitionThread.h trunk/nextgen/usb/vmusb/rdothread/Makefile.am trunk/nextgen/usb/vmusb/router/COutputThread.cpp trunk/nextgen/usb/vmusb/tclserver/CV6533.cpp trunk/nextgen/usb/vmusb/tclserver/CV812.cpp trunk/nextgen/usb/vmusb/tclserver/ChicoTrigger.cpp trunk/nextgen/usb/vmusb/vmusb/CVMUSB.cpp trunk/nextgen/usb/vmusb/vmusb/CVMUSB.h trunk/nextgen/usb/vmusb/vmusb/CVMUSBReadoutList.cpp trunk/nextgen/usb/vmusb/vmusb/CVMUSBReadoutList.h trunk/nextgen/usb/vmusb/vmusb/CVMUSBRemote.cpp trunk/nextgen/usb/vmusb/vmusb/CVMUSBRemote.h trunk/nextgen/usb/vmusb/vmusb/Makefile.am trunk/nextgen/utilities/bufdump/Makefile.am trunk/nextgen/utilities/sclclient/Makefile.am Added Paths: ----------- trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.cpp trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.h trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.h trunk/nextgen/usb/vmusb/devices/CTclModule.cpp trunk/nextgen/usb/vmusb/devices/CTclModule.h trunk/nextgen/usb/vmusb/driverkit/ trunk/nextgen/usb/vmusb/driverkit/Makefile-template.in trunk/nextgen/usb/vmusb/driverkit/Makefile.am trunk/nextgen/usb/vmusb/driverkit/VMUSBDriverIncludes.in trunk/nextgen/usb/vmusb/driverkit/drivertemplate.cpp trunk/nextgen/usb/vmusb/vmusbReadout.xml Removed Paths: ------------- trunk/nextgen/usb/vmusb/driverkit/Makefile-template.in trunk/nextgen/usb/vmusb/driverkit/Makefile.am trunk/nextgen/usb/vmusb/driverkit/VMUSBDriverIncludes.in trunk/nextgen/usb/vmusb/driverkit/drivertemplate.cpp Property Changed: ---------------- trunk/nextgen/ trunk/nextgen/base/thread/ Property changes on: trunk/nextgen ___________________________________________________________________ Modified: svn:mergeinfo - /branches/nextgen-ccusb-feature:2631-2641 /branches/nextgen-ccusb-userdrivers-feature:2644-2659 + /branches/nextgen-ccusb-feature:2631-2641 /branches/nextgen-ccusb-userdrivers-feature:2644-2659 /branches/nextgen-vmusb-userdrivers-feature:2665-2711 Modified: trunk/nextgen/base/dataflow/Makefile.am =================================================================== --- trunk/nextgen/base/dataflow/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/base/dataflow/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -59,7 +59,7 @@ $(CC) -c ringtostdoutsw.c $(THREADC_FLAGS) ringtostdout_LDADD = ringtostdoutsw.o libDataFlow.la \ - $(top_builddir)/base/exception/libException.la \ + @top_builddir@/base/exception/libException.la \ $(THREADLD_FLAGS) ringtostdout_CXXFLAGS = $(AM_CXXFLAGS) $(THREADCXX_FLAGS) @@ -72,7 +72,7 @@ $(CC) -c stdintoringsw.c $(THREADC_FLAGS) stdintoring_LDADD = stdintoringsw.o libDataFlow.la \ - $(top_builddir)/base/exception/libException.la \ + @top_builddir@/base/exception/libException.la \ $(THREADLD_FLAGS) stdintoring_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) @@ -89,18 +89,22 @@ ManageTest.cpp WhilePredTest.cpp crmastertests.cpp RemoteTests.cpp unittests_LDADD = -L@prefix@/lib $(CPPUNIT_LDFLAGS) \ - $(top_builddir)/base/exception/libException.la \ + @top_builddir@/base/exception/libException.la \ -lDataFlow unittests_LDFLAGS = -Wl,"-rpath-link=$(libdir)" producer_SOURCES = producer.cpp -producer_LDADD = -L@prefix@/lib -lDataFlow $(top_builddir)/base/exception/libException.la + +producer_LDADD = -L@prefix@/lib -lDataFlow @top_builddir@/base/exception/libException.la + producer_LDFLAGS = -Wl,"-rpath-link=$(libdir)" consumer_SOURCES = consumer.cpp -consumer_LDADD = -L@prefix@/lib -lDataFlow $(top_builddir)/base/exception/libException.la + +consumer_LDADD = -L@prefix@/lib -lDataFlow @top_builddir@/base/exception/libException.la + consumer_LDFLAGS = -Wl,"-rpath-link=$(libdir)" TESTS=./unittests Modified: trunk/nextgen/base/tclplus/Makefile.am =================================================================== --- trunk/nextgen/base/tclplus/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/base/tclplus/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -26,6 +26,8 @@ # CItemConfiguration.cpp CConfigurableObject.cpp + + testableObjects = TCLInterpreter.lo TCLProcessor.lo \ TCLVariable.lo TCLString.lo \ TCLResult.lo TCLTimer.lo TCLFileHandler.lo \ @@ -65,7 +67,8 @@ evttclsh_DEPENDENCIES = libtclPlus.la evttclsh_LDADD = libtclPlus.la $(TCL_LDFLAGS) \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(TCL_LDFLAGS) evttclsh_LDFLAGS = -Wl,"-rpath-link=$(libdir)" $(TCL_LDFLAGS) @@ -108,6 +111,7 @@ tcpservertest_LDADD = libtclPlus.la \ @top_srcdir@/base/exception/libException.la \ $(TCL_LDFLAGS) + tcpservertest_LDFLAGS = -Wl,"-rpath-link=$(libdir)" $(TCL_LDFLAGS) Property changes on: trunk/nextgen/base/thread ___________________________________________________________________ Modified: svn:mergeinfo - /branches/nextgen-ccusb-feature/base/thread:2631-2641 /branches/nextgen-ccusb-userdrivers-feature/base/thread:2644-2660 + /branches/nextgen-ccusb-feature/base/thread:2631-2641 /branches/nextgen-ccusb-userdrivers-feature/base/thread:2644-2660 /branches/nextgen-vmusb-userdrivers-feature/base/thread:2665-2711 Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/configure.ac 2012-05-01 17:55:39 UTC (rev 2713) @@ -3,6 +3,7 @@ AC_PREREQ(2.61) AC_INIT(nscldaq, 10.1-003, fo...@ns...) + AC_CONFIG_SRCDIR([/utilities/StringsToIntegers.h]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -556,6 +557,8 @@ usb/vmusb/threadcomm/Makefile usb/vmusb/router/Makefile usb/vmusb/rdothread/Makefile usb/vmusb/tclserver/Makefile usb/vmusb/daqconfig/Makefile usb/vmusb/commands/Makefile + usb/vmusb/driverkit/Makefile usb/vmusb/driverkit/Makefile-template + usb/vmusb/driverkit/VMUSBDriverIncludes usb/ccusb/Makefile usb/ccusb/ccusb/Makefile usb/ccusb/devices/Makefile usb/ccusb/threadcomm/Makefile usb/ccusb/router/Makefile Modified: trunk/nextgen/daq/format/Makefile.am =================================================================== --- trunk/nextgen/daq/format/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/daq/format/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -46,13 +46,14 @@ unittests_LDADD = -L$(libdir) $(CPPUNIT_LDFLAGS) \ @top_srcdir@/base/dataflow/libDataFlow.la \ - @top_builddir@/base/exception/libException.la \ - @top_srcdir@/daq/format/libdataformat.la + @top_srcdir@/daq/format/libdataformat.la \ + @top_srcdir@/base/exception/libException.la + unittests_LDFLAGS = -Wl,"-rpath-link=$(libdir)" TESTS=./unittests -EXTRA_DIST = dataformat.xml \ No newline at end of file +EXTRA_DIST = dataformat.xml Modified: trunk/nextgen/docconfig/config =================================================================== --- trunk/nextgen/docconfig/config 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/docconfig/config 2012-05-01 17:55:39 UTC (rev 2713) @@ -1,2 +1,2 @@ introduction commands utilities libraries servers frameworks -1compatibility 1daq 1epics 1tcl 1sbsReadout 1usbReadout 3daq 3ccusb 3tcl 3sbsReadout 3usbReadout 5tcl +1compatibility 1daq 1epics 1tcl 1sbsReadout 1usbReadout 3daq 3ccusb 3vmusb 3tcl 3sbsReadout 3usbReadout 5tcl Modified: trunk/nextgen/epics/controlpush/Makefile.am =================================================================== --- trunk/nextgen/epics/controlpush/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/epics/controlpush/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -55,7 +55,7 @@ cmdline.c: options.ggo $(GENGETOPT) --unamed-opts <options.ggo -EXTRA_DIST=options.ggo Channels.dat controlpush.xml +EXTRA_DIST = options.ggo Channels.dat controlpush.xml noinst_PROGRAMS = unittests Modified: trunk/nextgen/usb/Makefile.am =================================================================== --- trunk/nextgen/usb/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -1 +1,8 @@ -SUBDIRS=vmusb ccusb \ No newline at end of file +SUBDIRS=vmusb ccusb + + +# +# Index the swig wrapper for the XX_USB packages: +# +install-exec-local: + (echo pkg_mkIndex $(libdir) libCVMUSB.so libCVMUSBReadoutList.so libCCCUSB.so libCCCUSBReadoutList.so | tclsh) \ No newline at end of file Modified: trunk/nextgen/usb/ccusb/ccusb/Makefile.am =================================================================== --- trunk/nextgen/usb/ccusb/ccusb/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/ccusb/ccusb/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -27,9 +27,6 @@ $(mkinstalldirs) @prefix@/ccusbdriver/includes $(INSTALL_DATA) *.h @prefix@/ccusbdriver/includes -install-exec-local: - (cd $(libdir); echo pkg_mkIndex . libCCCUSB.so libCCCUSBReadoutList.so | tclsh) - clean-local: $(RM) -f CCCUSB_wrap.cxx $(RM) -f CCCUSBReadoutList_wrap.cxx Modified: trunk/nextgen/usb/ccusb/ccusb.xml =================================================================== --- trunk/nextgen/usb/ccusb/ccusb.xml 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/ccusb/ccusb.xml 2012-05-01 17:55:39 UTC (rev 2713) @@ -109,13 +109,13 @@ <listitem> <para> In accordance with the way the CC-USB operates, you can create - two lists of <firstterm>stack</firstterm>s in CC-USB parlance. + two lists or <firstterm>stack</firstterm>s in CC-USB parlance. One stack is an event stack and is intended to be used to handle event triggers. The second stack is a scaler stack - and typically is set to readout periodicalyl. + and typically is set to readout periodically. </para> <para> - Each stack has, configuratino properties as well. One + Each stack has, configuration properties as well. One configuration property is the set of modules managed by that stack. Modules managed by that stack are initialized by the software, in accordance with their configuration, @@ -130,7 +130,7 @@ <title>Writing DAQ configuration files</title> <para> The DAQ configuration file is processed at the beginning of each run. - The configuratino file is processed in a fresh interpreter each time. + The configuration file is processed in a fresh interpreter each time. You therefore cannot maintain any state across runs via your configuration file. </para> @@ -210,8 +210,11 @@ <example> <title>Setting up a scaler stack</title> <programlisting> -stack create events -stack config events -modules [list testing tdc] -type event -delay 108 + +lrs2551 create counters -slot 5 +stack create scaler +stack config scaler -type scaler -period 2 -modules [list counters] + </programlisting> </example> </section> Modified: trunk/nextgen/usb/ccusb/commands/CBeginRun.cpp =================================================================== --- trunk/nextgen/usb/ccusb/commands/CBeginRun.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/ccusb/commands/CBeginRun.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -138,7 +138,7 @@ catch (...) { // Configuration file processing error of some sort... - tclUtil::setResult(interp, string("Begin - configuration file processing failed")); + tclUtil::setResult(interp, errorMessage); return TCL_ERROR; } Modified: trunk/nextgen/usb/ccusb/driverkit/drivertemplate.cpp =================================================================== --- trunk/nextgen/usb/ccusb/driverkit/drivertemplate.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/ccusb/driverkit/drivertemplate.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -316,5 +316,7 @@ /* END MODIFICATIONS */ + return TCL_OK; + } } Modified: trunk/nextgen/usb/ccusb/rdothread/CAcquisitionThread.cpp =================================================================== --- trunk/nextgen/usb/ccusb/rdothread/CAcquisitionThread.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/ccusb/rdothread/CAcquisitionThread.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -201,9 +201,12 @@ pBuffer = gFreeBuffers.get(); // need a new one. } else { -#ifdef REPORT_ERRORS - cerr << "Bad status from usbread: " << strerror(errno) << endl; -#endif + if (errno != ETIMEDOUT) { + cerr << "Bad status from usbread: " << strerror(errno) << endl; + cerr << "Ending the run .. check CAMAC crate. If it tripped off "; + cerr << " you'll need to restart this program\n"; + throw 1; + } } // Commands from our command queue. } Modified: trunk/nextgen/usb/vmusb/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -5,7 +5,8 @@ rdothread \ tclserver \ daqconfig \ - commands + commands \ + driverkit bin_PROGRAMS = VMUSBReadout @@ -41,7 +42,6 @@ $(TCL_LDFLAGS) $(USB_LIBS) @THREADLD_FLAGS@ - VMUSBReadout_LDFLAGS=-Wl,"-rpath=$(libdir)" cmdline.h: commandline.ggo @@ -53,4 +53,4 @@ $(GENGETOPT) <commandline.ggo $(CC) -c -I. cmdline.c $(THREADCFLAGS) -EXTRA_DIST=commandline.ggo \ No newline at end of file +EXTRA_DIST=commandline.ggo Modified: trunk/nextgen/usb/vmusb/commands/CBeginRun.cpp =================================================================== --- trunk/nextgen/usb/vmusb/commands/CBeginRun.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/commands/CBeginRun.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -115,21 +115,36 @@ // Now we can start the run. Globals::pConfig = new CConfiguration; + string errorMessage = "begin - Configuration fie processing failed: "; try { Globals::pConfig->processConfiguration(Globals::configurationFilename); } + catch (string msg) { + errorMessage += msg; + tclUtil::setResult(interp, errorMessage); + return TCL_ERROR; + } + catch (const char* msg) { + errorMessage += msg; + tclUtil::setResult(interp, errorMessage); + return TCL_ERROR; + } + catch (CException& e) { + errorMessage += e.ReasonText(); + tclUtil::setResult(interp, errorMessage); + return TCL_ERROR; + } catch (...) { // Configuration file processing error of some sort... - tclUtil::setResult(interp, string("Begin - configuration file processing failed")); + tclUtil::setResult(interp, errorMessage); return TCL_ERROR; } cerr << "Buffer multiplier (CBegin) = " << Globals::bufferMultiplier << endl; CAcquisitionThread* pReadout = CAcquisitionThread::getInstance(); - pReadout->start(Globals::pUSBController, - Globals::pConfig->getStacks()); + pReadout->start(Globals::pUSBController); tclUtil::setResult(interp, string("Begin - Run started")); return TCL_OK; Copied: trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.cpp (from rev 2711, branches/nextgen-vmusb-userdrivers-feature/usb/vmusb/daqconfig/CAddTclDriver.cpp) =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -0,0 +1,105 @@ +/* + 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 "CAddTclDriver.h" +#include <CTclModule.h> +#include <TCLInterpreter.h> +#include <TCLObject.h> +#include <CReadoutModule.h> +#include "CConfiguration.h" + +/** + * Constrution We need to register our command and save the configuration so that + * new elements can be added to it. + * + \param interp : CTCLInterpreter& + Tcl interpreter on which the command will be registered. + \param config : CConfiguration& config + The configuration of STACKs that will be manipulated by this command. + \param commandName std::string + Name of the command to register. +*/ +CAddTclDriver::CAddTclDriver(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CTCLObjectProcessor(interp, commandName), + m_Config(config) +{} + +/** + * Base class destructor does all the work: + */ +CAddTclDriver::~CAddTclDriver() {} + +/** + * Command processing. Ensure the command has the right number of parameter, + * Construct a TclDriver and register it with the configuration. + * We don't have any subcommands actually...unlike the other configuration support commands. + * + Command entry ensures there are at least a three command words, + the command itself, the subcommand and the name of a module being + manipulated. + + Based on the value of the subcommand, the appropriate processing + function is invoked. + + \param interp - The interpreter that's running this command. + \param objv - Vector of command words. + + \return int + \retval TCL_OK - The command succeeded. + \retval TCL_ERROR - The command failed in some way. + + \note The interpreter result will be empty on success and an error message on failure. +*/ +int +CAddTclDriver::operator()(CTCLInterpreter& interp, std::vector<CTCLObject>& objv) +{ + // must have two parameter: + + if (objv.size() != 2) { + m_Config.setResult("Usage:\n addtcldriver base-command-name"); + return TCL_ERROR; + } + + // Bind the name and get it as a string: + + objv[1].Bind(interp); + std::string baseCommand = objv[1]; + + // Ensure the base command is not an existing device name: + + CReadoutModule* pModule = m_Config.findAdc(baseCommand); + if (pModule) { + std::string msg = "Error registering "; + msg += baseCommand; + msg += " as a Tcl driver. There is already a module with that name"; + m_Config.setResult(msg); + return TCL_ERROR; + } + + // Create the wrapper object and register it with the configuratino. + // note that we need a configuration object (since that's what's actually registered), + // even though this has no intrinsic configuration (that's managed by the driver). + // + + CTclModule* pDriver = new CTclModule(baseCommand, interp); + pModule = new CReadoutModule(baseCommand, *pDriver); + m_Config.addAdc(pModule); + + return TCL_OK; + +} Copied: trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.h (from rev 2711, branches/nextgen-vmusb-userdrivers-feature/usb/vmusb/daqconfig/CAddTclDriver.h) =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CAddTclDriver.h 2012-05-01 17:55:39 UTC (rev 2713) @@ -0,0 +1,84 @@ +/* + 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 __CADDTCLDRIVER_H +#define __CADDTCLDRIVER_H + +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + + +class CTCLInterpreter; +class CTCLObject; +class CReadoutModule; +class CConfiguration; + +/** + * This class supports adding a Tcl command ensemble as a device support module instance. + * The base command is wrapped in a CTclDriver object and registered with the configuration + * as a digitizer device with a name that matches the name of the command ensemble. + * The intent is that one writes device support classes/types using one of the Tcl + * object oriented extensions such as itcl or snit and then create instances for each + * physical device you support, configuring the device and then invoking this command to add + * it to the set known by the readout software. The readout software will then use the wrapper + * to invoke Initialize and addReadoutList subcommands of the registered command to perform + * those deeds at the appropriate time for instances that were added to stacks. + * + * \verbatim + * addtcldriver command-base-name + */ + +class CAddTclDriver : public CTCLObjectProcessor +{ +private: + CConfiguration& m_Config; // The global configuration object. + + // Allowed canonicals: +public: + CAddTclDriver(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("addtcldriver")); + virtual ~CAddTclDriver(); + + // Forbidden canonicals: +private: + CAddTclDriver(const CAddTclDriver&); // copy construtor. + CAddTclDriver& operator+(const CAddTclDriver&); // assignment. + int operator==(const CAddTclDriver&); // equality compare. + int operator!=(const CAddTclDriver&); // inequality compare. + + // public members: + + virtual int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); +}; + +#endif Modified: trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -35,6 +35,7 @@ #include "CHINPCommand.h" #include "CV1729Command.h" #include "CV1495scCommand.h" +#include "CAddTclDriver.h" #include <CReadoutModule.h> #include <TCLInterpreter.h> @@ -63,6 +64,7 @@ m_pInterp(0) { Tcl_Interp* pInterp = Tcl_CreateInterp(); + Tcl_Init(pInterp); // Initialize the pkg search paths. m_pInterp = new CTCLInterpreter(pInterp); @@ -88,6 +90,7 @@ m_Commands.push_back(new CHINPCommand(*m_pInterp, *this)); m_Commands.push_back(new CV1729Command(*m_pInterp, *this)); m_Commands.push_back(new CV1495scCommand(*m_pInterp, *this)); + m_Commands.push_back(new CAddTclDriver(*m_pInterp, *this)); } /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.h 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/daqconfig/CConfiguration.h 2012-05-01 17:55:39 UTC (rev 2713) @@ -69,6 +69,10 @@ CConfiguration(); virtual ~CConfiguration(); + // selectors: + + CTCLInterpreter* getInterpreter() {return m_pInterp;} + // lazy so: private: CConfiguration(const CConfiguration& rhs); Copied: trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.cpp (from rev 2711, branches/nextgen-vmusb-userdrivers-feature/usb/vmusb/daqconfig/CUserCommand.cpp) =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -0,0 +1,409 @@ +/* + 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 "CUserCommand.h" + +#include <TCLInterpreter.h> +#include <TCLObject.h> +#include <CConfiguration.h> +#include <CReadoutModule.h> +#include <CReadoutHardware.h> +#include <Exception.h> +#include <Globals.h> + +using namespace std; + +/************************************************************** + * Canonical methods + **************************************************************/ + +/** + * Construct an instance of the command. + * + * @param interp - The interpreter the command is registered on. + * @param config - The configuration the command manipulates. + * @param commandName - The name of the command + * @param pTemplate - A template device driver which will be cloned + * to produce specific device driver instances. + */ +CUserCommand::CUserCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName, CReadoutHardware* pTemplate) : + CTCLObjectProcessor(interp, commandName), + m_Config(config), + m_pTemplate(pTemplate) +{ + +} +/** + * For now deletion is a no-op. + */ +CUserCommand::~CUserCommand() {} + +/********************************************************************* + * Command Processing + ********************************************************************/ + +/** + * Gains control when the registered command is invoked. Based on the + * Subcommand dispatches to one of create, config, cget or indicates + * an error with an error return in the Tcl interpreter. + * + * @param interp - Tcl Interpreter that is executing the command. + * @param objv - vector of wrapped Tcl_Objv objects that are the command words. + * + * @return int + * @return TCL_OK - successful command. See create, config, cget for information + * about what, if anything, the result might be. + * @return TCL_ERROR - Failed command. The command result is a human readable error + * message. + */ +int +CUserCommand::operator()(CTCLInterpreter& interp, std::vector<CTCLObject>& objv) +{ + if (objv.size() < 3) { + Usage("Incorrect number of command parameters", objv); + return TCL_ERROR; + } + // Get the subcommand keyword and dispatch or error: + + string subcommand = objv[1]; + if (subcommand == string("create")) { + return create(interp, objv); + } + else if (subcommand == string("config")) { + return config(interp, objv); + } + else if (subcommand == string("cget")) { + return cget(interp, objv); + } + else { + Usage("Invalid subcommand", objv); + return TCL_ERROR; + } + +} +/** + * Creates a new instance of a driver. This command has the form: + * + * \verbatim + * xxx create name ?options? + * \endverbatim + * + * Where options are a list of configuration option names followed by values as in e.g.: + * + * \verbatim + * xxx create name -slot 6 -anotheroption stuff ... + * \endverbatim + * + * @param interp - Tcl Interpreter that is executing the command. + * @param objv - vector of wrapped Tcl_Objv objects that are the command words. + * + * @return int + * @return TCL_OK - successful command. The command result is the name of the module + * supporting constructs like set name [xxx create george...] + * @return TCL_ERROR - Failed command. The command result is a human readable error + * message. + */ +int +CUserCommand::create(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv) +{ + // Need to make sure the word count of the command is valid. + + if ((objv.size() < 3) || ((objv.size() & 1) == 0)) { + Usage("Invalid number of command parameters, must be at least 3 and odd", + objv); + return TCL_ERROR; + } + + // Get the name of the module, ensure it will be unique: + + string name = objv[2]; + + CReadoutModule* pModule = m_Config.findAdc(name); + if (pModule) { + Usage("Duplicate module creation attempted: ", objv); + return TCL_ERROR; + } + // Since the module is unique, we can create it we won't register it until + // the configuration is successful; + + CReadoutHardware* pNewModule = m_pTemplate->clone(); + pModule = new CReadoutModule(name, *pNewModule); // Also attaches pAdc to configuration. + + // If there are configuration parametesr, process them + + int status = TCL_OK; + if (objv.size() > 3) { + status = configure(interp, + pModule, + objv); + } + + // Add the module if all is still ok. + + if (status == TCL_OK) { + m_Config.addAdc(pModule); + m_Config.setResult(name); + } + else { + delete pModule; + delete pNewModule; + } + return status; +} + +/* + Process the config subcommand. + - Ensure there are enough command parameters. We need at least 5, and + we need an odd number of configuration parameters to ensure that + the -switch/value pairs are balanced. + - Ensure the module exists. + - Let the configure utility take care of the rest of the work (factored code + with the create method). + + Parameters: + CTCLInterpreter& interp - Interpreter that is executing this command. + vector<CTCLObject>& objv - Vector of command words. + Returns: + int: + TCL_OK - Command was successful. + TCL_ERROR - Command failed. + Side effects: + The interpreter result is set with an error message if the return value + is TCL_ERROR, otherwise it is set with the module name. + +*/ +int +CUserCommand::config(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv) +{ + // Ensure the parameter counts are valid: + + if ((objv.size() < 5) || ((objv.size() & 1) == 0)) { + Usage("Incorrect number of command parameters for config", objv); + return TCL_ERROR; + } + + // Get the module name and locate it.. it's an error for the module to not exist. + + string name = objv[2]; + CReadoutModule* pModule = m_Config.findAdc(name); + if(!pModule) { + Usage("ad811 module does not exist", objv); + return TCL_ERROR; + } + // and configure: + + m_Config.setResult(name); // This gets overwritten in case of error. + return configure(interp, pModule, objv); + +} +/* + Process the cget subcommand which returns the configuration of a module as + a list of keyword/value pairs. + keyword/value pairs. + - ensure we have enough command line parameters (exactly 3). + - Ensure the module exists and get its pointer. + - Fetch the module's configuration. + - Map the configuration into a list of 2 element lists and set the + result accordingly. + + Parameters: + CTCLInterpreter& interp - Interpreter that is executing this command. + vector<CTCLObject>& objv - Vector of command words. + Returns: + int: + TCL_OK - Command was successful. + TCL_ERROR - Command failed. + Side effects: + The interpreter result is set. If the command returned an error, + This is a string that begins with the text ERROR: otherwise it is a + list of 2 element sublists where each sublist is a configuration keyword + value pair...e.g. {-base 0x80000000} ... +*/ +int +CUserCommand::cget(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv) +{ + if (objv.size() != 3) { + Usage("Invalid command parameter count for cget", objv); + return TCL_ERROR; + } + string name = objv[2]; + CReadoutModule *pModule = m_Config.findAdc(name); + if (!pModule) { + Usage("No such module", objv); + return TCL_ERROR; + } + CConfigurableObject::ConfigurationArray config = pModule->cget(); + + Tcl_Obj* pResult = Tcl_NewListObj(0, NULL); + + for (int i =0; i < config.size(); i++) { + Tcl_Obj* key = Tcl_NewStringObj(config[i].first.c_str(), -1); + Tcl_Obj* value = Tcl_NewStringObj(config[i].second.c_str(), -1); + + Tcl_Obj* sublist[2] = {key, value}; + Tcl_Obj* sl = Tcl_NewListObj(2, sublist); + Tcl_ListObjAppendElement(interp.getInterpreter(), pResult, sl); + } + Tcl_SetObjResult(interp.getInterpreter(), pResult); + return TCL_OK; +} + +/************************************************************************ + * Attribute selectors + ***********************************************************************/ + +CConfiguration* +CUserCommand::getConfiguration() +{ + return &m_Config; +} +/***********************************************************************/ +/* Produce an error message, set it in the interpreter result field. + Parameters: + msg - A string to put in the message. + objv - The command words which are also put in the error message to + help the user locate the problem. + +*/ +void +CUserCommand::Usage(std::string msg, std::vector<CTCLObject> objv) +{ + string result("ERROR: "); + string cmdName = objv[0]; + + result += msg; + result += "\n"; + for (int i = 0; i < objv.size(); i++) { + result += string(objv[i]); + result += ' '; + } + result += "\n"; + result += "Usage\n"; + result += " "; + result += cmdName; + result += " create name -slot n\n"; + result += " "; + result += cmdName; + result += " config name config-params...\n"; + result += " "; + result += cmdName; + result += " cget name"; + + m_Config.setResult(result); +} +/*******************************************************************/ +/* Configures an object. The caller is supposed to have + validated that an even number of configuration parameters have + been supplied. + + Parameters: + interp - The intepreter that is executing the caller. + pModule - Pointer to the module being configured. + config - The command doing the configuration. + firstPair - Index into config of the first keyword/value pair. + defaults to 3 which is just right for the create/config + subcommands. + Returns: + TCL_OK - The configuration succeeded. + TCL_ERROR - The configuration failed...and the interpreter result says why. +*/ +int +CUserCommand:: configure(CTCLInterpreter& interp, + CReadoutModule* pModule, + std::vector<CTCLObject>& config, + int firstPair) +{ + string message = "Invalid configuration parameter pair "; + + string key; + string value; + try { + for (int i =firstPair; i < config.size(); i+= 2) { + key = (string)config[i]; + value = (string)config[i+1]; + pModule->configure(key, value); + } + } + catch (CException& e) { + + Usage(configMessage(message, key, value, string(e.ReasonText())), + config); + return TCL_ERROR; + } + catch (string msg) { + Usage(configMessage(message, key, value, msg), + config); + return TCL_ERROR; + } + catch (const char* msg) { + Usage(configMessage(message, key, value, string(msg)), + config); + return TCL_ERROR; + } + catch (...) { + Usage(configMessage(message, key, value, string(" unexpected exception ")), + config); + return TCL_ERROR; + } + + return TCL_OK; +} +/*************************************************************************/ +/* + Factors the generation of an error message for configuration errors + out of the various exception handlers: +*/ +string +CUserCommand::configMessage(std::string base, + std::string key, + std::string value, + std::string errorMessage) +{ + string message = base; + message += key; + message += " "; + message += value; + message += " : "; + message += errorMessage; + + return message; + +} + +/********************************************************************** + * Static member functions. + **********************************************************************/ + +/** + * Add a new driver command to the set recognized by the + * configuration subsystem. + * + * @param command - command name. + * @param pTemplateObject - CReadoutControlHardware pointer to an object that will + * be cloned for the creation of each instance of the driver. + */ +void +CUserCommand::addDriver(std::string command, CReadoutHardware* pTemplateObject) +{ + CConfiguration* pConfig = Globals::pConfig; + new CUserCommand(*(pConfig->getInterpreter()), + *pConfig, command, pTemplateObject); +} Copied: trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.h (from rev 2711, branches/nextgen-vmusb-userdrivers-feature/usb/vmusb/daqconfig/CUserCommand.h) =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CUserCommand.h 2012-05-01 17:55:39 UTC (rev 2713) @@ -0,0 +1,127 @@ +/* + 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 __CUSERCOMMAND_H +#define __CUSERCOMMAND_H + +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + + +class CTCLInterpreter; +class CTCLObject; +class CConfiguration; +class CReadoutModule; +class CReadoutHardware; + +/*! + This class provides support for generic user written device drivers in C++ + A new device driver is implemented in a Tcl Loadable package (.so). The + xxx_Init for that package will then invoke + + \verbatim + CxxDriver* pTemplate = new CxxDriver; + CUserCommand::addDriver("xxx", pTemplate); + \endverbatim + + Where CxxDriver is derived from CReadoutHardware, xxx is the new Tcl command + ensemble that's created to run the driver from the configuration script and + pTemplate is duplicated each time a driver instance is required. + +\verbatim + This command is an ensemble of the form: + xxx create name -slot n + xxx config name option-value-pairs + xxx cget name +\endverbatim + + +*/ +class CUserCommand : public CTCLObjectProcessor +{ +private: + CConfiguration& m_Config; // This is the global configuration of devices. + CReadoutHardware* m_pTemplate; + + + // Allowed canonicals +public: + CUserCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName, CReadoutHardware* pTemplate); + virtual ~CUserCommand(); + + // Forbidden canonicals: +private: + CUserCommand(const CUserCommand& rhs); + CUserCommand& operator=(const CUserCommand& rhs); + int operator==(const CUserCommand& rhs) const; + int operator!=(const CUserCommand& rhs) const; +public: + + + // Public members like selectors and the command entry point: + + CConfiguration* getConfiguration(); + virtual int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + // Processors for the individual ensemble subcommands. +private: + int create(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + int config(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + int cget(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + + // Utitilities: + +private: + virtual void Usage(std::string msg, std::vector<CTCLObject> objv); + int configure(CTCLInterpreter& interp, + CReadoutModule* pModule, + std::vector<CTCLObject>& config, + int firstPair = 3); + std::string configMessage(std::string base, + std::string key, + std::string value, + std::string errorMessage); + +public: + // static entry that allows packages to register drivers with commands: + + static void addDriver(std::string command, CReadoutHardware* pTemplateObject); + +}; + +#endif Modified: trunk/nextgen/usb/vmusb/daqconfig/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2012-05-01 17:55:39 UTC (rev 2713) @@ -17,7 +17,9 @@ CHINPCommand.cpp \ CPSDCommand.cpp \ CV1729Command.cpp \ - CV1495scCommand.cpp + CV1495scCommand.cpp \ + CUserCommand.cpp \ + CAddTclDriver.cpp libVMUSBConfig_la_CXXFLAGS=@THREADCXX_FLAGS@ @@ -41,7 +43,9 @@ CHINPCommand.h \ CPSDCommand.h \ CV1729Command.h \ - CV1495scCommand.h + CV1495scCommand.h \ + CUserCommand.h \ + CAddTclDriver.h @@ -59,3 +63,7 @@ @top_srcdir@/base/exception/libException.la \ $(TCL_LDFLAGS) @THREADLD_FLAGS@ +install-data-local: + $(mkinstalldirs) @prefix@/vmusbdriver + $(mkinstalldirs) @prefix@/vmusbdriver/includes + $(INSTALL_DATA) *.h @prefix@/vmusbdriver/includes \ No newline at end of file Modified: trunk/nextgen/usb/vmusb/devices/C3820.cpp =================================================================== --- trunk/nextgen/usb/vmusb/devices/C3820.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/devices/C3820.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -173,8 +173,8 @@ initList.addWrite32(base+AcqMode, CVMUSBReadoutList::a32UserData, acq32Bit | acqLNEVME | acqArmWithFP | acqSRAMMemory | acqInpLNEInh4s | acqOutModeled | acqModeLatch); - initList.addWrite32(base+KeyArm, CVMUSBReadoutList::a32UserData, 0); - initList.addWrite32(base+KeyEnable, CVMUSBReadoutList::a32UserData, 0); + initList.addWrite32(base+KeyArm, CVMUSBReadoutList::a32UserData, (uint32_t)0); + initList.addWrite32(base+KeyEnable, CVMUSBReadoutList::a32UserData, (uint32_t)0); uint32_t inBuffer[100]; @@ -196,9 +196,9 @@ C3820::addReadoutList(CVMUSBReadoutList& list) { uint32_t base = getBase(); - list.addWrite32(base+KeyLNE, CVMUSBReadoutList::a32UserData, 0); + list.addWrite32(base+KeyLNE, CVMUSBReadoutList::a32UserData, (uint32_t)0); list.addBlockRead32(base+ShadowCounters, CVMUSBReadoutList::a32UserBlock, - 32); + (uint32_t)32); } /*! Modified: trunk/nextgen/usb/vmusb/devices/C785.cpp =================================================================== --- trunk/nextgen/usb/vmusb/devices/C785.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/devices/C785.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -43,9 +43,9 @@ // Address modifiers used to access the module: -Const(initamod) CVMUSBReadoutList::a32UserData; -Const(readamod) CVMUSBReadoutList::a32PrivBlock; -Const(cbltamod) CVMUSBReadoutList::a32PrivBlock; +static const uint8_t initamod(CVMUSBReadoutList::a32UserData); +static const uint8_t readamod(CVMUSBReadoutList::a32PrivBlock); +static const uint8_t cbltamod(CVMUSBReadoutList::a32PrivBlock); // Register map (offsets in bytes) for the V785 // Not an exhaustive list as the various test registers are omitted. @@ -380,22 +380,22 @@ // flipping the the SOFT.RESET bit in the bit set 1 register. // sett fig 4.12 in the V785 manual. - controller.vmeWrite16(base+BSet1, initamod, 0x80); - controller.vmeWrite16(base+BClear1, initamod, 0x80); + controller.vmeWrite16(base+BSet1, initamod, (uint16_t)0x80); + controller.vmeWrite16(base+BClear1, initamod, (uint16_t)0x80); // turn off multicast and set the mcast address to zero... // this latter because that tries to ensure there's not a collision between // The mcast and rotary base addresses. // - controller.vmeWrite16(base+McastAddr, initamod, 0); - controller.vmeWrite16(base+McastCtl, initamod, 0); + controller.vmeWrite16(base+McastAddr, initamod, (uint16_t)0); + controller.vmeWrite16(base+McastCtl, initamod, (uint16_t)0); // Set the GEOgraphical address of the module. uint16_t geo = getIntegerParameter("-geo"); controller.vmeWrite16(base+GEO, initamod, geo); - controller.vmeWrite16(base+BSet1, initamod, 0x80); - controller.vmeWrite16(base+BClear1, initamod, 0x80); + controller.vmeWrite16(base+BSet1, initamod, (uint16_t)0x80); + controller.vmeWrite16(base+BClear1, initamod, (uint16_t)0x80); // Set the thresholds for the module: // As well as the meaning of the thresholds. @@ -408,10 +408,10 @@ threshold); } if (getBoolParameter("-smallthresholds")) { - controller.vmeWrite16(base+BSet2, initamod, 0x100); // big thresholds. + controller.vmeWrite16(base+BSet2, initamod, (uint16_t)0x100); // big thresholds. } else { - controller.vmeWrite16(base+BClear2, initamod, 0x100); // small thresholds. + controller.vmeWrite16(base+BClear2, initamod, (uint16_t)0x100); // small thresholds. } // Set the interrupt characteristics of the module: @@ -427,7 +427,7 @@ // // controller.vmeWrite16(base+EventTrig, initamod, WhenIRQ); // - controller.vmeWrite16(base+EventTrig, initamod, 1); + controller.vmeWrite16(base+EventTrig, initamod, (uint16_t)1); // Set the fast clear window: @@ -438,10 +438,10 @@ bool supressed = getBoolParameter("-supressrange"); if (!supressed) { // Set means disable checks. - controller.vmeWrite16(base+BSet2, initamod, 0x38); + controller.vmeWrite16(base+BSet2, initamod, (uint16_t)0x38); } else { - controller.vmeWrite16(base+BClear2, initamod, 0x38); + controller.vmeWrite16(base+BClear2, initamod, (uint16_t)0x38); } // If the user chooses to require data even if the module @@ -449,10 +449,10 @@ bool requireData = getBoolParameter("-requiredata"); if (requireData) { - controller.vmeWrite16(base+BSet2, initamod, 0x1000); + controller.vmeWrite16(base+BSet2, initamod, (uint16_t)0x1000); } else { - controller.vmeWrite16(base+BClear2, initamod, 0x1000); + controller.vmeWrite16(base+BClear2, initamod, (uint16_t)0x1000); } // If the module is a 775 write the timerange register. @@ -496,7 +496,7 @@ // All this makes the mask: // 0x24 // - controller.vmeWrite16(base+Control1, initamod, 0x24); + controller.vmeWrite16(base+Control1, initamod, (uint16_t)0x24); @@ -524,9 +524,9 @@ // Clear event buffers: list.addWrite16(base + BSet2, - initamod, 4); + initamod, (uint16_t)4); list.addWrite16(base + BClear2, - initamod, 4); + initamod, (uint16_t)4); } } Modified: trunk/nextgen/usb/vmusb/devices/C830.cpp =================================================================== --- trunk/nextgen/usb/vmusb/devices/C830.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/devices/C830.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -224,7 +224,7 @@ // Reset the module: - controller.vmeWrite16(baseAddress + RESET, configAmod, 0); + controller.vmeWrite16(baseAddress + RESET, configAmod, (uint16_t)0); // Create and build the list to initialize the module completely. @@ -302,7 +302,7 @@ if (getTriggerSource() == vme) { list.addDelay(50); // Seems to need a settled bus? - list.addWrite16(baseAddress + TRIGGER, configAmod, 0); + list.addWrite16(baseAddress + TRIGGER, configAmod, (uint16_t)0); list.addDelay(75); // 200ns units. } // Add the transfer from the MEB @@ -313,7 +313,7 @@ list.addRead32(baseAddress + MEB + i*sizeof(long), configAmod); } - list.addWrite16(baseAddress + CLEAR, configAmod, 0); + list.addWrite16(baseAddress + CLEAR, configAmod, (uint16_t)0); } Modified: trunk/nextgen/usb/vmusb/devices/CCAENChain.cpp =================================================================== --- trunk/nextgen/usb/vmusb/devices/CCAENChain.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/devices/CCAENChain.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -30,8 +30,8 @@ static const unsigned int LongwordsPerModule(36); // Maximum # longwords/module. -static const int cbltamod(CVMUSBReadoutList::a32UserBlock); -static const int mcstamod(CVMUSBReadoutList::a32UserData); +static const uint8_t cbltamod(CVMUSBReadoutList::a32UserBlock); +static const uint8_t mcstamod(CVMUSBReadoutList::a32UserData); static const uint32_t BSET2(0x1032); // Offset to the bit set 2 register. static const uint32_t BCLR2(0x1034); // Offset t the bit clear 2 register. Modified: trunk/nextgen/usb/vmusb/devices/CConfigurableObject.cpp =================================================================== --- trunk/nextgen/usb/vmusb/devices/CConfigurableObject.cpp 2012-05-01 16:52:05 UTC (rev 2712) +++ trunk/nextgen/usb/vmusb/devices/CConfigurableObject.cpp 2012-05-01 17:55:39 UTC (rev 2713) @@ -20,12 +20,15 @@ #include <stdlib.h> #include <errno.h> #include <tcl.h> +#include <ErrnoException.h> +#include <TCLInterpreter.h> +#include <TCLObject.h> #include <math.h> -#include <tcl.h> -#include <string.h> +#include <stdlib.h> +#include <sstream> + using namespace std; - //////////////////////////////////////////////////////////////////////////// ////////////////////////// Constants /////////////////////////////////// /////////////////////////////////////////////////////////////////////////// @@ -34,6 +37,19 @@ {CConfigurableObject::limit(0), CConfigurableObject::limit(0)}; + +// Inline utilities: + +// Convert an integer to a string: + +inline std::string itos(int i) +{ + std::stringstream ss; + ss << i; + return ss.str(); +} + + /////////////////////////////////////////////////////////////////////////// //////////////////////// Canonical member functions /////////////////////// /////////////////////////////////////////////////////////////////////////// @@ -50,20 +66,19 @@ /*! Destruction probably will result in some memory leaks since - it is possible that the typeChecker's will have parameters that - are dynamically allocated. In a future life we can provide - cleanup functions.. for now we just assume that destruction will - be infrequent, and leaks will be small enough to be tolerated. - - I think that destruction is not necessary since all the - pairs will copyconstruct/assign into the map. - This is a place holder for later code that can handle deletion of the - typechecker args. + it is possible that user typeChecker's may have parameters that + are dynamically allocated. + If people use the convenience functions for building typed parameters, + we will manage that memory properly. Each dynamic item gets added to the m_constraints + list from which it gets deleted via free. + */ CConfigurableObject::~CConfigurableObject() { - deleteEnumCheckers(); + releaseConstraintCheckers(); + + } /*! @@ -74,7 +89,6 @@ m_name(rhs.m_name), m_parameters(rhs.m_parameters) { - addEnumCheckers(rhs.m_EnumCheckers); } /*! @@ -86,8 +100,6 @@ if (this != &rhs) { m_name = rhs.m_name; m_parameters = rhs.m_parameters; - deleteEnumCheckers(); - addEnumCheckers(rhs.m_EnumCheckers); } return *this; } @@ -149,8 +161,6 @@ ConfigData data = found->second; return data.first; } - - /*! Get the values of all the configuration parameters. \return CCOnfigurableObject::ConfigurationArray @@ -177,6 +187,89 @@ } return result; } +/////////////////////////////////////////////////////////////////////////// +/////////////////////// Establishing the configuration ///////////////////// +/////////////////////////////////////////////////////////////////////////// + +/*! + Adds a configuration parameter to the configuration. + If there is already a configuration parameter by this name, + it is silently ovewritten. + + \param name : std::string + Name of the parameter to add. + \param checker : typeChecker + A type checker to validate the values proposed for the parameter, + if NULL, no validation is performed. + \param arg : void + Parameter passed without interpretation to the typechecker at validation + time. + \param defaultValue : string (default = "") + Initial value for the parameter. +*/ +void +CConfigurableObject::addParameter(string name, + typeChecker checker, + void* arg, + string defaultValue) +{ + TypeCheckInfo checkInfo(checker, arg); + ConfigData data(defaultValue, checkInfo); + m_parameters[name] = data; // This overwrites any prior. +} + +/*! + Configure the value of a parameter. + \param name : std::string + Name of the parameter to configure. + \param value : std::string + New value of the parameter + + \throw std::string("No such parameter") if the parameter 'name' is not defined. + \throw std::string("Validation failed for 'name' <- 'value'") if the value + does not pass the validator for the parameter. +*/ +void +CConfigurableObject::configure(string name, string value) +{ + // Locate the parameter and complain if it isn't in the map: + + ConfigIterator item = m_parameters.find(name); + if(item == m_parameters.end()) { + string msg("No such parameter: "); + msg += name; + throw msg; + } + // If the parameter has a validator get it and validate: + + TypeCheckInfo checker = item->second.second; + typeChecker pCheck = checker.first; + if (pCheck) { // No checker means no checkig. + if (! (*pCheck)(name, value, checker.second)) { + string msg("Validation failed for "); + msg += name; + msg += " <- "; + msg += value; + throw msg; + } + } + // Now set the new validated value: + + m_parameters[name].first = value; + +} +/*! + clear the current configuration. The configuration map m_parameters + map is emptied. +*/ +void +CConfigurableObject::clearConfiguration() +{ + m_parameters.clear(); + releaseConstraintCheckers(); +} + + ///////////////////////////////////////////////////////////////////////////// ///////////////////// convenience functions ///////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -294,38 +387,69 @@ return result; } -/////////////////////////////////////////////////////////////////////////// -/////////////////////// Establishing he configuration ///////////////////// -/////////////////////////////////////////////////////////////////////////// -/*! - Adds a configuration parameter to the configuration. - If there is already a configuration parameter by this name, - it is silently ovewritten. +/** + * Add an integer parameter to the configuration that has no limits. + * + * @param name - Name of the configuration item (e.g. -someparam). + * @param defaultVal - Value given the configuration parameter if it is not explicitly configured. + */ +void +CConfigurableObject::addIntegerParameter(std::string name, int defaultVal) +{ - \param name : std::string - Name of the parameter to add. - \param checker : typeChecker - A type checker to validate the values proposed for the parameter, - if NULL, no validation is performed. - \param arg : void - Parameter passed without interpretation to the typechecker at validation - time. - \param defaultValue : string (default = "") - Initial value for the parameter. -*/ + + // Use the normal creation function. + + addParameter(name, CConfigurableObject::isInteger, NULL, itos(defaultVal)); + +} +/** + * Add an integer parameter to the configuration with supplied lower and + * upper limits. + * + * @param name - Name of the parameter (e.g. -someparam). + * @param low - Low limit on the values accepted for the parameter. + * @param high - High limit on the values accepted for the parameter. + * @param defaultVal - Default value of not explicitly given. This is 0 unless that's outside the + * low/high range in which case, low is used. + */ void -CConfigurableObject::addParameter(string name, - typeChecker checker, - void* arg, - string defaultValue) +CConfigurableObject::addIntegerParameter(std::string name, int low, int high, int defaultVal) { - TypeCheckInfo checkInfo(checker, arg); - ConfigData data(defaultValue, checkInfo); - m_parameters[name] = data; // This overwrites any prior. + // Build the constraint object, and hook it into the autodelete mechanism. + + Limits* pLimit = new Limits; + pLimit->first.s_checkMe = true; + pLimit->first.s_value = low; + pLimit->second.s_checkMe = true; + pLimit->second.s_value = high; + + DynamicConstraint c = { + releaseLimitsConstraint, + reinterpret_cast<void*>(pLimit) + }; + m_constraints.push_back(c); + + // Add the parameter: + + addParameter(name, CConfigurableObject::isInteger, pLimit, itos(defaultVal)); + + } - /** + * Add a boolean parameter to the configuration. + * + * @param name - Name of the parameter e.g. -somebool + * @param defaultVal - Default value of the parameter + */ +void +CConfigurableObject::addBooleanParameter(std::string name, bool defaultVal) +{ + addParameter(name, CConfigurableObject::isBool, NULL, + std::string(defaultVal ? "true" : "false")); +} +/** * Convenience function to add an enumerated parameter. * @param name The name of the new parameter. * @param pValues Null terminated list of strings that are the valid values for the @@ -333,7 +457,7 @@ * @param defaultValue default value of the parameter. This parameter is optional and * defaults to first valid value * @note it is illegal; for pValues to contain an empty string but it's the responsibility of the - * caller to ensure this.k + * caller to ensure this. */ void CConfigurableObject::addEnumParameter(string name, @@ -345,60 +469,158 @@ while(*p) { pNewItem->insert(*p++); } - m_EnumCheckers.push_back(pNewItem); addParameter(name, isEnum, pNewItem, defaultValue == "" ? pValues[0] : defaultValue); + + // Arrange for the constraint to be freed on construction: + + DynamicConstraint cRelease = { + CConfigurableObject::releaseEnumConstraint, reinterpret_cast<void*>(pNewItem) + }; + m_constraints.push_back(cRelease); } -/*! - Configure the value of a parameter. - \param name : std::string - Name... [truncated message content] |