Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -re28e96fba3f2293208e6d91673288acba2514cca -rd502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision e28e96fba3f2293208e6d91673288acba2514cca) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision d502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92) @@ -97,6 +97,7 @@ F32 fillFlowRateAverage; ///< Fill flow average value. F32 fillLastTemperature; ///< Fill last temperature value. BOOL isThisFirstFill; ///< Fill flag to indicate whether it is the first fill or not. + BOOL fillAvgConductivityOutOfRange; ///< Fill average conductivity out of range. } FILL_CONDITION_STATUS_T; /// DG broadcast dialysate fill data structure. @@ -108,7 +109,7 @@ F32 pctDiffInConductivity; ///< The percent difference between CD1 and CD2. F32 usedAcidVolumeML; ///< The used acid volume in ML. F32 usedBicarbVolumeML; ///< The used bicarb volume in ML. -} DG_FILL_DIALYSATE_DATA_T; +} DG_FILL_MODE_DATA_T; static U32 fillModeDataPublicationTimerCounter; ///< Used to schedule dialysate fill data publication to CAN bus. static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. @@ -376,6 +377,7 @@ fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; fillStatus.isThisFirstFill = TRUE; + fillStatus.fillAvgConductivityOutOfRange = FALSE; } /*********************************************************************//** @@ -393,6 +395,19 @@ /*********************************************************************//** * @brief + * The isAvgConductivityOutOfRange function returns the boolean flag that indicates + * whether the average conductivity is out of range. + * @details Inputs: none + * @details Outputs: none + * @return fillStatus.fillAvgConductivityOutOfRange + *************************************************************************/ +BOOL isAvgConductivityOutOfRange( void ) +{ + return fillStatus.fillAvgConductivityOutOfRange; +} + +/*********************************************************************//** + * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. @@ -741,13 +756,25 @@ #ifndef DISABLE_DIALYSATE_CHECK // SRSDG 400 if ( TRUE == isValueWithinPercentRange( avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { + fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode + requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg bicarb is out of range SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgBicardConductivity, BICARB_NORMAL_CONDUCTIVITY ); } + else + { + fillStatus.fillAvgConductivityOutOfRange = FALSE; + } if ( TRUE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { + fillStatus.fillAvgConductivityOutOfRange = TRUE; // signal idle mode + requestNewOperationMode( DG_MODE_GENE ); // leave fill mode if bad fill is detected due to avg acid out of range SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_CONDUCTIVITY_FAULT, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); } + else + { + fillStatus.fillAvgConductivityOutOfRange = FALSE; + } #endif // Done with this fill. Calculate the average fill flow rate and average temperature // Reset the variables for the next fill @@ -937,7 +964,7 @@ // publish Drain pump data on interval if ( ++fillModeDataPublicationTimerCounter >= getU32OverrideValue( &fillModeDataPublishInterval ) ) { - DG_FILL_DIALYSATE_DATA_T fillModeData; + DG_FILL_MODE_DATA_T fillModeData; // Populate the data structure for publication fillModeData.averageAcidConductivity = averageAcidConductivity; @@ -947,7 +974,7 @@ fillModeData.usedAcidVolumeML = usedAcidVolumeML.data; fillModeData.usedBicarbVolumeML = usedBicarbVolumeML.data; - broadcastData( MSG_ID_DRAIN_PUMP_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&fillModeData, sizeof( DG_FILL_DIALYSATE_DATA_T ) ); + broadcastData( MSG_ID_DG_FILL_MODE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&fillModeData, sizeof( DG_FILL_MODE_DATA_T ) ); fillModeDataPublicationTimerCounter = 0; } Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -re28e96fba3f2293208e6d91673288acba2514cca -rd502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision e28e96fba3f2293208e6d91673288acba2514cca) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision d502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92) @@ -49,6 +49,8 @@ BOOL isThisTheFirstFill( void ); +BOOL isAvgConductivityOutOfRange( void ); + BOOL testSetUsedAcidVolumeMLOverride( F32 value ); BOOL testSetUsedBicarbVolumeMLOverride( F32 value ); Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r025612ad77fe630889a364586de54bffe5262d56 -rd502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 025612ad77fe630889a364586de54bffe5262d56) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision d502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92) @@ -21,6 +21,7 @@ #include "DrainPump.h" #include "FPGA.h" #include "Heaters.h" +#include "ModeFill.h" #include "ModeGenIdle.h" #include "NVDataMgmt.h" #include "OperationModes.h" @@ -52,14 +53,23 @@ // ********** private data ********** static DG_GEN_IDLE_MODE_STATE_T genIdleState; ///< Currently active generation idle state. +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T badFillState; ///< Current active bad fill state. static F32 flushLinesVolumeL = 0.0; ///< Volume of water pumped by RO pump during flush lines state. static U32 hdLostCommStartTime_ms = 0; ///< Lost communication with HD start time in ms. // ********** private function prototypes ********** +static DG_GEN_IDLE_MODE_STATE_T handleIdleStartState( void ); static DG_GEN_IDLE_MODE_STATE_T handleFlushLinesState( void ); static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ); +static DG_GEN_IDLE_MODE_STATE_T handleBadFillState( void ); // This state has sub-states 1.0 to 1.4 +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFirstDrainState( void ); // idle 1.0 +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFlushFillState( void ); // idle 1.1 +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleSecondDrainState( void ); // idle 1.2 +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( void ); // idle 1.3 +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleClearAlarmState( void ); // idle 1.4 + /*********************************************************************//** * @brief * The initGenIdleMode function initializes the generation idle mode module. @@ -70,6 +80,7 @@ void initGenIdleMode( void ) { genIdleState = DG_GEN_IDLE_MODE_STATE_START; + badFillState = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; flushLinesVolumeL = 0.0; hdLostCommStartTime_ms = 0; } @@ -118,6 +129,35 @@ /*********************************************************************//** * @brief + * The getCurrentGenIdleState function returns the current state of the + * generation idle mode. + * @details Inputs: genIdleState + * @details Outputs: none + * @return the current state of generation idle mode + *************************************************************************/ +DG_GEN_IDLE_MODE_STATE_T getCurrentGenIdleState( void ) +{ + return genIdleState; +} + +/*********************************************************************//** + * @brief + * The requestDGStop function handles an HD request to stop (return to standby mode). + * @details Inputs: none + * @details Outputs: DG standby mode requested + * @return TRUE if request accepted, FALSE if not. + *************************************************************************/ +BOOL requestDGStop( void ) +{ + BOOL result = TRUE; + + requestNewOperationMode( DG_MODE_STAN ); + + return result; +} + +/*********************************************************************//** + * @brief * The execGenIdleMode function executes the generation idle mode state machine. * @details Inputs: genIdleState * @details Outputs: Check water quality, generation idle mode state machine executed @@ -148,7 +188,7 @@ switch ( genIdleState ) { case DG_GEN_IDLE_MODE_STATE_START: - genIdleState = DG_GEN_IDLE_MODE_STATE_FLUSH_LINES; + genIdleState = handleIdleStartState(); break; case DG_GEN_IDLE_MODE_STATE_FLUSH_LINES: @@ -159,6 +199,10 @@ genIdleState = handleFlushWaterState(); break; + case DG_GEN_IDLE_MODE_STATE_HANDLE_BAD_FILL: + genIdleState = handleBadFillState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_GEN_IDLE_MODE_INVALID_EXEC_STATE, genIdleState ) genIdleState = DG_GEN_IDLE_MODE_STATE_START; @@ -170,30 +214,25 @@ /*********************************************************************//** * @brief - * The getCurrentGenIdleState function returns the current state of the - * generation idle mode. - * @details Inputs: genIdleState - * @details Outputs: none - * @return the current state of generation idle mode + * The handleIdleStartState function executes the start state of the + * generation idle mode state machine. + * @details Inputs: flushLinesVolumeL + * @details Outputs: Integrate volume of water moved through line + * @return the next state *************************************************************************/ -DG_GEN_IDLE_MODE_STATE_T getCurrentGenIdleState( void ) +static DG_GEN_IDLE_MODE_STATE_T handleIdleStartState( void ) { - return genIdleState; -} + DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_START; -/*********************************************************************//** - * @brief - * The requestDGStop function handles an HD request to stop (return to standby mode). - * @details Inputs: none - * @details Outputs: DG standby mode requested - * @return TRUE if request accepted, FALSE if not. - *************************************************************************/ -BOOL requestDGStop( void ) -{ - BOOL result = TRUE; + if ( TRUE == isAvgConductivityOutOfRange() ) + { + result = DG_GEN_IDLE_MODE_STATE_HANDLE_BAD_FILL ; + } + else + { + result = DG_GEN_IDLE_MODE_STATE_FLUSH_LINES; + } - requestNewOperationMode( DG_MODE_STAN ); - return result; } @@ -229,14 +268,154 @@ /*********************************************************************//** * @brief * The handleFlushWaterState function executes the flush water state - * of the generation idle mode state machine. + * generation idle mode state machine. * @details Inputs: none * @details Outputs: none * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ) { - return DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; + DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; + + return result; } +/*********************************************************************//** + * @brief + * The handleBadFillState function executes the bad fill state of the + * generation idle mode state machine. + * @details Inputs: + * @details Outputs: + * @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; + + // Execute current bad fill state + switch ( badFillState ) + { + case DG_HANDLE_BAD_FILL_STATE_START: + badFillState = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; + break; + + case DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN: // idle 1.0 + badFillState = handleFirstDrainState(); + break; + + case DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL: // idle 1.1 + badFillState = handleFlushFillState(); + break; + + case DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN: // idle 1.2 + badFillState = handleSecondDrainState(); + break; + + case DG_HANDLE_BAD_FILL_STATE_REFILL: + badFillState = handleRefillState(); // idle 1.3 + break; + + case DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM: + badFillState = handleClearAlarmState(); // idle 1.4 + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_GEN_IDLE_MODE_INVALID_EXEC_STATE, genIdleState ) + badFillState = DG_HANDLE_BAD_FILL_STATE_START; + break; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleFirstDrainState function executes the first drain state of the + * handle bad fill state machine. + * @details Inputs: + * @details Outputs: + * @return the next state + *************************************************************************/ +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFirstDrainState( void ) +{ + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; + + requestNewOperationMode( DG_MODE_DRAI ); // go to drain mode to empty bad dialysate because this is a bad fill + result = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; // after first drain is completed, go to next sub-state + + return result; +} + +/*********************************************************************//** + * @brief + * The handleFlushFillState function executes the flush fill state of the + * handle bad fill state machine. + * @details Inputs: + * @details Outputs: + * @return the next state + *************************************************************************/ +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFlushFillState( void ) +{ + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; + + requestNewOperationMode( DG_MODE_FILL ); // When fill is completed, it goes to generation idle mode (DG_GEN_IDLE_MODE_STATE_START) + result = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; // (idle 1.2) + + return result; +} + +/*********************************************************************//** + * @brief + * The handleSecondDrainState function executes the second drain state of the + * handle bad fill state machine. + * @details Inputs: + * @details Outputs: + * @return the next state + *************************************************************************/ +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleSecondDrainState( void ) +{ + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; + + requestNewOperationMode( DG_MODE_DRAI ); // go to drain mode to empty bad dialysate because this is a bad fill + result = DG_HANDLE_BAD_FILL_STATE_REFILL; // after second drain completed, go to refill sub-state (idle 1.3) + + return result; +} + +/*********************************************************************//** + * @brief + * The handleRefillState function executes refill state of the + * handle bad fill state machine. + * @details Inputs: + * @details Outputs: + * @return the next state + *************************************************************************/ +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( void ) +{ + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_REFILL; + + requestNewOperationMode( DG_MODE_FILL ); + result = DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM; // (idle 1.4) + + return result; +} + +/*********************************************************************//** + * @brief + * The handleClearAlarmState function executes the clear alarm state of the + * handle bad fill state machine. + * @details Inputs: + * @details Outputs: + * @return the next state + *************************************************************************/ +static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleClearAlarmState( void ) +{ + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM; + + // clear "Wait for dialysate alarm" before resume to normal state + requestNewOperationMode( DG_MODE_GENE ); // go to generation idle mode + + return result; +} + /**@}*/ Index: firmware/App/Modes/ModeGenIdle.h =================================================================== diff -u -r025612ad77fe630889a364586de54bffe5262d56 -rd502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92 --- firmware/App/Modes/ModeGenIdle.h (.../ModeGenIdle.h) (revision 025612ad77fe630889a364586de54bffe5262d56) +++ firmware/App/Modes/ModeGenIdle.h (.../ModeGenIdle.h) (revision d502fb7b72c8b3aa4f3a7cdbc4b3c4f7b5ae7c92) @@ -34,12 +34,12 @@ // ********** public function prototypes ********** void initGenIdleMode( void ); // initialize this module -U32 transitionToGenIdleMode( void ); // prepares for transition to generation idle mode +U32 transitionToGenIdleMode( void ); // prepares for transition to generation idle mode U32 execGenIdleMode( void ); // execute the generation idle mode state machine (call from OperationModes) DG_GEN_IDLE_MODE_STATE_T getCurrentGenIdleState( void ); // get the current state of generation idle mode -BOOL requestDGStop( void ); // HD requests DG stop (go back to standby mode) +BOOL requestDGStop( void ); // HD requests DG stop (go back to standby mode) /**@}*/