px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
px_defs.h
1#ifndef __PX_DEFS_H__
2#define __PX_DEFS_H__
3/* =============================================================================
4 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
5 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
6 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
7 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
8 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
9
10 Copyright (c) 2008 Pieter Conradie <https://piconomix.com>
11
12 License: MIT
13 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
14
15 Title: px_defs.h : Common definitions
16 Author(s): Pieter Conradie
17 Creation Date: 2008-02-05
18
19============================================================================= */
20/**
21 * @ingroup COMMON
22 * @defgroup PX_DEFS px_defs.h : Common definitions
23 *
24 * Definition of standard types, boolean, scope and utility macros.
25 *
26 * File:
27 * - common/inc/px_defs.h
28 *
29 * @{
30 */
31
32/* _____STANDARD INCLUDES____________________________________________________ */
33#include "px_compiler.h"
34
35#ifndef __PX_STD_TYPES_ABSENT__
36#include <stdbool.h>
37#include <stddef.h>
38#include <stdint.h>
39#endif
40
41/* _____PROJECT INCLUDES_____________________________________________________ */
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46/* _____DEFINITIONS__________________________________________________________ */
47#ifndef NULL
48/// NULL pointer
49#define NULL 0
50#endif
51
52/* _____TYPE DEFINITIONS_____________________________________________________ */
53#ifdef __PX_STD_TYPES_ABSENT__
54// Provide standard types if absent from standard C library
55typedef unsigned char uint8_t;
56typedef signed char int8_t;
57typedef unsigned short uint16_t;
58typedef signed short int16_t;
59typedef unsigned long uint32_t;
60typedef signed long int32_t;
61typedef unsigned long long uint64_t;
62typedef signed long long int64_t;
63
64#ifndef _Bool
65#define _Bool uint8_t
66#endif
67#ifndef bool
68#define bool _Bool
69#endif
70#ifndef false
71#define false 0
72#endif
73#ifndef true
74#define true (!false)
75#endif
76
77#endif
78
79/* _____MACROS_______________________________________________________________ */
80/// @name Minimum and maximum of standard types
81/// @{
82#define PX_U8_MIN 0x00 ///< Minimum of unsigned 8-bit value
83#define PX_U8_MAX 0xff ///< Maximum of unsigned 8-bit value
84#define PX_U16_MIN 0x0000 ///< Minimum of unsigned 16-bit value
85#define PX_U16_MAX 0xffff ///< Maximum of unsigned 16-bit value
86#define PX_U32_MIN 0x00000000 ///< Minimum of unsigned 32-bit value
87#define PX_U32_MAX 0xffffffff ///< Maximum of unsigned 32-bit value
88#define PX_S8_MIN (-0x80) ///< Minimum of signed 8-bit value
89#define PX_S8_MAX 0x7f ///< Maximum of signed 8-bit value
90#define PX_S16_MIN (-0x8000) ///< Minimum of signed 16-bit value
91#define PX_S16_MAX 0x7fff ///< Maximum of signed 16-bit value
92#define PX_S32_MIN (-0x80000000) ///< Minimum of signed 32-bit value
93#define PX_S32_MAX 0x7fffffff ///< Maximum of signed 32-bit value
94/// @}
95
96/**
97 * @name Type size and sign macros
98 *
99 * Source: [Catching Integer Overflows in C](http://www.fefe.de/intof.html)
100 */
101/// @{
102///@cond INTERNAL
103#define __PX_HALF_MAX_SIGNED(type) ((type)1 << (sizeof(type) * 8 - 2))
104#define __PX_MAX_SIGNED(type) (__PX_HALF_MAX_SIGNED(type) - 1 + __PX_HALF_MAX_SIGNED(type))
105#define __PX_MIN_SIGNED(type) (-1 - __PX_MAX_SIGNED(type))
106///@endcond
107
108/// Test if a type is signed or unsigned
109#define PX_TYPE_IS_SIGNED(type) ((type) - 1 < 1)
110
111/**
112 * Return the minimum of a type.
113 *
114 * For an unsigned type it is zero.
115 * For a signed type this is the largest negative value
116 */
117#define PX_MIN_OF_TYPE(type) (PX_TYPE_IS_SIGNED(type) ? __PX_MIN_SIGNED(type) : (type)0)
118
119/// Return the maximum of a type.
120#define PX_MAX_OF_TYPE(type) ((type) ~PX_MIN_OF_TYPE(type))
121/// @}
122
123/// @name Concatenation macros
124/// @{
125
126#define _PX_CONCAT(x, y) x ## y
127
128/**
129 * Recursive token concatenation macro.
130 *
131 * Example:
132 * @code{.c}
133 * #define XY 123456
134 * #define TOKEN1 X
135 * #define TOKEN2 Y
136 * #define TOKEN1_2 PX_CONCAT(TOKEN1, TOKEN2)
137 *
138 * int i = TOKEN1_2;
139 * @endcode
140 *
141 * Preprocessor steps:
142 *
143 * 1. TOKEN1_2 is replaced with PX_CONCAT(TOKEN1, TOKEN2)
144 * 2. PX_CONCAT(TOKEN1, TOKEN2) is replaced with _PX_CONCAT(X, Y)
145 * 3. _PX_CONCAT(X, Y) is replaced with XY
146 * 4. XY is replaced with 123456
147 *
148 * Compiler step:
149 *
150 * 1. An integer variable called "i" is created and initialised with 123456
151 */
152#define PX_CONCAT(x, y) _PX_CONCAT(x, y)
153/// @}
154
155/// @name Stringify macros
156/// @{
157
158#define _PX_STRINGIFY(x) #x
159
160/**
161 * Recursive stringify macro.
162 *
163 * Example:
164 * @code{.c}
165 * #define VERSION_MAJOR 2
166 * #define VERSION_MINOR 12
167 *
168 * printf("Version " PX_STRINGIFY(VERSION_MAJOR) "." PX_STRINGIFY(VERSION_MINOR));
169 * @endcode
170 */
171#define PX_STRINGIFY(x) _PX_STRINGIFY(x)
172/// @}
173
174/// @name Bit manipulation macros useful for example to manipulate GPIO pins
175/// @{
176
177/// Set a bit (1)
178#define PX_BIT_SET_HI(var, bit) do { (var) |= (1ul << (bit)); } while(0)
179
180/// Clear a bit (0)
181#define PX_BIT_SET_LO(var, bit) do { (var) &= ~(1ul << (bit)); } while(0)
182
183/// Toggle a bit
184#define PX_BIT_TOGGLE(var, bit) do { (var) ^= (1ul << (bit)); } while(0)
185
186/// Test if a bit is set (1?)
187#define PX_BIT_IS_HI(var, bit) (((var) & (1ul << (bit))) != 0)
188
189/// Test if a bit is cleared (0?)
190#define PX_BIT_IS_LO(var, bit) (((var) & (1ul << (bit))) == 0)
191
192/// Wait until a bit is set
193#define PX_WAIT_UNTIL_BIT_IS_HI(var, bit) do { ; } while(PX_BIT_IS_LO((var), (bit)))
194
195/// Wait until a bit is cleared
196#define PX_WAIT_UNTIL_BIT_IS_LO(var, bit) do { ; } while(PX_BIT_IS_HI((var), (bit)))
197/// @}
198
199/// @name Bit mask macros
200/// @{
201
202/// Clear bits (set bits to 0)
203#define PX_BIT_MASK_SET_LO(var, bit_mask, shift) \
204 do { (var) &= ~((bit_mask) << (shift)); } while(0)
205
206/// Set bits (set bits to 1)
207#define PX_BIT_MASK_SET_HI(var, bit_mask, shift) \
208 do { (var) |= ((bit_mask) << (shift)); } while(0)
209
210/// Mask bits (set to 0) and then set to value
211#define PX_BIT_MASK_SET_VAL(var, bit_mask, val, shift) \
212 do { (var) = ((var) & (~((bit_mask) << (shift)))) | ((val) << (shift)); } while(0)
213/// @}
214
215/// @name Byte extraction macros
216/// @{
217
218/// Extract the high 4 bits of a 8-bit value
219#define PX_U8_HI4(data) ((uint8_t)(((data) >> 4) & 0x0f))
220
221/// Extract the low 4 bits of a 8-bit value
222#define PX_U8_LO4(data) ((uint8_t)((data) & 0x0f))
223
224/// Extract the high 8 bits of a 16-bit value (Most Significant Byte)
225#define PX_U16_HI8(data) ((uint8_t)(((data) >> 8) & 0xff))
226
227/// Extract the low 8 bits of a 16-bit value (Least Significant Byte)
228#define PX_U16_LO8(data) ((uint8_t)((data) & 0xff))
229
230/// Extract the high 8 bits (bits 31..24) of a 32-bit value
231#define PX_U32_HI8(data) ((uint8_t)(((data) >> 24) & 0xff))
232
233/// Extract the middle high 8 bits (bits 23..16) of a 32-bit value
234#define PX_U32_MH8(data) ((uint8_t)(((data) >> 16) & 0xff))
235
236/// Extract the middle low 8 bits (bits 15..8) of a 32-bit value
237#define PX_U32_ML8(data) ((uint8_t)(((data) >> 8) & 0xff))
238
239/// Extract the low 8 bits (bits 7..0) of a 32-bit value
240#define PX_U32_LO8(data) ((uint8_t)((data) & 0xff))
241
242/// Extract the high 16 bits (bits 31..16) of a 32-bit value
243#define PX_U32_HI16(data) ((uint16_t)(((data) >> 16) & 0xffff))
244
245/// Extract the low 16 bits (bits 15..0) of a 32-bit value
246#define PX_U32_LO16(data) ((uint16_t)((data) & 0xffff))
247/// @}
248
249/// @name Bit concatenation macros
250/// @{
251
252/// Concatenate 8 bits to form 8-bit value
253#define PX_U8_CONCAT_U1(b7, b6, b5, b4, b3, b2, b1, b0) \
254 ( (((b7) & 0x01) << 7) | (((b6) & 0x01) << 6) | (((b5) & 0x01) << 5) | (((b4) & 0x01) << 4) \
255 | (((b3) & 0x01) << 3) | (((b2) & 0x01) << 2) | (((b1) & 0x01) << 1) | (((b0) & 0x01) << 0) )
256
257/// @}
258
259/// @name Byte concatenation macros
260/// @{
261
262/// Concatenate 2 x 4 bits to form 8-bit value
263#define PX_U8_CONCAT_U4(hi4, lo4) \
264 ( (((uint8_t)((hi4) & 0x0f)) << 4) \
265 | ((uint8_t)((lo4) & 0x0f)) )
266
267/// Concatenate 2 x 8 bits to form 16-bit value
268#define PX_U16_CONCAT_U8(hi8, lo8) \
269 ( (((uint16_t)((hi8) & 0xff)) << 8) \
270 | ((uint16_t)((lo8) & 0xff)) )
271
272/// Concatenate 4 x 8 bits to form 32-bit value
273#define PX_U32_CONCAT_U8(hi8, mh8, ml8, lo8) \
274 ( (((uint32_t)((hi8) & 0xff)) << 24) \
275 | (((uint32_t)((mh8) & 0xff)) << 16) \
276 | (((uint32_t)((ml8) & 0xff)) << 8 ) \
277 | ((uint32_t)((lo8) & 0xff)) )
278/// @}
279
280/// @name General utility macros
281/// @{
282
283/// Calculate unsigned division with rounding to nearest integer value
284#define PX_UDIV_ROUND(dividend, divisor) (((dividend) + ((divisor) / 2)) / (divisor))
285
286/// Calculate unsigned division with rounding to nearest integer value
287#define PX_UDIV_ROUNDUP(dividend, divisor) (((dividend) + ((divisor) - 1)) / (divisor))
288
289/// Calculate signed division with rounding to nearest integer value
290#define PX_SDIV_ROUND(dividend, divisor) (((dividend < 0) ^ (divisor < 0)) ? (((dividend) - ((divisor) / 2)) / (divisor)) : (((dividend) + ((divisor) / 2)) / (divisor)))
291
292/// Calculate the number of items in an array
293#define PX_SIZEOF_ARRAY(array) (sizeof(array) / sizeof((array)[0]))
294
295/// Is value a power of two (1, 2, 4, 8, 16, ...)?
296#define PX_VAL_IS_PWR_OF_TWO(value) (((value) & ((value) - 1)) == 0)
297
298/// Swap the value of two variables
299#define PX_SWAP(type_t, i , j) do { type_t _k = i; i = j; j = _k; } while (0)
300
301/// Maximum of two values
302#define PX_MAX(i, j) (i > j ? i : j)
303
304/// Minimum of two values
305#define PX_MIN(i, j) (i < j ? i : j)
306
307/// @}
308
309#ifdef __cplusplus
310}
311#endif
312
313/// @}
314#endif