/************************************************************************** * * Copyright (c) 2025-2026 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 DryBiCart.c * * @author (last) Sameer Kalliadan Poyil * @date (last) 06-Feb-2026 * * @author (original) Vinayakam Mani * @date (original) 19-Nov-2025 * ***************************************************************************/ #include "BalancingChamber.h" #include "Common.h" #include "ConcentratePumps.h" #include "Conductivity.h" #include "DialysatePumps.h" #include "DDDefs.h" #include "DryBiCart.h" #include "Level.h" #include "Messaging.h" #include "ModeGenDialysate.h" #include "OperationModes.h" #include "PIControllers.h" #include "PressureSensor.h" #include "PersistentAlarm.h" #include "Pressure.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup DryBiCart * @{ */ // ********** private definitions ********** #define DRY_BICART_DATA_PUBLISH_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the balancing chamber data published. // Dry Bicart Fill #define DRY_BICART_FILL_DURATION_MIN_MS (2 * MS_PER_SECOND) ///< Minimum fill duration to be met to end the fill cycle. #define DRY_BICART_FILL_COMPLETE_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to reset the request flag after fill complete #define DRY_BICART_FILL_DURATION_DIFF_MS 750 ///< Fill duration difference between last and current fill cycle. #define DRY_BICART_FILL_COMPLETE_PRESSURE 15.0F ///< Maximum pressure reached to indicate the dry bicart fill being completed. #define DRY_BICART_FILL_INITIATE_PRESSURE 7.5F ///< Minimum pressure required to initiate the dry bicart fill process. #define DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT 10 ///< Default max fill cycle allowed for dry bicart fill/mix with water. #define DRY_BICART_MAX_FILL_CYCLE_CNT 30 ///< Max fill cycle allowed (by override) for dry bicart fill/mix with water. // Dry Bicart Fill Vent #define DRY_BICART_FILL_VENT_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to vent dry bicart gas before actuating Bicarb chamber(F) venting. #define DRY_BICART_FILL_VENT_MAX_TIME_MS ( 10 * MS_PER_SECOND ) ///< Max time to vent both dry bicart and Chamber F. #define DRY_BICART_FILL_VENT_COMPLETE_PRESSURE 1.5F ///< Pressure reached to indicate the dry bicart venting being completed. // Bicarb chamber fill/Supply #define DRY_BICART_SUPPLY_VALVE_D80_OPEN_TIME_MS ( 1 * MS_PER_SECOND ) ///< Max time allowed for supply (opening D80 valve) during bicarb chamber (F) fill. #define DRY_BICART_SUPPLY_VENT_TIME_MS ( 1 * MS_PER_SECOND ) ///< Wait time to vent dry bicart gas before actuating Bicarb chamber(F) venting. #define DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ( 3 * MS_PER_SECOND ) ///< Max time to vent both dry bicart and Chamber F. // Dry Bicart Drain #define LARGE_DRY_BICART_MAX_DRAIN_TIME_MS ( 8 * SEC_PER_MIN * MS_PER_SECOND ) ///< Max drain time for large dry bicart in ms. #define SMALL_DRY_BICART_MAX_DRAIN_TIME_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) ///< Max drain time for small dry bicart in ms. #define DRY_BICART_DRAIN_FLUID_PHASE_TIME_MS ( 3 * MS_PER_SECOND ) ///< Time to stay in fluid drain per cycle #define DRY_BICART_DRAIN_VENT_PHASE_TIME_MS ( 8 * MS_PER_SECOND ) ///< Time to keep D64 open per vent cycle #define DRY_BICART_DRAIN_COND_SAMPLE_PERIOD_MS 500 ///< Conductivity sample period #define DRY_BICART_DRAIN_COND_ZERO_THRESH 0.05F ///< Zero conductivity threshold #define DRY_BICART_DRAIN_COND_STABLE_SAMPLES 10U ///< Debounce samples (10*50ms=500ms) // drybicarb mixing #define DEFAULT_ACID_VOLUME_ML 0.67F ///< Acid concentrate volume in ml. #define DEFAULT_BICARB_VOLUME_ML 1.15F ///< Bicarb concentrate volume in ml. #define KP_SCALE_FACTOR 1 #define KI_SCALE_FACTOR 1 #define BICARB_VOL_CONTROL_P_COEFFICIENT ( 0.0002121 / KP_SCALE_FACTOR )//0.000065F ///< Propotional gain (kp) #define BICARB_VOL_CONTROL_I_COEFFICIENT ( 0.0001121 * KI_SCALE_FACTOR )//0.00022F ///< Integral gain. (ki) #define MIN_BICARB_VOLUME_MLPM 0.0004242 ///< Minimum target bicarb in mL/min. #define MAX_BICARB_VOLUME_MLPM 2.0 ///< Maximum target bicarb volume in mL/min. #define ACID_VOL_CONTROL_P_COEFFICIENT 0.0002121//0.000065F ///< Propotional gain (kp) #define ACID_VOL_CONTROL_I_COEFFICIENT 0.0001121//0.00022F ///< Integral gain. (ki) #define MIN_ACID_VOLUME_MLPM 0.0004242 // 0.2 ///< Minimum target acid volume in mL/min. #define MAX_ACID_VOLUME_MLPM 1.85 ///< Maximum target acid volume in mL/min. #define STD_BICARB_DOSING 1.146666667F ///< Standard bicarb dosing volume #define STD_ACID_DOSING 0.666666667F ///< Standard acid dosing volume #define DRY_BICARB_TARGET_CONDUCTIVITY 2714.0F ///< Target bicarb conductivity #define DRY_BICARB_DELTA_CONDUCTIVITY 50.0F ///< Delta bicarb conductivity #define DRY_ACID_BICARB_TARGET_CONDUCTIVITY 13734.87F ///< Target acid bicarb mix conductivity #define DRY_ACID_BICARB_DELTA_CONDUCTIVITY 100.0F ///< Delta acid bicarb mix conductivity #define ACID_TYPE_1K_2_5_CA 11192.55F ///< standard acid conductivity for 1K #define ACID_TYPE_2K_2_5_CA 11313.62F ///< standard acid conductivity for 2K #define ACID_TYPE_3K_2_5_CA 11435.68F ///< standard acid conductivity for 3K #define MIN_BICARB_CONDUCTIVITY 2000 ///< Minimum Bicarb conductivity limit #define MAX_BICARB_CONDUCTIVITY 4000 ///< Maximum Bicarb conductivity limit #define DOSING_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump control #define DOSE_CONTROL_INTERVAL_MS 3000 ///< Dialysate dosing control interval in ms #define DOSE_CONTROL_INTERVAL ( DOSE_CONTROL_INTERVAL_MS /\ TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate dose is controlled. /// Payload record structure for dry bicart fill request typedef struct { U32 startStop; ///< Dry bicart fill request start:1 and stop: 0 } DRY_BICART_FILL_START_CMD_PAYLOAD_T; /// Enumeration of dry bicart top level state machine operation typedef enum DryBicart_StateMachines { DRY_BICART_IDLE = 0, ///< Dry bicart Idle DRY_BICART_INITIAL_FILL, ///< Dry bicart initial fill DRY_BICART_SUPPLY, ///< Dry bicart chamber fill DRY_BICART_DRAIN, ///< Dry bicart drain NUM_OF_DRY_BICART_OPERATION ///< Number of dry bicart operation } DRY_BICART_OPERATION_T; /// Enumeration of dialysate Dosing. typedef enum DialysateDosing { BICARB_DOSE = 0, ///< Bicarb Dose DIALYSATE_DOSE_FIRST = BICARB_DOSE, ///< First dialysate Dose in list ACID_DOSE, ///< Acid Dose NUM_OF_DIALYSATE_DOSE ///< Number of dialysate Dose } DIALYSATE_DOSING_T; /// Enumeration of dialysate Dosing states. typedef enum DialysateDosing_States { DIALYSATE_OPEN_LOOP_STATE = 0, ///< Dialysate open loop state DIALYSATE_DOSING_RAMP_UP_STATE, ///< Dialysate dose ramp up state DIALYSATE_DOSING_CONTROL_TO_TARGET_STATE, ///< Dialysate dose control to target state NUM_OF_DIALYSATE_DOSING_STATES ///< Number of dialysate dose states } DIALYSATE_DOSING_STATE_T; /// Dialysate Dosing data structure typedef struct { U32 controlTimerCounter; ///< Timer counter to perform control on dialysate dose. DIALYSATE_DOSING_STATE_T dialysateDosingState; ///< Current state of dialysate dose controller state machine. //BOOL isDialPumpOn; ///< Flag indicates dialysate pump On or Off state //F32 prevPumpTargetSpeed; ///< Previous target dialysate pumps' speed (mL/min). //F32 currentPumpSpeed; ///< Current controlled dialysate pumps' speed (mL/min). //U32 directionErrorCount; ///< dialysate pump direction error count from power up. //U32 lastDirectionErrorCount; ///< last dialysate pump direction error count from power up. U08 control; ///< Dialysate dose control } DIALYSATE_DOSE_DATA_T; // ********** private data ********** static DRY_BICART_FILL_EXEC_STATE_T dryBiCartFillExecState; ///< Current state of dry bicart fill executive state machine. static BICARB_CHAMBER_FILL_EXEC_STATE_T bicarbChamberFillExecState; ///< Current state of bicarb chamber fill executive state machine. static DRY_BICART_DRAIN_EXEC_STATE_T dryBiCartDrainExecState; ///< Current state of dry bicart drain executive state machine // fill static U32 dryBiCartFillStartTime; ///< Dry bicart fill start time. static U32 biCartFillCycleCounter; ///< Number of drybicart fill cycle static U32 lastFillDurationInMS; ///< Previous time duration to fill the bicart fill. static U32 currentFillDurationInMS; ///< Current time duration to fill the bicart fill. static OVERRIDE_U32_T biCartMaxFillCycleCount; ///< Maximum number of drybicart fill cycle ( overrideable) // initiate the fill/supply/drain static OVERRIDE_U32_T dryBiCartFillRequested; ///< Start/stop dry bicart fill. static OVERRIDE_U32_T bicarbChamberFillRequested; ///< Start/stop bicarb chamber fill. static OVERRIDE_U32_T dryBiCartDrainRequested; ///< Start/stop dry bicart drain. // publish static OVERRIDE_U32_T dryBiCartDataPublishInterval; ///< Dry bicart data publish interval. static U32 dryBiCartDataPublicationTimerCounter; ///< Used to schedule drybicart data publication to CAN bus. // cart selection for draining static OVERRIDE_U32_T dryBiCartType; ///< Dry bicart size(small/large) // supply static U32 dryBiCarbSupplyStartTime; ///< Bicarb supply start time from bicart to Chamber F. // vent static U32 dryBiCarbSypplyVentStartTime; ///< Bicarb supply vent start time for both bicart & Chamber F. // drain static U32 dryBiCartDrainStartTime; ///< Drain overall start time (for max timeout) static U32 dryBiCartDrainLastCondSampleTime; ///< Last time conductivity was sampled static U32 dryBiCartDrainCondStableCount; ///< Debounce counter for "zero" conductivity static U32 dryBiCartDrainTimePeriod; ///< Dry bicart drain time period static DRY_BICART_OPERATION_T dryBicartStartRequest; ///< Dry bicart operation, fill or supply or drain request // drybicart mixing static OVERRIDE_F32_T dryBiCartAcidDoseVolume; ///< Acid concentrate volume in ml ( overrideable). static OVERRIDE_F32_T dryBiCartBicarbDoseVolume; ///< Bicarb concentrate volume in ml ( overrideable). static OVERRIDE_F32_T dryBiCartAcidDoseVolumeKpGain; ///< Acid concentrate volume in ml ( overrideable). static OVERRIDE_F32_T dryBiCartAcidDoseVolumeKiGain; ///< Acid concentrate volume in ml ( overrideable). static OVERRIDE_F32_T dryBiCartBicarbDoseVolumeKpGain; ///< Acid concentrate volume in ml ( overrideable). static OVERRIDE_F32_T dryBiCartBicarbDoseVolumeKiGain; ///< Acid concentrate volume in ml ( overrideable). static DIALYSATE_DOSE_DATA_T dialysateDose[ NUM_OF_DIALYSATE_DOSE ]; ///< Array of dialysate Dose data structure. static OVERRIDE_F32_T dryBiCartBicarbTargetConductivity; ///< Target bicarb conductivity static OVERRIDE_F32_T dryBiCartBicarbDeltaConductivity; ///< Target delta conductivity static OVERRIDE_F32_T dryBiCartAcidBicarbMixTargetConductivity; ///< Acid bicarb mix conductivity static OVERRIDE_F32_T dryBiCartAcidBicarbMixDeltaConductivity; ///< Acid bicarb delta conductivity static PI_CONTROLLER_SIGNALS_DATA bicarbControlSignals; ///< Bicarb closed loop control signal data static PI_CONTROLLER_SIGNALS_DATA acidControlSignals; ///< Acid closed loop control signal data //For testing static F32 pIControlSignal[ NUM_OF_CONTROLLER_SIGNAL ]; // ********** private function prototypes ********** static void updateDrybicartOperation(void); // Fill static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartStartState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterStartState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterEndState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasStartState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasEndState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillDurationCheckState( void ); static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillCompleteState( void ); // Supply & Vent static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberStartState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCartridgeFillWaterStartState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCartridgeFillWaterEndState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCheckLevelState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberFillState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberPressureCheckState( void ); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberSupplyVentStartState(void); static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberSupplyVentEndState(void); // Drain static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartDrainStartState( void ); static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainState( void ); static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainDurationCheckState( void ); static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainEndState( void ); // dosing control loop static DIALYSATE_DOSING_STATE_T handleDialysateOpenLoopState( DIALYSATE_DOSING_T doseId ); static DIALYSATE_DOSING_STATE_T handleDialysateDoseRampToTargetState( DIALYSATE_DOSING_T doseId ); static DIALYSATE_DOSING_STATE_T handleDialysateDoseControlToTargetState( DIALYSATE_DOSING_T doseId ); // publish the status static void publishDryBicartData( void ); static U32 getDryBicartFillDataPublishInterval( void ); /*********************************************************************//** * @brief * The The initDryBiCart function initializes the Dry Bicarbonate Cartridge * module. * @details \b Inputs: none * @details \b Outputs: unit variables initialized * @return none *************************************************************************/ void initDryBiCart( void ) { DIALYSATE_DOSING_T doseId; dryBiCartFillExecState = DRY_BICART_START_STATE; bicarbChamberFillExecState = BICARB_CHAMBER_START_STATE; dryBiCartDrainExecState = DRY_BICART_DRAIN_START_STATE; dryBicartStartRequest = DRY_BICART_IDLE; for ( doseId = DIALYSATE_DOSE_FIRST; doseId < NUM_OF_DIALYSATE_DOSE; doseId++ ) { dialysateDose[ doseId ].dialysateDosingState = DIALYSATE_OPEN_LOOP_STATE; } dryBiCartDataPublishInterval.data = DRY_BICART_DATA_PUBLISH_INTERVAL; dryBiCartDataPublishInterval.ovData = DRY_BICART_DATA_PUBLISH_INTERVAL; dryBiCartDataPublishInterval.ovInitData = 0; dryBiCartDataPublishInterval.override = OVERRIDE_RESET; biCartMaxFillCycleCount.data = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; biCartMaxFillCycleCount.ovData = DRY_BICART_DEFAULT_MAX_FILL_CYCLE_CNT; biCartMaxFillCycleCount.ovInitData = 0; biCartMaxFillCycleCount.override = OVERRIDE_RESET; dryBiCartFillRequested.data = FALSE; dryBiCartFillRequested.ovData = FALSE; dryBiCartFillRequested.ovInitData = FALSE; dryBiCartFillRequested.override = OVERRIDE_RESET; dryBiCartDrainRequested.data = FALSE; dryBiCartDrainRequested.ovData = FALSE; dryBiCartDrainRequested.ovInitData = FALSE; dryBiCartDrainRequested.override = OVERRIDE_RESET; bicarbChamberFillRequested.data = FALSE; bicarbChamberFillRequested.ovData = FALSE; bicarbChamberFillRequested.ovInitData = FALSE; bicarbChamberFillRequested.override = OVERRIDE_RESET; dryBiCartType.data = FALSE; dryBiCartType.ovData = FALSE; dryBiCartType.ovInitData = 0; dryBiCartType.override = OVERRIDE_RESET; dryBiCartAcidDoseVolume.data = DEFAULT_ACID_VOLUME_ML; dryBiCartAcidDoseVolume.ovData = DEFAULT_ACID_VOLUME_ML; dryBiCartAcidDoseVolume.ovInitData = 0.0F; dryBiCartAcidDoseVolume.override = OVERRIDE_RESET; dryBiCartBicarbDoseVolume.data = DEFAULT_BICARB_VOLUME_ML; dryBiCartBicarbDoseVolume.ovData = DEFAULT_BICARB_VOLUME_ML; dryBiCartBicarbDoseVolume.ovInitData = 0.0F; dryBiCartBicarbDoseVolume.override = OVERRIDE_RESET; dryBiCartAcidDoseVolumeKpGain.data = ACID_VOL_CONTROL_P_COEFFICIENT; dryBiCartAcidDoseVolumeKpGain.ovData = ACID_VOL_CONTROL_P_COEFFICIENT; dryBiCartAcidDoseVolumeKpGain.ovInitData = 0.0F; dryBiCartAcidDoseVolumeKpGain.override = OVERRIDE_RESET; dryBiCartAcidDoseVolumeKiGain.data = ACID_VOL_CONTROL_I_COEFFICIENT; dryBiCartAcidDoseVolumeKiGain.ovData = ACID_VOL_CONTROL_I_COEFFICIENT; dryBiCartAcidDoseVolumeKiGain.ovInitData = 0.0F; dryBiCartAcidDoseVolumeKiGain.override = OVERRIDE_RESET; dryBiCartBicarbDoseVolumeKpGain.data = BICARB_VOL_CONTROL_P_COEFFICIENT; dryBiCartBicarbDoseVolumeKpGain.ovData = BICARB_VOL_CONTROL_P_COEFFICIENT; dryBiCartBicarbDoseVolumeKpGain.ovInitData = 0.0F; dryBiCartBicarbDoseVolumeKpGain.override = OVERRIDE_RESET; dryBiCartBicarbDoseVolumeKiGain.data = BICARB_VOL_CONTROL_I_COEFFICIENT; dryBiCartBicarbDoseVolumeKiGain.ovData = BICARB_VOL_CONTROL_I_COEFFICIENT; dryBiCartBicarbDoseVolumeKiGain.ovInitData = 0.0F; dryBiCartBicarbDoseVolumeKiGain.override = OVERRIDE_RESET; dryBiCartBicarbTargetConductivity.data = DRY_BICARB_TARGET_CONDUCTIVITY; dryBiCartBicarbTargetConductivity.ovData = DRY_BICARB_TARGET_CONDUCTIVITY; dryBiCartBicarbTargetConductivity.ovInitData = 0.0F; dryBiCartBicarbTargetConductivity.override = OVERRIDE_RESET; dryBiCartBicarbDeltaConductivity.data = DRY_BICARB_DELTA_CONDUCTIVITY; dryBiCartBicarbDeltaConductivity.ovData = DRY_BICARB_DELTA_CONDUCTIVITY; dryBiCartBicarbDeltaConductivity.ovInitData = 0.0F; dryBiCartBicarbDeltaConductivity.override = OVERRIDE_RESET; dryBiCartAcidBicarbMixTargetConductivity.data = DRY_ACID_BICARB_TARGET_CONDUCTIVITY; dryBiCartAcidBicarbMixTargetConductivity.ovData = DRY_ACID_BICARB_TARGET_CONDUCTIVITY; dryBiCartAcidBicarbMixTargetConductivity.ovInitData = 0.0F; dryBiCartAcidBicarbMixTargetConductivity.override = OVERRIDE_RESET; dryBiCartAcidBicarbMixDeltaConductivity.data = DRY_ACID_BICARB_DELTA_CONDUCTIVITY; dryBiCartAcidBicarbMixDeltaConductivity.ovData = DRY_ACID_BICARB_DELTA_CONDUCTIVITY; dryBiCartAcidBicarbMixDeltaConductivity.ovInitData = 0.0F; dryBiCartAcidBicarbMixDeltaConductivity.override = OVERRIDE_RESET; dryBiCartFillStartTime = 0; lastFillDurationInMS = 0; currentFillDurationInMS = 0; dryBiCartDataPublicationTimerCounter = 0; biCartFillCycleCounter = 0; dryBiCarbSupplyStartTime = 0; dryBiCarbSypplyVentStartTime = 0; dryBiCartDrainStartTime = 0; dryBiCartDrainLastCondSampleTime = 0; dryBiCartDrainCondStableCount = 0; dryBiCartDrainTimePeriod = 0; initializePIController(PI_CONTROLLER_ID_BICARB_VOL, MIN_BICARB_VOLUME_MLPM,\ getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); initializePIController(PI_CONTROLLER_ID_ACID_VOL, MIN_ACID_VOLUME_MLPM, \ getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); } /*********************************************************************//** * @brief * The transitionToDryBicart function prepares for transition to * dry bicart fill/degas operations. * @details \b Inputs: none * @details \b Outputs: none * @return none *************************************************************************/ void transitionToDryBicart( void ) { initDryBiCart(); } /*********************************************************************//** * @brief * The execDialysateCompositionDosingController function executes the dialysate dosing controller. * @details \b Inputs: dialysateDosingState * @details \b Outputs: dialysateDosingState * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid dialysate dosing * state machine found. * @return none *************************************************************************/ void execDialysateCompositionDosingController( void ) { DIALYSATE_DOSING_T doseId; for ( doseId = DIALYSATE_DOSE_FIRST; doseId < NUM_OF_DIALYSATE_DOSE; doseId++ ) { switch ( dialysateDose[ doseId ].dialysateDosingState ) { case DIALYSATE_OPEN_LOOP_STATE: dialysateDose[ doseId ].dialysateDosingState = handleDialysateOpenLoopState( doseId ); break; case DIALYSATE_DOSING_RAMP_UP_STATE: dialysateDose[ doseId ].dialysateDosingState = handleDialysateDoseRampToTargetState( doseId ); break; case DIALYSATE_DOSING_CONTROL_TO_TARGET_STATE: dialysateDose[ doseId ].dialysateDosingState = handleDialysateDoseControlToTargetState( doseId ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSATE_DOSE_EXEC_INVALID_STATE, doseId ) dialysateDose[ doseId ].dialysateDosingState = DIALYSATE_OPEN_LOOP_STATE; break; } } } /*********************************************************************//** * @brief * The execDryBicart function executes the set of dry bicarbonate cartridge fill, * bicarbonate chamber fill and bicarbonate cartridge drain related state machines one at time * @details \b Inputs: dryBicartStartRequest * @details \b Outputs: none * @return none. *************************************************************************/ void execDryBicart( void ) { updateDrybicartOperation(); // top level state machine selection DRY_BICART_OPERATION_T dryBicartState = dryBicartStartRequest; U32 dryBicartSubstate; switch ( dryBicartState ) { case DRY_BICART_IDLE: // run as idle state dryBicartSubstate = 0x0; break; case DRY_BICART_INITIAL_FILL: // Dry bicart fill exec dryBicartSubstate = execDryBicartFillMode(); break; case DRY_BICART_SUPPLY: // Fill Bicarb chamber F exec dryBicartSubstate = execBicarbChamberFillMode(); break; case DRY_BICART_DRAIN: // Dry bicart drain exec dryBicartSubstate = execDryBicartDrainMode(); break; default: // software fault, dryBicartSubstate = 0x0; dryBicartStartRequest = DRY_BICART_IDLE; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DRY_BICART_FILL_INVALID_EXEC_STATE, dryBicartStartRequest ); break; } (void)dryBicartSubstate; // Publish dry bicart data publishDryBicartData(); } /*********************************************************************//** * @brief * The execDryBicartFillMode function executes the dry bicart fill (mixing water * with dry sodium bicarbonate ) state machine. * @details \b Inputs: dryBiCartFillExecState * @details \b Outputs: dryBiCartFillExecState * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong dry bicart fill state * invoked. * @return current state. *************************************************************************/ U32 execDryBicartFillMode( void ) { // execute drybicart fill state machine switch ( dryBiCartFillExecState ) { case DRY_BICART_START_STATE: dryBiCartFillExecState = handleDryBicartStartState(); break; case DRY_BICART_FILL_WATER_START_STATE: dryBiCartFillExecState = handleDryBicartFillWaterStartState(); break; case DRY_BICART_FILL_WATER_END_STATE: dryBiCartFillExecState = handleDryBicartFillWaterEndState(); break; case DRY_BICART_DEGAS_START_STATE: dryBiCartFillExecState = handleDryBicartDegasStartState(); break; case DRY_BICART_DEGAS_END_STATE: dryBiCartFillExecState = handleDryBicartDegasEndState(); break; case DRY_BICART_FILL_DURATION_CHECK_STATE: dryBiCartFillExecState = handleDryBicartFillDurationCheckState(); break; case DRY_BICART_FILL_COMPLETE_STATE: dryBiCartFillExecState = handleDryBicartFillCompleteState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DRY_BICART_FILL_INVALID_EXEC_STATE, dryBiCartFillExecState ); break; } return dryBiCartFillExecState; } /*********************************************************************//** * @brief * The execBicarbChamberFillMode function executes the bicarb chamber fill * (delivering bicarbonate from Bicart assembly to chamber F)state machine. * @details \b Inputs: bicarbChamberFillExecState * @details \b Outputs: bicarbChamberFillExecState * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong bicarb chamber * fill state invoked. * @return current state. *************************************************************************/ U32 execBicarbChamberFillMode( void ) { // closed loop bicarb and acid dosing controller execDialysateCompositionDosingController(); // execute bicarb chamber fill state machine switch ( bicarbChamberFillExecState ) { case BICARB_CHAMBER_START_STATE: bicarbChamberFillExecState = handleBicarbChamberStartState(); break; case BICARB_CARTRIDGE_FILL_WATER_START_STATE: bicarbChamberFillExecState = handleBicarbChamberCartridgeFillWaterStartState(); break; case BICARB_CARTRIDGE_FILL_WATER_END_STATE: bicarbChamberFillExecState = handleBicarbChamberCartridgeFillWaterEndState(); break; case BICARB_CHAMBER_CHECK_LEVEL_STATE: bicarbChamberFillExecState = handleBicarbChamberCheckLevelState(); break; case BICARB_CHAMBER_FILL_STATE: bicarbChamberFillExecState = handleBicarbChamberFillState(); break; case BICARB_CHAMBER_PRESSURE_CHECK_STATE: bicarbChamberFillExecState = handleBicarbChamberPressureCheckState(); break; case BICARB_SUPPLY_VENT_START_STATE: bicarbChamberFillExecState = handleBicarbChamberSupplyVentStartState(); break; case BICARB_SUPPLY_VENT_END_STATE: bicarbChamberFillExecState = handleBicarbChamberSupplyVentEndState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_BICARB_CHAMBER_FILL_INVALID_EXEC_STATE, bicarbChamberFillExecState ); break; } return bicarbChamberFillExecState; } /*********************************************************************//** * @brief * The execDryBicartDrainMode function executes the dry bicart drain state machine. * @details \b Inputs: dryBiCartDrainExecState * @details \b Outputs: dryBiCartDrainExecState * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong dry bicart drain state * invoked. * @return current state. *************************************************************************/ U32 execDryBicartDrainMode( void ) { // execute drybicart drain state machine switch ( dryBiCartDrainExecState ) { case DRY_BICART_DRAIN_START_STATE: dryBiCartDrainExecState = handleDryBicartDrainStartState(); break; case DRY_BICART_FLUID_DRAIN_STATE: dryBiCartDrainExecState = handleDryBicartFluidDrainState(); break; case DRY_BICART_FLUID_DRAIN_DURATION_CHECK_STATE: dryBiCartDrainExecState = handleDryBicartFluidDrainDurationCheckState(); break; case DRY_BICART_FLUID_DRAIN_END_STATE: dryBiCartDrainExecState = handleDryBicartFluidDrainEndState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DRY_BICART_DRAIN_INVALID_EXEC_STATE, dryBiCartDrainExecState ); break; } return dryBiCartDrainExecState; } /*********************************************************************//** * @brief * The setBicarbDoseVol function sets bicarb dose volume provided by the controller * @details \b Inputs: none * @details \b Outputs: dryBiCartBicarbDoseVolume * @param targetValue bicarb dose volume * @return TRUE if successful, FALSE if not. *************************************************************************/ void setBicarbDoseVol( F32 targetValue ) { dryBiCartBicarbDoseVolume.data = targetValue; } /*********************************************************************//** * @brief * TThe getBicarbDoseVol function gets the bicarb dose volume provided by the controller * @details \b Inputs: dryBiCartBicarbDoseVolume * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getBicarbDoseVol( void ) { F32 result = dryBiCartBicarbDoseVolume.data; if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolume.override ) { result = dryBiCartBicarbDoseVolume.ovData; } return result; } /*********************************************************************//** * @brief * The setAcidDoseVol function sets acid dose volume provided by the controller * flag value to be True. * @details \b Inputs: none * @details \b Outputs: dryBiCartAcidDoseVolume * @param targetValue acid dose volume * @return TRUE if successful, FALSE if not. *************************************************************************/ void setAcidDoseVol( F32 targetValue ) { dryBiCartAcidDoseVolume.data = targetValue; } /*********************************************************************//** * @brief * The getBicarbAcidDoseVol function gets acid dose volume provided by the controller * flag values * @details \b Inputs: dryBiCartAcidDoseVolume * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getAcidDoseVol( void ) { F32 result = dryBiCartAcidDoseVolume.data; if ( OVERRIDE_KEY == dryBiCartAcidDoseVolume.override ) { result = dryBiCartAcidDoseVolume.ovData; } return result; } /*********************************************************************//** * @brief * The getBicarbDeltaConductivity function gets the delta target conductivity * @details \b Inputs: dryBiCartBicarbDeltaConductivity * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getBicarbDeltaConductivity( void ) { F32 result = dryBiCartBicarbDeltaConductivity.data; if ( OVERRIDE_KEY == dryBiCartBicarbDeltaConductivity.override ) { result = dryBiCartBicarbDeltaConductivity.ovData; } return result; } /*********************************************************************//** * @brief * The getBicarbTargetConductivity function gets the target conductivity * @details \b Inputs: dryBiCartBicarbTargetConductivity * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getBicarbTargetConductivity( void ) { F32 result = dryBiCartBicarbTargetConductivity.data; if ( OVERRIDE_KEY == dryBiCartBicarbTargetConductivity.override ) { result = dryBiCartBicarbTargetConductivity.ovData; } return result; } /*********************************************************************//** * @brief * The getAcidBicarbDeltaConductivity function gets the acid bicarb delta target conductivity * flag values * @details \b Inputs: dryBiCartAcidBicarbMixDeltaConductivity * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getAcidBicarbDeltaConductivity( void ) { F32 result = dryBiCartAcidBicarbMixDeltaConductivity.data; if ( OVERRIDE_KEY == dryBiCartAcidBicarbMixDeltaConductivity.override ) { result = dryBiCartAcidBicarbMixDeltaConductivity.ovData; } return result; } /*********************************************************************//** * @brief * The getAcidBicarbTargetConductivity function gets the acid bicarb delta target conductivity * flag values * @details \b Inputs: dryBiCartAcidBicarbMixTargetConductivity * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getAcidBicarbTargetConductivity( void ) { F32 result = dryBiCartAcidBicarbMixTargetConductivity.data; if ( OVERRIDE_KEY == dryBiCartAcidBicarbMixTargetConductivity.override ) { result = dryBiCartAcidBicarbMixTargetConductivity.ovData; } return result; } /*********************************************************************//** * @brief * The getBicarbKpGainCoefficient function gets the Kp Gain for closed loop * bicarb dose volume control * flag values * @details \b Inputs: dryBiCartBicarbDoseVolumeKpGain * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getBicarbKpGainCoefficient( void ) { F32 result = dryBiCartBicarbDoseVolumeKpGain.data; if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolumeKpGain.override ) { result = dryBiCartBicarbDoseVolumeKpGain.ovData; } return result; } /*********************************************************************//** * @brief * The getBicarbKiGainCoefficient function gets the Kp Gain for closed loop * bicarb dose volume control * flag values * @details \b Inputs: dryBiCartBicarbDoseVolumeKiGain * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getBicarbKiGainCoefficient( void ) { F32 result = dryBiCartBicarbDoseVolumeKiGain.data; if ( OVERRIDE_KEY == dryBiCartBicarbDoseVolumeKiGain.override ) { result = dryBiCartBicarbDoseVolumeKiGain.ovData; } return result; } /*********************************************************************//** * @brief * The getAcidKpGainCoefficient function gets the Kp Gain for closed loop * acid dose volume control * flag values * @details \b Inputs: dryBiCartAcidDoseVolumeKpGain * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getAcidKpGainCoefficient( void ) { F32 result = dryBiCartAcidDoseVolumeKpGain.data; if ( OVERRIDE_KEY == dryBiCartAcidDoseVolumeKpGain.override ) { result = dryBiCartAcidDoseVolumeKpGain.ovData; } return result; } /*********************************************************************//** * @brief * The getAcidKiGainCoefficient function gets the Ki Gain for closed loop * acid dose volume control * flag values * @details \b Inputs: dryBiCartAcidDoseVolumeKiGain * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ F32 getAcidKiGainCoefficient( void ) { F32 result = dryBiCartAcidDoseVolumeKiGain.data; if ( OVERRIDE_KEY == dryBiCartAcidDoseVolumeKiGain.override ) { result = dryBiCartAcidDoseVolumeKiGain.ovData; } return result; } /*********************************************************************//** * @brief * The setBicarbChamberFillRequested function sets the chmaberFillRequest * flag value to be True. * @details \b Inputs: dryBiCartFillRequested, dryBiCartDrainRequested * @details \b Outputs: bicarbChamberFillRequested * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL setBicarbChamberFillRequested( void ) { BOOL result = FALSE; BOOL requestStatus = getU32OverrideValue( &dryBiCartFillRequested ) || getU32OverrideValue( &dryBiCartDrainRequested ); // ensure that there is no other operation in progress before new request set to true if ( FALSE == requestStatus ) { bicarbChamberFillRequested.data = TRUE; result = TRUE; } return result; } /*********************************************************************//** * @brief * The getBicarbChamberFillRequested function gets the chmaberFillRequest * flag values * @details \b Inputs: bicarbChamberFillRequested * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL getBicarbChamberFillRequested( void ) { BOOL result = FALSE; if ( (TRUE == getU32OverrideValue( &bicarbChamberFillRequested ) ) ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The setBicartFillRequested function sets the bicart fill request * flag value to be True. * @details \b Inputs: bicarbChamberFillRequested, dryBiCartDrainRequested * @details \b Outputs: dryBiCartFillRequested * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL setBicartFillRequested( void ) { BOOL result = FALSE; BOOL requestStatus = getU32OverrideValue( &bicarbChamberFillRequested ) || getU32OverrideValue( &dryBiCartDrainRequested ); //ensure that there is no other operation in progress before new request set to true if ( FALSE == requestStatus ) { dryBiCartFillRequested.data = TRUE; result = TRUE; } return result; } /*********************************************************************//** * @brief * The getBicartFillRequested function gets the bicart fill request * flag value * @details \b Inputs: dryBiCartFillRequested * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL getBicartFillRequested( void ) { BOOL result = FALSE; if ( ( TRUE == getU32OverrideValue( &dryBiCartFillRequested ) ) ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The setBicartDrainRequested function sets the bicart drain request * flag value to be True. * @details \b Inputs: bicarbChamberFillRequested,dryBiCartFillRequested * @details \b Outputs: dryBiCartDrainRequested * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL setBicartDrainRequested( void ) { BOOL result = FALSE; BOOL requestStatus = getU32OverrideValue( &bicarbChamberFillRequested ) || getU32OverrideValue( &dryBiCartFillRequested ); //ensure that there is no other operation in progress before new request set to true if ( FALSE == requestStatus ) { dryBiCartDrainRequested.data = TRUE; result = TRUE; } return result; } /*********************************************************************//** * @brief * The getBicartDrainRequested function gets the bicart drain request * flag value * @details \b Inputs: dryBiCartDrainRequested * @details \b Outputs: none * @return TRUE if successful, FALSE if not. *************************************************************************/ BOOL getBicartDrainRequested( void ) { BOOL result = FALSE; if ( ( TRUE == getU32OverrideValue( &dryBiCartDrainRequested ) ) ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The getCurrentDryBiCartFillExecState function returns the current state * of the dry bicart fill state. * @details \b Inputs: dryBiCartFillExecState * @details \b Outputs: none * @return the current state of dry bicart fill exec state. *************************************************************************/ DRY_BICART_FILL_EXEC_STATE_T getCurrentDryBiCartFillExecState( void ) { return dryBiCartFillExecState; } /*********************************************************************//** * @brief * The handleDialysateOpenLoopState function handles the dialysate open loop state of * the dialysate dose controller state machine. * @details \b Inputs: D17_COND, D29_COND * @details \b Outputs: none * @param doseId dialysate dose id to run the dialysate dose * @return next state for the controller state machine *************************************************************************/ static DIALYSATE_DOSING_STATE_T handleDialysateOpenLoopState( DIALYSATE_DOSING_T doseId ) { DIALYSATE_DOSING_STATE_T result = DIALYSATE_OPEN_LOOP_STATE; if ( BICARB_DOSE == doseId ) { #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ F32 measuredBicarbConductivity = getFilteredConductivity( D17_COND ); #else F32 biCarbConductivity = getConductivityValue( D17_COND ); #endif // if measured conductivity crossed (targetConductivity- deltaConuctivity) , switch to closed loop if ( measuredBicarbConductivity >= ( getBicarbTargetConductivity() - getBicarbDeltaConductivity() ) ) { result = DIALYSATE_DOSING_RAMP_UP_STATE; } } else if ( ACID_DOSE == doseId ) { #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ F32 measuredAcidBicarbMixConductivity = getFilteredConductivity( D29_COND ); #else F32 acidBicarbMixConductivity = getConductivityValue( D29_COND ); #endif // if measured conductivity crossed (targetConductivity- deltaConuctivity) , switch to closed loop if ( measuredAcidBicarbMixConductivity >= ( getAcidBicarbTargetConductivity() - getAcidBicarbDeltaConductivity() ) ) { result = DIALYSATE_DOSING_RAMP_UP_STATE; } } return result; } /*********************************************************************//** * @brief * The handleDialysatePumpRampToTargetState function handles the dialysate ramp to target state of * the dialysate dose controller state machine. * @details \b Inputs: none * @details \b Outputs: none * @param doseId dose id to * @return next state for the controller state machine *************************************************************************/ static DIALYSATE_DOSING_STATE_T handleDialysateDoseRampToTargetState( DIALYSATE_DOSING_T doseId ) { DIALYSATE_DOSING_STATE_T state = DIALYSATE_DOSING_RAMP_UP_STATE; //if ( TRUE == stepDialysatePumpToTargetSpeed( pumpId ) ) { if ( BICARB_DOSE == doseId ) { resetPIController( PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD ); state = DIALYSATE_DOSING_CONTROL_TO_TARGET_STATE; } else if ( ACID_DOSE == doseId ) { resetPIController( PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD ); state = DIALYSATE_DOSING_CONTROL_TO_TARGET_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDialysatePumpControlToTargetState function handles the control to * target state of the dialysate dose controller state machine.. * @details \b Inputs: D17_COND, D29_COND, controlTimerCounter * @details \b Outputs:none * @return next state of the controller state machine *************************************************************************/ static DIALYSATE_DOSING_STATE_T handleDialysateDoseControlToTargetState( DIALYSATE_DOSING_T doseId ) { DIALYSATE_DOSING_STATE_T state = DIALYSATE_DOSING_CONTROL_TO_TARGET_STATE; // control at set minimum interval or interval is expired and balance chamber fill is complete if ( ( ( ++dialysateDose[ doseId ].controlTimerCounter >= DOSE_CONTROL_INTERVAL ) /*|| ( TRUE == dialPumpsReadyToControl ) ) && ( TRUE != isDialPumpOpenLoopEnabled[ pumpId ] )*/ ) ) { dialysateDose[ doseId ].controlTimerCounter = 0; //dialPumpsReadyToControl = TRUE; // Control happen only when balancing chamber fill is complete. //if ( FALSE == getBalancingChamberFillinProgressStatus() ) { // Control based on the measured and target conductivity if ( BICARB_DOSE == doseId ) { #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ F32 measuredBicarbConductivity = getFilteredConductivity( D17_COND ); #else F32 biCarbConductivity = getConductivityValue( D17_COND ); #endif F32 bicarbDoseVol = runPIController(PI_CONTROLLER_ID_BICARB_VOL, getBicarbTargetConductivity(), measuredBicarbConductivity); //Set bicarb dosing vol setBicarbDoseVol( bicarbDoseVol ); U32 i; for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) { pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_BICARB_VOL, (PI_CONTROLLER_SIGNALS_ID)i ); } memcpy((void*)&bicarbControlSignals, (void*)&pIControlSignal, sizeof(PI_CONTROLLER_SIGNALS_DATA)); } // ACID dose else if ( ACID_DOSE == doseId ) { #ifdef __TEENSY_CONDUCTIVITY_DRIVER__ F32 measuredAcidBicarbMixConductivity = getFilteredConductivity( D29_COND ); #else F32 acidBicarbMixConductivity = getFilteredConductivity( D29_COND ); #endif F32 acidDoseVol = runPIController(PI_CONTROLLER_ID_ACID_VOL, getAcidBicarbTargetConductivity(), measuredAcidBicarbMixConductivity); //Set acid dosing vol setAcidDoseVol( acidDoseVol ); U32 i; for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) { pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_ACID_VOL, (PI_CONTROLLER_SIGNALS_ID)i ); } memcpy((void*)&acidControlSignals, (void*)&pIControlSignal, sizeof(PI_CONTROLLER_SIGNALS_DATA)); } } } return state; } /*********************************************************************//** * @brief * The updateDrybicartOperation function initiates the water fill, bicarbonate supply or bicarbonate drain * operation * @details \b Inputs: none * @details \b Outputs: dryBicartStartRequest * @return none *************************************************************************/ static void updateDrybicartOperation(void) { if ( TRUE == getBicarbChamberFillRequested() ) { // supply dryBicartStartRequest = DRY_BICART_SUPPLY ; } else if ( TRUE == getBicartFillRequested() ) { // fill dryBicartStartRequest = DRY_BICART_INITIAL_FILL; } else if ( TRUE == getBicartDrainRequested() ) { //drain dryBicartStartRequest = DRY_BICART_DRAIN; } else { // idle dryBicartStartRequest = DRY_BICART_IDLE; } } /*********************************************************************//** * @brief * The handleDryBicartStartState function wait for a fill request * @details \b Inputs: dryBiCartFillRequested * @details \b Outputs: valve states * @return the next drybicart fill water start state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartStartState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_START_STATE; if ( TRUE == getU32OverrideValue( &dryBiCartFillRequested ) ) { // fill drybicart only if iofp state is in FP_MODE_GENP //if(FP_MODE_GENP == getCurrentFPOperationMode()) { // TODO: pre gen should start the D12 pump and D14 valve setValveState( D14_VALV, VALVE_STATE_OPEN ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); state = DRY_BICART_FILL_WATER_START_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDryBicartFillWaterStartState function initiates the water fill * into dry bicarbonate cartridge. * @details \b Inputs: none * @details \b Outputs: valve states * @return the next drybicart fill water end state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterStartState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_WATER_START_STATE; // Close vent valves and de-scaling valve setValveState( D80_VALV, VALVE_STATE_CLOSED ); setValveState( D81_VALV, VALVE_STATE_CLOSED ); setValveState( D85_VALV, VALVE_STATE_CLOSED ); //Open D65 setValveState( D65_VALV, VALVE_STATE_OPEN ); //Open D64 setValveState( D64_VALV, VALVE_STATE_OPEN ); //Initiate timer to measure length of fill dryBiCartFillStartTime = getMSTimerCount(); state = DRY_BICART_FILL_WATER_END_STATE; return state; } /*********************************************************************//** * @brief * The handleDryBicartFillWaterEndState function closes the valve opened * for Dry bicart fill. * @details \b Inputs: D66 pressure sensor reading * @details \b Outputs: valve states * @return the next drybicart degas start state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillWaterEndState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_WATER_END_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); // Close dry bicart inlet water if bicart is filled with water if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_PRESSURE ) { setValveState( D65_VALV, VALVE_STATE_CLOSED ); lastFillDurationInMS = currentFillDurationInMS; currentFillDurationInMS = calcTimeSince( dryBiCartFillStartTime ); //Increment number of fill cycle biCartFillCycleCounter++; state = DRY_BICART_DEGAS_START_STATE; } //TODO:Handle timeout alarm for opening D65 valve too long return state; } /*********************************************************************//** * @brief * The handleDryBicartDegasStartState function actuates the vent valve * present in the Bicart assembly. * @details \b Inputs: none * @details \b Outputs: valve states * @return the next drybicart degas end state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasStartState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_DEGAS_START_STATE; //Close D64 setValveState( D64_VALV, VALVE_STATE_CLOSED); //Vent bicart setValveState( D85_VALV, VALVE_STATE_OPEN ); //Initiate timer to measure length of bicart vent dryBiCartFillStartTime = getMSTimerCount(); state = DRY_BICART_DEGAS_END_STATE; return state; } /*********************************************************************//** * @brief * The handleDryBicartDegasEndState function open vent valve present in * the F Chamber (Bicarb) and closes the vent valve once pressure is met. * @details \b Inputs: D66 pressure sensor reading, dryBiCartFillStartTime * @details \b Outputs: valve states * @return the next drybicart fill duration check state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartDegasEndState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_DEGAS_END_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); if ( TRUE == didTimeout( dryBiCartFillStartTime, DRY_BICART_FILL_VENT_TIME_MS ) ) { //Vent chamber F setValveState( D64_VALV, VALVE_STATE_OPEN ); } // D66 pressure drops or time out if ( ( d66Pressure <= DRY_BICART_FILL_VENT_COMPLETE_PRESSURE ) || ( TRUE == didTimeout( dryBiCartFillStartTime, DRY_BICART_FILL_VENT_MAX_TIME_MS ) ) ) { setValveState( D64_VALV, VALVE_STATE_OPEN ); setValveState( D85_VALV, VALVE_STATE_CLOSED ); state = DRY_BICART_FILL_DURATION_CHECK_STATE; } //TODO: Alarm when vent timeout exceeded, but pressure not dropped below expected PSI (0 psi) return state; } /*********************************************************************//** * @brief * The handleDryBicartFillDurationCheckState function checks the fill duration * between last and current fill and exits if the duration is reduced over period * or number of fill cycle done. * @details \b Inputs: currentFillDurationInMS, lastFillDurationInMS, biCartMaxFillCycleCount * D66 pressure, biCartFillCycleCounter, dryBiCartFillRequested * @details \b Outputs: valve states * @return the next drybicart fill state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillDurationCheckState( void ) { DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_DURATION_CHECK_STATE; U32 diffInFillDuration = abs( currentFillDurationInMS - lastFillDurationInMS ); U32 dryBiCartMaxFillCount = getU32OverrideValue( &biCartMaxFillCycleCount ); F32 d66Pressure = getFilteredPressure( D66_PRES ); // Fill time shortens over the period or number of fill cycle exceeded if ( ( ( currentFillDurationInMS <= DRY_BICART_FILL_DURATION_MIN_MS ) && ( diffInFillDuration <= DRY_BICART_FILL_DURATION_DIFF_MS ) ) || ( biCartFillCycleCounter >= dryBiCartMaxFillCount ) ) { state = DRY_BICART_FILL_COMPLETE_STATE; // TODO: stop the D12 pump signalDialysatePumpHardStop( D12_PUMP ); // TODO: close the D14 valve setValveState( D14_VALV, VALVE_STATE_CLOSED ); // TODO: remove ? start timer for timeout to reset fill complete state to DRY_BICART_START_STATE dryBiCartFillStartTime = getMSTimerCount(); } else { // Stop drycart fill if fill request flag is set to false. if ( FALSE == getU32OverrideValue( &dryBiCartFillRequested ) ) { dryBiCartFillRequested.data = FALSE; state = DRY_BICART_START_STATE; } else { // transition to next fill cycle and degas state = DRY_BICART_FILL_WATER_START_STATE; } } return state; } /*********************************************************************//** * @brief * The handleDryBicartFillCompleteState function terminal for the dry bicart * fill states. * @details \b Inputs: dryBiCartFillRequested * @details \b Outputs: valve states * @return the next drybicart start state. *************************************************************************/ static DRY_BICART_FILL_EXEC_STATE_T handleDryBicartFillCompleteState( void ) { // stay in this state till bicart request is cleared so that fill complete status can be checked DRY_BICART_FILL_EXEC_STATE_T state = DRY_BICART_FILL_COMPLETE_STATE; // TODO: check whether its required or not, right now in pre-gen need to check the fill complete status // TODO: implement the broadcast message for fill complete if ( TRUE == didTimeout( dryBiCartFillStartTime, DRY_BICART_FILL_COMPLETE_TIME_MS ) ) { // Go idle dryBiCartFillRequested.data = FALSE; // for this request override also cleared dryBiCartFillRequested.ovData = FALSE; state = DRY_BICART_START_STATE; } return state; } /*********************************************************************//** * @brief * The getDryBicartFillDataPublishInterval function gets the dry bicart * fill data publish interval. * @details \b Inputs: dryBiCartDataPublishInterval * @details \b Outputs: none * @return the interval at dry bicart fill/supply/drain data being published. *************************************************************************/ static U32 getDryBicartFillDataPublishInterval( void ) { U32 result = getU32OverrideValue( &dryBiCartDataPublishInterval ); return result; } /*********************************************************************//** * @brief * The handleBicarbChamberStartState function wait for bicarb chamber fill request * @details \b Inputs: bicarbChamberFillRequested * @details \b Outputs: none * @return the next drybicart fluid drain state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberStartState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_START_STATE; if ( TRUE == getU32OverrideValue( &bicarbChamberFillRequested ) ) { state = BICARB_CARTRIDGE_FILL_WATER_START_STATE; } return state; } /*********************************************************************//** * @brief * The handleBicarbChamberCartridgeFillWaterStartState function fill water in the dry bicart * @details \b Inputs: none * @details \b Outputs: valve states * @return the next bicarb cartridge fill water end state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCartridgeFillWaterStartState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CARTRIDGE_FILL_WATER_END_STATE; // Close vent valves and descaling valve setValveState( D81_VALV, VALVE_STATE_CLOSED ); setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D85_VALV, VALVE_STATE_CLOSED ); // open inlet water to bicart setValveState( D65_VALV, VALVE_STATE_OPEN ); return state; } /*********************************************************************//** * @brief * The handleBicarbChamberCartridgeFillWaterStartState function stop water in the dry bicart * @details \b Inputs: D66 pressure * @details \b Outputs: valve states * @return the next bicarb chamber check level state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCartridgeFillWaterEndState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CARTRIDGE_FILL_WATER_END_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_PRESSURE ) { // Close water inlet valve as D66 pressure reaches 15 PSI. setValveState( D65_VALV, VALVE_STATE_CLOSED ); state = BICARB_CHAMBER_CHECK_LEVEL_STATE; } return state; } /*********************************************************************//** * @brief * The handleBicarbChamberCheckLevelState function checks the bicarb level(D63) * in the chamber F and decides to open the bicarb inlet valve (D80). * @details \b Inputs: D63 level * @details \b Outputs: valve states, dryBiCarbSupplyStartTime * @return the next bicarb chamber fill state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberCheckLevelState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_CHECK_LEVEL_STATE; LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); // TODO: Confirm D80 open on chamber low or end of balancing chamber switching? // TODO: Enable the below code once level sensor is working //if ( LEVEL_STATE_LOW == bicarbChamberLevel ) //{ if ( getBalancingChamberFillinProgressStatus() == FALSE ) { // Open the Bicarb chamber inlet valve setValveState( D80_VALV, VALVE_STATE_OPEN ); // Start a timer when bicarb supply started to chamber F dryBiCarbSupplyStartTime = getMSTimerCount(); state = BICARB_CHAMBER_FILL_STATE; } //} return state; } /*********************************************************************//** * @brief * The handleBicarbChamberFillState function checks the D66 pressure & * decides to open D65 and Close the inlet valve (D80) once level reached * @details \b Inputs: D66 pressure sensor reading, D63 level * @details \b Outputs: valve states * @return the next bicarb chamber pressure check state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberFillState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_FILL_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); // Once level reached, close the valve if ( LEVEL_STATE_HIGH == bicarbChamberLevel ) { setValveState( D80_VALV, VALVE_STATE_CLOSED ); state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; } // Open water inlet valve to fill the bicart else if ( d66Pressure <= DRY_BICART_FILL_INITIATE_PRESSURE ) { setValveState( D65_VALV, VALVE_STATE_OPEN ); state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; } return state; } /*********************************************************************//** * @brief * The handleBicarbChamberPressureCheckStartState function actuates the vent valve * present in the Bicart assembly. * @details \b Inputs: D66 Pressure, D63 level, dryBiCarbSupplyStartTime * @details \b Outputs: dryBiCarbSypplyVentStartTime * @return the next bicarb chamber Supply Vent Start state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberPressureCheckState( void ) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_CHAMBER_PRESSURE_CHECK_STATE; F32 d66Pressure = getFilteredPressure( D66_PRES ); LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); // Once level reached, close the valve if ( ( LEVEL_STATE_HIGH == bicarbChamberLevel ) || ( TRUE == didTimeout( dryBiCarbSupplyStartTime, DRY_BICART_SUPPLY_VALVE_D80_OPEN_TIME_MS ) ) ) { setValveState( D65_VALV, VALVE_STATE_CLOSED ); setValveState( D80_VALV, VALVE_STATE_CLOSED ); dryBiCarbSypplyVentStartTime = getMSTimerCount(); state = BICARB_SUPPLY_VENT_START_STATE; } // Close water inlet valve as fill is complete. if ( d66Pressure >= DRY_BICART_FILL_COMPLETE_PRESSURE ) { setValveState( D65_VALV, VALVE_STATE_CLOSED ); } return state; } /*********************************************************************//** * @brief * The handleBicarbChamberSupplyVentStartState function actuates the vent valve * present in the Bicart assembly. * @details \b Inputs: dryBiCarbSypplyVentStartTime * @details \b Outputs: dryBiCarbSypplyVentStartTime * @return the next bicarb chamber Supply Vent End state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberSupplyVentStartState(void) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_SUPPLY_VENT_START_STATE; if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_TIME_MS ) ) { //Vent bicart after 1 sec setValveState( D85_VALV, VALVE_STATE_OPEN ); } if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ) ) { //Vent chamber F after 3 sec setValveState( D64_VALV, VALVE_STATE_OPEN ); dryBiCarbSypplyVentStartTime = getMSTimerCount(); state = BICARB_SUPPLY_VENT_END_STATE; } return state; } /*********************************************************************//** * @brief * The handleBicarbChamberSupplyVentEndState function actuates the vent valve * present in the Bicart assembly. * @details \b Inputs: dryBiCarbSypplyVentStartTime * @details \b Outputs: none * @return the next bicarb chamber start state. *************************************************************************/ static BICARB_CHAMBER_FILL_EXEC_STATE_T handleBicarbChamberSupplyVentEndState(void) { BICARB_CHAMBER_FILL_EXEC_STATE_T state = BICARB_SUPPLY_VENT_END_STATE; // close bicart vent and chamber f vent after 3 sec if ( TRUE == didTimeout( dryBiCarbSypplyVentStartTime, DRY_BICART_SUPPLY_VENT_MAX_TIME_MS ) ) { setValveState( D85_VALV, VALVE_STATE_CLOSED ); setValveState( D64_VALV, VALVE_STATE_CLOSED); bicarbChamberFillRequested.data = FALSE; // for this request override also cleared bicarbChamberFillRequested.ovData = FALSE; state = BICARB_CHAMBER_START_STATE; } return state; } /*********************************************************************//** * @brief * The handleDryBicartDrainStartState function set the one time actuation * for bicarb drain request. * @details \b Inputs: dryBiCartDrainRequested, dryBiCartType * @details \b Outputs: valve states, dryBiCartDrainStartTime, dryBiCartDrainTimePeriod * dryBiCartDrainLastCondSampleTime, dryBiCartDrainCondStableCount * @return the next drybicart fluid drain state. *************************************************************************/ static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartDrainStartState( void ) { DRY_BICART_DRAIN_EXEC_STATE_T state = DRY_BICART_DRAIN_START_STATE; if ( TRUE == getU32OverrideValue( &dryBiCartDrainRequested ) ) { if ( TRUE == getU32OverrideValue( &dryBiCartType ) ) { dryBiCartDrainTimePeriod = LARGE_DRY_BICART_MAX_DRAIN_TIME_MS; } else { dryBiCartDrainTimePeriod = SMALL_DRY_BICART_MAX_DRAIN_TIME_MS; } // open bypass valve setValveState( D34_VALV, VALVE_STATE_OPEN ); // TODO: open DD drain setValveState( D53_VALV, VALVE_STATE_OPEN ); // TODO: open iofp drain valve setValveState( M12_VALV, VALVE_STATE_OPEN ); // Open balancing chamber valves valveControlForBCOpenState(); //Close D14 valve setValveState( D14_VALV, VALVE_STATE_CLOSED ); // Run D10 In Open loop mode(max speed 200ml/min) setConcentratePumpTargetSpeed( D10_PUMP, DRAIN_BICART_PUMP_SPEED, DOSING_CONT_VOLUME ); requestConcentratePumpOn( D10_PUMP ); // Run D48 at 1000 rpm,There is no improvement over above 1000 rpm for drain duration. setDialysatePumpTargetRPM( D48_PUMP, DIAL_PUMP_DRAIN_RPM, TRUE ); dryBiCartDrainStartTime = getMSTimerCount(); dryBiCartDrainLastCondSampleTime = dryBiCartDrainStartTime; dryBiCartDrainCondStableCount = 0; state = DRY_BICART_FLUID_DRAIN_STATE; } return state; } /*********************************************************************//** * @brief * The handleDryBicartFluidDrainState function initiates the water drain * from dry bicarbonate cartridge. * @details \b Inputs: none * @details \b Outputs: none * @return the next drybicart drain duration check state. *************************************************************************/ static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainState( void ) { DRY_BICART_DRAIN_EXEC_STATE_T state = DRY_BICART_FLUID_DRAIN_STATE; // Open vent valves and close descaling valve setValveState( D80_VALV, VALVE_STATE_OPEN ); setValveState( D81_VALV, VALVE_STATE_CLOSED ); setValveState( D85_VALV, VALVE_STATE_OPEN ); // Open D64 valve (vent for equilibrium) setValveState( D64_VALV, VALVE_STATE_OPEN ); state = DRY_BICART_FLUID_DRAIN_DURATION_CHECK_STATE; return state; } /*********************************************************************//** * @brief * The handleDryBicartFluidDrainDurationCheckState function monitors conductivity * through D17 and D74 and determines drain completion or drain complete by max timeout * @details \b Inputs: P17_COND, P74_COND, dryBiCartDrainCondStableCount, dryBiCartDrainStartTime * @details \b Outputs: dryBiCartDrainLastCondSampleTime * @return the next drybicart drain end state. *************************************************************************/ static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainDurationCheckState( void ) { // switch back to DRY_BICART_FLUID_DRAIN_STATE if not fully drained or not timeout DRY_BICART_DRAIN_EXEC_STATE_T state = DRY_BICART_FLUID_DRAIN_DURATION_CHECK_STATE; // Max drain time fall back, it is different for small and large bicart, // 4 minutes for small bicart with full of water and 8 minutes for large bicart // TODO: user settings should be derived for large and small dry bicart for drain time out // right now dialin override is provided. if ( TRUE == didTimeout( dryBiCartDrainStartTime, dryBiCartDrainTimePeriod ) ) { state = DRY_BICART_FLUID_DRAIN_END_STATE; // Stop pumps requestConcentratePumpOff( D10_PUMP, FALSE ); signalDialysatePumpHardStop( D48_PUMP ); // Close valves used for drain setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D80_VALV, VALVE_STATE_CLOSED ); setValveState( D85_VALV, VALVE_STATE_CLOSED ); // close bypass valve setValveState( D34_VALV, VALVE_STATE_CLOSED ); // TODO: close DD drain setValveState( D53_VALV, VALVE_STATE_CLOSED ); // TODO : close iofp drain valve setValveState( M12_VALV, VALVE_STATE_CLOSED ); //close all balancing chamber valves valveControlForBCClosedState(); } else { //TODO , disabling conductivity related checks since cond17 and cond74 values reading as zero now #if 0 // Sample conductivity periodically if ( TRUE == didTimeout( dryBiCartDrainLastCondSampleTime, DRY_BICART_DRAIN_COND_SAMPLE_PERIOD_MS ) ) { F32 cond17 = getFilteredConductivity( D17_COND ); F32 cond74 = getFilteredConductivity( D74_COND ); dryBiCartDrainLastCondSampleTime = getMSTimerCount(); // Debounce "zero conductivity" detection if ( ( cond17 <= DRY_BICART_DRAIN_COND_ZERO_THRESH ) && ( cond74 <= DRY_BICART_DRAIN_COND_ZERO_THRESH ) ) { dryBiCartDrainCondStableCount++; } if ( dryBiCartDrainCondStableCount >= DRY_BICART_DRAIN_COND_STABLE_SAMPLES ) { state = DRY_BICART_FLUID_DRAIN_END_STATE; } } #endif } return state; } /*********************************************************************//** * @brief * The handleDryBicartFluidDrainEndState function handles the end state for * draining of the fluid. * @details \b Inputs: dryBiCartDrainRequested * @details \b Outputs: dryBiCartDrainRequested * @return the next drybicart drain start state. *************************************************************************/ static DRY_BICART_DRAIN_EXEC_STATE_T handleDryBicartFluidDrainEndState( void ) { // stay in this state till drain request is cleared so that Drain completion status can be checked DRY_BICART_DRAIN_EXEC_STATE_T state = DRY_BICART_FLUID_DRAIN_END_STATE; // Go idle dryBiCartDrainRequested.data = FALSE; // for this request override also cleared dryBiCartDrainRequested.ovData = FALSE; state = DRY_BICART_DRAIN_START_STATE; return state; } /*********************************************************************//** * @brief * The publishDryBicartData function broadcasts the dry bicart * data at defined interval. * @details \b Inputs: dryBiCartDataPublicationTimerCounter * @details \b Outputs: none * @details \b Message \Sent: MSG_ID_DD_DRY_BICART_DATA to publish the dry bicart * data. * @return none *************************************************************************/ static void publishDryBicartData( void ) { if ( ++dryBiCartDataPublicationTimerCounter >= getDryBicartFillDataPublishInterval() ) { DRY_BICART_DATA_T data; data.dryBiCartFillExecState = (U32)dryBiCartFillExecState; data.bicarbChamberFillExecState = (U32)bicarbChamberFillExecState; data.dryBiCartDrainExecState = (U32)dryBiCartDrainExecState; data.dryBiCartFillCycleCounter = biCartFillCycleCounter; data.dryBiCartMaxFillCycleCount = getU32OverrideValue( &biCartMaxFillCycleCount ); data.dryBiCartFillRequest = getU32OverrideValue( &dryBiCartFillRequested ); data.bicarbChamberFillRequest = getU32OverrideValue( &bicarbChamberFillRequested ); data.dryBiCartDrainRequest = getU32OverrideValue( &dryBiCartDrainRequested ); data.dryBiCartLastFillTime = lastFillDurationInMS; data.dryBiCartCurrentFillTime = currentFillDurationInMS; data.dryBiCartType = getU32OverrideValue( &dryBiCartType ); data.dryBiCartDrainTimePeriod = dryBiCartDrainTimePeriod; // TODO: remove after feature testing memcpy( &data.dryBiCartBicarbDosingControl, &bicarbControlSignals, sizeof( PI_CONTROLLER_SIGNALS_DATA ) ); // TODO: remove after feature testing memcpy( &data.dryBiCartAcidDosingControl , &acidControlSignals , sizeof( PI_CONTROLLER_SIGNALS_DATA ) ); data.dryBiCartAcidDoseVolume = getAcidDoseVol(); data.dryBiCartBicarbDoseVolume = getBicarbDoseVol(); // TODO: remove after feature testing data.dryBiCartBicarbDosingKPgain = getBicarbKpGainCoefficient(); // TODO: remove after feature testing data.dryBiCartBicarbDosingKIgain = getBicarbKiGainCoefficient(); broadcastData( MSG_ID_DD_DRY_BICART_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( DRY_BICART_DATA_T ) ); dryBiCartDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testDDDryBiCartDataPublishIntervalOverride function overrides the * DD dry bicart data publish interval. * @details \b Inputs: dryBiCartDataPublishInterval * @details \b Outputs: dryBiCartDataPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the DD dry bicart data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &dryBiCartDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testDryBiCartFillCycleMaxCountOverride function sets the override value * of the max dry bicart fill cycle count. * @details Inputs: biCartMaxFillCycleCount * @details Outputs: biCartMaxFillCycleCount * @param message Override message from Dialin which includes the override * value to override the max dry bicart fill cycle count. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartFillCycleMaxCountOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &biCartMaxFillCycleCount, 0, DRY_BICART_MAX_FILL_CYCLE_CNT ); return result; } /*********************************************************************//** * @brief * The testDryBiCartFillRequestOverride function starts/stops the dry bicart * fill. * @details \b Inputs: dryBiCartFillRequested * @details \b Outputs: dryBiCartFillRequested * @param message set message from Dialin which includes the dry bicart fill * start/stop. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testDryBiCartFillRequestOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &dryBiCartFillRequested, FALSE, TRUE ); return result; } /*********************************************************************//** * @brief * The testBiCarbChamberFillRequestOverride function starts/stops the bicarb * chamber F fill. * @details \b Inputs: bicarbChamberFillRequested * @details \b Outputs: bicarbChamberFillRequested * @param message set message from Dialin which includes the bicarb chamber * fill start/stop. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testBiCarbChamberFillRequestOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &bicarbChamberFillRequested, FALSE, TRUE ); return result; } /*********************************************************************//** * @brief * The testDryBiCartDrainRequestOverride function starts/stops the bicart * drain request * @details \b Inputs: dryBiCartDrainRequested * @details \b Outputs: dryBiCartDrainRequested * @param message set message from Dialin which includes the bicart * drain request start/stop. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testDryBiCartDrainRequestOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &dryBiCartDrainRequested, FALSE, TRUE ); return result; } /*********************************************************************//** * @brief * The testDryBiCartTypeOverride function selects small/large cartridge type * @details \b Inputs: dryBiCartType * @details \b Outputs: dryBiCartType * @param message set message from Dialin for small/large bicart type * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testDryBiCartTypeOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &dryBiCartType, FALSE, TRUE ); return result; } /*********************************************************************//** * @brief * The testAcidDoseVolumeOverride function sets the override value * of the acid concentrate dosing volume. * @details Inputs: dryBiCartAcidDoseVolume * @details Outputs: dryBiCartAcidDoseVolume * @param message Override message from Dialin which includes the override * value to override the acid concentrate dosing volume. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartAcidDoseVolumeOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartAcidDoseVolume ); return result; } /*********************************************************************//** * @brief * The testBicarbDoseVolumeOverride function sets the override value * of the bicarb concentrate dosing volume. * @details Inputs: dryBiCartBicarbDoseVolume * @details Outputs: dryBiCartBicarbDoseVolume * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate dosing volume. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartBicarbDoseVolumeOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartBicarbDoseVolume ); return result; } /*********************************************************************//** * @brief * The testDryBiCartBicarbKpGainBicarbDoseVolumeOverride function sets the override value * of the Kp gain coefficient for closed loop bicarb dosing volume control * @details Inputs: dryBiCartBicarbDoseVolumeKpGain * @details Outputs: dryBiCartBicarbDoseVolumeKpGain * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate dosing volume kp gain. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartBicarbDoseVolControlKpGainOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartBicarbDoseVolumeKpGain ); initializePIController(PI_CONTROLLER_ID_BICARB_VOL, MIN_BICARB_VOLUME_MLPM,\ getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); return result; } /*********************************************************************//** * @brief * The testDryBiCartBicarbKiGainBicarbDoseVolumeOverride function sets the override value * of the Ki gain coefficient for closed loop bicarb concentrate dosing volume control * @details Inputs: dryBiCartBicarbDoseVolumeKiGain * @details Outputs: dryBiCartBicarbDoseVolumeKiGain * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate dosing volume ki gain. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartBicarbDoseVolControlKiGainOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartBicarbDoseVolumeKiGain ); initializePIController(PI_CONTROLLER_ID_BICARB_VOL, MIN_BICARB_VOLUME_MLPM,\ getBicarbKpGainCoefficient(), getBicarbKiGainCoefficient(),\ MIN_BICARB_VOLUME_MLPM, MAX_BICARB_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_BICARB_VOL, STD_BICARB_DOSING, DOSING_NO_FEED_FORWARD); return result; } /*********************************************************************//** * @brief * The testDryBiCartBicarbKpGainBicarbDoseVolumeOverride function sets the override value * of the Kp gain coefficient for closed loop acid concentrate dosing volume control * @details Inputs: dryBiCartAcidDoseVolumeKpGain * @details Outputs: dryBiCartAcidDoseVolumeKpGain * @param message Override message from Dialin which includes the override * value to override the acid concentrate dosing volume kp gain. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartAcidDoseVolControlKpGainOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartAcidDoseVolumeKpGain ); initializePIController(PI_CONTROLLER_ID_ACID_VOL, MIN_ACID_VOLUME_MLPM, \ getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); return result; } /*********************************************************************//** * @brief * The testDryBiCartBicarbKiGainBicarbDoseVolumeOverride function sets the override value * of the Ki gain coefficient for closed loop acid concentrate dosing volume control * @details Inputs: dryBiCartAcidDoseVolumeKiGain * @details Outputs: dryBiCartAcidDoseVolumeKiGain * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate dosing volume ki gain. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartAcidDoseVolControlKiGainOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartAcidDoseVolumeKiGain ); initializePIController(PI_CONTROLLER_ID_ACID_VOL, MIN_ACID_VOLUME_MLPM, \ getAcidKpGainCoefficient(), getAcidKiGainCoefficient(),\ MIN_ACID_VOLUME_MLPM, MAX_ACID_VOLUME_MLPM, FALSE, DOSING_NO_FEED_FORWARD ); resetPIController(PI_CONTROLLER_ID_ACID_VOL, STD_ACID_DOSING, DOSING_NO_FEED_FORWARD); return result; } /*********************************************************************//** * @brief * The testDryBiCartTargetConductivityOverride function sets the override value * of target conductivity for closed loop control * @details Inputs: dryBiCartTargetConductivity * @details Outputs: dryBiCartTargetConductivity * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate target conductivity. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartTargetConductivityOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartBicarbTargetConductivity ); return result; } /*********************************************************************//** * @brief * The testDryBiCartDeltaConductivityOverride function sets the override value * of delta target conductivity for closed loop control * @details Inputs: dryBiCartDeltaConductivity * @details Outputs: dryBiCartDeltaConductivity * @param message Override message from Dialin which includes the override * value to override the bicarb concentrate delta target conductivity. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartDeltaConductivityOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartBicarbDeltaConductivity ); return result; } /*********************************************************************//** * @brief * The testDryBiCartAcidBicarbTargetConductivityOverride function sets the override value * of acid bicarb mix target conductivity for closed loop control * @details Inputs: dryBiCartAcidBicarbMixTargetConductivity * @details Outputs: dryBiCartAcidBicarbMixTargetConductivity * @param message Override message from Dialin which includes the override * value to override the acid bicarb mix target conductivity. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartAcidBicarbTargetConductivityOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartAcidBicarbMixTargetConductivity ); return result; } /*********************************************************************//** * @brief * The testDryBiCartAcidBicarbDeltaConductivityOverride function sets the override value * of delta target conductivity for acid bicarb mix closed loop control * @details Inputs: dryBiCartDeltaConductivity * * @details Outputs: dryBiCartDeltaConductivity * @param message Override message from Dialin which includes the override * value to override the acid bicarb mix target delta conductivity. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDryBiCartAcidBicarbDeltaConductivityOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &dryBiCartAcidBicarbMixDeltaConductivity ); return result; } /**@}*/