Index: firmware/App/Controllers/Bubble.c =================================================================== diff -u -rf007d2e06b612caed19e9c044fede4a100d2fc2f -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision f007d2e06b612caed19e9c044fede4a100d2fc2f) +++ firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -194,6 +194,7 @@ bubblesStatus[ bubble ].data = BUBBLE_DETECTED; } +#ifndef DISABLE_BUBBLE_ALARMS // Check status reading and act upon if ( BUBBLE_DETECTED == getBubbleStatus( bubble ) ) { @@ -246,6 +247,7 @@ clearAlarmCondition( ALARM_ID_HD_VENOUS_BUBBLE_DETECTED_RINSEBACK ); } } +#endif if ( TRUE == bubblesSelfTestRequested[ bubble ] ) { Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -ra69fcb7945b0300b47ce3287f8cb22c7c26171dc -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision a69fcb7945b0300b47ce3287f8cb22c7c26171dc) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -22,6 +22,7 @@ #include "ModeInitPOST.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" +#include "PersistentAlarm.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "Timers.h" @@ -33,15 +34,22 @@ // ********** private definitions ********** -#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 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 MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. +#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. -#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. +#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. +#define DIALYSATE_TEMP_PERSISTENCE_PERIOD ( 3 * MS_PER_SECOND ) ///< Persistence period for dialysate temperature alarm. + +#define DIALYSATE_TEMP_RECOVERY_TOLERANCE_C 2.0 ///< Dialysate temperature recovery tolerance in degree C. +#define DIALYSATE_TEMP_TOLERANCE_C 4.0 ///< Dialysate temperature tolerance in degree C. +#define DIALYSATE_TEMP_HIGH_LIMIT_C 42.0 ///< Dialysate high temperature limit in degree C. +#define DIALYSATE_TEMP_LOW_LIMIT_C 33.0 ///< Dialysate low temperature limit in degree C. + /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States { @@ -161,6 +169,9 @@ lgLoadCellReadingsIdx = 0; lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + + initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); } /*********************************************************************//** @@ -543,18 +554,6 @@ /*********************************************************************//** * @brief - * The getDialysateTemperature function gets the latest dialysate temperature. - * @details Inputs: dgDialysateTemp - * @details Outputs: none - * @return the current dialysate temperature - *************************************************************************/ -F32 getDialysateTemperature( void ) -{ - return dgDialysateTemp; -} - -/*********************************************************************//** - * @brief * The getDGDisinfectsStates function returns the DG disinfects readings. * @details Inputs: none * @details Outputs: disinfectsStatus @@ -567,6 +566,18 @@ /*********************************************************************//** * @brief + * The getDialysateTemperature function gets the latest dialysate temperature. + * @details Inputs: dgDialysateTemp + * @details Outputs: none + * @return the current dialysate temperature + *************************************************************************/ +F32 getDialysateTemperature( void ) +{ + return dgDialysateTemp; +} + +/*********************************************************************//** + * @brief * The getReservoirWeight function gets the load cell weight of a given reservoir. * @details Inputs: loadCellWeightInGrams[] * @details Outputs: none @@ -1113,6 +1124,47 @@ /*********************************************************************//** * @brief + * The checkDialysateTemperature function checks the dialysate temperature + * reported by DG and alarm if temperature is out of range. + * @details Inputs: dgTrimmerTempSet, dgDialysateTemp, dgRedundantDialysateTemp + * @details Outputs: alarm if dialysate temperature is out of accepted range + * @return none + *************************************************************************/ +void checkDialysateTemperature( void ) +{ + BOOL const dialysateHighTemp = ( ( ( dgDialysateTemp - dgTrimmerTempSet ) > DIALYSATE_TEMP_TOLERANCE_C ) || + ( dgDialysateTemp > DIALYSATE_TEMP_HIGH_LIMIT_C ) ); + + BOOL const dialysateLowTemp = ( ( ( dgTrimmerTempSet - dgDialysateTemp ) > DIALYSATE_TEMP_TOLERANCE_C ) || + ( dgDialysateTemp < DIALYSATE_TEMP_LOW_LIMIT_C ) ); + + BOOL const dialysateTempRecovered = fabs( dgDialysateTemp - dgTrimmerTempSet ) < DIALYSATE_TEMP_RECOVERY_TOLERANCE_C ? TRUE : FALSE; + +#ifndef DISABLE_DIALYSATE_TEMP_CHECK + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dgTrimmerTempSet, dgDialysateTemp ); + } + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateLowTemp ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dgTrimmerTempSet, dgDialysateTemp ); + } + + if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) + { + clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH ); + } + + if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateTempRecovered ) ) + { + clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_LOW ); + } +#endif +} + +/*********************************************************************//** + * @brief * The checkDGRestart function checks to see if DG has restarted after started * by HD and triggers appropriate alarm. * @details Inputs: dgStarted Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -ra69fcb7945b0300b47ce3287f8cb22c7c26171dc -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision a69fcb7945b0300b47ce3287f8cb22c7c26171dc) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -44,6 +44,8 @@ /// Delay (in task intervals) after POST completes. #define POST_COMPLETED_DELAY ( 2 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +/// Maximum wait time for UI to send its final POST result. +#define POST_UI_MAX_WAIT_TIME ( 2 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) // ********** private data ********** @@ -54,13 +56,17 @@ static BOOL uiPOSTPassed; ///< Final result for UI POST tests (TRUE = passed, FALSE = failed). static BOOL dgPOSTPassed; ///< Final result for DG POST tests (TRUE = passed, FALSE = failed). +static BOOL uiPOSTResultReceived; ///< Have we received a final POST result from the UI? +static BOOL dgPOSTResultReceived; ///< Have we received a final POST result from the DG? +static U32 waitForUIPostTimerCtr; ///< Timer counter to limit wait for UI final POST result. static U32 postCompleteDelayTimerCtr; ///< Timer counter for 2 second delay after POST completes and before transitioning to Standbymode. // ********** private function prototypes ********** static HD_POST_STATE_T handlePOSTStatus( SELF_TEST_STATUS_T testStatus ); static SELF_TEST_STATUS_T execFWCompatibilityTest( void ); +static SELF_TEST_STATUS_T execUITest( void ); /*********************************************************************//** * @brief @@ -77,6 +83,9 @@ tempPOSTPassed = TRUE; uiPOSTPassed = FALSE; dgPOSTPassed = FALSE; + uiPOSTResultReceived = FALSE; + dgPOSTResultReceived = FALSE; + waitForUIPostTimerCtr = 0; postCompleteDelayTimerCtr = 0; } @@ -114,8 +123,6 @@ // Ignore stop button in this mode. } - // TODO - send POST status on CAN - // Execute current POST state *Note - these switch cases must be in same order as enum HD_POST_States switch ( postState ) { @@ -125,7 +132,6 @@ case POST_STATE_FW_INTEGRITY: testStatus = execIntegrityTest(); - testStatus = SELF_TEST_STATUS_PASSED; postState = handlePOSTStatus( testStatus ); break; @@ -201,8 +207,7 @@ break; case POST_STATE_UI_POST: - // TODO implement the UI POST self test - testStatus = SELF_TEST_STATUS_PASSED; + testStatus = execUITest(); postState = handlePOSTStatus( testStatus ); break; @@ -211,11 +216,10 @@ postState = handlePOSTStatus( testStatus ); break; - // Should be last POST (and last POST test must be a test that completes in a single call) + // Should be last POST (and last POST test must be a test that completes in a single call) case POST_STATE_FPGA: testStatus = execFPGATest(); handlePOSTStatus( testStatus ); // Ignoring return value because last test - if ( TRUE == tempPOSTPassed ) { postState = POST_STATE_COMPLETED; @@ -226,8 +230,6 @@ } break; - // TODO - add POST test requiring all DG and UI POST tests to pass - case POST_STATE_COMPLETED: // Set overall HD POST status to "passed" postPassed = TRUE; @@ -278,6 +280,7 @@ void signalUIPOSTFinalResult( BOOL passed ) { uiPOSTPassed = passed; + uiPOSTResultReceived = TRUE; } /*********************************************************************//** @@ -292,6 +295,7 @@ void signalDGPOSTFinalResult( BOOL passed ) { dgPOSTPassed = passed; + dgPOSTResultReceived = TRUE; } /*********************************************************************//** @@ -370,9 +374,48 @@ { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; - // TODO - implement + // TODO - implement (need UI to include its version/compatibility info in its request for f/w versions so we can check compatibility) + //SW_COMPATIBILITY_REV return result; } +/*********************************************************************//** + * @brief + * The execUITest function executes the UI POST passed test. + * @details Inputs: uiPOSTResultReceived, uiPOSTPassed, waitForUIPostTimerCtr + * @details Outputs: waitForUIPostTimerCtr + * @return in progress, passed, or failed + *************************************************************************/ +static SELF_TEST_STATUS_T execUITest( void ) +{ +#ifndef DISABLE_UI_POST_TEST + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + // UI should have sent POST results before we start this test + if ( TRUE == uiPOSTResultReceived ) + { + if ( TRUE == uiPOSTPassed ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_UI_POST_FAILED, 0 ) + result = SELF_TEST_STATUS_FAILED; + } + } + // If UI had not already sent POST results before we started, allow finite period for UI to send. + else if ( ++waitForUIPostTimerCtr > POST_UI_MAX_WAIT_TIME ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_UI_POST_FAILED, 1 ) + result = SELF_TEST_STATUS_FAILED; + } +#else + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; +#endif + + return result; +} + /**@}*/ Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rdbfeaf78c05fc922eba6ff8c7a31ba8a9392c642 -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision dbfeaf78c05fc922eba6ff8c7a31ba8a9392c642) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -604,6 +604,8 @@ activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); } + checkDialysateTemperature(); + // Treatment mode state machine switch ( currentTreatmentState ) { Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -rdbfeaf78c05fc922eba6ff8c7a31ba8a9392c642 -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision dbfeaf78c05fc922eba6ff8c7a31ba8a9392c642) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -345,7 +345,7 @@ TREATMENT_PARAM_T param; // Set all treatment parameters (except UF volume which is not yet received) - for ( param = TREATMENT_PARAM_FIRST_UINT; param < TREATMENT_PARAM_UF_VOLUME; param++ ) + for ( param = TREATMENT_PARAM_FIRST_UINT; param < NUM_OF_TREATMENT_PARAMS; param++ ) { setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ); } Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -ra7208ef0e06ae2d91b2f144e6e25a6fefde8c022 -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision a7208ef0e06ae2d91b2f144e6e25a6fefde8c022) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -63,8 +63,9 @@ #define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. #define ALARM_AUDIO_TEST_TONE 4 ///< Alarm audio state for continuous test tone. -#define ALARM_AUDIO_CURRENT_HG_MIN_MA 10.0 ///< Minimum audio current (high gain) during test tone self-test (in mA). -#define ALARM_AUDIO_CURRENT_LG_MIN_MA 10.0 ///< Minimum audio current (low gain) during test tone self-test (in mA). +#define ALARM_AUDIO_CURRENT_HG_MIN_MA 20.0 ///< Minimum audio current (high gain) during test tone self-test (in mA). // TODO - Why is HG so low? S/B same as LG I think. +#define ALARM_AUDIO_CURRENT_LG_MIN_MA 60.0 ///< Minimum audio current (low gain) during test tone self-test (in mA). +#define ALARM_AUDIO_MAX_TEST_TIME_MS 1000 ///< Maximum time for audio current to reach threshold in test. /// Alarm priority ranking record. typedef struct @@ -74,6 +75,15 @@ U32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered } ALARM_PRIORITY_RANKS_T; +/// Enumeration of alarm audio self-test states. +typedef enum Alarm_Lamp_Self_Test_States +{ + ALARM_AUDIO_SELF_TEST_STATE_START = 0, ///< Start state of alarm lamp self-test. + ALARM_AUDIO_SELF_TEST_STATE_PRIMARY, ///< Red state of alarm lamp self-test. + ALARM_AUDIO_SELF_TEST_STATE_COMPLETE, ///< Completed state of alarm lamp self-test. + NUM_OF_ALARM_AUDIO_SELF_TEST_STATES ///< Number of states in alarm lamp self-test. +} ALARM_AUDIO_SELF_TEST_STATE_T; + // ********** private data ********** static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm @@ -102,6 +112,8 @@ static BOOL alarmUserRecoveryActionEnabled[ NUMBER_OF_ALARM_USER_ACTIONS ]; ///< Alarm user recovery actions enabled flags. +/// Current state of the alarm audio self tests. +static ALARM_AUDIO_SELF_TEST_STATE_T alarmAudioSelfTestState; /// Flag indicates whether alarm audio test tone should be output. static BOOL alarmAudioTestToneRequested; @@ -176,7 +188,8 @@ alarmStatus.noDialRecirc = FALSE; alarmStatus.usrACKRequired = FALSE; - alarmAudioTestToneRequested = FALSE; + alarmAudioTestToneRequested = FALSE; + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; } /*********************************************************************//** @@ -697,7 +710,7 @@ alarmPrimaryAudioCurrentHG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); alarmPrimaryAudioCurrentLG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); - alarmBackupAudioCurrent.data = getIntADCVoltageConverted( INT_ADC_BACKUP_ALARM_CURRENT ); + alarmBackupAudioCurrent.data = getFPGABackupAlarmAudioCurrent(); // TODO - Check current vs. expected audio output @@ -844,15 +857,23 @@ { U32 volume = getAlarmAudioVolume(); - if ( TRUE == alarmAudioTestToneRequested ) - { // Play test tone at max volume for next 50 ms - setAlarmAudioState( ALARM_AUDIO_TEST_TONE, 0 ); + // If we're not in Init-POST mode, ensure audio test tone request is cancelled. + if ( getCurrentOperationMode() != MODE_INIT ) + { alarmAudioTestToneRequested = FALSE; } + + // If audio test in progress, play test tone. + if ( TRUE == alarmAudioTestToneRequested ) + { // Play test tone at min volume + setAlarmAudioState( ALARM_AUDIO_TEST_TONE, 4 ); + } + // If alarm silenced, play no alarm audio. else if ( TRUE == alarmStatus.alarmsSilenced ) { setAlarmAudioState( ALARM_PRIORITY_NONE, volume ); } + // Otherwise, play alarm audio as appropriate based on current alarm status else { if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) @@ -1235,36 +1256,55 @@ * The execAlarmAudioSelfTest function outputs a test audio tone and * measures the audio current level. The test passes if the audio current * exceeds TBD mA. - * @details Inputs: alarmBackupAudioCurrent + * @details Inputs: alarmAudioSelfTestState * @details Outputs: none * @return the current backup alarm audio current (in mA). *************************************************************************/ SELF_TEST_STATUS_T execAlarmAudioSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + static U32 testStartTime; - if ( alarmAudioTestToneRequested != TRUE ) + switch ( alarmAudioSelfTestState ) { - alarmAudioTestToneRequested = TRUE; - setAlarmAudio(); - } - else - { - F32 almHGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); - F32 almLGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); + case ALARM_AUDIO_SELF_TEST_STATE_START: + testStartTime = getMSTimerCount(); + // Start test tone + alarmAudioTestToneRequested = TRUE; + setAlarmAudio(); + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_PRIMARY; + break; - // Check if alarm audio current is sufficiently high indicating alarm tone is being output -// TODO - need tone to be on longer than 50ms. make duration long (1 sec) at first to characterize the audio, then change to exit test when threshold met or t/o -// if ( ( almHGCurrent > ALARM_AUDIO_CURRENT_HG_MIN_MA ) && -// ( almLGCurrent > ALARM_AUDIO_CURRENT_LG_MIN_MA ) ) - { - result = SELF_TEST_STATUS_PASSED; - } -// else -// { -// result = SELF_TEST_STATUS_FAILED; -// SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_ALARM_AUDIO_SELF_TEST_FAILURE, almHGCurrent, almLGCurrent ); -// } + case ALARM_AUDIO_SELF_TEST_STATE_PRIMARY: + { + F32 almHGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); + F32 almLGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); + + // Check if alarm audio current is sufficiently high indicating alarm tone is being output + if ( ( almHGCurrent > ALARM_AUDIO_CURRENT_HG_MIN_MA ) && + ( almLGCurrent > ALARM_AUDIO_CURRENT_LG_MIN_MA ) ) + { + alarmAudioTestToneRequested = FALSE; + result = SELF_TEST_STATUS_PASSED; + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_COMPLETE; + } + else if ( TRUE == didTimeout( testStartTime, ALARM_AUDIO_MAX_TEST_TIME_MS ) ) + { + alarmAudioTestToneRequested = FALSE; + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_ALARM_AUDIO_SELF_TEST_FAILURE, almHGCurrent, almLGCurrent ); + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_COMPLETE; + } + } + break; + + case ALARM_AUDIO_SELF_TEST_STATE_COMPLETE: + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; // Should only get here if re-starting self-tests. + break; + + default: + // TODO - s/w fault + break; } return result; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r3f2b9de757500da37e0ed8881e4e906d94f3076c -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -327,14 +327,6 @@ { canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent ); } -#ifdef DEBUG_ENABLED - { - char debugStr[100]; - sprintf( debugStr, "SystemComm-HD resend Last Frame. %2d\n", lastCANPacketSentChannel ); - sendDebugData( (U08*)debugStr, strlen(debugStr) ); - sendDebugDataToUI( (U08*)debugStr ); - } -#endif } // We must be only node on CAN bus - nobody is ACKing our transmitted frames else @@ -343,13 +335,6 @@ canXmitRetryCtr = MAX_XMIT_RETRIES; signalCANXmitsCompleted(); // Clear pending xmit flag clearCANXmitBuffers(); // Clear xmit buffers - nothing is going out right now -#ifdef DEBUG_ENABLED - { - char debugStr[100]; - sprintf( debugStr, "SystemComm-HD is only node.\n" ); - sendDebugData( (U08*)debugStr, strlen(debugStr) ); - } -#endif } } } @@ -968,13 +953,6 @@ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, (U32)ALARM_SOURCE_HD ); #endif } -#ifdef DEBUG_ENABLED - { - char debugStr[100]; - sprintf( debugStr, "SystemComm-HD-Bad Msg CRC.\n" ); - sendDebugDataToUI( (U08*)debugStr ); - } -#endif } /*********************************************************************//** @@ -1557,6 +1535,14 @@ handleTestDialOutPumpHomeRequest( message ); break; + case MSG_ID_SUPER_CLEAR_ALARMS_CMD: + handleTestSuperClearAlarmsRequest( message ); + break; + + case MSG_ID_HD_SET_OP_MODE_REQUEST: + handleTestSetOpModeRequest( message ); + break; + case MSG_ID_HD_FLUID_LEAK_SEND_INTERVAL_OVERRIDE: handleSetFluidLeakBroadcastIntervalOverrideRequest( message ); break; @@ -1589,6 +1575,10 @@ handleBubbleSelfTestRequest( message ); break; + case MSG_ID_HD_BLOOD_PRIME_VOLUME_OVERRIDE: + handleBloodPrimeVolumeOverrideRequest( message ); + break; + case MSG_ID_HD_SWITCHES_STATUS_OVERRIDE: handleSetSwitchesStatusOverrideRequest( message ); break; @@ -1597,18 +1587,14 @@ handleTestSwitchesPublishIntervalOverrideRequest( message ); break; + case MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE: + handleBloodPrimeSafetyVolumeOverrideRequest( message ); + break; + case MSG_ID_HD_BATTERY_REMAINING_PERCENT_OVERRIDE: handleBatteryRemainingPercentOverrideRequest( message ); break; - case MSG_ID_HD_SET_OP_MODE_REQUEST: - handleTestSetOpModeRequest( message ); - break; - - case MSG_ID_SUPER_CLEAR_ALARMS_CMD: - handleTestSuperClearAlarmsRequest( message ); - break; - case MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: handleTestSyringePumpDataBroadcastIntervalOverrideRequest( message ); break; @@ -1645,6 +1631,10 @@ handleTestValvesCurrentOverrideRequest( message ); break; + case MSG_ID_HD_VALVES_POSITION_COUNT_OVERRIDE: + handleTestValvesPositionCountOverrideRequest( message ); + break; + case MSG_ID_HD_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE: handleTestMonitoredVoltagesSendIntervalOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r3f2b9de757500da37e0ed8881e4e906d94f3076c -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -3167,7 +3167,7 @@ TEMPERATURE_SENSORS_DATA_T payload; memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? @@ -3943,9 +3943,11 @@ void handleFWVersionRequest( MESSAGE_T *message ) { MESSAGE_T msg; - HD_VERSIONS_T payload; + HD_VERSIONS_T payload; // TODO - add compatibility data to response U08 *payloadPtr = msg.payload; + // TODO - grab UI version data when UI includes it in this message + // Populate payload payload.major = (U08)HD_VERSION_MAJOR; payload.minor = (U08)HD_VERSION_MINOR; @@ -6093,6 +6095,7 @@ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) { result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); @@ -6109,6 +6112,70 @@ /*********************************************************************//** * @brief + * The handleBloodPrimeVolumeOverrideRequest function handles a request to + * override the calculated blood prime volume (in mL). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleBloodPrimeVolumeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetBloodPrimeVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetBloodPrimeVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleBloodPrimeSafetyVolumeOverrideRequest function handles a request to + * override the calculated safety blood prime volume (in mL). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleBloodPrimeSafetyVolumeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetBloodPrimeSafetyVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetBloodPrimeSafetyVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleHDSoftwareResetRequest function handles a request to reset the * HD firmware processor. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r3f2b9de757500da37e0ed8881e4e906d94f3076c -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -679,6 +679,12 @@ // MSG_ID_HD_BUBBLE_SELF_TEST_REQUEST void handleBubbleSelfTestRequest( MESSAGE_T *message ); +// MSG_ID_HD_BLOOD_PRIME_VOLUME_OVERRIDE +void handleBloodPrimeVolumeOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE +void handleBloodPrimeSafetyVolumeOverrideRequest( MESSAGE_T *message ); + // MSG_ID_HD_SWITCHES_STATUS_OVERRIDE void handleSetSwitchesStatusOverrideRequest( MESSAGE_T *message ); Index: firmware/App/Services/WatchdogMgmt.c =================================================================== diff -u -rf3326a3d0fd2a465a518e31ee578e335db301c27 -r58f8416a9ff9c68ee34361ac23a46dcf56cfa79e --- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision f3326a3d0fd2a465a518e31ee578e335db301c27) +++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 58f8416a9ff9c68ee34361ac23a46dcf56cfa79e) @@ -16,6 +16,7 @@ ***************************************************************************/ #include "CPLD.h" +#include "FPGA.h" #include "InternalADC.h" #include "SafetyShutdown.h" #include "SystemCommMessages.h" @@ -30,11 +31,11 @@ // ********** private definitions ********** #define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval (in ms). -#define WATCHDOG_POST_TIMEOUT_MS 100 ///< Watchdog POST test timeout (in ms). +#define WATCHDOG_POST_TIMEOUT_MS 500 ///< Watchdog POST test timeout (in ms). #define WATCHDOG_RECOVERY_TIME_MS 250 ///< After watchdog POST test, wait this long (in ms) before moving on. -#define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 1.0 ///< Maximum voltage on 24V line when watchdog is expired. -#define MIN_BACKUP_ALARM_CURRENT 10.0 ///< Minimum backup alarm audio current (in mA) detected when watchdog is expired. +#define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 5.0 ///< Maximum voltage on 24V line when watchdog is expired. // TODO - check w/ Systems. Takes time for V to bleed off. Had to raise to 5V. +#define MIN_BACKUP_ALARM_CURRENT_MA 200.0 ///< Minimum backup alarm audio current (in mA) detected when watchdog is expired. /// Enumeration of watchdog self-test states. typedef enum Watchdog_Self_Test_States @@ -124,7 +125,6 @@ } } - /*********************************************************************//** * @brief * The checkInWithWatchdogMgmt function checks a given task in with the @@ -168,23 +168,32 @@ // Waiting here for w.d. test period to prevent this task from checking in - watchdog should expire } if ( getCPLDWatchdogExpired() == PIN_SIGNAL_HIGH ) - { + { + F32 v24 = getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS ); + F32 audioCurrent = getFPGABackupAlarmAudioCurrent(); + // Verify 24V is down when w.d. expired - if ( getIntADCVoltageConverted( INT_ADC_24V_ACTUATORS ) > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) + if ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) { - // TODO - alarm + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 2.0, v24 ); + watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } +#ifndef DISABLE_ALARM_AUDIO // Verify backup alarm audio is on when w.d. expired - if ( getIntADCVoltageConverted( INT_ADC_BACKUP_ALARM_CURRENT ) < MIN_BACKUP_ALARM_CURRENT ) + else if ( audioCurrent < MIN_BACKUP_ALARM_CURRENT_MA ) { - // TODO - alarm + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_WATCHDOG_POST_TEST_FAILED, 3.0, audioCurrent ); + watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } - // TODO - user needs to verify backup alarm audio and LED? - watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED; +#endif + else + { + watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED; + } } else { - activateAlarmNoData( ALARM_ID_WATCHDOG_POST_TEST_FAILED ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 1 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } watchdogSelfTestTimerCount = getMSTimerCount();