Index: firmware/App/Controllers/BloodLeak.h =================================================================== diff -u -r242ad36c7a1ec4ee5012c9f009899f9e0bd87628 -ra06953d0fc210dd9157388c27120e2225c898a37 --- firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 242ad36c7a1ec4ee5012c9f009899f9e0bd87628) +++ firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision a06953d0fc210dd9157388c27120e2225c898a37) @@ -63,7 +63,7 @@ SELF_TEST_STATUS_T execBloodLeakSelfTest( void ); BLOOD_LEAK_STATUS_T getBloodLeakStatus( void ); -SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ); +SELF_TEST_STATUS_T getBloodLeakSelfTestStatus( void ); BOOL testSetBloodLeakDataPublishIntervalOverride( U32 value ); BOOL testResetBloodLeakDataPublishIntervalOverride( void ); Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -rd089b3bd30b565fb264817b6df70e083d8a9ec46 -ra06953d0fc210dd9157388c27120e2225c898a37 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision d089b3bd30b565fb264817b6df70e083d8a9ec46) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision a06953d0fc210dd9157388c27120e2225c898a37) @@ -7,38 +7,39 @@ * * @file DGInterface.c * -* @author (last) Dara Navaei -* @date (last) 15-Jul-2022 +* @author (last) Michael Garthwaite +* @date (last) 08-Aug-2022 * * @author (original) Sean * @date (original) 08-Apr-2020 * ***************************************************************************/ #include // To check for NaN - + #include "DialInFlow.h" #include "Dialysis.h" -#include "DGDefs.h" +#include "DGDefs.h" #include "DGInterface.h" #include "ModeInitPOST.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "PersistentAlarm.h" -#include "SystemCommMessages.h" -#include "Timers.h" - -/** - * @addtogroup DGInterface - * @{ - */ - -// ********** private definitions ********** - -#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. -#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. +#include "SystemComm.h" +#include "SystemCommMessages.h" +#include "Timers.h" +/** + * @addtogroup DGInterface + * @{ + */ + +// ********** private definitions ********** + +#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. +#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. + #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. #define DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C 2.0F ///< Dialysate temperature out of target tolerance C. @@ -47,9 +48,15 @@ #define DIALYSATE_TEMP_HIGH_SAFETY_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Dialysate temperature high safety timeout in milliseconds. #define DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C 42.0F ///< Dialysate low safety temperature limit in C. #define DIALYSATE_TEMP_LOW_SAFETY_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Dialysate temperature low safety timeout in milliseconds. +#define DG_DATA_FRESHNESS_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< DG data freshness timeout (in ms). // ********** private data ********** +static const U32 DIP_LOAD_CELL_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_TEMPERATURE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_RESERVOIRS_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); +static const U32 DIP_DG_OP_MODE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); + // DG status static DG_OP_MODE_T dgCurrentOpMode; ///< Current DG operation mode. static U32 dgSubMode; ///< Current state (sub-mode) of current DG operation mode. @@ -61,7 +68,7 @@ static U32 timeStartMS = 0; // TODO is this needed? // DG sensor data -static F32 dgDialysateTemp; ///< Dialysate temperature reported by the DG. +static F32 dgDialysateTemp; ///< Dialysate temperature reported by the DG. static F32 dgRedundantDialysateTemp = 0.0; ///< Redundant dialysate temperature reported by the DG. static F32 dgPrimaryTemp = 0.0; ///< Latest RO water temperature reported by the DG. static F32 dgTrimmerTempSet; ///< Trimmer heater target temperature commanded. @@ -72,7 +79,7 @@ /// Filtered (32 sample) weight of reservoirs. static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; static F32 lgFilteredReservoirBackupWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; - + // Load cell filtering data static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; ///< Holds load cell samples for large load cell moving average. static U32 lgLoadCellReadingsIdx = 0; ///< Index for next sample in large load cell rolling average sample array. @@ -81,18 +88,22 @@ static F32 lgLoadCellBackupReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc large load cell moving average. // DG Dialysate flow rate -static F32 dgDialysateFlowRateMlMin; ///< Latest dialysate flow rate reported by the DG. -static BOOL dgDialysateFlowDataFreshFlag; ///< Flag to signal the execDialInFlowMonitor() to process fresh flow rate data +static F32 dgDialysateFlowRateMlMin = 0.0; ///< Latest dialysate flow rate reported by the DG. +static BOOL dgDialysateFlowDataFreshFlag = FALSE; ///< Flag to signal the execDialInFlowMonitor() to process fresh flow rate data +static BOOL dgLoadCellDataFreshFlag = FALSE; ///< Flag to signal the handleLoadCellReadingsFromDG() to process fresh load cell data +static BOOL dgDialysateTemperatureDataFreshFlag = FALSE; ///< Flag to signal the handleTemperatureReadingsFromDG() to process fresh temperature data +static BOOL dgReservoirsDataFreshFlag = FALSE; ///< Flag to signal the handleDGReservoirData() to process fresh reservoirs data +static BOOL dgOpModeDataFreshFlag = FALSE; ///< Flag to signal the handleDGOpMode() to process fresh dg op mode data // Reservoir data static DG_RESERVOIR_ID_T dgActiveReservoir; ///< Latest active reservoir reported by the DG. static DG_RESERVOIR_ID_T dgActiveReservoirSet; ///< Active reservoir commanded. // TODO remove below variables -static U32 dgReservoirFillVolumeTarget = 0; ///< Latest fill-to volume reported by the DG. -static U32 dgReservoirFillVolumeTargetSet = 0; ///< Fill-to volume commanded. -static U32 dgReservoirDrainVolumeTarget = 0; ///< Latest drain-to volume reported by the DG. -static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. +static U32 dgReservoirFillVolumeTarget = 0; ///< Latest fill-to volume reported by the DG. +static U32 dgReservoirFillVolumeTargetSet = 0; ///< Fill-to volume commanded. +static U32 dgReservoirDrainVolumeTarget = 0; ///< Latest drain-to volume reported by the DG. +static U32 dgReservoirDrainVolumeTargetSet = 0; ///< Drain-to volume commanded. static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. static DG_MIXING_RATIOS_T dgMixingRatios; ///< DG mixing ratios. @@ -101,21 +112,21 @@ // DG command response static DG_CMD_RESPONSE_T dgCmdResp[ NUM_OF_DG_COMMANDS ]; ///< Keep the latest DG command response for each command. - -// ********** private function prototypes ********** +// ********** private function prototypes ********** + static void checkDGRestart( void ); static void checkDGTrimmerHeaterStatus( void ); -/*********************************************************************//** - * @brief - * The initDGInterface function initializes the DGInterface module. - * @details Inputs: none - * @details Outputs: DGInterface module initialized. - * @return none - *************************************************************************/ -void initDGInterface( void ) -{ +/*********************************************************************//** + * @brief + * The initDGInterface function initializes the DGInterface module. + * @details Inputs: none + * @details Outputs: DGInterface module initialized. + * @return none + *************************************************************************/ +void initDGInterface( void ) +{ U32 i, j; dgStarted = FALSE; @@ -171,8 +182,43 @@ initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS, DIALYSATE_TEMP_OUT_OF_TARGET_TIMEOUT_MS ); + + initPersistentAlarm( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE, DG_DATA_FRESHNESS_TIMEOUT_MS, DG_DATA_FRESHNESS_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_DIALYSATE_TEMPERATURE_DATA_MESSAGE_NOT_RECEIVE, DG_DATA_FRESHNESS_TIMEOUT_MS, DG_DATA_FRESHNESS_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE, DG_DATA_FRESHNESS_TIMEOUT_MS, DG_DATA_FRESHNESS_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE, DG_DATA_FRESHNESS_TIMEOUT_MS, DG_DATA_FRESHNESS_TIMEOUT_MS ); } - + +/**********************************************************************//** + * @brief + * The checkDGDataFreshness function checks the condition + * for triggering an alarm if the DG fresh data is not received for 2 seconds. + * @details Inputs: none + * @details Outputs: an alarm is triggered or an alarm condition is cleared + * @param alarm ID of alarm to check + * @param flag to signal the fresh data processing + * @return None + *************************************************************************/ +void checkDGDataFreshness( ALARM_ID_T alarmID, BOOL *dgFreshDataFlag ) +{ + if ( TRUE == *dgFreshDataFlag ) + { + *dgFreshDataFlag = FALSE; + checkPersistentAlarm( alarmID, FALSE, 0.0, 0.0 ); + } + else + { // Alarm if not receiving DG fresh data message in timely manner + if ( TRUE == isDGCommunicating() ) + { + checkPersistentAlarm( alarmID, TRUE, 0.0, 0.0 ); + } + else + { + checkPersistentAlarm( alarmID, FALSE, 0.0, 0.0 ); + } + } +} + /*********************************************************************//** * @brief * The execDGInterfaceMonitor function executes the DG Interface monitoring @@ -183,9 +229,20 @@ *************************************************************************/ void execDGInterfaceMonitor( void ) { - // TODO - make sure DG sensor/state data is coming in timely manner (e.g. load cells s/b every 100 ms) + // Trigger alarm if not receiving new load cell data message in timely manner + /*checkDGDataFreshness( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE, &dgLoadCellDataFreshFlag ); - // Check to see if DG has restarted + // Trigger alarm if not receiving new dialysate temperature data message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_DIALYSATE_TEMPERATURE_DATA_MESSAGE_NOT_RECEIVE, &dgDialysateTemperatureDataFreshFlag ); + + // Trigger alarm if not receiving new reservoirs data message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE, &dgReservoirsDataFreshFlag ); + + // Trigger alarm if not receiving new DG op mode message in timely manner + checkDGDataFreshness( ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE, &dgOpModeDataFreshFlag ); + + // Check to see if DG has restarted*/ + checkDGRestart(); // Check the status of the trimmer heater @@ -203,46 +260,46 @@ void dialysisResumed( void ) { timeStartMS = getMSTimerCount(); -} - -/*********************************************************************//** - * @brief - * The getDGOpMode function gets the current DG operating mode. - * @details Inputs: dgCurrentOpMode - * @details Outputs: none - * @return Current DG operating mode. - *************************************************************************/ -DG_OP_MODE_T getDGOpMode( void ) -{ - return dgCurrentOpMode; -} - -/*********************************************************************//** - * @brief - * The getDGSubMode function gets the current DG operating sub-mode. - * @details Inputs: dgSubMode - * @details Outputs: none - * @return Current DG operating sub-mode. - *************************************************************************/ -U32 getDGSubMode( void ) -{ - return dgSubMode; -} - -/*********************************************************************//** - * @brief - * The getDGActiveReservoir function gets the current active reservoir. - * @details Inputs: dgActiveReservoirSet - * @details Outputs: none - * @return Currently commanded active reservoir. - *************************************************************************/ -DG_RESERVOIR_ID_T getDGActiveReservoir( void ) -{ - return dgActiveReservoirSet; } /*********************************************************************//** * @brief + * The getDGOpMode function gets the current DG operating mode. + * @details Inputs: dgCurrentOpMode + * @details Outputs: none + * @return Current DG operating mode. + *************************************************************************/ +DG_OP_MODE_T getDGOpMode( void ) +{ + return dgCurrentOpMode; +} + +/*********************************************************************//** + * @brief + * The getDGSubMode function gets the current DG operating sub-mode. + * @details Inputs: dgSubMode + * @details Outputs: none + * @return Current DG operating sub-mode. + *************************************************************************/ +U32 getDGSubMode( void ) +{ + return dgSubMode; +} + +/*********************************************************************//** + * @brief + * The getDGActiveReservoir function gets the current active reservoir. + * @details Inputs: dgActiveReservoirSet + * @details Outputs: none + * @return Currently commanded active reservoir. + *************************************************************************/ +DG_RESERVOIR_ID_T getDGActiveReservoir( void ) +{ + return dgActiveReservoirSet; +} + +/*********************************************************************//** + * @brief * The getDGInactiveReservoir function gets the currently inactive reservoir. * @details Inputs: dgActiveReservoirSet * @details Outputs: none @@ -253,7 +310,7 @@ DG_RESERVOIR_ID_T inactiveRes = ( DG_RESERVOIR_2 == dgActiveReservoirSet ? DG_RESERVOIR_1 : DG_RESERVOIR_2 ); return inactiveRes; -} +} /*********************************************************************//** * @brief @@ -267,7 +324,7 @@ { return ( dgActiveReservoir == dgActiveReservoirSet ); } - + /*********************************************************************//** * @brief * The getDGDialysateFlowRateLMin function gets the latest dialysate flow @@ -281,7 +338,7 @@ F32 result = dgDialysateFlowRateMlMin; return result; -} +} /*********************************************************************//** * @brief @@ -299,7 +356,7 @@ return result; } - + /*********************************************************************//** * @brief * The getLoadCellWeight function gets the current load cell weight. @@ -391,26 +448,26 @@ /*********************************************************************//** * @brief - * The getDialysateTemperature function gets the latest dialysate temperature. - * @details Inputs: dgDialysateTemp + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none * @details Outputs: none - * @return the current dialysate temperature + * @return the current DG disinfects readings *************************************************************************/ -F32 getDialysateTemperature( void ) +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) { - return dgDialysateTemp; + return disinfectsStatus; } /*********************************************************************//** * @brief - * The getDGDisinfectsStates function returns the DG disinfects readings. - * @details Inputs: none + * The getDialysateTemperature function gets the latest dialysate temperature. + * @details Inputs: dgDialysateTemp * @details Outputs: none - * @return the current DG disinfects readings + * @return the current dialysate temperature *************************************************************************/ -DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +F32 getDialysateTemperature( void ) { - return disinfectsStatus; + return dgDialysateTemp; } /*********************************************************************//** @@ -441,72 +498,78 @@ memcpy( data, &dgServiceAndUsageData, sizeof( DG_SERVICE_AND_USAGE_DATA_T ) ); } -/*********************************************************************//** - * @brief - * The setDGOpMode function sets the latest DG operating mode reported by - * the DG. - * @details Inputs: none - * @details Outputs: dgCurrentOpMode, dgSubMode - * @param opMode operating mode reported by DG - * @param subMode sub-mode (current state) of operating mode reported by DG - * @return none - *************************************************************************/ -void setDGOpMode( U32 opMode, U32 subMode ) -{ - if ( opMode < NUM_OF_DG_MODES ) - { - dgCurrentOpMode = (DG_OP_MODE_T)opMode; - dgSubMode = subMode; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); - } -} - -/*********************************************************************//** - * @brief - * The setDialysateTemperatureReadings function sets the latest dialysate - * temperatures reported by the DG. - * @details Inputs: none - * @details Outputs: dgDialysateTemp, dgRedundantDialysateTemp - * @param temp1 dialysate temperature reported by DG - * @param temp2 redundant dialysate temperature reported by DG - * @return none - *************************************************************************/ -void setDialysateTemperatureReadings( F32 temp1, F32 temp2 ) -{ - dgDialysateTemp = temp1; - dgRedundantDialysateTemp = temp2; -} - -/*********************************************************************//** - * @brief - * The setDGReservoirsData function sets the latest reservoir data - * reported by the DG. - * @details Inputs: none - * @details Outputs: dgActiveReservoir, dgReservoirFillVolumeTarget, dgReservoirDrainVolumeTarget - * @param resID ID of active reservoir - * @param fillVol Reservoir fill to volume reported by DG - * @param drainVol Reservoir drain to volume reported by DG - * @return none - *************************************************************************/ -void setDGReservoirsData( DG_RESERVOIR_ID_T resID, U32 fillVol, U32 drainVol ) -{ - if ( resID < NUM_OF_DG_RESERVOIRS ) - { - dgActiveReservoir = resID; - dgReservoirFillVolumeTarget = fillVol; - dgReservoirDrainVolumeTarget = drainVol; - } - else +/*********************************************************************//** + * @brief + * The setDGOpMode function sets the latest DG operating mode reported by + * the DG. + * @details Inputs: none + * @details Outputs: dgCurrentOpMode, dgSubMode + * @param opMode operating mode reported by DG + * @param subMode sub-mode (current state) of operating mode reported by DG + * @return none + *************************************************************************/ +void setDGOpMode( U32 opMode, U32 subMode ) +{ + if ( opMode < NUM_OF_DG_MODES ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); - } -} + dgCurrentOpMode = (DG_OP_MODE_T)opMode; + dgSubMode = subMode; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); + } + dgOpModeDataFreshFlag = TRUE; +} + /*********************************************************************//** * @brief + * The setDialysateTemperatureReadings function sets the latest dialysate + * temperatures reported by the DG. + * @details Inputs: none + * @details Outputs: dgDialysateTemp, dgRedundantDialysateTemp + * @param temp1 dialysate temperature reported by DG + * @param temp2 redundant dialysate temperature reported by DG + * @return none + *************************************************************************/ +void setDialysateTemperatureReadings( F32 temp1, F32 temp2 ) +{ + dgDialysateTemp = temp1; + dgRedundantDialysateTemp = temp2; + + dgDialysateTemperatureDataFreshFlag = TRUE; +} + +/*********************************************************************//** + * @brief + * The setDGReservoirsData function sets the latest reservoir data + * reported by the DG. + * @details Inputs: none + * @details Outputs: dgActiveReservoir, dgReservoirFillVolumeTarget, dgReservoirDrainVolumeTarget + * @param resID ID of active reservoir + * @param fillVol Reservoir fill to volume reported by DG + * @param drainVol Reservoir drain to volume reported by DG + * @return none + *************************************************************************/ +void setDGReservoirsData( DG_RESERVOIR_ID_T resID, U32 fillVol, U32 drainVol ) +{ + if ( resID < NUM_OF_DG_RESERVOIRS ) + { + dgActiveReservoir = resID; + dgReservoirFillVolumeTarget = fillVol; + dgReservoirDrainVolumeTarget = drainVol; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); + } + + dgReservoirsDataFreshFlag = TRUE; +} + +/*********************************************************************//** + * @brief * The setDialysateFlowData function sets the latest dialysate flow rate * and its freshness status. The dialysate flow data is reported by the DG. * @details Inputs: none @@ -570,6 +633,8 @@ // Update Dialysis sub-mode with new reservoir volumes updateReservoirVolumes( res1Primary, res2Primary ); + + dgLoadCellDataFreshFlag = TRUE; } /*********************************************************************//** @@ -645,108 +710,108 @@ memcpy( &dgServiceAndUsageData.dgUsageInfo, data, sizeof( HD_VERSION_DG_USAGE_INFO_T ) ); } -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief * The cmdSetDGDialysateHeatingParams function sends the dialysate heating - * parameters to DG. - * @details Inputs: none - * @details Outputs: dgTrimmerTempSet + * parameters to DG. + * @details Inputs: none + * @details Outputs: dgTrimmerTempSet * @param heatingParams Dialysate heating parameters to be sent to DG - * @return none - *************************************************************************/ -void cmdSetDGDialysateHeatingParams( DG_CMD_DIALYSATE_HEATING_PARAMS_T heatingParams ) -{ + * @return none + *************************************************************************/ +void cmdSetDGDialysateHeatingParams( DG_CMD_DIALYSATE_HEATING_PARAMS_T heatingParams ) +{ dgTrimmerTempSet = heatingParams.trimmerTargetTemperature; - // TODO what should we do with the BOOL return of this function? - sendDialysateHeatingParamsToDG( &heatingParams ); -} - -/*********************************************************************//** - * @brief - * The cmdStartDG function sends a start command to the DG. DG will transition - * from standby to recirculate mode and start producing warm, pure water. - * @details Inputs: none - * @details Outputs: start DG command sent - * @return none - *************************************************************************/ -void cmdStartDG( void ) -{ + // TODO what should we do with the BOOL return of this function? + sendDialysateHeatingParamsToDG( &heatingParams ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDG function sends a start command to the DG. DG will transition + * from standby to recirculate mode and start producing warm, pure water. + * @details Inputs: none + * @details Outputs: start DG command sent + * @return none + *************************************************************************/ +void cmdStartDG( void ) +{ dgStartCommandSent = TRUE; - - sendDGStartStopCommand( (BOOL)START_DG_CMD ); -} - -/*********************************************************************//** - * @brief - * The cmdStopDG function sends a stop command to the DG. DG will transition - * from recirculate mode to standby mode. Pumps and heater go off. - * @details Inputs: none - * @details Outputs: stop DG command sent - * @return none - *************************************************************************/ -void cmdStopDG( void ) -{ + + sendDGStartStopCommand( (BOOL)START_DG_CMD ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDG function sends a stop command to the DG. DG will transition + * from recirculate mode to standby mode. Pumps and heater go off. + * @details Inputs: none + * @details Outputs: stop DG command sent + * @return none + *************************************************************************/ +void cmdStopDG( void ) +{ dgStarted = FALSE; - - sendDGStartStopCommand( (BOOL)STOP_DG_CMD ); -} - -/*********************************************************************//** - * @brief - * The cmdStartDGTrimmerHeater function sends a start trimmer heater command - * to the DG. - * @details Inputs: none - * @details Outputs: start DG trimmer heater command sent - * @return none - *************************************************************************/ -void cmdStartDGTrimmerHeater( void ) -{ + + sendDGStartStopCommand( (BOOL)STOP_DG_CMD ); +} + +/*********************************************************************//** + * @brief + * The cmdStartDGTrimmerHeater function sends a start trimmer heater command + * to the DG. + * @details Inputs: none + * @details Outputs: start DG trimmer heater command sent + * @return none + *************************************************************************/ +void cmdStartDGTrimmerHeater( void ) +{ dgTrimmerHeaterOn = TRUE; dgCmdResp[ DG_CMD_START_TRIMMER_HEATER ].commandID = DG_CMD_NONE; - - sendDGStartStopTrimmerHeaterCommand( START_DG_CMD ); -} - -/*********************************************************************//** - * @brief - * The cmdStopDGTrimmerHeater function sends a stop trimmer heater command - * to the DG. - * @details Inputs: none - * @details Outputs: stop DG trimmer heater command sent - * @return none - *************************************************************************/ -void cmdStopDGTrimmerHeater( void ) -{ + + sendDGStartStopTrimmerHeaterCommand( START_DG_CMD ); +} + +/*********************************************************************//** + * @brief + * The cmdStopDGTrimmerHeater function sends a stop trimmer heater command + * to the DG. + * @details Inputs: none + * @details Outputs: stop DG trimmer heater command sent + * @return none + *************************************************************************/ +void cmdStopDGTrimmerHeater( void ) +{ dgTrimmerHeaterOn = FALSE; dgCmdResp[ DG_CMD_STOP_TRIMMER_HEATER ].commandID = DG_CMD_NONE; - sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD ); -} - -/*********************************************************************//** - * @brief - * The cmdSetDGActiveReservoir function sends a set active reservoir command - * message to the DG. - * @details Inputs: none - * @details Outputs: set active reservoir command sent to DG. - * @param resID ID of reservoir to set as active (reservoir for HD to draw from) - * @return none - *************************************************************************/ -void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ) -{ - if ( resID < NUM_OF_DG_RESERVOIRS ) - { + sendDGStartStopTrimmerHeaterCommand( STOP_DG_CMD ); +} + +/*********************************************************************//** + * @brief + * The cmdSetDGActiveReservoir function sends a set active reservoir command + * message to the DG. + * @details Inputs: none + * @details Outputs: set active reservoir command sent to DG. + * @param resID ID of reservoir to set as active (reservoir for HD to draw from) + * @return none + *************************************************************************/ +void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ) +{ + if ( resID < NUM_OF_DG_RESERVOIRS ) + { dgActiveReservoirSet = resID; dgCmdResp[ DG_CMD_SWITCH_RESERVOIR ].commandID = DG_CMD_NONE; - - sendDGSwitchReservoirCommand( (U32)resID ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, (U32)resID ); - } -} + sendDGSwitchReservoirCommand( (U32)resID ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, (U32)resID ); + } +} + /*********************************************************************//** * @brief * The cmdChangeDGValveSetting function sends a change valve setting command @@ -769,24 +834,24 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_VALVE_SETTING_ID, (U32)valveSettingID ); } } - -/*********************************************************************//** - * @brief - * The cmdStartDGFill function sends a fill command message to the DG. - * @details Inputs: none - * @details Outputs: fill command sent to DG. + +/*********************************************************************//** + * @brief + * The cmdStartDGFill function sends a fill command message to the DG. + * @details Inputs: none + * @details Outputs: fill command sent to DG. * @param fillToVolMl volume (in mL) to fill inactive reservoir to - * @param targetFlowLPM target flow rate in L/min - * @return none - *************************************************************************/ -void cmdStartDGFill( U32 fillToVolMl, F32 targetFlowLPM ) + * @param targetFlowLPM target flow rate in L/min + * @return none + *************************************************************************/ +void cmdStartDGFill( U32 fillToVolMl, F32 targetFlowLPM ) { - dgCmdResp[ DG_CMD_START_FILL ].commandID = DG_CMD_NONE; + dgCmdResp[ DG_CMD_START_FILL ].commandID = DG_CMD_NONE; dgReservoirFillVolumeTargetSet = fillToVolMl; - - sendDGFillCommand( DG_CMD_START, fillToVolMl, targetFlowLPM ); -} + sendDGFillCommand( DG_CMD_START, fillToVolMl, targetFlowLPM ); +} + /*********************************************************************//** * @brief * The cmdStopDGFill function sends a fill command with stop parameter message to the DG. @@ -801,45 +866,45 @@ sendDGFillCommand( DG_CMD_STOP, 0, 0 ); } - -/*********************************************************************//** - * @brief - * The cmdStartDGDrain function sends a drain command message to the DG. - * @details Inputs: none + +/*********************************************************************//** + * @brief + * The cmdStartDGDrain function sends a drain command message to the DG. + * @details Inputs: none * @details Outputs: drain command sent to DG. * @param drainToVolMl volume (in mL) to drain inactive reservoir to * @param tareLoadCell flag to tell DG tare load cell or not - * @param start flag to tell DG to start or stop the drain mode - * @return none - *************************************************************************/ -void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell, BOOL rinse, BOOL start ) + * @param start flag to tell DG to start or stop the drain mode + * @return none + *************************************************************************/ +void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell, BOOL rinse, BOOL start ) { DRAIN_RESERVOIR_CMD_PAYLOAD_T payload; dgCmdResp[ DG_CMD_START_DRAIN ].commandID = DG_CMD_NONE; payload.drainToVolumeML = drainToVolMl; payload.tareLoadCells = tareLoadCell; payload.rinseConcentrateLines = rinse; - payload.cmd = start; + payload.cmd = start; dgReservoirDrainVolumeTargetSet = drainToVolMl; - - sendDGDrainCommand( &payload ); -} - -/*********************************************************************//** - * @brief - * The cmdDGSampleWater function sends a sample water command message to the DG. - * @details Inputs: none - * @details Outputs: sample water command sent to DG. - * @return none - *************************************************************************/ -void cmdDGSampleWater( SAMPLE_WATER_CMD_T cmd ) -{ - sendDGSampleWaterCommand( cmd ); + + sendDGDrainCommand( &payload ); } /*********************************************************************//** * @brief + * The cmdDGSampleWater function sends a sample water command message to the DG. + * @details Inputs: none + * @details Outputs: sample water command sent to DG. + * @return none + *************************************************************************/ +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 @@ -916,7 +981,7 @@ dgCmdResp[ DG_CMD_START_CHEM_DISINFECT ].commandID = DG_CMD_NONE; sendDGStartChemicalDisinfectModeCommand( start ); -} +} /*********************************************************************//** * @brief @@ -949,6 +1014,19 @@ /*********************************************************************//** * @brief + * The cmdSetDGToServiceMode function sends a request to DG to transition + * to service mode. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void cmdSetDGToServiceMode( void ) +{ + sendDGServiceModeRequest(); +} + +/*********************************************************************//** + * @brief * The handleDGCommandResponse function processes the latest DG command response. * @details Inputs: none * @details Outputs: process command response from DG @@ -1149,4 +1227,4 @@ return result; } -/**@}*/ +/**@}*/ Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r242ad36c7a1ec4ee5012c9f009899f9e0bd87628 -ra06953d0fc210dd9157388c27120e2225c898a37 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 242ad36c7a1ec4ee5012c9f009899f9e0bd87628) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision a06953d0fc210dd9157388c27120e2225c898a37) @@ -7,8 +7,8 @@ * * @file FPGA.c * -* @author (last) Dara Navaei -* @date (last) 20-Jun-2022 +* @author (last) Michael Garthwaite +* @date (last) 08-Aug-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -245,8 +245,10 @@ U16 bloodLeakRxFIFOCount; ///< Reg 448. Blood leak receive FIFO count. U08 bloodLeakRxFIFODataOut; ///< Reg 450. Blood leak receive FIFO data out. U08 dummyByte; ///< Reg 451. Dummy byte to meet the even of the data. + U16 fpgaCompatibilityRev; ///< Reg 452. Compatibility revisions U08 bloodLeakSelfTestErrorCounter; ///< Reg 452. Blood leak self test error counter. U08 bloodLeakZeroErrorCounter; ///< Reg 453. Blood leak zero error counter. + } FPGA_SENSORS_T; /// Record structure for FPGA continuous priority writes. @@ -931,25 +933,18 @@ { SELF_TEST_STATUS_T result; - // Check FPGA reported correct ID + // check FPGA reported correct ID if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) { // Check FPGA compatibility w/ firmware - if ( fpgaHeader.fpgaRevMajor > MIN_HD_FPGA_MAJOR ) + if ( HD_FPGA_COMPATIBILITY_REV == fpgaSensorReadings.fpgaCompatibilityRev ) { result = SELF_TEST_STATUS_PASSED; } else { - if ( fpgaHeader.fpgaRev >= MIN_HD_FPGA_MINOR ) - { - result = SELF_TEST_STATUS_PASSED; - } - else - { - result = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_POST_TEST_FAILED, (U32)fpgaHeader.fpgaRevMajor, (U32)fpgaHeader.fpgaRev ) - } + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_POST_TEST_FAILED, (U32)HD_FPGA_COMPATIBILITY_REV, (U32)fpgaSensorReadings.fpgaCompatibilityRev ) } } else @@ -977,11 +972,14 @@ U32 const diffFPGATimerCount = (U32)u16DiffWithWrap( currentFPGATimerCount_ms, newFPGATimerCount_ms ); U32 const diffTimerCount = u32DiffWithWrap( currentTimerCount_ms, newTimerCount_ms ); - if ( getCurrentOperationMode() > MODE_INIT ) + if ( getCurrentOperationMode() != MODE_INIT ) { if ( abs( diffFPGATimerCount - diffTimerCount ) > PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_CLOCK_SPEED_CHECK_FAILURE, diffFPGATimerCount, diffTimerCount ); + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CLOCK_SPEED_ERROR ) ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_CLOCK_SPEED_CHECK_FAILURE, diffFPGATimerCount, diffTimerCount ); + } } }