/************************************************************************** * * Copyright (c) 2024-2024 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 FPGA.c * * @author (last) Sean Nash * @date (last) 30-Jul-2024 * * @author (original) Sean Nash * @date (original) 30-Jul-2024 * ***************************************************************************/ #include // For memset(), memcpy() #include "sci.h" #include "sys_dma.h" #include "Comm.h" #include "Compatible.h" #include "FPGA.h" #include "FpgaTD.h" #include "Messaging.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Timers.h" #include "Utilities.h" /** * @addtogroup FpgaTD * @{ */ // ********** private definitions ********** #define FPGA_EXPECTED_ID 0x03 ///< Expected ID for TD FPGA. #define PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE 1 ///< Tolerance for processor clock speed check against FPGA clock. #define MAX_FPGA_COMM_FAILURES_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< FPGA comm failures window #define MAX_FPGA_COMM_FAILURES 3 ///< FPGA maximum comm failures per MAX_FPGA_COMM_FAILURES_WINDOW_MS #define MIN_POWER_ON_TIME_FOR_COMM_FAILS ( 1 * MS_PER_SECOND ) ///< Allow FPGA comm errors for first second after power-up #define FPGA_BP_ENABLE_BIT_MASK 0x01 ///< Bit mask for enabling the blood pump. #define FPGA_BP_DIRECTION_FWD_BIT_MASK 0x02 ///< Bit mask for setting the blood pump direction. #define FPGA_BP_HOME_BIT_MASK 0x04 ///< Bit mask for requesting a blood pump home operation. #define FPGA_VBT_OPEN_BIT_MASK 0x01 ///< Bit mask for setting VBT valve position to open. #define FPGA_INPUT_VOLTAGE_SCALE 3.0F ///< FPGA source and aux voltage. #define FPGA_PVN_VOLTAGE_SCALE 1.0F ///< FPGA pvn voltage. #define FPGA_ALARM_AUDIO_VOLUME_SHIFT 3 ///< Shift alarm audio volume 3 bits to left before writing to register. #define FPGA_ALARM_AUDIO_DIVIDE_SHIFT 6 ///< Shift alarm audio volume divider 6 bits to left before writing to register. #define FPGA_BACKUP_ALARM_AUDIO_CONVERT 0.4F ///< Converts backup (piezo) alarm audio ADC volts to amps. #define FRONT_DOOR_SWITCH_MASK 0x0010 ///< Front door switch bit mask. Bit 4 of the GPIO register. #define PUMP_TRACK_SWITCH_MASK 0x0020 ///< Pump track switch bit mask. Bit 5 of the GPIO register. #define FPGA_AIRTRAP_LEVEL_LOW_MASK 0x0008 ///< Bit mask for air trap lower level sensor. #define FPGA_AIRTRAP_LEVEL_HIGH_MASK 0x0004 ///< Bit mask for air trap upper level sensor. #define FPGA_ADV_BUBBLE_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. #define FPGA_ADV_BUBBLE_SELF_TEST_CMD 0x08 ///< Bit for venous air bubble detector self-test command. // FPGA Sensors Record #pragma pack(push,1) /// Record structure for FPGA header read. typedef struct { U08 fpgaId; ///< Reg 0. FPGA ID code. Checked against expected value at power up to verify basic FPGA communication and operation. U08 fpgaRev; ///< Reg 1. FPGA revision (minor) being reported. U08 fpgaRevMajor; ///< Reg 2. FPGA revision (major) being reported. U08 fpgaRevLab; ///< Reg 3. FPGA revision (lab) being reported. } FPGA_HEADER_T; // Read only on FPGA /// Record structure for FPGA continuous priority reads. typedef struct { 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 reserved1; ///< Reg 261. Reserved and available for future use. U16 sPumpDACSet; ///< Reg 262. Syringe pump DAC setting. U16 sPumpDACEEProm; ///< Reg 264. Syringe pump DAC EEProm data. U16 PBoPressure; ///< Reg 266. PBo raw pressure data. S16 PBoTemperature; ///< Reg 268. PBo raw temperature data. U08 PBoReadCount; ///< Reg 270. PBo read count. U08 PBoErrorCount; ///< Reg 271. PBo error count. U32 reserved3; ///< Reg 272. Reserved and available for future use. U16 PBAPressure; ///< Reg 276. PBA raw pressure data. S16 PBATemperature; ///< Reg 278. PBA raw temperature data. U08 PBAReadCount; ///< Reg 280. PBA read count. U08 PBAErrorCount; ///< Reg 281. PBA error count. S16 VBACmdPosition; ///< Reg 282. VBA commanded position (200 steps/rev). S16 VBAEncPosition; ///< Reg 284. VBA encoder position (1024 counts/rev). U08 VBAStatus; ///< Reg 286. VBA status. U08 reserved4; ///< Reg 287. Reserved and available for future use. U08 BEMStatus; ///< Reg 288. BEM status. U08 BEMEncStatus; ///< Reg 289. BEM encoder status. S32 BEMEncPosition; ///< Reg 290. BEM encoder position. S16 BPSpeed; ///< Reg 294. BP measured speed (RPM). S16 BPTorque; ///< Reg 296. BP measured torque. S16 BPSpeedFromHall; ///< Reg 298. BP measured speed from hall sensor(s). S16 VBVCmdPosition; ///< Reg 300. VBV commanded position (200 steps/rev). S16 VBVEncPosition; ///< Reg 302. VBV encoder position (1024 counts/rev). U08 VBVStatus; ///< Reg 304. VBV status. U08 BPStatus; ///< Reg 305. BP status. U16 GPIOReg; ///< Reg 306. GPIO register. U08 HEPStatus; ///< Reg 308. HEP status register. U08 HEPAdcReadCount; ///< Reg 309. HEP ADC read counter. U08 HEPAdcDacStatus; ///< Reg 310. HEP ADC/DAC status register. U08 HEPEncStatus; ///< Reg 311. HEP encoder status register. S32 HEPEncPosition; ///< Reg 312. HEP encoder position. U16 HEPAdcCh0; ///< Reg 316. HEP ADC channel 0 reading. U16 HEPAdcCh1; ///< Reg 318. HEP ADC channel 1 reading. U16 HEPAdcCh2; ///< Reg 320. HEP ADC channel 2 reading. U16 HEPAdcCh3; ///< Reg 322. HEP ADC channel 3 reading. U16 fpgaAdcTemperature; ///< Reg 324. FPGA ADC temperature. U16 fpga1msTimerCounter; ///< Reg 326. FPGA 1 millisecond timer counter. U16 alarmBuzzerCurrentAdc; ///< Reg 328. Alarm buzzer current ADC reading. U16 fpgaVccInternalAdc; ///< Reg 330. FPGA Vcc internal voltage ADC reading. U16 fpgaCompatibilityRev; ///< Reg 332. Compatibility revision. U08 VBTStatus; ///< Reg 334. VBT status register. U08 VBTStatusPWM; ///< Reg 335. VBT PWM status register. S16 ACPower1Current; ///< Reg 336. AC power current - 1. S16 ACPower1Voltage; ///< Reg 338. AC power voltage - 1. S16 ACPower2Current; ///< Reg 340. AC power current - 2. S16 ACPower2Voltage; ///< Reg 342. AC power voltage - 2. S16 ACPower3Current; ///< Reg 344. AC power current - 3. S16 ACPower3Voltage; ///< Reg 346. AC power voltage - 3. } FPGA_SENSORS_T; /// Record structure for FPGA continuous priority writes. typedef struct { U16 fpgaGenWrRd; ///< Reg 04. FPGA general write/read-back register (mirrored to a general read register in read page at addr 256). U08 VBTControl; ///< Reg 06. VBT valve control register. U08 reserved1; ///< Reg 07. Reserved. U08 VBTPWMEnable; ///< Reg 08. VBT valve PWM enable register. U08 reserved2; ///< Reg 09. Reserved. U16 VBTPWMLowPeriod; ///< Reg 10. VBT PWM low signal period register. U16 VBTPWMPeriod; ///< Reg 12. VBT PWM period register. U16 VBTPWMPUllInTime; ///< Reg 14. VBT PWM pull in time register. U16 ACHeaterPWM; ///< Reg 16. AC heater PWM duty cycle set register. U08 ATAPControl; ///< Reg 18. Air pump control register. U08 BEMControl; ///< Reg 19. Blood ejector stepper motor control register. U16 BEMSetSpeed; ///< Reg 20. Blood ejector stepper motor step register. U16 BPSetSpeed; ///< Reg 22. Blood pump speed set register (RPM). U08 BPControl; ///< Reg 24. Blood pump control register. U08 VBVControl; ///< Reg 25. VBV control register. U16 VBVPosition; ///< Reg 26. VBV position set register (200 steps/rev). U16 VBAPosition; ///< Reg 28. VBA position set register (200 steps/rev). U16 VBAControl; ///< Reg 30. VBA control register. U08 reserved3; ///< Reg 31. Reserved. U16 reserved4; ///< Reg 32. Reserved. U08 alarmControl; ///< Reg 34. Alarm audio control register. U08 reserved5; ///< Reg 35. Reserved. U32 reserved6; ///< Reg 36. Reserved. U16 reserved7; ///< Reg 40. Reserved. U16 reserved8; ///< Reg 42. Reserved. U08 sensorTest; ///< Reg 44. Sensor self-test control register. } FPGA_ACTUATORS_T; #pragma pack(pop) // ********** private data ********** // FPGA data static FPGA_HEADER_T fpgaHeader; ///< Record of last received FPGA header data. static FPGA_SENSORS_T fpgaSensorReadings; ///< Record of last received FPGA priority sensor data. static FPGA_ACTUATORS_T fpgaActuatorSetPoints; ///< Record of next transmitted FPGA priority actuator data. // FPGA Clock Speed Test static U16 currentFPGATimerCount_ms = 0; ///< Last read ms timer count from FPGA. static U32 currentTimerCount_ms = 0; ///< Last read ms timer count from processor. // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initFpgaTD function initializes the TD FPGA unit. * @details \b Inputs: none * @details \b Outputs: TD FPGA unit initialized. * @return none *************************************************************************/ void initFpgaTD( void ) { // Initialize fpga driver initFPGA( (U08*)&fpgaHeader, (U08*)&fpgaSensorReadings, (U08*)&fpgaActuatorSetPoints, sizeof(FPGA_HEADER_T), sizeof(FPGA_SENSORS_T), sizeof(FPGA_ACTUATORS_T) ); // Initialize fpga data structures memset( &fpgaHeader, 0, sizeof(FPGA_HEADER_T) ); memset( &fpgaSensorReadings, 0, sizeof(FPGA_SENSORS_T) ); memset( &fpgaActuatorSetPoints, 0, sizeof(FPGA_ACTUATORS_T) ); fpgaActuatorSetPoints.alarmControl = (U08)MIN_ALARM_VOLUME_ATTENUATION << 2; // Start alarm audio volume at maximum // Set VBA and VBV to default configuration + disabled so they do not run immediately on power up fpgaActuatorSetPoints.VBAControl = FPGA_PINCH_VALVES_1_32_STEP | FPGA_PINCH_VALVES_DISABLE | FPGA_PINCH_VALVES_NOT_RESET | FPGA_PINCH_VALVES_NOT_SLEEP; fpgaActuatorSetPoints.VBVControl = FPGA_PINCH_VALVES_1_32_STEP | FPGA_PINCH_VALVES_DISABLE | FPGA_PINCH_VALVES_NOT_RESET | FPGA_PINCH_VALVES_NOT_SLEEP; // initialize FPGA comm failures windowed timer count initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_COMM_FAILURES, MAX_FPGA_COMM_FAILURES, MAX_FPGA_COMM_FAILURES_WINDOW_MS); } /*********************************************************************//** * @brief * The execFPGATest function executes the FPGA self-test. * @details \b Alarm: ALARM_ID_TD_FPGA_POST_TEST_FAILED if self-test fails. * @details \b Inputs: fpgaHeader * @details \b Outputs: none * @return passed or failed *************************************************************************/ SELF_TEST_STATUS_T execFPGATest( void ) { SELF_TEST_STATUS_T result; // check FPGA reported correct ID if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) { // Check FPGA compatibility w/ firmware if ( TD_FPGA_COMPATIBILITY_REV == fpgaSensorReadings.fpgaCompatibilityRev ) { result = SELF_TEST_STATUS_PASSED; } else { result = SELF_TEST_STATUS_FAILED; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_FPGA_POST_TEST_FAILED, (U32)TD_FPGA_COMPATIBILITY_REV, (U32)fpgaSensorReadings.fpgaCompatibilityRev ) } } else { result = SELF_TEST_STATUS_FAILED; SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TD_FPGA_POST_TEST_FAILED, (U32)fpgaHeader.fpgaId ) } return result; } /*********************************************************************//** * @brief * The getFPGATimerCount function gets the latest FPGA timer millisecond count. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return last FPGA millisecond timer count *************************************************************************/ U16 getFPGATimerCount( void ) { return fpgaSensorReadings.fpga1msTimerCounter; } /*********************************************************************//** * @brief * The execFPGAClockSpeedTest function verifies the processor clock speed * against the FPGA clock. * @details \b Alarm: ALARM_ID_TD_FPGA_CLOCK_SPEED_CHECK_FAILURE if test fails. * @details \b Inputs: fpgaSensorReadings.fpgaTimerCount_ms, msTimerCount, * currentFPGATimerCount_ms, currentTimerCount_ms * @details \b Outputs: currentFPGATimerCount_ms, currentTimerCount_ms * @return none *************************************************************************/ void execFPGAClockSpeedTest( void ) { // DEBUG WARNING // It may be necessary to comment out the following // code to prevent the alarm from occurring while // debugging. U16 newFPGATimerCount_ms = getFPGATimerCount(); U32 newTimerCount_ms = getMSTimerCount(); U32 diffFPGATimerCount = (U32)u16DiffWithWrap( currentFPGATimerCount_ms, newFPGATimerCount_ms ); U32 diffTimerCount = u32DiffWithWrap( currentTimerCount_ms, newTimerCount_ms ); if ( getCurrentOperationMode() != MODE_INIT ) { if ( abs( diffFPGATimerCount - diffTimerCount ) > PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE ) { if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CLOCK_SPEED_ERROR ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_FPGA_CLOCK_SPEED_CHECK_FAILURE, diffFPGATimerCount, diffTimerCount ); } } } currentFPGATimerCount_ms = newFPGATimerCount_ms; currentTimerCount_ms = newTimerCount_ms; } /*********************************************************************//** * @brief * The getFPGAVersions function gets the fpga version numbers. * @details \b Inputs: fpgaHeader * @details \b Outputs: Given version reference variables are populated. * @return none *************************************************************************/ void getFPGAVersions( U08 *Id, U08 *Maj, U08 *Min, U08 *Lab ) { *Id = fpgaHeader.fpgaId; *Min = fpgaHeader.fpgaRev; *Maj = fpgaHeader.fpgaRevMajor; *Lab = fpgaHeader.fpgaRevLab; } /*********************************************************************//** * @brief * The getFPGATemperature function gets the fpga internal die temperature. * @details \b Inputs: fpgaHeader * @details \b Outputs: none * @return current internal FPGA die temperature (in counts) *************************************************************************/ U16 getFPGATemperature( void ) { return fpgaSensorReadings.fpgaAdcTemperature; } /*********************************************************************//** * @brief * The getFPGAVcc function gets the fpga input voltage. * @details \b Inputs: fpgaHeader * @details \b Outputs: none * @return current FPGA input voltage (in volts) *************************************************************************/ F32 getFPGAVcc( void ) { F32 result = (F32)fpgaSensorReadings.fpgaVccInternalAdc * FPGA_INPUT_VOLTAGE_SCALE / (F32)BITS_12_FULL_SCALE; return result; } /*********************************************************************//** * @brief * The getFPGAVccAux function gets the fpga aux. voltage. * @details \b Inputs: fpgaHeader * @details \b Outputs: none * @return current FPGA aux. voltage (in volts) *************************************************************************/ F32 getFPGAVccAux( void ) { F32 result = 0.0F;//(F32)fpgaSensorReadings.fpgaAuxVoltage * FPGA_INPUT_VOLTAGE_SCALE / (F32)BITS_12_FULL_SCALE; return result; } /*********************************************************************//** * @brief * The getFPGAVpvn function gets the fpga pvn voltage. * @details \b Inputs: fpgaHeader * @details \b Outputs: none * @return current FPGA pvn voltage (in volts) *************************************************************************/ F32 getFPGAVpvn( void ) { F32 result = 0.0F;//(F32)fpgaSensorReadings.fpgaVpvn * FPGA_PVN_VOLTAGE_SCALE / (F32)BITS_12_FULL_SCALE; return result; } /*********************************************************************//** * @brief * The setAlarmAudioState function sets the fpga audio control to the given * state and volume. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given state or volume * level is invalid. * @details \b Inputs: none * @details \b Outputs: alarm audio state and attenuation set * @param state the state of alarm audio to command (3..5): * 0 - No alarm tone * 1 - Low priority alarm tone (c e) * 2 - Medium priority alarm tone (c f# c) * 3 - High priority alarm tone (c f# c - c f#) * 4 - Continuous test tone (e) * @param volumeLevel the level of attenuation to command (0..2): * 4 - 3 dB gain * 3 - 6 dB gain * 2 - 9 dB gain * 1 - 12 dB gain * 0 - 15 dB gain * @param volumeDivider further attenuation via divider (6..7): * 0 - Divide by 2 * 1 - Divide by 4 * 2 - Divide by 8 * 3 - Divide by 16 * @return none *************************************************************************/ void setAlarmAudioState( U32 state, U32 volumeLevel, U32 volumeDivider ) { U08 audioCmd = (U08)state; audioCmd |= ( (U08)volumeLevel << FPGA_ALARM_AUDIO_VOLUME_SHIFT ); audioCmd |= ( (U08)volumeDivider << FPGA_ALARM_AUDIO_DIVIDE_SHIFT ); if ( ( state <= NUM_OF_ALARM_PRIORITIES ) && ( volumeLevel <= MAX_ALARM_VOLUME_ATTENUATION ) ) { fpgaActuatorSetPoints.alarmControl = audioCmd; } else { // S/w fault to indicate issue w/ s/w SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_INVALID_ALARM_AUDIO_PARAM, (U32)audioCmd ) // Set alarm audio to high priority, max volume for safety since s/w seems to be having trouble setting audio correctly audioCmd = (U08)ALARM_PRIORITY_HIGH; audioCmd |= ( (U08)MIN_ALARM_VOLUME_ATTENUATION << FPGA_ALARM_AUDIO_VOLUME_SHIFT ); fpgaActuatorSetPoints.alarmControl = audioCmd; } } /*********************************************************************//** * @brief * The setBPEnabled function enables or disables the blood pump per * the given flag. * @details \b Inputs: none * @details \b Outputs: Blood pump enabled or disabled (bit 0 of BP control register) * @param enable TRUE if BP enable is requested, FALSE if BP disable is requested * @return none *************************************************************************/ void setBPEnabled( BOOL enable ) { if ( TRUE == enable ) { fpgaActuatorSetPoints.BPControl |= FPGA_BP_ENABLE_BIT_MASK; } else { fpgaActuatorSetPoints.BPControl &= ~((U08)FPGA_BP_ENABLE_BIT_MASK); } } /*********************************************************************//** * @brief * The setBPDirection function sets the direction for the blood pump * motor to the given direction. * @details \b Inputs: none * @details \b Outputs: Blood pump motor direction is set (bit 1 of BP control register). * 0 - CW (forward) * 1 - CCW (reverse) * @param dir the desired direction for the blood pump motor (fwd or rev) * @return none *************************************************************************/ void setBPDirection( MOTOR_DIR_T dir ) { if ( MOTOR_DIR_REVERSE == dir ) { fpgaActuatorSetPoints.BPControl &= ~((U08)FPGA_BP_DIRECTION_FWD_BIT_MASK); } else { fpgaActuatorSetPoints.BPControl |= FPGA_BP_DIRECTION_FWD_BIT_MASK; } } /*********************************************************************//** * @brief * The homeBP function sets the bit requesting that the blood pump * be homed. * @details \b Inputs: none * @details \b Outputs: BP home request is set (bit 2 of BP control register). * @return none *************************************************************************/ void homeBP( void ) { fpgaActuatorSetPoints.BPControl |= FPGA_BP_HOME_BIT_MASK; } /*********************************************************************//** * @brief * The resetBPHomeRequest function resets the fpga blood pump home * request. * @note This function should be called after request is made and transmission * to FPGA is complete. * @details \b Inputs: none * @details \b Outputs: BP home request is cleared (bit 2 of BP control register) * @return none *************************************************************************/ void resetBPHomeRequest( void ) { fpgaActuatorSetPoints.BPControl &= ~((U08)FPGA_BP_HOME_BIT_MASK); } /*********************************************************************//** * @brief * The setBPSetSpeed function sets the fpga blood pump set speed * to the given speed (0..3000 RPM). * @details \b Inputs: none * @details \b Outputs: BP set speed is set * @param rpm the set point for the BP speed (in RPM). * @return none *************************************************************************/ void setBPSetSpeed( U16 rpm ) { fpgaActuatorSetPoints.BPSetSpeed = rpm; } /*********************************************************************//** * @brief * The getBPSpeed function gets the latest blood pump speed (in RPM) * from the FPGA. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return Latest blood pump speed. *************************************************************************/ U16 getBPSpeed( void ) { return fpgaSensorReadings.BPSpeed; } /*********************************************************************//** * @brief * The getBloodPumpHallSensorCount function gets the latest blood pump * hall sensor count. Count is a 16 bit free running counter. If counter is * counting up, indicates motor is running in forward direction. If counter is * counting down, indicates motor is running in reverse direction. Counter will * wrap at 0/65535. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return Latest blood pump hall sensor count reading. *************************************************************************/ U16 getBloodPumpHallSensorCount( void ) { return 0;//fpgaSensorReadings.bloodPumpHallSensorCount; } /*********************************************************************//** * @brief * The getBloodPumpHallSensorStatus function gets the latest blood pump * hall sensor status. * Bit 7 - Derived direction of the blood pump motor (0=Fwd, 1=Rev) * Bit 6 - Unused * Bit 5-0 - Direction error count since power-up (rolls over) * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest blood pump hall sensor status reading. *************************************************************************/ U08 getBloodPumpHallSensorStatus( void ) { return 0;//fpgaSensorReadings.bloodPumpHallSensorStatus; } /*********************************************************************//** * @brief * The getPBAPressure function gets the latest arterial pressure reading. * The high 2 bits are status bits: 00=ok, 01=cmd mode, 10=stale data, 11=diag * The low 14 bits are data. Zero is at 1638. Values above are positive, * below are negative. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest arterial pressure reading *************************************************************************/ U16 getPBAPressure( void ) { return fpgaSensorReadings.PBAPressure; } /*********************************************************************//** * @brief * The getPBATemperature function gets the latest arterial pressure * sensor temperature reading. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest arterial pressure sensor temperature reading *************************************************************************/ S16 getPBATemperature( void ) { return fpgaSensorReadings.PBATemperature; } /*********************************************************************//** * @brief * The getPBAReadCounter function gets the latest arterial * pressure sensor read counter. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest arterial pressure sensor read counter *************************************************************************/ U08 getPBAReadCounter( void ) { return fpgaSensorReadings.PBAReadCount; } /*********************************************************************//** * @brief * The getPBAErrorCounter function gets the latest arterial * pressure sensor error counter. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest arterial pressure sensor error counter *************************************************************************/ U08 getPBAErrorCounter( void ) { return fpgaSensorReadings.PBAErrorCount; } /*********************************************************************//** * @brief * The getPBOPressure function gets the latest venous pressure reading. * The high 2 bits are status bits: 00=ok, 01=cmd mode, 10=stale data, 11=diag * The low 14 bits are data. Zero is at 1638. Values above are positive, * below are negative. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest venous pressure reading *************************************************************************/ U16 getPBOPressure( void ) { return fpgaSensorReadings.PBoPressure; } /*********************************************************************//** * @brief * The getPBOTemperature function gets the latest venous pressure * sensor temperature reading. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest venous pressure sensor temperature reading *************************************************************************/ S16 getPBOTemperature( void ) { return fpgaSensorReadings.PBoTemperature; } /*********************************************************************//** * @brief * The getPBOReadCounter function gets the latest venous pressure * sensor read counter. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest venous pressure sensor read counter *************************************************************************/ U08 getPBOReadCounter( void ) { return fpgaSensorReadings.PBoReadCount; } /*********************************************************************//** * @brief * The getPBOErrorCounter function gets the latest venous pressure * sensor error counter. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest venous pressure sensor error counter *************************************************************************/ U08 getPBOErrorCounter( void ) { return fpgaSensorReadings.PBoErrorCount; } /*********************************************************************//** * @brief * The getFPGABackupAlarmAudioCurrent function gets the latest piezo alarm * audio current reading. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return Latest piezo alarm audio current reading *************************************************************************/ F32 getFPGABackupAlarmAudioCurrent( void ) { U16 adcCnts = fpgaSensorReadings.alarmBuzzerCurrentAdc; F32 result = ( ( (F32)adcCnts / (F32)BITS_12_FULL_SCALE ) * FPGA_BACKUP_ALARM_AUDIO_CONVERT ) * (F32)MA_PER_AMP; return result; } /*********************************************************************//** * @brief * The getFPGAAirTrapLevels function gets the latest air trap level sensor * readings. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return none *************************************************************************/ void getFPGAAirTrapLevels( BOOL *airAtLower, BOOL *airAtUpper ) { U16 fpgaGPIO = fpgaSensorReadings.GPIOReg; U16 lower = fpgaGPIO & FPGA_AIRTRAP_LEVEL_LOW_MASK; U16 upper = fpgaGPIO & FPGA_AIRTRAP_LEVEL_HIGH_MASK; *airAtLower = ( 0 == lower ? FALSE : TRUE ); *airAtUpper = ( 0 == upper ? FALSE : TRUE ); } /*********************************************************************//** * @brief * The setFPGAValvesControlMode function sets the valves control mode. * @note VBTControl register bit 0 will drive state of VBT valve (0=closed, 1=open). * @details \b Inputs: fpgaActuatorSetPoints * @details \b Outputs: fpgaActuatorSetPoints * @param bits : The bits to enable the PID controller of a valve * @return none *************************************************************************/ void setVBTValveState( OPN_CLS_STATE_T state ) { if ( STATE_OPEN == state ) { fpgaActuatorSetPoints.VBTControl |= FPGA_VBT_OPEN_BIT_MASK; } else { fpgaActuatorSetPoints.VBTControl &= ~((U08)FPGA_VBT_OPEN_BIT_MASK); } } /*********************************************************************//** * @brief * The ADVBubbleDetected function determines whether ADV bubble detector * sensor is currently detecting a bubble. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return TRUE if latest ADV reading shows bubble detected, FALSE if not *************************************************************************/ BOOL ADVBubbleDetected( void ) { U16 noBubbleDetected = 0; noBubbleDetected = fpgaSensorReadings.GPIOReg & FPGA_ADV_BUBBLE_STATUS_MASK; return ( 0 == noBubbleDetected ? TRUE : FALSE ); } /*********************************************************************//** * @brief * The setFPGAVenousBubbleSelfTest function sets the given air bubble detector into * self-test mode via the FPGA. * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @return: none *************************************************************************/ void setFPGAVenousBubbleSelfTest( void ) { fpgaActuatorSetPoints.sensorTest |= FPGA_ADV_BUBBLE_SELF_TEST_CMD; } /*********************************************************************//** * @brief * The clearFPGAVenousBubbleSelfTest function clears the given air bubble detector * from self-test mode via the FPGA. * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @return: none *************************************************************************/ void clearFPGAVenousBubbleSelfTest( void ) { fpgaActuatorSetPoints.sensorTest &= ~FPGA_ADV_BUBBLE_SELF_TEST_CMD; } /*********************************************************************//** * @brief * The setVBAControl function sets the control bits for the venous pinch valve. * Microstep setting: bits 0..2: * 0=full step (100% torque) * 1=1/2 step (100% torque) * 2=1/16 step * 3=1/32 step * 4=full step (modified) * 5=1/2 step (modified) * 6=1/4 step * 7=1/8 step * Direction: bit 3 * 0=forward * 1=reverse * Enable: bit 4 (active low) * 0=enabled * 1=disabled * Reset: bit 5 (active low) * 0=reset (set to 1 after power up) * Sleep: bit 6 (active low) * 0=sleep mode * Reserved: bit 7 * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param controlBits The control bits to apply to the venous pinch valve. * @return none *************************************************************************/ void setVBVControl( U08 controlBits ) { } /*********************************************************************//** * @brief * The getVBVControl function gets the current control bits for the VBV. * @details \b Inputs: fpgaActuatorSetPoints * @details \b Outputs: none * @return fpgaActuatorSetPoints.VBVControl *************************************************************************/ U08 getVBVControl( void ) { return fpgaActuatorSetPoints.VBVControl; } /*********************************************************************//** * @brief * The setVBVPosition function sets the travel from current position for the * VBV in counts (or microcounts if microstepping is set in control register). * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param setPoint The target encoder position of the VBV in counts * @return none *************************************************************************/ void setVBVPosition( U16 setPoint ) { fpgaActuatorSetPoints.VBVPosition = setPoint; } /*********************************************************************//** * @brief * The getVBVEncoderPosition function reads the current encoder position of the * VBV in counts. * @note There are 1024 encoder counts per revolution. The encoder position * register provides the number of steps traveled since last command given. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The current encoder position of VBV *************************************************************************/ S16 getVBVEncoderPosition( void ) { return fpgaSensorReadings.VBVEncPosition; } /*********************************************************************//** * @brief * The getVBVCmdPosition function returns the current amount of travel * from the pre-command position in steps (or microsteps if microstepping is * set in control register) for VBV. * @note There are 200 steps per revolution * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The commanded encoder position of VBV *************************************************************************/ S16 getVBVCmdPosition( void ) { return fpgaSensorReadings.VBVCmdPosition; } /*********************************************************************//** * @brief * The getVBVStatus function reads the status of the venous pinch valve. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return Latest status of the venous pinch valve *************************************************************************/ U16 getVBVStatus( void ) { return fpgaSensorReadings.VBVStatus; } /*********************************************************************//** * @brief * The setVBAControl function sets the control bits for the arterial pinch valve. * Microstep setting: bits 0..2: * 0=full step (100% torque) * 1=1/2 step (100% torque) * 2=1/16 step * 3=1/32 step * 4=full step (modified) * 5=1/2 step (modified) * 6=1/4 step * 7=1/8 step * Direction: bit 3 * 0=forward * 1=reverse * Enable: bit 4 (active low) * 0=enabled * 1=disabled * Reset: bit 5 (active low) * 0=reset (set to 1 after power up) * Sleep: bit 6 (active low) * 0=sleep mode * Reserved: bit 7 * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param controlBits The control bits to apply to the arterial pinch valve. * @return none *************************************************************************/ void setVBAControl( U08 controlBits ) { fpgaActuatorSetPoints.VBAControl = controlBits; } /*********************************************************************//** * @brief * The getVBAControl function gets the current control bits for the VBA. * @details \b Inputs: fpgaActuatorSetPoints * @details \b Outputs: none * @return fpgaActuatorSetPoints.VBAControl *************************************************************************/ U08 getVBAControl( void ) { return fpgaActuatorSetPoints.VBAControl; } /*********************************************************************//** * @brief * The setVBAPosition function sets the travel from current position for the * VBA in counts (or microcounts if microstepping is set in control register). * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param setPoint The target encoder position of the VBA in counts * @return none *************************************************************************/ void setVBAPosition( U16 setPoint ) { fpgaActuatorSetPoints.VBAPosition = setPoint; } /*********************************************************************//** * @brief * The getVBAEncoderPosition function reads the current encoder position of the * VBA in counts. * @note There are 1024 encoder counts per revolution * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest encoder position of VBA *************************************************************************/ S16 getVBAEncoderPosition( void ) { return fpgaSensorReadings.VBAEncPosition; } /*********************************************************************//** * @brief * The getVBACmdPosition function returns returns the current amount of travel * from the pre-command position in steps (or microsteps if microstepping is * set in control register) for VBA. * @note There are 200 steps per revolution * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The commanded encoder position of VBA *************************************************************************/ S16 getVBACmdPosition( void ) { return fpgaSensorReadings.VBACmdPosition; } /*********************************************************************//** * @brief * The getVBAStatus function reads the status of the arterial pinch valve. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return Latest status of the arterial pinch valve *************************************************************************/ U16 getVBAStatus( void ) { return fpgaSensorReadings.VBAStatus; } /*********************************************************************//** * @brief * The getFPGABoardTemperature function reads the FPGA board temperature. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest FPGA board temperature in ADC counts *************************************************************************/ U16 getFPGABoardTemperature( void ) { return fpgaSensorReadings.fpgaAdcTemperature; } /*********************************************************************//** * The getFPGAFrontDoorStatus function returns the FPGA front door status * bit (0x10). * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return TRUE if front door is closed, FALSE if not. *************************************************************************/ BOOL getFPGAFrontDoorClosedStatus( void ) { BOOL result = TRUE; if ( ( fpgaSensorReadings.GPIOReg & FRONT_DOOR_SWITCH_MASK ) != 0 ) { result = FALSE; } return result; } /*********************************************************************//** * @brief * The getFPGAPBAADCTemperature function returns the PBA ADC temperature. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest PBA temperature in ADC counts *************************************************************************/ U32 getFPGAPBAADCTemperature( void ) { return fpgaSensorReadings.PBATemperature; } /*********************************************************************//** * @brief * The getFPGAInletFan1TogglePeriod function returns the inlet fan 1 pulse time. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest inlet fan 1 pulse time (in 2.5 uSec) *************************************************************************/ U16 getFPGAInletFan1TogglePeriod( void ) { return 0;//fpgaSensorReadings.fan1PulseTime; } /*********************************************************************//** * @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. * @details \b Alarm: ALARM_ID_TD_FPGA_COMM_TIMEOUT if 3 comm failures in last 1 minute. * @details \b Inputs: Millisecond counter * @details \b Outputs: none * @return none *************************************************************************/ void checkFPGACommFailure( void ) { if ( getMSTimerCount() > MIN_POWER_ON_TIME_FOR_COMM_FAILS ) { if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_COMM_FAILURES ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_FPGA_COMM_TIMEOUT, MAX_FPGA_COMM_FAILURES, (U32)fpgaSensorReadings.errorCountProcessor ) } } } /*********************************************************************//** * @brief * The checkFPGAFEOEFailure function increments the FPGA comm failure * windowed timer if an FE or OE error has occurred and returns whether * or not the number of failures in * the window have been reached. * @details \b Alarm: ALARM_ID_TD_FPGA_COMM_TIMEOUT if 3 comm failures in last 1 minute. * @details \b Inputs: Millisecond timer * @details \b Outputs: none * @return none *************************************************************************/ void checkFPGAFEOEFailure( void ) { BOOL FPGAFEOEError = getSci2FEOEError(); if ( TRUE == FPGAFEOEError) { if ( getMSTimerCount() > MIN_POWER_ON_TIME_FOR_COMM_FAILS ) { if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_COMM_FAILURES ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_FPGA_COMM_TIMEOUT, MAX_FPGA_COMM_FAILURES, (U32)fpgaSensorReadings.errorCountProcessor ) } } } } /**@}*/