Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r6419179374edcd65da462de84e8aeaefb7e20320 -r78cee9347b3766ac7c14d413ed848be758c7e9cd --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 6419179374edcd65da462de84e8aeaefb7e20320) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 78cee9347b3766ac7c14d413ed848be758c7e9cd) @@ -16,13 +16,15 @@ ***************************************************************************/ #include "DialInFlow.h" +#include "Dialysis.h" #include "DGDefs.h" +#include "DGInterface.h" #include "ModeInitPOST.h" -#include "ModeTreatment.h" +#include "ModeTreatment.h" +#include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "Timers.h" -#include "DGInterface.h" /** * @addtogroup DGInterface @@ -36,6 +38,8 @@ #define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). +#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. + #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. /// States of the treatment reservoir management state machine. @@ -100,6 +104,7 @@ static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. static U32 resUseTimer = 0; ///< Used to track time pumping from active reservoir (for volume used calculation). static F32 resUseVolumeMl = 0.0; ///< Accumulated volume used from active reservoir. +static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. // DG command response static DG_CMD_RESPONSE_T dgCmdResp[ NUM_OF_DG_COMMANDS ]; ///< Keep the latest DG command response for each command. @@ -226,6 +231,19 @@ } resUseTimer = getMSTimerCount(); + // Alarm if active reservoir is full and inactive reservoir is not yet ready + if ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) + { + if ( currentTrtResMgmtState < TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH, getReservoirWeight( getDGActiveReservoir() ), (F32)currentTrtResMgmtState ) + } + else + { + clearAlarmCondition( ALARM_ID_HD_RESERVOIR_FULL_AND_DG_NOT_READY_TO_SWITCH ); + } + } + // Treatment reservoir mgmt. state machine switch ( currentTrtResMgmtState ) { @@ -265,8 +283,14 @@ if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) - { - cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML ); + { + U32 fillToVolume = FILL_RESERVOIR_TO_VOLUME_ML; + + if ( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) <= SLOW_DIALYSATE_FLOW_ML_MIN ) + { + fillToVolume = FILL_RESERVOIR_TO_VOLUME_LOW_FLOW_ML; + } + cmdStartDGFill( fillToVolume ); } } else @@ -297,9 +321,8 @@ case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE: // Reservoir switch during treatment should only occur in this state (i.e. when DG is ready). - // Switch reservoirs when active reservoir is spent (i.e. we have pumped fill volume through dialyzer) and DG ready - if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) && - ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) ) + // Switch reservoirs when active reservoir is spent or full (i.e. we have pumped fill volume through dialyzer) and DG ready + if ( ( resUseVolumeMl >= (F32)dgReservoirFillVolumeTargetSet ) || ( getReservoirWeight( getDGActiveReservoir() ) > MAX_RESERVOIR_VOLUME_ML ) ) { DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); @@ -491,7 +514,7 @@ } else { - activateAlarmNoData( ALARM_ID_HD_SOFTWARE_FAULT ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_LOAD_CELL_ID, loadCellID ); } return result; @@ -518,6 +541,34 @@ return result; } +/*********************************************************************//** + * @brief + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @return the current DG disinfects readings + *************************************************************************/ +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +{ + return disinfectsStatus; +} + +/*********************************************************************//** + * The getReservoirWeight function gets the load cell weight of a given + * reservoir. + * @details Inputs: loadCellWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get weight for + * @return the current weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ) +{ + LOAD_CELL_ID_T lc = ( DG_RESERVOIR_1 == resID ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); + F32 wt = getLoadCellWeight( lc ); + + return wt; +} + /*********************************************************************//** * @brief * The setDGOpMode function sets the latest DG operating mode reported by @@ -537,7 +588,7 @@ } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); } } @@ -593,8 +644,8 @@ dgReservoirDrainVolumeTarget = drainVol; } else - { - // TODO - s/w fault + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); } } @@ -670,7 +721,7 @@ loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_BACKUP ].data = res2Backup; - // feed new weight samples into filters and update moving averages + // Feed new weight samples into filters and update moving averages for ( res = DG_RESERVOIR_1; res < NUM_OF_DG_RESERVOIRS; res++ ) { F32 wt = ( res == DG_RESERVOIR_1 ? res1Primary : res2Primary ); @@ -680,8 +731,25 @@ lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; } lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); + + // Update Dialysis sub-mode with new reservoir volumes + updateReservoirVolumes( res1Primary, res2Primary ); } +/*********************************************************************//** + * @brief + * The setDGDisinfectsStates function sets the latest disinfects states + * from DG. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @param states latest DG disinfects state readings + * @return none + *************************************************************************/ +void setDGDisinfectsStates( DG_DISINFECT_UI_STATES_T states ) +{ + memcpy( &disinfectsStatus, &states, sizeof(DG_DISINFECT_UI_STATES_T) ); +} + /*********************************************************************//** * @brief * The cmdSetDGDialysateTargetTemps function sends a target dialysate @@ -709,7 +777,8 @@ *************************************************************************/ void cmdStartDG( void ) { - dgStartCommandSent = TRUE; + dgStartCommandSent = TRUE; + sendDGStartStopCommand( START_DG_CMD ); } @@ -723,7 +792,8 @@ *************************************************************************/ void cmdStopDG( void ) { - dgStarted = FALSE; + dgStarted = FALSE; + sendDGStartStopCommand( STOP_DG_CMD ); } @@ -738,7 +808,8 @@ void cmdStartDGTrimmerHeater( void ) { dgTrimmerHeaterOn = TRUE; - dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + sendDGStartStopTrimmerHeaterCommand( START_DG_CMD, dgTrimmerTempSet ); } @@ -754,6 +825,7 @@ { dgTrimmerHeaterOn = FALSE; dgCmdResp[ DG_CMD_STOP_TRIMMER_HEATER ].commandID = DG_CMD_NONE; + sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD, 0 ); } @@ -771,7 +843,8 @@ if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoirSet = resID; - dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; + dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; + sendDGSwitchReservoirCommand( (U32)resID ); } else @@ -794,6 +867,7 @@ if ( valveSettingID < NUM_OF_DG_VALVE_SETTTINGS ) { dgCmdResp[ DG_CMD_VALVE_SETTING ].commandID = DG_CMD_NONE; + sendDGChangeValveSettingCommand( (U32)valveSettingID ); } else @@ -813,7 +887,8 @@ void cmdStartDGFill( U32 fillToVolMl ) { dgCmdResp[ DG_CMD_START_FILL ].commandID = DG_CMD_NONE; - dgReservoirFillVolumeTargetSet = fillToVolMl; + dgReservoirFillVolumeTargetSet = fillToVolMl; + sendDGFillCommand( DG_CMD_START, fillToVolMl ); } @@ -828,6 +903,7 @@ { dgCmdResp[ DG_CMD_STOP_FILL ].commandID = DG_CMD_NONE; dgReservoirFillVolumeTargetSet = 0; + sendDGFillCommand( DG_CMD_STOP, 0 ); } @@ -847,7 +923,8 @@ dgCmdResp[ DG_CMD_START_DRAIN ].commandID = DG_CMD_NONE; payload.drainToVolumeML = drainToVolMl; payload.tareLoadCells = tareLoadCell; - dgReservoirDrainVolumeTargetSet = drainToVolMl; + dgReservoirDrainVolumeTargetSet = drainToVolMl; + sendDGDrainCommand( &payload ); } @@ -861,10 +938,106 @@ void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) { sendDGSampleWaterCommand( cmd ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGFlush function sends a start flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: start flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGFlush( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_FLUSH ].commandID = DG_CMD_NONE; + + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGFlush function sends a stop flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: stop flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGFlush( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_FLUSH ].commandID = DG_CMD_NONE; + + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGHeatDisinfect function sends a start heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGHeatDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGHeatDisinfect function sends a stop heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGHeatDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGChemicalDisinfect function sends a start chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGChemicalDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartChemicalDisinfectModeCommand( start ); } /*********************************************************************//** * @brief + * The cmdStopDGChemicalDisinfect function sends a stop chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGChemicalDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + + sendDGStartChemicalDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief * The handleDGCommandResponse function processes the latest DG command response. * @details Inputs: none * @details Outputs: process command response from DG