μHAL (v2.6.5)
Part of the IPbus software repository
IPbusInspector.cpp
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 
4  This file is part of uHAL.
5 
6  uHAL is a hardware access library and programming framework
7  originally developed for upgrades of the Level-1 trigger of the CMS
8  experiment at CERN.
9 
10  uHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  uHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Andrew Rose, Imperial College, London
25  email: awr01 <AT> imperial.ac.uk
26 
27  Marc Magrans de Abril, CERN
28  email: marc.magrans.de.abril <AT> cern.ch
29 
30 ---------------------------------------------------------------------------
31 */
32 
33 #include "uhal/IPbusInspector.hpp"
34 
35 
36 #include "uhal/ProtocolIPbus.hpp"
37 #include "uhal/log/LogLevels.hpp"
39 #include "uhal/log/log.hpp"
40 
41 
42 namespace uhal
43 {
44 
45  template< uint8_t IPbus_major , uint8_t IPbus_minor >
47  mHeader ( 0 ),
48  mWordCounter ( 0 ),
49  mTransactionId ( 0 ),
50  mResponseGood ( 0 ),
51  mPacketHeader ( 0 ),
52  mPacketCounter ( 0 ),
53  mPacketType ( 0 )
54  {}
55 
56  template< uint8_t IPbus_major , uint8_t IPbus_minor >
58 
59  template< uint8_t IPbus_major , uint8_t IPbus_minor >
60  bool HostToTargetInspector<IPbus_major , IPbus_minor>::analyze ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd , const bool& aContinueOnError )
61  {
62  for ( std::vector<uint32_t>::const_iterator lIt ( aIt ); lIt != aEnd; ++lIt )
63  {
64  log ( Debug , Integer ( *lIt, IntFmt<hex,fixed>() ) );
65  }
66 
67  // log ( Notice() , Pointer(&(*aIt)) , " : " , Pointer(&(*aEnd)) , "(", Integer((&(*aEnd)-&(*aIt))*4) ,")" );
68  uint32_t lAddress , lAddend , lAndTerm , lOrTerm ;
69  std::vector<uint32_t>::const_iterator lPayloadBegin, lPayloadEnd;
70 
71  if ( IPbus_major != 1 )
72  {
73  mPacketHeader = *aIt++;
74  mPacketCounter = ( mPacketHeader>>8 ) &0xFFFF ;
75  mPacketType = mPacketHeader&0x0F ;
76  }
77 
78  switch ( mPacketType )
79  {
80  case 0:
81 
82  if ( IPbus_major != 1 )
83  {
84  if ( !control_packet_header ( ) )
85  {
86  return true;
87  }
88  }
89 
90  do
91  {
92  mHeader = *aIt++;
93 
95  mHeader ,
96  mType ,
97  mWordCounter ,
100  )
101  {
102  log ( Error() , "Unable to parse send header " , Integer ( mHeader, IntFmt<hex,fixed>() ) );
103 
104  if ( IPbus_major != 1 )
105  {
106  if ( ! aContinueOnError )
107  {
108  aIt--;
109  return true;
110  }
111 
112  log ( Warning() , "Attempting to see if it is because the bad header was, in fact, a packet header" );
113  aIt--;
114  return this->analyze ( aIt , aEnd );
115  }
116  else
117  {
118  return false;
119  }
120  }
121 
122  if ( ( IPbus_major==1 && mResponseGood != 0 ) || ( IPbus_major==2 && mResponseGood != 0xf ) )
123  {
124  log ( Error(), "Bad InfoCode value of ", Integer ( mResponseGood ), " detected in IPbus transaction request header ", Integer ( mHeader, IntFmt<hex,fixed>() ) );
125  return false;
126  }
127 
128  switch ( mType )
129  {
130  case B_O_T:
131  bot();
132  break;
133  case NI_READ:
134  lAddress = *aIt++;
135  ni_read ( lAddress );
136  break;
137  case READ:
138  lAddress = *aIt++;
139  read ( lAddress );
140  break;
141  case CONFIG_SPACE_READ:
142  lAddress = *aIt++;
143  readConfigurationSpace( lAddress );
144  break;
145  case NI_WRITE:
146  lAddress = *aIt++;
147  lPayloadBegin = aIt;
148  lPayloadEnd = aIt + mWordCounter;
149  ni_write ( lAddress , lPayloadBegin , lPayloadEnd );
150  aIt += mWordCounter;
151  break;
152  case WRITE:
153  lAddress = *aIt++;
154  lPayloadBegin = aIt;
155  lPayloadEnd = aIt + mWordCounter;
156  write ( lAddress , lPayloadBegin , lPayloadEnd );
157  aIt += mWordCounter;
158  break;
159  case RMW_SUM:
160  lAddress = *aIt++;
161  lAddend = *aIt++;
162  rmw_sum ( lAddress , lAddend );
163  break;
164  case RMW_BITS:
165  lAddress = *aIt++;
166  lAndTerm = *aIt++;
167  lOrTerm = *aIt++;
168  rmw_bits ( lAddress , lAndTerm , lOrTerm );
169  break;
170  default:
171  unknown_type();
172  return false;
173  }
174  }
175  while ( aIt!=aEnd );
176 
177  break;
178  case 1:
179  aIt=aEnd;
181  break;
182  case 2:
183  aIt=aEnd;
185  break;
186  default:
188  return false;
189  }
190 
191  return true;
192  }
193 
194 
195  template< uint8_t IPbus_major , uint8_t IPbus_minor >
197  {
198  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | BOT, transaction ID " , Integer ( mTransactionId ) );
199  }
200 
201 
202  template< uint8_t IPbus_major , uint8_t IPbus_minor >
204  {
205  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
206  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
207  }
208 
209 
210  template< uint8_t IPbus_major , uint8_t IPbus_minor >
212  {
213  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
214  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
215  }
216 
217 
218  template< uint8_t IPbus_major , uint8_t IPbus_minor >
220  {
221  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing 'configuration space' read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
222  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
223  }
224 
225 
226  template< uint8_t IPbus_major , uint8_t IPbus_minor >
227  void HostToTargetInspector<IPbus_major , IPbus_minor>::ni_write ( const uint32_t& aAddress , std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
228  {
229  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
230  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
231  uint32_t lCounter ( 0 );
232 
233  while ( aIt != aEnd )
234  {
235  log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
236  }
237  }
238 
239 
240  template< uint8_t IPbus_major , uint8_t IPbus_minor >
241  void HostToTargetInspector<IPbus_major , IPbus_minor>::write ( const uint32_t& aAddress , std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
242  {
243  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
244  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
245  uint32_t lCounter ( 0 );
246 
247  while ( aIt != aEnd )
248  {
249  log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
250  }
251  }
252 
253 
254  template< uint8_t IPbus_major , uint8_t IPbus_minor >
255  void HostToTargetInspector<IPbus_major , IPbus_minor>::rmw_sum ( const uint32_t& aAddress , const uint32_t& aAddend )
256  {
257  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write sum, transaction ID " , Integer ( mTransactionId ) );
258  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
259  log ( Notice() , Integer ( aAddend, IntFmt<hex,fixed>() ) , " | > Addend" );
260  }
261 
262 
263  template< uint8_t IPbus_major , uint8_t IPbus_minor >
264  void HostToTargetInspector<IPbus_major , IPbus_minor>::rmw_bits ( const uint32_t& aAddress , const uint32_t& aAndTerm , const uint32_t& aOrTerm )
265  {
266  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write bits, transaction ID " , Integer ( mTransactionId ) );
267  log ( Notice() , Integer ( aAddress, IntFmt<hex,fixed>() ) , " | > Address" );
268  log ( Notice() , Integer ( aAndTerm, IntFmt<hex,fixed>() ) , " | > And-term" );
269  log ( Notice() , Integer ( aOrTerm, IntFmt<hex,fixed>() ) , " | > Or-term" );
270  }
271 
272 
273  template< uint8_t IPbus_major , uint8_t IPbus_minor >
275  {
276  log ( Error() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Unknown Transaction Header" );
277  }
278 
279 
280  template< uint8_t IPbus_major , uint8_t IPbus_minor >
282  {
283  log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Control (Instruction) Packet Header , Packet Counter " , Integer ( mPacketCounter ) );
284  return true;
285  }
286 
287 
288  template< uint8_t IPbus_major , uint8_t IPbus_minor >
290  {
291  log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Status Packet Header" );
292  }
293 
294 
295  template< uint8_t IPbus_major , uint8_t IPbus_minor >
297  {
298  log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Resend Request Packet Header" );
299  }
300 
301 
302  template< uint8_t IPbus_major , uint8_t IPbus_minor >
304  {
305  log ( Error() , Integer ( mPacketHeader, IntFmt<hex,fixed>() ) , " | Unknown Packet Header" );
306  }
307 
308 
309 
310 
311 
312  template< uint8_t IPbus_major , uint8_t IPbus_minor >
315  mHeader ( 0 ),
316  mWordCounter ( 0 ),
317  mTransactionId ( 0 ),
318  mResponseGood ( 0 ),
319  mPacketHeader ( 0 ),
320  mPacketCounter ( 0 ),
321  mPacketType ( 0 )
322  {}
323 
324 
325  template< uint8_t IPbus_major , uint8_t IPbus_minor >
327 
328 
329  template< uint8_t IPbus_major , uint8_t IPbus_minor >
330  bool TargetToHostInspector<IPbus_major , IPbus_minor>::analyze ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd , const bool& aContinueOnError )
331  {
332  uint32_t lNewValue;
333  std::vector<uint32_t>::const_iterator lPayloadBegin, lPayloadEnd;
334 
335  if ( IPbus_major != 1 )
336  {
337  mPacketHeader = *aIt++;
338  mPacketCounter = ( mPacketHeader>>8 ) &0xFFFF ;
339  mPacketType = mPacketHeader&0x0F ;
340  }
341 
342  switch ( mPacketType )
343  {
344  case 0:
345 
346  if ( IPbus_major != 1 )
347  {
348  if ( !control_packet_header ( ) )
349  {
350  return false;
351  }
352  }
353 
354  do
355  {
356  mHeader = *aIt++;
357 
359  mHeader ,
360  mType ,
361  mWordCounter ,
363  mResponseGood )
364  )
365  {
366  log ( Error() , "Unable to parse reply header " , Integer ( mHeader, IntFmt<hex,fixed>() ) );
367 
368  if ( IPbus_major != 1 )
369  {
370  if ( ! aContinueOnError )
371  {
372  aIt--;
373  return true;
374  }
375 
376  log ( Warning() , "Attempting to see if it is because the bad header was, in fact, a packet header" );
377  aIt--;
378  return this->analyze ( aIt , aEnd );
379  }
380  else
381  {
382  return false;
383  }
384  }
385 
386  switch ( mType )
387  {
388  case B_O_T:
389  bot();
390  break;
391  case NI_READ:
392  lPayloadBegin = aIt;
393  lPayloadEnd = aIt + mWordCounter;
394  ni_read ( lPayloadBegin , lPayloadEnd );
395  aIt += mWordCounter;
396  break;
397  case READ:
398  lPayloadBegin = aIt;
399  lPayloadEnd = aIt + mWordCounter;
400  read ( lPayloadBegin , lPayloadEnd );
401  aIt += mWordCounter;
402  break;
403  case NI_WRITE:
404  ni_write ();
405  break;
406  case WRITE:
407  write ();
408  break;
409  case RMW_SUM:
410  lNewValue = *aIt++;
411  rmw_sum ( lNewValue );
412  break;
413  case RMW_BITS:
414  lNewValue = *aIt++;
415  rmw_bits ( lNewValue );
416  break;
417  default:
418  unknown_type();
419  return false;
420  }
421  }
422  while ( aIt!=aEnd );
423 
424  break;
425  case 1:
426  aIt=aEnd;
428  break;
429  default:
431  return false;
432  }
433 
434  return true;
435  }
436 
437 
438  template< uint8_t IPbus_major , uint8_t IPbus_minor >
440  {
441  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | BOT, transaction ID " , Integer ( mTransactionId ) );
442  }
443 
444 
445  template< uint8_t IPbus_major , uint8_t IPbus_minor >
446  void TargetToHostInspector<IPbus_major , IPbus_minor>::ni_read ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
447  {
448  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
449  uint32_t lCounter ( 0 );
450 
451  while ( aIt != aEnd )
452  {
453  log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
454  }
455  }
456 
457 
458  template< uint8_t IPbus_major , uint8_t IPbus_minor >
459  void TargetToHostInspector<IPbus_major , IPbus_minor>::read ( std::vector<uint32_t>::const_iterator& aIt , const std::vector<uint32_t>::const_iterator& aEnd )
460  {
461  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing read, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
462  uint32_t lCounter ( 0 );
463 
464  while ( aIt != aEnd )
465  {
466  log ( Notice() , Integer ( *aIt++, IntFmt<hex,fixed>() ) , " | > Data [" , Integer ( lCounter++ ) , "]" );
467  }
468  }
469 
470 
471  template< uint8_t IPbus_major , uint8_t IPbus_minor >
473  {
474  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Non-incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
475  }
476 
477 
478  template< uint8_t IPbus_major , uint8_t IPbus_minor >
480  {
481  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Incrementing write, size " , Integer ( mWordCounter ) , ", transaction ID " , Integer ( mTransactionId ) );
482  }
483 
484 
485  template< uint8_t IPbus_major , uint8_t IPbus_minor >
487  {
488  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write sum, transaction ID " , Integer ( mTransactionId ) );
489  log ( Notice() , Integer ( aNewValue, IntFmt<hex,fixed>() ) , " | > Data" );
490  }
491 
492 
493  template< uint8_t IPbus_major , uint8_t IPbus_minor >
495  {
496  log ( Notice() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Read-modify-write bits, transaction ID " , Integer ( mTransactionId ) );
497  log ( Notice() , Integer ( aNewValue, IntFmt<hex,fixed>() ) , " | > Data" );
498  }
499 
500 
501  template< uint8_t IPbus_major , uint8_t IPbus_minor >
503  {
504  log ( Error() , Integer ( mHeader, IntFmt<hex,fixed>() ) , " | Unknown Transaction Header" );
505  }
506 
507 
508  template< uint8_t IPbus_major , uint8_t IPbus_minor >
510  {
511  log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Control (Instruction) Packet Header , Packet Counter " , Integer ( mPacketCounter ) );
512  return true;
513  }
514 
515 
516  template< uint8_t IPbus_major , uint8_t IPbus_minor >
518  {
519  log ( Notice() , Integer ( mPacketHeader , IntFmt<hex,fixed>() ) , " | Status Packet Header" );
520  }
521 
522 
523  template< uint8_t IPbus_major , uint8_t IPbus_minor >
525  {
526  log ( Error() , Integer ( mPacketHeader, IntFmt<hex,fixed>() ) , " | Unknown Packet Header" );
527  }
528 
529 
530  template class HostToTargetInspector<1, 3>;
531  template class HostToTargetInspector<2, 0>;
532  template class TargetToHostInspector<1, 3>;
533  template class TargetToHostInspector<2, 0>;
534 }
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t&#39;s.
NoticeLevel Notice
Definition: LogLevels.cpp:96
virtual void unknown_type()
Virtual callback function for the case where the header is unknown.
uint32_t mTransactionId
The current transaction id.
A class which provides the version-specific functionality for IPbus.
virtual bool control_packet_header()
Virtual callback function called when an IPbus 2.0 control packet header is observed.
virtual void rmw_sum(const uint32_t &aAddress, const uint32_t &aAddend)
Virtual callback function called when a read-modify-write sum is observed.
uint32_t mPacketType
The current IPbus2 packet type.
Helper class to decode IPbus packets as passed from the Client to the Target.
virtual void read(const uint32_t &aAddress)
Virtual callback function called when an incrementing read is observed.
uint32_t mTransactionId
The current transaction id.
virtual void write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when an incrementing write is observed.
virtual ~TargetToHostInspector()
Destructor.
virtual void rmw_sum(const uint32_t &aNewValue)
Virtual callback function called when a read-modify-write sum is observed.
uint32_t mHeader
The current raw transaction header.
uint32_t mPacketHeader
The current raw IPbus2 packet header.
virtual bool control_packet_header()
Virtual callback function called when an IPbus 2.0 control packet header is observed.
virtual void unknown_packet_header()
Virtual callback function called when an unknown IPbus 2.0 packet header is observed.
virtual void ni_write()
Virtual callback function called when a non-incrementing write is observed.
virtual void ni_write(const uint32_t &aAddress, std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when a non-incrementing write is observed.
WarningLevel Warning
Definition: LogLevels.cpp:79
TargetToHostInspector()
Default constructor.
virtual void ni_read(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when a non-incrementing read is observed.
uint32_t mWordCounter
The current word count.
Helper class to decode IPbus packets as passed from the Target to the Client.
ErrorLevel Error
Definition: LogLevels.cpp:61
virtual void unknown_type()
Virtual callback function for the case where the header is unknown.
virtual void bot()
Virtual callback function called when a Byte-OrderTransaction is observed.
virtual void ni_read(const uint32_t &aAddress)
Virtual callback function called when a non-incrementing read is observed.
Empty struct which acts as a dummy variable for passing the formatting information around...
eIPbusTransactionType mType
The current transaction type.
uint32_t mPacketType
The current IPbus2 packet type.
virtual void unknown_packet_header()
Virtual callback function called when an unknown IPbus 2.0 packet header is observed.
uint32_t mHeader
The current raw transaction header.
virtual void rmw_bits(const uint32_t &aNewValue)
Virtual callback function called when a read-modify-write bits is observed.
uint8_t mResponseGood
The current error code/flag.
eIPbusTransactionType mType
The current transaction type.
virtual void rmw_bits(const uint32_t &aAddress, const uint32_t &aAndTerm, const uint32_t &aOrTerm)
Virtual callback function called when a read-modify-write bits is observed.
virtual void resend_packet_header()
Virtual callback function called when an IPbus 2.0 resend packet header is observed.
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t&#39;s.
virtual void write()
Virtual callback function called when an incrementing write is observed.
virtual void status_packet_header()
Virtual callback function called when an IPbus 2.0 status packet header is observed.
HostToTargetInspector()
Default constructor.
virtual ~HostToTargetInspector()
Destructor.
uint32_t mPacketCounter
The current IPbus2 packet counter.
uint32_t mWordCounter
The current word count.
virtual void read(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd)
Virtual callback function called when an incrementing read is observed.
DebugLevel Debug
Definition: LogLevels.cpp:133
virtual void status_packet_header()
Virtual callback function called when an IPbus 2.0 status packet header is observed.
virtual void readConfigurationSpace(const uint32_t &aAddress)
Virtual callback function called when an incrementing "configuration space" read is observed...
uint8_t mResponseGood
The current error code/flag.
virtual void bot()
Virtual callback function called when a Byte-OrderTransaction is observed.
uint32_t mPacketCounter
The current IPbus2 packet counter.
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
uint32_t mPacketHeader
The current raw IPbus2 packet header.