From bd5617bd56242257ec6d58236f9f41e079dbfe1c Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Sat, 18 Jul 2020 03:12:06 +0900
Subject: [PATCH] Improve DMA test software

---
 .../main_pcie40_dmahighrate.cpp               | 97 +++++++++++--------
 1 file changed, 57 insertions(+), 40 deletions(-)

diff --git a/Pcie40Applications/main_pcie40_dmahighrate.cpp b/Pcie40Applications/main_pcie40_dmahighrate.cpp
index c118d95..7180c0a 100644
--- a/Pcie40Applications/main_pcie40_dmahighrate.cpp
+++ b/Pcie40Applications/main_pcie40_dmahighrate.cpp
@@ -1,4 +1,3 @@
-bool check_second_crc = false ;
 bool exit_on_error = false ;
 int nTot = 1000000 ;
 int max_number_of_messages = 10 ;
@@ -75,7 +74,7 @@ const int CRC16_XMODEM_TABLE[] = {
   0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
 } ;
 
-void crc_calc( unsigned int & crc, unsigned int & data ){
+void crc_calc( unsigned int & crc, const unsigned int & data ){
   int byte1, byte2, byte3, byte4 ;
   byte1 = data & 0xFF;
   byte2 = ( data & 0xFF00 ) >> 8;
@@ -87,8 +86,7 @@ void crc_calc( unsigned int & crc, unsigned int & data ){
   crc = (((crc)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc)>>8)&0xff)^byte1] ;
 }
 
-unsigned int get_crc( std::vector< unsigned int > &data , unsigned int initial_value ) {
-  //  return 0 ;
+unsigned int get_crc( const std::vector< unsigned int > &data , unsigned int initial_value ) {
   unsigned int result = initial_value ;
   for( auto it = data.begin() ; it != data.end() ; ++it ) crc_calc( result , (*it) ) ;
   return result ;
@@ -135,7 +133,7 @@ void printFullData( unsigned int * data ) {
             data[8*eventSize+3], data[8*eventSize+2], data[8*eventSize+1], data[8*eventSize] ) ;
 }
 
-int analyzeHeader( unsigned int * data , unsigned int & size , double & dsize , int & total_pages , int & index_pages ) 
+int analyzeHeader( unsigned int * & data , unsigned int & size , double & dsize , int & total_pages , int & index_pages ) 
 {
   if ( data == 0 ) {
     n_messages[ 0 ] = n_messages[ 0 ] + 1 ; 
@@ -143,8 +141,8 @@ int analyzeHeader( unsigned int * data , unsigned int & size , double & dsize ,
       printf( "No data\n" ) ;
     return 1 ; 
   }
-  size = data[ 0 ] & 0xFFFF ;
-  dsize += size * 32 ;  // in bytes 
+  unsigned int fragment_size = data[ 0 ] & 0xFFFF ;
+  dsize += fragment_size * 32 ;  // in bytes 
   if ( ( data[7] != 0 ) || ( data[6] != 0 ) || ( data[5] != 0 ) || ( data[3] != 0 ) ) {
     n_messages[ 1 ] = n_messages[ 1 ] + 1 ; 
     if ( n_messages[ 1 ] < max_number_of_messages )  {
@@ -152,15 +150,15 @@ int analyzeHeader( unsigned int * data , unsigned int & size , double & dsize ,
       printHeader( data ) ; 
     }
     return 1 ;
-  } else if ( ( data[ 0 ] & 0xFFFF ) != size ) {
+  } else if ( ( data[ 0 ] & 0xFFFF ) != fragment_size ) {
     n_messages[ 2 ] = n_messages[ 2 ] + 1 ; 
     if ( n_messages[ 2 ] < max_number_of_messages ) 
-      printf( "Bad size %d %d\n" , data[0] & 0xFFFF , size ) ;
+      printf( "Bad size %d %d\n" , data[0] & 0xFFFF , fragment_size ) ;
     return 1 ;
-  } else if ( ( ( data[ 2 ] & 0xFFFF0000 ) >> 16 ) != ( size * 32 ) ) {
+  } else if ( ( ( data[ 2 ] & 0xFFFF0000 ) >> 16 ) != ( fragment_size * 32 ) ) {
     n_messages[ 3 ] = n_messages[ 3 ] + 1 ; 
     if ( n_messages[ 3 ] < max_number_of_messages ) 
-      printf( "Bad word size %d %d\n" , ( data[ 2 ] & 0xFFFF0000 ) >> 16 , size * 32 ) ;
+      printf( "Bad word size %d %d\n" , ( data[ 2 ] & 0xFFFF0000 ) >> 16 , fragment_size * 32 ) ;
     return 1 ;
   } else if ( ( ( data[ 0 ] & 0xFFFF0000 ) != 0xEEEE0000 ) || 
 	      ( data[ 1 ] != 0xAAAAEEEE ) ||
@@ -173,19 +171,19 @@ int analyzeHeader( unsigned int * data , unsigned int & size , double & dsize ,
     return 1 ;
   }
   // Check trailer
-  if ( data[ 8*(size-1) ] != size ) {
+  if ( data[ 8*(fragment_size-1) ] != fragment_size ) {
     n_messages[ 5 ] = n_messages[ 5 ] + 1 ; 
     if ( n_messages[ 5 ] < max_number_of_messages ) 
-      printf( "Bad size in trailer %d %d\n" , data[8*(size-1)], size ) ;
+      printf( "Bad size in trailer %d %d\n" , data[8*(fragment_size-1)], fragment_size ) ;
     return 1 ;
-  } else if ( ( data[ 8*(size-1)+1 ] != 0 ) || ( data[ 8*(size-1)+2 ] != 0 ) || 
-	      ( data[ 8*(size-1)+3 ] != 0 ) || ( data[ 8*(size-1)+4 ] != 0 ) ||
-	      ( data[ 8*(size-1)+5 ] != 0 ) || ( data[ 8*(size-1)+6 ] != 0 ) || 
-	      ( data[ 8*(size-1)+7 ] != 0 ) ) {
+  } else if ( ( data[ 8*(fragment_size-1)+1 ] != 0 ) || ( data[ 8*(fragment_size-1)+2 ] != 0 ) || 
+	      ( data[ 8*(fragment_size-1)+3 ] != 0 ) || ( data[ 8*(fragment_size-1)+4 ] != 0 ) ||
+	      ( data[ 8*(fragment_size-1)+5 ] != 0 ) || ( data[ 8*(fragment_size-1)+6 ] != 0 ) || 
+	      ( data[ 8*(fragment_size-1)+7 ] != 0 ) ) {
     n_messages[ 6 ] = n_messages[ 6 ] + 1 ; 
     if ( n_messages[ 6 ] < max_number_of_messages ) {
       printf( "Bad trailer\n" ) ;
-      printTrailer( &data[ 8*(size-1) ] ) ;
+      printTrailer( &data[ 8*(fragment_size-1) ] ) ;
     }
     return 1 ;
   }
@@ -193,15 +191,19 @@ int analyzeHeader( unsigned int * data , unsigned int & size , double & dsize ,
   total_pages = ( data[ 4 ] & 0xFFFF0000 ) >> 16 ;
   index_pages = ( data[ 4 ] & 0xFFFF ) ; 
 
+  size = fragment_size ;
+
   // Remove header and trailer from data
-  std::copy( data + 8 , data + 8*(size-1) , data ) ;
+  unsigned int * tmp = new unsigned int[ S_PAGE_SLOT_SIZE/4 ] ;
+  memcpy( tmp , &data[ 8 ], 8*(fragment_size-2)*4 ) ;  
+  delete [] data ;
+  data = tmp ;
   if ( total_pages != 1 ) return -1 ; 
   return 0 ; 
 }
 
 int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned int &exprun , unsigned int &runnumber , unsigned int &evtnum ,
 		      std::set< int > vlinks ) {
-
   //  TO CHECK LATER unsigned int event_size = data[ 8 ] ; 
   if ( ( data[ 1 ] & 0xFFFF0000 ) != 0x7F7F0000 ) {
     n_messages[ 7 ] = n_messages[ 7 ] + 1 ; 
@@ -247,13 +249,15 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
   f_crc.push_back( exp_run ) ;
   unsigned int first_crc = get_crc( f_crc , crc_init ) ;
 
+  std::vector< unsigned int > all_crc_data ; 
+  all_crc_data.reserve( 48 ) ;
+  std::vector< std::vector< unsigned int > > data_all_crc ;
+  
   // find number of links
   unsigned int numLinks = 0 ;
   unsigned int linksize = data[ 8 ] & 0xFFFFFFFF ;  // to be checked with Yamada-san if OK
   unsigned int current_event_start = 8 ;
 
-  bool first_crc_checked = false ;
-
   while ( true ) { 
     unsigned int linknumber = ( data[ current_event_start + 1 ] & 0xFF00 ) >> 8 ;
     if ( vlinks.count( linknumber ) == 0 ) { 
@@ -282,16 +286,15 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
       return 1 ;
     }
     std::vector< unsigned int > data_crc( data + current_event_start + 2 , data + current_event_start + linksize - 2 ) ;
+    data_all_crc.push_back( data_crc ) ;
     unsigned int crc_calc = get_crc( data_crc , first_crc ) ;
     unsigned int crc_data = data[ current_event_start + linksize - 2 ] & 0xFFFF ;
+    all_crc_data.push_back( crc_data ) ;
     if ( crc_calc != crc_data ) {
-      if ( ( check_second_crc ) ) { // || ( ! first_crc_checked ) ) {
-	n_messages[ 15 ] = n_messages[ 15 ] + 1 ; 
-	if ( n_messages[ 15 ] < max_number_of_messages ) 
-	  printf( "CRC Error %X %X %d %d\n" , crc_calc , crc_data , first_crc_checked , check_second_crc ) ;
-	return 1 ;
-      }
-      first_crc_checked = true ;
+      n_messages[ 15 ] = n_messages[ 15 ] + 1 ; 
+      if ( n_messages[ 15 ] < max_number_of_messages ) 
+    	printf( "CRC Error %X %X\n" , crc_calc , crc_data ) ;
+      return 1 ;
     }
     numLinks++ ;
     if ( ( ( data[ current_event_start + linksize ] & 0xFFFF0000 ) == 0x7FFF0000 ) ) break ;
@@ -305,10 +308,22 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
       printf( "Some links are missing\n" ) ;
     return 1 ;
   }
+
+  int index = 0 ; 
+  for( auto it = data_all_crc.begin() ; it != data_all_crc.end() ; ++it ) {
+    //    printf( "CRC Error %X %X for link %d\n" , get_crc( (*it) , first_crc )  , all_crc_data[ index ] , index ) ;
+    if ( get_crc( (*it) , first_crc ) != all_crc_data[ index ] ) {
+      n_messages[ 15 ] = n_messages[ 15 ] + 1 ;
+      if ( n_messages[ 15 ] < max_number_of_messages )
+        printf( "CRC Error %X %X for link %d\n" , get_crc( (*it) , first_crc )  , all_crc_data[ index ] , index ) ;
+      return 1 ;
+    }
+    index++ ;
+  }
+
   return 0 ;
 }
 
-
 void analyzeEventGenerator( unsigned int * data , int i , unsigned int size ) {
   if ( data == 0 ) {
     printf( "No data\n" ) ;
@@ -360,8 +375,6 @@ void analyzeEventGenerator( unsigned int * data , int i , unsigned int size ) {
 // 0 = data, 1 = generator
 
 int main (int argc ,char** argv) {
-  std::vector< unsigned int > te ; 
-  get_crc( te , 0 ) ; 
   double triggerRate = 400 ; // kHz
   double data_size = 0. ;
 
@@ -449,6 +462,7 @@ int main (int argc ,char** argv) {
   int total_pages = 0 ; 
   int index_pages = 0 ; 
   int previous_index = 0 ; 
+  unsigned int frag_size = 0 ;
   auto t1 = std::chrono::high_resolution_clock::now();
   while ( k < nTot ) { 
     // start DMA and wait for one or more super pages of data
@@ -463,16 +477,17 @@ int main (int argc ,char** argv) {
       // printf( "Event number %d\n" , getEventNumber( data ) ) ; 
       if ( ! isData ) analyzeEventGenerator( data , i , size ) ;
       else { 
-	int ret = analyzeHeader( data , esize , data_size , total_pages , index_pages ) ; 
-
+	int ret = analyzeHeader( data , frag_size , data_size , total_pages , index_pages ) ; 
 	if ( 0 != ret ) { 
 	  if ( -1 == ret ) {
-	    if ( index_pages == 0 ) 
+	    if ( index_pages == 0 ) {
+	      esize = frag_size ;
 	      combined_data = new unsigned int[ total_pages * S_PAGE_SLOT_SIZE/4 ] ;
-	    std::copy( data , data + 8*(size-2) , combined_data + previous_index ) ; 
-	    previous_index = previous_index + 8*(size-2) ;
+	    } else esize += frag_size ;
+	    memcpy( &combined_data[ previous_index ] , data , 8*(frag_size-2)*4 ) ;
+	    delete [] data ;
+	    previous_index = previous_index + 8*(frag_size-2) ;
 	    if ( index_pages != ( total_pages - 1 ) ) {
-	      delete data ;
 	      ++i ;
 	      if ( ( i > 0 ) && ( ( i % S_PAGE_SLOT_NMB ) == 0 ) ) pcie40_freeSuperPage( 0 , 1 ) ;
 	      continue ; 
@@ -482,13 +497,15 @@ int main (int argc ,char** argv) {
 	    if ( exit_on_error ) exit( 0 ) ;
 	    errors++ ;
 	  }
-	} else if ( 0 != analyzeEventData( data , i , esize , exprun , runnumber , evtnum , valid_links ) ) {
+	} else esize = frag_size ;
+	
+	if ( 0 != analyzeEventData( data , k , esize , exprun , runnumber , evtnum , valid_links ) ) {
 	  if ( exit_on_error ) exit( 0 ) ;
 	  errors++ ;
 	}
       }
       previous_index = 0 ; 
-      delete data ;
+      delete [] data ;
       // if ( i != getEventNumber( data ) ) printf( "Mismatch event number %d %d\n" , i , getEventNumber( data ) ) ;
       ++i ;
       ++k ;
-- 
GitLab