Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r43e59e505bbea87c76822c51a3273eec3f4addaa -r72e4c11140e7a0d186c3a6e58ef724b7e126bab8 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 43e59e505bbea87c76822c51a3273eec3f4addaa) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 72e4c11140e7a0d186c3a6e58ef724b7e126bab8) @@ -42,13 +42,22 @@ #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. #define DIALYSATE_TEMP_PERSISTENCE_PERIOD ( 3 * MS_PER_SECOND ) ///< Persistence period for dialysate temperature alarm. +static U32 loadcellDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh load cell data message is received +static U32 temperatureDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh temperature data message is received +static U32 reservoirsDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh reservoirs data message is received +static U32 dgOpModeDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dg op mode data message is received + #define DIALYSATE_TEMP_RECOVERY_TOLERANCE_C 2.0F ///< Dialysate temperature recovery tolerance in degree C. #define DIALYSATE_TEMP_TOLERANCE_C 4.0F ///< Dialysate temperature tolerance in degree C. #define DIALYSATE_TEMP_HIGH_LIMIT_C 42.0F ///< Dialysate high temperature limit in degree C. #define DIALYSATE_TEMP_LOW_LIMIT_C 33.0F ///< Dialysate low temperature limit in degree C. // ********** 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); // DN-19AUG2022 +static const U32 DIP_RESERVOIRS_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); // DN-22AUG2022 +static const U32 DIP_DG_OP_MODE_DATA_MESSAGE_ALARM_THRESHOLD = ((2 * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); // DN-22AUG2022 // DG status static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; ///< Current DG operation mode. @@ -83,7 +92,14 @@ // DG Dialysate flow rate 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 dgTemperatureDataFreshFlag = FALSE; ///< Flag to signal the handleTemperatureReadingsFromDG() to process fresh temperature data // DN-19AUG2022 +static BOOL dgReservoirsDataFreshFlag = FALSE; ///< Flag to signal the handleDGReservoirData() to process fresh reservoirs data // DN-22AUG2022 +static BOOL dgOpModeDataFreshFlag = FALSE; ///< Flag to signal the handleDGOpMode() to process fresh dg op mode data // DN-22AUG2022 + + + // Reservoir data static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; ///< Latest active reservoir reported by the DG. static DG_RESERVOIR_ID_T dgActiveReservoirSet = DG_RESERVOIR_2; ///< Active reservoir commanded. @@ -171,6 +187,26 @@ { // 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 - DN-22AUG2022 + if ( TRUE == getLoadCellDataFreshFlag() ) + { + loadcellDataMessageFreshStatusCounter = 0; + } + else + { // Alarm if not receiving new load cell data message in timely manner + if ( TRUE == isDGCommunicating() ) + { + if ( ++loadcellDataMessageFreshStatusCounter > DIP_LOAD_CELL_DATA_MESSAGE_ALARM_THRESHOLD ) + { + activateAlarmNoData( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE ); + } + } + else + { + loadcellDataMessageFreshStatusCounter = 0; + } + } + // Check to see if DG has restarted checkDGRestart(); } @@ -282,6 +318,74 @@ return result; } + +/*********************************************************************//** + * @brief + * The getLoadCellDataFreshFlag function returns a flag to indicate + * if the load cell data message reported by the DG is fresh or stale data. + * @details Inputs: dgLoadCellDataFreshFlag + * @details Outputs: dgLoadCellDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getLoadCellDataFreshFlag( void ) +{ + BOOL result = dgLoadCellDataFreshFlag; + + dgLoadCellDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getTemperatureDataFreshFlag function returns a flag to indicate + * if the temperature data message reported by the DG is fresh or stale data. + * @details Inputs: dgTemperatureDataFreshFlag + * @details Outputs: dgTemperatureDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getTemperatureDataFreshFlag( void ) // DN-19AUG2022 +{ + BOOL result = dgTemperatureDataFreshFlag; + + dgTemperatureDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getReservoirsDataFreshFlag function returns a flag to indicate + * if the reservoirs data message reported by the DG is fresh or stale data. + * @details Inputs: dgTemperatureDataFreshFlag + * @details Outputs: dgTemperatureDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getReservoirsDataFreshFlag( void ) // DN-22AUG2022 +{ + BOOL result = dgReservoirsDataFreshFlag; + + dgReservoirsDataFreshFlag = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getDGOpModeDataFreshFlag function returns a flag to indicate + * if the dg op mode data message reported by the DG is fresh or stale data. + * @details Inputs: dgTemperatureDataFreshFlag + * @details Outputs: dgTemperatureDataFreshFlag + * @return T/F flag to indicate fresh/stale status of load cell data. + *************************************************************************/ +BOOL getDgOpModeDataFreshFlag( void ) // DN-22AUG2022 +{ + BOOL result = dgOpModeDataFreshFlag; + + dgOpModeDataFreshFlag = FALSE; + + return result; +} /*********************************************************************//** * @brief @@ -420,7 +524,32 @@ * @return none *************************************************************************/ void setDGOpMode( U32 opMode, U32 subMode ) -{ +{ + // DN-22AUG2022 + // BEGIN + // Trigger alarm if not receiving new DG Op Mode data message in timely manner + if ( TRUE == getDgOpModeDataFreshFlag() ) + { + dgOpModeDataMessageFreshStatusCounter = 0; + } + else + { + // Alarm if not receiving new lDG Op Mode data message in timely manner + if ( TRUE == isDGCommunicating() ) // DN-22AUG2022 + { + if ( ++dgOpModeDataMessageFreshStatusCounter > DIP_DG_OP_MODE_DATA_MESSAGE_ALARM_THRESHOLD ) + { + activateAlarmNoData( ALARM_ID_HD_NEW_DG_OPERATION_MODE_MESSAGE_NOT_RECEIVE ); + } + } + else + { + dgOpModeDataMessageFreshStatusCounter = 0; + } + + } + // END - DN-22AUG2022 + if ( opMode < NUM_OF_DG_MODES ) { dgCurrentOpMode = (DG_OP_MODE_T)opMode; @@ -429,7 +558,9 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_OPERATING_MODE, opMode ); - } + } + + dgOpModeDataFreshFlag = TRUE; } /*********************************************************************//** @@ -443,9 +574,36 @@ * @return none *************************************************************************/ void setDialysateTemperatureReadings( F32 temp1, F32 temp2 ) -{ - dgDialysateTemp = temp1; - dgRedundantDialysateTemp = temp2; +{ + // DN-19AUG2022 + // BEGIN + // Trigger alarm if not receiving new load cell data message in timely manner + if ( TRUE == getTemperatureDataFreshFlag() ) + { + temperatureDataMessageFreshStatusCounter = 0; + } + else + { + // Alarm if not receiving new load cell data message in timely manner + if ( TRUE == isDGCommunicating() ) // DN-19AUG2022 + { + if ( ++temperatureDataMessageFreshStatusCounter > DIP_TEMPERATURE_DATA_MESSAGE_ALARM_THRESHOLD ) + { + activateAlarmNoData( ALARM_ID_HD_NEW_DIALYSATE_TEMPERATURE_DATA_MESSAGE_NOT_RECEIVE ); + } + } + else + { + temperatureDataMessageFreshStatusCounter = 0; + } + + } + // END - DN-19AUG2022 + + dgDialysateTemp = temp1; + dgRedundantDialysateTemp = temp2; + + dgTemperatureDataFreshFlag = TRUE; } /*********************************************************************//** @@ -460,7 +618,32 @@ * @return none *************************************************************************/ void setDGReservoirsData( DG_RESERVOIR_ID_T resID, U32 fillVol, U32 drainVol ) -{ +{ + // DN-22AUG2022 + // BEGIN + // Trigger alarm if not receiving new reservoirs data message in timely manner + if ( TRUE == getReservoirsDataFreshFlag() ) + { + reservoirsDataMessageFreshStatusCounter = 0; + } + else + { + // Alarm if not receiving new reservoirs data message in timely manner + if ( TRUE == isDGCommunicating() ) // DN-22AUG2022 + { + if ( ++reservoirsDataMessageFreshStatusCounter > DIP_RESERVOIRS_DATA_MESSAGE_ALARM_THRESHOLD ) + { + activateAlarmNoData( ALARM_ID_HD_NEW_RESERVOIRS_DATA_MESSAGE_NOT_RECEIVE ); + } + } + else + { + reservoirsDataMessageFreshStatusCounter = 0; + } + + } + // END - DN-22AUG2022 + if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoir = resID; @@ -470,7 +653,9 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_RESERVOIR_ID, resID ); - } + } + + dgReservoirsDataFreshFlag = TRUE; // DN-22AUG2022 } /*********************************************************************//** @@ -514,6 +699,28 @@ DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); BOOL inTreatment = ( MODE_TREA == getCurrentOperationMode() ? TRUE : FALSE ); + /* ========== + // Trigger alarm if not receiving new load cell data message in timely manner + if ( TRUE == getLoadCellDataFreshFlag() ) + { + loadcellDataMessageFreshStatusCounter = 0; + } + else + { // Alarm if not receiving new load cell data message in timely manner + if ( TRUE == isDGCommunicating() ) + { + if ( ++loadcellDataMessageFreshStatusCounter > DIP_LOAD_CELL_DATA_MESSAGE_ALARM_THRESHOLD ) + { + activateAlarmNoData( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE ); + } + } + else + { + loadcellDataMessageFreshStatusCounter = 0; + } + } + ========= */ + loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_PRIMARY ].data = res1Primary; loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_BACKUP ].data = res1Backup; loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; @@ -538,6 +745,8 @@ // Update Dialysis sub-mode with new reservoir volumes updateReservoirVolumes( res1Primary, res2Primary ); + + dgLoadCellDataFreshFlag = TRUE; } /*********************************************************************//**