Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -r85b81717a743d9a805d249dbb10f58253410f00c -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 85b81717a743d9a805d249dbb10f58253410f00c) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file LoadCell.c * * @author (last) Dara Navaei -* @date (last) 02-May-2022 +* @date (last) 03-Aug-2022 * * @author (original) Saeed Nejatali * @date (original) 25-Feb-2020 @@ -170,10 +170,10 @@ loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].rawReading = b2 & MASK_OFF_U32_MSB; // Check error bits from new readings - a1 = ( a1 >> 31 ) << SHIFT_24_BITS; - a2 = ( a2 >> 31 ) << SHIFT_16_BITS_FOR_WORD_SHIFT; - b1 = ( b1 >> 31 ) << SHIFT_8_BITS_FOR_BYTE_SHIFT; - b2 = ( b2 >> 31 ); + a1 = ( a1 >> SHIFT_BITS_BY_31 ) << SHIFT_24_BITS; + a2 = ( a2 >> SHIFT_BITS_BY_31 ) << SHIFT_16_BITS_FOR_WORD_SHIFT; + b1 = ( b1 >> SHIFT_BITS_BY_31 ) << SHIFT_8_BITS_FOR_BYTE_SHIFT; + b2 = ( b2 >> SHIFT_BITS_BY_31 ); if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, ( ( a1 > 0 ) || ( a2 > 0 ) || ( b1 > 0 ) || ( b2 > 0 ) ) ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, ( a1 | a2 | b1 | b2 ) ) @@ -277,7 +277,7 @@ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = getNVRecord2Driver( GET_CAL_LOAD_CELL_SENSORS, (U08*)&loadCellsCalRecord, sizeof( DG_LOAD_CELLS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_LOAD_CELLS, ALARM_ID_DG_LOAD_CELLS_INVALID_CAL_RECORD ); + NUM_OF_CAL_DATA_LOAD_CELLS, ALARM_ID_DG_LOAD_CELLS_INVALID_CAL_RECORD ); if ( TRUE == calStatus ) { @@ -293,6 +293,29 @@ /*********************************************************************//** * @brief + * The isLoadCellTared function returns load cell tare status + * for a given load cell ID. + * @details Inputs: none + * @details Outputs: load cell tare status + * @param loadCellID ID of load cell tare status + *************************************************************************/ +BOOL isLoadCellTared( LOAD_CELL_ID_T loadCellID ) +{ + BOOL tared = FALSE; + + if ( fabs( loadcells[ loadCellID ].autoCalOffset ) < NEARLY_ZERO ) + { + tared = FALSE; + } + else + { + tared = TRUE; + } + return tared; +} + +/*********************************************************************//** + * @brief * The tareLoadCell function sets the load cell auto calibration offset * for a given load cell ID. * @details Inputs: none @@ -302,9 +325,8 @@ void tareLoadCell( LOAD_CELL_ID_T loadCellID ) { BOOL isWeightOutOfRange = FALSE; + F32 weight = getLoadCellSmallFilteredWeight( loadCellID ); - F32 weight = getLoadCellSmallFilteredWeight( loadCellID ); - // Check if the load cell is being tared for the first time if ( hasLoadCellBeenTared[ loadCellID ] != TRUE ) { @@ -474,31 +496,38 @@ *************************************************************************/ static void monitorLoadCellsPrimaryBackupDriftOutOfRange( void ) { - // TODO do we need this function at all? - F32 drift; + F32 drift = 0.0; + F32 loadCellADrift = 0.0; + F32 loadCellBDrift = 0.0; + BOOL isDriftOutOfRange = FALSE; - F32 loadCellADrift = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - + // Test is valid after load cells are tared + if ( isLoadCellTared( LOAD_CELL_RESERVOIR_1_PRIMARY ) && isLoadCellTared( LOAD_CELL_RESERVOIR_1_BACKUP ) ) + { + loadCellADrift = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ) ); - - F32 loadCellBDrift = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - + } + if ( isLoadCellTared( LOAD_CELL_RESERVOIR_2_PRIMARY ) && isLoadCellTared( LOAD_CELL_RESERVOIR_2_BACKUP ) ) + { + loadCellBDrift = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_BACKUP ) ); + } - BOOL isDriftOutOfRange = ( loadCellADrift > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ) || - ( loadCellBDrift > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ); - - if ( TRUE == isDriftOutOfRange ) + if ( ( loadCellADrift > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ) || + ( loadCellBDrift > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ) ) { + isDriftOutOfRange = TRUE; drift = ( loadCellADrift > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ? loadCellADrift : loadCellBDrift ); } else { + isDriftOutOfRange = FALSE; // Pick the biggest drift in between the two load cells when none of the is above range drift = ( loadCellADrift > loadCellBDrift ? loadCellADrift : loadCellBDrift ); } - // TODO this alarm is disabled until a better drift algorithm is figured out. Drift check might be removed from the load cells - //checkPersistentAlarm( ALARM_ID_DG_LOAD_CELL_PRIMARY_BACKUP_DRIFT_OUT_OF_RANGE, isDriftOutOfRange, drift, - // LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ); + checkPersistentAlarm( ALARM_ID_DG_LOAD_CELL_PRIMARY_BACKUP_DRIFT_OUT_OF_RANGE, isDriftOutOfRange, drift, + LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ); } Index: firmware/App/Modes/ModeService.c =================================================================== diff -u -rca42d4bb2bde856750630050d393d6ae26a4e957 -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Modes/ModeService.c (.../ModeService.c) (revision ca42d4bb2bde856750630050d393d6ae26a4e957) +++ firmware/App/Modes/ModeService.c (.../ModeService.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file ModeService.c * * @author (last) Dara Navaei -* @date (last) 24-Oct-2021 +* @date (last) 03-Aug-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r439e62fe1d95d3e5398bd396e0955c1ac1ba1417 -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 439e62fe1d95d3e5398bd396e0955c1ac1ba1417) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file OperationModes.c * * @author (last) Dara Navaei -* @date (last) 25-Apr-2022 +* @date (last) 15-Jul-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -65,7 +65,7 @@ /* SERV */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* INIT */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_INIT, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* STAN */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_GENE, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM }, - /* SOLO */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM /*DG_MODE_NLEG*/ }, // TODO for testing only + /* SOLO */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM /*DG_MODE_NLEG*/ }, // TODO for testing only /* GENE */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_GENE, DG_MODE_FILL, DG_MODE_DRAI, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* FILL */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_GENE, DG_MODE_FILL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* DRAI */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_GENE, DG_MODE_NLEG, DG_MODE_DRAI, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rca42d4bb2bde856750630050d393d6ae26a4e957 -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision ca42d4bb2bde856750630050d393d6ae26a4e957) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file AlarmMgmtSWFaults.h * * @author (last) Dara Navaei -* @date (last) 24-May-2022 +* @date (last) 03-Aug-2022 * * @author (original) Quang Nguyen * @date (original) 20-May-2021 @@ -67,7 +67,7 @@ SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, SW_FAULT_ID_HEATERS_INVALID_EXEC_STATE, - SW_FAULT_ID______AVAILABLE, + SW_FAULT_ID_INVALID_EMSTAT_CONDUCTIVITY_BOARD_SELECTED, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, // 40 SW_FAULT_ID_VALVES_INVALID_VALVE_ID, SW_FAULT_ID_CAN_PARITY_ERROR, Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r965eb10d9407c25e8cf334623ad45e126cecee97 -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 965eb10d9407c25e8cf334623ad45e126cecee97) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file Reservoirs.c * * @author (last) Dara Navaei -* @date (last) 23-May-2022 +* @date (last) 03-Aug-2022 * * @author (original) Sean * @date (original) 18-Mar-2020 @@ -17,6 +17,7 @@ #include // for memcpy() +#include "ConcentratePumps.h" #include "DrainPump.h" #include "Heaters.h" #include "LoadCell.h" @@ -50,6 +51,7 @@ #define MAX_REDUNDANT_LOAD_CELL_DIFF 50.0F ///< Maximum difference in redundant load cells when determining if fill completed. #define MAX_DRAIN_RPM_MLP 2400.0F ///< Maximum drain RPM in mL/min. #define DATA_PUBLISH_COUNTER_START_COUNT 5 ///< Data publish counter start count. +#define ENVIRONMENT_TEMPERATURE_C 23.5F ///< Device's environment temperature in C. // TODO add this to the cal records // ********** private data ********** @@ -66,6 +68,9 @@ F32 tempReservoirEndFill; ///< Temperature reservoir at the end of the fill in C. F32 tempTargetTrimmer; ///< Temperature target trimmer heater in C. F32 flowTargetDialysateLPM; ///< Dialysate target flow rate in L/min. + F32 tempRsrvr0ActualTrimmer; ///< Temperature actual reservoir in C. + F32 tempFillMixAvgTrimmer; ///< Temperature fill mix average trimmer in C. + F32 tempRsrvrEndFillTrimmer; ///< Temperature reservoir end fill trimmer in C. } HEATERS_TEMPERATURE_CALC_DATA_T; /// Reservoirs previous status @@ -94,7 +99,7 @@ static DG_RESERVOIR_VOLUME_RECORD_T reservoirsCalRecord; ///< DG reservoirs non-volatile record. static DG_HEATING_CAL_RECORD_T heatingConstsCalRecord; ///< DG heating calibration record. static F32 targetFillFlowRateLPM; ///< Target fill flow rate in L/min. -static BOOL isThisTheFirstCycle = TRUE; ///< Boolean flag to indicate whether this is the first cycle. +static BOOL isThisTheFirstCycle; ///< Boolean flag to indicate whether this is the first cycle. static RESERVOIRS_PREVIOUS_STATUS reservoirPreviousStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoirs previous status. /*********************************************************************//** @@ -142,8 +147,7 @@ // publish active reservoir, fill/drain volume targets at 1 Hz. if ( ++dataPublishCounter >= RESERVOIR_DATA_PUB_INTERVAL ) { - RESERVOIR_DATA_T data; - + RESERVOIR_DATA_T data; data.activeReservoir = getU32OverrideValue( &activeReservoir ); data.fillToVolumeMl = getU32OverrideValue( &fillVolumeTargetMl ); data.drainToVolumeMl = getU32OverrideValue( &drainVolumeTargetMl ); @@ -204,9 +208,8 @@ void setActiveReservoirCmd( DG_RESERVOIR_ID_T resID ) { DG_CMD_RESPONSE_T cmdResponse; - - cmdResponse.commandID = DG_CMD_SWITCH_RESERVOIR; - cmdResponse.rejected = TRUE; + cmdResponse.commandID = DG_CMD_SWITCH_RESERVOIR; + cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; // switch reservoir command only valid in generation idle mode @@ -257,8 +260,8 @@ { DG_CMD_RESPONSE_T cmdResponse; - cmdResponse.commandID = DG_CMD_VALVE_SETTING; - cmdResponse.rejected = TRUE; + cmdResponse.commandID = DG_CMD_VALVE_SETTING; + cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; // valve setting command only valid in generation idle mode @@ -535,9 +538,6 @@ heatersTempCalc.tempTargetTrimmer = params.trimmerTargetTemperature; heatersTempCalc.flowTargetDialysateLPM = params.dialysateFlowLPM; - // Set the trimmer heater target temperature since this value is needed for calculations - setHeaterTargetTemperature( DG_TRIMMER_HEATER, heatersTempCalc.tempTargetTrimmer ); - // Check if this is the first time that the dialysate heating parameters are set in DG if ( TRUE == isThisTheFirstCycle ) { @@ -574,7 +574,7 @@ F32 fillPart = ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ) * tempAvgFill; F32 tempReservoir0Actual = ultrafilterPart + fillPart; - F32 tempReservoirEndfillActual = tempReservoir0Actual + ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RsrvrTauCPerMS ); + F32 tempReservoirEndfillActual = tempReservoir0Actual + ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * RsrvrTauCPerMS ); heatersTempCalc.tempReservoirUseActual = tempReservoirEndfillActual + ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); } else @@ -589,19 +589,24 @@ * @brief * The getPrimaryHeaterTargetTemperature function calculates the primary * heater target temperature and returns target temperature value. - * @details Inputs: none + * @details Inputs: heatingConstsCalRecord * @details Outputs: heatersTempCalc * @return primary heater target temperature *************************************************************************/ F32 getPrimaryHeaterTargetTemperature( void ) { // TODO once the equations are solidified, add the equations as comments to the lines - F32 tempTarget = 0.0; - F32 targetFillVolML = getTargetFillVolumeML(); - F32 UFTimeConstant = 0.0; - F32 tempLastFill = getLastFillTemperature(); - F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); - F32 RsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 tempTarget = 0.0; + F32 priTargetTemp = 0.0; + F32 targetFillVolML = getTargetFillVolumeML(); + F32 UFTimeConstant = 0.0; + F32 tempLastFill = getLastFillTemperature(); + F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 RsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 targetROFlowLPM = getTargetROPumpFlowRateLPM(); + F32 tgtAicdFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP1_ACID ) / ML_PER_LITER; + F32 tgtBicarbFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP2_BICARB ) / ML_PER_LITER; + F32 tgtTotalFlowLPM = targetROFlowLPM + tgtAicdFlowLPM + tgtBicarbFlowLPM; if ( FALSE == isThisTheFirstFill() ) { @@ -611,7 +616,7 @@ tempReservoirUse = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; heatersTempCalc.tempReservoirEndFill = tempReservoirUse - ( heatersTempCalc.timeReservoirFill2SwitchMS * RsrvrTauCPerMS ); - heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * 0.5 ) * RsrvrTauCPerMS ); + heatersTempCalc.tempReservoir0 = heatersTempCalc.tempReservoirEndFill - ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * RsrvrTauCPerMS ); heatersTempCalc.timeUFDecayMS = (F32)heatersTempCalc.timeReservoirCycleMS - heatersTempCalc.timeReservoirFillMS; UFTimeConstant = heatersTempCalc.timeUFDecayMS * UFTauCPerMS; @@ -626,11 +631,57 @@ tempTarget = heatersTempCalc.tempTargetTrimmer + RESERVOIR_EXTRA_TEMPERATURE; } - return tempTarget; + if ( targetROFlowLPM > 0 ) + { + priTargetTemp = ( tempTarget * ( tgtTotalFlowLPM / targetROFlowLPM ) ) - ( ENVIRONMENT_TEMPERATURE_C * ( tgtAicdFlowLPM / targetROFlowLPM ) ) - + ( ENVIRONMENT_TEMPERATURE_C * ( tgtBicarbFlowLPM / targetROFlowLPM ) ); + } + + return priTargetTemp; } /*********************************************************************//** * @brief + * The getTrimmerHeaterTargetTemperature function calculates the trimmer + * heater target temperature and returns target temperature value. + * @details Inputs: heatingConstsCalRecord + * @details Outputs: heatersTempCalc + * @return primary heater target temperature + *************************************************************************/ +F32 getTrimmerHeaterTargetTemperature( void ) +{ + F32 tempRsrvrActual = 0.0; + F32 fillROAvgActual = getAvgFillTemperature(); + F32 targetFillVolML = getTargetFillVolumeML(); + F32 UFTauCPerMS = heatingConstsCalRecord.ultrafilterTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 tempLastFill = getLastFillTemperature(); + F32 tempUFFill = tempLastFill + ( heatersTempCalc.timeUFDecayMS * UFTauCPerMS ); + F32 rsrvrTauCPerMS = heatingConstsCalRecord.reservoirTempTauCPerMin / ( SEC_PER_MIN * MS_PER_SECOND ); + F32 targetROFlowLPM = getTargetROPumpFlowRateLPM(); + F32 tgtAicdFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP1_ACID ) / ML_PER_LITER; + F32 tgtBicarbFlowLPM = getConcentratePumpTargetFlowMLPM( CONCENTRATEPUMPS_CP2_BICARB ) / ML_PER_LITER; + F32 tgtTotalFlowLPM = targetROFlowLPM + tgtAicdFlowLPM + tgtBicarbFlowLPM; + + if ( tgtTotalFlowLPM > 0 ) + { + heatersTempCalc.tempFillMixAvgTrimmer = ( fillROAvgActual * ( tgtTotalFlowLPM / targetROFlowLPM ) ) + + ( ENVIRONMENT_TEMPERATURE_C * ( tgtAicdFlowLPM / targetROFlowLPM ) ) + + ( ENVIRONMENT_TEMPERATURE_C * ( tgtBicarbFlowLPM / targetROFlowLPM ) ); + + heatersTempCalc.tempRsrvr0ActualTrimmer = ( ( heatingConstsCalRecord.ultrafilterVolmL / targetFillVolML ) * tempUFFill ) + + ( ( ( targetFillVolML - heatingConstsCalRecord.ultrafilterVolmL ) / targetFillVolML ) * + heatersTempCalc.tempFillMixAvgTrimmer ); + + heatersTempCalc.tempRsrvrEndFillTrimmer = heatersTempCalc.tempRsrvr0ActualTrimmer + ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * rsrvrTauCPerMS ); + + tempRsrvrActual = heatersTempCalc.tempRsrvrEndFillTrimmer + ( ( heatersTempCalc.timeReservoirFillMS * HALF ) * rsrvrTauCPerMS ); + } + + return tempRsrvrActual; +} + +/*********************************************************************//** + * @brief * The getReservoirsCalRecord function returns the reservoirs' calibration * record. * @details Inputs: reservoirsCalRecord Index: firmware/App/Services/Reservoirs.h =================================================================== diff -u -r965eb10d9407c25e8cf334623ad45e126cecee97 -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 965eb10d9407c25e8cf334623ad45e126cecee97) +++ firmware/App/Services/Reservoirs.h (.../Reservoirs.h) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file Reservoirs.h * * @author (last) Dara Navaei -* @date (last) 07-Mar-2022 +* @date (last) 31-May-2022 * * @author (original) Sean * @date (original) 18-Mar-2020 @@ -85,6 +85,9 @@ F32 tempAvgFill; ///< Average fill temperature F32 tempLastFill; ///< Last fill temperature F32 timereservoirFill; ///< Reservoir fill time in milliseconds + F32 tempRsrvr0ActualTrimmer; ///< Temperature actual reservoir in C. + F32 tempFillMixAvgTrimmer; ///< Temperature fill mix average trimmer in C. + F32 tempRsrvrEndFillTrimmer; ///< Temperature reservoir end fill trimmer in C. } RESERVOIR_DATA_T; // ********** public function prototypes ********** @@ -109,6 +112,7 @@ F32 getTargetFillFlowRateLPM( void ); F32 getReservoirActualTemperature( void ); F32 getPrimaryHeaterTargetTemperature( void ); +F32 getTrimmerHeaterTargetTemperature( void ); F32 getTargetDialysateFlowLPM( void ); DG_RESERVOIR_VOLUME_RECORD_T getReservoirsCalRecord( void ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -re26af49fdfca8aa748d463cdcb610f9a835e943a -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e26af49fdfca8aa748d463cdcb610f9a835e943a) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file SystemComm.c * * @author (last) Dara Navaei -* @date (last) 23-May-2022 +* @date (last) 12-Jul-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -655,7 +655,6 @@ if ( TRUE == didTimeout( timeOfLastHDCheckIn, HD_COMM_TIMEOUT_IN_MS ) ) { hdCommunicationStatus.data = FALSE; - activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); } } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r7e4b720b0f1067fb1d0714626ef6c058e7c68fef -r849d55bf09a76e59424878b1ae4dac4b51ead3a9 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 7e4b720b0f1067fb1d0714626ef6c058e7c68fef) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 849d55bf09a76e59424878b1ae4dac4b51ead3a9) @@ -8,7 +8,7 @@ * @file SystemCommMessages.c * * @author (last) Dara Navaei -* @date (last) 25-May-2022 +* @date (last) 21-Jun-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -1093,10 +1093,39 @@ if ( message->hdr.payloadLen == sizeof( TRIMMER_HEATER_CMD_T ) ) { TRIMMER_HEATER_CMD_T heaterCmd; + DG_CMD_RESPONSE_T cmdResponse; + cmdResponse.commandID = DG_CMD_START_TRIMMER_HEATER; + cmdResponse.rejected = FALSE; + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; + result = TRUE; - result = TRUE; memcpy( &heaterCmd, message->payload, sizeof( TRIMMER_HEATER_CMD_T ) ); - handleTrimmerHeaterCmd( &heaterCmd ); + + if ( TRUE == heaterCmd.startHeater ) + { + BOOL isSet = setHeaterTargetTemperature( DG_TRIMMER_HEATER, heaterCmd.targetTemp ); + + if ( TRUE == isSet ) + { +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_TRIMMER_HEATER ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + startHeater( DG_TRIMMER_HEATER ); + } + } + else + { + cmdResponse.rejected = TRUE; + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; + } + } + else + { + stopHeater( DG_TRIMMER_HEATER ); + } + + sendCommandResponseMsg( &cmdResponse ); } sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result );