Index: firmware/App/Controllers/Valves.h =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Controllers/Valves.h (.../Valves.h) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Controllers/Valves.h (.../Valves.h) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -33,6 +33,9 @@ // ********** public definitions ********** +#define VALVE_NO_FORCE_HOME FALSE ///< Do not re-home valve if already homed - just go to position A instead +#define VALVE_CARTRIDGE_MAY_BE_PRESENT TRUE ///< A cartridge may be present, so allow for homed positions to be further away from where expected + /// Valves positions typedef enum valveStatesNames { Index: firmware/App/Drivers/RotaryValve.h =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Drivers/RotaryValve.h (.../RotaryValve.h) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Drivers/RotaryValve.h (.../RotaryValve.h) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -44,6 +44,8 @@ H1_VALV = 0, ///< Arterial rotary pinch valve FIRST_VALVE = H1_VALV, ///< First valve H19_VALV, ///< Venous rotary pinch valve +// H13_VALV, ///< Air trap valueIN +// H20_VALV, ///< Air trap valueOUT NUM_OF_VALVES ///< Number of valves } VALVE_T; Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r9cc543b1c2508280767573e20eddd94e68be1fb5 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 9cc543b1c2508280767573e20eddd94e68be1fb5) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -69,7 +69,7 @@ static U32 postCompleteDelayTimerCtr; ///< Timer counter for 2 second delay after POST completes and before transitioning to Standbymode. static UI_VERSIONS_T uiVersion = { 0, 0, 0, 0, 0 }; ///< Version and compatibility information reported by UI. -static DD_VERSIONS_T dgVersion = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ///< Version and compatibility information reported by DG. +static DD_VERSIONS_T ddVersion = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ///< Version and compatibility information reported by DG. static U32 startPOSTDelayCounter = 0; ///< Start POST delay counter. extern U32 savedResetReasonCode; ///< Saved reset reason code from sys_startup.c. @@ -379,7 +379,7 @@ *************************************************************************/ void signalDDVersion( DD_VERSIONS_T version ) { - dgVersion = version; + ddVersion = version; } /*********************************************************************//** @@ -391,11 +391,24 @@ *************************************************************************/ DD_VERSIONS_T getDDVersion( void ) { - return dgVersion; + return ddVersion; } /*********************************************************************//** * @brief + * The getDDComppatabilitys function returns the DD version information. + * @details \b Inputs: dgVersion + * @details \b Outputs: none + * @return dgVersion + *************************************************************************/ +U32 getDDCompatibility( void ) +{ + ddVersion = getDDVersion(); + return ddVersion.compatibilityRev; +} + +/*********************************************************************//** + * @brief * The isPOSTCompleted function determines whether all HD POST have * been run and completed. If true, call the isPOSTPassed() to see final * result (pass/fail). Index: firmware/App/Modes/ModeInitPOST.h =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Modes/ModeInitPOST.h (.../ModeInitPOST.h) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Modes/ModeInitPOST.h (.../ModeInitPOST.h) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -47,6 +47,7 @@ void signalDDVersion( DD_VERSIONS_T version ); // Record DD version info DD_VERSIONS_T getDDVersion( void ); // Get DD version info +U32 getDDCompatibility( void ); // Get DD compatability BOOL getDDPOSTPassed( void ); // Get DD POST pass/fail status /**@}*/ Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r120487ddf3e3d69d1de5094d5252c037588e2ed8 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 120487ddf3e3d69d1de5094d5252c037588e2ed8) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -18,15 +18,20 @@ #include "AirTrap.h" #include "BloodFlow.h" #include "Buttons.h" +#include "Bubbles.h" #include "DDInterface.h" #include "Messaging.h" +#include "ModeInitPOST.h" #include "ModePreTreat.h" #include "ModeTreatment.h" #include "ModeStandby.h" #include "OperationModes.h" #include "Switches.h" #include "SystemCommTD.h" +#include "SyringePump.h" #include "TxParams.h" +#include "Valves.h" +#include "Valve3Way.h" /** * @addtogroup TDStandbyMode @@ -38,15 +43,38 @@ #define USER_COMMAND_CANCEL 0 ///< Cancel treatment workflow command code. #define USER_COMMAND_INITIATE 1 ///< Initiate treatment workflow command code. +/// DG cleaning mode status data structure +typedef struct +{ + BOOL startCleaningMode; ///< Flag to indicate to start cleaning mode. + DD_COMMAND_T startRequestCmdID; ///< DG cleaning mode start request command ID. + ALARM_ID_T alarmID; ///< The informative alarm to trigger for each cleaning mode. + DD_OP_MODE_T ddOpMode; ///< DG operation mode. + BOOL sampleRqstTrgrd; ///< Flag to indicate the sample alarm has been triggered (for RO perm and chem flush). + GENERIC_CONFIRM_ID_T sampleRequestID; ///< Sample request pass/fail message status. + GENERIC_CONFIRM_ID_T stopRequestCmdID; ///< Stop DG cleaning request command ID +} DD_CLEANING_MODE_STATUS_T; + // ********** private data ********** static TD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. static BOOL treatStartReqReceived; ///< Flag indicates user has requested initiation of a treatment. +static GENERIC_CONFIRM_ID_T disinfectCancelReqID; ///< ID of requested cancel disinfect mode. +static BOOL homingInitiated; ///< Boolean flag to indicate homing is initiated. +static DD_CLEANING_MODE_STATUS_T currentDDCleaningMode; ///< Current DG cleaning mode status. +static BOOL flagNoDisinfectRequired = FALSE; ///< Flag indicates disinfect not required on next mode entry. // ********** private function prototypes ********** static TD_STANDBY_STATE_T handleStandbyModeStartState( void ); static TD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ); +static void clearCurrentCleaningModeStatus( void ); +static void setStandbyWaitForTreatmentActuators( void ); +static TD_STANDBY_STATE_T handleStandbyModeWaitForDDCleaningModeStartState( void ); +static TD_STANDBY_STATE_T handleStandbyModeDDCleaningModeInProgressState( void ); +static void handleChemFlushSampleCollection( void ); +static void handleROPermeateSampleCollection( void ); +static TD_STANDBY_STATE_T handleStandbyModeWaitForDDCleaningModeCmdResponseState( void ); /*********************************************************************//** * @brief @@ -59,6 +87,8 @@ { currentStandbyState = STANDBY_START_STATE; treatStartReqReceived = FALSE; + disinfectCancelReqID = GENERIC_CONFIRM_ID_NONE; + homingInitiated = FALSE; } /*********************************************************************//** @@ -71,32 +101,52 @@ *************************************************************************/ U32 transitionToStandbyMode( void ) { - TD_OP_MODE_T previousOpMode = getPreviousOperationMode(); +// TD_OP_MODE_T previousOpMode = getPreviousOperationMode(); //ToDo + U08 requestPayload[3] = { 0U, 0U, 0U }; // Re-initialize when transitioning to standby mode initStandbyMode(); resetDDInterface(); + resetAirTrap(); + resetBloodPumpRotorCount(); + resetPreLoadStatus(); + setVenousBubbleDetectionEnabled( H18_BBLD, FALSE ); setCurrentSubState( NO_SUB_STATE ); +// clearNoRetriggerFlag(); // Alarm flag + clearCurrentCleaningModeStatus(); // Set user alarm recovery actions allowed in this mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); - // Pumps should be off -// signalBloodPumpHardStop(); -// stopSyringePump(); + setStandbyWaitForTreatmentActuators(); - // Set valves to default positions -// setValveAirTrap( VALVE_3WAY_COMMON_TO_CLOSED_STATE ); -// setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); -// setValvePosition( H19, VALVE_POSITION_A_INSERT_EJECT ); + // If we just exited Post Treatment Mode, goto disinfect sub state. + //ToDo +// if ( ( MODE_POST == previousOpMode ) && ( flagNoDisinfectRequired != TRUE ) ) +// { +// doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode +// currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; //ToDo +// } +// else +// { +// flagNoDisinfectRequired = FALSE; +// doorClosedRequired( TRUE ); +// currentStandbyState = STANDBY_START_STATE; //ToDo +// } + // Standby currently supports Start and Wait For Treatment states. + // Disinfect/cleaning states are not enabled until the handlers are implemented. + flagNoDisinfectRequired = FALSE; + doorClosedRequired( TRUE ); + currentStandbyState = STANDBY_START_STATE; +// syringeDetectionRequired( FALSE ); //Todo -// doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode - // Request DD service record and usage information from DD -// sendDGServiceRequestToDG(); -// sendDGUsageInfoRequestToDG(); +// sendDDServiceRequestToDD(); + broadcastData( MSG_ID_TD_DD_REQUEST_SERVICE_RECORD_FROM_TD, COMM_BUFFER_OUT_CAN_TD_2_DD, requestPayload, sizeof( requestPayload ) ); + broadcastData( MSG_ID_TD_DD_USAGE_INFO_REQUEST, COMM_BUFFER_OUT_CAN_TD_2_DD, requestPayload, sizeof( requestPayload ) ); +// sendDDUsageInfoRequestToDD(); //TODO need to enable return currentStandbyState; } @@ -128,6 +178,22 @@ currentStandbyState = handleStandbyModeWaitForTreatmentState(); break; + case STANDBY_WAIT_FOR_DISINFECT_STATE: +// currentStandbyState = handleStandbyModeWaitForDisinfectState(); + break; + + case STANDBY_WAIT_FOR_DD_CLEANING_MODE_CMD_RESPONSE_STATE: + currentStandbyState = handleStandbyModeWaitForDDCleaningModeCmdResponseState(); + break; + + case STANDBY_WAIT_FOR_DD_CLEANING_MODE_TO_START_STATE: + currentStandbyState = handleStandbyModeWaitForDDCleaningModeStartState(); + break; + + case STANDBY_CLEANING_MODE_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDDCleaningModeInProgressState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); currentStandbyState = STANDBY_START_STATE; @@ -148,50 +214,37 @@ *************************************************************************/ static TD_STANDBY_STATE_T handleStandbyModeStartState( void ) { - TD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; + TD_STANDBY_STATE_T state = STANDBY_START_STATE; - // Wait for door to be closed so we can home actuators -// if ( STATE_CLOSED == getSwitchState( H9_SWCH ) ) -// { -// // If we haven't already initiated homing of actuators, initiate now -// if ( homingInitiated != TRUE ) -// { -// VALVE_T valve; -// -// // Home pumps and valves -// for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) -// { -// homeValve( valve, VALVE_NO_FORCE_HOME, VALVE_CARTRIDGE_MAY_BE_PRESENT ); -// } -// homeBloodPump(); -// homeDialInPump(); -// homeDialOutPump(); -// retractSyringePump(); -// -// homingInitiated = TRUE; -// } -// else -// { -// // If homing has been initiated, wait for syringe pump to home and the verify force sensor calibration -//#ifndef _RELEASE_ -// if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) ) -// { -// state = STANDBY_WAIT_FOR_TREATMENT_STATE; // Go to wait for treatment state after above check -// } -// else -//#endif -// { -// if ( ( TRUE == isSyringePumpHome() ) && ( TRUE == isSyringePumpStopped() ) ) -// { -// syringePumpVerifyForceSensorDACCalibration(); -// homingInitiated = FALSE; // reset for next time -// doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode -// state = STANDBY_WAIT_FOR_TREATMENT_STATE; // Go to wait for treatment state after above check -// } -// } -// } -// } + // If we haven't already initiated homing of actuators, initiate now + if ( homingInitiated != TRUE ) + { + VALVE_T valve; + // Home pumps and valves + for ( valve = H1_VALV; valve < NUM_OF_VALVES; ++valve ) + { + homeValve( valve, VALVE_NO_FORCE_HOME, VALVE_CARTRIDGE_MAY_BE_PRESENT ); + } + if ( FALSE == isSyringePumpHome() ) + { + retractSyringePump(); + } + homingInitiated = TRUE; + } + else + { + // If homing has been initiated, wait for syringe pump to home and the verify force sensor calibration + if ( ( TRUE == isSyringePumpHome() ) && ( TRUE == isSyringePumpStopped() ) && ( VALVE_POSITION_A_INSERT_EJECT == getValvePosition( H1_VALV ) ) && ( VALVE_POSITION_A_INSERT_EJECT == getValvePosition( H19_VALV ) ) ) + { + syringePumpVerifyForceSensorDACCalibration(); + homingInitiated = FALSE; // reset for next time + doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode + setStandbyWaitForTreatmentActuators(); + state = STANDBY_WAIT_FOR_TREATMENT_STATE; // Go to wait for treatment state after above check + } + } + return state; } @@ -209,46 +262,45 @@ DD_OP_MODE_T ddOperationMode = getDDOpMode(); F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; -// switch ( dgOperationMode ) -// { -// case DG_MODE_GENE: -// // If DG is in idle generation state while we are in standby mode, transition DG to standby too -// cmdStopDG(); -// break; -// -// // If DG is any of the cleaning modes, set the HD standby to be in the corresponding cleaning mode -// case DG_MODE_FLUS: -// case DG_MODE_HEAT: -// case DG_MODE_CHEM: -// case DG_MODE_CHFL: -// case DG_MODE_HCOL: -// case DG_MODE_ROPS: -// setRequestedCleaningMode( dgOperationMode ); -// state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_TO_START_STATE; -// break; -// -// default: -// // Do nothing. There are other DG modes that HD standby does not need to act upon them. -// break; -// } + switch ( ddOperationMode ) + { + case DD_MODE_GENE: + // If DD is in idle generation state while we are in standby mode, transition DD to standby too +// cmdStopDD(); + break; + // If DD is any of the cleaning modes, set the TD standby to be in the corresponding cleaning mode + case DD_MODE_HEAT: + case DD_MODE_HCOL: + case DD_MODE_ROPS: +// setRequestedCleaningMode( ddOperationMode ); +// state = STANDBY_WAIT_FOR_DD_CLEANING_MODE_TO_START_STATE; + // DD cleaning mode handling is not enabled yet. + // Stay in Wait For Treatment until DD returns to a supported standby state. + break; + + default: + // Do nothing. There are other DD modes that TD standby does not need to act upon them. + break; + } + // If DD is communicating and we don't yet have DD version info, request it -// if ( TRUE == isDDCommunicating() ) -// { -// DG_VERSIONS_T ddVersion = getDDVersion(); -// -// if ( 0 == dgVersion.compatibilityRev ) -// { -// sendFWVersionRequest(); -// } -// } + if ( TRUE == isDDCommunicating() ) + { + if ( FALSE == getDDCompatibility()) + { + U08*fwbuf = NULL; + sendMessage( MSG_ID_FW_VERSIONS_REQUEST, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08*)(&fwbuf), 3 ); + } + } // If treatment start is requested by user, initiate treatment workflow (transition to treatment params mode). if ( TRUE == treatStartReqReceived ) { PRESSURE_LIMIT_CHANGE_RESPONSE_T respRecord = { TRUE, REQUEST_REJECT_REASON_NONE, 0, 0, 0, 0 }; // Initialize treatment modes before starting a new treatment +// initTreatParamsMode(); initPreTreatmentMode(); initTreatmentMode(); // initPostTreatmentMode(); @@ -276,6 +328,38 @@ /*********************************************************************//** * @brief + * The setStandbyWaitForTreatmentActuators function sets TD actuators to + * the required Standby: Wait For Treatment state. + * @details \b Inputs: none + * @details \b Outputs: TD actuators set to standby state. + * @return none + *************************************************************************/ +static void setStandbyWaitForTreatmentActuators( void ) +{ + // Pumps should be off. + signalBloodPumpHardStop(); + stopSyringePump(); + + // Set air trap valves to closed position. + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + + // Set pinch valves to load / insert-eject position. + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + +// TODO: Add remaining Standby actuator settings when existing control +// functions are confirmed: +// H12 Air Pump Off +// H5 Ejector Off +// Dialyzer Bypassed +// Qd 0 +// Quf 0 +// Qs 0 +} + +/*********************************************************************//** + * @brief * The signalUserInitiateTreatment function handles user initiation of a * treatment. * @details \b Inputs: none @@ -286,61 +370,106 @@ *************************************************************************/ BOOL signalUserInitiateTreatment( MESSAGE_T *message ) { - BOOL result = FALSE; - U32 cmd = 0; - TD_OP_MODE_T mode = getCurrentOperationMode(); - REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + BOOL result = FALSE; + U32 cmd = 0; + TD_OP_MODE_T mode = getCurrentOperationMode(); + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; UI_RESPONSE_PAYLOAD_T response; - // Verify message payload length is valid + memset( &response, 0, sizeof( UI_RESPONSE_PAYLOAD_T ) ); + + // Verify message payload length is valid. if ( sizeof( U32 ) == message->hdr.payloadLen ) { memcpy( &cmd, message->payload, sizeof( U32 ) ); if ( USER_COMMAND_INITIATE == cmd ) { - // Verify TD is in standby mode waiting for treatment start request - if ( ( mode != MODE_STAN ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE != currentStandbyState ) ) + // Verify TD is in Standby mode and waiting for treatment start request. + if ( ( MODE_STAN != mode ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE != currentStandbyState ) ) { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } + #ifndef TEST_UI_ONLY - // Verify DD is communicating with HD - else if ( isDDCommunicating() != TRUE ) + // Verify DD is communicating. + else if ( TRUE != isDDCommunicating() ) { rejReason = REQUEST_REJECT_REASON_DD_COMM_LOST; } - // Verify DD is not busy - else if ( ( DD_MODE_STAN != getDDOpMode() ) || ( DD_STANDBY_MODE_STATE_IDLE != getDDSubMode() ) ) // || ( isDDPOSTPassed() != TRUE ) ) + // Verify DD is ready and not busy with flush/disinfect/cleaning/generation. + else if ( ( DD_MODE_STAN != getDDOpMode() ) || ( DD_STANDBY_MODE_STATE_IDLE != getDDSubMode() ) ) { rejReason = REQUEST_REJECT_REASON_DD_NOT_IN_STANDBY_IDLE_STATE; } + else if ( FALSE == getDDCompatibility() ) + { + rejReason = REQUEST_REJECT_REASON_DD_INCOMPATIBLE; + } +// else if ( TRUE == isDDDisinfectionOverdue() ) +// { +// rejReason = REQUEST_REJECT_REASON_DISINFECT_HAS_BEEN_EXPIRED; +// } +// else if ( TRUE == isDDFlushOverdue() ) +// { +// rejReason = REQUEST_REJECT_REASON_FILTER_FLUSH_HAS_BEEN_EXPIRED; +// } +// else if ( TRUE == isDDTemperatureTooHigh() ) +// { +// rejReason = REQUEST_REJECT_REASON_RO_FILTER_TEMPERATURE_OUT_OF_RANGE; +// } +// else if ( TRUE == isDDServiceOverdue() ) +// { +// rejReason = REQUEST_REJECT_REASON_DD_SERVICE_IS_DUE; +// } +// else if ( TRUE == isTDServiceOverdue() ) +// { +// rejReason = REQUEST_REJECT_REASON_TD_SERVICE_IS_DUE; +// } +// else if ( FALSE == isFPStandbymode() ) +// { +// rejReason = REQUEST_REJECT_REASON_TD_SERVICE_IS_DUE; +// } +// else if ( TRUE == isfpServiceOverdue() ) +// { +// rejReason = REQUEST_REJECT_REASON_TD_SERVICE_IS_DUE; +// } + #endif else { - // If request to start treatment not rejected, set flag to initiate treatment workflow +// Low battery is a warning only, not a rejection. + //ToDo +// if ( TRUE == isBatteryRemainingCapacityLessThan60Wh() ) +// { +// SET_ALARM( ALARM_ID_TD_LOW_BATTERY_CHARGE ); +// } + + // If request to start treatment not rejected, set flag to initiate treatment workflow. result = TRUE; treatStartReqReceived = TRUE; } } else if ( USER_COMMAND_CANCEL == cmd ) { - //result = signalUserCancelTreatment(); - if ( result != TRUE ) - { - rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; - } + //Cancel is not currently supported here. + //Keep rejected unless signalUserCancelTreatment() is implemented/enabled. + rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } else { rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; } } + else + { + rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; + } - // Respond to request to start treatment - response.accepted = result; + // Respond to request to start treatment. + response.accepted = result; response.rejectionReason = rejReason; - sendMessage( MSG_ID_TD_RESP_INITIATE_TREATMENT_WORKFLOW, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&response), sizeof( UI_RESPONSE_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_RESP_INITIATE_TREATMENT_WORKFLOW, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*) &response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } @@ -359,22 +488,23 @@ switch ( action ) { case ALARM_ACTION_STOP: -// if ( isAlarmActive( ALARM_ID_HD_VENOUS_BUBBLE_DETECTED ) != TRUE ) -// { -// // no stop action in standby mode -// } -// // if Dialin enabled bubble detection, stop on venous bubble detection alarm -// else -// { -// // Pumps should be off -// signalBloodPumpHardStop(); -// stopSyringePump(); -// -// // Set valves to safe positions -// setValveAirTrap( STATE_CLOSED ); -// setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); -// setValvePosition( H19, VALVE_POSITION_C_CLOSE ); -// } + if ( isAlarmActive( ALARM_ID_TD_VENOUS_BUBBLE_DETECTED ) != TRUE ) + { + // no stop action in standby mode + } + // if Dialin enabled bubble detection, stop on venous bubble detection alarm + else + { + // Pumps should be off + signalBloodPumpHardStop(); + stopSyringePump(); + + // Set valves to safe positions + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + } break; default: @@ -383,7 +513,271 @@ } } +/*********************************************************************//** + * @brief + * The clearCurrentCleaningModeStatus function clears the DG cleaning mode + * variables. + * @details \b Inputs: none + * @details \b Outputs: currentDGCleaningMode + * @return none + *************************************************************************/ +static void clearCurrentCleaningModeStatus( void ) +{ + currentDDCleaningMode.startCleaningMode = FALSE; + currentDDCleaningMode.alarmID = ALARM_ID_NO_ALARM; + currentDDCleaningMode.startRequestCmdID = DD_CMD_NONE; + currentDDCleaningMode.ddOpMode = DD_MODE_FAUL; + currentDDCleaningMode.sampleRqstTrgrd = FALSE; + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; + currentDDCleaningMode.stopRequestCmdID = GENERIC_CONFIRM_ID_NONE; +} +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForDDCleaningModeStartState function handles + * the standby mode wait for DD cleaning mode start state. + * @details Inputs: currentDDCleaningMode + * @details Outputs: none + * @return next state of the standby mode state machine + *************************************************************************/ +static TD_STANDBY_STATE_T handleStandbyModeWaitForDDCleaningModeStartState( void ) +{ + TD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DD_CLEANING_MODE_TO_START_STATE; + + if ( currentDDCleaningMode.ddOpMode == getDDOpMode() ) + { + state = STANDBY_CLEANING_MODE_IN_PROGRESS_STATE; + activateAlarmNoData( currentDDCleaningMode.alarmID ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDDCleaningModeInProgressState function handles + * the standby mode DD cleaning mode in progress state. + * @details \b Inputs: currentDDCleaningMode + * @details \b Outputs: none + * @return next state of the standby mode state machine + *************************************************************************/ +static TD_STANDBY_STATE_T handleStandbyModeDDCleaningModeInProgressState( void ) +{ + TD_STANDBY_STATE_T state = STANDBY_CLEANING_MODE_IN_PROGRESS_STATE; + + if ( DD_MODE_CHFL == currentDDCleaningMode.ddOpMode ) + { + handleChemFlushSampleCollection(); + } + else if ( DD_MODE_ROPS == currentDDCleaningMode.ddOpMode ) + { + handleROPermeateSampleCollection(); + } + + if ( getDDOpMode() != currentDDCleaningMode.ddOpMode ) + { + state = STANDBY_WAIT_FOR_TREATMENT_STATE; + clearAlarm( currentDDCleaningMode.alarmID ); + // In case alarm 306 has been triggered, and it was not cleared, clear it upon exiting the disinfection mode. + clearAlarm( ALARM_ID_DD_TURN_OFF_INLET_WATER_VALVES ); + clearCurrentCleaningModeStatus(); + } + else + { + // If we are in the cleaning modes and the corresponding placeholder alarm is not active, reactivate it. + if ( FALSE == isAlarmActive( currentDDCleaningMode.alarmID ) ) + { + activateAlarmNoData( currentDDCleaningMode.alarmID ); + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleChemFlushSampleCollection function handles the chemical disinfect + * flush mode's sample collection. In this state of the chemical disinfect + * flush mode, user interaction is needed. + * @details \b Inputs: currentDDCleaningMode + * @details \b Outputs: currentDDCleaningMode + * @return none + *************************************************************************/ +static void handleChemFlushSampleCollection( void ) +{ + U08 *payloadPtr = NULL; + if ( ( FALSE == currentDDCleaningMode.sampleRqstTrgrd ) && ( TRUE == isAlarmActive( ALARM_ID_DD_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ) ) ) + { + // Check if the flush sample alarm has been raised for the first time in the sample flush state + currentDDCleaningMode.sampleRqstTrgrd = TRUE; + } + else if ( ( TRUE == currentDDCleaningMode.sampleRqstTrgrd ) && ( FALSE == isAlarmActive( ALARM_ID_DD_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ) ) ) + { + GENERIC_CONFIRMATION_REQUEST_T genericConfRequest; + + // Sample flush alarm has been triggered and the user has cleared the alarm by pressing Ok. The user is collecting sample. + // Send the notification to the UI to prompt the pass/fail screen so the user can choose whether the sampling after flush passed or failed + currentDDCleaningMode.sampleRqstTrgrd = FALSE; + + genericConfRequest.requestID = (U32)GENERIC_CONFIRM_ID_DISINFECT_CHEM_FLUSH_SAMPLE_PASS_FAIL; + genericConfRequest.requestType = (U32)GENERIC_CONFIRM_CMD_REQUEST_OPEN; + genericConfRequest.rejectReason = 0; + genericConfRequest.genericPayload1 = 0.0F; + genericConfRequest.genericPayload2 = 0.0F; + genericConfRequest.genericPayload3 = 0.0F; + genericConfRequest.genericPayload4 = 0.0F; + +// currentDDCleaningMode.sampleRequestID = addConfirmationRequest( &genericConfRequest ); //ToDo + } + + if ( currentDDCleaningMode.sampleRequestID != GENERIC_CONFIRM_ID_NONE ) + { + // There is a user confirm + CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_ACCEPTED; //getConfirmationRequestStatus( currentDDCleaningMode.sampleRequestID, 0.0F, 0.0F, 0.0F, 0.0F ); //Todo + U32 sampleStatus = 0; + + switch( status ) + { + // If the request status is accepted send a 1 to DG + case CONFIRMATION_REQUEST_STATUS_ACCEPTED: + sampleStatus = (U32)CONFIRMATION_REQUEST_STATUS_ACCEPTED; + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; + memcpy( payloadPtr, &sampleStatus, sizeof( U32 ) ); + broadcastData( MSG_ID_TD_SEND_CHEM_FLUSH_SAMPLE_PASS_FAIL_TO_DD, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08*) &payloadPtr, 3 ); +// handleSendChemFlushPassFailToDD( sampleStatus ); + break; + + // If the request timed out or rejected, it is 0 or failure to DG + case CONFIRMATION_REQUEST_STATUS_TIMEOUT: + case CONFIRMATION_REQUEST_STATUS_REJECTED: + memcpy( payloadPtr, &sampleStatus, sizeof( U32 ) ); + broadcastData( MSG_ID_TD_SEND_CHEM_FLUSH_SAMPLE_PASS_FAIL_TO_DD, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08*) &payloadPtr, 3 ); + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; +// handleSendChemFlushPassFailToDD( sampleStatus ); + break; + + case CONFIRMATION_REQUEST_STATUS_PENDING: + case CONFIRMATION_REQUEST_STATUS_UNUSED: + default: + // Nothing to do + break; + } + } +} + +/*********************************************************************//** + * @brief + * The handleROPermeateSampleCollection function handles the RO permeate + * sample collection with the user + * @details \b Inputs: currentDDCleaningMode + * @details \b Outputs: currentDDCleaningMode + * @return none + *************************************************************************/ +static void handleROPermeateSampleCollection( void ) +{ + UI_OFF_BUTTON_PAYLOAD_T cmd; + if ( ( FALSE == currentDDCleaningMode.sampleRqstTrgrd ) && ( TRUE == isAlarmActive( ALARM_ID_DD_RO_PERMEATE_SAMPLE_REMOVE_DIA_CAP ) ) ) + { + // Check if the flush sample alarm has been raised for the first time in the sample flush state + currentDDCleaningMode.sampleRqstTrgrd = TRUE; + } + else if ( ( TRUE == currentDDCleaningMode.sampleRqstTrgrd ) && ( FALSE == isAlarmActive( ALARM_ID_DD_RO_PERMEATE_SAMPLE_REMOVE_DIA_CAP ) ) ) + { + GENERIC_CONFIRMATION_REQUEST_T genericConfRequest; + + // Sample flush alarm has been triggered and the user has cleared the alarm by pressing Ok. The user is collecting sample. + // Send the notification to the UI to prompt the pass/fail screen so the user can choose whether the sampling after flush passed or failed + currentDDCleaningMode.sampleRqstTrgrd = FALSE; + + genericConfRequest.requestID = (U32)GENERIC_CONFIRM_ID_RO_PERMEATE_SAMPLE_STOP_OR_DISPENSE; + genericConfRequest.requestType = (U32)GENERIC_CONFIRM_CMD_REQUEST_OPEN; + genericConfRequest.rejectReason = 0; + genericConfRequest.genericPayload1 = 0.0F; + genericConfRequest.genericPayload2 = 0.0F; + genericConfRequest.genericPayload3 = 0.0F; + genericConfRequest.genericPayload4 = 0.0F; + +// currentDDCleaningMode.sampleRequestID = addConfirmationRequest( &genericConfRequest ); + } + + if ( currentDDCleaningMode.sampleRequestID != GENERIC_CONFIRM_ID_NONE ) + { + // There is a user confirm + CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_ACCEPTED; //getConfirmationRequestStatus( currentDDCleaningMode.sampleRequestID, 0.0F, 0.0F, 0.0F, 0.0F ); + cmd.id = GENERIC_CONFIRM_ID_DISINFECT_STOP_RO_PERMEATE_SAMPLE; + + switch( status ) + { + // If the request status is accepted send a 1 to DG + case CONFIRMATION_REQUEST_STATUS_ACCEPTED: + cmd.command = GENERIC_CONFIRM_CMD_ACCEPT_CLOSE; + cmd.reason = REQUEST_REJECT_REASON_NONE; + sendMessage( MSG_ID_TD_SEND_RO_PERMEATE_SAMPLE_DISPENSE_REQUEST_TO_DD, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08 *)&cmd, sizeof( UI_OFF_BUTTON_PAYLOAD_T ) ); + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; + break; + + // If the request timed out or rejected, it is 0 or failure to DG + case CONFIRMATION_REQUEST_STATUS_TIMEOUT: + cmd.command = GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE; + cmd.reason = REQUEST_REJECT_REASON_NONE; + sendMessage( MSG_ID_TD_SEND_RO_PERMEATE_SAMPLE_DISPENSE_REQUEST_TO_DD, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08 *)&cmd, sizeof( UI_OFF_BUTTON_PAYLOAD_T ) ); + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; + break; + + case CONFIRMATION_REQUEST_STATUS_REJECTED: + cmd.command = GENERIC_CONFIRM_CMD_REJECT; + cmd.reason = REQUEST_REJECT_REASON_NONE; + sendMessage( MSG_ID_TD_SEND_RO_PERMEATE_SAMPLE_DISPENSE_REQUEST_TO_DD, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08 *)&cmd, sizeof( UI_OFF_BUTTON_PAYLOAD_T ) ); + currentDDCleaningMode.sampleRequestID = GENERIC_CONFIRM_ID_NONE; + break; + + case CONFIRMATION_REQUEST_STATUS_PENDING: + case CONFIRMATION_REQUEST_STATUS_UNUSED: + default: + // Nothing to do + break; + } + } +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForDDCleaningModeCmdResponseState function handles + * the standby mode wait for DD cleaning mode command response state. + * @details \b Inputs: currentDDCleaningMode + * @details \b Outputs: currentDDCleaningMode + * @return next state of the standby mode state machine + *************************************************************************/ +static TD_STANDBY_STATE_T handleStandbyModeWaitForDDCleaningModeCmdResponseState( void ) +{ + DD_CMD_RESPONSE_T ddCmdResp; + TD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DD_CLEANING_MODE_CMD_RESPONSE_STATE; + UI_OFF_BUTTON_PAYLOAD_T cmd; + + if ( TRUE == getDDCommandResponse( currentDDCleaningMode.startRequestCmdID, &ddCmdResp ) ) + { + // Assume the command will be rejected and it goes back to wait for disinfect command + state = STANDBY_WAIT_FOR_DISINFECT_STATE; + currentDDCleaningMode.startCleaningMode = FALSE; + + if ( DD_CMD_REQUEST_REJECT_REASON_NONE == ddCmdResp.rejectCode ) + { + state = STANDBY_WAIT_FOR_DD_CLEANING_MODE_TO_START_STATE; + cmd.command = GENERIC_CONFIRM_CMD_ACCEPT_CLOSE; + } + else + { + cmd.command = GENERIC_CONFIRM_CMD_REJECT; + } + cmd.reason = ddCmdResp.rejectCode; + cmd.id = GENERIC_CONFIRM_ID_DISINFECT_STOP_WATERFLUSH; + sendMessage( MSG_ID_TD_DISINFECT_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&cmd, sizeof( UI_OFF_BUTTON_PAYLOAD_T ) ); + } + + return state; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/OperationModes.h =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Modes/OperationModes.h (.../OperationModes.h) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Modes/OperationModes.h (.../OperationModes.h) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -40,6 +40,18 @@ U32 subMode; ///< Current sub-mode of current operating mode } OP_MODE_PAYLOAD_T; +/// Payload structure for generic confirmation request +typedef struct +{ + U32 requestID; ///< Generic request ID. + U32 requestType; ///< Generic request type. + U32 rejectReason; ///< Reject reason. + F32 genericPayload1; ///< Generic payload 1. + F32 genericPayload2; ///< Generic payload 2. + F32 genericPayload3; ///< Generic payload 3. + F32 genericPayload4; ///< Generic payload 4. +} GENERIC_CONFIRMATION_REQUEST_T; + // ********** public function prototypes ********** void initOperationModes( void ); // Initialize this unit Index: firmware/App/Services/Messaging.h =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r7a211da92e750bc5e306e897e956487a4303a36b --- firmware/App/Services/Messaging.h (.../Messaging.h) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/Messaging.h (.../Messaging.h) (revision 7a211da92e750bc5e306e897e956487a4303a36b) @@ -51,6 +51,14 @@ } UI_OFF_BUTTON_RESPONSE_PAYLOAD_T; #pragma pack(pop) +/// Payload record structure for off button response. +typedef struct +{ + U32 id; + U32 command; + U32 reason; +} UI_OFF_BUTTON_PAYLOAD_T; + /// Payload record structure for UI response. typedef struct {