Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -rea5e0b24346fda778c846c6c3b29bd2236e9dc93 -r89a95cb8fbc537f1c7a5448a05788342f7319c01 --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision ea5e0b24346fda778c846c6c3b29bd2236e9dc93) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 89a95cb8fbc537f1c7a5448a05788342f7319c01) @@ -1,626 +1,673 @@ -/************************************************************************** - * - * 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 DialOutFlow.c - * - * @date 7-Jan-2020 - * @author L. Baloa - * - * @brief Monitor/Controller for dialysate outlet pump and load cell sensor. - * - **************************************************************************/ - -#ifndef _VECTORCAST_ - #include -#endif - -#include "etpwm.h" -#include "gio.h" -#include "mibspi.h" - -#include "Common.h" -#include "FPGA.h" -#include "InternalADC.h" -#include "OperationModes.h" -#include "PIControllers.h" -#include "SystemCommMessages.h" -#include "TaskGeneral.h" -#include "TaskPriority.h" -#include "Timers.h" -#include "FIRFilters.h" -#include "DialOutFlow.h" - -// ********** private definitions ********** - -#define DIAL_OUT_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) // interval (ms/task time) at which the dialIn flow data is published on the CAN bus - -#define MAX_DIAL_OUT_FLOW_RATE 500 // mL/min -#define MIN_DIAL_OUT_FLOW_RATE 100 // mL/min - -#define MAX_DIAL_OUT_PUMP_PWM_STEP_CHANGE 0.005 // duty cycle TODO - fixed or parameterized or set in motor controller? -#define MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE 0.88 // controller will error if PWM duty cycle > 90%, so set max to 88% -#define MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE 0.12 // controller will error if PWM duty cycle < 10%, so set min to 12% - -#define DIP_CONTROL_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) // interval (ms/task time) at which the dialIn pump is controlled -#define DIP_P_COEFFICIENT 0.0002 // P term for dialIn pump control -#define DIP_I_COEFFICIENT 0.00002 // I term for dialIn pump control -#define DIP_MAX_ERROR_SUM 10.0 // for anti-wind-up in I term -#define DIP_MIN_ERROR_SUM -10.0 -#define DIP_MAX_PWM_DC_DELTA 0.01 // prevents large steps in PWM duty cycle -#define DIP_MIN_PWM_DC_DELTA -0.01 - -#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 // motor controller current should not exceed this when pump should be stopped -#define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 // motor controller current should always exceed this when pump should be running -#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 // motor controller current should not exceed this when pump should be running -#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 // motor controller current errors persisting beyond this duration will trigger an alarm - -#define DIP_SPEED_ADC_TO_RPM_FACTOR 1.375 // conversion factor from ADC counts to RPM for dialIn pump motor -#define DIP_CURRENT_ADC_TO_MA_FACTOR 2.65 // conversion factor from ADC counts to mA for dialIn pump motor - -#define DIP_REV_PER_LITER 124.0 // rotor revolutions per liter -#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) -#define DIP_GEAR_RATIO 32.0 // dialIn pump motor to dialIn pump gear ratio -#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0003717 // ~27 BP motor RPM = 1% PWM duty cycle -#define DIP_PWM_ZERO_OFFSET 0.1 // 10% PWM duty cycle = zero speed -#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) - -#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 // BP analog signals are 0-3V (while int. ADC ref V is 3.3V) -#define DIAL_IN_PUMP_ADC_MID_PT_BITS ( (F32)( INT_ADC_FULL_SCALE_BITS >> 1 ) * ( DIAL_IN_PUMP_ADC_FULL_SCALE_V / INT_ADC_REF_V ) ) -#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_MID_PT_BITS ) - -#define DIAL_OUT_FLOW_SAMPLE_FREQ ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) -#define SIZE_OF_ROLLING_AVG (U32)( (F32)DIAL_IN_FLOW_SAMPLE_FREQ * 0.8 ) // measured dialIn flow is filtered w/ moving average -#define MAX_FLOW_FILTER_INTERVAL 5 // slowest sample interval for filter is every 5th sample - -// pin assignments for pump stop and direction outputs -#define STOP_DI_PUMP_GIO_PORT_PIN 2U -#define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 // (ENA - re-purposed as output GPIO) - -// dialOut pump stop and direction macros -#define SET_DIP_DIR() {mibspiREG5->PC3 |= DIR_DI_PUMP_SPI5_PORT_MASK;} -#define SET_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) -#define CLR_DIP_DIR() {mibspiREG5->PC3 &= ~DIR_DI_PUMP_SPI5_PORT_MASK;} -#define CLR_DIP_STOP() gioSetBit( gioPORTA, STOP_DI_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) - - -// ********** private data ********** - -static DIALOUT_FLOW_STATE_T dialOutFlowState = DIALOUT_FLOW_STOP_STATE; // current state of dialOut flow state machine - -static U32 dialOutFlowDataPublicationTimerCounter = 5; // used to schedule dialIn flow data publication to CAN bus - -DATA_DECL( U32, DialOutFlowDataPub, dialOutFlowDataPublishInterval, DIAL_OUT_FLOW_DATA_PUB_INTERVAL, DIAL_OUT_FLOW_DATA_PUB_INTERVAL ); // interval (in ms) at which to publish dialIn flow data to CAN bus -DATA_DECL( S32, TargetDialOutFlowRate, targetDialOutFlowRate, 0, 0 ); // requested dialIn flow rate -DATA_DECL( F32, MeasuredDialOutFlowRate, measuredDialOutFlowRate, 0.0, 0.0 ); // measured dialIn flow rate -DATA_DECL( F32, MeasuredDialOutPumpRotorSpeed, dialOutPumpRotorSpeedRPM, 0.0, 0.0 );// measured dialIn pump rotor speed -DATA_DECL( F32, MeasuredDialOutPumpSpeed, dialOutPumpSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor speed -DATA_DECL( F32, MeasuredDialOutPumpMCSpeed, adcDialOutPumpMCSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor controller speed -DATA_DECL( F32, MeasuredDialOutPumpMCCurrent, adcDialOutPumpMCCurrentmA, 0.0, 0.0 );// measured dialIn pump motor controller current - -// Rx values -static U32 rxTotalTargetVolumeInMl; -static U32 rxTargetTimeInSamples; -static U32 rxTargetFlowRate; -static F32 targetVolumeRatePerSample; - -// Controller key values -static F32 targetVolumeInMl; -static F32 measuredVolumeInMl; -static F32 sentPWM; - -// ********** private function prototypes ********** - -static DIALOUT_FLOW_STATE_T handleDialOutFlowStopState( void ); -static DIALOUT_FLOW_STATE_T handleDialOutFlowRunUFState( void ); -static DIALOUT_FLOW_STATE_T handleDialOutFlowPauseUFState( void ); - -static void setControlSignalPWM( F32 newPWM ); -static void stopDialOutPump( void ); -static void updateTargetVolume( void ); - -static void setDialOutPumpDirection( MOTOR_DIR_T dir ); - - - -//delete-this static void releaseDialOutPumpStop( void ); -static void publishDialOutFlowData( void ); -static DATA_GET_PROTOTYPE( U32, getPublishDialOutFlowDataInterval ); - - -static void setControlSignalPWM( F32 newPWM ) -{ - F32 roundOffSet = newPWM != 0.0 ? FLOAT_TO_INT_ROUNDUP_OFFSET : 0.0; - etpwmSetCmpA( etpwmREG2, (U32)( (S32)( ( newPWM * (F32)(etpwmREG2->TBPRD) ) + roundOffSet) ) ); -} - -static void updateTargetVolume( void ) -{ - rxTotalTargetVolumeInMl += targetVolumeRatePerSample; -} - - -BOOL setDialOutFlowRxTotalVolumeAndRxTime( U32 rxTotaVolumeInMl, U32 rxTotalTimeInMinutes, U32 rxFlowRate) -{ - #define SECS_IN_MIN 60 - - - BOOL returnValue = TRUE; - - rxTotalTargetVolumeInMl = rxTotaVolumeInMl; - rxTargetTimeInSamples = rxTotalTimeInMinutes * SEC_PER_MIN * DIAL_OUT_FLOW_SAMPLE_FREQ ; - rxTargetFlowRate = rxFlowRate; - - targetVolumeRatePerSample = (F32) rxTotalTargetVolumeInMl / (F32) rxTargetTimeInSamples; - - - return returnValue; -} - -/************************************************************************* - * @brief initDialOutFlow - * The initDialOutFlow function initializes the DialOutFlow module. - * @details - * Inputs : none - * Outputs : DialOutFlow module initialized. - * @param none - * @return none - *************************************************************************/ -void initDialOutFlow( void ) -{ - dialOutFlowState = DIALOUT_FLOW_STOP_STATE; - targetVolumeInMl = 0.0; - - stopDialOutPump(); - setDialOutPumpDirection( MOTOR_DIR_FORWARD ); - - initializeFilter(FILTER_ID_LOAD_CELL_WEIGHT, 0); - - // initialize dialysate outlet flow PI controller - initializePIController( PI_CONTROLLER_ID_LOAD_CELL, MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE, - DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, - MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE); -} - - -/************************************************************************* - * @brief execDialOutFlowMonitor - * The execDialOutFlowMonitor function executes the dialIn flow monitor. - * @details - * Inputs : none - * Outputs : measuredDialOutFlowRate, adcDialOutPumpMCSpeedRPM, adcDialOutPumpMCCurrentmA - * @param none - * @return none - *************************************************************************/ -/*void execDialOutFlowMonitor( void ) -{ - U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); - U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); - F32 dipFlow = getFPGADialysateFlow(); - - adcDialOutPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; - adcDialOutPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; - - filterDialOutFlowReadings( dipFlow ); - - // don't start enforcing checks until out of init/POST mode - if ( getCurrentOperationMode() != MODE_INIT ) - { - checkDialOutPumpDirection(); - checkDialOutPumpMCCurrent(); - } - - // publish dialIn flow data on interval - publishDialOutFlowData(); -}*/ - -/************************************************************************* - * @brief execDialOutFlowController - * The execDialOutFlowController function executes the dialIn flow controller. - * @details - * Inputs : dialOutPumpState - * Outputs : dialOutPumpState - * @param none - * @return none - *************************************************************************/ -void execDialOutFlowController( void ) -{ - switch ( dialOutFlowState ) - { - case DIALOUT_FLOW_STOP_STATE: - dialOutFlowState = handleDialOutFlowStopState(); - break; - - case DIALOUT_FLOW_RUN_UF_STATE: - dialOutFlowState = handleDialOutFlowRunUFState(); - break; - - case DIALOUT_FLOW_PAUSE_UF_STATE: - dialOutFlowState = handleDialOutFlowPauseUFState(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_STATE, dialOutFlowState ) - break; - } -} - -/************************************************************************* - * @brief handleDialOutFlowStopState - * The handleDialOutFlowStopState function handles the dialout flow stop state \n - * of the dialout flow state machine. - * @details - * Inputs : targetDialOutFlowRate, dialOutPumpDirection - * Outputs : dialOutPumpPWMDutyCyclePctSet, dialOutPumpDirectionSet, isDialOutPumpOn - * @param none - * @return next state - *************************************************************************/ -static DIALOUT_FLOW_STATE_T handleDialOutFlowStopState( void ) -{ - DIALOUT_FLOW_STATE_T result = DIALOUT_FLOW_STOP_STATE; - - stopDialOutPump(); - - return result; -} - -/************************************************************************* - * @brief handleDialOutFlowPauseUFState - * The handleDialOutPumpRampingDownState function handles the ramp down state \n - * of the dialIn pump controller state machine. - * @details - * Inputs : dialOutPumpPWMDutyCyclePctSet - * Outputs : dialOutPumpPWMDutyCyclePctSet - * @param none - * @return next state - *************************************************************************/ -static DIALOUT_FLOW_STATE_T handleDialOutFlowPauseUFState( void ) -{ - sentPWM = runPIController( PI_CONTROLLER_ID_LOAD_CELL, targetVolumeInMl, measuredVolumeInMl ); - - setControlSignalPWM( sentPWM ); - - return DIALOUT_FLOW_PAUSE_UF_STATE; -} - -/************************************************************************* - * @brief handleDialOutFlowRunUFState - * The handleDialOutFlowRunUFState function handles the dialout flow - * controller during run state. - * @details - * Inputs : none - * Outputs : dialout flow State - * @param none - * @return next state - *************************************************************************/ -static DIALOUT_FLOW_STATE_T handleDialOutFlowRunUFState( void ) -{ - updateTargetVolume(); - - sentPWM = runPIController( PI_CONTROLLER_ID_LOAD_CELL, targetVolumeInMl, measuredVolumeInMl ); - - setControlSignalPWM( sentPWM ); - - return DIALOUT_FLOW_RUN_UF_STATE; -} - -/************************************************************************* - * @brief stopDialOutPump - * The stopDialOutPump function sets the dialout flow stop signal and PWM - * duty cycle to 0.0. - * @details - * Inputs : none - * Outputs : dialOut pump stop signal activated, PWM duty cycle zeroed - * @param none - * @return none - *************************************************************************/ -static void stopDialOutPump( void ) -{ - setControlSignalPWM(0.0); - SET_DIP_STOP(); -} - - -/************************************************************************* - * @brief setDialOutPumpDirection - * The setDialOutPumpDirection function sets the set dialIn pump direction to \n - * the given direction. - * @details - * Inputs : dialOutPumpState - * Outputs : dialOutPumpState - * @param dir : dialIn pump direction to set - * @return none - *************************************************************************/ -static void setDialOutPumpDirection( MOTOR_DIR_T dir ) -{ - switch ( dir ) - { - case MOTOR_DIR_FORWARD: - SET_DIP_DIR(); - break; - - case MOTOR_DIR_REVERSE: - CLR_DIP_DIR(); - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_DIRECTION, dir ) - break; - } -} - -/************************************************************************* - * @brief getPublishDialOutFlowDataInterval - * The getPublishDialOutFlowDataInterval function gets the dialIn flow data \n - * publication interval. - * @details - * Inputs : dialOutFlowDataPublishInterval - * Outputs : none - * @param none - * @return the current dialIn flow data publication interval (in ms). - *************************************************************************/ -DATA_GET( U32, getPublishDialOutFlowDataInterval, dialOutFlowDataPublishInterval ) - -/************************************************************************* - * @brief getTargetDialOutFlowRate - * The getTargetDialOutFlowRate function gets the current target dialIn flow \n - * rate. - * @details - * Inputs : targetDialOutFlowRate - * Outputs : none - * @param none - * @return the current target dialIn flow rate (in mL/min). - *************************************************************************/ -DATA_GET( S32, getTargetDialOutFlowRate, targetDialOutFlowRate ) - -/************************************************************************* - * @brief getMeasuredDialOutFlowRate - * The getMeasuredDialOutFlowRate function gets the measured dialIn flow \n - * rate. - * @details - * Inputs : measuredDialOutFlowRate - * Outputs : none - * @param none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutVolume, measuredDialOutFlowRate ) - -/************************************************************************* - * @brief getMeasuredDialOutPumpRotorSpeed - * The getMeasuredDialOutPumpRotorSpeed function gets the measured dialIn flow \n - * rate. - * @details - * Inputs : dialOutPumpRotorSpeedRPM - * Outputs : none - * @param none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutPumpRotorSpeed, dialOutPumpRotorSpeedRPM ) - -/************************************************************************* - * @brief getMeasuredDialOutPumpSpeed - * The getMeasuredDialOutPumpSpeed function gets the measured dialIn flow \n - * rate. - * @details - * Inputs : dialOutPumpSpeedRPM - * Outputs : none - * @param none - * @return the current dialIn flow rate (in mL/min). - *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutPumpSpeed, dialOutPumpSpeedRPM ) - -/************************************************************************* - * @brief getMeasuredDialOutPumpMCSpeed - * The getMeasuredDialOutPumpMCSpeed function gets the measured dialIn pump \n - * speed. - * @details - * Inputs : adcDialOutPumpMCSpeedRPM - * Outputs : none - * @param none - * @return the current dialIn pump speed (in RPM). - *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutPumpMCSpeed, adcDialOutPumpMCSpeedRPM ) - -/************************************************************************* - * @brief getMeasuredDialOutPumpMCCurrent - * The getMeasuredDialOutPumpMCCurrent function gets the measured dialIn pump \n - * current. - * @details - * Inputs : adcDialOutPumpMCCurrentmA - * Outputs : none - * @param none - * @return the current dialIn pump current (in mA). - *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutPumpMCCurrent, adcDialOutPumpMCCurrentmA ) - -/************************************************************************* - * @brief publishDialOutFlowData - * The publishDialOutFlowData function publishes dialIn flow data at the set \n - * interval. - * @details - * Inputs : target flow rate, measured flow rate, measured MC speed, \n - * measured MC current - * Outputs : DialIn flow data is published to CAN bus. - * @param none - * @return none - *************************************************************************/ -static void publishDialOutFlowData( void ) -{ - // publish dialIn flow data on interval - if ( ++dialOutFlowDataPublicationTimerCounter > DIAL_OUT_FLOW_DATA_PUB_INTERVAL ) - { -#ifdef DEBUG_ENABLED - // TODO - temporary debug code - remove later - char debugFlowStr[ 256 ]; - - sprintf( debugFlowStr, "St:%5d, Set Pt:%5d, Meas. Vol:%5d, PWM:%5d \n", (S32) dialOutFlowState, (S32) targetVolumeInMl, (S32) measuredVolumeInMl,(S32)(sentPWM * FRACTION_TO_PERCENT_FACTOR) ); - sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); -#endif - //broadcastDialOutFlowData( flowStPt, measFlow, measRotSpd, measSpd, measMCSpd, measMCCurr, pumpPWMPctDutyCycle ); - dialOutFlowDataPublicationTimerCounter = 0; - } -} - - -/************************************************************************* - * @brief execDialOutFlowTest - * The execDialOutFlowTest function executes the state machine for the \n - * DialOutFlow self test. - * @details - * Inputs : none - * Outputs : none - * @param none - * @return the current state of the DialOutFlow self test. - *************************************************************************/ -SELF_TEST_STATUS_T execDialOutFlowTest( void ) -{ - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - - // TODO - implement self test(s) - - return result; -} - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/************************************************************************* - * @brief testSetDialOutFlowDataPublishIntervalOverride - * The testSetDialOutFlowDataPublishIntervalOverride function overrides the \n - * dialIn flow data publish interval. - * @details - * Inputs : none - * Outputs : dialOutFlowDataPublishInterval - * @param value : override dialIn flow data publish interval with (in ms) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetDialOutFlowDataPublishIntervalOverride( U32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - U32 intvl = value / TASK_PRIORITY_INTERVAL; - - result = TRUE; - dialOutFlowDataPublishInterval.ovData = intvl; - dialOutFlowDataPublishInterval.override = OVERRIDE_KEY; - } - - return result; -} - -/************************************************************************* - * @brief testResetDialOutFlowDataPublishIntervalOverride - * The testResetDialOutFlowDataPublishIntervalOverride function resets the override \n - * of the dialIn flow data publish interval. - * @details - * Inputs : none - * Outputs : dialOutFlowDataPublishInterval - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetDialOutFlowDataPublishIntervalOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - dialOutFlowDataPublishInterval.override = OVERRIDE_RESET; - dialOutFlowDataPublishInterval.ovData = dialOutFlowDataPublishInterval.ovInitData; - } - - return result; -} - -/************************************************************************* - * @brief testSetTargetDialOutFlowRateOverride and testResetTargetDialOutFlowRateOverride - * The testSetTargetDialOutFlowRateOverride function overrides the target \n - * dialIn flow rate. \n - * The testResetTargetDialOutFlowRateOverride function resets the override of the \n - * target dialIn flow rate. - * @details - * Inputs : none - * Outputs : targetDialOutFlowRate - * @param value : override target dialIn flow rate (in mL/min) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( S32, testSetTargetDialOutFlowRateOverride, testResetTargetDialOutFlowRateOverride, targetDialOutFlowRate ) - -/************************************************************************* - * @brief testSetMeasuredDialOutFlowRateOverride and testResetMeasuredDialOutFlowRateOverride - * The testResetMeasuredDialOutFlowRateOverride function overrides the measured \n - * dialIn flow rate. \n - * The testResetOffButtonStateOverride function resets the override of the \n - * measured dialIn flow rate. - * @details - * Inputs : none - * Outputs : measuredDialOutFlowRate - * @param value : override measured dialIn flow rate (in mL/min) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutFlowRateOverride, testResetMeasuredDialOutFlowRateOverride, measuredDialOutFlowRate ) - -/************************************************************************* - * @brief testSetMeasuredDialOutPumpRotorSpeedOverride and testResetMeasuredDialOutPumpRotorSpeedOverride - * The testSetMeasuredDialOutPumpRotorSpeedOverride function overrides the measured \n - * dialIn pump rotor speed. \n - * The testResetMeasuredDialOutPumpRotorSpeedOverride function resets the override of the \n - * measured dialIn pump rotor speed. - * @details - * Inputs : none - * Outputs : dialOutPumpRotorSpeedRPM - * @param value : override measured dialIn pump rotor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpRotorSpeedOverride, testResetMeasuredDialOutPumpRotorSpeedOverride, dialOutPumpRotorSpeedRPM ) - -/************************************************************************* - * @brief testSetMeasuredDialOutPumpSpeedOverride and testResetMeasuredDialOutPumpSpeedOverride - * The testSetMeasuredDialOutPumpSpeedOverride function overrides the measured \n - * dialIn pump motor speed. \n - * The testResetMeasuredDialOutPumpSpeedOverride function resets the override of the \n - * measured dialIn pump motor speed. - * @details - * Inputs : none - * Outputs : dialOutPumpSpeedRPM - * @param value : override measured dialIn pump motor speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpSpeedOverride, testResetMeasuredDialOutPumpSpeedOverride, dialOutPumpSpeedRPM ) - -/************************************************************************* - * @brief testSetMeasuredDialOutPumpMCSpeedOverride and testResetMeasuredDialOutPumpMCSpeedOverride - * The testSetMeasuredDialOutPumpMCSpeedOverride function overrides the measured \n - * dialIn pump motor speed. \n - * The testResetMeasuredDialOutPumpMCSpeedOverride function resets the override of the \n - * measured dialIn pump motor speed. - * @details - * Inputs : none - * Outputs : adcDialOutPumpMCSpeedRPM - * @param value : override measured dialIn pump speed (in RPM) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpMCSpeedOverride, testResetMeasuredDialOutPumpMCSpeedOverride, adcDialOutPumpMCSpeedRPM ) - -/************************************************************************* - * @brief testSetMeasuredDialOutPumpMCCurrentOverride and testResetMeasuredDialOutPumpMCCurrentOverride - * The testSetMeasuredDialOutPumpMCCurrentOverride function overrides the measured \n - * dialIn pump motor current. \n - * The testResetMeasuredDialOutPumpMCCurrentOverride function resets the override of the \n - * measured dialIn pump motor current. - * @details - * Inputs : none - * Outputs : adcDialOutPumpMCCurrentmA - * @param value : override measured dialIn pump current (in mA) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpMCCurrentOverride, testResetMeasuredDialOutPumpMCCurrentOverride, adcDialOutPumpMCCurrentmA ) - - +/************************************************************************** + * + * 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 DialOutFlow.c + * + * @date 7-Jan-2020 + * @author L. Baloa + * + * @brief Monitor/Controller for dialysate outlet pump and load cell sensor. + * + **************************************************************************/ + +#ifndef _VECTORCAST_ + #include +#endif + +#include "etpwm.h" +#include "gio.h" +#include "spi.h" + +#include "Common.h" +#include "FPGA.h" +#include "InternalADC.h" +#include "OperationModes.h" +#include "PIControllers.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "TaskPriority.h" +#include "Timers.h" +#include "FIRFilters.h" +#include "DialOutFlow.h" + +// ********** private definitions ********** + +#define DIAL_OUT_FLOW_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) // interval (ms/task time) at which the dialIn flow data is published on the CAN bus + +#define MAX_DIAL_OUT_FLOW_RATE 500 // mL/min +#define MIN_DIAL_OUT_FLOW_RATE 100 // mL/min + +#define DIP_P_COEFFICIENT 0.0002 // P term for dialIn pump control +#define DIP_I_COEFFICIENT 0.00002 // I term for dialIn pump control +#define MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE 0.88 // controller will error if PWM duty cycle > 90%, so set max to 88% +#define MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE 0.12 // controller will error if PWM duty cycle < 10%, so set min to 12% + +#define DIP_CONTROL_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) // interval (ms/task time) at which the dialIn pump is controlled + +#define DIP_MAX_CURR_WHEN_STOPPED_MA 150.0 // motor controller current should not exceed this when pump should be stopped +#define DIP_MIN_CURR_WHEN_RUNNING_MA 150.0 // motor controller current should always exceed this when pump should be running +#define DIP_MAX_CURR_WHEN_RUNNING_MA 1000.0 // motor controller current should not exceed this when pump should be running +#define DIP_MAX_CURR_ERROR_DURATION_MS 2000 // motor controller current errors persisting beyond this duration will trigger an alarm + +#define DIP_REV_PER_LITER 124.0 // rotor revolutions per liter +#define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) +#define DIP_GEAR_RATIO 32.0 // dialIn pump motor to dialIn pump gear ratio +#define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0003717 // ~27 BP motor RPM = 1% PWM duty cycle +#define DIP_PWM_ZERO_OFFSET 0.1 // 10% PWM duty cycle = zero speed +#define DIP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * DIP_GEAR_RATIO * DIP_MOTOR_RPM_TO_PWM_DC_FACTOR + DIP_PWM_ZERO_OFFSET ) + +#define DIAL_IN_PUMP_ADC_FULL_SCALE_V 3.0 // BP analog signals are 0-3V (while int. ADC ref V is 3.3V) +#define DIAL_IN_PUMP_ADC_MID_PT_BITS ( (F32)( INT_ADC_FULL_SCALE_BITS >> 1 ) * ( DIAL_IN_PUMP_ADC_FULL_SCALE_V / INT_ADC_REF_V ) ) +#define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)DIAL_IN_PUMP_ADC_MID_PT_BITS ) + +#define DIAL_OUT_FLOW_SAMPLE_FREQ ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) + +// dialOut pump stop and direction macros +#define STOP_DO_PUMP_SPI4_PORT_MASK 0x00000200 // (SPI4CLK - re-purposed as output GPIO) + +#define SET_DOP_STOP() {spiREG4->PC3 |= STOP_DO_PUMP_SPI4_PORT_MASK;} +#define CLR_DOP_STOP() {spiREG4->PC3 &= ~STOP_DO_PUMP_SPI4_PORT_MASK;} + + +#define STOP_DO_PUMP_GIO_PORT_PIN 6U + +#define SET_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_HIGH ) +#define CLR_DOP_DIR() gioSetBit( gioPORTA, STOP_DO_PUMP_GIO_PORT_PIN, PIN_SIGNAL_LOW ) + +typedef enum DialOutFlow_Measured_Signals +{ + DIALOUT_LOAD_CELL_WEIGHT = 0, + DIALOUT_MOTOR_SPEED, + DIALOUT_MOTOR_CURRENT, + NUM_OF_DIALOUT_MEASURED_SIGNALS +} DIALOUT_MEASURED_SIGNALS_T; + + +// ********** private data ********** + +static DIALOUT_FLOW_STATE_T dialOutFlowState = DIALOUT_FLOW_STOP_STATE; // current state of dialOut flow state machine + +static U32 dialOutFlowDataPublicationTimerCounter = 5; // used to schedule dialIn flow data publication to CAN bus + +DATA_DECL( U32, DialOutFlowDataPub, dialOutFlowDataPublishInterval, DIAL_OUT_FLOW_DATA_PUB_INTERVAL, DIAL_OUT_FLOW_DATA_PUB_INTERVAL ); // interval (in ms) at which to publish dialIn flow data to CAN bus +DATA_DECL( S32, TargetDialOutFlowRate, targetDialOutFlowRate, 0, 0 ); // requested dialIn flow rate +DATA_DECL( F32, MeasuredDialOutFlowRate, measuredDialOutFlowRate, 0.0, 0.0 ); // measured dialIn flow rate +DATA_DECL( F32, MeasuredDialOutPumpRotorSpeed, dialOutPumpRotorSpeedRPM, 0.0, 0.0 );// measured dialIn pump rotor speed +DATA_DECL( F32, MeasuredDialOutPumpSpeed, dialOutPumpSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor speed +DATA_DECL( F32, MeasuredDialOutPumpMCSpeed, adcDialOutPumpMCSpeedRPM, 0.0, 0.0 ); // measured dialIn pump motor controller speed +DATA_DECL( F32, MeasuredDialOutPumpMCCurrent, adcDialOutPumpMCCurrentmA, 0.0, 0.0 );// measured dialIn pump motor controller current + +// Rx values +static U32 rxTotalTargetVolumeInMl; +static U32 rxTargetTimeInSamples; +static U32 rxTargetFlowRate; +static F32 targetVolumeRatePerSample; + +// Variables used in loop + + +// Controller key values +static F32 loadCellVolumeInMl; +static F32 bagStartVolumeInMl; + +static F32 bagMeasuredUFVolumeInMl; +static F32 accumulativeTotalUFVolumeInMl; + +static F32 totalMeasuredUFVolumeInMl; +static F32 totalTargetUFVolumeInMl; + +static F32 sentPWM; + +// ********** private function prototypes ********** + +static DIALOUT_FLOW_STATE_T handleDialOutFlowStopState( void ); +static DIALOUT_FLOW_STATE_T handleDialOutFlowRunUFState( void ); +static DIALOUT_FLOW_STATE_T handleDialOutFlowPauseUFState( void ); + +static void setControlSignalPWM( F32 newPWM ); +static void stopDialOutPump( void ); +static void updateTargetVolume( void ); + +static void setDialOutPumpDirection( MOTOR_DIR_T dir ); + + + +static void publishDialOutFlowData( void ); +static DATA_GET_PROTOTYPE( U32, getPublishDialOutFlowDataInterval ); + +void startDialOut( BOOL isNewBag ) +{ + if( isNewBag ) + { + bagStartVolumeInMl = 0.0; + } +} + +void stopDialOut( void ) +{ + +} + +void pauseDialOut( void ) +{ + +} + +static void setControlSignalPWM( F32 newPWM ) +{ + F32 roundOffSet = newPWM != 0.0 ? FLOAT_TO_INT_ROUNDUP_OFFSET : 0.0; + etpwmSetCmpA( etpwmREG3, (U32)( (S32)( ( newPWM * (F32)(etpwmREG3->TBPRD) ) + roundOffSet) ) ); +} + +static void updateTargetVolume( void ) +{ + rxTotalTargetVolumeInMl += targetVolumeRatePerSample; +} + + +BOOL setDialOutFlowRxTotalVolumeAndRxTime( U32 rxTotaVolumeInMl, U32 rxTotalTimeInMinutes, U32 rxFlowRate) +{ + #define SECS_IN_MIN 60 + + + BOOL returnValue = TRUE; + + rxTotalTargetVolumeInMl = rxTotaVolumeInMl; + rxTargetTimeInSamples = rxTotalTimeInMinutes * SEC_PER_MIN * DIAL_OUT_FLOW_SAMPLE_FREQ ; + rxTargetFlowRate = rxFlowRate; + + targetVolumeRatePerSample = (F32) rxTotalTargetVolumeInMl / (F32) rxTargetTimeInSamples; + + + return returnValue; +} + +/************************************************************************* + * @brief initDialOutFlow + * The initDialOutFlow function initializes the DialOutFlow module. + * @details + * Inputs : none + * Outputs : DialOutFlow module initialized. + * @param none + * @return none + *************************************************************************/ +void initDialOutFlow( void ) +{ + dialOutFlowState = DIALOUT_FLOW_STOP_STATE; + totalTargetUFVolumeInMl = 0.0; + + stopDialOutPump(); + setDialOutPumpDirection( MOTOR_DIR_FORWARD ); + + initializeFilter(FILTER_ID_LOAD_CELL_WEIGHT, 0); + + bagStartVolumeInMl = 0.0; + accumulativeTotalUFVolumeInMl = 0.0; + + // initialize dialysate outlet flow PI controller + initializePIController( PI_CONTROLLER_ID_LOAD_CELL, MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE, + DIP_P_COEFFICIENT, DIP_I_COEFFICIENT, + MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_OUT_PUMP_PWM_DUTY_CYCLE); +} + +F32 getMeasuredVariable( DIALOUT_MEASURED_SIGNALS_T signal) +{ + #define DIP_SPEED_ADC_TO_RPM_FACTOR 1.375 // conversion factor from ADC counts to RPM for dialIn pump motor + #define DIP_CURRENT_ADC_TO_MA_FACTOR 2.65 // conversion factor from ADC counts to mA for dialIn pump motor + F32 returnValue = 0.0; + + switch ( signal ) + { + case DIALOUT_LOAD_CELL_WEIGHT: + returnValue = 0.0; // TODO: getFPGALoadCellWeight(); + break; + + case DIALOUT_MOTOR_SPEED: + returnValue = getIntADCReading( INT_ADC_DIAL_OUT_PUMP_SPEED ) * DIP_SPEED_ADC_TO_RPM_FACTOR; + break; + + case DIALOUT_MOTOR_CURRENT: + returnValue = getIntADCReading( INT_ADC_DIAL_OUT_PUMP_MOTOR_CURRENT ) * DIP_CURRENT_ADC_TO_MA_FACTOR; + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_MEASURED_SIGNAL_STATE, signal ) + break; + + } +} + +/************************************************************************* + * @brief execDialOutFlowMonitor + * The execDialOutFlowMonitor function executes the dialIn flow monitor. + * @details + * Inputs : none + * Outputs : measuredDialOutFlowRate, adcDialOutPumpMCSpeedRPM, adcDialOutPumpMCCurrentmA + * @param none + * @return none + *************************************************************************/ +/*void execDialOutFlowMonitor( void ) +{ + U16 dopRPM = getIntADCReading( INT_ADC_DIAL_OUT_PUMP_SPEED ); + U16 dopmA = getIntADCReading( INT_ADC_DIAL_OUT_PUMP_MOTOR_CURRENT ); + F32 dopLoadCellWeightinGr = getFPGALoadCellWeight(); + + adcDialOutPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; + adcDialOutPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; + + // publish dialIn flow data on interval + + publishDialOutFlowData(); +}*/ + +/************************************************************************* + * @brief execDialOutFlowController + * The execDialOutFlowController function executes the dialIn flow controller. + * @details + * Inputs : dialOutPumpState + * Outputs : dialOutPumpState + * @param none + * @return none + *************************************************************************/ +void execDialOutFlowController( void ) +{ + switch ( dialOutFlowState ) + { + case DIALOUT_FLOW_STOP_STATE: + dialOutFlowState = handleDialOutFlowStopState(); + break; + + case DIALOUT_FLOW_RUN_UF_STATE: + dialOutFlowState = handleDialOutFlowRunUFState(); + break; + + case DIALOUT_FLOW_PAUSE_UF_STATE: + dialOutFlowState = handleDialOutFlowPauseUFState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_STATE, dialOutFlowState ) + break; + } +} + +/************************************************************************* + * @brief handleDialOutFlowStopState + * The handleDialOutFlowStopState function handles the dialout flow stop state \n + * of the dialout flow state machine. + * @details + * Inputs : targetDialOutFlowRate, dialOutPumpDirection + * Outputs : dialOutPumpPWMDutyCyclePctSet, dialOutPumpDirectionSet, isDialOutPumpOn + * @param none + * @return next state + *************************************************************************/ +static DIALOUT_FLOW_STATE_T handleDialOutFlowStopState( void ) +{ + DIALOUT_FLOW_STATE_T result = DIALOUT_FLOW_STOP_STATE; + + stopDialOutPump(); + + return result; +} + +/************************************************************************* + * @brief handleDialOutFlowPauseUFState + * The handleDialOutPumpRampingDownState function handles the ramp down state \n + * of the dialIn pump controller state machine. + * @details + * Inputs : dialOutPumpPWMDutyCyclePctSet + * Outputs : dialOutPumpPWMDutyCyclePctSet + * @param none + * @return next state + *************************************************************************/ +static DIALOUT_FLOW_STATE_T handleDialOutFlowPauseUFState( void ) +{ + sentPWM = runPIController( PI_CONTROLLER_ID_LOAD_CELL, totalTargetUFVolumeInMl, totalMeasuredUFVolumeInMl ); + + setControlSignalPWM( sentPWM ); + + return DIALOUT_FLOW_PAUSE_UF_STATE; +} + +/************************************************************************* + * @brief handleDialOutFlowRunUFState + * The handleDialOutFlowRunUFState function handles the dialout flow + * controller during run state. + * @details + * Inputs : none + * Outputs : dialout flow State + * @param none + * @return next state + *************************************************************************/ +static DIALOUT_FLOW_STATE_T handleDialOutFlowRunUFState( void ) +{ + updateTargetVolume(); + + sentPWM = runPIController( PI_CONTROLLER_ID_LOAD_CELL, totalTargetUFVolumeInMl, totalMeasuredUFVolumeInMl ); + + setControlSignalPWM( sentPWM ); + + return DIALOUT_FLOW_RUN_UF_STATE; +} + +/************************************************************************* + * @brief stopDialOutPump + * The stopDialOutPump function sets the dialout flow stop signal and PWM + * duty cycle to 0.0. + * @details + * Inputs : none + * Outputs : dialOut pump stop signal activated, PWM duty cycle zeroed + * @param none + * @return none + *************************************************************************/ +static void stopDialOutPump( void ) +{ + setControlSignalPWM(0.0); + SET_DOP_STOP(); +} + + +/************************************************************************* + * @brief setDialOutPumpDirection + * The setDialOutPumpDirection function sets the set dialIn pump direction to \n + * the given direction. + * @details + * Inputs : dialOutPumpState + * Outputs : dialOutPumpState + * @param dir : dialIn pump direction to set + * @return none + *************************************************************************/ +static void setDialOutPumpDirection( MOTOR_DIR_T dir ) +{ + switch ( dir ) + { + case MOTOR_DIR_FORWARD: + SET_DOP_DIR(); + break; + + case MOTOR_DIR_REVERSE: + CLR_DOP_DIR(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_DIRECTION, dir ) + break; + } +} + +/************************************************************************* + * @brief getPublishDialOutFlowDataInterval + * The getPublishDialOutFlowDataInterval function gets the dialIn flow data \n + * publication interval. + * @details + * Inputs : dialOutFlowDataPublishInterval + * Outputs : none + * @param none + * @return the current dialIn flow data publication interval (in ms). + *************************************************************************/ +DATA_GET( U32, getPublishDialOutFlowDataInterval, dialOutFlowDataPublishInterval ) + +/************************************************************************* + * @brief getTargetDialOutFlowRate + * The getTargetDialOutFlowRate function gets the current target dialIn flow \n + * rate. + * @details + * Inputs : targetDialOutFlowRate + * Outputs : none + * @param none + * @return the current target dialIn flow rate (in mL/min). + *************************************************************************/ +DATA_GET( S32, getTargetDialOutFlowRate, targetDialOutFlowRate ) + +/************************************************************************* + * @brief getMeasuredDialOutFlowRate + * The getMeasuredDialOutFlowRate function gets the measured dialIn flow \n + * rate. + * @details + * Inputs : measuredDialOutFlowRate + * Outputs : none + * @param none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ +DATA_GET( F32, getMeasuredDialOutVolume, measuredDialOutFlowRate ) + +/************************************************************************* + * @brief getMeasuredDialOutPumpRotorSpeed + * The getMeasuredDialOutPumpRotorSpeed function gets the measured dialIn flow \n + * rate. + * @details + * Inputs : dialOutPumpRotorSpeedRPM + * Outputs : none + * @param none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ +DATA_GET( F32, getMeasuredDialOutPumpRotorSpeed, dialOutPumpRotorSpeedRPM ) + +/************************************************************************* + * @brief getMeasuredDialOutPumpSpeed + * The getMeasuredDialOutPumpSpeed function gets the measured dialIn flow \n + * rate. + * @details + * Inputs : dialOutPumpSpeedRPM + * Outputs : none + * @param none + * @return the current dialIn flow rate (in mL/min). + *************************************************************************/ +DATA_GET( F32, getMeasuredDialOutPumpSpeed, dialOutPumpSpeedRPM ) + +/************************************************************************* + * @brief getMeasuredDialOutPumpMCSpeed + * The getMeasuredDialOutPumpMCSpeed function gets the measured dialIn pump \n + * speed. + * @details + * Inputs : adcDialOutPumpMCSpeedRPM + * Outputs : none + * @param none + * @return the current dialIn pump speed (in RPM). + *************************************************************************/ +DATA_GET( F32, getMeasuredDialOutPumpMCSpeed, adcDialOutPumpMCSpeedRPM ) + +/************************************************************************* + * @brief getMeasuredDialOutPumpMCCurrent + * The getMeasuredDialOutPumpMCCurrent function gets the measured dialIn pump \n + * current. + * @details + * Inputs : adcDialOutPumpMCCurrentmA + * Outputs : none + * @param none + * @return the current dialIn pump current (in mA). + *************************************************************************/ +DATA_GET( F32, getMeasuredDialOutPumpMCCurrent, adcDialOutPumpMCCurrentmA ) + +/************************************************************************* + * @brief publishDialOutFlowData + * The publishDialOutFlowData function publishes dialIn flow data at the set \n + * interval. + * @details + * Inputs : target flow rate, measured flow rate, measured MC speed, \n + * measured MC current + * Outputs : DialIn flow data is published to CAN bus. + * @param none + * @return none + *************************************************************************/ +static void publishDialOutFlowData( void ) +{ + // publish dialIn flow data on interval + if ( ++dialOutFlowDataPublicationTimerCounter > DIAL_OUT_FLOW_DATA_PUB_INTERVAL ) + { +#ifdef DEBUG_ENABLED + // TODO - temporary debug code - remove later + char debugFlowStr[ 256 ]; + + sprintf( debugFlowStr, "St:%5d, Set Pt:%5d, Meas. Vol:%5d, PWM:%5d \n", (S32) dialOutFlowState, (S32) totalTargetUFVolumeInMl, (S32) totalMeasuredUFVolumeInMl,(S32)(sentPWM * FRACTION_TO_PERCENT_FACTOR) ); + sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); +#endif + //broadcastDialOutFlowData( flowStPt, measFlow, measRotSpd, measSpd, measMCSpd, measMCCurr, pumpPWMPctDutyCycle ); + dialOutFlowDataPublicationTimerCounter = 0; + } +} + + +/************************************************************************* + * @brief execDialOutFlowTest + * The execDialOutFlowTest function executes the state machine for the \n + * DialOutFlow self test. + * @details + * Inputs : none + * Outputs : none + * @param none + * @return the current state of the DialOutFlow self test. + *************************************************************************/ +SELF_TEST_STATUS_T execDialOutFlowTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + + // TODO - implement self test(s) + + return result; +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/************************************************************************* + * @brief testSetDialOutFlowDataPublishIntervalOverride + * The testSetDialOutFlowDataPublishIntervalOverride function overrides the \n + * dialIn flow data publish interval. + * @details + * Inputs : none + * Outputs : dialOutFlowDataPublishInterval + * @param value : override dialIn flow data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDialOutFlowDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + + result = TRUE; + dialOutFlowDataPublishInterval.ovData = intvl; + dialOutFlowDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/************************************************************************* + * @brief testResetDialOutFlowDataPublishIntervalOverride + * The testResetDialOutFlowDataPublishIntervalOverride function resets the override \n + * of the dialIn flow data publish interval. + * @details + * Inputs : none + * Outputs : dialOutFlowDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDialOutFlowDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dialOutFlowDataPublishInterval.override = OVERRIDE_RESET; + dialOutFlowDataPublishInterval.ovData = dialOutFlowDataPublishInterval.ovInitData; + } + + return result; +} + +/************************************************************************* + * @brief testSetTargetDialOutFlowRateOverride and testResetTargetDialOutFlowRateOverride + * The testSetTargetDialOutFlowRateOverride function overrides the target \n + * dialIn flow rate. \n + * The testResetTargetDialOutFlowRateOverride function resets the override of the \n + * target dialIn flow rate. + * @details + * Inputs : none + * Outputs : targetDialOutFlowRate + * @param value : override target dialIn flow rate (in mL/min) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( S32, testSetTargetDialOutFlowRateOverride, testResetTargetDialOutFlowRateOverride, targetDialOutFlowRate ) + +/************************************************************************* + * @brief testSetMeasuredDialOutFlowRateOverride and testResetMeasuredDialOutFlowRateOverride + * The testResetMeasuredDialOutFlowRateOverride function overrides the measured \n + * dialIn flow rate. \n + * The testResetOffButtonStateOverride function resets the override of the \n + * measured dialIn flow rate. + * @details + * Inputs : none + * Outputs : measuredDialOutFlowRate + * @param value : override measured dialIn flow rate (in mL/min) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutFlowRateOverride, testResetMeasuredDialOutFlowRateOverride, measuredDialOutFlowRate ) + +/************************************************************************* + * @brief testSetMeasuredDialOutPumpRotorSpeedOverride and testResetMeasuredDialOutPumpRotorSpeedOverride + * The testSetMeasuredDialOutPumpRotorSpeedOverride function overrides the measured \n + * dialIn pump rotor speed. \n + * The testResetMeasuredDialOutPumpRotorSpeedOverride function resets the override of the \n + * measured dialIn pump rotor speed. + * @details + * Inputs : none + * Outputs : dialOutPumpRotorSpeedRPM + * @param value : override measured dialIn pump rotor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpRotorSpeedOverride, testResetMeasuredDialOutPumpRotorSpeedOverride, dialOutPumpRotorSpeedRPM ) + +/************************************************************************* + * @brief testSetMeasuredDialOutPumpSpeedOverride and testResetMeasuredDialOutPumpSpeedOverride + * The testSetMeasuredDialOutPumpSpeedOverride function overrides the measured \n + * dialIn pump motor speed. \n + * The testResetMeasuredDialOutPumpSpeedOverride function resets the override of the \n + * measured dialIn pump motor speed. + * @details + * Inputs : none + * Outputs : dialOutPumpSpeedRPM + * @param value : override measured dialIn pump motor speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpSpeedOverride, testResetMeasuredDialOutPumpSpeedOverride, dialOutPumpSpeedRPM ) + +/************************************************************************* + * @brief testSetMeasuredDialOutPumpMCSpeedOverride and testResetMeasuredDialOutPumpMCSpeedOverride + * The testSetMeasuredDialOutPumpMCSpeedOverride function overrides the measured \n + * dialIn pump motor speed. \n + * The testResetMeasuredDialOutPumpMCSpeedOverride function resets the override of the \n + * measured dialIn pump motor speed. + * @details + * Inputs : none + * Outputs : adcDialOutPumpMCSpeedRPM + * @param value : override measured dialIn pump speed (in RPM) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpMCSpeedOverride, testResetMeasuredDialOutPumpMCSpeedOverride, adcDialOutPumpMCSpeedRPM ) + +/************************************************************************* + * @brief testSetMeasuredDialOutPumpMCCurrentOverride and testResetMeasuredDialOutPumpMCCurrentOverride + * The testSetMeasuredDialOutPumpMCCurrentOverride function overrides the measured \n + * dialIn pump motor current. \n + * The testResetMeasuredDialOutPumpMCCurrentOverride function resets the override of the \n + * measured dialIn pump motor current. + * @details + * Inputs : none + * Outputs : adcDialOutPumpMCCurrentmA + * @param value : override measured dialIn pump current (in mA) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +DATA_OVERRIDE_FUNC( F32, testSetMeasuredDialOutPumpMCCurrentOverride, testResetMeasuredDialOutPumpMCCurrentOverride, adcDialOutPumpMCCurrentmA ) + + Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r5217f70ca5c74bd586dc14540e6404b43feea004 -r89a95cb8fbc537f1c7a5448a05788342f7319c01 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 5217f70ca5c74bd586dc14540e6404b43feea004) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 89a95cb8fbc537f1c7a5448a05788342f7319c01) @@ -1,192 +1,193 @@ -/************************************************************************** - * - * Copyright (c) 2019-2019 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 AlarmMgmt.h - * - * @date 07-Nov-2019 - * @author S. Nash - * - * @brief header file for Alarm Management service module. - * - **************************************************************************/ - -#ifndef __ALARM_MGMT_H__ -#define __ALARM_MGMT_H__ - -// ********** public definitions ********** - -typedef enum Alarm_List -{ - ALARM_ID_NO_ALARM = 0, - ALARM_ID_SOFTWARE_FAULT, - ALARM_ID_STUCK_BUTTON_TEST_FAILED, - ALARM_ID_FPGA_POST_TEST_FAILED, - ALARM_ID_WATCHDOG_POST_TEST_FAILED, - ALARM_ID_UI_COMM_POST_FAILED, // 5 - ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, - ALARM_ID_BLOOD_PUMP_MC_SPEED_CHECK, - ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, - ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, - ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, // 10 - ALARM_ID_DIAL_IN_PUMP_MC_SPEED_CHECK, - ALARM_ID_DIAL_IN_PUMP_MC_DIRECTION_CHECK, - ALARM_ID_DIAL_IN_PUMP_ROTOR_SPEED_CHECK, - ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK, - ALARM_ID_DIAL_OUT_PUMP_MC_SPEED_CHECK, // 15 - ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, - ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK, - ALARM_ID_WATCHDOG_EXPIRED, - ALARM_ID_RTC_COMM_ERROR, - ALARM_ID_RTC_CONFIG_ERROR, // 20 - NUM_OF_ALARM_IDS -} ALARM_ID_T; - -typedef enum Alarm_Priorities -{ - ALARM_PRIORITY_NONE = 0, - ALARM_PRIORITY_LOW, - ALARM_PRIORITY_MEDIUM, - ALARM_PRIORITY_HIGH, - NUM_OF_ALARM_PRIORITIES -} ALARM_PRIORITY_T; - -typedef enum Alarm_Data_Types -{ - ALARM_DATA_TYPE_NONE = 0, - ALARM_DATA_TYPE_U32, - ALARM_DATA_TYPE_S32, - ALARM_DATA_TYPE_F32, - ALARM_DATA_TYPE_BOOL, - NUM_OF_ALARM_DATA_TYPES -} ALARM_DATA_TYPES_T; - -#pragma pack(push,4) -typedef struct -{ - ALARM_PRIORITY_T alarmsState; // current alarm priority level - BOOL alarmsSilenced; // alarms are currently silenced? - U32 alarmsSilenceStart; // time stamp for when alarms were silenced (ms) - U32 alarmsSilenceExpiresIn; // time until alarm silence expires (seconds) - BOOL alarmsToEscalate; // are any active alarms due to escalate (should UI show count down timer?) - U32 alarmsEscalatesIn; // time until alarm will escalate (seconds) - ALARM_ID_T alarmTop; // ID of current top alarm that will drive lamp/audio and UI should be displaying right now - BOOL systemFault; // a system fault is active? - BOOL stop; // we should be in controlled stop right now - BOOL noClear; // no recovery will be possible - BOOL noResume; // treatment may not be resumed at this time - BOOL noRinseback; // rinseback may not be initiated at this time - BOOL noEndTreatment; // ending the treatment is not an option at this time - BOOL noNewTreatment; // no new treatments may be started even if current treatment is ended - BOOL bypassDialyzer; // the dialyzer should be bypassed at this time -} COMP_ALARM_STATUS_T; - -typedef struct -{ - U32 data; -} ALARM_DATA_U32_T; - -typedef struct -{ - S32 data; -} ALARM_DATA_S32_T; - -typedef struct -{ - F32 data; -} ALARM_DATA_F32_T; - -typedef struct -{ - BOOL data; -} ALARM_DATA_BOOL_T; - -typedef union -{ - ALARM_DATA_U32_T uInt; - ALARM_DATA_S32_T sInt; - ALARM_DATA_F32_T flt; - ALARM_DATA_BOOL_T bln; -} ALARM_DATAS_T; - -typedef struct -{ - ALARM_DATA_TYPES_T dataType; - ALARM_DATAS_T data; -} ALARM_DATA_T; -#pragma pack(pop) - -typedef enum -{ - SW_FAULT_ID_NONE = 0, - SW_FAULT_ID_ALARM_LAMP_INVALID_PATTERN_REQUESTED, - SW_FAULT_ID_ALARM_LAMP_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_BLOOD_FLOW_SET_TOO_HIGH, - SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_STATE, - SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_DIRECTION, // 5 - SW_FAULT_ID_BUTTONS_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED, - SW_FAULT_ID_INT_ADC_DATA_OVERRUN, - SW_FAULT_ID_INT_ADC_INVALID_CHANNEL_REQUESTED, - SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE, // 10 - SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, - SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, - SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, - SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, - SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, // 15 - SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, - SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, - SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, - SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, - SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, // 20 - SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, - SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, - SW_FAULT_ID_FPGA_INVALID_IN_STATE, - SW_FAULT_ID_FPGA_INVALID_OUT_STATE, - SW_FAULT_ID_FPGA_WRITE_CMD_TOO_MUCH_DATA, // 25 - SW_FAULT_ID_FPGA_WRITE_RSP_TOO_MUCH_DATA, - SW_FAULT_ID_FPGA_READ_CMD_TOO_MUCH_DATA, - SW_FAULT_ID_FPGA_READ_RSP_TOO_MUCH_DATA, - SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL, - SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE, // 30 - SW_FAULT_ID_MSG_QUEUES_GET_INVALID_QUEUE, - SW_FAULT_ID_MSG_QUEUES_IS_EMPTY_INVALID_QUEUE, - SW_FAULT_ID_MSG_QUEUES_IS_FULL_INVALID_QUEUE, - SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, // 35 - SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_DIRECTION, - SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_STATE, - SW_FAULT_ID_DIAL_IN_FLOW_SET_TOO_HIGH, - SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_DIRECTION, - SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_STATE, // 40 - SW_FAULT_ID_DIAL_OUT_FLOW_SET_TOO_HIGH, - SW_FAULT_ID_BLOOD_FLOW_INVALID_FILTER_STATE, - SW_FAULT_ID_DIAL_IN_FLOW_INVALID_FILTER_STATE, - SW_FAULT_ID_RTC_EXEC_INVALID_STATE, - SW_FAULT_ID_RTC_SELF_TEST_INVALID_STATE, // 45 - SW_FAULT_ID_RTC_TRANSACTION_SERVICE_INVALID_STATE, - NUM_OF_SW_FAULT_IDS -} SW_FAULT_ID_T; - -// ********** public function prototypes ********** - -void initAlarmMgmt( void ); -void execAlarmMgmt( void ); - -void activateAlarmNoData( ALARM_ID_T alarm ); -void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ); -void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ); -void clearAlarm( ALARM_ID_T alarm ); -BOOL isAlarmActive( ALARM_ID_T alarm ); - -BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ); -BOOL testResetAlarmStatusPublishIntervalOverride( void ); -BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); -BOOL testResetAlarmStateOverride( U32 alarmID ); -BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ); -BOOL testResetAlarmStartOverride( U32 alarmID ); - -#endif +/************************************************************************** + * + * Copyright (c) 2019-2019 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 AlarmMgmt.h + * + * @date 07-Nov-2019 + * @author S. Nash + * + * @brief header file for Alarm Management service module. + * + **************************************************************************/ + +#ifndef __ALARM_MGMT_H__ +#define __ALARM_MGMT_H__ + +// ********** public definitions ********** + +typedef enum Alarm_List +{ + ALARM_ID_NO_ALARM = 0, + ALARM_ID_SOFTWARE_FAULT, + ALARM_ID_STUCK_BUTTON_TEST_FAILED, + ALARM_ID_FPGA_POST_TEST_FAILED, + ALARM_ID_WATCHDOG_POST_TEST_FAILED, + ALARM_ID_UI_COMM_POST_FAILED, // 5 + ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, + ALARM_ID_BLOOD_PUMP_MC_SPEED_CHECK, + ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, + ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, + ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK, // 10 + ALARM_ID_DIAL_IN_PUMP_MC_SPEED_CHECK, + ALARM_ID_DIAL_IN_PUMP_MC_DIRECTION_CHECK, + ALARM_ID_DIAL_IN_PUMP_ROTOR_SPEED_CHECK, + ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK, + ALARM_ID_DIAL_OUT_PUMP_MC_SPEED_CHECK, // 15 + ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK, + ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK, + ALARM_ID_WATCHDOG_EXPIRED, + ALARM_ID_RTC_COMM_ERROR, + ALARM_ID_RTC_CONFIG_ERROR, // 20 + NUM_OF_ALARM_IDS +} ALARM_ID_T; + +typedef enum Alarm_Priorities +{ + ALARM_PRIORITY_NONE = 0, + ALARM_PRIORITY_LOW, + ALARM_PRIORITY_MEDIUM, + ALARM_PRIORITY_HIGH, + NUM_OF_ALARM_PRIORITIES +} ALARM_PRIORITY_T; + +typedef enum Alarm_Data_Types +{ + ALARM_DATA_TYPE_NONE = 0, + ALARM_DATA_TYPE_U32, + ALARM_DATA_TYPE_S32, + ALARM_DATA_TYPE_F32, + ALARM_DATA_TYPE_BOOL, + NUM_OF_ALARM_DATA_TYPES +} ALARM_DATA_TYPES_T; + +#pragma pack(push,4) +typedef struct +{ + ALARM_PRIORITY_T alarmsState; // current alarm priority level + BOOL alarmsSilenced; // alarms are currently silenced? + U32 alarmsSilenceStart; // time stamp for when alarms were silenced (ms) + U32 alarmsSilenceExpiresIn; // time until alarm silence expires (seconds) + BOOL alarmsToEscalate; // are any active alarms due to escalate (should UI show count down timer?) + U32 alarmsEscalatesIn; // time until alarm will escalate (seconds) + ALARM_ID_T alarmTop; // ID of current top alarm that will drive lamp/audio and UI should be displaying right now + BOOL systemFault; // a system fault is active? + BOOL stop; // we should be in controlled stop right now + BOOL noClear; // no recovery will be possible + BOOL noResume; // treatment may not be resumed at this time + BOOL noRinseback; // rinseback may not be initiated at this time + BOOL noEndTreatment; // ending the treatment is not an option at this time + BOOL noNewTreatment; // no new treatments may be started even if current treatment is ended + BOOL bypassDialyzer; // the dialyzer should be bypassed at this time +} COMP_ALARM_STATUS_T; + +typedef struct +{ + U32 data; +} ALARM_DATA_U32_T; + +typedef struct +{ + S32 data; +} ALARM_DATA_S32_T; + +typedef struct +{ + F32 data; +} ALARM_DATA_F32_T; + +typedef struct +{ + BOOL data; +} ALARM_DATA_BOOL_T; + +typedef union +{ + ALARM_DATA_U32_T uInt; + ALARM_DATA_S32_T sInt; + ALARM_DATA_F32_T flt; + ALARM_DATA_BOOL_T bln; +} ALARM_DATAS_T; + +typedef struct +{ + ALARM_DATA_TYPES_T dataType; + ALARM_DATAS_T data; +} ALARM_DATA_T; +#pragma pack(pop) + +typedef enum +{ + SW_FAULT_ID_NONE = 0, + SW_FAULT_ID_ALARM_LAMP_INVALID_PATTERN_REQUESTED, + SW_FAULT_ID_ALARM_LAMP_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_BLOOD_FLOW_SET_TOO_HIGH, + SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_STATE, + SW_FAULT_ID_BLOOD_FLOW_INVALID_BLOOD_PUMP_DIRECTION, // 5 + SW_FAULT_ID_BUTTONS_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED, + SW_FAULT_ID_INT_ADC_DATA_OVERRUN, + SW_FAULT_ID_INT_ADC_INVALID_CHANNEL_REQUESTED, + SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE, // 10 + SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, + SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, + SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, + SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, + SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, // 15 + SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, + SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, + SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, + SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, + SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, // 20 + SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, + SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, + SW_FAULT_ID_FPGA_INVALID_IN_STATE, + SW_FAULT_ID_FPGA_INVALID_OUT_STATE, + SW_FAULT_ID_FPGA_WRITE_CMD_TOO_MUCH_DATA, // 25 + SW_FAULT_ID_FPGA_WRITE_RSP_TOO_MUCH_DATA, + SW_FAULT_ID_FPGA_READ_CMD_TOO_MUCH_DATA, + SW_FAULT_ID_FPGA_READ_RSP_TOO_MUCH_DATA, + SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL, + SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE, // 30 + SW_FAULT_ID_MSG_QUEUES_GET_INVALID_QUEUE, + SW_FAULT_ID_MSG_QUEUES_IS_EMPTY_INVALID_QUEUE, + SW_FAULT_ID_MSG_QUEUES_IS_FULL_INVALID_QUEUE, + SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, // 35 + SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_DIRECTION, + SW_FAULT_ID_DIAL_IN_FLOW_INVALID_DIAL_IN_PUMP_STATE, + SW_FAULT_ID_DIAL_IN_FLOW_SET_TOO_HIGH, + SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_DIRECTION, + SW_FAULT_ID_DIAL_OUT_FLOW_INVALID_DIAL_OUT_PUMP_STATE, // 40 + SW_FAULT_ID_DIAL_OUT_FLOW_SET_TOO_HIGH, + SW_FAULT_ID_BLOOD_FLOW_INVALID_FILTER_STATE, + SW_FAULT_ID_DIAL_IN_FLOW_INVALID_FILTER_STATE, + SW_FAULT_ID_RTC_EXEC_INVALID_STATE, + SW_FAULT_ID_RTC_SELF_TEST_INVALID_STATE, // 45 + SW_FAULT_ID_RTC_TRANSACTION_SERVICE_INVALID_STATE, + SW_FAULT_ID_DIAL_OUT_MEASURED_SIGNAL_STATE, + NUM_OF_SW_FAULT_IDS +} SW_FAULT_ID_T; + +// ********** public function prototypes ********** + +void initAlarmMgmt( void ); +void execAlarmMgmt( void ); + +void activateAlarmNoData( ALARM_ID_T alarm ); +void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ); +void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ); +void clearAlarm( ALARM_ID_T alarm ); +BOOL isAlarmActive( ALARM_ID_T alarm ); + +BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ); +BOOL testResetAlarmStatusPublishIntervalOverride( void ); +BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); +BOOL testResetAlarmStateOverride( U32 alarmID ); +BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ); +BOOL testResetAlarmStartOverride( U32 alarmID ); + +#endif