Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -104,6 +104,7 @@ static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. static U32 resUseTimer = 0; ///< Used to track time pumping from active reservoir (for volume used calculation). static F32 resUseVolumeMl = 0.0; ///< Accumulated volume used from active reservoir. +static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. // DG command response static DG_CMD_RESPONSE_T dgCmdResp[ NUM_OF_DG_COMMANDS ]; ///< Keep the latest DG command response for each command. @@ -542,6 +543,17 @@ /*********************************************************************//** * @brief + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @return the current DG disinfects readings + *************************************************************************/ +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +{ + return disinfectsStatus; +} + +/*********************************************************************//** * The getReservoirWeight function gets the load cell weight of a given * reservoir. * @details Inputs: loadCellWeightInGrams[] @@ -724,6 +736,20 @@ updateReservoirVolumes( res1Primary, res2Primary ); } +/*********************************************************************//** + * @brief + * The setDGDisinfectsStates function sets the latest disinfects states + * from DG. + * @details Inputs: none + * @details Outputs: disinfectsStatus + * @param states latest DG disinfects state readings + * @return none + *************************************************************************/ +void setDGDisinfectsStates( DG_DISINFECT_UI_STATES_T states ) +{ + memcpy( &disinfectsStatus, &states, sizeof(DG_DISINFECT_UI_STATES_T) ); +} + /*********************************************************************//** * @brief * The cmdSetDGDialysateTargetTemps function sends a target dialysate @@ -903,10 +929,100 @@ void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) { sendDGSampleWaterCommand( cmd ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGFlush function sends a start flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: start flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGFlush( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_FLUSH ].commandID = DG_CMD_NONE; + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGFlush function sends a stop flush command message to + * the DG. + * @details Inputs: none + * @details Outputs: stop flush mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGFlush( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_FLUSH ].commandID = DG_CMD_NONE; + sendDGStartFlushModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGHeatDisinfect function sends a start heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGHeatDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGHeatDisinfect function sends a stop heat disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop heat disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGHeatDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_HEAT_DISINFECT ].commandID = DG_CMD_NONE; + sendDGStartHeatDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGChemicalDisinfect function sends a start chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: start chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStartDGChemicalDisinfect( void ) +{ + BOOL start = TRUE; + dgCmdResp[ DG_CMD_START_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + sendDGStartChemicalDisinfectModeCommand( start ); } /*********************************************************************//** * @brief + * The cmdStopDGChemicalDisinfect function sends a stop chemical disinfect + * command message to the DG. + * @details Inputs: none + * @details Outputs: stop chemical disinfect mode command sent to DG. + * @return none + *************************************************************************/ +void cmdStopDGChemicalDisinfect( void ) +{ + BOOL start = FALSE; + dgCmdResp[ DG_CMD_STOP_CHEM_DISINFECT ].commandID = DG_CMD_NONE; + sendDGStartChemicalDisinfectModeCommand( start ); +} + +/*********************************************************************//** + * @brief * The handleDGCommandResponse function processes the latest DG command response. * @details Inputs: none * @details Outputs: process command response from DG Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -169,14 +169,14 @@ { VALVE_POSITION_T commandedPosition; ///< Valve commanded position enum VALVE_POSITION_T currentPosition; ///< Valve current position enum - S16 currentPositionInCounts; ///< Valve current position in counts + OVERRIDE_S32_T currentPositionInCounts; ///< Valve current position in counts S16 targetPositionInCounts; ///< Valve target position in counts BOOL hasTransitionBeenRequested; ///< Valve transition request flag VALVE_STATE_T execState; ///< Valve execution state U32 transitionStartTime; ///< Valve transition start time S16 positions[ NUM_OF_VALVE_POSITIONS ]; ///< Valve positions array (Pos A, Pos B, Pos C) VALVE_MODE_T controlMode; ///< Valve control mode (PID, bypass, disable) - F32 current; ///< Valve current + OVERRIDE_F32_T current; ///< Valve current U32 overCurrentCounter; ///< Valve over current counter U32 positionOutOfRangeCounter; ///< Valve position out of range counter U32 dataPublishCounter; ///< Valve data publish counter @@ -243,10 +243,11 @@ static BOOL areValvesFunctional( void ); static void setFPGAValveSetPoint( VALVE_T valve, S16 position, BOOL enableCurrentRelaxation ); static void convertAndMonitorValvesCurrent( void ); -static void getAndMonitorValvesCurrentPosition( void ); +static void getAndMonitorValvesCurrentFPGAPosition( void ); static U32 getPublishValvesDataInterval( void ); static void publishValvesData( VALVE_T valve ); static void setValveNextStep( VALVE_T valve, U32 stepChange ); +static S16 getValvePositionCounts( VALVE_T valve ); // These functions will be used in debug only mode #ifdef DEBUG_ENABLED @@ -280,6 +281,10 @@ for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) { valvesStatus[ valve ].execState = VALVE_STATE_WAIT_FOR_POST; + valvesStatus[ valve ].current.data = 0.0; + valvesStatus[ valve ].current.ovData = 0.0; + valvesStatus[ valve ].current.ovInitData = 0.0; + valvesStatus[ valve ].current.override = 0; } // Close air trap valve @@ -367,6 +372,26 @@ /*********************************************************************//** * @brief + * The getValveCurrent function returns the current of a valve. + * @details Inputs: none + * @details Outputs: valvesStatus + * @param valve that the current is requested + * @return returns the current of the valve in float + *************************************************************************/ +F32 getValveCurrent( VALVE_T valve ) +{ + F32 current = valvesStatus[ valve ].current.data; + + if ( OVERRIDE_KEY == valvesStatus[ valve ].current.override ) + { + current = valvesStatus[ valve ].current.ovData; + } + + return current; +} + +/*********************************************************************//** + * @brief * The setValveBloodTrap function set the blood trap valve to open or close * position. * @details Inputs: valveAirTrapStatus @@ -599,7 +624,7 @@ { // Get ready for the energized state valvesStatus[ valve ].homingEdgeDetectionCounter = 0; - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + HOMING_STEP_CHANGE_IN_COUNTS; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + HOMING_STEP_CHANGE_IN_COUNTS; valvesStatus[ valve ].hasValveBeenHomed = FALSE; valvesStatus[ valve ].currentPosition = VALVE_POSITION_NOT_IN_POSITION; setFPGAValveSetPoint( valve, valvesStatus[ valve ].targetPositionInCounts, FALSE ); @@ -622,7 +647,7 @@ { VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; S16 deltaPosition = targetPosition - currentPosition; @@ -643,7 +668,6 @@ { valvesStatus[ valve ].homingEdgeDetectionCounter++; } - } // Reached to target, go for the next target else @@ -669,7 +693,7 @@ { VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; S16 deltaPosition = currentPosition - targetPosition; @@ -815,7 +839,7 @@ // Get the corresponding counts of the positions S16 commandedPosition = valvesStatus[ valve ].positions[ commandedPositionEnum ]; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; // Check if the valve is within range of the final commanded position. @@ -941,7 +965,7 @@ #endif // Get the current position of the valves in counts and store them - getAndMonitorValvesCurrentPosition(); + getAndMonitorValvesCurrentFPGAPosition(); #ifndef DISABLE_3WAY_VALVES // Get the current in ADC and convert them to amps @@ -1084,22 +1108,22 @@ U16 currentInADC = 0; currentInADC = getFPGAValveDialyzerInletCurrentCounts(); - valvesStatus[ VDI ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VDI ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveDialyzerOutletCurrentCounts(); - valvesStatus[ VDO ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VDO ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveBloodArterialCurrentCounts(); - valvesStatus[ VBA ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VBA ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveBloodVenousCurrentCounts(); - valvesStatus[ VBV ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VBV ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; // Check the current of all the valves for ( valve = VDI; valve < NUM_OF_VALVES; valve++) { // Absolute value is used to cover both positive and negative values - F32 current = fabs( valvesStatus[ valve ].current ); + F32 current = fabs( getValveCurrent( valve ) ); if ( current > VALVES_CURRENT_THRESHOLD_AMPS ) { @@ -1113,8 +1137,7 @@ #endif } // If the current is below the threshold again and the counter for the time is greater than - else if ( current < VALVES_CURRENT_THRESHOLD_AMPS && - valvesStatus[ valve ].overCurrentCounter > 0 ) + else if ( ( current < VALVES_CURRENT_THRESHOLD_AMPS ) && ( valvesStatus[ valve ].overCurrentCounter > 0 ) ) { valvesStatus[ valve ].overCurrentCounter = 0; } @@ -1123,27 +1146,27 @@ /*********************************************************************//** * @brief - * The getAndMonitorValvesCurrentPosition function gets the current position \n - * of the valves and stores them into the structure of each valve. The function \n - * checks whether any of the valves have deviated from their current position \n - * if they are in idle state. If any of the valves have deviated, the function \n - * raises an alarm. + * The getAndMonitorValvesCurrentFPGAPosition function gets the current + * position of the valves from FPGA and stores them into the structure of + * each valve.The function checks whether any of the valves have deviated + * from their current position if they are in idle state. If any of the + * valves have deviated, the function raises an alarm. * @details Inputs: valvesStatus * @details Outputs: valvesStatus * @return none *************************************************************************/ -static void getAndMonitorValvesCurrentPosition( void ) +static void getAndMonitorValvesCurrentFPGAPosition( void ) { VALVE_T valve; S16 currentPostion = 0; S16 commandedPoistion = 0; VALVE_POSITION_T commandedPositionEnum; // Get the position of the valves and update the structure of each valve - valvesStatus[ VDI ].currentPositionInCounts = getFPGAValveDialyzerInletPosition(); - valvesStatus[ VDO ].currentPositionInCounts = getFPGAValveDialyzerOutletPosition(); - valvesStatus[ VBA ].currentPositionInCounts = getFPGAValveBloodArterialPosition(); - valvesStatus[ VBV ].currentPositionInCounts = getFPGAValveBloodVenousPosition(); + valvesStatus[ VDI ].currentPositionInCounts.data = (S32)getFPGAValveDialyzerInletPosition(); + valvesStatus[ VDO ].currentPositionInCounts.data = (S32)getFPGAValveDialyzerOutletPosition(); + valvesStatus[ VBA ].currentPositionInCounts.data = (S32)getFPGAValveBloodArterialPosition(); + valvesStatus[ VBV ].currentPositionInCounts.data = (S32)getFPGAValveBloodVenousPosition(); #ifndef DISABLE_3WAY_VALVES // Check the position of each valve @@ -1154,7 +1177,7 @@ { U32 maxDeviation = MAX_DEVIATION_FROM_TARGET_IN_COUNTS; - currentPostion = valvesStatus[ valve ].currentPositionInCounts; + currentPostion = getValvePositionCounts( valve ); commandedPositionEnum = valvesStatus[ valve ].commandedPosition; commandedPoistion = valvesStatus[ valve ].positions[ commandedPositionEnum ]; @@ -1225,10 +1248,10 @@ HD_VALVE_DATA_T valveData; valveData.valveID = (U32)valve; valveData.state = (U32)valvesStatus[ valve ].execState; - valveData.currentPosID = (U32)valvesStatus[ valve ].currentPosition; - valveData.currentPos = valvesStatus[ valve ].currentPositionInCounts; + valveData.currentPosID = (U32)getValvePosition( valve ); + valveData.currentPos = getValvePositionCounts( valve ); valveData.nextPos = valvesStatus[ valve ].targetPositionInCounts; - valveData.current = valvesStatus[ valve ].current; + valveData.current = getValveCurrent( valve ); valveData.posC = valvesStatus[ valve ].positions[ VALVE_POSITION_C_CLOSE ]; valveData.posA = valvesStatus[ valve ].positions[ VALVE_POSITION_A_INSERT_EJECT ]; valveData.posB = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ]; @@ -1255,7 +1278,7 @@ S16 nextStep = 0; VALVE_POSITION_T currentPositionEnum = valvesStatus[ valve ].currentPosition; VALVE_POSITION_T commandedPositionEnum = valvesStatus[ valve ].commandedPosition; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 commandedPosition = valvesStatus[ valve ].positions[ commandedPositionEnum ]; // If the next step is less than the specified step change, set that @@ -1281,22 +1304,22 @@ // Subtract the defined number of steps for the next transition if ( commandedPositionEnum == VALVE_POSITION_B_OPEN ) { - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; } if ( commandedPositionEnum == VALVE_POSITION_C_CLOSE ) { - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts - nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; } break; case VALVE_POSITION_B_OPEN: // If the valve is currently in position B, subtract the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts - nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; break; case VALVE_POSITION_C_CLOSE: // If the valve is currently in position C, add the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; break; default: @@ -1309,6 +1332,27 @@ setFPGAValveSetPoint( valve, valvesStatus[ valve ].targetPositionInCounts, FALSE ); } +/*********************************************************************//** + * @brief + * The getValvePositionCounts function returns a valve's position in + * counts. + * @details Inputs: valvesStatus + * @details Outputs: none + * @param valve that its position in counts is requested + * @return current position of the valve in counts (S16) + *************************************************************************/ +static S16 getValvePositionCounts( VALVE_T valve ) +{ + S16 position = (S16)valvesStatus[ valve ].currentPositionInCounts.data; + + if ( OVERRIDE_KEY == valvesStatus[ valve ].currentPositionInCounts.override ) + { + position = (S16)valvesStatus[ valve ].currentPositionInCounts.ovData; + } + + return position; +} + #ifdef DEBUG_ENABLED /*********************************************************************//** * @brief @@ -1464,7 +1508,7 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { // Get the current position of the valve as the initial position valvesPositionOverride[ valve ].ovInitData = (U32)valvesStatus[ valve ].currentPosition; @@ -1483,14 +1527,14 @@ * of the valves publish interval. * @details Inputs: valvesDataPublishInterval * @details Outputs: valvesDataPublishInterval - * @param valve that its data publish will be overridden + * @param valve that its position override will be reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetValvesPositionOverride( U32 valve ) { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { valvesPositionOverride[ valve ].override = OVERRIDE_RESET; valvesPositionOverride[ valve ].ovData = valvesPositionOverride[ valve ].ovInitData; @@ -1518,13 +1562,13 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { BOOL homingStatus = valvesStatus[ valve ].hasValveBeenHomed; // The PWM should be in range and also the valve direction should be legal and the valve must have been homed // Prior to running this command - if ( pwm <= VALVE_MAX_ALLOWED_PWM_PERCENT && direction < NUM_OF_VALVE_DIRECTION && homingStatus ) + if ( ( pwm <= VALVE_MAX_ALLOWED_PWM_PERCENT ) && ( direction < NUM_OF_VALVE_DIRECTION ) && ( TRUE == homingStatus ) ) { valvesStatus[ (VALVE_T)valve ].bypassModeStatus.commandedPWMInPercent = (U16)pwm; valvesStatus[ (VALVE_T)valve ].bypassModeStatus.direction = (VALVE_DIRECTION_T)direction; @@ -1533,7 +1577,6 @@ valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasBypassModeBeenRequeseted = TRUE; // This flag is used to check if a change in PWM has been requested so the new PWM is processed and set valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasChangeBeenRequested = TRUE; - result = TRUE; } } @@ -1547,25 +1590,122 @@ * control mode. * @details Inputs: valvesStatus * @details Outputs: valvesStatus - * @param valve that its data publish will be overridden + * @param valve that its PWM override will be reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetValvePWMOverride( U32 valve ) { BOOL result = FALSE; // Check if the valve is in the range of the valves available - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { // Turn off the bypass mode request and the change request valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasBypassModeBeenRequeseted = FALSE; valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasChangeBeenRequested = FALSE; + result = TRUE; + } + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValvesCurrentOverride function overrides the valves' current. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve to override its current + * @param current of the valve that will be overridden + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValvesCurrentOverride( U32 valve, F32 current ) +{ + BOOL result = FALSE; + + // Check if the valve is in the range of the valves available + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].current.override = OVERRIDE_KEY; + valvesStatus[ (VALVE_T)valve ].current.ovData = current; + valvesStatus[ (VALVE_T)valve ].current.ovInitData = valvesStatus[ (VALVE_T)valve ].current.data; result = TRUE; } return result; } + +/*********************************************************************//** + * @brief + * The testResetValvesCurrentOverride function resets the override + * of the valves' current. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve that its current override will be reset + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetValvesCurrentOverride( U32 valve ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].current.override = OVERRIDE_RESET; + valvesStatus[ (VALVE_T)valve ].current.ovData = valvesStatus[ (VALVE_T)valve ].current.ovInitData; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValvesPositionCountOverride function overrides the valves + * position in counts. + * @details Inputs: valvesPositionOverride, valvesStatus + * @details Outputs: valvesPositionOverride + * @param valve to override its position + * @param position of the valve that will be overridden + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValvesPositionCountOverride( U32 valve, U32 count ) +{ + BOOL result = FALSE; + + // Check if the valve is in the range of the valves available + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.override = OVERRIDE_KEY; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovData = (S32)count; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovInitData = valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.data; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetValvesPositionCountOverride function resets the override + * of the valves' position in counts. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve that its position count override will be reset + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetValvesPositionCountOverride( U32 valve ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.override = OVERRIDE_RESET; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovData = valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovInitData; + result = TRUE; + } + + return result; +} + #endif /**@}*/ Index: firmware/App/HDCommon.h =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -81,6 +81,7 @@ #define ALLOW_1_MIN_TREATMENT_DURATION 1 // Allow user to change treatment duration to as low as 1 minute // #define DISABLE_SYRINGE_PUMP_ALARMS 1 // Disable some syringe pump alarms that are triggering intermittently + #include #include #endif Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -169,6 +169,11 @@ break; case POST_STATE_ALARM_AUDIO: +#ifdef DONT_SKIP_NV_POST + // Skip the rest of the POSTs + postState = POST_STATE_COMPLETED; + testStatus = SELF_TEST_STATUS_PASSED; +#endif testStatus = execAlarmAudioSelfTest(); postState = handlePOSTStatus( testStatus ); break; Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -31,6 +31,8 @@ #include "OperationModes.h" #include "SystemComm.h" #include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "Timers.h" #ifdef EMC_TEST_BUILD // TODO - test code #include "FPGA.h" #endif @@ -42,19 +44,30 @@ // ********** private definitions ********** +#define DISINFECTS_DATA_PUB_INTERVAL ( 4 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Disinfects data publish interval in counts. + // ********** private data ********** -static HD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. +static HD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. -static BOOL treatStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of a treatment +static BOOL treatStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of a treatment. +static BOOL flushStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of flush mode. +static BOOL heatDisinfectStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of heat disinfect mode. +static BOOL chemDisinfectStartReqReceived = FALSE; ///< Flag indicates user has requested initiation of chemical disinfect mode. +static U32 dataPublishCounter = 0; ///< Disinfects data publish counter. +static BOOL hasDisinfectCmdBeenSet = FALSE; ///< Flag indicates that a disinfect command has been set. +static DG_DISINFECT_STATE_T dgDisinfectState; ///< DG disinfect state to be boadcast to UI. // ********** private function prototypes ********** -static HD_STANDBY_STATE_T handleStandbyWait4TreatmentState( void ); -static HD_STANDBY_STATE_T handleStandbyDGFlushState( void ); -static HD_STANDBY_STATE_T handleStandbyDGHeatDisinfectState( void ); -static HD_STANDBY_STATE_T handleStandbyDGChemDisinfectState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ); +static HD_STANDBY_STATE_T handleStandbyModeWaitForDisinfectState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGFlushInProgressState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGHeatDisinfectInProgressState( void ); +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ); +static void publishDisinfectData( void ); + /*********************************************************************//** * @brief * The initStandbyMode function initializes the Standby Mode module. @@ -64,8 +77,12 @@ *************************************************************************/ void initStandbyMode( void ) { - currentStandbyState = STANDBY_START_STATE; - treatStartReqReceived = FALSE; + currentStandbyState = STANDBY_START_STATE; + treatStartReqReceived = FALSE; + flushStartReqReceived = FALSE; + dataPublishCounter = 0; + hasDisinfectCmdBeenSet = FALSE; + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; } /*********************************************************************//** @@ -123,20 +140,28 @@ break; case STANDBY_WAIT_FOR_TREATMENT_STATE: - currentStandbyState = handleStandbyWait4TreatmentState(); + currentStandbyState = handleStandbyModeWaitForTreatmentState(); break; + case STANDBY_WAIT_FOR_DISINFECT_STATE: + currentStandbyState = handleStandbyModeWaitForDisinfectState(); + break; + case STANDBY_DG_FLUSH_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGFlushInProgressState(); break; case STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGHeatDisinfectInProgressState(); break; case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: + currentStandbyState = handleStandbyModeDGChemDisininfectInProgressState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); + currentStandbyState = STANDBY_START_STATE; break; } #else @@ -369,4 +394,326 @@ // Alarm actions not handled in Standby mode } +/*********************************************************************//** + * @brief + * The signalUserInitiateFlushMode function handles user initiation of flush + * mode. + * @details Inputs: currentStandbyState + * @details Outputs: flushStartReqReceived + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateFlushMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( ( MODE_STAN == getCurrentOperationMode() ) && ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + flushStartReqReceived = TRUE; + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalUserInitiateFlushMode function handles user initiation of heat + * disinfect mode. + * @details Inputs: currentStandbyState + * @details Outputs: heatDisinfectStartReqReceived + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateHeatDisinfectMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( ( MODE_STAN == getCurrentOperationMode() ) && ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + heatDisinfectStartReqReceived = TRUE; + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalUserInitiateChemicalDisinfectMode function handles user + * initiation of chemical disinfect mode. + * @details Inputs: currentStandbyState + * @details Outputs: chemDisinfectStartReqReceived + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalUserInitiateChemicalDisinfectMode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( ( MODE_STAN == getCurrentOperationMode() ) && ( STANDBY_WAIT_FOR_DISINFECT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + chemDisinfectStartReqReceived = TRUE; + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalInitiateStandbyDisinfectSubmode function handles user + * initiation of setting the disinfects submode. + * @details Inputs: currentStandbyState + * @details Outputs: currentStandbyState + * @return TRUE if signal accepted, FALSE if not + *************************************************************************/ +BOOL signalInitiateStandbyDisinfectSubmode( void ) +{ + BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + + if ( ( MODE_STAN == getCurrentOperationMode() ) && ( STANDBY_WAIT_FOR_TREATMENT_STATE == currentStandbyState ) ) + { + if ( TRUE == isDGCommunicating() ) + { + currentStandbyState = STANDBY_WAIT_FOR_DISINFECT_STATE; + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_DG_COMM_LOST; + } + } + + sendDisinfectConfirmResponse( result, rejReason ); + + return result; +} + +// ********** private functions ********** + +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForTreatmentState function handles wait for + * treatment state. + * @details Inputs: treatStartReqReceived + * @details Outputs: treatStartReqReceived + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForTreatmentState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; + + if ( TRUE == treatStartReqReceived ) + { + // Initialize treatment modes before starting a new treatment + initTreatParamsMode(); + initPreTreatmentMode(); + initTreatmentMode(); + initPostTreatmentMode(); + // Start treatment workflow with treatment parameters mode + requestNewOperationMode( MODE_TPAR ); + treatStartReqReceived = FALSE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeWaitForDisinfectState function handles wait for + * disinfect state. + * @details Inputs: flushStartReqReceived, heatDisinfectStartReqReceived, + * chemDisinfectStartReqReceived, hasDisinfectCmdBeenSet + * @details Outputs: flushStartReqReceived, heatDisinfectStartReqReceived, + * chemDisinfectStartReqReceived, hasDisinfectCmdBeenSet, dgDisinfectState, + * currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeWaitForDisinfectState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DISINFECT_STATE; + + if ( TRUE == flushStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGFlush(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_FLUS == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + dgDisinfectState = DG_DISINFECT_FLUSH_STATE; + currentStandbyState = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + } + } + else if ( TRUE == heatDisinfectStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGHeatDisinfect(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_HEAT == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + dgDisinfectState = DG_DISINFECT_HEAT_STATE; + currentStandbyState = STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE; + } + } + else if ( TRUE == chemDisinfectStartReqReceived ) + { + if ( FALSE == hasDisinfectCmdBeenSet ) + { + cmdStartDGChemicalDisinfect(); + hasDisinfectCmdBeenSet = TRUE; + } + else if ( DG_MODE_CHEM == getDGOpMode() ) + { + hasDisinfectCmdBeenSet = FALSE; + dgDisinfectState = DG_DISINFECT_CHEM_STATE; + currentStandbyState = STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGFlushInProgressState function handles DG flush + * in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGFlushInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_FLUSH_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_FLUS ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGHeatDisinfectInProgressState function handles DG + * heat disinfect in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGHeatDisinfectInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_HEAT ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief + * The handleStandbyModeDGChemDisininfectInProgressState function handles + * DG chemical disinfect in progress state. + * @details Inputs: none + * @details Outputs: dgDisinfectState, currentStandbyState + * @return next state of the standby mode state machine + *************************************************************************/ +static HD_STANDBY_STATE_T handleStandbyModeDGChemDisininfectInProgressState( void ) +{ + HD_STANDBY_STATE_T state = STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE; + + if ( getDGOpMode() != DG_MODE_CHEM ) + { + dgDisinfectState = DG_DISINFECT_NOT_RUNNING_STATE; + currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; + } + publishDisinfectData(); + + return state; +} + +/*********************************************************************//** + * @brief + * The publishDisinfectData function publishes disinfects data at + * the set interval. + * @details Inputs: dataPublishCounter + * @details Outputs: dataPublishCounter + * @return: none + *************************************************************************/ +static void publishDisinfectData( void ) +{ + if ( ++dataPublishCounter > DISINFECTS_DATA_PUB_INTERVAL ) + { + DG_DISINFECT_UI_STATES_T state = getDGDisinfectsStates(); + DISINFECTS_DATA_T data; + + switch( currentStandbyState ) + { + case STANDBY_DG_FLUSH_IN_PROGRESS_STATE: + data.disinfectDGState = state.flushUIState; + break; + + case STANDBY_DG_HEAT_DISINFECT_IN_PROGRESS_STATE: + data.disinfectDGState = state.heatDisinfectUIState; + break; + + case STANDBY_DG_CHEM_DISINFECT_IN_PROGRESS_STATE: + data.disinfectDGState = state.chemDisinfectUIState; + break; + } + + data.disinfectSubModeHDState = (U32)dgDisinfectState; + + broadcastDisinfectsData( &data ); + + dataPublishCounter = 0; + } +} + /**@}*/ Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -141,7 +141,7 @@ U16 alarmsFlags; ///< Bit flags: 1 = true, 0 = false for each bit flag } ALARM_COMP_STATUS_PAYLOAD_T; #pragma pack(pop) - + // ********** public function prototypes ********** void initAlarmMgmt( void ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -1080,8 +1080,8 @@ { U16 msgID; - memcpy( &msgID, (U08*)&pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); + memcpy( &msgID, (U08*)&pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); pendingAckList[ i ].used = FALSE; // Take pending message off of list } } @@ -1271,10 +1271,30 @@ handleUITreatmentLogDataRequest( message ); break; + case MSG_ID_UI_DISINFECT_REQUEST: + handleUIDisinfectRequest( message ); + break; + case MSG_ID_DG_COMMAND_RESPONSE: handleDGCmdResp( message ); break; + case MSG_ID_DG_FLUSH_DATA: + handleFlushUIStateReadingFromDG( message ); + break; + + case MSG_ID_DG_HEAT_DISINFECT_DATA: + handleHeatDisinfectUIStateReadingFromDG( message ); + break; + + case MSG_ID_DG_CHEM_DISINFECT_DATA: + handleChemDisinfectUIStateReadingFromDG( message ); + break; + + case MSG_ID_HD_SET_CALIBRATION_RECORD: + handleSetHDCalibrationRecord( message ); + break; + case MSG_ID_UI_HD_SET_RTC_REQUEST: handleUIClockSyncRequest( message ); break; @@ -1291,6 +1311,11 @@ handleUIActiveAlarmsListRequest( message ); break; + case MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_REQUEST: + handleSetHDStandbyDisinfectSubmodeRequest( message ); + break; + + // NOTE: this always must be the last case case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); break; @@ -1599,6 +1624,14 @@ handleTestSyringePumpMeasuredVolumeOverrideRequest( message ); break; + case MSG_ID_HD_VALVES_CURRENT_OVERRIDE: + handleTestValvesCurrentOverrideRequest( message ); + break; + + case MSD_ID_HD_VALVES_POSITION_COUNT_OVERRIDE: + handleTestValvesPositionCountOverrideRequest( message ); + break; + case MSG_ID_HD_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE: handleTestMonitoredVoltagesSendIntervalOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -707,6 +707,150 @@ } /*********************************************************************//** + * @brief + * The handleUIDisinfectRequest function handles a disinfect/flush 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 handleUIDisinfectRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( message->hdr.payloadLen == sizeof(U32) ) + { + U32 cmd; + + memcpy( &cmd, message->payload, sizeof(U32) ); + + if ( 0 == cmd ) // Command 0 = Flush + { + result = signalUserInitiateFlushMode(); + } + else if ( 1 == cmd ) // Command 1 = Heat disinfect + { + result = signalUserInitiateHeatDisinfectMode(); + } + else if ( 2 == cmd ) // Command 2 = chemical disinfect + { + result = signalUserInitiateChemicalDisinfectMode(); + } + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** + * @brief + * The sendDisinfectConfirmResponse function constructs a disinfect or flush + * confirm user action response to the UI and queues the msg for + * transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Disposable removal confirm response msg constructed + * and queued. + * @param accepted T/F - was disinfect or flush confirm request accepted? + * @param reason reason why request was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDisinfectConfirmResponse( BOOL accepted, U32 reason ) +{ + return sendUIResponseMsg( MSG_ID_HD_DISINFECT_RESPONSE, accepted, reason ); +} + +/*********************************************************************//** + * @brief + * The handleSetHDStandbyDisinfectSubmode function handles setting the + * standby submode to wait for disisnfect state. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleSetHDStandbyDisinfectSubmodeRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // The payload should be 0 in this case because there is mode in this command + if ( 0 == message->hdr.payloadLen ) + { + signalInitiateStandbyDisinfectSubmode(); + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, result ); +} + +/*********************************************************************//** + * @brief + * The handleSetHDStandbyDisinfectSubmodeResponse function constructs a + * standby submode change to wait for disinfect confirm user action response + * to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Disposable removal confirm response msg constructed + * and queued. + * @param accepted T/F - was set standby submode confirm request accepted? + * @param reason reason why request was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL handleSetHDStandbyDisinfectSubmodeResponse( BOOL accepted, U32 reason ) +{ + return sendUIResponseMsg( MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_RESPONSE, accepted, reason ); +} + +/*********************************************************************//** + * @brief + * The handleFlushUIStateReadingFromDG function handles the readings of DG + * flush mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleFlushUIStateReadingFromDG( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(MODE_FLUSH_DATA_T) ) + { + MODE_FLUSH_DATA_T payload; + DG_DISINFECT_UI_STATES_T uiStates; + + memcpy( &payload, message->payload, sizeof(MODE_FLUSH_DATA_T) ); + + uiStates.heatDisinfectUIState = 0; + uiStates.chemDisinfectUIState = 0; + uiStates.flushUIState = payload.flushUIState; + + setDGDisinfectsStates( uiStates ); + } +} + +/*********************************************************************//** + * @brief + * The handleHeatDisinfectUIStateReadingFromDG function handles the readings + * of DG heat disinfect mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleHeatDisinfectUIStateReadingFromDG( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(MODE_HEAT_DISINFECT_DATA_T) ) + { + MODE_HEAT_DISINFECT_DATA_T payload; + DG_DISINFECT_UI_STATES_T uiStates; + + memcpy( &payload, message->payload, sizeof(MODE_HEAT_DISINFECT_DATA_T) ); + + uiStates.heatDisinfectUIState = payload.heatDisinfectUIState; + uiStates.chemDisinfectUIState = 0; + uiStates.flushUIState = 0; + + setDGDisinfectsStates( uiStates ); + } +} + +/*********************************************************************//**  * @brief  * The handleUIActiveAlarmsListRequest function handles UI active alarms list request.  * @details Inputs: none @@ -728,7 +872,32 @@ /*********************************************************************//** * @brief - * The sendTreatmentLogData function constructs a treatment log data message + * The handleChemDisinfectUIStateReadingFromDG function handles the readings + * of DG chemical disinfect mode. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChemDisinfectUIStateReadingFromDG( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(MODE_CHEMICAL_DISINFECT_DATA_T) ) + { + MODE_CHEMICAL_DISINFECT_DATA_T payload; + DG_DISINFECT_UI_STATES_T uiStates; + + memcpy( &payload, message->payload, sizeof(MODE_CHEMICAL_DISINFECT_DATA_T) ); + + uiStates.heatDisinfectUIState = 0; + uiStates.chemDisinfectUIState = payload.chemDisinfectUIState; + uiStates.flushUIState = 0; + + setDGDisinfectsStates( uiStates ); + } +} + +/*********************************************************************//** + * The sendActiveAlarmsList function constructs a treatment log data message * for UI and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none * @details Outputs: Treatment log data msg constructed and queued. @@ -1333,6 +1502,92 @@ /*********************************************************************//** * @brief + * The sendDGStartFlushModeCommand function constructs a DG start/stop + * flush mode command message and queues the msg for transmit on the + * appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG start flush mode command msg constructed and queued. + * @param start TRUE indicates start flush mode + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGStartFlushModeCommand( BOOL start ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_START_STOP_FLUSH; + msg.hdr.payloadLen = sizeof( BOOL ); + + memcpy( msg.payload, &start, sizeof( BOOL ) ); + + // 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_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGStartHeatDisinfectModeCommand function constructs a DG start/stop + * heat disinfect mode command message and queues the msg for transmit on + * the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG start heat disinfect mode command msg constructed + * and queued. + * @param start TRUE indicates start heat disinfect mode + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGStartHeatDisinfectModeCommand( BOOL start ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_START_STOP_HEAT_DISINFECT; + msg.hdr.payloadLen = sizeof( BOOL ); + + memcpy( msg.payload, &start, sizeof( BOOL ) ); + + // 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_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The sendDGStartChemicalDisinfectModeCommand function constructs a DG + * start/stop chemical disinfect mode command message and queues the msg + * for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG start chemical disinfect mode command msg + * constructed and queued. + * @param start TRUE indicates start chemical disinfect mode + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGStartChemicalDisinfectModeCommand( BOOL start ) +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_START_STOP_CHEM_DISINFECT; + msg.hdr.payloadLen = sizeof( BOOL ); + + memcpy( msg.payload, &start, sizeof( BOOL ) ); + + // 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_DG, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The broadcastAccelData function constructs an accelerometer data msg to * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -2451,6 +2706,33 @@ return result; } +/*********************************************************************//** + * @brief + * The broadcastDisinfectsData function sends out the disinfects data. + * @details Inputs: none + * @details Outputs: disinfects data msg constructed and queued + * @param disinfectsData which is disinfects msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastDisinfectsData( DISINFECTS_DATA_T *disinfectsData ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_STANDBY_STATE; + msg.hdr.payloadLen = sizeof( DISINFECTS_DATA_T ); + + memcpy( payloadPtr, disinfectsData, sizeof( DISINFECTS_DATA_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; +} + #ifdef EMC_TEST_BUILD BOOL broadcastCANErrorCount( U32 count ) { @@ -5344,13 +5626,13 @@ *************************************************************************/ void handleSetFluidLeakStateOverrideRequest( MESSAGE_T *message ) { - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + TEST_OVERRIDE_PAYLOAD_T payload; BOOL result = FALSE; // Verify payload length - if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { - memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); if ( FALSE == payload.reset ) { result = testSetFluidLeakStateOverride( ( FLUID_LEAK_STATES_T)( payload.state.u32 ) ); @@ -6117,13 +6399,46 @@ /*********************************************************************//** * @brief - * The handleTestMonitoredVoltagesSendIntervalOverrideRequest function handles a - * request to override the monitored HD voltages data publication interval. + * The handleTestValvesCurrentOverrideRequest function handles a + * request to override HD valves' current. * @details Inputs: none * @details Outputs: message handled * @param message : a pointer to the message to handle * @return none *************************************************************************/ +void handleTestValvesCurrentOverrideRequest( 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 = testSetValvesCurrentOverride( payload.index, payload.state.f32 ); + } + else + { + result = testResetValvesCurrentOverride( payload.index ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestMonitoredVoltagesSendIntervalOverrideRequest function + * handles a request to override the monitored HD voltages data + * publication interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ void handleTestMonitoredVoltagesSendIntervalOverrideRequest( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; @@ -6149,6 +6464,38 @@ /*********************************************************************//** * @brief + * The handleTestValvesPositionCountOverrideRequest function handles a + * request to override HD valves' position in counts. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestValvesPositionCountOverrideRequest( 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 = testSetValvesPositionCountOverride( payload.index, payload.state.u32 ); + } + else + { + result = testResetValvesPositionCountOverride( payload.index ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestMonitoredVoltageOverrideRequest function handles a * request to override the monitored HD voltage override. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r5e650bc96230e209560abfe290f1ec93e1667d82 -rab57180655892575252175a4310d97a1c8c46e74 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 5e650bc96230e209560abfe290f1ec93e1667d82) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision ab57180655892575252175a4310d97a1c8c46e74) @@ -37,6 +37,7 @@ #include "NVDataMgmt.h" #include "PresOccl.h" #include "Rinseback.h" +#include "ModeStandby.h" #include "SyringePump.h" #include "Valves.h" #include "Voltages.h" @@ -268,6 +269,27 @@ // MSG_ID_HD_TREATMENT_LOG_DATA_RESPONSE BOOL sendTreatmentLogData( BOOL accepted, U32 reason, TREATMENT_LOG_DATA_PAYLOAD_T *logDataPtr ); +// MSG_ID_UI_DISINFECT_REQUEST +void handleUIDisinfectRequest( MESSAGE_T *message ); + +// MSG_ID_HD_DISINFECT_RESPONSE +BOOL sendDisinfectConfirmResponse( BOOL accepted, U32 reason ); + +// MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_REQUEST +void handleSetHDStandbyDisinfectSubmodeRequest( MESSAGE_T *message ); + +// MSG_ID_HD_SET_STANDBY_DISINFECT_SUB_MODE_RESPONSE +BOOL handleSetHDStandbyDisinfectSubmodeResponse( BOOL accepted, U32 reason ); + +// MSG_ID_DG_FLUSH_DATA +void handleFlushUIStateReadingFromDG( MESSAGE_T *message ); + +// MSG_ID_DG_HEAT_DISINFECT_DATA +void handleHeatDisinfectUIStateReadingFromDG( MESSAGE_T *message ); + +// MSG_ID_DG_CHEM_DISINFECT_DATA +void handleChemDisinfectUIStateReadingFromDG( MESSAGE_T *message ); + // MSG_ID_UI_ACTIVE_ALARMS_LIST_REQUEST void handleUIActiveAlarmsListRequest( MESSAGE_T *message ); @@ -309,6 +331,15 @@ // MSG_ID_DG_OP_MODE void handleDGOpMode( MESSAGE_T *message ); +// MSG_ID_DG_START_STOP_FLUSH +BOOL sendDGStartFlushModeCommand( BOOL start ); + +// MSG_ID_DG_START_STOP_HEAT_DISINFECT +BOOL sendDGStartHeatDisinfectModeCommand( BOOL start ); + +// MSG_ID_DG_START_STOP_CHEM_DISINFECT +BOOL sendDGStartChemicalDisinfectModeCommand( BOOL start ); + // *********** public data broad cast functions ********** // MSG_ID_HD_ACCELEROMETER_DATA @@ -419,6 +450,9 @@ // MSG_ID_Hd_SEND_SERVICE_RECORD BOOL sendHDServiceRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ); +// MSG_ID_HD_STANDBY_STATE +BOOL broadcastDisinfectsData( DISINFECTS_DATA_T *disinfectsData ); + #ifdef EMC_TEST_BUILD // MSG_ID_CAN_ERROR_COUNT BOOL broadcastCANErrorCount( U32 count ); @@ -677,6 +711,12 @@ // MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE: void handleTestSyringePumpMeasuredVolumeOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_VALVES_CURRENT_OVERRIDE +void handleTestValvesCurrentOverrideRequest( MESSAGE_T *message ); + +// MSD_ID_HD_VALVES_POSITION_COUNT_OVERRIDE +void handleTestValvesPositionCountOverrideRequest( MESSAGE_T *message ); + // MSG_ID_HD_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE void handleTestMonitoredVoltagesSendIntervalOverrideRequest( MESSAGE_T *message );