Advertisement
Guest User

Untitled

a guest
Aug 3rd, 2015
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.12 KB | None | 0 0
  1. #include <CAENVMElib.h>
  2. #include <iostream>
  3. #include <stdexcept>
  4. #include <unistd.h>
  5.  
  6. using namespace std;
  7.  
  8. const string error_codes[] = {"Success","Bus Error","Comm Error","Generic Error","Invalid Param","Timeout Error"};
  9.  
  10.  
  11. #define S(x) #x
  12. #define S_(x) S(x)
  13. #define S__LINE__ S_(__LINE__)
  14. #define SAFE(call) { \
  15.     const int err = call; \
  16.     if (err) throw std::runtime_error("CAEN Error (" + error_codes[-err] + ") at " __FILE__ ":" S__LINE__ " " #call);  \
  17. }
  18.  
  19. class VMEBridge {
  20.    
  21.     public:
  22.         VMEBridge(int link, int board) {
  23.             SAFE(CAENVME_Init(cvV1718,link,board,&handle));
  24.         }
  25.        
  26.         virtual ~VMEBridge() {
  27.             SAFE(CAENVME_End(handle));
  28.         }
  29.  
  30.         inline void write32(uint32_t addr, uint32_t data) {
  31.             SAFE(CAENVME_WriteCycle(handle, addr, &data, cvA32_U_DATA, cvD32));
  32.             usleep(10000);
  33.         }        
  34.        
  35.         inline uint32_t read32(uint32_t addr) {
  36.             uint32_t read;
  37.             usleep(1);
  38.             SAFE(CAENVME_ReadCycle(handle, addr, &read, cvA32_U_DATA, cvD32));
  39.             return read;
  40.         }
  41.        
  42.         inline void write16(uint32_t addr, uint32_t data) {
  43.             SAFE(CAENVME_WriteCycle(handle, addr, &data, cvA32_U_DATA, cvD16));
  44.             usleep(10000);
  45.         }        
  46.        
  47.         inline uint32_t read16(uint32_t addr) {
  48.             uint32_t read;
  49.             SAFE(CAENVME_ReadCycle(handle, addr, &read, cvA32_U_DATA, cvD16));
  50.             return read;
  51.         }
  52.        
  53.         inline uint32_t readBLT(uint32_t addr, void *buffer, uint32_t size) {
  54.             uint32_t bytes;
  55.             CAENVME_MBLTReadCycle(handle, addr, buffer, size, cvA32_U_MBLT, (int*)&bytes);
  56.             return bytes;
  57.         }
  58.        
  59.     protected:
  60.         int handle;
  61. };
  62.  
  63. typedef struct {
  64.  
  65.     //REG_CHANNEL_ENABLE_MASK
  66.     uint32_t enabled; // 1 bit
  67.    
  68.     //REG_GLOBAL_TRIGGER_MASK
  69.     uint32_t global_trigger; // 1 bit
  70.    
  71.     //REG_TRIGGER_OUT_MASK
  72.     uint32_t trg_out; // 1 bit
  73.    
  74.     //REG_RECORD_LENGTH
  75.     uint32_t record_length; // 16* bit
  76.    
  77.     //REG_DYNAMIC_RANGE
  78.     uint32_t dynamic_range; // 1 bit
  79.    
  80.     //REG_NEV_AGGREGATE
  81.     uint32_t ev_per_buffer; // 10 bit
  82.    
  83.     //REG_PRE_TRG
  84.     uint32_t pretrigger; // 9* bit
  85.    
  86.     //REG_LONG_GATE
  87.     uint32_t long_gate; // 12 bit
  88.    
  89.     //REG_SHORT_GATE
  90.     uint32_t short_gate; // 12 bit
  91.    
  92.     //REG_PRE_GATE
  93.     uint32_t gate_offset; // 8 bit
  94.    
  95.     //REG_DPP_TRG_THRESHOLD
  96.     uint32_t trg_threshold; // 12 bit
  97.    
  98.     //REG_BASELINE_THRESHOLD
  99.     uint32_t fixed_baseline; // 12 bit
  100.    
  101.     //REG_SHAPED_TRIGGER_WIDTH
  102.     uint32_t shaped_trigger_width; // 10 bit
  103.    
  104.     //REG_TRIGGER_HOLDOFF
  105.     uint32_t trigger_holdoff; // 10* bit
  106.    
  107.     //REG_DPP_CTRL
  108.     uint32_t charge_sensitivity; // 3 bit (see docs)
  109.     uint32_t pulse_polarity; // 1 bit (0->positive, 1->negative)
  110.     uint32_t trigger_config; // 2 bit (see docs)
  111.     uint32_t baseline_mean; // 3 bit (fixed, 16, 64, 256, 1024)
  112.     uint32_t self_trigger; // 1 bit (0->enabled, 1->disabled)
  113.    
  114.     //REG_DC_OFFSET
  115.     uint32_t dc_offset; // 16 bit (-1V to 1V)
  116.  
  117. } V1730_chan_config;
  118.  
  119. typedef struct {
  120.  
  121.     //REG_CONFIG
  122.     uint32_t dual_trace; // 1 bit
  123.     uint32_t analog_probe; // 2 bit (see docs)
  124.     uint32_t oscilloscope_mode; // 1 bit
  125.     uint32_t digital_virt_probe_1; // 3 bit (see docs)
  126.     uint32_t digital_virt_probe_2; // 3 bit (see docs)
  127.    
  128.     //REG_GLOBAL_TRIGGER_MASK
  129.     uint32_t coincidence_window; // 3 bit
  130.     uint32_t global_majority_level; // 3 bit
  131.     uint32_t external_global_trigger; // 1 bit
  132.     uint32_t software_global_trigger; // 1 bit
  133.    
  134.     //REG_TRIGGER_OUT_MASK
  135.     uint32_t out_logic; // 2 bit (OR,AND,MAJORITY)
  136.     uint32_t out_majority_level; // 3 bit
  137.     uint32_t external_trg_out; // 1 bit
  138.     uint32_t software_trg_out; // 1 bit
  139.    
  140.     //REG_BUFF_ORG
  141.     uint32_t buff_org;
  142.    
  143.     //REG_READOUT_BLT_AGGREGATE_NUMBER
  144.     uint16_t max_board_agg_blt;
  145.    
  146. } V1730_card_config;
  147.  
  148. class V1730_DPP_PSD {
  149.  
  150.     //system wide
  151.     #define REG_CONFIG 0x8000
  152.     #define REG_CONFIG_SET 0x8004
  153.     #define REG_CONFIG_CLEAR 0x8008
  154.     #define REG_BUFF_ORG 0x800C
  155.     #define REG_FRONT_PANEL_CONTROL 0x811C
  156.     #define REG_DUMMY 0xEF20
  157.     #define REG_SOFTWARE_RESET 0xEF24
  158.     #define REG_SOFTWARE_CLEAR 0xEF28
  159.     #define REG_BOARD_CONFIGURATION_RELOAD 0xEF34
  160.  
  161.     //per channel, or with 0x0n00
  162.     #define REG_RECORD_LENGTH 0x1020
  163.     #define REG_DYNAMIC_RANGE 0x1024
  164.     #define REG_NEV_AGGREGATE 0x1034
  165.     #define REG_PRE_TRG 0x1038
  166.     #define REG_SHORT_GATE 0x1054
  167.     #define REG_LONG_GATE 0x1058
  168.     #define REG_PRE_GATE 0x105C
  169.     #define REG_DPP_TRG_THRESHOLD 0x1060
  170.     #define REG_BASELINE_THRESHOLD 0x1064
  171.     #define REG_SHAPED_TRIGGER_WIDTH 0x1070
  172.     #define REG_TRIGGER_HOLDOFF 0x1074
  173.     #define REG_DPP_CTRL 0x1080
  174.     #define REG_TRIGGER_CTRL 0x1084
  175.     #define REG_DC_OFFSET 0x1098
  176.  
  177.     //acquisition
  178.     #define REG_ACQUISITION_CONTROL 0x8100
  179.     #define REG_ACQUISITION_STATUS 0x8104
  180.     #define REG_SOFTWARE_TRIGGER 0x8108
  181.     #define REG_GLOBAL_TRIGGER_MASK 0x810C
  182.     #define REG_TRIGGER_OUT_MASK 0x8110
  183.     #define REG_CHANNEL_ENABLE_MASK 0x8120
  184.  
  185.     //readout
  186.     #define REG_EVENT_SIZE 0x814C
  187.     #define REG_READOUT_CONTROL 0xEF00
  188.     #define REG_READOUT_STATUS 0xEF04
  189.     #define REG_VME_ADDRESS_RELOCATION 0xEF10
  190.     #define REG_READOUT_BLT_AGGREGATE_NUMBER 0xEF1C
  191.    
  192.     public:
  193.         V1730_DPP_PSD(VMEBridge &_bridge, uint32_t _baseaddr) : bridge(_bridge), baseaddr(_baseaddr) {
  194.            
  195.             //These are "do nothing" defaults, testparams() will set up the acquisition
  196.            
  197.             card.dual_trace = 0; // 1 bit
  198.             card.analog_probe = 0; // 2 bit (see docs)
  199.             card.oscilloscope_mode = 1; // 1 bit
  200.             card.digital_virt_probe_1 = 0; // 3 bit (see docs)
  201.             card.digital_virt_probe_2 = 0; // 3 bit (see docs)
  202.             card.coincidence_window = 1; // 3 bit
  203.             card.global_majority_level = 0; // 3 bit
  204.             card.external_global_trigger = 0; // 1 bit
  205.             card.software_global_trigger = 0; // 1 bit
  206.             card.out_logic = 0; // 2 bit (OR,AND,MAJORITY)
  207.             card.out_majority_level = 0; // 3 bit
  208.             card.external_trg_out = 0; // 1 bit
  209.             card.software_trg_out = 0; // 1 bit
  210.             card.max_board_agg_blt = 500;
  211.            
  212.             for (uint32_t ch = 0; ch < 16; ch++) {
  213.                 chans[ch].enabled = 0; //1 bit
  214.                 chans[ch].global_trigger = 0; // 1 bit
  215.                 chans[ch].trg_out = 0; // 1 bit
  216.                 chans[ch].record_length = 80; // 16* bit
  217.                 chans[ch].dynamic_range = 0; // 1 bit
  218.                 chans[ch].ev_per_buffer = 10; // 10 bit
  219.                 chans[ch].pretrigger = 50; // 9* bit
  220.                 chans[ch].long_gate = 20; // 12 bit
  221.                 chans[ch].short_gate = 10; // 12 bit
  222.                 chans[ch].gate_offset = 5; // 8 bit
  223.                 chans[ch].trg_threshold = 33; // 12 bit
  224.                 chans[ch].fixed_baseline = 0; // 12 bit
  225.                 chans[ch].shaped_trigger_width = 10; // 10 bit
  226.                 chans[ch].trigger_holdoff = 10; // 10* bit
  227.                 chans[ch].charge_sensitivity = 000; // 3 bit (see docs)
  228.                 chans[ch].pulse_polarity = 1; // 1 bit (0->positive, 1->negative)
  229.                 chans[ch].trigger_config = 0; // 2 bit (see docs)
  230.                 chans[ch].baseline_mean = 3; // 3 bit (fixed,16,64,256,1024)
  231.                 chans[ch].self_trigger = 1; // 1 bit (0->enabled, 1->disabled)
  232.                
  233.                 chans[ch].dc_offset = 0x8000; // 16 bit (-1V to 1V)
  234.             }
  235.        
  236.         }
  237.        
  238.         virtual ~V1730_DPP_PSD() {
  239.             //Fully reset the board just in case
  240.             write32(REG_BOARD_CONFIGURATION_RELOAD,0);
  241.         }
  242.        
  243.         void testparams() {
  244.             card.external_global_trigger = 1;
  245.             chans[0].enabled = 1;
  246.            
  247.             //chans[0].pulse_polarity = 0;
  248.             //chans[0].global_trigger = 1;
  249.             //chans[0].self_trigger = 1;
  250.            
  251.             //chans[1].enabled = 1;
  252.             //chans[2].enabled = 1;
  253.             //chans[3].enabled = 1;
  254.             //chans[4].enabled = 1;
  255.             //chans[5].enabled = 1;
  256.             //chans[6].enabled = 1;
  257.             //chans[7].enabled = 1;
  258.             //chans[8].enabled = 1;
  259.             //chans[9].enabled = 1;
  260.             //chans[10].enabled = 1;
  261.             //chans[11].enabled = 1;
  262.             //chans[12].enabled = 1;
  263.             //chans[13].enabled = 1;
  264.             //chans[14].enabled = 1;
  265.             //chans[15].enabled = 1;
  266.         }
  267.        
  268.         void program() { //FIXME validate bit fields!!!
  269.             //used to build bit fields
  270.             uint32_t data;
  271.            
  272.             cout << "\treset" << endl;
  273.            
  274.             //Fully reset the board just in case
  275.             write32(REG_BOARD_CONFIGURATION_RELOAD,0);
  276.            
  277.             cout << "\tttl" << endl;
  278.    
  279.             //Set TTL logic levels, ignore LVDS and debug settings
  280.             write32(REG_FRONT_PANEL_CONTROL,1);
  281.            
  282.             cout << "\tconfig" << endl;
  283.    
  284.             data = (1 << 4)
  285.                  | (1 << 8)
  286.                  | (card.dual_trace << 11)
  287.                  | (card.analog_probe << 12)
  288.                  | (card.oscilloscope_mode << 16)
  289.                  | (1 << 17)
  290.                  | (1 << 18)
  291.                  | (1 << 19)
  292.                  | (card.digital_virt_probe_1 << 23)
  293.                  | (card.digital_virt_probe_2 << 26);
  294.             write32(REG_CONFIG,data);
  295.    
  296.             //build masks while configuring channels
  297.             uint32_t channel_enable_mask = 0;
  298.             uint32_t global_trigger_mask = (card.coincidence_window << 20)
  299.                                          | (card.global_majority_level << 24)
  300.                                          | (card.external_global_trigger << 30)
  301.                                          | (card.software_global_trigger << 31);
  302.             uint32_t trigger_out_mask = (card.out_logic << 8)
  303.                                       | (card.out_majority_level << 10)
  304.                                       | (card.external_trg_out << 30)
  305.                                       | (card.software_trg_out << 31);
  306.            
  307.             //keep track of the size of the buffers for each memory location
  308.             uint32_t buffer_sizes[8] = { 0, 0, 0, 0, 0, 0, 0, 0}; //in locations
  309.    
  310.             //keep track of how to config the local triggers
  311.             uint32_t local_logic[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  312.    
  313.             for (int ch = 0; ch < 16; ch++) {
  314.                 channel_enable_mask |= (chans[ch].enabled << ch);
  315.                 global_trigger_mask |= (chans[ch].global_trigger << (ch/2));
  316.                 trigger_out_mask |= (chans[ch].trg_out << (ch/2));
  317.            
  318.                 cout << "\tch" << ch << endl;
  319.                
  320.                 if (ch % 2 == 0) { //memory shared between pairs
  321.                
  322.                     if (chans[ch].global_trigger) {
  323.                         if (chans[ch+1].global_trigger) {
  324.                             local_logic[ch/2] = 3;
  325.                         } else {
  326.                             local_logic[ch/2] = 1;
  327.                         }
  328.                     } else {
  329.                         if (chans[ch+1].global_trigger) {
  330.                             local_logic[ch/2] = 2;
  331.                         } else {
  332.                             local_logic[ch/2] = 0;
  333.                         }
  334.                     }
  335.            
  336.                     cout << "\t\trecord" << endl;
  337.                
  338.                     if (chans[ch].record_length > 65535) throw runtime_error("Number of samples exceeds 4095");
  339.                     data = chans[ch].record_length%8 ?  chans[ch].record_length/8+1 : chans[ch].record_length/8;
  340.                     write32(REG_RECORD_LENGTH|(ch<<8),data);
  341.                     chans[ch].record_length = read32(REG_RECORD_LENGTH|(ch<<8))*8;
  342.                 } else {
  343.                     chans[ch].record_length = chans[ch-1].record_length;
  344.                     chans[ch].ev_per_buffer = chans[ch-1].ev_per_buffer;
  345.                 }
  346.            
  347.                 cout << "\t\tbuffer" << endl;
  348.                
  349.                 if (chans[ch].ev_per_buffer < 2) throw runtime_error("Number of events per channel buffer must be at least 2");
  350.                 if (chans[ch].ev_per_buffer > 1023) throw runtime_error("Number of events per channel buffer exceeds 1023");
  351.                 write32(REG_NEV_AGGREGATE|(ch<<8),chans[ch].ev_per_buffer);
  352.                
  353.                 if (chans[ch].enabled) {
  354.                     buffer_sizes[ch/2] = (2 + chans[ch].record_length/8)*chans[ch].ev_per_buffer;
  355.                 }
  356.                
  357.                 cout << "\t\tpre_trig" << endl;
  358.                
  359.                 if (chans[ch].pretrigger > 2044) throw runtime_error("Pretrigger samples exceeds 2044");
  360.                 write32(REG_PRE_TRG|(ch<<8),chans[ch].pretrigger/4);
  361.            
  362.                 cout << "\t\tlong_gate" << endl;
  363.                
  364.                 if (chans[ch].short_gate > 4095) throw runtime_error("Short gate samples exceeds 4095");
  365.                 write32(REG_SHORT_GATE|(ch<<8),chans[ch].short_gate);
  366.            
  367.                 cout << "\t\tshort_gate" << endl;
  368.                
  369.                 if (chans[ch].long_gate > 4095) throw runtime_error("Long gate samples exceeds 4095");
  370.                 write32(REG_LONG_GATE|(ch<<8),chans[ch].long_gate);
  371.            
  372.                 cout << "\t\tgate_offset" << endl;
  373.                
  374.                 if (chans[ch].gate_offset > 255) throw runtime_error("Gate offset samples exceeds 255");
  375.                 if (chans[ch].pretrigger < chans[ch].gate_offset + 19) throw runtime_error("Gate offset and pretrigger relationship violated");
  376.                 write32(REG_PRE_GATE|(ch<<8),chans[ch].gate_offset);
  377.            
  378.                 cout << "\t\ttrig_threshold" << endl;
  379.                
  380.                 if (chans[ch].trg_threshold > 4095) throw runtime_error("Trigger threshold exceeds 4095");
  381.                 write32(REG_DPP_TRG_THRESHOLD|(ch<<8),chans[ch].trg_threshold);
  382.            
  383.                 cout << "\t\tfixed_baseleine" << endl;
  384.                
  385.                 if (chans[ch].fixed_baseline > 4095) throw runtime_error("Fixed baseline exceeds 4095");
  386.                 write32(REG_BASELINE_THRESHOLD|(ch<<8),chans[ch].fixed_baseline);
  387.                
  388.                 cout << "\t\tshaped_trigger_width" << endl;
  389.                
  390.                 if (chans[ch].shaped_trigger_width > 1023) throw runtime_error("Shaped trigger width exceeds 1023");
  391.                 write32(REG_SHAPED_TRIGGER_WIDTH|(ch<<8),chans[ch].shaped_trigger_width);
  392.                
  393.                 cout << "\t\ttrigger_holdoff" << endl;
  394.                
  395.                 if (chans[ch].trigger_holdoff > 4092) throw runtime_error("Trigger holdoff width exceeds 4092");
  396.                 write32(REG_TRIGGER_HOLDOFF|(ch<<8),chans[ch].trigger_holdoff/4);
  397.            
  398.                 cout << "\t\tdpp_ctrl" << endl;
  399.                
  400.                 data = (chans[ch].charge_sensitivity)
  401.                      | (chans[ch].pulse_polarity << 16)
  402.                      | (chans[ch].trigger_config << 18)
  403.                      | (chans[ch].baseline_mean << 20)
  404.                      | (chans[ch].self_trigger << 24);
  405.                 write32(REG_DPP_CTRL|(ch<<8),data);
  406.                
  407.                 cout << "\t\ttrigger_ctrl" << endl;
  408.                
  409.                 data = local_logic[ch/2] | (1<<2);
  410.                 write32(REG_TRIGGER_CTRL|(ch<<8),data);
  411.            
  412.                 cout << "\t\tdc_offset" << endl;
  413.                
  414.                 if (chans[ch].dc_offset > 65535) throw runtime_error("DC Offset cannot exceed 0xFFFF");
  415.                 write32(REG_DC_OFFSET|(ch<<8),chans[ch].dc_offset);
  416.                
  417.             }
  418.            
  419.             cout << "\tchannel_enable_mask" << endl;
  420.            
  421.             write32(REG_CHANNEL_ENABLE_MASK,channel_enable_mask);
  422.            
  423.             cout << "\tglobal_trigger_mask" << endl;
  424.            
  425.             write32(REG_GLOBAL_TRIGGER_MASK,global_trigger_mask);
  426.            
  427.             cout << "\ttrigger_out_mask" << endl;
  428.            
  429.             write32(REG_TRIGGER_OUT_MASK,trigger_out_mask);
  430.    
  431.             cout << "\tbuff_org" << endl;
  432.                
  433.             uint32_t largest_buffer = 0;
  434.             for (int i = 0; i < 8; i++) if (largest_buffer < buffer_sizes[i]) largest_buffer = buffer_sizes[i];
  435.             const uint32_t total_locations = 640000/8;
  436.             const uint32_t num_buffers = total_locations/largest_buffer;
  437.             uint32_t shifter = num_buffers;
  438.             for (card.buff_org = 0; shifter != 1; shifter = shifter >> 1, card.buff_org++);
  439.             if (1 << card.buff_org < num_buffers) card.buff_org++;
  440.             if (card.buff_org > 0xA) card.buff_org = 0xA;
  441.             if (card.buff_org < 0x2) card.buff_org = 0x2;
  442.             cout << "Largest buffer: " << largest_buffer << " loc\nDesired buffers: " << num_buffers << "\nProgrammed buffers: " << (1<<card.buff_org) << endl;
  443.             write32(REG_BUFF_ORG,card.buff_org);
  444.            
  445.             //Set max board aggregates to transver per readout
  446.             write16(REG_READOUT_BLT_AGGREGATE_NUMBER,card.max_board_agg_blt);
  447.            
  448.             //Enable VME BLT readout
  449.             write16(REG_READOUT_CONTROL,0);
  450.         }
  451.        
  452.         void startAcquisition() {
  453.             write32(REG_ACQUISITION_CONTROL,1<<2);
  454.         }
  455.        
  456.         void stopAcquisition() {
  457.             write32(REG_ACQUISITION_CONTROL,0);
  458.         }
  459.        
  460.         bool readoutReady() {
  461.             return read32(REG_ACQUISITION_STATUS) & (1 << 3);
  462.         }
  463.        
  464.         size_t readoutBLT(char *buffer, size_t buffer_size) {
  465.             size_t offset = 0, total = 0;
  466.             while (readoutReady()) {
  467.                 uint32_t next = read32(REG_EVENT_SIZE);
  468.                 total += 4*next;
  469.                 if (offset+total > buffer_size) throw runtime_error("Readout buffer too small!");
  470.                 size_t lastoff = offset;
  471.                 while (offset < total) {
  472.                     size_t remaining = total-offset, read;
  473.                     if (remaining > 4090) {
  474.                         read = readBLT(0x0000, buffer+offset, 4090);
  475.                     } else {
  476.                         remaining = 8*(remaining%8 ? remaining/8+1 : remaining/8); // needs to be multiples of 8 (64bit)
  477.                         read = readBLT(0x0000, buffer+offset, remaining);
  478.                     }
  479.                     offset += read;
  480.                     if (!read) {
  481.                         cout << "\tfailed event size " << offset-lastoff << " / " << next*4 << endl;
  482.                         break;
  483.                     }
  484.                 }
  485.             }
  486.             return total;
  487.         }
  488.        
  489.         inline void write16(uint32_t reg, uint32_t data) {
  490.             bridge.write16(baseaddr|reg,data);
  491.         }
  492.        
  493.         inline uint32_t read16(uint32_t reg) {
  494.             return bridge.read16(baseaddr|reg);
  495.         }
  496.        
  497.         inline void write32(uint32_t reg, uint32_t data) {
  498.             bridge.write32(baseaddr|reg,data);
  499.         }
  500.        
  501.         inline uint32_t read32(uint32_t reg) {
  502.             return bridge.read32(baseaddr|reg);
  503.         }
  504.        
  505.         inline uint32_t readBLT(uint32_t addr, void *buffer, uint32_t size) {
  506.             return bridge.readBLT(baseaddr|addr,buffer,size);
  507.         }
  508.        
  509.     protected:
  510.    
  511.         VMEBridge &bridge;
  512.         uint32_t baseaddr;
  513.         V1730_card_config card;
  514.         V1730_chan_config chans[16];
  515. };
  516.  
  517. size_t event_counter;
  518. size_t chanagg_counter;
  519. size_t boardagg_counter;
  520. size_t readout_counter;
  521.  
  522. uint32_t* decode_chan_agg(uint32_t *chanagg) {
  523.     const bool format_flag = chanagg[0] & 0x80000000;
  524.     if (!format_flag) throw runtime_error("Channel format not found");
  525.    
  526.     chanagg_counter++;
  527.    
  528.     const uint32_t size = chanagg[0] & 0x7FFF;
  529.     const uint32_t format = chanagg[1];
  530.     const uint32_t samples = (format & 0xFFF)*8;
  531.    
  532.     if (!format_flag) cout << samples << endl;
  533.      
  534.     //cout << "\tc: " << size << ' ' << samples << endl;
  535.    
  536.     /*
  537.     const bool dualtrace_enable = format & (1<<31);
  538.     const bool charge_enable =format & (1<<30);
  539.     const bool time_enable = format & (1<<29);
  540.     const bool baseline_enable = format & (1<<28);
  541.     const bool waveform_enable = format & (1<<27);
  542.     const uint32_t extras = (format >> 24) & 0x7;
  543.     const uint32_t analog_probe = (format >> 22) & 0x3;
  544.     const uint32_t digital_probe_2 = (format >> 19) & 0x7;
  545.     const uint32_t digital_probe_1 = (format >> 16) & 0x7;
  546.     */
  547.    
  548.     for (uint32_t *event = chanagg+2; event-chanagg+1 < size; event += samples/2+3) {
  549.        
  550.         event_counter++;
  551.    
  552.         const bool oddch = event[0] & 0x80000000;
  553.         const uint32_t timetag = event[0] & 0x7FFFFFFF;
  554.        
  555.         //cout << "\t\te: " << oddch << ' ' << timetag << endl;
  556.        
  557.         for (uint32_t *word = event, sample = 0; sample < samples; word++, sample+=2) {
  558.             uint16_t sample0 = *word & 0x3FFF;
  559.             uint8_t dp10 = (*word >> 14) & 0x1;
  560.             uint8_t dp20 = (*word >> 15) & 0x1;
  561.             uint16_t sample1 = (*word >> 16) & 0x3FFF;
  562.             uint8_t dp11 = (*word >> 30) & 0x1;
  563.             uint8_t dp21 = (*word >> 31) & 0x1;
  564.         }
  565.    
  566.     }
  567.    
  568.     return chanagg + size;
  569. }
  570.  
  571. uint32_t* decode_board_agg(uint32_t *boardagg) {
  572.     if (boardagg[0] == 0xFFFFFFFF) {
  573.         boardagg++; //sometimes padded
  574.         cout << "padded\n";
  575.     }
  576.     if ((boardagg[0] & 0xF0000000) != 0xA0000000)
  577.         throw runtime_error("Board aggregate missing tag");
  578.    
  579.     boardagg_counter++;    
  580.    
  581.     uint32_t size = boardagg[0] & 0x0FFFFFFF;
  582.    
  583.     const uint32_t board = (boardagg[1] >> 28) & 0xF;
  584.     const bool fail = boardagg[1] & (1 << 26);
  585.     const uint32_t pattern = (boardagg[1] >> 8) & 0x7FFF;
  586.     const uint32_t mask = boardagg[1] & 0xFF;
  587.    
  588.     const uint32_t count = boardagg[2] & 0x7FFFFF;
  589.     const uint32_t timetag = boardagg[3];
  590.    
  591.     //cout << "b: " << count << ' ' << timetag << hex << mask << dec << endl;
  592.    
  593.     uint32_t *chans = boardagg+4;
  594.    
  595.     for (uint32_t gr = 0; gr < 8; gr++) {
  596.         if (mask & (1 << gr)) {
  597.             chans = decode_chan_agg(chans);
  598.         }
  599.     }
  600.    
  601.     return boardagg+size;
  602. }
  603.  
  604. int main(int argc, char **argv) {
  605.  
  606.     cout << "Opening VME link..." << endl;
  607.    
  608.     VMEBridge bridge(0,0);
  609.     V1730_DPP_PSD dgtz(bridge,0xAAAA0000);
  610.    
  611.     //load the test paramters (temp)
  612.     dgtz.testparams();
  613.    
  614.     cout << "Programming Digitizer..." << endl;
  615.    
  616.     dgtz.program();
  617.    
  618.     cout << "Starting acquisition..." << endl;
  619.    
  620.     dgtz.startAcquisition();
  621.    
  622.     size_t buffer_size = 100*1024*1024;
  623.     char *buffer = new char[buffer_size];
  624.    
  625.     event_counter = chanagg_counter = boardagg_counter = readout_counter = 0;
  626.    
  627.     while (true) {
  628.    
  629.         while (!dgtz.readoutReady());
  630.        
  631.         size_t readout_size = dgtz.readoutBLT(buffer,buffer_size);
  632.         readout_counter++;
  633.         cout << "readout " << readout_counter << " : " << readout_size << " bytes" << endl;
  634.        
  635.        
  636.         uint32_t *next = (uint32_t*)buffer, *start = (uint32_t*)buffer;
  637.         while (((next = decode_board_agg(next)) - start + 1)*4 < readout_size) {
  638.            
  639.         }
  640.         cout << "e: " << event_counter << " / c: " << chanagg_counter << " / b: " << boardagg_counter << endl;
  641.        
  642.     }
  643.    
  644.     delete [] buffer;
  645.    
  646.     //Stop Aquisition
  647.     dgtz.stopAcquisition();
  648.    
  649.    
  650.     return 0;
  651.  
  652. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement