AltSoftSerial_Timers.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* An Alternative Software Serial Library
  2. * http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
  3. * Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #if defined(ALTSS_USE_TIMER1)
  24. #define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS10))
  25. #define CONFIG_TIMER_PRESCALE_8() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS11))
  26. #define CONFIG_TIMER_PRESCALE_256() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS12))
  27. #define CONFIG_MATCH_NORMAL() (TCCR1A = TCCR1A & ~((1<<COM1A1) | (1<<COM1A0)))
  28. #define CONFIG_MATCH_TOGGLE() (TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1A0))
  29. #define CONFIG_MATCH_CLEAR() (TCCR1A = (TCCR1A | (1<<COM1A1)) & ~(1<<COM1A0))
  30. #define CONFIG_MATCH_SET() (TCCR1A = TCCR1A | ((1<<COM1A1) | (1<<COM1A0)))
  31. #define CONFIG_CAPTURE_FALLING_EDGE() (TCCR1B &= ~(1<<ICES1))
  32. #define CONFIG_CAPTURE_RISING_EDGE() (TCCR1B |= (1<<ICES1))
  33. #define ENABLE_INT_INPUT_CAPTURE() (TIFR1 = (1<<ICF1), TIMSK1 = (1<<ICIE1))
  34. #define ENABLE_INT_COMPARE_A() (TIFR1 = (1<<OCF1A), TIMSK1 |= (1<<OCIE1A))
  35. #define ENABLE_INT_COMPARE_B() (TIFR1 = (1<<OCF1B), TIMSK1 |= (1<<OCIE1B))
  36. #define DISABLE_INT_INPUT_CAPTURE() (TIMSK1 &= ~(1<<ICIE1))
  37. #define DISABLE_INT_COMPARE_A() (TIMSK1 &= ~(1<<OCIE1A))
  38. #define DISABLE_INT_COMPARE_B() (TIMSK1 &= ~(1<<OCIE1B))
  39. #define GET_TIMER_COUNT() (TCNT1)
  40. #define GET_INPUT_CAPTURE() (ICR1)
  41. #define GET_COMPARE_A() (OCR1A)
  42. #define GET_COMPARE_B() (OCR1B)
  43. #define SET_COMPARE_A(val) (OCR1A = (val))
  44. #define SET_COMPARE_B(val) (OCR1B = (val))
  45. #define CAPTURE_INTERRUPT TIMER1_CAPT_vect
  46. #define COMPARE_A_INTERRUPT TIMER1_COMPA_vect
  47. #define COMPARE_B_INTERRUPT TIMER1_COMPB_vect
  48. #elif defined(ALTSS_USE_TIMER3)
  49. #define CONFIG_TIMER_NOPRESCALE() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS30))
  50. #define CONFIG_TIMER_PRESCALE_8() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS31))
  51. #define CONFIG_TIMER_PRESCALE_256() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS32))
  52. #define CONFIG_MATCH_NORMAL() (TCCR3A = TCCR3A & ~((1<<COM3A1) | (1<<COM3A0)))
  53. #define CONFIG_MATCH_TOGGLE() (TCCR3A = (TCCR3A & ~(1<<COM3A1)) | (1<<COM3A0))
  54. #define CONFIG_MATCH_CLEAR() (TCCR3A = (TCCR3A | (1<<COM3A1)) & ~(1<<COM3A0))
  55. #define CONFIG_MATCH_SET() (TCCR3A = TCCR3A | ((1<<COM3A1) | (1<<COM3A0)))
  56. #define CONFIG_CAPTURE_FALLING_EDGE() (TCCR3B &= ~(1<<ICES3))
  57. #define CONFIG_CAPTURE_RISING_EDGE() (TCCR3B |= (1<<ICES3))
  58. #define ENABLE_INT_INPUT_CAPTURE() (TIFR3 = (1<<ICF3), TIMSK3 = (1<<ICIE3))
  59. #define ENABLE_INT_COMPARE_A() (TIFR3 = (1<<OCF3A), TIMSK3 |= (1<<OCIE3A))
  60. #define ENABLE_INT_COMPARE_B() (TIFR3 = (1<<OCF3B), TIMSK3 |= (1<<OCIE3B))
  61. #define DISABLE_INT_INPUT_CAPTURE() (TIMSK3 &= ~(1<<ICIE3))
  62. #define DISABLE_INT_COMPARE_A() (TIMSK3 &= ~(1<<OCIE3A))
  63. #define DISABLE_INT_COMPARE_B() (TIMSK3 &= ~(1<<OCIE3B))
  64. #define GET_TIMER_COUNT() (TCNT3)
  65. #define GET_INPUT_CAPTURE() (ICR3)
  66. #define GET_COMPARE_A() (OCR3A)
  67. #define GET_COMPARE_B() (OCR3B)
  68. #define SET_COMPARE_A(val) (OCR3A = (val))
  69. #define SET_COMPARE_B(val) (OCR3B = (val))
  70. #define CAPTURE_INTERRUPT TIMER3_CAPT_vect
  71. #define COMPARE_A_INTERRUPT TIMER3_COMPA_vect
  72. #define COMPARE_B_INTERRUPT TIMER3_COMPB_vect
  73. #elif defined(ALTSS_USE_TIMER4)
  74. #define CONFIG_TIMER_NOPRESCALE() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS40))
  75. #define CONFIG_TIMER_PRESCALE_8() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS41))
  76. #define CONFIG_TIMER_PRESCALE_256() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS42))
  77. #define CONFIG_MATCH_NORMAL() (TCCR4A = TCCR4A & ~((1<<COM4A1) | (1<<COM4A0)))
  78. #define CONFIG_MATCH_TOGGLE() (TCCR4A = (TCCR4A & ~(1<<COM4A1)) | (1<<COM4A0))
  79. #define CONFIG_MATCH_CLEAR() (TCCR4A = (TCCR4A | (1<<COM4A1)) & ~(1<<COM4A0))
  80. #define CONFIG_MATCH_SET() (TCCR4A = TCCR4A | ((1<<COM4A1) | (1<<COM4A0)))
  81. #define CONFIG_CAPTURE_FALLING_EDGE() (TCCR4B &= ~(1<<ICES4))
  82. #define CONFIG_CAPTURE_RISING_EDGE() (TCCR4B |= (1<<ICES4))
  83. #define ENABLE_INT_INPUT_CAPTURE() (TIFR4 = (1<<ICF4), TIMSK4 = (1<<ICIE4))
  84. #define ENABLE_INT_COMPARE_A() (TIFR4 = (1<<OCF4A), TIMSK4 |= (1<<OCIE4A))
  85. #define ENABLE_INT_COMPARE_B() (TIFR4 = (1<<OCF4B), TIMSK4 |= (1<<OCIE4B))
  86. #define DISABLE_INT_INPUT_CAPTURE() (TIMSK4 &= ~(1<<ICIE4))
  87. #define DISABLE_INT_COMPARE_A() (TIMSK4 &= ~(1<<OCIE4A))
  88. #define DISABLE_INT_COMPARE_B() (TIMSK4 &= ~(1<<OCIE4B))
  89. #define GET_TIMER_COUNT() (TCNT4)
  90. #define GET_INPUT_CAPTURE() (ICR4)
  91. #define GET_COMPARE_A() (OCR4A)
  92. #define GET_COMPARE_B() (OCR4B)
  93. #define SET_COMPARE_A(val) (OCR4A = (val))
  94. #define SET_COMPARE_B(val) (OCR4B = (val))
  95. #define CAPTURE_INTERRUPT TIMER4_CAPT_vect
  96. #define COMPARE_A_INTERRUPT TIMER4_COMPA_vect
  97. #define COMPARE_B_INTERRUPT TIMER4_COMPB_vect
  98. #elif defined(ALTSS_USE_TIMER5)
  99. #define CONFIG_TIMER_NOPRESCALE() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS50))
  100. #define CONFIG_TIMER_PRESCALE_8() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS51))
  101. #define CONFIG_TIMER_PRESCALE_256() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS52))
  102. #define CONFIG_MATCH_NORMAL() (TCCR5A = TCCR5A & ~((1<<COM5A1) | (1<<COM5A0)))
  103. #define CONFIG_MATCH_TOGGLE() (TCCR5A = (TCCR5A & ~(1<<COM5A1)) | (1<<COM5A0))
  104. #define CONFIG_MATCH_CLEAR() (TCCR5A = (TCCR5A | (1<<COM5A1)) & ~(1<<COM5A0))
  105. #define CONFIG_MATCH_SET() (TCCR5A = TCCR5A | ((1<<COM5A1) | (1<<COM5A0)))
  106. #define CONFIG_CAPTURE_FALLING_EDGE() (TCCR5B &= ~(1<<ICES5))
  107. #define CONFIG_CAPTURE_RISING_EDGE() (TCCR5B |= (1<<ICES5))
  108. #define ENABLE_INT_INPUT_CAPTURE() (TIFR5 = (1<<ICF5), TIMSK5 = (1<<ICIE5))
  109. #define ENABLE_INT_COMPARE_A() (TIFR5 = (1<<OCF5A), TIMSK5 |= (1<<OCIE5A))
  110. #define ENABLE_INT_COMPARE_B() (TIFR5 = (1<<OCF5B), TIMSK5 |= (1<<OCIE5B))
  111. #define DISABLE_INT_INPUT_CAPTURE() (TIMSK5 &= ~(1<<ICIE5))
  112. #define DISABLE_INT_COMPARE_A() (TIMSK5 &= ~(1<<OCIE5A))
  113. #define DISABLE_INT_COMPARE_B() (TIMSK5 &= ~(1<<OCIE5B))
  114. #define GET_TIMER_COUNT() (TCNT5)
  115. #define GET_INPUT_CAPTURE() (ICR5)
  116. #define GET_COMPARE_A() (OCR5A)
  117. #define GET_COMPARE_B() (OCR5B)
  118. #define SET_COMPARE_A(val) (OCR5A = (val))
  119. #define SET_COMPARE_B(val) (OCR5B = (val))
  120. #define CAPTURE_INTERRUPT TIMER5_CAPT_vect
  121. #define COMPARE_A_INTERRUPT TIMER5_COMPA_vect
  122. #define COMPARE_B_INTERRUPT TIMER5_COMPB_vect
  123. #elif defined(ALTSS_USE_FTM0)
  124. // CH5 = input capture (input, pin 20)
  125. // CH6 = compare a (output, pin 21)
  126. // CH0 = compare b (input timeout)
  127. #define CONFIG_TIMER_NOPRESCALE() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
  128. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
  129. digitalWriteFast(21, HIGH); \
  130. NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
  131. FTM0_C0SC = 0x18; \
  132. NVIC_ENABLE_IRQ(IRQ_FTM0);
  133. #define CONFIG_TIMER_PRESCALE_8() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
  134. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(3); \
  135. digitalWriteFast(21, HIGH); \
  136. NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
  137. FTM0_C0SC = 0x18; \
  138. NVIC_ENABLE_IRQ(IRQ_FTM0);
  139. #define CONFIG_TIMER_PRESCALE_128() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
  140. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(7); \
  141. digitalWriteFast(21, HIGH); \
  142. NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
  143. FTM0_C0SC = 0x18; \
  144. NVIC_ENABLE_IRQ(IRQ_FTM0);
  145. #define CONFIG_MATCH_NORMAL() (FTM0_C6SC = 0)
  146. #define CONFIG_MATCH_TOGGLE() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x14)
  147. #define CONFIG_MATCH_CLEAR() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x18)
  148. #define CONFIG_MATCH_SET() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x1C)
  149. #define CONFIG_CAPTURE_FALLING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x08)
  150. #define CONFIG_CAPTURE_RISING_EDGE() (FTM0_C5SC = (FTM0_C5SC & 0xC3) | 0x04)
  151. #define ENABLE_INT_INPUT_CAPTURE() FTM0_C5SC = 0x48; \
  152. CORE_PIN20_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_PE|PORT_PCR_PS
  153. #define ENABLE_INT_COMPARE_A() FTM0_C6SC |= 0x40; \
  154. CORE_PIN21_CONFIG = PORT_PCR_MUX(4)|PORT_PCR_DSE|PORT_PCR_SRE
  155. #define ENABLE_INT_COMPARE_B() (FTM0_C0SC = 0x58)
  156. #define DISABLE_INT_INPUT_CAPTURE() FTM0_C5SC &= ~0x40; \
  157. CORE_PIN20_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_PE|PORT_PCR_PS
  158. #define DISABLE_INT_COMPARE_A() FTM0_C6SC &= ~0x40; \
  159. CORE_PIN21_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE; \
  160. digitalWriteFast(21, HIGH)
  161. #define DISABLE_INT_COMPARE_B() (FTM0_C0SC &= ~0x40)
  162. #define GET_TIMER_COUNT() (FTM0_CNT)
  163. #define GET_INPUT_CAPTURE() (FTM0_C5V)
  164. #define GET_COMPARE_A() (FTM0_C6V)
  165. #define GET_COMPARE_B() (FTM0_C0V)
  166. #define SET_COMPARE_A(val) (FTM0_C6V = val)
  167. #define SET_COMPARE_B(val) if (FTM0_C0SC & FTM_CSC_CHF) FTM0_C0SC = 0x18; \
  168. do { FTM0_C0V = (val); } while (FTM0_C0V != (val));
  169. #define CAPTURE_INTERRUPT altss_capture_interrupt
  170. #define COMPARE_A_INTERRUPT altss_compare_a_interrupt
  171. #define COMPARE_B_INTERRUPT altss_compare_b_interrupt
  172. #ifdef ISR
  173. #undef ISR
  174. #endif
  175. #define ISR(f) static void f (void)
  176. #endif