From 5851f2a63d814ae4abc4b14d0b39bd4787a8b664 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Thu, 17 Sep 2015 17:16:53 +0200 Subject: [PATCH 01/13] New scaler object --- include/VME_ScalerV8x0.h | 35 +++++++++++++++++++ src/VME_ScalerV8x0.cpp | 73 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 include/VME_ScalerV8x0.h create mode 100644 src/VME_ScalerV8x0.cpp diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h new file mode 100644 index 0000000..bb04a62 --- /dev/null +++ b/include/VME_ScalerV8x0.h @@ -0,0 +1,35 @@ +#ifndef VME_ScalerV8x0_h +#define VME_ScalerV8x0_h + +#include "VME_GenericBoard.h" + +namespace VME +{ + enum ScalerV8x0Register { + kV8x0ChannelEnable = 0x1100, + kV8x0Control = 0x1108, + kV8x0FWVersion = 0x1132, + kV8x0OUI = 0x402a, + kV8x0ModelVersion = 0x4032, + kV8x0HWRevision = 0x404e, + kV8x0SerialMSB = 0x4f02, + kV8x0SerialLSB = 0x4f06 + }; + class ScalerV8x0 : public GenericBoard + { + public: + ScalerV8x0(int32_t bhandle, uint32_t baseaddr); + inline ~ScalerV8x0() {;} + + unsigned int GetSerialNumber() const; + unsigned short GetModuleVersion() const; + unsigned short GetModuleType() const; + unsigned short GetManufacturerId() const; + //unsigned short GetIdentifier() const; + + private: + + }; +} + +#endif diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp new file mode 100644 index 0000000..cbb2e32 --- /dev/null +++ b/src/VME_ScalerV8x0.cpp @@ -0,0 +1,73 @@ +#include "VME_ScalerV8x0.h" + +namespace VME +{ + ScalerV8x0::ScalerV8x0(int32_t bhandle, uint32_t baseaddr) : + GenericBoard(bhandle, baseaddr) + { + std::ostringstream os; + os << "New Scaler module added:" << "\n\t" + //<< " Identifier: 0x" << std::hex << GetIdentifier() << "\n\t" + << " Serial number: " << std::dec << GetSerialNumber() << "\n\t" + << " Version: " << std::dec << GetModuleVersion() << "\n\t" + << " Type: " << std::dec << GetModuleType() << "\n\t" + << " Manufacturer: 0x" << std::hex << GetManufacturerId(); + PrintInfo(os.str()); + } + + unsigned int + ScalerV8x0::GetSerialNumber() const + { + uint16_t word1, word2; + try { + ReadRegister(kV8x0SerialMSB, &word1); + ReadRegister(kV8x0SerialLSB, &word2); + return static_cast(((word1&0xffff)<<16)+(word2&0xffff)); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + unsigned short + ScalerV8x0::GetModuleVersion() const + { + uint16_t word; + try { + ReadRegister(kV8x0HWRevision, &word); + return static_cast(word&0xffff); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + unsigned short + ScalerV8x0::GetModuleType() const + { + uint16_t word; + try { + ReadRegister(kV8x0ModelVersion, &word); + return static_cast(word&0xffff); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + unsigned short + ScalerV8x0::GetManufacturerId() const + { + uint16_t word; + try { + ReadRegister(kV8x0OUI, &word); + return static_cast(word&0xffff); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + /*unsigned short + ScalerV8x0::GetIdentifier() const + { + uint16_t word; + try { + ReadRegister(kIdentifier, &word); + return word; + } catch (Exception& e) { e.Dump(); } + return 0; + }*/ +} From a285d6fe9f635f05a54b2b1ff3ed393f5b8159ad Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Thu, 17 Sep 2015 17:23:10 +0200 Subject: [PATCH 02/13] Added POI and channel value extraction --- include/VME_ScalerV8x0.h | 5 +++++ src/VME_ScalerV8x0.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index bb04a62..fb99fd9 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -6,6 +6,7 @@ namespace VME { enum ScalerV8x0Register { + kV8x0ChannelValue = 0x1000, kV8x0ChannelEnable = 0x1100, kV8x0Control = 0x1108, kV8x0FWVersion = 0x1132, @@ -27,6 +28,10 @@ namespace VME unsigned short GetManufacturerId() const; //unsigned short GetIdentifier() const; + unsigned int GetChannelValue(unsigned short channel_id) const; + + void SetPOI(unsigned int poi) const; + unsigned int GetPOI() const; private: }; diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index cbb2e32..0dfe09e 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -70,4 +70,36 @@ namespace VME } catch (Exception& e) { e.Dump(); } return 0; }*/ + + unsigned int + ScalerV8x0::GetChannelValue(unsigned short channel_id) const + { + uint32_t word; + ScalerV8x0Register reg = static_cast(kV8x0ChannelValue+(channel_id*4)); + try { + ReadRegister(reg, &word); + return static_cast(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + void + ScalerV8x0::SetPOI(unsigned int poi) const + { + try { + WriteRegister(kV8x0ChannelEnable, poi); + } catch (Exception& e) { e.Dump(); } + } + + unsigned int + ScalerV8x0::GetPOI() const + { + uint32_t word; + try { + ReadRegister(kV8x0ChannelEnable, &word); + return static_cast(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + } From 8401dc277fcadc8b72b2d9ab0929701e5c94dc1e Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Thu, 17 Sep 2015 17:25:22 +0200 Subject: [PATCH 03/13] Added Control and Status skeletton --- include/VME_ScalerV8x0.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index fb99fd9..cc57cf1 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -16,6 +16,22 @@ namespace VME kV8x0SerialMSB = 0x4f02, kV8x0SerialLSB = 0x4f06 }; + class ScalerV8x0Control + { + public: + inline ScalerV8x0Control(unsigned int word): fWord(word) {;} + inline ~ScalerV8x0Control() {;} + private: + unsigned int fWord; + }; + class ScalerV8x0Status + { + public: + inline ScalerV8x0Status(unsigned int word): fWord(word) {;} + inline ~ScalerV8x0Status() {;} + private: + unsigned int fWord; + }; class ScalerV8x0 : public GenericBoard { public: From 31d9a7b43c1132a9d61599559ceb9417454f762a Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Thu, 17 Sep 2015 22:38:12 +0200 Subject: [PATCH 04/13] Added status register --- include/VME_ScalerV8x0.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index cc57cf1..359db34 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -29,6 +29,15 @@ namespace VME public: inline ScalerV8x0Status(unsigned int word): fWord(word) {;} inline ~ScalerV8x0Status() {;} + + inline bool DataReady() const { return fWord&0x1; } + inline bool AlmostFull() const { return (fWord>>1)&0x1; } + inline bool Full() const { return (fWord>>2)&0x1; } + inline bool GlobalDataReady() const { return (fWord>>3)&0x1; } + inline bool GlobalBusy() const { return (fWord>>4)&0x1; } + inline bool TermOn() const { return (fWord>>5)&0x1; } + inline bool TermOff() const { return (fWord>>6)&0x1; } + inline bool BusError() const { return (fWord>>7)&0x1; } private: unsigned int fWord; }; @@ -48,6 +57,10 @@ namespace VME void SetPOI(unsigned int poi) const; unsigned int GetPOI() const; + + ScalerV8x0Status GetStatus() const; + ScalerV8x0Control GetControl() const; + void SetControl(const ScalerV8x0Control& control) const; private: }; From 19718520d05e599201bbf1d1bb5c24127764b570 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 09:45:38 +0200 Subject: [PATCH 05/13] Finished filling the control and status word parsing/building, and their propagation to/from the board --- include/VME_ScalerV8x0.h | 41 ++++++++++++++++++++++++++++++++++++---- src/VME_ScalerV8x0.cpp | 29 ++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index 359db34..eda00dd 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -9,6 +9,7 @@ namespace VME kV8x0ChannelValue = 0x1000, kV8x0ChannelEnable = 0x1100, kV8x0Control = 0x1108, + kV8x0Status = 0x110e, kV8x0FWVersion = 0x1132, kV8x0OUI = 0x402a, kV8x0ModelVersion = 0x4032, @@ -19,15 +20,46 @@ namespace VME class ScalerV8x0Control { public: - inline ScalerV8x0Control(unsigned int word): fWord(word) {;} + inline ScalerV8x0Control(unsigned short word): fWord(word) {;} inline ~ScalerV8x0Control() {;} + + inline unsigned short GetWord() const { return fWord; } + + enum AcquisitionMode { TriggerDisabled=0x0, TriggerRandom=0x1, PeriodicalTrigger=0x2 }; + inline void SetAcquisitionMode(const AcquisitionMode& mode) { SetBit(0, mode&0x1); SetBit(1, (mode>>1)&0x1); } + inline AcquisitionMode GetAcquisitionMode() const { + unsigned short word1 = GetBit(0), word2 = GetBit(1); + return static_cast(word1+(word2<<1)); + } + + enum DataFormat { DF32bit=0x0, DF26bit=0x1 }; + inline void SetDataFormat(const DataFormat& fmt) { SetBit(2, fmt); } + inline DataFormat GetDataFormat() const { return static_cast(GetBit(2)); } + + inline void SetBusError(bool enable) { SetBit(4, enable); } + inline bool GetBusError() const { return GetBit(4); } + + inline void SetHeader(bool enable) { SetBit(5, enable); } + inline bool GetHeader() const { return GetBit(5); } + + inline void SetClearMEB(bool enable) { SetBit(6, enable); } + inline bool GetClearMEB() const { return GetBit(6); } + + inline void SetAutoReset(bool enable) { SetBit(7, enable); } + inline bool GetAutoReset() const { return GetBit(7); } + private: - unsigned int fWord; + inline bool GetBit(unsigned short id) const { return static_cast((fWord>>id)&0x1); } + inline void SetBit(unsigned short id, unsigned short value=0x1) { + if (value==GetBit(id)) return; + unsigned short sign = (value==0x0) ? -1 : 1; fWord += sign*(0x1<>6)&0x1; } inline bool BusError() const { return (fWord>>7)&0x1; } private: - unsigned int fWord; + unsigned short fWord; }; class ScalerV8x0 : public GenericBoard { @@ -61,6 +93,7 @@ namespace VME ScalerV8x0Status GetStatus() const; ScalerV8x0Control GetControl() const; void SetControl(const ScalerV8x0Control& control) const; + private: }; diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index 0dfe09e..bb72a8e 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -101,5 +101,34 @@ namespace VME } catch (Exception& e) { e.Dump(); } return 0; } + + ScalerV8x0Status + ScalerV8x0::GetStatus() const + { + uint16_t word; + try { + ReadRegister(kV8x0Status, &word); + return ScalerV8x0Status(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + ScalerV8x0Control + ScalerV8x0::GetControl() const + { + uint16_t word; + try { + ReadRegister(kV8x0Control, &word); + return ScalerV8x0Control(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + void + ScalerV8x0::SetControl(const ScalerV8x0Control& control) const + { + try { + WriteRegister(kV8x0Control, control.GetWord()); + } catch (Exception& e) { e.Dump(); } + } } From 40c4d4956aca4055aab6376604d2ca0627e9009c Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 09:54:42 +0200 Subject: [PATCH 06/13] Added the trigger counter --- include/VME_ScalerV8x0.h | 23 +++++++++++++---------- src/VME_ScalerV8x0.cpp | 11 +++++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index eda00dd..accaadd 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -6,16 +6,17 @@ namespace VME { enum ScalerV8x0Register { - kV8x0ChannelValue = 0x1000, - kV8x0ChannelEnable = 0x1100, - kV8x0Control = 0x1108, - kV8x0Status = 0x110e, - kV8x0FWVersion = 0x1132, - kV8x0OUI = 0x402a, - kV8x0ModelVersion = 0x4032, - kV8x0HWRevision = 0x404e, - kV8x0SerialMSB = 0x4f02, - kV8x0SerialLSB = 0x4f06 + kV8x0ChannelValue = 0x1000, + kV8x0ChannelEnable = 0x1100, + kV8x0Control = 0x1108, + kV8x0Status = 0x110e, + kV8x0TriggerCounter = 0x1128, + kV8x0FWVersion = 0x1132, + kV8x0OUI = 0x402a, + kV8x0ModelVersion = 0x4032, + kV8x0HWRevision = 0x404e, + kV8x0SerialMSB = 0x4f02, + kV8x0SerialLSB = 0x4f06 }; class ScalerV8x0Control { @@ -90,6 +91,8 @@ namespace VME void SetPOI(unsigned int poi) const; unsigned int GetPOI() const; + unsigned int GetTriggerCounter() const; + ScalerV8x0Status GetStatus() const; ScalerV8x0Control GetControl() const; void SetControl(const ScalerV8x0Control& control) const; diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index bb72a8e..ac99017 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -102,6 +102,17 @@ namespace VME return 0; } + unsigned int + ScalerV8x0::GetTriggerCounter() const + { + uint32_t word; + try { + ReadRegister(kV8x0TriggerCounter, &word); + return static_cast(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + ScalerV8x0Status ScalerV8x0::GetStatus() const { From 6dd3aff3a76d4885540329d9c925fdff181b348b Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 10:24:31 +0200 Subject: [PATCH 07/13] Added the parser to a scaler event/header --- include/VME_ScalerV8x0.h | 84 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index accaadd..250a6e5 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -1,10 +1,71 @@ #ifndef VME_ScalerV8x0_h #define VME_ScalerV8x0_h +#include #include "VME_GenericBoard.h" namespace VME { + /** + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ + enum ScalerV8x0DataFormat { DF32bit=0x0, DF26bit=0x1 }; + enum ScalerV8x0TriggerSource { TSExternalTrigger=0x0, TSTimerTrigger=0x1, TSVMETrigger=0x2 }; + + /** + * \brief Parser for a scaler event/header + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ + class ScalerEvent + { + public: + inline ScalerEvent(unsigned int word) : fWord(word) {;} + inline ~ScalerEvent() {;} + + inline unsigned int GetWord() const { return fWord; } + + inline unsigned short GetGeo() const { return ((fWord>>27)&0x1f); } + inline bool IsHeader(unsigned short geo=0) const { + bool header_bit = (fWord>>26)&0x1; + if (geo>0) return (header_bit and GetGeo()==geo); + return header_bit; + } + + inline unsigned short GetTriggerNumber(unsigned short geo=0) const { + if (!IsHeader(geo)) throw Exception(__PRETTY_FUNCTION__, "Trying to extract the trigger number from a non-header ScalerEvent word", JustWarning); + return (fWord&0xffff); + } + inline ScalerV8x0TriggerSource GetTriggerSource(unsigned short geo=0) const { + if (!IsHeader(geo)) throw Exception(__PRETTY_FUNCTION__, "Trying to extract the trigger source from a non-header ScalerEvent word", JustWarning); + return static_cast((fWord>>16)&0x3); + } + inline unsigned short GetNumChannels(unsigned short geo=0) const { + if (!IsHeader(geo)) throw Exception(__PRETTY_FUNCTION__, "Trying to extract the number of enabled channels from a non-header ScalerEvent word", JustWarning); + return ((fWord>>18)&0x3f); + } + + inline unsigned short GetChannelId() const { return ((fWord>>27)&0x1f); } + inline unsigned int GetChannelCounter(const ScalerV8x0DataFormat& df) const { + switch (df) { + case DF32bit: return fWord; + case DF26bit: return (fWord&0x3ffffff); + } + } + + private: + unsigned int fWord; + }; + + /// A collection of ScalerEvent objects + typedef std::vector ScalerEventCollection; + + /** + * \brief List of registers to handle a CAEN V8x0 scaler module + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ enum ScalerV8x0Register { kV8x0ChannelValue = 0x1000, kV8x0ChannelEnable = 0x1100, @@ -18,6 +79,11 @@ namespace VME kV8x0SerialMSB = 0x4f02, kV8x0SerialLSB = 0x4f06 }; + + /** + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ class ScalerV8x0Control { public: @@ -33,9 +99,8 @@ namespace VME return static_cast(word1+(word2<<1)); } - enum DataFormat { DF32bit=0x0, DF26bit=0x1 }; - inline void SetDataFormat(const DataFormat& fmt) { SetBit(2, fmt); } - inline DataFormat GetDataFormat() const { return static_cast(GetBit(2)); } + inline void SetDataFormat(const ScalerV8x0DataFormat& fmt) { SetBit(2, fmt); } + inline ScalerV8x0DataFormat GetDataFormat() const { return static_cast(GetBit(2)); } inline void SetBusError(bool enable) { SetBit(4, enable); } inline bool GetBusError() const { return GetBit(4); } @@ -57,6 +122,11 @@ namespace VME } unsigned short fWord; }; + + /** + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ class ScalerV8x0Status { public: @@ -74,6 +144,12 @@ namespace VME private: unsigned short fWord; }; + + /** + * \brief Handler object for a CAEN V8x0 scaler module + * \date 17 Sep 2015 + * \author Laurent Forthomme + */ class ScalerV8x0 : public GenericBoard { public: @@ -93,6 +169,8 @@ namespace VME unsigned int GetTriggerCounter() const; + ScalerEventCollection FetchEvents(); + ScalerV8x0Status GetStatus() const; ScalerV8x0Control GetControl() const; void SetControl(const ScalerV8x0Control& control) const; From 91db6f4ab57bd0b4f2f989f225c155dee6602abe Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 10:28:16 +0200 Subject: [PATCH 08/13] Enabled to retrieve the GEO address from board --- include/VME_ScalerV8x0.h | 6 ++++-- src/VME_ScalerV8x0.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index 250a6e5..ced1c03 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -26,10 +26,10 @@ namespace VME inline unsigned int GetWord() const { return fWord; } - inline unsigned short GetGeo() const { return ((fWord>>27)&0x1f); } + inline unsigned short GetGEO() const { return ((fWord>>27)&0x1f); } inline bool IsHeader(unsigned short geo=0) const { bool header_bit = (fWord>>26)&0x1; - if (geo>0) return (header_bit and GetGeo()==geo); + if (geo>0) return (header_bit and GetGEO()==geo); return header_bit; } @@ -71,6 +71,7 @@ namespace VME kV8x0ChannelEnable = 0x1100, kV8x0Control = 0x1108, kV8x0Status = 0x110e, + kV8x0GEO = 0x1110, kV8x0TriggerCounter = 0x1128, kV8x0FWVersion = 0x1132, kV8x0OUI = 0x402a, @@ -161,6 +162,7 @@ namespace VME unsigned short GetModuleType() const; unsigned short GetManufacturerId() const; //unsigned short GetIdentifier() const; + unsigned short GetGEO() const; unsigned int GetChannelValue(unsigned short channel_id) const; diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index ac99017..f822846 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -71,6 +71,17 @@ namespace VME return 0; }*/ + unsigned short + ScalerV8x0::GetGEO() const + { + uint16_t word; + try { + ReadRegister(kV8x0GEO, &word); + return static_cast(word&0x1f); + } catch (Exception& e) { e.Dump(); } + return 0; + } + unsigned int ScalerV8x0::GetChannelValue(unsigned short channel_id) const { From cd2efd2ec3a9f5104e86b298d8ec1b73b9280ab7 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 10:43:05 +0200 Subject: [PATCH 09/13] Added the block transfer capability --- include/VME_ScalerV8x0.h | 15 ++++++--- src/VME_ScalerV8x0.cpp | 72 +++++++++++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index ced1c03..cae1213 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -2,8 +2,12 @@ #define VME_ScalerV8x0_h #include +#include + #include "VME_GenericBoard.h" +#define TDC_ACQ_STOP 20001 + namespace VME { /** @@ -67,6 +71,7 @@ namespace VME * \author Laurent Forthomme */ enum ScalerV8x0Register { + kV8x0OutputBuffer = 0x0000, kV8x0ChannelValue = 0x1000, kV8x0ChannelEnable = 0x1100, kV8x0Control = 0x1108, @@ -155,7 +160,7 @@ namespace VME { public: ScalerV8x0(int32_t bhandle, uint32_t baseaddr); - inline ~ScalerV8x0() {;} + ~ScalerV8x0(); unsigned int GetSerialNumber() const; unsigned short GetModuleVersion() const; @@ -163,22 +168,24 @@ namespace VME unsigned short GetManufacturerId() const; //unsigned short GetIdentifier() const; unsigned short GetGEO() const; - - unsigned int GetChannelValue(unsigned short channel_id) const; void SetPOI(unsigned int poi) const; unsigned int GetPOI() const; unsigned int GetTriggerCounter() const; + unsigned int GetChannelValue(unsigned short channel_id) const; ScalerEventCollection FetchEvents(); ScalerV8x0Status GetStatus() const; ScalerV8x0Control GetControl() const; void SetControl(const ScalerV8x0Control& control) const; + + void abort(); private: - + unsigned int* fBuffer; + bool gEnd; }; } diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index f822846..ee39c28 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -13,6 +13,17 @@ namespace VME << " Type: " << std::dec << GetModuleType() << "\n\t" << " Manufacturer: 0x" << std::hex << GetManufacturerId(); PrintInfo(os.str()); + fBuffer = (unsigned int*)malloc(32*1024*1024); // 32MB of buffer! + if (fBuffer==NULL) { + throw Exception(__PRETTY_FUNCTION__, "Output buffer has not been allocated!", Fatal); + } + gEnd = false; + } + + ScalerV8x0::~ScalerV8x0() + { + free(fBuffer); + fBuffer = NULL; } unsigned int @@ -82,18 +93,6 @@ namespace VME return 0; } - unsigned int - ScalerV8x0::GetChannelValue(unsigned short channel_id) const - { - uint32_t word; - ScalerV8x0Register reg = static_cast(kV8x0ChannelValue+(channel_id*4)); - try { - ReadRegister(reg, &word); - return static_cast(word); - } catch (Exception& e) { e.Dump(); } - return 0; - } - void ScalerV8x0::SetPOI(unsigned int poi) const { @@ -124,6 +123,47 @@ namespace VME return 0; } + unsigned int + ScalerV8x0::GetChannelValue(unsigned short channel_id) const + { + if (channel_id<0 or channel_id>31) { + std::ostringstream os; os << "Trying to extract the value of a channel outside allowed range: " << channel_id; + throw Exception(__PRETTY_FUNCTION__, os.str(), JustWarning); + } + uint32_t word; + ScalerV8x0Register reg = static_cast(kV8x0ChannelValue+(channel_id*4)); + try { + ReadRegister(reg, &word); + return static_cast(word); + } catch (Exception& e) { e.Dump(); } + return 0; + } + + ScalerEventCollection + ScalerV8x0::FetchEvents() + { + if (gEnd) + throw Exception(__PRETTY_FUNCTION__, "Abort state detected... quitting", JustWarning, TDC_ACQ_STOP); + ScalerEventCollection ec; ec.clear(); + + memset(fBuffer, 0, sizeof(unsigned int)); + + int count = 0; + const int blts = 4096; // size of the transfer in bytes + bool finished; + std::ostringstream o; + + // Start Readout (check if BERR is set to 0) + CVErrorCodes ret = CAENVME_BLTReadCycle(fHandle, fBaseAddr+kV8x0OutputBuffer, (char*)fBuffer, blts, cvA32_U_BLT, cvD32, &count); + finished = ((ret==cvSuccess)||(ret==cvBusError)||(ret==cvCommError)); //FIXME investigate... + if (finished && gEnd) { + throw Exception(__PRETTY_FUNCTION__, "Abort state detected... quitting", JustWarning, TDC_ACQ_STOP); + } + for (int i=0; i Date: Fri, 18 Sep 2015 10:43:58 +0200 Subject: [PATCH 10/13] Switching from A24 to A32 --- include/VME_ScalerV8x0.h | 2 +- src/VME_ScalerV8x0.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index cae1213..2040b1d 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -156,7 +156,7 @@ namespace VME * \date 17 Sep 2015 * \author Laurent Forthomme */ - class ScalerV8x0 : public GenericBoard + class ScalerV8x0 : public GenericBoard { public: ScalerV8x0(int32_t bhandle, uint32_t baseaddr); diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index ee39c28..4ed25cb 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -3,7 +3,7 @@ namespace VME { ScalerV8x0::ScalerV8x0(int32_t bhandle, uint32_t baseaddr) : - GenericBoard(bhandle, baseaddr) + GenericBoard(bhandle, baseaddr) { std::ostringstream os; os << "New Scaler module added:" << "\n\t" From 4f3fafb847b0acca1c86b9ba4b9e5b2b1f113219 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 10:51:43 +0200 Subject: [PATCH 11/13] The VMEReader object can now add scalers to its controlling capabilities --- include/VMEReader.h | 22 +++++++++++++++++++++- include/VME_ScalerV8x0.h | 3 +++ src/VMEReader.cpp | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/VMEReader.h b/include/VMEReader.h index b70e412..9bda654 100644 --- a/include/VMEReader.h +++ b/include/VMEReader.h @@ -10,6 +10,7 @@ #include "VME_CFDV812.h" #include "VME_CAENETControllerV288.h" #include "VME_TDCV1x90.h" +#include "VME_ScalerV8x0.h" #include "NIM_HVModuleN470.h" @@ -58,6 +59,23 @@ class VMEReader : public Client inline size_t GetNumTDC() const { return fTDCCollection.size(); } inline VME::TDCCollection GetTDCCollection() { return fTDCCollection; } + /** + * \brief Add a scaler to handle + * \param[in] address 32-bit address of the scaler module on the VME bus + * Create a new scaler handler for the VME bus + */ + void AddScaler(uint32_t address); + /** + * \brief Get a scaler on the VME bus + * Return a pointer to the scaler object, given its physical address on the VME bus + */ + inline VME::ScalerV8x0* GetScaler(uint32_t address) { + if (fScalerCollection.count(address)==0) return 0; + return fScalerCollection[address]; + } + inline size_t GetNumScaler() const { return fScalerCollection.size(); } + inline VME::ScalerCollection GetScalerCollection() { return fScalerCollection; } + void AddIOModule(uint32_t address); inline VME::IOModuleV262* GetIOModule() { return fSG; } @@ -166,8 +184,10 @@ class VMEReader : public Client VME::CFDCollection fCFDCollection; /// Pointer to the VME input/output module object VME::IOModuleV262* fSG; - /// Pointer to the VME general purpose FPGA unit object + /// A set of pointers to VME general purpose FPGA unit objects indexed by their physical VME address VME::FPGAUnitCollection fFPGACollection; + /// A set of pointers to scaler objects indexed by their physical VME address + VME::ScalerCollection fScalerCollection; /// Pointer to the VME CAENET controller VME::CAENETControllerV288* fCAENET; /// Pointer to the NIM high voltage module (passing through the CAENET controller) diff --git a/include/VME_ScalerV8x0.h b/include/VME_ScalerV8x0.h index 2040b1d..e9c9658 100644 --- a/include/VME_ScalerV8x0.h +++ b/include/VME_ScalerV8x0.h @@ -2,6 +2,7 @@ #define VME_ScalerV8x0_h #include +#include #include #include "VME_GenericBoard.h" @@ -187,6 +188,8 @@ namespace VME unsigned int* fBuffer; bool gEnd; }; + + typedef std::map ScalerCollection; } #endif diff --git a/src/VMEReader.cpp b/src/VMEReader.cpp index cbd3f16..a70e18e 100644 --- a/src/VMEReader.cpp +++ b/src/VMEReader.cpp @@ -232,6 +232,24 @@ VMEReader::AddTDC(uint32_t address) throw Exception(__PRETTY_FUNCTION__, os.str(), Info, TDC_ACQ_START); } +void +VMEReader::AddScaler(uint32_t address) +{ + if (!fBridge) throw Exception(__PRETTY_FUNCTION__, "No bridge detected! Aborting...", Fatal); + try { + fScalerCollection.insert(std::pair( + address, + new VME::ScalerV8x0(fBridge->GetHandle(), address) + )); + } catch (Exception& e) { + e.Dump(); + if (fOnSocket) Client::Send(e); + } + std::ostringstream os; + os << "Scaler with base address 0x" << std::hex << address << " successfully built"; + throw Exception(__PRETTY_FUNCTION__, os.str(), Info, TDC_ACQ_START); +} + void VMEReader::AddCFD(uint32_t address) { From c19751ccf4f7506600edd8c43d826a02ed70d061 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 11:09:55 +0200 Subject: [PATCH 12/13] Added the xml config parsing part in VMEReader to handle scaler objects --- src/VMEReader.cpp | 21 +++++++++++++++++++++ src/VME_ScalerV8x0.cpp | 15 +++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/VMEReader.cpp b/src/VMEReader.cpp index a70e18e..26bf833 100644 --- a/src/VMEReader.cpp +++ b/src/VMEReader.cpp @@ -188,6 +188,27 @@ VMEReader::ReadXML(const char* filename) } catch (Exception& e) { throw e; } } } + for (tinyxml2::XMLElement* asca=doc.FirstChildElement("scaler"); asca!=NULL; asca=asca->NextSiblingElement("scaler")) { + if (const char* address=asca->Attribute("address")) { + unsigned long addr = static_cast(strtol(address, NULL, 0)); + if (!addr) throw Exception(__PRETTY_FUNCTION__, "Failed to parse scaler's base address", Fatal); + try { + try { AddScaler(addr); } catch (Exception& e) { if (fOnSocket) Client::Send(e); } + VME::ScalerV8x0* sca = GetScaler(addr); + VME::ScalerV8x0Control control = sca->GetControl(); + if (const char* hdr=asca->Attribute("header")) { + if (!strcmp(hdr, "true") or !strcmp(hdr, "True") or !strcmp(hdr, "1")) control.SetHeader(true); + if (!strcmp(hdr, "false") or !strcmp(hdr, "False") or !strcmp(hdr, "0")) control.SetHeader(false); + } + if (tinyxml2::XMLElement* poi=asca->FirstChildElement("poi")) { sca->SetPOI(atoi(poi->GetText())); } + if (tinyxml2::XMLElement* df=asca->FirstChildElement("data_format")) { + if (!strcmp(df->GetText(), "26bit")) control.SetDataFormat(VME::DF26bit); + if (!strcmp(df->GetText(), "32bit")) control.SetDataFormat(VME::DF32bit); + } + sca->SetControl(control); + } catch (Exception& e) { throw e; } + } + } std::cout << "Global acquisition mode: " << fGlobalAcqMode << std::endl; unsigned int run = GetRunNumber(); std::ifstream source(filename, std::ios::binary); diff --git a/src/VME_ScalerV8x0.cpp b/src/VME_ScalerV8x0.cpp index 4ed25cb..9946bd9 100644 --- a/src/VME_ScalerV8x0.cpp +++ b/src/VME_ScalerV8x0.cpp @@ -3,7 +3,7 @@ namespace VME { ScalerV8x0::ScalerV8x0(int32_t bhandle, uint32_t baseaddr) : - GenericBoard(bhandle, baseaddr) + GenericBoard(bhandle, baseaddr), gEnd(false) { std::ostringstream os; os << "New Scaler module added:" << "\n\t" @@ -17,7 +17,18 @@ namespace VME if (fBuffer==NULL) { throw Exception(__PRETTY_FUNCTION__, "Output buffer has not been allocated!", Fatal); } - gEnd = false; + + // Default values + SetPOI(0xffffffff); + + ScalerV8x0Control control = GetControl(); + control.SetDataFormat(DF26bit); + control.SetAcquisitionMode(ScalerV8x0Control::TriggerDisabled); + control.SetBusError(false); + control.SetHeader(true); + control.SetClearMEB(false); + control.SetAutoReset(false); + SetControl(control); } ScalerV8x0::~ScalerV8x0() From 1548038c6bcd4be3a28b5488ee47869bd4e8cad5 Mon Sep 17 00:00:00 2001 From: Laurent Forthomme Date: Fri, 18 Sep 2015 11:13:46 +0200 Subject: [PATCH 13/13] Added an example configuration with only one scaler attached --- config/config_scaler.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 config/config_scaler.xml diff --git a/config/config_scaler.xml b/config/config_scaler.xml new file mode 100644 index 0000000..b02568b --- /dev/null +++ b/config/config_scaler.xml @@ -0,0 +1,5 @@ + + + 4294967295 + 26bit +