Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -re93b63ee6a4e46aca48197d9d7a5fbd1ecd2b09e -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision e93b63ee6a4e46aca48197d9d7a5fbd1ecd2b09e) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -8,7 +8,7 @@ * @file DGInterface.c * * @author (last) Dara Navaei -* @date (last) 13-Jul-2022 +* @date (last) 15-Jul-2022 * * @author (original) Sean * @date (original) 08-Apr-2020 @@ -48,6 +48,7 @@ #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 LOAD_CELL_DATA_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Load cell freshness timeout (in ms). // ********** private data ********** @@ -57,20 +58,20 @@ 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 = DG_MODE_INIT; ///< Current DG operation mode. -static U32 dgSubMode = 0; ///< Current state (sub-mode) of current DG operation mode. -static BOOL dgStartCommandSent = FALSE; ///< Flag indicates command to start DG has been sent. -static BOOL dgStarted = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop. +static DG_OP_MODE_T dgCurrentOpMode; ///< Current DG operation mode. +static U32 dgSubMode; ///< Current state (sub-mode) of current DG operation mode. +static BOOL dgStartCommandSent; ///< Flag indicates command to start DG has been sent. +static BOOL dgStarted; ///< Flag indicates whether we have commanded the DG to start or stop. static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. // State machine states 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 = 0.0; ///< Trimmer heater target temperature commanded. +static F32 dgTrimmerTempSet; ///< Trimmer heater target temperature commanded. static F32 dgTrimmerTemp = 0.0; ///< Latest dialysate temperature reported by the DG. /// Measured weight from load cells. @@ -99,8 +100,8 @@ static U32 dgOpModeDataMessageFreshStatusCounter = 0; ///< Counter use to trigger alarm if no fresh dg op mode data message is received // 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. +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. @@ -129,28 +130,36 @@ { U32 i, j; - dgStarted = FALSE; - dgTrimmerHeaterOn = FALSE; - dgTrimmerTempSet = 0.0; - dgActiveReservoirSet = DG_RESERVOIR_2; - dgReservoirFillVolumeTargetSet = 0; + dgStarted = FALSE; + dgTrimmerHeaterOn = FALSE; + dgTrimmerTempSet = 0.0F; + dgActiveReservoirSet = DG_RESERVOIR_2; + dgActiveReservoir = DG_RESERVOIR_2; + dgReservoirFillVolumeTargetSet = 0; dgReservoirDrainVolumeTargetSet = 0; + dgDialysateTemp = 0.0F; + dgCurrentOpMode = DG_MODE_INIT; + dgSubMode = 0; + dgStartCommandSent = FALSE; + dgDialysateFlowRateMlMin = 0.0; + dgDialysateFlowDataFreshFlag = FALSE; // initialize load cell weights for ( i = 0; i < NUM_OF_LOAD_CELLS; i++ ) { - loadCellWeightInGrams[ i ].data = 0.0; + loadCellWeightInGrams[ i ].data = 0.0; loadCellWeightInGrams[ i ].ovInitData = 0.0; - loadCellWeightInGrams[ i ].ovData = 0.0; - loadCellWeightInGrams[ i ].override = 0; + loadCellWeightInGrams[ i ].ovData = 0.0; + loadCellWeightInGrams[ i ].override = 0; } // initialize reservoirs weights for ( i = 0; i < NUM_OF_DG_RESERVOIRS; i++ ) { lgFilteredReservoirWeightInGrams[ i ] = 0.0; + for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) { - lgLoadCellReadings[ i ][ j ] = 0.0; + lgLoadCellReadings[ i ][ j ] = 0.0; lgLoadCellBackupReadings[ i ][ j ] = 0.0; } } @@ -163,9 +172,9 @@ dgCmdResp[ i ].rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; } - lgLoadCellReadingsIdx = 0; - lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; - lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + lgLoadCellReadingsIdx = 0; + lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; + lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; @@ -488,26 +497,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; } /*********************************************************************//** @@ -1010,6 +1019,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 @@ -1075,12 +1097,19 @@ * @brief * The checkDialysateTemperature function checks the dialysate temperature * reported by DG and alarm if temperature is out of range. - * @details Inputs: dgTrimmerTempSet, dgDialysateTemp, dgRedundantDialysateTemp - * @details Outputs: alarm if dialysate temperature is out of accepted range + * @details Inputs: dgTrimmerTempSet, dgDialysateTemp + * @details Outputs: none * @return none *************************************************************************/ void checkDialysateTemperature( void ) { + BOOL isTDiTempAboveHighSafety = ( dgDialysateTemp >= DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C ? TRUE : FALSE ); + BOOL isTDiTempAboveLowSafety = ( dgDialysateTemp >= DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C ? TRUE : FALSE ); + F32 TDiHigh = dgTrimmerTempSet + DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; + BOOL isTDiTempAboveDialysateTarget = ( TDiHigh >= dgDialysateTemp ? TRUE : FALSE ); + F32 TDiLow = dgTrimmerTempSet - DIALYSATE_TEMP_OUT_OF_TARGET_TOL_C; + BOOL isTDiTempBelowDialysateTarget = ( TDiLow >= dgDialysateTemp ? TRUE : FALSE ); + /*BOOL const dialysateHighTemp = ( ( ( dgDialysateTemp - dgTrimmerTempSet ) > DIALYSATE_TEMP_TOLERANCE_C ) || ( dgDialysateTemp > DIALYSATE_TEMP_HIGH_LIMIT_C ) ); @@ -1089,20 +1118,17 @@ BOOL const dialysateTempRecovered = fabs( dgDialysateTemp - dgTrimmerTempSet ) < DIALYSATE_TEMP_RECOVERY_TOLERANCE_C ? TRUE : FALSE; + #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DIALYSATE_TEMP_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dgTrimmerTempSet, dgDialysateTemp ); - } + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_HIGH_SAFETY_RANGE, isTDiTempAboveHighSafety, dgDialysateTemp, DIALYSATE_TEMP_HIGH_SAFETY_LIMIT_C ); + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_OUT_OF_LOW_SAFETY_RANGE, isTDiTempAboveLowSafety, dgDialysateTemp, DIALYSATE_TEMP_LOW_SAFETY_LIMIT_C ); - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateLowTemp ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dgTrimmerTempSet, dgDialysateTemp ); - } - + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP, isTDiTempAboveDialysateTarget, dgDialysateTemp, TDiHigh ); + checkPersistentAlarm( ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP, isTDiTempBelowDialysateTarget, dgDialysateTemp, TDiLow ); + } if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) { clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH ); Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -re54806da466a8c52e19fd272356dbbfde04171fd -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision e54806da466a8c52e19fd272356dbbfde04171fd) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -8,7 +8,7 @@ * @file DGInterface.h * * @author (last) Dara Navaei -* @date (last) 13-Jul-2022 +* @date (last) 15-Jul-2022 * * @author (original) Sean * @date (original) 08-Apr-2020 @@ -74,30 +74,30 @@ /// Payload record structure for DG temperature sensors data message. typedef struct { - F32 inletPrimaryHeater; ///< Inlet primary heater temperature sensor - F32 outletPrimaryHeater; ///< Outlet primary heater temperature sensor - F32 conductivitySensor1; ///< Conductivity sensor 1 temperature sensor - F32 conductivitySensor2; ///< Conductivity sensor 2 temperature sensor - F32 outletRedundant; ///< Outlet redundant temperature sensor - F32 inletDialysate; ///< Inlet dialysate temperature sensor - F32 primaryHeaterThermocouple; ///< Primary heaters thermocouple sensor - F32 trimmerHeaterThermocouple; ///< Trimmer heater thermocouple sensor - F32 priamyHeaterColdjunction; ///< Primary heaters cold junction temperature sensor - F32 trimmerHeaterColdjunction; ///< Trimmer heater cold junction temperature sensor - F32 primaryHeaterInternal; ///< Primary heaters internal temperature (calculated from thermocouple and cold junction) - F32 trimmerHeaterInternal; ///< Trimmer heater internal temperature (calculated from thermocouple and cold junction) - F32 fpgaBoard; ///< FPGA board temperature sensor - F32 loadCellA1B1; ///< Load cell A1/B1 temperature sensor - F32 loadCellA2B2; ///< Load cell A2/B2 temperature sensor - F32 internalTHDORTD; ///< THDo RTD channel temperature sensor - F32 internalTDIRTD; ///< TDI RTD channel temperature sensor - F32 internalCondSnsrTemp; ///< Conductivity Sensor internal temperature sensor - U32 primaryThermoCoupleRaw; ///< Primary heaters thermocouple raw ADC value - U32 primaryColdjuncRaw; ///< Primary heaters cold junction raw ADC value - U32 trimmerThermoCoupleRaw; ///< Trimmer heater thermocouple raw ADC value - U32 trimmerColdjuncRaw; ///< Trimmer heater cold junction raw ADC value - S32 cond1Raw; ///< Conductivity sensor 1 raw temperature ADC value - S32 cond2Raw; ///< Conductivity sensor 2 raw temperature ADC value + F32 TPi; ///< Inlet primary heaters temperature sensor + F32 TPo; ///< Outlet primary heaters temperature sensor + F32 TD1; ///< Conductivity sensor 1 temperature sensor + F32 TD2; ///< Conductivity sensor 2 temperature sensor + F32 TRo; ///< Outlet redundant temperature sensor + F32 TDi; ///< Inlet dialysate temperature sensor + F32 HtrPrimThermo; ///< Primary heaters internal temperature sensor + F32 HtrTrimThermo; ///< Trimmer heater internal temperature sensor + F32 HtrPrimColdJunc; ///< Primary heaters cold junction temperature sensor + F32 HtrTrimColdJunc; ///< Trimmer heater cold junction temperature sensor + F32 HtrPrimInternal; ///< Primary heaters internal temperature + F32 HtrTrimInternal; ///< Trimmer heater internal temperature + F32 DGBoardTemp; ///< DG board temperature + F32 ResOneLoadCellTemp; ///< Reservoir 1 load cell sensor temperature + F32 ResTwoLoadCellTemp; ///< Reservoir 2 load cell sensor temperature + F32 THDoInternalTemp; ///< THDo RTD channel temperature sensor + F32 TDiInternalTemp; ///< TDI RTD channel temperature sensor + F32 internalCondSnsrTemp; ///< Conductivity Sensor internal temperature sensor + U32 primaryThermoCoupleRaw; ///< Primary heaters thermocouple raw ADC value + U32 primaryColdjuncRaw; ///< Primary heaters cold junction raw ADC value + U32 trimmerThermoCoupleRaw; ///< Trimmer heater thermocouple raw ADC value + U32 trimmerColdjuncRaw; ///< Trimmer heater cold junction raw ADC value + S32 cond1Raw; ///< Conductivity sensor 1 raw temperature ADC value + S32 cond2Raw; ///< Conductivity sensor 2 raw temperature ADC value } TEMPERATURE_SENSORS_DATA_T; /// Payload record structure for a drain reservoir command message. @@ -157,6 +157,7 @@ F32 getReservoirBackupWeightLargeFilter( DG_RESERVOIR_ID_T resID ); F32 getDialysateTemperature( void ); DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ); +F32 getDialysateTemperature( void ); DG_MIXING_RATIOS_T getDGMixingRatios( void ); void setDGOpMode( U32 opMode, U32 subMode ); @@ -185,6 +186,7 @@ void cmdStartDGChemicalDisinfect( void ); void cmdStopDGChemicalDisinfect( void ); void cmdRequestDGMixingRatios( void ); +void cmdSetDGToServiceMode( void ); void handleDGCommandResponse( DG_CMD_RESPONSE_T *dgCmdRespPtr ); BOOL getDGCommandResponse( U32 commandID, DG_CMD_RESPONSE_T *cmdRespPtr ); Index: firmware/App/Controllers/Temperatures.c =================================================================== diff -u -r0b0cfd7e0f84f89b3a428cf77334e2d76b13a6a9 -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision 0b0cfd7e0f84f89b3a428cf77334e2d76b13a6a9) +++ firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -288,9 +288,10 @@ if ( ( temperature > MAX_ALLOWED_TEMPERATURE ) || ( temperature < MIN_ALLOWED_TEMPERATURE ) ) { - isTempOutOfRange |= TRUE; - lastFaultSensor = sensor; + isTempOutOfRange = TRUE; + lastFaultSensor = sensor; } + } checkPersistentAlarm( ALARM_ID_HD_TEMPERATURES_OUT_OF_RANGE, isTempOutOfRange, lastFaultSensor, MAX_ALLOWED_TEMPERATURE ); Index: firmware/App/Modes/Prime.c =================================================================== diff -u -re54806da466a8c52e19fd272356dbbfde04171fd -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision e54806da466a8c52e19fd272356dbbfde04171fd) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -7,8 +7,8 @@ * * @file Prime.c * -* @author (last) Michael Garthwaite -* @date (last) 21-Apr-2022 +* @author (last) Bill Bracken +* @date (last) 24-Aug-2022 * * @author (original) Quang Nguyen * @date (original) 08-Dec-2020 @@ -51,6 +51,7 @@ #define DIALYZER_VOLUME_SCALE_FACTOR 0.5F ///< Half of the dialyzer total volume. #define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. +#define PURGE_AIR_TIME_OUT_COUNT ( 120 * MS_PER_SECOND ) ///< Time period count for purge air time out. #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. Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -re54806da466a8c52e19fd272356dbbfde04171fd -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e54806da466a8c52e19fd272356dbbfde04171fd) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -8,7 +8,7 @@ * @file SystemComm.c * * @author (last) Dara Navaei -* @date (last) 14-Jun-2022 +* @date (last) 03-Aug-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -54,7 +54,7 @@ #define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< Maximum time for a Denali message that requires ACK to be ACK'd #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 MSG_NOT_ACKED_MAX_RETRIES 20 ///< 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) @@ -112,10 +112,6 @@ static U32 timeOfLastUICheckIn = 0; ///< Last time UI checked in static volatile BOOL uiDidCommunicate = FALSE; ///< Has UI every sent a message -#ifdef EMC_TEST_BUILD - static U32 badCANCount; // Test code in support of EMC testing -#endif - // ********** private function prototypes ********** static void clearCANXmitBuffers( void ); @@ -233,7 +229,11 @@ * @return TRUE if UI has communicated since power up, FALSE if not *************************************************************************/ BOOL uiCommunicated( void ) -{ +{ +#ifdef SIMULATE_UI + uiDidCommunicate = TRUE; +#endif + return uiDidCommunicate; } @@ -592,10 +592,6 @@ else if ( -1 == msgSize ) // Candidate message with bad CRC found? { badCRCDetected = TRUE; -#ifdef EMC_TEST_BUILD - badCANCount++; - broadcastCANErrorCount( badCANCount ); -#endif getFromCommBuffer( MSG_IN_BUFFERS[ i ], data, 1 ); // Consume sync byte so we can re-sync messagesInBuffer = TRUE; // Keep processing this buffer } // Looks like there is a complete message in the comm buffer @@ -730,10 +726,6 @@ } else // CRC failed { -#ifdef EMC_TEST_BUILD - badCANCount++; - broadcastCANErrorCount( badCANCount ); -#endif checkTooManyBadMsgCRCs(); } } @@ -751,7 +743,9 @@ static void checkForCommTimeouts( void ) { if ( TRUE == uiDidCommunicate ) - { + { + HD_OP_MODE_T opMode = getCurrentOperationMode(); + if ( TRUE == didTimeout( timeOfLastUICheckIn, UI_COMM_TIMEOUT_IN_MS ) ) { #ifndef _RELEASE_ @@ -762,13 +756,21 @@ } } - if ( TRUE == didTimeout( timeOfLastDGCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) + // Only alarm on DG comm loss while in the treatment workflow + if ( MODE_PRET == opMode || MODE_TREA == opMode || MODE_POST == opMode ) { + if ( TRUE == didTimeout( timeOfLastDGCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) + { #ifndef RUN_WITHOUT_DG - activateAlarmNoData( ALARM_ID_DG_COMM_TIMEOUT ); - dgIsCommunicating = FALSE; + activateAlarmNoData( ALARM_ID_DG_COMM_TIMEOUT ); + dgIsCommunicating = FALSE; #endif + } } + else // Otherwise clear the alarm + { + clearAlarm( ALARM_ID_DG_COMM_TIMEOUT ); + } } } @@ -879,13 +881,7 @@ // Find expired messages pending ACK for ( i = 0; i < PENDING_ACK_LIST_SIZE; i++ ) { // Pending ACK expired? - U32 timeoutPeriod = MSG_NOT_ACKED_TIMEOUT_MS; // set the timeout as default - - if ( MODE_INIT == getCurrentOperationMode() ) - { // change it to longer timeout if the HD is in INIT state - timeoutPeriod = MSG_NOT_ACKED_TIMEOUT_MS_INIT; - } - if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, timeoutPeriod ) ) ) + if ( ( TRUE == pendingAckList[ i ].used ) && ( TRUE == didTimeout( pendingAckList[ i ].timeStamp, MSG_NOT_ACKED_TIMEOUT_MS ) ) ) { // If retries left, reset and resend pending message if ( pendingAckList[ i ].retries > 0 ) { // Re-queue message for transmit @@ -1151,7 +1147,6 @@ handleTesterLogInRequest( message ); break; - // The default cannot be reached in VectorCAST since the cases are run in a for loop default: // Un-recognized or un-handled message ID received - ignore break; @@ -1616,10 +1611,6 @@ handleTestSyringePumpHeprinBolusTargetRateOverrideRequest( message ); break; - case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: - handleTestCurrentTreamtmentParametersRequest( message ); - break; - case MSG_ID_HD_FANS_DUTY_CYCLE_OVERRIDE: handleSetFansDutyCycleOverrideRequest( message ); break; @@ -1656,6 +1647,11 @@ handleResendAllAlarmsCommand( message ); break; + case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: + handleTestCurrentTreamtmentParametersRequest( message ); + break; + + // The default cannot be reached in VectorCAST since the cases are run in a for loop default: // Unrecognized message ID received - ignore Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -re54806da466a8c52e19fd272356dbbfde04171fd -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e54806da466a8c52e19fd272356dbbfde04171fd) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Dara Navaei -* @date (last) 14-Jun-2022 +* @author (last) Bill Bracken +* @date (last) 22-Aug-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -28,6 +28,7 @@ #include "Fans.h" #include "FPGA.h" #include "ModeStandby.h" +#include "ModeInitPOST.h" #include "OperationModes.h" #include "RTC.h" #include "SampleWater.h" @@ -2002,35 +2003,6 @@ } -#ifdef EMC_TEST_BUILD -/*********************************************************************//** - * @brief - * The broadcastCANErrorCount function handles the CAN error count - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -BOOL broadcastCANErrorCount( U32 count ) -{ - BOOL result; - MESSAGE_T msg; - U08 *payloadPtr = msg.payload; - - // Create a message record - blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_CAN_ERROR_COUNT; - msg.hdr.payloadLen = sizeof( U32 ); - - memcpy( payloadPtr, &count, sizeof( U32 ) ); - - // 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; -} -#endif - // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** @@ -2269,7 +2241,6 @@ { BOOL result; MESSAGE_T msg; - U08 *payloadPtr = msg.payload; // Create a message record blankMessage( &msg ); @@ -2362,13 +2333,13 @@ { TEMPERATURE_SENSORS_DATA_T payload; - memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); - } - // TODO - what to do if invalid payload length? - // TODO - how to know if DG stops sending these? -} - + memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); + } + // TODO - what to do if invalid payload length? + // TODO - how to know if DG stops sending these? +} + /*********************************************************************//** * @brief * The handleDialysateFlowData function handles dialysate flow data broadcast @@ -2671,111 +2642,111 @@ return result; } -/*********************************************************************//** - * @brief - * The handleChangeUFSettingsRequest function handles a ultrafiltration - * change settings request message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeUFSettingsRequest( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(F32) ) - { - F32 uFVolume; - - memcpy( &uFVolume, message->payload, sizeof(F32) ); - - verifyUFSettingsChange( uFVolume ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} - -/*********************************************************************//** - * @brief - * The handleChangeUFSettingsConfirmation function handles a ultrafiltration - * change setting confirmation message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeUFSettingsConfirmation( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ) - { - UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T payload; - - memcpy( &payload, message->payload, sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ); - - verifyUFSettingsConfirmation( payload.volume_mL, payload.adjustType ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} - -/*********************************************************************//** - * @brief - * The handleChangeTreatmentDurationRequest function handles a treatment - * duration setting change message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeTreatmentDurationRequest( MESSAGE_T *message ) -{ - if ( message->hdr.payloadLen == sizeof(U32) ) - { +/*********************************************************************//** + * @brief + * The handleChangeUFSettingsRequest function handles a ultrafiltration + * change settings request message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeUFSettingsRequest( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(F32) ) + { + F32 uFVolume; + + memcpy( &uFVolume, message->payload, sizeof(F32) ); + + verifyUFSettingsChange( uFVolume ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The handleChangeUFSettingsConfirmation function handles a ultrafiltration + * change setting confirmation message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeUFSettingsConfirmation( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ) + { + UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(UF_SETTINGS_CHANGE_CONFIRMATION_PAYLOAD_T) ); + + verifyUFSettingsConfirmation( payload.volume_mL, payload.adjustType ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The handleChangeTreatmentDurationRequest function handles a treatment + * duration setting change message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeTreatmentDurationRequest( MESSAGE_T *message ) +{ + if ( message->hdr.payloadLen == sizeof(U32) ) + { U32 timeInMin; - - memcpy( &timeInMin, message->payload, sizeof(U32) ); - verifyTreatmentDurationSettingChange( timeInMin ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } -} -/*********************************************************************//** - * @brief - * The handleChangeBloodDialysateRateChangeRequest function handles a blood - * and dialysate rate settings change message from the UI. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ) -{ - U32 expPayloadSize = sizeof(U32) + sizeof(U32); - - if ( expPayloadSize == message->hdr.payloadLen ) - { - U32 bloodRate; - U32 dialRate; - - memcpy( &bloodRate, &message->payload[0], sizeof(U32) ); - memcpy( &dialRate, &message->payload[sizeof(U32)], sizeof(U32) ); - - verifyBloodAndDialysateRateSettingsChange( bloodRate, dialRate ); - } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); - } + memcpy( &timeInMin, message->payload, sizeof(U32) ); + verifyTreatmentDurationSettingChange( timeInMin ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } } /*********************************************************************//** * @brief + * The handleChangeBloodDialysateRateChangeRequest function handles a blood + * and dialysate rate settings change message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message ) +{ + U32 expPayloadSize = sizeof(U32) + sizeof(U32); + + if ( expPayloadSize == message->hdr.payloadLen ) + { + U32 bloodRate; + U32 dialRate; + + memcpy( &bloodRate, &message->payload[0], sizeof(U32) ); + memcpy( &dialRate, &message->payload[sizeof(U32)], sizeof(U32) ); + + verifyBloodAndDialysateRateSettingsChange( bloodRate, dialRate ); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief * The handleChangePressureLimitsRequest function handles a pressure limits * change message from the UI. * @details Inputs: none @@ -5158,6 +5129,7 @@ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) { result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); @@ -7033,15 +7005,26 @@ { BOOL status = FALSE; HD_OP_MODE_T currentMode = getCurrentOperationMode(); + DG_OP_MODE_T currentDGMode = getDGOpMode(); REQUEST_REJECT_REASON_CODE_T reject; if ( 0 == message->hdr.payloadLen ) { if ( ( MODE_STAN == currentMode ) || ( MODE_FAUL == currentMode ) ) { - status = TRUE; + requestNewOperationMode( MODE_SERV ); - reject = REQUEST_REJECT_REASON_NONE; + + if ( (DG_MODE_STAN == currentDGMode) || (DG_MODE_FAUL == currentDGMode) ) + { + status = TRUE; + cmdSetDGToServiceMode(); + reject = REQUEST_REJECT_REASON_NONE; + } + else + { + reject = REQUEST_REJECT_REASON_DG_NOT_IN_STANDBY_IDLE_STATE; + } } else { @@ -7319,4 +7302,28 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The sendDGServiceModeRequest function constructs a service mode request msg + * to the DG and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG Service mode request msg constructed and queued. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendDGServiceModeRequest() +{ + BOOL result; + MESSAGE_T msg; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_REQUEST_DG_SERVICE_MODE; + msg.hdr.payloadLen = 0; + + // 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; +} + /**@}*/ Index: firmware/source/sys_main.c =================================================================== diff -u -rfba3daf7d2ab628bf90da7504b38d0b03f9e0bd9 -r9d083454c3e951c3b598ceb9dd60cd7e62ad4999 --- firmware/source/sys_main.c (.../sys_main.c) (revision fba3daf7d2ab628bf90da7504b38d0b03f9e0bd9) +++ firmware/source/sys_main.c (.../sys_main.c) (revision 9d083454c3e951c3b598ceb9dd60cd7e62ad4999) @@ -73,6 +73,7 @@ #include "Buttons.h" #include "CommBuffers.h" #include "CPLD.h" +#include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "Fans.h" @@ -187,6 +188,7 @@ initRTC(); // Initialize services initCommBuffers(); + initDGInterface(); initIntegrity(); initFPGA(); initMsgQueues();