Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r2f82b22d4dc271fe3f955b17f75fb3191c429779 -r21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 2f82b22d4dc271fe3f955b17f75fb3191c429779) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -7,8 +7,8 @@ * * @file ModePreTreat.c * -* @author (last) Raghu Kallala -* @date (last) 08-May-2026 +* @author (last) Praneeth Bunne +* @date (last) 19-May-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -22,6 +22,7 @@ #include "OperationModes.h" #include "TaskGeneral.h" #include "Timers.h" +#include "TubeSetInstall.h" #include "TxParams.h" /** * @addtogroup TDPreTreatmentMode @@ -35,42 +36,53 @@ // ********** private data ********** static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state +static BOOL goToInstallStateRequested; ///< Flag indicating a request to transition to Install state. static BOOL alarmActionResumeReceived; ///< Flag indicates alarm action resume received. static BOOL tubeSetInstallRequested; ///< Request to re-enter install flow (mid-treatment / failure) static U32 submodeCompleteTransitionTimeCounter; ///< Sub-mode completed transition wait time counter. // ********** private function prototypes ********** -static TD_PRE_TREATMENT_MODE_STATE_T handleDrySelfTestState( void ); ///< Handle dry self tests state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ); ///< Handle Water Sample state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ); ///< Handle Self Test Consumable state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ); ///< Handle Self Test No Cart state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); ///< Handle Install state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); ///< Handle Self Test Dry state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); ///< Handle Prime state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); ///< Handle Recirculate state during Pre-Treatment static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); ///< Handle Confirm Rx state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment +static TD_PRE_TREATMENT_MODE_STATE_T handleDrySelfTestState( void ); ///< Handle dry self tests state during Pre-Treatment /*********************************************************************//** * @brief * The initPreTreatmentMode function initializes the Pre-Treatment mode. -* @details Inputs: none -* @details Outputs: Resets the Treatment Parameters session and sets the initial +* @details \b Inputs: none +* @details \b Outputs: Resets the Treatment Parameters session and sets the initial * Pre-Treatment sub-state. * @return none **************************************************************************/ void initPreTreatmentMode( void ) { // Start a fresh Treatment Parameters session for this run. resetTreatmentParameters(); - currentPreTreatmentState = TD_PRE_TREATMENT_CART_INSTALL_STATE; + currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; + goToInstallStateRequested = FALSE; } /*********************************************************************//** * @brief * The transitionToPreTreatmentMode function prepares the system for * entry into Pre-Treatment mode. -* @details Inputs: none -* @details Outputs: Initializes mode specific state and returns the starting +* @details \b Inputs: none +* @details \b Outputs: Initializes mode specific state and returns the starting * Pre-Treatment sub-state. * @return Initial Pre-Treatment sub-state **************************************************************************/ U32 transitionToPreTreatmentMode( void ) { initPreTreatmentMode(); + initTubeSetInstall(); return (U32)currentPreTreatmentState; } @@ -79,8 +91,8 @@ * @brief * The execPreTreatmentMode function executes the Pre-Treatment * mode state machine. - * @details Inputs: stop button status and system conditions via helpers. - * @details Outputs: Advances the Pre-Treatment sub-state and + * @details \b Inputs: stop button status and system conditions via helpers. + * @details \b Outputs: Advances the Pre-Treatment sub-state and * previously received user confirmations. * @return current Pre-Treatment sub-state. *************************************************************************/ @@ -108,8 +120,8 @@ // currentPreTreatmentState = handleSelfTestNoCartState(); break; - case TD_PRE_TREATMENT_CART_INSTALL_STATE: - // currentPreTreatmentState = handleInstallState(); + case TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE: + currentPreTreatmentState = handleInstallState(); break; case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: @@ -156,6 +168,62 @@ /*********************************************************************//** * @brief + * The handleWaterSampleState function executes the Water Sample state of + * pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleWaterSampleState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_WATER_SAMPLE_STATE; + + // TODO: Transition to Self test consumable state on completion when implemented + // state = TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleSelfTestConsumableState function executes the Self Test + * Consumable state of pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestConsumableState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE; + + // TODO: Transition to Self test no cart state on completion when implemented + // state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleSelfTestNoCartState function executes the Self Test No Cart + * state of pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestNoCartState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE; + + // TODO: Transition to Tubing set install state on completion when implemented + // state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; + + return state; +>>>>>>> 0675141b5089536135dd205aeb65b62967ec3524 +} + +/*********************************************************************//** + * @brief +<<<<<<< HEAD * The handleSelfTestDryState function performs dry self-test. * @details \b Inputs: none * @details \b Outputs: transition to prime state on user request @@ -190,16 +258,98 @@ } } +======= + * The handleInstallState function calls Tube Set Install Service and + * advances to Self Test Dry state once the service signals + * completion. + * @details \b Inputs: none + * @details \b Outputs: Advances Pre-Treatment state when install is complete. + * @return next Pre-Treatment mode state + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; + + // call tube set install service to auto-load tube set + execTubeSetInstall(); + + if ( TRUE == isTubeSetInstallComplete() ) + { + state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + } + return state; } /*********************************************************************//** * @brief + * The handleSelfTestDryState function executes the Self Test Dry state + * of pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + + if ( TRUE == goToInstallStateRequested ) + { + goToInstallStateRequested = FALSE; + initTubeSetInstall(); + state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; + } + + // TODO: Transition to Prime state on completion when implemented + // state = TD_PRE_TREATMENT_PRIME_STATE; + + return state; +} + +/*********************************************************************//** + * @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 + * @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; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleRecirculateState function executes the Recirculate state of + * pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_RECIRCULATE_STATE; + + // TODO: Transition to Confirm RX state on completion when implemented + // state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + +>>>>>>> 0675141b5089536135dd205aeb65b62967ec3524 + return state; +} + +/*********************************************************************//** + * @brief * The handleRxState function executes the Confirm Rx pre-treatment step. * @details \b Inputs: none * @details \b Outputs: Requests transition to Treatment mode when the prescription * is valid and confirmed otherwise remains in Confirm Rx. - * @return next Pre-Treatment mode sub-state. + * @return next Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ) { @@ -242,6 +392,38 @@ /*********************************************************************//** * @brief + * The handlePatientConnectionState function executes the Patient + * Connection state of pre-treatment mode. + * @details \b Inputs: TODO fill up if any + * @details \b Outputs: TODO fill up if any + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + + // TODO : after implementing this state, place the transition in the right place + + //requestNewOperationMode( MODE_TREA ); + + return state; +} + +/*********************************************************************//** + * @brief + * The PreTxRequestTubeSetInstall function signals a request to transition + * the Pre-Treatment mode state machine to Install state. + * @details \b Inputs: none + * @details \b Outputs: goToInstallStateRequested + * @return none + *************************************************************************/ +void PreTxRequestTubeSetInstall( void ) +{ + goToInstallStateRequested = TRUE; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. * @details \b Inputs: none Index: firmware/App/Modes/ModePreTreat.h =================================================================== diff -u -r0da5bca220fe41798cf066597d47a5e279f6e8f0 -r21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 --- firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 0da5bca220fe41798cf066597d47a5e279f6e8f0) +++ firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -7,15 +7,14 @@ * * @file ModePreTreat.h * -* @author (last) Raghu Kallala -* @date (last) 08-May-2026 +* @author (last) Praneeth Bunne +* @date (last) 19-May-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 * ***************************************************************************/ - #ifndef __MODE_PRE_TREAT_H__ #define __MODE_PRE_TREAT_H__ @@ -39,6 +38,7 @@ void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ); // Execute alarm action as appropriate for pre-treatment mode TD_PRE_TREATMENT_MODE_STATE_T getPreTreatmentSubState( void ); // Get the current pre-treatment sub mode. +void PreTxRequestTubeSetInstall( void ); // Request Pre-Treatment mode to transition to Install state. /**@}*/ Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r0da5bca220fe41798cf066597d47a5e279f6e8f0 -r21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 0da5bca220fe41798cf066597d47a5e279f6e8f0) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -7,8 +7,8 @@ * * @file AlarmMgmtSWFaults.h * -* @author (last) Raghu Kallala -* @date (last) 30-Apr-2026 +* @author (last) Praneeth Bunne +* @date (last) 21-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -187,7 +187,16 @@ SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER = 156, SW_FAULT_ID_INVALID_TREATMENT_MODALITY = 157, SW_FAULT_ID_INVALID_DD_DIALYSATE_DATA = 158, - SW_FAULT_ID_TD_INVALID_DRY_SELF_TEST_STATE = 159, + SW_FAULT_ID_TD_SYRINGE_INVALID_BOLUS_CMD = 159, + SW_FAULT_ID_TD_SYRINGE_INVALID_CONT_CMD = 160, + SW_FAULT_ID_TD_SYRINGE_INVALID_STATE = 161, + SW_FAULT_ID_TD_SYRINGE_INVALID_VREF = 162, + SW_FAULT_ID_MODE_PRE_TX_INSTALL_INVALID_STATE = 163, + SW_FAULT_ID_MODE_POST_TREATMENT_INVALID_STATE = 164, + SW_FAULT_ID_MODE_POST_TREATMENT_INVALID_STATE1 = 165, + SW_FAULT_ID_MODE_POST_TX_AUTO_EJECT_INVALID_STATE = 166, + SW_FAULT_ID_INVALID_MESSAGE_PAYLOAD_LENGTH = 167, + SW_FAULT_ID_TD_INVALID_DRY_SELF_TEST_STATE = 168, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FpgaTD.c =================================================================== diff -u -r2f82b22d4dc271fe3f955b17f75fb3191c429779 -r21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 --- firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 2f82b22d4dc271fe3f955b17f75fb3191c429779) +++ firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -7,8 +7,8 @@ * * @file FpgaTD.c * -* @author (last) Jashwant Gantyada -* @date (last) 13-Mar-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 22-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -102,10 +102,10 @@ U16 fpgaGenWrRd; ///< Reg 256. FPGA general read-back register (mirrored from a general write register in write page at addr 4). U08 errorCountProcessor; ///< Reg 258. Error count for processor communications. U08 errorCountPC; ///< Reg 259. Error count for TBD. - U08 sPumpDACRdStatus; ///< Reg 260. Syringe pump DAC read status. + U08 h10DACRdStatus; ///< Reg 260. H10 Syringe pump DAC read status. U08 h6HallStatus; ///< Reg 261. H6 hall sensor status. - U16 sPumpDACSet; ///< Reg 262. Syringe pump DAC setting. - U16 sPumpDACEEProm; ///< Reg 264. Syringe pump DAC EEProm data. + U16 h10DACSetting; ///< Reg 262. H10 Syringe pump DAC setting. + U16 h10DACEEProm; ///< Reg 264. H10 Syringe pump DAC EEProm data. U16 h14Pressure; ///< Reg 266. H14 raw pressure data. S16 h14Temperature; ///< Reg 268. H14 raw temperature data. U08 h14ReadCount; ///< Reg 270. H14 read count. @@ -126,15 +126,15 @@ S16 h19EncPosition; ///< Reg 298. H19 encoder position (1000 steps/rev). S16 h19MaxEncPosition; ///< Reg 300. H19 max encoder position. U16 GPIOReg; ///< Reg 302. GPIO register. - U08 HEPStatus; ///< Reg 304. HEP status register. - U08 HEPAdcReadCount; ///< Reg 305. HEP ADC read counter. - U08 HEPAdcDacStatus; ///< Reg 306. HEP ADC/DAC status register. - U08 HEPEncStatus; ///< Reg 307. HEP encoder status register. - S32 HEPEncPosition; ///< Reg 308. HEP encoder position. - U16 HEPAdcCh0; ///< Reg 312. HEP ADC channel 0 reading. - U16 HEPAdcCh1; ///< Reg 314. HEP ADC channel 1 reading. - U16 HEPAdcCh2; ///< Reg 316. HEP ADC channel 2 reading. - U16 HEPAdcCh3; ///< Reg 318. HEP ADC channel 3 reading. + U08 h10Status; ///< Reg 304. H10 Syringe pump status register. + U08 h10AdcReadCount; ///< Reg 305. H10 Syringe pump ADC read counter. + U08 h10AdcDacStatus; ///< Reg 306. H10 Syringe pump ADC/DAC status register. + U08 h10EncStatus; ///< Reg 307. H10 Syringe pump encoder status register. + S32 h10EncPosition; ///< Reg 308. H10 Syringe pump encoder position. + U16 h10AdcCh0; ///< Reg 312. H10 Syringe pump ADC channel 0 reading. + U16 h10AdcCh1; ///< Reg 314. H10 Syringe pump ADC channel 1 reading. + U16 h10AdcCh2; ///< Reg 316. H10 Syringe pump ADC channel 2 reading. + U16 h10AdcCh3; ///< Reg 318. H10 Syringe pump ADC channel 3 reading. U16 fpgaAdcTemperature; ///< Reg 320. FPGA ADC temperature. U16 fpga1msTimerCounter; ///< Reg 322. FPGA 1 millisecond timer counter. U16 alarmBuzzerCurrentAdc; ///< Reg 324. Alarm buzzer current ADC reading. @@ -194,6 +194,11 @@ U16 syrPumpDACData; ///< Reg 38. Syringe pump DAC data (12 bits). U16 syrPumpDACControl; ///< Reg 40. Syringe pump ADC and DAC control register. U16 h12Period; ///< Reg 42. H12 Period + U08 h10Control; ///< Reg 33. H10 Syringe pump control register. + U32 h10Speed; ///< Reg 34. H10 Syringe pump time between step toggle (1/2 step period). + U16 h10DACData; ///< Reg 38. H10 Syringe pump DAC data (12 bits). + U16 h10DACControl; ///< Reg 40. H10 Syringe pump ADC and DAC control register. + U16 h12Period; ///< Reg 42. H12 Air pump time period for each count in PWM register. U32 h5SetSpeed; ///< Reg 44. H5 ejector motor set speed. } FPGA_ACTUATORS_T; @@ -1291,6 +1296,18 @@ /*********************************************************************//** * @brief + * The getAirPumpRPM function reads the air pump RPM from FPGA. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return air pump RPM value + *************************************************************************/ +U16 getAirPumpRPM( void ) +{ + return fpgaSensorReadings.h12Speed; +} + +/*********************************************************************//** + * @brief * The checkFPGACommFailure function increments the FPGA comm failure * windowed timer and returns whether or not the number of failures in * the window have been reached. @@ -1341,4 +1358,226 @@ } } +/*********************************************************************//** + * @brief + * The setFPGASyringePumpControlFlags function sets the syringe pump control + * register per given bit flags. + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints + * @param bitFlags control bit settings for syringe pump + * @return none + *************************************************************************/ +void setFPGASyringePumpControlFlags( U08 bitFlags ) +{ + fpgaActuatorSetPoints.h10Control = bitFlags; +} + +/*********************************************************************//** + * @brief + * The setFPGASyringePumpADCandDACControlFlags function sets the syringe pump + * ADC/DAC control register per given bit flags. + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints + * @param bitFlags ADC/DAC control bit settings for syringe pump + * @return none + *************************************************************************/ +void setFPGASyringePumpADCandDACControlFlags( U08 bitFlags ) +{ + fpgaActuatorSetPoints.h10DACControl = bitFlags; +} + +/*********************************************************************//** + * @brief + * The setFPGASyringePumpDACOutputLevel function sets the syringe pump force + * sensor DAC output level register to a given value. + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints + * @param counts level to set syringe pump force sensor DAC to + * @return none + *************************************************************************/ +void setFPGASyringePumpDACOutputLevel( U16 counts ) +{ + fpgaActuatorSetPoints.h10DACData = counts; +} + +/*********************************************************************//** + * @brief + * The setFPGASyringePumpStepToggleTime function sets the syringe pump stepper + * toggle time register to a given period (in uSec). + * @details \b Inputs: none + * @details \b Outputs: fpgaActuatorSetPoints + * @param microSeconds toggle the stepper motor at this time interval to set pump speed + * @return none + *************************************************************************/ +void setFPGASyringePumpStepToggleTime( U32 microSeconds ) +{ + fpgaActuatorSetPoints.h10Speed = microSeconds; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpStatus function gets the latest syringe pump status + * register reading. Bit 0 indicates a fault. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump status reading + *************************************************************************/ +U08 getFPGASyringePumpStatus( void ) +{ + return fpgaSensorReadings.h10Status; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCReadCounter function gets the latest syringe pump + * ADC read counter. Counter is 8-bit and rolls over when exceeding 255. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC read counter + *************************************************************************/ +U08 getFPGASyringePumpADCReadCounter( void ) +{ + return fpgaSensorReadings.h10AdcReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCandDACStatus function gets the latest syringe pump + * ADC/DAC status register reading. + * Bit 7 = DAC write and read-back done + * Bit 6 = I2C error on DAC data transfer + * Bit 0..5 = count of I2C errors, rolls over after 63 + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC/DAC status reading + *************************************************************************/ +U08 getFPGASyringePumpADCandDACStatus( void ) +{ + return fpgaSensorReadings.h10AdcDacStatus; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpEncoderStatus function gets the latest syringe pump + * encoder status register reading. + * Bit 7 = direction (0=fwd, 1=rev) + * Bit 0..5 = direction error count (# of errors after power up, rolls over after 63) + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump encoder status reading + *************************************************************************/ +U08 getFPGASyringePumpEncoderStatus( void ) +{ + return fpgaSensorReadings.h10EncStatus; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpEncoderPosition function gets the latest syringe pump + * encoder position reading. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump encoder position reading + *************************************************************************/ +U32 getFPGASyringePumpEncoderPosition( void ) +{ + return fpgaSensorReadings.h10EncPosition; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCChannel0 function gets the latest syringe pump ADC + * channel 0 register reading (syringe pump force sensor). + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC channel 0 reading + *************************************************************************/ +U16 getFPGASyringePumpADCChannel0( void ) +{ + return fpgaSensorReadings.h10AdcCh0; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCChannel1 function gets the latest syringe pump ADC + * channel 1 register reading (syringe detection switch). + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC channel 1 reading + *************************************************************************/ +U16 getFPGASyringePumpADCChannel1( void ) +{ + return fpgaSensorReadings.h10AdcCh1; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCChannel2 function gets the latest syringe pump ADC + * channel 2 register reading (syringe pump home position sensor). + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC channel 2 reading + *************************************************************************/ +U16 getFPGASyringePumpADCChannel2( void ) +{ + return fpgaSensorReadings.h10AdcCh2; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpADCChannel3 function gets the latest syringe pump ADC + * channel 3 register reading. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump ADC channel 3 reading + *************************************************************************/ +U16 getFPGASyringePumpADCChannel3( void ) +{ + return fpgaSensorReadings.h10AdcCh3; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpDACStatus function gets the latest syringe pump + * DAC status. + * Bit 0: PD0 + * Bit 1: PD1 + * Bit 2: POR + * Bit 3: Ready (not busy) + * Bits 4..7: N/A + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump DAC status reading + *************************************************************************/ +U08 getFPGASyringePumpDACStatus( void ) +{ + return fpgaSensorReadings.h10DACRdStatus; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpDACSetting function gets the latest syringe pump + * DAC setting. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump DAC setting + *************************************************************************/ +U16 getFPGASyringePumpDACSetting( void ) +{ + return fpgaSensorReadings.h10DACSetting; +} + +/*********************************************************************//** + * @brief + * The getFPGASyringePumpDACStoredSetting function gets the latest syringe + * pump DAC setting stored in sensor's EEPROM. + * @details \b Inputs: fpgaSensorReadings + * @details \b Outputs: none + * @return last syringe pump DAC setting stored in EEPROM + *************************************************************************/ +U16 getFPGASyringePumpDACStoredSetting( void ) +{ + return fpgaSensorReadings.h10DACEEProm; +} + /**@}*/ Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rf47837d7c20f6ebe4950758aa4f153ac79d5ae57 -r21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision f47837d7c20f6ebe4950758aa4f153ac79d5ae57) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Raghu Kallala -* @date (last) 30-Apr-2026 +* @author (last) Praneeth Bunne +* @date (last) 21-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -39,8 +39,11 @@ #include "StateTxDialysis.h" #include "StateTxPaused.h" #include "Switches.h" +#include "SyringePump.h" #include "SystemCommTD.h" #include "Temperatures.h" +#include "TubeSetAutoEject.h" +#include "TubeSetInstall.h" #include "TxParams.h" #include "Utilities.h" #include "Valve3Way.h" @@ -116,6 +119,8 @@ { MSG_ID_UI_BLOOD_PRIME_CMD_REQUEST, &bloodPrimeHandleCmdRequest }, { MSG_ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_REQUEST, &bloodPrimeHandleBloodFlowChangeRequest }, { MSG_ID_TD_TUBE_SET_AUTHENTICATION_ACK_RESPONSE, &drySelfTestHandleTubingSetAuthResponse }, + { MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST, &handleAutoLoadRequest }, + { MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST, &handleAutoEjectRequest }, { MSG_ID_TD_SOFTWARE_RESET_REQUEST, &testTDSoftwareResetRequest }, { MSG_ID_TD_BUBBLE_OVERRIDE_REQUEST, &testBubbleDetectOverride }, { MSG_ID_TD_BUBBLE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testBubblesDataPublishIntervalOverride }, @@ -185,6 +190,19 @@ { MSG_ID_TD_BLOOD_PRIME_VOLUME_OVERRIDE, &testBloodPrimeVolumeOverride }, { MSG_ID_TD_BLOOD_PRIME_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testBloodPrimePublishIntervalOverride }, { MSG_ID_TD_ENABLE_VENOUS_BUBBLE_ALARM, &testEnableVenousBubbleAlarm }, + { MSG_ID_TD_SYRINGE_PUMP_OPERATION_REQUEST, &testSyringePumpOperationRequest }, + { MSG_ID_HD_SYRINGE_PUMP_PUBLISH_INTERVAL_OVERRIDE, &testSyringePumpDataPublishIntervalOverride }, + { MSG_ID_TD_SYRINGE_PUMP_RATE_OVERRIDE_REQUEST, &testSyringePumpMeasuredRateOverride }, + { MSG_ID_TD_SYRINGE_PUMP_FORCE_OVERRIDE_REQUEST, &testSyringePumpMeasuredForceOverride }, + { MSG_ID_TD_SYRINGE_PUMP_HOME_OVERRIDE_REQUEST, &testSyringePumpMeasuredHomeOverride }, + { MSG_ID_TD_SYRINGE_PUMP_POSITION_OVERRIDE_REQUEST, &testSyringePumpMeasuredPositionOverride }, + { MSG_ID_TD_SYRINGE_PUMP_VOLUME_OVERRIDE_REQUEST, &testSyringePumpMeasuredVolumeOverride }, + { MSG_ID_TD_SYRINGE_PUMP_STATUS_OVERRIDE_REQUEST, &testSyringePumpStatusOverride }, + { MSG_ID_TD_SYRINGE_PUMP_ENCODER_STATUS_OVERRIDE_REQUEST, &testSyringePumpEncoderStatusOverride }, + { MSG_ID_TD_SYRINGE_PUMP_ADC_DAC_STATUS_OVERRIDE_REQUEST, &testSyringePumpADCandDACStatusOverride }, + { MSG_ID_TD_SYRINGE_PUMP_ADC_READ_COUNTER_OVERRIDE_REQUEST, &testSyringePumpADCReadCounterOverride }, + { MSG_ID_TD_HEPARIN_BOLUS_TARGET_RATE_OVERRIDE_REQUEST, &testHeparinBolusTargetRateOverride }, + { MSG_ID_TD_SYRINGE_PUMP_FORCE_SENSOR_CALIBRATION_REQUEST, &testCalibrateForceSensor }, }; #define NUM_OF_FUNCTION_HANDLERS (sizeof(MSG_FUNCTION_HANDLER_LOOKUP) / sizeof(MSG_HANDLER_LOOKUP_T)) Index: firmware/App/Services/StateServices/DrySelfTests.c =================================================================== diff -u --- firmware/App/Services/StateServices/DrySelfTests.c (revision 0) +++ firmware/App/Services/StateServices/DrySelfTests.c (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -0,0 +1,1156 @@ +/************************************************************************** +* +* Copyright (c) 2026-2026 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file DrySelfTests.c +* +* @author (last) Varshini Nagabooshanam +* @date (last) 01-Apr-2026 +* +* @author (original) Varshini Nagabooshanam +* @date (original) 01-Apr-2026 +* +***************************************************************************/ + +#include "AirPump.h" +#include "AirTrap.h" +#include "BloodFlow.h" +#include "Bubbles.h" +#include "Buttons.h" +#include "Common.h" +#include "DDInterface.h" +#include "DrySelfTests.h" +#include "LevelSensors.h" +#include "Messaging.h" +#include "ModePreTreat.h" +#include "ModeTreatment.h" +#include "OperationModes.h" +#include "Pressures.h" +#include "RotaryValve.h" +#include "Switches.h" +#include "TaskGeneral.h" +#include "TDCommon.h" +#include "Timers.h" +#include "TxParams.h" +#include "Utilities.h" +#include "Valves.h" +#include "Valve3Way.h" + +/** + * @addtogroup DrySelfTests + * @{ + */ + +// ********** private definitions ********** + +// Pressure self-test timing +#define PRE_NORMAL_PRESSURE_DELAY_MS ( 5 * MS_PER_SECOND ) ///< Delay before capturing baseline arterial and venous pressures. +#define STABILITY_PRESSURE_CHECK_TIME_MS ( 4 * MS_PER_SECOND ) ///< Time allowed for pressure stabilization. +#define VENOUS_PRESSURE_LEAK_CHECK_TIME ( 4 * MS_PER_SECOND ) ///< Time to monitor venous pressure decay (leak check). +#define ARTERIAL_PRESSURE_LEAK_CHECK_TIME ( 4 * MS_PER_SECOND ) ///< Time to monitor arterial pressure decay (leak check). +#define TUBING_SET_INSERT_PRESSURE_SETTLE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Time required for pressure settling after tubing set insertion. +#define VENOUS_PRESSURE_TIMEOUT_MS ( 60 * MS_PER_SECOND ) ///< Max time allowed to reach venous pressure target. +#define ARTERIAL_PRESSURE_TIMEOUT_MS ( 30 * MS_PER_SECOND ) ///< Max time allowed to reach arterial pressure target. +#define MAX_DRY_SELF_TEST_TIME ( 12 * SEC_PER_MIN ) ///< Maximum total dry self-test duration. +#define SELF_TEST_TIME_DATA_PUB_INTERVAL ( 1 * MS_PER_SECOND ) ///< Interval for publishing self-test progress data. +#define TUBING_SET_AUTH_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Tubing set authentication timeout + +//Pressure self-test pump flow +#define BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW 100 ///< Blood pump flow rate during arterial pressure self-test (mL/min). + +// Pressure thresholds +#define ZERO_PRESSURE_THRESHOLD_MMHG 15.0F ///< Zeroing the pressure +#define VENOUS_PRESSURE_TARGET_MMHG 250.0F ///< Target venous pressure threshold during pressure build. +#define ARTERIAL_PRESSURE_TARGET_MMHG -200.0F ///< Target arterial pressure threshold during pressure build. +#define VENOUS_PRESSURE_STABILITY_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed venous pressure variation during stabilization. +#define ARTERIAL_PRESSURE_STABILITY_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed arterial pressure variation during stabilization. +#define VENOUS_PRESSURE_LEAK_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed venous pressure difference during leak check. +#define ARTERIAL_PRESSURE_LEAK_DIFF_TOLERANCE_MMHG 5.0F ///< Max allowed arterial pressure difference during leak check. +#define VENOUS_PRESSURE_RELIEF_THRESHOLD_MMHG 20.0F ///< Venous pressure must return within this threshold after relief. +#define ARTERIAL_PRESSURE_RELIEF_THRESHOLD_MMHG 20.0F ///< Arterial pressure must return within this threshold after relief. + +/// Payload record structure for dry self-test authentication response +typedef struct +{ + U32 validTubingSet; + U32 modalityMatch; +} UI_TUBING_SET_AUTH_RESPONSE_PAYLOAD_T; + +// ********** private data ********** + +static DRY_SELF_TESTS_STATE_T currentDrySelfTestsState; ///< Current state of Dry Self-Test state machine +static U32 selfTestPreviousPublishDataTime; ///< Last progress data publish time +static BOOL doorStateAfterTubingSetInstall; ///< Tracks door transition after tubing set install +static U32 selfTestStartTime; ///< Start time of dry self-tests +static BOOL selfTestsResumeRequested; ///< Resume requested from STOPPED state +static BOOL tubingSetLeakChecksStarted; ///< Indicates tubing set leak check started +static BOOL barcodeScanResponseReceived; ///< Barcode response received flag +static U32 authenticationStartTime; ///< Authentication start timer +static BOOL authResponseReceived; ///< Indicates UI auth response received +static BOOL authResponseValidTubingSet; ///< Indicates tubing set is valid +static BOOL authResponseModalityAccepted; ///< Indicates tubing set modality is accepted +static U32 pressureSelfTestPreNormalStartTime; ///< Start time for pre-normal pressure setup delay +static U32 venousSetupStartTime; ///< Venous setup start time +static F32 peakVenousPressure; ///< Peak venous pressure during stabilization +static U32 venousPressureStabilizationStartTime; ///< Start time for venous stabilization +static F32 venousPressureP1; ///< First stable venous pressure sample +static F32 venousPressureP2; ///< Second venous pressure sample for leak check +static U32 venousPressureLeakCheckStartTime; ///< Start time for venous leak check +static U32 venousPressureReliefStartTime; ///< Start time for venous pressure relief +static U32 arterialSetupStartTime; ///< Arterial pressure setup state entry +static U32 pressureSelfTestArterialStartTime; ///< Start time for arterial pressure build-up +static F32 peakArterialPressure; ///< Peak arterial pressure during stabilization +static U32 arterialPressureStabilizationStartTime; ///< Start time for arterial stabilization +static F32 arterialPressureP1; ///< First stable arterial pressure sample +static F32 arterialPressureP2; ///< Second arterial pressure sample for leak check +static U32 arterialPressureLeakCheckStartTime; ///< Start time for arterial leak check +static U32 arterialPressureReliefStartTime; ///< Start time for arterial pressure relief + +// ********** private function prototypes ********** + +static void publishDrySelfTestProgress( void ); +static void resetSelfTestsFlags( void ); +static void setAlarmResumePerDoor( void ); +static void transitionToDrySelfTestsState( DRY_SELF_TESTS_STATE_T newState ); + +static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedTubingSetCheckState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubingSetLoadedCheckState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubingSetAuthenticationState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorNormalSetupState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureSetupState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureStabilizationState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureLeakCheckState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureReliefState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureSetupState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureStabilizationState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureLeakCheckState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureReliefState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ); + +/*********************************************************************//** + * @brief + * The initDrySelfTests function initializes the DrySelfTests unit. + * @details \b Inputs: none + * @details \b Outputs: DrySelfTests unit initialized. + * @return none + *************************************************************************/ +void initDrySelfTests( void ) +{ + currentDrySelfTestsState = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + selfTestStartTime = 0; + selfTestPreviousPublishDataTime = 0; + pressureSelfTestPreNormalStartTime = 0; + venousSetupStartTime = 0; + venousPressureStabilizationStartTime = 0; + venousPressureLeakCheckStartTime = 0; + venousPressureReliefStartTime = 0; + pressureSelfTestArterialStartTime = 0; + arterialPressureStabilizationStartTime = 0; + arterialPressureLeakCheckStartTime = 0; + arterialPressureReliefStartTime = 0; + authenticationStartTime = 0; + doorStateAfterTubingSetInstall = TRUE; + selfTestsResumeRequested = FALSE; + barcodeScanResponseReceived = FALSE; + authResponseReceived = FALSE; + authResponseValidTubingSet = FALSE; + authResponseModalityAccepted = FALSE; + peakVenousPressure = 0.0F; + venousPressureP1 = 0.0F; + venousPressureP2 = 0.0F; + peakArterialPressure = 0.0F; + arterialPressureP1 = 0.0F; + arterialPressureP2 = 0.0F; +} + +/*********************************************************************//** + * @brief + * The transitionToDrySelfTests function resets anything required before + * the start of dry self-tests. + * @details \b Inputs: front door state + * @details \b Outputs: Dry self-tests re-initialized, changed depending + * on front door state + * @return none + *************************************************************************/ +void transitionToDrySelfTests( void ) +{ + selfTestStartTime = getMSTimerCount(); + selfTestPreviousPublishDataTime = getMSTimerCount(); + doorClosedRequired( TRUE ); + setCurrentSubState( (U32)currentDrySelfTestsState ); + transitionToDrySelfTestsState( currentDrySelfTestsState ); + + signalBloodPumpHardStop(); + + endAirTrapControl(); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + + if ( STATE_CLOSED == getSwitchState( H9_SWCH ) ) + { + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + } + else + { + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + } + + resetSelfTestsFlags(); +} + +/*********************************************************************//** + * @brief + * The execDrySelfTests function executes the dry self-tests state machine. + * @details \b Inputs: currentDrySelfTestsState + * @details \b Outputs: currentDrySelfTestsState, pressureSelfTestPreNormalStartTime + * @return none + *************************************************************************/ +void execDrySelfTests( void ) +{ + DRY_SELF_TESTS_STATE_T priorSubState = currentDrySelfTestsState; + + switch ( currentDrySelfTestsState ) + { + case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: + currentDrySelfTestsState = handleDrySelfTestWaitForDoorCloseState(); + break; + + case DRY_SELF_TESTS_USED_TUBING_SET_CHECK_STATE: + currentDrySelfTestsState = handleDrySelfTestUsedTubingSetCheckState(); + break; + + case DRY_SELF_TESTS_TUBING_SET_LOADED_CHECK_STATE: + currentDrySelfTestsState = handleDrySelfTestTubingSetLoadedCheckState(); + break; + + case DRY_SELF_TESTS_TUBING_SET_AUTHENTICATION_STATE: + currentDrySelfTestsState = handleDrySelfTestTubingSetAuthenticationState(); + break; + + case DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestPressureSensorNormalSetupState(); + break; + + case DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestVenousPressureSetupState(); + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE: + currentDrySelfTestsState = handleDrySelfTestVenousPressureStabilizationState(); + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE: + currentDrySelfTestsState = handleDrySelfTestVenousPressureLeakCheckState(); + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE: + currentDrySelfTestsState = handleDrySelfTestVenousPressureReliefState(); + break; + + case DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE: + currentDrySelfTestsState = handleDrySelfTestArterialPressureSetupState(); + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE: + currentDrySelfTestsState = handleDrySelfTestArterialPressureStabilizationState(); + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE: + currentDrySelfTestsState = handleDrySelfTestArterialPressureLeakCheckState(); + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE: + currentDrySelfTestsState = handleDrySelfTestArterialPressureReliefState(); + break; + + case DRY_SELF_TESTS_STOPPED_STATE: + currentDrySelfTestsState = handleDrySelfTestStoppedState(); + break; + + case DRY_SELF_TESTS_COMPLETE_STATE: + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_DRY_SELF_TEST_STATE, currentDrySelfTestsState ); + break; + } + + // Self-tests flags should be handled by now, reset if flags not handled with current state + resetSelfTestsFlags(); + + if ( priorSubState != currentDrySelfTestsState ) + { + transitionToDrySelfTestsState( currentDrySelfTestsState ); + setCurrentSubState( (U32)currentDrySelfTestsState ); + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, priorSubState, currentDrySelfTestsState ); + } + + publishDrySelfTestProgress(); +} + +/*********************************************************************//** +* @brief +* The publishDrySelfTestProgress function publishes dry self-test progress. +* @details \b Inputs: selfTestPreviousPublishDataTime +* @details \b Outputs: progress data broadcast +* @return none +*************************************************************************/ +static void publishDrySelfTestProgress( void ) +{ + if ( calcTimeSince( selfTestPreviousPublishDataTime ) >= SELF_TEST_TIME_DATA_PUB_INTERVAL ) + { + U32 const elapsedSelfTestTimeInSecs = calcTimeSince( selfTestStartTime ) / MS_PER_SECOND; + SELF_TEST_DRY_PAYLOAD_T data; + + selfTestPreviousPublishDataTime = getMSTimerCount(); + + data.timeout = MAX_DRY_SELF_TEST_TIME; + data.countdown = ( elapsedSelfTestTimeInSecs <= MAX_DRY_SELF_TEST_TIME ? ( MAX_DRY_SELF_TEST_TIME - elapsedSelfTestTimeInSecs ) : 0 ); + broadcastData( MSG_ID_TD_DRY_SELF_TEST_PROGRESS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( SELF_TEST_DRY_PAYLOAD_T ) ); + } +} + +/*********************************************************************//** + * @brief + * The signalResumeDrySelfTests function signals the self-tests to resume + * previous operation. + * @details \b Inputs: none + * @details \b Outputs: primeResumeRequested + * @return none + *************************************************************************/ +void signalResumeDrySelfTests( void ) +{ + selfTestsResumeRequested = TRUE; +} + +/*********************************************************************//** + * @brief + * The resetSelfTestsFlags function resets all self-tests signal flags. + * @details \b Inputs: none + * @details \b Outputs: signal flags set to FALSE + * @return none + *************************************************************************/ +static void resetSelfTestsFlags( void ) +{ + selfTestsResumeRequested = FALSE; +} + +/*********************************************************************//** +* @brief +* The setAlarmResumePerDoor function enables resume only when +* required conditions are satisfied. +* @details \b Inputs: Front door switch state +* @details \b Outputs: resume alarm enabled/disabled +* @return none +*************************************************************************/ +static void setAlarmResumePerDoor( void ) +{ + BOOL doorClosed = FALSE; + doorClosed = ( STATE_CLOSED == getSwitchState( H9_SWCH ) ); + + if ( TRUE == doorClosed ) + { + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + } + else + { + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); + } +} + +/*********************************************************************//** + * @brief + * The getDrySelfTestsState function returns the current state of dry self-tests sub-mode. + * @details \b Inputs: currentDrySelfTestsState + * @details \b Outputs: none + * @return current dry self-tests state + *************************************************************************/ +U32 getDrySelfTestsState( void ) +{ + return (U32)currentDrySelfTestsState; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestWaitForDoorCloseState function makes sure door is + * closed before starting self-tests. + * @details \b Inputs: none + * @details \b Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestWaitForDoorCloseState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + OPN_CLS_STATE_T door = getSwitchState( H9_SWCH ); + + // Want to pinch off saline once door closed after tubing set install + handleDoorCloseAfterTubingSetInsertion(); + + if ( STATE_CLOSED == door ) + { + doorClosedRequired( TRUE ); + state = DRY_SELF_TESTS_USED_TUBING_SET_CHECK_STATE; + } + + return state; +} + +/*********************************************************************//** +* @brief +* The handleDrySelfTestUsedTubingSetCheckState function verify no fluid is +* detected by bubble detectors to ensure the tubing set is new. +* @details \b Inputs: none +* @details \b Outputs: +* @return the next state of dry self-tests state machine +*************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestUsedTubingSetCheckState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_TUBING_SET_CHECK_STATE; + BUBBLE_STATE_T bubble = getBubbleDetectedState( H18_BBLD ); + AIR_TRAP_LEVELS_T lower = getLevelSensorState( H17_LEVL ); + AIR_TRAP_LEVELS_T upper = getLevelSensorState( H16_LEVL ); + + if ( ( BUBBLE_DETECTED == bubble ) && ( AIR_TRAP_LEVEL_AIR == lower ) && ( AIR_TRAP_LEVEL_AIR == upper ) ) + { + resetArtVenPressureOffsets(); + // TODO: Send barcode scan command through FPGA interface + state = DRY_SELF_TESTS_TUBING_SET_LOADED_CHECK_STATE; + } + else + { + // Allow wet tubing set only for test configuration + if ( TRUE == getTestConfigStatus( TEST_CONFIG_USE_WET_TUBING_SET ) ) + { + // TODO: Send barcode scan command through FPGA interface + state = DRY_SELF_TESTS_TUBING_SET_LOADED_CHECK_STATE; + } + else + { + // If tubing set is invalid it triggers an alarm + //SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_INSTALL_NEW_BLOOD_TUBING_SET, (U32)bubble, (U32)lower, (U32)upper ); + //signalGoToInstallState(); + } + } + + return state; +} + +/*********************************************************************//** +* @brief +* The handleDrySelfTestTubingSetLoadedCheckState function handles barcode +* scan result and transitions to authentication state if scan succeeded. +* @details \b Inputs: barcodeScanResponseReceived, barcodeScanSuccessful +* @details \b Outputs: authenticationStartTime +* @return the next state of dry self-tests state machine +*************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubingSetLoadedCheckState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_TUBING_SET_LOADED_CHECK_STATE; + + if ( TRUE == barcodeScanResponseReceived ) + { + barcodeScanResponseReceived = FALSE; + // Send barcode for authentication + sendMessage( MSG_ID_TD_TUBE_SET_AUTHENTICATION_REQUEST, COMM_BUFFER_OUT_CAN_TD_2_UI, NULL, 0 ); + authenticationStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_TUBING_SET_AUTHENTICATION_STATE; + } + else + { + activateAlarmNoData( ALARM_ID_TD_INSTALL_NEW_BLOOD_TUBING_SET ); + //signalGoToInstallState(); + } + + return state; +} + +/*********************************************************************//** +* @brief +* The handleDrySelfTestTubingSetAuthenticationState function handles tubing set +* authentication and processes the authentication response. +* @details \b Inputs: authResponseReceived, authResponseValidTubingSet, +* authResponseModalityAccepted +* @details \b Outputs: pressureSelfTestPreNormalStartTime +* @return the next state of dry self-tests state machine +*************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestTubingSetAuthenticationState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_TUBING_SET_AUTHENTICATION_STATE; + + // Response received + if ( TRUE == authResponseReceived ) + { + authResponseReceived = FALSE; + + // Invalid tubing set + if ( FALSE == authResponseValidTubingSet ) + { + activateAlarmNoData( ALARM_ID_TD_INVALID_TUBING_SET ); + //signalGoToInstallState(); + } + // Modality mismatch + else if ( FALSE == authResponseModalityAccepted ) + { + //signalGoToInstallState(); + } + // If valid it goes to next state + else + { + //tubingSetChecksCompleted = TRUE; + pressureSelfTestPreNormalStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE; + } + } + + //Timeout Alarm + else + { + if ( TRUE == didTimeout( authenticationStartTime, TUBING_SET_AUTH_TIMEOUT_MS ) ) + { + activateAlarmNoData( ALARM_ID_TD_TUBING_SET_AUTHENTICATION_TIMEOUT ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureSensorNormalSetupState function handles the setup + * for pressure sensors dry self-test. + * @details \b Inputs: pressureSelfTestPreNormalStartTime + * @details \b Outputs: previousNormalArterialPressure, previousNormalVenousPressure + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorNormalSetupState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE; + + if ( TRUE == didTimeout( pressureSelfTestPreNormalStartTime, PRE_NORMAL_PRESSURE_DELAY_MS ) ) + { + F32 art = getFilteredArterialPressure(); + F32 ven = getFilteredVenousPressure(); + + if ( ( fabs(art) < ZERO_PRESSURE_THRESHOLD_MMHG ) && ( fabs(ven) < ZERO_PRESSURE_THRESHOLD_MMHG ) ) + { + setArtVenPressureOffsets(); + venousSetupStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE; + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRESSURE_TOO_HIGH_TO_ZERO, art, ven ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** +* @brief +* The handleDrySelfTestVenousPressureSetupState function handles the setup +* for the venous pressure sensor dry self-test. +* @details \b Inputs: none +* @details \b Outputs: venousPressureStabilizationStartTime +* @return the next state of dry self-tests state machine +*************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureSetupState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE; + F32 ven = getFilteredVenousPressure(); + + // If it reaches to traget venous pressure >= 250 mmHg then the transition to venous pressure stablization state + if ( ven >= VENOUS_PRESSURE_TARGET_MMHG ) + { + peakVenousPressure = ven; + venousPressureStabilizationStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE; + } + // Time out alarm if it does not reach within 60 sec tolerance + else if ( TRUE == didTimeout( venousSetupStartTime, VENOUS_PRESSURE_TIMEOUT_MS ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURIZATION_TIMEOUT, ven ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestVenousPressureStabilizationState function handles + * venous pressure stabilization check. + * @details \b Inputs: venousPressureStabilizationStartTime, peakVenousPressure + * @details \b Outputs: venousPressureP1 + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureStabilizationState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE; + + if ( TRUE == didTimeout( venousPressureStabilizationStartTime, STABILITY_PRESSURE_CHECK_TIME_MS ) ) + { + F32 currentVenousPressure = getFilteredVenousPressure(); + F32 diff = fabs( peakVenousPressure - currentVenousPressure ); + + if ( diff <= VENOUS_PRESSURE_STABILITY_DIFF_TOLERANCE_MMHG ) + { + venousPressureP1 = currentVenousPressure; + venousPressureLeakCheckStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE; + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_DECAY, diff ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestVenousPressureLeakCheckState function handles + * venous pressure leak check. + * @details \b Inputs: venousPressureLeakCheckStartTime, venousPressureP1 + * @details \b Outputs: venousPressureP2 + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureLeakCheckState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE; + + if ( TRUE == didTimeout( venousPressureLeakCheckStartTime, VENOUS_PRESSURE_LEAK_CHECK_TIME ) ) + { + venousPressureP2 = getFilteredVenousPressure(); + F32 diff = fabs( venousPressureP1 - venousPressureP2 ); + + if ( diff <= VENOUS_PRESSURE_LEAK_DIFF_TOLERANCE_MMHG ) + { + venousPressureReliefStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE; + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_LEAK, venousPressureP1, venousPressureP2 ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestVenousPressureReliefState function handles + * venous pressure relief state. + * @details \b Inputs: venousPressureReliefStartTime + * @details \b Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestVenousPressureReliefState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE; + + if ( TRUE == didTimeout( venousPressureReliefStartTime, STABILITY_PRESSURE_CHECK_TIME_MS ) ) + { + F32 ven = getFilteredVenousPressure(); + + if ( fabs( ven ) <= VENOUS_PRESSURE_RELIEF_THRESHOLD_MMHG ) + { + arterialSetupStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE; + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_RELIEF, ven ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestPressureArterialSetupState function handles the setup + * for the arterial pressure sensor dry self-test. + * @details \b Inputs: none + * @details \b Outputs: pressureSelfTestArterialStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureSetupState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE; + F32 art = getFilteredArterialPressure(); + + // Check the target for arterial pressure <= -200 mmHg and then transition to arterial pressure stabilization state + if ( art <= ARTERIAL_PRESSURE_TARGET_MMHG ) + { + peakArterialPressure = art; + arterialPressureStabilizationStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE; + + } + // Time out alarm if it does not reach within 30 sec tolerance + else if ( TRUE == didTimeout( pressureSelfTestArterialStartTime, ARTERIAL_PRESSURE_TIMEOUT_MS ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURIZATION_TIMEOUT, art ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestArterialPressureStabilizationState function monitors + * arterial pressure, verifies target pressure is reached, and records P1 + * after stabilization. + * @details \b Inputs: pressureSelfTestArterialStartTime, + * arterialPressureStabilizationStartTime + * @details \b Outputs: peakArterialPressure, arterialPressureP1, + * arterialPressureLeakCheckStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureStabilizationState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE; + + if ( TRUE == didTimeout( arterialPressureStabilizationStartTime, STABILITY_PRESSURE_CHECK_TIME_MS ) ) + { + F32 currentArterialPressure = getFilteredArterialPressure(); + F32 diff = fabs( peakArterialPressure - currentArterialPressure ); + + if ( diff <= ARTERIAL_PRESSURE_STABILITY_DIFF_TOLERANCE_MMHG ) + { + arterialPressureP1 = currentArterialPressure; + arterialPressureLeakCheckStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE; + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_DECAY, diff ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestArterialPressureLeakCheckState function verifies + * arterial pressure leak by comparing P1 and P2. + * @details \b Inputs: arterialPressureLeakCheckStartTime, arterialPressureP1 + * @details \b Outputs: arterialPressureP2 + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureLeakCheckState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE; + + if ( TRUE == didTimeout( arterialPressureLeakCheckStartTime, ARTERIAL_PRESSURE_LEAK_CHECK_TIME ) ) + { + arterialPressureP2 = getFilteredArterialPressure(); + F32 diff = fabs( arterialPressureP1 - arterialPressureP2 ); + + if ( diff <= ARTERIAL_PRESSURE_LEAK_DIFF_TOLERANCE_MMHG ) + { + arterialPressureReliefStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE; + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_LEAK, diff ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestArterialPressureReliefState function relieves + * arterial pressure and verifies return to baseline. + * @details \b Inputs: arterialPressureReliefStartTime + * @details \b Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestArterialPressureReliefState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE; + + if ( TRUE == didTimeout( arterialPressureReliefStartTime, STABILITY_PRESSURE_CHECK_TIME_MS ) ) + { + F32 art = getFilteredArterialPressure(); + + if ( fabs( art ) <= ARTERIAL_PRESSURE_RELIEF_THRESHOLD_MMHG ) + { + state = DRY_SELF_TESTS_COMPLETE_STATE; + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_RELIEF, art ); + state = DRY_SELF_TESTS_STOPPED_STATE; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrySelfTestStoppedState function handles the stopped dry self-tests + * operation. + * @details \b Inputs: selfTestsResumeRequested, tubingSetLeakChecksStarted + * @details \b Outputs: selfTestsResumeRequested, selfTestStartTime + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_STOPPED_STATE; + + setAlarmResumePerDoor(); + doorClosedRequired( FALSE ); + + // if resume request, resume dry self-tests + if ( TRUE == selfTestsResumeRequested ) + { + // Restart self-test start time + selfTestsResumeRequested = FALSE; + selfTestStartTime = getMSTimerCount(); + doorClosedRequired( TRUE ); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + if ( TRUE == tubingSetLeakChecksStarted ) + { + pressureSelfTestPreNormalStartTime = getMSTimerCount(); + state = DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE; + } + else + { + state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + } + } + + return state; +} + +/*********************************************************************//** +* @brief +* The drySelfTestHandleTubingSetAuthResponse function handles the UI +* barcode scan response. +* @details \b Message \b Received: MSG_ID_UI_TUBE_SET_AUTHENTICATION_ACK +* @details \b Message \b Sent: MSG_ID_TD_TUBE_SET_AUTHENTICATION_ACK +* @details \b Inputs: message containing barcode scan success status +* @details \b Outputs: authResponseValidTubingSet, authResponseModalityAccepted, +* authResponseReceived +* @return TRUE if request is valid, FALSE otherwise +*************************************************************************/ +BOOL drySelfTestHandleTubingSetAuthResponse( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( sizeof( UI_TUBING_SET_AUTH_RESPONSE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + UI_TUBING_SET_AUTH_RESPONSE_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof( payload ) ); + + authResponseValidTubingSet = (BOOL)payload.validTubingSet; + authResponseModalityAccepted = (BOOL)payload.modalityMatch; + authResponseReceived = TRUE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** +* @brief +* The transitionToDrySelfTestsState function handles the transition to +* dry self-test states by setting actuators. +* @details \b Inputs: none +* @details \b Outputs: none +* @param newState the targeted dry self-test state +* @return none +*************************************************************************/ +static void transitionToDrySelfTestsState( DRY_SELF_TESTS_STATE_T newState ) +{ + switch ( newState ) + { + case DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_USED_TUBING_SET_CHECK_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_TUBING_SET_LOADED_CHECK_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_TUBING_SET_AUTHENTICATION_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + if ( DRY_SELF_TESTS_TUBING_SET_AUTHENTICATION_STATE == newState ) + { + authenticationStartTime = getMSTimerCount(); + } + } + break; + + case DRY_SELF_TESTS_PRESSURE_SENSOR_NORMAL_SETUP_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + setAirPumpState( AIR_PUMP_STATE_ON, AIR_PUMP_DUTY_CYCLE_MAX ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_DRY_SELF_TEST_PRESSURE_RESULT, (U32)DRY_SELF_TESTS_PRESSURE_VENOUS_SETUP_STATE, 0 ); + venousSetupStartTime = getMSTimerCount(); + } + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_STABILIZATION_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_LEAK_CHECK_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_VENOUS_PRESSURE_RELIEF_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + setBloodPumpTargetFlowRate( BLOOD_PUMP_PRESSURE_SELF_TEST_FLOW, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_DRY_SELF_TEST_PRESSURE_RESULT, (U32)DRY_SELF_TESTS_PRESSURE_ARTERIAL_SETUP_STATE, 0 ); + pressureSelfTestArterialStartTime = getMSTimerCount(); + } + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_STABILIZATION_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_LEAK_CHECK_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + 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 ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_ARTERIAL_PRESSURE_RELIEF_STATE: + { + U32 targetDialysateFlowMLPM = (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_OPEN_STATE ); + cmdBypassDialyzer( TRUE ); + cmdChangeQd( targetDialysateFlowMLPM ); + cmdChangeQuf( 0.0F ); + } + break; + + case DRY_SELF_TESTS_COMPLETE_STATE: + signalBloodPumpHardStop(); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + cmdChangeQuf( 0.0F ); + break; + + case DRY_SELF_TESTS_STOPPED_STATE: + { + signalBloodPumpHardStop(); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + // Set valves for stop + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); + setAlarmResumePerDoor(); + doorClosedRequired( FALSE ); + } + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_DRY_SELF_TEST_STATE, (U32)newState ); + break; + } +} + +/*********************************************************************//** + * @brief + * The handleDoorCloseAfterTubingSetInsertion function handles the check + * for door close after tubing set install so that saline line can be pinched. + * @details Inputs: door states + * @details Outputs: doorStateAfterTubingSetInstall + * @return none + *************************************************************************/ +void handleDoorCloseAfterTubingSetInsertion( void ) +{ + OPN_CLS_STATE_T door = getSwitchState( H9_SWCH ); + + if ( STATE_OPEN == door ) + { + doorStateAfterTubingSetInstall = FALSE; + } + if ( ( STATE_CLOSED == door ) && ( FALSE == doorStateAfterTubingSetInstall ) ) + { + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + doorStateAfterTubingSetInstall = TRUE; + } +} + +/**@}*/ Index: firmware/App/Services/StateServices/DrySelfTests.h =================================================================== diff -u --- firmware/App/Services/StateServices/DrySelfTests.h (revision 0) +++ firmware/App/Services/StateServices/DrySelfTests.h (revision 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9) @@ -0,0 +1,55 @@ +/************************************************************************** +* +* Copyright (c) 2026-2026 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file DrySelfTests.h +* +* @author (last) Varshini Nagabooshanam +* @date (last) 01-Apr-2026 +* +* @author (original) Varshini Nagabooshanam +* @date (original) 01-Apr-2026 +* +***************************************************************************/ + +#ifndef __SELF_TESTS_H__ +#define __SELF_TESTS_H__ + +#include "TDCommon.h" +#include "TDDefs.h" + +/** + * @defgroup DrySelfTests + * @brief DrySelfTests module. This module handles dry self-tests execution for pre-treatment mode and treatment modes. + * + * @addtogroup DrySelfTests + * @{ + */ + +// ********** public definitions ********** + +/// Payload record structure for dry self-test data broadcast message +typedef struct +{ + U32 timeout; ///< Dry self-test timeout (in seconds) + U32 countdown; ///< Dry self-test timeout countdown (in seconds) +} SELF_TEST_DRY_PAYLOAD_T; + +// ********** public function prototypes ********** + +void initDrySelfTests( void ); +void transitionToDrySelfTests( void ); +void execDrySelfTests( void ); + +void signalResumeDrySelfTests( void ); +U32 getDrySelfTestsState( void ); +BOOL drySelfTestHandleTubingSetAuthResponse( MESSAGE_T *message ); + +void handleDoorCloseAfterTubingSetInsertion( void ); + +/**@}*/ + +#endif Fisheye: Tag 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 refers to a dead (removed) revision in file `firmware/App/Services/DrySelfTests.c'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 21a1f9847f1ccf22ec8b906bcdadea47ec7b5dc9 refers to a dead (removed) revision in file `firmware/App/Services/DrySelfTests.h'. Fisheye: No comparison available. Pass `N' to diff?