#endif
+/* Tests below are done in the compile time, don't actually get run. */
+/* Check whether a enumerator flag can be used in C++ */
+
+
+template<typename T> __attribute__((unused)) static void test_binary_operators()
+{
+ T flag1 = (T)0;
+ T flag2 = (T)0;
+ flag1 = ~flag1;
+ flag1 = flag1 | flag2;
+ flag1 = flag1 & flag2;
+ flag1 = flag1 ^ flag2;
+ flag1 = flag1 >> 2;
+ flag1 = flag1 << 2;
+ flag1 |= flag2;
+ flag1 &= flag2;
+ flag1 ^= flag2;
+ flag1 >>= 2;
+ flag1 <<= 2;
+}
+
+//Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h
+#include "hal/timer_types.h"
+template void test_binary_operators<timer_intr_t>();
+
+
+
+
// Forces to not inline function
#define NOINLINE_ATTR __attribute__((noinline))
+// This allows using enum as flags in C++
+// Format: FLAG_ATTR(flag_enum_t)
+#ifdef __cplusplus
+
+#define FLAG_ATTR_IMPL(TYPE, INT_TYPE) \
+constexpr TYPE operator~ (TYPE a) { return (TYPE)~(INT_TYPE)a; } \
+constexpr TYPE operator| (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a | (INT_TYPE)b); } \
+constexpr TYPE operator& (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a & (INT_TYPE)b); } \
+constexpr TYPE operator^ (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a ^ (INT_TYPE)b); } \
+constexpr TYPE operator>> (TYPE a, int b) { return (TYPE)((INT_TYPE)a >> b); } \
+constexpr TYPE operator<< (TYPE a, int b) { return (TYPE)((INT_TYPE)a << b); } \
+TYPE& operator|=(TYPE& a, TYPE b) { a = a | b; return a; } \
+TYPE& operator&=(TYPE& a, TYPE b) { a = a & b; return a; } \
+TYPE& operator^=(TYPE& a, TYPE b) { a = a ^ b; return a; } \
+TYPE& operator>>=(TYPE& a, int b) { a >>= b; return a; } \
+TYPE& operator<<=(TYPE& a, int b) { a <<= b; return a; }
+
+#define FLAG_ATTR_U32(TYPE) FLAG_ATTR_IMPL(TYPE, uint32_t)
+#define FLAG_ATTR FLAG_ATTR_U32
+
+#else
+#define FLAG_ATTR(TYPE)
+#endif
+
// Implementation for a unique custom section
//
// This prevents gcc producing "x causes a section type conflict with y"
TIMER_START = 1, /*!<Start timer counter*/
} timer_start_t;
-
/**
* @brief Interrupt types of the timer.
*/
TIMER_INTR_T1 = BIT(1), /*!< interrupt of timer 1 */
TIMER_INTR_WDT = BIT(2), /*!< interrupt of watchdog */
} timer_intr_t;
+FLAG_ATTR(timer_intr_t)
/**
* @brief Behavior of the watchdog if a stage times out.