-
Notifications
You must be signed in to change notification settings - Fork 3
/
std_macros.h
executable file
·452 lines (389 loc) · 12 KB
/
std_macros.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
/*******************************************************************************
*
* Copyright (C) u-blox AG
* u-blox AG, Thalwil, Switzerland
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR U-BLOX MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
*******************************************************************************
*
* Project: PE_ANS
*
******************************************************************************/
/*!
\file
\brief Standard Macros
Standard Macros are implemented in this file which are widely used within our
software.
*/
/*******************************************************************************
* $Id: std_macros.h 63615 2012-11-27 10:12:42Z andrea.foni $
******************************************************************************/
#ifndef __STD_MACROS_H__
#define __STD_MACROS_H__ //!< multiple inclusion guard
//! absolute value of x
/**
\note For floating points one should use fabs for R8 and fabsf for R4.
\note x should be a variable or constant not an expression
\param x a number
\return the absolute value of x
*/
#define ABS(x) ( ((x) >= 0) ? (x) : -(x) )
//! minimum of a and b
/**
\note a and b should be variables or constants not expressions
\param a a number
\param b a number
\return the minimum of a and b
*/
#ifndef MIN
#define MIN(a,b) ( ((a) <= (b)) ? (a) : (b) )
#endif
//! maximum of a and b
/**
\note a and b should be variables or constants not expressions
\param a a number
\param b a number
\return the maximum of a and b
*/
#define MAX(a,b) ( ((a) >= (b)) ? (a) : (b) )
//! create a bitmask for bit a
/**
The bit a must have a valid range of 0 to 31.
\note This macro may be used in drv_xxx_type files,
as it is expanded by the conversion scripts .
\param a bit
\return bitmask with the bits a set to 1
*/
#define BIT(a) (((U4)1) << (U)(a))
//! create a bitmask for bit a
/**
The bit a must have a valid range of 0 to 63.
\note This macro may be used in drv_xxx_type files,
as it is expanded by the conversion scripts .
\param a bit
\return bitmask with the bits a set to 1
*/
#define BIT8(a) (((U8)1) << (U)(a))
//! create a bitmask for bit 0 to a-1
/**
The bit a must have a valid range of 0 to 32.
\note This macro may be used in drv_xxx_type files,
as it is expanded by the conversion scripts .
\param a bit
\return bitmask with the bits 0 to a-1 set to 1
*/
#define MASK(a) ((U4)(((U)(a)<32) ? BIT((U)(a)&31)-1 : 0xFFFFFFFF))
//! create a bitmask for a to b bits
/**
The bits a and b have a valid range of 0 to 31.
The bits a and b are included in the bitmask.
\param a start bit
\param b end bit
\return bitmask with the bits a to b set to 1
*/
#define BITS(a,b) ( ( ((MAX((U)(a),(U)(b)) - MIN((U)(a),(U)(b)) + 1) <= 0) ? (U)0x00000000 : \
((MAX((U)(a),(U)(b)) - MIN((U)(a),(U)(b)) + 1) >= 32) ? (U)0xFFFFFFFF : \
((BIT(MAX((U)(a),(U)(b)) - MIN((U)(a),(U)(b))) - 1) * 2 + 1) ) \
<< MIN((U)(a),(U)(b) ) )
//! count the leading zeros
/*!
count the number of leading zeros of a value
\param x the value to count the leading zeros
\return the number of leading zeros
*/
#define CLZ(x) (((x) & BIT(31)) ? 0 : \
((x) & BIT(30)) ? 1 : \
((x) & BIT(29)) ? 2 : \
((x) & BIT(28)) ? 3 : \
((x) & BIT(27)) ? 4 : \
((x) & BIT(26)) ? 5 : \
((x) & BIT(25)) ? 6 : \
((x) & BIT(24)) ? 7 : \
\
((x) & BIT(23)) ? 8 : \
((x) & BIT(22)) ? 9 : \
((x) & BIT(21)) ? 10 : \
((x) & BIT(20)) ? 11 : \
((x) & BIT(19)) ? 12 : \
((x) & BIT(18)) ? 13 : \
((x) & BIT(17)) ? 14 : \
((x) & BIT(16)) ? 15 : \
\
((x) & BIT(15)) ? 16 : \
((x) & BIT(14)) ? 17 : \
((x) & BIT(13)) ? 18 : \
((x) & BIT(12)) ? 19 : \
((x) & BIT(11)) ? 20 : \
((x) & BIT(10)) ? 21 : \
((x) & BIT( 9)) ? 22 : \
((x) & BIT( 8)) ? 23 : \
\
((x) & BIT( 7)) ? 24 : \
((x) & BIT( 6)) ? 25 : \
((x) & BIT( 5)) ? 26 : \
((x) & BIT( 4)) ? 27 : \
((x) & BIT( 3)) ? 28 : \
((x) & BIT( 2)) ? 29 : \
((x) & BIT( 1)) ? 30 : \
((x) & BIT( 0)) ? 31 : \
32 )
//! count the tailing zeros
/*!
count the number of tailing zeros of a value
\param x the value to count the tailing zeros
\return the number of tailing zeros
*/
#define CTZ(x) (((x) & BIT( 0)) ? 0 : \
((x) & BIT( 1)) ? 1 : \
((x) & BIT( 2)) ? 2 : \
((x) & BIT( 3)) ? 3 : \
((x) & BIT( 4)) ? 4 : \
((x) & BIT( 5)) ? 5 : \
((x) & BIT( 6)) ? 6 : \
((x) & BIT( 7)) ? 7 : \
\
((x) & BIT( 8)) ? 8 : \
((x) & BIT( 9)) ? 9 : \
((x) & BIT(10)) ? 10 : \
((x) & BIT(11)) ? 11 : \
((x) & BIT(12)) ? 12 : \
((x) & BIT(13)) ? 13 : \
((x) & BIT(14)) ? 14 : \
((x) & BIT(15)) ? 15 : \
\
((x) & BIT(16)) ? 16 : \
((x) & BIT(17)) ? 17 : \
((x) & BIT(18)) ? 18 : \
((x) & BIT(19)) ? 19 : \
((x) & BIT(20)) ? 20 : \
((x) & BIT(21)) ? 21 : \
((x) & BIT(22)) ? 22 : \
((x) & BIT(23)) ? 23 : \
\
((x) & BIT(24)) ? 24 : \
((x) & BIT(25)) ? 25 : \
((x) & BIT(26)) ? 26 : \
((x) & BIT(27)) ? 27 : \
((x) & BIT(28)) ? 28 : \
((x) & BIT(29)) ? 29 : \
((x) & BIT(30)) ? 30 : \
((x) & BIT(31)) ? 31 : \
32 )
//! calculate bit count for a given type
/*!
calculate bit count for a given type. this is to
avoid magic numbers such as \c 32 or \c 64.
\param t type, e.g. #U4
\return number of bits, e.g. 32
*/
#define BITCNT(t) ((U)(sizeof(t)*8))
//! binary log of constant c
/** Return binary log of constant c
\note use lib_uint_logb for variables
\note c should be a constant not an expression
\param c a number in the range 1 .. 2^32-1
\return the binary log of c
*/
#define LOGB(c) ( ((c) >= BIT(31)) ? 31 : \
((c) >= BIT(30)) ? 30 : \
((c) >= BIT(29)) ? 29 : \
((c) >= BIT(28)) ? 28 : \
((c) >= BIT(27)) ? 27 : \
((c) >= BIT(26)) ? 26 : \
((c) >= BIT(25)) ? 25 : \
((c) >= BIT(24)) ? 24 : \
\
((c) >= BIT(23)) ? 23 : \
((c) >= BIT(22)) ? 22 : \
((c) >= BIT(21)) ? 21 : \
((c) >= BIT(20)) ? 20 : \
((c) >= BIT(19)) ? 19 : \
((c) >= BIT(18)) ? 18 : \
((c) >= BIT(17)) ? 17 : \
((c) >= BIT(16)) ? 16 : \
\
((c) >= BIT(15)) ? 15 : \
((c) >= BIT(14)) ? 14 : \
((c) >= BIT(13)) ? 13 : \
((c) >= BIT(12)) ? 12 : \
((c) >= BIT(11)) ? 11 : \
((c) >= BIT(10)) ? 10 : \
((c) >= BIT( 9)) ? 9 : \
((c) >= BIT( 8)) ? 8 : \
\
((c) >= BIT( 7)) ? 7 : \
((c) >= BIT( 6)) ? 6 : \
((c) >= BIT( 5)) ? 5 : \
((c) >= BIT( 4)) ? 4 : \
((c) >= BIT( 3)) ? 3 : \
((c) >= BIT( 2)) ? 2 : \
((c) >= BIT( 1)) ? 1 : \
((c) >= BIT( 0)) ? 0 : \
/* error */ -1 )
//! get the number of bits used for a numeric states
/**
Seraches for the first number x where 2^x is greather than a
\param a number in the range 1 .. 2^32
\return the number of bits used to cover the numeric range 0 to a
*/
#define NUMBITS(a) ( (a < 0) ? 0 : \
(a == 1) ? 1 : \
(1 + LOGB((a) - 1)) )
//! Limit to Maximum
/*!
Limit a value to a given upper Limit
\param val value to limit
\param lim limit
\return value clipped if above \a lim
*/
#define LIMIT_UP(val,lim) ((val) > (lim) ? (lim) : (val))
//! Limit to Minimum
/*!
Limit a value to a given lower Limit
\param val value to limit
\param lim limit
\return value clipped if below \a lim
*/
#define LIMIT_LO(val,lim) ((val) < (lim) ? (lim) : (val))
//! signal a unused argument or variable to avoid compiler warnings
/**
\param a the unused variable or argument
*/
#define UNUSED(a) ((void) (a))
//! Align Value
/*!
This macro can be used to align sizes or addresses to a specific \a nByte boundary,
where \a nByte must be of the form 2^k. E.g. ALIGN(foo,sizeof(U4)) rounds up \c foo
to be a multiple of 4
\param val value to align
\param nBytes alignment size
\return aligned value
*/
#define ALIGN(val,nBytes) \
(((val)+((nBytes)-1))&(~((nBytes)-1)))
//! execute the function at address
/**
This macro calls the function at the address pAdr. No arguments are
passed to the function and the return value is ignored. In other words
the function should have the following declaration.
\code
void FunctionName(void);
\endcode
\param pAdr the address of the function
*/
#define EXECUTE(pAdr) ((void (*)(void))((U4)(pAdr)))()
//! endless define
/** Use this define in endless while loops in the following way:
This macro inhibits lint warning 716.
\code
while (ENDLESS)
{
// do something here
}
\endcode
*/
#define ENDLESS /*lint -save -e716*/ TRUE /*lint -restore*/
//! fallthrough define
/** Use this define to signal a fallthrough in a switch statement from
one case to the following one.
\code
switch (s)
{
case a:
break;
case b:
FALLTHROUGH
default:
}
\endcode
*/
#define FALLTHROUGH /*lint -fallthrough @fallthrough@ */
//! cast an address into an array
/**
Splint does not support cast to arrays. This marco will take
care of the missing cast support.
\param type the type of one array element
\param num the number of elements in the array
\param addr the address to cast
\return the casted array
*/
#ifdef S_SPLINT_S
#define ARRAYCAST(type, num, addr) ( (type*)(addr)) // size unused
#else
#define ARRAYCAST(type, num, addr) (*(type (*)[num]) (addr))
#endif
//! returns number of elements of an array
/**
This macro is very usful to calculate the number of elements of an
array. The number of elements is calculated by dividing the size of the
array by the size of one element.
\param array an array
\return the number of elements
*/
#define NUMOF(array) (sizeof(array)/sizeof(*(array)))
//! \name Special Cast Macros
//@{
//! Cast C2 to U2
/*!
Cast a 2-byte complex value to a 2-byte unsigned integer
\note does not work for literal constants or expressions, i.e. \a c should be an lvalue
\param c the C2 value to be casted
\return the casted U2 value
*/
#define C2_TO_U2(c) (*(U2*)&(c))
//! Cast U2 to C2
/*!
Cast a 2-byte unsigned integer to a 2-byte complex value
\note does not work for literal constants or expressions, i.e. \a u should be an lvalue
\param u the U2 value to be casted
\return the casted C2 value
*/
#define U2_TO_C2(u) (*(C2*)&(u))
//! Cast C4 to U4
/*!
Cast a 4-byte complex value to a 4-byte unsigned integer
\note does not work for literal constants or expressions, i.e. \a c should be an lvalue
\param c the C4 value to be casted
\return the casted U4 value
*/
#define C4_TO_U4(c) (*(U4*)&(c))
//! Cast U4 to C4
/*!
Cast a 4-byte unsigned integer to a 4-byte complex value
\note does not work for literal constants or expressions, i.e. \a u should be an lvalue
\param u the U4 value to be casted
\return the casted C4 value
*/
#define U4_TO_C4(u) (*(C4*)&(u))
//@}
//! Byte access to register
/*!
Access a byte from a 32bit register
\param reg the register to access (type REG)
\param ofs byte offset (0..3)
\return byte represented as U1
*/
#define READ_REG_BYTE(reg,ofs) \
*(((U1*)®)+((ofs)&0x3))
//! Halfword access to register
/*!
Access a Halfword from a 32bit register
\param reg the register to access (type REG)
\param ofs halfword offset (0..1)
\return halfword represented as U2
*/
#define READ_REG_HWORD(reg,ofs) \
*(((U2*)®)+((ofs)&0x1))
#endif // __STD_MACROS_H__