diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml old mode 100644 new mode 100755 diff --git a/CHANGELOG b/CHANGELOG old mode 100755 new mode 100644 diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 84014073fdc4a51d5f5e3dbce1a4462ba37fcca4..30f9be1defa8d6d718750659e85f19f66fad7b9c --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,17 @@ endif(uhal_boost) find_package(Boost 1.53 REQUIRED system filesystem thread program_options) #find_package(Boost 1.53 REQUIRED filesystem system-mt ) +# builds eudaq producer +if(DEFINED ENV{EUDAQ}) + SET(USE_EUDAQ ON) + INCLUDE_DIRECTORIES($ENV{EUDAQ}/main/include) + set(EUDAQ_LIB -L$ENV{EUDAQ}/lib EUDAQ) + message(STATUS "Using EUDAQ from $ENV{EUDAQ}") +else() + message(STATUS "EUDAQ variable is not defined. Building without EUDAQ producer") +endif() + + message("#### Done ####") #all the subdirs diff --git a/HWDescription/BeBoard.cc b/HWDescription/BeBoard.cc index 3997bd48d7f3f799b62d63ddcb20dc8f023c68c3..850c800543e71ed52ad5bd13eb22e7b4bd428e60 100644 --- a/HWDescription/BeBoard.cc +++ b/HWDescription/BeBoard.cc @@ -22,6 +22,7 @@ namespace Ph2_HwDescription { BeBoard::BeBoard() : fBeId ( 0 ), fEventType (EventType::VR), + fChipType (ChipType::CBC3), fCondDataSet (nullptr) {} @@ -124,7 +125,7 @@ namespace Ph2_HwDescription { if (cCondItem.fCbcId != cCbc->getCbcId() ) continue; else if (cCbc->getFeId() == cCondItem.fFeId && cCbc->getCbcId() == cCondItem.fCbcId) { - CbcRegItem cRegItem = cCbc->getRegItem ( cCondItem.fRegName ); + RegItem cRegItem = cCbc->getRegItem ( cCondItem.fRegName ); cCondItem.fValue = cRegItem.fValue; } } diff --git a/HWDescription/BeBoard.h b/HWDescription/BeBoard.h index 353f3f0cb3cbff177d5adb01bbae024c9ab24d8b..52b811d23937e373050511a1f994917f2f97c90c 100644 --- a/HWDescription/BeBoard.h +++ b/HWDescription/BeBoard.h @@ -202,6 +202,15 @@ namespace Ph2_HwDescription { return fEventType; } + void setChipType (const ChipType pChipType) + { + fChipType = pChipType; + } + ChipType getChipType() const + { + return fChipType; + } + void addConditionDataSet (ConditionDataSet* pSet) { if (pSet != nullptr) @@ -222,6 +231,7 @@ namespace Ph2_HwDescription { //uint16_t fNCbcDataSize; BoardType fBoardType; EventType fEventType; + ChipType fChipType; BeBoardRegMap fRegMap; /*!< Map of BeBoard Register Names vs. Register Values */ diff --git a/HWDescription/Cbc.cc b/HWDescription/Cbc.cc index 20ff9a70d30f35270db4cdb1375ae951367ba28a..0a0c94cb214af8faccdeb1a25e1f386e6a7c0f1d 100644 --- a/HWDescription/Cbc.cc +++ b/HWDescription/Cbc.cc @@ -80,7 +80,7 @@ namespace Ph2_HwDescription { { std::string line, fName, fPage_str, fAddress_str, fDefValue_str, fValue_str; int cLineCounter = 0; - CbcRegItem fRegItem; + RegItem fRegItem; while ( getline ( file, line ) ) { @@ -150,9 +150,9 @@ namespace Ph2_HwDescription { i->second.fValue = psetValue; } - CbcRegItem Cbc::getRegItem ( const std::string& pReg ) + RegItem Cbc::getRegItem ( const std::string& pReg ) { - CbcRegItem cItem; + RegItem cItem; CbcRegMap::iterator i = fRegMap.find ( pReg ); if ( i != std::end ( fRegMap ) ) return ( i->second ); @@ -174,7 +174,7 @@ namespace Ph2_HwDescription { if ( file ) { - std::set<CbcRegPair, RegItemComparer> fSetRegItem; + std::set<CbcRegPair, CbcRegItemComparer> fSetRegItem; for ( auto& it : fRegMap ) fSetRegItem.insert ( {it.first, it.second} ); @@ -222,7 +222,7 @@ namespace Ph2_HwDescription { } - bool RegItemComparer::operator() ( const CbcRegPair& pRegItem1, const CbcRegPair& pRegItem2 ) const + bool CbcRegItemComparer::operator() ( const CbcRegPair& pRegItem1, const CbcRegPair& pRegItem2 ) const { if ( pRegItem1.second.fPage != pRegItem2.second.fPage ) return pRegItem1.second.fPage < pRegItem2.second.fPage; diff --git a/HWDescription/Cbc.h b/HWDescription/Cbc.h index 1e106fe17313d1dc9ee13c6b66968cc04614f0bc..28952f8a8966dce3578d99a6b8a7a06b7be7decc 100644 --- a/HWDescription/Cbc.h +++ b/HWDescription/Cbc.h @@ -14,7 +14,7 @@ #define Cbc_h__ #include "FrontEndDescription.h" -#include "CbcRegItem.h" +#include "RegItem.h" #include "../Utils/Visitor.h" #include "../Utils/Exception.h" #include <iostream> @@ -34,8 +34,8 @@ */ namespace Ph2_HwDescription { - using CbcRegMap = std::map < std::string, CbcRegItem >; - using CbcRegPair = std::pair <std::string, CbcRegItem>; + using CbcRegMap = std::map < std::string, RegItem >; + using CbcRegPair = std::pair <std::string, RegItem>; using CommentMap = std::map <int, std::string>; /*! @@ -97,7 +97,7 @@ namespace Ph2_HwDescription { * \param pReg * \return RegItem */ - CbcRegItem getRegItem ( const std::string& pReg ); + RegItem getRegItem ( const std::string& pReg ); /*! * \brief Write the registers of the Map in a file * \param filename @@ -158,15 +158,16 @@ namespace Ph2_HwDescription { /*! * \struct RegItemComparer - * \brief Compare two pair of Register Name Versus CbcRegItem by the Page and Adress of the CbcRegItem + * \brief Compare two pair of Register Name Versus RegItem by the Page and Adress of the RegItem */ - struct RegItemComparer + + + struct CbcRegItemComparer { bool operator() ( const CbcRegPair& pRegItem1, const CbcRegPair& pRegItem2 ) const; }; - } #endif diff --git a/HWDescription/CbcRegItem.h b/HWDescription/CbcRegItem.h deleted file mode 100644 index 300707073306365f5d783b35f95ae376d056d837..0000000000000000000000000000000000000000 --- a/HWDescription/CbcRegItem.h +++ /dev/null @@ -1,36 +0,0 @@ -/*! - - \file CbcRegItem.h - \brief CbcRegItem description, contents of the structure CbcRegItem with is the value of the CbcRegMap - \author Lorenzo BIDEGAIN - \version 1.0 - \date 25/06/14 - Support : mail to : lorenzo.bidegain@cern.ch - - */ - -#ifndef _CbcRegItem_h__ -#define _CbcRegItem_h__ - -#include <stdint.h> - -namespace Ph2_HwDescription { - - /*! - * \struct CbcRegItem - * \brief Struct for CbcRegisterItem that is identified by Page, Address, DefaultValue, Value - */ - struct CbcRegItem - { - CbcRegItem() {}; - CbcRegItem (uint8_t pPage, uint8_t pAddress, uint8_t pDefValue, uint8_t pValue) : fPage (pPage), fAddress (pAddress), fDefValue (pDefValue), fValue (pValue) {} - - uint8_t fPage; - uint8_t fAddress; - uint8_t fDefValue; - uint8_t fValue; - - }; -} - -#endif diff --git a/HWDescription/Definition.h b/HWDescription/Definition.h index 67dd110dcea88b7dad04b15d56d2c2711b9afb9a..493772633f652e9deebfa0925293c3c89b2bc3a9 100644 --- a/HWDescription/Definition.h +++ b/HWDescription/Definition.h @@ -39,8 +39,18 @@ #define EVENT_HEADER_TDC_SIZE_32 6 // total of 6 32 bit words for HEADER + TDC #define EVENT_HEADER_SIZE_32 5 // 5 words for the header -#define MPA_HEADER_SIZE_32 4099 -#define MPA_EVENT_SIZE_32 240 +#define MPAlight_HEADER_SIZE_32 4099 +#define MPAlight_EVENT_SIZE_32 240 + + +#define MPA_HEADER_SIZE_32 1 +#define MPA_EVENT_SIZE_32 5 + + + + +#define SSA_HEADER_SIZE_32 1 +#define SSA_EVENT_SIZE_32 5 //Event @@ -80,6 +90,18 @@ // points to bufferoverlow #define D19C_OFFSET_ERROR_CBC3 2*32+0 +//MPA +//in uint32_t words +//#define D19C_EVENT_SIZE_32_MPA 32 +#define D19C_PCluster_SIZE_32_MPA 14 +#define D19C_SCluster_SIZE_32_MPA 11 + + +//D19C +//D19C event header size +#define D19C_EVENT_HEADER1_SIZE_32 4 +//#define D19C_EVENT_HEADER2_SIZE_32 1 + //Event //#define OFFSET_BUNCH 8 @@ -106,8 +128,8 @@ #define WIDTH_CBCSTUBDATA 12 //------------------------------------------------------------------------------ -enum class BoardType {GLIB, ICGLIB, CTA, ICFC7, CBC3FC7, D19C, MPAGLIB, SUPERVISOR}; -enum class ChipType {UNDEFINED = 0, CBC2, CBC3}; +enum class BoardType {GLIB, ICGLIB, CTA, ICFC7, CBC3FC7, D19C, MPAlightGLIB, SUPERVISOR}; +enum class ChipType {UNDEFINED = 0, CBC2, CBC3, MPA, SSA}; enum class SLinkDebugMode {SUMMARY = 0, FULL = 1, ERROR = 2}; enum class EventType {ZS = 1, VR = 2}; diff --git a/HWDescription/MPA.cc b/HWDescription/MPA.cc index c17f1fda8be4286f096a510a9acf80142ed6a78f..5495c7ba1696d84650f3e4e20e62e1591459acb7 100644 --- a/HWDescription/MPA.cc +++ b/HWDescription/MPA.cc @@ -22,16 +22,18 @@ namespace Ph2_HwDescription { // C'tors with object FE Description - MPA::MPA ( const FrontEndDescription& pFeDesc, uint8_t pMPAId, uint8_t pMPASide ) : FrontEndDescription ( pFeDesc ), - fMPAId ( pMPAId ), fMPASide ( pMPASide ) + MPA::MPA ( const FrontEndDescription& pFeDesc, uint8_t pMPAId ) : FrontEndDescription ( pFeDesc ), + fMPAId ( pMPAId ) {} // C'tors which take BeId, FMCId, FeID, MPAId - MPA::MPA ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAId, uint8_t pMPASide) : FrontEndDescription ( pBeId, pFMCId, pFeId ), fMPAId ( pMPAId ), fMPASide ( pMPASide ) - - {} + MPA::MPA (uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAId, const std::string &filename) : FrontEndDescription ( pBeId, pFMCId, pFeId ), fMPAId ( pMPAId ) + { + loadfRegMap ( filename ); + this->setChipType (ChipType::MPA); + } // Copy C'tor @@ -48,4 +50,157 @@ namespace Ph2_HwDescription { } + + + //load fRegMap from file + + void MPA::loadfRegMap ( const std::string& filename ) + { + std::ifstream file ( filename.c_str(), std::ios::in ); + + if ( file ) + { + std::string line, fName, fPage_str, fAddress_str, fDefValue_str, fValue_str; + int cLineCounter = 0; + RegItem fRegItem; + + while ( getline ( file, line ) ) + { + if ( line.find_first_not_of ( " \t" ) == std::string::npos ) + { + fCommentMap[cLineCounter] = line; + cLineCounter++; + //continue; + } + + else if ( line.at ( 0 ) == '#' || line.at ( 0 ) == '*' || line.empty() ) + { + //if it is a comment, save the line mapped to the line number so I can later insert it in the same place + fCommentMap[cLineCounter] = line; + cLineCounter++; + //continue; + } + else + { + std::istringstream input ( line ); + input >> fName >> fPage_str >> fAddress_str >> fDefValue_str >> fValue_str; + + fRegItem.fPage = strtoul ( fPage_str.c_str(), 0, 16 ); + fRegItem.fAddress = strtoul ( fAddress_str.c_str(), 0, 16 ); + fRegItem.fDefValue = strtoul ( fDefValue_str.c_str(), 0, 16 ); + fRegItem.fValue = strtoul ( fValue_str.c_str(), 0, 16 ); + + fRegMap[fName] = fRegItem; + cLineCounter++; + } + } + + file.close(); + } + else + { + LOG (ERROR) << "The MPA Settings File " << filename << " does not exist!" ; + exit (1); + } + + //for (auto cItem : fRegMap) + //LOG (DEBUG) << cItem.first; + } + + + + uint8_t MPA::getReg ( const std::string& pReg ) const + { + MPARegMap::const_iterator i = fRegMap.find ( pReg ); + + if ( i == fRegMap.end() ) + { + LOG (INFO) << "The MPA object: " << +fMPAId << " doesn't have " << pReg ; + return 0; + } + else + return i->second.fValue; + } + + + void MPA::setReg ( const std::string& pReg, uint8_t psetValue ) + { + MPARegMap::iterator i = fRegMap.find ( pReg ); + + if ( i == fRegMap.end() ) + LOG (INFO) << "The MPA object: " << +fMPAId << " doesn't have " << pReg ; + else + i->second.fValue = psetValue; + } + + RegItem MPA::getRegItem ( const std::string& pReg ) + { + RegItem cItem; + MPARegMap::iterator i = fRegMap.find ( pReg ); + + if ( i != std::end ( fRegMap ) ) return ( i->second ); + else + { + LOG (ERROR) << "Error, no Register " << pReg << " found in the RegisterMap of MPA " << +fMPAId << "!" ; + throw Exception ( "MPA: no matching register found" ); + return cItem; + } + } + + + //Write RegValues in a file + + void MPA::saveRegMap ( const std::string& filename ) + { + + std::ofstream file ( filename.c_str(), std::ios::out | std::ios::trunc ); + + if ( file ) + { + std::set<MPARegPair, MPARegItemComparer> fSetRegItem; + + for ( auto& it : fRegMap ) + fSetRegItem.insert ( {it.first, it.second} ); + + int cLineCounter = 0; + + for ( const auto& v : fSetRegItem ) + { + while (fCommentMap.find (cLineCounter) != std::end (fCommentMap) ) + { + auto cComment = fCommentMap.find (cLineCounter); + + file << cComment->second << std::endl; + cLineCounter++; + } + + file << v.first; + + for ( int j = 0; j < 48; j++ ) + file << " "; + + file.seekp ( -v.first.size(), std::ios_base::cur ); + + + file << "0x" << std::setfill ( '0' ) << std::setw ( 2 ) << std::hex << std::uppercase << int ( v.second.fPage ) << "\t0x" << std::setfill ( '0' ) << std::setw ( 2 ) << std::hex << std::uppercase << int ( v.second.fAddress ) << "\t0x" << std::setfill ( '0' ) << std::setw ( 2 ) << std::hex << std::uppercase << int ( v.second.fDefValue ) << "\t0x" << std::setfill ( '0' ) << std::setw ( 2 ) << std::hex << std::uppercase << int ( v.second.fValue ) << std::endl; + + cLineCounter++; + } + + file.close(); + } + else + LOG (ERROR) << "Error opening file" ; + } + + + bool MPARegItemComparer::operator() ( const MPARegPair& pRegItem1, const MPARegPair& pRegItem2 ) const + { + if ( pRegItem1.second.fPage != pRegItem2.second.fPage ) + return pRegItem1.second.fPage < pRegItem2.second.fPage; + else return pRegItem1.second.fAddress < pRegItem2.second.fAddress; + } + + + } diff --git a/HWDescription/MPA.h b/HWDescription/MPA.h index 7cfdff2185cb56375a5a4bcda9bb5b4328c3e88a..7f635b72370c9e8e439c8d1df234a086789846f9 100644 --- a/HWDescription/MPA.h +++ b/HWDescription/MPA.h @@ -14,7 +14,7 @@ #define MPA_h__ #include "FrontEndDescription.h" -#include "CbcRegItem.h" +#include "RegItem.h" #include "../Utils/Visitor.h" #include "../Utils/Exception.h" #include "../Utils/easylogging++.h" @@ -25,7 +25,7 @@ #include <utility> #include <set> -// MPA2 Chip HW Description Class +// MPA Chip HW Description Class /*! @@ -33,7 +33,9 @@ * \brief Namespace regrouping all the hardware description */ namespace Ph2_HwDescription { - + using MPARegMap = std::map < std::string, RegItem >; + using MPARegPair = std::pair <std::string, RegItem>; + using CommentMap = std::map <int, std::string>; class MPA : public FrontEndDescription { @@ -41,10 +43,10 @@ namespace Ph2_HwDescription { public: // C'tors which take BeId, FMCId, FeID, MPAId - MPA ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAId, uint8_t pMPASide); + MPA ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAId, const std::string& filename); // C'tors with object FE Description - MPA ( const FrontEndDescription& pFeDesc, uint8_t pMPAId , uint8_t pMPASide); + MPA ( const FrontEndDescription& pFeDesc, uint8_t pMPAId ); // Default C'tor MPA(); @@ -68,32 +70,56 @@ namespace Ph2_HwDescription { fMPAId = pMPAId; } - - - uint8_t getMPASide() const + void loadfRegMap ( const std::string& filename ); + /*! + * \brief Get any register from the Map + * \param pReg + * \return The value of the register + */ + uint8_t getReg ( const std::string& pReg ) const; + /*! + * \brief Set any register of the Map + * \param pReg + * \param psetValue + */ + void setReg ( const std::string& pReg, uint8_t psetValue ); + /*! + * \brief Get any registeritem of the Map + * \param pReg + * \return RegItem + */ + RegItem getRegItem ( const std::string& pReg ); + /*! + * \brief Write the registers of the Map in a file + * \param filename + */ + void saveRegMap ( const std::string& filename ); + /*! + * \brief Get the Map of the registers + * \return The map of register + */ + MPARegMap& getRegMap() { - return fMPASide; + return fRegMap; } - /*! - * \brief Set the MPA Id - * \param pMPAId - */ - void setMPASide ( uint8_t pMPASide ) + const MPARegMap& getRegMap() const { - fMPASide = pMPASide; + return fRegMap; } - - protected: - + MPARegMap fRegMap; uint8_t fMPAId; - uint8_t fMPASide; - + CommentMap fCommentMap; }; + struct MPARegItemComparer + { + + bool operator() ( const MPARegPair& pRegItem1, const MPARegPair& pRegItem2 ) const; + }; } #endif diff --git a/HWDescription/MPAlight.cc b/HWDescription/MPAlight.cc new file mode 100644 index 0000000000000000000000000000000000000000..62313df8e56cfc6c8617c230d75b880af8e3fe82 --- /dev/null +++ b/HWDescription/MPAlight.cc @@ -0,0 +1,51 @@ +/*! + + Filename : MPAlight.cc + Content : MPAlight Description class, config of the MPAlights + Programmer : Lorenzo BIDEGAIN + Version : 1.0 + Date of Creation : 25/06/14 + Support : mail to : lorenzo.bidegain@gmail.com + + */ + +#include "MPAlight.h" +#include <fstream> +#include <cstdio> +#include <sstream> +#include <iostream> +#include <string.h> +#include <iomanip> +#include "Definition.h" + + +namespace Ph2_HwDescription { + // C'tors with object FE Description + + MPAlight::MPAlight ( const FrontEndDescription& pFeDesc, uint8_t pMPAlightId, uint8_t pMPAlightSide ) : FrontEndDescription ( pFeDesc ), + fMPAlightId ( pMPAlightId ), fMPAlightSide ( pMPAlightSide ) + + {} + + // C'tors which take BeId, FMCId, FeID, MPAlightId + + MPAlight::MPAlight ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAlightId, uint8_t pMPAlightSide) : FrontEndDescription ( pBeId, pFMCId, pFeId ), fMPAlightId ( pMPAlightId ), fMPAlightSide ( pMPAlightSide ) + + {} + + // Copy C'tor + + MPAlight::MPAlight ( const MPAlight& MPAlightobj ) : FrontEndDescription ( MPAlightobj ), + fMPAlightId ( MPAlightobj.fMPAlightId ) + { + } + + + // D'Tor + + MPAlight::~MPAlight() + { + + } + +} diff --git a/HWDescription/MPAlight.h b/HWDescription/MPAlight.h new file mode 100644 index 0000000000000000000000000000000000000000..baa28a6b415d51abb1fd6e1f922bac2cfb4ea8f5 --- /dev/null +++ b/HWDescription/MPAlight.h @@ -0,0 +1,98 @@ +/*! + + \file MPAlight.h + \brief MPAlight Description class, config of the MPAlights + \author Lorenzo BIDEGAIN + \version 1.0 + \date 25/06/14 + Support : mail to : lorenzo.bidegain@gmail.com + + */ + + +#ifndef MPAlight_h__ +#define MPAlight_h__ + +#include "FrontEndDescription.h" +#include "../Utils/Visitor.h" +#include "../Utils/Exception.h" +#include "../Utils/easylogging++.h" +#include <iostream> +#include <map> +#include <string> +#include <stdint.h> +#include <utility> +#include <set> + +// MPAlight Chip HW Description Class + + +/*! + * \namespace Ph2_HwDescription + * \brief Namespace regrouping all the hardware description + */ +namespace Ph2_HwDescription { + + + class MPAlight : public FrontEndDescription + { + + public: + + // C'tors which take BeId, FMCId, FeID, MPAlightId + MPAlight ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pMPAlightId, uint8_t pMPAlightSide); + + // C'tors with object FE Description + MPAlight ( const FrontEndDescription& pFeDesc, uint8_t pMPAlightId , uint8_t pMPAlightSide); + + // Default C'tor + MPAlight(); + + // Copy C'tor + MPAlight ( const MPAlight& MPAlightobj ); + + // D'Tor + ~MPAlight(); + + uint8_t getMPAlightId() const + { + return fMPAlightId; + } + /*! + * \brief Set the MPAlight Id + * \param pMPAlightId + */ + void setMPAlightId ( uint8_t pMPAlightId ) + { + fMPAlightId = pMPAlightId; + } + + + + uint8_t getMPAlightSide() const + { + return fMPAlightSide; + } + /*! + * \brief Set the MPAlight Id + * \param pMPAlightId + */ + void setMPAlightSide ( uint8_t pMPAlightSide ) + { + fMPAlightSide = pMPAlightSide; + } + + + + protected: + + uint8_t fMPAlightId; + uint8_t fMPAlightSide; + + + }; + + +} + +#endif diff --git a/HWDescription/Module.cc b/HWDescription/Module.cc index 28d9a7b3552f5d8ddea848b6363dcaa71be96450..42a0efbad20a52c08c6c49fe3e6faae10217d11e 100644 --- a/HWDescription/Module.cc +++ b/HWDescription/Module.cc @@ -67,12 +67,12 @@ namespace Ph2_HwDescription { } - MPA* Module::getMPA ( uint8_t pMPAId ) const + MPAlight* Module::getMPAlight ( uint8_t pMPAlightId ) const { - for ( MPA* m : fMPAVector ) + for ( MPAlight* m : fMPAlightVector ) { - if ( m->getMPAId() == pMPAId ) + if ( m->getMPAlightId() == pMPAlightId ) return m; } @@ -82,14 +82,14 @@ namespace Ph2_HwDescription { - bool Module::removeMPA ( uint8_t pMPAId ) + bool Module::removeMPAlight ( uint8_t pMPAlightId ) { - std::vector < MPA* > :: iterator i; + std::vector < MPAlight* > :: iterator i; bool found = false; - for ( i = fMPAVector.begin(); i != fMPAVector.end(); ++i ) + for ( i = fMPAlightVector.begin(); i != fMPAlightVector.end(); ++i ) { - if ( (*i)->getMPAId() == pMPAId ) + if ( (*i)->getMPAlightId() == pMPAlightId ) { found = true; break; @@ -98,16 +98,121 @@ namespace Ph2_HwDescription { if ( found ) { - fMPAVector.erase ( i ); + fMPAlightVector.erase ( i ); return true; } else { - LOG (INFO) << "Error:The Module " << +fModuleId << " doesn't have the MPA " << +pMPAId ; + LOG (INFO) << "Error:The Module " << +fModuleId << " doesn't have the MPAlight " << +pMPAlightId ; return false; } } + + + + + + MPA* Module::getMPA ( uint8_t pMPAId ) const + { + + for ( MPA* m : fMPAVector ) + { + if ( m->getMPAId() == pMPAId ) + return m; + } + + return nullptr; + + } + + + + bool Module::removeMPA ( uint8_t pMPAId ) + { + std::vector < MPA* > :: iterator i; + bool found = false; + + for ( i = fMPAVector.begin(); i != fMPAVector.end(); ++i ) + { + if ( (*i)->getMPAId() == pMPAId ) + { + found = true; + break; + } + } + + if ( found ) + { + fMPAVector.erase ( i ); + return true; + } + else + { + LOG (INFO) << "Error:The Module " << +fModuleId << " doesn't have the MPA " << +pMPAId ; + return false; + } + } + + + + + + + + + + + + + + + + + SSA* Module::getSSA ( uint8_t pSSAId ) const + { + + for ( SSA* m : fSSAVector ) + { + if ( m->getSSAId() == pSSAId ) + return m; + } + + return nullptr; + + } + + + + bool Module::removeSSA ( uint8_t pSSAId ) + { + std::vector < SSA* > :: iterator i; + bool found = false; + + for ( i = fSSAVector.begin(); i != fSSAVector.end(); ++i ) + { + if ( (*i)->getSSAId() == pSSAId ) + { + found = true; + break; + } + } + + if ( found ) + { + fSSAVector.erase ( i ); + return true; + } + else + { + LOG (INFO) << "Error:The Module " << +fModuleId << " doesn't have the SSA " << +pSSAId ; + return false; + } + } + + + + } diff --git a/HWDescription/Module.h b/HWDescription/Module.h index 3c1e43f2ecc2d8d6661ff724ed9c1600388d7c3a..c26d632827e225587c480bbe6ecd5811a5ff8154 100644 --- a/HWDescription/Module.h +++ b/HWDescription/Module.h @@ -14,7 +14,9 @@ #include "FrontEndDescription.h" #include "Cbc.h" +#include "MPAlight.h" #include "MPA.h" +#include "SSA.h" #include "../Utils/Visitor.h" #include "../Utils/easylogging++.h" #include <vector> @@ -53,8 +55,13 @@ namespace Ph2_HwDescription { fCbcVector.clear(); + for ( auto& pMPAlight : fMPAlightVector ) + delete pMPAlight; + + fMPAlightVector.clear(); + for ( auto& pMPA : fMPAVector ) - delete pMPA; + delete pMPA; fMPAVector.clear(); @@ -86,12 +93,26 @@ namespace Ph2_HwDescription { } + uint8_t getNMPAlight() const + { + return fMPAlightVector.size(); + } + + + uint8_t getNMPA() const { return fMPAVector.size(); } + uint8_t getNSSA() const + { + return fSSAVector.size(); + } + + + /*! * \brief Adding a Cbc to the vector * \param pCbc @@ -129,6 +150,18 @@ namespace Ph2_HwDescription { fCbcVector.push_back ( pCbc ); } + void addMPAlight ( MPAlight& pMPAlight ) + { + fMPAlightVector.push_back ( &pMPAlight ); + } + void addMPAlight ( MPAlight* pMPAlight ) + { + fMPAlightVector.push_back ( pMPAlight ); + } + + + + void addMPA ( MPA& pMPA ) { fMPAVector.push_back ( &pMPA ); @@ -139,6 +172,21 @@ namespace Ph2_HwDescription { } + + + + void addSSA ( SSA& pSSA ) + { + fSSAVector.push_back ( &pSSA ); + } + void addSSA ( SSA* pSSA ) + { + fSSAVector.push_back ( pSSA ); + } + + + + /*! * \brief Remove a Cbc from the vector * \param pCbcId @@ -154,18 +202,51 @@ namespace Ph2_HwDescription { /*! - * \brief Remove a MPA from the vector - * \param pMPAId + * \brief Remove a MPAlight from the vector + * \param pMPAlightId * \return a bool which indicate if the removing was successful */ - bool removeMPA ( uint8_t pMPAId ); + bool removeMPAlight ( uint8_t pMPAlightId ); /*! - * \brief Get a MPA from the vector - * \param pMPAId - * \return a pointer of MPA, so we can manipulate directly the MPA contained in the vector + * \brief Get a MPAlight from the vector + * \param pMPAlightId + * \return a pointer of MPAlight, so we can manipulate directly the MPAlight contained in the vector */ + MPAlight* getMPAlight ( uint8_t pMPAlightId ) const; + + + /*! + * \brief Remove a MPA from the vector + * \param pMPAId + * \return a bool which indicate if the removing was successful + */ + bool removeMPA ( uint8_t pMPAId ); + /*! + * \brief Get a MPA from the vector + * \param pMPAId + * \return a pointer of MPA, so we can manipulate directly the MPA contained in the vector + */ MPA* getMPA ( uint8_t pMPAId ) const; + + + + + /*! + * \brief Remove a SSA from the vector + * \param pSSAId + * \return a bool which indicate if the removing was successful + */ + bool removeSSA ( uint8_t pSSAId ); + /*! + * \brief Get a SSA from the vector + * \param pSSAId + * \return a pointer of SSA, so we can manipulate directly the SSA contained in the vector + */ + SSA* getSSA ( uint8_t pSSAId ) const; + + + /*! * \brief Get the Module Id * \return The Module ID @@ -185,7 +266,9 @@ namespace Ph2_HwDescription { std::vector < Cbc* > fCbcVector; + std::vector < MPAlight* > fMPAlightVector; std::vector < MPA* > fMPAVector; + std::vector < SSA* > fSSAVector; protected: diff --git a/HWDescription/RegItem.h b/HWDescription/RegItem.h new file mode 100644 index 0000000000000000000000000000000000000000..8b4aeba985e4fd6f76f85c2d2be9dc0943e86d62 --- /dev/null +++ b/HWDescription/RegItem.h @@ -0,0 +1,36 @@ +/*! + + \file RegItem.h + \brief RegItem description, contents of the structure RegItem with is the value of the CbcRegMap + \author Lorenzo BIDEGAIN + \version 1.0 + \date 25/06/14 + Support : mail to : lorenzo.bidegain@cern.ch + + */ + +#ifndef _RegItem_h__ +#define _RegItem_h__ + +#include <stdint.h> + +namespace Ph2_HwDescription { + + /*! + * \struct RegItem + * \brief Struct for CbcRegisterItem that is identified by Page, Address, DefaultValue, Value + */ + struct RegItem + { + RegItem() {}; + RegItem (uint8_t pPage, uint16_t pAddress, uint8_t pDefValue, uint8_t pValue) : fPage (pPage), fAddress (pAddress), fDefValue (pDefValue), fValue (pValue) {} + + uint8_t fPage; + uint16_t fAddress; + uint8_t fDefValue; + uint8_t fValue; + + }; +} + +#endif diff --git a/HWDescription/SSA.cc b/HWDescription/SSA.cc new file mode 100644 index 0000000000000000000000000000000000000000..0367d549cf3874f22f2e28b7e037deaeb205fde8 --- /dev/null +++ b/HWDescription/SSA.cc @@ -0,0 +1,51 @@ +/*! + + Filename : SSA.cc + Content : SSA Description class, config of the SSAs + Programmer : Lorenzo BIDEGAIN + Version : 1.0 + Date of Creation : 25/06/14 + Support : mail to : lorenzo.bidegain@gmail.com + + */ + +#include "SSA.h" +#include <fstream> +#include <cstdio> +#include <sstream> +#include <iostream> +#include <string.h> +#include <iomanip> +#include "Definition.h" + + +namespace Ph2_HwDescription { + // C'tors with object FE Description + + SSA::SSA ( const FrontEndDescription& pFeDesc, uint8_t pSSAId, uint8_t) : FrontEndDescription ( pFeDesc ), + fSSAId ( pSSAId ) + + {} + + // C'tors which take BeId, FMCId, FeID, SSAId + + SSA::SSA ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pSSAId, uint8_t) : FrontEndDescription ( pBeId, pFMCId, pFeId ), fSSAId ( pSSAId ) + + {} + + // Copy C'tor + + SSA::SSA ( const SSA& SSAobj ) : FrontEndDescription ( SSAobj ), + fSSAId ( SSAobj.fSSAId ) + { + } + + + // D'Tor + + SSA::~SSA() + { + + } + +} diff --git a/HWDescription/SSA.h b/HWDescription/SSA.h new file mode 100644 index 0000000000000000000000000000000000000000..96fc500d9f68fed706ea7b8fd0018e59b855c2c6 --- /dev/null +++ b/HWDescription/SSA.h @@ -0,0 +1,83 @@ +/*! + + \file SSA.h + \brief SSA Description class, config of the SSAs + \author Lorenzo BIDEGAIN + \version 1.0 + \date 25/06/14 + Support : mail to : lorenzo.bidegain@gmail.com + + */ + + +#ifndef SSA_h__ +#define SSA_h__ + +#include "FrontEndDescription.h" +#include "RegItem.h" +#include "../Utils/Visitor.h" +#include "../Utils/Exception.h" +#include "../Utils/easylogging++.h" +#include <iostream> +#include <map> +#include <string> +#include <stdint.h> +#include <utility> +#include <set> + +// SSA2 Chip HW Description Class + + +/*! + * \namespace Ph2_HwDescription + * \brief Namespace regrouping all the hardware description + */ +namespace Ph2_HwDescription { + + + class SSA : public FrontEndDescription + { + + public: + + // C'tors which take BeId, FMCId, FeID, SSAId + SSA ( uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pSSAId, uint8_t pSSASide); + + // C'tors with object FE Description + SSA ( const FrontEndDescription& pFeDesc, uint8_t pSSAId , uint8_t pSSASide); + + // Default C'tor + SSA(); + + // Copy C'tor + SSA ( const SSA& SSAobj ); + + // D'Tor + ~SSA(); + + uint8_t getSSAId() const + { + return fSSAId; + } + /*! + * \brief Set the SSA Id + * \param pSSAId + */ + void setSSAId ( uint8_t pSSAId ) + { + fSSAId = pSSAId; + } + + + protected: + + uint8_t fSSAId; + uint8_t fSSASide; + + + }; + + +} + +#endif diff --git a/HWInterface/BeBoardFWInterface.h b/HWInterface/BeBoardFWInterface.h index 9c18843ac0232b26ba980a95d3f01412b12091d9..ce2a0f375985775c59c7ad3da0beb20692f0fabd 100644 --- a/HWInterface/BeBoardFWInterface.h +++ b/HWInterface/BeBoardFWInterface.h @@ -22,7 +22,7 @@ #include "../Utils/easylogging++.h" #include "../HWDescription/BeBoard.h" #include "../HWDescription/Definition.h" -#include "../HWDescription/CbcRegItem.h" +#include "../HWDescription/RegItem.h" #include "../HWDescription/Cbc.h" #include "../HWDescription/Module.h" #include "../HWDescription/BeBoard.h" @@ -132,28 +132,28 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - virtual void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ + virtual void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ /*! * \brief Encode a/several word(s) readable for a Cbc * \param pRegItem : RegItem containing infos (name, adress, value...) about the register to write * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - virtual void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ + virtual void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ /*! * \brief Encode a/several word(s) for Broadcast write to CBCs * \param pRegItem : RegItem containing infos (name, adress, value...) about the register to write * \param pNCbc : number of CBCs to write to * \param pVecReq : Vector to stack the encoded words */ - virtual void BCEncodeReg ( const CbcRegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead = false, bool pWrite = false ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ + virtual void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead = false, bool pWrite = false ) = 0; /*!< Encode a/several word(s) readable for a Cbc*/ /*! * \brief Decode a word from a read of a register of the Cbc * \param pRegItem : RegItem containing infos (name, adress, value...) about the register to read * \param pCbcId : Id of the Cbc to work with * \param pWord : variable to put the decoded word */ - virtual void DecodeReg ( CbcRegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) = 0; /*!< Decode a word from a read of a register of the Cbc*/ + virtual void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) = 0; /*!< Decode a word from a read of a register of the Cbc*/ //virtual pure methods which are defined in the proper BoardFWInterface class diff --git a/HWInterface/Cbc3Fc7FWInterface.cc b/HWInterface/Cbc3Fc7FWInterface.cc index a71e3c0982d34d59bfda08e8baa964faf8ee92e8..33134e556dbd1b6990e239c6ae6d3c262c7fa658 100644 --- a/HWInterface/Cbc3Fc7FWInterface.cc +++ b/HWInterface/Cbc3Fc7FWInterface.cc @@ -239,7 +239,7 @@ namespace Ph2_HwInterface { { uint8_t cStubLogicInput = cCbc->getReg ("Pipe&StubInpSel&Ptwidth"); cStubLogictInputMap[cCbc] = cStubLogicInput; - CbcRegItem cRegItem (0, 0x12, 0, ( (cStubLogicInput & 0xCF) | (0x20 & 0x30) ) ); + RegItem cRegItem (0, 0x12, 0, ( (cStubLogicInput & 0xCF) | (0x20 & 0x30) ) ); cVecReq.clear(); this->EncodeReg (cRegItem, cFe->getFeId(), cCbc->getCbcId(), cVecReq, true, true); uint8_t cWriteAttempts = 0 ; @@ -266,7 +266,7 @@ namespace Ph2_HwInterface { uint32_t cStatus = ReadReg ("cbc_system_stat.io.cbc1.slvs5"); LOG (DEBUG) << cCounter << " " << std::bitset<32> (cStatus); std::this_thread::sleep_for (std::chrono::microseconds (10) ); - //CbcRegItem cRegItem (0, 0x1D, 0, 0); + //RegItem cRegItem (0, 0x1D, 0, 0); //std::vector<uint32_t> cVecReq; //this->EncodeReg (cRegItem, 0, cVecReq, true, false); //this->ReadCbcBlockReg (cVecReq); @@ -304,7 +304,7 @@ namespace Ph2_HwInterface { for (auto cFe : pBoard->fModuleVector) for (auto cCbc : cFe->fCbcVector) { - CbcRegItem cRegItem (0, 0x12, 0, cStubLogictInputMap[cCbc] ); + RegItem cRegItem (0, 0x12, 0, cStubLogictInputMap[cCbc] ); cVecReq.clear(); this->EncodeReg (cRegItem, cFe->getFeId(), cCbc->getCbcId(), cVecReq, true, true); uint8_t cWriteAttempts = 0; @@ -495,7 +495,7 @@ namespace Ph2_HwInterface { //TODO: check what to do with fFMCid and if I need it! // this is clearly for addressing individual CBCs, have to see how to deal with broadcast commands // for this FW, page values are 1 and 2 so need to increment the 0 and 1 from config file - void Cbc3Fc7FWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void Cbc3Fc7FWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, @@ -505,7 +505,7 @@ namespace Ph2_HwInterface { //TODO: not sure if thisF fFMCId is really needed here! pVecReq.push_back ( ( (fFMCId ) << 29 ) | ( (pCbcId + 1) << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( (pRegItem.fPage) << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void Cbc3Fc7FWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void Cbc3Fc7FWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -517,7 +517,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( cGlobalCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( (pRegItem.fPage ) << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void Cbc3Fc7FWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void Cbc3Fc7FWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, @@ -527,7 +527,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( (fFMCId ) << 29 ) | ( fBroadcastCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( (pRegItem.fPage ) << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void Cbc3Fc7FWInterface::DecodeReg ( CbcRegItem& pRegItem, + void Cbc3Fc7FWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, diff --git a/HWInterface/Cbc3Fc7FWInterface.h b/HWInterface/Cbc3Fc7FWInterface.h index 81ac432c9bc0ba47940eef3985df992d27e42cb6..ffa1717309a4e4e0d8c18f434913145af6d50ec3 100644 --- a/HWInterface/Cbc3Fc7FWInterface.h +++ b/HWInterface/Cbc3Fc7FWInterface.h @@ -206,10 +206,10 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void BCEncodeReg ( const CbcRegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; - void DecodeReg ( CbcRegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; bool WriteCbcBlockReg ( std::vector<uint32_t>& pVecReg, uint8_t& pWriteAttempts, bool pReadback) override; diff --git a/HWInterface/CbcInterface.cc b/HWInterface/CbcInterface.cc index 403c3e8ba1ab807391d5b769fcf9a8789800c4e2..fd98141a129eb00229956c73f930d51477aa4741 100644 --- a/HWInterface/CbcInterface.cc +++ b/HWInterface/CbcInterface.cc @@ -65,7 +65,7 @@ namespace Ph2_HwInterface { //vector to encode all the registers into std::vector<uint32_t> cVec; - //Deal with the CbcRegItems and encode them + //Deal with the RegItems and encode them CbcRegMap cCbcRegMap = pCbc->getRegMap(); @@ -105,7 +105,7 @@ namespace Ph2_HwInterface { //helper vector to store the register names in the same order as the RegItems std::vector<std::string> cNameVec; - //Deal with the CbcRegItems and encode them + //Deal with the RegItems and encode them CbcRegMap cCbcRegMap = pCbc->getRegMap(); @@ -139,7 +139,7 @@ namespace Ph2_HwInterface { //for ( const auto& cReg : cVec ) for ( const auto& cReadWord : cVec ) { - CbcRegItem cRegItem; + RegItem cRegItem; std::string cName = cNameVec[idxReadWord++]; fBoardFW->DecodeReg ( cRegItem, cCbcId, cReadWord, cRead, cFailed ); @@ -159,7 +159,7 @@ namespace Ph2_HwInterface { setBoard ( pCbc->getBeBoardIdentifier() ); //next, get the reg item - CbcRegItem cRegItem = pCbc->getRegItem ( pRegNode ); + RegItem cRegItem = pCbc->getRegItem ( pRegNode ); cRegItem.fValue = pValue; //vector for transaction @@ -191,8 +191,8 @@ namespace Ph2_HwInterface { std::vector<uint32_t> cVec; - //Deal with the CbcRegItems and encode them - CbcRegItem cRegItem; + //Deal with the RegItems and encode them + RegItem cRegItem; for ( const auto& cReg : pVecReq ) { @@ -233,7 +233,7 @@ namespace Ph2_HwInterface { { setBoard ( pCbc->getBeBoardIdentifier() ); - CbcRegItem cRegItem = pCbc->getRegItem ( pRegNode ); + RegItem cRegItem = pCbc->getRegItem ( pRegNode ); std::vector<uint32_t> cVecReq; @@ -259,8 +259,8 @@ namespace Ph2_HwInterface { std::vector<uint32_t> cVec; - //Deal with the CbcRegItems and encode them - CbcRegItem cRegItem; + //Deal with the RegItems and encode them + RegItem cRegItem; for ( const auto& cReg : pVecReg ) { @@ -300,7 +300,7 @@ namespace Ph2_HwInterface { //void CbcInterface::ReadAllCbc ( const Module* pModule ) //{ - //CbcRegItem cRegItem; + //RegItem cRegItem; //uint8_t cCbcId; //std::vector<uint32_t> cVecReq; //std::vector<std::string> cVecRegNode; @@ -349,7 +349,7 @@ namespace Ph2_HwInterface { //first set the correct BeBoard setBoard ( pModule->getBeBoardIdentifier() ); - CbcRegItem cRegItem = pModule->fCbcVector.at (0)->getRegItem ( pRegNode ); + RegItem cRegItem = pModule->fCbcVector.at (0)->getRegItem ( pRegNode ); cRegItem.fValue = pValue; //vector for transaction @@ -381,8 +381,8 @@ namespace Ph2_HwInterface { std::vector<uint32_t> cVec; - //Deal with the CbcRegItems and encode them - CbcRegItem cRegItem; + //Deal with the RegItems and encode them + RegItem cRegItem; for ( const auto& cReg : pVecReg ) { diff --git a/HWInterface/CtaFWInterface.cc b/HWInterface/CtaFWInterface.cc index 21eb42f6bb2110f2fccb277fde06b2a569380a81..92f7c4f5c83e0d1142b0dbd8dafd80620303e367 100644 --- a/HWInterface/CtaFWInterface.cc +++ b/HWInterface/CtaFWInterface.cc @@ -487,7 +487,7 @@ namespace Ph2_HwInterface { // CBC Methods // ///////////////////////////////////////////////////// - void CtaFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void CtaFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, @@ -501,7 +501,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( pCbcId + 0x41 ) << 21 | ( pCbcId & 7 ) << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void CtaFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void CtaFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -513,7 +513,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( pCbcId + 0x41 ) << 21 | pCbcId << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void CtaFWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void CtaFWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, @@ -526,7 +526,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( cCbcId + 0x41 ) << 21 | ( cCbcId & 7 ) << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void CtaFWInterface::DecodeReg ( CbcRegItem& pRegItem, + void CtaFWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, diff --git a/HWInterface/CtaFWInterface.h b/HWInterface/CtaFWInterface.h index 2b33b493eb9b6cb44068ec2f3fa9094b534d4472..2e5ecb1d609b7f491c20055797bde4821bf62b7f 100644 --- a/HWInterface/CtaFWInterface.h +++ b/HWInterface/CtaFWInterface.h @@ -194,7 +194,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead = false, bool pWrite = false ); /*!< Encode a/several word(s) readable for a Cbc*/ @@ -203,7 +203,7 @@ namespace Ph2_HwInterface { * \param pRegItem : RegItem containing infos (name, adress, value...) about the register to write * \param pVecReq : Vector to stack the encoded words */ - void BCEncodeReg ( const CbcRegItem& pRegItem, + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead = false, @@ -214,7 +214,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -226,7 +226,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pWord : variable to put the decoded word */ - void DecodeReg ( CbcRegItem& pRegItem, + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, diff --git a/HWInterface/D19cFWInterface.cc b/HWInterface/D19cFWInterface.cc index 9df0e508ff2e59a8d18b12e9a3dacbd68f5e4e13..d209f0dcdf95d288a21277fed23be480c52d1e1e 100755 --- a/HWInterface/D19cFWInterface.cc +++ b/HWInterface/D19cFWInterface.cc @@ -44,7 +44,7 @@ namespace Ph2_HwInterface { { if ( fFileHandler == nullptr ) fSaveToFile = false; else fSaveToFile = true; - fResetAttempts = 0 ; + fResetAttempts = 0 ; } D19cFWInterface::D19cFWInterface ( const char* pId, @@ -71,7 +71,7 @@ namespace Ph2_HwInterface { { if ( fFileHandler == nullptr ) fSaveToFile = false; else fSaveToFile = true; - fResetAttempts = 0 ; + fResetAttempts = 0 ; } void D19cFWInterface::setFileHandler (FileHandler* pHandler) @@ -98,7 +98,7 @@ namespace Ph2_HwInterface { { int error_block_id = (cError & 0x0000000f); int error_code = ( (cError & 0x00000ff0) >> 4); - LOG (ERROR) << "Block: " << BOLDRED << error_block_id << RESET << ", Code: " << BOLDRED << error_code << RESET; + LOG (ERROR) << "Block: " << BOLDRED << error_block_id << RESET << ", Code: " << BOLDRED << std::hex << error_code << std::dec << RESET; } } } @@ -132,19 +132,19 @@ namespace Ph2_HwInterface { case 0x5: name = "8xCBC3_FMC1"; break; - + case 0x6: name = "8xCBC3_FMC2"; break; - + case 0x7: name = "FMC_1CBC3"; break; - + case 0x8: name = "FMC_MPA_SSA_BOARD"; break; - + case 0x9: name = "FMC_FERMI_TRIGGER_BOARD"; break; @@ -202,12 +202,13 @@ namespace Ph2_HwInterface { break; case 0x2: - chip_type = ChipType::UNDEFINED; + chip_type = ChipType::MPA; + break; + + case 0x3: + chip_type = ChipType::SSA; break; - case 0x3: - chip_type = ChipType::UNDEFINED; - break; } return chip_type; @@ -310,11 +311,11 @@ namespace Ph2_HwInterface { fFirwmareChipType = getChipType (cChipTypeCode); fFWNHybrids = ReadReg ("fc7_daq_stat.general.info.num_hybrids"); fFWNChips = ReadReg ("fc7_daq_stat.general.info.num_chips"); - fCBC3Emulator = (ReadReg ("fc7_daq_stat.general.info.implementation") == 2); + fChipEmulator = (ReadReg ("fc7_daq_stat.general.info.implementation") == 2); fIsDDR3Readout = (ReadReg("fc7_daq_stat.ddr3_block.is_ddr3_type") == 1); fI2CVersion = (ReadReg("fc7_daq_stat.command_processor_block.i2c.master_version")); if(fI2CVersion >= 1) this->SetI2CAddressTable(); - + fNCbc = 0; std::vector< std::pair<std::string, uint32_t> > cVecReg; @@ -333,14 +334,24 @@ namespace Ph2_HwInterface { LOG (INFO) << "Enabling Hybrid " << (int) cFe->getFeId(); hybrid_enable |= 1 << cFe->getFeId(); - //configure the CBCs - preliminary FW only supports 1 CBC but put the rest of the code there and comment - for ( Cbc* cCbc : cFe->fCbcVector) - { - LOG (INFO) << " Enabling Chip " << (int) cCbc->getCbcId(); - chips_enable[cFe->getFeId()] |= 1 << cCbc->getCbcId(); - //need to increment the NCbc counter for I2C controller - fNCbc++; + if (fFirwmareChipType == ChipType::CBC2 || fFirwmareChipType == ChipType::CBC3) { + for ( Cbc* cCbc : cFe->fCbcVector) + { + LOG (INFO) << " Enabling Chip " << (int) cCbc->getCbcId(); + chips_enable[cFe->getFeId()] |= 1 << cCbc->getCbcId(); + //need to increment the NCbc counter for I2C controller + fNCbc++; + } + } else if (fFirwmareChipType == ChipType::MPA) { + for ( MPA* cMPA : cFe->fMPAVector) + { + LOG (INFO) << " Enabling Chip " << (int) cMPA->getMPAId(); + chips_enable[cFe->getFeId()] |= 1 << cMPA->getMPAId(); + //need to increment the counter for I2C controller + fNMPA++; + } } + } // hybrid / chips enabling part @@ -355,7 +366,7 @@ namespace Ph2_HwInterface { } delete chips_enable; - LOG (INFO) << BOLDGREEN << fNHybrids << " hybrid(s) was(were) enabled with the total amount of " << fNCbc << " chip(s)!" << RESET; + LOG (INFO) << BOLDGREEN << fNHybrids << " hybrid(s) was(were) enabled with the total amount of " << fNCbc+fNMPA << " chip(s)!" << RESET; //last, loop over the variable registers from the HWDescription.xml file //this is where I should get all the clocking and FastCommandInterface settings @@ -396,7 +407,7 @@ namespace Ph2_HwInterface { WriteReg ("fc7_daq_ctrl.command_processor_block.i2c.command_fifo", cInit); //read the replies for the pings! std::vector<uint32_t> pReplies; - bool cReadSuccess = !ReadI2C (fNCbc, pReplies); + bool cReadSuccess = !ReadI2C (fNCbc+fNMPA, pReplies); bool cWordCorrect = true; if (cReadSuccess) @@ -419,16 +430,16 @@ namespace Ph2_HwInterface { } } - if (cReadSuccess && cWordCorrect) LOG (INFO) << "Successfully received *Pings* from " << fNCbc << " Cbcs"; + if (cReadSuccess && cWordCorrect) LOG (INFO) << "Successfully received *Pings* from " << fNCbc+fNMPA << " Chips"; - if (!cReadSuccess) LOG (ERROR) << RED << "Did not receive the correct number of *Pings*; expected: " << fNCbc << ", received: " << pReplies.size() << RESET; + if (!cReadSuccess) LOG (ERROR) << RED << "Did not receive the correct number of *Pings*; expected: " << fNCbc+fNMPA << ", received: " << pReplies.size() << RESET; if (!cWordCorrect) LOG (ERROR) << RED << "FE/CBC ids are not correct!" << RESET; this->PhaseTuning (pBoard); this->ResetReadout(); - + //adding an Orbit reset to align CBC L1A counters this->WriteReg("fc7_daq_ctrl.fast_command_block.control.fast_orbit_reset",0x1); } @@ -553,9 +564,43 @@ namespace Ph2_HwInterface { } // set i2c address table depending on the hybrid - void D19cFWInterface::SetI2CAddressTable() + void D19cFWInterface::SetI2CAddressTable() { LOG (INFO) << BOLDGREEN << "Setting the I2C address table" << RESET; + + // creating the map + std::vector< std::vector<uint32_t> > i2c_slave_map; + + // setting the map for different chip types + if (fFirwmareChipType == ChipType::CBC2 || fFirwmareChipType == ChipType::CBC3) { + // nothing to de done here default addresses are set for CBC + // actually FIXME + return; + } else if (fFirwmareChipType == ChipType::MPA) { + for (int id = 0; id < fFWNChips; id++) { + // for chip emulator register width is 8 bits, not 16 as for MPA + if(!fChipEmulator) { + i2c_slave_map.push_back({0b1000000 + id, 2, 1, 1, 1, 1}); + } else { + i2c_slave_map.push_back({0b1000000 + id, 1, 1, 1, 1, 1}); + } + } + } + + for (int ism = 0; ism < i2c_slave_map.size(); ism++) { + // setting the params + uint32_t shifted_i2c_address = i2c_slave_map[ism][0]<<25; + uint32_t shifted_register_address_nbytes = i2c_slave_map[ism][1]<<10; + uint32_t shifted_data_wr_nbytes = i2c_slave_map[ism][2]<<5; + uint32_t shifted_data_rd_nbytes = i2c_slave_map[ism][3]<<0; + uint32_t shifted_stop_for_rd_en = i2c_slave_map[ism][4]<<24; + uint32_t shifted_nack_en = i2c_slave_map[ism][5]<<23; + + // writing the item to the firmware + uint32_t final_item = shifted_i2c_address + shifted_register_address_nbytes + shifted_data_wr_nbytes + shifted_data_rd_nbytes + shifted_stop_for_rd_en + shifted_nack_en; + std::string curreg = "fc7_daq_cnfg.command_processor_block.i2c_address_table.slave_" + std::to_string(ism) + "_config"; + WriteReg(curreg, final_item); + } } void D19cFWInterface::Start() @@ -567,7 +612,7 @@ namespace Ph2_HwInterface { WriteReg ("fc7_daq_ctrl.stub_counter_block.general.shutter_open", 0x1); WriteReg ("fc7_daq_ctrl.stub_counter_block.general.shutter_open", 0x0); std::this_thread::sleep_for (std::chrono::microseconds (10) ); - + WriteReg ("fc7_daq_ctrl.fast_command_block.control.start_trigger", 0x1); std::this_thread::sleep_for (std::chrono::microseconds (10) ); } @@ -578,7 +623,7 @@ namespace Ph2_HwInterface { WriteReg ("fc7_daq_ctrl.stub_counter_block.general.shutter_close", 0x1); WriteReg ("fc7_daq_ctrl.stub_counter_block.general.shutter_close", 0x0); std::this_thread::sleep_for (std::chrono::microseconds (10) ); - + WriteReg ("fc7_daq_ctrl.fast_command_block.control.stop_trigger", 0x1); std::this_thread::sleep_for (std::chrono::microseconds (10) ); @@ -605,7 +650,7 @@ namespace Ph2_HwInterface { void D19cFWInterface::Pause() { - LOG (INFO) << BOLDBLUE << "................................ Pausing run ... " << RESET ; + LOG (INFO) << BOLDBLUE << "................................ Pausing run ... " << RESET ; WriteReg ("fc7_daq_ctrl.fast_command_block.control.stop_trigger", 0x1); std::this_thread::sleep_for (std::chrono::microseconds (10) ); } @@ -613,10 +658,10 @@ namespace Ph2_HwInterface { void D19cFWInterface::Resume() { - LOG (INFO) << BOLDBLUE << "Reseting readout before resuming run ... " << RESET ; + LOG (INFO) << BOLDBLUE << "Reseting readout before resuming run ... " << RESET ; this->ResetReadout(); - - LOG (INFO) << BOLDBLUE << "................................ Resuming run ... " << RESET ; + + LOG (INFO) << BOLDBLUE << "................................ Resuming run ... " << RESET ; WriteReg ("fc7_daq_ctrl.fast_command_block.control.start_trigger", 0x1); std::this_thread::sleep_for (std::chrono::microseconds (10) ); } @@ -628,7 +673,7 @@ namespace Ph2_HwInterface { WriteReg ("fc7_daq_ctrl.readout_block.control.readout_reset", 0x0); std::this_thread::sleep_for (std::chrono::microseconds (10) ); - + if (fIsDDR3Readout) { fDDR3Offset = 0; fDDR3Calibrated = (ReadReg("fc7_daq_stat.ddr3_block.init_calib_done") == 1); @@ -644,7 +689,7 @@ namespace Ph2_HwInterface { void D19cFWInterface::DDR3SelfTest() { - //opened issue: without this time delay the self-test doesn't examine entire 4Gb address space of the chip(reason not obvious) + //opened issue: without this time delay the self-test doesn't examine entire 4Gb address space of the chip(reason not obvious) std::this_thread::sleep_for (std::chrono::seconds (1) ); if (fIsDDR3Readout && fDDR3Calibrated) { // trigger the self check @@ -699,7 +744,7 @@ namespace Ph2_HwInterface { if (fFirwmareChipType == ChipType::CBC3) { - if (!fCBC3Emulator) + if (!fChipEmulator) { bool cDoAuto = true; @@ -723,10 +768,11 @@ namespace Ph2_HwInterface { cHipRegMap[cCbc] = cOriginalHipReg; - CbcRegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" ); + RegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" ); cRegItem.fValue = (cOriginalStubLogicInput & 0xCF) | (0x20 & 0x30); this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getCbcId(), cVecReq, true, true); + cRegItem = cCbc->getRegItem ( "HIP&TestMode" ); cRegItem.fValue = (cOriginalHipReg & ~ (0x1 << 4) ); this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getCbcId(), cVecReq, true, true); @@ -768,7 +814,7 @@ namespace Ph2_HwInterface { for (auto cCbc : cFe->fCbcVector) { - CbcRegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" ); + RegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" ); cRegItem.fValue = cStubLogictInputMap[cCbc]; //this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getCbcId(), cVecReq, true, true); @@ -779,6 +825,7 @@ namespace Ph2_HwInterface { } } + cWriteAttempts = 0; this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); @@ -839,6 +886,84 @@ namespace Ph2_HwInterface { { // no timing tuning needed } + else if (fFirwmareChipType == ChipType::MPA) + { + // first need to set the proper i2c settings of the chip for the phase alignment + std::map<MPA*, uint8_t> cReadoutModeMap; + std::map<MPA*, uint8_t> cStubModeMap; + std::vector<uint32_t> cVecReq; + + cVecReq.clear(); + + for (auto cFe : pBoard->fModuleVector) + { + for (auto cMpa : cFe->fMPAVector) + { + + uint8_t cOriginalReadoutMode = cMpa->getReg ("ReadoutMode"); + uint8_t cOriginalStubMode = cMpa->getReg ("ECM"); + cReadoutModeMap[cMpa] = cOriginalReadoutMode; + cStubModeMap[cMpa] = cOriginalStubMode; + + // sync mode + RegItem cRegItem = cMpa->getRegItem ( "ReadoutMode" ); + cRegItem.fValue = 0x00; + this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true); + + uint8_t cWriteAttempts = 0; + this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + cVecReq.clear(); + + // ps stub mode + cRegItem = cMpa->getRegItem ( "ECM" ); + cRegItem.fValue = 0x08; + this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true); + + cWriteAttempts = 0; + this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + cVecReq.clear(); + + } + } + + uint8_t cWriteAttempts = 0; + //this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + std::this_thread::sleep_for (std::chrono::milliseconds (10) ); + + // now do phase tuning + Align_out(); + + //re-enable everything back + cVecReq.clear(); + for (auto cFe : pBoard->fModuleVector) + { + for (auto cMpa : cFe->fMPAVector) + { + + RegItem cRegItem = cMpa->getRegItem ( "ReadoutMode" ); + cRegItem.fValue = cReadoutModeMap[cMpa]; + this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true); + + cWriteAttempts = 0; + this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + cVecReq.clear(); + + cRegItem = cMpa->getRegItem ( "ECM" ); + cRegItem.fValue = cStubModeMap[cMpa]; + this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true); + + cWriteAttempts = 0; + this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + cVecReq.clear(); + + } + } + + cWriteAttempts = 0; + //this->WriteCbcBlockReg (cVecReq, cWriteAttempts, true); + + LOG (INFO) << GREEN << "MPA Phase tuning finished succesfully" << RESET; + } else { LOG (INFO) << "No tuning procedure implemented for this chip type."; @@ -849,13 +974,12 @@ namespace Ph2_HwInterface { uint32_t D19cFWInterface::ReadData ( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait) { uint32_t cEventSize = computeEventSize (pBoard); - uint32_t cBoardHeader1Size = D19C_EVENT_HEADER1_SIZE_32_CBC3; uint32_t cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt"); uint32_t data_handshake = ReadReg ("fc7_daq_cnfg.readout_block.global.data_handshake_enable"); uint32_t cPackageSize = ReadReg ("fc7_daq_cnfg.readout_block.packet_nbr") + 1; - bool pFailed = false; - int cCounter = 0 ; + bool pFailed = false; + int cCounter = 0 ; while (cNWords == 0 && !pFailed ) { cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt"); @@ -864,25 +988,25 @@ namespace Ph2_HwInterface { } cCounter++; - if (!pWait) + if (!pWait) return 0; else std::this_thread::sleep_for (std::chrono::microseconds (10) ); } - + uint32_t cNEvents = 0; - uint32_t cNtriggers = 0; + uint32_t cNtriggers = 0; uint32_t cNtriggers_prev = cNtriggers; - + if (data_handshake == 1 && !pFailed ) { cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt"); - cNtriggers = ReadReg ("fc7_daq_stat.fast_command_block.trigger_in_counter"); + cNtriggers = ReadReg ("fc7_daq_stat.fast_command_block.trigger_in_counter"); cNtriggers_prev = cNtriggers; uint32_t cNWords_prev = cNWords; uint32_t cReadoutReq = ReadReg ("fc7_daq_stat.readout_block.general.readout_req"); - - cCounter = 0 ; + + cCounter = 0 ; while (cReadoutReq == 0 && !pFailed ) { if (!pWait) { @@ -898,9 +1022,9 @@ namespace Ph2_HwInterface { /*if( cNWords == cNWords_prev && cCounter > 100 && cNtriggers != cNtriggers_prev ) { - pFailed = true; - LOG (INFO) << BOLDRED << "Warning!! Read-out has stopped responding after receiving " << +cNtriggers << " triggers!! Read back " << +cNWords << " from FC7." << RESET ; - + pFailed = true; + LOG (INFO) << BOLDRED << "Warning!! Read-out has stopped responding after receiving " << +cNtriggers << " triggers!! Read back " << +cNWords << " from FC7." << RESET ; + } else*/ if( cNtriggers == cNtriggers_prev && cCounter > 0 ) @@ -914,8 +1038,9 @@ namespace Ph2_HwInterface { } cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt"); - if (pBoard->getEventType() == EventType::VR) + if (pBoard->getEventType() == EventType::VR and fFirwmareChipType != ChipType::MPA) { + cNEvents = cNWords / computeEventSize (pBoard); if ( (cNWords % computeEventSize (pBoard) ) != 0) { pFailed = true; @@ -936,7 +1061,6 @@ namespace Ph2_HwInterface { } else pData = ReadBlockRegValue ("fc7_daq_ctrl.readout_block.readout_fifo", cNWords); - } else if(!pFailed) { @@ -958,8 +1082,8 @@ namespace Ph2_HwInterface { } std::this_thread::sleep_for (std::chrono::milliseconds (10) ); cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt"); - cNEventsAvailable = (uint32_t) cNWords / cEventSize; - } + cNEventsAvailable = (uint32_t) cNWords / cEventSize; + } std::vector<uint32_t> event_data; if (fIsDDR3Readout) { @@ -971,7 +1095,7 @@ namespace Ph2_HwInterface { } else { event_data = ReadBlockRegValue ("fc7_daq_ctrl.readout_block.readout_fifo", cNEventsAvailable*cEventSize); } - + pData.insert (pData.end(), event_data.begin(), event_data.end() ); cNEvents += cNEventsAvailable; @@ -982,22 +1106,21 @@ namespace Ph2_HwInterface { { pData.clear(); - LOG(INFO) << BOLDRED << "Re-starting the run and resetting the readout" << RESET; - + LOG(INFO) << BOLDRED << "Re-starting the run and resetting the readout" << RESET; + this->Stop(); std::this_thread::sleep_for (std::chrono::milliseconds (500) ); LOG(INFO) << BOLDGREEN << " ... Run Stopped, current trigger FSM state: " << +ReadReg ("fc7_daq_stat.fast_command_block.general.fsm_state") << RESET; - + this->Start(); std::this_thread::sleep_for (std::chrono::milliseconds (500) ); LOG(INFO) << BOLDGREEN << " ... Run Started, current trigger FSM state: " << +ReadReg ("fc7_daq_stat.fast_command_block.general.fsm_state") << RESET; - LOG (INFO) << BOLDRED << " ... trying to read data again .... " << RESET ; + LOG (INFO) << BOLDRED << " ... trying to read data again .... " << RESET ; cNEvents = this->ReadData(pBoard, pBreakTrigger, pData, pWait); } if (fSaveToFile) - fFileHandler->set (pData); - + fFileHandler->set (pData); //need to return the number of events read return cNEvents; } @@ -1075,11 +1198,14 @@ namespace Ph2_HwInterface { this->ResetReadout(); this->ReadNEvents (pBoard, pNEvents, pData); - } + } if (fSaveToFile) - fFileHandler->set (pData); - } + { + + fFileHandler->set (pData); + } +} /** compute the block size according to the number of CBC's on this board * this will have to change with a more generic FW */ @@ -1087,12 +1213,23 @@ namespace Ph2_HwInterface { { uint32_t cNFe = pBoard->getNFe(); uint32_t cNCbc = 0; + uint32_t cNMPA = 0; + uint32_t cNSSA = 0; uint32_t cNEventSize32 = 0; for (const auto& cFe : pBoard->fModuleVector) + { cNCbc += cFe->getNCbc(); - - cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3; + cNMPA += cFe->getNMPA(); + cNSSA += cFe->getNSSA(); + } + if (cNCbc>0) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3; + if (cNMPA>0) cNEventSize32 = 32*10;//cant do this + if (cNCbc>0 && cNMPA>0) + { + LOG(INFO) << "Not configurable for multiple chips"; + exit (1); + } if (fIsDDR3Readout) { uint32_t cNEventSize32_divided_by_8 = ((cNEventSize32 >> 3) << 3); @@ -1100,7 +1237,7 @@ namespace Ph2_HwInterface { cNEventSize32 = cNEventSize32_divided_by_8 + 8; } } - + return cNEventSize32; } @@ -1133,7 +1270,7 @@ namespace Ph2_HwInterface { //TODO: check what to do with fFMCid and if I need it! // this is clearly for addressing individual CBCs, have to see how to deal with broadcast commands - void D19cFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void D19cFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pReadBack, @@ -1145,7 +1282,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( 0 << 28 ) | ( pFeId << 24 ) | ( pCbcId << 20 ) | ( pReadBack << 19 ) | ( pUseMask << 18 ) | ( (pRegItem.fPage ) << 17 ) | ( ( !pWrite ) << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue); } - void D19cFWInterface::EncodeReg (const CbcRegItem& pRegItem, + void D19cFWInterface::EncodeReg (const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -1164,7 +1301,7 @@ namespace Ph2_HwInterface { } } - void D19cFWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void D19cFWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pReadBack, @@ -1176,7 +1313,7 @@ namespace Ph2_HwInterface { } - void D19cFWInterface::DecodeReg ( CbcRegItem& pRegItem, + void D19cFWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, @@ -1248,7 +1385,7 @@ namespace Ph2_HwInterface { //reset the I2C controller WriteReg ("fc7_daq_ctrl.command_processor_block.i2c.control.reset_fifos", 0x1); usleep (10); - + try { WriteBlockReg ( "fc7_daq_ctrl.command_processor_block.i2c.command_fifo", pVecSend ); @@ -1357,7 +1494,6 @@ namespace Ph2_HwInterface { else throw Exception ( "Too many CBC readback errors - no functional I2C communication. Check the Setup" ); } - return cSuccess; } @@ -1709,6 +1845,489 @@ namespace Ph2_HwInterface { return false; } + void D19cFWInterface::PSInterfaceBoard_SendI2CCommand(uint32_t slave_id,uint32_t board_id,uint32_t read,uint32_t register_address, uint32_t data) + { + + std::chrono::milliseconds cWait( 10 ); + std::chrono::milliseconds cShort( 1 ); + + uint32_t shifted_command_type = 1 << 31; + uint32_t shifted_word_id_0 = 0; + uint32_t shifted_slave_id = slave_id << 21; + uint32_t shifted_board_id = board_id << 20; + uint32_t shifted_read = read << 16; + uint32_t shifted_register_address = register_address; + + uint32_t shifted_word_id_1 = 1<<26; + uint32_t shifted_data = data; + + + uint32_t word_0 = shifted_command_type + shifted_word_id_0 + shifted_slave_id + shifted_board_id + shifted_read + shifted_register_address; + uint32_t word_1 = shifted_command_type + shifted_word_id_1 + shifted_data; + + + WriteReg( "fc7_daq_ctrl.command_processor_block.i2c.command_fifo", word_0); + std::this_thread::sleep_for( cShort ); + WriteReg( "fc7_daq_ctrl.command_processor_block.i2c.command_fifo", word_1); + std::this_thread::sleep_for( cShort ); + + int readempty = ReadReg ("fc7_daq_stat.command_processor_block.i2c.reply_fifo.empty"); + while (readempty > 0) + { + std::this_thread::sleep_for( cShort ); + readempty = ReadReg ("fc7_daq_stat.command_processor_block.i2c.reply_fifo.empty"); + } + + int reply = ReadReg ("fc7_daq_ctrl.command_processor_block.i2c.mpa_ssa_i2c_reply"); + int reply_err = ReadReg ("fc7_daq_ctrl.command_processor_block.i2c.mpa_ssa_i2c_reply.err"); + int reply_data = ReadReg ("fc7_daq_ctrl.command_processor_block.i2c.mpa_ssa_i2c_reply.data"); + + if (reply_err == 1) LOG(ERROR) << "Error code: "<< std::hex << reply_data << std::dec; + // print "ERROR! Error flag is set to 1. The data is treated as the error code." + //elif reply_slave_id != slave_id: + // print "ERROR! Slave ID doesn't correspond to the one sent" + //elif reply_board_id != board_id: + // print "ERROR! Board ID doesn't correspond to the one sent" + + else + { + if (read == 1) LOG (DEBUG) << "Data that was read is: "<< reply_data; + else LOG (DEBUG) << "Successful write transaction" ; + } + } + + void D19cFWInterface::PSInterfaceBoard_ConfigureI2CMaster(uint32_t pEnabled = 1, uint32_t pFrequency = 4) + { + // wait for all commands to be executed + std::chrono::milliseconds cWait( 100 ); + while (!ReadReg("fc7_daq_stat.command_processor_block.i2c.command_fifo.empty")) { + std::this_thread::sleep_for( cWait ); + } + + if( pEnabled > 0) LOG (INFO) << "Enabling the MPA SSA Board I2C master"; + else LOG (INFO) << "Disabling the MPA SSA Board I2C master"; + + // setting the values + WriteReg( "fc7_daq_cnfg.physical_interface_block.i2c.master_en", int(not pEnabled) ); + WriteReg( "fc7_daq_cnfg.mpa_ssa_board_block.i2c_master_en", pEnabled); + WriteReg( "fc7_daq_cnfg.mpa_ssa_board_block.i2c_freq", pFrequency); + + std::this_thread::sleep_for( cWait ); + + // resetting the fifos and the board + WriteReg( "fc7_daq_ctrl.command_processor_block.i2c.control.reset", 1); + WriteReg( "fc7_daq_ctrl.command_processor_block.i2c.control.reset_fifos", 1); + WriteReg( "fc7_daq_ctrl.mpa_ssa_board_block.reset", 1); + std::this_thread::sleep_for( cWait ); + } + + + void D19cFWInterface::PSInterfaceBoard_PowerOn( uint8_t mpaid , uint8_t ssaid ) + { + + uint32_t val = (mpaid << 5) + (ssaid << 1); + uint32_t read = 1; + uint32_t write = 0; + uint32_t SLOW = 2; + uint32_t i2cmux = 0; + uint32_t pcf8574 = 1; + uint32_t dac7678 = 4; + uint32_t powerenable = 2; + + PSInterfaceBoard_SetSlaveMap(); + + LOG(INFO) << "Interface Board Power ON"; + + PSInterfaceBoard_ConfigureI2CMaster(1, SLOW); + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x02); + PSInterfaceBoard_SendI2CCommand(powerenable, 0, write, 0, 0x00); + PSInterfaceBoard_ConfigureI2CMaster(0, SLOW); + + } + + + + void D19cFWInterface::PSInterfaceBoard_PowerOff() + { + + uint32_t read = 1; + uint32_t write = 0; + uint32_t SLOW = 2; + uint32_t i2cmux = 0; + uint32_t pcf8574 = 1; + uint32_t dac7678 = 4; + uint32_t powerenable = 2; + + PSInterfaceBoard_SetSlaveMap(); + + LOG(INFO) << "Interface Board Power OFF"; + + PSInterfaceBoard_ConfigureI2CMaster(1, SLOW); + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x02); + PSInterfaceBoard_SendI2CCommand(powerenable, 0, write, 0, 0x01); + PSInterfaceBoard_ConfigureI2CMaster(0, SLOW); + + } + + void D19cFWInterface::PSInterfaceBoard_PowerOn_MPA(float VDDPST , float DVDD , float AVDD , float VBG , uint8_t mpaid , uint8_t ssaid ) + { + + uint32_t read = 1; + uint32_t write = 0; + uint32_t SLOW = 2; + uint32_t i2cmux = 0; + uint32_t pcf8574 = 1; + uint32_t dac7678 = 4; + uint32_t powerenable = 2; + std::chrono::milliseconds cWait( 1500 ); + + PSInterfaceBoard_SetSlaveMap(); + PSInterfaceBoard_ConfigureI2CMaster(1,SLOW); + + float Vc = 0.0003632813; + + LOG(INFO) << "mpa vdd on" ; + + float Vlimit = 1.32; + if (VDDPST > Vlimit) VDDPST = Vlimit; + float diffvoltage = 1.5 - VDDPST; + uint32_t setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x34, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + LOG(INFO) << "mpa vddD on"; + Vlimit = 1.2; + if (DVDD > Vlimit) DVDD = Vlimit; + diffvoltage = 1.5 - DVDD; + setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x30, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + LOG(INFO) << "mpa vddA on"; + Vlimit = 1.32; + if (AVDD > Vlimit) AVDD = Vlimit; + diffvoltage = 1.5 - AVDD; + setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01) ; // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x32, setvoltage) ; // tx to DAC C + std::this_thread::sleep_for( cWait ); + + LOG(INFO) << "mpa VBG on"; + Vlimit = 0.5; + if (VBG > Vlimit) VBG = Vlimit; + float Vc2 = 4095/1.5; + setvoltage = int(round(VBG * Vc2)); + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x36, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + + LOG(INFO) << "mpa enable"; + uint32_t val2 = (mpaid << 5) + 16; // reset bit for MPA + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x02); // route to 2nd PCF8574 + PSInterfaceBoard_SendI2CCommand(pcf8574, 0, write, 0, val2); // set reset bit + std::this_thread::sleep_for( cWait ); + + // disable the i2c master at the end (first set the mux to the chip + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x04); + PSInterfaceBoard_ConfigureI2CMaster(0); + } + + + void D19cFWInterface::PSInterfaceBoard_PowerOff_MPA(uint8_t mpaid , uint8_t ssaid ) + { + uint32_t write = 0; + uint32_t SLOW = 2; + uint32_t i2cmux = 0; + uint32_t pcf8574 = 1; // MPA and SSA address and reset 8 bit port + uint32_t dac7678 = 4; + uint32_t powerenable = 2; + float Vc = 0.0003632813; // V/Dac step + std::chrono::milliseconds cWait( 1500 ); + + PSInterfaceBoard_SetSlaveMap(); + PSInterfaceBoard_ConfigureI2CMaster(1, SLOW); + + LOG(INFO) << "mpa disable"; + uint32_t val = (mpaid << 5) + (ssaid << 1); // reset bit for MPA + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x02); // route to 2nd PCF8574 + PSInterfaceBoard_SendI2CCommand(pcf8574, 0, write, 0, val); // set reset bit + std::this_thread::sleep_for( cWait ); + + + LOG(INFO) << "mpa VBG off"; + uint32_t setvoltage = 0; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x36, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + + LOG(INFO) << "mpa vddA off"; + float diffvoltage = 1.5; + setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x32, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + LOG(INFO) << "mpa vddA off"; + diffvoltage = 1.5; + setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x30, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + + LOG(INFO) << "mpa vdd off"; + diffvoltage = 1.5; + setvoltage = int(round(diffvoltage / Vc)); + if (setvoltage > 4095) setvoltage = 4095; + setvoltage = setvoltage << 4; + PSInterfaceBoard_SendI2CCommand(i2cmux, 0, write, 0, 0x01); // to SCO on PCA9646 + PSInterfaceBoard_SendI2CCommand(dac7678, 0, write, 0x34, setvoltage); // tx to DAC C + std::this_thread::sleep_for( cWait ); + } + + void D19cFWInterface::PSInterfaceBoard_SetSlaveMap() + { + + std::vector< std::vector<uint32_t> > i2c_slave_map; + i2c_slave_map.push_back({0b1110000, 0, 1, 1, 0, 1}); + i2c_slave_map.push_back({0b0100000, 0, 1, 1, 0, 1}); + i2c_slave_map.push_back({0b0100100, 0, 1, 1, 0, 1}); + i2c_slave_map.push_back({0b0010100, 0, 2, 3, 0, 1}); + i2c_slave_map.push_back({0b1001000, 1, 2, 2, 0, 0}); + i2c_slave_map.push_back({0b1000000, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000001, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000010, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000100, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000101, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000110, 1, 2, 2, 0, 1}); + i2c_slave_map.push_back({0b1000000, 2, 1, 1, 1, 0}); + i2c_slave_map.push_back({0b0100000, 2, 1, 1, 1, 0}); + i2c_slave_map.push_back({0b0000000, 0, 1, 1, 0, 0}); + i2c_slave_map.push_back({0b0000000, 0, 1, 1, 0, 0}); + i2c_slave_map.push_back({0b1011111, 1, 1, 1, 1, 0}); + + + LOG(INFO) << "Updating the Slave ID Map (mpa ssa board) "; + + for (int ism = 0; ism < 16; ism++) + { + uint32_t shifted_i2c_address = i2c_slave_map[ism][0]<<25; + uint32_t shifted_register_address_nbytes = i2c_slave_map[ism][1]<<6; + uint32_t shifted_data_wr_nbytes = i2c_slave_map[ism][2]<<4; + uint32_t shifted_data_rd_nbytes = i2c_slave_map[ism][3]<<2; + uint32_t shifted_stop_for_rd_en = i2c_slave_map[ism][4]<<1; + uint32_t shifted_nack_en = i2c_slave_map[ism][5]<<0; + uint32_t final_command = shifted_i2c_address + shifted_register_address_nbytes + shifted_data_wr_nbytes + shifted_data_rd_nbytes + shifted_stop_for_rd_en + shifted_nack_en; + + std::string curreg = "fc7_daq_cnfg.mpa_ssa_board_block.slave_"+std::to_string(ism)+"_config"; + WriteReg(curreg, final_command); + } + + } + + std::vector<uint16_t> D19cFWInterface::ReadoutCounters_MPA(uint32_t raw_mode_en) + { + //Apparently not a thing now? + WriteReg("fc7_daq_cnfg.physical_interface_block.slvs_debug.raw_mode_en", raw_mode_en); + uint32_t mpa_counters_ready = ReadReg("fc7_daq_stat.physical_interface_block.slvs_debug.ps_counters_ready"); + std::chrono::milliseconds cWait( 10 ); + std::vector<uint16_t> count(2040, 0); + //std::cout<<"MCR "<<mpa_counters_ready<<std::endl; + PS_Start_counters_read(); + uint32_t timeout = 0; + while ((mpa_counters_ready == 0) & (timeout < 50)) + { + std::this_thread::sleep_for( cWait ); + mpa_counters_ready = ReadReg("fc7_daq_stat.physical_interface_block.slvs_debug.ps_counters_ready"); + //std::cout<<"MCR iwh"<<mpa_counters_ready<<std::endl; + timeout += 1; + } + if (timeout >= 50) + { + std::cout<<"fail"<<std::endl; + return count; + } + + if (raw_mode_en == 1) + { + uint32_t cycle = 0; + for (int i=0; i<20000;i++) + { + uint32_t fifo1_word = ReadReg("fc7_daq_ctrl.physical_interface_block.slvs_debug.fifo1_data"); + uint32_t fifo2_word = ReadReg("fc7_daq_ctrl.physical_interface_block.slvs_debug.fifo2_data"); + + uint32_t line1 = (fifo1_word&0x0000FF)>>0; //to_number(fifo1_word,8,0) + uint32_t line2 = (fifo1_word&0x00FF00)>>8; // to_number(fifo1_word,16,8) + uint32_t line3 = (fifo1_word&0xFF0000)>>16; // to_number(fifo1_word,24,16) + + uint32_t line4 = (fifo2_word&0x0000FF)>>0; //to_number(fifo2_word,8,0) + uint32_t line5 = (fifo2_word&0x00FF00)>>8; // to_number(fifo2_word,16,8) + + if (((line1 & 0b10000000) == 128) && ((line4 & 0b10000000) == 128)) + { + uint32_t temp = ((line2 & 0b00100000) << 9) | ((line3 & 0b00100000) << 8) | ((line4 & 0b00100000) << 7) | ((line5 & 0b00100000) << 6) | ((line1 & 0b00010000) << 6) | ((line2 & 0b00010000) << 5) | ((line3 & 0b00010000) << 4) | ((line4 & 0b00010000) << 3) | ((line5 & 0b10000000) >> 1) | ((line1 & 0b01000000) >> 1) | ((line2 & 0b01000000) >> 2) | ((line3 & 0b01000000) >> 3) | ((line4 & 0b01000000) >> 4) | ((line5 & 0b01000000) >> 5) | ((line1 & 0b00100000) >> 5); + if (temp != 0) { + count[cycle] = temp - 1; + cycle += 1; + } + } + } + } else { + ReadReg("fc7_daq_ctrl.physical_interface_block.slvs_debug.fifo2_data"); + for (int i=0; i<2040;i++) + { + //std::chrono::milliseconds cWait( 100 ); + count[i] = ReadReg("fc7_daq_ctrl.physical_interface_block.slvs_debug.fifo2_data") - 1; + //std::cout<<i<<" "<<count[i]<<std::endl; + } + } + + std::this_thread::sleep_for( cWait ); + mpa_counters_ready = ReadReg("fc7_daq_stat.physical_interface_block.slvs_debug.ps_counters_ready"); + return count; + } + + + + + void D19cFWInterface::PS_Open_shutter(uint32_t duration ) + { + Compose_fast_command(duration,0,1,0,0); + } + + void D19cFWInterface::PS_Close_shutter(uint32_t duration ) + { + Compose_fast_command(duration,0,0,0,1); + } + + void D19cFWInterface::PS_Clear_counters(uint32_t duration ) + { + Compose_fast_command(duration,0,1,0,1); + } + void D19cFWInterface::PS_Start_counters_read(uint32_t duration ) + { + Compose_fast_command(duration,1,0,0,1); + } + + void D19cFWInterface::Pix_write_MPA(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel,uint32_t data) + { + uint8_t cWriteAttempts = 0; + bool rep; + + RegItem rowreg =cRegItem; + rowreg.fAddress = ((row & 0x0001f) << 11 ) | ((cRegItem.fAddress & 0x000f) << 7 ) | (pixel & 0xfffffff); + rowreg.fValue = data; + std::vector<uint32_t> cVecReq; + cVecReq.clear(); + this->EncodeReg (rowreg, cMPA->getFeId(), cMPA->getMPAId(), cVecReq, true, true); + this->WriteCbcBlockReg (cVecReq, cWriteAttempts, false); + } + + uint32_t D19cFWInterface::Pix_read_MPA(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel) + { + uint8_t cWriteAttempts = 0; + uint32_t rep; + + RegItem rowreg =cRegItem; + rowreg.fValue = 0x00; + rowreg.fAddress = ((row & 0x0001f) << 11 ) | ((cRegItem.fAddress & 0x000f) << 7 ) | (pixel & 0xfffffff); + + + + std::vector<uint32_t> cVecReq; + cVecReq.clear(); + + + + this->EncodeReg (rowreg, cMPA->getFeId(), cMPA->getMPAId(), cVecReq, true, false); + this->ReadCbcBlockReg (cVecReq); + //for (auto iiii : cVecReq)std::cout<<iiii<<std::endl; + + + //std::chrono::milliseconds cShort( 1 ); + //uint32_t readempty = ReadReg ("fc7_daq_stat.command_processor_block.i2c.reply_fifo.empty"); + //while (readempty == 0) + // { + // std::cout<<"RE:"<<readempty<<std::endl; + // //ReadStatus() + // std::this_thread::sleep_for( cShort ); + // readempty = ReadReg ("fc7_daq_stat.command_processor_block.i2c.reply_fifo.empty"); + // } + //uint32_t forcedreply = ReadReg("fc7_daq_ctrl.command_processor_block.i2c.reply_fifo"); + //rep = ReadReg ("fc7_daq_ctrl.command_processor_block.i2c.mpa_ssa_i2c_reply.data"); + + return cVecReq[0]; + } + + + void D19cFWInterface::Compose_fast_command(uint32_t duration ,uint32_t resync_en ,uint32_t l1a_en ,uint32_t cal_pulse_en ,uint32_t bc0_en ) + { + uint32_t encode_resync = resync_en<<16; + uint32_t encode_cal_pulse = cal_pulse_en<<17; + uint32_t encode_l1a = l1a_en<<18; + uint32_t encode_bc0 = bc0_en<<19; + uint32_t encode_duration = duration<<28; + + uint32_t final_command = encode_resync + encode_l1a + encode_cal_pulse + encode_bc0 + encode_duration; + + WriteReg("fc7_daq_ctrl.fast_command_block.control", final_command); + + } + + + + void D19cFWInterface::Align_out() + { + int cCounter = 0; + int cMaxAttempts = 10; + + uint32_t hardware_ready = 0; + + while (hardware_ready < 1) + { + if (cCounter++ > cMaxAttempts) + { + uint32_t delay5_done_cbc0 = ReadReg ("fc7_daq_stat.physical_interface_block.delay5_done_cbc0"); + uint32_t serializer_done_cbc0 = ReadReg ("fc7_daq_stat.physical_interface_block.serializer_done_cbc0"); + uint32_t bitslip_done_cbc0 = ReadReg ("fc7_daq_stat.physical_interface_block.bitslip_done_cbc0"); + + uint32_t delay5_done_cbc1 = ReadReg ("fc7_daq_stat.physical_interface_block.delay5_done_cbc1"); + uint32_t serializer_done_cbc1 = ReadReg ("fc7_daq_stat.physical_interface_block.serializer_done_cbc1"); + uint32_t bitslip_done_cbc1 = ReadReg ("fc7_daq_stat.physical_interface_block.bitslip_done_cbc1"); + LOG (INFO) << "Clock Data Timing tuning failed after " << cMaxAttempts << " attempts with value - aborting!"; + LOG (INFO) << "Debug Info CBC0: delay5 done: " << delay5_done_cbc0 << ", serializer_done: " << serializer_done_cbc0 << ", bitslip_done: " << bitslip_done_cbc0; + LOG (INFO) << "Debug Info CBC1: delay5 done: " << delay5_done_cbc1 << ", serializer_done: " << serializer_done_cbc1 << ", bitslip_done: " << bitslip_done_cbc1; + uint32_t tuning_state_cbc0 = ReadReg("fc7_daq_stat.physical_interface_block.state_tuning_cbc0"); + uint32_t tuning_state_cbc1 = ReadReg("fc7_daq_stat.physical_interface_block.state_tuning_cbc1"); + LOG(INFO) << "tuning state cbc0: " << tuning_state_cbc0 << ", cbc1: " << tuning_state_cbc1; + exit (1); + } + + this->CbcFastReset(); + usleep (10); + // reset the timing tuning + WriteReg("fc7_daq_ctrl.physical_interface_block.control.cbc3_tune_again", 0x1); + + std::this_thread::sleep_for (std::chrono::milliseconds (100) ); + hardware_ready = ReadReg ("fc7_daq_stat.physical_interface_block.hardware_ready"); + } + } } diff --git a/HWInterface/D19cFWInterface.h b/HWInterface/D19cFWInterface.h old mode 100755 new mode 100644 index 7857397e2b5d9cd701176078d0b30c8438805b63..af0e3acd14ff00de4f5fce9b6f2cf012c945b06d --- a/HWInterface/D19cFWInterface.h +++ b/HWInterface/D19cFWInterface.h @@ -46,23 +46,25 @@ namespace Ph2_HwInterface { FileHandler* fFileHandler ; uint32_t fBroadcastCbcId; uint32_t fNCbc; + uint32_t fNMPA; + uint32_t fFMCId; // number of chips and hybrids defined in firmware (compiled for) int fFWNHybrids; int fFWNChips; ChipType fFirwmareChipType; - bool fCBC3Emulator; + bool fChipEmulator; bool fIsDDR3Readout; bool fDDR3Calibrated; uint32_t fDDR3Offset; // i2c version of master - uint32_t fI2CVersion; + uint32_t fI2CVersion; const uint32_t SINGLE_I2C_WAIT = 200; //used for 1MHz I2C - // some useful stuff - int fResetAttempts; + // some useful stuff + int fResetAttempts; public: /*! * @@ -197,7 +199,8 @@ namespace Ph2_HwInterface { ChipType getChipType(uint32_t pChipCode); // set i2c address table depending on the hybrid void SetI2CAddressTable(); - + // alignement + void Align_out(); //template to copy every nth element out of a vector to another vector template<class in_it, class out_it> @@ -239,6 +242,7 @@ namespace Ph2_HwInterface { public: + /////////////////////////////////////////////////////// // CBC Methods // ///////////////////////////////////////////////////// @@ -250,10 +254,10 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg (const CbcRegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void EncodeReg (const CbcRegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void BCEncodeReg (const CbcRegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; - void DecodeReg ( CbcRegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; + void EncodeReg (const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void EncodeReg (const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void BCEncodeReg (const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pReadBack, bool pWrite ) override; + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; bool WriteCbcBlockReg ( std::vector<uint32_t>& pVecReg, uint8_t& pWriteAttempts, bool pReadback) override; @@ -278,6 +282,31 @@ namespace Ph2_HwInterface { bool Measure2SOccupancy(uint32_t pNEvents, uint8_t **&pErrorCounters, uint8_t ***&pChannelCounters); void Manage2SCountersMemory(uint8_t **&pErrorCounters, uint8_t ***&pChannelCounters, bool pAllocate); + /////////////////////////////////////////////////////// + // MPA/SSA Methods // + ///////////////////////////////////////////////////// + + + + void PSInterfaceBoard_SendI2CCommand(uint32_t slave_id,uint32_t board_id,uint32_t read,uint32_t register_address, uint32_t data); + void PSInterfaceBoard_ConfigureI2CMaster(uint32_t pEnabled, uint32_t pFrequency); + void PSInterfaceBoard_SetSlaveMap(); + void PSInterfaceBoard_PowerOn(uint8_t mpaid = 0 , uint8_t ssaid = 0 ); + void PSInterfaceBoard_PowerOff(); + void PSInterfaceBoard_PowerOn_MPA(float VDDPST = 1.25, float DVDD = 1.2, float AVDD = 1.25, float VBG = 0.3, uint8_t mpaid = 0 , uint8_t ssaid = 0); + void PSInterfaceBoard_PowerOff_MPA(uint8_t mpaid = 0 , uint8_t ssaid = 0 ); + + void Pix_write_MPA(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel,uint32_t data); + uint32_t Pix_read_MPA(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel); + std::vector<uint16_t> ReadoutCounters_MPA(uint32_t raw_mode_en = 0); + + void Compose_fast_command(uint32_t duration = 0,uint32_t resync_en = 0,uint32_t l1a_en = 0,uint32_t cal_pulse_en = 0,uint32_t bc0_en = 0); + void PS_Open_shutter(uint32_t duration = 0); + void PS_Close_shutter(uint32_t duration = 0); + void PS_Clear_counters(uint32_t duration = 0); + void PS_Start_counters_read(uint32_t duration = 0); + + /////////////////////////////////////////////////////// // FPGA CONFIG // ///////////////////////////////////////////////////// diff --git a/HWInterface/GlibFWInterface.cc b/HWInterface/GlibFWInterface.cc index 073bc470fd93d9182d830bf2fca99bcff1180d76..85d5518aed639ce21e9a07a7c939737ba30034a4 100644 --- a/HWInterface/GlibFWInterface.cc +++ b/HWInterface/GlibFWInterface.cc @@ -471,7 +471,7 @@ namespace Ph2_HwInterface { // CBC Methods // ///////////////////////////////////////////////////// - void GlibFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void GlibFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, @@ -485,7 +485,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( pCbcId >> 3 ) << 21 | ( pCbcId & 7 ) << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void GlibFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void GlibFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -497,7 +497,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( pFeId << 21 | pCbcId << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void GlibFWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void GlibFWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, @@ -510,7 +510,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( cCbcId >> 3 ) << 21 | ( cCbcId & 7 ) << 17 | pRegItem.fPage << 16 | pRegItem.fAddress << 8 | uValue ); } - void GlibFWInterface::DecodeReg ( CbcRegItem& pRegItem, + void GlibFWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, diff --git a/HWInterface/GlibFWInterface.h b/HWInterface/GlibFWInterface.h index a1ca9456c8547033bc5a7030e40958a71d0b903c..cba093dfbee6633a7e515b5d410320b6ed6a818d 100644 --- a/HWInterface/GlibFWInterface.h +++ b/HWInterface/GlibFWInterface.h @@ -186,7 +186,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead = false, bool pWrite = false ) override; /*!< Encode a/several word(s) readable for a Cbc*/ @@ -195,7 +195,7 @@ namespace Ph2_HwInterface { * \param pRegItem : RegItem containing infos (name, adress, value...) about the register to write * \param pVecReq : Vector to stack the encoded words */ - void BCEncodeReg ( const CbcRegItem& pRegItem, + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead = false, @@ -206,7 +206,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -218,7 +218,7 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pWord : variable to put the decoded word */ - void DecodeReg ( CbcRegItem& pRegItem, + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, diff --git a/HWInterface/ICFc7FWInterface.cc b/HWInterface/ICFc7FWInterface.cc index aad56df2be7afa5d27b82067bb85280ce3c7a3a8..26cef25bf0e978eed70df9b16a6c323714c4d509 100644 --- a/HWInterface/ICFc7FWInterface.cc +++ b/HWInterface/ICFc7FWInterface.cc @@ -365,7 +365,7 @@ namespace Ph2_HwInterface { ///////////////////////////////////////////////////// // this is clearly for addressing individual CBCs, have to see how to deal with broadcast commands - void ICFc7FWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void ICFc7FWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, @@ -374,7 +374,7 @@ namespace Ph2_HwInterface { //use fBroadcastCBCId for broadcast commands pVecReq.push_back ( ( fFMCId << 28 ) | ( pCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICFc7FWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void ICFc7FWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -385,7 +385,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( pFeId << 28 ) | ( pCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICFc7FWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void ICFc7FWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, @@ -395,7 +395,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( fFMCId << 28 ) | ( fBroadcastCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICFc7FWInterface::DecodeReg ( CbcRegItem& pRegItem, + void ICFc7FWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, @@ -443,7 +443,7 @@ namespace Ph2_HwInterface { } //here i create a dummy reg item for decoding so I can find if 1 cFailed - CbcRegItem cItem; + RegItem cItem; //uint8_t cCbcId; //bool cRead; diff --git a/HWInterface/ICFc7FWInterface.h b/HWInterface/ICFc7FWInterface.h index 5f39d10ac9e143bab9780f38eae8ec353aeb9ab1..0c0f79d96fcf07be3ed3f19b3a09b2f4cbb72fbd 100644 --- a/HWInterface/ICFc7FWInterface.h +++ b/HWInterface/ICFc7FWInterface.h @@ -205,10 +205,10 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void BCEncodeReg ( const CbcRegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; - void DecodeReg ( CbcRegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; bool WriteCbcBlockReg ( std::vector<uint32_t>& pVecReg, uint8_t& pWriteAttempts, bool pReadback) override; diff --git a/HWInterface/ICGlibFWInterface.cc b/HWInterface/ICGlibFWInterface.cc index 29aa4d03d6acd33bf0eec0d10d95977e1c5f9df6..40400b2c7444074406b615b37a6c9b2560f2350e 100644 --- a/HWInterface/ICGlibFWInterface.cc +++ b/HWInterface/ICGlibFWInterface.cc @@ -363,7 +363,7 @@ namespace Ph2_HwInterface { ///////////////////////////////////////////////////// // this is clearly for addressing individual CBCs, have to see how to deal with broadcast commands - void ICGlibFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void ICGlibFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, @@ -372,7 +372,7 @@ namespace Ph2_HwInterface { //use fBroadcastCBCId for broadcast commands pVecReq.push_back ( ( fFMCId << 28 ) | ( pCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICGlibFWInterface::EncodeReg ( const CbcRegItem& pRegItem, + void ICGlibFWInterface::EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, @@ -383,7 +383,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( pFeId << 28 ) | ( pCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICGlibFWInterface::BCEncodeReg ( const CbcRegItem& pRegItem, + void ICGlibFWInterface::BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, @@ -393,7 +393,7 @@ namespace Ph2_HwInterface { pVecReq.push_back ( ( fFMCId << 28 ) | ( fBroadcastCbcId << 24 ) | ( pRead << 21 ) | ( pWrite << 20 ) | ( pRegItem.fPage << 16 ) | ( pRegItem.fAddress << 8 ) | pRegItem.fValue ); } - void ICGlibFWInterface::DecodeReg ( CbcRegItem& pRegItem, + void ICGlibFWInterface::DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, @@ -441,7 +441,7 @@ namespace Ph2_HwInterface { } //here i create a dummy reg item for decoding so I can find if 1 cFailed - CbcRegItem cItem; + RegItem cItem; //uint8_t cCbcId; //bool cRead; diff --git a/HWInterface/ICGlibFWInterface.h b/HWInterface/ICGlibFWInterface.h index 9c2a0a6bee4e86a6501bc8b14554043ce141701a..07daca33c4446f5edcab2a9c5f1da01b6e33e7db 100644 --- a/HWInterface/ICGlibFWInterface.h +++ b/HWInterface/ICGlibFWInterface.h @@ -205,10 +205,10 @@ namespace Ph2_HwInterface { * \param pCbcId : Id of the Cbc to work with * \param pVecReq : Vector to stack the encoded words */ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void EncodeReg ( const CbcRegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ - void BCEncodeReg ( const CbcRegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; - void DecodeReg ( CbcRegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; /*!< Encode a/several word(s) readable for a Cbc*/ + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) override; + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, bool& pFailed ) override; bool WriteCbcBlockReg ( std::vector<uint32_t>& pVecReg, uint8_t& pWriteAttempts, bool pReadback) override; diff --git a/HWInterface/MPAInterface.cc b/HWInterface/MPAInterface.cc index 28c2ff6bf696a366af88a47549b71abf9fcadf1d..e06fbb51ee34194987144e93b9cb09dd8d3e3abb 100644 --- a/HWInterface/MPAInterface.cc +++ b/HWInterface/MPAInterface.cc @@ -2,10 +2,9 @@ FileName : MPAInterface.cc Content : User Interface to the MPAs - Programmer : Lorenzo BIDEGAIN, Nicolas PIERRE, Georg AUZINGER + Programmer : K. nash, M. Haranko, D. Ceresa Version : 1.0 - Date of creation : 10/07/14 - Support : mail to : lorenzo.bidegain@gmail.com, nico.pierre@icloud.com + Date of creation : 5/01/18 */ @@ -18,6 +17,8 @@ namespace Ph2_HwInterface { + + MPAInterface::MPAInterface( const BeBoardFWMap& pBoardMap ) : fBoardMap( pBoardMap ), fBoardFW( nullptr ), @@ -45,7 +46,6 @@ void MPAInterface::setBoard( uint16_t pBoardIdentifier ) else { fBoardFW = i->second; - fMPAFW = dynamic_cast<MPAGlibFWInterface*>(fBoardFW); prevBoardIdentifier = pBoardIdentifier; } } @@ -56,441 +56,629 @@ void MPAInterface::setBoard( uint16_t pBoardIdentifier ) void MPAInterface::setFileHandler (FileHandler* pHandler) { - setBoard(0); - fMPAFW->setFileHandler ( pHandler); + setBoard(0); + dynamic_cast<D19cFWInterface*>(fBoardFW)->setFileHandler ( pHandler); +} + + +//Straight python port +void MPAInterface::PowerOn(float VDDPST , float DVDD , float AVDD , float VBG , uint8_t mpaid , uint8_t ssaid ) +{ + setBoard(0); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PSInterfaceBoard_PowerOn_MPA(VDDPST, DVDD, AVDD, VBG, mpaid, ssaid); } +void MPAInterface::PowerOff(uint8_t mpaid , uint8_t ssaid ) +{ + setBoard(0); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PSInterfaceBoard_PowerOff_MPA( ); +} +void MPAInterface::MainPowerOn(uint8_t mpaid , uint8_t ssaid ) +{ + setBoard(0); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PSInterfaceBoard_PowerOn( ); +} -void MPAInterface::HeaderInitMPA(int nmpa, bool lr) +void MPAInterface::MainPowerOff() { - setBoard(0); - fMPAFW->HeaderInitMPA( nmpa , lr); + setBoard(0); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PSInterfaceBoard_PowerOff( ); } +bool MPAInterface::ConfigureMPA (const MPA* pMPA, bool pVerifLoop) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + //vector to encode all the registers into + std::vector<uint32_t> cVec; + //Deal with the RegItems and encode them -void MPAInterface::ConfigureMPA(std::vector< uint32_t >* conf_upload, int conf ,int nmpa, bool lr) + MPARegMap cMPARegMap = pMPA->getRegMap(); + + for ( auto& cRegItem : cMPARegMap ) + { + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg (cRegItem.second, pMPA->getFeId(), pMPA->getMPAId(), cVec, pVerifLoop, true); +#ifdef COUNT_FLAG + fRegisterCount++; +#endif + } + + // write the registers, the answer will be in the same cVec + // the number of times the write operation has been attempted is given by cWriteAttempts + uint8_t cWriteAttempts = 0 ; + bool cSuccess = dynamic_cast<D19cFWInterface*>(fBoardFW)->WriteCbcBlockReg ( cVec, cWriteAttempts, pVerifLoop); + +#ifdef COUNT_FLAG + fTransactionCount++; +#endif + + return cSuccess; +} + + + +bool MPAInterface::WriteMPAReg ( MPA* pMPA, const std::string& pRegNode, uint8_t pValue, bool pVerifLoop ) { - setBoard(0); - fMPAFW->upload( conf_upload, conf,nmpa , lr); + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + //next, get the reg item + RegItem cRegItem = pMPA->getRegItem ( pRegNode ); + cRegItem.fValue = pValue; + + //vector for transaction + std::vector<uint32_t> cVec; + + // encode the reg specific to the FW, pVerifLoop decides if it should be read back, true means to write it + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg ( cRegItem, pMPA->getFeId(), pMPA->getMPAId(), cVec, pVerifLoop, true ); + // write the registers, the answer will be in the same cVec + // the number of times the write operation has been attempted is given by cWriteAttempts + uint8_t cWriteAttempts = 0; + bool cSuccess = dynamic_cast<D19cFWInterface*>(fBoardFW)->WriteCbcBlockReg ( cVec, cWriteAttempts, pVerifLoop ); + + //update the HWDescription object + + if (cSuccess) + pMPA->setReg ( pRegNode, pValue ); + +#ifdef COUNT_FLAG + fRegisterCount++; + fTransactionCount++; +#endif + + return cSuccess; } -void MPAInterface::SendConfig(int nummpal, int nummpar) + + + +bool MPAInterface::WriteMPAMultReg ( MPA* pMPA, const std::vector< std::pair<std::string, uint8_t> >& pVecReq, bool pVerifLoop ) { - setBoard(0); - fMPAFW->write(nummpal, nummpar); + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + std::vector<uint32_t> cVec; + + //Deal with the RegItems and encode them + RegItem cRegItem; + + for ( const auto& cReg : pVecReq ) + { + cRegItem = pMPA->getRegItem ( cReg.first ); + cRegItem.fValue = cReg.second; + + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg ( cRegItem, pMPA->getFeId(), pMPA->getMPAId(), cVec, pVerifLoop, true ); +#ifdef COUNT_FLAG + fRegisterCount++; +#endif + } + + // write the registers, the answer will be in the same cVec + // the number of times the write operation has been attempted is given by cWriteAttempts + uint8_t cWriteAttempts = 0 ; + bool cSuccess = dynamic_cast<D19cFWInterface*>(fBoardFW)->WriteCbcBlockReg ( cVec, cWriteAttempts, pVerifLoop ); + +#ifdef COUNT_FLAG + fTransactionCount++; +#endif + + // if the transaction is successfull, update the HWDescription object + if (cSuccess) + { + for ( const auto& cReg : pVecReq ) + { + cRegItem = pMPA->getRegItem ( cReg.first ); + pMPA->setReg ( cReg.first, cReg.second ); + } + } + + return cSuccess; } +uint8_t MPAInterface::ReadMPAReg ( MPA* pMPA, const std::string& pRegNode ) +{ + setBoard ( pMPA->getBeBoardIdentifier() ); + RegItem cRegItem = pMPA->getRegItem ( pRegNode ); + std::vector<uint32_t> cVecReq; -int MPAInterface::WaitTestbeam() + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg ( cRegItem, pMPA->getFeId(), pMPA->getMPAId(), cVecReq, true, false ); + dynamic_cast<D19cFWInterface*>(fBoardFW)->ReadCbcBlockReg ( cVecReq ); + + //bools to find the values of failed and read + bool cFailed = false; + bool cRead; + uint8_t cMPAId; + dynamic_cast<D19cFWInterface*>(fBoardFW)->DecodeReg ( cRegItem, cMPAId, cVecReq[0], cRead, cFailed ); + + if (!cFailed) pMPA->setReg ( pRegNode, cRegItem.fValue ); + + return cRegItem.fValue; +} + +void MPAInterface::ReadMPAMultReg ( MPA* pMPA, const std::vector<std::string>& pVecReg ) { - setBoard(0); - return fMPAFW->WaitTestbeam(); + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + std::vector<uint32_t> cVec; + + //Deal with the RegItems and encode them + RegItem cRegItem; + + for ( const auto& cReg : pVecReg ) + { + cRegItem = pMPA->getRegItem ( cReg ); + + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg ( cRegItem, pMPA->getFeId(), pMPA->getMPAId(), cVec, true, false ); +#ifdef COUNT_FLAG + fRegisterCount++; +#endif + } + + // write the registers, the answer will be in the same cVec + dynamic_cast<D19cFWInterface*>(fBoardFW)->ReadCbcBlockReg ( cVec); + +#ifdef COUNT_FLAG + fTransactionCount++; +#endif + + bool cFailed = false; + bool cRead; + uint8_t cMPAId; + //update the HWDescription object with the value I just read + uint32_t idxReadWord = 0; + + for ( const auto& cReg : pVecReg ) + //for ( const auto& cReadWord : cVec ) + { + uint32_t cReadWord = cVec[idxReadWord++]; + dynamic_cast<D19cFWInterface*>(fBoardFW)->DecodeReg ( cRegItem, cMPAId, cReadWord, cRead, cFailed ); + + // here I need to find the string matching to the reg item! + if (!cFailed) + pMPA->setReg ( cReg, cRegItem.fValue ); + } } +void MPAInterface::ReadMPA ( MPA* pMPA ) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + //vector to encode all the registers into + std::vector<uint32_t> cVec; + //helper vector to store the register names in the same order as the RegItems + std::vector<std::string> cNameVec; + //Deal with the RegItems and encode them + MPARegMap cMPARegMap = pMPA->getRegMap(); -void MPAInterface::SequencerInit(int smode,int sdur,int mem,int ibuff) + for ( auto& cRegItem : cMPARegMap ) + { + cRegItem.second.fValue = 0x00; + dynamic_cast<D19cFWInterface*>(fBoardFW)->EncodeReg (cRegItem.second, pMPA->getFeId(), pMPA->getMPAId(), cVec, true, false); + //push back the names in cNameVec for latercReg + cNameVec.push_back (cRegItem.first); +#ifdef COUNT_FLAG + fRegisterCount++; +#endif + } + + // write the registers, the answer will be in the same cVec + //bool cSuccess = dynamic_cast<D19cFWInterface*>(fBoardFW)->WriteCbcBlockReg ( cVec, pVerifLoop); + + // write the registers, the answer will be in the same cVec + dynamic_cast<D19cFWInterface*>(fBoardFW)->ReadCbcBlockReg ( cVec); + +#ifdef COUNT_FLAG + fTransactionCount++; +#endif + + bool cFailed = false; + bool cRead; + uint8_t cMPAId; + //update the HWDescription object with the value I just read + uint32_t idxReadWord = 0; + + //for ( const auto& cReg : cVec ) + for ( const auto& cReadWord : cVec ) + { + RegItem cRegItem; + std::string cName = cNameVec[idxReadWord++]; + dynamic_cast<D19cFWInterface*>(fBoardFW)->DecodeReg ( cRegItem, cMPAId, cReadWord, cRead, cFailed ); + + // here I need to find the string matching to the reg item! + if (!cFailed) + pMPA->setReg ( cName, cRegItem.fValue ); + + } + +} + +void MPAInterface::Pix_write(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel,uint32_t data) { - setBoard(0); - fMPAFW->SequencerInit(smode,sdur,mem,ibuff); + //first, identify the correct BeBoardFWInterface + setBoard ( cMPA->getBeBoardIdentifier() ); + return dynamic_cast<D19cFWInterface*>(fBoardFW)->Pix_write_MPA(cMPA,cRegItem,row, pixel, data); } -void MPAInterface::TestbeamInit(int sdur,int clock, int phase) +uint32_t MPAInterface::Pix_read(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel) { - setBoard(0); - fMPAFW->TestbeamInit(sdur,clock, phase); + //first, identify the correct BeBoardFWInterface + setBoard ( cMPA->getBeBoardIdentifier() ); + return dynamic_cast<D19cFWInterface*>(fBoardFW)->Pix_read_MPA(cMPA, cRegItem, row, pixel); } +void MPAInterface::PS_Start_counters_read(MPA* pMPA, uint32_t duration ) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Start_counters_read(duration); +} + -std::pair<std::vector<uint32_t>, std::vector<uint32_t>> MPAInterface::ReadMPAData(int buffer_num, int mpa, bool lr) +void MPAInterface::PS_Clear_counters(MPA* pMPA, uint32_t duration) { - setBoard(0); - fMPAFW->HeaderInitMPA( mpa , lr ); - return fMPAFW->ReadMPAData(buffer_num, mpa, lr); + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Clear_counters(duration); } +std::vector<uint16_t> MPAInterface::ReadoutCounters_MPA(MPA* pMPA, uint32_t raw_mode_en) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + return dynamic_cast<D19cFWInterface*>(fBoardFW)->ReadoutCounters_MPA(raw_mode_en); +} +Stubs MPAInterface::Format_stubs(std::vector<std::vector<uint8_t>> rawstubs) +{ + int j = 0; + int cycle = 0; + Stubs formstubs; + for(int i=0; i<39; i++) + { -uint32_t MPAInterface::ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ) + if ((rawstubs[0][i] & 0b10000000) == 128) + { + j = i+1; + formstubs.pos.push_back(std::vector<uint8_t>(5,0)); + formstubs.row.push_back(std::vector<uint8_t>(5,0)); + formstubs.cur.push_back(std::vector<uint8_t>(5,0)); + + + formstubs.nst.push_back(((rawstubs[1][i] & 0b10000000) >> 5) | ((rawstubs[2][i] & 0b10000000) >> 6) | ((rawstubs[3][i] & 0b10000000) >> 7)); + formstubs.pos[cycle][0] = ((rawstubs[4][i] & 0b10000000) << 0) | ((rawstubs[0][i] & 0b01000000) << 0) | ((rawstubs[1][i] & 0b01000000) >> 1) | ((rawstubs[2][i] & 0b01000000) >> 2) | ((rawstubs[3][i] & 0b01000000) >> 3) | ((rawstubs[4][i] & 0b01000000) >> 4) | ((rawstubs[0][i] & 0b00100000) >> 4) | ((rawstubs[1][i] & 0b00100000) >> 5); + formstubs.pos[cycle][1] = ((rawstubs[4][i] & 0b00010000) << 3) | ((rawstubs[0][i] & 0b00001000) << 3) | ((rawstubs[1][i] & 0b00001000) << 2) | ((rawstubs[2][i] & 0b00001000) << 1) | ((rawstubs[3][i] & 0b00001000) << 0) | ((rawstubs[4][i] & 0b00001000) >> 1) | ((rawstubs[0][i] & 0b00000100) >> 1) | ((rawstubs[1][i] & 0b00000100) >> 2); + formstubs.pos[cycle][2] = ((rawstubs[4][i] & 0b00000010) << 6) | ((rawstubs[0][i] & 0b00000001) << 6) | ((rawstubs[1][i] & 0b00000001) << 5) | ((rawstubs[2][i] & 0b00000001) << 4) | ((rawstubs[3][i] & 0b00000001) << 3) | ((rawstubs[4][i] & 0b00000001) << 3) | ((rawstubs[1][j] & 0b10000000) >> 6) | ((rawstubs[2][j] & 0b10000000) >> 7); + formstubs.pos[cycle][3] = ((rawstubs[0][j] & 0b00100000) << 2) | ((rawstubs[1][j] & 0b00100000) << 1) | ((rawstubs[2][j] & 0b00100000) << 0) | ((rawstubs[3][j] & 0b00100000) >> 1) | ((rawstubs[4][j] & 0b00100000) >> 2) | ((rawstubs[0][j] & 0b00010000) >> 2) | ((rawstubs[1][j] & 0b00010000) >> 3) | ((rawstubs[2][j] & 0b00010000) >> 4); + formstubs.pos[cycle][4] = ((rawstubs[0][j] & 0b00000100) << 5) | ((rawstubs[1][j] & 0b00000100) << 4) | ((rawstubs[2][j] & 0b00000100) << 3) | ((rawstubs[3][j] & 0b00000100) << 2) | ((rawstubs[4][j] & 0b00000100) << 1) | ((rawstubs[0][j] & 0b00000010) << 1) | ((rawstubs[1][j] & 0b00000010) << 0) | ((rawstubs[2][j] & 0b00000010) >> 1); + formstubs.row[cycle][0] = ((rawstubs[0][i] & 0b00010000) >> 1) | ((rawstubs[1][i] & 0b00010000) >> 2) | ((rawstubs[2][i] & 0b00010000) >> 3) | ((rawstubs[3][i] & 0b00010000) >> 4); + formstubs.row[cycle][1] = ((rawstubs[0][i] & 0b00000010) << 2) | ((rawstubs[1][i] & 0b00000010) << 1) | ((rawstubs[2][i] & 0b00000010) << 0) | ((rawstubs[3][i] & 0b00000010) >> 1); + formstubs.row[cycle][2] = ((rawstubs[1][j] & 0b01000000) >> 3) | ((rawstubs[2][j] & 0b01000000) >> 4) | ((rawstubs[3][j] & 0b01000000) >> 5) | ((rawstubs[4][j] & 0b01000000) >> 6); + formstubs.row[cycle][3] = ((rawstubs[1][j] & 0b00001000) >> 0) | ((rawstubs[2][j] & 0b00001000) >> 1) | ((rawstubs[3][j] & 0b00001000) >> 2) | ((rawstubs[4][j] & 0b00001000) >> 3); + formstubs.row[cycle][4] = ((rawstubs[1][j] & 0b00000001) << 3) | ((rawstubs[2][j] & 0b00000001) << 2) | ((rawstubs[3][j] & 0b00000001) << 1) | ((rawstubs[4][j] & 0b00000001) << 0); + formstubs.cur[cycle][0] = ((rawstubs[2][i] & 0b00100000) >> 3) | ((rawstubs[3][i] & 0b00100000) >> 4) | ((rawstubs[4][i] & 0b00100000) >> 5); + formstubs.cur[cycle][1] = ((rawstubs[2][i] & 0b00000100) >> 0) | ((rawstubs[3][i] & 0b00000100) >> 1) | ((rawstubs[4][i] & 0b00000100) >> 2); + formstubs.cur[cycle][2] = ((rawstubs[3][j] & 0b10000000) >> 5) | ((rawstubs[4][j] & 0b10000000) >> 6) | ((rawstubs[0][j] & 0b01000000) >> 6); + formstubs.cur[cycle][3] = ((rawstubs[3][j] & 0b00010000) >> 2) | ((rawstubs[4][j] & 0b00010000) >> 3) | ((rawstubs[0][j] & 0b00001000) >> 3); + formstubs.cur[cycle][4] = ((rawstubs[3][j] & 0b00000010) << 1) | ((rawstubs[4][j] & 0b00000010) >> 0) | ((rawstubs[0][j] & 0b00000001) >> 0); + //std::cout<<"RS1 "<<+formstubs.pos[cycle][0]<<std::endl; + //std::cout<<"RS2 "<<+formstubs.pos[cycle][1]<<std::endl; + //std::cout<<"RS3 "<<+formstubs.pos[cycle][2]<<std::endl; std::cout<<"RS01"<<+rawstubs[1][i]<<std::endl; + //std::cout<<"RS4 "<<+formstubs.pos[cycle][3]<<std::endl; + cycle += 1; + } + } + return formstubs; +} + +L1data MPAInterface::Format_l1(std::vector<uint8_t> rawl1,bool verbose) { - setBoard(0); - return fMPAFW->ReadData( pBoard, pBreakTrigger, pData, pWait ); + bool found = false; + uint8_t header,error,L1_ID,strip_counter,pixel_counter; + L1data formL1data; + + std::vector<uint16_t> strip_data, pixel_data; + uint16_t curdata; + + + for (int i=1; i<200 ;i++) + { + if ((rawl1[i] == 255)&(rawl1[i-1] == 255)&(~found)) + { + header = rawl1[i-1] << 11 | rawl1[i-1] << 3 | ((rawl1[i+1] & 0b11100000) >> 5); + error = ((rawl1[i+1] & 0b00011000) >> 3); + L1_ID = ((rawl1[i+1] & 0b00000111) << 6) | ((rawl1[i+2] & 0b11111100) >> 2); + strip_counter = ((rawl1[i+2] & 0b00000001) << 4) | ((rawl1[i+3] & 0b11110000) >> 4); + pixel_counter = ((rawl1[i+3] & 0b00001111) << 1) | ((rawl1[i+4] & 0b10000000) >> 7); + + uint8_t wordl=11,counter=0; + bool curbit; + uint8_t bitmask = 0b10000000; + for (int j=4; j<50 ;j++) + { + for(int k=0; k<8 ;k++) + { + curbit = (rawl1[i+j]&(bitmask>>k)); + counter += 1; + curdata += (curbit<<(wordl-counter)); + if(counter==wordl) + { + if (wordl==11) strip_data.push_back(curdata); + else pixel_data.push_back(curdata); + if(strip_counter==strip_data.size()) wordl=14; + curdata = 0; + counter = 0; + } + } + } + found = true; + } + } + if (found) + { + formL1data.strip_counter = strip_counter; + formL1data.pixel_counter = pixel_counter; + if(verbose) + { + std::cout<<"Header: "<<std::bitset<8>(header)<<std::endl; + std::cout<<"Error: "<<std::bitset<8>(error)<<std::endl; + std::cout<<"L1 ID: "<<L1_ID<<std::endl; + std::cout<<"Strip counter: "<<strip_counter<<std::endl; + std::cout<<"Pixel counter: "<<pixel_counter<<std::endl; + std::cout<<"Strip data:"<<std::endl; + } + + for (auto& sdata : strip_data) + { + formL1data.pos_strip.push_back((sdata & 0b11111110000) >> 4); + formL1data.width_strip.push_back((sdata & 0b00000001110) >> 1); + formL1data.MIP.push_back((sdata & 0b00000000001)); + + if (verbose)std::cout<< "\tPosition: "<<formL1data.pos_strip.back()<<"\n\tWidth: "<<formL1data.width_strip.back()<<"\n\tMIP: "<<formL1data.MIP.back()<<std::endl; + } + if(verbose) std::cout<<"Pixel data:"<<std::endl; + + for (auto& pdata : pixel_data) + { + formL1data.pos_pixel.push_back((pdata & 0b11111110000000) >> 7); + formL1data.width_pixel.push_back((pdata & 0b00000001110000) >> 4); + formL1data.Z.push_back((pdata & 0b00000000001111) + 1); + + if(verbose) std::cout<< "\tPosition: " << formL1data.pos_pixel.back()<<"\n\tWidth: "<<formL1data.width_pixel.back()<<"\n\tRow Number: "<<formL1data.Z.back()<<std::endl; + } + + return formL1data; + } + else std::cout<<"Header not found!"<<std::endl; } +void MPAInterface::Activate_async(MPA* pMPA) +{ + WriteMPAReg( pMPA,"ReadoutMode",0b01); +} +void MPAInterface::Activate_sync(MPA* pMPA) +{ + WriteMPAReg(pMPA,"ReadoutMode",0b00); +} + +void MPAInterface::Activate_pp(MPA* pMPA) +{ + WriteMPAReg(pMPA,"ECM",0b10000001); +} -std::vector<uint32_t>* MPAInterface::GetcurData() +void MPAInterface::Activate_ss(MPA* pMPA) { - setBoard(0); - return fMPAFW->GetcurData(); + WriteMPAReg(pMPA,"ECM",0b01000001); } -void MPAInterface::ReadTrig(int buffer_num) +void MPAInterface::Activate_ps(MPA* pMPA) { - setBoard(0); - return fMPAFW->ReadTrig(buffer_num); + WriteMPAReg(pMPA,"ECM",0b00001000); } -void MPAInterface::Cleardata() + +void MPAInterface::Pix_Set_enable(MPA* pMPA,uint32_t r,uint32_t p,uint32_t PixelMask=1,uint32_t Polarity=1,uint32_t EnEdgeBR=1,uint32_t EnLevelBR=0,uint32_t Encount=0,uint32_t DigCal=0,uint32_t AnCal=0,uint32_t BRclk=0) { - setBoard(0); - fMPAFW->Cleardata( ); + uint32_t comboword = (PixelMask) + (Polarity<<1) + (EnEdgeBR<<2) + (EnLevelBR<<3) + (Encount<<4) + (DigCal<<5) + (AnCal<<6) + (BRclk<<7); + Pix_write(pMPA,pMPA->getRegItem("ENFLAGS"), r, p, comboword ); } +void MPAInterface::Pix_Smode(MPA* pMPA,uint32_t r,uint32_t p, std::string smode = "edge") +{ + uint32_t smodewrite = 0b00; + if (smode == "edge") + uint32_t smodewrite = 0b00; + if (smode == "level") + uint32_t smodewrite = 0b01; + if (smode == "or") + uint32_t smodewrite = 0b10; + if (smode == "xor") + uint32_t smodewrite = 0b11; + Pix_write(pMPA,pMPA->getRegItem("ModeSel"), r, p, smodewrite ) ; +} +void MPAInterface::Enable_pix_BRcal(MPA* pMPA,uint32_t r,uint32_t p,std::string polarity,std::string smode) +{ + uint32_t PixelMask=1,Polarity=1,EnEdgeBR=1,EnLevelBR=0,Encount=0,DigCal=0,AnCal=0,BRclk=0; + + if (polarity == "rise") Polarity = 1; + else if (polarity == "fall") Polarity = 0; + else + { + std::cout<<"bad pol option"<<std::endl; + return; + } + if (smode == "level") + { + Pix_Smode(pMPA,r,p, "level"); + EnEdgeBR=0,EnLevelBR=1,Encount=1,AnCal=1; + } + else if (smode == "edge") + { + Pix_Smode(pMPA,r,p, "edge"); + EnEdgeBR=1,EnLevelBR=0,Encount=1,AnCal=1; + } + else + { + std::cout<<"bad edge option"<<std::endl; + return; + } + Pix_Set_enable(pMPA,r,p,PixelMask,Polarity,EnEdgeBR,EnLevelBR,Encount,DigCal,AnCal,BRclk); +} +void MPAInterface::Enable_pix_counter(MPA* pMPA,uint32_t r,uint32_t p) +{ + uint32_t PixelMask=1,Polarity=1,EnEdgeBR=0,EnLevelBR=0,Encount=1,DigCal=0,AnCal=1,BRclk=0; + Pix_Set_enable(pMPA,r,p,PixelMask,Polarity,EnEdgeBR,EnLevelBR,Encount,DigCal,AnCal,BRclk); +} +void MPAInterface::Enable_pix_sync(MPA* pMPA,uint32_t r,uint32_t p) +{ + uint32_t PixelMask=1,Polarity=1,EnEdgeBR=0,EnLevelBR=0,Encount=1,DigCal=0,AnCal=1,BRclk=0; + Pix_Set_enable(pMPA,r,p,PixelMask,Polarity,EnEdgeBR,EnLevelBR,Encount,DigCal,AnCal,BRclk); +} +void MPAInterface::Disable_pixel(MPA* pMPA,uint32_t r,uint32_t p) +{ + uint32_t PixelMask=0,Polarity=0,EnEdgeBR=0,EnLevelBR=0,Encount=0,DigCal=0,AnCal=0,BRclk=0; + Pix_Set_enable(pMPA,r,p,PixelMask,Polarity,EnEdgeBR,EnLevelBR,Encount,DigCal,AnCal,BRclk); +} +void MPAInterface::Enable_pix_digi(MPA* pMPA,uint32_t r,uint32_t p) +{ + uint32_t PixelMask=0,Polarity=0,EnEdgeBR=0,EnLevelBR=0,Encount=0,DigCal=1,AnCal=0,BRclk=0; + Pix_Set_enable(pMPA,r,p,PixelMask,Polarity,EnEdgeBR,EnLevelBR,Encount,DigCal,AnCal,BRclk); +} +void MPAInterface::Set_calibration(MPA* pMPA, uint8_t cal) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + // write + WriteMPAReg( pMPA,"CalDAC0",cal); + WriteMPAReg( pMPA,"CalDAC1",cal); + WriteMPAReg( pMPA,"CalDAC2",cal); + WriteMPAReg( pMPA,"CalDAC3",cal); + WriteMPAReg( pMPA,"CalDAC4",cal); + WriteMPAReg( pMPA,"CalDAC5",cal); + WriteMPAReg( pMPA,"CalDAC6",cal); +} -std::pair<std::vector<uint32_t>, std::vector<std::string>> MPAInterface::FormatData(std::pair<std::vector<uint32_t>, std::vector<uint32_t>> data) +void MPAInterface::Set_threshold(MPA* pMPA, uint8_t th) { - std::vector<uint32_t> counter_data = data.first; - std::vector<uint32_t> memory_data = data.second; - std::vector<uint32_t> bitpix(50); - std::vector<std::string> mem(96); + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + // write + WriteMPAReg( pMPA,"ThDAC0",th); + WriteMPAReg( pMPA,"ThDAC1",th); + WriteMPAReg( pMPA,"ThDAC2",th); + WriteMPAReg( pMPA,"ThDAC3",th); + WriteMPAReg( pMPA,"ThDAC4",th); + WriteMPAReg( pMPA,"ThDAC5",th); + WriteMPAReg( pMPA,"ThDAC6",th); + +} - for (int x=0;x<24; x++) - { - int shift1 = 0; - int shift2 = 16; +void MPAInterface::Send_pulses(MPA* pMPA, uint32_t n_pulse) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + + // configure test pulse fsm + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.misc.backpressure_enable", 0x0); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.misc.initial_fast_reset_enable", 0); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.test_pulse.en_fast_reset", 0); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.test_pulse.en_test_pulse", 1); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.test_pulse.en_l1a", 0); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.trigger_source", 6); + fBoardFW->WriteReg ("fc7_daq_cnfg.fast_command_block.triggers_to_accept", n_pulse); + fBoardFW->WriteReg ("fc7_daq_ctrl.fast_command_block.control.load_config", 0x1); + + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Open_shutter(); + + // start triggering machine which will send N events + fBoardFW->WriteReg ("fc7_daq_ctrl.fast_command_block.control.start_trigger", 0x1); + // wait + while (fBoardFW->ReadReg("fc7_daq_stat.fast_command_block.general.fsm_state")) { + usleep(10); + } + // close + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Close_shutter(); +} + +void MPAInterface::Shutter_loop(MPA* pMPA, uint32_t dur) +{ + //first, identify the correct BeBoardFWInterface + setBoard ( pMPA->getBeBoardIdentifier() ); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Open_shutter(); + usleep(dur); + dynamic_cast<D19cFWInterface*>(fBoardFW)->PS_Close_shutter(); +} - uint32_t l((counter_data[x+1] >> shift1) & 0xFFFF); - uint32_t r((counter_data[x+1] >> shift2) & 0xFFFF); - bitpix[2*x] = l; - bitpix[2*x+1] = r; - } - std::bitset<32> y(memory_data[215]); - std::string memory_string = y.to_string(); - for (int x=1;x<216; x++) - { - std::bitset<32> y(memory_data[215 - x]); - memory_string = memory_string + y.to_string(); - } - for (int x=0;x<96; x++) - { - mem[x] = memory_string.substr(x*72, 72); - - } - std::pair<std::vector<uint32_t>, std::vector<std::string>> returndata(bitpix,mem); - return returndata; -} - -std::pair<std::vector<uint32_t>, std::vector<uint64_t>> MPAInterface::ReadMemory(std::vector<std::string> intmemory, int mode) -{ - std::string memory; - std::vector<uint32_t> BX(96); - uint64_t hit; - std::vector<int> row(96); - std::vector<int> col(96); - std::vector<uint64_t> data(96); - std::vector<int> bend(96); - std::string header; - //Only implements noprocessing mode - if (mode == 3) - { - for (int x=0;x<96; x++) - { +uint32_t MPAInterface::Read_pixel_counter(MPA* pMPA,uint32_t row, uint32_t pixel) +{ + setBoard(0); + uint32_t data1 = Pix_read(pMPA,pMPA->getRegItem("ReadCounter_LSB"),row,pixel); + uint32_t data2 = Pix_read(pMPA,pMPA->getRegItem("ReadCounter_MSB"),row,pixel); - header = intmemory[x].substr(0, 8); - if (header != "11111111") break; + uint32_t data = ((data2 & 0x0ffffff) << 8) | (data1 & 0x0fffffff); + return data; +} - std::bitset<16> b(intmemory[x].substr(8, 16)); - BX[x] = b.to_ulong(); - std::bitset<48> p(intmemory[x].substr(24, 48)); - hit = p.to_ulong(); - data[x]=hit; - } +uint32_t MPAInterface::ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ) +{ + setBoard(0); + return dynamic_cast<D19cFWInterface*>(fBoardFW)->ReadData( pBoard, pBreakTrigger, pData, pWait ); +} - } - - std::pair<std::vector<uint32_t>, std::vector<uint64_t>> returndata(BX, data); - return returndata; - -} - - -std::vector< uint32_t > MPAInterface::ReadConfig(const std::string& pFilename, int nmpa, int conf) -{ - - pugi::xml_document doc; - std::string fullname = "settings/MPAFiles/Conf_"+pFilename+"_MPA"+std::to_string(nmpa)+"_config"+std::to_string(conf)+".xml"; - pugi::xml_parse_result result = doc.load_file( fullname.c_str() ); - if ( !result ) - { - std::cout << "ERROR :\n Unable to open the file : " << pFilename << std::endl; - std::cout << "Error description : " << result.description() << std::endl; - } - - std::vector< uint32_t > conf_upload(25); - int perif = -1; - for ( pugi::xml_node cBeBoardNode = doc.child( "CONF" ).child( "periphery" ).first_child(); cBeBoardNode; cBeBoardNode = cBeBoardNode.next_sibling() ) - { - if (static_cast<std::string>(cBeBoardNode.name())=="OM") perif = convertAnyInt(cBeBoardNode.child_value()); - if (static_cast<std::string>(cBeBoardNode.name())=="RT") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 3) << 2 ); - if (static_cast<std::string>(cBeBoardNode.name())=="SCW") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 4 ); - if (static_cast<std::string>(cBeBoardNode.name())=="SH2") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 8 ); - if (static_cast<std::string>(cBeBoardNode.name())=="SH1") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 12); - if (static_cast<std::string>(cBeBoardNode.name())=="CALDAC") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 255) << 16); - if (static_cast<std::string>(cBeBoardNode.name())=="THDAC") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 255) << 24); - } - conf_upload[0] = perif; - for ( pugi::xml_node cBeBoardNode = doc.child( "CONF" ).first_child(); cBeBoardNode; cBeBoardNode = cBeBoardNode.next_sibling() ) - { - int pix = 0; - if (static_cast<std::string>(cBeBoardNode.name())=="pixel") - { - int pixnum = convertAnyInt(cBeBoardNode.attribute("n").value()); - - if (pixnum<17 and pixnum>8) - { - for ( pugi::xml_node cBeBoardNode1 = cBeBoardNode.first_child(); cBeBoardNode1; cBeBoardNode1 = cBeBoardNode1.next_sibling() ) - { - if (static_cast<std::string>(cBeBoardNode1.name())=="PMR") pix |= convertAnyInt(cBeBoardNode1.child_value()); - if (static_cast<std::string>(cBeBoardNode1.name())=="ARR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 1 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 2 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="CER") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 7 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="SP") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 8 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="SR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 9 ) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="PML") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 10); - if (static_cast<std::string>(cBeBoardNode1.name())=="ARL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 11) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 12) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="CEL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 17); - if (static_cast<std::string>(cBeBoardNode1.name())=="CW") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 2) << 18); - - - } - } - else if (pixnum<25 and pixnum>0) - { - for ( pugi::xml_node cBeBoardNode1 = cBeBoardNode.first_child(); cBeBoardNode1; cBeBoardNode1 = cBeBoardNode1.next_sibling() ) - { - if (static_cast<std::string>(cBeBoardNode1.name())=="PML") pix |= convertAnyInt(cBeBoardNode1.child_value()); - if (static_cast<std::string>(cBeBoardNode1.name())=="ARL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 1 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 2 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="CEL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 7 ) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="CW") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 3) << 8 ); - if (static_cast<std::string>(cBeBoardNode1.name())=="PMR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 10) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="ARR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 11); - if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 31) << 12) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="CER") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 17) ; - if (static_cast<std::string>(cBeBoardNode1.name())=="SP") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 18); - if (static_cast<std::string>(cBeBoardNode1.name())=="SR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 19); - - } - } - conf_upload[pixnum] = pix; - } - - } - return conf_upload; -} - - - - -void MPAInterface::ModifyPerif(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload) -{ - std::vector<std::string> vars = mod.first; - std::vector< uint32_t > vals = mod.second; - uint32_t perif = conf_upload->at(0); - - for (uint32_t iperif=0;iperif<vars.size(); iperif++) - { - if (vars[iperif]=="OM") - { - perif = (perif&~3); - perif |= (vals[iperif]); - } - if (vars[iperif]=="RT") - { - perif = (perif&~(3<<2)); - perif |= ((vals[iperif]& 3) << 2 ); - } - if (vars[iperif]=="SCW") - { - perif = (perif&~(15<<4)); - perif |= ((vals[iperif]& 15) << 4 ); - } - if (vars[iperif]=="SH2") - { - perif = (perif&~(15<<8)); - perif |= ((vals[iperif]& 15) << 8 ); - } - if (vars[iperif]=="SH1") - { - perif = (perif&~(15<<12)); - perif |= ((vals[iperif]& 15) << 12); - } - if (vars[iperif]=="CALDAC") - { - perif = (perif&~(255<<16)); - perif |= ((vals[iperif]& 255) << 16); - } - if (vars[iperif]=="THDAC") - { - perif = (perif&~(255<<24)); - perif |= ((vals[iperif]& 255) << 24); - } - - } - conf_upload->at(0) = perif; - -} -void MPAInterface::ModifyPix(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload , uint32_t pixnum ) -{ - - std::vector<std::string> vars = mod.first; - std::vector< uint32_t > vals = mod.second; - - uint32_t pix = conf_upload->at(pixnum); - if (pixnum<17 and pixnum>8) - { - for (uint32_t ipix=0;ipix<vars.size(); ipix++) - { - if (vars[ipix]=="PMR") - { - pix = (pix&~1); - pix |= (vals[ipix]); - } - if (vars[ipix]=="ARR") - { - pix = (pix&~(1<<1)); - pix |= ((vals[ipix]& 1) << 1); - } - if (vars[ipix]=="TRIMDACL") - { - pix = (pix&~(31<<2)); - pix |= ((vals[ipix]& 31) << 2); - } - if (vars[ipix]=="CER") - { - pix = (pix&~(1<<7)); - pix |= ((vals[ipix]& 1) << 7); - } - if (vars[ipix]=="SP") - { - pix = (pix&~(1<<8)); - pix |= ((vals[ipix]& 1) << 8); - } - if (vars[ipix]=="SR") - { - pix = (pix&~(1<<9)); - pix |= ((vals[ipix]& 1) << 9); - } - if (vars[ipix]=="PML") - { - pix = (pix&~(1<<10)); - pix |= ((vals[ipix]& 1) << 10); - } - if (vars[ipix]=="ARL") - { - pix = (pix&~(1<<11)); - pix |= ((vals[ipix]& 1) << 11); - } - if (vars[ipix]=="TRIMDACR") - { - pix = (pix&~(31<<12)); - pix |= ((vals[ipix]& 31) << 12); - } - - if (vars[ipix]=="CEL") - { - pix = (pix&~(1<<17)); - pix |= ((vals[ipix]& 1) << 17); - } - if (vars[ipix]=="CW") - { - pix = (pix&~(2<<18)); - pix |= ((vals[ipix]& 2) << 18); - } - } - } - else if (pixnum<25 and pixnum>0) - { - for (uint32_t ipix=0;ipix<vars.size(); ipix++) - { - if (vars[ipix]=="PML") - { - pix = (pix&~1); - pix |= (vals[ipix]); - } - if (vars[ipix]=="ARL") - { - pix = (pix&~(1<<1)); - pix |= ((vals[ipix]& 1) << 1); - } - if (vars[ipix]=="TRIMDACL") - { - pix = (pix&~(31<<2)); - pix |= ((vals[ipix]& 31) << 2); - } - if (vars[ipix]=="CEL") - { - pix = (pix&~(1<<7)); - pix |= ((vals[ipix]& 1) << 7); - } - if (vars[ipix]=="CW") - { - pix = (pix&~(3<<8)); - pix |= ((vals[ipix]& 3) << 8); - } - if (vars[ipix]=="PMR") - { - pix = (pix&~(1<<10)); - pix |= ((vals[ipix]& 1) << 10); - } - if (vars[ipix]=="ARR") - { - pix = (pix&~(1<<11)); - pix |= ((vals[ipix]& 1) << 11); - } - if (vars[ipix]=="TRIMDACR") - { - pix = (pix&~(31<<12)); - pix |= ((vals[ipix]& 31) << 12); - } - if (vars[ipix]=="CER") - { - pix = (pix&~(1<<17)); - pix |= ((vals[ipix]& 1) << 17); - } - if (vars[ipix]=="SP") - { - pix = (pix&~(1<<18)); - pix |= ((vals[ipix]& 1) << 18); - } - if (vars[ipix]=="SR") - { - pix = (pix&~(1<<19)); - pix |= ((vals[ipix]& 1) << 19); - } - } - } - - - conf_upload->at(pixnum) = pix; +void MPAInterface::Cleardata() +{ + setBoard(0); + //dynamic_cast<D19cFWInterface*>(fBoardFW)->Cleardata( ); } diff --git a/HWInterface/MPAInterface.h b/HWInterface/MPAInterface.h index 45c0c5e817434b958551afc5c59c2569bc6cd1b4..e5e7bc1d404378e905bfe087fd63992547ba3ed8 100644 --- a/HWInterface/MPAInterface.h +++ b/HWInterface/MPAInterface.h @@ -13,7 +13,7 @@ #define __MPAINTERFACE_H__ #include <vector> -#include "../HWInterface/MPAGlibFWInterface.h" +#include "../HWInterface/D19cFWInterface.h" #include "pugixml/pugixml.hpp" using namespace Ph2_HwDescription; @@ -24,104 +24,124 @@ using namespace Ph2_HwDescription; namespace Ph2_HwInterface { - using BeBoardFWMap = std::map<uint16_t, BeBoardFWInterface*>; /*!< Map of Board connected */ +using BeBoardFWMap = std::map<uint16_t, BeBoardFWInterface*>; /*!< Map of Board connected */ - /*! - * \class MPAInterface - * \brief Class representing the User Interface to the MPA on different boards - */ - class MPAInterface - { +/*! + * \class MPAInterface + * \brief Class representing the User Interface to the MPA on different boards + */ + +struct Stubs { + std::vector<uint8_t> nst; + std::vector<std::vector<uint8_t>> pos; + std::vector<std::vector<uint8_t>> row; + std::vector<std::vector<uint8_t>> cur; +}; + +struct L1data { + uint8_t strip_counter; + uint8_t pixel_counter; + std::vector<uint8_t> pos_strip; + std::vector<uint8_t> width_strip; + std::vector<uint8_t> MIP; + std::vector<uint8_t> pos_pixel; + std::vector<uint8_t> width_pixel; + std::vector<uint8_t> Z; +}; + +class MPAInterface +{ + +private: + BeBoardFWMap fBoardMap; /*!< Map of Board connected */ + BeBoardFWInterface* fBoardFW; /*!< Board loaded */ + uint16_t prevBoardIdentifier; /*!< Id of the previous board */ + + uint16_t fRegisterCount; /*!< Counter for the number of Registers written */ + uint16_t fTransactionCount; /*!< Counter for the number of Transactions */ + + +private: + /*! + * \brief Set the board to talk with + * \param pBoardId + */ + void setBoard( uint16_t pBoardIdentifier ); + +public: + /*! + * \brief Constructor of the MPAInterface Class + * \param pBoardMap + */ + MPAInterface( const BeBoardFWMap& pBoardMap ); + /*! + * \brief Destructor of the MPAInterface Class + */ + ~MPAInterface(); + + void setFileHandler (FileHandler* pHandler); + void PowerOff(uint8_t mpaid = 0 , uint8_t ssaid = 0 ); + void PowerOn(float VDDPST = 1.25, float DVDD = 1.2, float AVDD = 1.25, float VBG = 0.3, uint8_t mpaid = 0 , uint8_t ssaid = 0); + void MainPowerOn(uint8_t mpaid = 0, uint8_t ssaid = 0); + void MainPowerOff(); - private: - BeBoardFWMap fBoardMap; /*!< Map of Board connected */ - BeBoardFWInterface* fBoardFW; /*!< Board loaded */ - MPAGlibFWInterface* fMPAFW; /*!< Board loaded */ - uint16_t prevBoardIdentifier; /*!< Id of the previous board */ + bool ConfigureMPA (const MPA* pMPA , bool pVerifLoop = true); - uint16_t fRegisterCount; /*!< Counter for the number of Registers written */ - uint16_t fTransactionCount; /*!< Counter for the number of Transactions */ - private: - /*! - * \brief Set the board to talk with - * \param pBoardId - */ - void setBoard( uint16_t pBoardIdentifier ); + uint32_t ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ); - public: - /*! - * \brief Constructor of the MPAInterface Class - * \param pBoardMap - */ - MPAInterface( const BeBoardFWMap& pBoardMap ); - /*! - * \brief Destructor of the MPAInterface Class - */ - ~MPAInterface(); - void setFileHandler (FileHandler* pHandler); + void ReadMPA ( MPA* pMPA ); - /*! - * \uploads configuration data to glib - */ - void ConfigureMPA(std::vector< uint32_t >* conf_upload, int conf ,int nmpa, bool lr); + bool WriteMPAReg ( MPA* pMPA, const std::string& pRegNode, uint8_t pValue, bool pVerifLoop = true ); + bool WriteMPAMultReg ( MPA* pMPA, const std::vector< std::pair<std::string, uint8_t> >& pVecReq, bool pVerifLoop = true ); + uint8_t ReadMPAReg ( MPA* pMPA, const std::string& pRegNode ); + void ReadMPAMultReg ( MPA* pMPA, const std::vector<std::string>& pVecReg ); - /*! - * \sends configuration data to MAPSA from glib - */ - void SendConfig(int nummpal, int nummpar); - void ReadTrig(int buffer_num); - std::vector<uint32_t>* GetcurData(); + void Pix_write(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel,uint32_t data); + uint32_t Pix_read(MPA* cMPA,RegItem cRegItem,uint32_t row,uint32_t pixel); - /*! - * \initializes AR header - */ - void HeaderInitMPA(int nmpa, bool lr); - /*! - * \modify periphery configuration - */ - void ModifyPerif(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload); - int WaitTestbeam(); - /*! - * \modify pixel configuration for pixel pixnum - */ - void ModifyPix(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload, uint32_t pixnum ); + void activate_I2C_chip(); + std::vector<uint16_t> ReadoutCounters_MPA(MPA* pMPA, uint32_t raw_mode_en); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> ReadMPAData(int buffer_num, int mpa, bool lr); + void PS_Open_shutter(MPA* pMPA, uint32_t duration = 0 ); + void PS_Close_shutter(MPA* pMPA, uint32_t duration = 0 ); + void PS_Clear_counters(MPA *pMPA, uint32_t duration = 0 ); + void PS_Start_counters_read(MPA* pMPA, uint32_t duration = 0 ); - uint32_t ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ); - /*! - * \format the raw data output of ReadData to organize into events. Segmented due to processing time - */ - std::pair<std::vector<uint32_t>, std::vector<std::string>> FormatData(std::pair<std::vector<uint32_t>, std::vector<uint32_t>> data); + void Activate_async(MPA* pMPA); + void Activate_sync(MPA* pMPA); + void Activate_pp(MPA* pMPA); + void Activate_ss(MPA* pMPA); + void Activate_ps(MPA* pMPA); - /*! - * \further formats the output of FormatData to a human readable format. Segmented due to processing time - */ - std::pair<std::vector<uint32_t>, std::vector<uint64_t>> ReadMemory(std::vector<std::string> intmemory, int mode); + void Enable_pix_counter(MPA* pMPA,uint32_t r,uint32_t p); + void Enable_pix_sync(MPA* pMPA,uint32_t r,uint32_t p); + void Disable_pixel(MPA* pMPA,uint32_t r,uint32_t p); + void Enable_pix_digi(MPA* pMPA,uint32_t r,uint32_t p); + void Set_calibration(MPA* pMPA,uint8_t cal); + void Set_threshold(MPA* pMPA,uint8_t th); - /*! - * \reads in in configuration data from xml file for mpa nmpa and configuration number conf - */ - std::vector< uint32_t > ReadConfig(const std::string& pFilename, int nmpa, int conf); + uint32_t Read_pixel_counter(MPA* pMPA,uint32_t row, uint32_t pixel); + void Send_pulses(MPA* pMPA, uint32_t n_pulse); + void Shutter_loop(MPA* pMPA, uint32_t dur); - /*! - * \initializes sequencer (starts daq) - */ - void SequencerInit(int smode,int sdur,int mem,int ibuff); - void TestbeamInit(int sdur,int clock, int phase); + void Pix_Smode(MPA* pMPA,uint32_t r,uint32_t p, std::string smode); + void Enable_pix_BRcal(MPA* pMPA,uint32_t r,uint32_t p,std::string polarity = "rise",std::string smode = "edge"); + void Pix_Set_enable(MPA* pMPA,uint32_t r,uint32_t p,uint32_t PixelMask,uint32_t Polarity,uint32_t EnEdgeBR,uint32_t EnLevelBR,uint32_t Encount,uint32_t DigCal,uint32_t AnCal,uint32_t BRclk); + Stubs Format_stubs(std::vector<std::vector<uint8_t>> rawstubs); + L1data Format_l1(std::vector<uint8_t> rawl1,bool verbose=false); - void Cleardata(); - }; + void Cleardata(); +}; } #endif diff --git a/HWInterface/MPAGlibFWInterface.cc b/HWInterface/MPAlightGlibFWInterface.cc similarity index 74% rename from HWInterface/MPAGlibFWInterface.cc rename to HWInterface/MPAlightGlibFWInterface.cc index 854f09d47b393c7249da3f9389c1c9eb935a60c1..0962b24a49930ebf001b0cd430d889f0754b98a1 100644 --- a/HWInterface/MPAGlibFWInterface.cc +++ b/HWInterface/MPAlightGlibFWInterface.cc @@ -1,7 +1,7 @@ /* - FileName : MPAGlibFWInterface.h - Content : MPAGlibFWInterface init/config of the Glib and its Cbc's + FileName : MPAlightGlibFWInterface.h + Content : MPAlightGlibFWInterface init/config of the Glib and its Cbc's Programmer : Lorenzo BIDEGAIN, Nicolas PIERRE Version : 1.0 Date of creation : 28/07/14 @@ -12,13 +12,13 @@ #include <time.h> #include <chrono> #include <uhal/uhal.hpp> -#include "MPAGlibFWInterface.h" +#include "MPAlightGlibFWInterface.h" #include "GlibFpgaConfig.h" // namespace Ph2_HwInterface { - MPAGlibFWInterface::MPAGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId ) : + MPAlightGlibFWInterface::MPAlightGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId ) : BeBoardFWInterface( puHalConfigFileName, pBoardId ), fpgaConfig( nullptr ), fData( nullptr ), @@ -26,7 +26,7 @@ namespace Ph2_HwInterface {} - MPAGlibFWInterface::MPAGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId, FileHandler* pFileHandler ) : + MPAlightGlibFWInterface::MPAlightGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId, FileHandler* pFileHandler ) : BeBoardFWInterface( puHalConfigFileName, pBoardId ), fpgaConfig( nullptr ), fData( nullptr ), @@ -37,7 +37,7 @@ namespace Ph2_HwInterface else fSaveToFile = true; } - MPAGlibFWInterface::MPAGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable ) : + MPAlightGlibFWInterface::MPAlightGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable ) : BeBoardFWInterface( pId, pUri, pAddressTable ), fpgaConfig( nullptr ), fData( nullptr ), @@ -45,7 +45,7 @@ namespace Ph2_HwInterface {} - MPAGlibFWInterface::MPAGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable, FileHandler* pFileHandler ) : + MPAlightGlibFWInterface::MPAlightGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable, FileHandler* pFileHandler ) : BeBoardFWInterface( pId, pUri, pAddressTable ), fpgaConfig( nullptr ), fData( nullptr ), @@ -57,7 +57,7 @@ namespace Ph2_HwInterface } - void MPAGlibFWInterface::setFileHandler (FileHandler* pHandler) + void MPAlightGlibFWInterface::setFileHandler (FileHandler* pHandler) { if (pHandler != nullptr ) { @@ -67,24 +67,24 @@ namespace Ph2_HwInterface else LOG (INFO) << "Error, can not set NULL FileHandler" ; } - uint32_t MPAGlibFWInterface::getBoardInfo() + uint32_t MPAlightGlibFWInterface::getBoardInfo() { return 0; } - void MPAGlibFWInterface::Start() + void MPAlightGlibFWInterface::Start() { TestbeamInit(500000,0, 0); } - void MPAGlibFWInterface::Stop() + void MPAlightGlibFWInterface::Stop() { WriteReg( "Control.testbeam_mode", 0 ); WriteReg( "Control.beam_on", 0 ); } - void MPAGlibFWInterface::Cleardata() + void MPAlightGlibFWInterface::Cleardata() { delete curData; curData=new std::vector<uint32_t>; @@ -93,21 +93,21 @@ namespace Ph2_HwInterface - void MPAGlibFWInterface::Pause() + void MPAlightGlibFWInterface::Pause() { } - void MPAGlibFWInterface::Resume() + void MPAlightGlibFWInterface::Resume() { } - uint32_t MPAGlibFWInterface::ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ) + uint32_t MPAlightGlibFWInterface::ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ) { if ( fData ) delete fData; @@ -132,7 +132,7 @@ namespace Ph2_HwInterface - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> MPAGlibFWInterface::ReadMPAData(int buffer_num, int mpa, bool lr) + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> MPAlightGlibFWInterface::ReadMPAlightData(int buffer_num, int mpa, bool lr) { std::string targ; if (lr) targ = "Readout_Right.Counter.MPA" + std::to_string(mpa); @@ -163,12 +163,12 @@ namespace Ph2_HwInterface /** compute the block size according to the number of CBC's on this board * this will have to change with a more generic FW */ - uint32_t MPAGlibFWInterface::computeBlockSize( BeBoard* pBoard ) + uint32_t MPAlightGlibFWInterface::computeBlockSize( BeBoard* pBoard ) { return 0; } - std::vector<uint32_t> MPAGlibFWInterface::ReadBlockRegValue( const std::string& pRegNode, const uint32_t& pBlocksize ) + std::vector<uint32_t> MPAlightGlibFWInterface::ReadBlockRegValue( const std::string& pRegNode, const uint32_t& pBlocksize ) { uhal::ValVector<uint32_t> valBlock = ReadBlockReg( pRegNode, pBlocksize ); std::vector<uint32_t> vBlock = valBlock.value(); @@ -184,7 +184,7 @@ namespace Ph2_HwInterface return vBlock; } - bool MPAGlibFWInterface::WriteBlockReg( const std::string& pRegNode, const std::vector< uint32_t >& pValues ) + bool MPAlightGlibFWInterface::WriteBlockReg( const std::string& pRegNode, const std::vector< uint32_t >& pValues ) { bool cWriteCorr = RegManager::WriteBlockReg( pRegNode, pValues ); @@ -193,7 +193,7 @@ namespace Ph2_HwInterface return cWriteCorr; } - void MPAGlibFWInterface::SelectDaqSRAM( uint32_t pNthAcq ) + void MPAlightGlibFWInterface::SelectDaqSRAM( uint32_t pNthAcq ) { } @@ -202,33 +202,33 @@ namespace Ph2_HwInterface //Methods for Cbc's: - void MPAGlibFWInterface::threadAcquisitionLoop( BeBoard* pBoard, HwInterfaceVisitor* visitor ) + void MPAlightGlibFWInterface::threadAcquisitionLoop( BeBoard* pBoard, HwInterfaceVisitor* visitor ) { }; - bool MPAGlibFWInterface::I2cCmdAckWait( uint32_t pAckVal, uint8_t pNcount ) + bool MPAlightGlibFWInterface::I2cCmdAckWait( uint32_t pAckVal, uint8_t pNcount ) { return true; } - void MPAGlibFWInterface::WriteI2C( std::vector<uint32_t>& pVecReq, bool pWrite ) + void MPAlightGlibFWInterface::WriteI2C( std::vector<uint32_t>& pVecReq, bool pWrite ) { } - void MPAGlibFWInterface::ReadI2C( std::vector<uint32_t>& pVecReq ) + void MPAlightGlibFWInterface::ReadI2C( std::vector<uint32_t>& pVecReq ) { } - void MPAGlibFWInterface::FlashProm( const std::string& strConfig, const char* pstrFile ) + void MPAlightGlibFWInterface::FlashProm( const std::string& strConfig, const char* pstrFile ) { } - void MPAGlibFWInterface::JumpToFpgaConfig( const std::string& strConfig ) + void MPAlightGlibFWInterface::JumpToFpgaConfig( const std::string& strConfig ) { } @@ -238,7 +238,7 @@ namespace Ph2_HwInterface - void MPAGlibFWInterface::PowerOn() + void MPAlightGlibFWInterface::PowerOn() { std::chrono::milliseconds cWait( 20 ); @@ -275,7 +275,7 @@ namespace Ph2_HwInterface } - void MPAGlibFWInterface::PowerOff() + void MPAlightGlibFWInterface::PowerOff() { std::chrono::milliseconds cWait( 10 ); @@ -300,7 +300,7 @@ namespace Ph2_HwInterface - void MPAGlibFWInterface::ReadVer() + void MPAlightGlibFWInterface::ReadVer() { std::cout<<"\nReading GLIB firmware version:"; std::cout<<ReadReg( "Control.firm_ver" )<<std::endl; @@ -316,10 +316,10 @@ namespace Ph2_HwInterface - int MPAGlibFWInterface::WaitSequencer() + int MPAlightGlibFWInterface::WaitSequencer() { int i=0; - + uhal::ValWord<uint32_t> busyseq; std::chrono::milliseconds cWait( 1 ); busyseq = ReadReg("Control.Sequencer.busy"); @@ -338,7 +338,7 @@ namespace Ph2_HwInterface - int MPAGlibFWInterface::WaitTestbeam() + int MPAlightGlibFWInterface::WaitTestbeam() { int returnval = 0; int i=0; @@ -350,11 +350,11 @@ namespace Ph2_HwInterface { buffers_num = ReadReg("Control.Sequencer.buffers_num"); i++; - if (i % 20000==0) + if (i % 20000==0) { std::cout<<"Waiting for Spill: "<<i/10000<<" seconds"<<std::endl; } - if (i == 30000) + if (i == 30000) { returnval=1; } @@ -365,13 +365,13 @@ namespace Ph2_HwInterface - void MPAGlibFWInterface::ReadTrig(int buffer_num) + void MPAlightGlibFWInterface::ReadTrig(int buffer_num) { int total_trigs = -1; int trigger_counter = -1; int trigger_total_counter = -1; //int Offset_BEAM = -1; - //int Offset_MPA = -1; + //int Offset_MPAlight = -1; std::string targ; total_trigs = ReadReg("Control.total_triggers"); @@ -400,13 +400,13 @@ namespace Ph2_HwInterface } - void MPAGlibFWInterface::HeaderInitMPA(int nmpa, bool lr) + void MPAlightGlibFWInterface::HeaderInitMPAlight(int nmpa, bool lr) { if (lr) WriteReg( "Readout_Right.Header.MPA"+std::to_string(nmpa), 0xFFFFFFF0 + nmpa ); else WriteReg( "Readout_Left.Header.MPA"+std::to_string(nmpa), 0xFFFFFFF0 + nmpa ); } - void MPAGlibFWInterface::TestbeamInit(int sdur,int clock, int phase) + void MPAlightGlibFWInterface::TestbeamInit(int sdur,int clock, int phase) { WriteReg( "Control.beam_on", 0 ); WriteReg("Control.readout", 1); @@ -418,19 +418,19 @@ namespace Ph2_HwInterface } - void MPAGlibFWInterface::StrobeSettings(int snum, int sdel, int slen, + void MPAlightGlibFWInterface::StrobeSettings(int snum, int sdel, int slen, int sdist, int cal) { WriteReg("Shutter.Strobe.number", snum); WriteReg("Shutter.Strobe.delay", sdel); WriteReg("Shutter.Strobe.length", slen); WriteReg("Shutter.Strobe.distance", sdist); - + WriteReg("Control.calibration", cal); } - void MPAGlibFWInterface::SequencerInit(int smode,int sdur,int mem,int ibuff) + void MPAlightGlibFWInterface::SequencerInit(int smode,int sdur,int mem,int ibuff) { WriteReg("Shutter.time", sdur); WriteReg("Control.testbeam_mode", 0x0); @@ -439,15 +439,15 @@ namespace Ph2_HwInterface WriteReg("Control.Sequencer.buffers_index", ibuff); } - void MPAGlibFWInterface::ReadNEvents (BeBoard* pBoard, uint32_t pNEvents, std::vector<uint32_t>& pData, bool pWait) + void MPAlightGlibFWInterface::ReadNEvents (BeBoard* pBoard, uint32_t pNEvents, std::vector<uint32_t>& pData, bool pWait) { } - void MPAGlibFWInterface::upload( std::vector< uint32_t > *conf_upload, int conf, int nmpa, bool lr) + void MPAlightGlibFWInterface::upload( std::vector< uint32_t > *conf_upload, int conf, int nmpa, bool lr) { if (lr) WriteBlockReg( "Configuration_Right.Memory_DataConf.MPA"+std::to_string(nmpa)+".config_"+std::to_string(conf), (*conf_upload)); else WriteBlockReg( "Configuration_Left.Memory_DataConf.MPA"+std::to_string(nmpa)+".config_"+std::to_string(conf), (*conf_upload)); } - void MPAGlibFWInterface::write(int nummpal, int nummpar) + void MPAlightGlibFWInterface::write(int nummpal, int nummpar) { WriteReg("Configuration_Left.num_MPA",nummpal); WriteReg("Configuration_Right.num_MPA",nummpar); @@ -456,12 +456,12 @@ namespace Ph2_HwInterface } - void MPAGlibFWInterface::CbcTestPulse() + void MPAlightGlibFWInterface::CbcTestPulse() { } - void MPAGlibFWInterface::CbcTrigger() - { + void MPAlightGlibFWInterface::CbcTrigger() + { } } diff --git a/HWInterface/MPAGlibFWInterface.h b/HWInterface/MPAlightGlibFWInterface.h similarity index 85% rename from HWInterface/MPAGlibFWInterface.h rename to HWInterface/MPAlightGlibFWInterface.h index fa2d466618430067ebff4d9c2460d772b85bc9d9..0b64e16886efcd18fd4848b1238082cc7e06f295 100644 --- a/HWInterface/MPAGlibFWInterface.h +++ b/HWInterface/MPAlightGlibFWInterface.h @@ -1,7 +1,7 @@ /*! - \file MPAGlibFWInterface.h - \brief MPAGlibFWInterface init/config of the Glib and its Cbc's + \file MPAlightGlibFWInterface.h + \brief MPAlightGlibFWInterface init/config of the Glib and its Cbc's \author Lorenzo BIDEGAIN, Nicolas PIERRE \version 1.0 \date 28/07/14 @@ -9,8 +9,8 @@ */ -#ifndef __MPAGlibFWInterface_H__ -#define __MPAGlibFWInterface_H__ +#ifndef __MPAlightGlibFWInterface_H__ +#define __MPAlightGlibFWInterface_H__ #include <string> #include <map> @@ -33,10 +33,10 @@ namespace Ph2_HwInterface { class FpgaConfig; /*! - * \class MPAGlibFWInterface + * \class MPAlightGlibFWInterface * \brief init/config of the Glib and its Cbc's */ -class MPAGlibFWInterface : public BeBoardFWInterface +class MPAlightGlibFWInterface : public BeBoardFWInterface { private: @@ -59,29 +59,29 @@ private: public: /*! - * \brief Constructor of the MPAGlibFWInterface class + * \brief Constructor of the MPAlightGlibFWInterface class * \param puHalConfigFileName : path of the uHal Config File * \param pBoardId */ - MPAGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId ); - MPAGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId, FileHandler* pFileHandler ); + MPAlightGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId ); + MPAlightGlibFWInterface( const char* puHalConfigFileName, uint32_t pBoardId, FileHandler* pFileHandler ); /*! - * \brief Constructor of the MPAGlibFWInterface class + * \brief Constructor of the MPAlightGlibFWInterface class * \param pId : ID string * \param pUri: URI string * \param pAddressTable: address tabel string */ - MPAGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable ); - MPAGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable, FileHandler* pFileHandler ); + MPAlightGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable ); + MPAlightGlibFWInterface( const char* pId, const char* pUri, const char* pAddressTable, FileHandler* pFileHandler ); void setFileHandler (FileHandler* pHandler); uint32_t getBoardInfo(); /*! - * \brief Destructor of the MPAGlibFWInterface class + * \brief Destructor of the MPAlightGlibFWInterface class */ - ~MPAGlibFWInterface() + ~MPAlightGlibFWInterface() { if (fData) delete fData; } @@ -94,27 +94,27 @@ public: - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) {}; - void EncodeReg ( const CbcRegItem& pRegItem, + void EncodeReg ( const RegItem& pRegItem, uint8_t pFeId, uint8_t pCbcId, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) {}; - - void BCEncodeReg ( const CbcRegItem& pRegItem, + + void BCEncodeReg ( const RegItem& pRegItem, uint8_t pNCbc, std::vector<uint32_t>& pVecReq, bool pRead, bool pWrite ) {}; - void DecodeReg ( CbcRegItem& pRegItem, + void DecodeReg ( RegItem& pRegItem, uint8_t& pCbcId, uint32_t pWord, bool& pRead, @@ -123,7 +123,7 @@ public: - + @@ -233,7 +233,7 @@ public: bool BCWriteCbcBlockReg ( std::vector<uint32_t>& pVecReg, bool pReadback) {return false;}; - + void ReadCbcBlockReg ( std::vector<uint32_t>& pVecReg ) {}; @@ -246,13 +246,13 @@ public: void CbcFastReset() {}; - + void CbcHardReset() {}; void ReadNEvents (BeBoard* pBoard, uint32_t pNEvents ) {}; - + void FlashProm( const std::string& strConfig, const char* pstrFile ); /*! \brief Jump to an FPGA configuration */ void JumpToFpgaConfig( const std::string& strConfig); @@ -276,12 +276,12 @@ public: void PowerOff() override; void TestbeamInit(int sdur,int clock, int phase); void StrobeSettings(int snum, int sdel, int slen, int sdist, int cal); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> ReadMPAData(int buffernum, int mpa, bool lr); + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> ReadMPAlightData(int buffernum, int mpa, bool lr); void SequencerInit(int smode,int sdur,int mem,int ibuff); void upload(std::vector< uint32_t > *conf_upload, int conf, int nmpa, bool lr); void write(int nummpal, int nummpar); - void HeaderInitMPA(int nmpa, bool lr); + void HeaderInitMPAlight(int nmpa, bool lr); void ReadTrig(int buffer_num); int WaitSequencer(); int WaitTestbeam(); diff --git a/HWInterface/MPAlightInterface.cc b/HWInterface/MPAlightInterface.cc new file mode 100644 index 0000000000000000000000000000000000000000..2b9855d8ee46c8a7b13312d000c6f5df40a76fed --- /dev/null +++ b/HWInterface/MPAlightInterface.cc @@ -0,0 +1,497 @@ +/* + + FileName : MPAlightInterface.cc + Content : User Interface to the MPAlights + Programmer : Lorenzo BIDEGAIN, Nicolas PIERRE, Georg AUZINGER + Version : 1.0 + Date of creation : 10/07/14 + Support : mail to : lorenzo.bidegain@gmail.com, nico.pierre@icloud.com + + */ + +#include "MPAlightInterface.h" +#include "../Utils/ConsoleColor.h" +#include <typeinfo> +#define DEV_FLAG 0 +// #define COUNT_FLAG 0 + +namespace Ph2_HwInterface +{ + +MPAlightInterface::MPAlightInterface( const BeBoardFWMap& pBoardMap ) : + fBoardMap( pBoardMap ), + fBoardFW( nullptr ), + prevBoardIdentifier( 65535 ), + fRegisterCount( 0 ), + fTransactionCount( 0 ) +{ +#ifdef COUNT_FLAG + std::cout << "Counting number of Transactions!" << std::endl; +#endif +} + +MPAlightInterface::~MPAlightInterface() +{ +} + +void MPAlightInterface::setBoard( uint16_t pBoardIdentifier ) +{ + if ( prevBoardIdentifier != pBoardIdentifier ) + { + BeBoardFWMap::iterator i = fBoardMap.find( pBoardIdentifier ); + + if ( i == fBoardMap.end() ) + std::cout << "The Board: " << +( pBoardIdentifier >> 8 ) << " doesn't exist" << std::endl; + else + { + fBoardFW = i->second; + fMPAlightFW = dynamic_cast<MPAlightGlibFWInterface*>(fBoardFW); + prevBoardIdentifier = pBoardIdentifier; + } + } +} + + + + +void MPAlightInterface::setFileHandler (FileHandler* pHandler) +{ + setBoard(0); + fMPAlightFW->setFileHandler ( pHandler); +} + + + + + + +void MPAlightInterface::HeaderInitMPAlight(int nmpa, bool lr) +{ + setBoard(0); + fMPAlightFW->HeaderInitMPAlight( nmpa , lr); +} + + + +void MPAlightInterface::ConfigureMPAlight(std::vector< uint32_t >* conf_upload, int conf ,int nmpa, bool lr) +{ + setBoard(0); + fMPAlightFW->upload( conf_upload, conf,nmpa , lr); +} + +void MPAlightInterface::SendConfig(int nummpal, int nummpar) +{ + setBoard(0); + fMPAlightFW->write(nummpal, nummpar); +} + + + + +int MPAlightInterface::WaitTestbeam() +{ + setBoard(0); + return fMPAlightFW->WaitTestbeam(); +} + + + + +void MPAlightInterface::SequencerInit(int smode,int sdur,int mem,int ibuff) +{ + setBoard(0); + fMPAlightFW->SequencerInit(smode,sdur,mem,ibuff); +} + + +void MPAlightInterface::TestbeamInit(int sdur,int clock, int phase) +{ + setBoard(0); + fMPAlightFW->TestbeamInit(sdur,clock, phase); +} + + + +std::pair<std::vector<uint32_t>, std::vector<uint32_t>> MPAlightInterface::ReadMPAlightData(int buffer_num, int mpa, bool lr) +{ + setBoard(0); + fMPAlightFW->HeaderInitMPAlight( mpa , lr ); + return fMPAlightFW->ReadMPAlightData(buffer_num, mpa, lr); +} + + + +uint32_t MPAlightInterface::ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ) +{ + setBoard(0); + return fMPAlightFW->ReadData( pBoard, pBreakTrigger, pData, pWait ); +} + + + +std::vector<uint32_t>* MPAlightInterface::GetcurData() +{ + setBoard(0); + return fMPAlightFW->GetcurData(); +} + +void MPAlightInterface::ReadTrig(int buffer_num) +{ + setBoard(0); + return fMPAlightFW->ReadTrig(buffer_num); +} + + + +void MPAlightInterface::Cleardata() +{ + setBoard(0); + fMPAlightFW->Cleardata( ); +} + + + + + + + + + +std::pair<std::vector<uint32_t>, std::vector<std::string>> MPAlightInterface::FormatData(std::pair<std::vector<uint32_t>, std::vector<uint32_t>> data) +{ + std::vector<uint32_t> counter_data = data.first; + std::vector<uint32_t> memory_data = data.second; + std::vector<uint32_t> bitpix(50); + std::vector<std::string> mem(96); + + for (int x=0;x<24; x++) + { + int shift1 = 0; + int shift2 = 16; + + + + uint32_t l((counter_data[x+1] >> shift1) & 0xFFFF); + uint32_t r((counter_data[x+1] >> shift2) & 0xFFFF); + bitpix[2*x] = l; + bitpix[2*x+1] = r; + + } + + std::bitset<32> y(memory_data[215]); + std::string memory_string = y.to_string(); + for (int x=1;x<216; x++) + { + std::bitset<32> y(memory_data[215 - x]); + memory_string = memory_string + y.to_string(); + } + for (int x=0;x<96; x++) + { + mem[x] = memory_string.substr(x*72, 72); + + } + std::pair<std::vector<uint32_t>, std::vector<std::string>> returndata(bitpix,mem); + return returndata; +} + +std::pair<std::vector<uint32_t>, std::vector<uint64_t>> MPAlightInterface::ReadMemory(std::vector<std::string> intmemory, int mode) +{ + std::string memory; + std::vector<uint32_t> BX(96); + uint64_t hit; + std::vector<int> row(96); + std::vector<int> col(96); + std::vector<uint64_t> data(96); + std::vector<int> bend(96); + std::string header; + //Only implements noprocessing mode + if (mode == 3) + { + for (int x=0;x<96; x++) + { + + header = intmemory[x].substr(0, 8); + if (header != "11111111") break; + + std::bitset<16> b(intmemory[x].substr(8, 16)); + BX[x] = b.to_ulong(); + + std::bitset<48> p(intmemory[x].substr(24, 48)); + hit = p.to_ulong(); + + data[x]=hit; + } + + } + + std::pair<std::vector<uint32_t>, std::vector<uint64_t>> returndata(BX, data); + return returndata; + +} + + +std::vector< uint32_t > MPAlightInterface::ReadConfig(const std::string& pFilename, int nmpa, int conf) +{ + + pugi::xml_document doc; + std::string fullname = "settings/MPAlightFiles/Conf_"+pFilename+"_MPA"+std::to_string(nmpa)+"_config"+std::to_string(conf)+".xml"; + pugi::xml_parse_result result = doc.load_file( fullname.c_str() ); + if ( !result ) + { + std::cout << "ERROR :\n Unable to open the file : " << pFilename << std::endl; + std::cout << "Error description : " << result.description() << std::endl; + } + + std::vector< uint32_t > conf_upload(25); + int perif = -1; + for ( pugi::xml_node cBeBoardNode = doc.child( "CONF" ).child( "periphery" ).first_child(); cBeBoardNode; cBeBoardNode = cBeBoardNode.next_sibling() ) + { + if (static_cast<std::string>(cBeBoardNode.name())=="OM") perif = convertAnyInt(cBeBoardNode.child_value()); + if (static_cast<std::string>(cBeBoardNode.name())=="RT") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 3) << 2 ); + if (static_cast<std::string>(cBeBoardNode.name())=="SCW") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 4 ); + if (static_cast<std::string>(cBeBoardNode.name())=="SH2") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 8 ); + if (static_cast<std::string>(cBeBoardNode.name())=="SH1") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 15) << 12); + if (static_cast<std::string>(cBeBoardNode.name())=="CALDAC") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 255) << 16); + if (static_cast<std::string>(cBeBoardNode.name())=="THDAC") perif |= ((convertAnyInt(cBeBoardNode.child_value())& 255) << 24); + } + conf_upload[0] = perif; + for ( pugi::xml_node cBeBoardNode = doc.child( "CONF" ).first_child(); cBeBoardNode; cBeBoardNode = cBeBoardNode.next_sibling() ) + { + int pix = 0; + if (static_cast<std::string>(cBeBoardNode.name())=="pixel") + { + int pixnum = convertAnyInt(cBeBoardNode.attribute("n").value()); + + if (pixnum<17 and pixnum>8) + { + for ( pugi::xml_node cBeBoardNode1 = cBeBoardNode.first_child(); cBeBoardNode1; cBeBoardNode1 = cBeBoardNode1.next_sibling() ) + { + if (static_cast<std::string>(cBeBoardNode1.name())=="PMR") pix |= convertAnyInt(cBeBoardNode1.child_value()); + if (static_cast<std::string>(cBeBoardNode1.name())=="ARR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 1 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 2 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="CER") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 7 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="SP") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 8 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="SR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 9 ) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="PML") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 10); + if (static_cast<std::string>(cBeBoardNode1.name())=="ARL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 11) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 12) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="CEL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 17); + if (static_cast<std::string>(cBeBoardNode1.name())=="CW") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 2) << 18); + + + } + } + else if (pixnum<25 and pixnum>0) + { + for ( pugi::xml_node cBeBoardNode1 = cBeBoardNode.first_child(); cBeBoardNode1; cBeBoardNode1 = cBeBoardNode1.next_sibling() ) + { + if (static_cast<std::string>(cBeBoardNode1.name())=="PML") pix |= convertAnyInt(cBeBoardNode1.child_value()); + if (static_cast<std::string>(cBeBoardNode1.name())=="ARL") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 1 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 31) << 2 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="CEL") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 7 ) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="CW") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 3) << 8 ); + if (static_cast<std::string>(cBeBoardNode1.name())=="PMR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 10) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="ARR") pix |= ((convertAnyInt(cBeBoardNode1.child_value())& 1) << 11); + if (static_cast<std::string>(cBeBoardNode1.name())=="TRIMDACR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 31) << 12) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="CER") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 17) ; + if (static_cast<std::string>(cBeBoardNode1.name())=="SP") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 18); + if (static_cast<std::string>(cBeBoardNode1.name())=="SR") pix |= ((convertAnyInt(cBeBoardNode1.child_value()) & 1) << 19); + + } + } + conf_upload[pixnum] = pix; + } + + } + return conf_upload; +} + + + + +void MPAlightInterface::ModifyPerif(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload) +{ + std::vector<std::string> vars = mod.first; + std::vector< uint32_t > vals = mod.second; + uint32_t perif = conf_upload->at(0); + + for (uint32_t iperif=0;iperif<vars.size(); iperif++) + { + if (vars[iperif]=="OM") + { + perif = (perif&~3); + perif |= (vals[iperif]); + } + if (vars[iperif]=="RT") + { + perif = (perif&~(3<<2)); + perif |= ((vals[iperif]& 3) << 2 ); + } + if (vars[iperif]=="SCW") + { + perif = (perif&~(15<<4)); + perif |= ((vals[iperif]& 15) << 4 ); + } + if (vars[iperif]=="SH2") + { + perif = (perif&~(15<<8)); + perif |= ((vals[iperif]& 15) << 8 ); + } + if (vars[iperif]=="SH1") + { + perif = (perif&~(15<<12)); + perif |= ((vals[iperif]& 15) << 12); + } + if (vars[iperif]=="CALDAC") + { + perif = (perif&~(255<<16)); + perif |= ((vals[iperif]& 255) << 16); + } + if (vars[iperif]=="THDAC") + { + perif = (perif&~(255<<24)); + perif |= ((vals[iperif]& 255) << 24); + } + + } + conf_upload->at(0) = perif; + +} +void MPAlightInterface::ModifyPix(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload , uint32_t pixnum ) +{ + + std::vector<std::string> vars = mod.first; + std::vector< uint32_t > vals = mod.second; + + uint32_t pix = conf_upload->at(pixnum); + if (pixnum<17 and pixnum>8) + { + for (uint32_t ipix=0;ipix<vars.size(); ipix++) + { + if (vars[ipix]=="PMR") + { + pix = (pix&~1); + pix |= (vals[ipix]); + } + if (vars[ipix]=="ARR") + { + pix = (pix&~(1<<1)); + pix |= ((vals[ipix]& 1) << 1); + } + if (vars[ipix]=="TRIMDACL") + { + pix = (pix&~(31<<2)); + pix |= ((vals[ipix]& 31) << 2); + } + if (vars[ipix]=="CER") + { + pix = (pix&~(1<<7)); + pix |= ((vals[ipix]& 1) << 7); + } + if (vars[ipix]=="SP") + { + pix = (pix&~(1<<8)); + pix |= ((vals[ipix]& 1) << 8); + } + if (vars[ipix]=="SR") + { + pix = (pix&~(1<<9)); + pix |= ((vals[ipix]& 1) << 9); + } + if (vars[ipix]=="PML") + { + pix = (pix&~(1<<10)); + pix |= ((vals[ipix]& 1) << 10); + } + if (vars[ipix]=="ARL") + { + pix = (pix&~(1<<11)); + pix |= ((vals[ipix]& 1) << 11); + } + if (vars[ipix]=="TRIMDACR") + { + pix = (pix&~(31<<12)); + pix |= ((vals[ipix]& 31) << 12); + } + + if (vars[ipix]=="CEL") + { + pix = (pix&~(1<<17)); + pix |= ((vals[ipix]& 1) << 17); + } + if (vars[ipix]=="CW") + { + pix = (pix&~(2<<18)); + pix |= ((vals[ipix]& 2) << 18); + } + } + } + else if (pixnum<25 and pixnum>0) + { + for (uint32_t ipix=0;ipix<vars.size(); ipix++) + { + if (vars[ipix]=="PML") + { + pix = (pix&~1); + pix |= (vals[ipix]); + } + if (vars[ipix]=="ARL") + { + pix = (pix&~(1<<1)); + pix |= ((vals[ipix]& 1) << 1); + } + if (vars[ipix]=="TRIMDACL") + { + pix = (pix&~(31<<2)); + pix |= ((vals[ipix]& 31) << 2); + } + if (vars[ipix]=="CEL") + { + pix = (pix&~(1<<7)); + pix |= ((vals[ipix]& 1) << 7); + } + if (vars[ipix]=="CW") + { + pix = (pix&~(3<<8)); + pix |= ((vals[ipix]& 3) << 8); + } + if (vars[ipix]=="PMR") + { + pix = (pix&~(1<<10)); + pix |= ((vals[ipix]& 1) << 10); + } + if (vars[ipix]=="ARR") + { + pix = (pix&~(1<<11)); + pix |= ((vals[ipix]& 1) << 11); + } + if (vars[ipix]=="TRIMDACR") + { + pix = (pix&~(31<<12)); + pix |= ((vals[ipix]& 31) << 12); + } + if (vars[ipix]=="CER") + { + pix = (pix&~(1<<17)); + pix |= ((vals[ipix]& 1) << 17); + } + if (vars[ipix]=="SP") + { + pix = (pix&~(1<<18)); + pix |= ((vals[ipix]& 1) << 18); + } + if (vars[ipix]=="SR") + { + pix = (pix&~(1<<19)); + pix |= ((vals[ipix]& 1) << 19); + } + } + } + + + conf_upload->at(pixnum) = pix; + +} + + +} diff --git a/HWInterface/MPAlightInterface.h b/HWInterface/MPAlightInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..35da1adccb4bcf3b5e7e061964aacec5fc0bf14f --- /dev/null +++ b/HWInterface/MPAlightInterface.h @@ -0,0 +1,127 @@ +/*! + + \file MPAlightInterface.h + \brief User Interface to the MPAlights + \author Lorenzo BIDEGAIN, Nicolas PIERRE + \version 1.0 + \date 31/07/14 + Support : mail to : lorenzo.bidegain@gmail.com, nico.pierre@icloud.com + + */ + +#ifndef __MPAlightINTERFACE_H__ +#define __MPAlightINTERFACE_H__ + +#include <vector> +#include "../HWInterface/MPAlightGlibFWInterface.h" +#include "pugixml/pugixml.hpp" +using namespace Ph2_HwDescription; + +/*! + * \namespace Ph2_HwInterface + * \brief Namespace regrouping all the interfaces to the hardware + */ +namespace Ph2_HwInterface +{ + + using BeBoardFWMap = std::map<uint16_t, BeBoardFWInterface*>; /*!< Map of Board connected */ + + /*! + * \class MPAlightInterface + * \brief Class representing the User Interface to the MPAlight on different boards + */ + class MPAlightInterface + { + + private: + BeBoardFWMap fBoardMap; /*!< Map of Board connected */ + BeBoardFWInterface* fBoardFW; /*!< Board loaded */ + MPAlightGlibFWInterface* fMPAlightFW; /*!< Board loaded */ + uint16_t prevBoardIdentifier; /*!< Id of the previous board */ + + uint16_t fRegisterCount; /*!< Counter for the number of Registers written */ + uint16_t fTransactionCount; /*!< Counter for the number of Transactions */ + + + private: + /*! + * \brief Set the board to talk with + * \param pBoardId + */ + void setBoard( uint16_t pBoardIdentifier ); + + public: + /*! + * \brief Constructor of the MPAlightInterface Class + * \param pBoardMap + */ + MPAlightInterface( const BeBoardFWMap& pBoardMap ); + /*! + * \brief Destructor of the MPAlightInterface Class + */ + ~MPAlightInterface(); + + void setFileHandler (FileHandler* pHandler); + + + /*! + * \uploads configuration data to glib + */ + void ConfigureMPAlight(std::vector< uint32_t >* conf_upload, int conf ,int nmpa, bool lr); + + /*! + * \sends configuration data to MAPSA from glib + */ + void SendConfig(int nummpal, int nummpar); + + + void ReadTrig(int buffer_num); + + std::vector<uint32_t>* GetcurData(); + + /*! + * \initializes AR header + */ + void HeaderInitMPAlight(int nmpa, bool lr); + + /*! + * \modify periphery configuration + */ + void ModifyPerif(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload); + int WaitTestbeam(); + /*! + * \modify pixel configuration for pixel pixnum + */ + void ModifyPix(std::pair < std::vector< std::string > ,std::vector< uint32_t >> mod , std::vector< uint32_t >* conf_upload, uint32_t pixnum ); + + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> ReadMPAlightData(int buffer_num, int mpa, bool lr); + + uint32_t ReadData( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait ); + /*! + * \format the raw data output of ReadData to organize into events. Segmented due to processing time + */ + std::pair<std::vector<uint32_t>, std::vector<std::string>> FormatData(std::pair<std::vector<uint32_t>, std::vector<uint32_t>> data); + + /*! + * \further formats the output of FormatData to a human readable format. Segmented due to processing time + */ + std::pair<std::vector<uint32_t>, std::vector<uint64_t>> ReadMemory(std::vector<std::string> intmemory, int mode); + + /*! + * \reads in in configuration data from xml file for mpa nmpa and configuration number conf + */ + std::vector< uint32_t > ReadConfig(const std::string& pFilename, int nmpa, int conf); + + /*! + * \initializes sequencer (starts daq) + */ + void SequencerInit(int smode,int sdur,int mem,int ibuff); + + void TestbeamInit(int sdur,int clock, int phase); + + + void Cleardata(); + }; +} + +#endif diff --git a/HWInterface/SSAInterface.cc b/HWInterface/SSAInterface.cc new file mode 100644 index 0000000000000000000000000000000000000000..685d4861a5cbe2eb0146eead53c906e12be3f174 --- /dev/null +++ b/HWInterface/SSAInterface.cc @@ -0,0 +1,79 @@ +/* + + FileName : SSAInterface.cc + Content : User Interface to the SSAs + Programmer : Lorenzo BIDEGAIN, Nicolas PIERRE, Georg AUZINGER + Version : 1.0 + Date of creation : 10/07/14 + Support : mail to : lorenzo.bidegain@gmail.com, nico.pierre@icloud.com + + */ + +#include "SSAInterface.h" +#include "../Utils/ConsoleColor.h" +#include <typeinfo> +#define DEV_FLAG 0 +// #define COUNT_FLAG 0 + +namespace Ph2_HwInterface +{ + +SSAInterface::SSAInterface( const BeBoardFWMap& pBoardMap ) : + fBoardMap( pBoardMap ), + fBoardFW( nullptr ), + prevBoardIdentifier( 65535 ), + fRegisterCount( 0 ), + fTransactionCount( 0 ) +{ +#ifdef COUNT_FLAG + std::cout << "Counting number of Transactions!" << std::endl; +#endif +} + +SSAInterface::~SSAInterface() +{ +} + +void SSAInterface::setBoard( uint16_t pBoardIdentifier ) +{ + if ( prevBoardIdentifier != pBoardIdentifier ) + { + BeBoardFWMap::iterator i = fBoardMap.find( pBoardIdentifier ); + + if ( i == fBoardMap.end() ) + std::cout << "The Board: " << +( pBoardIdentifier >> 8 ) << " doesn't exist" << std::endl; + else + { + fBoardFW = i->second; + fSSAFW = dynamic_cast<D19cFWInterface*>(fBoardFW); + prevBoardIdentifier = pBoardIdentifier; + } + } +} + +void SSAInterface::SCurves() +{ + std::cout << ":::] MEASURING S-CURVES" << std::endl; + ssaEnableAsyncRO(true); + ssaEnableAsyncRO(false); +} + +void SSAInterface::ssaEnableAsyncRO(bool value) +{ + std::cout << ":::] ASYNC --- Enabled" << std::endl; + // write 0b01 to ReadoutMode + // write 0 to AsyncRead_StartDel_MSB + // write 8 to AsyncRead_StartDel_LSB + // read and check last line + // tell Fc7 to write 8 to cnfg_phy_slvs_ssa_first_counter_del +} + + +void SSAInterface::setFileHandler (FileHandler* pHandler) +{ + setBoard(0); + fSSAFW->setFileHandler ( pHandler); +} + + +} diff --git a/HWInterface/SSAInterface.h b/HWInterface/SSAInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..4b56d1b9af7d21cf14e40fb15205c8f54aa679ed --- /dev/null +++ b/HWInterface/SSAInterface.h @@ -0,0 +1,76 @@ +/*! + + \file SSAInterface.h + \brief User Interface to the SSAs + \author Lorenzo BIDEGAIN, Nicolas PIERRE + \version 1.0 + \date 31/07/14 + Support : mail to : lorenzo.bidegain@gmail.com, nico.pierre@icloud.com + + */ + +#ifndef __SSAINTERFACE_H__ +#define __SSAINTERFACE_H__ + +#include <vector> +#include "../HWInterface/D19cFWInterface.h" +#include "pugixml/pugixml.hpp" +using namespace Ph2_HwDescription; + +/*! + * \namespace Ph2_HwInterface + * \brief Namespace regrouping all the interfaces to the hardware + */ +namespace Ph2_HwInterface +{ + + using BeBoardFWMap = std::map<uint16_t, BeBoardFWInterface*>; /*!< Map of Board connected */ + + /*! + * \class SSAInterface + * \brief Class representing the User Interface to the SSA on different boards + */ + class SSAInterface + { + + private: + BeBoardFWMap fBoardMap; /*!< Map of Board connected */ + BeBoardFWInterface* fBoardFW; /*!< Board loaded */ + D19cFWInterface* fSSAFW; /*!< Board loaded */ + uint16_t prevBoardIdentifier; /*!< Id of the previous board */ + + uint16_t fRegisterCount; /*!< Counter for the number of Registers written */ + uint16_t fTransactionCount; /*!< Counter for the number of Transactions */ + + + private: + /*! + * \brief Set the board to talk with + * \param pBoardId + */ + void setBoard( uint16_t pBoardIdentifier ); + + public: + /*! + * \brief Constructor of the SSAInterface Class + * \param pBoardMap + */ + SSAInterface( const BeBoardFWMap& pBoardMap ); + /*! + * \brief Destructor of the SSAInterface Class + */ + ~SSAInterface(); + + void setFileHandler (FileHandler* pHandler); + void SCurves (); + + void ssaEnableAsyncRO(bool value); + /*! + * \uploads configuration data to glib + */ + void ConfigureSSA(std::vector< uint32_t >* conf_upload, int conf ,int nSSA, bool lr); + + }; +} + +#endif diff --git a/HWInterface/dummy.xml b/HWInterface/dummy.xml old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/RootWeb/example.sh b/RootWeb/example.sh old mode 100755 new mode 100644 diff --git a/System/FileParser.cc b/System/FileParser.cc index 3ce1ea9a7200e56e13e19b155cc20612b96dbe3a..037f989c26ae6eb16398ba68aa4069a6d175bbd6 100644 --- a/System/FileParser.cc +++ b/System/FileParser.cc @@ -110,8 +110,8 @@ namespace Ph2_System { pBeBoardFWMap[cBeBoard->getBeBoardIdentifier()] = new Cbc3Fc7FWInterface ( cId.c_str(), cUri.c_str(), cAddressTable.c_str() ); else if (cBeBoard->getBoardType() == BoardType::D19C) pBeBoardFWMap[cBeBoard->getBeBoardIdentifier()] = new D19cFWInterface ( cId.c_str(), cUri.c_str(), cAddressTable.c_str() ); - else if (cBeBoard->getBoardType() == BoardType::MPAGLIB) - pBeBoardFWMap[cBeBoard->getBeBoardIdentifier()] = new MPAGlibFWInterface ( cId.c_str(), cUri.c_str(), cAddressTable.c_str() ); + else if (cBeBoard->getBoardType() == BoardType::MPAlightGLIB) + pBeBoardFWMap[cBeBoard->getBeBoardIdentifier()] = new MPAlightGlibFWInterface ( cId.c_str(), cUri.c_str(), cAddressTable.c_str() ); //else //cBeBoardFWInterface = new OtherFWInterface(); @@ -134,7 +134,14 @@ namespace Ph2_System { Module* cModule = new Module ( cBeId, cModuleNode.attribute ( "FMCId" ).as_int(), cModuleNode.attribute ( "FeId" ).as_int(), cModuleId ); cBeBoard->addModule ( cModule ); - this->parseCbc (cModuleNode, cModule, os); + this->parseCbc (cModuleNode, cModule, os); + this->parseMPA (cModuleNode, cModule, os); + if (cModule->getNCbc() > 0) { + cBeBoard->setChipType(ChipType::CBC3); + } else if (cModule->getNMPA() > 0) { + cBeBoard->setChipType(ChipType::MPA); + } + } } } @@ -198,7 +205,7 @@ namespace Ph2_System { else if (cBoardType == "ICFC7") cBeBoard->setBoardType (BoardType::ICFC7); else if (cBoardType == "CBC3FC7") cBeBoard->setBoardType (BoardType::CBC3FC7); else if (cBoardType == "D19C") cBeBoard->setBoardType (BoardType::D19C); - else if (cBoardType == "MPAGLIB") cBeBoard->setBoardType (BoardType::MPAGLIB); + else if (cBoardType == "MPAlightGLIB") cBeBoard->setBoardType (BoardType::MPAlightGLIB); else { LOG (ERROR) << "Error: Unknown Board Type: " << cBoardType << " - aborting!"; @@ -349,7 +356,7 @@ namespace Ph2_System { if (cCbc->getCbcId() != cCbcId) continue; else if (cCbc->getFeId() == cFeId && cCbc->getCbcId() == cCbcId) { - CbcRegItem cRegItem = cCbc->getRegItem ( cRegName ); + RegItem cRegItem = cCbc->getRegItem ( cRegName ); cPage = cRegItem.fPage; cAddress = cRegItem.fAddress; cValue = cRegItem.fValue; @@ -424,6 +431,46 @@ namespace Ph2_System { this->parseGlobalCbcSettings (pModuleNode, pModule, os); } + + + + void FileParser::parseMPA (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os ) + { + pugi::xml_node cMPAPathPrefixNode = pModuleNode.child ( "MPA_Files" ); + std::string cFilePrefix = expandEnvironmentVariables (static_cast<std::string> ( cMPAPathPrefixNode.attribute ( "path" ).value() ) ); + + if ( !cFilePrefix.empty() ) os << GREEN << "|" << " " << "|" << " " << "|" << "----" << "MPA Files Path : " << cFilePrefix << RESET << std::endl; + + // Iterate the MPA node + for ( pugi::xml_node cMPANode = pModuleNode.child ( "MPA" ); cMPANode; cMPANode = cMPANode.next_sibling() ) + { + os << BOLDCYAN << "|" << " " << "|" << " " << "|" << "----" << cMPANode.name() << " " + << cMPANode.first_attribute().name() << " :" << cMPANode.attribute ( "Id" ).value() + << ", File: " << expandEnvironmentVariables (cMPANode.attribute ( "configfile" ).value() ) << RESET << std:: endl; + + std::string cFileName; + + if ( !cFilePrefix.empty() ) + { + if (cFilePrefix.at (cFilePrefix.length() - 1) != '/') + cFilePrefix.append ("/"); + + cFileName = cFilePrefix + expandEnvironmentVariables (cMPANode.attribute ( "configfile" ).value() ); + } + else cFileName = expandEnvironmentVariables (cMPANode.attribute ( "configfile" ).value() ); + + MPA* cMPA = new MPA ( pModule->getBeId(), pModuleNode.attribute ( "FMCId" ).as_int(), pModuleNode.attribute ( "FeId" ).as_int(), cMPANode.attribute ( "Id" ).as_int(), cFileName ); + + pModule->addMPA (cMPA); + } + + // parse the GlobalMPASettings so that Global CBC regisers take precedence over Global CBC settings which take precedence over CBC specific settings + //this->parseGlobalCbcSettings (pModuleNode, pModule, os); + } + + + + void FileParser::parseGlobalCbcSettings (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os) { //use this to parse GlobalCBCRegisters and the Global CBC settings diff --git a/System/FileParser.h b/System/FileParser.h index dd294b13d741116c9fbffb215c5597738c9c39fd..159789899e91a7f0ea527d4ea5725a490954078a 100644 --- a/System/FileParser.h +++ b/System/FileParser.h @@ -23,7 +23,7 @@ #include "../HWInterface/ICFc7FWInterface.h" #include "../HWInterface/Cbc3Fc7FWInterface.h" #include "../HWInterface/D19cFWInterface.h" -#include "../HWInterface/MPAGlibFWInterface.h" +#include "../HWInterface/MPAlightGlibFWInterface.h" #include "../HWDescription/Definition.h" #include "../Utils/Utilities.h" #include "../Utils/Exception.h" @@ -111,6 +111,8 @@ namespace Ph2_System { BeBoard* parseBeBoard (pugi::xml_node pNode, BeBoardVec& pBoardVector, std::ostream& os ); void parseRegister (pugi::xml_node pNode, std::string& pAttributeString, uint32_t& pValue, BeBoard* pBoard, std::ostream& os ); void parseSLink (pugi::xml_node pSLinkNode, BeBoard* pBoard, std::ostream& os ); + void parseMPA (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os ); + void parseCbc (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os ); void parseCbcSettings (pugi::xml_node pCbcNode, Cbc* pCbc, std::ostream& os); void parseGlobalCbcSettings (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os); diff --git a/System/SystemController.cc b/System/SystemController.cc index 91c76ecb94d522b7e4463f4ca423b013f4643bdc..575c647fed89061ba30899161c023ab20892782c 100644 --- a/System/SystemController.cc +++ b/System/SystemController.cc @@ -119,6 +119,8 @@ namespace Ph2_System { fBeBoardInterface = new BeBoardInterface ( fBeBoardFWMap ); fCbcInterface = new CbcInterface ( fBeBoardFWMap ); + fMPAlightInterface = new MPAlightInterface ( fBeBoardFWMap ); + fSSAInterface = new SSAInterface ( fBeBoardFWMap ); fMPAInterface = new MPAInterface ( fBeBoardFWMap ); if (fWriteHandlerEnabled) @@ -172,6 +174,14 @@ namespace Ph2_System { LOG (INFO) << GREEN << "Successfully configured Cbc " << int ( cCbc->getCbcId() ) << RESET; } } + for (auto& cMPA : cFe->fMPAVector) + { + if ( !bIgnoreI2c ) + { + fMPAInterface->ConfigureMPA ( cMPA ); + LOG (INFO) << GREEN << "Successfully configured MPA " << int ( cMPA->getMPAId() ) << RESET; + } + } } //CbcFastReset as per recommendation of Mark Raymond @@ -198,8 +208,8 @@ namespace Ph2_System { if (cBoardType == BoardType::GLIB) cBoardTypeString = "GLIB"; - else if (cBoardType == BoardType::MPAGLIB) - cBoardTypeString = "MPAGLIB"; + else if (cBoardType == BoardType::MPAlightGLIB) + cBoardTypeString = "MPAlightGLIB"; else if (cBoardType == BoardType::CTA) cBoardTypeString = "CTA"; else if (cBoardType == BoardType::ICGLIB) @@ -237,10 +247,17 @@ namespace Ph2_System { { uint32_t cNEventSize32 = 0; uint32_t cNCbc = 0; + uint32_t cNMPA = 0; + uint32_t cNSSA = 0; uint32_t cNFe = pBoard->getNFe(); for (const auto& cFe : pBoard->fModuleVector) + { cNCbc += cFe->getNCbc(); + cNMPA += cFe->getNMPA(); + cNSSA += cFe->getNSSA(); + } + if (pBoard->getBoardType() == BoardType::GLIB) { @@ -254,9 +271,8 @@ namespace Ph2_System { cNEventSize32 = EVENT_HEADER_SIZE_32 + 16 * CBC_EVENT_SIZE_32; } - if (pBoard->getBoardType() == BoardType::MPAGLIB) - cNEventSize32 = MPA_HEADER_SIZE_32 + 6 * MPA_EVENT_SIZE_32; - + if (pBoard->getBoardType() == BoardType::MPAlightGLIB) + cNEventSize32 = MPAlight_HEADER_SIZE_32 + 6 * MPAlight_EVENT_SIZE_32; else if (pBoard->getBoardType() == BoardType::CTA) { //this is legacy as the fNCbcDataSize is not used any more @@ -275,8 +291,13 @@ namespace Ph2_System { else if (pBoard->getBoardType() == BoardType::CBC3FC7) cNEventSize32 = EVENT_HEADER_TDC_SIZE_32_CBC3 + cNCbc * CBC_EVENT_SIZE_32_CBC3; else if (pBoard->getBoardType() == BoardType::D19C) - cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3; - + if (cNCbc>0) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3; + if (cNMPA>0) cNEventSize32 = 30;//cant do this; + if (cNCbc>0 && cNMPA>0) + { + LOG(INFO) << "Not configurable for multiple chips"; + exit (1); + } return cNEventSize32; } @@ -349,6 +370,7 @@ namespace Ph2_System { uint32_t cNPackets = fBeBoardInterface->ReadData (pBoard, false, pData, pWait); //pass data by reference to set and let it know what board we are dealing with fData->Set (pBoard, pData, cNPackets, fBeBoardInterface->getBoardType (pBoard) ); + //return the packet size return cNPackets; } diff --git a/System/SystemController.h b/System/SystemController.h index f11c0a2b972bdcf5bd777b0c8990fe0d814f4318..09ec5c0a436d557005cc14c6ac9f5c34fe514fe7 100644 --- a/System/SystemController.h +++ b/System/SystemController.h @@ -15,6 +15,8 @@ #include "FileParser.h" #include "../HWInterface/CbcInterface.h" +#include "../HWInterface/MPAlightInterface.h" +#include "../HWInterface/SSAInterface.h" #include "../HWInterface/MPAInterface.h" #include "../HWInterface/BeBoardInterface.h" #include "../HWInterface/BeBoardFWInterface.h" @@ -59,6 +61,8 @@ namespace Ph2_System { public: BeBoardInterface* fBeBoardInterface; /*!< Interface to the BeBoard */ CbcInterface* fCbcInterface; /*!< Interface to the Cbc */ + MPAlightInterface* fMPAlightInterface; /*!< Interface to the Cbc */ + SSAInterface* fSSAInterface; /*!< Interface to the Cbc */ MPAInterface* fMPAInterface; /*!< Interface to the Cbc */ BeBoardVec fBoardVector; /*!< Vector of Board pointers */ BeBoardFWMap fBeBoardFWMap; diff --git a/Utils/CMakeLists.txt b/Utils/CMakeLists.txt index ee8941340f6d786eeb008e7eea63f0db8ec7d79d..60903edd73b8d5d3267a572a4a31448fd60c1d2b 100644 --- a/Utils/CMakeLists.txt +++ b/Utils/CMakeLists.txt @@ -17,7 +17,7 @@ if(NOT DEFINED ENV{OTSDAQ_CMSOUTERTRACKER_DIR}) #add the library add_library(Ph2_Utils SHARED ${SOURCES} ${HEADERS}) - set(LIBS ${LIBS} cactus_extern_pugixml) + #set(LIBS ${LIBS} pugixml) TARGET_LINK_LIBRARIES(Ph2_Utils ${LIBS}) #check for ZMQ installed diff --git a/Utils/D19cCbc3Event.cc b/Utils/D19cCbc3Event.cc index 1608beaaf642f5cb32c10cc1f78ae17af8b80d8a..e290efe3694e09755ec3bc943a5feab705baa59f 100644 --- a/Utils/D19cCbc3Event.cc +++ b/Utils/D19cCbc3Event.cc @@ -50,7 +50,7 @@ namespace Ph2_HwInterface { if (fEventSize != list.size() ) LOG (ERROR) << "Vector size doesnt match the BLOCK_SIZE in Header1"; - // dummy size + fDummySize = (0xFF & list.at (1) ) >> 0; fDummySize *= 4; @@ -68,7 +68,7 @@ namespace Ph2_HwInterface { fEventDataSize = fEventSize; // not iterate through modules - uint32_t address_offset = D19C_EVENT_HEADER1_SIZE_32_CBC3; + uint32_t address_offset = D19C_EVENT_HEADER1_SIZE_32; while(address_offset < fEventSize-fDummySize) { if (((list.at(address_offset) >> 28) & 0xF) == 0b1010) { diff --git a/Utils/D19cCbc3EventZS.cc b/Utils/D19cCbc3EventZS.cc index e119fde6bcad419ead6c3ed6bb37db0cc0c69e78..eee3e923054181751037948b0434ac583cd62dc2 100644 --- a/Utils/D19cCbc3EventZS.cc +++ b/Utils/D19cCbc3EventZS.cc @@ -25,7 +25,7 @@ namespace Ph2_HwInterface { void D19cCbc3EventZS::SetEvent ( const BeBoard* pBoard, uint32_t pZSEventSize, const std::vector<uint32_t>& list) { //LOG(INFO) << "event size: " << +pZSEventSize; - + // these two values come from width of the hybrid/cbc enabled mask uint8_t fMaxHybrids = 8; @@ -34,11 +34,11 @@ namespace Ph2_HwInterface { //LOG (INFO) << "Block size: " << fEventSize; if (fEventSize != list.size() || fEventSize != pZSEventSize ) - LOG (ERROR) << "Vector size doesnt match the BLOCK_SIZE in Header1"; + LOG (ERROR) << "Vector size doesnt match the BLOCK_SIZE in Header1"; uint8_t header1_size = (0xFF000000 & list.at (0) ) >> 24; - if (header1_size != D19C_EVENT_HEADER1_SIZE_32_CBC3) + if (header1_size != D19C_EVENT_HEADER1_SIZE_32) LOG (ERROR) << "Misaligned data: Header1 size doesnt correspond to the one sent from firmware"; fNFe_software = static_cast<uint8_t> (pBoard->getNFe() ); @@ -72,7 +72,7 @@ namespace Ph2_HwInterface { fEventDataSize = fEventSize; // now iterate through modules - uint32_t address_offset = D19C_EVENT_HEADER1_SIZE_32_CBC3; + uint32_t address_offset = D19C_EVENT_HEADER1_SIZE_32; for (uint8_t cFe = 0; cFe < fNFe_software; cFe++) { @@ -86,13 +86,10 @@ namespace Ph2_HwInterface { uint8_t header2_size = (0x00FF0000 & list.at (address_offset + 0) ) >> 16; //LOG(INFO) << "FE Data Size: " << +fe_data_size; - - uint8_t cChipIDPrev = 255; // to be sure that we are starting from new chip everytime uint32_t word_id = address_offset; while (word_id < (address_offset + (fe_data_size - 1))) { - uint8_t cChipID = (0xE0000000 & list.at(word_id)) >> 29; //LOG(INFO) << "ChipId: " << +cChipID << ", Word ID: " << +word_id; diff --git a/Utils/D19cMPAEvent.cc b/Utils/D19cMPAEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..f85c6204ac2610f1c328b7e5b4578565fba8eb00 --- /dev/null +++ b/Utils/D19cMPAEvent.cc @@ -0,0 +1,616 @@ +/* + + FileName : Event.cc + Content : Event handling from DAQ + Programmer : Nicolas PIERRE + Version : 1.0 + Date of creation : 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#include "../Utils/D19cMPAEvent.h" + +using namespace Ph2_HwDescription; + + +namespace Ph2_HwInterface { + + // Event implementation + D19cMPAEvent::D19cMPAEvent ( const BeBoard* pBoard, uint32_t pNbMPA, const std::vector<uint32_t>& list ) + { + SetEvent ( pBoard, pNbMPA, list ); + } + + void D19cMPAEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbMPA, const std::vector<uint32_t>& list ) + { + uint8_t fMaxHybrids=0; + uint16_t cH1size_32_MPA = 4 ; + uint16_t index = cH1size_32_MPA; + std::set<uint16_t> HybridIds; + while(index<list.size()) + { + uint16_t cSPLeading = ((0xF0000000 & list.at (index)) >> 28 ); + if(cSPLeading!= 0x5 and cSPLeading!= 0xA)break; + uint16_t fHID=((0x00FF0000 & list.at (index))>>16) ; + if(HybridIds.find(fHID)==HybridIds.end()) + { + fMaxHybrids+=1; + HybridIds.insert(fHID); + } + index+=((0x00000FFF & list.at (index)))*4 ; + } + + fEventSize = 4*((0x0000FFFF & list.at (0)) - (0x000000FF & list.at (1))); + if (fEventSize!=list.size() ) + LOG (ERROR) << "Incorrect event size"; + + + uint16_t cLeading = ((0xFFFF0000 & list.at (0)) >> 16 ); + if (cLeading != 0xFFFF ) + LOG (ERROR) << "Incorrect leading bits"; + + fDummySize = (0x000000FF & list.at (1)); + fCBCDataType = ((0x0000FF00 & list.at(1))) >> 8; + fTLUTriggerID = ((0xFFFF0000 & list.at (1)) ) >> 16; + + fEventCount = (0x00FFFFFF & list.at (2)); + fTDC = ((0xFF000000 & list.at (2))) >>24; + + if (fTDC >= 5) fTDC-=5; + else fTDC+=3; + + fBunch = (0xFFFFFFFF & list.at (3)); + + + fBeId = pBoard->getBeId(); + fBeFWType = 0; + fBeStatus = 0; + fEventDataSize = fEventSize; + + // not iterate through modules + uint32_t address_offset = D19C_EVENT_HEADER1_SIZE_32; + uint32_t data_offset = address_offset; + + + + // iterating through the first hybrid chips + + for (uint8_t pFeId = 0; pFeId < fMaxHybrids; pFeId++) + { + + for (uint8_t pMPAId = 0; pMPAId < pNbMPA; pMPAId++ ) + { + + + uint8_t cPLeadingMPA = ((0xF0000000 & list.at (data_offset)) >> 28 ); + uint8_t cErrorMPA = ((0x0F000000 & list.at (data_offset)) >> 24 ); + uint8_t cHidMPA = ((0x00FF0000 & list.at (data_offset)) >> 16 ); + uint8_t cCidMPA = ((0x0000F000 & list.at (data_offset)) >> 16 ); + uint16_t cL1size_32_MPA = ((0x00000FFF & list.at (data_offset)))*4; + + + uint16_t cFrameDelay = (0x00000FFF & list.at (data_offset+1)) ; + uint8_t cChipType = (0x0000F000 & list.at (data_offset+1)) ; + uint8_t cSsize_32_MPA =0; + + cSsize_32_MPA = ((0x00000FFF & list.at (data_offset+cL1size_32_MPA)))*4; + uint8_t cSLeadingMPA = ((0xF0000000 & list.at (data_offset+cL1size_32_MPA)) >> 28 ); + uint16_t cSdelay = ((0x00FFF000 & list.at (data_offset+cL1size_32_MPA))>>12); + + uint8_t cSyncBit1 = ((0x00008000 & list.at (data_offset+cL1size_32_MPA+1)) >> 15); + uint8_t cSyncBit2 = ((0x00004000 & list.at (data_offset+cL1size_32_MPA+1)) >> 14); + + + if (cPLeadingMPA != 0xA ) LOG (ERROR) << "Incorrect L1A header for MPA " << unsigned(pMPAId); + if (cSLeadingMPA != 0x5 ) LOG (ERROR) << "Incorrect stub header for MPA " << unsigned(pMPAId); + if (cErrorMPA != 0) LOG (INFO) << BOLDRED << "Error code " << unsigned(cErrorMPA) <<" for MPA " << unsigned(pMPAId); + if (cSyncBit1!=1) LOG (INFO) << BOLDRED << "Warning, sync bit 1 not 1, data frame probably misaligned!" << RESET; + if (cSyncBit2!=0) LOG (INFO) << BOLDRED << "Warning, sync bit 2 not 0, data frame probably misaligned!" << RESET; + + uint16_t cKey = encodeId (pFeId, pMPAId); + + + uint32_t begin = data_offset; + uint16_t cFevSize = cL1size_32_MPA+cSsize_32_MPA; + + uint32_t end = begin + cFevSize; + + std::vector<uint32_t> cMPAData (std::next (std::begin (list), begin), std::next (std::begin (list), end) ); + + fEventDataMap[cKey] = cMPAData; + data_offset += cFevSize; + + + } + address_offset = data_offset; // probably needs to be fixed + } + } + + bool D19cMPAEvent::Error(uint8_t pFeId, uint8_t pMPAId, uint32_t i) const + { + uint32_t error = Error(pFeId, pMPAId); + if (i == 0) return ((error & 0x1) >> 0); + else if (i == 1) return ((error & 0x2) >> 1); + else { + LOG(ERROR) << "bit id must be less or equals 1"; + return true; + } + } + + uint32_t D19cMPAEvent::Error ( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint32_t cError = ( (cData->second.at(0) & 0x00000003) >> 0 ); + return cError; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + uint16_t D19cMPAEvent::GetMPAL1Counter( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint16_t L1cnt = ( (cData->second.at(2) & 0x01FF0000) >> 16); + return L1cnt; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + uint8_t D19cMPAEvent::GetMPAChipType( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint8_t MPACT = ( (cData->second.at(1) & 0x0000F000) >> 12); + return MPACT; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + uint8_t D19cMPAEvent::GetMPAChipID( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint8_t MPACID = ( (cData->second.at(0) & 0x0000F000) >> 12); + return MPACID; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + uint16_t D19cMPAEvent::GetMPAHybridID( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint16_t MPAHID = ( (cData->second.at(0) & 0x00FF0000) >> 16); + return MPAHID; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + + + uint8_t D19cMPAEvent::GetMPAError( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint8_t MPAERR = ( (cData->second.at(0) & 0xC0000000) >> 30); + return MPAERR; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + + + + + uint8_t D19cMPAEvent::GetNStripClusters( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint8_t Nstrip = ( (cData->second.at(2) & 0x00001F00) >> 8); + return Nstrip; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + + + + uint8_t D19cMPAEvent::GetNPixelClusters( uint8_t pFeId, uint8_t pMPAId ) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + if (cData != std::end (fEventDataMap) ) + { + // buf overflow and lat error + uint8_t Npix = (cData->second.at(2) & 0x0000001F); + return Npix; + } + else + { + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + return 0; + } + } + + + + uint32_t D19cMPAEvent::DivideBy2RoundUp(uint32_t value) const + { + return (value + value%2)/2; + } + + + + uint32_t D19cMPAEvent::GetCluster(EventDataMap::const_iterator cData,uint8_t nclus,uint8_t cClusterSize,uint8_t deltaword) const + { + uint32_t mask = ((1<<cClusterSize)-1)<<(32-cClusterSize); + + uint32_t startbit = nclus*cClusterSize; + uint32_t endbit = startbit+cClusterSize; + uint8_t nstartword = int(startbit/32); + uint8_t nendword = int(endbit/32); + + uint32_t startword = cData->second.at(nstartword+deltaword); + + uint8_t displaceL = startbit%32; + uint32_t curLmask = mask>>displaceL; + uint32_t curLword = ((startword&curLmask)>>std::max(0,32-(displaceL+cClusterSize+1))); + + uint8_t displaceR = 0; + uint32_t curRword = 0; + if(nstartword!=nendword) + { + uint32_t endword = cData->second.at(nendword+deltaword); + + displaceR = endbit%32; + uint32_t curRmask = mask<<(cClusterSize-displaceR); + curRword = ((endword&curRmask)>> (31-displaceR)); + } + uint32_t word = ((curLword<<abs(std::min(0,31-(displaceL+cClusterSize)))) + curRword)>>1; + return word; + } + + + + + + + + + std::vector<SCluster> D19cMPAEvent::GetStripClusters ( uint8_t pFeId, uint8_t pMPAId) const + { + std::vector<SCluster> result; + + uint8_t cNstrip = GetNStripClusters(pFeId, pMPAId); + if (cNstrip == 0) return result; + + SCluster aSCluster; + + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + uint8_t cSClusterSize = D19C_SCluster_SIZE_32_MPA ; + uint8_t deltaword = 3; + uint8_t nstrips = 0; + while(nstrips < cNstrip) + { + + uint32_t word = GetCluster(cData,nstrips,cSClusterSize,deltaword); + + aSCluster.fAddress = ((0x000007f0 & word)>>4) - 1; + aSCluster.fMip = (0x0000000e & word) >> 1; + aSCluster.fWidth = 0x00000001 & word; + + result.push_back(aSCluster); + nstrips += 1; + } + return result; + } + + + + + + + + std::vector<PCluster> D19cMPAEvent::GetPixelClusters ( uint8_t pFeId, uint8_t pMPAId) const + { + std::vector<PCluster> result; + uint8_t cNpix = GetNPixelClusters(pFeId, pMPAId); + if (cNpix == 0) return result; + PCluster aPCluster; + + uint8_t cNstrip = GetNStripClusters(pFeId, pMPAId); + uint8_t cSClusterSize = D19C_SCluster_SIZE_32_MPA ; + uint32_t nendword = int(cSClusterSize*(cNstrip+1)/32); + + uint8_t cPClusterSize = D19C_PCluster_SIZE_32_MPA ; + + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + uint8_t deltaword = 3+nendword;//+1? + uint8_t npix = 0; + while(npix < cNpix) + { + uint32_t word = GetCluster(cData,npix,cPClusterSize,deltaword); + aPCluster.fAddress = (0x00003f80 & word) >> 7 ; + aPCluster.fWidth = (0x00000070 & word) >> 4 ; + aPCluster.fZpos = 0x0000000F & word ; + + result.push_back(aPCluster); + npix += 1; + } + + return result; + } + + + /*uint32_t D19cMPAEvent::GetSync1( uint8_t pFeId, uint8_t pMPAId) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + return (cData->second.at(31) & 0x02000000) >> 25; + } + + + uint32_t D19cMPAEvent::GetSync2( uint8_t pFeId, uint8_t pMPAId) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + + return (cData->second.at(31) & 0x01000000) >> 24; + }*/ + + + uint32_t D19cMPAEvent::GetBX1_NStubs( uint8_t pFeId, uint8_t pMPAId) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + uint16_t cL1size_32_MPA = (0x00000FFF & cData->second.at (0))*4 ; + + return (0x00000007 & cData->second.at (cL1size_32_MPA+1)); + } + + + uint16_t D19cMPAEvent::GetStubDataDelay( uint8_t pFeId, uint8_t pMPAId) const + { + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + uint16_t cL1size_32_MPA = (0x00000FFF & cData->second.at (0))*4 ; + + return (0x00FFF000 & cData->second.at (cL1size_32_MPA)); + } + + //Very untested + std::vector<Stub> D19cMPAEvent::StubVector (uint8_t pFeId, uint8_t pMPAId) const + { + std::vector<Stub> cStubVec; + //here create stubs and return the vector + uint16_t cKey = encodeId (pFeId, pMPAId); + EventDataMap::const_iterator cData = fEventDataMap.find (cKey); + uint16_t cL1size_32_MPA = (0x00000FFF & cData->second.at (0))*4 ; + //Apparently something needs to be done with this? + uint16_t stubdelay = (cData->second.at (cL1size_32_MPA) & 0x00FFF000) >> 12 ; + if (cData != std::end (fEventDataMap) ) + { + uint8_t pos1 = (cData->second.at (cL1size_32_MPA+1) & 0x00FF0000) >> 16 ; + uint8_t pos2 = (cData->second.at (cL1size_32_MPA+2) & 0x000000FF) >> 0; + uint8_t pos3 = (cData->second.at (cL1size_32_MPA+2) & 0x00FF0000) >> 16 ; + uint8_t pos4 = (cData->second.at (cL1size_32_MPA+3) & 0x000000FF) >> 0; + uint8_t pos5 = (cData->second.at (cL1size_32_MPA+3) & 0x00FF0000) >> 16 ; + + + uint8_t bend1 = (cData->second.at (cL1size_32_MPA+1) & 0xF0000000) >> 28; + uint8_t bend2 = (cData->second.at (cL1size_32_MPA+2) & 0x0000F000) >> 12; + uint8_t bend3 = (cData->second.at (cL1size_32_MPA+2) & 0xF0000000) >> 28; + uint8_t bend4 = (cData->second.at (cL1size_32_MPA+3) & 0x0000F000) >> 12; + uint8_t bend5 = (cData->second.at (cL1size_32_MPA+3) & 0xF0000000) >> 28; + + + uint8_t row1 = (cData->second.at (cL1size_32_MPA+1) & 0x0F000000) >> 24; + uint8_t row2 = (cData->second.at (cL1size_32_MPA+2) & 0x00000F00) >> 8; + uint8_t row3 = (cData->second.at (cL1size_32_MPA+2) & 0x0F000000) >> 24; + uint8_t row4 = (cData->second.at (cL1size_32_MPA+3) & 0x00000F00) >> 8; + uint8_t row5 = (cData->second.at (cL1size_32_MPA+3) & 0x0F000000) >> 24; + + + + + if (pos1 != 0 ) cStubVec.emplace_back (pos1, bend1, row1) ; + if (pos2 != 0 ) cStubVec.emplace_back (pos2, bend2, row2) ; + if (pos3 != 0 ) cStubVec.emplace_back (pos3, bend3, row3) ; + if (pos4 != 0 ) cStubVec.emplace_back (pos4, bend4, row4) ; + if (pos5 != 0 ) cStubVec.emplace_back (pos5, bend5, row5) ; + + } + else + LOG (INFO) << "Event: FE " << +pFeId << " MPA " << +pMPAId << " is not found." ; + + return cStubVec; + } + + + void D19cMPAEvent::print ( std::ostream& os) const + { + os << "MPA Event #" << std::endl; + for (auto const& cKey : this->fEventDataMap) + { + uint8_t cFeId; + uint8_t cMpaId; + this->decodeId (cKey.first, cFeId, cMpaId); + os << "Hybrid " << +cFeId << ", Chip " << +cMpaId << std::endl; + os << "\t L1 Counter: " << GetMPAL1Counter(cFeId, cMpaId) << std::endl; + os << "\t Error: " << Error(cFeId, cMpaId) << std::endl; + os << "\t N Pixel Clusters: " << GetNPixelClusters(cFeId, cMpaId) << std::endl; + for(auto pcluster: GetPixelClusters(cFeId, cMpaId)) os << "\t\t Cluster Address: " << +pcluster.fAddress << ", Width: " << +pcluster.fWidth << ", ZPos: " << +pcluster.fZpos << std::endl; + os << "\t N Strip Clusters: " << GetNStripClusters(cFeId, cMpaId) << std::endl; + for(auto scluster: GetStripClusters(cFeId, cMpaId)) os << "\t\t Cluster Address: " << +scluster.fAddress << ", Width: " << +scluster.fWidth << ", MIP: " << +scluster.fMip << std::endl; + os << std::endl; + } + } + + + uint32_t D19cMPAEvent::GetNHits (uint8_t pFeId, uint8_t pMPAId) const + { + return GetNPixelClusters(pFeId, pMPAId) + GetNStripClusters(pFeId, pMPAId); + } + + + + + std::string D19cMPAEvent::StubBitString ( uint8_t pFeId, uint8_t pCbcId ) const + { + std::ostringstream os; + + std::vector<Stub> cStubVector = this->StubVector (pFeId, pCbcId); + + for (auto cStub : cStubVector) + os << std::bitset<8> (cStub.getPosition() ) << " " << std::bitset<4> (cStub.getBend() ) << " "; + + return os.str(); + } + + + + //These are unimplemented + + uint32_t D19cMPAEvent::PipelineAddress( uint8_t pFeId, uint8_t pMPAId ) const + { + return 0; + } + + std::string D19cMPAEvent::HexString() const + { + return ""; + } + + bool D19cMPAEvent::DataBit ( uint8_t pFeId, uint8_t pMPAId, uint32_t i ) const + { + return false; + } + + std::vector<uint32_t> D19cMPAEvent::GetHits (uint8_t pFeId, uint8_t pMPAId) const + { + std::vector<uint32_t> none; + return none; + } + + std::string D19cMPAEvent::DataHexString ( uint8_t pFeId, uint8_t pMPAId ) const + { + return ""; + } + + bool D19cMPAEvent::StubBit ( uint8_t pFeId, uint8_t pMPAId ) const + { + return false; + } + + + SLinkEvent D19cMPAEvent::GetSLinkEvent ( BeBoard* pBoard) const + { + SLinkEvent none; + return none; + } + + + + + std::string D19cMPAEvent::GlibFlagString ( uint8_t pFeId, uint8_t pCbcId ) const + { + return ""; + } + + std::string D19cMPAEvent::DataBitString ( uint8_t pFeId, uint8_t pCbcId ) const + { + return ""; + } + + + + std::vector<bool> D19cMPAEvent::DataBitVector ( uint8_t pFeId, uint8_t pCbcId ) const + { + std::vector<bool> none; + return none; + } + + std::vector<Cluster> D19cMPAEvent::getClusters ( uint8_t pFeId, uint8_t pCbcId) const + { + std::vector<Cluster> none; + return none; + } + + std::vector<bool> D19cMPAEvent::DataBitVector ( uint8_t pFeId, uint8_t pCbcId, const std::vector<uint8_t>& channelList ) const + { + std::vector<bool> none; + return none; + } + + + + +} diff --git a/Utils/D19cMPAEvent.h b/Utils/D19cMPAEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..0e3b0001253fd665501f0fb16807107b0b7f4e9c --- /dev/null +++ b/Utils/D19cMPAEvent.h @@ -0,0 +1,238 @@ +/* + + \file Event.h + \brief Event handling from DAQ + \author Nicolas PIERRE + \version 1.0 + \date 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#ifndef __D19cMPAEvent_H__ +#define __D19cMPAEvent_H__ + +#include "Event.h" + + +using namespace Ph2_HwDescription; + +namespace Ph2_HwInterface { + + /*! + * \class MPAEvent + * \brief Event container to manipulate event flux from the MPA2 + */ + class D19cMPAEvent : public Event + { + public: + /*! + * \brief Constructor of the Event Class + * \param pBoard : Board to work with + * \param pNbMPA + * \param pEventBuf : the pointer to the raw Event buffer of this Event + */ + D19cMPAEvent ( const BeBoard* pBoard, uint32_t pNbMPA, const std::vector<uint32_t>& list ); + /*! + * \brief Copy Constructor of the Event Class + */ + //MPAEvent ( const Event& pEvent ); + /*! + * \brief Destructor of the Event Class + */ + ~D19cMPAEvent() + { + } + /*! + * \brief Set an Event to the Event map + * \param pEvent : Event to set + * \return Aknowledgement of the Event setting (1/0) + */ + void SetEvent ( const BeBoard* pBoard, uint32_t pNbMPA, const std::vector<uint32_t>& list ) override; + + /*! + * \brief Get the MPA Event counter + * \return MPA Event counter + */ + uint32_t GetEventCountCBC() const override + { + return fEventCount; + } + + //private members of MPA events only + uint32_t GetBeId() const + { + return fBeId; + } + uint8_t GetFWType() const + { + return fBeFWType; + } + uint32_t GetCBCDataType() const + { + return fCBCDataType; + } + uint32_t GetNC() const + { + return fNCbc; + } + uint32_t GetEventDataSize() const + { + return fEventDataSize; + } + uint32_t GetBeStatus() const + { + return fBeStatus; + } + /*! + * \brief Convert Data to Hex string + * \return Data string in hex + */ + std::string HexString() const override; + /*! + * \brief Function to get bit string in hexadecimal format for MPA data + * \param pFeId : FE Id + * \param pMPAId : MPA Id + * \return Data Bit string in Hex + */ + std::string DataHexString ( uint8_t pFeId, uint8_t pMPAId ) const override; + + /*! + * \brief Function to get Error bit + * \param pFeId : FE Id + * \param pMPAId : Cbc Id + * \param i : Error bit number i + * \return Error bit + */ + bool Error ( uint8_t pFeId, uint8_t pMPAId, uint32_t i ) const override; + /*! + * \brief Function to get all Error bits + * \param pFeId : FE Id + * \param pMPAId : MPA Id + * \return Error bit + */ + uint32_t Error ( uint8_t pFeId, uint8_t pMPAId ) const override; + + /*! + * \brief Function to count the Hits in this event + * \param pFeId : FE Id + * \param pMPAId : MPA Id + * \return number of hits + */ + uint32_t GetNHits (uint8_t pFeId, uint8_t pMPAId) const override; + /*! + * \brief Function to get a sparsified hit vector + * \param pFeId : FE Id + * \param pMPAId : MPA Id + * \return vector with hit channels + */ + std::vector<uint32_t> GetHits (uint8_t pFeId, uint8_t pMPAId) const override; + /*! + * \brief Function to get pipeline address + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Pipeline address + */ + uint32_t PipelineAddress ( uint8_t pFeId, uint8_t pCbcId ) const override; + /*! + * \brief Function to get a CBC pixel bit data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \param i : pixel bit data number i + * \return Data Bit + */ + bool DataBit ( uint8_t pFeId, uint8_t pCbcId, uint32_t i ) const override; + /*! + * \brief Function to get bit string of CBC data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Data Bit string + */ + std::string DataBitString ( uint8_t pFeId, uint8_t pCbcId ) const override; + /*! + * \brief Function to get bit vector of CBC data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Data Bit vector + */ + std::vector<bool> DataBitVector ( uint8_t pFeId, uint8_t pCbcId ) const override; + std::vector<bool> DataBitVector ( uint8_t pFeId, uint8_t pCbcId, const std::vector<uint8_t>& channelList ) const override; + /*! + * \brief Function to get GLIB flag string + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Glib flag string + */ + std::vector<Cluster> getClusters ( uint8_t pFeId, uint8_t pCbcId) const override; + + std::string GlibFlagString ( uint8_t pFeId, uint8_t pCbcId ) const override; + /*! + * \brief Function to get Stub bit + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return stub bit? + */ + std::string StubBitString ( uint8_t pFeId, uint8_t pCbcId ) const override; + /*! + * \brief Function to get Stub bit + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return stub bit? + */ + bool StubBit ( uint8_t pFeId, uint8_t pCbcId ) const override; + /*! + * \brief Get a vector of Stubs - will be empty for Cbc2 + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + */ + std::vector<Stub> StubVector (uint8_t pFeId, uint8_t pCbcId ) const override; + + uint16_t GetMPAL1Counter( uint8_t pFeId, uint8_t pMPAId ) const; + + uint8_t GetNStripClusters( uint8_t pFeId, uint8_t pMPAId ) const; + + std::vector<SCluster> GetStripClusters ( uint8_t pFeId, uint8_t pMPAId) const; + + uint8_t GetNPixelClusters( uint8_t pFeId, uint8_t pMPAId ) const; + + std::vector<PCluster> GetPixelClusters ( uint8_t pFeId, uint8_t pMPAId) const; + + uint8_t GetMPAChipType ( uint8_t pFeId, uint8_t pMPAId ) const; + + uint8_t GetMPAChipID ( uint8_t pFeId, uint8_t pMPAId ) const; + + uint16_t GetMPAHybridID ( uint8_t pFeId, uint8_t pMPAId ) const; + + uint8_t GetMPAError ( uint8_t pFeId, uint8_t pMPAId ) const; + + //uint32_t GetSync1( uint8_t pFeId, uint8_t pMPAId) const; + + //uint32_t GetSync2( uint8_t pFeId, uint8_t pMPAId) const; + + uint32_t GetBX1_NStubs( uint8_t pFeId, uint8_t pMPAId) const; + + uint16_t GetStubDataDelay( uint8_t pFeId, uint8_t pMPAId) const; + + uint32_t DivideBy2RoundUp(uint32_t value) const; + + uint32_t GetCluster(EventDataMap::const_iterator cData,uint8_t nclus,uint8_t cClusterSize,uint8_t deltaword) const; + + void print (std::ostream& out) const override; + + private: + uint32_t reverse_bits ( uint32_t n) const + { + n = ( (n >> 1) & 0x55555555) | ( (n << 1) & 0xaaaaaaaa) ; + n = ( (n >> 2) & 0x33333333) | ( (n << 2) & 0xcccccccc) ; + n = ( (n >> 4) & 0x0f0f0f0f) | ( (n << 4) & 0xf0f0f0f0) ; + n = ( (n >> 8) & 0x00ff00ff) | ( (n << 8) & 0xff00ff00) ; + n = ( (n >> 16) & 0x0000ffff) | ( (n << 16) & 0xffff0000) ; + return n; + } + + void printMPAHeader (std::ostream& os, uint8_t pFeId, uint8_t pMPAId) const; + + SLinkEvent GetSLinkEvent ( BeBoard* pBoard) const override; + }; +} +#endif diff --git a/Utils/Data.cc b/Utils/Data.cc index e6c2462d506203bfd33976a04e4600fc2134418a..ce964f64249ba719b9e3ccd670c7ef5357f7019a 100644 --- a/Utils/Data.cc +++ b/Utils/Data.cc @@ -44,14 +44,26 @@ namespace Ph2_HwInterface { // be aware that eventsize is not constant for the zs event, so we are not using it fEventSize = static_cast<uint32_t> ( (pData.size() ) / fNevents ); + uint32_t indextoread=0; + uint16_t nHybrid=0; + uint16_t cHybrid=-1; + EventType fEventType = pBoard->getEventType(); if (pType == BoardType::D19C) { uint32_t fNFe = pBoard->getNFe(); - if (fEventType == EventType::ZS) fNCbc = 0; - else fNCbc = (fEventSize - D19C_EVENT_HEADER1_SIZE_32_CBC3) / D19C_EVENT_SIZE_32_CBC3 / fNFe; + if (fEventType == EventType::ZS) + { + fNCbc = 0; + fNMPA = 0; + } + else { + fNCbc = (fEventSize - D19C_EVENT_HEADER1_SIZE_32_CBC3) / D19C_EVENT_SIZE_32_CBC3 / fNFe; + //fNMPA = (fEventSize - D19C_EVENT_HEADER1_SIZE_32) / D19C_EVENT_HEADER1_SIZE_32 / fNFe; + fNMPA = 1; + } } else if (pType == BoardType::CBC3FC7) fNCbc = (fEventSize - (EVENT_HEADER_SIZE_32_CBC3) ) / (CBC_EVENT_SIZE_32_CBC3); else fNCbc = ( fEventSize - ( EVENT_HEADER_TDC_SIZE_32 ) ) / ( CBC_EVENT_SIZE_32 ); @@ -62,13 +74,38 @@ namespace Ph2_HwInterface { //use a SwapIndex to decide wether to swap a word or not //use a WordIndex to pick events apart uint32_t cWordIndex = 0; + uint32_t cWordWriteIndex = 0; uint32_t cSwapIndex = 0; // index of the word inside the event (ZS) uint32_t fZSEventSize = 0; uint32_t cZSWordIndex = 0; - + uint16_t cH1size_32_MPA = 4 ; + uint16_t cDummysize = 0; + uint16_t cBlksize = 0; for ( auto word : pData ) { + //std::cout<<std::bitset<32>(word)<<std::endl; + if(lvec.size()==0 and pBoard->getChipType() == ChipType::MPA) + { + uint16_t cLeading = ((0xFFFF0000 & pData.at (cWordIndex)) >> 16 ); + if (cLeading!=0xFFFF)break; + cBlksize = 4*(0x0000FFFF & pData.at (cWordIndex)); + cDummysize = 4*(0x000000FF & pData.at (cWordIndex+1)); + fEventSize = cBlksize; + if((cWordIndex+fEventSize)>pData.size())break; + uint16_t fNMPA=0; + uint16_t curEventSize = cH1size_32_MPA; + while((cWordIndex+curEventSize)<pData.size() and curEventSize<(fEventSize-cDummysize)) + { + uint16_t cPLeading = ((0xF0000000 & pData.at (cWordIndex+curEventSize)) >> 28 ); + curEventSize+=((0x00000FFF & pData.at (cWordIndex+curEventSize)))*4 ; + uint16_t cSLeading = ((0xF0000000 & pData.at (cWordIndex+curEventSize)) >> 28 ); + curEventSize+=((0x00000FFF & pData.at (cWordIndex+curEventSize)))*4 ; + fNMPA+=1 ; + } + } + + //if the SwapIndex is greater than 0 and a multiple of the event size in 32 bit words, reset SwapIndex to 0 if (cSwapIndex > 0 && cSwapIndex % fEventSize == 0) cSwapIndex = 0; @@ -124,10 +161,25 @@ namespace Ph2_HwInterface { } else { - if ( cWordIndex > 0 && (cWordIndex + 1) % fEventSize == 0 ) + if(pBoard->getChipType() == ChipType::MPA ) + { + if (pType == BoardType::D19C and lvec.size()==fEventSize) + { + //for ( auto& lv : lvec ) + //std::cout<<" -"<<std::bitset<32>(lv)<<std::endl; + //std::cout<<std::endl; + std::vector<uint32_t> lvectrunc(&lvec[0], &lvec[fEventSize-cDummysize]); + fEventList.push_back ( new D19cMPAEvent ( pBoard, fNMPA, lvectrunc ) ); + lvec.clear(); + if (fEventList.size() >= fNevents) break; + cWordWriteIndex = cWordIndex; + } + } + else if ( cWordIndex > 0 && (cWordIndex + 1) % fEventSize == 0 ) { - if (pType == BoardType::D19C) - fEventList.push_back ( new D19cCbc3Event ( pBoard, fNCbc, lvec ) ); + if (pType == BoardType::D19C) { + if (pBoard->getChipType() == ChipType::CBC3) fEventList.push_back ( new D19cCbc3Event ( pBoard, fNCbc, lvec ) ); + } else if (pType == BoardType::CBC3FC7) fEventList.push_back ( new Cbc3Event ( pBoard, fNCbc, lvec ) ); else diff --git a/Utils/Data.h b/Utils/Data.h index d9091307c49adc4dc0af8b4aef1e05c63658d8a4..ff944472f3a62439052a4fba2704c1d6fbe1796a 100644 --- a/Utils/Data.h +++ b/Utils/Data.h @@ -20,8 +20,10 @@ #include "../Utils/Event.h" #include "../Utils/Cbc2Event.h" #include "../Utils/Cbc3Event.h" +#include "../Utils/SSAEvent.h" #include "../Utils/D19cCbc3Event.h" #include "../Utils/D19cCbc3EventZS.h" +#include "../Utils/D19cMPAEvent.h" #include "../Utils/easylogging++.h" #include "../HWDescription/BeBoard.h" #include "../HWDescription/Definition.h" @@ -40,6 +42,7 @@ namespace Ph2_HwInterface { uint32_t fNevents; /*! Number of Events<*/ uint32_t fCurrentEvent; /*! Current EventNumber in use <*/ uint32_t fNCbc; /*! Number of CBCs in the setup <*/ + uint32_t fNMPA; /*! Number of MPAs in the setup <*/ uint32_t fEventSize; /*! Size of 1 Event <*/ //to look up if an index is first or last word valid for up to 8 CBCs per AMC diff --git a/Utils/Event.h b/Utils/Event.h index 78a6c2fe9e85a766cdae9e7422cc31236e5d50c7..078ae6faa3f18deef03ed3b23a6bf4f0258268de 100644 --- a/Utils/Event.h +++ b/Utils/Event.h @@ -43,10 +43,29 @@ namespace Ph2_HwInterface { double getBaricentre(); }; + class PCluster + { + public: + + uint8_t fAddress; + uint8_t fWidth; + uint8_t fZpos; + double getBaricentre(); + }; + + class SCluster + { + public: + uint8_t fAddress; + uint8_t fMip; + uint8_t fWidth; + double getBaricentre(); + }; + class Stub { public: - Stub (uint8_t pPosition, uint8_t pBend) : fPosition (pPosition), fBend (pBend) + Stub (uint8_t pPosition, uint8_t pBend, uint8_t pRow=0) : fPosition (pPosition), fBend (pBend), fRow (pRow) { //with Strips starting at 0 fCenter = static_cast<float> ( (pPosition / 2.) - 1); @@ -59,6 +78,10 @@ namespace Ph2_HwInterface { { return fBend; } + uint8_t getRow() + { + return fRow; + } float getCenter() { return fCenter; @@ -66,6 +89,7 @@ namespace Ph2_HwInterface { private: uint8_t fPosition; uint8_t fBend; + uint8_t fRow; float fCenter; }; @@ -202,6 +226,14 @@ namespace Ph2_HwInterface { { return fTDC; } + /*! + * \brief Get tlu trigger id value + * \return tlu value + */ + uint32_t GetTLUTriggerID() const + { + return fTLUTriggerID; + } /*! * \brief Get an event contained in a Cbc * \param pFeId : FE Id diff --git a/Utils/FileHeader.h b/Utils/FileHeader.h index e8cb70f8dfc47650d4bba3199dd3c4bbf7fa8298..e561a12b6d0cc82b368b7c9c0234f0230864d76c 100644 --- a/Utils/FileHeader.h +++ b/Utils/FileHeader.h @@ -71,8 +71,8 @@ class FileHeader { if (fType == "GLIB") return BoardType::GLIB; - else if (fType == "MPAGLIB") - return BoardType::MPAGLIB; + else if (fType == "MPAlightGLIB") + return BoardType::MPAlightGLIB; else if (fType == "CTA") return BoardType::CTA; else if (fType == "ICGLIB") diff --git a/Utils/MPAEvent.cc b/Utils/MPAEvent.cc index 4dc8f188c243e1ae2e2990511da280d9801b6b95..c56f89f9d38e550599a188f79fd9017f8c303a9a 100644 --- a/Utils/MPAEvent.cc +++ b/Utils/MPAEvent.cc @@ -39,50 +39,6 @@ namespace Ph2_HwInterface { void MPAEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) { - fEventSize = pNbCbc * CBC_EVENT_SIZE_32 + EVENT_HEADER_TDC_SIZE_32; - - - - - ftotal_trigs = 0x00FFFFFF & list.at (0); - ftrigger_total_counter = 0x00FFFFFF & list.at (1); - ftrigger_counter = 0x00FFFFFF & list.at (2); - - - ftrigger_offset_BEAM.clear(); - - ftrigger_offset_MPA.clear(); - - - ftrigger_offset_BEAM.insert( ftrigger_offset_BEAM.begin(), list.begin()+3, list.begin()+(3+2048) ); - ftrigger_offset_MPA.insert( ftrigger_offset_MPA.begin(), list.begin()+(3+2048), list.begin()+(3+2048*2) ); - - - //now decode FEEvents - uint32_t cNFe = static_cast<uint32_t> ( pBoard->getNFe() ); - for ( uint8_t cFeId = 0; cFeId < cNFe; cFeId++ ) - { - uint32_t cNMPA; - cNMPA = static_cast<uint32_t> ( pBoard->getModule ( cFeId )->getNMPA() ); - - for ( uint8_t cMPAId = 0; cMPAId < cNMPA; cMPAId++ ) - { - uint16_t cKey = encodeId (cFeId, cMPAId); - - uint32_t begin = MPA_HEADER_SIZE_32 + cFeId * MPA_EVENT_SIZE_32 * cNMPA + cMPAId * MPA_EVENT_SIZE_32; - uint32_t end = begin + MPA_EVENT_SIZE_32; - - std::vector<uint32_t> cMPAData (std::next (std::begin (list), begin), std::next (std::begin (list), end) ); - - - - fEventDataMap[cKey] = cMPAData; - } - - - } - } - } diff --git a/Utils/MPAEvent.h b/Utils/MPAEvent.h index 0d5f7fb0760ab76a328192cb1b1cbe2d1b00e19f..d24535253f5632f700365fd7e22afe0d949707af 100644 --- a/Utils/MPAEvent.h +++ b/Utils/MPAEvent.h @@ -53,15 +53,6 @@ namespace Ph2_HwInterface { private: - uint32_t ftotal_trigs; - uint32_t ftrigger_total_counter; - uint32_t ftrigger_counter; - - std::vector<uint32_t> ftrigger_offset_BEAM; - std::vector<uint32_t> ftrigger_offset_MPA; - - - }; } #endif diff --git a/Utils/MPAlightEvent.cc b/Utils/MPAlightEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..4ccd1079878da5e1f72a4f9ba30731736e7c3823 --- /dev/null +++ b/Utils/MPAlightEvent.cc @@ -0,0 +1,88 @@ +/* + + FileName : Event.cc + Content : Event handling from DAQ + Programmer : Nicolas PIERRE + Version : 1.0 + Date of creation : 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#include "../Utils/MPAlightEvent.h" + +using namespace Ph2_HwDescription; + + +namespace Ph2_HwInterface { + + // Event implementation + MPAlightEvent::MPAlightEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) + { + SetEvent ( pBoard, pNbCbc, list ); + } + + + //MPAlightEvent::MPAlightEvent ( const Event& pEvent ) : + //fBunch ( pEvent.fBunch ), + //fOrbit ( pEvent.fOrbit ), + //fLumi ( pEvent.fLumi ), + //fEventCount ( pEvent.fEventCount ), + //fEventCountCBC ( pEvent.fEventCountCBC ), + //fTDC ( pEvent.fTDC ), + //fEventSize (pEvent.fEventSize), + //fEventDataMap ( pEvent.fEventDataMap ) + //{ + + //} + + + void MPAlightEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) + { + fEventSize = pNbCbc * CBC_EVENT_SIZE_32 + EVENT_HEADER_TDC_SIZE_32; + + + + + ftotal_trigs = 0x00FFFFFF & list.at (0); + ftrigger_total_counter = 0x00FFFFFF & list.at (1); + ftrigger_counter = 0x00FFFFFF & list.at (2); + + + ftrigger_offset_BEAM.clear(); + + ftrigger_offset_MPAlight.clear(); + + + ftrigger_offset_BEAM.insert( ftrigger_offset_BEAM.begin(), list.begin()+3, list.begin()+(3+2048) ); + ftrigger_offset_MPAlight.insert( ftrigger_offset_MPAlight.begin(), list.begin()+(3+2048), list.begin()+(3+2048*2) ); + + + //now decode FEEvents + uint32_t cNFe = static_cast<uint32_t> ( pBoard->getNFe() ); + for ( uint8_t cFeId = 0; cFeId < cNFe; cFeId++ ) + { + uint32_t cNMPAlight; + cNMPAlight = static_cast<uint32_t> ( pBoard->getModule ( cFeId )->getNMPAlight() ); + + for ( uint8_t cMPAlightId = 0; cMPAlightId < cNMPAlight; cMPAlightId++ ) + { + uint16_t cKey = encodeId (cFeId, cMPAlightId); + + uint32_t begin = MPAlight_HEADER_SIZE_32 + cFeId * MPAlight_EVENT_SIZE_32 * cNMPAlight + cMPAlightId * MPAlight_EVENT_SIZE_32; + uint32_t end = begin + MPAlight_EVENT_SIZE_32; + + std::vector<uint32_t> cMPAlightData (std::next (std::begin (list), begin), std::next (std::begin (list), end) ); + + + + fEventDataMap[cKey] = cMPAlightData; + } + + + } + + } + + +} diff --git a/Utils/MPAlightEvent.h b/Utils/MPAlightEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..b77a47da1da2a11297f979e76fc02a924ac793ce --- /dev/null +++ b/Utils/MPAlightEvent.h @@ -0,0 +1,67 @@ +/* + + \file Event.h + \brief Event handling from DAQ + \author Nicolas PIERRE + \version 1.0 + \date 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#ifndef __MPAlightEVENT_H__ +#define __MPAlightEVENT_H__ + +#include "Event.h" + + +using namespace Ph2_HwDescription; + +namespace Ph2_HwInterface { + + /*! + * \class MPAlightEvent + * \brief Event container to manipulate event flux from the MPAlight + */ + class MPAlightEvent : public Event + { + public: + /*! + * \brief Constructor of the Event Class + * \param pBoard : Board to work with + * \param pNbCbc + * \param pEventBuf : the pointer to the raw Event buffer of this Event + */ + MPAlightEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ); + /*! + * \brief Copy Constructor of the Event Class + */ + //MPAlightEvent ( const Event& pEvent ); + /*! + * \brief Destructor of the Event Class + */ + ~MPAlightEvent() + { + } + /*! + * \brief Set an Event to the Event map + * \param pEvent : Event to set + * \return Aknowledgement of the Event setting (1/0) + */ + void SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) override; + + private: + + + uint32_t ftotal_trigs; + uint32_t ftrigger_total_counter; + uint32_t ftrigger_counter; + + std::vector<uint32_t> ftrigger_offset_BEAM; + std::vector<uint32_t> ftrigger_offset_MPAlight; + + + + }; +} +#endif diff --git a/Utils/SSAEvent.cc b/Utils/SSAEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..c63960435d164c4ad90f2a7c04e695b3fd8d4bc4 --- /dev/null +++ b/Utils/SSAEvent.cc @@ -0,0 +1,99 @@ +/* + + FileName : Event.cc + Content : Event handling from DAQ + Programmer : Nicolas PIERRE + Version : 1.0 + Date of creation : 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#include "../Utils/SSAEvent.h" + +using namespace Ph2_HwDescription; + + +namespace Ph2_HwInterface { + + // Event implementation + SSAEvent::SSAEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) + { + SetEvent ( pBoard, pNbCbc, list ); + } + + + //SSAEvent::SSAEvent ( const Event& pEvent ) : + //fBunch ( pEvent.fBunch ), + //fOrbit ( pEvent.fOrbit ), + //fLumi ( pEvent.fLumi ), + //fEventCount ( pEvent.fEventCount ), + //fEventCountCBC ( pEvent.fEventCountCBC ), + //fTDC ( pEvent.fTDC ), + //fEventSize (pEvent.fEventSize), + //fEventDataMap ( pEvent.fEventDataMap ) + //{ + + //} + + + void SSAEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) + { + fEventSize = pNbCbc * CBC_EVENT_SIZE_32 + EVENT_HEADER_TDC_SIZE_32; + + + //now decode FEEvents + uint32_t cNFe = static_cast<uint32_t> ( pBoard->getNFe() ); + for ( uint8_t cFeId = 0; cFeId < cNFe; cFeId++ ) + { + uint32_t cNSSA; + cNSSA = static_cast<uint32_t> ( pBoard->getModule ( cFeId )->getNSSA() ); + + for ( uint8_t cSSAId = 0; cSSAId < cNSSA; cSSAId++ ) + { + uint16_t cKey = encodeId (cFeId, cSSAId); + + uint32_t begin = SSA_HEADER_SIZE_32 + cFeId * SSA_EVENT_SIZE_32 * cNSSA + cSSAId * SSA_EVENT_SIZE_32; + uint32_t end = begin + SSA_EVENT_SIZE_32; + + std::vector<uint32_t> cSSAData (std::next (std::begin (list), begin), std::next (std::begin (list), end) ); + + + + fEventDataMap[cKey] = cSSAData; + } + + + } + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/Utils/SSAEvent.h b/Utils/SSAEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..07b4eef0ecb6bcabe051da6b332877c550689893 --- /dev/null +++ b/Utils/SSAEvent.h @@ -0,0 +1,167 @@ +/* + + \file Event.h + \brief Event handling from DAQ + \author Nicolas PIERRE + \version 1.0 + \date 10/07/14 + Support : mail to : nicolas.pierre@icloud.com + + */ + +#ifndef __SSAEVENT_H__ +#define __SSAEVENT_H__ + +#include "Event.h" + + +using namespace Ph2_HwDescription; + +namespace Ph2_HwInterface { + + /*! + * \class SSAEvent + * \brief Event container to manipulate event flux from the SSA + */ + class SSAEvent : public Event + { + public: + /*! + * \brief Constructor of the Event Class + * \param pBoard : Board to work with + * \param pNbCbc + * \param pEventBuf : the pointer to the raw Event buffer of this Event + */ + SSAEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ); + /*! + * \brief Copy Constructor of the Event Class + */ + //SSAEvent ( const Event& pEvent ); + /*! + * \brief Destructor of the Event Class + */ + ~SSAEvent() + { + } + /*! + * \brief Set an Event to the Event map + * \param pEvent : Event to set + * \return Aknowledgement of the Event setting (1/0) + */ + void SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list ) override; + + uint32_t GetEventCountCBC() const override{}; + + /*! + * \brief Convert Data to Hex string + * \return Data string in hex + */ + std::string HexString() const override{}; + /*! + * \brief Function to get bit string in hexadecimal format for CBC data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Data Bit string in Hex + */ + std::string DataHexString ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + + /*! + * \brief Function to get Error bit + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \param i : Error bit number i + * \return Error bit + */ + bool Error ( uint8_t pFeId, uint8_t pCbcId, uint32_t i ) const override{}; + /*! + * \brief Function to get all Error bits + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Error bit + */ + uint32_t Error ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Function to get pipeline address + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Pipeline address + */ + uint32_t PipelineAddress ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Function to get a CBC pixel bit data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \param i : pixel bit data number i + * \return Data Bit + */ + bool DataBit ( uint8_t pFeId, uint8_t pCbcId, uint32_t i ) const override{}; + /*! + * \brief Function to get bit string of CBC data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Data Bit string + */ + std::string DataBitString ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Function to get bit vector of CBC data + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Data Bit vector + */ + std::vector<bool> DataBitVector ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + std::vector<bool> DataBitVector ( uint8_t pFeId, uint8_t pCbcId, const std::vector<uint8_t>& channelList ) const override{}; + /*! + * \brief Function to get GLIB flag string + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return Glib flag string + */ + std::string GlibFlagString ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Function to get Stub bit + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return stub bit? + */ + std::string StubBitString ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Function to get Stub bit + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return stub bit? + */ + bool StubBit ( uint8_t pFeId, uint8_t pCbcId ) const override{}; + /*! + * \brief Get a vector of Stubs - will be empty for Cbc2 + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + */ + std::vector<Stub> StubVector (uint8_t pFeId, uint8_t pCbcId ) const override{}; + + /*! + * \brief Function to count the Hits in this event + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return number of hits + */ + uint32_t GetNHits (uint8_t pFeId, uint8_t pCbcId) const override{}; + /*! + * \brief Function to get a sparsified hit vector + * \param pFeId : FE Id + * \param pCbcId : Cbc Id + * \return vector with hit channels + */ + std::vector<uint32_t> GetHits (uint8_t pFeId, uint8_t pCbcId) const override{}; + + std::vector<Cluster> getClusters ( uint8_t pFeId, uint8_t pCbcId) const override{}; + + void print (std::ostream& out) const override{}; + + SLinkEvent GetSLinkEvent ( BeBoard* pBoard) const override{}; + + + private: + + }; +} +#endif diff --git a/analysis/analyzeEvents.sh b/analysis/analyzeEvents.sh old mode 100755 new mode 100644 diff --git a/cmake/FindCACTUS.cmake b/cmake/FindCACTUS.cmake index 2f363c63f107abc8b53ba1d74c462828cad8d0cd..744f0dd559e2a4782d3a5c2fb32268d39ed44ad4 100644 --- a/cmake/FindCACTUS.cmake +++ b/cmake/FindCACTUS.cmake @@ -14,7 +14,7 @@ if(uhal_include) set(CACTUS_ROOT /opt/cactus/) set(CACTUS_FOUND TRUE) #MESSAGE(STATUS "Found uHAL in ${CACTUS_ROOT}") - file(GLOB_RECURSE amc13_include ${CACTUS_ROOT}/*AMC13.hh) + file(GLOB_RECURSE amc13_include ${CACTUS_ROOT}/include/amc13/*AMC13.hh) if(amc13_include) set(CACTUS_AMC13_FOUND TRUE) #message(STATUS "Found AMC13 compoenent in ${CACTUS_ROOT}") diff --git a/comp.sh b/comp.sh new file mode 100644 index 0000000000000000000000000000000000000000..fdc53fd7b62d089f89750280a6c2620ba1848749 --- /dev/null +++ b/comp.sh @@ -0,0 +1,8 @@ +rm -rf build/* +cd build +cmake ../ +cd .. +make -C build/ -j 4 + + + diff --git a/doxyfile b/doxyfile old mode 100755 new mode 100644 diff --git a/firmware/2CBC_beamtest_DIO5_stub_fixed.mcs b/firmware/2CBC_beamtest_DIO5_stub_fixed.mcs old mode 100755 new mode 100644 diff --git a/quickcomp.sh b/quickcomp.sh new file mode 100644 index 0000000000000000000000000000000000000000..725962909f19914114680f1d47bfff96a6a32430 --- /dev/null +++ b/quickcomp.sh @@ -0,0 +1,18 @@ +#rm -rf build/Utils +#rm -rf build/System +rm -rf build/HWInterface +rm -rf build/src +cd build +cmake ../ +cd .. +make -C build/ -j 4 + +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 +MPA_async_test -f settings/D19CDescriptionMPARU_calib.xml --ncalib=0 +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 --reset=False +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 --reset=False +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 --reset=False +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 --reset=False +#MPA_async_test -f settings/D19CDescriptionMPARU.xml --ncalib=0 --reset=False +#MPA_async_test -f settings/D19CDescriptionMPARU.xml diff --git a/runDQM.sh b/runDQM.sh old mode 100755 new mode 100644 diff --git a/run_irradtest.sh b/run_irradtest.sh old mode 100755 new mode 100644 diff --git a/settings/CBC3DescriptionIC.xml b/settings/CBC3DescriptionIC.xml old mode 100755 new mode 100644 diff --git a/settings/CTADescription_2CBC.xml b/settings/CTADescription_2CBC.xml old mode 100755 new mode 100644 diff --git a/settings/CbcFiles/CBC3_default.txt b/settings/CbcFiles/CBC3_default.txt old mode 100755 new mode 100644 diff --git a/settings/CbcFiles/Cbc_default_electron.txt b/settings/CbcFiles/Cbc_default_electron.txt old mode 100755 new mode 100644 diff --git a/settings/CbcFiles/Cbc_default_hole.txt b/settings/CbcFiles/Cbc_default_hole.txt old mode 100755 new mode 100644 diff --git a/settings/CbcFiles/Cbc_default_irrad.txt b/settings/CbcFiles/Cbc_default_irrad.txt old mode 100755 new mode 100644 diff --git a/settings/D19CDescription.xml b/settings/D19CDescription.xml index 6b47b968ee90489bb62883037660986f1c7e3263..6d2d9f6f7f68cbede28b6d5c41d33de918afcd25 100755 --- a/settings/D19CDescription.xml +++ b/settings/D19CDescription.xml @@ -46,7 +46,7 @@ <Register name="fast_command_block"> <Register name="triggers_to_accept"> 0 </Register> <Register name="trigger_source"> 3 </Register> - <Register name="user_trigger_frequency"> 1000 </Register> + <Register name="stubs_mask"> 1 </Register> <!--this is the delay for the stub trigger--> <Register name="stub_trigger_delay_value"> 0 </Register> @@ -150,5 +150,3 @@ </Settings> </HwDescription> - - diff --git a/settings/D19CDescriptionMPA.xml b/settings/D19CDescriptionMPA.xml new file mode 100644 index 0000000000000000000000000000000000000000..ef1e5a658ba079ff5c5352cfd7200f77ca66d693 --- /dev/null +++ b/settings/D19CDescriptionMPA.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="utf-8"?> +<HwDescription> + <BeBoard Id="0" boardType="D19C" eventType="VR"> + + <connection id="board" uri="ipbusudp-2.0://192.168.1.79:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> + + + <!--connection id="board" uri="ipbusudp-2.0://192.168.21.210:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + <!--connection id="board" uri="chtcp-2.0://localhost:10204?target=192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + + <Module FeId="0" FMCId="0" ModuleId="0" Status="1"> + <MPA_Files path="./settings/MPAFiles/" /> + <MPA Id="0" configfile="MPA_default.txt" /> + <!--MPA Id="1" configfile="MPA_default_emulator.txt" /--> + </Module> + + <!--CONFIG--> + <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 --> + <Register name="fc7_daq_cnfg"> + <!-- Clock control --> + <Register name="clock"> + <Register name="ext_clk_en"> 0 </Register> + </Register> + <!-- TTC --> + <Register name="ttc"> + <Register name="ttc_enable"> 0 </Register> + </Register> + <!-- Fast Command Block --> + <Register name="fast_command_block"> + <Register name="triggers_to_accept"> 0 </Register> + <Register name="trigger_source"> 3 </Register> + <Register name="user_trigger_frequency"> 100 </Register> + <Register name="stubs_mask"> 1 </Register> + <!--this is the delay for the stub trigger--> + <Register name="stub_trigger_delay_value"> 0 </Register> + <Register name="stub_trigger_veto_length"> 0 </Register> + <Register name="test_pulse"> + <Register name="delay_after_fast_reset"> 50 </Register> + <Register name="delay_after_test_pulse"> 200 </Register> + <Register name="delay_before_next_pulse"> 400 </Register> + <Register name="en_fast_reset"> 0 </Register> + <Register name="en_test_pulse"> 1 </Register> + <Register name="en_l1a"> 0 </Register> + </Register> + <Register name="ext_trigger_delay_value"> 50 </Register> + <Register name="antenna_trigger_delay_value"> 200 </Register> + <Register name="delay_between_two_consecutive"> 10 </Register> + <Register name="misc"> + <Register name="backpressure_enable"> 1 </Register> + <Register name="stubOR"> 1 </Register> + <Register name="initial_fast_reset_enable"> 0 </Register> + </Register> + </Register> + <!-- I2C manager --> + <Register name="command_processor_block"> + </Register> + <!-- Phy Block --> + <Register name="physical_interface_block"> + <Register name="i2c"> + <Register name="frequency"> 4 </Register> + </Register> + </Register> + <!-- Readout Block --> + <Register name="readout_block"> + <Register name="packet_nbr"> 499 </Register> + <Register name="global"> + <Register name="data_handshake_enable"> 1 </Register> + <Register name="int_trig_enable"> 0 </Register> + <Register name="int_trig_rate"> 0 </Register> + <Register name="trigger_type"> 0 </Register> + <Register name="data_type"> 0 </Register> + <!--this is what is commonly known as stub latency--> + <Register name="common_stubdata_delay"> 27 </Register> + </Register> + </Register> + <!-- DIO5 Block --> + <Register name="dio5_block"> + <Register name="dio5_en"> 0 </Register> + <Register name="ch1"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch2"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch3"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch4"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch5"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + </Register> + <!-- TLU Block --> + <Register name="tlu_block"> + <Register name="tlu_enabled"> 0 </Register> + <Register name="handshake_mode"> 2 </Register> + <Register name="trigger_id_delay"> 1 </Register> + </Register> + </Register> + </BeBoard> + +<Settings> + + <!--[>Calibration<]--> + <Setting name="TargetVcth">0x78</Setting> + <Setting name="TargetOffset">0x50</Setting> + <Setting name="Nevents">50</Setting> + <Setting name="TestPulsePotentiometer">0x00</Setting> + <Setting name="HoleMode">0</Setting> + <Setting name="VerificationLoop">1</Setting> + + <!--Signal Scan Fit--> + <Setting name="InitialVcth">0x78</Setting> + <Setting name="SignalScanStep">2</Setting> + <Setting name="FitSignal">0</Setting> + +</Settings> +</HwDescription> diff --git a/settings/D19CDescriptionMPARU.xml b/settings/D19CDescriptionMPARU.xml new file mode 100644 index 0000000000000000000000000000000000000000..fc52277009fbdddff3ecbe9f52d9f75a95c03414 --- /dev/null +++ b/settings/D19CDescriptionMPARU.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<HwDescription> + <BeBoard Id="0" boardType="D19C" eventType="VR"> + <connection id="board" uri="ipbusudp-2.0://192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> + <!--connection id="board" uri="ipbusudp-2.0://192.168.21.210:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + <!--connection id="board" uri="chtcp-2.0://localhost:10204?target=192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + + <Module FeId="0" FMCId="0" ModuleId="0" Status="1"> + <MPA_Files path="./settings/MPAFiles/" /> + <MPA Id="0" configfile="MPA_default.txt" /> + <!--MPA Id="1" configfile="MPA_default_emulator.txt" /--> + </Module> + + <!--CONFIG--> + <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 --> + <Register name="fc7_daq_cnfg"> + <!-- Clock control --> + <Register name="clock"> + <Register name="ext_clk_en"> 0 </Register> + </Register> + <!-- TTC --> + <Register name="ttc"> + <Register name="ttc_enable"> 0 </Register> + </Register> + <!-- Fast Command Block --> + <Register name="fast_command_block"> + <Register name="triggers_to_accept"> 0 </Register> + <Register name="trigger_source"> 5 </Register> + <Register name="user_trigger_frequency"> 100 </Register> + <Register name="stubs_mask"> 1 </Register> + <!--this is the delay for the stub trigger--> + <Register name="stub_trigger_delay_value"> 0 </Register> + <Register name="stub_trigger_veto_length"> 0 </Register> + <Register name="test_pulse"> + <Register name="delay_after_fast_reset"> 50 </Register> + <Register name="delay_after_test_pulse"> 200 </Register> + <Register name="delay_before_next_pulse"> 400 </Register> + <Register name="en_fast_reset"> 0 </Register> + <Register name="en_test_pulse"> 1 </Register> + <Register name="en_l1a"> 0 </Register> + </Register> + <Register name="ext_trigger_delay_value"> 50 </Register> + <Register name="antenna_trigger_delay_value"> 200 </Register> + <Register name="delay_between_two_consecutive"> 10 </Register> + <Register name="misc"> + <Register name="backpressure_enable"> 1 </Register> + <Register name="stubOR"> 1 </Register> + <Register name="initial_fast_reset_enable"> 0 </Register> + </Register> + </Register> + <!-- I2C manager --> + <Register name="command_processor_block"> + </Register> + <!-- Phy Block --> + <Register name="physical_interface_block"> + <Register name="i2c"> + <Register name="frequency"> 4 </Register> + </Register> + </Register> + <!-- Readout Block --> + <Register name="readout_block"> + <Register name="packet_nbr"> 499 </Register> + <Register name="global"> + <Register name="data_handshake_enable"> 1 </Register> + <Register name="int_trig_enable"> 0 </Register> + <Register name="int_trig_rate"> 0 </Register> + <Register name="trigger_type"> 0 </Register> + <Register name="data_type"> 0 </Register> + <!--this is what is commonly known as stub latency--> + <Register name="common_stubdata_delay"> 27 </Register> + </Register> + </Register> + <!-- DIO5 Block --> + <Register name="dio5_block"> + <Register name="dio5_en"> 0 </Register> + <Register name="ch1"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch2"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch3"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch4"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch5"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + </Register> + <!-- TLU Block --> + <Register name="tlu_block"> + <Register name="tlu_enabled"> 0 </Register> + <Register name="handshake_mode"> 2 </Register> + <Register name="trigger_id_delay"> 1 </Register> + </Register> + </Register> + </BeBoard> + +<Settings> + + <!--[>Calibration<]--> + <Setting name="TargetVcth">0x78</Setting> + <Setting name="TargetOffset">0x50</Setting> + <Setting name="Nevents">50</Setting> + <Setting name="TestPulsePotentiometer">0x00</Setting> + <Setting name="HoleMode">0</Setting> + <Setting name="VerificationLoop">1</Setting> + + <!--Signal Scan Fit--> + <Setting name="InitialVcth">0x78</Setting> + <Setting name="SignalScanStep">2</Setting> + <Setting name="FitSignal">0</Setting> + +</Settings> +</HwDescription> diff --git a/settings/D19CDescriptionMPA_old.xml b/settings/D19CDescriptionMPA_old.xml new file mode 100644 index 0000000000000000000000000000000000000000..bab968cb03f3724c7bace6b321a045ff4f2dcfd0 --- /dev/null +++ b/settings/D19CDescriptionMPA_old.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<HwDescription> + <BeBoard Id="0" boardType="D19C" eventType="VR"> + <!--connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.1.81:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + <!--connection id="board" uri="ipbusudp-2.0://192.168.21.210:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /--> + <connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> + + <Module FeId="0" FMCId="0" ModuleId="0" Status="1"> + <MPA_Files path="./settings/MPAFiles/" /> + <MPA Id="0" configfile="MPA_default.txt" /> + <!--MPA Id="1" configfile="MPA_default_emulator.txt" /--> + </Module> + + <!--CONFIG--> + <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 --> + <Register name="fc7_daq_cnfg"> + <!-- Clock control --> + <Register name="clock"> + <Register name="ext_clk_en"> 0 </Register> + </Register> + <!-- TTC --> + <Register name="ttc"> + <Register name="ttc_enable"> 0 </Register> + </Register> + <!-- Fast Command Block --> + <Register name="fast_command_block"> + <Register name="triggers_to_accept"> 0 </Register> + <Register name="trigger_source"> 3 </Register> + <Register name="user_trigger_frequency"> 100 </Register> + <Register name="stubs_mask"> 1 </Register> + <!--this is the delay for the stub trigger--> + <Register name="stub_trigger_delay_value"> 0 </Register> + <Register name="stub_trigger_veto_length"> 0 </Register> + <Register name="test_pulse"> + <Register name="delay_after_fast_reset"> 50 </Register> + <Register name="delay_after_test_pulse"> 200 </Register> + <Register name="delay_before_next_pulse"> 400 </Register> + <Register name="en_fast_reset"> 1 </Register> + <Register name="en_test_pulse"> 1 </Register> + <Register name="en_l1a"> 1 </Register> + </Register> + <Register name="ext_trigger_delay_value"> 50 </Register> + <Register name="antenna_trigger_delay_value"> 200 </Register> + <Register name="delay_between_two_consecutive"> 10 </Register> + <Register name="misc"> + <Register name="backpressure_enable"> 1 </Register> + <Register name="stubOR"> 1 </Register> + <Register name="initial_fast_reset_enable"> 0 </Register> + </Register> + </Register> + <!-- I2C manager --> + <Register name="command_processor_block"> + </Register> + <!-- Phy Block --> + <Register name="physical_interface_block"> + <Register name="i2c"> + <Register name="frequency"> 4 </Register> + </Register> + </Register> + <!-- Readout Block --> + <Register name="readout_block"> + <Register name="packet_nbr"> 499 </Register> + <Register name="global"> + <Register name="data_handshake_enable"> 1 </Register> + <Register name="int_trig_enable"> 0 </Register> + <Register name="int_trig_rate"> 0 </Register> + <Register name="trigger_type"> 0 </Register> + <Register name="data_type"> 0 </Register> + <!--this is what is commonly known as stub latency--> + <Register name="common_stubdata_delay"> 27 </Register> + </Register> + </Register> + <!-- DIO5 Block --> + <Register name="dio5_block"> + <Register name="dio5_en"> 1 </Register> + <Register name="ch1"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch2"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch3"> + <Register name="out_enable"> 1 </Register> + <Register name="term_enable"> 0 </Register> + <Register name="threshold"> 0 </Register> + </Register> + <Register name="ch4"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + <Register name="ch5"> + <Register name="out_enable"> 0 </Register> + <Register name="term_enable"> 1 </Register> + <Register name="threshold"> 50 </Register> + </Register> + </Register> + <!-- TLU Block --> + <Register name="tlu_block"> + <Register name="handshake_mode"> 1 </Register> + <Register name="tlu_enabled"> 1 </Register> + </Register> + </Register> + </BeBoard> + +<Settings> + + <!--[>Calibration<]--> + <Setting name="TargetVcth">0x78</Setting> + <Setting name="TargetOffset">0x50</Setting> + <Setting name="Nevents">50</Setting> + <Setting name="TestPulsePotentiometer">0x00</Setting> + <Setting name="HoleMode">0</Setting> + <Setting name="VerificationLoop">1</Setting> + + <!--Signal Scan Fit--> + <Setting name="InitialVcth">0x78</Setting> + <Setting name="SignalScanStep">2</Setting> + <Setting name="FitSignal">0</Setting> + +</Settings> +</HwDescription> + diff --git a/settings/FNAL_TB.xml b/settings/FNAL_TB.xml old mode 100755 new mode 100644 diff --git a/settings/GLIBDescription_2CBC.xml b/settings/GLIBDescription_2CBC.xml old mode 100755 new mode 100644 diff --git a/settings/GLIBDescription_8CBC.xml b/settings/GLIBDescription_8CBC.xml old mode 100755 new mode 100644 diff --git a/settings/HWDescription_MAPSA.xml b/settings/HWDescription_MAPSA.xml index d5bcde4c1bc0bfc00ac819b9279d6a2c80ded6cf..f6e9540f88c8d7ad1b94a1170fc89de1c370e754 100644 --- a/settings/HWDescription_MAPSA.xml +++ b/settings/HWDescription_MAPSA.xml @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='utf-8'?> <HwDescription> - <BeBoard Id="0" boardType="MPAGLIB"> - <connection id="board" uri="ipbusudp-2.0://192.168.0.175:50001" address_table="file://settings/address_tables/address_table_MaPSA.xml" /> + <BeBoard Id="0" boardType="MPAlightGLIB"> + <connection id="board" uri="ipbusudp-2.0://192.168.1.51:50001" address_table="file://settings/address_tables/address_table_SSA.xml" /> </BeBoard> </HwDescription> diff --git a/settings/HWDescription_MPA.xml b/settings/HWDescription_MPA.xml new file mode 100644 index 0000000000000000000000000000000000000000..ef9c9f3723b474d2f7b48307f1679668eb69d5f7 --- /dev/null +++ b/settings/HWDescription_MPA.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='utf-8'?> +<HwDescription> + <BeBoard Id="0" boardType="D19C" > + <connection id="board" uri="ipbusudp-2.0://192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> + </BeBoard> +</HwDescription> diff --git a/settings/HWDescription_SSA.xml b/settings/HWDescription_SSA.xml new file mode 100644 index 0000000000000000000000000000000000000000..a18022c7d000f74eb7320f3a06a0372d64e62d7b --- /dev/null +++ b/settings/HWDescription_SSA.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='utf-8'?> +<HwDescription> + <BeBoard Id="0" boardType="D19C" > + <connection id="board" uri="ipbusudp-2.0://192.168.1.79:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> + </BeBoard> +</HwDescription> diff --git a/settings/ICDescription.xml b/settings/ICDescription.xml old mode 100755 new mode 100644 diff --git a/settings/MPAFiles/MPA_default.txt b/settings/MPAFiles/MPA_default.txt new file mode 100644 index 0000000000000000000000000000000000000000..6c7fed2d8f6d96951a67786a4c2f77b720c5f945 --- /dev/null +++ b/settings/MPAFiles/MPA_default.txt @@ -0,0 +1,30 @@ +*-------------------------------------------------------------------------------- +* Periphery Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +ReadoutMode 0x0 0x8800 0x0 0x0 +ECM 0x0 0x8801 0x8 0xc8 +EdgeSelT1Raw 0x0 0x881e 0x3 0x0 +CalDAC0 0x0 0x8840 0x0 0x0 +CalDAC1 0x0 0x8841 0x0 0x0 +CalDAC2 0x0 0x8842 0x0 0x0 +CalDAC3 0x0 0x8843 0x0 0x0 +CalDAC4 0x0 0x8844 0x0 0x0 +CalDAC5 0x0 0x8845 0x0 0x0 +CalDAC6 0x0 0x8846 0x0 0x0 +ThDAC0 0x0 0x8847 0x0 0x60 +ThDAC1 0x0 0x8848 0x0 0x60 +ThDAC2 0x0 0x8849 0x0 0x60 +ThDAC3 0x0 0x884a 0x0 0x60 +ThDAC4 0x0 0x884b 0x0 0x60 +ThDAC5 0x0 0x884c 0x0 0x60 +ThDAC6 0x0 0x884d 0x0 0x60 + +*-------------------------------------------------------------------------------- +* Pixel Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +*-------------------------------------------------------------------------------- +ENFLAGS 0x0 0x0 0x0 0x0 +ModeSel 0x0 0x1 0x0 0x0 +TrimDAC 0x0 0x2 0x0 0x0 diff --git a/settings/MPAFiles/MPA_default_allreg.txt b/settings/MPAFiles/MPA_default_allreg.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0c5a3a3ecde74387c600a3bc4a3087267b19578 --- /dev/null +++ b/settings/MPAFiles/MPA_default_allreg.txt @@ -0,0 +1,2064 @@ +*-------------------------------------------------------------------------------- +* Periphery Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +ReadoutMode 0x0 0x8800 0x0 0x0 +ECM 0x0 0x8801 0x8 0x8 +RetimePix 0x0 0x8802 0x4 0x4 +LowPowerTL 0x0 0x8803 0x0 0x0 +ChipN 0x0 0x8804 0x0 0x0 +CodeDM8 0x0 0x8805 0x3f 0x3f +CodeM76 0x0 0x8806 0x3e 0x3e +CodeM54 0x0 0x8807 0x3d 0x3d +CodeM32 0x0 0x8808 0x28 0x28 +CodeM10 0x0 0x8809 0x0 0x0 +CodeP12 0x0 0x880a 0x0 0x0 +CodeP34 0x0 0x880b 0x9 0x9 +CodeP56 0x0 0x880c 0x12 0x12 +CodeP78 0x0 0x880d 0x1b 0x1b +OutSetting_0 0x0 0x880e 0x0 0x0 +OutSetting_1 0x0 0x880f 0x0 0x0 +OutSetting_2 0x0 0x8810 0x0 0x0 +OutSetting_3 0x0 0x8811 0x0 0x0 +OutSetting_4 0x0 0x8812 0x0 0x0 +OutSetting_5 0x0 0x8813 0x0 0x0 +InSetting_0 0x0 0x8814 0x0 0x0 +InSetting_1 0x0 0x8815 0x0 0x0 +InSetting_2 0x0 0x8816 0x0 0x0 +InSetting_3 0x0 0x8817 0x0 0x0 +InSetting_4 0x0 0x8818 0x0 0x0 +InSetting_5 0x0 0x8819 0x0 0x0 +InSetting_6 0x0 0x881a 0x0 0x0 +InSetting_7 0x0 0x881b 0x0 0x0 +InSetting_8 0x0 0x881c 0x0 0x0 +EdgeSelTrig 0x0 0x881d 0xff 0xff +EdgeSelT1Raw 0x0 0x881e 0x3 0x3 +ConfDLL 0x0 0x881f 0x0 0x0 +PhaseShift 0x0 0x8820 0x0 0x0 +CalLen 0x0 0x8821 0x0 0x0 +LatencyRx320 0x0 0x8822 0x1b 0x1b +LatencyRx40 0x0 0x8823 0x1 0x1 +LFSR_data 0x0 0x8824 0x0 0x0 +ClkEnable 0x0 0x8825 0x0 0x0 +ConfSLVS 0x0 0x8826 0x0 0x0 +SEUcntPeri 0x0 0x8827 0x0 0x0 +ErrorL1 0x0 0x8828 0x0 0x0 +OFcnt 0x0 0x8829 0x0 0x0 +L1OffsetPeri_1 0x0 0x882a 0x0 0x0 +L1OffsetPeri_2 0x0 0x882b 0x0 0x0 +SSAOffset_1 0x0 0x882c 0x0 0x0 +SSAOffset_2 0x0 0x882d 0x0 0x0 +EfuseMode 0x0 0x8832 0x0 0x0 +EfuseProg0 0x0 0x8833 0x0 0x0 +EfuseProg1 0x0 0x8834 0x0 0x0 +EfuseProg2 0x0 0x8835 0x0 0x0 +EfuseProg3 0x0 0x8836 0x0 0x0 +EfuseValue0 0x0 0x8837 0x0 0x0 +EfuseValue1 0x0 0x8838 0x0 0x0 +EfuseValue2 0x0 0x8839 0x0 0x0 +EfuseValue3 0x0 0x883a 0x0 0x0 +CalDAC0 0x0 0x8840 0x0 0x0 +CalDAC1 0x0 0x8841 0x0 0x0 +CalDAC2 0x0 0x8842 0x0 0x0 +CalDAC3 0x0 0x8843 0x0 0x0 +CalDAC4 0x0 0x8844 0x0 0x0 +CalDAC5 0x0 0x8845 0x0 0x0 +CalDAC6 0x0 0x8846 0x0 0x0 +ThDAC0 0x0 0x8847 0x0 0x0 +ThDAC1 0x0 0x8848 0x0 0x0 +ThDAC2 0x0 0x8849 0x0 0x0 +ThDAC3 0x0 0x884a 0x0 0x0 +ThDAC4 0x0 0x884b 0x0 0x0 +ThDAC5 0x0 0x884c 0x0 0x0 +ThDAC6 0x0 0x884d 0x0 0x0 +A0 0x0 0x884e 0x0 0x0 +A1 0x0 0x884f 0x0 0x0 +A2 0x0 0x8850 0x0 0x0 +A3 0x0 0x8851 0x0 0x0 +A4 0x0 0x8852 0x0 0x0 +A5 0x0 0x8853 0x0 0x0 +A6 0x0 0x8854 0x0 0x0 +B0 0x0 0x8855 0x0 0x0 +B1 0x0 0x8856 0x0 0x0 +B2 0x0 0x8857 0x0 0x0 +B3 0x0 0x8858 0x0 0x0 +B4 0x0 0x8859 0x0 0x0 +B5 0x0 0x885a 0x0 0x0 +B6 0x0 0x885b 0x0 0x0 +C0 0x0 0x885c 0x0 0x0 +C1 0x0 0x885d 0x0 0x0 +C2 0x0 0x885e 0x0 0x0 +C3 0x0 0x885f 0x0 0x0 +C4 0x0 0x8860 0x0 0x0 +C5 0x0 0x8861 0x0 0x0 +C6 0x0 0x8862 0x0 0x0 +D0 0x0 0x8863 0x0 0x0 +D1 0x0 0x8864 0x0 0x0 +D2 0x0 0x8865 0x0 0x0 +D3 0x0 0x8866 0x0 0x0 +D4 0x0 0x8867 0x0 0x0 +D5 0x0 0x8868 0x0 0x0 +D6 0x0 0x8869 0x0 0x0 +E0 0x0 0x886a 0x0 0x0 +E1 0x0 0x886b 0x0 0x0 +E2 0x0 0x886c 0x0 0x0 +E3 0x0 0x886d 0x0 0x0 +E4 0x0 0x886e 0x0 0x0 +E5 0x0 0x886f 0x0 0x0 +E6 0x0 0x8870 0x0 0x0 +F0 0x0 0x8871 0x0 0x0 +F1 0x0 0x8872 0x0 0x0 +F2 0x0 0x8873 0x0 0x0 +F3 0x0 0x8874 0x0 0x0 +F4 0x0 0x8875 0x0 0x0 +F5 0x0 0x8876 0x0 0x0 +F6 0x0 0x8877 0x0 0x0 +TEST0 0x0 0x8878 0x0 0x0 +TEST1 0x0 0x8879 0x0 0x0 +TEST2 0x0 0x887a 0x0 0x0 +TEST3 0x0 0x887b 0x0 0x0 +TEST4 0x0 0x887c 0x0 0x0 +TEST5 0x0 0x887d 0x0 0x0 +TEST6 0x0 0x887e 0x0 0x0 +TESTMUX 0x0 0x887f 0x0 0x0 +DL_en 0x0 0x8880 0x0 0x0 +DL_ctrl0 0x0 0x8881 0x0 0x0 +DL_ctrl1 0x0 0x8882 0x0 0x0 +DL_ctrl2 0x0 0x8883 0x0 0x0 +DL_ctrl3 0x0 0x8884 0x0 0x0 +DL_ctrl4 0x0 0x8885 0x0 0x0 +DL_ctrl5 0x0 0x8886 0x0 0x0 +DL_ctrl6 0x0 0x8887 0x0 0x0 +*-------------------------------------------------------------------------------- +* Memory Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +L1Offset_1 0x0 0x1 0xf4 0xf4 +L1Offset_2 0x0 0x2 0x1 0x1 +ClrRst 0x0 0x3 0xef 0xef +MemGatEn 0x0 0x4 0x1 0x1 +SEUcntRow 0x0 0x5 0x0 0x0 + +*-------------------------------------------------------------------------------- +* Pixel Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +*-------------------------------------------------------------------------------- +ENFLAGS 0x0 0x0 0x0 0x0 +ModeSel 0x0 0x1 0x0 0x0 +TrimDAC 0x0 0x2 0x0 0x0 +ClusterCut 0x0 0x3 0x0 0x0 +HipCut 0x0 0x4 0x0 0x0 +DigPattern 0x0 0x5 0x0 0x0 +ReadCounter_LSB 0x0 0x9 0x0 0x0 +ReadCounter_MSB 0x0 0xa 0x0 0x0 + +*-------------------------------------------------------------------------------- +* Pixel Trims +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +*-------------------------------------------------------------------------------- +trim_r1p1 0x0 0x901 0xF 0xF +trim_r1p2 0x0 0x902 0xF 0xF +trim_r1p3 0x0 0x903 0xF 0xF +trim_r1p4 0x0 0x904 0xF 0xF +trim_r1p5 0x0 0x905 0xF 0xF +trim_r1p6 0x0 0x906 0xF 0xF +trim_r1p7 0x0 0x907 0xF 0xF +trim_r1p8 0x0 0x908 0xF 0xF +trim_r1p9 0x0 0x909 0xF 0xF +trim_r1p10 0x0 0x90a 0xF 0xF +trim_r1p11 0x0 0x90b 0xF 0xF +trim_r1p12 0x0 0x90c 0xF 0xF +trim_r1p13 0x0 0x90d 0xF 0xF +trim_r1p14 0x0 0x90e 0xF 0xF +trim_r1p15 0x0 0x90f 0xF 0xF +trim_r1p16 0x0 0x910 0xF 0xF +trim_r1p17 0x0 0x911 0xF 0xF +trim_r1p18 0x0 0x912 0xF 0xF +trim_r1p19 0x0 0x913 0xF 0xF +trim_r1p20 0x0 0x914 0xF 0xF +trim_r1p21 0x0 0x915 0xF 0xF +trim_r1p22 0x0 0x916 0xF 0xF +trim_r1p23 0x0 0x917 0xF 0xF +trim_r1p24 0x0 0x918 0xF 0xF +trim_r1p25 0x0 0x919 0xF 0xF +trim_r1p26 0x0 0x91a 0xF 0xF +trim_r1p27 0x0 0x91b 0xF 0xF +trim_r1p28 0x0 0x91c 0xF 0xF +trim_r1p29 0x0 0x91d 0xF 0xF +trim_r1p30 0x0 0x91e 0xF 0xF +trim_r1p31 0x0 0x91f 0xF 0xF +trim_r1p32 0x0 0x920 0xF 0xF +trim_r1p33 0x0 0x921 0xF 0xF +trim_r1p34 0x0 0x922 0xF 0xF +trim_r1p35 0x0 0x923 0xF 0xF +trim_r1p36 0x0 0x924 0xF 0xF +trim_r1p37 0x0 0x925 0xF 0xF +trim_r1p38 0x0 0x926 0xF 0xF +trim_r1p39 0x0 0x927 0xF 0xF +trim_r1p40 0x0 0x928 0xF 0xF +trim_r1p41 0x0 0x929 0xF 0xF +trim_r1p42 0x0 0x92a 0xF 0xF +trim_r1p43 0x0 0x92b 0xF 0xF +trim_r1p44 0x0 0x92c 0xF 0xF +trim_r1p45 0x0 0x92d 0xF 0xF +trim_r1p46 0x0 0x92e 0xF 0xF +trim_r1p47 0x0 0x92f 0xF 0xF +trim_r1p48 0x0 0x930 0xF 0xF +trim_r1p49 0x0 0x931 0xF 0xF +trim_r1p50 0x0 0x932 0xF 0xF +trim_r1p51 0x0 0x933 0xF 0xF +trim_r1p52 0x0 0x934 0xF 0xF +trim_r1p53 0x0 0x935 0xF 0xF +trim_r1p54 0x0 0x936 0xF 0xF +trim_r1p55 0x0 0x937 0xF 0xF +trim_r1p56 0x0 0x938 0xF 0xF +trim_r1p57 0x0 0x939 0xF 0xF +trim_r1p58 0x0 0x93a 0xF 0xF +trim_r1p59 0x0 0x93b 0xF 0xF +trim_r1p60 0x0 0x93c 0xF 0xF +trim_r1p61 0x0 0x93d 0xF 0xF +trim_r1p62 0x0 0x93e 0xF 0xF +trim_r1p63 0x0 0x93f 0xF 0xF +trim_r1p64 0x0 0x940 0xF 0xF +trim_r1p65 0x0 0x941 0xF 0xF +trim_r1p66 0x0 0x942 0xF 0xF +trim_r1p67 0x0 0x943 0xF 0xF +trim_r1p68 0x0 0x944 0xF 0xF +trim_r1p69 0x0 0x945 0xF 0xF +trim_r1p70 0x0 0x946 0xF 0xF +trim_r1p71 0x0 0x947 0xF 0xF +trim_r1p72 0x0 0x948 0xF 0xF +trim_r1p73 0x0 0x949 0xF 0xF +trim_r1p74 0x0 0x94a 0xF 0xF +trim_r1p75 0x0 0x94b 0xF 0xF +trim_r1p76 0x0 0x94c 0xF 0xF +trim_r1p77 0x0 0x94d 0xF 0xF +trim_r1p78 0x0 0x94e 0xF 0xF +trim_r1p79 0x0 0x94f 0xF 0xF +trim_r1p80 0x0 0x950 0xF 0xF +trim_r1p81 0x0 0x951 0xF 0xF +trim_r1p82 0x0 0x952 0xF 0xF +trim_r1p83 0x0 0x953 0xF 0xF +trim_r1p84 0x0 0x954 0xF 0xF +trim_r1p85 0x0 0x955 0xF 0xF +trim_r1p86 0x0 0x956 0xF 0xF +trim_r1p87 0x0 0x957 0xF 0xF +trim_r1p88 0x0 0x958 0xF 0xF +trim_r1p89 0x0 0x959 0xF 0xF +trim_r1p90 0x0 0x95a 0xF 0xF +trim_r1p91 0x0 0x95b 0xF 0xF +trim_r1p92 0x0 0x95c 0xF 0xF +trim_r1p93 0x0 0x95d 0xF 0xF +trim_r1p94 0x0 0x95e 0xF 0xF +trim_r1p95 0x0 0x95f 0xF 0xF +trim_r1p96 0x0 0x960 0xF 0xF +trim_r1p97 0x0 0x961 0xF 0xF +trim_r1p98 0x0 0x962 0xF 0xF +trim_r1p99 0x0 0x963 0xF 0xF +trim_r1p100 0x0 0x964 0xF 0xF +trim_r1p101 0x0 0x965 0xF 0xF +trim_r1p102 0x0 0x966 0xF 0xF +trim_r1p103 0x0 0x967 0xF 0xF +trim_r1p104 0x0 0x968 0xF 0xF +trim_r1p105 0x0 0x969 0xF 0xF +trim_r1p106 0x0 0x96a 0xF 0xF +trim_r1p107 0x0 0x96b 0xF 0xF +trim_r1p108 0x0 0x96c 0xF 0xF +trim_r1p109 0x0 0x96d 0xF 0xF +trim_r1p110 0x0 0x96e 0xF 0xF +trim_r1p111 0x0 0x96f 0xF 0xF +trim_r1p112 0x0 0x970 0xF 0xF +trim_r1p113 0x0 0x971 0xF 0xF +trim_r1p114 0x0 0x972 0xF 0xF +trim_r1p115 0x0 0x973 0xF 0xF +trim_r1p116 0x0 0x974 0xF 0xF +trim_r1p117 0x0 0x975 0xF 0xF +trim_r1p118 0x0 0x976 0xF 0xF +trim_r1p119 0x0 0x977 0xF 0xF +trim_r2p1 0x0 0x1101 0xF 0xF +trim_r2p2 0x0 0x1102 0xF 0xF +trim_r2p3 0x0 0x1103 0xF 0xF +trim_r2p4 0x0 0x1104 0xF 0xF +trim_r2p5 0x0 0x1105 0xF 0xF +trim_r2p6 0x0 0x1106 0xF 0xF +trim_r2p7 0x0 0x1107 0xF 0xF +trim_r2p8 0x0 0x1108 0xF 0xF +trim_r2p9 0x0 0x1109 0xF 0xF +trim_r2p10 0x0 0x110a 0xF 0xF +trim_r2p11 0x0 0x110b 0xF 0xF +trim_r2p12 0x0 0x110c 0xF 0xF +trim_r2p13 0x0 0x110d 0xF 0xF +trim_r2p14 0x0 0x110e 0xF 0xF +trim_r2p15 0x0 0x110f 0xF 0xF +trim_r2p16 0x0 0x1110 0xF 0xF +trim_r2p17 0x0 0x1111 0xF 0xF +trim_r2p18 0x0 0x1112 0xF 0xF +trim_r2p19 0x0 0x1113 0xF 0xF +trim_r2p20 0x0 0x1114 0xF 0xF +trim_r2p21 0x0 0x1115 0xF 0xF +trim_r2p22 0x0 0x1116 0xF 0xF +trim_r2p23 0x0 0x1117 0xF 0xF +trim_r2p24 0x0 0x1118 0xF 0xF +trim_r2p25 0x0 0x1119 0xF 0xF +trim_r2p26 0x0 0x111a 0xF 0xF +trim_r2p27 0x0 0x111b 0xF 0xF +trim_r2p28 0x0 0x111c 0xF 0xF +trim_r2p29 0x0 0x111d 0xF 0xF +trim_r2p30 0x0 0x111e 0xF 0xF +trim_r2p31 0x0 0x111f 0xF 0xF +trim_r2p32 0x0 0x1120 0xF 0xF +trim_r2p33 0x0 0x1121 0xF 0xF +trim_r2p34 0x0 0x1122 0xF 0xF +trim_r2p35 0x0 0x1123 0xF 0xF +trim_r2p36 0x0 0x1124 0xF 0xF +trim_r2p37 0x0 0x1125 0xF 0xF +trim_r2p38 0x0 0x1126 0xF 0xF +trim_r2p39 0x0 0x1127 0xF 0xF +trim_r2p40 0x0 0x1128 0xF 0xF +trim_r2p41 0x0 0x1129 0xF 0xF +trim_r2p42 0x0 0x112a 0xF 0xF +trim_r2p43 0x0 0x112b 0xF 0xF +trim_r2p44 0x0 0x112c 0xF 0xF +trim_r2p45 0x0 0x112d 0xF 0xF +trim_r2p46 0x0 0x112e 0xF 0xF +trim_r2p47 0x0 0x112f 0xF 0xF +trim_r2p48 0x0 0x1130 0xF 0xF +trim_r2p49 0x0 0x1131 0xF 0xF +trim_r2p50 0x0 0x1132 0xF 0xF +trim_r2p51 0x0 0x1133 0xF 0xF +trim_r2p52 0x0 0x1134 0xF 0xF +trim_r2p53 0x0 0x1135 0xF 0xF +trim_r2p54 0x0 0x1136 0xF 0xF +trim_r2p55 0x0 0x1137 0xF 0xF +trim_r2p56 0x0 0x1138 0xF 0xF +trim_r2p57 0x0 0x1139 0xF 0xF +trim_r2p58 0x0 0x113a 0xF 0xF +trim_r2p59 0x0 0x113b 0xF 0xF +trim_r2p60 0x0 0x113c 0xF 0xF +trim_r2p61 0x0 0x113d 0xF 0xF +trim_r2p62 0x0 0x113e 0xF 0xF +trim_r2p63 0x0 0x113f 0xF 0xF +trim_r2p64 0x0 0x1140 0xF 0xF +trim_r2p65 0x0 0x1141 0xF 0xF +trim_r2p66 0x0 0x1142 0xF 0xF +trim_r2p67 0x0 0x1143 0xF 0xF +trim_r2p68 0x0 0x1144 0xF 0xF +trim_r2p69 0x0 0x1145 0xF 0xF +trim_r2p70 0x0 0x1146 0xF 0xF +trim_r2p71 0x0 0x1147 0xF 0xF +trim_r2p72 0x0 0x1148 0xF 0xF +trim_r2p73 0x0 0x1149 0xF 0xF +trim_r2p74 0x0 0x114a 0xF 0xF +trim_r2p75 0x0 0x114b 0xF 0xF +trim_r2p76 0x0 0x114c 0xF 0xF +trim_r2p77 0x0 0x114d 0xF 0xF +trim_r2p78 0x0 0x114e 0xF 0xF +trim_r2p79 0x0 0x114f 0xF 0xF +trim_r2p80 0x0 0x1150 0xF 0xF +trim_r2p81 0x0 0x1151 0xF 0xF +trim_r2p82 0x0 0x1152 0xF 0xF +trim_r2p83 0x0 0x1153 0xF 0xF +trim_r2p84 0x0 0x1154 0xF 0xF +trim_r2p85 0x0 0x1155 0xF 0xF +trim_r2p86 0x0 0x1156 0xF 0xF +trim_r2p87 0x0 0x1157 0xF 0xF +trim_r2p88 0x0 0x1158 0xF 0xF +trim_r2p89 0x0 0x1159 0xF 0xF +trim_r2p90 0x0 0x115a 0xF 0xF +trim_r2p91 0x0 0x115b 0xF 0xF +trim_r2p92 0x0 0x115c 0xF 0xF +trim_r2p93 0x0 0x115d 0xF 0xF +trim_r2p94 0x0 0x115e 0xF 0xF +trim_r2p95 0x0 0x115f 0xF 0xF +trim_r2p96 0x0 0x1160 0xF 0xF +trim_r2p97 0x0 0x1161 0xF 0xF +trim_r2p98 0x0 0x1162 0xF 0xF +trim_r2p99 0x0 0x1163 0xF 0xF +trim_r2p100 0x0 0x1164 0xF 0xF +trim_r2p101 0x0 0x1165 0xF 0xF +trim_r2p102 0x0 0x1166 0xF 0xF +trim_r2p103 0x0 0x1167 0xF 0xF +trim_r2p104 0x0 0x1168 0xF 0xF +trim_r2p105 0x0 0x1169 0xF 0xF +trim_r2p106 0x0 0x116a 0xF 0xF +trim_r2p107 0x0 0x116b 0xF 0xF +trim_r2p108 0x0 0x116c 0xF 0xF +trim_r2p109 0x0 0x116d 0xF 0xF +trim_r2p110 0x0 0x116e 0xF 0xF +trim_r2p111 0x0 0x116f 0xF 0xF +trim_r2p112 0x0 0x1170 0xF 0xF +trim_r2p113 0x0 0x1171 0xF 0xF +trim_r2p114 0x0 0x1172 0xF 0xF +trim_r2p115 0x0 0x1173 0xF 0xF +trim_r2p116 0x0 0x1174 0xF 0xF +trim_r2p117 0x0 0x1175 0xF 0xF +trim_r2p118 0x0 0x1176 0xF 0xF +trim_r2p119 0x0 0x1177 0xF 0xF +trim_r3p1 0x0 0x1901 0xF 0xF +trim_r3p2 0x0 0x1902 0xF 0xF +trim_r3p3 0x0 0x1903 0xF 0xF +trim_r3p4 0x0 0x1904 0xF 0xF +trim_r3p5 0x0 0x1905 0xF 0xF +trim_r3p6 0x0 0x1906 0xF 0xF +trim_r3p7 0x0 0x1907 0xF 0xF +trim_r3p8 0x0 0x1908 0xF 0xF +trim_r3p9 0x0 0x1909 0xF 0xF +trim_r3p10 0x0 0x190a 0xF 0xF +trim_r3p11 0x0 0x190b 0xF 0xF +trim_r3p12 0x0 0x190c 0xF 0xF +trim_r3p13 0x0 0x190d 0xF 0xF +trim_r3p14 0x0 0x190e 0xF 0xF +trim_r3p15 0x0 0x190f 0xF 0xF +trim_r3p16 0x0 0x1910 0xF 0xF +trim_r3p17 0x0 0x1911 0xF 0xF +trim_r3p18 0x0 0x1912 0xF 0xF +trim_r3p19 0x0 0x1913 0xF 0xF +trim_r3p20 0x0 0x1914 0xF 0xF +trim_r3p21 0x0 0x1915 0xF 0xF +trim_r3p22 0x0 0x1916 0xF 0xF +trim_r3p23 0x0 0x1917 0xF 0xF +trim_r3p24 0x0 0x1918 0xF 0xF +trim_r3p25 0x0 0x1919 0xF 0xF +trim_r3p26 0x0 0x191a 0xF 0xF +trim_r3p27 0x0 0x191b 0xF 0xF +trim_r3p28 0x0 0x191c 0xF 0xF +trim_r3p29 0x0 0x191d 0xF 0xF +trim_r3p30 0x0 0x191e 0xF 0xF +trim_r3p31 0x0 0x191f 0xF 0xF +trim_r3p32 0x0 0x1920 0xF 0xF +trim_r3p33 0x0 0x1921 0xF 0xF +trim_r3p34 0x0 0x1922 0xF 0xF +trim_r3p35 0x0 0x1923 0xF 0xF +trim_r3p36 0x0 0x1924 0xF 0xF +trim_r3p37 0x0 0x1925 0xF 0xF +trim_r3p38 0x0 0x1926 0xF 0xF +trim_r3p39 0x0 0x1927 0xF 0xF +trim_r3p40 0x0 0x1928 0xF 0xF +trim_r3p41 0x0 0x1929 0xF 0xF +trim_r3p42 0x0 0x192a 0xF 0xF +trim_r3p43 0x0 0x192b 0xF 0xF +trim_r3p44 0x0 0x192c 0xF 0xF +trim_r3p45 0x0 0x192d 0xF 0xF +trim_r3p46 0x0 0x192e 0xF 0xF +trim_r3p47 0x0 0x192f 0xF 0xF +trim_r3p48 0x0 0x1930 0xF 0xF +trim_r3p49 0x0 0x1931 0xF 0xF +trim_r3p50 0x0 0x1932 0xF 0xF +trim_r3p51 0x0 0x1933 0xF 0xF +trim_r3p52 0x0 0x1934 0xF 0xF +trim_r3p53 0x0 0x1935 0xF 0xF +trim_r3p54 0x0 0x1936 0xF 0xF +trim_r3p55 0x0 0x1937 0xF 0xF +trim_r3p56 0x0 0x1938 0xF 0xF +trim_r3p57 0x0 0x1939 0xF 0xF +trim_r3p58 0x0 0x193a 0xF 0xF +trim_r3p59 0x0 0x193b 0xF 0xF +trim_r3p60 0x0 0x193c 0xF 0xF +trim_r3p61 0x0 0x193d 0xF 0xF +trim_r3p62 0x0 0x193e 0xF 0xF +trim_r3p63 0x0 0x193f 0xF 0xF +trim_r3p64 0x0 0x1940 0xF 0xF +trim_r3p65 0x0 0x1941 0xF 0xF +trim_r3p66 0x0 0x1942 0xF 0xF +trim_r3p67 0x0 0x1943 0xF 0xF +trim_r3p68 0x0 0x1944 0xF 0xF +trim_r3p69 0x0 0x1945 0xF 0xF +trim_r3p70 0x0 0x1946 0xF 0xF +trim_r3p71 0x0 0x1947 0xF 0xF +trim_r3p72 0x0 0x1948 0xF 0xF +trim_r3p73 0x0 0x1949 0xF 0xF +trim_r3p74 0x0 0x194a 0xF 0xF +trim_r3p75 0x0 0x194b 0xF 0xF +trim_r3p76 0x0 0x194c 0xF 0xF +trim_r3p77 0x0 0x194d 0xF 0xF +trim_r3p78 0x0 0x194e 0xF 0xF +trim_r3p79 0x0 0x194f 0xF 0xF +trim_r3p80 0x0 0x1950 0xF 0xF +trim_r3p81 0x0 0x1951 0xF 0xF +trim_r3p82 0x0 0x1952 0xF 0xF +trim_r3p83 0x0 0x1953 0xF 0xF +trim_r3p84 0x0 0x1954 0xF 0xF +trim_r3p85 0x0 0x1955 0xF 0xF +trim_r3p86 0x0 0x1956 0xF 0xF +trim_r3p87 0x0 0x1957 0xF 0xF +trim_r3p88 0x0 0x1958 0xF 0xF +trim_r3p89 0x0 0x1959 0xF 0xF +trim_r3p90 0x0 0x195a 0xF 0xF +trim_r3p91 0x0 0x195b 0xF 0xF +trim_r3p92 0x0 0x195c 0xF 0xF +trim_r3p93 0x0 0x195d 0xF 0xF +trim_r3p94 0x0 0x195e 0xF 0xF +trim_r3p95 0x0 0x195f 0xF 0xF +trim_r3p96 0x0 0x1960 0xF 0xF +trim_r3p97 0x0 0x1961 0xF 0xF +trim_r3p98 0x0 0x1962 0xF 0xF +trim_r3p99 0x0 0x1963 0xF 0xF +trim_r3p100 0x0 0x1964 0xF 0xF +trim_r3p101 0x0 0x1965 0xF 0xF +trim_r3p102 0x0 0x1966 0xF 0xF +trim_r3p103 0x0 0x1967 0xF 0xF +trim_r3p104 0x0 0x1968 0xF 0xF +trim_r3p105 0x0 0x1969 0xF 0xF +trim_r3p106 0x0 0x196a 0xF 0xF +trim_r3p107 0x0 0x196b 0xF 0xF +trim_r3p108 0x0 0x196c 0xF 0xF +trim_r3p109 0x0 0x196d 0xF 0xF +trim_r3p110 0x0 0x196e 0xF 0xF +trim_r3p111 0x0 0x196f 0xF 0xF +trim_r3p112 0x0 0x1970 0xF 0xF +trim_r3p113 0x0 0x1971 0xF 0xF +trim_r3p114 0x0 0x1972 0xF 0xF +trim_r3p115 0x0 0x1973 0xF 0xF +trim_r3p116 0x0 0x1974 0xF 0xF +trim_r3p117 0x0 0x1975 0xF 0xF +trim_r3p118 0x0 0x1976 0xF 0xF +trim_r3p119 0x0 0x1977 0xF 0xF +trim_r4p1 0x0 0x2101 0xF 0xF +trim_r4p2 0x0 0x2102 0xF 0xF +trim_r4p3 0x0 0x2103 0xF 0xF +trim_r4p4 0x0 0x2104 0xF 0xF +trim_r4p5 0x0 0x2105 0xF 0xF +trim_r4p6 0x0 0x2106 0xF 0xF +trim_r4p7 0x0 0x2107 0xF 0xF +trim_r4p8 0x0 0x2108 0xF 0xF +trim_r4p9 0x0 0x2109 0xF 0xF +trim_r4p10 0x0 0x210a 0xF 0xF +trim_r4p11 0x0 0x210b 0xF 0xF +trim_r4p12 0x0 0x210c 0xF 0xF +trim_r4p13 0x0 0x210d 0xF 0xF +trim_r4p14 0x0 0x210e 0xF 0xF +trim_r4p15 0x0 0x210f 0xF 0xF +trim_r4p16 0x0 0x2110 0xF 0xF +trim_r4p17 0x0 0x2111 0xF 0xF +trim_r4p18 0x0 0x2112 0xF 0xF +trim_r4p19 0x0 0x2113 0xF 0xF +trim_r4p20 0x0 0x2114 0xF 0xF +trim_r4p21 0x0 0x2115 0xF 0xF +trim_r4p22 0x0 0x2116 0xF 0xF +trim_r4p23 0x0 0x2117 0xF 0xF +trim_r4p24 0x0 0x2118 0xF 0xF +trim_r4p25 0x0 0x2119 0xF 0xF +trim_r4p26 0x0 0x211a 0xF 0xF +trim_r4p27 0x0 0x211b 0xF 0xF +trim_r4p28 0x0 0x211c 0xF 0xF +trim_r4p29 0x0 0x211d 0xF 0xF +trim_r4p30 0x0 0x211e 0xF 0xF +trim_r4p31 0x0 0x211f 0xF 0xF +trim_r4p32 0x0 0x2120 0xF 0xF +trim_r4p33 0x0 0x2121 0xF 0xF +trim_r4p34 0x0 0x2122 0xF 0xF +trim_r4p35 0x0 0x2123 0xF 0xF +trim_r4p36 0x0 0x2124 0xF 0xF +trim_r4p37 0x0 0x2125 0xF 0xF +trim_r4p38 0x0 0x2126 0xF 0xF +trim_r4p39 0x0 0x2127 0xF 0xF +trim_r4p40 0x0 0x2128 0xF 0xF +trim_r4p41 0x0 0x2129 0xF 0xF +trim_r4p42 0x0 0x212a 0xF 0xF +trim_r4p43 0x0 0x212b 0xF 0xF +trim_r4p44 0x0 0x212c 0xF 0xF +trim_r4p45 0x0 0x212d 0xF 0xF +trim_r4p46 0x0 0x212e 0xF 0xF +trim_r4p47 0x0 0x212f 0xF 0xF +trim_r4p48 0x0 0x2130 0xF 0xF +trim_r4p49 0x0 0x2131 0xF 0xF +trim_r4p50 0x0 0x2132 0xF 0xF +trim_r4p51 0x0 0x2133 0xF 0xF +trim_r4p52 0x0 0x2134 0xF 0xF +trim_r4p53 0x0 0x2135 0xF 0xF +trim_r4p54 0x0 0x2136 0xF 0xF +trim_r4p55 0x0 0x2137 0xF 0xF +trim_r4p56 0x0 0x2138 0xF 0xF +trim_r4p57 0x0 0x2139 0xF 0xF +trim_r4p58 0x0 0x213a 0xF 0xF +trim_r4p59 0x0 0x213b 0xF 0xF +trim_r4p60 0x0 0x213c 0xF 0xF +trim_r4p61 0x0 0x213d 0xF 0xF +trim_r4p62 0x0 0x213e 0xF 0xF +trim_r4p63 0x0 0x213f 0xF 0xF +trim_r4p64 0x0 0x2140 0xF 0xF +trim_r4p65 0x0 0x2141 0xF 0xF +trim_r4p66 0x0 0x2142 0xF 0xF +trim_r4p67 0x0 0x2143 0xF 0xF +trim_r4p68 0x0 0x2144 0xF 0xF +trim_r4p69 0x0 0x2145 0xF 0xF +trim_r4p70 0x0 0x2146 0xF 0xF +trim_r4p71 0x0 0x2147 0xF 0xF +trim_r4p72 0x0 0x2148 0xF 0xF +trim_r4p73 0x0 0x2149 0xF 0xF +trim_r4p74 0x0 0x214a 0xF 0xF +trim_r4p75 0x0 0x214b 0xF 0xF +trim_r4p76 0x0 0x214c 0xF 0xF +trim_r4p77 0x0 0x214d 0xF 0xF +trim_r4p78 0x0 0x214e 0xF 0xF +trim_r4p79 0x0 0x214f 0xF 0xF +trim_r4p80 0x0 0x2150 0xF 0xF +trim_r4p81 0x0 0x2151 0xF 0xF +trim_r4p82 0x0 0x2152 0xF 0xF +trim_r4p83 0x0 0x2153 0xF 0xF +trim_r4p84 0x0 0x2154 0xF 0xF +trim_r4p85 0x0 0x2155 0xF 0xF +trim_r4p86 0x0 0x2156 0xF 0xF +trim_r4p87 0x0 0x2157 0xF 0xF +trim_r4p88 0x0 0x2158 0xF 0xF +trim_r4p89 0x0 0x2159 0xF 0xF +trim_r4p90 0x0 0x215a 0xF 0xF +trim_r4p91 0x0 0x215b 0xF 0xF +trim_r4p92 0x0 0x215c 0xF 0xF +trim_r4p93 0x0 0x215d 0xF 0xF +trim_r4p94 0x0 0x215e 0xF 0xF +trim_r4p95 0x0 0x215f 0xF 0xF +trim_r4p96 0x0 0x2160 0xF 0xF +trim_r4p97 0x0 0x2161 0xF 0xF +trim_r4p98 0x0 0x2162 0xF 0xF +trim_r4p99 0x0 0x2163 0xF 0xF +trim_r4p100 0x0 0x2164 0xF 0xF +trim_r4p101 0x0 0x2165 0xF 0xF +trim_r4p102 0x0 0x2166 0xF 0xF +trim_r4p103 0x0 0x2167 0xF 0xF +trim_r4p104 0x0 0x2168 0xF 0xF +trim_r4p105 0x0 0x2169 0xF 0xF +trim_r4p106 0x0 0x216a 0xF 0xF +trim_r4p107 0x0 0x216b 0xF 0xF +trim_r4p108 0x0 0x216c 0xF 0xF +trim_r4p109 0x0 0x216d 0xF 0xF +trim_r4p110 0x0 0x216e 0xF 0xF +trim_r4p111 0x0 0x216f 0xF 0xF +trim_r4p112 0x0 0x2170 0xF 0xF +trim_r4p113 0x0 0x2171 0xF 0xF +trim_r4p114 0x0 0x2172 0xF 0xF +trim_r4p115 0x0 0x2173 0xF 0xF +trim_r4p116 0x0 0x2174 0xF 0xF +trim_r4p117 0x0 0x2175 0xF 0xF +trim_r4p118 0x0 0x2176 0xF 0xF +trim_r4p119 0x0 0x2177 0xF 0xF +trim_r5p1 0x0 0x2901 0xF 0xF +trim_r5p2 0x0 0x2902 0xF 0xF +trim_r5p3 0x0 0x2903 0xF 0xF +trim_r5p4 0x0 0x2904 0xF 0xF +trim_r5p5 0x0 0x2905 0xF 0xF +trim_r5p6 0x0 0x2906 0xF 0xF +trim_r5p7 0x0 0x2907 0xF 0xF +trim_r5p8 0x0 0x2908 0xF 0xF +trim_r5p9 0x0 0x2909 0xF 0xF +trim_r5p10 0x0 0x290a 0xF 0xF +trim_r5p11 0x0 0x290b 0xF 0xF +trim_r5p12 0x0 0x290c 0xF 0xF +trim_r5p13 0x0 0x290d 0xF 0xF +trim_r5p14 0x0 0x290e 0xF 0xF +trim_r5p15 0x0 0x290f 0xF 0xF +trim_r5p16 0x0 0x2910 0xF 0xF +trim_r5p17 0x0 0x2911 0xF 0xF +trim_r5p18 0x0 0x2912 0xF 0xF +trim_r5p19 0x0 0x2913 0xF 0xF +trim_r5p20 0x0 0x2914 0xF 0xF +trim_r5p21 0x0 0x2915 0xF 0xF +trim_r5p22 0x0 0x2916 0xF 0xF +trim_r5p23 0x0 0x2917 0xF 0xF +trim_r5p24 0x0 0x2918 0xF 0xF +trim_r5p25 0x0 0x2919 0xF 0xF +trim_r5p26 0x0 0x291a 0xF 0xF +trim_r5p27 0x0 0x291b 0xF 0xF +trim_r5p28 0x0 0x291c 0xF 0xF +trim_r5p29 0x0 0x291d 0xF 0xF +trim_r5p30 0x0 0x291e 0xF 0xF +trim_r5p31 0x0 0x291f 0xF 0xF +trim_r5p32 0x0 0x2920 0xF 0xF +trim_r5p33 0x0 0x2921 0xF 0xF +trim_r5p34 0x0 0x2922 0xF 0xF +trim_r5p35 0x0 0x2923 0xF 0xF +trim_r5p36 0x0 0x2924 0xF 0xF +trim_r5p37 0x0 0x2925 0xF 0xF +trim_r5p38 0x0 0x2926 0xF 0xF +trim_r5p39 0x0 0x2927 0xF 0xF +trim_r5p40 0x0 0x2928 0xF 0xF +trim_r5p41 0x0 0x2929 0xF 0xF +trim_r5p42 0x0 0x292a 0xF 0xF +trim_r5p43 0x0 0x292b 0xF 0xF +trim_r5p44 0x0 0x292c 0xF 0xF +trim_r5p45 0x0 0x292d 0xF 0xF +trim_r5p46 0x0 0x292e 0xF 0xF +trim_r5p47 0x0 0x292f 0xF 0xF +trim_r5p48 0x0 0x2930 0xF 0xF +trim_r5p49 0x0 0x2931 0xF 0xF +trim_r5p50 0x0 0x2932 0xF 0xF +trim_r5p51 0x0 0x2933 0xF 0xF +trim_r5p52 0x0 0x2934 0xF 0xF +trim_r5p53 0x0 0x2935 0xF 0xF +trim_r5p54 0x0 0x2936 0xF 0xF +trim_r5p55 0x0 0x2937 0xF 0xF +trim_r5p56 0x0 0x2938 0xF 0xF +trim_r5p57 0x0 0x2939 0xF 0xF +trim_r5p58 0x0 0x293a 0xF 0xF +trim_r5p59 0x0 0x293b 0xF 0xF +trim_r5p60 0x0 0x293c 0xF 0xF +trim_r5p61 0x0 0x293d 0xF 0xF +trim_r5p62 0x0 0x293e 0xF 0xF +trim_r5p63 0x0 0x293f 0xF 0xF +trim_r5p64 0x0 0x2940 0xF 0xF +trim_r5p65 0x0 0x2941 0xF 0xF +trim_r5p66 0x0 0x2942 0xF 0xF +trim_r5p67 0x0 0x2943 0xF 0xF +trim_r5p68 0x0 0x2944 0xF 0xF +trim_r5p69 0x0 0x2945 0xF 0xF +trim_r5p70 0x0 0x2946 0xF 0xF +trim_r5p71 0x0 0x2947 0xF 0xF +trim_r5p72 0x0 0x2948 0xF 0xF +trim_r5p73 0x0 0x2949 0xF 0xF +trim_r5p74 0x0 0x294a 0xF 0xF +trim_r5p75 0x0 0x294b 0xF 0xF +trim_r5p76 0x0 0x294c 0xF 0xF +trim_r5p77 0x0 0x294d 0xF 0xF +trim_r5p78 0x0 0x294e 0xF 0xF +trim_r5p79 0x0 0x294f 0xF 0xF +trim_r5p80 0x0 0x2950 0xF 0xF +trim_r5p81 0x0 0x2951 0xF 0xF +trim_r5p82 0x0 0x2952 0xF 0xF +trim_r5p83 0x0 0x2953 0xF 0xF +trim_r5p84 0x0 0x2954 0xF 0xF +trim_r5p85 0x0 0x2955 0xF 0xF +trim_r5p86 0x0 0x2956 0xF 0xF +trim_r5p87 0x0 0x2957 0xF 0xF +trim_r5p88 0x0 0x2958 0xF 0xF +trim_r5p89 0x0 0x2959 0xF 0xF +trim_r5p90 0x0 0x295a 0xF 0xF +trim_r5p91 0x0 0x295b 0xF 0xF +trim_r5p92 0x0 0x295c 0xF 0xF +trim_r5p93 0x0 0x295d 0xF 0xF +trim_r5p94 0x0 0x295e 0xF 0xF +trim_r5p95 0x0 0x295f 0xF 0xF +trim_r5p96 0x0 0x2960 0xF 0xF +trim_r5p97 0x0 0x2961 0xF 0xF +trim_r5p98 0x0 0x2962 0xF 0xF +trim_r5p99 0x0 0x2963 0xF 0xF +trim_r5p100 0x0 0x2964 0xF 0xF +trim_r5p101 0x0 0x2965 0xF 0xF +trim_r5p102 0x0 0x2966 0xF 0xF +trim_r5p103 0x0 0x2967 0xF 0xF +trim_r5p104 0x0 0x2968 0xF 0xF +trim_r5p105 0x0 0x2969 0xF 0xF +trim_r5p106 0x0 0x296a 0xF 0xF +trim_r5p107 0x0 0x296b 0xF 0xF +trim_r5p108 0x0 0x296c 0xF 0xF +trim_r5p109 0x0 0x296d 0xF 0xF +trim_r5p110 0x0 0x296e 0xF 0xF +trim_r5p111 0x0 0x296f 0xF 0xF +trim_r5p112 0x0 0x2970 0xF 0xF +trim_r5p113 0x0 0x2971 0xF 0xF +trim_r5p114 0x0 0x2972 0xF 0xF +trim_r5p115 0x0 0x2973 0xF 0xF +trim_r5p116 0x0 0x2974 0xF 0xF +trim_r5p117 0x0 0x2975 0xF 0xF +trim_r5p118 0x0 0x2976 0xF 0xF +trim_r5p119 0x0 0x2977 0xF 0xF +trim_r6p1 0x0 0x3101 0xF 0xF +trim_r6p2 0x0 0x3102 0xF 0xF +trim_r6p3 0x0 0x3103 0xF 0xF +trim_r6p4 0x0 0x3104 0xF 0xF +trim_r6p5 0x0 0x3105 0xF 0xF +trim_r6p6 0x0 0x3106 0xF 0xF +trim_r6p7 0x0 0x3107 0xF 0xF +trim_r6p8 0x0 0x3108 0xF 0xF +trim_r6p9 0x0 0x3109 0xF 0xF +trim_r6p10 0x0 0x310a 0xF 0xF +trim_r6p11 0x0 0x310b 0xF 0xF +trim_r6p12 0x0 0x310c 0xF 0xF +trim_r6p13 0x0 0x310d 0xF 0xF +trim_r6p14 0x0 0x310e 0xF 0xF +trim_r6p15 0x0 0x310f 0xF 0xF +trim_r6p16 0x0 0x3110 0xF 0xF +trim_r6p17 0x0 0x3111 0xF 0xF +trim_r6p18 0x0 0x3112 0xF 0xF +trim_r6p19 0x0 0x3113 0xF 0xF +trim_r6p20 0x0 0x3114 0xF 0xF +trim_r6p21 0x0 0x3115 0xF 0xF +trim_r6p22 0x0 0x3116 0xF 0xF +trim_r6p23 0x0 0x3117 0xF 0xF +trim_r6p24 0x0 0x3118 0xF 0xF +trim_r6p25 0x0 0x3119 0xF 0xF +trim_r6p26 0x0 0x311a 0xF 0xF +trim_r6p27 0x0 0x311b 0xF 0xF +trim_r6p28 0x0 0x311c 0xF 0xF +trim_r6p29 0x0 0x311d 0xF 0xF +trim_r6p30 0x0 0x311e 0xF 0xF +trim_r6p31 0x0 0x311f 0xF 0xF +trim_r6p32 0x0 0x3120 0xF 0xF +trim_r6p33 0x0 0x3121 0xF 0xF +trim_r6p34 0x0 0x3122 0xF 0xF +trim_r6p35 0x0 0x3123 0xF 0xF +trim_r6p36 0x0 0x3124 0xF 0xF +trim_r6p37 0x0 0x3125 0xF 0xF +trim_r6p38 0x0 0x3126 0xF 0xF +trim_r6p39 0x0 0x3127 0xF 0xF +trim_r6p40 0x0 0x3128 0xF 0xF +trim_r6p41 0x0 0x3129 0xF 0xF +trim_r6p42 0x0 0x312a 0xF 0xF +trim_r6p43 0x0 0x312b 0xF 0xF +trim_r6p44 0x0 0x312c 0xF 0xF +trim_r6p45 0x0 0x312d 0xF 0xF +trim_r6p46 0x0 0x312e 0xF 0xF +trim_r6p47 0x0 0x312f 0xF 0xF +trim_r6p48 0x0 0x3130 0xF 0xF +trim_r6p49 0x0 0x3131 0xF 0xF +trim_r6p50 0x0 0x3132 0xF 0xF +trim_r6p51 0x0 0x3133 0xF 0xF +trim_r6p52 0x0 0x3134 0xF 0xF +trim_r6p53 0x0 0x3135 0xF 0xF +trim_r6p54 0x0 0x3136 0xF 0xF +trim_r6p55 0x0 0x3137 0xF 0xF +trim_r6p56 0x0 0x3138 0xF 0xF +trim_r6p57 0x0 0x3139 0xF 0xF +trim_r6p58 0x0 0x313a 0xF 0xF +trim_r6p59 0x0 0x313b 0xF 0xF +trim_r6p60 0x0 0x313c 0xF 0xF +trim_r6p61 0x0 0x313d 0xF 0xF +trim_r6p62 0x0 0x313e 0xF 0xF +trim_r6p63 0x0 0x313f 0xF 0xF +trim_r6p64 0x0 0x3140 0xF 0xF +trim_r6p65 0x0 0x3141 0xF 0xF +trim_r6p66 0x0 0x3142 0xF 0xF +trim_r6p67 0x0 0x3143 0xF 0xF +trim_r6p68 0x0 0x3144 0xF 0xF +trim_r6p69 0x0 0x3145 0xF 0xF +trim_r6p70 0x0 0x3146 0xF 0xF +trim_r6p71 0x0 0x3147 0xF 0xF +trim_r6p72 0x0 0x3148 0xF 0xF +trim_r6p73 0x0 0x3149 0xF 0xF +trim_r6p74 0x0 0x314a 0xF 0xF +trim_r6p75 0x0 0x314b 0xF 0xF +trim_r6p76 0x0 0x314c 0xF 0xF +trim_r6p77 0x0 0x314d 0xF 0xF +trim_r6p78 0x0 0x314e 0xF 0xF +trim_r6p79 0x0 0x314f 0xF 0xF +trim_r6p80 0x0 0x3150 0xF 0xF +trim_r6p81 0x0 0x3151 0xF 0xF +trim_r6p82 0x0 0x3152 0xF 0xF +trim_r6p83 0x0 0x3153 0xF 0xF +trim_r6p84 0x0 0x3154 0xF 0xF +trim_r6p85 0x0 0x3155 0xF 0xF +trim_r6p86 0x0 0x3156 0xF 0xF +trim_r6p87 0x0 0x3157 0xF 0xF +trim_r6p88 0x0 0x3158 0xF 0xF +trim_r6p89 0x0 0x3159 0xF 0xF +trim_r6p90 0x0 0x315a 0xF 0xF +trim_r6p91 0x0 0x315b 0xF 0xF +trim_r6p92 0x0 0x315c 0xF 0xF +trim_r6p93 0x0 0x315d 0xF 0xF +trim_r6p94 0x0 0x315e 0xF 0xF +trim_r6p95 0x0 0x315f 0xF 0xF +trim_r6p96 0x0 0x3160 0xF 0xF +trim_r6p97 0x0 0x3161 0xF 0xF +trim_r6p98 0x0 0x3162 0xF 0xF +trim_r6p99 0x0 0x3163 0xF 0xF +trim_r6p100 0x0 0x3164 0xF 0xF +trim_r6p101 0x0 0x3165 0xF 0xF +trim_r6p102 0x0 0x3166 0xF 0xF +trim_r6p103 0x0 0x3167 0xF 0xF +trim_r6p104 0x0 0x3168 0xF 0xF +trim_r6p105 0x0 0x3169 0xF 0xF +trim_r6p106 0x0 0x316a 0xF 0xF +trim_r6p107 0x0 0x316b 0xF 0xF +trim_r6p108 0x0 0x316c 0xF 0xF +trim_r6p109 0x0 0x316d 0xF 0xF +trim_r6p110 0x0 0x316e 0xF 0xF +trim_r6p111 0x0 0x316f 0xF 0xF +trim_r6p112 0x0 0x3170 0xF 0xF +trim_r6p113 0x0 0x3171 0xF 0xF +trim_r6p114 0x0 0x3172 0xF 0xF +trim_r6p115 0x0 0x3173 0xF 0xF +trim_r6p116 0x0 0x3174 0xF 0xF +trim_r6p117 0x0 0x3175 0xF 0xF +trim_r6p118 0x0 0x3176 0xF 0xF +trim_r6p119 0x0 0x3177 0xF 0xF +trim_r7p1 0x0 0x3901 0xF 0xF +trim_r7p2 0x0 0x3902 0xF 0xF +trim_r7p3 0x0 0x3903 0xF 0xF +trim_r7p4 0x0 0x3904 0xF 0xF +trim_r7p5 0x0 0x3905 0xF 0xF +trim_r7p6 0x0 0x3906 0xF 0xF +trim_r7p7 0x0 0x3907 0xF 0xF +trim_r7p8 0x0 0x3908 0xF 0xF +trim_r7p9 0x0 0x3909 0xF 0xF +trim_r7p10 0x0 0x390a 0xF 0xF +trim_r7p11 0x0 0x390b 0xF 0xF +trim_r7p12 0x0 0x390c 0xF 0xF +trim_r7p13 0x0 0x390d 0xF 0xF +trim_r7p14 0x0 0x390e 0xF 0xF +trim_r7p15 0x0 0x390f 0xF 0xF +trim_r7p16 0x0 0x3910 0xF 0xF +trim_r7p17 0x0 0x3911 0xF 0xF +trim_r7p18 0x0 0x3912 0xF 0xF +trim_r7p19 0x0 0x3913 0xF 0xF +trim_r7p20 0x0 0x3914 0xF 0xF +trim_r7p21 0x0 0x3915 0xF 0xF +trim_r7p22 0x0 0x3916 0xF 0xF +trim_r7p23 0x0 0x3917 0xF 0xF +trim_r7p24 0x0 0x3918 0xF 0xF +trim_r7p25 0x0 0x3919 0xF 0xF +trim_r7p26 0x0 0x391a 0xF 0xF +trim_r7p27 0x0 0x391b 0xF 0xF +trim_r7p28 0x0 0x391c 0xF 0xF +trim_r7p29 0x0 0x391d 0xF 0xF +trim_r7p30 0x0 0x391e 0xF 0xF +trim_r7p31 0x0 0x391f 0xF 0xF +trim_r7p32 0x0 0x3920 0xF 0xF +trim_r7p33 0x0 0x3921 0xF 0xF +trim_r7p34 0x0 0x3922 0xF 0xF +trim_r7p35 0x0 0x3923 0xF 0xF +trim_r7p36 0x0 0x3924 0xF 0xF +trim_r7p37 0x0 0x3925 0xF 0xF +trim_r7p38 0x0 0x3926 0xF 0xF +trim_r7p39 0x0 0x3927 0xF 0xF +trim_r7p40 0x0 0x3928 0xF 0xF +trim_r7p41 0x0 0x3929 0xF 0xF +trim_r7p42 0x0 0x392a 0xF 0xF +trim_r7p43 0x0 0x392b 0xF 0xF +trim_r7p44 0x0 0x392c 0xF 0xF +trim_r7p45 0x0 0x392d 0xF 0xF +trim_r7p46 0x0 0x392e 0xF 0xF +trim_r7p47 0x0 0x392f 0xF 0xF +trim_r7p48 0x0 0x3930 0xF 0xF +trim_r7p49 0x0 0x3931 0xF 0xF +trim_r7p50 0x0 0x3932 0xF 0xF +trim_r7p51 0x0 0x3933 0xF 0xF +trim_r7p52 0x0 0x3934 0xF 0xF +trim_r7p53 0x0 0x3935 0xF 0xF +trim_r7p54 0x0 0x3936 0xF 0xF +trim_r7p55 0x0 0x3937 0xF 0xF +trim_r7p56 0x0 0x3938 0xF 0xF +trim_r7p57 0x0 0x3939 0xF 0xF +trim_r7p58 0x0 0x393a 0xF 0xF +trim_r7p59 0x0 0x393b 0xF 0xF +trim_r7p60 0x0 0x393c 0xF 0xF +trim_r7p61 0x0 0x393d 0xF 0xF +trim_r7p62 0x0 0x393e 0xF 0xF +trim_r7p63 0x0 0x393f 0xF 0xF +trim_r7p64 0x0 0x3940 0xF 0xF +trim_r7p65 0x0 0x3941 0xF 0xF +trim_r7p66 0x0 0x3942 0xF 0xF +trim_r7p67 0x0 0x3943 0xF 0xF +trim_r7p68 0x0 0x3944 0xF 0xF +trim_r7p69 0x0 0x3945 0xF 0xF +trim_r7p70 0x0 0x3946 0xF 0xF +trim_r7p71 0x0 0x3947 0xF 0xF +trim_r7p72 0x0 0x3948 0xF 0xF +trim_r7p73 0x0 0x3949 0xF 0xF +trim_r7p74 0x0 0x394a 0xF 0xF +trim_r7p75 0x0 0x394b 0xF 0xF +trim_r7p76 0x0 0x394c 0xF 0xF +trim_r7p77 0x0 0x394d 0xF 0xF +trim_r7p78 0x0 0x394e 0xF 0xF +trim_r7p79 0x0 0x394f 0xF 0xF +trim_r7p80 0x0 0x3950 0xF 0xF +trim_r7p81 0x0 0x3951 0xF 0xF +trim_r7p82 0x0 0x3952 0xF 0xF +trim_r7p83 0x0 0x3953 0xF 0xF +trim_r7p84 0x0 0x3954 0xF 0xF +trim_r7p85 0x0 0x3955 0xF 0xF +trim_r7p86 0x0 0x3956 0xF 0xF +trim_r7p87 0x0 0x3957 0xF 0xF +trim_r7p88 0x0 0x3958 0xF 0xF +trim_r7p89 0x0 0x3959 0xF 0xF +trim_r7p90 0x0 0x395a 0xF 0xF +trim_r7p91 0x0 0x395b 0xF 0xF +trim_r7p92 0x0 0x395c 0xF 0xF +trim_r7p93 0x0 0x395d 0xF 0xF +trim_r7p94 0x0 0x395e 0xF 0xF +trim_r7p95 0x0 0x395f 0xF 0xF +trim_r7p96 0x0 0x3960 0xF 0xF +trim_r7p97 0x0 0x3961 0xF 0xF +trim_r7p98 0x0 0x3962 0xF 0xF +trim_r7p99 0x0 0x3963 0xF 0xF +trim_r7p100 0x0 0x3964 0xF 0xF +trim_r7p101 0x0 0x3965 0xF 0xF +trim_r7p102 0x0 0x3966 0xF 0xF +trim_r7p103 0x0 0x3967 0xF 0xF +trim_r7p104 0x0 0x3968 0xF 0xF +trim_r7p105 0x0 0x3969 0xF 0xF +trim_r7p106 0x0 0x396a 0xF 0xF +trim_r7p107 0x0 0x396b 0xF 0xF +trim_r7p108 0x0 0x396c 0xF 0xF +trim_r7p109 0x0 0x396d 0xF 0xF +trim_r7p110 0x0 0x396e 0xF 0xF +trim_r7p111 0x0 0x396f 0xF 0xF +trim_r7p112 0x0 0x3970 0xF 0xF +trim_r7p113 0x0 0x3971 0xF 0xF +trim_r7p114 0x0 0x3972 0xF 0xF +trim_r7p115 0x0 0x3973 0xF 0xF +trim_r7p116 0x0 0x3974 0xF 0xF +trim_r7p117 0x0 0x3975 0xF 0xF +trim_r7p118 0x0 0x3976 0xF 0xF +trim_r7p119 0x0 0x3977 0xF 0xF +trim_r8p1 0x0 0x4101 0xF 0xF +trim_r8p2 0x0 0x4102 0xF 0xF +trim_r8p3 0x0 0x4103 0xF 0xF +trim_r8p4 0x0 0x4104 0xF 0xF +trim_r8p5 0x0 0x4105 0xF 0xF +trim_r8p6 0x0 0x4106 0xF 0xF +trim_r8p7 0x0 0x4107 0xF 0xF +trim_r8p8 0x0 0x4108 0xF 0xF +trim_r8p9 0x0 0x4109 0xF 0xF +trim_r8p10 0x0 0x410a 0xF 0xF +trim_r8p11 0x0 0x410b 0xF 0xF +trim_r8p12 0x0 0x410c 0xF 0xF +trim_r8p13 0x0 0x410d 0xF 0xF +trim_r8p14 0x0 0x410e 0xF 0xF +trim_r8p15 0x0 0x410f 0xF 0xF +trim_r8p16 0x0 0x4110 0xF 0xF +trim_r8p17 0x0 0x4111 0xF 0xF +trim_r8p18 0x0 0x4112 0xF 0xF +trim_r8p19 0x0 0x4113 0xF 0xF +trim_r8p20 0x0 0x4114 0xF 0xF +trim_r8p21 0x0 0x4115 0xF 0xF +trim_r8p22 0x0 0x4116 0xF 0xF +trim_r8p23 0x0 0x4117 0xF 0xF +trim_r8p24 0x0 0x4118 0xF 0xF +trim_r8p25 0x0 0x4119 0xF 0xF +trim_r8p26 0x0 0x411a 0xF 0xF +trim_r8p27 0x0 0x411b 0xF 0xF +trim_r8p28 0x0 0x411c 0xF 0xF +trim_r8p29 0x0 0x411d 0xF 0xF +trim_r8p30 0x0 0x411e 0xF 0xF +trim_r8p31 0x0 0x411f 0xF 0xF +trim_r8p32 0x0 0x4120 0xF 0xF +trim_r8p33 0x0 0x4121 0xF 0xF +trim_r8p34 0x0 0x4122 0xF 0xF +trim_r8p35 0x0 0x4123 0xF 0xF +trim_r8p36 0x0 0x4124 0xF 0xF +trim_r8p37 0x0 0x4125 0xF 0xF +trim_r8p38 0x0 0x4126 0xF 0xF +trim_r8p39 0x0 0x4127 0xF 0xF +trim_r8p40 0x0 0x4128 0xF 0xF +trim_r8p41 0x0 0x4129 0xF 0xF +trim_r8p42 0x0 0x412a 0xF 0xF +trim_r8p43 0x0 0x412b 0xF 0xF +trim_r8p44 0x0 0x412c 0xF 0xF +trim_r8p45 0x0 0x412d 0xF 0xF +trim_r8p46 0x0 0x412e 0xF 0xF +trim_r8p47 0x0 0x412f 0xF 0xF +trim_r8p48 0x0 0x4130 0xF 0xF +trim_r8p49 0x0 0x4131 0xF 0xF +trim_r8p50 0x0 0x4132 0xF 0xF +trim_r8p51 0x0 0x4133 0xF 0xF +trim_r8p52 0x0 0x4134 0xF 0xF +trim_r8p53 0x0 0x4135 0xF 0xF +trim_r8p54 0x0 0x4136 0xF 0xF +trim_r8p55 0x0 0x4137 0xF 0xF +trim_r8p56 0x0 0x4138 0xF 0xF +trim_r8p57 0x0 0x4139 0xF 0xF +trim_r8p58 0x0 0x413a 0xF 0xF +trim_r8p59 0x0 0x413b 0xF 0xF +trim_r8p60 0x0 0x413c 0xF 0xF +trim_r8p61 0x0 0x413d 0xF 0xF +trim_r8p62 0x0 0x413e 0xF 0xF +trim_r8p63 0x0 0x413f 0xF 0xF +trim_r8p64 0x0 0x4140 0xF 0xF +trim_r8p65 0x0 0x4141 0xF 0xF +trim_r8p66 0x0 0x4142 0xF 0xF +trim_r8p67 0x0 0x4143 0xF 0xF +trim_r8p68 0x0 0x4144 0xF 0xF +trim_r8p69 0x0 0x4145 0xF 0xF +trim_r8p70 0x0 0x4146 0xF 0xF +trim_r8p71 0x0 0x4147 0xF 0xF +trim_r8p72 0x0 0x4148 0xF 0xF +trim_r8p73 0x0 0x4149 0xF 0xF +trim_r8p74 0x0 0x414a 0xF 0xF +trim_r8p75 0x0 0x414b 0xF 0xF +trim_r8p76 0x0 0x414c 0xF 0xF +trim_r8p77 0x0 0x414d 0xF 0xF +trim_r8p78 0x0 0x414e 0xF 0xF +trim_r8p79 0x0 0x414f 0xF 0xF +trim_r8p80 0x0 0x4150 0xF 0xF +trim_r8p81 0x0 0x4151 0xF 0xF +trim_r8p82 0x0 0x4152 0xF 0xF +trim_r8p83 0x0 0x4153 0xF 0xF +trim_r8p84 0x0 0x4154 0xF 0xF +trim_r8p85 0x0 0x4155 0xF 0xF +trim_r8p86 0x0 0x4156 0xF 0xF +trim_r8p87 0x0 0x4157 0xF 0xF +trim_r8p88 0x0 0x4158 0xF 0xF +trim_r8p89 0x0 0x4159 0xF 0xF +trim_r8p90 0x0 0x415a 0xF 0xF +trim_r8p91 0x0 0x415b 0xF 0xF +trim_r8p92 0x0 0x415c 0xF 0xF +trim_r8p93 0x0 0x415d 0xF 0xF +trim_r8p94 0x0 0x415e 0xF 0xF +trim_r8p95 0x0 0x415f 0xF 0xF +trim_r8p96 0x0 0x4160 0xF 0xF +trim_r8p97 0x0 0x4161 0xF 0xF +trim_r8p98 0x0 0x4162 0xF 0xF +trim_r8p99 0x0 0x4163 0xF 0xF +trim_r8p100 0x0 0x4164 0xF 0xF +trim_r8p101 0x0 0x4165 0xF 0xF +trim_r8p102 0x0 0x4166 0xF 0xF +trim_r8p103 0x0 0x4167 0xF 0xF +trim_r8p104 0x0 0x4168 0xF 0xF +trim_r8p105 0x0 0x4169 0xF 0xF +trim_r8p106 0x0 0x416a 0xF 0xF +trim_r8p107 0x0 0x416b 0xF 0xF +trim_r8p108 0x0 0x416c 0xF 0xF +trim_r8p109 0x0 0x416d 0xF 0xF +trim_r8p110 0x0 0x416e 0xF 0xF +trim_r8p111 0x0 0x416f 0xF 0xF +trim_r8p112 0x0 0x4170 0xF 0xF +trim_r8p113 0x0 0x4171 0xF 0xF +trim_r8p114 0x0 0x4172 0xF 0xF +trim_r8p115 0x0 0x4173 0xF 0xF +trim_r8p116 0x0 0x4174 0xF 0xF +trim_r8p117 0x0 0x4175 0xF 0xF +trim_r8p118 0x0 0x4176 0xF 0xF +trim_r8p119 0x0 0x4177 0xF 0xF +trim_r9p1 0x0 0x4901 0xF 0xF +trim_r9p2 0x0 0x4902 0xF 0xF +trim_r9p3 0x0 0x4903 0xF 0xF +trim_r9p4 0x0 0x4904 0xF 0xF +trim_r9p5 0x0 0x4905 0xF 0xF +trim_r9p6 0x0 0x4906 0xF 0xF +trim_r9p7 0x0 0x4907 0xF 0xF +trim_r9p8 0x0 0x4908 0xF 0xF +trim_r9p9 0x0 0x4909 0xF 0xF +trim_r9p10 0x0 0x490a 0xF 0xF +trim_r9p11 0x0 0x490b 0xF 0xF +trim_r9p12 0x0 0x490c 0xF 0xF +trim_r9p13 0x0 0x490d 0xF 0xF +trim_r9p14 0x0 0x490e 0xF 0xF +trim_r9p15 0x0 0x490f 0xF 0xF +trim_r9p16 0x0 0x4910 0xF 0xF +trim_r9p17 0x0 0x4911 0xF 0xF +trim_r9p18 0x0 0x4912 0xF 0xF +trim_r9p19 0x0 0x4913 0xF 0xF +trim_r9p20 0x0 0x4914 0xF 0xF +trim_r9p21 0x0 0x4915 0xF 0xF +trim_r9p22 0x0 0x4916 0xF 0xF +trim_r9p23 0x0 0x4917 0xF 0xF +trim_r9p24 0x0 0x4918 0xF 0xF +trim_r9p25 0x0 0x4919 0xF 0xF +trim_r9p26 0x0 0x491a 0xF 0xF +trim_r9p27 0x0 0x491b 0xF 0xF +trim_r9p28 0x0 0x491c 0xF 0xF +trim_r9p29 0x0 0x491d 0xF 0xF +trim_r9p30 0x0 0x491e 0xF 0xF +trim_r9p31 0x0 0x491f 0xF 0xF +trim_r9p32 0x0 0x4920 0xF 0xF +trim_r9p33 0x0 0x4921 0xF 0xF +trim_r9p34 0x0 0x4922 0xF 0xF +trim_r9p35 0x0 0x4923 0xF 0xF +trim_r9p36 0x0 0x4924 0xF 0xF +trim_r9p37 0x0 0x4925 0xF 0xF +trim_r9p38 0x0 0x4926 0xF 0xF +trim_r9p39 0x0 0x4927 0xF 0xF +trim_r9p40 0x0 0x4928 0xF 0xF +trim_r9p41 0x0 0x4929 0xF 0xF +trim_r9p42 0x0 0x492a 0xF 0xF +trim_r9p43 0x0 0x492b 0xF 0xF +trim_r9p44 0x0 0x492c 0xF 0xF +trim_r9p45 0x0 0x492d 0xF 0xF +trim_r9p46 0x0 0x492e 0xF 0xF +trim_r9p47 0x0 0x492f 0xF 0xF +trim_r9p48 0x0 0x4930 0xF 0xF +trim_r9p49 0x0 0x4931 0xF 0xF +trim_r9p50 0x0 0x4932 0xF 0xF +trim_r9p51 0x0 0x4933 0xF 0xF +trim_r9p52 0x0 0x4934 0xF 0xF +trim_r9p53 0x0 0x4935 0xF 0xF +trim_r9p54 0x0 0x4936 0xF 0xF +trim_r9p55 0x0 0x4937 0xF 0xF +trim_r9p56 0x0 0x4938 0xF 0xF +trim_r9p57 0x0 0x4939 0xF 0xF +trim_r9p58 0x0 0x493a 0xF 0xF +trim_r9p59 0x0 0x493b 0xF 0xF +trim_r9p60 0x0 0x493c 0xF 0xF +trim_r9p61 0x0 0x493d 0xF 0xF +trim_r9p62 0x0 0x493e 0xF 0xF +trim_r9p63 0x0 0x493f 0xF 0xF +trim_r9p64 0x0 0x4940 0xF 0xF +trim_r9p65 0x0 0x4941 0xF 0xF +trim_r9p66 0x0 0x4942 0xF 0xF +trim_r9p67 0x0 0x4943 0xF 0xF +trim_r9p68 0x0 0x4944 0xF 0xF +trim_r9p69 0x0 0x4945 0xF 0xF +trim_r9p70 0x0 0x4946 0xF 0xF +trim_r9p71 0x0 0x4947 0xF 0xF +trim_r9p72 0x0 0x4948 0xF 0xF +trim_r9p73 0x0 0x4949 0xF 0xF +trim_r9p74 0x0 0x494a 0xF 0xF +trim_r9p75 0x0 0x494b 0xF 0xF +trim_r9p76 0x0 0x494c 0xF 0xF +trim_r9p77 0x0 0x494d 0xF 0xF +trim_r9p78 0x0 0x494e 0xF 0xF +trim_r9p79 0x0 0x494f 0xF 0xF +trim_r9p80 0x0 0x4950 0xF 0xF +trim_r9p81 0x0 0x4951 0xF 0xF +trim_r9p82 0x0 0x4952 0xF 0xF +trim_r9p83 0x0 0x4953 0xF 0xF +trim_r9p84 0x0 0x4954 0xF 0xF +trim_r9p85 0x0 0x4955 0xF 0xF +trim_r9p86 0x0 0x4956 0xF 0xF +trim_r9p87 0x0 0x4957 0xF 0xF +trim_r9p88 0x0 0x4958 0xF 0xF +trim_r9p89 0x0 0x4959 0xF 0xF +trim_r9p90 0x0 0x495a 0xF 0xF +trim_r9p91 0x0 0x495b 0xF 0xF +trim_r9p92 0x0 0x495c 0xF 0xF +trim_r9p93 0x0 0x495d 0xF 0xF +trim_r9p94 0x0 0x495e 0xF 0xF +trim_r9p95 0x0 0x495f 0xF 0xF +trim_r9p96 0x0 0x4960 0xF 0xF +trim_r9p97 0x0 0x4961 0xF 0xF +trim_r9p98 0x0 0x4962 0xF 0xF +trim_r9p99 0x0 0x4963 0xF 0xF +trim_r9p100 0x0 0x4964 0xF 0xF +trim_r9p101 0x0 0x4965 0xF 0xF +trim_r9p102 0x0 0x4966 0xF 0xF +trim_r9p103 0x0 0x4967 0xF 0xF +trim_r9p104 0x0 0x4968 0xF 0xF +trim_r9p105 0x0 0x4969 0xF 0xF +trim_r9p106 0x0 0x496a 0xF 0xF +trim_r9p107 0x0 0x496b 0xF 0xF +trim_r9p108 0x0 0x496c 0xF 0xF +trim_r9p109 0x0 0x496d 0xF 0xF +trim_r9p110 0x0 0x496e 0xF 0xF +trim_r9p111 0x0 0x496f 0xF 0xF +trim_r9p112 0x0 0x4970 0xF 0xF +trim_r9p113 0x0 0x4971 0xF 0xF +trim_r9p114 0x0 0x4972 0xF 0xF +trim_r9p115 0x0 0x4973 0xF 0xF +trim_r9p116 0x0 0x4974 0xF 0xF +trim_r9p117 0x0 0x4975 0xF 0xF +trim_r9p118 0x0 0x4976 0xF 0xF +trim_r9p119 0x0 0x4977 0xF 0xF +trim_r10p1 0x0 0x5101 0xF 0xF +trim_r10p2 0x0 0x5102 0xF 0xF +trim_r10p3 0x0 0x5103 0xF 0xF +trim_r10p4 0x0 0x5104 0xF 0xF +trim_r10p5 0x0 0x5105 0xF 0xF +trim_r10p6 0x0 0x5106 0xF 0xF +trim_r10p7 0x0 0x5107 0xF 0xF +trim_r10p8 0x0 0x5108 0xF 0xF +trim_r10p9 0x0 0x5109 0xF 0xF +trim_r10p10 0x0 0x510a 0xF 0xF +trim_r10p11 0x0 0x510b 0xF 0xF +trim_r10p12 0x0 0x510c 0xF 0xF +trim_r10p13 0x0 0x510d 0xF 0xF +trim_r10p14 0x0 0x510e 0xF 0xF +trim_r10p15 0x0 0x510f 0xF 0xF +trim_r10p16 0x0 0x5110 0xF 0xF +trim_r10p17 0x0 0x5111 0xF 0xF +trim_r10p18 0x0 0x5112 0xF 0xF +trim_r10p19 0x0 0x5113 0xF 0xF +trim_r10p20 0x0 0x5114 0xF 0xF +trim_r10p21 0x0 0x5115 0xF 0xF +trim_r10p22 0x0 0x5116 0xF 0xF +trim_r10p23 0x0 0x5117 0xF 0xF +trim_r10p24 0x0 0x5118 0xF 0xF +trim_r10p25 0x0 0x5119 0xF 0xF +trim_r10p26 0x0 0x511a 0xF 0xF +trim_r10p27 0x0 0x511b 0xF 0xF +trim_r10p28 0x0 0x511c 0xF 0xF +trim_r10p29 0x0 0x511d 0xF 0xF +trim_r10p30 0x0 0x511e 0xF 0xF +trim_r10p31 0x0 0x511f 0xF 0xF +trim_r10p32 0x0 0x5120 0xF 0xF +trim_r10p33 0x0 0x5121 0xF 0xF +trim_r10p34 0x0 0x5122 0xF 0xF +trim_r10p35 0x0 0x5123 0xF 0xF +trim_r10p36 0x0 0x5124 0xF 0xF +trim_r10p37 0x0 0x5125 0xF 0xF +trim_r10p38 0x0 0x5126 0xF 0xF +trim_r10p39 0x0 0x5127 0xF 0xF +trim_r10p40 0x0 0x5128 0xF 0xF +trim_r10p41 0x0 0x5129 0xF 0xF +trim_r10p42 0x0 0x512a 0xF 0xF +trim_r10p43 0x0 0x512b 0xF 0xF +trim_r10p44 0x0 0x512c 0xF 0xF +trim_r10p45 0x0 0x512d 0xF 0xF +trim_r10p46 0x0 0x512e 0xF 0xF +trim_r10p47 0x0 0x512f 0xF 0xF +trim_r10p48 0x0 0x5130 0xF 0xF +trim_r10p49 0x0 0x5131 0xF 0xF +trim_r10p50 0x0 0x5132 0xF 0xF +trim_r10p51 0x0 0x5133 0xF 0xF +trim_r10p52 0x0 0x5134 0xF 0xF +trim_r10p53 0x0 0x5135 0xF 0xF +trim_r10p54 0x0 0x5136 0xF 0xF +trim_r10p55 0x0 0x5137 0xF 0xF +trim_r10p56 0x0 0x5138 0xF 0xF +trim_r10p57 0x0 0x5139 0xF 0xF +trim_r10p58 0x0 0x513a 0xF 0xF +trim_r10p59 0x0 0x513b 0xF 0xF +trim_r10p60 0x0 0x513c 0xF 0xF +trim_r10p61 0x0 0x513d 0xF 0xF +trim_r10p62 0x0 0x513e 0xF 0xF +trim_r10p63 0x0 0x513f 0xF 0xF +trim_r10p64 0x0 0x5140 0xF 0xF +trim_r10p65 0x0 0x5141 0xF 0xF +trim_r10p66 0x0 0x5142 0xF 0xF +trim_r10p67 0x0 0x5143 0xF 0xF +trim_r10p68 0x0 0x5144 0xF 0xF +trim_r10p69 0x0 0x5145 0xF 0xF +trim_r10p70 0x0 0x5146 0xF 0xF +trim_r10p71 0x0 0x5147 0xF 0xF +trim_r10p72 0x0 0x5148 0xF 0xF +trim_r10p73 0x0 0x5149 0xF 0xF +trim_r10p74 0x0 0x514a 0xF 0xF +trim_r10p75 0x0 0x514b 0xF 0xF +trim_r10p76 0x0 0x514c 0xF 0xF +trim_r10p77 0x0 0x514d 0xF 0xF +trim_r10p78 0x0 0x514e 0xF 0xF +trim_r10p79 0x0 0x514f 0xF 0xF +trim_r10p80 0x0 0x5150 0xF 0xF +trim_r10p81 0x0 0x5151 0xF 0xF +trim_r10p82 0x0 0x5152 0xF 0xF +trim_r10p83 0x0 0x5153 0xF 0xF +trim_r10p84 0x0 0x5154 0xF 0xF +trim_r10p85 0x0 0x5155 0xF 0xF +trim_r10p86 0x0 0x5156 0xF 0xF +trim_r10p87 0x0 0x5157 0xF 0xF +trim_r10p88 0x0 0x5158 0xF 0xF +trim_r10p89 0x0 0x5159 0xF 0xF +trim_r10p90 0x0 0x515a 0xF 0xF +trim_r10p91 0x0 0x515b 0xF 0xF +trim_r10p92 0x0 0x515c 0xF 0xF +trim_r10p93 0x0 0x515d 0xF 0xF +trim_r10p94 0x0 0x515e 0xF 0xF +trim_r10p95 0x0 0x515f 0xF 0xF +trim_r10p96 0x0 0x5160 0xF 0xF +trim_r10p97 0x0 0x5161 0xF 0xF +trim_r10p98 0x0 0x5162 0xF 0xF +trim_r10p99 0x0 0x5163 0xF 0xF +trim_r10p100 0x0 0x5164 0xF 0xF +trim_r10p101 0x0 0x5165 0xF 0xF +trim_r10p102 0x0 0x5166 0xF 0xF +trim_r10p103 0x0 0x5167 0xF 0xF +trim_r10p104 0x0 0x5168 0xF 0xF +trim_r10p105 0x0 0x5169 0xF 0xF +trim_r10p106 0x0 0x516a 0xF 0xF +trim_r10p107 0x0 0x516b 0xF 0xF +trim_r10p108 0x0 0x516c 0xF 0xF +trim_r10p109 0x0 0x516d 0xF 0xF +trim_r10p110 0x0 0x516e 0xF 0xF +trim_r10p111 0x0 0x516f 0xF 0xF +trim_r10p112 0x0 0x5170 0xF 0xF +trim_r10p113 0x0 0x5171 0xF 0xF +trim_r10p114 0x0 0x5172 0xF 0xF +trim_r10p115 0x0 0x5173 0xF 0xF +trim_r10p116 0x0 0x5174 0xF 0xF +trim_r10p117 0x0 0x5175 0xF 0xF +trim_r10p118 0x0 0x5176 0xF 0xF +trim_r10p119 0x0 0x5177 0xF 0xF +trim_r11p1 0x0 0x5901 0xF 0xF +trim_r11p2 0x0 0x5902 0xF 0xF +trim_r11p3 0x0 0x5903 0xF 0xF +trim_r11p4 0x0 0x5904 0xF 0xF +trim_r11p5 0x0 0x5905 0xF 0xF +trim_r11p6 0x0 0x5906 0xF 0xF +trim_r11p7 0x0 0x5907 0xF 0xF +trim_r11p8 0x0 0x5908 0xF 0xF +trim_r11p9 0x0 0x5909 0xF 0xF +trim_r11p10 0x0 0x590a 0xF 0xF +trim_r11p11 0x0 0x590b 0xF 0xF +trim_r11p12 0x0 0x590c 0xF 0xF +trim_r11p13 0x0 0x590d 0xF 0xF +trim_r11p14 0x0 0x590e 0xF 0xF +trim_r11p15 0x0 0x590f 0xF 0xF +trim_r11p16 0x0 0x5910 0xF 0xF +trim_r11p17 0x0 0x5911 0xF 0xF +trim_r11p18 0x0 0x5912 0xF 0xF +trim_r11p19 0x0 0x5913 0xF 0xF +trim_r11p20 0x0 0x5914 0xF 0xF +trim_r11p21 0x0 0x5915 0xF 0xF +trim_r11p22 0x0 0x5916 0xF 0xF +trim_r11p23 0x0 0x5917 0xF 0xF +trim_r11p24 0x0 0x5918 0xF 0xF +trim_r11p25 0x0 0x5919 0xF 0xF +trim_r11p26 0x0 0x591a 0xF 0xF +trim_r11p27 0x0 0x591b 0xF 0xF +trim_r11p28 0x0 0x591c 0xF 0xF +trim_r11p29 0x0 0x591d 0xF 0xF +trim_r11p30 0x0 0x591e 0xF 0xF +trim_r11p31 0x0 0x591f 0xF 0xF +trim_r11p32 0x0 0x5920 0xF 0xF +trim_r11p33 0x0 0x5921 0xF 0xF +trim_r11p34 0x0 0x5922 0xF 0xF +trim_r11p35 0x0 0x5923 0xF 0xF +trim_r11p36 0x0 0x5924 0xF 0xF +trim_r11p37 0x0 0x5925 0xF 0xF +trim_r11p38 0x0 0x5926 0xF 0xF +trim_r11p39 0x0 0x5927 0xF 0xF +trim_r11p40 0x0 0x5928 0xF 0xF +trim_r11p41 0x0 0x5929 0xF 0xF +trim_r11p42 0x0 0x592a 0xF 0xF +trim_r11p43 0x0 0x592b 0xF 0xF +trim_r11p44 0x0 0x592c 0xF 0xF +trim_r11p45 0x0 0x592d 0xF 0xF +trim_r11p46 0x0 0x592e 0xF 0xF +trim_r11p47 0x0 0x592f 0xF 0xF +trim_r11p48 0x0 0x5930 0xF 0xF +trim_r11p49 0x0 0x5931 0xF 0xF +trim_r11p50 0x0 0x5932 0xF 0xF +trim_r11p51 0x0 0x5933 0xF 0xF +trim_r11p52 0x0 0x5934 0xF 0xF +trim_r11p53 0x0 0x5935 0xF 0xF +trim_r11p54 0x0 0x5936 0xF 0xF +trim_r11p55 0x0 0x5937 0xF 0xF +trim_r11p56 0x0 0x5938 0xF 0xF +trim_r11p57 0x0 0x5939 0xF 0xF +trim_r11p58 0x0 0x593a 0xF 0xF +trim_r11p59 0x0 0x593b 0xF 0xF +trim_r11p60 0x0 0x593c 0xF 0xF +trim_r11p61 0x0 0x593d 0xF 0xF +trim_r11p62 0x0 0x593e 0xF 0xF +trim_r11p63 0x0 0x593f 0xF 0xF +trim_r11p64 0x0 0x5940 0xF 0xF +trim_r11p65 0x0 0x5941 0xF 0xF +trim_r11p66 0x0 0x5942 0xF 0xF +trim_r11p67 0x0 0x5943 0xF 0xF +trim_r11p68 0x0 0x5944 0xF 0xF +trim_r11p69 0x0 0x5945 0xF 0xF +trim_r11p70 0x0 0x5946 0xF 0xF +trim_r11p71 0x0 0x5947 0xF 0xF +trim_r11p72 0x0 0x5948 0xF 0xF +trim_r11p73 0x0 0x5949 0xF 0xF +trim_r11p74 0x0 0x594a 0xF 0xF +trim_r11p75 0x0 0x594b 0xF 0xF +trim_r11p76 0x0 0x594c 0xF 0xF +trim_r11p77 0x0 0x594d 0xF 0xF +trim_r11p78 0x0 0x594e 0xF 0xF +trim_r11p79 0x0 0x594f 0xF 0xF +trim_r11p80 0x0 0x5950 0xF 0xF +trim_r11p81 0x0 0x5951 0xF 0xF +trim_r11p82 0x0 0x5952 0xF 0xF +trim_r11p83 0x0 0x5953 0xF 0xF +trim_r11p84 0x0 0x5954 0xF 0xF +trim_r11p85 0x0 0x5955 0xF 0xF +trim_r11p86 0x0 0x5956 0xF 0xF +trim_r11p87 0x0 0x5957 0xF 0xF +trim_r11p88 0x0 0x5958 0xF 0xF +trim_r11p89 0x0 0x5959 0xF 0xF +trim_r11p90 0x0 0x595a 0xF 0xF +trim_r11p91 0x0 0x595b 0xF 0xF +trim_r11p92 0x0 0x595c 0xF 0xF +trim_r11p93 0x0 0x595d 0xF 0xF +trim_r11p94 0x0 0x595e 0xF 0xF +trim_r11p95 0x0 0x595f 0xF 0xF +trim_r11p96 0x0 0x5960 0xF 0xF +trim_r11p97 0x0 0x5961 0xF 0xF +trim_r11p98 0x0 0x5962 0xF 0xF +trim_r11p99 0x0 0x5963 0xF 0xF +trim_r11p100 0x0 0x5964 0xF 0xF +trim_r11p101 0x0 0x5965 0xF 0xF +trim_r11p102 0x0 0x5966 0xF 0xF +trim_r11p103 0x0 0x5967 0xF 0xF +trim_r11p104 0x0 0x5968 0xF 0xF +trim_r11p105 0x0 0x5969 0xF 0xF +trim_r11p106 0x0 0x596a 0xF 0xF +trim_r11p107 0x0 0x596b 0xF 0xF +trim_r11p108 0x0 0x596c 0xF 0xF +trim_r11p109 0x0 0x596d 0xF 0xF +trim_r11p110 0x0 0x596e 0xF 0xF +trim_r11p111 0x0 0x596f 0xF 0xF +trim_r11p112 0x0 0x5970 0xF 0xF +trim_r11p113 0x0 0x5971 0xF 0xF +trim_r11p114 0x0 0x5972 0xF 0xF +trim_r11p115 0x0 0x5973 0xF 0xF +trim_r11p116 0x0 0x5974 0xF 0xF +trim_r11p117 0x0 0x5975 0xF 0xF +trim_r11p118 0x0 0x5976 0xF 0xF +trim_r11p119 0x0 0x5977 0xF 0xF +trim_r12p1 0x0 0x6101 0xF 0xF +trim_r12p2 0x0 0x6102 0xF 0xF +trim_r12p3 0x0 0x6103 0xF 0xF +trim_r12p4 0x0 0x6104 0xF 0xF +trim_r12p5 0x0 0x6105 0xF 0xF +trim_r12p6 0x0 0x6106 0xF 0xF +trim_r12p7 0x0 0x6107 0xF 0xF +trim_r12p8 0x0 0x6108 0xF 0xF +trim_r12p9 0x0 0x6109 0xF 0xF +trim_r12p10 0x0 0x610a 0xF 0xF +trim_r12p11 0x0 0x610b 0xF 0xF +trim_r12p12 0x0 0x610c 0xF 0xF +trim_r12p13 0x0 0x610d 0xF 0xF +trim_r12p14 0x0 0x610e 0xF 0xF +trim_r12p15 0x0 0x610f 0xF 0xF +trim_r12p16 0x0 0x6110 0xF 0xF +trim_r12p17 0x0 0x6111 0xF 0xF +trim_r12p18 0x0 0x6112 0xF 0xF +trim_r12p19 0x0 0x6113 0xF 0xF +trim_r12p20 0x0 0x6114 0xF 0xF +trim_r12p21 0x0 0x6115 0xF 0xF +trim_r12p22 0x0 0x6116 0xF 0xF +trim_r12p23 0x0 0x6117 0xF 0xF +trim_r12p24 0x0 0x6118 0xF 0xF +trim_r12p25 0x0 0x6119 0xF 0xF +trim_r12p26 0x0 0x611a 0xF 0xF +trim_r12p27 0x0 0x611b 0xF 0xF +trim_r12p28 0x0 0x611c 0xF 0xF +trim_r12p29 0x0 0x611d 0xF 0xF +trim_r12p30 0x0 0x611e 0xF 0xF +trim_r12p31 0x0 0x611f 0xF 0xF +trim_r12p32 0x0 0x6120 0xF 0xF +trim_r12p33 0x0 0x6121 0xF 0xF +trim_r12p34 0x0 0x6122 0xF 0xF +trim_r12p35 0x0 0x6123 0xF 0xF +trim_r12p36 0x0 0x6124 0xF 0xF +trim_r12p37 0x0 0x6125 0xF 0xF +trim_r12p38 0x0 0x6126 0xF 0xF +trim_r12p39 0x0 0x6127 0xF 0xF +trim_r12p40 0x0 0x6128 0xF 0xF +trim_r12p41 0x0 0x6129 0xF 0xF +trim_r12p42 0x0 0x612a 0xF 0xF +trim_r12p43 0x0 0x612b 0xF 0xF +trim_r12p44 0x0 0x612c 0xF 0xF +trim_r12p45 0x0 0x612d 0xF 0xF +trim_r12p46 0x0 0x612e 0xF 0xF +trim_r12p47 0x0 0x612f 0xF 0xF +trim_r12p48 0x0 0x6130 0xF 0xF +trim_r12p49 0x0 0x6131 0xF 0xF +trim_r12p50 0x0 0x6132 0xF 0xF +trim_r12p51 0x0 0x6133 0xF 0xF +trim_r12p52 0x0 0x6134 0xF 0xF +trim_r12p53 0x0 0x6135 0xF 0xF +trim_r12p54 0x0 0x6136 0xF 0xF +trim_r12p55 0x0 0x6137 0xF 0xF +trim_r12p56 0x0 0x6138 0xF 0xF +trim_r12p57 0x0 0x6139 0xF 0xF +trim_r12p58 0x0 0x613a 0xF 0xF +trim_r12p59 0x0 0x613b 0xF 0xF +trim_r12p60 0x0 0x613c 0xF 0xF +trim_r12p61 0x0 0x613d 0xF 0xF +trim_r12p62 0x0 0x613e 0xF 0xF +trim_r12p63 0x0 0x613f 0xF 0xF +trim_r12p64 0x0 0x6140 0xF 0xF +trim_r12p65 0x0 0x6141 0xF 0xF +trim_r12p66 0x0 0x6142 0xF 0xF +trim_r12p67 0x0 0x6143 0xF 0xF +trim_r12p68 0x0 0x6144 0xF 0xF +trim_r12p69 0x0 0x6145 0xF 0xF +trim_r12p70 0x0 0x6146 0xF 0xF +trim_r12p71 0x0 0x6147 0xF 0xF +trim_r12p72 0x0 0x6148 0xF 0xF +trim_r12p73 0x0 0x6149 0xF 0xF +trim_r12p74 0x0 0x614a 0xF 0xF +trim_r12p75 0x0 0x614b 0xF 0xF +trim_r12p76 0x0 0x614c 0xF 0xF +trim_r12p77 0x0 0x614d 0xF 0xF +trim_r12p78 0x0 0x614e 0xF 0xF +trim_r12p79 0x0 0x614f 0xF 0xF +trim_r12p80 0x0 0x6150 0xF 0xF +trim_r12p81 0x0 0x6151 0xF 0xF +trim_r12p82 0x0 0x6152 0xF 0xF +trim_r12p83 0x0 0x6153 0xF 0xF +trim_r12p84 0x0 0x6154 0xF 0xF +trim_r12p85 0x0 0x6155 0xF 0xF +trim_r12p86 0x0 0x6156 0xF 0xF +trim_r12p87 0x0 0x6157 0xF 0xF +trim_r12p88 0x0 0x6158 0xF 0xF +trim_r12p89 0x0 0x6159 0xF 0xF +trim_r12p90 0x0 0x615a 0xF 0xF +trim_r12p91 0x0 0x615b 0xF 0xF +trim_r12p92 0x0 0x615c 0xF 0xF +trim_r12p93 0x0 0x615d 0xF 0xF +trim_r12p94 0x0 0x615e 0xF 0xF +trim_r12p95 0x0 0x615f 0xF 0xF +trim_r12p96 0x0 0x6160 0xF 0xF +trim_r12p97 0x0 0x6161 0xF 0xF +trim_r12p98 0x0 0x6162 0xF 0xF +trim_r12p99 0x0 0x6163 0xF 0xF +trim_r12p100 0x0 0x6164 0xF 0xF +trim_r12p101 0x0 0x6165 0xF 0xF +trim_r12p102 0x0 0x6166 0xF 0xF +trim_r12p103 0x0 0x6167 0xF 0xF +trim_r12p104 0x0 0x6168 0xF 0xF +trim_r12p105 0x0 0x6169 0xF 0xF +trim_r12p106 0x0 0x616a 0xF 0xF +trim_r12p107 0x0 0x616b 0xF 0xF +trim_r12p108 0x0 0x616c 0xF 0xF +trim_r12p109 0x0 0x616d 0xF 0xF +trim_r12p110 0x0 0x616e 0xF 0xF +trim_r12p111 0x0 0x616f 0xF 0xF +trim_r12p112 0x0 0x6170 0xF 0xF +trim_r12p113 0x0 0x6171 0xF 0xF +trim_r12p114 0x0 0x6172 0xF 0xF +trim_r12p115 0x0 0x6173 0xF 0xF +trim_r12p116 0x0 0x6174 0xF 0xF +trim_r12p117 0x0 0x6175 0xF 0xF +trim_r12p118 0x0 0x6176 0xF 0xF +trim_r12p119 0x0 0x6177 0xF 0xF +trim_r13p1 0x0 0x6901 0xF 0xF +trim_r13p2 0x0 0x6902 0xF 0xF +trim_r13p3 0x0 0x6903 0xF 0xF +trim_r13p4 0x0 0x6904 0xF 0xF +trim_r13p5 0x0 0x6905 0xF 0xF +trim_r13p6 0x0 0x6906 0xF 0xF +trim_r13p7 0x0 0x6907 0xF 0xF +trim_r13p8 0x0 0x6908 0xF 0xF +trim_r13p9 0x0 0x6909 0xF 0xF +trim_r13p10 0x0 0x690a 0xF 0xF +trim_r13p11 0x0 0x690b 0xF 0xF +trim_r13p12 0x0 0x690c 0xF 0xF +trim_r13p13 0x0 0x690d 0xF 0xF +trim_r13p14 0x0 0x690e 0xF 0xF +trim_r13p15 0x0 0x690f 0xF 0xF +trim_r13p16 0x0 0x6910 0xF 0xF +trim_r13p17 0x0 0x6911 0xF 0xF +trim_r13p18 0x0 0x6912 0xF 0xF +trim_r13p19 0x0 0x6913 0xF 0xF +trim_r13p20 0x0 0x6914 0xF 0xF +trim_r13p21 0x0 0x6915 0xF 0xF +trim_r13p22 0x0 0x6916 0xF 0xF +trim_r13p23 0x0 0x6917 0xF 0xF +trim_r13p24 0x0 0x6918 0xF 0xF +trim_r13p25 0x0 0x6919 0xF 0xF +trim_r13p26 0x0 0x691a 0xF 0xF +trim_r13p27 0x0 0x691b 0xF 0xF +trim_r13p28 0x0 0x691c 0xF 0xF +trim_r13p29 0x0 0x691d 0xF 0xF +trim_r13p30 0x0 0x691e 0xF 0xF +trim_r13p31 0x0 0x691f 0xF 0xF +trim_r13p32 0x0 0x6920 0xF 0xF +trim_r13p33 0x0 0x6921 0xF 0xF +trim_r13p34 0x0 0x6922 0xF 0xF +trim_r13p35 0x0 0x6923 0xF 0xF +trim_r13p36 0x0 0x6924 0xF 0xF +trim_r13p37 0x0 0x6925 0xF 0xF +trim_r13p38 0x0 0x6926 0xF 0xF +trim_r13p39 0x0 0x6927 0xF 0xF +trim_r13p40 0x0 0x6928 0xF 0xF +trim_r13p41 0x0 0x6929 0xF 0xF +trim_r13p42 0x0 0x692a 0xF 0xF +trim_r13p43 0x0 0x692b 0xF 0xF +trim_r13p44 0x0 0x692c 0xF 0xF +trim_r13p45 0x0 0x692d 0xF 0xF +trim_r13p46 0x0 0x692e 0xF 0xF +trim_r13p47 0x0 0x692f 0xF 0xF +trim_r13p48 0x0 0x6930 0xF 0xF +trim_r13p49 0x0 0x6931 0xF 0xF +trim_r13p50 0x0 0x6932 0xF 0xF +trim_r13p51 0x0 0x6933 0xF 0xF +trim_r13p52 0x0 0x6934 0xF 0xF +trim_r13p53 0x0 0x6935 0xF 0xF +trim_r13p54 0x0 0x6936 0xF 0xF +trim_r13p55 0x0 0x6937 0xF 0xF +trim_r13p56 0x0 0x6938 0xF 0xF +trim_r13p57 0x0 0x6939 0xF 0xF +trim_r13p58 0x0 0x693a 0xF 0xF +trim_r13p59 0x0 0x693b 0xF 0xF +trim_r13p60 0x0 0x693c 0xF 0xF +trim_r13p61 0x0 0x693d 0xF 0xF +trim_r13p62 0x0 0x693e 0xF 0xF +trim_r13p63 0x0 0x693f 0xF 0xF +trim_r13p64 0x0 0x6940 0xF 0xF +trim_r13p65 0x0 0x6941 0xF 0xF +trim_r13p66 0x0 0x6942 0xF 0xF +trim_r13p67 0x0 0x6943 0xF 0xF +trim_r13p68 0x0 0x6944 0xF 0xF +trim_r13p69 0x0 0x6945 0xF 0xF +trim_r13p70 0x0 0x6946 0xF 0xF +trim_r13p71 0x0 0x6947 0xF 0xF +trim_r13p72 0x0 0x6948 0xF 0xF +trim_r13p73 0x0 0x6949 0xF 0xF +trim_r13p74 0x0 0x694a 0xF 0xF +trim_r13p75 0x0 0x694b 0xF 0xF +trim_r13p76 0x0 0x694c 0xF 0xF +trim_r13p77 0x0 0x694d 0xF 0xF +trim_r13p78 0x0 0x694e 0xF 0xF +trim_r13p79 0x0 0x694f 0xF 0xF +trim_r13p80 0x0 0x6950 0xF 0xF +trim_r13p81 0x0 0x6951 0xF 0xF +trim_r13p82 0x0 0x6952 0xF 0xF +trim_r13p83 0x0 0x6953 0xF 0xF +trim_r13p84 0x0 0x6954 0xF 0xF +trim_r13p85 0x0 0x6955 0xF 0xF +trim_r13p86 0x0 0x6956 0xF 0xF +trim_r13p87 0x0 0x6957 0xF 0xF +trim_r13p88 0x0 0x6958 0xF 0xF +trim_r13p89 0x0 0x6959 0xF 0xF +trim_r13p90 0x0 0x695a 0xF 0xF +trim_r13p91 0x0 0x695b 0xF 0xF +trim_r13p92 0x0 0x695c 0xF 0xF +trim_r13p93 0x0 0x695d 0xF 0xF +trim_r13p94 0x0 0x695e 0xF 0xF +trim_r13p95 0x0 0x695f 0xF 0xF +trim_r13p96 0x0 0x6960 0xF 0xF +trim_r13p97 0x0 0x6961 0xF 0xF +trim_r13p98 0x0 0x6962 0xF 0xF +trim_r13p99 0x0 0x6963 0xF 0xF +trim_r13p100 0x0 0x6964 0xF 0xF +trim_r13p101 0x0 0x6965 0xF 0xF +trim_r13p102 0x0 0x6966 0xF 0xF +trim_r13p103 0x0 0x6967 0xF 0xF +trim_r13p104 0x0 0x6968 0xF 0xF +trim_r13p105 0x0 0x6969 0xF 0xF +trim_r13p106 0x0 0x696a 0xF 0xF +trim_r13p107 0x0 0x696b 0xF 0xF +trim_r13p108 0x0 0x696c 0xF 0xF +trim_r13p109 0x0 0x696d 0xF 0xF +trim_r13p110 0x0 0x696e 0xF 0xF +trim_r13p111 0x0 0x696f 0xF 0xF +trim_r13p112 0x0 0x6970 0xF 0xF +trim_r13p113 0x0 0x6971 0xF 0xF +trim_r13p114 0x0 0x6972 0xF 0xF +trim_r13p115 0x0 0x6973 0xF 0xF +trim_r13p116 0x0 0x6974 0xF 0xF +trim_r13p117 0x0 0x6975 0xF 0xF +trim_r13p118 0x0 0x6976 0xF 0xF +trim_r13p119 0x0 0x6977 0xF 0xF +trim_r14p1 0x0 0x7101 0xF 0xF +trim_r14p2 0x0 0x7102 0xF 0xF +trim_r14p3 0x0 0x7103 0xF 0xF +trim_r14p4 0x0 0x7104 0xF 0xF +trim_r14p5 0x0 0x7105 0xF 0xF +trim_r14p6 0x0 0x7106 0xF 0xF +trim_r14p7 0x0 0x7107 0xF 0xF +trim_r14p8 0x0 0x7108 0xF 0xF +trim_r14p9 0x0 0x7109 0xF 0xF +trim_r14p10 0x0 0x710a 0xF 0xF +trim_r14p11 0x0 0x710b 0xF 0xF +trim_r14p12 0x0 0x710c 0xF 0xF +trim_r14p13 0x0 0x710d 0xF 0xF +trim_r14p14 0x0 0x710e 0xF 0xF +trim_r14p15 0x0 0x710f 0xF 0xF +trim_r14p16 0x0 0x7110 0xF 0xF +trim_r14p17 0x0 0x7111 0xF 0xF +trim_r14p18 0x0 0x7112 0xF 0xF +trim_r14p19 0x0 0x7113 0xF 0xF +trim_r14p20 0x0 0x7114 0xF 0xF +trim_r14p21 0x0 0x7115 0xF 0xF +trim_r14p22 0x0 0x7116 0xF 0xF +trim_r14p23 0x0 0x7117 0xF 0xF +trim_r14p24 0x0 0x7118 0xF 0xF +trim_r14p25 0x0 0x7119 0xF 0xF +trim_r14p26 0x0 0x711a 0xF 0xF +trim_r14p27 0x0 0x711b 0xF 0xF +trim_r14p28 0x0 0x711c 0xF 0xF +trim_r14p29 0x0 0x711d 0xF 0xF +trim_r14p30 0x0 0x711e 0xF 0xF +trim_r14p31 0x0 0x711f 0xF 0xF +trim_r14p32 0x0 0x7120 0xF 0xF +trim_r14p33 0x0 0x7121 0xF 0xF +trim_r14p34 0x0 0x7122 0xF 0xF +trim_r14p35 0x0 0x7123 0xF 0xF +trim_r14p36 0x0 0x7124 0xF 0xF +trim_r14p37 0x0 0x7125 0xF 0xF +trim_r14p38 0x0 0x7126 0xF 0xF +trim_r14p39 0x0 0x7127 0xF 0xF +trim_r14p40 0x0 0x7128 0xF 0xF +trim_r14p41 0x0 0x7129 0xF 0xF +trim_r14p42 0x0 0x712a 0xF 0xF +trim_r14p43 0x0 0x712b 0xF 0xF +trim_r14p44 0x0 0x712c 0xF 0xF +trim_r14p45 0x0 0x712d 0xF 0xF +trim_r14p46 0x0 0x712e 0xF 0xF +trim_r14p47 0x0 0x712f 0xF 0xF +trim_r14p48 0x0 0x7130 0xF 0xF +trim_r14p49 0x0 0x7131 0xF 0xF +trim_r14p50 0x0 0x7132 0xF 0xF +trim_r14p51 0x0 0x7133 0xF 0xF +trim_r14p52 0x0 0x7134 0xF 0xF +trim_r14p53 0x0 0x7135 0xF 0xF +trim_r14p54 0x0 0x7136 0xF 0xF +trim_r14p55 0x0 0x7137 0xF 0xF +trim_r14p56 0x0 0x7138 0xF 0xF +trim_r14p57 0x0 0x7139 0xF 0xF +trim_r14p58 0x0 0x713a 0xF 0xF +trim_r14p59 0x0 0x713b 0xF 0xF +trim_r14p60 0x0 0x713c 0xF 0xF +trim_r14p61 0x0 0x713d 0xF 0xF +trim_r14p62 0x0 0x713e 0xF 0xF +trim_r14p63 0x0 0x713f 0xF 0xF +trim_r14p64 0x0 0x7140 0xF 0xF +trim_r14p65 0x0 0x7141 0xF 0xF +trim_r14p66 0x0 0x7142 0xF 0xF +trim_r14p67 0x0 0x7143 0xF 0xF +trim_r14p68 0x0 0x7144 0xF 0xF +trim_r14p69 0x0 0x7145 0xF 0xF +trim_r14p70 0x0 0x7146 0xF 0xF +trim_r14p71 0x0 0x7147 0xF 0xF +trim_r14p72 0x0 0x7148 0xF 0xF +trim_r14p73 0x0 0x7149 0xF 0xF +trim_r14p74 0x0 0x714a 0xF 0xF +trim_r14p75 0x0 0x714b 0xF 0xF +trim_r14p76 0x0 0x714c 0xF 0xF +trim_r14p77 0x0 0x714d 0xF 0xF +trim_r14p78 0x0 0x714e 0xF 0xF +trim_r14p79 0x0 0x714f 0xF 0xF +trim_r14p80 0x0 0x7150 0xF 0xF +trim_r14p81 0x0 0x7151 0xF 0xF +trim_r14p82 0x0 0x7152 0xF 0xF +trim_r14p83 0x0 0x7153 0xF 0xF +trim_r14p84 0x0 0x7154 0xF 0xF +trim_r14p85 0x0 0x7155 0xF 0xF +trim_r14p86 0x0 0x7156 0xF 0xF +trim_r14p87 0x0 0x7157 0xF 0xF +trim_r14p88 0x0 0x7158 0xF 0xF +trim_r14p89 0x0 0x7159 0xF 0xF +trim_r14p90 0x0 0x715a 0xF 0xF +trim_r14p91 0x0 0x715b 0xF 0xF +trim_r14p92 0x0 0x715c 0xF 0xF +trim_r14p93 0x0 0x715d 0xF 0xF +trim_r14p94 0x0 0x715e 0xF 0xF +trim_r14p95 0x0 0x715f 0xF 0xF +trim_r14p96 0x0 0x7160 0xF 0xF +trim_r14p97 0x0 0x7161 0xF 0xF +trim_r14p98 0x0 0x7162 0xF 0xF +trim_r14p99 0x0 0x7163 0xF 0xF +trim_r14p100 0x0 0x7164 0xF 0xF +trim_r14p101 0x0 0x7165 0xF 0xF +trim_r14p102 0x0 0x7166 0xF 0xF +trim_r14p103 0x0 0x7167 0xF 0xF +trim_r14p104 0x0 0x7168 0xF 0xF +trim_r14p105 0x0 0x7169 0xF 0xF +trim_r14p106 0x0 0x716a 0xF 0xF +trim_r14p107 0x0 0x716b 0xF 0xF +trim_r14p108 0x0 0x716c 0xF 0xF +trim_r14p109 0x0 0x716d 0xF 0xF +trim_r14p110 0x0 0x716e 0xF 0xF +trim_r14p111 0x0 0x716f 0xF 0xF +trim_r14p112 0x0 0x7170 0xF 0xF +trim_r14p113 0x0 0x7171 0xF 0xF +trim_r14p114 0x0 0x7172 0xF 0xF +trim_r14p115 0x0 0x7173 0xF 0xF +trim_r14p116 0x0 0x7174 0xF 0xF +trim_r14p117 0x0 0x7175 0xF 0xF +trim_r14p118 0x0 0x7176 0xF 0xF +trim_r14p119 0x0 0x7177 0xF 0xF +trim_r15p1 0x0 0x7901 0xF 0xF +trim_r15p2 0x0 0x7902 0xF 0xF +trim_r15p3 0x0 0x7903 0xF 0xF +trim_r15p4 0x0 0x7904 0xF 0xF +trim_r15p5 0x0 0x7905 0xF 0xF +trim_r15p6 0x0 0x7906 0xF 0xF +trim_r15p7 0x0 0x7907 0xF 0xF +trim_r15p8 0x0 0x7908 0xF 0xF +trim_r15p9 0x0 0x7909 0xF 0xF +trim_r15p10 0x0 0x790a 0xF 0xF +trim_r15p11 0x0 0x790b 0xF 0xF +trim_r15p12 0x0 0x790c 0xF 0xF +trim_r15p13 0x0 0x790d 0xF 0xF +trim_r15p14 0x0 0x790e 0xF 0xF +trim_r15p15 0x0 0x790f 0xF 0xF +trim_r15p16 0x0 0x7910 0xF 0xF +trim_r15p17 0x0 0x7911 0xF 0xF +trim_r15p18 0x0 0x7912 0xF 0xF +trim_r15p19 0x0 0x7913 0xF 0xF +trim_r15p20 0x0 0x7914 0xF 0xF +trim_r15p21 0x0 0x7915 0xF 0xF +trim_r15p22 0x0 0x7916 0xF 0xF +trim_r15p23 0x0 0x7917 0xF 0xF +trim_r15p24 0x0 0x7918 0xF 0xF +trim_r15p25 0x0 0x7919 0xF 0xF +trim_r15p26 0x0 0x791a 0xF 0xF +trim_r15p27 0x0 0x791b 0xF 0xF +trim_r15p28 0x0 0x791c 0xF 0xF +trim_r15p29 0x0 0x791d 0xF 0xF +trim_r15p30 0x0 0x791e 0xF 0xF +trim_r15p31 0x0 0x791f 0xF 0xF +trim_r15p32 0x0 0x7920 0xF 0xF +trim_r15p33 0x0 0x7921 0xF 0xF +trim_r15p34 0x0 0x7922 0xF 0xF +trim_r15p35 0x0 0x7923 0xF 0xF +trim_r15p36 0x0 0x7924 0xF 0xF +trim_r15p37 0x0 0x7925 0xF 0xF +trim_r15p38 0x0 0x7926 0xF 0xF +trim_r15p39 0x0 0x7927 0xF 0xF +trim_r15p40 0x0 0x7928 0xF 0xF +trim_r15p41 0x0 0x7929 0xF 0xF +trim_r15p42 0x0 0x792a 0xF 0xF +trim_r15p43 0x0 0x792b 0xF 0xF +trim_r15p44 0x0 0x792c 0xF 0xF +trim_r15p45 0x0 0x792d 0xF 0xF +trim_r15p46 0x0 0x792e 0xF 0xF +trim_r15p47 0x0 0x792f 0xF 0xF +trim_r15p48 0x0 0x7930 0xF 0xF +trim_r15p49 0x0 0x7931 0xF 0xF +trim_r15p50 0x0 0x7932 0xF 0xF +trim_r15p51 0x0 0x7933 0xF 0xF +trim_r15p52 0x0 0x7934 0xF 0xF +trim_r15p53 0x0 0x7935 0xF 0xF +trim_r15p54 0x0 0x7936 0xF 0xF +trim_r15p55 0x0 0x7937 0xF 0xF +trim_r15p56 0x0 0x7938 0xF 0xF +trim_r15p57 0x0 0x7939 0xF 0xF +trim_r15p58 0x0 0x793a 0xF 0xF +trim_r15p59 0x0 0x793b 0xF 0xF +trim_r15p60 0x0 0x793c 0xF 0xF +trim_r15p61 0x0 0x793d 0xF 0xF +trim_r15p62 0x0 0x793e 0xF 0xF +trim_r15p63 0x0 0x793f 0xF 0xF +trim_r15p64 0x0 0x7940 0xF 0xF +trim_r15p65 0x0 0x7941 0xF 0xF +trim_r15p66 0x0 0x7942 0xF 0xF +trim_r15p67 0x0 0x7943 0xF 0xF +trim_r15p68 0x0 0x7944 0xF 0xF +trim_r15p69 0x0 0x7945 0xF 0xF +trim_r15p70 0x0 0x7946 0xF 0xF +trim_r15p71 0x0 0x7947 0xF 0xF +trim_r15p72 0x0 0x7948 0xF 0xF +trim_r15p73 0x0 0x7949 0xF 0xF +trim_r15p74 0x0 0x794a 0xF 0xF +trim_r15p75 0x0 0x794b 0xF 0xF +trim_r15p76 0x0 0x794c 0xF 0xF +trim_r15p77 0x0 0x794d 0xF 0xF +trim_r15p78 0x0 0x794e 0xF 0xF +trim_r15p79 0x0 0x794f 0xF 0xF +trim_r15p80 0x0 0x7950 0xF 0xF +trim_r15p81 0x0 0x7951 0xF 0xF +trim_r15p82 0x0 0x7952 0xF 0xF +trim_r15p83 0x0 0x7953 0xF 0xF +trim_r15p84 0x0 0x7954 0xF 0xF +trim_r15p85 0x0 0x7955 0xF 0xF +trim_r15p86 0x0 0x7956 0xF 0xF +trim_r15p87 0x0 0x7957 0xF 0xF +trim_r15p88 0x0 0x7958 0xF 0xF +trim_r15p89 0x0 0x7959 0xF 0xF +trim_r15p90 0x0 0x795a 0xF 0xF +trim_r15p91 0x0 0x795b 0xF 0xF +trim_r15p92 0x0 0x795c 0xF 0xF +trim_r15p93 0x0 0x795d 0xF 0xF +trim_r15p94 0x0 0x795e 0xF 0xF +trim_r15p95 0x0 0x795f 0xF 0xF +trim_r15p96 0x0 0x7960 0xF 0xF +trim_r15p97 0x0 0x7961 0xF 0xF +trim_r15p98 0x0 0x7962 0xF 0xF +trim_r15p99 0x0 0x7963 0xF 0xF +trim_r15p100 0x0 0x7964 0xF 0xF +trim_r15p101 0x0 0x7965 0xF 0xF +trim_r15p102 0x0 0x7966 0xF 0xF +trim_r15p103 0x0 0x7967 0xF 0xF +trim_r15p104 0x0 0x7968 0xF 0xF +trim_r15p105 0x0 0x7969 0xF 0xF +trim_r15p106 0x0 0x796a 0xF 0xF +trim_r15p107 0x0 0x796b 0xF 0xF +trim_r15p108 0x0 0x796c 0xF 0xF +trim_r15p109 0x0 0x796d 0xF 0xF +trim_r15p110 0x0 0x796e 0xF 0xF +trim_r15p111 0x0 0x796f 0xF 0xF +trim_r15p112 0x0 0x7970 0xF 0xF +trim_r15p113 0x0 0x7971 0xF 0xF +trim_r15p114 0x0 0x7972 0xF 0xF +trim_r15p115 0x0 0x7973 0xF 0xF +trim_r15p116 0x0 0x7974 0xF 0xF +trim_r15p117 0x0 0x7975 0xF 0xF +trim_r15p118 0x0 0x7976 0xF 0xF +trim_r15p119 0x0 0x7977 0xF 0xF +trim_r16p1 0x0 0x8101 0xF 0xF +trim_r16p2 0x0 0x8102 0xF 0xF +trim_r16p3 0x0 0x8103 0xF 0xF +trim_r16p4 0x0 0x8104 0xF 0xF +trim_r16p5 0x0 0x8105 0xF 0xF +trim_r16p6 0x0 0x8106 0xF 0xF +trim_r16p7 0x0 0x8107 0xF 0xF +trim_r16p8 0x0 0x8108 0xF 0xF +trim_r16p9 0x0 0x8109 0xF 0xF +trim_r16p10 0x0 0x810a 0xF 0xF +trim_r16p11 0x0 0x810b 0xF 0xF +trim_r16p12 0x0 0x810c 0xF 0xF +trim_r16p13 0x0 0x810d 0xF 0xF +trim_r16p14 0x0 0x810e 0xF 0xF +trim_r16p15 0x0 0x810f 0xF 0xF +trim_r16p16 0x0 0x8110 0xF 0xF +trim_r16p17 0x0 0x8111 0xF 0xF +trim_r16p18 0x0 0x8112 0xF 0xF +trim_r16p19 0x0 0x8113 0xF 0xF +trim_r16p20 0x0 0x8114 0xF 0xF +trim_r16p21 0x0 0x8115 0xF 0xF +trim_r16p22 0x0 0x8116 0xF 0xF +trim_r16p23 0x0 0x8117 0xF 0xF +trim_r16p24 0x0 0x8118 0xF 0xF +trim_r16p25 0x0 0x8119 0xF 0xF +trim_r16p26 0x0 0x811a 0xF 0xF +trim_r16p27 0x0 0x811b 0xF 0xF +trim_r16p28 0x0 0x811c 0xF 0xF +trim_r16p29 0x0 0x811d 0xF 0xF +trim_r16p30 0x0 0x811e 0xF 0xF +trim_r16p31 0x0 0x811f 0xF 0xF +trim_r16p32 0x0 0x8120 0xF 0xF +trim_r16p33 0x0 0x8121 0xF 0xF +trim_r16p34 0x0 0x8122 0xF 0xF +trim_r16p35 0x0 0x8123 0xF 0xF +trim_r16p36 0x0 0x8124 0xF 0xF +trim_r16p37 0x0 0x8125 0xF 0xF +trim_r16p38 0x0 0x8126 0xF 0xF +trim_r16p39 0x0 0x8127 0xF 0xF +trim_r16p40 0x0 0x8128 0xF 0xF +trim_r16p41 0x0 0x8129 0xF 0xF +trim_r16p42 0x0 0x812a 0xF 0xF +trim_r16p43 0x0 0x812b 0xF 0xF +trim_r16p44 0x0 0x812c 0xF 0xF +trim_r16p45 0x0 0x812d 0xF 0xF +trim_r16p46 0x0 0x812e 0xF 0xF +trim_r16p47 0x0 0x812f 0xF 0xF +trim_r16p48 0x0 0x8130 0xF 0xF +trim_r16p49 0x0 0x8131 0xF 0xF +trim_r16p50 0x0 0x8132 0xF 0xF +trim_r16p51 0x0 0x8133 0xF 0xF +trim_r16p52 0x0 0x8134 0xF 0xF +trim_r16p53 0x0 0x8135 0xF 0xF +trim_r16p54 0x0 0x8136 0xF 0xF +trim_r16p55 0x0 0x8137 0xF 0xF +trim_r16p56 0x0 0x8138 0xF 0xF +trim_r16p57 0x0 0x8139 0xF 0xF +trim_r16p58 0x0 0x813a 0xF 0xF +trim_r16p59 0x0 0x813b 0xF 0xF +trim_r16p60 0x0 0x813c 0xF 0xF +trim_r16p61 0x0 0x813d 0xF 0xF +trim_r16p62 0x0 0x813e 0xF 0xF +trim_r16p63 0x0 0x813f 0xF 0xF +trim_r16p64 0x0 0x8140 0xF 0xF +trim_r16p65 0x0 0x8141 0xF 0xF +trim_r16p66 0x0 0x8142 0xF 0xF +trim_r16p67 0x0 0x8143 0xF 0xF +trim_r16p68 0x0 0x8144 0xF 0xF +trim_r16p69 0x0 0x8145 0xF 0xF +trim_r16p70 0x0 0x8146 0xF 0xF +trim_r16p71 0x0 0x8147 0xF 0xF +trim_r16p72 0x0 0x8148 0xF 0xF +trim_r16p73 0x0 0x8149 0xF 0xF +trim_r16p74 0x0 0x814a 0xF 0xF +trim_r16p75 0x0 0x814b 0xF 0xF +trim_r16p76 0x0 0x814c 0xF 0xF +trim_r16p77 0x0 0x814d 0xF 0xF +trim_r16p78 0x0 0x814e 0xF 0xF +trim_r16p79 0x0 0x814f 0xF 0xF +trim_r16p80 0x0 0x8150 0xF 0xF +trim_r16p81 0x0 0x8151 0xF 0xF +trim_r16p82 0x0 0x8152 0xF 0xF +trim_r16p83 0x0 0x8153 0xF 0xF +trim_r16p84 0x0 0x8154 0xF 0xF +trim_r16p85 0x0 0x8155 0xF 0xF +trim_r16p86 0x0 0x8156 0xF 0xF +trim_r16p87 0x0 0x8157 0xF 0xF +trim_r16p88 0x0 0x8158 0xF 0xF +trim_r16p89 0x0 0x8159 0xF 0xF +trim_r16p90 0x0 0x815a 0xF 0xF +trim_r16p91 0x0 0x815b 0xF 0xF +trim_r16p92 0x0 0x815c 0xF 0xF +trim_r16p93 0x0 0x815d 0xF 0xF +trim_r16p94 0x0 0x815e 0xF 0xF +trim_r16p95 0x0 0x815f 0xF 0xF +trim_r16p96 0x0 0x8160 0xF 0xF +trim_r16p97 0x0 0x8161 0xF 0xF +trim_r16p98 0x0 0x8162 0xF 0xF +trim_r16p99 0x0 0x8163 0xF 0xF +trim_r16p100 0x0 0x8164 0xF 0xF +trim_r16p101 0x0 0x8165 0xF 0xF +trim_r16p102 0x0 0x8166 0xF 0xF +trim_r16p103 0x0 0x8167 0xF 0xF +trim_r16p104 0x0 0x8168 0xF 0xF +trim_r16p105 0x0 0x8169 0xF 0xF +trim_r16p106 0x0 0x816a 0xF 0xF +trim_r16p107 0x0 0x816b 0xF 0xF +trim_r16p108 0x0 0x816c 0xF 0xF +trim_r16p109 0x0 0x816d 0xF 0xF +trim_r16p110 0x0 0x816e 0xF 0xF +trim_r16p111 0x0 0x816f 0xF 0xF +trim_r16p112 0x0 0x8170 0xF 0xF +trim_r16p113 0x0 0x8171 0xF 0xF +trim_r16p114 0x0 0x8172 0xF 0xF +trim_r16p115 0x0 0x8173 0xF 0xF +trim_r16p116 0x0 0x8174 0xF 0xF +trim_r16p117 0x0 0x8175 0xF 0xF +trim_r16p118 0x0 0x8176 0xF 0xF +trim_r16p119 0x0 0x8177 0xF 0xF diff --git a/settings/MPAFiles/MPA_default_emulator.txt b/settings/MPAFiles/MPA_default_emulator.txt new file mode 100644 index 0000000000000000000000000000000000000000..941b3a2b4414377690c7ac591024368b90657ae0 --- /dev/null +++ b/settings/MPAFiles/MPA_default_emulator.txt @@ -0,0 +1,11 @@ +*-------------------------------------------------------------------------------- +* Periphery Registers +*-------------------------------------------------------------------------------- +* RegName Page Addr Defval Value +*nrPclusters 0x0 0x0004 0x00 0x02 +*pClusterAddress 0x0 0x0005 0x00 0x20 +ReadoutMode 0x0 0x8800 0x00 0x00 +ECM 0x0 0x8801 0x08 0x08 +*EdgeSelT1Raw 0x0 0x881e 0x03 0x00 * strange, seems that you can not readback this register +*PhaseShift 0x0 0x8820 0x00 0x00 + diff --git a/settings/MPAlightFiles/Conf_MPA_default_config1.xml b/settings/MPAlightFiles/Conf_MPA_default_config1.xml new file mode 100644 index 0000000000000000000000000000000000000000..0452ddac616043bb1b48f7fe3976fdacb94cc232 --- /dev/null +++ b/settings/MPAlightFiles/Conf_MPA_default_config1.xml @@ -0,0 +1,323 @@ +<CONF> + <periphery> + <OM>3</OM> + <RT>0</RT> + <SCW>0</SCW> + <SH2>0</SH2> + <SH1>0</SH1> + <CALDAC>70</CALDAC> + <THDAC>100</THDAC> + </periphery> + <pixel n="1"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="2"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="3"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="4"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="5"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="6"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="7"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="8"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="9"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="10"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="11"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="12"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="13"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="14"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="15"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="16"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="17"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="18"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="19"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="20"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="21"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="22"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="23"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> + <pixel n="24"> + <PML>1</PML> + <ARL>1</ARL> + <TRIMDACL>15</TRIMDACL> + <CEL>0</CEL> + <CW>0</CW> + <PMR>1</PMR> + <ARR>1</ARR> + <TRIMDACR>15</TRIMDACR> + <CER>0</CER> + <SP>1</SP> + <SR>1</SR> + </pixel> +</CONF> diff --git a/settings/address_tables/IC_address_table.xml b/settings/address_tables/IC_address_table.xml old mode 100755 new mode 100644 diff --git a/settings/address_tables/IC_cbc3_address_table.xml b/settings/address_tables/IC_cbc3_address_table.xml old mode 100755 new mode 100644 diff --git a/settings/address_tables/address_table_2CBC.xml b/settings/address_tables/address_table_2CBC.xml old mode 100755 new mode 100644 diff --git a/settings/address_tables/address_table_8CBC.xml b/settings/address_tables/address_table_8CBC.xml old mode 100755 new mode 100644 diff --git a/settings/address_tables/address_table_CTA_2CBC.xml b/settings/address_tables/address_table_CTA_2CBC.xml old mode 100755 new mode 100644 diff --git a/settings/address_tables/d19c_address_table.xml b/settings/address_tables/d19c_address_table.xml index 276099ad76f9113530c133ce3bacd1e62486045d..c8c80aed9bff2a2c92fdb243f32855634d4f390f 100755 --- a/settings/address_tables/d19c_address_table.xml +++ b/settings/address_tables/d19c_address_table.xml @@ -41,17 +41,57 @@ <node id="chips_enable_hyb_12" address="0x009" mask="0x000000FF"/> <node id="chips_enable_hyb_13" address="0x009" mask="0x0000FF00"/> <node id="chips_enable_hyb_14" address="0x009" mask="0x00FF0000"/> - <node id="chips_enable_hyb_15" address="0x009" mask="0xFF000000"/> + <node id="chips_enable_hyb_15" address="0x009" mask="0xFF000000"/> </node> <node id="command_processor_block" address="0x1000"> + <node id="i2c_address_table" address="0x000"> + <node id="slave_0_config" address="0x000" mask="0xffffffff"/> + <node id="slave_0_config_i2c_address" address="0x000" mask="0xfe000000"/> + <node id="slave_0_config_stop_for_rd_en" address="0x000" mask="0x01000000"/> + <node id="slave_0_config_nack_en" address="0x000" mask="0x00800000"/> + <node id="slave_0_config_register_address_nbytes" address="0x000" mask="0x00000C00"/> + <node id="slave_0_config_data_wr_nbytes" address="0x000" mask="0x000003E0"/> + <node id="slave_0_config_data_rd_nbytes" address="0x000" mask="0x0000001F"/> + <node id="slave_1_config" address="0x001" mask="0xffffffff"/> + <node id="slave_2_config" address="0x002" mask="0xffffffff"/> + <node id="slave_3_config" address="0x003" mask="0xffffffff"/> + <node id="slave_4_config" address="0x004" mask="0xffffffff"/> + <node id="slave_5_config" address="0x005" mask="0xffffffff"/> + <node id="slave_6_config" address="0x006" mask="0xffffffff"/> + <node id="slave_7_config" address="0x007" mask="0xffffffff"/> + <node id="slave_8_config" address="0x008" mask="0xffffffff"/> + <node id="slave_9_config" address="0x009" mask="0xffffffff"/> + <node id="slave_10_config" address="0x00A" mask="0xffffffff"/> + <node id="slave_11_config" address="0x00B" mask="0xffffffff"/> + <node id="slave_12_config" address="0x00C" mask="0xffffffff"/> + <node id="slave_13_config" address="0x00D" mask="0xffffffff"/> + <node id="slave_14_config" address="0x00E" mask="0xffffffff"/> + <node id="slave_15_config" address="0x00F" mask="0xffffffff"/> + <node id="slave_16_config" address="0x010" mask="0xffffffff"/> + <node id="slave_17_config" address="0x011" mask="0xffffffff"/> + <node id="slave_18_config" address="0x012" mask="0xffffffff"/> + <node id="slave_19_config" address="0x013" mask="0xffffffff"/> + <node id="slave_20_config" address="0x014" mask="0xffffffff"/> + <node id="slave_21_config" address="0x015" mask="0xffffffff"/> + <node id="slave_22_config" address="0x016" mask="0xffffffff"/> + <node id="slave_23_config" address="0x017" mask="0xffffffff"/> + <node id="slave_24_config" address="0x018" mask="0xffffffff"/> + <node id="slave_25_config" address="0x019" mask="0xffffffff"/> + <node id="slave_26_config" address="0x01A" mask="0xffffffff"/> + <node id="slave_27_config" address="0x01B" mask="0xffffffff"/> + <node id="slave_28_config" address="0x01C" mask="0xffffffff"/> + <node id="slave_29_config" address="0x01D" mask="0xffffffff"/> + <node id="slave_30_config" address="0x01E" mask="0xffffffff"/> + <node id="slave_31_config" address="0x01F" mask="0xffffffff"/> + </node> </node> <node id="fast_command_block" address="0x2000" description="internal fast signal is generated in the fast_signal_generator module and the settings are here."> <node id="triggers_to_accept" address="0x000" description="# of periodic fast signal cycle from the start signal."/> <node id="user_trigger_frequency" address="0x001" description="User-defined frequency in kHz"/> <node id="trigger_source" address="0x002" mask="0x0000000F" description="1 - L1, 2 - Stubs, 3 - User-Defined Frequency"/> - <node id="stubs_mask" address="0x003" mask="0x0000FFFF" description="if mode is stubs, then coincidence mask can be set here: 0x0000000f requires presence of stubs from hybrids 0,1,2,3"/> + <node id="stubs_mask" address="0x003" mask="0x0000FFFF" description="if mode is stubs, then coincidence mask can be set here: 0x0000000f requires presence of stubs from hybrids 0,1,2,3"/> <node id="stub_trigger_veto_length" address="0x003" mask="0x01FF0000" description="if mode is stubs, then following triggers can be vetoed (to control the rate)"/> <node id="test_pulse" description="configuration of the test pulse delays."> <node id="delay_after_fast_reset" address="0x004" description="delay between fast reset and following test pulse command"/> @@ -73,6 +113,9 @@ </node> <node id="physical_interface_block" address="0x3000"> + <node id="slvs_debug" address="0x000"> + <node id="raw_mode_en" mask="0x00000001"/> + </node> <node id="i2c" address="0x001"> <node id="frequency" mask="0x0000000f"/> <node id="master_en" mask="0x00000100"/> @@ -80,9 +123,9 @@ </node> <node id="readout_block" address="0x5000"> - <node id="packet_nbr" address="0x000" mask="0x0000ffff"/> + <node id="packet_nbr" address="0x000" mask="0x0000ffff"/> <node id="global" address="0x001"> - <node id="data_handshake_enable" mask="0x00000001"/> + <node id="data_handshake_enable" mask="0x00000001"/> <node id="int_trig_enable" mask="0x00000004"/> <node id="int_trig_rate" mask="0x000001f0"/> <node id="trigger_type" mask="0x0000f000"/> @@ -124,6 +167,28 @@ <node id="tlu_block" address="0x7000"> <node id="handshake_mode" address="0x000" mask="0x00000003"/> <node id="tlu_enabled" address="0x000" mask="0x00000010"/> + <node id="trigger_id_delay" address="0x000" mask="0x00000f00"/> + </node> + + <node id="mpa_ssa_board_block" address="0x9000"> + <node id="i2c_master_en" address="0x000" mask="0x00000001"/> + <node id="i2c_freq" address="0x000" mask="0x0000003C"/> + <node id="slave_0_config" address="0x002" mask="0xffffffff" /> + <node id="slave_1_config" address="0x003" mask="0xffffffff" /> + <node id="slave_2_config" address="0x004" mask="0xffffffff" /> + <node id="slave_3_config" address="0x005" mask="0xffffffff" /> + <node id="slave_4_config" address="0x006" mask="0xffffffff" /> + <node id="slave_5_config" address="0x007" mask="0xffffffff" /> + <node id="slave_6_config" address="0x008" mask="0xffffffff" /> + <node id="slave_7_config" address="0x009" mask="0xffffffff" /> + <node id="slave_8_config" address="0x00A" mask="0xffffffff" /> + <node id="slave_9_config" address="0x00B" mask="0xffffffff" /> + <node id="slave_10_config" address="0x00C" mask="0xffffffff" /> + <node id="slave_11_config" address="0x00D" mask="0xffffffff" /> + <node id="slave_12_config" address="0x00E" mask="0xffffffff" /> + <node id="slave_13_config" address="0x00F" mask="0xffffffff" /> + <node id="slave_14_config" address="0x010" mask="0xffffffff" /> + <node id="slave_15_config" address="0x011" mask="0xffffffff" /> </node> <node id="calibration_2s_block" address="0xE000"> @@ -159,6 +224,22 @@ </node> <node id="command_fifo" address="0x002" permission="w" mode="non-incremental" description="command fifo(write i2c commands here)"/> <node id="reply_fifo" address="0x003" permission="r" mode="non-incremental" description="reply fifo(read i2c replies here)"/> + + <node id="mpa_ssa_i2c_command" address="0x002" > + <node id="command_type" mask="0xf0000000" /> + <node id="word_id" mask="0x0C000000" /> + <node id="word0_slave_id" mask="0x03E00000" /> + <node id="word0_board_id" mask="0x00100000" /> + <node id="word0_read" mask="0x00010000" /> + <node id="word0_register" mask="0x0000FFFF" /> + <node id="word1_data" mask="0x00FFFFFF" /> + </node> + <node id="mpa_ssa_i2c_reply" address="0x003" > + <node id="slave_id" mask="0xF8000000" /> + <node id="board_id" mask="0x04000000" /> + <node id="err" mask="0x01000000" /> + <node id="data" mask="0x000000FF" /> + </node> </node> </node> @@ -183,6 +264,10 @@ <node id="chip_hard_reset" mask="0x00000001"/> <node id="cbc3_tune_again" mask="0x00000002"/> </node> + <node id="slvs_debug"> + <node id="fifo1_data" address="0x001" permission="r" mode="non-incremental"/> + <node id="fifo2_data" address="0x002" permission="r" mode="non-incremental"/> + </node> <node id="phase_tuning_ctrl" address="0x015" mask="0xFFFFFFFF"/> </node> @@ -200,7 +285,7 @@ </node> </node> - <node id="tlu_block" address="0x7000"> + <node id="tlu_block" address="0x7000"> </node> <node id="ddr3_block" address="0x8000"> @@ -208,6 +293,10 @@ <node id="traffic_str" mask="0x00000001"/> </node> </node> + <node id="mpa_ssa_board_block" address="0x9000"> + <node id="reset" address="0x000" mask="0x00000001"/> + </node> + <node id="calibration_2s_block" address="0xE000"> <node id="control" address="0x000"> @@ -292,7 +381,11 @@ <node id="bitslip_done_cbc1" address="0x002" mask="0x00000040"/> <node id="state_tuning_cbc0" address="0x002" mask="0x00F00000"/> <node id="state_tuning_cbc1" address="0x002" mask="0x0F000000"/> - </node> + <node id="slvs_debug" address="0x00F"> + <node id="ps_counters_ready" mask="0x00000004"/> + <node id="ps_counters_fsm_state" mask="0x000000f0"/> + </node> + </node> <node id="be_proc" address="0x4000"> <node id="general" address="0x000"> @@ -321,7 +414,7 @@ <node id="fsm_status" address="0x000" mask="0x00000ff0"/> <node id="words_cnt" address="0x001" mask="0xffffffff"/> </node> - + </node> <node id="dio5_block" address="0x6000"> @@ -334,8 +427,8 @@ <node id="tlu_block" address="0x7000"> <node id="fifo_empty" address="0x000" mask="0x00000001"/> <node id="fifo_full" address="0x000" mask="0x00000002"/> - <node id="trigger_id_fifo" address="0x001" mask="0x00007fff"/> - </node> + <node id="trigger_id_fifo" address="0x001" mask="0x00007fff"/> + </node> <node id="ddr3_block" address="0x8000"> <node id="is_ddr3_type" address="0x000" mask="0x00000001"/> diff --git a/settings/address_tables/fc7_system_address_table.xml b/settings/address_tables/fc7_system_address_table.xml old mode 100755 new mode 100644 diff --git a/settings/logger.conf b/settings/logger.conf old mode 100755 new mode 100644 diff --git a/setup.sh b/setup.sh old mode 100755 new mode 100644 index 5c279159d3605092325f8bbd12748dfba68f161f..cda436bbb99db0791f24252bf336f2c6b8ab6dce --- a/setup.sh +++ b/setup.sh @@ -20,9 +20,9 @@ fi #ROOT #source /usr/local/bin/thisroot.sh -source /opt/local/root/bin/thisroot.sh +source /home/mpc/Kevins_Stuff/temp/Root/bin/thisroot.sh #export ROOTLIB=/usr/local/lib/root -export ROOTLIB=/opt/local/root/lib +export ROOTLIB=/home/mpc/Kevins_Stuff/temp/Root/lib #export ROOTSYS=/usr/local/lib/root #ZMQ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b7abf122462d3364a76b7017a266573951b3d1f..822f7d8dda71ee106e7dfcef52bcf2aa5f64358e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,8 +76,20 @@ list(REMOVE_ITEM BINARIES test.cc) message("#### Building the following executables: ####") foreach( sourcefile ${BINARIES} ) string(REPLACE ".cc" "" name ${sourcefile}) - message(STATUS " ${name}") - add_executable(${name} ${sourcefile}) - target_link_libraries(${name} ${LIBS}) + if(${name} MATCHES "eudaqproducer") + message(STATUS "Skipping ${name}") + else() + message(STATUS " ${name}") + message(STATUS " ${LIBS}") + add_executable(${name} ${sourcefile}) + target_link_libraries(${name} ${LIBS}) + endif() endforeach(sourcefile ${BINARIES}) + +# build eudaq producer +if(USE_EUDAQ) + message(STATUS " eudaqproducer") + add_executable(eudaqproducer eudaqproducer.cc) + target_link_libraries(eudaqproducer ${LIBS} ${EUDAQ_LIB}) +endif(USE_EUDAQ) message("#### End ####") diff --git a/src/MPA_async_test.cc b/src/MPA_async_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..d7c6e074269c545f5a08c562cafc4fad66570035 --- /dev/null +++ b/src/MPA_async_test.cc @@ -0,0 +1,423 @@ +//Simple test script to demonstrate use of middleware for the purposes of usercode development + +#include <cstring> +#include <iostream> +#include <fstream> + +#include <sstream> + +#include "../Utils/Utilities.h" +#include "../HWDescription/SSA.h" +#include "../HWDescription/Module.h" +#include "../HWDescription/BeBoard.h" +#include "../HWInterface/MPAInterface.h" +#include "../HWInterface/D19cFWInterface.h" +#include "../HWInterface/BeBoardInterface.h" +#include "../HWDescription/Definition.h" +#include "../HWDescription/FrontEndDescription.h" +#include "../Utils/Timer.h" +#include <inttypes.h> +#include "../Utils/argvparser.h" +#include "../Utils/ConsoleColor.h" +#include "../System/SystemController.h" +#include "../Utils/CommonVisitors.h" +#include "../tools/Tool.h" + +#include "TH1.h" +#include <TF1.h> +#include "TH2.h" +#include "TFile.h" +#include "TCanvas.h" + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; + +using namespace std; +INITIALIZE_EASYLOGGINGPP + +int main( int argc, char** argv ) +{ + + //configure the logger + el::Configurations conf ("settings/logger.conf"); + el::Loggers::reconfigureAllLoggers (conf); + ArgvParser cmd; + // init + cmd.setIntroductoryDescription ( "CMS Ph2_ACF d19c Testboard Firmware Test Application" ); + // error codes + cmd.addErrorCode ( 0, "Success" ); + cmd.addErrorCode ( 1, "Error" ); + // options + cmd.setHelpOption ( "h", "help", "Print this help page" ); + cmd.defineOption ( "file", "Hw Description File . Default value: settings/D19CDescriptionMPA.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOption ( "extxt", "extxt"); + cmd.defineOption ( "reset", "reset"); + cmd.defineOption ( "writetrim", "writetrim"); + cmd.defineOption ( "ncalib", "ncalib"); + cmd.defineOptionAlternative ( "file", "f" ); + + int result = cmd.parse ( argc, argv ); + if ( result != ArgvParser::NoParserError ) + { + LOG (INFO) << cmd.parseErrorDescription ( result ); + exit ( 1 ); + } + + // init + std::string extxt = ( cmd.foundOption ( "extxt" ) ) ? cmd.optionValue ( "extxt" ) : ""; + std::string ancalib = ( cmd.foundOption ( "ncalib" ) ) ? cmd.optionValue ( "ncalib" ) : "1000"; + std::string areset = ( cmd.foundOption ( "reset" ) ) ? cmd.optionValue ( "reset" ) : "True"; + std::string awritetrim = ( cmd.foundOption ( "writetrim" ) ) ? cmd.optionValue ( "writetrim" ) : "True"; + + bool cals=true; + bool writetrim=true; + bool reset=true; + + + std::cout<<"awritetrim "<<awritetrim<<std::endl; + std::cout<<"areset "<<areset<<std::endl; + uint32_t npulses =std::stoi(ancalib); + std::cout<<"npulses "<<npulses<<std::endl; + + if(npulses==0)cals=false; + std::cout<<"cals "<<cals<<std::endl; + if(awritetrim=="False")writetrim=false; + if(areset=="False")reset=false; + + + uint32_t inittrim=15; + float lowrep = 0.01; + float highrep = 1.4; + if(!cals) + { + inittrim=31; + //inittrim=0; + lowrep = 0.01; + highrep = 10.0; + } + std::cout<<" inittrim "<<inittrim<<std::endl; + std::cout<<lowrep<<" "<<highrep<<std::endl; + std::cout<<lowrep<<" "<<highrep<<std::endl; + std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CDescriptionMPA.xml"; + std::stringstream outp; + Tool cTool; + cTool.InitializeHw ( cHWFile, outp); + cTool.InitializeSettings ( cHWFile, outp ); + cTool.ConfigureHw (); + + LOG (INFO) << outp.str(); + MPAInterface* cMPAInterface = cTool.fMPAInterface; + BeBoard* cBoard = cTool.fBoardVector.at( 0 ); + MPA* cMPAChip = cBoard->fModuleVector.at(0)->fMPAVector.at(0); + cTool.setFWTestPulse(); + + if(reset)std::cout<<"Resetting trims"<<std::endl; + if(writetrim)std::cout<<"Writing trims"<<std::endl; + + std::chrono::milliseconds ShortWait( 10 ); + + cMPAInterface->PS_Clear_counters(cMPAChip); + cMPAInterface->PS_Clear_counters(cMPAChip); + + std::pair<int, int> rows = {1,17}; //number of rows 1 - 17 + std::pair<int, int> cols = {1,121}; //number of cols 1 - 121 + std::pair<int, int> th = {0,255}; // change to 255 + + + std::vector<TH1F*> scurves; + TH2F* scurve_2d = new TH2F("scurve_2d", "scurve_2d;Pixel [#];Threshold [VCth]", 2040, -0.5, 2039.5, th.second-th.first, th.first-0.5, th.second-0.5); + TH1F* noise_pedestal = new TH1F("noise_pedestal", "Noise pedestal; Noise pedestal [VCth];Entries", 160, 19.5, 179.5); + TH1F* noise_rms = new TH1F("noise_rms", "Noise RMS;Noise RMS [VCth];Entries", 200, -0.5, 19.5); + + + std::string title; + + cMPAInterface->Activate_async(cMPAChip); + if(cals)cMPAInterface->Set_calibration(cMPAChip,90); // maybe this modifies individual dacs? + + uint32_t npixtot = 0; + cMPAInterface->Disable_pixel(cMPAChip,0,0); + std::vector<std::pair<int,int>> coords; + for(int row=rows.first; row<rows.second; row++)//enable and disable pixels? + { + for(int col=cols.first; col<cols.second; col++) + { + + if(reset) + { + cMPAInterface->Pix_write(cMPAChip,cMPAChip->getRegItem("TrimDAC"),row, col,inittrim); + } + cMPAInterface->Enable_pix_counter(cMPAChip, row, col); + title = "trim_r"+std::to_string(row)+"p"+std::to_string(col); + scurves.push_back(new TH1F(title.c_str(),title.c_str(),th.second-th.first, th.first-0.5, th.second-0.5)); // make a new scurve for this one + coords.push_back(std::pair<int, int> {row,col}); + + npixtot+=1; + } + } + + + + std::cout <<"Numpix -- "<< npixtot <<std::endl; + std::vector<uint16_t> countersfifo; + uint32_t totalevents = 0; + uint32_t totaleventsprev = 0; + uint32_t nrep = 0; + for(int ith=th.first;ith<th.second;ith++) + { + + cMPAInterface->PS_Clear_counters(cMPAChip, 8); + cMPAInterface->PS_Clear_counters(cMPAChip, 8); + + int ithset=ith%255; // change from *4, why mod 250? + std::cout<<"VCth = "<<ithset<<std::endl; + cMPAInterface->Set_threshold(cMPAChip, ithset); + + std::this_thread::sleep_for( ShortWait ); + if(cals)cMPAInterface->Send_pulses(cMPAChip, npulses); + else cMPAInterface->Shutter_loop(cMPAChip, 5000); + std::this_thread::sleep_for( ShortWait ); + + //FIFO readout + countersfifo = cMPAInterface->ReadoutCounters_MPA(cMPAChip, 0); + + //Randomly the counters fail + //this fixes the issue but this needs to be looked at further + totalevents = std::accumulate(countersfifo.begin()+1, countersfifo.end(), 0); + std::cout<<totalevents<<std::endl; + if (totaleventsprev>50) + { + if ((float(totalevents)/float(totaleventsprev))<lowrep or (float(totalevents)/float(totaleventsprev)>highrep)) + { + ith-=1; + nrep+=1; + std::cout<<"Repeat "<<nrep<<std::endl; + if (nrep<5) continue; + totaleventsprev = 0; + } + } + totaleventsprev = totalevents; + // fill the scurves + for(int row=rows.first; row<rows.second; row++) { + for(int col=cols.first; col<cols.second; col++) { + int scurve_id = (row-rows.first)*(cols.second-cols.first) + (col-cols.first); + scurves[scurve_id]->SetBinContent(scurves[scurve_id]->FindBin(ithset), countersfifo[(row-1)*120 + col-1]); + } + } + + // fill 2d + for(int row = 0; row < rows.second; row++) { + for(int col = 0; col < cols.second; col++) { + scurve_2d->SetBinContent(row*cols.second+col, ithset-th.first, countersfifo[row*120 + col]); + } + } + nrep=0; + + + + } + + std::ofstream pedestalfile; + pedestalfile.open("HVCalibpedestal.txt"); + std::ofstream calibfile; + calibfile.open("settings/MPAFiles/MPA_calib.txt"); + + std::ifstream lfile("settings/MPAFiles/MPA_default.txt"); + if (lfile.is_open()) { + std::string line; + while (getline(lfile, line)) { + calibfile << line<<+"\n"; + } + lfile.close(); + } + // fit scurves + /* + int count = 0; + for(TH1F* scurve : scurves) { + if (count > 1920) break; + else count++; + // get max + int i_max = scurve->GetMaximumBin(); + //LOG(INFO) << "name: " << scurve->GetName() << ", max bin: " << i_max; + // fit + std::string name = "fit_" + std::string(scurve->GetName()); + TF1* ff = new TF1(name.c_str(),"[2]*TMath::Erfc((x-[0])/[1])+[3]", scurve->GetBinCenter(i_max+10), scurve->GetBinCenter(scurve->GetNbinsX())); + ff->SetParLimits(0, scurve->GetBinCenter(i_max+10), scurve->GetBinCenter(scurve->GetNbinsX())); + ff->SetParameter(0, scurve->GetBinCenter(i_max+20)); + ff->SetParLimits(1, 0., 50.); + ff->SetParameter(1, 2); + ff->SetParLimits(2, 0., 5*npulses); + ff->SetParameter(2, npulses/2); + ff->SetParLimits(3, -10, npulses); + ff->SetParameter(3, 0.); + scurve->Fit(name.c_str(), "NRQ+"); + + noise_pedestal->Fill(ff->GetParameter(0)); + noise_rms->Fill(ff->GetParameter(1)); + pedestalfile << ff->GetName()<< " " << ff->GetParameter(0)<< " " << ff->GetParameter(1) << std::endl; + } + */ + std::vector<std::pair<std::pair<int,int>, float>> trimvals; + int ncurve = 0; + double maxmax=0.0; + //new TH1F(title.c_str(),title.c_str(),th.second-th.first, th.first-0.5, th.second-0.5)); + for(TH1F* scurve : scurves) { + maxmax=std::max(maxmax,scurve->GetMaximum()); + int maxbin = scurve->GetMaximumBin(); + float fullmax = scurve->GetMaximum(); + int nplat=0; + int fbin=0; + float halfval=0.; + float prevval=0.; + float pcont=0.; + for (int xbin=0;xbin<scurve->GetNbinsX()+1;xbin++) + { + float bcont = scurve->GetBinContent(xbin); + if(bcont==npulses)nplat+=1; + else nplat=0; + if(nplat==5)fbin=xbin; + if((cals and fbin!=0 and bcont<(float(npulses)/2.0) and halfval<1.0) or (!cals and bcont<(float(fullmax)/2.0) and halfval<1.0 and xbin>maxbin)) { + halfval=(scurve->GetBinCenter(xbin)*bcont+prevval*pcont)/(pcont+bcont); + std::pair<std::pair<int,int>, float> curtrimval; + curtrimval.first = coords[ncurve]; + curtrimval.second = halfval; + trimvals.push_back(curtrimval); + } + prevval=scurve->GetBinCenter(xbin); + pcont = scurve->GetBinContent(xbin); + } + ncurve+=1; + //TF1* ff = new TF1(name.c_str(),"[2]*TMath::Erfc((x-[0])/[1])+[3]", scurve->GetBinCenter(xbin), scurve->GetBinCenter(scurve->GetNbinsX())); + //ff->SetParLimits(0, scurve->GetBinCenter(i_max+10), scurve->GetBinCenter(scurve->GetNbinsX())); + //ff->SetParameter(0, scurve->GetBinCenter(i_max+20)); + } + + float avecalib = 0.0; + int ncalib = 0; + std::cout<<"prenorm"<<std::endl; + for(auto tval:trimvals) + { + std::cout<<(tval.first).first<<","<<(tval.first).second<<" "<<tval.second<<std::endl; + ncalib+=1; + avecalib+=tval.second; + } + + avecalib/=float(ncalib); + if(!reset) avecalib=62.0; + std::cout<<"Ave "<<avecalib<<std::endl; + std::cout<<"norming"<<std::endl; + int maxtrim=-1; + int mintrim=999; + int nup=0; + int ndown=0; + std::vector<int> untrimmed; + int ntrims = 0; + for(auto tval:trimvals) + { + float old=15.0; + if(!reset) + { + uint32_t old1=(cMPAInterface->Pix_read(cMPAChip,cMPAChip->getRegItem("TrimDAC"),(tval.first).first, (tval.first).second))&0xff; + std::cout<<"newold "<<old1<<std::endl; + old=float(old1); + + } + tval.second=((avecalib-tval.second)*0.256)+(old); + uint32_t towriteval =round(tval.second); + maxtrim=std::max(maxtrim,int(round(tval.second))); + mintrim=std::min(mintrim,int(round(tval.second))); + if(towriteval>31) + { + untrimmed.push_back(ntrims); + towriteval=31; + nup+=1; + uint32_t addr = (((tval.first).first & 0x0001f) << 11 ) | ((0x0 & 0x000f) << 7 ) | ((tval.first).second & 0xfffffff); + calibfile <<"ENFLAGS_r"<<(tval.first).first<<"p"<<(tval.first).second<<"\t0x"<<std::hex<<0<<"\t0x"<<addr<<"\t0x"<<0<<"\t0x"<<0<<"\n"<<std::dec; + } + else if(towriteval<0) + { + untrimmed.push_back(ntrims); + towriteval=0; + ndown+=1; + uint32_t addr = (((tval.first).first & 0x0001f) << 11 ) | ((0x0 & 0x000f) << 7 ) | ((tval.first).second & 0xfffffff); + calibfile <<"ENFLAGS_r"<<(tval.first).first<<"p"<<(tval.first).second<<"\t0x"<<std::hex<<0<<"\t0x"<<addr<<"\t0x"<<0<<"\t0x"<<0<<"\n"<<std::dec; + } + else { + uint32_t addr = (((tval.first).first & 0x0001f) << 11 ) | ((0x0 & 0x000f) << 7 ) | ((tval.first).second & 0xfffffff); + uint32_t comboword = (1) + (1<<1) + (0<<2) + (0<<3) + (1<<4) + (0<<5) + (1<<6) + (0<<7); + calibfile <<"ENFLAGS_r"<<(tval.first).first<<"p"<<(tval.first).second<<"\t0x"<<std::hex<<0<<"\t0x"<<addr<<"\t0x"<<0<<"\t0x"<<comboword<<"\n"<<std::dec; + addr = (((tval.first).first & 0x0001f) << 11 ) | ((0x2 & 0x000f) << 7 ) | ((tval.first).second & 0xfffffff); + calibfile <<"trim_r"<<(tval.first).first<<"p"<<(tval.first).second<<"\t0x"<<std::hex<<0<<"\t0x"<<addr<<"\t0x"<<15<<"\t0x"<<towriteval<<"\n"<<std::dec; + + } + if(writetrim)cMPAInterface->Pix_write(cMPAChip,cMPAChip->getRegItem("TrimDAC"),(tval.first).first, (tval.first).second, towriteval); + + std::cout<<(tval.first).first<<","<<(tval.first).second<<" "<<tval.second<<" "<<towriteval<<std::endl; + ntrims+=1; + } + std::cout<<"ntot "<<ncalib<<std::endl; + std::cout<<"nNone "<<scurves.size()-trimvals.size()<<std::endl; + std::cout<<"nup "<<nup<<std::endl; + std::cout<<"ndown "<<ndown<<std::endl; + std::cout<<"maxtrim "<<maxtrim<<std::endl; + std::cout<<"mintrim "<<mintrim<<std::endl; + TFile *file = new TFile("scurves_mpa.root", "RECREATE"); + file->cd(); + + // maybe write all the histograms to the root file as well, or a text file, only looking for noise pedestal and rms + + TCanvas * c1 = new TCanvas("scurve_multi", "c1", 10, 10, 700, 500);//-c settings/D19CDescription.xml -f ../../Downloads/d19c_mpa_none_27022019.bin -i + + c1->cd(); + int ihist = 0; + TH1F* summedhist = new TH1F("summedhist", "summedhist", 255,-.5,254.5); + for (auto& hist : scurves) + { + + if (std::find(untrimmed.begin(), untrimmed.end(), ihist) != untrimmed.end()) continue; + + if (ihist==0) + { + + std::cout<<"Hist "<<ihist<<" "<<hist->Integral()<<std::endl; + hist->SetMaximum(maxmax); + hist->SetLineColor(1); + hist->SetTitle(";Thresh DAC;Counts"); + //hist->SetMaximum(40000); + hist->SetStats(0); + hist->Draw("L"); + summedhist=hist; + } + else + { + summedhist->Add(hist); + hist->SetLineColor(ihist%60+1); + hist->Draw("sameL"); + } + ihist += 1; + } + + std::cout<<"RMS "<<summedhist->GetRMS()<<std::endl; + c1->Write(); + + TCanvas * c2 = new TCanvas(scurve_2d->GetName(), "c2", 10, 10, 700, 500); + c2->cd(); + scurve_2d->Draw("colz"); + c2->Write(); + + TCanvas * c3 = new TCanvas(noise_pedestal->GetName(), "c3", 10, 10, 700, 500); + c3->cd(); + noise_pedestal->Draw(); + c3->Write(); + + TCanvas * c4 = new TCanvas(noise_rms->GetName(), "c4", 10, 10, 700, 500); + c4->cd(); + noise_rms->Draw(); + c4->Write(); + + file->Close(); + +}//int main + diff --git a/src/MPA_async_test_calibration.cc b/src/MPA_async_test_calibration.cc new file mode 100644 index 0000000000000000000000000000000000000000..8267bfb0986d65133718d6702b051dec39dedc98 --- /dev/null +++ b/src/MPA_async_test_calibration.cc @@ -0,0 +1,268 @@ +//Simple test script to demonstrate use of middleware for the purposes of usercode development + +#include <cstring> +#include <iostream> +#include <fstream> +#include "../Utils/Utilities.h" +#include "../HWDescription/SSA.h" +#include "../HWDescription/Module.h" +#include "../HWDescription/BeBoard.h" +#include "../HWInterface/MPAInterface.h" +#include "../HWInterface/D19cFWInterface.h" +#include "../HWInterface/BeBoardInterface.h" +#include "../HWDescription/Definition.h" +#include "../HWDescription/FrontEndDescription.h" +#include "../Utils/Timer.h" +#include <inttypes.h> +#include "../Utils/argvparser.h" +#include "../Utils/ConsoleColor.h" +#include "../System/SystemController.h" +#include "../Utils/CommonVisitors.h" +#include "../tools/Tool.h" + +#include "TH1.h" +#include <TF1.h> +#include "TH2.h" +#include "TFile.h" +#include "TCanvas.h" + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; + +using namespace std; +INITIALIZE_EASYLOGGINGPP + +int main( int argc, char** argv ) +{ + + //configure the logger + el::Configurations conf ("settings/logger.conf"); + el::Loggers::reconfigureAllLoggers (conf); + ArgvParser cmd; + // init + cmd.setIntroductoryDescription ( "CMS Ph2_ACF d19c Testboard Firmware Test Application" ); + // error codes + cmd.addErrorCode ( 0, "Success" ); + cmd.addErrorCode ( 1, "Error" ); + // options + cmd.setHelpOption ( "h", "help", "Print this help page" ); + cmd.defineOption ( "file", "Hw Description File . Default value: settings/D19CDescriptionMPA.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "file", "f" ); + + int result = cmd.parse ( argc, argv ); + if ( result != ArgvParser::NoParserError ) + { + LOG (INFO) << cmd.parseErrorDescription ( result ); + exit ( 1 ); + } + + // init + std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CDescriptionMPA.xml"; + std::stringstream outp; + Tool cTool; + cTool.InitializeHw ( cHWFile, outp); + cTool.InitializeSettings ( cHWFile, outp ); + cTool.ConfigureHw (); + LOG (INFO) << outp.str(); + MPAInterface* cMPAInterface = cTool.fMPAInterface; + BeBoard* cBoard = cTool.fBoardVector.at( 0 ); + MPA* cMPAChip = cBoard->fModuleVector.at(0)->fMPAVector.at(0); + cTool.setFWTestPulse(); + + std::chrono::milliseconds ShortWait( 10 ); + + cMPAInterface->PS_Clear_counters(cMPAChip); + cMPAInterface->PS_Clear_counters(cMPAChip); + std::ofstream pedestalfile; + pedestalfile.open("pedestal.txt"); +// std::pair<int, int> rows = {1,17}; //number of rows + std::pair<int, int> rows = {1,5}; // number of rows divided by 4 +// std::pair<int, int> cols = {1,120}; //number of cols + std::pair<int, int> cols = {1,31};// number of cols divided by 4 + std::pair<int, int> th = {0,255}; // change to 255 + int npulses = 1000; + + std::vector<TH1F*> scurves; + TH2F* scurve_2d = new TH2F("scurve_2d", "scurve_2d;Pixel [#];Threshold [VCth]", 2040, -0.5, 2039.5, th.second-th.first, th.first-0.5, th.second-0.5); + TH1F* noise_pedestal = new TH1F("noise_pedestal", "Noise pedestal; Noise pedestal [VCth];Entries", 80, 59.5, 139.5); + TH1F* noise_rms = new TH1F("noise_rms", "Noise RMS;Noise RMS [VCth];Entries", 100, -0.5, 9.5); + std::string title; + for(int row=1; row<17; row++)//enable and disable pixels? + { + for(int col=1; col<120; col++) + { + title = std::to_string(row)+","+std::to_string(col); + scurves.push_back(new TH1F(title.c_str(),title.c_str(),th.second-th.first, th.first-0.5, th.second-0.5)); // make a new scurve for this one + } + } + + + for(int calib = 0; calib < 32; calib++)// modify offsets + { + cMPAInterface->Activate_async(cMPAChip); + cMPAInterface->Set_calibration(cMPAChip, calib); // maybe this modifies individual dacs? + for(int rspacing = 0; rspacing < 4; rspacing ++)// spaces rows + { + for(int cspacing = 0; cspacing <4; cspacing ++) + { + uint32_t npixtot = 0; + cMPAInterface->Disable_pixel(cMPAChip,0,0); + int newrows; + int newcols; + for(int row=rows.first; row<rows.second; row++)//enable and disable pixels? + { + newrows = 4*row - rspacing; + if(newrows > 119) + { + } + else + { + for(int col=cols.first; col<cols.second; col++) + { + newcols = 4*col-cspacing; + std::cout<<"enable pix counter "<<newrows<<" "<<newcols<<std::endl; + cMPAInterface->Enable_pix_counter(cMPAChip, newrows, newcols); + npixtot+=1; + } + } + } + + std::cout <<"Numpix -- "<< npixtot <<std::endl; + std::vector<uint16_t> countersfifo;// start here next time, see how countersfifo needs to be modified so that appropriate coords are recorded FIXME need to look at newrow and newcol and put into appropriate locations + uint32_t totalevents = 0; + uint32_t totaleventsprev = 0; + uint32_t nrep = 0; + for(int ith=th.first;ith<th.second;ith++) + { + + int ithset=ith; // change from *4, why mod 250? + std::cout<<"VCth = "<<ithset<<std::endl; + std::cout<<ith<<std::endl; + cMPAInterface->Set_threshold(cMPAChip, ithset); + + std::this_thread::sleep_for( ShortWait ); + cMPAInterface->Send_pulses(cMPAChip, npulses); + std::this_thread::sleep_for( ShortWait ); + + //FIFO readout + countersfifo = cMPAInterface->ReadoutCounters_MPA(cMPAChip, 0); + + //Randomly the counters fail + //this fixes the issue but this needs to be looked at further + totalevents = std::accumulate(countersfifo.begin()+1, countersfifo.end(), 0); + std::cout<<totalevents<<std::endl; + if (totaleventsprev>50 and totalevents==0) + { + ith-=1; + nrep+=1; + std::cout<<"Repeat "<<nrep<<std::endl; + if (nrep<5) continue; + totaleventsprev = 0; + } + // fill the scurves, need to modify for new row and new col + for(int row=rows.first; row<rows.second; row++) { + newrows = 4*row - rspacing; + for(int col=cols.first; col<cols.second; col++) { + newcols = 4*col - cspacing; + if(newcols >119) + { + continue; + } + int scurve_id = (newrows-1)*(119)+ (newcols-1); + std::cout << scurve_id << std::endl; + std::cout << countersfifo[(newrows-1)*120+newcols-1]<<std::endl; + scurves[scurve_id]->SetBinContent(scurves[scurve_id]->FindBin(ithset), countersfifo[(newrows-1)*120 + newcols-1]); + std::cout << "finished" << scurve_id << std::endl; + } + } + + // fill 2d +/* for(int row = 0; row < 16; row++) { + for(int col = 0; col < 120; col++) { + scurve_2d->SetBinContent(row*120+col, ithset-th.first, countersfifo[row*120 + col]); + } + } +*/ nrep=0; + + cMPAInterface->PS_Clear_counters(cMPAChip, 8); + cMPAInterface->PS_Clear_counters(cMPAChip, 8); + totaleventsprev = totalevents; + } + } + } + + + // fit scurves + int count = 0; + for(TH1F* scurve : scurves) { + if (count > 1920) break; + else count++; + // get max + int i_max = scurve->GetMaximumBin(); + //LOG(INFO) << "name: " << scurve->GetName() << ", max bin: " << i_max; + // fit + std::string name = "fit_" + std::string(scurve->GetName()); + TF1* ff = new TF1(name.c_str(),"[2]*TMath::Erfc((x-[0])/[1])+[3]", scurve->GetBinCenter(i_max+10), scurve->GetBinCenter(scurve->GetNbinsX())); + ff->SetParLimits(0, scurve->GetBinCenter(i_max+10), scurve->GetBinCenter(scurve->GetNbinsX())); + ff->SetParameter(0, scurve->GetBinCenter(i_max+20)); + ff->SetParLimits(1, 0., 50.); + ff->SetParameter(1, 2); + ff->SetParLimits(2, 0., 5*npulses); + ff->SetParameter(2, npulses/2); + ff->SetParLimits(3, -10, npulses); + ff->SetParameter(3, 0.); + scurve->Fit(name.c_str(), "NRQ+"); + + noise_pedestal->Fill(ff->GetParameter(0)); + noise_rms->Fill(ff->GetParameter(1)); + pedestalfile<<"calib "<< calib << " " << ff->GetName()<< " " << ff->GetParameter(0)<< std::endl; + } + } +/* TFile *file = new TFile("scurves_mpa.root", "RECREATE"); + file->cd(); + + // maybe write all the histograms to the root file as well, or a text file, only looking for noise pedestal and rms + + TCanvas * c1 = new TCanvas("scurve_multi", "c1", 10, 10, 700, 500);//-c settings/D19CDescription.xml -f ../../Downloads/d19c_mpa_none_27022019.bin -i + + c1->cd(); + int ihist = 0; + for (auto& hist : scurves) + { + if (ihist==0) + { + hist->SetLineColor(1); + hist->SetTitle(";Thresh DAC;Counts"); + //hist->SetMaximum(40000); + hist->SetStats(0); + hist->Draw("L"); + } + else + { + hist->SetLineColor(ihist%60+1); + hist->Draw("sameL"); + } + ihist += 1; + } + c1->Write(); + + TCanvas * c2 = new TCanvas(scurve_2d->GetName(), "c2", 10, 10, 700, 500); + c2->cd(); + scurve_2d->Draw("colz"); + c2->Write(); + + TCanvas * c3 = new TCanvas(noise_pedestal->GetName(), "c3", 10, 10, 700, 500); + c3->cd(); + noise_pedestal->Draw(); + c3->Write(); + + TCanvas * c4 = new TCanvas(noise_rms->GetName(), "c4", 10, 10, 700, 500); + c4->cd(); + noise_rms->Draw(); + c4->Write(); + + file->Close(); +*/ +}//int main diff --git a/src/MPA_sync_test.cc b/src/MPA_sync_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..a728f868236a0a9de5dbf9f00c944c9f07872a71 --- /dev/null +++ b/src/MPA_sync_test.cc @@ -0,0 +1,143 @@ +//Simple test script to demonstrate use of middleware for the purposes of usercode development + +#include <cstring> +#include <iostream> +#include <fstream> +#include "../Utils/Utilities.h" +#include "../HWDescription/SSA.h" +#include "../HWDescription/Module.h" +#include "../HWDescription/BeBoard.h" +#include "../HWInterface/MPAInterface.h" +#include "../HWInterface/D19cFWInterface.h" +#include "../HWInterface/BeBoardInterface.h" +#include "../HWDescription/Definition.h" +#include "../HWDescription/FrontEndDescription.h" +#include "../Utils/Timer.h" +#include <inttypes.h> +#include "../Utils/argvparser.h" +#include "../Utils/ConsoleColor.h" +#include "../System/SystemController.h" +#include "../Utils/CommonVisitors.h" +#include "TH1.h" +#include "TCanvas.h" + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; + +using namespace std; +INITIALIZE_EASYLOGGINGPP + +int main( int argc, char* argv[] ) +{ + + + std::string cHWFile = "settings/HWDescription_MPA.xml"; + ofstream myfile; + //ofstream scurvecsv; + //scurvecsv.open ("scurvetemp.csv"); + + + SystemController mysyscontroller; + std::cout << "\nInitHW"; + mysyscontroller.InitializeHw( cHWFile ); + std::cout << "\nMPAI"; + MPAInterface* fMPAInterface = mysyscontroller.fMPAInterface; + std::cout << "\nBOARD"<<std::endl; + + BeBoard* pBoard = mysyscontroller.fBoardVector.at( 0 ); + MPA* mpa1 = pBoard->fModuleVector.at(0)->fMPAVector.at(0); + + + std::chrono::milliseconds LongPOWait( 500 ); + std::chrono::milliseconds ShortWait( 10 ); + + fMPAInterface->PS_Clear_counters(mpa1); + fMPAInterface->PS_Clear_counters(mpa1); + //fMPAInterface->activate_I2C_chip(); + + + + std::pair<uint32_t, uint32_t> rows = {0,17}; + std::pair<uint32_t, uint32_t> cols = {0,120}; + //std::pair<uint32_t, uint32_t> rows = {5,7}; + //std::pair<uint32_t, uint32_t> cols = {1,5}; + std::pair<uint32_t, uint32_t> th = {0,250}; + + std::vector<TH1F*> scurves; + std::string title; + + + + + + + uint32_t cdata = 0; + + uint32_t curpnum = 0; + uint32_t totalevents = 0; + uint32_t totaleventsprev = 0; + uint32_t nrep = 0; + std::cout <<"Setup"<< std::endl; + + fMPAInterface->Set_threshold(mpa1,100); + fMPAInterface->Activate_sync(mpa1); + fMPAInterface->Activate_pp(mpa1); + fMPAInterface->Set_calibration(mpa1,100); + Stubs curstub; + uint32_t npixtot = 0; + //mysyscontroller.fMPAInterface->Start ( pBoard ); + for(int row=rows.first; row<rows.second; row++) + { + for(int col=cols.first; col<cols.second; col++) + { + std::cout <<row<<","<<col<<std::endl; + fMPAInterface->Disable_pixel(mpa1,0,0); + std::this_thread::sleep_for( ShortWait ); + fMPAInterface->Enable_pix_BRcal(mpa1,row, col, "rise", "edge"); + std::this_thread::sleep_for( ShortWait ); + fMPAInterface->Send_pulses(mpa1,1); + std::this_thread::sleep_for( ShortWait ); + //fMPAInterface->ReadData ( pBoard ); + const std::vector<Event*>& events = mysyscontroller.GetEvents ( pBoard ); + + for ( auto& ev : events ) + { + std::cout<<"tst"<<std::endl; + } + + npixtot+=1; + } + } + //mysyscontroller.fMPAInterface->Stop ( pBoard ); + + std::cout <<"Numpix -- "<< npixtot <<std::endl; + + + TCanvas * c1 = new TCanvas("c1", "c1", 1000, 500); + int ihist = 0; + for (auto& hist : scurves) + { + //std::cout<<"drawing "<<ihist<<hist->>Integral()<<std::endl; + if (ihist==0) + { + hist->SetLineColor(1); + hist->SetTitle(";Thresh DAC;Counts"); + hist->SetMaximum(40000); + hist->SetStats(0); + hist->Draw("L"); + } + else + { + hist->SetLineColor(ihist%60+1); + hist->Draw("sameL"); + } + ihist += 1; + } + c1->Print("scurvetemp.root","root"); + + + std::this_thread::sleep_for( LongPOWait ); + +}//int main diff --git a/src/MPAthreshtest.cc b/src/MPAthreshtest.cc new file mode 100644 index 0000000000000000000000000000000000000000..23b44f2c11fe909ddc3edf43fb0b35db10199d3d --- /dev/null +++ b/src/MPAthreshtest.cc @@ -0,0 +1,342 @@ +#include <fstream> +#include <ios> +#include <cstring> + +#include "../Utils/Utilities.h" +#include "../System/SystemController.h" +#include "../Utils/CommonVisitors.h" +#include "../Utils/argvparser.h" +#include "../Utils/Timer.h" +#include "../tools/Tool.h" +#include "CtaFpgaConfig.h" +#include "TROOT.h" +#include "TApplication.h" + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; +INITIALIZE_EASYLOGGINGPP + +int main ( int argc, char** argv ) +{ + //configure the logger + el::Configurations conf ("settings/logger.conf"); + el::Loggers::reconfigureAllLoggers (conf); + ArgvParser cmd; + // init + cmd.setIntroductoryDescription ( "CMS Ph2_ACF d19c Testboard Firmware Test Application" ); + // error codes + cmd.addErrorCode ( 0, "Success" ); + cmd.addErrorCode ( 1, "Error" ); + // options + cmd.setHelpOption ( "h", "help", "Print this help page" ); + cmd.defineOption ( "file", "Hw Description File . Default value: settings/D19CHWDescription.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "file", "f" ); + cmd.defineOption ( "testpulse", "Check test pulse for different groups", ArgvParser::NoOptionAttribute ); + cmd.defineOptionAlternative ( "testpulse", "t" ); + cmd.defineOption ( "rate", "Measure maximal readout rate", ArgvParser::NoOptionAttribute ); + cmd.defineOptionAlternative ( "rate", "r" ); + cmd.defineOption ( "ipb_rate", "Measure maximal IPBus readout rate", ArgvParser::NoOptionAttribute ); + cmd.defineOptionAlternative ( "ipb_rate", "i" ); + cmd.defineOption ( "occupancy", "Measure 2S Occupancy", ArgvParser::NoOptionAttribute ); + cmd.defineOptionAlternative ( "occupancy", "m" ); + cmd.defineOption ( "output", "Output Directory . Default value: Results", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "output", "o" ); + cmd.defineOption ( "configure", "Configure HW", ArgvParser::NoOptionAttribute ); + cmd.defineOptionAlternative ( "configure", "c" ); + cmd.defineOption ( "save", "Save the data to a raw file. ", ArgvParser::OptionRequiresValue ); + cmd.defineOptionAlternative ( "save", "s" ); + cmd.defineOption ( "events", "Number of Events . Default value: 10000", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "events", "e" ); + cmd.defineOption ( "pkgsize", "Avg package size (for IPBus readout speed test)", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "pkgsize", "p" ); + cmd.defineOption ( "evtsize", "Avg event size (for IPBus readout speed test)", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "evtsize", "w" ); + cmd.defineOption ( "dqm", "Print every i-th event. ", ArgvParser::OptionRequiresValue ); + cmd.defineOptionAlternative ( "dqm", "d" ); + cmd.defineOption ( "mask", "Hybrid mask - default all enabled", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOption ( "hard_reset", "Hard Reset the board", ArgvParser::NoOptionAttribute ); + cmd.defineOption ( "ddr3test", "Test the on-board ddr3 chip", ArgvParser::NoOptionAttribute ); + + + int result = cmd.parse ( argc, argv ); + + if ( result != ArgvParser::NoParserError ) + { + LOG (INFO) << cmd.parseErrorDescription ( result ); + exit ( 1 ); + } + + bool cHardReset = ( cmd.foundOption ( "hard_reset" ) ) ? true : false; + bool cDDR3SelfTest = ( cmd.foundOption ( "ddr3test" ) ) ? true : false; + + bool cSaveToFile = false; + std::string cOutputFile; + + if ( cmd.foundOption ( "save" ) ) + cSaveToFile = true ; + + // now query the parsing results + std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CHWDescription.xml"; + + std::stringstream outp; + Tool cTool; + cTool.InitializeHw ( cHWFile, outp); + cTool.InitializeSettings ( cHWFile, outp ); + LOG (INFO) << outp.str(); + if ( cSaveToFile ) + { + cOutputFile = cmd.optionValue ( "save" ); + cTool.InitResultFile ( cOutputFile ); + } + if (!cHardReset) cTool.ConfigureHw (); + + BeBoard* pBoard = cTool.fBoardVector.at(0); + cTool.fBeBoardInterface->getBoardInfo(pBoard); + + bool cTestPulse = ( cmd.foundOption ( "testpulse" ) ) ? true : false; + bool cRate = ( cmd.foundOption ( "rate" ) ) ? true : false; + bool cIPB_Rate = ( cmd.foundOption ( "ipb_rate" ) ) ? true : false; + bool cOccupancy = ( cmd.foundOption ( "occupancy" ) ) ? true : false; + + if ( cHardReset ) { + cTool.fBeBoardInterface->RebootBoard(pBoard); + } else if ( cDDR3SelfTest ) { + cTool.fBeBoardInterface->setBoard ( pBoard->getBeBoardIdentifier() ); + dynamic_cast<D19cFWInterface*>(cTool.fBeBoardInterface->getFirmwareInterface())->DDR3SelfTest(); + //(D19cFWInterface*)(cTool.fBeBoardInterface->fBoardFW)->DDR3SelfTest(); + } else { + if ( cTestPulse ) + { + auto cSetting = cTool.fSettingsMap.find ( "TestPulsePotentiometer" ); + uint8_t cTestPulseAmplitude = ( cSetting != std::end ( cTool.fSettingsMap ) ) ? cSetting->second : 0x7F; + + uint32_t cNGroups = 8; + uint32_t cN = 0; + cTool.setFWTestPulse(); + + for (int i = 0; i < cNGroups; i++) + { + cTool.setSystemTestPulse(cTestPulseAmplitude,i,true,false); + cTool.ReadNEvents( pBoard, 1 ); + + const std::vector<Event*>& events = cTool.GetEvents ( pBoard ); + for ( auto& ev : events ) + { + LOG (INFO) << ">>> Event #" << cN++ ; + outp.str (""); + outp << *ev; + LOG (INFO) << outp.str(); + } + } + + } + + if ( cRate ) + { + + uint32_t cNEventsToCollect = ( cmd.foundOption ( "events" ) ) ? convertAnyInt ( cmd.optionValue ( "events" ).c_str() ) : 10000; + + // be careful works only for one hybrid + std::vector < Cbc* > cCbcVector = pBoard->getModule(0)->fCbcVector; + std::vector < MPA* > cMpaVector = pBoard->getModule(0)->fMPAVector; + uint32_t cChips = cCbcVector.size() + cMpaVector.size(); + + Timer t; + t.start(); + + + D19cFWInterface* d19cfw = (D19cFWInterface*)cTool.fBeBoardInterface->getFirmwareInterface(); + MPAInterface* fMPAInterface = cTool.fMPAInterface; + for(uint8_t ithresh=0;ithresh<50;ithresh++) + { + uint32_t cN = 0; + uint32_t count = 0; + uint8_t threshset = ((ithresh*5)%250); + double cAvgOccupancy = 0; + cTool.Start ( pBoard ); + LOG (INFO) << "Setting thresh: " << unsigned(threshset)<<std::endl; + fMPAInterface->Set_threshold(cMpaVector[0],threshset%250); + while ( cN < cNEventsToCollect ) + { + //std::cout<<cN%100<<std::endl; + //d19cfw->WriteReg("fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cN%100); + + + + + cTool.ReadData ( pBoard ); + const std::vector<Event*>& events = cTool.GetEvents ( pBoard ); + for ( auto& ev : events ) + { + + count++; + cN++; + + double cAvgOccupancyHyb0 = 0; + if (pBoard->getChipType() == ChipType::CBC3) { + for(auto cCbc: cCbcVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cCbc->getCbcId()); + } else if (pBoard->getChipType() == ChipType::MPA) { + for(auto cMpa: cMpaVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cMpa->getMPAId()); + } + + cAvgOccupancy += (cAvgOccupancyHyb0/cChips); + + + if ( cmd.foundOption ( "dqm" ) ) + { + if ( count % atoi ( cmd.optionValue ( "dqm" ).c_str() ) == 0 ) + { + LOG (INFO) << ">>> Event #" << count ; + outp.str (""); + outp << *ev << std::endl; + LOG (INFO) << outp.str(); + } + } + + if ( count % 10000 == 0 ) + LOG (INFO) << ">>> Recorded Event #" << count ; + break; + } + + } + LOG (INFO) << "Hits: " << cAvgOccupancy*cChips <<std::endl; + cTool.Stop ( pBoard ); + + t.stop(); + + } + } + + if ( cIPB_Rate ) + { + uint32_t cN = 0; + + uint32_t cNEventsToCollect = ( cmd.foundOption ( "events" ) ) ? convertAnyInt ( cmd.optionValue ( "events" ).c_str() ) : 10000; + uint32_t cPackageSize = ( cmd.foundOption ( "pkgsize" ) ) ? convertAnyInt ( cmd.optionValue ( "pkgsize" ).c_str() ) : 100; + uint32_t cEvtSize = ( cmd.foundOption ( "evtsize" ) ) ? convertAnyInt ( cmd.optionValue ( "evtsize" ).c_str() ) : 94; + + + Timer t; + t.start(); + + while ( cN < cNEventsToCollect ) + { + cTool.fBeBoardInterface->ReadBlockBoardReg(pBoard, "fc7_daq_ctrl.readout_block.readout_fifo", cPackageSize*cEvtSize); + cN += cPackageSize; + } + cTool.Stop ( pBoard ); + + t.stop(); + LOG (INFO) << "Measured maximal IPBus readout rate: " << (double)(cN/t.getElapsedTime())/1000 << "kHz (based on " << +cN << " events, avg package size: " << +cPackageSize << " events, avg event size: " << +cEvtSize << " words)"; + } + + // measures the 2s occupancy + if (cOccupancy) { + // init + LOG(INFO) << "Initating occupancy meauserement"; + uint32_t cNEventsToCollect = ( cmd.foundOption ( "events" ) ) ? convertAnyInt ( cmd.optionValue ( "events" ).c_str() ) : 200; + + // get fw interface + D19cFWInterface* d19cfw = (D19cFWInterface*)cTool.fBeBoardInterface->getFirmwareInterface(); + + // init threshold visitior + ThresholdVisitor cThresholdVisitor (cTool.fCbcInterface, 0); + cTool.accept (cThresholdVisitor); + auto cFe0 = pBoard->fModuleVector.at(0); + + // hybrid mask + uint32_t cHybridMask = ( cmd.foundOption ( "mask" ) ) ? convertAnyInt ( cmd.optionValue ( "mask" ).c_str() ) : 0xFFFFFFFF;; + d19cfw->WriteReg("fc7_daq_cnfg.calibration_2s_block.enable_hybrids", cHybridMask); + + // + uint32_t cThresholdMin = 400; + uint32_t cThresholdMax = 800; + + // create counters + uint8_t ***cChannelCounters = nullptr; + uint8_t **cErrorCounters = nullptr; + // allocate memory + d19cfw->Manage2SCountersMemory(cErrorCounters, cChannelCounters, true); + + // start time counting + Timer t; + t.start(); + + bool doScan = true; + if (!doScan) { + // measure + d19cfw->Measure2SOccupancy(cNEventsToCollect, cErrorCounters, cChannelCounters); + + // debug test + //for(uint8_t ch = 0; ch < NCHANNELS; ch++) std::cout << "Ch: " << +ch << ", Counter: " << +cChannelCounters[0][0][ch] << std::endl; + + } else { + + bool useCounters = true; + + LOG(INFO) << "Mode: " << (useCounters ? "2S Counters" : "Conventional"); + + // do threshokd scan + for (uint32_t cThreshold = cThresholdMin; cThreshold < cThresholdMax; cThreshold++) { + + // set threshold + for(auto& cCbc : cFe0->fCbcVector) { + cThresholdVisitor.setThreshold(cThreshold); + cCbc->accept(cThresholdVisitor); + } + + // measure (equvuvalient tasks) + if (useCounters) { + d19cfw->Measure2SOccupancy(cNEventsToCollect, cErrorCounters, cChannelCounters); + } else { + cTool.ReadNEvents( pBoard, cNEventsToCollect ); + const std::vector<Event*>& events = cTool.GetEvents ( pBoard ); + for ( auto& ev : events ) { + for(auto& cFe : pBoard->fModuleVector) { + for(auto& cCbc : cFe->fCbcVector) { + for(uint8_t ch = 0; ch < NCHANNELS; ch++) { + if (ev->DataBit(cFe->getFeId(), cCbc->getCbcId(), ch)) + cChannelCounters[cFe->getFeId()][cCbc->getCbcId()][ch]++; + } + } + } + } + + } + + // debug output + std::cout << "th" << cThreshold << ":\t"; + for(uint8_t ch = 0; ch < 16; ch++) std::cout << +cChannelCounters[0][0][ch] << "\t"; + std::cout << std::endl; + + // reset the counters + for(auto& cFe : pBoard->fModuleVector) { + for(auto& cCbc : cFe->fCbcVector) { + for(uint8_t ch = 0; ch < NCHANNELS; ch++) { + cChannelCounters[cFe->getFeId()][cCbc->getCbcId()][ch] = 0; + } + } + } + + } + + t.stop(); + + // print + LOG(INFO) << "Time spent for SCurves: " << 1000*t.getElapsedTime()/(cThresholdMax-cThresholdMin) << " mililiseconds per point (" << cThresholdMax-cThresholdMin << " points)"; + } + + // release memory + d19cfw->Manage2SCountersMemory(cErrorCounters, cChannelCounters, false); + } + } + + LOG (INFO) << "*** End of the DAQ test ***" ; + cTool.SaveResults(); + cTool.CloseResultFile(); + cTool.Destroy(); + + return 0; +} diff --git a/src/MuModdaqtest.cc b/src/MuModdaqtest.cc index d8ff995eb984b119150b778a9aaa55773b220984..220c0d7895a5fd1637b99a8eb95448a621dc8150 100644 --- a/src/MuModdaqtest.cc +++ b/src/MuModdaqtest.cc @@ -1,5 +1,5 @@ -//Simple bare bones daq to be used as a template for the +//Simple bare bones daq to be used as a template for the //relevant sections of usercode in order to test the middleware @@ -7,11 +7,11 @@ #include <fstream> #include "../Utils/Utilities.h" #include "../HWDescription/Cbc.h" -#include "../HWDescription/MPA.h" +#include "../HWDescription/MPAlight.h" #include "../HWDescription/Module.h" #include "../HWDescription/BeBoard.h" -#include "../HWInterface/MPAInterface.h" -#include "../HWInterface/MPAGlibFWInterface.h" +#include "../HWInterface/MPAlightInterface.h" +#include "../HWInterface/MPAlightGlibFWInterface.h" #include "../HWInterface/CbcInterface.h" #include "../HWInterface/BeBoardInterface.h" #include "../HWDescription/Definition.h" @@ -59,39 +59,39 @@ int main( int argc, char* argv[] ) std::cout << "\nInitHW"; mysyscontroller.InitializeHw( cHWFile ); std::cout << "\nMPAI"; - MPAInterface* fMPAInterface = mysyscontroller.fMPAInterface; + MPAlightInterface* fMPAlightInterface = mysyscontroller.fMPAlightInterface; std::cout << "\nBOARD"<<std::endl; BeBoard* pBoard = mysyscontroller.fBoardVector.at( 0 ); - + uint8_t pBeId = 0; uint8_t pFMCId = 0; //One BE board, multiple FE's for module. Cside identifies whether the firmware accesses the left - //or right six MPAs + //or right six MPAlights //Left uint8_t pFeId = 0; int cside=1; - Module* MAPSAR = new Module(); + Module* MAPSAR = new Module(); for (int i=0;i<6;i++) { - MAPSAR->addMPA(new MPA(pBeId, pFMCId, pFeId, i, cside)); + MAPSAR->addMPAlight(new MPAlight(pBeId, pFMCId, pFeId, i, cside)); } - uint8_t nummpaR =MAPSAR->getNMPA(); + uint8_t nummpaR =MAPSAR->getNMPAlight(); //Right pFeId = 1; cside=0; - Module* MAPSAL = new Module(); + Module* MAPSAL = new Module(); for (int i=0;i<6;i++) { - MAPSAL->addMPA(new MPA(pBeId, pFMCId, pFeId, i, cside)); + MAPSAL->addMPAlight(new MPAlight(pBeId, pFMCId, pFeId, i, cside)); } - uint8_t nummpaL =MAPSAL->getNMPA(); + uint8_t nummpaL =MAPSAL->getNMPAlight(); std::cout<<"Number of MPAs in Left MAPSA "<<int(nummpaL)<<std::endl; @@ -100,18 +100,18 @@ int main( int argc, char* argv[] ) //Add both modules to the BE board pBoard->addModule(MAPSAL); pBoard->addModule(MAPSAR); - - //Power on and check FW version. These do not need to be called every time datataking begins. + + //Power on and check FW version. These do not need to be called every time datataking begins. std::cout << "\nExecuting POWER ON..."; mysyscontroller.fBeBoardInterface->PowerOn(pBoard); - std::cout << "\nFirmware version: "; + std::cout << "\nFirmware version: "; mysyscontroller.fBeBoardInterface->ReadVer(pBoard); std::chrono::milliseconds cWait( 10 ); - //Initialize configuration data + //Initialize configuration data std::vector<std::vector< uint32_t >> confsR; std::vector<std::vector< uint32_t >> confsL; @@ -125,30 +125,30 @@ int main( int argc, char* argv[] ) int curside; for(int i=0;i<nummpaR;i++) { - MPA* curmpa = (MAPSAR->getMPA(i)); - curside =int(curmpa->getMPASide()); + MPAlight* curmpa = (MAPSAR->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); std::this_thread::sleep_for( cWait ); - confsR.push_back(fMPAInterface->ReadConfig("calibratedRight", i+1, 1)); - fMPAInterface->ModifyPerif(mod1,&confsR.back()); - fMPAInterface->ConfigureMPA(&confsR.back(), 1 , i+1 , curside); + confsR.push_back(fMPAlightInterface->ReadConfig("calibratedRight", i+1, 1)); + fMPAlightInterface->ModifyPerif(mod1,&confsR.back()); + fMPAlightInterface->ConfigureMPAlight(&confsR.back(), 1 , i+1 , curside); } for(int i=0;i<nummpaL;i++) { - MPA* curmpa = (MAPSAL->getMPA(i)); - curside =int(curmpa->getMPASide()); + MPAlight* curmpa = (MAPSAL->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); std::this_thread::sleep_for( cWait ); - confsL.push_back(fMPAInterface->ReadConfig("calibratedLeft", i+1, 1)); - fMPAInterface->ModifyPerif(mod1,&confsL.back()); - fMPAInterface->ConfigureMPA(&confsL.back(), 1 , i+1 , curside); + confsL.push_back(fMPAlightInterface->ReadConfig("calibratedLeft", i+1, 1)); + fMPAlightInterface->ModifyPerif(mod1,&confsL.back()); + fMPAlightInterface->ConfigureMPAlight(&confsL.back(), 1 , i+1 , curside); } - //Transfer configuration information to MPAs after loading - fMPAInterface->SendConfig(nummpaL,nummpaR); + //Transfer configuration information to MPAlights after loading + fMPAlightInterface->SendConfig(nummpaL,nummpaR); std::chrono::milliseconds cWait1( 100 );// int ibuffer = 1; @@ -156,8 +156,8 @@ int main( int argc, char* argv[] ) //Option 1 just takes data continuously, option 2 waits for triggers - fMPAInterface->SequencerInit(1,200000,1,0); - //fMPAInterface->TestbeamInit(500000,0, 0); + fMPAlightInterface->SequencerInit(1,200000,1,0); + //fMPAlightInterface->TestbeamInit(500000,0, 0); //Always four buffers in current FW @@ -167,31 +167,31 @@ int main( int argc, char* argv[] ) //Release all data currently stored before taking new data for(int i=0;i<nummpaR;i++) { - MPA* curmpa = (MAPSAR->getMPA(i)); - curside =int(curmpa->getMPASide()); + MPAlight* curmpa = (MAPSAR->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); std::this_thread::sleep_for( cWait ); for(int k=1;k<=nbuffers;k++) { - fMPAInterface->HeaderInitMPA(i+1,curside); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAInterface->ReadMPAData(k,i+1,curside); - fMPAInterface->ReadTrig(k); + fMPAlightInterface->HeaderInitMPAlight(i+1,curside); + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAlightInterface->ReadMPAlightData(k,i+1,curside); + fMPAlightInterface->ReadTrig(k); } } for(int i=0;i<nummpaL;i++) { - MPA* curmpa = (MAPSAL->getMPA(i)); - curside =int(curmpa->getMPASide()); + MPAlight* curmpa = (MAPSAL->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); std::this_thread::sleep_for( cWait ); for(int k=1;k<=nbuffers;k++) { - fMPAInterface->HeaderInitMPA(i+1,curside); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAInterface->ReadMPAData(k,i+1,curside); - fMPAInterface->ReadTrig(k); + fMPAlightInterface->HeaderInitMPAlight(i+1,curside); + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAlightInterface->ReadMPAlightData(k,i+1,curside); + fMPAlightInterface->ReadTrig(k); } } - fMPAInterface->Cleardata(); + fMPAlightInterface->Cleardata(); @@ -211,25 +211,25 @@ int main( int argc, char* argv[] ) { tempspill=spill; - spill+=fMPAInterface->WaitTestbeam(); + spill+=fMPAlightInterface->WaitTestbeam(); if (tempspill!=spill) std::cout<<"Starting Spill "<<spill<<std::endl; - fMPAInterface->Cleardata(); - fMPAInterface->ReadTrig(ibuffer); + fMPAlightInterface->Cleardata(); + fMPAlightInterface->ReadTrig(ibuffer); for(int i=0;i<nummpaL;i++) { - MPA* curmpa = (MAPSAL->getMPA(i)); - curside =int(curmpa->getMPASide()); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAInterface->ReadMPAData(ibuffer,i+1,curside); + MPAlight* curmpa = (MAPSAL->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAlightInterface->ReadMPAlightData(ibuffer,i+1,curside); } for(int i=0;i<nummpaR;i++) { - MPA* curmpa = (MAPSAR->getMPA(i)); - curside =int(curmpa->getMPASide()); - std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAInterface->ReadMPAData(ibuffer,i+1,curside); + MPAlight* curmpa = (MAPSAR->getMPAlight(i)); + curside =int(curmpa->getMPAlightSide()); + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> returndata = fMPAlightInterface->ReadMPAlightData(ibuffer,i+1,curside); } @@ -239,16 +239,16 @@ int main( int argc, char* argv[] ) nev+=1; if (nev%100==0) std::cout<<nev<<" Events"<<std::endl; - + //For testing puroses, output all collected data - std::vector<uint32_t> cData = *(fMPAInterface->GetcurData()); + std::vector<uint32_t> cData = *(fMPAlightInterface->GetcurData()); int iic1 = 0; for( unsigned int iic1=0;iic1<cData.size();iic1++) { outFile_.write( (char*)&cData.at(iic1), sizeof(uint32_t)); - + } @@ -258,4 +258,3 @@ int main( int argc, char* argv[] ) }//while (not Kill) outFile_.close(); }//int main - diff --git a/src/calibrate.cc b/src/calibrate.cc deleted file mode 100644 index 79fb39ee60f771241ffa12614a6c971df5e8481f..0000000000000000000000000000000000000000 --- a/src/calibrate.cc +++ /dev/null @@ -1,146 +0,0 @@ -#include <cstring> -#include "../HWDescription/Cbc.h" -#include "../HWDescription/Module.h" -#include "../HWDescription/BeBoard.h" -#include "../HWInterface/CbcInterface.h" -#include "../HWInterface/BeBoardInterface.h" -#include "../HWDescription/Definition.h" -#include "../tools/Calibration.h" -#include "../tools/PedeNoise.h" -#include "../Utils/argvparser.h" -#include "TROOT.h" -#include "TApplication.h" -#include "../Utils/Timer.h" - - -using namespace Ph2_HwDescription; -using namespace Ph2_HwInterface; -using namespace Ph2_System; -using namespace CommandLineProcessing; - -INITIALIZE_EASYLOGGINGPP - -int main ( int argc, char* argv[] ) -{ - //configure the logger - el::Configurations conf ("settings/logger.conf"); - el::Loggers::reconfigureAllLoggers (conf); - - ArgvParser cmd; - - // init - cmd.setIntroductoryDescription ( "CMS Ph2_ACF calibration routine using K. Uchida's algorithm or a fast algorithm" ); - // error codes - cmd.addErrorCode ( 0, "Success" ); - cmd.addErrorCode ( 1, "Error" ); - // options - cmd.setHelpOption ( "h", "help", "Print this help page" ); - - cmd.defineOption ( "file", "Hw Description File . Default value: settings/Calibration8CBC.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "file", "f" ); - - cmd.defineOption ( "output", "Output Directory . Default value: Results", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "output", "o" ); - - cmd.defineOption ( "skip", "skip scaning VCth vs Vplus", ArgvParser::NoOptionAttribute ); - cmd.defineOptionAlternative ( "skip", "s" ); - - //cmd.defineOption( "old", "Use old calibration algorithm", ArgvParser::NoOptionAttribute ); - //cms.defineOptionAlternative ("old", "v" ); - - cmd.defineOption ( "noise", "Perform noise scan after Offset tuning", ArgvParser::NoOptionAttribute ); - cmd.defineOptionAlternative ( "noise", "n" ); - - cmd.defineOption ( "allChan", "Do calibration using all channels? Default: false", ArgvParser::NoOptionAttribute ); - cmd.defineOptionAlternative ( "allChan", "a" ); - - cmd.defineOption ( "batch", "Run the application in batch mode", ArgvParser::NoOptionAttribute ); - cmd.defineOptionAlternative ( "batch", "b" ); - - - int result = cmd.parse ( argc, argv ); - - if ( result != ArgvParser::NoParserError ) - { - LOG (INFO) << cmd.parseErrorDescription ( result ); - exit ( 1 ); - } - - // now query the parsing results - std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/Calibration8CBC.xml"; - std::string cDirectory = ( cmd.foundOption ( "output" ) ) ? cmd.optionValue ( "output" ) : "Results/"; - cDirectory += "Calibration"; - bool cVplus = ( cmd.foundOption ( "skip" ) ) ? false : true; - //bool cOld = ( cmd.foundOption( "old" ) ) ? true : false; - - bool cAllChan = ( cmd.foundOption ( "allChan" ) ) ? true : false; - bool batchMode = ( cmd.foundOption ( "batch" ) ) ? true : false; - bool cNoiseScan = ( cmd.foundOption ("noise") ) ? true : false; - - TApplication cApp ( "Root Application", &argc, argv ); - - if ( batchMode ) gROOT->SetBatch ( true ); - else TQObject::Connect ( "TCanvas", "Closed()", "TApplication", &cApp, "Terminate()" ); - - Timer t; - - //create a genereic Tool Object, I can then construct all other tools from that using the Inherit() method - //this tool stays on the stack and lives until main finishes - all other tools will update the HWStructure from cTool - Tool cTool; - std::stringstream outp; - cTool.InitializeHw ( cHWFile, outp ); - cTool.InitializeSettings ( cHWFile, outp ); - LOG (INFO) << outp.str(); - outp.str (""); - cTool.ConfigureHw (); - cTool.CreateResultDirectory ( cDirectory ); - cTool.InitResultFile ( "CalibrationResults" ); - cTool.StartHttpServer(); - //cTool.ConfigureHw (); - //if ( !cOld ) - //{ - t.start(); - - // now create a calibration object - Calibration cCalibration; - cCalibration.Inherit (&cTool); - //second parameter disables stub logic on CBC3 - cCalibration.Initialise ( cAllChan, true ); - - if ( cVplus ) cCalibration.FindVplus(); - - cCalibration.FindOffsets(); - cCalibration.writeObjects(); - cCalibration.dumpConfigFiles(); - t.stop(); - t.show ( "Time to Calibrate the system: " ); - - if (cNoiseScan) - { - t.start(); - //if this is true, I need to create an object of type PedeNoise from the members of Calibration - //tool provides an Inherit(Tool* pTool) for this purpose - PedeNoise cPedeNoise; - cPedeNoise.Inherit (&cTool); - //second parameter disables stub logic on CBC3 - cPedeNoise.Initialise (cAllChan, true); // canvases etc. for fast calibration - cPedeNoise.measureNoise(); - - //cPedeNoise.sweepSCurves (225); - //cPedeNoise.sweepSCurves (205); - - cPedeNoise.Validate(); - cPedeNoise.writeObjects( ); - cPedeNoise.dumpConfigFiles(); - t.stop(); - t.show ( "Time to Scan Pedestals and Noise" ); - } - - cTool.SaveResults(); - cTool.CloseResultFile(); - cTool.Destroy(); - - if ( !batchMode ) cApp.Run(); - - return 0; -} diff --git a/src/d19c_mpa_power_utility.cc b/src/d19c_mpa_power_utility.cc new file mode 100644 index 0000000000000000000000000000000000000000..f2520fbf62fe4151ad36fbdb77be9e144e6efc4b --- /dev/null +++ b/src/d19c_mpa_power_utility.cc @@ -0,0 +1,85 @@ +#include <fstream> +#include <ios> +#include <cstring> + +#include "../Utils/Utilities.h" +#include "../System/SystemController.h" +#include "../Utils/CommonVisitors.h" +#include "../Utils/argvparser.h" +#include "../Utils/Timer.h" +#include "../tools/Tool.h" +#include "CtaFpgaConfig.h" +#include "TROOT.h" +#include "TApplication.h" + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; +INITIALIZE_EASYLOGGINGPP + +int main ( int argc, char** argv ) +{ + //configure the logger + el::Configurations conf ("settings/logger.conf"); + el::Loggers::reconfigureAllLoggers (conf); + ArgvParser cmd; + // init + cmd.setIntroductoryDescription ( "CMS Ph2_ACF d19c MPA power management utility" ); + // error codes + cmd.addErrorCode ( 0, "Success" ); + cmd.addErrorCode ( 1, "Error" ); + // options + cmd.setHelpOption ( "h", "help", "Print this help page" ); + cmd.defineOption ( "file", "Hw Description File . Default value: settings/D19CHWDescription.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); + cmd.defineOptionAlternative ( "file", "f" ); + cmd.defineOption ( "power_on", "Power On the MPA chip", ArgvParser::NoOptionAttribute ); + cmd.defineOption ( "power_off", "Power Off the MPA chip", ArgvParser::NoOptionAttribute ); + + int result = cmd.parse ( argc, argv ); + + if ( result != ArgvParser::NoParserError ) + { + LOG (INFO) << cmd.parseErrorDescription ( result ); + exit ( 1 ); + } + + // now query the parsing results + std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CHWDescription.xml"; + + // defines what to do with a chip + bool cPowerOff = ( cmd.foundOption ( "power_off" ) ) ? true : false; + bool cPowerOn = ( cmd.foundOption ( "power_on" ) ) ? true : false; + + std::stringstream outp; + SystemController cSystemController; + cSystemController.InitializeHw ( cHWFile, outp); + cSystemController.InitializeSettings ( cHWFile, outp ); + LOG (INFO) << outp.str(); + //cSystemController.ConfigureHw (true); + + BeBoard* pBoard = cSystemController.fBoardVector.at(0); + cSystemController.fBeBoardInterface->getBoardInfo(pBoard); + + if ( cPowerOff ) { + LOG (INFO) << "Powering Off the Chip" ; + cSystemController.fMPAInterface->PowerOff(); + std::this_thread::sleep_for (std::chrono::milliseconds (500) ); + LOG (INFO) << "Powering Off the Board" ; + cSystemController.fMPAInterface->MainPowerOff(); + } + else if ( cPowerOn ) { + LOG (INFO) << "Powering On the Board" ; + cSystemController.fMPAInterface->MainPowerOn(); + std::this_thread::sleep_for (std::chrono::milliseconds (500) ); + LOG (INFO) << "Powering On the Chip" ; + cSystemController.fMPAInterface->PowerOn(); + } else { + LOG (INFO) << "No command specified"; + } + + LOG (INFO) << "*** Power Utility Done ***" ; + cSystemController.Destroy(); + + return 0; +} diff --git a/src/d19c_test.cc b/src/d19c_test.cc index eb51c8a369bb267fb1bd7650228cf2e35be3160f..d8d45e3f60961ff31ce0a7df1ac80db3e28df7e6 100644 --- a/src/d19c_test.cc +++ b/src/d19c_test.cc @@ -143,7 +143,8 @@ int main ( int argc, char** argv ) // be careful works only for one hybrid std::vector < Cbc* > cCbcVector = pBoard->getModule(0)->fCbcVector; - uint32_t cNCbc = cCbcVector.size(); + std::vector < MPA* > cMpaVector = pBoard->getModule(0)->fMPAVector; + uint32_t cChips = cCbcVector.size() + cMpaVector.size(); Timer t; t.start(); @@ -161,8 +162,12 @@ int main ( int argc, char** argv ) cN++; double cAvgOccupancyHyb0 = 0; - for(auto cCbc: cCbcVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cCbc->getCbcId()); - cAvgOccupancy += (cAvgOccupancyHyb0/cNCbc); + if (pBoard->getChipType() == ChipType::CBC3) { + for(auto cCbc: cCbcVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cCbc->getCbcId()); + } else if (pBoard->getChipType() == ChipType::MPA) { + for(auto cMpa: cMpaVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cMpa->getMPAId()); + } + cAvgOccupancy += (cAvgOccupancyHyb0/cChips); if ( cmd.foundOption ( "dqm" ) ) { diff --git a/src/eudaqproducer.cc b/src/eudaqproducer.cc new file mode 100644 index 0000000000000000000000000000000000000000..156d3b7983e7ec95c1468c2f7803e9e8f30fb200 --- /dev/null +++ b/src/eudaqproducer.cc @@ -0,0 +1,422 @@ +#include "eudaq/Configuration.hh" +#include "eudaq/Producer.hh" +#include "eudaq/Logger.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/Timer.hh" +#include "eudaq/Utils.hh" +#include "eudaq/OptionParser.hh" +#include <iostream> +#include <ostream> +#include <vector> + +#include "../Utils/Utilities.h" +#include "../System/SystemController.h" +#include "../Utils/argvparser.h" + +// A name to identify the raw data format of the events generated +// Modify this to something appropriate for your producer. +static const std::string EUDAQ_EVENT_TYPE = "Ph2Event"; + +using namespace Ph2_HwDescription; +using namespace Ph2_HwInterface; +using namespace Ph2_System; +using namespace CommandLineProcessing; +INITIALIZE_EASYLOGGINGPP + +// Declare a new class that inherits from eudaq::Producer +class Ph2Producer : public eudaq::Producer { + public: + + // The constructor must call the eudaq::Producer constructor with the name + // and the runcontrol connection string, and initialize any member variables. + Ph2Producer(const std::string & name, const std::string & runcontrol, const std::string & pHWFile) + : eudaq::Producer(name, runcontrol), + m_run(0), m_ev(0), stopping(false), done(false), started(0), configured(false), fSystemController(0), fHWFile(pHWFile) { + } + + ~Ph2Producer() { + if(fSystemController) { + fSystemController->Destroy(); + delete fSystemController; + } + } + + // This gets called whenever the DAQ is configured + virtual void OnConfigure(const eudaq::Configuration & config) { + LOG(INFO) << "Configuring: " << config.Name(); + + // to re-initialize everything better delete SystemController + if(fSystemController) { + fSystemController->Destroy(); + delete fSystemController; + } + fSystemController = new SystemController; + + std::stringstream outp; + fSystemController->InitializeHw ( fHWFile, outp ); + LOG (INFO) << outp.str(); + outp.str (""); + fSystemController->ConfigureHw (); + fHandshakeEnabled = (fSystemController->fBeBoardInterface->ReadBoardReg(fSystemController->fBoardVector.at(0), "fc7_daq_cnfg.readout_block.global.data_handshake_enable") > 0); + + configured = true; + + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Configured (" + config.Name() + ")"); + } + + // This gets called whenever a new run is started + // It receives the new run number as a parameter + virtual void OnStartRun(unsigned param) { + m_run = param; + m_ev = 0; + + LOG(INFO) << "Start Run: " << m_run; + + // It must send a BORE to the Data Collector + eudaq::RawDataEvent bore(eudaq::RawDataEvent::BORE(EUDAQ_EVENT_TYPE, m_run)); + + // Send the event to the Data Collector + SendEvent(bore); + + // finally start the run + for(auto cBoard : fSystemController->fBoardVector) { + fSystemController->fBeBoardInterface->Start(cBoard); + } + + LOG(INFO) << "Run Started, number of trigger received so far: " << +fSystemController->fBeBoardInterface->ReadBoardReg(fSystemController->fBoardVector.at(0), "fc7_daq_stat.fast_command_block.trigger_in_counter"); + + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Running"); + started=true; + } + + // This gets called whenever a run is stopped + virtual void OnStopRun() { + LOG(INFO) << "Stopping Run: " << m_run; + + // Set a flag to signal to the polling loop that the run is over + stopping = true; + + // finally stop the run + for(auto cBoard : fSystemController->fBoardVector) { + fSystemController->fBeBoardInterface->Stop(cBoard); + } + + // wait until all events have been read out from the hardware + while (stopping) { + eudaq::mSleep(20); + } + + started=false; + + // Send an EORE after all the real events have been sent + SendEvent(eudaq::RawDataEvent::EORE("Run Stopped", m_run, ++m_ev)); + + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Stopped"); + + LOG(INFO) << "Run Stopped, number of trigger received so far: " << +fSystemController->fBeBoardInterface->ReadBoardReg(fSystemController->fBoardVector.at(0), "fc7_daq_stat.fast_command_block.trigger_in_counter"); + } + + // This gets called when the Run Control is terminating, + // we should also exit. + virtual void OnTerminate() { + LOG(INFO) << "Terminating..."; + done = true; + } + + // This is just an example, adapt it to your hardware + void ReadoutLoop() { + // Loop until Run Control tells us to terminate + while (!done) { + if (!EventsPending()) { + // No events are pending, so check if the run is stopping + if (stopping) { + // if so, signal that there are no events left + stopping = false; + } + // Now sleep for a bit, to prevent chewing up all the CPU + eudaq::mSleep(20); + // Then restart the loop + continue; + } + + if (!started) + { + // Now sleep for a bit, to prevent chewing up all the CPU + eudaq::mSleep(20); + // Then restart the loop + continue; + } + + // If we get here, there must be data to read out + // FIXME FIXME It shouldn't iterate through boards like this, because then it'll construct events from different boards as different events + for(auto cBoard : fSystemController->fBoardVector) { + uint32_t cPacketSize = fSystemController->ReadData ( cBoard ); + const std::vector<Event*> cEvents = fSystemController->GetEvents ( cBoard ); + + for ( auto cEvent : cEvents ) + { + // Create a RawDataEvent to contain the event data to be sent + eudaq::RawDataEvent ev(EUDAQ_EVENT_TYPE, m_run, m_ev); + + // Convert Ph2 Acf to EUDAQ event + this->ConvertEvent(cBoard, cEvent, &ev); + + // Send the event to the Data Collector + SendEvent(ev); + // Now increment the event number + m_ev++; + } + + LOG(INFO) << "Got " << +cPacketSize << " events. Current effective occupancy (NHits/NEvents) is " << (float)fHitsCounter/m_ev; + } + + LOG(INFO) << "Built events counter is: " << m_ev; + } + } + + void ConvertEvent(const BeBoard* pBoard, const Event* pPh2Event, eudaq::RawDataEvent *pEudaqEvent) + { + pEudaqEvent->SetTag("L1_COUNTER_BOARD",pPh2Event->GetEventCount()); + pEudaqEvent->SetTag("TDC",pPh2Event->GetTDC()); + pEudaqEvent->SetTag("BX_COUNTER",pPh2Event->GetBunch()); + pEudaqEvent->SetTag("TLU_TRIGGER_ID",pPh2Event->GetTLUTriggerID()); + + // each Module reads out 2 sensors, 2*i - bottom one, 2*i+1 - top one + uint32_t cSensorId = 0; + for(auto cFe : pBoard->fModuleVector) { + std::vector<unsigned char> top_channel_data; + std::vector<unsigned char> bottom_channel_data; + size_t top_offset = 0, bottom_offset = 0; + std::vector<unsigned char> top_data_final(6); + std::vector<unsigned char> bottom_data_final(6); + + int cRealChipNumber = -1; + + // parsing cbc data (cbc2 or cbc3) + if (pBoard->getChipType() == ChipType::CBC3) { + uint32_t cFirstCbcId = cFe->fCbcVector.at(0)->getCbcId(); + for(auto cCbc : cFe->fCbcVector) { + int cChipId = (int)cCbc->getCbcId(); + const std::vector<uint32_t> cHitsVector = pPh2Event->GetHits(cCbc->getFeId(),cCbc->getCbcId()); + fHitsCounter += pPh2Event->GetNHits(cCbc->getFeId(),cCbc->getCbcId()); + for (auto hit : cHitsVector) { + if( hit%2 == 0 ) { + //top sensor + top_channel_data.resize(top_offset+6); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 0], ((cChipId-cFirstCbcId)*NCHANNELS/2) + hit/2); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 2], 0); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 4], 1); + top_offset += 6; + } + else { + //bottom sensor + bottom_channel_data.resize(bottom_offset+6); + eudaq::setlittleendian<unsigned short>(&bottom_channel_data[bottom_offset + 0], ((cChipId-cFirstCbcId)*NCHANNELS/2) + (hit-1)/2); + eudaq::setlittleendian<unsigned short>(&bottom_channel_data[bottom_offset + 2], 0); + eudaq::setlittleendian<unsigned short>(&bottom_channel_data[bottom_offset + 4], 1); + bottom_offset += 6; + } + } + + //as we want to really know the position of hit, we'll not skip disabled chips, and set N cbc's to the maximal chip id. + if (cChipId > cRealChipNumber) { + cRealChipNumber = cChipId; + } + } + cRealChipNumber = cRealChipNumber + 1 - cFirstCbcId; + + eudaq::setlittleendian<unsigned short>(&top_data_final[0], (NCHANNELS/2) * cRealChipNumber); + eudaq::setlittleendian<unsigned short>(&top_data_final[2], 1); + unsigned short numhits_top = (top_channel_data.size()) / 6; + eudaq::setlittleendian<unsigned short>(&top_data_final[4], 0x8000 | numhits_top); + top_data_final.insert(top_data_final.end(), top_channel_data.begin(), top_channel_data.end()); + pEudaqEvent->AddBlock(cSensorId,top_data_final); + + eudaq::setlittleendian<unsigned short>(&bottom_data_final[0], (NCHANNELS/2) * cRealChipNumber); + eudaq::setlittleendian<unsigned short>(&bottom_data_final[2], 1); + unsigned short numhits_bottom = (bottom_channel_data.size()) / 6; + eudaq::setlittleendian<unsigned short>(&bottom_data_final[4], 0x8000 | numhits_bottom); + bottom_data_final.insert(bottom_data_final.end(), bottom_channel_data.begin(), bottom_channel_data.end()); + pEudaqEvent->AddBlock(cSensorId+1,bottom_data_final); + //LOG(INFO) << "Hits Top: " << +numhits_top << ", Hits Bottom: " << +numhits_bottom; + cSensorId += 2; + } else if (pBoard->getChipType() == ChipType::MPA) { + // check + if (cFe->fMPAVector.size() != 1) { + // the question here was how to arrange the mpas for one sensor + LOG(WARNING) << "Producer is currently implemented only for one MPA chip without SSA. Do further implementation please"; + } + // convert pointer + const D19cMPAEvent *cMPAEvent = dynamic_cast<const D19cMPAEvent*> (pPh2Event); + // get data + for(auto cMpa : cFe->fMPAVector) { + std::vector<PCluster> pClusterVector = cMPAEvent->GetPixelClusters(cMpa->getFeId(),cMpa->getMPAId()); + for (auto pCluster : pClusterVector) { + for(int pixel = 0; pixel <= pCluster.fWidth; pixel++) { + top_channel_data.resize(top_offset+6); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 0], pCluster.fAddress + pixel); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 2], pCluster.fZpos); + eudaq::setlittleendian<unsigned short>(&top_channel_data[top_offset + 4], 1); + top_offset += 6; + + fHitsCounter++; + } + } + + eudaq::setlittleendian<unsigned short>(&top_data_final[0], 120); + eudaq::setlittleendian<unsigned short>(&top_data_final[2], 16); + unsigned short numhits_top = (top_channel_data.size()) / 6; + eudaq::setlittleendian<unsigned short>(&top_data_final[4], 0x8000 | numhits_top); + top_data_final.insert(top_data_final.end(), top_channel_data.begin(), top_channel_data.end()); + pEudaqEvent->AddBlock(cSensorId,top_data_final); + + //LOG(INFO) << "Hits Top: " << +numhits_top; + cSensorId += 1; + } + } + + } + + // setting tags + if (pBoard->getChipType() == ChipType::CBC3) { + for(auto cFe : pBoard->fModuleVector) { + for(auto cCbc : cFe->fCbcVector) { + char name[100]; + uint32_t cFeId = cCbc->getFeId(); + uint32_t cCbcId = cCbc->getCbcId(); + + std::sprintf (name, "pipeline_address_%02d_%02d", cFeId, cCbcId); + pEudaqEvent->SetTag(name, (uint32_t)pPh2Event->PipelineAddress(cFeId,cCbcId)); + std::sprintf (name, "error_%02d_%02d", cFeId, cCbcId); + pEudaqEvent->SetTag(name, (uint32_t)pPh2Event->Error(cFeId,cCbcId)); + //std::sprintf (name, "l1_counter_%02d_%02d", cFeId, cCbcId); + //pEudaqEvent->SetTag(name, (uint32_t)pPh2Event->L1Counter(cFeId,cCbcId)); + uint8_t cStubId = 0; + for(auto cStub : pPh2Event->StubVector(cFeId,cCbcId)) { + std::sprintf (name, "stub_pos_%02d_%02d_%01d", cFeId, cCbcId,cStubId); + pEudaqEvent->SetTag(name, (uint32_t)cStub.getPosition()); + std::sprintf (name, "stub_bend_%02d_%02d_%01d", cFeId, cCbcId,cStubId); + pEudaqEvent->SetTag(name, (uint32_t)cStub.getBend()); + + cStubId++; + } + } + } + } else if (pBoard->getChipType() == ChipType::MPA) { + // convert pointer + const D19cMPAEvent *cMPAEvent = dynamic_cast<const D19cMPAEvent*> (pPh2Event); + // set tags + for(auto cFe : pBoard->fModuleVector) { + for(auto cMpa : cFe->fMPAVector) { + char name[100]; + uint32_t cFeId = cMpa->getFeId(); + uint32_t cMpaId = cMpa->getMPAId(); + + std::sprintf (name, "mpa_%02d_%02d_error", cFeId, cMpaId); + pEudaqEvent->SetTag(name, (uint32_t)cMPAEvent->Error(cFeId,cMpaId)); + std::sprintf (name, "mpa_%02d_%02d_l1counter", cFeId, cMpaId); + pEudaqEvent->SetTag(name, (uint32_t)cMPAEvent->GetMPAL1Counter(cFeId,cMpaId)); + std::sprintf (name, "mpa_%02d_%02d_nstrip_clu", cFeId, cMpaId); + pEudaqEvent->SetTag(name, (uint32_t)cMPAEvent->GetNStripClusters(cFeId,cMpaId)); + std::sprintf (name, "mpa_%02d_%02d_npix_clu", cFeId, cMpaId); + pEudaqEvent->SetTag(name, (uint32_t)cMPAEvent->GetNPixelClusters(cFeId,cMpaId)); + std::sprintf (name, "mpa_%02d_%02d_nbx1_stubs", cFeId, cMpaId); + pEudaqEvent->SetTag(name, (uint32_t)cMPAEvent->GetBX1_NStubs(cFeId,cMpaId)); + + uint8_t cStubId = 0; + for (auto cStub : cMPAEvent->StubVector(cFeId, cMpaId)) { + std::sprintf (name, "mpa_%02d_%02d_stub_%02d", cFeId, cMpaId, cStubId); + uint32_t cStubEncoded = (cStub.getPosition() & 0xFF) | ((cStub.getRow() & 0x0F) << 8) | ((cStub.getBend() & 0x07) << 16); + pEudaqEvent->SetTag(name, cStubEncoded); + cStubId++; + } + + + } + } + } + } + + bool EventsPending() { + if(configured) { + if (fHandshakeEnabled) { + for(auto cBoard : fSystemController->fBoardVector) { + if (cBoard->getBoardType() == BoardType::D19C) + { + if (fSystemController->fBeBoardInterface->ReadBoardReg(cBoard,"fc7_daq_stat.readout_block.general.readout_req") > 0) { + return true; + } + } + } + } + } + return false; + } + + private: + unsigned m_run, m_ev; + bool stopping, done,started, configured; + + SystemController *fSystemController; + bool fHandshakeEnabled; + uint32_t fHitsCounter; + std::string fHWFile; +}; + +// The main function that will create a Producer instance and run it +int main ( int argc, char* argv[] ) +{ + //configure the logger + el::Configurations conf ("settings/logger.conf"); + el::Loggers::reconfigureAllLoggers (conf); + + ArgvParser cmd; + + // init + cmd.setIntroductoryDescription ( "CMS Ph2_ACF EUDAQ Producer for the Test Beam operation" ); + // error codes + cmd.addErrorCode ( 0, "Success" ); + cmd.addErrorCode ( 1, "Error" ); + // options + cmd.setHelpOption ( "h", "help", "Print this help page" ); + + cmd.defineOption ( "file", "Hw Description File . Default value: settings/D19CDescription.xml", ArgvParser::OptionRequiresValue); + cmd.defineOptionAlternative ( "file", "f" ); + + cmd.defineOption ( "runcontrol", "The RunControl address. Default value: tcp://localhost:44000", ArgvParser::OptionRequiresValue); + cmd.defineOptionAlternative ( "runcontrol", "r" ); + + cmd.defineOption ( "loglevel", "The EUDAQ LogLevel. Default value: NONE", ArgvParser::OptionRequiresValue); + cmd.defineOptionAlternative ( "loglevel", "l" ); + + cmd.defineOption ( "print", "Print every i-th event. Default: 1000", ArgvParser::OptionRequiresValue ); + cmd.defineOptionAlternative ( "print", "p" ); + + int result = cmd.parse ( argc, argv ); + if ( result != ArgvParser::NoParserError ) + { + LOG (INFO) << cmd.parseErrorDescription ( result ); + exit ( 1 ); + } + + std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CDescription.xml"; + std::string cRunControlAddress = ( cmd.foundOption ( "runcontrol" ) ) ? cmd.optionValue ( "runcontrol" ) : "tcp://localhost:44000"; + std::string cLogLevel = ( cmd.foundOption ( "loglevel" ) ) ? cmd.optionValue ( "loglevel" ) : "NONE"; + uint32_t cNPrint = ( cmd.foundOption ( "print" ) ) ? atoi (cmd.optionValue ( "file" ).c_str()) : 1000; + + // Set the Log level for displaying messages based on command-line + EUDAQ_LOG_LEVEL(cLogLevel); + + //producer name + std::string cProducerName = "Ph2Producer"; + // construct producer + Ph2Producer cProducer(cProducerName, cRunControlAddress, cHWFile); + + // And set it running... + cProducer.ReadoutLoop(); + + return 0; +} diff --git a/src/integratedtester.cc b/src/integratedtester.cc deleted file mode 100644 index 32b8b404949ac382c81f450ad7c2d2c6b6a970c0..0000000000000000000000000000000000000000 --- a/src/integratedtester.cc +++ /dev/null @@ -1,745 +0,0 @@ -#include <cstring> -#include <iostream> -#include <unistd.h> -#include <limits.h> -#include <signal.h> -#include <chrono> -#include <thread> -#include <sys/wait.h> -#include "boost/tokenizer.hpp" -#include <boost/filesystem.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/spirit/include/qi_parse.hpp> -#include <boost/spirit/include/qi_numeric.hpp> - -#include "../HWDescription/Cbc.h" -#include "../HWDescription/Module.h" -#include "../HWDescription/BeBoard.h" -#include "../HWInterface/CbcInterface.h" -#include "../HWInterface/BeBoardInterface.h" -#include "../HWDescription/Definition.h" -#include "../tools/HybridTester.h" -#include "../tools/RegisterTester.h" -#include "../tools/ShortFinder.h" -#include "../tools/AntennaTester.h" -#include "../tools/Calibration.h" -#include "../tools/PedeNoise.h" -#include "../Utils/argvparser.h" -#include "TROOT.h" -#include "TApplication.h" -#include "../Utils/Timer.h" - -#ifdef __USBINST__ -#include <zmq.hpp> -#include "../../Ph2_USBInstDriver/Utils/zmqutils.h" -#include "../Utils/AppLock.cc" -#include "../../Ph2_USBInstDriver/HMP4040/HMP4040Controller.h" -#include "../../Ph2_USBInstDriver/HMP4040/HMP4040Client.h" -using namespace Ph2_UsbInst; -#endif - -using namespace Ph2_HwDescription; -using namespace Ph2_HwInterface; -using namespace Ph2_System; -using namespace CommandLineProcessing; -INITIALIZE_EASYLOGGINGPP - - - -// need this to reset terminal output -const std::string rst ("\033[0m"); - -// Typedefs for Containers -typedef std::map<std::string, double> HMP4040_currents; -typedef std::map<double, std::string> HMP4040_voltages; -typedef std::pair< time_t, HMP4040_currents> HMP4040_measurement; - - -// generic tokenize string function - blatantly copied from G.Auzinger -std::vector<std::string> tokenize_input ( std::string& cInput, const char* cSeperator) -{ - std::vector<std::string> cOutput; - - boost::char_separator<char> sep (cSeperator); - boost::tokenizer<boost::char_separator<char>> tokens (cInput, sep); - - for (const auto& t : tokens) - cOutput.push_back (t); - - return cOutput; -} -// function to return home directory -std::string getHomeDirectory() -{ - char buffer[256]; - std::string currentDir = getcwd (buffer, sizeof (buffer) ); - std::vector<std::string> directories = tokenize_input ( currentDir, "/"); - std::string homeDir = "/" + directories[0] + "/" + directories[1]; - return homeDir; -} -// function to create bash script which launches the HMP4040 server in a tmux session called HMP4040_Server -void create_HMP4040server_tmuxSession (std::string pHostname = "localhost", int pZmqPortNumber = 8081, int pHttpPortNumber = 8080, int pMeasureInterval_s = 2 ) -{ - char buffer[256]; - std::string currentDir = getcwd (buffer, sizeof (buffer) ); - std::string baseDirectory = getHomeDirectory() + "/Ph2_USBInstDriver"; - - // create bash script to launch HMP4040 sessions - sprintf (buffer, "%s/start_HMP4040.sh", baseDirectory.c_str() ); - std::ofstream starterScript ( buffer ); - starterScript << "#!/bin/bash" << std::endl; - - // check if the tmux session with the name HMP4040_Server already exists... if it doesn't create one with that name. - starterScript << "SESSION_NAME=HMP4040_Server" << std::endl << std::endl ; - starterScript << "tmux list-session 2>&1 | grep -q \"^$SESSION_NAME\" || tmux new-session -s $SESSION_NAME -d" << std::endl; - // send chdir via tmux session - sprintf (buffer, "tmux send-keys -t $SESSION_NAME \"cd %s\" Enter", baseDirectory.c_str() ); - starterScript << buffer << std::endl << std::endl; - // set-up environment for Ph2_USB_InstDriver - starterScript << "tmux send-keys -t $SESSION_NAME \". ./setup.sh\" Enter" << std::endl; - // launch HMP4040 server - sprintf (buffer, "tmux send-keys -t $SESSION_NAME \"lvSupervisor -r %d -p %d -i %d\" Enter", pZmqPortNumber, pHttpPortNumber, pMeasureInterval_s ) ; - starterScript << buffer << std::endl; - starterScript.close(); -} - -// function to check if a string is alphanumeric ... -// shamelessly copied from a google search -bool is_numeric (std::string const& str) -{ - std::string::const_iterator first (str.begin() ), last (str.end() ); - return boost::spirit::qi::parse (first, last, boost::spirit::double_) && first == last; -} - -// check if the HMP4040 server has been launched -// if not launch it in a tmux session using a bask script created by create_HMP4040server_tmuxSession -// -int launch_HMP4040server ( std::string pHostname, int& pZmqPortNumber, int& pHttpPortNumber, int pMeasureInterval_s ) -{ -#ifdef __USBINST__ - LOG (INFO) << "Check if HMP4040 server is not launched and if so launch it." ; - char buffer[256]; - std::string currentDir = getcwd (buffer, sizeof (buffer) ); - std::string baseDirectory = getHomeDirectory() + "/Ph2_USBInstDriver"; - - // first check if process if running - //before I do anything else, try to find an existing lock and if so, terminate - AppLock* cLock = new AppLock ("/tmp/lvSupervisor.lock" ); - - // server already running - if (cLock->getLockDescriptor() < 0) - { - //might as well retreive the info before quitting! - std::string cInfo = cLock->get_info(); - LOG (INFO) << "Retreived the following parameters from the info file: " << cInfo; - LOG (INFO) << "HMP4040 server already running .... so do nothing!"; - - if (cLock) delete cLock; - - - //tokenize the cInfo string to recover the port numbers so the client can be smart enough to connect to the correct port! - std::vector<std::string> cTokens = tokenize_input ( cInfo, " "); - std::vector<int> cPorts; - cPorts.clear(); - - for ( auto token : cTokens ) - { - if ( is_numeric (token) ) - cPorts.push_back ( boost::lexical_cast<int> (token) ); - } - - //ports passed as reference so they can be passed on in main() - // THttp port comes first, then ZMQ - pHttpPortNumber = cPorts[0]; - pZmqPortNumber = cPorts[1]; - } - else - { - // have to do this here because actually lvSupervisor attempts to access the LOCK file as well... - if (cLock) delete cLock; - - LOG (INFO) << "HMP4040 server not running .... so try and launch it."; - // launch the server in the background with nohup... probably not the smartest way of doing this but the only way I know how without using screen/tmux - // // sprintf(cmd, "nohup bin/lvSupervisor -r %d -p %d -i %d 0< /dev/null", pZmqPortNumber, pHttpPortNumber, cMeasureInterval_s); - // nohup has a problem that i cannot seem to make it ignore std_in ... which seems to cause the server to crash/time-out ... - // so do this with tmux instead - create_HMP4040server_tmuxSession (pHostname, pZmqPortNumber, pHttpPortNumber, pMeasureInterval_s ); - char cmd[120]; - sprintf (cmd, ". %s/start_HMP4040.sh", baseDirectory.c_str() ); - system (cmd); - - // start monitoring the voltages and currents on the HMP4040 - HMP4040Client* cClient = new HMP4040Client (pHostname, pZmqPortNumber); - cClient->StartMonitoring(); - std::this_thread::sleep_for (std::chrono::seconds (pMeasureInterval_s * 2) ); - - if (cClient) delete cClient; - } - - -#endif - return 0; -} -// check that the currents drawn on the low voltage lines of the hybrid are within the "normal" range -HMP4040_measurement get_HMP4040currents ( std::string pHostname = "localhost", int pZmqPortNumber = 8081, int pHttpPortNumber = 8080 ) -{ - HMP4040_measurement cMeasurement; - HMP4040_currents cCurrents ; - HMP4040_voltages cVoltages = { {5.0, "pLVDS"}, {5.0, "nLVDS"}, {3.3, "VREG"}, {1.2, "CBC"}}; - -#ifdef __USBINST__ - HMP4040Client* cClient = new HMP4040Client (pHostname, pZmqPortNumber); - - int iterations = 0 ; - // get the latest reading from the logged using the HMP4040 monitoring function. - cClient->GetLatestReadValues(); - MeasurementValues cValues = cClient->fValues; - cMeasurement.first = cValues.fTimestamp; - - for ( int i = 0 ; i < 4 ; i += 1 ) - { - auto search = cVoltages.find (cValues.fVoltages.at (i) ); - - if (search != cVoltages.end() ) - cCurrents.insert (std::pair<std::string, double> (search->second, cValues.fCurrents.at (i) * 1e3 ) ); - } - - cMeasurement.second = cCurrents; - - if (cClient) delete cClient; - -#endif - return cMeasurement; -} -bool check_CurrentConsumption (Tool pTool, int pNCBCs = 2, std::string pHostname = "localhost", int pZmqPortNumber = 8081, int pHttpPortNumber = 8080, int pMeasureInterval_s = 2 ) -{ - double vLVDS = 5.0 ; - double vRegulator = 3.3 ; - double vCBC = 1.2 ; - - //nominal currents for the 4 different low voltage lines on the hybrid : all in mA - //nominal current drawn by one CBC - double ncCBC = 60; - HMP4040_currents cCurrentLimits = { {"pLVDS", 14.0}, {"nLVDS", 14.0}, {"VREG", 160.0}, {"CBC", ncCBC * pNCBCs}}; - std::vector<std::string> cChannelNames = { "pLVDS", "nLVDS", "VREG", "CBC"}; - - int chkLVDS = 0; - int chkRegulator = 0; - int chkCBC = 0; - int chkCurrent = 0; - int cNumReads = 3; -#ifdef __USBINST__ - std::string message; - int iterations = 0 ; - // get the latest reading from the logged using the HMP4040 monitoring function. - HMP4040_measurement cMeasurement = get_HMP4040currents ( pHostname, pZmqPortNumber, pHttpPortNumber ); - time_t cTimeStamp = cMeasurement.first; - HMP4040_currents cCurrentsMeasured = cMeasurement.second; - int cNumTimes_limitReached = 0 ; - - do - { - message = ""; - bool limitReached = false ; - - for (auto channelName : cChannelNames ) - { - //auto cCurrentMeasurement = cCurrentLimits.at("pLVDS"); - auto srch_cLimits = cCurrentLimits.find (channelName); - - if (srch_cLimits != cCurrentLimits.end() ) - { - auto srch_cMeasurements = cCurrentsMeasured.find (channelName); - - if ( srch_cMeasurements != cCurrentsMeasured.end() ) - { - double deviationFromNominalValue = std::fabs (srch_cLimits->second - srch_cMeasurements->second) / srch_cLimits->second ; - limitReached = ( deviationFromNominalValue > 0.33 ) ? true : false ; - char buffer[120]; - sprintf (buffer, "# Current measured on %s = %.3f mA.\n", (srch_cMeasurements->first).c_str(), (double) (srch_cMeasurements->second) ); - message += buffer; - //LOG (INFO) << srch_cLimits->first << " : " << srch_cLimits->second ; - //LOG (INFO) << srch_cMeasurements->first << " : " << srch_cMeasurements->second; - } - } - } - - // wait for 5s before checking for a new value - std::this_thread::sleep_for (std::chrono::seconds (pMeasureInterval_s * 2) ); - // check for a new value - cMeasurement = get_HMP4040currents ( pHostname, pZmqPortNumber, pHttpPortNumber ); - cCurrentsMeasured = cMeasurement.second; - - if ( cTimeStamp < cMeasurement.first) iterations++; - - cTimeStamp = cMeasurement.first; - - if ( limitReached) - { - cNumTimes_limitReached++; - LOG (INFO) << BOLDRED << "Nominal current consumption limits exceeded!!" << rst ; - } - } - while ( iterations < cNumReads); - - message += "#"; - pTool.AmmendReport (message); - return ( cNumTimes_limitReached >= 2 ) ? false : true ; -#else - return true; -#endif -} -// check that the CBC registers can be written -// tool tries to write 2 bit patterns (0xAA , 0x55) to the CBCs and checks how many write operations have failed -bool check_Registers (Tool* pTool) -{ - // first check that the registers could be read/written to correctly - RegisterTester cRegisterTester; - cRegisterTester.Inherit (pTool); - LOG (INFO) << "Running registers testing tool ... "; - cRegisterTester.TestRegisters(); - - cRegisterTester.PrintTestReport(); - // once we've finished checking the registers reload the default values into the CBCs - cRegisterTester.ReconfigureRegisters(); - // this was here to check that the reconfiguration worked... - //cRegisterTester.dumpConfigFiles(); - //and now get the results (pass/fail) of the register test - bool cRegTest = cRegisterTester.PassedTest(); - - std::string line = cRegTest ? ("# Register test passed.") : ("# Register test failed : " + std::to_string (cRegisterTester.GetNumFails() ) + " registers could not be written to.") ; - cRegisterTester.AmmendReport ( line ); - return cRegTest; -} -// perform the CBC Vplus, Voffset calibration -void perform_Calibration (Tool* pTool) -{ - Calibration cCalibration; - cCalibration.Inherit (pTool); - cCalibration.Initialise ( false ); - - cCalibration.FindVplus(); - cCalibration.FindOffsets(); - cCalibration.writeObjects(); - cCalibration.dumpConfigFiles(); -} -// find the shorts on the DUT -bool check_Shorts (Tool* pTool, uint32_t cMaxNumShorts) -{ - ShortFinder cShortFinder; - cShortFinder.Inherit (pTool); - cShortFinder.ConfigureHw(); - //reload the calibration values for the CBCs - //cShortFinder.ReconfigureRegisters(); - // I don't think this is neccesary ... but here for now - //cShortFinder.ConfigureVcth (0x78); - - cShortFinder.Initialize(); - cShortFinder.FindShorts(); - //cShortFinder.writeObjects(); - cShortFinder.SaveResults(); - uint32_t cNShorts = cShortFinder.GetNShorts() ; - char line[120]; - sprintf (line, "# %d shorts found on hybrid = %d", cNShorts ); - cShortFinder.AmmendReport (line); - cShortFinder.AmmendReport ( ( cNShorts <= cMaxNumShorts) ? ("# Shorts test passed.") : ("# Shorts test failed.") ); - - - LOG (INFO) << GREEN << "\t\t" + std::to_string (cNShorts) + " shorts found on hybrid." << rst ; - return ( cNShorts <= cMaxNumShorts) ? true : false; -} -// measure the occupancy on the TOP/BOTTOM pads of the DUT -void perform_OccupancyMeasurment (Tool* pTool ) -{ - LOG (INFO) << "Starting noise occupancy test." ; - - HybridTester cHybridTester; - cHybridTester.Inherit (pTool); - cHybridTester.ConfigureHw(); - cHybridTester.Initialize(); - - // re-configure CBC regsiters with values from the calibration - //cHybridTester.ReconfigureCBCRegisters(); - // I don't think this is neccesary ... but here for now - //cHybridTester.ConfigureVcth (0x78); - - // measure occupancy - cHybridTester.Measure(); - // display noisy/dead channels - cHybridTester.DisplayNoisyChannels(); - cHybridTester.DisplayDeadChannels(); - - // save results - cHybridTester.writeObjects(); - - char line[120]; - sprintf (line, "# Top Pad Occupancy = %.2f ± %.3f", cHybridTester.GetMeanOccupancyTop(), cHybridTester.GetRMSOccupancyTop() ); - cHybridTester.AmmendReport (line); - sprintf (line, "# Bottom Pad Occupancy = %.2f ± %.3f", cHybridTester.GetMeanOccupancyBottom(), cHybridTester.GetRMSOccupancyBottom() ); - cHybridTester.AmmendReport (line); - - // measure pedestal - -} -void perform_AntennaOccupancyMeasurement (Tool* pTool ) -{ - LOG (INFO) << "Starting occupancy measurement using the antenna." ; - - AntennaTester cAntennaTester; - cAntennaTester.Inherit (pTool); - cAntennaTester.ConfigureHw (); - cAntennaTester.Initialize(); - - // re-configure CBC regsiters with values from the calibration - //cAntennaTester.ReconfigureCBCRegisters(); - cAntennaTester.ConfigureVcth (0x78); - - // measure occupancy - cAntennaTester.Measure(); - - // save results - cAntennaTester.writeObjects(); - //char line[120]; - //sprintf(line, "# Top Pad Occupancy = %.2f ± %.3f" , cHybridTester.GetMeanOccupancyTop() , cHybridTester.GetRMSOccupancyTop() ); - //cHybridTester.AmmendReport(line); - //sprintf(line, "# Bottom Pad Occupancy = %.2f ± %.3f" , cHybridTester.GetMeanOccupancyBottom() , cHybridTester.GetRMSOccupancyBottom() ); - //cHybridTester.AmmendReport(line); - -} - -int main ( int argc, char* argv[] ) -{ - //configure the logger - el::Configurations conf ("settings/logger.conf"); - el::Loggers::reconfigureAllLoggers (conf); - - - ArgvParser cmd; - - // init - cmd.setIntroductoryDescription ( "CMS Ph2_ACF Integrated validation test performs the following actions:"); - // error codes - cmd.addErrorCode ( 0, "Success" ); - cmd.addErrorCode ( 1, "Error" ); - // options - cmd.setHelpOption ( "h", "help", "Print this help page" ); - - cmd.defineOption ( "numCBCs", "Number of CBCs. Default is 2", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "numCBCs", "n" ); - - cmd.defineOption ( "file", "Hw Description File . Default value: settings/Calibration2CBC.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "file", "f" ); - - cmd.defineOption ( "output", "Output Directory . Default value: Results", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "output", "o" ); - - cmd.defineOption ( "batch", "Run the application in batch mode", ArgvParser::NoOptionAttribute ); - cmd.defineOptionAlternative ( "batch", "b" ); - - cmd.defineOption ( "hport", "Port number on which to run THttpServer for HMP4040 logger., Default: 8080", ArgvParser::OptionRequiresValue ); - cmd.defineOptionAlternative ( "hport", "p" ); - - cmd.defineOption ( "cport", "Port number on which to run ZMQ server for HMP4040 client., Default: 8081", ArgvParser::OptionRequiresValue ); - cmd.defineOptionAlternative ( "cport", "r" ); - - cmd.defineOption ( "settingsHMP4040", "Hw Description File for HMP4040. Default value: ../Ph2_USBInstDriver/settings/HMP4040.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ ); - cmd.defineOptionAlternative ( "settingsHMP4040", "s" ); - - cmd.defineOption ( "logHMP4040", "Save the data to a text file. Default value: LV_log.txt", ArgvParser::OptionRequiresValue ); - cmd.defineOptionAlternative ( "logHMP4040", "l" ); - - cmd.defineOption ( "interval", "Read Interval for the Power supply monitoring in seconds, Default: 2s", ArgvParser::OptionRequiresValue ); - cmd.defineOptionAlternative ( "interval", "i" ); - - cmd.defineOption ( "checkCurrents", "Check the consumption of the DUT.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "checkRegisters", "Check WRITE/READ to and from registers on DUT.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "calibrate", "Calibration CBCs' Vplus/Voffset on DUT.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "checkShorts", "Identify shorts on DUT.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "measureOccupancy", "Measure (NOISE) occuapncy on DUT.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "antennaTest", "Measure occuapncy on the DUT using the Antenna.", ArgvParser::NoOptionAttribute ); - - cmd.defineOption ( "all", "Perform ALL tests on DUT : checkCurrents , checkRegisters, calibrate, checkShorts, and measureOccupancy. ", ArgvParser::NoOptionAttribute ); - - int result = cmd.parse ( argc, argv ); - - if ( result != ArgvParser::NoParserError ) - { - LOG (INFO) << cmd.parseErrorDescription ( result ); - exit ( 1 ); - } - - // now query the parsing results - int cNumCBCs = ( cmd.foundOption ( "numCBCs" ) ) ? atoi (cmd.optionValue ( "numCBCs" ).c_str() ) : 2; - std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : ("settings/Calibration" + std::to_string (cNumCBCs) + "CBC.xml"); - - std::string cDirectory = ( cmd.foundOption ( "output" ) ) ? cmd.optionValue ( "output" ) : "Results/IntegratedTester"; - - bool batchMode = ( cmd.foundOption ( "batch" ) ) ? true : false; - - std::string cHostname = (cmd.foundOption ("hostname") ) ? cmd.optionValue ("hostname") : "localhost"; - int httpPortNumber = ( cmd.foundOption ( "hport" ) ) ? atoi (cmd.optionValue ( "hport" ).c_str() ) : 8080; - int zmqPortNumber = ( cmd.foundOption ( "cport" ) ) ? atoi (cmd.optionValue ( "cport" ).c_str() ) : 8081; - std::string cPowerSupplyHWFile = ( cmd.foundOption ( "settingsHMP4040" ) ) ? cmd.optionValue ( "settingsHMP4040" ) : "../Ph2_USBInstDriver/settings/HMP4040.xml"; - std::string cPowerSupplyOutputFile = ( cmd.foundOption ( "logHMP4040" ) ) ? cmd.optionValue ( "logHMP4040" ) : "LV_log.txt"; - int cInterval = ( cmd.foundOption ( "interval" ) ) ? atoi (cmd.optionValue ( "interval" ).c_str() ) : 2; - //cHWFile = "settings/Calibration" + std::to_string(cNumCBCs) + "CBC.xml"; - - bool cCurrents = ( cmd.foundOption ( "checkCurrents" ) ) ? true : false; - bool cRegisters = ( cmd.foundOption ( "checkRegisters" ) ) ? true : false; - bool cCalibrate = ( cmd.foundOption ( "calibrate" ) ) ? true : false; - bool cShorts = ( cmd.foundOption ( "checkShorts" ) ) ? true : false; - bool cOccupancy = ( cmd.foundOption ( "measureOccupancy" ) ) ? true : false; - bool cAntennaMeasurement = ( cmd.foundOption ( "antennaTest" ) ) ? true : false; - bool cAll = ( cmd.foundOption ( "all" ) ) ? true : false; - - uint32_t cMaxNumShorts = 10; - - TApplication cApp ( "Root Application", &argc, argv ); - - if ( batchMode ) gROOT->SetBatch ( true ); - else TQObject::Connect ( "TCanvas", "Closed()", "TApplication", &cApp, "Terminate()" ); - - - // set all test flags ON if all flag set in arguments passed to tester. - if ( cAll ) - { - cCurrents = true; - cRegisters = true; - cCalibrate = true; - cShorts = true ; - cOccupancy = true; - } - - //Start server to communicate with HMP404 instrument via usbtmc and SCPI - pid_t childPid; // the child process that the execution will soon run inside of. - childPid = fork(); - - if (childPid < 0) // fork failed - { - // log the error - exit (1); - } - else if (childPid == 0) // fork succeeded - { - if ( cCurrents ) - { - // launch HMP4040 server - launch_HMP4040server ( cHostname, zmqPortNumber, httpPortNumber, cInterval); - } - exit (0); - } - else // Main (parent) process after fork succeeds - { - int returnStatus = -1 ; - waitpid (childPid, &returnStatus, 0); // Parent process waits here for child to terminate. - - if (returnStatus == 0) // Verify child process terminated without error. - { - if ( cCurrents ) - { -#if __ZMQ__ - LOG (INFO) << "HMP4040 server launcher terminated normally ... so can now start integrated tester." ; -#endif - } - - Timer tGlobal; - tGlobal.start(); - Timer t; - - //create a genereic Tool Object, I can then construct all other tools from that using the Inherit() method - //this tool stays on the stack and lives until main finishes - all other tools will update the HWStructure from cTool - std::stringstream outp; - Tool cTool; - cTool.InitializeHw ( cHWFile, outp ); - cTool.InitializeSettings ( cHWFile, outp ); - LOG (INFO) << outp.str(); - cTool.CreateResultDirectory ( cDirectory ); - cTool.InitResultFile ( "Summary" ); - cTool.StartHttpServer(); - cTool.ConfigureHw (); - cTool.CreateReport(); - - char line[120]; - - // perform current consumption test if --checkCurrents flag set in arguments passed to tester - if ( cCurrents ) - { - t.start(); - bool currentConsumptionTest_passed = check_CurrentConsumption (cTool, cNumCBCs, cHostname, zmqPortNumber, httpPortNumber, cInterval); - cTool.AmmendReport ( ( currentConsumptionTest_passed) ? ("# Current consumption test passed.") : ("# Current consumption test failed.") ); - t.stop(); - sprintf (line, "# %.3f s required to check current consumption on low voltage power supply.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "Current consumption test of the DUT"); - - // if DUT failscurrent consumption test then stop here - if ( !currentConsumptionTest_passed ) - { - LOG (INFO) << BOLDRED << "Hybrid did not pass current consumption test. Stopping tester." ; - LOG (INFO) << BOLDBLUE << "Stopping DUT tester!" << rst ; - // add cTool destroy here! - // have to destroy the tool at the end of the program - cTool.SaveResults(); - cTool.CloseResultFile(); - cTool.Destroy(); - exit (0); - } - - } - - // perform register R&W test if --checkRegisters flag set in arguments passed to tester - if ( cRegisters ) - { - t.start(); - bool registerReadWriteTest_passed = check_Registers (&cTool); - t.stop(); - sprintf (line, "# %.3f s required to check register WRITE operation.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "Read/Write register test of the DUT" ); - - // if DUT fails register R&W test then stop here. - if ( !registerReadWriteTest_passed ) - { - LOG (INFO) << BOLDRED << "Hybrid did not pass register check. Stopping tester." << rst ; - LOG (INFO) << BOLDBLUE << "Stopping DUT tester!" << rst ; - // have to destroy the tool at the end of the program - cTool.SaveResults(); - cTool.CloseResultFile(); - cTool.Destroy(); - exit (0); - } - } - - // perform calibration of the CBCs on the DUT if --calibrate flag set in arguments passed to tester - if ( cCalibrate ) - { - LOG (INFO) << GREEN << "Hybrid passed register check. Moving on to calibration of the CBCs on the DUT." << rst ; - t.start(); - perform_Calibration (&cTool); - LOG (INFO) << "Calibration finished." ; - t.stop(); - sprintf (line, "# %.3f s required to calibrate Vplus,Voffset on CBCs.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - - t.show ( "Calibration of the DUT" ); - } - - // look for shorts on the DUT if --checkShorts flag set in arguments passed to tester - if ( cShorts ) - { - //if calibrate flag has not been set then make sure that the calibration is done before the occupancy - //measurement is performed! - if ( !cCalibrate) - { - LOG (INFO) << GREEN << "Calibrating CBCs before starting antenna test of the CBCs on the DUT." << rst ; - t.start(); - perform_Calibration (&cTool); - LOG (INFO) << "Calibration finished." ; - t.stop(); - sprintf (line, "# %.3f s required to calibrate Vplus,Voffset on CBCs.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "Calibration of the DUT" ); - } - - LOG (INFO) << "Starting short(s) test." ; - t.start(); - bool shortFinder_passed = check_Shorts (&cTool, cMaxNumShorts); - t.stop(); - sprintf (line, "# %.3f s required to identify shorts on DUT.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - - t.show ( "Short finding on the DUT" ); - - if ( !shortFinder_passed ) - { - LOG (INFO) << BOLDRED << "Hybrid did not pass shorts check. Stopping tester." ; - LOG (INFO) << BOLDBLUE << "Stopping DUT tester!" << rst ; - - cTool.SaveResults(); - cTool.CloseResultFile(); - cTool.Destroy(); - exit (0); - } - } - - - // measure (noise) occupancy on dut if --measureOccupancy flag set in arguments passed to tester - if ( cOccupancy ) - { - // if calibrate flag has not been set then make sure that the calibration is done before the occupancy - // measurement is performed! - if ( !cCalibrate) - { - LOG (INFO) << GREEN << "Calibrating CBCs before starting antenna test of the CBCs on the DUT." << rst ; - t.start(); - perform_Calibration (&cTool); - LOG (INFO) << "Calibration finished." ; - t.stop(); - sprintf (line, "# %.3f s required to calibrate Vplus,Voffset on CBCs.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "Calibration of the DUT" ); - } - - t.start(); - perform_OccupancyMeasurment (&cTool); - t.stop(); - sprintf (line, "# %.3f s required to measure (NOISE) occupancy on DUT.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "(Noise) Occupancy measurement"); - } - - // measure occupancy on dut whilst using the antenna to capacitively couple charge into the CBCs - // --antennaTest flag must be set in the arguments sent to the tester - if ( cAntennaMeasurement ) - { - - //if calibrate flag has not been set then make sure that the calibration is done before the occupancy - //measurement is performed! - if ( !cCalibrate) - { - LOG (INFO) << GREEN << "Calibrating CBCs before starting antenna test of the CBCs on the DUT." << rst ; - t.start(); - perform_Calibration (&cTool); - LOG (INFO) << "Calibration finished." ; - t.stop(); - sprintf (line, "# %.3f s required to calibrate Vplus,Voffset on CBCs.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "Calibration of the DUT" ); - - } - - t.start(); - perform_AntennaOccupancyMeasurement (&cTool); - t.stop(); - sprintf (line, "# %.3f s required to measure occupancy on the DUT with the Antenna.", t.getElapsedTime() ); - cTool.AmmendReport ( line); - t.show ( "(Antenna) Occupancy measurement"); - } - - tGlobal.stop(); - tGlobal.show ( "Complete system test" ); - sprintf (line, "# %.3f s required to test DUT.", tGlobal.getElapsedTime() ); - cTool.AmmendReport ( line); - - // have to destroy the tool at the end of the program - //cTool.SaveResults(); // if this is here then you end up with 2 copies of all histograms and canvases in the root file ... so I've removed it - cTool.CloseResultFile(); - cTool.Destroy(); - } - else if (returnStatus == 1) - { - LOG (INFO) << "The child process terminated with an error!." ; - exit (1); - } - } - - - if ( !batchMode ) cApp.Run(); - - return 0; -}