Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r8684ff2cbf3f43cd0c7bcc5f25aaf6d5766c9d4c -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 8684ff2cbf3f43cd0c7bcc5f25aaf6d5766c9d4c) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -46,8 +46,8 @@ #define MAX_BLOOD_PUMP_PWM_STEP_UP_CHANGE 0.008 ///< Max duty cycle change when ramping up ~ 100 mL/min/s. #define MAX_BLOOD_PUMP_PWM_STEP_DN_CHANGE 0.016 ///< Max duty cycle change when ramping down ~ 200 mL/min/s. -#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.88 ///< Controller will error if PWM duty cycle > 90%, so set max to 88% -#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.12 ///< Controller will error if PWM duty cycle < 10%, so set min to 12% +#define MAX_BLOOD_PUMP_PWM_DUTY_CYCLE 0.89 ///< Controller will error if PWM duty cycle > 90%, so set max to 89% +#define MIN_BLOOD_PUMP_PWM_DUTY_CYCLE 0.10 ///< Controller will error if PWM duty cycle < 10%, so set min to 10% /// Interval (ms/task time) at which the blood pump is controlled. static const U32 BP_CONTROL_INTERVAL = ( 10000 / TASK_GENERAL_INTERVAL ); @@ -82,14 +82,19 @@ #define BP_MAX_CURR_WHEN_STOPPED_MA 150.0 ///< Motor controller current should not exceed this when pump should be stopped #define BP_MAX_CURR_WHEN_RUNNING_MA 2000.0 ///< Motor controller current should not exceed this when pump should be running #define BP_MAX_CURR_ERROR_DURATION_MS 2000 ///< Motor controller current errors persisting beyond this duration will trigger an alarm - -#define BP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< Conversion factor from ADC counts to RPM for blood pump motor + +#ifndef V2_0_SYSTEM + #define BP_SPEED_ADC_TO_RPM_FACTOR 1.751752 ///< Conversion factor from ADC counts to RPM for blood pump motor + #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00025 ///< ~40 BP motor RPM = 1% PWM duty cycle +#else + #define BP_SPEED_ADC_TO_RPM_FACTOR 1.280938 ///< Conversion factor from ADC counts to RPM for blood pump motor + #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.0003125 ///< ~32 BP motor RPM = 1% PWM duty cycle +#endif #define BP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< Conversion factor from ADC counts to mA for blood pump motor #define BP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter #define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( BP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to motor RPM. #define BP_GEAR_RATIO 32.0 ///< Blood pump motor to blood pump gear ratio -#define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.00028 ///< ~28 BP motor RPM = 1% PWM duty cycle #define BP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed /// Conversion factor from mL/min to estimated PWM duty cycle %. #define BP_PWM_FROM_ML_PER_MIN(rate) ( (rate) * BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR * BP_GEAR_RATIO * BP_MOTOR_RPM_TO_PWM_DC_FACTOR + BP_PWM_ZERO_OFFSET ) @@ -105,27 +110,39 @@ #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) #define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). +/// Blood flow read timeout alarm persistence. +#define BLOOD_FLOW_READ_TIMEOUT_PERSIST ( 2 * MS_PER_SECOND ) + #define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x7 ///< Blood flow meter NVM parameter status. /// Enumeration of blood pump controller states. typedef enum BloodPump_States { - BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state. - BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state. - BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state. - BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state. - NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states. + BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state + BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state + BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state + BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state + NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states } BLOOD_PUMP_STATE_T; /// Enumeration of blood pump self-test states. typedef enum BloodFlow_Self_Test_States { - BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state. - BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state. - BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state. - NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states. + BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state + BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state + BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state + NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states } BLOOD_FLOW_SELF_TEST_STATE_T; +/// Enumeration of blood flow read counters. +typedef enum BloodFlow_Read_Counters +{ + BLOOD_FLOW_READ_CTR_FAST_PACKET = 0, ///< Blood flow fast packet read counter + BLOOD_FLOW_READ_CTR_SLOW_PACKET, ///< Blood flow slow packet read counter + BLOOD_FLOW_READ_CTR_STATUS_PACKET, ///< Blood flow status packet read counter + NUM_OF_BLOOD_FLOW_READ_COUNTERS ///< Number of blood pump read counters. +} BLOOD_FLOW_READ_COUNTER_T; + // Pin assignments for pump stop and direction outputs #define STOP_CAN3_PORT_MASK 0x00000002 // (Tx - re-purposed as output GPIO for blood pump stop signal) #define DIR_CAN3_PORT_MASK 0x00000002 // (Rx - re-purposed as output GPIO for blood pump direction signal) @@ -176,6 +193,12 @@ static F32 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer +static U32 bpCurrErrorDurationCtr = 0; ///< Used for tracking persistence of bp current errors + +static U08 lastBloodFlowFastPacketReadCtr = 0; ///< Previous read counter for the blood flow fast packets +static U08 lastBloodFlowSlowPacketReadCtr = 0; ///< Previous read counter for the blood flow slow packets +static U08 lastBloodFlowStatusPacketReadCtr = 0; ///< Previous read counter for the blood flow status packets + // ********** private function prototypes ********** static BLOOD_PUMP_STATE_T handleBloodPumpOffState( void ); @@ -228,6 +251,7 @@ MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); // Initialize persistent alarm for flow sensor + initPersistentAlarm( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_READ_TIMEOUT_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, 0, BP_FLOW_VS_SPEED_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_OFF_CHECK, 0, BP_OFF_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, 0, BP_MOTOR_SPEED_ERROR_PERSIST ); @@ -423,13 +447,37 @@ HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); - #ifndef V1_5_SYSTEM F32 bpFlow = ( getFPGABloodFlow() * bloodFlowCalGain ) + bloodFlowCalOffset; #else - F32 bpFlow = ( ( getFPGABloodFlow() * -1.0 ) * bloodFlowCalGain ) + bloodFlowCalOffset; // Blood flow sensor installed backwards on HD + F32 bpFlow = ( ( getFPGABloodFlow() * -1.0 ) * bloodFlowCalGain ) + bloodFlowCalOffset; // Blood flow sensor installed backwards on HD #endif - + U08 fpReadCtr = getFPGABloodFlowFastPacketReadCounter(); + U08 spReadCtr = getFPGABloodFlowSlowPacketReadCounter(); + U08 stpReadCtr = getFPGABloodFlowStatusPacketReadCounter(); + U08 flowErrorCtr = getFPGABloodFlowErrorCounter(); + +#ifndef DISABLE_FPGA_COUNTER_CHECKS + // Check for stale flow reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( fpReadCtr == lastBloodFlowFastPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_FAST_PACKET ) + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( spReadCtr == lastBloodFlowSlowPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_SLOW_PACKET ) + } +// if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( stpReadCtr == lastBloodFlowStatusPacketReadCtr ) ) ) +// { +// SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_STATUS_PACKET ) +// } +#endif + + // Record flow read counters for next time around + lastBloodFlowFastPacketReadCtr = fpReadCtr; + lastBloodFlowSlowPacketReadCtr = spReadCtr; + lastBloodFlowStatusPacketReadCtr = stpReadCtr; + adcBloodPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpRPM)) * BP_SPEED_ADC_TO_RPM_FACTOR; adcBloodPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpmA)) * BP_CURRENT_ADC_TO_MA_FACTOR; bloodFlowSignalStrength.data = getFPGABloodFlowSignalStrength(); @@ -458,6 +506,7 @@ // Publish blood flow data on interval publishBloodFlowData(); } +//ALARM_ID_HD_BP_FLOW_SENSOR_ERROR = 208, ///< HD blood flow sensor error /*********************************************************************//** * @brief @@ -715,7 +764,7 @@ * @details Outputs: none * @return the current blood flow data publication interval (in task intervals). *************************************************************************/ -U32 getPublishBloodFlowDataInterval( void ) +U32 getPublishBloodFlowDataInterval( void ) { U32 result = bloodFlowDataPublishInterval.data; @@ -1193,7 +1242,7 @@ HD_FLOW_SENSORS_CAL_RECORD_T cal = getHDFlowSensorsCalibrationRecord(); // Retrieve blood flow sensor calibration data and check for sensor connected status - if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != getFPGABloodFlowMeterStatus() ) + if ( BFM_SENSOR_PARAM_CORRUPT_STATUS != bfmStatus ) { bloodFlowCalGain = cal.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].gain; bloodFlowCalOffset = cal.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].offset; @@ -1321,7 +1370,7 @@ /*********************************************************************//** * @brief - * The testResetOffButtonStateOverride function resets the override of the + * The testResetMeasuredBloodFlowRateOverride function resets the override of the * measured blood flow rate. * @details Inputs: none * @details Outputs: measuredBloodFlowRate Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r6fcdec8a308be986e5a64b4222918e718622a19d -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 6fcdec8a308be986e5a64b4222918e718622a19d) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -166,8 +166,9 @@ static U32 errorDialOutRotorSpeedPersistTimerCtr = 0; ///< Persistence timer counter for rotor speed error condition. static U32 errorDialOutPumpDirectionPersistTimerCtr = 0; ///< Persistence timer counter for pump direction error condition. -static DIAL_OUT_PUMP_SELF_TEST_STATE_T dialOutPumpSelfTestState = DIAL_OUT_PUMP_SELF_TEST_STATE_START; ///< Current state of the dialysate outlet pump self-test state machine. -static U32 dialOutPumpSelfTestTimerCount = 0; ///< Timer counter for time reference during self-test. +// TODO: Enable when self-test ready +//static DIAL_OUT_PUMP_SELF_TEST_STATE_T dialOutPumpSelfTestState = DIAL_OUT_PUMP_SELF_TEST_STATE_START; ///< Current state of the dialysate outlet pump self-test state machine. +//static U32 dialOutPumpSelfTestTimerCount = 0; ///< Timer counter for time reference during self-test. // ********** private function prototypes ********** Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -re5d1d67106a93a6cd1b5692b586625d715732e2f -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision e5d1d67106a93a6cd1b5692b586625d715732e2f) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -169,14 +169,14 @@ { VALVE_POSITION_T commandedPosition; ///< Valve commanded position enum VALVE_POSITION_T currentPosition; ///< Valve current position enum - S16 currentPositionInCounts; ///< Valve current position in counts + OVERRIDE_S32_T currentPositionInCounts; ///< Valve current position in counts S16 targetPositionInCounts; ///< Valve target position in counts BOOL hasTransitionBeenRequested; ///< Valve transition request flag VALVE_STATE_T execState; ///< Valve execution state U32 transitionStartTime; ///< Valve transition start time S16 positions[ NUM_OF_VALVE_POSITIONS ]; ///< Valve positions array (Pos A, Pos B, Pos C) VALVE_MODE_T controlMode; ///< Valve control mode (PID, bypass, disable) - F32 current; ///< Valve current + OVERRIDE_F32_T current; ///< Valve current U32 overCurrentCounter; ///< Valve over current counter U32 positionOutOfRangeCounter; ///< Valve position out of range counter U32 dataPublishCounter; ///< Valve data publish counter @@ -243,10 +243,11 @@ static BOOL areValvesFunctional( void ); static void setFPGAValveSetPoint( VALVE_T valve, S16 position, BOOL enableCurrentRelaxation ); static void convertAndMonitorValvesCurrent( void ); -static void getAndMonitorValvesCurrentPosition( void ); +static void getAndMonitorValvesCurrentFPGAPosition( void ); static U32 getPublishValvesDataInterval( void ); static void publishValvesData( VALVE_T valve ); static void setValveNextStep( VALVE_T valve, U32 stepChange ); +static S16 getValvePositionCounts( VALVE_T valve ); // These functions will be used in debug only mode #ifdef DEBUG_ENABLED @@ -280,6 +281,10 @@ for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) { valvesStatus[ valve ].execState = VALVE_STATE_WAIT_FOR_POST; + valvesStatus[ valve ].current.data = 0.0; + valvesStatus[ valve ].current.ovData = 0.0; + valvesStatus[ valve ].current.ovInitData = 0.0; + valvesStatus[ valve ].current.override = 0; } // Close air trap valve @@ -367,6 +372,26 @@ /*********************************************************************//** * @brief + * The getValveCurrent function returns the current of a valve. + * @details Inputs: none + * @details Outputs: valvesStatus + * @param valve that the current is requested + * @return returns the current of the valve in float + *************************************************************************/ +F32 getValveCurrent( VALVE_T valve ) +{ + F32 current = valvesStatus[ valve ].current.data; + + if ( OVERRIDE_KEY == valvesStatus[ valve ].current.override ) + { + current = valvesStatus[ valve ].current.ovData; + } + + return current; +} + +/*********************************************************************//** + * @brief * The setValveBloodTrap function set the blood trap valve to open or close * position. * @details Inputs: valveAirTrapStatus @@ -599,7 +624,7 @@ { // Get ready for the energized state valvesStatus[ valve ].homingEdgeDetectionCounter = 0; - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + HOMING_STEP_CHANGE_IN_COUNTS; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + HOMING_STEP_CHANGE_IN_COUNTS; valvesStatus[ valve ].hasValveBeenHomed = FALSE; valvesStatus[ valve ].currentPosition = VALVE_POSITION_NOT_IN_POSITION; setFPGAValveSetPoint( valve, valvesStatus[ valve ].targetPositionInCounts, FALSE ); @@ -622,7 +647,7 @@ { VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; S16 deltaPosition = targetPosition - currentPosition; @@ -643,7 +668,6 @@ { valvesStatus[ valve ].homingEdgeDetectionCounter++; } - } // Reached to target, go for the next target else @@ -669,7 +693,7 @@ { VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; S16 deltaPosition = currentPosition - targetPosition; @@ -815,7 +839,7 @@ // Get the corresponding counts of the positions S16 commandedPosition = valvesStatus[ valve ].positions[ commandedPositionEnum ]; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; // Check if the valve is within range of the final commanded position. @@ -941,7 +965,7 @@ #endif // Get the current position of the valves in counts and store them - getAndMonitorValvesCurrentPosition(); + getAndMonitorValvesCurrentFPGAPosition(); #ifndef DISABLE_3WAY_VALVES // Get the current in ADC and convert them to amps @@ -1084,22 +1108,22 @@ U16 currentInADC = 0; currentInADC = getFPGAValveDialyzerInletCurrentCounts(); - valvesStatus[ VDI ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VDI ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveDialyzerOutletCurrentCounts(); - valvesStatus[ VDO ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VDO ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveBloodArterialCurrentCounts(); - valvesStatus[ VBA ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VBA ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; currentInADC = getFPGAValveBloodVenousCurrentCounts(); - valvesStatus[ VBV ].current = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; + valvesStatus[ VBV ].current.data = ( (F32)currentInADC / ADC_TO_CURRENT_CONVERSION_CONSTANT ) - 1; // Check the current of all the valves for ( valve = VDI; valve < NUM_OF_VALVES; valve++) { // Absolute value is used to cover both positive and negative values - F32 current = fabs( valvesStatus[ valve ].current ); + F32 current = fabs( getValveCurrent( valve ) ); if ( current > VALVES_CURRENT_THRESHOLD_AMPS ) { @@ -1113,8 +1137,7 @@ #endif } // If the current is below the threshold again and the counter for the time is greater than - else if ( current < VALVES_CURRENT_THRESHOLD_AMPS && - valvesStatus[ valve ].overCurrentCounter > 0 ) + else if ( ( current < VALVES_CURRENT_THRESHOLD_AMPS ) && ( valvesStatus[ valve ].overCurrentCounter > 0 ) ) { valvesStatus[ valve ].overCurrentCounter = 0; } @@ -1123,27 +1146,27 @@ /*********************************************************************//** * @brief - * The getAndMonitorValvesCurrentPosition function gets the current position \n - * of the valves and stores them into the structure of each valve. The function \n - * checks whether any of the valves have deviated from their current position \n - * if they are in idle state. If any of the valves have deviated, the function \n - * raises an alarm. + * The getAndMonitorValvesCurrentFPGAPosition function gets the current + * position of the valves from FPGA and stores them into the structure of + * each valve.The function checks whether any of the valves have deviated + * from their current position if they are in idle state. If any of the + * valves have deviated, the function raises an alarm. * @details Inputs: valvesStatus * @details Outputs: valvesStatus * @return none *************************************************************************/ -static void getAndMonitorValvesCurrentPosition( void ) +static void getAndMonitorValvesCurrentFPGAPosition( void ) { VALVE_T valve; S16 currentPostion = 0; S16 commandedPoistion = 0; VALVE_POSITION_T commandedPositionEnum; // Get the position of the valves and update the structure of each valve - valvesStatus[ VDI ].currentPositionInCounts = getFPGAValveDialyzerInletPosition(); - valvesStatus[ VDO ].currentPositionInCounts = getFPGAValveDialyzerOutletPosition(); - valvesStatus[ VBA ].currentPositionInCounts = getFPGAValveBloodArterialPosition(); - valvesStatus[ VBV ].currentPositionInCounts = getFPGAValveBloodVenousPosition(); + valvesStatus[ VDI ].currentPositionInCounts.data = (S32)getFPGAValveDialyzerInletPosition(); + valvesStatus[ VDO ].currentPositionInCounts.data = (S32)getFPGAValveDialyzerOutletPosition(); + valvesStatus[ VBA ].currentPositionInCounts.data = (S32)getFPGAValveBloodArterialPosition(); + valvesStatus[ VBV ].currentPositionInCounts.data = (S32)getFPGAValveBloodVenousPosition(); #ifndef DISABLE_3WAY_VALVES // Check the position of each valve @@ -1154,7 +1177,7 @@ { U32 maxDeviation = MAX_DEVIATION_FROM_TARGET_IN_COUNTS; - currentPostion = valvesStatus[ valve ].currentPositionInCounts; + currentPostion = getValvePositionCounts( valve ); commandedPositionEnum = valvesStatus[ valve ].commandedPosition; commandedPoistion = valvesStatus[ valve ].positions[ commandedPositionEnum ]; @@ -1226,9 +1249,9 @@ valveData.valveID = (U32)valve; valveData.state = (U32)valvesStatus[ valve ].execState; valveData.currentPosID = (U32)valvesStatus[ valve ].currentPosition; - valveData.currentPos = valvesStatus[ valve ].currentPositionInCounts; + valveData.currentPos = getValvePositionCounts( valve ); valveData.nextPos = valvesStatus[ valve ].targetPositionInCounts; - valveData.current = valvesStatus[ valve ].current; + valveData.current = getValveCurrent( valve ); valveData.posC = valvesStatus[ valve ].positions[ VALVE_POSITION_C_CLOSE ]; valveData.posA = valvesStatus[ valve ].positions[ VALVE_POSITION_A_INSERT_EJECT ]; valveData.posB = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ]; @@ -1255,7 +1278,7 @@ S16 nextStep = 0; VALVE_POSITION_T currentPositionEnum = valvesStatus[ valve ].currentPosition; VALVE_POSITION_T commandedPositionEnum = valvesStatus[ valve ].commandedPosition; - S16 currentPosition = valvesStatus[ valve ].currentPositionInCounts; + S16 currentPosition = getValvePositionCounts( valve ); S16 commandedPosition = valvesStatus[ valve ].positions[ commandedPositionEnum ]; // If the next step is less than the specified step change, set that @@ -1281,22 +1304,22 @@ // Subtract the defined number of steps for the next transition if ( commandedPositionEnum == VALVE_POSITION_B_OPEN ) { - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; } if ( commandedPositionEnum == VALVE_POSITION_C_CLOSE ) { - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts - nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; } break; case VALVE_POSITION_B_OPEN: // If the valve is currently in position B, subtract the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts - nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; break; case VALVE_POSITION_C_CLOSE: // If the valve is currently in position C, add the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = valvesStatus[ valve ].currentPositionInCounts + nextStep; + valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; break; default: @@ -1309,6 +1332,27 @@ setFPGAValveSetPoint( valve, valvesStatus[ valve ].targetPositionInCounts, FALSE ); } +/*********************************************************************//** + * @brief + * The getValvePositionCounts function returns a valve's position in + * counts. + * @details Inputs: valvesStatus + * @details Outputs: none + * @param valve that its position in counts is requested + * @return current position of the valve in counts (S16) + *************************************************************************/ +static S16 getValvePositionCounts( VALVE_T valve ) +{ + S16 position = (S16)valvesStatus[ valve ].currentPositionInCounts.data; + + if ( OVERRIDE_KEY == valvesStatus[ valve ].currentPositionInCounts.override ) + { + position = (S16)valvesStatus[ valve ].currentPositionInCounts.ovData; + } + + return position; +} + #ifdef DEBUG_ENABLED /*********************************************************************//** * @brief @@ -1464,7 +1508,7 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { // Get the current position of the valve as the initial position valvesPositionOverride[ valve ].ovInitData = (U32)valvesStatus[ valve ].currentPosition; @@ -1483,14 +1527,14 @@ * of the valves publish interval. * @details Inputs: valvesDataPublishInterval * @details Outputs: valvesDataPublishInterval - * @param valve that its data publish will be overridden + * @param valve that its position override will be reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetValvesPositionOverride( U32 valve ) { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { valvesPositionOverride[ valve ].override = OVERRIDE_RESET; valvesPositionOverride[ valve ].ovData = valvesPositionOverride[ valve ].ovInitData; @@ -1518,13 +1562,13 @@ { BOOL result = FALSE; - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { BOOL homingStatus = valvesStatus[ valve ].hasValveBeenHomed; // The PWM should be in range and also the valve direction should be legal and the valve must have been homed // Prior to running this command - if ( pwm <= VALVE_MAX_ALLOWED_PWM_PERCENT && direction < NUM_OF_VALVE_DIRECTION && homingStatus ) + if ( ( pwm <= VALVE_MAX_ALLOWED_PWM_PERCENT ) && ( direction < NUM_OF_VALVE_DIRECTION ) && ( TRUE == homingStatus ) ) { valvesStatus[ (VALVE_T)valve ].bypassModeStatus.commandedPWMInPercent = (U16)pwm; valvesStatus[ (VALVE_T)valve ].bypassModeStatus.direction = (VALVE_DIRECTION_T)direction; @@ -1533,7 +1577,6 @@ valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasBypassModeBeenRequeseted = TRUE; // This flag is used to check if a change in PWM has been requested so the new PWM is processed and set valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasChangeBeenRequested = TRUE; - result = TRUE; } } @@ -1547,25 +1590,122 @@ * control mode. * @details Inputs: valvesStatus * @details Outputs: valvesStatus - * @param valve that its data publish will be overridden + * @param valve that its PWM override will be reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetValvePWMOverride( U32 valve ) { BOOL result = FALSE; // Check if the valve is in the range of the valves available - if ( TRUE == isTestingActivated() && valve < NUM_OF_VALVES ) + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) { // Turn off the bypass mode request and the change request valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasBypassModeBeenRequeseted = FALSE; valvesStatus[ (VALVE_T)valve ].bypassModeStatus.hasChangeBeenRequested = FALSE; + result = TRUE; + } + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValvesCurrentOverride function overrides the valves' current. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve to override its current + * @param current of the valve that will be overridden + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValvesCurrentOverride( U32 valve, F32 current ) +{ + BOOL result = FALSE; + + // Check if the valve is in the range of the valves available + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].current.override = OVERRIDE_KEY; + valvesStatus[ (VALVE_T)valve ].current.ovData = current; + valvesStatus[ (VALVE_T)valve ].current.ovInitData = valvesStatus[ (VALVE_T)valve ].current.data; result = TRUE; } return result; } + +/*********************************************************************//** + * @brief + * The testResetValvesCurrentOverride function resets the override + * of the valves' current. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve that its current override will be reset + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetValvesCurrentOverride( U32 valve ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].current.override = OVERRIDE_RESET; + valvesStatus[ (VALVE_T)valve ].current.ovData = valvesStatus[ (VALVE_T)valve ].current.ovInitData; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValvesPositionCountOverride function overrides the valves + * position in counts. + * @details Inputs: valvesPositionOverride, valvesStatus + * @details Outputs: valvesPositionOverride + * @param valve to override its position + * @param position of the valve that will be overridden + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValvesPositionCountOverride( U32 valve, U32 count ) +{ + BOOL result = FALSE; + + // Check if the valve is in the range of the valves available + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.override = OVERRIDE_KEY; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovData = (S32)count; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovInitData = valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.data; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetValvesPositionCountOverride function resets the override + * of the valves' position in counts. + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus + * @param valve that its position count override will be reset + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetValvesPositionCountOverride( U32 valve ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( valve < NUM_OF_VALVES ) ) + { + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.override = OVERRIDE_RESET; + valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovData = valvesStatus[ (VALVE_T)valve ].currentPositionInCounts.ovInitData; + result = TRUE; + } + + return result; +} + #endif /**@}*/ Index: firmware/App/Modes/BloodPrime.c =================================================================== diff -u -rea0047d0cb48b899475cf519e7e4997d96f5e538 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision ea0047d0cb48b899475cf519e7e4997d96f5e538) +++ firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -39,10 +39,13 @@ // TODO - get from Systems when available #define TARGET_BLOOD_PRIME_VOLUME_ML 300.0 ///< Target blood prime volume to prime the blood side circuit (in mL). #define MIN_RAMP_TIME_SEC 60 ///< Minimum ramp time for blood prime (in seconds). + +#ifndef DISABLE_PUMP_FLOW_CHECKS /// Maximum blood prime volume measured by independent means (as % of target). static const F32 MAX_BLOOD_PRIME_SAFETY_VOLUME_ML = ( TARGET_BLOOD_PRIME_VOLUME_ML * 1.2 ); /// Minimum blood prime volume measured by independent means (as % of target). static const F32 MIN_BLOOD_PRIME_SAFETY_VOLUME_ML = ( TARGET_BLOOD_PRIME_VOLUME_ML * 0.8 ); +#endif /// Initial flow rate for blood pump when starting blood prime operation. #define BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN 100 Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -19,6 +19,7 @@ #include "AlarmLamp.h" #include "BloodFlow.h" #include "Buttons.h" +#include "Compatible.h" #include "CPLD.h" #include "DialInFlow.h" #include "FPGA.h" @@ -46,6 +47,7 @@ // ********** private function prototypes ********** static HD_POST_STATE_T handlePOSTStatus( SELF_TEST_STATUS_T testStatus ); +static SELF_TEST_STATUS_T execFWCompatibilityTest( void ); /*********************************************************************//** * @brief @@ -101,7 +103,7 @@ switch ( postState ) { case POST_STATE_START: - postState = POST_STATE_WATCHDOG; + postState = POST_STATE_FW_COMPATIBILITY; #ifdef SKIP_POST postState = POST_STATE_COMPLETED; #endif @@ -111,6 +113,11 @@ #endif break; + case POST_STATE_FW_COMPATIBILITY: + testStatus = execFWCompatibilityTest(); + postState = handlePOSTStatus( testStatus ); + break; + case POST_STATE_WATCHDOG: testStatus = execWatchdogTest(); postState = handlePOSTStatus( testStatus ); @@ -260,8 +267,9 @@ } else if ( testStatus == SELF_TEST_STATUS_FAILED ) { - requestAlarmLampPattern( LAMP_PATTERN_FAULT ); + // At least one POST has failed tempPOSTPassed = FALSE; + // Test that failed should have triggered a fault which will request fault mode, so should POST state machine should never see FAILED state and will fault if it does result = POST_STATE_FAILED; } else @@ -271,3 +279,21 @@ return result; } + +/*********************************************************************//** + * @brief + * The execFWCompatibilityTest function executes the firmware compatibility test. + * @details Inputs: none + * @details Outputs: none + * @return in progress, passed, or failed + *************************************************************************/ +static SELF_TEST_STATUS_T execFWCompatibilityTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; + + // TODO - implement + + return result; +} + +/**@}*/ Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r340ca3700bbc4235d85d82864597fe17ab4b557a -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 340ca3700bbc4235d85d82864597fe17ab4b557a) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -136,8 +136,7 @@ break; default: - // TODO - s/w fault - currentStandbyState = STANDBY_START_STATE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); break; } #else @@ -225,7 +224,7 @@ break; default: - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_STANDBY_INVALID_STATE, currentStandbyState ); currentStandbyState = STANDBY_START_STATE; break; } Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -rb5accb82ac043938255883b6c60a6f81795569b0 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision b5accb82ac043938255883b6c60a6f81795569b0) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -43,10 +43,13 @@ #define RINSEBACK_FLOW_RATE_ADJ_ML_MIN 25 ///< Adjustment amount (in mL/min) to apply when user requests increase/decrease in flow rate. #define MIN_RINSEBACK_FLOW_RATE_ML_MIN 50 ///< Minimum rinseback flow rate (in mL/min). #define MAX_RINSEBACK_FLOW_RATE_ML_MIN 150 ///< Maximum rinseback flow rate (in mL/min). + +#ifndef DISABLE_PUMP_FLOW_CHECKS /// Maximum rinseback volume measured by independent means (as % of target). static const F32 MAX_RINSEBACK_SAFETY_VOLUME_ML = ( TARGET_RINSEBACK_VOLUME_ML * 1.2 ); /// Minimum rinseback volume measured by independent means (as % of target). static const F32 MIN_RINSEBACK_SAFETY_VOLUME_ML = ( TARGET_RINSEBACK_VOLUME_ML * 0.8 ); +#endif /// Interval at which rinseback progress is to be published to UI. static const U32 RINSEBACK_DATA_PUBLISH_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rf699178c91a882b71e96ebab9d24bb21005a4526 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision f699178c91a882b71e96ebab9d24bb21005a4526) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -212,10 +212,10 @@ void transitionToNoCartSelfTests( void ) { F32 const bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - F32 const hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 const hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); #ifndef DISABLE_SYRINGE_PUMP - useHeparin = ( ( bolusVol > 0.0 ) || ( hepRate > 0.0 ) ); + useHeparin = ( ( bolusVol > 0.0 ) || ( hepRate > 0.0 ) ? TRUE : FALSE ); #else useHeparin = FALSE; #endif @@ -333,14 +333,6 @@ *************************************************************************/ void transitionToDrySelfTests() { - F32 const bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - F32 const hepRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - -#ifndef DISABLE_SYRINGE_PUMP - useHeparin = ( ( bolusVol > 0.0 ) || ( hepRate > 0.0 ) ); -#else - useHeparin = FALSE; -#endif currentDrySelfTestsState = DRY_SELF_TESTS_START_STATE; pressureSelfTestBloodPumpRunStartTime = 0; pressureSelfTestNormalizedStartTime = 0; @@ -634,7 +626,7 @@ if ( TRUE == useHeparin ) { - if ( ( FALSE == isSyringePumpHome() ) && ( TRUE == isSyringePumpStopped() ) ) + if ( TRUE == isSyringePumpStopped() ) { retractSyringePump(); } @@ -794,10 +786,6 @@ { state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; } - else - { - activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); - } if ( TRUE == doesAlarmStatusIndicateStop() ) { Index: firmware/App/Modes/TreatmentEnd.c =================================================================== diff -u -re82f92d4dec50a1e1362cf175fb20d412ddc5b32 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision e82f92d4dec50a1e1362cf175fb20d412ddc5b32) +++ firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -109,7 +109,8 @@ { initTreatmentEnd(); - // TODO - stop any DG fill that may be in progress + // Stop any DG fill that may be in progress + cmdStopDGFill(); // Set valves setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -20,8 +20,10 @@ #define __ALARM_MGMT_C__ #include "AlarmLamp.h" -#include "FPGA.h" +#include "FPGA.h" +#include "InternalADC.h" #include "OperationModes.h" +#include "SafetyShutdown.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -35,6 +37,8 @@ /// Interval to control lamp and audio and to publish alarm status data. static const U32 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 ) #define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. @@ -64,14 +68,29 @@ // ********** private data ********** -static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. +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. /// Table - current state of each alarm static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; /// Table - current state of each alarm condition (detected or cleared) static BOOL alarmIsDetected[ 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 ]; +/// Interval (in task intervals) at which to publish alarm information to CAN bus. +static OVERRIDE_U32_T alarmInfoPublishInterval = { ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, 0 }; +#ifndef ALARM_VOLUME_DEFAULT_LOW +/// Set alarm audio volume attenuation level (0..4 - lower level = higher gain). +static OVERRIDE_U32_T alarmAudioVolumeLevel = { MIN_ALARM_VOLUME_ATTENUATION, MIN_ALARM_VOLUME_ATTENUATION, MIN_ALARM_VOLUME_ATTENUATION, 0 }; +#else +static OVERRIDE_U32_T alarmAudioVolumeLevel = { MAX_ALARM_VOLUME_ATTENUATION, MAX_ALARM_VOLUME_ATTENUATION, MAX_ALARM_VOLUME_ATTENUATION, 0 }; +#endif +/// Alarm audio current (high gain) measured at ADC. +static OVERRIDE_F32_T alarmPrimaryAudioCurrentHG = { 0.0, 0.0, 0.0, 0 }; +/// Alarm audio current (low gain) measured at ADC. +static OVERRIDE_F32_T alarmPrimaryAudioCurrentLG = { 0.0, 0.0, 0.0, 0 }; +/// Alarm backup audio current measured at ADC. +static OVERRIDE_F32_T alarmBackupAudioCurrent = { 0.0, 0.0, 0.0, 0 }; /// Record for the current composite alarm status. static COMP_ALARM_STATUS_T alarmStatus; @@ -82,12 +101,11 @@ /// Alarm user recovery actions enabled flags. static BOOL alarmUserRecoveryActionEnabled[ NUMBER_OF_ALARM_USER_ACTIONS ]; -static U32 alarmAudioVolumeLevel = 3; //MIN_ALARM_VOLUME_ATTENUATION; ///< Set alarm audio volume attenuation level (0..4 - lower level = higher gain). - // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); - + +static void monitorAlarms( void ); static void updateAlarmsState( void ); static void setAlarmLamp( void ); static void setAlarmAudio( void ); @@ -99,6 +117,9 @@ static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); static U32 getAlarmStartTime( ALARM_ID_T alarmID ); + +static void publishAlarmInfo( void ); +static U32 getPublishAlarmInfoInterval( void ); /*********************************************************************//** * @brief @@ -139,7 +160,7 @@ alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmsEscalatesIn = 0; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; - alarmStatus.topAlarmConditionnDetected = FALSE; + alarmStatus.topAlarmConditionDetected = FALSE; alarmStatus.systemFault = FALSE; alarmStatus.stop = FALSE; alarmStatus.lampOn = FALSE; @@ -163,6 +184,7 @@ *************************************************************************/ void execAlarmMgmt( void ) { + monitorAlarms(); handleAlarmEscalations(); updateAlarmsState(); updateAlarmsFlags(); @@ -564,10 +586,21 @@ *************************************************************************/ void setAlarmAudioVolume( U32 volumeLevel ) { + BOOL accepted = FALSE; + U32 rejReason = REQUEST_REJECT_REASON_NONE; + if ( ( volumeLevel > 0 ) && ( volumeLevel <= MAX_ALARM_VOLUME_LEVEL ) ) { // Convert volume level to attenuation level - alarmAudioVolumeLevel = MAX_ALARM_VOLUME_LEVEL - volumeLevel; + alarmAudioVolumeLevel.data = MAX_ALARM_VOLUME_LEVEL - volumeLevel; + accepted = TRUE; } + else + { + rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + + // Send response to UI + sendAlarmAudioVolumeSetResponse( accepted, rejReason ); } /*********************************************************************//** @@ -600,6 +633,27 @@ return result; } + +/*********************************************************************//** + * @brief + * The monitorAlarms function monitors alarm audio current. + * @details Inputs: alarmStatusTable[] + * @details Outputs: alarmPriorityFIFO[], alarmStatus + * @return none + *************************************************************************/ +static void monitorAlarms( void ) +{ + U32 volume = getAlarmAudioVolume(); + + alarmPrimaryAudioCurrentHG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); + alarmPrimaryAudioCurrentLG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); + alarmBackupAudioCurrent.data = getIntADCVoltageConverted( INT_ADC_BACKUP_ALARM_CURRENT ); + + // TODO - Check current vs. expected audio output + + // Publish alarm information at interval + publishAlarmInfo(); +} /*********************************************************************//** * @brief @@ -663,7 +717,8 @@ // Update alarm to display per highest priority FIFO alarmStatus.alarmsState = highestPriority; - alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; + alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; + alarmStatus.topAlarmConditionDetected = alarmIsDetected[ alarmStatus.alarmTop ]; alarmStatus.systemFault = faultsActive; alarmStatus.noDialRecirc = dialysateRecircBlocked; } @@ -737,22 +792,24 @@ *************************************************************************/ static void setAlarmAudio( void ) { + U32 volume = getAlarmAudioVolume(); + if ( TRUE == alarmStatus.alarmsSilenced ) { - setAlarmAudioState( ALARM_PRIORITY_NONE, alarmAudioVolumeLevel ); + setAlarmAudioState( ALARM_PRIORITY_NONE, volume ); } else // Alarms not silenced { if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) { #ifndef DISABLE_ALARM_AUDIO - setAlarmAudioState( alarmStatus.alarmsState, alarmAudioVolumeLevel ); + setAlarmAudioState( alarmStatus.alarmsState, volume ); #endif } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - setAlarmAudioState( ALARM_PRIORITY_HIGH, alarmAudioVolumeLevel ); + setAlarmAudioState( ALARM_PRIORITY_HIGH, volume ); } } } @@ -871,6 +928,7 @@ BOOL noEndTreatment = FALSE; BOOL noNewTreatment = FALSE; BOOL usrAckReq = FALSE; + BOOL noMinimize = TRUE; ALARM_ID_T a; // Determine alarm flags @@ -911,7 +969,7 @@ } // Alarm table loop // If top alarm condition not cleared, block resume and rinseback flags - if ( TRUE == alarmStatus.topAlarmConditionnDetected ) + if ( TRUE == alarmStatus.topAlarmConditionDetected ) { noResume = TRUE; noRinseback = TRUE; @@ -920,14 +978,20 @@ // If top alarm requires user ack or no other user options enabled for recoverable alarm and condition cleared, set user ack flag and block other flags if ( ( TRUE == ALARM_TABLE[ alarmStatus.alarmTop ].alarmUserAckRequired ) || ( ( FALSE == alarmStatus.noClear ) && ( noResume ) && ( noRinseback ) && ( noEndTreatment ) && - ( FALSE == alarmStatus.topAlarmConditionnDetected ) ) ) + ( FALSE == alarmStatus.topAlarmConditionDetected ) ) ) { usrAckReq = TRUE; noResume = TRUE; noRinseback = TRUE; noEndTreatment = TRUE; } + // If in Treatment-Stop state, allow user to minimize the alarm window + if ( ( MODE_TREA == getCurrentOperationMode() ) && ( TREATMENT_STOP_STATE == getTreatmentState() ) ) + { + noMinimize = FALSE; + } + // Set updated alarm flags alarmStatus.systemFault = systemFault; alarmStatus.stop = stop; @@ -936,7 +1000,8 @@ alarmStatus.noRinseback = noRinseback; alarmStatus.noEndTreatment = noEndTreatment; alarmStatus.noNewTreatment = noNewTreatment; - alarmStatus.usrACKRequired = usrAckReq; + alarmStatus.usrACKRequired = usrAckReq; + alarmStatus.noMinimize = noMinimize; } /*********************************************************************//** @@ -984,6 +1049,131 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) } } + +/*********************************************************************//** + * @brief + * The publishAlarmInfo function publishes alarm information at the set + * interval. + * @details Inputs: + * @details Outputs: alarm information are published to CAN bus. + * @return none + *************************************************************************/ +static void publishAlarmInfo( void ) +{ + // Publish voltages monitor data on interval + if ( ++alarmInfoPublicationTimerCounter >= getPublishAlarmInfoInterval() ) + { + ALARM_INFO_PAYLOAD_T data; + + data.audioVolume = MAX_ALARM_VOLUME_LEVEL - getAlarmAudioVolume(); // convert back to 1..5 volume level for publication + data.audioCurrHG = getAlarmAudioPrimaryHighGainCurrent(); + data.audioCurrLG = getAlarmAudioPrimaryLowGainCurrent(); + data.backupAudioCurr = getAlarmAudioBackupCurrent(); + data.safetyShutdown = isSafetyShutdownActivated(); + + broadcastAlarmInfo( data ); + alarmInfoPublicationTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief + * The getPublishAlarmInfoInterval function gets the blood flow data + * publication interval. + * @details Inputs: alarmInfoPublishInterval + * @details Outputs: none + * @return the current alarm information publication interval (in task intervals). + *************************************************************************/ +static U32 getPublishAlarmInfoInterval( void ) +{ + U32 result = alarmInfoPublishInterval.data; + + if ( OVERRIDE_KEY == alarmInfoPublishInterval.override ) + { + result = alarmInfoPublishInterval.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioVolume function gets the current alarm audio volume level. + * @details Inputs: alarmAudioVolumeLevel + * @details Outputs: none + * @return the current alarm audio volume level. + *************************************************************************/ +U32 getAlarmAudioVolume( void ) +{ + U32 result = alarmAudioVolumeLevel.data; + + if ( OVERRIDE_KEY == alarmAudioVolumeLevel.override ) + { + result = alarmAudioVolumeLevel.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioPrimaryHighGainCurrent function gets the current alarm + * audio high gain current. + * @details Inputs: alarmPrimaryAudioCurrentHG + * @details Outputs: none + * @return the current alarm audio high gain current (in mA). + *************************************************************************/ +F32 getAlarmAudioPrimaryHighGainCurrent( void ) +{ + F32 result = alarmPrimaryAudioCurrentHG.data; + + if ( OVERRIDE_KEY == alarmPrimaryAudioCurrentHG.override ) + { + result = alarmPrimaryAudioCurrentHG.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioPrimaryLowGainCurrent function gets the current alarm + * audio low gain current. + * @details Inputs: alarmPrimaryAudioCurrentLG + * @details Outputs: none + * @return the current alarm audio low gain current (in mA). + *************************************************************************/ +F32 getAlarmAudioPrimaryLowGainCurrent( void ) +{ + F32 result = alarmPrimaryAudioCurrentLG.data; + + if ( OVERRIDE_KEY == alarmPrimaryAudioCurrentLG.override ) + { + result = alarmPrimaryAudioCurrentLG.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioBackupCurrent function gets the current backup alarm + * audio current. + * @details Inputs: alarmBackupAudioCurrent + * @details Outputs: none + * @return the current backup alarm audio current (in mA). + *************************************************************************/ +F32 getAlarmAudioBackupCurrent( void ) +{ + F32 result = alarmBackupAudioCurrent.data; + + if ( OVERRIDE_KEY == alarmBackupAudioCurrent.override ) + { + result = alarmBackupAudioCurrent.ovData; + } + + return result; +} /************************************************************************* @@ -1154,6 +1344,233 @@ } return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmInfoPublishIntervalOverride function sets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @param ms milliseconds between alarm info broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / TASK_GENERAL_INTERVAL; + + result = TRUE; + alarmInfoPublishInterval.ovData = intvl; + alarmInfoPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmInfoPublishIntervalOverride function resets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmInfoPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmInfoPublishInterval.override = OVERRIDE_RESET; + alarmInfoPublishInterval.ovData = alarmInfoPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmAudioVolumeLevelOverride function sets the override of the + * alarm audio volume. + * @details Inputs: none + * @details Outputs: alarmAudioVolumeLevel + * @param volume volume level (1..5) of alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmAudioVolumeLevelOverride( U32 volume ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmAudioVolumeLevel.ovData = MAX_ALARM_VOLUME_LEVEL - volume; + alarmAudioVolumeLevel.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmAudioVolumeLevelOverride function resets the override of the + * alarm audio volume. + * @details Inputs: none + * @details Outputs: alarmAudioVolumeLevel + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmAudioVolumeLevelOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmAudioVolumeLevel.override = OVERRIDE_RESET; + alarmAudioVolumeLevel.ovData = alarmAudioVolumeLevel.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetPrimaryAlarmAudioCurrentHGOverride function sets the override of the + * alarm audio current (high gain) in mA. + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentHG + * @param mA milliamps measured from high gain channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetPrimaryAlarmAudioCurrentHGOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentHG.ovData = mA; + alarmPrimaryAudioCurrentHG.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetPrimaryAlarmAudioCurrentHGOverride function resets the override of the + * alarm audio current (high gain). + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentHG + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetPrimaryAlarmAudioCurrentHGOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentHG.override = OVERRIDE_RESET; + alarmPrimaryAudioCurrentHG.ovData = alarmPrimaryAudioCurrentHG.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetPrimaryAlarmAudioCurrentLGOverride function sets the override of the + * alarm audio current (low gain) in mA. + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentLG + * @param mA milliamps measured from low gain channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetPrimaryAlarmAudioCurrentLGOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentLG.ovData = mA; + alarmPrimaryAudioCurrentLG.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetPrimaryAlarmAudioCurrentLGOverride function resets the override of the + * alarm audio current (low gain). + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentLG + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetPrimaryAlarmAudioCurrentLGOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentLG.override = OVERRIDE_RESET; + alarmPrimaryAudioCurrentLG.ovData = alarmPrimaryAudioCurrentLG.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBackupAlarmAudioCurrentOverride function sets the override of the + * alarm audio current (backup) in mA. + * @details Inputs: none + * @details Outputs: alarmBackupAudioCurrent + * @param mA milliamps measured from backup channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetBackupAlarmAudioCurrentOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmBackupAudioCurrent.ovData = mA; + alarmBackupAudioCurrent.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBackupAlarmAudioCurrentOverride function resets the override of the + * alarm audio current (backup). + * @details Inputs: none + * @details Outputs: alarmBackupAudioCurrent + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetBackupAlarmAudioCurrentOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmBackupAudioCurrent.override = OVERRIDE_RESET; + alarmBackupAudioCurrent.ovData = alarmBackupAudioCurrent.ovInitData; + } + + return result; } /**@}*/ Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -51,7 +51,7 @@ ALARM_ACTION_ACK, ///< User selected Ack from alarm recovery options NUMBER_OF_ALARM_ACTIONS ///< Number of alarm actions } ALARM_ACTION_T; - + #pragma pack(push, 4) /// Record structure for detailing the properties of the current composite alarm status. typedef struct @@ -63,7 +63,7 @@ BOOL alarmsToEscalate; ///< Are any active alarms due to escalate (should UI show count down timer?) U32 alarmsEscalatesIn; ///< Time until alarm will escalate (seconds) ALARM_ID_T alarmTop; ///< ID of current top alarm that will drive lamp/audio and UI should be displaying right now - BOOL topAlarmConditionnDetected; ///< Condition for top alarm is still being detected + BOOL topAlarmConditionDetected; ///< Condition for top alarm is still being detected BOOL systemFault; ///< A system fault is active? BOOL stop; ///< We should be in controlled stop right now BOOL noClear; ///< No recovery will be possible @@ -73,6 +73,7 @@ BOOL noNewTreatment; ///< No new treatments may be started even if current treatment is ended BOOL noDialRecirc; ///< No dialysate re-circulation allowed at this time BOOL usrACKRequired; ///< The user must acknowledge top alarm + BOOL noMinimize; ///< Prevent user from minimizing the alarm window BOOL lampOn; ///< The alarm lamp is on } COMP_ALARM_STATUS_T; @@ -115,6 +116,17 @@ ALARM_DATA_TYPES_T dataType; ///< The type of alarm data provided. ALARM_DATAS_T data; ///< The alarm data of specified type. } ALARM_DATA_T; + +/// Payload record structure for the alarm info message. +typedef struct +{ + U32 audioVolume; ///< Audio volume level (1..5) + F32 audioCurrHG; ///< Primary alarm audio current - high gain (mA) + F32 audioCurrLG; ///< Primary alarm audio current - low gain (mA) + F32 backupAudioCurr; ///< Backup alarm audio current (mA) + BOOL safetyShutdown; ///< Safety shutdown activated? (T/F) +} ALARM_INFO_PAYLOAD_T; + #pragma pack(pop) #pragma pack(push, 2) @@ -279,13 +291,27 @@ BOOL doesAlarmStatusIndicateStop( void ); ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ); BOOL isAlarmRecoverable( ALARM_ID_T alarm ); -void setAlarmAudioVolume( U32 volumeLevel ); +void setAlarmAudioVolume( U32 volumeLevel ); +U32 getAlarmAudioVolume( void ); +F32 getAlarmAudioPrimaryHighGainCurrent( void ); +F32 getAlarmAudioPrimaryLowGainCurrent( void ); +F32 getAlarmAudioBackupCurrent( void ); BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); BOOL testResetAlarmStateOverride( U32 alarmID ); BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ); BOOL testResetAlarmStartOverride( U32 alarmID ); -BOOL testClearAllAlarms( U32 key ); +BOOL testClearAllAlarms( U32 key ); +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ); +BOOL testResetAlarmInfoPublishIntervalOverride( void ); +BOOL testSetAlarmAudioVolumeLevelOverride( U32 volume ); +BOOL testResetAlarmAudioVolumeLevelOverride( void ); +BOOL testSetPrimaryAlarmAudioCurrentHGOverride( F32 mA ); +BOOL testResetPrimaryAlarmAudioCurrentHGOverride( void ); +BOOL testSetPrimaryAlarmAudioCurrentLGOverride( F32 mA ); +BOOL testResetPrimaryAlarmAudioCurrentLGOverride( void ); +BOOL testSetBackupAlarmAudioCurrentOverride( F32 mA ); +BOOL testResetBackupAlarmAudioCurrentOverride( void ); /**@}*/ Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r9feea867113c62088f0ce91750127972dbd9bf53 -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 9feea867113c62088f0ce91750127972dbd9bf53) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -943,8 +943,10 @@ if ( TRUE == didTimeout( timeOfLastDGCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) { +#ifndef RUN_WITHOUT_DG activateAlarmNoData( ALARM_ID_DG_COMM_TIMEOUT ); dgIsCommunicating = FALSE; +#endif } } } @@ -1078,8 +1080,8 @@ { U16 msgID; - memcpy( &msgID, (U08*)&pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); + memcpy( &msgID, (U08*)&pendingAckList[ i ].msg[ sizeof( U08 ) + sizeof( U16) ], sizeof( U16 ) ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CAN_MESSAGE_NOT_ACKED, (U32)msgID ); pendingAckList[ i ].used = FALSE; // Take pending message off of list } } @@ -1205,6 +1207,10 @@ handleHeparinCommandRequest( message ); break; + case MSG_ID_UI_SET_ALARM_AUDIO_VOLUME_LEVEL_CMD: + handleAlarmAudioVolumeSetCmd( message ); + break; + case MSG_ID_UI_SET_UF_VOLUME_PARAMETER: handleUFVolumeSetRequest( message ); break; @@ -1533,6 +1539,10 @@ handleSetFluidLeakBroadcastIntervalOverrideRequest( message ); break; + case MSG_ID_HD_BLOOD_LEAK_STATUS_OVERRIDE: + handleSetFluidLeakStateDetectorOverrideRequest( message ); + break; + case MSG_ID_HD_FLUID_LEAK_STATE_OVERRIDE: handleSetFluidLeakStateOverrideRequest( message ); break; @@ -1541,10 +1551,6 @@ handleSetBloodLeakDataBroadcastIntervalOverrideRequest( message ); break; - case MSG_ID_HD_BLOOD_LEAK_STATUS_OVERRIDE: - handleSetBloodLeakStatusOverrideRequest( message ); - break; - case MSG_ID_HD_BLOOD_LEAK_ZERO_REQUEST: handleBloodLeakZeroRequest( message ); break; @@ -1589,6 +1595,58 @@ handleTestSyringePumpMeasuredVolumeOverrideRequest( message ); break; + case MSG_ID_HD_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE: + handleTestMonitoredVoltagesSendIntervalOverrideRequest( message ); + break; + + case MSG_ID_HD_MONITORED_VOLTAGES_OVERRIDE: + handleTestMonitoredVoltageOverrideRequest( message ); + break; + + case MSG_ID_HD_ALARM_INFO_SEND_INTERVAL_OVERRIDE: + handleTestAlarmInfoSendIntervalOverrideRequest( message ); + break; + + case MSG_ID_HD_ALARM_AUDIO_VOLUME_LEVEL_OVERRIDE: + handleTestAlarmAudioVolumeOverrideRequest( message ); + break; + + case MSG_ID_HD_ALARM_AUDIO_CURRENT_HG_OVERRIDE: + handleTestAlarmAudioCurrentHgOverrideRequest( message ); + break; + + case MSG_ID_HD_ALARM_AUDIO_CURRENT_LG_OVERRIDE: + handleTestAlarmAudioCurrentLgOverrideRequest( message ); + break; + + case MSG_ID_HD_ALARM_BACKUP_AUDIO_CURRENT_OVERRIDE: + handleTestAlarmBackupAudioCurrentOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_STATUS_OVERRIDE: + handleTestSyringePumpStatusOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_ENCODER_STATUS_OVERRIDE: + handleTestSyringePumpEncoderStatusOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_ADC_DAC_STATUS_OVERRIDE: + handleTestSyringePumpADCandDACStatusOverrideRequest( message ); + break; + + case MSG_ID_HD_SYRINGE_PUMP_ADC_READ_COUNTER_OVERRIDE: + handleTestSyringePumpADCReadCtrOverrideRequest( message ); + break; + + case MSG_ID_HD_VALVES_CURRENT_OVERRIDE: + handleTestValvesCurrentOverrideRequest( message ); + break; + + case MSD_ID_HD_VALVES_POSITION_COUNT_OVERRIDE: + handleTestValvesPositionCountOverrideRequest( message ); + break; + default: // Unrecognized message ID received - ignore break; Index: firmware/HD.dil =================================================================== diff -u -r850f74b97895fd0f6c4728541ac2582f7b5c5a0b -rf0c52f6adff7b61132953890a74f1c462b31eedf --- firmware/HD.dil (.../HD.dil) (revision 850f74b97895fd0f6c4728541ac2582f7b5c5a0b) +++ firmware/HD.dil (.../HD.dil) (revision f0c52f6adff7b61132953890a74f1c462b31eedf) @@ -7020,12 +7020,12 @@ DRIVER.I2C.VAR.I2C_DATACOUNT.VALUE=8 DRIVER.I2C.VAR.I2C_ADDRMODE.VALUE=7BIT_AMODE DRIVER.I2C.VAR.I2C_PORT_BIT0_FUN.VALUE=0 -DRIVER.I2C.VAR.I2C_PORT_BIT0_PDR.VALUE=0 +DRIVER.I2C.VAR.I2C_PORT_BIT0_PDR.VALUE=1 DRIVER.I2C.VAR.I2C_BC_VALUE.VALUE=0x0003 DRIVER.I2C.VAR.I2C_PORT_BIT1_FUN.VALUE=0 DRIVER.I2C.VAR.I2C_RM_ENA.VALUE=1 DRIVER.I2C.VAR.I2C_BC.VALUE=8_BIT -DRIVER.I2C.VAR.I2C_PORT_BIT1_PDR.VALUE=0 +DRIVER.I2C.VAR.I2C_PORT_BIT1_PDR.VALUE=1 DRIVER.I2C.VAR.I2C_TXRX_VALUE.VALUE=0 DRIVER.I2C.VAR.I2C_SCDLVL.VALUE=0 DRIVER.I2C.VAR.I2C_PORT_BIT0_PSL.VALUE=1