@@ -154,5 +154,142 @@ void PatternPlayer::exePat2()
154154 mBar ->modifyRegister (Cru::Registers::PATPLAYER_CFG.index , 4 , 1 , 0x0 );
155155}
156156
157+ uint128_t PatternPlayer::getValueFromString (const std::string &s, unsigned int nBits, const std::string &name) {
158+ if (nBits > 128 ) {
159+ nBits = 128 ;
160+ }
161+ uint128_t v = 0 ;
162+ uint128_t vmax = (((uint128_t )1 ) << nBits) - 1 ;
163+ std::string error = " Parsing parameter " + name + " : " ;
164+ auto addDigit = [&] (uint128_t digit, uint128_t base) {
165+ bool overflow = 0 ;
166+ if (digit >= base) {
167+ overflow =1 ;
168+ } else if (v > (vmax / base)) {
169+ overflow = 1 ;
170+ }
171+ v = v * ((uint128_t )base);
172+ if (v > vmax - ((uint128_t )digit)) {
173+ overflow = 1 ;
174+ }
175+ v = v + ((uint128_t )digit);
176+ if (v > vmax) {
177+ overflow = 1 ;
178+ }
179+ if (overflow) {
180+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
181+ << ErrorInfo::Message (error + " Value exceeds " + std::to_string (nBits) + " bits" ));
182+ }
183+ return ;
184+ };
185+ if (!strncmp (s.c_str (), " 0x" , 2 )) {
186+ // hexadecimal string
187+ for (unsigned int i=2 ; i<s.length (); i++) {
188+ uint8_t c = s[i];
189+ uint128_t x = 0 ;
190+ if ( ( c >= ' 0' ) && ( c <= ' 9' )) {
191+ x = c - ' 0' ;
192+ } else if ( ( c >= ' A' ) && ( c <= ' F' )) {
193+ x = 10 + c - ' A' ;
194+ } else if ( ( c >= ' a' ) && ( c <= ' f' )) {
195+ x = 10 + c - ' a' ;
196+ } else {
197+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
198+ << ErrorInfo::Message (error + " Value has wrong hexadecimal syntax" ));
199+ }
200+ addDigit (x, (uint128_t )16 );
201+ }
202+ } else {
203+ // decimal string
204+ for (unsigned int i=0 ; i<s.length (); i++) {
205+ uint8_t c = s[i];
206+ uint128_t x = 0 ;
207+ if ( ( c >= ' 0' ) && ( c <= ' 9' )) {
208+ x = c - ' 0' ;
209+ } else {
210+ BOOST_THROW_EXCEPTION (InvalidOptionValueException ()
211+ << ErrorInfo::Message (error + " Value has wrong decimal syntax" ));
212+ }
213+ addDigit (x, (uint128_t )10 );
214+ }
215+ }
216+ return v;
217+ }
218+
219+ PatternPlayer::Info PatternPlayer::getInfoFromString (const std::vector<std::string> ¶meters) {
220+ roc::PatternPlayer::Info ppInfo;
221+
222+ int infoField = 0 ;
223+ for (const auto & parameter : parameters) {
224+ if (parameter.find (' #' ) == std::string::npos) {
225+ infoField++;
226+ }
227+ }
228+
229+ if (infoField != 15 ) { // Test that we have enough non-comment parameters
230+ BOOST_THROW_EXCEPTION (InvalidOptionValueException () << ErrorInfo::Message (" Wrong number of non-comment parameters for the Pattern Player: " + std::to_string (infoField) + " /15" ));
231+ }
232+
233+ infoField = 0 ;
234+ for (const auto & parameter : parameters) {
235+ if (parameter.find (' #' ) == std::string::npos) {
236+ switch (infoField) {
237+ bool boolValue;
238+ case 0 :
239+ ppInfo.pat0 = PatternPlayer::getValueFromString (parameter, 80 , " pat0" );
240+ break ;
241+ case 1 :
242+ ppInfo.pat1 = PatternPlayer::getValueFromString (parameter, 80 , " pat1" );
243+ break ;
244+ case 2 :
245+ ppInfo.pat2 = PatternPlayer::getValueFromString (parameter, 80 , " pat2" );
246+ break ;
247+ case 3 :
248+ ppInfo.pat3 = PatternPlayer::getValueFromString (parameter, 80 , " pat3" );
249+ break ;
250+ case 4 :
251+ ppInfo.pat1Length = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat1Length" );
252+ break ;
253+ case 5 :
254+ ppInfo.pat1Delay = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat1Delay" );
255+ break ;
256+ case 6 :
257+ ppInfo.pat2Length = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat2Length" );
258+ break ;
259+ case 7 :
260+ ppInfo.pat3Length = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat3Length" );
261+ break ;
262+ case 8 :
263+ ppInfo.pat1TriggerSelect = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat1TriggerSelect" );
264+ break ;
265+ case 9 :
266+ ppInfo.pat2TriggerSelect = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat2TriggerSelect" );
267+ break ;
268+ case 10 :
269+ ppInfo.pat3TriggerSelect = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat3TriggerSelect" );
270+ break ;
271+ case 11 :
272+ ppInfo.pat2TriggerTF = (uint32_t )PatternPlayer::getValueFromString (parameter, 32 , " pat2TriggerTF" );
273+ break ;
274+ case 12 :
275+ std::istringstream (parameter) >> std::boolalpha >> boolValue;
276+ ppInfo.exePat1AtStart = boolValue;
277+ break ;
278+ case 13 :
279+ std::istringstream (parameter) >> std::boolalpha >> boolValue;
280+ ppInfo.exePat1Now = boolValue;
281+ break ;
282+ case 14 :
283+ std::istringstream (parameter) >> std::boolalpha >> boolValue;
284+ ppInfo.exePat2Now = boolValue;
285+ break ;
286+ }
287+ infoField++;
288+ }
289+ }
290+ return ppInfo;
291+ }
292+
293+
157294} // namespace roc
158295} // namespace o2
0 commit comments