Index: Utilities.c =================================================================== diff -u -rc639b7a9238140949b634e8a920973f6b0699776 -r0f1d0c443daee3e30ae823711e85f3410bbf49fe --- Utilities.c (.../Utilities.c) (revision c639b7a9238140949b634e8a920973f6b0699776) +++ Utilities.c (.../Utilities.c) (revision 0f1d0c443daee3e30ae823711e85f3410bbf49fe) @@ -1,19 +1,19 @@ -/************************************************************************** - * - * Copyright (c) 2019-2020 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 Utilities.c - * - * @date 23-Oct-2019 - * @author S. Nash - * - * @brief Utilities service module. Provides miscellaneous utility \n - * functions. - * - **************************************************************************/ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 Utilities.c +* +* @author (last) Quang Nguyen +* @date (last) 23-Nov-2020 +* +* @author (original) Sean +* @date (original) 17-Feb-2020 +* +***************************************************************************/ #include "Common.h" #include "Timers.h" @@ -26,8 +26,12 @@ // ********** private definitions ********** -#define INITIAL_CRC16_VAL 0xFFFF ///< Seed for 16-bit CRC function. -#define INITIAL_CRC08_VAL 0x00 ///< Seed for 8-bit CRC function. +#define INITIAL_CRC16_VAL 0xFFFF ///< Seed for 16-bit CRC function +#define INITIAL_CRC08_VAL 0x00 ///< Seed for 8-bit CRC function + +#define ASCII_CODE_LETTER_A 0x41 ///< ASCII code in hex for letter A. +#define ASCII_CODE_NUMBER_ZERO 0x30 ///< ASCII code in hex for number zero. +#define ASCII_CODE_NUMBER_SEVEN 0x37 ///< ASCII code in hex for number seven. // ********** private data ********** @@ -89,23 +93,22 @@ }; // variables for time windowed counts (counts # of instances in a specific window of time) -static BOOL timeWindowedCountsInitialized[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Initialized flags for time windowed counts. -static U32 timeWindowedCountsMaxCount[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Max. counts for time windowed counts. -static U32 timeWindowedCountsWindowMs[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Time windows (in ms) for time windowed counts. -static U32 timeWindowedCounts[ NUM_OF_TIME_WINDOWED_COUNTS ][ MAX_TIME_WINDOWED_COUNT ]; ///< Time stamps for instances for time windowed counts. -static U32 timeWindowedCountIndexes[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< List indexes for time windowed counts. -static U32 timeWindowedCountCounts[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Current counts for time windowed counts. - +static BOOL timeWindowedCountsInitialized[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Initialized flags for time windowed counts +static U32 timeWindowedCountsMaxCount[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Max. counts for time windowed counts +static U32 timeWindowedCountsWindowMs[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Time windows (in ms) for time windowed counts +static U32 timeWindowedCounts[ NUM_OF_TIME_WINDOWED_COUNTS ][ MAX_TIME_WINDOWED_COUNT ]; ///< Time stamps for instances for time windowed counts +static U32 timeWindowedCountIndexes[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< List indexes for time windowed counts +static U32 timeWindowedCountCounts[ NUM_OF_TIME_WINDOWED_COUNTS ]; ///< Current counts for time windowed counts + /*********************************************************************//** * @brief - * The crc16 function calculates a 16-bit CRC for a given range of bytes \n - * in memory. Poly = 0x1021. Not reflected. Initial value = 0xFFFF. - * @details - * Inputs : none - * Outputs : none - * @param address : pointer to start address of memory range to calculate CRC for - * @param len : # of bytes in the memory range to calculate CRC for - * @return CRC + * The crc16 function calculates a 16-bit CRC for a given range of bytes + * in memory. Poly = 0x1021. Not reflected. Initial value = 0xFFFF. + * @details Inputs: crc16_table[] + * @details Outputs: none + * @param address pointer to start address of memory range to calculate CRC for + * @param len number of bytes in the memory range to calculate CRC for + * @return CRC as a U16 *************************************************************************/ U16 crc16( const U08 *address, U32 len ) { @@ -122,14 +125,13 @@ /*********************************************************************//** * @brief - * The crc8 function calculates a 8-bit CRC for a given range of bytes \n + * The crc8 function calculates a 8-bit CRC for a given range of bytes * in memory. - * @details - * Inputs : none - * Outputs : none - * @param address : pointer to start address of memory range to calculate CRC for - * @param len : # of bytes in the memory range to calculate CRC for - * @return CRC + * @details Inputs: crc8_table[] + * @details Outputs: none + * @param address pointer to start address of memory range to calculate CRC for + * @param len number of bytes in the memory range to calculate CRC for + * @return CRC as a U08 *************************************************************************/ U08 crc8( const U08 *address, U32 len ) { @@ -142,17 +144,47 @@ } return crc; +} + +/*********************************************************************//** + * @brief + * The u32DiffWithWrap function calculates the difference between two given + * unsigned 32-bit numbers. If the second (ending) number is less than the + * first (starting) number, then the difference is calculated with a wrap past + * 32-bit full scale to zero. + * @details Inputs: none + * @details Outputs: none + * @param start first number to compute difference for + * @param end second number to compute difference for + * @return the difference between the two given numbers + *************************************************************************/ +U32 u32DiffWithWrap( U32 start, U32 end ) +{ + U32 result; + + // no wrap + if ( end >= start ) + { + result = end - start; + } + // wrapped + else + { + result = ( 0xFFFFFFFF - start ) + end + 1; + } + + return result; } /*********************************************************************//** * @brief * The initTimeWindowedCount function initializes a given time windowed count. - * @details - * Inputs : none - * Outputs : all time windowed count variables for a given time windowed count are initialized. - * @param cnt : ID of the time windowed count to initialize - * @param maxCnt : maximum number of instances in the time window for this count - * @param winMs : number of ms in the time window for this count + * @details Inputs: timeWindowedCountsMaxCount, timeWindowedCountsInitialized + * @details Outputs: timeWindowedCountsMaxCount, timeWindowedCountsInitialized, alarm if + * software fault occurred + * @param cnt ID of the time windowed count to initialize + * @param maxCnt maximum number of instances in the time window for this count + * @param winMs number of ms in the time window for this count * @return none *************************************************************************/ void initTimeWindowedCount( TIME_WINDOWED_COUNT_T cnt, U32 maxCnt, U32 winMs ) @@ -174,22 +206,38 @@ } else { - timeWindowedCountsInitialized[ cnt ] = FALSE; + if ( cnt < NUM_OF_TIME_WINDOWED_COUNTS ) + { + timeWindowedCountsInitialized[ cnt ] = FALSE; +#ifdef _DG_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_INVALID_WIN_MAX_COUNT, maxCnt ) +#else + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_INVALID_WIN_MAX_COUNT, maxCnt ) +#endif + } + else + { +#ifdef _DG_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_INVALID_WIN_COUNT, cnt ) +#else + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_INVALID_WIN_COUNT, cnt ) +#endif + } } } /*********************************************************************//** * @brief - * The incTimeWindowedCount function adds a new instance to a given time \n - * windowed count. Must call initTimeWindowedCount() prior to calling this \n + * The incTimeWindowedCount function adds a new instance to a given time + * windowed count. Must call initTimeWindowedCount() prior to calling this * function for a given time windowed count. - * *Note - thread protection not provided - assumed function will be called \n + * *Note - thread protection not provided - assumed function will be called * by one task for a given time windowed count. - * @details - * Inputs : timeWindowedCounts[][], timeWindowedCountIndexes[], timeWindowedCountCounts[] - * Outputs : timeWindowedCounts[][], timeWindowedCountIndexes[], timeWindowedCountCounts[] - * @param cnt : ID of the time windowed count to add an instance to - * @return TRUE if this instances brings the count to the maximum within \n + * @details Inputs: timeWindowedCounts, timeWindowedCountIndexes, timeWindowedCountCounts + * @details Outputs: timeWindowedCounts, timeWindowedCountIndexes, timeWindowedCountCounts, + * alarm if a software fault occurred + * @param cnt ID of the time windowed count to add an instance to + * @return TRUE if this instances brings the count to the maximum within * this counts time window, otherwise FALSE *************************************************************************/ BOOL incTimeWindowedCount( TIME_WINDOWED_COUNT_T cnt ) @@ -215,13 +263,179 @@ else { #ifdef _DG_ - SET_ALARM_WITH_1_U32_DATA ( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR ); + SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR, cnt ); #else - SET_ALARM_WITH_1_U32_DATA ( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR ); + SET_ALARM_WITH_2_U32_DATA ( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_UTIL_TIME_WINDOWED_COUNT_ERROR, cnt ); #endif } return result; +} + +/*********************************************************************//** + * @brief + * The getCriticalData function gets the value for a given critical data + * record. The integrity of the critical data is checked first. If the + * critical data record fails the integrity check, a fault is triggered. + * @details Inputs: none + * @details Outputs: alarm if HD critical error occurred + * @param data Ptr to a critical data record + * @return The data from a critical data record + *************************************************************************/ +CRITICAL_DATAS_T getCriticalData( CRITICAL_DATA_T *data ) +{ + CRITICAL_DATAS_T result; + CRITICAL_DATA_T d; + + _disable_IRQ(); + d = *data; + _enable_IRQ(); + + result = d.data; + // verify data integrity + if ( ( ~d.data.uInt != d.comp ) || + ( isCriticalDataInRange( &d ) != TRUE ) || + ( d.set != TRUE ) || + ( data->typ >= NUM_OF_CRITICAL_DATA_TYPES ) ) + { + result.uInt = 0; +#ifdef _DG_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_CRITICAL_DATA_ERROR, (U32)&data[0], 0 ) +#else + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_CRITICAL_DATA_ERROR, (U32)&data[0], 0 ) +#endif + } + + return result; +} + +/*********************************************************************//** + * @brief + * The isCriticalDataInRange function determines whether a critical data + * value is within the range set for that critical data. + * @details Inputs: none + * @details Outputs: none + * @param data Ptr to a critical data record + * @return TRUE if given data is in range, FALSE if not + *************************************************************************/ +BOOL isCriticalDataInRange( CRITICAL_DATA_T *data ) +{ + BOOL result = FALSE; + + if ( CRITICAL_DATA_TYPE_F32 == data->typ ) + { + if ( ( data->data.sFlt >= data->minimum.sFlt ) && ( data->data.sFlt <= data->maximum.sFlt ) ) + { + result = TRUE; + } + } + else if ( CRITICAL_DATA_TYPE_S32 == data->typ ) + { + if ( ( data->data.sInt >= data->minimum.sInt ) && ( data->data.sInt <= data->maximum.sInt ) ) + { + result = TRUE; + } + } + else + { + if ( ( data->data.uInt >= data->minimum.uInt ) && ( data->data.uInt <= data->maximum.uInt ) ) + { + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setCriticalData function sets the value for a given critical data + * record. + * @details Inputs: none + * @details Outputs: alarm if HD critical error occurred + * @param data Ptr to a critical data record + * @param value a value to set + * @return TRUE if set was successful, FALSE if not (out of range) + *************************************************************************/ +BOOL setCriticalData( CRITICAL_DATA_T *data, CRITICAL_DATAS_T value ) +{ + BOOL result = FALSE; + + if ( data->typ < NUM_OF_CRITICAL_DATA_TYPES ) + { + CRITICAL_DATA_T tmp = *data; + + // test set on temporary data record so it can have its range pre-checked + tmp.data = value; + if ( TRUE == isCriticalDataInRange( &tmp ) ) + { + _disable_IRQ(); + data->data = value; + data->comp = ~data->data.uInt; + data->set = TRUE; + _enable_IRQ(); + result = TRUE; + } + } + else + { +#ifdef _DG_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_CRITICAL_DATA_ERROR, (U32)&data[0], 1 ) +#else + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_CRITICAL_DATA_ERROR, (U32)&data[0], 1 ) +#endif + } + + return result; +} + +/*********************************************************************//** + * @brief + * The resetCriticalData function resets a critical data record. + * @details Inputs: none + * @details Outputs: Given critical data record is reset to unset w/ default value. + * @param data Ptr to a critical data record + * @return none + *************************************************************************/ +void resetCriticalData( CRITICAL_DATA_T *data ) +{ + _disable_IRQ(); + data->set = FALSE; + data->data.uInt = data->defValue.uInt; + data->comp = ~data->data.uInt; + _enable_IRQ(); } + +/*********************************************************************//** + * @brief + * The hexStrToDec function convert hex string to decimal value. + * @details Inputs: none + * @details Outputs: none + * @param valuePtr pointer to hex string to convert + * @param size size of the hex string to convert + * @return converted value of hex string + *************************************************************************/ +U32 hexStrToDec( U08 const * const valuePtr, U08 size ) +{ + U08 ii; + U08 value; + U32 result = 0; + + for ( ii = 0; ii < size; ++ii ) + { + if ( valuePtr[ii] < ASCII_CODE_LETTER_A ) + { + value = ( valuePtr[ii] - ASCII_CODE_NUMBER_ZERO ); + result = ( result << 4 ) | value; + } + else + { + value = ( valuePtr[ii] - ASCII_CODE_NUMBER_SEVEN ); + result = ( result << 4 ) | value; + } + } + + return result; +} /**@}*/