From 07e9f621f260e508f9b5ef6187c50a9d0e549954 Mon Sep 17 00:00:00 2001 From: Maps Date: Fri, 29 Mar 2024 20:22:15 +0100 Subject: [PATCH] started adding mimosis c library --- {analysis/mbs => c++}/CMakeLists.txt | 0 {analysis/mbs => c++}/main.cxx | 91 ++++++--- c++/mimosis.cxx | 116 +++++++++++ c++/trbnet.h | 287 --------------------------- scripts/Mimosis.pm | 1 + 5 files changed, 185 insertions(+), 310 deletions(-) rename {analysis/mbs => c++}/CMakeLists.txt (100%) rename {analysis/mbs => c++}/main.cxx (83%) create mode 100644 c++/mimosis.cxx delete mode 100644 c++/trbnet.h diff --git a/analysis/mbs/CMakeLists.txt b/c++/CMakeLists.txt similarity index 100% rename from analysis/mbs/CMakeLists.txt rename to c++/CMakeLists.txt diff --git a/analysis/mbs/main.cxx b/c++/main.cxx similarity index 83% rename from analysis/mbs/main.cxx rename to c++/main.cxx index a5b0fa7..1343f40 100644 --- a/analysis/mbs/main.cxx +++ b/c++/main.cxx @@ -9,50 +9,67 @@ #include #include +//Necessary for readout handler #include "hadaq/api.h" +//Necessary to control mimosis and trbnet #include "trbnet.h" using namespace std::chrono; - +//Enum to make access to the information vector more clear enum params {STATE, YLOW, YHIG, XLOW, XHIG, REGION, VCASN, VPHFINE}; + +//Collection of data related variables used throughout the programm. namespace Data { + //Main data array holds counts of pulses for every pixel and VPH_FINE std::array dataArray; + + int dataFraCnt = 0; int limitFra = 500; short vphfine; + //Boundaries within pulses were done int yLow, yHig, xLow, xHig; int yLowMax = 504, yHigMax = 0, xLowMax = 1024, xHigMax = 0; int sLowMax = 255, sHigMax = 0; + //Directory where data and METADATA will be put. std::string dataDir; + //Current state of the programm. std::string state; + //Keep track of VCASN to put in METADATA later. std::vector vcasnVec; + //Measure time of execution of the programm and put + //information in METADATA decltype(high_resolution_clock::now()) start; + //Keep track whether mimosis frame counter was not incremented by 1, + //which would indicate droped frames in the R/O. std::vector mimFraCntNewVec; std::vector mimFraCntOldVec; }; -std::string pidName = "/tmp/hldprint-pid"; + +//Name of PID file. +const std::string pidName = "/tmp/hldprint-pid"; + +//Write PID to PID-file void write_pid(void) { int pid = (int)getpid(); - // std::cout << pid << '\n'; - FILE *pidFile = fopen(pidName.c_str(), "w"); if(pidFile == nullptr) { @@ -67,9 +84,13 @@ void write_pid(void) +//Open a pipe and wait for commands and informations +//from controller script std::vector await_params() { + //Receiving pipe for informations from controller std::string pipeName = "/tmp/scurveipipe"; + FILE *iPipe = fopen(pipeName.c_str(), "r"); if(iPipe == nullptr) { @@ -77,9 +98,15 @@ std::vector await_params() std::exit(-1); } + + //Read from pipe char by char until full frame is reached. + //Frames start with START and end with END. + //Information is delimited by '-' characters. int buf; bool foundFrame = false, foundSta = false, foundEnd = false; std::string word; + + //Staore all informations, without START and END, in values vector. std::vector values; buf = fgetc(iPipe); @@ -106,6 +133,7 @@ std::vector await_params() } } + //Delete "START" from first position values.erase(values.begin()); // for (const auto& i: values) @@ -113,14 +141,20 @@ std::vector await_params() fclose(iPipe); + //Return the whole array. return values; } +//Open a pipe to transmit an acknowledgement to the +//controller script int send_ack() { + //Transmitting pipe to acknowledge receiving and processing of informations + //A simple 'ACK' indicates the controller successful operation std::string pipeName = "/tmp/scurveapipe"; + FILE *iPipe = fopen(pipeName.c_str(), "w"); if(iPipe == nullptr) { @@ -136,10 +170,11 @@ int send_ack() -void make_fit(std::string reg, std::string vcasn) +//Writing contents of Data::dataArr to file. +void write_data(std::string reg, std::string vcasn) { - // auto start = high_resolution_clock::now(); - + //For each VCASN a new sub dir is created and a csv file with + //the same name holds the data. std::string subDir = Data::dataDir + "/" + reg + "-" + vcasn; mkdir(subDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); @@ -147,39 +182,41 @@ void make_fit(std::string reg, std::string vcasn) std::string fileName = subDir + "/" + reg + "-" + vcasn + ".csv"; + //Buffered ofstream increases performance. + //One could also dump the whole array as binary file, but this complicates + //Post processing a bit. + //Another option would be to include root and use TTree's. std::ofstream file(fileName); char buffer[1000000]; file.rdbuf()->pubsetbuf(buffer, sizeof(buffer)); + //Only write relevant data between boundaries of scan. for(int y = Data::yLowMax; y <= Data::yHigMax; y++) { + for(int x = Data::xLowMax; x <= Data::xHigMax; x++) { + for(int s = Data::sLowMax; s <= Data::sHigMax; s++) { + uint32_t v = Data::dataArray[(y*1024+x)*255+s]; file << v << '\t'; - // if(v != 0) { printf("%d %d %d %d\n",y,x,s,v); } + + //Reset data to 0 Data::dataArray[(y*1024+x)*255+s] = 0; } file << '\n'; } } file.close(); - - // auto stop = high_resolution_clock::now(); - // auto duration = duration_cast(stop - start); - // std::cout << duration.count() << std::endl; - - return; } +//Decodeing of mimosis words into pixels bool decode_pixel(const uint32_t& word, int& column, int& row, const int& region) { const unsigned long pixelcode = (word >> 6) & 0x3ff; - unsigned long - side = 0, - topdown = 0; + unsigned long side = 0, topdown = 0; if((pixelcode&3) == 0x1 || (pixelcode&3) == 0x2) side = 1; if((pixelcode&3) == 0x3 || (pixelcode&3) == 0x2) topdown = 1; @@ -192,6 +229,7 @@ bool decode_pixel(const uint32_t& word, int& column, int& row, const int& region +//Main data taking procedure. void take_data(std::string src) { hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(src.c_str()); @@ -330,11 +368,11 @@ void take_data(std::string src) } ENDFUNC: ref.Disconnect(); - return; } +//Keep track of maximum values of boundaries of scan. void find_edge() { using namespace Data; @@ -346,10 +384,11 @@ void find_edge() +//Write the METADATA file and put into dataDir. void write_meta() { - std::string fileName = Data::dataDir + "/METADATA"; + std::ofstream file(fileName); file << "START:" << '\t' << Data::dataDir << '\n'; @@ -380,6 +419,9 @@ void write_meta() +//Signal handler for clean exit at CTRL-C. +//Data will be dumped and marked with 'INTERRUPTED', +//if current state was a data taking state. void signal_handler( int signum ) { std::cout << "Interrupt signal (" << signum << ") received Cleaning up...\n"; @@ -390,13 +432,13 @@ void signal_handler( int signum ) std::string lastReg = "INTERRUPTED"; std::string lastVca = "INTERRUPTED"; - make_fit(lastReg, lastVca); + write_data(lastReg, lastVca); std::cout << "Remining data indicated by INTERRUPTED flags.\n"; } else { } - //remove pid file + //Remove pid file remove(pidName.c_str()); write_meta(); @@ -406,6 +448,7 @@ void signal_handler( int signum ) +//main. Make initialization and then enter main loop. int main(int argc, char* argv[]) { //Read stream url @@ -453,7 +496,7 @@ int main(int argc, char* argv[]) Data::dataArray[(y*1024+x)*255+s] = 0; - //Control loop. After init phase, + //Main control loop. After init phase, //wait for commands from control script AWAIT: stateVec = await_params(); @@ -485,7 +528,7 @@ int main(int argc, char* argv[]) std::string vcaStr = stateVec[params::VCASN]; Data::vcasnVec.push_back(vcaStr); std::printf("Write data: %s %s\n",regStr.c_str(),vcaStr.c_str()); - make_fit(regStr,vcaStr); + write_data(regStr,vcaStr); send_ack(); goto AWAIT; @@ -502,6 +545,8 @@ int main(int argc, char* argv[]) } else { + //Never happend so far, but just in case, + //exit cleanly and remove pid file std::printf("Received garbage. Exiting.\n"); remove(pidName.c_str()); diff --git a/c++/mimosis.cxx b/c++/mimosis.cxx new file mode 100644 index 0000000..c5e434a --- /dev/null +++ b/c++/mimosis.cxx @@ -0,0 +1,116 @@ +#include +#include "trbnet.h" + +/* Make sure the right libraries are used, to get trbnet c + * code working (from trbnettools use trbnetd/libtrbnet.*). + * Also set DAQOPSERVER like usual. + * */ + + +namespace mimosis +{ + + void register_write(const int& fpga, const int& mim_reg, const int& mim_data, const bool& singleaccess) noexcept + { + const uint32_t addr = 0x12; + const uint32_t cmd = mim_reg >> 8; + const uint32_t data = ((mim_reg & 0xff) << 8 ) + mim_data; + + if( singleaccess ) + { + + { + const uint32_t com = (( mim_reg >> 8 ) << 16 ) + ( addr << 1); + const uint32_t arr[3] = { 0x010, com, 0x1}; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + + { + const uint32_t com = ( mim_reg << 16 ) + ( (addr + 1) << 1); + const uint32_t arr[3] = { 0x010, com, 0x1}; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + + { + const uint32_t com = ( mim_data << 16 ) + ( (addr + 2) << 1); + const uint32_t arr[3] = { 0x010, com, 0x1}; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + + } + else if ( !singleaccess ) + { + const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1); + const uint32_t arr[3] = { 0x001, com, 0x1}; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + } + + + int register_read(const int& fpga, const int& mim_reg, const bool& singleaccess) noexcept + { + const uint32_t addr = 0x12; + const uint32_t cmd = mim_reg >> 8; + const uint32_t data = mim_reg & 0xff; + + if( singleaccess ) + { + return 0; + } + else if( !singleaccess ) + { + { + const uint32_t com = ( data << 16 ) + ( cmd << 8 ) + ( addr << 1); + const uint32_t arr[3] = { 0x0, com, 0x1 }; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + + { + const uint32_t com = ( 0x15 << 1); + const uint32_t arr[3] = { 0x110, com, 0x1 }; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3); + } + + const uint32_t size = 2; + uint32_t res[size]; + trb_register_read(fpga, 0xde04, res, size); + return res[1]; + } + return 0; + } + + + void instr_write(const int& fpga, const int& cmd) noexcept + { + const uint32_t com = ( cmd << 8 ) + ( 0x11 << 1 ); + const uint32_t arr[3] = { 0x0, com, 0x1 }; + trb_register_write_mem(fpga, 0xde01, 0, arr, 3 ); + } + +}; + + +namespace adc +{ + + void write(const int& fpga, const int& addr, const int& cmd, const int& data) noexcept + { + const uint32_t com = (data << 16) + (cmd << 8) + 0x80 + addr; + const uint32_t arr[2] = { 0x001, com }; + trb_register_write_mem(fpga, 0xd681, 0, arr, 2 ); + } + + + int read(const int& fpga, const int& addr, const int& cmd) noexcept + { + const uint32_t com = (cmd << 8) + 0x80 + addr; + const uint32_t arr[2] = { 0x101, com }; + trb_register_write_mem(fpga, 0xd681, 0, arr, 2 ); + + uint32_t res[2]; + trb_register_read(fpga, 0xd684, res, 2); + + return res[1]; + } + +}; diff --git a/c++/trbnet.h b/c++/trbnet.h deleted file mode 100644 index f0478ee..0000000 --- a/c++/trbnet.h +++ /dev/null @@ -1,287 +0,0 @@ -#ifndef TRBNET_H -#define TRBNET_H - -extern const char trbnet_version[]; - -#include -#include - -extern unsigned int trb_debug; - -#ifdef PEXOR -extern char pexor_deviceName[256]; -extern int pexor_dma; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------------------------------------------------------------------- */ - -int init_ports(); - -int trb_register_read(uint16_t trb_address, - uint16_t reg_address, - uint32_t* data, - unsigned int dsize); - -int trb_registertime_read(uint16_t trb_address, - uint16_t reg_address, - uint32_t* data, - unsigned int dsize); - -int trb_register_read_mem(uint16_t trb_address, - uint16_t reg_address, - uint8_t option, - uint16_t size, - uint32_t* data, - unsigned int dsize); - -int trb_registertime_read_mem(uint16_t trb_address, - uint16_t reg_address, - uint8_t option, - uint16_t size, - uint32_t* data, - unsigned int dsize); - -int trb_register_write(uint16_t trb_address, - uint16_t reg_address, - uint32_t value); - -int trb_register_write_mem(uint16_t trb_address, - uint16_t reg_address, - uint8_t option, - const uint32_t* data, - uint16_t size); - -int trb_read_uid(uint16_t trb_address, - uint32_t* data, - unsigned int dsize); - -int trb_set_address(uint64_t uid, - uint8_t endpoint, - uint16_t trb_address); - - -int trb_ipu_data_read(uint8_t type, - uint8_t trg_info, - uint8_t trg_random, - uint16_t trg_number, - uint32_t* data, - unsigned int dsize); - -int trb_send_trigger(uint8_t type, - uint32_t info, - uint8_t random, - uint16_t number); - -int trb_send_trigger_rich(uint8_t input, - uint8_t type, - uint32_t info, - uint8_t random, - uint16_t number); - -int fpga_register_read(uint32_t reg_address, - uint32_t* value); - -int fpga_register_write(uint32_t reg_address, - uint32_t value); - -int trb_nettrace(uint16_t trb_address, - uint32_t *data, - unsigned int dsize); - -int trb_register_setbit(uint16_t trb_address, - uint16_t reg_address, - uint32_t bitMask); - -int trb_register_clearbit(uint16_t trb_address, - uint16_t reg_address, - uint32_t bitMask); - -int trb_register_loadbit(uint16_t trb_address, - uint16_t reg_address, - uint32_t bitMask, - uint32_t bitValue); - -#ifdef PEXOR -int fpga_register_read_mem(uint32_t reg_address, - uint32_t* data, - unsigned int size); - -int fpga_register_write_mem(uint32_t reg_address, - const uint32_t* data, - unsigned int size); -#endif - -int trb_fifo_flush(uint8_t channel); - -int network_reset(); - -int com_reset(); - -/* ---------------------------------------------------------------------- */ - -/* This library provides several function to access the trbnet on a - Etrax-Board. - -*/ - -/************************************************************************/ -/* In case of any error the gloabl varianble 'trb_errno' will be set, */ -/* see trberror.h for details. */ -/************************************************************************/ - - -/************************************************************************/ -/* int trb_register_read(uint16_t trb_address, - uint16_t reg_address, - uint32_t* data, - unsigned int dsize); - - trb_address: TRB-Address of the TRB-Endpoint - reg_address: Register-Address to be read from, broadcasts are supported - data: Pointer to a uint32_t Data-Buffer - dsize: Size of the Data-Buffer in units of 32bit-words - - ReturnValue: == -1 on error, trberrno will be set - >= 0 number of 32bit-words which were stored in Data-Buffer - - TRB-Channel used: slow control (3) - - reads the register reg_address of a TRB-Endpoint with address - trb_address. The received data is stored in the Data-Buffer data. - - The format of the Data-Buffer is: - first word: TRB-Address of the sender - second word: register value - - --> The size of the Data-Buffer must be at least >= 2 - -*/ - - -/************************************************************************/ -/* int trb_register_read_mem(uint16_t trb_address, - uint16_t reg_address, - uint8_t option, - uint16_t size, - uint32_t* data, - unsigned int dsize); - - trb_address: TRB-Address of the TRB-Endpoint - reg_address: Register-Address to be read from, broadcasts are supported - uint8_t option: - uint16_t size: Number of 32Bit-words to be read - data: Pointer to a uint32_t Data-Buffer - dsize: Size of the Data-Buffer in units of 32bit-words - - ReturnValue: == -1 on error, trberrno will be set - >= 0 number of 32bit-words which were stored in Data-Buffer - - TRB-Channel used: slow control (3) - - reads the register reg_address of a TRB-Endpoint with address - trb_address. The received data is stored in the Data-Buffer data. - - The format of the Data-Buffer is: - first word: TRB-Address of the sender (Lower 2Bytes), len (Upper 2bytes) - second word: register value - - --> The size of the Data-Buffer must be at least >= 2 - -*/ - - -/************************************************************************/ -/* int trb_register_write(uint16_t trb_address, - uint16_t reg_address, - uint32_t value); - - trb_address: TRB-Address of the TRB-Endpoint, broadcasts are supported - reg_address: Register-Address to be written to - value: 32bit-word to be writen to the register - - ReturnValue: == -1 on error, trberrno will be set - - TRB-Channel used: slow control (3) - - writes the value to the register reg_address of a TRB-Endpoint with address - trb_address. -*/ - -/************************************************************************/ -/* int trb_read_uid(uint16_t trb_address, - uint32_t* data, - unsigned int dsize); - - trb_address: TRB-Address of the TRB-Endpoint, broadcasts are supported - data: Pointer to a uint32_t Data-Buffer - dsize: Size of the Data-Buffer in units of 32bit-words - - ReturnValue: == -1 on error, trberrno will be set - >= 0 number of 32bit-words which were stored in Data-Buffer - - TRB-Channel used: slow control (3) - - reads the Unique-Id of a TRB-Endpoint with address trb_address. The - received data is stored in the Data-Buffer data. - - The format of the Data-Buffer is: - first word: UID High-32Bit Word - second word: UID Low-32Bit Word - third word: Endpoint Number - fourth word: TRB-Address of the sender - - --> The size of the Data-Buffer must be at least >= 4 - -*/ - -/************************************************************************/ -/* int trb_set_address(uint64_t uid, - uint8_t endpoint, - uint16_t trb_address); - - uint64_t uid: the UID of the Endpoint - uint8_t endpoint: Number of the TRBNet-Endpoint - uint16_t trb_address: the new TRB-Netaddress, broadcasts are not supported - - ReturnValue: == -1 on error, trberrno will be set - == 0 on success - - TRB-Channel used: slow control (3) - - sets a new TRB-Address trb_address of the give TRFNet-endpoint. -*/ - -/************************************************************************/ -/* int trb_ipu_data_read(uint8_t type, - uint8_t trg_info, - uint8_t trg_random, - uint16_t trg_number, - uint32_t* data, - unsigned int dsize); - - data: Pointer to a uint32_t Data-Buffer - dsize: Size of the Data-Buffer in units of 32bit-words - - ReturnValue: == -1 on error, trberrno will be set - >= 0 0 number of 32bit-words which were stored in Data-Buffer - - send a request to all TRBNet-Endpoints to readout the IPU-Data. The IPU - Datastream will be stored in the user DataBufer. -*/ - -/************************************************************************/ -/* int trb_send_trigger(uint8_t type, - uint32_t info, - uint8_t random, - uint16_t number); -*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/scripts/Mimosis.pm b/scripts/Mimosis.pm index 1c5f2ca..19f10c1 100755 --- a/scripts/Mimosis.pm +++ b/scripts/Mimosis.pm @@ -816,6 +816,7 @@ sub mimosis_scan_region Mimosis::mimosis_register_write( $fpga, 0x0177, ( $pixpulseD_B & 0xff00 ) >> 8, $a ); usleep($slow); Mimosis::mimosis_register_write( $fpga, 0x007d, $modpulse, $a ); usleep($slow); #set modpulse. possible values: 1f/1, 1f/2, 1f/4, 1f/8, 1f/16, 1f/32, 1f/64, 1f/128 + for ( my $yOff = $ySta; $yOff <= $yEnd; $yOff+=$yTra ) { -- 2.43.0