2 * @brief LPCUSB library's common macros, definitions
\r
5 * Copyright(C) NXP Semiconductors, 2012
\r
6 * Copyright(C) Dean Camera, 2011, 2012
\r
7 * All rights reserved.
\r
10 * Software that is described herein is for illustrative purposes only
\r
11 * which provides customers with programming information regarding the
\r
12 * LPC products. This software is supplied "AS IS" without any warranties of
\r
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
\r
14 * all warranties, express or implied, including all implied warranties of
\r
15 * merchantability, fitness for a particular purpose and non-infringement of
\r
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
\r
17 * or liability for the use of the software, conveys no license or rights under any
\r
18 * patent, copyright, mask work right, or any other intellectual property rights in
\r
19 * or to any products. NXP Semiconductors reserves the right to make changes
\r
20 * in the software without notification. NXP Semiconductors also makes no
\r
21 * representation or warranty that such application will be suitable for the
\r
22 * specified use without further testing or modification.
\r
25 * Permission to use, copy, modify, and distribute this software and its
\r
26 * documentation is hereby granted, under NXP Semiconductors' and its
\r
27 * licensor's relevant copyrights in the software, without fee, provided that it
\r
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
\r
29 * copyright, permission, and disclaimer notice must appear in all copies of
\r
34 /** @defgroup Group_Common Common Utility Headers - LPCUSBlib/Common/Common.h
\r
35 * @ingroup LPCUSBlib
\r
36 * @brief Common library convenience headers, macros and functions.
\r
38 * Common utility headers containing macros, functions, enums and types which are common to all
\r
39 * aspects of the library.
\r
44 /** @defgroup Group_GlobalInt Global Interrupt Macros
\r
45 * @brief Convenience macros for the management of interrupts globally within the device.
\r
47 * Macros and functions to create and control global interrupts within the device.
\r
50 #ifndef __LPCUSBlib_COMMON_H__
\r
51 #define __LPCUSBlib_COMMON_H__
\r
54 #define __INCLUDE_FROM_COMMON_H
\r
58 #include <stdbool.h>
\r
62 #if defined(USE_LUFA_CONFIG_HEADER)
\r
63 #include "LUFAConfig.h"
\r
66 #if 1 // TODO add control macros later
\r
67 #include "../LPCUSBlibConfig.h"
\r
70 #include "CompilerSpecific.h"
\r
71 #include "Attributes.h"
\r
73 /* Enable C linkage for C++ Compilers: */
\r
74 #if defined(__cplusplus)
\r
78 /* Architecture specific utility includes: */
\r
79 #if defined(__DOXYGEN__)
\r
80 /** Type define for an unsigned integer the same width as the selected architecture's machine register.
\r
81 * This is distinct from the non-specific standard int data type, whose width is machine dependant but
\r
82 * which may not reflect the actual machine register width on some targets (e.g. LPC).
\r
84 typedef MACHINE_REG_t uint_reg_t;
\r
86 typedef uint32_t uint_reg_t;
\r
87 #define ARCH_LITTLE_ENDIAN
\r
88 #define PROGMEM const
\r
89 #define pgm_read_byte(x) (*x)
\r
90 #define memcmp_P(...) memcmp(__VA_ARGS__)
\r
91 #define memcpy_P(...) memcpy(__VA_ARGS__)
\r
92 #include "Endianness.h"
\r
95 /* Public Interface - May be used in end-application: */
\r
97 /** Macro for encasing other multi-statement macros. This should be used along with an opening brace
\r
98 * before the start of any multi-statement macro, so that the macros contents as a whole are treated
\r
99 * as a discrete block and not as a list of separate statements which may cause problems when used as
\r
100 * a block (such as inline \c if statements).
\r
104 /** Macro for encasing other multi-statement macros. This should be used along with a preceding closing
\r
105 * brace at the end of any multi-statement macro, so that the macros contents as a whole are treated
\r
106 * as a discrete block and not as a list of separate statements which may cause problems when used as
\r
107 * a block (such as inline \c if statements).
\r
109 #define MACROE while (0)
\r
111 /** Convenience macro to determine the larger of two values.
\r
113 * @note This macro should only be used with operands that do not have side effects from being evaluated
\r
116 * @param x First value to compare
\r
117 * @param y First value to compare
\r
119 * @return The larger of the two input parameters
\r
121 #if !defined(MAX) || defined(__DOXYGEN__)
\r
122 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
\r
125 /** Convenience macro to determine the smaller of two values.
\r
127 * @note This macro should only be used with operands that do not have side effects from being evaluated
\r
130 * @param x First value to compare
\r
131 * @param y First value to compare
\r
133 * @return The smaller of the two input parameters
\r
135 #if !defined(MIN) || defined(__DOXYGEN__)
\r
136 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
\r
139 #if !defined(STRINGIFY) || defined(__DOXYGEN__)
\r
140 /** Converts the given input into a string, via the C Preprocessor. This macro puts literal quotation
\r
141 * marks around the input, converting the source into a string literal.
\r
143 * @param x Input to convert into a string literal.
\r
145 * @return String version of the input.
\r
147 #define STRINGIFY(x) #x
\r
149 /** Converts the given input into a string after macro expansion, via the C Preprocessor. This macro puts
\r
150 * literal quotation marks around the expanded input, converting the source into a string literal.
\r
152 * @param x Input to expand and convert into a string literal.
\r
154 * @return String version of the expanded input.
\r
156 #define STRINGIFY_EXPANDED(x) STRINGIFY(x)
\r
159 /* Inline Functions: */
\r
160 /** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1,
\r
163 * @param Byte Byte of data whose bits are to be reversed.
\r
165 static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
\r
166 static inline uint8_t BitReverse(uint8_t Byte)
\r
168 Byte = (((Byte & 0xF0) >> 4) | ((Byte & 0x0F) << 4));
\r
169 Byte = (((Byte & 0xCC) >> 2) | ((Byte & 0x33) << 2));
\r
170 Byte = (((Byte & 0xAA) >> 1) | ((Byte & 0x55) << 1));
\r
175 /** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be
\r
176 * at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations
\r
177 * may be slightly higher.
\r
179 * @param Milliseconds Number of milliseconds to delay
\r
181 PRAGMA_ALWAYS_INLINE
\r
182 static inline void Delay_MS(uint16_t Milliseconds) ATTR_ALWAYS_INLINE;
\r
183 static inline void Delay_MS(uint16_t Milliseconds)
\r
185 while (Milliseconds--)
\r
187 volatile uint32_t i;
\r
189 for (i = 0; i < (4 * 1000); i++) { /* This logic was tested. It gives app. 1 micro sec delay */
\r
195 /** Retrieves a mask which contains the current state of the global interrupts for the device. This
\r
196 * value can be stored before altering the global interrupt enable state, before restoring the
\r
197 * flag(s) back to their previous values after a critical section using @ref SetGlobalInterruptMask().
\r
199 * @ingroup Group_GlobalInt
\r
201 * @return Mask containing the current Global Interrupt Enable Mask bit(s).
\r
203 PRAGMA_ALWAYS_INLINE
\r
204 static inline uint_reg_t GetGlobalInterruptMask(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
\r
205 static inline uint_reg_t GetGlobalInterruptMask(void)
\r
207 GCC_MEMORY_BARRIER();
\r
208 // TODO #warning GetGlobalInterruptMask() is not implemented under ARCH_LPC.
\r
210 //GCC_MEMORY_BARRIER();
\r
213 /** Sets the global interrupt enable state of the microcontroller to the mask passed into the function.
\r
214 * This can be combined with @ref GetGlobalInterruptMask() to save and restore the Global Interrupt Enable
\r
215 * Mask bit(s) of the device after a critical section has completed.
\r
217 * @ingroup Group_GlobalInt
\r
219 * @param GlobalIntState Global Interrupt Enable Mask value to use
\r
221 PRAGMA_ALWAYS_INLINE
\r
222 static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE;
\r
223 static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState)
\r
225 GCC_MEMORY_BARRIER();
\r
226 // TODO #warning SetGlobalInterruptMask() is not implemented under ARCH_LPC.
\r
227 GCC_MEMORY_BARRIER();
\r
230 /** Enables global interrupt handling for the device, allowing interrupts to be handled.
\r
232 * @ingroup Group_GlobalInt
\r
234 PRAGMA_ALWAYS_INLINE
\r
235 static inline void GlobalInterruptEnable(void) ATTR_ALWAYS_INLINE;
\r
236 static inline void GlobalInterruptEnable(void)
\r
238 GCC_MEMORY_BARRIER();
\r
239 // TODO #warning GlobalInterruptEnable() is not implemented under ARCH_LPC.
\r
240 GCC_MEMORY_BARRIER();
\r
243 /** Disabled global interrupt handling for the device, preventing interrupts from being handled.
\r
245 * @ingroup Group_GlobalInt
\r
247 PRAGMA_ALWAYS_INLINE
\r
248 static inline void GlobalInterruptDisable(void) ATTR_ALWAYS_INLINE;
\r
249 static inline void GlobalInterruptDisable(void)
\r
251 GCC_MEMORY_BARRIER();
\r
252 // TODO #warning GlobalInterruptDisable() is not implemented under ARCH_LPC.
\r
253 GCC_MEMORY_BARRIER();
\r
256 /* Disable C linkage for C++ Compilers: */
\r
257 #if defined(__cplusplus)
\r