1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 /**************************************************************************//** 35 36 @File endian_ext.h 37 38 @Description Big/little endian swapping routines. 39 *//***************************************************************************/ 40 41 #ifndef __ENDIAN_EXT_H 42 #define __ENDIAN_EXT_H 43 44 #include "std_ext.h" 45 46 47 /**************************************************************************//** 48 @Group gen_id General Drivers Utilities 49 50 @Description General usage API. This API is intended for usage by both the 51 internal modules and the user's application. 52 53 @{ 54 *//***************************************************************************/ 55 56 /**************************************************************************//** 57 @Group endian_id Big/Little-Endian Conversion 58 59 @Description Routines and macros for Big/Little-Endian conversion and 60 general byte swapping. 61 62 All routines and macros are expecting unsigned values as 63 parameters, but will generate the correct result also for 64 signed values. Therefore, signed/unsigned casting is allowed. 65 @{ 66 *//***************************************************************************/ 67 68 /**************************************************************************//** 69 @Collection Byte-Swap Macros 70 71 Macros for swapping byte order. 72 73 @Cautions The parameters of these macros are evaluated multiple times. 74 For calculated expressions or expressions that contain function 75 calls it is recommended to use the byte-swap routines. 76 77 @{ 78 *//***************************************************************************/ 79 80 /**************************************************************************//** 81 @Description Swaps the byte order of a given 16-bit value. 82 83 @Param[in] val - The 16-bit value to swap. 84 85 @Return The byte-swapped value.. 86 87 @Cautions The given value is evaluated multiple times by this macro. 88 For calculated expressions or expressions that contain function 89 calls it is recommended to use the SwapUint16() routine. 90 91 @hideinitializer 92 *//***************************************************************************/ 93 #define SWAP_UINT16(val) \ 94 ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8))) 95 96 /**************************************************************************//** 97 @Description Swaps the byte order of a given 32-bit value. 98 99 @Param[in] val - The 32-bit value to swap. 100 101 @Return The byte-swapped value.. 102 103 @Cautions The given value is evaluated multiple times by this macro. 104 For calculated expressions or expressions that contain function 105 calls it is recommended to use the SwapUint32() routine. 106 107 @hideinitializer 108 *//***************************************************************************/ 109 #define SWAP_UINT32(val) \ 110 ((uint32_t)((((val) & 0x000000FF) << 24) | \ 111 (((val) & 0x0000FF00) << 8) | \ 112 (((val) & 0x00FF0000) >> 8) | \ 113 (((val) & 0xFF000000) >> 24))) 114 115 /**************************************************************************//** 116 @Description Swaps the byte order of a given 64-bit value. 117 118 @Param[in] val - The 64-bit value to swap. 119 120 @Return The byte-swapped value.. 121 122 @Cautions The given value is evaluated multiple times by this macro. 123 For calculated expressions or expressions that contain function 124 calls it is recommended to use the SwapUint64() routine. 125 126 @hideinitializer 127 *//***************************************************************************/ 128 #define SWAP_UINT64(val) \ 129 ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \ 130 (((val) & 0x000000000000FF00ULL) << 40) | \ 131 (((val) & 0x0000000000FF0000ULL) << 24) | \ 132 (((val) & 0x00000000FF000000ULL) << 8) | \ 133 (((val) & 0x000000FF00000000ULL) >> 8) | \ 134 (((val) & 0x0000FF0000000000ULL) >> 24) | \ 135 (((val) & 0x00FF000000000000ULL) >> 40) | \ 136 (((val) & 0xFF00000000000000ULL) >> 56))) 137 138 /* @} */ 139 140 /**************************************************************************//** 141 @Collection Byte-Swap Routines 142 143 Routines for swapping the byte order of a given parameter and 144 returning the swapped value. 145 146 These inline routines are safer than the byte-swap macros, 147 because they evaluate the parameter expression only once. 148 @{ 149 *//***************************************************************************/ 150 151 /**************************************************************************//** 152 @Function SwapUint16 153 154 @Description Returns the byte-swapped value of a given 16-bit value. 155 156 @Param[in] val - The 16-bit value. 157 158 @Return The byte-swapped value of the parameter. 159 *//***************************************************************************/ 160 static __inline__ uint16_t SwapUint16(uint16_t val) 161 { 162 return (uint16_t)(((val & 0x00FF) << 8) | 163 ((val & 0xFF00) >> 8)); 164 } 165 166 /**************************************************************************//** 167 @Function SwapUint32 168 169 @Description Returns the byte-swapped value of a given 32-bit value. 170 171 @Param[in] val - The 32-bit value. 172 173 @Return The byte-swapped value of the parameter. 174 *//***************************************************************************/ 175 static __inline__ uint32_t SwapUint32(uint32_t val) 176 { 177 return (uint32_t)(((val & 0x000000FF) << 24) | 178 ((val & 0x0000FF00) << 8) | 179 ((val & 0x00FF0000) >> 8) | 180 ((val & 0xFF000000) >> 24)); 181 } 182 183 /**************************************************************************//** 184 @Function SwapUint64 185 186 @Description Returns the byte-swapped value of a given 64-bit value. 187 188 @Param[in] val - The 64-bit value. 189 190 @Return The byte-swapped value of the parameter. 191 *//***************************************************************************/ 192 static __inline__ uint64_t SwapUint64(uint64_t val) 193 { 194 return (uint64_t)(((val & 0x00000000000000FFULL) << 56) | 195 ((val & 0x000000000000FF00ULL) << 40) | 196 ((val & 0x0000000000FF0000ULL) << 24) | 197 ((val & 0x00000000FF000000ULL) << 8) | 198 ((val & 0x000000FF00000000ULL) >> 8) | 199 ((val & 0x0000FF0000000000ULL) >> 24) | 200 ((val & 0x00FF000000000000ULL) >> 40) | 201 ((val & 0xFF00000000000000ULL) >> 56)); 202 } 203 204 /* @} */ 205 206 /**************************************************************************//** 207 @Collection In-place Byte-Swap-And-Set Routines 208 209 Routines for swapping the byte order of a given variable and 210 setting the swapped value back to the same variable. 211 @{ 212 *//***************************************************************************/ 213 214 /**************************************************************************//** 215 @Function SwapUint16P 216 217 @Description Swaps the byte order of a given 16-bit variable. 218 219 @Param[in] p_Val - Pointer to the 16-bit variable. 220 221 @Return None. 222 *//***************************************************************************/ 223 static __inline__ void SwapUint16P(uint16_t *p_Val) 224 { 225 *p_Val = SwapUint16(*p_Val); 226 } 227 228 /**************************************************************************//** 229 @Function SwapUint32P 230 231 @Description Swaps the byte order of a given 32-bit variable. 232 233 @Param[in] p_Val - Pointer to the 32-bit variable. 234 235 @Return None. 236 *//***************************************************************************/ 237 static __inline__ void SwapUint32P(uint32_t *p_Val) 238 { 239 *p_Val = SwapUint32(*p_Val); 240 } 241 242 /**************************************************************************//** 243 @Function SwapUint64P 244 245 @Description Swaps the byte order of a given 64-bit variable. 246 247 @Param[in] p_Val - Pointer to the 64-bit variable. 248 249 @Return None. 250 *//***************************************************************************/ 251 static __inline__ void SwapUint64P(uint64_t *p_Val) 252 { 253 *p_Val = SwapUint64(*p_Val); 254 } 255 256 /* @} */ 257 258 259 /**************************************************************************//** 260 @Collection Little-Endian Conversion Macros 261 262 These macros convert given parameters to or from Little-Endian 263 format. Use these macros when you want to read or write a specific 264 Little-Endian value in memory, without a-priori knowing the CPU 265 byte order. 266 267 These macros use the byte-swap routines. For conversion of 268 constants in initialization structures, you may use the CONST 269 versions of these macros (see below), which are using the 270 byte-swap macros instead. 271 @{ 272 *//***************************************************************************/ 273 274 /**************************************************************************//** 275 @Description Converts a given 16-bit value from CPU byte order to 276 Little-Endian byte order. 277 278 @Param[in] val - The 16-bit value to convert. 279 280 @Return The converted value. 281 282 @hideinitializer 283 *//***************************************************************************/ 284 #define CPU_TO_LE16(val) SwapUint16(val) 285 286 /**************************************************************************//** 287 @Description Converts a given 32-bit value from CPU byte order to 288 Little-Endian byte order. 289 290 @Param[in] val - The 32-bit value to convert. 291 292 @Return The converted value. 293 294 @hideinitializer 295 *//***************************************************************************/ 296 #define CPU_TO_LE32(val) SwapUint32(val) 297 298 /**************************************************************************//** 299 @Description Converts a given 64-bit value from CPU byte order to 300 Little-Endian byte order. 301 302 @Param[in] val - The 64-bit value to convert. 303 304 @Return The converted value. 305 306 @hideinitializer 307 *//***************************************************************************/ 308 #define CPU_TO_LE64(val) SwapUint64(val) 309 310 311 /**************************************************************************//** 312 @Description Converts a given 16-bit value from Little-Endian byte order to 313 CPU byte order. 314 315 @Param[in] val - The 16-bit value to convert. 316 317 @Return The converted value. 318 319 @hideinitializer 320 *//***************************************************************************/ 321 #define LE16_TO_CPU(val) CPU_TO_LE16(val) 322 323 /**************************************************************************//** 324 @Description Converts a given 32-bit value from Little-Endian byte order to 325 CPU byte order. 326 327 @Param[in] val - The 32-bit value to convert. 328 329 @Return The converted value. 330 331 @hideinitializer 332 *//***************************************************************************/ 333 #define LE32_TO_CPU(val) CPU_TO_LE32(val) 334 335 /**************************************************************************//** 336 @Description Converts a given 64-bit value from Little-Endian byte order to 337 CPU byte order. 338 339 @Param[in] val - The 64-bit value to convert. 340 341 @Return The converted value. 342 343 @hideinitializer 344 *//***************************************************************************/ 345 #define LE64_TO_CPU(val) CPU_TO_LE64(val) 346 347 /* @} */ 348 349 /**************************************************************************//** 350 @Collection Little-Endian Constant Conversion Macros 351 352 These macros convert given constants to or from Little-Endian 353 format. Use these macros when you want to read or write a specific 354 Little-Endian constant in memory, without a-priori knowing the 355 CPU byte order. 356 357 These macros use the byte-swap macros, therefore can be used for 358 conversion of constants in initialization structures. 359 360 @Cautions The parameters of these macros are evaluated multiple times. 361 For non-constant expressions, use the non-CONST macro versions. 362 363 @{ 364 *//***************************************************************************/ 365 366 /**************************************************************************//** 367 @Description Converts a given 16-bit constant from CPU byte order to 368 Little-Endian byte order. 369 370 @Param[in] val - The 16-bit value to convert. 371 372 @Return The converted value. 373 374 @hideinitializer 375 *//***************************************************************************/ 376 #define CONST_CPU_TO_LE16(val) SWAP_UINT16(val) 377 378 /**************************************************************************//** 379 @Description Converts a given 32-bit constant from CPU byte order to 380 Little-Endian byte order. 381 382 @Param[in] val - The 32-bit value to convert. 383 384 @Return The converted value. 385 386 @hideinitializer 387 *//***************************************************************************/ 388 #define CONST_CPU_TO_LE32(val) SWAP_UINT32(val) 389 390 /**************************************************************************//** 391 @Description Converts a given 64-bit constant from CPU byte order to 392 Little-Endian byte order. 393 394 @Param[in] val - The 64-bit value to convert. 395 396 @Return The converted value. 397 398 @hideinitializer 399 *//***************************************************************************/ 400 #define CONST_CPU_TO_LE64(val) SWAP_UINT64(val) 401 402 403 /**************************************************************************//** 404 @Description Converts a given 16-bit constant from Little-Endian byte order 405 to CPU byte order. 406 407 @Param[in] val - The 16-bit value to convert. 408 409 @Return The converted value. 410 411 @hideinitializer 412 *//***************************************************************************/ 413 #define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val) 414 415 /**************************************************************************//** 416 @Description Converts a given 32-bit constant from Little-Endian byte order 417 to CPU byte order. 418 419 @Param[in] val - The 32-bit value to convert. 420 421 @Return The converted value. 422 423 @hideinitializer 424 *//***************************************************************************/ 425 #define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val) 426 427 /**************************************************************************//** 428 @Description Converts a given 64-bit constant from Little-Endian byte order 429 to CPU byte order. 430 431 @Param[in] val - The 64-bit value to convert. 432 433 @Return The converted value. 434 435 @hideinitializer 436 *//***************************************************************************/ 437 #define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val) 438 439 /* @} */ 440 441 442 /** @} */ /* end of endian_id group */ 443 /** @} */ /* end of gen_id group */ 444 445 446 #endif /* __ENDIAN_EXT_H */ 447 448