Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rcd3f58205f4dab89291b29ee73b7fa9c31773abc -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision cd3f58205f4dab89291b29ee73b7fa9c31773abc) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) @@ -1,15 +1,15 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-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) Dara Navaei -* @date (last) 04-Aug-2022 +* @date (last) 26-Sep-2023 * * @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" /** @@ -88,15 +89,28 @@ #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 FPGA_CONC_PUMP_FAULT_BITS 0x03 ///< Concentrate pump fault bits mask. +#define FPGA_CP1_PARKED_BIT 0x04 ///< Concentrate pump 1 parked status bit mask. +#define FPGA_CP2_PARKED_BIT 0x10 ///< Concentrate pump 2 parked status bit mask. +#define FPGA_CP1_PARK_FAULT_BIT 0x08 ///< Concentrate pump 1 park fault status bit mask. +#define FPGA_CP2_PARK_FAULT_BIT 0x20 ///< Concentrate pump 2 park fault status bit mask. +#define FPGA_CONC_PUMP_PARK_COMMAND 0x80 ///< Park command bit for the concentrate pumps. #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 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. + +#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 + // FPGA header struct. #pragma pack(push,1) typedef struct @@ -163,10 +177,10 @@ U08 fpgaTRoErrorCnt; ///< Reg 361. Redundant outlet temperature sensor error count U08 fpgaTDiReadCnt; ///< Reg 362. Dialysate inlet temperature sensor read count U08 fpgaTDiErrorCnt; ///< Reg 363. Dialysate inlet temperature sensor error count - U08 fpgaPrimaryHeaterFlags; ///< Reg 364. Primary heater flags - U08 fpgaPrimaryHeaterReadCnt; ///< Reg 365. Primary heater read count - U08 fpgaTrimmerHeaterFlags; ///< Reg 366. Trimmer heater flags - U08 fpgaTrimmerHeaterReadCnt; ///< Reg 367. Trimmer heater read count + U08 fpgaPrimaryHeaterFlags; ///< Reg 364. Primary heater flags (thermo-couple) + U08 fpgaPrimaryHeaterReadCnt; ///< Reg 365. Primary heater read count (thermo-couple) + U08 fpgaTrimmerHeaterFlags; ///< Reg 366. Trimmer heater flags (thermo-couple) + U08 fpgaTrimmerHeaterReadCnt; ///< Reg 367. Trimmer heater read count (thermo-couple) U08 fpgaCPoFault; ///< Reg 368. CPo conductivity sensor fault U08 fpgaCPoReadCnt; ///< Reg 369. CPo conductivity sensor read count @@ -175,7 +189,7 @@ U08 fpgaCPiReadCnt; ///< Reg 372. CPi conductivity sensor read count U08 fpgaCPiErrorCnt; ///< Reg 373. CPi conductivity sensor error count U08 fpgaCP1CP2Fault; ///< Reg 374. Concentrate pump fault register for CP1 and CP2 - U08 fpgaReserved1; ///< Reg 375. Reserved + U08 fpgaHWConfigReg; ///< Reg 375. Hardware configuration register (i.e. BETA or DVT) U16 fpgaValveStates; ///< Reg 376. Valves states U16 fpgaFanIn1Pulse; ///< Reg 378. Fan inlet 1 pulse time in 2.5 us resolution @@ -239,6 +253,7 @@ U08 fpgaHeater1ADCErrorCount; ///< Reg 481. Heater 1 ADC error count U16 fpgaPowerSupply2; ///< Reg 482. Power supply 2 count U16 fpgaOnBoardThermistor; ///< Reg 484. Onboard thermistor + U08 fpgaDrainPumpDirection; ///< Reg 486. Drain pump direction } DG_FPGA_SENSORS_T; typedef struct @@ -309,15 +324,14 @@ U16 fpgaDACRegFIn; ///< Reg 126. Debug DAC channel F output U16 fpgaDACRegGIn; ///< Reg 128. Debug DAC channel G output U16 fpgaDACRegHIn; ///< Reg 130. Debug DAC channel H output - U08 fgpaNewCP2Control; ///< Reg 132. Concentrate pump 2 control + U08 fpgaNewCP2Control; ///< Reg 132. Concentrate pump 2 control U08 fpgaNewCP1Control; ///< Reg 133. Concentrate pump 1 control } FPGA_ACTUATORS_T; #pragma pack(pop) // ********** private data ********** static FPGA_STATE_T fpgaState = FPGA_STATE_START; ///< FPGA current state. -static U32 fpgaCommRetryCount = 0; ///< FPGA communication retry count. static U32 fpgaReceiptCounter = 0; ///< FPGA receipt completed counter. static U32 fpgaTransmitCounter = 0; ///< FPGA transmit completed counter. static BOOL fpgaWriteCommandInProgress = FALSE; ///< Flag indicates whether a FPGA write command is in progress. @@ -342,7 +356,6 @@ static FPGA_HEADER_T fpgaHeader; ///< FPGA header structure. 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. // ********** private function prototypes ********** @@ -362,8 +375,10 @@ static void startDMAReceiptOfReadResp( void ); static void consumeUnexpectedData( void ); -static void monitorFPGAPowerStatus( void ); +static BOOL checkFPGACommFailure( void ); +static BOOL checkFPGAFEOEFailure( void ); + /*********************************************************************//** * @brief * The initFPGA function initializes the FPGA module. @@ -480,8 +495,9 @@ // there shouldn't be any data pending yet consumeUnexpectedData(); - // Initialize the persistent alarm for FPGA power out - initPersistentAlarm( ALARM_ID_DG_FPGA_POWER_OUT_TIMEOUT, FPGA_POWER_OUT_TIMEOUT_MS, FPGA_POWER_OUT_TIMEOUT_MS ); + // initialize FPGA clock speed error time windowed count + initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_COMM_FAILURES, MAX_FPGA_COMM_FAILURES, MAX_FPGA_COMM_FAILURES_WINDOW_MS); + } /*********************************************************************//** @@ -558,15 +574,9 @@ *************************************************************************/ void execFPGAIn( void ) { - fpgaReadByteSize = sizeof( DG_FPGA_SENSORS_T ); + // Check if FE or OE error has occurred + checkFPGAFEOEFailure(); -#ifndef _RELEASE_ - if( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) || ( DG_MODE_INIT == getCurrentOperationMode() ) ) - { - fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; - } -#endif - // FPGA incoming state machine switch ( fpgaState ) { @@ -578,8 +588,6 @@ fpgaState = handleFPGAReceiveHeaderState(); break; - // TODO - sensor/ADC init/configuration states - case FPGA_STATE_RCV_ALL_SENSORS: fpgaState = handleFPGAReceiveAllSensorsState(); break; @@ -600,22 +608,9 @@ break; } - // if retries for commands exceeds limit or FPGA reports comm error, fault - if ( ( fpgaCommRetryCount > MAX_COMM_ERROR_RETRIES ) -#ifdef _RELEASE_ - || ( fpgaSensorReadings.fpgaIOErrorCntProcessor > MAX_COMM_ERROR_RETRIES ) ) -#else - ) -#endif - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_FPGA_COMM_TIMEOUT, fpgaCommRetryCount, (U32)fpgaSensorReadings.fpgaIOErrorCntProcessor ) - } - // reset comm flags after processing incoming responses resetFPGACommFlags(); - // Check the FPGA power status - monitorFPGAPowerStatus(); } /*********************************************************************//** @@ -627,24 +622,13 @@ *************************************************************************/ void execFPGAOut( void ) { - fpgaReadByteSize = sizeof( DG_FPGA_SENSORS_T ); - -#ifndef _RELEASE_ - if( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) || ( DG_MODE_INIT == getCurrentOperationMode() ) ) - { - fpgaReadByteSize = FPGA_SIZE_OF_V3_READ_BYTES; - } -#endif - // FPGA outgoing state machine switch ( fpgaState ) { case FPGA_STATE_READ_HEADER: fpgaState = handleFPGAReadHeaderState(); break; - // TODO - sensor/ADC init/configuration states - case FPGA_STATE_WRITE_ALL_ACTUATORS: fpgaState = handleFPGAWriteAllActuatorsState(); break; @@ -722,24 +706,23 @@ // does the FPGA response CRC check out? if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) { - fpgaCommRetryCount = 0; // capture the read values memcpy( &fpgaHeader, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( FPGA_HEADER_T ) ); result = FPGA_STATE_WRITE_ALL_ACTUATORS; } else { - fpgaCommRetryCount++; + checkFPGACommFailure(); } } else // header read was NAK'd { - fpgaCommRetryCount++; + checkFPGACommFailure(); } } else // no response to read command { - fpgaCommRetryCount++; + checkFPGACommFailure(); } // There should not be any data received at this time @@ -771,11 +754,17 @@ fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) ] = GET_MSB_OF_WORD( crc ); fpgaWriteCmdBuffer[ FPGA_WRITE_CMD_HDR_LEN + sizeof( FPGA_ACTUATORS_T ) + 1 ] = GET_LSB_OF_WORD( crc ); + // reset one-time sets after actuator set points xmit message created + fpgaActuatorSetPoints.fpgaNewCP1Control &= ~FPGA_CONC_PUMP_PARK_COMMAND; // clear concentrate pump park command bits + fpgaActuatorSetPoints.fpgaNewCP2Control &= ~FPGA_CONC_PUMP_PARK_COMMAND; + fpgaActuatorSetPoints.fpgaCP1Control &= ~FPGA_CONC_PUMP_PARK_COMMAND; + fpgaActuatorSetPoints.fpgaCP2Control &= ~FPGA_CONC_PUMP_PARK_COMMAND; + // construct bulk read command to read sensor data registers starting at address 8 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; + fpgaReadCmdBuffer[ 3 ] = sizeof( DG_FPGA_SENSORS_T ); crc = crc16( fpgaReadCmdBuffer, FPGA_READ_CMD_HDR_LEN ); fpgaReadCmdBuffer[ 4 ] = GET_MSB_OF_WORD( crc ); fpgaReadCmdBuffer[ 5 ] = GET_LSB_OF_WORD( crc ); @@ -786,7 +775,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 + FPGA_CRC_LEN ); + setupDMAForReadResp( FPGA_READ_RSP_HDR_LEN + sizeof( DG_FPGA_SENSORS_T ) + FPGA_CRC_LEN ); // set fpga comm flags for bulk write cmd and follow-up bulk read command fpgaWriteCommandInProgress = TRUE; @@ -811,43 +800,75 @@ FPGA_STATE_T result = FPGA_STATE_WRITE_ALL_ACTUATORS; // check bulk write command success - if ( ( FALSE == fpgaWriteCommandResponseReceived ) || ( fpgaWriteResponseBuffer[ 0 ] != FPGA_WRITE_CMD_ACK ) ) + if ( TRUE == fpgaWriteCommandResponseReceived ) { - fpgaCommRetryCount++; + // The write command completed so check for validity + if ( fpgaWriteResponseBuffer[ 0 ] == FPGA_WRITE_CMD_ACK) + { + // Message is an ack - check CRC + U32 rspSize = FPGA_READ_RSP_HDR_LEN; + U32 crcPos = rspSize; + U16 crc = MAKE_WORD_OF_BYTES( fpgaWriteResponseBuffer[ crcPos ], fpgaWriteResponseBuffer[ crcPos + 1 ] ); + + // Does the FPGA response CRC checkout? + if ( crc != crc16( fpgaWriteResponseBuffer, rspSize ) ) + { + // CRC failed + checkFPGACommFailure(); + } + } + else + { + // Not an ACK + checkFPGACommFailure(); + } } + else + { + // Timeout - communication error + checkFPGACommFailure(); + } - // if bulk read command is ACK'd, collect the readings - if ( TRUE == fpgaReadCommandResponseReceived ) + /* If the write command response (ACK) was not received, the read response + * was not issued. If this is the case the read response will also + * timeout. For FPGA V&V testing this will cause two timeouts to occur. + * The V&V expectation is that when the timeout test is executed a + * single timeout will occur. + */ + if ( TRUE == fpgaWriteCommandResponseReceived ) { - // did FPGA Ack the read command? - if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) + // if bulk read command is ACK'd, collect the readings + if ( TRUE == fpgaReadCommandResponseReceived ) { - U32 rspSize = FPGA_READ_RSP_HDR_LEN + fpgaReadByteSize; - U32 crcPos = rspSize; - U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); - - // does the FPGA response CRC check out? - if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) + // did FPGA ACK the read command? + if ( fpgaReadResponseBuffer[ 0 ] == FPGA_READ_CMD_ACK ) { - fpgaCommRetryCount = 0; - // capture the read values - memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], fpgaReadByteSize ); - result = FPGA_STATE_WRITE_ALL_ACTUATORS; + U32 rspSize = FPGA_READ_RSP_HDR_LEN + sizeof( DG_FPGA_SENSORS_T ); + U32 crcPos = rspSize; + U16 crc = MAKE_WORD_OF_BYTES( fpgaReadResponseBuffer[ crcPos ], fpgaReadResponseBuffer[ crcPos + 1 ] ); + + // does the FPGA response CRC check out? + if ( crc == crc16( fpgaReadResponseBuffer, rspSize ) ) + { + // capture the read values + memcpy( &fpgaSensorReadings, &fpgaReadResponseBuffer[ FPGA_READ_RSP_HDR_LEN ], sizeof( DG_FPGA_SENSORS_T ) ); + result = FPGA_STATE_WRITE_ALL_ACTUATORS; + } + else // bad CRC + { + checkFPGACommFailure(); + } } - else // bad CRC + else // read command was NAK'd { - fpgaCommRetryCount++; + checkFPGACommFailure(); } } - else // read command was NAK'd + else // no response to read command { - fpgaCommRetryCount++; + checkFPGACommFailure(); } } - else // no response to read command - { - fpgaCommRetryCount++; - } // There should not be any data received at this time consumeUnexpectedData(); @@ -867,7 +888,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 ) @@ -884,13 +905,53 @@ { 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; + return result; } /*********************************************************************//** * @brief + * The execFPGAClockSpeedTest function verifies the processor clock speed + * against the FPGA clock. + * @details Inputs: fpgaHeader, + * window timer TIME_WINDOWED_COUNT_FPGA_CLOCK_SPEED_ERROR + * @details Outputs: none + * @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. + */ + + static U16 currentFPGATimerCount_ms = 0; + static U32 currentTimerCount_ms = 0; + + 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 ); + } + } + } + + currentFPGATimerCount_ms = newFPGATimerCount_ms; + currentTimerCount_ms = newTimerCount_ms; +} + +/*********************************************************************//** + * @brief * The setupDMAForWriteCmd function sets the byte count for the next DMA * write command to the FPGA. * @details Inputs: none @@ -1058,22 +1119,6 @@ /*********************************************************************//** * @brief - * The monitorFPGAPowerStatus function monitors the status of the FPGA power source. - * @details Inputs: none - * @details Outputs: none - * @return none - *************************************************************************/ -static void monitorFPGAPowerStatus( void ) -{ - // If the GIO bit returned a 0 it mean the power is out, otherwise the power is not out - BOOL isPowerOut = ( TRUE == (BOOL)gioGetBit( gioPORTA, FPGA_GPIO_POWER_STATUS_PIN ) ? FALSE : TRUE ); - - // TODO check to make sure alarm is not raised when the power is good - checkPersistentAlarm( ALARM_ID_DG_FPGA_POWER_OUT_TIMEOUT, isPowerOut, 0, FPGA_POWER_OUT_TIMEOUT_MS ); -} - -/*********************************************************************//** - * @brief * The setFPGAValveStates function sets the DG valve states with a 16-bit * set of states - one bit per valve, with a 1 meaning "energized" and a 0 * meaning "de-energized". The bit positions for these bit states are as follows: @@ -1158,7 +1203,8 @@ *************************************************************************/ void setFPGAV3AcidPumpControl( U08 pumpControl ) { - fpgaActuatorSetPoints.fpgaCP1Control = pumpControl; + fpgaActuatorSetPoints.fpgaCP1Control &= FPGA_CONC_PUMP_PARK_COMMAND; + fpgaActuatorSetPoints.fpgaCP1Control |= pumpControl; } /*********************************************************************//** @@ -1172,11 +1218,38 @@ *************************************************************************/ void setFPGAV3BicarbPumpControl( U08 pumpControl ) { - fpgaActuatorSetPoints.fpgaCP2Control = pumpControl; + fpgaActuatorSetPoints.fpgaCP2Control &= FPGA_CONC_PUMP_PARK_COMMAND; + fpgaActuatorSetPoints.fpgaCP2Control |= pumpControl; } /*********************************************************************//** * @brief + * The setFPGABicarbPumpControl function sets the park command bit for the + * concentrate pump CP1. + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaCP1Control + * @return none + *************************************************************************/ +void setFPGAV3AcidPumpParkCmd( void ) +{ + fpgaActuatorSetPoints.fpgaCP1Control |= FPGA_CONC_PUMP_PARK_COMMAND; // this bit must be cleared after next transmit to prevent continuous park commands +} + +/*********************************************************************//** + * @brief + * The setFPGAV3BicarbPumpParkCmd function sets the park command bit for the + * concentrate pump CP2. + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaCP2Control + * @return none + *************************************************************************/ +void setFPGAV3BicarbPumpParkCmd( void ) +{ + fpgaActuatorSetPoints.fpgaCP2Control |= FPGA_CONC_PUMP_PARK_COMMAND; // this bit must be cleared after next transmit to prevent continuous park commands +} + +/*********************************************************************//** + * @brief * The setFPGAAcidPumpSetStepSpeed function sets the step speed period for * concentrate pump CP1. * @details Inputs: none @@ -1207,32 +1280,116 @@ * @brief * The setFPGAAcidPumpControl function sets the DVT concentrate pump 1 * (acid pump) control mode. + * bit 7: Park (set in different function) + * bit 6: nSleep + * bit 5: nReset + * bit 4: nEnable + * bit 3: Direction (1=Fwd, 0=Rev) + * bit 0-2: Microstepping resolution * @details Inputs: none * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP1Control * @param control Concentrate pump control set * @return none *************************************************************************/ void setFPGAAcidPumpControl( U08 control ) { - fpgaActuatorSetPoints.fpgaNewCP1Control = control; + fpgaActuatorSetPoints.fpgaNewCP1Control &= FPGA_CONC_PUMP_PARK_COMMAND; // preserve msb (park command bit) + fpgaActuatorSetPoints.fpgaNewCP1Control |= control; } /*********************************************************************//** * @brief + * The getFPGAAcidPumpControlStatus function gets the status of the + * acid pump control status bits. + * bit 7: Park (set in different function) + * bit 6: nSleep + * bit 5: nReset + * bit 4: nEnable + * bit 3: Direction (1=Fwd, 0=Rev) + * bit 0-2: Microstepping resolution + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP1Control + * @return Acid pump control status bit + *************************************************************************/ +U08 getFPGAAcidPumpControlStatus( void ) +{ + return fpgaActuatorSetPoints.fpgaNewCP1Control; +} + +/*********************************************************************//** + * @brief * The setFPGABicarbPumpControl function sets the DVT concentrate pump 2 * (bicarb pump) control mode. + * bit 7: Park (set in different function) + * bit 6: nSleep + * bit 5: nReset + * bit 4: nEnable + * bit 3: Direction (1=Fwd, 0=Rev) + * bit 0-2: Microstepping resolution * @details Inputs: none - * @details Outputs: fpgaActuatorSetPoints.fgpaNewCP2Control + * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP2Control * @param control Concentrate pump control set * @return none *************************************************************************/ void setFPGABicarbPumpControl( U08 control ) { - fpgaActuatorSetPoints.fgpaNewCP2Control = control; + fpgaActuatorSetPoints.fpgaNewCP2Control &= FPGA_CONC_PUMP_PARK_COMMAND; // preserve msb (park command bit) + fpgaActuatorSetPoints.fpgaNewCP2Control |= control; } /*********************************************************************//** * @brief + * The getFPGABicarbPumpControlStatus function gets the DVT concentrate pump 2 + * (bicarb pump) control mode. + * bit 7: Park (set in different function) + * bit 6: nSleep + * bit 5: nReset + * bit 4: nEnable + * bit 3: Direction (1=Fwd, 0=Rev) + * bit 0-2: Microstepping resolution + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP2Control + * @return Bicarb pump control status bit + *************************************************************************/ +U08 getFPGABicarbPumpControlStatus( void ) +{ + return fpgaActuatorSetPoints.fpgaNewCP2Control; +} + +/*********************************************************************//** + * @brief + * The setFPGAAcidPumpParkCmd function sets the DVT concentrate pump 1 + * (acid pump) park command bit. + * bit 7: Park command bit + * bit 0-6: Other pump control bits (set in different function) + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP1Control + * @param Park command bit set + * @return none + *************************************************************************/ +void setFPGAAcidPumpParkCmd( void ) +{ + fpgaActuatorSetPoints.fpgaNewCP1Control |= FPGA_CONC_PUMP_PARK_COMMAND; // this bit must be cleared after next transmit to prevent continuous park commands +} + +/*********************************************************************//** + * @brief + * The setFPGABicarbPumpParkCmd function sets the DVT concentrate pump 2 + * (bicarb pump) park command bit. + * bit 7: Park command bit + * bit 0-6: Other pump control bits (set in different function) + * @details Inputs: none + * @details Outputs: fpgaActuatorSetPoints.fpgaNewCP2Control + * @param Park command bit set + * @return none + *************************************************************************/ +void setFPGABicarbPumpParkCmd( void ) +{ + fpgaActuatorSetPoints.fpgaNewCP2Control |= FPGA_CONC_PUMP_PARK_COMMAND; // this bit must be cleared after next transmit to prevent continuous park commands +} + +/*********************************************************************//** + * @brief * The getFPGAVersions function gets the FPGA version numbers. * @details Inputs: fpgaHeader * @details Outputs: none @@ -1762,11 +1919,75 @@ *************************************************************************/ U08 getFPGAConcentratePumpsFault( void ) { - return fpgaSensorReadings.fpgaCP1CP2Fault; + return fpgaSensorReadings.fpgaCP1CP2Fault & FPGA_CONC_PUMP_FAULT_BITS; } /*********************************************************************//** * @brief + * The getFPGAAcidPumpIsParked function gets whether the acid pump is currently + * parked. + * @details Inputs: fpgaSensorReadings.fpgaCP1CP2Fault + * @details Outputs: none + * @return TRUE if acid pump is parked, FALSE if not + *************************************************************************/ +BOOL getFPGAAcidPumpIsParked( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCP1CP2Fault & FPGA_CP1_PARKED_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGABicarbPumpIsParked function gets whether the bicarb pump is currently + * parked. + * @details Inputs: fpgaSensorReadings.fpgaCP1CP2Fault + * @details Outputs: none + * @return TRUE if bicarb pump is parked, FALSE if not + *************************************************************************/ +BOOL getFPGABicarbPumpIsParked( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCP1CP2Fault & FPGA_CP2_PARKED_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAAcidPumpParkFault function gets whether the acid pump park command + * has faulted. + * @details Inputs: fpgaSensorReadings.fpgaCP1CP2Fault + * @details Outputs: none + * @return TRUE if acid pump park command faulted, FALSE if not + *************************************************************************/ +BOOL getFPGAAcidPumpParkFault( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCP1CP2Fault & FPGA_CP1_PARK_FAULT_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGABicarbPumpParkFault function gets whether the bicarb pump park command + * has faulted. + * @details Inputs: fpgaSensorReadings.fpgaCP1CP2Fault + * @details Outputs: none + * @return TRUE if bicarb pump park command faulted, FALSE if not + *************************************************************************/ +BOOL getFPGABicarbPumpParkFault( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCP1CP2Fault & FPGA_CP2_PARK_FAULT_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief * The getFPGAEmstatOutByte function gets Emstat conductivity sensor output byte. * @details Inputs: fpgaSensorReadings.fpgaEmstatOutByte * @details Outputs: none @@ -2077,6 +2298,60 @@ /*********************************************************************//** * @brief + * The getFPGAInternalVccVoltage function gets the FPGA internal Vcc voltage. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return internal Vcc voltage + *************************************************************************/ +U16 getFPGAInternalVccVoltage( void ) +{ + return fpgaSensorReadings.fpgaADCVccInt; +} + +/*********************************************************************//** + * @brief + * The getFPGAInternalVccAuxilaryVoltage function gets the FPGA auxiliary + * Vcc voltage. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return auxiliary Vcc voltage + *************************************************************************/ +U16 getFPGAInternalVccAuxiliaryVoltage( void ) +{ + return fpgaSensorReadings.fpgaADCVccAux; +} + +/*********************************************************************//** + * @brief + * The getFPGAVPVNVoltage function gets the FPGA VPVN voltage. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return VPVN voltage + *************************************************************************/ +U16 getFPGAVPVNVoltage( void ) +{ + return fpgaSensorReadings.fpgaADCVPVN; +} + +#ifndef _RELEASE_ +/*********************************************************************//** + * @brief + * The getHardwareConfigStatus function returns the status of the hardware + * configuration. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return status of the hardware configuration + *************************************************************************/ +HARDWARE_CONFIG_T getHardwareConfigStatus( void ) +{ + HARDWARE_CONFIG_T configValue = (HARDWARE_CONFIG_T)fpgaSensorReadings.fpgaHWConfigReg; + + return configValue; +} +#endif + +/*********************************************************************//** + * @brief * The getFPGABaroReadCount function gets the FPGA barometric sensor read count. * @details Inputs: fpgaSensorReadings * @details Outputs: none @@ -2368,4 +2643,151 @@ return fpgaSensorReadings.fpgaHeaterGNDADC; } +/*********************************************************************//** + * @brief + * The getFPGAHeaterGateADCReadCount function returns the main primary heater + * voltage ADC read count. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return main primary heater voltage ADC read count + *************************************************************************/ +U08 getFPGAHeaterGateADCReadCount( void ) +{ + return fpgaSensorReadings.fpgaHeater1ADCReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGAHeaterGateADCReadCount function returns the main primary heater + * voltage ADC error count. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return main primary heater voltage ADC error count + *************************************************************************/ +U08 getFPGAHeaterGateADCErrorCount( void ) +{ + return fpgaSensorReadings.fpgaHeater1ADCErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADrainPumpCurrentFeedback function returns the drain pump current + * feedback. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return drain pump current feedback + *************************************************************************/ +U16 getFPGADrainPumpCurrentFeedback( void ) +{ + return fpgaSensorReadings.fpgaDrainPumpCurrentFeedback; +} + +/*********************************************************************//** + * @brief + * The getFPGADrainPumpSpeedFeedback function returns the drain pump speed + * feedback. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return drain pump speed feedback + *************************************************************************/ +U16 getFPGADrainPumpSpeedFeedback( void ) +{ + return fpgaSensorReadings.fpgaDrainPumpSpeedFeedback; +} + +/*********************************************************************//** + * @brief + * The getFPGADrainPumpDirection function returns the drain pump direction. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return drain pump direction + *************************************************************************/ +U08 getFPGADrainPumpDirection( void ) +{ + return fpgaSensorReadings.fpgaDrainPumpDirection; +} + +/*********************************************************************//** + * @brief + * The getFPGAOnBoardThermistorCount function returns the onboard thermistor + * count. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return onboard thermistor + *************************************************************************/ +U16 getFPGAOnBoardThermistorCount( void ) +{ + return fpgaSensorReadings.fpgaOnBoardThermistor; +} + +/*********************************************************************//** + * @brief + * The getFPGAPowerSupply2ThermistorCount function returns the + * Power Supply 2 thermistor + * count. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return onboard thermistor + *************************************************************************/ +U16 getFPGAPowerSupply2ThermistorCount( void ) +{ + return fpgaSensorReadings.fpgaPowerSupply2; +} + +/*********************************************************************//** + * @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 Inputs: none + * @details Outputs: none + * @return TRUE if windowed count exceeded, else false. + *************************************************************************/ +BOOL checkFPGACommFailure( void ) +{ + BOOL status = FALSE; + + 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_DG_FPGA_COMM_TIMEOUT, MAX_FPGA_COMM_FAILURES, (U32)fpgaSensorReadings.fpgaIOErrorCntProcessor ) + status = TRUE; + } + } + + return status; + +} + +/*********************************************************************//** + * @brief + * The checkFPGACommFailure 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 Inputs: none + * @details Outputs: none + * @return TRUE if windowed count exceeded, else false. + *************************************************************************/ +static BOOL checkFPGAFEOEFailure( void ) +{ + BOOL status = FALSE; + 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_DG_FPGA_COMM_TIMEOUT, MAX_FPGA_COMM_FAILURES, (U32)fpgaSensorReadings.fpgaIOErrorCntProcessor ) + status = TRUE; + } + } + } + + return status; +} + /**@}*/