Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rfbb180e9b4830dd5f890f4f33f022ce375ff4012 -r38b5b0408730290c3ad591711ba1613e85045cd5 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision fbb180e9b4830dd5f890f4f33f022ce375ff4012) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 38b5b0408730290c3ad591711ba1613e85045cd5) @@ -23,8 +23,10 @@ #include "Comm.h" #include "Compatible.h" #include "FPGA.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" +#include "Timers.h" #include "Utilities.h" /** @@ -78,6 +80,9 @@ #define MAX_COMM_ERROR_RETRIES 5 ///< Maximum consecutive FPGA communication error retries. +#define FPGA_INPUT_VOLTAGE_SCALE 3.0 ///< FPGA source and aux voltage. +#define FPGA_PVN_VOLTAGE_SCALE 1.0 ///< FPGA pvn voltage. + #define FPGA_ADC1_AUTO_READ_ENABLE 0x01 ///< Auto-read enable bit for ADC1 control register. #define FPGA_AIRTRAP_LEVEL_LOW_MASK 0x0008 ///< Bit mask for air trap lower level sensor. @@ -100,10 +105,14 @@ #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. +#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.4 ///< 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_BACKUP_ALARM_AUDIO_CONVERT 0.4 ///< Converts backup (piezo) alarm audio ADC volts to amps. +#define PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE 1 ///< Tolerance for processor clock speed check against FPGA clock. // FPGA Sensors Record #pragma pack(push,1) @@ -142,19 +151,19 @@ U16 bloodOcclusionData; ///< Reg 276. Blood pump occlusion sensor data. U08 bloodOcclusionReadCount; ///< Reg 278. Blood pump occlusion sensor read count. U08 bloodOcclusionErrorCount; ///< Reg 279. Blood pump occlusion sensor error count. - U16 dialysateInOcclusionData; ///< Reg 280. Dialysate inlet pump occlusion sensor data. - U08 dialysateInOcclusionReadCount; ///< Reg 282. Dialysate inlet pump occlusion sensor read count. - U08 dialysateInOcclusionErrorCount; ///< Reg 283. Dialysate inlet pump occlusion sensor error count. - U16 dialysateOutOcclusionData; ///< Reg 284. Dialysate outlet pump occlusion sensor data. - U08 dialysateOutOcclusionReadCount; ///< Reg 286. Dialysate outlet pump occlusion sensor read count. - U08 dialysateOutOcclusionErrorCount; ///< Reg 287. Dialysate outlet pump occlusion sensor error count. + U16 obsolete1; ///< Reg 280. Unused. + U08 obsolete2; ///< Reg 282. Unused. + U08 obsolete3; ///< Reg 283. Unused. + U16 obsolete4; ///< Reg 284. Unused. + U08 obsolete5; ///< Reg 286. Unused. + U08 obsolete6; ///< Reg 287. Unused. U16 bloodPumpHallSensorCount; ///< Reg 288. Blood pump hall sensor count. U08 bloodPumpHallSensorStatus; ///< Reg 290. Blood pump hall sensor status. U08 dialInPumpHallSensorStatus; ///< Reg 291. Dialysate inlet pump hall sensor status. U32 adc1Channel0; ///< Reg 292. ADC1 channel 0 data. U32 adc1Channel1; ///< Reg 296. ADC1 channel 1 data. U32 bloodFlowSoundSpeedData; ///< Reg 300. Blood flow sensor - sound speed data. - U32 bloodFlowAccFlowData; ///< Reg 304. Blood flow sensor - accumualted flow data. + U32 bloodFlowAccFlowData; ///< Reg 304. Blood flow sensor - accumulated flow data. F32 bloodFlowSignalStrength; ///< Reg 308. Blood flow sensor - signal strength. U08 adc1SequenceCount; ///< Reg 312. ADC1 round robin channel sequence count. U08 adc1ErrorCount; ///< Reg 313. ADC1 error count. @@ -173,7 +182,7 @@ U16 dialInPumpHallSensorCount; ///< Reg 336. Dialysate inlet pump hall sensor count. U16 dialOutPumpHallSensorCount; ///< Reg 338. Dialysate outlet pump hall sensor count. U32 dialysateFlowSoundSpeedData; ///< Reg 340. Dialysate flow sensor - sound speed data. - U32 dialysateFlowAccFlowData; ///< Reg 344. Dialysate flow sensor - accumualted flow data. + U32 dialysateFlowAccFlowData; ///< Reg 344. Dialysate flow sensor - accumulated flow data. F32 dialysateFlowSignalStrength; ///< Reg 348. Dialysate flow sensor - signal strength. U16 fan1PulseTime; ///< Reg 352. Fan 1 pulse time in 2.5 uSec resolution. 0xFFFF if fan RPM < 500 RPM. U16 fan2PUlseTime; ///< Reg 354. Fan 2 pulse time in 2.5 uSec resolution. 0xFFFF if fan RPM < 500 RPM. @@ -188,7 +197,7 @@ U16 VBVPWMTarget; ///< Reg 372. PWM target duty cycle for VBV pinch valve. U16 VDiPWMTarget; ///< Reg 374. PWM target duty cycle for VDi pinch valve. U16 VDoPWMTarget; ///< Reg 376. PWM target duty cycle for VDo pinch valve. - U16 VSparePWMTarget; ///< Reg 378. Internal FPGA Vcc Aux voltage. + U16 fpgaAuxVoltage; ///< Reg 378. Internal FPGA Vcc Aux voltage. 3V range over 12 bits (0..4095). U08 syringePumpStatus; ///< Reg 380. Syringe pump status register. U08 syringePumpADCReadCounter; ///< Reg 381. Syringe pump ADC read counter. U08 syringePumpADCandDACStatus; ///< Reg 382. Syringe pump ADC and DAC status register. @@ -203,11 +212,11 @@ U16 VBVCurrent; ///< Reg 400. VBV pinch valve current (Register VAUX2) U16 VDoCurrent; ///< Reg 402. VDo pinch valve current (Register VAUX3) U16 VBACurrent; ///< Reg 404. VBA pinch valve current (Register VAUX8) - U16 VDiSpeed; ///< Reg 406. VDi pinch valve current (Register VAUX9) + U16 VDiSpeed; ///< Reg 406. VDi pinch valve current (Register VAUX5) U16 VDoSpeed; ///< Reg 408. VDo pinch valve speed (Register VAUX10) - U16 VDiCurrent; ///< Reg 410. VDi pinch valve current (Register VAUX11) - U16 VSpareSpeed; ///< Reg 412. VSpare speed (Register VAUX5) - U16 VSpareCurrent; ///< Reg 414. VSpare current (Register VAUX13) + U16 VDiCurrent; ///< Reg 410. VDi pinch valve current (Register VAUX13) + U16 fpgaTemperature; ///< Reg 412. FPGA die temperature (deg C = counts x (503.975/4096) - 273.15). + U16 fpgaVpvn; ///< Reg 414. FPGA pvn voltage. 1V range over 12 bits (0..4095). U16 fpgaTimerCount_ms; ///< Reg 416. Free running 1ms timer counter. Rolls over at 65535.Internal FPGA timer count in ms. U16 backupAlarmAudioPeakCurrent; ///< Reg 418. Piezo alarm peak ADC current in previous 10ms. 12 bit unsigned. } FPGA_SENSORS_T; @@ -294,6 +303,9 @@ static FPGA_SENSORS_ASYNC_T fpgaSensorReadingsAsync; ///< Record of last received async (as needed) FPGA sensor data. #endif +static U16 currentFPGATimerCount_ms; ///< Current FPGA timer count in ms. +static U32 currentTimerCount_ms; ///< Current processor timer count in ms. + // ********** private function prototypes ********** static FPGA_STATE_T handleFPGAReadHeaderState( void ); @@ -919,6 +931,33 @@ /*********************************************************************//** * @brief + * The execFPGAClockSpeedTest function verifies the processor clock speed + * against the FPGA clock. + * @details Inputs: fpgaHeader + * @details Outputs: none + * @return passed, or failed + *************************************************************************/ +void execFPGAClockSpeedTest( void ) +{ + U16 const newFPGATimerCount_ms = getFPGATimerCount(); + U32 const newTimerCount_ms = getMSTimerCount(); + U32 const diffFPGATimerCount = (U32)u16DiffWithWrap( currentFPGATimerCount_ms, newFPGATimerCount_ms ); + U32 const diffTimerCount = u32DiffWithWrap( currentTimerCount_ms, newTimerCount_ms ); + + if ( getCurrentOperationMode() > MODE_INIT ) + { + if ( abs( diffFPGATimerCount - diffTimerCount ) > PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_FPGA_CLOCK_SPEED_CHECK_FAILURE, diffFPGATimerCount, diffTimerCount ); + } + } + + currentFPGATimerCount_ms = newFPGATimerCount_ms; + currentTimerCount_ms = newTimerCount_ms; +} + +/*********************************************************************//** + * @brief * The consumeUnexpectedData function checks to see if a byte is sitting in * the SCI2 received data register. * @details Inputs: fpgaHeader @@ -1114,29 +1153,89 @@ /*********************************************************************//** * @brief + * The getFPGATemperature function gets the fpga internal die temperature. + * @details Inputs: fpgaHeader + * @details Outputs: none + * @return current internal FPGA die temperature (in counts) + *************************************************************************/ +U16 getFPGATemperature( void ) +{ + return fpgaSensorReadings.fpgaTemperature; +} + +/*********************************************************************//** + * @brief + * The getFPGAVcc function gets the fpga input voltage. + * @details Inputs: fpgaHeader + * @details Outputs: none + * @return current FPGA input voltage (in volts) + *************************************************************************/ +F32 getFPGAVcc( void ) +{ + F32 result = (F32)fpgaSensorReadings.fpgaIntVoltage * FPGA_INPUT_VOLTAGE_SCALE / (F32)BITS_12_FULL_SCALE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAVccAux function gets the fpga aux. voltage. + * @details Inputs: fpgaHeader + * @details Outputs: none + * @return current FPGA aux. voltage (in volts) + *************************************************************************/ +F32 getFPGAVccAux( void ) +{ + F32 result = (F32)fpgaSensorReadings.fpgaAuxVoltage * FPGA_INPUT_VOLTAGE_SCALE / (F32)BITS_12_FULL_SCALE; + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAVpvn function gets the fpga pvn voltage. + * @details Inputs: fpgaHeader + * @details Outputs: none + * @return current FPGA pvn voltage (in volts) + *************************************************************************/ +F32 getFPGAVpvn( void ) +{ + F32 result = (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 Inputs: none * @details Outputs: alarm audio state and attenuation set - * @param state the state of alarm audio to command: + * @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..4) + * @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 ) +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 ) ) { @@ -1441,32 +1540,6 @@ /*********************************************************************//** * @brief - * The getFPGADialInPumpOcclusion function gets the latest dialysate - * inlet occlusion reading. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return last dialysate inlet occlusion reading - *************************************************************************/ -U16 getFPGADialInPumpOcclusion( void ) -{ - return fpgaSensorReadings.dialysateInOcclusionData; -} - -/*********************************************************************//** - * @brief - * The getFPGADialOutPumpOcclusion function gets the latest dialysate - * outlet occlusion reading. - * @details Inputs: fpgaSensorReadings - * @details Outputs: none - * @return last dialysate outlet occlusion reading - *************************************************************************/ -U16 getFPGADialOutPumpOcclusion( void ) -{ - return fpgaSensorReadings.dialysateOutOcclusionData; -} - -/*********************************************************************//** - * @brief * The getFPGABloodPumpOcclusionReadCounter function gets the latest blood * pump occlusion read counter. * @details Inputs: fpgaSensorReadings @@ -1480,32 +1553,6 @@ /*********************************************************************//** * @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 @@ -1519,43 +1566,43 @@ /*********************************************************************//** * @brief - * The getFPGADialInPumpOcclusionErrorCounter function gets the latest dialysate - * inlet pump occlusion error counter. + * 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 + * signed channel reading. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return last dialysate inlet pump occlusion error counter + * @return last arterial pressure reading *************************************************************************/ -U08 getFPGADialInPumpOcclusionErrorCounter( void ) +U32 getFPGAArterialPressure( void ) { - return fpgaSensorReadings.dialysateInOcclusionErrorCount; + return fpgaSensorReadings.adc1Channel0; } /*********************************************************************//** * @brief - * The getFPGADialOutPumpOcclusionErrorCounter function gets the latest dialysate - * outlet pump occlusion error counter. + * The getFPGAArterialPressureReadCounter function gets the latest arterial + * pressure sensor read counter. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return last dialysate outlet pump occlusion error counter + * @return last arterial pressure sensor read counter *************************************************************************/ -U08 getFPGADialOutPumpOcclusionErrorCounter( void ) +U08 getFPGAArterialPressureReadCounter( void ) { - return fpgaSensorReadings.dialysateOutOcclusionErrorCount; + return fpgaSensorReadings.adc1SequenceCount; } /*********************************************************************//** * @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 - * signed channel reading. + * The getFPGAArterialPressureErrorCounter function gets the latest arterial + * pressure sensor error counter. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return last arterial pressure reading + * @return last arterial pressure sensor error counter *************************************************************************/ -U32 getFPGAArterialPressure( void ) +U08 getFPGAArterialPressureErrorCounter( void ) { - return fpgaSensorReadings.adc1Channel0; + return fpgaSensorReadings.adc1ErrorCount; } /*********************************************************************//** @@ -1581,11 +1628,9 @@ * @details Outputs: none * @return last venous pressure sensor temperature reading *************************************************************************/ -F32 getFPGAVenousPressureTemperature( void ) +U16 getFPGAVenousPressureTemperature( void ) { - F32 result = ( (F32)fpgaSensorReadings.venousTemperature / FPGA_PBO_TEMP_DIVISOR ) * FPGA_PBO_TEMP_GAIN - FPGA_PBO_TEMP_OFFSET; - - return result; + return fpgaSensorReadings.venousTemperature; } /*********************************************************************//** @@ -2332,6 +2377,17 @@ /*********************************************************************//** * @brief + * The getFPGABoardTemperature function reads the FPGA board temperature. + * @details Inputs: none + * @details Outputs: fpgaSensorReadings + * @return Current FPGA board temperature + *************************************************************************/ +U16 getFPGABoardTemperature( void ) +{ + return fpgaSensorReadings.fpgaTemperature; +} + +/*********************************************************************//** * The getFPGAFrontDoorStatus function returns the FPGA front door status * bit. * @details Inputs: none @@ -2345,6 +2401,29 @@ /*********************************************************************//** * @brief + * The getFPGAPBAADCTemperature function reads the PBA ADC temperature. + * @details Inputs: none + * @details Outputs: fpgaSensorReadings + * @return PBA ADC temperature + *************************************************************************/ +U32 getFPGAPBAADCTemperature( void ) +{ + return fpgaSensorReadings.adc1Channel1; +} + +/*********************************************************************//** + * @brief + * The getFPGAInletFan1TogglePeriod function reads the inlet fan 1 pulse time. + * @details Inputs: none + * @details Outputs: fpgaSensorReadings + * @return Inlet fan 1 pulse time + *************************************************************************/ +U16 getFPGAInletFan1TogglePeriod( void ) +{ + return fpgaSensorReadings.fan1PulseTime; +} + +/*********************************************************************//** * The getFPGAPumpTrackSwitchStatus function returns the FPGA pump track * switch status bit. * @details Inputs: none