Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -rc230be1bd4296324bf5dfc288c212eb7c2ce5d2d -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision c230be1bd4296324bf5dfc288c212eb7c2ce5d2d) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -20,6 +20,7 @@ #include "FPGA.h" #include "NVDataMgmt.h" #include "MessageSupport.h" +#include "ModeFill.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" @@ -52,6 +53,9 @@ #define MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 200.0F ///< Maximum allowed low conductivity value in uS/cm. #define MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 220.0F ///< Minimum allowed low conductivity value in uS/cm. +#define MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 100.0F ///< Maximum RO only mode high conductivity value in uS/cm. +#define MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 90.0F ///< Minimum RO only mode high conductivity value in uS/cm. + #define MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< New reading every 800 ms, expect to get valid new reading in 1s. #define MAX_CONDUCTIVITY_SENSOR_FAILURES 5 ///< maximum number of conductivity sensor errors within window period before alarm. #define MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ( 60 * MS_PER_SECOND ) ///< Conductivity sensor error window. @@ -299,9 +303,20 @@ { DG_OP_MODE_T opMode = getCurrentOperationMode(); F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - BOOL isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); - BOOL isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); + BOOL isConductTooLow = FALSE; + BOOL isConductTooHigh = FALSE; + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + } + else + { + isConductTooLow = FALSE; + isConductTooHigh = ( conductivity > MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? TRUE : FALSE ); + } + switch( opMode ) { case DG_MODE_GENE: @@ -317,7 +332,14 @@ if ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) { - isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + } + else + { + isConductTooHigh = ( conductivity <= MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? FALSE : TRUE ); + } } // Per PRS 404 Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -rc230be1bd4296324bf5dfc288c212eb7c2ce5d2d -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision c230be1bd4296324bf5dfc288c212eb7c2ce5d2d) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -139,6 +139,7 @@ static U32 pumpSpeedIndex; ///< Index used to access the desired pump speed in roPumpFlushBubblesSpeed table. static BOOL havePauseActuatorsBeenSet; ///< Flag to indicate the actuators have been set to pause for the first time. +static BOOL hasROOnlyModeBeenEnabled; ///< Flag to indicate the RO only mode has been set or not. static OVERRIDE_F32_T usedAcidVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated acid concentration volume has been used in mL. static OVERRIDE_F32_T usedBicarbVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated bicarb concentration volume has been used in mL. static OVERRIDE_U32_T fillModeDataPublishInterval = { FILL_MODE_DATA_PUB_INTERVAL, @@ -169,7 +170,7 @@ * @details Outputs: fillState, dialysateFillStartTime, reservoirBaseWeight, * totalROFlowRateMLPM, concentrateTestStartTime, acidConductivityTotal, * bicarbConductivityTotal, conductivitySampleCount, havePauseActuatorsBeenSet - * concentratePumpPrimeCount + * concentratePumpPrimeCount, hasROOnlyModeBeenEnabled * @return none *************************************************************************/ void initFillMode( void ) @@ -197,6 +198,7 @@ sumFillCPoConductivity = 0.0F; sumFillRejRatio = 0.0F; fillCPoConductivitySampleCnt = 0; + hasROOnlyModeBeenEnabled = FALSE; } /*********************************************************************//** @@ -439,6 +441,7 @@ * @details Inputs: none * @details Outputs: none * @param flag to TRUE if prime is needed otherwise FALSE + * @return none *************************************************************************/ void setThisFisrtFillFlag( BOOL flag ) { @@ -447,6 +450,32 @@ /*********************************************************************//** * @brief + * The enableROOnlyMode function sets the boolean flag that indicates RO + * only mode has been enabled. + * @details Inputs: none + * @details Outputs: hasROOnlyModeBeenEnabled + * @return none + *************************************************************************/ +void enableROOnlyMode( void ) +{ + hasROOnlyModeBeenEnabled = TRUE; +} + +/*********************************************************************//** + * @brief + * The isROOnlyModeEnabled function returns the status of RO only mode. + * @details Inputs: none + * @details Outputs: none + * @return hasROOnlyModeBeenEnabled, TRUE if the RO only mode has been set + * otherwise, FALSE + *************************************************************************/ +BOOL isROOnlyModeEnabled( void ) +{ + return hasROOnlyModeBeenEnabled; +} + +/*********************************************************************//** + * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. @@ -847,7 +876,7 @@ // Fault alarm per PRS 483 SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, avgCPo, MAX_CPO_CONDUCTIVITY_ALLOW ); } - if ( avgRR > MAX_RO_REJECTION_RATIO_ALLOW ) + if ( ( avgRR > MAX_RO_REJECTION_RATIO_ALLOW ) && ( FALSE == isROOnlyModeEnabled() ) ) { // Fault alarm per PRS 483 SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, MAX_RO_REJECTION_RATIO_ALLOW ); @@ -1063,6 +1092,7 @@ fillModeData.usedAcidVolumeML = getChemicalUsedVolumeML( ACID ); fillModeData.usedBicarbVolumeML = getChemicalUsedVolumeML( BICARB ); fillModeData.integratedVolumeML = getIntegratedVolumeML(); + fillModeData.roOnlyModeStatus = (U32)isROOnlyModeEnabled(); broadcastData( MSG_ID_DG_FILL_MODE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&fillModeData, sizeof( DG_FILL_MODE_DATA_T ) ); Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -r6530db1926d689b51c2f5fcd6ae928c40ebf5f42 -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 6530db1926d689b51c2f5fcd6ae928c40ebf5f42) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -49,6 +49,7 @@ F32 usedAcidVolumeML; ///< The used acid volume in ML. F32 usedBicarbVolumeML; ///< The used bicarb volume in ML. F32 integratedVolumeML; ///< Integrated volume in milliliters. + U32 roOnlyModeStatus; ///< RO only mode status. } DG_FILL_MODE_DATA_T; // ********** public function prototypes ********** @@ -60,21 +61,20 @@ U32 execFillMode( void ); // execute the fill mode state machine (call from OperationModes) F32 getAvgFillFlowRateLPM( void ); - F32 getAvgFillTemperature( void ); - F32 getLastFillTemperature( void ); void setThisFisrtFillFlag( BOOL flag ); // indicates bottles need prime when set to TRUE - void resetFillStatusParameters( void ); BOOL isThisTheFirstFill( void ); F32 getChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ); - void resetChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ); +void enableROOnlyMode( void ); +BOOL isROOnlyModeEnabled( void ); + BOOL testSetUsedAcidVolumeMLOverride( F32 value ); BOOL testResetUsedAcidVolumeMLOverride( void ); Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r4c7ef2a9a07569d02844f58b74c4fbdc96a06999 -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 4c7ef2a9a07569d02844f58b74c4fbdc96a06999) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -274,6 +274,8 @@ postCompleted = TRUE; // Broadcast final POST passed sendPOSTFinalResult( TRUE ); + // Request whether we are in the RO only mode from UI + requestROOnlyModeStatusFromUI(); // Go to standby mode requestNewOperationMode( DG_MODE_STAN ); break; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rc230be1bd4296324bf5dfc288c212eb7c2ce5d2d -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision c230be1bd4296324bf5dfc288c212eb7c2ce5d2d) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -921,6 +921,10 @@ handleReceiveChemFlushSampleResultsFromHD( message ); break; + case MSG_ID_DG_SET_RO_ONLY_MODE: + handleSetROOnlyMode( message ); + break; + // NOTE: This case must be last case MSG_ID_DG_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rc230be1bd4296324bf5dfc288c212eb7c2ce5d2d -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c230be1bd4296324bf5dfc288c212eb7c2ce5d2d) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -81,7 +81,8 @@ // ********** private function prototypes ********** static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); +static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); +static BOOL sendUIResponseMsg( MSG_ID_T msgID, BOOL accepted, U32 reason ); /*********************************************************************//** * @brief @@ -222,7 +223,39 @@ return result; } +/*********************************************************************//** + * @brief + * The sendUIResponseMsg function constructs an UI response message for a + * handled UI message and queues it for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: response message constructed and queued for transmit. + * @param msgID ID of handled message that we are responding to + * @param accepted T/F - request accepted? + * @param reason reason code if rejected + * @return TRUE if response message successfully queued for transmit, FALSE if not + *************************************************************************/ +static BOOL sendUIResponseMsg( MSG_ID_T msgID, BOOL accepted, U32 reason ) +{ + BOOL result; + MESSAGE_T msg; + UI_RESPONSE_PAYLOAD_T cmd; + cmd.accepted = accepted; + cmd.rejectionReason = reason; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = msgID; + msg.hdr.payloadLen = sizeof( UI_RESPONSE_PAYLOAD_T ); + memcpy( &msg.payload, &cmd, sizeof( UI_RESPONSE_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_DG_2_UI, ACK_REQUIRED ); + + return result; +} + + // *********************************************************************** // ***************** Message Sending Helper Functions ******************** // *********************************************************************** @@ -1685,7 +1718,79 @@ sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, status ); } +/*********************************************************************//** + * @brief + * The handleSetROOnlyMode function handles the setting of the RO mode only. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetROOnlyMode( MESSAGE_T* message ) +{ + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PAYLOAD_LENGTH; + BOOL accepted = FALSE; + if ( message->hdr.payloadLen == sizeof(U32) ) + { + U32 result; + + rejReason = REQUEST_REJECT_REASON_NONE; + + memcpy( &result, message->payload, sizeof(U32) ); + + if ( ( 0 == result ) || ( 1 == result ) ) + { + switch ( getCurrentOperationMode() ) + { + case DG_MODE_FAUL: + case DG_MODE_SERV: + case DG_MODE_INIT: + case DG_MODE_STAN: + if ( TRUE == (BOOL)result ) + { + enableROOnlyMode(); + accepted = TRUE; + } + break; + + default: + rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_DG_BUSY; + break; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PARAMETER; + } + } + + sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, accepted, rejReason ); + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_REQUIRED ); +} + +/*********************************************************************//** + * @brief + * The requestROOnlyModeStatusFromUI function handles the request + * the RO only mode status from UI. + * @details Inputs: none + * @details Outputs: message handled + * @return none + *************************************************************************/ +void requestROOnlyModeStatusFromUI( void ) +{ + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_RO_ONLY_MODE_STATUS_REQUEST; + msg.hdr.payloadLen = 0; + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_REQUIRED ); +} + + // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rc230be1bd4296324bf5dfc288c212eb7c2ce5d2d -rb0f90032367640dd22ddfbe0307a20cb6e931ceb --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision c230be1bd4296324bf5dfc288c212eb7c2ce5d2d) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision b0f90032367640dd22ddfbe0307a20cb6e931ceb) @@ -48,6 +48,13 @@ #define ACK_REQUIRED TRUE ///< Require an ACK. #define ACK_NOT_REQUIRED FALSE ///< Not require an ACK. +/// UI response payload data structure +typedef struct +{ + BOOL accepted; ///< Accepted/Rejected + U32 rejectionReason; ///< Rejection reason if not accepted. +} UI_RESPONSE_PAYLOAD_T; + // ********** public function prototypes ********** U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ); @@ -169,6 +176,12 @@ // MSG_ID_HD_SEND_CHEM_FLUSH_SAMPLE_PASS_FAIL_TO_DG void handleReceiveChemFlushSampleResultsFromHD( MESSAGE_T *message ); +// MSG_ID_DG_SET_RO_MODE_ONLY +void handleSetROOnlyMode( MESSAGE_T* message ); + +// MSG_ID_DG_REQUEST_RO_MODE_ONLY_STATUS +void requestROOnlyModeStatusFromUI( void ); + // *********** public test support message functions ********** // MSG_TESTER_LOG_IN