Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r3d667b0820cfb0a8d1dbc96f4ca205da77c3ff03 -r44a100f8e5210a02c23b8fcc4527d8e96d577381 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 3d667b0820cfb0a8d1dbc96f4ca205da77c3ff03) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) @@ -20,8 +20,9 @@ #include "sci.h" #include "sys_dma.h" -#include "FPGA.h" #include "Comm.h" +#include "Compatible.h" +#include "FPGA.h" #include "SystemCommMessages.h" #include "Utilities.h" @@ -82,15 +83,23 @@ #define FPGA_AIRTRAP_LEVEL_HIGH_MASK 0x0004 ///< Bit mask for air trap upper level sensor. #define FPGA_FLUID_LEAK_STATE_MASK 0x0040 ///< Bit mask for fluid leak detector. + #define FPGA_BLOOD_LEAK_STATUS_MASK 0x1000 ///< Bit mask for blood leak detector. #define FPGA_BLOOD_LEAK_ZERO_STATE_MASK 0x2000 ///< Bit mask for blood leak detector zero. - #define FPGA_BLOOD_LEAK_ZERO_CMD 0x02 ///< Bit for blood leak detector zero command. #define FPGA_BLOOD_LEAK_SELF_TEST_CMD 0x01 ///< Bit for blood leak detector self test command. -#define FPGA_ADA_INPUT_STATUS_MASK 0x0001 ///< Bit mask for arterial air bubble detector input status. -#define FPGA_ADV_INPUT_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. +#define FPGA_ADA_BUBBLE_STATUS_MASK 0x0001 ///< Bit mask for arterial air bubble detector input status. +#define FPGA_ADV_BUBBLE_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. +#define FPGA_ADA_BUBBLE_SELF_TEST_CMD 0x04 ///< Bit for arterial air bubble detector self-test command. +#define FPGA_ADV_BUBBLE_SELF_TEST_CMD 0x08 ///< Bit for venous air bubble detector self-test command. +#define FPGA_PBO_TEMP_DIVISOR 2047.0 ///< Used in conversion of PBo temperature reading to deg C. +#define FPGA_PBO_TEMP_GAIN 200.0 ///< Used in conversion of PBo temperature reading to deg C. +#define FPGA_PBO_TEMP_OFFSET 50.0 ///< Used in conversion of PBo temperature reading to deg C. + +#define FPGA_ALARM_AUDIO_VOLUME_SHIFT 3 ///< Shift alarm audio volume 3 bits to left before writing to register. + // FPGA Sensors Record #pragma pack(push,1) /// Record structure for FPGA header read. @@ -525,9 +534,14 @@ } // If retries for commands exceeds limit, fault - if ( fpgaCommRetryCount > MAX_COMM_ERROR_RETRIES ) + if ( ( fpgaCommRetryCount > MAX_COMM_ERROR_RETRIES ) +#ifdef _RELEASE_ + || ( fpgaSensorReadings.errorCountProcessor > MAX_COMM_ERROR_RETRIES ) ) +#else + ) +#endif { - activateAlarmNoData( ALARM_ID_HD_FPGA_COMM_TIMEOUT ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_COMM_TIMEOUT, fpgaCommRetryCount, (U32)fpgaSensorReadings.errorCountProcessor ) } // Reset comm flags after processing incoming responses @@ -866,7 +880,23 @@ // Check FPGA reported correct ID if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) { - result = SELF_TEST_STATUS_PASSED; + // Check FPGA compatibility w/ firmware + if ( fpgaHeader.fpgaRevMajor > MIN_HD_FPGA_MAJOR ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + if ( ( MIN_HD_FPGA_MAJOR == fpgaHeader.fpgaRevMajor ) && ( fpgaHeader.fpgaRev >= MIN_HD_FPGA_MINOR ) ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_POST_TEST_FAILED, (U32)fpgaHeader.fpgaRevMajor, (U32)fpgaHeader.fpgaRev ) + } + } } else { @@ -1071,6 +1101,7 @@ * 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..4) * 4 - 3 dB gain * 3 - 6 dB gain @@ -1079,25 +1110,24 @@ * 0 - 15 dB gain * @return none *************************************************************************/ -void setAlarmAudioState( ALARM_PRIORITY_T state, U32 volumeLevel ) +void setAlarmAudioState( U32 state, U32 volumeLevel ) { - if ( ( state < NUM_OF_ALARM_PRIORITIES ) && ( volumeLevel <= MAX_ALARM_VOLUME_ATTENUATION ) ) - { - U08 audioCmd = (U08)state; + U08 audioCmd = (U08)state; - audioCmd |= ( (U08)volumeLevel << 2 ); + audioCmd |= ( (U08)volumeLevel << FPGA_ALARM_AUDIO_VOLUME_SHIFT ); + + if ( ( state <= NUM_OF_ALARM_PRIORITIES ) && ( volumeLevel <= MAX_ALARM_VOLUME_ATTENUATION ) ) + { fpgaActuatorSetPoints.alarmControl = audioCmd; } else { - U08 audioCmd = (U08)ALARM_PRIORITY_HIGH; - + // S/w fault to indicate issue w/ s/w + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_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)MIN_ALARM_VOLUME_ATTENUATION << 2 ); + audioCmd = (U08)ALARM_PRIORITY_HIGH; + audioCmd |= ( (U08)MIN_ALARM_VOLUME_ATTENUATION << FPGA_ALARM_AUDIO_VOLUME_SHIFT ); fpgaActuatorSetPoints.alarmControl = audioCmd; - // S/w fault to indicate issue w/ s/w - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_INVALID_ALARM_AUDIO_PARAM, volumeLevel ) - } } @@ -1141,30 +1171,82 @@ /*********************************************************************//** * @brief - * The getFPGADialysateFlow function gets the latest dialysate flow reading. + * The getFPGABloodFlowMeterStatus function gets the blood flow meter status. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return last dialysate flow reading + * @return current blood flow meter status *************************************************************************/ -F32 getFPGADialysateFlow( void ) +U08 getFPGABloodFlowMeterStatus( void ) { - return fpgaSensorReadings.dialysateFlowLast; + return fpgaSensorReadings.bloodFlowMeterDeviceStatus; } /*********************************************************************//** * @brief - * The getFPGABloodFlowMeterStatus function gets the blood flow meter status. + * The getFPGABloodFlowFastPacketReadCounter function gets the blood + * flow meter fast packet read counter. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return current blood flow meter status + * @return current blood flow meter fast packet read counter *************************************************************************/ -U08 getFPGABloodFlowMeterStatus( void ) +U08 getFPGABloodFlowFastPacketReadCounter( void ) { - return fpgaSensorReadings.bloodFlowMeterDeviceStatus; + return fpgaSensorReadings.bloodFlowMeterDataPktCount; } /*********************************************************************//** * @brief + * The getFPGABloodFlowSlowPacketReadCounter function gets the blood + * flow meter slow packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter slow packet read counter + *************************************************************************/ +U08 getFPGABloodFlowSlowPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.bloodFlowMeterSlowPktCounts & MASK_OFF_NIBBLE_LSB ) >> SHIFT_BITS_BY_4; +} + +/*********************************************************************//** + * @brief + * The getFPGABloodFlowStatusPacketReadCounter function gets the blood + * flow meter status packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter status packet read counter + *************************************************************************/ +U08 getFPGABloodFlowStatusPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.bloodFlowMeterSlowPktCounts & MASK_OFF_NIBBLE_MSB ); +} + +/*********************************************************************//** + * @brief + * The getFPGABloodFlowErrorCounter function gets the blood flow meter + * error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter error counter + *************************************************************************/ +U08 getFPGABloodFlowErrorCounter( void ) +{ + return fpgaSensorReadings.bloodFlowMeterErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlow function gets the latest dialysate flow reading. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate flow reading + *************************************************************************/ +F32 getFPGADialysateFlow( void ) +{ + return fpgaSensorReadings.dialysateFlowLast; +} + +/*********************************************************************//** + * @brief * The getFPGADialysateFlowMeterStatus function gets the dialysate flow meter status. * @details Inputs: fpgaSensorReadings * @details Outputs: none @@ -1177,6 +1259,58 @@ /*********************************************************************//** * @brief + * The getFPGADialysateFlowFastPacketReadCounter function gets the dialysate + * flow meter fast packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter fast packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowFastPacketReadCounter( void ) +{ + return fpgaSensorReadings.dialysateFlowMeterDataPktCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowSlowPacketReadCounter function gets the dialysate + * flow meter slow packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter slow packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowSlowPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.dialysateFlowMeterSlowPckCounts & MASK_OFF_NIBBLE_LSB ) >> SHIFT_BITS_BY_4; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowStatusPacketReadCounter function gets the dialysate + * flow meter status packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter status packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowStatusPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.dialysateFlowMeterSlowPckCounts & MASK_OFF_NIBBLE_MSB ); +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowErrorCounter function gets the dialysate flow meter + * error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter error counter + *************************************************************************/ +U08 getFPGADialysateFlowErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateFlowMeterErrorCount; +} + +/*********************************************************************//** + * @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 @@ -1195,9 +1329,9 @@ * @brief * The getFPGABloodPumpHallSensorStatus function gets the latest blood pump * hall sensor status. - * Bit 0 - Derived direction of the blood pump motor (0=Fwd, 1=Rev) - * Bit 1 - A direction error was detected in the current hall sensor phase - * Bit 2 - A direction error was detected since the last read of this register + * 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 Inputs: fpgaSensorReadings * @details Outputs: none * @return last blood pump hall sensor status reading. @@ -1227,9 +1361,9 @@ * @brief * The getFPGADialInPumpHallSensorStatus function gets the latest dialysate inlet pump * hall sensor status. - * Bit 0 - Derived direction of the dialyste inlet pump motor (0=Fwd, 1=Rev) - * Bit 1 - A direction error was detected in the current hall sensor phase - * Bit 2 - A direction error was detected since the last read of this register + * Bit 7 - Derived direction of the dialysate inlet pump motor (0=Fwd, 1=Rev) + * Bit 6 - Unused + * Bit 5-0 - Direction error count since power-up (rolls over) * @details Inputs: fpgaSensorReadings * @details Outputs: none * @return last dialysate inlet pump hall sensor status reading. @@ -1259,9 +1393,9 @@ * @brief * The getFPGADialOutPumpHallSensorStatus function gets the latest dialysate outlet pump * hall sensor status. - * Bit 0 - Derived direction of the dialysate outlet pump motor (0=Fwd, 1=Rev) - * Bit 1 - A direction error was detected in the current hall sensor phase - * Bit 2 - A direction error was detected since the last read of this register + * Bit 7 - Derived direction of the dialysate outlet pump motor (0=Fwd, 1=Rev) + * Bit 6 - Unused + * Bit 5-0 - Direction error count since power-up (rolls over) * @details Inputs: fpgaSensorReadings * @details Outputs: none * @return last dialysate outlet pump hall sensor status reading. @@ -1311,6 +1445,84 @@ /*********************************************************************//** * @brief + * The getFPGABloodPumpOcclusionReadCounter function gets the latest blood + * pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last blood pump occlusion read counter + *************************************************************************/ +U08 getFPGABloodPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.bloodOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpOcclusionReadCounter function gets the latest dialysate + * inlet pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate inlet pump occlusion read counter + *************************************************************************/ +U08 getFPGADialInPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.dialysateInOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpOcclusionReadCounter function gets the latest dialysate + * outlet pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate outlet pump occlusion read counter + *************************************************************************/ +U08 getFPGADialOutPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.dialysateOutOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGABloodPumpOcclusionErrorCounter function gets the latest blood + * pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last blood pump occlusion error counter + *************************************************************************/ +U08 getFPGABloodPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.bloodOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpOcclusionErrorCounter function gets the latest dialysate + * inlet pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate inlet pump occlusion error counter + *************************************************************************/ +U08 getFPGADialInPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateInOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpOcclusionErrorCounter function gets the latest dialysate + * outlet pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate outlet pump occlusion error counter + *************************************************************************/ +U08 getFPGADialOutPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateOutOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief * The getFPGAArterialPressure function gets the latest arterial pressure reading. * High byte indicates alarm status for ADC channel. * Low 24-bits are channel reading. Subtract 2^23 from low 24 bits to get @@ -1326,7 +1538,7 @@ /*********************************************************************//** * @brief - * The getFPGAVenousPressure function gets the venous arterial pressure reading. + * The getFPGAVenousPressure 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. @@ -1341,6 +1553,34 @@ /*********************************************************************//** * @brief + * The getFPGAVenousPressureTemperature function gets the latest venous pressure + * sensor temperature reading. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last venous pressure sensor temperature reading + *************************************************************************/ +F32 getFPGAVenousPressureTemperature( void ) +{ + F32 result = ( (F32)fpgaSensorReadings.venousTemperature / FPGA_PBO_TEMP_DIVISOR ) * FPGA_PBO_TEMP_GAIN - FPGA_PBO_TEMP_OFFSET; + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAVenousPressureReadCounter function gets the latest venous pressure + * sensor read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last venous pressure sensor read counter + *************************************************************************/ +U08 getFPGAVenousPressureReadCounter( void ) +{ + return fpgaSensorReadings.venousReadCounter; +} + +/*********************************************************************//** + * @brief * The setFPGASyringePumpControlFlags function sets the syringe pump control * register per given bit flags. * @details Inputs: none @@ -1602,36 +1842,6 @@ /*********************************************************************//** * @brief - * The getFPGAArterialAirBubbleStatus function gets the latest arterial air - * bubble detector status. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return TRUE if air bubble is detected, otherwise FALSE - *************************************************************************/ -BOOL getFPGAArterialAirBubbleStatus( void ) -{ - U16 const status = fpgaSensorReadings.fpgaGPIO & FPGA_ADA_INPUT_STATUS_MASK; - - return ( 0 == status ? TRUE : FALSE ); -} - -/*********************************************************************//** - * @brief - * The getFPGAVenousAirBubbleStatus function gets the latest venous air - * bubble detector status. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return TRUE if air bubble is detected, otherwise FALSE - *************************************************************************/ -BOOL getFPGAVenousAirBubbleStatus( void ) -{ - U16 const status = fpgaSensorReadings.fpgaGPIO & FPGA_ADV_INPUT_STATUS_MASK; - - return ( 0 == status ? FALSE : TRUE ); -} - -/*********************************************************************//** - * @brief * The getDoorState function gets the current state of door switch. * @details Inputs: none * @details Outputs: none @@ -1719,9 +1929,9 @@ * @brief * The setFPGABloodLeakZero function sets the Blood Leak detector into * zeroing mode via the FPGA. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return FPGABloodLeakZeroDetected + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints + * @return none *************************************************************************/ void setFPGABloodLeakZero( void ) { @@ -1745,9 +1955,9 @@ * @brief * The setFPGABloodLeakSelfTest function sets the Blood Leak detector into * self-test mode via the FPGA. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return FPGABloodLeakZeroDetected + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints + * @return: none *************************************************************************/ void setFPGABloodLeakSelfTest( void ) { @@ -1769,6 +1979,78 @@ /*********************************************************************//** * @brief + * The noFPGABubbleDetected function returns TRUE if no air bubble has been + * detected and FALSE if an air bubble has been detected. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return noFPGABubbleDetected + *************************************************************************/ +BOOL noFPGABubbleDetected( U32 bubble ) +{ + U16 noFPGABubbleDetected = 0; + + if ( bubble == ADA ) + { + noFPGABubbleDetected = fpgaSensorReadings.fpgaGPIO & FPGA_ADA_BUBBLE_STATUS_MASK; + } + else if ( bubble == ADV ) + { + noFPGABubbleDetected = fpgaSensorReadings.fpgaGPIO & FPGA_ADV_BUBBLE_STATUS_MASK; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_ID, bubble ) + } + + return ( 0 != noFPGABubbleDetected ? TRUE : FALSE ); +} + +/*********************************************************************//** + * @brief + * The setFPGABubbleSelfTest function sets the given air bubble detector into + * self-test mode via the FPGA. + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints + * @return: none + *************************************************************************/ +void setFPGABubbleSelfTest( U32 bubble ) +{ + if ( bubble == ADA ) + { + fpgaActuatorSetPoints.fpgaSensorTest |= FPGA_ADA_BUBBLE_SELF_TEST_CMD; + } + else if ( bubble == ADV ) + { + fpgaActuatorSetPoints.fpgaSensorTest |= FPGA_ADV_BUBBLE_SELF_TEST_CMD; + } +} + +/*********************************************************************//** + * @brief + * The clearFPGABubbleSelfTest function clears the given air bubble detector + * from self-test mode via the FPGA. + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints + * @return: none + *************************************************************************/ +void clearFPGABubbleSelfTest( U32 bubble ) +{ + if ( bubble == ADA ) + { + fpgaActuatorSetPoints.fpgaSensorTest &= ~FPGA_ADA_BUBBLE_SELF_TEST_CMD; + } + else if ( bubble == ADV ) + { + fpgaActuatorSetPoints.fpgaSensorTest &= ~FPGA_ADV_BUBBLE_SELF_TEST_CMD; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BUBBLE_ID, bubble ) + } +} + +/*********************************************************************//** + * @brief * The setValveDialyzerInletPosition function sets the position of VDi * in counts * @details Inputs: fpgaActuatorSetPoints