Index: firmware/App/Controllers/AirPump.c =================================================================== diff -u -r25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe) +++ firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -7,8 +7,8 @@ * * @file AirPump.c * -* @author (last) Varshini Nagabooshanam -* @date (last) 02-Jul-2026 +* @author (last) Santhosh Reddy +* @date (last) 07-Aug-2026 * * @author (original) Sean Nash * @date (original) 19-Sep-2024 @@ -52,7 +52,7 @@ static AIR_PUMP_STATE_T currentAirPumpState; ///< Current air pump control state. static U08 airPumpStallCounter; ///< Air pump stall counter static U08 airPumpStartDelayCounter; ///< Delay before evaluating air pump stall condition -static U16 currentAirPumpRPM; ///< Current air pump RPM +static OVERRIDE_U32_T currentAirPumpRPM; ///< Current air pump RPM static F32 currentAirPumpPowerLevel; ///< Current air pump power level setting in % duty cycle (0..100%). static U32 airPumpDataPublicationTimerCounter; ///< Air pump data broadcast timer counter. static OVERRIDE_U32_T airPumpDataPublishInterval; ///< Air pump data broadcast interval (in ms). @@ -81,7 +81,10 @@ airPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; currentAirPumpState = AIR_PUMP_STATE_INIT; currentAirPumpPowerLevel = AIR_PUMP_MOTOR_OFF; - currentAirPumpRPM = 0; + currentAirPumpRPM.data = 0; + currentAirPumpRPM.ovData = 0; + currentAirPumpRPM.ovInitData = 0; + currentAirPumpRPM.override = OVERRIDE_RESET; airPumpStallCounter = 0; airPumpStartDelayCounter = 0; airPumpDataPublishInterval.data = AIR_PUMP_DATA_PUB_INTERVAL; @@ -179,7 +182,7 @@ // Check stall condition checkAirPumpStallCondition(); // update the speed every tick - currentAirPumpRPM = getAirPumpMotorRPM(); + currentAirPumpRPM.data = (U32)getAirPumpMotorRPM(); publishAirPumpData(); } @@ -255,12 +258,14 @@ airPumpStartDelayCounter++; airPumpStallCounter = 0; } - else if ( 0 == currentAirPumpRPM ) + else if ( 0 == getU32OverrideValue( ¤tAirPumpRPM ) ) { // Air pump commanded on but RPM remains zero if ( ++airPumpStallCounter >= AIR_PUMP_STALL_PERSISTENCE ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AIR_PUMP_STALL, currentAirPumpPowerLevel, currentAirPumpRPM ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AIR_PUMP_STALL, + currentAirPumpPowerLevel, + getU32OverrideValue( ¤tAirPumpRPM ) ); // Stop H12 air pump setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); } @@ -300,7 +305,7 @@ data.h12State = getAirPumpState(); data.h12Power = currentAirPumpPowerLevel; - data.h12Rpm = (U32)currentAirPumpRPM; + data.h12Rpm = getU32OverrideValue( ¤tAirPumpRPM ); //TODO:remove after validating pump speed data.fpgah12Rpm = getAirPumpMotorFPGARPM(); //TODO:remove after validating pump speed @@ -365,5 +370,22 @@ return result; } +/*********************************************************************//** + * @brief + * The testAirPumpRPMOverride function overrides the RPM value reported + * by the air pump sensor. + * @details \b Inputs: none + * @details \b Outputs: currentAirPumpRPM + * @param message Override message from Dialin which includes the RPM + * value to override the air pump RPM to. + * @return TRUE if override request is successful, FALSE if not + *************************************************************************/ +BOOL testAirPumpRPMOverride( MESSAGE_T *message ) +{ + BOOL result = u32Override( message, ¤tAirPumpRPM, 0, 0xFFFF ); + + return result; +} + /**@}*/ Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -8,7 +8,7 @@ * @file AirTrap.c * * @author (last) Varshini Nagabooshanam -* @date (last) 18-Jun-2026 +* @date (last) 24-Jun-2026 * * @author (original) Sean Nash * @date (original) 24-Oct-2024 @@ -85,7 +85,7 @@ static OVERRIDE_F32_T airTrapAirPumpRaisePowerLevel; ///< Air pump power level to use when raising the air trap blood level. static OVERRIDE_F32_T airTrapAirPumpLowerPowerLevel; ///< Air pump power level to use when lowering the air trap blood level. -static BOOL pendingStartAirTrapController; ///< Flag indicates an air trap controller start request is pending. +static BOOL pendingStartAirTrapController; ///< Indicates an air trap controller start request is pending. static BOOL pendingStopAirTrapController; ///< Flag indicates an air trap controller stop request is pending. static U32 airTrapFillStartTime; ///< Air trap fill (raise level) operation start time. Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r1fa3d19e3ca08af7cedbf481265989830dba2627 -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 1fa3d19e3ca08af7cedbf481265989830dba2627) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -23,6 +23,7 @@ #include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" +#include "Prime.h" #include "StatePreTxRecirculate.h" #include "SyringePump.h" #include "TaskGeneral.h" @@ -54,6 +55,8 @@ static U32 preTreatmentStateBroadcastTimerCtr; ///< Pre-Treatment state data broadcast timer counter. static OVERRIDE_U32_T preTreatmentStatePublishInterval; ///< Pre-Treatment state data publication interval override. +static BOOL resumePreTxAlarmResponseRequest; ///< Flag indicates user has requested PreTx resume. + // ********** private function prototypes ********** static void setPreTreatStateTransition( void ); ///< Configure actuators and variables for Pre-Treatment state transitions. @@ -105,13 +108,13 @@ { initPreTreatmentMode(); initTubeSetInstall(); + initPrime(); // TODO: remove after implementing blood pump homing in some state homeBloodPump(); - // TODO: remove these homeValve() when SELF_TEST_NO_CART_STATE is implemented (homing valves is handled over there). - homeValve(H1_VALV, FALSE, FALSE); - homeValve(H19_VALV, FALSE, FALSE); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); return (U32)currentPreTreatmentState; } @@ -143,11 +146,11 @@ break; case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: - // currentPreTreatmentState = handleSelfTestDryState(); + currentPreTreatmentState = handleSelfTestDryState(); break; case TD_PRE_TREATMENT_PRIME_STATE: - // currentPreTreatmentState = handlePrimeState(); + currentPreTreatmentState = handlePrimeState(); break; case TD_PRE_TREATMENT_CONFIRM_RX_STATE: @@ -211,7 +214,9 @@ break; case TD_PRE_TREATMENT_CONFIRM_RX_STATE: - // No action required. + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); break; case TD_PRE_TREATMENT_RECIRCULATE_STATE: @@ -220,14 +225,14 @@ case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: signalBloodPumpHardStop(); - setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); stopSyringePump(); - // TODO: Set H5 ejector Off. + // TODO: Set H5 ejector Off.state // TODO: Command DD to bypass dialyzer, set QDt to prescribed rate, // Quf to 0, and Qs to 0. break; @@ -283,8 +288,8 @@ state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; } - // TODO: Transition to Prime state on completion when implemented - // state = TD_PRE_TREATMENT_PRIME_STATE; + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + state = TD_PRE_TREATMENT_PRIME_STATE; return state; } @@ -293,17 +298,24 @@ * @brief * The handlePrimeState function executes the Prime state of * pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any + * @details \b Inputs: none + * @details \b Outputs: none * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_PRIME_STATE; - // TODO: Transition to Recirculate state on completion when implemented - // state = TD_PRE_TREATMENT_RECIRCULATE_STATE; + execPrime(); + if ( PRIME_COMPLETE_STATE == getCurrentPrimeState() ) + { + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TD_PRIME_COMPLETE, (U32)getCurrentPrimeState() ); + transitionToPreTxRecirculate(); + state = TD_PRE_TREATMENT_RECIRCULATE_STATE; + } + return state; } @@ -321,9 +333,11 @@ execPreTxRecirculate(); - if ( TRUE == continueFromRecirculateRequested ) + //if ( TRUE == continueFromRecirculateRequested ) + if ( FALSE == isAnyAlarmActive() ) { - continueFromRecirculateRequested = FALSE; + //continueFromRecirculateRequested = FALSE; + endAirTrapControl(); state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; } @@ -360,7 +374,8 @@ presUFRateMlMin = ( presUFVolumeL * (F32)ML_PER_LITER ) / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); // Direct DD to generate dialysate and bypass while priming blood cmdStartGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFRateMlMin, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), TRUE, + 0, //getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), //TODO: Update temperature with tx param temp when we are ready + TRUE, getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), @@ -501,6 +516,7 @@ break; case ALARM_ACTION_RESUME: + resumePreTxAlarmResponseRequest = TRUE; if ( TD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) { signalResumePreTxRecirculate(); @@ -515,6 +531,17 @@ /*********************************************************************//** * @brief + * The signalPreTxResumeRequest function signals that user wants to resume. + * @details \b Inputs: resumePreTxAlarmResponseRequest + * @details \b Outputs: none + * @return TRUE if resume has been requested, FALSE if not + *************************************************************************/ +BOOL signalPreTxResumeRequest( void ) +{ + return resumePreTxAlarmResponseRequest; +} + +/*********************************************************************//** * The publishPreTreatmentStates function publishes the current * Pre-Treatment state and associated sub-state data to the UI. * @details \b Inputs: currentPreTreatmentState, preTreatmentStatePublishInterval Index: firmware/App/Modes/ModePreTreat.h =================================================================== diff -u -ree84e20f729b0aace2b1728c16de9a89e06eee38 -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision ee84e20f729b0aace2b1728c16de9a89e06eee38) +++ firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -8,7 +8,7 @@ * @file ModePreTreat.h * * @author (last) Vijay Pamula -* @date (last) 12-Jun-2026 +* @date (last) 30-Jul-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -36,11 +36,15 @@ U32 transitionToPreTreatmentMode( void ); // Prepares for transition to pre-treatment mode U32 execPreTreatmentMode( void ); // Execute the pre-treatment mode state machine (call from OperationModes) void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ); // Execute alarm action as appropriate for pre-treatment mode -BOOL signalPreTxResumeRequest( void ); +BOOL signalPreTxResumeRequest( void ); // Signal resume alarm response from user -void PreTxRequestTubeSetInstall( void ); // Request Pre-Treatment mode to transition to Install state. -void PreTxRequestContinueFromRecirculate( void ); // Request Pre-Treatment mode to transition to Patient Connection state. +void PreTxRequestTubeSetInstall( void ); // Request Pre-Treatment mode to transition to Install state. +void PreTxRequestContinueFromRecirculate( void ); // Request Pre-Treatment mode to transition to Confirm Rx. +BOOL handleStartTreatmentRequest ( MESSAGE_T *message ); // Handle UI request to start treatment. +BOOL signalPreTreatmentBackoutToStandby( void ); // Request transition from Pre-Treatment Install: Await Confirmation to Standby. +BOOL testPreTreatmentStatePublishIntervalOverride( MESSAGE_T *message ); + /**@}*/ #endif Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r83310420ae862de4724f8cfbbaeda9936c47801b -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 83310420ae862de4724f8cfbbaeda9936c47801b) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -8,7 +8,7 @@ * @file ModeStandby.c * * @author (last) Vijay Pamula -* @date (last) 07-Jul-2026 +* @date (last) 27-Jul-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -275,7 +275,7 @@ respRecord.tmpPresLimitWindowmmHg = getSysConfigTreatmentParameterU32DefaultValue( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ); sendPressureLimitsChangeResponse( &respRecord ); // start DD pre-gen // TODO - cmdStartPreGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + cmdStartPreGenerateDialysate( 600, //(F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, @@ -399,8 +399,9 @@ } else if ( USER_COMMAND_CANCEL == cmd ) { - //result = signalUserCancelTreatment(); - if ( result != TRUE ) + result = signalPreTreatmentBackoutToStandby(); + + if ( TRUE != result ) { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r83310420ae862de4724f8cfbbaeda9936c47801b -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 83310420ae862de4724f8cfbbaeda9936c47801b) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -7,8 +7,8 @@ * * @file ModeTreatment.c * -* @author (last) Vijay Pamula -* @date (last) 26-Jun-2026 +* @author (last) Praneeth Bunne +* @date (last) 10-Aug-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -30,6 +30,8 @@ #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" //#include "Switches.h" #include "TaskGeneral.h" #include "Timers.h" @@ -91,9 +93,13 @@ static BOOL resumeTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment resume. static BOOL initiateRinsebackAlarmResponseRequest; ///< Flag indicates user has requested rinseback. static BOOL endTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment end. +static BOOL initiateTempBreakALarmReponseRequest; ///< Flag indicates user has requested temporary break. static BOOL endTreatmentRequest; ///< Flag indicates user has requested end of treatment from rinseback workflow. static BOOL bloodPrimeToDialysisRequest; ///< Flag indicates blood prime has completed and time to start dialysis. static BOOL resumeBlockedByAlarm; ///< Flag indicates an alarm has blocked resume of this treatment. +static BOOL rinsebackToRecircRequest; ///< Flag indicates rinseback sub-mode has requested transition to Re-circulate. +static BOOL recirculateToBloodPrimeRequest; ///< Flag indicates re-circulate sub-mode has requested transition to Treatment Blood prime. +static BOOL recircAllowed; ///< Flag indicates re-circulate allowed only if user selects temp break option. static U32 treatmentStartTimeStamp; ///< Treatment start timestamp for logging purpose. static U32 treatmentEndTimeStamp; ///< Treatment end timestamp for logging purpose. @@ -131,6 +137,7 @@ treatmentCompleted = FALSE; rinsebackDone = FALSE; resumeBlockedByAlarm = FALSE; + recircAllowed = FALSE; treatmentTimePublishInterval.data = TREATMENT_TIME_DATA_PUB_INTERVAL; treatmentTimePublishInterval.ovData = TREATMENT_TIME_DATA_PUB_INTERVAL; @@ -185,8 +192,8 @@ initBloodPrime(); initDialysis(); initTreatmentPaused(); -// initRinseback(); -// initTreatmentRecirc(); + initRinseback(); + initTreatmentRecirc(); // initTreatmentEnd(); initFluidBolus(); @@ -210,7 +217,8 @@ // Direct DD to generate dialysate and bypass while priming blood cmdStartGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFRateMlMin, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), TRUE, + 0, //getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), //TODO: Update temperature with tx param temp when we are ready + TRUE, getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), @@ -266,6 +274,20 @@ /*********************************************************************//** * @brief + * The isRecircAllowed function determines whether the recirculation is + * allowed or not. Only allowed in temporary break option + * seen an alarm that prevents resumption. + * @details \b Inputs: recircAllowed + * @details \b Outputs: none + * @return isRecircAllowed + *************************************************************************/ +BOOL isRecircAllowed( void ) +{ + return recircAllowed; +} + +/*********************************************************************//** + * @brief * The getTreatmentTimeRemainingSecs function determines the number of seconds * remaining in the treatment. * @details \b Inputs: presTreatmentTimeSecs, treatmentTimeMS @@ -349,6 +371,35 @@ /*********************************************************************//** * @brief + * The setRinsebackIsCompleted function sets that flag indicating whether a + * rinseback has been completed. Call this function with TRUE when rinseback + * operation is completed. Call this function with FALSE at start of blood + * prime operation. + * @details Inputs: none + * @details Outputs: rinsebackDone + * @param flag TRUE if rinseback has been completed, FALSE if not + * @return none + *************************************************************************/ +void setRinsebackIsCompleted( BOOL flag ) +{ + rinsebackDone = flag; +} + +/*********************************************************************//** + * @brief + * The getRinsebackIsCompleted function determines whether a rinseback has been + * completed (indicating blood-side circuit should be primarily saline or online fluid). + * @details Inputs: rinsebackDone + * @details Outputs: none + * @return rinsebackDone + *************************************************************************/ +BOOL getRinsebackIsCompleted( void ) +{ + return rinsebackDone; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToTreatmentMode function executes the given alarm action * as appropriate while in Treatment Mode. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid alarm action given. @@ -381,6 +432,10 @@ // Nothing to be done here break; + case ALARM_ACTION_TEMPORARY_BREAK: + initiateTempBreakALarmReponseRequest = TRUE; + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_INVALID_ALARM_ACTION, (U32)action ) break; @@ -415,6 +470,32 @@ /*********************************************************************//** * @brief + * The signalGoToBloodPrime function signals that user wants to return + * to treatment blood prime from recirculate workflow. + * @details Inputs: none + * @details Outputs: recirculateToBloodPrimeRequest + * @return none + *************************************************************************/ +void signalGoToBloodPrime( void ) +{ + recirculateToBloodPrimeRequest = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalRinsebackToRecirc function signals that user wants to continue + * on to re-circulate portion of rinseback workflow. + * @details Inputs: none + * @details Outputs: rinsebackToRecircRequest + * @return none + *************************************************************************/ +void signalRinsebackToRecirc( void ) +{ + rinsebackToRecircRequest = TRUE; +} + +/*********************************************************************//** + * @brief * The execTreatmentMode function executes the Treatment Mode state machine. * @details \b Alarm: ALARM_ID_TD_TREATMENT_PED_BY_USER if user presses * the button @@ -562,8 +643,9 @@ * @brief * The handleTreatmentBloodPrimeState function handles the blood prime state of * the Treatment Mode state machine. - * @details \b Inputs: presUFRate - * @details \b Outputs: none + * @details \b Inputs: presUFRate, bloodPrimeToDialysisRequest, recircAllowed + * @details \b Outputs: lastTreatmentTimeStamp, presUFRate, presUFVolumeMl, + * presUFRateMlMin, recircAllowed * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ) @@ -594,6 +676,39 @@ // { // sendTreatmentLogEventData( UF_START_RESUME_EVENT, 0.0, presUFRate ); // } + + // Came back from temp break? + if ( TRUE == recircAllowed ) + { + // Add rinseback volume (ml) to uf volume. + F32 newUFVolumeMl = ( getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) * + (F32)ML_PER_LITER ) + getDeliveredRinsebackVolume(); + F32 remainingTimeMins = (F32)( getTreatmentTimeRemainingSecs() / SEC_PER_MIN ); + F32 newUFRateMlMin = ( remainingTimeMins > 0.0F ) ? + ( newUFVolumeMl / remainingTimeMins ) : 0.0F; + + // Clamp to max UF volume + if ( newUFVolumeMl > (F32)MAX_UF_VOLUME_ML ) + { + newUFVolumeMl = (F32)MAX_UF_VOLUME_ML; + } + + // Clamp to max UF rate + if ( newUFRateMlMin > MAX_UF_RATE_ML_MIN ) + { + newUFRateMlMin = MAX_UF_RATE_ML_MIN; + } + + presUFVolumeMl = newUFVolumeMl; + presUFRateMlMin = newUFRateMlMin; + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, + presUFVolumeMl / (F32)ML_PER_LITER ); + setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + presUFVolumeMl, + presUFRateMlMin ); + recircAllowed = FALSE; + } + transitionToDialysis(); // // To update partial blood pump occlusion baseline - start of treatment // signalBloodPumpPressureOcclBaseline(); @@ -659,8 +774,9 @@ * @brief * The handleTreatmentPausedState function executes the Paused state of the * Treatment Mode state machine. - * @details \b Inputs: none - * @details \b Outputs: treatment paused sub-mode executed. + * @details \b Inputs: resumeTreatmentAlarmResponseRequest, initiateTempBreakALarmReponseRequest, + * initiateRinsebackAlarmResponseRequest, endTreatmentAlarmResponseRequest + * @details \b Outputs: lastTreatmentTimeStamp, recircAllowed * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentPausedState( void ) @@ -671,8 +787,6 @@ // If user requests resumption of treatment, resume treatment if ( TRUE == resumeTreatmentAlarmResponseRequest ) { - resumeTreatmentAlarmResponseRequest = FALSE; - if ( TRUE == getBloodIsPrimed() ) { lastTreatmentTimeStamp = getMSTimerCount(); @@ -686,18 +800,26 @@ } signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); } - // If user requests rinseback, go to rinseback -// else if ( TRUE == initiateRinsebackAlarmResponseRequest ) -// { -// transitionToRinseback(); -// result = TREATMENT_RINSEBACK_STATE; -// } + // If user requests temp break, go to rinseback and then recirc + else if ( TRUE == initiateTempBreakALarmReponseRequest ) + { + recircAllowed = TRUE; + transitionToRinseback(); + result = TREATMENT_RINSEBACK_STATE; + } + // If user requests blood return & end treatemnt, go to rinseback only and end treat + else if ( TRUE == initiateRinsebackAlarmResponseRequest ) + { + recircAllowed = FALSE; + transitionToRinseback(); + result = TREATMENT_RINSEBACK_STATE; + } // If user requests treatment end, end treatment -// else if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } + else if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + requestNewOperationMode( MODE_POST ); + } // Otherwise execute state machine for treatment paused sub-mode else { @@ -723,89 +845,75 @@ * The handleTreatmentRinsebackState function executes the rinseback state of the * Treatment Mode state machine. * @details \b Inputs: endTreatmentAlarmResponseRequest, resumeTreatmentAlarmResponseRequest, - * rinsebackToRecircRequest, rinsebackTopedRequest, endTreatmentRequest - * @details \b Outputs: treatment rinseback sub-mode executed, sendLastTreatmentPeriodicData + * rinsebackToRecircRequest + * @details \b Outputs: sendLastTreatmentPeriodicData * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentRinsebackState( void ) { TREATMENT_STATE_T result = TREATMENT_RINSEBACK_STATE; -// // If user requests treatment end, end treatment -// if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } -// // Otherwise execute state machine for treatment rinseback sub-mode -// else -// { -// // If user requests resumption of treatment, resume rinseback -// if ( TRUE == resumeTreatmentAlarmResponseRequest ) -// { -// resumeTreatmentAlarmResponseRequest = FALSE; -// signalRinsebackAlarmResumeUserAction(); -// } -// // Execute treatment rinseback sub-mode -// execRinseback(); -// } -// -// // Handle signals from rinseback sub-mode -// if ( TRUE == rinsebackToRecircRequest ) -// { -// transitionToTreatmentRecirc(); -// result = TREATMENT_RECIRC_STATE; -// } -// else if ( TRUE == rinsebackTopedRequest ) -// { -// transitionToTreatment(); -// result = TREATMENT_PAUSED_STATE; -// } -// else if ( TRUE == endTreatmentRequest ) -// { -// requestNewOperationMode( MODE_POST ); -// } + // If user requests treatment end, end treatment + if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + requestNewOperationMode( MODE_POST ); + } + else + { + // Forward alarm resume action to rinseback sub-mode as a rinseback specific resume + if ( TRUE == resumeTreatmentAlarmResponseRequest ) + { + signalRinsebackAlarmResumeUserAction(); + } + // Execute treatment rinseback sub-mode + execRinseback(); + } + + // Handle signals from rinseback sub-mode + if ( TRUE == rinsebackToRecircRequest ) + { + transitionToTreatmentRecirc(); + result = TREATMENT_RECIRC_STATE; + } + return result; } /*********************************************************************//** * @brief * The handleTreatmentRecircState function executes the re-circulate state of the * Treatment Mode state machine. - * @details \b Inputs: endTreatmentAlarmResponseRequest, rinsebackTopedRequest, - * endTreatmentRequest + * @details \b Inputs: endTreatmentAlarmResponseRequest, recirculateToBloodPrimeRequest * @details \b Outputs: sendLastTreatmentPeriodicData * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentRecircState( void ) { TREATMENT_STATE_T result = TREATMENT_RECIRC_STATE; -// // If user requests treatment end, end treatment -// if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } -// else -// { -// // Execute treatment re-circ sub-mode -// execTreatmentRecirc(); -// } -// -// // Handle signals from treatment re-circ sub-mode -// if ( TRUE == rinsebackTopedRequest ) -// { -// Dialysis(); -// transitionToTreatment(); -// result = TREATMENT__STATE; -// } -// else if ( TRUE == endTreatmentRequest ) -// { -// requestNewOperationMode( MODE_POST ); -// } + // If user requests treatment end, end treatment + if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + // Stop dialysate generation + cmdStopGenerateDialysate(); + requestNewOperationMode( MODE_POST ); + } + else + { + // Execute treatment re-circ sub-mode + execTreatmentRecirc(); + } + // Back to blood prime when user requests resume treatment + if ( TRUE == recirculateToBloodPrimeRequest ) + { + transitionToBloodPrime(); + result = TREATMENT_BLOOD_PRIME_STATE; + } + return result; } @@ -910,8 +1018,8 @@ payload.dialysisState = getDialysisState(); payload.isoUFState = 0; payload.txPausedState = getCurrentTreatmentPausedState(); - payload.rinsebackState = 0; // getCurrentRinsebackState(); - payload.txRecircState = 0; // getCurrentTreatmentRecircState(); + payload.rinsebackState = getCurrentRinsebackState(); + payload.txRecircState = getCurrentTreatmentRecircState(); payload.txEndState = 0; // getCurrentTreatmentEndState(); payload.txFluidBolusState = getCurrentFluidBolusState(); payload.txHepState = 0; // @@ -1095,11 +1203,11 @@ *************************************************************************/ static void resetSignalFlags( void ) { -// rinsebackTopedRequest = FALSE; endTreatmentRequest = FALSE; -// rinsebackToRecircRequest = FALSE; + rinsebackToRecircRequest = FALSE; bloodPrimeToDialysisRequest = FALSE; -// treatmentEndToRinsebackRequest = FALSE; +// treatmentEndToRinsebackRequest = FALSE; // TODO: Declare & uncomment when end treat is implemented. + recirculateToBloodPrimeRequest = FALSE; } /*********************************************************************//** @@ -1114,6 +1222,7 @@ resumeTreatmentAlarmResponseRequest = FALSE; initiateRinsebackAlarmResponseRequest = FALSE; endTreatmentAlarmResponseRequest = FALSE; + initiateTempBreakALarmReponseRequest = FALSE; } /*********************************************************************//** Index: firmware/App/Modes/StateTxDialysis.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -8,7 +8,7 @@ * @file StateTxDialysis.c * * @author (last) Praneeth Bunne -* @date (last) 03-Jun-2026 +* @date (last) 09-Jul-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -117,12 +117,13 @@ // Set user alarm recovery actions allowed in this sub-mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_TEMPORARY_BREAK, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); // Set actuators as appropriate for state - cmdStartGenerateDialysate( setDialysateFlowRate, setUFRateMlMin, dialTemp, FALSE, - acidConvFactor, bicarbConvFactor, sodium, bicarbonate ); + cmdStartGenerateDialysate( setDialysateFlowRate, setUFRateMlMin, 0, //dialTemp, //TODO: Update temperature with dialTemp when we are ready + FALSE, acidConvFactor, bicarbConvFactor, sodium, bicarbonate ); transitionToDialysisState( currentDialysisState ); // Set substate for event Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -8,7 +8,7 @@ * @file AlarmMgmtSWFaults.h * * @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @date (last) 07-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -199,12 +199,17 @@ SW_FAULT_ID_PRE_TX_RECIRC_INVALID_STATE = 168, SW_FAULT_ID_TD_VALVES_INVALID_VALVE2 = 169, SW_FAULT_ID_INVALID_TUBE_SET_TYPE = 170, - SW_FAULT_ID_MODE_PRE_TX_PRIME_INVALID_STATE = 171, - SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER1 = 172, - SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER3 = 173, - SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER4 = 174, - SW_FAULT_ID_PID_CTRL_INVALID_SIGNAL = 175, - SW_FAULT_ID_INVALID_DD_BAL_CHAMBER_DATA = 176, + SW_FAULT_ID_INVALID_MESSAGE_PAYLOAD_LENGTH = 171, + SW_FAULT_ID_TD_BP_DRIVER_STATE = 172, + SW_FAULT_ID_TD_BP_MODULE_STATE = 173, + SW_FAULT_ID_INVALID_RINSEBACK_STATE = 174, + SW_FAULT_ID_TREATMENT_INVALID_RECIRC_STATE = 175, + SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER1 = 176, + SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER3 = 177, + SW_FAULT_ID_PID_CTRL_INVALID_CONTROLLER4 = 178, + SW_FAULT_ID_PID_CTRL_INVALID_SIGNAL = 179, + SW_FAULT_ID_MODE_PRE_TX_PRIME_INVALID_STATE = 180, + SW_FAULT_ID_INVALID_DD_BAL_CHAMBER_DATA = 181, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @author (last) Praneeth Bunne +* @date (last) 10-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -21,6 +21,7 @@ #include "AirTrap.h" #include "AlarmMgmt.h" #include "BloodFlow.h" +#include "BPModule.h" #include "Bubbles.h" #include "Buttons.h" #include "Compatible.h" @@ -31,6 +32,8 @@ #include "FpgaTD.h" #include "LevelSensors.h" #include "Messaging.h" +#include "ModeInitPOST.h" +#include "ModePreTreat.h" #include "ModeStandby.h" #include "ModeTreatment.h" #include "OperationModes.h" @@ -41,6 +44,8 @@ #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" #include "Switches.h" #include "SyringePump.h" #include "SystemCommTD.h" @@ -112,6 +117,7 @@ { MSG_ID_FW_VERSIONS_REQUEST, &handleVersionRequestMessage }, { MSG_ID_UI_CHECK_IN, &handleUICheckIn }, { MSG_ID_DD_OP_MODE_DATA, &setDDOpMode }, + { MSG_ID_UI_VERSION_INFO_RESPONSE, &handleUIVersionResponse }, { MSG_ID_DD_GEN_DIALYSATE_MODE_DATA, &setDialysateData }, { MSG_ID_DD_PRESSURES_DATA, &setDialysatePressure }, { MSG_ID_UI_TREATMENT_PARAMS_TO_VALIDATE, &validateAndSetTreatmentParameters }, @@ -122,6 +128,7 @@ { MSG_ID_UI_VITALS_ADJUSTMENT_REQUEST, &vitalsAdjustmentHandleChangeRequest }, { MSG_ID_UI_BOLUS_VOLUME_CHANGE_REQUEST, &validateAndSetBolusVolume }, { MSG_ID_UI_INITIATE_TREATMENT_WORKFLOW, &signalUserInitiateTreatment }, + { MSG_ID_UI_START_TREATMENT_REQUEST, &handleStartTreatmentRequest }, { MSG_ID_UI_UF_PAUSE_RESUME_REQUEST, &signalPauseResumeUF }, { MSG_ID_TESTER_LOGIN_REQUEST, &handleTesterLogInRequest }, { MSG_ID_UI_PRESSURE_LIMIT_WIDEN_REQUEST, &pressureLimitHandleWidenRequest }, @@ -135,8 +142,12 @@ { MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST, &handleAutoLoadRequest }, { MSG_ID_UI_SETUP_TUBING_SET_CONNECTIONS_CONFIRM_REQUEST, &handleSetupTubingSetConnectionConfirmRequest }, { MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST, &handleAutoEjectRequest }, + { MSG_ID_UI_BLOOD_PRESSURE_REQUEST, &bpModuleHandleVitalsRequest }, { MSG_ID_FFU_SIGNAL_TD_UPDATE_AVAILABLE, &handleUpdateAvailable }, { MSG_ID_UI_FLUID_BOLUS_REQUEST, &handleFluidBolusRequest }, + { MSG_ID_UI_RINSEBACK_CMD_REQUEST, &signalRinsebackUserAction }, + { MSG_ID_UI_RECIRCULATE_REQUEST, &signalTreatmentRecircUserAction }, + { MSG_ID_UI_GENERIC_CONFIRMATION_RESULT_RESPONSE, &handleUIConfirmation }, { MSG_ID_TD_SOFTWARE_RESET_REQUEST, &testTDSoftwareResetRequest }, { MSG_ID_TD_BUBBLE_OVERRIDE_REQUEST, &testBubbleDetectOverride }, { MSG_ID_TD_BUBBLE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testBubblesDataPublishIntervalOverride }, @@ -146,6 +157,7 @@ { MSG_ID_TD_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testPressuresDataPublishIntervalOverride }, { MSG_ID_TD_AIR_PUMP_SET_STATE_REQUEST, &testSetAirPump }, { MSG_ID_TD_AIR_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testAirPumpDataPublishIntervalOverride }, + { MSG_ID_TD_AIR_PUMP_RPM_OVERRIDE_REQUEST, &testAirPumpRPMOverride }, { MSG_ID_TD_SWITCHES_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testSwitchesDataPublishIntervalOverride }, { MSG_ID_TD_SWITCH_STATE_OVERRIDE_REQUEST, &testSwitchOverride }, { MSG_ID_TD_OFF_BUTTON_OVERRIDE_REQUEST, &testOffButtonOverride }, @@ -220,6 +232,8 @@ { MSG_ID_TD_HEPARIN_BOLUS_TARGET_RATE_OVERRIDE_REQUEST, &testHeparinBolusTargetRateOverride }, { MSG_ID_TD_SYRINGE_PUMP_FORCE_SENSOR_CALIBRATION_REQUEST, &testCalibrateForceSensor }, { MSG_ID_TD_GET_ALARM_PROPERTIES_REQUEST, &testGetAlarmPropertiesRequest }, + { MSG_ID_TD_RINSEBACK_VOLUME_OVERRIDE, &testRinsebackVolumeOverride }, + { MSG_ID_TD_RINSEBACK_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRinsebackPublishIntervalOverride }, { MSG_ID_TD_PRIME_PUBLISH_INTERVAL_OVERRIDE, &testPrimePublishIntervalOverride }, }; @@ -241,7 +255,6 @@ static MsgFuncPtr getMsgHandler( U16 msgID ); static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); /*********************************************************************//** * @brief @@ -400,7 +413,7 @@ * @param ack TRUE to ACK, FALSE to NAK * @return TRUE if response message successfully queued for transmit, FALSE if not *************************************************************************/ -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) +BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) { BOOL result; MESSAGE_T msg; @@ -527,7 +540,79 @@ return result; } +/*********************************************************************//** + * @brief + * The handleUIVersionResponse function handles a response to request for + * UI version information. + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle. + * @return none + *************************************************************************/ +BOOL handleUIVersionResponse( MESSAGE_T *message ) +{ + BOOL result = TRUE; + // Get UI version data and have it recorded + if ( sizeof(UI_VERSIONS_T) == message->hdr.payloadLen ) + { + UI_VERSIONS_T uiVersion; + + memcpy( &uiVersion, &message->payload[ 0 ], sizeof(UI_VERSIONS_T) ); + signalUIVersion( uiVersion ); + } + + return result; +} + +/*********************************************************************//** + * The sendPOSTFinalResult function sends the overall TD POST result + * and queues the message for transmit on the appropriate CAN channel. + * @details \b Message \b Sent: MSG_ID_TD_POST_FINAL_TEST_RESULT + * @details \b Inputs: none + * @details \b Outputs: TD POST final result msg queued for CAN transmit. + * @param passed TRUE if all TD POST tests passed, FALSE otherwise. + * @return TRUE if message successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTFinalResult( BOOL passed ) +{ + // Use the generic send helper for transmission. + return sendMessage( MSG_ID_TD_POST_FINAL_TEST_RESULT, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08 *)&passed, sizeof( BOOL ) ); +} + +/*********************************************************************//** + * @brief + * The handleUIConfirmationResponse function handles a UI response for a + * confirmation request. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message pointer to the received confirmation response message + * @return TRUE if message handled successfully, FALSE if not + *************************************************************************/ +BOOL handleUIConfirmation( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( ( 2U * sizeof(U32) ) == message->hdr.payloadLen ) + { + U32 requestID; + U32 status; + + memcpy( &requestID, message->payload, sizeof(U32) ); + memcpy( &status, message->payload + sizeof(U32), sizeof(U32) ); + + if ( ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == ( CONFIRMATION_REQUEST_STATUS_T)status ) || + ( CONFIRMATION_REQUEST_STATUS_REJECTED == ( CONFIRMATION_REQUEST_STATUS_T)status ) ) + { + setConfirmationRequestStatus( ( GENERIC_CONFIRM_ID_T )requestID, + ( CONFIRMATION_REQUEST_STATUS_T)status ); + result = TRUE; + } + } + + return result; +} + // *********************************************************************** // ***************** Message Sending Helper Functions ******************** // *********************************************************************** @@ -572,36 +657,108 @@ /*********************************************************************//** * @brief - * The sendOffButtonMsgToUI function constructs an off button msg to the UI - * and queues the msg for transmit on the appropriate CAN channel. - * @details \b Message \b Sent: MSG_ID_OFF_BUTTON_PRESS_REQUEST + * The sendUIVersionRequest function constructs a UI version request msg + * to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details \b Message \b Sent: MSG_ID_TD_UI_VERSION_INFO_REQUEST * @details \b Inputs: none - * @details \b Outputs: Off button msg constructed and queued. - * @param prompt 0=prompt user to confirm, 1=cancel prompt, 2=reject user off request + * @details \b Outputs: none * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendOffButtonMsgToUI( U08 prompt ) +BOOL sendUIVersionRequest( void ) { BOOL result; MESSAGE_T msg; - UI_OFF_BUTTON_RESPONSE_PAYLOAD_T cmd; - cmd.userRequest = prompt; - // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_OFF_BUTTON_PRESS_REQUEST; - msg.hdr.payloadLen = sizeof( UI_OFF_BUTTON_RESPONSE_PAYLOAD_T ); + msg.hdr.msgID = MSG_ID_TD_UI_VERSION_INFO_REQUEST; + msg.hdr.payloadLen = 0; - memcpy( &msg.payload, &cmd, sizeof( UI_OFF_BUTTON_RESPONSE_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_TD_2_UI, ACK_REQUIRED ); return result; } +/*********************************************************************//** + * @brief + * The sendRequestForDDResendAlarms function sends out the TD request for + * DD re-send all active alarms. + * @details \b Inputs: none + * @details \b Outputs: DD alarms re-send request msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendRequestForDDResendAlarms( void ) +{ + BOOL result; + MESSAGE_T msg; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_TD_DD_ALARMS_REQUEST; + msg.hdr.payloadLen = 0; + + // 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_TD_2_DD, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * The sendPOSTTestResult function sends the result of a single TD POST + * test to the UI. + * @details \b Message \b Sent: MSG_ID_TD_POST_SINGLE_TEST_RESULT + * @details \b Inputs: none + * @details \b Outputs: TD POST test result msg queued for CAN transmit. + * @param test ID of the TD POST test. + * @param passed TRUE if POST test passed, FALSE if POST test failed. + * @return TRUE if message successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTTestResult( TD_POST_STATE_T test, BOOL passed ) +{ + U08 payload[ sizeof( BOOL ) + sizeof( U32 ) ]; + U32 testID = (U32)test; + + memcpy( payload, &passed, sizeof( BOOL ) ); + memcpy( &payload[ sizeof( BOOL ) ], &testID, sizeof( U32 ) ); + + // Use the generic send helper for transmission. + return sendMessage( MSG_ID_TD_POST_SINGLE_TEST_RESULT, COMM_BUFFER_OUT_CAN_TD_BROADCAST, payload, sizeof( payload ) ); +} + +/*********************************************************************//** + * @brief + * The sendConfirmationRequest function constructs and transmits a + * confirmation request message to the UI. + * @details \b Message \b Sent: MSG_ID_TD_UI_GENERIC_CONFIRMATION_REQUEST + * @details \b Inputs: none + * @details \b Outputs: none + * @param requestID ID of the confirmation being requested + * @param requestType Type of confirmation being requested + * @param rejectReason Reason for reject if type is reject, 0 otherwise + * @return none + *************************************************************************/ +void sendConfirmationRequest( GENERIC_CONFIRM_ID_T requestID, + GENERIC_CONFIRM_COMMAND_T requestType, + U32 rejectReason ) +{ + GENERIC_CONFIRMATION_REQUEST_T payload; + + payload.requestID = (U32)requestID; + payload.requestType = (U32)requestType; + payload.rejectReason = rejectReason; + payload.genericPayload1 = 0.0F; + payload.genericPayload2 = 0.0F; + payload.genericPayload3 = 0.0F; + payload.genericPayload4 = 0.0F; + + sendMessage( MSG_ID_TD_UI_GENERIC_CONFIRMATION_REQUEST, + COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08*)&payload, + sizeof( GENERIC_CONFIRMATION_REQUEST_T ) ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Services/StateServices/Prime.c =================================================================== diff -u -r25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe -r6c933adfd50a0bc041dc29f4bfa15de5e9f4843a --- firmware/App/Services/StateServices/Prime.c (.../Prime.c) (revision 25aeff9e9994d2e7aab3b4e6171c56fdac6a01fe) +++ firmware/App/Services/StateServices/Prime.c (.../Prime.c) (revision 6c933adfd50a0bc041dc29f4bfa15de5e9f4843a) @@ -317,6 +317,7 @@ case PRIME_DC_INITIAL_DIALYSATE_STATE: dcInitialPrimeInterval = (U32)( ( ( dialyzerDialysateVolume * 60.0F ) / (F32)TARGET_DIALYSATE_FLOW_RATE + 30.0F ) * (F32)MS_PER_SECOND ); startProgressSequence( dcInitialPrimeInterval ); + dcInitialPrimeTimerCtr = 0; cmdBypassDialyzer( FALSE ); stateEntryTimerCtr = getMSTimerCount(); break; @@ -356,6 +357,7 @@ dcReversePrimeDuration = (U32)( ( ( dialyzerDialysateVolume * 0.5F * (F32)SEC_PER_MIN ) / (F32)MAX_UF_RATE ) + 30.0F ) * (F32)MS_PER_SECOND; dcDiscardAndRevPrimeInterval = ( dcDiscardDuration > dcReversePrimeDuration ) ? dcDiscardDuration : dcReversePrimeDuration; startProgressSequence( dcDiscardAndRevPrimeInterval ); + startAirTrapControl(); signalBloodPumpHardStop(); cmdDDprimeFluidDiscard( TRUE ); setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); @@ -370,6 +372,7 @@ setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + endAirTrapControl(); setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); @@ -908,7 +911,9 @@ if ( DD_GEND_DIALYSATE_DELIVERY_STATE == getCurrentGenDState() ) { - if ( ++dcInitialPrimeTimerCtr >= dcInitialPrimeInterval ) + dcInitialPrimeTimerCtr += TASK_GENERAL_INTERVAL; + + if ( dcInitialPrimeTimerCtr >= dcInitialPrimeInterval ) { setPrimeStateTransition( PRIME_WAIT_FOR_AIR_TRAP_FILL_STATE ); state = PRIME_WAIT_FOR_AIR_TRAP_FILL_STATE; @@ -1171,11 +1176,14 @@ elapsedMs = calcTimeSince( primeStartTime ); } - elapsedMs = ( elapsedMs > primeTimeCreditMs ) ? ( elapsedMs - primeTimeCreditMs ) : 0; - remainingMs = ( elapsedMs < PRIME_TOTAL_DURATION_INTERVAL ) ? ( PRIME_TOTAL_DURATION_INTERVAL - elapsedMs ) : 0; + // Updates total remaining time if any sequence done early. + remainingMs = ( remainingMs > primeTimeCreditMs ) ? + ( remainingMs - primeTimeCreditMs ) : 0; + + data.primeState = (U32)currentPrimeState; data.totalDurationSec = PRIME_TOTAL_DURATION_INTERVAL / MS_PER_SECOND; data.countDownSec = remainingMs / MS_PER_SECOND;