/**********************************************************************//** * * Copyright (c) 2019-2020 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 Pressures.c * * @date 05-Apr-2020 * @author S. Nash * * @brief Monitor for DG pressure sensors. * **************************************************************************/ #include "Pressures.h" #include "AlarmMgmt.h" #include "FPGA.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskPriority.h" #include "Timers.h" /** * @addtogroup DGPressures * @{ */ // ********** private definitions ********** /// Default publication interval for pressure and occlusion data. #define PRESSURES_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< interval (ms/task time) at which the pressures data is published on the CAN bus. /// Defined states for the pressures monitor state machine. typedef enum PresOccl_States { PRESSURE_INIT_STATE = 0, ///< Initialization state. PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. NUM_OF_PRESSURE_STATES ///< Number of pressure monitor states. } PRESSURE_STATE_T; /// Defined states for the pressures self test state machine. typedef enum Pressures_Self_Test_States { PRESSURE_SELF_TEST_STATE_START = 0, ///< Self test start state. PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. PRESSURE_TEST_STATE_COMPLETE, ///< Self test completed state. NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure self test states. } PRESSURE_SELF_TEST_STATE_T; // ********** private data ********** static PRESSURE_STATE_T pressuresState = PRESSURE_INIT_STATE; ///< current state of pressure monitor state machine. static U32 pressuresDataPublicationTimerCounter = 0; ///< used to schedule pressure data publication to CAN bus. static OVERRIDE_U32_T pressuresDataPublishInterval = { PRESSURES_DATA_PUB_INTERVAL, PRESSURES_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish pressures data to CAN bus. static OVERRIDE_F32_T pressures[ NUM_OF_PRESSURE_SENSORS ]; ///< Measured weight from load cells. static PRESSURE_SELF_TEST_STATE_T pressuresSelfTestState = PRESSURE_SELF_TEST_STATE_START; ///< current pressure self test state. static U32 pressuresSelfTestTimerCount = 0; ///< timer counter for pressure self test. // ********** private function prototypes ********** static PRESSURE_STATE_T handlePressuresInitState( void ); static PRESSURE_STATE_T handlePressuresContReadState( void ); static void checkPressures( void ); static void publishPressuresData( void ); static DATA_GET_PROTOTYPE( U32, getPublishPressuresDataInterval ); /**@}*/ /*********************************************************************//** * @brief * The initPressures function initializes the Pressures module. * @details * Inputs : none * Outputs : Pressures module initialized. * @return none *************************************************************************/ void initPressures( void ) { // TODO - anything to initialize? } /*********************************************************************//** * @brief * The execPressures function executes the pressure monitor. * @details * Inputs : pressuresState * Outputs : pressuresState * @return none *************************************************************************/ void execPressures( void ) { // state machine switch ( pressuresState ) { case PRESSURE_INIT_STATE: pressuresState = handlePressuresInitState(); break; case PRESSURE_CONTINUOUS_READ_STATE: pressuresState = handlePressuresContReadState(); break; default: pressuresState = PRESSURE_INIT_STATE; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, 0, pressuresState ) // TODO - replace 1st param with s/w fault enum break; } // publish pressure/occlusion data on interval publishPressuresData(); } /*********************************************************************//** * @brief * The handlePressuresInitState function handles the pressures initialize state \n * of the pressures monitor state machine. * @details * Inputs : TBD * Outputs : TBD * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressuresInitState( void ) { PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; return result; } /*********************************************************************//** * @brief * The handlePressuresContReadState function handles the continuous read state \n * of the pressures monitor state machine. * @details * Inputs : TBD * Outputs : pressure sensor values updated * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressuresContReadState( void ) { PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; U16 roIn = getFPGAROPumpInletPressure(); U16 roOut = getFPGAROPumpOutletPressure(); U16 drainIn = getFPGADrainPumpInletPressure(); U16 drainOut = getFPGADrainPumpOutletPressure(); // TODO - convert ADC counts to mmHg for each sensor pressures[ PRESSURE_SENSOR_RO_PUMP_INLET ].data = (F32)roIn; pressures[ PRESSURE_SENSOR_RO_PUMP_OUTLET ].data = (F32)roOut; pressures[ PRESSURE_SENSOR_DRAIN_PUMP_INLET ].data = (F32)drainIn; pressures[ PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ].data = (F32)drainOut; // TODO - any filtering required??? // check for pressure ranges checkPressures(); // TODO - any other checks return result; } /*********************************************************************//** * @brief * The checkPressures function checks the pressure sensors are in range. * @details * Inputs : pressures[] * Outputs : none * @return none *************************************************************************/ static void checkPressures( void ) { } /*********************************************************************//** * @brief * The getPublishPresOcclDataInterval function gets the pressure/occlusion data \n * publication interval. * @details * Inputs : pressuresDataPublishInterval * Outputs : none * @return the current pressures data publication interval (in task intervals). *************************************************************************/ U32 getPublishPressuresDataInterval( void ) { U32 result = pressuresDataPublishInterval.data; if ( OVERRIDE_KEY == pressuresDataPublishInterval.override ) { result = pressuresDataPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The getMeasuredArterialPressure function gets the current arterial pressure. * @details * Inputs : arterialPressure * Outputs : none * @return the current arterial pressure (in mmHg). *************************************************************************/ F32 getMeasuredDGPressure( U32 pressureID ) { F32 result = 0.0; if ( pressureID <= NUM_OF_PRESSURE_SENSORS ) { if ( OVERRIDE_KEY == pressures[ pressureID ].override ) { result = pressures[ pressureID ].ovData; } else { result = pressures[ pressureID ].data; } } else { activateAlarmNoData( ALARM_ID_SOFTWARE_FAULT ); } return result; } /*********************************************************************//** * @brief * The publishPressuresData function publishes DG pressures data at the \n * set interval. * @details * Inputs : pressuresDataPublicationTimerCounter * Outputs : DG Pressures data are published to CAN bus. * @return none *************************************************************************/ static void publishPressuresData( void ) { // publish pressure/occlusion data on interval if ( ++pressuresDataPublicationTimerCounter >= getPublishPressuresDataInterval() ) { F32 roIn = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ); F32 roOut = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); F32 drainIn = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_INLET ); F32 drainOut = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); broadcastPressuresData( roIn, roOut, drainIn, drainOut ); pressuresDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The execPressuresTest function executes the state machine for the \n * Pressures self test. * @details * Inputs : none * Outputs : none * @return the current state of the Pressures self test. *************************************************************************/ SELF_TEST_STATUS_T execPressuresTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; // TODO - implement self test(s) return result; } /**@}*/ /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetPressuresDataPublishIntervalOverride function overrides the \n * pressure and occlusion data publish interval. * @details * Inputs : none * Outputs : pressuresDataPublishInterval * @param value : override pressure and occlusion data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetPressuresDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; result = TRUE; pressuresDataPublishInterval.ovData = intvl; pressuresDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetPressuresDataPublishIntervalOverride function resets the override \n * of the pressure and occlusion data publish interval. * @details * Inputs : none * Outputs : pressuresDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetPressuresDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; pressuresDataPublishInterval.override = OVERRIDE_RESET; pressuresDataPublishInterval.ovData = pressuresDataPublishInterval.ovInitData; } return result; } /************************************************************************* * @brief * The testSetDGPressureSensorOverride function overrides the value of the \n * specified pressure sensor with a given value. * Inputs : none * Outputs : pressures[] * @param sensor : ID of pressure sensor to override for * @param value : override value for the given pressure sensor ID * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDGPressureSensorOverride( U32 sensor, F32 value ) { BOOL result = FALSE; if ( sensor < NUM_OF_PRESSURE_SENSORS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; pressures[ sensor ].ovData = value; pressures[ sensor ].override = OVERRIDE_KEY; } } return result; } /************************************************************************* * @brief * The testResetDGPressureSensorOverride function resets the override of the \n * specified DG pressure sensor. * @details * Inputs : none * Outputs : pressures[] * @param value : ID of sensor to reset override pressure for * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetDGPressureSensorOverride( U32 sensor ) { BOOL result = FALSE; if ( sensor < NUM_OF_PRESSURE_SENSORS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; pressures[ sensor ].override = OVERRIDE_RESET; pressures[ sensor ].ovData = pressures[ sensor ].ovInitData; } } return result; }