Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r98a1a2a624373a1d140daed0136522ab6e635237 -reeaab2a9a685fb18845888d91040d3aa01977f6d --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 98a1a2a624373a1d140daed0136522ab6e635237) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision eeaab2a9a685fb18845888d91040d3aa01977f6d) @@ -1,15 +1,15 @@ /************************************************************************** * -* Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeGenIdle.c * -* @author (last) Dara Navaei -* @date (last) 23-May-2022 +* @author (last) Michael Garthwaite +* @date (last) 16-May-2023 * * @author (original) Quang Nguyen * @date (original) 06-Aug-2021 @@ -46,24 +46,25 @@ // ********** 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 TARGET_RO_FLOW_RATE_L 0.4F ///< Target flow rate for RO pump. #define BAD_FLUSH_FILL_TARGET_VOLUME_ML 1000 ///< Target fill volume in the bad flush fill state. #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. // ********** private data ********** +static U32 dataPublishCounter; ///< Used to schedule gen idle data publication to CAN bus. static DG_GEN_IDLE_MODE_STATE_T genIdleState; ///< Currently active generation idle state. // 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. 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 badFillSubstatesPublishInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, - BAD_FILL_SUBSTATES_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish bad fill sub-states to CAN bus. +static OVERRIDE_U32_T genIdleDataPublicationInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, + BAD_FILL_SUBSTATES_PUB_INTERVAL, + 0, 0 }; ///< Interval (in ms) at which to publish bad fill sub-states to CAN bus. // ********** private function prototypes ********** @@ -75,9 +76,9 @@ 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 publishBadFillSubstates( U32 badFill ); +static void publishGenIdleSubstates(); /*********************************************************************//** * @brief @@ -103,7 +104,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 ); @@ -114,9 +115,12 @@ 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 ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); // UV reactors on turnOnUVReactor( INLET_UV_REACTOR ); @@ -126,9 +130,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; @@ -190,7 +198,6 @@ checkInletWaterConductivity(); checkInletWaterTemperature(); checkInletWaterPressure(); - checkRORejectionRatio(); // Transition to standby mode when HD is not communicating if ( TRUE == isHDCommunicating() ) @@ -226,6 +233,8 @@ break; } + publishGenIdleSubstates(); + return (U32)genIdleState; } @@ -274,12 +283,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 ) @@ -301,7 +311,7 @@ break; case DG_HANDLE_BAD_FILL_STATE_REFILL: - badFillState = handleRefillState(); + badFillState = handleRefillState( &result ); break; default: @@ -310,6 +320,10 @@ break; } + if ( priorSubState != badFillState ) + { + setCurrentSubState( badFillState ); + } return result; } @@ -325,9 +339,6 @@ { DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; - // Publish the state prior to requesting a drain and transitioning to drain mode - publishBadFillSubstates( state ); - // Drain the bad filled reservoir first requestNewOperationMode( DG_MODE_DRAI ); @@ -347,23 +358,16 @@ 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; - // Publish the state prior to transitioning to fill mode - publishBadFillSubstates( state ); - // Start the flush fill startFillCmd( BAD_FLUSH_FILL_TARGET_VOLUME_ML, getTargetFillFlowRateLPM() ); } - else - { - publishBadFillSubstates( state ); - } return state; } @@ -380,9 +384,6 @@ { DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; - // Publish the state prior to transitioning to drain mode - publishBadFillSubstates( state ); - requestNewOperationMode( DG_MODE_DRAI ); return state; @@ -400,9 +401,6 @@ { DG_GEN_IDLE_MODE_BAD_FILL_STATE_T state = DG_HANDLE_BAD_FILL_STATE_REFILL; - // Publish the state prior to transitioning to fill mode - publishBadFillSubstates( state ); - // Refill to the saved target fill volume (~1500 mL) startFillCmd( targetFillVolumeML, getTargetFillFlowRateLPM() ); @@ -414,39 +412,49 @@ * 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; - publishBadFillSubstates( state ); - // 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; } /*********************************************************************//** * @brief - * The publishBadFillSubstates function publishes idle mode bad fill + * The publishGenIdleSubstates function publishes gen idle * sub-states at the set interval. - * @details Inputs: none - * @details Outputs: none - * @param badFill the bad fill state that has to be published + * @details Inputs: handleBadFillFlag, badFillState, targetFillVolumeML, + * dataPublishCounter + * @details Outputs: dataPublishCounter * @return none *************************************************************************/ -static void publishBadFillSubstates( U32 badFill ) +static void publishGenIdleSubstates( void ) { - GEN_IDLE_BAD_FILL_STATE data; + // publish Gen Idle pump data on interval + if ( ++dataPublishCounter >= getU32OverrideValue( &genIdleDataPublicationInterval ) ) + { + DG_GEN_IDLE_DATA_T data; - data.badFillState = badFill; + // Populate the data structure for publication + data.badFillSignal = (U32)handleBadFillFlag; + data.badFillState = (U32)badFillState; + data.genIdleState = (U32)getCurrentGenIdleState(); + data.targetFillVolumemL = targetFillVolumeML; - broadcastData( MSG_ID_DG_BAD_FILL_SUB_STATE, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( GEN_IDLE_BAD_FILL_STATE ) ); + broadcastData( MSG_ID_DG_GEN_IDLE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( DG_GEN_IDLE_DATA_T ) ); + + dataPublishCounter = 0; + } } @@ -464,15 +472,15 @@ * @param: value override bad fill sub-states publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testSetBadFillSubstatesPublishIntervalOverride( U32 value ) +BOOL testSetGenIdleSubstatesPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_GENERAL_INTERVAL; - badFillSubstatesPublishInterval.ovData = intvl; - badFillSubstatesPublishInterval.override = OVERRIDE_KEY; + genIdleDataPublicationInterval.ovData = intvl; + genIdleDataPublicationInterval.override = OVERRIDE_KEY; result = TRUE; } @@ -487,14 +495,14 @@ * @details Outputs: badFillSubstatesPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ -BOOL testResetBadFillSubstatesPublishIntervalOverride( void ) +BOOL testResetGenIdleSubstatesPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { - badFillSubstatesPublishInterval.override = OVERRIDE_RESET; - badFillSubstatesPublishInterval.ovData = badFillSubstatesPublishInterval.ovInitData; + genIdleDataPublicationInterval.override = OVERRIDE_RESET; + genIdleDataPublicationInterval.ovData = genIdleDataPublicationInterval.ovInitData; result = TRUE; }