Skip to content
Snippets Groups Projects
Commit 599e172a authored by Ezekiel Dohmen's avatar Ezekiel Dohmen
Browse files

Cleaning up PPS checking logic, allowing for longer pulse widths on the PPS to be valid

parent 98f01de5
No related branches found
No related tags found
1 merge request!653Adding sync code, to re-sync ADCs on startup.
......@@ -177,8 +177,8 @@ void fe_start_controller( void )
one_pps_sync_t onePps;
onePps.time = IOP_IO_RATE * 4; /// @param onePpsTime One PPS diagnostic check
one_pps_sync_t onePps = {0,9999};
......@@ -566,8 +566,7 @@ void fe_start_controller( void )
// will have the main loop skip adc read on first cycle
sync21pps = 1;
// Need to set onePps vars for use in 1PPS timing diag later
onePps.signalHi = 1;
onePps.time = cycleNum;
onePps.last_cycle_high = 1;
pLocalEpics->epicsOutput.timeErr = syncSource;
timeSec = current_time_fe( ) - 1;
break;
......@@ -1021,8 +1020,7 @@ void fe_start_controller( void )
{
// Check if front end continues to be in sync with 1pps
// If not, set sync error flag
sync21pps_check( &onePps, padcinfo, hkp_cycle );
if ( onePps.time > 1 ) //If PPS high was detected on a cycle other than the first 2 hkp_cycle
if ( sync21pps_check( &onePps, padcinfo, hkp_cycle ) != 0 )
{
diagWord |= TIME_ERR_1PPS;
feStatus |= FE_ERROR_TIMING;
......
......@@ -100,7 +100,8 @@ sync2pps_signal( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, uint64_t cpuClock[]
total_ns += timer_tock_ns(&start_tsc);
timer_start( &start_tsc );
} while ( status == 0 && p1pps->value < ONE_PPS_THRESH && pps_wait < p1pps->time );
} while ( status == 0 && p1pps->value < ONE_PPS_THRESH &&
pps_wait < MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH );
RTSLOG_INFO("It took an avg %llu ns to read the next ADC value while looking for the PPS,"
" estimated clock rate of %llu Hz. Num samples: %d\n",
......@@ -111,11 +112,12 @@ sync2pps_signal( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, uint64_t cpuClock[]
if (status != 0) return status; //If the ADC read failed, we can't continue
#ifdef TEST_NOSYNC
pps_wait = p1pps->time + 1;
//This will force the PPS to "timeout", so we can check the fallback logic
pps_wait = MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH + 1;
#endif
// If 1PPS signal not found, assume the ADC is being clocked (external/internal) and try
// to sync up with the ADC read period
if ( pps_wait >= p1pps->time )
if ( pps_wait >= MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH )
{
RTSLOG_INFO("Failed to find 1 pps signal on channel %d of card %d\n, defaulting to SYNC_SRC_NONE. \n",
ADC_DUOTONE_CHAN, ADC_ONEPPS_BRD);
......@@ -129,30 +131,70 @@ sync2pps_signal( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, uint64_t cpuClock[]
status = iop_adc_read( padcinfo, cpuClock );
nanotime = current_nanosecond( );
pps_wait++;
} while ( status == 0 && nanotime < 50000 && pps_wait < p1pps->time );
} while ( status == 0 && nanotime < 50000 && pps_wait < MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH );
if (status != 0) return status; //If the ADC read failed, we can't continue
if ( pps_wait >= p1pps->time )
if ( pps_wait >= MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH )
{
RTSLOG_ERROR("Could not sync to the ADC data within the given number of attempts (%d), last nanotime: %lu\n",
p1pps->time, nanotime);
MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH, nanotime);
return SYNC2PPS_ERROR_SYSTIME;
}
}
return sync;
}
void
sync21pps_check( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, int hk_cycle )
// Possible error states:
// 1. No PPS
// - transition_high_cycle will be invalid
// 2. Always over thresh
// - last_cycle_high will be true on last cycle
// 3. More than one pulse in second
// - transition_high_cycle will be larger than MAX_CYCLE_FOR_1PPS_TO_BE_HIGH
// 4. Transition to high and stay high
// - last_cycle_high will be true on last cycle
// 5. Go high mid-second and low after new second
// - Will fail both exit tests, handled
int sync21pps_check( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, int cycle_64k_Hz )
{
p1pps->value = adcinfo.adcData[ ADC_ONEPPS_BRD ][ ADC_DUOTONE_CHAN ];
if ( ( p1pps->value > ONE_PPS_THRESH ) && ( p1pps->signalHi == 0 ) )
p1pps->value = padcinfo->adcData[ ADC_ONEPPS_BRD ][ ADC_DUOTONE_CHAN ];
if ( p1pps->value > ONE_PPS_THRESH )
{
p1pps->time = hk_cycle;
p1pps->signalHi = 1;
//New high state
if ( p1pps->last_cycle_high == 0 ) {
p1pps->last_cycle_high = 1;
p1pps->transition_high_cycle = cycle_64k_Hz;
}
//Continue high state
}
else {
p1pps->last_cycle_high = 0;
}
if ( p1pps->value < ONE_PPS_THRESH )
p1pps->signalHi = 0;
return;
//On last cycle, we expect one of each transition
//and to be in the low state
if ( cycle_64k_Hz == MODEL_RATE_HZ ) {
if( p1pps->transition_high_cycle > MAX_CYCLE_FOR_1PPS_TO_BE_HIGH ||
p1pps->last_cycle_high == 1) {
RTSLOG_ERROR("PPS Tracking error, transition_high_cycle: %d, last_cycle_high: %d\n",
p1pps->transition_high_cycle,
p1pps->last_cycle_high);
return -1;
}
p1pps->transition_high_cycle = 9999;//Reset to invalid number
}
return 0;
}
......@@ -8,6 +8,9 @@
extern "C" {
#endif
#define MAX_CYCLE_FOR_1PPS_TO_BE_HIGH (2)
#define MAX_CYCLES_TO_WAIT_FOR_1PPS_HIGH (MODEL_RATE_HZ * 4) //4 seconds
typedef enum
{
SYNC2PPS_ERROR_OK = 0,
......@@ -16,11 +19,19 @@ typedef enum
SYNC2PPS_ERROR_ADC_TO = ADC_TO_ERROR, //-7
} SYNC2PPS_ERROR_T;
typedef struct one_pps_sync_t
{
float value; /// @param onePps Value of 1PPS signal, if used, for diagnostics
int last_cycle_high; /// @param last_cycle_high One PPS diagnostic check
int transition_high_cycle;
} one_pps_sync_t;
void print_sync2pps_error(SYNC2PPS_ERROR_T error_no);
SYNC2PPS_ERROR_T sync2pps_signal( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, uint64_t cpuClock[] );
void sync21pps_check( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, int hk_cycle );
int sync21pps_check( one_pps_sync_t* p1pps, adcInfo_t* padcinfo, int hk_cycle );
#ifdef __cplusplus
......
......@@ -69,12 +69,6 @@ typedef struct timing_diag_t
} timing_diag_t;
typedef struct one_pps_sync_t
{
float value; /// @param onePps Value of 1PPS signal, if used, for diagnostics
int signalHi; /// @param onePpsHi One PPS diagnostic check
int time; /// @param onePpsTime One PPS diagnostic check
} one_pps_sync_t;
typedef struct loopbacktest_t
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment