1 /**
2  ****************************************************************************************
3  *
4  * @file co_math.h
5  *
6  * @brief Common optimized math functions
7  *
8  * Copyright (C) RivieraWaves 2009-2015
9  *
10  *
11  ****************************************************************************************
12  */
13 
14 #ifndef _CO_MATH_H_
15 #define _CO_MATH_H_
16 
17 /**
18  *****************************************************************************************
19  * @defgroup CO_MATH Math functions
20  * @ingroup COMMON
21  * @brief  Optimized math functions and other computations.
22  *
23  * @{
24  *****************************************************************************************
25  */
26 
27 /*
28  * INCLUDE FILES
29  ****************************************************************************************
30  */
31 #include <stdint.h>        // standard integer definitions
32 #include <stdbool.h>       // boolean definitions
33 #include <stdlib.h>        // standard library
34 #include "ble_arch.h"
35 
36 extern void srand (unsigned int seed);
37 extern int rand (void);
38 
39 /*
40  * MACROS
41  ****************************************************************************************
42  */
43 /**
44  ****************************************************************************************
45  * @brief Return value with one bit set.
46  *
47  * @param[in] pos Position of the bit to set.
48  *
49  * @return Value with one bit set.  There is no return type since this is a macro and this
50  * will be resolved by the compiler upon assignment to an l-value.
51  ****************************************************************************************
52  */
53 #define CO_BIT(pos) (1UL<<(pos))
54 
55 /**
56  ****************************************************************************************
57  * @brief Align val on the multiple of 4 equal or nearest higher.
58  * @param[in] val Value to align.
59  * @return Value aligned.
60  ****************************************************************************************
61  */
62 #define CO_ALIGN4_HI(val) (((val)+3)&~3)
63 
64 
65 /**
66  ****************************************************************************************
67  * @brief Align val on the multiple of 4 equal or nearest lower.
68  * @param[in] val Value to align.
69  * @return Value aligned.
70  ****************************************************************************************
71  */
72 #define CO_ALIGN4_LO(val) ((val)&~3)
73 
74 /**
75  ****************************************************************************************
76  * @brief Align val on the multiple of 2 equal or nearest higher.
77  * @param[in] val Value to align.
78  * @return Value aligned.
79  ****************************************************************************************
80  */
81 #define CO_ALIGN2_HI(val) (((val)+1)&~1)
82 
83 
84 /**
85  ****************************************************************************************
86  * @brief Align val on the multiple of 2 equal or nearest lower.
87  * @param[in] val Value to align.
88  * @return Value aligned.
89  ****************************************************************************************
90  */
91 #define CO_ALIGN2_LO(val) ((val)&~1)
92 
93 
94 /*
95  * FUNCTION DEFINTIONS
96  ****************************************************************************************
97  */
98 /**
99  ****************************************************************************************
100  * @brief Count leading zeros.
101  * @param[in] val Value to count the number of leading zeros on.
102  * @return Number of leading zeros when value is written as 32 bits.
103  ****************************************************************************************
104  */
co_clz(uint32_t val)105 __INLINE uint32_t co_clz(uint32_t val)
106 {
107     #if defined(__arm__)
108     return __builtin_clz(val);
109     #elif defined(__GNUC__)
110     if (val == 0)
111     {
112         return 32;
113     }
114     return __builtin_clz(val);
115     #else
116     uint32_t i;
117     for (i = 0; i < 32; i++)
118     {
119         if (val & CO_BIT(31 - i))
120             break;
121     }
122     return i;
123     #endif // defined(__arm__)
124 }
125 
126 /**
127  ****************************************************************************************
128  * @brief Function to initialize the random seed.
129  * @param[in] seed The seed number to use to generate the random sequence.
130  ****************************************************************************************
131  */
co_random_init(uint32_t seed)132 __INLINE void co_random_init(uint32_t seed)
133 {
134     srand(seed);
135 }
136 
137 /**
138  ****************************************************************************************
139  * @brief Function to get an 8 bit random number.
140  * @return Random byte value.
141  ****************************************************************************************
142  */
co_rand_byte(void)143 __INLINE uint8_t co_rand_byte(void)
144 {
145     return (uint8_t)(rand() & 0xFF);
146 }
147 
148 /**
149  ****************************************************************************************
150  * @brief Function to get an 16 bit random number.
151  * @return Random half word value.
152  ****************************************************************************************
153  */
co_rand_hword(void)154 __INLINE uint16_t co_rand_hword(void)
155 {
156     return (uint16_t)(rand() & 0xFFFF);
157 }
158 
159 /**
160  ****************************************************************************************
161  * @brief Function to get an 32 bit random number.
162  * @return Random word value.
163  ****************************************************************************************
164  */
co_rand_word(void)165 __INLINE uint32_t co_rand_word(void)
166 {
167     return (uint32_t)rand();
168 }
169 
170 /**
171  ****************************************************************************************
172  * @brief Function to return the smallest of 2 unsigned 32 bits words.
173  * @return The smallest value.
174  ****************************************************************************************
175  */
co_min(uint32_t a,uint32_t b)176 __INLINE uint32_t co_min(uint32_t a, uint32_t b)
177 {
178     return a < b ? a : b;
179 }
180 
181 /**
182  ****************************************************************************************
183  * @brief Function to return the greatest of 2 unsigned 32 bits words.
184  * @return The greatest value.
185  ****************************************************************************************
186  */
co_max(uint32_t a,uint32_t b)187 __INLINE uint32_t co_max(uint32_t a, uint32_t b)
188 {
189     return a > b ? a : b;
190 }
191 
192 /**
193  ****************************************************************************************
194  * @brief Function to return the absolute value of a signed integer.
195  * @return The absolute value.
196  ****************************************************************************************
197  */
co_abs(int val)198 __INLINE int co_abs(int val)
199 {
200     return val < 0 ? val*(-1) : val;
201 }
202 
203 /// @} CO_MATH
204 
205 
206 #endif // _CO_MATH_H_
207