Index: firmware/App/Controllers/AlarmLamp.c =================================================================== diff -u -ra2bc96881a5fc3d8f779246b2abebf15a8de9384 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/AlarmLamp.c (.../AlarmLamp.c) (revision a2bc96881a5fc3d8f779246b2abebf15a8de9384) +++ firmware/App/Controllers/AlarmLamp.c (.../AlarmLamp.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -71,7 +71,7 @@ static BOOL alarmLampOn = FALSE; ///< Flag indicates whether an any lamp is currently on. /// Two step alarm lamp patterns (repeating). -const struct LampPatterns lampPatterns[ NUM_OF_LAMP_PATTERNS ] = { +const struct LampPatterns LAMP_PATTERNS[ NUM_OF_LAMP_PATTERNS ] = { { { 500, 500 }, { LAMP_STATE_OFF, LAMP_STATE_OFF }, { LAMP_STATE_OFF, LAMP_STATE_OFF }, { LAMP_STATE_OFF, LAMP_STATE_OFF } }, // LAMP_PATTERN_OFF { { 500, 500 }, { LAMP_STATE_ON, LAMP_STATE_ON }, { LAMP_STATE_OFF, LAMP_STATE_OFF }, { LAMP_STATE_OFF, LAMP_STATE_OFF } }, // LAMP_PATTERN_OK { { 250, 250 }, { LAMP_STATE_OFF, LAMP_STATE_OFF }, { LAMP_STATE_OFF, LAMP_STATE_OFF }, { LAMP_STATE_ON, LAMP_STATE_OFF } }, // LAMP_PATTERN_FAULT @@ -135,7 +135,7 @@ if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) { // If pattern step duration has elapsed, move to next step - if ( lampPatternStepTimer >= lampPatterns[ getCurrentAlarmLampPattern() ].duration[ currentLampPatternStep ] ) + if ( lampPatternStepTimer >= LAMP_PATTERNS[ getCurrentAlarmLampPattern() ].duration[ currentLampPatternStep ] ) { // Increment pattern step currentLampPatternStep++; @@ -177,7 +177,7 @@ * @details Outputs: none * @return currentLampPattern *************************************************************************/ -LAMP_PATTERN_T getCurrentAlarmLampPattern( void ) +LAMP_PATTERN_T getCurrentAlarmLampPattern( void ) { LAMP_PATTERN_T result = (LAMP_PATTERN_T)currentLampPattern.data; @@ -280,17 +280,17 @@ alarmLampOn = FALSE; lampPatternStepTimer = 0; - if ( lampPatterns[ getCurrentAlarmLampPattern() ].green[ currentLampPatternStep ] == LAMP_STATE_ON ) + if ( LAMP_PATTERNS[ getCurrentAlarmLampPattern() ].green[ currentLampPatternStep ] == LAMP_STATE_ON ) { green = PIN_SIGNAL_HIGH; alarmLampOn = TRUE; } - if ( lampPatterns[ getCurrentAlarmLampPattern() ].blue[ currentLampPatternStep ] == LAMP_STATE_ON ) + if ( LAMP_PATTERNS[ getCurrentAlarmLampPattern() ].blue[ currentLampPatternStep ] == LAMP_STATE_ON ) { blue = PIN_SIGNAL_HIGH; alarmLampOn = TRUE; } - if ( lampPatterns[ getCurrentAlarmLampPattern() ].red[ currentLampPatternStep ] == LAMP_STATE_ON ) + if ( LAMP_PATTERNS[ getCurrentAlarmLampPattern() ].red[ currentLampPatternStep ] == LAMP_STATE_ON ) { red = PIN_SIGNAL_HIGH; alarmLampOn = TRUE; Index: firmware/App/Controllers/Buttons.c =================================================================== diff -u -r0b3a29a3a189b9d357d3eaa554c7baf22de30e81 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 0b3a29a3a189b9d357d3eaa554c7baf22de30e81) +++ firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -138,14 +138,14 @@ PIN_SIGNAL_STATE_T off = getCPLDOffButton(); PIN_SIGNAL_STATE_T stop = getCPLDStopButton(); - // set current button states read from CPLD + // Set current button states read from CPLD dataOffButtonState.data = ( off == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); dataStopButtonState.data = ( stop == PIN_SIGNAL_HIGH ? BUTTON_STATE_PRESSED : BUTTON_STATE_RELEASED ); - // handle button state transitions for stop button + // Handle button state transitions for stop button handleStopButtonProcessing(); - // handle button state transitions for off button + // Handle button state transitions for off button handleOffButtonProcessing(); } @@ -225,7 +225,7 @@ case BUTTON_SELF_TEST_STATE_START: buttonSelfTestState = BUTTON_SELF_TEST_STATE_IN_PROGRESS; buttonSelfTestTimerCount = getMSTimerCount(); - // no break here so we pass through directly to in progress processing + // No break here so we pass through directly to in progress processing case BUTTON_SELF_TEST_STATE_IN_PROGRESS: if ( ( dataOffButtonState.data == BUTTON_STATE_RELEASED ) && ( dataStopButtonState.data == BUTTON_STATE_RELEASED ) ) @@ -241,11 +241,11 @@ buttonSelfTestState = BUTTON_SELF_TEST_STATE_COMPLETE; result = SELF_TEST_STATUS_FAILED; } - // else just stay in progress and wait for next call + // Else just stay in progress and wait for next call break; case BUTTON_SELF_TEST_STATE_COMPLETE: - // if we get called in this state, assume we're doing self-test again + // If we get called in this state, assume we are doing self-test again buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; break; @@ -273,7 +273,7 @@ switch ( response ) { case OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF: - // if we're in a mode that allows power off, set off pending flag and request user confirmation + // If we are in a mode that allows power off, set off pending flag and request user confirmation if ( TRUE == isCurrentOpModeOkToTurnOff() ) { offRequestAwaitingUserConfirmation = TRUE; @@ -283,18 +283,18 @@ #endif } else - { // send rejection response to power off request + { // Send rejection response to power off request sendOffButtonMsgToUI( OFF_BUTTON_CMD_REJECT_USER_OFF_REQUEST ); } break; case OFF_BUTTON_RSP_USER_CONFIRMS_POWER_OFF: - // is an off request pending user confirmation? + // Is an off request pending user confirmation? if ( TRUE == offRequestAwaitingUserConfirmation ) { - // reset off request pending flag + // Reset off request pending flag offRequestAwaitingUserConfirmation = FALSE; - // if we're in a mode that allows power off, initiate power off sequence + // If we are in a mode that allows power off, initiate power off sequence if ( TRUE == isCurrentOpModeOkToTurnOff() ) { broadcastPowerOffWarning(); @@ -315,18 +315,18 @@ break; case OFF_BUTTON_RSP_USER_REJECTS_POWER_OFF: - // is an off request pending user confirmation? + // Is an off request pending user confirmation? if ( TRUE == offRequestAwaitingUserConfirmation ) { - // reset off request pending flag + // Reset off request pending flag offRequestAwaitingUserConfirmation = FALSE; } break; default: - // ok - do nothing + // Ok - do nothing break; - } // end switch + } // End switch } /*********************************************************************//** @@ -360,12 +360,12 @@ *************************************************************************/ static void handleOffButtonProcessing( void ) { - // handle button state transitions for off button + // 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 + // If off request in a valid mode, send to UI for user confirmation userConfirmOffButton( OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF ); #ifdef SIMULATE_UI userConfirmOffButton( OFF_BUTTON_RSP_USER_CONFIRMS_POWER_OFF ); @@ -374,7 +374,7 @@ prevOffButtonState = getOffButtonState(); } - // if off request has not been confirmed by user before it expires, cancel it + // If off request has not been confirmed by user before it expires, cancel it if ( TRUE == offRequestAwaitingUserConfirmation ) { offRequestPendingTimer += TASK_PRIORITY_INTERVAL; @@ -385,14 +385,14 @@ } } - // if user confirmed off button press, manage off request sequence + // 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 + // Delay power off to provide sub-systems time to prepare for shutdown offRequestDelayTimer += TASK_PRIORITY_INTERVAL; if ( offRequestDelayTimer >= OFF_REQUEST_DELAY_TIME_MS ) { - // power off sequence is 4 50 ms toggles of the off request output signal + // Power off sequence is 4 50 ms toggles of the off request output signal offRequestPulseTimer += TASK_PRIORITY_INTERVAL; if ( offRequestPulseTimer >= OFF_REQUEST_PULSE_INTVL_MS ) { @@ -418,7 +418,7 @@ *************************************************************************/ static void handleStopButtonProcessing( void ) { - // handle button state transitions for stop button + // Handle button state transitions for stop button if ( getStopButtonState() != prevStopButtonState ) { if ( getStopButtonState() == BUTTON_STATE_PRESSED ) @@ -429,10 +429,10 @@ prevStopButtonState = getStopButtonState(); } - // handle when a stop button press is pending + // Handle when a stop button press is pending if ( TRUE == stopButtonPressPending ) { - // if stop button not consumed within a reasonable time, s/w fault + // If stop button not consumed within a reasonable time, s/w fault if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT_MS ) ) { stopButtonPressPending = FALSE; Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -ra2bc96881a5fc3d8f779246b2abebf15a8de9384 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision a2bc96881a5fc3d8f779246b2abebf15a8de9384) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -32,7 +32,10 @@ #define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. #define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. -#define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). +#define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). + +#define SIZE_OF_SMALL_LOAD_CELL_AVG 8 ///< Small load cell moving average has 8 samples. +#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States @@ -57,8 +60,9 @@ static BOOL dgTrimmerHeaterOn = FALSE; ///< Flag indicates whether we have commanded the DG to start or stop the trimmer heater. static BOOL dgWaterSampled = FALSE; ///< Flag indicates whether we have commanded the DG to sample water. -// State machine states -static TREATMENT_RESERVOIR_MGMT_STATE_T currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; ///< Current state of treatment mode reservoir management. +// State machine states +/// Current state of treatment mode reservoir management. +static TREATMENT_RESERVOIR_MGMT_STATE_T currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; static U32 resMgmtTimer = 0; ///< Used for keeping state time. // DG sensor data @@ -70,10 +74,27 @@ static F32 dgTrimmerTempSet = 0.0; ///< Trimmer heater target temperature commanded. static F32 dgTrimmerTemp = 0.0; ///< Latest dialysate temperature reported by the DG. +/// Measured weight from load cells. +static OVERRIDE_F32_T loadCellWeightInGrams[ NUM_OF_LOAD_CELLS ]; +/// Filtered (8 sample) weight of reservoirs. +static F32 smFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; +/// Filtered (32 sample) weight of reservoirs. +static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; + +// Load cell filtering data +/// Holds load cell samples for small load cell moving average +static F32 smLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_SMALL_LOAD_CELL_AVG ]; +static U32 smLoadCellReadingsIdx = 0; ///< index for next sample in small load cell rolling average sample array +static F32 smLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< rolling total - used to calc small load cell moving average +/// Holds load cell samples for large load cell moving average +static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; +static U32 lgLoadCellReadingsIdx = 0; ///< index for next sample in large load cell rolling average sample array +static F32 lgLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< rolling total - used to calc large load cell moving average + // DG pumps data -static F32 dgROPumpFlowRateMlMin = 0.0; ///< Latest RO water flow rate reported by the DG. -static U32 dgROPumpPressureSetPtPSI = 0; ///< Latest RO pump target pressure reported by the DG. -static U32 dgDrainPumpSpeedSetPtRPM = 0; ///< Latest Drain pump target speed reported by the DG. +static F32 dgROPumpFlowRateMlMin = 0.0; ///< Latest RO water flow rate reported by the DG. +static U32 dgROPumpPressureSetPtPSI = 0; ///< Latest RO pump target pressure reported by the DG. +static U32 dgDrainPumpSpeedSetPtRPM = 0; ///< Latest Drain pump target speed reported by the DG. // Reservoir data static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; ///< Latest active reservoir reported by the DG. @@ -98,19 +119,62 @@ *************************************************************************/ void initDGInterface( void ) { + U32 i, j; + dgStarted = FALSE; dgTrimmerHeaterOn = FALSE; dgWaterSampled = FALSE; dgPrimaryTempSet = 0.0; dgTrimmerTempSet = 0.0; dgActiveReservoirSet = DG_RESERVOIR_2; dgReservoirFillVolumeTargetSet = 0; - dgReservoirDrainVolumeTargetSet = 0; - initPreTreatmentReservoirMgmt(); -} + dgReservoirDrainVolumeTargetSet = 0; + + // initialize load cell weights + for ( i = 0; i < NUM_OF_LOAD_CELLS; i++ ) + { + loadCellWeightInGrams[ i ].data = 0.0; + loadCellWeightInGrams[ i ].ovInitData = 0.0; + loadCellWeightInGrams[ i ].ovData = 0.0; + loadCellWeightInGrams[ i ].override = 0; + } + // initialize reservoirs weights + for ( i = 0; i < NUM_OF_DG_RESERVOIRS; i++ ) + { + smFilteredReservoirWeightInGrams[ i ] = 0.0; + lgFilteredReservoirWeightInGrams[ i ] = 0.0; + for ( j = 0; j < SIZE_OF_SMALL_LOAD_CELL_AVG; j++ ) + { + smLoadCellReadings[ i ][ j ] = 0.0; + } + for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) + { + lgLoadCellReadings[ i ][ j ] = 0.0; + } + } + smLoadCellReadingsIdx = 0; + smLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; + smLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + lgLoadCellReadingsIdx = 0; + lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; + lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; +} /*********************************************************************//** * @brief + * The execDGInterfaceMonitor function executes the DG Interface monitoring + * function. Ensures DG is sending fresh data in a timely manner. + * @details Inputs: TBD + * @details Outputs: TBD + * @return none + *************************************************************************/ +void execDGInterfaceMonitor( void ) +{ + // TODO - make sure DG sensor/state data is coming in timely manner (e.g. load cells s/b every 100 ms) +} + +/*********************************************************************//** + * @brief * The initPreTreatmentReservoirMgmt function initializes the pre-treatment * reservoir management state machine. * @details Inputs: none @@ -141,18 +205,6 @@ resUseVolumeMl = 0.0; } -/*********************************************************************//** - * @brief - * The execPreTreatmentReservoirMgmt function executes the state machine for the - * reservoir management during pre-treatment mode. - * @details Inputs: none - * @details Outputs: DG reservoirs (drains & fills) managed. - * @return none - *************************************************************************/ -void execPreTreatmentReservoirMgmt( void ) -{ -} - /*********************************************************************//** * @brief * The execTreatmentReservoirMgmt function executes the state machine for the @@ -187,7 +239,7 @@ { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) { - cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML ); + cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, FALSE ); } } else if ( DG_MODE_DRAI == dgOpMode ) @@ -317,8 +369,8 @@ DG_RESERVOIR_ID_T getDGActiveReservoir( void ) { return dgActiveReservoirSet; -} - +} + /*********************************************************************//** * @brief * The getDGInactiveReservoir function gets the currently inactive reservoir. @@ -331,8 +383,8 @@ DG_RESERVOIR_ID_T inactiveRes = ( DG_RESERVOIR_2 == dgActiveReservoirSet ? DG_RESERVOIR_1 : DG_RESERVOIR_2 ); return inactiveRes; -} - +} + /*********************************************************************//** * @brief * The getDGPressure function gets the latest pressure reported by the DG @@ -403,6 +455,79 @@ return result; } +/*********************************************************************//** + * @brief + * The getLoadCellWeightInGrams function gets the load cell weight. + * @details Inputs: loadCellWeightInGrams + * @details Outputs: none + * @param loadCellID ID of load cell to get + * @return the current load cell weight in grams + *************************************************************************/ +F32 getLoadCellWeightInGrams( LOAD_CELL_T loadCellID ) +{ + F32 result = 0.0; + + if ( loadCellID < NUM_OF_LOAD_CELLS ) + { + if ( OVERRIDE_KEY == loadCellWeightInGrams[ loadCellID ].override ) + { + result = loadCellWeightInGrams[ loadCellID ].ovData; + } + else + { + result = loadCellWeightInGrams[ loadCellID ].data; + } + } + else + { + activateAlarmNoData( ALARM_ID_HD_SOFTWARE_FAULT ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getReservoirWeightSmallFilter function gets the load cell weight + * of the given reservoir after large (8 sample) filter applied. + * @details Inputs: lgFilteredReservoirWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get filtered weight for + * @return the current filtered weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirWeightSmallFilter( DG_RESERVOIR_ID_T resID ) +{ + F32 result = 0.0; + + if ( resID < NUM_OF_DG_RESERVOIRS ) + { + result = smFilteredReservoirWeightInGrams[ resID ]; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getReservoirWeightLargeFilter function gets the load cell weight + * of the given reservoir after large (32 sample) filter applied. + * @details Inputs: lgFilteredReservoirWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get filtered weight for + * @return the current filtered weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirWeightLargeFilter( DG_RESERVOIR_ID_T resID ) +{ + F32 result = 0.0; + + if ( resID < NUM_OF_DG_RESERVOIRS ) + { + result = lgFilteredReservoirWeightInGrams[ resID ]; + } + + return result; +} + /*********************************************************************//** * @brief * The setDGOpMode function sets the latest DG operating mode reported by @@ -530,6 +655,47 @@ dgDrainPumpSpeedSetPtRPM = rpmSetPt; } +/*********************************************************************//** + * @brief + * The setNewLoadCellReadings function sets the latest DG reservoir load cell + * readings sent by the DG (in g or mL). New readings are expected once + * every 100 ms. + * @details Inputs: none + * @details Outputs: loadCellWeightInGrams[], smFilteredReservoirWeightInGrams[], + * lgFilteredReservoirWeightInGrams[] + * @param res1Primary New weight from primary load cell of reservoir 1 + * @param res1Backup New weight from backup load cell of reservoir 1 + * @param res2Primary New weight from primary load cell of reservoir 2 + * @param res2Backup New weight from backup load cell of reservoir 2 + * @return none + *************************************************************************/ +void setNewLoadCellReadings( F32 res1Primary, F32 res1Backup, F32 res2Primary, F32 res2Backup ) +{ + DG_RESERVOIR_ID_T res; + + loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_PRIMARY ].data = res1Primary; + loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_BACKUP ].data = res1Backup; + loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; + loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_BACKUP ].data = res2Backup; + + // feed new weight samples into filters and update moving averages + for ( res = DG_RESERVOIR_1; res < NUM_OF_DG_RESERVOIRS; res++ ) + { + F32 wt = ( res == DG_RESERVOIR_1 ? res1Primary : res2Primary ); + + smLoadCellReadingsTotal[ res ] -= smLoadCellReadings[ res ][ smLoadCellReadingsIdx ]; + lgLoadCellReadingsTotal[ res ] -= lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ]; + smLoadCellReadings[ res ][ smLoadCellReadingsIdx ] = wt; + lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ] = wt; + smLoadCellReadingsTotal[ res ] += wt; + lgLoadCellReadingsTotal[ res ] += wt; + smFilteredReservoirWeightInGrams[ res ] = smLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_SMALL_LOAD_CELL_AVG; + lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; + } + smLoadCellReadingsIdx = INC_WRAP( smLoadCellReadingsIdx, 0, SIZE_OF_SMALL_LOAD_CELL_AVG - 1 ); + lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); +} + /*********************************************************************//** * @brief * The cmdSetDGDialysateTargetTemps function sends a target dialysate @@ -643,18 +809,18 @@ * @brief * The cmdStartDGDrain function sends a drain command message to the DG. * @details Inputs: none - * @details Outputs: drain command sent to DG. + * @details Outputs: drain command sent to DG. * @param drainToVolMl volume (in mL) to drain inactive reservoir to + * @param tareLoadCell flag to tell DG tare load cell or not * @return none *************************************************************************/ -void cmdStartDGDrain( U32 drainToVolMl ) +void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell ) { DRAIN_RESERVOIR_CMD_PAYLOAD_T payload; - DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); - - dgReservoirDrainVolumeTargetSet = drainToVolMl; + payload.drainToVolumeML = drainToVolMl; - payload.tareLoadCells = ( FALSE == resHasBeenTared[ inactiveRes ] ? TRUE : FALSE ); + payload.tareLoadCells = tareLoadCell; + dgReservoirDrainVolumeTargetSet = drainToVolMl; sendDGDrainCommand( &payload ); } @@ -670,5 +836,64 @@ dgWaterSampled = TRUE; sendDGSampleWaterCommand(); } - + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetDialOutLoadCellWeightOverride function overrides the value of the + * load cell sensor with a given weight (in grams). + * @details Inputs: loadCellWeightInGrams[] + * @details Outputs: loadCellWeightInGrams[] + * @param sensor ID of load cell sensor to override weight for + * @param value override weight (in grams) for the given sensor + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDialOutLoadCellWeightOverride( U32 sensor, F32 value ) +{ + BOOL result = FALSE; + + if ( sensor < NUM_OF_LOAD_CELLS ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + loadCellWeightInGrams[ sensor ].ovData = value; + loadCellWeightInGrams[ sensor ].override = OVERRIDE_KEY; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetDialOutLoadCellWeightOverride function resets the override of the + * load cell sensor. + * @details Inputs: loadCellWeightInGrams[] + * @details Outputs: loadCellWeightInGrams[] + * @param sensor ID of load cell sensor to override weight for + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDialOutLoadCellWeightOverride( U32 sensor ) +{ + BOOL result = FALSE; + + if ( sensor < NUM_OF_LOAD_CELLS ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + loadCellWeightInGrams[ sensor ].override = OVERRIDE_RESET; + loadCellWeightInGrams[ sensor ].ovData = loadCellWeightInGrams[ sensor ].ovInitData; + } + } + + return result; +} + /**@}*/ Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -32,19 +32,29 @@ // ********** public definitions ********** -#define DRAIN_RESERVOIR_TO_VOLUME_ML 200 ///< Drain reservoir to this volume (in mL) during treatment. +#define DRAIN_RESERVOIR_TO_VOLUME_ML 200 ///< Drain reservoir to this volume (in mL) during treatment. #ifndef V1_5_SYSTEM -#define FILL_RESERVOIR_TO_VOLUME_ML 1700 ///< Fill reservoir to this volume (in mL) during treatment. +#define FILL_RESERVOIR_TO_VOLUME_ML 1700 ///< Fill reservoir to this volume (in mL) during treatment. #else -#define FILL_RESERVOIR_TO_VOLUME_ML 1300 ///< Fill reservoir to this volume (in mL) during treatment. +#define FILL_RESERVOIR_TO_VOLUME_ML 1300 ///< Fill reservoir to this volume (in mL) during treatment. #endif +/// Enumeration of load cell sensors. +typedef enum Load_Cells +{ + LOAD_CELL_RESERVOIR_1_PRIMARY = 0, ///< Primary load cell for reservoir 1. + LOAD_CELL_RESERVOIR_1_BACKUP, ///< Backup load cell for reservoir 1. + LOAD_CELL_RESERVOIR_2_PRIMARY, ///< Primary load cell for reservoir 2. + LOAD_CELL_RESERVOIR_2_BACKUP, ///< Backup load cell for reservoir 2. + NUM_OF_LOAD_CELLS ///< Number of load cell sensors. +} LOAD_CELL_T; + /// Enumeration of DG reservoirs. typedef enum DG_Reservoirs { - DG_RESERVOIR_1 = 0, ///< Reservoir #1. - DG_RESERVOIR_2, ///< Reservoir #2. - NUM_OF_DG_RESERVOIRS ///< Number of reservoirs. + DG_RESERVOIR_1 = 0, ///< Reservoir #1. + DG_RESERVOIR_2, ///< Reservoir #2. + NUM_OF_DG_RESERVOIRS ///< Number of reservoirs. } DG_RESERVOIR_ID_T; /// Enumeration of DG pressure sensors. @@ -115,11 +125,13 @@ // ********** public function prototypes ********** -void initDGInterface( void ); -void initPreTreatmentReservoirMgmt( void ); -void execPreTreatmentReservoirMgmt( void ); -void initTreatmentReservoirMgmt( void ); -void execTreatmentReservoirMgmt( void ); +void initDGInterface( void ); + +void execDGInterfaceMonitor( void ); + +void initPreTreatmentReservoirMgmt( void ); +void initTreatmentReservoirMgmt( void ); +void execTreatmentReservoirMgmt( void ); DG_OP_MODE_T getDGOpMode( void ); U32 getDGSubMode( void ); @@ -129,6 +141,9 @@ U32 getDGROPumpPressureSetPt( void ); F32 getDGROPumpFlowRateMlMin( void ); U32 getDGDrainPumpRPMSetPt( void ); +F32 getLoadCellWeightInGrams( LOAD_CELL_T loadCellID ); +F32 getReservoirWeightSmallFilter( DG_RESERVOIR_ID_T resID ); +F32 getReservoirWeightLargeFilter( DG_RESERVOIR_ID_T resID ); void setDGOpMode( U32 opMode, U32 subMode ); void setDialysateTemperatureReadings( F32 temp1, F32 temp2 ); @@ -137,17 +152,21 @@ void setDGPressures( F32 roIn, F32 roOut, F32 drainIn, F32 drainOut ); void setDGROPumpData( U32 presSetPt, F32 flowRate ); void setDGDrainPumpData( U32 rpmSetPt ); +void setNewLoadCellReadings( F32 res1Primary, F32 res1Backup, F32 res2Primary, F32 res2Backup ); void cmdSetDGDialysateTargetTemps( F32 primaryHtrTemp, F32 trimmerHtrTemp ); void cmdStartDG( void ); void cmdStopDG( void ); void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ); void cmdStartDGFill( U32 fillToVolMl ); -void cmdStartDGDrain( U32 drainToVolMl ); +void cmdStartDGDrain( U32 drainToVolMl, BOOL tareLoadCell ); void cmdStartDGTrimmerHeater( void ); void cmdStopDGTrimmerHeater( void ); void cmdDGSampleWater( void ); +BOOL testSetDialOutLoadCellWeightOverride( U32 sensor, F32 value ); +BOOL testResetDialOutLoadCellWeightOverride( U32 sensor ); + /**@}*/ #endif Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -ra2bc96881a5fc3d8f779246b2abebf15a8de9384 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision a2bc96881a5fc3d8f779246b2abebf15a8de9384) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -132,7 +132,6 @@ static PUMP_CONTROL_MODE_T dialOutPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Requested control mode for dialysate outlet pump (open or closed loop). static PUMP_CONTROL_MODE_T dialOutPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Currently set control mode for dialysate outlet pump. -static OVERRIDE_F32_T loadCellWeightInGrams[ NUM_OF_LOAD_CELLS ]; ///< Measured weight from load cells. static OVERRIDE_U32_T dialOutDataPublishInterval = { DIAL_OUT_DATA_PUB_INTERVAL, DIAL_OUT_DATA_PUB_INTERVAL, DIAL_OUT_DATA_PUB_INTERVAL, 0 }; ///< Interval (in ms) at which to publish dialysate outlet data to CAN bus. static OVERRIDE_F32_T referenceUFVolumeInMl = { 0.0, 0.0, 0.0, 0 }; ///< Target ultrafiltration volume (in mL). static OVERRIDE_F32_T totalMeasuredUFVolumeInMl = { 0.0, 0.0, 0.0, 0 }; ///< Total measured ultrafiltration volume (in mL). @@ -203,12 +202,6 @@ dopLastMotorHallSensorCounts[ i ] = 0; } - // Initialize load cell weights - for ( i = 0; i < NUM_OF_LOAD_CELLS; i++ ) - { - loadCellWeightInGrams[ i ].data = 0.0; - } - // Initialize dialysate outlet flow PI controller initializePIController( PI_CONTROLLER_ID_ULTRAFILTRATION, MIN_DIAL_OUT_PUMP_PWM_DUTY_CYCLE, DOP_P_COEFFICIENT, DOP_I_COEFFICIENT, @@ -383,30 +376,6 @@ /*********************************************************************//** * @brief - * The setDialOutUFVolumes function sets the ultrafiltration reference and - * measured total volumes (in mL). - * @details Inputs: none - * @details Outputs: loadCellWeightInGrams[] - * @param res1Primary New weight from primary load cell of reservoir 1 - * @param res1Backup New weight from backup load cell of reservoir 1 - * @param res2Primary New weight from primary load cell of reservoir 2 - * @param res2Backup New weight from backup load cell of reservoir 2 - * @return TRUE if successful, FALSE if not - *************************************************************************/ -BOOL setNewLoadCellReadings( F32 res1Primary, F32 res1Backup, F32 res2Primary, F32 res2Backup ) -{ - BOOL result = TRUE; - - loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_PRIMARY ].data = res1Primary; - loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_1_BACKUP ].data = res1Backup; - loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_PRIMARY ].data = res2Primary; - loadCellWeightInGrams[ LOAD_CELL_RESERVOIR_2_BACKUP ].data = res2Backup; - - return result; -} - -/*********************************************************************//** - * @brief * The execDialOutFlowMonitor function executes the dialysate outlet pump * and load cell sensor monitor. Checks are performed. Data is published * at appropriate interval. @@ -1010,37 +979,6 @@ /*********************************************************************//** * @brief - * The getLoadCellWeightInGrams function gets the load cell weight. - * @details Inputs: loadCellWeightInGrams - * @details Outputs: none - * @param loadCellID ID of load cell to get - * @return the current load cell weight in grams - *************************************************************************/ -F32 getLoadCellWeightInGrams( U32 loadCellID ) -{ - F32 result = 0.0; - - if ( loadCellID < NUM_OF_LOAD_CELLS ) - { - if ( OVERRIDE_KEY == loadCellWeightInGrams[ loadCellID ].override ) - { - result = loadCellWeightInGrams[ loadCellID ].ovData; - } - else - { - result = loadCellWeightInGrams[ loadCellID ].data; - } - } - else - { - activateAlarmNoData( ALARM_ID_HD_SOFTWARE_FAULT ); - } - - return result; -} - -/*********************************************************************//** - * @brief * The getTotalTargetDialOutUFVolumeInMl function gets the target UF volume. * @details Inputs: referenceUFVolumeInMl * @details Outputs: none @@ -1515,57 +1453,4 @@ return result; } -/*********************************************************************//** - * @brief - * The testSetDialOutLoadCellWeightOverride function overrides the value of the - * load cell sensor with a given weight (in grams). - * @details Inputs: loadCellWeightInGrams[] - * @details Outputs: loadCellWeightInGrams[] - * @param sensor ID of load cell sensor to override weight for - * @param value override weight (in grams) for the given sensor - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetDialOutLoadCellWeightOverride( U32 sensor, F32 value ) -{ - BOOL result = FALSE; - - if ( sensor < NUM_OF_LOAD_CELLS ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - loadCellWeightInGrams[ sensor ].ovData = value; - loadCellWeightInGrams[ sensor ].override = OVERRIDE_KEY; - } - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetDialOutLoadCellWeightOverride function resets the override of the - * load cell sensor. - * @details Inputs: loadCellWeightInGrams[] - * @details Outputs: loadCellWeightInGrams[] - * @param sensor ID of load cell sensor to override weight for - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetDialOutLoadCellWeightOverride( U32 sensor ) -{ - BOOL result = FALSE; - - if ( sensor < NUM_OF_LOAD_CELLS ) - { - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - loadCellWeightInGrams[ sensor ].override = OVERRIDE_RESET; - loadCellWeightInGrams[ sensor ].ovData = loadCellWeightInGrams[ sensor ].ovInitData; - } - } - - return result; -} - /**@}*/ Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -197,16 +197,16 @@ static OVERRIDE_U32_T valvesPositionOverride[ NUM_OF_VALVES ] = { VALVE_POSITION_C_CLOSE, VALVE_POSITION_C_CLOSE, 0, 0 }; ///< Valves position override -static const U16 valvesControlModesSetBits[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_MODES ] = - { { VDI_SET_PID_BIT_MASK, VDI_SET_BYPASS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, - { VDO_SET_PID_BIT_MASK, VDO_SET_BYPASS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, - { VBA_SET_PID_BIT_MASK, VBA_SET_BYPASS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, - { VBV_SET_PID_BIT_MASK, VBV_SET_BYPASS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control mode set bits +static const U16 VALVE_CONTROL_MODES_SET_BITS[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_MODES ] = + { { VDI_SET_PID_BIT_MASK, VDI_SET_BYPASS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, + { VDO_SET_PID_BIT_MASK, VDO_SET_BYPASS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, + { VBA_SET_PID_BIT_MASK, VBA_SET_BYPASS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, + { VBV_SET_PID_BIT_MASK, VBV_SET_BYPASS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control mode set bits -static const U16 valvesControlModesResetBits[ NUM_OF_VALVES ] = { VDI_RESET_CONTROL_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK, - VBA_RESET_CONTROL_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK }; ///< Valves control modes rest bits +static const U16 VALVE_CONTROL_MODES_RESET_BITS[ NUM_OF_VALVES ] = { VDI_RESET_CONTROL_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK, + VBA_RESET_CONTROL_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK }; ///< Valves control modes rest bits -static const U16 valvesControlStatusBits[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_STATUS ] = +static const U16 VALVE_CONTROL_STATUS_BITS[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_STATUS ] = { { VDI_INIT_STATUS_BIT_MASK, VDI_ENABLE_PID_STATUS_BIT_MASK, VDI_ENABLE_BYPASS_STATUS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, { VDO_INIT_STATUS_BIT_MASK, VDO_ENABLE_PID_STATUS_BIT_MASK, VDO_ENABLE_BYPASS_STATUS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, { VBA_INIT_STATUS_BIT_MASK, VBA_ENABLE_PID_STATUS_BIT_MASK, VBA_ENABLE_BYPASS_STATUS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, @@ -895,8 +895,8 @@ static void setValveControlMode( VALVE_T valve, VALVE_MODE_T mode ) { // Get the set and reset bits for the particular valve - U16 control = valvesControlModesSetBits[ valve ][ mode ]; - U16 reset = valvesControlModesResetBits[ valve ]; + U16 control = VALVE_CONTROL_MODES_SET_BITS[ valve ][ mode ]; + U16 reset = VALVE_CONTROL_MODES_RESET_BITS[ valve ]; // Reset the control bits of the particular valve valvesControlSetBits &= reset; @@ -964,28 +964,28 @@ // Depending on the control mode of the valve, different bit masks will be checked if ( mode == VALVE_CONTROL_MODE_ENABLE_PID ) { - if ( ! ( status & valvesControlStatusBits[ valve ][ VALVE_CONTROL_STATUS_INITIALIZED ] ) ) + if ( ! ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_INITIALIZED ] ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); result = FALSE; } - if ( ! ( status & valvesControlStatusBits[ valve ][ VALVE_CONTROL_STATUS_PID_ENABLED ] ) ) + if ( ! ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_PID_ENABLED ] ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); result = FALSE; } } else if ( mode == VALVE_CONTORL_MODE_ENABLE_BYPASS ) { - if ( ! ( status & valvesControlStatusBits[ valve ][ VALVE_CONTROL_STATUS_BYPASS_ENABLED ] ) ) + if ( ! ( status & VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_BYPASS_ENABLED ] ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); result = FALSE; } } else if ( mode == VALVE_CONTROL_MODE_DISABLE_ALL ) { - if ( ! ( status & ( ~valvesControlStatusBits[ valve ][ VALVE_CONTROL_STATUS_DISABLED ] ) ) ) + if ( ! ( status & ( ~VALVE_CONTROL_STATUS_BITS[ valve ][ VALVE_CONTROL_STATUS_DISABLED ] ) ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_NOT_FUNCTIONAL, (U32)valve, (U32)mode ); result = FALSE; Index: firmware/App/Drivers/InternalADC.c =================================================================== diff -u -ref95a6c8bdfb5ada99e6cffb9627155b6d3cd8c6 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Drivers/InternalADC.c (.../InternalADC.c) (revision ef95a6c8bdfb5ada99e6cffb9627155b6d3cd8c6) +++ firmware/App/Drivers/InternalADC.c (.../InternalADC.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -28,8 +28,8 @@ // ********** private definitions ********** #define MAX_ADC_CHANNELS 24 ///< ADC supports up to 24 channels. -#define SIZE_OF_ROLLING_AVG 16 ///< samples in rolling average calculations. -#define ROLLING_AVG_SHIFT_DIVIDER 4 ///< rolling average shift divider. +#define SIZE_OF_ROLLING_AVG 16 ///< Samples in rolling average calculations. +#define ROLLING_AVG_SHIFT_DIVIDER 4 ///< Rolling average shift divider. /// Mapping from enumerated used ADC channel to processor channel ID. const INT_ADC_CHANNEL_T ADC_CHANNEL_NUM_TO_CHANNEL_ID[ MAX_ADC_CHANNELS ] = @@ -83,7 +83,7 @@ { U32 c,r; - // zero all adc values and stats + // Zero all adc values and stats adcRawReadingsCount = 0; for ( c = 0; c < NUM_OF_INT_ADC_CHANNELS; c++ ) { @@ -98,7 +98,7 @@ } } - // enable interrupt when all channels converted + // Enable interrupt when all channels converted adcEnableNotification( adcREG1, adcGROUP1 ); } @@ -134,7 +134,7 @@ if ( adcRawReadingsCount < NUM_OF_INT_ADC_CHANNELS ) { - // process readings from last conversion + // Process readings from last conversion for ( i = 0; i < adcRawReadingsCount; i++ ) { U32 ch = ADC_CHANNEL_NUM_TO_CHANNEL_ID[ adcRawReadings[ i ].id ]; @@ -151,7 +151,7 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INT_ADC_DATA_OVERRUN, adcRawReadingsCount ) } - // start an adc channel group conversion + // Start an adc channel group conversion adcStartConversion( adcREG1, adcGROUP1 ); } Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -raeb1dea9ea10fcc70ae66023a87b565f29924c07 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision aeb1dea9ea10fcc70ae66023a87b565f29924c07) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -233,17 +233,17 @@ *************************************************************************/ void startDialysis( void ) { - // set last UF timestamp so UF ref is resumed from this time + // Set last UF timestamp so UF ref is resumed from this time lastUFTimeStamp = getMSTimerCount(); - // send dialysate outlet pump latest UF volumes + // Send dialysate outlet pump latest UF volumes setDialOutUFVolumes( refUFVolume, measUFVolume ); - // set valves for dialysis + // Set valves for dialysis setValvePosition( VDI, VALVE_POSITION_B_OPEN ); setValvePosition( VDO, VALVE_POSITION_B_OPEN ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); setValvePosition( VBV, VALVE_POSITION_B_OPEN ); - // restart pumps + // Restart pumps #ifndef RUN_PUMPS_OPEN_LOOP setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); @@ -253,7 +253,7 @@ #endif setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); // TODO - Heparin pump - // tell DG to start heating dialysate + // Tell DG to start heating dialysate cmdStartDGTrimmerHeater(); } @@ -268,12 +268,12 @@ *************************************************************************/ void stopDialysis( void ) { - // stop pumps + // Stop pumps setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); // TODO - stop Heparin pump - // tell DG to stop heating dialysate + // Tell DG to stop heating dialysate cmdStopDGTrimmerHeater(); } @@ -294,7 +294,7 @@ TREATMENT_STATE_T currTreatSubMode = getTreatmentState(); SALINE_BOLUS_STATE_T currSalineBolusState = getSalineBolusState(); - // must be in treatment mode, dialysis sub-mode, saline bolus in idle state in order to start a saline bolus + // Must be in treatment mode, dialysis sub-mode, saline bolus in idle state in order to start a saline bolus if ( currOpMode != MODE_TREA ) { rejReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; @@ -317,7 +317,7 @@ salineBolusStartRequested = TRUE; } - // send response + // Send response sendSalineBolusResponse( accept, rejReason, salineBolusVolume ); } @@ -338,7 +338,7 @@ TREATMENT_STATE_T currTreatSubMode = getTreatmentState(); SALINE_BOLUS_STATE_T currSalineBolusState = getSalineBolusState(); - // must be in treatment mode, dialysis sub-mode, saline bolus in delivery state in order to abort a saline bolus + // Must be in treatment mode, dialysis sub-mode, saline bolus in delivery state in order to abort a saline bolus if ( currOpMode != MODE_TREA ) { rejReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; @@ -357,7 +357,7 @@ salineBolusAbortRequested = TRUE; } - // send response + // Send response sendSalineBolusResponse( accept, rejReason, salineBolusVolume ); } @@ -430,9 +430,9 @@ ( DIALYSIS_UF_STATE == currentDialysisState ) && ( UF_RUNNING_STATE == currentUFState ) ) { result = TRUE; - // set outlet pump to dialysate rate + // Set outlet pump to dialysate rate setDialOutPumpTargetRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // go to UF paused state + // Go to UF paused state currentUFState = UF_PAUSED_STATE; } else @@ -455,9 +455,9 @@ } } - // send response w/ reason code if rejected + // Send response w/ reason code if rejected sendUFPauseResumeResponse( result, rejectReason, currentUFState ); - // send state data immediately for UI update + // Send state data immediately for UI update broadcastTreatmentTimeAndState(); return result; @@ -481,11 +481,11 @@ ( DIALYSIS_UF_STATE == currentDialysisState ) && ( UF_PAUSED_STATE == currentUFState ) ) { result = TRUE; - // set outlet pump to dialysate rate + set UF rate + // Set outlet pump to dialysate rate + set UF rate setDialOutPumpTargetRate( setDialysateFlowRate + FLOAT_TO_INT_WITH_ROUND( setUFRate ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // restart UF time accumulation for reference volume calculation + // Restart UF time accumulation for reference volume calculation lastUFTimeStamp = getMSTimerCount(); - // go to UF paused state + // Go to UF paused state currentUFState = UF_RUNNING_STATE; } else @@ -508,9 +508,9 @@ } } - // send response w/ reason code if rejected + // Send response w/ reason code if rejected sendUFPauseResumeResponse( result, rejectReason, currentUFState ); - // send state data immediately for UI update + // Send state data immediately for UI update broadcastTreatmentTimeAndState(); return result; @@ -525,10 +525,10 @@ *************************************************************************/ void execDialysis( void ) { - // check ultrafiltration max rate and accuracy during dialysis (even when ultrafiltration is paused). + // Check ultrafiltration max rate and accuracy during dialysis (even when ultrafiltration is paused). checkUFAccuracyAndVolume(); - // dialysis state machine + // Dialysis state machine switch ( currentDialysisState ) { case DIALYSIS_START_STATE: @@ -548,7 +548,7 @@ break; } - // publish saline bolus data at set interval (whether we're delivering one or not) + // Publish saline bolus data at set interval (whether we are delivering one or not) publishSalineBolusData(); } @@ -675,14 +675,14 @@ { UF_STATE_T result = UF_PAUSED_STATE; - // calculate UF volumes and provide to dialysate outlet pump controller + // Calculate UF volumes and provide to dialysate outlet pump controller updateUFVolumes(); - // handle saline bolus start request from user + // Handle saline bolus start request from user if ( TRUE == salineBolusStartRequested ) { salineBolusAutoResumeUF = FALSE; - // go to saline bolus state if we can + // Go to saline bolus state if we can if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) { *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; @@ -692,25 +692,18 @@ salineBolusStartRequested = FALSE; } } - // handle auto-resume after saline bolus + // Handle auto-resume after saline bolus else if ( TRUE == salineBolusAutoResumeUF ) { salineBolusAutoResumeUF = FALSE; - // set outlet pump to dialysate rate + set UF rate + // Set outlet pump to dialysate rate + set UF rate setDialOutPumpTargetRate( setDialysateFlowRate + FLOAT_TO_INT_WITH_ROUND( setUFRate ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); - // restart UF time accumulation for reference volume calculation + // Restart UF time accumulation for reference volume calculation lastUFTimeStamp = getMSTimerCount(); - // resume UF + // Resume UF result = UF_RUNNING_STATE; } - // TODO - test code - remove later - if ( TRUE == isStopButtonPressed() ) - { - resumeUF(); - result = UF_RUNNING_STATE; - } - return result; } @@ -730,31 +723,31 @@ U32 newTime = getMSTimerCount(); U32 msSinceLast = calcTimeBetween( lastUFTimeStamp, newTime ); - // update UF time + // Update UF time uFTimeMS += msSinceLast; lastUFTimeStamp = newTime; - // update UF ref volume in UF running state only + // Update UF ref volume in UF running state only refUFVolume += ( ( (F32)msSinceLast / MS_PER_SECOND ) / SEC_PER_MIN ) * setUFRate; - // calculate UF volumes and provide to dialysate outlet pump controller + // Calculate UF volumes and provide to dialysate outlet pump controller updateUFVolumes(); - // if we've reached target UF volume, UF is complete + // If we have reached target UF volume, UF is complete if ( measUFVolume >= maxUFVolumeML ) { result = UF_COMPLETED_STATE; } - // handle saline bolus start request from user + // Handle saline bolus start request from user else if ( TRUE == salineBolusStartRequested ) { if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) { - // since we were doing UF prior to saline bolus, we want to auto-resume when done + // Since we were doing UF prior to saline bolus, we want to auto-resume when done salineBolusAutoResumeUF = TRUE; - // go to UF paused state + // Go to UF paused state result = UF_PAUSED_STATE; - // go to saline bolus state + // Go to saline bolus state *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; } else @@ -763,13 +756,6 @@ } } - // TODO - test code - remove later - if ( TRUE == isStopButtonPressed() ) - { - pauseUF(); - result = UF_PAUSED_STATE; - } - return result; } @@ -786,14 +772,14 @@ { UF_STATE_T result = UF_OFF_STATE; - // calculate UF volumes and provide to dialysate outlet pump controller + // Calculate UF volumes and provide to dialysate outlet pump controller updateUFVolumes(); - // handle saline bolus start request from user + // Handle saline bolus start request from user if ( TRUE == salineBolusStartRequested ) { salineBolusAutoResumeUF = FALSE; - // go to saline bolus state + // Go to saline bolus state if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) { *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; @@ -820,14 +806,14 @@ { UF_STATE_T result = UF_COMPLETED_STATE; - // calculate UF volumes and provide to dialysate outlet pump controller + // Calculate UF volumes and provide to dialysate outlet pump controller updateUFVolumes(); - // handle saline bolus start request from user + // Handle saline bolus start request from user if ( TRUE == salineBolusStartRequested ) { salineBolusAutoResumeUF = FALSE; - // go to saline bolus state + // Go to saline bolus state if ( SALINE_BOLUS_STATE_IDLE == currentSalineBolusState ) { *dialysisState = DIALYSIS_SALINE_BOLUS_STATE; @@ -854,11 +840,11 @@ { SALINE_BOLUS_STATE_T result = SALINE_BOLUS_STATE_IDLE; - // handle saline bolus start request from user + // Handle saline bolus start request from user if ( TRUE == salineBolusStartRequested ) { salineBolusStartRequested = FALSE; - // cmd all pumps to stop + // Cmd all pumps to stop #ifndef RUN_PUMPS_OPEN_LOOP setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); @@ -868,7 +854,7 @@ setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); #endif - // begin saline bolus + // Begin saline bolus result = SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP; } @@ -890,31 +876,31 @@ if ( ( FALSE == isBloodPumpRunning() ) && ( FALSE == isDialInPumpRunning() ) && ( FALSE == isDialOutPumpRunning() ) ) { - // reset bolus data before we start + // Reset bolus data before we start bolusSalineVolumeDelivered = 0.0; bolusSalineVolumeDelivered_Safety = 0.0; bolusSalineMotorCount = 0; bolusSalineLastMotorCount = getBloodPumpMotorCount(); bolusSalineLastVolumeTimeStamp = getMSTimerCount(); - // bypass dialyzer + // Bypass dialyzer setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); - // switch to saline bag + // Switch to saline bag setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); - // start blood pump at saline bolus rate + // Start blood pump at saline bolus rate #ifndef RUN_PUMPS_OPEN_LOOP setBloodPumpTargetFlowRate( SALINE_BOLUS_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); #else setBloodPumpTargetFlowRate( SALINE_BOLUS_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); #endif - // start dialysate inlet pump at re-circ rate + // Start dialysate inlet pump at re-circ rate #ifndef RUN_PUMPS_OPEN_LOOP setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); #else setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); #endif - // begin saline bolus + // Begin saline bolus result = SALINE_BOLUS_STATE_IN_PROGRESS; } @@ -941,7 +927,7 @@ U32 bldPumpMotorCount = getBloodPumpMotorCount(); U32 bldPumpMotorDelta = u32DiffWithWrap( bolusSalineLastMotorCount, bldPumpMotorCount ); - // update saline bolus volumes + // Update saline bolus volumes bolusSalineLastVolumeTimeStamp = getMSTimerCount(); bolusSalineVolumeDelivered += volSinceLastUpdateMl; totalSalineVolumeDelivered += volSinceLastUpdateMl; @@ -958,17 +944,17 @@ } #endif - // determine if we've reached maximum saline delivery volume + // Determine if we have reached maximum saline delivery volume if ( ( totalSalineVolumeDelivered >= (F32)MAX_SALINE_VOLUME_DELIVERED ) ) { result = SALINE_BOLUS_STATE_MAX_DELIVERED; } else { - // determine if bolus is complete + // Determine if bolus is complete if ( bolusSalineVolumeDelivered >= bolusTargetVolume ) { - // if safety thinks we've under-delivered the bolus, throw a fault + // If safety thinks we have under-delivered the bolus, throw a fault if ( bolusSalineVolumeDelivered_Safety < ( bolusTargetVolume * MIN_SALINE_BOLUS_VOLUME_PCT ) ) { #ifndef DISABLE_SALINE_BOLUS_CHECKS @@ -978,13 +964,13 @@ } result = SALINE_BOLUS_STATE_IDLE; } - // user is aborting saline bolus + // User is aborting saline bolus else if ( TRUE == salineBolusAbortRequested ) { salineBolusAbortRequested = FALSE; result = SALINE_BOLUS_STATE_IDLE; } - // determine if safety thinks we've over-delivered the bolus + // Determine if safety thinks we have over-delivered the bolus else if ( bolusSalineVolumeDelivered_Safety > ( bolusTargetVolume * MAX_SALINE_BOLUS_VOLUME_PCT ) ) { #ifndef DISABLE_SALINE_BOLUS_CHECKS @@ -995,27 +981,27 @@ } } - // are we stopping the bolus? + // Are we stopping the bolus? if ( result != SALINE_BOLUS_STATE_IN_PROGRESS ) { - // hard stop blood and dialysate pumps + // Hard stop blood and dialysate pumps signalBloodPumpHardStop(); signalDialInPumpHardStop(); - // send last saline bolus data + // Send last saline bolus data bolusSalineVolumeDelivered = 0.0; salineBolusBroadcastTimerCtr = SALINE_BOLUS_DATA_PUB_INTERVAL; publishSalineBolusData(); - // dialysis back to UF state + // Dialysis back to UF state *dialysisState = DIALYSIS_UF_STATE; - // end dialyzer bypass and resume dialysis if no alarms triggered + // End dialyzer bypass and resume dialysis if no alarms triggered if ( FALSE == errorFound ) { - // resume UF if appropriate + // Resume UF if appropriate if ( TRUE == salineBolusAutoResumeUF ) { currentUFState = UF_RUNNING_STATE; } - // resume dialysis + // Resume dialysis startDialysis(); } } @@ -1036,8 +1022,8 @@ { SALINE_BOLUS_STATE_T result = SALINE_BOLUS_STATE_MAX_DELIVERED; - // this is a terminal state for a given treatment - no more saline may be delivered to patient - // if we get here, pop back to UF + // This is a terminal state for a given treatment - no more saline may be delivered to patient + // If we get here, pop back to UF *dialysisState = DIALYSIS_UF_STATE; return result; @@ -1076,35 +1062,27 @@ *************************************************************************/ static void checkUFAccuracyAndVolume( void ) { - F32 uFMeasRate = measUFVolume - lastUFVolumeChecked; + F32 uFMeasRate = measUFVolume - lastUFVolumeChecked; // Volumes are at start/end of 1 hour period, so implied rate is per hour - // check max UF rate in last hour // TODO - is this check necessary considering next check below is a tighter check on this? -// if ( uFMeasRate > MAX_UF_RATE_ML_PER_HOUR ) -// { -//#ifndef DISABLE_UF_ALARMS -// SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); -//#endif -// } - - // check UF rate diff from target in last hour + // Check UF rate diff from target in last hour if ( uFMeasRate > maxUFRateAccuracyError_Ml_hr ) { #ifndef DISABLE_UF_ALARMS SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); #endif } - // if actively performing ultrafiltration right now, increment timer and see if time to start another 1 hour check period + // If actively performing ultrafiltration right now, increment timer and see if time to start another 1 hour check period if ( UF_RUNNING_STATE == currentUFState ) { if ( ++uFAccuracyCheckTimerCtr >= UF_ACCURACY_CHECK_INTERVAL ) { - // reset for next check interval + // Reset for next check interval lastUFVolumeChecked = measUFVolume; uFAccuracyCheckTimerCtr = 0; } } - // check total UF volume error + // Check total UF volume error if ( ( fabs( refUFVolume - measUFVolume ) ) >= (F32)MAX_UF_ACCURACY_ERROR_ML ) { #ifndef DISABLE_UF_ALARMS @@ -1128,7 +1106,7 @@ DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); F32 latestResVolume = getReservoirWeightSmallFilter( activeRes ); - // calculate UF volumes and provide to dialysate outlet pump controller + // Calculate UF volumes and provide to dialysate outlet pump controller measUFVolume = measUFVolumeFromPriorReservoirs + ( latestResVolume - resStartVolume[ activeRes ] ); resFinalVolume[ activeRes ] = latestResVolume; setDialOutUFVolumes( refUFVolume, measUFVolume ); @@ -1148,7 +1126,7 @@ DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); F32 resVolume = getReservoirWeightLargeFilter( inactiveRes ); - // set starting baseline volume for next reservoir before we switch to it + // Set starting baseline volume for next reservoir before we switch to it resStartVolume[ inactiveRes ] = resVolume; } @@ -1166,7 +1144,7 @@ DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); DG_RESERVOIR_ID_T inactiveRes = ( activeRes == DG_RESERVOIR_1 ? DG_RESERVOIR_2 : DG_RESERVOIR_1 ); - // update UF volume from prior reservoirs per tentative res volume for last reservoir + // Update UF volume from prior reservoirs per tentative res volume for last reservoir measUFVolumeFromPriorReservoirs += ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); } @@ -1184,7 +1162,7 @@ DG_RESERVOIR_ID_T inactiveRes = getDGInactiveReservoir(); F32 resVolume = getReservoirWeightLargeFilter( inactiveRes ); - // update UF volume from prior reservoirs per final res volume for last reservoir a bit after we've switched and reservoir has settled + // Update UF volume from prior reservoirs per final res volume for last reservoir a bit after we have switched and reservoir has settled measUFVolumeFromPriorReservoirs -= ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); resFinalVolume[ inactiveRes ] = resVolume; measUFVolumeFromPriorReservoirs += ( resFinalVolume[ inactiveRes ] - resStartVolume[ inactiveRes ] ); Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r8128289dea98878d92bf170fde1c7145f858baa5 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 8128289dea98878d92bf170fde1c7145f858baa5) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -61,12 +61,18 @@ void transitionToPreTreatmentMode( void ) { treatStartReqReceived = FALSE; + + // Set user alarm recovery actions allowed in this mode + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); + currentPreTreatmentState = PRE_TREATMENT_START_STATE; } /*********************************************************************//** * @brief - * The execFaultMode function executes the Pre-Treatment Mode state machine. + * The execPreTreatmentMode function executes the Pre-Treatment Mode state machine. * @details Inputs: none * @details Outputs: none * @return current state (sub-mode) @@ -147,6 +153,20 @@ /*********************************************************************//** * @brief + * The signalAlarmActionToPreTreatmentMode function executes the given alarm action + * as appropriate while in PreTreatment Mode. + * @details Inputs: none + * @details Outputs: given alarm action executed + * @param action ID of alarm action to execute + * @return none + *************************************************************************/ +void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ) +{ + // TODO - implement +} + +/*********************************************************************//** + * @brief * The handleSelfTestNoCartState function handles self-test with no cartrige. * @details Inputs: none * @details Outputs: home blood pump and dialysate pumps Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r8128289dea98878d92bf170fde1c7145f858baa5 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 8128289dea98878d92bf170fde1c7145f858baa5) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -30,10 +30,6 @@ #ifdef EMC_TEST_BUILD // TODO - test code #include "FPGA.h" #endif -#ifdef RM46_EVAL_BOARD_TARGET - #include "Timers.h" - static U32 start; -#endif /** * @addtogroup HDStandbyMode @@ -73,18 +69,20 @@ *************************************************************************/ void transitionToStandbyMode( void ) { - // re-initialize when transitioning to standby mode + // Re-initialize when transitioning to standby mode initStandbyMode(); initDGInterface(); resetAirTrap(); - // pumps should be off + // Set user alarm recovery actions allowed in this mode + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); + + // Pumps should be off setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#ifdef RM46_EVAL_BOARD_TARGET - start = getMSTimerCount(); -#endif } /*********************************************************************//** @@ -103,11 +101,16 @@ BOOL stop = isStopButtonPressed(); #ifndef RUN_WITHOUT_DG - // state machine to get DG to prep a reservoir so we can start a treatment + if ( TRUE == stop ) + { + activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); + } + + // State machine to get DG to prep a reservoir so we can start a treatment switch ( currentStandbyState ) { case STANDBY_START_STATE: - // temporary test code - TODO - remove later + // Temporary test code - TODO - remove later if ( TRUE == isDGCommunicating() ) { currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; @@ -129,12 +132,12 @@ break; } #else - // state machine to get DG to prep a reservoir so we can start a treatment + // State machine to get DG to prep a reservoir so we can start a treatment switch ( currentStandbyState ) { case STANDBY_START_STATE: currentStandbyState = STANDBY_WAIT_FOR_TREATMENT_STATE; - // temporary test code - TODO - remove later + // Temporary test code - TODO - remove later homeBloodPump(); homeDialInPump(); homeDialOutPump(); @@ -164,33 +167,33 @@ toggle = INC_WRAP( toggle, 0, 3 ); switch ( toggle ) { - case 0: // pumps and valves off + case 0: // Pumps and valves off setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); break; - case 1: // pumps on, valves off + case 1: // Pumps on, valves off setBloodPumpTargetFlowRate( 200, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialInPumpTargetFlowRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( 500, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); break; - case 2: // pumps on, valves on + case 2: // Pumps on, valves on setValvePosition( VDI, VALVE_POSITION_B_OPEN ); setValvePosition( VDO, VALVE_POSITION_B_OPEN ); setValvePosition( VBA, VALVE_POSITION_B_OPEN ); setValvePosition( VBV, VALVE_POSITION_B_OPEN ); break; - case 3: // pumps off, valves on + case 3: // Pumps off, valves on setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); break; - default: // shouldn't get here, reset if we do + default: // Should not get here, reset if we do toggle = 0; setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); @@ -216,13 +219,6 @@ } #endif -#ifdef RM46_EVAL_BOARD_TARGET - if ( TRUE == didTimeout( start, 5000U ) ) - { - requestNewOperationMode( MODE_TPAR ); - } -#endif - return currentStandbyState; } @@ -248,4 +244,18 @@ return result; } +/*********************************************************************//** + * @brief + * The signalAlarmActionToStandbyMode function executes the given alarm action + * as appropriate while in Standby Mode. + * @details Inputs: none + * @details Outputs: given alarm action executed + * @param action ID of alarm action to execute + * @return none + *************************************************************************/ +void signalAlarmActionToStandbyMode( ALARM_ACTION_T action ) +{ + // TODO - implement +} + /**@}*/ Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -ref95a6c8bdfb5ada99e6cffb9627155b6d3cd8c6 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision ef95a6c8bdfb5ada99e6cffb9627155b6d3cd8c6) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -15,7 +15,7 @@ * ***************************************************************************/ -#include // for memcpy() +#include // For memcpy() #include "AlarmLamp.h" #include "BloodFlow.h" @@ -25,10 +25,6 @@ #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SystemCommMessages.h" -#ifdef RM46_EVAL_BOARD_TARGET - #include "Timers.h" - static U32 start; -#endif /** * @addtogroup HDTreatmentParamsMode @@ -43,9 +39,9 @@ typedef struct { CRITICAL_DATA_TYPES_T dataType; ///< Data type for the treatment parameter - CRITICAL_DATAS_T min; ///< minimum of range - CRITICAL_DATAS_T max; ///< maximum of range - CRITICAL_DATAS_T def; ///< default value + CRITICAL_DATAS_T min; ///< Minimum of range + CRITICAL_DATAS_T max; ///< Maximum of range + CRITICAL_DATAS_T def; ///< Default value } TREATMENT_PARAMS_PROPERTIES_T; // ********** private data ********** @@ -75,11 +71,11 @@ { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=8.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_UF_VOLUME }; -// current treatment parameter values +// Current treatment parameter values static CRITICAL_DATA_T treatmentParameters[ NUM_OF_TREATMENT_PARAMS ]; ///< Treatment parameters. static CRITICAL_DATAS_T stagedParams[ NUM_OF_TREATMENT_PARAMS ]; ///< Temporary staged treatment parameters for validation and awaiting user confirmation. -// original treatment parameter values (for those that can be changed during treatment) +// Original treatment parameter values (for those that can be changed during treatment) static ADJ_TREATMENT_PARAMS_T origTreatmentParams; ///< Originally set (before treatment) treatment parameters. static BOOL validTreatParamsReceived = FALSE; ///< Flag indicates user has provided treatment parameters. @@ -119,21 +115,21 @@ *************************************************************************/ void transitionToTreatParamsMode( void ) { - // reset this mode + // Reset this mode initTreatParamsMode(); - // reset all treatment parameters when transitioning to this mode + // Reset all treatment parameters when transitioning to this mode resetAllTreatmentParameters(); validTreatParamsReceived = FALSE; treatParamsConfirmed = FALSE; treatParamsRejected = FALSE; treatmentCancelled = FALSE; - // temporary test code. TODO - remove later -#ifdef RM46_EVAL_BOARD_TARGET - start = getMSTimerCount(); -#endif + // Set user alarm recovery actions allowed in this mode + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); } /*********************************************************************//** @@ -150,20 +146,17 @@ for ( param = 0; param < NUM_OF_TREATMENT_PARAMS; param++ ) { - // set type, range, and default value for each treatment parameter + // Set type, range, and default value for each treatment parameter treatmentParameters[ param ].typ = TREAT_PARAMS_PROPERTIES[ param ].dataType; treatmentParameters[ param ].minimum = TREAT_PARAMS_PROPERTIES[ param ].min; treatmentParameters[ param ].maximum = TREAT_PARAMS_PROPERTIES[ param ].max; treatmentParameters[ param ].defValue = TREAT_PARAMS_PROPERTIES[ param ].def; resetCriticalData( &treatmentParameters[ param ] ); - // set staged parameter values to zero + // Set staged parameter values to zero stagedParams[ param ].uInt = 0; } -#ifndef DISABLE_UI_TREATMENT_WORKFLOW - setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, 0.6 ); -#endif - // zero original parameter values + // Zero original parameter values origTreatmentParams.bloodFlowRate_mL_min = 0; origTreatmentParams.dialysateFlowRate_mL_min = 0; origTreatmentParams.treatmentDuration_min = 0; @@ -241,14 +234,28 @@ /*********************************************************************//** * @brief - * The execFaultMode function executes the Operating Parameters Mode state machine. + * The signalAlarmActionToTreatParamsMode function executes the given alarm action + * as appropriate while in Treatment Parameters Mode. + * @details Inputs: none + * @details Outputs: given alarm action executed + * @param action ID of alarm action to execute + * @return none + *************************************************************************/ +void signalAlarmActionToTreatParamsMode( ALARM_ACTION_T action ) +{ + +} + +/*********************************************************************//** + * @brief + * The execTreatParamsMode function executes the Operating Parameters Mode state machine. * @details Inputs: treatParamsState * @details Outputs: treatParamsState * @return current state (sub-mode) *************************************************************************/ U32 execTreatParamsMode( void ) { - // execute mode state machine + // Execute mode state machine switch ( currentTreatmentParamsState ) { case HD_TREATMENT_PARAMS_MODE_STATE_START: @@ -268,15 +275,6 @@ break; } -#ifdef DISABLE_UI_TREATMENT_WORKFLOW - requestNewOperationMode( MODE_PRET ); -#endif -#ifdef RM46_EVAL_BOARD_TARGET - if ( TRUE == didTimeout( start, 5000U ) ) - { - requestNewOperationMode( MODE_PRET ); - } -#endif return (U32)currentTreatmentParamsState; } @@ -295,14 +293,14 @@ if ( TRUE == treatmentCancelled ) { - // go back to standby mode + // Go back to standby mode requestNewOperationMode( MODE_STAN ); treatmentCancelled = FALSE; } else if ( TRUE == validTreatParamsReceived ) { - // go to wait for user confirmation state + // Go to wait for user confirmation state result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM; validTreatParamsReceived = FALSE; @@ -323,20 +321,20 @@ { HD_TREATMENT_PARAMS_MODE_STATE_T result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM; - // if user confirms treatment parameters, set them + // If user confirms treatment parameters, set them if ( TRUE == treatParamsConfirmed ) { TREATMENT_PARAM_T param; - // set all treatment parameters (except UF volume which is not yet received) + // Set all treatment parameters (except UF volume which is not yet received) for ( param = TREATMENT_PARAM_FIRST_UINT; param < TREATMENT_PARAM_UF_VOLUME; param++ ) { if ( FALSE == setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ) ) { // TODO - should never get here - s/w fault? } } - // retain original settings for treatment that may be adjusted later during treatment + // Retain original settings for treatment that may be adjusted later during treatment origTreatmentParams.bloodFlowRate_mL_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_BLOOD_FLOW ] ).uInt; origTreatmentParams.dialysateFlowRate_mL_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ] ).uInt; origTreatmentParams.treatmentDuration_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ] ).uInt; @@ -345,22 +343,22 @@ origTreatmentParams.venousPressureLowLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ] ).sInt; origTreatmentParams.venousPressureHighLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ] ).sInt; - // go to pre-treatment mode + // Go to pre-treatment mode requestNewOperationMode( MODE_PRET ); treatParamsConfirmed = FALSE; } else if ( TRUE == treatParamsRejected ) { treatParamsRejected = FALSE; - // user rejected last parameter set, so reset them and wait for new set + // User rejected last parameter set, so reset them and wait for new set resetAllTreatmentParameters(); result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_SEND; } else if ( TRUE == treatmentCancelled ) { treatmentCancelled = FALSE; - // go back to standby mode + // Go back to standby mode requestNewOperationMode( MODE_STAN ); } @@ -369,6 +367,36 @@ /*********************************************************************//** * @brief + * The validateAndSetUFVolume function validates received ultrafiltration + * volume treatment parameter. + * @details Inputs: none + * @details Outputs: + * @param uFVolumeMl UF volume (in mL) from UI to validate + * @return TRUE if received UF volume parameter is valid, FALSE if not + *************************************************************************/ +BOOL validateAndSetUFVolume( F32 uFVolumeMl ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + F32 uFVolumeL = uFVolumeMl / (F32)ML_PER_LITER; + + // Validate given UF volume TODO - check dependencies too + accepted = setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, uFVolumeL ); + if ( FALSE == accepted ) + { + rejReason = REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE; + } + + // Respond to set treatment parameters request message + uFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + uFVolumeMl = uFVolumeL * (F32)ML_PER_LITER; + sendUFVolumeSetResponseMsg( accepted, rejReason, uFVolumeMl ); + + return accepted; +} + +/*********************************************************************//** + * @brief * The validateAndSetTreatmentParameters function validates received * treatment parameters. * @details Inputs: none @@ -382,23 +410,23 @@ BOOL paramsAreInRange, paramsAreConsistent; U32 rejReasons[ NUM_OF_TREATMENT_PARAMS ]; - // extract treatment parameters from given payload to staging array so we can more easily work with them + // Extract treatment parameters from given payload to staging array so we can more easily work with them extractTreatmentParamsFromPayload( params ); - // range check each treatment parameter + // Range check each treatment parameter paramsAreInRange = checkTreatmentParamsInRange( &rejReasons[0] ); - // validate dependencies + // Validate dependencies paramsAreConsistent = checkTreatmentParamsDependencies( &rejReasons[0] ); - // determine overall validity of received treatment parameters + // Determine overall validity of received treatment parameters if ( ( TRUE == paramsAreInRange ) && ( TRUE == paramsAreConsistent ) ) { paramsAreInvalid = FALSE; validTreatParamsReceived = TRUE; } - // respond to set treatment parameters request message + // Respond to set treatment parameters request message sendTreatmentParamsResponse( paramsAreInvalid, &rejReasons[0] ); return !paramsAreInvalid; @@ -418,7 +446,7 @@ BOOL result = TRUE; TREATMENT_PARAM_T param; - // range check treatment parameters up to (but not including) UF volume + // Range check treatment parameters up to (but not including) UF volume for ( param = TREATMENT_PARAM_FIRST_UINT; param < TREATMENT_PARAM_UF_VOLUME; param++ ) { BOOL isParamInRange = isTreatmentParamInRange( param, stagedParams[ param ] ); @@ -452,30 +480,30 @@ S32 venousPresLimitDelta = stagedParams[ TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ].sInt - \ stagedParams[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ].sInt; - // check max dialysate volume dependency + // Check max dialysate volume dependency if ( dialysateVolume_mL > MAX_DIALYSATE_VOLUME_ML ) { reasons[ TREATMENT_PARAM_DIALYSATE_FLOW ] = REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE; reasons[ TREATMENT_PARAM_TREATMENT_DURATION ] = REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE; result = FALSE; } - // check Heparin pre-stop vs. treatment duration + // Check Heparin pre-stop vs. treatment duration if ( stagedParams[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].uInt > stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt ) { reasons[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_PRESTOP_EXCEEDS_DURATION; result = FALSE; } - // check arterial alarm limits dependency + // Check arterial alarm limits dependency if ( arterialPresLimitDelta < MIN_PRESSURE_ALARM_LIMIT_DELTA_MMHG ) { reasons[ TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ] = REQUEST_REJECT_REASON_ARTERIAL_PRESSURE_LOW_VS_HIGH; reasons[ TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ] = REQUEST_REJECT_REASON_ARTERIAL_PRESSURE_LOW_VS_HIGH; result = FALSE; } - // check venous alarm limits dependency + // Check venous alarm limits dependency if ( venousPresLimitDelta < MIN_PRESSURE_ALARM_LIMIT_DELTA_MMHG ) { reasons[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ] = REQUEST_REJECT_REASON_VENOUS_PRESSURE_LOW_VS_HIGH; @@ -544,7 +572,7 @@ *************************************************************************/ static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ) { - // pull treatment parameters into data array so we can more easily work with them + // Pull treatment parameters into data array so we can more easily work with them memcpy( &stagedParams[0], &payload, sizeof(TREATMENT_PARAMS_DATA_PAYLOAD_T) ); } @@ -583,7 +611,7 @@ { BOOL result = FALSE; - // validate parameter + // Validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; @@ -613,7 +641,7 @@ { BOOL result = FALSE; - // validate parameter + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; @@ -643,7 +671,7 @@ { BOOL result = FALSE; - // validate parameter + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; @@ -672,7 +700,7 @@ { U32 result = 1; - // validate parameter + // Validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); @@ -700,7 +728,7 @@ { S32 result = 1; - // validate parameter + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); @@ -728,7 +756,7 @@ { F32 result = 1.0; - // validate parameter + // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); @@ -767,7 +795,7 @@ { if ( TRUE == isTestingActivated() ) { - // set parameter per its type + // Set parameter per its type if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) { result = setTreatmentParameterU32( param, value.uInt ); Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r34767560b0e6574c26f5b86628e12f6bdddbd760 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 34767560b0e6574c26f5b86628e12f6bdddbd760) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -19,7 +19,8 @@ #define __ALARM_MGMT_C__ -#include "AlarmLamp.h" +#include "AlarmLamp.h" +#include "FPGA.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -31,51 +32,74 @@ */ // ********** 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 ) -#define ALARM_STATUS_PUBLISH_INTERVAL (250 / TASK_GENERAL_INTERVAL) ///< Default interval to publish alarm status data. - #define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. +#define ALARM_SILENCE_REQUESTED 1 ///< User cmd to request alarm silence (1=silence, 0=cancel silence). -#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. +#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. -// *** This declaration will cause a compiler error if alarmTable does not have same # of alarms as the Alarm_List enumeration. +// *** 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 ) ]; /// 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 assignment for backup alarm audio enable -#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 ///< pin SPI3-CS0 - re-purposed as output GPIO for back audio enable. -// backup alarm audio enable/disable macros +// Pin assignment for backup alarm audio enable +#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 ///< Pin SPI3-CS0 - re-purposed as output GPIO for back audio enable. +// 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 CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. + +/// Alarm priority ranking record. +typedef struct +{ + ALARM_ID_T alarmID; ///< ID of highest priority alarm in this priority category + U32 subRank; ///< Sub-rank of this alarm + U32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered +} ALARM_PRIORITY_RANKS_T; // ********** private data ********** -/// interval (in ms) 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 }; - static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. -static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< table - current state of each alarm -static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< table - when alarm became active for each alarm (if active) or zero (if inactive) -static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. -static ALARM_ID_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; ///< FIFO - first activated alarm in each alarm priority category. +/// 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 ]; + +/// Record for the current composite alarm status. +static COMP_ALARM_STATUS_T alarmStatus; + +/// FIFO - first activated or highest sub-rank alarm in each alarm priority category. +static ALARM_PRIORITY_RANKS_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; + +/// 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 updateAlarmsState( void ); -static void setAlarmLampAndAudio( void ); +static void setAlarmLamp( void ); +static void setAlarmAudio( void ); static void updateAlarmsSilenceStatus( void ); static void handleAlarmEscalations( void ); static void updateAlarmsFlags( void ); - + +static void clearAllRecoverableAlarms( void ); static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); -static U32 getAlarmStartTime( U32 alarmID ); -static U32 getPublishAlarmStatusInterval( void ); +static U32 getAlarmStartTime( ALARM_ID_T alarmID ); /*********************************************************************//** * @brief @@ -89,45 +113,51 @@ ALARM_PRIORITY_T p; ALARM_ID_T a; - // disable backup audio + // Disable backup audio CLR_BACKUP_AUDIO_ENABLE(); - // initialize alarm states and start time stamps + // Initialize alarm states and start time stamps for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { - alarmIsActive[ a ] = FALSE; + 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 + // Initialize alarm FIFOs for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { - alarmPriorityFIFO[ p ] = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ p ].alarmID = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ p ].subRank = LOWEST_ALARM_SUB_RANK; + alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; } - // initialize composite alarm state + // Initialize composite alarm state alarmStatus.alarmsState = ALARM_PRIORITY_NONE; alarmStatus.alarmsSilenced = FALSE; alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmsEscalatesIn = 0; - alarmStatus.alarmTop = ALARM_ID_NO_ALARM; + alarmStatus.alarmTop = ALARM_ID_NO_ALARM; + alarmStatus.topAlarmConditionnDetected = FALSE; alarmStatus.systemFault = FALSE; - alarmStatus.stop = FALSE; + alarmStatus.stop = FALSE; + alarmStatus.lampOn = FALSE; alarmStatus.noClear = FALSE; alarmStatus.noResume = FALSE; alarmStatus.noRinseback = FALSE; alarmStatus.noEndTreatment = FALSE; alarmStatus.noNewTreatment = FALSE; + alarmStatus.usrACKRequired = FALSE; } /*********************************************************************//** * @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: alarmStatusTable[], alarmTable[] + * @details Inputs: alarmStatusTable[], ALARM_TABLE[] * @details Outputs: alarmStatus * @return none *************************************************************************/ @@ -137,10 +167,12 @@ updateAlarmsState(); updateAlarmsFlags(); updateAlarmsSilenceStatus(); - setAlarmLampAndAudio(); - // publish alarm status at interval - if ( ++alarmStatusPublicationTimerCounter >= getPublishAlarmStatusInterval() ) - { + // Publish alarm status at interval + if ( ++alarmStatusPublicationTimerCounter >= ALARM_STATUS_PUBLISH_INTERVAL ) + { + // Lamp and audio timing sync'd with broadcast so UI can stay in sync with lamp rhythm + setAlarmLamp(); + setAlarmAudio(); broadcastAlarmStatus( alarmStatus ); alarmStatusPublicationTimerCounter = 0; } @@ -156,24 +188,33 @@ *************************************************************************/ static void activateAlarm( ALARM_ID_T alarm ) { - // verify given alarm + // Verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { - // no need to do anything if alarm is already active + // No need to do anything if alarm is already active if ( FALSE == alarmIsActive[ alarm ] ) { - // if alarms silenced, end silence due to new alarm + // If alarms silenced, end silence due to new alarm alarmStatus.alarmsSilenced = FALSE; - // if alarm is a fault, request transition to fault mode + // If alarm is a fault, request transition to fault mode if ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) { -#ifndef RM46_EVAL_BOARD_TARGET requestNewOperationMode( MODE_FAUL ); -#endif } - // activate alarm - alarmIsActive[ alarm ] = TRUE; - alarmStartedAt[ alarm ].data = getMSTimerCount(); + // Activate alarm + alarmIsActive[ alarm ] = TRUE; + alarmStartedAt[ alarm ].data = getMSTimerCount(); + alarmIsDetected[ alarm ] = TRUE; + // If alarm has clear condition immediately property, clear condition now + if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) + { + clearAlarmCondition( alarm ); + } + // If alarm has stop property, signal stop now + if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) + { + initiateAlarmAction( ALARM_ACTION_STOP ); + } } } else @@ -194,7 +235,7 @@ *************************************************************************/ void activateAlarmNoData( ALARM_ID_T alarm ) { - // broadcast alarm and data if alarm not already active + // Broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA ); @@ -227,7 +268,7 @@ *************************************************************************/ void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) { - // broadcast alarm and data if alarm not already active + // Broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, alarmData, BLANK_ALARM_DATA ); @@ -261,7 +302,7 @@ *************************************************************************/ void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ) { - // broadcast alarm and data if alarm not already active + // Broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, alarmData1, alarmData2 ); @@ -279,33 +320,59 @@ } #endif #endif -} - +} + +/*********************************************************************//** + * @brief + * The clearAlarmCondition function clears a given alarm's condition detected + * flag. Also an alarm message is broadcast to the rest of the system. + * @details Inputs: none + * @details Outputs: alarmIsDetected[] + * @param alarm ID of alarm to clear condition for + * @return none + *************************************************************************/ +void clearAlarmCondition( ALARM_ID_T alarm ) +{ + // Verify given alarm + if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) + { + // Clear alarm condition and broadcast alarm condition clear if not already cleared + if ( TRUE == alarmIsDetected[ alarm ] ) + { + alarmIsDetected[ alarm ] = FALSE; + broadcastAlarmConditionCleared( alarm ); + } + } +} + /*********************************************************************//** * @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[] + * @details Outputs: AlarmStatusTable[], alarmIsActive[], alarmStartedAt[], + * alarmIsDetected[] * @param alarm ID of alarm to clear * @return none *************************************************************************/ void clearAlarm( ALARM_ID_T alarm ) { - // verify given alarm + // Verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { - // verify alarm can be cleared + // Verify alarm can be cleared if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) { - // clear alarm and broadcast alarm clear if not already cleared + // Clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ] ) { broadcastAlarmCleared( alarm ); - alarmIsActive[ alarm ] = FALSE; + alarmIsActive[ alarm ] = FALSE; + alarmIsDetected[ alarm ] = FALSE; + alarmStartedAt[ alarm ].data = 0; - // clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ ALARM_TABLE[ alarm ].alarmPriority ] == alarm ) + // Clear FIFO if this alarm was in it + if ( alarmPriorityFIFO[ ALARM_TABLE[ alarm ].alarmPriority ].alarmID == alarm ) { resetAlarmPriorityFIFO( ALARM_TABLE[ alarm ].alarmPriority ); } @@ -329,6 +396,120 @@ } } +/*********************************************************************//** + * @brief + * The setAlarmUserActionEnabled function enables/disables specific alarm + * recovery user actions while in specific modes. Ack option is always + * potentially enabled - automatically enabled as appropriate by updateAlarmsFlags(). + * @details Inputs: none + * @details Outputs: + * @param action ID of user alarm recovery action to enable/disable + * @param enabled set to TRUE to enable action, FALSE to disable + * @return none + *************************************************************************/ +void setAlarmUserActionEnabled( ALARM_USER_ACTION_T action, BOOL enabled ) +{ + if ( action < NUMBER_OF_ALARM_USER_ACTIONS ) + { + alarmUserRecoveryActionEnabled[ action ] = enabled; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_USER_ACTION, (U32)action ) + } +} + +/*********************************************************************//** + * @brief + * The signalAlarmSilence function handles an alarm silence request from + * the user. + * @details Inputs: none + * @details Outputs: alarm silence status updated + * @param cmd ID of user command (1=silence, 0=cancel silence) + * @return none + *************************************************************************/ +void signalAlarmSilence( U32 cmd ) +{ + if ( ALARM_SILENCE_REQUESTED == cmd ) + { + if ( FALSE == alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenced = TRUE; + alarmStatus.alarmsSilenceStart = getMSTimerCount(); + alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS; + } + } + else + { + if ( TRUE == alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenced = FALSE; + alarmStatus.alarmsSilenceStart = 0; + alarmStatus.alarmsSilenceExpiresIn = 0; + } + } +} + +/*********************************************************************//** + * @brief + * The signalAlarmUserActionInitiated function clears all non-recoverable alarms + * and initiates selected user action. + * @details Inputs: none + * @details Outputs: + * @param action ID of user's selected action to initiate + * @return none + *************************************************************************/ +void signalAlarmUserActionInitiated( ALARM_USER_ACTION_T action ) +{ + // Validate given action + if ( action < NUMBER_OF_ALARM_USER_ACTIONS ) + { + ALARM_ID_T a = alarmStatus.alarmTop; + + if ( ALARM_USER_ACTION_ACK == action ) + { + // If user acknowledged top alarm, just clear that alarm + if ( TRUE == ALARM_TABLE[ a ].alarmUserAckRequired ) + { + clearAlarm( a ); + } + // Otherwise we must be in mode/state where ack was only option - so clear all like other options + else + { + clearAllRecoverableAlarms(); + } + } + else + { + clearAllRecoverableAlarms(); + } + } + + // Initiate user selected action + switch ( action ) + { + case ALARM_USER_ACTION_RESUME: + initiateAlarmAction( ALARM_ACTION_RESUME ); + break; + + case ALARM_USER_ACTION_RINSEBACK: + initiateAlarmAction( ALARM_ACTION_RINSEBACK ); + break; + + case ALARM_USER_ACTION_END_TREATMENT: + initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); + break; + + case ALARM_USER_ACTION_ACK: + initiateAlarmAction( ALARM_ACTION_ACK ); + break; + + default: + // TODO - s/w fault? + break; + } +} + /*********************************************************************//** * @brief * The isAlarmActive function determines whether a given alarm is currently @@ -362,7 +543,7 @@ * @brief * The isAlarmRecoverable function determines whether a given alarm is * recoverable. -* @details Inputs: alarmTable[] +* @details Inputs: ALARM_TABLE[] * @details Outputs: none * @param alarm ID of alarm to check * @return TRUE if given alarm is recoverable, FALSE if not @@ -373,6 +554,22 @@ return result; } + +/*********************************************************************//** + * @brief +* The setAlarmAudioVolume function sets the current alarm audio volume level. +* @details Inputs: none +* @details Outputs: alarmAudioVolumeLevel +* @param volumeLevel level of volume requested (1..5) +* @return none +*************************************************************************/ +void setAlarmAudioVolume( U32 volumeLevel ) +{ + if ( ( volumeLevel > 0 ) && ( volumeLevel <= MAX_ALARM_VOLUME_LEVEL ) ) + { // Convert volume level to attenuation level + alarmAudioVolumeLevel = MAX_ALARM_VOLUME_LEVEL - volumeLevel; + } +} /*********************************************************************//** * @brief @@ -382,7 +579,7 @@ * @param alarmID ID of alarm to check * @return The start time stamp of given alarm ID *************************************************************************/ -static U32 getAlarmStartTime( U32 alarmID ) +static U32 getAlarmStartTime( ALARM_ID_T alarmID ) { U32 result = 0; @@ -419,40 +616,63 @@ ALARM_ID_T a; BOOL faultsActive = FALSE; - // update FIFOs per active alarms table + // 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; - if ( ALARM_ID_NO_ALARM == alarmPriorityFIFO[ almPriority ] ) - { - alarmPriorityFIFO[ almPriority ] = a; - } - highestPriority = MAX( almPriority, highestPriority ); + ALARM_PRIORITY_T almPriority = ALARM_TABLE[ a ].alarmPriority; + U32 subRank = ALARM_TABLE[ a ].alarmSubRank; + U32 msSinceTriggered = calcTimeSince( getAlarmStartTime( a ) ); + + // See if this alarm is higher rank than highest active alarm in this priority category so far + if ( subRank <= alarmPriorityFIFO[ almPriority ].subRank ) + { + // If sub-rank is a tie, see which alarm was triggered first + if ( subRank == alarmPriorityFIFO[ almPriority ].subRank ) + { + if ( msSinceTriggered > alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS ) + { + alarmPriorityFIFO[ almPriority ].alarmID = a; + alarmPriorityFIFO[ almPriority ].subRank = subRank; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + } + } + // Otherwise, this alarm simply outranks current candidate and wins outright + else + { + alarmPriorityFIFO[ almPriority ].alarmID = a; + alarmPriorityFIFO[ almPriority ].subRank = subRank; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + } + } + // 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; } } } - // update alarm to display per highest priority FIFO + // Update alarm to display per highest priority FIFO alarmStatus.alarmsState = highestPriority; - alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ]; + alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; alarmStatus.systemFault = faultsActive; } /*********************************************************************//** * @brief - * The setAlarmLampAndAudio function sets the alarm lamp and audio patterns - * according to the current state of alarms. + * 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 setAlarmLampAndAudio( void ) -{ +static void setAlarmLamp( void ) +{ + // Set alarm lamp pattern to appropriate pattern for current alarm state if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) { switch ( alarmStatus.alarmsState ) @@ -485,45 +705,52 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) break; } - alarmStatus.lampOn = getAlarmLampOn(); } + + // Execute alarm lamp controller + execAlarmLamp(); + + // Set lamp on flag to match current state of alarm lamp + if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) + { + alarmStatus.lampOn = getAlarmLampOn(); + } else { alarmStatus.lampOn = FALSE; } - - if ( TRUE == alarmStatus.alarmsSilenced ) - { - // TODO - no audio - } - else // alarms not silenced - { - switch ( alarmStatus.alarmsState ) - { - case ALARM_PRIORITY_NONE: - // TODO - no audio - break; - - case ALARM_PRIORITY_LOW: - // TODO - low priority audio - break; - - case ALARM_PRIORITY_MEDIUM: - // TODO - medium priority audio - break; - - case ALARM_PRIORITY_HIGH: - // TODO - high priority audio - break; - - default: - // TODO - high priority audio - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - break; - } - } } +/*********************************************************************//** + * @brief + * The setAlarmAudio function sets the alarm audio pattern according to + * the current state of alarms. + * @details Inputs: none + * @details Outputs: Alarm audio patter set according to current alarms status. + * @return none + *************************************************************************/ +static void setAlarmAudio( void ) +{ + if ( TRUE == alarmStatus.alarmsSilenced ) + { + setAlarmAudioState( ALARM_PRIORITY_NONE, alarmAudioVolumeLevel ); + } + else // Alarms not silenced + { + if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) + { +#ifndef DISABLE_ALARM_AUDIO + setAlarmAudioState( alarmStatus.alarmsState, alarmAudioVolumeLevel ); +#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 ); + } + } +} + /*********************************************************************//** * @brief * The updateAlarmsSilenceStatus function updates the alarms silence state. @@ -533,7 +760,7 @@ *************************************************************************/ static void updateAlarmsSilenceStatus( void ) { - // if alarms not silenced, reset alarms silence related properties + // If alarms not silenced, reset alarms silence related properties if ( TRUE != alarmStatus.alarmsSilenced ) { alarmStatus.alarmsSilenceExpiresIn = 0; @@ -551,7 +778,7 @@ { alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; } - // if alarms silence expires, end it + // If alarms silence expires, end it if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) { alarmStatus.alarmsSilenced = FALSE; @@ -562,7 +789,7 @@ /*********************************************************************//** * @brief * The handleAlarmEscalations function handles alarm escalation. - * @details Inputs: alarmIsActive[], alarmTable[] + * @details Inputs: alarmIsActive[], ALARM_TABLE[] * @details Outputs: alarm(s) escalated when appropriate * @return none *************************************************************************/ @@ -572,42 +799,42 @@ ALARM_ID_T nextAlarmToEscalate = ALARM_ID_NO_ALARM; ALARM_ID_T a; - // update escalations + // Update escalations for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { if ( TRUE == alarmIsActive[ a ] ) { - // does active alarm escalate? + // Does active alarm escalate? if ( ALARM_ID_NO_ALARM != ALARM_TABLE[ a ].alarmEscalatesTo ) { S32 msRemaining = (S32)ALARM_TABLE[ a ].alarmEscalatesAfter - (S32)calcTimeSince( getAlarmStartTime( a ) ); S32 secsRemaining = ( msRemaining / MS_PER_SECOND ) + 1; - // time to escalate? + // Time to escalate? if ( msRemaining <= 0 ) { activateAlarmNoData( ALARM_TABLE[ a ].alarmEscalatesTo ); clearAlarm( a ); } else - { // no candidates for alarm escalation yet? + { // No candidates for alarm escalation yet? if ( ALARM_ID_NO_ALARM == nextAlarmToEscalate ) { secsToEscalate = secsRemaining; nextAlarmToEscalate = a; } - // sooner candidate for alarm escalation? + // Sooner candidate for alarm escalation? else if ( secsRemaining < secsToEscalate ) { secsToEscalate = secsRemaining; nextAlarmToEscalate = a; } } - } // if alarm escalates - } // if alarm active - } // alarm table loop + } // If alarm escalates + } // If alarm active + } // Alarm table loop - // update alarm escalation properties + // Update alarm escalation properties if ( TRUE == alarmStatus.systemFault || ALARM_ID_NO_ALARM == nextAlarmToEscalate ) { alarmStatus.alarmsToEscalate = FALSE; @@ -637,32 +864,95 @@ BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; BOOL noNewTreatment = FALSE; - ALARM_ID_T a; + BOOL usrAckReq = FALSE; + ALARM_ID_T a; - // determine alarm flags + // 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 ); - noResume = ( TRUE == ALARM_TABLE[ a ].alarmNoResume ? TRUE : noResume ); - noRinseback = ( TRUE == ALARM_TABLE[ a ].alarmNoRinseback ? TRUE : noRinseback ); - noEndTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoEndTreatment ? TRUE : noEndTreatment ); - noNewTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoNewTreatment ? TRUE : noNewTreatment ); - - } // if alarm active - } // alarm table loop - - // set updated alarm flags + noClear = ( TRUE == ALARM_TABLE[ a ].alarmNoClear ? TRUE : noClear ); + noNewTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoNewTreatment ? TRUE : noNewTreatment ); + // Set user alarm recovery actions allowed flags + 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 ); + } + else + { + noEndTreatment = TRUE; + } + } // If alarm active + } // Alarm table loop + + // If top alarm condition not cleared, block resume and rinseback flags + if ( TRUE == alarmStatus.topAlarmConditionnDetected ) + { + noResume = TRUE; + noRinseback = TRUE; + } + + // 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 ) ) ) + { + usrAckReq = TRUE; + noResume = TRUE; + noRinseback = TRUE; + noEndTreatment = TRUE; + } + + // Set updated alarm flags alarmStatus.systemFault = systemFault; alarmStatus.stop = stop; alarmStatus.noClear = noClear; alarmStatus.noResume = noResume; alarmStatus.noRinseback = noRinseback; alarmStatus.noEndTreatment = noEndTreatment; alarmStatus.noNewTreatment = noNewTreatment; + alarmStatus.usrACKRequired = usrAckReq; +} + +/*********************************************************************//** + * @brief + * The clearAllRecoverableAlarms function clears all currently active + * recoverable alarms. + * @details Inputs: ALARM_TABLE[] + * @details Outputs: All currently active recoverable alarms are cleared + * @return none + *************************************************************************/ +static void clearAllRecoverableAlarms( void ) +{ + ALARM_ID_T a = alarmStatus.alarmTop; + + for ( a = ALARM_ID_HD_SOFTWARE_FAULT; a < NUM_OF_ALARM_IDS; a++ ) + { + // Is alarm recoverable? + if ( FALSE == ALARM_TABLE[ a ].alarmNoClear ) + { + clearAlarm( a ); + } + } } /*********************************************************************//** @@ -676,94 +966,27 @@ *************************************************************************/ static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) { - // verify priority + // Verify priority if ( priority < NUM_OF_ALARM_PRIORITIES ) { - alarmPriorityFIFO[ priority ] = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ priority ].alarmID = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ priority ].subRank = LOWEST_ALARM_SUB_RANK; + alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = 0; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) } } -/*********************************************************************//** - * @brief - * The getPublishAlarmStatusInterval function gets the alarm status - * publication interval. - * @details Inputs: alarmStatusPublishInterval - * @details Outputs: none - * @return the current alarm status publication interval (in ms). - *************************************************************************/ -U32 getPublishAlarmStatusInterval( void ) -{ - U32 result = alarmStatusPublishInterval.data; - - if ( OVERRIDE_KEY == alarmStatusPublishInterval.override ) - { - result = alarmStatusPublishInterval.ovData; - } - - return result; -} - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief - * The testSetAlarmStatusPublishIntervalOverride function overrides the - * alarm status publish interval. - * @details Inputs: none - * @details Outputs: alarmStatusPublishInterval - * @param value override blood flow data publish interval with (in ms) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ) -{ - BOOL result = FALSE; - - // verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - U32 intvl = value / TASK_GENERAL_INTERVAL; - - result = TRUE; - alarmStatusPublishInterval.ovData = intvl; - alarmStatusPublishInterval.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetAlarmStatusPublishIntervalOverride function resets the override - * of the alarm status publish interval. - * @details Inputs: none - * @details Outputs: alarmStatusPublishInterval - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetAlarmStatusPublishIntervalOverride( void ) -{ - BOOL result = FALSE; - - // verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - alarmStatusPublishInterval.override = OVERRIDE_RESET; - alarmStatusPublishInterval.ovData = alarmStatusPublishInterval.ovInitData; - } - - return result; -} - -/*********************************************************************//** - * @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. @@ -779,7 +1002,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { - // verify tester has logged in with HD + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { if ( TRUE == state ) @@ -812,7 +1035,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { - // verify tester has logged in with HD + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { result = TRUE; @@ -839,7 +1062,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { - // verify tester has logged in with HD + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { U32 tim = getMSTimerCount(); @@ -871,7 +1094,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { - // verify tester has logged in with HD + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { result = TRUE; @@ -897,24 +1120,24 @@ { BOOL result = FALSE; - // verify key + // Verify key if ( SUPERVISOR_ALARM_KEY == key ) { - // verify tester has logged in with HD + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { ALARM_ID_T a; - // clear all active alarms + // Clear all active alarms for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { if ( TRUE == alarmIsActive[ a ] ) { broadcastAlarmCleared( a ); alarmIsActive[ a ] = FALSE; alarmStartedAt[ a ].data = 0; - // clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ ALARM_TABLE[ a ].alarmPriority ] == a ) + // Clear FIFO if this alarm was in it + if ( alarmPriorityFIFO[ ALARM_TABLE[ a ].alarmPriority ].alarmID == a ) { resetAlarmPriorityFIFO( ALARM_TABLE[ a ].alarmPriority ); } Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -rbd1ef41547aab439201897e2dcc873479a468c0a -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision bd1ef41547aab439201897e2dcc873479a468c0a) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -33,7 +33,25 @@ // ********** public definitions ********** #include "AlarmDefs.h" - + +/// Interval (in ms) at which alarm lamp and audio control will be executed. +#define ALARM_LAMP_AND_AUDIO_CONTROL_INTERVAL_MS 250 + +#define MAX_ALARM_VOLUME_LEVEL 5 +#define MAX_ALARM_VOLUME_ATTENUATION 4 +#define MIN_ALARM_VOLUME_ATTENUATION 0 + +/// Enumeration of alarm actions. +typedef enum Alarm_Actions +{ + ALARM_ACTION_STOP = 0, ///< Alarm state requests HD in safe state (pumps stopped, heater off, valves in safe state) + ALARM_ACTION_RESUME, ///< User selected resume from alarm recovery options + ALARM_ACTION_RINSEBACK, ///< User selected rinseback from alarm recovery options + ALARM_ACTION_END_TREATMENT, ///< User selected end treatment from alarm recovery options + ALARM_ACTION_ACK, ///< User selected Ack from alarm recovery options + NUMBER_OF_ALARM_ACTIONS ///< Number of alarm actions +} ALARM_ACTION_T; + /// Alarm data types list. typedef enum Alarm_Data_Types { @@ -49,22 +67,23 @@ /// Record structure for detailing the properties of the current composite alarm status. typedef struct { - ALARM_PRIORITY_T alarmsState; ///< current alarm priority level - BOOL alarmsSilenced; ///< alarms are currently silenced? - U32 alarmsSilenceStart; ///< time stamp for when alarms were silenced (ms) - U32 alarmsSilenceExpiresIn; ///< time until alarm silence expires (seconds) - BOOL alarmsToEscalate; ///< are any active alarms due to escalate (should UI show count down timer?) - U32 alarmsEscalatesIn; ///< time until alarm will escalate (seconds) - ALARM_ID_T alarmTop; ///< ID of current top alarm that will drive lamp/audio and UI should be displaying right now - BOOL systemFault; ///< a system fault is active? - BOOL stop; ///< we should be in controlled stop right now - BOOL noClear; ///< no recovery will be possible - BOOL noResume; ///< treatment may not be resumed at this time - BOOL noRinseback; ///< rinseback may not be initiated at this time - BOOL noEndTreatment; ///< ending the treatment is not an option at this time - BOOL noNewTreatment; ///< no new treatments may be started even if current treatment is ended - BOOL bypassDialyzer; ///< the dialyzer should be bypassed at this time - BOOL lampOn; ///< the alarm lamp is on + ALARM_PRIORITY_T alarmsState; ///< Current alarm priority level + BOOL alarmsSilenced; ///< Alarms are currently silenced? + U32 alarmsSilenceStart; ///< Time stamp for when alarms were silenced (ms) + U32 alarmsSilenceExpiresIn; ///< Time until alarm silence expires (seconds) + BOOL alarmsToEscalate; ///< Are any active alarms due to escalate (should UI show count down timer?) + U32 alarmsEscalatesIn; ///< Time until alarm will escalate (seconds) + ALARM_ID_T alarmTop; ///< ID of current top alarm that will drive lamp/audio and UI should be displaying right now + BOOL topAlarmConditionnDetected; ///< 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 + BOOL noResume; ///< Treatment may not be resumed at this time + BOOL noRinseback; ///< Rinseback may not be initiated at this time + BOOL noEndTreatment; ///< Ending the treatment is not an option at this time + BOOL noNewTreatment; ///< No new treatments may be started even if current treatment is ended + BOOL usrACKRequired; ///< The user must acknowledge top alarm + BOOL lampOn; ///< The alarm lamp is on } COMP_ALARM_STATUS_T; /// Record structure for unsigned integer alarm data. @@ -116,7 +135,7 @@ U32 alarmTop; ///< ID of top active alarm U32 escalatesIn; ///< Top active alarm escalates in this many seconds U32 silenceExpiresIn; ///< Silencing of alarms expires in this many seconds - U16 alarmsFlags; ///< bit flags: 1 = true, 0 = false for each bit flag + U16 alarmsFlags; ///< Bit flags: 1 = true, 0 = false for each bit flag } ALARM_COMP_STATUS_PAYLOAD_T; #pragma pack(pop) @@ -165,18 +184,18 @@ 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____AVAILABLE_1, - SW_FAULT_ID____AVAILABLE_2, + 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____AVAILABLE_3, - SW_FAULT_ID____AVAILABLE_4, + 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____AVAILABLE_5, + SW_FAULT_ID_MODE_TREATMENT_INVALID_ALARM_ACTION, SW_FAULT_ID_MODE_PRIME_RESERVOIR_MGMT_INVALID_STATE, SW_FAULT_ID_DIALYSIS_INVALID_STATE, // 55 SW_FAULT_ID_DIALYSIS_INVALID_UF_STATE, @@ -217,6 +236,8 @@ SW_FAULT_ID_DIALYSIS_INVALID_SALINE_BOLUS_STATE, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, SW_FAULT_ID_MODE_PRE_TREATMENT_PRIME_INVALID_STATE, + SW_FAULT_ID_SYSTEM_COMM_INVALID_FRAME_SIZE, + SW_FAULT_ID_SYSTEM_CMMM_CAN_TRANSMIT_REJECTED, // 95 NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; @@ -228,13 +249,16 @@ void activateAlarmNoData( ALARM_ID_T alarm ); void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ); void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ); -void clearAlarm( ALARM_ID_T alarm ); +void clearAlarm( ALARM_ID_T alarm ); +void clearAlarmCondition( ALARM_ID_T alarm ); +void setAlarmUserActionEnabled( ALARM_USER_ACTION_T action, BOOL enabled ); +void signalAlarmSilence( U32 cmd ); +void signalAlarmUserActionInitiated( ALARM_USER_ACTION_T action ); BOOL isAlarmActive( ALARM_ID_T alarm ); ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ); -BOOL isAlarmRecoverable( ALARM_ID_T alarm ); +BOOL isAlarmRecoverable( ALARM_ID_T alarm ); +void setAlarmAudioVolume( U32 volumeLevel ); -BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ); -BOOL testResetAlarmStatusPublishIntervalOverride( void ); BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); BOOL testResetAlarmStateOverride( U32 alarmID ); BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ); Index: firmware/App/Services/PIControllers.c =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -30,32 +30,43 @@ /// Minimum integral coefficient - cannot be zero. #define MIN_KI NEARLY_ZERO -/// Record for PI controller. +/// Enumeration of PI controller direction. +typedef enum controller_Directions +{ + CONTROLLER_BIDIRECTIONAL = 0, ///< Controller runs bidirectional so it covers positive and negative control signals + CONTROLLER_UNIDIRECTIONAL, ///< Controller runs unidirectional so it only covers positive control signals + NUM_OF_CONTROLLELR_DIRECTIONS ///< Number of PI controllers directions +} PI_CONTROLLER_DIRECTIONS_T; + +/// Record for PI controller. typedef struct { // -- PI's parameters -- - F32 Kp; ///< Proportional Value. - F32 Ki; ///< Integral Value. - F32 uMax; ///< Maximum control signal. - F32 uMin; ///< Minimum control signal. + F32 Kp; ///< Proportional Value. + F32 Ki; ///< Integral Value. + F32 uMax; ///< Maximum control signal. + F32 uMin; ///< Minimum control signal. // -- PI's signals -- - F32 referenceSignal; ///< Reference signal. - F32 measuredSignal; ///< Measured signal. - F32 errorSignal; ///< Reference - measured signal. - F32 errorSumBeforeWindUp; ///< Error signal before windup correction. - F32 errorSum; ///< Error integral after windup correction. - F32 controlSignal; ///< Actual control signal. + F32 referenceSignal; ///< Reference signal. + F32 measuredSignal; ///< Measured signal. + F32 errorSignal; ///< Reference - measured signal. + F32 errorSumBeforeWindUp; ///< Error signal before windup correction. + F32 errorSum; ///< Error integral after windup correction. + F32 controlSignal; ///< Actual control signal. + F32 maxErrorSumStep; ///< maximum change in I (error sum) for a single control interval. + PI_CONTROLLER_DIRECTIONS_T direction; ///< PI controller control direction. } PI_CONTROLLER_T; -#define SET_CONTROLLER( c, id ) ((c) = &piControllers[id]) ///< Macro to set a local controller pointer to a given piController. +/// Macro to set a local controller pointer to a given piController. +#define SET_CONTROLLER( c, id ) ((c) = &piControllers[id]) // ********** private data ********** /// PI Controllers -- initial configurations. static PI_CONTROLLER_T piControllers[ NUM_OF_PI_CONTROLLERS_IDS ] = -{ // Kp Ki uMax uMin ref meas err esw esum ctrl - { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_ULTRAFILTRATION - { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_BLOOD_FLOW - { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } // PI_CONTROLLER_ID_DIALYSATE_FLOW +{ // Kp Ki uMax uMin ref meas err esw esum ctrl Ilimit controller type + { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_ULTRAFILTRATION + { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_BLOOD_FLOW + { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0, CONTROLLER_UNIDIRECTIONAL } // PI_CONTROLLER_ID_DIALYSATE_FLOW }; /**@}*/ @@ -148,28 +159,54 @@ F32 result = 0.0; if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) - { + { F32 controlSignalBeforeWindup; F32 windupError; SET_CONTROLLER( controller, controllerID ); controller->referenceSignal = referenceSignal; - controller->measuredSignal = measuredSignal; + controller->measuredSignal = measuredSignal; + // Calculate error signal - controller->errorSignal = fabs( referenceSignal ) - ( referenceSignal < 0.0 ? ( measuredSignal * -1.0 ) : measuredSignal ); - controller->errorSum += controller->errorSignal; - // Anti-windup - controller->errorSumBeforeWindUp = controller->errorSum; + if ( controller->direction == CONTROLLER_UNIDIRECTIONAL ) + { + controller->errorSignal = fabs( referenceSignal ) - ( referenceSignal < 0.0 ? ( measuredSignal * -1.0 ) : measuredSignal ); + } + else + { + controller->errorSignal = referenceSignal - measuredSignal; + } + + // Limit error sum step size + if ( fabs( controller->errorSignal ) > controller->maxErrorSumStep ) + { + if ( controller->errorSignal < 0.0 ) + { + controller->errorSum += ( controller->maxErrorSumStep * -1.0 ); + } + else + { + controller->errorSum += controller->maxErrorSumStep; + } + } + else + { + controller->errorSum += controller->errorSignal; + } + // Calculate control signal + controller->errorSumBeforeWindUp = controller->errorSum; controlSignalBeforeWindup = ( controller->Kp * controller->errorSignal ) + ( controller->Ki * controller->errorSum ); - controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, controller->uMax ); + controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, controller->uMax ); + // Handle anti-windup for i term windupError = controlSignalBeforeWindup - controller->controlSignal; if ( fabs( windupError ) > NEARLY_ZERO ) { controller->errorSum -= ( windupError / controller->Ki ); - } + } + result = controller->controlSignal; } else Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rc414ee882e06359e06b48b1939a90784ae028aa5 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c414ee882e06359e06b48b1939a90784ae028aa5) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -571,7 +571,7 @@ * tared after draining * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendDGDrainCommand( DRAIN_RESERVOIR_CMD_PAYLOAD_T *payload ) +BOOL sendDGDrainCommand( DRAIN_RESERVOIR_CMD_PAYLOAD_T *drainCmdPtr ) { BOOL result; MESSAGE_T msg; @@ -582,7 +582,7 @@ msg.hdr.msgID = MSG_ID_DG_DRAIN_CMD; msg.hdr.payloadLen = sizeof( DRAIN_RESERVOIR_CMD_PAYLOAD_T ); - memcpy( payloadPtr, payload, sizeof( DRAIN_RESERVOIR_CMD_PAYLOAD_T ) ); + memcpy( payloadPtr, drainCmdPtr, sizeof( DRAIN_RESERVOIR_CMD_PAYLOAD_T ) ); // 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_HD_2_DG, ACK_REQUIRED ); @@ -1402,14 +1402,12 @@ *************************************************************************/ void handleLoadCellReadingsFromDG( MESSAGE_T *message ) { - BOOL result = FALSE; - if ( message->hdr.payloadLen == sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ) { LOAD_CELL_READINGS_PAYLOAD_T payload; memcpy( &payload, message->payload, sizeof(LOAD_CELL_READINGS_PAYLOAD_T) ); - result = setNewLoadCellReadings( payload.res1PrimaryLoadCell, payload.res1BackupLoadCell, payload.res2PrimaryLoadCell, payload.res2BackupLoadCell ); + setNewLoadCellReadings( payload.res1PrimaryLoadCell, payload.res1BackupLoadCell, payload.res2PrimaryLoadCell, payload.res2BackupLoadCell ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? @@ -2069,10 +2067,6 @@ setDGOpMode( mode, subMode ); checkInFromDG(); // TODO - here until we implement DG check-in w/ HD broadcast } - else - { - sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_DG, FALSE ); - } } /*********************************************************************//** Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rdf41331377d5da437e853327019c17c58e3af775 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision df41331377d5da437e853327019c17c58e3af775) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -172,7 +172,7 @@ BOOL sendDGFillCommand( U32 fillToVolumeMl ); // MSG_ID_DG_DRAIN_CMD -BOOL sendDGDrainCommand( DRAIN_RESERVOIR_CMD_PAYLOAD_T *payload ); +BOOL sendDGDrainCommand( DRAIN_RESERVOIR_CMD_PAYLOAD_T *drainCmdPtr ); // MSG_ID_STARTING_STOPPING_TREATMENT_CMD BOOL sendDGStartStopCommand( BOOL start ); Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -raeb1dea9ea10fcc70ae66023a87b565f29924c07 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision aeb1dea9ea10fcc70ae66023a87b565f29924c07) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -30,12 +30,6 @@ #include "TaskGeneral.h" #include "RTC.h" -#ifdef RM46_EVAL_BOARD_TARGET - #include "CPLD.h" - #include "SystemCommMessages.h" - static BOOL lastUserPress = FALSE; -#endif - /** * @addtogroup TaskGeneral * @{ @@ -55,73 +49,54 @@ void taskGeneral( void ) { #ifdef TASK_TIMING_OUTPUT_ENABLED - // set GPIO high to indicate general task has begun executing + // Set GPIO high to indicate general task has begun executing setCPLDLampGreen( PIN_SIGNAL_HIGH ); #endif - // check in with watchdog manager - checkInWithWatchdogMgmt( TASK_GENERAL ); // do this first to keep timing consistent with watchdog management + // Check in with watchdog manager + checkInWithWatchdogMgmt( TASK_GENERAL ); // Do this first to keep timing consistent with watchdog management - // manage data received from other sub-systems + // Manage data received from other sub-systems execSystemCommRx(); - // prevent most processing until UI has started communicating + // Prevent most processing until UI has started communicating #ifndef SIMULATE_UI if ( TRUE == uiCommunicated() ) #endif - { - // monitor DG interface + { + // Monitor DG execDGInterfaceMonitor(); - // monitor pressure/occlusion sensors + // Monitor pressure/occlusion sensors execPresOccl(); - // run operation mode state machine + // Run operation mode state machine execOperationModes(); - // control air trap valve + // Control air trap valve execAirTrapController(); - // control blood pump + // Control blood pump execBloodFlowController(); - // control dialysate inlet pump + // Control dialysate inlet pump execDialInFlowController(); - // control dialysate outlet pump + // Control dialysate outlet pump execDialOutFlowController(); - // manage RTC + // Manage RTC execRTC(); - // manage alarm state + // Manage alarm state execAlarmMgmt(); - // control alarm lamp - execAlarmLamp(); - -#ifdef RM46_EVAL_BOARD_TARGET - if ( getUserButtonState() == PIN_SIGNAL_LOW ) - { - if ( lastUserPress == FALSE ) - { - lastUserPress = TRUE; - setUserLED( FALSE ); - sendOffButtonMsgToUI(TRUE); - } - } - else - { - lastUserPress = FALSE; - } -#endif - - // manage data to be transmitted to other sub-systems + // Manage data to be transmitted to other sub-systems execSystemCommTx(); } #ifdef TASK_TIMING_OUTPUT_ENABLED - // set GPIO low to indicate general task has finished executing + // Set GPIO low to indicate general task has finished executing setCPLDLampGreen( PIN_SIGNAL_LOW ); #endif } Fisheye: Tag 766708fceb0bdf1af8c7897df29d4f5036bfd3db refers to a dead (removed) revision in file `results/VectorCAST.log'. Fisheye: No comparison available. Pass `N' to diff? Index: results/cppcheckError.csv =================================================================== diff -u -raf02c3139b58ff98e2beb38704955d748e30ea35 -r766708fceb0bdf1af8c7897df29d4f5036bfd3db --- results/cppcheckError.csv (.../cppcheckError.csv) (revision af02c3139b58ff98e2beb38704955d748e30ea35) +++ results/cppcheckError.csv (.../cppcheckError.csv) (revision 766708fceb0bdf1af8c7897df29d4f5036bfd3db) @@ -44,7 +44,7 @@ hdfirmware/firmware/App/Services/FPGA.c,1201,style,unusedFunction,The function 'getFPGADialInPumpHallSensorStatus' is never used. hdfirmware/firmware/App/Services/FPGA.c,1233,style,unusedFunction,The function 'getFPGADialOutPumpHallSensorStatus' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,340,style,unusedFunction,The function 'getMfgData' is never used. -hdfirmware/firmware/App/Services/PIControllers.c,192,style,unusedFunction,The function 'getPIControllerSignals' is never used. +hdfirmware/firmware/App/Services/PIControllers.c,229,style,unusedFunction,The function 'getPIControllerSignals' is never used. hdfirmware/firmware/FWCommon/RTC.c,422,style,unusedFunction,The function 'getRTCTimestamp' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,465,style,unusedFunction,The function 'getServiceDate' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,558,style,unusedFunction,The function 'getTreatmentTime' is never used. @@ -70,5 +70,7 @@ hdfirmware/firmware/FWCommon/NVDataMgmt.c,440,style,unusedFunction,The function 'setServiceDate' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,534,style,unusedFunction,The function 'setTreatmentTime' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,572,style,unusedFunction,The function 'setWaterConsumption' is never used. +hdfirmware/firmware/App/Services/AlarmMgmt.c,756,style,unusedFunction,The function 'testResetAlarmStatusPublishIntervalOverride' is never used. +hdfirmware/firmware/App/Services/AlarmMgmt.c,731,style,unusedFunction,The function 'testSetAlarmStatusPublishIntervalOverride' is never used. hdfirmware/firmware/FWCommon/NVDataMgmt.c,487,style,unusedFunction,The function 'writeLogData' is never used. ,,information,missingInclude,Cppcheck cannot find all the include files (use --check-config for details)