Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u -r273f797e1b0f70a9d5720d1ffff29d26ff5144af -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 273f797e1b0f70a9d5720d1ffff29d26ff5144af) +++ firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -18,6 +18,7 @@ #include "ConcentratePumps.h" #include "FPGA.h" +#include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -34,6 +35,7 @@ #define CONCENTRATE_PUMP_SPEED_INCREMENT 8.0 ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. #define CONCENTRATE_PUMP_MIN_SPEED 3.0 ///< Minimum speed for concentrate pump in mL per min. #define CONCENTRATE_PUMP_MAX_SPEED 49.0 ///< Maximum speed for concentrate pump in mL per min. +#define CONCENTRATE_PUMP_ERROR_TOLERANCE 0.02 ///< Measured speed needs to be within 2% of commanded speed. #define CONCENTRATE_PUMP_VOLUME_PER_REV 0.15 ///< Volume output every revolution (mL). #define CONCENTRATE_PUMP_PULSE_PER_REV 4.0 ///< Number of pulses generate for every revolution. @@ -48,6 +50,7 @@ #define CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is monitored. #define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. +#define CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for concentrate pump speed control error. /// Enumeration of concentrate pump states. typedef enum ConcentratePumpState @@ -70,6 +73,7 @@ static F32 pumpTargetSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Target concentrate pumps' speed (mL/min). static F32 currentPumpSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Current controlled concentrate pumps' speed (mL/min). +static OVERRIDE_F32_T measuredPumpSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Measured concentrate pump speed (mL/min). static U16 togglePeriodCount[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). // ********** private function prototypes ********** @@ -80,6 +84,7 @@ static void stepConcentratePumpToTargetSpeed( CONCENTRATE_PUMPS_T pumpId ); static CONCENTRATE_PUMP_STATE_T handleConcentratePumpOnState( void ); static U32 getPublishConcentratePumpDataInterval( void ); +static F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ); /*********************************************************************//** * @brief @@ -97,6 +102,11 @@ concentratePumpMonitorTimerCounter = 0; stopConcentratePump(); + + initPersistentAlarm( PERSISTENT_ALARM_CP1_SPEED_CONTROL_ERROR, ALARM_ID_CP1_SPEED_CONTROL_ERROR, + TRUE, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_CP2_SPEED_CONTROL_ERROR, ALARM_ID_CP2_SPEED_CONTROL_ERROR, + TRUE, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ); } /*********************************************************************//** @@ -111,19 +121,25 @@ if ( ++concentratePumpMonitorTimerCounter >= getPublishConcentratePumpDataInterval() ) { CONCENTRATE_PUMP_DATA_T data; - concentratePumpMonitorTimerCounter = 0U; F32 const cp1PulseWidthInSecond = (F32)( getFPGACP1HallSensePulseWidth() * CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION ) / US_PER_SECOND; F32 const cp2PulseWidthInSecond = (F32)( getFPGACP2HallSensePulseWidth() * CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION ) / US_PER_SECOND; - F32 const cp1SpeedMlPerMin = ( 1 / cp1PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; - F32 const cp2SpeedMlPerMin = ( 1 / cp2PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + measuredPumpSpeed[ CONCENTRATEPUMPS_CP1 ].data = ( 1 / cp1PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + measuredPumpSpeed[ CONCENTRATEPUMPS_CP2 ].data = ( 1 / cp2PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + F32 const cp1Error = fabs( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1 ) - pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ] ) / pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ]; + F32 const cp2Error = fabs( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2 ) - pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ] ) / pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ]; + data.cp1TargetSpeed = pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ]; - data.cp1MeasuredSpeed = cp1SpeedMlPerMin; + data.cp1MeasuredSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1 ); data.cp2TargetSpeed = pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ]; - data.cp2MeasuredSpeed = cp2SpeedMlPerMin; + data.cp2MeasuredSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2 ); + checkPersistentAlarm( PERSISTENT_ALARM_CP1_SPEED_CONTROL_ERROR, cp1Error > CONCENTRATE_PUMP_ERROR_TOLERANCE, cp1Error ); + checkPersistentAlarm( PERSISTENT_ALARM_CP2_SPEED_CONTROL_ERROR, cp2Error > CONCENTRATE_PUMP_ERROR_TOLERANCE, cp2Error ); + + concentratePumpMonitorTimerCounter = 0U; broadcastConcentratePumpData( &data ); } } @@ -227,6 +243,7 @@ { pumpTargetSpeed[ ii ] = 0.0; currentPumpSpeed[ ii ] = 0.0; + measuredPumpSpeed[ ii ].data = 0.0; } setFPGACP1Control( CONCENTRATE_PUMP_OFF_CONTROL ); @@ -353,7 +370,36 @@ return result; } +/*********************************************************************//** + * @brief + * The getMeasuredPumpSpeed function gets the measured concentrate pump flow rate. + * @details Inputs: measuredPumpSpeed + * @details Outputs: none + * @param pumpId concentrate pump id to increase current step speed + * @return the current concentrate pump flow rate (in mL/min). + *************************************************************************/ +static F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 result = 0.0; + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + result = measuredPumpSpeed[ pumpId ].data; + + if ( OVERRIDE_KEY == measuredPumpSpeed[ pumpId ].override ) + { + result = measuredPumpSpeed[ pumpId ].ovData; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return result; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -432,4 +478,51 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetConcentratePumpMeasuredSpeedOverride function overrides the + * measured speed value of given concentrate pump id. + * @details Inputs: none + * @details Outputs: measuredPumpSpeed[] + * @param pumpId concentrate pump id + * @param value override concentrate pump measured speed + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetConcentratePumpMeasuredSpeedOverride( U32 pumpId, F32 value ) +{ + BOOL result = FALSE; + + if ( ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) && isTestingActivated() ) + { + result = TRUE; + measuredPumpSpeed[ pumpId ].ovData = value; + measuredPumpSpeed[ pumpId ].override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetConcentratePumpMeasuredSpeedOverride function resets the + * measured speed value of given concentrate pump id. + * @details Inputs: none + * @details Outputs: measuredPumpSpeed[] + * @param pumpId concentrate pump id + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetConcentratePumpMeasuredSpeedOverride( U32 pumpId ) +{ + BOOL result = FALSE; + + if ( ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) && isTestingActivated() ) + { + result = TRUE; + measuredPumpSpeed[ pumpId ].ovData = 0.0; + measuredPumpSpeed[ pumpId ].override = OVERRIDE_RESET; + } + + return result; +} + /**@}*/ Index: firmware/App/Controllers/ConcentratePumps.h =================================================================== diff -u -r62ee40b55ed96eb0de1c0f05455eb986f76c1842 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision 62ee40b55ed96eb0de1c0f05455eb986f76c1842) +++ firmware/App/Controllers/ConcentratePumps.h (.../ConcentratePumps.h) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -61,6 +61,8 @@ BOOL testSetConcentratePumpDataPublishIntervalOverride( U32 value ); BOOL testResetConcentratePumpDataPublishIntervalOverride( void ); BOOL testSetConcentratePumpTargetSpeedOverride( U32 pumpId, F32 value ); +BOOL testSetConcentratePumpMeasuredSpeedOverride( U32 pumpId, F32 value ); +BOOL testResetConcentratePumpMeasuredSpeedOverride( U32 pumpId ); /**@}*/ Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r62ee40b55ed96eb0de1c0f05455eb986f76c1842 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 62ee40b55ed96eb0de1c0f05455eb986f76c1842) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -36,18 +36,21 @@ // ********** private definitions ********** -#define FILL_MIN_RO_FLOW_RATE 0.6 ///< Minimum RO flow rate in fill mode. -#define FILL_MAX_RO_FLOW_RATE 1.0 ///< Maximum RO flow rate in fill mode. -#define FILL_TARGET_RO_FLOW_RATE 0.8 ///< Target RO flow rate in fill mode. -#define FILL_TARGET_RO_PRESSURE_PSI 120 ///< Target RO pressure in fill mode. -#define RO_FLOW_RATE_OUT_OF_RANGE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for RO flow rate out of range. +#define FILL_MIN_RO_FLOW_RATE 0.6 ///< Minimum RO flow rate in fill mode. +#define FILL_MAX_RO_FLOW_RATE 1.0 ///< Maximum RO flow rate in fill mode. +#define FILL_TARGET_RO_FLOW_RATE 0.8 ///< Target RO flow rate in fill mode. +#define FILL_TARGET_RO_PRESSURE_PSI 120 ///< Target RO pressure in fill mode. +#define RO_FLOW_RATE_OUT_OF_RANGE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for RO flow rate out of range. -#define DIALYSATE_ACID_CONCENTRATE_RATIO ( 2.35618 / 100 ) ///< Ratio between RO water and acid concentrate. -#define DIALYSATE_BICARB_CONCENTRATE_RATIO ( 4.06812 / 100 ) ///< Ratio between RO water and bicarbonate concentrate. +#define DIALYSATE_ACID_CONCENTRATE_RATIO ( 2.35618 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and acid concentrate. +#define DIALYSATE_BICARB_CONCENTRATE_RATIO ( 4.06812 / FRACTION_TO_PERCENT_FACTOR ) ///< Ratio between RO water and bicarbonate concentrate. +#define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. + // ********** private data ********** -static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. +static DG_FILL_MODE_STATE_T fillState; ///< Currently active fill state. +static U32 dialysateFillStartTime; ///< Current time when starting to fill dialysate. // ********** private function prototypes ********** @@ -82,6 +85,7 @@ void transitionToFillMode( void ) { fillState = DG_FILL_MODE_STATE_START; + dialysateFillStartTime = getMSTimerCount(); // set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); @@ -90,6 +94,19 @@ /*********************************************************************//** * @brief + * The exitFillMode function prepares to exit fill mode. + * @details Inputs: none + * @details Outputs: requests concentrate pumps off, set valve to no fill + * @return none + *************************************************************************/ +void exitFillMode( void ) +{ + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + requestConcentratePumpsOff(); +} + +/*********************************************************************//** + * @brief * The execFillMode function executes the fill mode state machine. * @details Inputs: fillState * @details Outputs: Check water quality, fill mode state machine executed @@ -103,6 +120,12 @@ checkInletPressure(); checkRORejectionRatio(); + // check if run out of time to fill the reservoir + if ( didTimeout( dialysateFillStartTime, DIALYSATE_FILL_TIME_OUT ) ) + { + activateAlarmNoData( ALARM_ID_DG_DIALYSATE_FILL_OUT_OF_TIME ); + } + // execute current Fill state switch ( fillState ) { @@ -255,7 +278,7 @@ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1, acidCP1PumpFlowRate ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2, bicarbCP2PumpFlowRate ); - BOOL const isROPumpFlowRateOutOfRange = ( measuredROFlowRate <= FILL_MIN_RO_FLOW_RATE ) || ( measuredROFlowRate >= FILL_MAX_RO_FLOW_RATE ) ; + BOOL const isROPumpFlowRateOutOfRange = ( measuredROFlowRate <= FILL_MIN_RO_FLOW_RATE ) || ( measuredROFlowRate >= FILL_MAX_RO_FLOW_RATE ); checkPersistentAlarm( PERSISTENT_ALARM_RO_PUMP_FLOW_RATE_OUT_OF_RANGE, isROPumpFlowRateOutOfRange, measuredROFlowRate ); } Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -r16cd633e1d18224face6f977120ccab3846e7671 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 16cd633e1d18224face6f977120ccab3846e7671) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -35,6 +35,7 @@ void initFillMode( void ); // initialize this module void transitionToFillMode( void ); // prepares for transition to fill mode +void exitFillMode( void ); // prepares to exit fill mode U32 execFillMode( void ); // execute the fill mode state machine (call from OperationModes) /**@}*/ Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r0bf1c0824844ed4c227eef0323238daedf505dc7 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 0bf1c0824844ed4c227eef0323238daedf505dc7) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -69,6 +69,7 @@ // ********** private function prototypes ********** static DG_OP_MODE_T arbitrateModeRequest( void ); +static void exitCurrentOperationMode( DG_OP_MODE_T oldMode ); static void transitionToNewOperationMode( DG_OP_MODE_T newMode ); static void broadcastOperationMode( void ); @@ -134,6 +135,7 @@ if ( currentMode != newMode ) { // handle transition to new mode + exitCurrentOperationMode( currentMode ); transitionToNewOperationMode( newMode ); currentMode = newMode; } @@ -270,6 +272,28 @@ /*********************************************************************//** * @brief + * The exitCurrentOperationMode function undergo the process of exit the + * current operation mode. + * @details Inputs: none + * @details Outputs: clean up when exit current mode + * @param oldMode old op mode to clean up + * @return none + *************************************************************************/ +static void exitCurrentOperationMode( DG_OP_MODE_T oldMode ) +{ + switch ( oldMode ) + { + case DG_MODE_FILL: + exitFillMode(); + break; + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, 0, (U32)oldMode ) // TODO - add s/w fault enum to 1st data param + break; + } +} + +/*********************************************************************//** + * @brief * The transitionToNewOperationMode function undergo the process of transition * to new operation mode. * @details Inputs: none Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r7e2931d9a468ca3b6e1f2bb88ef0910960dfdb29 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 7e2931d9a468ca3b6e1f2bb88ef0910960dfdb29) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -1148,6 +1148,10 @@ handleDGSoftwareResetRequest( message ); break; + case MSG_ID_DG_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE: + handleConcentratePumpMeasuredSpeedlOverride( message ); + break; + case MSG_ID_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE: handleSetConcentratePumpTargetSpeed( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r62ee40b55ed96eb0de1c0f05455eb986f76c1842 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 62ee40b55ed96eb0de1c0f05455eb986f76c1842) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -1886,6 +1886,38 @@ /*********************************************************************//** * @brief + * The handleConcentratePumpMeasuredSpeedlOverride function handles a request + * to override a concentrate pump measured speed value. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleConcentratePumpMeasuredSpeedlOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetConcentratePumpMeasuredSpeedOverride( payload.index, payload.state.f32 ); + } + else + { + result = testResetConcentratePumpMeasuredSpeedOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleSetConcentratePumpTargetSpeed function handles a request to * override a concentrate pump's target speed value. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r7e2931d9a468ca3b6e1f2bb88ef0910960dfdb29 -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 7e2931d9a468ca3b6e1f2bb88ef0910960dfdb29) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -200,6 +200,9 @@ // MSG_ID_DG_SOFTWARE_RESET_REQUEST void handleDGSoftwareResetRequest( MESSAGE_T *message); +// MSG_ID_DG_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE +void handleConcentratePumpMeasuredSpeedlOverride( MESSAGE_T *message ); + // MSG_ID_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE void handleSetConcentratePumpTargetSpeed( MESSAGE_T *message );