Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r2c08db070a6e09306caf461e7aceeb53097fd995 -rf847ac4a7a0a080c4b62886243f5b863c4e7730d --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 2c08db070a6e09306caf461e7aceeb53097fd995) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision f847ac4a7a0a080c4b62886243f5b863c4e7730d) @@ -9,7 +9,7 @@ * @file ModeGenIdle.c * * @author (last) Dara Navaei -* @date (last) 02-Jan-2023 +* @date (last) 19-Sep-2023 * * @author (original) Quang Nguyen * @date (original) 06-Aug-2021 @@ -39,15 +39,14 @@ #include "Valves.h" /** - * @addtogroup DGRecirculateMode + * @addtogroup DGGenIdleMode * @{ */ // ********** private definitions ********** #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. -#define TARGET_RO_FLOW_RATE_L 0.3F ///< Target flow rate for RO pump. -#define BAD_FLUSH_FILL_TARGET_VOLUME_ML 1000 ///< Target fill volume in the bad flush fill state. +#define TARGET_RO_FLOW_RATE_L 0.8F ///< Target flow rate for RO pump. #define HD_LOST_COMM_TIMEOUT_MS (5 * SEC_PER_MIN * MS_PER_SECOND ) ///< The time of HD lost comm before DG transition back to standby. #define BAD_FILL_SUBSTATES_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the bad fill sub-states is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 61 ///< Data publish counter start count. @@ -59,8 +58,10 @@ // NOTE: the bad fill state must be initialized here and not in the transition function since in case of a bad fill, the transition function is called // several times to drain and fill and handle a bad fill. static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T badFillState = DG_HANDLE_BAD_FILL_STATE_START; ///< Initialize bad fill sub-state. +// NOTE: the empty bottle flag must be initialized here and not in transition function since this flag must be set to false once the empty bottle +// fill is finished. +static BOOL handleEmptyBottleFlag = FALSE; ///< Internal siganl flag to handle empty bottle flag. static U32 hdLostCommStartTime_ms; ///< Lost communication with HD start time in ms. -static U32 targetFillVolumeML; ///< Save the target fill volume before calling startFillCmd(). static BOOL handleBadFillFlag; ///< Internal signal flag to handle bad fill. static OVERRIDE_U32_T genIdleDataPublicationInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, BAD_FILL_SUBSTATES_PUB_INTERVAL, @@ -76,7 +77,7 @@ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFirstDrainState( void ); static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFlushFillState( void ); static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleSecondDrainState( void ); -static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( void ); +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( DG_GEN_IDLE_MODE_STATE_T* idleState ); static void publishGenIdleSubstates(); @@ -104,7 +105,7 @@ { // Re-initialize each time we transition to generation idle mode initGenIdleMode(); - + setCurrentSubState( NO_SUB_STATE ); // Set initial actuator states setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); @@ -115,6 +116,9 @@ setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + // Set back the conductivity of CD2 calibration table to the normal calibration table + setCondcutivitySensorCalTable( CONDUCTIVITYSENSORS_CD2_SENSOR, CAL_DATA_CD2_COND_SENSOR ); + signalDrainPumpHardStop(); requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); @@ -127,9 +131,13 @@ // because the initial guess in the heaters driver needs the target flow to calculate // the new PWMs for the main and small primary heaters setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); - setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); - startHeater( DG_PRIMARY_HEATER ); + if ( FALSE == isHeaterOn( DG_PRIMARY_HEATER ) ) + { + setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); + startHeater( DG_PRIMARY_HEATER ); + } + setCPLDCleanLEDColor( CPLD_CLEAN_LED_OFF ); return genIdleState; @@ -150,6 +158,19 @@ /*********************************************************************//** * @brief + * The getCurrentGenIdleBadFillState function returns the current state of the + * generation idle mode bad fill. + * @details Inputs: badFillState + * @details Outputs: none + * @return the current state of generation idle mode bad fill + *************************************************************************/ +DG_GEN_IDLE_MODE_BAD_FILL_STATE_T getCurrentGenIdleBadFillState( void ) +{ + return badFillState; +} + +/*********************************************************************//** + * @brief * The requestDGStop function handles an HD request to stop (return to standby mode). * @details Inputs: none * @details Outputs: DG standby mode requested @@ -169,13 +190,13 @@ * The setBadAvgConductivityDetectedFlag function sets a flag to indicate * that bad average conductivity is detected. * @details Inputs: none - * @details Outputs: none + * @details Outputs: handleBadFillFlag, badFillState * @param flag to TRUE if bad avg conductivity otherwise FALSE *************************************************************************/ void setBadAvgConductivityDetectedFlag( BOOL badAvgConducitivyflag ) { handleBadFillFlag = badAvgConducitivyflag; - badFillState = DG_HANDLE_BAD_FILL_STATE_START; // Reset bad fill state too so we start at beginning + badFillState = DG_HANDLE_BAD_FILL_STATE_START; // Reset bad fill state too so we start at beginning } /*********************************************************************//** @@ -235,8 +256,8 @@ * @brief * The handleIdleStartState function executes the start state of the * generation idle mode state machine. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: handleEmptyBottleFlag + * @details Outputs: handleEmptyBottleFlag, handleBadFillFlag, badFillState * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleIdleStartState( void ) @@ -251,6 +272,14 @@ { badFillState = DG_HANDLE_BAD_FILL_STATE_START; result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; + + if ( ( TRUE == handleEmptyBottleFlag ) && ( DG_MODE_FILL == getPreviousOperationMode() ) ) + { + // If the previous mode was fill and the empty bottle flag was TRUE, set it to FALSE and clear the informative alarm + // Done with the empty bottle handling + handleEmptyBottleFlag = FALSE; + clearAlarmCondition( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); + } } return result; @@ -260,14 +289,20 @@ * @brief * The handleFlushWaterState function executes the flush water state * generation idle mode state machine. - * @details Inputs: none - * @details Outputs: none + * @details Inputs: handleEmptyBottleFlag + * @details Outputs: handleEmptyBottleFlag * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ) { DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; + if ( ( TRUE == isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) ) || ( TRUE == isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) ) ) + { + // The empty bottle alarms are active set the empty bottle alarm to TRUE. + handleEmptyBottleFlag = TRUE; + } + return result; } @@ -276,12 +311,13 @@ * The handleBadFillState function executes the bad fill state of the * generation idle mode state machine. * @details Inputs: none - * @details Outputs: badFillState + * @details Outputs: badFillState, genIdleState * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleBadFillState( void ) { DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_HANDLE_BAD_FILL; + U32 priorSubState = badFillState; // Execute current bad fill state switch ( badFillState ) @@ -303,7 +339,7 @@ break; case DG_HANDLE_BAD_FILL_STATE_REFILL: - badFillState = handleRefillState(); + badFillState = handleRefillState( &result ); break; default: @@ -312,6 +348,10 @@ break; } + if ( priorSubState != badFillState ) + { + setCurrentSubState( badFillState ); + } return result; } @@ -346,15 +386,15 @@ DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; // Check if the alarm has been cleared by the user and if yes, continue with the fill - if ( FALSE == isAlarmActive( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE ) ) + if ( FALSE == isAlarmActive( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE ) ) { - // Save the HD target fill volume before command 1000 mL fill volume - targetFillVolumeML = getTargetFillVolumeML(); + state = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; - state = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; - - // Start the flush fill - startFillCmd( BAD_FLUSH_FILL_TARGET_VOLUME_ML, getTargetFillFlowRateLPM() ); + // Start the flush fill. + // NOTE: the actual target fill from HD is sent here but at this stage the fill target is 1000 mL. + // The other functions that check against the fill target know to check for 1000 mL. This is to make sure + // the actual fill target from HD is not overridden in case multiple bad fills occurred back to back. + startFillCmd( getTargetFillVolumeML(), getTargetFillFlowRateLPM() ); } return state; @@ -390,7 +430,7 @@ DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_REFILL; // Refill to the saved target fill volume (~1500 mL) - startFillCmd( targetFillVolumeML, getTargetFillFlowRateLPM() ); + startFillCmd( getTargetFillVolumeML(), getTargetFillFlowRateLPM() ); return state; } @@ -400,17 +440,19 @@ * The handleRefillState function executes refill state of the handle bad * fill state machine. * @details Inputs: none - * @details Outputs: none + * @details Outputs: handleBadFillFlag + * @param idleState reference variable for the next idle state * @return the next state *************************************************************************/ -static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( void ) +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( DG_GEN_IDLE_MODE_STATE_T* idleState ) { DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_START; // Clear wait for dialysate alarm condition to allow resume - clearAlarmCondition( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); // resume option will appear + clearAlarmCondition( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); // resume option will appear // Set flag to FALSE here so next call to idle exec will move to normal flush water state handleBadFillFlag = FALSE; + *idleState = DG_GEN_IDLE_MODE_STATE_START; return state; } @@ -435,15 +477,28 @@ data.badFillSignal = (U32)handleBadFillFlag; data.badFillState = (U32)badFillState; data.genIdleState = (U32)getCurrentGenIdleState(); - data.targetFillVolumemL = targetFillVolumeML; + data.targetFillVolumemL = getTargetFillVolumeML(); broadcastData( MSG_ID_DG_GEN_IDLE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( DG_GEN_IDLE_DATA_T ) ); dataPublishCounter = 0; } } +/*********************************************************************//** + * @brief + * The getCurrentBadFillSignal function returns the current + * generation idle mode bad fill flag. + * @details Inputs: handleBadFillFlag + * @details Outputs: none + * @return the current generation idle mode bad fill flag + *************************************************************************/ +BOOL getCurrentBadFillSignal( void ) +{ + return handleBadFillFlag; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -455,7 +510,7 @@ * bad fill sub-states publish interval. * @details Inputs: badFillSubstatesPublishInterval * @details Outputs: badFillSubstatesPublishInterval - * @param: value override bad fill sub-states publish interval with (in ms) + * @param value override bad fill sub-states publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetGenIdleSubstatesPublishIntervalOverride( U32 value )