Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r43a84133216095b12529dbfcc957bb3738bbc3a2 -r0f68c8f7dadf2a493aed0d123a10a42474b7b7cb --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 43a84133216095b12529dbfcc957bb3738bbc3a2) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 0f68c8f7dadf2a493aed0d123a10a42474b7b7cb) @@ -7,8 +7,8 @@ * * @file ModePreTreat.c * -* @author (last) Hung Nguyen -* @date (last) 15-Feb-2022 +* @author (last) Darren Cox +* @date (last) 17-Mar-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -161,6 +161,19 @@ cmdStopDGTrimmerHeater(); + // Pumps should be off + signalBloodPumpHardStop(); + signalDialInPumpHardStop(); + signalDialOutPumpHardStop(); + stopSyringePump(); + + // Set valves to default positions + setValveAirTrap( STATE_CLOSED ); + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( VDO, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( VBV, VALVE_POSITION_A_INSERT_EJECT ); + // Set user alarm recovery actions allowed in this mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); @@ -189,7 +202,9 @@ switch ( currentPreTreatmentState ) { case HD_PRE_TREATMENT_START_STATE: +#ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SAMPLE_WATER ) != SW_CONFIG_ENABLE_VALUE ) +#endif { transitionToSampleWater(); } @@ -247,6 +262,46 @@ /*********************************************************************//** * @brief + * The verifySwitchStatus function checks Pump Track and Door switches are closed. + * Verify Syringe is installed if needed. + * Alarm is set if not. Alarms cleared by driver executives. + * @details Inputs: none + * @details Outputs: Alarm + * @return none + *************************************************************************/ +void verifySwitchStatus( void ) +{ + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SWITCHES_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + if ( STATE_OPEN == getSwitchStatus( FRONT_DOOR ) ) + { + activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); + } + + if ( STATE_OPEN == getSwitchStatus( PUMP_TRACK_SWITCH ) ) + { + activateAlarmNoData( ALARM_ID_PUMP_TRACK_LATCH_OPENED ); + } + } + +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + if ( ( FALSE == isSyringeDetected() ) && ( ( bolusVol > NEARLY_ZERO ) && ( hepRate > NEARLY_ZERO ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_REMOVED ); + } + } +} + +/*********************************************************************//** + * @brief * The signalUserConfirmInstallation function handles user confirmation of * disposable installation. * @details Inputs: none @@ -255,17 +310,60 @@ *************************************************************************/ void signalUserConfirmInstallation( void ) { + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + confirmInstallRequested = FALSE; + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); F32 hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); - // Accept installation confirmation if we are in install state of pre-treatment mode and syringe is detected or Heparin not being used in this treatment. - if ( ( MODE_PRET == getCurrentOperationMode() ) && - ( HD_PRE_TREATMENT_CART_INSTALL_STATE == currentPreTreatmentState ) && - ( ( TRUE == isSyringeDetected() ) || ( ( bolusVol < NEARLY_ZERO ) && ( hepRate < NEARLY_ZERO ) ) ) ) + // Accept installation confirmation if we are in install state of pre-treatment mode and + // Door closed, Cartridge installed, syringe is detected or Heparin not being used in this treatment. + if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_CART_INSTALL_STATE == currentPreTreatmentState ) ) { - confirmInstallRequested = TRUE; + OPN_CLS_STATE_T frontDoor = getSwitchStatus( FRONT_DOOR ); + OPN_CLS_STATE_T pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_SWITCHES_MONITOR ) ) + { + frontDoor = STATE_CLOSED; + pumpTrack = STATE_CLOSED; + } +#endif + + if ( STATE_CLOSED == pumpTrack ) + { + if ( STATE_CLOSED == frontDoor ) + { + if ( ( TRUE == isSyringeDetected() ) || ( ( bolusVol < NEARLY_ZERO ) && ( hepRate < NEARLY_ZERO ) ) ) + { + // Everything is properly installed + accepted = TRUE; + confirmInstallRequested = TRUE; + } + else + { + rejReason = REQUEST_REJECT_REASON_SYRINGE_NOT_PRESENT; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_DOOR_NOT_CLOSED; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_PUMP_TRACK_NOT_CLOSED; + } } - // TODO - send a reject reason if not accepting confirmation + else + { + rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + sendConsumableInstallCmdResponse( accepted, (U32) rejReason ); } /*********************************************************************//** @@ -346,10 +444,12 @@ BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NO_PATIENT_CONNECTION_CONFIRM; +#ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { patientConnectionConfirm = TRUE; } +#endif if ( TRUE == patientConnectionConfirm ) { @@ -420,12 +520,24 @@ * given reservoir. * @details Inputs: reservoirFilledStatus * @details Outputs: none - * @return TRUE if reservoir has been filled, otherwise FALSE; + * @return TRUE if reservoir has been filled, otherwise FALSE *************************************************************************/ BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) { return reservoirFilledStatus[ reservoirID ]; } +/*********************************************************************//** + * @brief + * The getPreTreatmentSubState function gets the current + * pre-treatment mode state. + * @details Inputs: currentPreTreatmentState + * @details Outputs: none + * @return currentPreTreatmentState + *************************************************************************/ +HD_PRE_TREATMENT_MODE_STATE_T getPreTreatmentSubState( void ) +{ + return currentPreTreatmentState; +} /*********************************************************************//** * @brief @@ -451,6 +563,7 @@ preTreatmentData.primeState = getPrimeState(); preTreatmentData.recircState = getPreTreatmentRecircState(); preTreatmentData.patientConnectionState = 0; + preTreatmentData.wetSelfTestsState = getWetSelfTestState(); broadcastData( MSG_ID_PRE_TREATMENT_STATE, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&preTreatmentData, sizeof( PRE_TREATMENT_STATE_DATA_T ) ); preTreatmentPublishTimerCounter = 0; @@ -485,12 +598,18 @@ { VALVE_T valve; + // Set valves for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) { setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); } - setValveAirTrap( STATE_CLOSED ); + + // Pumps should be off + signalBloodPumpHardStop(); + signalDialInPumpHardStop(); + signalDialOutPumpHardStop(); + stopSyringePump(); } /*********************************************************************//** @@ -535,28 +654,29 @@ execSampleWater(); - if ( ( SAMPLE_WATER_COMPLETE_STATE == getSampleWaterState() ) || - ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_SAMPLE_WATER ) ) ) + if ( SAMPLE_WATER_COMPLETE_STATE == getSampleWaterState() ) { - cmdDGSampleWater( SAMPLE_WATER_CMD_END ); - - if ( SELF_TEST_STATUS_PASSED == getSampleWaterResult() ) { - if ( ( DG_MODE_STAN == dgOpMode ) && ( DG_STANDBY_MODE_STATE_IDLE == dgSubMode ) ) + cmdDGSampleWater( SAMPLE_WATER_CMD_END ); + + if ( SELF_TEST_STATUS_PASSED == getSampleWaterResult() ) { - state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; - cmdStartDG(); - transitionToConsumableSelfTest(); + if ( ( DG_MODE_STAN == dgOpMode ) && ( DG_STANDBY_MODE_STATE_IDLE == dgSubMode ) ) + { + state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + cmdStartDG(); + transitionToConsumableSelfTest(); + } + else + { + cmdStopDG(); + } } else { - cmdStopDG(); + requestNewOperationMode( MODE_STAN ); } } - else - { - requestNewOperationMode( MODE_STAN ); - } } return state; @@ -601,11 +721,6 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; - if ( STATE_OPEN == getFPGADoorState() ) - { - activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); - } - if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; @@ -623,6 +738,14 @@ transitionToCartridgeInstallation(); } } + else + { + if ( ( NO_CART_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE <= getNoCartSelfTestsState() ) && + ( NO_CART_SELF_TESTS_STOPPED_STATE != getNoCartSelfTestsState() ) ) + { + verifySwitchStatus(); + } + } return state; } @@ -639,10 +762,12 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_CART_INSTALL_STATE; +#ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { confirmInstallRequested = TRUE; } +#endif if ( TRUE == confirmInstallRequested ) { @@ -665,11 +790,6 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_DRY_STATE; - if ( STATE_OPEN == getFPGADoorState() ) - { - activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); - } - if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; @@ -687,6 +807,14 @@ transitionToPrime(); } } + else + { + if ( ( DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE <= getDrySelfTestsState() ) && + ( DRY_SELF_TESTS_STOPPED_STATE != getDrySelfTestsState() ) ) + { + verifySwitchStatus(); + } + } return state; } @@ -703,11 +831,6 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_PRIME_STATE; - if ( STATE_OPEN == getFPGADoorState() ) - { - activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); - } - if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; @@ -726,6 +849,13 @@ transitionToPreTreatmentRecirc(); } } + else + { + if ( ( HD_PRIME_PAUSE != getPrimeState() ) ) + { + verifySwitchStatus(); + } + } return state; } @@ -742,11 +872,6 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_RECIRCULATE_STATE; - if ( STATE_OPEN == getFPGADoorState() ) - { - activateAlarmNoData( ALARM_ID_CARTRIDGE_DOOR_OPENED ); - } - if ( TRUE == alarmActionResumeReceived ) { alarmActionResumeReceived = FALSE; @@ -755,10 +880,17 @@ execPreTreatmentRecirc(); + if ( PRE_TREATMENT_RECIRC_STOPPED_STATE != getPreTreatmentRecircState() ) + { + verifySwitchStatus(); + } + +#ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_INTERACTION ) ) { continueToTreatmentRequested = TRUE; } +#endif if ( TRUE == continueToTreatmentRequested ) { @@ -785,7 +917,6 @@ DG_RESERVOIR_ID_T const activeRes = getDGActiveReservoir(); setStartReservoirVolume( activeRes ); - resetHeparinVolumeDelivered(); // get clean starting volume/position before we start treatment requestNewOperationMode( MODE_TREA ); } @@ -950,21 +1081,25 @@ { U32 volume = FILL_RESERVOIR_TO_VOLUME_ML; +#ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) != SW_CONFIG_ENABLE_VALUE ) { volume = PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML; } +#endif cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); } else { U32 volume = FILL_RESERVOIR_TO_VOLUME_ML; +#ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) != SW_CONFIG_ENABLE_VALUE ) { volume = PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML; } +#endif cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); } @@ -973,10 +1108,12 @@ { U32 volume = FILL_RESERVOIR_TO_VOLUME_ML; +#ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) != SW_CONFIG_ENABLE_VALUE ) { volume = PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML; } +#endif cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); } @@ -999,12 +1136,20 @@ DG_CMD_RESPONSE_T dgCmdResp; DG_OP_MODE_T dgOpMode = getDGOpMode(); - - if ( ( TRUE == getDGCommandResponse( DG_CMD_START_FILL, &dgCmdResp ) ) && ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejectCode ) ) + // handle fill command response from DG + if ( TRUE == getDGCommandResponse( DG_CMD_START_FILL, &dgCmdResp ) ) { - state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + if ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejectCode ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + } + else if ( dgCmdResp.rejectCode != DG_CMD_REQUEST_REJECT_REASON_NONE ) + { + // TODO - s/w fault + } } + // wait for DG to begin filling before moving on to next state if ( DG_MODE_FILL == dgOpMode ) { state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; @@ -1049,11 +1194,13 @@ if ( FALSE == reservoirFlushedStatus[ DG_RESERVOIR_1 ] ) { +#ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) { reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; } else +#endif { reservoirFlushedStatus[ DG_RESERVOIR_1 ] = TRUE; cmdSetDGActiveReservoir( DG_RESERVOIR_1 );