Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r992975fb3cd56ddd7567b5e27f8bebd9b9948e9d -re0f0e562f964f53ac9b9bd62ff2092c0b12e202b --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 992975fb3cd56ddd7567b5e27f8bebd9b9948e9d) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision e0f0e562f964f53ac9b9bd62ff2092c0b12e202b) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2024 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 ModeDrain.c * * @author (last) Dara Navaei -* @date (last) 16-May-2023 +* @date (last) 23-Oct-2024 * * @author (original) Leonardo Baloa * @date (original) 20-Dec-2019 @@ -20,16 +20,19 @@ #include "CPLD.h" #include "DrainPump.h" #include "Heaters.h" -#include "ModeFill.h" #include "ModeDrain.h" +#include "ModeFill.h" +#include "ModeGenIdle.h" #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" #include "SystemComm.h" +#include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" #include "Timers.h" +#include "Utilities.h" #include "Valves.h" /** @@ -61,34 +64,33 @@ #define CONCENTRATE_BOTTLE_RESERVOIOR_FILLS 3 ///< Concentrate bottle reservoir vlls. #define BICARB_PERCENT_FILL 0.03514F ///< Bicarb volume percentage of reservoir volume. #define ACID_PERCENT_FILL 0.02222F ///< Acid volume percentage of reservoir volume. +#define DATA_PUBLISH_COUNTER_START_COUNT 70 ///< Data publish counter start count. +#define DRAIN_MODE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the drain mode data is published on the CAN bus. +#define MIN_CONCENTRATE_VOLUME_ML 500.0F ///< Minimum concentrate volume in milliliters. -///< Concentrate bottle acid low volume in mL. -static const F32 CONCENTRATE_BOTTLE_ACID_LOW_VOLUME_ML = ( CONCENTRATE_BOTTLE_PRIMING_VOL_ML + - ( CONCENTRATE_BOTTLE_RESERVOIOR_VOL_ML * CONCENTRATE_BOTTLE_RESERVOIOR_FILLS * ACID_PERCENT_FILL) ); - -///< Concentrate bottle bicarb low volume in mL. -static const F32 CONCENTRATE_BOTTLE_BICARB_LOW_VOLUME_ML = ( CONCENTRATE_BOTTLE_PRIMING_VOL_ML + - ( CONCENTRATE_BOTTLE_RESERVOIOR_VOL_ML * CONCENTRATE_BOTTLE_RESERVOIOR_FILLS * BICARB_PERCENT_FILL) ); - // ********** private data ********** static DG_DRAIN_STATE_T drainState; ///< Currently active drain state. static U32 drainEmptyTareTimerCtr; ///< Timer counter for delay between drain complete and load cell tare. static BOOL rinseConcentrateLines; ///< Flag indicates to rinse concentrate lines. static U32 rinseConcentrateLinesTimerCtr; ///< Timer counter for rinsing concentrate lines. static U32 dialysateDrainStartTime; ///< Dialysate drain start time. - +static U32 dataPublishCounter; ///< Used to schedule drain mode data publication to CAN bus. +static OVERRIDE_U32_T drainModeDataPublishInterval = { DRAIN_MODE_DATA_PUB_INTERVAL, + DRAIN_MODE_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish drain mode data to CAN bus. // ********** private function prototypes ********** static DG_DRAIN_STATE_T handleDrainStateStart( void ); static DG_DRAIN_STATE_T handleDrainStateDrain( void ); static DG_DRAIN_STATE_T handleDrainStateTare( void ); static DG_DRAIN_STATE_T handleRinseState( void ); +static void publishDrainModeData( void ); /*********************************************************************//** * @brief * The initDrainMode function initializes the drain mode module. * @details Inputs: none * @details Outputs: drainState, drainEmptyTareTimerCtr, dialysateDrainStartTime, + * dataPublishCounter * rinseConcentrateLinesTimerCtr * @return none *************************************************************************/ @@ -100,6 +102,7 @@ drainEmptyTareTimerCtr = 0; rinseConcentrateLinesTimerCtr = 0; dialysateDrainStartTime = 0; + dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; } /*********************************************************************//** @@ -195,6 +198,8 @@ break; } + publishDrainModeData(); + return drainState; } @@ -296,19 +301,29 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_EMPTY_BOTTLES_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif { + HD_MODE_SUB_MODE_T hdMode; + + getHDOperationMode( &hdMode ); + // Detect empty bottles using integrated volumes - if ( ( acidBottleVolML - getChemicalUsedVolumeML( ACID ) ) <= CONCENTRATE_BOTTLE_ACID_LOW_VOLUME_ML ) // SRSDG 836 + if ( ( ( acidBottleVolML - getChemicalUsedVolumeML( ACID ) ) <= MIN_CONCENTRATE_VOLUME_ML ) && // SRSDG 836 + ( hdMode.hdMode != MODE_POST ) && // don't care about concentrates after treatment complete + ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) { resetChemicalUsedVolumeML( ACID ); - setThisFisrtFillFlag( TRUE ); // indicates bottles need prime + setThisFirstFillFlag( TRUE ); // indicates bottles need prime activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); + activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); } - if ( ( bicarbBottleVolML - getChemicalUsedVolumeML( BICARB ) ) <= CONCENTRATE_BOTTLE_BICARB_LOW_VOLUME_ML ) // SRSDG 837 + if ( ( ( bicarbBottleVolML - getChemicalUsedVolumeML( BICARB ) ) <= MIN_CONCENTRATE_VOLUME_ML ) && // SRSDG 837 + ( hdMode.hdMode != MODE_POST ) && // don't care about concentrates after treatment complete + ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) { resetChemicalUsedVolumeML( BICARB ); - setThisFisrtFillFlag( TRUE ); + setThisFirstFillFlag( TRUE ); activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); + activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); } } @@ -334,7 +349,7 @@ * The handleDrainStateTare function handles the tare state of the drain mode * state machine. * @details Inputs: drainEmptyTareTimerCtr - * @details Outputs: drainEmptyTareTimerCtr + * @details Outputs: drainEmptyTareTimerCtr, rinseConcentrateLines * @return the next state *************************************************************************/ static DG_DRAIN_STATE_T handleDrainStateTare( void ) @@ -368,8 +383,8 @@ * @brief * The handleRinseState function handles the tare state of the drain mode * state machine. - * @details Inputs: drainEmptyTareTimerCtr - * @details Outputs: drainEmptyTareTimerCtr + * @details Inputs: drainEmptyTareTimerCtr, rinseConcentrateLines + * @details Outputs: drainEmptyTareTimerCtr, rinseConcentrateLines * @return the next state *************************************************************************/ static DG_DRAIN_STATE_T handleRinseState( void ) @@ -381,6 +396,7 @@ if ( ++rinseConcentrateLinesTimerCtr > RINSE_CONCENTRATE_LINES_WAIT ) { rinseConcentrateLinesTimerCtr = 0; + rinseConcentrateLines = FALSE; requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); requestNewOperationMode( DG_MODE_GENE ); @@ -394,4 +410,81 @@ return result; } +/*********************************************************************//** + * @brief + * The publishDrainModeData function publishes fill mode data + * at the set interval. + * @details Inputs: dataPublishCounter, drainModeDataPublishInterval + * @details Outputs: drainModeData + * @return none + *************************************************************************/ +static void publishDrainModeData( void ) +{ + // publish Drain mode data on interval + if ( ++dataPublishCounter >= getU32OverrideValue( &drainModeDataPublishInterval ) ) + { + DG_DRAIN_MODE_DATA_T drainModeData; + + drainModeData.drainModeState = drainState; + drainModeData.badFillSignal = getCurrentBadFillSignal(); + drainModeData.badFillState = getCurrentGenIdleBadFillState(); + + broadcastData( MSG_ID_DG_DRAIN_MODE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&drainModeData, sizeof( DG_DRAIN_MODE_DATA_T ) ); + // Populate the data structure for publication + dataPublishCounter = 0; + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetDrainModeDataPublishIntervalOverride function overrides the + * drain mode data publish interval. + * @details Inputs: drainModeDataPublishInterval + * @details Outputs: drainModeDataPublishInterval + * @param value override drain mode data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDrainModeDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_GENERAL_INTERVAL; + drainModeDataPublishInterval.ovData = intvl; + drainModeDataPublishInterval.override = OVERRIDE_KEY; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetDrainModeDataPublishIntervalOverride function resets the + * override of the drain mode data publish interval. + * @details Inputs: drainModeDataPublishInterval + * @details Outputs: drainModeDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDrainModeDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + drainModeDataPublishInterval.override = OVERRIDE_RESET; + drainModeDataPublishInterval.ovData = drainModeDataPublishInterval.ovInitData; + result = TRUE; + } + + return result; +} + /**@}*/