Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -rafe402337b84d8843c6ab544643fc403cb382c43 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision afe402337b84d8843c6ab544643fc403cb382c43) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -93,6 +93,7 @@ /// Expected position of empty in relation to home position. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84F ) + /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5F ) /// Minimum retract position. @@ -156,8 +157,10 @@ #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 { Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r4a369538d8e96eada94bc74da213c54c33107426 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 4a369538d8e96eada94bc74da213c54c33107426) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -652,8 +652,7 @@ signalBloodPumpHardStop(); signalDialOutPumpHardStop(); - //setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 250, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); // TODO remove this line once the new flow control is implemented + setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGTrimmerHeater(); } Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r1f91b5a53bda942b0967817bbd5e68a499dbf816 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 1f91b5a53bda942b0967817bbd5e68a499dbf816) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -46,6 +46,7 @@ #define BLOOD_PUMP_FAST_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump fast flow rate during prime recirculate blood circuit state. #define BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN 300 ///< Blood pump flow rate during prime the saline dialyzer dialysate state. #define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. +#define DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN 600 ///< Dialysate pump flow rate during priming fluid path. #define DPO_PUMP_PRIME_FLOW_RATE_ML_MIN 225 ///< Dialysate outlet pump flow rate needed to match PWM with dialysate inlet pump @ 300 mL/min in open loop mode. #define DIALYSATE_DIALYZER_TUBE_VOLUME_ML 115 ///< This total tube volume is used to calculate the Dpi & Dpo time out in the dialysate dialyzer state. @@ -877,15 +878,15 @@ { DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; + rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; rsrvrCmd.useLastTrimmerHeaterDC = FALSE; cmdSetDGActiveReservoir( &rsrvrCmd ); if ( TRUE == hasDGCompletedReservoirSwitch() ) { signalBloodPumpHardStop(); - setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r6742b3e355d70e0bdf036ed93cc2268bdd36cb99 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 6742b3e355d70e0bdf036ed93cc2268bdd36cb99) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -7,8 +7,8 @@ * * @file SelfTests.c * -* @author (last) Dara Navaei -* @date (last) 11-Jan-2023 +* @author (last) Michael Garthwaite +* @date (last) 23-Jan-2023 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -115,6 +115,7 @@ static F32 reservoirVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Hold the current volume of all reservoirs. static BOOL isValvesSettingSent; ///< Flag indicates valve setting change has been send to DG. +static U32 selfTestCartridgeSettleTime; ///< Cartridge settle start time. static U32 selfTestStartTime; ///< Starting time of self-test (in ms). static U32 selfTestPreviousPublishDataTime; ///< Last time self-test time data is being published (in ms). static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. @@ -135,6 +136,7 @@ static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestHomeIdleState( void ); static NO_CART_SELF_TESTS_STATE_T handleNoCartSelfTestStoppedState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestStartState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedCartridgeCheckState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalSetupState( void ); @@ -289,6 +291,8 @@ *************************************************************************/ void execNoCartSelfTests( void ) { + NO_CART_SELF_TESTS_STATE_T priorSubState = currentNoCartSelfTestsState; + // execute no cartridge self-tests state machine switch ( currentNoCartSelfTestsState ) { @@ -336,6 +340,10 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + if ( priorSubState != currentNoCartSelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentNoCartSelfTestsState ); + } // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { @@ -353,7 +361,7 @@ } else { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); +// SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); } } } @@ -388,9 +396,9 @@ previousNormalVenousPressure = 0.0; selfTestStartTime = getMSTimerCount(); selfTestPreviousPublishDataTime = getMSTimerCount(); + selfTestCartridgeSettleTime = getMSTimerCount(); + doorClosedRequired( FALSE, TRUE ); - doorClosedRequired( TRUE, TRUE ); - // Pumps should be off signalBloodPumpHardStop(); signalDialInPumpHardStop(); @@ -416,25 +424,13 @@ *************************************************************************/ void execDrySelfTests( void ) { + DRY_SELF_TESTS_STATE_T priorSubState = currentDrySelfTestsState; + // execute dry self-tests state machine switch ( currentDrySelfTestsState ) { case DRY_SELF_TESTS_START_STATE: - // Ensure occlusion sensor has time to settle after cartridge insertion before starting dry self-tests - if ( TRUE == didTimeout( selfTestStartTime, CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ) ) - { - setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) - { - currentDrySelfTestsState = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; - } - else -#endif - { - currentDrySelfTestsState = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; - } - } + currentDrySelfTestsState = handleDrySelfTestStartState(); break; case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: @@ -512,6 +508,10 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + if ( priorSubState != currentDrySelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentDrySelfTestsState ); + } // Publish current self-test time data if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) { @@ -590,6 +590,8 @@ *************************************************************************/ void execWetSelfTests( void ) { + WET_SELF_TESTS_STATE_T priorSubState = currentWetSelfTestsState; + #ifndef _RELEASE_ if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) || ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) ) ) @@ -660,6 +662,11 @@ // Self-tests flags should be handled by now, reset if flags not handled with current state resetSelfTestsFlags(); + + if ( priorSubState != currentWetSelfTestsState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentWetSelfTestsState ); + } } /*********************************************************************//** @@ -893,6 +900,52 @@ /*********************************************************************//** * @brief + * The handleDrySelfTestStartState function makes sure door is + * closed before starting self-tests. + * @details Inputs: none + * @details Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestStartState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_START_STATE; + OPN_CLS_STATE_T pumpTrack = getSwitchStatus( PUMP_TRACK_SWITCH ); + + if ( STATE_CLOSED == pumpTrack ) + { + // Ensure occlusion sensor has time to settle after cartridge insertion before starting dry self-tests + if ( TRUE == didTimeout( selfTestCartridgeSettleTime, CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ) ) + { + setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed + doorClosedRequired( TRUE, TRUE ); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) + { + state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; + } + else +#endif + { + state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + } + } + } + + else + { + // doorClosedRequired() will trigger alarms if pumpTrack is open + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleDrySelfTestWaitForDoorCloseState function makes sure door is * closed before starting self-tests. * @details Inputs: none @@ -908,8 +961,7 @@ // Restart self-test start time selfTestStartTime = getMSTimerCount(); - // TODO: Use appropriate sensor driver - if (( STATE_CLOSED == frontDoor ) && (STATE_CLOSED == pumpTrack ) ) + if ( ( STATE_CLOSED == frontDoor ) && ( STATE_CLOSED == pumpTrack ) ) { state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); @@ -1453,22 +1505,24 @@ doorClosedRequired( FALSE, FALSE ); - // Restart self-test start time - selfTestStartTime = getMSTimerCount(); - if ( TRUE == selfTestsResumeRequested ) { + // Restart self-test start time + selfTestStartTime = getMSTimerCount(); selfTestsResumeRequested = FALSE; - doorClosedRequired( TRUE, TRUE ); + selfTestCartridgeSettleTime = getMSTimerCount(); + #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) ) { + doorClosedRequired( TRUE, TRUE ); state = DRY_SELF_TESTS_SYRINGE_PUMP_PRIME_STATE; } else #endif { - state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + doorClosedRequired( FALSE, TRUE ); + state = DRY_SELF_TESTS_START_STATE; } } Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r0f9838d6b8606a6a9853ccb6157e4c25d70ddd02 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 0f9838d6b8606a6a9853ccb6157e4c25d70ddd02) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -959,23 +959,24 @@ else { if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) -#ifndef _RELEASE_ { - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) != SW_CONFIG_ENABLE_VALUE ) +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) ) { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) + setAlarmAudioState( ALARM_PRIORITY_HIGH, + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); + } + + else +#endif + { setAlarmAudioState( alarmStatus.alarmsState, ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); } } - else -#endif - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - setAlarmAudioState( ALARM_PRIORITY_HIGH, - ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], - ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); - } } }