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; } /*********************************************************************//** Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -rcbaa57803fa8359407a799fca0cde6ae2c486bd7 -r72e4c11140e7a0d186c3a6e58ef724b7e126bab8 --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision cbaa57803fa8359407a799fca0cde6ae2c486bd7) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 72e4c11140e7a0d186c3a6e58ef724b7e126bab8) @@ -149,6 +149,7 @@ DG_RESERVOIR_ID_T getDGInactiveReservoir( void ); BOOL hasDGCompletedReservoirSwitch( void ); BOOL getDialysateFlowDataFreshFlag( void ); +BOOL getLoadCellDataFreshFlag(void); F32 getDGDialysateFlowRateLMin( void ); F32 getLoadCellWeight( LOAD_CELL_ID_T loadCellID ); F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ); Index: firmware/App/Modes/Prime.c =================================================================== diff -u -raceb6e5388e905d119c5c379bc97ced0720aa270 -r72e4c11140e7a0d186c3a6e58ef724b7e126bab8 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision aceb6e5388e905d119c5c379bc97ced0720aa270) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 72e4c11140e7a0d186c3a6e58ef724b7e126bab8) @@ -53,6 +53,7 @@ #define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. #define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. +#define PRIME_SALINE_DIALYZER_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for prime saline dialyzer time out. #define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. #define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. #define STEADY_VOLUME_COUNT_SEC ( 10000 / LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ///< Counter must be greater than 10 seconds before steady volume is true. @@ -500,7 +501,7 @@ if ( TRUE == didTimeout( purgeAirTimeOutStartTime, PURGE_AIR_TIME_OUT_COUNT ) ) { - activateAlarmNoData( ALARM_ID_HD_PRIME_PURGE_AIR_TIME_OUT ); + activateAlarmNoData( ALARM_ID_HD_PRIME_SALINE_PURGE_AIR_TIME_OUT ); } if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) @@ -732,6 +733,11 @@ state = HD_PRIME_RESERVOIR_TWO_FILL_COMPLETE_STATE; } + if ( TRUE == didTimeout( primeSalineDialyzerStartTime, PRIME_SALINE_DIALYZER_TIME_OUT_COUNT ) ) + { + activateAlarmNoData( ALARM_ID_PRIME_SALINE_DIALYZER_TIME_OUT ); // Trigger HD prime saline dialyzer time out alarm. + } + if ( TRUE == doesAlarmStatusIndicateStop() ) { setupForPrimePause(); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r1b738450008f53cdacc28226a503593bb54ba901 -r72e4c11140e7a0d186c3a6e58ef724b7e126bab8 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 1b738450008f53cdacc28226a503593bb54ba901) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 72e4c11140e7a0d186c3a6e58ef724b7e126bab8) @@ -56,7 +56,7 @@ #define MSG_NOT_ACKED_TIMEOUT_MS_INIT 5000 ///< Maximum time for a Denali message that requires ACK to be ACK'd on the INIT state for the first (UI version request) message of the POST #define MSG_NOT_ACKED_MAX_RETRIES 3 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm #define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time - + #pragma pack(push, 1) /// Record for transmitted message that is pending acknowledgment from receiver. @@ -96,6 +96,7 @@ COMM_BUFFER_IN_CAN_UI_BROADCAST, COMM_BUFFER_IN_CAN_PC, }; +//extern U32 loadcellDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh load cell data message is received - DN-22AUG2022 static U08 lastCANPacketSent[ CAN_MESSAGE_PAYLOAD_SIZE ]; ///< Keep last packet sent on CAN bus in case we need to re-send. static CAN_MESSAGE_BOX_T lastCANPacketSentChannel = (CAN_MESSAGE_BOX_T)0; ///< Keep channel last packet was sent on CAN bus in case we need to re-send. @@ -257,7 +258,7 @@ * @return none *************************************************************************/ void execSystemCommRx( void ) -{ +{ // Parse messages from comm buffers and queue them processIncomingData(); @@ -702,6 +703,12 @@ { BOOL isThereMsgRcvd = TRUE; // Assume TRUE at first to get into while loop MESSAGE_WRAPPER_T message; + + // DN-22AUG2022 - Try here for debug + //if ( ++loadcellDataMessageFreshStatusCounter > DIP_LOAD_CELL_DATA_MESSAGE_ALARM_THRESHOLD ) + //{ + // activateAlarmNoData( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE ); + //} while ( TRUE == isThereMsgRcvd ) { Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r1b738450008f53cdacc28226a503593bb54ba901 -r72e4c11140e7a0d186c3a6e58ef724b7e126bab8 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 1b738450008f53cdacc28226a503593bb54ba901) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 72e4c11140e7a0d186c3a6e58ef724b7e126bab8) @@ -41,7 +41,8 @@ #include "Utilities.h" #include "Valves.h" #include "WatchdogMgmt.h" -#include "HDDefs.h" +#include "HDDefs.h" +#include "TaskPriority.h" /** * @addtogroup SystemCommMessages @@ -61,9 +62,9 @@ #pragma pack(pop) // ********** private data ********** - static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether an external tester (connected PC) has sent a valid login message. static volatile U16 nextSeqNo = 1; ///< Value of sequence number to use for next transmitted message. + /// List of message IDs that are requested not to be transmitted. static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 };