My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

compiler.h 35KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /**
  2. * \file
  3. *
  4. * \brief Commonly used includes, types and macros.
  5. *
  6. * Copyright (c) 2010-2016 Atmel Corporation. All rights reserved.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. *
  22. * 3. The name of Atmel may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * 4. This software may only be redistributed and used in connection with an
  26. * Atmel microcontroller product.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  31. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  32. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * \asf_license_stop
  41. *
  42. */
  43. /*
  44. * Support and FAQ: visit <a href="https://www.atmel.com/design-support/">Atmel Support</a>
  45. */
  46. #ifndef UTILS_COMPILER_H
  47. #define UTILS_COMPILER_H
  48. #include <sam.h>
  49. #include <chip.h>
  50. #include "arduino_due_x.h"
  51. #include "conf_clock.h"
  52. #ifdef SAM3XA_SERIES
  53. #define SAM3XA 1
  54. #endif
  55. #define UDD_NO_SLEEP_MGR 1
  56. #define pmc_is_wakeup_clocks_restored() true
  57. #undef udd_get_endpoint_size_max
  58. #define UDD_USB_INT_FUN USBD_ISR
  59. /**
  60. * \defgroup group_sam_utils Compiler abstraction layer and code utilities
  61. *
  62. * Compiler abstraction layer and code utilities for AT91SAM.
  63. * This module provides various abstraction layers and utilities to make code compatible between different compilers.
  64. *
  65. * \{
  66. */
  67. #include <stddef.h>
  68. #if (defined __ICCARM__)
  69. # include <intrinsics.h>
  70. #endif
  71. #include <sam.h>
  72. #include "preprocessor.h"
  73. //_____ D E C L A R A T I O N S ____________________________________________
  74. #ifndef __ASSEMBLY__ // Not defined for assembling.
  75. #include <stdio.h>
  76. #include <stdbool.h>
  77. #include <stdint.h>
  78. #include <stdlib.h>
  79. #ifdef __ICCARM__
  80. /*! \name Compiler Keywords
  81. *
  82. * Port of some keywords from GCC to IAR Embedded Workbench.
  83. */
  84. //! @{
  85. #define __asm__ asm
  86. #define __inline__ inline
  87. #define __volatile__
  88. //! @}
  89. #endif
  90. #define FUNC_PTR void *
  91. /**
  92. * \def UNUSED
  93. * \brief Marking \a v as a unused parameter or value.
  94. */
  95. #ifndef UNUSED
  96. #define UNUSED(x) ((void)(x))
  97. #endif
  98. /**
  99. * \def unused
  100. * \brief Marking \a v as a unused parameter or value.
  101. */
  102. #define unused(v) do { (void)(v); }while(0)
  103. /**
  104. * \def barrier
  105. * \brief Memory barrier
  106. */
  107. #define barrier() __DMB()
  108. /**
  109. * \brief Emit the compiler pragma \a arg.
  110. *
  111. * \param arg The pragma directive as it would appear after \e \#pragma
  112. * (i.e. not stringified).
  113. */
  114. #define COMPILER_PRAGMA(arg) _Pragma(#arg)
  115. /**
  116. * \def COMPILER_PACK_SET(alignment)
  117. * \brief Set maximum alignment for subsequent struct and union
  118. * definitions to \a alignment.
  119. */
  120. #define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment))
  121. /**
  122. * \def COMPILER_PACK_RESET()
  123. * \brief Set default alignment for subsequent struct and union
  124. * definitions.
  125. */
  126. #define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack())
  127. /**
  128. * \brief Set aligned boundary.
  129. */
  130. #if (defined __GNUC__) || (defined __CC_ARM)
  131. # define COMPILER_ALIGNED(a) __attribute__((__aligned__(a)))
  132. #elif (defined __ICCARM__)
  133. # define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a)
  134. #endif
  135. /**
  136. * \brief Set word-aligned boundary.
  137. */
  138. #if (defined __GNUC__) || defined(__CC_ARM)
  139. #define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4)))
  140. #elif (defined __ICCARM__)
  141. #define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4)
  142. #endif
  143. /**
  144. * \def __always_inline
  145. * \brief The function should always be inlined.
  146. *
  147. * This annotation instructs the compiler to ignore its inlining
  148. * heuristics and inline the function no matter how big it thinks it
  149. * becomes.
  150. */
  151. #ifdef __CC_ARM
  152. # define __always_inline __forceinline
  153. #elif (defined __GNUC__)
  154. #ifdef __always_inline
  155. # undef __always_inline
  156. #endif
  157. # define __always_inline inline __attribute__((__always_inline__))
  158. #elif (defined __ICCARM__)
  159. # define __always_inline _Pragma("inline=forced")
  160. #endif
  161. /**
  162. * \def __no_inline
  163. * \brief The function should not be inlined.
  164. *
  165. * This annotation instructs the compiler to ignore its inlining
  166. * heuristics and not inline the function.
  167. */
  168. #ifdef __CC_ARM
  169. # define __no_inline __attribute__((noinline))
  170. #elif (defined __GNUC__)
  171. # define __no_inline __attribute__((__noinline__))
  172. #elif (defined __ICCARM__)
  173. # define __no_inline _Pragma("inline=never")
  174. #endif
  175. /*! \brief This macro is used to test fatal errors.
  176. *
  177. * The macro tests if the expression is false. If it is, a fatal error is
  178. * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO
  179. * is defined, a unit test version of the macro is used, to allow execution
  180. * of further tests after a false expression.
  181. *
  182. * \param expr Expression to evaluate and supposed to be nonzero.
  183. */
  184. #ifdef _ASSERT_ENABLE_
  185. # if defined(TEST_SUITE_DEFINE_ASSERT_MACRO)
  186. // Assert() is defined in unit_test/suite.h
  187. # include "unit_test/suite.h"
  188. # else
  189. #undef TEST_SUITE_DEFINE_ASSERT_MACRO
  190. # define Assert(expr) \
  191. {\
  192. if (!(expr)) while (true);\
  193. }
  194. # endif
  195. #else
  196. # define Assert(expr) ((void) 0)
  197. #endif
  198. /* Define WEAK attribute */
  199. #if defined ( __CC_ARM ) /* Keil µVision 4 */
  200. # define WEAK __attribute__ ((weak))
  201. #elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
  202. # define WEAK __weak
  203. #elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */
  204. # define WEAK __attribute__ ((weak))
  205. #endif
  206. /* Define NO_INIT attribute */
  207. #if 0 //ndef NO_INIT
  208. #ifdef __CC_ARM
  209. # define NO_INIT __attribute__((zero_init))
  210. #elif defined ( __ICCARM__ )
  211. # define NO_INIT __no_init
  212. #elif defined ( __GNUC__ )
  213. # define NO_INIT __attribute__((section(".no_init")))
  214. #endif
  215. #endif
  216. /* Define RAMFUNC attribute */
  217. #if defined ( __CC_ARM ) /* Keil µVision 4 */
  218. # define RAMFUNC __attribute__ ((section(".ramfunc")))
  219. #elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
  220. # define RAMFUNC __ramfunc
  221. #elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */
  222. # define RAMFUNC __attribute__ ((section(".ramfunc")))
  223. #endif
  224. /* Define OPTIMIZE_HIGH attribute */
  225. #if defined ( __CC_ARM ) /* Keil µVision 4 */
  226. # define OPTIMIZE_HIGH _Pragma("O3")
  227. #elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
  228. # define OPTIMIZE_HIGH _Pragma("optimize=high")
  229. #elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */
  230. # define OPTIMIZE_HIGH __attribute__((optimize("s")))
  231. #endif
  232. /*! \name Usual Types
  233. */
  234. //! @{
  235. typedef unsigned char Bool; //!< Boolean.
  236. #ifndef __cplusplus
  237. #ifndef __bool_true_false_are_defined
  238. typedef unsigned char bool; //!< Boolean.
  239. #endif
  240. #endif
  241. typedef int8_t S8 ; //!< 8-bit signed integer.
  242. typedef uint8_t U8 ; //!< 8-bit unsigned integer.
  243. typedef int16_t S16; //!< 16-bit signed integer.
  244. typedef uint16_t U16; //!< 16-bit unsigned integer.
  245. typedef uint16_t le16_t;
  246. typedef uint16_t be16_t;
  247. typedef int32_t S32; //!< 32-bit signed integer.
  248. typedef uint32_t U32; //!< 32-bit unsigned integer.
  249. typedef uint32_t le32_t;
  250. typedef uint32_t be32_t;
  251. typedef int64_t S64; //!< 64-bit signed integer.
  252. typedef uint64_t U64; //!< 64-bit unsigned integer.
  253. typedef float F32; //!< 32-bit floating-point number.
  254. typedef double F64; //!< 64-bit floating-point number.
  255. typedef uint32_t iram_size_t;
  256. //! @}
  257. /*! \name Status Types
  258. */
  259. //! @{
  260. typedef bool Status_bool_t; //!< Boolean status.
  261. typedef U8 Status_t; //!< 8-bit-coded status.
  262. //! @}
  263. /*! \name Aliasing Aggregate Types
  264. */
  265. //! @{
  266. //! 16-bit union.
  267. typedef union
  268. {
  269. S16 s16 ;
  270. U16 u16 ;
  271. S8 s8 [2];
  272. U8 u8 [2];
  273. } Union16;
  274. //! 32-bit union.
  275. typedef union
  276. {
  277. S32 s32 ;
  278. U32 u32 ;
  279. S16 s16[2];
  280. U16 u16[2];
  281. S8 s8 [4];
  282. U8 u8 [4];
  283. } Union32;
  284. //! 64-bit union.
  285. typedef union
  286. {
  287. S64 s64 ;
  288. U64 u64 ;
  289. S32 s32[2];
  290. U32 u32[2];
  291. S16 s16[4];
  292. U16 u16[4];
  293. S8 s8 [8];
  294. U8 u8 [8];
  295. } Union64;
  296. //! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers.
  297. typedef union
  298. {
  299. S64 *s64ptr;
  300. U64 *u64ptr;
  301. S32 *s32ptr;
  302. U32 *u32ptr;
  303. S16 *s16ptr;
  304. U16 *u16ptr;
  305. S8 *s8ptr ;
  306. U8 *u8ptr ;
  307. } UnionPtr;
  308. //! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers.
  309. typedef union
  310. {
  311. volatile S64 *s64ptr;
  312. volatile U64 *u64ptr;
  313. volatile S32 *s32ptr;
  314. volatile U32 *u32ptr;
  315. volatile S16 *s16ptr;
  316. volatile U16 *u16ptr;
  317. volatile S8 *s8ptr ;
  318. volatile U8 *u8ptr ;
  319. } UnionVPtr;
  320. //! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers.
  321. typedef union
  322. {
  323. const S64 *s64ptr;
  324. const U64 *u64ptr;
  325. const S32 *s32ptr;
  326. const U32 *u32ptr;
  327. const S16 *s16ptr;
  328. const U16 *u16ptr;
  329. const S8 *s8ptr ;
  330. const U8 *u8ptr ;
  331. } UnionCPtr;
  332. //! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers.
  333. typedef union
  334. {
  335. const volatile S64 *s64ptr;
  336. const volatile U64 *u64ptr;
  337. const volatile S32 *s32ptr;
  338. const volatile U32 *u32ptr;
  339. const volatile S16 *s16ptr;
  340. const volatile U16 *u16ptr;
  341. const volatile S8 *s8ptr ;
  342. const volatile U8 *u8ptr ;
  343. } UnionCVPtr;
  344. //! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers.
  345. typedef struct
  346. {
  347. S64 *s64ptr;
  348. U64 *u64ptr;
  349. S32 *s32ptr;
  350. U32 *u32ptr;
  351. S16 *s16ptr;
  352. U16 *u16ptr;
  353. S8 *s8ptr ;
  354. U8 *u8ptr ;
  355. } StructPtr;
  356. //! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers.
  357. typedef struct
  358. {
  359. volatile S64 *s64ptr;
  360. volatile U64 *u64ptr;
  361. volatile S32 *s32ptr;
  362. volatile U32 *u32ptr;
  363. volatile S16 *s16ptr;
  364. volatile U16 *u16ptr;
  365. volatile S8 *s8ptr ;
  366. volatile U8 *u8ptr ;
  367. } StructVPtr;
  368. //! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers.
  369. typedef struct
  370. {
  371. const S64 *s64ptr;
  372. const U64 *u64ptr;
  373. const S32 *s32ptr;
  374. const U32 *u32ptr;
  375. const S16 *s16ptr;
  376. const U16 *u16ptr;
  377. const S8 *s8ptr ;
  378. const U8 *u8ptr ;
  379. } StructCPtr;
  380. //! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers.
  381. typedef struct
  382. {
  383. const volatile S64 *s64ptr;
  384. const volatile U64 *u64ptr;
  385. const volatile S32 *s32ptr;
  386. const volatile U32 *u32ptr;
  387. const volatile S16 *s16ptr;
  388. const volatile U16 *u16ptr;
  389. const volatile S8 *s8ptr ;
  390. const volatile U8 *u8ptr ;
  391. } StructCVPtr;
  392. //! @}
  393. #endif // #ifndef __ASSEMBLY__
  394. /*! \name Usual Constants
  395. */
  396. //! @{
  397. #define DISABLE 0
  398. #define ENABLE 1
  399. #ifndef __cplusplus
  400. #ifndef __bool_true_false_are_defined
  401. #define false (1==0)
  402. #define true (1==1)
  403. #endif
  404. #endif
  405. #ifndef PASS
  406. #define PASS 0
  407. #endif
  408. #ifndef FAIL
  409. #define FAIL 1
  410. #endif
  411. #ifndef LOW
  412. #define LOW 0x0
  413. #endif
  414. #ifndef HIGH
  415. #define HIGH 0x1
  416. #endif
  417. //! @}
  418. #ifndef __ASSEMBLY__ // not for assembling.
  419. //! \name Optimization Control
  420. //@{
  421. /**
  422. * \def likely(exp)
  423. * \brief The expression \a exp is likely to be true
  424. */
  425. #ifndef likely
  426. # define likely(exp) (exp)
  427. #endif
  428. /**
  429. * \def unlikely(exp)
  430. * \brief The expression \a exp is unlikely to be true
  431. */
  432. #ifndef unlikely
  433. # define unlikely(exp) (exp)
  434. #endif
  435. /**
  436. * \def is_constant(exp)
  437. * \brief Determine if an expression evaluates to a constant value.
  438. *
  439. * \param exp Any expression
  440. *
  441. * \return true if \a exp is constant, false otherwise.
  442. */
  443. #if (defined __GNUC__) || (defined __CC_ARM)
  444. # define is_constant(exp) __builtin_constant_p(exp)
  445. #else
  446. # define is_constant(exp) (0)
  447. #endif
  448. //! @}
  449. /*! \name Bit-Field Handling
  450. */
  451. //! @{
  452. /*! \brief Reads the bits of a value specified by a given bit-mask.
  453. *
  454. * \param value Value to read bits from.
  455. * \param mask Bit-mask indicating bits to read.
  456. *
  457. * \return Read bits.
  458. */
  459. #define Rd_bits( value, mask) ((value) & (mask))
  460. /*! \brief Writes the bits of a C lvalue specified by a given bit-mask.
  461. *
  462. * \param lvalue C lvalue to write bits to.
  463. * \param mask Bit-mask indicating bits to write.
  464. * \param bits Bits to write.
  465. *
  466. * \return Resulting value with written bits.
  467. */
  468. #define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\
  469. ((bits ) & (mask)))
  470. /*! \brief Tests the bits of a value specified by a given bit-mask.
  471. *
  472. * \param value Value of which to test bits.
  473. * \param mask Bit-mask indicating bits to test.
  474. *
  475. * \return \c 1 if at least one of the tested bits is set, else \c 0.
  476. */
  477. #define Tst_bits( value, mask) (Rd_bits(value, mask) != 0)
  478. /*! \brief Clears the bits of a C lvalue specified by a given bit-mask.
  479. *
  480. * \param lvalue C lvalue of which to clear bits.
  481. * \param mask Bit-mask indicating bits to clear.
  482. *
  483. * \return Resulting value with cleared bits.
  484. */
  485. #define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask))
  486. /*! \brief Sets the bits of a C lvalue specified by a given bit-mask.
  487. *
  488. * \param lvalue C lvalue of which to set bits.
  489. * \param mask Bit-mask indicating bits to set.
  490. *
  491. * \return Resulting value with set bits.
  492. */
  493. #define Set_bits(lvalue, mask) ((lvalue) |= (mask))
  494. /*! \brief Toggles the bits of a C lvalue specified by a given bit-mask.
  495. *
  496. * \param lvalue C lvalue of which to toggle bits.
  497. * \param mask Bit-mask indicating bits to toggle.
  498. *
  499. * \return Resulting value with toggled bits.
  500. */
  501. #define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask))
  502. /*! \brief Reads the bit-field of a value specified by a given bit-mask.
  503. *
  504. * \param value Value to read a bit-field from.
  505. * \param mask Bit-mask indicating the bit-field to read.
  506. *
  507. * \return Read bit-field.
  508. */
  509. #define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask))
  510. /*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask.
  511. *
  512. * \param lvalue C lvalue to write a bit-field to.
  513. * \param mask Bit-mask indicating the bit-field to write.
  514. * \param bitfield Bit-field to write.
  515. *
  516. * \return Resulting value with written bit-field.
  517. */
  518. #define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask)))
  519. //! @}
  520. /*! \name Zero-Bit Counting
  521. *
  522. * Under GCC, __builtin_clz and __builtin_ctz behave like macros when
  523. * applied to constant expressions (values known at compile time), so they are
  524. * more optimized than the use of the corresponding assembly instructions and
  525. * they can be used as constant expressions e.g. to initialize objects having
  526. * static storage duration, and like the corresponding assembly instructions
  527. * when applied to non-constant expressions (values unknown at compile time), so
  528. * they are more optimized than an assembly periphrasis. Hence, clz and ctz
  529. * ensure a possible and optimized behavior for both constant and non-constant
  530. * expressions.
  531. */
  532. //! @{
  533. /*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer.
  534. *
  535. * \param u Value of which to count the leading zero bits.
  536. *
  537. * \return The count of leading zero bits in \a u.
  538. */
  539. #ifndef clz
  540. #if (defined __GNUC__) || (defined __CC_ARM)
  541. # define clz(u) ((u) ? __builtin_clz(u) : 32)
  542. #elif (defined __ICCARM__)
  543. # define clz(u) ((u) ? __CLZ(u) : 32)
  544. #else
  545. # define clz(u) (((u) == 0) ? 32 : \
  546. ((u) & (1UL << 31)) ? 0 : \
  547. ((u) & (1UL << 30)) ? 1 : \
  548. ((u) & (1UL << 29)) ? 2 : \
  549. ((u) & (1UL << 28)) ? 3 : \
  550. ((u) & (1UL << 27)) ? 4 : \
  551. ((u) & (1UL << 26)) ? 5 : \
  552. ((u) & (1UL << 25)) ? 6 : \
  553. ((u) & (1UL << 24)) ? 7 : \
  554. ((u) & (1UL << 23)) ? 8 : \
  555. ((u) & (1UL << 22)) ? 9 : \
  556. ((u) & (1UL << 21)) ? 10 : \
  557. ((u) & (1UL << 20)) ? 11 : \
  558. ((u) & (1UL << 19)) ? 12 : \
  559. ((u) & (1UL << 18)) ? 13 : \
  560. ((u) & (1UL << 17)) ? 14 : \
  561. ((u) & (1UL << 16)) ? 15 : \
  562. ((u) & (1UL << 15)) ? 16 : \
  563. ((u) & (1UL << 14)) ? 17 : \
  564. ((u) & (1UL << 13)) ? 18 : \
  565. ((u) & (1UL << 12)) ? 19 : \
  566. ((u) & (1UL << 11)) ? 20 : \
  567. ((u) & (1UL << 10)) ? 21 : \
  568. ((u) & (1UL << 9)) ? 22 : \
  569. ((u) & (1UL << 8)) ? 23 : \
  570. ((u) & (1UL << 7)) ? 24 : \
  571. ((u) & (1UL << 6)) ? 25 : \
  572. ((u) & (1UL << 5)) ? 26 : \
  573. ((u) & (1UL << 4)) ? 27 : \
  574. ((u) & (1UL << 3)) ? 28 : \
  575. ((u) & (1UL << 2)) ? 29 : \
  576. ((u) & (1UL << 1)) ? 30 : \
  577. 31)
  578. #endif
  579. #endif
  580. /*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer.
  581. *
  582. * \param u Value of which to count the trailing zero bits.
  583. *
  584. * \return The count of trailing zero bits in \a u.
  585. */
  586. #ifndef ctz
  587. #if (defined __GNUC__) || (defined __CC_ARM)
  588. # define ctz(u) ((u) ? __builtin_ctz(u) : 32)
  589. #else
  590. # define ctz(u) ((u) & (1UL << 0) ? 0 : \
  591. (u) & (1UL << 1) ? 1 : \
  592. (u) & (1UL << 2) ? 2 : \
  593. (u) & (1UL << 3) ? 3 : \
  594. (u) & (1UL << 4) ? 4 : \
  595. (u) & (1UL << 5) ? 5 : \
  596. (u) & (1UL << 6) ? 6 : \
  597. (u) & (1UL << 7) ? 7 : \
  598. (u) & (1UL << 8) ? 8 : \
  599. (u) & (1UL << 9) ? 9 : \
  600. (u) & (1UL << 10) ? 10 : \
  601. (u) & (1UL << 11) ? 11 : \
  602. (u) & (1UL << 12) ? 12 : \
  603. (u) & (1UL << 13) ? 13 : \
  604. (u) & (1UL << 14) ? 14 : \
  605. (u) & (1UL << 15) ? 15 : \
  606. (u) & (1UL << 16) ? 16 : \
  607. (u) & (1UL << 17) ? 17 : \
  608. (u) & (1UL << 18) ? 18 : \
  609. (u) & (1UL << 19) ? 19 : \
  610. (u) & (1UL << 20) ? 20 : \
  611. (u) & (1UL << 21) ? 21 : \
  612. (u) & (1UL << 22) ? 22 : \
  613. (u) & (1UL << 23) ? 23 : \
  614. (u) & (1UL << 24) ? 24 : \
  615. (u) & (1UL << 25) ? 25 : \
  616. (u) & (1UL << 26) ? 26 : \
  617. (u) & (1UL << 27) ? 27 : \
  618. (u) & (1UL << 28) ? 28 : \
  619. (u) & (1UL << 29) ? 29 : \
  620. (u) & (1UL << 30) ? 30 : \
  621. (u) & (1UL << 31) ? 31 : \
  622. 32)
  623. #endif
  624. #endif
  625. //! @}
  626. /*! \name Bit Reversing
  627. */
  628. //! @{
  629. /*! \brief Reverses the bits of \a u8.
  630. *
  631. * \param u8 U8 of which to reverse the bits.
  632. *
  633. * \return Value resulting from \a u8 with reversed bits.
  634. */
  635. #define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24))
  636. /*! \brief Reverses the bits of \a u16.
  637. *
  638. * \param u16 U16 of which to reverse the bits.
  639. *
  640. * \return Value resulting from \a u16 with reversed bits.
  641. */
  642. #define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16))
  643. /*! \brief Reverses the bits of \a u32.
  644. *
  645. * \param u32 U32 of which to reverse the bits.
  646. *
  647. * \return Value resulting from \a u32 with reversed bits.
  648. */
  649. #define bit_reverse32(u32) __RBIT(u32)
  650. /*! \brief Reverses the bits of \a u64.
  651. *
  652. * \param u64 U64 of which to reverse the bits.
  653. *
  654. * \return Value resulting from \a u64 with reversed bits.
  655. */
  656. #define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\
  657. ((U64)bit_reverse32((U64)(u64)) << 32)))
  658. //! @}
  659. /*! \name Alignment
  660. */
  661. //! @{
  662. /*! \brief Tests alignment of the number \a val with the \a n boundary.
  663. *
  664. * \param val Input value.
  665. * \param n Boundary.
  666. *
  667. * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0.
  668. */
  669. #define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) )
  670. /*! \brief Gets alignment of the number \a val with respect to the \a n boundary.
  671. *
  672. * \param val Input value.
  673. * \param n Boundary.
  674. *
  675. * \return Alignment of the number \a val with respect to the \a n boundary.
  676. */
  677. #define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) )
  678. /*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary.
  679. *
  680. * \param lval Input/output lvalue.
  681. * \param n Boundary.
  682. * \param alg Alignment.
  683. *
  684. * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary.
  685. */
  686. #define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) )
  687. /*! \brief Aligns the number \a val with the upper \a n boundary.
  688. *
  689. * \param val Input value.
  690. * \param n Boundary.
  691. *
  692. * \return Value resulting from the number \a val aligned with the upper \a n boundary.
  693. */
  694. #define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1))
  695. /*! \brief Aligns the number \a val with the lower \a n boundary.
  696. *
  697. * \param val Input value.
  698. * \param n Boundary.
  699. *
  700. * \return Value resulting from the number \a val aligned with the lower \a n boundary.
  701. */
  702. #define Align_down(val, n ) ( (val) & ~((n) - 1))
  703. //! @}
  704. /*! \brief Calls the routine at address \a addr.
  705. *
  706. * It generates a long call opcode.
  707. *
  708. * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if
  709. * it is invoked from the CPU supervisor mode.
  710. *
  711. * \param addr Address of the routine to call.
  712. *
  713. * \note It may be used as a long jump opcode in some special cases.
  714. */
  715. #define Long_call(addr) ((*(void (*)(void))(addr))())
  716. /*! \name MCU Endianism Handling
  717. * ARM is MCU little endianism.
  718. */
  719. //! @{
  720. #define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16.
  721. #define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16.
  722. #define MSH(u32) (((U16 *)&(u32))[1]) //!< Most significant half-word of \a u32.
  723. #define LSH(u32) (((U16 *)&(u32))[0]) //!< Least significant half-word of \a u32.
  724. #define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32.
  725. #define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32.
  726. #define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32.
  727. #define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32.
  728. #define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32.
  729. #define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32.
  730. #define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32.
  731. #define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32.
  732. #define MSW(u64) (((U32 *)&(u64))[1]) //!< Most significant word of \a u64.
  733. #define LSW(u64) (((U32 *)&(u64))[0]) //!< Least significant word of \a u64.
  734. #define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64.
  735. #define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64.
  736. #define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64.
  737. #define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64.
  738. #define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64.
  739. #define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64.
  740. #define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64.
  741. #define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64.
  742. #define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64.
  743. #define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64.
  744. #define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64.
  745. #define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64.
  746. #define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64.
  747. #define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64.
  748. #define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64.
  749. #define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64.
  750. #define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64.
  751. #define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64.
  752. #define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64.
  753. #define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64.
  754. #define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64.
  755. #define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64.
  756. #define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64.
  757. #define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64.
  758. #define BE16(x) swap16(x)
  759. #define LE16(x) (x)
  760. #define le16_to_cpu(x) (x)
  761. #define cpu_to_le16(x) (x)
  762. #define LE16_TO_CPU(x) (x)
  763. #define CPU_TO_LE16(x) (x)
  764. #define be16_to_cpu(x) swap16(x)
  765. #define cpu_to_be16(x) swap16(x)
  766. #define BE16_TO_CPU(x) swap16(x)
  767. #define CPU_TO_BE16(x) swap16(x)
  768. #define le32_to_cpu(x) (x)
  769. #define cpu_to_le32(x) (x)
  770. #define LE32_TO_CPU(x) (x)
  771. #define CPU_TO_LE32(x) (x)
  772. #define be32_to_cpu(x) swap32(x)
  773. #define cpu_to_be32(x) swap32(x)
  774. #define BE32_TO_CPU(x) swap32(x)
  775. #define CPU_TO_BE32(x) swap32(x)
  776. //! @}
  777. /*! \name Endianism Conversion
  778. *
  779. * The same considerations as for clz and ctz apply here but GCC's
  780. * __builtin_bswap_32 and __builtin_bswap_64 do not behave like macros when
  781. * applied to constant expressions, so two sets of macros are defined here:
  782. * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known
  783. * at compile time);
  784. * - swap16, swap32 and swap64 to apply to non-constant expressions (values
  785. * unknown at compile time).
  786. */
  787. //! @{
  788. /*! \brief Toggles the endianism of \a u16 (by swapping its bytes).
  789. *
  790. * \param u16 U16 of which to toggle the endianism.
  791. *
  792. * \return Value resulting from \a u16 with toggled endianism.
  793. *
  794. * \note More optimized if only used with values known at compile time.
  795. */
  796. #define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\
  797. ((U16)(u16) << 8)))
  798. /*! \brief Toggles the endianism of \a u32 (by swapping its bytes).
  799. *
  800. * \param u32 U32 of which to toggle the endianism.
  801. *
  802. * \return Value resulting from \a u32 with toggled endianism.
  803. *
  804. * \note More optimized if only used with values known at compile time.
  805. */
  806. #define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\
  807. ((U32)Swap16((U32)(u32)) << 16)))
  808. /*! \brief Toggles the endianism of \a u64 (by swapping its bytes).
  809. *
  810. * \param u64 U64 of which to toggle the endianism.
  811. *
  812. * \return Value resulting from \a u64 with toggled endianism.
  813. *
  814. * \note More optimized if only used with values known at compile time.
  815. */
  816. #define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\
  817. ((U64)Swap32((U64)(u64)) << 32)))
  818. /*! \brief Toggles the endianism of \a u16 (by swapping its bytes).
  819. *
  820. * \param u16 U16 of which to toggle the endianism.
  821. *
  822. * \return Value resulting from \a u16 with toggled endianism.
  823. *
  824. * \note More optimized if only used with values unknown at compile time.
  825. */
  826. #define swap16(u16) Swap16(u16)
  827. /*! \brief Toggles the endianism of \a u32 (by swapping its bytes).
  828. *
  829. * \param u32 U32 of which to toggle the endianism.
  830. *
  831. * \return Value resulting from \a u32 with toggled endianism.
  832. *
  833. * \note More optimized if only used with values unknown at compile time.
  834. */
  835. #if (defined __GNUC__)
  836. # define swap32(u32) ((U32)__builtin_bswap32((U32)(u32)))
  837. #else
  838. # define swap32(u32) Swap32(u32)
  839. #endif
  840. /*! \brief Toggles the endianism of \a u64 (by swapping its bytes).
  841. *
  842. * \param u64 U64 of which to toggle the endianism.
  843. *
  844. * \return Value resulting from \a u64 with toggled endianism.
  845. *
  846. * \note More optimized if only used with values unknown at compile time.
  847. */
  848. #if (defined __GNUC__)
  849. # define swap64(u64) ((U64)__builtin_bswap64((U64)(u64)))
  850. #else
  851. # define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\
  852. ((U64)swap32((U64)(u64)) << 32)))
  853. #endif
  854. //! @}
  855. /*! \name Target Abstraction
  856. */
  857. //! @{
  858. #define _GLOBEXT_ extern //!< extern storage-class specifier.
  859. #define _CONST_TYPE_ const //!< const type qualifier.
  860. #define _MEM_TYPE_SLOW_ //!< Slow memory type.
  861. #define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type.
  862. #define _MEM_TYPE_FAST_ //!< Fast memory type.
  863. typedef U8 Byte; //!< 8-bit unsigned integer.
  864. #define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM.
  865. #define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM.
  866. #define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM.
  867. #define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM.
  868. #define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32.
  869. #define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32.
  870. #define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32.
  871. #define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32.
  872. #define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32.
  873. #define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32.
  874. #define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32.
  875. #define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32.
  876. //! @}
  877. /**
  878. * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using
  879. * integer arithmetic.
  880. *
  881. * \param a An integer
  882. * \param b Another integer
  883. *
  884. * \return (\a a / \a b) rounded up to the nearest integer.
  885. */
  886. #define div_ceil(a, b) (((a) + (b) - 1) / (b))
  887. #endif // #ifndef __ASSEMBLY__
  888. #ifdef __ICCARM__
  889. #define SHORTENUM __packed
  890. #elif defined(__GNUC__)
  891. #define SHORTENUM __attribute__((packed))
  892. #endif
  893. /* No operation */
  894. #ifdef __ICCARM__
  895. #define nop() __no_operation()
  896. #elif defined(__GNUC__)
  897. #define nop() (__NOP())
  898. #endif
  899. #define FLASH_DECLARE(x) const x
  900. #define FLASH_EXTERN(x) extern const x
  901. #define PGM_READ_BYTE(x) *(x)
  902. #define PGM_READ_WORD(x) *(x)
  903. #define PGM_READ_DWORD(x) *(x)
  904. #define MEMCPY_ENDIAN memcpy
  905. #define PGM_READ_BLOCK(dst, src, len) memcpy((dst), (src), (len))
  906. /*Defines the Flash Storage for the request and response of MAC*/
  907. #define CMD_ID_OCTET (0)
  908. /* Converting of values from CPU endian to little endian. */
  909. #define CPU_ENDIAN_TO_LE16(x) (x)
  910. #define CPU_ENDIAN_TO_LE32(x) (x)
  911. #define CPU_ENDIAN_TO_LE64(x) (x)
  912. /* Converting of values from little endian to CPU endian. */
  913. #define LE16_TO_CPU_ENDIAN(x) (x)
  914. #define LE32_TO_CPU_ENDIAN(x) (x)
  915. #define LE64_TO_CPU_ENDIAN(x) (x)
  916. /* Converting of constants from little endian to CPU endian. */
  917. #define CLE16_TO_CPU_ENDIAN(x) (x)
  918. #define CLE32_TO_CPU_ENDIAN(x) (x)
  919. #define CLE64_TO_CPU_ENDIAN(x) (x)
  920. /* Converting of constants from CPU endian to little endian. */
  921. #define CCPU_ENDIAN_TO_LE16(x) (x)
  922. #define CCPU_ENDIAN_TO_LE32(x) (x)
  923. #define CCPU_ENDIAN_TO_LE64(x) (x)
  924. #define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src))
  925. #define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src))
  926. /**
  927. * @brief Converts a 64-Bit value into a 8 Byte array
  928. *
  929. * @param[in] value 64-Bit value
  930. * @param[out] data Pointer to the 8 Byte array to be updated with 64-Bit value
  931. * @ingroup apiPalApi
  932. */
  933. static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data)
  934. {
  935. uint8_t val_index = 0;
  936. while (val_index < 8)
  937. {
  938. data[val_index++] = value & 0xFF;
  939. value = value >> 8;
  940. }
  941. }
  942. /**
  943. * @brief Converts a 16-Bit value into a 2 Byte array
  944. *
  945. * @param[in] value 16-Bit value
  946. * @param[out] data Pointer to the 2 Byte array to be updated with 16-Bit value
  947. * @ingroup apiPalApi
  948. */
  949. static inline void convert_16_bit_to_byte_array(uint16_t value, uint8_t *data)
  950. {
  951. data[0] = value & 0xFF;
  952. data[1] = (value >> 8) & 0xFF;
  953. }
  954. /* Converts a 16-Bit value into a 2 Byte array */
  955. static inline void convert_spec_16_bit_to_byte_array(uint16_t value, uint8_t *data)
  956. {
  957. data[0] = value & 0xFF;
  958. data[1] = (value >> 8) & 0xFF;
  959. }
  960. /* Converts a 16-Bit value into a 2 Byte array */
  961. static inline void convert_16_bit_to_byte_address(uint16_t value, uint8_t *data)
  962. {
  963. data[0] = value & 0xFF;
  964. data[1] = (value >> 8) & 0xFF;
  965. }
  966. /*
  967. * @brief Converts a 2 Byte array into a 16-Bit value
  968. *
  969. * @param data Specifies the pointer to the 2 Byte array
  970. *
  971. * @return 16-Bit value
  972. * @ingroup apiPalApi
  973. */
  974. static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data)
  975. {
  976. return (data[0] | ((uint16_t)data[1] << 8));
  977. }
  978. /* Converts a 8 Byte array into a 32-Bit value */
  979. static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data)
  980. {
  981. union
  982. {
  983. uint32_t u32;
  984. uint8_t u8[8];
  985. }long_addr;
  986. uint8_t index;
  987. for (index = 0; index < 4; index++) {
  988. long_addr.u8[index] = *data++;
  989. }
  990. return long_addr.u32;
  991. }
  992. /**
  993. * @brief Converts a 8 Byte array into a 64-Bit value
  994. *
  995. * @param data Specifies the pointer to the 8 Byte array
  996. *
  997. * @return 64-Bit value
  998. * @ingroup apiPalApi
  999. */
  1000. static inline uint64_t convert_byte_array_to_64_bit(uint8_t *data)
  1001. {
  1002. union
  1003. {
  1004. uint64_t u64;
  1005. uint8_t u8[8];
  1006. } long_addr;
  1007. uint8_t val_index;
  1008. for (val_index = 0; val_index < 8; val_index++)
  1009. {
  1010. long_addr.u8[val_index] = *data++;
  1011. }
  1012. return long_addr.u64;
  1013. }
  1014. /**
  1015. * \}
  1016. */
  1017. #endif /* UTILS_COMPILER_H */