tinyusb
common.h
Go to the documentation of this file.
1 /**************************************************************************/
37 /**************************************************************************/
38 
43 #ifndef _TUSB_COMMON_H_
44 #define _TUSB_COMMON_H_
45 
46 #ifdef __cplusplus
47  extern "C" {
48 #endif
49 
50 //--------------------------------------------------------------------+
51 // MACROS
52 //--------------------------------------------------------------------+
53 #define STRING_(x) #x // stringify without expand
54 #define XSTRING_(x) STRING_(x) // expand then stringify
55 #define STRING_CONCAT_(a, b) a##b // concat without expand
56 #define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) // expand then concat
57 
58 //--------------------------------------------------------------------+
59 // INCLUDES
60 //--------------------------------------------------------------------+
61 
62 //------------- Standard Header -------------//
63 #include "primitive_types.h"
64 #include <stddef.h>
65 #include <string.h>
66 #include <stdio.h>
67 
68 //------------- TUSB Option Header -------------//
69 #include "tusb_option.h"
70 
71 //------------- General Header -------------//
72 #include "compiler/compiler.h"
73 #include "assertion.h"
74 #include "binary.h"
75 #include "tusb_errors.h"
76 
77 //------------- TUSB Header -------------//
78 #include "tusb_types.h"
79 #include "std_descriptors.h"
80 #include "std_request.h"
81 
82 #include "osal/osal.h"
83 
84 //--------------------------------------------------------------------+
85 // MACROS
86 //--------------------------------------------------------------------+
87 #define STRING_(x) #x
88 #define XSTRING_(x) STRING_(x)
89 #define STRING_CONCAT_(a, b) a##b
90 #define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b)
91 
92 #define MAX_OF(a, b) ( (a) > (b) ? (a) : (b) )
93 #define MIN_OF(a, b) ( (a) < (b) ? (a) : (b) )
94 
95 #define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
96 #define U16_LOW_U8(u16) ((uint8_t) ((u16) & 0x00ff))
97 #define U16_TO_U8S_BE(u16) U16_HIGH_U8(u16), U16_LOW_U8(u16)
98 #define U16_TO_U8S_LE(u16) U16_LOW_U8(u16), U16_HIGH_U8(u16)
99 
100 #define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
101 #define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
102 #define U32_B3_U8(u32) ((uint8_t) (((u32) >> 8) & 0x000000ff))
103 #define U32_B4_U8(u32) ((uint8_t) ((u32) & 0x000000ff)) // LSB
104 
105 #define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
106 #define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
107 
108 //------------- Endian Conversion -------------//
109 #define ENDIAN_BE(u32) \
110  (uint32_t) ( (((u32) & 0xFF) << 24) | (((u32) & 0xFF00) << 8) | (((u32) >> 8) & 0xFF00) | (((u32) >> 24) & 0xFF) )
111 
112 #define ENDIAN_BE16(le16) ((uint16_t) ((U16_LOW_U8(le16) << 8) | U16_HIGH_U8(le16)) )
113 
114 #ifndef __n2be_16
115 #define __n2be_16(u16) ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) )
116 #define __be2n_16(u16) __n2be_16(u16)
117 #endif
118 
119 //--------------------------------------------------------------------+
120 // INLINE FUNCTION
121 //--------------------------------------------------------------------+
122 #define memclr_(buffer, size) memset((buffer), 0, (size))
123 
124 
125 static inline uint8_t const * descriptor_next(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
126 static inline uint8_t const * descriptor_next(uint8_t const p_desc[])
127 {
128  return p_desc + p_desc[DESCRIPTOR_OFFSET_LENGTH];
129 }
130 
131 static inline uint8_t descriptor_typeof(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
132 static inline uint8_t descriptor_typeof(uint8_t const p_desc[])
133 {
134  return p_desc[DESCRIPTOR_OFFSET_TYPE];
135 }
136 
137 //------------- Conversion -------------//
139 static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) ATTR_ALWAYS_INLINE ATTR_CONST;
140 static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
141 {
142  return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
143 }
144 
145 static inline uint8_t u16_high_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
146 static inline uint8_t u16_high_u8(uint16_t u16)
147 {
148  return (uint8_t) ( ((uint16_t) (u16 >> 8)) & 0x00ff);
149 }
150 
151 static inline uint8_t u16_low_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
152 static inline uint8_t u16_low_u8(uint16_t u16)
153 {
154  return (uint8_t) (u16 & 0x00ff);
155 }
156 
157 static inline uint16_t u16_le2be(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
158 static inline uint16_t u16_le2be(uint16_t u16)
159 {
160  return ((uint16_t)(u16_low_u8(u16) << 8)) | u16_high_u8(u16);
161 }
162 
163 //------------- Min -------------//
164 static inline uint8_t min8_of(uint8_t x, uint8_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
165 static inline uint8_t min8_of(uint8_t x, uint8_t y)
166 {
167  return (x < y) ? x : y;
168 }
169 
170 static inline uint16_t min16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
171 static inline uint16_t min16_of(uint16_t x, uint16_t y)
172 {
173  return (x < y) ? x : y;
174 }
175 
176 static inline uint32_t min32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
177 static inline uint32_t min32_of(uint32_t x, uint32_t y)
178 {
179  return (x < y) ? x : y;
180 }
181 
182 //------------- Max -------------//
183 static inline uint32_t max32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
184 static inline uint32_t max32_of(uint32_t x, uint32_t y)
185 {
186  return (x > y) ? x : y;
187 }
188 
189 static inline uint16_t max16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
190 static inline uint16_t max16_of(uint16_t x, uint16_t y)
191 {
192  return (x > y) ? x : y;
193 }
194 
195 //------------- Align -------------//
196 static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
197 static inline uint32_t align32 (uint32_t value)
198 {
199  return (value & 0xFFFFFFE0UL);
200 }
201 
202 static inline uint32_t align16 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
203 static inline uint32_t align16 (uint32_t value)
204 {
205  return (value & 0xFFFFFFF0UL);
206 }
207 
208 static inline uint32_t align_n (uint32_t alignment, uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
209 static inline uint32_t align_n (uint32_t alignment, uint32_t value)
210 {
211  return value & ((uint32_t) ~(alignment-1));
212 }
213 
214 static inline uint32_t align4k (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
215 static inline uint32_t align4k (uint32_t value)
216 {
217  return (value & 0xFFFFF000UL);
218 }
219 
220 static inline uint32_t offset4k(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
221 static inline uint32_t offset4k(uint32_t value)
222 {
223  return (value & 0xFFFUL);
224 }
225 
226 //------------- Mathematics -------------//
227 static inline uint32_t abs_of(int32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
228 static inline uint32_t abs_of(int32_t value)
229 {
230  return (value < 0) ? (-value) : value;
231 }
232 
233 
235 static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
236 static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper)
237 {
238  return (lower <= value) && (value <= upper);
239 }
240 
242 static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
243 static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper)
244 {
245  return (lower < value) && (value < upper);
246 }
247 
248 // TODO use clz
249 static inline uint8_t log2_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
250 static inline uint8_t log2_of(uint32_t value)
251 {
252  uint8_t result = 0; // log2 of a value is its MSB's position
253 
254  while (value >>= 1)
255  {
256  result++;
257  }
258  return result;
259 }
260 
261 // return the number of set bits in value
262 static inline uint8_t cardinality_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
263 static inline uint8_t cardinality_of(uint32_t value)
264 {
265  // Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only
266  // the high bit set, then it will only go once through the loop
267  // Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie)
268  // mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method
269  // "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and
270  // published in 1964 in a book edited by Beckenbach.)"
271  uint8_t count;
272  for (count = 0; value; count++)
273  {
274  value &= value - 1; // clear the least significant bit set
275  }
276 
277  return count;
278 }
279 
280 #ifdef __cplusplus
281  }
282 #endif
283 
284 #endif /* _TUSB_COMMON_H_ */
285 
#define ATTR_PURE
Many functions have no effects except the return value and their return value depends only on the par...
Definition: compiler_gcc.h:96
static bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST
inclusive range checking
Definition: common.h:236
static uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) ATTR_ALWAYS_INLINE ATTR_CONST
form an uint32_t from 4 x uint8_t
Definition: common.h:140
static bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST
exclusive range checking
Definition: common.h:243
#define ATTR_ALWAYS_INLINE
Generally, functions are not inlined unless optimization is specified. For functions declared inline...
Definition: compiler_gcc.h:89
#define ATTR_CONST
Many functions do not examine any values except their arguments, and have no effects except the retur...
Definition: compiler_gcc.h:100