/************************************************************************** * * Copyright (c) 2020-2023 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 Fans.c * * @author (last) Dara Navaei * @date (last) 03-May-2023 * * @author (original) Dara Navaei * @date (original) 25-Nov-2020 * ***************************************************************************/ #include "etpwm.h" #include "math.h" #include "Fans.h" #include "FPGA.h" #include "MessageSupport.h" #include "NVDataMgmt.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" #include "Thermistors.h" #include "Timers.h" /** * @addtogroup Fans * @{ */ // ********** private definitions ********** #define FANS_MIN_DUTY_CYCLE 0.1F ///< Fans min PWM. #define FANS_MAX_DUTY_CYCLE 0.95F ///< Fans max PWM. #define MIN_ALLOWED_AMBIENT_TEMPERATURE 20 ///< Min allowed ambient temperature. #define MAX_ALLOWED_AMBINET_TEMPERATURE 70 ///< Max allowed ambient temperature. #define FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE 0.3F ///< Fans max allowed ramp up PWM change. #define FANS_MAX_ALLOWED_RAMP_DOWN_DELTA_DUTY_CYCLE 0.005F ///< Fans min allowed ramp down PWM change. #define TOGGLE_PERIOD_RESOLUTION_SECONDS 0.0000025F ///< FPGA fans toggle period resolution in micro seconds. #define ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION 4 ///< FPGA rotational to toggle period conversion coefficient. #define FANS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans publish data time interval in counts. #define FANS_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans control time interval in counts. #define FANS_ZERO_RPM_TOGGLE_PERIOD_VALUE 0xFFFF ///< Fans zero RPM toggle period value. #define MIN_TARGET_RPM_IN_SELF_TEST 1000 ///< Fans min target RPM that they should be during POST. #define FANS_SELF_TEST_WAIT_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans self test wait time for the fans to get to RPM. #define FANS_SELF_TEST_TARGET_PWM 0.5F ///< Fans self test target PWM for testing the fans are running. #define FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL ( 3 * MS_PER_SECOND ) ///< Fans max allowed RPM out of range time interval. #define FANS_MAX_ALLOWED_RPM 5500 ///< Fans max allowed RPM value. #define FANS_MIN_ALLOWED_RPM 150 ///< Fans max allowed RPM value. #define FANS_MIN_RPM_OUT_OF_RANGE_TOL 0.25F ///< Fans min RPM out of range tolerance. #define FANS_MAX_RPM_OUT_OF_RANGE_TOL 0.5F ///< Fans max RPM out of range tolerance. #define DATA_PUBLISH_COUNTER_START_COUNT 12 ///< Data publish counter start count. /// Fans exec states typedef enum fans_Exec_States { FANS_EXEC_STATE_START = 0, ///< Fans exec state start state. FANS_EXEC_STATE_RUN_STATE, ///< Fans exec state run state. NUM_OF_FANS_EXEC_STATES, ///< Number of fans exec states. } FANS_EXEC_STATES_T; /// Fans status struct typedef struct { OVERRIDE_F32_T dutyCycle; ///< Fans duty cycle that was fed to the fans. F32 targetRPM; ///< Fans target RPM. OVERRIDE_F32_T rpm[ NUM_OF_FANS_NAMES ]; ///< Fan's current tachometers reading in RPM. } FAN_STATUS_T; // ********** private data ********** static FAN_STATUS_T fansStatus; ///< Fans status. static FANS_EXEC_STATES_T fansExecState; ///< Fans exec state. static U32 fansControlCounter; ///< Fans control interval counter. static U32 fansPublishCounter; ///< Fans data publish interval counter. static BOOL hasAlarmBeenRaised; ///< Flag that indicates whether the RPM out of range alarm been raise. static U32 rpmAlarmStartTimeOffset; ///< RPM out of range alarm start time offset. static U32 rpmAlarmStartTime; ///< RPM alarm start time. static DG_FANS_CAL_RECORD_T fansCalReocrd; ///< Fans calibration record. /// Temperature to duty cycle conversion slope (duty cycle not in percent) static const F32 SLOPE = ( FANS_MAX_DUTY_CYCLE - FANS_MIN_DUTY_CYCLE ) / ( MAX_ALLOWED_AMBINET_TEMPERATURE - MIN_ALLOWED_AMBIENT_TEMPERATURE ); /// FGPA Toggle to RPM conversion coefficient static const F32 TOGGLE_PERIOD_2_RPM_COEFFICIENT = SEC_PER_MIN / ( TOGGLE_PERIOD_RESOLUTION_SECONDS * ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION ); static OVERRIDE_U32_T fansPublishInterval = { FANS_DATA_PUBLISH_INTERVAL, FANS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Fans publish time interval override. // ********** private function prototypes ********** static FANS_EXEC_STATES_T handleExecStateStart( void ); static FANS_EXEC_STATES_T handleExecStateRun( void ); static void setInletFansDutyCycle( F32 pwm ); static void setOutletFansDutyCycle( F32 pwm ); static F32 getMaximumTemperature( void ); static void convertTogglePeriod2RPM( void ); static void monitorFans( void ); static void publishFansData( void ); /*********************************************************************//** * @brief * The initFans function initializes the fans module. * @details Inputs: none * @details Outputs: fansExecState, fansControlCounter, fansPublishCounter, * hasAlarmBeenRaised, rpmAlarmStartTime, * fansStatus, rpmAlarmStartTimeOffset * @return none *************************************************************************/ void initFans( void ) { FAN_NAMES_T fan; // Initialize the variables fansExecState = FANS_EXEC_STATE_START; fansControlCounter = 0; fansPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; hasAlarmBeenRaised = FALSE; rpmAlarmStartTime = 0; rpmAlarmStartTimeOffset = 0; fansStatus.dutyCycle.data = 0.0; fansStatus.dutyCycle.ovData = 0.0; fansStatus.dutyCycle.ovInitData = 0.0; fansStatus.dutyCycle.override = OVERRIDE_RESET; fansStatus.targetRPM = 0.0; // Initialize the fans for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ ) { fansStatus.rpm[ fan ].data = 0.0; fansStatus.rpm[ fan ].ovData = 0.0; fansStatus.rpm[ fan ].ovInitData = 0.0; fansStatus.rpm[ fan ].override = OVERRIDE_RESET; } // Initialize a persistent alarm for fans RPM out of range initPersistentAlarm( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL, FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL ); } /*********************************************************************//** * @brief * The execFansSelfTest function executes the fans self test. * @details Inputs: none * @details Outputs: fansCalReocrd * @return Status of self test *************************************************************************/ SELF_TEST_STATUS_T execFansSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = getNVRecord2Driver( GET_CAL_FANS_RECORD, (U08*)&fansCalReocrd, sizeof( DG_FANS_CAL_RECORD_T ), NUM_OF_CAL_DATA_FANS, ALARM_ID_NO_ALARM ); if ( TRUE == calStatus ) { result = SELF_TEST_STATUS_PASSED; } else { result = SELF_TEST_STATUS_FAILED; } return result; } /*********************************************************************//** * @brief * The execFans function executes the execFans exec states. * @details Inputs: fansExecState * @details Outputs: fansExecState * @return none *************************************************************************/ void execFans( void ) { switch ( fansExecState ) { case FANS_EXEC_STATE_START: fansExecState = handleExecStateStart(); break; case FANS_EXEC_STATE_RUN_STATE: fansExecState = handleExecStateRun(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_FAN_INVALID_EXEC_STATE, fansExecState ); fansExecState = FANS_EXEC_STATE_RUN_STATE; break; } // Convert the counts to RPM convertTogglePeriod2RPM(); // Monitor the RPM of the fans monitorFans(); publishFansData(); } /*********************************************************************//** * @brief * The getFanRPM function returns the RPM a the selected fan. * @details Inputs: fansStatus * @details Outputs: none * @param selected fan to read its RPM * @return RPM of the selected fan *************************************************************************/ F32 getMeasuredFanRPM( FAN_NAMES_T fan ) { F32 rpm; // Check if the called fan is in range if ( fan < NUM_OF_FANS_NAMES ) { // Assume there is no override rpm = fansStatus.rpm[ fan ].data; if ( OVERRIDE_KEY == fansStatus.rpm[ fan ].override ) { rpm = fansStatus.rpm[ fan ].ovData; } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FAN_SELECTED, fan ); } return rpm; } /*********************************************************************//** * @brief * The handleFansExecStateStart function handles the start state of the * fans exec state machine. * @details Inputs: none * @details Outputs: none * @return the next state of the exec state machine *************************************************************************/ static FANS_EXEC_STATES_T handleExecStateStart( void ) { FANS_EXEC_STATES_T state = FANS_EXEC_STATE_RUN_STATE; // Start the fans with minimum PWM. The control will decide the next PWM automatically. setInletFansDutyCycle( FANS_MIN_DUTY_CYCLE ); setOutletFansDutyCycle( FANS_MIN_DUTY_CYCLE ); return state; } /*********************************************************************//** * @brief * The handleFansExecStateRun function handles the run state of the * fans exec state machine. * @details Inputs: fansStatus, fansControlCounter * @details Outputs: fansStatus, fansControlCounter * @return the next state of the exec state machine *************************************************************************/ static FANS_EXEC_STATES_T handleExecStateRun( void ) { FANS_EXEC_STATES_T state = FANS_EXEC_STATE_RUN_STATE; // Check if it is time to check for the control and the duty cycle override is in the reset mode so the duty cycle // is not overridden if ( ( ++fansControlCounter > FANS_CONTROL_INTERVAL ) && ( OVERRIDE_RESET == fansStatus.dutyCycle.override ) ) { // Get the maximum temperature among all the thermistors and temperature sensors to run fan from the hottest temperature F32 temperature = getMaximumTemperature(); // Solve the linear equation to calculate the duty cycle from temperature F32 dutyCycle = ( SLOPE * ( temperature - MIN_ALLOWED_AMBIENT_TEMPERATURE ) ) + FANS_MIN_DUTY_CYCLE; // Check whether the duty cycle is not outside of the range and cap it if needed if ( dutyCycle < FANS_MIN_DUTY_CYCLE ) { dutyCycle = FANS_MIN_DUTY_CYCLE; } if ( dutyCycle > FANS_MAX_DUTY_CYCLE ) { dutyCycle = FANS_MAX_DUTY_CYCLE; } // If the fans calculated duty cycle is greater than the previous calculated duty cycle, we are ramping up // otherwise, we are ramping down if ( dutyCycle >= fansStatus.dutyCycle.data ) { // If the delta duty cycle from the previous duty cycle is greater than the max allowed ramp up duty cycle, // otherwise, only add the delta duty cycle if ( ( dutyCycle - fansStatus.dutyCycle.data ) >= FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE ) { fansStatus.dutyCycle.data += FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE; } else { fansStatus.dutyCycle.data = dutyCycle; } } else { // If the delta duty cycle from the previous duty cycle is greater than the max allowed ramp down duty cycle, // otherwise, only add the delta duty cycle if ( ( fansStatus.dutyCycle.data - dutyCycle ) >= FANS_MAX_ALLOWED_RAMP_DOWN_DELTA_DUTY_CYCLE ) { // If we are ramping down, set the target duty cycle to max allowed ramp down duty cycle fansStatus.dutyCycle.data -= FANS_MAX_ALLOWED_RAMP_DOWN_DELTA_DUTY_CYCLE; } else { fansStatus.dutyCycle.data = dutyCycle; } } // Calculate the target RPM for the the duty cycle fansStatus.targetRPM = fansStatus.dutyCycle.data * FANS_MAX_ALLOWED_RPM; // Set the PWM to inlet and outlet fans setInletFansDutyCycle( fansStatus.dutyCycle.data ); setOutletFansDutyCycle( fansStatus.dutyCycle.data ); // Reset the counter fansControlCounter = 0; } else if ( OVERRIDE_KEY == fansStatus.dutyCycle.override ) { // Set the PWM to inlet and outlet fans setInletFansDutyCycle( fansStatus.dutyCycle.ovData ); setOutletFansDutyCycle( fansStatus.dutyCycle.ovData ); } return state; } /*********************************************************************//** * @brief * The setInletFansPWM function sets the inlet fans PWM. * @details Inputs: none * @details Outputs: none * @param PWM that will be set * @return none *************************************************************************/ static void setInletFansDutyCycle( F32 pwm ) { etpwmSetCmpA( etpwmREG6, (U32)( (S32)( ( pwm * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); } /*********************************************************************//** * @brief * The setOutletFansPWM function sets the outlet fans PWM. * @details Inputs: none * @details Outputs: none * @param PWM that will be set * @return none ************************************************************************/ static void setOutletFansDutyCycle( F32 pwm ) { etpwmSetCmpB( etpwmREG6, (U32)( (S32)( ( pwm * (F32)(etpwmREG6->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); } /*********************************************************************//** * @brief * The getMaximumTemperature function runs through the thermistors driver * and finds the maximum temperature. * @details Inputs: none * @details Outputs: none * @return maximum temperature of the thermistors and sensors ************************************************************************/ static F32 getMaximumTemperature( void ) { F32 temperature = 0.0F; F32 maxTemperature = 0.0F; THERMISTORS_TEMP_SENSORS_T thermistor; // Loop through the sensors and thermistors for ( thermistor = THERMISTOR_ONBOARD_NTC; thermistor < NUM_OF_THERMISTORS; thermistor++ ) { temperature = getThermistorTemperatureValue( thermistor ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); } // The temperature sensors that are on the hardware and are not on the fluid path are used to // decide the maximum temperature temperature = getTemperatureValue( TEMPSENSORS_FPGA_BOARD_SENSOR ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); temperature = getTemperatureValue( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); return maxTemperature; } /*********************************************************************//** * @brief * The convertTogglePeriod2RPM function runs through the list of the fans * to get the FPGA pulse from them and converts them to RPM. * @details Inputs: none * @details Outputs: fansStatus * @return none ************************************************************************/ static void convertTogglePeriod2RPM( void ) { FAN_NAMES_T fan; U32 togglePeriods[ NUM_OF_FANS_NAMES ]; togglePeriods[ FAN_INLET_1 ] = getFPGAInletFan1TogglePeriod(); togglePeriods[ FAN_INLET_2 ] = getFPGAInletFan2TogglePeriod(); togglePeriods[ FAN_INLET_3 ] = getFPGAInletFan3TogglePeriod(); togglePeriods[ FAN_OUTLET_1 ] = getFPGAOutletFan1TogglePeriod(); togglePeriods[ FAN_OUTLET_2 ] = getFPGAOutletFan2TogglePeriod(); togglePeriods[ FAN_OUTLET_3 ] = getFPGAOutletFan3TogglePeriod(); for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ ) { // If the pulse is close to 0 or 0, FPGA will report 0xFFFF // Otherwise, convert the pulse to RPM if ( togglePeriods[ fan ] == FANS_ZERO_RPM_TOGGLE_PERIOD_VALUE ) { fansStatus.rpm[ fan ].data = 0; } else { // Convert toggle period to RPM fansStatus.rpm[ fan ].data = TOGGLE_PERIOD_2_RPM_COEFFICIENT / togglePeriods[ fan ]; } } } /*********************************************************************//** * @brief * The monitorFans function monitors the fans for RPM. * @details Inputs: rpmAlarmStartTimer, hasAlarmBeenRaised * @details Outputs: rpmAlarmStartTimer, hasAlarmBeenRaised * @return none *************************************************************************/ static void monitorFans( void ) { FAN_NAMES_T fan; F32 rpm = 0.0F; BOOL isAlarmTriggered = FALSE; BOOL isFanRPMOutOfRange = FALSE; // The RPM is expected to be 5500 @ 100% duty cycle // The nominal RPM = duty cycle * 5500 / 1.0 // The RPM tolerance is -25% to +50% of the nominal RPM F32 dutyCycle = getF32OverrideValue( &fansStatus.dutyCycle ); F32 fansNominalRPM = dutyCycle * FANS_MAX_ALLOWED_RPM; F32 fansMinAllowedRPM = fansNominalRPM - ( fansNominalRPM * FANS_MIN_RPM_OUT_OF_RANGE_TOL ); F32 fansMaxAllowedRPM = fansNominalRPM + ( fansNominalRPM * FANS_MAX_RPM_OUT_OF_RANGE_TOL ); for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ ) { rpm = getMeasuredFanRPM( fan ); isFanRPMOutOfRange |= ( ( rpm < fansMinAllowedRPM ) || ( ( rpm > fansMaxAllowedRPM ) ) ? TRUE : FALSE ); } // If the fans alarm has been raised already, do not raise again if ( FALSE == hasAlarmBeenRaised ) { isAlarmTriggered = isPersistentAlarmTriggered( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, isFanRPMOutOfRange ); if ( TRUE == isAlarmTriggered ) { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, rpm ) // Set the alarm flag to TRUE hasAlarmBeenRaised = TRUE; // If the alarm has been raised but the start time of the alarm has not been set, set the alarm start timer if ( 0 == rpmAlarmStartTime ) { rpmAlarmStartTime = getMSTimerCount(); } } } // If the alarm has been raised and the alarm has been silent for at least a day, set the flag to FALSE // This way, if the fans RPM are out of range the alarm will be raised again. This alarm is supposed to be raised // and remain silent for a defined period of time. else { S32 elapsedTime = rpmAlarmStartTime - rpmAlarmStartTimeOffset; if ( calcTimeSince( elapsedTime ) >= SECONDS_IN_A_DAY * MS_PER_SECOND ) { hasAlarmBeenRaised = FALSE; rpmAlarmStartTime = 0; rpmAlarmStartTimeOffset = 0; } } } /*********************************************************************//** * @brief * The publishFansData function publishes the fans data at the specified * time interval. * @details Inputs: fansPublishCounter, fansPublishInterval * @details Outputs: fansPublishCounter * @return none *************************************************************************/ static void publishFansData( void ) { if ( ++fansPublishCounter >= getU32OverrideValue( &fansPublishInterval ) ) { FANS_DATA_T fansData; fansData.dutyCycle = ( OVERRIDE_RESET == fansStatus.dutyCycle.override ? fansStatus.dutyCycle.data : fansStatus.dutyCycle.ovData ) * FRACTION_TO_PERCENT_FACTOR; fansData.targetFansRPM = fansStatus.targetRPM; fansData.fanInlet1RPM = getMeasuredFanRPM( FAN_INLET_1 ); fansData.fanInlet2RPM = getMeasuredFanRPM( FAN_INLET_2 ); fansData.fanInlet3RPM = getMeasuredFanRPM( FAN_INLET_3 ); fansData.fanOutlet1RPM = getMeasuredFanRPM( FAN_OUTLET_1 ); fansData.fanOutlet2RPM = getMeasuredFanRPM( FAN_OUTLET_2 ); fansData.fanOutlet3RPM = getMeasuredFanRPM( FAN_OUTLET_3 ); fansData.rpmAlarmTimeOffset = calcTimeSince( rpmAlarmStartTime - rpmAlarmStartTimeOffset ); broadcastData( MSG_ID_DG_FANS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&fansData, sizeof( FANS_DATA_T ) ); fansPublishCounter = 0; } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetFanPublishIntervalOverride function overrides the fans data * publish interval. * @details Inputs: fansPublishInterval * @details Outputs: fansPublishInterval * @param value : override fans data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetFanPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_GENERAL_INTERVAL; result = TRUE; fansPublishInterval.ovData = intvl; fansPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetFanPublishIntervalOverride function resets the override * of the fans data publish interval. * @details Inputs: fansPublishInterval * @details Outputs: fansPublishInterval * @return TRUE if override reset successful, FALSE if not ************************************************************************/ BOOL testResetFanPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; fansPublishInterval.override = OVERRIDE_RESET; fansPublishInterval.ovData = fansPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetFanRPMOverride function overrides the RPM of a fan. * @details Inputs: none * @details Outputs: fansStatus * @param fanId fan ID * @param rpm the RPM override value * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetFanRPMOverride( U32 fanId, F32 rpm ) { BOOL result = FALSE; if ( fanId < NUM_OF_FANS_NAMES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; fansStatus.rpm[ fanId ].ovData = rpm; fansStatus.rpm[ fanId ].override = OVERRIDE_KEY; } } return result; } /*********************************************************************//** * @brief * The testResetFanRPMOverride function resets the override value of a fan. * @details Inputs: fansStatus * @details Outputs: fansStatus * @param fanId fan index * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetFanRPMOverride( U32 fanId ) { BOOL result = FALSE; if ( fanId < NUM_OF_FANS_NAMES ) { if ( TRUE == isTestingActivated() ) { result = TRUE; fansStatus.rpm[ fanId ].ovData = fansStatus.rpm[ fanId ].ovInitData; fansStatus.rpm[ fanId ].override = OVERRIDE_RESET; } } return result; } /*********************************************************************//** * @brief * The testSetFanRPMAlarmStartTimestamp function set the fan RPM alarm start * time offset. * @details Inputs: none * @details Outputs: rpmAlarmStartTimeOffset * @param milliSeconds the milliseconds the time to be offset * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetFanRPMAlarmStartTimestamp( U32 milliSeconds ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { rpmAlarmStartTimeOffset = milliSeconds; result = TRUE; } return result; } /*********************************************************************//** * @brief * The testSetFansDutyCycleOverride function overrides fans duty cycle * @details Inputs: none * @details Outputs: fansStatus * @param value the duty cycle value to be overridden * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetFansDutyCycleOverride( F32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { if( ( value >= FANS_MIN_DUTY_CYCLE ) && ( value <= FANS_MAX_DUTY_CYCLE ) ) { fansStatus.dutyCycle.ovData = value; fansStatus.dutyCycle.override = OVERRIDE_KEY; result = TRUE; } } return result; } /*********************************************************************//** * @brief * The testResetFansDutyCycleOverride function resets the fans duty cycle * override * @details Inputs: none * @details Outputs: fansStatus * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetFansDutyCycleOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { fansStatus.dutyCycle.override = OVERRIDE_RESET; fansStatus.dutyCycle.ovData = 0.0; result = TRUE; } return result; } /**@}*/