Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -rc0273c73da6b6dee4ad6f1d54cb6c6f27a262b5b -r3ded5ffcbcade3f1da5d40c52936ab5f97fc6ec9 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision c0273c73da6b6dee4ad6f1d54cb6c6f27a262b5b) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 3ded5ffcbcade3f1da5d40c52936ab5f97fc6ec9) @@ -25,6 +25,7 @@ #include "FPGA.h" #include "InternalADC.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PIControllers.h" #include "SystemCommMessages.h" @@ -127,10 +128,12 @@ static BOOL isDialInPumpOn = FALSE; ///< dialIn pump is currently running static F32 dialInPumpPWMDutyCyclePct = 0.0; ///< initial dialIn pump PWM duty cycle static F32 dialInPumpPWMDutyCyclePctSet = 0.0; ///< currently set dialIn pump PWM duty cycle -static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; ///< requested dialIn flow direction -static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; ///< currently set dialIn flow direction +static MOTOR_DIR_T dialInPumpDirection = MOTOR_DIR_FORWARD; ///< requested dialysate flow direction +static MOTOR_DIR_T dialInPumpDirectionSet = MOTOR_DIR_FORWARD; ///< currently set dialysate flow direction static PUMP_CONTROL_MODE_T dialInPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested dialIn pump control mode. static PUMP_CONTROL_MODE_T dialInPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP;///< currently set dialIn pump control mode. +static F32 dialInFlowCalGain = 1.0; ///< dialysate flow calibration gain. +static F32 dialInFlowCalOffset = 0.0; ///< dialysate flow calibration offset. static OVERRIDE_U32_T dialInFlowDataPublishInterval = { DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, DIAL_IN_FLOW_DATA_PUB_INTERVAL, 0 }; ///< interval (in ms) at which to publish dialIn flow data to CAN bus static OVERRIDE_S32_T targetDialInFlowRate = { 0, 0, 0, 0 }; ///< requested dialIn flow rate @@ -357,7 +360,7 @@ { U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); - F32 dipFlow = getFPGADialysateFlow(); + F32 dipFlow = ( getFPGADialysateFlow() + dialInFlowCalOffset ) * dialInFlowCalGain; adcDialInPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; adcDialInPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; @@ -649,9 +652,19 @@ * @details * Inputs : dialInFlowDataPublishInterval * Outputs : none - * @return the current dialIn flow data publication interval (in ms). + * @return the current dialIn flow data publication interval (in task intervals). *************************************************************************/ -DATA_GET( U32, getPublishDialInFlowDataInterval, dialInFlowDataPublishInterval ) +U32 getPublishDialInFlowDataInterval( void ) +{ + U32 result = dialInFlowDataPublishInterval.data; + + if ( OVERRIDE_KEY == dialInFlowDataPublishInterval.override ) + { + result = dialInFlowDataPublishInterval.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -662,7 +675,17 @@ * Outputs : none * @return the current target dialIn flow rate (in mL/min). *************************************************************************/ -DATA_GET( S32, getTargetDialInFlowRate, targetDialInFlowRate ) +S32 getTargetDialInFlowRate( void ) +{ + S32 result = targetDialInFlowRate.data; + + if ( OVERRIDE_KEY == targetDialInFlowRate.override ) + { + result = targetDialInFlowRate.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -673,7 +696,17 @@ * Outputs : none / * @return the current dialIn flow rate (in mL/min). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInFlowRate, measuredDialInFlowRate ) +F32 getMeasuredDialInFlowRate( void ) +{ + F32 result = measuredDialInFlowRate.data; + + if ( OVERRIDE_KEY == measuredDialInFlowRate.override ) + { + result = measuredDialInFlowRate.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -684,7 +717,17 @@ * Outputs : none * @return the current dialIn flow rate (in mL/min). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInPumpRotorSpeed, dialInPumpRotorSpeedRPM ) +F32 getMeasuredDialInPumpRotorSpeed( void ) +{ + F32 result = dialInPumpRotorSpeedRPM.data; + + if ( OVERRIDE_KEY == dialInPumpRotorSpeedRPM.override ) + { + result = dialInPumpRotorSpeedRPM.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -695,7 +738,17 @@ * Outputs : none * @return the current dialIn flow rate (in mL/min). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInPumpSpeed, dialInPumpSpeedRPM ) +F32 getMeasuredDialInPumpSpeed( void ) +{ + F32 result = dialInPumpSpeedRPM.data; + + if ( OVERRIDE_KEY == dialInPumpSpeedRPM.override ) + { + result = dialInPumpSpeedRPM.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -706,7 +759,17 @@ * Outputs : none * @return the current dialIn pump speed (in RPM). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInPumpMCSpeed, adcDialInPumpMCSpeedRPM ) +F32 getMeasuredDialInPumpMCSpeed( void ) +{ + F32 result = adcDialInPumpMCSpeedRPM.data; + + if ( OVERRIDE_KEY == adcDialInPumpMCSpeedRPM.override ) + { + result = adcDialInPumpMCSpeedRPM.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -717,7 +780,17 @@ * Outputs : none / * @return the current dialIn pump current (in mA). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInPumpMCCurrent, adcDialInPumpMCCurrentmA ) +F32 getMeasuredDialInPumpMCCurrent( void ) +{ + F32 result = adcDialInPumpMCCurrentmA.data; + + if ( OVERRIDE_KEY == adcDialInPumpMCCurrentmA.override ) + { + result = adcDialInPumpMCCurrentmA.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -753,6 +826,7 @@ * @details * Inputs : none * Outputs : flowReadingsTotal, flowReadingsIdx, flowReadingsCount all set to zero. + * @return none *************************************************************************/ static void resetDialInFlowMovingAverage( void ) { @@ -764,11 +838,10 @@ /*********************************************************************//** * @brief - * The filterDialInFlowReadings function adds a new flow sample to the filter \n - * if decimation rate for current set point calls for it. + * The filterDialInFlowReadings function adds a new flow sample to the filter. * @details * Inputs : none - * Outputs : flowReadings[], flowReadingsIdx, flowReadingsCount + * Outputs : flowReadings[], flowReadingsIdx, flowReadingsCount, flowReadingsTotal * @return none *************************************************************************/ static void filterDialInFlowReadings( F32 flow ) @@ -1072,9 +1145,32 @@ SELF_TEST_STATUS_T execDialInFlowTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - - // TODO - implement self test(s) - + CALIBRATION_DATA_T cal; + + switch ( dialInPumpSelfTestState ) + { + case DIAL_IN_FLOW_SELF_TEST_STATE_START: + // retrieve blood flow sensor calibration data + if ( TRUE == getCalibrationData( &cal ) ) + { + dialInFlowCalGain = cal.dialysateFlowGain; + dialInFlowCalOffset = cal.dialysateFlowOffset_mL_min; + dialInPumpSelfTestState = DIAL_IN_FLOW_TEST_STATE_COMPLETE; // TODO - implement rest of self test(s) + result = SELF_TEST_STATUS_PASSED; + } + break; + + case DIAL_IN_FLOW_TEST_STATE_IN_PROGRESS: + break; + + case DIAL_IN_FLOW_TEST_STATE_COMPLETE: + break; + + default: + // TODO - s/w fault + break; + } + return result; } @@ -1084,6 +1180,59 @@ *************************************************************************/ +/*********************************************************************//** + * @brief + * The setDialInFlowCalibration function sets the dialysate flow calibration \n + * factors and has them stored in non-volatile memory. + * @details + * Inputs : none + * Outputs : dialInFlowCalGain, dialInFlowCalOffset + * @param gain : gain calibration factor for dialysate flow sensor + * @param offset : offset calibration factor for dialysate flow sensor + * @return TRUE if calibration factors successfully set/stored, FALSE if not + *************************************************************************/ +BOOL setDialInFlowCalibration( F32 gain, F32 offset ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + CALIBRATION_DATA_T cal; + + if ( TRUE == getCalibrationData( &cal ) ) + { // keep locally and apply immediately + dialInFlowCalGain = gain; + dialInFlowCalOffset = offset; + // also update calibration record in non-volatile memory + cal.dialysateFlowGain = gain; + cal.dialysateFlowOffset_mL_min = offset; + if ( TRUE == setCalibrationData( cal ) ) + { + result = TRUE; + } + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getDialInFlowCalibration function retrieves the current dialysate flow \n + * calibration factors. + * @details + * Inputs : dialInFlowCalGain, dialInFlowCalOffset + * Outputs : none + * @param gain : value to populate with gain calibration factor for dialysate flow sensor + * @param offset : value to populate with offset calibration factor for dialysate flow sensor + * @return none + *************************************************************************/ +void getDialInFlowCalibration( F32 *gain, F32 *offset ) +{ + *gain = dialInFlowCalGain; + *offset = dialInFlowCalOffset; +} + /*********************************************************************//** * @brief * The testSetDialInFlowDataPublishIntervalOverride function overrides the \n