1-
1+
22// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
33// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
44// All rights not expressly granted are reserved.
@@ -32,51 +32,103 @@ using namespace o2::roc;
3232namespace po = boost::program_options;
3333using namespace boost ::multiprecision;
3434
35+ // 128-bit hex string parser
36+ // nBits specifies the maximum allowed bit width
37+ // throws exception on error
38+ uint128_t parsePattern (const std::string &s, int nBits = 128 ) {
39+ uint128_t v = 0 ;
40+ if (strncmp (s.c_str (), " 0x" , 2 ) || (s.length () <= 2 )) {
41+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
42+ << ErrorInfo::Message (" Pattern must be hexadecimal" ));
43+ }
44+ for (unsigned int i=2 ; i<s.length (); i++) {
45+ int c = s[i];
46+ uint128_t x = 0 ;
47+ if ( ( c >= ' 0' ) && ( c <= ' 9' )) {
48+ x = c - ' 0' ;
49+ } else if ( ( c >= ' A' ) && ( c <= ' F' )) {
50+ x = 10 + c - ' A' ;
51+ } else if ( ( c >= ' a' ) && ( c <= ' f' )) {
52+ x = 10 + c - ' a' ;
53+ } else {
54+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
55+ << ErrorInfo::Message (" Pattern must be hexadecimal" ));
56+ }
57+ v = (v << 4 ) + x;
58+
59+ /*
60+ // print value
61+ for (int k=8; k > 0; k--) {
62+ printf("%04X ", (unsigned int)((v >> ((k-1)*16)) & 0xffff));
63+ }
64+ printf("\n");
65+ */
66+ }
67+
68+ if (((v >> nBits) != 0 ) || (s.length () - 2 > 32 )) {
69+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
70+ << ErrorInfo::Message (" Pattern exceeds " + std::to_string (nBits) + " bits" ));
71+ }
72+ return v;
73+ }
74+
3575class ProgramPatternPlayer : public Program
3676{
3777 public:
3878 virtual Description getDescription ()
3979 {
4080 return { " PatternPlayer" , " Configure the CRU pattern player" ,
41- " o2-roc-pat-player --id 42:00.0 --sync 0x0123457899876543210abcdefedcb --sync -length 4 --sync -delay 2 --sync -at-start\n " };
81+ " o2-roc-pat-player --id 42:00.0 --pat1 0x012345789abdef0123 --pat1 -length 4 --pat1 -delay 2 --execute-pat1 -at-start\n " };
4282 }
4383
4484 virtual void addOptions (boost::program_options::options_description& options)
4585 {
4686 Options::addOptionCardId (options);
47- options.add_options ()(" sync" ,
48- po::value<std::string>(&mOptions .syncPattern )->default_value (" 0x0" ),
49- " 80-bit sync pattern in hex" );
50- options.add_options ()(" reset" ,
51- po::value<std::string>(&mOptions .resetPattern )->default_value (" 0x0" ),
52- " 80-bit reset pattern in hex" );
53- options.add_options ()(" idle" ,
54- po::value<std::string>(&mOptions .idlePattern )->default_value (" 0x0" ),
55- " 80-bit idle pattern in hex" );
56- options.add_options ()(" sync-length" ,
57- po::value<uint32_t >(&mOptions .syncLength )->default_value (1 ),
58- " Sync pattern's length" );
59- options.add_options ()(" sync-delay" ,
60- po::value<uint32_t >(&mOptions .syncDelay )->default_value (0 ),
61- " Sync pattern's delay" );
62- options.add_options ()(" reset-length" ,
63- po::value<uint32_t >(&mOptions .resetLength )->default_value (1 ),
64- " Reset pattern's length" );
65- options.add_options ()(" reset-trigger-select" ,
66- po::value<uint32_t >(&mOptions .resetTriggerSelect )->default_value (30 ),
67- " Select trigger for SYNC from TTC_DATA[0-31]" );
68- options.add_options ()(" sync-trigger-select" ,
69- po::value<uint32_t >(&mOptions .syncTriggerSelect )->default_value (29 ),
70- " Select trigger for RESET from TTC_DATA[0-31]" );
71- options.add_options ()(" sync-at-start" ,
72- po::bool_switch (&mOptions .syncAtStart )->default_value (false ),
73- " Enable automatically sending a sync pattern when runenable goes high" );
74- options.add_options ()(" trigger-sync" ,
75- po::bool_switch (&mOptions .triggerSync )->default_value (false ),
76- " Manually trigger the SYNC pattern" );
77- options.add_options ()(" trigger-reset" ,
78- po::bool_switch (&mOptions .triggerReset )->default_value (false ),
79- " Manually trigger the reset pattern" );
87+ options.add_options ()(" pat0" ,
88+ po::value<std::string>(&mOptions .pat0 ),
89+ " 80-bit pat0 pattern in hex" );
90+ options.add_options ()(" pat1" ,
91+ po::value<std::string>(&mOptions .pat1 ),
92+ " 80-bit pat1 pattern in hex" );
93+ options.add_options ()(" pat2" ,
94+ po::value<std::string>(&mOptions .pat2 ),
95+ " 80-bit pat2 pattern in hex" );
96+ options.add_options ()(" pat3" ,
97+ po::value<std::string>(&mOptions .pat3 ),
98+ " 80-bit pat3 pattern in hex" );
99+ options.add_options ()(" pat1-length" ,
100+ po::value<uint32_t >(&mOptions .info .pat1Length ),
101+ " pat1 pattern's length" );
102+ options.add_options ()(" pat1-delay" ,
103+ po::value<uint32_t >(&mOptions .info .pat1Delay ),
104+ " pat1 pattern's delay" );
105+ options.add_options ()(" pat2-length" ,
106+ po::value<uint32_t >(&mOptions .info .pat2Length ),
107+ " pat2 pattern's length" );
108+ options.add_options ()(" pat2-trigger-counters" ,
109+ po::value<uint32_t >(&mOptions .info .pat2TriggerTF ),
110+ " Trigger counters for pat2: TF[31:20] ORBIT[19:12] BC[11:0]" );
111+ options.add_options ()(" pat3-length" ,
112+ po::value<uint32_t >(&mOptions .info .pat3Length ),
113+ " pat3 pattern's length" );
114+ options.add_options ()(" pat1-trigger-select" ,
115+ po::value<uint32_t >(&mOptions .info .pat1TriggerSelect ),
116+ " Select trigger for pat1" );
117+ options.add_options ()(" pat2-trigger-select" ,
118+ po::value<uint32_t >(&mOptions .info .pat2TriggerSelect ),
119+ " Select trigger for pat2" );
120+ options.add_options ()(" pat3-trigger-select" ,
121+ po::value<uint32_t >(&mOptions .info .pat3TriggerSelect ),
122+ " Select trigger for pat3" );
123+ options.add_options ()(" execute-pat1-at-start" ,
124+ po::bool_switch (&mOptions .info .exePat1AtStart )->default_value (false ),
125+ " Enable automatically sending a pat1 pattern when runenable goes high" );
126+ options.add_options ()(" execute-pat1-now" ,
127+ po::bool_switch (&mOptions .info .exePat1Now )->default_value (false ),
128+ " Manually trigger the pat1 pattern now" );
129+ options.add_options ()(" execute-pat2-now" ,
130+ po::bool_switch (&mOptions .info .exePat2Now )->default_value (false ),
131+ " Manually trigger the pat2 pattern now" );
80132 options.add_options ()(" read-back" ,
81133 po::bool_switch (&mOptions .readBack )->default_value (false ),
82134 " Reads back the pattern player configuration [DOES NOT CONFIGURE!!]" );
@@ -98,45 +150,53 @@ class ProgramPatternPlayer : public Program
98150 return ;
99151 }
100152
153+ if (mOptions .pat0 .length ()) {
154+ mOptions .info .pat0 = parsePattern (mOptions .pat0 , 80 );
155+ }
156+ if (mOptions .pat1 .length ()) {
157+ mOptions .info .pat1 = parsePattern (mOptions .pat1 , 80 );
158+ }
159+ if (mOptions .pat2 .length ()) {
160+ mOptions .info .pat2 = parsePattern (mOptions .pat2 , 80 );
161+ }
162+ if (mOptions .pat3 .length ()) {
163+ mOptions .info .pat3 = parsePattern (mOptions .pat3 , 80 );
164+ }
165+
101166 auto cruBar2 = std::dynamic_pointer_cast<CruBar>(bar2);
102167 if (!mOptions .readBack ) {
103- cruBar2->patternPlayer ({ uint128_t (mOptions .syncPattern ), // TODO: Parse this correctly!
104- uint128_t (mOptions .resetPattern ),
105- uint128_t (mOptions .idlePattern ),
106- mOptions .syncLength ,
107- mOptions .syncDelay ,
108- mOptions .resetLength ,
109- mOptions .resetTriggerSelect ,
110- mOptions .syncTriggerSelect ,
111- mOptions .syncAtStart ,
112- mOptions .triggerSync ,
113- mOptions .triggerReset });
168+ cruBar2->patternPlayer (mOptions .info );
114169 } else {
115170 auto ppInfo = cruBar2->patternPlayerRead ();
116- std::cout << " sync pattern:\t\t 0x" << std::hex << ppInfo.syncPattern << std::endl;
117- std::cout << " reset pattern:\t\t 0x" << ppInfo.resetPattern << std::endl;
118- std::cout << " idle pattern:\t\t 0x" << ppInfo.idlePattern << std::dec << std::endl;
119- std::cout << " sync length:\t\t " << ppInfo.syncLength << std::endl;
120- std::cout << " sync delay:\t\t " << ppInfo.syncDelay << std::endl;
121- std::cout << " reset length:\t\t " << ppInfo.resetLength << std::endl;
122- std::cout << " reset trigger select:\t " << ppInfo.resetTriggerSelect << std::endl;
123- std::cout << " sync trigger select:\t " << ppInfo.syncTriggerSelect << std::endl;
171+ std::cout << " pat0 pattern:\t\t 0x" << std::hex << ppInfo.pat0 << std::endl;
172+ std::cout << " pat1 pattern:\t\t 0x" << std::hex << ppInfo.pat1 << std::endl;
173+ std::cout << " pat2 pattern:\t\t 0x" << std::hex << ppInfo.pat2 << std::endl;
174+ std::cout << " pat3 pattern:\t\t 0x" << std::hex << ppInfo.pat3 << std::endl;
175+
176+ std::cout << " pat1 length:\t\t " << std::dec << ppInfo.pat1Length << std::endl;
177+ std::cout << " pat1 delay:\t\t " << std::dec << ppInfo.pat1Delay << std::endl;
178+ std::cout << " pat2 length:\t\t " << std::dec << ppInfo.pat2Length << std::endl;
179+ std::cout << " pat3 length:\t\t " << std::dec << ppInfo.pat3Length << std::endl;
180+
181+ std::cout << " pat1 trigger select:\t 0x" << std::hex << ppInfo.pat1TriggerSelect << std::endl;
182+ std::cout << " pat2 trigger select:\t 0x" << std::hex << ppInfo.pat2TriggerSelect << std::endl;
183+ std::cout << " pat3 trigger select:\t 0x" << std::hex << ppInfo.pat3TriggerSelect << std::endl;
184+
185+ std::cout << " pat2 trigger counters:\t "
186+ << " TF 0x" << std::hex << ((ppInfo.pat2TriggerTF >> 20 ) & 0xFFF )
187+ << " ORBIT 0x" << std::hex << ((ppInfo.pat2TriggerTF >> 12 ) & 0xFF )
188+ << " BC 0x" << std::hex << (ppInfo.pat2TriggerTF & 0xFFF )
189+ << std::endl;
124190 }
125191 }
126192
127193 private:
128194 struct OptionsStruct {
129- std::string syncPattern = " 0x0" ;
130- std::string resetPattern = " 0x0" ;
131- std::string idlePattern = " 0x0" ;
132- uint32_t syncLength = 1 ;
133- uint32_t syncDelay = 0 ;
134- uint32_t resetLength = 1 ;
135- uint32_t resetTriggerSelect = 30 ;
136- uint32_t syncTriggerSelect = 29 ;
137- bool syncAtStart = false ;
138- bool triggerSync = false ;
139- bool triggerReset = false ;
195+ std::string pat0;
196+ std::string pat1;
197+ std::string pat2;
198+ std::string pat3;
199+ PatternPlayer::Info info;
140200 bool readBack = false ;
141201 } mOptions ;
142202};
0 commit comments