Marlin_Firmware/Marlin/src/core/macros.h

274 lines
7.9 KiB
C
Raw Normal View History

/**
2016-03-24 13:01:20 -05:00
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _CORE_MACROS_H_
#define _CORE_MACROS_H_
#define NUM_AXIS 4
#define ABCE 4
#define XYZE 4
#define ABC 3
#define XYZ 3
2018-05-13 03:44:24 -05:00
#define _AXIS(A) (A##_AXIS)
#define _XMIN_ 100
#define _YMIN_ 200
#define _ZMIN_ 300
#define _XMAX_ 101
#define _YMAX_ 201
#define _ZMAX_ 301
Fixes for the Arduino DUE HAL (Serial Port, Graphics Display, EEPROM emulation) (#8651) * Fixing the DUE serial port assignments: Now -1 means the SAM3x USB Device emulating a serial port, and 0 means the USB to serial adapter included as a programming port * Improving the Fast IO port access implementation on Arduino DUE * Implemented EEPROM emulation on Due by storing data on the internal FLASH (with wear leveling) * Implemented a Software SPI for the ST7920 graphics display for the Arduino RAMPS for DUE, as the default one in u8glib is clocking data too fast on ARM, and the display does not understand it. * Fixing the case where the serial port selected is the USB device * Adding configuration for the Makerparts 3D printer (www.makerparts.net) * Tuned MakerParts acceleration on X and Y axis so it never loses steps. Also adjusted pulses per mm to match default hw configuration * Fine tuned Maximum acceleration for MakerParts printer * Style cleanup * Style cleanup (2) * Style fixes (3) * Fixing the DUE serial port assignments: Now -1 means the SAM3x USB Device emulating a serial port, and 0 means the USB to serial adapter included as a programming port * Improving the Fast IO port access implementation on Arduino DUE * Implemented EEPROM emulation on Due by storing data on the internal FLASH (with wear leveling) * Implemented a Software SPI for the ST7920 graphics display for the Arduino RAMPS for DUE, as the default one in u8glib is clocking data too fast on ARM, and the display does not understand it. * Fixing the case where the serial port selected is the USB device * Adding configuration for the Makerparts 3D printer (www.makerparts.net) * Tuned MakerParts acceleration on X and Y axis so it never loses steps. Also adjusted pulses per mm to match default hw configuration * Fine tuned Maximum acceleration for MakerParts printer * Style cleanup * Style changes to u8g_dev_st7920_128_64_sw_spi.cpp * Even more improvements to the FastIO HAL for DUE. Now WRITE() is 2 ASM instructions, if value is constant, and 5 cycles if value is not constant. Previously, it was 7..8 cycles * After some problems and debugging, seems we need to align the interrupt vector table to 256 bytes, otherwise, the program sometimes stops working * Moved comments out of macro, otherwise, token pasting does not properly work sometimes * Improved Software SPI implementation on DUE: Now it honors the selected speed passed to spiInit(). This allows much faster SDCARD access, improving SDCARD menus and reducing latency * Update u8g_dev_st7920_128_64_sw_spi.cpp * Disabling EEPROM over FLASH emulatiion if an I2C or SPI EEPROM is present
2017-12-12 17:51:36 -06:00
#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
#define FORCE_INLINE __attribute__((always_inline)) inline
#define _UNUSED __attribute__((unused))
#define _O0 __attribute__((optimize("O0")))
#define _Os __attribute__((optimize("Os")))
#define _O1 __attribute__((optimize("O1")))
#define _O2 __attribute__((optimize("O2")))
#define _O3 __attribute__((optimize("O3")))
2017-04-11 11:11:17 -05:00
// Clock speed factors
#if !defined(CYCLES_PER_MICROSECOND) && !defined(__STM32F1__)
2018-02-10 20:08:48 -06:00
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20 on AVR
#endif
2016-09-23 23:59:16 -05:00
// Nanoseconds per cycle
#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
2017-04-11 02:33:46 -05:00
// Remove compiler warning on an unused variable
#define UNUSED(x) (void) (x)
2016-03-14 01:15:17 -05:00
// Macros to make a string from a macro
#define STRINGIFY_(M) #M
#define STRINGIFY(M) STRINGIFY_(M)
2016-03-14 01:15:17 -05:00
2018-05-08 05:10:27 -05:00
#define A(CODE) " " CODE "\n\t"
#define L(CODE) CODE ":\n\t"
// Macros for bit masks
2018-02-01 00:06:44 -06:00
#undef _BV
2018-05-21 20:32:10 -05:00
#define _BV(n) (1<<(n))
2018-02-01 00:06:44 -06:00
#define TEST(n,b) !!((n)&_BV(b))
2016-02-29 01:29:53 -06:00
#define SBI(n,b) (n |= _BV(b))
#define CBI(n,b) (n &= ~_BV(b))
2018-05-24 00:04:47 -05:00
#define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0)
2018-02-01 00:06:44 -06:00
#define _BV32(b) (1UL << (b))
#define TEST32(n,b) !!((n)&_BV32(b))
#define SBI32(n,b) (n |= _BV32(b))
#define CBI32(n,b) (n &= ~_BV32(b))
// Macros for maths shortcuts
#undef M_PI
#define M_PI 3.14159265358979323846f
#define RADIANS(d) ((d)*float(M_PI)/180.0f)
#define DEGREES(r) ((r)*180.0f/float(M_PI))
2016-09-11 21:02:37 -05:00
#define HYPOT2(x,y) (sq(x)+sq(y))
#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R)))
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
2017-09-06 06:28:32 -05:00
#define SIGN(a) ((a>0)-(a<0))
#define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1)))
// Macros to constrain values
// Avoid double evaluation of arguments to NOMORE/NOLESS/LIMIT
#undef NOMORE
#undef NOLESS
#undef LIMIT
#ifdef __cplusplus
// C++11 solution that is standards compliant.
template <class V, class N> static inline constexpr void NOLESS(V& v, const N n) {
if (v < n) v = n;
}
template <class V, class N> static inline constexpr void NOMORE(V& v, const N n) {
if (v > n) v = n;
}
template <class V, class N1, class N2> static inline constexpr void LIMIT(V& v, const N1 n1, const N2 n2) {
if (v < n1) v = n1;
else if (v > n2) v = n2;
}
#else
// Using GCC extensions, but Travis GCC version does not like it and gives
// "error: statement-expressions are not allowed outside functions nor in template-argument lists"
#define NOLESS(v, n) \
do { \
__typeof__(n) _n = (n); \
if (v < _n) v = _n; \
} while(0)
#define NOMORE(v, n) \
do { \
__typeof__(n) _n = (n); \
if (v > _n) v = _n; \
} while(0)
#define LIMIT(v, n1, n2) \
do { \
__typeof__(n1) _n1 = (n1); \
__typeof__(n2) _n2 = (n2); \
if (v < _n1) v = _n1; \
else if (v > _n2) v = _n2; \
} while(0)
#endif
// Macros to support option testing
#define _CAT(a, ...) a ## __VA_ARGS__
#define SWITCH_ENABLED_false 0
#define SWITCH_ENABLED_true 1
#define SWITCH_ENABLED_0 0
#define SWITCH_ENABLED_1 1
#define SWITCH_ENABLED_0x0 0
#define SWITCH_ENABLED_0x1 1
#define SWITCH_ENABLED_ 1
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
#define DISABLED(b) !ENABLED(b)
2017-03-31 09:00:49 -05:00
#define WITHIN(V,L,H) ((V) >= (L) && (V) <= (H))
#define NUMERIC(a) WITHIN(a, '0', '9')
2017-05-20 03:03:08 -05:00
#define DECIMAL(a) (NUMERIC(a) || a == '.')
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+')
#define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+')
2015-07-22 17:50:20 -05:00
#define COUNT(a) (sizeof(a)/sizeof(*a))
2016-10-22 10:07:18 -05:00
#define ZERO(a) memset(a,0,sizeof(a))
#define COPY(a,b) memcpy(a,b,MIN(sizeof(a),sizeof(b)))
2015-07-22 17:50:20 -05:00
2016-07-01 22:27:55 -05:00
// Macros for initializing arrays
#define ARRAY_6(v1, v2, v3, v4, v5, v6, ...) { v1, v2, v3, v4, v5, v6 }
#define ARRAY_5(v1, v2, v3, v4, v5, ...) { v1, v2, v3, v4, v5 }
#define ARRAY_4(v1, v2, v3, v4, ...) { v1, v2, v3, v4 }
#define ARRAY_3(v1, v2, v3, ...) { v1, v2, v3 }
#define ARRAY_2(v1, v2, ...) { v1, v2 }
#define ARRAY_1(v1, ...) { v1 }
#define _ARRAY_N(N, ...) ARRAY_ ##N(__VA_ARGS__)
#define ARRAY_N(N, ...) _ARRAY_N(N, __VA_ARGS__)
2016-07-01 22:27:55 -05:00
2016-05-17 16:56:49 -05:00
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INCREMENT_(n) INC_ ##n
#define INCREMENT(n) INCREMENT_(n)
// Macros for subtracting
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DECREMENT_(n) DEC_ ##n
#define DECREMENT(n) DECREMENT_(n)
#define PIN_EXISTS(PN) (defined(PN ##_PIN) && PN ##_PIN >= 0)
2016-04-10 17:55:12 -05:00
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define MMM_TO_MMS(MM_M) ((MM_M)/60.0f)
#define MMS_TO_MMM(MM_S) ((MM_S)*60.0f)
#define NOOP do{} while(0)
#define CEILING(x,y) (((x) + (y) - 1) / (y))
2016-04-28 19:59:52 -05:00
// Avoid double evaluation of arguments on MIN/MAX/ABS
#undef MIN
#undef MAX
#undef ABS
#ifdef __cplusplus
// C++11 solution that is standards compliant. Return type is deduced automatically
template <class L, class R> static inline constexpr auto MIN(const L lhs, const R rhs) -> decltype(lhs + rhs) {
return lhs < rhs ? lhs : rhs;
}
template <class L, class R> static inline constexpr auto MAX(const L lhs, const R rhs) -> decltype(lhs + rhs){
return lhs > rhs ? lhs : rhs;
}
template <class T> static inline constexpr const T ABS(const T v) {
return v >= 0 ? v : -v;
}
#else
// Using GCC extensions, but Travis GCC version does not like it and gives
// "error: statement-expressions are not allowed outside functions nor in template-argument lists"
#define MIN(a, b) \
({__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b;})
#define MAX(a, b) \
({__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b;})
#define ABS(a) \
({__typeof__(a) _a = (a); \
_a >= 0 ? _a : -_a;})
#endif
#define MIN3(a, b, c) MIN(MIN(a, b), c)
#define MIN4(a, b, c, d) MIN(MIN3(a, b, c), d)
#define MIN5(a, b, c, d, e) MIN(MIN4(a, b, c, d), e)
#define MAX3(a, b, c) MAX(MAX(a, b), c)
#define MAX4(a, b, c, d) MAX(MAX3(a, b, c), d)
#define MAX5(a, b, c, d, e) MAX(MAX4(a, b, c, d), e)
2016-08-18 22:13:47 -05:00
#define UNEAR_ZERO(x) ((x) < 0.000001f)
#define NEAR_ZERO(x) WITHIN(x, -0.000001f, 0.000001f)
2016-09-11 21:02:37 -05:00
#define NEAR(x,y) NEAR_ZERO((x)-(y))
#define RECIPROCAL(x) (NEAR_ZERO(x) ? 0 : (1 / float(x)))
#define FIXFLOAT(f) (f + (f < 0 ? -0.00005f : 0.00005f))
//
// Maths macros that can be overridden by HAL
//
#define ATAN2(y, x) atan2f(y, x)
#define POW(x, y) powf(x, y)
#define SQRT(x) sqrtf(x)
#define RSQRT(x) (1 / sqrtf(x))
#define CEIL(x) ceilf(x)
#define FLOOR(x) floorf(x)
#define LROUND(x) lroundf(x)
#define FMOD(x, y) fmodf(x, y)
#define HYPOT(x,y) SQRT(HYPOT2(x,y))
#endif // _CORE_MACROS_H_