Index: firmware/App/Controllers/HemoDiaFiltration.c =================================================================== diff -u -rfc697848283d289571f9d365b28acf44beb0883e -rfff7eb3560421130e0cd4788f84bce0a8ee7ff44 --- firmware/App/Controllers/HemoDiaFiltration.c (.../HemoDiaFiltration.c) (revision fc697848283d289571f9d365b28acf44beb0883e) +++ firmware/App/Controllers/HemoDiaFiltration.c (.../HemoDiaFiltration.c) (revision fff7eb3560421130e0cd4788f84bce0a8ee7ff44) @@ -15,15 +15,15 @@ * ***************************************************************************/ -#include "PIControllers.h" -#include "Pressures.h" +#include "BloodFlow.h" +#include "DDInterface.h" +#include "HemoDiaFiltration.h" #include "Messaging.h" #include "OperationModes.h" +#include "PIDControllers.h" +#include "Pressures.h" #include "TaskGeneral.h" #include "TestSupport.h" -#include "DDInterface.h" -#include "BloodFlow.h" -#include "HemoDiaFiltration.h" /** * @addtogroup Hemodiafiltration @@ -32,21 +32,15 @@ // ********** private definitions ********** -#define HDF_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the hemodiafiltration data published. -#define SECONDS_PER_MINUTE 60 ///< seconds per minute -#define HDF_CONTROL_PERIOD_SECONDS 2 ///< Interval at which the hemodiafiltration flow rate adjustment is executed in seconds -#define HDF_CONTROL_PERIOD_MS ( HDF_CONTROL_PERIOD_SECONDS * MS_PER_SECOND ) ///< Interval at which the hemodiafiltration flow rate adjustment is executed in milliseconds +#define HDF_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the hemodiafiltration data published. +#define SECONDS_PER_MINUTE 60 ///< seconds per minute +#define HDF_CONTROL_PERIOD_SECONDS 2 ///< Interval at which the hemodiafiltration flow rate adjustment is executed in seconds +#define HDF_CONTROL_PERIOD_MS ( HDF_CONTROL_PERIOD_SECONDS * MS_PER_SECOND ) ///< Interval at which the hemodiafiltration flow rate adjustment is executed in milliseconds #define HDF_CONTROL_INTERVAL ( HDF_CONTROL_PERIOD_MS / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the peroidic hemodiafiltration flow rate is calculated. #define ZERO_RATE 0.0F ///< Zero value. #define SUB_PUMP_PRESSURE_CONTROL_P_COEFFICIENT 0.5F ///< P term for Sub pump pressure control. #define SUB_PUMP_PRESSURE_CONTROL_I_COEFFICIENT 5.0F ///< I term for Sub pump pressure control. -// Parameters that will be set in some other place , set here for testing -#define HDF_MAX_FILTRATION_FRACTION 0.35F ///< HDF maximum filtration fraction (Qs+Quf)/Qb -#define HDF_MAX_TMP 400.0F ///< HDF maximum TMP - trans-membrane pressure = (Pb - Pd) -#define HDF_MAX_RATE 200.0F ///< Maximum substitution flow rate - - // ********** private data ********** static HDF_EXEC_STATE_T hdfExecState; ///< Current hemodiafiltration executive state. @@ -62,8 +56,6 @@ static BOOL isHDFRateUpdated; ///< flag indicating to update HDF rate needed. static BOOL reachedMaximumHDFVolume; ///< flag indicating that the current HDF volume has reached the maximum volume. static F32 hdfMaxFiltrationFraction; ///< Current HDF maximum filtration fraction. -static F32 hdfMaxTMP; ///< Current HDF maximum TMP in mmHg. -static F32 hdfMaxRate; ///< Current HDF maximum flow rate in ml/min. static OVERRIDE_U32_T hdfDataPublishInterval; ///< Hemodiafiltration data publish interval. // ********** private function prototypes ********** @@ -84,7 +76,7 @@ void initHemodiafiltration( void ) { // Initialize substitution pump PI controller to target pressure - initializePIController( PI_CONTROLLER_ID_SUB_PUMP_PRES, ZERO_RATE, SUB_PUMP_PRESSURE_CONTROL_P_COEFFICIENT, SUB_PUMP_PRESSURE_CONTROL_I_COEFFICIENT, + initializePIDController( PID_CONTROLLER_ID_SUB_PUMP_PRES, ZERO_RATE, SUB_PUMP_PRESSURE_CONTROL_P_COEFFICIENT, SUB_PUMP_PRESSURE_CONTROL_I_COEFFICIENT, 0.0F, ZERO_RATE, HDF_MAX_RATE, FALSE, 0 ); hdfExecState = TD_HDF_PAUSED; @@ -102,8 +94,6 @@ hdfCurrentVolume = 0.0; reachedMaximumHDFVolume = FALSE; hdfMaxFiltrationFraction = HDF_MAX_FILTRATION_FRACTION; - hdfMaxTMP = HDF_MAX_TMP; - hdfMaxRate = HDF_MAX_RATE; hdfDataPublicationTimerCounter = 0; isHDFRateUpdated = FALSE; } @@ -178,21 +168,23 @@ if ( FALSE == reachedMaximumHDFVolume && TRUE == isHemodiafiltrationRequested ) { + // manual rate set, use that as the proposed rate if ( hdfManualRate > ZERO_RATE ) - { // manual rate set, use that as the proposed rate + { hdfCurrentRate = CheckHDFRate( hdfManualRate ); - } - else - { // TMP control, resume with previous HDF rate - // TODO: make sure that hdfCurrentRate is not 0 if HDF is actually wanted (volume not > max) - hdfCurrentRate = CheckHDFRate( hdfCurrentRate ); - if ( hdfCurrentRate > ZERO_RATE ) - { - resetPIController( PI_CONTROLLER_ID_SUB_PUMP_PRES, hdfCurrentRate, 0.0F ); + } + else + { + // TMP control, resume with previous HDF rate + // TODO: make sure that hdfCurrentRate is not 0 if HDF is actually wanted (volume not > max) + hdfCurrentRate = CheckHDFRate( hdfCurrentRate ); + if ( hdfCurrentRate > ZERO_RATE ) + { + resetPIDController( PID_CONTROLLER_ID_SUB_PUMP_PRES, hdfCurrentRate, 0.0F ); hdfControlTimerCounter = 0; - } - } - isHDFRateUpdated = TRUE; + } + } + isHDFRateUpdated = TRUE; //Transition to run state state = TD_HDF_RUNNING; } @@ -210,7 +202,7 @@ *************************************************************************/ static HDF_EXEC_STATE_T handleHDFRunningState( void ) { - HDF_EXEC_STATE_T state = DD_HDF_RUNNING; + HDF_EXEC_STATE_T state = TD_HDF_RUNNING; if ( TRUE != isHemodiafiltrationRequested ) { @@ -229,19 +221,33 @@ * @brief * The setHemodiafiltrationParameters function sets the the hemodiafiltration requested * parameters for this treatment. - * @details \b Inputs: setHDFTMPTarget, setHDFManualRate, setHDFMaximumVolume - * @details \b Outputs: local variables set: hdfTMPTarget, hdfManualRate, setHDFMaximumVolume + * @details \b Inputs: setHDFTMPTarget, setHDFMaximumVolume + * @details \b Outputs: local variables set: hdfTMPTarget, setHDFMaximumVolume * @return none. *************************************************************************/ -void setHemodiafiltrationParameters( F32 setHDFTMPTarget, F32 setHDFManualRate, F32 setHDFMaximumVolume) +void setHemodiafiltrationParameters( F32 setHDFTMPTarget, F32 setHDFMaximumVolume ) { hdfTMPTarget = setHDFTMPTarget; // mmHg - hdfManualRate = setHDFManualRate; // ml/min hdfMaximumVolume = setHDFMaximumVolume; // ml + } /*********************************************************************//** * @brief + * The setHemoDiafiltrationManualRate function sets the the hemodiafiltration open + * loop rate for this treatment. + * @details \b Inputs: setHDFManualRate + * @details \b Outputs: local variables set: hdfManualRate + * @return none. + *************************************************************************/ +void setHemoDiafiltrationManualRate( F32 setHDFManualRate ) +{ + hdfManualRate = setHDFManualRate; + +} + +/*********************************************************************//** + * @brief * The StartHemodiafiltration function starts or resumes hemodiafiltration flow * @details \b Inputs: None * @details \b Outputs: Hemodiafiltration is running @@ -305,22 +311,25 @@ static void UpdateHDFRateAndVolume( void ) { + F32 new_rate = 0.0F; + if ( ( ++hdfControlTimerCounter >= HDF_CONTROL_INTERVAL ) ) { // get new rate from PI controller if ( ZERO_RATE == hdfManualRate ) - { - F32 new_rate = runPIController( PI_CONTROLLER_ID_SUB_PUMP_PRES, hdfTMP_target, getLongFilteredTMPPressure() ); - hdfCurrentRate = CheckHDFRate( new_rate ); - } + { + new_rate = runPIDController( PID_CONTROLLER_ID_SUB_PUMP_PRES, hdfTMPTarget, getLongFilteredTMPPressure() ); + hdfCurrentRate = CheckHDFRate( new_rate ); + } // update and check volume - hdfCurrentvolume += ((F32) HDF_CONTROL_PERIOD_SECONDS / (F32) SECONDS_PER_MINUTE) * hdfCurrentRate; //ml - if ( currentHDFvolume > hdfMaximumVolume ) + hdfCurrentVolume += ((F32) HDF_CONTROL_PERIOD_SECONDS / (F32) SECONDS_PER_MINUTE) * hdfCurrentRate; //ml + + if ( hdfCurrentVolume > hdfMaximumVolume ) { reachedMaximumHDFVolume = TRUE; - // Done delivering HDF, turn off pump and go to pause state - hdfCurrentRate = ZERO_RATE; - hdfExecState = TD_HDF_PAUSED; + // Done delivering HDF, turn off pump and go to pause state + hdfCurrentRate = ZERO_RATE; + hdfExecState = TD_HDF_PAUSED; } hdfControlTimerCounter = 0; isHDFRateUpdated = TRUE; //Some rate updates could be avoided by checking new rate against old rate @@ -342,6 +351,19 @@ /*********************************************************************//** * @brief + * The getCurrentHDFRate function returns the current rate + * of the hemodiafiltration. + * @details \b Inputs: hdfCurrentRate + * @details \b Outputs: none + * @return the current state of HDF rate. + *************************************************************************/ +F32 getCurrentHDFRate( void ) +{ + return hdfCurrentRate; +} + +/*********************************************************************//** + * @brief * The publishHemodiafiltrationData function broadcasts the hemodiafiltration * data at defined interval. * @details \b Inputs: hdfDataPublicationTimerCounter @@ -364,7 +386,7 @@ data.isHDFRequested = (U32)isHemodiafiltrationRequested; data.hdfRequestedVolume = hdfMaximumVolume; data.hdfTotalVolume = hdfCurrentVolume; - broadcastData( MSG_ID_TD_HDF_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( HDF_DATA_T ) ); + broadcastData( MSG_ID_TD_HEMODIAFILTRATION_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( HDF_DATA_T ) ); hdfDataPublicationTimerCounter = 0; } @@ -385,12 +407,36 @@ * (in ms) to override the TD hemodiafiltration data publish interval to. * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testDDHDFDataPublishIntervalOverride( MESSAGE_T *message ) +BOOL testTDHDFDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &hdfDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } +BOOL testTDHDFStartStopHDFOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + HDF_START_PAYLOAD_T payload; + // If testing is activated and payload size is valid + if ( ( TRUE == isTestingActivated() ) && ( message->hdr.payloadLen == sizeof(HDF_START_PAYLOAD_T) ) ) + { + memcpy( &payload, message->payload, sizeof(HDF_START_PAYLOAD_T) ); + + setHemodiafiltrationParameters( payload.hdfTMPTgt, payload.hdfVolume ); + setHemoDiafiltrationManualRate( payload.hdfRate ); + + if( TRUE == payload.hdfStart ) + { + StartHemodiafiltration(); + } + else + { + StopHemodiafiltration(); + } + result = TRUE; + } + return result; +} /**@}*/