Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -60,7 +60,6 @@ static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. static BOOL dgStarted = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop. static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. -static BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we have commanded the DG to sample water. // State machine states /// Current state of treatment mode reservoir management. @@ -127,7 +126,6 @@ dgStarted = FALSE; dgTrimmerHeaterOn = FALSE; - dgWaterSampled = FALSE; dgPrimaryTempSet = 0.0; dgTrimmerTempSet = 0.0; dgActiveReservoirSet = DG_RESERVOIR_2; @@ -856,10 +854,9 @@ * @details Outputs: sample water command sent to DG. * @return none *************************************************************************/ -void cmdDGSampleWater( void ) +void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) { - dgWaterSampled = TRUE; - sendDGSampleWaterCommand(); + sendDGSampleWaterCommand( cmd ); } /*********************************************************************//** Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -151,8 +151,8 @@ void cmdStartDGFill( U32 fillToVolMl ); void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell ); void cmdStartDGTrimmerHeater( void ); -void cmdStopDGTrimmerHeater( void ); -void cmdDGSampleWater( void ); +void cmdStopDGTrimmerHeater( void ); +void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ); void handleDGCommandResponse( DG_CMD_RESPONSE_T *dgCmdRespPtr ); BOOL getDGCommandResponse( U32 commandID, DG_CMD_RESPONSE_T *cmdRespPtr ); Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -22,6 +22,7 @@ #include "PreTreatmentRecirc.h" #include "Prime.h" #include "SelfTests.h" +#include "SampleWater.h" #include "SystemCommMessages.h" /** @@ -43,6 +44,7 @@ static void resetSignalFlags( void ); +static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); @@ -61,6 +63,7 @@ { currentPreTreatmentState = HD_PRE_TREATMENT_START_STATE; + initSampleWater(); initPrime(); initSelfTests(); @@ -98,14 +101,12 @@ switch ( currentPreTreatmentState ) { case HD_PRE_TREATMENT_START_STATE: - cmdStartDG(); - cmdSetDGDialysateTargetTemps( 39.0, 37.0 ); + transitionToSampleWater(); currentPreTreatmentState = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; break; case HD_PRE_TREATMENT_WATER_SAMPLE_STATE: - transitionToNoCartSelfTests(); - currentPreTreatmentState = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + currentPreTreatmentState = handleWaterSampleState(); break; case HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE: @@ -219,6 +220,28 @@ /*********************************************************************//** * @brief + * The handleWaterSampleState function handles patient connection state + * during pre-treatment mode. + * @details Inputs: none + * @details Outputs: requested mode transition to treatment mode + * @return current state (sub-mode) + *************************************************************************/ +static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) +{ + HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; + + execSampleWater(); + + if ( TRUE == isSampleWaterPassed() ) + { + state = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleSelfTestNoCartState function handles self-test with no cartridge. * @details Inputs: none * @details Outputs: home blood pump and dialysate pumps Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r72551346728009770b22d327a1ac4fad8b5a1675 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 72551346728009770b22d327a1ac4fad8b5a1675) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -169,6 +169,8 @@ switch ( currentPrimeState ) { case HD_PRIME_START_STATE: + cmdStartDG(); + cmdSetDGDialysateTargetTemps( 39.0, 37.0 ); cmdSetDGActiveReservoir( DG_RESERVOIR_2 ); #ifdef SKIP_PRIMING currentPrimeState = HD_PRIME_RESERVOIR_ONE_FILL_COMPLETE_STATE; Index: firmware/App/Modes/SampleWater.c =================================================================== diff -u --- firmware/App/Modes/SampleWater.c (revision 0) +++ firmware/App/Modes/SampleWater.c (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -0,0 +1,200 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 SampleWater.c +* +* @author (last) Quang Nguyen +* @date (last) 19-Feb-2021 +* +* @author (original) Quang Nguyen +* @date (original) 19-Feb-2021 +* +***************************************************************************/ + +#include "DGInterface.h" +#include "HDDefs.h" +#include "SampleWater.h" +#include "TaskGeneral.h" + +/** + * @addtogroup SampleWater + * @{ + */ + +// ********** private definitions ********** + +#define MAX_FLUSH_TIME_COUNT ( 60 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Maximum flush time count relative to task general interval. + +// ********** private data ********** + +static BOOL sampleWaterStartRequested; +static BOOL sampleWaterStopRequested; +static BOOL sampleWaterTakenConfirm; + +static SAMPLE_WATER_STATE_T currentSampleWaterState; +static U32 flushTimerCounter; +static BOOL sampleWaterPassed; +static BOOL sampleWaterFailed; + +// ********** private function prototypes ********** + +static SAMPLE_WATER_STATE_T handleWaterSampleSetupState( void ); +static SAMPLE_WATER_STATE_T handleWaterSampleState( void ); +static SAMPLE_WATER_STATE_T handleWaterSampleResultState( void ); + +/*********************************************************************//** + * @brief + * The initSampleWater function initializes the Pre-Treatment SampleWater module. + * @details Inputs: none + * @details Outputs: SampleWater module initialized. + * @return none +*************************************************************************/ +void initSampleWater( void ) +{ + sampleWaterStartRequested = FALSE; + sampleWaterStopRequested = FALSE; + sampleWaterTakenConfirm = FALSE; + + currentSampleWaterState = SAMPLE_WATER_SETUP_STATE; + flushTimerCounter = 0; + sampleWaterPassed = FALSE; + sampleWaterFailed = FALSE; +} + +/*********************************************************************//** + * @brief + * The transitionToSampleWater function prepares for transition to sample water mode. + * @details Inputs: none + * @details Outputs: Commanded DG to flush filters and re-initializes SampleWater module + * @return none +*************************************************************************/ +void transitionToSampleWater( void ) +{ + cmdDGSampleWater( SAMPLE_WATER_CMD_FLUSH ); + + initSampleWater(); +} + +/*********************************************************************//** + * @brief + * The execSampleWater function executes the Sample Water state machine. + * @details Inputs: currentSampleWaterState + * @details Outputs: currentSampleWaterState + * @return none +*************************************************************************/ +void execSampleWater( void ) +{ + switch ( currentSampleWaterState ) + { + case SAMPLE_WATER_SETUP_STATE: + currentSampleWaterState = handleWaterSampleSetupState(); + break; + + case SAMPLE_WATER_STATE: + currentSampleWaterState = handleWaterSampleState(); + break; + + case SAMPLE_WATER_RESULT_STATE: + currentSampleWaterState = handleWaterSampleResultState(); + break; + + default: + // TODO: alarm + break; + } +} + +/*********************************************************************//** + * @brief + * The isSampleWaterPassed function returns the result of sample water. + * @details Inputs: sampleWaterPassed + * @details Outputs: none + * @return TRUE if sample water result passed, otherwise FALSE + *************************************************************************/ +BOOL isSampleWaterPassed( void ) +{ + return sampleWaterPassed; +} + +/*********************************************************************//** + * @brief + * The handleWaterSampleSetupState function waits for filter flush period elapsed. + * @details Inputs: flushTimerCounter + * @details Outputs: none + * @return current state +*************************************************************************/ +static SAMPLE_WATER_STATE_T handleWaterSampleSetupState( void ) +{ + SAMPLE_WATER_STATE_T state = SAMPLE_WATER_SETUP_STATE; + + if ( MAX_FLUSH_TIME_COUNT < flushTimerCounter++ ) + { + state = SAMPLE_WATER_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleWaterSampleState function passes sample water commands from user + * down to DG. + * @details Inputs: sampleWaterTakenConfirm, sampleWaterStartRequested, sampleWaterStopRequested + * @details Outputs: Processed commands from user + * @return current state +*************************************************************************/ +static SAMPLE_WATER_STATE_T handleWaterSampleState( void ) +{ + SAMPLE_WATER_STATE_T state = SAMPLE_WATER_STATE; + DG_CMD_RESPONSE_T dgCmdResp; + + if ( TRUE == sampleWaterTakenConfirm ) + { + sampleWaterTakenConfirm = FALSE; + state = SAMPLE_WATER_RESULT_STATE; + } + + if ( TRUE == sampleWaterStartRequested ) + { + sampleWaterStartRequested = FALSE; + cmdDGSampleWater( SAMPLE_WATER_CMD_START ); + } + + if ( TRUE == sampleWaterStopRequested ) + { + sampleWaterStopRequested = FALSE; + cmdDGSampleWater( SAMPLE_WATER_CMD_STOP ); + } + + if ( ( TRUE == getDGCommandResponse( DG_CMD_START_DRAIN, &dgCmdResp ) ) && ( DG_CMD_REQUEST_REJECT_REASON_FLUSH_EXPIRED == dgCmdResp.rejected ) ) + { + cmdDGSampleWater( SAMPLE_WATER_CMD_FLUSH ); + state = SAMPLE_WATER_SETUP_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleWaterSampleResultState function triggers a fault if user + * provides failed sample water result. + * @details Inputs: sampleWaterFailed + * @details Outputs: triggers a fault alarm + * @return current state +*************************************************************************/ +static SAMPLE_WATER_STATE_T handleWaterSampleResultState( void ) +{ + if ( TRUE == sampleWaterFailed ) + { + // TODO: Trigger fault + } + + return SAMPLE_WATER_RESULT_STATE; +} + +/**@}*/ Index: firmware/App/Modes/SampleWater.h =================================================================== diff -u --- firmware/App/Modes/SampleWater.h (revision 0) +++ firmware/App/Modes/SampleWater.h (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -0,0 +1,43 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 SampleWater.h +* +* @author (last) Quang Nguyen +* @date (last) 19-Feb-2021 +* +* @author (original) Quang Nguyen +* @date (original) 19-Feb-2021 +* +***************************************************************************/ + +#ifndef __SAMPLE_WATER_H__ +#define __SAMPLE_WATER_H__ + +#include "HDCommon.h" + +/** + * @defgroup SampleWater SampleWater + * @brief SampleWater sub-mode of pre-treatment mode. This sub-mode allows user to sample water and enter manual test result. + * + * @addtogroup SampleWater + * @{ + */ + +// ********** public definitions ********** + +// ********** public function prototypes ********** + +void initSampleWater( void ); +void transitionToSampleWater( void ); + +void execSampleWater( void ); +BOOL isSampleWaterPassed( void ); + +/**@}*/ + +#endif Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -681,18 +681,21 @@ * The sendDGSampleWaterCommand function constructs a DG sample water command * message and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none - * @details Outputs: DG sample water command msg constructed and queued. + * @details Outputs: DG sample water command msg constructed and queued. + * @param cmd sample water sub-command * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDGSampleWaterCommand( void ) +BOOL sendDGSampleWaterCommand( SAMPLE_WATER_CMD_T cmd ) { BOOL result; MESSAGE_T msg; // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_SAMPLE_WATER_CMD; - msg.hdr.payloadLen = 0; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( msg.payload, &cmd, 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_HD_2_DG, ACK_REQUIRED ); Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r981de1f5228152ec6877aceae3d66ebf5efc7101 -r633861a3e472c1a288fa10a52ec0f7e7153e4dce --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 981de1f5228152ec6877aceae3d66ebf5efc7101) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 633861a3e472c1a288fa10a52ec0f7e7153e4dce) @@ -179,7 +179,7 @@ BOOL sendDGStartStopTrimmerHeaterCommand( BOOL start, F32 trimmerHtrTemp ); // MSG_ID_DG_SAMPLE_WATER_CMD -BOOL sendDGSampleWaterCommand( void ); +BOOL sendDGSampleWaterCommand( SAMPLE_WATER_CMD_T cmd ); // MSG_ID_DG_COMMAND_RESPONSE void handleDGCmdResp( MESSAGE_T *messagePtr );