#include <array>
#include <sys/stat.h>
+//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<uint32_t,1025*505*256> 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<std::string> 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<uint32_t> mimFraCntNewVec;
std::vector<uint32_t> 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) {
+//Open a pipe and wait for commands and informations
+//from controller script
std::vector<std::string> await_params()
{
+ //Receiving pipe for informations from controller
std::string pipeName = "/tmp/scurveipipe";
+
FILE *iPipe = fopen(pipeName.c_str(), "r");
if(iPipe == nullptr) {
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<std::string> values;
buf = fgetc(iPipe);
}
}
+ //Delete "START" from first position
values.erase(values.begin());
// for (const auto& i: values)
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) {
-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);
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<microseconds>(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;
+//Main data taking procedure.
void take_data(std::string src)
{
hadaq::ReadoutHandle ref = hadaq::ReadoutHandle::Connect(src.c_str());
}
ENDFUNC:
ref.Disconnect();
- return;
}
+//Keep track of maximum values of boundaries of scan.
void find_edge()
{
using namespace Data;
+//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';
+//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";
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();
+//main. Make initialization and then enter main loop.
int main(int argc, char* argv[])
{
//Read stream url
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();
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;
} 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());
--- /dev/null
+#include <iostream>
+#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];
+ }
+
+};
+++ /dev/null
-#ifndef TRBNET_H
-#define TRBNET_H
-
-extern const char trbnet_version[];
-
-#include <stdint.h>
-#include <stdio.h>
-
-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
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 ) {