From: <ro...@us...> - 2010-08-12 10:40:21
|
Revision: 2375 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2375&view=rev Author: ron-fox Date: 2010-08-12 10:40:15 +0000 (Thu, 12 Aug 2010) Log Message: ----------- - Bump minor version number. - Add -multievent, -irqthreshold, -resolution parameters to CMADC32 class. - Fixed some interesting error in C785... missed a GetIntegerParameter that needed an m_pConfiguration-> in front of it... Modified Paths: -------------- trunk/llnlReadout/configure.in trunk/llnlReadout/devices/C785.cpp trunk/llnlReadout/devices/CMADC32.cpp trunk/llnlReadout/devices/CMADC32.h Modified: trunk/llnlReadout/configure.in =================================================================== --- trunk/llnlReadout/configure.in 2010-08-12 09:31:46 UTC (rev 2374) +++ trunk/llnlReadout/configure.in 2010-08-12 10:40:15 UTC (rev 2375) @@ -8,7 +8,7 @@ # Separate device libraries. -AM_INIT_AUTOMAKE(llnlReadout, 3.3, fo...@ns...) +AM_INIT_AUTOMAKE(llnlReadout, 3.4, fo...@ns...) # # The variable below should track the Modified: trunk/llnlReadout/devices/C785.cpp =================================================================== --- trunk/llnlReadout/devices/C785.cpp 2010-08-12 09:31:46 UTC (rev 2374) +++ trunk/llnlReadout/devices/C785.cpp 2010-08-12 10:40:15 UTC (rev 2375) @@ -490,7 +490,7 @@ void C785::addReadoutList(CVMUSBReadoutList& list) { - uint32_t base = getUnsignedParameter("-base"); + uint32_t base = m_pConfiguration->getUnsignedParameter("-base"); // only read 1 event. // for (int i =0; i < EventsPerRead; i++) { Modified: trunk/llnlReadout/devices/CMADC32.cpp =================================================================== --- trunk/llnlReadout/devices/CMADC32.cpp 2010-08-12 09:31:46 UTC (rev 2374) +++ trunk/llnlReadout/devices/CMADC32.cpp 2010-08-12 10:40:15 UTC (rev 2375) @@ -60,10 +60,20 @@ Const(Ipl) 0x6010; Const(Vector) 0x6012; +Const(IrqReset) 0x6016; +Const(IrqThreshold) 0x6018; +Const(MaxTransfer) 0x601a; +Const(WithdrawIrqOnEmpty) 0x601c; +Const(CbltMcstControl) 0x6020; +Const(CbltAddress) 0x6022; +Const(McstAddress) 0x6024; + + Const(LongCount) 0x6030; Const(DataFormat) 0x6032; Const(ReadoutReset) 0x6034; +Const(MultiEvent) 0x6036; Const(MarkType) 0x6038; Const(StartAcq) 0x603A; Const(InitFifo) 0x603c; @@ -93,6 +103,17 @@ Const(TestPulser) 0x6070; // In order to ensure it's off ! +// Mcast/CBLT control register bits: + +Const(MCSTENB) 0x80; +Const(MCSTDIS) 0x40; +Const(FIRSTENB) 0x20; +Const(FIRSTDIS) 0x10; +Const(LASTENB) 0x08; +Const(LASTDIS) 0x04; +Const(CBLTENB) 0x02; +Const(CBLTDIS) 0x01; + ///////////////////////////////////////////////////////////////////////////////// // Data that drives parameter validity checks. @@ -138,30 +159,48 @@ static CConfigurableObject::isListParameter HoldValidity(Zero, Byte, HoldValueOk); +// Limits on irqthreshold: +static CConfigurableObject::limit irqThresholdMax(956); // that's what the manual says +static CConfigurableObject::Limits irqThresholdLimits(Zero, irqThresholdMax); + + + + // 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*); +static const char* GateModeValues[2] = {"common", "separate"}; +static 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*); +static const char* InputRangeValues[3] = {"4v", "8v", "10v"}; +static 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*); +static const char* TimingSourceValues[2] = {"vme", "external"}; +static const int TimingSourceNumValues = sizeof(TimingSourceValues)/sizeof(char*); // Legal values for the timing divisor (0-15) static CConfigurableObject::limit divisorLimit(0xffff); static CConfigurableObject::Limits DivisorLimits(Zero, divisorLimit); +// Legal values for the resolution...note in this case the default is explicitly defined as 8k + +static const char* resolutions[5] = { + "2k", + "4k", + "4khires", + "8k", + "8khires" +}; +static const int resolutionsNumValues = sizeof(resolutions)/sizeof(char*); + //////////////////////////////////////////////////////////////////////////////// // Constructors and implemented canonical operations: @@ -276,6 +315,21 @@ m_pConfiguration->addParameter("-pulser", CConfigurableObject::isBool, NULL, "false"); + + // Parameters to support multi-event/irq mode + + m_pConfiguration->addParameter("-multievent", CConfigurableObject::isBool, + NULL, "false"); + m_pConfiguration->addParameter("-irqthreshold", CConfigurableObject::isInteger, + &irqThresholdLimits, "0"); + + static CConfigurableObject::isEnumParameter validResolution; + for(int i = 0; i < resolutionsNumValues; i++) { + validResolution.insert(resolutions[i]); + } + m_pConfiguration->addParameter("-resolution", CConfigurableObject::isEnum, + &validResolution, "8k"); + } /*! Initialize the module prior to data taking. We will get the initialization @@ -328,6 +382,9 @@ int timedivisor = m_pConfiguration->getIntegerParameter("-timingdivisor"); vector<int> thresholds = m_pConfiguration->getIntegerList("-thresholds"); bool pulser = m_pConfiguration->getBoolParameter("-pulser"); + bool multiEvent = m_pConfiguration->getBoolParameter("-multievent"); + string resolution = m_pConfiguration->cget("-resolution"); + int irqThreshold= m_pConfiguration->getIntegerParameter("-irqthreshold"); // Write the thresholds. @@ -455,6 +512,18 @@ list.addWrite16(base + NIMBusyFunction, initamod, 0); list.addDelay(MADCDELAY); + // Process -resolution, -irqthreshold and -multievent + + list.addWrite16(base + Resolution, initamod, resolutionValue(resolution)); + list.addWrite16(base + IrqThreshold, initamod, irqThreshold); + list.addWrite16(base + WithdrawIrqOnEmpty, initamod, 1); + if(multiEvent) { + list.addWrite16(base + MultiEvent, initamod, 3); + } + else { + list.addWrite16(base + MultiEvent, initamod, 0); + } + // 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. @@ -475,6 +544,7 @@ + // Execute the list to initialize the module: @@ -513,3 +583,71 @@ { return new CMADC32(*this); } +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Code here provides support for the madcchain pseudo module that use these devices +// in CBLT mode. +// + +/*! + Set up the chain/mcast addresses. + @param controller - Handle to VM_USB controller object. + @param position - A value from the position enumerator CMADC32::ChainPosition + @param cbltBase - Base address for CBLT transfers. + @param mcastBase - Base address for multicast transfers. + + Note that both mcast and cblt are enabled for now. +*/ +void +CMADC32::setChainAddresses(CVMUSB& controller, + CMADC32::ChainPosition position, + uint32_t cbltBase, + uint32_t mcastBase) +{ + + uint32_t base = m_pConfiguration->getIntegerParameter("-base"); + + // Compute the value of the control register..though we will first program + // the addresses then the control register: + + uint16_t controlRegister = MCSTENB | CBLTENB; // This much is invariant. + switch (position) { + first: + controlRegister |= FIRSTENB | LASTDIS; + break; + middle: + controlRegister |= FIRSTDIS | LASTDIS; + break; + last: + controlRegister |= FIRSTDIS | LASTENB; + } + + // program the registers, note that the address registers take only the top 8 bits. + + controller.vmeWrite16(base + CbltAddress, initamod, cbltBase >> 24); + controller.vmeWrite16(base + McstAddress, initamod, mcastBase >> 24); + controller.vmeWrite16(base + CbltMcstControl, initamod, controlRegister); + +} +/////////////////////////////////////////////////////////////////////////////////////////////// +// +// Private utilities: +// + +/* +** convert the resolution string into a register value. +*/ +int +CMADC32::resolutionValue(string selector) +{ + for (int i =0; i < resolutionsNumValues; i++) { + if (selector == resolutions[i]) { + return i; + } + } + // enum checking should prevent this so: + + string msg = "Invalid value for resolution parameter: "; + msg += selector; + throw msg; +} Modified: trunk/llnlReadout/devices/CMADC32.h =================================================================== --- trunk/llnlReadout/devices/CMADC32.h 2010-08-12 09:31:46 UTC (rev 2374) +++ trunk/llnlReadout/devices/CMADC32.h 2010-08-12 10:40:15 UTC (rev 2375) @@ -77,10 +77,21 @@ -timingsource enum (vme,external) Determines where timestamp source is. -timingdivisor int [0-15] Divisor (2^n) of timestamp clock -thresholds int[32] [0-4095] Threshold settings (0 means unused). + -multievent bool (false) Enable/disablen multi-event mode. + -irqthreshold integer 0 # Events before interrupt. + -resolution enum (8k) 2k 4k 4khires 8k 8khires .. + possible ADC resolution values. + \endverbatim */ class CMADC32 : public CReadoutHardware { +public: + enum ChainPosition { + first, + middle, + last + }; private: CReadoutModule* m_pConfiguration; public: @@ -100,7 +111,17 @@ virtual void addReadoutList(CVMUSBReadoutList& list); virtual CReadoutHardware* clone() const; + // The following functions are used by the madcchain module. + // + void setChainAddresses(CVMUSB& controller, + ChainPosition position, + uint32_t cbltBase, + uint32_t mcastBase); + + // Utilities: + + int resolutionValue(std::string selector); // Resolution string to register value. }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |