/************************************************************************** * * Copyright (c) 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 BPDriver.c * * @author (last) Varshini Nagabooshanam * @date (last) 18-May-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 18-May-2026 * ***************************************************************************/ #include "AlarmMgmtTD.h" #include "BPDriver.h" #include "FpgaTD.h" /** * @addtogroup BPDriver * @{ */ // ********** private definitions ********** #define BP_RESP_CODE_MASK 0x3C ///< Blood pressure response code mask. #define BP_RESP_CODE_SHIFT 2 ///< Blood pressure response code bit shift. #define BP_MODULE_ERROR_MASK 0x40 ///< Blood pressure module error mask. #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 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_STATE_T; // ********** private data ********** static BP_DRIVER_STATE_T bpDriverState = BP_DRIVER_IDLE_STATE; ///< Current blood pressure driver state. static BP_RESULTS_T bpResults; ///< Latest blood pressure measurement results. static BOOL bpMeasurementReady; ///< Blood pressure measurement ready static BOOL bpDriverError; ///< Blood pressure driver error static BOOL requestAdultBPMeasurement; ///< Request adult BP measurement static BOOL requestPedsBPMeasurement; ///< Request pediatric BP measurement static BOOL requestAbortBPMeasurement; ///< Request abort BP measurement // ********** 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 handleBPDriverGetDataState( void ); /*********************************************************************//** * @brief * The initBPDriver function initializes the blood pressure driver. * @details \b Inputs: none * @details \b Outputs: BPDriver variables initialized * @return none ***************************************************************************/ void initBPDriver( void ) { bpDriverState = BP_DRIVER_IDLE_STATE; bpMeasurementReady = FALSE; bpDriverError = FALSE; requestAdultBPMeasurement = FALSE; requestPedsBPMeasurement = FALSE; requestAbortBPMeasurement = FALSE; bpResults.systolic = 0; bpResults.diastolic = 0; bpResults.heartRate = 0; } /*********************************************************************//** * @brief * The getBPResponseCode function returns the FPGA NIBP response code. * @details \b Inputs: getNIBPStatusResponse * @details \b Outputs: none * @return FPGA NIBP response code. ***************************************************************************/ static U08 getBPResponseCode( void ) { return ( ( getNIBPStatusResponse() & BP_RESP_CODE_MASK ) >> BP_RESP_CODE_SHIFT ); } /*********************************************************************//** * @brief * The execBPDriver function executes the blood pressure driver state * machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT * @details \b Inputs: bpDriverState * @details \b Outputs: bpDriverState, bpResults * @return none ***************************************************************************/ void execBPDriver( void ) { switch ( bpDriverState ) { case BP_DRIVER_IDLE_STATE: bpDriverState = handleBPDriverIdleState(); break; case BP_DRIVER_MEASURE_STATE: bpDriverState = handleBPDriverMeasureState(); break; case BP_DRIVER_GET_DATA_STATE: bpDriverState = handleBPDriverGetDataState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_BP_DRIVER_STATE, bpDriverState ); bpDriverState = BP_DRIVER_IDLE_STATE; break; } } /*********************************************************************//** * @brief * The handleBPDriverIdleState function executes the BP driver idle * state handling. * @details \b Inputs: requestAdultBPMeasurement, requestPedsBPMeasurement, * requestAbortBPMeasurement * @details \b Outputs: nextState * @return next BP module state ***************************************************************************/ static BP_DRIVER_STATE_T handleBPDriverIdleState( void ) { BP_DRIVER_STATE_T nextState = BP_DRIVER_IDLE_STATE; if ( TRUE == requestAdultBPMeasurement ) { requestAdultBPMeasurement = FALSE; bpMeasurementReady = FALSE; bpDriverError = FALSE; setNIBPCommand( FPGA_NIBP_CMD_START_BP ); nextState = BP_DRIVER_MEASURE_STATE; } else if ( TRUE == requestPedsBPMeasurement ) { requestPedsBPMeasurement = FALSE; bpMeasurementReady = FALSE; bpDriverError = FALSE; setNIBPCommand( FPGA_NIBP_CMD_START_PEDS_BP ); nextState = BP_DRIVER_MEASURE_STATE; } else if ( TRUE == requestAbortBPMeasurement ) { requestAbortBPMeasurement = FALSE; setNIBPCommand( FPGA_NIBP_CMD_ABORT_BP ); } return nextState; } /*********************************************************************//** * @brief * The handleBPDriverMeasureState function executes the BP driver * measurement state handling. * @details \b Inputs: getNIBPStatusResponse * @details \b Outputs: setNIBPCommand, bpDriverState, bpDriverError * @return next BP driver state ***************************************************************************/ static BP_DRIVER_STATE_T handleBPDriverMeasureState( void ) { BP_DRIVER_STATE_T nextState = BP_DRIVER_MEASURE_STATE; if ( BP_MODULE_BUSY_CLEAR == ( getNIBPStatusResponse() & BP_MODULE_BUSY_MASK ) ) { // Verify BP measurement data is available if ( BP_RESP_CODE_BPDATA == getBPResponseCode() ) { setNIBPCommand( FPGA_NIBP_CMD_GET_BP_DATA ); nextState = BP_DRIVER_GET_DATA_STATE; } // Check whether BP module error occurred else if ( BP_MODULE_BUSY_CLEAR != ( getNIBPStatusResponse() & BP_MODULE_ERROR_MASK ) ) { bpDriverError = TRUE; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, getNIBPStatusResponse(), bpDriverState ); nextState = BP_DRIVER_IDLE_STATE; } } return nextState; } /*********************************************************************//** * @brief * The handleBPDriverGetDataState function retrieves blood pressure * measurement results. * @details \b Inputs: getNIBPStatusResponse * @details \b Outputs: bpResults * @return next BP driver state ***************************************************************************/ static BP_DRIVER_STATE_T handleBPDriverGetDataState( void ) { BP_DRIVER_STATE_T nextState = BP_DRIVER_GET_DATA_STATE; if ( ( getNIBPStatusResponse() & BP_MODULE_BUSY_MASK ) == 0 ) { bpResults.systolic = getNIBPSystolicPressure(); bpResults.diastolic = getNIBPDiastolicPressure(); bpResults.heartRate = getNIBPHeartRate(); bpMeasurementReady = TRUE; nextState = BP_DRIVER_IDLE_STATE; } return nextState; } /*********************************************************************//** * @brief * The startAdultBPMeasurement function requests an adult blood pressure * measurement. * @details \b Inputs: none * @details \b Outputs: requestAdultBPMeasurement * @return none ***************************************************************************/ void startAdultBPMeasurement( void ) { requestAdultBPMeasurement = TRUE; } /*********************************************************************//** * @brief * The startPedsBPMeasurement function requests a pediatric blood pressure * measurement. * @details \b Inputs: none * @details \b Outputs: requestPedsBPMeasurement * @return none ***************************************************************************/ void startPedsBPMeasurement( void ) { requestPedsBPMeasurement = TRUE; } /*********************************************************************//** * @brief * The abortBPMeasurement function aborts the active blood pressure * measurement. * @details \b Inputs: none * @details \b Outputs: requestAbortBPMeasurement * @return none ***************************************************************************/ void abortBPMeasurement( void ) { requestAbortBPMeasurement = TRUE; } /*********************************************************************//** * @brief * The isBPMeasurementReady function returns the blood pressure * measurement ready status * @details \b Inputs: bpMeasurementReady * @details \b Outputs: none * @return TRUE if measurement ready, FALSE otherwise. ***************************************************************************/ BOOL isBPMeasurementReady( void ) { return bpMeasurementReady; } /*********************************************************************//** * @brief * The hasBPDriverError function returns the blood pressure driver * error status. * @details \b Inputs: bpDriverError * @details \b Outputs: none * @return TRUE if module error exists, FALSE otherwise. ***************************************************************************/ BOOL hasBPDriverError( void ) { return bpDriverError; } /*********************************************************************//** * @brief * The getBPResults function returns the latest BP measurement results. * @note * This function shall only be called from the GeneralTask context to * avoid concurrent access while bpResults is being updated. * @details \b Inputs: bpResults * @details \b Outputs: results * @return TRUE if results copied, FALSE otherwise. ***************************************************************************/ BOOL getBPResults( BP_RESULTS_T *results ) { BOOL result = FALSE; if ( ( NULL != results ) && ( TRUE == bpMeasurementReady ) ) { *results = bpResults; result = TRUE; } return result; } /**@}*/