Index: firmware/App/Controllers/Fans.c =================================================================== diff -u -r09e6cf9de34acf18f6e1138bf56ac0edb4821186 -r68aefeff8890cdfa956c7bfdf0d4505b4ac25cb7 --- firmware/App/Controllers/Fans.c (.../Fans.c) (revision 09e6cf9de34acf18f6e1138bf56ac0edb4821186) +++ firmware/App/Controllers/Fans.c (.../Fans.c) (revision 68aefeff8890cdfa956c7bfdf0d4505b4ac25cb7) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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. @@ -51,7 +51,6 @@ #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_MONITOR_INTERVAL_COUNT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans monitor time interval in counts. #define FANS_MIN_RPM_OUT_OF_RANGE_TOL 0.25 ///< Fans min RPM out of range tolerance. #define FANS_MAX_RPM_OUT_OF_RANGE_TOL 0.5 ///< Fans max RPM out of range tolerance. @@ -73,52 +72,57 @@ static FAN_STATUS_T fansStatus; ///< Fans status. static FANS_EXEC_STATES_T fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE; ///< Fans exec state. -static U32 fansControlCounter = 0; ///< Fans control interval counter. -static U32 fansPublishCounter = 0; ///< Fans data publish interval counter. -static U32 fansMonitorCounter = 0; ///< Fans monitor interval counter. +static U32 fansControlCounter = 0; ///< Fans control interval counter. +static U32 fansPublishCounter = 0; ///< Fans data publish interval counter. static BOOL isPOSTComplete = FALSE; ///< Flag that indicates whether POST is complete or not. static BOOL hasAlarmBeenRaised = FALSE; ///< Flag that indicates whether RPM out of range alarm has been raised once. -static U32 rpmAlarmStartTimer = 0; ///< RPM out of range alarm start timer when the alarm is raised. +static OVERRIDE_U32_T rpmAlarmStartTimeOffset = { 0, 0, 0, 0}; ///< RPM out of range alarm start time offset. +static U32 rpmAlarmStartTime = 0; ///< RPM alarm start time. /// 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 +static OVERRIDE_U32_T fansPublishInterval = { FANS_DATA_PUBLISH_INTERVAL, + FANS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Fans publish time interval override static FANS_EXEC_STATES_T handleExecStateWaitForPOST( void ); static FANS_EXEC_STATES_T handleExecStateRun( void ); static void setInletFansDutyCycle( F32 pwm ); -static F32 getMaximumTemperature( void ); +static F32 getMaximumTemperature( void ); static void convertTogglePeriod2RPM( void ); static void monitorFans( void ); -static U32 getPublishFansDataInterval( void ); +static U32 getPublishFansDataInterval( void ); +static U32 getRPMAlarmStartTimeOffset( void ); static void publishFansData( void ); /*********************************************************************//** * @brief * The initFans function initializes the fans module. * @details Inputs: none - * @details Outputs: fansExecState, fansMonitorCounter, fansControlCounter, + * @details Outputs: fansExecState, fansControlCounter, * fansPublishCounter, isPOSTComplete, hasAlarmBeenRaised, fansStatus, - * rpmAlarmStartTimer + * rpmAlarmStartTime, rpmAlarmStartTimeOffset * @return none *************************************************************************/ void initFans( void ) { FAN_NAMES_T fan; // Initialize the variables - fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE; - fansControlCounter = 0; - fansPublishCounter = 0; - fansMonitorCounter = 0; - isPOSTComplete = FALSE; - hasAlarmBeenRaised = FALSE; - rpmAlarmStartTimer = 0; + fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE; + fansControlCounter = 0; + fansPublishCounter = 0; + isPOSTComplete = FALSE; + hasAlarmBeenRaised = FALSE; + rpmAlarmStartTime = 0; + rpmAlarmStartTimeOffset.data = 0; + rpmAlarmStartTimeOffset.ovData = 0; + rpmAlarmStartTimeOffset.ovInitData = 0; + rpmAlarmStartTimeOffset.override = 0; // Initialize the fans for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ ) @@ -186,6 +190,7 @@ // Monitor the RPM of the fans monitorFans(); + // Check for the publication time publishFansData(); } @@ -348,18 +353,18 @@ F32 maxTemperature = 0.0; - // NOTE: a for loop was not used because the venous pressure sensor's temperature + // NOTE: A for loop was not used because the venous pressure sensor's temperature // is not used as one of temperature values to decide the hottest temperature - temperature = getTemperatureValue( THERMISTOR_ONBOARD_NTC ); + temperature = getTemperatureValue( THERMISTOR_ONBOARD_NTC ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); - temperature = getTemperatureValue( THERMISTOR_POWER_SUPPLY_1 ); + temperature = getTemperatureValue( THERMISTOR_POWER_SUPPLY_1 ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); - temperature = getTemperatureValue( TEMPSENSOR_FPGA_BOARD_SENSOR ); + temperature = getTemperatureValue( TEMPSENSOR_FPGA_BOARD_SENSOR ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); - temperature = getTemperatureValue( TEMPSENSOR_PBA_ADC_SENSOR ); + temperature = getTemperatureValue( TEMPSENSOR_PBA_ADC_SENSOR ); maxTemperature = ( temperature > maxTemperature ? temperature : maxTemperature ); return maxTemperature; @@ -399,59 +404,74 @@ /*********************************************************************//** * @brief * The monitorFans function monitors the fans for RPM. - * @details Inputs: fansMonitorCounter, rpmAlarmStartTimer, hasAlarmBeenRaised - * @details Outputs: fansMonitorCounter, hasAlarmBeenRaised, rpmAlarmStartTimer + * @details Inputs: rpmAlarmStartTimer, hasAlarmBeenRaised + * @details Outputs: hasAlarmBeenRaised, rpmAlarmStartTimer * @return none *************************************************************************/ static void monitorFans( void ) { - if ( ++fansMonitorCounter >= FANS_MONITOR_INTERVAL_COUNT ) - { - if ( FALSE == hasAlarmBeenRaised ) - { - FAN_NAMES_T fan; - BOOL isFanRPMOutOfRange = FALSE; - BOOL isAlarmTriggered = FALSE; - F32 rpm = 0.0; + FAN_NAMES_T fan; + BOOL isFanRPMOutOfRange = FALSE; + BOOL isAlarmTriggered = FALSE; + F32 rpm = 0.0; - // 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 fansNominalRPM = fansStatus.targetDutyCycle * 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 ); + // 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 fansNominalRPM = fansStatus.targetDutyCycle * 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 ); - } + // Loop through the fans and make sure the each of them have RPM in range + for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ ) + { + rpm = getMeasuredFanRPM( fan ); + isFanRPMOutOfRange |= ( ( rpm < fansMinAllowedRPM ) || ( rpm > fansMaxAllowedRPM ) ? TRUE : FALSE ); + } - isAlarmTriggered = isPersistentAlarmTriggered( ALARM_ID_HD_FAN_RPM_OUT_OF_RANGE, isFanRPMOutOfRange ); + if ( FALSE == hasAlarmBeenRaised ) + { + isAlarmTriggered = isPersistentAlarmTriggered( ALARM_ID_HD_FAN_RPM_OUT_OF_RANGE, isFanRPMOutOfRange ); - if ( TRUE == isAlarmTriggered ) - { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_FAN_RPM_OUT_OF_RANGE, rpm ) - // Set the alarm flag to TRUE - hasAlarmBeenRaised = TRUE; - } - // If the alarm has been raised but the time that the alarm has not been set, set the alarm start timer - if ( ( TRUE == hasAlarmBeenRaised ) && ( 0 == rpmAlarmStartTimer ) ) - { - rpmAlarmStartTimer = getMSTimerCount(); - } + if ( TRUE == isAlarmTriggered ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_FAN_RPM_OUT_OF_RANGE, rpm ) + // Set the alarm flag to TRUE + hasAlarmBeenRaised = TRUE; } - // 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 define period of time. - else if ( ( TRUE == hasAlarmBeenRaised ) && ( TRUE == didTimeout( rpmAlarmStartTimer, SECONDS_IN_A_DAY ) ) ) + // If the alarm has been raised but the start time of the alarm has not been set, set the alarm start timer + if ( ( TRUE == hasAlarmBeenRaised ) && ( 0 == rpmAlarmStartTime ) ) { - hasAlarmBeenRaised = FALSE; - rpmAlarmStartTimer = 0; + 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 if ( ( TRUE == hasAlarmBeenRaised ) && ( ( calcTimeSince( rpmAlarmStartTime ) + getRPMAlarmStartTimeOffset() ) >= SECONDS_IN_A_DAY * MS_PER_SECOND ) ) + { + hasAlarmBeenRaised = FALSE; + rpmAlarmStartTime = 0; + } +} - fansMonitorCounter = 0; +/*********************************************************************//** + * @brief + * The getRPMAlarmStartTimeOffset function gets the RPM alarm start time offset in MS. + * @details Inputs: rpmAlarmStartTimeOffset + * @details Outputs: none + * @return the RPM alarm start time offset + *************************************************************************/ +static U32 getRPMAlarmStartTimeOffset( void ) +{ + U32 startTime = rpmAlarmStartTimeOffset.data; + + if ( OVERRIDE_KEY == rpmAlarmStartTimeOffset.override ) + { + startTime = rpmAlarmStartTimeOffset.ovData; } + + return startTime; } /*********************************************************************//** @@ -485,13 +505,14 @@ { if ( ++fansPublishCounter > getPublishFansDataInterval() ) { - FANS_DATA_T fansData; + FANS_DATA_T data; - fansData.fansDutyCycle = fansStatus.targetDutyCycle * FRACTION_TO_PERCENT_FACTOR; - fansData.fansTargetRPM = fansStatus.targetRPM; - fansData.fanInlet1RPM = getMeasuredFanRPM( FAN_INLET_1 ); + data.fansDutyCycle = fansStatus.targetDutyCycle * FRACTION_TO_PERCENT_FACTOR; + data.fansTargetRPM = fansStatus.targetRPM; + data.fanInlet1RPM = getMeasuredFanRPM( FAN_INLET_1 ); + data.rpmAlarmTimeOffset = getRPMAlarmStartTimeOffset(); - broadcastData( MSG_ID_HD_FANS_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&fansData, sizeof( FANS_DATA_T ) ); + broadcastData( MSG_ID_HD_FANS_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( FANS_DATA_T ) ); fansPublishCounter = 0; } @@ -601,5 +622,54 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetFanRPMAlarmStartTimeOffsetOverride function overrides the RPM alarm + * start time offset. + * @details Inputs: none + * @details Outputs: rpmAlarmStartTimeOffset + * @param hours hours to override + * @param minutes minutes to override + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetFanRPMAlarmStartTimeOffsetOverride( U32 hours, U32 minutes ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + rpmAlarmStartTimeOffset.ovData = rpmAlarmStartTimeOffset.ovData + ( ( hours * MIN_PER_HOUR * SEC_PER_MIN ) + ( minutes * SEC_PER_MIN ) ) * MS_PER_SECOND; + rpmAlarmStartTimeOffset.override = OVERRIDE_KEY; + + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetFanRPMAlarmStartTimeOffsetOverride function resets the RPM alarm + * start time offset override. + * @details Inputs: none + * @details Outputs: rpmAlarmStartTimeOffset + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetFanRPMAlarmStartTimeOffsetOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + rpmAlarmStartTimeOffset.override = OVERRIDE_RESET; + rpmAlarmStartTimeOffset.ovData = 0; + rpmAlarmStartTimeOffset.data = 0; + + result = TRUE; + } + + return result; +} + /**@}*/