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.

229 line
7.3KB

  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #ifndef Wiring_h
  31. #define Wiring_h
  32. #include <stdint.h>
  33. #include <stdlib.h>
  34. #include <stdbool.h>
  35. #include "binary.h"
  36. #include "core_id.h"
  37. #include "core_pins.h"
  38. // type_traits interferes with min() and other defines
  39. // include it early, so we can define these later
  40. // for Arduino compatibility
  41. #ifdef __cplusplus
  42. #include <type_traits>
  43. // when the input number is an integer type, do all math as 32 bit signed long
  44. template <class T, class A, class B, class C, class D>
  45. long map(T _x, A _in_min, B _in_max, C _out_min, D _out_max, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
  46. {
  47. long x = _x, in_min = _in_min, in_max = _in_max, out_min = _out_min, out_max = _out_max;
  48. // Arduino's traditional algorithm
  49. #if 0
  50. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  51. #endif
  52. #if 0
  53. // st42's suggestion: https://github.com/arduino/Arduino/issues/2466#issuecomment-69873889
  54. if ((in_max - in_min) > (out_max - out_min)) {
  55. return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min;
  56. } else {
  57. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  58. }
  59. #endif
  60. // first compute the ranges and check if input doesn't matter
  61. long in_range = in_max - in_min;
  62. long out_range = out_max - out_min;
  63. if (in_range == 0) return out_min + out_range / 2;
  64. // compute the numerator
  65. long num = (x - in_min) * out_range;
  66. // before dividing, add extra for proper round off (towards zero)
  67. if (out_range >= 0) {
  68. num += in_range / 2;
  69. } else {
  70. num -= in_range / 2;
  71. }
  72. // divide by input range and add output offset to complete map() compute
  73. long result = num / in_range + out_min;
  74. // fix "a strange behaviour with negative numbers" (see ArduinoCore-API issue #51)
  75. // this step can be deleted if you don't care about non-linear output
  76. // behavior extrapolating slightly beyond the mapped input & output range
  77. if (out_range >= 0) {
  78. if (in_range * num < 0) return result - 1;
  79. } else {
  80. if (in_range * num >= 0) return result + 1;
  81. }
  82. return result;
  83. // more conversation:
  84. // https://forum.pjrc.com/threads/44503-map()-function-improvements
  85. }
  86. // when the input is a float or double, do all math using the input's type
  87. template <class T, class A, class B, class C, class D>
  88. T map(T x, A in_min, B in_max, C out_min, D out_max, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0)
  89. {
  90. return (x - (T)in_min) * ((T)out_max - (T)out_min) / ((T)in_max - (T)in_min) + (T)out_min;
  91. }
  92. //#include <algorithm> // this isn't really needed, is it? (slows down compiling)
  93. #include <utility>
  94. // https://forum.pjrc.com/threads/44596-Teensyduino-1-37-Beta-2-(Arduino-1-8-3-support)?p=145150&viewfull=1#post145150
  95. template<class A, class B>
  96. constexpr auto min(A&& a, B&& b) -> decltype(a < b ? std::forward<A>(a) : std::forward<B>(b)) {
  97. return a < b ? std::forward<A>(a) : std::forward<B>(b);
  98. }
  99. template<class A, class B>
  100. constexpr auto max(A&& a, B&& b) -> decltype(a < b ? std::forward<A>(a) : std::forward<B>(b)) {
  101. return a >= b ? std::forward<A>(a) : std::forward<B>(b);
  102. }
  103. #else // not C++
  104. #define min(a, b) ({ \
  105. typeof(a) _a = (a); \
  106. typeof(b) _b = (b); \
  107. (_a < _b) ? _a : _b; \
  108. })
  109. #define max(a, b) ({ \
  110. typeof(a) _a = (a); \
  111. typeof(b) _b = (b); \
  112. (_a > _b) ? _a : _b; \
  113. })
  114. #endif
  115. #ifdef PI
  116. #undef PI
  117. #endif
  118. #define PI 3.1415926535897932384626433832795
  119. #define HALF_PI 1.5707963267948966192313216916398
  120. #define TWO_PI 6.283185307179586476925286766559
  121. #define DEG_TO_RAD 0.017453292519943295769236907684886
  122. #define RAD_TO_DEG 57.295779513082320876798154814105
  123. #ifndef M_PI
  124. #define M_PI 3.1415926535897932384626433832795
  125. #endif
  126. #ifndef M_SQRT2
  127. #define M_SQRT2 1.4142135623730950488016887
  128. #endif
  129. #define SERIAL 0
  130. #define DISPLAY 1
  131. // undefine stdlib's abs if encountered
  132. #ifdef abs
  133. #undef abs
  134. #endif
  135. #if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
  136. #define typeof(a) decltype(a)
  137. #endif
  138. #define abs(x) ({ \
  139. typeof(x) _x = (x); \
  140. (_x > 0) ? _x : -_x; \
  141. })
  142. #define constrain(amt, low, high) ({ \
  143. typeof(amt) _amt = (amt); \
  144. typeof(low) _low = (low); \
  145. typeof(high) _high = (high); \
  146. (_amt < _low) ? _low : ((_amt > _high) ? _high : _amt); \
  147. })
  148. #define round(x) ({ \
  149. typeof(x) _x = (x); \
  150. (_x>=0) ? (long)(_x+0.5) : (long)(_x-0.5); \
  151. })
  152. #define radians(deg) ((deg)*DEG_TO_RAD)
  153. #define degrees(rad) ((rad)*RAD_TO_DEG)
  154. #define sq(x) ({ \
  155. typeof(x) _x = (x); \
  156. _x * _x; \
  157. })
  158. #ifdef __cplusplus
  159. extern "C"{
  160. #endif
  161. extern double exp10(double x);
  162. extern float exp10f(float x);
  163. extern long double exp10l(long double x);
  164. extern double pow10(double x);
  165. extern float pow10f(float x);
  166. extern long double pow10l(long double x);
  167. #define stricmp(a, b) strcasecmp(a, b)
  168. #define sei() __enable_irq()
  169. #define cli() __disable_irq()
  170. #define interrupts() __enable_irq()
  171. #define noInterrupts() __disable_irq()
  172. #define clockCyclesPerMicrosecond() ( F_CPU_ACTUAL / 1000000L )
  173. #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
  174. #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
  175. #define lowByte(w) ((uint8_t)((w) & 0xFF))
  176. #define highByte(w) ((uint8_t)((w) >> 8))
  177. #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
  178. #define bitSet(value, bit) ((value) |= (1UL << (bit)))
  179. #define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
  180. #define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet((value), (bit)) : bitClear((value), (bit)))
  181. typedef unsigned int word;
  182. #define bit(b) (1UL << (b))
  183. typedef uint8_t byte;
  184. uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout);
  185. void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);
  186. void setup(void);
  187. void loop(void);
  188. void *extmem_malloc(size_t size);
  189. void extmem_free(void *ptr);
  190. void *extmem_calloc(size_t nmemb, size_t size);
  191. void *extmem_realloc(void *ptr, size_t size);
  192. #ifdef __cplusplus
  193. } // extern "C"
  194. #endif
  195. // fix C++ boolean issue
  196. // https://github.com/arduino/Arduino/pull/2151
  197. #ifdef __cplusplus
  198. typedef bool boolean;
  199. #else
  200. typedef uint8_t boolean;
  201. #endif
  202. #endif