Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r46b163d19c65e8c21db7b0247bbb1af0dba1ece5 -r908d078b2a7bad32ffe52ca6b7472b61225b25c8 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 46b163d19c65e8c21db7b0247bbb1af0dba1ece5) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 908d078b2a7bad32ffe52ca6b7472b61225b25c8) @@ -8,7 +8,7 @@ * @file SyringePump.c * * @author (last) Dara Navaei -* @date (last) 22-Sep-2022 +* @date (last) 03-Oct-2022 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -68,7 +68,6 @@ #define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. #define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. #define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. -#define SYRINGE_PUMP_ADC_READ_PERSISTENCE 100 ///< Syringe pump ADC stale read alarm persistence time (in ms). #define STEPS_TO_MICROSTEPS( s ) ( (s) * 32.0F ) ///< Macro conversion from steps to microsteps. #define MICROSTEPS_TO_STEPS( m ) ( (m) / 32.0F ) ///< Macro conversion from microsteps to steps. @@ -154,6 +153,9 @@ #define SYRINGE_PUMP_RAMP_STALL_RETRIES 3 ///< Syringe pump ramp stall retries allowed. #define SYRINGE_PUMP_STALL_SPEED_THRESHOLD 0.05F ///< Minimum syringe pump speed to be considered not stalled. +#define SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Syringe pump ADC FPGA error timeout in milliseconds. +#define SYRINGE_PUMP_DAC_MAX_RETRIES 5 ///< Syringe pump DAC retries to write. +#define SYRINGE_PUMP_DAC_TIMER ( 200 / TASK_PRIORITY_INTERVAL ) ///< Syringe pump DAC timer between retries. /// Defined states for the syringe pump control state machine. typedef enum SyringePump_States { @@ -222,12 +224,13 @@ static BOOL syringePumpDACVrefWriteInProgress; ///< Flag indicates DAC Vref write is in progress. static F32 syringePumpDACVref; ///< DAC Vref setting for force sensor. -static U08 lastSyringePumpADCReadCtr; ///< Remember last ADC read counter to check new reads are fresh. - static U32 syringePumpStallCtr; ///< Counts time when position is not changing during ramp. static U32 syringePumpStallRetryCount; ///< Counts pump ramp up stall retries. static HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T forceSensorCalRecord; ///< HD heparin force sensor calibration record. +static U32 syringePumpDACRetryCount; +static U32 syringePumpDACRetryTimer; + // ********** private function prototypes ********** static void resetSyringePumpRequestFlags( void ); @@ -305,8 +308,6 @@ syringePumpPrimeCompleted = FALSE; syringePumpRampUpPct = 0.0; - lastSyringePumpADCReadCtr = 0; - // Zero pump position counts buffer syringePumpMotorSpeedCalcIdx = 0; for ( i = 0; i < SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN; i++ ) @@ -316,15 +317,19 @@ syringePumpStallCtr = 0; syringePumpStallRetryCount = 0; + syringePumpDACRetryCount = 0; + syringePumpDACRetryTimer = 0; // Initialize persistent alarms - initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR, 0, SYRINGE_PUMP_ADC_READ_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, 0, SYRINGE_PUMP_DIR_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, 0, SYRINGE_PUMP_DIR_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_RUNNING_WHILE_BP_OFF_ERROR, 0, SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, 0, SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, 0, SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_SYRINGE_PUMP_ADC, ALARM_ID_HD_SYRINGE_PUMP_FPGA_ADC_FAULT, + SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS, SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS ); + // Reset request flags resetSyringePumpRequestFlags(); } @@ -1069,22 +1074,15 @@ } } - if ( syringePumpDACVrefWriteInProgress != TRUE ) + if ( ( FALSE == syringePumpDACVrefWriteInProgress ) && ( getCurrentOperationMode() > MODE_INIT ) ) { - // Check ADC read is fresh (takes FPGA a while to configure ADC so don't check until after init/POST mode - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR, - ( ( getCurrentOperationMode() > MODE_INIT ) && ( lastSyringePumpADCReadCtr == getSyringePumpADCReadCounter() ) ) ) ) - { #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR ); - } + { + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_SYRINGE_PUMP_ADC, getSyringePumpADCandDACStatus(), getSyringePumpADCReadCounter() ); } - lastSyringePumpADCReadCtr = getSyringePumpADCReadCounter(); - // Check pump status if ( getSyringePumpStatus() != 0 ) { @@ -1111,6 +1109,11 @@ isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, FALSE ); } + if ( syringePumpDACRetryCount > 0 ) + { + syringePumpDACRetryTimer++; + } + // Execute syringe pump control state machine switch ( syringePumpState ) { @@ -1269,7 +1272,8 @@ sendTreatmentLogEventData( HEPARIN_START_RESUME_EVENT, 0.0, syringePumpSetRate ); result = SYRINGE_PUMP_HEP_CONTINUOUS_STATE; } - else if ( TRUE == syringePumpDACVrefSetRequested ) + else if ( ( TRUE == syringePumpDACVrefSetRequested ) || + ( ( syringePumpDACRetryCount > 0 ) && ( syringePumpDACRetryTimer > SYRINGE_PUMP_DAC_TIMER ) ) ) { U16 vRef = (U16)( ( syringePumpDACVref / SYRINGE_PUMP_ADC_REF_V ) * SYRINGE_PUMP_DAC_FULL_SCALE_BITS ); @@ -1576,28 +1580,46 @@ * The handleSyringePumpCalibrateForceSensorState function handles the * calibrate force sensor state of the syringe pump control state machine. * of the syringe pump control state machine. - * @details Inputs: DAC status + * @details Inputs: DAC status, syringePumpDACRetryCount * @details Outputs: syringePumpDACVrefWriteInProgress, ADC read mode restored + * syringePumpDACRetryCount, syringePumpDACRetryTimer * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpCalibrateForceSensorState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE; U08 adcDACStatus = getSyringePumpADCandDACStatus(); - // Wait for DAC setting write to EEPROM to complete - if ( ( adcDACStatus & SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_DONE ) != 0 ) + // Check DAC write error + if ( ( adcDACStatus & SYRINGE_PUMP_DAC_WRITE_ERROR_BIT ) != 0 ) { + syringePumpDACRetryCount++; + + if ( syringePumpDACRetryCount > SYRINGE_PUMP_DAC_MAX_RETRIES ) + { + syringePumpDACRetryCount = 0; + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_DAC_WRITE_ERROR ); + } + syringePumpDACVrefWriteInProgress = FALSE; // Switch back from DAC to ADC control setFPGASyringePumpADCandDACControlFlags( SYRINGE_PUMP_ADC_DAC_CONTROL_RD_DAC_ON_ADC | SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_ADC ); // Back to off state result = SYRINGE_PUMP_OFF_STATE; } - // Check DAC write error - else if ( ( adcDACStatus & SYRINGE_PUMP_DAC_WRITE_ERROR_BIT ) != 0 ) + + // Wait for DAC setting write to EEPROM to complete + else if ( ( adcDACStatus & SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_DONE ) != 0 ) { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_DAC_WRITE_ERROR ); + // We're done and no error bit found. + // Clear retry attempts. + syringePumpDACRetryCount = 0; + syringePumpDACRetryTimer = 0; + syringePumpDACVrefWriteInProgress = FALSE; + // Switch back from DAC to ADC control + setFPGASyringePumpADCandDACControlFlags( SYRINGE_PUMP_ADC_DAC_CONTROL_RD_DAC_ON_ADC | SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_ADC ); + // Back to off state + result = SYRINGE_PUMP_OFF_STATE; } return result;