MIDAS
Loading...
Searching...
No Matches
v1720CONET2.cxx
Go to the documentation of this file.
1/*****************************************************************************/
10#include "v1720CONET2.hxx"
11#include <stdlib.h>
12
13#define UNUSED(x) ((void)(x))
14
15using namespace std;
16
18const char * v1720CONET2::config_str[] = {\
19 "setup = INT : 0",\
20 "Acq mode = INT : 3",\
21 "Channel Configuration = DWORD : 131088",\
22 "Buffer organization = INT : 10",\
23 "Custom size = INT : 625",\
24 "Channel Mask = DWORD : 255",\
25 "Trigger Source = DWORD : 1073741824",\
26 "Trigger Output = DWORD : 1073741824",\
27 "Post Trigger = DWORD : 1000",\
28 /*"fp_io_ctrl = DWORD : 0x104", */ \
29 "almost_full = DWORD : 850",\
30 /*"fp_lvds_io_ctrl = DWORD : 0x22", */ \
31 /*"Trigger Positive Pulse = BOOL : n",*/ \
32 /*"Pre-Record_ZS = WORD : 4", */ \
33 /*"Post-Record_ZS = WORD : 4", */ \
34 "Threshold = DWORD[8] :",\
35 "[0] 2200",\
36 "[1] 2108",\
37 "[2] 2100",\
38 "[3] 2108",\
39 "[4] 9",\
40 "[5] 9",\
41 "[6] 9",\
42 "[7] 9",\
43 "NbOUThreshold = DWORD[8] :",\
44 "[0] 2",\
45 "[1] 2",\
46 "[2] 2",\
47 "[3] 2",\
48 "[4] 2",\
49 "[5] 2",\
50 "[6] 2",\
51 "[7] 2",\
52 "ZS_Threshold = INT[8] :",\
53 "[0] 0x80000d93",\
54 "[1] 0x80000d93",\
55 "[2] 0x80000d93",\
56 "[3] 0x80000d93",\
57 "[4] 0x80000d93",\
58 "[5] 0x80000d93",\
59 "[6] 0x80000d93",\
60 "[7] 0x80000d93",\
61 "ZS_NsAmp = DWORD[8] :",\
62 "[0] 0x50005",\
63 "[1] 0x50005",\
64 "[2] 0x50005",\
65 "[3] 0x50005",\
66 "[4] 0x50005",\
67 "[5] 0x50005",\
68 "[6] 0x50005",\
69 "[7] 0x50005",\
70 "DAC = DWORD[8] :",\
71 "[0] 10000",\
72 "[1] 10000",\
73 "[2] 10000",\
74 "[3] 10000",\
75 "[4] 10000",\
76 "[5] 10000",\
77 "[6] 10000",\
78 "[7] 10000",\
79 NULL };
80
81#if SIMULATION
90{
91 _handle = -1;
92 _odb_handle = 0;
93 verbose = 0;
94 _running=false;
95 _settings_loaded=false;
96 _settings_touched=false;
97 mZLE=false;
98 mDataType = 0;
99}
100#else
112: _feindex(feindex), _link(link), _board(board), _moduleID(moduleID)
113{
114 _handle = -1;
115 _odb_handle = 0;
116 verbose = 0;
117 _settings_loaded=false;
118 _settings_touched=false;
119 _running=false;
120 mZLE=false;
121 mDataType = 0;
122}
123#endif //SIMULATION
129v1720CONET2::~v1720CONET2()
130{
131}
132
139{
140 stringstream txt;
141#if SIMULATION
142 txt << "B" << _board;
143#else
144 txt << "F" << _feindex << _link << _board;
145#endif
146 return txt.str();
147}
154{
155 return (_handle >= 0);
156}
163{
164 return _running;
165}
172{
173 if (verbose) cout << GetName() << "::Connect()\n";
174 if (IsConnected()) { cout << "Error: trying to connect already connected board" << endl;
175 return (CAENComm_ErrorCode) 1; }
176#if SIMULATION
177 if (verbose) cout << "Opening device " << _board << endl;
178#else
179 if (verbose) cout << "Opening device (i,l,b) = (" << _feindex << "," << _link << "," << _board << ")" << endl;
180#endif
181
183
184#if SIMULATION
186 _handle = 1; //random
187#else
189#endif
190
191 if (sCAEN != CAENComm_Success) _handle = -1;
192 return sCAEN;
193}
200{
201 if (verbose) cout << GetName() << "::Disconnect()\n";
202 if (!IsConnected()) { cout << "Error: trying to disconnect already disconnected board" << endl; return (CAENComm_ErrorCode)1; }
203 if (IsRunning()) { cout << "Error: trying to disconnect running board" << endl; return (CAENComm_ErrorCode)1; }
204#if SIMULATION
205 if (verbose) cout << "Closing device " << _board << endl;
206#else
207 if (verbose) cout << "Closing device (i,l,b) = (" << _feindex << "," << _link << "," << _board << ")" << endl;
208#endif
209
211
212#if SIMULATION
214#else
216#endif
217
218 _handle = -1;
219 return sCAEN;
220}
231{
232 if (verbose) cout << GetName() << "::StartRun()\n";
233 if (IsRunning()) {
234 cout << "Error: trying to start already started board" << endl;
235 return (CAENComm_ErrorCode)1;
236 }
237 if (!IsConnected()) {
238 cout << "Error: trying to start disconnected board" << endl;
239 return (CAENComm_ErrorCode)1;
240 }
242 {
243 cm_msg(MINFO, "feoV1720", "Note: settings on board %s touched. Re-initializing board.",
244 GetName().c_str());
245 cout << "reinitializing" << endl;
247 }
248
250 if (e == CAENComm_Success) _running=true;
251 return e;
252}
262{
263 if (verbose) cout << GetName() << "::StopRun()\n";
264 if (!IsRunning()) { cout << "Error: trying to stop already stopped board" << endl; return (CAENComm_ErrorCode)1; }
265 if (!IsConnected()) { cout << "Error: trying to stop disconnected board" << endl; return (CAENComm_ErrorCode)1; }
267 if (e == CAENComm_Success) _running=false;
268 return e;
269}
282{
283#if SIMULATION
284 return CAENComm_Success;
285#else
286 return ov1720_Setup(_handle, mode);
287#endif
288}
298{
299#if SIMULATION
300 return CAENComm_Success;
301#else
303#endif
304}
314{
315#if SIMULATION
316 return CAENComm_Success;
317#else
319#endif
320}
329{
330 if (verbose >= 2) cout << GetName() << "::ReadReg(" << hex << address << ")" << endl;
331#if SIMULATION
332 return CAENComm_Success;
333#else
334 return CAENComm_Read32(_handle, address, val);
335#endif
336}
345{
346 if (verbose >= 2) cout << GetName() << "::WriteReg(" << hex << address << "," << val << ")" << endl;
347#if SIMULATION
348 return CAENComm_Success;
349#else
350 return CAENComm_Write32(_handle, address, val);
351#endif
352}
362{
363#if SIMULATION
364 return CAENComm_Success;
365#else
367#endif
368}
369
371#define MAX_BLT_READ_SIZE 10000
383{
384 if (!IsConnected()) {
385 cout << "Error: trying to ReadEvent disconnected board" << endl;
386 return (CAENComm_ErrorCode)1;
387 }
389 int tempnw = 0;
390 *dwords_read = 0;
391
392 //read size of event to be read
393#if SIMULATION
396#else
398#endif
399
400 while (size_remaining > 0 && sCAEN == CAENComm_Success)
401 {
402#if SIMULATION
404 for (WORD i = 0; i < to_read; i++)
405 *data_pos++ = rand();
407 tempnw = to_read; //simulate success reading all data
408#else
409 //calculate amount of data to be read in this iteration
412#endif
413
414 if (verbose >= 2) cout << sCAEN << " = BLTRead(handle=" << _handle
415 << ", addr=" << V1720_EVENT_READOUT_BUFFER
416 << ", data_pos=" << data_pos
417 << ", to_read=" << to_read
418 << ", tempnw returned " << tempnw << ");" << endl;
419
420 //increment pointers/counters
423 data_pos += tempnw;
424 }
425 return sCAEN;
426}
436{
437 if (verbose) cout << GetName() << "::SendTrigger()" << endl;
438 if (!IsConnected()) { cout << "Error: trying to SendTrigger disconnected board" << endl; return (CAENComm_ErrorCode)1; }
439#if SIMULATION
440 if (verbose) cout << "Sending Trigger " << _board << endl;
441#else
442 if (verbose) cout << "Sending Trigger (l,b) = (" << _link << "," << _board << ")" << endl;
443#endif
444
445 return WriteReg(V1720_SW_TRIGGER, 0x1);
446}
465{
466 char set_str[200];
467
468#if SIMULATION
469 sprintf(set_str, "/Equipment/FEv1720_SIM/Settings/Board%d", _board);
470#else
471 if(_feindex == -1)
472 sprintf(set_str, "/Equipment/FEv1720I/Settings/Board%d", _moduleID);
473 else
474 sprintf(set_str, "/Equipment/FEv1720I%0d/Settings/Board%d", _feindex, _moduleID);
475#endif
476
477 if (verbose) cout << GetName() << "::SetODBRecord(" << h << "," << set_str << ",...)" << endl;
478 int status,size;
479 //create record if doesn't exist and find key
482 if (status != DB_SUCCESS) cm_msg(MINFO,"FE","Key %s not found", set_str);
483
484 //hotlink
485 size = sizeof(V1720_CONFIG_SETTINGS);
487
488 //get actual record
489 status = db_get_record(h, _odb_handle, &config, &size, 0);
490 if (status == DB_SUCCESS) _settings_loaded = true;
491 _settings_touched = true;
492
493 return status; //== DB_SUCCESS for success
494}
515{
516 if (verbose) cout << GetName() << "::InitializeForAcq()" << endl;
517
518 if (!_settings_loaded) {
519 cout << "Error: cannot call InitializeForAcq() without settings loaded properly" << endl;
520 return -1; }
521 if (!IsConnected()) {
522 cout << "Error: trying to call InitializeForAcq() to unconnected board" << endl;
523 return -1; }
524 if (IsRunning()) {
525 cout << "Error: trying to call InitializeForAcq() to already running board" << endl;
526 return -1; }
527
528 //don't do anything if settings haven't been changed
529 if (_settings_loaded && !_settings_touched) return 0;
530
532
533 // Set register V1720_FP_IO_CONTROL (0x811C) to default settings
534 // (output trigger) will set the board that output the clock latter
535 sCAEN = WriteReg(V1720_FP_IO_CONTROL, 0x00000000);
536
537 // Clear the board
540
541 // Setup Busy daisy chaining
542 printf("\nBusy daisy chaining \n\n");
544 //sCAEN = WriteReg(V1720_FP_LVDS_IO_CRTL, 0x22);
546
547#if SIMULATION
548 cm_msg(MINFO,"feoV1720","Simulation, no firmware check");
549#else
550 // Firmware version check
551 // read each AMC firmware version
552 // [31:16] Revision date Y/M/DD
553 // [15:8] Firmware Revision (X)
554 // [7:0] Firmware Revision (Y)
555 // eg 0x760C0103 is 12th June 07, revision 1.3
556 int addr = 0;
557 uint32_t version = 0;
559 // Hardcode correct firmware verisons
560 // Current release 3.4_0.11 Feb 2012
561 const uint32_t amc_fw_ver = 0xc102000b;
562 const uint32_t roc_fw_ver = 0xc2080304;
563 const uint32_t roc_fw_ver_test = 0xc5250306; //new version we're testing
564
565 for(int iCh=0;iCh<8;iCh++) {
566 addr = 0x108c | (iCh << 8);
567 sCAEN = ReadReg(addr, &version);
568 if((iCh != 0) && (prev_chan != version)) {
569 cm_msg(MERROR, "feoV1720","Error AMC Channels have different Firmware \n");
570 }
571 prev_chan = version;
572 }
573 cm_msg(MINFO,"feoV1720","Format: YMDD:XX.YY");
574 if(version != amc_fw_ver) {
575 cm_msg(MERROR,"feoV1720","Incorrect AMC Firmware Version: 0x%08x", version);
576 }
577 else {
578 cm_msg(MINFO,"feoV1720","AMC Firmware Version: 0x%08x", version);
579 }
580
581 // read ROC firmware revision
582 // Format as above
584 switch (version)
585 {
586 case roc_fw_ver:
587 cm_msg(MINFO,"feoV1720","ROC Firmware Version: 0x%08x", version);
588 break;
589 case roc_fw_ver_test:
590 cm_msg(MINFO,"feoV1720","*** WARNING *** using new ROC Firmware Version: 0x%08x", version);
591 break;
592 default:
593 cm_msg(MERROR,"feoV1720","Incorrect ROC Firmware Version: 0x%08x", version);
594 break;
595 }
596
597 // Verify Board Type
598 const uint32_t v1720_board_type = 0x03;
599 sCAEN = ReadReg(V1720_BOARD_INFO, &version);
600 if((version & 0xFF) != v1720_board_type)
601 cm_msg(MINFO,"feoV1720","*** WARNING *** Trying to use a v1720 frontend with another"
602 " type of board. Results will be unexpected!");
603
604#endif //SIMULATION
605
607
608 //use preset setting if enabled
610 //else use odb values
611 else
612 {
613 //already reset/clear earlier this function, so skip here
623 //WriteReg(V1720_ALMOST_FULL_LEVEL, 850);
627
628 //set specfic channel values
629 for (int iChan=0; iChan<8; iChan++)
630 {
636 //NB: in original frontend, zst and zsn regs were set via a short calculation in the
637 //frontend, not the exact values as in odb. it was not clear that this was done
638 //without looking at source code, so i have changed it to just take values direct
639 //from ODB.
640 //On my todo list is to figure out a better way of setting up ODB settings
641 //for the frontends.
642
643 }
644 //could do Status here
645 }
646
647 //todo: some kind of check to make sure stuff is set correctly???
648
649 _settings_touched = false;
650 UNUSED(sCAEN);
651
652 //ready to do startrun
653
654 return 0;
655}
667
668 // Set Device, data type and packing for QT calculation later
669 int dataType = ((aChannelConfig >> 11) & 0x1);
670 if(((aChannelConfig >> 16) & 0xF) == 0) {
671 if(dataType == 1) {
672 // 2.5 pack, full data
673 mDataType = 1;
674 mZLE=0;
675 cm_msg(MINFO,"FE","Data Type: Full data with 2.5 Packing");
676 }
677 else{
678 // 2 pack, full data
679 mZLE=0;
680 mDataType = 0;
681 cm_msg(MINFO,"FE","Data Type: Full data with 2 Packing");
682 }
683 }
684 else if(((aChannelConfig >> 16) & 0xF) == 2) {
685 if(dataType == 1) {
686 // 2.5 pack, ZLE data
687 mDataType = 3;
688 cm_msg(MINFO,"FE","Data Type: ZLE data with 2.5 Packing");
689 mZLE=1;
690 }
691 else{
692 // 2 pack, ZLE data
693 mDataType = 2;
694 cm_msg(MINFO,"FE","Data Type: ZLE data with 2 Packing");
695 mZLE=1;
696 }
697 }
698 else{
699 cm_msg(MERROR,"FE","V1720 Data format Unrecognised reg: 0x%04x", 0x8000);
700 }
701}
710 return mZLE;
711}
720 // >>> Create bank.
721 // QtData is the pointer to the memory location hodling the Qt data
722 // Content
723 // V1720 event counter
724 // V1720 Trigger time tag
725 // Number of Qt
726 // QT format: channel 28 time 16 charge 0
727 char tBankName[5];
728 sprintf(tBankName,"QT%02d",moduleID);
731
732
733 // >>> copy some header words
734 *QtData = *(pZLEData+2); // event counter QtData[0]
735 QtData++;
736 *QtData = *(pZLEData+3); // trigger time tag QtData[1]
737 QtData++;
738
739 // >>> Figure out channel mapping
740 //if(mNCh==0){
741 int mNCh=0;
742 uint32_t mChMap[8];
743 uint32_t chMask = pZLEData[1] & 0xFF;
744 for(int iCh=0; iCh<8; iCh++){
745 if(chMask & (1<<iCh)){
746 mChMap[mNCh] = iCh;
747 mNCh++;
748 }
749 }
750 if(mNCh==0){
751 // printf("No channels found for module %i! Something wrong with channel mask\n", aModule);
752 }
753 //}
754
755 // >>> Skip location QtData[2]. Will be used for number of QT;
757 *(nQt) = 0;
758 QtData++;
759 //std::cout << QtData[0] << " " << *(QtData-2) << " " << QtData[1] << " " << *nQt << " " << *(QtData-1)<< " ";
760 // >>> Loop over ZLE data and fill up Qt data bank
761
762 uint32_t iPtr=4;
763 for(int iCh=0; iCh<mNCh; iCh++){
765 uint32_t iChPtr = 1;// The chSize space is included in chSize
766 uint32_t iBin=0;
767 iPtr++;
768 //std::cout << "--------------- Channel: " << aModule << "-" << iCh << " size=" << chSize << " " << std::endl;
770 while(iChPtr<chSize){
771 uint32_t goodData = ((pZLEData[iPtr]>>31) & 0x1);
772 uint32_t nWords = (pZLEData[iPtr] & 0xFFFFF);
773 if(prevGoodData==0 && goodData==0){ // consecutive skip. Bad
774 /* std::cout << "consecutive skip: V1720=" << aModule
775 << " | ch=" << iCh
776 << " | prev word=" << pZLEData[iPtr-1]
777 << " | cur word=" << pZLEData[iPtr] << std::endl;
778 */}
780 if(goodData){
782 uint32_t min=4096;
783 uint32_t baseline = (pZLEData[iPtr+1]&0xFFF);
784 for(uint32_t iWord=0; iWord<nWords; iWord++){
785 iPtr++;
786 iChPtr++;
787 if(min > (pZLEData[iPtr]&0xFFF) ){
788 iMin = iBin+iWord*2;
789 min = (pZLEData[iPtr]&0xFFF);
790 }
791 if(min > ((pZLEData[iPtr]>>16)&0xFFF) ){
792 iMin = iBin+iWord*2+1;
793 min = ((pZLEData[iPtr]>>16)&0xFFF);
794 }
795 }
796 // package channel | iMin | min in one 32 bit word
797 // don't bother for now. Temporary!!!!
798 (*nQt)++; // increment number of Qt
799 min = baseline-min; // turn it into a positive number
800 *QtData = (((mChMap[iCh]<<28) & 0xF0000000) |
801 ((iMin<<16) & 0x0FFF0000) |
802 (min & 0x0000FFFF));
803 QtData++;
804 //std::cout << aModule << " " << mChMap[iCh] << " " << iMin << " " << min << " " << *(QtData-1) << std::endl;
805 }
806 else{ // skip
807 iBin += (nWords*2);
808 }
809
810 iChPtr++;
811 iPtr++;
812 }
813 }
814 //std::cout << " | " << *nQt << std::endl;
815 bk_close(pevent, QtData);
816}
817
v1720CONET2(int feindex, int link, int board, int moduleID)
Constructor for the module object.
std::string GetName()
Get short string identifying the module's index, link and board number.
int _link
Optical link number.
bool _settings_loaded
ODB settings loaded.
CAENComm_ErrorCode WriteReg(DWORD, DWORD)
Write to 32-bit register.
BOOL IsZLEData()
Get ZLE setting.
CAENComm_ErrorCode SendTrigger()
Send a software trigger to the board.
int InitializeForAcq()
Initialize the hardware for data acquisition.
CAENComm_ErrorCode ChannelConfig(uint32_t)
Control data acquisition.
void fillQtBank(char *aDest, uint32_t *aZLEData, int aModule)
Fill Qt Bank.
int _handle
Device handler.
int _moduleID
Unique module ID.
bool _settings_touched
ODB settings touched.
CAENComm_ErrorCode SetupPreset(int)
Setup board registers using preset (see ov1720.c:ov1720_Setup())
CAENComm_ErrorCode ReadReg(DWORD, DWORD *)
Read 32-bit register.
CAENComm_ErrorCode Disconnect()
Disconnect the board through the optical link.
CAENComm_ErrorCode Poll(DWORD *)
Poll Event Stored register.
CAENComm_ErrorCode AcqCtl(uint32_t)
Control data acquisition.
static const char * config_str[]
Configuration string for this module. (ODB: /Equipment/[eq_name]/Settings/[board_name]/)
CAENComm_ErrorCode StartRun()
Start data acquisition.
BOOL mZLE
true if ZLE (Zero-length encoding) is enabled on all channels
CAENComm_ErrorCode StopRun()
Start data acquisition.
int _feindex
Frontend index number.
CAENComm_ErrorCode ReadEvent(DWORD *, int *)
Read event buffer.
bool IsRunning()
Get run status.
void getChannelConfig(DWORD aChannelConfig)
Get data type and ZLE configuration.
int SetODBRecord(HNDLE h, void(*cb_func)(INT, INT, void *))
Set the ODB record for this module.
bool IsConnected()
Get connected status.
HNDLE _odb_handle
ODB handle.
bool _running
Run in progress.
struct v1720CONET2::V1720_CONFIG_SETTINGS config
instance of config structure
int _board
Module/Board number.
CAENComm_ErrorCode Connect()
Connect the board through the optical link.
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16788
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16569
#define DB_SUCCESS
Definition midas.h:631
unsigned short int WORD
Definition mcstd.h:49
unsigned int DWORD
Definition mcstd.h:51
#define MINFO
Definition midas.h:560
#define MERROR
Definition midas.h:559
#define MODE_READ
Definition midas.h:370
#define TID_DWORD
Definition midas.h:336
#define UNUSED
Definition mongoose6.h:113
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT db_open_record(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info)
Definition odb.cxx:13292
INT db_get_record(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align)
Definition odb.cxx:11709
char * strcomb(const char **list)
Definition odb.cxx:571
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12801
void * data
Definition mana.cxx:268
BOOL verbose
Definition mana.cxx:255
char addr[128]
Definition mcnaf.cxx:104
INT i
Definition mdump.cxx:32
INT HNDLE
Definition midas.h:132
DWORD BOOL
Definition midas.h:105
int INT
Definition midas.h:129
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Settings structure for this v1740 module.
DWORD threshold[8]
0x1n80@[11.. 0]
DWORD nbouthreshold[8]
0x1n84@[11.. 0]
INT zs_threshold[8]
0x1n24@[31.. 0]
DWORD channel_config
0x8000@[19.. 0]
DWORD zs_nsamp[8]
0x1n28@[31.. 0]
DWORD dac[8]
0x1n98@[15.. 0]
DWORD channel_mask
0x8120@[ 7.. 0]
INT buffer_organization
0x800C@[ 3.. 0]
DWORD trigger_source
0x810C@[31.. 0]
DWORD trigger_output
0x8110@[31.. 0]
DWORD post_trigger
0x8114@[31.. 0]
INT setup
Initial board setup mode number.
static double e(void)
Definition tinyexpr.c:136
#define MAX_BLT_READ_SIZE
Maximum size of data to read using BLT (32-bit) cycle.