Index: firmware/App/Services/TDInterface.c =================================================================== diff -u -r333e2d0c0462dcb4343a279420949cce716ebab7 -r2ae6daaf7d4cf33e3e9b1ade40750f3eae04c128 --- firmware/App/Services/TDInterface.c (.../TDInterface.c) (revision 333e2d0c0462dcb4343a279420949cce716ebab7) +++ firmware/App/Services/TDInterface.c (.../TDInterface.c) (revision 2ae6daaf7d4cf33e3e9b1ade40750f3eae04c128) @@ -1,21 +1,23 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file TDInterface.c * * @author (last) Vinayakam Mani -* @date (last) 28-Oct-2024 +* @date (last) 26-Feb-2026 * * @author (original) Vinayakam Mani -* @date (original) 28-Oct-2024 +* @date (original) 06-Nov-2024 * ***************************************************************************/ #include "DialysatePumps.h" +#include "FPInterface.h" +#include "FPOperationModes.h" #include "Messaging.h" #include "MessagePayloads.h" #include "ModeGenDialysate.h" @@ -36,21 +38,68 @@ // ********** private definitions ********** -#define TD_DATA_FRESHNESS_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< TD data freshness timeout (in ms). +#define TD_DATA_FRESHNESS_TIMEOUT_MS ( 3 * MS_PER_SECOND ) ///< TD data freshness timeout (in ms). +#define TD_DIALYSATE_FLOWRATE_MIN_ML_MIN ( 50.0F ) ///< TD Min dialysate flow rate (mL/min) +#define TD_DIALYSATE_FLOWRATE_MAX_ML_MIN ( 600.0F ) ///< TD Max dialysate flow rate (mL/min) + +#define TD_UF_RATE_MIN_ML_MIN ( 0.0F ) ///< TD Min UF rate (mL/min) +#define TD_UF_RATE_MAX_ML_MIN ( 2000.0F / 60.0F ) ///< TD Max UF rate (mL/min) + +#define TD_DIALYSATE_TEMP_MIN_DEGC ( 35.0F ) ///< TD Min dialysate temperature (deg C) +#define TD_DIALYSATE_TEMP_MAX_DEGC ( 38.0F ) ///< TD Max dialysate temperature (deg C) + +#define TD_ACID_TYPE_MIN ( 0U ) ///< TD Min acid type index +#define TD_ACID_TYPE_MAX ( (U32)( NUM_OF_ACID_TYPE - 1U ) ) ///< TD Max acid type index + +#define TD_SODIUM_MIN ( 130U ) ///< TD Min acid type index +#define TD_SODIUM_MAX ( 155U ) ///< TD Max acid type index + +#define TD_BICARBONATE_MIN ( 20U ) ///< TD Min acid type index +#define TD_BICARBONATE_MAX ( 40U ) ///< TD Max acid type index + +#define BICARBONATE_CONVERSION_FACTOR 0.07337F ///< Bicarbonate conversion factor mS/cm per mmol/L +#define MAX_ACID_CONC_TYPES 10 ///< Number of acid concentrate conversion factors + +// TODO move to institutional records once implemented +/// Acid concentration conversion factors for each acid type +const F32 ACID_CONVERSION_FACTOR[ MAX_ACID_CONC_TYPES ] = { 0.11192F, + 0.11313F, + 0.11435F, + 0.0F, + 0.0F, + 0.0F, + 0.0F, + 0.0F, + 0.0F, + 0.0F }; + +/// Enumeration of TD Treatment Overrides +typedef enum TD_Treatment_Override +{ + TD_TREATMENT_OVERRIDE_DIALYSATE_FLOWRATE = 0, ///< TD Dialysate flow rate + TD_TREATMENT_OVERRIDE_UF_RATE, ///< TD Ultrafilteration rate + TD_TREATMENT_OVERRIDE_DIALYSATE_TEMP, ///< TD Target Dialysate Temperature + TD_TREATMENT_OVERRIDE_ACID_TYPE, ///< TD Acid type + TD_TREATMENT_OVERRIDE_BICARB_TYPE, ///< TD Bicarb type + NUM_OF_TD_TREATMENT_OVERRIDES, ///< Number of TD override treatment parameters +} TD_TREATMENT_OVERRIDE_INDEX_T; + // ********** private data ********** // TD status -static TD_OP_MODE_T tdCurrentOpMode; ///< Current TD operation mode. -static U32 tdSubMode; ///< Current state (sub-mode) of current TD operation mode. -static F32 tdDialysateFlowrate; ///< TD dialysate flow rate -static F32 tdUFRate; ///< TD ultrafiltration rate -static F32 tdTargetDialysateTemp; ///< TD target dialysate temperature -static BOOL tdDialyzerBypass; ///< TD dialyzer bypass -static DD_ACID_TYPES_T tdAcidType; ///< TD Acid type. -static DD_BICARB_TYPES_T tdBicarbType; ///< TD Bicarb type. +static TD_OP_MODE_T tdCurrentOpMode; ///< Current TD operation mode. +static U32 tdSubMode; ///< Current state (sub-mode) of current TD operation mode. +static BOOL tdDialyzerBypass; ///< TD dialyzer bypass +static BOOL tdOpModeDataFreshFlag = FALSE; ///< Flag to signal/process fresh TD op mode data -static BOOL tdOpModeDataFreshFlag = FALSE; ///< Flag to signal/process fresh TD op mode data +static OVERRIDE_F32_T tdDialysateFlowrate; ///< TD Dialysate flow rate +static OVERRIDE_F32_T tdUFRate; ///< TD ultrafiltration rate +static OVERRIDE_F32_T tdDialysateTemp; ///< TD Target Dialysate Temperature +static OVERRIDE_F32_T tdAcidConvFactor; ///< TD Acid conversion factor +static OVERRIDE_F32_T tdBicarbConvFactor; ///< TD Bicarb conversion factor +static OVERRIDE_U32_T tdSodium; ///< TD Sodium concentrate +static OVERRIDE_U32_T tdBicarbonate; ///< TD Bicarbonate concentrate // ********** private function prototypes ********** @@ -65,15 +114,47 @@ *************************************************************************/ void initTDInterface( void ) { - // Initialize unit variables - tdCurrentOpMode = MODE_INIT; - tdSubMode = 0; - tdDialysateFlowrate = MAX_DIALYSATE_FLOW_RATE; // Will update later based on the TD value - tdUFRate = 0.0F; - tdTargetDialysateTemp = 0.0F; - tdDialyzerBypass = FALSE; - tdAcidType = ACID_08_1251_1; - tdBicarbType = BICARB_08_677753_0; + // Initialize unit state variables + tdCurrentOpMode = MODE_INIT; + tdSubMode = 0U; + tdDialyzerBypass = FALSE; + tdOpModeDataFreshFlag = FALSE; + + // Initialize treatment parameters from TD + tdDialysateFlowrate.data = 0.0F; + tdDialysateFlowrate.ovData = 0.0F; + tdDialysateFlowrate.ovInitData = TD_DIALYSATE_FLOWRATE_MIN_ML_MIN; + tdDialysateFlowrate.override = OVERRIDE_RESET; + + tdUFRate.data = 0.0F; + tdUFRate.ovData = 0.0F; + tdUFRate.ovInitData = TD_UF_RATE_MIN_ML_MIN; + tdUFRate.override = OVERRIDE_RESET; + + tdDialysateTemp.data = 0.0F; + tdDialysateTemp.ovData = 0.0F; + tdDialysateTemp.ovInitData = TD_DIALYSATE_TEMP_MIN_DEGC; + tdDialysateTemp.override = OVERRIDE_RESET; + + tdAcidConvFactor.data = 0.0F; + tdAcidConvFactor.ovData = 0.0F; + tdAcidConvFactor.ovInitData = ACID_CONVERSION_FACTOR[ TD_ACID_TYPE_MIN ]; + tdAcidConvFactor.override = OVERRIDE_RESET; + + tdBicarbConvFactor.data = 0.0F; + tdBicarbConvFactor.ovData = 0.0F; + tdBicarbConvFactor.ovInitData = BICARBONATE_CONVERSION_FACTOR; + tdBicarbConvFactor.override = OVERRIDE_RESET; + + tdSodium.data = 0.0F; + tdSodium.ovData = 0.0F; + tdSodium.ovInitData = TD_SODIUM_MIN; + tdSodium.override = OVERRIDE_RESET; + + tdBicarbonate.data = 0.0F; + tdBicarbonate.ovData = 0.0F; + tdBicarbonate.ovInitData = TD_BICARBONATE_MIN; + tdBicarbonate.override = OVERRIDE_RESET; } /**********************************************************************//** @@ -184,7 +265,7 @@ *************************************************************************/ void setTDDialysateFlowrate( F32 dialFlowrate ) { - tdDialysateFlowrate = dialFlowrate; + tdDialysateFlowrate.data = dialFlowrate; } /*********************************************************************//** @@ -197,21 +278,21 @@ *************************************************************************/ void setTDUFRate( F32 ufRate ) { - tdUFRate = ufRate; + tdUFRate.data = ufRate; } /*********************************************************************//** * @brief * The setTDTargetDialysateTemperature function sets the latest TD dialysate * temperature. * @details \b Inputs: none - * @details \b Outputs: tdTargetDialysateTemp + * @details \b Outputs: tdDialysateTemp * @param Target dialysate temperature. * @return none. *************************************************************************/ void setTDTargetDialysateTemperature( F32 dialTemperature ) { - tdTargetDialysateTemp = dialTemperature; + tdDialysateTemp.data = dialTemperature; } /*********************************************************************//** @@ -233,15 +314,17 @@ * The setTDAcidAndBicarbType function sets the acid and bicarb types to be * used in dialysate generation. * @details \b Inputs: none - * @details \b Outputs: tdAcidType,tdBicarbType + * @details \b Outputs: tdAcidConvFactor,tdBicarbConvFactor * @param acid which is the type of acid * @param bicarb which is the type of bicarb * @return none *************************************************************************/ -void setTDAcidAndBicarbType( U32 acid, U32 bicarb ) +void setTDAcidAndBicarbType( F32 acidConvFactor, F32 bicarbConvFactor, U32 sodium, U32 bicarbonate ) { - tdAcidType = (DD_ACID_TYPES_T)acid; - tdBicarbType = (DD_BICARB_TYPES_T)bicarb; + tdAcidConvFactor.data = acidConvFactor; + tdBicarbConvFactor.data = bicarbConvFactor; + tdSodium.data = sodium; + tdBicarbonate.data = bicarbonate; } /*********************************************************************//** @@ -254,7 +337,7 @@ *************************************************************************/ F32 getTDDialysateFlowrate( void ) { - return tdDialysateFlowrate; + return getF32OverrideValue( &tdDialysateFlowrate ); } /*********************************************************************//** @@ -267,20 +350,20 @@ *************************************************************************/ F32 getTDUFRate( void ) { - return tdUFRate; + return getF32OverrideValue( &tdUFRate ); } /*********************************************************************//** * @brief * The getTDTargetDialysateTemperature function gets the latest TD * target dialysate temperature rate. - * @details \b Inputs: tdTargetDialysateTemp + * @details \b Inputs: tdDialysateTemp * @details \b Outputs: none * @return Latest target dialysate temperature. *************************************************************************/ F32 getTDTargetDialysateTemperature( void ) { - return tdTargetDialysateTemp; + return getF32OverrideValue( &tdDialysateTemp ); } /*********************************************************************//** @@ -296,30 +379,62 @@ return tdDialyzerBypass; } +/****************************************************************************** + * @brief + * The getTDAcidConversionFactor function gets the latest Acid concentrate + * conversion factor. + * @details \b Inputs: tdAcidConvFactor + * @details \b Outputs: None + * @return Latest acid concentrate type. . + ******************************************************************************/ +F32 getTDAcidConversionFactor( void ) +{ + F32 value = getF32OverrideValue( &tdAcidConvFactor ); + + return value; +} + /*********************************************************************//** * @brief - * The getTDAcidConcentrateType function gets the latest Acid concentrate - * type. - * @details \b Inputs: tdAcidType + * The getTDBicarbConversionFactor function gets the latest Bicarb concentrate + * conversion factor. + * @details \b Inputs: tdBicarbConvFactor * @details \b Outputs: none - * @return Latest acid concentrate type. + * @return Latest bicarb concentrate type. *************************************************************************/ -DD_ACID_TYPES_T getTDAcidConcentrateType( void ) +F32 getTDBicarbConversionFactor( void ) { - return tdAcidType; + F32 value = getF32OverrideValue( &tdBicarbConvFactor ); + + return value; } +/****************************************************************************** + * @brief + * The getTDSodiumConcentration function gets the Sodium concentration. + * @details \b Inputs: tdSodium + * @details \b Outputs: None + * @return Latest sodium concentration. + ******************************************************************************/ +U32 getTDSodiumConcentration( void ) +{ + U32 value = getU32OverrideValue( &tdSodium ); + + return value; +} + /*********************************************************************//** * @brief - * The getTDBicarbConcentrateType function gets the latest Bicarb concentrate - * type. - * @details \b Inputs: tdBicarbType + * The getTDBicarbonateConcentration function gets the latest bicarbonate concentration + * @details \b Inputs: tdBicarbonate * @details \b Outputs: none - * @return Latest bicarb concentrate type. + * @return Latest bicarbonate concentration. *************************************************************************/ -DD_BICARB_TYPES_T getTDBicarbConcentrateType( void ) +U32 getTDBicarbonateConcentration( void ) { - return tdBicarbType; + U32 value = getU32OverrideValue( &tdBicarbonate ); + + return value; } /*********************************************************************//** @@ -334,30 +449,55 @@ BOOL handlePreGenDialysateRequestMsg( MESSAGE_T *message ) { BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T fpReason = REQUEST_REJECT_REASON_NONE; if ( message->hdr.payloadLen == sizeof( PRE_GEN_DIALYSATE_REQ_PAYLOAD_T ) ) { PRE_GEN_DIALYSATE_REQ_PAYLOAD_T startPreGenRequest; DD_OP_MODE_T ddMode = getCurrentOperationMode(); + FP_OP_MODE_T fpMode = getCurrentFPOperationMode(); memcpy( &startPreGenRequest, message->payload, sizeof( PRE_GEN_DIALYSATE_REQ_PAYLOAD_T ) ); // Process the pre-gen dialysate delivery request message if ( ( DD_MODE_STAN == ddMode ) && ( TRUE == startPreGenRequest.start ) ) { + // Start FP Pre-Generate Permeate + + if ( ( FP_MODE_STAN == fpMode ) && ( getTestConfigStatus( TEST_CONFIG_DD_RUN_SOLO ) == FALSE ) ) + { + fpReason = signalStartGenPermeate(); + } + else + { + fpReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; + } // start pre-gen dialysate result = requestDDPreGenStart(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } // Update Temperature, Acid/Bicarb type and dialysate rate for pregen process. setTDDialysateFlowrate( startPreGenRequest.dialRate ); setTDTargetDialysateTemperature( startPreGenRequest.dialTemp ); - setTDAcidAndBicarbType( startPreGenRequest.acidType, startPreGenRequest.bicarbType ); + setTDAcidAndBicarbType( startPreGenRequest.acidConvFactor, startPreGenRequest.bicarbConvFactor, + startPreGenRequest.sodium, startPreGenRequest.bicarbonate ); } else if ( DD_MODE_PREG == ddMode ) { if ( FALSE == startPreGenRequest.start ) { // stop pre generate diaysate delivery result = requestDDPreGenStop(); + // stop FP Pre-Generate Permeate + fpReason = signalStopGenPermeate(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } } } } @@ -381,6 +521,7 @@ BOOL handleDialysateDeliveryRequestMsg( MESSAGE_T *message ) { BOOL result = FALSE; + REQUEST_REJECT_REASON_CODE_T fpReason = REQUEST_REJECT_REASON_NONE; if ( message->hdr.payloadLen == sizeof( DIALYSATE_DELIVERY_REQ_PAYLOAD_T ) ) { @@ -398,7 +539,8 @@ setTDTargetDialysateTemperature( startTxRequest.dialTemp ); // Set concentrate types, Bypass dialyzer - setTDAcidAndBicarbType( startTxRequest.acidType, startTxRequest.bicarbType ); + setTDAcidAndBicarbType( startTxRequest.acidConvFactor, startTxRequest.bicarbConvFactor, + startTxRequest.sodium, startTxRequest.bicarbonate ); setTDDialyzerBypass( startTxRequest.bypassDialyzer ); // start dialysate generation @@ -410,6 +552,13 @@ { // stop dialysate generation result = requestDDGenDialyasteStop(); + // stop FP Pre-Generate Permeate + fpReason = signalStopGenPermeate(); + + if ( REQUEST_REJECT_REASON_NONE != fpReason ) + { + result = FALSE; + } } else { @@ -419,7 +568,8 @@ setTDTargetDialysateTemperature( startTxRequest.dialTemp ); // Set concentrate types, Bypass dialyzer - setTDAcidAndBicarbType( startTxRequest.acidType, startTxRequest.bicarbType ); + setTDAcidAndBicarbType( startTxRequest.acidConvFactor, startTxRequest.bicarbConvFactor, + startTxRequest.sodium, startTxRequest.bicarbonate ); setTDDialyzerBypass( startTxRequest.bypassDialyzer ); // Signal to update treatement parameters @@ -441,4 +591,59 @@ *************************************************************************/ +/****************************************************************************** +* @brief +* Processes TD treatment parameter override request from Dialin. +* @details \b Inputs: Override payload from Dialin (TEST_OVERRIDE_ARRAY_PAYLOAD_T) +* @details \b Outputs: Updated TD override structures and treatment parameter +* update flag. +* @param message Pointer to the override message received from Dialin. +* @return TRUE if the override is successfully applied, FALSE otherwise. +******************************************************************************/ +BOOL testTDTreatmentParamsOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + + getOverrideArrayPayloadFromMessage( message, &payload ); + + if ( DD_MODE_GEND == getCurrentOperationMode() ) + { + switch ( (TD_TREATMENT_OVERRIDE_INDEX_T)payload.index ) + { + case TD_TREATMENT_OVERRIDE_DIALYSATE_FLOWRATE: + result = f32Override( message, &tdDialysateFlowrate ); + break; + + case TD_TREATMENT_OVERRIDE_UF_RATE: + result = f32Override( message, &tdUFRate ); + break; + + case TD_TREATMENT_OVERRIDE_DIALYSATE_TEMP: + result = f32Override( message, &tdDialysateTemp ); + break; + + // TODO change acid and bicarb types to convFactor and add Sodium and Bicarbonate + case TD_TREATMENT_OVERRIDE_ACID_TYPE: + result = f32Override( message, &tdAcidConvFactor); + break; + + case TD_TREATMENT_OVERRIDE_BICARB_TYPE: + result = f32Override( message, &tdBicarbConvFactor); + break; + + default: + result = FALSE; + break; + } + + if ( TRUE == result ) + { + setTreatmentParamUpdate(); + } + } + + return result; +} + /**@}*/