diff --git a/Pcie40Applications/pcie40_ul_lib.cpp b/Pcie40Applications/pcie40_ul_lib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..289d2f7bedf2c336f6be79d2e64c4e52b531147a --- /dev/null +++ b/Pcie40Applications/pcie40_ul_lib.cpp @@ -0,0 +1,380 @@ +#include "pcie40_ul_lib.h" + +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 crc_calc_event( unsigned int* data, int start_pos ){ + int i = 0; + int cur_pos = start_pos; + int first_crc ; + int crc = 0xffff ; + int size = data[ cur_pos % DMASIZE ]; + + int good_flag = 0; + + if( size > 0xffff || size <= 0 ){ + printf("Invalid total event size %.8x\n", size); + return -1; + } + + /* printf( "TRL %.8x %.8x %.8x\n", */ + /* data[ ( cur_pos + size - 1 + DMASIZE ) % DMASIZE ], */ + /* data[ ( cur_pos + 1 + size ) % DMASIZE ], */ + /* data[ ( cur_pos + 2 + size ) % DMASIZE ] ); */ + + cur_pos = start_pos + 4; + unsigned int ctime = data[ cur_pos % DMASIZE ]; + + cur_pos = start_pos + 3; + unsigned int evenum = data[ cur_pos % DMASIZE ]; + cur_pos = start_pos + 5; + unsigned int utime = data[ cur_pos % DMASIZE ]; + cur_pos = start_pos + 2; + unsigned int exp_run = data[ cur_pos % DMASIZE ] ; + + int offset = 8; // size of ROB header [words] + + int link_num = 0; + + + crc_calc( &crc, &ctime ); + crc_calc( &crc, &evenum ); + crc_calc( &crc, &utime ); + crc_calc( &crc, &exp_run ); + first_crc = crc ; + + +#ifdef DEBUG + printf("Start\n"); + for( i = start_pos ; i < start_pos + size ; i++){ + printf("%.8x\n", data[ i % DMASIZE ] ); + } + printf("End\n"); +#endif + int bad = 0; + + while( offset + 4 < size ){ // 4 = ROB trailer size + cur_pos = start_pos + offset; + int size_link = data[ cur_pos % DMASIZE ] & 0x000ffff ; + if ( 0 >= size_link || size_link > 10000000 ){ + printf("[ERROR] Invalid size per link (%.8x words): link num %d\n", size_link, link_num); + return -1 ; // it could be that the memory was read + } + + // + // Calculation of CRC + // + crc = first_crc ; +#ifdef DEBUG + printf("%.8x %.8x crc %.8x\n", data[ ( start_pos + offset ) % DMASIZE ], data[ ( start_pos + offset + 1 ) % DMASIZE ], crc ); +#endif + for ( cur_pos = start_pos + offset + 2 ; cur_pos < start_pos + offset + size_link -2; ++cur_pos ) { + crc_calc( &crc, &data[ cur_pos % DMASIZE ] ); +#ifdef DEBUG + printf("crc %.8x data %.8x\n", crc, data[ cur_pos % DMASIZE ] ); +#endif + } +#ifdef DEBUG + printf("%.8x %.8x\n", data[ ( cur_pos ) % DMASIZE ], data[ ( cur_pos + 1 ) % DMASIZE ]); +#endif + // cur_pos = start_pos + 8 + size_link -2; + cur_pos = start_pos + offset + size_link -2; +#ifdef DEBUG + printf("calcd %.4x data %.4x\n", crc, data[ cur_pos % DMASIZE ] & 0xffff ); +#endif + + // + // Check of CRC + // + if( ( crc & 0xffff ) != ( data[ cur_pos % DMASIZE ] & 0xffff ) ){ + printf("%.2d Bad ! calcd %.4x data %.4x offset %.4x size %.4x szlnk %.4x trl %.8x\n", + link_num, crc, data[ cur_pos % DMASIZE ] & 0xffff, offset, size, size_link, data[ (cur_pos+1) % DMASIZE ] ); + bad = 1; + + }else{ + good_flag = 1; + // printf("%.2d Good ! calcd %.4x data %.4x offset %.4x size %.4x szlnk %.4x trl %.8x\n", + // link_num, crc, data[ cur_pos % DMASIZE ] & 0xffff, offset, size, size_link, data[ (cur_pos+1) % DMASIZE ] ); + + } + link_num++; + offset += size_link; + } + + if( bad ){ + // if( evenum > 50000 ){ + // if( 1 ){ + for( i = 0 ; i < size ; i++){ + printf("%.8x ", data[ ( start_pos + i ) % DMASIZE ] ); + if( i % 8 == 7 ) printf("\n"); + } + printf("\n"); + good_flag = -2; + } + return good_flag; + +} + + 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 * nmissed ) { + + int magic; + int size, size_link; + int ix ; + + int offset; + unsigned int exp_run, evenum, ctime, utime; + int start_pos = *ce; + int cnt = 0; + int cur_pos = *ce + 1; + int ret = 0; + + while( !( ( ( magic = data[ cur_pos % DMASIZE ] ) & 0xffff0000 ) != 0x7f7f0000 ) ){ + usleep(1000); + cnt++; + // + // Scan to find x"7f7f...." + // + if( cnt > 10 ){ + cnt = 0; + int j = 0 ; + for ( j = 0 ; j < DMASIZE ; ++j ) { + if ( ( ( data[ ( cur_pos + j ) % DMASIZE ] & 0xffff0000 ) == 0x7f7f0000 ) ){ + evenum = data[ ( cur_pos + j + 2 ) % DMASIZE ]; + if( evenum > *evn ){ + *evn = evenum; + cur_pos = ( cur_pos + j - 1 + DMASIZE ) % DMASIZE; + size = data[ cur_pos ] ; + *ce = ( cur_pos + size ) % DMASIZE; + printf( "New Event number prev %d new %d pos %d size %d\n" , *evn , evenum, cur_pos, size ); + crc_calc_event( data, cur_pos ); + + }else{ + printf( "Old Event number prev %d new %d pos %d\n" , *evn , evenum, ( cur_pos + j - 1 + DMASIZE ) % DMASIZE ); + break; + } + }else{ + continue; + } + } + } + } + + return size ; + } + +int readout(){ +// int main (int argc ,char** argv) { + // Stop trigger + /* 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 + // fp = popen( "ssh robbep@vme \"trigft -53 pulse 1000 -1\"" , "r" ) ; + // sleep( 2 ) ; + /* while( fgets( buf , sizeof(buf) , fp ) != NULL ) { */ + /* // printf( "A= %d\n" , strncmp( exp , buf , 3 ) ) ; */ + /* // printf( strncmp( &buf[0] , 'exp' , 1 ) ) ; */ + /* tmp = strdup( buf ) ; */ + /* if ( strncmp( exp , buf , 3 ) == 0 ) { */ + /* //printf( '%s\n' , buf ) ; */ + /* // printf( "ICI\n" ) ; */ + /* ptr = strtok( tmp , " " ) ; */ + /* ptr = strtok( NULL , " " ) ; */ + /* ptr = strtok( NULL , " " ) ; */ + /* ptr = strtok( NULL , " " ) ; */ + /* // while ( ptr != NULL ) { */ + /* run = atoi( ptr ) ; */ + /* // ptr = strtok( NULL , " " ) ; */ + /* } */ + /* //} */ + /* } */ + /* pclose( fp ) ; */ + //sleep( 2 ) ; + + int run = 0 ; + FILE* fp; + char * ptr ; + char * tmp ; + char buf[1000] ; + char exp[] = "exp" ; + + unsigned int * data ; + double time_spent ; + int retry ; + int bad ; + int evn ; + evn = 0 ; + bad = 0 ; + retry = 0 ; + int pctime, putime ; + pctime = 0 ; + putime = 0 ; + + int i ; + int size, size_256, currentEventIndex, crc, nErr, nEvt, nRetry, nMissed ; + currentEventIndex = 0 ; + nErr = 0 ; + nEvt = 0 ; + nRetry = 0 ; + nMissed = 0 ; + int read_dma = 1 ; + clock_t begin = clock() ; + int size_zero_cnt = 0; + + int start_flag = 1; + + int magic; + int size_link; + + int offset; + unsigned int next_exp_run, cur_exp_run = 0, evenum, ctime, utime, first_eve = 0; + int start_pos = 0; + int cnt = 0; + int eve_cnt = 0, first_event_flag = 0, crc_err_eve_cnt = 0; + + + int cur_pos = 0; + int ret = 0; + unsigned int cur_eve = 0, next_eve = 0; + int mod_pos = 0; + + // if ( ( nEvt % 1000 == 1 ) && ( size != 0 ) ) printf( "Event number %d\n", nEvt ) ; + + // + // Read the 1st data + // + if ( read_dma == 1 ) { + // set busy + //res = ecs_write( 0 , 2 , 0x000501A0 , 0x1 ) ; + //sleep(5); + res = pcie40_b2dmapointerread( 0 , &data ) ; + if ( start_flag == 1 ){ + ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; + start_flag = 0; + } + //usleep( 5 ) ; + // release busy + //res = ecs_write( 0 , 2 , 0x000501A0 , 0x0 ) ; + read_dma = 1 ; + } + + // + // Main loop + // + while( 1 ){ + while( 1 ){ + if( !( ( ( ( magic = data[ ( cur_pos + 1 ) % DMASIZE ] ) & 0xffff0000 ) != 0x7f7f0000 ) + || data[ ( cur_pos + data[ cur_pos % DMASIZE ] - 1 + DMASIZE ) % DMASIZE ] != 0x7fff0006 ) ){ + break; + } + // printf("MAGIC %.8x\n", magic); + + // usleep(1000); // to avoid BUSY loop + + // + // Refresh DMA memory + // + res = pcie40_b2dmapointerread( 0 , &data ) ; + int wait_flag = 0; + // + // Scan to find x"7f7f...." + // + if( cnt > 100 ){ + cnt = 0; + int j = 0 ; + for ( j = 0 ; j < DMASIZE ; ++j ) { +#ifdef DEBUG + printf("%.8x %d\n", data[ ( cur_pos + j + 1 ) % DMASIZE ], cur_pos + j ); +#endif + if ( ( ( data[ ( cur_pos + j + 1 ) % DMASIZE ] & 0xffff0000 ) == 0x7f7f0000 ) ){ + next_eve = data[ ( cur_pos + j + 3 ) % DMASIZE ]; + next_exp_run = data[ ( cur_pos + j + 2 ) % DMASIZE ] ; + + // printf( "TRAILER %.8x %.8x %.8x\n",data[ ( cur_pos + j + data[ ( cur_pos + j + DMASIZE ) % DMASIZE ] - 1 + DMASIZE ) % DMASIZE ] ); + + if( next_eve > cur_eve && next_exp_run >= cur_exp_run ){ + /* if( data[ ( ( data[ ( cur_pos + j + DMASIZE ) % DMASIZE ] ) - 1 + DMASIZE ) % DMASIZE ] != 0x7fff0006 ){ */ + /* usleep(1000); */ + /* break; */ + /* } */ + cur_pos = ( cur_pos + j + DMASIZE ) % DMASIZE; + size = data[ cur_pos ]; + // printf( "Detect new Event number prev %.8x new %.8x pos %.8x size %.8x\n" , cur_eve , next_eve, cur_pos, size ); + break; + }else{ + // printf( "Detect Old Event number prev %.8x new %.8x pos %d\n" , cur_eve , next_eve, ( cur_pos + j + DMASIZE ) % DMASIZE ); + break; + } + }else{ + continue; + } + } + } + cnt++; + } + size = data[ cur_pos ] ; + + next_eve = data[ ( cur_pos + 3 ) % DMASIZE ]; + next_exp_run = data[ ( cur_pos + 2 ) % DMASIZE ]; + + if( first_event_flag == 0 || cur_exp_run != next_exp_run ){ + first_event_flag = 1; + first_eve = next_eve; + crc_err_eve_cnt = 0; + eve_cnt = 0; + } + eve_cnt++; + ret = crc_calc_event( data, cur_pos ); + if( ret != 1 ){ + crc_err_eve_cnt++; + } + + if(ret != 1 || eve_cnt % 100 == 0 ){ + printf( "Event number prev %.8x new %.8x pos %.8x size %.8x\n" , cur_eve , next_eve, cur_pos, size ); + } + cur_eve = next_eve; + cur_exp_run = next_exp_run; + if(ret != 1 || eve_cnt % 10000 == 0 ){ + printf("STATUS : tot eve %d read eve %d err_eve %d run %d\n", next_eve - first_eve, eve_cnt, crc_err_eve_cnt, cur_exp_run ); + } + mod_pos = ( cur_pos + size ) % 8; + if( mod_pos != 0 ){ + cur_pos = ( cur_pos + size + DMASIZE + ( 8 - mod_pos) ) % DMASIZE ; + }else{ + cur_pos = ( cur_pos + size + DMASIZE ) % DMASIZE ; + } + + } + + + clock_t end = clock(); + time_spent += (double)(end - begin) / CLOCKS_PER_SEC; + + ecs_close( 0 , 0 ) ; + + printf( "Timing = %f s\n" , time_spent ) ; + 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 ; + } diff --git a/Pcie40Applications/pcie40_ul_lib.h b/Pcie40Applications/pcie40_ul_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..6f580bf8171d5bd42ddad2c7f00657df1860395b --- /dev/null +++ b/Pcie40Applications/pcie40_ul_lib.h @@ -0,0 +1,59 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <time.h> +#include "altera_dma_regs.h" + +extern "C" int ecs_open(int dev, int bar); +extern "C" void ecs_close(int dev, int bar); +extern "C" int pcie40_b2dmabufferreset(int fd); +extern "C" int pcie40_b2dmapointerread(int fd , unsigned int ** pData ); +extern "C" int ecs_write(int dev, int bar, unsigned add, int val); + +//#define DEBUG + +const int CRC16_XMODEM_TABLE[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +} ; + + + +int crc_calc( int * crc, unsigned int * data ); + +int crc_calc_event( unsigned int* data, int start_pos ); + +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 * nmissed ); +int readout();