From 721eb62a54b4d8dc5f7d39ff3ce6211e0d2d2533 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Mon, 13 Jul 2020 07:42:30 +0900
Subject: [PATCH] Add possibility to test large (>8 kB) events

---
 Pcie40Applications/main_pcie40_dma.cpp        |  2 +-
 .../main_pcie40_dmahighrate.cpp               | 83 ++++++++++++++-----
 2 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/Pcie40Applications/main_pcie40_dma.cpp b/Pcie40Applications/main_pcie40_dma.cpp
index 8a8aaab..ba66d6d 100644
--- a/Pcie40Applications/main_pcie40_dma.cpp
+++ b/Pcie40Applications/main_pcie40_dma.cpp
@@ -73,7 +73,7 @@ int main (int argc ,char** argv) {
 
   unsigned int * data = pcie40_getSuperPagePointer( 0 , 0 , 0 ) ; 
   printData( data ) ; 
-  data = pcie40_getSuperPagePointer( 0 , 0 , 2 ) ; 
+  data = pcie40_getSuperPagePointer( 0 , 0 , 1 ) ; 
   printData( data ) ; 
   //data = pcie40_getSuperPagePointer( 0 , 1 , 0 ) ; 
   //printData( data ) ; 
diff --git a/Pcie40Applications/main_pcie40_dmahighrate.cpp b/Pcie40Applications/main_pcie40_dmahighrate.cpp
index e825160..c118d95 100644
--- a/Pcie40Applications/main_pcie40_dmahighrate.cpp
+++ b/Pcie40Applications/main_pcie40_dmahighrate.cpp
@@ -13,6 +13,7 @@ int max_number_of_messages = 10 ;
 #include <vector>
 #include <set>
 #include <map>
+#include <cstring>
 
 std::map< int , int > n_messages = { 
   { 0 , 0 } , // no data
@@ -87,6 +88,7 @@ void crc_calc( unsigned int & crc, unsigned int & data ){
 }
 
 unsigned int get_crc( std::vector< unsigned int > &data , unsigned int initial_value ) {
+  //  return 0 ;
   unsigned int result = initial_value ;
   for( auto it = data.begin() ; it != data.end() ; ++it ) crc_calc( result , (*it) ) ;
   return result ;
@@ -133,15 +135,14 @@ void printFullData( unsigned int * data ) {
             data[8*eventSize+3], data[8*eventSize+2], data[8*eventSize+1], data[8*eventSize] ) ;
 }
 
-int analyzeEventData( unsigned int * data , int i , unsigned int &exprun , unsigned int &runnumber , unsigned int &evtnum , double & dsize ,
-		      std::set< int > vlinks ) {
+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 ; 
     if ( n_messages[ 0 ] < max_number_of_messages ) 
       printf( "No data\n" ) ;
     return 1 ; 
   }
-  unsigned int size ;
   size = data[ 0 ] & 0xFFFF ;
   dsize += size * 32 ;  // in bytes 
   if ( ( data[7] != 0 ) || ( data[6] != 0 ) || ( data[5] != 0 ) || ( data[3] != 0 ) ) {
@@ -189,14 +190,26 @@ int analyzeEventData( unsigned int * data , int i , unsigned int &exprun , unsig
     return 1 ;
   }
 
+  total_pages = ( data[ 4 ] & 0xFFFF0000 ) >> 16 ;
+  index_pages = ( data[ 4 ] & 0xFFFF ) ; 
+
+  // Remove header and trailer from data
+  std::copy( data + 8 , data + 8*(size-1) , data ) ;
+  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[ 9 ] & 0xFFFF0000 ) != 0x7F7F0000 ) {
+  if ( ( data[ 1 ] & 0xFFFF0000 ) != 0x7F7F0000 ) {
     n_messages[ 7 ] = n_messages[ 7 ] + 1 ; 
     if ( n_messages[ 7 ] < max_number_of_messages ) 
       printf( "Bad code 7F7F\n" ) ;
     return 1 ;
   }
-  if ( ( data[ 9 ] & 0xFF00 ) >> 8 != 0 ) {
+  if ( ( data[ 1 ] & 0xFF00 ) >> 8 != 0 ) {
     n_messages[ 8 ] = n_messages[ 8 ] + 1 ; 
     if ( n_messages[ 8 ] < max_number_of_messages ) 
       printf( "Bad version\n" ) ;
@@ -204,27 +217,27 @@ int analyzeEventData( unsigned int * data , int i , unsigned int &exprun , unsig
   }
 
   if ( 0 == runnumber ) 
-    runnumber = (data[10]&0xFFFFFF00)>>8 ;
+    runnumber = (data[2]&0xFFFFFF00)>>8 ;
   else {
-    if ( runnumber != ((data[10]&0xFFFFFF00)>>8) )  {
+    if ( runnumber != ((data[2]&0xFFFFFF00)>>8) )  {
       n_messages[ 9 ] = n_messages[ 9 ] + 1 ; 
       if ( n_messages[ 9 ] < max_number_of_messages ) 
-	printf( "Bad runnumber: %d\n", (data[10]&0xFFFFFF00)>>8 ) ;
+	printf( "Bad runnumber: %d\n", (data[2]&0xFFFFFF00)>>8 ) ;
       return 1 ;
     }
   }
 
-  if ( evtnum == std::numeric_limits<unsigned int>::max() ) evtnum = data[11] ;
-  if ( ( evtnum + i ) != data[11] ) {
+  if ( evtnum == std::numeric_limits<unsigned int>::max() ) evtnum = data[3] ;
+  if ( ( evtnum + i ) != data[3] ) {
     n_messages[ 10 ] = n_messages[ 10 ] + 1 ; 
     if ( n_messages[ 10 ] < max_number_of_messages ) 
-      printf( "Bad event number %d %d\n" , i+evtnum , data[11] ) ;
+      printf( "Bad event number %d %d\n" , i+evtnum , data[3] ) ;
   }
   
-  unsigned int myevtnum = data[ 11 ] ; 
-  unsigned int ctime = data[ 12 ] ;
-  unsigned int utime = data[ 13 ] ;
-  unsigned int exp_run = data[ 10 ] ; 
+  unsigned int myevtnum = data[ 3 ] ; 
+  unsigned int ctime = data[ 4 ] ;
+  unsigned int utime = data[ 5] ;
+  unsigned int exp_run = data[ 2 ] ; 
 
   unsigned int crc_init = 0xFFFF ;
   std::vector< unsigned int > f_crc ; 
@@ -236,8 +249,8 @@ int analyzeEventData( unsigned int * data , int i , unsigned int &exprun , unsig
 
   // find number of links
   unsigned int numLinks = 0 ;
-  unsigned int linksize = data[ 16 ] & 0xFFFFFFFF ;  // to be checked with Yamada-san if OK
-  unsigned int current_event_start = 16 ;
+  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 ;
 
@@ -347,6 +360,8 @@ 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. ;
 
@@ -423,13 +438,19 @@ int main (int argc ,char** argv) {
 
   int rv ;
   unsigned int * data ;
+  unsigned int * combined_data; 
   int i = 0 ;
+  int k = 0 ; 
   unsigned int exprun = 0 ;
   unsigned int runnumber = 0; 
   unsigned int evtnum = std::numeric_limits<unsigned int>::max() ;
   int errors = 0 ;
+  unsigned int esize = 0 ; 
+  int total_pages = 0 ; 
+  int index_pages = 0 ; 
+  int previous_index = 0 ; 
   auto t1 = std::chrono::high_resolution_clock::now();
-  while ( i < nTot ) { 
+  while ( k < nTot ) { 
     // start DMA and wait for one or more super pages of data
     rv = pcie40_dmaStart( 0 ) ;
     //printf( "Number of super page received: %d\n" , rv ) ;
@@ -442,16 +463,36 @@ int main (int argc ,char** argv) {
       // printf( "Event number %d\n" , getEventNumber( data ) ) ; 
       if ( ! isData ) analyzeEventGenerator( data , i , size ) ;
       else { 
-	if ( 0 != analyzeEventData( data , i , exprun , runnumber , evtnum , data_size , valid_links ) ) {
+	int ret = analyzeHeader( data , esize , data_size , total_pages , index_pages ) ; 
+
+	if ( 0 != ret ) { 
+	  if ( -1 == ret ) {
+	    if ( index_pages == 0 ) 
+	      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) ;
+	    if ( index_pages != ( total_pages - 1 ) ) {
+	      delete data ;
+	      ++i ;
+	      if ( ( i > 0 ) && ( ( i % S_PAGE_SLOT_NMB ) == 0 ) ) pcie40_freeSuperPage( 0 , 1 ) ;
+	      continue ; 
+	    }
+	    data = combined_data ; 
+	  } else { 
+	    if ( exit_on_error ) exit( 0 ) ;
+	    errors++ ;
+	  }
+	} else if ( 0 != analyzeEventData( data , i , esize , exprun , runnumber , evtnum , valid_links ) ) {
 	  if ( exit_on_error ) exit( 0 ) ;
 	  errors++ ;
 	}
       }
-
+      previous_index = 0 ; 
       delete data ;
       // if ( i != getEventNumber( data ) ) printf( "Mismatch event number %d %d\n" , i , getEventNumber( data ) ) ;
       ++i ;
-      if ( ( i % 1000 ) == 0 ) printf( "Event number %d\n" , i ) ;
+      ++k ;
+      if ( ( k % 1000 ) == 0 ) printf( "Event number %d\n" , k ) ;
       if ( ( i > 0 ) && ( ( i % S_PAGE_SLOT_NMB ) == 0 ) ) pcie40_freeSuperPage( 0 , 1 ) ;
     }
   }
-- 
GitLab