Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r9e2667ac9d2f1b2add9811f93477f0365f1b4eb7 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 9e2667ac9d2f1b2add9811f93477f0365f1b4eb7) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -53,7 +53,7 @@ #define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.12 ///< Controller will error if PWM duty cycle < 10%, so set min to 12% /// Interval (ms/task time) at which the blood pump is controlled. -#define BP_CONTROL_INTERVAL ( 10000 / TASK_GENERAL_INTERVAL ) +static const U32 BP_CONTROL_INTERVAL = ( 10000 / TASK_GENERAL_INTERVAL ); #define BP_P_COEFFICIENT 0.00035 ///< P term for blood pump control #define BP_I_COEFFICIENT 0.00035 ///< I term for blood pump control @@ -63,19 +63,24 @@ #define BP_SPEED_CALC_INTERVAL ( 40 / TASK_PRIORITY_INTERVAL ) /// Number of hall sensor counts kept in buffer to hold last 1 second of count data. #define BP_SPEED_CALC_BUFFER_LEN ( 1000 / BP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) -#define BP_HALL_EDGE_COUNTS_PER_REV 48 ///< Number of hall sensor edge counts per motor revolution. #define BP_MAX_ROTOR_SPEED_RPM 100.0 ///< Maximum rotor speed allowed for blood pump. #define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. #define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). -#define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. -#define BP_FLOW_VS_SPEED_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) for flow vs. motor speed error condition. -#define BP_OFF_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) for motor off error condition. -#define BP_MOTOR_SPEED_ERROR_PERSIST ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) motor speed error condition. -#define BP_ROTOR_SPEED_ERROR_PERSIST ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) rotor speed error condition. -#define BP_DIRECTION_ERROR_PERSIST (250 / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) pump direction error condition. -#define BP_MAX_ROTOR_SPEED_ERROR_PERSIST ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL) ///< Persist time (task intervals) blood pump rotor speed too fast error condition. +#define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. +/// Persist time (task intervals) for flow vs. motor speed error condition. +static const U32 BP_FLOW_VS_SPEED_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) for motor off error condition. +static const U32 BP_OFF_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) motor speed error condition. +static const U32 BP_MOTOR_SPEED_ERROR_PERSIST = ((5 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) rotor speed error condition. +static const U32 BP_ROTOR_SPEED_ERROR_PERSIST = ((12 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) pump direction error condition. +static const U32 BP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); +/// Persist time (task intervals) blood pump rotor speed too fast error condition. +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ((1 * MS_PER_SECOND) / TASK_PRIORITY_INTERVAL); #define BP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped #define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running @@ -382,7 +387,7 @@ *************************************************************************/ U32 getBloodPumpMotorCount( void ) { - return bloodPumpMotorEdgeCount / BP_HALL_EDGE_COUNTS_PER_REV; + return bloodPumpMotorEdgeCount; } /*********************************************************************//** @@ -931,25 +936,32 @@ if ( ++bpMotorSpeedCalcTimerCtr >= BP_SPEED_CALC_INTERVAL ) { U16 bpMotorHallSensorCount = getFPGABloodPumpHallSensorCount(); + U16 last = bpLastMotorHallSensorCounts[ bpMotorSpeedCalcIdx ]; U32 nextIdx = INC_WRAP( bpMotorSpeedCalcIdx, 0, BP_SPEED_CALC_BUFFER_LEN - 1 ); U16 incDelta = ( bpMotorHallSensorCount >= bpLastMotorHallSensorCounts[ nextIdx ] ? \ bpMotorHallSensorCount - bpLastMotorHallSensorCounts[ nextIdx ] : \ ( HEX_64_K - bpLastMotorHallSensorCounts[ nextIdx ] ) + bpMotorHallSensorCount ); U16 decDelta = HEX_64_K - incDelta; - U16 delta; - + U16 spdDelta; + U16 delta; + // Determine blood pump speed/direction from delta hall sensor count since last interval if ( incDelta < decDelta ) { - delta = incDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + spdDelta = incDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN; + // Keep a running 32-bit edge count used for safety check on volume in some functions + delta = ( bpMotorHallSensorCount >= last ? bpMotorHallSensorCount - last : ( HEX_64_K - last ) + bpMotorHallSensorCount ); + bloodPumpMotorEdgeCount += delta; } else { - delta = decDelta; - bloodPumpSpeedRPM.data = ( (F32)delta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + spdDelta = decDelta; + bloodPumpSpeedRPM.data = ( (F32)spdDelta / (F32)BP_HALL_EDGE_COUNTS_PER_REV ) * (F32)SEC_PER_MIN * -1.0; + // Keep a running 32-bit edge count used for safety check on volume in some functions + delta = ( bpMotorHallSensorCount <= last ? last - bpMotorHallSensorCount : ( HEX_64_K - bpMotorHallSensorCount ) + last ); + bloodPumpMotorEdgeCount -= (S32)delta; } - bloodPumpMotorEdgeCount += delta; // Update last count for next time bpLastMotorHallSensorCounts[ nextIdx ] = bpMotorHallSensorCount; Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r27f3db92495948d4c1192421c1b0c20338c4a034 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 27f3db92495948d4c1192421c1b0c20338c4a034) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -57,10 +57,10 @@ // DG status static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. -static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. +static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. +static BOOL dgStartCommandSent = FALSE; ///< Flag indicates command to start DG has been sent. static BOOL dgStarted = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop. static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. -static BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we have commanded the DG to sample water. // State machine states /// Current state of treatment mode reservoir management. @@ -127,7 +127,6 @@ dgStarted = FALSE; dgTrimmerHeaterOn = FALSE; - dgWaterSampled = FALSE; dgPrimaryTempSet = 0.0; dgTrimmerTempSet = 0.0; dgActiveReservoirSet = DG_RESERVOIR_2; @@ -734,7 +733,7 @@ *************************************************************************/ void cmdStartDG( void ) { - dgStarted = TRUE; + dgStartCommandSent = TRUE; sendDGStartStopCommand( START_DG_CMD ); } @@ -839,8 +838,22 @@ { dgCmdResp[ DG_CMD_START_FILL ].commandID = DG_CMD_NONE; dgReservoirFillVolumeTargetSet = fillToVolMl; - sendDGFillCommand( fillToVolMl ); + sendDGFillCommand( DG_CMD_START, fillToVolMl ); } + +/*********************************************************************//** + * @brief + * The cmdStopDGFill function sends a fill command with stop parameter message to the DG. + * @details Inputs: none + * @details Outputs: fill command with stop parameter sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGFill( void ) +{ + dgCmdResp[ DG_CMD_STOP_FILL ].commandID = DG_CMD_NONE; + dgReservoirFillVolumeTargetSet = 0; + sendDGFillCommand( DG_CMD_STOP, 0 ); +} /*********************************************************************//** * @brief @@ -869,10 +882,9 @@ * @details Outputs: sample water command sent to DG. * @return none *************************************************************************/ -void cmdDGSampleWater( void ) +void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) { - dgWaterSampled = TRUE; - sendDGSampleWaterCommand(); + sendDGSampleWaterCommand( cmd ); } /*********************************************************************//** @@ -938,7 +950,33 @@ return hasCommandResp; } +/*********************************************************************//** + * @brief + * The checkDGRestart function checks to see if DG has restarted after started + * by HD and triggers appropriate alarm. + * @details Inputs: dgStarted + * @details Outputs: triggers a fault alarm if DG restarted + * @return none + *************************************************************************/ +void checkDGRestart( void ) +{ + if ( dgStartCommandSent == TRUE && ( DG_MODE_CIRC == dgCurrentOpMode ) ) + { + dgStartCommandSent = FALSE; + dgStarted = TRUE; + } + if ( TRUE == dgStarted ) + { + if ( ( DG_MODE_FAUL != dgCurrentOpMode ) && ( DG_MODE_CIRC != dgCurrentOpMode ) && + ( DG_MODE_FILL != dgCurrentOpMode ) && ( DG_MODE_DRAI != dgCurrentOpMode ) ) + { + activateAlarmNoData( ALARM_ID_DG_RESTARTED_FAULT ); + } + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r2f2419f67d9d458837893fef5cc1b21870021026 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 2f2419f67d9d458837893fef5cc1b21870021026) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -120,7 +120,8 @@ void execDGInterfaceMonitor( void ); void initTreatmentReservoirMgmt( void ); -void execTreatmentReservoirMgmt( void ); +void dialysisResumed( void ); +void execTreatmentReservoirMgmt( void ); DG_OP_MODE_T getDGOpMode( void ); U32 getDGSubMode( void ); Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r27f3db92495948d4c1192421c1b0c20338c4a034 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 27f3db92495948d4c1192421c1b0c20338c4a034) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -80,7 +80,6 @@ #define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. -#define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running. #define DIP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running. #define DIP_MAX_CURR_ERROR_DURATION_MS 2000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. @@ -1172,7 +1171,7 @@ else { dipCurr = fabs( getMeasuredDialInPumpMCCurrent() ); - if ( ( dipCurr < DIP_MIN_CURR_WHEN_RUNNING_MA ) || ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) ) + if ( dipCurr > DIP_MAX_CURR_WHEN_RUNNING_MA ) { dipCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; if ( dipCurrErrorDurationCtr > DIP_MAX_CURR_ERROR_DURATION_MS ) @@ -1229,8 +1228,10 @@ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; CALIBRATION_DATA_T cal; +#ifndef SKIP_CALIBRATION_TESTS // Retrieve dialysate flow sensor calibration data if ( ( TRUE == getCalibrationData( &cal ) ) && ( DFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGADialysateFlowMeterStatus() ) ) +#endif { dialInFlowCalGain = cal.dialysateFlowGain; dialInFlowCalOffset = cal.dialysateFlowOffset_mL_min; Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -re23087e0c17f6ea81d60641fdb52121a8dd5a099 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision e23087e0c17f6ea81d60641fdb52121a8dd5a099) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -78,7 +78,6 @@ static const U32 DOP_DIRECTION_ERROR_PERSIST = (250 / TASK_PRIORITY_INTERVAL); #define DOP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped. -#define DOP_MIN_CURR_WHEN_RUNNING_MA 150.0 ///< Motor controller current should always exceed this when pump should be running. #define DOP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running. #define DOP_MAX_CURR_ERROR_DURATION_MS 2000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm. @@ -940,7 +939,7 @@ else { dopCurr = fabs( getMeasuredDialOutPumpMCCurrent() ); - if ( ( dopCurr < DOP_MIN_CURR_WHEN_RUNNING_MA ) || ( dopCurr > DOP_MAX_CURR_WHEN_RUNNING_MA ) ) + if ( dopCurr > DOP_MAX_CURR_WHEN_RUNNING_MA ) { dopCurrErrorDurationCtr += TASK_PRIORITY_INTERVAL; if ( dopCurrErrorDurationCtr > DOP_MAX_CURR_ERROR_DURATION_MS ) Index: firmware/App/HDCommon.h =================================================================== diff -u -r9e2667ac9d2f1b2add9811f93477f0365f1b4eb7 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 9e2667ac9d2f1b2add9811f93477f0365f1b4eb7) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -42,15 +42,15 @@ // #define DISABLE_3WAY_VALVES 1 // Disable 3-way valves // #define TST_3WAY_VALVES_ALWAYS_OPEN 1 // After POST and homing, open all 4 valves #define DISABLE_ACCELS 1 // Disable accelerometer POST and monitoring - #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages - #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message - #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks - #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks - #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks - #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks - #define DISABLE_SALINE_BOLUS_CHECKS 1 // Do not error on HD saline bolus checks +// #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages +// #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message +// #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks +// #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks +// #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks +// #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks +// #define DISABLE_SALINE_BOLUS_CHECKS 1 // Do not error on HD saline bolus checks #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks - #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks +// #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position // #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) // #define RAW_FLOW_SENSOR_DATA 1 // Test build will not filter flow sensor data Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r27f3db92495948d4c1192421c1b0c20338c4a034 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 27f3db92495948d4c1192421c1b0c20338c4a034) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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. @@ -17,13 +17,16 @@ #include "AlarmMgmt.h" #include "Buttons.h" +#include "ConsumableSelfTest.h" #include "FPGA.h" #include "ModePreTreat.h" #include "OperationModes.h" #include "PreTreatmentRecirc.h" #include "Prime.h" #include "SelfTests.h" +#include "SampleWater.h" #include "SystemCommMessages.h" +#include "TaskGeneral.h" /** * @addtogroup HDPreTreatmentMode @@ -32,25 +35,67 @@ // ********** private definitions ********** +/// Interval (ms/task time) at which the pre-treatment state data is published on the CAN bus. +#define PRE_TREATMENT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + +#define DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN 100 ///< Patient connection sub-mode dialysate inlet pump flow rate in mL/min. + +#define PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML 1300 ///< Fill reservoir one to this volume (in mL) during pre-treatment mode. +#define PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML 700 ///< Fill reservoir two to this volume (in mL) during pre-treatment mode. + +/// States of the pre-treatment reservoir management state machine. +typedef enum PreTreatmentReservoirMgmt_States +{ + PRE_TREATMENT_RESERVOIR_MGMT_START_STATE = 0, ///< Wait for signal to start drain and fill reservoirs. + PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE, ///< Command DG to start draining reservoir. + PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE, ///< After sending drain command, process DG drain command response. + PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE, ///< Command DG to start filling reservoir. + PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE, ///< After sending fill command, process DG fill command response. + PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE, ///< Reservoir fill has completed. + NUM_OF_PRE_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of pre-treatments reservoir mgmt. states. +} PRE_TREATMENT_RESERVOIR_MGMT_STATE_T; + // ********** private data ********** -static BOOL treatStartReqReceived = FALSE; ///< Flag indicates user requests treatment begin. -static BOOL alarmActionStopReceived = FALSE; ///< Flag indicates an alarm w/ stop property was triggered. +static BOOL confirmInstallRequested = FALSE; ///< Flag indicates user confirms disposable installation. +static BOOL continueToTreatmentRequested = FALSE; ///< Flag indicates user requests to continue to treatment from re-circ. +static BOOL setUFVolStatus; ///< The status of set UF volume operation. +static BOOL patientConnectionConfirm; ///< Flag indicates user has confirmed patient connection complete. +static BOOL treatmentStartRequested = FALSE; ///< Flag indicates user requests treatment begin. + static BOOL alarmActionResumeReceived = FALSE; ///< Flag indicates alarm action resume received. static HD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current state of pre-treatment mode state machine. +static U32 preTreatmentPublishTimerCounter; ///< Pre-treatment data broadcast timer counter used to schedule when to transmit data. +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current pre-treatment reservoir management state. +static BOOL fillReservoirOneStartRequested; ///< Flag indicates fill reservoir one has been requested. +static BOOL reservoirFilledStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Flag indicates a reservoir has been filled. + // ********** private function prototypes ********** +static void publishPreTreatmentState( void ); static void resetSignalFlags( void ); +static void transitionToCartridgeInstallation( void ); +static void transitionToPatientConnection( void ); +static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ); +static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); static HD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); +static void execPreTreatmentReservoirMgmt( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtStartState( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdState( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdRespState( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdState( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdRespState( void ); +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCompleteState( void ); + /*********************************************************************//** * @brief * The initPreTreatmentMode function initializes the Pre-Treatment Mode module. @@ -61,7 +106,15 @@ void initPreTreatmentMode( void ) { currentPreTreatmentState = HD_PRE_TREATMENT_START_STATE; + setUFVolStatus = FALSE; + patientConnectionConfirm = FALSE; + fillReservoirOneStartRequested = FALSE; + reservoirFilledStatus[ DG_RESERVOIR_1 ] = FALSE; + reservoirFilledStatus[ DG_RESERVOIR_2 ] = FALSE; + + initSampleWater(); + initConsumableSelfTest(); initPrime(); initSelfTests(); @@ -84,6 +137,7 @@ setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); initPreTreatmentMode(); + cmdStopDGTrimmerHeater(); } /*********************************************************************//** @@ -106,16 +160,18 @@ switch ( currentPreTreatmentState ) { case HD_PRE_TREATMENT_START_STATE: - cmdStartDG(); - cmdSetDGDialysateTargetTemps( 39.0, 37.0 ); + transitionToSampleWater(); currentPreTreatmentState = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; break; case HD_PRE_TREATMENT_WATER_SAMPLE_STATE: - transitionToNoCartSelfTests(); - currentPreTreatmentState = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + currentPreTreatmentState = handleWaterSampleState(); break; + case HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE: + currentPreTreatmentState = handleSelfTestConsumableState(); + break; + case HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE: currentPreTreatmentState = handleSelfTestNoCartState(); break; @@ -146,38 +202,133 @@ break; } + // Execute reservoir management for pre-treatment mode + execPreTreatmentReservoirMgmt(); + // Alarm response request flags should be handled at this point, reset in case not handled in current state resetSignalFlags(); + // Broadcast pre-treatment data + publishPreTreatmentState(); + return (U32)currentPreTreatmentState; } /*********************************************************************//** * @brief - * The signalUserBeginningTreatment function handles user start of a - * treatment. + * The signalUserConfirmInstallation function handles user confirmation of + * disposable installation. * @details Inputs: none - * @details Outputs: treatStartReqReceived, send response to treatment start + * @details Outputs: confirmInstallRequested * @return TRUE if signal accepted, FALSE if not *************************************************************************/ -BOOL signalUserBeginningTreatment( void ) +void signalUserConfirmInstallation( void ) { - BOOL result = FALSE; + if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_CART_INSTALL_STATE == currentPreTreatmentState ) ) + { + confirmInstallRequested = TRUE; + } +} - // TODO: check patient connection sub-mode state - if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == currentPreTreatmentState ) ) +/*********************************************************************//** + * @brief + * The signalUserContinueToTreatment function handles user request to continue + * to treatment. + * @details Inputs: none + * @details Outputs: handled and send response to continue to treatment request + * @return none + *************************************************************************/ +void signalUserContinueToTreatment( void ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( HD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) { - treatStartReqReceived = TRUE; - result = TRUE; + continueToTreatmentRequested = TRUE; + accepted = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; } - sendTreatmentStartResponseMsg( result, 0 ); // TODO - provide reason code if rejected + sendContinueToTreatmentCmdResponse( accepted, rejReason ); +} - return result; +/*********************************************************************//** + * @brief + * The setUserSetUFVolumeStatus function sets the status for user sets UF + * volume operation. + * @details Inputs: set UF volume operation status + * @details Outputs: setUFVolStatus + * @return none + *************************************************************************/ +void setUserSetUFVolumeStatus( BOOL status ) +{ + setUFVolStatus = status; } /*********************************************************************//** * @brief + * The signalUserConfirmPatientConnection function handles user confirms + * patient connection message. + * @details Inputs: none + * @details Outputs: handled and send response to patient connection confirmation + * @return none + *************************************************************************/ +void signalUserConfirmPatientConnection( void ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_UF_VOLUME_NOT_SET; + + if ( TRUE == setUFVolStatus ) + { + if ( HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == currentPreTreatmentState ) + { + patientConnectionConfirm = TRUE; + accepted = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } + } + + sendPatientConnectionConfirmCmdResponse( accepted, rejReason ); +} + +/*********************************************************************//** + * @brief + * The signalUserStartTreatment function handles user requests to start treatment. + * @details Inputs: patientConnectionConfirm, currentPreTreatmentState + * @details Outputs: handled and send response to treatment start request + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserStartTreatment( void ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NO_PATIENT_CONNECTION_CONFIRM; + + if ( TRUE == patientConnectionConfirm ) + { + if ( ( MODE_PRET == getCurrentOperationMode() ) && ( HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == currentPreTreatmentState ) ) + { + treatmentStartRequested = TRUE; + accepted = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } + } + + sendTreatmentStartResponseMsg( accepted, rejReason ); + + return accepted; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in PreTreatment Mode. * @details Inputs: none @@ -190,15 +341,22 @@ switch( action ) { case ALARM_ACTION_STOP: - alarmActionStopReceived = TRUE; + // Stop signal actively polled by mode/sub-mode/state break; case ALARM_ACTION_RESUME: alarmActionResumeReceived = TRUE; break; case ALARM_ACTION_END_TREATMENT: - requestNewOperationMode( MODE_STAN ); + if ( HD_PRE_TREATMENT_PRIME_STATE > currentPreTreatmentState ) + { + requestNewOperationMode( MODE_STAN ); + } + else + { + requestNewOperationMode( MODE_POST ); + } break; case ALARM_ACTION_ACK: @@ -213,20 +371,153 @@ /*********************************************************************//** * @brief + * The getReservoirFillStatus function returns the fill complete status for + * given reservoir. + * @details Inputs: reservoirFilledStatus + * @details Outputs: none + * @return TRUE if reservoir has been filled, otherwise FALSE; + *************************************************************************/ +BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) +{ + return reservoirFilledStatus[ reservoirID ]; +} + +/*********************************************************************//** + * @brief + * The publishPreTreatmentState function broadcasts pre-treatment sub-mode + * and current sub-mode state. + * @details Inputs: pre-treatment sub-mode, state + * @details Outputs: pre-treatment sub-mode, state messages sent on interval + * @return none + *************************************************************************/ +static void publishPreTreatmentState( void ) +{ + // Broadcast treatment time and state data at interval + if ( ++preTreatmentPublishTimerCounter >= PRE_TREATMENT_DATA_PUB_INTERVAL ) + { + PRE_TREATMENT_STATE_DATA_T preTreatmentData; + + preTreatmentData.preTreatmentSubMode = currentPreTreatmentState; + preTreatmentData.sampleWaterState = getSampleWaterState(); + preTreatmentData.consumableSelfTestsState = getConsumableSelfTestState(); + preTreatmentData.noCartSelfTestsState = getNoCartSelfTestsState(); + preTreatmentData.installState = 0; + preTreatmentData.drySelfTestsState = getDrySelfTestsState(); + preTreatmentData.primeState = getPrimeState(); + preTreatmentData.recircState = getPreTreatmentRecircState(); + preTreatmentData.patientConnectionState = 0; + + broadcastPreTreatmentState( &preTreatmentData ); + preTreatmentPublishTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief * The resetSignalFlags function resets all signal flags. * @details Inputs: none * @details Outputs: signal flags set to FALSE * @return none *************************************************************************/ static void resetSignalFlags( void ) { - treatStartReqReceived = FALSE; - alarmActionStopReceived = FALSE; + treatmentStartRequested = FALSE; + confirmInstallRequested = FALSE; + continueToTreatmentRequested = FALSE; + alarmActionResumeReceived = FALSE; } /*********************************************************************//** * @brief + * The transitionToCartridgeInstallation function prepares actuators before + * transition to pre-treatment install state. + * @details Inputs: none + * @details Outputs: valves are in insert position + * @return none + *************************************************************************/ +static void transitionToCartridgeInstallation( void ) +{ + VALVE_T valve; + + for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) + { + setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); + } + + setValveAirTrap( STATE_CLOSED ); +} + +/*********************************************************************//** + * @brief + * The transitionToPatientConnection function prepares actuators before + * transition to pre-treatment patient connection state. + * @details Inputs: none + * @details Outputs: Stopped pumps + * @return none + *************************************************************************/ +static void transitionToPatientConnection( void ) +{ + setUFVolStatus = FALSE; + patientConnectionConfirm = FALSE; + treatmentStartRequested = FALSE; + + cmdStartDGTrimmerHeater(); + + signalBloodPumpHardStop(); + signalDialOutPumpHardStop(); + setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); +} + +/*********************************************************************//** + * @brief + * The handleWaterSampleState function handles sample water state during + * pre-treatment mode. + * @details Inputs: none + * @details Outputs: executed sample water state machine + * @return current state (sub-mode) + *************************************************************************/ +static HD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) +{ + HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_WATER_SAMPLE_STATE; + + execSampleWater(); + + if ( TRUE == isSampleWaterPassed() ) + { + state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + transitionToConsumableSelfTest(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleSelfTestConsumableState function handles consumable self-test state + * during pre-treatment mode. + * @details Inputs: none + * @details Outputs: executed consumable self-test state machine + * @return current state (sub-mode) + *************************************************************************/ +static HD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ) +{ + HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + + execConsumableSelfTest(); + + if ( CONSUMABLE_SELF_TESTS_COMPLETE_STATE == getConsumableSelfTestState() ) + { + state = HD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + fillReservoirOneStartRequested = TRUE; + transitionToNoCartSelfTests(); + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleSelfTestNoCartState function handles self-test with no cartridge. * @details Inputs: none * @details Outputs: home blood pump and dialysate pumps @@ -243,19 +534,16 @@ if ( TRUE == alarmActionResumeReceived ) { + alarmActionResumeReceived = FALSE; signalResumeSelfTests(); } - if ( TRUE == alarmActionStopReceived ) - { - signalStopSelfTests(); - } - execNoCartSelfTests(); if ( TRUE == isNoCartSelfTestsPassed() ) { state = HD_PRE_TREATMENT_CART_INSTALL_STATE; + transitionToCartridgeInstallation(); } return state; @@ -272,9 +560,12 @@ { HD_PRE_TREATMENT_MODE_STATE_T state = HD_PRE_TREATMENT_CART_INSTALL_STATE; - // TODO: handle install verification and transition - transitionToDrySelfTests(); - state = HD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + if ( TRUE == confirmInstallRequested ) + { + confirmInstallRequested = FALSE; + state = HD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + transitionToDrySelfTests(); + } return state; } @@ -297,20 +588,16 @@ if ( TRUE == alarmActionResumeReceived ) { + alarmActionResumeReceived = FALSE; signalResumeSelfTests(); } - if ( TRUE == alarmActionStopReceived ) - { - signalStopSelfTests(); - } - execDrySelfTests(); if ( TRUE == isDrySelfTestsPassed() ) { - transitionToPrime(); state = HD_PRE_TREATMENT_PRIME_STATE; + transitionToPrime(); } return state; @@ -334,14 +621,10 @@ if ( TRUE == alarmActionResumeReceived ) { + alarmActionResumeReceived = FALSE; signalResumePrime(); } - if ( TRUE == alarmActionStopReceived ) - { - signalStopPrime(); - } - execPrime(); if ( TRUE == isPrimeCompleted() ) @@ -373,19 +656,17 @@ if ( TRUE == alarmActionResumeReceived ) { + alarmActionResumeReceived = FALSE; signalResumePreTreatmentRecirc(); } - if ( TRUE == alarmActionStopReceived ) - { - signalStopPreTreatmentRecirc(); - } - execPreTreatmentRecirc(); - if ( TRUE == isPatientConnectionRequested() ) + if ( TRUE == continueToTreatmentRequested ) { + continueToTreatmentRequested = FALSE; state = HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + transitionToPatientConnection(); } return state; @@ -401,15 +682,220 @@ *************************************************************************/ static HD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ) { - DG_RESERVOIR_ID_T const activeRes = getDGActiveReservoir(); - - if ( TRUE == treatStartReqReceived ) + if ( TRUE == treatmentStartRequested ) { + DG_RESERVOIR_ID_T const activeRes = getDGActiveReservoir(); setStartReservoirVolume( activeRes ); requestNewOperationMode( MODE_TREA ); } return HD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } +/*********************************************************************//** + * @brief + * The execPreTreatmentReservoirMgmt function executes the state machine for + * reservoir management during pre-treatment mode. + * @details Inputs: currentReservoirMgmtState + * @details Outputs: DG reservoirs' fills managed. + * @return none + *************************************************************************/ +static void execPreTreatmentReservoirMgmt( void ) +{ + // treatment reservoir mgmt. state machine + switch ( currentReservoirMgmtState ) + { + case PRE_TREATMENT_RESERVOIR_MGMT_START_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtStartState(); + break; + + case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtDrainCmdState(); + break; + + case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtDrainCmdRespState(); + break; + + case PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCmdState(); + break; + + case PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCmdRespState(); + break; + + case PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE: + currentReservoirMgmtState = handlePreTreatmentReservoirMgmtFillCompleteState(); + break; + + default: + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRIME_RESERVOIR_MGMT_INVALID_STATE, (U32)currentReservoirMgmtState ); + break; + } +} + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtStartState function handles reservoir + * management start state for pre-treatment mode. + * @details Inputs: fillReservoirOneStartRequested + * @details Outputs: processed fill reservoir one request + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtStartState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; + + if ( TRUE == fillReservoirOneStartRequested ) + { + fillReservoirOneStartRequested = FALSE; + state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtDrainCmdState function sends drain + * command to DG when DG is in re-circulate mode. + * @details Inputs: fillReservoirOneStartRequested + * @details Outputs: processed fill reservoir one request + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + DG_OP_MODE_T dgOpMode = getDGOpMode(); + + if ( DG_MODE_CIRC == dgOpMode ) + { + if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; + cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE ); + } + } + else if ( DG_MODE_STAN == dgOpMode ) + { + cmdStartDG(); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtDrainCmdRespState function waits + * and processes DG drain command response. + * @details Inputs: DG drain command response + * @details Outputs: processed DG drain command response + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtDrainCmdRespState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; + DG_CMD_RESPONSE_T dgCmdResp; + + if ( ( TRUE == getDGCommandResponse( DG_CMD_START_DRAIN, &dgCmdResp ) ) && ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejected ) ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + } + + if ( DG_MODE_DRAI == getDGOpMode() ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + } + + return state; +} + + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtFillCmdState function sends fill + * command to DG when DG is in re-circulate mode. + * @details Inputs: DG operation mode and operation sub-mode + * @details Outputs: sent fill command to DG + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + + if ( ( DG_MODE_CIRC == getDGOpMode() ) && ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getDGSubMode() ) ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; + + if ( DG_RESERVOIR_1 == getDGInactiveReservoir() ) + { + cmdStartDGFill( PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML ); + } + else + { + cmdStartDGFill( PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML ); + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtFillCmdRespState function waits + * and processes DG fill command response. + * @details Inputs: DG fill command response + * @details Outputs: processed DG fill command response + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdRespState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; + DG_CMD_RESPONSE_T dgCmdResp; + + if ( ( TRUE == getDGCommandResponse( DG_CMD_START_FILL, &dgCmdResp ) ) && ( DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE == dgCmdResp.rejected ) ) + { + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + } + + if ( DG_MODE_FILL == getDGOpMode() ) + { + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handlePreTreatmentReservoirMgmtFillCompleteState function switches + * reservoir after the first one fill is complete and restart reservoir management + * state machine. + * @details Inputs: DG operation mode + * @details Outputs: switch active reservoir and signal prime fill complete status + * @return current state of pre-treatment reservoir management + *************************************************************************/ +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCompleteState( void ) +{ + PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; + + if ( DG_MODE_CIRC == getDGOpMode() ) + { + if ( FALSE == reservoirFilledStatus[ DG_RESERVOIR_1 ] ) + { + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; + cmdSetDGActiveReservoir( DG_RESERVOIR_1 ); + } + else if ( ( TRUE == reservoirFilledStatus[ DG_RESERVOIR_1 ] ) && ( FALSE == reservoirFilledStatus[ DG_RESERVOIR_2 ] ) ) + { + reservoirFilledStatus[ DG_RESERVOIR_2 ] = TRUE; + } + } + + return state; +} + /**@}*/ Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r6b870cd0699bb3ee22b93981d51373a6c2d56162 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 6b870cd0699bb3ee22b93981d51373a6c2d56162) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -537,7 +537,11 @@ * active. * @details Inputs: alarmStatus * @details Outputs: none +<<<<<<< HEAD * @return TRUE if any alarm is active, FALSE if not +======= + * @return TRUE if given alarm is active, FALSE if not +>>>>>>> DEN-7091-pre-treatment-mode *************************************************************************/ BOOL isAnyAlarmActive( void ) { Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r936acbb405970a406c8b1f557ea727e7cbf74c94 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 936acbb405970a406c8b1f557ea727e7cbf74c94) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -1201,6 +1201,18 @@ handleUFVolumeSetRequest( message ); break; + case MSG_ID_UI_RINSEBACK_CMD: + handlRinsebackCmd( message ); + break; + + case MSG_ID_UI_RECIRC_CMD: + handleTreatmentRecircCmd( message ); + break; + + case MSG_ID_UI_TX_END_CMD: + handleTreatmentEndCmd( message ); + break; + case MSG_ID_UI_SAMPLE_WATER_CMD: handleSampleWaterCmd( message ); break; @@ -1289,6 +1301,10 @@ case MSG_ID_BLOOD_FLOW_SEND_INTERVAL_OVERRIDE: handleTestBloodFlowBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_TREATMENT_TIME_REMAINING_OVERRIDE: + handleTestTreatmentTimeRemainingOverrideRequest( message ); break; case MSG_ID_BLOOD_PUMP_MEAS_SPEED_OVERRIDE: @@ -1465,10 +1481,46 @@ handleTestDialOutPumpHomeRequest( message ); break; + case MSG_ID_HD_SET_OP_MODE_REQUEST: + handleTestSetOpModeRequest( message ); + break; + case MSG_ID_SUPER_CLEAR_ALARMS_CMD: handleTestSuperClearAlarmsRequest( message ); break; + case MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: + handleTestSyringePumpDataBroadcastIntervalOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_OPERATION_REQUEST: + handleTestSyringePumpOperationRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE: + handleTestSyringePumpMeasuredRateOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE: + handleTestSyringePumpMeasuredForceOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE: + handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE: + handleTestSyringePumpMeasuredHomeOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE: + handleTestSyringePumpMeasuredPositionOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE: + handleTestSyringePumpMeasuredVolumeOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r936acbb405970a406c8b1f557ea727e7cbf74c94 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 936acbb405970a406c8b1f557ea727e7cbf74c94) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -28,13 +28,16 @@ #include "ModePreTreat.h" #include "ModeStandby.h" #include "ModeTreatment.h" -#include "ModeTreatmentParams.h" -#include "PresOccl.h" +#include "ModeTreatmentParams.h" +#include "OperationModes.h" +#include "PresOccl.h" #include "RTC.h" #include "SampleWater.h" #include "SafetyShutdown.h" #include "SystemComm.h" -#include "SystemCommMessages.h" +#include "SystemCommMessages.h" +#include "TreatmentEnd.h" +#include "TreatmentRecirc.h" #include "Utilities.h" #include "Valves.h" #include "WatchdogMgmt.h" @@ -398,8 +401,8 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); return result; -} - +} + /*********************************************************************//** * @brief * The sendChangeBloodDialysateRateChangeResponse function constructs a change @@ -1259,6 +1262,34 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); return result; +} + +/*********************************************************************//** + * @brief + * The broadcastSyringePumpData function constructs a syringe pump data + * msg to be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: syringe pump data msg constructed and queued. + * @param data syringe pump data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastSyringePumpData( SYRINGE_PUMP_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SYRINGE_PUMP_DATA; + msg.hdr.payloadLen = sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; } /*********************************************************************//** @@ -1358,28 +1389,19 @@ * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: treatment state msg constructed and queued - * @param subMode Current state (sub-mode) of treatment - * @param uFState Current state of ultrafiltration - * @param salineBolusState 1=saline bolus in progress, 0=not, 2=max bolus volume reached + * @param payload Record with treatment state data * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL broadcastTreatmentState( U32 subMode, U32 uFState, U32 salineBolusState ) +BOOL broadcastTreatmentState( TREATMENT_STATE_DATA_T payload ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; - TREATMENT_STATE_DATA_T payload; - // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_TREATMENT_STATE; msg.hdr.payloadLen = sizeof( TREATMENT_STATE_DATA_T ); - payload.treatmentSubMode = subMode; - payload.uFState = uFState; - payload.salineBolusState = salineBolusState; - payload.heparinState = 0; // TODO - add this later - memcpy( payloadPtr, &payload, sizeof( TREATMENT_STATE_DATA_T ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer @@ -1529,6 +1551,124 @@ /***********************************************************************//** * @brief + * The broadcastTreatmentStopData function constructs a treatment stop data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: treatment stop data msg constructed and queued + * @param timeout treatment stop timeout (in sec) + * @param countdown treatment stop timeout count down (in sec) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastTreatmentStopData( U32 timeout, U32 countdown ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_TREATMENT_STOP_TIMER_DATA; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); + + memcpy( payloadPtr, &timeout, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &countdown, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief + * The broadcastRinsebackData function constructs a rinseback data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: rinseback data msg constructed and queued + * @param data rinseback data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastRinsebackData( RINSEBACK_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RINSEBACK_PROGRESS; + msg.hdr.payloadLen = sizeof( RINSEBACK_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( RINSEBACK_DATA_PAYLOAD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief + * The broadcastRecircData function constructs a treatment re-circ data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: treatment re-circ data msg constructed and queued + * @param timeout re-circulation timeout (in sec) + * @param countdown re-circulation timeout count down (in sec) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastRecircData( U32 timeout, U32 countdown ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RECIRC_PROGRESS; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ); + + memcpy( payloadPtr, &timeout, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &countdown, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief + * The broadcastBloodPrimeData function constructs a blood prime data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: blood prime data msg constructed and queued + * @param data blood prime data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastBloodPrimeData( BLOOD_PRIME_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_BLOOD_PRIME_PROGRESS; + msg.hdr.payloadLen = sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief * The broadcastAirTrapData function constructs an HD air trap data msg to \n * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -1714,7 +1854,7 @@ memcpy( &cmd, payloadPtr, sizeof( U32 ) ); - signalAlarmSilence( cmd ); + signalAlarmSilence( (ALARM_SILENCE_CMD_T)cmd ); } else { @@ -2254,7 +2394,7 @@ sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); } } - + /*********************************************************************//** * @brief * The handleChangeBloodDialysateRateChangeRequest function handles a blood @@ -2350,9 +2490,10 @@ * @param accepted T/F - was saline bolus request accepted? * @param rejReason reason why request was rejected (or zero if accepted) * @param bolusVol volume (in mL) currently set for saline bolus + * @param bolusState current state of saline bolus * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendSalineBolusResponse( BOOL accepted, U32 rejReason, U32 bolusVol ) +BOOL sendSalineBolusResponse( BOOL accepted, U32 rejReason, U32 bolusVol, U32 bolusState ) { BOOL result; MESSAGE_T msg; @@ -2361,19 +2502,191 @@ // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_USER_SALINE_BOLUS_RESPONSE; - msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( U32 ); + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ); memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); payloadPtr += sizeof( BOOL ); memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); memcpy( payloadPtr, &bolusVol, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &bolusState, sizeof( U32 ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); return result; +} + +/*********************************************************************//** + * @brief + * The handlRinsebackCmd function handles a rinseback user action command + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handlRinsebackCmd( MESSAGE_T *message ) +{ + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 cmd; + + memcpy( &cmd, &message->payload[0], sizeof(U32) ); + + signalRinsebackUserAction( (REQUESTED_RINSEBACK_USER_ACTIONS_T)cmd ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The sendRinsebackCmdResponse function constructs a rinseback user action + * response to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Rinseback command response msg constructed and queued. + * @param accepted T/F - was rinseback user action accepted? + * @param rejReason reason why action was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendRinsebackCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RINSEBACK_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTreatmentRecircCmd function handles a treatment re-circ user action command + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTreatmentRecircCmd( MESSAGE_T *message ) +{ + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 cmd; + + memcpy( &cmd, &message->payload[0], sizeof(U32) ); + + signalTreatmentRecircUserAction( (REQUESTED_TREATMENT_RECIRC_USER_ACTIONS_T)cmd ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The sendTreatmentRecircCmdResponse function constructs a treatment re-circulation + * user action response to the UI and queues the msg for transmit on the appropriate + * CAN channel. + * @details Inputs: none + * @details Outputs: Treatment re-circ command response msg constructed and queued. + * @param accepted T/F - was re-circ user action accepted? + * @param rejReason reason why action was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTreatmentRecircCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RECIRC_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); + + return result; } + +/*********************************************************************//** + * @brief + * The handleTreatmentEndCmd function handles a treatment end user action command + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTreatmentEndCmd( MESSAGE_T *message ) +{ + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 cmd; + + memcpy( &cmd, &message->payload[0], sizeof(U32) ); + + signalTreatmentEndUserAction( (REQUESTED_TREATMENT_END_USER_ACTIONS_T)cmd ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The sendTreatmentEndCmdResponse function constructs a treatment end + * user action response to the UI and queues the msg for transmit on the + * appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Treatment end command response msg constructed and queued. + * @param accepted T/F - was user action accepted? + * @param rejReason reason why action was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTreatmentEndCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_TX_END_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); + + return result; +} /*********************************************************************//** * @brief @@ -3331,7 +3644,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetBloodPumpOcclusionOverride( payload.state.f32 ); + result = testSetBloodPumpOcclusionOverride( payload.state.u32 ); } else { @@ -3363,7 +3676,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetDialInPumpOcclusionOverride( payload.state.f32 ); + result = testSetDialInPumpOcclusionOverride( payload.state.u32 ); } else { @@ -3395,7 +3708,7 @@ memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); if ( FALSE == payload.reset ) { - result = testSetDialOutPumpOcclusionOverride( payload.state.f32 ); + result = testSetDialOutPumpOcclusionOverride( payload.state.u32 ); } else { @@ -3729,6 +4042,31 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The handleTestTreatmentTimeRemainingOverrideRequest function handles a treatment + * time remaining override request message. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestTreatmentTimeRemainingOverrideRequest( MESSAGE_T *message ) +{ + U32 payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(U32) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(U32) ); + result = testSetTreatmentTimeRemainingOverride( payload ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /*********************************************************************//** * @brief * The handleTestHDSafetyShutdownOverrideRequest function handles a @@ -3859,84 +4197,6 @@ /*********************************************************************//** * @brief - * The handleSetAccelCalibration function handles a request to set - * accelerometer calibration factors. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetAccelCalibration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - // Verify payload length - if ( message->hdr.payloadLen == sizeof(ACCEL_CAL_PAYLOAD_T) ) - { - ACCEL_CAL_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof(ACCEL_CAL_PAYLOAD_T) ); - result = setAccelCalibration( payload.xOffset, payload.yOffset, payload.zOffset ); - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** - * @brief - * The handleSetBloodFlowCalibration function handles a request to set - * blood flow calibration factors. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetBloodFlowCalibration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - // Verify payload length - if ( message->hdr.payloadLen == sizeof(LINEAR_F32_CAL_PAYLOAD_T) ) - { - LINEAR_F32_CAL_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof(LINEAR_F32_CAL_PAYLOAD_T) ); - result = setBloodFlowCalibration( payload.gain, payload.offset ); - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** - * @brief - * The handleSetDialysateFlowCalibration function handles a request to set - * dialysate flow calibration factors. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSetDialysateFlowCalibration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - - // Verify payload length - if ( message->hdr.payloadLen == sizeof(LINEAR_F32_CAL_PAYLOAD_T) ) - { - LINEAR_F32_CAL_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof(LINEAR_F32_CAL_PAYLOAD_T) ); - result = setDialInFlowCalibration( payload.gain, payload.offset ); - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** - * @brief * The handleTestSetTreatmentParameter function handles a request to set * a specific treatment parameter value. * @details Inputs: none @@ -4211,9 +4471,8 @@ * @brief * The handleTestBloodPumpHomeRequest function handles a request to home * the blood pump. - * @details - * Inputs : none - * Outputs : message handled + * @details Inputs: none + * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ @@ -4234,9 +4493,8 @@ * @brief * The handleTestDialInPumpHomeRequest function handles a request to home * the dialysate inlet pump. - * @details - * Inputs : none - * Outputs : message handled + * @details Inputs: none + * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ @@ -4257,9 +4515,8 @@ * @brief * The handleTestDialOutPumpHomeRequest function handles a request to home * the dialysate outlet pump. - * @details - * Inputs : none - * Outputs : message handled + * @details Inputs: none + * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ @@ -4280,9 +4537,8 @@ * @brief * The handleTestSuperClearAlarmsRequest function handles a request to clear * all active alarms. - * @details - * Inputs : none - * Outputs : message handled + * @details Inputs: none + * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ @@ -4296,12 +4552,284 @@ memcpy( &key, message->payload, sizeof(U32) ); result = testClearAllAlarms( key ); + } - result = TRUE; + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSetOpModeRequest function handles a request to set the + * HD operation mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSetOpModeRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + U32 mode; + + memcpy( &mode, message->payload, sizeof(U32) ); + result = testSetOperationMode( (HD_OP_MODE_T)mode ); } // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The handleTestSyringePumpDataBroadcastIntervalOverrideRequest function handles a + * request to override the syringe pump data broadcast interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpDataPublishIntervalOverride( (U32)(payload.state.u32) ); + } + else + { + result = testResetSyringePumpDataPublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpOperationRequest function handles a + * request to initiate a syringe pump operation. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpOperationRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(SYRINGE_PUMP_OP_PAYLOAD_T) ) + { + SYRINGE_PUMP_OP_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(SYRINGE_PUMP_OP_PAYLOAD_T) ); + result = testSyringePumpOperationRequest( payload ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredRateOverrideRequest function handles a + * request to override the syringe pump measured rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredRateOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredRateOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredRateOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredForceOverrideRequest function handles a + * request to override the syringe pump measured force analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredForceOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredForceOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredForceOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredSyringeDetectOverrideRequest function handles a + * request to override the syringe pump syringe detected analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredSyringeDetectOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredSyringeDetectOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredHomeOverrideRequest function handles a + * request to override the syringe pump measured home analog signal. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredHomeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredHomeOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredHomeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredPositionOverrideRequest function handles a + * request to override the syringe pump measured position. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredPositionOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredPositionOverride( (S32)(payload.state.u32) ); + } + else + { + result = testResetSyringePumpMeasuredPositionOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestSyringePumpMeasuredVolumeOverrideRequest function handles a + * request to override the syringe pump measured volume delivered. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpMeasuredVolumeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetSyringePumpMeasuredVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetSyringePumpMeasuredVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r936acbb405970a406c8b1f557ea727e7cbf74c94 -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 936acbb405970a406c8b1f557ea727e7cbf74c94) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -21,6 +21,7 @@ #include "HDCommon.h" #include "AirTrap.h" #include "BloodFlow.h" +#include "BloodPrime.h" #include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" @@ -31,6 +32,8 @@ #include "MsgQueues.h" #include "NVDataMgmt.h" #include "PresOccl.h" +#include "Rinseback.h" +#include "SyringePump.h" #include "Valves.h" /** @@ -137,17 +140,20 @@ // MSG_ID_USER_TREATMENT_TIME_CHANGE_RESPONSE BOOL sendChangeTreatmentDurationResponse( BOOL accepted, U32 reason, U32 time_min, F32 volume_mL ); +// MSG_ID_TREATMENT_TIME_REMAINING_OVERRIDE: +void handleTestTreatmentTimeRemainingOverrideRequest( MESSAGE_T *message ); + // MSG_ID_TREATMENT_PARAM_CHANGE_RANGES BOOL sendTreatmentParamsRangesToUI( U32 minTime, U32 maxTime, F32 minUFVol, F32 maxUFVol, U32 minDialRate, U32 maxDialRate ); - + // MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_REQUEST void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ); // MSG_ID_USER_SALINE_BOLUS_REQUEST void handleSalineBolusRequest( MESSAGE_T *message ); // MSG_ID_USER_SALINE_BOLUS_RESPONSE -BOOL sendSalineBolusResponse( BOOL accepted, U32 rejReason, U32 bolusVol ); +BOOL sendSalineBolusResponse( BOOL accepted, U32 rejReason, U32 bolusVol, U32 bolusState ); // MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_RESPONSE BOOL sendChangeBloodDialysateRateChangeResponse( BOOL accepted, U32 reason, U32 bloodRate, U32 dialRate ); @@ -158,6 +164,24 @@ // MSG_ID_HD_PRESSURE_LIMITS_CHANGE_RESPONSE BOOL sendPressureLimitsChangeResponse( PRESSURE_LIMIT_CHANGE_RESPONSE_T *data ); +// MSG_ID_UI_RINSEBACK_CMD +void handlRinsebackCmd( MESSAGE_T *message ); + +// MSG_ID_HD_RINSEBACK_CMD_RESPONSE +BOOL sendRinsebackCmdResponse( BOOL accepted, U32 rejReason ); + +// MSG_ID_UI_RECIRC_CMD +void handleTreatmentRecircCmd( MESSAGE_T *message ); + +// MSG_ID_HD_RECIRC_CMD_RESPONSE +BOOL sendTreatmentRecircCmdResponse( BOOL accepted, U32 rejReason ); + +// MSG_ID_UI_TX_END_CMD: +void handleTreatmentEndCmd( MESSAGE_T *message ); + +// MSG_ID_HD_RECIRC_CMD_RESPONSE +BOOL sendTreatmentEndCmdResponse( BOOL accepted, U32 rejReason ); + // MSG_ID_UI_SAMPLE_WATER_CMD void handleSampleWaterCmd( MESSAGE_T *message ); @@ -250,7 +274,10 @@ BOOL broadcastDialInFlowData( DIALIN_PUMP_STATUS_PAYLOAD_T *dialInData ); // MSG_ID_DIALYSATE_OUT_FLOW_DATA -BOOL broadcastDialOutFlowData( DIAL_OUT_FLOW_DATA_T *dialOutFlowData ); +BOOL broadcastDialOutFlowData( DIAL_OUT_FLOW_DATA_T *dialOutFlowData ); + +// MSG_ID_HD_SYRINGE_PUMP_DATA +BOOL broadcastSyringePumpData( SYRINGE_PUMP_DATA_PAYLOAD_T data ); // MSG_ID_PRESSURE_OCCLUSION_DATA BOOL broadcastPresOcclData( PRESSURE_OCCLUSION_DATA_T data ); @@ -262,7 +289,7 @@ BOOL broadcastTreatmentTime( U32 secsTotTreatment, U32 secsElapsed, U32 secsRemaining ); // MSG_ID_TREATMENT_STATE -BOOL broadcastTreatmentState( U32 subMode, U32 uFState, U32 salineBolusState ); +BOOL broadcastTreatmentState( TREATMENT_STATE_DATA_T payload ); // MSG_ID_PRE_TREATMENT_STATE BOOL broadcastPreTreatmentState( PRE_TREATMENT_STATE_DATA_T *preTreatmentDataPtr ); @@ -279,6 +306,18 @@ // MSG_ID_SALINE_BOLUS_DATA BOOL broadcastSalineBolusData( SALINE_BOLUS_DATA_PAYLOAD_T data ); +// MSG_ID_HD_TREATMENT_STOP_TIMER_DATA +BOOL broadcastTreatmentStopData( U32 timeout, U32 countdown ); + +// MSG_ID_HD_RINSEBACK_PROGRESS +BOOL broadcastRinsebackData( RINSEBACK_DATA_PAYLOAD_T data ); + +// MSG_ID_HD_RECIRC_PROGRESS +BOOL broadcastRecircData( U32 timeout, U32 countdown ); + +// MSG_ID_HD_BLOOD_PRIME_PROGRESS +BOOL broadcastBloodPrimeData( BLOOD_PRIME_DATA_PAYLOAD_T data ); + // MSG_ID_HD_AIR_TRAP_DATA BOOL broadcastAirTrapData( AIR_TRAP_LEVELS_T lowerLevel, AIR_TRAP_LEVELS_T upperLevel ); @@ -430,15 +469,6 @@ // MSG_ID_HD_ACCEL_SEND_INTERVAL_OVERRIDE: void handleTestHDAccelBroadcastIntervalOverrideRequest( MESSAGE_T *message ); -// MSG_ID_HD_ACCEL_SET_CALIBRATION: -void handleSetAccelCalibration( MESSAGE_T *message ); - -// MSG_ID_HD_BLOOD_FLOW_SET_CALIBRATION: -void handleSetBloodFlowCalibration( MESSAGE_T *message ); - -// MSG_ID_HD_DIALYSATE_FLOW_SET_CALIBRATION: -void handleSetDialysateFlowCalibration( MESSAGE_T *message ); - // MSG_ID_HD_SET_PARAMETER_TREATMENT_PARAMETER void handleTestSetTreatmentParameter( MESSAGE_T *message ); @@ -483,12 +513,33 @@ // MSG_ID_SUPER_CLEAR_ALARMS_CMD void handleTestSuperClearAlarmsRequest( MESSAGE_T *message ); -// MSG_ID_HD_REQUEST_CALIBRATION_DATA -void handleTestHDCalibrationDataRequest( MESSAGE_T *message ); +// MSG_ID_HD_SET_OP_MODE_REQUEST +void handleTestSetOpModeRequest( MESSAGE_T *message ); -// MSG_ID_HD_ERASE_CALIBRATION_DATA -void handleTestEraseHDCalibrationDataRequest( MESSAGE_T *message ); +// MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: +void handleTestSyringePumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_SYRINGE_PUMP_OPERATION_REQUEST: +void handleTestSyringePumpOperationRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE: +void handleTestSyringePumpMeasuredRateOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE: +void handleTestSyringePumpMeasuredForceOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE: +void handleTestSyringePumpMeasuredSyringeDetectOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE: +void handleTestSyringePumpMeasuredHomeOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE: +void handleTestSyringePumpMeasuredPositionOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE: +void handleTestSyringePumpMeasuredVolumeOverrideRequest( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/source/sys_main.c =================================================================== diff -u -r569bc4e8119455be23c9d57353243e4479f4afcd -r97e24856b80f612b2556fb9a599e40659710822a --- firmware/source/sys_main.c (.../sys_main.c) (revision 569bc4e8119455be23c9d57353243e4479f4afcd) +++ firmware/source/sys_main.c (.../sys_main.c) (revision 97e24856b80f612b2556fb9a599e40659710822a) @@ -82,6 +82,7 @@ #include "PresOccl.h" #include "RTC.h" #include "SafetyShutdown.h" +#include "SyringePump.h" #include "SystemComm.h" #include "TaskBG.h" #include "Timers.h" @@ -192,6 +193,7 @@ initBloodFlow(); initDialInFlow(); initDialOutFlow(); + initSyringePump(); initValves(); // Initialize modes initOperationModes();