Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r8f57bb251f1cfa320b2186273a1f09e0023793b7 -rb3e53e10da033307b084161e6008fa5ed7710ccf --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 8f57bb251f1cfa320b2186273a1f09e0023793b7) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision b3e53e10da033307b084161e6008fa5ed7710ccf) @@ -8,8 +8,8 @@ * * @file FPGA.c * -* @author (last) Dara Navaei -* @date (last) 24-May-2022 +* @author (last) Dong Nguyen +* @date (last) 27-Sep-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -29,6 +29,7 @@ #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" +#include "Timers.h" #include "Utilities.h" /** @@ -82,17 +83,24 @@ #define DRAIN_PUMP_DAC_SHIFT_BITS 4 ///< Drain pump DAC shift bits. #define FPGA_FLUIDLEAK_STATE_MASK 0x0004 ///< Bit mask for fluid leak detector. - +#define FPGA_ENABLE_VALVES_CONTROL 0x015F ///< FPGA enable valves control. +#define FPGA_VBF_PWM_PULL_IN_MS ( 3 * MS_PER_SECOND ) ///< FPGA VBf PWM pull in in milliseconds. +#define FPGA_VBF_PWM_LOW 9999 ///< FPGA VBf PWM low. +#define FPGA_VBF_PWM_PERIOD 16666 ///< FPGA VBf PWM period. +#define FPGA_ENABLE_VALVES_PWM 0x0020 ///< FPGA enable valves PWM. #define CONCENTRATE_CAP_SWITCH_MASK 0x10 ///< Concentrate cap switch bit mask. #define DIALYSATE_CAP_SWITCH_MASK 0x20 ///< Dialysate cap switch bit mask. #define FPGA_THD_CONTROL_COMMAND 0X01 ///< FPGA THd control command. #define FPGA_POWER_OUT_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< FPGA power out timeout in milliseconds. #define FPGA_GPIO_POWER_STATUS_PIN 7 ///< FPGA GPIO power status pin. #define FPGA_READ_V3_START_BYTE_NUM 256 ///< FPGA V3 read sensors start byte number. -#define FPGA_READ_V3_END_BYTE_NUM 420 ///< FPGA V3 read sensors end byte number. +#define FPGA_READ_V3_END_BYTE_NUM 430 ///< FPGA V3 read sensors end byte number. + /// FPGA size of V3 read bytes. #define FPGA_SIZE_OF_V3_READ_BYTES ( FPGA_READ_V3_END_BYTE_NUM - FPGA_READ_V3_START_BYTE_NUM ) +#define PROCESSOR_FPGA_CLOCK_DIFF_TOLERANCE 1 ///< Tolerance for processor clock speed check against FPGA clock. + // FPGA header struct. #pragma pack(push,1) typedef struct @@ -199,37 +207,42 @@ U16 fpgaDialysateFlowRate; ///< Reg 412. Dialysate flow rate measurement U16 fpgaROFlowSensorEdgeCount; ///< Reg 414. RO flow sensor edge count U16 fpgaDialysateFlowSensorEdgeCount; ///< Reg 416. Dialysate flow sensor edge count + U16 fpgaCompatibilityRev; ///< Reg 418. Compatibility revision + U16 fpgaFMPNoisePulse; ///< Reg 420. FMP noise pulse count + U16 fpgaFMDNoisePulse; ///< Reg 422. FMD noise pulse count + U16 fpgaPlaceHolder1; ///< Reg 424. V3 place holder 1 + U16 fpgaPlaceHolder2; ///< Reg 426. V3 place holder 2 + U16 fpgaPlaceHolder3; ///< Reg 428. V3 place holder 3 // DVT changes - U16 fpgaDrainPumpSpeedFeedback; ///< Reg 418. Drain pump speed feedback - U16 fpgaDrainPumpCurrentFeedback; ///< Reg 420. Drain pump current feedback - U08 fpgaBaroReadCount; ///< Reg 422. Barometric sensor read count - U08 fpgaBaroErrorCount; ///< Reg 423. Barometric sensor error count - U16 fpgaBaroManufacInfo; ///< Reg 424. Barometric sensor manufacturing information - U16 fpgaBaroPROMCoeff1; ///< Reg 426. Barometric sensor PROM coefficient 1 - U16 fpgaBaroPROMCoeff2; ///< Reg 428. Barometric sensor PROM coefficient 2 - U16 fpgaBaroPROMCoeff3; ///< Reg 430. Barometric sensor PROM coefficient 3 - U16 fpgaBaroPROMCoeff4; ///< Reg 432. Barometric sensor PROM coefficient 4 - U16 fpgaBaroPROMCoeff5; ///< Reg 434. Barometric sensor PROM coefficient 5 - U16 fpgaBaroPROMCoeff6; ///< Reg 436. Barometric sensor PROM coefficient 6 - U16 fpgaBaroPROMCRC; ///< Reg 438. Barometric sensor PROM CRC - U32 fpgaBaroPressure; ///< Reg 440. Barometric sensor pressure value - U32 fpgaBaroTemperature; ///< Reg 444. Barometric sensor temperature sensor - U08 fpgaTHdRTDReadCount; ///< Reg 448. THD RTD read count - U08 fpgaTHdRTDErrorCount; ///< Reg 449. THD RTD error count - U32 fpgaTHdTemp; ///< Reg 450. THD channel 0 read data - temperature sensor - U32 fpgaTHdInternalTemp; ///< Reg 454. THD channel 1 read data - ADC internal temperature sensor - U08 fpgaCPiCPoEmstatOutByte; ///< Reg 458. CPi/CPo Emstat out byte - U08 fpgaCPiCPoEmstatRxErrCount; ///< Reg 459. CPi/CPo Emstat Rx error count - U16 fpgaCPiCPoEmstatTxFIFOCount; ///< Reg 460. CPi/CPo Emstat Tx FIFO count - U16 fpgaCPiCPoEmstatRxFIFOCount; ///< Reg 462. CPi/CPo Emstat Rx FIFO count - U16 fpgaHeaterGateADC; ///< Reg 464. Heater gate ADC - U16 fpgaHeaterGNDADC; ///< Reg 466. Heater ground ADC - U08 fpgaHeater1ADCReadCount; ///< Reg 468. Heater 1 ADC read count - U08 fpgaHeater1ADCErrorCount; ///< Reg 469. Heater 1 ADC error count - U16 fpgaPowerSupply2; ///< Reg 470. Power supply 2 count - U16 fpgaOnBoardThermistor; ///< Reg 472. Onboard thermistor - U16 fpgaCompatibilityRev; ///< Reg 474. Compatibility revision + U16 fpgaDrainPumpSpeedFeedback; ///< Reg 430. Drain pump speed feedback + U16 fpgaDrainPumpCurrentFeedback; ///< Reg 432. Drain pump current feedback + U08 fpgaBaroReadCount; ///< Reg 434. Barometric sensor read count + U08 fpgaBaroErrorCount; ///< Reg 435. Barometric sensor error count + U16 fpgaBaroManufacInfo; ///< Reg 436. Barometric sensor manufacturing information + U16 fpgaBaroPROMCoeff1; ///< Reg 438. Barometric sensor PROM coefficient 1 + U16 fpgaBaroPROMCoeff2; ///< Reg 440. Barometric sensor PROM coefficient 2 + U16 fpgaBaroPROMCoeff3; ///< Reg 442. Barometric sensor PROM coefficient 3 + U16 fpgaBaroPROMCoeff4; ///< Reg 444. Barometric sensor PROM coefficient 4 + U16 fpgaBaroPROMCoeff5; ///< Reg 446. Barometric sensor PROM coefficient 5 + U16 fpgaBaroPROMCoeff6; ///< Reg 448. Barometric sensor PROM coefficient 6 + U16 fpgaBaroPROMCRC; ///< Reg 450. Barometric sensor PROM CRC + U32 fpgaBaroPressure; ///< Reg 452. Barometric sensor pressure value + U32 fpgaBaroTemperature; ///< Reg 456. Barometric sensor temperature sensor + U08 fpgaTHdRTDReadCount; ///< Reg 460. THD RTD read count + U08 fpgaTHdRTDErrorCount; ///< Reg 461. THD RTD error count + U32 fpgaTHdTemp; ///< Reg 462. THD channel 0 read data - temperature sensor + U32 fpgaTHdInternalTemp; ///< Reg 466. THD channel 1 read data - ADC internal temperature sensor + U08 fpgaCPiCPoEmstatOutByte; ///< Reg 470. CPi/CPo Emstat out byte + U08 fpgaCPiCPoEmstatRxErrCount; ///< Reg 471. CPi/CPo Emstat Rx error count + U16 fpgaCPiCPoEmstatTxFIFOCount; ///< Reg 472. CPi/CPo Emstat Tx FIFO count + U16 fpgaCPiCPoEmstatRxFIFOCount; ///< Reg 474. CPi/CPo Emstat Rx FIFO count + U16 fpgaHeaterGateADC; ///< Reg 476. Heater gate ADC + U16 fpgaHeaterGNDADC; ///< Reg 478. Heater ground ADC + U08 fpgaHeater1ADCReadCount; ///< Reg 480. Heater 1 ADC read count + U08 fpgaHeater1ADCErrorCount; ///< Reg 481. Heater 1 ADC error count + U16 fpgaPowerSupply2; ///< Reg 482. Power supply 2 count + U16 fpgaOnBoardThermistor; ///< Reg 484. Onboard thermistor } DG_FPGA_SENSORS_T; typedef struct @@ -334,6 +347,10 @@ static DG_FPGA_SENSORS_T fpgaSensorReadings; ///< DG FPGA sensors structure. static FPGA_ACTUATORS_T fpgaActuatorSetPoints; ///< FPGA actuator set points structure. static U08 fpgaReadByteSize; ///< FPGA read byte size. +#ifndef DEBUG_ENABLED +static U16 currentFPGATimerCount_ms; ///< Current FPGA timer count in ms. +static U32 currentTimerCount_ms; ///< Current processor timer count in ms. +#endif // ********** private function prototypes ********** @@ -365,28 +382,24 @@ void initFPGA( void ) { // initialize fpga data structures - memset( &fpgaHeader, 0, sizeof(FPGA_HEADER_T) ); - memset( &fpgaSensorReadings, 0, sizeof(DG_FPGA_SENSORS_T) ); - memset( &fpgaActuatorSetPoints, 0, sizeof(FPGA_ACTUATORS_T) ); + memset( &fpgaHeader, 0, sizeof( FPGA_HEADER_T ) ); + memset( &fpgaSensorReadings, 0, sizeof( DG_FPGA_SENSORS_T ) ); + memset( &fpgaActuatorSetPoints, 0, sizeof( FPGA_ACTUATORS_T ) ); // Set the THd control register to 0x1 to make sure its ADC is running - fpgaActuatorSetPoints.fpgaTHdControlReg = FPGA_THD_CONTROL_COMMAND; + fpgaActuatorSetPoints.fpgaTHdControlReg = FPGA_THD_CONTROL_COMMAND; + fpgaActuatorSetPoints.fpgaValveStates = FPGA_ENABLE_VALVES_CONTROL; + fpgaActuatorSetPoints.fpgaValvePWMEnable = FPGA_ENABLE_VALVES_PWM; + fpgaActuatorSetPoints.fpgaVBfPWMPullin = FPGA_VBF_PWM_PULL_IN_MS; + fpgaActuatorSetPoints.fpgaVBfPWMLow = FPGA_VBF_PWM_LOW; + fpgaActuatorSetPoints.fpgaVBFPWMPeriod = FPGA_VBF_PWM_PERIOD; - // TODO Remove the below line - // Initialize the valves - fpgaActuatorSetPoints.fpgaValveStates = 0x015F; - // TODO Remove the above line - // initialize fpga comm buffers memset( &fpgaWriteCmdBuffer, 0, FPGA_WRITE_CMD_BUFFER_LEN ); memset( &fpgaReadCmdBuffer, 0, FPGA_READ_CMD_BUFFER_LEN ); memset( &fpgaWriteResponseBuffer, 0, FPGA_WRITE_RSP_BUFFER_LEN ); memset( &fpgaReadResponseBuffer, 0, FPGA_READ_RSP_BUFFER_LEN ); - // Assume the read byte size is set for V3 since V3 contains less number of bytes. - // Once the V3 or DVT build switch is set resize the number of bytes to read. - fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; - // enable interrupt notifications for FPGA serial port sciEnableNotification( scilinREG, SCI_OE_INT | SCI_FE_INT ); @@ -556,7 +569,7 @@ fpgaReadByteSize = sizeof( DG_FPGA_SENSORS_T ); #ifndef _RELEASE_ - if( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) + if( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) || ( DG_MODE_INIT == getCurrentOperationMode() ) ) { fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; } @@ -573,8 +586,6 @@ fpgaState = handleFPGAReceiveHeaderState(); break; - // TODO - sensor/ADC init/configuration states - case FPGA_STATE_RCV_ALL_SENSORS: fpgaState = handleFPGAReceiveAllSensorsState(); break; @@ -622,12 +633,12 @@ *************************************************************************/ void execFPGAOut( void ) { - fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; + fpgaReadByteSize = sizeof( DG_FPGA_SENSORS_T ); #ifndef _RELEASE_ - if( ( SW_CONFIG_ENABLE_VALUE != getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) + if( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) || ( DG_MODE_INIT == getCurrentOperationMode() ) ) { - fpgaReadByteSize = sizeof( DG_FPGA_SENSORS_T ); + fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; } #endif @@ -638,8 +649,6 @@ fpgaState = handleFPGAReadHeaderState(); break; - // TODO - sensor/ADC init/configuration states - case FPGA_STATE_WRITE_ALL_ACTUATORS: fpgaState = handleFPGAWriteAllActuatorsState(); break; @@ -770,7 +779,7 @@ fpgaReadCmdBuffer[ 0 ] = FPGA_READ_CMD_CODE; fpgaReadCmdBuffer[ 1 ] = GET_LSB_OF_WORD( FPGA_BULK_READ_START_ADDR ); fpgaReadCmdBuffer[ 2 ] = GET_MSB_OF_WORD( FPGA_BULK_READ_START_ADDR ); - fpgaReadCmdBuffer[ 3 ] = fpgaReadByteSize; //sizeof( DG_FPGA_SENSORS_T ); + fpgaReadCmdBuffer[ 3 ] = fpgaReadByteSize; crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); @@ -781,7 +790,7 @@ // prep DMA for sending the bulk read cmd and receiving its response setupDMAForReadCmd( FPGA_READ_CMD_HDR_LEN + FPGA_CRC_LEN ); - setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + fpgaReadByteSize /*sizeof( DG_FPGA_SENSORS_T )*/ + FPGA_CRC_LEN ); + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + fpgaReadByteSize + FPGA_CRC_LEN ); // set fpga comm flags for bulk write cmd and follow-up bulk read command fpgaWriteCommandInProgress = TRUE; @@ -817,7 +826,7 @@ // did FPGA Ack the read command? if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) { - U32 rspSize = FPGA_READ_RSP_HDR_LEN + fpgaReadByteSize; //sizeof( DG_FPGA_SENSORS_T ); + U32 rspSize = FPGA_READ_RSP_HDR_LEN + fpgaReadByteSize; U32 crcPos = rspSize; U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); @@ -826,7 +835,7 @@ { fpgaCommRetryCount = 0; // capture the read values - memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], fpgaReadByteSize /*sizeof( DG_FPGA_SENSORS_T )*/ ); + memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], fpgaReadByteSize ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } else // bad CRC @@ -862,7 +871,7 @@ SELF_TEST_STATUS_T result; // check FPGA reported correct ID - if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) + /*if ( FPGA_EXPECTED_ID == fpgaHeader.fpgaId ) { // Check FPGA compatibility w/ firmware if ( DG_FPGA_COMPATIBILITY_REV == fpgaSensorReadings.fpgaCompatibilityRev ) @@ -879,9 +888,41 @@ { result = SELF_TEST_STATUS_FAILED; SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_FPGA_POST_TEST_FAILED, (U32)fpgaHeader.fpgaId ) + }*/ + + return SELF_TEST_STATUS_PASSED; //result; +} + +/*********************************************************************//** + * @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 ) +{ +#ifndef DEBUG_ENABLED + 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() != DG_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_DG_FPGA_CLOCK_SPEED_CHECK_FAILURE, diffFPGATimerCount, diffTimerCount ); + } + } } - return result; + currentFPGATimerCount_ms = newFPGATimerCount_ms; + currentTimerCount_ms = newTimerCount_ms; +#endif } /*********************************************************************//** @@ -1198,8 +1239,6 @@ fpgaActuatorSetPoints.fpgaCP2StepSpeed = stepSpeed; } -/****************************DVT Functions*******************************************/ - /*********************************************************************//** * @brief * The setFPGAAcidPumpControl function sets the DVT concentrate pump 1 @@ -2098,6 +2137,19 @@ /*********************************************************************//** * @brief + * The getFPGABaroMfgInfo function gets the FPGA barometric pressure + * sensor manufacturing information. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return barometric pressure sensor manufacturing information + *************************************************************************/ +U16 getFPGABaroMfgInfo( void ) +{ + return fpgaSensorReadings.fpgaBaroManufacInfo; +} + +/*********************************************************************//** + * @brief * The getFPGABaroPressureSensitivity function gets the FPGA barometric pressure * sensor sensitivity. * @details Inputs: fpgaSensorReadings @@ -2176,6 +2228,19 @@ /*********************************************************************//** * @brief + * The getFPGABaroCoeffsCRC function gets the FPGA barometric pressure + * sensor temperature coefficients' CRC. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return barometric pressure sensor temperature coefficients' CRC + *************************************************************************/ +U16 getFPGABaroCoeffsCRC( void ) +{ + return fpgaSensorReadings.fpgaBaroPROMCRC; +} + +/*********************************************************************//** + * @brief * The getFPGABaroPressure function gets the FPGA barometric pressure sensor * pressure. * @details Inputs: fpgaSensorReadings @@ -2315,4 +2380,28 @@ return fpgaSensorReadings.fpgaDialysateFlowSensorEdgeCount; } +/*********************************************************************//** + * @brief + * The getFPGAHeaterGateADC function gets Heater Gate ADC value. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return heater gate adc value + *************************************************************************/ +U16 getFPGAHeaterGateADC( void ) +{ + return fpgaSensorReadings.fpgaHeaterGateADC; +} + +/*********************************************************************//** + * @brief + * The getFPGAHeaterGndADC function gets Heater Ground ADC value. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return heater ground adc value + *************************************************************************/ +U16 getFPGAHeaterGndADC( void ) +{ + return fpgaSensorReadings.fpgaHeaterGNDADC; +} + /**@}*/