Fix corner case in the HID report descriptor Mouse/Joystick tempates at the 8/16...
[pub/USBasp.git] / LUFA / Common / Endianness.h
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2011.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 /** \file
32 * \brief Endianness and Byte Ordering macros and functions.
33 *
34 * \copydetails Group_Endianness
35 */
36
37 /** \ingroup Group_Endianness
38 * \defgroup Group_ByteSwapping Byte Reordering
39 * \brief Macros and functions for forced byte reordering.
40 */
41
42 /** \ingroup Group_Endianness
43 * \defgroup Group_EndianConversion Endianness Conversion
44 * \brief Macros and functions for automatic endianness conversion.
45 */
46
47 /** \ingroup Group_Common
48 * \defgroup Group_Endianness Endianness and Byte Ordering
49 * \brief Convenience macros and functions relating to byte (re-)ordering
50 *
51 * Common library convenience macros and functions relating to byte (re-)ordering.
52 *
53 * @{
54 */
55
56 #ifndef __LUFA_ENDIANNESS_H__
57 #define __LUFA_ENDIANNESS_H__
58
59 /* Preprocessor Checks: */
60 #if !defined(__INCLUDE_FROM_COMMON_H)
61 #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
62 #endif
63
64 /* Public Interface - May be used in end-application: */
65 /* Macros: */
66 /** Swaps the byte ordering of a 16-bit value at compile-time. Do not use this macro for swapping byte orderings
67 * of dynamic values computed at runtime, use \ref SwapEndian_16() instead. The result of this macro can be used
68 * inside struct or other variable initializers outside of a function, something that is not possible with the
69 * inline function variant.
70 *
71 * \ingroup Group_ByteSwapping
72 *
73 * \param[in] x 16-bit value whose byte ordering is to be swapped.
74 *
75 * \return Input value with the byte ordering reversed.
76 */
77 #define SWAPENDIAN_16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
78
79 /** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings
80 * of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used
81 * inside struct or other variable initializers outside of a function, something that is not possible with the
82 * inline function variant.
83 *
84 * \ingroup Group_ByteSwapping
85 *
86 * \param[in] x 32-bit value whose byte ordering is to be swapped.
87 *
88 * \return Input value with the byte ordering reversed.
89 */
90 #define SWAPENDIAN_32(x) ((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \
91 (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL))
92
93 #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu)
94 #define le16_to_cpu(x) SwapEndian_16(x)
95 #define le32_to_cpu(x) SwapEndian_32(x)
96 #define be16_to_cpu(x) x
97 #define be32_to_cpu(x) x
98 #define cpu_to_le16(x) SwapEndian_16(x)
99 #define cpu_to_le32(x) SwapEndian_32(x)
100 #define cpu_to_be16(x) x
101 #define cpu_to_be32(x) x
102 #define LE16_TO_CPU(x) SWAPENDIAN_16(x)
103 #define LE32_TO_CPU(x) SWAPENDIAN_32(x)
104 #define BE16_TO_CPU(x) x
105 #define BE32_TO_CPU(x) x
106 #define CPU_TO_LE16(x) SWAPENDIAN_16(x)
107 #define CPU_TO_LE32(x) SWAPENDIAN_32(x)
108 #define CPU_TO_BE16(x) x
109 #define CPU_TO_BE32(x) x
110 #elif !defined(le16_to_cpu)
111 /** \name Run-time endianness conversion */
112 //@{
113
114 /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
115 * Endianness of the currently selected CPU architecture.
116 *
117 * On little endian architectures, this macro does nothing.
118 *
119 * \note This macro is designed for run-time conversion of data - for compile-time endianness
120 * conversion, use \ref LE16_TO_CPU instead.
121 *
122 * \ingroup Group_EndianConversion
123 *
124 * \param[in] x Data to perform the endianness conversion on.
125 *
126 * \return Endian corrected version of the input value.
127 */
128 #define le16_to_cpu(x) x
129
130 /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
131 * Endianness of the currently selected CPU architecture.
132 *
133 * On little endian architectures, this macro does nothing.
134 *
135 * \note This macro is designed for run-time conversion of data - for compile-time endianness
136 * conversion, use \ref LE32_TO_CPU instead.
137 *
138 * \ingroup Group_EndianConversion
139 *
140 * \param[in] x Data to perform the endianness conversion on.
141 *
142 * \return Endian corrected version of the input value.
143 */
144 #define le32_to_cpu(x) x
145
146 /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
147 * Endianness of the currently selected CPU architecture.
148 *
149 * On big endian architectures, this macro does nothing.
150 *
151 * \note This macro is designed for run-time conversion of data - for compile-time endianness
152 * conversion, use \ref BE16_TO_CPU instead.
153 *
154 * \ingroup Group_EndianConversion
155 *
156 * \param[in] x Data to perform the endianness conversion on.
157 *
158 * \return Endian corrected version of the input value.
159 */
160 #define be16_to_cpu(x) SwapEndian_16(x)
161
162 /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
163 * Endianness of the currently selected CPU architecture.
164 *
165 * On big endian architectures, this macro does nothing.
166 *
167 * \note This macro is designed for run-time conversion of data - for compile-time endianness
168 * conversion, use \ref BE32_TO_CPU instead.
169 *
170 * \ingroup Group_EndianConversion
171 *
172 * \param[in] x Data to perform the endianness conversion on.
173 *
174 * \return Endian corrected version of the input value.
175 */
176 #define be32_to_cpu(x) SwapEndian_32(x)
177
178 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
179 * is in Little Endian format regardless of the currently selected CPU architecture.
180 *
181 * On little endian architectures, this macro does nothing.
182 *
183 * \note This macro is designed for run-time conversion of data - for compile-time endianness
184 * conversion, use \ref CPU_TO_LE16 instead.
185 *
186 * \ingroup Group_EndianConversion
187 *
188 * \param[in] x Data to perform the endianness conversion on.
189 *
190 * \return Endian corrected version of the input value.
191 */
192 #define cpu_to_le16(x) x
193
194 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
195 * is in Little Endian format regardless of the currently selected CPU architecture.
196 *
197 * On little endian architectures, this macro does nothing.
198 *
199 * \note This macro is designed for run-time conversion of data - for compile-time endianness
200 * conversion, use \ref CPU_TO_LE32 instead.
201 *
202 * \ingroup Group_EndianConversion
203 *
204 * \param[in] x Data to perform the endianness conversion on.
205 *
206 * \return Endian corrected version of the input value.
207 */
208 #define cpu_to_le32(x) x
209
210 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
211 * is in Big Endian format regardless of the currently selected CPU architecture.
212 *
213 * On big endian architectures, this macro does nothing.
214 *
215 * \note This macro is designed for run-time conversion of data - for compile-time endianness
216 * conversion, use \ref CPU_TO_BE16 instead.
217 *
218 * \ingroup Group_EndianConversion
219 *
220 * \param[in] x Data to perform the endianness conversion on.
221 *
222 * \return Endian corrected version of the input value.
223 */
224 #define cpu_to_be16(x) SwapEndian_16(x)
225
226 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
227 * is in Big Endian format regardless of the currently selected CPU architecture.
228 *
229 * On big endian architectures, this macro does nothing.
230 *
231 * \note This macro is designed for run-time conversion of data - for compile-time endianness
232 * conversion, use \ref CPU_TO_BE32 instead.
233 *
234 * \ingroup Group_EndianConversion
235 *
236 * \param[in] x Data to perform the endianness conversion on.
237 *
238 * \return Endian corrected version of the input value.
239 */
240 #define cpu_to_be32(x) SwapEndian_32(x)
241
242 //@}
243
244 /** \name Compile-time endianness conversion */
245 //@{
246
247 /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
248 * Endianness of the currently selected CPU architecture.
249 *
250 * On little endian architectures, this macro does nothing.
251 *
252 * \note This macro is designed for compile-time conversion of data - for run time endianness
253 * conversion, use \ref le16_to_cpu instead.
254 *
255 * \ingroup Group_EndianConversion
256 *
257 * \param[in] x Data to perform the endianness conversion on.
258 *
259 * \return Endian corrected version of the input value.
260 */
261 #define LE16_TO_CPU(x) x
262
263 /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
264 * Endianness of the currently selected CPU architecture.
265 *
266 * On little endian architectures, this macro does nothing.
267 *
268 * \note This macro is designed for compile-time conversion of data - for run time endianness
269 * conversion, use \ref le32_to_cpu instead.
270 *
271 * \ingroup Group_EndianConversion
272 *
273 * \param[in] x Data to perform the endianness conversion on.
274 *
275 * \return Endian corrected version of the input value.
276 */
277 #define LE32_TO_CPU(x) x
278
279 /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
280 * Endianness of the currently selected CPU architecture.
281 *
282 * On big endian architectures, this macro does nothing.
283 *
284 * \note This macro is designed for compile-time conversion of data - for run-time endianness
285 * conversion, use \ref be16_to_cpu instead.
286 *
287 * \ingroup Group_EndianConversion
288 *
289 * \param[in] x Data to perform the endianness conversion on.
290 *
291 * \return Endian corrected version of the input value.
292 */
293 #define BE16_TO_CPU(x) SWAPENDIAN_16(x)
294
295 /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
296 * Endianness of the currently selected CPU architecture.
297 *
298 * On big endian architectures, this macro does nothing.
299 *
300 * \note This macro is designed for compile-time conversion of data - for run-time endianness
301 * conversion, use \ref be32_to_cpu instead.
302 *
303 * \ingroup Group_EndianConversion
304 *
305 * \param[in] x Data to perform the endianness conversion on.
306 *
307 * \return Endian corrected version of the input value.
308 */
309 #define BE32_TO_CPU(x) SWAPENDIAN_32(x)
310
311 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
312 * is in Little Endian format regardless of the currently selected CPU architecture.
313 *
314 * On little endian architectures, this macro does nothing.
315 *
316 * \note This macro is designed for compile-time conversion of data - for run-time endianness
317 * conversion, use \ref cpu_to_le16 instead.
318 *
319 * \ingroup Group_EndianConversion
320 *
321 * \param[in] x Data to perform the endianness conversion on.
322 *
323 * \return Endian corrected version of the input value.
324 */
325 #define CPU_TO_LE16(x) x
326
327 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
328 * is in Little Endian format regardless of the currently selected CPU architecture.
329 *
330 * On little endian architectures, this macro does nothing.
331 *
332 * \note This macro is designed for compile-time conversion of data - for run-time endianness
333 * conversion, use \ref cpu_to_le32 instead.
334 *
335 * \ingroup Group_EndianConversion
336 *
337 * \param[in] x Data to perform the endianness conversion on.
338 *
339 * \return Endian corrected version of the input value.
340 */
341 #define CPU_TO_LE32(x) x
342
343 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
344 * is in Big Endian format regardless of the currently selected CPU architecture.
345 *
346 * On big endian architectures, this macro does nothing.
347 *
348 * \note This macro is designed for compile-time conversion of data - for run-time endianness
349 * conversion, use \ref cpu_to_be16 instead.
350 *
351 * \ingroup Group_EndianConversion
352 *
353 * \param[in] x Data to perform the endianness conversion on.
354 *
355 * \return Endian corrected version of the input value.
356 */
357 #define CPU_TO_BE16(x) SWAPENDIAN_16(x)
358
359 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
360 * is in Big Endian format regardless of the currently selected CPU architecture.
361 *
362 * On big endian architectures, this macro does nothing.
363 *
364 * \note This macro is designed for compile-time conversion of data - for run-time endianness
365 * conversion, use \ref cpu_to_be32 instead.
366 *
367 * \ingroup Group_EndianConversion
368 *
369 * \param[in] x Data to perform the endianness conversion on.
370 *
371 * \return Endian corrected version of the input value.
372 */
373 #define CPU_TO_BE32(x) SWAPENDIAN_32(x)
374
375 //! @}
376 #endif
377
378 /* Inline Functions: */
379 /** Function to reverse the byte ordering of the individual bytes in a 16 bit value.
380 *
381 * \ingroup Group_ByteSwapping
382 *
383 * \param[in] Word Word of data whose bytes are to be swapped.
384 */
385 static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
386 static inline uint16_t SwapEndian_16(const uint16_t Word)
387 {
388 uint8_t Temp;
389
390 union
391 {
392 uint16_t Word;
393 uint8_t Bytes[2];
394 } Data;
395
396 Data.Word = Word;
397
398 Temp = Data.Bytes[0];
399 Data.Bytes[0] = Data.Bytes[1];
400 Data.Bytes[1] = Temp;
401
402 return Data.Word;
403 }
404
405 /** Function to reverse the byte ordering of the individual bytes in a 32 bit value.
406 *
407 * \ingroup Group_ByteSwapping
408 *
409 * \param[in] DWord Double word of data whose bytes are to be swapped.
410 */
411 static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
412 static inline uint32_t SwapEndian_32(const uint32_t DWord)
413 {
414 uint8_t Temp;
415
416 union
417 {
418 uint32_t DWord;
419 uint8_t Bytes[4];
420 } Data;
421
422 Data.DWord = DWord;
423
424 Temp = Data.Bytes[0];
425 Data.Bytes[0] = Data.Bytes[3];
426 Data.Bytes[3] = Temp;
427
428 Temp = Data.Bytes[1];
429 Data.Bytes[1] = Data.Bytes[2];
430 Data.Bytes[2] = Temp;
431
432 return Data.DWord;
433 }
434
435 /** Function to reverse the byte ordering of the individual bytes in a n byte value.
436 *
437 * \ingroup Group_ByteSwapping
438 *
439 * \param[in,out] Data Pointer to a number containing an even number of bytes to be reversed.
440 * \param[in] Bytes Length of the data in bytes.
441 */
442 static inline void SwapEndian_n(void* Data,
443 uint8_t Bytes) ATTR_NON_NULL_PTR_ARG(1);
444 static inline void SwapEndian_n(void* Data,
445 uint8_t Bytes)
446 {
447 uint8_t* CurrDataPos = (uint8_t*)Data;
448
449 while (Bytes > 1)
450 {
451 uint8_t Temp = *CurrDataPos;
452 *CurrDataPos = *(CurrDataPos + Bytes - 1);
453 *(CurrDataPos + Bytes - 1) = Temp;
454
455 CurrDataPos++;
456 Bytes -= 2;
457 }
458 }
459
460 #endif
461
462 /** @} */