From b932391ff734c51022dcf135f4795112840b1163 Mon Sep 17 00:00:00 2001 From: Jonathan Hanks <jonathan.hanks@ligo.org> Date: Thu, 26 Sep 2019 17:12:28 -0700 Subject: [PATCH] Adding a test pcaspy ioc for the standalone_edcu and reformatting the edcu. --- src/epics/seq/standalone_edcu.cc | 207 +++++++++++++++++-------------- src/epics/seq/test/epics_test.py | 94 ++++++++++++++ 2 files changed, 208 insertions(+), 93 deletions(-) create mode 100755 src/epics/seq/test/epics_test.py diff --git a/src/epics/seq/standalone_edcu.cc b/src/epics/seq/standalone_edcu.cc index 22ab8cf13..fcd4394a2 100644 --- a/src/epics/seq/standalone_edcu.cc +++ b/src/epics/seq/standalone_edcu.cc @@ -1,8 +1,8 @@ /// @file /src/epics/seq/edcu.c /// @brief Contains required 'main' function to startup EPICS sequencers, -///along with supporting routines. +/// along with supporting routines. ///< This code is taken from EPICS example included in the EPICS -///<distribution and modified for LIGO use. +///< distribution and modified for LIGO use. /********************COPYRIGHT NOTIFICATION********************************** This software was developed under a United States Government license @@ -44,8 +44,7 @@ char naughtyList[ EDCU_MAX_CHANS ][ 64 ]; // Function prototypes // **************************************************************************************** -int checkFileCrc( const char* ); - +int checkFileCrc( const char* ); unsigned long daqFileCrc; typedef struct daqd_c @@ -79,9 +78,12 @@ static float dataBuffer[ 2 ][ EDCU_MAX_CHANS ]; static int timeIndex; static int cycleIndex; static int symmetricom_fd = -1; -int timemarks[ 16 ] = { 1000*1000, 63500*1000, 126000*1000, 188500*1000, 251000*1000, 313500*1000, - 376000*1000, 438500*1000, 501000*1000, 563500*1000, 626000*1000, 688500*1000, - 751000*1000, 813500*1000, 876000*1000, 938500*1000 }; +int timemarks[ 16 ] = { 1000 * 1000, 63500 * 1000, 126000 * 1000, + 188500 * 1000, 251000 * 1000, 313500 * 1000, + 376000 * 1000, 438500 * 1000, 501000 * 1000, + 563500 * 1000, 626000 * 1000, 688500 * 1000, + 751000 * 1000, 813500 * 1000, 876000 * 1000, + 938500 * 1000 }; int nextTrig = 0; // End Header ************************************************************ @@ -123,7 +125,7 @@ waitGpsTrigger( unsigned long gpssec, int cycle ) long waitNewCycleGps( long* gps_sec ) { - long last_cycle = 0; + long last_cycle = 0; static long cycle = 0; static int sync21pps = 1; unsigned long lastSec; @@ -134,10 +136,16 @@ waitNewCycleGps( long* gps_sec ) if ( sync21pps ) { startTime = gpsSec = symm_gps_time( &gpsNano, 0 ); - printf("\n%ld:%ld (%d)\n", (long int)gpsSec, (long int)gpsNano, (long int)timemarks[0]); - for ( ;startTime == gpsSec || gpsNano < timemarks[0]; ) + printf( "\n%ld:%ld (%d)\n", + (long int)gpsSec, + (long int)gpsNano, + (long int)timemarks[ 0 ] ); + for ( ; startTime == gpsSec || gpsNano < timemarks[ 0 ]; ) { - printf("%ld:%ld (%d)\n", (long int)gpsSec, (long int)gpsNano, (long int)timemarks[0]); + printf( "%ld:%ld (%d)\n", + (long int)gpsSec, + (long int)gpsNano, + (long int)timemarks[ 0 ] ); usleep( 1000 ); gpsSec = symm_gps_time( &gpsNano, 0 ); @@ -145,11 +153,11 @@ waitNewCycleGps( long* gps_sec ) printf( "Found Sync at %ld %ld\nFrom start time of %ld\n", gpsSec, gpsNano, - startTime); + startTime ); sync21pps = 0; } gpsSec = symm_gps_time( &gpsNano, 0 ); - while (gpsNano < timemarks[cycle]) + while ( gpsNano < timemarks[ cycle ] ) { usleep( 500 ); gpsSec = symm_gps_time( &gpsNano, 0 ); @@ -162,7 +170,6 @@ waitNewCycleGps( long* gps_sec ) return last_cycle; } - // ************************************************************************** long waitNewCycle( long* gps_sec ) @@ -173,7 +180,7 @@ waitNewCycle( long* gps_sec ) static int sync21pps = 1; unsigned long lastSec; - if (!sipc) + if ( !sipc ) { return waitNewCycleGps( gps_sec ); } @@ -260,7 +267,7 @@ subscriptionHandler( struct event_handler_args args ) if ( args.type == DBR_FLOAT ) { float val = *( (float*)args.dbr ); - * ((float*)(args.usr)) = val; + *( (float*)( args.usr ) ) = val; } else { @@ -409,8 +416,8 @@ edcuCreateChanFile( char* fdir, char* edcuinifilename, char* fecid ) { sprintf( errMsg, "DAQ FILE ERROR: FILE %s DOES NOT EXIST\n", masterfile ); - fprintf(stderr, "%s", errMsg); - //logFileEntry( errMsg ); + fprintf( stderr, "%s", errMsg ); + // logFileEntry( errMsg ); goto done; } // Open the file to write the composite channel list. @@ -420,8 +427,8 @@ edcuCreateChanFile( char* fdir, char* edcuinifilename, char* fecid ) sprintf( errMsg, "DAQ FILE ERROR: FILE %s DOES NOT EXIST\n", edcuinifilename ); - fprintf(stderr, "%s", errMsg); - //logFileEntry( errMsg ); + fprintf( stderr, "%s", errMsg ); + // logFileEntry( errMsg ); goto done; } @@ -487,21 +494,21 @@ done: } int -veto_line_due_to_datarate(const char* line) +veto_line_due_to_datarate( const char* line ) { const int datarate_eq_len = 9; - if (!line) + if ( !line ) { return 0; } - if (strncmp("datarate=", line, datarate_eq_len) != 0) + if ( strncmp( "datarate=", line, datarate_eq_len ) != 0 ) { return 0; } - if (strcmp("16\n", line + datarate_eq_len) == 0 || - strcmp("16", line + datarate_eq_len) == 0) + if ( strcmp( "16\n", line + datarate_eq_len ) == 0 || + strcmp( "16", line + datarate_eq_len ) == 0 ) { return 0; } @@ -509,21 +516,21 @@ veto_line_due_to_datarate(const char* line) } int -veto_line_due_to_datatype(const char* line) +veto_line_due_to_datatype( const char* line ) { const int datatype_eq_len = 9; - if (!line) + if ( !line ) { return 0; } - if (strncmp("datatype=", line, datatype_eq_len) != 0) + if ( strncmp( "datatype=", line, datatype_eq_len ) != 0 ) { return 0; } - if (strcmp("4\n", line + datatype_eq_len) == 0 || - strcmp("4", line + datatype_eq_len) == 0) + if ( strcmp( "4\n", line + datatype_eq_len ) == 0 || + strcmp( "4", line + datatype_eq_len ) == 0 ) { return 0; } @@ -532,7 +539,9 @@ veto_line_due_to_datatype(const char* line) // ************************************************************************** void -edcuCreateChanList( const char* pref, const char* daqfilename, const char* edculogfilename ) +edcuCreateChanList( const char* pref, + const char* daqfilename, + const char* edculogfilename ) { // ************************************************************************** int i; @@ -544,7 +553,7 @@ edcuCreateChanList( const char* pref, const char* daqfilename, const char* edcul char line[ 128 ]; char* newname; - char eccname[ 256 ]; + char eccname[ 256 ]; sprintf( eccname, "%s%s", pref, "EDCU_CHAN_CONN" ); char chcntname[ 256 ]; sprintf( chcntname, "%s%s", pref, "EDCU_CHAN_CNT" ); @@ -556,8 +565,8 @@ edcuCreateChanList( const char* pref, const char* daqfilename, const char* edcul daqfileptr = fopen( daqfilename, "r" ); if ( daqfileptr == NULL ) { - fprintf(stderr, - "DAQ FILE ERROR: FILE %s DOES NOT EXIST\n", daqfilename ); + fprintf( + stderr, "DAQ FILE ERROR: FILE %s DOES NOT EXIST\n", daqfilename ); } edculog = fopen( edculogfilename, "w" ); if ( daqfileptr == NULL ) @@ -591,15 +600,19 @@ edcuCreateChanList( const char* pref, const char* daqfilename, const char* edcul } else { - if (veto_line_due_to_datarate(line)) + if ( veto_line_due_to_datarate( line ) ) { - fprintf(stderr, "Invalid data rate found, all entries must be 16Hz\n"); - exit(1); + fprintf( + stderr, + "Invalid data rate found, all entries must be 16Hz\n" ); + exit( 1 ); } - if (veto_line_due_to_datatype(line)) + if ( veto_line_due_to_datatype( line ) ) { - fprintf(stderr, "Invalid data type found, all entries must be 4 (float)\n"); - exit(1); + fprintf( stderr, + "Invalid data type found, all entries must be 4 " + "(float)\n" ); + exit( 1 ); } } } @@ -610,10 +623,10 @@ edcuCreateChanList( const char* pref, const char* daqfilename, const char* edcul printf( "CRC data length = %d\n", xferInfo.crcLength ); chid chid1; - if (ca_context_create( ca_enable_preemptive_callback ) != ECA_NORMAL) + if ( ca_context_create( ca_enable_preemptive_callback ) != ECA_NORMAL ) { - fprintf(stderr, "Error creating the EPCIS CA context\n"); - exit(1); + fprintf( stderr, "Error creating the EPCIS CA context\n" ); + exit( 1 ); } for ( i = 0; i < daqd_edcu1.num_chans; i++ ) @@ -638,27 +651,31 @@ edcuCreateChanList( const char* pref, const char* daqfilename, const char* edcul } else { - status = ca_create_channel( daqd_edcu1.channel_name[ i ], - connectCallback, - (void*)&(daqd_edcu1.channel_status[i]), - 0, - &chid1 ); - if (status != ECA_NORMAL) + status = + ca_create_channel( daqd_edcu1.channel_name[ i ], + connectCallback, + (void*)&( daqd_edcu1.channel_status[ i ] ), + 0, + &chid1 ); + if ( status != ECA_NORMAL ) { - fprintf(stderr, "Error creating connection to %s\n", - daqd_edcu1.channel_name[ i ]); + fprintf( stderr, + "Error creating connection to %s\n", + daqd_edcu1.channel_name[ i ] ); } - status = ca_create_subscription( DBR_FLOAT, - 0, - chid1, - DBE_VALUE, - subscriptionHandler, - (void*)&(daqd_edcu1.channel_value[i]), - 0 ); - if (status != ECA_NORMAL) + status = ca_create_subscription( + DBR_FLOAT, + 0, + chid1, + DBE_VALUE, + subscriptionHandler, + (void*)&( daqd_edcu1.channel_value[ i ] ), + 0 ); + if ( status != ECA_NORMAL ) { - fprintf(stderr, "Error creating subscription for %s\n", - daqd_edcu1.channel_name[ i ]); + fprintf( stderr, + "Error creating subscription for %s\n", + daqd_edcu1.channel_name[ i ] ); } } } @@ -738,7 +755,7 @@ edcuInitialize( const char* shmem_fname, const char* sync_source ) shmTpTable = (struct cdsDaqNetGdsTpNum*)( (char*)dcu_addr + CDS_DAQ_NET_GDS_TP_TABLE_OFFSET ); - if (sync_source && strcmp(sync_source, "-") != 0) + if ( sync_source && strcmp( sync_source, "-" ) != 0 ) { // Find Sync source sync_addr = (void*)findSharedMemory( (char*)sync_source ); @@ -773,8 +790,8 @@ checkFileCrc( const char* fName ) /// Routine for logging messages to ioc.log file. /// @param[in] message Ptr to string containing message to be logged. -//void -//logFileEntry( char* message ) +// void +// logFileEntry( char* message ) //{ // FILE* log; // char timestring[ 256 ]; @@ -786,13 +803,14 @@ checkFileCrc( const char* fName ) // if ( log == NULL ) // { // status = dbNameToAddr( reloadtimechannel, &paddr ); -// status = dbPutField( &paddr, DBR_STRING, "ERR - NO LOG FILE FOUND", 1 ); +// status = dbPutField( &paddr, DBR_STRING, "ERR - NO LOG FILE FOUND", 1 +// ); // } // else // { // fprintf( log, "%s\n%s\n", timestring, message ); -// fprintf( log, "***************************************************\n" ); -// fclose( log ); +// fprintf( log, "***************************************************\n" +// ); fclose( log ); // } //} @@ -824,7 +842,7 @@ main( int argc, char* argv[] ) int send_daq_reset = 0; const char* daqsharedmemname = "edc_daq"; - //const char* syncsharedmemname = "-"; + // const char* syncsharedmemname = "-"; const char* logdir = "logs"; const char* daqFile = "edc.ini"; const char* prefix = ""; @@ -832,7 +850,7 @@ main( int argc, char* argv[] ) char logfilename[ 256 ] = ""; char edculogfilename[ 256 ] = ""; - int delay_multiplier = 0; + int delay_multiplier = 0; int cur_arg = 0; while ( ( cur_arg = getopt( argc, argv, "b:l:d:i:w:p:" ) ) != EOF ) @@ -842,7 +860,7 @@ main( int argc, char* argv[] ) case 'b': daqsharedmemname = optarg; break; - //case 't': + // case 't': // syncsharedmemname = optarg; // break; case 'l': @@ -879,7 +897,7 @@ main( int argc, char* argv[] ) sprintf( edculogfilename, "%s%s", logdir, "/edcu.log" ); for ( ii = 0; ii < EDCU_MAX_CHANS; ii++ ) daqd_edcu1.channel_status[ ii ] = 0xbad; - edcuInitialize( daqsharedmemname, "-"); + edcuInitialize( daqsharedmemname, "-" ); // edcuCreateChanFile(daqDir,daqFile,pref); edcuCreateChanList( prefix, daqFile, edculogfilename ); int datarate = daqd_edcu1.num_chans * 64 / 1000; @@ -906,9 +924,9 @@ main( int argc, char* argv[] ) "Chan Cnt", daqd_edcu1.num_chans ); - GPS::gps_clock clock(0); - GPS::gps_time time_step = GPS::gps_time(0, 1000000000 / 16 ); - GPS::gps_time transmit_time = clock.now( ); + GPS::gps_clock clock( 0 ); + GPS::gps_time time_step = GPS::gps_time( 0, 1000000000 / 16 ); + GPS::gps_time transmit_time = clock.now( ); ++transmit_time.sec; transmit_time.nanosec = 0; @@ -919,9 +937,9 @@ main( int argc, char* argv[] ) for ( ;; ) { dropout = 0; - //daqd_edcu1.epicsSync = waitNewCycle( &daqd_edcu1.gpsTime ); + // daqd_edcu1.epicsSync = waitNewCycle( &daqd_edcu1.gpsTime ); GPS::gps_time now = clock.now( ); - while (now < transmit_time ) + while ( now < transmit_time ) { usleep( 1 ); now = clock.now( ); @@ -934,30 +952,33 @@ main( int argc, char* argv[] ) edcuWriteData( daqd_edcu1.epicsSync, daqd_edcu1.gpsTime, mydcuid, send_daq_reset ); send_daq_reset = 0; -// status = dbPutField( &gpstimedisplayaddr, -// DBR_LONG, -// &daqd_edcu1.gpsTime, -// 1 ); // Init to zero. -// status = dbPutField( &daqbyteaddr, DBR_LONG, &datarate, 1 ); + // status = dbPutField( &gpstimedisplayaddr, + // DBR_LONG, + // &daqd_edcu1.gpsTime, + // 1 ); // Init to zero. + // status = dbPutField( &daqbyteaddr, DBR_LONG, &datarate, 1 ); int conChans = daqd_edcu1.con_chans; -// status = dbPutField( &eccaddr, DBR_LONG, &conChans, 1 ); + // status = dbPutField( &eccaddr, DBR_LONG, &conChans, 1 ); // Check unconnected channels once per second if ( daqd_edcu1.epicsSync == 0 ) { -// status = dbGetField( -// &daqresetaddr, DBR_LONG, &daqreset, &ropts, &nvals, NULL ); -// if ( daqreset ) -// { -// status = dbPutField( -// &daqresetaddr, DBR_LONG, &ropts, 1 ); // Init to zero. -// send_daq_reset = 1; -// } + // status = dbGetField( + // &daqresetaddr, DBR_LONG, &daqreset, &ropts, + // &nvals, NULL ); + // if ( daqreset ) + // { + // status = dbPutField( + // &daqresetaddr, DBR_LONG, &ropts, 1 ); // Init + // to zero. + // send_daq_reset = 1; + // } numDC = edcuFindUnconnChannels( ); if ( numDC < ( pageNumDisp * 40 ) ) pageNumDisp--; -// numReport = edcuReportUnconnChannels( pref, numDC, pageNumDisp ); + // numReport = edcuReportUnconnChannels( pref, numDC, + // pageNumDisp ); } -// status = dbPutField( &chnotfoundaddr, DBR_LONG, &numDC, 1 ); + // status = dbPutField( &chnotfoundaddr, DBR_LONG, &numDC, 1 ); fivesectimer = ( fivesectimer + 1 ) % 50; // Increment 5 second timer for triggering CRC checks. @@ -974,7 +995,7 @@ main( int argc, char* argv[] ) } }*/ - cycle = (cycle + 1) % 16; + cycle = ( cycle + 1 ) % 16; transmit_time = transmit_time + time_step; } diff --git a/src/epics/seq/test/epics_test.py b/src/epics/seq/test/epics_test.py new file mode 100755 index 000000000..fec3fab38 --- /dev/null +++ b/src/epics/seq/test/epics_test.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +import threading + +import pcaspy + +def write_ini_file(prefix, db, fname): + print("Writing ini file '{0}'".format(fname)) + with open(fname, 'wt') as f: + f.write("""[default] +gain=1.0 +acquire=3 +dcuid=12 +ifoid=0 +datatype=4 +datarate=16 +offset=0 +slope=1.0 +units=undef +""") + keys = list(db.keys()) + keys.sort() + i = 0 + for entry in keys: + f.write("""[{0}{1}] +datarate=16 +datatype=4 +chnnum={2} +""".format(prefix, entry, 40000 + i)) + i += 1 + for entry in ['EDCU_CHAN_CONN', 'EDCU_CHAN_CNT', 'EDCU_CHAN_NOCON']: + f.write("""[{0}{1}] +datarate=16 +datatype=4 +chnnum={2} +""".format(prefix, entry, 40000 + i)) + + +def read_time(): + with open("/proc/gps", "rt") as f: + data = f.read() + dot = data.find('.') + return int(data[0:dot]) + +class myDriver(pcaspy.Driver): + def __init__(self, offsets): + super(myDriver, self).__init__() + self.__offsets = offsets + self.__lock = threading.Lock() + + def read(self, reason): + with self.__lock: + return self.getParam(reason) + + def write(self, reason, val): + return False + + def update_vals(self, ref_time): + with self.__lock: + for entry in self.__offsets: + val = (ref_time % 100000) + self.__offsets[entry] + #if entry == "EDC-189--gpssmd100koff1p--24--2--16": + # print("X6:EDC-189--gpssmd100koff1p--24--2--16 == {0} offset of {1}".format(val, self.__offsets[entry])) + self.setParam(entry, val) + self.updatePVs() + +prefix="X6:" +db = {} +offsets = {} + +def add_entry(db, i, offset): + global offsets + name="EDC-{0}--gpssmd100koff1p--{1}--4--16".format(i, offset) + db[name] = {'type': 'int' } + offsets[name] = offset + return db + +for i in range(2000): + db = add_entry(db, i, i%33) + +write_ini_file(prefix, db, 'edcu.ini') + +server = pcaspy.SimpleServer() +server.createPV(prefix, db) +driver = myDriver(offsets) +driver.update_vals(read_time()) + +last_sec = read_time() +while True: + server.process(0.2) + cur_sec = read_time() + if cur_sec != last_sec: + driver.update_vals(cur_sec) + last_sec = cur_sec -- GitLab