/************************************************************************** * * Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeGenDialysate.c * * @author (last) Vinayakam Mani * @date (last) 30-Oct-2024 * * @author (original) Vinayakam Mani * @date (original) 30-Oct-2024 * ***************************************************************************/ #include "BalancingChamber.h" #include "ConcentratePumps.h" #include "Conductivity.h" #include "DialysatePumps.h" #include "FpgaDD.h" #include "Heaters.h" #include "Level.h" #include "Messaging.h" #include "ModeGenDialysate.h" #include "ModeStandby.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Pressure.h" #include "TaskGeneral.h" #include "TDInterface.h" #include "Temperature.h" #include "Timers.h" #include "Valves.h" /** * @addtogroup DDGenDialysateMode * @{ */ // ********** private definitions ********** #define HYD_CHAMBER_FLUID_TEMP_C_MIN 35.0F ///< Minimum hydraulics fluid temperature in deg celcius #define GEN_DIALYSATE_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the gen dialysate mode data published. #define DIALYSATE_TEMP_OUT_OF_TARGET_CLEAR_TOL_C 2.0F ///< Dialysate temperature clear alarm tolerance C #define DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C 4.0F ///< Dialysate temperature out of target tolerance C. #define DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ( 90 * MS_PER_SECOND ) ///< Dialysate temperature out of target timeout in milliseconds. #define DIALYSATE_TEMP_UPPER_MAX_SAFETY_LIMIT_C 46.0F ///< Dialysate upper bound maximum temperature limit in C. #define DIALYSATE_TEMP_UPPER_MAX_SAFETY_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Dialysate temperature upper bound maximum safety timeout in milliseconds. #define DIALYSATE_TEMP_UPPER_SAFETY_LIMIT_C 42.0F ///< Dialysate upper bound safety temperature limit in C. #define DIALYSATE_TEMP_LOWER_SAFETY_LIMIT_C 33.0F ///< Dialysate lower bound safety temperature limit in C. #define DIALYSATE_TEMP_CLEAR_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature clear persistence timeout. //Testing #define DELAY_BC_SWITCHING_AT_START_UP ( 3 * MS_PER_SECOND ) ///< Provide a balancing chamber switching start up delay to stabilize pump speed etc., /// Payload record structure for Gen dialysate execution state set request typedef struct { U32 execStateSet; ///< Gen dialysate execution state machine set request } GEND_EXEC_STATE_SET_CMD_PAYLOAD_T; // ********** private data ********** static DD_GEND_MODE_STATE_T genDialysateState = DD_GEND_STATE_START; ///< Currently active gen dialysate state. static OVERRIDE_F32_T targetHydChamberFluidTemp; ///< Target hydraulics chamber fluid temperature. static OVERRIDE_U32_T isDialDeliveryInProgress; ///< To indicate dialysate started delivering to dialyzer for treatment (overrideable) static OVERRIDE_U32_T isDialysateGoodtoDeliver; ///< Flag indicating whether ready to deliver dialysate or not. static BOOL pendingStopDDGenDialRequest; ///< Flag indicating TD has requested DD stop the generate dialysate. static U32 genDialysateDataPublicationTimerCounter; ///< Used to schedule generate dialysate data publication to CAN bus. static OVERRIDE_U32_T genDialysateDataPublishInterval; ///< Generate dialysate mode data publish interval. static BOOL isTreatmentParamUpdated; ///< To indicate change in treatment parameters //Testing static U32 bypassStateDelayStartTimeMS; ///< Delay balancing chamber switching for a second to preapre pump steady state. static BOOL delayBypassStateFlag; ///< To indicate change in treatment parameters // ********** private function prototypes ********** static void setModeGenDStateTransition( DD_GEND_MODE_STATE_T state ); static DD_GEND_MODE_STATE_T handleGenDDialysateBypassState( void ); static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryState( void ); static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryPauseState( void ); static DD_GEND_MODE_STATE_T handleGenDDialysateIsolatedUFState( void ); static F32 getGenDialysateTargetTemperature( void ); static void checkDialysateTemperature( void ); static void publishGenDialysateModeData( void ); /*********************************************************************//** * @brief * The initGenDialysateMode function initializes the dialysis generation mode unit. * @details \b Inputs: none * @details \b Outputs: Gen dialysate mode unit initialized * @return none *************************************************************************/ void initGenDialysateMode( void ) { targetHydChamberFluidTemp.data = HYD_CHAMBER_FLUID_TEMP_C_MIN; targetHydChamberFluidTemp.ovInitData = HYD_CHAMBER_FLUID_TEMP_C_MIN; targetHydChamberFluidTemp.ovData = HYD_CHAMBER_FLUID_TEMP_C_MIN; targetHydChamberFluidTemp.override = OVERRIDE_RESET; genDialysateState = DD_GEND_STATE_START; isDialysateGoodtoDeliver.data = FALSE; isDialysateGoodtoDeliver.ovData = FALSE; isDialysateGoodtoDeliver.ovInitData = FALSE; isDialysateGoodtoDeliver.override = OVERRIDE_RESET; isDialDeliveryInProgress.data = FALSE; isDialDeliveryInProgress.ovData = FALSE; isDialDeliveryInProgress.ovInitData = FALSE; isDialDeliveryInProgress.override = OVERRIDE_RESET; pendingStopDDGenDialRequest = FALSE; genDialysateDataPublishInterval.data = GEN_DIALYSATE_DATA_PUBLISH_INTERVAL; genDialysateDataPublishInterval.ovData = GEN_DIALYSATE_DATA_PUBLISH_INTERVAL; genDialysateDataPublishInterval.ovInitData = 0; genDialysateDataPublishInterval.override = OVERRIDE_RESET; genDialysateDataPublicationTimerCounter = 0; isTreatmentParamUpdated = FALSE; //Testing bypassStateDelayStartTimeMS = 0; delayBypassStateFlag = TRUE; //Initialize balancing chamber module initBalanceChamber(); initPersistentAlarm( ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, DIALYSATE_TEMP_CLEAR_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, DIALYSATE_TEMP_CLEAR_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP, DIALYSATE_TEMP_CLEAR_TIMEOUT_MS, DIALYSATE_TEMP_UPPER_MAX_SAFETY_TIMEOUT_MS ); } /*********************************************************************//** * @brief * The transitionToGenDialysateMode function prepares for transition to gen * dialysate mode. * @details \b Inputs: none * @details \b Outputs: none * @return initial state *************************************************************************/ U32 transitionToGenDialysateMode( void ) { initGenDialysateMode(); setCurrentSubState( NO_SUB_STATE ); return genDialysateState; } /*********************************************************************//** * @brief * The execGenDialysateMonitor function monitors the balancing chamber fill * operations and alarm if temperature and conductivity is not in range. * @details \b Inputs: isBalChamberFillInProgress * @details \b Outputs: isDialysateGoodtoDeliver * @return none. *************************************************************************/ void execGenDialysateMonitor( void ) { // Read temperature and conductivity //F32 hydChamberTemperature = getTemperatureValue( D4_TEMP ); //F32 biCarbConductivity = getConductivityValue( D17_COND ); //F32 acidBicarbMixConductivity = getConductivityValue( D29_COND ); // Monitor critical parameter while balancing chamber fill is in progress if ( TRUE == getBalancingChamberFillinProgressStatus() ) { // Temperature range check // Coductivity range check isDialysateGoodtoDeliver.data = TRUE; } } /*********************************************************************//** * @brief * The setModeGenDStateTransition function sets the actuators and variables * for the state transition in generate dialysis mode. * @details Inputs: Valve states, Pump speed * @details Outputs: Actuate valves, pumps as desired. * @param state gen dialysate state enum * @return none *************************************************************************/ static void setModeGenDStateTransition( DD_GEND_MODE_STATE_T state ) { // Execute on running state switch( state ) { case DD_GEND_STATE_START: // Do nothing break; case DD_GEND_DIALYSATE_BYPASS_STATE: //Previous state setValveState( M4_VALV, VALVE_STATE_OPEN ); // Get the target temperature from TD targetHydChamberFluidTemp.data = getTDTargetDialysateTemperature(); // Turn on the primary heater setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); startHeater( D5_HEAT ); setValveState( D14_VALV, VALVE_STATE_OPEN ); //Testing : Enable close loop once testing is complete //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve setValveState( D35_VALV, VALVE_STATE_CLOSED ); // VDI setValveState( D40_VALV, VALVE_STATE_CLOSED ); // VDO setValveState( D34_VALV, VALVE_STATE_OPEN ); // Bypass valve //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); transitionToBalChamberFill(); //Testing bypassStateDelayStartTimeMS = getMSTimerCount(); break; case DD_GEND_DIALYSATE_DELIVERY_STATE: //Previous state setValveState( M4_VALV, VALVE_STATE_OPEN ); // Get the target temperature from TD targetHydChamberFluidTemp.data = getTDTargetDialysateTemperature(); setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); startHeater( D5_HEAT ); setValveState( D14_VALV, VALVE_STATE_OPEN ); //setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D12_PUMP, FRESH_DIAL_PUMP_INITIAL_RPM, TRUE ); setValveState( D53_VALV, VALVE_STATE_OPEN ); // Drain valve //setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, FALSE ); setDialysatePumpTargetRPM( D48_PUMP, SPENT_DIAL_PUMP_INITIAL_RPM, TRUE ); // Disable bypass valve setValveState( D34_VALV, VALVE_STATE_CLOSED ); // Bypass valve setValveState( D35_VALV, VALVE_STATE_OPEN ); // VDI setValveState( D40_VALV, VALVE_STATE_OPEN ); // VDO break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: // stop the motor during pause conditions signalDialysatePumpHardStop( D12_PUMP ); signalDialysatePumpHardStop( D48_PUMP ); requestConcentratePumpOff( D11_PUMP, FALSE ); requestConcentratePumpOff( D10_PUMP, FALSE ); stopHeater( 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 the DD - water inlet and drain valves? break; case DD_GEND_ISOLATED_UF_STATE: //TODO : define actuators states break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_GEND_MODE_INVALID_EXEC_STATE1, state ) break; } } /*********************************************************************//** * @brief * The execGenDialysateMode function executes the Gen dialysate mode state machine. * @details \b Inputs: pendingStopDDGenDialRequest,genDialysateState * @details \b Outputs: Gen dialysate mode state machine executed * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when wrong gen dialysate state invoked. * @return current state. *************************************************************************/ U32 execGenDialysateMode( void ) { // Manage water level control hydChamberWaterInletControl(); // Update any dynamic treatment parameter changes updateTreatmentSettings(); //Check Dialysate Temperature checkDialysateTemperature(); //TODO: Transition to post gen dialysate then standby. if ( TRUE == pendingStopDDGenDialRequest ) { pendingStopDDGenDialRequest = FALSE; requestNewOperationMode( DD_MODE_STAN ); } // Continuous water inlet pressure check else if ( ( genDialysateState != DD_GEND_DIALYSATE_DELIVERY_PAUSE ) && ( TRUE == areInletWaterConditionsAlarmsActive() ) ) { //Check RO alarms as required setModeGenDStateTransition( DD_GEND_DIALYSATE_DELIVERY_PAUSE ); genDialysateState = DD_GEND_DIALYSATE_DELIVERY_PAUSE; } else { // execute current gen dialysate state switch ( genDialysateState ) { case DD_GEND_STATE_START: setModeGenDStateTransition( DD_GEND_DIALYSATE_BYPASS_STATE ); genDialysateState = DD_GEND_DIALYSATE_BYPASS_STATE; break; case DD_GEND_DIALYSATE_BYPASS_STATE: genDialysateState = handleGenDDialysateBypassState(); break; case DD_GEND_DIALYSATE_DELIVERY_STATE: genDialysateState = handleGenDDialysateDeliveryState(); break; case DD_GEND_DIALYSATE_DELIVERY_PAUSE: genDialysateState = handleGenDDialysateDeliveryPauseState(); break; case DD_GEND_ISOLATED_UF_STATE: genDialysateState = handleGenDDialysateIsolatedUFState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_GEND_MODE_INVALID_EXEC_STATE, genDialysateState ) genDialysateState = DD_GEND_STATE_START; break; } } //Publish Gen dialysate mode data publishGenDialysateModeData(); return genDialysateState; } /*********************************************************************//** * @brief * The hydChamberWaterInletControl function checks the water level and allow * the water into hydraulics for dialysate generation. * @details \b Inputs: floater levels. * @details \b Outputs: none * @return the current state of gen dialysate mode *************************************************************************/ BOOL hydChamberWaterInletControl( void ) { // Read floater switch BOOL result = FALSE; LEVEL_STATE_T floaterLevel = getLevelStatus( D6_LEVL ); //Make sure Water Inlet Valve is open setValveState( M4_VALV, VALVE_STATE_OPEN ); // High level is met if ( LEVEL_STATE_HIGH == floaterLevel ) { //turn off inlet water valve setValveState( D3_VALV, VALVE_STATE_CLOSED ); // Water level reached high. result = TRUE; } else { // if level is not met,allow inlet water to hydraulics chamber setValveState( D3_VALV, VALVE_STATE_OPEN ); } return result; } /*********************************************************************//** * @brief * The handleGenDDialysateIsolatedUFState function performs the * Isolated ultrafiltration operations. * @details \b Inputs: none. * @details \b Outputs: none * @return the current state of gen dialysate mode *************************************************************************/ static DD_GEND_MODE_STATE_T handleGenDDialysateIsolatedUFState( void ) { DD_GEND_MODE_STATE_T state = DD_GEND_ISOLATED_UF_STATE; //TODO: define isoalted ultrafilteration. return state; } /*********************************************************************//** * @brief * The handleGenDDialysateBypassState function produces dialysate * by executing balancing chamber and decides to pass the dialysate * to dialyzer for treatment. * @details \b Inputs: none * @details \b Outputs: balancing chamber state. * @return the current state of gen dialysate mode *************************************************************************/ static DD_GEND_MODE_STATE_T handleGenDDialysateBypassState( void ) { DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_BYPASS_STATE; //Testing if ( TRUE == delayBypassStateFlag ) { if ( TRUE == didTimeout( bypassStateDelayStartTimeMS, DELAY_BC_SWITCHING_AT_START_UP ) ) { delayBypassStateFlag = FALSE; } } else { //Execute balancing chamber execBalancingChamberControl(); } //if the produced dialysate is good and TD asks for dialysate delivery //move to next state if ( ( TRUE == getDialGoodToDeliverStatus() ) && ( FALSE == getTDDialyzerBypass() ) ) { setModeGenDStateTransition( DD_GEND_DIALYSATE_DELIVERY_STATE ); isDialDeliveryInProgress.data = TRUE; state = DD_GEND_DIALYSATE_DELIVERY_STATE; } return state; } /*********************************************************************//** * @brief * The handleGenDDialysateDeliveryState function performing dialysate * delivery by executing balancing chamber. * @details \b Inputs: none * @details \b Outputs: balancing chamber state. * @return the current state of gen dialysate mode *************************************************************************/ static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryState( void ) { DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_DELIVERY_STATE; //Execute balancing chamber execBalancingChamberControl(); // if TD asks for bypass or dialysate is not good to deliver //transition to produce dialystate state if ( ( FALSE == getDialGoodToDeliverStatus() ) || ( TRUE == getTDDialyzerBypass() ) ) { setModeGenDStateTransition( DD_GEND_DIALYSATE_BYPASS_STATE ); isDialDeliveryInProgress.data = FALSE; state = DD_GEND_DIALYSATE_BYPASS_STATE; } return state; } /*********************************************************************//** * @brief * The requestDDGenDialyasteStop function handles an TD request to stop * generation dialysis mode. * @details \b Inputs: Generation dialysate mode / state * @details \b Outputs: mode pendingStopDDGenDialRequest * @return TRUE if request accepted, FALSE if not. *************************************************************************/ BOOL requestDDGenDialyasteStop( void ) { BOOL status = FALSE; if ( DD_MODE_GEND == getCurrentOperationMode() ) { pendingStopDDGenDialRequest = TRUE; status = TRUE; } return status; } /*********************************************************************//** * @brief * The handleGenDDialysateDeliveryPauseState function pause the dialysate * delivery due to alarms conditions or some control asked to be in * paused state. * @details \b Inputs: none * @details \b Outputs: none * @return the current state of gen dialysate mode *************************************************************************/ static DD_GEND_MODE_STATE_T handleGenDDialysateDeliveryPauseState( void ) { DD_GEND_MODE_STATE_T state = DD_GEND_DIALYSATE_DELIVERY_PAUSE; //TODO : Handle pause state. return state; } /*********************************************************************//** * @brief * The getCurrentGenDialysateState function returns the current state of the * gen dialysate mode. * @details \b Inputs: genDialysateState * @details \b Outputs: none * @return the current state of gen dialysate mode *************************************************************************/ DD_GEND_MODE_STATE_T getCurrentGenDialysateState( void ) { return genDialysateState; } /*********************************************************************//** * @brief * The setTreatmentParamUpdate function sets the flag to indicate one or more * treatement parameters updated. * gen dialysate mode. * @details \b Inputs: none * @details \b Outputs: isTreatmentParamUpdated * @return none *************************************************************************/ void setTreatmentParamUpdate( void ) { isTreatmentParamUpdated = TRUE; } /*********************************************************************//** * @brief * The updateTreatmentSettings function updates the switching rate post the * treatement parameters updated during treatement. * @details \b Inputs: isTreatmentParamUpdated * @details \b Outputs: balChamberSwitchingPeriod,isTreatmentParamUpdated. * @return none *************************************************************************/ void updateTreatmentSettings( void ) { // Update any dynamic treatment parameter changes if ( TRUE == isTreatmentParamUpdated ) { // Update the balancing chamber switching rate based on dialysis rate updateBalChamberSwitchingPeriod(); // Get the target temperature from TD targetHydChamberFluidTemp.data = getTDTargetDialysateTemperature(); // Update the target temperature for heater control setHeaterTargetTemperature( D5_HEAT, getGenDialysateTargetTemperature() ); //TODO: update others parameters setting as needed. //reset the flag isTreatmentParamUpdated = FALSE; } } /*********************************************************************//** * @brief * The getDialGoodToDeliverStatus function gets the dialysate good to deliver * status. * @details \b Inputs: isDialysateGoodtoDeliver * @details \b Outputs: none * @return the current status of dialysate delivery *************************************************************************/ U32 getDialGoodToDeliverStatus( void ) { U32 result = getU32OverrideValue( &isDialysateGoodtoDeliver ); return result; } /*********************************************************************//** * @brief * The getDialDeliveryProgressStatus function gets the dialysate delivery * progress status. * @details \b Inputs: isDialDeliveryInProgress * @details \b Outputs: none * @return the current status of dialysate delivery *************************************************************************/ U32 getDialDeliveryProgressStatus( void ) { U32 result = getU32OverrideValue( &isDialDeliveryInProgress ); return result; } /*********************************************************************//** * @brief * The getGenDilaysateDataPublishInterval function gets the generate dialysate * mode data publish interval. * @details \b Inputs: genDialysateDataPublishInterval * @details \b Outputs: none * @return the interval at generate dialysate mode data being published. *************************************************************************/ static U32 getGenDilaysateDataPublishInterval( void ) { U32 result = getU32OverrideValue( &genDialysateDataPublishInterval ); return result; } /*********************************************************************//** * @brief * The getGenDialysateTargetTemperature function gets the target dialysate * temperature. * @details \b Inputs: getGenDialysateTargetTemperature * @details \b Outputs: none * @return the target dialysate temperature for the treatment. *************************************************************************/ static F32 getGenDialysateTargetTemperature( void ) { F32 temp = getF32OverrideValue( &targetHydChamberFluidTemp ); return temp; } /*********************************************************************//** * @brief * The checkDialysateTemperature function checks the dialysate temperature * against the target temperature and alarm if temperature is out of range. * @details \b Inputs: targetTemp, dialysateTemp * @details \b Outputs: none * @details \b Alarms: ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP when * dialysate temp goes beyound high safety temperature limit * @details \b Alarms: ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP when * dialysate temp goes beyound high temperature limit * @details \b Alarms: ALARM_ID_DD_DIALYSATE_TEMP_BELOW_TARGET_TEMP when * dialysate temp goes beyound low temperature limit * @return none *************************************************************************/ static void checkDialysateTemperature( void ) { F32 dialysateTemp = getConductivityTemperatureValue( D29_COND ); // Assuming the closest temp sensor to dialyzer F32 targetTemp = getTDTargetDialysateTemperature(); BOOL isDialTempAboveHighSafety = ( dialysateTemp >= DIALYSATE_TEMP_UPPER_MAX_SAFETY_LIMIT_C ? TRUE : FALSE ); BOOL isDialTempAboveLowSafety = ( dialysateTemp > DIALYSATE_TEMP_UPPER_SAFETY_LIMIT_C ? TRUE : FALSE ); BOOL isDialTempBelowLowSafety = ( dialysateTemp < DIALYSATE_TEMP_LOWER_SAFETY_LIMIT_C ? TRUE : FALSE ); F32 dialHigh = targetTemp + DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; BOOL isDialTempAboveDialysateTarget = ( dialysateTemp > dialHigh ? TRUE : FALSE ); F32 dialLow = targetTemp - DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; BOOL isDialTempBelowDialysateTarget = ( dialysateTemp < dialLow ? TRUE : FALSE ); BOOL isTempBelowTrigger = (BOOL)( isDialTempBelowLowSafety || isDialTempBelowDialysateTarget ); BOOL isTempAboveTrigger = (BOOL)( isDialTempAboveLowSafety || isDialTempAboveDialysateTarget ); if ( DD_GEND_DIALYSATE_DELIVERY_STATE == genDialysateState ) { // check clear condition first if ( TRUE == isAlarmActive( ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP ) ) { isDialTempAboveHighSafety = ( dialysateTemp <= ( targetTemp + DIALYSATE_TEMP_OUT_OF_TARGET_CLEAR_TOL_C ) ? FALSE : TRUE ); } checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP, isDialTempAboveHighSafety, dialysateTemp, targetTemp ); if ( TRUE == isAlarmActive( ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP ) ) { isTempAboveTrigger = ( dialysateTemp <= ( targetTemp + DIALYSATE_TEMP_OUT_OF_TARGET_CLEAR_TOL_C ) ? FALSE : TRUE ); } checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, isTempAboveTrigger, dialysateTemp, targetTemp ); if ( TRUE == isAlarmActive( ALARM_ID_DD_DIALYSATE_TEMP_BELOW_TARGET_TEMP ) ) { isTempBelowTrigger = ( dialysateTemp >= ( targetTemp - DIALYSATE_TEMP_OUT_OF_TARGET_CLEAR_TOL_C ) ? FALSE : TRUE ); } checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, isTempBelowTrigger, dialysateTemp, targetTemp ); } else { checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP, FALSE, dialysateTemp, targetTemp ); checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, FALSE, dialysateTemp, targetTemp ); checkPersistentAlarm(ALARM_ID_DD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, FALSE, dialysateTemp, targetTemp ); } } /*********************************************************************//** * @brief * The publishGenDialysateModeData function broadcasts the generate dialysate * mode data at defined interval. * @details \b Inputs: genDialysateDataPublicationTimerCounter * @details \b Outputs: DD generate dialysate data broadcast message sent * @details \b Message \Sent: MSG_ID_DD_GEN_DIALYSATE_MODE_DATA to publish the * generate dialysate mode data. * @return none *************************************************************************/ static void publishGenDialysateModeData( void ) { if ( ++genDialysateDataPublicationTimerCounter >= getGenDilaysateDataPublishInterval() ) { GEN_DIALYSATE_MODE_DATA_T data; data.genDialysateExecState = (U32)getCurrentGenDialysateState(); data.isDialDelInProgress = (BOOL)getDialDeliveryProgressStatus(); data.d6Level = (U32)getLevelStatus( D6_LEVL ); data.d63Level = (U32)getLevelStatus( D63_LEVL ); data.d46Level = (U32)getLevelStatus( D46_LEVL ); data.d9Pressure = getFilteredPressure( D9_PRES ); data.d18Pressure = getFilteredPressure( D18_PRES ); data.d51Pressure = getFilteredPressure( D51_PRES ); data.isDialysateGoodtoDeliver = (BOOL)getDialGoodToDeliverStatus(); broadcastData( MSG_ID_DD_GEN_DIALYSATE_MODE_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( GEN_DIALYSATE_MODE_DATA_T ) ); genDialysateDataPublicationTimerCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testDDGenDialysateDataPublishIntervalOverride function overrides the * DD generate dialysate mode data publish interval. * @details \b Inputs: genDialysateDataPublishInterval * @details \b Outputs: genDialysateDataPublishInterval * @param Override message from Dialin which includes the interval * (in ms) to override the DD generate dialysate data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDDGenDialysateDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &genDialysateDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testDialDeliveryInProgressOverride function sets the override value * of the dialysate delivery In progress flag. * @details Inputs: isDialDeliveryInProgress * @details Outputs: isDialDeliveryInProgress * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDialDeliveryInProgressOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &isDialDeliveryInProgress, 0, TRUE ); return result; } /*********************************************************************//** * @brief * The testDialGoodToDeliverStatusOverride function sets the override value * of the dialysate good to deliver status flag. * @details Inputs: isDialysateGoodtoDeliver * @details Outputs: isDialysateGoodtoDeliver * @param message Override message from Dialin which includes the override * value to override the dialysate delivery in progress flag. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testDialGoodToDeliverStatusOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &isDialysateGoodtoDeliver, 0, TRUE ); return result; } /*********************************************************************//** * @brief * The testGenDHydChamberFluidTempOverride function sets the override value * of the hydraulics chamber fluid temperature. * @details Inputs: targetHydChamberFluidTemp * @details Outputs: targetHydChamberFluidTemp * @param message Override message from Dialin which includes the override * value of the hydraulics chamber fluid temperature. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testGenDHydChamberFluidTempOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &targetHydChamberFluidTemp ); return result; } /*********************************************************************//** * @brief * The testGenDExecStateOverride function sets the Gen dialysate execution state * machine to given state. * @details \b Inputs: tester logged in, execStateSet * @details \b Outputs: genDialysateState * @param message set message from Dialin which includes the generate dialysate * execution state to be set. * @return TRUE if set request is successful, FALSE if not *************************************************************************/ BOOL testGenDExecStateOverride( MESSAGE_T *message ) { BOOL result = FALSE; // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid if ( sizeof( GEND_EXEC_STATE_SET_CMD_PAYLOAD_T ) == message->hdr.payloadLen ) { GEND_EXEC_STATE_SET_CMD_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(GEND_EXEC_STATE_SET_CMD_PAYLOAD_T) ); // Validate the state to be set if ( payload.execStateSet < NUM_OF_DD_GEND_MODE_STATES ) { //set the GenD exec state machine DD_GEND_MODE_STATE_T state = (DD_GEND_MODE_STATE_T)payload.execStateSet; setModeGenDStateTransition( state ); genDialysateState = state; result = TRUE; } } } return result; } /**@}*/