]> git.gir.st - tmk_keyboard.git/blob - tmk_core/protocol/lufa/LUFA-git/LUFA/Common/Endianness.h
Merge commit 'f6d56675f9f981c5464f0ca7a1fbb0162154e8c5'
[tmk_keyboard.git] / tmk_core / protocol / lufa / LUFA-git / LUFA / Common / Endianness.h
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2014.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2014 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 disclaims 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 /* Enable C linkage for C++ Compilers: */
60 #if defined(__cplusplus)
61 extern "C" {
62 #endif
63
64 /* Preprocessor Checks: */
65 #if !defined(__INCLUDE_FROM_COMMON_H)
66 #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality.
67 #endif
68
69 #if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
70 #error ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set for the specified architecture.
71 #endif
72
73 /* Public Interface - May be used in end-application: */
74 /* Macros: */
75 /** Swaps the byte ordering of a 16-bit value at compile-time. Do not use this macro for swapping byte orderings
76 * of dynamic values computed at runtime, use \ref SwapEndian_16() instead. The result of this macro can be used
77 * inside struct or other variable initializers outside of a function, something that is not possible with the
78 * inline function variant.
79 *
80 * \hideinitializer
81 *
82 * \ingroup Group_ByteSwapping
83 *
84 * \param[in] x 16-bit value whose byte ordering is to be swapped.
85 *
86 * \return Input value with the byte ordering reversed.
87 */
88 #define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
89
90 /** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings
91 * of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used
92 * inside struct or other variable initializers outside of a function, something that is not possible with the
93 * inline function variant.
94 *
95 * \hideinitializer
96 *
97 * \ingroup Group_ByteSwapping
98 *
99 * \param[in] x 32-bit value whose byte ordering is to be swapped.
100 *
101 * \return Input value with the byte ordering reversed.
102 */
103 #define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \
104 (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL))
105
106 #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu)
107 #define le16_to_cpu(x) SwapEndian_16(x)
108 #define le32_to_cpu(x) SwapEndian_32(x)
109 #define be16_to_cpu(x) (x)
110 #define be32_to_cpu(x) (x)
111 #define cpu_to_le16(x) SwapEndian_16(x)
112 #define cpu_to_le32(x) SwapEndian_32(x)
113 #define cpu_to_be16(x) (x)
114 #define cpu_to_be32(x) (x)
115 #define LE16_TO_CPU(x) SWAPENDIAN_16(x)
116 #define LE32_TO_CPU(x) SWAPENDIAN_32(x)
117 #define BE16_TO_CPU(x) (x)
118 #define BE32_TO_CPU(x) (x)
119 #define CPU_TO_LE16(x) SWAPENDIAN_16(x)
120 #define CPU_TO_LE32(x) SWAPENDIAN_32(x)
121 #define CPU_TO_BE16(x) (x)
122 #define CPU_TO_BE32(x) (x)
123 #elif !defined(le16_to_cpu)
124 /** \name Run-time endianness conversion */
125 //@{
126
127 /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
128 * Endianness of the currently selected CPU architecture.
129 *
130 * On little endian architectures, this macro does nothing.
131 *
132 * \note This macro is designed for run-time conversion of data - for compile-time endianness
133 * conversion, use \ref LE16_TO_CPU instead.
134 *
135 * \ingroup Group_EndianConversion
136 *
137 * \param[in] x Data to perform the endianness conversion on.
138 *
139 * \return Endian corrected version of the input value.
140 */
141 #define le16_to_cpu(x) (x)
142
143 /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
144 * Endianness of the currently selected CPU architecture.
145 *
146 * On little endian architectures, this macro does nothing.
147 *
148 * \note This macro is designed for run-time conversion of data - for compile-time endianness
149 * conversion, use \ref LE32_TO_CPU instead.
150 *
151 * \ingroup Group_EndianConversion
152 *
153 * \param[in] x Data to perform the endianness conversion on.
154 *
155 * \return Endian corrected version of the input value.
156 */
157 #define le32_to_cpu(x) (x)
158
159 /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
160 * Endianness of the currently selected CPU architecture.
161 *
162 * On big endian architectures, this macro does nothing.
163 *
164 * \note This macro is designed for run-time conversion of data - for compile-time endianness
165 * conversion, use \ref BE16_TO_CPU instead.
166 *
167 * \ingroup Group_EndianConversion
168 *
169 * \param[in] x Data to perform the endianness conversion on.
170 *
171 * \return Endian corrected version of the input value.
172 */
173 #define be16_to_cpu(x) SwapEndian_16(x)
174
175 /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
176 * Endianness of the currently selected CPU architecture.
177 *
178 * On big endian architectures, this macro does nothing.
179 *
180 * \note This macro is designed for run-time conversion of data - for compile-time endianness
181 * conversion, use \ref BE32_TO_CPU instead.
182 *
183 * \ingroup Group_EndianConversion
184 *
185 * \param[in] x Data to perform the endianness conversion on.
186 *
187 * \return Endian corrected version of the input value.
188 */
189 #define be32_to_cpu(x) SwapEndian_32(x)
190
191 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
192 * is in Little Endian format regardless of the currently selected CPU architecture.
193 *
194 * On little endian architectures, this macro does nothing.
195 *
196 * \note This macro is designed for run-time conversion of data - for compile-time endianness
197 * conversion, use \ref CPU_TO_LE16 instead.
198 *
199 * \ingroup Group_EndianConversion
200 *
201 * \param[in] x Data to perform the endianness conversion on.
202 *
203 * \return Endian corrected version of the input value.
204 */
205 #define cpu_to_le16(x) (x)
206
207 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
208 * is in Little Endian format regardless of the currently selected CPU architecture.
209 *
210 * On little endian architectures, this macro does nothing.
211 *
212 * \note This macro is designed for run-time conversion of data - for compile-time endianness
213 * conversion, use \ref CPU_TO_LE32 instead.
214 *
215 * \ingroup Group_EndianConversion
216 *
217 * \param[in] x Data to perform the endianness conversion on.
218 *
219 * \return Endian corrected version of the input value.
220 */
221 #define cpu_to_le32(x) (x)
222
223 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
224 * is in Big Endian format regardless of the currently selected CPU architecture.
225 *
226 * On big endian architectures, this macro does nothing.
227 *
228 * \note This macro is designed for run-time conversion of data - for compile-time endianness
229 * conversion, use \ref CPU_TO_BE16 instead.
230 *
231 * \ingroup Group_EndianConversion
232 *
233 * \param[in] x Data to perform the endianness conversion on.
234 *
235 * \return Endian corrected version of the input value.
236 */
237 #define cpu_to_be16(x) SwapEndian_16(x)
238
239 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
240 * is in Big Endian format regardless of the currently selected CPU architecture.
241 *
242 * On big endian architectures, this macro does nothing.
243 *
244 * \note This macro is designed for run-time conversion of data - for compile-time endianness
245 * conversion, use \ref CPU_TO_BE32 instead.
246 *
247 * \ingroup Group_EndianConversion
248 *
249 * \param[in] x Data to perform the endianness conversion on.
250 *
251 * \return Endian corrected version of the input value.
252 */
253 #define cpu_to_be32(x) SwapEndian_32(x)
254
255 //@}
256
257 /** \name Compile-time endianness conversion */
258 //@{
259
260 /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the
261 * Endianness of the currently selected CPU architecture.
262 *
263 * On little endian architectures, this macro does nothing.
264 *
265 * \note This macro is designed for compile-time conversion of data - for run time endianness
266 * conversion, use \ref le16_to_cpu instead.
267 *
268 * \ingroup Group_EndianConversion
269 *
270 * \param[in] x Data to perform the endianness conversion on.
271 *
272 * \return Endian corrected version of the input value.
273 */
274 #define LE16_TO_CPU(x) (x)
275
276 /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
277 * Endianness of the currently selected CPU architecture.
278 *
279 * On little endian architectures, this macro does nothing.
280 *
281 * \note This macro is designed for compile-time conversion of data - for run time endianness
282 * conversion, use \ref le32_to_cpu instead.
283 *
284 * \ingroup Group_EndianConversion
285 *
286 * \param[in] x Data to perform the endianness conversion on.
287 *
288 * \return Endian corrected version of the input value.
289 */
290 #define LE32_TO_CPU(x) (x)
291
292 /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
293 * Endianness of the currently selected CPU architecture.
294 *
295 * On big endian architectures, this macro does nothing.
296 *
297 * \note This macro is designed for compile-time conversion of data - for run-time endianness
298 * conversion, use \ref be16_to_cpu instead.
299 *
300 * \ingroup Group_EndianConversion
301 *
302 * \param[in] x Data to perform the endianness conversion on.
303 *
304 * \return Endian corrected version of the input value.
305 */
306 #define BE16_TO_CPU(x) SWAPENDIAN_16(x)
307
308 /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the
309 * Endianness of the currently selected CPU architecture.
310 *
311 * On big endian architectures, this macro does nothing.
312 *
313 * \note This macro is designed for compile-time conversion of data - for run-time endianness
314 * conversion, use \ref be32_to_cpu instead.
315 *
316 * \ingroup Group_EndianConversion
317 *
318 * \param[in] x Data to perform the endianness conversion on.
319 *
320 * \return Endian corrected version of the input value.
321 */
322 #define BE32_TO_CPU(x) SWAPENDIAN_32(x)
323
324 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
325 * is in Little Endian format regardless of the currently selected CPU architecture.
326 *
327 * On little endian architectures, this macro does nothing.
328 *
329 * \note This macro is designed for compile-time conversion of data - for run-time endianness
330 * conversion, use \ref cpu_to_le16 instead.
331 *
332 * \ingroup Group_EndianConversion
333 *
334 * \param[in] x Data to perform the endianness conversion on.
335 *
336 * \return Endian corrected version of the input value.
337 */
338 #define CPU_TO_LE16(x) (x)
339
340 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
341 * is in Little Endian format regardless of the currently selected CPU architecture.
342 *
343 * On little endian architectures, this macro does nothing.
344 *
345 * \note This macro is designed for compile-time conversion of data - for run-time endianness
346 * conversion, use \ref cpu_to_le32 instead.
347 *
348 * \ingroup Group_EndianConversion
349 *
350 * \param[in] x Data to perform the endianness conversion on.
351 *
352 * \return Endian corrected version of the input value.
353 */
354 #define CPU_TO_LE32(x) (x)
355
356 /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
357 * is in Big Endian format regardless of the currently selected CPU architecture.
358 *
359 * On big endian architectures, this macro does nothing.
360 *
361 * \note This macro is designed for compile-time conversion of data - for run-time endianness
362 * conversion, use \ref cpu_to_be16 instead.
363 *
364 * \ingroup Group_EndianConversion
365 *
366 * \param[in] x Data to perform the endianness conversion on.
367 *
368 * \return Endian corrected version of the input value.
369 */
370 #define CPU_TO_BE16(x) SWAPENDIAN_16(x)
371
372 /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
373 * is in Big Endian format regardless of the currently selected CPU architecture.
374 *
375 * On big endian architectures, this macro does nothing.
376 *
377 * \note This macro is designed for compile-time conversion of data - for run-time endianness
378 * conversion, use \ref cpu_to_be32 instead.
379 *
380 * \ingroup Group_EndianConversion
381 *
382 * \param[in] x Data to perform the endianness conversion on.
383 *
384 * \return Endian corrected version of the input value.
385 */
386 #define CPU_TO_BE32(x) SWAPENDIAN_32(x)
387
388 //! @}
389 #endif
390
391 /* Inline Functions: */
392 /** Function to reverse the byte ordering of the individual bytes in a 16 bit value.
393 *
394 * \ingroup Group_ByteSwapping
395 *
396 * \param[in] Word Word of data whose bytes are to be swapped.
397 *
398 * \return Input data with the individual bytes reversed.
399 */
400 static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
401 static inline uint16_t SwapEndian_16(const uint16_t Word)
402 {
403 if (GCC_IS_COMPILE_CONST(Word))
404 return SWAPENDIAN_16(Word);
405
406 uint8_t Temp;
407
408 union
409 {
410 uint16_t Word;
411 uint8_t Bytes[2];
412 } Data;
413
414 Data.Word = Word;
415
416 Temp = Data.Bytes[0];
417 Data.Bytes[0] = Data.Bytes[1];
418 Data.Bytes[1] = Temp;
419
420 return Data.Word;
421 }
422
423 /** Function to reverse the byte ordering of the individual bytes in a 32 bit value.
424 *
425 * \ingroup Group_ByteSwapping
426 *
427 * \param[in] DWord Double word of data whose bytes are to be swapped.
428 *
429 * \return Input data with the individual bytes reversed.
430 */
431 static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
432 static inline uint32_t SwapEndian_32(const uint32_t DWord)
433 {
434 if (GCC_IS_COMPILE_CONST(DWord))
435 return SWAPENDIAN_32(DWord);
436
437 uint8_t Temp;
438
439 union
440 {
441 uint32_t DWord;
442 uint8_t Bytes[4];
443 } Data;
444
445 Data.DWord = DWord;
446
447 Temp = Data.Bytes[0];
448 Data.Bytes[0] = Data.Bytes[3];
449 Data.Bytes[3] = Temp;
450
451 Temp = Data.Bytes[1];
452 Data.Bytes[1] = Data.Bytes[2];
453 Data.Bytes[2] = Temp;
454
455 return Data.DWord;
456 }
457
458 /** Function to reverse the byte ordering of the individual bytes in a n byte value.
459 *
460 * \ingroup Group_ByteSwapping
461 *
462 * \param[in,out] Data Pointer to a number containing an even number of bytes to be reversed.
463 * \param[in] Length Length of the data in bytes.
464 *
465 * \return Input data with the individual bytes reversed.
466 */
467 static inline void SwapEndian_n(void* const Data,
468 uint8_t Length) ATTR_NON_NULL_PTR_ARG(1);
469 static inline void SwapEndian_n(void* const Data,
470 uint8_t Length)
471 {
472 uint8_t* CurrDataPos = (uint8_t*)Data;
473
474 while (Length > 1)
475 {
476 uint8_t Temp = *CurrDataPos;
477 *CurrDataPos = *(CurrDataPos + Length - 1);
478 *(CurrDataPos + Length - 1) = Temp;
479
480 CurrDataPos++;
481 Length -= 2;
482 }
483 }
484
485 /* Disable C linkage for C++ Compilers: */
486 #if defined(__cplusplus)
487 }
488 #endif
489
490 #endif
491
492 /** @} */
493
Imprint / Impressum