Index: firmware/App/Modes/ModeTxParams.c =================================================================== diff -u -r79c2105d7ec35f3caeb977f6e2cc1b494853d211 -rc8a6bfae0f88b45e3783632c868235077e4cbeec --- firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision 79c2105d7ec35f3caeb977f6e2cc1b494853d211) +++ firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision c8a6bfae0f88b45e3783632c868235077e4cbeec) @@ -83,6 +83,13 @@ U32 rejReason; ///< Rejection reason code (if rejected). F32 ufVolumeMl; ///< Validated ultrafiltration volume (in mL). } UF_VOLUME_VAL_RESP_DATA_PAYLOAD_T; + +/// Record structure for set treatment parameter Dialin message. +typedef struct +{ + U32 paramID; ///< Treatment parameter ID. + CRITICAL_DATAS_T value; ///< Set value. +} DIALIN_SET_TX_PARAM_PAYLOAD_T; #pragma pack(pop) // ********** private data ********** @@ -92,20 +99,24 @@ /// Treatment parameter properties (types, ranges and defaults). const TREATMENT_PARAMS_PROPERTIES_T TREAT_PARAMS_PROPERTIES[ NUM_OF_TREATMENT_PARAMS ] = { - { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=500}, {.uInt=100} }, // TREATMENT_PARAM_BLOOD_FLOW - { CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=600}, {.uInt=100} }, // TREATMENT_PARAM_DIALYSATE_FLOW - { CRITICAL_DATA_TYPE_U32, {.uInt=60}, {.uInt=480}, {.uInt=240} }, // TREATMENT_PARAM_TREATMENT_DURATION + { CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=500}, {.uInt=50} }, // TREATMENT_PARAM_BLOOD_FLOW + { CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=600}, {.uInt=50} }, // TREATMENT_PARAM_DIALYSATE_FLOW + { CRITICAL_DATA_TYPE_U32, {.uInt=60}, {.uInt=480}, {.uInt=60} }, // TREATMENT_PARAM_TREATMENT_DURATION { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=300}, {.uInt=100} }, // TREATMENT_PARAM_SALINE_BOLUS_VOLUME + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=480}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_STOP_TIME { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=2}, {.uInt=0} }, // TREATMENT_PARAM_ACID_CONCENTRATE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_BICARB_CONCENTRATE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=5}, {.uInt=0} }, // TREATMENT_PARAM_DIALYZER_TYPE - { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=60}, {.uInt=30} }, // TREATMENT_PARAM_BP_MEAS_INTERVAL + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=60}, {.uInt=0} }, // TREATMENT_PARAM_BP_MEAS_INTERVAL { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=300}, {.uInt=200} }, // TREATMENT_PARAM_RINSEBACK_FLOW_RATE + { CRITICAL_DATA_TYPE_U32, {.uInt=300}, {.uInt=300}, {.uInt=300} }, // TREATMENT_PARAM_RINSEBACK_VOLUME { CRITICAL_DATA_TYPE_S32, {.sInt=120}, {.sInt=200}, {.sInt=120} }, // TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW { CRITICAL_DATA_TYPE_S32, {.sInt=100}, {.sInt=200}, {.sInt=100} }, // TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW { CRITICAL_DATA_TYPE_S32, {.sInt=20}, {.sInt=35}, {.sInt=20} }, // TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC { CRITICAL_DATA_TYPE_S32, {.sInt=40}, {.sInt=100}, {.sInt=40} }, // TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW { CRITICAL_DATA_TYPE_F32, {.sFlt=35.0}, {.sFlt=37.0}, {.sFlt=37.0} }, // TREATMENT_PARAM_DIALYSATE_TEMPERATURE + { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=1.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_HEPARIN_DISPENSE_RATE + { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=2.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=8.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_UF_VOLUME }; @@ -485,7 +496,7 @@ paramsAreInRange = checkTreatmentParamsInRange( &rejReasons[0] ); // Validate dependencies - paramsAreConsistent = TRUE; // checkTreatmentParamsDependencies( &rejReasons[0] ); // TODO + paramsAreConsistent = checkTreatmentParamsDependencies( &rejReasons[0] ); // Determine overall validity of received treatment parameters if ( ( TRUE == paramsAreInRange ) && ( TRUE == paramsAreConsistent ) ) @@ -550,6 +561,35 @@ /*********************************************************************//** * @brief + * The checkTreatmentParamsDependencies function checks dependencies between + * received treatment parameters. + * @details \b Inputs: stagedParams[] + * @details \b Outputs: reasons[] + * @param reasons Pointer to array of reject reason codes for each parameter + * @return TRUE if treatment parameter dependencies are ok, FALSE if not + *************************************************************************/ +static BOOL checkTreatmentParamsDependencies( U32 *reasons ) +{ + BOOL result = TRUE; + + // Verify Heparin stop time is only set if Heparin dispense rate is set + if ( ( stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt > 0 ) && ( stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt < NEARLY_ZERO ) ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_WITH_NO_DISPENSE; + result = FALSE; + } + // Verify Heparin stop time does not exceed Tx duration + else if ( stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt > stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_EXCEEDS_DURATION; + result = FALSE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The validateAndSetUFVolume function validates received ultrafiltration * volume treatment parameter. * @details \b Message \b Sent: MSG_ID_TD_RESP_ULTRAFILTRATION_VOLUME_TO_VALIDATE @@ -1180,4 +1220,88 @@ return value; } + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetTreatmentParameter function sets a given treatment parameter + * to a given value. + * @details \b Inputs: none + * @details \b Outputs: treatmentParameters[] + * @param message Set treatment parameter message from Dialin which includes + * the ID of the treatment parameter to be set and the value to set it to. + * @return TRUE if set request is successful, FALSE if not + *************************************************************************/ +BOOL testSetTreatmentParameter( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length is valid + if ( message->hdr.payloadLen != sizeof( DIALIN_SET_TX_PARAM_PAYLOAD_T ) ) + { + DIALIN_SET_TX_PARAM_PAYLOAD_T payload; + + memcpy( (U08*)&payload, &message->payload[0], sizeof( DIALIN_SET_TX_PARAM_PAYLOAD_T ) ); + + // Verify treatment parameter ID is valid + if ( (TREATMENT_PARAM_T)payload.paramID < NUM_OF_TREATMENT_PARAMS ) + { + // Set the given Tx param to the given value + if ( (TREATMENT_PARAM_T)payload.paramID <= TREATMENT_PARAM_LAST_UINT ) + { + result = setTreatmentParameterU32( (TREATMENT_PARAM_T)payload.paramID, payload.value.uInt ); + } + else if ( (TREATMENT_PARAM_T)payload.paramID >= TREATMENT_PARAM_FIRST_F32 ) + { + result = setTreatmentParameterF32( (TREATMENT_PARAM_T)payload.paramID, payload.value.sFlt ); + } + else + { + result = setTreatmentParameterS32( (TREATMENT_PARAM_T)payload.paramID, payload.value.sInt ); + } + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testTxParamsRequest function publishes the complete set of treatment + * parameters. + * @details \b Message \b Sent: MSG_ID_TD_RSP_CURRENT_TREATMENT_PARAMETERS + * @details \b Inputs: treatmentParameters[] + * @details \b Outputs: none + * @param message The message from Dialin requesting that treatment parameters + * be published. + * @return TRUE if publish treatment parameters request is successful, FALSE if not + *************************************************************************/ +BOOL testTxParamsRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length + if ( 0 == message->hdr.payloadLen ) + { + CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T payload; + TREATMENT_PARAM_T param; + + // Build and publish current treatment parameters record + for ( param = (TREATMENT_PARAM_T)0; param < NUM_OF_TREATMENT_PARAMS; param++ ) + { + stagedParams[ param ] = treatmentParameters[ param ].data; + } + memcpy( (U08*)&payload, (U08*)&stagedParams[0], sizeof( CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_RSP_CURRENT_TREATMENT_PARAMETERS, COMM_BUFFER_OUT_CAN_PC, (U08*)&payload, sizeof( CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T ) ); + + result = TRUE; + } + + return result; +} + /**@}*/