1 /**
2 ****************************************************************************************
3 *
4 * @file co_utils.h
5 *
6 * @brief Common utilities definitions
7 *
8 * Copyright (C) RivieraWaves 2009-2015
9 *
10 *
11 ****************************************************************************************
12 */
13 #ifndef _CO_UTILS_H_
14 #define _CO_UTILS_H_
15
16 /**
17 ****************************************************************************************
18 * @defgroup CO_UTILS Utilities
19 * @ingroup COMMON
20 * @brief Common utilities
21 *
22 * This module contains the common utilities functions and macros.
23 *
24 * @{
25 ****************************************************************************************
26 */
27
28 /*
29 * INCLUDE FILES
30 ****************************************************************************************
31 */
32
33 #include <stdint.h> // standard definitions
34 #include <stddef.h> // standard definitions
35 #include "co_bt.h" // common bt definitions
36 #include "rwip_config.h" // SW configuration
37 //#include "core_cm0.h" // for inline functions
38 #include "stdint.h"
39 /*
40 * MACRO DEFINITIONS
41 ****************************************************************************************
42 */
43
44 /// Common constants - bit field definitions
45 #define BIT0 0x0001
46 #define BIT1 0x0002
47 #define BIT2 0x0004
48 #define BIT3 0x0008
49 #define BIT4 0x0010
50 #define BIT5 0x0020
51 #define BIT6 0x0040
52 #define BIT7 0x0080
53 #define BIT8 0x0100
54 #define BIT9 0x0200
55 #define BIT10 0x0400
56 #define BIT11 0x0800
57 #define BIT12 0x1000
58 #define BIT13 0x2000
59 #define BIT14 0x4000
60 #define BIT15 0x8000
61
62 #define BIT16 0x00010000
63 #define BIT17 0x00020000
64 #define BIT18 0x00040000
65 #define BIT19 0x00080000
66 #define BIT20 0x00100000
67 #define BIT21 0x00200000
68 #define BIT22 0x00400000
69 #define BIT23 0x00800000L
70 #define BIT24 0x01000000L
71 #define BIT25 0x02000000L
72 #define BIT26 0x04000000L
73 #define BIT27 0x08000000L
74 #define BIT28 0x10000000L
75 #define BIT29 0x20000000L
76 #define BIT30 0x40000000L
77 #define BIT31 0x80000000UL
78
79 /// Number of '1' bits in a byte
80 #define NB_ONE_BITS(byte) (one_bits[byte & 0x0F] + one_bits[byte >> 4])
81
82 /// Get the number of elements within an array, give also number of rows in a 2-D array
83 #define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0]))
84
85 /// Get the number of columns within a 2-D array
86 #define ARRAY_NB_COLUMNS(array) (sizeof((array[0]))/sizeof((array)[0][0]))
87
88
89 /// Macro for LMP message handler function declaration or definition
90 #define LMP_MSG_HANDLER(msg_name) __STATIC int lmp_##msg_name##_handler(struct lmp_##msg_name const *param, \
91 ke_task_id_t const dest_id)
92
93 /// Macro for HCI message handler function declaration or definition (for multi-instanciated tasks)
94 #define HCI_CMD_HANDLER_C(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \
95 ke_task_id_t const dest_id, \
96 uint16_t opcode)
97
98 /// Macro for HCI message handler function declaration or definition (with parameters)
99 #define HCI_CMD_HANDLER(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \
100 uint16_t opcode)
101
102 /// Macro for HCI message handler function declaration or definition (with parameters)
103 #define HCI_CMD_HANDLER_TAB(task) __STATIC const struct task##_hci_cmd_handler task##_hci_command_handler_tab[] =
104
105
106 /*
107 * TYPE DEFINITIONS
108 ****************************************************************************************
109 */
110
111
112 /*
113 * CONSTANT DECLARATIONS
114 ****************************************************************************************
115 */
116
117 /// Number of '1' bits in values from 0 to 15, used to fasten bit counting
118 extern const unsigned char one_bits[16];
119
120 /// Conversion table Sleep Clock Accuracy to PPM
121 extern const uint16_t co_sca2ppm[];
122
123 /// NULL BD address
124 extern const struct bd_addr co_null_bdaddr;
125
126 /// NULL BD address
127 extern const struct bd_addr co_default_bdaddr;
128
129 /*
130 * MACROS
131 ****************************************************************************************
132 */
133
134 /// MACRO to build a subversion field from the Minor and Release fields
135 #define CO_SUBVERSION_BUILD(minor, release) (((minor) << 8) | (release))
136
137
138 /// Macro to get a structure from one of its structure field
139 #define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) ))
140
141 /*
142 * OPERATIONS ON BT CLOCK
143 ****************************************************************************************
144 */
145
146 /**
147 ****************************************************************************************
148 * @brief Clocks addition with 2 operands
149 *
150 * @param[in] clock_a 1st operand value (in BT slots)
151 * @param[in] clock_b 2nd operand value (in BT slots)
152 * @return result operation result (in BT slots)
153 ****************************************************************************************
154 */
155 #define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & MAX_SLOT_CLOCK))
156
157 /**
158 ****************************************************************************************
159 * @brief Clocks addition with 3 operands
160 *
161 * @param[in] clock_a 1st operand value (in BT slots)
162 * @param[in] clock_b 2nd operand value (in BT slots)
163 * @param[in] clock_c 3rd operand value (in BT slots)
164 * @return result operation result (in BT slots)
165 ****************************************************************************************
166 */
167 #define CLK_ADD_3(clock_a, clock_b, clock_c) ((uint32_t)(((clock_a) + (clock_b) + (clock_c)) & MAX_SLOT_CLOCK))
168
169 /**
170 ****************************************************************************************
171 * @brief Clocks subtraction
172 *
173 * @param[in] clock_a 1st operand value (in BT slots)
174 * @param[in] clock_b 2nd operand value (in BT slots)
175 * @return result operation result (in BT slots)
176 ****************************************************************************************
177 */
178 #define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & MAX_SLOT_CLOCK))
179
180 /**
181 ****************************************************************************************
182 * @brief Clocks time difference
183 *
184 * @param[in] clock_a 1st operand value (in BT slots)
185 * @param[in] clock_b 2nd operand value (in BT slots)
186 * @return result return the time difference from clock A to clock B
187 * - result < 0 => clock_b is in the past
188 * - result == 0 => clock_a is equal to clock_b
189 * - result > 0 => clock_b is in the future
190 ****************************************************************************************
191 */
192 #define CLK_DIFF(clock_a, clock_b) ( (CLK_SUB((clock_b), (clock_a)) > ((MAX_SLOT_CLOCK+1) >> 1)) ? \
193 ((int32_t)((-CLK_SUB((clock_a), (clock_b))))) : ((int32_t)((CLK_SUB((clock_b), (clock_a))))) )
194
195 /**
196 ****************************************************************************************
197 * @brief Check if an instant is passed
198 *
199 * @param[in] instant Instant reference (in BT slots)
200 * @param[in] clock Current timestamp (in BT slots)
201 * @return result True: clock is after or equal to the instant | False: clock is before the instant
202 ****************************************************************************************
203 */
204 #define CLK_INSTANT_PASSED(instant, clock) ((uint32_t)(clock - instant) < (MAX_SLOT_CLOCK >> 1))
205
206 /// macro to extract a field from a value containing several fields
207 /// @param[in] __r bit field value
208 /// @param[in] __f field name
209 /// @return the value of the register masked and shifted
210 #define GETF(__r, __f) \
211 (( (__r) & (__f##_MASK) ) >> (__f##_LSB))
212
213 /// macro to set a field value into a value containing several fields.
214 /// @param[in] __r bit field value
215 /// @param[in] __f field name
216 /// @param[in] __v value to put in field
217 #define SETF(__r, __f, __v) \
218 do { \
219 ASSERT_ERR( ( ( ( (__v) << (__f##_LSB) ) & ( ~(__f##_MASK) ) ) ) == 0 ); \
220 __r = (((__r) & ~(__f##_MASK)) | (__v) << (__f##_LSB)); \
221 } while (0)
222
223
224
225 /// macro to extract a bit field from a value containing several fields
226 /// @param[in] __r bit field value
227 /// @param[in] __b bit field name
228 /// @return the value of the register masked and shifted
229 #define GETB(__r, __b) \
230 (( (__r) & (__b##_BIT) ) >> (__b##_POS))
231
232 /// macro to set a bit field value into a value containing several fields.
233 /// @param[in] __r bit field value
234 /// @param[in] __b bit field name
235 /// @param[in] __v value to put in field
236 #define SETB(__r, __b, __v) \
237 do { \
238 ASSERT_ERR( ( ( ( (__v) << (__b##_POS) ) & ( ~(__b##_BIT) ) ) ) == 0 ); \
239 __r = (((__r) & ~(__b##_BIT)) | (__v) << (__b##_POS)); \
240 } while (0)
241
242
243
244 /*
245 * FUNCTION DEFINITIONS
246 ****************************************************************************************
247 */
248 /**
249 ****************************************************************************************
250 * @brief Read an aligned 32 bit word.
251 * @param[in] ptr32 The address of the first byte of the 32 bit word.
252 * @return The 32 bit value.
253 ****************************************************************************************
254 */
co_read32(void const * ptr32)255 __INLINE uint32_t co_read32(void const *ptr32)
256 {
257 return *((uint32_t*)ptr32);
258 }
259
260 /**
261 ****************************************************************************************
262 * @brief Read an aligned 16 bits word.
263 * @param[in] ptr16 The address of the first byte of the 16 bits word.
264 * @return The 16 bits value.
265 ****************************************************************************************
266 */
co_read16(void const * ptr16)267 __INLINE uint16_t co_read16(void const *ptr16)
268 {
269 return *((uint16_t*)ptr16);
270 }
271
272 /**
273 ****************************************************************************************
274 * @brief Write an aligned 32 bits word.
275 * @param[in] ptr32 The address of the first byte of the 32 bits word.
276 * @param[in] value The value to write.
277 ****************************************************************************************
278 */
co_write32(void const * ptr32,uint32_t value)279 __INLINE void co_write32(void const *ptr32, uint32_t value)
280 {
281 *(uint32_t*)ptr32 = value;
282 }
283
284 /**
285 ****************************************************************************************
286 * @brief Write an aligned 16 bits word.
287 * @param[in] ptr16 The address of the first byte of the 16 bits word.
288 * @param[in] value The value to write.
289 ****************************************************************************************
290 */
co_write16(void const * ptr16,uint32_t value)291 __INLINE void co_write16(void const *ptr16, uint32_t value)
292 {
293 *(uint16_t*)ptr16 = value;
294 }
295
296 /**
297 ****************************************************************************************
298 * @brief Write a 8 bits word.
299 * @param[in] ptr8 The address of the first byte of the 8 bits word.
300 * @param[in] value The value to write.
301 ****************************************************************************************
302 */
co_write8(void const * ptr8,uint32_t value)303 __INLINE void co_write8(void const *ptr8, uint32_t value)
304 {
305 *(uint8_t*)ptr8 = value;
306 }
307
308 /**
309 ****************************************************************************************
310 * @brief Read a packed 16 bits word.
311 * @param[in] ptr16 The address of the first byte of the 16 bits word.
312 * @return The 16 bits value.
313 ****************************************************************************************
314 */
315 #if 1
316 #define co_read16p(ptr16) (((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8)
317 #else
co_read16p(void const * ptr16)318 __INLINE uint16_t co_read16p(void const *ptr16)
319 {
320 uint16_t value = ((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8;
321 return value;
322 }
323 #endif
324
325 /**
326 ****************************************************************************************
327 * @brief Read a packed 24 bits word.
328 * @param[in] ptr24 The address of the first byte of the 24 bits word.
329 * @return The 24 bits value.
330 ****************************************************************************************
331 */
co_read24p(void const * ptr24)332 __INLINE uint32_t co_read24p(void const *ptr24)
333 {
334 uint16_t addr_l, addr_h;
335 addr_l = co_read16p((uint16_t *)ptr24);
336 addr_h = *((uint16_t *)ptr24 + 1) & 0x00FF;
337 return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
338 }
339
340 /**
341 ****************************************************************************************
342 * @brief Write a packed 24 bits word.
343 * @param[in] ptr24 The address of the first byte of the 24 bits word.
344 * @param[in] value The value to write.
345 ****************************************************************************************
346 */
co_write24p(void const * ptr24,uint32_t value)347 __INLINE void co_write24p(void const *ptr24, uint32_t value)
348 {
349 uint8_t *ptr=(uint8_t*)ptr24;
350
351 *ptr++ = (uint8_t)(value&0xff);
352 *ptr++ = (uint8_t)((value&0xff00)>>8);
353 *ptr++ = (uint8_t)((value&0xff0000)>>16);
354 }
355
356 /**
357 ****************************************************************************************
358 * @brief Read a packed 32 bits word.
359 * @param[in] ptr32 The address of the first byte of the 32 bits word.
360 * @return The 32 bits value.
361 ****************************************************************************************
362 */
co_read32p(void const * ptr32)363 __INLINE uint32_t co_read32p(void const *ptr32)
364 {
365 uint16_t addr_l, addr_h;
366 addr_l = co_read16p((uint16_t *)ptr32);
367 addr_h = co_read16p((uint16_t *)ptr32 + 1);
368 return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
369 }
370 /**
371 ****************************************************************************************
372 * @brief Write a packed 32 bits word.
373 * @param[in] ptr32 The address of the first byte of the 32 bits word.
374 * @param[in] value The value to write.
375 ****************************************************************************************
376 */
co_write32p(void const * ptr32,uint32_t value)377 __INLINE void co_write32p(void const *ptr32, uint32_t value)
378 {
379 uint8_t *ptr=(uint8_t*)ptr32;
380
381 *ptr++ = (uint8_t)(value&0xff);
382 *ptr++ = (uint8_t)((value&0xff00)>>8);
383 *ptr++ = (uint8_t)((value&0xff0000)>>16);
384 *ptr = (uint8_t)((value&0xff000000)>>24);
385 }
386
387 /**
388 ****************************************************************************************
389 * @brief Write a packed 16 bits word.
390 * @param[in] ptr16 The address of the first byte of the 16 bits word.
391 * @param[in] value The value to write.
392 ****************************************************************************************
393 */
co_write16p(void const * ptr16,uint16_t value)394 __INLINE void co_write16p(void const *ptr16, uint16_t value)
395 {
396 uint8_t *ptr=(uint8_t*)ptr16;
397
398 *ptr++ = value&0xff;
399 *ptr = (value&0xff00)>>8;
400 }
401
402
403 /*
404 * FUNCTION DECLARATIONS
405 ****************************************************************************************
406 */
407
408 #if RW_DEBUG
409 /**
410 ****************************************************************************************
411 * @brief Convert bytes to hexadecimal string
412 *
413 * @param[out] dest Pointer to the destination string (must be 2x longer than input table)
414 * @param[in] src Pointer to the bytes table
415 * @param[in] nb_bytes Number of bytes to display in the string
416 ****************************************************************************************
417 */
418 void co_bytes_to_string(char* dest, uint8_t* src, uint8_t nb_bytes);
419 #endif //RW_DEBUG
420
421 /**
422 ****************************************************************************************
423 * @brief Compares two Bluetooth device addresses
424 *
425 * This function checks if the two bd address are equal.
426 *
427 * @param[in] bd_address1 Pointer on the first bd address to be compared.
428 * @param[in] bd_address2 Pointer on the second bd address to be compared.
429 *
430 * @return result of the comparison (true or false).
431 *
432 ****************************************************************************************
433 */
434 bool co_bdaddr_compare(struct bd_addr const *bd_address1,
435 struct bd_addr const *bd_address2);
436
437 #if (BT_EMB_PRESENT)
438
439 /**
440 ******************************************************************************
441 * @brief Convert an duration in baseband slot to a duration in number of ticks.
442 * @param[in] slot_cnt Duration in number of baseband slot
443 * @return Duration (in number of ticks).
444 ******************************************************************************
445 */
446 uint32_t co_slot_to_duration(uint16_t slot_cnt);
447
448 /**
449 ******************************************************************************
450 * @brief Count the number of good channels in a map
451 * @param[in] map Channel Map (bit fields for the 79 BT RF channels)
452 * @return Number of good channels
453 ******************************************************************************
454 */
455 uint8_t co_nb_good_channels(const struct chnl_map* map);
456
457 #endif //BT_EMB_PRESENT
458
459 /// @} CO_UTILS
460
461 #endif // _CO_UTILS_H_
462