/************************************************************************** * * Copyright (c) 2025-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModePreGenDialysate.c * * @author (last) Sameer Kalliadan Poyil * @date (last) 10-Jul-2026 * * @author (original) Vinayakam Mani * @date (original) 18-Apr-2025 * ***************************************************************************/ #include "BalancingChamber.h" #include "ConcentratePumps.h" #include "DialysatePumps.h" #include "DryBiCart.h" #include "FPOperationModes.h" #include "Heaters.h" #include "Level.h" #include "ModePreGenDialysate.h" #include "ModeGenDialysate.h" #include "ModeFault.h" #include "Messaging.h" #include "OperationModes.h" #include "Pressure.h" #include "RinsePump.h" #include "TaskGeneral.h" #include "Timers.h" #include "Utilities.h" #include "Valves.h" /** * @addtogroup DDPreGenDialysateMode * @{ */ // ********** private definitions ********** /// Interval (ms/task time) at which the pre-treatment state data is published on the CAN bus. #define PRE_GEN_DIALYSATE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pre-gen dialysate mode data published. #define HYD_CHAMBER_PRES_CHECK_TIME_OUT ( 30 * MS_PER_SECOND ) ///< Time out period when hydraulics chamber pressure check initiated #define NEG_PRES_PERSISTENCE_TIME_MS ( 1 * MS_PER_SECOND ) ///< Persistence time for Hydraulics chamber negative degassing pressure check. #define PRE_GEN_DEFAULT_TIME_OUT ( 60 * MS_PER_SECOND ) #define PRE_GEN_FILL_HYDRO_CHAMBER_TIMEOUT ( 120 * MS_PER_SECOND ) #define PRE_GEN_PRIME_CONCENTRATE_TIMEOUT ( 120 * MS_PER_SECOND ) #define PRE_GEN_PRIME_CONCENTRATE_PUMP_SPEED 100.0F #define PRE_GEN_PRIME_CONCENTRATE_VOLUME 0xFFFF #define PRE_GEN_PRIME_BAL_CHAMBER_CONCENTRATE_PUMP_SPEED 60.0F #define PRE_GEN_PRIME_D12_RPM 1500.0F #define PRE_GEN_PRIME_D48_RPM 2000.0F #define PRE_GEN_PRIME_DIALYZER_CONCENTRATE_PUMP_SPEED 30.0F // ********** private data ********** static DD_PRE_GEN_DIALYSATE_STATE_T preGenDialysateState; ///< Currently active pre-gen dialysate state. static DD_WET_SELF_TEST_STATE_T wetSelfTestState; ///< Currently active pre-gen Wet self test state. static U32 hydChamberPressureCheckStartTimeMS; ///< Current time when hydraulics chamber pressure check started in milliseconds. static U32 pressureCheckPersistanceStartTimeMS; ///< Current time for pressure check persistance time started in milliseconds. static BOOL pendingStartDDGenDialRequest; ///< Flag indicating TD has requested DD start the generation dialysate request. static BOOL pendingStopDDPreGenDialRequest; ///< Flag indicating TD has requested DD stop the pre generation dialysate. static U32 preGenDialysatePublishTimerCounter; ///< Pre-Gen Dialysate data broadcast timer counter used to schedule when to transmit data. static OVERRIDE_U32_T preGenDialysateModePublishInterval; ///< Interval (in task intervals) at which to publish pre-gen dialysate mode data to CAN bus. static U32 preGenAcidPrimeTimer; static U32 preGenBicarbPrimeTimer; static U32 preGenfillChamberCTimer; static BOOL currentHydroChamberStatus; // ********** private function prototypes ********** static void publishPreGenDialysateState( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handlePreGenDialysateFillCompleteCheckState( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handleDryBicartInitialFillState( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handleFillChamberF( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handlePrimeBicarbLine( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handlePrimeAcidLine( void ); static DD_PRE_GEN_DIALYSATE_STATE_T handleWaitForFPState( void ); static void setModePreGenDialysateTransition( DD_PRE_GEN_DIALYSATE_STATE_T state ); //Wet Self test static void setModePreGenWetSelfStateTransition( DD_WET_SELF_TEST_STATE_T state ); static void execWetSelfTest( void ); static DD_WET_SELF_TEST_STATE_T handleNegativeDeaerationPressureCheckState( void ); static DD_WET_SELF_TEST_STATE_T handlePositiveDeaerationPressureCheckState( void ); /*********************************************************************//** * @brief * The initPreGenDialysateMode function initializes the Pre-Generation * Dialysate Mode unit. * @details \b Inputs : none * @details \b Outputs: Pre-Gen Dialysate mode unit initialized * @return none *************************************************************************/ void initPreGenDialysateMode( void ) { preGenDialysateState = DD_PRE_GEN_WAIT_FOR_FP_GEN; wetSelfTestState = DD_WET_SELF_TEST_START; hydChamberPressureCheckStartTimeMS = 0; pressureCheckPersistanceStartTimeMS = 0; pendingStartDDGenDialRequest = FALSE; pendingStopDDPreGenDialRequest = FALSE; preGenDialysateModePublishInterval.data = PRE_GEN_DIALYSATE_DATA_PUB_INTERVAL; preGenDialysateModePublishInterval.ovData = PRE_GEN_DIALYSATE_DATA_PUB_INTERVAL; preGenDialysateModePublishInterval.ovInitData = 0; preGenDialysateModePublishInterval.override = OVERRIDE_RESET; currentHydroChamberStatus = FALSE; preGenAcidPrimeTimer = 0; preGenBicarbPrimeTimer = 0; preGenfillChamberCTimer = 0; } /*********************************************************************//** * @brief * The transitionToPreGenDialysateMode function prepares for transition * to Pre-Gen Dialysate mode from standby mode. * @details \b Inputs: none * @details \b Outputs: none * @return initial state *************************************************************************/ U32 transitionToPreGenDialysateMode( void ) { initPreGenDialysateMode(); deenergizeActuators( PARK_CONC_PUMPS ); // Deactivate Balancing Chamber Switching requestBalChamberSwitching( FALSE ); setCurrentSubState( NO_SUB_STATE ); return preGenDialysateState; } /*********************************************************************//** * @brief * The execPreGenDialysateMode function executes the Pre-Gen Dialysate mode * state machine. * @details \b Inputs: preGenDialysateState * @details \b Outputs: Pre-Gen Dialysate mode state machine executed * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong pre gen dialysate * state invoked * @return current state of Pre-Gen Dialysate Mode *************************************************************************/ U32 execPreGenDialysateMode( void ) { DD_PRE_GEN_DIALYSATE_STATE_T prevState = preGenDialysateState; if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_SKIP_PRE_GEN_PRIMING ) ) { preGenDialysateState = DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND; } //Manage Inlet water control after hydro chamber fill if( DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK < preGenDialysateState ) { currentHydroChamberStatus = hydChamberWaterInletControl(); } //TODO: Transition to post gen dialysate if concentrate priming has been started if ( TRUE == pendingStopDDPreGenDialRequest ) { pendingStopDDPreGenDialRequest = FALSE; requestNewOperationMode( DD_MODE_STAN ); } else { // execute current pre-gen dialysate state switch ( preGenDialysateState ) { case DD_PRE_GEN_WAIT_FOR_FP_GEN: preGenDialysateState = handleWaitForFPState(); break; case DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK: preGenDialysateState = handlePreGenDialysateFillCompleteCheckState(); break; case DD_PRE_GEN_DRY_BICART_INITIAL_FILL: preGenDialysateState = handleDryBicartInitialFillState(); break; case DD_PRE_GEN_FILL_CHAMBER_F: preGenDialysateState = handleFillChamberF(); break; case DD_PRE_GEN_PRIME_BICARB_LINE: preGenDialysateState = handlePrimeBicarbLine(); break; case DD_PRE_GEN_PRIME_ACID_LINE: preGenDialysateState = handlePrimeAcidLine(); break; case DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND: if ( TRUE == pendingStartDDGenDialRequest ) { pendingStartDDGenDialRequest = FALSE; requestNewOperationMode( DD_MODE_GEND ); } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_PRE_GEND_MODE_INVALID_EXEC_STATE, preGenDialysateState ) break; } } if ( prevState != preGenDialysateState ) { setModePreGenDialysateTransition( preGenDialysateState ); SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_PRE_GEN_CHANGE, prevState, preGenDialysateState ) } publishPreGenDialysateState(); return preGenDialysateState; } /*********************************************************************//** * @brief * The getCurrentPreGenDialysateState function returns the current state * of the Pre-Gen Dialysate mode. * @details \b Inputs: preGenDialysateState * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ DD_PRE_GEN_DIALYSATE_STATE_T getCurrentPreGenDialysateState( void ) { return preGenDialysateState; } /*********************************************************************//** * @brief * The requestDDGenDialStart function handles an TD request to start * generation dialysis mode. * @details \b Inputs: Pre generation dailysate state * @details \b Outputs: pendingStartDDGenDialRequest * @return TRUE if request accepted, FALSE if not. *************************************************************************/ BOOL requestDDGenDialStart( void ) { BOOL result = FALSE; if ( DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND == preGenDialysateState ) { result = TRUE; pendingStartDDGenDialRequest = TRUE; } return result; } /*********************************************************************//** * @brief * The requestDDPreGenStop function handles an TD request to stop * pre-generation dialysis mode. * @details \b Inputs: Pre generation dialysate mode / state * @details \b Outputs: pendingStopDDPreGenDialRequest * @return TRUE if request accepted, FALSE if not. *************************************************************************/ BOOL requestDDPreGenStop( void ) { BOOL status = FALSE; if ( DD_MODE_PREG == getCurrentOperationMode() ) { pendingStopDDPreGenDialRequest = TRUE; status = TRUE; } return status; } /*********************************************************************//** * @brief * The handleWaitForFPState function checks the state of FP * transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ static DD_PRE_GEN_DIALYSATE_STATE_T handleWaitForFPState( void ) { DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_WAIT_FOR_FP_GEN; FP_OP_MODE_T fpMode = getCurrentFPOperationMode(); if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_RUN_SOLO ) ) { state = DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK; } else if ( ( FP_MODE_DEGP == fpMode ) || ( FP_MODE_GENP == fpMode ) ) { state = DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK; } //TODO: Should DD keep a timer and Alarm if FP never transitions? return state; } /*********************************************************************//** * @brief * The handlePreGenDialysateFillCompleteCheckState function checks the * hydrochamber fill and transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ static DD_PRE_GEN_DIALYSATE_STATE_T handlePreGenDialysateFillCompleteCheckState( void ) { DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK; if ( LVL_STATE_HIGH == getFloaterStatus( D6_LEVL ) ) { state = DD_PRE_GEN_FILL_CHAMBER_F; //TODO: Rework disable dry bicarb config. Currently skipping // all concentrate related priming if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_DRY_BICARB ) ) { state = DD_PRE_GEN_PRIME_BICARB_LINE; } } //TODO: Timeout alarm. 120s return state; } /*********************************************************************//** * @brief * The handleDryBicartInitialFillState function executes initial dry bicart fill request * @details \b Inputs: none * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ static DD_PRE_GEN_DIALYSATE_STATE_T handleDryBicartInitialFillState( void ) { //TODO: Change to wet self test state later DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_DRY_BICART_INITIAL_FILL; if ( TRUE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_DRY_BICARB ) ) { state = DD_PRE_GEN_FILL_CHAMBER_F; } else { // stay in this state till bicart fill complete. if ( getCurrentDryBiCartPreGenFillExecState() == DRY_BICART_FILL_COMPLETE_STATE ) { state = DD_PRE_GEN_FILL_CHAMBER_F; } // TODO: Alarm if it is not completed within 1.5 minutes } return state; } /*********************************************************************//** * @brief * The handleFillChamberF function checks the * chamber F fill and transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ static DD_PRE_GEN_DIALYSATE_STATE_T handleFillChamberF( void ) { DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_FILL_CHAMBER_F; if ( PRE_GEN_BICARB_SUPPLY_VENT_END_STATE == getCurrentDryBiCartPreGenFillExecState() ) { state = DD_PRE_GEN_PRIME_BICARB_LINE; } //TODO: Timeout alarm. 120s return state; } /*********************************************************************//** * @brief * The handlePrimeBicarbLine function handles priming the bicarb line * and transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of PreGenDialysate mode *************************************************************************/ static DD_PRE_GEN_DIALYSATE_STATE_T handlePrimeBicarbLine( void ) { DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_PRIME_BICARB_LINE; if ( TRUE == didTimeout( preGenBicarbPrimeTimer, PRE_GEN_PRIME_CONCENTRATE_TIMEOUT ) ) { state = DD_PRE_GEN_PRIME_ACID_LINE; } return state; } static DD_PRE_GEN_DIALYSATE_STATE_T handlePrimeAcidLine( void ) { DD_PRE_GEN_DIALYSATE_STATE_T state = DD_PRE_GEN_PRIME_ACID_LINE; if ( TRUE == didTimeout( preGenAcidPrimeTimer, PRE_GEN_PRIME_CONCENTRATE_TIMEOUT ) ) { state = DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND; } return state; } /*********************************************************************//** * @brief * The setModeGenPDefTransition function sets the actuators and variables * for the state transition in generate permeate mode. * @details Inputs: none * @details Outputs: Actuate valves, pumps as desired. * @param state gen permeate state enum * @return none *************************************************************************/ static void setModePreGenDialysateTransition( DD_PRE_GEN_DIALYSATE_STATE_T state ) { // Execute on running state switch( state ) { case DD_PRE_GEN_WAIT_FOR_FP_GEN: break; case DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK: preGenfillChamberCTimer = getMSTimerCount(); setValveState( D14_VALV, VALVE_STATE_CLOSED ); setValveState( D3_VALV, VALVE_STATE_OPEN ); break; case DD_PRE_GEN_DRY_BICART_INITIAL_FILL: if ( FALSE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_DRY_BICARB ) ) { setBicartFillRequested(); } break; case DD_PRE_GEN_FILL_CHAMBER_F: if ( FALSE == getTestConfigStatus( TEST_CONFIG_DD_DISABLE_DRY_BICARB ) ) { setBicartPreGenFillRequested(); } setDialysatePumpTargetRPM( D12_PUMP, PRE_GEN_PRIME_D12_RPM, TRUE ); break; case DD_PRE_GEN_PRIME_BICARB_LINE: preGenBicarbPrimeTimer = getMSTimerCount(); // dialyzer bypass setValveState( D34_VALV, VALVE_STATE_OPEN ); setValveState( D91_VALV, VALVE_STATE_CLOSED ); setValveState( D35_VALV, VALVE_STATE_CLOSED ); setValveState( D40_VALV, VALVE_STATE_CLOSED ); // open BC fresh side setValveState( D19_VALV, VALVE_STATE_OPEN ); setValveState( D20_VALV, VALVE_STATE_OPEN ); setValveState( D21_VALV, VALVE_STATE_OPEN ); setValveState( D22_VALV, VALVE_STATE_OPEN ); // close BC spent side setValveState( D23_VALV, VALVE_STATE_CLOSED ); setValveState( D24_VALV, VALVE_STATE_CLOSED ); setValveState( D25_VALV, VALVE_STATE_CLOSED ); setValveState( D26_VALV, VALVE_STATE_CLOSED ); //vent air to chamber h setValveState( D47_VALV, VALVE_STATE_OPEN ); setValveState( D14_VALV, VALVE_STATE_CLOSED ); setValveState( D80_VALV, VALVE_STATE_CLOSED ); //set bicarb concentrate pump and rinse pump setRinsePumpState( RINSE_PUMP_STATE_ON ); setConcentratePumpTargetSpeed( D10_PUMP, PRE_GEN_PRIME_CONCENTRATE_PUMP_SPEED, PRE_GEN_PRIME_CONCENTRATE_VOLUME ); requestConcentratePumpOn( D10_PUMP ); break; case DD_PRE_GEN_PRIME_ACID_LINE: requestConcentratePumpOff( D10_PUMP, FALSE ); //TODO: Merge concentrate line priming to one state. preGenAcidPrimeTimer = getMSTimerCount(); // dialyzer bypass setValveState( D34_VALV, VALVE_STATE_OPEN ); setValveState( D91_VALV, VALVE_STATE_CLOSED ); setValveState( D35_VALV, VALVE_STATE_CLOSED ); setValveState( D40_VALV, VALVE_STATE_CLOSED ); // open BC fresh side setValveState( D19_VALV, VALVE_STATE_OPEN ); setValveState( D20_VALV, VALVE_STATE_OPEN ); setValveState( D21_VALV, VALVE_STATE_OPEN ); setValveState( D22_VALV, VALVE_STATE_OPEN ); // close BC spent side setValveState( D23_VALV, VALVE_STATE_CLOSED ); setValveState( D24_VALV, VALVE_STATE_CLOSED ); setValveState( D25_VALV, VALVE_STATE_CLOSED ); setValveState( D26_VALV, VALVE_STATE_CLOSED ); //vent air to chamber h setValveState( D47_VALV, VALVE_STATE_OPEN ); setValveState( D14_VALV, VALVE_STATE_CLOSED ); setValveState( D80_VALV, VALVE_STATE_CLOSED ); //set acid concentrate pump and rinse pump setRinsePumpState( RINSE_PUMP_STATE_ON ); setConcentratePumpTargetSpeed( D11_PUMP, PRE_GEN_PRIME_CONCENTRATE_PUMP_SPEED, PRE_GEN_PRIME_CONCENTRATE_VOLUME ); requestConcentratePumpOn( D11_PUMP ); break; case DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND: //TODO: update to recirculation instead of off states. requestConcentratePumpOff( D10_PUMP, FALSE ); requestConcentratePumpOff( D11_PUMP, FALSE ); setRinsePumpState( RINSE_PUMP_STATE_OFF ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FP_SOFTWARE_FAULT, FP_FAULT_ID_FP_INVALID_GENP_STATE, state ) break; } } /*********************************************************************//** * @brief * The setModePreGenWetSelfStateTransition function sets the actuators and variables * for the state transition in pre-gen WetSlef test mode. * @details Inputs: Valve states, Pump speed * @details Outputs: Actuate valves, pumps as desired. * @param state pre gen wet self test state enum * @return none *************************************************************************/ static void setModePreGenWetSelfStateTransition( DD_WET_SELF_TEST_STATE_T state ) { // Execute on running state switch( state ) { case DD_WET_SELF_TEST_START: // DO nothing break; case DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK: // Start timer for hyd chamber negative pressure check state hydChamberPressureCheckStartTimeMS = getMSTimerCount(); // Start D12/Degassing pump - closed loop control setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); break; case DD_WET_SELF_TEST_POSITIVE_DEAERATION_PRES_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_SPENT_DIAL_PRES_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_BAL_CHAMBER_VALV_LEAK_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_DIAL_FLOW_PATH_LEAK_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_UF_PRES_DROP_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_BLOOD_LEAK_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_BAL_CHAMBER_MEMBRANE_INTEGRITY_CHECK: // TODO : lists the valves/pumps state break; case DD_WET_SELF_TEST_LEVEL_SENSOR_CHECK: //TODO : define actuators states break; case DD_WET_SELF_TEST_PAUSE: //TODO : define actuators states break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE1, state ) break; } } /*********************************************************************//** * @brief * The execWetSelfTest function executes the pregen mode wet self test state machine. * @details \b Inputs: wetSelfTestState * @details \b Outputs: Wet self test state machine executed * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong pre gen wet self test * state invoked. * @return current wet self state. *************************************************************************/ static void execWetSelfTest( void ) { DD_WET_SELF_TEST_STATE_T priorSubState = wetSelfTestState; // execute current Wet self test state switch ( wetSelfTestState ) { case DD_WET_SELF_TEST_START: setModePreGenWetSelfStateTransition( DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK ); wetSelfTestState = DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK; break; case DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK: wetSelfTestState = handleNegativeDeaerationPressureCheckState(); break; case DD_WET_SELF_TEST_POSITIVE_DEAERATION_PRES_CHECK: wetSelfTestState = handlePositiveDeaerationPressureCheckState(); break; case DD_WET_SELF_TEST_PAUSE: //TODO : define state break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_PRE_GEND_WET_SELF_TEST_INVALID_EXEC_STATE, wetSelfTestState ) wetSelfTestState = DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK; break; } if ( priorSubState != wetSelfTestState ) { setCurrentSubState( (U32)wetSelfTestState ); //SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_SUB_STATE_CHANGE, priorSubState, wetSelfTestState ); } //TODO: Publish wet self test status //publishWetSelfTestData(); } /*********************************************************************//** * @brief * The handleNegativeDeaerationPressureCheckState function checks the * negative deaeration pressure check range and transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of Wet Self test *************************************************************************/ static DD_WET_SELF_TEST_STATE_T handleNegativeDeaerationPressureCheckState( void ) { DD_WET_SELF_TEST_STATE_T state = DD_WET_SELF_TEST_NEGATIVE_DEAERATION_PRES_CHECK; F32 hydPressure = getFilteredPressure( D9_PRES ); // For Degassing close loop pump control, the calculated negative pressure added up with pressure adjustment factor // to drive more negative pressure.Remove the pressure adjustment factor for actual pressure check. F32 targetPressure = getDialysatePumpTargetPressure( D12_PUMP ) - DEGAS_PUMP_TARGET_PRES_ADJ_THRESHOLD; if ( hydPressure <= targetPressure ) { if ( 0 == pressureCheckPersistanceStartTimeMS ) { pressureCheckPersistanceStartTimeMS = getMSTimerCount(); } else if ( TRUE == didTimeout( pressureCheckPersistanceStartTimeMS, NEG_PRES_PERSISTENCE_TIME_MS ) ) { pressureCheckPersistanceStartTimeMS = 0; state = DD_WET_SELF_TEST_POSITIVE_DEAERATION_PRES_CHECK; setModePreGenWetSelfStateTransition ( state ); } } else if ( TRUE == didTimeout( hydChamberPressureCheckStartTimeMS, HYD_CHAMBER_PRES_CHECK_TIME_OUT ) ) { // time out alarm and pause the self test SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DD_GEND_HYD_CHAMBER_PRESS_OUT_OF_RANGE, hydPressure ); state = DD_WET_SELF_TEST_PAUSE; setModePreGenWetSelfStateTransition ( state ); } return state; } /*********************************************************************//** * @brief * The handlePositiveDeaerationPressureCheckState function checks the * postive deaeration pressure check range and transition to next state. * @details \b Inputs: state * @details \b Outputs: none * @return current state of Wet Self test *************************************************************************/ static DD_WET_SELF_TEST_STATE_T handlePositiveDeaerationPressureCheckState( void ) { //TODO: define pressure check DD_WET_SELF_TEST_STATE_T state = DD_WET_SELF_TEST_POSITIVE_DEAERATION_PRES_CHECK; return state; } /*********************************************************************//** * @brief * The publishPreGenDialysateState function publishes Pre-Generation dialysate * mode data. * @details \b Inputs: preGenDialysatePublishTimerCounter, preGenDialysateModePublishInterval * @details \b Outputs: preGenDialysatePublishTimerCounter * @details \b Message \Sent: MSG_ID_DD_PRE_GEN_DIALYSATE_STATE_DATA to publish the * pre generate dialysate mode data. * @return none *************************************************************************/ static void publishPreGenDialysateState( void ) { // publish data at periodic interval if ( ++preGenDialysatePublishTimerCounter >= getU32OverrideValue( &preGenDialysateModePublishInterval ) ) { PRE_GEN_DIALYSATE_STATE_DATA_T preGenDialysateData; preGenDialysateData.preGenDialysateExecState = preGenDialysateState; broadcastData( MSG_ID_DD_PRE_GEN_DIALYSATE_STATE_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&preGenDialysateData, sizeof( PRE_GEN_DIALYSATE_STATE_DATA_T ) ); preGenDialysatePublishTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testDDPreGenDialysateDataPublishIntervalOverride function overrides the * DD pre generate dialysate mode data publish interval. * @details \b Inputs: preGenDialysateModePublishInterval * @details \b Outputs: preGenDialysateModePublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the DD pre generate dialysate data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDDPreGenDialysateDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &preGenDialysateModePublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testValidateDDPreGenDialysateChangeReq function validate whether request * operation sub mode is legal or not. * @details \b Inputs: none * @details \b Outputs: none * @param newSubMode the enumerated sub state of the mode * @return TRUE if request is legal, FALSE if not *************************************************************************/ BOOL testValidateDDPreGenDialysateChangeReq( U32 newSubMode ) { BOOL result = FALSE; if ( newSubMode < NUM_OF_DD_PRE_GEN_DIALYSATE_STATES ) { switch ( newSubMode ) { // TODO add validate condition after checking with Vinay case DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK: case DD_PRE_GEN_DRY_BICART_INITIAL_FILL: case DD_PRE_GEN_FILL_CHAMBER_F: case DD_PRE_GEN_PRIME_BICARB_LINE: case DD_PRE_GEN_PRIME_ACID_LINE: case DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND: result = TRUE; break; default: break; } } return result; } /*********************************************************************//** * @brief * The testSignalNewDDPreGenDialysateSubMode function request transition * to a new operation sub mode. * @details \b Inputs: none * @details \b Outputs: preGenDialysateState * @param newSubMode the enumerated sub state of the mode * @return none *************************************************************************/ void testSignalNewDDPreGenDialysateSubMode( U32 newSubMode ) { if ( newSubMode < NUM_OF_DD_PRE_GEN_DIALYSATE_STATES ) { preGenDialysateState = (DD_PRE_GEN_DIALYSATE_STATE_T)newSubMode; switch ( newSubMode ) { // TODO add logic after checking with Vinay // Any of these state require no special handling case DD_PRE_GEN_DIALYSATE_HYD_CHAMBER_FILL_CHECK: case DD_PRE_GEN_DRY_BICART_INITIAL_FILL: case DD_PRE_GEN_FILL_CHAMBER_F: case DD_PRE_GEN_PRIME_BICARB_LINE: case DD_PRE_GEN_PRIME_ACID_LINE: case DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND: default: break; } // TODO should setState handled separately for wet self state? } } /**@}*/