Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -rce3a23a23a5dc7d214793ccbdc81d8afd9504af9 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision ce3a23a23a5dc7d214793ccbdc81d8afd9504af9) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -77,7 +77,7 @@ static U32 fillStartTime = 0; ///< Time stamp for start of air trap fill. static U32 airPumpOnDelayStartTime = 0; ///< Air pump On start time. static U32 stopAirPumpStartTime = 0; ///< Stop air pump start time. -/// Air pump on delay after fill adjustment +// Air pump on delay after fill adjustment static const U32 AIR_PUMP_ON_DELAY_ADJUST_AFTER_FILL = ( AIR_PUMP_ON_DELAY_TIME_MS - ( 1 * MS_PER_SECOND ) ); static BOOL airTrapValveOpenAtStartOfTreatement = FALSE; ///< To Keep the fluid level high close to Air trap upper level during start of treatment @@ -203,7 +203,7 @@ AIR_TRAP_LEVELS_T lowerAirTrap, upperAirTrap; AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; - // Get latest level readings + // Get latest raw level readings getFPGAAirTrapLevels( &lower, &upper ); rawAirTrapLevels[ AIR_TRAP_LEVEL_SENSOR_LOWER ].data = (U32)( TRUE == lower ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); rawAirTrapLevels[ AIR_TRAP_LEVEL_SENSOR_UPPER ].data = (U32)( TRUE == upper ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); @@ -426,7 +426,7 @@ setValveAirTrap( STATE_OPEN ); fillStartTime = getMSTimerCount(); - SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, 0, 0 ); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, STATE_OPEN, 0 ); result = AIR_TRAP_VALVE_OPEN_STATE; } @@ -451,13 +451,13 @@ pendingStopAirTrapController = FALSE; result = AIR_TRAP_MANUAL_CONTROL_STATE; } - // Transition to closed valve state when fluid detected at lower level + // Transition to closed valve state when fluid detected at upper level else if ( AIR_TRAP_LEVEL_FLUID == getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { setValveAirTrap( STATE_CLOSED ); + airPumpOnDelayStartTime = u32DiffWithWrap( AIR_PUMP_ON_DELAY_ADJUST_AFTER_FILL, getMSTimerCount() ); signalLowVenousPressureCheck(); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_AIR_TRAP_FILL, STATE_CLOSED, 0 ); - airPumpOnDelayStartTime = u32DiffWithWrap( AIR_PUMP_ON_DELAY_ADJUST_AFTER_FILL, getMSTimerCount() ); result = AIR_TRAP_VALVE_CLOSED_STATE; } return result; @@ -500,19 +500,19 @@ *************************************************************************/ AIR_TRAP_LEVELS_T getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSORS_T sensor ) { - AIR_TRAP_LEVELS_T result; + AIR_TRAP_LEVELS_T result; - if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) - { - result = (AIR_TRAP_LEVELS_T)getU32OverrideValue( &rawAirTrapLevels[ sensor ] ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_AIR_TRAP_INVALID_LEVEL_SENSOR, (U32)sensor ) - result = AIR_TRAP_LEVEL_AIR; - } + if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) + { + result = (AIR_TRAP_LEVELS_T)getU32OverrideValue( &rawAirTrapLevels[ sensor ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (U32)SW_FAULT_ID_AIR_TRAP_INVALID_LEVEL_SENSOR, (U32)sensor ) + result = AIR_TRAP_LEVEL_AIR; + } - return result; + return result; } /*********************************************************************//** @@ -524,19 +524,19 @@ *************************************************************************/ static void publishAirTrapData( void ) { - // Publish air trap data on interval - if ( ++airTrapDataPublicationTimerCounter >= getU32OverrideValue( &airTrapDataPublishInterval ) ) - { - AIR_TRAP_PAYLOAD_T data; + // Publish air trap data on interval + if ( ++airTrapDataPublicationTimerCounter >= getU32OverrideValue( &airTrapDataPublishInterval ) ) + { + AIR_TRAP_PAYLOAD_T data; - data.lowerLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); - data.upperLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); - data.rawLowerLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); - data.rawUpperLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); + data.lowerLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); + data.upperLevel = getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); + data.rawLowerLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ); + data.rawUpperLevel = getRawAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ); - broadcastData( MSG_ID_HD_AIR_TRAP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( AIR_TRAP_PAYLOAD_T ) ); - airTrapDataPublicationTimerCounter = 0; - } + broadcastData( MSG_ID_HD_AIR_TRAP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( AIR_TRAP_PAYLOAD_T ) ); + airTrapDataPublicationTimerCounter = 0; + } } /*********************************************************************//** @@ -674,19 +674,19 @@ *************************************************************************/ BOOL testSetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor, AIR_TRAP_LEVELS_T level ) { - BOOL result = FALSE; + BOOL result = FALSE; - if ( ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) && ( level < NUM_OF_AIR_TRAP_LEVELS ) ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - rawAirTrapLevels[ sensor ].ovData = (U32)level; - rawAirTrapLevels[ sensor ].override = OVERRIDE_KEY; - } - } + if ( ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) && ( level < NUM_OF_AIR_TRAP_LEVELS ) ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rawAirTrapLevels[ sensor ].ovData = (U32)level; + rawAirTrapLevels[ sensor ].override = OVERRIDE_KEY; + } + } - return result; + return result; } /*********************************************************************//** @@ -700,19 +700,19 @@ *************************************************************************/ BOOL testResetRawAirTrapLevelOverride( AIR_TRAP_LEVEL_SENSORS_T sensor ) { - BOOL result = FALSE; + BOOL result = FALSE; - if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - rawAirTrapLevels[ sensor ].override = OVERRIDE_RESET; - rawAirTrapLevels[ sensor ].ovData = rawAirTrapLevels[ sensor ].ovInitData; - } - } + if ( sensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rawAirTrapLevels[ sensor ].override = OVERRIDE_RESET; + rawAirTrapLevels[ sensor ].ovData = rawAirTrapLevels[ sensor ].ovInitData; + } + } - return result; + return result; } /**@}*/ Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r23f982d7ee27914707822bfa1c4a6765f5bb8786 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 23f982d7ee27914707822bfa1c4a6765f5bb8786) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -88,7 +88,7 @@ /// Persist time (in ms) pump direction error condition. static const U32 BP_DIRECTION_ERROR_PERSIST = ( 250 ); /// Persist time period (in ms) blood pump rotor speed too fast error condition. -static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ( 1 * MS_PER_SECOND ); +static const U32 BP_MAX_ROTOR_SPEED_ERROR_PERSIST = ( 10 * MS_PER_SECOND ); #define BP_MAX_CURR_WHEN_STOPPED_MA 150.0F ///< Motor controller current should not exceed this when pump should be stopped. #define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0F ///< Motor controller current should not exceed this when pump should be running. Index: firmware/App/Controllers/Buttons.c =================================================================== diff -u -rdb291cc22fd8f10e6e47cad468e14ed5590a94f2 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision db291cc22fd8f10e6e47cad468e14ed5590a94f2) +++ firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -382,50 +382,49 @@ offRequestPulseTimer = 0; offRequestPulseCount = OFF_REQUEST_PULSE_COUNT; offButtonPressPending = TRUE; -} - -/*********************************************************************//** - * @brief - * The handleOffButtonProcessing function checks for and processes off button - * activity. - * @details Inputs: offButtonState, prevOffButtonState - * @details Outputs: offButtonPressPending, offRequestPulseCount, offRequestPulseTimer - * @return none - *************************************************************************/ -static void handleOffButtonProcessing( void ) -{ - // Handle button state transitions for off button - if ( getOffButtonState() != prevOffButtonState ) - { - if ( getOffButtonState() == BUTTON_STATE_PRESSED ) - { - // If off request in a valid mode, send to UI for user confirmation +} + +/*********************************************************************//** + * @brief + * The handleOffButtonProcessing function checks for and processes off button + * activity. + * @details Inputs: offButtonState, prevOffButtonState + * @details Outputs: offButtonPressPending, offRequestPulseCount, offRequestPulseTimer + * @return none + *************************************************************************/ +static void handleOffButtonProcessing( void ) +{ + // Handle button state transitions for off button + if ( getOffButtonState() != prevOffButtonState ) + { + if ( getOffButtonState() == BUTTON_STATE_PRESSED ) + { + // If off request in a valid mode, send to UI for user confirmation userConfirmOffButton( OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF ); // Log off button press - sendTreatmentLogEventData( OFF_BUTTON_PRESSED_EVENT, 0.0F, 0.0F ); - SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BUTTON, BUTTON_OFF, BUTTON_STATE_PRESSED ) + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BUTTON, BUTTON_OFF, BUTTON_STATE_PRESSED ) } else { SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BUTTON, BUTTON_OFF, BUTTON_STATE_RELEASED ) - } - prevOffButtonState = getOffButtonState(); - } - - // If off request has not been confirmed by user before it expires, cancel it - if ( TRUE == offRequestAwaitingUserConfirmation ) - { - offRequestPendingTimer += TASK_PRIORITY_INTERVAL; - if ( offRequestPendingTimer >= OFF_REQUEST_EXPIRATION_TIME_MS ) - { - offRequestAwaitingUserConfirmation = FALSE; - sendOffButtonMsgToUI( OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT ); - } - } - - // If user confirmed off button press, manage off request sequence - if ( TRUE == offButtonPressPending ) + } + prevOffButtonState = getOffButtonState(); + } + + // If off request has not been confirmed by user before it expires, cancel it + if ( TRUE == offRequestAwaitingUserConfirmation ) { + offRequestPendingTimer += TASK_PRIORITY_INTERVAL; + if ( offRequestPendingTimer >= OFF_REQUEST_EXPIRATION_TIME_MS ) + { + offRequestAwaitingUserConfirmation = FALSE; + sendOffButtonMsgToUI( OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT ); + } + } + + // If user confirmed off button press, manage off request sequence + if ( TRUE == offButtonPressPending ) + { // Delay power off to provide sub-systems time to prepare for shutdown offRequestDelayTimer += TASK_PRIORITY_INTERVAL; if ( offRequestDelayTimer >= OFF_REQUEST_DELAY_TIME_MS ) @@ -442,65 +441,64 @@ } toggleCPLDOffRequest(); } - } - } -} - -/*********************************************************************//** - * @brief - * The handleStopButtonProcessing function checks for and processes stop button - * activity. - * @details Inputs: stopButtonState, prevStopButtonState - * @details Outputs: stopButtonPressPending - * @return none - *************************************************************************/ -static void handleStopButtonProcessing( void ) -{ - // Handle button state transitions for stop button - if ( getStopButtonState() != prevStopButtonState ) - { - if ( getStopButtonState() == BUTTON_STATE_PRESSED ) - { - stopButtonPressPending = TRUE; + } + } +} + +/*********************************************************************//** + * @brief + * The handleStopButtonProcessing function checks for and processes stop button + * activity. + * @details Inputs: stopButtonState, prevStopButtonState + * @details Outputs: stopButtonPressPending + * @return none + *************************************************************************/ +static void handleStopButtonProcessing( void ) +{ + // Handle button state transitions for stop button + if ( getStopButtonState() != prevStopButtonState ) + { + if ( getStopButtonState() == BUTTON_STATE_PRESSED ) + { + stopButtonPressPending = TRUE; stopButtonPendingTimer = getMSTimerCount(); // Log stop button press - sendTreatmentLogEventData( STOP_BUTTON_PRESSED_EVENT, 0.0F, 0.0F ); SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BUTTON, BUTTON_STOP, BUTTON_STATE_PRESSED ) } else { SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BUTTON, BUTTON_STOP, BUTTON_STATE_RELEASED ) - } - prevStopButtonState = getStopButtonState(); - } - - // Handle when a stop button press is pending - if ( TRUE == stopButtonPressPending ) - { - // If stop button not consumed within a reasonable time, s/w fault - if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT_MS ) ) - { - stopButtonPressPending = FALSE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED ) - } - } -} - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testSetOffButtonStateOverride function overrides the state of then - * off button with a given state.n - * @details Inputs: none - * @details Outputs: dataOffButtonState - * @param value override state for the off button - * @return TRUE if override successful, FALSE if not - *************************************************************************/ + } + prevStopButtonState = getStopButtonState(); + } + + // Handle when a stop button press is pending + if ( TRUE == stopButtonPressPending ) + { + // If stop button not consumed within a reasonable time, s/w fault + if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT_MS ) ) + { + stopButtonPressPending = FALSE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED ) + } + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetOffButtonStateOverride function overrides the state of then + * off button with a given state.n + * @details Inputs: none + * @details Outputs: dataOffButtonState + * @param value override state for the off button + * @return TRUE if override successful, FALSE if not + *************************************************************************/ BOOL testSetOffButtonStateOverride( U32 value ) { BOOL result = FALSE; Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r0d0b4afdb49885d5cc66246a144268797d8f30e1 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 0d0b4afdb49885d5cc66246a144268797d8f30e1) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -40,13 +40,13 @@ // ********** private definitions ********** /// Default publication interval for pressure and occlusion data. -#define PRES_OCCL_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pressure/occlusion data is published on the CAN bus. -#define PRES_LIMIT_STABILIZATION_OFF ( 0 ) ///< pressure limit stabilization period off -#define PRES_LIMIT_STABILIZATION_2_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit second stage stabilization period (in ms) -#define PRES_LIMIT_STABILIZATION_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit stabilization period (in ms). -#define PRES_LIMIT_SHORT_STABILIZE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Duration of pressure limit short stabilization period (in ms). -#define PRES_LIMIT_RESTABILIZE_TIME_MS ( 15 * SEC_PER_MIN * MS_PER_SECOND ) ///< Duration of pressure limit re-stabilize period (in ms). -/// Pressure Limit minimum stabilization time before short stabilization time activation +#define PRES_OCCL_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pressure/occlusion data is published on the CAN bus. +#define PRES_LIMIT_STABILIZATION_OFF ( 0 ) ///< pressure limit stabilization period off +#define PRES_LIMIT_STABILIZATION_2_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit second stage stabilization period (in ms) +#define PRES_LIMIT_STABILIZATION_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit stabilization period (in ms). +#define PRES_LIMIT_SHORT_STABILIZE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Duration of pressure limit short stabilization period (in ms). +#define PRES_LIMIT_RESTABILIZE_TIME_MS ( 15 * SEC_PER_MIN * MS_PER_SECOND ) ///< Duration of pressure limit re-stabilize period (in ms). +// Pressure Limit minimum stabilization time before short stabilization time activation static const U32 PRES_LIMIT_MIN_STABILIZATION_TIME_IN_MS = ( PRES_LIMIT_STABILIZATION_TIME_MS - PRES_LIMIT_SHORT_STABILIZE_TIME_MS ); #define ARTERIAL_PRESSURE_CONVERSION_OFFSET 0x800000 ///< Arterial pressure conversion coefficient. @@ -86,7 +86,7 @@ #define MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_MS ( 1200 ) ///< To monitor low Venous pressure in the defined interval in a case where continuous air fill event happens followed by exemption period to stabilize the pressure #define MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_WINDOW ( MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_MS / \ - TASK_GENERAL_INTERVAL ) ///< Low Venous pressure monitoring window between air fill events based on the task interval time + TASK_GENERAL_INTERVAL ) ///< Low Venous pressure monitoring window between air fill events based on the task interval time #define PSI_TO_MMHG ( 51.7149F ) ///< Conversion factor for converting PSI to mmHg. @@ -179,7 +179,7 @@ static OVERRIDE_F32_T shortFilteredArterialPressure = { 0.0, 0.0, 0.0, 0 }; ///< Measured arterial pressure after short (1 s) filter. static F32 longFilteredVenousPressure; ///< Measured venous pressure after long (10 s) filter. static OVERRIDE_F32_T shortFilteredVenousPressure = { 0.0, 0.0, 0.0, 0 }; ///< Measured venous pressure after short (1 s) filter. -static STABILIZATION_PERIODS_T pressureStabilizeTime; ///< Pressure stabilization time based on system events such as airpump, treatment param changes etc., +static STABILIZATION_PERIODS_T pressureStabilizeTime; ///< Pressure stabilization time based on system events such as airpump, treatment param changes etc., static BOOL resetFillExemptPeriod; ///< Flag to reset the exempt period after defined time expire. static BOOL lowVenousPressureExemptCheck; ///< low venous pressure exempt check flag based on the air trap valve status @@ -1063,8 +1063,8 @@ *************************************************************************/ void signalLowVenousPressureCheck( void ) { - // When flag set, low venous pressure exempt counter increments. - lowVenousPressureExemptCheck = TRUE; + // When flag set, low venous pressure exempt counter increments. + lowVenousPressureExemptCheck = TRUE; } /*********************************************************************//** Index: firmware/App/Controllers/PresOccl.h =================================================================== diff -u -rfe09c28f4311017a2a7ba7a3953d85a61ccd7b97 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision fe09c28f4311017a2a7ba7a3953d85a61ccd7b97) +++ firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -35,10 +35,10 @@ /// Enumeration of stabilization periods. typedef enum StabilizationPeriods { - STABILIZATION_PERIOD_OFF = 0, ///< Stabilization period off - 0 seconds - USE_SHORT_STABILIZATION_PERIOD, ///< Short stabilization period for air pump event - 10 seconds - USE_NORMAL_STABILIZATION_PERIOD, ///< Normal Stabilization period for system events, excluding airpump events ( treatment param change, resume treatment etc.,) - 60 seconds - NUM_OF_STABILIZATION_PERIODS ///< Number of stabilization periods + STABILIZATION_PERIOD_OFF = 0, ///< Stabilization period off - 0 seconds + USE_SHORT_STABILIZATION_PERIOD, ///< Short stabilization period for air pump event - 10 seconds + USE_NORMAL_STABILIZATION_PERIOD, ///< Normal Stabilization period for system events, excluding airpump events ( treatment param change, resume treatment etc.,) - 60 seconds + NUM_OF_STABILIZATION_PERIODS ///< Number of stabilization periods } STABILIZATION_PERIODS_T; /// Enumeration of pressure sensors monitored by this module. @@ -52,13 +52,13 @@ /// Enumeration of arterial/venous pressure limits states. typedef enum PressureLimitsStates { - PRESSURE_LIMITS_STATE_OFF = 0, ///< Off - not pressure low/high alarms will be detected) - PRESSURE_LIMITS_STATE_IDLE, ///< Idle - in Treatment mode state where BP is stopped - no pressure low/high alarms - PRESSURE_LIMITS_STATE_WIDE, ///< Wide - in Treatment mode state where BP is running but wide limits apply - PRESSURE_LIMITS_STATE_STABILIZATION, ///< Stabilization - in Treatment mode state where BP is running (dialysis or stop), but need to stabilize first - PRESSURE_LIMITS_STATE_STABILIZATION_2, ///< Second stage stabilization - re adjust the pressure that has been drifted due to UF control etc and limit windows apply - PRESSURE_LIMITS_STATE_STABLE, ///< Stable - in Treatment mode state where BP is running (dialysis or stop) and limit windows apply - NUM_OF_PRESSURE_LIMITS_STATES ///< Number of pressure limits states + PRESSURE_LIMITS_STATE_OFF = 0, ///< Off - not pressure low/high alarms will be detected) + PRESSURE_LIMITS_STATE_IDLE, ///< Idle - in Treatment mode state where BP is stopped - no pressure low/high alarms + PRESSURE_LIMITS_STATE_WIDE, ///< Wide - in Treatment mode state where BP is running but wide limits apply + PRESSURE_LIMITS_STATE_STABILIZATION, ///< Stabilization - in Treatment mode state where BP is running (dialysis or stop), but need to stabilize first + PRESSURE_LIMITS_STATE_STABILIZATION_2, ///< Second stage stabilization - re adjust the pressure that has been drifted due to UF control etc and limit windows apply + PRESSURE_LIMITS_STATE_STABLE, ///< Stable - in Treatment mode state where BP is running (dialysis or stop) and limit windows apply + NUM_OF_PRESSURE_LIMITS_STATES ///< Number of pressure limits states } PRESSURE_LIMITS_STATES_T; /// Payload record structure for the pressure & occlusions data message. Index: firmware/App/Controllers/Switches.c =================================================================== diff -u -rdb291cc22fd8f10e6e47cad468e14ed5590a94f2 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/Switches.c (.../Switches.c) (revision db291cc22fd8f10e6e47cad468e14ed5590a94f2) +++ firmware/App/Controllers/Switches.c (.../Switches.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -137,17 +137,6 @@ // If the debounce time has been elapsed, update the switch status to the new status else if ( TRUE == didTimeout( switchesStatus[ i ].debounceStartTime, SWITCHES_DEBOUNCE_TIME_MS ) ) { - if ( FRONT_DOOR == i ) - { - // Log front door switch change - sendTreatmentLogEventData( FRONT_DOOR_SWITCH_CHANGED_EVENT, (F32)switchesStatus[ i ].status.data, (F32)currentSwitchStatus ); - } - // removed explicit check due to VectorCast coverage - else - { - // Log pump track switch change - sendTreatmentLogEventData( PUMP_TRACK_SWITCH_CHANGED_EVENT, (F32)switchesStatus[ i ].status.data, (F32)currentSwitchStatus ); - } // If the bit is 0, the door switch is open, because it is normally open switch switchesStatus[ i ].debounceStartTime = 0; switchesStatus[ i ].status.data = currentSwitchStatus; Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r61840ac769170169fb94a4d0b168452db54a129b -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 61840ac769170169fb94a4d0b168452db54a129b) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -1086,11 +1086,6 @@ syringePumpMeasSyringeDetectionSwitch.data = ( (F32)getFPGASyringePumpADCChannel1() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; } - // Log syringe detect switch changes - if ( prevSyringeDetected != isSyringeDetected() ) - { - sendTreatmentLogEventData( SYRINGE_DETECTION_SWITCH_CHANGED_EVENT, (F32)prevSyringeDetected, (F32)isSyringeDetected() ); - } // Handle syringe detect alarm management #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r089ef1b131059c038f3b6f56748e809c59cae971 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 089ef1b131059c038f3b6f56748e809c59cae971) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -771,7 +771,7 @@ if ( HW_CONFIG_BETA == getHardwareConfigStatus() ) { energizedUpperEdge = INITIAL_V3_ENERGIZED_EDGE_UPPER_RANGE; - energizedLowerEdge = INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE; + energizedLowerEdge = INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE; } #endif Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -rdb291cc22fd8f10e6e47cad468e14ed5590a94f2 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision db291cc22fd8f10e6e47cad468e14ed5590a94f2) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -307,21 +307,21 @@ *************************************************************************/ void setDialysisBloodPumpFlowRate( U32 bPFlow ) { - setBloodFlowRate = bPFlow; + setBloodFlowRate = bPFlow; - // Make rate changes in real time if currently performing dialysis. - if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) - { - PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Make rate changes in real time if currently performing dialysis. + if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) + { + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) - { - mode = PUMP_CONTROL_MODE_OPEN_LOOP; - } + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); - } + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); + } } /*********************************************************************//** @@ -338,25 +338,25 @@ *************************************************************************/ void setDialysisDialInFlowAndUFRate( U32 dPFlow, F32 maxUFVol, F32 uFRate ) { - setDialysateFlowRate = dPFlow; - setUFVolumeML = maxUFVol; - setUFRate = uFRate; + setDialysateFlowRate = dPFlow; + setUFVolumeML = maxUFVol; + setUFRate = uFRate; - // Make rate changes in real time if currently performing dialysis. - if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) - { - PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Make rate changes in real time if currently performing dialysis. + if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) + { + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) - { - mode = PUMP_CONTROL_MODE_OPEN_LOOP; - } + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); + setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); - setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - } + setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + } } /*********************************************************************//** Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r775fc673109760677ca4c3ed6e95af9324b02169 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 775fc673109760677ca4c3ed6e95af9324b02169) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -782,7 +782,28 @@ } state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_CMD_RESPONSE_STATE; } + else + { + switch ( getDGOpMode() ) + { + case DG_MODE_FLUS: + case DG_MODE_HEAT: + case DG_MODE_CHEM: + case DG_MODE_CHFL: + case DG_MODE_ROPS: + // This is for the situations that any of the disinfect modes are started using the proxy commands while the HD + // is in this state of the Standby Mode. + setRequestedCleaningMode( getDGOpMode() ); + state = STANDBY_WAIT_FOR_DG_CLEANING_MODE_TO_START_STATE; + currentDGCleaningMode.startCleaningMode = FALSE; + break; + default: + // Do nothing we are not in the cleaning mode + break; + } + } + return state; } Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r775fc673109760677ca4c3ed6e95af9324b02169 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 775fc673109760677ca4c3ed6e95af9324b02169) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -1014,23 +1014,28 @@ *************************************************************************/ BOOL verifyTreatmentDurationSettingChange( U32 treatmentTime ) { - BOOL result = FALSE; + BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejectReason = REQUEST_REJECT_REASON_NONE; - HD_OP_MODE_T currMode = getCurrentOperationMode(); + HD_OP_MODE_T currMode = getCurrentOperationMode(); // Check if we are in an appropriate treatment state for settings adjustment if ( ( MODE_TREA == currMode ) && ( currentTreatmentState > TREATMENT_START_STATE ) && ( currentTreatmentState < TREATMENT_END_STATE ) && ( CALC_ELAPSED_TREAT_TIME_IN_MIN() < treatmentTime ) && ( treatmentTime >= getMinTreatmentTimeInMinutes() ) ) { - F32 uFVolume; - U32 dialVolume = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) * treatmentTime; // In mL - // Always adjust UF volume to accommodate treatment time change (not UF rate) - uFVolume = ( (F32)( treatmentTime - CALC_ELAPSED_TREAT_TIME_IN_MIN() ) * presUFRate ) + getUltrafiltrationReferenceVolume(); - if ( ( treatmentTime <= MAX_TREATMENT_TIME_MINUTES ) && - ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) && - ( uFVolume <= MAX_UF_VOLUME_ML ) ) + F32 uFVolume = ( (F32)( treatmentTime - CALC_ELAPSED_TREAT_TIME_IN_MIN() ) * presUFRate ) + getUltrafiltrationReferenceVolume(); + F32 uFVolumeL = uFVolume / ML_PER_LITER; + U32 dialVolume = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) * treatmentTime; // In mL + // The minimum treatment time is either in the range of the institutional record or the 1-minute treatment config has been requested which is an exception + BOOL isMinTxTimeValid = ( ( treatmentTime >= getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ) ) || + ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_ONE_MINUTE_TREATMENT ) ) ? TRUE : FALSE ); + BOOL isTxTimeValid = ( ( TRUE == isMinTxTimeValid ) && + ( treatmentTime <= getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ) ) ? TRUE : FALSE ); + BOOL isMinUFVolValid = ( ( uFVolumeL >= getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_UF_VOLUME ) ) || ( uFVolumeL <= 0.0F ) ? TRUE : FALSE ); + BOOL isUFVolValid = ( ( TRUE == isMinUFVolValid ) && ( uFVolumeL <= getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_UF_VOLUME ) ) ? TRUE : FALSE ); + + if ( ( TRUE == isTxTimeValid ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) && ( TRUE == isUFVolValid ) ) { result = TRUE; sendTreatmentLogEventData( TREATMENT_DURATION_CHANGE_EVENT, ( presTreatmentTimeSecs / SEC_PER_MIN ), treatmentTime ); @@ -1043,11 +1048,11 @@ } else { - if ( treatmentTime > MAX_TREATMENT_TIME_MINUTES ) + if ( FALSE == isTxTimeValid ) { rejectReason = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; } - else if ( uFVolume > MAX_UF_VOLUME_ML ) + else if ( FALSE == isUFVolValid ) { rejectReason = REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE; } @@ -1117,7 +1122,9 @@ // Check if we are in an appropriate treatment state for settings adjustment if ( ( MODE_TREA == currMode ) && ( currentTreatmentState > TREATMENT_START_STATE ) && ( currentTreatmentState < TREATMENT_END_STATE ) && - ( uFVolume <= MAX_UF_VOLUME_ML ) && ( uFVolume > colUFVol ) && + ( uFVolume >= ( getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_UF_VOLUME ) * ML_PER_LITER ) ) && + ( uFVolume <= ( getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_UF_VOLUME ) * ML_PER_LITER ) ) && + ( uFVolume > colUFVol ) && ( CALC_TREAT_TIME_REMAINING_IN_SECS() >= PREVENT_UF_VOL_CHANGE_IF_NEARLY_DONE_SEC ) ) { DIALYSIS_STATE_T currDialysisState = getDialysisState(); @@ -1170,7 +1177,7 @@ rejectReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; } // UF volume cannot be set lower than the UF volume that has already been collected - else if ( ( uFVolume > MAX_UF_VOLUME_ML ) || + else if ( ( uFVolume > ( getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_UF_VOLUME ) * ML_PER_LITER ) ) || ( uFVolume <= colUFVol ) ) { rejectReason = REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE; @@ -1211,9 +1218,8 @@ UF_STATE_T currUFState = getUltrafiltrationState(); sendTreatmentLogEventData( UF_VOLUME_CHANGE_EVENT, presMaxUFVolumeML, pendingUFVolumeChange ); - result = TRUE; presMaxUFVolumeML = pendingUFVolumeChange; - setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); + result = setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); // User should only allow UF rate adjustment to achieve UF volume change if ( UF_ADJ_UF_RATE == adjustment ) @@ -1276,8 +1282,10 @@ U32 dialVolume = dialRate * ( (U32)( (F32)presTreatmentTimeSecs / (F32)SEC_PER_MIN ) + 1 ); // In mL // Validate new rates - if ( ( bloodRate >= MIN_SET_BLOOD_FLOW_RATE ) && ( bloodRate <= MAX_SET_BLOOD_FLOW_RATE ) && - ( dialRate >= MIN_DIAL_IN_FLOW_RATE ) && ( dialRate <= MAX_DIAL_IN_FLOW_RATE ) && + if ( ( bloodRate >= getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ) ) && + ( bloodRate <= getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ) ) && + ( dialRate >= getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ) ) && + ( dialRate <= getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ) ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) ) { result = TRUE; @@ -1287,7 +1295,7 @@ sendTreatmentLogEventData( BLOOD_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), bloodRate ); signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); // Set to new rate - setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, bloodRate ); + result &= setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, bloodRate ); setDialysisBloodPumpFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) ); } @@ -1297,17 +1305,19 @@ sendTreatmentLogEventData( DIALYSATE_FLOW_RATE_CHANGE_EVENT, getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), dialRate ); signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); // Set to new rate - setTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW, dialRate ); + result &= setTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW, dialRate ); setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); } } else { - if ( ( bloodRate < MIN_SET_BLOOD_FLOW_RATE ) || ( bloodRate > MAX_SET_BLOOD_FLOW_RATE ) ) + if ( ( bloodRate < getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ) ) || + ( bloodRate > getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_BLOOD_FLOW ) ) ) { rejectReason = REQUEST_REJECT_REASON_BLOOD_FLOW_OUT_OF_RANGE; } - else if ( ( dialRate < MIN_DIAL_IN_FLOW_RATE ) || ( dialRate > MAX_DIAL_IN_FLOW_RATE ) ) + else if ( ( dialRate < getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ) ) || + ( dialRate > getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_DIALYSATE_FLOW ) ) ) { rejectReason = REQUEST_REJECT_REASON_DIAL_FLOW_OUT_OF_RANGE; } Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -r775fc673109760677ca4c3ed6e95af9324b02169 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision 775fc673109760677ca4c3ed6e95af9324b02169) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -90,6 +90,7 @@ static BOOL treatParamsConfirmed = FALSE; ///< Flag indicates user has confirmed the treatment parameters. static BOOL treatParamsRejected = FALSE; ///< Flag indicates user has rejected the treatment parameters. static BOOL treatmentCancelled = FALSE; ///< Flag indicates user has cancelled the treatment. +static HD_INSTITUTIONAL_RECORD_T hdInstitutionalRecord; ///< Institutional record. // ********** private function prototypes ********** @@ -100,6 +101,8 @@ static BOOL checkTreatmentParamsDependencies( U32 *reasons ); static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ); static void sendTreatmentParamsResponse( BOOL rejected, U32 *reasons ); +static void checkPressureParamsRange( TREATMENT_PARAMS_DATA_PAYLOAD_T* txParams ); +static void getInstitutionalRecordEdgeValue( TREATMENT_PARAM_T param, CRITICAL_DATAS_T* value, BOOL isMin ); /*********************************************************************//** * @brief @@ -146,6 +149,9 @@ // Request the concentrate pumps mixing ratios and the DG fill mode prepare time cmdRequestDGMixingRatios(); + // Get the institutional record upon transitioning to treatment parameters + getNVRecord2Driver( GET_INSTITUTIONAL_RECORD, (U08*)&hdInstitutionalRecord, sizeof( HD_INSTITUTIONAL_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + return currentTreatmentParamsState; } @@ -482,6 +488,10 @@ params.heparinType = 0; } + // Check the received arterial and venous pressure values from the UI to be checked and capped against the min and max + // values in the institutional record + checkPressureParamsRange( ¶ms ); + // Extract treatment parameters from given payload to staging array so we can more easily work with them extractTreatmentParamsFromPayload( params ); @@ -603,7 +613,7 @@ * @brief * The isTreatmentParamInRange function determines whether a given treatment * parameter is in range. - * @details Inputs: treatParamsRanges[] + * @details Inputs: treatParamsRanges[], hdInstitutionalRecord * @details Outputs: none * @param param ID of parameter to check range for * @param value value of parameter to check range for @@ -615,27 +625,105 @@ if ( param < NUM_OF_TREATMENT_PARAMS ) { - if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) + switch( param ) { - if ( value.uInt >= TREAT_PARAMS_PROPERTIES[ param ].min.uInt && value.uInt <= TREAT_PARAMS_PROPERTIES[ param ].max.uInt ) - { - result = TRUE; - } + case TREATMENT_PARAM_BLOOD_FLOW: + result = ( ( value.uInt >= hdInstitutionalRecord.minBloodFlowMLPM ) && + ( value.uInt <= hdInstitutionalRecord.maxBloodFlowMLPM ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_DIALYSATE_FLOW: + result = ( ( value.uInt >= hdInstitutionalRecord.minDialysateFlowMLPM ) && + ( value.uInt <= hdInstitutionalRecord.maxDialysateFlowMLPM ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_TREATMENT_DURATION: + result = ( ( value.uInt >= hdInstitutionalRecord.minTxDurationMIN ) && + ( value.uInt <= hdInstitutionalRecord.maxTxDurationMIN ) ? TRUE : FALSE ); + // If the 1-minute treatment is selected, it is ok to accept the time. This test configuration specifically checks for a 1-minute run + result |= ( TRUE == getTestConfigStatus( TEST_CONFIG_ENABLE_ONE_MINUTE_TREATMENT ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME: + result = ( ( value.uInt >= hdInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN ) && + ( value.uInt <= hdInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN ) ? TRUE : FALSE ); + // The value of the heparin pre stop time should only be checked if the heparin dispense rate in not zero. + // If the stop time is outside of range but the heparin dispense rate is 0, this item has passed regardless. + // If the stop time is outside of range and the heparin is not 0, then this item has failed. + // Staged params is directly used because the heparin dispense rate is check after the stop so we need to know about it + // prior to checking later in this switch case + result |= ( stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt <= NEARLY_ZERO ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_SALINE_BOLUS_VOLUME: + result = ( ( value.uInt >= hdInstitutionalRecord.minSalineBolusVolumeML ) && + ( value.uInt <= hdInstitutionalRecord.maxSalineBolusVolumeML ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_DIALYSATE_TEMPERATURE: + result = ( ( value.sFlt >= hdInstitutionalRecord.minDialysateTempC ) && + ( value.sFlt <= hdInstitutionalRecord.maxDialysateTempC ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW: + result = ( ( value.sInt >= hdInstitutionalRecord.minArtPressLimitWindowMMHG ) && + ( value.sInt <= hdInstitutionalRecord.maxArtPressLimitWindowMMHG ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW: + result = ( ( value.sInt >= hdInstitutionalRecord.minVenPressLimitWindowMMHG ) && + ( value.sInt <= hdInstitutionalRecord.maxVenPressLimitWindowMMHG ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC: + result = ( ( value.sInt >= hdInstitutionalRecord.minVenAsymPressLimitMMHG ) && + ( value.sInt <= hdInstitutionalRecord.maxVenAsymPressLimitMMHG ) ? TRUE : FALSE ); + break; + + case TREATMENT_PARAM_UF_VOLUME: + result = ( ( value.sFlt >= hdInstitutionalRecord.minUFVolumeL ) && ( value.sFlt <= hdInstitutionalRecord.maxUFVolumeL ) ? TRUE : FALSE ); + result |= ( value.sFlt <= NEARLY_ZERO ? TRUE : FALSE ); // There might be a minimum UF volume set in the institutional record but a treatment with 0 vol should be allowed + break; + + case TREATMENT_PARAM_HEPARIN_DISPENSE_RATE: + result = ( ( value.sFlt >= hdInstitutionalRecord.minHeparinDispRateMLPHR ) && + ( value.sFlt <= hdInstitutionalRecord.maxHeparinDispRateMLPHR ) ? TRUE : FALSE ); + result |= ( value.sFlt <= NEARLY_ZERO ? TRUE : FALSE ); // Even if the minimum is not 0, 0 is accepted meaning heparin can be turned off + break; + + case TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME: + result = ( ( value.sFlt >= hdInstitutionalRecord.minHeparinBolusVolumeML ) && + ( value.sFlt <= hdInstitutionalRecord.maxHeparinBolusVolumeML ) ? TRUE : FALSE ); + result |= ( value.sFlt <= NEARLY_ZERO ? TRUE : FALSE ); // Even if the minimum is not 0, 0 is accepted meaning heparin can be turned off + break; + + default: +#ifndef _VECTORCAST_ + // The treatment parameters that do not have any institutional record. + // Right now, all the F32 and S32 data types are covered in the institutional record and therefore, there is no test case that is either F32 or S32 + // and gets here so it is removed from VectorCAST to be able to achieve 100% coverage of the function + // The treatment parameters that do not have any institutional record. + if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) +#endif + { + result = ( ( value.uInt >= TREAT_PARAMS_PROPERTIES[ param ].min.uInt ) && + ( value.uInt <= TREAT_PARAMS_PROPERTIES[ param ].max.uInt ) ? TRUE : FALSE ); + } +#ifndef _VECTORCAST_ + // Right now, all the F32 and S32 data types are covered in the institutional record and therefore, there is no test case that is either F32 or S32 + // and gets here so it is removed from VectorCAST to be able to achieve 100% coverage of the function + else if ( CRITICAL_DATA_TYPE_S32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) + { + result = ( ( value.sInt >= TREAT_PARAMS_PROPERTIES[ param ].min.sInt ) && + ( value.sInt <= TREAT_PARAMS_PROPERTIES[ param ].max.sInt ) ? TRUE : FALSE ); + } + else + { + result = ( ( value.sFlt >= TREAT_PARAMS_PROPERTIES[ param ].min.sFlt ) && + ( value.sFlt <= TREAT_PARAMS_PROPERTIES[ param ].max.sFlt ) ? TRUE : FALSE ); + } +#endif } - else if ( CRITICAL_DATA_TYPE_S32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) - { - if ( value.sInt >= TREAT_PARAMS_PROPERTIES[ param ].min.sInt && value.sInt <= TREAT_PARAMS_PROPERTIES[ param ].max.sInt ) - { - result = TRUE; - } - } - else - { - if ( value.sFlt >= TREAT_PARAMS_PROPERTIES[ param ].min.sFlt && value.sFlt <= TREAT_PARAMS_PROPERTIES[ param ].max.sFlt ) - { - result = TRUE; - } - } } else { @@ -660,7 +748,9 @@ if ( param < NUM_OF_TREATMENT_PARAMS ) { - result = TREAT_PARAMS_PROPERTIES[ param ].min.sInt; + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, TRUE ); + result = value.sInt; } else { @@ -685,7 +775,9 @@ if ( param < NUM_OF_TREATMENT_PARAMS ) { - result = TREAT_PARAMS_PROPERTIES[ param ].max.sInt; + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, FALSE ); + result = value.sInt; } else { @@ -697,6 +789,251 @@ /*********************************************************************//** * @brief + * The getU32TreatmentParamLowerRangeLimit function returns the lower range + * limit for a given unsigned integer treatment parameter. + * @details Inputs: none + * @details Outputs: none + * @param param ID of parameter to get lower range limit for + * @return lower range limit for given unsigned integer treatment parameter + *************************************************************************/ +U32 getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ) +{ + U32 result = 0; + + if ( param < NUM_OF_TREATMENT_PARAMS ) + { + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, TRUE ); + result = value.uInt; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_U32_PARAM_MIN_LIMIT, (U32)param ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getU32TreatmentParamUpperRangeLimit function returns the upper range + * limit for a given unsigned integer treatment parameter. + * @details Inputs: none + * @details Outputs: none + * @param param ID of parameter to get upper range limit for + * @return upper range limit for given unsigned integer treatment parameter + *************************************************************************/ +U32 getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ) +{ + U32 result = 0; + + if ( param < NUM_OF_TREATMENT_PARAMS ) + { + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, FALSE ); + result = value.uInt; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_U32_PARAM_MAX_LIMIT, (U32)param ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getF32TreatmentParamLowerRangeLimit function returns the lower range + * limit for a given float treatment parameter. + * @details Inputs: none + * @details Outputs: none + * @param param ID of parameter to get lower range limit for + * @return lower range limit for given float treatment parameter + *************************************************************************/ +F32 getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ) +{ + F32 result = 0; + + if ( param < NUM_OF_TREATMENT_PARAMS ) + { + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, TRUE ); + result = value.sFlt; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_F32_PARAM_MIN_LIMIT, (U32)param ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getF32TreatmentParamUpperRangeLimit function returns the upper range + * limit for a given float treatment parameter. + * @details Inputs: none + * @details Outputs: none + * @param param ID of parameter to get lower range limit for + * @return upper range limit for given float treatment parameter + *************************************************************************/ +F32 getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ) +{ + F32 result = 0; + + if ( param < NUM_OF_TREATMENT_PARAMS ) + { + CRITICAL_DATAS_T value; + getInstitutionalRecordEdgeValue( param, &value, FALSE ); + result = value.sFlt; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_F32_PARAM_MAX_LIMIT, (U32)param ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getS32DefaultTreatmentParamEdge function returns the min or max of + * the default treatment parameters + * @details Inputs: TREAT_PARAMS_PROPERTIES + * @details Outputs: none + * @param param ID of parameter + * @param isMin to indicate whether minimum is needed for maximum + * @return the requested min or max value + *************************************************************************/ +S32 getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ) +{ + S32 value = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.sInt : TREAT_PARAMS_PROPERTIES[ param ].max.sInt ); + + return value; +} + +/*********************************************************************//** + * @brief + * The getU32DefaultTreatmentParamEdge function returns the min or max of + * the default treatment parameters + * @details Inputs: TREAT_PARAMS_PROPERTIES + * @details Outputs: none + * @param param ID of parameter + * @param isMin to indicate whether minimum is needed for maximum + * @return the requested min or max value + *************************************************************************/ +U32 getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ) +{ + U32 value = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.uInt : TREAT_PARAMS_PROPERTIES[ param ].max.uInt ); + + return value; +} + +/*********************************************************************//** + * @brief + * The getF32DefaultTreatmentParamEdge function returns the min or max of + * the default treatment parameters + * @details Inputs: TREAT_PARAMS_PROPERTIES + * @details Outputs: none + * @param param ID of parameter + * @param isMin to indicate whether minimum is needed for maximum + * @return the requested min or max value + *************************************************************************/ +F32 getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ) +{ + F32 value = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.sFlt : TREAT_PARAMS_PROPERTIES[ param ].max.sFlt ); + + return value; +} + +/*********************************************************************//** + * @brief + * The isNVInstitutionalRecordInRange function checks whether all the + * institutional NV records are valid and within range or not. + * @details Inputs: none + * @details Outputs: none + * @param nvInstRcrd pointer to the institutional record in the non-volatile + * data management + * @return TRUE if all of the parameters are valid otherwise, FALSE + *************************************************************************/ +BOOL isNVInstitutionalRecordInRange( HD_INSTITUTIONAL_RECORD_T* nvInstRcrd ) +{ + BOOL result = TRUE; + + result &= ( ( nvInstRcrd->minBloodFlowMLPM >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_BLOOD_FLOW ].min.uInt ) && + ( nvInstRcrd->minBloodFlowMLPM <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_BLOOD_FLOW ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxBloodFlowMLPM >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_BLOOD_FLOW ].min.uInt ) && + ( nvInstRcrd->maxBloodFlowMLPM <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_BLOOD_FLOW ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minDialysateFlowMLPM >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_FLOW ].min.uInt ) && + ( nvInstRcrd->minDialysateFlowMLPM <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_FLOW ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxDialysateFlowMLPM >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_FLOW ].min.uInt ) && + ( nvInstRcrd->maxDialysateFlowMLPM <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_FLOW ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minTxDurationMIN >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_TREATMENT_DURATION ].min.uInt ) && + ( nvInstRcrd->minTxDurationMIN <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_TREATMENT_DURATION ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxTxDurationMIN >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_TREATMENT_DURATION ].min.uInt ) && + ( nvInstRcrd->maxTxDurationMIN <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_TREATMENT_DURATION ].max.uInt ) ? TRUE : FALSE ); +#ifndef _VECTORCAST_ + // The heparin stop time has been masked out from VectorCAST because the minimum time is 0 minutes while the variable is a U32 so it cannot be + // tested in VectorCAST by setting the minimum to less than 0. + result &= ( ( nvInstRcrd->minStopHeparinDispBeforeTxEndMIN >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].min.uInt ) && + ( nvInstRcrd->minStopHeparinDispBeforeTxEndMIN <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxStopHeparinDispBeforeTxEndMIN >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].min.uInt ) && + ( nvInstRcrd->maxStopHeparinDispBeforeTxEndMIN <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].max.uInt ) ? TRUE : FALSE ); +#endif + result &= ( ( nvInstRcrd->minSalineBolusVolumeML >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_SALINE_BOLUS_VOLUME ].min.uInt ) && + ( nvInstRcrd->minSalineBolusVolumeML <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_SALINE_BOLUS_VOLUME ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxSalineBolusVolumeML >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_SALINE_BOLUS_VOLUME ].min.uInt ) && + ( nvInstRcrd->maxSalineBolusVolumeML <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_SALINE_BOLUS_VOLUME ].max.uInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minDialysateTempC >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_TEMPERATURE ].min.sFlt ) && + ( nvInstRcrd->minDialysateTempC <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_TEMPERATURE ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxDialysateTempC >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_TEMPERATURE ].min.sFlt ) && + ( nvInstRcrd->maxDialysateTempC <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_DIALYSATE_TEMPERATURE ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minArtPressLimitWindowMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ].min.sInt ) && + ( nvInstRcrd->minArtPressLimitWindowMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxArtPressLimitWindowMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ].min.sInt ) && + ( nvInstRcrd->maxArtPressLimitWindowMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minVenPressLimitWindowMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ].min.sInt ) && + ( nvInstRcrd->minVenPressLimitWindowMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxVenPressLimitWindowMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ].min.sInt ) && + ( nvInstRcrd->maxVenPressLimitWindowMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minVenAsymPressLimitMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ].min.sInt ) && + ( nvInstRcrd->minVenAsymPressLimitMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxVenAsymPressLimitMMHG >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ].min.sInt ) && + ( nvInstRcrd->maxVenAsymPressLimitMMHG <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ].max.sInt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minUFVolumeL >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_UF_VOLUME ].min.sFlt ) && + ( nvInstRcrd->minUFVolumeL <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_UF_VOLUME ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxUFVolumeL >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_UF_VOLUME ].min.sFlt ) && + ( nvInstRcrd->maxUFVolumeL <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_UF_VOLUME ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minHeparinDispRateMLPHR >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].min.sFlt ) && + ( nvInstRcrd->minHeparinDispRateMLPHR <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxHeparinDispRateMLPHR >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].min.sFlt ) && + ( nvInstRcrd->maxHeparinDispRateMLPHR <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->minHeparinBolusVolumeML >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].min.sFlt ) && + ( nvInstRcrd->minHeparinBolusVolumeML <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].max.sFlt ) ? TRUE : FALSE ); + result &= ( ( nvInstRcrd->maxHeparinBolusVolumeML >= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].min.sFlt ) && + ( nvInstRcrd->maxHeparinBolusVolumeML <= TREAT_PARAMS_PROPERTIES[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].max.sFlt ) ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The setNVInstitutionalRecordToTxParamsRecord function sets the newly received + * institutional record from the non-volatile memory to the local copy in the + * treatment parameters. + * @details Inputs: none + * @details Outputs: hdInstitutionalRecord + * @param nvInstitutionalRecord pointer to the newly received institutional record + * in the non-volatile data management. + * @return none + *************************************************************************/ +void setNVInstitutionalRecordToTxParamsRecord( HD_INSTITUTIONAL_RECORD_T* nvInstitutionalRecord ) +{ + memcpy( &hdInstitutionalRecord, nvInstitutionalRecord, sizeof(HD_INSTITUTIONAL_RECORD_T) ); +} + +/*********************************************************************//** + * @brief * The extractTreatmentParamsFromPayload function extracts the individual * treatment parameters received from the UI into a staging array where * they will be validated and stay until user confirms them. @@ -745,15 +1082,22 @@ *************************************************************************/ BOOL setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ) { + CRITICAL_DATAS_T integerData; BOOL result = FALSE; + integerData.uInt = value; + result = isTreatmentParamInRange( param, integerData ); + // Validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { - CRITICAL_DATAS_T data = treatmentParameters[ param ].data; + if ( TRUE == result ) + { + CRITICAL_DATAS_T data = treatmentParameters[ param ].data; - data.uInt = value; - result = setCriticalData( &treatmentParameters[ param ], data ); + data.uInt = value; + result = setCriticalData( &treatmentParameters[ param ], data ); + } } else { @@ -775,15 +1119,22 @@ *************************************************************************/ BOOL setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ) { + CRITICAL_DATAS_T unsignedIntData; BOOL result = FALSE; + unsignedIntData.sInt = value; + result = isTreatmentParamInRange( param, unsignedIntData ); + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { - CRITICAL_DATAS_T data = treatmentParameters[ param ].data; + if ( TRUE == result ) + { + CRITICAL_DATAS_T data = treatmentParameters[ param ].data; - data.sInt = value; - result = setCriticalData( &treatmentParameters[ param ], data ); + data.sInt = value; + result = setCriticalData( &treatmentParameters[ param ], data ); + } } else { @@ -805,15 +1156,22 @@ *************************************************************************/ BOOL setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ) { + CRITICAL_DATAS_T floatData; BOOL result = FALSE; + floatData.sFlt = value; + result = isTreatmentParamInRange( param, floatData ); + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { - CRITICAL_DATAS_T data = treatmentParameters[ param ].data; + if ( TRUE == result ) + { + CRITICAL_DATAS_T data = treatmentParameters[ param ].data; - data.sFlt = value; - result = setCriticalData( &treatmentParameters[ param ], data ); + data.sFlt = value; + result = setCriticalData( &treatmentParameters[ param ], data ); + } } else { @@ -951,7 +1309,142 @@ return ( ( origTreatmentParams.uFVolume_L * ML_PER_LITER ) / origTreatmentParams.treatmentDuration_min ); } +/*********************************************************************//** + * @brief + * The checkPressureParamsRange function checks the provided arterial and venous + * pressure values that are provided by the user + * @details Inputs: hdInstitutionalRecord + * @details Outputs: none + * @param txParams pointer to the provided treatment parameters + * @return none + *************************************************************************/ +static void checkPressureParamsRange( TREATMENT_PARAMS_DATA_PAYLOAD_T* txParams ) +{ + S32 pressureMMHG = 0; + S32 minInstitutionalMMHG = 0; + S32 maxInstitutionalMMHG = 0; + // Check arterial pressure ranges + pressureMMHG = txParams->arterialPressureLimitWindow_mmHg; + minInstitutionalMMHG = hdInstitutionalRecord.minArtPressLimitWindowMMHG; + maxInstitutionalMMHG = hdInstitutionalRecord.maxArtPressLimitWindowMMHG; + pressureMMHG = ( pressureMMHG < minInstitutionalMMHG ? minInstitutionalMMHG : pressureMMHG ); + pressureMMHG = ( pressureMMHG > maxInstitutionalMMHG ? maxInstitutionalMMHG : pressureMMHG ); + txParams->arterialPressureLimitWindow_mmHg = pressureMMHG; + + // Check venous pressure ranges + pressureMMHG = txParams->venousPressureLimitWindow_mmHg; + minInstitutionalMMHG = hdInstitutionalRecord.minVenPressLimitWindowMMHG; + maxInstitutionalMMHG = hdInstitutionalRecord.maxVenPressLimitWindowMMHG; + pressureMMHG = ( pressureMMHG < minInstitutionalMMHG ? minInstitutionalMMHG : pressureMMHG ); + pressureMMHG = ( pressureMMHG > maxInstitutionalMMHG ? maxInstitutionalMMHG : pressureMMHG ); + txParams->venousPressureLimitWindow_mmHg = pressureMMHG; + + // Check venous asymmetric ranges + pressureMMHG = txParams->venousPressureLimitAsymmetric_mmHg; + minInstitutionalMMHG = hdInstitutionalRecord.minVenAsymPressLimitMMHG; + maxInstitutionalMMHG = hdInstitutionalRecord.maxVenAsymPressLimitMMHG; + pressureMMHG = ( pressureMMHG < minInstitutionalMMHG ? minInstitutionalMMHG : pressureMMHG ); + pressureMMHG = ( pressureMMHG > maxInstitutionalMMHG ? maxInstitutionalMMHG : pressureMMHG ); + txParams->venousPressureLimitAsymmetric_mmHg = pressureMMHG; +} + +/*********************************************************************//** + * @brief + * The getInstitutionalRecordEdgeValue function returns the minimum or + * the maximum value in the HD institutional record + * @details Inputs: hdInstitutionalRecord + * @details Outputs: none + * @param txParams pointer to the provided treatment parameters + * @param value pointer the CRITICAL_DATAS_T union + * @param isMin boolean flag to indicate whether min is needed or max + * @return none + *************************************************************************/ +static void getInstitutionalRecordEdgeValue( TREATMENT_PARAM_T param, CRITICAL_DATAS_T* value, BOOL isMin ) +{ + if ( param < NUM_OF_TREATMENT_PARAMS ) + { + switch( param ) + { + case TREATMENT_PARAM_BLOOD_FLOW: + value->uInt = ( TRUE == isMin ? hdInstitutionalRecord.minBloodFlowMLPM : hdInstitutionalRecord.maxBloodFlowMLPM ); + break; + + case TREATMENT_PARAM_DIALYSATE_FLOW: + value->uInt = ( TRUE == isMin ? hdInstitutionalRecord.minDialysateFlowMLPM : hdInstitutionalRecord.maxDialysateFlowMLPM ); + break; + + case TREATMENT_PARAM_TREATMENT_DURATION: + value->uInt = ( TRUE == isMin ? hdInstitutionalRecord.minTxDurationMIN : hdInstitutionalRecord.maxTxDurationMIN ); + break; + + case TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME: + value->uInt = ( TRUE == isMin ? hdInstitutionalRecord.minStopHeparinDispBeforeTxEndMIN : hdInstitutionalRecord.maxStopHeparinDispBeforeTxEndMIN ); + break; + + case TREATMENT_PARAM_SALINE_BOLUS_VOLUME: + value->uInt = ( TRUE == isMin ? hdInstitutionalRecord.minSalineBolusVolumeML : hdInstitutionalRecord.maxSalineBolusVolumeML ); + break; + + case TREATMENT_PARAM_DIALYSATE_TEMPERATURE: + value->sFlt = ( TRUE == isMin ? hdInstitutionalRecord.minDialysateTempC : hdInstitutionalRecord.maxDialysateTempC ); + break; + + case TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW: + value->sInt = ( TRUE == isMin ? hdInstitutionalRecord.minArtPressLimitWindowMMHG : hdInstitutionalRecord.maxArtPressLimitWindowMMHG ); + break; + + case TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW: + value->sInt = ( TRUE == isMin ? hdInstitutionalRecord.minVenPressLimitWindowMMHG : hdInstitutionalRecord.maxVenPressLimitWindowMMHG ); + break; + + case TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC: + value->sInt = ( TRUE == isMin ? hdInstitutionalRecord.minVenAsymPressLimitMMHG : hdInstitutionalRecord.maxVenAsymPressLimitMMHG ); + break; + + case TREATMENT_PARAM_UF_VOLUME: + value->sFlt = ( TRUE == isMin ? hdInstitutionalRecord.minUFVolumeL : hdInstitutionalRecord.maxUFVolumeL ); + break; + + case TREATMENT_PARAM_HEPARIN_DISPENSE_RATE: + value->sFlt = ( TRUE == isMin ? hdInstitutionalRecord.minHeparinDispRateMLPHR : hdInstitutionalRecord.maxHeparinDispRateMLPHR ); + break; + + case TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME: + value->sFlt = ( TRUE == isMin ? hdInstitutionalRecord.minHeparinBolusVolumeML : hdInstitutionalRecord.maxHeparinBolusVolumeML ); + break; + + default: +#ifndef _VECTORCAST_ + // The treatment parameters that do not have any institutional record. + // Right now, all the F32 and S32 data types are covered in the institutional record and therefore, there is no test case that is either F32 or S32 + // and gets here so it is removed from VectorCAST to be able to achieve 100% coverage of the function + if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) +#endif + { + value->uInt = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.uInt : TREAT_PARAMS_PROPERTIES[ param ].max.uInt ); + } +#ifndef _VECTORCAST_ + // Right now, all the F32 and S32 data types are covered in the institutional record and therefore, there is no test case that is either F32 or S32 + // and gets here so it is removed from VectorCAST to be able to achieve 100% coverage of the function + else if ( CRITICAL_DATA_TYPE_S32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) + { + value->sInt = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.sInt : TREAT_PARAMS_PROPERTIES[ param ].max.sInt ); + } + else + { + value->sFlt = ( TRUE == isMin ? TREAT_PARAMS_PROPERTIES[ param ].min.sFlt : TREAT_PARAMS_PROPERTIES[ param ].max.sFlt ); + } +#endif + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_PARAM, (U32)param ) + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/ModeTreatmentParams.h =================================================================== diff -u -r775fc673109760677ca4c3ed6e95af9324b02169 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision 775fc673109760677ca4c3ed6e95af9324b02169) +++ firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -20,6 +20,7 @@ #include "HDCommon.h" #include "HDDefs.h" +#include "NVDataMgmt.h" #include "Utilities.h" /** @@ -106,6 +107,17 @@ BOOL isTreatmentParamInRange( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ); // Check range for a proposed treatment parameter value S32 getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ); // Get the lower range limit for a signed integer treatment parameter S32 getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ); // Get the upper range limit for a signed integer treatment parameter +U32 getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ); // Get the lower range limit for an unsigned integer treatment parameter +U32 getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ); // Get the upper range limit for an unsigned integer treatment parameter +F32 getF32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ); // Get the lower range limit for a float treatment parameter +F32 getF32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ); // Get the upper range limit for a float treatment parameter +S32 getS32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ); +U32 getU32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ); +F32 getF32DefaultTreatmentParamEdge( TREATMENT_PARAM_T param, BOOL isMin ); + +BOOL isNVInstitutionalRecordInRange( HD_INSTITUTIONAL_RECORD_T* nvInstRcrd ); // Is non-volatile memory institutional record in range +void setNVInstitutionalRecordToTxParamsRecord( HD_INSTITUTIONAL_RECORD_T* nvInstitutionalRecord ); // Set the recently received institution record from NV to local tx parameters + F32 getUltrafiltrationVolumeOriginal( void ); // Get the original ultrafiltration volume, set in pre-treatment mode by user. F32 getUltrafiltrationRateOriginal( void ); // Get/calculate the original ultrafiltration rate, by ultrafiltration volume and treatment duration set in pre-treatment mode by user. Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -rdb291cc22fd8f10e6e47cad468e14ed5590a94f2 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision db291cc22fd8f10e6e47cad468e14ed5590a94f2) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -347,10 +347,6 @@ setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); - if ( isTreatmentCompleted() != TRUE ) - { - sendTreatmentLogEventData( MID_TREATMENT_RINSE_BACK_EVENT, 0.0, rinsebackRate_mL_min ); - } setupForRinsebackDelivery( rinsebackRate_mL_min ); // From moment we start rinseback, we consider blood side of dialyzer no longer fully primed setBloodIsPrimed( FALSE ); Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rc9d0d71b4bb1b14c785bf51399f1da5820ded7a7 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision c9d0d71b4bb1b14c785bf51399f1da5820ded7a7) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -14,58 +14,58 @@ * @date (original) 07-Nov-2019 * ***************************************************************************/ - -#include "mibspi.h" - + +#include "mibspi.h" + #define __ALARM_MGMT_C__ #include "AlarmLamp.h" #include "CPLD.h" #include "FPGA.h" -#include "InternalADC.h" +#include "InternalADC.h" #include "OperationModes.h" #include "SafetyShutdown.h" -#include "SystemCommMessages.h" -#include "TaskGeneral.h" -#include "Timers.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "Timers.h" -/** - * @addtogroup AlarmManagement - * @{ - */ - -// ********** private definitions ********** +/** + * @addtogroup AlarmManagement + * @{ + */ -/// Interval to control lamp and audio and to publish alarm status data. -#define ALARM_STATUS_PUBLISH_INTERVAL ( ALARM_LAMP_AND_AUDIO_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) +// ********** private definitions ********** + +/// Interval to control lamp and audio and to publish alarm status data. +#define ALARM_STATUS_PUBLISH_INTERVAL ( ALARM_LAMP_AND_AUDIO_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) /// Interval (ms/task time) at which the alarm information is published on the CAN bus. #define ALARM_INFO_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Interval (ms/task time) Alarms are blocked after the return of AC power. #define ALARM_BLOCKED_COUNT_AFTER_AC_RETURN ( 10*MS_PER_SECOND / TASK_GENERAL_INTERVAL ) - -#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. - + +#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. + #define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. #define LOWEST_ALARM_SUB_RANK 999 ///< Lowest alarm sub-rank that can be set. #define ALARM_NOT_BLOCKED 0 ///< Alarm blocked timer value that indicates no alarm block -#define MIN_TIME_BETWEEN_ALARM_ACTIONS_MS MS_PER_SECOND ///< Minimum time between user alarm actions (in ms). - +#define MIN_TIME_BETWEEN_ALARM_ACTIONS_MS MS_PER_SECOND ///< Minimum time between user alarm actions (in ms). + // *** This declaration will cause a compiler error if ALARM_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmTableSizeAssertion[ ( ( sizeof( ALARM_TABLE ) / sizeof( ALARM_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; // *** This declaration will cause a compiler error if ALARM_RANK_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmRankTableSizeAssertion[ ( ( sizeof( ALARM_RANK_TABLE ) / sizeof( ALARM_RANK_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; -/// A blank alarm data record for alarms that do not include alarm data when triggered. -const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; - -/// Pin SPI3-CS0 - re-purposed as output GPIO for backup alarm audio enable. -#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 -// Backup alarm audio enable/disable macros -#define SET_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 |= BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to enable backup alarm audio. +/// A blank alarm data record for alarms that do not include alarm data when triggered. +const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; + +/// Pin SPI3-CS0 - re-purposed as output GPIO for backup alarm audio enable. +#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 +// Backup alarm audio enable/disable macros +#define SET_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 |= BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to enable backup alarm audio. #define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. #define ALARM_AUDIO_TEST_TONE 4 ///< Alarm audio state for continuous test tone. @@ -82,7 +82,7 @@ U32 subRank; ///< Sub-rank of this alarm S32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered } ALARM_PRIORITY_RANKS_T; - + /// Enumeration of alarm audio self-test states. typedef enum Alarm_Audio_Self_Test_States { @@ -110,17 +110,17 @@ { 4, 2 } }; -// ********** private data ********** - -static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm +// ********** private data ********** + +static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm static BOOL alarmIsDetected[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm condition (detected or cleared) -static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< Table - when alarm became active for each alarm (if active) or zero (if inactive) +static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< Table - when alarm became active for each alarm (if active) or zero (if inactive) static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. -static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. +static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. static U32 audioTestStartTime; ///< Start time of audio alarm current self-test. static U32 alarmsBlockedTimer = 0; ///< Countdown timer used to temporarily block new alarms from being initiated static U32 lastUserAlarmActionReceivedTime = 0; ///< Time of last alarm action by user received from the UI (ms timestamp). - + /// Interval (in task intervals) at which to publish alarm status to CAN bus. static OVERRIDE_U32_T alarmStatusPublishInterval = { ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, 0 }; @@ -136,7 +136,7 @@ static OVERRIDE_F32_T alarmBackupAudioCurrent = { 0.0, 0.0, 0.0, 0 }; ///< Alarm backup audio current measured at ADC. -static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. +static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. static ALARM_PRIORITY_RANKS_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; ///< FIFO - first activated or highest sub-rank alarm in each alarm priority category. static BOOL alarmUserRecoveryActionEnabled[ NUMBER_OF_ALARM_USER_ACTIONS ]; ///< Alarm user recovery actions enabled flags. @@ -149,105 +149,105 @@ static BOOL resumeBlockedByAlarmProperty; ///< Flag indicates whether treatment resumption is currently blocked by alarm property. static BOOL alarmNoRetrigger; ///< Flag indicates whether some alarms should be prevented from re-triggering after being cleared by rinseback or end-tx options -// ********** private function prototypes ********** - -static void activateAlarm( ALARM_ID_T alarm ); +// ********** private function prototypes ********** -static void monitorAlarms( void ); -static void updateAlarmsState( void ); -static void setAlarmLamp( void ); +static void activateAlarm( ALARM_ID_T alarm ); + +static void monitorAlarms( void ); +static void updateAlarmsState( void ); +static void setAlarmLamp( void ); static void setAlarmAudio( void ); -static void updateAlarmsSilenceStatus( void ); -static void updateAlarmsFlags( void ); +static void updateAlarmsSilenceStatus( void ); +static void updateAlarmsFlags( void ); -static BOOL clearAllRecoverableAlarms( ALARM_USER_ACTION_T action ); -static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); - +static BOOL clearAllRecoverableAlarms( ALARM_USER_ACTION_T action ); +static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); + static U32 getAlarmStartTime( ALARM_ID_T alarmID ); static void publishAlarmInfo( void ); - -/*********************************************************************//** - * @brief - * The initAlarmMgmt function initializes the AlarmMgmt module. - * @details Inputs: none - * @details Outputs: AlarmMgmt module initialized. - * @return none - *************************************************************************/ -void initAlarmMgmt( void ) -{ - ALARM_PRIORITY_T p; + +/*********************************************************************//** + * @brief + * The initAlarmMgmt function initializes the AlarmMgmt module. + * @details Inputs: none + * @details Outputs: AlarmMgmt module initialized. + * @return none + *************************************************************************/ +void initAlarmMgmt( void ) +{ + ALARM_PRIORITY_T p; ALARM_ID_T a; ALARM_BUTTON_BLOCKER_T b; - - // Disable backup audio - CLR_BACKUP_AUDIO_ENABLE(); - - // Initialize alarm states and start time stamps - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { + + // Disable backup audio + CLR_BACKUP_AUDIO_ENABLE(); + + // Initialize alarm states and start time stamps + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { alarmIsActive[ a ] = FALSE; - alarmIsDetected[ a ] = FALSE;; - alarmStartedAt[ a ].data = 0; - alarmStartedAt[ a ].ovData = 0; - alarmStartedAt[ a ].ovInitData = 0; - alarmStartedAt[ a ].override = OVERRIDE_RESET; - } - // Initialize alarm FIFOs - for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) - { + alarmIsDetected[ a ] = FALSE;; + alarmStartedAt[ a ].data = 0; + alarmStartedAt[ a ].ovData = 0; + alarmStartedAt[ a ].ovInitData = 0; + alarmStartedAt[ a ].override = OVERRIDE_RESET; + } + // Initialize alarm FIFOs + for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) + { alarmPriorityFIFO[ p ].alarmID = ALARM_ID_NO_ALARM; alarmPriorityFIFO[ p ].subRank = LOWEST_ALARM_SUB_RANK; - alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; + alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; } // Initialize alarm button blocker flags for ( b = (ALARM_BUTTON_BLOCKER_T)0; b < NUM_OF_ALARM_BUTTON_BLOCKERS; b++ ) { alarmButtonBlockers[ b ] = FALSE; - } - // Initialize composite alarm state - alarmStatus.alarmsState = ALARM_PRIORITY_NONE; - alarmStatus.alarmsSilenced = FALSE; - alarmStatus.alarmsSilenceStart = 0; + } + // Initialize composite alarm state + alarmStatus.alarmsState = ALARM_PRIORITY_NONE; + alarmStatus.alarmsSilenced = FALSE; + alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmsEscalatesIn = 0; - alarmStatus.alarmsToEscalate = FALSE; + alarmStatus.alarmsToEscalate = FALSE; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; - alarmStatus.topAlarmConditionDetected = FALSE; - alarmStatus.systemFault = FALSE; + alarmStatus.topAlarmConditionDetected = FALSE; + alarmStatus.systemFault = FALSE; alarmStatus.stop = FALSE; - alarmStatus.lampOn = FALSE; - alarmStatus.noClear = FALSE; - alarmStatus.noResume = FALSE; - alarmStatus.noRinseback = FALSE; + alarmStatus.lampOn = FALSE; + alarmStatus.noClear = FALSE; + alarmStatus.noResume = FALSE; + alarmStatus.noRinseback = FALSE; alarmStatus.noEndTreatment = FALSE; alarmStatus.noBloodRecirc = FALSE; - alarmStatus.noDialRecirc = FALSE; + alarmStatus.noDialRecirc = FALSE; alarmStatus.ok = FALSE; alarmsBlockedTimer = 0; lastUserAlarmActionReceivedTime = 0; alarmAudioTestToneRequested = FALSE; resumeBlockedByAlarmProperty = FALSE; alarmNoRetrigger = FALSE; - alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; -} - -/*********************************************************************//** - * @brief - * The execAlarmMgmt function executes the alarm management functions to be - * done periodically. The composite alarm state is updated, alarm lamp and - * audio patterns are updated, and status is sent out to the rest of the system. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -void execAlarmMgmt( void ) + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; +} + +/*********************************************************************//** + * @brief + * The execAlarmMgmt function executes the alarm management functions to be + * done periodically. The composite alarm state is updated, alarm lamp and + * audio patterns are updated, and status is sent out to the rest of the system. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void execAlarmMgmt( void ) { monitorAlarms(); - updateAlarmsState(); - updateAlarmsFlags(); - updateAlarmsSilenceStatus(); + updateAlarmsState(); + updateAlarmsFlags(); + updateAlarmsSilenceStatus(); // Publish alarm status and information at interval publishAlarmInfo(); @@ -256,7 +256,7 @@ { alarmsBlockedTimer--; } -} +} /*********************************************************************//** * @brief @@ -271,9 +271,9 @@ // Verify valid alarm index if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { - // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm + // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm if ( ( FALSE == alarmIsActive[ alarm ] ) || - ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) + ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) { // If alarms are silenced and this new alarm is of higher or same priority, end silence due to new alarm if ( ( ALARM_TABLE[ alarm ].alarmPriority > ALARM_TABLE[ alarmStatus.alarmTop ].alarmPriority ) || @@ -286,18 +286,18 @@ if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) { alarmStatus.alarmTop = alarm; - } + } // If alarm stops, set that status immediately (don't wait for status update function) if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) { alarmStatus.stop = TRUE; } - // If alarm is a fault (and not in service mode), request transition to fault mode - if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) - { - requestNewOperationMode( MODE_FAUL ); - } - // Activate alarm + // If alarm is a fault (and not in service mode), request transition to fault mode + if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) + { + requestNewOperationMode( MODE_FAUL ); + } + // Activate alarm alarmIsActive[ alarm ] = TRUE; alarmStartedAt[ alarm ].data = getMSTimerCount(); alarmIsDetected[ alarm ] = TRUE; @@ -311,61 +311,61 @@ if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) { initiateAlarmAction( ALARM_ACTION_STOP ); - } - } - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) + } + } } -} - -/*********************************************************************//** - * @brief - * The activateAlarmNoData function activates a given alarm. Also, an alarm - * message is broadcast to the rest of the system. This function will - * include given data in the broadcast message for logging. - * @details Inputs: none - * @details Outputs: alarm triggered message sent, alarm activated - * @param alarm ID of alarm to activate - * @return none - *************************************************************************/ -void activateAlarmNoData( ALARM_ID_T alarm ) + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) + } +} + +/*********************************************************************//** + * @brief + * The activateAlarmNoData function activates a given alarm. Also, an alarm + * message is broadcast to the rest of the system. This function will + * include given data in the broadcast message for logging. + * @details Inputs: none + * @details Outputs: alarm triggered message sent, alarm activated + * @param alarm ID of alarm to activate + * @return none + *************************************************************************/ +void activateAlarmNoData( ALARM_ID_T alarm ) { - activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA, FALSE ); -} - -/*********************************************************************//** - * @brief - * The activateAlarm1Data function activates a given alarm. Also, an alarm - * message is broadcast to the rest of the system. This function will - * include given data in the broadcast message for logging. - * @details Inputs: none - * @details Outputs: alarm triggered message sent, alarm activated - * @param alarm ID of alarm to activate - * @param alarmData supporting data to include in alarm msg - * @return none - *************************************************************************/ -void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) -{ + activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA, FALSE ); +} + +/*********************************************************************//** + * @brief + * The activateAlarm1Data function activates a given alarm. Also, an alarm + * message is broadcast to the rest of the system. This function will + * include given data in the broadcast message for logging. + * @details Inputs: none + * @details Outputs: alarm triggered message sent, alarm activated + * @param alarm ID of alarm to activate + * @param alarmData supporting data to include in alarm msg + * @return none + *************************************************************************/ +void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) +{ activateAlarm2Data( alarm, alarmData, BLANK_ALARM_DATA, FALSE ); -} - -/*********************************************************************//** - * @brief - * The activateAlarm2Data function activates a given alarm. Also, an alarm - * message is broadcast to the rest of the system. This function will - * include two given data in the broadcast message for logging. - * @details Inputs: alarmsBlockedTimer, determines blocked alarm conditions - * @details Outputs: alarm triggered message sent, alarm activated - * @param alarm ID of alarm to activate - * @param alarmData1 supporting data to include in alarm msg +} + +/*********************************************************************//** + * @brief + * The activateAlarm2Data function activates a given alarm. Also, an alarm + * message is broadcast to the rest of the system. This function will + * include two given data in the broadcast message for logging. + * @details Inputs: alarmsBlockedTimer, determines blocked alarm conditions + * @details Outputs: alarm triggered message sent, alarm activated + * @param alarm ID of alarm to activate + * @param alarmData1 supporting data to include in alarm msg * @param alarmData2 supporting data to include in alarm msg - * @param outside flag indicates whether alarm is originating from outside HD f/w - * @return none - *************************************************************************/ -void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2, BOOL outside ) -{ + * @param outside flag indicates whether alarm is originating from outside HD f/w + * @return none + *************************************************************************/ +void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2, BOOL outside ) +{ // Block if new alarms are occur during loss of AC power if ( ( TRUE == getCPLDACPowerLossDetected() ) ) { @@ -418,7 +418,7 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) - } + } } /*********************************************************************//** @@ -448,42 +448,42 @@ } } -/*********************************************************************//** - * @brief - * The clearAlarm function clears a given alarm if it is recoverable. Also - * an alarm message is broadcast to the rest of the system. - * @details Inputs: none +/*********************************************************************//** + * @brief + * The clearAlarm function clears a given alarm if it is recoverable. Also + * an alarm message is broadcast to the rest of the system. + * @details Inputs: none * @details Outputs: AlarmStatusTable[], alarmIsActive[], alarmStartedAt[], - * alarmIsDetected[] - * @param alarm ID of alarm to clear - * @return none - *************************************************************************/ -void clearAlarm( ALARM_ID_T alarm ) -{ - // Verify given alarm - if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) - { - // Verify alarm can be cleared - if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) - { - // Clear alarm and broadcast alarm clear if not already cleared - if ( TRUE == alarmIsActive[ alarm ] ) + * alarmIsDetected[] + * @param alarm ID of alarm to clear + * @return none + *************************************************************************/ +void clearAlarm( ALARM_ID_T alarm ) +{ + // Verify given alarm + if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) + { + // Verify alarm can be cleared + if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) + { + // Clear alarm and broadcast alarm clear if not already cleared + if ( TRUE == alarmIsActive[ alarm ] ) { ALARM_ID_DATA_PUBLISH_T data; data.alarmID = (U32) alarm; - + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); alarmIsActive[ alarm ] = FALSE; clearAlarmCondition( alarm ); - alarmStartedAt[ alarm ].data = 0; - } - } - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, alarm ) - } + alarmStartedAt[ alarm ].data = 0; + } + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, alarm ) + } } /*********************************************************************//** @@ -508,8 +508,8 @@ BOOL getNoRetriggerFlag( void ) { return alarmNoRetrigger; -} - +} + /*********************************************************************//** * @brief * The setAlarmUserActionEnabled function enables/disables specific alarm @@ -680,17 +680,17 @@ lastUserAlarmActionReceivedTime = getMSTimerCount(); } -/*********************************************************************//** - * @brief - * The isAlarmActive function determines whether a given alarm is currently - * active. - * @details Inputs: alarmIsActive[] - * @details Outputs: none - * @param alarm ID of alarm to check - * @return TRUE if given alarm is active, FALSE if not - *************************************************************************/ -BOOL isAlarmActive( ALARM_ID_T alarm ) -{ +/*********************************************************************//** + * @brief + * The isAlarmActive function determines whether a given alarm is currently + * active. + * @details Inputs: alarmIsActive[] + * @details Outputs: none + * @param alarm ID of alarm to check + * @return TRUE if given alarm is active, FALSE if not + *************************************************************************/ +BOOL isAlarmActive( ALARM_ID_T alarm ) +{ BOOL result = FALSE; if ( alarm < NUM_OF_ALARM_IDS ) @@ -700,9 +700,9 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_ALARM_ID_REFERENCED, (U32)alarm ); - } - - return result; + } + + return result; } /*********************************************************************//** @@ -831,7 +831,7 @@ ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ) { return alarmStatus.alarmsState; -} +} /*********************************************************************//** * @brief @@ -864,7 +864,6 @@ if ( ( volumeLevel > 0 ) && ( volumeLevel <= MAX_ALARM_VOLUME_LEVEL ) ) { - sendTreatmentLogEventData( ALARM_AUDIO_VOLUME_CHANGED_EVENT, (F32)volumeLevel, (F32)getAlarmAudioVolume() ); // Convert volume level to attenuation level alarmAudioVolumeLevel.data = MAX_ALARM_VOLUME_LEVEL - volumeLevel; accepted = TRUE; @@ -951,15 +950,15 @@ } } } - -/*********************************************************************//** - * @brief - * The getAlarmStartTime function gets the active state of a given alarm. - * @details Inputs: alarmStartedAt[] - * @details Outputs: none - * @param alarmID ID of alarm to check - * @return The start time stamp of given alarm ID - *************************************************************************/ + +/*********************************************************************//** + * @brief + * The getAlarmStartTime function gets the active state of a given alarm. + * @details Inputs: alarmStartedAt[] + * @details Outputs: none + * @param alarmID ID of alarm to check + * @return The start time stamp of given alarm ID + *************************************************************************/ static U32 getAlarmStartTime( ALARM_ID_T alarmID ) { U32 result = 0; @@ -1009,34 +1008,34 @@ // TODO - Check current vs. expected audio output } - -/*********************************************************************//** - * @brief - * The updateAlarmsState function updates the alarms state and alarm to - * display. - * @details Inputs: alarmStatusTable[] - * @details Outputs: alarmPriorityFIFO[], alarmStatus - * @return none - *************************************************************************/ -static void updateAlarmsState( void ) -{ - ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE, p; - ALARM_ID_T a; + +/*********************************************************************//** + * @brief + * The updateAlarmsState function updates the alarms state and alarm to + * display. + * @details Inputs: alarmStatusTable[] + * @details Outputs: alarmPriorityFIFO[], alarmStatus + * @return none + *************************************************************************/ +static void updateAlarmsState( void ) +{ + ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE, p; + ALARM_ID_T a; BOOL faultsActive = FALSE; - BOOL dialysateRecircBlocked = FALSE; + BOOL dialysateRecircBlocked = FALSE; BOOL bloodRecircBlocked = FALSE; // Reset priority FIFOs so we can re-determine them below for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { resetAlarmPriorityFIFO( p ); } - - // Update FIFOs and sub-ranks per active alarms table - for alarm ranking purposes to determine "top" alarm - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { - if ( TRUE == alarmIsActive[ a ] ) - { + + // Update FIFOs and sub-ranks per active alarms table - for alarm ranking purposes to determine "top" alarm + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == alarmIsActive[ a ] ) + { ALARM_PRIORITY_T almPriority = ALARM_TABLE[ a ].alarmPriority; U32 subRank = ALARM_TABLE[ a ].alarmSubRank; U32 msSinceTriggered = calcTimeSince( getAlarmStartTime( a ) ); @@ -1062,81 +1061,81 @@ alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = (S32)msSinceTriggered; } } - // Track highest priority alarm found so far of all priority categories + // Track highest priority alarm found so far of all priority categories highestPriority = MAX( almPriority, highestPriority ); - // Track whether any active faults have been found so far - if ( TRUE == ALARM_TABLE[ a ].alarmIsFault ) - { - faultsActive = TRUE; + // Track whether any active faults have been found so far + if ( TRUE == ALARM_TABLE[ a ].alarmIsFault ) + { + faultsActive = TRUE; } // Track whether any active alarms prevent dialysate re-circulation so far if ( TRUE == ALARM_TABLE[ a ].alarmNoDialysateRecirc ) { dialysateRecircBlocked = TRUE; - } + } // Track whether any active alarms prevent blood re-circulation so far if ( TRUE == ALARM_TABLE[ a ].alarmNoBloodRecirc ) { bloodRecircBlocked = TRUE; } - } - } - - // Update alarm to display per highest priority FIFO - alarmStatus.alarmsState = highestPriority; + } + } + + // Update alarm to display per highest priority FIFO + alarmStatus.alarmsState = highestPriority; alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; - alarmStatus.topAlarmConditionDetected = alarmIsDetected[ alarmStatus.alarmTop ]; + alarmStatus.topAlarmConditionDetected = alarmIsDetected[ alarmStatus.alarmTop ]; alarmStatus.systemFault = faultsActive; alarmStatus.noBloodRecirc = bloodRecircBlocked; - alarmStatus.noDialRecirc = dialysateRecircBlocked; -} - -/*********************************************************************//** - * @brief + alarmStatus.noDialRecirc = dialysateRecircBlocked; +} + +/*********************************************************************//** + * @brief * The setAlarmLamp function sets the alarm lamp pattern according to the - * current state of alarms. - * @details Inputs: none - * @details Outputs: Alarm lamp patter set according to current alarms status. - * @return none - *************************************************************************/ -static void setAlarmLamp( void ) + * current state of alarms. + * @details Inputs: none + * @details Outputs: Alarm lamp patter set according to current alarms status. + * @return none + *************************************************************************/ +static void setAlarmLamp( void ) { - // Set alarm lamp pattern to appropriate pattern for current alarm state - if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) - { - switch ( alarmStatus.alarmsState ) - { - case ALARM_PRIORITY_NONE: - requestAlarmLampPattern( LAMP_PATTERN_OK ); - break; - - case ALARM_PRIORITY_LOW: - requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); - break; - - case ALARM_PRIORITY_MEDIUM: - requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); - break; - - case ALARM_PRIORITY_HIGH: - if ( TRUE == ALARM_TABLE[ alarmStatus.alarmTop ].alarmIsFault ) - { - requestAlarmLampPattern( LAMP_PATTERN_FAULT ); - } - else - { - requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); - } - break; - - default: - requestAlarmLampPattern( LAMP_PATTERN_FAULT ); - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - break; + // Set alarm lamp pattern to appropriate pattern for current alarm state + if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) + { + switch ( alarmStatus.alarmsState ) + { + case ALARM_PRIORITY_NONE: + requestAlarmLampPattern( LAMP_PATTERN_OK ); + break; + + case ALARM_PRIORITY_LOW: + requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); + break; + + case ALARM_PRIORITY_MEDIUM: + requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); + break; + + case ALARM_PRIORITY_HIGH: + if ( TRUE == ALARM_TABLE[ alarmStatus.alarmTop ].alarmIsFault ) + { + requestAlarmLampPattern( LAMP_PATTERN_FAULT ); + } + else + { + requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); + } + break; + + default: + requestAlarmLampPattern( LAMP_PATTERN_FAULT ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) + break; } } - // Execute alarm lamp controller + // Execute alarm lamp controller execAlarmLamp(); // Set lamp on flag to match current state of alarm lamp @@ -1147,9 +1146,9 @@ else { alarmStatus.lampOn = FALSE; - } -} - + } +} + /*********************************************************************//** * @brief * The setAlarmAudio function sets the alarm audio pattern according to @@ -1206,64 +1205,64 @@ } } -/*********************************************************************//** - * @brief - * The updateAlarmsSilenceStatus function updates the alarms silence state. - * @details Inputs: alarmStatus - * @details Outputs: alarmStatus - * @return none - *************************************************************************/ -static void updateAlarmsSilenceStatus( void ) -{ - // If alarms not silenced, reset alarms silence related properties - if ( TRUE != alarmStatus.alarmsSilenced ) - { - alarmStatus.alarmsSilenceExpiresIn = 0; - alarmStatus.alarmsSilenceStart = 0; - } - else - { - U32 timeSinceAlarmSilenceStart = calcTimeSince( alarmStatus.alarmsSilenceStart ) / MS_PER_SECOND; - - if ( timeSinceAlarmSilenceStart >= ALARM_SILENCE_EXPIRES_IN_SECS ) - { - alarmStatus.alarmsSilenceExpiresIn = 0; - } - else - { - alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; - } - // If alarms silence expires, end it - if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) - { - alarmStatus.alarmsSilenced = FALSE; - } - } -} +/*********************************************************************//** + * @brief + * The updateAlarmsSilenceStatus function updates the alarms silence state. + * @details Inputs: alarmStatus + * @details Outputs: alarmStatus + * @return none + *************************************************************************/ +static void updateAlarmsSilenceStatus( void ) +{ + // If alarms not silenced, reset alarms silence related properties + if ( TRUE != alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenceExpiresIn = 0; + alarmStatus.alarmsSilenceStart = 0; + } + else + { + U32 timeSinceAlarmSilenceStart = calcTimeSince( alarmStatus.alarmsSilenceStart ) / MS_PER_SECOND; -/*********************************************************************//** - * @brief - * The updateAlarmsFlags function updates the alarms flags of the alarms - * status record. - * @details Inputs: alarmStatus, alarmIsActive, ALARM_TABLE, alarmButtonBlockers - * @details Outputs: alarmStatus, alarmUserRecoveryActionEnabled, - * @return none - *************************************************************************/ -static void updateAlarmsFlags( void ) -{ - BOOL systemFault = FALSE; - BOOL stop = FALSE; - BOOL noClear = FALSE; + if ( timeSinceAlarmSilenceStart >= ALARM_SILENCE_EXPIRES_IN_SECS ) + { + alarmStatus.alarmsSilenceExpiresIn = 0; + } + else + { + alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; + } + // If alarms silence expires, end it + if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) + { + alarmStatus.alarmsSilenced = FALSE; + } + } +} + +/*********************************************************************//** + * @brief + * The updateAlarmsFlags function updates the alarms flags of the alarms + * status record. + * @details Inputs: alarmStatus, alarmIsActive, ALARM_TABLE, alarmButtonBlockers + * @details Outputs: alarmStatus, alarmUserRecoveryActionEnabled, + * @return none + *************************************************************************/ +static void updateAlarmsFlags( void ) +{ + BOOL systemFault = FALSE; + BOOL stop = FALSE; + BOOL noClear = FALSE; BOOL noResume = FALSE; - BOOL noResumePerAlarmPropertyOnly = alarmNoRetrigger; // cannot resume if no re-trigger flag is set - BOOL noRinseback = FALSE; + BOOL noResumePerAlarmPropertyOnly = alarmNoRetrigger; // cannot resume if no re-trigger flag is set + BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; - BOOL endTxOnlyAlarmActive = FALSE; + BOOL endTxOnlyAlarmActive = FALSE; BOOL usrAckReq = FALSE; BOOL noMinimize = TRUE; HD_OP_MODE_T currentMode = getCurrentOperationMode(); - ALARM_ID_T a; - + ALARM_ID_T a; + // Set user alarm recovery actions allowed by state flags alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RESUME ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ? FALSE : TRUE ); alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ? FALSE : TRUE ); @@ -1273,38 +1272,38 @@ alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] = FALSE; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] = FALSE; - // Determine alarm flags - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { - if ( TRUE == alarmIsActive[ a ] ) - { - systemFault = ( TRUE == ALARM_TABLE[ a ].alarmIsFault ? TRUE : systemFault ); - stop = ( TRUE == ALARM_TABLE[ a ].alarmStops ? TRUE : stop ); + // Determine alarm flags + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == alarmIsActive[ a ] ) + { + systemFault = ( TRUE == ALARM_TABLE[ a ].alarmIsFault ? TRUE : systemFault ); + stop = ( TRUE == ALARM_TABLE[ a ].alarmStops ? TRUE : stop ); noClear = ( TRUE == ALARM_TABLE[ a ].alarmNoClear ? TRUE : noClear ); noResumePerAlarmPropertyOnly = ( ALARM_TABLE[ a ].alarmNoResume ? TRUE : noResumePerAlarmPropertyOnly ); // Set user alarm recovery actions allowed flags alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] |= ALARM_TABLE[ a ].alarmNoResume; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] |= ALARM_TABLE[ a ].alarmNoRinseback; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] |= ALARM_TABLE[ a ].alarmNoEndTreatment; if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ) - { + { noResume = ( TRUE == ALARM_TABLE[ a ].alarmNoResume ? TRUE : noResume ); } else { noResume = TRUE; - } + } if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ) { noRinseback = ( TRUE == ALARM_TABLE[ a ].alarmNoRinseback ? TRUE : noRinseback ); } else { noRinseback = TRUE; - } + } if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_END_TREATMENT ] ) { - noEndTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoEndTreatment ? TRUE : noEndTreatment ); + noEndTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoEndTreatment ? TRUE : noEndTreatment ); } else { @@ -1317,7 +1316,7 @@ { endTxOnlyAlarmActive = TRUE; } - } // If alarm active + } // If alarm active } // Alarm table loop // If top alarm condition not cleared, block resume @@ -1360,17 +1359,17 @@ noMinimize = FALSE; } - // Set updated alarm flags - alarmStatus.systemFault = systemFault; - alarmStatus.stop = stop; - alarmStatus.noClear = noClear; - alarmStatus.noResume = noResume; - alarmStatus.noRinseback = noRinseback; - alarmStatus.noEndTreatment = noEndTreatment; - alarmStatus.ok = usrAckReq; + // Set updated alarm flags + alarmStatus.systemFault = systemFault; + alarmStatus.stop = stop; + alarmStatus.noClear = noClear; + alarmStatus.noResume = noResume; + alarmStatus.noRinseback = noRinseback; + alarmStatus.noEndTreatment = noEndTreatment; + alarmStatus.ok = usrAckReq; alarmStatus.noMinimize = noMinimize; alarmStatus.noReTrigger = alarmNoRetrigger; - resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; + resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; } /*********************************************************************//** @@ -1441,31 +1440,31 @@ } return result; -} - -/*********************************************************************//** - * @brief - * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm - * priority. - * @details Inputs: none - * @details Outputs: alarmPriorityFIFO[] - * @param priority priority of FIFO to reset - * @return none - *************************************************************************/ -static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) -{ - // Verify priority - if ( priority < NUM_OF_ALARM_PRIORITIES ) - { +} + +/*********************************************************************//** + * @brief + * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm + * priority. + * @details Inputs: none + * @details Outputs: alarmPriorityFIFO[] + * @param priority priority of FIFO to reset + * @return none + *************************************************************************/ +static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) +{ + // Verify priority + if ( priority < NUM_OF_ALARM_PRIORITIES ) + { alarmPriorityFIFO[ priority ].alarmID = ALARM_ID_NO_ALARM; alarmPriorityFIFO[ priority ].subRank = LOWEST_ALARM_SUB_RANK; - alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = -1; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) - } -} + alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = -1; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) + } +} /*********************************************************************//** * @brief @@ -1683,132 +1682,132 @@ { alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; } - - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testSetAlarmStateOverride function overrides the state of the - * alarm active state for a given alarm with the alarm management with - * a given active state. - * @details Inputs: none - * @details Outputs: alarm activated or cleared - * @param alarmID ID of alarm to activate or clear - * @param value override state for the given alarm ID (1=activate, 0=clear) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetAlarmStateOverride( U32 alarmID, U32 state ) -{ - BOOL result = FALSE; - - if ( alarmID < NUM_OF_ALARM_IDS ) - { + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetAlarmStateOverride function overrides the state of the + * alarm active state for a given alarm with the alarm management with + * a given active state. + * @details Inputs: none + * @details Outputs: alarm activated or cleared + * @param alarmID ID of alarm to activate or clear + * @param value override state for the given alarm ID (1=activate, 0=clear) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmStateOverride( U32 alarmID, U32 state ) +{ + BOOL result = FALSE; + + if ( alarmID < NUM_OF_ALARM_IDS ) + { // Verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - if ( TRUE == state ) - { - activateAlarmNoData( (ALARM_ID_T)alarmID ); - } - else - { - clearAlarm( (ALARM_ID_T)alarmID ); - } - result = TRUE; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetAlarmStateOverride function resets the override of the - * state of the active state for a given alarm with the alarm management. - * @details Inputs: none - * @details Outputs: alarm cleared - * @param alarmID ID of alarm to clear - * @return TRUE if alarm clear successful, FALSE if not - *************************************************************************/ -BOOL testResetAlarmStateOverride( U32 alarmID ) -{ - BOOL result = FALSE; - - if ( alarmID < NUM_OF_ALARM_IDS ) - { + if ( TRUE == isTestingActivated() ) + { + if ( TRUE == state ) + { + activateAlarmNoData( (ALARM_ID_T)alarmID ); + } + else + { + clearAlarm( (ALARM_ID_T)alarmID ); + } + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmStateOverride function resets the override of the + * state of the active state for a given alarm with the alarm management. + * @details Inputs: none + * @details Outputs: alarm cleared + * @param alarmID ID of alarm to clear + * @return TRUE if alarm clear successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmStateOverride( U32 alarmID ) +{ + BOOL result = FALSE; + + if ( alarmID < NUM_OF_ALARM_IDS ) + { // Verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - clearAlarm( (ALARM_ID_T)alarmID ); - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetAlarmStartOverride function overrides the start time - * for a given alarm with the alarm management with a given start time. - * @details Inputs: none - * @details Outputs: alarmStartedAt[] - * @param alarmID ID of alarm to override start time for - * @param value override time since start (in ms) for the given alarm ID - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ) -{ - BOOL result = FALSE; - - if ( alarmID < NUM_OF_ALARM_IDS ) - { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + clearAlarm( (ALARM_ID_T)alarmID ); + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmStartOverride function overrides the start time + * for a given alarm with the alarm management with a given start time. + * @details Inputs: none + * @details Outputs: alarmStartedAt[] + * @param alarmID ID of alarm to override start time for + * @param value override time since start (in ms) for the given alarm ID + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ) +{ + BOOL result = FALSE; + + if ( alarmID < NUM_OF_ALARM_IDS ) + { // Verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - U32 tim = getMSTimerCount(); - - if ( tim > value ) - { - result = TRUE; - alarmStartedAt[ alarmID ].ovData = ( tim - value ); - alarmStartedAt[ alarmID ].override = OVERRIDE_KEY; - } - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetAlarmStartOverride function resets the override of the - * start time for a given alarm with the alarm management. - * @details Inputs: none - * @details Outputs: alarmStartedAt[] - * @param alarmID ID of alarm to reset override of start time for - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetAlarmStartOverride( U32 alarmID ) -{ - BOOL result = FALSE; - - if ( alarmID < NUM_OF_ALARM_IDS ) - { + if ( TRUE == isTestingActivated() ) + { + U32 tim = getMSTimerCount(); + + if ( tim > value ) + { + result = TRUE; + alarmStartedAt[ alarmID ].ovData = ( tim - value ); + alarmStartedAt[ alarmID ].override = OVERRIDE_KEY; + } + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmStartOverride function resets the override of the + * start time for a given alarm with the alarm management. + * @details Inputs: none + * @details Outputs: alarmStartedAt[] + * @param alarmID ID of alarm to reset override of start time for + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmStartOverride( U32 alarmID ) +{ + BOOL result = FALSE; + + if ( alarmID < NUM_OF_ALARM_IDS ) + { // Verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - alarmStartedAt[ alarmID ].override = OVERRIDE_RESET; - alarmStartedAt[ alarmID ].ovData = alarmStartedAt[ alarmID ].ovInitData; - } - } - - return result; + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmStartedAt[ alarmID ].override = OVERRIDE_RESET; + alarmStartedAt[ alarmID ].ovData = alarmStartedAt[ alarmID ].ovInitData; + } + } + + return result; } /*********************************************************************//** @@ -2135,6 +2134,6 @@ } return result; -} +} /**@}*/ Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rdb291cc22fd8f10e6e47cad468e14ed5590a94f2 -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision db291cc22fd8f10e6e47cad468e14ed5590a94f2) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -14,87 +14,87 @@ * @date (original) 20-May-2021 * ***************************************************************************/ - -#ifndef __ALARM_MGMT_SW_FAULTS_H__ -#define __ALARM_MGMT_SW_FAULTS_H__ - -/** - * @addtogroup AlarmManagement - * @{ - */ - -// ********** public definitions ********** - -/// Listing of specific software faults for logging purposes. -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_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, - SW_FAULT_ID_FPGA_INVALID_ALARM_AUDIO_PARAM, - 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_PRES_OCCL_INVALID_STATE, - SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_SIGNAL_ACTION, - SW_FAULT_ID_ALARM_MGMT_INVALID_USER_ACTION, - SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL, // 50 - SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, - SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL, - SW_FAULT_ID_MODE_TREATMENT_INVALID_ALARM_ACTION, - SW_FAULT_ID_MODE_PRE_TREATMENT_RESERVOIR_MGMT_INVALID_STATE, - SW_FAULT_ID_DIALYSIS_INVALID_STATE, // 55 - SW_FAULT_ID_DIALYSIS_INVALID_UF_STATE, - SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE, - SW_FAULT_ID_MODE_TREATMENT_INVALID_STATE, - SW_FAULT_ID_INTERRUPTS_INVALID_EDGE_DETECTED, // 60 - SW_FAULT_ID_INVALID_DG_PRESSURE_ID, + +#ifndef __ALARM_MGMT_SW_FAULTS_H__ +#define __ALARM_MGMT_SW_FAULTS_H__ + +/** + * @addtogroup AlarmManagement + * @{ + */ + +// ********** public definitions ********** + +/// Listing of specific software faults for logging purposes. +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_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, + SW_FAULT_ID_FPGA_INVALID_ALARM_AUDIO_PARAM, + 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_PRES_OCCL_INVALID_STATE, + SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_SIGNAL_ACTION, + SW_FAULT_ID_ALARM_MGMT_INVALID_USER_ACTION, + SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL, // 50 + SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, + SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL, + SW_FAULT_ID_MODE_TREATMENT_INVALID_ALARM_ACTION, + SW_FAULT_ID_MODE_PRE_TREATMENT_RESERVOIR_MGMT_INVALID_STATE, + SW_FAULT_ID_DIALYSIS_INVALID_STATE, // 55 + SW_FAULT_ID_DIALYSIS_INVALID_UF_STATE, + SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE, + SW_FAULT_ID_MODE_TREATMENT_INVALID_STATE, + SW_FAULT_ID_INTERRUPTS_INVALID_EDGE_DETECTED, // 60 + SW_FAULT_ID_INVALID_DG_PRESSURE_ID, SW_FAULT_ID_CAN_PARITY_ERROR, SW_FAULT_ID_CAN_PASSIVE_WARNING, SW_FAULT_ID_CAN_OFF_ERROR, - SW_FAULT_ID_____AVAILABLE_2, // 65 - SW_FAULT_ID_____AVAILABLE_3, + SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_U32_PARAM_MIN_LIMIT, // 65 + SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_U32_PARAM_MAX_LIMIT, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR, SW_FAULT_ID_ACCEL_INVALID_STATE, SW_FAULT_ID_ACCEL_GET_INVALID_AXIS, @@ -187,9 +187,11 @@ SW_FAULT_ID_PRES_LIMITS_INVALID_STATE, SW_FAULT_ID_BLOOD_LEAK_EMBEDDED_MODE_INVALID_STATE, SW_FAULT_ID_BATTERY_INVALID_MANAGEMENT_DATA_STATE, - NUM_OF_SW_FAULT_IDS -} SW_FAULT_ID_T; - + SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_F32_PARAM_MIN_LIMIT, + SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_F32_PARAM_MAX_LIMIT, // 160 + NUM_OF_SW_FAULT_IDS +} SW_FAULT_ID_T; + /**@}*/ -#endif +#endif Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r0563950b76967db544ca2d17fe2b1008ca13b41b -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 0563950b76967db544ca2d17fe2b1008ca13b41b) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -1209,6 +1209,10 @@ handleReceiveROPermeateSampleReadyToDispenseFromDG( message ); break; + case MSG_ID_UI_INSTITUTIONAL_RECORD_REQUEST: + sendInstitutionalRecordToUI( message ); + break; + // NOTE: this always must be the last case case MSG_ID_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); @@ -1820,6 +1824,14 @@ handleTestHDRecirulationPctOverrideRequest( message ); break; + case MSG_ID_HD_GET_INSTITUTIONAL_RECORD: + handleGetHDInstitutionalRecord( message ); + break; + + case MSG_ID_HD_SET_INSTITUTIONAL_RECORD: + handleSetHDInstitutionalRecord( message ); + break; + // The default cannot be reached in VectorCAST since the cases are run in a for loop default: // Unrecognized message ID received - ignore Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r0563950b76967db544ca2d17fe2b1008ca13b41b -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 0563950b76967db544ca2d17fe2b1008ca13b41b) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -1987,7 +1987,7 @@ * @brief * The sendHDServiceRecord function sends out the HD service record. * @details Inputs: none - * @details Outputs: HD system record msg constructed and queued + * @details Outputs: HD service record msg constructed and queued * @param msgCurrNum: current payload number * @param msgTotalNum: total number of payloads * @param length: buffer length to be written @@ -3593,7 +3593,41 @@ } } +/*********************************************************************//** + * @brief + * The sendInstitutionalRecordToUI function sends the institutional record to UI + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void sendInstitutionalRecordToUI( MESSAGE_T* message ) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 accept = 1; + U32 reson = 0; + HD_INSTITUTIONAL_RECORD_T hdInstitutionalRecord; + + getNVRecord2Driver( GET_INSTITUTIONAL_RECORD, (U08*)&hdInstitutionalRecord, sizeof( HD_INSTITUTIONAL_RECORD_T ), 0, ALARM_ID_NO_ALARM ); + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_INSTITUTIONAL_RECORD_RESPONSE; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( HD_INSTITUTIONAL_RECORD_T ) - sizeof( U32 ) - sizeof( U16 ); + + memcpy( payloadPtr, &accept, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &reson, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + memcpy( payloadPtr, &hdInstitutionalRecord, sizeof( HD_INSTITUTIONAL_RECORD_T ) - sizeof( U32 ) - sizeof( U16 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_NOT_REQUIRED ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -5219,25 +5253,25 @@ *************************************************************************/ void handleSetRawAirTrapLevelSensorOverrideRequest( MESSAGE_T *message ) { - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; - BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; - // Verify payload length - if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) - { - memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); - if ( FALSE == payload.reset ) - { - result = testSetRawAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index, (AIR_TRAP_LEVELS_T)( payload.state.u32 ) ); - } - else - { - result = testResetRawAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index ); - } - } + // Verify payload length + if ( sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_ARRAY_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetRawAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index, (AIR_TRAP_LEVELS_T)( payload.state.u32 ) ); + } + else + { + result = testResetRawAirTrapLevelOverride( (AIR_TRAP_LEVEL_SENSORS_T)payload.index ); + } + } - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } /*********************************************************************//** @@ -8561,4 +8595,106 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** +* @brief +* The handleGetHDInstitutionalRecord function handles a request to get the HD +* institutional record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleGetHDInstitutionalRecord( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + // Tester must be logged in + if ( TRUE == isTestingActivated() ) + { + result = sendRecordToDialin( NVDATAMGMT_INTITUTIONAL_RECORD ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The sendHDInstitutionalRecord function sends out the HD institutional record. + * @details Inputs: none + * @details Outputs: HD institutional record msg constructed and queued + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param srvcRcrdAddress: start address of the institutional record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendHDInstitutionalRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_SEND_INSTITUTIONAL_RECORD; + msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + + memcpy( payloadPtr, &payloadCurrNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &payloadTotalNum, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, &length, sizeof( U32 ) ); + payloadPtr += sizeof( U32 ); + + memcpy( payloadPtr, srvcRcrdAddress, length ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_PC, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** +* @brief +* The handleSetHDInstitutionalRecord function handles a request to set the HD +* institutional data record. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetHDInstitutionalRecord( MESSAGE_T *message ) +{ + BOOL status = FALSE; + U08* payloadPtr = message->payload; + U32 currentMessage; + U32 totalMessages; + U32 payloadLength; + + if ( ( message->hdr.payloadLen >= ( sizeof(currentMessage) + sizeof(totalMessages) + sizeof(payloadLength) ) ) && + ( MODE_SERV == getCurrentOperationMode() ) ) + { + memcpy(¤tMessage, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&totalMessages, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + memcpy(&payloadLength, payloadPtr, sizeof(U32)); + payloadPtr += sizeof(U32); + + status = receiveRecordFromDialin( NVDATAMGMT_INTITUTIONAL_RECORD, currentMessage, totalMessages, payloadLength, payloadPtr ); + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r0563950b76967db544ca2d17fe2b1008ca13b41b -r747c714d2b4f80b598a66326d62a179aeefda390 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 0563950b76967db544ca2d17fe2b1008ca13b41b) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 747c714d2b4f80b598a66326d62a179aeefda390) @@ -558,6 +558,9 @@ // MSG_ID_DG_SEND_RO_PERMEATE_SAMPLE_DISPENSE_READY_TO_HD void handleReceiveROPermeateSampleReadyToDispenseFromDG( MESSAGE_T* message ); +// MSG_ID_UI_INSTITUTIONAL_RECORD_REQUEST +void sendInstitutionalRecordToUI( MESSAGE_T* message ); + // *********** public test support message functions ********** // MSG_TESTER_LOG_IN @@ -1009,6 +1012,15 @@ // MSG_ID_HD_RECIRULATION_PCT_OVERRIDE void handleTestHDRecirulationPctOverrideRequest( MESSAGE_T* message ); +// MSG_ID_HD_GET_INSTITUTIONAL_RECORD +void handleGetHDInstitutionalRecord( MESSAGE_T *message ); + +// MSG_ID_HD_SEND_INSTITUTIONAL_RECORD +BOOL sendHDInstitutionalRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* srvcRcrdAddress ); + +// MSG_ID_HD_SET_INSTITUTIONAL_RECORD +void handleSetHDInstitutionalRecord( MESSAGE_T *message ); + /**@}*/ #endif