Index: firmware/App/Controllers/DialysatePumps.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Controllers/DialysatePumps.h (.../DialysatePumps.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file DialysatePumps.h * * @author (last) Vinayakam Mani -* @date (last) 13-May-2025 +* @date (last) 13-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 07-Oct-2024 @@ -24,15 +24,15 @@ * @defgroup DialysatePumps DialysatePumps * @brief Dialysate Pumps monitor/controller module. Controls and monitors the dialysate pumps. * Dialysate pump manufacturer: Diener Silencer Series Gear Pumps, PN: 01483-PM-3-RA. - * The pump shall produce flow rates of 350-2700 ml/min. + * The pump shall run at 200(10%) -2700(90%)RPM. * * @addtogroup DialysatePumps * @{ */ // ********** public definitions ********** -#define MIN_DIALYSATE_PUMP_RPM 350 ///< Minimum RPM target for dialysate pump (though zero is allowed if turning pump off). +#define MIN_DIALYSATE_PUMP_RPM 200 ///< Minimum RPM target for dialysate pump (though zero is allowed if turning pump off). #define MAX_DIALYSATE_PUMP_RPM 2650 ///< Maximum RPM target for dialysate pump. #define DEGAS_PUMP_TARGET_PRES_ADJ_THRESHOLD -1.0F ///< Dialysate Pump(D12) target pressure threshold adjustment factor. Index: firmware/App/Controllers/PermeateTank.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Controllers/PermeateTank.c (.../PermeateTank.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Controllers/PermeateTank.c (.../PermeateTank.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file PermeateTank.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -20,6 +20,7 @@ #include "Messaging.h" #include "PermeateTank.h" #include "TaskGeneral.h" +#include "TDInterface.h" #include "Timers.h" #include "Utilities.h" #include "Valves.h" @@ -33,9 +34,12 @@ #define PERMEATE_TANK_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) for permeate tank broadcast #define PERMEATE_TANK_PUBLISH_COUNTER_START_COUNT 9 ///< Publishing counter offset -#define PERMEATE_TANK_FILL_SWITCH_MS ( 10 * MS_PER_SECOND ) ///< state switch timeout in fill state ( in ms ) -#define PERMEATE_TANK_FULL_SWITCH_MS ( 1 * MS_PER_SECOND ) ///< state switch timeout in full state (in ms) -#define PERMEATE_TANK_FULL_TIMEOUT_MS ( 60 * MS_PER_SECOND ) ///< timeout being in full state too long ( in ms ) +#define PERMEATE_TANK_FULL_SWITCH_MS ( 1 * MS_PER_SECOND ) ///< State switch timeout in full state (in ms) +#define PERMEATE_TANK_EMPTY_LEVEL_VOL_ML 0 ///< Permeate tank volume in empty level ( in ml ) +#define PERMEATE_TANK_LOW_LEVEL_VOL_ML 957 ///< Permeate tank volume in low level ( in ml ) +#define PERMEATE_TANK_HIGH_LEVEL_VOL_ML 1345 ///< Permeate tank volume in high level ( in ml ) +#define PERMEATE_TANK_FULL_LEVEL_VOL_ML 1532 ///< Permeate tank volume in full level ( in ml ) +#define RINSE_PUMP_TARGET_FLOW 228.89 ///< Rinse pump rate // ********** private data ********** @@ -44,9 +48,11 @@ static OVERRIDE_U32_T permeateTankPublishInterval; ///< Interval (in ms) at which to publish permeate tank data to CAN bus. static BOOL pendingStartPermeateTankController; ///< Flag indicates an air trap controller start request is pending. static BOOL pendingStopPermeateTankController; ///< Flag indicates an air trap controller stop request is pending. -static U32 tankFullAlarmTimeout; ///< Time stamp to track alarm timeout. +static U32 tankFullAlarmTimer; ///< Time stamp to track alarm timeout during tank full. +static U32 tankFillAlarmTimer; ///< Time stamp to track alarm timeout during tank fill. static U32 tankFullDelayTime; ///< Time stamp to track delay before valve switch. -static U32 tankFillDelayTime; ///< Time stamp to track fill timeout. +static F32 tankFullAlarmTimeout; ///< Permeate tank full alarm timeout +static F32 tankFillAlarmTimeout; ///< Permeate tank fill alarm timeout // ********** private function prototypes ********** @@ -71,9 +77,11 @@ permeateTankPublishInterval.ovData = PERMEATE_TANK_PUMP_DATA_PUB_INTERVAL; permeateTankPublishInterval.ovInitData = PERMEATE_TANK_PUMP_DATA_PUB_INTERVAL; permeateTankPublishInterval.override = OVERRIDE_RESET; - tankFillDelayTime = 0; tankFullDelayTime = 0; - tankFullAlarmTimeout = 0; + tankFullAlarmTimer = 0; + tankFillAlarmTimer = 0; + tankFullAlarmTimeout = 0.0F; + tankFillAlarmTimeout = 0.0F; } /*********************************************************************//** @@ -156,6 +164,46 @@ /*********************************************************************//** * @brief + * The getTankFullAlarmTimeout function returns the tank full alarm timeout + * @details \b Inputs: none + * @details \b Outputs: tankFullAlarmTimeout + * @return the alarm timeout for tank full + *************************************************************************/ +F32 getTankFullAlarmTimeout( void ) +{ + F32 expectedDeprimeTime = 0.0F; + F32 expectedTankFullTime = 0.0F; + F32 ddConsumptionRate = getTDDialysateFlowrate() + RINSE_PUMP_TARGET_FLOW; + + expectedTankFullTime = ( ( PERMEATE_TANK_HIGH_LEVEL_VOL_ML - PERMEATE_TANK_LOW_LEVEL_VOL_ML ) / ddConsumptionRate ) * SEC_PER_MIN; + expectedDeprimeTime = ( ( PERMEATE_TANK_LOW_LEVEL_VOL_ML - PERMEATE_TANK_EMPTY_LEVEL_VOL_ML ) / ddConsumptionRate ) * SEC_PER_MIN; + tankFullAlarmTimeout = expectedTankFullTime + expectedDeprimeTime; + + return tankFullAlarmTimeout; +} + +/*********************************************************************//** + * @brief + * The getTankFillAlarmTimeout function returns the tank fill alarm timeout + * @details \b Inputs: none + * @details \b Outputs: tankFillAlarmTimeout + * @return the alarm timeout for tank fill + *************************************************************************/ +F32 getTankFillAlarmTimeout( void ) +{ + F32 expectedOverfillTime = 0.0F; + F32 expectedTankFillTime = 0.0F; + F32 ddConsumptionRate = getTDDialysateFlowrate() + RINSE_PUMP_TARGET_FLOW; + + expectedTankFillTime = ( ( PERMEATE_TANK_HIGH_LEVEL_VOL_ML - PERMEATE_TANK_LOW_LEVEL_VOL_ML ) / ddConsumptionRate ) * SEC_PER_MIN; + expectedOverfillTime = ( ( PERMEATE_TANK_FULL_LEVEL_VOL_ML - PERMEATE_TANK_HIGH_LEVEL_VOL_ML ) / ddConsumptionRate ) * SEC_PER_MIN; + tankFillAlarmTimeout = ( expectedTankFillTime + ( expectedOverfillTime / 2 ) ); + + return tankFillAlarmTimeout; +} + +/*********************************************************************//** + * @brief * The execPermeateTankController function executes the air trap control state machine. * @details \b Alarm: ALARM_ID_FP_SOFTWARE_FAULT if current permeate tank control * state is invalid. @@ -243,6 +291,11 @@ PERMEATE_TANK_STATE_T state = PERMEATE_TANK_FILL_STATE; LEVEL_STATE_T level = getLevelStatus( P25_LEVL ); + if ( TRUE == didTimeout( tankFillAlarmTimer, getTankFillAlarmTimeout() ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_FP_GEN_PERMEATE_TANK_FILL_TIMEOUT, level ) + } + // Transition to manual valve control state when requested if ( TRUE == pendingStopPermeateTankController ) { @@ -254,13 +307,6 @@ { state = PERMEATE_TANK_FULL_STATE; } - else if ( level == LEVEL_STATE_LOW ) - { - if ( TRUE == didTimeout( tankFillDelayTime, PERMEATE_TANK_FILL_SWITCH_MS ) ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_FP_GEN_PERMEATE_TANK_FILL_TIMEOUT, level ) - } - } return state; } @@ -278,7 +324,7 @@ PERMEATE_TANK_STATE_T state = PERMEATE_TANK_FULL_STATE; LEVEL_STATE_T level = getLevelStatus( P25_LEVL ); - if ( TRUE == didTimeout( tankFullAlarmTimeout, PERMEATE_TANK_FULL_TIMEOUT_MS ) ) + if ( TRUE == didTimeout( tankFullAlarmTimer, getTankFullAlarmTimeout() ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_FP_GEN_PERMEATE_TANK_FULL_TIMEOUT, level ) } @@ -327,20 +373,20 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); // Current set to Medium recovery for alpha HW setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_OPEN ); - tankFillDelayTime = getMSTimerCount(); + tankFillAlarmTimer = getMSTimerCount(); break; case PERMEATE_TANK_FULL_STATE: setValveState( M4_VALV, VALVE_STATE_CLOSED ); setValveState( M12_VALV, VALVE_STATE_CLOSED ); - setValveState( P6_VALV, VALVE_STATE_CLOSED ); + setValveState( P6_VALV, VALVE_STATE_OPEN ); setValveState( P11_VALV, VALVE_STATE_OPEN ); setValveState( P33_VALV, VALVE_STATE_OPEN ); - setValveState( P34_VALV, VALVE_STATE_OPEN ); + setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); tankFullDelayTime = getMSTimerCount(); - tankFullAlarmTimeout = getMSTimerCount(); + tankFullAlarmTimer = getMSTimerCount(); break; default: Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ROPump.c * -* @author (last) Michael Garthwaite -* @date (last) 08-Sep-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -17,6 +17,7 @@ #include // for log() #include "Flow.h" +#include "FPOperationModes.h" //#include "NVDataMgmt.h" #include "Messaging.h" #include "MessageSupport.h" @@ -39,8 +40,8 @@ #define RO_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO Pump data is published on the CAN bus. #define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. -#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.1F ///< P term for RO pump flow control. -#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.8F ///< I term for RO pump flow control. +#define ROP_FLOW_CONTROL_P_COEFFICIENT 0.000065F ///< P term for RO pump flow control. +#define ROP_FLOW_CONTROL_I_COEFFICIENT 0.00022F ///< I term for RO pump flow control. #define ROP_MIN_FLOW_TO_CONTROL_PCT 0.75F #define ROP_PRESSURE_CONTROL_P_COEFFICIENT 0.15F ///< P term for RO pump pressure control. #define ROP_PRESSURE_CONTROL_I_COEFFICIENT 0.65F ///< I term for RO pump pressure control. @@ -57,6 +58,9 @@ #define ROP_FLOW_TO_PWM_PCT(flow) ( ( ROP_FLOW_TO_PWM_SLOPE * log(flow) + ROP_FLOW_TO_PWM_INTERCEPT ) / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) ///< PWM line equation for flow converted to percentage. #define ROP_FLOW_TO_PWM(flow) ( ROP_FLOW_TO_PWM_SLOPE * log(flow) + ROP_FLOW_TO_PWM_INTERCEPT ) ///< PWM line equation for flow converted to percentage. +#define FP_FLOW_RATE_BELOW_TARGET_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Timeout for flow rate below 75% of target flow rate +#define FP_FLOW_RATE_BELOW_TARGET_CLEAR_MS ( 10 * MS_PER_SECOND ) ///< Clear timeout for flow rate below target flow rate + // ********** private data ********** static RO_PUMP_STATE_T roPumpState; ///< Current state of pump controller state machine. @@ -104,6 +108,8 @@ initializePIController( PI_CONTROLLER_ID_RO_PUMP_PRES, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, ROP_PRESSURE_CONTROL_P_COEFFICIENT, ROP_PRESSURE_CONTROL_I_COEFFICIENT, MIN_FLUID_PUMP_DUTY_CYCLE_PCT, MAX_FLUID_PUMP_DUTY_CYCLE_PCT, FALSE, 0 ); + initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_RATE_BELOW_TARGET, FP_FLOW_RATE_BELOW_TARGET_CLEAR_MS, FP_FLOW_RATE_BELOW_TARGET_TIMEOUT_MS ); + roPumpState = RO_PUMP_OFF_STATE; isROPumpOn = FALSE; stopPumpRequest = FALSE; @@ -123,9 +129,9 @@ targetROPumpPressure.ovData = 0.0F; targetROPumpPressure.ovInitData = 0.0F; targetROPumpPressure.override = OVERRIDE_RESET; - roPumpOpenLoopTargetDutyCycle.data = 0; - roPumpOpenLoopTargetDutyCycle.ovData = 0; - roPumpOpenLoopTargetDutyCycle.ovInitData = 0; + roPumpOpenLoopTargetDutyCycle.data = 0.0; + roPumpOpenLoopTargetDutyCycle.ovData = 0.0; + roPumpOpenLoopTargetDutyCycle.ovInitData = 0.0; roPumpOpenLoopTargetDutyCycle.override = OVERRIDE_RESET; stopROPump(); @@ -241,14 +247,22 @@ if ( getTargetROPumpFlowRateMLPM() > 0 ) { ///transition to closed loop - resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, getTargetROPumpDutyCyclePCT(), 0 ); + if ( getCurrentFPOperationMode() == FP_MODE_GENP ) + { + roPumpDutyCyclePctSet = getCurrentROPumpDutyCyclePCT(); + } + else + { + roPumpDutyCyclePctSet = roPumpFlowToPWM( getTargetROPumpFlowRateMLPM() ); + } + resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, roPumpDutyCyclePctSet, 0.0F ); state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; } // If there is a target pressure set, transition to the PI controller and control to pressure. else if ( getTargetROPumpPressure() > 0.0F ) { //transition to closed loop - resetPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, getTargetROPumpPressure(), 0 ); + resetPIController( PI_CONTROLLER_ID_RO_PUMP_PRES, getTargetROPumpPressure(), 0.0F ); state = RO_PUMP_CONTROL_TO_TARGET_PRESSURE_STATE; } else if ( (F32)getTargetROPumpDutyCyclePCT() == 0.0F ) @@ -271,6 +285,9 @@ { RO_PUMP_STATE_T state = RO_PUMP_CONTROL_TO_TARGET_FLOW_STATE; F32 nexttgtflow = 0.0; + F32 currentFlowRate = 0.0; + F32 adjustedFlowRRate = 0.0; + BOOL isFlowRateLow = FALSE; // Check if need to switch control modes if ( getTargetROPumpPressure() > 0.0F ) @@ -293,20 +310,27 @@ } else if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) { + currentFlowRate = getFilteredFlow( P16_FLOW ); + adjustedFlowRRate = (F32)getTargetROPumpFlowRateMLPM() * ROP_MIN_FLOW_TO_CONTROL_PCT; + // P16 flow seems to lag in current Leahi HW. We will wait till we hit a % of target flow before we start changing control. - if( ( TRUE == roPumpStartControl ) || ( getFilteredFlow( P16_FLOW ) >= ( (F32)getTargetROPumpFlowRateMLPM() * ROP_MIN_FLOW_TO_CONTROL_PCT ) ) ) + if( ( TRUE == roPumpStartControl ) || ( currentFlowRate >= ( adjustedFlowRRate ) ) ) { - //roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), getFilteredFlow( P16_FLOW ) ); - //setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); - nexttgtflow = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), getFilteredFlow( P16_FLOW ) ); - nexttgtflow = (U16)MIN( ROP_FLOW_TO_PWM( nexttgtflow ), ( MAX_FLUID_PUMP_PWM_DUTY_CYCLE * MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ); - setFluidPumpPWMDutyCycle( P12_PUMP, nexttgtflow ); + roPumpDutyCyclePctSet = runPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, (F32)getTargetROPumpFlowRateMLPM(), currentFlowRate ); + roPumpDutyCyclePctSet = MIN( roPumpDutyCyclePctSet, ( MAX_FLUID_PUMP_PWM_DUTY_CYCLE * MAX_FLUID_PUMP_DUTY_CYCLE_PCT ) ); + setFluidPumpPctToPWMDutyCycle( P12_PUMP, roPumpDutyCyclePctSet ); + if ( FALSE == roPumpStartControl ) { roPumpStartControl = TRUE; } } roControlTimerCounter = 0; + + //is flow rate less than 75% of the target flow rate + // wait for 10 seconds for timeout + isFlowRateLow = ( ( currentFlowRate < ( adjustedFlowRRate ) ) ? TRUE : FALSE); + checkPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_RATE_BELOW_TARGET, isFlowRateLow, currentFlowRate, adjustedFlowRRate); } return state; @@ -586,7 +610,7 @@ * The roPumpPresToPWM function calculates the duty cycle for the given target * pressure. * @details \b Inputs: none - * @details \b Outputs: dutyCyclePct + * @details \b Outputs: none * @param targetPressure target pressure value to control in PSI * @return the current target RO pump PWM in a percentage. *************************************************************************/ @@ -602,7 +626,7 @@ * The roPumpFlowToPWM function calculates the duty cycle for the given target * flow rate. * @details \b Inputs: none - * @details \b Outputs: dutyCyclePct + * @details \b Outputs: none * @param targetFlow target flow value to control in in mL/min * @return the current target RO pump PWM in a percentage. *************************************************************************/ @@ -615,10 +639,11 @@ /*********************************************************************//** * @brief - * The signalROPumpStop function stops the P12 pump immediately and + * The signalROPumpHardStop function stops the P12 pump immediately and * resets all the variables associated with the P12 pump run. - * @details \b Inputs: roPumpState[] - * @details \b Outputs: stopPumpRequest[] + * @details \b Inputs: targetROPumpFlowRate, targetROPumpPressure + * @details \b Outputs: roPumpState, roPumpDutyCyclePctSet, roControlTimerCounter, + * roPumpOpenLoopTargetDutyCycle, targetROPumpFlowRate, targetROPumpPressure * @return none *************************************************************************/ void signalROPumpHardStop( void ) @@ -727,8 +752,10 @@ * @brief * The testROPumpTargetPressureOverride function overrides the RO pump * data publish interval. - * @details \b Inputs: targetROPumpPressure - * @details \b Outputs: targetROPumpPressure + * @details \b Inputs: targetROPumpPressure, targetROPumpFlowRate, + * roPumpOpenLoopTargetDutyCycle + * @details \b Outputs: targetROPumpPressure, targetROPumpFlowRate, + * roPumpOpenLoopTargetDutyCycle * @param message Override message from Dialin which includes the value * of the target pressure * @return TRUE if override successful, FALSE if not @@ -776,8 +803,10 @@ * @brief * The testROPumpTargetFlowOverride function overrides the RO pump * data publish interval. - * @details \b Inputs: targetROPumpFlowRate - * @details \b Outputs: targetROPumpFlowRate + * @details \b Inputs: targetROPumpFlowRate, roPumpOpenLoopTargetDutyCycle, + * targetROPumpPressure + * @details \b Outputs: targetROPumpFlowRate, roPumpOpenLoopTargetDutyCycle, + * targetROPumpPressure * @param message Override message from Dialin which includes the value * of the target flow * @return TRUE if override successful, FALSE if not @@ -825,8 +854,10 @@ * @brief * The testROPumpTargetDutyCycleOverride function overrides the RO pump * duty cycle. - * @details \b Inputs: roPumpOpenLoopTargetDutyCycle - * @details \b Outputs: roPumpOpenLoopTargetDutyCycle + * @details \b Inputs: roPumpOpenLoopTargetDutyCycle, targetROPumpPressure, + * targetROPumpFlowRate + * @details \b Outputs: roPumpOpenLoopTargetDutyCycle, targetROPumpPressure, + * targetROPumpFlowRate * @param message Override message from Dialin which includes the value * of the target flow * @return TRUE if override successful, FALSE if not @@ -873,8 +904,8 @@ /*********************************************************************//** * @brief * The testBoostPumpHardStopOverride function stops the RO pump. - * @details \b Inputs: boostPumpOpenLoopTargetDutyCycle - * @details \b Outputs: boostPumpOpenLoopTargetDutyCycle + * @details \b Inputs: roPumpOpenLoopTargetDutyCycle + * @details \b Outputs: roPumpOpenLoopTargetDutyCycle * @param message Override message from Dialin which includes the value * of the target flow * @return TRUE if override successful, FALSE if not Index: firmware/App/Controllers/SpentChamberFill.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Controllers/SpentChamberFill.h (.../SpentChamberFill.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Controllers/SpentChamberFill.h (.../SpentChamberFill.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file SpentChamberFill.h * * @author (last) Vinayakam Mani -* @date (last) 26-Aug-2025 +* @date (last) 13-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 21-Aug-2025 @@ -33,7 +33,7 @@ #define FRESH_DIAL_FILL_PRESSURE_MIN_PSIG 22.0F ///< Minimum fresh dialysate pressure (D18) limit for spent chamber fill operations. #define FRESH_DIAL_FILL_PRESSURE_MAX_PSIG 30.0F ///< Maximum fresh dialysate pressure (D18) limit for spent chamber fill operations. -#define SPENT_DIAL_FILL_PRESSURE_MIN_PSIG 24.0F ///< Minimum spent dialysate pressure (D51) limit for spent chamber fill operations. +#define SPENT_DIAL_FILL_PRESSURE_MIN_PSIG -10.0F ///< Minimum spent dialysate pressure (D51) limit for spent chamber fill operations. #define SPENT_DIAL_FILL_PRESSURE_MAX_PSIG 30.0F ///< Maximum spent dialysate pressure (D51) limit for spent chamber fill operations. /// spent chamber fill data structure Index: firmware/App/DDCommon.h =================================================================== diff -u -r8da32de696045734940af89ccd1457bf826b367e -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 8da32de696045734940af89ccd1457bf826b367e) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file DDCommon.h * * @author (last) Vinayakam Mani -* @date (last) 03-Sep-2025 +* @date (last) 14-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 @@ -54,6 +54,9 @@ //Uncomment below for bicarb chamber filling //#define __BICARB_CHAMBER_FILL__ 1 +//Uncomment below for Maxon controller speed change +//#define __MAXON_SPEED_UPDATE__ 1 + #include #include #endif Index: firmware/App/Drivers/FluidPump.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Drivers/FluidPump.c (.../FluidPump.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Drivers/FluidPump.c (.../FluidPump.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FluidPump.c * -* @author (last) Michael Garthwaite -* @date (last) 08-Sep-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -313,7 +313,7 @@ *************************************************************************/ F32 convertDutyCycleCntToPct( U32 dutyCycleCnt ) { - F32 pwmCnt = (F32)MAX( ( dutyCycleCnt / MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) , MIN_FLUID_PUMP_PWM_DUTY_CYCLE ); + F32 pwmCnt = MAX( ( (F32)dutyCycleCnt / (F32)MAX_FLUID_PUMP_PWM_DUTY_CYCLE ) , (F32)MIN_FLUID_PUMP_PWM_DUTY_CYCLE ); return pwmCnt; } Index: firmware/App/Drivers/TemperatureSensors.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file TemperatureSensors.c * -* @author (last) Michael Garthwaite -* @date (last) 10-Nov-2025 +* @author (last) Vinayakam Mani +* @date (last) 18-Sep-2025 * * @author (original) Vinayakam Mani * @date (original) 25-Sep-2024 Index: firmware/App/Modes/FPModes/FPModeFault.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FPModeFault.c (.../FPModeFault.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FPModeFault.c (.../FPModeFault.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FPModeFault.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -299,10 +299,11 @@ } } } - // Defeatured System. Only have m4 to control + // Defeatured System. Only have m4 and m12 to control else { - setValveState( M4_VALV, VALVE_STATE_CLOSED); + setValveState( M4_VALV, VALVE_STATE_CLOSED ); + setValveState( M12_VALV, VALVE_STATE_CLOSED ); } } Index: firmware/App/Modes/FPModes/FPModeStandby.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FPModeStandby.c (.../FPModeStandby.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FPModeStandby.c (.../FPModeStandby.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FPModeStandby.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -20,6 +20,7 @@ #include "FPOperationModes.h" #include "ModePreGenPermeateDefeatured.h" #include "ModePreGenPermeate.h" +#include "PermeateTank.h" #include "PersistentAlarm.h" #include "ROPump.h" #include "SystemCommDD.h" @@ -65,6 +66,7 @@ { initFPStandbyMode(); + resetPermeateTank(); setValveState( M4_VALV,VALVE_STATE_CLOSED ); setValveState( M12_VALV, VALVE_STATE_CLOSED ); setValveState( P6_VALV,VALVE_STATE_CLOSED ); Index: firmware/App/Modes/FPModes/FPOperationModes.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FPOperationModes.c (.../FPOperationModes.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FPOperationModes.c (.../FPOperationModes.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FPOperationModes.c * -* @author (last) Michael Garthwaite -* @date (last) 30-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -131,7 +131,7 @@ // Is requested new mode valid and legal at this time? if ( ( newMode >= FP_MODE_NLEG ) && ( isTestingActivated() != TRUE ) ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, newMode ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, newMode ) newMode = currentMode; } @@ -181,7 +181,7 @@ break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, currentMode ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_OP_MODES_INVALID_MODE_STATE, currentMode ) currentMode = FP_MODE_FAUL; currentSubMode = 0; break; @@ -220,7 +220,7 @@ } else { // Invalid mode requested - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, newMode ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, newMode ) } } @@ -348,7 +348,7 @@ default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, newMode ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, newMode ) break; } } @@ -405,7 +405,7 @@ * The isFPDefeatured function returns if the Leahi device is defeatured. * @details \b Inputs: none * @details \b Outputs: none - * @return the boolean if the FP device is defeatured. + * @return TRUE if FP device is de-featured, FALSE if not. *************************************************************************/ BOOL isFPDefeatured( void ) { @@ -419,7 +419,7 @@ * has a boost pump installed. * @details \b Inputs: none * @details \b Outputs: none - * @return the boolean if boost pump is installed. + * @return TRUE if FP device is contains a boost pump, FALSE if not. *************************************************************************/ BOOL isBoostPumpInstalled( void ) { @@ -433,21 +433,29 @@ * has a boost pump installed. * @details \b Inputs: none * @details \b Outputs: none - * @return the rejection reason codes for stopping generate permeate. + * @return the rejection reason code for stopping generate permeate. *************************************************************************/ REQUEST_REJECT_REASON_CODE_T signalStopGenPermeate( void ) { REQUEST_REJECT_REASON_CODE_T reason = REQUEST_REJECT_REASON_NONE; + BOOL result = FALSE; + // Stop is agnostic to defeatured/featured. // As long as were not in fault or POST, request to go to standby to stop - if ( currentMode >= FP_MODE_STAN ) + if ( TRUE == isFPDefeatured() ) { - requestNewFPOperationMode( FP_MODE_STAN ); + result = requestPreGenDefStop(); } else { + result = requestPreGenStop(); + } + + if ( FALSE == result ) + { reason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } + return reason; } @@ -457,20 +465,28 @@ * has a boost pump installed. * @details \b Inputs: none * @details \b Outputs: none - * @return the rejection reason codes for starting generate permeate. + * @return the rejection reason code for starting generate permeate. *************************************************************************/ REQUEST_REJECT_REASON_CODE_T signalStartGenPermeate( void ) { REQUEST_REJECT_REASON_CODE_T reason = REQUEST_REJECT_REASON_NONE; + BOOL result = FALSE; + // TODO - Service and disinfection checks happen here. if ( TRUE == isFPDefeatured() ) { - requestNewFPOperationMode( FP_MODE_DPGP ); + result = requestPreGenDefStart(); } else { - requestNewFPOperationMode( FP_MODE_PGEN ); + result = requestPreGenStart(); } + + if ( FALSE == result ) + { + reason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } + return reason; } Index: firmware/App/Modes/FPModes/FlushConcentrate.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FlushConcentrate.c (.../FlushConcentrate.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FlushConcentrate.c (.../FlushConcentrate.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file FlushConcentrate.c * * @author (last) “rkallala” -* @date (last) 24-Oct-2025 +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -20,6 +20,7 @@ #include "FlowSensor.h" #include "FlushConcentrate.h" #include "FPOperationModes.h" +#include "Level.h" #include "MessageSupport.h" #include "Messaging.h" #include "PermeateTank.h" @@ -39,23 +40,27 @@ #define CONCENTRATE_FLUSH_MAX_TIMEOUT ( 600 * MS_PER_SECOND ) ///< Max override timeout for 10 minutes #define CONCENTRATE_FLUSH_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen water mode data published. #define CONCENTRATE_FLUSH_TIMEOUT ( 30 * MS_PER_SECOND ) ///< Concentrate flush timer (in ms) -#define CONCENTRATE_FLUSH_RO_PUMP_TGT_PWM 0.8F ///< target in PWM % for the RO pump during concentrate flush. +#define CONCENTRATE_FLUSH_RO_PUMP_TGT_PWM 0.75F ///< target in PWM % for the RO pump during concentrate flush. #define CONCENTRATE_FLUSH_BOOST_PUMP_TGT_PSI 25 ///< Pressure target in PSI for the boost pump during concentrate flush. #define CONCENTRATE_FLUSH_VOLUME_THRESHOLD_ML 1000.0F ///< Integrated volume threshold in ml #define CONCENTRATE_FLUSH_VOLUME_THRESHOLD_PCT 0.9F ///< Integrated volume threshold percentage #define CONCENTRATE_FLUSH_VOLUME_THRESHOLD CONCENTRATE_FLUSH_VOLUME_THRESHOLD_ML * CONCENTRATE_FLUSH_VOLUME_THRESHOLD_PCT ///< alarm threshold for integrated volume +#define CONCENTRATE_FLUSH_WAIT_FOR_TANK_FULL_TIMEOUT ( 60 * MS_PER_SECOND ) ///< Concentrate flush wait for tank full timer (in ms) +#define CONCENTRATE_FLUSH_WAIT_FOR_TANK_FULL_TGT_FLOW 700 ///< target flow rate for waiting for tank state +#define CONCENTRATE_FLUSH_BOOST_PUMP_TGT_PSI 25 ///< Pressure target in PSI for the boost pump during concentrate flush. +#define MIN_BOOST_PUMP_DUTY_CYCLE_PCT 0.5F ///< Minimum duty cycle value for boost pump during open loop control + // ********** private data ********** -static const F32 CONCENTRATE_FLOW_INTEGRATOR = 1.0F / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); ///< Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. static FP_CONC_FLUSH_STATE_T concentrateFlushState; ///< Currently active Concentrate flush state. static U32 concentrateFlushDataPublicationTimerCounter; ///< Used to schedule Concentrate flush data publication to CAN bus. static OVERRIDE_U32_T concentrateFlushDataPublishInterval; ///< Concentrate Flush mode data publish interval. static OVERRIDE_U32_T concentrateFlushTimeout; ///< Concentrate Flush timeout value static U32 concentrateFlushTimer; ///< Concentrate Flush timeout timer static BOOL pendingStartConcentrateFlushRequest; ///< signal to start flushing. static BOOL isFlushComplete; ///< Concentrate Flush complete BOOL -static F32 cumulativeConcentrateVolume_mL; ///< cumulative concentrate volume for integrated volume +static BOOL isTankFilled; ///< Concentrate tank filled in permeate flush state // ********** private function prototypes ********** @@ -88,7 +93,7 @@ concentrateFlushTimer = 0; isFlushComplete = FALSE; pendingStartConcentrateFlushRequest = FALSE; - cumulativeConcentrateVolume_mL = 0.0F; + isTankFilled = FALSE; } /*********************************************************************//** @@ -131,35 +136,45 @@ /*********************************************************************//** * @brief * The handleConcentrateFlushProgressState handles the in progress state of Concentrate flush - * @details \b Inputs: none - * @details \b Outputs: none + * @details \b Inputs: concentrateFlushTimer + * @details \b Outputs: isFlushComplete * @return the next state of Concentrate flush state *************************************************************************/ static FP_CONC_FLUSH_STATE_T handleConcentrateFlushProgressState( void ) { FP_CONC_FLUSH_STATE_T state = CONC_FLUSH_IN_PROGRESS; - BOOL isVolumeOutOfRange = FALSE; + LEVEL_STATE_T level = getLevelStatus( P25_LEVL ); // if ( TRUE == 1 ) )// TODO Alarm and Stop State Rework // { // state = CONC_FLUSH_PAUSED; // } - // TODO - Condition is to be removed once P7 flow meter is removed. - cumulativeConcentrateVolume_mL = getFlowRate( P7_FLOW ) * CONCENTRATE_FLOW_INTEGRATOR; - if( TRUE == didTimeout( concentrateFlushTimer, getConcentrateFlushTimeout() ) ) + if ( TRUE == didTimeout( concentrateFlushTimer, getConcentrateFlushTimeout() ) ) { - isVolumeOutOfRange = ( cumulativeConcentrateVolume_mL >= CONCENTRATE_FLUSH_VOLUME_THRESHOLD ? TRUE : FALSE ); - - if( FALSE == isVolumeOutOfRange ) - { isFlushComplete = TRUE; state = CONC_FLUSH_PAUSED; + } + // Manual control of Permeate tank to prevent over fill. + if ( LEVEL_STATE_HIGH == level ) + { + setValveState( M4_VALV, VALVE_STATE_CLOSED ); + if ( TRUE == isBoostPumpInstalled() ) + { + F32 currentDutyCyclePct = getCurrentBoostPumpDutyCyclePCT() > MIN_BOOST_PUMP_DUTY_CYCLE_PCT ? getCurrentBoostPumpDutyCyclePCT(): MIN_BOOST_PUMP_DUTY_CYCLE_PCT; + + setBoostPumpTargetDutyCycle( currentDutyCyclePct ); + isTankFilled = TRUE; } - else + } + else if ( LEVEL_STATE_LOW == level ) + { + setValveState( M4_VALV, VALVE_STATE_OPEN ); + // set boost pump to closed loop when M4 closed. Added Tank fill check to avoid reset during initial transition + if ( ( TRUE == isBoostPumpInstalled() ) && ( TRUE == isTankFilled ) ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_CONCENTRATE_FLUSH_VOLUME_OUT_OF_RANGE, CONCENTRATE_FLUSH_VOLUME_THRESHOLD, cumulativeConcentrateVolume_mL) - state = CONC_FLUSH_PAUSED; + setBoostPumpTargetPressure( CONCENTRATE_FLUSH_BOOST_PUMP_TGT_PSI ); + isTankFilled = FALSE; } } @@ -168,9 +183,9 @@ /*********************************************************************//** * @brief - * The handleConcentrateFlushProgressState handles the in progress state of Concentrate flush - * @details \b Inputs: none - * @details \b Outputs: none + * The handleConcentrateFlushPausedState handles the paused state of Concentrate flush + * @details \b Inputs: pendingStartConcentrateFlushRequest + * @details \b Outputs: isFlushComplete, pendingStartConcentrateFlushRequest * @return the next state of Concentrate flush state *************************************************************************/ static FP_CONC_FLUSH_STATE_T handleConcentrateFlushPausedState( void ) @@ -210,14 +225,12 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_OPEN ); setValveState( P39_VALV, VALVE_STATE_OPEN ); - startPermeateTankControl(); if ( TRUE == isBoostPumpInstalled() ) { setBoostPumpTargetPressure( CONCENTRATE_FLUSH_BOOST_PUMP_TGT_PSI ); } setROPumpTargetDutyCycle( CONCENTRATE_FLUSH_RO_PUMP_TGT_PWM, TRUE ); concentrateFlushTimer = getMSTimerCount(); - cumulativeConcentrateVolume_mL = 0; break; case CONC_FLUSH_PAUSED: @@ -232,7 +245,6 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); - if ( TRUE == isBoostPumpInstalled() ) { signalBoostPumpHardStop(); Index: firmware/App/Modes/FPModes/FlushFilter.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FlushFilter.c (.../FlushFilter.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FlushFilter.c (.../FlushFilter.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,14 +7,15 @@ * * @file FlushFilter.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 * ***************************************************************************/ +#include "BoostPump.h" #include "FlushFilter.h" #include "FPOperationModes.h" #include "MessageSupport.h" @@ -23,6 +24,7 @@ #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" +#include "WaterQualityMonitor.h" /** * @addtogroup FPFilterFlush @@ -33,8 +35,8 @@ #define FILTER_FLUSH_MAX_TIMEOUT ( 600 * MS_PER_SECOND ) ///< Max override timeout for 10 minutes #define FILTER_FLUSH_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen water mode data published. -#define FILTER_FLUSH_TIMEOUT ( 30 * MS_PER_SECOND ) ///< filter flush timer (in ms) -#define FILTER_HEALTH_PRESSURE_DIFF 15 ///< Filter flush pressure difference threshold for alarm +#define FILTER_FLUSH_TIMEOUT ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Filter flush timeout for 3 minutes (in ms) +#define FILTER_FLUSH_BOOST_PUMP_TGT_PSI 25 ///< Pressure target in PSI for the boost pump during filter flush. // ********** private data ********** @@ -96,6 +98,7 @@ { case FILTER_FLUSH_IN_PROGRESS: filterFlushState = handleFilterFlushProgressState(); + checkInletTemperatures(); break; case FILTER_FLUSH_PAUSED: @@ -120,14 +123,12 @@ * @brief * The handleFilterFlushProgressState handles the in progress state of filter flush * @details \b Inputs: filterFlushTimer - * @details \b Outputs: none + * @details \b Outputs: isFlushComplete * @return the next state of filter flush state *************************************************************************/ static FP_FILTER_FLUSH_STATE_T handleFilterFlushProgressState( void ) { FP_FILTER_FLUSH_STATE_T state = FILTER_FLUSH_IN_PROGRESS; - BOOL isPressureOutOfRange = FALSE; - F32 pressureDif = 0.0; // if ( TRUE == 1 )// TODO Alarm and Stop State Rework // { @@ -136,27 +137,16 @@ if( TRUE == didTimeout( filterFlushTimer, getFilterFlushTimeout() ) ) { - pressureDif = fabs( getFilteredPressure(M3_PRES) - getFilteredPressure(P8_PRES) ); - isPressureOutOfRange = ( pressureDif > FILTER_HEALTH_PRESSURE_DIFF ? TRUE : FALSE ); - - if( TRUE == isPressureOutOfRange ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_FILTER_HEALTH_PRESSURE_OUT_OF_RANGE, pressureDif, FILTER_HEALTH_PRESSURE_DIFF ); - state = FILTER_FLUSH_PAUSED; - } - else - { - isFlushComplete = TRUE; - state = FILTER_FLUSH_PAUSED; - } + isFlushComplete = TRUE; + state = FILTER_FLUSH_PAUSED; } return state; } /*********************************************************************//** * @brief - * The handleFilterFlushProgressState handles the in progress state of filter flush + * The handleFilterFlushPausedState handles the pause state of filter flush * @details \b Inputs: pendingStartFilterFlushRequest * @details \b Outputs: pendingStartFilterFlushRequest, isFlushComplete * @return the next state of filter flush state @@ -199,6 +189,10 @@ setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_OPEN ); filterFlushTimer = getMSTimerCount(); + if ( TRUE == isBoostPumpInstalled() ) + { + setBoostPumpTargetPressure( FILTER_FLUSH_BOOST_PUMP_TGT_PSI ); + } break; case FILTER_FLUSH_PAUSED: @@ -213,6 +207,10 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); + if ( TRUE == isBoostPumpInstalled() ) + { + signalBoostPumpHardStop(); + } } break; Index: firmware/App/Modes/FPModes/FlushPermeate.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/FlushPermeate.c (.../FlushPermeate.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/FlushPermeate.c (.../FlushPermeate.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FlushPermeate.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -19,9 +19,9 @@ #include "Conductivity.h" #include "FlushPermeate.h" #include "FPOperationModes.h" +#include "Level.h" #include "MessageSupport.h" #include "Messaging.h" -#include "PermeateTank.h" #include "Pressure.h" #include "ROPump.h" #include "TaskGeneral.h" @@ -35,13 +35,14 @@ // ********** private definitions ********** -#define PERMEATE_FLUSH_MAX_TIMEOUT ( 600 * MS_PER_SECOND ) ///< Max override timeout for 10 minutes +#define PERMEATE_FLUSH_MAX_TIMEOUT ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Max override timeout for 10 minutes #define PERMEATE_FLUSH_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen water mode data published. -#define PERMEATE_FLUSH_TIMEOUT ( 120 * MS_PER_SECOND ) ///< Permeate flush timer (in ms) -#define PERMEATE_FLUSH_ALARM_TIMEOUT ( 180 * MS_PER_SECOND ) ///< Permeate flush alarm timer (in ms) +#define PERMEATE_FLUSH_TIMEOUT ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Permeate flush timer (in ms) timeout for 2 minutes +#define PERMEATE_FLUSH_ALARM_TIMEOUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Permeate flush alarm timer (in ms) timeout for 5 minutes #define PERMEATE_FLUSH_RO_PUMP_TGT_ML 700 ///< Pressure target in ml/min for the RO pump during permeate flush. #define PERMEATE_FLUSH_BOOST_PUMP_TGT_PSI 25 ///< Pressure target in PSI for the boost pump during permeate flush. #define PERMEATE_FLUSH_CONDUCTIVITY_THRESHOLD 200.0F ///< Conductivity alarm threshold for permeate flush. +#define MIN_BOOST_PUMP_DUTY_CYCLE_PCT 0.5F ///< Minimum duty cycle value for boost pump during open loop control // ********** private data ********** @@ -54,6 +55,7 @@ static U32 permeateFlushAlarmTimer; static BOOL pendingStartPermeateFlushRequest; ///< signal to start flushing. static BOOL isFlushComplete; ///< Permeate Flush complete BOOL +static BOOL isTankFilled; ///< Permeate tank filled in permeate flush state // ********** private function prototypes ********** @@ -92,6 +94,7 @@ permeateFlushAlarmTimer = 0; isFlushComplete = FALSE; pendingStartPermeateFlushRequest = FALSE; + isTankFilled = FALSE; } /*********************************************************************//** @@ -141,25 +144,51 @@ static FP_PERM_FLUSH_STATE_T handlePermeateFlushProgressState( void ) { FP_PERM_FLUSH_STATE_T state = PERM_FLUSH_IN_PROGRESS; + LEVEL_STATE_T level = getLevelStatus( P25_LEVL ); // if ( TRUE == 1 ))// TODO Alarm and Stop State Rework // { // state = PERM_FLUSH_PAUSED; // } - if( TRUE == didTimeout( permeateFlushTimer, getPermeateFlushTimeout() ) ) + // Manual control of Permeate tank while in Permeate Flush + // to prevent overfill. + if ( LEVEL_STATE_HIGH == level ) { + setValveState( M4_VALV, VALVE_STATE_CLOSED ); + if ( TRUE == isBoostPumpInstalled() ) + { + // TODO update the default min duty cycle value after testing + F32 currentDutyCyclePct = getCurrentBoostPumpDutyCyclePCT() > MIN_BOOST_PUMP_DUTY_CYCLE_PCT ? getCurrentBoostPumpDutyCyclePCT(): MIN_BOOST_PUMP_DUTY_CYCLE_PCT; + + setBoostPumpTargetDutyCycle( currentDutyCyclePct ); + isTankFilled = TRUE; + } + } + else if ( LEVEL_STATE_LOW == level ) + { + setValveState( M4_VALV, VALVE_STATE_OPEN ); + // set boost pump to closed loop when M4 closed. Added Tank fill check to avoid reset during initial transition + if ( ( TRUE == isBoostPumpInstalled() ) && ( TRUE == isTankFilled ) ) + { + setBoostPumpTargetPressure( PERMEATE_FLUSH_BOOST_PUMP_TGT_PSI ); + isTankFilled = FALSE; + } + } + + if ( TRUE == didTimeout( permeateFlushTimer, getPermeateFlushTimeout() ) ) + { F32 p18conductivity = getFilteredConductivity( P18_COND ); - if( PERMEATE_FLUSH_CONDUCTIVITY_THRESHOLD > p18conductivity ) + if ( ( PERMEATE_FLUSH_CONDUCTIVITY_THRESHOLD > p18conductivity ) && ( LEVEL_STATE_HIGH == level ) ) { isFlushComplete = TRUE; state = PERM_FLUSH_PAUSED; } - // If conductivity is not in range, continue to monitor until timeout + // If conductivity is not in range, continue to monitor until timeout, TODO if conductivity fluctuates for another 3 minutes else { - if( TRUE == didTimeout( permeateFlushAlarmTimer, getPermeateFlushAlarmTimeout() ) ) + if ( TRUE == didTimeout( permeateFlushAlarmTimer, getPermeateFlushAlarmTimeout() ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_PERMEATE_FLUSH_CONDUCTIVITY_TIMEOUT, PERMEATE_FLUSH_CONDUCTIVITY_THRESHOLD, p18conductivity) state = PERM_FLUSH_PAUSED; @@ -215,7 +244,6 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_OPEN ); - startPermeateTankControl(); if ( TRUE == isBoostPumpInstalled() ) { setBoostPumpTargetPressure( PERMEATE_FLUSH_BOOST_PUMP_TGT_PSI ); @@ -239,7 +267,6 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_CLOSED ); - if ( TRUE == isBoostPumpInstalled() ) { signalBoostPumpHardStop(); Index: firmware/App/Modes/FPModes/ModeGenPermeate.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/ModeGenPermeate.c (.../ModeGenPermeate.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/ModeGenPermeate.c (.../ModeGenPermeate.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModeGenPermeate.c * -* @author (last) Michael Garthwaite -* @date (last) 08-Sep-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -17,6 +17,7 @@ #include "BoostPump.h" #include "FPInterface.h" +#include "Flow.h" #include "FPModeStandby.h" #include "FPOperationModes.h" #include "Level.h" @@ -25,10 +26,12 @@ #include "ModeGenPermeate.h" #include "ModePreGenPermeate.h" #include "PermeateTank.h" +#include "PIControllers.h" #include "ROPump.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" +#include "WaterQualityMonitor.h" /** * @addtogroup FPGenPermeateMode @@ -37,15 +40,29 @@ // ********** private definitions ********** -#define PRE_GEN_PERMEATE_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen permeate mode data published. -#define GEN_PERMEATE_BOOST_PUMP_TGT_PSI 25.0F ///< Pressure target in PSI for the boost pump during generate permeate mode. -#define GEN_PERMEATE_RO_PUMP_TGT_ML 700 ///< Flow target in ml/min for the ro pump during generate permeate mode. +#define PRE_GEN_PERMEATE_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen permeate mode data published. +#define GEN_PERMEATE_BOOST_PUMP_TGT_PSI 25.0F ///< Pressure target in PSI for the boost pump during generate permeate mode. +#define GEN_PERMEATE_RO_PUMP_TGT_ML 750 ///< Flow target in ml/min for the ro pump during generate permeate mode. +#define PUMP_REST_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< Duraion for open loop control at the start of tank fill/full state ( in ms ) +#define RO_REJECTION_WAIT_TIME_MS ( 8 * MS_PER_SECOND ) ///< RO rejection alarm wait time. 5 seconds for RR to stabilize and 3 seconds for calculating rolling average ( in ms ) +#define MIN_SAMPLES_NEEDED_FOR_DUTY_CYCLE_AVG 10 ///< Minimum number for samples needed for calculating the average duty cycle +#define PERMEATE_FLOW_OUT_OF_RANGE_TIMEOUT_MS ( 12 * MS_PER_SECOND ) ///< Permeate flow low tolerance out of range timeout // ********** private data ********** static FP_GENP_MODE_STATE_T genPermeateState; ///< Currently active generate Permeate state. static U32 genPermeateDataPublicationTimerCounter; ///< Used to schedule generate Permeate data publication to CAN bus. static OVERRIDE_U32_T genPermeateDataPublishInterval; ///< Generate permeate mode data publish interval. +static F32 fillDutySum; ///< Sum of duty cycle values for one fill cycle. +static U32 fillDutyCount; ///< Sample counts for one fill cycle. +static F32 prevFillAvgDutyCycle; ///< Average vale of duty cycle during previous fill state. +static BOOL isFillAvgValid; ///< Flag to check if the average fill duty cycle value is valid or not. +static F32 fullDutySum; ///< Sum of duty cycle values for one full cycle. +static U32 fullDutyCount; ///< Sample counts for one full cycle. +static F32 prevFullAvgDutyCycle; ///< Average vale of duty cycle during previous full state. +static BOOL isFullAvgValid; ///< Flag to check if the average full duty cycle value is valid or not. +static U32 timeInState; ///< Time to wait after reset before starting close loop control (temporary) +static BOOL stateTransitioned; ///< Flag to check if permeate tank state transitioned // ********** private function prototypes ********** @@ -54,6 +71,8 @@ static FP_GENP_MODE_STATE_T handleGenPTankFillState( void ); static void setModeGenPTransition( FP_GENP_MODE_STATE_T state ); static U32 getGenPermeateDataPublishInterval( void ); +static void updateDutyCycleAvg( FP_GENP_MODE_STATE_T state ); +static void calculateDutyCycleAvg( FP_GENP_MODE_STATE_T state ); /*********************************************************************//** * @brief @@ -70,6 +89,16 @@ genPermeateDataPublishInterval.ovInitData = 0; genPermeateDataPublishInterval.override = OVERRIDE_RESET; genPermeateDataPublicationTimerCounter = 0; + fillDutySum = 0.0F; + fillDutyCount = 0; + prevFillAvgDutyCycle = 0.0F; + isFillAvgValid = FALSE; + fullDutySum = 0.0F; + fullDutyCount = 0; + prevFullAvgDutyCycle = 0.0F; + isFullAvgValid = FALSE; + timeInState = 0; + stateTransitioned = FALSE; } /*********************************************************************//** @@ -107,10 +136,12 @@ switch ( genPermeateState ) { case FP_GENP_TANK_FILL_STATE: + updateDutyCycleAvg( FP_GENP_TANK_FILL_STATE ); genPermeateState = handleGenPTankFillState(); break; case FP_GENP_TANK_FULL_STATE: + updateDutyCycleAvg( FP_GENP_TANK_FULL_STATE ); genPermeateState = handleGenPTankFullState(); break; @@ -122,9 +153,20 @@ if ( prevState != genPermeateState ) { + stateTransitioned = TRUE; + calculateDutyCycleAvg( prevState ); setModeGenPTransition( genPermeateState ); SEND_EVENT_WITH_2_U32_DATA( FP_EVENT_GENP_CHANGE, genPermeateState, prevState ) } + + checkInletPressures(); + + checkPermeateHighFlow(); + + checkPermeateLowFlow(); + + checkInletTemperatures(); + //Publish Gen Permeate mode data publishGenPModeData(); @@ -133,29 +175,88 @@ /*********************************************************************//** * @brief + * The requestGenWaterStart function handles an DD request to start (go to gen permeate mode). + * @details \b Inputs: none + * @details \b Outputs: none + * @return TRUE if request accepted, FALSE if not. + *************************************************************************/ +BOOL requestGenWaterStart( void ) +{ + BOOL result = TRUE; + requestNewFPOperationMode( FP_MODE_GENP ); + + return result; +} + +/*********************************************************************//** + * @brief + * The requestGenWaterStop function handles an DD request to stop (go to standby mode). + * @details \b Inputs: none + * @details \b Outputs: none + * @return TRUE if request accepted, FALSE if not. + *************************************************************************/ +BOOL requestGenWaterStop( void ) +{ + BOOL result = TRUE; + signalROPumpHardStop(); + + if ( TRUE == isBoostPumpInstalled() ) + { + signalBoostPumpHardStop(); + } + requestNewFPOperationMode( FP_MODE_STAN ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getCurrentGenPermeateState function returns the current state of the + * gen permeate mode. + * @details \b Inputs: genPermeateState + * @details \b Outputs: genPermeateState + * @return the current state of gen permeate mode + *************************************************************************/ +FP_GENP_MODE_STATE_T getCurrentGenPermeateState( void ) +{ + return genPermeateState; +} + +/*********************************************************************//** + * @brief * The setModeGenPTransition function sets the actuators and variables * for the state transition in generate permeate mode. - * @details Inputs: Valve states, Pump speed + * @details Inputs: none * @details Outputs: Actuate valves, pumps as desired. * @param state gen permeate state enum * @return none *************************************************************************/ static void setModeGenPTransition( FP_GENP_MODE_STATE_T state ) { + F32 initDutyCycle = 0.0F; + // Execute on running state switch( state ) { case FP_GENP_TANK_FILL_STATE: + initDutyCycle = isFillAvgValid ? prevFillAvgDutyCycle : getCurrentROPumpDutyCyclePCT(); + setROPumpTargetDutyCycle( initDutyCycle, TRUE ); + timeInState = getMSTimerCount(); if ( TRUE == isBoostPumpInstalled() ) { setBoostPumpTargetPressure( GEN_PERMEATE_BOOST_PUMP_TGT_PSI ); } break; case FP_GENP_TANK_FULL_STATE: + initDutyCycle = isFullAvgValid ? prevFullAvgDutyCycle : getCurrentROPumpDutyCyclePCT(); + setROPumpTargetDutyCycle( initDutyCycle, TRUE ); + timeInState = getMSTimerCount(); if ( TRUE == isBoostPumpInstalled() ) { - signalBoostPumpHardStop(); + F32 currentDutyCyclePct = getCurrentBoostPumpDutyCyclePCT(); + + setBoostPumpTargetDutyCycle( currentDutyCyclePct ); } break; @@ -168,15 +269,26 @@ /*********************************************************************//** * @brief * The handleGenPTankFillState handles the fill state of gen water. - * @details \b Inputs: none - * @details \b Outputs: none + * @details \b Inputs: timeInState, stateTransitioned + * @details \b Outputs: stateTransitioned * @return the next state of gen water mode *************************************************************************/ static FP_GENP_MODE_STATE_T handleGenPTankFillState( void ) { FP_GENP_MODE_STATE_T state = FP_GENP_TANK_FILL_STATE; PERMEATE_TANK_STATE_T permemeateTankState = getPermeateTankState(); + // Wait for set timeout before transition to closed loop control + if ( TRUE == didTimeout( timeInState, PUMP_REST_TIMEOUT_MS ) && stateTransitioned == TRUE ) + { + stateTransitioned = FALSE; + setROPumpTargetFlowRateMLPM( GEN_PERMEATE_RO_PUMP_TGT_ML, TRUE ); + } + // Wait for RO rejection to stabilize after transition from full to fill + RO Rejection moving average duration + if ( TRUE == didTimeout( timeInState, RO_REJECTION_WAIT_TIME_MS ) ) + { + checkRORejectionRatio(); + } if ( permemeateTankState == PERMEATE_TANK_FULL_STATE ) { state = FP_GENP_TANK_FULL_STATE; @@ -188,15 +300,21 @@ /*********************************************************************//** * @brief * The handleGenPTankFullState handles the full state of gen permeate. - * @details \b Inputs: stateDelayTime - * @details \b Outputs: none + * @details \b Inputs: timeInState, stateTransitioned + * @details \b Outputs: stateTransitioned * @return the next state of gen permeate mode *************************************************************************/ static FP_GENP_MODE_STATE_T handleGenPTankFullState( void ) { FP_GENP_MODE_STATE_T state = FP_GENP_TANK_FULL_STATE; PERMEATE_TANK_STATE_T permemeateTankState = getPermeateTankState(); + // Wait for set timeout before transition to closed loop control + if ( TRUE == didTimeout( timeInState, PUMP_REST_TIMEOUT_MS ) && stateTransitioned == TRUE ) + { + stateTransitioned = FALSE; + setROPumpTargetFlowRateMLPM( GEN_PERMEATE_RO_PUMP_TGT_ML, TRUE ); + } if ( permemeateTankState == PERMEATE_TANK_FILL_STATE ) { state = FP_GENP_TANK_FILL_STATE; @@ -207,15 +325,56 @@ /*********************************************************************//** * @brief - * The getCurrentGenPermeateState function returns the current state of the - * gen permeate mode. - * @details \b Inputs: genPermeateState - * @details \b Outputs: genPermeateState - * @return the current state of gen permeate mode + * The updateDutyCycleAvg function accumulates duty cycle samples for + * states in generate permeate mode. + * @details \b Inputs: none + * @details \b Outputs: fillDutySum, fillDutyCount, fullDutySum, fullDutyCount + * @param state genPermeateState enum + * @return none +*************************************************************************/ +static void updateDutyCycleAvg( FP_GENP_MODE_STATE_T state ) +{ + F32 duty = getCurrentROPumpDutyCyclePCT(); + + if ( state == FP_GENP_TANK_FILL_STATE ) + { + fillDutySum += duty; + fillDutyCount++; + } + else if ( state == FP_GENP_TANK_FULL_STATE ) + { + fullDutySum += duty; + fullDutyCount++; + } +} + +/*********************************************************************//** + * @brief + * The calculateDutyCycleAvg function computes the average duty cycle + * from the accumulated samples collected using updateDutyCyle. + * @details \b Inputs: fillDutyCount, fullDutyCount + * @details \b Outputs: prevFillAvgDutyCycle, isFillAvgValid, fillDutySum, + * fillDutyCount, prevFullAvgDutyCycle, isFullAvgValid, fullDutySum, + * fullDutyCount + * @param state genPermeateState enum + * @return none *************************************************************************/ -FP_GENP_MODE_STATE_T getCurrentGenPermeateState( void ) +static void calculateDutyCycleAvg( FP_GENP_MODE_STATE_T state ) { - return genPermeateState; + if ( state == FP_GENP_TANK_FILL_STATE && fillDutyCount > MIN_SAMPLES_NEEDED_FOR_DUTY_CYCLE_AVG) + { + prevFillAvgDutyCycle = fillDutySum / (F32)fillDutyCount; + isFillAvgValid = TRUE; + fillDutySum = 0.0F; + fillDutyCount = 0; + } + else if ( state == FP_GENP_TANK_FULL_STATE && fullDutyCount > MIN_SAMPLES_NEEDED_FOR_DUTY_CYCLE_AVG ) + { + prevFullAvgDutyCycle = fullDutySum / (F32)fullDutyCount; + isFullAvgValid = TRUE; + fullDutySum = 0.0F; + fullDutyCount = 0; + } } /*********************************************************************//** @@ -258,43 +417,7 @@ } } -/*********************************************************************//** - * @brief - * The requestGenWaterStart function handles an DD request to start (go to gen permeate mode). - * @details \b Inputs: none - * @details \b Outputs: none - * @return TRUE if request accepted, FALSE if not. - *************************************************************************/ -BOOL requestGenWaterStart( void ) -{ - BOOL result = TRUE; - requestNewFPOperationMode( FP_MODE_GENP ); - return result; -} - -/*********************************************************************//** - * @brief - * The requestGenWaterStop function handles an DD request to stop (go to standby mode). - * @details \b Inputs: none - * @details \b Outputs: none - * @return TRUE if request accepted, FALSE if not. - *************************************************************************/ -BOOL requestGenWaterStop( void ) -{ - BOOL result = TRUE; - signalROPumpHardStop(); - - if ( TRUE == isBoostPumpInstalled() ) - { - signalBoostPumpHardStop(); - } - requestNewFPOperationMode( FP_MODE_STAN ); - - return result; -} - - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/FPModes/ModeGenPermeateDefeatured.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/ModeGenPermeateDefeatured.c (.../ModeGenPermeateDefeatured.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/ModeGenPermeateDefeatured.c (.../ModeGenPermeateDefeatured.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModeGenPermeateDefeatured.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -24,6 +24,7 @@ #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" +#include "WaterQualityMonitor.h" /** * @addtogroup FPGenPermeateDefeaturedMode @@ -118,6 +119,9 @@ setModeGenPDefTransition( genPermeateDefState ); SEND_EVENT_WITH_2_U32_DATA( FP_EVENT_GENP_DEF_CHANGE, genPermeateDefState, prevState ) } + + checkInletPressures(); + //Publish Gen Permeate mode data publishGenPDefModeData(); @@ -140,7 +144,7 @@ { case FP_GENP_DEF_SUPPLY_WATER: setValveState( M4_VALV, VALVE_STATE_OPEN ); - setValveState( M12_VALV, VALVE_STATE_CLOSED ); + setValveState( M12_VALV, VALVE_STATE_OPEN ); setValveState( P6_VALV, VALVE_STATE_CLOSED ); setValveState( P11_VALV, VALVE_STATE_CLOSED ); setValveState( P33_VALV, VALVE_STATE_CLOSED ); Index: firmware/App/Modes/FPModes/ModePreGenPermeate.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/ModePreGenPermeate.c (.../ModePreGenPermeate.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/ModePreGenPermeate.c (.../ModePreGenPermeate.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModePreGenPermeate.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -31,6 +31,7 @@ #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" +#include "WaterQualityMonitor.h" /** * @addtogroup FPPreGenPermeateMode @@ -40,9 +41,10 @@ // ********** private definitions ********** #define PRE_GENP_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pre gen Permeate mode data published. -#define VERIFY_WATER_RO_PUMP_TGT_FLOW_ML 700 ///< Target flow rate for RO pump in ml/min +#define VERIFY_WATER_RO_PUMP_TGT_FLOW_ML 750 ///< Target flow rate for RO pump in ml/min #define VERIFY_WATER_BOOST_PUMP_TGT_PSI 25 ///< Target pressure for boost pump in psi. #define VERIFY_WATER_TIMEOUT_MS ( 30 * MS_PER_SECOND ) ///< Verify Water timer ( in ms ) +#define FLOW_CONTROL_STABLIZED_TIMEOUT_MS ( 25 * MS_PER_SECOND ) ///< Flow control stablized time ( in ms ) // ********** private data ********** @@ -113,6 +115,7 @@ U32 execPreGenPMode( void ) { FP_PRE_GENP_MODE_STATE_T previouspreGenPState = preGenPState; + // execute current pre gen Permeate state switch ( preGenPState ) { @@ -145,7 +148,7 @@ break; } - if( previouspreGenPState != preGenPState ) + if ( previouspreGenPState != preGenPState ) { setModePreGenPTransition( preGenPState ); SEND_EVENT_WITH_2_U32_DATA( FP_EVENT_PRE_GEN_CHANGE, preGenPState, previouspreGenPState ) @@ -194,6 +197,7 @@ setValveState( P34_VALV, VALVE_STATE_CLOSED ); // Current set to Medium recovery for alpha HW setValveState( P37_VALV, VALVE_STATE_CLOSED ); setValveState( P39_VALV, VALVE_STATE_OPEN ); + startPermeateTankControl(); if ( TRUE == isBoostPumpInstalled() ) { @@ -263,7 +267,7 @@ execFilterFlush(); - if( TRUE == isFilterFlushComplete() ) + if ( TRUE == isFilterFlushComplete() ) { signalStartPermeateFlush(); state = FP_PRE_GENP_PERMEATE_FLUSH; @@ -291,7 +295,7 @@ execPermeateFlush(); - if( TRUE == isPermeateFlushComplete() ) + if ( TRUE == isPermeateFlushComplete() ) { signalStartConcentrateFlush(); state = FP_PRE_GENP_CONCENTRATE_FLUSH; @@ -319,7 +323,7 @@ execConcentrateFlush(); - if( TRUE == isConcentrateFlushComplete() ) + if ( TRUE == isConcentrateFlushComplete() ) { state = FP_PRE_GENP_VERIFY_WATER; } @@ -340,12 +344,24 @@ FP_PRE_GENP_MODE_STATE_T state = FP_PRE_GENP_VERIFY_WATER; F32 roCurrentDutyCycle = getCurrentROPumpDutyCyclePCT(); + //Stay in this state for 25 seconds to stablize flow control + if ( TRUE == didTimeout( verifyWaterTimer, FLOW_CONTROL_STABLIZED_TIMEOUT_MS ) ) + { + // check next 5 seconds for water quality + // check permeate high flow rate is within range + checkPermeateHighFlow(); + // check low flow rate is within range + checkPermeateLowFlow(); + // check conductivity is within range + checkOutletConductivity(); + } + // if ( TRUE == 1 ))// TODO Alarm and Stop State Rework // { // state = FP_PRE_GENP_PAUSED; // } - - if( TRUE == didTimeout( verifyWaterTimer, VERIFY_WATER_TIMEOUT_MS ) ) + // wait 30 second before moving to water generation mode + if ( TRUE == didTimeout( verifyWaterTimer, VERIFY_WATER_TIMEOUT_MS ) ) { transitionToGenPermeateMode(); requestGenWaterStart(); // transition function will clear start flag Index: firmware/App/Modes/FPModes/ModePreGenPermeateDefeatured.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/FPModes/ModePreGenPermeateDefeatured.c (.../ModePreGenPermeateDefeatured.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/FPModes/ModePreGenPermeateDefeatured.c (.../ModePreGenPermeateDefeatured.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModePreGenPermeateDefeatured.c * -* @author (last) “Raghu -* @date (last) 14-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -151,7 +151,7 @@ { case FP_PRE_GENP_DEF_FLUSH: setValveState( M4_VALV, VALVE_STATE_OPEN ); - setValveState( M12_VALV, VALVE_STATE_CLOSED ); + setValveState( M12_VALV, VALVE_STATE_OPEN ); setValveState( P6_VALV, VALVE_STATE_CLOSED ); setValveState( P11_VALV, VALVE_STATE_CLOSED ); setValveState( P33_VALV, VALVE_STATE_CLOSED ); @@ -285,9 +285,12 @@ { BOOL result = FALSE; - result = TRUE; - pendingStartPreGenDefRequest = TRUE; - requestNewFPOperationMode( FP_MODE_DPGP ); + if ( ( FP_MODE_STAN == getCurrentFPOperationMode() ) && ( FP_STANDBY_MODE_STATE_IDLE == getCurrentFPStandbyState() ) ) + { + result = TRUE; + pendingStartPreGenDefRequest = TRUE; + requestNewFPOperationMode( FP_MODE_DPGP ); + } return result; } Index: firmware/App/Modes/ModeGenDialysate.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/ModeGenDialysate.c (.../ModeGenDialysate.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModeGenDialysate.c * -* @author (last) Jonny Paguio -* @date (last) 07-Oct-2025 +* @author (last) Vinayakam Mani +* @date (last) 14-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -60,7 +60,8 @@ #define LINEAR_SLOPE_FACTOR -0.0029F ///< Slope factor used in adjusted dialysate temperature linear calculation for high Qds #define LINEAR_INTERCEPT_FACTOR 3.47F ///< Intercept factor used in adjusted dialysate temperature linear calculation for high Qds #define LOW_DIAL_FLOW_RATE 150.0F ///< Dialysate flow rate lesser than 150 considered to be low Qds. -#define SPENT_CHAMBER_FILL_MAX_COUNT 15 ///< Total number of spent chamber fill allowed. +#define ZERO_DIAL_FLOW_RATE 0.0F ///< Zero dialysate flow rate +#define SPENT_CHAMBER_FILL_MAX_COUNT 10 ///< Total number of spent chamber fill allowed. #define BICARB_CHAMBER_FILL_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Bicarb chamber fill timeout. //Testing #define DELAY_BC_SWITCHING_AT_START_UP ( 10 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., @@ -211,12 +212,13 @@ case DD_GEND_DIALYSATE_BYPASS_STATE: setValveState( D14_VALV, VALVE_STATE_OPEN ); - setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve + setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve // Turn on the primary heater calculateTargetDialysateTemp(); @@ -245,7 +247,7 @@ setValveState( D47_VALV, VALVE_STATE_CLOSED ); // spent chamber purge valve setValveState( D64_VALV, VALVE_STATE_CLOSED ); setValveState( D14_VALV, VALVE_STATE_OPEN ); - setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve + setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve // Turn on the primary heater calculateTargetDialysateTemp(); @@ -265,15 +267,17 @@ setValveState( D34_VALV, VALVE_STATE_CLOSED ); // Bypass valve setValveState( D35_VALV, VALVE_STATE_OPEN ); // VDI setValveState( D40_VALV, VALVE_STATE_OPEN ); // VDO + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve break; case DD_GEND_SPENT_CHAMBER_FILL_STATE: //Set valves and actuators setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO setValveState( D14_VALV, VALVE_STATE_OPEN ); - setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve + setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve setValveState( D47_VALV, VALVE_STATE_OPEN ); // Spent chamber purge valve requestConcentratePumpOff( D76_PUMP, FALSE ); @@ -307,9 +311,10 @@ setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO setValveState( D14_VALV, VALVE_STATE_CLOSED ); - setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve + setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve setValveState( D64_VALV, VALVE_STATE_OPEN ); // Bicarb chamber purge valve + setValveState( D80_VALV, VALVE_STATE_OPEN ); // Bicarb valve bicarbFillStartTimeMS = getMSTimerCount(); // Turn on the primary heater @@ -327,22 +332,40 @@ break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: - // stop the motor during pause conditions - signalDialysatePumpHardStop( D12_PUMP ); + setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); requestConcentratePumpOff( D76_PUMP, FALSE ); //Rinse pump Off setRinsePumpState( RINSE_PUMP_STATE_OFF ); - stopHeater( D5_HEAT ); + // Turn on the primary heater + calculateTargetDialysateTemp(); + setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); + //Disable the D28 based temp control as fluid dispense being stopped by balancing chamber. + setD28TempFeedbackControl( FALSE ); + startHeater( D5_HEAT ); stopHeater( D45_HEAT ); - //Enable bypass valve - setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI - setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO - setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve + //close valves + setValveState( D35_VALV, VALVE_STATE_CLOSED ); + setValveState( D40_VALV, VALVE_STATE_CLOSED ); + setValveState( D31_VALV, VALVE_STATE_CLOSED ); + setValveState( D47_VALV, VALVE_STATE_CLOSED ); + setValveState( D64_VALV, VALVE_STATE_CLOSED ); + setValveState( D54_VALV, VALVE_STATE_CLOSED ); + setValveState( D14_VALV, VALVE_STATE_CLOSED ); + setValveState( D52_VALV, VALVE_STATE_CLOSED ); + setValveState( D65_VALV, VALVE_STATE_CLOSED ); + setValveState( D81_VALV, VALVE_STATE_CLOSED ); + setValveState( D8_VALV, VALVE_STATE_CLOSED ); + //Close all balancing chamber valves + valveControlForBCClosedState(); + + setValveState( D34_VALV, VALVE_STATE_OPEN ); + setValveState( D53_VALV, VALVE_STATE_OPEN ); + setValveState( D80_VALV, VALVE_STATE_OPEN ); break; case DD_GEND_ISOLATED_UF_STATE: @@ -449,8 +472,9 @@ BOOL hydChamberWaterInletControl( void ) { // Read floater switch - BOOL result = FALSE; - LEVEL_STATE_T floaterLevel = getLevelStatus( D6_LEVL ); + BOOL result = FALSE; + LEVEL_STATE_T floaterLevel = getLevelStatus( D6_LEVL ); + BOOL balancingChambFillInProgress = getBalancingChamberFillinProgressStatus(); // High level is met if ( LEVEL_STATE_HIGH == floaterLevel ) @@ -461,7 +485,7 @@ // Water level reached high. result = TRUE; } - else + else if ( LEVEL_STATE_LOW == floaterLevel || TRUE != balancingChambFillInProgress ) { // if level is not met,allow inlet water to hydraulics chamber setValveState( D3_VALV, VALVE_STATE_OPEN ); @@ -613,9 +637,10 @@ *************************************************************************/ static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryState( void ) { - DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_DELIVERY_STATE; - LEVEL_STATE_T spentChamberLevel = getLevelStatus( D46_LEVL ); - LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); + DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_DELIVERY_STATE; + LEVEL_STATE_T spentChamberLevel = getLevelStatus( D46_LEVL ); + LEVEL_STATE_T bicarbChamberLevel = getLevelStatus( D63_LEVL ); + BOOL balancingChambFillInProgress = getBalancingChamberFillinProgressStatus(); // if TD asks for bypass or dialysate is not good to deliver //transition to bypass dialystate state @@ -763,8 +788,13 @@ static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryPauseState( void ) { DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_DELIVERY_PAUSE; + F32 dialFlowrate = getTDDialysateFlowrate(); - //TODO : Handle pause state. + // Resume pause when Qd is not zero + if ( dialFlowrate > ZERO_DIAL_FLOW_RATE ) + { + state = DD_GEND_DIALYSATE_BYPASS_STATE; + } return state; } Index: firmware/App/Modes/ModeGenDialysate.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/ModeGenDialysate.h (.../ModeGenDialysate.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/ModeGenDialysate.h (.../ModeGenDialysate.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModeGenDialysate.h * -* @author (last) Jonny Paguio -* @date (last) 29-Sep-2025 +* @author (last) Vinayakam Mani +* @date (last) 14-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -33,7 +33,7 @@ #define FRESH_DIAL_PUMP_INITIAL_RPM 2500 ///< Nominal RPM target for fresh dialysate pump to maintain required pressure. #define SPENT_DIAL_PUMP_INITIAL_RPM 2300 ///< Nominal RPM target for spent dialysate pump to maintain required pressure. -#define SPENT_DIAL_PUMP_FILL_RPM 350 ///< Nominal RPM target for spent chamber fill operations. +#define SPENT_DIAL_PUMP_FILL_RPM 200 ///< Nominal RPM target for spent chamber fill operations. /// Generate dialysate mode data structure typedef struct Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file ModeInitPOST.c * * @author (last) Vinayakam Mani -* @date (last) 25-Dec-2024 +* @date (last) 23-Jan-2025 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file ModeStandby.c * -* @author (last) Vinayakam Mani -* @date (last) 08-Aug-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 @@ -25,6 +25,7 @@ #include "Messaging.h" //#include "NVDataMgmt.h" #include "OperationModes.h" +#include "PermeateTank.h" #include "Pressure.h" #include "SystemCommDD.h" #include "TaskGeneral.h" @@ -90,6 +91,8 @@ deenergizeActuators( PARK_CONC_PUMPS ); + resetPermeateTank(); + // // Upon transition to mode standby set CD1 and CD2 calibration records to be picked to the normal // // table. If the chemical disinfect fails, the mode transitions back to mode standby. // setCondcutivitySensorCalTable( D17_COND, CAL_DATA_CD1_COND_SENSOR ); Index: firmware/App/Monitors/BloodLeak.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/BloodLeak.c (.../BloodLeak.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/BloodLeak.c (.../BloodLeak.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file BloodLeak.c * * @author (last) Dara Navaei -* @date (last) 22-Oct-2025 +* @date (last) 05-Dec-2025 * * @author (original) Dara Navaei * @date (original) 18-Aug-2025 @@ -542,20 +542,23 @@ *************************************************************************/ BOOL isBloodLeakZeroingNeeded( void ) { - BOOL status = FALSE; - TD_OP_MODE_T opMode = getTDOpMode(); + BOOL status = FALSE; - if ( MODE_PRET == opMode ) + TD_MODE_SUB_MODE_T tdModes; + + getTDOperationMode( &tdModes ); + + if ( MODE_PRET == tdModes.tdMode ) { U32 intensity = getEmbModeInfoValue( I_EMB_MODE_CMD ); if ( ( intensity <= BLD_START_OF_TX_MIN_INTENSITY_DRIFT ) || ( intensity >= BLD_MAX_UPPER_INTENSITY_DRIFT ) ) { - SEND_EVENT_WITH_2_F32_DATA( DD_EVENT_BLOOD_LEAK_ZEROING_REQUIRED, intensity, opMode ) + SEND_EVENT_WITH_2_F32_DATA( DD_EVENT_BLOOD_LEAK_ZEROING_REQUIRED, intensity, tdModes.tdMode ) status = TRUE; } } - else if ( MODE_TREA == opMode ) + else if ( MODE_TREA == tdModes.tdMode ) { status |= isLowerRangeIntensityDriftZeroingNeeded(); status |= isUpperIntensityZeroingNeeded(); @@ -858,9 +861,13 @@ { BLOOD_LEAK_STATE_T state = BLOOD_LEAK_NORMAL_STATE; + TD_MODE_SUB_MODE_T tdModes; + + getTDOperationMode( &tdModes ); + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); - switch ( getTDOpMode() ) + switch ( tdModes.tdMode ) { case MODE_TREA: case MODE_SERV: @@ -1481,8 +1488,6 @@ data.driftInRangeStatus = bloodLeakZeroingStatus.driftInRangeStatus; data.driftUpperRangeStatus = bloodLeakZeroingStatus.driftUpperRangeStatus; - data.TEMP_REMOVE_VARIABLE = (U32)get_TEMP_REMOVE_STATUS(); - bloodLeakDataPublicationCounter = 0; broadcastData( MSG_ID_DD_BLOOD_LEAK_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( BLOOD_LEAK_DATA_T ) ); @@ -2013,12 +2018,15 @@ *************************************************************************/ BOOL testSetBloodLeak2EmbeddedMode( MESSAGE_T *message ) { - BOOL result = FALSE; - TD_OP_MODE_T mode = getTDOpMode(); + BOOL result = FALSE; + TD_MODE_SUB_MODE_T tdModes; + + getTDOperationMode( &tdModes ); + // Check if the mode is fault, service or standby before accepting a transition to // the embedded mode - if ( ( MODE_FAUL == mode ) || ( MODE_SERV == mode ) || ( MODE_STAN == mode ) ) + if ( ( MODE_FAUL == tdModes.tdMode ) || ( MODE_SERV == tdModes.tdMode ) || ( MODE_STAN == tdModes.tdMode ) ) { bloodLeakSignalEmbModeReq = TRUE; bloodLeakEmbModeRqstedCmd = CS_EMB_MODE_CMD; Index: firmware/App/Monitors/BloodLeak.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/BloodLeak.h (.../BloodLeak.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/BloodLeak.h (.../BloodLeak.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file BloodLeak.h * -* @author (last) Dara Navaei -* @date (last) 22-Oct-2025 +* @author (last) Sean Nash +* @date (last) 12-Sep-2025 * * @author (original) Dara Navaei * @date (original) 18-Aug-2025 @@ -55,7 +55,6 @@ U32 bloodLeakTimeSinceZeroMS; ///< Blood leak detector time since last zero in milliseconds. U32 driftInRangeStatus; ///< Blood leak detector drift in range status. U32 driftUpperRangeStatus; ///< Blood leak detector drift upper range status. - U32 TEMP_REMOVE_VARIABLE; } BLOOD_LEAK_DATA_T; // ********** public function prototypes ********** Index: firmware/App/Monitors/Conductivity.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/Conductivity.c (.../Conductivity.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file Conductivity.c * -* @author (last) Vinayakam Mani -* @date (last) 10-Sep-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 13-Sep-2024 @@ -20,6 +20,7 @@ #include "Conductivity.h" #include "MessageSupport.h" #include "Messaging.h" +#include "ModeGenPermeate.h" #include "OperationModes.h" #include "TaskPriority.h" #include "Utilities.h" @@ -37,6 +38,9 @@ #define CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS ( 500 ) ///< Filter conductivity temperature data for given time #define SIZE_OF_FLOW_ROLLING_AVG ( CONDUCTIVITY_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity moving average sample count. #define SIZE_OF_FLOW_TEMP_ROLLING_AVG ( CONDUCTIVITY_TEMP_SAMPLE_FILTER_MS / TASK_PRIORITY_INTERVAL ) ///< Filtered conductivity temprature moving average sample count. +#define RO_RR_MOVING_AVG_NUM_OF_SAMPLES 30 ///< RO rejection ratio moving average number of samples. +#define FRACTION_TO_PERCENT_CONVERSION_FACTOR 100.0F ///< RO rejection ratio factor to percentage conversion factor value +#define RO_RR_SAMPLE_COLLECTION_INTERVAL 10 ///< Collect RO rejection ratio sample for every 10th time in priority task /// Filter conductivity readings record. typedef struct @@ -66,13 +70,26 @@ static OVERRIDE_U32_T ddConductivityDataPublishInterval; ///< DD Conductivity sensors publish time interval override. static U32 fpConductivityPublishTimerCounter; ///< FP Conductivity data publication counter. static OVERRIDE_U32_T fpConductivityDataPublishInterval; ///< FP Conductivity sensors publish time interval override. +static F32 roRejectionRatio; ///< All time RO rejection ratio. +static F32 roRejectionRatioTankFill; ///< RO rejection ratio during permeate tank fill state. +static U32 roRRPublishTimerCounter; ///< RO rejection ratio publication counter. +static OVERRIDE_U32_T roRRDataPublishInterval; ///< RO rejection ratio publish time interval override. +static OVERRIDE_F32_T roRRAvg; ///< Average RO rejection ratio. +static F32 roRRRunningSum; ///< RO rejection ratio running sum. +static F32 roRRSamples[ RO_RR_MOVING_AVG_NUM_OF_SAMPLES ]; ///< RO rejection ratio samples array. +static U32 roRRSamplesNextIndex; ///< RO rejection ratio sample next index number. +static U32 roRRCount; ///< RO rejection ratio Number of samples in average buffer. +static F32 roRRTankFillAvg; ///< Average RO rejection ratio during permeate tank fill state. +static U32 roRRSampleIntervalCounter; ///< RO rejection ratio sample collection timer counter. // ********** private function prototypes ********** static void publishConductivitySensorsData( void ); static void filterConductivitySensors( void ); static void filterConductivitySensorReadings( void ); static void filterConductivitySensorTemperatureReadings( void ); +static void calcRORejectionRatio( void ); +static void filterRORejectionRatioReadings( void ); /*********************************************************************//** * @brief @@ -89,7 +106,21 @@ ddConductivityPublishTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; fpConductivityPublishTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + roRRPublishTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + roRejectionRatio = 0.0F; + roRejectionRatioTankFill = 0.0F; + roRRRunningSum = 0.0F; + roRRSamplesNextIndex = 0; + roRRCount = 0; + roRRTankFillAvg = 0.0F; + roRRAvg.data = 0.0F; + roRRAvg.ovData = 0.0F; + roRRAvg.ovInitData = 0.0F; + roRRAvg.override = OVERRIDE_RESET; + roRRSampleIntervalCounter = 0; + memset( &roRRSamples, 0, sizeof( roRRSamples ) ); + // Initialize override structures for each conductivity sensor for ( sensor = FIRST_DD_COND_SENSOR; sensor < NUM_OF_CONDUCTIVITY_SENSORS; sensor++ ) { @@ -121,6 +152,11 @@ fpConductivityDataPublishInterval.ovData = COND_SENSOR_REPORT_PERIOD; fpConductivityDataPublishInterval.ovInitData = 0; fpConductivityDataPublishInterval.override = OVERRIDE_RESET; + + roRRDataPublishInterval.data = COND_SENSOR_REPORT_PERIOD; + roRRDataPublishInterval.ovData = COND_SENSOR_REPORT_PERIOD; + roRRDataPublishInterval.ovInitData = 0; + roRRDataPublishInterval.override = OVERRIDE_RESET; } /*********************************************************************//** @@ -147,6 +183,8 @@ #endif filterConductivitySensors(); + calcRORejectionRatio(); // TODO: should this be called here or inside filter function + filterRORejectionRatioReadings(); // publish conductivity sensors publishConductivitySensorsData(); } @@ -289,10 +327,123 @@ /*********************************************************************//** * @brief + * The calcRORejectionRatio function calculates the RO rejection ratio using + * the P9 sensor conductivity value and P18 sensor conductivity value. + * @details Inputs: P9 sensor conductivity, P18 sensor conductivity + * @details Outputs: RO rejection ratio, Tank fill RO rejection ratio + * @return none + *************************************************************************/ +static void calcRORejectionRatio( void ) +{ + F32 feedConductivity = getFilteredConductivity( P9_COND ); + F32 permeateConductivity = getFilteredConductivity( P18_COND ); + + roRejectionRatio = RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE; + + if ( fabs(feedConductivity) >= NEARLY_ZERO ) + { + roRejectionRatio = FRACTION_TO_PERCENT_CONVERSION_FACTOR * ( ( feedConductivity - permeateConductivity ) / feedConductivity ); + } + if ( getCurrentGenPermeateState() == FP_GENP_TANK_FILL_STATE ) + { + roRejectionRatioTankFill = roRejectionRatio; + } +} + +/*********************************************************************//** + * @brief + * The filterRORejectionRatioReadings function adds a new ro rejection ratio + * sample to the filters. + * @details \b Inputs: RO rejection ratio all time and during tank fill state + * @details \b Outputs: roRRRunningSumC, roRRSamples[], roRRSamplesNextIndex, + * roRRCount, roRRAvg, roRRTankFillAvg + * @return none + *************************************************************************/ +static void filterRORejectionRatioReadings( void ) +{ + F32 roRR = 0.0F; + + // Moving average samples are collected for every 100 msec + if ( ++roRRSampleIntervalCounter >= RO_RR_SAMPLE_COLLECTION_INTERVAL ) + { + // Filter RO rejection ratio + roRRRunningSum -= roRRSamples[ roRRSamplesNextIndex ]; + roRR = getRORejectonRatio(); + roRRSamples[ roRRSamplesNextIndex ] = roRR; + roRRRunningSum += roRR; + roRRSamplesNextIndex = INC_WRAP( roRRSamplesNextIndex, 0, RO_RR_MOVING_AVG_NUM_OF_SAMPLES - 1 ); + roRRCount = INC_CAP( roRRCount, RO_RR_MOVING_AVG_NUM_OF_SAMPLES ); + roRRAvg.data = roRRRunningSum / (F32)roRRCount; + roRRSampleIntervalCounter = 0; + + // Update the Filter RO rejection ratio during tank fill if the tank is filling + if ( getCurrentGenPermeateState() == FP_GENP_TANK_FILL_STATE ) + { + roRRTankFillAvg = roRRAvg.data; + } + } +} + +/*********************************************************************//** + * @brief + * The getRORejectonRatio function returns the RO rejection ratio + * @details \b Inputs: roRejectionRatio + * @details \b Outputs: none + * @return the RO rejection ratio in percentage + *************************************************************************/ +F32 getRORejectonRatio( void ) +{ + return roRejectionRatio; +} + +/*********************************************************************//** + * @brief + * The getTankFillRORejectionRatio function returns the RO rejection ratio + * during tank fill state + * @details \b Inputs: roRejectionRatioTankFill + * @details \b Outputs: none + * @return the tank fill RO rejection ratio in percentage + *************************************************************************/ +F32 getTankFillRORejectionRatio( void ) +{ + return roRejectionRatioTankFill; +} + +/*********************************************************************//** + * @brief + * The getRORRAverage function returns the average RO rejection ratio + * @details \b Inputs: roRRAvg + * @details \b Outputs: none + * @return the average RO rejection ratio in percentage + *************************************************************************/ +F32 getRORRAverage( void ) +{ + F32 avgRORR = getF32OverrideValue( &roRRAvg ); + + return avgRORR; +} + +/*********************************************************************//** + * @brief + * The getTankFillRORRAverage function returns the average RO rejection ratio + * during tank fill state + * @details \b Inputs: roRRTankFillAvg + * @details \b Outputs: none + * @return the average tank fill RO rejection ratio in percentage + *************************************************************************/ +F32 getTankFillRORRAverage( void ) +{ + return roRRTankFillAvg; +} + +/*********************************************************************//** + * @brief * The publishConductivitySensorsData function publishes DD conductivity data * at a set interval. - * @details \b Inputs: conductivityPublishTimerCounter - * @details \b Outputs: conductivityPublishTimerCounter + * @details \b Inputs: ddconductivityPublishTimerCounter, fpConductivityPublishTimerCounter, + * roRRPublishTimerCounter + * @details \b Outputs: ddconductivityPublishTimerCounter, fpConductivityPublishTimerCounter, + * roRRPublishTimerCounter, DD, FP, RO data broadcast message sent * @details \b Message \b Sent: MSG_ID_DD_CONDUCTIVITY_DATA to publish DD conductivity data. * @details \b Message \b Sent: MSG_ID_FP_CONDUCTIVITY_DATA to publish FP conductivity data. * @return none @@ -325,6 +476,21 @@ broadcastData( MSG_ID_FP_CONDUCTIVITY_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( FP_CONDUCTIVITY_DATA_T ) ); } + + // publish ro rejection ratio data on interval + if ( ++roRRPublishTimerCounter >= getU32OverrideValue( &roRRDataPublishInterval ) ) + { + RO_REJECTION_RATIO_DATA_T data; + + data.rawRORejectionRatio = getRORejectonRatio(); + data.rawRORejectionRatioTankFill = getTankFillRORejectionRatio(); + data.avgRORejectionRatio = getRORRAverage(); + data.avgRORejectionRatioTankFill = getTankFillRORRAverage(); + data.genPermeateState = (U32)getCurrentGenPermeateState(); + roRRPublishTimerCounter = 0; + + broadcastData( MSG_ID_FP_RO_REJECTION_RATIO_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( RO_REJECTION_RATIO_DATA_T ) ); + } } @@ -465,4 +631,38 @@ return result; } +/*********************************************************************//** + * @brief + * The testRORejectionRatioDataPublishIntervalOverride function overrides the + * RO Rejection ratio data publish interval. + * @details \b Inputs: none + * @details \b Outputs: roRRDataPublishInterval + * @param message Override message from Dialin which includes the value + * that override valves states publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testRORejectionRatioDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &roRRDataPublishInterval, TASK_PRIORITY_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testRORejectionRatioFilteredOverride function + * overrides the filtered RO rejection value with a given value. + * @details \b Inputs: none + * @details \b Outputs: roRRAvg + * @param message Override message from Dialin which includes override value + * of the RO rejection ratio. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testRORejectionRatioFilteredOverride( MESSAGE_T *message ) +{ + BOOL result = f32Override( message, &roRRAvg ); + + return result; +} + /**@}*/ Index: firmware/App/Monitors/Conductivity.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/Conductivity.h (.../Conductivity.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/Conductivity.h (.../Conductivity.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file Conductivity.h * -* @author (last) Vinayakam Mani -* @date (last) 09-Sep-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 13-Sep-2024 @@ -33,6 +33,9 @@ // ********** public definitions ********** +#define RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE 100.0F ///< Out of range value for RO rejection ratio when CPi conductivity is zero. + +#pragma pack(push, 1) /// Conductivity data struct. typedef struct { @@ -50,19 +53,36 @@ F32 p18Conductivity; ///< (P18) conductivity sensor value } FP_CONDUCTIVITY_DATA_T; +/// RO rejection ratio data struct. +typedef struct +{ + F32 rawRORejectionRatio; ///< RO rejection ratio during tank full and fill state + F32 rawRORejectionRatioTankFill; ///< RO rejection ratio during tank fill state + F32 avgRORejectionRatio; ///< RO rejection ratio average during tank full and fill state + F32 avgRORejectionRatioTankFill; ///< RO rejection ratio average during tank fill state + U32 genPermeateState; ///< Permeate tank state +} RO_REJECTION_RATIO_DATA_T; +#pragma pack(pop) + // ********** public function prototypes ********** void initConductivity( void ); void execConductivity( void ); F32 getFilteredConductivity( CONDUCTIVITY_SENSORS_T sensor ); F32 getFilteredConductivitySensorTemperature( CONDUCTIVITY_SENSORS_T sensor ); +F32 getRORejectonRatio( void ); +F32 getTankFillRORejectionRatio( void ); +F32 getRORRAverage( void ); +F32 getTankFillRORRAverage( void ); BOOL testDDConductivitySensorDataPublishIntervalOverride( MESSAGE_T *message ); BOOL testDDConductivitySensorFilteredReadingsOverride( MESSAGE_T *message ); BOOL testDDConductivitySensorFilteredTemperatureReadingsOverride( MESSAGE_T *message ); BOOL testFPConductivitySensorDataPublishIntervalOverride( MESSAGE_T *message ); BOOL testFPConductivitySensorFilteredReadingsOverride( MESSAGE_T *message ); BOOL testFPConductivitySensorFilteredTemperatureReadingsOverride( MESSAGE_T *message ); +BOOL testRORejectionRatioDataPublishIntervalOverride( MESSAGE_T *message ); +BOOL testRORejectionRatioFilteredOverride( MESSAGE_T *message ); /**@}*/ Index: firmware/App/Monitors/Flow.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/Flow.c (.../Flow.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/Flow.c (.../Flow.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file Flow.c * -* @author (last) Michael Garthwaite -* @date (last) 08-Sep-2025 +* @author (last) Jonny Paguio +* @date (last) 20-Oct-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -370,8 +370,6 @@ data.p7Flow = getFilteredFlow( P7_FLOW ); data.p16Flow = getFilteredFlow( P16_FLOW ); - data.p7Temp = getFilteredFlowSensorTemperature( P7_FLOW ); - data.p16Temp = getFilteredFlowSensorTemperature( P16_FLOW ); broadcastData( MSG_ID_FP_FLOW_DATA, COMM_BUFFER_OUT_CAN_FP_BROADCAST, (U08*)&data, sizeof( FLOW_TEMP_DATA_T ) ); flowsDataPublicationTimerCounter = 0; Index: firmware/App/Monitors/Flow.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/Flow.h (.../Flow.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/Flow.h (.../Flow.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file Flow.h * -* @author (last) Michael Garthwaite -* @date (last) 11-Sep-2025 +* @author (last) Jonny Paguio +* @date (last) 20-Oct-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -37,8 +37,6 @@ { F32 p7Flow; ///< P7 flow rate at water inlet. F32 p16Flow; ///< P16 flow rate at RO filter outlet. - F32 p7Temp; ///< P7 temperature from inlet flow sensor. - F32 p16Temp; ///< P16 temperature from outlet flow sensor. } FLOW_TEMP_DATA_T; // ********** public function prototypes ********** Index: firmware/App/Monitors/WaterQualityMonitor.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/WaterQualityMonitor.c (.../WaterQualityMonitor.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/WaterQualityMonitor.c (.../WaterQualityMonitor.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file WaterQualityMonitor.c * * @author (last) “rkallala” -* @date (last) 23-Oct-2025 +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -36,8 +36,8 @@ #define INLET_TEMPERATURE_LOW_THRESHOLD_C 5.0F ///< Minimum allowed Inlet temperature in C. #define INLET_TEMPERATURE_HIGH_THRESHOLD_C 30.0F ///< Maximum allowed Inlet temperature in C. -#define INLET_TEMPERATURE_PERSISTENCE_TIMER_MS ( 5 * MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Persistence timer to trigger alarm in ms. -#define INLET_TEMPERATURE_PERSISTENCE_CLEAR_MS ( 5 * MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Persistence timer to clear alarm in ms. +#define INLET_TEMPERATURE_PERSISTENCE_TIMER_MS ( 5 * MS_PER_SECOND ) ///< Persistence timer to trigger alarm in ms. +#define INLET_TEMPERATURE_PERSISTENCE_CLEAR_MS ( 5 * MS_PER_SECOND ) ///< Persistence timer to clear alarm in ms. #define MAX_INLET_RO_PUMP_PRESSURE_WARNING_PSIG 120.0F ///< Maximum allowed Input pressure to the RO membrane. #define MIN_INLET_WATER_PRESSURE_WARNING_LOW_PSIG 25.0F ///< Minimum allowed Input warning low pressure value in psig for RO featured. @@ -58,7 +58,13 @@ #define INLET_WATER_COND_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity out of range error in milliseconds. #define INLET_WATER_COND_OUT_OF_RANGE_CLEAR_MS ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity out of range clear in milliseconds. #define INLET_CONDUCTIVITY_HIGH_THRESHOLD_US 2000.0F ///< Maximum allowed outlet conductivity in uS/cm. +#define MIN_RO_REJECTION_RATIO_PCT 90.0F ///< Minimum RO rejection ration in percentage +#define PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Verify Water timer ( in ms ) +#define PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_CLEAR_MS ( 5 * MS_PER_SECOND ) ///< Verify Water timer ( in ms ) +#define PERMEATE_FLOW_FAULT_MIN_THRESHOLD 200.0F ///< Permeate flow low tolerance limit +#define PERMEATE_FLOW_OUT_OF_RANGE_TIMEOUT_MS ( 12 * MS_PER_SECOND ) ///< Permeate flow low tolerance out of range timeout + // ********** private data ********** // ********** private function prototypes ********** @@ -86,6 +92,11 @@ // Conductivity Alarms initPersistentAlarm( ALARM_ID_FP_INLET_CONDUCTIVITY_OUT_HIGH_RANGE, INLET_WATER_COND_OUT_OF_RANGE_CLEAR_MS, INLET_WATER_COND_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_FP_RO_OUTLET_CONDUCTIVITY_HIGH_RANGE, INLET_WATER_COND_OUT_OF_RANGE_CLEAR_MS, INLET_WATER_COND_OUT_OF_RANGE_TIMEOUT_MS ); + + //Flow Alarms + initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_HIGH_RANGE, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_CLEAR_MS, PERMEATE_FLOW_OUT_RANGE_PERSISTENCE_TIMEOUT_MS ); + // fault , clearing timeout is not applicable + initPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, 0, PERMEATE_FLOW_OUT_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** @@ -131,15 +142,15 @@ /*********************************************************************//** * @brief - * The checkPermeateFlow function checks the permeate flow rate from P16 - * against the set target flow rate and alarm if the flow is out of range. + * The checkPermeateHighFlow function checks the permeate flow rate from P16 + * against the set target flow rate and alarm if the flow is out of range high. * @details \b Inputs: permeateFlow * @details \b Outputs: none * @details \b Alarms: ALARM_ID_FP_PERMEATE_FLOW_OUT_HIGH_RANGE when * P16 flow goes beyond threshold limit from set target flow. * @return none *************************************************************************/ -void checkPermeateFlow( void ) +void checkPermeateHighFlow( void ) { F32 permeateFlow = getFilteredFlow( P16_FLOW ); BOOL isFlowOutOfRange = FALSE; @@ -151,6 +162,26 @@ /*********************************************************************//** * @brief + * The checkPermeateLowFlow function checks the permeate low flow rate from P16 + * against the set target flow rate and alarm if the flow is out of range. + * @details \b Inputs: permeateFlow + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE when + * P16 flow goes beyond threshold limit from set target flow. + * @return none + *************************************************************************/ +void checkPermeateLowFlow( void ) +{ + F32 permeateFlow = getFilteredFlow( P16_FLOW ); + BOOL isFlowOutOfRange = FALSE; + F32 minimumAllowedPermeateFlow = (F32)getTargetROPumpFlowRateMLPM() - PERMEATE_FLOW_FAULT_MIN_THRESHOLD; + + isFlowOutOfRange = ( ( permeateFlow < minimumAllowedPermeateFlow ) ? TRUE : FALSE); + checkPersistentAlarm( ALARM_ID_FP_PERMEATE_FLOW_OUT_LOW_RANGE, isFlowOutOfRange, permeateFlow, minimumAllowedPermeateFlow); +} + +/*********************************************************************//** + * @brief * The checkROPressures function checks the RO membrane pressure * against the pressure threshold and alarm if the pressure is out of range. * @details \b Inputs: pressureP13 @@ -261,7 +292,27 @@ checkPersistentAlarm( ALARM_ID_FP_RO_OUTLET_CONDUCTIVITY_HIGH_RANGE, isConductivityOutOfLowRange, conductivityP18, OUTLET_CONDUCTIVITY_HIGH_THRESHOLD_US ); } +/*********************************************************************//** + * @brief + * The checkRORejectionRatio function checks the RO rejection ratio + * alarm if the rejection ratio is out of range. + * @details \b Inputs: roRRAvg + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_FP_REJECTION_RATIO_LOW_RANGE when + * RO rejection ratio goes below allowed rejection ratio limit. + * @return none + *************************************************************************/ +void checkRORejectionRatio( void ) +{ + F32 avgRORR = getRORRAverage(); + // Alarm if the filtered average is less than allowed RO rejection limit + if ( avgRORR < MIN_RO_REJECTION_RATIO_PCT ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_REJECTION_RATIO_LOW_RANGE, avgRORR, MIN_RO_REJECTION_RATIO_PCT) + } +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Monitors/WaterQualityMonitor.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Monitors/WaterQualityMonitor.h (.../WaterQualityMonitor.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Monitors/WaterQualityMonitor.h (.../WaterQualityMonitor.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,7 +8,7 @@ * @file WaterQualityMonitor.h * * @author (last) “rkallala” -* @date (last) 23-Oct-2025 +* @date (last) 09-Dec-2025 * * @author (original) Michael Garthwaite * @date (original) 08-Sep-2025 @@ -42,6 +42,9 @@ void checkInletTemperatures( void ); void checkInletConductivity( void ); void checkOutletConductivity( void ); -void checkPermeateFlow( void ); +void checkPermeateHighFlow( void ); +void checkRORejectionRatio( void ); +void checkPermeateHighFlow( void ); +void checkPermeateLowFlow( void ); #endif Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -8,8 +8,8 @@ * * @file FpgaDD.c * -* @author (last) “rkallala” -* @date (last) 23-Oct-2025 +* @author (last) Dara Navaei +* @date (last) 14-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 26-Aug-2024 @@ -107,9 +107,13 @@ #define FPGA_CONDUCTIVITY_WR_ENABLE_BIT 0x04 ///< Conductivity Sensor write enable bit mask. #define FPGA_CONDUCTIVITY_RD_ENABLE_BIT 0x08 ///< Conductivity Sensor read enable bit mask. -#define FPGA_D42_BLOOD_LEAK_STATUS_MASK 0x04 ///< Bit mask for blood leak detector. -#define FPGA_D42_BLOOD_LEAK_ST_BIT_INDEX 2 ///< Bit index for the blood leak self test status bit. +#define FPGA_D42_BLOOD_LEAK_STATUS_MASK 0x04 ///< Bit mask for blood leak detector. +#define FPGA_D42_BLOOD_LEAK_ST_BIT_INDEX 2 ///< Bit index for the blood leak self test status bit. +#define MAX_PUMP_SPEED 3000.0F ///< Maxon controller pump maximum speed +#define PUMP_SPEED_OFFSET 168.7F ///< Speed Scale adjustment intercept factor +#define PUMP_SPEED_FULL_SCALE 3187.0F ///< Speed scale adjustment slope factor + #pragma pack(push,1) /// FPGA header struct. typedef struct @@ -540,7 +544,16 @@ *************************************************************************/ void setFPGAD48PumpSpeed( U16 speed ) { - fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; +#ifdef __MAXON_SPEED_UPDATE__ + { + U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); + fpgaActuatorSetPoints.fpgaD48PumpSpeed = currentSpeed; + } +#else + { + fpgaActuatorSetPoints.fpgaD48PumpSpeed = speed; + } +#endif } /*********************************************************************//** @@ -554,7 +567,16 @@ *************************************************************************/ void setFPGAD12PumpSpeed( U16 speed ) { - fpgaActuatorSetPoints.fpgaD12PumpSpeed = speed; +#ifdef __MAXON_SPEED_UPDATE__ + { + U16 currentSpeed =(U16)( ( ( speed + PUMP_SPEED_OFFSET ) / PUMP_SPEED_FULL_SCALE ) * MAX_PUMP_SPEED ); + fpgaActuatorSetPoints.fpgaD12PumpSpeed = currentSpeed; + } +#else + { + fpgaActuatorSetPoints.fpgaD12PumpSpeed = speed; + } +#endif } /*********************************************************************//** @@ -2739,11 +2761,6 @@ return selfTestStatus; } -U08 get_TEMP_REMOVE_STATUS( void ) -{ - return fpgaSensorReadings.fpgaD42PulseStatus; -} - /*********************************************************************//** * @brief * The setFPGABloodLeakUARTControl function sets the blood leak sensor UART Index: firmware/App/Services/FpgaDD.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file FpgaDD.h * -* @author (last) “rkallala” -* @date (last) 23-Oct-2025 +* @author (last) Dara Navaei +* @date (last) 14-Nov-2025 * * @author (original) Vinayakam Mani * @date (original) 26-Aug-2024 @@ -230,7 +230,6 @@ U16 getFPGABloodLeakRxFIFOCount( void ); U08 getFPGABloodLeakRxErrorCount( void ); U08 getFPGABloodLeakRxFIFODataOut( void ); -U08 get_TEMP_REMOVE_STATUS( void ); //*************** IOFP ******************* Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Michael Garthwaite -* @date (last) 10-Nov-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 07-Aug-2024 @@ -230,12 +230,15 @@ { MSG_ID_FP_FILTERED_COND_SENSOR_TEMPERATURE_OVERRIDE_REQUEST, &testFPConductivitySensorFilteredTemperatureReadingsOverride }, { MSG_ID_DD_VOLTAGE_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testVoltageDataPublishIntervalOverride }, { MSG_ID_DD_MONITORED_VOLTAGE_OVERRIDE_REQUEST, &testVoltageOverride }, + { MSG_ID_DD_TREATMENT_PARAMS_OVERRIDE_REQUEST, &testTDTreatmentParamsOverride }, { MSG_ID_FP_LEVEL_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testFPLevelsDataPublishIntervalOverride }, { MSG_ID_FP_LEVEL_OVERRIDE_REQUEST, &testFPLevelStateOverride }, { MSG_ID_FP_PERMEATE_TANK_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testPermeateTankDataPublishIntervalOverride }, { MSG_ID_FP_RO_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testROPumpDataPublishIntervalOverride }, { MSG_ID_DD_RINSE_PUMP_DATA_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRinsePumpDataPublishIntervalOverride }, { MSG_ID_FP_SET_START_STOP_OVERRIDE_REQUEST, &testSetGeneratePermeateSignal }, + { MSG_ID_FP_RO_REJECTION_RATIO_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRORejectionRatioDataPublishIntervalOverride }, + { MSG_ID_FP_RO_FILTERED_REJECTION_RATIO_OVERRIDE_REQUEST, &testRORejectionRatioFilteredOverride }, }; /// Calculation for number of entries in the incoming message function handler look-up table. @@ -455,10 +458,7 @@ // ACK/NAK request if ( message->hdr.msgID < MSG_ID_FIRST_TD_TESTER_MESSAGE ) { -// if ( respBuffer != COMM_BUFFER_NOT_USED ) -// { -// sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, respBuffer, ack ); -// } + // only Sending Test ACK for dialin messages. } else { Index: firmware/App/Services/TDInterface.c =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Services/TDInterface.c (.../TDInterface.c) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Services/TDInterface.c (.../TDInterface.c) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file TDInterface.c * -* @author (last) Michael Garthwaite -* @date (last) 30-Oct-2025 +* @author (last) “rkallala” +* @date (last) 09-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -17,6 +17,7 @@ #include "DialysatePumps.h" #include "FPInterface.h" +#include "FPOperationModes.h" #include "Messaging.h" #include "MessagePayloads.h" #include "ModeGenDialysate.h" @@ -37,22 +38,49 @@ // ********** private definitions ********** -#define TD_DATA_FRESHNESS_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< TD data freshness timeout (in ms). +#define TD_DATA_FRESHNESS_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< TD data freshness timeout (in ms). +#define TD_DIALYSATE_FLOWRATE_MIN_ML_MIN ( 50.0F ) ///< TD Min dialysate flow rate (mL/min) +#define TD_DIALYSATE_FLOWRATE_MAX_ML_MIN ( 600.0F ) ///< TD Max dialysate flow rate (mL/min) + +#define TD_UF_RATE_MIN_ML_MIN ( 0.0F ) ///< TD Min UF rate (mL/min) +#define TD_UF_RATE_MAX_ML_MIN ( 2000.0F / 60.0F ) ///< TD Max UF rate (mL/min) + +#define TD_DIALYSATE_TEMP_MIN_DEGC ( 35.0F ) ///< TD Min dialysate temperature (deg C) +#define TD_DIALYSATE_TEMP_MAX_DEGC ( 38.0F ) ///< TD Max dialysate temperature (deg C) + +#define TD_ACID_TYPE_MIN ( 0U ) ///< TD Min acid type index +#define TD_ACID_TYPE_MAX ( (U32)( NUM_OF_ACID_TYPE - 1U ) ) ///< TD Max acid type index + +#define TD_BICARB_TYPE_MIN ( 0U ) ///< TD Min bicarb type index +#define TD_BICARB_TYPE_MAX ( (U32)( NUM_OF_BICARB_TYPE - 1U ) ) ///< TD Max bicarb type index + +/// Enumeration of TD Treatment Overrides +typedef enum TD_Treatment_Override +{ + TD_TREATMENT_OVERRIDE_DIALYSATE_FLOWRATE = 0, ///< TD Dialysate flow rate + TD_TREATMENT_OVERRIDE_UF_RATE, ///< TD Ultrafilteration rate + TD_TREATMENT_OVERRIDE_DIALYSATE_TEMP, ///< TD Target Dialysate Temperature + TD_TREATMENT_OVERRIDE_ACID_TYPE, ///< TD Acid type + TD_TREATMENT_OVERRIDE_BICARB_TYPE, ///< TD Bicarb type + NUM_OF_TD_TREATMENT_OVERRIDES, ///< Number of TD override treatment parameters +} TD_TREATMENT_OVERRIDE_INDEX_T; + // ********** private data ********** // TD status -static TD_OP_MODE_T tdCurrentOpMode; ///< Current TD operation mode. -static U32 tdSubMode; ///< Current state (sub-mode) of current TD operation mode. -static F32 tdDialysateFlowrate; ///< TD dialysate flow rate -static F32 tdUFRate; ///< TD ultrafiltration rate -static F32 tdTargetDialysateTemp; ///< TD target dialysate temperature -static BOOL tdDialyzerBypass; ///< TD dialyzer bypass -static DD_ACID_TYPES_T tdAcidType; ///< TD Acid type. -static DD_BICARB_TYPES_T tdBicarbType; ///< TD Bicarb type. +static TD_OP_MODE_T tdCurrentOpMode; ///< Current TD operation mode. +static U32 tdSubMode; ///< Current state (sub-mode) of current TD operation mode. +static BOOL tdDialyzerBypass; ///< TD dialyzer bypass -static BOOL tdOpModeDataFreshFlag = FALSE; ///< Flag to signal/process fresh TD op mode data +static BOOL tdOpModeDataFreshFlag = FALSE; ///< Flag to signal/process fresh TD op mode data +static OVERRIDE_F32_T tdDialysateFlowrate; ///< TD Dialysate flow rate +static OVERRIDE_F32_T tdUFRate; ///< TD ultrafiltration rate +static OVERRIDE_F32_T tdDialysateTemp; ///< TD Target Dialysate Temperature +static OVERRIDE_U32_T tdAcidType; ///< TD Acid type +static OVERRIDE_U32_T tdBicarbType; ///< TD Bicarb type + // ********** private function prototypes ********** static void checkTDDataFreshness( ALARM_ID_T alarmID, BOOL *tdFreshDataFlag ); @@ -66,15 +94,37 @@ *************************************************************************/ void initTDInterface( void ) { - // Initialize unit variables - tdCurrentOpMode = MODE_INIT; - tdSubMode = 0; - tdDialysateFlowrate = MAX_DIALYSATE_FLOW_RATE; // Will update later based on the TD value - tdUFRate = 0.0F; - tdTargetDialysateTemp = 0.0F; - tdDialyzerBypass = FALSE; - tdAcidType = ACID_08_1251_1; - tdBicarbType = BICARB_08_677753_0; + // Initialize unit state variables + tdCurrentOpMode = MODE_INIT; + tdSubMode = 0U; + tdDialyzerBypass = FALSE; + tdOpModeDataFreshFlag = FALSE; + + // Initialize treatment parameters from TD + tdDialysateFlowrate.data = 0.0F; + tdDialysateFlowrate.ovData = 0.0F; + tdDialysateFlowrate.ovInitData = TD_DIALYSATE_FLOWRATE_MIN_ML_MIN; + tdDialysateFlowrate.override = OVERRIDE_RESET; + + tdUFRate.data = 0.0F; + tdUFRate.ovData = 0.0F; + tdUFRate.ovInitData = TD_UF_RATE_MIN_ML_MIN; + tdUFRate.override = OVERRIDE_RESET; + + tdDialysateTemp.data = 0.0F; + tdDialysateTemp.ovData = 0.0F; + tdDialysateTemp.ovInitData = TD_DIALYSATE_TEMP_MIN_DEGC; + tdDialysateTemp.override = OVERRIDE_RESET; + + tdAcidType.data = TD_ACID_TYPE_MIN; + tdAcidType.ovData = TD_ACID_TYPE_MIN; + tdAcidType.ovInitData = TD_ACID_TYPE_MIN; + tdAcidType.override = OVERRIDE_RESET; + + tdBicarbType.data = TD_BICARB_TYPE_MIN; + tdBicarbType.ovData = TD_BICARB_TYPE_MIN; + tdBicarbType.ovInitData = TD_BICARB_TYPE_MIN; + tdBicarbType.override = OVERRIDE_RESET; } /**********************************************************************//** @@ -185,7 +235,7 @@ *************************************************************************/ void setTDDialysateFlowrate( F32 dialFlowrate ) { - tdDialysateFlowrate = dialFlowrate; + tdDialysateFlowrate.data = dialFlowrate; } /*********************************************************************//** @@ -198,21 +248,21 @@ *************************************************************************/ void setTDUFRate( F32 ufRate ) { - tdUFRate = ufRate; + tdUFRate.data = ufRate; } /*********************************************************************//** * @brief * The setTDTargetDialysateTemperature function sets the latest TD dialysate * temperature. * @details \b Inputs: none - * @details \b Outputs: tdTargetDialysateTemp + * @details \b Outputs: tdDialysateTemp * @param Target dialysate temperature. * @return none. *************************************************************************/ void setTDTargetDialysateTemperature( F32 dialTemperature ) { - tdTargetDialysateTemp = dialTemperature; + tdDialysateTemp.data = dialTemperature; } /*********************************************************************//** @@ -241,8 +291,8 @@ *************************************************************************/ void setTDAcidAndBicarbType( U32 acid, U32 bicarb ) { - tdAcidType = (DD_ACID_TYPES_T)acid; - tdBicarbType = (DD_BICARB_TYPES_T)bicarb; + tdAcidType.data = (DD_ACID_TYPES_T)acid; + tdBicarbType.data = (DD_BICARB_TYPES_T)bicarb; } /*********************************************************************//** @@ -255,7 +305,7 @@ *************************************************************************/ F32 getTDDialysateFlowrate( void ) { - return tdDialysateFlowrate; + return getF32OverrideValue( &tdDialysateFlowrate ); } /*********************************************************************//** @@ -268,20 +318,20 @@ *************************************************************************/ F32 getTDUFRate( void ) { - return tdUFRate; + return getF32OverrideValue( &tdUFRate ); } /*********************************************************************//** * @brief * The getTDTargetDialysateTemperature function gets the latest TD * target dialysate temperature rate. - * @details \b Inputs: tdTargetDialysateTemp + * @details \b Inputs: tdDialysateTemp * @details \b Outputs: none * @return Latest target dialysate temperature. *************************************************************************/ F32 getTDTargetDialysateTemperature( void ) { - return tdTargetDialysateTemp; + return getF32OverrideValue( &tdDialysateTemp ); } /*********************************************************************//** @@ -297,17 +347,20 @@ return tdDialyzerBypass; } -/*********************************************************************//** + +/****************************************************************************** * @brief * The getTDAcidConcentrateType function gets the latest Acid concentrate * type. * @details \b Inputs: tdAcidType - * @details \b Outputs: none - * @return Latest acid concentrate type. - *************************************************************************/ + * @details \b Outputs: None + * @return Latest acid concentrate type. . + ******************************************************************************/ DD_ACID_TYPES_T getTDAcidConcentrateType( void ) { - return tdAcidType; + U32 value = getU32OverrideValue( &tdAcidType ); + + return (DD_ACID_TYPES_T)value; } /*********************************************************************//** @@ -320,7 +373,9 @@ *************************************************************************/ DD_BICARB_TYPES_T getTDBicarbConcentrateType( void ) { - return tdBicarbType; + U32 value = getU32OverrideValue( &tdBicarbType ); + + return (DD_BICARB_TYPES_T)value; } /*********************************************************************//** @@ -341,16 +396,30 @@ { PRE_GEN_DIALYSATE_REQ_PAYLOAD_T startPreGenRequest; DD_OP_MODE_T ddMode = getCurrentOperationMode(); + FP_OP_MODE_T fpMode = getCurrentFPOperationMode(); memcpy( &startPreGenRequest, message->payload, sizeof( PRE_GEN_DIALYSATE_REQ_PAYLOAD_T ) ); // Process the pre-gen dialysate delivery request message if ( ( DD_MODE_STAN == ddMode ) && ( TRUE == startPreGenRequest.start ) ) { // Start FP Pre-Generate Permeate - fpReason = signalStartGenPermeate(); + + if ( FP_MODE_STAN == fpMode ) + { + fpReason = signalStartGenPermeate(); + } + else + { + fpReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } // start pre-gen dialysate result = requestDDPreGenStart(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } // Update Temperature, Acid/Bicarb type and dialysate rate for pregen process. setTDDialysateFlowrate( startPreGenRequest.dialRate ); setTDTargetDialysateTemperature( startPreGenRequest.dialTemp ); @@ -364,6 +433,11 @@ result = requestDDPreGenStop(); // stop FP Pre-Generate Permeate fpReason = signalStopGenPermeate(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } } } } @@ -419,6 +493,11 @@ result = requestDDGenDialyasteStop(); // stop FP Pre-Generate Permeate fpReason = signalStopGenPermeate(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } } else { @@ -450,4 +529,58 @@ *************************************************************************/ +/****************************************************************************** +* @brief +* Processes TD treatment parameter override request from Dialin. +* @details \b Inputs: Override payload from Dialin (TEST_OVERRIDE_ARRAY_PAYLOAD_T) +* @details \b Outputs: Updated TD override structures and treatment parameter +* update flag. +* @param message Pointer to the override message received from Dialin. +* @return TRUE if the override is successfully applied, FALSE otherwise. +******************************************************************************/ +BOOL testTDTreatmentParamsOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + + getOverrideArrayPayloadFromMessage( message, &payload ); + + if ( DD_MODE_GEND == getCurrentOperationMode() ) + { + switch ( (TD_TREATMENT_OVERRIDE_INDEX_T)payload.index ) + { + case TD_TREATMENT_OVERRIDE_DIALYSATE_FLOWRATE: + result = f32Override( message, &tdDialysateFlowrate ); + break; + + case TD_TREATMENT_OVERRIDE_UF_RATE: + result = f32Override( message, &tdUFRate ); + break; + + case TD_TREATMENT_OVERRIDE_DIALYSATE_TEMP: + result = f32Override( message, &tdDialysateTemp ); + break; + + case TD_TREATMENT_OVERRIDE_ACID_TYPE: + result = u32Override( message,&tdAcidType,TD_ACID_TYPE_MIN,TD_ACID_TYPE_MAX ); + break; + + case TD_TREATMENT_OVERRIDE_BICARB_TYPE: + result = u32Override( message,&tdBicarbType,TD_BICARB_TYPE_MIN,TD_BICARB_TYPE_MAX ); + break; + + default: + result = FALSE; + break; + } + + if ( TRUE == result ) + { + setTreatmentParamUpdate(); + } + } + + return result; +} + /**@}*/ Index: firmware/App/Services/TDInterface.h =================================================================== diff -u -rc07917caced76b53a0ed8f35167fac6f9d8310a4 -rf4a8565c7edec12094b8a737ed7b8cd3424a9208 --- firmware/App/Services/TDInterface.h (.../TDInterface.h) (revision c07917caced76b53a0ed8f35167fac6f9d8310a4) +++ firmware/App/Services/TDInterface.h (.../TDInterface.h) (revision f4a8565c7edec12094b8a737ed7b8cd3424a9208) @@ -7,8 +7,8 @@ * * @file TDInterface.h * -* @author (last) Vinayakam Mani -* @date (last) 30-May-2025 +* @author (last) Varshini Nagabooshanam +* @date (last) 04-Dec-2025 * * @author (original) Vinayakam Mani * @date (original) 06-Nov-2024 @@ -57,6 +57,8 @@ DD_ACID_TYPES_T getTDAcidConcentrateType( void ); DD_BICARB_TYPES_T getTDBicarbConcentrateType( void ); +BOOL testTDTreatmentParamsOverride( MESSAGE_T *message ); + /**@}*/ #endif