Index: firmware/App/Controllers/FlowSensors.c =================================================================== diff -u -r0f4fbb2a56cdbe35dcedd9cad23867fd7248f86e -r696e732c9742535a58b9c65f243df7cd797d1423 --- firmware/App/Controllers/FlowSensors.c (.../FlowSensors.c) (revision 0f4fbb2a56cdbe35dcedd9cad23867fd7248f86e) +++ firmware/App/Controllers/FlowSensors.c (.../FlowSensors.c) (revision 696e732c9742535a58b9c65f243df7cd797d1423) @@ -1,3 +1,19 @@ +/************************************************************************** +* +* Copyright (c) 2022-2022 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 FlowSensors.c +* +* @author (last) Dara Navaei +* @date (last) 01-Aug-2022 +* +* @author (original) Dara Navaei +* @date (original) 21-Jul-2022 +* +***************************************************************************/ #include @@ -17,30 +33,30 @@ // ********** private definitions ********** -#define FLOW_SENSORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the Dialysate flow data is published on the CAN bus. -#define FLOW_SENSORS_EDGES_BUFFER_LENGTH 100 -#define FLOW_SENSORS_PULSES_PER_LITER 110000 // TODO calibration record +#define FLOW_SENSORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the Dialysate flow data is published on the CAN bus. +#define FLOW_SENSORS_EDGES_BUFFER_LENGTH 100 ///< Flow sensors edges buffer length. +#define FLOW_SENSORS_PULSES_PER_LITER 110000 ///< Flow sensors pulses per liter +#define FLOW_OUT_OF_RANGE_TIME_OUT_MS ( 12 * MS_PER_SECOND ) ///< Flow out of range time out in milliseconds. +#define DATA_PUBLISH_COUNTER_START_COUNT 20 ///< Data publish counter start count. -#define FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL ( 12 * MS_PER_SECOND ) // Why is this so long? ///< Flow out of range time out in counts. -#define DATA_PUBLISH_COUNTER_START_COUNT 20 ///< Data publish counter start count. +static const F32 FLOW_SENSORS_LITERS_PER_PULSES = ( 1.0 / (F32)FLOW_SENSORS_PULSES_PER_LITER ); ///< Flow sensors liters/pulses coefficient. -static const F32 FLOW_SENSORS_LITERS_PER_PULSES = ( 1.0 / (F32)FLOW_SENSORS_PULSES_PER_LITER ); - // ********** private data ********** +/// Flow sensors data structure typedef struct { - U08 edgeCountsIndex; - U16 edgeCountsBuffer[ FLOW_SENSORS_EDGES_BUFFER_LENGTH ]; - OVERRIDE_F32_T measuredFlowLPM; - OVERRIDE_F32_T measuredROFlowWithCPsLPM; + U08 edgeCountsIndex; ///< Edge counts index. + U16 edgeCountsBuffer[ FLOW_SENSORS_EDGES_BUFFER_LENGTH ]; ///< Edge counts buffer array. + OVERRIDE_F32_T measuredFlowLPM; ///< Measured flow in L/min. + OVERRIDE_F32_T measuredROFlowWithCPsLPM; ///< Measured RO flow with concentrate pumps in L/min. } FLOW_SENSOR_STATUS_T; -static U32 dataPublicationCounter; ///< Used to schedule Dialysate flow data publication to CAN bus. +static U32 dataPublicationCounter; ///< Used to schedule Dialysate flow data publication to CAN bus. static OVERRIDE_U32_T flowSensorsDataPublishInterval = { FLOW_SENSORS_DATA_PUB_INTERVAL, FLOW_SENSORS_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish Dialysate flow data to CAN bus. -static FLOW_SENSOR_STATUS_T flowSensorStatus[ NUM_OF_FLOW_SENSORS ]; + 0, 0 }; ///< Interval (in ms) at which to publish Dialysate flow data to CAN bus. +static FLOW_SENSOR_STATUS_T flowSensorStatus[ NUM_OF_FLOW_SENSORS ]; ///< Flow sensors status. static DG_FLOW_SENSORS_CAL_RECORD_T flowSensorsCalRecord; ///< Flow sensors calibration record. // ********** private function prototypes ********** @@ -65,7 +81,8 @@ } // Initialize the persistent alarm for flow out of upper and lower range - initPersistentAlarm( ALARM_ID_DIALYSATE_FLOW_RATE_OUT_OF_RANGE, FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL, FLOW_OUT_OF_RANGE_PERSISTENT_INTERVAL ); + initPersistentAlarm( ALARM_ID_DG_DIALYSATE_FLOW_RATE_OUT_OF_MAX_RANGE, FLOW_OUT_OF_RANGE_TIME_OUT_MS, FLOW_OUT_OF_RANGE_TIME_OUT_MS ); + initPersistentAlarm( ALARM_ID_DG_RO_FLOW_RATE_OUT_OF_MAX_RANGE, FLOW_OUT_OF_RANGE_TIME_OUT_MS, FLOW_OUT_OF_RANGE_TIME_OUT_MS ); dataPublicationCounter = DATA_PUBLISH_COUNTER_START_COUNT; } @@ -81,32 +98,35 @@ { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = getNVRecord2Driver( GET_CAL_FLOW_SENSORS, (U08*)&flowSensorsCalRecord, sizeof( DG_FLOW_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_DIALYSATE_FLOW_SENSOR_INVALID_CAL_RECORD ); - result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_FLOW_SENSORS_INVALID_CAL_RECORD ); + result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + return result; } /*********************************************************************//** * @brief - * The execFlowSesnorsMonitor function executes the flow sensors monitor. + * The execFlowSensorsMonitor function executes the flow sensors monitor. * @details Inputs: none * @details Outputs: flowSensorStatus, flowSensorsCalRecord * @return none *************************************************************************/ -void execFlowSesnorsMonitor( void ) +void execFlowSensorsMonitor( void ) { U08 i; - U08 countsIndex; - U16 oldestEdgeCount; - U16 oldest2CurrentEdgeDiff; - F32 flowBeforeCalibrationLPM; + U08 countsIndex = 0; + U16 oldestEdgeCount = 0; + U16 oldest2CurrentEdgeDiff = 0; + F32 flowBeforeCalibrationLPM = 0.0F; + F32 currentFlowLPM = 0.0F; + BOOL isFlowOutOfRange = FALSE; // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) { getNVRecord2Driver( GET_CAL_FLOW_SENSORS, (U08*)&flowSensorsCalRecord, sizeof( DG_FLOW_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_DIALYSATE_FLOW_SENSOR_INVALID_CAL_RECORD ); + NUM_OF_CAL_DATA_FLOW_SENSORS, ALARM_ID_DG_FLOW_SENSORS_INVALID_CAL_RECORD ); } for ( i = 0; i < NUM_OF_FLOW_SENSORS; i++ ) @@ -137,19 +157,23 @@ #ifndef _VECTORCAST_ default: - // TODO software fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLOW_SENSOR_SELECTED, i ); break; #endif } - flowSensorStatus[ i ].edgeCountsIndex = INC_WRAP( countsIndex, 0, FLOW_SENSORS_EDGES_BUFFER_LENGTH ); + flowSensorStatus[ i ].edgeCountsIndex = INC_WRAP( countsIndex, 0, ( FLOW_SENSORS_EDGES_BUFFER_LENGTH - 1 ) ); } + // Check the dialysate flow rate for the maximum allowed flow rate + currentFlowLPM = getMeasuredFlowRateLPM( DIALYSATE_FLOW_SENSOR ); + isFlowOutOfRange = ( currentFlowLPM > MAX_FLOWRATE_LPM ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_DG_DIALYSATE_FLOW_RATE_OUT_OF_MAX_RANGE, isFlowOutOfRange, currentFlowLPM, MAX_FLOWRATE_LPM ); - // TODO dialysate flow alarm. Is it needed? - //currentFlow = getMeasuredDialysateFlowRate(); - //isFlowOutOfUpperRange = ( currentFlow > MAX_DIALYSATE_FLOWRATE_LPM ? TRUE : FALSE ); - //checkPersistentAlarm( ALARM_ID_DIALYSATE_FLOW_RATE_OUT_OF_RANGE, isFlowOutOfUpperRange, currentFlow, MAX_DIALYSATE_FLOWRATE_LPM ); + // Check the RO flow rate for the maximum allowed flow rate + currentFlowLPM = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); + isFlowOutOfRange = ( currentFlowLPM > MAX_FLOWRATE_LPM ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_DG_RO_FLOW_RATE_OUT_OF_MAX_RANGE, isFlowOutOfRange, currentFlowLPM, MAX_FLOWRATE_LPM ); publishFlowSensorsData(); } @@ -164,11 +188,28 @@ *************************************************************************/ F32 getMeasuredFlowRateLPM( FLOW_SENSORS_T sensorId ) { - return getF32OverrideValue( &flowSensorStatus[ sensorId ].measuredFlowLPM ); + F32 flow = getF32OverrideValue( &flowSensorStatus[ sensorId ].measuredFlowLPM ); + + return flow; } /*********************************************************************//** * @brief + * The getMeasuredROFlowRateWithConcPumpsLPM function gets the measured flow + * rate of a flow sensor in L/min. + * @details Inputs: flowSensorStatus + * @details Outputs: flowSensorStatus + * @return the current flow rate (in L/min). + *************************************************************************/ +F32 getMeasuredROFlowRateWithConcPumpsLPM( void ) +{ + F32 flow = getF32OverrideValue( &flowSensorStatus[ RO_FLOW_SENSOR ].measuredROFlowWithCPsLPM ); + + return flow; +} + +/*********************************************************************//** + * @brief * The publishFlowSensorsData function publishes flow sensors data at * the set interval. * @details Inputs: flowSensorsDataPublicationCounter, @@ -182,13 +223,13 @@ if ( ++dataPublicationCounter >= getU32OverrideValue( &flowSensorsDataPublishInterval ) ) { FLOW_SENSORS_DATA_T data; + data.ROFlowRateLPM = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); data.dialysateFlowRateLPM = getMeasuredFlowRateLPM( DIALYSATE_FLOW_SENSOR ); - data.ROFlowRateWithCPsLPM = getF32OverrideValue( &flowSensorStatus[ RO_FLOW_SENSOR ].measuredROFlowWithCPsLPM ); + data.ROFlowRateWithCPsLPM = getMeasuredROFlowRateWithConcPumpsLPM(); dataPublicationCounter = 0; broadcastData( MSG_ID_DG_FLOW_SENSORS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( FLOW_SENSORS_DATA_T ) ); - } } @@ -278,12 +319,15 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() ) + if ( sensorId < NUM_OF_FLOW_SENSORS ) { - flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData = flowSensorStatus[ sensorId ].measuredFlowLPM.data; - flowSensorStatus[ sensorId ].measuredFlowLPM.ovData = flowLPM; - flowSensorStatus[ sensorId ].measuredFlowLPM.override = OVERRIDE_KEY; - result = TRUE; + if ( TRUE == isTestingActivated() ) + { + flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData = flowSensorStatus[ sensorId ].measuredFlowLPM.data; + flowSensorStatus[ sensorId ].measuredFlowLPM.ovData = flowLPM; + flowSensorStatus[ sensorId ].measuredFlowLPM.override = OVERRIDE_KEY; + result = TRUE; + } } return result; @@ -302,13 +346,16 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() ) + if ( sensorId < NUM_OF_FLOW_SENSORS ) { - flowSensorStatus[ sensorId ].measuredFlowLPM.data = flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData; - flowSensorStatus[ sensorId ].measuredFlowLPM.override = OVERRIDE_RESET; - flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData = 0.0; - flowSensorStatus[ sensorId ].measuredFlowLPM.ovData = 0.0; - result = TRUE; + if ( TRUE == isTestingActivated() ) + { + flowSensorStatus[ sensorId ].measuredFlowLPM.data = flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData; + flowSensorStatus[ sensorId ].measuredFlowLPM.override = OVERRIDE_RESET; + flowSensorStatus[ sensorId ].measuredFlowLPM.ovInitData = 0.0F; + flowSensorStatus[ sensorId ].measuredFlowLPM.ovData = 0.0F; + result = TRUE; + } } return result;