Index: firmware/App/Drivers/BPDriver.c =================================================================== diff -u -r143f7b732efbb9efdc690757823e711b5022b29d -r12fa9b72d8e338b624879c284488a04b17115762 --- firmware/App/Drivers/BPDriver.c (.../BPDriver.c) (revision 143f7b732efbb9efdc690757823e711b5022b29d) +++ firmware/App/Drivers/BPDriver.c (.../BPDriver.c) (revision 12fa9b72d8e338b624879c284488a04b17115762) @@ -17,7 +17,9 @@ #include "AlarmMgmtTD.h" #include "BPDriver.h" +#include "Common.h" #include "FpgaTD.h" +#include "TaskGeneral.h" /** * @addtogroup BPDriver @@ -32,14 +34,24 @@ #define BP_MODULE_BUSY_MASK 0x80 ///< Blood Pressure module busy mask #define BP_RESP_CODE_BPDATA 0x07 ///< Blood pressure response code indicating BP data is available. #define BP_MODULE_BUSY_CLEAR 0 ///< Blood pressure module buy clear +#define BP_COMMAND_CLEAR_DELAY_TICKS ( ( 10 / TASK_GENERAL_INTERVAL ) + 1 ) +#define BP_FPGA_CMD_GIVEN_MASK 0x10 +#define BP_MODULE_CMD_STARTED_MASK 0x01 +#define BP_MODULE_CMD_IN_PROGRESS_MASK 0x02 /// Blood pressure driver states. typedef enum { - BP_DRIVER_IDLE_STATE = 0, ///< Idle state. - BP_DRIVER_MEASURE_STATE, ///< Measurement state. - BP_DRIVER_GET_DATA_STATE, ///< Get data state. - NUM_OF_BP_DRIVER_STATES ///< Number of BP driver states. + BP_DRIVER_IDLE_STATE = 0, + BP_DRIVER_CLEAR_CMD_STATE, + BP_DRIVER_WAIT_CLEAR_CMD_STATE, + BP_DRIVER_SEND_CMD_STATE, + BP_DRIVER_WAIT_FPGA_ACK_STATE, + BP_DRIVER_CLEAR_CMD_AFTER_ACK_STATE, + BP_DRIVER_WAIT_MODULE_START_STATE, + BP_DRIVER_WAIT_MEASUREMENT_COMPLETE_STATE, + BP_DRIVER_GET_DATA_STATE, + NUM_OF_BP_DRIVER_STATES } BP_DRIVER_STATE_T; // ********** private data ********** @@ -52,12 +64,20 @@ static BOOL requestPedsBPMeasurement; ///< Request pediatric BP measurement static BOOL requestAbortBPMeasurement; ///< Request abort BP measurement static BOOL bpCuffConnected; ///< Blood pressure cuff connection +static U08 pendingBPCommand; ///< Pending BP command +static U08 bpCommandClearCtr; ///< Command clear delay counter // ********** private function prototypes ********** static U08 getBPResponseCode( void ); static BP_DRIVER_STATE_T handleBPDriverIdleState( void ); -static BP_DRIVER_STATE_T handleBPDriverMeasureState( void ); +static BP_DRIVER_STATE_T handleBPDriverClearCmdState( void ); +static BP_DRIVER_STATE_T handleBPDriverWaitClearCmdState( void ); +static BP_DRIVER_STATE_T handleBPDriverSendCmdState( void ); +static BP_DRIVER_STATE_T handleBPDriverWaitFpgaAckState( void ); +static BP_DRIVER_STATE_T handleBPDriverClearCmdAfterAckState( void ); +static BP_DRIVER_STATE_T handleBPDriverWaitModuleStartState( void ); +static BP_DRIVER_STATE_T handleBPDriverWaitMeasurementCompleteState( void ); static BP_DRIVER_STATE_T handleBPDriverGetDataState( void ); /*********************************************************************//** @@ -79,6 +99,8 @@ bpResults.systolic = 0; bpResults.diastolic = 0; bpResults.heartRate = 0; + pendingBPCommand = (U08)BP_CMD_IDLE; + bpCommandClearCtr = 0; } /*********************************************************************//** @@ -104,18 +126,42 @@ ***************************************************************************/ void execBPDriver( void ) { - bpCuffConnected = ( getNIBPControlStatus() != 0 ); + bpCuffConnected = ( getNIBPControlStatus() != 0 ) ? TRUE : FALSE; switch ( bpDriverState ) { case BP_DRIVER_IDLE_STATE: bpDriverState = handleBPDriverIdleState(); break; - case BP_DRIVER_MEASURE_STATE: - bpDriverState = handleBPDriverMeasureState(); + case BP_DRIVER_CLEAR_CMD_STATE: + bpDriverState = handleBPDriverClearCmdState(); break; + case BP_DRIVER_WAIT_CLEAR_CMD_STATE: + bpDriverState = handleBPDriverWaitClearCmdState(); + break; + + case BP_DRIVER_SEND_CMD_STATE: + bpDriverState = handleBPDriverSendCmdState(); + break; + + case BP_DRIVER_WAIT_FPGA_ACK_STATE: + bpDriverState = handleBPDriverWaitFpgaAckState(); + break; + + case BP_DRIVER_CLEAR_CMD_AFTER_ACK_STATE: + bpDriverState = handleBPDriverClearCmdAfterAckState(); + break; + + case BP_DRIVER_WAIT_MODULE_START_STATE: + bpDriverState = handleBPDriverWaitModuleStartState(); + break; + + case BP_DRIVER_WAIT_MEASUREMENT_COMPLETE_STATE: + bpDriverState = handleBPDriverWaitMeasurementCompleteState(); + break; + case BP_DRIVER_GET_DATA_STATE: bpDriverState = handleBPDriverGetDataState(); break; @@ -142,60 +188,147 @@ if ( TRUE == requestAdultBPMeasurement ) { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_IDLE_STATE, BP_DRIVER_MEASURE_STATE ) + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_IDLE_STATE, BP_DRIVER_CLEAR_CMD_STATE ); requestAdultBPMeasurement = FALSE; bpMeasurementReady = FALSE; bpDriverError = FALSE; - setNIBPCommand( (U08)BP_CMD_START_BP ); - nextState = BP_DRIVER_MEASURE_STATE; + pendingBPCommand = (U08)BP_CMD_START_BP; + nextState = BP_DRIVER_CLEAR_CMD_STATE; } else if ( TRUE == requestPedsBPMeasurement ) { requestPedsBPMeasurement = FALSE; bpMeasurementReady = FALSE; bpDriverError = FALSE; - setNIBPCommand( (U08)BP_CMD_START_PEDS_BP ); - nextState = BP_DRIVER_MEASURE_STATE; + pendingBPCommand = (U08)BP_CMD_START_PEDS_BP; + nextState = BP_DRIVER_CLEAR_CMD_STATE; } else if ( TRUE == requestAbortBPMeasurement ) { requestAbortBPMeasurement = FALSE; - setNIBPCommand( (U08)BP_CMD_ABORT_BP ); + pendingBPCommand = (U08)BP_CMD_ABORT_BP; + nextState = BP_DRIVER_CLEAR_CMD_STATE; } return nextState; } /*********************************************************************//** * @brief -* The handleBPDriverMeasureState function executes the BP driver -* measurement state handling. +* The handleBPDriverClearCmdState function clears the BP command ready bit. * @details \b Inputs: none -* @details \b Outputs: setNIBPCommand, bpDriverState, bpDriverError +* @details \b Outputs: setNIBPCommand, bpCommandClearCtr * @return next BP driver state ***************************************************************************/ -static BP_DRIVER_STATE_T handleBPDriverMeasureState( void ) +static BP_DRIVER_STATE_T handleBPDriverClearCmdState( void ) { - BP_DRIVER_STATE_T nextState = BP_DRIVER_MEASURE_STATE; + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_CLEAR_CMD_STATE; - if ( BP_MODULE_BUSY_CLEAR == ( getNIBPStatusResponse() & BP_MODULE_BUSY_MASK ) ) + setNIBPCommand( (U08)BP_CMD_IDLE ); + bpCommandClearCtr = 0; + + return nextState; +} + +/*********************************************************************//** +* @brief +* The handleBPDriverWaitClearCmdState function waits after clearing the +* BP command ready bit. +* @details \b Inputs: bpCommandClearCtr +* @details \b Outputs: bpCommandClearCtr +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverWaitClearCmdState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_CLEAR_CMD_STATE; + + bpCommandClearCtr++; + if ( bpCommandClearCtr >= BP_COMMAND_CLEAR_DELAY_TICKS ) { - U32 respCode = getBPResponseCode(); + bpCommandClearCtr = 0; + nextState = BP_DRIVER_SEND_CMD_STATE; + } - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, 11, respCode ) - // Verify BP measurement data is available - if ( BP_RESP_CODE_BPDATA == respCode ) + return nextState; +} + +/*********************************************************************//** +* @brief +* The handleBPDriverSendCmdState function sends the pending BP command. +* @details \b Inputs: pendingBPCommand +* @details \b Outputs: setNIBPCommand +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverSendCmdState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_FPGA_ACK_STATE; + + setNIBPCommand( pendingBPCommand ); + + return nextState; +} + +/*********************************************************************//** +* @brief +* The handleBPDriverWaitFpgaAckState function waits for FPGA command +* acknowledge. +* @details \b Inputs: getNIBPControlStatus +* @details \b Outputs: none +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverWaitFpgaAckState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_FPGA_ACK_STATE; + + if ( 0 != ( getNIBPControlStatus() & BP_FPGA_CMD_GIVEN_MASK ) ) + { + nextState = BP_DRIVER_CLEAR_CMD_AFTER_ACK_STATE; + } + + return nextState; +} + +/*********************************************************************//** +* @brief +* The handleBPDriverClearCmdAfterAckState function clears the BP command +* ready bit after FPGA acknowledge. +* @details \b Inputs: none +* @details \b Outputs: setNIBPCommand +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverClearCmdAfterAckState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_MODULE_START_STATE; + + setNIBPCommand( (U08)BP_CMD_IDLE ); + + return nextState; +} + +/*********************************************************************//** +* @brief +* The handleBPDriverWaitModuleStartState function waits for the BP module +* to signal that the command started. +* @details \b Inputs: getNIBPStatusResponse, pendingBPCommand +* @details \b Outputs: none +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverWaitModuleStartState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_MODULE_START_STATE; + + if ( 0 != ( getNIBPStatusResponse() & BP_MODULE_CMD_STARTED_MASK ) ) + { + if ( ( (U08)BP_CMD_START_BP == pendingBPCommand ) || ( (U08)BP_CMD_START_PEDS_BP == pendingBPCommand ) ) { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_MEASURE_STATE, BP_DRIVER_GET_DATA_STATE ) - setNIBPCommand( (U08)BP_CMD_GET_BP_DATA ); + nextState = BP_DRIVER_WAIT_MEASUREMENT_COMPLETE_STATE; + } + else if ( (U08)BP_CMD_GET_BP_DATA == pendingBPCommand ) + { nextState = BP_DRIVER_GET_DATA_STATE; } - // Check whether BP module error occurred - else if ( BP_MODULE_BUSY_CLEAR != ( getNIBPStatusResponse() & BP_MODULE_ERROR_MASK ) ) + else { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_MEASURE_STATE, BP_DRIVER_IDLE_STATE ) - bpDriverError = TRUE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, getNIBPStatusResponse(), bpDriverState ); nextState = BP_DRIVER_IDLE_STATE; } } @@ -205,30 +338,53 @@ /*********************************************************************//** * @brief -* The handleBPDriverGetDataState function retrieves blood pressure -* measurement results. +* The handleBPDriverWaitMeasurementCompleteState function waits for the +* BP measurement command to complete. * @details \b Inputs: getNIBPStatusResponse -* @details \b Outputs: bpMeasurementReady +* @details \b Outputs: pendingBPCommand * @return next BP driver state ***************************************************************************/ -static BP_DRIVER_STATE_T handleBPDriverGetDataState( void ) +static BP_DRIVER_STATE_T handleBPDriverWaitMeasurementCompleteState( void ) { - BP_DRIVER_STATE_T nextState = BP_DRIVER_GET_DATA_STATE; + BP_DRIVER_STATE_T nextState = BP_DRIVER_WAIT_MEASUREMENT_COMPLETE_STATE; - if ( ( getNIBPStatusResponse() & BP_MODULE_BUSY_MASK ) == 0 ) + if ( 0 == ( getNIBPStatusResponse() & BP_MODULE_CMD_IN_PROGRESS_MASK ) ) { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_GET_DATA_STATE, 11 ) - bpResults.systolic = getNIBPSystolicPressure(); - bpResults.diastolic = getNIBPDiastolicPressure(); - bpResults.heartRate = getNIBPHeartRate(); - bpMeasurementReady = TRUE; - nextState = BP_DRIVER_IDLE_STATE; + pendingBPCommand = (U08)BP_CMD_GET_BP_DATA; + nextState = BP_DRIVER_CLEAR_CMD_STATE; } + else if ( 0 != ( getNIBPStatusResponse() & BP_MODULE_ERROR_MASK ) ) + { + bpDriverError = TRUE; + nextState = BP_DRIVER_IDLE_STATE; + } return nextState; } /*********************************************************************//** +* @brief +* The handleBPDriverGetDataState function retrieves blood pressure +* measurement results. +* @details \b Inputs: FPGA NIBP blood pressure registers +* @details \b Outputs: bpResults, bpMeasurementReady +* @return next BP driver state +***************************************************************************/ +static BP_DRIVER_STATE_T handleBPDriverGetDataState( void ) +{ + BP_DRIVER_STATE_T nextState = BP_DRIVER_IDLE_STATE; + + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_BUTTON, BP_DRIVER_GET_DATA_STATE, 11 ); + bpResults.systolic = (U32)getNIBPSystolicPressure(); + bpResults.diastolic = (U32)getNIBPDiastolicPressure(); + bpResults.heartRate = (U32)getNIBPHeartRate(); + bpMeasurementReady = TRUE; + pendingBPCommand = (U08)BP_CMD_IDLE; + + return nextState; +} + +/*********************************************************************//** * @brief * The startAdultBPMeasurement function requests an adult blood pressure * measurement. Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -ra8396c9e402372dd7c6ad9df69d5b5fb500a66bf -r12fa9b72d8e338b624879c284488a04b17115762 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision a8396c9e402372dd7c6ad9df69d5b5fb500a66bf) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 12fa9b72d8e338b624879c284488a04b17115762) @@ -7,8 +7,8 @@ * * @file ModeTreatment.c * -* @author (last) Arpita Srivastava -* @date (last) 12-May-2026 +* @author (last) Praneeth Bunne +* @date (last) 04-Jun-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -21,6 +21,7 @@ #include "Bubbles.h" #include "Buttons.h" #include "DDInterface.h" +#include "FluidBolus.h" #include "Messaging.h" #include "ModeService.h" #include "ModeTreatment.h" @@ -54,8 +55,6 @@ #define TREATMENT_SETTINGS_RANGES_PUB_INTERVAL ( ( 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) /// Ultrafiltration data broadcast interval (ms/task time) count. #define ULTRAFILTRATION_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) -/// Saline bolus data broadcast interval (ms/task time) count. // TODO - move to StateTxSalineBolus.c when implemented -#define SALINE_BOLUS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Macro to calculate the elapsed treatment time in seconds. #define CALC_ELAPSED_TREAT_TIME_IN_SECS() ( treatmentTimeMS / MS_PER_SECOND ) @@ -73,7 +72,7 @@ static BOOL treatmentCompleted; ///< Flag indicates whether the treatment has completed. static U32 presTreatmentTimeSecs; ///< Prescribed treatment time (in seconds). -static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in L). +static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in Ml). static F32 presUFRateMlMin; ///< Prescribed ultrafiltration rate (in mL/Min). static U32 treatmentTimeMS; ///< Elapsed treatment time (in ms). @@ -82,7 +81,6 @@ static U32 treatmentStateBroadcastTimerCtr; ///< Treatment state data broadcast timer counter used to schedule when to transmit data. static U32 treatmentParamsRangesBroadcastTimerCtr; ///< Treatment parameter ranges broadcast timer counter used to schedule when to transmit updated ranges. static U32 ultrafiltrationBroadcastTimerCtr; ///< Ultrafiltration data broadcast timer counter used to schedule when to transmit data. -static U32 salineBolusBroadcastTimerCtr; ///< Saline bolus data broadcast timer counter used to schedule when to transmit data. /// Interval (in task intervals) at which to publish alarm status to CAN bus. static OVERRIDE_U32_T treatmentTimePublishInterval; @@ -105,15 +103,13 @@ static void broadcastTreatmentSettingsRanges( void ); static void broadcastTreatmentPeriodicData(); -static void publishSalineBolusData( void ); // TODO - move to StateTxSalineBolus.c when implemented static void publishUltrafiltrationData( void ); static U32 getMinTreatmentTimeInMinutes( void ); static TREATMENT_STATE_T handleTreatmentStartState( void ); static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ); static TREATMENT_STATE_T handleTreatmentDialysisState( void ); static TREATMENT_STATE_T handleTreatmentIsoUFState( void ); static TREATMENT_STATE_T handleTreatmentDialysatePausedState( void ); -static TREATMENT_STATE_T handleTreatmentSalineBolusState( void ); static TREATMENT_STATE_T handleTreatmentPausedState( void ); static TREATMENT_STATE_T handleTreatmentRinsebackState( void ); static TREATMENT_STATE_T handleTreatmentRecircState( void ); @@ -156,7 +152,6 @@ treatmentStateBroadcastTimerCtr = TREATMENT_STATE_DATA_PUB_INTERVAL; // So we send state data immediately when we begin treatment mode treatmentParamsRangesBroadcastTimerCtr = TREATMENT_SETTINGS_RANGES_PUB_INTERVAL; // So we send ranges immediately when we begin treatment mode ultrafiltrationBroadcastTimerCtr = ULTRAFILTRATION_DATA_PUB_INTERVAL; // So we send ultrafiltration immediately when we begin treatment mode - salineBolusBroadcastTimerCtr = SALINE_BOLUS_DATA_PUB_INTERVAL; // So we send saline bolus data immediately when we begin treatment mode presTreatmentTimeSecs = 0; presUFVolumeMl = 0.0F; @@ -195,6 +190,7 @@ // initRinseback(); // initTreatmentRecirc(); // initTreatmentEnd(); + initFluidBolus(); // Started the treatment - set the start time in epoch // setTxLastStartTimeEpoch( getRTCTimestamp() ); @@ -469,10 +465,6 @@ // currentTreatmentState = handleTreatmentIsoUFState(); // break; // -// case TREATMENT_SALINE_BOLUS_STATE: -// currentTreatmentState = handleTreatmentSalineBolusState(); -// break; -// // case TREATMENT_DIALYSATE_PAUSED_STATE: // currentTreatmentState = handleTreatmentDialysatePausedState(); // break; @@ -509,14 +501,15 @@ broadcastTreatmentPeriodicData(); // Publish ultrafiltration data at set interval (whether we are performing UF or not) publishUltrafiltrationData(); - // Publish saline bolus data at set interval (whether we are delivering one or not) - publishSalineBolusData(); // Manage air trap control execAirTrapMonitorTreatment(); // Execute Blood pressure module execBPModule(); + // Call fluid bolus + execFluidBolus(); + return currentTreatmentState; } @@ -631,10 +624,15 @@ U32 msSinceLast = calcTimeBetween( lastTreatmentTimeStamp, newTime ); DIALYSIS_STATE_T dialysisState = getDialysisState(); - // Update treatment time - treatmentTimeMS += msSinceLast; + // Always update timestamp to avoid time jump on bolus exit lastTreatmentTimeStamp = newTime; + // Only update treatment time when fluid bolus is not active + if ( FALSE == isFluidBolusActive() ) + { + treatmentTimeMS += msSinceLast; + } + // End treatment if treatment duration has been reached if ( CALC_ELAPSED_TREAT_TIME_IN_SECS() >= presTreatmentTimeSecs ) { @@ -919,14 +917,32 @@ payload.rinsebackState = 0; // getCurrentRinsebackState(); payload.txRecircState = 0; // getCurrentTreatmentRecircState(); payload.txEndState = 0; // getCurrentTreatmentEndState(); - payload.txSalBolusState = 0; // + payload.txFluidBolusState = getCurrentFluidBolusState(); payload.txHepState = 0; // broadcastData( MSG_ID_TD_TREATMENT_STATE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&payload), sizeof( TREATMENT_STATE_DATA_T ) ); } } /*********************************************************************//** * @brief + * The updateTreatmentBroadcastData function updates treatment broadcast + * data values used for treatment time and ultrafiltration broadcasts. + * @details \b Inputs: none. + * @details \b Outputs: presTreatmentTimeSecs, presUFVolumeMl, presUFRateMlMin. + * @param ufRateLhr ultrafiltration rate in L/hr. + * @return none. + *************************************************************************/ +void updateTreatmentBroadcastData( F32 ufRateLhr ) +{ + presTreatmentTimeSecs = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ) * SEC_PER_MIN; + + presUFVolumeMl = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + + presUFRateMlMin = ( ufRateLhr * (F32)ML_PER_LITER ) / (F32)MIN_PER_HOUR; +} + +/*********************************************************************//** + * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts * updated treatment parameter ranges that the user may change during treatment. * It is assumed that prescription settings have already been set prior to calling @@ -1106,30 +1122,6 @@ /*********************************************************************//** * @brief - * The publishSalineBolusData function publishes the saline bolus data - * at the set time interval. - * @details \b Inputs: none - * @details \b Outputs: none - * @param dialysisState next dialysis state - * @return next saline bolus state - *************************************************************************/ -static void publishSalineBolusData( void ) -{ - if ( ++salineBolusBroadcastTimerCtr >= SALINE_BOLUS_DATA_PUB_INTERVAL ) - { - SALINE_BOLUS_DATA_PAYLOAD_T data; - - data.tgtSalineVolumeMl = getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); - data.cumSalineVolumeMl = 0.0F; // TODO - data.bolSalineVolumeMl = 0.0F; // TODO - - sendMessage( MSG_ID_TD_SALINE_BOLUS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&data), sizeof( SALINE_BOLUS_DATA_PAYLOAD_T ) ); - salineBolusBroadcastTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief * The publishUltrafiltrationData function publishes the ultrafiltration data * at the set time interval. * @details \b Inputs: none @@ -1146,7 +1138,7 @@ presUFRateLHr = presUFVolumeL / ( (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ) / (F32)MIN_PER_HOUR ); data.setUFVolumeL = presUFVolumeL; - data.tgtUFRateLHr = presUFRateLHr; + data.tgtUFRateLHr = ( presUFRateMlMin * (F32)MIN_PER_HOUR ) / (F32)ML_PER_LITER; data.ufVolumeDeliveredL = getUltrafiltrationVolumeDrawn(); data.ufState = (U32)getDialysisState(); Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r9c4cdc42d3bcef089a9627b206496cb23bc3f643 -r12fa9b72d8e338b624879c284488a04b17115762 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 9c4cdc42d3bcef089a9627b206496cb23bc3f643) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 12fa9b72d8e338b624879c284488a04b17115762) @@ -7,28 +7,28 @@ * * @file AlarmMgmtSWFaults.h * -* @author (last) Dara Navaei -* @date (last) 27-May-2026 +* @author (last) Praneeth Bunne +* @date (last) 04-Jun-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 * ***************************************************************************/ - -#ifndef __ALARM_MGMT_SW_FAULTS_H__ -#define __ALARM_MGMT_SW_FAULTS_H__ - -/** - * @addtogroup AlarmManagement - * @{ - */ - -// ********** public definitions ********** - -/// Listing of specific software faults for logging purposes. -typedef enum -{ - SW_FAULT_ID_NONE = 0, + +#ifndef __ALARM_MGMT_SW_FAULTS_H__ +#define __ALARM_MGMT_SW_FAULTS_H__ + +/** + * @addtogroup AlarmManagement + * @{ + */ + +// ********** public definitions ********** + +/// Listing of specific software faults for logging purposes. +typedef enum +{ + SW_FAULT_ID_NONE = 0, SW_FAULT_ID_ALARM_LAMP_INVALID_PATTERN_REQUESTED = 1, SW_FAULT_ID_ALARM_LAMP_INVALID_SELF_TEST_STATE = 2, SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE = 3, @@ -195,12 +195,13 @@ 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_BP_DRIVER_STATE = 168, - SW_FAULT_ID_TD_BP_MODULE_STATE = 169, + SW_FAULT_ID_INVALID_FLUID_BOLUS_STATE = 167, + SW_FAULT_ID_INVALID_MESSAGE_PAYLOAD_LENGTH = 168, + SW_FAULT_ID_TD_BP_DRIVER_STATE = 169, + SW_FAULT_ID_TD_BP_MODULE_STATE = 170, NUM_OF_SW_FAULT_IDS -} SW_FAULT_ID_T; - +} SW_FAULT_ID_T; + /**@}*/ -#endif +#endif Index: firmware/App/Services/FpgaTD.c =================================================================== diff -u -r41b06072545ff2013cbb16cd874da07ad563b10e -r12fa9b72d8e338b624879c284488a04b17115762 --- firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 41b06072545ff2013cbb16cd874da07ad563b10e) +++ firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 12fa9b72d8e338b624879c284488a04b17115762) @@ -71,6 +71,9 @@ #define FPGA_H18_BUBBLE_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. #define FPGA_H18_BUBBLE_SELF_TEST_CMD 0x08 ///< Bit for venous air bubble detector self-test command. +#define FPGA_NIBP_CMD_MASK 0x0F ///< Bit mask for NIBP command bits +#define FPGA_NIBP_CMD_RDY 0x10 ///< NIBP command ready pulse bit + /// Control bits to run syringe pump in reverse direction // TODO - move to syringe pump controller unit when implemented. static const U08 SYRINGE_PUMP_CONTROL_RUN_REVERSE = SYRINGE_PUMP_CONTROL_SLEEP_OFF | SYRINGE_PUMP_CONTROL_NOT_RESET | @@ -165,6 +168,18 @@ U32 baroTemperature; ///< Reg 372. Baro temperature value in counts. U08 baroReadCount; ///< Reg 376. Baro read count. U08 baroErrorCount; ///< Reg 377. Baro error count. + U08 notUsed; ///< Reg 378. + U08 sPumpDacRdByte2; ///< Reg 379. + U08 sPumpDacRdByte3; ///< Reg 380. + U08 sPumpDacRdByte4; ///< Reg 381. + U08 sPumpDacRdByte5; ///< Reg 382. + U08 sPumpDacRdByte6; ///< Reg 383. + U08 nibpCtlStatus; ///< Reg 384. NIBP control status register. + U08 nibpStatusResp; ///< Reg 385. NIBP response status register. + S16 cuffPressure; ///< Reg 386. NIBP cuff pressure in mmHg. + U16 bpSystolic; ///< Reg 388. Systolic BP in mmHg. + U16 bpDiastolic; ///< Reg 390. Diastolic BP in mmHg. + U16 bpHr; ///< Reg 392. Heart rate in BPM. } FPGA_SENSORS_T; /// Record structure for FPGA continuous priority writes. @@ -192,8 +207,9 @@ 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. + U08 h10DACControl; ///< Reg 40. H10 Syringe pump ADC and DAC control register. + U16 nibpCtl; ///< Reg 41. NIBP control register. + U16 nibpInflate; ///< Reg 42. NIBP inflate pressure register. U32 h5SetSpeed; ///< Reg 44. H5 ejector motor set speed. } FPGA_ACTUATORS_T; @@ -950,21 +966,6 @@ /*********************************************************************//** * @brief - * The setH12AirPumpMotorPWMCntTime function sets the air pump motor PWM count - * time in increments of 10 nS. The PWM period will then be 255 x given - * value x 10 nS. - * @details \b Inputs: fpgaActuatorSetPoints.h12Period - * @details \b Outputs: fpgaActuatorSetPoints.h12Period - * @param tenNS The time associated with each PWM count in power level setting. - * @return none - *************************************************************************/ -void setH12AirPumpMotorPWMCntTime( U16 tenNS ) -{ - fpgaActuatorSetPoints.h12Period = tenNS; -} - -/*********************************************************************//** - * @brief * The H18BubbleDetected function determines whether H18 bubble detector * sensor is currently detecting a bubble. * @details \b Inputs: fpgaSensorReadings @@ -1364,9 +1365,8 @@ *************************************************************************/ void setFPGASyringePumpControlFlags( U08 bitFlags ) { - fpgaActuatorSetPoints.h10Control = bitFlags; + return fpgaActuatorSetPoints.h10Control = bitFlags; } - /*********************************************************************//** * @brief * The setFPGASyringePumpADCandDACControlFlags function sets the syringe pump @@ -1575,4 +1575,114 @@ return fpgaSensorReadings.h10DACEEProm; } +/*********************************************************************//** +* @brief +* The setNIBPCommand function sets the FPGA NIBP command bits and pulses +* the command ready bit to notify the FPGA that a new NIBP command is +* available. +* @details \b Inputs: command +* @details \b Outputs: fpgaActuatorSetPoints.nibpCtl +* @return none +*************************************************************************/ +void setNIBPCommand( U08 command ) +{ + fpgaActuatorSetPoints.nibpCtl &= ~FPGA_NIBP_CMD_MASK; + fpgaActuatorSetPoints.nibpCtl |= ( (U16)command & FPGA_NIBP_CMD_MASK ); + if ( 0 == command ) + { + fpgaActuatorSetPoints.nibpCtl &= ~FPGA_NIBP_CMD_RDY; + } + else + { + fpgaActuatorSetPoints.nibpCtl |= FPGA_NIBP_CMD_RDY; + } +} + +/*********************************************************************//** +* @brief +* The setNIBPInflatePressure function sets the initial NIBP cuff inflate +* pressure register. +* @details \b Inputs: pressure +* @details \b Outputs: fpgaActuatorSetPoints.nibpInflate +* @return none +*************************************************************************/ +void setNIBPInflatePressure( U16 pressure ) +{ + fpgaActuatorSetPoints.nibpInflate = pressure; +} + +/********************************************************************//** + * @brief + * The getNIBPControlStatus function returns the FPGA NIBP control status. + * @details \b Inputs: fpgaSensorReadings.nibpCtlStatus + * @details \b Outputs: none + * @return FPGA NIBP control status register. + ***************************************************************************/ +U08 getNIBPControlStatus( void ) +{ + return fpgaSensorReadings.nibpCtlStatus; +} + +/*********************************************************************//** + * @brief + * The getNIBPStatusResponse function returns the FPGA NIBP response status. + * @details \b Inputs: fpgaSensorReadings.nibpStatusResp + * @details \b Outputs: none + * @return FPGA NIBP response status register. + ***************************************************************************/ +U08 getNIBPStatusResponse( void ) +{ + return fpgaSensorReadings.nibpStatusResp; +} + +/*********************************************************************//** +* @brief +* The getNIBPCuffPressure function returns the FPGA NIBP cuff pressure. +* @details \b Inputs: fpgaSensorReadings.cuffPressure +* @details \b Outputs: none +* @return NIBP cuff pressure in mmHg. +*************************************************************************/ +S16 getNIBPCuffPressure( void ) +{ + return fpgaSensorReadings.cuffPressure; +} + +/*********************************************************************//** +* @brief +* The getNIBPSystolicPressure function returns the FPGA systolic blood +* pressure measurement. +* @details \b Inputs: fpgaSensorReadings.bpSystolic +* @details \b Outputs: none +* @return Systolic blood pressure in mmHg. +*************************************************************************/ +U16 getNIBPSystolicPressure( void ) +{ + return fpgaSensorReadings.bpSystolic; +} + +/*********************************************************************//** +* @brief +* The getNIBPDiastolicPressure function returns the FPGA diastolic blood +* pressure measurement. +* @details \b Inputs: fpgaSensorReadings.bpDiastolic +* @details \b Outputs: none +* @return Diastolic blood pressure in mmHg. +*************************************************************************/ +U16 getNIBPDiastolicPressure( void ) +{ + return fpgaSensorReadings.bpDiastolic; +} + +/*********************************************************************//** +* @brief +* The getNIBPHeartRate function returns the FPGA heart rate measurement. +* @details \b Inputs: fpgaSensorReadings.bpHr +* @details \b Outputs: none +* @return Heart rate in BPM. +*************************************************************************/ +U16 getNIBPHeartRate( void ) +{ + return fpgaSensorReadings.bpHr; +} + /**@}*/ Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r9c4cdc42d3bcef089a9627b206496cb23bc3f643 -r12fa9b72d8e338b624879c284488a04b17115762 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 9c4cdc42d3bcef089a9627b206496cb23bc3f643) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 12fa9b72d8e338b624879c284488a04b17115762) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Dara Navaei -* @date (last) 27-May-2026 +* @author (last) Praneeth Bunne +* @date (last) 04-Jun-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -28,10 +28,12 @@ #include "CpldInterface.h" #include "DDInterface.h" #include "Ejector.h" +#include "FluidBolus.h" #include "FpgaTD.h" #include "LevelSensors.h" #include "Messaging.h" #include "ModeStandby.h" +#include "ModeTreatment.h" #include "OperationModes.h" #include "PAL.h" #include "Pressures.h" @@ -113,16 +115,27 @@ { MSG_ID_DD_GEN_DIALYSATE_MODE_DATA, &setDialysateData }, { MSG_ID_DD_PRESSURES_DATA, &setDialysatePressure }, { MSG_ID_UI_TREATMENT_PARAMS_TO_VALIDATE, &validateAndSetTreatmentParameters }, + { MSG_ID_UI_TREATMENT_UF_VOLUME_VALIDATE_REQUEST, &validateAndSetUFVolume }, + { MSG_ID_UI_ULTRAFILTRATION_CHANGE_CONFIRM_REQUEST, &signalUserConfirmationOfUFVolume }, + { MSG_ID_UI_DURATION_VALIDATE_REQUEST, &validateAndSetTreatmentDuration }, + { MSG_ID_UI_DURATION_CONFIRM_REQUEST, &signalUserConfirmationOfTreatmentDuration }, + { MSG_ID_UI_BOLUS_VOLUME_CHANGE_REQUEST, &validateAndSetBolusVolume }, { MSG_ID_UI_INITIATE_TREATMENT_WORKFLOW, &signalUserInitiateTreatment }, { MSG_ID_UI_UF_PAUSE_RESUME_REQUEST, &signalPauseResumeUF }, { MSG_ID_TESTER_LOGIN_REQUEST, &handleTesterLogInRequest }, { MSG_ID_UI_PRESSURE_LIMIT_WIDEN_REQUEST, &pressureLimitHandleWidenRequest }, + { MSG_ID_UI_PRESSURE_LIMITS_CHANGE_REQUEST, &pressureLimitHandleChangeRequest }, + { MSG_ID_UI_TREATMENT_SET_POINTS_CHANGE_REQUEST, &validateAndSetTreatmentSetPoints }, + { MSG_ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_REQUEST, &validateAndSetBloodFlowRate }, + { MSG_ID_UI_TREATMENT_SET_POINT_DIALYSATE_FLOW_CHANGE_REQUEST, &validateAndSetDialysateFlowRate }, + { MSG_ID_UI_TREATMENT_SET_POINT_DIALYSATE_TEMP_CHANGE_REQUEST, &validateAndSetDialysateTemperature }, { MSG_ID_UI_BLOOD_PRIME_CMD_REQUEST, &bloodPrimeHandleCmdRequest }, { MSG_ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_REQUEST, &bloodPrimeHandleBloodFlowChangeRequest }, { MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST, &handleAutoLoadRequest }, { 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_TD_SOFTWARE_RESET_REQUEST, &testTDSoftwareResetRequest }, { MSG_ID_TD_BUBBLE_OVERRIDE_REQUEST, &testBubbleDetectOverride }, { MSG_ID_TD_BUBBLE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testBubblesDataPublishIntervalOverride }, @@ -207,6 +220,7 @@ { MSG_ID_TD_SYRINGE_PUMP_FORCE_SENSOR_CALIBRATION_REQUEST, &testCalibrateForceSensor }, }; +/// Number of entries in the message handling function lookup table. #define NUM_OF_FUNCTION_HANDLERS (sizeof(MSG_FUNCTION_HANDLER_LOOKUP) / sizeof(MSG_HANDLER_LOOKUP_T)) // ********** private data **********