Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r4b358e1af8512dd9a0e948ef7c534b6af393b611 -r44a100f8e5210a02c23b8fcc4527d8e96d577381 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 4b358e1af8512dd9a0e948ef7c534b6af393b611) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) @@ -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" @@ -44,9 +45,11 @@ // ********** private definitions ********** #define MAX_TREATMENT_TIME_MINUTES ( 8 * MIN_PER_HOUR ) ///< Maximum treatment time (in minutes). +#ifndef ALLOW_1_MIN_TREATMENT_DURATION #define MIN_TREATMENT_TIME_MINUTES ( 1 * MIN_PER_HOUR ) ///< Minimum treatment time (in minutes). -#define MAX_UF_RATE_ML_MIN ( (F32)2500 / (F32)MIN_PER_HOUR ) ///< Maximum ultrafiltration rate (in mL/min). -#define MAX_UF_VOLUME_ML ( 8 * ML_PER_LITER ) ///< Maximum ultrafiltration volume (in mL). +#else +#define MIN_TREATMENT_TIME_MINUTES ( 1 ) ///< Minimum treatment time (in minutes). +#endif #define MAX_DIALYSATE_VOLUME_ML ( 150 * ML_PER_LITER ) ///< Maximum dialysate volume (in mL). #define USER_CONFIRM_CHANGE_TIMEOUT_MS ( 60 * MS_PER_SECOND ) ///< Require user to confirm UF volume change within this time. @@ -58,6 +61,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 ); +/// Interval (ms/task time) at which the treatment periodic data is logged. +static const U32 TREATMENT_PERIODIC_DATA_LOG_INTERVAL = ( MS_PER_SECOND ); #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. @@ -99,11 +106,20 @@ 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 U32 lastTreatmentPeriodicDataPublishTimeStamp; ///< Last treatment 30 minutes periodic data publish time stamp. +static U32 lastTreatmentPeriodicDataCollectTimeStamp; ///< Last treatment periodic data collect time stamp. +static F32 lastUltraFiltrationVolume_mL; ///< Last 30 minutes ultra filtration volume in mL. +static F32 bloodFlowRateTotal_mL_min; ///< Blood flow rate total, used to calculate blood flow rate average over 30 minutes. +static F32 dialysateFlowRateTotal_mL_min; ///< Dialysate flow rate total, used to calculate dialysate flow rate average over 30 minutes. +static F32 arterialPressureTotal_mmHg; ///< Arterial pressure total, used to calculate arterial pressure average over 30 minutes. +static F32 venousPressureTotal_mmHg; ///< 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 ); @@ -125,7 +141,7 @@ bloodIsPrimed = FALSE; treatmentCompleted = FALSE; - rinsebackDone = TRUE; + rinsebackDone = FALSE; treatmentTimeMS = 0; lastTreatmentTimeStamp = 0; @@ -146,6 +162,14 @@ pendingUFVolumeChange = 0.0; pendingUFRateChange = 0.0; pendingTreatmentTimeChange = 0; + + lastTreatmentPeriodicDataPublishTimeStamp = 0; + lastTreatmentPeriodicDataCollectTimeStamp = 0; + lastUltraFiltrationVolume_mL = 0.0; + bloodFlowRateTotal_mL_min = 0.0; + dialysateFlowRateTotal_mL_min = 0.0; + arterialPressureTotal_mmHg = 0.0; + venousPressureTotal_mmHg = 0.0; } /*********************************************************************//** @@ -241,6 +265,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 +498,7 @@ // Broadcast treatment data broadcastTreatmentTimeAndState(); broadcastTreatmentSettingsRanges(); + broadcastTreatmentPeriodicData(); // Manage air trap control execAirTrapMonitorTreatment(); @@ -625,6 +663,7 @@ // Otherwise execute state machine for treatment stop sub-mode else { + execTreatmentReservoirMgmt(); execTreatmentStop(); } @@ -1221,7 +1260,49 @@ } } +/*********************************************************************//** + * @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 ) +{ + U32 const timeElapsedSinceLastCollect_ms = calcTimeBetween( lastTreatmentPeriodicDataCollectTimeStamp, treatmentTimeMS ); + if ( timeElapsedSinceLastCollect_ms >= TREATMENT_PERIODIC_DATA_LOG_INTERVAL ) + { + lastTreatmentPeriodicDataCollectTimeStamp = treatmentTimeMS; + bloodFlowRateTotal_mL_min += getMeasuredBloodFlowRate(); + dialysateFlowRateTotal_mL_min += getMeasuredDialInFlowRate(); + arterialPressureTotal_mmHg += getMeasuredArterialPressure(); + venousPressureTotal_mmHg += getMeasuredVenousPressure(); + } + + if ( calcTimeBetween( lastTreatmentPeriodicDataPublishTimeStamp, treatmentTimeMS ) >= TREATMENT_PERIODIC_DATA_PUB_INTERVAL ) + { + TREATMENT_LOG_DATA_PERIODIC_T periodTreatmentData; + U32 const numberOfDataPoint = TREATMENT_PERIODIC_DATA_PUB_INTERVAL / TREATMENT_PERIODIC_DATA_LOG_INTERVAL; + + periodTreatmentData.avgUFRate = ( getUltrafiltrationVolumeCollected() - lastUltraFiltrationVolume_mL ) / ( numberOfDataPoint / SEC_PER_MIN ); + periodTreatmentData.avgBloodFlowRate = bloodFlowRateTotal_mL_min / numberOfDataPoint; + periodTreatmentData.avgDialysateFlowRate = dialysateFlowRateTotal_mL_min / numberOfDataPoint; + periodTreatmentData.avgArterialPressure = arterialPressureTotal_mmHg / numberOfDataPoint; + periodTreatmentData.avgVenousPressure = venousPressureTotal_mmHg / numberOfDataPoint; + + lastTreatmentPeriodicDataPublishTimeStamp = treatmentTimeMS; + lastUltraFiltrationVolume_mL = getUltrafiltrationVolumeCollected(); + bloodFlowRateTotal_mL_min = 0.0; + dialysateFlowRateTotal_mL_min = 0.0; + arterialPressureTotal_mmHg = 0.0; + venousPressureTotal_mmHg = 0.0; + sendTreatmentPeriodicDataToUI( &periodTreatmentData ); + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/