DAC TX Dropout
There is an issue in the RTS where long cycles in (only) a usermodel driving a DAC will cause the IOP to drive the DAC to 0 for the remainder of the second.
I observed high CPU max times on the usermodel corresponding with the zeroed data.
Test Setup
A LIGO DAC and 20-bit DAC looped back into a ADC. I added a delay part, and trigger a delay during the diaggui capture .
In the above pictures we can see both DACs are affected by the introduced time glitch.
Code Issues
src/include/drv/iop_dac_functions.c:162
/// - -- Determine if memory block has been set with the correct
/// cycle count by control app.
if ( ioMemData->iodata[ mm ][ ioMemCntrDac ].cycle == ioClockDac )
{
dacEnable |= pBits[ card ];
}
else
{
dacEnable &= ~( pBits[ card ] );
dacChanErr[ card ] += 1;
}
... //In the above code, if we ever miss data from the usermodel, the IOP
... //increments the dacChanErr count. And in the code below, if dacChanErr
... //is positive, we zero out the DAC's output.
/// - ---- Read DAC output value from shared memory and reset
/// memory to zero
if ( ( !dacChanErr[ card ] ) && ( iopDacEnable ) )
{
dac_out = ioMemData->iodata[ mm ][ ioMemCntrDac ] .data[ chan ];
/// - --------- Zero out data in case user app dies by next
/// cycle when two or more apps share same DAC module.
ioMemData->iodata[ mm ][ ioMemCntrDac ].data[ chan ] = 0;
}
else
{
dac_out = 0;
status = 1;
}
So, when does dacChanErr
get reset? Once a second...
src/fe/controllerIop.c:1235
// *****************************************************************
/// \> Cycle 21, Update ADC/DAC status to EPICS.
// *****************************************************************
if ( hkp_cycle == HKP_ADC_DAC_STAT_UPDATES )
{
pLocalEpics->epicsOutput.ovAccum = overflowAcc;
feStatus |= adc_status_update( &adcinfo );
feStatus |= dac_status_update( &dacinfo );
// pLocalEpics->epicsOutput.fe_status = NORMAL_RUN;
}
src/include/drv
LIGO_INLINE int
dac_status_update( dacInfo_t* dacinfo )
{
...
dacChanErr[ jj ] = 0;
...