/************************************************************************** * * 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_PINCH_VALVES_STOPPED 0x00 ///< FPGA pinch valve control register setting to stop valve motors. #define FPGA_VBV_CLOSED_LOOP 0x01 ///< Bit mask for running VBV motor in closed loop mode. #define FPGA_VBA_CLOSED_LOOP 0x02 ///< Bit mask for running VBA motor in closed loop mode. #define FPGA_VBV_OPEN_LOOP 0x04 ///< Bit mask for running VBV motor in open loop mode. #define FPGA_VBA_OPEN_LOOP 0x80 ///< Bit mask for running VBA motor in open loop mode. //#define FPGA_VALVES_MIN_PWM_MODE_COUNT 2500 ///< FPGA valves minimum PWM in PWM mode in counts. #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. #define FPGA_PBO_TEMP_DIVISOR 2047.0F ///< Used in conversion of PBo temperature reading to deg C. #define FPGA_PBO_TEMP_GAIN 200.0F ///< Used in conversion of PBo temperature reading to deg C. #define FPGA_PBO_TEMP_OFFSET 50.0F ///< Used in conversion of PBo temperature reading to deg C. // 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. S32 PBoPressure; ///< Reg 266. PBo raw pressure data. S32 PBoTemperature; ///< Reg 270. PBo raw temperature data. U08 PBoReadCount; ///< Reg 274. PBo read count. U08 PBoErrorCount; ///< Reg 275. PBo error count. S32 PBAPressure; ///< Reg 276. PBA raw pressure data. S32 PBATemperature; ///< Reg 280. PBA raw temperature data. U08 PBAReadCount; ///< Reg 284. PBA read count. U08 PBAErrorCount; ///< Reg 285. PBA error count. S16 ATAPSpeed; ///< Reg 286. ATAP speed. 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. S16 BPTorque; ///< Reg 296. BP measured torque. S16 BPSpeedFromHall; ///< Reg 298. BP measured speed from hall sensor(s). S16 VBVPosition; ///< Reg 300. VBV encoder position. U08 VBVStatus; ///< Reg 302. VBV status register. U08 VBAStatus; ///< Reg 303. VBA status register. S16 VBAPosition; ///< Reg 304. VBA encoder position. 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. } 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 ATAPSetSpeed; ///< Reg 16. Air pump speed 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. U08 BPControl; ///< Reg 24. Blood pump control register. U08 pinchValveControl; ///< Reg 25. Pinch valve control register (VBA and VBV). S16 VBVPosition; ///< Reg 26. VBV position set register. S16 VBAPosition; ///< Reg 28. VBA position set register. U16 VBVStepSpeed; ///< Reg 30. VBV step speed set register. U16 VBAStepSpeed; ///< Reg 32. VBA step speed set register. U08 alarmControl; ///< Reg 34. Alarm audio register. U08 reserved3; ///< Reg 35. Reserved. U32 reserved4; ///< Reg 36. Reserved. U32 reserved5; ///< Reg 40. 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 be "stopped". // the valves will not move to 0 position fpgaActuatorSetPoints.pinchValveControl = FPGA_PINCH_VALVES_STOPPED; // 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 getFPGABloodPumpHallSensorCount 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 getFPGABloodPumpHallSensorCount( void ) { return 0;//fpgaSensorReadings.bloodPumpHallSensorCount; } /*********************************************************************//** * @brief * The getFPGABloodPumpHallSensorStatus 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 getFPGABloodPumpHallSensorStatus( void ) { return 0;//fpgaSensorReadings.bloodPumpHallSensorStatus; } /*********************************************************************//** * @brief * The getPBAPressure function gets the latest arterial pressure reading. * High byte indicates alarm status for ADC channel. * @note Low 24-bits are channel reading. Subtract 2^23 from low 24 bits to get * signed channel reading. * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return latest arterial pressure reading *************************************************************************/ S32 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 *************************************************************************/ S32 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 *************************************************************************/ S32 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 *************************************************************************/ S32 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. * @details \b Inputs: fpgaActuatorSetPoints * @details \b Outputs: fpgaActuatorSetPoints * @param bits : The bits to enable the PID controller of a valve * @return none *************************************************************************/ void setFPGAValvesControlMode( U16 bits ) { //fpgaActuatorSetPoints.fpgaPIDControl = bits; } /*********************************************************************//** * @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 setVBVPosition function sets the target encoder position of VBV * in counts * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param setPoint The target encoder position of the VBV in counts * @return none *************************************************************************/ void setVBVPosition( S16 setPoint ) { fpgaActuatorSetPoints.VBVPosition = setPoint; } /*********************************************************************//** * @brief * The getVBVPosition function returns the current encoder position of * VBV in counts * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The current encoder position of VBV *************************************************************************/ S16 getVBVPosition( void ) { return fpgaSensorReadings.VBVPosition; } /*********************************************************************//** * @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 getFPGAValveBloodVenousCurrentCounts function returns the current * of VBV in counts * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest current of VBV *************************************************************************/ U16 getFPGAValveBloodVenousCurrentCounts( void ) { return 0;//fpgaSensorReadings.VBVCurrent; } /*********************************************************************//** * @brief * The setVBAPosition function sets the target encoder position of the VBA * in counts * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints * @param setPoint The target encoder position of the VBA in counts * @return none *************************************************************************/ void setVBAPosition( S16 setPoint ) { fpgaActuatorSetPoints.VBAPosition = setPoint; } /*********************************************************************//** * @brief * The getVBAPosition function reads the current encoder position of the * VBA in counts * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest encoder position of VBA *************************************************************************/ S16 getVBAPosition( void ) { return fpgaSensorReadings.VBAPosition; } /*********************************************************************//** * @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 getFPGAValveBloodArterialCurrentCounts function reads the current * of VBA in counts * @details \b Inputs: fpgaSensorReadings * @details \b Outputs: none * @return The latest current of VBA *************************************************************************/ U16 getFPGAValveBloodArterialCurrentCounts( void ) { return 0;//fpgaSensorReadings.; } /*********************************************************************//** * @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 ) } } } } /**@}*/