Index: firmware/App/Drivers/Battery.c =================================================================== diff -u -r315969d00060073e112c4619946c13a61f68bcbd -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Drivers/Battery.c (.../Battery.c) (revision 315969d00060073e112c4619946c13a61f68bcbd) +++ firmware/App/Drivers/Battery.c (.../Battery.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -83,7 +83,6 @@ { lastBatteryMonitorTime = getMSTimerCount(); -#ifndef DISABLE_BATT_COMM if ( FALSE == hasBatteryChargerStatus ) { hasBatteryChargerStatus = TRUE; @@ -96,7 +95,10 @@ { if ( ++lostACPowerPersistentCount > AC_POWER_LOST_PERSISTENT_COUNT ) { + +#ifndef DISABLE_BATT_COMM SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_AC_POWER_LOST, batteryStatus ); +#endif } } else @@ -115,7 +117,6 @@ getBatteryData( BATTERY_PACK_REL_STATE_OF_CHARGE_CMD, &batteryRelStateOfCharge_pct ); } } -#endif } } @@ -176,7 +177,9 @@ else { generateStopCondition(); +#ifndef DISABLE_BATT_COMM SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BATTERY_COMM_FAULT, slaveAddr ); +#endif } } Index: firmware/App/HDCommon.h =================================================================== diff -u -r92c04526739f32e904fe258bd622aa08734ce343 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 92c04526739f32e904fe258bd622aa08734ce343) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -66,7 +66,7 @@ #define SKIP_CONSUMABLE_TESTS 1 // Skip pre-treatment consumable Self-tests #define SKIP_DRY_SELF_TESTS 1 // Skip pre-treatment dry self-tests #define SKIP_UI_INTERACTION 1 // Skip UI interaction. -// #define DISABLE_BATT_COMM 1 // Disable battery communication. + #define DISABLE_BATT_COMM 1 // Disable battery communication. #define SKIP_AIR_BUBBLE_CHECK 1 // Skip air bubble detector self-test. #define DISABLE_OCCLUSION_SELF_TEST 1 // Skip occlusion sensor self-test. #define SKIP_CARTRIDGE_REMOVAL 1 // Skip cartridge removal check Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -rc14a0220256e92a6339a444a3e1bc85e159ccce3 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision c14a0220256e92a6339a444a3e1bc85e159ccce3) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -433,9 +433,7 @@ *************************************************************************/ F32 getUltrafiltrationVolumeCollected( void ) { - F32 result = measUFVolume; - - return result; + return measUFVolume; } /*********************************************************************//** Index: firmware/App/Modes/ModePostTreat.c =================================================================== diff -u -re5d1d67106a93a6cd1b5692b586625d715732e2f -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision e5d1d67106a93a6cd1b5692b586625d715732e2f) +++ firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -27,7 +27,9 @@ #include "OperationModes.h" #include "PresOccl.h" #include "ModePostTreat.h" +#include "ModeTreatment.h" #include "ModeTreatmentParams.h" +#include "SampleWater.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -79,6 +81,7 @@ static HD_POST_TREATMENT_STATE_T handlePostTreatmentDrainReservoirsState( void ); static HD_POST_TREATMENT_STATE_T handlePostTreatmentVerifyState( void ); +static void collectTreatmentLogData( void ); static void execDrainReservoirs( void ); static BOOL isReservoirDrainStarted( void ); static DRAIN_STATE_T handleDrainFirstReservoirStartState( void ); @@ -138,6 +141,8 @@ signalBloodPumpHardStop(); signalDialOutPumpHardStop(); signalDialInPumpHardStop(); + + collectTreatmentLogData(); } /*********************************************************************//** @@ -376,6 +381,54 @@ /*********************************************************************//** * @brief + * The collectTreatmentLogData function collects treatment data. + * @details Inputs: none + * @details Outputs: collected treatment data + * @return none + *************************************************************************/ +static void collectTreatmentLogData( void ) +{ + // TODO: Fill in missing log data + treatmentLogData.bloodFlowRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); + treatmentLogData.dialysateFlowRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + treatmentLogData.treatmentDuration_min = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + treatmentLogData.actualTreatmentDur_min = getActualTreatmentTimeMins(); + + treatmentLogData.acidConcentrate = getTreatmentParameterU32( TREATMENT_PARAM_ACID_CONCENTRATE ); + treatmentLogData.bicarbConcentrate = getTreatmentParameterU32( TREATMENT_PARAM_BICARB_CONCENTRATE ); +// treatmentLogData.potassiumConcentration = 0; +// treatmentLogData.calciumConcentration = 0; +// treatmentLogData.bicarbonateConcentration = 0; +// treatmentLogData.sodiumConcentration = 0; + + treatmentLogData.dialysateTemperature_degC = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + treatmentLogData.dialyzerType = getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ); +// treatmentLogData.treatmentDateAndTime = 0; + +// treatmentLogData.avgBloodFlow_mL_min; +// treatmentLogData.avgDialysateFlow_mL_min; +// treatmentLogData.dialysateVolumeUsed_L; +// treatmentLogData.avgDialysateTemperature_degC; + + treatmentLogData.targetUFVolume_L = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + treatmentLogData.actualUFVolume_L = getTotalMeasuredUFVolumeInMl(); + treatmentLogData.targetUFRate_mL_min = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) * ML_PER_LITER / treatmentLogData.treatmentDuration_min; + treatmentLogData.actualUFRate_mL_min = getTotalMeasuredUFVolumeInMl() / treatmentLogData.actualTreatmentDur_min; +// treatmentLogData.salineBolusVolume_mL; + +// treatmentLogData.heparinType; + treatmentLogData.heparinBolusVolume_mL = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + treatmentLogData.heparinDispenseRate_mL_hr = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + treatmentLogData.heparinPreStop_min = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); +// treatmentLogData.heparinDeliveredVolume_mL; + +// treatmentLogData.endTreatmentEarlyAlarm; +// treatmentLogData.deviceID; + treatmentLogData.waterSampleTestResult = (U32)getSampleWaterResult(); +} + +/*********************************************************************//** + * @brief * The execDrainReservoirs function executes the drain reservoirs operation. * @details Inputs: currentDrainReservoirState * @details Outputs: currentDrainReservoirState Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r4b358e1af8512dd9a0e948ef7c534b6af393b611 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 4b358e1af8512dd9a0e948ef7c534b6af393b611) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -27,6 +27,7 @@ #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "Rinseback.h" +#include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -58,6 +59,10 @@ static const U32 TREATMENT_STATE_DATA_PUB_INTERVAL = ( 250 / TASK_GENERAL_INTERVAL ); /// Interval (ms/task time) at which updated, valid treatment setting ranges are published on the CAN bus. static const U32 TREATMENT_SETTINGS_RANGES_PUB_INTERVAL = ( ( 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ); +/// Interval (ms/task time) at which the treatment periodic data is published on the CAN bus. +static const U32 TREATMENT_PERIODIC_DATA_PUB_INTERVAL = ( ( 30 * SEC_PER_MIN * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ); +/// Interval (ms/task time) at which the treatment periodic data is logged. +static const U32 TREATMENT_PERIODIC_DATA_LOG_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); #define CALC_ELAPSED_TREAT_TIME_IN_SECS() ( treatmentTimeMS / MS_PER_SECOND ) ///< Macro to calculate the elapsed treatment time in seconds. /// Macro to calculate the elapsed treatment time in minutes. @@ -84,6 +89,7 @@ static U32 treatmentTimeBroadcastTimerCtr; ///< Treatment time data broadcast timer counter used to schedule when to transmit data. static U32 treatmentStateBroadcastTimerCtr; ///< Treatment state data broadcast timer counter used to schedule when to transmit data. static U32 treatmentParamsRangesBroadcastTimerCtr; ///< Treatment parameter ranges broadcast timer counter used to schedule when to transmit updated ranges. +static U32 treatmentPeriodDataBroadcastTimerCtr; ///< Treatment 30 minutes periodic data broadcast timer counter used to schedule when to transmit data. static BOOL resumeTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment resume. static BOOL initiateRinsebackAlarmResponseRequest; ///< Flag indicates user has requested rinseback. @@ -99,11 +105,18 @@ static F32 pendingUFRateChange; ///< An ultrafiltration rate change (mL/min) is pending user confirmation. static U32 pendingTreatmentTimeChange; ///< A treatment time change (min) is pending user confirmation. +static F32 bloodFlowRateTotal; ///< Blood flow rate total, used to calculate blood flow rate average over 30 minutes. +static F32 dialysateFlowRateTotal; ///< Dialysate flow rate total, used to calculate dialysate flow rate average over 30 minutes. +static F32 ultraFiltrationRateTotal; ///< UF rate total, used to calculate UF rate average over 30 minutes. +static F32 arterialPressureTotal; ///< Arterial pressure total, used to calculate arterial pressure average over 30 minutes. +static F32 venousPressureTotal; ///< Venous pressure total, used to calculate venous pressure average over 30 minutes. + // ********** private function prototypes ********** static void resetSignalFlags( void ); static void resetAlarmSignalFlags( void ); static void broadcastTreatmentSettingsRanges( void ); +static void broadcastTreatmentPeriodicData(); static TREATMENT_STATE_T handleTreatmentStartState( void ); static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ); static TREATMENT_STATE_T handleTreatmentDialysisState( void ); @@ -132,6 +145,7 @@ treatmentTimeBroadcastTimerCtr = TREATMENT_TIME_DATA_PUB_INTERVAL; // So we send time data immediately when we begin treatment mode treatmentStateBroadcastTimerCtr = TREATMENT_STATE_DATA_PUB_INTERVAL; // So we send state data immediately when we begin treatment mode treatmentParamsRangesBroadcastTimerCtr = TREATMENT_SETTINGS_RANGES_PUB_INTERVAL; // So we send ranges immediately when we begin treatment mode + treatmentPeriodDataBroadcastTimerCtr = 0; presTreatmentTimeSecs = 0; presBloodFlowRate = 0; @@ -146,6 +160,12 @@ pendingUFVolumeChange = 0.0; pendingUFRateChange = 0.0; pendingTreatmentTimeChange = 0; + + bloodFlowRateTotal = 0.0; + dialysateFlowRateTotal = 0.0; + ultraFiltrationRateTotal = 0.0; + arterialPressureTotal = 0.0; + venousPressureTotal = 0.0; } /*********************************************************************//** @@ -241,6 +261,19 @@ /*********************************************************************//** * @brief + * The getActualTreatmentTimeMins function determines the actual treatment + * duration in minutes. + * @details Inputs: treatmentTimeMS + * @details Outputs: none + * @return The actual treatment duration in minutes. + *************************************************************************/ +U32 getActualTreatmentTimeMins( void ) +{ + return ( treatmentTimeMS / ( MS_PER_SECOND * SEC_PER_MIN ) ); +} + +/*********************************************************************//** + * @brief * The getRinsebackCompleted function determines whether a rinseback has been * completed (indicating blood-side circuit should be primarily saline). * @details Inputs: rinsebackDone @@ -461,6 +494,7 @@ // Broadcast treatment data broadcastTreatmentTimeAndState(); broadcastTreatmentSettingsRanges(); + broadcastTreatmentPeriodicData(); // Manage air trap control execAirTrapMonitorTreatment(); @@ -1221,7 +1255,48 @@ } } +/*********************************************************************//** + * @brief + * The broadcastTreatmentPeriodicData function computes and broadcasts + * periodic treatment data during treatment. + * @details Inputs: treatmentPeriodDataBroadcastTimerCtr + * @details Outputs: collected and sent average treatment data over 30 minutes + * @return none + *************************************************************************/ +static void broadcastTreatmentPeriodicData( void ) +{ + if ( ( treatmentPeriodDataBroadcastTimerCtr % TREATMENT_PERIODIC_DATA_LOG_INTERVAL ) == 0 ) + { + bloodFlowRateTotal += getMeasuredBloodFlowRate(); + dialysateFlowRateTotal += getMeasuredDialInFlowRate(); + ultraFiltrationRateTotal += getTotalMeasuredUFVolumeInMl() / getActualTreatmentTimeMins(); + arterialPressureTotal += getMeasuredArterialPressure(); + venousPressureTotal += getMeasuredVenousPressure(); + } + if ( ++treatmentPeriodDataBroadcastTimerCtr >= TREATMENT_PERIODIC_DATA_PUB_INTERVAL ) + { + U32 const numberOfDataPoint = TREATMENT_PERIODIC_DATA_PUB_INTERVAL / TREATMENT_PERIODIC_DATA_LOG_INTERVAL; + TREATMENT_LOG_DATA_PERIODIC_T periodTreatmentData; + + periodTreatmentData.timestamp = getRTCTimestamp(); + periodTreatmentData.avgBloodFlowRate += bloodFlowRateTotal / numberOfDataPoint; + periodTreatmentData.avgDialysateFlowRate += dialysateFlowRateTotal / numberOfDataPoint; + periodTreatmentData.avgUFRate += ultraFiltrationRateTotal / numberOfDataPoint; + periodTreatmentData.avgArterialPressure += arterialPressureTotal / numberOfDataPoint; + periodTreatmentData.avgVenousPressure += venousPressureTotal / numberOfDataPoint; + + treatmentPeriodDataBroadcastTimerCtr = 0; + bloodFlowRateTotal = 0.0; + dialysateFlowRateTotal = 0.0; + ultraFiltrationRateTotal = 0.0; + arterialPressureTotal = 0.0; + venousPressureTotal = 0.0; + sendTreatmentPeriodDataToUI( &periodTreatmentData ); + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -rac6532c81f2a6d4ad1c67420c22d59f6aeeaae13 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision ac6532c81f2a6d4ad1c67420c22d59f6aeeaae13) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -81,6 +81,17 @@ S32 venHighLimit; } PRESSURE_LIMIT_CHANGE_RESPONSE_T; +/// Payload record structure for the treatment log 30 minutes periodic data. +typedef struct +{ + U32 timestamp; + F32 avgBloodFlowRate; + F32 avgDialysateFlowRate; + F32 avgUFRate; + F32 avgArterialPressure; + F32 avgVenousPressure; +} TREATMENT_LOG_DATA_PERIODIC_T; + // ********** public function prototypes ********** void initTreatmentMode( void ); // Initialize this module @@ -96,6 +107,7 @@ TREATMENT_STATE_T getTreatmentState( void ); // Determine the current treatment sub-mode (state) BOOL isTreatmentCompleted( void ); // Determine whether the treatment has completed U32 getTreatmentTimeRemainingSecs( void ); // Determine number of seconds remaining in the treatment +U32 getActualTreatmentTimeMins( void ); // Determine the actual treatment duration in minutes BOOL getRinsebackCompleted( void ); // Determine whether a rinseback has been completed void setRinsebackIsCompleted( BOOL flag ); // Set whether a rinseback has been completed (T blocks rinseback option) BOOL getBloodIsPrimed( void ); // Determine whether the blood-side circuit of the dialyzer has been primed with blood Index: firmware/App/Modes/PreTreatmentRecirc.c =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Modes/PreTreatmentRecirc.c (.../PreTreatmentRecirc.c) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Modes/PreTreatmentRecirc.c (.../PreTreatmentRecirc.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "AirTrap.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "BloodFlow.h" @@ -158,6 +159,7 @@ setValveAirTrap( STATE_CLOSED ); cmdSetDGActiveReservoir( DG_RESERVOIR_1 ); cmdStartDGTrimmerHeater(); + startAirTrapControl(); setBloodPumpTargetFlowRate( BLOOD_PUMP_RECIRC_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialInPumpTargetFlowRate( DIALYSATE_PUMP_RECIRC_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); @@ -182,6 +184,7 @@ signalDialInPumpHardStop(); signalBloodPumpHardStop(); cmdStopDGTrimmerHeater(); + endAirTrapControl(); state = PRE_TREATMENT_RECIRC_STOPPED_STATE; } Index: firmware/App/Services/Integrity.c =================================================================== diff -u -r161dc3734f29dcd986683008a01c30114279698b -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Services/Integrity.c (.../Integrity.c) (revision 161dc3734f29dcd986683008a01c30114279698b) +++ firmware/App/Services/Integrity.c (.../Integrity.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -55,14 +55,25 @@ { CRC_TABLE const * const crcTablePtr = (CRC_TABLE *)CRC_TABLE_STARTING_ADDR; BOOL integrityStatus = TRUE; + SELF_TEST_STATUS_T result; U32 i; for ( i = 0; i < crcTablePtr->num_recs; ++i ) { integrityStatus &= checkCrc( &crcTablePtr->recs[i] ); } - return ( TRUE == integrityStatus ) ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED; + if ( TRUE == integrityStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + activateAlarmNoData( ALARM_ID_HD_INTEGRITY_POST_TEST_FAILED ); + } + + return result; } /*********************************************************************//** Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r6cd114c4deffb81e85c6cd3ebaf550fe4661efda -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 6cd114c4deffb81e85c6cd3ebaf550fe4661efda) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -538,8 +538,33 @@ result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); return result; -} +} + +/*********************************************************************//** + * @brief + * The sendTreatmentPeriodDataToUI function constructs a treatment period + * data message to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: Treatment parameter ranges msg constructed and queued. + * @param periodDataPtr treatment log period data record pointer + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTreatmentPeriodDataToUI( TREATMENT_LOG_DATA_PERIODIC_T * periodDataPtr ) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_TREATMENT_LOG_PERIOD_DATA; + msg.hdr.payloadLen = sizeof( TREATMENT_LOG_DATA_PERIODIC_T ); + + memcpy( payloadPtr, periodDataPtr, sizeof( TREATMENT_LOG_DATA_PERIODIC_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + return serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); +} + /*********************************************************************//**  * @brief  * The handlePatientDisconnectionConfirmCmd function handles user confirms Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r6cd114c4deffb81e85c6cd3ebaf550fe4661efda -r84bb8663dae71170e1743a2bed37b0aa47465b47 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 6cd114c4deffb81e85c6cd3ebaf550fe4661efda) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 84bb8663dae71170e1743a2bed37b0aa47465b47) @@ -149,6 +149,9 @@ // MSG_ID_TREATMENT_PARAM_CHANGE_RANGES BOOL sendTreatmentParamsRangesToUI( U32 minTime, U32 maxTime, F32 minUFVol, F32 maxUFVol, U32 minDialRate, U32 maxDialRate ); +// MSG_ID_HD_TREATMENT_LOG_PERIOD_DATA +BOOL sendTreatmentPeriodDataToUI( TREATMENT_LOG_DATA_PERIODIC_T * periodDataPtr ); + // MSG_ID_USER_BLOOD_DIAL_RATE_CHANGE_REQUEST void handleChangeBloodDialysateRateChangeRequest( MESSAGE_T *message );