PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

MsTimer2.cpp 6.8KB

3 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. MsTimer2.h - Using timer2 with 1ms resolution
  3. Javier Valencia <javiervalencia80@gmail.com>
  4. https://github.com/PaulStoffregen/MsTimer2
  5. History:
  6. 6/Jun/14 - V0.7 added support for Teensy 3.0 & 3.1
  7. 29/Dec/11 - V0.6 added support for ATmega32u4, AT90USB646, AT90USB1286 (paul@pjrc.com)
  8. some improvements added by Bill Perry
  9. note: uses timer4 on Atmega32u4
  10. 29/May/09 - V0.5 added support for Atmega1280 (thanks to Manuel Negri)
  11. 19/Mar/09 - V0.4 added support for ATmega328P (thanks to Jerome Despatis)
  12. 11/Jun/08 - V0.3
  13. changes to allow working with different CPU frequencies
  14. added support for ATMega128 (using timer2)
  15. compatible with ATMega48/88/168/8
  16. 10/May/08 - V0.2 added some security tests and volatile keywords
  17. 9/May/08 - V0.1 released working on ATMEGA168 only
  18. This library is free software; you can redistribute it and/or
  19. modify it under the terms of the GNU Lesser General Public
  20. License as published by the Free Software Foundation; either
  21. version 2.1 of the License, or (at your option) any later version.
  22. This library is distributed in the hope that it will be useful,
  23. but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. Lesser General Public License for more details.
  26. You should have received a copy of the GNU Lesser General Public
  27. License along with this library; if not, write to the Free Software
  28. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  29. */
  30. #include <MsTimer2.h>
  31. unsigned long MsTimer2::msecs;
  32. void (*MsTimer2::func)();
  33. volatile unsigned long MsTimer2::count;
  34. volatile char MsTimer2::overflowing;
  35. volatile unsigned int MsTimer2::tcnt2;
  36. #if defined(__arm__) && defined(TEENSYDUINO)
  37. static IntervalTimer itimer;
  38. #endif
  39. void MsTimer2::set(unsigned long ms, void (*f)()) {
  40. float prescaler = 0.0;
  41. if (ms == 0)
  42. msecs = 1;
  43. else
  44. msecs = ms;
  45. func = f;
  46. #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  47. TIMSK2 &= ~(1<<TOIE2);
  48. TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  49. TCCR2B &= ~(1<<WGM22);
  50. ASSR &= ~(1<<AS2);
  51. TIMSK2 &= ~(1<<OCIE2A);
  52. if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
  53. TCCR2B |= (1<<CS22);
  54. TCCR2B &= ~((1<<CS21) | (1<<CS20));
  55. prescaler = 64.0;
  56. } else if (F_CPU < 1000000UL) { // prescaler set to 8
  57. TCCR2B |= (1<<CS21);
  58. TCCR2B &= ~((1<<CS22) | (1<<CS20));
  59. prescaler = 8.0;
  60. } else { // F_CPU > 16Mhz, prescaler set to 128
  61. TCCR2B |= ((1<<CS22) | (1<<CS20));
  62. TCCR2B &= ~(1<<CS21);
  63. prescaler = 128.0;
  64. }
  65. #elif defined (__AVR_ATmega8__)
  66. TIMSK &= ~(1<<TOIE2);
  67. TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
  68. TIMSK &= ~(1<<OCIE2);
  69. ASSR &= ~(1<<AS2);
  70. if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
  71. TCCR2 |= (1<<CS22);
  72. TCCR2 &= ~((1<<CS21) | (1<<CS20));
  73. prescaler = 64.0;
  74. } else if (F_CPU < 1000000UL) { // prescaler set to 8
  75. TCCR2 |= (1<<CS21);
  76. TCCR2 &= ~((1<<CS22) | (1<<CS20));
  77. prescaler = 8.0;
  78. } else { // F_CPU > 16Mhz, prescaler set to 128
  79. TCCR2 |= ((1<<CS22) && (1<<CS20));
  80. TCCR2 &= ~(1<<CS21);
  81. prescaler = 128.0;
  82. }
  83. #elif defined (__AVR_ATmega128__)
  84. TIMSK &= ~(1<<TOIE2);
  85. TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
  86. TIMSK &= ~(1<<OCIE2);
  87. if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
  88. TCCR2 |= ((1<<CS21) | (1<<CS20));
  89. TCCR2 &= ~(1<<CS22);
  90. prescaler = 64.0;
  91. } else if (F_CPU < 1000000UL) { // prescaler set to 8
  92. TCCR2 |= (1<<CS21);
  93. TCCR2 &= ~((1<<CS22) | (1<<CS20));
  94. prescaler = 8.0;
  95. } else { // F_CPU > 16Mhz, prescaler set to 256
  96. TCCR2 |= (1<<CS22);
  97. TCCR2 &= ~((1<<CS21) | (1<<CS20));
  98. prescaler = 256.0;
  99. }
  100. #elif defined (__AVR_ATmega32U4__)
  101. TCCR4B = 0;
  102. TCCR4A = 0;
  103. TCCR4C = 0;
  104. TCCR4D = 0;
  105. TCCR4E = 0;
  106. if (F_CPU >= 16000000L) {
  107. TCCR4B = (1<<CS43) | (1<<PSR4);
  108. prescaler = 128.0;
  109. } else if (F_CPU >= 8000000L) {
  110. TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4);
  111. prescaler = 64.0;
  112. } else if (F_CPU >= 4000000L) {
  113. TCCR4B = (1<<CS42) | (1<<CS41) | (1<<PSR4);
  114. prescaler = 32.0;
  115. } else if (F_CPU >= 2000000L) {
  116. TCCR4B = (1<<CS42) | (1<<CS40) | (1<<PSR4);
  117. prescaler = 16.0;
  118. } else if (F_CPU >= 1000000L) {
  119. TCCR4B = (1<<CS42) | (1<<PSR4);
  120. prescaler = 8.0;
  121. } else if (F_CPU >= 500000L) {
  122. TCCR4B = (1<<CS41) | (1<<CS40) | (1<<PSR4);
  123. prescaler = 4.0;
  124. } else {
  125. TCCR4B = (1<<CS41) | (1<<PSR4);
  126. prescaler = 2.0;
  127. }
  128. tcnt2 = (int)((float)F_CPU * 0.001 / prescaler) - 1;
  129. OCR4C = tcnt2;
  130. return;
  131. #elif defined(__arm__) && defined(TEENSYDUINO)
  132. // nothing needed here
  133. #else
  134. #error Unsupported CPU type
  135. #endif
  136. tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);
  137. }
  138. void MsTimer2::start() {
  139. count = 0;
  140. overflowing = 0;
  141. #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  142. TCNT2 = tcnt2;
  143. TIMSK2 |= (1<<TOIE2);
  144. #elif defined (__AVR_ATmega128__)
  145. TCNT2 = tcnt2;
  146. TIMSK |= (1<<TOIE2);
  147. #elif defined (__AVR_ATmega8__)
  148. TCNT2 = tcnt2;
  149. TIMSK |= (1<<TOIE2);
  150. #elif defined (__AVR_ATmega32U4__)
  151. TIFR4 = (1<<TOV4);
  152. TCNT4 = 0;
  153. TIMSK4 = (1<<TOIE4);
  154. #elif defined(__arm__) && defined(TEENSYDUINO)
  155. itimer.begin(MsTimer2::_overflow, 1000);
  156. #endif
  157. }
  158. void MsTimer2::stop() {
  159. #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  160. TIMSK2 &= ~(1<<TOIE2);
  161. #elif defined (__AVR_ATmega128__)
  162. TIMSK &= ~(1<<TOIE2);
  163. #elif defined (__AVR_ATmega8__)
  164. TIMSK &= ~(1<<TOIE2);
  165. #elif defined (__AVR_ATmega32U4__)
  166. TIMSK4 = 0;
  167. #elif defined(__arm__) && defined(TEENSYDUINO)
  168. itimer.end();
  169. #endif
  170. }
  171. void MsTimer2::_overflow() {
  172. count += 1;
  173. if (count >= msecs && !overflowing) {
  174. overflowing = 1;
  175. count = count - msecs; // subtract ms to catch missed overflows
  176. // set to 0 if you don't want this.
  177. (*func)();
  178. overflowing = 0;
  179. }
  180. }
  181. #if defined (__AVR__)
  182. #if defined (__AVR_ATmega32U4__)
  183. ISR(TIMER4_OVF_vect) {
  184. #else
  185. ISR(TIMER2_OVF_vect) {
  186. #endif
  187. #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  188. TCNT2 = MsTimer2::tcnt2;
  189. #elif defined (__AVR_ATmega128__)
  190. TCNT2 = MsTimer2::tcnt2;
  191. #elif defined (__AVR_ATmega8__)
  192. TCNT2 = MsTimer2::tcnt2;
  193. #elif defined (__AVR_ATmega32U4__)
  194. // not necessary on 32u4's high speed timer4
  195. #endif
  196. MsTimer2::_overflow();
  197. }
  198. #endif // AVR