Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_WallbotBLE_Challenge by
app_util.h
00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 /** @file 00014 * 00015 * @defgroup app_util Utility Functions and Definitions 00016 * @{ 00017 * @ingroup app_common 00018 * 00019 * @brief Various types and definitions available to all applications. 00020 */ 00021 00022 #ifndef APP_UTIL_H__ 00023 #define APP_UTIL_H__ 00024 00025 #include <stdint.h> 00026 #include <stdbool.h> 00027 #include "compiler_abstraction.h" 00028 00029 enum 00030 { 00031 UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */ 00032 UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */ 00033 UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */ 00034 }; 00035 00036 /**@brief Macro for doing static (i.e. compile time) assertion. 00037 * 00038 * @note If the assertion fails when compiling using Keil, the compiler will report error message 00039 * "error: #94: the size of an array must be greater than zero" (while gcc will list the 00040 * symbol static_assert_failed, making the error message more readable). 00041 * If the supplied expression can not be evaluated at compile time, Keil will report 00042 * "error: #28: expression must have a constant value". 00043 * 00044 * @note The macro is intentionally implemented not using do while(0), allowing it to be used 00045 * outside function blocks (e.g. close to global type- and variable declarations). 00046 * If used in a code block, it must be used before any executable code in this block. 00047 * 00048 * @param[in] EXPR Constant expression to be verified. 00049 */ 00050 00051 #if defined(__GNUC__) 00052 #define STATIC_ASSERT(EXPR) typedef char __attribute__((unused)) static_assert_failed[(EXPR) ? 1 : -1] 00053 #else 00054 #define STATIC_ASSERT(EXPR) typedef char static_assert_failed[(EXPR) ? 1 : -1] 00055 #endif 00056 00057 00058 /**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */ 00059 typedef uint8_t uint16_le_t[2]; 00060 00061 /**@brief type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */ 00062 typedef uint8_t uint32_le_t[4]; 00063 00064 /**@brief Byte array type. */ 00065 typedef struct 00066 { 00067 uint16_t size; /**< Number of array entries. */ 00068 uint8_t * p_data; /**< Pointer to array entries. */ 00069 } uint8_array_t; 00070 00071 /**@brief Perform rounded integer division (as opposed to truncating the result). 00072 * 00073 * @param[in] A Numerator. 00074 * @param[in] B Denominator. 00075 * 00076 * @return Rounded (integer) result of dividing A by B. 00077 */ 00078 #define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) 00079 00080 /**@brief Check if the integer provided is a power of two. 00081 * 00082 * @param[in] A Number to be tested. 00083 * 00084 * @return true if value is power of two. 00085 * @return false if value not power of two. 00086 */ 00087 #define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) 00088 00089 /**@brief To convert ticks to millisecond 00090 * @param[in] time Number of millseconds that needs to be converted. 00091 * @param[in] resolution Units to be converted. 00092 */ 00093 #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) 00094 00095 00096 /**@brief Perform integer division, making sure the result is rounded up. 00097 * 00098 * @details One typical use for this is to compute the number of objects with size B is needed to 00099 * hold A number of bytes. 00100 * 00101 * @param[in] A Numerator. 00102 * @param[in] B Denominator. 00103 * 00104 * @return Integer result of dividing A by B, rounded up. 00105 */ 00106 #define CEIL_DIV(A, B) \ 00107 /*lint -save -e573 */ \ 00108 ((((A) - 1) / (B)) + 1) \ 00109 /*lint -restore */ 00110 00111 /**@brief Function for encoding a uint16 value. 00112 * 00113 * @param[in] value Value to be encoded. 00114 * @param[out] p_encoded_data Buffer where the encoded data is to be written. 00115 * 00116 * @return Number of bytes written. 00117 */ 00118 static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data) 00119 { 00120 p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0); 00121 p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8); 00122 return sizeof(uint16_t); 00123 } 00124 00125 /**@brief Function for encoding a uint32 value. 00126 * 00127 * @param[in] value Value to be encoded. 00128 * @param[out] p_encoded_data Buffer where the encoded data is to be written. 00129 * 00130 * @return Number of bytes written. 00131 */ 00132 static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data) 00133 { 00134 p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0); 00135 p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8); 00136 p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16); 00137 p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24); 00138 return sizeof(uint32_t); 00139 } 00140 00141 /**@brief Function for decoding a uint16 value. 00142 * 00143 * @param[in] p_encoded_data Buffer where the encoded data is stored. 00144 * 00145 * @return Decoded value. 00146 */ 00147 static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data) 00148 { 00149 return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | 00150 (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 )); 00151 } 00152 00153 /**@brief Function for decoding a uint32 value. 00154 * 00155 * @param[in] p_encoded_data Buffer where the encoded data is stored. 00156 * 00157 * @return Decoded value. 00158 */ 00159 static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data) 00160 { 00161 return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | 00162 (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | 00163 (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) | 00164 (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 )); 00165 } 00166 00167 /** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts. 00168 * 00169 * @details The calculation is based on a linearized version of the battery's discharge 00170 * curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and 00171 * is considered to be the lower boundary. 00172 * 00173 * The discharge curve for CR2032 is non-linear. In this model it is split into 00174 * 4 linear sections: 00175 * - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV) 00176 * - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV) 00177 * - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV) 00178 * - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV) 00179 * 00180 * These numbers are by no means accurate. Temperature and 00181 * load in the actual application is not accounted for! 00182 * 00183 * @param[in] mvolts The voltage in mV 00184 * 00185 * @return Battery level in percent. 00186 */ 00187 static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts) 00188 { 00189 uint8_t battery_level; 00190 00191 if (mvolts >= 3000) 00192 { 00193 battery_level = 100; 00194 } 00195 else if (mvolts > 2900) 00196 { 00197 battery_level = 100 - ((3000 - mvolts) * 58) / 100; 00198 } 00199 else if (mvolts > 2740) 00200 { 00201 battery_level = 42 - ((2900 - mvolts) * 24) / 160; 00202 } 00203 else if (mvolts > 2440) 00204 { 00205 battery_level = 18 - ((2740 - mvolts) * 12) / 300; 00206 } 00207 else if (mvolts > 2100) 00208 { 00209 battery_level = 6 - ((2440 - mvolts) * 6) / 340; 00210 } 00211 else 00212 { 00213 battery_level = 0; 00214 } 00215 00216 return battery_level; 00217 } 00218 00219 /**@brief Function for checking if a pointer value is aligned to a 4 byte boundary. 00220 * 00221 * @param[in] p Pointer value to be checked. 00222 * 00223 * @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise. 00224 */ 00225 static __INLINE bool is_word_aligned(void * p) 00226 { 00227 return (((uintptr_t)p & 0x03) == 0); 00228 } 00229 00230 #endif // APP_UTIL_H__ 00231 00232 /** @} */
Generated on Tue Jul 12 2022 13:52:30 by
