diff --git a/Pcie40Applications/main_pcie40_ul.c b/Pcie40Applications/main_pcie40_ul.c index 35988a3ee7dd03085c280852965c021657ba168d..d74c246dffd15dc41e025fbdc314a9965994cd1e 100644 --- a/Pcie40Applications/main_pcie40_ul.c +++ b/Pcie40Applications/main_pcie40_ul.c @@ -41,21 +41,21 @@ const int CRC16_XMODEM_TABLE[] = { -int crc_calc( int crc, unsigned int data ){ - int byte1, byte2, byte3, byte4, crc_temp ; - byte1 = data & 0xFF; - byte2 = ( data & 0xFF00 ) >> 8; - byte3 = ( data & 0xFF0000 ) >> 16; - byte4 = ( data & 0xFF000000 ) >> 24; - crc_temp = (((crc)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc)>>8)&0xff)^byte4] ; - crc_temp = (((crc_temp)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc_temp)>>8)&0xff)^byte3] ; - crc_temp = (((crc_temp)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc_temp)>>8)&0xff)^byte2] ; - crc_temp = (((crc_temp)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc_temp)>>8)&0xff)^byte1] ; - return crc_temp; +int crc_calc( int * crc, unsigned int * data ){ + int byte1, byte2, byte3, byte4 ; + byte1 = (*data) & 0xFF; + byte2 = ( (*data) & 0xFF00 ) >> 8; + byte3 = ( (*data) & 0xFF0000 ) >> 16; + byte4 = ( (*data) & 0xFF000000 ) >> 24; + *crc = ((((*crc))<<8)&0xff00) ^ CRC16_XMODEM_TABLE[((((*crc))>>8)&0xff)^byte4] ; + *crc = ((((*crc))<<8)&0xff00) ^ CRC16_XMODEM_TABLE[((((*crc))>>8)&0xff)^byte3] ; + *crc = ((((*crc))<<8)&0xff00) ^ CRC16_XMODEM_TABLE[((((*crc))>>8)&0xff)^byte2] ; + *crc = ((((*crc))<<8)&0xff00) ^ CRC16_XMODEM_TABLE[((((*crc))>>8)&0xff)^byte1] ; } int decode_data_wUL( unsigned int * data , unsigned int * ce , int * crc , int * run , - int * bad , int *evn , int * retry , int * pctime , int * putime ) { + int * bad , int *evn , int * retry , int * pctime , int * putime , + int * nmissed ) { int magic; int size, size_link; @@ -65,15 +65,42 @@ int decode_data_wUL( unsigned int * data , unsigned int * ce , int * crc , int * unsigned int exp_run, evenum, ctime, utime; *crc = 0 ; - size = data[ ( *ce ) % DMASIZE ] ; + size = data[ ( *ce ) % DMASIZE ] ; magic = data[ ( *ce + 1 ) % DMASIZE ] ; // Check a new event is available in the memory if( ( magic & 0xffff0000 ) != 0x7f7f0000 ){ // printf("Invalid magic number %.8x\n", magic ); - return 0; - } + if ( ( *evn > 1 ) && ( ( ( data[ (*ce - 2 ) % DMASIZE ] & 0xffff0000 ) != 0xbbbc0000 ) && + ( ( data[ (*ce -2) % DMASIZE ] & 0xFFFF0000 ) != 0x7FFF0000 )) ) { + // printf( "Problem %d retry %d\n" , *evn , *retry ) ; + ++(*retry) ; + //ecs_write( 0 , 2 , 0x000501A0 , 0x1 ) ; + + if ( *retry < 3 ) { + return 0 ; + } + *retry = 0 ; + + // search for next good event + int j = 0 ; + for ( j = 0 ; j < DMASIZE ; ++j ) { + if ( ( ( data[ j ] & 0xffff0000 ) == 0x7f7f0000 ) && + ( ( data[ ( j + 2 ) % DMASIZE ] > *evn ) ) ) { + size = data[ ( j - 1 ) % DMASIZE ] ; + *ce = ( ( j - 1 ) % DMASIZE ) ; + //printf( "New event number %d %d\n" , *evn , data[ ( j + 2 ) % DMASIZE ] ) ; + break ; + } + } + } else { + return 0; + } + } + + if ( 0 == size ) return 0 ; + ix = *ce + 4; ctime = data[ ix % DMASIZE ]; ix = *ce + 3; @@ -81,82 +108,119 @@ int decode_data_wUL( unsigned int * data , unsigned int * ce , int * crc , int * ix = *ce + 5; utime = data[ ix % DMASIZE ]; ix = *ce + 2; - exp_run = data[ ix % DMASIZE ] >> 8 ; - - // printf("exprun %.8x eve %d\n", exp_run, evenum ); - - if ( exp_run != *run ) { // it may be that the old data is still in memory - // printf( "RUN = %d\n", *run ) ; + exp_run = data[ ix % DMASIZE ] ; + + // printf("exprun %.8x eve %d ce %d\n", exp_run, evenum , *ce ); + + if ( ( exp_run >> 8 ) != *run ) { // it may be that the old data is still in memory return 0 ; } + if ( evenum < *evn ) return 0 ; + if ( evenum != *evn ) { - printf( "Bad event number %d %d %d %d %d %d\n" , evenum , *evn , ctime , utime , *pctime , *putime ) ; + printf( "Bad event number %d %d %d %d %d %d retry = %d\n" , evenum , *evn , ctime , utime , *pctime , *putime , + *retry ) ; + *nmissed += (- *evn + evenum ) ; + *evn = evenum ; + *bad = 1 ; + //if ( evenum != 0 ) { + // int j = 0 ; + // for ( j = 0 ; j < DMASIZE ; ++j ) { + // printf( "%d %.8x %d\n" , j , data[ j ] , *ce ) ; + // } + // exit( 0 ) ; + //} } + *putime = utime ; *pctime = ctime ; offset = 8; // size of ROB header [words] + int first_crc ; + *crc = 0xffff ; + crc_calc( crc, &ctime ); + crc_calc( crc, &evenum ); + crc_calc( crc, &utime ); + crc_calc( crc, &exp_run ); + first_crc = *crc ; while( offset + 4 != size ){ // 4 = ROB trailer size - *crc = 0xffff ; - ix = *ce + offset; size_link = data[ ix % DMASIZE ] & 0x00ffffff ; - if ( 0 == size_link ) return 0 ; // it could be that the memory was read // while being filled // Calculation of CRC - *crc = crc_calc( *crc, ctime ); - *crc = crc_calc( *crc, evenum ); - *crc = crc_calc( *crc, utime ); - *crc = crc_calc( *crc, ( exp_run << 8 ) ); + *crc = first_crc ; for ( ix = *ce + offset + 2 ; ix < *ce + offset + size_link -2; ++ix ) { - *crc = crc_calc( *crc, data[ ix % DMASIZE ] ); + crc_calc( crc, &data[ ix % DMASIZE ] ); } ix = *ce + 8 + size_link -2; if( ( *crc & 0xffff ) != ( data[ ix % DMASIZE ] & 0xffff ) ){ // retry, could be that the event is not fully in memory + //ecs_write( 0 , 2 , 0x000501A0 , 0x1 ) ; ++(*retry) ; - if ( *retry < 3 ) return 0 ; + if ( *retry < 10 ) { + return 0 ; + } *bad = 1 ; - printf( "Error in CRC comparison calc %.8x : data %.8x\n" , *crc , data[ ix % DMASIZE ] ); + printf( "Error in CRC comparison calc %.8x : data %.8x, offset = %d, retry = %d\n" , *crc , data[ ix % DMASIZE ] , + offset, *retry ); + + // if ( evenum != 0 ) { + // int j = 0 ; + // for ( j = 0 ; j < DMASIZE ; ++j ) { + // printf( "%d %.8x %d\n" , j , data[ j ] , *ce ) ; + // } + // exit( 0 ) ; + //} + + *retry = 0 ; } + // ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; offset += size_link; if( offset + 4 > size ){ printf( "Invalid data size sum of link size %d size = %d\n" , offset + 4, size ); + // if ( evenum != 0 ) { + // int j = 0 ; + // for ( j = 0 ; j < DMASIZE ; ++j ) { + // printf( "%d %.8x %d\n" , j , data[ j ] , *ce ) ; + // } + // exit( 0 ) ; + //} return -1 ; } } return size ; } - int main (int argc ,char** argv) { // Stop trigger - system( "ssh vme \"resetft -80\"" ) ; + system( "ssh robbep@vme \"resetft -53\"" ) ; sleep( 2 ) ; int res = ecs_open( 0 , 0 ) ; if ( -1 == res ) printf("ERROR: Could not open device (BAR 0)\n") ; else printf("SUCCESS: Device opened for DMA\n"); res = ecs_open( 0 , 2 ) ; + // ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; + ecs_write( 0 , 2 , 0x000501A0 , 0x1 ) ; pcie40_b2dmabufferreset( 0 ) ; // Start trigger int run = 0 ; FILE* fp; char * ptr ; char * tmp ; - fp = popen( "ssh vme \"trigft -80 pulse 100 -1\"" , "r" ) ; + fp = popen( "ssh robbep@vme \"trigft -53 pulse 1000 -1\"" , "r" ) ; char buf[1000] ; char exp[] = "exp" ; - // sleep( 2 ) ; + // sleep( 2 ) ; while( fgets( buf , sizeof(buf) , fp ) != NULL ) { // printf( "A= %d\n" , strncmp( exp , buf , 3 ) ) ; // printf( strncmp( &buf[0] , 'exp' , 1 ) ) ; @@ -192,24 +256,40 @@ int main (int argc ,char** argv) { putime = 0 ; int i ; - int size, size_256, currentEventIndex, crc, nErr, nEvt, nRetry ; + int size, size_256, currentEventIndex, crc, nErr, nEvt, nRetry, nMissed ; currentEventIndex = 0 ; nErr = 0 ; nEvt = 0 ; nRetry = 0 ; - clock_t begin = clock(); - for ( i = 0 ; i < 1000000 ; ++i ) { - if ( ( nEvt % 10000 == 1 ) && ( size != 0 ) ) printf( "Event number %d\n", nEvt ) ; + nMissed = 0 ; + int read_dma = 1 ; + clock_t begin = clock() ; + + for ( i = 0 ; i < 10000000 ; ++i ) { + if ( ( nEvt % 1000 == 1 ) && ( size != 0 ) ) printf( "Event number %d\n", nEvt ) ; + if ( read_dma == 1 ) { + // set busy + //res = ecs_write( 0 , 2 , 0x000501A0 , 0x1 ) ; + //sleep(5); + res = pcie40_b2dmapointerread( 0 , &data ) ; + if ( 1 == i ) ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; + //usleep( 5 ) ; + // release busy + //res = ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; + read_dma = 1 ; + } - res = pcie40_b2dmapointerread( 0 , &data ) ; bad = 0 ; size = decode_data_wUL( data , ¤tEventIndex , &crc , &run , &bad , &evn , &retry , - &pctime , &putime ) ; - if ( 0 == size ) continue ; + &pctime , &putime , &nMissed ) ; + if ( 0 == size ) { + read_dma = 1 ; + continue ; + } if ( retry != 0 ) nRetry++ ; - retry = 0 ; if ( size == -1 ) { nErr++ ; + read_dma = 1 ; continue ; } if ( bad == 1 ) nErr++ ; @@ -217,12 +297,16 @@ int main (int argc ,char** argv) { if( size % 8 != 0 ){ size_256 = ( size/8 + 1 )*8; + } else { + size_256 = size ; } currentEventIndex = ( currentEventIndex + size_256 ) % DMASIZE ; nEvt++ ; - + read_dma = 1 ; + retry = 0 ; } + clock_t end = clock(); time_spent += (double)(end - begin) / CLOCKS_PER_SEC; @@ -234,5 +318,6 @@ int main (int argc ,char** argv) { printf( "Number of events = %d \n", nEvt ) ; printf( "Number of errors = %d \n", nErr ) ; printf( "Number of retries = %d \n", nRetry ) ; + printf( "Number of missed = %d \n", nMissed ) ; return 0 ; }