Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r033fc7e3272b2dcec81a2177f901360587c0b45c -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 033fc7e3272b2dcec81a2177f901360587c0b45c) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -7,8 +7,8 @@ * * @file BloodFlow.c * -* @author (last) Dara Navaei -* @date (last) 26-Jul-2023 +* @author (last) Sean Nash +* @date (last) 10-Aug-2023 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -22,8 +22,8 @@ #include "gio.h" #include "reg_het.h" -#include "Battery.h" #include "BloodFlow.h" +#include "CPLD.h" #include "FPGA.h" #include "InternalADC.h" #include "NVDataMgmt.h" @@ -1261,7 +1261,7 @@ BOOL const isRunningMCCurrentBad = ( ( BLOOD_PUMP_OFF_STATE != bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ) ? TRUE : FALSE ); if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BLOOD_PUMP_MC_CURRENT_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) && - ( FALSE == isACPowerLost() ) ) + ( getCPLDACPowerLossDetected() != TRUE ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r808738c04be99223438be862ab69d30b156f9fbd -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 808738c04be99223438be862ab69d30b156f9fbd) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -8,7 +8,7 @@ * @file BloodLeak.c * * @author (last) Dara Navaei -* @date (last) 21-Jul-2023 +* @date (last) 16-Aug-2023 * * @author (original) Peman Montazemi * @date (original) 18-Mar-2021 @@ -647,6 +647,7 @@ bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; state = BLOOD_LEAK_INIT_STATE; } + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_BLOOD_LEAK_SELF_TEST_RESULT, bloodLeakSelfTestStatus, state ); } return state; @@ -686,15 +687,13 @@ if ( ++bloodLeakPersistenceCtr > BLOOD_LEAK_PERSISTENCE ) { bloodLeakPersistenceCtr = BLOOD_LEAK_PERSISTENCE; -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); - activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); - bloodLeakRecoveryStartTimeMS = getMSTimerCount(); - state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; - } + if ( getTestConfigStatus( TEST_CONFIG_DISABLE_BLOOD_LEAK_ALARM ) != TRUE ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ); + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + } } } else if ( bloodLeakPersistenceCtr > 0 ) Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r1b76127ac6833e64fb04749707ae899052402f3e -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 1b76127ac6833e64fb04749707ae899052402f3e) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -8,7 +8,7 @@ * @file DGInterface.c * * @author (last) Sean Nash -* @date (last) 07-Jul-2023 +* @date (last) 14-Aug-2023 * * @author (original) Sean * @date (original) 08-Apr-2020 @@ -17,7 +17,7 @@ #include // To check for NaN -#include "Battery.h" +#include "CPLD.h" #include "DialInFlow.h" #include "Dialysis.h" #include "DGDefs.h" @@ -96,8 +96,8 @@ static BOOL dgOpModeDataFreshFlag = FALSE; ///< Flag to signal the handleDGOpMode() to process fresh dg op mode data // Reservoir data -static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; ///< Latest active reservoir reported by the DG. -static DG_RESERVOIR_ID_T dgActiveReservoirSet = DG_RESERVOIR_2; ///< Active reservoir commanded. +static DG_RESERVOIR_ID_T dgActiveReservoir; ///< Latest active reservoir reported by the DG. +static DG_RESERVOIR_ID_T dgActiveReservoirSet; ///< Active reservoir commanded. static DG_DISINFECT_UI_STATES_T disinfectsStatus; ///< DG disinfects status. static DG_MIXING_RATIOS_T dgMixingRatios; ///< DG mixing ratios. @@ -124,6 +124,7 @@ { U32 i, j; + // NOTE: the active reservoir is set to reservoir 1 since DG will send active reservoir 1 as active on power up dgStarted = FALSE; dgTrimmerHeaterOn = FALSE; dgTrimmerTempSet = 0.0F; @@ -226,7 +227,7 @@ *************************************************************************/ void execDGInterfaceMonitor( void ) { - if ( isACPowerLost() != TRUE ) + if ( getCPLDACPowerLossDetected() != TRUE ) { // Trigger alarm if not receiving new load cell data message in timely manner checkDGDataFreshness( ALARM_ID_HD_NEW_LOAD_CELL_DATA_MESSAGE_NOT_RECEIVE, &dgLoadCellDataFreshFlag ); @@ -1310,7 +1311,7 @@ U32 trimmerState = dgHeatersData.trimmerHeaterState; DG_OP_MODE_T dgOp = getDGOpMode(); - if ( isACPowerLost() != TRUE ) + if ( getCPLDACPowerLossDetected() != TRUE ) { if ( ( DG_MODE_GENE == dgOp ) || ( DG_MODE_FILL == dgOp ) || ( DG_MODE_DRAI == dgOp ) ) { Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r033fc7e3272b2dcec81a2177f901360587c0b45c -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 033fc7e3272b2dcec81a2177f901360587c0b45c) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -8,7 +8,7 @@ * @file SyringePump.c * * @author (last) Sean Nash -* @date (last) 03-Jun-2023 +* @date (last) 16-Aug-2023 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -70,7 +70,8 @@ #define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. #define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. #define SYRINGE_PUMP_OFF_ERROR_MAX_CNT 10 ///< Maximum number of syringe pump not stopped errors within time window before alarm triggered. Do not exceed MAX_TIME_WINDOWED_COUNT. -#define SYRINGE_PUMP_OFF_ERROR_TIME_WIN_MS (1 * MS_PER_SECOND) ///< Time window for Syringe Pump not stopped error. +#define SYRINGE_PUMP_OFF_ERROR_TIME_WIN_MS ( 1 * MS_PER_SECOND ) ///< Time window for Syringe Pump not stopped error. +#define SYRINGE_PUMP_PRIMING_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Timeout for syringe pump prime operation. #define STEPS_TO_MICROSTEPS( s ) ( (s) * 32.0F ) ///< Macro conversion from steps to microsteps. #define MICROSTEPS_TO_STEPS( m ) ( (m) / 32.0F ) ///< Macro conversion from microsteps to steps. @@ -236,6 +237,7 @@ static BOOL syringeVolumeAdequate; ///< Flag indicates whether Heparin volume is sufficient to complete treatment. static BOOL syringePumpPrimeCompleted; ///< Flag indicates prime operation was completed. static BOOL syringePumpPreLoadCompleted; ///< Flag indicates preload operation was completed. +static U32 syringePumpStateStartTime; ///< Time current syringe pump state started. static BOOL syringePumpDACVrefWriteInProgress; ///< Flag indicates DAC Vref write is in progress. static F32 syringePumpDACVref; ///< DAC Vref setting for force sensor. @@ -315,6 +317,7 @@ syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; syringePumpSafetyVolumeDelivered = 0.0; + syringePumpStateStartTime = getMSTimerCount(); syringePumpPositionKnown = FALSE; syringePumpPlungerFound = FALSE; @@ -1363,6 +1366,7 @@ // If we are starting an active pump state, set direction and calculate target toggle time to achieve desired rate if ( ( result != SYRINGE_PUMP_OFF_STATE ) && ( result != SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE ) ) { + syringePumpStateStartTime = getMSTimerCount(); if ( SYRINGE_PUMP_RETRACT_STATE == result ) { // Set fpga direction to reverse @@ -1579,7 +1583,7 @@ * @brief * The handleSyringePumpPrimeState function handles the prime state * of the syringe pump control state machine. - * @details Inputs: syringePumpVolumeDelivered.data + * @details Inputs: syringePumpVolumeDelivered, syringePumpStateStartTime * @details Outputs: Syringe pump ramped up to prime rate, alarm conditions checked * @return next state *************************************************************************/ @@ -1601,6 +1605,13 @@ syringePumpVolumeStartPosition = syringePumpPosition.data; } + // Check for timeout + if ( TRUE == didTimeout( syringePumpStateStartTime, SYRINGE_PUMP_PRIMING_TIMEOUT_MS ) ) + { + stopPump = TRUE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, (F32)SYRINGE_PUMP_PRIMING_TIMEOUT_MS, 0.0F ) + } + // Check for stall stopPump = checkForStall( stopPump ); @@ -1876,6 +1887,10 @@ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, currentForceV ) result = TRUE; } + else + { + clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION ); + } } // Check with persistence during continuous state Index: firmware/App/HDCommon.h =================================================================== diff -u -rd3cf039dc65c1b1b199e47bf694e040712c5bd12 -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision d3cf039dc65c1b1b199e47bf694e040712c5bd12) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -25,7 +25,7 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 #define HD_VERSION_MICRO 0 -#define HD_VERSION_BUILD 209 +#define HD_VERSION_BUILD 228 // ********** development build switches ********** Index: firmware/App/Modes/ModePostTreat.c =================================================================== diff -u -ra56db4650fe5652d633e0c51b29da32d5d708608 -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision a56db4650fe5652d633e0c51b29da32d5d708608) +++ firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -418,7 +418,7 @@ *************************************************************************/ static HD_POST_TREATMENT_STATE_T handlePostTreatmentDrainReservoirsState( void ) { - HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_DRAIN_RESERVOIRS_STATE; + HD_POST_TREATMENT_STATE_T state = HD_POST_TREATMENT_DRAIN_RESERVOIRS_STATE; execDrainReservoirs(); @@ -557,7 +557,19 @@ static void execDrainReservoirs( void ) { DRAIN_STATE_T priorSubState = currentDrainReservoirState; + DG_OP_MODE_T dgMode = getDGOpMode(); + if ( DG_MODE_STAN == dgMode ) + { // In case DG was reset/power cycled, re-start DG so we can drain the reservoirs + cmdStartDG(); + currentDrainReservoirState = DRAIN_RESERVOIR_SWITCH_STATE; + } + else if ( DG_MODE_FAUL == dgMode ) + { // In case DG faulted, skip DG drain states and move on + currentDrainReservoirState = DRAIN_RESERVOIR_COMPLETE_STATE; + } + + // Execute post-tx drain state machine switch ( currentDrainReservoirState ) { case DRAIN_RESERVOIR_SWITCH_STATE: @@ -600,7 +612,7 @@ static DRAIN_STATE_T handleDrainReservoirSwitchState( void ) { DRAIN_STATE_T state = DRAIN_RESERVOIR_SWITCH_STATE; - DG_OP_MODE_T dgMode = getDGOpMode(); + DG_OP_MODE_T dgMode = getDGOpMode(); if ( ( DG_MODE_GENE == dgMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == getDGSubMode() ) ) { @@ -636,14 +648,6 @@ } } } - else if ( DG_MODE_STAN == dgMode ) - { // In case DG was reset/power cycled, re-start DG so we can drain the reservoirs - cmdStartDG(); - } - else if ( DG_MODE_FAUL == dgMode ) - { // In case DG faulted, skip DG drain states and move on - state = DRAIN_RESERVOIR_COMPLETE_STATE; - } return state; } Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -r3217afc81447c9299c3a6ffc39744964b6ed48af -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 3217afc81447c9299c3a6ffc39744964b6ed48af) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -864,15 +864,8 @@ if ( RINSEBACK_PAUSED_STATE == rinsebackState ) { - if ( getNoRetriggerFlag() != TRUE ) - { - result = TRUE; - resumeRinsebackRequested = TRUE; - } - else - { - *rejReason = REQUEST_REJECT_REASON_TREATMENT_CANNOT_BE_RESUMED; - } + result = TRUE; + resumeRinsebackRequested = TRUE; } else if ( RINSEBACK_RECONNECT_PATIENT_STATE == rinsebackState ) { Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r24c447c3ee627c242fae1ce9c74d2b4d4a09e8c0 -r4d0c621f5994e1de8bf7d3337678f7835292ce73 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 24c447c3ee627c242fae1ce9c74d2b4d4a09e8c0) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 4d0c621f5994e1de8bf7d3337678f7835292ce73) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Michael Garthwaite -* @date (last) 31-Jul-2023 +* @author (last) Bill Bracken +* @date (last) 22-Aug-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -27,6 +27,7 @@ #include "ConsumableSelfTest.h" #include "Fans.h" #include "FPGA.h" +#include "Integrity.h" #include "ModeStandby.h" #include "ModeInitPOST.h" #include "OperationModes.h" @@ -3029,6 +3030,27 @@ /*********************************************************************//** * @brief + * The handlePostTxNextCmd function handles a post-treatment next request + * message from the UI. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handlePostTxNextCmd( MESSAGE_T *message ) +{ + if ( 0 == message->hdr.payloadLen ) + { + requestPostTxNext(); + } + else + { + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_HD_2_UI, FALSE ); + } +} + +/*********************************************************************//** + * @brief * The sendTreatmentRecircCmdResponse function constructs a treatment re-circulation * user action response to the UI and queues the msg for transmit on the appropriate * CAN channel. @@ -3061,6 +3083,38 @@ /*********************************************************************//** * @brief + * The sendPostTxNextCmdResponse function constructs a post-treatment next + * command response to the UI and queues the msg for transmit on the appropriate + * CAN channel. + * @details Inputs: none + * @details Outputs: Post-treatment next command response msg constructed and queued. + * @param accepted T/F - was request accepted? + * @param rejReason reason why request was rejected (or zero if accepted) + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPostTxNextCmdResponse( BOOL accepted, U32 rejReason ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_POST_TX_NEXT_CMD_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &accepted, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // 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_UI, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The handleTreatmentEndCmd function handles a treatment end user action command * message from the UI. * @details Inputs: none @@ -6144,7 +6198,6 @@ TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; BOOL result = FALSE; -#ifndef _RELEASE_ // Verify payload length if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) { @@ -6158,7 +6211,6 @@ result = testResetValvesCurrentOverride( payload.index ); } } -#endif // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); @@ -8339,4 +8391,68 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status ); } +/*********************************************************************//** + * @brief + * The handleTestHDRAMStatusOverrideRequest function handles a request to + * override the RAM status register. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestHDRAMStatusOverrideRequest( MESSAGE_T* message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetRAMStatusOverride( payload.index, payload.state.u32 ); + } + else + { + result = testResetRAMStatusOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestHDPendingACKOverrideRequest function handles a + * request to override pending ACKs. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestHDPendingACKOverrideRequest( 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 = testSetPendingACKOverride( payload.state.u32 ); + } + else + { + result = testResetPendingACKOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/