Index: firmware/App/Modes/ModeHeatDisinfectActiveCool.c =================================================================== diff -u -r2e56064726838bfb626ec3ea40132c4e3681639a -rd731f3fda9d25e0d63100f648510e9c8cdd21f89 --- firmware/App/Modes/ModeHeatDisinfectActiveCool.c (.../ModeHeatDisinfectActiveCool.c) (revision 2e56064726838bfb626ec3ea40132c4e3681639a) +++ firmware/App/Modes/ModeHeatDisinfectActiveCool.c (.../ModeHeatDisinfectActiveCool.c) (revision d731f3fda9d25e0d63100f648510e9c8cdd21f89) @@ -26,6 +26,7 @@ #include "OperationModes.h" #include "Reservoirs.h" #include "ROPump.h" +#include "RTC.h" #include "Switches.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" @@ -63,7 +64,7 @@ #define ROF_ACTIVE_COOL_BELOW_TEMP_TIMEOUT_MS ( 30 * MS_PER_SECOND ) #define ROF_ACTIVE_COOL_TARGET_DARIN_RPM 600 #define ROF_ACTIVE_COOL_MIX_DRAIN_VALVE_ON_TIMEOUT_MS ( 5 * MS_PER_SECOND ) -#define ROF_ACTIVE_COOL_RSRVR_MIX_DRAIN_TIMEOUT_MS ( 2.5 * SEC_PER_MIN * MS_PER_SECOND ) +#define ROF_ACTIVE_COOL_RSRVR_MIX_DRAIN_TIMEOUT_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) #define ROF_ACTIVE_COOL_MIX_DRAIN_STEADY_TIMEOUT_MS ( 15 * MS_PER_SECOND ) // Reservoir cool down defines @@ -74,15 +75,21 @@ #define RSRVR_ACTIVE_COOL_BELOW_TARGET_TEMP_TIMEOUT_MS ( 15 * MS_PER_SECOND ) #define RSRVR_ACTIVE_COOL_TARGET_TEMP_TIMEOUT_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) +/// Non-volatile write structure +typedef struct +{ + BOOL hasDisStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect status been written to NV or not. +} DISINFECT_NV_OPS_T; + static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T heatDisinfectActiveCoolState; ///< Mode heat disinfect active cool state. static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T heatDisinfectActiceCoolPrevState; ///< Mode heat disinfect active cool previous state. static U32 stateStartTimeMS; ///< Mode heat disinfect active cool state timer in milliseconds. static U32 dataPublishCounter; ///< Mode heat disinfect active cool data publish counter. static U32 overallHeatDisinfectActiveCoolTimer; ///< Mode heat disinfect active cool over mode timer. -static U32 ROFCoolingTimer; // TODO remove ///< Mode heat disinfect active cool RO filter cooling timer. static ALARM_ID_T alarmDetectedPendingTrigger; ///< Mode heat disinfect active cool pending alarm trigger. static DIS_RSRVR_STATUS_T rsrvrsStatus; ///< Mode heat disinfect active cool reservoirs status. static U32 tempBelowTargetStartTimeMS; ///< Mode heat disinfect active cool temperature below target time in milliseconds. +static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. static CANCELLATION_MODE_T cancellationMode; ///< Cancellation mode. // ********** private function prototypes ********** @@ -96,7 +103,6 @@ static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1FillR2ToR1State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR1State( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolDrainR2State( void ); -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCoolDownROFilterState( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCompleteState( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCancelWaterPathState( void ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCancelBasicPathState( void ); @@ -105,6 +111,7 @@ static void publishHeatDisinfectActiveCoolData( void ); static void monitorModeHeatDisinfectActiveCool( void ); static void setHeatDisinfectActiveCoolActuators( DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeoutStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrPartialFillStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMixDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ); @@ -119,20 +126,20 @@ * @details Outputs: heatDisinfectActiveCoolState, stateStartTimeMS, * dataPublishCounter, overallHeatDisinfectActiveCoolTimer, * alarmDetectedPendingTrigger, heatDisinfectActiceCoolPrevState, rsrvrsStatus, - * tempBelowTargetStartTimeMS + * tempBelowTargetStartTimeMS, disinfectNVOps * @return none *************************************************************************/ void initHeatDisinfectActiveCoolMode( void ) { - heatDisinfectActiveCoolState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; - heatDisinfectActiceCoolPrevState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; - stateStartTimeMS = getMSTimerCount(); - dataPublishCounter = 0; - overallHeatDisinfectActiveCoolTimer = getMSTimerCount(); - ROFCoolingTimer = 0; - alarmDetectedPendingTrigger = ALARM_ID_NO_ALARM; - tempBelowTargetStartTimeMS = getMSTimerCount(); - cancellationMode = CANCELLATION_MODE_NONE; + heatDisinfectActiveCoolState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; + heatDisinfectActiceCoolPrevState = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_START; + stateStartTimeMS = getMSTimerCount(); + dataPublishCounter = 0; + overallHeatDisinfectActiveCoolTimer = getMSTimerCount(); + alarmDetectedPendingTrigger = ALARM_ID_NO_ALARM; + tempBelowTargetStartTimeMS = getMSTimerCount(); + cancellationMode = CANCELLATION_MODE_NONE; + disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; // Initialize the reservoirs rsrvrsStatus.rsrvrFillStableTime = 0; @@ -220,10 +227,6 @@ heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolDrainR2State(); break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COOL_DOWN_RO_FILTER: - heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolCoolDownROFilterState(); - break; - case DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE: heatDisinfectActiveCoolState = handleHeatDisinfectActiveCoolCancelWaterPathState(); break; @@ -288,6 +291,21 @@ return status; } +/*********************************************************************//** + * @brief + * The getDisinfectRsrvrFillStatus function gets the disinfect reservoir + * fill status. + * @details Inputs: none + * @details Outputs: none + * @param rsrvrID the reservoir to check + * @param *rsrvrStatus pointer to the reservoir status structure + * @param targetVolML the fill target for the reservoir in milliliters + * @param fillTimeoutMS the timeout in milliseconds that the reservoir should + * be filled by then + * @param stateTimerMS the time of the state that the reservoir fill is being + * requested + * @return status of the reservoir fill + *************************************************************************/ DG_RESERVOIR_STATUS_T getDisinfectRsrvrFillStatus( DG_RESERVOIR_ID_T rsrvrID, DIS_RSRVR_STATUS_T *rsrvrStatus, F32 targetVolML, U32 fillTimeoutMS, U32 stateTimerMS ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_BELOW_TARGET; @@ -361,8 +379,6 @@ { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE; - setHeatDisinfectActiveCoolActuators( state ); - stateStartTimeMS = getMSTimerCount(); rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; @@ -446,62 +462,6 @@ /*********************************************************************//** * @brief - * The handleHeatDisinfectActiveCoolCoolDownROFilterState function handles - * the heat disinfect active cool cool down RO filter state. The state - * monitors the temperature at THd and if it is less than 45 C, it transitions - * to the next state. - * @details Inputs: stateTimer, ROFCoolingTimer - * @details Outputs: stateTimer, ROFcoolingTimer, heatDisinfectUIState, - * heatDisinfectActiceCoolPrevState, heatDisinfectActiceCoolPrevState - * @return next state of the heat disinfect active cool state machine - *************************************************************************/ -static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T handleHeatDisinfectActiveCoolCoolDownROFilterState( void ) -{ - DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COOL_DOWN_RO_FILTER; - - // THd is the closet sensor to the RO filter and this temperature is monitored - // until it is dropped below 45 C to be able to run fluid through the RO filter - F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); - - if ( ( 0 == ROFCoolingTimer ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) - { - // Temperature is below target - perform mandatory cool down - ROFCoolingTimer = getMSTimerCount(); - } - else if ( THdTemp >= TARGET_THD_SENSOR_FOR_RINSING_C ) - { - // Temperature is not below target - reset the timer and keep looking - ROFCoolingTimer = 0; - } - - if ( ( ROFCoolingTimer != 0 ) && ( TRUE == didTimeout( ROFCoolingTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) - { - // Temperature is below target, transition to next state - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VBF, VALVE_STATE_CLOSED ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - signalROPumpHardStop(); - - stateStartTimeMS = getMSTimerCount(); - state = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COMPLETE; - } - else if ( ( TRUE == didTimeout( stateStartTimeMS, ROF_COOL_DOWN_MAX_TIME_MS ) ) ) - { - heatDisinfectActiceCoolPrevState = state; - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_ACTIVE_COOL_TIME_OUT; - state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE; - } - - return state; -} - -/*********************************************************************//** - * @brief * The handleHeatDisinfectActiveCoolCompleteState function handles the * heat disinfect active cool complete state. * @details Inputs: none @@ -512,8 +472,13 @@ { DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state = DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_COMPLETE; - stopDGHeatDisinfectActiveCool(); + writeDisinfectDataToNV( USAGE_INFO_HEAT_DIS_ACTIVE_COOL ); + if ( TRUE == disinfectNVOps.hasDisStatusBeenWrittenToNV ) + { + stopDGHeatDisinfectActiveCool(); + } + return state; } @@ -574,7 +539,6 @@ setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); signalDrainPumpHardStop(); - state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_BASIC_PATH_STATE; } @@ -933,6 +897,24 @@ } } +/*********************************************************************//** + * @brief + * The writeDisinfectDataToNV function writes the disinfection data to the + * non-volatile memory. + * @details Inputs: disinfectNVOps + * @details Outputs: disinfectNVOps + * @param info the type disinfect data to write to the memory (i.e. heat + * disinfect start time) + * @return: none + *************************************************************************/ +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) +{ + if ( FALSE == disinfectNVOps.hasDisStatusBeenWrittenToNV ) + { + disinfectNVOps.hasDisStatusBeenWrittenToNV = setLastDisinfectDate( info, getRTCTimestamp() ); + } +} + static DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T checkRsrvrMgmtTimeoutStatus( DG_RESERVOIR_ID_T rsrvrID, DG_HEAT_DISINFECT_ACTIVE_COOL_STATE_T state ) { if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) @@ -967,11 +949,15 @@ if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE == state ) { - state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_BELOW_TARGET; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; } else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R2_STATE == state ) { - state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_BELOW_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; } setHeatDisinfectActiveCoolActuators( state ); } @@ -1016,15 +1002,20 @@ { if ( DG_HEAT_DISINFECT_ACITVE_COOL_MIX_DRAIN_R1_STATE == state ) { + tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); deenergizeActuators( NO_PARK_CONC_PUMPS ); rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_ABOVE_TARGET; state = DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE; } else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_MIX_DRAIN_R2_STATE == state ) { + tareLoadCell( LOAD_CELL_RESERVOIR_2_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_2_BACKUP ); rsrvrsStatus.rsrvr[ switchRsrvrID ].rStatus = DG_RESERVOIR_BELOW_TARGET; rsrvrsStatus.isThisInitialDrain = FALSE; state = DG_HEAT_DISINFECT_ACTIVE_COOL_FILL_R1_STATE; + setHeatDisinfectActiveCoolActuators( state ); } } else @@ -1066,24 +1057,29 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvrsStatus.rsrvr[ rsrvrID ].rStatus ) { - if ( TRUE == didTimeout( tempBelowTargetStartTimeMS, RSRVR_ACTIVE_COOL_BELOW_TARGET_TEMP_TIMEOUT_MS ) ) - { - stateStartTimeMS = getMSTimerCount(); + stateStartTimeMS = getMSTimerCount(); - if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE == state ) + if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE == state ) + { + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_REACHED_TARGET; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_BELOW_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + } + else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE == state ) + { + if ( TRUE == didTimeout( tempBelowTargetStartTimeMS, RSRVR_ACTIVE_COOL_BELOW_TARGET_TEMP_TIMEOUT_MS ) ) { - state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_ABOVE_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE; } - else if ( DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_FILL_R2_TO_R1_STATE == state ) + else { - state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_1 ].rStatus = DG_RESERVOIR_REACHED_TARGET; + rsrvrsStatus.rsrvr[ DG_RESERVOIR_2 ].rStatus = DG_RESERVOIR_BELOW_TARGET; + state = DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R2_FILL_R1_TO_R2_STATE; } - setHeatDisinfectActiveCoolActuators( state ); } - else if ( TRUE == didTimeout( stateStartTimeMS, DG_HEAT_DISINFECT_ACTIVE_COOL_DRAIN_R1_STATE ) ) - { - state = DG_HEAT_DISINFECT_ACTIVE_COOL_CANCEL_WATER_PATH_STATE; - } + setHeatDisinfectActiveCoolActuators( state ); } state = checkRsrvrMgmtTimeoutStatus( rsrvrID, state ); Index: firmware/App/Modes/ModeHeatDisinfectActiveCool.h =================================================================== diff -u -r2e56064726838bfb626ec3ea40132c4e3681639a -rd731f3fda9d25e0d63100f648510e9c8cdd21f89 --- firmware/App/Modes/ModeHeatDisinfectActiveCool.h (.../ModeHeatDisinfectActiveCool.h) (revision 2e56064726838bfb626ec3ea40132c4e3681639a) +++ firmware/App/Modes/ModeHeatDisinfectActiveCool.h (.../ModeHeatDisinfectActiveCool.h) (revision d731f3fda9d25e0d63100f648510e9c8cdd21f89) @@ -70,6 +70,7 @@ BOOL stopDGHeatDisinfectActiveCool( void ); // Stop DG heat disinfect +// Public functions for fill and drain. These functions should be used for filling and draining in other disinfect modes in the future DG_RESERVOIR_STATUS_T getDisinfectRsrvrFillStatus( DG_RESERVOIR_ID_T rsrvrID, DIS_RSRVR_STATUS_T *rsrvrStatus, F32 targetVolML, U32 fillTimeoutMS, U32 stateTimerMS ); DG_RESERVOIR_STATUS_T getDisinfectRsrvrDrainStatus( DG_RESERVOIR_ID_T rsrvrID, DIS_RSRVR_STATUS_T *rsrvrStatus, U32 drainSteadyTimeoutMS, U32 drainStateTimeoutMS, U32 stateTimerMS ); Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r56ba1b163b0cbf6953638065b2108f745b17ec8f -rd731f3fda9d25e0d63100f648510e9c8cdd21f89 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 56ba1b163b0cbf6953638065b2108f745b17ec8f) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision d731f3fda9d25e0d63100f648510e9c8cdd21f89) @@ -558,14 +558,14 @@ { DG_CMD_RESPONSE_T cmdResponse; DG_USAGE_INFO_RECORD_T usageInfo; + OPN_CLS_STATE_T concCap = getSwitchStatus( CONCENTRATE_CAP ); + OPN_CLS_STATE_T diaCap = getSwitchStatus( DIALYSATE_CAP ); getNVRecord2Driver( GET_USAGE_RECORD, (U08*)&usageInfo, sizeof( DG_USAGE_INFO_RECORD_T ), 0, ALARM_ID_NO_ALARM ); - cmdResponse.commandID = DG_CMD_START_HEAT_DISINFECT; - cmdResponse.rejected = FALSE; - cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - OPN_CLS_STATE_T concCap = getSwitchStatus( CONCENTRATE_CAP ); - OPN_CLS_STATE_T diaCap = getSwitchStatus( DIALYSATE_CAP ); + cmdResponse.commandID = DG_CMD_START_HEAT_DISINFECT; + cmdResponse.rejected = FALSE; + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) ) @@ -621,7 +621,7 @@ cmdResponse.commandID = DG_CMD_START_CHEM_DISINFECT; cmdResponse.rejected = FALSE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - OPN_CLS_STATE_T diaCap = getSwitchStatus( DIALYSATE_CAP ); + OPN_CLS_STATE_T diaCap = getSwitchStatus( DIALYSATE_CAP ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) ) @@ -668,20 +668,22 @@ // Chemical disinfect flush cannot be run in solo mode because the user has to confirm that the acid is inserted or removed if ( ( DG_MODE_STAN == getCurrentOperationMode() ) && ( DG_STANDBY_MODE_STATE_IDLE == standbyState ) ) { + OPN_CLS_STATE_T concCap = getSwitchStatus( CONCENTRATE_CAP ); OPN_CLS_STATE_T diaCap = getSwitchStatus( DIALYSATE_CAP ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) ) { + concCap = STATE_CLOSED; diaCap = STATE_CLOSED; } #endif - // When chemical disinfect flush is about to be started, dialysate cap must be closed - if ( STATE_OPEN == diaCap ) + if ( ( STATE_OPEN == concCap ) || ( STATE_OPEN == diaCap ) ) { cmdResponse.rejected = TRUE; - cmdResponse.rejectCode = REQUEST_REJECT_REASON_DG_DIALYSATE_CAP_OPEN; + cmdResponse.rejectCode = ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ? REQUEST_REJECT_REASON_DG_DIALYSATE_CAP_OPEN : + REQUEST_REJECT_REASON_DG_CONCENTRATE_CAP_OPEN ); } else { Index: firmware/App/Modes/ModeStandby.h =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -rd731f3fda9d25e0d63100f648510e9c8cdd21f89 --- firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision d731f3fda9d25e0d63100f648510e9c8cdd21f89) @@ -48,7 +48,6 @@ BOOL requestDGStart( void ); // HD requests DG start (go to generation idle mode) BOOL startDGFlush( void ); // HD start flush mode - BOOL startDGHeatDisinfect( void ); // HD start heat disinfect mode BOOL startDGHeatDisinfectActiveCool( void ); DG_STANDBY_MODE_STATE_T getCurrentStandbyState( void ); // get the current state of the standby mode. Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r2e56064726838bfb626ec3ea40132c4e3681639a -rd731f3fda9d25e0d63100f648510e9c8cdd21f89 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 2e56064726838bfb626ec3ea40132c4e3681639a) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d731f3fda9d25e0d63100f648510e9c8cdd21f89) @@ -674,7 +674,7 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SEND_SYSTEM_RECORD; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); @@ -685,7 +685,7 @@ memcpy( payloadPtr, &length, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, sysRcrdAddress, length ); + memcpy( payloadPtr, sysRcrdAddress, sizeof( U32 ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); @@ -713,7 +713,7 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SEND_SERVICE_RECORD; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); @@ -724,7 +724,7 @@ memcpy( payloadPtr, &length, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, srvcRcrdAddress, length ); + memcpy( payloadPtr, srvcRcrdAddress, sizeof( U32 ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED );