LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Endianness.h
Go to the documentation of this file.
1 /*
2  * @brief Endianness declaration
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * Copyright(C) Dean Camera, 2011, 2012
7  * All rights reserved.
8  *
9  * @par
10  * Software that is described herein is for illustrative purposes only
11  * which provides customers with programming information regarding the
12  * LPC products. This software is supplied "AS IS" without any warranties of
13  * any kind, and NXP Semiconductors and its licensor disclaim any and
14  * all warranties, express or implied, including all implied warranties of
15  * merchantability, fitness for a particular purpose and non-infringement of
16  * intellectual property rights. NXP Semiconductors assumes no responsibility
17  * or liability for the use of the software, conveys no license or rights under any
18  * patent, copyright, mask work right, or any other intellectual property rights in
19  * or to any products. NXP Semiconductors reserves the right to make changes
20  * in the software without notification. NXP Semiconductors also makes no
21  * representation or warranty that such application will be suitable for the
22  * specified use without further testing or modification.
23  *
24  * @par
25  * Permission to use, copy, modify, and distribute this software and its
26  * documentation is hereby granted, under NXP Semiconductors' and its
27  * licensor's relevant copyrights in the software, without fee, provided that it
28  * is used in conjunction with NXP Semiconductors microcontrollers. This
29  * copyright, permission, and disclaimer notice must appear in all copies of
30  * this code.
31 */
32 
33 
34 
54 #ifndef __LPCUSBlib_ENDIANNESS_H__
55 #define __LPCUSBlib_ENDIANNESS_H__
56 
57  /* Enable C linkage for C++ Compilers: */
58  #if defined(__cplusplus)
59  extern "C" {
60  #endif
61 
62  /* Preprocessor Checks: */
63  #if !defined(__INCLUDE_FROM_COMMON_H)
64  #error Do not include this file directly. Include LPCUSBlib/Common/Common.h instead to gain this functionality.
65  #endif
66 
67  #if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
68  #error ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set for the specified architecture.
69  #endif
70 
71  /* Public Interface - May be used in end-application: */
72  /* Macros: */
84  #define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
85 
97  #define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \
98  (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL))
99 
100  #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu)
101  #define le16_to_cpu(x) SwapEndian_16(x)
102  #define le32_to_cpu(x) SwapEndian_32(x)
103  #define be16_to_cpu(x) (x)
104  #define be32_to_cpu(x) (x)
105  #define cpu_to_le16(x) SwapEndian_16(x)
106  #define cpu_to_le32(x) SwapEndian_32(x)
107  #define cpu_to_be16(x) (x)
108  #define cpu_to_be32(x) (x)
109  #define LE16_TO_CPU(x) SWAPENDIAN_16(x)
110  #define LE32_TO_CPU(x) SWAPENDIAN_32(x)
111  #define BE16_TO_CPU(x) (x)
112  #define BE32_TO_CPU(x) (x)
113  #define CPU_TO_LE16(x) SWAPENDIAN_16(x)
114  #define CPU_TO_LE32(x) SWAPENDIAN_32(x)
115  #define CPU_TO_BE16(x) (x)
116  #define CPU_TO_BE32(x) (x)
117  #elif !defined(le16_to_cpu)
118 
120 
135  #define le16_to_cpu(x) (x)
136 
151  #define le32_to_cpu(x) (x)
152 
167  #define be16_to_cpu(x) SwapEndian_16(x)
168 
183  #define be32_to_cpu(x) SwapEndian_32(x)
184 
199  #define cpu_to_le16(x) (x)
200 
215  #define cpu_to_le32(x) (x)
216 
231  #define cpu_to_be16(x) SwapEndian_16(x)
232 
247  #define cpu_to_be32(x) SwapEndian_32(x)
248 
250 
253 
268  #define LE16_TO_CPU(x) (x)
269 
284  #define LE32_TO_CPU(x) (x)
285 
300  #define BE16_TO_CPU(x) SWAPENDIAN_16(x)
301 
316  #define BE32_TO_CPU(x) SWAPENDIAN_32(x)
317 
332  #define CPU_TO_LE16(x) (x)
333 
348  #define CPU_TO_LE32(x) (x)
349 
364  #define CPU_TO_BE16(x) SWAPENDIAN_16(x)
365 
380  #define CPU_TO_BE32(x) SWAPENDIAN_32(x)
381 
383  #endif
384 
385  /* Inline Functions: */
392  static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
393  static inline uint16_t SwapEndian_16(const uint16_t Word)
394  {
395  if (GCC_IS_COMPILE_CONST(Word))
396  return SWAPENDIAN_16(Word);
397 
398  uint8_t Temp;
399 
400  union
401  {
402  uint16_t Word;
403  uint8_t Bytes[2];
404  } Data;
405 
406  Data.Word = Word;
407 
408  Temp = Data.Bytes[0];
409  Data.Bytes[0] = Data.Bytes[1];
410  Data.Bytes[1] = Temp;
411 
412  return Data.Word;
413  }
414 
422  static inline uint32_t SwapEndian_32(const uint32_t DWord)
423  {
424  if (GCC_IS_COMPILE_CONST(DWord))
425  return SWAPENDIAN_32(DWord);
426 
427  uint8_t Temp;
428 
429  union
430  {
431  uint32_t DWord;
432  uint8_t Bytes[4];
433  } Data;
434 
435  Data.DWord = DWord;
436 
437  Temp = Data.Bytes[0];
438  Data.Bytes[0] = Data.Bytes[3];
439  Data.Bytes[3] = Temp;
440 
441  Temp = Data.Bytes[1];
442  Data.Bytes[1] = Data.Bytes[2];
443  Data.Bytes[2] = Temp;
444 
445  return Data.DWord;
446  }
447 
455  static inline void SwapEndian_n(void* const Data,
456  uint8_t Length) ATTR_NON_NULL_PTR_ARG(1);
457  static inline void SwapEndian_n(void* const Data,
458  uint8_t Length)
459  {
460  uint8_t* CurrDataPos = (uint8_t*)Data;
461 
462  while (Length > 1)
463  {
464  uint8_t Temp = *CurrDataPos;
465  *CurrDataPos = *(CurrDataPos + Length - 1);
466  *(CurrDataPos + Length - 1) = Temp;
467 
468  CurrDataPos++;
469  Length -= 2;
470  }
471  }
472 
473  /* Disable C linkage for C++ Compilers: */
474  #if defined(__cplusplus)
475  }
476  #endif
477 
478 #endif
479